From a7fd79192623d101a8445ee76ec4187763885be2 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Thu, 13 Nov 2014 19:30:51 +0200 Subject: [PATCH] initial import --- .krazy | 5 + CMakeLists.txt | 360 + COPYING | 346 + COPYING.DOC | 397 + COPYING.LIB | 510 + CTestConfig.cmake | 13 + ConfigureChecks.cmake | 102 + KDE4WorkspaceConfig.cmake.in | 70 + Mainpage.dox | 51 + README | 1 + README.pam | 72 + appmenu/CMakeLists.txt | 37 + appmenu/appmenu.cpp | 399 + appmenu/appmenu.desktop | 96 + appmenu/appmenu.h | 154 + appmenu/appmenu_dbus.cpp | 69 + appmenu/appmenu_dbus.h | 100 + appmenu/com.canonical.AppMenu.Registrar.xml | 56 + appmenu/glowbar.cpp | 109 + appmenu/glowbar.h | 51 + appmenu/gtkicons.h | 146 + appmenu/kdbusimporter.h | 75 + appmenu/menubar.cpp | 166 + appmenu/menubar.h | 87 + appmenu/menubutton.cpp | 85 + appmenu/menubutton.h | 54 + appmenu/menuimporter.cpp | 224 + appmenu/menuimporter.h | 98 + appmenu/menuwidget.cpp | 387 + appmenu/menuwidget.h | 143 + appmenu/org.kde.kded.appmenu.xml | 31 + appmenu/shadows.cpp | 381 + appmenu/shadows.h | 51 + appmenu/topmenubar.cpp | 176 + appmenu/topmenubar.h | 81 + appmenu/verticalmenu.cpp | 79 + appmenu/verticalmenu.h | 56 + cmake/CMakeLists.txt | 3 + cmake/modules/CMakeLists.txt | 17 + cmake/modules/COPYING-CMAKE-SCRIPTS | 22 + cmake/modules/FindCkConnector.cmake | 59 + cmake/modules/FindDBus.cmake | 72 + cmake/modules/FindLibXKlavier.cmake | 29 + cmake/modules/FindOpenGLES.cmake | 52 + cmake/modules/FindPAM.cmake | 74 + cmake/modules/FindPCIUTILS.cmake | 29 + cmake/modules/FindQJSON.cmake | 36 + cmake/modules/FindQalculate.cmake | 52 + cmake/modules/FindRAW1394.cmake | 20 + cmake/modules/FindSensors.cmake | 16 + cmake/modules/FindUDev.cmake | 19 + cmake/modules/FindWayland.cmake | 62 + cmake/modules/FindX11_XCB.cmake | 31 + cmake/modules/FindXCB.cmake | 123 + cmake/modules/PkgConfigGetVar.cmake | 32 + cmake/modules/UnixAuth.cmake | 55 + config-X11.h.cmake | 41 + config-unix.h.cmake | 35 + config-workspace.h.cmake | 159 + cursors/CMakeLists.txt | 13 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/KDE_Classic/cursors/X_cursor | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/all-scroll | 1 + .../KDE_Classic/cursors/bottom_left_corner | Bin 0 -> 1088 bytes .../KDE_Classic/cursors/bottom_right_corner | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/bottom_side | Bin 0 -> 1024 bytes cursors/KDE_Classic/cursors/center_ptr | Bin 0 -> 832 bytes cursors/KDE_Classic/cursors/closedhand | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/col-resize | 1 + cursors/KDE_Classic/cursors/cross | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/crossed_circle | 1 + cursors/KDE_Classic/cursors/crosshair | Bin 0 -> 1088 bytes .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/KDE_Classic/cursors/dnd-move | 1 + cursors/KDE_Classic/cursors/dnd-no-drop | 1 + cursors/KDE_Classic/cursors/dnd-none | 1 + cursors/KDE_Classic/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/KDE_Classic/cursors/fleur | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/forbidden | Bin 0 -> 1664 bytes cursors/KDE_Classic/cursors/half-busy | Bin 0 -> 4160 bytes cursors/KDE_Classic/cursors/hand1 | Bin 0 -> 896 bytes cursors/KDE_Classic/cursors/hand2 | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/help | Bin 0 -> 4160 bytes cursors/KDE_Classic/cursors/ibeam | Bin 0 -> 640 bytes cursors/KDE_Classic/cursors/left_ptr | Bin 0 -> 704 bytes cursors/KDE_Classic/cursors/left_ptr_watch | 1 + cursors/KDE_Classic/cursors/left_side | Bin 0 -> 1024 bytes cursors/KDE_Classic/cursors/move | 1 + cursors/KDE_Classic/cursors/n-resize | 1 + cursors/KDE_Classic/cursors/not-allowed | 1 + cursors/KDE_Classic/cursors/openhand | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/pirate | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/pointer | 1 + cursors/KDE_Classic/cursors/pointing_hand | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/progress | 1 + cursors/KDE_Classic/cursors/question_arrow | Bin 0 -> 768 bytes cursors/KDE_Classic/cursors/right_ptr | Bin 0 -> 704 bytes cursors/KDE_Classic/cursors/right_side | Bin 0 -> 1024 bytes cursors/KDE_Classic/cursors/row-resize | 1 + cursors/KDE_Classic/cursors/s-resize | 1 + cursors/KDE_Classic/cursors/sb_h_double_arrow | Bin 0 -> 604 bytes cursors/KDE_Classic/cursors/sb_v_double_arrow | Bin 0 -> 604 bytes cursors/KDE_Classic/cursors/size_all | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/size_bdiag | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/size_fdiag | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/size_hor | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/size_ver | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/split_h | Bin 0 -> 4160 bytes cursors/KDE_Classic/cursors/split_v | Bin 0 -> 4160 bytes cursors/KDE_Classic/cursors/text | 1 + cursors/KDE_Classic/cursors/top_left_corner | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/top_right_corner | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/top_side | Bin 0 -> 1024 bytes cursors/KDE_Classic/cursors/up_arrow | Bin 0 -> 832 bytes cursors/KDE_Classic/cursors/v_double_arrow | 1 + cursors/KDE_Classic/cursors/w-resize | 1 + cursors/KDE_Classic/cursors/wait | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/watch | Bin 0 -> 1088 bytes cursors/KDE_Classic/cursors/whats_this | 1 + cursors/KDE_Classic/cursors/xcursorconfig | 1 + cursors/KDE_Classic/cursors/xterm | Bin 0 -> 640 bytes cursors/KDE_Classic/index.theme | 3 + cursors/LICENSE | 165 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/03b6e0fcb3499374a867c041f52298f0 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/1081e37283d90000800003c07f3ef6bf | 1 + .../cursors/3085a0e285430894940527032f8b26df | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/6407b0e94181790501fd1e167b474872 | 1 + .../cursors/640fb0e74195791501fd1ed57b41487f | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/Oxygen_Black/cursors/X_cursor | Bin 0 -> 32416 bytes .../cursors/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/Oxygen_Black/cursors/alias | 1 + cursors/Oxygen_Black/cursors/all-scroll | 1 + .../cursors/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/Oxygen_Black/cursors/circle | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/closedhand | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/col-resize | 1 + cursors/Oxygen_Black/cursors/color-picker | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/copy | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/cross | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/crossed_circle | 1 + .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/Oxygen_Black/cursors/dnd-copy | 1 + cursors/Oxygen_Black/cursors/dnd-link | 1 + cursors/Oxygen_Black/cursors/dnd-move | 1 + cursors/Oxygen_Black/cursors/dnd-no-drop | 1 + cursors/Oxygen_Black/cursors/dnd-none | 1 + cursors/Oxygen_Black/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/Oxygen_Black/cursors/fleur | Bin 0 -> 57504 bytes cursors/Oxygen_Black/cursors/forbidden | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/half-busy | Bin 0 -> 1034800 bytes cursors/Oxygen_Black/cursors/hand1 | 1 + cursors/Oxygen_Black/cursors/hand2 | 1 + cursors/Oxygen_Black/cursors/help | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/ibeam | 1 + cursors/Oxygen_Black/cursors/left_ptr | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/left_ptr_watch | 1 + cursors/Oxygen_Black/cursors/link | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/move | 1 + cursors/Oxygen_Black/cursors/n-resize | 1 + cursors/Oxygen_Black/cursors/not-allowed | 1 + cursors/Oxygen_Black/cursors/openhand | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/pencil | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/pirate | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/plus | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/pointer | 1 + cursors/Oxygen_Black/cursors/pointing_hand | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/progress | 1 + cursors/Oxygen_Black/cursors/question_arrow | 1 + cursors/Oxygen_Black/cursors/row-resize | 1 + cursors/Oxygen_Black/cursors/s-resize | 1 + .../Oxygen_Black/cursors/sb_h_double_arrow | 1 + .../Oxygen_Black/cursors/sb_v_double_arrow | 1 + cursors/Oxygen_Black/cursors/size_all | 1 + cursors/Oxygen_Black/cursors/size_bdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/size_fdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/size_hor | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/size_ver | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/split_h | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/split_v | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/text | 1 + cursors/Oxygen_Black/cursors/up_arrow | Bin 0 -> 32416 bytes cursors/Oxygen_Black/cursors/v_double_arrow | 1 + cursors/Oxygen_Black/cursors/w-resize | 1 + cursors/Oxygen_Black/cursors/wait | Bin 0 -> 1034800 bytes cursors/Oxygen_Black/cursors/watch | 1 + cursors/Oxygen_Black/cursors/whats_this | 1 + cursors/Oxygen_Black/cursors/xterm | Bin 0 -> 32416 bytes cursors/Oxygen_Black/index.theme | 3 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/03b6e0fcb3499374a867c041f52298f0 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/1081e37283d90000800003c07f3ef6bf | 1 + .../cursors/3085a0e285430894940527032f8b26df | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/6407b0e94181790501fd1e167b474872 | 1 + .../cursors/640fb0e74195791501fd1ed57b41487f | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/Oxygen_Blue/cursors/X_cursor | Bin 0 -> 32416 bytes .../cursors/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/Oxygen_Blue/cursors/alias | 1 + cursors/Oxygen_Blue/cursors/all-scroll | 1 + .../cursors/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/Oxygen_Blue/cursors/circle | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/closedhand | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/col-resize | 1 + cursors/Oxygen_Blue/cursors/color-picker | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/copy | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/cross | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/crossed_circle | 1 + .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/Oxygen_Blue/cursors/dnd-copy | 1 + cursors/Oxygen_Blue/cursors/dnd-link | 1 + cursors/Oxygen_Blue/cursors/dnd-move | 1 + cursors/Oxygen_Blue/cursors/dnd-no-drop | 1 + cursors/Oxygen_Blue/cursors/dnd-none | 1 + cursors/Oxygen_Blue/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/Oxygen_Blue/cursors/fleur | Bin 0 -> 57504 bytes cursors/Oxygen_Blue/cursors/forbidden | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/half-busy | Bin 0 -> 1034800 bytes cursors/Oxygen_Blue/cursors/hand1 | 1 + cursors/Oxygen_Blue/cursors/hand2 | 1 + cursors/Oxygen_Blue/cursors/help | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/ibeam | 1 + cursors/Oxygen_Blue/cursors/left_ptr | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/left_ptr_watch | 1 + cursors/Oxygen_Blue/cursors/link | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/move | 1 + cursors/Oxygen_Blue/cursors/n-resize | 1 + cursors/Oxygen_Blue/cursors/not-allowed | 1 + cursors/Oxygen_Blue/cursors/openhand | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/pencil | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/pirate | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/plus | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/pointer | 1 + cursors/Oxygen_Blue/cursors/pointing_hand | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/progress | 1 + cursors/Oxygen_Blue/cursors/question_arrow | 1 + cursors/Oxygen_Blue/cursors/row-resize | 1 + cursors/Oxygen_Blue/cursors/s-resize | 1 + cursors/Oxygen_Blue/cursors/sb_h_double_arrow | 1 + cursors/Oxygen_Blue/cursors/sb_v_double_arrow | 1 + cursors/Oxygen_Blue/cursors/size_all | 1 + cursors/Oxygen_Blue/cursors/size_bdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/size_fdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/size_hor | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/size_ver | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/split_h | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/split_v | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/text | 1 + cursors/Oxygen_Blue/cursors/up_arrow | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/cursors/v_double_arrow | 1 + cursors/Oxygen_Blue/cursors/w-resize | 1 + cursors/Oxygen_Blue/cursors/wait | Bin 0 -> 1034800 bytes cursors/Oxygen_Blue/cursors/watch | 1 + cursors/Oxygen_Blue/cursors/whats_this | 1 + cursors/Oxygen_Blue/cursors/xterm | Bin 0 -> 32416 bytes cursors/Oxygen_Blue/index.theme | 3 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/03b6e0fcb3499374a867c041f52298f0 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/1081e37283d90000800003c07f3ef6bf | 1 + .../cursors/3085a0e285430894940527032f8b26df | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/6407b0e94181790501fd1e167b474872 | 1 + .../cursors/640fb0e74195791501fd1ed57b41487f | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/Oxygen_White/cursors/X_cursor | Bin 0 -> 32416 bytes .../cursors/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/Oxygen_White/cursors/alias | 1 + cursors/Oxygen_White/cursors/all-scroll | 1 + .../cursors/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/Oxygen_White/cursors/circle | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/closedhand | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/col-resize | 1 + cursors/Oxygen_White/cursors/color-picker | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/copy | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/cross | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/crossed_circle | 1 + .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/Oxygen_White/cursors/dnd-copy | 1 + cursors/Oxygen_White/cursors/dnd-link | 1 + cursors/Oxygen_White/cursors/dnd-move | 1 + cursors/Oxygen_White/cursors/dnd-no-drop | 1 + cursors/Oxygen_White/cursors/dnd-none | 1 + cursors/Oxygen_White/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/Oxygen_White/cursors/fleur | Bin 0 -> 57504 bytes cursors/Oxygen_White/cursors/forbidden | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/half-busy | Bin 0 -> 1034800 bytes cursors/Oxygen_White/cursors/hand1 | 1 + cursors/Oxygen_White/cursors/hand2 | 1 + cursors/Oxygen_White/cursors/help | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/ibeam | 1 + cursors/Oxygen_White/cursors/left_ptr | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/left_ptr_watch | 1 + cursors/Oxygen_White/cursors/link | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/move | 1 + cursors/Oxygen_White/cursors/n-resize | 1 + cursors/Oxygen_White/cursors/not-allowed | 1 + cursors/Oxygen_White/cursors/openhand | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/pencil | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/pirate | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/plus | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/pointer | 1 + cursors/Oxygen_White/cursors/pointing_hand | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/progress | 1 + cursors/Oxygen_White/cursors/question_arrow | 1 + cursors/Oxygen_White/cursors/row-resize | 1 + cursors/Oxygen_White/cursors/s-resize | 1 + .../Oxygen_White/cursors/sb_h_double_arrow | 1 + .../Oxygen_White/cursors/sb_v_double_arrow | 1 + cursors/Oxygen_White/cursors/size_all | 1 + cursors/Oxygen_White/cursors/size_bdiag | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/size_fdiag | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/size_hor | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/size_ver | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/split_h | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/split_v | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/text | 1 + cursors/Oxygen_White/cursors/up_arrow | Bin 0 -> 32416 bytes cursors/Oxygen_White/cursors/v_double_arrow | 1 + cursors/Oxygen_White/cursors/w-resize | 1 + cursors/Oxygen_White/cursors/wait | Bin 0 -> 1034800 bytes cursors/Oxygen_White/cursors/watch | 1 + cursors/Oxygen_White/cursors/whats_this | 1 + cursors/Oxygen_White/cursors/xterm | Bin 0 -> 32416 bytes cursors/Oxygen_White/index.theme | 3 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/03b6e0fcb3499374a867c041f52298f0 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/1081e37283d90000800003c07f3ef6bf | 1 + .../cursors/3085a0e285430894940527032f8b26df | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/6407b0e94181790501fd1e167b474872 | 1 + .../cursors/640fb0e74195791501fd1ed57b41487f | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/Oxygen_Yellow/cursors/X_cursor | Bin 0 -> 32416 bytes .../cursors/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/Oxygen_Yellow/cursors/alias | 1 + cursors/Oxygen_Yellow/cursors/all-scroll | 1 + .../cursors/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/Oxygen_Yellow/cursors/circle | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/closedhand | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/col-resize | 1 + cursors/Oxygen_Yellow/cursors/color-picker | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/copy | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/cross | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/crossed_circle | 1 + .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/Oxygen_Yellow/cursors/dnd-copy | 1 + cursors/Oxygen_Yellow/cursors/dnd-link | 1 + cursors/Oxygen_Yellow/cursors/dnd-move | 1 + cursors/Oxygen_Yellow/cursors/dnd-no-drop | 1 + cursors/Oxygen_Yellow/cursors/dnd-none | 1 + cursors/Oxygen_Yellow/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/Oxygen_Yellow/cursors/fleur | Bin 0 -> 57504 bytes cursors/Oxygen_Yellow/cursors/forbidden | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/half-busy | Bin 0 -> 1034800 bytes cursors/Oxygen_Yellow/cursors/hand1 | 1 + cursors/Oxygen_Yellow/cursors/hand2 | 1 + cursors/Oxygen_Yellow/cursors/help | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/ibeam | 1 + cursors/Oxygen_Yellow/cursors/left_ptr | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/left_ptr_watch | 1 + cursors/Oxygen_Yellow/cursors/link | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/move | 1 + cursors/Oxygen_Yellow/cursors/n-resize | 1 + cursors/Oxygen_Yellow/cursors/not-allowed | 1 + cursors/Oxygen_Yellow/cursors/openhand | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/pencil | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/pirate | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/plus | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/pointer | 1 + cursors/Oxygen_Yellow/cursors/pointing_hand | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/progress | 1 + cursors/Oxygen_Yellow/cursors/question_arrow | 1 + cursors/Oxygen_Yellow/cursors/row-resize | 1 + cursors/Oxygen_Yellow/cursors/s-resize | 1 + .../Oxygen_Yellow/cursors/sb_h_double_arrow | 1 + .../Oxygen_Yellow/cursors/sb_v_double_arrow | 1 + cursors/Oxygen_Yellow/cursors/size_all | 1 + cursors/Oxygen_Yellow/cursors/size_bdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/size_fdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/size_hor | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/size_ver | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/split_h | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/split_v | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/text | 1 + cursors/Oxygen_Yellow/cursors/up_arrow | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/cursors/v_double_arrow | 1 + cursors/Oxygen_Yellow/cursors/w-resize | 1 + cursors/Oxygen_Yellow/cursors/wait | Bin 0 -> 1034800 bytes cursors/Oxygen_Yellow/cursors/watch | 1 + cursors/Oxygen_Yellow/cursors/whats_this | 1 + cursors/Oxygen_Yellow/cursors/xterm | Bin 0 -> 32416 bytes cursors/Oxygen_Yellow/index.theme | 3 + .../cursors/00000000000000020006000e7e9ffc3f | 1 + .../cursors/00008160000006810000408080010102 | 1 + .../cursors/03b6e0fcb3499374a867c041f52298f0 | 1 + .../cursors/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../cursors/1081e37283d90000800003c07f3ef6bf | 1 + .../cursors/3085a0e285430894940527032f8b26df | 1 + .../cursors/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../cursors/4498f0e0c1937ffe01fd06f973665830 | 1 + .../cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../cursors/6407b0e94181790501fd1e167b474872 | 1 + .../cursors/640fb0e74195791501fd1ed57b41487f | 1 + .../cursors/9081237383d90e509aa00f00170e968f | 1 + .../cursors/9d800788f1b08800ae810202380a0822 | 1 + cursors/Oxygen_Zion/cursors/X_cursor | Bin 0 -> 32416 bytes .../cursors/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/Oxygen_Zion/cursors/alias | 1 + cursors/Oxygen_Zion/cursors/all-scroll | 1 + .../cursors/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/Oxygen_Zion/cursors/circle | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/closedhand | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/col-resize | 1 + cursors/Oxygen_Zion/cursors/color-picker | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/copy | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/cross | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/crossed_circle | 1 + .../cursors/d9ce0ab605698f320427677b458ad60b | 1 + cursors/Oxygen_Zion/cursors/dnd-copy | 1 + cursors/Oxygen_Zion/cursors/dnd-link | 1 + cursors/Oxygen_Zion/cursors/dnd-move | 1 + cursors/Oxygen_Zion/cursors/dnd-no-drop | 1 + cursors/Oxygen_Zion/cursors/dnd-none | 1 + cursors/Oxygen_Zion/cursors/e-resize | 1 + .../cursors/e29285e634086352946a0e7090d73106 | 1 + .../cursors/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/Oxygen_Zion/cursors/fleur | Bin 0 -> 57504 bytes cursors/Oxygen_Zion/cursors/forbidden | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/half-busy | Bin 0 -> 1034800 bytes cursors/Oxygen_Zion/cursors/hand1 | 1 + cursors/Oxygen_Zion/cursors/hand2 | 1 + cursors/Oxygen_Zion/cursors/help | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/ibeam | 1 + cursors/Oxygen_Zion/cursors/left_ptr | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/left_ptr_watch | 1 + cursors/Oxygen_Zion/cursors/link | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/move | 1 + cursors/Oxygen_Zion/cursors/n-resize | 1 + cursors/Oxygen_Zion/cursors/not-allowed | 1 + cursors/Oxygen_Zion/cursors/openhand | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/pencil | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/pirate | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/plus | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/pointer | 1 + cursors/Oxygen_Zion/cursors/pointing_hand | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/progress | 1 + cursors/Oxygen_Zion/cursors/question_arrow | 1 + cursors/Oxygen_Zion/cursors/row-resize | 1 + cursors/Oxygen_Zion/cursors/s-resize | 1 + cursors/Oxygen_Zion/cursors/sb_h_double_arrow | 1 + cursors/Oxygen_Zion/cursors/sb_v_double_arrow | 1 + cursors/Oxygen_Zion/cursors/size_all | 1 + cursors/Oxygen_Zion/cursors/size_bdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/size_fdiag | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/size_hor | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/size_ver | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/split_h | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/split_v | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/text | 1 + cursors/Oxygen_Zion/cursors/up_arrow | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/cursors/v_double_arrow | 1 + cursors/Oxygen_Zion/cursors/w-resize | 1 + cursors/Oxygen_Zion/cursors/wait | Bin 0 -> 1034800 bytes cursors/Oxygen_Zion/cursors/watch | 1 + cursors/Oxygen_Zion/cursors/whats_this | 1 + cursors/Oxygen_Zion/cursors/xterm | Bin 0 -> 32416 bytes cursors/Oxygen_Zion/index.theme | 3 + cursors/src/CMakeLists.txt | 49 + cursors/src/COPYING | 18 + cursors/src/LICENSE | 674 ++ cursors/src/README | 17 + cursors/src/TODO | 1 + cursors/src/config.cmake | 8 + cursors/src/config/Description | 5 + cursors/src/config/X_cursor.in | 1 + cursors/src/config/circle.in | 1 + cursors/src/config/closedhand.in | 1 + cursors/src/config/color-picker.in | 1 + cursors/src/config/copy.in | 1 + cursors/src/config/cross.in | 1 + cursors/src/config/fleur.in | 1 + cursors/src/config/forbidden.in | 1 + cursors/src/config/half-busy.in | 18 + cursors/src/config/help.in | 1 + cursors/src/config/left_ptr.in | 1 + cursors/src/config/link.in | 1 + cursors/src/config/openhand.in | 1 + cursors/src/config/pencil.in | 1 + cursors/src/config/pirate.in | 1 + cursors/src/config/plus.in | 1 + cursors/src/config/pointing_hand.in | 1 + cursors/src/config/size_bdiag.in | 1 + cursors/src/config/size_fdiag.in | 1 + cursors/src/config/size_hor.in | 1 + cursors/src/config/size_ver.in | 1 + cursors/src/config/split_h.in | 1 + cursors/src/config/split_v.in | 1 + cursors/src/config/up_arrow.in | 1 + cursors/src/config/wait.in | 18 + cursors/src/config/xterm.in | 1 + cursors/src/cursors.cmake | 120 + cursors/src/make_config.cmake | 33 + cursors/src/make_svg.cmake | 20 + cursors/src/setup.cmake | 32 + cursors/src/svg/busy.svg | 166 + cursors/src/svg/busy1.svg | 166 + cursors/src/svg/busy10.svg | 166 + cursors/src/svg/busy11.svg | 166 + cursors/src/svg/busy12.svg | 166 + cursors/src/svg/busy13.svg | 166 + cursors/src/svg/busy14.svg | 166 + cursors/src/svg/busy15.svg | 166 + cursors/src/svg/busy16.svg | 166 + cursors/src/svg/busy17.svg | 166 + cursors/src/svg/busy2.svg | 166 + cursors/src/svg/busy3.svg | 166 + cursors/src/svg/busy4.svg | 166 + cursors/src/svg/busy5.svg | 166 + cursors/src/svg/busy6.svg | 166 + cursors/src/svg/busy7.svg | 166 + cursors/src/svg/busy8.svg | 166 + cursors/src/svg/busy9.svg | 166 + cursors/src/svg/circle.svg | 333 + cursors/src/svg/copy.svg | 326 + cursors/src/svg/cross.svg | 112 + cursors/src/svg/dnd-move.svg | 717 ++ cursors/src/svg/fleur.svg | 393 + cursors/src/svg/forbidden.svg | 465 + cursors/src/svg/grab.svg | 185 + cursors/src/svg/grab_open.svg | 177 + cursors/src/svg/half-busy.svg | 270 + cursors/src/svg/half-busy1.svg | 270 + cursors/src/svg/half-busy10.svg | 271 + cursors/src/svg/half-busy11.svg | 271 + cursors/src/svg/half-busy12.svg | 250 + cursors/src/svg/half-busy13.svg | 250 + cursors/src/svg/half-busy14.svg | 271 + cursors/src/svg/half-busy15.svg | 271 + cursors/src/svg/half-busy16.svg | 271 + cursors/src/svg/half-busy17.svg | 271 + cursors/src/svg/half-busy2.svg | 249 + cursors/src/svg/half-busy3.svg | 249 + cursors/src/svg/half-busy4.svg | 270 + cursors/src/svg/half-busy5.svg | 271 + cursors/src/svg/half-busy6.svg | 271 + cursors/src/svg/half-busy7.svg | 271 + cursors/src/svg/half-busy8.svg | 271 + cursors/src/svg/half-busy9.svg | 271 + cursors/src/svg/hand.svg | 516 + cursors/src/svg/help.svg | 457 + cursors/src/svg/kill.svg | 399 + cursors/src/svg/left_ptr.svg | 170 + cursors/src/svg/link.svg | 321 + cursors/src/svg/pencil.svg | 200 + cursors/src/svg/picker.svg | 253 + cursors/src/svg/plus.svg | 799 ++ cursors/src/svg/size_diag-tl2br.svg | 569 + cursors/src/svg/size_diag-tr2bl.svg | 573 + cursors/src/svg/size_hor.svg | 570 + cursors/src/svg/size_ver.svg | 220 + cursors/src/svg/split_h.svg | 225 + cursors/src/svg/split_v.svg | 226 + cursors/src/svg/up_arrow.svg | 205 + cursors/src/svg/x.svg | 1130 ++ cursors/src/svg/xterm.svg | 165 + cursors/src/symlinks/.directory | 5 + .../symlinks/00000000000000020006000e7e9ffc3f | 1 + .../symlinks/00008160000006810000408080010102 | 1 + .../symlinks/03b6e0fcb3499374a867c041f52298f0 | 1 + .../symlinks/08e8e1c95fe2fc01f976f1e063a24ccd | 1 + .../symlinks/1081e37283d90000800003c07f3ef6bf | 1 + .../symlinks/3085a0e285430894940527032f8b26df | 1 + .../symlinks/3ecb610c1bf2410f44200f48c40d3599 | 1 + .../symlinks/4498f0e0c1937ffe01fd06f973665830 | 1 + .../symlinks/5c6cd98b3f3ebcb1f9c7f1c204630408 | 1 + .../symlinks/6407b0e94181790501fd1e167b474872 | 1 + .../symlinks/640fb0e74195791501fd1ed57b41487f | 1 + .../symlinks/9081237383d90e509aa00f00170e968f | 1 + .../symlinks/9d800788f1b08800ae810202380a0822 | 1 + .../symlinks/a2a266d0498c3104214a47bd64ab0fc8 | 1 + cursors/src/symlinks/alias | 1 + cursors/src/symlinks/all-scroll | 1 + .../symlinks/b66166c04f8c3109214a4fbd64a50fc8 | 1 + cursors/src/symlinks/col-resize | 1 + cursors/src/symlinks/crossed_circle | 1 + .../symlinks/d9ce0ab605698f320427677b458ad60b | 1 + cursors/src/symlinks/dnd-copy | 1 + cursors/src/symlinks/dnd-link | 1 + cursors/src/symlinks/dnd-move | 1 + cursors/src/symlinks/dnd-no-drop | 1 + cursors/src/symlinks/dnd-none | 1 + cursors/src/symlinks/e-resize | 1 + .../symlinks/e29285e634086352946a0e7090d73106 | 1 + .../symlinks/fcf21c00b30f7e3f83fe0dfd12e71cff | 1 + cursors/src/symlinks/hand1 | 1 + cursors/src/symlinks/hand2 | 1 + cursors/src/symlinks/ibeam | 1 + cursors/src/symlinks/left_ptr_watch | 1 + cursors/src/symlinks/move | 1 + cursors/src/symlinks/n-resize | 1 + cursors/src/symlinks/not-allowed | 1 + cursors/src/symlinks/pointer | 1 + cursors/src/symlinks/progress | 1 + cursors/src/symlinks/question_arrow | 1 + cursors/src/symlinks/row-resize | 1 + cursors/src/symlinks/s-resize | 1 + cursors/src/symlinks/sb_h_double_arrow | 1 + cursors/src/symlinks/sb_v_double_arrow | 1 + cursors/src/symlinks/size_all | 1 + cursors/src/symlinks/text | 1 + cursors/src/symlinks/v_double_arrow | 1 + cursors/src/symlinks/w-resize | 1 + cursors/src/symlinks/watch | 1 + cursors/src/symlinks/whats_this | 1 + cursors/src/theme-black/CMakeLists.txt | 1 + cursors/src/theme-black/colors.in | 3 + cursors/src/theme-black/index.theme | 3 + cursors/src/theme-blue/CMakeLists.txt | 1 + cursors/src/theme-blue/colors.in | 3 + cursors/src/theme-blue/index.theme | 3 + cursors/src/theme-bluecurve/CMakeLists.txt | 1 + cursors/src/theme-bluecurve/colors.in | 3 + cursors/src/theme-bluecurve/index.theme | 3 + cursors/src/theme-brown/CMakeLists.txt | 1 + cursors/src/theme-brown/colors.in | 3 + cursors/src/theme-brown/index.theme | 3 + cursors/src/theme-cherry/CMakeLists.txt | 1 + cursors/src/theme-cherry/colors.in | 6 + cursors/src/theme-cherry/index.theme | 3 + cursors/src/theme-chrome/CMakeLists.txt | 1 + cursors/src/theme-chrome/colors.in | 6 + cursors/src/theme-chrome/index.theme | 3 + cursors/src/theme-desert/CMakeLists.txt | 1 + cursors/src/theme-desert/colors.in | 6 + cursors/src/theme-desert/index.theme | 3 + cursors/src/theme-emerald/CMakeLists.txt | 1 + cursors/src/theme-emerald/colors.in | 3 + cursors/src/theme-emerald/index.theme | 3 + cursors/src/theme-green/CMakeLists.txt | 1 + cursors/src/theme-green/colors.in | 3 + cursors/src/theme-green/index.theme | 3 + cursors/src/theme-grey/CMakeLists.txt | 1 + cursors/src/theme-grey/colors.in | 3 + cursors/src/theme-grey/index.theme | 3 + cursors/src/theme-honeycomb/CMakeLists.txt | 1 + cursors/src/theme-honeycomb/colors.in | 6 + cursors/src/theme-honeycomb/index.theme | 3 + cursors/src/theme-hot_orange/CMakeLists.txt | 1 + cursors/src/theme-hot_orange/colors.in | 3 + cursors/src/theme-hot_orange/index.theme | 3 + cursors/src/theme-lilac/CMakeLists.txt | 1 + cursors/src/theme-lilac/colors.in | 6 + cursors/src/theme-lilac/index.theme | 3 + .../src/theme-midnight_meadow/CMakeLists.txt | 1 + cursors/src/theme-midnight_meadow/colors.in | 3 + cursors/src/theme-midnight_meadow/index.theme | 3 + cursors/src/theme-navy/CMakeLists.txt | 1 + cursors/src/theme-navy/colors.in | 3 + cursors/src/theme-navy/index.theme | 3 + cursors/src/theme-norway/CMakeLists.txt | 1 + cursors/src/theme-norway/colors.in | 6 + cursors/src/theme-norway/index.theme | 3 + cursors/src/theme-obsidian-hc/CMakeLists.txt | 1 + cursors/src/theme-obsidian-hc/colors.in | 6 + cursors/src/theme-obsidian-hc/index.theme | 3 + cursors/src/theme-obsidian/CMakeLists.txt | 1 + cursors/src/theme-obsidian/colors.in | 6 + cursors/src/theme-obsidian/index.theme | 3 + cursors/src/theme-olympus-inv/CMakeLists.txt | 1 + cursors/src/theme-olympus-inv/colors.in | 3 + cursors/src/theme-olympus-inv/index.theme | 3 + cursors/src/theme-olympus/CMakeLists.txt | 1 + cursors/src/theme-olympus/colors.in | 3 + cursors/src/theme-olympus/index.theme | 3 + cursors/src/theme-orchid/CMakeLists.txt | 1 + cursors/src/theme-orchid/colors.in | 6 + cursors/src/theme-orchid/index.theme | 3 + cursors/src/theme-oxygen/CMakeLists.txt | 1 + cursors/src/theme-oxygen/colors.in | 6 + cursors/src/theme-oxygen/index.theme | 3 + cursors/src/theme-peach/CMakeLists.txt | 1 + cursors/src/theme-peach/colors.in | 6 + cursors/src/theme-peach/index.theme | 3 + cursors/src/theme-purple/CMakeLists.txt | 1 + cursors/src/theme-purple/colors.in | 3 + cursors/src/theme-purple/index.theme | 3 + .../src/theme-red-argentina/CMakeLists.txt | 1 + cursors/src/theme-red-argentina/colors.in | 3 + cursors/src/theme-red-argentina/index.theme | 3 + cursors/src/theme-red/CMakeLists.txt | 1 + cursors/src/theme-red/colors.in | 3 + cursors/src/theme-red/index.theme | 3 + cursors/src/theme-sea_blue/CMakeLists.txt | 1 + cursors/src/theme-sea_blue/colors.in | 3 + cursors/src/theme-sea_blue/index.theme | 3 + cursors/src/theme-steel/CMakeLists.txt | 1 + cursors/src/theme-steel/colors.in | 6 + cursors/src/theme-steel/index.theme | 3 + cursors/src/theme-terra/CMakeLists.txt | 1 + cursors/src/theme-terra/colors.in | 6 + cursors/src/theme-terra/index.theme | 3 + cursors/src/theme-terra_green/CMakeLists.txt | 1 + cursors/src/theme-terra_green/colors.in | 6 + cursors/src/theme-terra_green/index.theme | 3 + cursors/src/theme-violet/CMakeLists.txt | 1 + cursors/src/theme-violet/colors.in | 3 + cursors/src/theme-violet/index.theme | 3 + cursors/src/theme-viorange/CMakeLists.txt | 1 + cursors/src/theme-viorange/colors.in | 3 + cursors/src/theme-viorange/index.theme | 3 + cursors/src/theme-white/CMakeLists.txt | 1 + cursors/src/theme-white/colors.in | 3 + cursors/src/theme-white/index.theme | 3 + cursors/src/theme-whitewater/CMakeLists.txt | 1 + cursors/src/theme-whitewater/colors.in | 6 + cursors/src/theme-whitewater/index.theme | 3 + cursors/src/theme-wonton/CMakeLists.txt | 1 + cursors/src/theme-wonton/colors.in | 6 + cursors/src/theme-wonton/index.theme | 3 + cursors/src/theme-yellow/CMakeLists.txt | 1 + cursors/src/theme-yellow/colors.in | 3 + cursors/src/theme-yellow/index.theme | 3 + cursors/src/theme-zion/CMakeLists.txt | 1 + cursors/src/theme-zion/colors.in | 3 + cursors/src/theme-zion/index.theme | 3 + cursors/src/theme.cmake | 2 + cursors/src/wincursor.py | 50 + doc/CMakeLists.txt | 12 + doc/PolicyKit-kde/CMakeLists.txt | 1 + doc/PolicyKit-kde/authdialog_1.png | Bin 0 -> 35345 bytes doc/PolicyKit-kde/authdialog_2.png | Bin 0 -> 27268 bytes doc/PolicyKit-kde/authdialog_3.png | Bin 0 -> 30019 bytes doc/PolicyKit-kde/authdialog_4.png | Bin 0 -> 33101 bytes doc/PolicyKit-kde/authdialog_5.png | Bin 0 -> 29978 bytes doc/PolicyKit-kde/authdialog_6.png | Bin 0 -> 28962 bytes doc/PolicyKit-kde/authorization.docbook | 112 + doc/PolicyKit-kde/authorization_1.png | Bin 0 -> 101385 bytes doc/PolicyKit-kde/authorization_2.png | Bin 0 -> 49686 bytes doc/PolicyKit-kde/authorizationagent.docbook | 120 + doc/PolicyKit-kde/howitworks.docbook | 53 + doc/PolicyKit-kde/index.docbook | 88 + doc/PolicyKit-kde/introduction.docbook | 28 + doc/kcontrol/CMakeLists.txt | 32 + doc/kcontrol/autostart/CMakeLists.txt | 3 + doc/kcontrol/autostart/index.docbook | 183 + doc/kcontrol/bell/CMakeLists.txt | 2 + doc/kcontrol/bell/index.docbook | 64 + doc/kcontrol/clock/CMakeLists.txt | 2 + doc/kcontrol/clock/index.docbook | 90 + doc/kcontrol/colors/CMakeLists.txt | 2 + doc/kcontrol/colors/index.docbook | 399 + doc/kcontrol/cursortheme/CMakeLists.txt | 2 + doc/kcontrol/cursortheme/index.docbook | 59 + doc/kcontrol/desktop/CMakeLists.txt | 2 + doc/kcontrol/desktop/index.docbook | 141 + .../desktopthemedetails/CMakeLists.txt | 3 + .../desktopthemedetails/clicking-apply.png | Bin 0 -> 124555 bytes .../desktopthemedetails/customizing.png | Bin 0 -> 128220 bytes .../desktopthemedetails/index.docbook | 182 + doc/kcontrol/fontinst/CMakeLists.txt | 2 + doc/kcontrol/fontinst/index.docbook | 109 + doc/kcontrol/fonts/CMakeLists.txt | 2 + doc/kcontrol/fonts/adjust-all.png | Bin 0 -> 32155 bytes doc/kcontrol/fonts/anti-aliasing.png | Bin 0 -> 21340 bytes doc/kcontrol/fonts/index.docbook | 169 + doc/kcontrol/fonts/main.png | Bin 0 -> 33765 bytes doc/kcontrol/joystick/CMakeLists.txt | 3 + doc/kcontrol/joystick/index.docbook | 137 + .../joystick/joystick-calibration.png | Bin 0 -> 25142 bytes doc/kcontrol/joystick/joystick-main.png | Bin 0 -> 45306 bytes doc/kcontrol/kcmaccess/CMakeLists.txt | 4 + doc/kcontrol/kcmaccess/index.docbook | 264 + doc/kcontrol/kcmsmserver/CMakeLists.txt | 3 + doc/kcontrol/kcmsmserver/index.docbook | 122 + doc/kcontrol/kcmstyle/CMakeLists.txt | 2 + doc/kcontrol/kcmstyle/index.docbook | 238 + doc/kcontrol/keyboard/CMakeLists.txt | 2 + doc/kcontrol/keyboard/index.docbook | 218 + doc/kcontrol/keys/CMakeLists.txt | 2 + doc/kcontrol/keys/index.docbook | 202 + doc/kcontrol/khotkeys/CMakeLists.txt | 2 + doc/kcontrol/khotkeys/groups-comment.png | Bin 0 -> 63546 bytes doc/kcontrol/khotkeys/index.docbook | 751 ++ doc/kcontrol/khotkeys/manage-export.png | Bin 0 -> 68149 bytes ...xygen-22x22-edit-clear-locationbar-rtl.png | Bin 0 -> 859 bytes doc/kcontrol/khotkeys/settings.png | Bin 0 -> 56454 bytes .../khotkeys/shortcuts-action-command.png | Bin 0 -> 64061 bytes .../khotkeys/shortcuts-action-keyboard.png | Bin 0 -> 70165 bytes .../khotkeys/shortcuts-trigger-keyboard.png | Bin 0 -> 63851 bytes .../khotkeys/shortcuts-trigger-mouse.png | Bin 0 -> 63226 bytes doc/kcontrol/kwincompositing/CMakeLists.txt | 2 + doc/kcontrol/kwincompositing/index.docbook | 82 + doc/kcontrol/kwindecoration/CMakeLists.txt | 2 + doc/kcontrol/kwindecoration/buttons.png | Bin 0 -> 38993 bytes doc/kcontrol/kwindecoration/decoration.png | Bin 0 -> 41641 bytes doc/kcontrol/kwindecoration/index.docbook | 150 + doc/kcontrol/kwindecoration/main.png | Bin 0 -> 78857 bytes doc/kcontrol/kwinscreenedges/CMakeLists.txt | 2 + doc/kcontrol/kwinscreenedges/index.docbook | 69 + doc/kcontrol/kwintabbox/CMakeLists.txt | 2 + doc/kcontrol/kwintabbox/index.docbook | 101 + doc/kcontrol/mouse/CMakeLists.txt | 2 + doc/kcontrol/mouse/index.docbook | 472 + doc/kcontrol/paths/CMakeLists.txt | 2 + doc/kcontrol/paths/index.docbook | 91 + doc/kcontrol/paths/paths.png | Bin 0 -> 11152 bytes doc/kcontrol/powerdevil/CMakeLists.txt | 3 + doc/kcontrol/powerdevil/activity.png | Bin 0 -> 60677 bytes doc/kcontrol/powerdevil/advanced.png | Bin 0 -> 53231 bytes doc/kcontrol/powerdevil/energy.png | Bin 0 -> 68729 bytes doc/kcontrol/powerdevil/index.docbook | 317 + doc/kcontrol/screensaver/CMakeLists.txt | 2 + doc/kcontrol/screensaver/index.docbook | 110 + doc/kcontrol/solid-actions/CMakeLists.txt | 3 + doc/kcontrol/solid-actions/add-action.png | Bin 0 -> 13822 bytes doc/kcontrol/solid-actions/edit-action.png | Bin 0 -> 49373 bytes doc/kcontrol/solid-actions/index.docbook | 222 + doc/kcontrol/solid-actions/main.png | Bin 0 -> 65245 bytes doc/kcontrol/splashscreen/CMakeLists.txt | 3 + doc/kcontrol/splashscreen/get-new-theme.png | Bin 0 -> 67741 bytes doc/kcontrol/splashscreen/index.docbook | 117 + doc/kcontrol/splashscreen/splash-main.png | Bin 0 -> 66684 bytes doc/kcontrol/windowbehaviour/CMakeLists.txt | 2 + doc/kcontrol/windowbehaviour/index.docbook | 676 ++ doc/kcontrol/windowspecific/CMakeLists.txt | 2 + doc/kcontrol/windowspecific/Face-smile.png | Bin 0 -> 1233 bytes .../windowspecific/akgregator-info.png | Bin 0 -> 12229 bytes .../windowspecific/akregator-attributes.png | Bin 0 -> 41221 bytes doc/kcontrol/windowspecific/akregator-fav.png | Bin 0 -> 135895 bytes .../windowspecific/config-win-behavior.png | Bin 0 -> 31261 bytes .../windowspecific/emacs-attribute.png | Bin 0 -> 40513 bytes doc/kcontrol/windowspecific/emacs-info.png | Bin 0 -> 12201 bytes .../focus-stealing-pop2top-attribute.png | Bin 0 -> 35461 bytes doc/kcontrol/windowspecific/index.docbook | 1025 ++ .../windowspecific/knotes-attribute.png | Bin 0 -> 35132 bytes doc/kcontrol/windowspecific/knotes-info.png | Bin 0 -> 12304 bytes .../windowspecific/kopete-attribute-2.png | Bin 0 -> 35206 bytes .../windowspecific/kopete-chat-attribute.png | Bin 0 -> 35186 bytes .../windowspecific/kopete-chat-info.png | Bin 0 -> 12436 bytes doc/kcontrol/windowspecific/kopete-info.png | Bin 0 -> 12195 bytes .../windowspecific/kwin-detect-window.png | Bin 0 -> 35258 bytes .../windowspecific/kwin-kopete-rules.png | Bin 0 -> 86327 bytes .../windowspecific/kwin-rule-editor.png | Bin 0 -> 54825 bytes .../kwin-rules-main-n-akregator.png | Bin 0 -> 30897 bytes .../windowspecific/kwin-rules-main.png | Bin 0 -> 31500 bytes .../windowspecific/kwin-rules-ordering.png | Bin 0 -> 50306 bytes .../windowspecific/kwin-window-attributes.png | Bin 0 -> 72244 bytes .../windowspecific/kwin-window-matching.png | Bin 0 -> 53362 bytes .../windowspecific/pager-4-desktops.png | Bin 0 -> 11817 bytes .../tbird-compose-attribute.png | Bin 0 -> 35452 bytes .../windowspecific/tbird-compose-info.png | Bin 0 -> 12719 bytes .../windowspecific/tbird-main-attribute.png | Bin 0 -> 40818 bytes .../windowspecific/tbird-main-info.png | Bin 0 -> 17472 bytes .../tbird-reminder-attribute-2.png | Bin 0 -> 35434 bytes .../windowspecific/tbird-reminder-info.png | Bin 0 -> 12756 bytes .../windowspecific/window-matching-emacs.png | Bin 0 -> 24891 bytes .../windowspecific/window-matching-init.png | Bin 0 -> 24334 bytes .../windowspecific/window-matching-knotes.png | Bin 0 -> 24579 bytes .../window-matching-kopete-chat.png | Bin 0 -> 24781 bytes .../windowspecific/window-matching-kopete.png | Bin 0 -> 24894 bytes .../window-matching-ready-akregator.png | Bin 0 -> 24812 bytes .../window-matching-tbird-compose.png | Bin 0 -> 24221 bytes .../window-matching-tbird-main.png | Bin 0 -> 24981 bytes .../window-matching-tbird-reminder.png | Bin 0 -> 24482 bytes doc/kcontrol/workspaceoptions/CMakeLists.txt | 2 + doc/kcontrol/workspaceoptions/index.docbook | 104 + doc/kdm/CMakeLists.txt | 6 + doc/kdm/index.docbook | 1786 +++ doc/kdm/kdmrc-ref.docbook | 2402 ++++ doc/kdm/theme-ref.docbook | 1348 +++ doc/kfontview/CMakeLists.txt | 1 + doc/kfontview/index.docbook | 124 + doc/kfontview/kfontview.png | Bin 0 -> 66103 bytes doc/kinfocenter/CMakeLists.txt | 1 + doc/kinfocenter/index.docbook | 931 ++ doc/kinfocenter/kinfocenter.png | Bin 0 -> 110663 bytes doc/kinfocenter/os_block.png | Bin 0 -> 15147 bytes doc/kinfocenter/pro_block.png | Bin 0 -> 11168 bytes doc/kinfocenter/sto_block.png | Bin 0 -> 10708 bytes doc/klipper/CMakeLists.txt | 4 + doc/klipper/index.docbook | 532 + doc/klipper/screenshot.png | Bin 0 -> 807 bytes doc/kmenuedit/CMakeLists.txt | 3 + doc/kmenuedit/done.png | Bin 0 -> 78661 bytes doc/kmenuedit/index.docbook | 645 ++ doc/kmenuedit/itemname.png | Bin 0 -> 19030 bytes doc/kmenuedit/new.png | Bin 0 -> 13473 bytes doc/kmenuedit/reset.png | Bin 0 -> 627 bytes doc/kmenuedit/selecticon.png | Bin 0 -> 65957 bytes doc/kmenuedit/selectinternet.png | Bin 0 -> 26896 bytes doc/ksysguard/CMakeLists.txt | 4 + doc/ksysguard/index.docbook | 533 + doc/plasma-desktop/CMakeLists.txt | 5 + doc/plasma-desktop/add-widgets.png | Bin 0 -> 28524 bytes doc/plasma-desktop/desktop-settings.png | Bin 0 -> 96709 bytes doc/plasma-desktop/device_notifier_widget.png | Bin 0 -> 38856 bytes .../device_notifier_widget_actions.png | Bin 0 -> 41041 bytes doc/plasma-desktop/index.docbook | 642 ++ doc/plasma-desktop/panel-settings.png | Bin 0 -> 35520 bytes .../plasma-desktop-annotated.png | Bin 0 -> 387050 bytes doc/plasma-desktop/system-tray-settings.png | Bin 0 -> 44856 bytes doc/plasma-desktop/system-tray-up-arrow.png | Bin 0 -> 428 bytes doc/plasma-desktop/taskbar-settings.png | Bin 0 -> 47842 bytes doc/systemsettings/CMakeLists.txt | 4 + doc/systemsettings/index.docbook | 473 + freespacenotifier/CMakeLists.txt | 28 + freespacenotifier/COPYING | 346 + freespacenotifier/Messages.sh | 3 + freespacenotifier/README | 3 + freespacenotifier/freespacenotifier.cpp | 182 + freespacenotifier/freespacenotifier.desktop | 131 + freespacenotifier/freespacenotifier.h | 52 + freespacenotifier/freespacenotifier.kcfg | 19 + freespacenotifier/freespacenotifier.notifyrc | 423 + .../freespacenotifier_prefs_base.ui | 91 + freespacenotifier/module.cpp | 36 + freespacenotifier/module.h | 39 + freespacenotifier/settings.kcfgc | 6 + kcheckpass/CMakeLists.txt | 31 + kcheckpass/README | 50 + kcheckpass/checkpass_aix.c | 95 + kcheckpass/checkpass_etcpasswd.c | 61 + kcheckpass/checkpass_osfc2passwd.c | 204 + kcheckpass/checkpass_pam.c | 204 + kcheckpass/checkpass_shadow.c | 86 + kcheckpass/config-kcheckpass.h.cmake | 3 + kcheckpass/kcheckpass-enums.h | 70 + kcheckpass/kcheckpass.c | 458 + kcheckpass/kcheckpass.h | 123 + kcminit/CMakeLists.txt | 26 + kcminit/Messages.sh | 2 + kcminit/main.cpp | 270 + kcminit/main.h | 47 + kcontrol/CMakeLists.txt | 52 + kcontrol/PURPOSE | 10 + kcontrol/access/CMakeLists.txt | 33 + kcontrol/access/Messages.sh | 4 + kcontrol/access/kaccess.cpp | 918 ++ kcontrol/access/kaccess.desktop | 97 + kcontrol/access/kaccess.h | 115 + kcontrol/access/kaccess.notifyrc | 1532 +++ kcontrol/access/kcmaccess.cpp | 783 ++ kcontrol/access/kcmaccess.desktop | 237 + kcontrol/access/kcmaccess.h | 76 + kcontrol/access/main.cpp | 52 + kcontrol/autostart/AUTHORS | 2 + kcontrol/autostart/CMakeLists.txt | 25 + kcontrol/autostart/Messages.sh | 4 + kcontrol/autostart/addscriptdialog.cpp | 103 + kcontrol/autostart/addscriptdialog.h | 56 + kcontrol/autostart/advanceddialog.cpp | 51 + kcontrol/autostart/advanceddialog.h | 40 + kcontrol/autostart/autostart.cpp | 440 + kcontrol/autostart/autostart.desktop | 190 + kcontrol/autostart/autostart.h | 75 + kcontrol/autostart/autostartconfig.ui | 82 + kcontrol/autostart/autostartitem.cpp | 111 + kcontrol/autostart/autostartitem.h | 75 + kcontrol/bell/CMakeLists.txt | 21 + kcontrol/bell/Messages.sh | 2 + kcontrol/bell/bell.cpp | 253 + kcontrol/bell/bell.desktop | 239 + kcontrol/bell/bell.h | 53 + kcontrol/colors/CMakeLists.txt | 16 + kcontrol/colors/Messages.sh | 4 + kcontrol/colors/README.i18n | 54 + kcontrol/colors/TODO | 3 + kcontrol/colors/colors.desktop | 194 + kcontrol/colors/colorschemes.knsrc | 6 + kcontrol/colors/colorscm.cpp | 1469 +++ kcontrol/colors/colorscm.h | 216 + kcontrol/colors/colorsettings.ui | 1298 +++ kcontrol/colors/preview.ui | 336 + kcontrol/colors/previewwidget.cpp | 168 + kcontrol/colors/previewwidget.h | 49 + kcontrol/colors/schemes/Honeycomb.colors | 96 + kcontrol/colors/schemes/Norway.colors | 96 + kcontrol/colors/schemes/ObsidianCoast.colors | 95 + kcontrol/colors/schemes/Oxygen.colors | 103 + kcontrol/colors/schemes/OxygenCold.colors | 95 + kcontrol/colors/schemes/Steel.colors | 95 + kcontrol/colors/schemes/WontonSoup.colors | 94 + kcontrol/colors/schemes/Zion.colors | 96 + kcontrol/colors/schemes/ZionReversed.colors | 96 + kcontrol/colors/setpreview.ui | 347 + kcontrol/colors/setpreviewwidget.cpp | 138 + kcontrol/colors/setpreviewwidget.h | 49 + kcontrol/dateandtime/CMakeLists.txt | 24 + kcontrol/dateandtime/Messages.sh | 3 + kcontrol/dateandtime/clock.desktop | 196 + kcontrol/dateandtime/dateandtime.ui | 198 + kcontrol/dateandtime/dtime.cpp | 463 + kcontrol/dateandtime/dtime.h | 121 + kcontrol/dateandtime/helper.cpp | 266 + kcontrol/dateandtime/helper.h | 51 + kcontrol/dateandtime/kcmclock_actions.actions | 209 + kcontrol/dateandtime/main.cpp | 122 + kcontrol/dateandtime/main.h | 47 + kcontrol/desktoppaths/CMakeLists.txt | 12 + kcontrol/desktoppaths/Messages.sh | 2 + kcontrol/desktoppaths/desktoppath.desktop | 236 + kcontrol/desktoppaths/globalpaths.cpp | 419 + kcontrol/desktoppaths/globalpaths.h | 84 + kcontrol/desktoppaths/kcmdesktoppaths.cpp | 29 + kcontrol/desktoppaths/kcmdesktoppaths.h | 27 + kcontrol/desktoptheme/CMakeLists.txt | 16 + kcontrol/desktoptheme/DesktopTheme.ui | 81 + kcontrol/desktoptheme/DesktopThemeDetails.ui | 395 + kcontrol/desktoptheme/Messages.sh | 4 + kcontrol/desktoptheme/desktoptheme.desktop | 187 + kcontrol/desktoptheme/desktopthemedetails.cpp | 582 + kcontrol/desktoptheme/desktopthemedetails.h | 68 + kcontrol/desktoptheme/kcmdesktoptheme.cpp | 183 + kcontrol/desktoptheme/kcmdesktoptheme.h | 71 + kcontrol/desktoptheme/thememodel.cpp | 209 + kcontrol/desktoptheme/thememodel.h | 87 + kcontrol/fonts/CMakeLists.txt | 35 + kcontrol/fonts/Messages.sh | 2 + kcontrol/fonts/fonts.cpp | 851 ++ kcontrol/fonts/fonts.desktop | 239 + kcontrol/fonts/fonts.h | 127 + kcontrol/fonts/kxftconfig.cpp | 847 ++ kcontrol/fonts/kxftconfig.h | 167 + kcontrol/hardware/CMakeLists.txt | 9 + kcontrol/hardware/display/CMakeLists.txt | 19 + kcontrol/hardware/display/Messages.sh | 2 + kcontrol/hardware/display/display.cpp | 118 + kcontrol/hardware/display/display.desktop | 187 + kcontrol/hardware/display/display.h | 48 + kcontrol/hardware/joystick/CMakeLists.txt | 26 + kcontrol/hardware/joystick/Messages.sh | 2 + kcontrol/hardware/joystick/caldialog.cpp | 200 + kcontrol/hardware/joystick/caldialog.h | 54 + kcontrol/hardware/joystick/joydevice.cpp | 402 + kcontrol/hardware/joystick/joydevice.h | 117 + kcontrol/hardware/joystick/joystick.cpp | 98 + kcontrol/hardware/joystick/joystick.desktop | 226 + kcontrol/hardware/joystick/joystick.h | 46 + kcontrol/hardware/joystick/joywidget.cpp | 418 + kcontrol/hardware/joystick/joywidget.h | 79 + kcontrol/hardware/joystick/poswidget.cpp | 133 + kcontrol/hardware/joystick/poswidget.h | 54 + kcontrol/input/AUTHORS | 7 + kcontrol/input/CMakeLists.txt | 107 + kcontrol/input/ChangeLog | 11 + kcontrol/input/Messages.sh | 4 + kcontrol/input/config-kcontrol-input.h.cmake | 3 + kcontrol/input/consoleUserPerms | 42 + kcontrol/input/core/bitmaps.h | 147 + kcontrol/input/core/themepage.cpp | 225 + kcontrol/input/core/themepage.h | 54 + kcontrol/input/cursor_large.bdf | 4447 ++++++++ kcontrol/input/cursor_large_black.pcf.gz | Bin 0 -> 3339 bytes kcontrol/input/cursor_large_white.pcf.gz | Bin 0 -> 3521 bytes kcontrol/input/cursor_small_white.pcf.gz | Bin 0 -> 3524 bytes kcontrol/input/cursortheme.desktop | 167 + kcontrol/input/kapplymousetheme.cpp | 91 + kcontrol/input/kcmcursortheme.cpp | 69 + kcontrol/input/kcmcursortheme.h | 42 + kcontrol/input/kmousedlg.ui | 295 + kcontrol/input/logitechmouse.cpp | 421 + kcontrol/input/logitechmouse.h | 107 + kcontrol/input/logitechmouse.usermap | 35 + kcontrol/input/logitechmouse_base.ui | 134 + kcontrol/input/main.cpp | 91 + kcontrol/input/mouse.cpp | 821 ++ kcontrol/input/mouse.desktop | 237 + kcontrol/input/mouse.h | 160 + kcontrol/input/pics/CMakeLists.txt | 1 + kcontrol/input/pics/mouse_lh.png | Bin 0 -> 10704 bytes kcontrol/input/pics/mouse_lh.svgz | Bin 0 -> 4614 bytes kcontrol/input/pics/mouse_rh.png | Bin 0 -> 10793 bytes kcontrol/input/pics/mouse_rh.svgz | Bin 0 -> 4528 bytes kcontrol/input/xcursor/cursortheme.cpp | 155 + kcontrol/input/xcursor/cursortheme.h | 143 + kcontrol/input/xcursor/itemdelegate.cpp | 174 + kcontrol/input/xcursor/itemdelegate.h | 42 + kcontrol/input/xcursor/previewwidget.cpp | 229 + kcontrol/input/xcursor/previewwidget.h | 51 + kcontrol/input/xcursor/sortproxymodel.cpp | 50 + kcontrol/input/xcursor/sortproxymodel.h | 77 + kcontrol/input/xcursor/thememodel.cpp | 413 + kcontrol/input/xcursor/thememodel.h | 114 + kcontrol/input/xcursor/themepage.cpp | 581 + kcontrol/input/xcursor/themepage.h | 99 + kcontrol/input/xcursor/themepage.ui | 120 + kcontrol/input/xcursor/xcursor.knsrc | 6 + kcontrol/input/xcursor/xcursortheme.cpp | 231 + kcontrol/input/xcursor/xcursortheme.h | 71 + kcontrol/keyboard/CMakeLists.txt | 146 + kcontrol/keyboard/Messages.sh | 5 + kcontrol/keyboard/README | 44 + kcontrol/keyboard/TODO | 37 + kcontrol/keyboard/bindings.cpp | 146 + kcontrol/keyboard/bindings.h | 54 + kcontrol/keyboard/flags.cpp | 299 + kcontrol/keyboard/flags.h | 72 + kcontrol/keyboard/iso_codes.cpp | 141 + kcontrol/keyboard/iso_codes.h | 72 + kcontrol/keyboard/kcm_add_layout_dialog.cpp | 165 + kcontrol/keyboard/kcm_add_layout_dialog.h | 58 + kcontrol/keyboard/kcm_add_layout_dialog.ui | 149 + kcontrol/keyboard/kcm_keyboard.cpp | 108 + kcontrol/keyboard/kcm_keyboard.desktop | 238 + kcontrol/keyboard/kcm_keyboard.h | 47 + kcontrol/keyboard/kcm_keyboard.ui | 478 + kcontrol/keyboard/kcm_keyboard_widget.cpp | 691 ++ kcontrol/keyboard/kcm_keyboard_widget.h | 102 + kcontrol/keyboard/kcm_view_models.cpp | 504 + kcontrol/keyboard/kcm_view_models.h | 170 + kcontrol/keyboard/kcmmisc.cpp | 237 + kcontrol/keyboard/kcmmisc.h | 91 + kcontrol/keyboard/kcmmiscwidget.ui | 335 + kcontrol/keyboard/keyboard.desktop | 75 + kcontrol/keyboard/keyboard_applet.cpp | 221 + kcontrol/keyboard/keyboard_applet.h | 81 + kcontrol/keyboard/keyboard_config.cpp | 208 + kcontrol/keyboard/keyboard_config.h | 93 + kcontrol/keyboard/keyboard_daemon.cpp | 245 + kcontrol/keyboard/keyboard_daemon.h | 80 + kcontrol/keyboard/keyboard_dbus.h | 27 + kcontrol/keyboard/keyboard_hardware.cpp | 112 + kcontrol/keyboard/keyboard_hardware.h | 25 + kcontrol/keyboard/layout_memory.cpp | 211 + kcontrol/keyboard/layout_memory.h | 66 + kcontrol/keyboard/layout_memory_persister.cpp | 260 + kcontrol/keyboard/layout_memory_persister.h | 52 + kcontrol/keyboard/layout_tray_icon.cpp | 125 + kcontrol/keyboard/layout_tray_icon.h | 69 + kcontrol/keyboard/layout_widget.cpp | 114 + kcontrol/keyboard/layout_widget.h | 59 + kcontrol/keyboard/layouts_menu.cpp | 142 + kcontrol/keyboard/layouts_menu.h | 56 + kcontrol/keyboard/numlockx.c | 305 + kcontrol/keyboard/pics/CMakeLists.txt | 1 + kcontrol/keyboard/pics/epo.png | Bin 0 -> 235 bytes .../keyboard/plasma_applet_keyboard.desktop | 161 + kcontrol/keyboard/preview/TODO | 10 + kcontrol/keyboard/preview/kbpreviewframe.cpp | 367 + kcontrol/keyboard/preview/kbpreviewframe.h | 55 + kcontrol/keyboard/preview/keyaliases.cpp | 127 + kcontrol/keyboard/preview/keyaliases.h | 35 + kcontrol/keyboard/preview/keyboardlayout.cpp | 186 + kcontrol/keyboard/preview/keyboardlayout.h | 50 + kcontrol/keyboard/preview/keyboardpainter.cpp | 53 + kcontrol/keyboard/preview/keyboardpainter.h | 44 + kcontrol/keyboard/preview/keysym2ucs.cpp | 899 ++ kcontrol/keyboard/preview/keysym2ucs.h | 27 + kcontrol/keyboard/preview/keysymbols.cpp | 60 + kcontrol/keyboard/preview/keysymbols.h | 37 + kcontrol/keyboard/preview/keysymhelper.cpp | 78 + kcontrol/keyboard/preview/keysymhelper.h | 40 + kcontrol/keyboard/tests/CMakeLists.txt | 30 + kcontrol/keyboard/tests/config/base.1.1.xml | 68 + kcontrol/keyboard/tests/config/base.bad.xml | 5 + kcontrol/keyboard/tests/config/base.xml | 48 + kcontrol/keyboard/tests/flags_test.cpp | 103 + kcontrol/keyboard/tests/iso_codes_test.cpp | 78 + .../keyboard/tests/keyboard_daemon_test.cpp | 101 + .../tests/layout_memory_persister_test.cpp | 160 + kcontrol/keyboard/tests/xkb_rules_test.cpp | 240 + kcontrol/keyboard/x11_helper.cpp | 402 + kcontrol/keyboard/x11_helper.h | 182 + kcontrol/keyboard/xinput_helper.cpp | 162 + kcontrol/keyboard/xinput_helper.h | 50 + kcontrol/keyboard/xkb_helper.cpp | 184 + kcontrol/keyboard/xkb_helper.h | 35 + kcontrol/keyboard/xkb_rules.cpp | 406 + kcontrol/keyboard/xkb_rules.h | 119 + kcontrol/keys/CMakeLists.txt | 46 + kcontrol/keys/ChangeLog | 29 + kcontrol/keys/Messages.sh | 7 + kcontrol/keys/README | 7 + kcontrol/keys/export_scheme_dialog.cpp | 74 + kcontrol/keys/export_scheme_dialog.h | 58 + kcontrol/keys/export_scheme_dialog.ui | 35 + kcontrol/keys/globalshortcuts.cpp | 92 + kcontrol/keys/globalshortcuts.h | 44 + kcontrol/keys/keys.desktop | 227 + kcontrol/keys/kglobalshortcutseditor.cpp | 676 ++ kcontrol/keys/kglobalshortcutseditor.h | 156 + kcontrol/keys/kglobalshortcutseditor.ui | 57 + kcontrol/keys/schemes/kde3.kksrc | 166 + kcontrol/keys/schemes/kde4.kksrc | 166 + kcontrol/keys/schemes/mac4.kksrc | 171 + kcontrol/keys/schemes/old_kde3.kksrc | 51 + kcontrol/keys/schemes/old_kde4.kksrc | 51 + kcontrol/keys/schemes/old_mac4.kksrc | 51 + kcontrol/keys/schemes/old_unix3.kksrc | 51 + kcontrol/keys/schemes/old_win3.kksrc | 51 + kcontrol/keys/schemes/old_win4.kksrc | 51 + kcontrol/keys/schemes/old_wm3.kksrc | 51 + kcontrol/keys/schemes/split_kksrc | 111 + kcontrol/keys/schemes/unix3.kksrc | 171 + kcontrol/keys/schemes/win3.kksrc | 170 + kcontrol/keys/schemes/win4.kksrc | 170 + kcontrol/keys/schemes/wm3.kksrc | 165 + kcontrol/keys/select_scheme_dialog.cpp | 79 + kcontrol/keys/select_scheme_dialog.h | 48 + kcontrol/keys/select_scheme_dialog.ui | 150 + kcontrol/kfontinst/AUTHORS | 1 + kcontrol/kfontinst/CMakeLists.txt | 51 + kcontrol/kfontinst/ChangeLog | 562 + kcontrol/kfontinst/Messages.sh | 4 + kcontrol/kfontinst/apps/CMakeLists.txt | 33 + kcontrol/kfontinst/apps/CreateParent.h | 73 + kcontrol/kfontinst/apps/Installer.cpp | 154 + kcontrol/kfontinst/apps/Installer.h | 53 + kcontrol/kfontinst/apps/Printer.cpp | 496 + kcontrol/kfontinst/apps/Printer.h | 103 + kcontrol/kfontinst/apps/Viewer.cpp | 166 + kcontrol/kfontinst/apps/Viewer.h | 59 + kcontrol/kfontinst/apps/installfont.desktop | 96 + kcontrol/kfontinst/apps/kfontview.desktop | 192 + kcontrol/kfontinst/apps/kfontviewui.rc | 4 + .../kfontinst/apps/ox16-app-kfontview.png | Bin 0 -> 719 bytes .../kfontinst/apps/ox22-app-kfontview.png | Bin 0 -> 1047 bytes .../kfontinst/apps/ox32-app-kfontview.png | Bin 0 -> 1545 bytes .../kfontinst/apps/ox48-app-kfontview.png | Bin 0 -> 2701 bytes .../kfontinst/apps/ox64-app-kfontview.png | Bin 0 -> 4025 bytes .../kfontinst/apps/oxsc-app-kfontview.svgz | Bin 0 -> 9292 bytes kcontrol/kfontinst/config-fontinst.h.cmake | 9 + kcontrol/kfontinst/dbus/CMakeLists.txt | 32 + kcontrol/kfontinst/dbus/FcConfig.cpp | 194 + kcontrol/kfontinst/dbus/FcConfig.h | 39 + kcontrol/kfontinst/dbus/Folder.cpp | 417 + kcontrol/kfontinst/dbus/Folder.h | 114 + kcontrol/kfontinst/dbus/FontInst.cpp | 971 ++ kcontrol/kfontinst/dbus/FontInst.h | 162 + kcontrol/kfontinst/dbus/FontinstIface.cpp | 28 + kcontrol/kfontinst/dbus/FontinstIface.h | 136 + kcontrol/kfontinst/dbus/Helper.cpp | 443 + kcontrol/kfontinst/dbus/Helper.h | 63 + kcontrol/kfontinst/dbus/Main.cpp | 36 + kcontrol/kfontinst/dbus/Utils.cpp | 249 + kcontrol/kfontinst/dbus/Utils.h | 54 + kcontrol/kfontinst/dbus/fontinst.actions | 227 + kcontrol/kfontinst/dbus/fontinst_x11 | 62 + .../dbus/org.kde.fontinst.service.cmake | 4 + .../org.kde.fontinst.system-service.cmake | 5 + kcontrol/kfontinst/dbus/org.kde.fontinst.xml | 112 + .../kfontinst/kcmfontinst/ActionLabel.cpp | 113 + kcontrol/kfontinst/kcmfontinst/ActionLabel.h | 58 + kcontrol/kfontinst/kcmfontinst/CMakeLists.txt | 18 + .../kcmfontinst/DuplicatesDialog.cpp | 682 ++ .../kfontinst/kcmfontinst/DuplicatesDialog.h | 181 + kcontrol/kfontinst/kcmfontinst/FcQuery.cpp | 120 + kcontrol/kfontinst/kcmfontinst/FcQuery.h | 70 + kcontrol/kfontinst/kcmfontinst/FontFilter.cpp | 424 + kcontrol/kfontinst/kcmfontinst/FontFilter.h | 99 + .../kcmfontinst/FontFilterProxyStyle.cpp | 165 + .../kcmfontinst/FontFilterProxyStyle.h | 69 + .../kfontinst/kcmfontinst/FontInstInterface.h | 23 + kcontrol/kfontinst/kcmfontinst/FontList.cpp | 2066 ++++ kcontrol/kfontinst/kcmfontinst/FontList.h | 383 + .../kfontinst/kcmfontinst/FontsPackage.cpp | 97 + kcontrol/kfontinst/kcmfontinst/FontsPackage.h | 42 + kcontrol/kfontinst/kcmfontinst/GroupList.cpp | 1030 ++ kcontrol/kfontinst/kcmfontinst/GroupList.h | 241 + kcontrol/kfontinst/kcmfontinst/JobRunner.cpp | 770 ++ kcontrol/kfontinst/kcmfontinst/JobRunner.h | 141 + .../kfontinst/kcmfontinst/KCmFontInst.cpp | 1270 +++ kcontrol/kfontinst/kcmfontinst/KCmFontInst.h | 145 + .../kfontinst/kcmfontinst/PreviewList.cpp | 223 + kcontrol/kfontinst/kcmfontinst/PreviewList.h | 105 + .../kfontinst/kcmfontinst/PrintDialog.cpp | 68 + kcontrol/kfontinst/kcmfontinst/PrintDialog.h | 49 + .../kfontinst/kcmfontinst/fontinst.desktop | 192 + .../kfontinst/kcmfontinst/kfontinst.knsrc | 7 + .../kcmfontinst/ox16-action-addfont.png | Bin 0 -> 704 bytes .../kcmfontinst/ox16-action-disablefont.png | Bin 0 -> 731 bytes .../kcmfontinst/ox16-action-enablefont.png | Bin 0 -> 736 bytes .../kcmfontinst/ox16-action-fontstatus.png | Bin 0 -> 744 bytes .../kcmfontinst/ox22-action-addfont.png | Bin 0 -> 1003 bytes .../kcmfontinst/ox22-action-disablefont.png | Bin 0 -> 1050 bytes .../kcmfontinst/ox22-action-enablefont.png | Bin 0 -> 1042 bytes .../kcmfontinst/ox22-action-fontstatus.png | Bin 0 -> 1096 bytes .../kcmfontinst/oxsc-action-addfont.svgz | Bin 0 -> 55400 bytes .../kcmfontinst/oxsc-action-disablefont.svgz | Bin 0 -> 55550 bytes .../kcmfontinst/oxsc-action-enablefont.svgz | Bin 0 -> 55250 bytes .../kcmfontinst/oxsc-action-fontstatus.svgz | Bin 0 -> 55218 bytes kcontrol/kfontinst/kio/CMakeLists.txt | 12 + kcontrol/kfontinst/kio/FontInstInterface.cpp | 176 + kcontrol/kfontinst/kio/FontInstInterface.h | 75 + kcontrol/kfontinst/kio/KioFonts.cpp | 823 ++ kcontrol/kfontinst/kio/KioFonts.h | 85 + kcontrol/kfontinst/kio/fonts.desktop | 99 + kcontrol/kfontinst/kio/fonts.protocol | 18 + .../kio/ox128-mimetypes-fonts-package.png | Bin 0 -> 5266 bytes .../kio/ox16-mimetypes-fonts-package.png | Bin 0 -> 638 bytes .../kio/ox22-mimetypes-fonts-package.png | Bin 0 -> 873 bytes .../kio/ox32-mimetypes-fonts-package.png | Bin 0 -> 1273 bytes .../kio/ox48-mimetypes-fonts-package.png | Bin 0 -> 1896 bytes .../kio/ox64-mimetypes-fonts-package.png | Bin 0 -> 2613 bytes .../kio/oxsc-mimetypes-fonts-package.svgz | Bin 0 -> 3498 bytes kcontrol/kfontinst/lib/CMakeLists.txt | 11 + kcontrol/kfontinst/lib/Family.cpp | 155 + kcontrol/kfontinst/lib/Family.h | 88 + kcontrol/kfontinst/lib/Fc.cpp | 650 ++ kcontrol/kfontinst/lib/Fc.h | 126 + kcontrol/kfontinst/lib/FcEngine.cpp | 1423 +++ kcontrol/kfontinst/lib/FcEngine.h | 136 + kcontrol/kfontinst/lib/File.cpp | 93 + kcontrol/kfontinst/lib/File.h | 82 + kcontrol/kfontinst/lib/KfiConstants.h | 130 + kcontrol/kfontinst/lib/Misc.cpp | 484 + kcontrol/kfontinst/lib/Misc.h | 123 + kcontrol/kfontinst/lib/Style.cpp | 189 + kcontrol/kfontinst/lib/Style.h | 83 + kcontrol/kfontinst/lib/WritingSystems.cpp | 176 + kcontrol/kfontinst/lib/WritingSystems.h | 53 + kcontrol/kfontinst/lib/XmlStrings.h | 45 + kcontrol/kfontinst/lib/kfontinst_export.h | 45 + ...pp-preferences-desktop-font-installer.svgz | Bin 0 -> 54135 bytes .../kfontinst/strigi-analyzer/CMakeLists.txt | 12 + .../kfontinst/strigi-analyzer/FontEngine.cpp | 1121 ++ .../kfontinst/strigi-analyzer/FontEngine.h | 125 + .../strigi-analyzer/FontThroughAnalyzer.cpp | 276 + .../strigi-analyzer/FontThroughAnalyzer.h | 56 + kcontrol/kfontinst/thumbnail/CMakeLists.txt | 14 + .../kfontinst/thumbnail/FontThumbnail.cpp | 127 + kcontrol/kfontinst/thumbnail/FontThumbnail.h | 51 + .../kfontinst/thumbnail/fontthumbnail.desktop | 98 + kcontrol/kfontinst/viewpart/CMakeLists.txt | 16 + kcontrol/kfontinst/viewpart/COPYING.UNICODE | 31 + kcontrol/kfontinst/viewpart/CharTip.cpp | 299 + kcontrol/kfontinst/viewpart/CharTip.h | 73 + kcontrol/kfontinst/viewpart/FontPreview.cpp | 180 + kcontrol/kfontinst/viewpart/FontPreview.h | 97 + kcontrol/kfontinst/viewpart/FontViewPart.cpp | 557 + kcontrol/kfontinst/viewpart/FontViewPart.h | 123 + .../viewpart/PreviewSelectAction.cpp | 99 + .../kfontinst/viewpart/PreviewSelectAction.h | 67 + kcontrol/kfontinst/viewpart/UnicodeBlocks.h | 179 + .../kfontinst/viewpart/UnicodeCategories.h | 2128 ++++ kcontrol/kfontinst/viewpart/UnicodeScripts.h | 1286 +++ .../viewpart/download-unicode-files.sh | 26 + .../viewpart/generate-unicode-tables.pl | 854 ++ .../kfontinst/viewpart/kfontviewpart.desktop | 98 + kcontrol/kfontinst/viewpart/kfontviewpart.rc | 11 + kcontrol/krdb/AUTHORS | 9 + kcontrol/krdb/CMakeLists.txt | 10 + kcontrol/krdb/Messages.sh | 2 + kcontrol/krdb/ad/AAAAAAGeneral.ad | 2 + kcontrol/krdb/ad/AAAMotif.ad | 74 + kcontrol/krdb/ad/AAATk.ad | 107 + kcontrol/krdb/ad/AAAXaw.ad | 36 + kcontrol/krdb/ad/AcroRead.ad | 8 + kcontrol/krdb/ad/CMakeLists.txt | 3 + kcontrol/krdb/ad/Editres.ad | 5 + kcontrol/krdb/ad/Emacs.ad | 17 + kcontrol/krdb/ad/GV.ad | 1 + kcontrol/krdb/ad/ML.ad | 36 + kcontrol/krdb/ad/Nedit.ad | 2 + kcontrol/krdb/ad/Netscape.ad | 25 + kcontrol/krdb/ad/README | 63 + kcontrol/krdb/ad/RVPlayer.ad | 40 + kcontrol/krdb/ad/WPerfect.ad | 68 + kcontrol/krdb/ad/XCalc.ad | 7 + kcontrol/krdb/ad/XOsview.ad | 5 + kcontrol/krdb/ad/XTerm.ad | 4 + kcontrol/krdb/ad/XV.ad | 2 + kcontrol/krdb/ad/Xawtv.ad | 10 + kcontrol/krdb/ad/Xdvi.ad | 1 + kcontrol/krdb/ad/Xpdf.ad | 3 + kcontrol/krdb/ad/krdb | 4 + kcontrol/krdb/krdb.cpp | 592 + kcontrol/krdb/krdb.h | 34 + kcontrol/krdb/krdb_clearlibrarypath.cpp | 75 + kcontrol/krdb/krdb_libpathwipe.upd | 2 + kcontrol/krdb/pics/CMakeLists.txt | 2 + kcontrol/krdb/pics/lo-energy.png | Bin 0 -> 1767 bytes kcontrol/krdb/pics/logo.png | Bin 0 -> 785 bytes kcontrol/krdb/pics/mini-world.png | Bin 0 -> 983 bytes kcontrol/krdb/themes/CMakeLists.txt | 12 + .../HighContrastDark-big/CMakeLists.txt | 1 + .../HighContrastDark-big.preview.png | Bin 0 -> 6976 bytes .../HighContrastDark-big.xml | 158 + .../themes/HighContrastDark/CMakeLists.txt | 1 + .../HighContrastDark.preview.png | Bin 0 -> 5385 bytes .../HighContrastDark/HighContrastDark.xml | 158 + .../HighContrastLight-big/CMakeLists.txt | 2 + .../HighContrastLight-big.preview.png | Bin 0 -> 42834 bytes .../HighContrastLight-big.xml | 158 + .../themes/HighContrastLight/CMakeLists.txt | 2 + .../HighContrastLight.preview.png | Bin 0 -> 40603 bytes .../HighContrastLight/HighContrastLight.xml | 158 + .../krdb/themes/KDE_Classic/CMakeLists.txt | 1 + .../KDE_Classic/KDE_Classic.preview.png | Bin 0 -> 36961 bytes .../krdb/themes/KDE_Classic/KDE_Classic.xml | 124 + kcontrol/krdb/themes/Keramik/CMakeLists.txt | 2 + .../krdb/themes/Keramik/Keramik.preview.png | Bin 0 -> 41073 bytes kcontrol/krdb/themes/Keramik/Keramik.xml | 124 + kcontrol/krdb/themes/Plastik/CMakeLists.txt | 1 + .../krdb/themes/Plastik/Plastik.preview.png | Bin 0 -> 37186 bytes kcontrol/krdb/themes/Plastik/Plastik.xml | 124 + kcontrol/krdb/themes/Platinum/CMakeLists.txt | 1 + .../krdb/themes/Platinum/Platinum.preview.png | Bin 0 -> 31282 bytes kcontrol/krdb/themes/Platinum/Platinum.xml | 124 + kcontrol/krdb/themes/Redmond/CMakeLists.txt | 1 + .../krdb/themes/Redmond/Redmond.preview.png | Bin 0 -> 30318 bytes kcontrol/krdb/themes/Redmond/Redmond.xml | 124 + kcontrol/krdb/themes/Sunshine/CMakeLists.txt | 1 + .../krdb/themes/Sunshine/Sunshine.preview.png | Bin 0 -> 28343 bytes kcontrol/krdb/themes/Sunshine/Sunshine.xml | 124 + .../themes/YellowOnBlue-big/CMakeLists.txt | 1 + .../YellowOnBlue-big.preview.png | Bin 0 -> 55401 bytes .../YellowOnBlue-big/YellowOnBlue-big.xml | 158 + .../krdb/themes/YellowOnBlue/CMakeLists.txt | 1 + .../YellowOnBlue/YellowOnBlue.preview.png | Bin 0 -> 53362 bytes .../krdb/themes/YellowOnBlue/YellowOnBlue.xml | 158 + kcontrol/launch/CMakeLists.txt | 27 + kcontrol/launch/Messages.sh | 2 + kcontrol/launch/interface_util.h | 26 + kcontrol/launch/kcmlaunch.cpp | 274 + kcontrol/launch/kcmlaunch.desktop | 231 + kcontrol/launch/kcmlaunch.h | 70 + kcontrol/randr/CMakeLists.txt | 74 + kcontrol/randr/ChangeLog | 34 + kcontrol/randr/Messages.sh | 4 + kcontrol/randr/TODO | 29 + kcontrol/randr/collapsiblewidget.cpp | 279 + kcontrol/randr/collapsiblewidget.h | 123 + kcontrol/randr/config-randr.h.cmake | 2 + kcontrol/randr/krandrapp.cpp | 53 + kcontrol/randr/krandrapp.h | 44 + kcontrol/randr/krandrmodule.cpp | 156 + kcontrol/randr/krandrmodule.h | 55 + kcontrol/randr/krandrpassivepopup.cpp | 123 + kcontrol/randr/krandrpassivepopup.h | 50 + kcontrol/randr/krandrstartup | 54 + kcontrol/randr/krandrtray.cpp | 620 ++ kcontrol/randr/krandrtray.desktop | 259 + kcontrol/randr/krandrtray.h | 73 + kcontrol/randr/ktimerdialog.cpp | 220 + kcontrol/randr/ktimerdialog.h | 173 + kcontrol/randr/layoutmanager.cpp | 150 + kcontrol/randr/layoutmanager.h | 48 + kcontrol/randr/legacyrandrconfig.cpp | 278 + kcontrol/randr/legacyrandrconfig.h | 65 + kcontrol/randr/legacyrandrconfigbase.ui | 146 + kcontrol/randr/legacyrandrscreen.cpp | 424 + kcontrol/randr/legacyrandrscreen.h | 160 + kcontrol/randr/main.cpp | 52 + kcontrol/randr/module/CMakeLists.txt | 25 + kcontrol/randr/module/Messages.sh | 2 + kcontrol/randr/module/TODO | 7 + kcontrol/randr/module/randrmonitor.cpp | 413 + kcontrol/randr/module/randrmonitor.desktop | 66 + kcontrol/randr/module/randrmonitor.h | 94 + kcontrol/randr/module/randrpolltest.cpp | 63 + kcontrol/randr/outputconfig.cpp | 516 + kcontrol/randr/outputconfig.h | 103 + kcontrol/randr/outputconfigbase.ui | 151 + kcontrol/randr/outputgraphicsitem.cpp | 317 + kcontrol/randr/outputgraphicsitem.h | 74 + kcontrol/randr/randr.cpp | 183 + kcontrol/randr/randr.desktop | 232 + kcontrol/randr/randr.h | 109 + kcontrol/randr/randrconfig.cpp | 479 + kcontrol/randr/randrconfig.h | 91 + kcontrol/randr/randrconfigbase.ui | 101 + kcontrol/randr/randrcrtc.cpp | 451 + kcontrol/randr/randrcrtc.h | 94 + kcontrol/randr/randrdisplay.cpp | 367 + kcontrol/randr/randrdisplay.h | 95 + kcontrol/randr/randrmode.cpp | 81 + kcontrol/randr/randrmode.h | 45 + kcontrol/randr/randroutput.cpp | 719 ++ kcontrol/randr/randroutput.h | 182 + kcontrol/randr/randrscreen.cpp | 682 ++ kcontrol/randr/randrscreen.h | 139 + kcontrol/screensaver/CMakeLists.txt | 43 + kcontrol/screensaver/Messages.sh | 6 + kcontrol/screensaver/category_list | 16 + .../screensaver/config-screensaver.h.cmake | 3 + kcontrol/screensaver/kssmonitor.h | 40 + kcontrol/screensaver/kswidget.cpp | 103 + kcontrol/screensaver/kswidget.h | 42 + kcontrol/screensaver/saverconfig.cpp | 69 + kcontrol/screensaver/saverconfig.h | 59 + kcontrol/screensaver/screensaver.desktop | 148 + kcontrol/screensaver/screensaver.ui | 352 + kcontrol/screensaver/scrnsave.cpp | 809 ++ kcontrol/screensaver/scrnsave.h | 124 + kcontrol/screensaver/testwin.cpp | 34 + kcontrol/screensaver/testwin.h | 39 + kcontrol/smartcard/CMakeLists.txt | 26 + kcontrol/smartcard/Messages.sh | 5 + kcontrol/smartcard/configure.in.in | 3 + kcontrol/smartcard/nosmartcardbase.ui | 79 + kcontrol/smartcard/smartcard.cpp | 424 + kcontrol/smartcard/smartcard.desktop | 235 + kcontrol/smartcard/smartcard.h | 91 + kcontrol/smartcard/smartcardbase.ui | 308 + kcontrol/standard_actions/CMakeLists.txt | 9 + kcontrol/standard_actions/Messages.sh | 2 + .../standard_actions/standard_actions.desktop | 210 + .../standard_actions_module.cpp | 170 + .../standard_actions_module.h | 49 + kcontrol/style/CMakeLists.txt | 31 + kcontrol/style/Messages.sh | 4 + kcontrol/style/finetuning.ui | 259 + kcontrol/style/kcmstyle.cpp | 868 ++ kcontrol/style/kcmstyle.h | 120 + kcontrol/style/kcmstyle.notifyrc | 179 + kcontrol/style/style.desktop | 232 + kcontrol/style/styleconfdialog.cpp | 48 + kcontrol/style/styleconfdialog.h | 46 + kcontrol/style/stylepreview.ui | 171 + kcontrol/workspaceoptions/CMakeLists.txt | 14 + kcontrol/workspaceoptions/Messages.sh | 3 + kcontrol/workspaceoptions/mainpage.ui | 99 + .../workspaceoptions/workspaceoptions.cpp | 358 + .../workspaceoptions/workspaceoptions.desktop | 182 + kcontrol/workspaceoptions/workspaceoptions.h | 56 + kde.pamd | 7 + kdm/CMakeLists.txt | 39 + kdm/ChangeLog | 585 + kdm/ConfigureChecks.cmake | 275 + kdm/README | 292 + kdm/TODO | 266 + kdm/backend/CMakeLists.txt | 83 + kdm/backend/access.c | 461 + kdm/backend/auth.c | 1313 +++ kdm/backend/bootman.c | 461 + kdm/backend/choose.c | 983 ++ kdm/backend/client.c | 2061 ++++ kdm/backend/ctrl.c | 992 ++ kdm/backend/daemon.c | 78 + kdm/backend/dm.c | 1748 +++ kdm/backend/dm.h | 696 ++ kdm/backend/dm_auth.h | 107 + kdm/backend/dm_error.h | 57 + kdm/backend/dm_socket.h | 72 + kdm/backend/dpylist.c | 291 + kdm/backend/error.c | 129 + kdm/backend/genauth.c | 497 + kdm/backend/greet.h | 287 + kdm/backend/inifile.c | 260 + kdm/backend/krb5auth.c | 231 + kdm/backend/netaddr.c | 217 + kdm/backend/policy.c | 271 + kdm/backend/printf.c | 873 ++ kdm/backend/process.c | 861 ++ kdm/backend/protodpy.c | 130 + kdm/backend/reset.c | 110 + kdm/backend/resource.c | 484 + kdm/backend/rpcauth.c | 62 + kdm/backend/server.c | 362 + kdm/backend/session.c | 836 ++ kdm/backend/sessreg.c | 338 + kdm/backend/socket.c | 410 + kdm/backend/streams.c | 127 + kdm/backend/util.c | 794 ++ kdm/backend/xdmauth.c | 193 + kdm/backend/xdmcp.c | 1134 ++ kdm/config-kdm.h.cmake | 141 + kdm/config.def | 2705 +++++ kdm/confproc.pl | 904 ++ kdm/kcm/AUTHORS | 6 + kdm/kcm/CMakeLists.txt | 54 + kdm/kcm/Messages.sh | 2 + kdm/kcm/anchor.png | Bin 0 -> 482 bytes kdm/kcm/background.cpp | 91 + kdm/kcm/background.h | 46 + kdm/kcm/background/CMakeLists.txt | 7 + kdm/kcm/background/Messages.sh | 4 + kdm/kcm/background/background.knsrc | 5 + kdm/kcm/background/bgadvanced.cpp | 459 + kdm/kcm/background/bgadvanced.h | 120 + kdm/kcm/background/bgadvanced_ui.ui | 286 + kdm/kcm/background/bgdefaults.h | 34 + kdm/kcm/background/bgdialog.cpp | 1098 ++ kdm/kcm/background/bgdialog.h | 109 + kdm/kcm/background/bgdialog_ui.ui | 633 ++ kdm/kcm/background/bgmonitor.cpp | 150 + kdm/kcm/background/bgmonitor.h | 70 + kdm/kcm/background/bgrender.cpp | 971 ++ kdm/kcm/background/bgrender.h | 114 + kdm/kcm/background/bgsettings.cpp | 1127 ++ kdm/kcm/background/bgsettings.h | 328 + kdm/kcm/background/bgwallpaper.cpp | 239 + kdm/kcm/background/bgwallpaper.h | 65 + kdm/kcm/background/bgwallpaper_ui.ui | 150 + kdm/kcm/background/patterns/CMakeLists.txt | 1 + kdm/kcm/background/patterns/fish.desktop | 88 + kdm/kcm/background/patterns/fish.png | Bin 0 -> 230 bytes kdm/kcm/background/patterns/flowers.desktop | 88 + kdm/kcm/background/patterns/flowers.png | Bin 0 -> 246 bytes .../background/patterns/night-rock.desktop | 86 + kdm/kcm/background/patterns/night-rock.jpg | Bin 0 -> 30425 bytes kdm/kcm/background/patterns/pavement.desktop | 87 + kdm/kcm/background/patterns/pavement.png | Bin 0 -> 241 bytes kdm/kcm/background/patterns/rattan.desktop | 87 + kdm/kcm/background/patterns/rattan.png | Bin 0 -> 245 bytes .../background/patterns/stonewall2.desktop | 86 + kdm/kcm/background/patterns/stonewall2.png | Bin 0 -> 40834 bytes kdm/kcm/background/patterns/triangles.desktop | 89 + kdm/kcm/background/patterns/triangles.png | Bin 0 -> 246 bytes kdm/kcm/background/pics/CMakeLists.txt | 1 + kdm/kcm/background/pics/monitor.png | Bin 0 -> 6650 bytes kdm/kcm/background/programs/CMakeLists.txt | 1 + kdm/kcm/background/programs/xearth.desktop | 90 + kdm/kcm/background/programs/xglobe.desktop | 90 + kdm/kcm/background/programs/xplanet.desktop | 91 + kdm/kcm/helper.cpp | 280 + kdm/kcm/helper.h | 60 + kdm/kcm/kbackedcombobox.cpp | 40 + kdm/kcm/kbackedcombobox.h | 38 + kdm/kcm/kcmkdm_actions.actions | 431 + kdm/kcm/kdm-conv.cpp | 366 + kdm/kcm/kdm-conv.h | 68 + kdm/kcm/kdm-dlg.cpp | 299 + kdm/kcm/kdm-dlg.h | 70 + kdm/kcm/kdm-gen.cpp | 244 + kdm/kcm/kdm-gen.h | 63 + kdm/kcm/kdm-shut.cpp | 211 + kdm/kcm/kdm-shut.h | 57 + kdm/kcm/kdm-theme.cpp | 409 + kdm/kcm/kdm-theme.h | 69 + kdm/kcm/kdm-users.cpp | 583 + kdm/kcm/kdm-users.h | 96 + kdm/kcm/kdm.desktop | 210 + kdm/kcm/kdm.knsrc | 7 + kdm/kcm/main.cpp | 464 + kdm/kcm/main.h | 93 + kdm/kcm/positioner.cpp | 222 + kdm/kcm/positioner.h | 62 + kdm/kfrontend/CMakeLists.txt | 116 + kdm/kfrontend/Messages.sh | 2 + kdm/kfrontend/genkdmconf.c | 3320 ++++++ kdm/kfrontend/kchooser.cpp | 252 + kdm/kfrontend/kchooser.h | 66 + kdm/kfrontend/kconsole.cpp | 175 + kdm/kfrontend/kconsole.h | 53 + kdm/kfrontend/kdm_config.c | 1468 +++ kdm/kfrontend/kdm_greet.c | 689 ++ kdm/kfrontend/kdm_greet.h | 83 + kdm/kfrontend/kdmclock.cpp | 149 + kdm/kfrontend/kdmclock.h | 55 + kdm/kfrontend/kdmconfig.cpp | 150 + kdm/kfrontend/kdmconfig.h | 56 + kdm/kfrontend/kdmctl.c | 233 + kdm/kfrontend/kdmshutdown.cpp | 735 ++ kdm/kfrontend/kdmshutdown.h | 189 + kdm/kfrontend/kfdialog.cpp | 193 + kdm/kfrontend/kfdialog.h | 71 + kdm/kfrontend/kgapp.cpp | 527 + kdm/kfrontend/kgapp.h | 59 + kdm/kfrontend/kgdialog.cpp | 239 + kdm/kfrontend/kgdialog.h | 90 + kdm/kfrontend/kgreeter.cpp | 1107 ++ kdm/kfrontend/kgreeter.h | 158 + kdm/kfrontend/kgverify.cpp | 1295 +++ kdm/kfrontend/kgverify.h | 256 + kdm/kfrontend/krootimage.cpp | 354 + kdm/kfrontend/krootimage.h | 101 + kdm/kfrontend/pics/CMakeLists.txt | 5 + kdm/kfrontend/pics/default1.png | Bin 0 -> 1830 bytes kdm/kfrontend/pics/default2.png | Bin 0 -> 4645 bytes kdm/kfrontend/pics/default3.png | Bin 0 -> 3949 bytes kdm/kfrontend/pics/kdelogo.png | Bin 0 -> 18660 bytes kdm/kfrontend/pics/root1.png | Bin 0 -> 2138 bytes kdm/kfrontend/pics/shutdown.png | Bin 0 -> 15579 bytes kdm/kfrontend/pics/stripes.png | Bin 0 -> 249137 bytes kdm/kfrontend/pics/stripes.png.desktop | 66 + kdm/kfrontend/sessions/9wm.desktop | 177 + kdm/kfrontend/sessions/CMakeLists.txt | 56 + kdm/kfrontend/sessions/aewm++.desktop | 176 + kdm/kfrontend/sessions/aewm.desktop | 177 + kdm/kfrontend/sessions/afterstep.desktop | 177 + kdm/kfrontend/sessions/amaterus.desktop | 176 + kdm/kfrontend/sessions/amiwm.desktop | 177 + kdm/kfrontend/sessions/asclassic.desktop | 176 + kdm/kfrontend/sessions/awesome.desktop | 136 + kdm/kfrontend/sessions/blackbox.desktop | 177 + kdm/kfrontend/sessions/cde.desktop | 178 + kdm/kfrontend/sessions/ctwm.desktop | 172 + kdm/kfrontend/sessions/cwwm.desktop | 175 + kdm/kfrontend/sessions/e16.desktop | 169 + kdm/kfrontend/sessions/enlightenment.desktop | 177 + kdm/kfrontend/sessions/evilwm.desktop | 175 + kdm/kfrontend/sessions/fluxbox.desktop | 173 + kdm/kfrontend/sessions/flwm.desktop | 175 + kdm/kfrontend/sessions/fvwm.desktop | 173 + kdm/kfrontend/sessions/fvwm95.desktop | 176 + kdm/kfrontend/sessions/gnome.desktop | 178 + kdm/kfrontend/sessions/golem.desktop | 177 + kdm/kfrontend/sessions/icewm.desktop | 177 + kdm/kfrontend/sessions/ion.desktop | 174 + .../sessions/kde-plasma-safe.desktop.cmake | 107 + .../sessions/kde-plasma.desktop.cmake | 109 + kdm/kfrontend/sessions/larswm.desktop | 173 + kdm/kfrontend/sessions/lwm.desktop | 176 + kdm/kfrontend/sessions/lxde.desktop | 130 + kdm/kfrontend/sessions/matchbox.desktop | 173 + kdm/kfrontend/sessions/metacity.desktop | 177 + kdm/kfrontend/sessions/mwm.desktop | 177 + kdm/kfrontend/sessions/olvwm.desktop | 175 + kdm/kfrontend/sessions/olwm.desktop | 175 + kdm/kfrontend/sessions/openbox.desktop | 179 + kdm/kfrontend/sessions/oroborus.desktop | 176 + kdm/kfrontend/sessions/phluid.desktop | 176 + kdm/kfrontend/sessions/pwm.desktop | 174 + kdm/kfrontend/sessions/qvwm.desktop | 177 + kdm/kfrontend/sessions/ratpoison.desktop | 175 + kdm/kfrontend/sessions/sapphire.desktop | 177 + kdm/kfrontend/sessions/sawfish.desktop | 174 + kdm/kfrontend/sessions/subtle.desktop | 64 + kdm/kfrontend/sessions/twm.desktop | 175 + kdm/kfrontend/sessions/ude.desktop | 179 + kdm/kfrontend/sessions/vtwm.desktop | 175 + kdm/kfrontend/sessions/w9wm.desktop | 175 + kdm/kfrontend/sessions/waimea.desktop | 176 + kdm/kfrontend/sessions/wm2.desktop | 177 + kdm/kfrontend/sessions/wmaker.desktop | 176 + kdm/kfrontend/sessions/xfce.desktop | 176 + kdm/kfrontend/sessions/xfce4.desktop | 142 + kdm/kfrontend/themer/kdmbutton.cpp | 101 + kdm/kfrontend/themer/kdmbutton.h | 49 + kdm/kfrontend/themer/kdmitem.cpp | 664 ++ kdm/kfrontend/themer/kdmitem.h | 275 + kdm/kfrontend/themer/kdmlabel.cpp | 365 + kdm/kfrontend/themer/kdmlabel.h | 104 + kdm/kfrontend/themer/kdmlayout.cpp | 254 + kdm/kfrontend/themer/kdmlayout.h | 93 + kdm/kfrontend/themer/kdmlist.cpp | 69 + kdm/kfrontend/themer/kdmlist.h | 44 + kdm/kfrontend/themer/kdmpixmap.cpp | 370 + kdm/kfrontend/themer/kdmpixmap.h | 93 + kdm/kfrontend/themer/kdmrect.cpp | 85 + kdm/kfrontend/themer/kdmrect.h | 54 + kdm/kfrontend/themer/kdmthemer.cpp | 275 + kdm/kfrontend/themer/kdmthemer.h | 115 + kdm/kfrontend/themer/parse.cpp | 332 + kdm/kfrontend/themer/parse.h | 74 + kdm/kfrontend/themes/CMakeLists.txt | 8 + kdm/kfrontend/themes/ariya/CMakeLists.txt | 16 + .../themes/ariya/KdmGreeterTheme.desktop | 54 + kdm/kfrontend/themes/ariya/ariya.xml | 150 + .../themes/ariya/lineedit_active.png | Bin 0 -> 1707 bytes .../themes/ariya/lineedit_normal.png | Bin 0 -> 686 bytes kdm/kfrontend/themes/ariya/lock.png | Bin 0 -> 844 bytes kdm/kfrontend/themes/ariya/login_active.png | Bin 0 -> 3367 bytes kdm/kfrontend/themes/ariya/login_normal.png | Bin 0 -> 3384 bytes kdm/kfrontend/themes/ariya/pw_icon.png | Bin 0 -> 738 bytes kdm/kfrontend/themes/ariya/rectangle.png | Bin 0 -> 16231 bytes .../themes/ariya/rectangle_overlay.png | Bin 0 -> 245 bytes kdm/kfrontend/themes/ariya/screenshot.png | Bin 0 -> 206831 bytes kdm/kfrontend/themes/ariya/session_normal.png | Bin 0 -> 1107 bytes kdm/kfrontend/themes/ariya/system_normal.png | Bin 0 -> 1218 bytes kdm/kfrontend/themes/ariya/user_icon.png | Bin 0 -> 1239 bytes kdm/kfrontend/themes/circles/CMakeLists.txt | 11 + .../themes/circles/KdmGreeterTheme.desktop | 182 + kdm/kfrontend/themes/circles/background.svg | 39 + kdm/kfrontend/themes/circles/circles.xml | 219 + kdm/kfrontend/themes/circles/flower.png | Bin 0 -> 114844 bytes kdm/kfrontend/themes/circles/help.png | Bin 0 -> 1536 bytes kdm/kfrontend/themes/circles/options.png | Bin 0 -> 1936 bytes kdm/kfrontend/themes/circles/screenshot.png | Bin 0 -> 14375 bytes kdm/kfrontend/themes/elarun/CMakeLists.txt | 16 + .../themes/elarun/KdmGreeterTheme.desktop | 53 + kdm/kfrontend/themes/elarun/elarun.xml | 150 + .../themes/elarun/lineedit_active.png | Bin 0 -> 1707 bytes .../themes/elarun/lineedit_normal.png | Bin 0 -> 686 bytes kdm/kfrontend/themes/elarun/lock.png | Bin 0 -> 844 bytes kdm/kfrontend/themes/elarun/login_active.png | Bin 0 -> 3367 bytes kdm/kfrontend/themes/elarun/login_normal.png | Bin 0 -> 3384 bytes kdm/kfrontend/themes/elarun/pw_icon.png | Bin 0 -> 738 bytes kdm/kfrontend/themes/elarun/rectangle.png | Bin 0 -> 16231 bytes .../themes/elarun/rectangle_overlay.png | Bin 0 -> 245 bytes kdm/kfrontend/themes/elarun/screenshot.png | Bin 0 -> 88147 bytes .../themes/elarun/session_normal.png | Bin 0 -> 1107 bytes kdm/kfrontend/themes/elarun/system_normal.png | Bin 0 -> 1218 bytes kdm/kfrontend/themes/elarun/user_icon.png | Bin 0 -> 1239 bytes kdm/kfrontend/themes/greeter.dtd | 118 + kdm/kfrontend/themes/horos/CMakeLists.txt | 16 + .../themes/horos/KdmGreeterTheme.desktop | 65 + kdm/kfrontend/themes/horos/horos.xml | 150 + .../themes/horos/lineedit_active.png | Bin 0 -> 1707 bytes .../themes/horos/lineedit_normal.png | Bin 0 -> 686 bytes kdm/kfrontend/themes/horos/lock.png | Bin 0 -> 844 bytes kdm/kfrontend/themes/horos/login_active.png | Bin 0 -> 3367 bytes kdm/kfrontend/themes/horos/login_normal.png | Bin 0 -> 3384 bytes kdm/kfrontend/themes/horos/pw_icon.png | Bin 0 -> 738 bytes kdm/kfrontend/themes/horos/rectangle.png | Bin 0 -> 16231 bytes .../themes/horos/rectangle_overlay.png | Bin 0 -> 245 bytes kdm/kfrontend/themes/horos/screenshot.png | Bin 0 -> 120536 bytes kdm/kfrontend/themes/horos/session_normal.png | Bin 0 -> 1107 bytes kdm/kfrontend/themes/horos/system_normal.png | Bin 0 -> 1218 bytes kdm/kfrontend/themes/horos/user_icon.png | Bin 0 -> 1239 bytes .../themes/oxygen-air/CMakeLists.txt | 14 + .../themes/oxygen-air/KdmGreeterTheme.desktop | 76 + kdm/kfrontend/themes/oxygen-air/caps.png | Bin 0 -> 2754 bytes kdm/kfrontend/themes/oxygen-air/icon-kde.png | Bin 0 -> 9423 bytes .../themes/oxygen-air/oxygen-air.xml | 124 + kdm/kfrontend/themes/oxygen-air/pw-entry.png | Bin 0 -> 1008 bytes .../themes/oxygen-air/screenshot.png | Bin 0 -> 197068 bytes .../themes/oxygen-air/session_button-li.png | Bin 0 -> 1570 bytes .../themes/oxygen-air/session_button.png | Bin 0 -> 1063 bytes .../themes/oxygen-air/system_button-li.png | Bin 0 -> 1723 bytes .../themes/oxygen-air/system_button.png | Bin 0 -> 1222 bytes .../themes/oxygen-air/user-entry.png | Bin 0 -> 1183 bytes kdm/kfrontend/themes/oxygen-air/win-login.png | Bin 0 -> 46122 bytes kdm/kfrontend/themes/oxygen/CMakeLists.txt | 11 + .../themes/oxygen/KdmGreeterTheme.desktop | 171 + kdm/kfrontend/themes/oxygen/background.svg | 84 + kdm/kfrontend/themes/oxygen/branding-icon.png | Bin 0 -> 2549 bytes kdm/kfrontend/themes/oxygen/oxygen-box.svg | 1496 +++ kdm/kfrontend/themes/oxygen/oxygen.svg | 97 + kdm/kfrontend/themes/oxygen/oxygen.xml | 215 + kdm/kfrontend/themes/oxygen/screenshot.png | Bin 0 -> 12952 bytes kdm/kfrontend/themes/oxygen/session.png | Bin 0 -> 1197 bytes kdm/kfrontend/themes/oxygen/system.png | Bin 0 -> 1309 bytes kdm/kfrontend/utils.cpp | 111 + kdm/kfrontend/utils.h | 46 + khotkeys/AUTHORS | 1 + khotkeys/CMakeLists.txt | 18 + khotkeys/ExtraDesktop.sh | 4 + khotkeys/Messages.sh | 4 + khotkeys/TODO | 82 + khotkeys/app/CMakeLists.txt | 27 + khotkeys/app/kded.cpp | 249 + khotkeys/app/kded.h | 103 + khotkeys/app/khotkeys.desktop | 153 + khotkeys/data/CMakeLists.txt | 6 + khotkeys/data/defaults.khotkeys | 400 + khotkeys/data/kde32b1.khotkeys | 3438 ++++++ .../data/konqueror_gestures_kde321.khotkeys | 4032 +++++++ khotkeys/data/printscreen.khotkeys | 436 + khotkeys/kcm_hotkeys/CMakeLists.txt | 104 + khotkeys/kcm_hotkeys/action_group_widget.cpp | 81 + khotkeys/kcm_hotkeys/action_group_widget.h | 78 + .../actions/action_widget_base.cpp | 34 + .../kcm_hotkeys/actions/action_widget_base.h | 54 + .../actions/command_url_action_widget.cpp | 76 + .../actions/command_url_action_widget.h | 62 + .../actions/command_url_action_widget.ui | 47 + .../actions/dbus_action_widget.cpp | 127 + .../kcm_hotkeys/actions/dbus_action_widget.h | 68 + .../kcm_hotkeys/actions/dbus_action_widget.ui | 118 + .../actions/keyboard_input_action_widget.cpp | 150 + .../actions/keyboard_input_action_widget.h | 64 + .../actions/keyboard_input_action_widget.ui | 70 + .../actions/menuentry_action_widget.cpp | 123 + .../actions/menuentry_action_widget.h | 70 + .../actions/menuentry_action_widget.ui | 50 + .../conditions/condition_type_menu.cpp | 44 + .../conditions/condition_type_menu.h | 54 + .../conditions/conditions_widget.cpp | 427 + .../conditions/conditions_widget.h | 96 + .../conditions/conditions_widget.ui | 54 + .../kcm_hotkeys/global_settings_widget.cpp | 152 + khotkeys/kcm_hotkeys/global_settings_widget.h | 73 + .../kcm_hotkeys/global_settings_widget.ui | 152 + .../helper_widgets/edit_gesture_dialog.cpp | 74 + .../helper_widgets/edit_gesture_dialog.h | 64 + .../helper_widgets/gesture_drawer.cpp | 108 + .../helper_widgets/gesture_drawer.h | 52 + .../helper_widgets/gesture_recorder.cpp | 74 + .../helper_widgets/gesture_recorder.h | 53 + .../helper_widgets/gesture_widget.cpp | 71 + .../helper_widgets/gesture_widget.h | 66 + .../helper_widgets/gesture_widget.ui | 44 + .../window_definition_list_widget.cpp | 274 + .../window_definition_list_widget.h | 121 + .../window_definition_list_widget.ui | 78 + .../window_definition_widget.cpp | 204 + .../helper_widgets/window_definition_widget.h | 114 + .../window_definition_widget.ui | 250 + .../helper_widgets/window_selector.cpp | 89 + .../helper_widgets/window_selector.h | 36 + khotkeys/kcm_hotkeys/hotkeys_context_menu.cpp | 422 + khotkeys/kcm_hotkeys/hotkeys_context_menu.h | 83 + .../kcm_hotkeys/hotkeys_export_widget.cpp | 91 + khotkeys/kcm_hotkeys/hotkeys_export_widget.h | 70 + khotkeys/kcm_hotkeys/hotkeys_export_widget.ui | 166 + khotkeys/kcm_hotkeys/hotkeys_model.cpp | 711 ++ khotkeys/kcm_hotkeys/hotkeys_model.h | 171 + khotkeys/kcm_hotkeys/hotkeys_proxy_model.cpp | 81 + khotkeys/kcm_hotkeys/hotkeys_proxy_model.h | 81 + khotkeys/kcm_hotkeys/hotkeys_tree_view.cpp | 97 + khotkeys/kcm_hotkeys/hotkeys_tree_view.h | 72 + khotkeys/kcm_hotkeys/hotkeys_widget_base.cpp | 75 + khotkeys/kcm_hotkeys/hotkeys_widget_base.h | 95 + khotkeys/kcm_hotkeys/hotkeys_widget_base.ui | 47 + khotkeys/kcm_hotkeys/hotkeys_widget_iface.cpp | 66 + khotkeys/kcm_hotkeys/hotkeys_widget_iface.h | 73 + khotkeys/kcm_hotkeys/kcm_hotkeys.cpp | 437 + khotkeys/kcm_hotkeys/kcm_hotkeys.h | 97 + khotkeys/kcm_hotkeys/kcm_hotkeys.ui | 86 + khotkeys/kcm_hotkeys/kcm_module_factory.cpp | 35 + khotkeys/kcm_hotkeys/kcm_module_factory.h | 28 + khotkeys/kcm_hotkeys/khotkeys.desktop | 187 + .../kcm_hotkeys/simple_action_data_widget.cpp | 168 + .../kcm_hotkeys/simple_action_data_widget.h | 82 + .../triggers/gesture_trigger_widget.cpp | 84 + .../triggers/gesture_trigger_widget.h | 71 + .../triggers/gesture_trigger_widget.ui | 28 + .../triggers/shortcut_trigger_widget.cpp | 100 + .../triggers/shortcut_trigger_widget.h | 70 + .../triggers/shortcut_trigger_widget.ui | 71 + .../triggers/trigger_widget_base.cpp | 31 + .../triggers/trigger_widget_base.h | 57 + .../triggers/window_trigger_widget.cpp | 141 + .../triggers/window_trigger_widget.h | 72 + .../triggers/window_trigger_widget.ui | 61 + khotkeys/libkhotkeysprivate/CMakeLists.txt | 79 + .../action_data/action_data.cpp | 208 + .../action_data/action_data.h | 92 + .../action_data/action_data_base.cpp | 199 + .../action_data/action_data_base.h | 191 + .../action_data/action_data_group.cpp | 194 + .../action_data/action_data_group.h | 145 + .../action_data/action_data_visitor.cpp | 61 + .../action_data/action_data_visitor.h | 91 + .../action_data/generic_action_data.cpp | 51 + .../action_data/generic_action_data.h | 57 + .../menuentry_shortcut_action_data.cpp | 65 + .../menuentry_shortcut_action_data.h | 61 + .../action_data/simple_action_data.cpp | 127 + .../action_data/simple_action_data.h | 143 + .../libkhotkeysprivate/actions/action.cpp | 55 + .../actions/action_list.cpp | 69 + .../actions/action_visitor.h | 64 + khotkeys/libkhotkeysprivate/actions/actions.h | 380 + .../actions/activate_window_action.cpp | 108 + .../actions/command_url_action.cpp | 153 + .../actions/dbus_action.cpp | 179 + .../actions/keyboard_input_action.cpp | 205 + .../actions/menuentry_action.cpp | 120 + .../conditions/active_window_condition.cpp | 119 + .../conditions/active_window_condition.h | 64 + .../conditions/and_condition.cpp | 78 + .../conditions/condition.cpp | 122 + .../libkhotkeysprivate/conditions/condition.h | 67 + .../conditions/conditions.h | 70 + .../conditions/conditions_list.cpp | 114 + .../conditions/conditions_list.h | 59 + .../conditions/conditions_list_base.cpp | 172 + .../conditions/conditions_list_base.h | 89 + .../conditions/conditions_visitor.cpp | 33 + .../conditions/conditions_visitor.h | 53 + .../conditions/existing_window_condition.cpp | 123 + .../conditions/existing_window_condition.h | 76 + .../conditions/not_condition.cpp | 78 + .../conditions/or_condition.cpp | 73 + khotkeys/libkhotkeysprivate/daemon/daemon.cpp | 178 + khotkeys/libkhotkeysprivate/daemon/daemon.h | 43 + khotkeys/libkhotkeysprivate/input.h | 25 + .../libkhotkeysprivate/khotkeysglobal.cpp | 86 + khotkeys/libkhotkeysprivate/khotkeysglobal.h | 48 + khotkeys/libkhotkeysprivate/libkhotkeysfwd.h | 38 + khotkeys/libkhotkeysprivate/settings.cpp | 533 + khotkeys/libkhotkeysprivate/settings.h | 260 + .../libkhotkeysprivate/settings_reader_v2.cpp | 510 + .../libkhotkeysprivate/settings_reader_v2.h | 112 + .../libkhotkeysprivate/settings_writer.cpp | 276 + khotkeys/libkhotkeysprivate/settings_writer.h | 90 + .../libkhotkeysprivate/shortcuts_handler.cpp | 237 + .../libkhotkeysprivate/shortcuts_handler.h | 120 + khotkeys/libkhotkeysprivate/sound.cpp | 343 + khotkeys/libkhotkeysprivate/sound.h | 58 + khotkeys/libkhotkeysprivate/soundrecorder.cpp | 81 + khotkeys/libkhotkeysprivate/soundrecorder.h | 62 + .../triggers/gesture_trigger.cpp | 502 + .../libkhotkeysprivate/triggers/gestures.cpp | 431 + .../libkhotkeysprivate/triggers/gestures.h | 151 + .../triggers/shortcut_trigger.cpp | 212 + .../libkhotkeysprivate/triggers/trigger.cpp | 63 + .../triggers/trigger_list.cpp | 122 + .../libkhotkeysprivate/triggers/triggers.cpp | 20 + .../libkhotkeysprivate/triggers/triggers.h | 402 + .../triggers/voice_trigger.cpp | 86 + .../triggers/window_trigger.cpp | 270 + khotkeys/libkhotkeysprivate/voices.cpp | 287 + khotkeys/libkhotkeysprivate/voices.h | 83 + .../libkhotkeysprivate/voicesignature.cpp | 423 + khotkeys/libkhotkeysprivate/voicesignature.h | 101 + .../libkhotkeysprivate/windows_handler.cpp | 199 + khotkeys/libkhotkeysprivate/windows_handler.h | 72 + .../window_selection_interface.cpp | 72 + .../window_selection_interface.h | 61 + .../windows_helper/window_selection_list.cpp | 111 + .../windows_helper/window_selection_list.h | 50 + .../windows_helper/window_selection_rules.cpp | 229 + .../windows_helper/window_selection_rules.h | 188 + khotkeys/test/CMakeLists.txt | 10 + khotkeys/test/kdedmodule_daemon_test.cpp | 75 + khotkeys/test/kdedmodule_daemon_test.h | 23 + kinfocenter/CMakeLists.txt | 32 + kinfocenter/Categories/CMakeLists.txt | 5 + .../Categories/deviceinfocategory.desktop | 64 + .../Categories/graphicalinfocategory.desktop | 65 + .../Categories/kinfocentercategory.desktop | 67 + .../Categories/lostfoundcategory.desktop | 83 + .../Categories/networkinfocategory.desktop | 65 + kinfocenter/Messages.sh | 3 + kinfocenter/Modules/CMakeLists.txt | 51 + kinfocenter/Modules/base/CMakeLists.txt | 6 + kinfocenter/Modules/base/Messages.sh | 2 + .../Modules/base/config-infocenter.h.cmake | 11 + kinfocenter/Modules/base/info_aix.cpp | 239 + kinfocenter/Modules/base/info_fbsd.cpp | 261 + kinfocenter/Modules/base/info_generic.cpp | 49 + kinfocenter/Modules/base/info_hpux.cpp | 240 + kinfocenter/Modules/base/info_linux.cpp | 179 + kinfocenter/Modules/base/info_netbsd.cpp | 179 + kinfocenter/Modules/base/info_openbsd.cpp | 172 + kinfocenter/Modules/base/info_osx.cpp | 75 + kinfocenter/Modules/base/info_sgi.cpp | 36 + kinfocenter/Modules/base/info_solaris.cpp | 40 + kinfocenter/Modules/base/os_base.h | 358 + kinfocenter/Modules/base/os_current.cpp | 46 + kinfocenter/Modules/base/os_current.h | 145 + kinfocenter/Modules/devinfo/CMakeLists.txt | 9 + kinfocenter/Modules/devinfo/Messages.sh | 2 + kinfocenter/Modules/devinfo/devicelisting.cpp | 263 + kinfocenter/Modules/devinfo/devicelisting.h | 103 + kinfocenter/Modules/devinfo/devinfo.cpp | 98 + kinfocenter/Modules/devinfo/devinfo.desktop | 186 + kinfocenter/Modules/devinfo/devinfo.h | 57 + kinfocenter/Modules/devinfo/infopanel.cpp | 143 + kinfocenter/Modules/devinfo/infopanel.h | 79 + kinfocenter/Modules/devinfo/nicsignals.cpp | 42 + kinfocenter/Modules/devinfo/nicsignals.h | 52 + kinfocenter/Modules/devinfo/qvlistlayout.cpp | 66 + kinfocenter/Modules/devinfo/qvlistlayout.h | 37 + kinfocenter/Modules/devinfo/soldevice.cpp | 149 + kinfocenter/Modules/devinfo/soldevice.h | 133 + .../Modules/devinfo/soldevicetypes.cpp | 946 ++ kinfocenter/Modules/devinfo/soldevicetypes.h | 221 + kinfocenter/Modules/devinfo/solidhelper.cpp | 48 + kinfocenter/Modules/devinfo/solidhelper.h | 37 + kinfocenter/Modules/info/AUTHORS | 32 + kinfocenter/Modules/info/CMakeLists.txt | 31 + kinfocenter/Modules/info/Messages.sh | 2 + kinfocenter/Modules/info/dma.desktop | 244 + kinfocenter/Modules/info/info.cpp | 119 + kinfocenter/Modules/info/info.h | 57 + kinfocenter/Modules/info/interrupts.desktop | 248 + kinfocenter/Modules/info/ioports.desktop | 244 + kinfocenter/Modules/info/main.cpp | 100 + kinfocenter/Modules/info/scsi.desktop | 246 + kinfocenter/Modules/info/xserver.desktop | 242 + .../Modules/infosummary/CMakeLists.txt | 8 + kinfocenter/Modules/infosummary/Messages.sh | 2 + .../Modules/infosummary/defaultboxwidget.cpp | 101 + .../Modules/infosummary/defaultboxwidget.h | 64 + kinfocenter/Modules/infosummary/infosum.cpp | 149 + kinfocenter/Modules/infosummary/infosum.h | 74 + .../infosummary/kcm_infosummary.desktop | 189 + kinfocenter/Modules/infosummary/osdepinfo.cpp | 56 + kinfocenter/Modules/infosummary/osdepinfo.h | 43 + .../Modules/infosummary/osdepinfo_unix.cpp | 34 + .../Modules/infosummary/progressboxwidget.cpp | 92 + .../Modules/infosummary/progressboxwidget.h | 61 + kinfocenter/Modules/memory/CMakeLists.txt | 18 + kinfocenter/Modules/memory/Messages.sh | 2 + kinfocenter/Modules/memory/base.h | 48 + kinfocenter/Modules/memory/chartWidget.cpp | 146 + kinfocenter/Modules/memory/chartWidget.h | 76 + kinfocenter/Modules/memory/kcm_memory.desktop | 240 + kinfocenter/Modules/memory/memory.cpp | 327 + kinfocenter/Modules/memory/memory.h | 70 + kinfocenter/Modules/memory/memory_fbsd.cpp | 67 + kinfocenter/Modules/memory/memory_hpux.cpp | 95 + kinfocenter/Modules/memory/memory_linux.cpp | 40 + kinfocenter/Modules/memory/memory_netbsd.cpp | 114 + kinfocenter/Modules/memory/memory_osx.cpp | 94 + kinfocenter/Modules/memory/memory_sgi.cpp | 75 + kinfocenter/Modules/memory/memory_solaris.cpp | 95 + kinfocenter/Modules/memory/memory_tru64.cpp | 83 + .../Modules/memory/physicalMemoryChart.cpp | 63 + .../Modules/memory/physicalMemoryChart.h | 53 + .../Modules/memory/swapMemoryChart.cpp | 56 + kinfocenter/Modules/memory/swapMemoryChart.h | 53 + .../Modules/memory/totalMemoryChart.cpp | 53 + kinfocenter/Modules/memory/totalMemoryChart.h | 53 + kinfocenter/Modules/nics/AUTHORS | 2 + kinfocenter/Modules/nics/CMakeLists.txt | 29 + kinfocenter/Modules/nics/Messages.sh | 2 + kinfocenter/Modules/nics/config-nic.h.cmake | 12 + kinfocenter/Modules/nics/nic.cpp | 319 + kinfocenter/Modules/nics/nic.desktop | 198 + kinfocenter/Modules/nics/nic.h | 44 + kinfocenter/Modules/opengl/CMakeLists.txt | 39 + kinfocenter/Modules/opengl/Messages.sh | 3 + kinfocenter/Modules/opengl/opengl.cpp | 876 ++ kinfocenter/Modules/opengl/opengl.desktop | 238 + kinfocenter/Modules/opengl/opengl.h | 40 + kinfocenter/Modules/opengl/opengl.ui | 26 + .../Modules/opengl/openglconfig.h.cmake | 27 + kinfocenter/Modules/pci/CMakeLists.txt | 39 + kinfocenter/Modules/pci/Messages.sh | 2 + kinfocenter/Modules/pci/kcm_pci.cpp | 94 + kinfocenter/Modules/pci/kcm_pci.desktop | 240 + kinfocenter/Modules/pci/kcm_pci.h | 51 + kinfocenter/Modules/pci/kpci.cpp | 808 ++ kinfocenter/Modules/pci/kpci.h | 14 + kinfocenter/Modules/pci/kpci_private.h | 784 ++ kinfocenter/Modules/samba/AUTHORS | 32 + kinfocenter/Modules/samba/CMakeLists.txt | 21 + kinfocenter/Modules/samba/Messages.sh | 2 + kinfocenter/Modules/samba/kcmsambaimports.cpp | 90 + kinfocenter/Modules/samba/kcmsambaimports.h | 50 + kinfocenter/Modules/samba/kcmsambalog.cpp | 232 + kinfocenter/Modules/samba/kcmsambalog.h | 83 + .../Modules/samba/kcmsambastatistics.cpp | 309 + .../Modules/samba/kcmsambastatistics.h | 113 + kinfocenter/Modules/samba/ksmbstatus.cpp | 217 + kinfocenter/Modules/samba/ksmbstatus.h | 62 + kinfocenter/Modules/samba/main.cpp | 107 + kinfocenter/Modules/samba/smbstatus.desktop | 241 + kinfocenter/Modules/usbview/CMakeLists.txt | 20 + kinfocenter/Modules/usbview/Messages.sh | 2 + kinfocenter/Modules/usbview/classes.i18n | 48 + kinfocenter/Modules/usbview/kcmusb.cpp | 178 + kinfocenter/Modules/usbview/kcmusb.desktop | 234 + kinfocenter/Modules/usbview/kcmusb.h | 43 + kinfocenter/Modules/usbview/usb.ids | 6430 +++++++++++ kinfocenter/Modules/usbview/usbdb.cpp | 108 + kinfocenter/Modules/usbview/usbdb.h | 36 + kinfocenter/Modules/usbview/usbdevices.cpp | 435 + kinfocenter/Modules/usbview/usbdevices.h | 91 + kinfocenter/Modules/view1394/CMakeLists.txt | 22 + kinfocenter/Modules/view1394/Messages.sh | 3 + kinfocenter/Modules/view1394/README | 13 + .../Modules/view1394/kcmview1394.desktop | 230 + kinfocenter/Modules/view1394/oui.db | 7965 ++++++++++++++ kinfocenter/Modules/view1394/view1394.cpp | 318 + kinfocenter/Modules/view1394/view1394.h | 74 + .../Modules/view1394/view1394widget.ui | 173 + kinfocenter/ToolTips/ktooltip.cpp | 102 + kinfocenter/ToolTips/ktooltip.h | 46 + kinfocenter/ToolTips/ktooltipwindow.cpp | 96 + kinfocenter/ToolTips/ktooltipwindow_p.h | 45 + kinfocenter/ToolTips/tooltipmanager.cpp | 233 + kinfocenter/ToolTips/tooltipmanager.h | 82 + kinfocenter/infocenter.cpp | 282 + kinfocenter/infocenter.h | 164 + kinfocenter/infokcmmodel.cpp | 269 + kinfocenter/infokcmmodel.h | 136 + kinfocenter/infokcmproxymodel.cpp | 54 + kinfocenter/infokcmproxymodel.h | 61 + kinfocenter/kcmcategoryitem.cpp | 95 + kinfocenter/kcmcategoryitem.h | 98 + kinfocenter/kcmcontainer.cpp | 149 + kinfocenter/kcmcontainer.h | 119 + kinfocenter/kcmtreeitem.cpp | 163 + kinfocenter/kcmtreeitem.h | 165 + kinfocenter/kinfocenter.desktop | 192 + kinfocenter/kinfocenterui.rc | 22 + kinfocenter/main.cpp | 63 + kinfocenter/main.h | 48 + kinfocenter/sidepanel.cpp | 138 + kinfocenter/sidepanel.h | 138 + klipper/CMakeLists.txt | 56 + klipper/Messages.sh | 5 + klipper/actionsconfig.ui | 118 + klipper/actionstreewidget.cpp | 64 + klipper/actionstreewidget.h | 76 + klipper/clipcommandprocess.cpp | 83 + klipper/clipcommandprocess.h | 44 + klipper/configdialog.cpp | 417 + klipper/configdialog.h | 124 + klipper/editactiondialog.cpp | 383 + klipper/editactiondialog.h | 73 + klipper/editactiondialog.ui | 226 + klipper/generalconfig.ui | 166 + klipper/history.cpp | 247 + klipper/history.h | 185 + klipper/historyimageitem.cpp | 64 + klipper/historyimageitem.h | 58 + klipper/historyitem.cpp | 124 + klipper/historyitem.h | 130 + klipper/historystringitem.cpp | 41 + klipper/historystringitem.h | 54 + klipper/historyurlitem.cpp | 73 + klipper/historyurlitem.h | 47 + klipper/klipper-kconfigxt.upd | 7 + klipper/klipper.cpp | 1092 ++ klipper/klipper.desktop | 272 + klipper/klipper.h | 207 + klipper/klipper.kcfg | 88 + klipper/klipperpopup.cpp | 298 + klipper/klipperpopup.h | 124 + klipper/klipperrc.desktop | 2431 +++++ klipper/klippersettings.kcfgc | 7 + klipper/main.cpp | 53 + klipper/popupproxy.cpp | 182 + klipper/popupproxy.h | 89 + klipper/tray.cpp | 78 + klipper/tray.h | 46 + klipper/urlgrabber.cpp | 526 + klipper/urlgrabber.h | 193 + klipper/version.h | 25 + kmenuedit/CMakeLists.txt | 39 + kmenuedit/Messages.sh | 3 + kmenuedit/basictab.cpp | 550 + kmenuedit/basictab.h | 91 + kmenuedit/hi16-app-kmenuedit.png | Bin 0 -> 649 bytes kmenuedit/hi22-app-kmenuedit.png | Bin 0 -> 1450 bytes kmenuedit/hi32-app-kmenuedit.png | Bin 0 -> 2054 bytes kmenuedit/hi48-app-kmenuedit.png | Bin 0 -> 1518 bytes kmenuedit/khotkeys.cpp | 115 + kmenuedit/khotkeys.h | 39 + kmenuedit/klinespellchecking.cpp | 108 + kmenuedit/klinespellchecking.h | 50 + kmenuedit/kmenuedit.cpp | 253 + kmenuedit/kmenuedit.desktop | 103 + kmenuedit/kmenuedit.h | 64 + kmenuedit/kmenueditui.rc | 52 + kmenuedit/main.cpp | 88 + kmenuedit/menufile.cpp | 568 + kmenuedit/menufile.h | 118 + kmenuedit/menuinfo.cpp | 479 + kmenuedit/menuinfo.h | 193 + kmenuedit/org.kde.kmenuedit.xml | 13 + kmenuedit/pixmaps/CMakeLists.txt | 2 + kmenuedit/pixmaps/hi22-action-menu_new.png | Bin 0 -> 1247 bytes .../pixmaps/hi22-action-menu_new_sep.png | Bin 0 -> 138 bytes kmenuedit/pixmaps/hi32-action-menu_new.png | Bin 0 -> 2054 bytes .../pixmaps/hi32-action-menu_new_sep.png | Bin 0 -> 562 bytes kmenuedit/preferencesdlg.cpp | 90 + kmenuedit/preferencesdlg.h | 68 + kmenuedit/treeview.cpp | 2002 ++++ kmenuedit/treeview.h | 242 + krunner/CMakeLists.txt | 82 + krunner/HACKING | 1 + krunner/Messages.sh | 4 + krunner/README | 34 + krunner/configdialog.cpp | 171 + krunner/configdialog.h | 68 + krunner/dbus/org.kde.krunner.App.xml | 33 + krunner/dbus/org.kde.krunner.service.in | 4 + krunner/interfaceOptions.ui | 105 + krunner/interfaces/default/interface.cpp | 664 ++ krunner/interfaces/default/interface.h | 124 + .../default/krunnerhistorycombobox.cpp | 130 + .../default/krunnerhistorycombobox.h | 63 + krunner/interfaces/default/resultitem.cpp | 656 ++ krunner/interfaces/default/resultitem.h | 155 + krunner/interfaces/default/resultscene.cpp | 422 + krunner/interfaces/default/resultscene.h | 107 + krunner/interfaces/default/resultview.cpp | 206 + krunner/interfaces/default/resultview.h | 68 + krunner/interfaces/default/selectionbar.cpp | 88 + krunner/interfaces/default/selectionbar.h | 52 + .../interfaces/quicksand/qs_completionbox.cpp | 97 + .../interfaces/quicksand/qs_completionbox.h | 72 + krunner/interfaces/quicksand/qs_dialog.cpp | 321 + krunner/interfaces/quicksand/qs_dialog.h | 79 + krunner/interfaces/quicksand/qs_matchitem.cpp | 84 + krunner/interfaces/quicksand/qs_matchitem.h | 78 + krunner/interfaces/quicksand/qs_matchview.cpp | 693 ++ krunner/interfaces/quicksand/qs_matchview.h | 165 + .../quicksand/qs_queryactionitem.cpp | 39 + .../interfaces/quicksand/qs_queryactionitem.h | 45 + .../quicksand/qs_querymatchitem.cpp | 35 + .../interfaces/quicksand/qs_querymatchitem.h | 40 + krunner/interfaces/quicksand/qs_statusbar.cpp | 84 + krunner/interfaces/quicksand/qs_statusbar.h | 55 + krunner/kcfg/klaunch.kcfg | 40 + krunner/kcfg/klaunchsettings.kcfgc | 4 + krunner/kcfg/krunner.kcfg | 68 + krunner/kcfg/krunnersettings.kcfgc | 4 + krunner/krunner.desktop | 86 + krunner/krunnerapp.cpp | 390 + krunner/krunnerapp.h | 106 + krunner/krunnerdialog.cpp | 556 + krunner/krunnerdialog.h | 126 + krunner/ksystemactivitydialog.cpp | 114 + krunner/ksystemactivitydialog.h | 63 + krunner/main.cpp | 68 + krunner/startupid.cpp | 365 + krunner/startupid.h | 70 + kscreensaver.pamd | 4 + kscreensaver/CMakeLists.txt | 4 + kscreensaver/README | 7 + .../kblank_screensaver/CMakeLists.txt | 23 + kscreensaver/kblank_screensaver/Messages.sh | 2 + kscreensaver/kblank_screensaver/blankscrn.cpp | 161 + kscreensaver/kblank_screensaver/blankscrn.h | 55 + .../kblank_screensaver/kblank.desktop | 370 + .../krandom_screensaver/CMakeLists.txt | 28 + kscreensaver/krandom_screensaver/Messages.sh | 2 + .../krandom_screensaver/krandom.desktop | 371 + kscreensaver/krandom_screensaver/random.cpp | 228 + kscreensaver/krandom_screensaver/random.h | 37 + kscreensaver/libkscreensaver/CMakeLists.txt | 21 + kscreensaver/libkscreensaver/Messages.sh | 2 + .../kscreensaver-kde3to4-porting.py | 90 + kscreensaver/libkscreensaver/kscreensaver.cpp | 231 + kscreensaver/libkscreensaver/kscreensaver.h | 168 + .../libkscreensaver/kscreensaver_export.h | 40 + .../libkscreensaver/kscreensaver_vroot.h | 132 + kscreensaver/libkscreensaver/main.cpp | 238 + .../libkscreensaver/screensaver.desktop | 92 + ksmserver/CMakeLists.txt | 87 + ksmserver/Copyright.txt | 56 + ksmserver/KSMServerInterface.h | 48 + ksmserver/LICENSE | 16 + ksmserver/Messages.sh | 2 + ksmserver/README | 162 + ksmserver/client.cpp | 185 + ksmserver/client.h | 66 + ksmserver/config-ksmserver.h.cmake | 4 + ksmserver/curtaineffect.cpp | 64 + ksmserver/curtaineffect.h | 46 + ksmserver/fadeeffect.cpp | 574 + ksmserver/fadeeffect.h | 97 + ksmserver/global.h | 31 + ksmserver/kcheckrunning.cpp | 33 + ksmserver/kcm/CMakeLists.txt | 18 + ksmserver/kcm/Messages.sh | 5 + ksmserver/kcm/kcmsmserver.cpp | 137 + ksmserver/kcm/kcmsmserver.desktop | 205 + ksmserver/kcm/kcmsmserver.h | 46 + ksmserver/kcm/smserverconfigdlg.ui | 171 + ksmserver/kcm/smserverconfigimpl.cpp | 39 + ksmserver/kcm/smserverconfigimpl.h | 50 + ksmserver/ksmserver_shortcuts.upd | 14 + ksmserver/legacy.cpp | 412 + ksmserver/logouteffect.cpp | 115 + ksmserver/logouteffect.h | 50 + ksmserver/main.cpp | 322 + ksmserver/org.kde.KSMServerInterface.xml | 42 + ksmserver/screenlocker/CMakeLists.txt | 36 + ksmserver/screenlocker/DESIGN | 25 + ksmserver/screenlocker/Messages.sh | 4 + ksmserver/screenlocker/autologout.cpp | 118 + ksmserver/screenlocker/autologout.h | 53 + ksmserver/screenlocker/data/CMakeLists.txt | 8 + .../force_krunner_lock_shortcut_unreg.cpp | 38 + .../kscreenlocker_locksession-shortcut.upd | 10 + .../dbus/org.freedesktop.ScreenSaver.xml | 41 + .../screenlocker/dbus/org.kde.screensaver.xml | 11 + ksmserver/screenlocker/greeter/CMakeLists.txt | 23 + ksmserver/screenlocker/greeter/Messages.sh | 3 + ksmserver/screenlocker/greeter/greeter.cpp | 543 + ksmserver/screenlocker/greeter/greeter.h | 187 + ksmserver/screenlocker/greeter/greeterapp.cpp | 519 + ksmserver/screenlocker/greeter/greeterapp.h | 85 + ksmserver/screenlocker/greeter/main.cpp | 109 + .../greeter/screensaverwindow.cpp | 225 + .../screenlocker/greeter/screensaverwindow.h | 72 + ksmserver/screenlocker/greeter/sessions.cpp | 162 + ksmserver/screenlocker/greeter/sessions.h | 95 + .../contents/ui/AccelButton.qml | 26 + .../contents/ui/Greeter.qml | 181 + .../contents/ui/SessionSwitching.qml | 147 + .../contents/ui/main.qml | 118 + .../org.kde.passworddialog/metadata.desktop | 101 + ksmserver/screenlocker/interface.cpp | 234 + ksmserver/screenlocker/interface.h | 129 + .../kcfg/kscreensaversettings.kcfg | 102 + .../kcfg/kscreensaversettings.kcfgc | 4 + ksmserver/screenlocker/kscreenlocker.notifyrc | 753 ++ ksmserver/screenlocker/ksldapp.cpp | 391 + ksmserver/screenlocker/ksldapp.h | 137 + ksmserver/screenlocker/lockwindow.cpp | 548 + ksmserver/screenlocker/lockwindow.h | 73 + ksmserver/server.cpp | 1082 ++ ksmserver/server.h | 280 + ksmserver/shutdown.cpp | 709 ++ ksmserver/shutdowndlg.cpp | 356 + ksmserver/shutdowndlg.h | 103 + ksmserver/startup.cpp | 566 + ksmserver/tests/CMakeLists.txt | 14 + ksmserver/tests/test.cpp | 47 + ksmserver/themes/contour/ContourButton.qml | 124 + ksmserver/themes/contour/main.qml | 151 + ksmserver/themes/contour/metadata.desktop | 107 + ksmserver/themes/contour/screenshot.png | Bin 0 -> 1026259 bytes ksmserver/themes/default/ContextMenu.qml | 131 + ksmserver/themes/default/KSMButton.qml | 245 + ksmserver/themes/default/MenuItem.qml | 160 + ksmserver/themes/default/helper.js | 20 + ksmserver/themes/default/main.qml | 453 + ksmserver/themes/default/metadata.desktop | 151 + ksmserver/themes/default/screenshot.png | Bin 0 -> 182970 bytes ksplash/CMakeLists.txt | 5 + ksplash/README | 62 + ksplash/kcm/CMakeLists.txt | 15 + ksplash/kcm/Messages.sh | 2 + ksplash/kcm/installer.cpp | 580 + ksplash/kcm/installer.h | 92 + ksplash/kcm/ksplash.knsrc | 5 + ksplash/kcm/ksplashthememgr.desktop | 226 + ksplash/kcm/main.cpp | 113 + ksplash/kcm/pics/CMakeLists.txt | 1 + ksplash/kcm/pics/hi128-app-ksplash.png | Bin 0 -> 13862 bytes ksplash/kcm/pics/hi16-app-ksplash.png | Bin 0 -> 1021 bytes ksplash/kcm/pics/hi22-app-ksplash.png | Bin 0 -> 1346 bytes ksplash/kcm/pics/hi32-app-ksplash.png | Bin 0 -> 2204 bytes ksplash/kcm/pics/hi48-app-ksplash.png | Bin 0 -> 3894 bytes ksplash/kcm/pics/hi64-app-ksplash.png | Bin 0 -> 5890 bytes ksplash/ksplashqml/CMakeLists.txt | 20 + ksplash/ksplashqml/SplashApp.cpp | 155 + ksplash/ksplashqml/SplashApp.h | 60 + ksplash/ksplashqml/SplashWindow.cpp | 85 + ksplash/ksplashqml/SplashWindow.h | 46 + ksplash/ksplashqml/SystemInfo.h | 60 + ksplash/ksplashqml/main.cpp | 68 + ksplash/ksplashqml/themes/CMakeLists.txt | 1 + .../themes/Minimalistic/CMakeLists.txt | 7 + .../themes/Minimalistic/Preview.png | Bin 0 -> 3935 bytes .../ksplashqml/themes/Minimalistic/Theme.rc | 9 + .../themes/Minimalistic/images/kdegear.png | Bin 0 -> 4375 bytes .../themes/Minimalistic/images/kdeletter.png | Bin 0 -> 2947 bytes .../Minimalistic/images/kdelogo-contrast.png | Bin 0 -> 22780 bytes .../themes/Minimalistic/images/kdelogo.png | Bin 0 -> 20156 bytes .../themes/Minimalistic/images/kdemask.png | Bin 0 -> 1090 bytes .../ksplashqml/themes/Minimalistic/main.qml | 181 + ksplash/ksplashx/CMakeLists.txt | 54 + ksplash/ksplashx/LICENSE | 12 + ksplash/ksplashx/README | 117 + ksplash/ksplashx/asm_scale.S | 806 ++ ksplash/ksplashx/defs.cpp | 77 + ksplash/ksplashx/defs.h | 166 + ksplash/ksplashx/kcpuinfo.cpp | 186 + ksplash/ksplashx/kcpuinfo.h | 67 + ksplash/ksplashx/main.cpp | 157 + ksplash/ksplashx/pixmap.cpp | 1044 ++ ksplash/ksplashx/pixmap.h | 82 + ksplash/ksplashx/qcolor.cpp | 1041 ++ ksplash/ksplashx/qcolor.h | 246 + ksplash/ksplashx/qcolor_p.cpp | 820 ++ ksplash/ksplashx/qcolor_p.h | 73 + ksplash/ksplashx/qcolor_x11.cpp | 871 ++ ksplash/ksplashx/qdatastream.h | 44 + ksplash/ksplashx/qglobal.cpp | 127 + ksplash/ksplashx/qglobal.h | 51 + ksplash/ksplashx/qimage.cpp | 6465 +++++++++++ ksplash/ksplashx/qimage.h | 430 + ksplash/ksplashx/qjpegio.cpp | 270 + ksplash/ksplashx/qnamespace.h | 924 ++ ksplash/ksplashx/qpngio.cpp | 365 + ksplash/ksplashx/qpoint.h | 226 + ksplash/ksplashx/qrect.cpp | 967 ++ ksplash/ksplashx/qrect.h | 283 + ksplash/ksplashx/qshared.h | 65 + ksplash/ksplashx/qsize.cpp | 439 + ksplash/ksplashx/qsize.h | 245 + ksplash/ksplashx/qwindowdefs.h | 44 + ksplash/ksplashx/qwinexport.h | 44 + ksplash/ksplashx/scale.cpp | 1054 ++ ksplash/ksplashx/scale.h | 87 + ksplash/ksplashx/scale/CMakeLists.txt | 8 + ksplash/ksplashx/scale/main.cpp | 45 + ksplash/ksplashx/splash.cpp | 1274 +++ ksplash/ksplashx/splash.h | 28 + ksplash/ksplashx/utils/CMakeLists.txt | 15 + ksplash/ksplashx/utils/blend.py | 66 + .../ksplashx/utils/fromksplashmldefault.sh | 104 + ksplash/ksplashx/utils/prepareanim.cpp | 47 + ksplash/ksplashx/utils/shade.cpp | 28 + ksplash/ksplashx/x11_defs.cpp | 287 + ksplash/ksplashx/x11_defs.h | 97 + ksplash/none/CMakeLists.txt | 1 + ksplash/none/Theme.rc | 7 + ksplash/simple/CMakeLists.txt | 19 + ksplash/simple/full/CMakeLists.txt | 1 + ksplash/simple/full/Preview.png | Bin 0 -> 198 bytes ksplash/simple/full/Theme.rc | 8 + ksplash/simple/main.cpp | 278 + ksplash/simple/small/CMakeLists.txt | 1 + ksplash/simple/small/Preview.png | Bin 0 -> 51211 bytes ksplash/simple/small/Theme.rc | 8 + kstartupconfig/CMakeLists.txt | 24 + kstartupconfig/kdostartupconfig.cpp | 169 + kstartupconfig/kstartupconfig.c | 158 + kstyles/CMakeLists.txt | 2 + kstyles/Mainpage.dox | 9 + kstyles/Messages.sh | 3 + kstyles/oxygen/CMakeLists.txt | 81 + kstyles/oxygen/README | 38 + .../oxygen/animations/oxygenanimationdata.cpp | 48 + .../oxygen/animations/oxygenanimationdata.h | 114 + .../oxygen/animations/oxygenanimations.cpp | 377 + kstyles/oxygen/animations/oxygenanimations.h | 217 + .../oxygen/animations/oxygenbaseengine.cpp | 28 + kstyles/oxygen/animations/oxygenbaseengine.h | 97 + kstyles/oxygen/animations/oxygendatamap.h | 176 + .../animations/oxygendockseparatordata.cpp | 81 + .../animations/oxygendockseparatordata.h | 170 + .../animations/oxygendockseparatorengine.cpp | 50 + .../animations/oxygendockseparatorengine.h | 112 + .../oxygen/animations/oxygenenabledata.cpp | 59 + kstyles/oxygen/animations/oxygenenabledata.h | 59 + .../oxygen/animations/oxygengenericdata.cpp | 42 + kstyles/oxygen/animations/oxygengenericdata.h | 93 + .../animations/oxygenheaderviewdata.cpp | 138 + .../oxygen/animations/oxygenheaderviewdata.h | 178 + .../animations/oxygenheaderviewengine.cpp | 57 + .../animations/oxygenheaderviewengine.h | 101 + .../oxygen/animations/oxygenmdiwindowdata.cpp | 91 + .../oxygen/animations/oxygenmdiwindowdata.h | 164 + .../animations/oxygenmdiwindowengine.cpp | 50 + .../oxygen/animations/oxygenmdiwindowengine.h | 115 + .../oxygen/animations/oxygenmenubardata.cpp | 227 + kstyles/oxygen/animations/oxygenmenubardata.h | 466 + .../oxygen/animations/oxygenmenubardata_imp.h | 291 + .../oxygen/animations/oxygenmenubarengine.cpp | 170 + .../oxygen/animations/oxygenmenubarengine.h | 240 + kstyles/oxygen/animations/oxygenmenudata.cpp | 28 + kstyles/oxygen/animations/oxygenmenudata.h | 115 + .../oxygen/animations/oxygenmenuengine.cpp | 194 + kstyles/oxygen/animations/oxygenmenuengine.h | 246 + .../animations/oxygenprogressbardata.cpp | 135 + .../oxygen/animations/oxygenprogressbardata.h | 91 + .../animations/oxygenprogressbarengine.cpp | 122 + .../animations/oxygenprogressbarengine.h | 151 + .../oxygen/animations/oxygenscrollbardata.cpp | 224 + .../oxygen/animations/oxygenscrollbardata.h | 243 + .../animations/oxygenscrollbarengine.cpp | 69 + .../oxygen/animations/oxygenscrollbarengine.h | 135 + .../oxygen/animations/oxygensliderdata.cpp | 79 + kstyles/oxygen/animations/oxygensliderdata.h | 81 + .../oxygen/animations/oxygensliderengine.cpp | 50 + .../oxygen/animations/oxygensliderengine.h | 115 + .../oxygen/animations/oxygenspinboxdata.cpp | 57 + kstyles/oxygen/animations/oxygenspinboxdata.h | 170 + .../oxygen/animations/oxygenspinboxengine.cpp | 50 + .../oxygen/animations/oxygenspinboxengine.h | 115 + .../animations/oxygensplitterengine.cpp | 63 + .../oxygen/animations/oxygensplitterengine.h | 116 + .../oxygen/animations/oxygentabbardata.cpp | 131 + kstyles/oxygen/animations/oxygentabbardata.h | 158 + .../oxygen/animations/oxygentabbarengine.cpp | 57 + .../oxygen/animations/oxygentabbarengine.h | 101 + .../oxygen/animations/oxygentoolbardata.cpp | 292 + kstyles/oxygen/animations/oxygentoolbardata.h | 219 + .../oxygen/animations/oxygentoolbarengine.cpp | 113 + .../oxygen/animations/oxygentoolbarengine.h | 124 + .../oxygen/animations/oxygentoolboxengine.cpp | 63 + .../oxygen/animations/oxygentoolboxengine.h | 116 + .../animations/oxygenwidgetstatedata.cpp | 48 + .../oxygen/animations/oxygenwidgetstatedata.h | 67 + .../animations/oxygenwidgetstateengine.cpp | 113 + .../animations/oxygenwidgetstateengine.h | 122 + kstyles/oxygen/config/CMakeLists.txt | 44 + kstyles/oxygen/config/main.cpp | 53 + .../config/oxygenanimationconfigwidget.cpp | 284 + .../config/oxygenanimationconfigwidget.h | 80 + kstyles/oxygen/config/oxygenconfigdialog.cpp | 254 + kstyles/oxygen/config/oxygenconfigdialog.h | 106 + .../oxygenfollowmouseanimationconfigitem.cpp | 84 + .../oxygenfollowmouseanimationconfigitem.h | 156 + kstyles/oxygen/config/oxygenstyleconfig.cpp | 415 + kstyles/oxygen/config/oxygenstyleconfig.h | 119 + .../ui/oxygenfollowmouseanimationconfigbox.ui | 143 + kstyles/oxygen/config/ui/oxygenstyleconfig.ui | 675 ++ kstyles/oxygen/debug/oxygenwidgetexplorer.cpp | 168 + kstyles/oxygen/debug/oxygenwidgetexplorer.h | 86 + kstyles/oxygen/demo/CMakeLists.txt | 39 + kstyles/oxygen/demo/main.cpp | 57 + kstyles/oxygen/demo/oxygenbenchmarkwidget.cpp | 175 + kstyles/oxygen/demo/oxygenbenchmarkwidget.h | 99 + .../oxygen/demo/oxygenbuttondemowidget.cpp | 266 + kstyles/oxygen/demo/oxygenbuttondemowidget.h | 84 + kstyles/oxygen/demo/oxygendemodialog.cpp | 236 + kstyles/oxygen/demo/oxygendemodialog.h | 108 + kstyles/oxygen/demo/oxygendemowidget.cpp | 28 + kstyles/oxygen/demo/oxygendemowidget.h | 67 + kstyles/oxygen/demo/oxygenframedemowidget.cpp | 109 + kstyles/oxygen/demo/oxygenframedemowidget.h | 85 + kstyles/oxygen/demo/oxygeninputdemowidget.cpp | 140 + kstyles/oxygen/demo/oxygeninputdemowidget.h | 73 + kstyles/oxygen/demo/oxygenlistdemowidget.cpp | 91 + kstyles/oxygen/demo/oxygenlistdemowidget.h | 66 + kstyles/oxygen/demo/oxygenmdidemowidget.cpp | 97 + kstyles/oxygen/demo/oxygenmdidemowidget.h | 64 + kstyles/oxygen/demo/oxygensimulator.cpp | 858 ++ kstyles/oxygen/demo/oxygensimulator.h | 267 + .../oxygen/demo/oxygensliderdemowidget.cpp | 138 + kstyles/oxygen/demo/oxygensliderdemowidget.h | 107 + kstyles/oxygen/demo/oxygentabdemowidget.cpp | 102 + kstyles/oxygen/demo/oxygentabdemowidget.h | 147 + kstyles/oxygen/demo/oxygentabwidget.h | 101 + .../oxygen/demo/ui/oxygenbenchmarkwidget.ui | 103 + .../oxygen/demo/ui/oxygenbuttondemowidget.ui | 548 + .../oxygen/demo/ui/oxygenframedemowidget.ui | 200 + .../oxygen/demo/ui/oxygeninputdemowidget.ui | 196 + .../oxygen/demo/ui/oxygenlistdemowidget.ui | 188 + kstyles/oxygen/demo/ui/oxygenmdidemowidget.ui | 165 + .../oxygen/demo/ui/oxygensliderdemowidget.ui | 167 + kstyles/oxygen/demo/ui/oxygentabdemowidget.ui | 251 + kstyles/oxygen/oxygen.kcfg | 302 + kstyles/oxygen/oxygen.themerc | 171 + kstyles/oxygen/oxygenaddeventfilter.h | 63 + kstyles/oxygen/oxygenanimationmodes.h | 48 + kstyles/oxygen/oxygenblurhelper.cpp | 307 + kstyles/oxygen/oxygenblurhelper.h | 172 + kstyles/oxygen/oxygenframeshadow.cpp | 561 + kstyles/oxygen/oxygenframeshadow.h | 301 + kstyles/oxygen/oxygenmdiwindowshadow.cpp | 223 + kstyles/oxygen/oxygenmdiwindowshadow.h | 193 + kstyles/oxygen/oxygenmetrics.h | 145 + kstyles/oxygen/oxygenmnemonics.cpp | 98 + kstyles/oxygen/oxygenmnemonics.h | 74 + kstyles/oxygen/oxygenpropertynames.cpp | 35 + kstyles/oxygen/oxygenpropertynames.h | 43 + kstyles/oxygen/oxygenshadowhelper.cpp | 424 + kstyles/oxygen/oxygenshadowhelper.h | 165 + kstyles/oxygen/oxygensplitterproxy.cpp | 354 + kstyles/oxygen/oxygensplitterproxy.h | 141 + kstyles/oxygen/oxygenstyle.cpp | 9640 +++++++++++++++++ kstyles/oxygen/oxygenstyle.h | 1003 ++ kstyles/oxygen/oxygenstyleconfigdata.kcfgc | 6 + kstyles/oxygen/oxygenstylehelper.cpp | 1290 +++ kstyles/oxygen/oxygenstylehelper.h | 295 + kstyles/oxygen/oxygenwindowmanager.cpp | 733 ++ kstyles/oxygen/oxygenwindowmanager.h | 319 + .../oxygen/transitions/oxygencomboboxdata.cpp | 153 + .../oxygen/transitions/oxygencomboboxdata.h | 95 + .../transitions/oxygencomboboxengine.cpp | 50 + .../oxygen/transitions/oxygencomboboxengine.h | 86 + .../oxygen/transitions/oxygenlabeldata.cpp | 223 + kstyles/oxygen/transitions/oxygenlabeldata.h | 114 + .../oxygen/transitions/oxygenlabelengine.cpp | 48 + .../oxygen/transitions/oxygenlabelengine.h | 86 + .../oxygen/transitions/oxygenlineeditdata.cpp | 263 + .../oxygen/transitions/oxygenlineeditdata.h | 144 + .../transitions/oxygenlineeditengine.cpp | 60 + .../oxygen/transitions/oxygenlineeditengine.h | 86 + .../transitions/oxygenstackedwidgetdata.cpp | 140 + .../transitions/oxygenstackedwidgetdata.h | 78 + .../transitions/oxygenstackedwidgetengine.cpp | 48 + .../transitions/oxygenstackedwidgetengine.h | 86 + .../transitions/oxygentransitiondata.cpp | 49 + .../oxygen/transitions/oxygentransitiondata.h | 151 + .../oxygen/transitions/oxygentransitions.cpp | 121 + .../oxygen/transitions/oxygentransitions.h | 105 + .../transitions/oxygentransitionwidget.cpp | 292 + .../transitions/oxygentransitionwidget.h | 238 + kstyles/themes/CMakeLists.txt | 36 + kstyles/themes/b3.themerc | 169 + kstyles/themes/beos.themerc | 175 + kstyles/themes/default.themerc | 171 + kstyles/themes/highcolor.themerc | 164 + kstyles/themes/keramik.themerc | 174 + kstyles/themes/light-v2.themerc | 160 + kstyles/themes/light-v3.themerc | 160 + kstyles/themes/mega.themerc | 83 + kstyles/themes/qtcde.themerc | 174 + kstyles/themes/qtcleanlooks.themerc | 132 + kstyles/themes/qtgtk.themerc | 138 + kstyles/themes/qtmacintosh.themerc | 140 + kstyles/themes/qtmotif.themerc | 167 + kstyles/themes/qtmotifplus.themerc | 165 + kstyles/themes/qtplastique.themerc | 135 + kstyles/themes/qtplatinum.themerc | 165 + kstyles/themes/qtsgi.themerc | 167 + kstyles/themes/qtwindows.themerc | 168 + kstyles/themes/qtwindowsvista.themerc | 137 + kstyles/themes/qtwindowsxp.themerc | 137 + ksysguard/CMakeLists.txt | 12 + ksysguard/README | 9 + ksysguard/example/CMakeLists.txt | 2 + ksysguard/example/ksysguard.notifyrc | 393 + ksysguard/example/ksysguarddrc | 22 + ksysguard/gui/CMakeLists.txt | 68 + ksysguard/gui/HostConnector.cpp | 230 + ksysguard/gui/HostConnector.h | 76 + ksysguard/gui/Messages.sh | 5 + ksysguard/gui/ProcessTable.sgrd | 6 + ksysguard/gui/SensorBrowser.cpp | 653 ++ ksysguard/gui/SensorBrowser.h | 212 + ksysguard/gui/SensorDisplayLib/BarGraph.cpp | 170 + ksysguard/gui/SensorDisplayLib/BarGraph.h | 91 + .../gui/SensorDisplayLib/DancingBars.cpp | 329 + ksysguard/gui/SensorDisplayLib/DancingBars.h | 76 + .../SensorDisplayLib/DancingBarsSettings.cpp | 386 + .../SensorDisplayLib/DancingBarsSettings.h | 108 + .../gui/SensorDisplayLib/DummyDisplay.cpp | 56 + ksysguard/gui/SensorDisplayLib/DummyDisplay.h | 39 + .../gui/SensorDisplayLib/FancyPlotter.cpp | 938 ++ ksysguard/gui/SensorDisplayLib/FancyPlotter.h | 144 + .../SensorDisplayLib/FancyPlotterSettings.cpp | 513 + .../SensorDisplayLib/FancyPlotterSettings.h | 131 + ksysguard/gui/SensorDisplayLib/ListView.cpp | 447 + ksysguard/gui/SensorDisplayLib/ListView.h | 113 + .../gui/SensorDisplayLib/ListViewSettings.cpp | 89 + .../gui/SensorDisplayLib/ListViewSettings.h | 58 + .../ListViewSettingsWidget.ui | 165 + ksysguard/gui/SensorDisplayLib/LogFile.cpp | 290 + ksysguard/gui/SensorDisplayLib/LogFile.h | 83 + .../gui/SensorDisplayLib/LogFileSettings.ui | 227 + ksysguard/gui/SensorDisplayLib/MultiMeter.cpp | 233 + ksysguard/gui/SensorDisplayLib/MultiMeter.h | 72 + .../SensorDisplayLib/MultiMeterSettings.cpp | 145 + .../gui/SensorDisplayLib/MultiMeterSettings.h | 69 + .../MultiMeterSettingsWidget.ui | 339 + .../SensorDisplayLib/ProcessController.cpp | 187 + .../gui/SensorDisplayLib/ProcessController.h | 95 + .../gui/SensorDisplayLib/SensorDisplay.cpp | 480 + .../gui/SensorDisplayLib/SensorDisplay.h | 315 + .../gui/SensorDisplayLib/SensorLogger.cpp | 662 ++ ksysguard/gui/SensorDisplayLib/SensorLogger.h | 148 + .../gui/SensorDisplayLib/SensorLoggerDlg.cpp | 120 + .../gui/SensorDisplayLib/SensorLoggerDlg.h | 66 + .../SensorDisplayLib/SensorLoggerDlgWidget.ui | 226 + .../SensorDisplayLib/SensorLoggerSettings.cpp | 90 + .../SensorDisplayLib/SensorLoggerSettings.h | 58 + .../SensorLoggerSettingsWidget.ui | 158 + .../gui/SensorDisplayLib/SensorModel.cpp | 298 + ksysguard/gui/SensorDisplayLib/SensorModel.h | 99 + ksysguard/gui/SharedSettings.h | 35 + ksysguard/gui/SignalIDs.h | 50 + ksysguard/gui/StyleEngine.cpp | 120 + ksysguard/gui/StyleEngine.h | 65 + ksysguard/gui/SystemLoad2.sgrd | 16 + ksysguard/gui/TimerSettings.cpp | 101 + ksysguard/gui/TimerSettings.h | 55 + ksysguard/gui/WorkSheet.cpp | 804 ++ ksysguard/gui/WorkSheet.h | 137 + ksysguard/gui/WorkSheetSettings.cpp | 154 + ksysguard/gui/WorkSheetSettings.h | 59 + ksysguard/gui/Workspace.cpp | 388 + ksysguard/gui/Workspace.h | 83 + ksysguard/gui/ksortfilterproxymodel.cpp | 84 + ksysguard/gui/ksortfilterproxymodel.h | 61 + ksysguard/gui/ksysguard.cpp | 590 + ksysguard/gui/ksysguard.desktop | 178 + ksysguard/gui/ksysguard.h | 114 + ksysguard/gui/ksysguard.knsrc | 24 + ksysguard/gui/ksysguardui.rc | 32 + ksysguard/gui/tests/CMakeLists.txt | 12 + ksysguard/gui/tests/ksysguarddtest.cpp | 286 + ksysguard/gui/tests/ksysguarddtest.h | 67 + ksysguard/ksysguardd/CContLib/ccont.c | 468 + ksysguard/ksysguardd/CContLib/ccont.h | 168 + ksysguard/ksysguardd/CMakeLists.txt | 72 + ksysguard/ksysguardd/Command.c | 327 + ksysguard/ksysguardd/Command.h | 139 + ksysguard/ksysguardd/FreeBSD/CMakeLists.txt | 14 + ksysguard/ksysguardd/FreeBSD/ChangeLog | 73 + ksysguard/ksysguardd/FreeBSD/Memory.c | 334 + ksysguard/ksysguardd/FreeBSD/Memory.h | 56 + ksysguard/ksysguardd/FreeBSD/ProcessList.c | 524 + ksysguard/ksysguardd/FreeBSD/ProcessList.h | 52 + ksysguard/ksysguardd/FreeBSD/TODO | 47 + ksysguard/ksysguardd/FreeBSD/acpi.c | 241 + ksysguard/ksysguardd/FreeBSD/acpi.h | 45 + ksysguard/ksysguardd/FreeBSD/apm.c | 103 + ksysguard/ksysguardd/FreeBSD/apm.h | 35 + ksysguard/ksysguardd/FreeBSD/cpuinfo.c | 655 ++ ksysguard/ksysguardd/FreeBSD/cpuinfo.h | 74 + ksysguard/ksysguardd/FreeBSD/diskstat.c | 386 + ksysguard/ksysguardd/FreeBSD/diskstat.h | 48 + ksysguard/ksysguardd/FreeBSD/loadavg.c | 95 + ksysguard/ksysguardd/FreeBSD/loadavg.h | 37 + ksysguard/ksysguardd/FreeBSD/logfile.c | 172 + ksysguard/ksysguardd/FreeBSD/logfile.h | 37 + ksysguard/ksysguardd/FreeBSD/netdev.c | 351 + ksysguard/ksysguardd/FreeBSD/netdev.h | 35 + ksysguard/ksysguardd/FreeBSD/stat.c | 380 + ksysguard/ksysguardd/FreeBSD/stat.h | 49 + ksysguard/ksysguardd/FreeBSD/uptime.c | 48 + ksysguard/ksysguardd/FreeBSD/uptime.h | 33 + ksysguard/ksysguardd/GNU/CMakeLists.txt | 5 + ksysguard/ksysguardd/GNU/dummy.cpp | 1 + ksysguard/ksysguardd/Irix/CMakeLists.txt | 9 + ksysguard/ksysguardd/Irix/LoadAvg.c | 88 + ksysguard/ksysguardd/Irix/LoadAvg.h | 41 + ksysguard/ksysguardd/Irix/Memory.c | 128 + ksysguard/ksysguardd/Irix/Memory.h | 46 + ksysguard/ksysguardd/Irix/NetDev.c | 343 + ksysguard/ksysguardd/Irix/NetDev.h | 35 + ksysguard/ksysguardd/Irix/ProcessList.c | 465 + ksysguard/ksysguardd/Irix/ProcessList.h | 43 + ksysguard/ksysguardd/Irix/cpu.c | 278 + ksysguard/ksysguardd/Irix/cpu.h | 43 + ksysguard/ksysguardd/Linux/CMakeLists.txt | 34 + ksysguard/ksysguardd/Linux/Memory.c | 294 + ksysguard/ksysguardd/Linux/Memory.h | 45 + ksysguard/ksysguardd/Linux/ProcessList.c | 676 ++ ksysguard/ksysguardd/Linux/ProcessList.h | 37 + ksysguard/ksysguardd/Linux/acpi.c | 468 + ksysguard/ksysguardd/Linux/acpi.h | 46 + ksysguard/ksysguardd/Linux/apm.c | 127 + ksysguard/ksysguardd/Linux/apm.h | 34 + ksysguard/ksysguardd/Linux/cpuinfo.c | 276 + ksysguard/ksysguardd/Linux/cpuinfo.h | 41 + ksysguard/ksysguardd/Linux/diskstat.c | 322 + ksysguard/ksysguardd/Linux/diskstat.h | 40 + ksysguard/ksysguardd/Linux/diskstats.c | 546 + ksysguard/ksysguardd/Linux/diskstats.h | 44 + ksysguard/ksysguardd/Linux/i8k.c | 150 + ksysguard/ksysguardd/Linux/i8k.h | 36 + ksysguard/ksysguardd/Linux/lmsensors.c | 313 + ksysguard/ksysguardd/Linux/lmsensors.h | 30 + ksysguard/ksysguardd/Linux/loadavg.c | 149 + ksysguard/ksysguardd/Linux/loadavg.h | 36 + ksysguard/ksysguardd/Linux/logfile.c | 174 + ksysguard/ksysguardd/Linux/logfile.h | 36 + ksysguard/ksysguardd/Linux/netdev.c | 557 + ksysguard/ksysguardd/Linux/netdev.h | 35 + ksysguard/ksysguardd/Linux/netstat.c | 505 + ksysguard/ksysguardd/Linux/netstat.h | 39 + ksysguard/ksysguardd/Linux/softraid.c | 625 ++ ksysguard/ksysguardd/Linux/softraid.h | 28 + ksysguard/ksysguardd/Linux/stat.c | 1087 ++ ksysguard/ksysguardd/Linux/stat.h | 76 + ksysguard/ksysguardd/Linux/uptime.c | 116 + ksysguard/ksysguardd/Linux/uptime.h | 27 + ksysguard/ksysguardd/NetBSD/CMakeLists.txt | 11 + ksysguard/ksysguardd/NetBSD/CPU.c | 204 + ksysguard/ksysguardd/NetBSD/CPU.h | 49 + ksysguard/ksysguardd/NetBSD/Memory.c | 219 + ksysguard/ksysguardd/NetBSD/Memory.h | 49 + ksysguard/ksysguardd/NetBSD/ProcessList.c | 454 + ksysguard/ksysguardd/NetBSD/ProcessList.h | 38 + ksysguard/ksysguardd/NetBSD/apm.c | 103 + ksysguard/ksysguardd/NetBSD/apm.h | 34 + ksysguard/ksysguardd/NetBSD/diskstat.c | 248 + ksysguard/ksysguardd/NetBSD/diskstat.h | 40 + ksysguard/ksysguardd/NetBSD/loadavg.c | 103 + ksysguard/ksysguardd/NetBSD/loadavg.h | 36 + ksysguard/ksysguardd/NetBSD/logfile.c | 175 + ksysguard/ksysguardd/NetBSD/logfile.h | 36 + ksysguard/ksysguardd/NetBSD/netdev.c | 305 + ksysguard/ksysguardd/NetBSD/netdev.h | 35 + ksysguard/ksysguardd/OpenBSD/CMakeLists.txt | 8 + ksysguard/ksysguardd/OpenBSD/ProcessList.c | 497 + ksysguard/ksysguardd/OpenBSD/ProcessList.h | 38 + ksysguard/ksysguardd/OpenBSD/cpu.c | 221 + ksysguard/ksysguardd/OpenBSD/cpu.h | 51 + ksysguard/ksysguardd/OpenBSD/memory.c | 238 + ksysguard/ksysguardd/OpenBSD/memory.h | 47 + ksysguard/ksysguardd/PWUIDCache.c | 114 + ksysguard/ksysguardd/PWUIDCache.h | 36 + ksysguard/ksysguardd/Porting-HOWTO | 135 + ksysguard/ksysguardd/Solaris/CMakeLists.txt | 13 + ksysguard/ksysguardd/Solaris/LoadAvg.c | 355 + ksysguard/ksysguardd/Solaris/LoadAvg.h | 55 + ksysguard/ksysguardd/Solaris/Memory.c | 303 + ksysguard/ksysguardd/Solaris/Memory.h | 47 + ksysguard/ksysguardd/Solaris/NetDev.c | 793 ++ ksysguard/ksysguardd/Solaris/NetDev.h | 65 + ksysguard/ksysguardd/Solaris/ProcessList.c | 439 + ksysguard/ksysguardd/Solaris/ProcessList.h | 43 + ksysguard/ksysguardd/Tru64/CMakeLists.txt | 7 + ksysguard/ksysguardd/Tru64/LoadAvg.c | 133 + ksysguard/ksysguardd/Tru64/LoadAvg.h | 41 + ksysguard/ksysguardd/Tru64/Memory.c | 237 + ksysguard/ksysguardd/Tru64/Memory.h | 46 + ksysguard/ksysguardd/Tru64/NetDev.c | 678 ++ ksysguard/ksysguardd/Tru64/NetDev.h | 59 + ksysguard/ksysguardd/conf.c | 141 + ksysguard/ksysguardd/conf.h | 36 + .../ksysguardd/config-ksysguardd.h.cmake | 3 + ksysguard/ksysguardd/ksysguardd.c | 615 ++ ksysguard/ksysguardd/ksysguardd.h | 51 + ksysguard/ksysguardd/modules.h | 208 + ksysguard/pics/CMakeLists.txt | 1 + ksysguard/pics/ox16-app-computer.png | Bin 0 -> 894 bytes ksysguard/pics/ox16-app-daemon.png | Bin 0 -> 226 bytes ksysguard/pics/ox16-app-kdeapp.png | Bin 0 -> 1027 bytes ksysguard/pics/ox16-app-kernel.png | Bin 0 -> 291 bytes ksysguard/pics/ox16-app-ksysguardd.png | Bin 0 -> 906 bytes ksysguard/pics/ox16-app-running.png | Bin 0 -> 554 bytes ksysguard/pics/ox16-app-shell.png | Bin 0 -> 890 bytes ksysguard/pics/ox16-app-unknownapp.png | Bin 0 -> 986 bytes ksysguard/pics/ox16-app-waiting.png | Bin 0 -> 784 bytes ksystraycmd/CMakeLists.txt | 11 + ksystraycmd/Messages.sh | 2 + ksystraycmd/README | 29 + ksystraycmd/ksystraycmd.cpp | 381 + ksystraycmd/ksystraycmd.h | 87 + ksystraycmd/main.cpp | 144 + ktouchpadenabler/CMakeLists.txt | 27 + ktouchpadenabler/COPYING | 339 + ktouchpadenabler/Messages.sh | 2 + ktouchpadenabler/ktouchpadenabler.desktop | 97 + ktouchpadenabler/ktouchpadenabler.kcfg | 12 + ktouchpadenabler/ktouchpadenabler_daemon.cpp | 218 + ktouchpadenabler/ktouchpadenabler_daemon.h | 37 + ktouchpadenabler/settings.kcfgc | 5 + kwin/CMakeLists.txt | 347 + kwin/COMPLIANCE | 254 + kwin/CONFIGURING | 73 + kwin/ExtraDesktop.sh | 4 + kwin/HACKING | 5 + kwin/Mainpage.dox | 19 + kwin/Messages.sh | 3 + kwin/README | 209 + kwin/activation.cpp | 899 ++ kwin/activities.cpp | 286 + kwin/activities.h | 130 + kwin/appmenu.cpp | 97 + kwin/appmenu.h | 60 + kwin/atoms.cpp | 142 + kwin/atoms.h | 76 + kwin/bridge.cpp | 369 + kwin/bridge.h | 110 + kwin/client.cpp | 2526 +++++ kwin/client.h | 1278 +++ kwin/client_machine.cpp | 239 + kwin/client_machine.h | 117 + kwin/clients/CMakeLists.txt | 6 + kwin/clients/Messages.sh | 4 + kwin/clients/aurorae/AUTHORS | 1 + kwin/clients/aurorae/CMakeLists.txt | 6 + kwin/clients/aurorae/README | 6 + kwin/clients/aurorae/TODO | 3 + kwin/clients/aurorae/src/CMakeLists.txt | 54 + kwin/clients/aurorae/src/aurorae.cpp | 664 ++ kwin/clients/aurorae/src/aurorae.desktop | 68 + kwin/clients/aurorae/src/aurorae.h | 193 + kwin/clients/aurorae/src/aurorae.knsrc | 4 + kwin/clients/aurorae/src/colorhelper.cpp | 65 + kwin/clients/aurorae/src/colorhelper.h | 240 + .../clients/aurorae/src/decorationoptions.cpp | 181 + kwin/clients/aurorae/src/decorationoptions.h | 222 + kwin/clients/aurorae/src/decorationplugin.cpp | 31 + kwin/clients/aurorae/src/decorationplugin.h | 28 + .../aurorae/src/kwindecoration.desktop | 53 + kwin/clients/aurorae/src/lib/auroraetheme.cpp | 515 + kwin/clients/aurorae/src/lib/auroraetheme.h | 228 + kwin/clients/aurorae/src/lib/themeconfig.cpp | 195 + kwin/clients/aurorae/src/lib/themeconfig.h | 421 + .../clients/aurorae/src/qml/AppMenuButton.qml | 28 + .../clients/aurorae/src/qml/AuroraeButton.qml | 214 + .../aurorae/src/qml/AuroraeButtonGroup.qml | 65 + .../aurorae/src/qml/AuroraeMaximizeButton.qml | 45 + kwin/clients/aurorae/src/qml/ButtonGroup.qml | 100 + kwin/clients/aurorae/src/qml/Decoration.qml | 43 + .../aurorae/src/qml/DecorationButton.qml | 154 + kwin/clients/aurorae/src/qml/MenuButton.qml | 85 + kwin/clients/aurorae/src/qml/aurorae.qml | 240 + kwin/clients/aurorae/src/qml/qmldir | 7 + kwin/clients/aurorae/theme-description | 163 + kwin/clients/aurorae/themes/CMakeLists.txt | 1 + .../aurorae/themes/plastik/CMakeLists.txt | 8 + .../themes/plastik/code/CMakeLists.txt | 11 + .../themes/plastik/code/plastikbutton.cpp | 454 + .../themes/plastik/code/plastikbutton.h | 61 + .../themes/plastik/code/plastikplugin.cpp | 34 + .../themes/plastik/code/plastikplugin.h | 30 + .../aurorae/themes/plastik/code/qmldir | 4 + .../plastik/package/contents/config/main.xml | 28 + .../package/contents/ui/PlastikButton.qml | 161 + .../plastik/package/contents/ui/config.ui | 99 + .../plastik/package/contents/ui/main.qml | 429 + .../themes/plastik/package/metadata.desktop | 145 + kwin/clients/b2/CMakeLists.txt | 18 + kwin/clients/b2/b2.desktop | 90 + kwin/clients/b2/b2client.cpp | 1587 +++ kwin/clients/b2/b2client.h | 190 + kwin/clients/b2/bitmaps.h | 82 + kwin/clients/b2/config/CMakeLists.txt | 14 + kwin/clients/b2/config/config.cpp | 198 + kwin/clients/b2/config/config.h | 66 + kwin/clients/laptop/CMakeLists.txt | 17 + kwin/clients/laptop/laptop.desktop | 91 + kwin/clients/laptop/laptopclient.cpp | 808 ++ kwin/clients/laptop/laptopclient.h | 93 + kwin/clients/oxygen/CMakeLists.txt | 38 + kwin/clients/oxygen/config/CMakeLists.txt | 35 + .../config/oxygenanimationconfigwidget.cpp | 156 + .../config/oxygenanimationconfigwidget.h | 88 + kwin/clients/oxygen/config/oxygenconfig.cpp | 180 + kwin/clients/oxygen/config/oxygenconfig.h | 110 + .../oxygen/config/oxygenconfigwidget.cpp | 249 + .../oxygen/config/oxygenconfigwidget.h | 135 + .../oxygen/config/oxygendetectwidget.cpp | 172 + .../oxygen/config/oxygendetectwidget.h | 113 + .../oxygen/config/oxygenexceptiondialog.cpp | 192 + .../oxygen/config/oxygenexceptiondialog.h | 117 + .../config/oxygenexceptionlistwidget.cpp | 347 + .../oxygen/config/oxygenexceptionlistwidget.h | 124 + .../oxygen/config/oxygenexceptionmodel.cpp | 105 + .../oxygen/config/oxygenexceptionmodel.h | 81 + .../oxygen/config/ui/oxygenconfigurationui.ui | 462 + .../oxygen/config/ui/oxygendetectwidget.ui | 87 + .../oxygen/config/ui/oxygenexceptiondialog.ui | 334 + .../config/ui/oxygenexceptionlistwidget.ui | 109 + kwin/clients/oxygen/data/CMakeLists.txt | 3 + kwin/clients/oxygen/data/oxygen.upd | 5 + kwin/clients/oxygen/data/update_oxygen.pl | 192 + kwin/clients/oxygen/demo/CMakeLists.txt | 26 + kwin/clients/oxygen/demo/main.cpp | 62 + .../oxygen/demo/oxygenshadowdemodialog.cpp | 133 + .../oxygen/demo/oxygenshadowdemodialog.h | 79 + .../oxygen/demo/oxygenshadowdemowidget.cpp | 105 + .../oxygen/demo/oxygenshadowdemowidget.h | 140 + .../oxygen/demo/ui/oxygenshadowdemo.ui | 58 + kwin/clients/oxygen/oxygenbutton.cpp | 439 + kwin/clients/oxygen/oxygenbutton.h | 206 + kwin/clients/oxygen/oxygenclient.cpp | 2048 ++++ kwin/clients/oxygen/oxygenclient.desktop | 180 + kwin/clients/oxygen/oxygenclient.h | 545 + .../oxygen/oxygenclientgroupitemdata.cpp | 353 + .../oxygen/oxygenclientgroupitemdata.h | 223 + kwin/clients/oxygen/oxygenconfigdata.kcfg | 134 + kwin/clients/oxygen/oxygenconfiguration.kcfgc | 6 + kwin/clients/oxygen/oxygendecohelper.cpp | 220 + kwin/clients/oxygen/oxygendecohelper.h | 89 + kwin/clients/oxygen/oxygendecorationdefines.h | 83 + kwin/clients/oxygen/oxygenexceptionlist.cpp | 104 + kwin/clients/oxygen/oxygenexceptionlist.h | 73 + kwin/clients/oxygen/oxygenfactory.cpp | 213 + kwin/clients/oxygen/oxygenfactory.h | 139 + kwin/clients/oxygen/oxygensizegrip.cpp | 237 + kwin/clients/oxygen/oxygensizegrip.h | 100 + .../oxygen/oxygentitleanimationdata.cpp | 152 + .../clients/oxygen/oxygentitleanimationdata.h | 258 + kwin/composite.cpp | 1225 +++ kwin/composite.h | 311 + kwin/compositingprefs.cpp | 166 + kwin/compositingprefs.h | 67 + kwin/config-kwin.h.cmake | 11 + kwin/cursor.cpp | 320 + kwin/cursor.h | 224 + kwin/data/CMakeLists.txt | 67 + kwin/data/fsp_workarounds_1.kwinrules | 81 + kwin/data/kwin_fsp_workarounds_1.upd | 3 + kwin/data/kwin_remove_delay_focus.sh | 4 + kwin/data/kwin_remove_delay_focus.upd | 2 + kwin/data/kwin_remove_effects.upd | 9 + kwin/data/kwin_translate_activity_rule.sh | 14 + kwin/data/kwin_translate_activity_rule.upd | 2 + kwin/data/kwin_translate_confrequest_rule.sh | 14 + kwin/data/kwin_translate_confrequest_rule.upd | 2 + kwin/data/kwin_update_410.upd | 2 + kwin/data/kwin_update_411.upd | 2 + kwin/data/kwin_update_49.upd | 2 + kwin/data/kwin_update_tabbox_qml_settings.upd | 2 + kwin/data/kwin_update_tabbox_settings.upd | 2 + kwin/data/pop.wav | Bin 0 -> 4068 bytes kwin/data/stripTitle.js | 104 + kwin/data/update_default_rules.cpp | 74 + kwin/data/update_kwin_410.cpp | 155 + kwin/data/update_kwin_411.cpp | 95 + kwin/data/update_kwin_49.cpp | 97 + kwin/data/update_kwin_49.h | 30 + kwin/data/update_kwin_49_main.cpp | 45 + kwin/data/update_tabbox_qml_settings.cpp | 66 + kwin/data/update_tabbox_settings.cpp | 54 + kwin/dbusinterface.cpp | 260 + kwin/dbusinterface.h | 159 + kwin/decorations.cpp | 188 + kwin/decorations.h | 76 + kwin/deleted.cpp | 188 + kwin/deleted.h | 109 + kwin/effects.cpp | 2111 ++++ kwin/effects.h | 496 + kwin/effects/CMakeLists.txt | 170 + kwin/effects/Messages.sh | 4 + kwin/effects/blur/CMakeLists.txt | 30 + kwin/effects/blur/blur.cpp | 728 ++ kwin/effects/blur/blur.desktop | 167 + kwin/effects/blur/blur.h | 111 + kwin/effects/blur/blur.kcfg | 15 + kwin/effects/blur/blur_config.cpp | 53 + kwin/effects/blur/blur_config.desktop | 91 + kwin/effects/blur/blur_config.h | 46 + kwin/effects/blur/blur_config.ui | 107 + kwin/effects/blur/blurconfig.kcfgc | 5 + kwin/effects/blur/blurshader.cpp | 506 + kwin/effects/blur/blurshader.h | 152 + kwin/effects/configs_builtins.cpp | 84 + kwin/effects/coverswitch/CMakeLists.txt | 37 + kwin/effects/coverswitch/coverswitch.cpp | 1061 ++ kwin/effects/coverswitch/coverswitch.desktop | 149 + kwin/effects/coverswitch/coverswitch.h | 160 + kwin/effects/coverswitch/coverswitch.kcfg | 42 + .../coverswitch/coverswitch_config.cpp | 58 + .../coverswitch/coverswitch_config.desktop | 78 + kwin/effects/coverswitch/coverswitch_config.h | 54 + .../effects/coverswitch/coverswitch_config.ui | 312 + .../coverswitch/coverswitchconfig.kcfgc | 5 + .../shaders/1.10/coverswitch-reflection.glsl | 9 + .../shaders/1.40/coverswitch-reflection.glsl | 12 + kwin/effects/cube/CMakeLists.txt | 63 + kwin/effects/cube/cube.cpp | 2127 ++++ kwin/effects/cube/cube.desktop | 165 + kwin/effects/cube/cube.h | 253 + kwin/effects/cube/cube.kcfg | 65 + kwin/effects/cube/cube_config.cpp | 106 + kwin/effects/cube/cube_config.desktop | 85 + kwin/effects/cube/cube_config.h | 57 + kwin/effects/cube/cube_config.ui | 571 + kwin/effects/cube/cube_inside.h | 40 + kwin/effects/cube/cube_proxy.cpp | 47 + kwin/effects/cube/cube_proxy.h | 45 + kwin/effects/cube/cubeconfig.kcfgc | 6 + kwin/effects/cube/cubeslide.cpp | 614 ++ kwin/effects/cube/cubeslide.desktop | 147 + kwin/effects/cube/cubeslide.h | 104 + kwin/effects/cube/cubeslide.kcfg | 25 + kwin/effects/cube/cubeslide_config.cpp | 61 + kwin/effects/cube/cubeslide_config.desktop | 77 + kwin/effects/cube/cubeslide_config.h | 54 + kwin/effects/cube/cubeslide_config.ui | 112 + kwin/effects/cube/cubeslideconfig.kcfgc | 5 + kwin/effects/cube/data/1.10/cube-cap.glsl | 29 + .../cube/data/1.10/cube-reflection.glsl | 8 + kwin/effects/cube/data/1.10/cylinder.vert | 49 + kwin/effects/cube/data/1.10/sphere.vert | 55 + kwin/effects/cube/data/1.40/cube-cap.glsl | 32 + .../cube/data/1.40/cube-reflection.glsl | 11 + kwin/effects/cube/data/1.40/cylinder.vert | 50 + kwin/effects/cube/data/1.40/sphere.vert | 56 + kwin/effects/cube/data/cubecap.png | Bin 0 -> 305666 bytes kwin/effects/dashboard/CMakeLists.txt | 28 + kwin/effects/dashboard/dashboard.cpp | 183 + kwin/effects/dashboard/dashboard.desktop | 145 + kwin/effects/dashboard/dashboard.h | 76 + kwin/effects/dashboard/dashboard.kcfg | 21 + kwin/effects/dashboard/dashboard_config.cpp | 53 + .../dashboard/dashboard_config.desktop | 84 + kwin/effects/dashboard/dashboard_config.h | 49 + kwin/effects/dashboard/dashboard_config.ui | 224 + kwin/effects/dashboard/dashboardconfig.kcfgc | 5 + kwin/effects/desktopgrid/CMakeLists.txt | 34 + kwin/effects/desktopgrid/desktopgrid.cpp | 1447 +++ kwin/effects/desktopgrid/desktopgrid.desktop | 157 + kwin/effects/desktopgrid/desktopgrid.h | 177 + kwin/effects/desktopgrid/desktopgrid.kcfg | 28 + .../desktopgrid/desktopgrid_config.cpp | 130 + .../desktopgrid/desktopgrid_config.desktop | 87 + kwin/effects/desktopgrid/desktopgrid_config.h | 62 + .../effects/desktopgrid/desktopgrid_config.ui | 245 + .../desktopgrid/desktopgridconfig.kcfgc | 5 + kwin/effects/desktopgrid/main.qml | 44 + kwin/effects/dialogparent/CMakeLists.txt | 1 + .../dialogparent/package/CMakeLists.txt | 6 + .../package/contents/code/main.js | 144 + .../dialogparent/package/metadata.desktop | 161 + kwin/effects/diminactive/CMakeLists.txt | 30 + kwin/effects/diminactive/diminactive.cpp | 143 + kwin/effects/diminactive/diminactive.desktop | 160 + kwin/effects/diminactive/diminactive.h | 83 + kwin/effects/diminactive/diminactive.kcfg | 24 + .../diminactive/diminactive_config.cpp | 68 + .../diminactive/diminactive_config.desktop | 83 + kwin/effects/diminactive/diminactive_config.h | 52 + .../effects/diminactive/diminactive_config.ui | 151 + .../diminactive/diminactiveconfig.kcfgc | 5 + kwin/effects/dimscreen/CMakeLists.txt | 12 + kwin/effects/dimscreen/dimscreen.cpp | 117 + kwin/effects/dimscreen/dimscreen.desktop | 150 + kwin/effects/dimscreen/dimscreen.h | 57 + kwin/effects/fade/CMakeLists.txt | 6 + .../fade/package/contents/code/main.js | 61 + .../fade/package/contents/config/main.xml | 20 + kwin/effects/fade/package/metadata.desktop | 164 + kwin/effects/fadedesktop/CMakeLists.txt | 6 + .../fadedesktop/package/contents/code/main.js | 48 + .../fadedesktop/package/metadata.desktop | 148 + kwin/effects/fallapart/CMakeLists.txt | 12 + kwin/effects/fallapart/fallapart.cpp | 176 + kwin/effects/fallapart/fallapart.desktop | 158 + kwin/effects/fallapart/fallapart.h | 62 + kwin/effects/flipswitch/CMakeLists.txt | 30 + kwin/effects/flipswitch/flipswitch.cpp | 1007 ++ kwin/effects/flipswitch/flipswitch.desktop | 149 + kwin/effects/flipswitch/flipswitch.h | 161 + kwin/effects/flipswitch/flipswitch.kcfg | 30 + kwin/effects/flipswitch/flipswitch_config.cpp | 85 + .../flipswitch/flipswitch_config.desktop | 79 + kwin/effects/flipswitch/flipswitch_config.h | 57 + kwin/effects/flipswitch/flipswitch_config.ui | 240 + .../effects/flipswitch/flipswitchconfig.kcfgc | 5 + kwin/effects/glide/CMakeLists.txt | 30 + kwin/effects/glide/glide.cpp | 251 + kwin/effects/glide/glide.desktop | 135 + kwin/effects/glide/glide.h | 98 + kwin/effects/glide/glide.kcfg | 18 + kwin/effects/glide/glide_config.cpp | 50 + kwin/effects/glide/glide_config.desktop | 70 + kwin/effects/glide/glide_config.h | 47 + kwin/effects/glide/glide_config.ui | 170 + kwin/effects/glide/glideconfig.kcfgc | 5 + kwin/effects/highlightwindow/CMakeLists.txt | 12 + .../highlightwindow/highlightwindow.cpp | 268 + .../highlightwindow/highlightwindow.desktop | 144 + .../effects/highlightwindow/highlightwindow.h | 78 + kwin/effects/invert/CMakeLists.txt | 33 + kwin/effects/invert/data/1.10/invert.frag | 22 + kwin/effects/invert/data/1.40/invert.frag | 25 + kwin/effects/invert/invert.cpp | 186 + kwin/effects/invert/invert.desktop | 165 + kwin/effects/invert/invert.h | 73 + kwin/effects/invert/invert_config.cpp | 96 + kwin/effects/invert/invert_config.desktop | 92 + kwin/effects/invert/invert_config.h | 49 + kwin/effects/kscreen/CMakeLists.txt | 14 + kwin/effects/kscreen/kscreen.cpp | 191 + kwin/effects/kscreen/kscreen.desktop | 95 + kwin/effects/kscreen/kscreen.h | 64 + kwin/effects/kscreen/kscreen.kcfg | 12 + kwin/effects/kscreen/kscreenconfig.kcfgc | 5 + kwin/effects/kwineffect.desktop | 99 + kwin/effects/login/CMakeLists.txt | 1 + kwin/effects/login/package/CMakeLists.txt | 6 + .../login/package/contents/code/main.js | 94 + .../login/package/contents/config/main.xml | 12 + .../login/package/contents/ui/config.ui | 38 + kwin/effects/login/package/metadata.desktop | 171 + kwin/effects/logout/CMakeLists.txt | 27 + .../effects/logout/data/1.10/logout-blur.frag | 9 + kwin/effects/logout/data/1.10/vignetting.frag | 8 + .../effects/logout/data/1.40/logout-blur.frag | 14 + kwin/effects/logout/data/1.40/vignetting.frag | 12 + kwin/effects/logout/logout.cpp | 461 + kwin/effects/logout/logout.desktop | 164 + kwin/effects/logout/logout.h | 90 + kwin/effects/logout/logout.kcfg | 12 + kwin/effects/logout/logoutconfig.kcfgc | 5 + kwin/effects/lookingglass/CMakeLists.txt | 38 + .../lookingglass/data/1.10/lookingglass.frag | 25 + .../lookingglass/data/1.40/lookingglass.frag | 28 + kwin/effects/lookingglass/lookingglass.cpp | 268 + .../effects/lookingglass/lookingglass.desktop | 157 + kwin/effects/lookingglass/lookingglass.h | 86 + kwin/effects/lookingglass/lookingglass.kcfg | 12 + .../lookingglass/lookingglass_config.cpp | 106 + .../lookingglass/lookingglass_config.desktop | 85 + .../lookingglass/lookingglass_config.h | 57 + .../lookingglass/lookingglass_config.ui | 60 + .../lookingglass/lookingglassconfig.kcfgc | 5 + kwin/effects/magiclamp/CMakeLists.txt | 30 + kwin/effects/magiclamp/magiclamp.cpp | 381 + kwin/effects/magiclamp/magiclamp.desktop | 157 + kwin/effects/magiclamp/magiclamp.h | 73 + kwin/effects/magiclamp/magiclamp.kcfg | 12 + kwin/effects/magiclamp/magiclamp_config.cpp | 62 + .../magiclamp/magiclamp_config.desktop | 81 + kwin/effects/magiclamp/magiclamp_config.h | 54 + kwin/effects/magiclamp/magiclamp_config.ui | 53 + kwin/effects/magiclamp/magiclampconfig.kcfgc | 5 + kwin/effects/magnifier/CMakeLists.txt | 29 + kwin/effects/magnifier/magnifier.cpp | 327 + kwin/effects/magnifier/magnifier.desktop | 166 + kwin/effects/magnifier/magnifier.h | 82 + kwin/effects/magnifier/magnifier.kcfg | 18 + kwin/effects/magnifier/magnifier_config.cpp | 106 + .../magnifier/magnifier_config.desktop | 92 + kwin/effects/magnifier/magnifier_config.h | 57 + kwin/effects/magnifier/magnifier_config.ui | 107 + kwin/effects/magnifier/magnifierconfig.kcfgc | 5 + kwin/effects/maximize/CMakeLists.txt | 1 + kwin/effects/maximize/package/CMakeLists.txt | 6 + .../package/contents/code/maximize.js | 80 + .../effects/maximize/package/metadata.desktop | 107 + kwin/effects/minimizeanimation/CMakeLists.txt | 12 + .../minimizeanimation/minimizeanimation.cpp | 158 + .../minimizeanimation.desktop | 160 + .../minimizeanimation/minimizeanimation.h | 60 + kwin/effects/mouseclick/CMakeLists.txt | 30 + kwin/effects/mouseclick/mouseclick.cpp | 382 + kwin/effects/mouseclick/mouseclick.desktop | 100 + kwin/effects/mouseclick/mouseclick.h | 183 + kwin/effects/mouseclick/mouseclick.kcfg | 34 + kwin/effects/mouseclick/mouseclick_config.cpp | 82 + .../mouseclick/mouseclick_config.desktop | 53 + kwin/effects/mouseclick/mouseclick_config.h | 56 + kwin/effects/mouseclick/mouseclick_config.ui | 294 + .../effects/mouseclick/mouseclickconfig.kcfgc | 5 + kwin/effects/mousemark/CMakeLists.txt | 30 + kwin/effects/mousemark/mousemark.cpp | 263 + kwin/effects/mousemark/mousemark.desktop | 162 + kwin/effects/mousemark/mousemark.h | 75 + kwin/effects/mousemark/mousemark.kcfg | 15 + kwin/effects/mousemark/mousemark_config.cpp | 96 + .../mousemark/mousemark_config.desktop | 87 + kwin/effects/mousemark/mousemark_config.h | 56 + kwin/effects/mousemark/mousemark_config.ui | 116 + kwin/effects/mousemark/mousemarkconfig.kcfgc | 5 + kwin/effects/presentwindows/CMakeLists.txt | 35 + kwin/effects/presentwindows/main.qml | 31 + .../effects/presentwindows/presentwindows.cpp | 2018 ++++ .../presentwindows/presentwindows.desktop | 159 + kwin/effects/presentwindows/presentwindows.h | 334 + .../presentwindows/presentwindows.kcfg | 59 + .../presentwindows/presentwindows_config.cpp | 103 + .../presentwindows_config.desktop | 87 + .../presentwindows/presentwindows_config.h | 58 + .../presentwindows/presentwindows_config.ui | 479 + .../presentwindows/presentwindows_proxy.cpp | 42 + .../presentwindows/presentwindows_proxy.h | 44 + .../presentwindows/presentwindowsconfig.kcfgc | 6 + kwin/effects/resize/CMakeLists.txt | 29 + kwin/effects/resize/resize.cpp | 167 + kwin/effects/resize/resize.desktop | 132 + kwin/effects/resize/resize.h | 69 + kwin/effects/resize/resize.kcfg | 15 + kwin/effects/resize/resize_config.cpp | 62 + kwin/effects/resize/resize_config.desktop | 77 + kwin/effects/resize/resize_config.h | 54 + kwin/effects/resize/resize_config.ui | 45 + kwin/effects/resize/resizeconfig.kcfgc | 5 + kwin/effects/scalein/CMakeLists.txt | 1 + kwin/effects/scalein/package/CMakeLists.txt | 6 + .../scalein/package/contents/code/main.js | 65 + kwin/effects/scalein/package/metadata.desktop | 165 + kwin/effects/screenedge/CMakeLists.txt | 12 + kwin/effects/screenedge/screenedgeeffect.cpp | 302 + .../screenedge/screenedgeeffect.desktop | 96 + kwin/effects/screenedge/screenedgeeffect.h | 72 + kwin/effects/screenshot/CMakeLists.txt | 12 + kwin/effects/screenshot/screenshot.cpp | 385 + kwin/effects/screenshot/screenshot.desktop | 125 + kwin/effects/screenshot/screenshot.h | 91 + kwin/effects/sheet/CMakeLists.txt | 14 + kwin/effects/sheet/sheet.cpp | 208 + kwin/effects/sheet/sheet.desktop | 144 + kwin/effects/sheet/sheet.h | 79 + kwin/effects/sheet/sheet.kcfg | 12 + kwin/effects/sheet/sheetconfig.kcfgc | 5 + kwin/effects/showfps/CMakeLists.txt | 30 + kwin/effects/showfps/showfps.cpp | 483 + kwin/effects/showfps/showfps.desktop | 160 + kwin/effects/showfps/showfps.h | 107 + kwin/effects/showfps/showfps.kcfg | 28 + kwin/effects/showfps/showfps_config.cpp | 62 + kwin/effects/showfps/showfps_config.desktop | 88 + kwin/effects/showfps/showfps_config.h | 47 + kwin/effects/showfps/showfps_config.ui | 175 + kwin/effects/showfps/showfpsconfig.kcfgc | 5 + kwin/effects/showpaint/CMakeLists.txt | 12 + kwin/effects/showpaint/showpaint.cpp | 118 + kwin/effects/showpaint/showpaint.desktop | 153 + kwin/effects/showpaint/showpaint.h | 46 + kwin/effects/slide/CMakeLists.txt | 12 + kwin/effects/slide/slide.cpp | 261 + kwin/effects/slide/slide.desktop | 148 + kwin/effects/slide/slide.h | 63 + kwin/effects/slideback/CMakeLists.txt | 12 + kwin/effects/slideback/slideback.cpp | 332 + kwin/effects/slideback/slideback.desktop | 119 + kwin/effects/slideback/slideback.h | 76 + kwin/effects/slidingpopups/CMakeLists.txt | 12 + kwin/effects/slidingpopups/slidingpopups.cpp | 341 + .../slidingpopups/slidingpopups.desktop | 138 + kwin/effects/slidingpopups/slidingpopups.h | 85 + kwin/effects/snaphelper/CMakeLists.txt | 12 + kwin/effects/snaphelper/snaphelper.cpp | 212 + kwin/effects/snaphelper/snaphelper.desktop | 141 + kwin/effects/snaphelper/snaphelper.h | 59 + kwin/effects/startupfeedback/CMakeLists.txt | 20 + .../data/blinking-startup-fragment.glsl | 13 + .../startupfeedback/startupfeedback.cpp | 420 + .../startupfeedback/startupfeedback.desktop | 121 + .../effects/startupfeedback/startupfeedback.h | 83 + kwin/effects/taskbarthumbnail/CMakeLists.txt | 12 + .../taskbarthumbnail/taskbarthumbnail.cpp | 163 + .../taskbarthumbnail/taskbarthumbnail.desktop | 158 + .../taskbarthumbnail/taskbarthumbnail.h | 61 + kwin/effects/thumbnailaside/CMakeLists.txt | 30 + .../effects/thumbnailaside/thumbnailaside.cpp | 191 + .../thumbnailaside/thumbnailaside.desktop | 159 + kwin/effects/thumbnailaside/thumbnailaside.h | 91 + .../thumbnailaside/thumbnailaside.kcfg | 21 + .../thumbnailaside/thumbnailaside_config.cpp | 90 + .../thumbnailaside_config.desktop | 85 + .../thumbnailaside/thumbnailaside_config.h | 56 + .../thumbnailaside/thumbnailaside_config.ui | 139 + .../thumbnailaside/thumbnailasideconfig.kcfgc | 5 + kwin/effects/trackmouse/CMakeLists.txt | 36 + kwin/effects/trackmouse/data/tm_inner.png | Bin 0 -> 1247 bytes kwin/effects/trackmouse/data/tm_outer.png | Bin 0 -> 1311 bytes kwin/effects/trackmouse/trackmouse.cpp | 279 + kwin/effects/trackmouse/trackmouse.desktop | 162 + kwin/effects/trackmouse/trackmouse.h | 78 + kwin/effects/trackmouse/trackmouse.kcfg | 21 + kwin/effects/trackmouse/trackmouse_config.cpp | 118 + .../trackmouse/trackmouse_config.desktop | 88 + kwin/effects/trackmouse/trackmouse_config.h | 63 + kwin/effects/trackmouse/trackmouse_config.ui | 134 + .../effects/trackmouse/trackmouseconfig.kcfgc | 5 + kwin/effects/translucency/CMakeLists.txt | 1 + .../translucency/package/CMakeLists.txt | 6 + .../package/contents/code/main.js | 256 + .../package/contents/config/main.xml | 39 + .../package/contents/ui/config.ui | 512 + .../translucency/package/metadata.desktop | 173 + kwin/effects/windowgeometry/CMakeLists.txt | 30 + .../effects/windowgeometry/windowgeometry.cpp | 225 + .../windowgeometry/windowgeometry.desktop | 131 + kwin/effects/windowgeometry/windowgeometry.h | 68 + .../windowgeometry/windowgeometry.kcfg | 15 + .../windowgeometry/windowgeometry_config.cpp | 81 + .../windowgeometry_config.desktop | 62 + .../windowgeometry/windowgeometry_config.h | 57 + .../windowgeometry/windowgeometry_config.ui | 43 + .../windowgeometry/windowgeometryconfig.kcfgc | 5 + kwin/effects/wobblywindows/CMakeLists.txt | 30 + kwin/effects/wobblywindows/wobblywindows.cpp | 1213 +++ .../wobblywindows/wobblywindows.desktop | 158 + kwin/effects/wobblywindows/wobblywindows.h | 211 + kwin/effects/wobblywindows/wobblywindows.kcfg | 66 + .../wobblywindows/wobblywindows_config.cpp | 114 + .../wobblywindows_config.desktop | 83 + .../wobblywindows/wobblywindows_config.h | 53 + .../wobblywindows/wobblywindows_config.ui | 380 + .../wobblywindows/wobblywindowsconfig.kcfgc | 5 + kwin/effects/zoom/CMakeLists.txt | 29 + kwin/effects/zoom/zoom.cpp | 515 + kwin/effects/zoom/zoom.desktop | 169 + kwin/effects/zoom/zoom.h | 134 + kwin/effects/zoom/zoom.kcfg | 33 + kwin/effects/zoom/zoom_config.cpp | 131 + kwin/effects/zoom/zoom_config.desktop | 94 + kwin/effects/zoom/zoom_config.h | 57 + kwin/effects/zoom/zoom_config.ui | 212 + kwin/effects/zoom/zoomconfig.kcfgc | 5 + kwin/egl_wayland_backend.cpp | 1007 ++ kwin/egl_wayland_backend.h | 359 + kwin/eglonxbackend.cpp | 481 + kwin/eglonxbackend.h | 78 + kwin/events.cpp | 1581 +++ kwin/focuschain.cpp | 266 + kwin/focuschain.h | 254 + kwin/geometry.cpp | 3352 ++++++ kwin/geometrytip.cpp | 68 + kwin/geometrytip.h | 45 + kwin/glxbackend.cpp | 719 ++ kwin/glxbackend.h | 93 + kwin/group.cpp | 1092 ++ kwin/group.h | 102 + kwin/kcmkwin/CMakeLists.txt | 15 + kwin/kcmkwin/kwincompositing/CMakeLists.txt | 23 + kwin/kcmkwin/kwincompositing/Messages.sh | 4 + kwin/kcmkwin/kwincompositing/dbus.h | 46 + kwin/kcmkwin/kwincompositing/interface_util.h | 26 + kwin/kcmkwin/kwincompositing/ktimerdialog.cpp | 174 + kwin/kcmkwin/kwincompositing/ktimerdialog.h | 171 + .../kwincompositing/kwincompositing.desktop | 220 + kwin/kcmkwin/kwincompositing/kwineffect.knsrc | 5 + kwin/kcmkwin/kwincompositing/main.cpp | 916 ++ kwin/kcmkwin/kwincompositing/main.h | 110 + kwin/kcmkwin/kwincompositing/main.ui | 988 ++ kwin/kcmkwin/kwindecoration/CMakeLists.txt | 38 + kwin/kcmkwin/kwindecoration/Messages.sh | 4 + kwin/kcmkwin/kwindecoration/auroraeconfig.ui | 137 + kwin/kcmkwin/kwindecoration/buttons.cpp | 837 ++ kwin/kcmkwin/kwindecoration/buttons.h | 225 + kwin/kcmkwin/kwindecoration/buttons.ui | 73 + .../kwindecoration/buttonsconfigdialog.cpp | 113 + .../kwindecoration/buttonsconfigdialog.h | 66 + kwin/kcmkwin/kwindecoration/config.ui | 46 + kwin/kcmkwin/kwindecoration/configdialog.cpp | 173 + kwin/kcmkwin/kwindecoration/configdialog.h | 85 + kwin/kcmkwin/kwindecoration/decoration.ui | 106 + .../kwindecoration/decorationmodel.cpp | 447 + kwin/kcmkwin/kwindecoration/decorationmodel.h | 150 + .../kcmkwin/kwindecoration/kwindecoration.cpp | 621 ++ .../kwindecoration/kwindecoration.desktop | 203 + kwin/kcmkwin/kwindecoration/kwindecoration.h | 146 + kwin/kcmkwin/kwindecoration/pixmaps.h | 126 + kwin/kcmkwin/kwindecoration/preview.cpp | 534 + kwin/kcmkwin/kwindecoration/preview.h | 169 + .../kwindecoration/qml/AuroraeDecoration.qml | 70 + .../kwindecoration/qml/AuroraePreview.qml | 52 + .../kwindecoration/qml/DecorationPreview.qml | 47 + kwin/kcmkwin/kwindecoration/qml/main.qml | 59 + kwin/kcmkwin/kwindesktop/CMakeLists.txt | 16 + kwin/kcmkwin/kwindesktop/Messages.sh | 4 + kwin/kcmkwin/kwindesktop/desktop.desktop | 201 + .../kwindesktop/desktopnameswidget.cpp | 125 + kwin/kcmkwin/kwindesktop/desktopnameswidget.h | 63 + kwin/kcmkwin/kwindesktop/main.cpp | 596 + kwin/kcmkwin/kwindesktop/main.h | 92 + kwin/kcmkwin/kwindesktop/main.ui | 324 + kwin/kcmkwin/kwinoptions/AUTHORS | 12 + kwin/kcmkwin/kwinoptions/CMakeLists.txt | 16 + kwin/kcmkwin/kwinoptions/ChangeLog | 51 + kwin/kcmkwin/kwinoptions/Messages.sh | 3 + kwin/kcmkwin/kwinoptions/actions.ui | 660 ++ kwin/kcmkwin/kwinoptions/advanced.ui | 290 + kwin/kcmkwin/kwinoptions/focus.ui | 590 + kwin/kcmkwin/kwinoptions/kwinactions.desktop | 183 + kwin/kcmkwin/kwinoptions/kwinadvanced.desktop | 224 + kwin/kcmkwin/kwinoptions/kwinfocus.desktop | 221 + kwin/kcmkwin/kwinoptions/kwinmoving.desktop | 223 + kwin/kcmkwin/kwinoptions/kwinoptions.desktop | 229 + kwin/kcmkwin/kwinoptions/main.cpp | 253 + kwin/kcmkwin/kwinoptions/main.h | 99 + kwin/kcmkwin/kwinoptions/mouse.cpp | 564 + kwin/kcmkwin/kwinoptions/mouse.h | 131 + kwin/kcmkwin/kwinoptions/mouse.ui | 836 ++ kwin/kcmkwin/kwinoptions/moving.ui | 277 + kwin/kcmkwin/kwinoptions/ox128-app-kcmkwm.png | Bin 0 -> 1335 bytes kwin/kcmkwin/kwinoptions/ox16-app-kcmkwm.png | Bin 0 -> 317 bytes kwin/kcmkwin/kwinoptions/ox22-app-kcmkwm.png | Bin 0 -> 364 bytes kwin/kcmkwin/kwinoptions/ox32-app-kcmkwm.png | Bin 0 -> 452 bytes kwin/kcmkwin/kwinoptions/ox48-app-kcmkwm.png | Bin 0 -> 620 bytes kwin/kcmkwin/kwinoptions/ox64-app-kcmkwm.png | Bin 0 -> 747 bytes kwin/kcmkwin/kwinoptions/oxsc-app-kcmkwm.svgz | Bin 0 -> 2352 bytes kwin/kcmkwin/kwinoptions/windows.cpp | 645 ++ kwin/kcmkwin/kwinoptions/windows.h | 193 + kwin/kcmkwin/kwinrules/CMakeLists.txt | 43 + kwin/kcmkwin/kwinrules/Messages.sh | 4 + kwin/kcmkwin/kwinrules/detectwidget.cpp | 238 + kwin/kcmkwin/kwinrules/detectwidget.h | 90 + kwin/kcmkwin/kwinrules/detectwidget.ui | 226 + kwin/kcmkwin/kwinrules/editshortcut.ui | 161 + kwin/kcmkwin/kwinrules/kcm.cpp | 108 + kwin/kcmkwin/kwinrules/kcm.h | 52 + kwin/kcmkwin/kwinrules/kwinrules.desktop | 199 + kwin/kcmkwin/kwinrules/kwinsrc.cpp | 27 + kwin/kcmkwin/kwinrules/main.cpp | 262 + kwin/kcmkwin/kwinrules/ruleslist.cpp | 265 + kwin/kcmkwin/kwinrules/ruleslist.h | 57 + kwin/kcmkwin/kwinrules/ruleslist.ui | 128 + kwin/kcmkwin/kwinrules/ruleswidget.cpp | 871 ++ kwin/kcmkwin/kwinrules/ruleswidget.h | 167 + kwin/kcmkwin/kwinrules/ruleswidgetbase.ui | 2674 +++++ kwin/kcmkwin/kwinrules/yesnobox.h | 57 + kwin/kcmkwin/kwinscreenedges/CMakeLists.txt | 13 + kwin/kcmkwin/kwinscreenedges/Messages.sh | 4 + .../kwinscreenedges/kwinscreenedges.desktop | 186 + kwin/kcmkwin/kwinscreenedges/main.cpp | 544 + kwin/kcmkwin/kwinscreenedges/main.h | 95 + kwin/kcmkwin/kwinscreenedges/main.ui | 358 + kwin/kcmkwin/kwinscreenedges/monitor.cpp | 294 + kwin/kcmkwin/kwinscreenedges/monitor.h | 113 + kwin/kcmkwin/kwinscripts/CMakeLists.txt | 23 + kwin/kcmkwin/kwinscripts/Messages.sh | 4 + kwin/kcmkwin/kwinscripts/kwinscripts.desktop | 154 + kwin/kcmkwin/kwinscripts/kwinscripts.knsrc | 5 + kwin/kcmkwin/kwinscripts/main.cpp | 26 + kwin/kcmkwin/kwinscripts/module.cpp | 131 + kwin/kcmkwin/kwinscripts/module.h | 70 + kwin/kcmkwin/kwinscripts/module.ui | 86 + kwin/kcmkwin/kwinscripts/version.h.cmake | 7 + kwin/kcmkwin/kwintabbox/CMakeLists.txt | 31 + kwin/kcmkwin/kwintabbox/Messages.sh | 4 + kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc | 5 + kwin/kcmkwin/kwintabbox/kwintabbox.desktop | 163 + kwin/kcmkwin/kwintabbox/layoutpreview.cpp | 181 + kwin/kcmkwin/kwintabbox/layoutpreview.h | 70 + kwin/kcmkwin/kwintabbox/main.cpp | 547 + kwin/kcmkwin/kwintabbox/main.h | 97 + kwin/kcmkwin/kwintabbox/main.ui | 696 ++ kwin/kcmkwin/kwintabbox/qml/main.qml | 59 + kwin/kcmkwin/kwintabbox/thumbnailitem.cpp | 89 + kwin/kcmkwin/kwintabbox/thumbnailitem.h | 59 + .../kcmkwin/kwintabbox/thumbnails/dolphin.png | Bin 0 -> 53721 bytes kwin/kcmkwin/kwintabbox/thumbnails/kmail.png | Bin 0 -> 64124 bytes .../kwintabbox/thumbnails/konqueror.png | Bin 0 -> 76360 bytes .../kwintabbox/thumbnails/systemsettings.png | Bin 0 -> 62546 bytes kwin/killer/CMakeLists.txt | 10 + kwin/killer/killer.cpp | 114 + kwin/killwindow.cpp | 223 + kwin/killwindow.h | 61 + kwin/kwin.kcfg | 310 + kwin/kwin.notifyrc | 281 + kwin/kwinbindings.cpp | 174 + kwin/lanczosfilter.cpp | 416 + kwin/lanczosfilter.h | 77 + kwin/layers.cpp | 879 ++ kwin/libkdecorations/CMakeLists.txt | 27 + kwin/libkdecorations/Mainpage.dox | 19 + kwin/libkdecorations/Messages.sh | 2 + kwin/libkdecorations/kcommondecoration.cpp | 1450 +++ kwin/libkdecorations/kcommondecoration.h | 534 + kwin/libkdecorations/kcommondecoration_p.cpp | 137 + kwin/libkdecorations/kcommondecoration_p.h | 79 + kwin/libkdecorations/kdecoration.cpp | 680 ++ kwin/libkdecorations/kdecoration.h | 1223 +++ kwin/libkdecorations/kdecoration_p.cpp | 216 + kwin/libkdecorations/kdecoration_p.h | 58 + .../libkdecorations/kdecoration_plugins_p.cpp | 284 + kwin/libkdecorations/kdecoration_plugins_p.h | 85 + kwin/libkdecorations/kdecorationbridge.h | 115 + kwin/libkdecorations/kdecorationfactory.cpp | 101 + kwin/libkdecorations/kdecorationfactory.h | 149 + kwin/libkwineffects/CMakeLists.txt | 104 + kwin/libkwineffects/Mainpage.dox | 22 + kwin/libkwineffects/Messages.sh | 2 + kwin/libkwineffects/anidata.cpp | 213 + kwin/libkwineffects/anidata_p.h | 59 + kwin/libkwineffects/kwinanimationeffect.cpp | 894 ++ kwin/libkwineffects/kwinanimationeffect.h | 219 + kwin/libkwineffects/kwinconfig.h.cmake | 25 + kwin/libkwineffects/kwineffects.cpp | 1745 +++ kwin/libkwineffects/kwineffects.h | 2891 +++++ kwin/libkwineffects/kwinglcolorcorrection.cpp | 691 ++ kwin/libkwineffects/kwinglcolorcorrection.h | 106 + kwin/libkwineffects/kwinglcolorcorrection_p.h | 167 + kwin/libkwineffects/kwinglobals.cpp | 71 + kwin/libkwineffects/kwinglobals.h | 224 + kwin/libkwineffects/kwinglplatform.cpp | 1074 ++ kwin/libkwineffects/kwinglplatform.h | 385 + kwin/libkwineffects/kwingltexture.cpp | 628 ++ kwin/libkwineffects/kwingltexture.h | 122 + kwin/libkwineffects/kwingltexture_p.h | 85 + kwin/libkwineffects/kwinglutils.cpp | 2020 ++++ kwin/libkwineffects/kwinglutils.h | 820 ++ kwin/libkwineffects/kwinglutils_funcs.cpp | 794 ++ kwin/libkwineffects/kwinglutils_funcs.h | 608 ++ kwin/libkwineffects/kwinxrenderutils.cpp | 194 + kwin/libkwineffects/kwinxrenderutils.h | 206 + kwin/main.cpp | 600 + kwin/main.h | 69 + kwin/manage.cpp | 771 ++ kwin/netinfo.cpp | 305 + kwin/netinfo.h | 93 + kwin/opengltest/CMakeLists.txt | 10 + kwin/opengltest/opengltest.cpp | 135 + kwin/options.cpp | 1114 ++ kwin/options.h | 888 ++ kwin/org.kde.KWin.xml | 110 + kwin/org.kde.kwin.Compositing.xml | 22 + kwin/org.kde.kwin.Effects.xml | 39 + kwin/outline.cpp | 306 + kwin/outline.h | 176 + kwin/overlaywindow.cpp | 179 + kwin/overlaywindow.h | 56 + kwin/ox16-app-kwin.png | Bin 0 -> 380 bytes kwin/ox32-app-kwin.png | Bin 0 -> 611 bytes kwin/ox48-app-kwin.png | Bin 0 -> 877 bytes kwin/oxsc-app-kwin.svgz | Bin 0 -> 3106 bytes kwin/paintredirector.cpp | 519 + kwin/paintredirector.h | 266 + kwin/placement.cpp | 943 ++ kwin/placement.h | 109 + kwin/resources.qrc | 17 + kwin/rules.cpp | 1085 ++ kwin/rules.h | 377 + kwin/scene.cpp | 935 ++ kwin/scene.h | 537 + kwin/scene_opengl.cpp | 2581 +++++ kwin/scene_opengl.h | 683 ++ kwin/scene_xrender.cpp | 1137 ++ kwin/scene_xrender.h | 205 + kwin/screenedge.cpp | 1066 ++ kwin/screenedge.h | 533 + kwin/screens.cpp | 163 + kwin/screens.h | 145 + kwin/scripting/CMakeLists.txt | 4 + kwin/scripting/Messages.sh | 4 + .../scripting/documentation-effect-global.xml | 179 + kwin/scripting/documentation-global.xml | 134 + kwin/scripting/genericscriptedconfig.cpp | 149 + kwin/scripting/genericscriptedconfig.h | 95 + kwin/scripting/kwinscript.desktop | 60 + kwin/scripting/meta.cpp | 240 + kwin/scripting/meta.h | 127 + kwin/scripting/scriptedeffect.cpp | 642 ++ kwin/scripting/scriptedeffect.h | 161 + kwin/scripting/scripting.cpp | 770 ++ kwin/scripting/scripting.h | 346 + kwin/scripting/scripting_model.cpp | 904 ++ kwin/scripting/scripting_model.h | 380 + kwin/scripting/scriptingutils.cpp | 46 + kwin/scripting/scriptingutils.h | 284 + kwin/scripting/timer.cpp | 43 + kwin/scripting/workspace_wrapper.cpp | 299 + kwin/scripting/workspace_wrapper.h | 322 + kwin/scripts/CMakeLists.txt | 9 + kwin/scripts/Messages.sh | 4 + .../desktopchangeosd/contents/ui/main.qml | 37 + .../desktopchangeosd/contents/ui/osd.qml | 297 + .../scripts/desktopchangeosd/metadata.desktop | 105 + .../contents/code/main.js | 34 + .../synchronizeskipswitcher/metadata.desktop | 99 + kwin/scripts/videowall/contents/code/main.js | 45 + kwin/scripts/videowall/metadata.desktop | 102 + kwin/settings.kcfgc | 7 + kwin/shaders/1.10/lanczos-fragment.glsl | 16 + kwin/shaders/1.10/scene-color-fragment.glsl | 5 + kwin/shaders/1.10/scene-color-vertex.glsl | 10 + kwin/shaders/1.10/scene-fragment.glsl | 23 + kwin/shaders/1.10/scene-generic-vertex.glsl | 17 + kwin/shaders/1.10/scene-vertex.glsl | 16 + kwin/shaders/1.40/lanczos-fragment.glsl | 19 + kwin/shaders/1.40/scene-color-fragment.glsl | 10 + kwin/shaders/1.40/scene-color-vertex.glsl | 13 + kwin/shaders/1.40/scene-fragment.glsl | 26 + kwin/shaders/1.40/scene-generic-vertex.glsl | 17 + kwin/shaders/1.40/scene-vertex.glsl | 17 + kwin/shadow.cpp | 238 + kwin/shadow.h | 161 + kwin/sm.cpp | 497 + kwin/sm.h | 112 + kwin/tabbox/CMakeLists.txt | 6 + kwin/tabbox/clientmodel.cpp | 258 + kwin/tabbox/clientmodel.h | 113 + kwin/tabbox/declarative.cpp | 436 + kwin/tabbox/declarative.h | 95 + kwin/tabbox/desktopchain.cpp | 142 + kwin/tabbox/desktopchain.h | 148 + kwin/tabbox/desktopmodel.cpp | 171 + kwin/tabbox/desktopmodel.h | 88 + kwin/tabbox/kwindesktopswitcher.desktop | 54 + kwin/tabbox/kwinwindowswitcher.desktop | 56 + kwin/tabbox/qml/CMakeLists.txt | 39 + kwin/tabbox/qml/IconTabBox.qml | 128 + kwin/tabbox/qml/ShadowedSvgItem.qml | 62 + .../clients/big_icons/contents/ui/main.qml | 115 + .../qml/clients/big_icons/metadata.desktop | 106 + .../qml/clients/compact/contents/ui/main.qml | 214 + .../qml/clients/compact/metadata.desktop | 106 + .../clients/informative/contents/ui/main.qml | 230 + .../qml/clients/informative/metadata.desktop | 104 + .../present_windows/contents/ui/main.qml | 199 + .../clients/present_windows/metadata.desktop | 105 + .../clients/small_icons/contents/ui/main.qml | 96 + .../qml/clients/small_icons/metadata.desktop | 105 + .../qml/clients/text/contents/ui/main.qml | 179 + kwin/tabbox/qml/clients/text/metadata.desktop | 103 + .../clients/thumbnails/contents/ui/main.qml | 204 + .../qml/clients/thumbnails/metadata.desktop | 103 + .../clients/window_strip/contents/ui/main.qml | 143 + .../qml/clients/window_strip/metadata.desktop | 100 + .../desktops/informative/contents/ui/main.qml | 234 + .../qml/desktops/informative/metadata.desktop | 103 + .../desktops/previews/contents/ui/main.qml | 172 + .../qml/desktops/previews/metadata.desktop | 98 + kwin/tabbox/qml/tabbox.qml | 79 + kwin/tabbox/tabbox.cpp | 1608 +++ kwin/tabbox/tabbox.h | 314 + kwin/tabbox/tabboxconfig.cpp | 209 + kwin/tabbox/tabboxconfig.h | 326 + kwin/tabbox/tabboxhandler.cpp | 533 + kwin/tabbox/tabboxhandler.h | 402 + kwin/tabbox/tests/CMakeLists.txt | 58 + kwin/tabbox/tests/mock_declarative.cpp | 94 + kwin/tabbox/tests/mock_tabboxclient.cpp | 38 + kwin/tabbox/tests/mock_tabboxclient.h | 67 + kwin/tabbox/tests/mock_tabboxhandler.cpp | 122 + kwin/tabbox/tests/mock_tabboxhandler.h | 100 + kwin/tabbox/tests/test_desktopchain.cpp | 263 + kwin/tabbox/tests/test_tabbox_clientmodel.cpp | 86 + kwin/tabbox/tests/test_tabbox_clientmodel.h | 52 + kwin/tabbox/tests/test_tabbox_config.cpp | 85 + kwin/tabbox/tests/test_tabbox_handler.cpp | 54 + kwin/tabgroup.cpp | 362 + kwin/tabgroup.h | 209 + kwin/tests/CMakeLists.txt | 90 + kwin/tests/test_client_machine.cpp | 157 + kwin/tests/test_screen_paint_data.cpp | 282 + kwin/tests/test_update_kwin_49.cpp | 543 + kwin/tests/test_virtual_desktops.cpp | 645 ++ kwin/tests/test_window_paint_data.cpp | 356 + kwin/tests/test_xcb_window.cpp | 174 + kwin/tests/test_xcb_wrapper.cpp | 214 + kwin/tests/testutils.h | 61 + kwin/thumbnailitem.cpp | 250 + kwin/thumbnailitem.h | 150 + kwin/toplevel.cpp | 505 + kwin/toplevel.h | 670 ++ kwin/unmanaged.cpp | 161 + kwin/unmanaged.h | 63 + kwin/useractions.cpp | 2035 ++++ kwin/useractions.h | 285 + kwin/utils.cpp | 356 + kwin/utils.h | 320 + kwin/virtualdesktops.cpp | 517 + kwin/virtualdesktops.h | 570 + kwin/workspace.cpp | 1581 +++ kwin/workspace.h | 732 ++ kwin/xcbutils.cpp | 257 + kwin/xcbutils.h | 700 ++ kwrited/CMakeLists.txt | 44 + kwrited/config-kwrited.h.cmake | 1 + kwrited/kwrited-autostart.desktop | 180 + kwrited/kwrited.cpp | 160 + kwrited/kwrited.desktop | 153 + kwrited/kwrited.h | 57 + kwrited/kwrited.notifyrc | 210 + libs/CMakeLists.txt | 19 + libs/Mainpage.dox | 16 + libs/kdm/CMakeLists.txt | 47 + libs/kdm/Messages.sh | 4 + libs/kdm/kgreet_classic.cpp | 480 + libs/kdm/kgreet_classic.h | 84 + libs/kdm/kgreet_generic.cpp | 355 + libs/kdm/kgreet_generic.h | 84 + libs/kdm/kgreet_winbind.cpp | 636 ++ libs/kdm/kgreet_winbind.h | 94 + libs/kdm/kgreeterplugin.h | 411 + libs/kephal/CMakeLists.txt | 5 + libs/kephal/Mainpage.dox | 8 + libs/kephal/README | 22 + libs/kephal/client/CMakeLists.txt | 52 + libs/kephal/client/FindKephal.cmake | 26 + libs/kephal/client/dbusconfigurations.cpp | 186 + libs/kephal/client/dbusconfigurations.h | 147 + libs/kephal/client/dbusoutputs.cpp | 200 + libs/kephal/client/dbusoutputs.h | 65 + libs/kephal/client/dbusscreens.cpp | 142 + libs/kephal/client/dbusscreens.h | 58 + libs/kephal/client/libkephal.cpp | 67 + libs/kephal/client/noconfigurations.cpp | 145 + libs/kephal/client/noconfigurations.h | 97 + libs/kephal/kephal/config-kephal.h.cmake | 1 + libs/kephal/kephal/configurations.cpp | 123 + libs/kephal/kephal/configurations.h | 179 + libs/kephal/kephal/desktopwidgetoutputs.cpp | 173 + libs/kephal/kephal/desktopwidgetoutputs.h | 55 + libs/kephal/kephal/desktopwidgetscreens.cpp | 100 + libs/kephal/kephal/desktopwidgetscreens.h | 53 + libs/kephal/kephal/kephal.h | 53 + libs/kephal/kephal/kephal_export.h | 46 + libs/kephal/kephal/outputs.cpp | 120 + libs/kephal/kephal/outputs.h | 283 + libs/kephal/kephal/screens.cpp | 175 + libs/kephal/kephal/screens.h | 230 + libs/kephal/kephal/simpleoutput.cpp | 188 + libs/kephal/kephal/simpleoutput.h | 95 + libs/kephal/kephal/simplescreen.cpp | 100 + libs/kephal/kephal/simplescreen.h | 65 + libs/kephal/service/CMakeLists.txt | 87 + libs/kephal/service/README | 5 + libs/kephal/service/backend.h | 40 + libs/kephal/service/backendconfigurations.cpp | 271 + libs/kephal/service/backendconfigurations.h | 157 + libs/kephal/service/backendoutputs.cpp | 114 + libs/kephal/service/backendoutputs.h | 74 + libs/kephal/service/configurationscreens.cpp | 75 + libs/kephal/service/configurationscreens.h | 51 + .../service/dbus/dbusapi_configurations.cpp | 200 + .../service/dbus/dbusapi_configurations.h | 85 + libs/kephal/service/dbus/dbusapi_outputs.cpp | 223 + libs/kephal/service/dbus/dbusapi_outputs.h | 90 + libs/kephal/service/dbus/dbusapi_screens.cpp | 114 + libs/kephal/service/dbus/dbusapi_screens.h | 65 + libs/kephal/service/edid.h | 40 + libs/kephal/service/externalconfiguration.cpp | 62 + libs/kephal/service/externalconfiguration.h | 69 + libs/kephal/service/kephal.desktop | 129 + libs/kephal/service/kephald.cpp | 43 + libs/kephal/service/kephald.h | 35 + libs/kephal/service/kephalservice.cpp | 198 + libs/kephal/service/kephalservice.h | 71 + libs/kephal/service/outputscreens.cpp | 270 + libs/kephal/service/outputscreens.h | 86 + libs/kephal/service/standalonekephald.cpp | 55 + libs/kephal/service/xml/README | 9 + .../kephal/service/xml/configurations_xml.cpp | 147 + libs/kephal/service/xml/configurations_xml.h | 136 + libs/kephal/service/xml/xmlnodehandler.cpp | 27 + libs/kephal/service/xml/xmlnodehandler.h | 207 + libs/kephal/service/xml/xmlnodehandler.h.cpp | 237 + libs/kephal/service/xml/xmltype.cpp | 215 + libs/kephal/service/xml/xmltype.h | 80 + libs/kephal/service/xmlconfiguration.cpp | 181 + libs/kephal/service/xmlconfiguration.h | 56 + libs/kephal/service/xmlconfigurations.cpp | 1358 +++ libs/kephal/service/xmlconfigurations.h | 153 + libs/kephal/service/xrandr12/README | 2 + libs/kephal/service/xrandr12/randr.cpp | 24 + libs/kephal/service/xrandr12/randr.h | 96 + libs/kephal/service/xrandr12/randrcrtc.cpp | 476 + libs/kephal/service/xrandr12/randrcrtc.h | 95 + libs/kephal/service/xrandr12/randrdisplay.cpp | 187 + libs/kephal/service/xrandr12/randrdisplay.h | 78 + libs/kephal/service/xrandr12/randrmode.cpp | 84 + libs/kephal/service/xrandr12/randrmode.h | 45 + libs/kephal/service/xrandr12/randroutput.cpp | 477 + libs/kephal/service/xrandr12/randroutput.h | 169 + libs/kephal/service/xrandr12/randrscreen.cpp | 388 + libs/kephal/service/xrandr12/randrscreen.h | 114 + libs/kephal/service/xrandroutputs.cpp | 423 + libs/kephal/service/xrandroutputs.h | 134 + libs/kephal/tests/CMakeLists.txt | 9 + libs/kephal/tests/README | 3 + libs/kephal/tests/kephalapp.cpp | 215 + libs/kephal/tests/kephalapp.h | 64 + libs/ksysguard/CMakeLists.txt | 26 + libs/ksysguard/config-ksysguard.h.cmake | 12 + libs/ksysguard/ksgrd/CMakeLists.txt | 27 + libs/ksysguard/ksgrd/Messages.sh | 2 + libs/ksysguard/ksgrd/SensorAgent.cpp | 310 + libs/ksysguard/ksgrd/SensorAgent.h | 137 + libs/ksysguard/ksgrd/SensorClient.h | 214 + libs/ksysguard/ksgrd/SensorManager.cpp | 429 + libs/ksysguard/ksgrd/SensorManager.h | 141 + libs/ksysguard/ksgrd/SensorShellAgent.cpp | 147 + libs/ksysguard/ksgrd/SensorShellAgent.h | 75 + libs/ksysguard/ksgrd/SensorSocketAgent.cpp | 131 + libs/ksysguard/ksgrd/SensorSocketAgent.h | 69 + libs/ksysguard/lsofui/CMakeLists.txt | 33 + libs/ksysguard/lsofui/LsofSearchWidget.cpp | 45 + libs/ksysguard/lsofui/LsofSearchWidget.h | 45 + libs/ksysguard/lsofui/LsofSearchWidget.ui | 54 + libs/ksysguard/lsofui/Messages.sh | 4 + libs/ksysguard/lsofui/ksysguardlsof.widgets | 8 + libs/ksysguard/lsofui/lsof.cpp | 89 + libs/ksysguard/lsofui/lsof.h | 83 + libs/ksysguard/processcore/CMakeLists.txt | 48 + libs/ksysguard/processcore/Messages.sh | 2 + libs/ksysguard/processcore/actions.actions | 599 + libs/ksysguard/processcore/atop_p.h | 162 + libs/ksysguard/processcore/helper.cpp | 125 + libs/ksysguard/processcore/helper.h | 42 + libs/ksysguard/processcore/process.cpp | 340 + libs/ksysguard/processcore/process.h | 208 + libs/ksysguard/processcore/processes.cpp | 547 + libs/ksysguard/processcore/processes.h | 270 + .../processcore/processes_atop_p.cpp | 375 + libs/ksysguard/processcore/processes_atop_p.h | 79 + .../processcore/processes_base_p.cpp | 22 + libs/ksysguard/processcore/processes_base_p.h | 150 + .../processcore/processes_dragonfly_p.cpp | 274 + .../processcore/processes_freebsd_p.cpp | 270 + .../ksysguard/processcore/processes_gnu_p.cpp | 98 + .../processcore/processes_linux_p.cpp | 701 ++ .../processcore/processes_local_p.cpp | 41 + .../ksysguard/processcore/processes_local_p.h | 72 + .../processcore/processes_netbsd_p.cpp | 292 + .../processcore/processes_openbsd_p.cpp | 306 + .../processcore/processes_remote_p.cpp | 274 + .../processcore/processes_remote_p.h | 78 + .../processcore/processes_solaris_p.cpp | 244 + libs/ksysguard/processui/CMakeLists.txt | 52 + libs/ksysguard/processui/KTextEditVT.cpp | 170 + libs/ksysguard/processui/KTextEditVT.h | 104 + libs/ksysguard/processui/Messages.sh | 4 + libs/ksysguard/processui/ProcessFilter.cpp | 148 + libs/ksysguard/processui/ProcessFilter.h | 64 + libs/ksysguard/processui/ProcessModel.cpp | 2090 ++++ libs/ksysguard/processui/ProcessModel.h | 189 + libs/ksysguard/processui/ProcessModel_p.h | 218 + libs/ksysguard/processui/ProcessWidgetUI.ui | 188 + libs/ksysguard/processui/ReniceDlg.cpp | 192 + libs/ksysguard/processui/ReniceDlg.h | 67 + libs/ksysguard/processui/ReniceDlgUi.ui | 489 + libs/ksysguard/processui/ksysguard.widgets | 17 + .../processui/ksysguardprocesslist.cpp | 1495 +++ .../processui/ksysguardprocesslist.h | 233 + libs/ksysguard/processui/scripting.cpp | 191 + libs/ksysguard/processui/scripting.h | 145 + libs/ksysguard/scripts/README | 40 + libs/ksysguard/scripts/smaps/helper.js | 71 + libs/ksysguard/scripts/smaps/index.html | 80 + libs/ksysguard/scripts/smaps/main.js | 280 + libs/ksysguard/scripts/smaps/smaps.desktop | 66 + libs/ksysguard/scripts/smaps/sorttable.js | 496 + libs/ksysguard/scripts/smaps/style.css | 94 + libs/ksysguard/signalplotter/CMakeLists.txt | 31 + .../signalplotter/kgraphicssignalplotter.cpp | 24 + .../signalplotter/kgraphicssignalplotter.h | 463 + .../signalplotter/ksignalplotter.cpp | 1158 ++ libs/ksysguard/signalplotter/ksignalplotter.h | 461 + .../signalplotter/ksignalplotter.widgets | 10 + .../signalplotter/ksignalplotter_p.h | 150 + libs/ksysguard/tests/CMakeLists.txt | 32 + .../tests/graphicssignalplotterbenchmark.cpp | 57 + .../tests/graphicssignalplotterbenchmark.h | 22 + libs/ksysguard/tests/guitest.cpp | 47 + libs/ksysguard/tests/guitest.h | 32 + libs/ksysguard/tests/processtest.cpp | 223 + libs/ksysguard/tests/processtest.h | 44 + .../tests/signalplotterbenchmark.cpp | 68 + libs/ksysguard/tests/signalplotterbenchmark.h | 18 + libs/ksysguard/tests/signalplottertest.cpp | 573 + libs/ksysguard/tests/signalplottertest.h | 29 + libs/kworkspace/CMakeLists.txt | 62 + libs/kworkspace/Mainpage.dox | 21 + libs/kworkspace/Messages.sh | 2 + libs/kworkspace/README | 6 + libs/kworkspace/interface_util.h | 26 + libs/kworkspace/kdisplaymanager.cpp | 909 ++ libs/kworkspace/kdisplaymanager.h | 102 + libs/kworkspace/kwindowlistmenu.cpp | 230 + libs/kworkspace/kwindowlistmenu.h | 79 + libs/kworkspace/kworkspace.cpp | 258 + libs/kworkspace/kworkspace.h | 150 + libs/kworkspace/kworkspace_export.h | 40 + libs/kworkspace/kworkspace_p.h | 53 + libs/kworkspace/org.kde.ActivityManager.xml | 127 + libs/kworkspace/screenpreviewwidget.cpp | 197 + libs/kworkspace/screenpreviewwidget.h | 69 + libs/oxygen/CMakeLists.txt | 58 + libs/oxygen/Messages.sh | 3 + libs/oxygen/oxygen_export.h | 40 + libs/oxygen/oxygenactiveshadowconfigdata.kcfg | 34 + .../oxygenactiveshadowconfiguration.kcfgc | 6 + libs/oxygen/oxygenanimation.cpp | 28 + libs/oxygen/oxygenanimation.h | 72 + libs/oxygen/oxygenanimationconfigitem.cpp | 108 + libs/oxygen/oxygenanimationconfigitem.h | 109 + .../oxygenbaseanimationconfigwidget.cpp | 88 + libs/oxygen/oxygenbaseanimationconfigwidget.h | 114 + .../oxygengenericanimationconfigitem.cpp | 65 + .../oxygen/oxygengenericanimationconfigitem.h | 109 + libs/oxygen/oxygenhelper.cpp | 1099 ++ libs/oxygen/oxygenhelper.h | 442 + .../oxygeninactiveshadowconfigdata.kcfg | 34 + .../oxygeninactiveshadowconfiguration.kcfgc | 6 + libs/oxygen/oxygenitemmodel.cpp | 70 + libs/oxygen/oxygenitemmodel.h | 115 + libs/oxygen/oxygenlistmodel.h | 370 + libs/oxygen/oxygenshadowcache.cpp | 467 + libs/oxygen/oxygenshadowcache.h | 257 + libs/oxygen/oxygenshadowconfigwidget.cpp | 161 + libs/oxygen/oxygenshadowconfigwidget.h | 110 + libs/oxygen/oxygentileset.cpp | 247 + libs/oxygen/oxygentileset.h | 167 + libs/oxygen/oxygenutil.cpp | 49 + libs/oxygen/oxygenutil.h | 45 + libs/oxygen/ui/oxygenanimationconfigitem.ui | 60 + libs/oxygen/ui/oxygenanimationconfigwidget.ui | 31 + .../ui/oxygengenericanimationconfigbox.ui | 88 + libs/oxygen/ui/oxygenshadowconfigurationui.ui | 146 + libs/plasmaclock/CMakeLists.txt | 38 + libs/plasmaclock/Messages.sh | 4 + libs/plasmaclock/calendar.cpp | 610 ++ libs/plasmaclock/calendar.h | 111 + libs/plasmaclock/calendarConfig.ui | 134 + libs/plasmaclock/calendarHolidaysConfig.ui | 158 + libs/plasmaclock/calendartable.cpp | 1328 +++ libs/plasmaclock/calendartable.h | 137 + libs/plasmaclock/clockapplet.cpp | 770 ++ libs/plasmaclock/clockapplet.h | 101 + libs/plasmaclock/config-calendartable.h.cmake | 2 + libs/plasmaclock/generalConfig.ui | 80 + libs/plasmaclock/plasmaclock_export.h | 40 + libs/plasmaclock/timezonesConfig.ui | 123 + libs/plasmaclock/wheelytoolbutton.cpp | 39 + libs/plasmaclock/wheelytoolbutton.h | 41 + libs/plasmagenericshell/BackgroundDialog.ui | 253 + libs/plasmagenericshell/CMakeLists.txt | 53 + libs/plasmagenericshell/Messages.sh | 4 + libs/plasmagenericshell/MousePlugins.ui | 79 + libs/plasmagenericshell/TODO | 16 + libs/plasmagenericshell/backgrounddialog.cpp | 632 ++ libs/plasmagenericshell/backgrounddialog.h | 80 + libs/plasmagenericshell/mouseinputbutton.cpp | 176 + libs/plasmagenericshell/mouseinputbutton.h | 60 + libs/plasmagenericshell/mouseplugins.cpp | 198 + libs/plasmagenericshell/mouseplugins.h | 65 + libs/plasmagenericshell/mousepluginwidget.cpp | 324 + libs/plasmagenericshell/mousepluginwidget.h | 82 + libs/plasmagenericshell/panelshadows.cpp | 238 + libs/plasmagenericshell/panelshadows.h | 51 + .../plasma-layout-template.desktop | 7 + .../plasmagenericshell_export.h | 40 + .../scripting/appinterface.cpp | 207 + .../scripting/appinterface.h | 100 + libs/plasmagenericshell/scripting/applet.cpp | 270 + libs/plasmagenericshell/scripting/applet.h | 85 + .../scripting/backportglobal.h | 365 + .../scripting/configgroup.cpp | 187 + .../scripting/configgroup.h | 69 + .../scripting/containment.cpp | 321 + .../scripting/containment.h | 110 + libs/plasmagenericshell/scripting/i18n.cpp | 121 + libs/plasmagenericshell/scripting/i18n.h | 35 + .../layouttemplatepackagestructure.cpp | 42 + .../layouttemplatepackagestructure.h | 41 + libs/plasmagenericshell/scripting/rect.cpp | 330 + .../scripting/scriptengine.cpp | 765 ++ .../scripting/scriptengine.h | 104 + libs/plasmagenericshell/scripting/widget.cpp | 181 + libs/plasmagenericshell/scripting/widget.h | 92 + libs/plasmagenericshell/tests/CMakeLists.txt | 33 + libs/plasmagenericshell/tests/background.cpp | 51 + libs/plasmagenericshell/tests/main.cpp | 56 + libs/plasmagenericshell/toolbutton.cpp | 215 + libs/plasmagenericshell/toolbutton.h | 67 + libs/plasmagenericshell/wallpaperpreview.cpp | 67 + libs/plasmagenericshell/wallpaperpreview.h | 51 + .../kcategorizeditemsviewmodels.cpp | 249 + .../kcategorizeditemsviewmodels_p.h | 178 + .../widgetsexplorer/openwidgetassistant.cpp | 199 + .../widgetsexplorer/openwidgetassistant_p.h | 61 + .../widgetsexplorer/package/Messages.sh | 3 + .../package/contents/ui/AppletDelegate.qml | 196 + .../package/contents/ui/Tooltip.qml | 149 + .../package/contents/ui/main.qml | 367 + .../widgetsexplorer/package/metadata.desktop | 58 + .../widgetsexplorer/plasmaappletitemmodel.cpp | 351 + .../widgetsexplorer/plasmaappletitemmodel_p.h | 124 + .../widgetsexplorer/widgetexplorer.cpp | 646 ++ .../widgetsexplorer/widgetexplorer.h | 192 + libs/taskmanager/CMakeLists.txt | 83 + libs/taskmanager/Mainpage.dox | 21 + libs/taskmanager/Messages.sh | 4 + libs/taskmanager/abstractgroupableitem.cpp | 141 + libs/taskmanager/abstractgroupableitem.h | 148 + libs/taskmanager/abstractgroupingstrategy.cpp | 275 + libs/taskmanager/abstractgroupingstrategy.h | 124 + libs/taskmanager/abstractsortingstrategy.cpp | 191 + libs/taskmanager/abstractsortingstrategy.h | 89 + libs/taskmanager/groupmanager.cpp | 1403 +++ libs/taskmanager/groupmanager.h | 232 + libs/taskmanager/launcherconfig.cpp | 211 + libs/taskmanager/launcherconfig.h | 65 + libs/taskmanager/launcherconfig.ui | 121 + libs/taskmanager/launcheritem.cpp | 510 + libs/taskmanager/launcheritem.h | 136 + libs/taskmanager/launcherproperties.cpp | 202 + libs/taskmanager/launcherproperties.h | 64 + libs/taskmanager/launcherproperties.ui | 81 + libs/taskmanager/startup.cpp | 125 + libs/taskmanager/startup.h | 100 + .../strategies/activitysortingstrategy.cpp | 222 + .../strategies/activitysortingstrategy.h | 61 + .../strategies/alphasortingstrategy.cpp | 100 + .../strategies/alphasortingstrategy.h | 47 + .../strategies/desktopsortingstrategy.cpp | 117 + .../strategies/desktopsortingstrategy.h | 52 + .../strategies/manualgroupingstrategy.cpp | 133 + .../strategies/manualgroupingstrategy.h | 89 + .../strategies/manualsortingstrategy.cpp | 112 + .../strategies/manualsortingstrategy.h | 51 + .../strategies/programgroupingstrategy.cpp | 273 + .../strategies/programgroupingstrategy.h | 81 + libs/taskmanager/task.cpp | 726 ++ libs/taskmanager/task.h | 452 + libs/taskmanager/task_p.h | 81 + libs/taskmanager/task_win.cpp | 169 + libs/taskmanager/task_x11.cpp | 274 + libs/taskmanager/taskactions.cpp | 732 ++ libs/taskmanager/taskactions.h | 146 + libs/taskmanager/taskactions_p.h | 236 + libs/taskmanager/taskgroup.cpp | 713 ++ libs/taskmanager/taskgroup.h | 162 + libs/taskmanager/taskitem.cpp | 744 ++ libs/taskmanager/taskitem.h | 125 + libs/taskmanager/taskmanager.cpp | 577 + libs/taskmanager/taskmanager.h | 228 + libs/taskmanager/taskmanager_export.h | 45 + libs/taskmanager/taskmanagerrulesrc | 16 + libs/taskmanager/tasksmodel.cpp | 539 + libs/taskmanager/tasksmodel.h | 107 + mkpamserv | 71 + plasma/.emacs-dirvars | 74 + plasma/CMakeLists.txt | 19 + plasma/HACKING | 21 + plasma/Mainpage.dox | 21 + plasma/README | 63 + plasma/design/CHANGELOG-4.2 | 263 + plasma/design/CHANGELOG-4.3 | 246 + plasma/design/CHANGELOG-4.4 | 169 + plasma/design/CHANGELOG-4.5 | 80 + plasma/design/CHANGELOG-4.6 | 53 + plasma/design/CHANGELOG-template | 43 + plasma/design/README | 9 + plasma/design/activities | 85 + plasma/design/containmentactions | 86 + plasma/design/context | 33 + plasma/design/dataengine | 62 + plasma/design/ideas.txt | 53 + plasma/design/notifications | 67 + plasma/design/plasma-desktop-screen-handling | 14 + plasma/design/plasmoids | 83 + plasma/design/remotewidgets | 40 + plasma/design/screensaver | 61 + plasma/design/security | 57 + plasma/design/standardEffects | 22 + plasma/design/systemtraywidget | 55 + plasma/design/tooltips | 39 + plasma/design/wallpaper | 99 + plasma/design/widgets | 43 + plasma/desktop/CMakeLists.txt | 5 + plasma/desktop/applets/CMakeLists.txt | 11 + plasma/desktop/applets/kickoff/CMakeLists.txt | 76 + plasma/desktop/applets/kickoff/DESIGN-GOALS | 71 + plasma/desktop/applets/kickoff/Messages.sh | 3 + plasma/desktop/applets/kickoff/STATUS-TODO | 66 + .../desktop/applets/kickoff/applet/applet.cpp | 256 + .../desktop/applets/kickoff/applet/applet.h | 82 + .../applets/kickoff/applet/kickoffConfig.ui | 127 + .../applet/plasma-applet-launcher.desktop | 184 + .../applets/kickoff/core/applicationmodel.cpp | 720 ++ .../applets/kickoff/core/applicationmodel.h | 145 + .../applets/kickoff/core/favoritesmodel.cpp | 350 + .../applets/kickoff/core/favoritesmodel.h | 72 + .../applets/kickoff/core/itemhandlers.cpp | 185 + .../applets/kickoff/core/itemhandlers.h | 59 + .../applets/kickoff/core/kickoff_export.h | 40 + .../kickoff/core/kickoffabstractmodel.cpp | 92 + .../kickoff/core/kickoffabstractmodel.h | 55 + .../applets/kickoff/core/kickoffmodel.cpp | 92 + .../applets/kickoff/core/kickoffmodel.h | 57 + .../kickoff/core/kickoffproxymodel.cpp | 92 + .../applets/kickoff/core/kickoffproxymodel.h | 55 + .../applets/kickoff/core/krunnermodel.cpp | 281 + .../applets/kickoff/core/krunnermodel.h | 73 + .../applets/kickoff/core/leavemodel.cpp | 205 + .../desktop/applets/kickoff/core/leavemodel.h | 50 + .../desktop/applets/kickoff/core/models.cpp | 211 + plasma/desktop/applets/kickoff/core/models.h | 138 + .../kickoff/core/org.kde.kickoff.recent.xml | 7 + .../applets/kickoff/core/org.kde.kickoff.xml | 7 + .../kickoff/core/recentapplications.cpp | 193 + .../applets/kickoff/core/recentapplications.h | 93 + .../kickoff/core/recentlyusedmodel.cpp | 282 + .../applets/kickoff/core/recentlyusedmodel.h | 78 + .../applets/kickoff/core/systemmodel.cpp | 483 + .../applets/kickoff/core/systemmodel.h | 103 + .../applets/kickoff/core/urlitemlauncher.cpp | 165 + .../applets/kickoff/core/urlitemlauncher.h | 89 + plasma/desktop/applets/kickoff/main.cpp | 48 + .../applets/kickoff/simpleapplet/menuview.cpp | 565 + .../applets/kickoff/simpleapplet/menuview.h | 179 + .../plasma-applet-simplelauncher.desktop | 168 + .../kickoff/simpleapplet/simpleapplet.cpp | 909 ++ .../kickoff/simpleapplet/simpleapplet.h | 164 + .../applets/kickoff/ui/brandingbutton.cpp | 102 + .../applets/kickoff/ui/brandingbutton.h | 60 + .../applets/kickoff/ui/contentareacap.cpp | 57 + .../applets/kickoff/ui/contentareacap.h | 38 + .../applets/kickoff/ui/contextmenufactory.cpp | 392 + .../applets/kickoff/ui/contextmenufactory.h | 58 + .../applets/kickoff/ui/flipscrollview.cpp | 576 + .../applets/kickoff/ui/flipscrollview.h | 101 + .../applets/kickoff/ui/itemdelegate.cpp | 114 + .../desktop/applets/kickoff/ui/itemdelegate.h | 65 + .../desktop/applets/kickoff/ui/launcher.cpp | 1076 ++ plasma/desktop/applets/kickoff/ui/launcher.h | 115 + .../desktop/applets/kickoff/ui/searchbar.cpp | 151 + plasma/desktop/applets/kickoff/ui/searchbar.h | 58 + plasma/desktop/applets/kickoff/ui/tabbar.cpp | 440 + plasma/desktop/applets/kickoff/ui/tabbar.h | 99 + .../applets/kickoff/ui/urlitemview.cpp | 716 ++ .../desktop/applets/kickoff/ui/urlitemview.h | 87 + plasma/desktop/applets/pager/CMakeLists.txt | 19 + plasma/desktop/applets/pager/Messages.sh | 4 + plasma/desktop/applets/pager/model.cpp | 250 + plasma/desktop/applets/pager/model.h | 112 + .../pager/package/contents/ui/main.qml | 241 + .../pager/package/contents/ui/utils.js | 6 + .../applets/pager/package/metadata.desktop | 58 + plasma/desktop/applets/pager/pager.cpp | 904 ++ plasma/desktop/applets/pager/pager.h | 174 + plasma/desktop/applets/pager/pagerConfig.ui | 168 + .../pager/plasma-pager-default.desktop | 173 + .../showActivityManager/CMakeLists.txt | 15 + .../applets/showActivityManager/Messages.sh | 4 + .../showActivityManager/activities.svgz | Bin 0 -> 58239 bytes .../package/contents/ui/main.qml | 64 + .../package/metadata.desktop | 129 + plasma/desktop/applets/tasks/CMakeLists.txt | 19 + plasma/desktop/applets/tasks/Messages.sh | 5 + .../tasks/package/contents/code/layout.js | 172 + .../tasks/package/contents/code/tools.js | 95 + .../tasks/package/contents/ui/GroupDialog.qml | 115 + .../contents/ui/GroupExpanderOverlay.qml | 98 + .../package/contents/ui/MouseHandler.qml | 90 + .../tasks/package/contents/ui/Task.qml | 290 + .../tasks/package/contents/ui/TaskList.qml | 39 + .../tasks/package/contents/ui/main.qml | 200 + .../applets/tasks/package/metadata.desktop | 171 + .../tasks/plasma-tasks-default.desktop | 171 + .../support/declarativeitemcontainer.cpp | 186 + .../support/declarativeitemcontainer_p.h | 59 + .../applets/tasks/support/draghelper.cpp | 61 + .../applets/tasks/support/draghelper.h | 45 + .../applets/tasks/support/textlabel.cpp | 262 + .../desktop/applets/tasks/support/textlabel.h | 75 + .../desktop/applets/tasks/support/tooltip.cpp | 256 + .../desktop/applets/tasks/support/tooltip.h | 131 + plasma/desktop/applets/tasks/tasks.cpp | 602 + plasma/desktop/applets/tasks/tasks.h | 92 + plasma/desktop/applets/tasks/tasksConfig.ui | 381 + plasma/desktop/applets/trash/CMakeLists.txt | 10 + plasma/desktop/applets/trash/Messages.sh | 2 + .../applets/trash/plasma-applet-trash.desktop | 173 + plasma/desktop/applets/trash/trash.cpp | 427 + plasma/desktop/applets/trash/trash.h | 94 + .../desktop/applets/windowlist/CMakeLists.txt | 14 + plasma/desktop/applets/windowlist/Messages.sh | 2 + .../desktop/applets/windowlist/WindowList.cpp | 313 + .../desktop/applets/windowlist/WindowList.h | 58 + .../plasma-applet-windowlist.desktop | 148 + plasma/desktop/containments/CMakeLists.txt | 2 + .../containments/desktop/CMakeLists.txt | 14 + .../desktop/containments/desktop/Messages.sh | 2 + .../desktop/containments/desktop/desktop.cpp | 185 + plasma/desktop/containments/desktop/desktop.h | 81 + .../containments/desktop/desktoplayout.cpp | 392 + .../containments/desktop/desktoplayout.h | 173 + .../containments/desktop/itemspace.cpp | 916 ++ .../desktop/containments/desktop/itemspace.h | 316 + .../plasma-containment-desktop.desktop | 108 + ...lasma-containment-desktopdashboard.desktop | 135 + .../plasma_desktop_containment.kwinrules | 14 + .../desktop/containments/panel/CMakeLists.txt | 12 + plasma/desktop/containments/panel/Messages.sh | 2 + plasma/desktop/containments/panel/panel.cpp | 743 ++ plasma/desktop/containments/panel/panel.h | 104 + .../panel/plasma-containment-panel.desktop | 135 + plasma/desktop/runners/CMakeLists.txt | 2 + .../runners/plasma-desktop/CMakeLists.txt | 10 + .../runners/plasma-desktop/Messages.sh | 4 + .../plasma-desktop/plasma-desktop-runner.cpp | 146 + .../plasma-desktop/plasma-desktop-runner.h | 51 + .../plasma-runner-plasma-desktop.desktop | 140 + plasma/desktop/shell/CMakeLists.txt | 95 + plasma/desktop/shell/Messages.sh | 5 + .../shell/accessibility/accessiblefactory.cpp | 23 + .../shell/accessibility/accessiblefactory.h | 8 + .../accessibility/accessibleplasmaview.cpp | 144 + .../accessibility/accessibleplasmaview.h | 98 + plasma/desktop/shell/activity.cpp | 420 + plasma/desktop/shell/activity.h | 169 + .../desktop/shell/activitymanager/Messages.sh | 4 + .../shell/activitymanager/activities.knsrc | 7 + .../shell/activitymanager/activitymanager.cpp | 324 + .../shell/activitymanager/activitymanager.h | 117 + .../activitymanager/kidenticongenerator.cpp | 295 + .../activitymanager/kidenticongenerator.h | 47 + .../package/contents/ui/.directory | 5 + .../package/contents/ui/ActivityDelegate.qml | 322 + .../package/contents/ui/main.qml | 305 + .../activitymanager/package/metadata.desktop | 60 + plasma/desktop/shell/checkbox.cpp | 52 + plasma/desktop/shell/checkbox.h | 45 + .../shell/configupdates/CMakeLists.txt | 26 + .../addShowActivitiesManagerPlasmoid.js | 53 + .../notifications-to-orgkdenotifications.cpp | 63 + .../notifications-to-orgkdenotifications.upd | 2 + .../plasma-add-shortcut-to-menu.cpp | 55 + .../plasma-add-shortcut-to-menu.upd | 2 + .../plasma-to-plasma-desktop.cpp | 90 + .../plasma-to-plasmadesktop-shortcuts.upd | 4 + .../plasmarc-to-plasmadesktoprc.upd | 3 + .../set-hidden-single-vd-pager.js | 10 + .../systray-to-notifications-widget.js | 35 + plasma/desktop/shell/controllerwindow.cpp | 558 + plasma/desktop/shell/controllerwindow.h | 110 + plasma/desktop/shell/dashboardview.cpp | 370 + plasma/desktop/shell/dashboardview.h | 86 + .../shell/data/layouts/00-defaultLayout.js | 19 + .../contents/layout.js | 3 + .../metadata.desktop | 75 + .../contents/layout.js | 39 + .../metadata.desktop | 76 + .../contents/layout.js | 3 + .../metadata.desktop | 70 + .../contents/layout.js | 25 + .../metadata.desktop | 71 + .../contents/layout.js | 15 + .../metadata.desktop | 72 + .../desktop/shell/data/plasma-desktop-js.xml | 15 + .../desktop/shell/data/plasma-desktop.desktop | 78 + .../shell/data/plasma-desktop.notifyrc | 264 + .../shell/data/plasma-shell-desktop.kcfg | 19 + .../shell/data/plasma-shell-desktop.kcfgc | 4 + plasma/desktop/shell/data/plasma-themes.knsrc | 6 + plasma/desktop/shell/data/plasma.desktop | 2 + .../desktop/shell/dbus/org.kde.plasma.App.xml | 46 + plasma/desktop/shell/desktopcorona.cpp | 772 ++ plasma/desktop/shell/desktopcorona.h | 131 + plasma/desktop/shell/desktopview.cpp | 391 + plasma/desktop/shell/desktopview.h | 102 + plasma/desktop/shell/interactiveconsole.cpp | 570 + plasma/desktop/shell/interactiveconsole.h | 115 + .../desktop/shell/klistconfirmationdialog.cpp | 165 + .../desktop/shell/klistconfirmationdialog.h | 63 + plasma/desktop/shell/main.cpp | 129 + plasma/desktop/shell/panelapplethandle.cpp | 220 + plasma/desktop/shell/panelapplethandle.h | 80 + plasma/desktop/shell/panelappletoverlay.cpp | 601 + plasma/desktop/shell/panelappletoverlay.h | 97 + plasma/desktop/shell/panelcontroller.cpp | 999 ++ plasma/desktop/shell/panelcontroller.h | 149 + plasma/desktop/shell/panelview.cpp | 1690 +++ plasma/desktop/shell/panelview.h | 290 + plasma/desktop/shell/panelview_win.cpp | 194 + plasma/desktop/shell/plasmaapp.cpp | 1545 +++ plasma/desktop/shell/plasmaapp.h | 192 + plasma/desktop/shell/positioningruler.cpp | 816 ++ plasma/desktop/shell/positioningruler.h | 79 + .../shell/scripting/desktopscriptengine.cpp | 63 + .../shell/scripting/desktopscriptengine.h | 45 + plasma/desktop/shell/scripting/panel.cpp | 414 + plasma/desktop/shell/scripting/panel.h | 105 + plasma/desktop/shell/supportinformation.cpp | 123 + plasma/desktop/shell/supportinformation.h | 52 + plasma/desktop/toolboxes/CMakeLists.txt | 30 + plasma/desktop/toolboxes/Messages.sh | 3 + plasma/desktop/toolboxes/desktoptoolbox.cpp | 859 ++ plasma/desktop/toolboxes/desktoptoolbox.h | 112 + plasma/desktop/toolboxes/internaltoolbox.cpp | 519 + plasma/desktop/toolboxes/internaltoolbox.h | 136 + plasma/desktop/toolboxes/paneltoolbox.cpp | 318 + plasma/desktop/toolboxes/paneltoolbox.h | 88 + .../plasma-toolbox-desktoptoolbox.desktop | 128 + .../plasma-toolbox-paneltoolbox.desktop | 128 + plasma/generic/CMakeLists.txt | 15 + plasma/generic/animators/CMakeLists.txt | 2 + plasma/generic/animators/Mainpage.dox | 9 + .../generic/animators/default/CMakeLists.txt | 10 + .../animators/default/defaultAnimator.cpp | 118 + .../animators/default/defaultAnimator.h | 46 + .../default/plasma-animator-default.desktop | 94 + plasma/generic/applets/CMakeLists.txt | 27 + plasma/generic/applets/Mainpage.dox | 10 + .../applets/activitybar/CMakeLists.txt | 17 + .../generic/applets/activitybar/Messages.sh | 2 + .../applets/activitybar/activitybar.cpp | 372 + .../generic/applets/activitybar/activitybar.h | 72 + .../plasma-applet-activitybar.desktop | 160 + .../applets/analog-clock/CMakeLists.txt | 10 + .../generic/applets/analog-clock/Messages.sh | 5 + plasma/generic/applets/analog-clock/clock.cpp | 472 + plasma/generic/applets/analog-clock/clock.h | 104 + .../applets/analog-clock/clockConfig.ui | 65 + .../plasma-applet-analogclock.desktop | 169 + .../applets/batterymonitor/CMakeLists.txt | 14 + .../applets/batterymonitor/Messages.sh | 4 + .../generic/applets/batterymonitor/README.txt | 32 + .../battery-oxygen-inkscape.svgz | Bin 0 -> 7039 bytes .../batterymonitor/battery-oxygen.svgz | Bin 0 -> 14542 bytes .../batterymonitor/contents/code/logic.js | 210 + .../batterymonitor/contents/config/main.xml | 14 + .../contents/ui/BatteryIcon.qml | 100 + .../contents/ui/BatteryItem.qml | 318 + .../contents/ui/BrightnessItem.qml | 91 + .../contents/ui/CompactRepresentation.qml | 112 + .../contents/ui/PopupDialog.qml | 174 + .../contents/ui/PowerManagementItem.qml | 66 + .../contents/ui/ScrollableListView.qml | 58 + .../contents/ui/batterymonitor.qml | 191 + .../applets/batterymonitor/metadata.desktop | 222 + .../generic/applets/calendar/CMakeLists.txt | 13 + plasma/generic/applets/calendar/calendar.cpp | 154 + plasma/generic/applets/calendar/calendar.h | 69 + .../applets/calendar/mini-calendar.svgz | Bin 0 -> 3859 bytes .../calendar/plasma-applet-calendar.desktop | 170 + .../applets/devicenotifier/CMakeLists.txt | 10 + .../applets/devicenotifier/Messages.sh | 4 + .../package/contents/config/main.xml | 20 + .../package/contents/ui/ActionItem.qml | 82 + .../package/contents/ui/DeviceItem.qml | 295 + .../package/contents/ui/StatusBar.qml | 147 + .../package/contents/ui/config.ui | 65 + .../package/contents/ui/devicenotifier.qml | 407 + .../devicenotifier/package/metadata.desktop | 172 + .../test-predicate-openinwindow.desktop | 75 + .../applets/digital-clock/CMakeLists.txt | 17 + .../generic/applets/digital-clock/Messages.sh | 4 + .../generic/applets/digital-clock/clock.cpp | 784 ++ plasma/generic/applets/digital-clock/clock.h | 110 + .../applets/digital-clock/clockConfig.ui | 487 + .../plasma-applet-digitalclock.desktop | 179 + plasma/generic/applets/icon/CMakeLists.txt | 9 + plasma/generic/applets/icon/Messages.sh | 2 + plasma/generic/applets/icon/icon.cpp | 549 + plasma/generic/applets/icon/icon.h | 90 + .../applets/icon/plasma-applet-icon.desktop | 180 + .../applets/lock_logout/CMakeLists.txt | 10 + .../generic/applets/lock_logout/Messages.sh | 4 + .../lock_logout/contents/config/main.xml | 26 + .../applets/lock_logout/contents/ui/config.ui | 117 + .../applets/lock_logout/contents/ui/data.js | 26 + .../lock_logout/contents/ui/lockout.qml | 238 + .../applets/lock_logout/metadata.desktop | 220 + .../applets/notifications/CMakeLists.txt | 2 + .../generic/applets/notifications/Messages.sh | 5 + .../notifications/contents/config/main.xml | 23 + .../notifications/contents/ui/JobDelegate.qml | 310 + .../notifications/contents/ui/Jobs.qml | 105 + .../contents/ui/LastNotificationPopup.qml | 415 + .../NotificationDelegate.qml | 254 + .../contents/ui/NotificationDelegate/qmldir | 1 + .../contents/ui/NotificationIcon.qml | 188 + .../contents/ui/Notifications.qml | 230 + .../notifications/contents/ui/Title.qml | 43 + .../notifications/contents/ui/config.ui | 69 + .../notifications/contents/ui/main.qml | 171 + .../notifications/contents/ui/uiproperties.js | 23 + .../applets/notifications/metadata.desktop | 164 + .../NotificationDelegate.qml | 195 + .../touch/ui/NotificationDelegate/qmldir | 1 + .../platformcontents/touch/ui/uiproperties.js | 23 + .../applets/panelspacer/CMakeLists.txt | 14 + .../generic/applets/panelspacer/Messages.sh | 2 + .../applets/panelspacer/panelspacer.cpp | 181 + .../generic/applets/panelspacer/panelspacer.h | 51 + ...plasma-applet-panelspacer-internal.desktop | 149 + .../applets/quicklaunch/CMakeLists.txt | 22 + .../generic/applets/quicklaunch/Messages.sh | 4 + .../applets/quicklaunch/icongridlayout.cpp | 422 + .../applets/quicklaunch/icongridlayout.h | 109 + .../generic/applets/quicklaunch/launcher.cpp | 122 + plasma/generic/applets/quicklaunch/launcher.h | 68 + .../applets/quicklaunch/launcherdata.cpp | 225 + .../applets/quicklaunch/launcherdata.h | 106 + .../applets/quicklaunch/launchergrid.cpp | 546 + .../applets/quicklaunch/launchergrid.h | 174 + .../plasma-applet-quicklaunch.desktop | 165 + plasma/generic/applets/quicklaunch/popup.cpp | 115 + plasma/generic/applets/quicklaunch/popup.h | 61 + .../applets/quicklaunch/popuplauncherlist.cpp | 477 + .../applets/quicklaunch/popuplauncherlist.h | 145 + .../applets/quicklaunch/quicklaunch.cpp | 1006 ++ .../generic/applets/quicklaunch/quicklaunch.h | 122 + .../applets/quicklaunch/quicklaunchConfig.ui | 156 + .../applets/system-monitor/CMakeLists.txt | 113 + .../applets/system-monitor/Messages.sh | 4 + .../generic/applets/system-monitor/applet.cpp | 428 + .../generic/applets/system-monitor/applet.h | 115 + .../applets/system-monitor/cpu-config.ui | 93 + plasma/generic/applets/system-monitor/cpu.cpp | 181 + plasma/generic/applets/system-monitor/cpu.h | 67 + .../applets/system-monitor/hdd-config.ui | 97 + plasma/generic/applets/system-monitor/hdd.cpp | 355 + plasma/generic/applets/system-monitor/hdd.h | 73 + .../system-monitor/hdd_activity-config.ui | 97 + .../applets/system-monitor/hdd_activity.cpp | 291 + .../applets/system-monitor/hdd_activity.h | 82 + .../applets/system-monitor/hdd_panel.svgz | Bin 0 -> 1364 bytes .../generic/applets/system-monitor/hwinfo.cpp | 161 + .../generic/applets/system-monitor/hwinfo.h | 67 + .../applets/system-monitor/monitorbutton.cpp | 125 + .../applets/system-monitor/monitorbutton.h | 53 + .../applets/system-monitor/monitoricon.cpp | 86 + .../applets/system-monitor/monitoricon.h | 49 + .../applets/system-monitor/net-config.ui | 93 + plasma/generic/applets/system-monitor/net.cpp | 199 + plasma/generic/applets/system-monitor/net.h | 66 + .../plasma-applet-sm_cpu.desktop | 156 + .../plasma-applet-sm_hdd.desktop | 111 + .../plasma-applet-sm_hdd_activity.desktop | 114 + .../plasma-applet-sm_hwinfo.desktop | 158 + .../plasma-applet-sm_net.desktop | 157 + .../plasma-applet-sm_ram.desktop | 151 + .../plasma-applet-sm_temperature.desktop | 156 + .../plasma-applet-system-monitor.desktop | 178 + .../applets/system-monitor/plotter.cpp | 266 + .../generic/applets/system-monitor/plotter.h | 77 + .../applets/system-monitor/ram-config.ui | 93 + plasma/generic/applets/system-monitor/ram.cpp | 276 + plasma/generic/applets/system-monitor/ram.h | 80 + .../applets/system-monitor/sm_export.h | 40 + .../applets/system-monitor/system-monitor.cpp | 297 + .../applets/system-monitor/system-monitor.h | 67 + .../system-monitor/temperature-config.ui | 90 + .../temperature-offset-delegate.cpp | 61 + .../temperature-offset-delegate.h | 47 + .../applets/system-monitor/temperature.cpp | 226 + .../applets/system-monitor/temperature.h | 67 + .../generic/applets/systemtray/CMakeLists.txt | 66 + plasma/generic/applets/systemtray/Messages.sh | 4 + plasma/generic/applets/systemtray/TODO | 17 + plasma/generic/applets/systemtray/config.h.in | 4 + .../applets/systemtray/core/manager.cpp | 132 + .../generic/applets/systemtray/core/manager.h | 103 + .../applets/systemtray/core/protocol.cpp | 35 + .../applets/systemtray/core/protocol.h | 74 + .../generic/applets/systemtray/core/task.cpp | 198 + plasma/generic/applets/systemtray/core/task.h | 237 + .../package/contents/code/IconsList.js | 34 + .../package/contents/code/TasksSet.js | 130 + .../systemtray/package/contents/code/main.js | 74 + .../package/contents/ui/ArrowArea.qml | 135 + .../package/contents/ui/IconsGrid.qml | 128 + .../package/contents/ui/IconsList.qml | 149 + .../contents/ui/StatusNotifierItem.qml | 276 + .../package/contents/ui/TrayIcon.qml | 31 + .../systemtray/package/contents/ui/main.qml | 347 + .../plasma-applet-systemtray.desktop | 176 + .../dbussystemtray/dbussystemtrayprotocol.cpp | 96 + .../dbussystemtray/dbussystemtrayprotocol.h | 63 + .../dbussystemtray/dbussystemtraytask.cpp | 409 + .../dbussystemtray/dbussystemtraytask.h | 149 + .../protocols/fdo/fdographicswidget.cpp | 227 + .../protocols/fdo/fdographicswidget.h | 65 + .../protocols/fdo/fdonotification.cpp | 40 + .../protocols/fdo/fdonotification.h | 52 + .../systemtray/protocols/fdo/fdoprotocol.cpp | 53 + .../systemtray/protocols/fdo/fdoprotocol.h | 48 + .../protocols/fdo/fdoselectionmanager.cpp | 428 + .../protocols/fdo/fdoselectionmanager.h | 68 + .../systemtray/protocols/fdo/fdotask.cpp | 112 + .../systemtray/protocols/fdo/fdotask.h | 59 + .../protocols/fdo/x11embedcontainer.cpp | 252 + .../protocols/fdo/x11embedcontainer.h | 58 + .../protocols/fdo/x11embeddelegate.cpp | 91 + .../protocols/fdo/x11embeddelegate.h | 55 + .../protocols/fdo/x11embedpainter.cpp | 152 + .../protocols/fdo/x11embedpainter.h | 54 + .../protocols/plasmoid/plasmoidtask.cpp | 205 + .../protocols/plasmoid/plasmoidtask.h | 76 + .../plasmoid/plasmoidtaskprotocol.cpp | 159 + .../protocols/plasmoid/plasmoidtaskprotocol.h | 65 + .../generic/applets/systemtray/ui/applet.cpp | 825 ++ plasma/generic/applets/systemtray/ui/applet.h | 174 + .../generic/applets/systemtray/ui/autohide.ui | 58 + .../systemtray/ui/mouseredirectarea.cpp | 185 + .../applets/systemtray/ui/mouseredirectarea.h | 97 + .../applets/systemtray/ui/visibleitems.ui | 87 + .../applets/systemtray/ui/widgetitem.cpp | 138 + .../applets/systemtray/ui/widgetitem.h | 81 + .../generic/applets/webbrowser/CMakeLists.txt | 19 + plasma/generic/applets/webbrowser/Messages.sh | 4 + .../applets/webbrowser/bookmarkitem.cpp | 70 + .../generic/applets/webbrowser/bookmarkitem.h | 49 + .../applets/webbrowser/bookmarksdelegate.cpp | 103 + .../applets/webbrowser/bookmarksdelegate.h | 55 + .../webbrowser/browserhistorycombobox.cpp | 446 + .../webbrowser/browserhistorycombobox.h | 133 + .../applets/webbrowser/browsermessagebox.cpp | 59 + .../applets/webbrowser/browsermessagebox.h | 49 + .../generic/applets/webbrowser/errorpage.cpp | 158 + plasma/generic/applets/webbrowser/errorpage.h | 29 + .../plasma-applet-webbrowser.desktop | 185 + .../generic/applets/webbrowser/webbrowser.cpp | 675 ++ .../generic/applets/webbrowser/webbrowser.h | 163 + .../applets/webbrowser/webbrowserconfig.ui | 120 + .../applets/webbrowser/webbrowserpage.cpp | 67 + .../applets/webbrowser/webbrowserpage.h | 45 + .../applets/webbrowser/webviewoverlay.cpp | 63 + .../applets/webbrowser/webviewoverlay.h | 53 + .../generic/containmentactions/CMakeLists.txt | 7 + .../applauncher/CMakeLists.txt | 11 + .../containmentactions/applauncher/launch.cpp | 136 + .../containmentactions/applauncher/launch.h | 55 + ...sma-containmentactions-applauncher.desktop | 168 + .../contextmenu/CMakeLists.txt | 18 + .../contextmenu/Messages.sh | 2 + .../containmentactions/contextmenu/menu.cpp | 313 + .../containmentactions/contextmenu/menu.h | 65 + ...sma-containmentactions-contextmenu.desktop | 149 + .../minimalcontextmenu/CMakeLists.txt | 11 + .../minimalcontextmenu/menu.cpp | 71 + .../minimalcontextmenu/menu.h | 43 + ...tainmentactions-minimalcontextmenu.desktop | 80 + .../containmentactions/paste/CMakeLists.txt | 11 + .../containmentactions/paste/paste.cpp | 56 + .../generic/containmentactions/paste/paste.h | 36 + .../plasma-containmentactions-paste.desktop | 149 + .../switchactivity/CMakeLists.txt | 12 + .../switchactivity/Messages.sh | 2 + ...-containmentactions-switchactivity.desktop | 147 + .../switchactivity/switch.cpp | 223 + .../switchactivity/switch.h | 52 + .../switchdesktop/CMakeLists.txt | 11 + .../switchdesktop/Messages.sh | 2 + .../switchdesktop/desktop.cpp | 112 + .../switchdesktop/desktop.h | 53 + ...a-containmentactions-switchdesktop.desktop | 150 + .../switchwindow/CMakeLists.txt | 12 + .../switchwindow/Messages.sh | 3 + .../containmentactions/switchwindow/config.ui | 38 + ...ma-containmentactions-switchwindow.desktop | 147 + .../switchwindow/switch.cpp | 264 + .../containmentactions/switchwindow/switch.h | 71 + plasma/generic/dataengines/CMakeLists.txt | 44 + plasma/generic/dataengines/Mainpage.dox | 10 + .../dataengines/activities/ActivityData.cpp | 87 + .../dataengines/activities/ActivityData.h | 48 + .../dataengines/activities/CMakeLists.txt | 28 + .../activities/activities.operations | 38 + .../dataengines/activities/activityengine.cpp | 270 + .../dataengines/activities/activityengine.h | 81 + .../dataengines/activities/activityjob.cpp | 105 + .../dataengines/activities/activityjob.h | 48 + .../activities/activityservice.cpp | 35 + .../dataengines/activities/activityservice.h | 50 + ...rg.kde.ActivityManager.ActivityRanking.xml | 24 + .../plasma-engine-activities.desktop | 130 + .../dataengines/akonadi/CMakeLists.txt | 29 + .../dataengines/akonadi/akonadiengine.cpp | 486 + .../dataengines/akonadi/akonadiengine.h | 85 + .../akonadi/plasma-engine-akonadi.desktop | 152 + .../applicationjobs/CMakeLists.txt | 21 + .../dataengines/applicationjobs/Messages.sh | 2 + .../applicationjobs.operations | 8 + .../dataengines/applicationjobs/jobaction.cpp | 51 + .../dataengines/applicationjobs/jobaction.h | 46 + .../applicationjobs/jobcontrol.cpp | 38 + .../dataengines/applicationjobs/jobcontrol.h | 42 + .../applicationjobs/kuiserverengine.cpp | 380 + .../applicationjobs/kuiserverengine.h | 145 + .../plasma-dataengine-applicationjobs.desktop | 147 + .../generic/dataengines/apps/CMakeLists.txt | 13 + plasma/generic/dataengines/apps/appjob.cpp | 45 + plasma/generic/dataengines/apps/appjob.h | 45 + .../generic/dataengines/apps/apps.operations | 5 + .../generic/dataengines/apps/appsengine.cpp | 92 + plasma/generic/dataengines/apps/appsengine.h | 66 + .../generic/dataengines/apps/appservice.cpp | 40 + plasma/generic/dataengines/apps/appservice.h | 48 + plasma/generic/dataengines/apps/appsource.cpp | 106 + plasma/generic/dataengines/apps/appsource.h | 59 + .../apps/plasma-dataengine-apps.desktop | 147 + .../dataengines/calendar/CMakeLists.txt | 44 + .../generic/dataengines/calendar/Messages.sh | 2 + .../dataengines/calendar/calendar.operations | 93 + .../dataengines/calendar/calendarengine.cpp | 314 + .../dataengines/calendar/calendarengine.h | 180 + .../calendar/eventdatacontainer.cpp | 233 + .../dataengines/calendar/eventdatacontainer.h | 50 + .../plasma-dataengine-calendar.desktop | 161 + .../devicenotifications/CMakeLists.txt | 12 + .../devicenotificationsengine.cpp | 64 + .../devicenotificationsengine.h | 52 + .../org.kde.DeviceNotifications.xml | 11 + ...sma-dataengine-devicenotifications.desktop | 133 + .../generic/dataengines/dict/CMakeLists.txt | 12 + plasma/generic/dataengines/dict/Messages.sh | 2 + plasma/generic/dataengines/dict/buggywords | 1 + .../generic/dataengines/dict/dictengine.cpp | 240 + plasma/generic/dataengines/dict/dictengine.h | 61 + .../dict/plasma-dataengine-dict.desktop | 171 + .../dataengines/executable/CMakeLists.txt | 10 + .../dataengines/executable/executable.cpp | 77 + .../dataengines/executable/executable.h | 53 + .../plasma-dataengine-executable.desktop | 161 + .../dataengines/favicons/CMakeLists.txt | 12 + .../dataengines/favicons/faviconprovider.cpp | 107 + .../dataengines/favicons/faviconprovider.h | 86 + .../generic/dataengines/favicons/favicons.cpp | 65 + .../generic/dataengines/favicons/favicons.h | 54 + .../plasma-dataengine-favicons.desktop | 159 + .../dataengines/filebrowser/CMakeLists.txt | 10 + .../filebrowser/filebrowserengine.cpp | 171 + .../filebrowser/filebrowserengine.h | 60 + .../plasma-dataengine-filebrowser.desktop | 162 + .../dataengines/geolocation/CMakeLists.txt | 63 + .../cmake/modules/Findlibgps.cmake | 16 + .../dataengines/geolocation/geolocation.cpp | 143 + .../dataengines/geolocation/geolocation.h | 61 + .../geolocation/geolocation_export.h | 41 + .../geolocation/geolocationprovider.cpp | 136 + .../geolocation/geolocationprovider.h | 82 + .../dataengines/geolocation/location_gps.cpp | 119 + .../dataengines/geolocation/location_gps.h | 66 + .../dataengines/geolocation/location_ip.cpp | 122 + .../dataengines/geolocation/location_ip.h | 47 + .../plasma-dataengine-geolocation.desktop | 150 + .../plasma-geolocation-gps.desktop | 143 + .../geolocation/plasma-geolocation-ip.desktop | 143 + .../plasma-geolocationprovider.desktop | 70 + .../dataengines/hotplug/CMakeLists.txt | 12 + .../dataengines/hotplug/hotplug.operations | 10 + .../dataengines/hotplug/hotplugengine.cpp | 269 + .../dataengines/hotplug/hotplugengine.h | 67 + .../dataengines/hotplug/hotplugjob.cpp | 45 + .../generic/dataengines/hotplug/hotplugjob.h | 50 + .../dataengines/hotplug/hotplugservice.cpp | 38 + .../dataengines/hotplug/hotplugservice.h | 43 + .../hotplug/plasma-dataengine-hotplug.desktop | 146 + .../dataengines/keystate/CMakeLists.txt | 12 + .../generic/dataengines/keystate/Messages.sh | 2 + .../dataengines/keystate/keyservice.cpp | 80 + .../generic/dataengines/keystate/keyservice.h | 69 + .../generic/dataengines/keystate/keystate.cpp | 143 + .../generic/dataengines/keystate/keystate.h | 60 + .../keystate/modifierkeystate.operations | 15 + .../plasma-dataengine-keystate.desktop | 148 + .../dataengines/metadata/CMakeLists.txt | 20 + .../generic/dataengines/metadata/Messages.sh | 2 + .../dataengines/metadata/metadata_engine.cpp | 148 + .../dataengines/metadata/metadata_engine.h | 52 + .../metadata/plasma-engine-metadata.desktop | 85 + .../generic/dataengines/mouse/CMakeLists.txt | 19 + .../mouse/cursornotificationhandler.cpp | 114 + .../mouse/cursornotificationhandler.h | 53 + .../generic/dataengines/mouse/mouseengine.cpp | 103 + .../generic/dataengines/mouse/mouseengine.h | 56 + .../mouse/plasma-dataengine-mouse.desktop | 153 + .../generic/dataengines/mpris2/CMakeLists.txt | 32 + plasma/generic/dataengines/mpris2/Messages.sh | 2 + plasma/generic/dataengines/mpris2/TODO | 2 + .../dataengines/mpris2/mpris2.operations | 49 + .../dataengines/mpris2/mpris2engine.cpp | 201 + .../generic/dataengines/mpris2/mpris2engine.h | 65 + .../dataengines/mpris2/multiplexedservice.cpp | 72 + .../dataengines/mpris2/multiplexedservice.h | 49 + .../dataengines/mpris2/multiplexer.cpp | 198 + .../generic/dataengines/mpris2/multiplexer.h | 58 + .../org.freedesktop.DBus.Properties.xml | 27 + .../mpris2/org.mpris.MediaPlayer2.Player.xml | 108 + .../mpris2/org.mpris.MediaPlayer2.xml | 41 + .../mpris2/plasma-dataengine-mpris2.desktop | 103 + .../dataengines/mpris2/playeractionjob.cpp | 180 + .../dataengines/mpris2/playeractionjob.h | 74 + .../dataengines/mpris2/playercontainer.cpp | 397 + .../dataengines/mpris2/playercontainer.h | 99 + .../dataengines/mpris2/playercontrol.cpp | 94 + .../dataengines/mpris2/playercontrol.h | 61 + .../dataengines/network/CMakeLists.txt | 10 + .../generic/dataengines/network/Messages.sh | 2 + .../dataengines/network/networkengine.cpp | 230 + .../dataengines/network/networkengine.h | 56 + .../network/plasma-dataengine-network.desktop | 183 + .../dataengines/notifications/CMakeLists.txt | 15 + .../dataengines/notifications/Messages.sh | 2 + .../notifications/notificationaction.cpp | 73 + .../notifications/notificationaction.h | 49 + .../notifications/notifications.operations | 37 + .../notifications/notificationsengine.cpp | 302 + .../notifications/notificationsengine.h | 82 + .../notifications/notificationservice.cpp | 38 + .../notifications/notificationservice.h | 42 + .../org.freedesktop.Notifications.xml | 37 + .../plasma-dataengine-notifications.desktop | 150 + .../dataengines/nowplaying/CMakeLists.txt | 56 + .../dataengines/nowplaying/Messages.sh | 2 + plasma/generic/dataengines/nowplaying/TODO | 9 + .../nowplaying/config-nowplaying.cmake | 1 + .../nowplaying/nowplaying.operations | 20 + .../nowplaying/nowplayingengine.cpp | 148 + .../dataengines/nowplaying/nowplayingengine.h | 59 + .../plasma-dataengine-nowplaying.desktop | 163 + .../nowplaying/playeractionjob.cpp | 116 + .../dataengines/nowplaying/playeractionjob.h | 54 + .../nowplaying/playercontainer.cpp | 82 + .../dataengines/nowplaying/playercontainer.h | 45 + .../dataengines/nowplaying/playercontrol.cpp | 75 + .../dataengines/nowplaying/playercontrol.h | 45 + .../playerinterface/dbuswatcher.cpp | 124 + .../nowplaying/playerinterface/dbuswatcher.h | 70 + .../nowplaying/playerinterface/juk.cpp | 244 + .../nowplaying/playerinterface/juk.h | 35 + .../nowplaying/playerinterface/juk_p.h | 75 + .../playerinterface/mpris/mpris.cpp | 396 + .../nowplaying/playerinterface/mpris/mpris.h | 34 + .../playerinterface/mpris/mpris_p.h | 89 + .../playerinterface/mpris/mprisdbustypes.cpp | 69 + .../playerinterface/mpris/mprisdbustypes.h | 79 + .../org.freedesktop.MediaPlayer.player.xml | 72 + .../org.freedesktop.MediaPlayer.root.xml | 19 + .../org.freedesktop.MediaPlayer.tracklist.xml | 44 + .../playerinterface/mpris2/mpris2.cpp | 500 + .../playerinterface/mpris2/mpris2.h | 35 + .../playerinterface/mpris2/mpris2_p.h | 113 + .../playerinterface/org.kde.juk.player.xml | 60 + .../nowplaying/playerinterface/player.cpp | 164 + .../nowplaying/playerinterface/player.h | 171 + .../playerinterface/playerfactory.cpp | 26 + .../playerinterface/playerfactory.h | 81 + .../playerinterface/pollingwatcher.cpp | 77 + .../playerinterface/pollingwatcher.h | 71 + .../nowplaying/playerinterface/xmms.cpp | 181 + .../nowplaying/playerinterface/xmms.h | 34 + .../nowplaying/playerinterface/xmms_p.h | 62 + .../generic/dataengines/places/CMakeLists.txt | 24 + plasma/generic/dataengines/places/TODO | 2 + plasma/generic/dataengines/places/jobs.h | 101 + plasma/generic/dataengines/places/modeljob.h | 44 + .../places/org.kde.places.operations | 33 + .../dataengines/places/placesengine.cpp | 123 + .../generic/dataengines/places/placesengine.h | 51 + .../dataengines/places/placeservice.cpp | 69 + .../generic/dataengines/places/placeservice.h | 45 + .../places/plasma-dataengine-places.desktop | 156 + .../dataengines/places/setupdevicejob.cpp | 39 + .../dataengines/places/setupdevicejob.h | 49 + .../powermanagement/CMakeLists.txt | 17 + .../dataengines/powermanagement/README.txt | 13 + .../plasma-dataengine-powermanagement.desktop | 147 + .../powermanagement/powermanagementengine.cpp | 486 + .../powermanagement/powermanagementengine.h | 86 + .../powermanagement/powermanagementjob.cpp | 159 + .../powermanagement/powermanagementjob.h | 47 + .../powermanagementservice.cpp | 35 + .../powermanagement/powermanagementservice.h | 39 + .../powermanagementservice.operations | 45 + plasma/generic/dataengines/rss/CMakeLists.txt | 13 + plasma/generic/dataengines/rss/Messages.sh | 2 + .../rss/plasma-dataengine-rss.desktop | 165 + plasma/generic/dataengines/rss/rss.cpp | 346 + plasma/generic/dataengines/rss/rss.h | 90 + .../generic/dataengines/share/CMakeLists.txt | 43 + plasma/generic/dataengines/share/Messages.sh | 2 + .../dataengines/share/backends/CMakeLists.txt | 11 + .../share/backends/im9/CMakeLists.txt | 7 + .../share/backends/im9/contents/code/main.js | 47 + .../share/backends/im9/metadata.desktop | 97 + .../backends/imgsusepasteorg/CMakeLists.txt | 7 + .../imgsusepasteorg/contents/code/main.js | 47 + .../backends/imgsusepasteorg/metadata.desktop | 119 + .../share/backends/imgur/CMakeLists.txt | 7 + .../backends/imgur/contents/code/main.js | 41 + .../share/backends/imgur/metadata.desktop | 125 + .../share/backends/kde/CMakeLists.txt | 7 + .../share/backends/kde/contents/code/main.js | 44 + .../share/backends/kde/metadata.desktop | 111 + .../share/backends/pastebincom/CMakeLists.txt | 7 + .../pastebincom/contents/code/main.js | 39 + .../backends/pastebincom/metadata.desktop | 126 + .../backends/pasteopensuseorg/CMakeLists.txt | 7 + .../pasteopensuseorg/contents/code/main.js | 46 + .../pasteopensuseorg/metadata.desktop | 127 + .../backends/pasteubuntucom/CMakeLists.txt | 7 + .../pasteubuntucom/contents/code/main.js | 41 + .../backends/pasteubuntucom/metadata.desktop | 70 + .../backends/privatepaste/CMakeLists.txt | 7 + .../privatepaste/contents/code/main.js | 46 + .../backends/privatepaste/metadata.desktop | 125 + .../simplestimagehosting/CMakeLists.txt | 7 + .../contents/code/main.js | 38 + .../simplestimagehosting/metadata.desktop | 121 + .../share/backends/wklej/CMakeLists.txt | 7 + .../backends/wklej/contents/code/main.js | 41 + .../share/backends/wklej/metadata.desktop | 126 + .../share/backends/wstaw/CMakeLists.txt | 7 + .../backends/wstaw/contents/code/main.js | 38 + .../share/backends/wstaw/metadata.desktop | 126 + .../data/plasma-dataengine-share.desktop | 127 + .../plasma-packagestructure-share.desktop | 121 + .../share/data/plasma_shareprovider.desktop | 60 + .../share/plugin_share_package.cpp | 23 + .../dataengines/share/share.operations | 10 + .../dataengines/share/share_package.cpp | 40 + .../generic/dataengines/share/share_package.h | 31 + .../generic/dataengines/share/shareengine.cpp | 120 + .../generic/dataengines/share/shareengine.h | 44 + .../dataengines/share/shareprovider.cpp | 348 + .../generic/dataengines/share/shareprovider.h | 98 + .../dataengines/share/shareservice.cpp | 181 + .../generic/dataengines/share/shareservice.h | 70 + .../dataengines/soliddevice/CMakeLists.txt | 16 + .../dataengines/soliddevice/Messages.sh | 2 + .../soliddevice/devicesignalmapmanager.cpp | 135 + .../soliddevice/devicesignalmapmanager.h | 49 + .../soliddevice/devicesignalmapper.cpp | 100 + .../soliddevice/devicesignalmapper.h | 114 + .../dataengines/soliddevice/hddtemp.cpp | 105 + .../generic/dataengines/soliddevice/hddtemp.h | 54 + .../plasma-dataengine-soliddevice.desktop | 159 + .../soliddevice/soliddevice.operations | 14 + .../soliddevice/soliddeviceengine.cpp | 806 ++ .../soliddevice/soliddeviceengine.h | 100 + .../soliddevice/soliddevicejob.cpp | 64 + .../dataengines/soliddevice/soliddevicejob.h | 50 + .../soliddevice/soliddeviceservice.cpp | 43 + .../soliddevice/soliddeviceservice.h | 43 + .../statusnotifieritem/CMakeLists.txt | 33 + .../plasma_engine_statusnotifieritem.desktop | 127 + .../statusnotifieritem.operations | 20 + .../statusnotifieritem_engine.cpp | 145 + .../statusnotifieritem_engine.h | 59 + .../statusnotifieritemjob.cpp | 57 + .../statusnotifieritemjob.h | 51 + .../statusnotifieritemservice.cpp | 41 + .../statusnotifieritemservice.h | 49 + .../statusnotifieritemsource.cpp | 485 + .../statusnotifieritemsource.h | 85 + .../statusnotifieritem/systemtraytypes.cpp | 129 + .../statusnotifieritem/systemtraytypes.h | 39 + .../dataengines/systemmonitor/CMakeLists.txt | 14 + .../dataengines/systemmonitor/Messages.sh | 2 + .../plasma-dataengine-systemmonitor.desktop | 166 + .../dataengines/systemmonitor/sensorclient.h | 192 + .../systemmonitor/systemmonitor.cpp | 210 + .../dataengines/systemmonitor/systemmonitor.h | 63 + .../generic/dataengines/tasks/CMakeLists.txt | 14 + .../tasks/plasma-dataengine-tasks.desktop | 156 + plasma/generic/dataengines/tasks/taskjob.cpp | 136 + plasma/generic/dataengines/tasks/taskjob.h | 48 + .../dataengines/tasks/tasks.operations | 43 + .../generic/dataengines/tasks/tasksengine.cpp | 129 + .../generic/dataengines/tasks/tasksengine.h | 75 + .../generic/dataengines/tasks/taskservice.cpp | 40 + .../generic/dataengines/tasks/taskservice.h | 48 + .../generic/dataengines/tasks/tasksource.cpp | 184 + plasma/generic/dataengines/tasks/tasksource.h | 59 + .../tasks/virtualdesktopssource.cpp | 51 + .../dataengines/tasks/virtualdesktopssource.h | 43 + .../generic/dataengines/time/CMakeLists.txt | 12 + .../time/plasma-dataengine-time.desktop | 165 + .../generic/dataengines/time/solarsystem.cpp | 335 + plasma/generic/dataengines/time/solarsystem.h | 128 + .../generic/dataengines/time/timeengine.cpp | 111 + plasma/generic/dataengines/time/timeengine.h | 52 + .../generic/dataengines/time/timesource.cpp | 259 + plasma/generic/dataengines/time/timesource.h | 62 + .../dataengines/weather/CMakeLists.txt | 7 + .../generic/dataengines/weather/Messages.sh | 10 + .../dataengines/weather/ions/CMakeLists.txt | 27 + .../weather/ions/bbcukmet/CMakeLists.txt | 8 + .../ions/bbcukmet/ion-bbcukmet.desktop | 158 + .../weather/ions/bbcukmet/ion_bbcukmet.cpp | 964 ++ .../weather/ions/bbcukmet/ion_bbcukmet.h | 178 + .../weather/ions/data/bbcukmet_i18n.dat | 118 + .../weather/ions/data/envcan_i18n.dat | 361 + .../weather/ions/data/noaa_i18n.dat | 359 + .../weather/ions/dataengineconsumer.h | 66 + .../weather/ions/debianweather/CMakeLists.txt | 16 + .../debianweather/ion-debianweather.desktop | 110 + .../ions/debianweather/iondebianweather.cpp | 293 + .../ions/debianweather/iondebianweather.h | 89 + .../weather/ions/envcan/CMakeLists.txt | 8 + .../weather/ions/envcan/ion-envcan.desktop | 153 + .../weather/ions/envcan/ion_envcan.cpp | 1922 ++++ .../weather/ions/envcan/ion_envcan.h | 261 + .../dataengines/weather/ions/includes/Ion | 1 + .../generic/dataengines/weather/ions/ion.cpp | 210 + plasma/generic/dataengines/weather/ions/ion.h | 132 + .../dataengines/weather/ions/ion_export.h | 40 + .../weather/ions/noaa/CMakeLists.txt | 8 + .../weather/ions/noaa/ion-noaa.desktop | 153 + .../weather/ions/noaa/ion_noaa.cpp | 967 ++ .../dataengines/weather/ions/noaa/ion_noaa.h | 185 + .../weather/ions/wetter.com/CMakeLists.txt | 7 + .../ions/wetter.com/ion-wettercom.desktop | 141 + .../weather/ions/wetter.com/ion_wettercom.cpp | 823 ++ .../weather/ions/wetter.com/ion_wettercom.h | 173 + .../weather/plasma-dataengine-weather.desktop | 157 + .../dataengines/weather/weatherengine.cpp | 275 + .../dataengines/weather/weatherengine.h | 137 + plasma/generic/runners/CMakeLists.txt | 23 + .../generic/runners/activities/CMakeLists.txt | 12 + plasma/generic/runners/activities/Messages.sh | 4 + .../runners/activities/activityrunner.cpp | 173 + .../runners/activities/activityrunner.h | 53 + .../plasma-runner-activityrunner.desktop | 121 + plasma/generic/runners/bookmarks/.gitignore | 1 + .../generic/runners/bookmarks/CMakeLists.txt | 45 + plasma/generic/runners/bookmarks/Messages.sh | 2 + .../runners/bookmarks/bookmarkmatch.cpp | 94 + .../generic/runners/bookmarks/bookmarkmatch.h | 47 + .../runners/bookmarks/bookmarksrunner.cpp | 143 + .../runners/bookmarks/bookmarksrunner.h | 64 + .../runners/bookmarks/bookmarksrunner_defs.h | 26 + plasma/generic/runners/bookmarks/browser.h | 39 + .../runners/bookmarks/browserfactory.cpp | 58 + .../runners/bookmarks/browserfactory.h | 38 + .../runners/bookmarks/browsers/chrome.cpp | 117 + .../runners/bookmarks/browsers/chrome.h | 49 + .../bookmarks/browsers/chromefindprofile.cpp | 63 + .../bookmarks/browsers/chromefindprofile.h | 40 + .../runners/bookmarks/browsers/findprofile.h | 42 + .../runners/bookmarks/browsers/firefox.cpp | 166 + .../runners/bookmarks/browsers/firefox.h | 48 + .../runners/bookmarks/browsers/kdebrowser.cpp | 103 + .../runners/bookmarks/browsers/kdebrowser.h | 52 + .../runners/bookmarks/browsers/opera.cpp | 101 + .../runners/bookmarks/browsers/opera.h | 45 + plasma/generic/runners/bookmarks/favicon.cpp | 26 + plasma/generic/runners/bookmarks/favicon.h | 55 + .../runners/bookmarks/faviconfromblob.cpp | 148 + .../runners/bookmarks/faviconfromblob.h | 50 + .../generic/runners/bookmarks/fetchsqlite.cpp | 97 + .../generic/runners/bookmarks/fetchsqlite.h | 56 + .../bookmarks/plasma-runner-bookmarks.desktop | 160 + .../runners/bookmarks/tests/CMakeLists.txt | 14 + .../.config/chromium/Local State | 65 + .../Chrome-Bookmarks-Sample.json | 55 + .../Chrome-Bookmarks-SecondProfile.json | 20 + .../bookmarks/tests/testchromebookmarks.cpp | 125 + .../bookmarks/tests/testchromebookmarks.h | 53 + .../generic/runners/calculator/CMakeLists.txt | 35 + plasma/generic/runners/calculator/Messages.sh | 2 + .../runners/calculator/calculatorrunner.cpp | 322 + .../runners/calculator/calculatorrunner.h | 60 + .../plasma-runner-calculator.desktop | 171 + .../runners/calculator/qalculate_engine.cpp | 127 + .../runners/calculator/qalculate_engine.h | 55 + plasma/generic/runners/kill/CMakeLists.txt | 28 + plasma/generic/runners/kill/Messages.sh | 3 + plasma/generic/runners/kill/TODO | 0 plasma/generic/runners/kill/killrunner.cpp | 223 + plasma/generic/runners/kill/killrunner.h | 77 + .../runners/kill/killrunner_config.cpp | 90 + .../generic/runners/kill/killrunner_config.h | 59 + .../generic/runners/kill/killrunner_config.ui | 129 + .../runners/kill/plasma-runner-kill.desktop | 147 + .../kill/plasma-runner-kill_config.desktop | 78 + .../generic/runners/locations/CMakeLists.txt | 11 + plasma/generic/runners/locations/Messages.sh | 2 + .../runners/locations/locationrunner.cpp | 166 + .../runners/locations/locationrunner.h | 41 + .../locations/plasma-runner-locations.desktop | 165 + .../runners/nepomuksearch/CMakeLists.txt | 34 + .../generic/runners/nepomuksearch/Messages.sh | 2 + .../nepomuksearch/nepomuksearchrunner.cpp | 386 + .../nepomuksearch/nepomuksearchrunner.h | 82 + .../plasma-runner-nepomuksearch.desktop | 125 + plasma/generic/runners/places/CMakeLists.txt | 18 + plasma/generic/runners/places/Messages.sh | 2 + .../generic/runners/places/placesrunner.cpp | 170 + plasma/generic/runners/places/placesrunner.h | 66 + .../places/plasma-runner-places.desktop | 133 + .../generic/runners/powerdevil/CMakeLists.txt | 15 + plasma/generic/runners/powerdevil/Messages.sh | 3 + .../runners/powerdevil/PowerDevilRunner.cpp | 329 + .../runners/powerdevil/PowerDevilRunner.h | 59 + .../plasma-runner-powerdevil.desktop | 159 + .../runners/recentdocuments/CMakeLists.txt | 11 + .../runners/recentdocuments/Messages.sh | 2 + plasma/generic/runners/recentdocuments/README | 7 + .../recentdocuments/recentdocuments.cpp | 111 + .../recentdocuments/recentdocuments.desktop | 97 + .../runners/recentdocuments/recentdocuments.h | 50 + .../generic/runners/services/CMakeLists.txt | 11 + plasma/generic/runners/services/Messages.sh | 2 + .../services/plasma-runner-services.desktop | 179 + .../runners/services/servicerunner.cpp | 256 + .../generic/runners/services/servicerunner.h | 56 + .../generic/runners/sessions/CMakeLists.txt | 14 + plasma/generic/runners/sessions/Messages.sh | 2 + .../sessions/plasma-runner-sessions.desktop | 164 + .../runners/sessions/sessionrunner.cpp | 284 + .../generic/runners/sessions/sessionrunner.h | 55 + plasma/generic/runners/shell/CMakeLists.txt | 12 + plasma/generic/runners/shell/Messages.sh | 4 + .../runners/shell/plasma-runner-shell.desktop | 168 + plasma/generic/runners/shell/shellOptions.ui | 264 + plasma/generic/runners/shell/shell_config.cpp | 61 + plasma/generic/runners/shell/shell_config.h | 45 + plasma/generic/runners/shell/shellrunner.cpp | 179 + plasma/generic/runners/shell/shellrunner.h | 59 + plasma/generic/runners/solid/CMakeLists.txt | 11 + plasma/generic/runners/solid/Messages.sh | 3 + .../generic/runners/solid/devicewrapper.cpp | 210 + plasma/generic/runners/solid/devicewrapper.h | 89 + .../runners/solid/plasma-runner-solid.desktop | 150 + plasma/generic/runners/solid/solidrunner.cpp | 286 + plasma/generic/runners/solid/solidrunner.h | 76 + .../runners/webshortcuts/CMakeLists.txt | 11 + .../generic/runners/webshortcuts/Messages.sh | 2 + .../plasma-runner-webshortcuts.desktop | 129 + .../webshortcuts/webshortcutrunner.cpp | 168 + .../runners/webshortcuts/webshortcutrunner.h | 56 + .../runners/windowedwidgets/CMakeLists.txt | 13 + .../runners/windowedwidgets/Messages.sh | 2 + .../plasma-runner-windowedwidgets.desktop | 136 + .../windowedwidgets/windowedwidgetsrunner.cpp | 134 + .../windowedwidgets/windowedwidgetsrunner.h | 58 + plasma/generic/runners/windows/CMakeLists.txt | 10 + plasma/generic/runners/windows/Messages.sh | 2 + .../windows/plasma-runner-windows.desktop | 149 + .../generic/runners/windows/windowsrunner.cpp | 467 + .../generic/runners/windows/windowsrunner.h | 68 + plasma/generic/scriptengines/CMakeLists.txt | 9 + .../scriptengines/python/CMakeLists.txt | 41 + .../plasma-scriptengine-applet-python.desktop | 149 + ...sma-scriptengine-dataengine-python.desktop | 151 + .../plasma-scriptengine-runner-python.desktop | 133 + ...asma-scriptengine-wallpaper-python.desktop | 137 + .../scriptengines/python/plasma_importer.py | 120 + .../scriptengines/python/plasmascript.py | 225 + .../scriptengines/python/pyappletscript.py | 172 + .../scriptengines/python/pydataengine.py | 79 + .../generic/scriptengines/python/pyrunner.py | 93 + .../scriptengines/python/pywallpaper.py | 97 + .../generic/scriptengines/ruby/CMakeLists.txt | 6 + plasma/generic/scriptengines/ruby/ChangeLog | 140 + plasma/generic/scriptengines/ruby/applet.rb | 1215 +++ .../generic/scriptengines/ruby/data_engine.rb | 147 + .../plasma-scriptengine-ruby-applet.desktop | 149 + ...lasma-scriptengine-ruby-dataengine.desktop | 150 + .../scriptengines/webkit/CMakeLists.txt | 33 + .../generic/scriptengines/webkit/Messages.sh | 2 + plasma/generic/scriptengines/webkit/README | 2 + .../generic/scriptengines/webkit/bundle.cpp | 430 + plasma/generic/scriptengines/webkit/bundle.h | 86 + .../dashboard/AppleClasses/AppleAnimator.js | 142 + .../dashboard/AppleClasses/AppleButton.js | 0 .../dashboard/AppleClasses/AppleInfoButton.js | 9 + .../dashboard/AppleClasses/AppleScrollArea.js | 127 + .../dashboard/AppleClasses/AppleScrollbar.js | 1 + .../dashboard/AppleClasses/AppleSlider.js | 1 + .../dashboard/AppleClasses/CMakeLists.txt | 7 + .../webkit/dashboard/CMakeLists.txt | 2 + .../webkit/dashboard/button/CMakeLists.txt | 2 + .../webkit/dashboard/button/genericButton.js | 8 + .../scriptengines/webkit/dashboard_plugin.cpp | 25 + .../scriptengines/webkit/dashboardapplet.cpp | 94 + .../scriptengines/webkit/dashboardapplet.h | 54 + .../scriptengines/webkit/dashboardjs.cpp | 179 + .../scriptengines/webkit/dashboardjs.h | 116 + .../plasma-packagestructure-dashboard.desktop | 159 + .../plasma-packagestructure-web.desktop | 163 + ...asma-scriptengine-applet-dashboard.desktop | 166 + .../plasma-scriptengine-applet-web.desktop | 163 + .../generic/scriptengines/webkit/plasmajs.cpp | 141 + .../generic/scriptengines/webkit/plasmajs.h | 93 + .../scriptengines/webkit/plasmawebapplet.cpp | 483 + .../scriptengines/webkit/plasmawebapplet.h | 112 + .../webkit/tests/AppletAnimatorTest.html | 39 + .../scriptengines/webkit/tests/HelloWorld.zip | Bin 0 -> 24205 bytes .../scriptengines/webkit/webapplet.cpp | 154 + .../generic/scriptengines/webkit/webapplet.h | 66 + .../webkit/webapplet_package.cpp | 50 + .../scriptengines/webkit/webapplet_package.h | 41 + .../scriptengines/webkit/webapplet_plugin.cpp | 25 + .../generic/scriptengines/webkit/webpage.cpp | 75 + plasma/generic/scriptengines/webkit/webpage.h | 49 + plasma/generic/shells/CMakeLists.txt | 1 + .../shells/plasma-windowed/CMakeLists.txt | 19 + .../shells/plasma-windowed/Messages.sh | 2 + .../generic/shells/plasma-windowed/main.cpp | 60 + .../shells/plasma-windowed/plasmaapp.cpp | 255 + .../shells/plasma-windowed/plasmaapp.h | 83 + .../shells/plasma-windowed/singleview.cpp | 165 + .../shells/plasma-windowed/singleview.h | 70 + plasma/generic/wallpapers/CMakeLists.txt | 2 + .../generic/wallpapers/color/CMakeLists.txt | 15 + plasma/generic/wallpapers/color/Messages.sh | 5 + .../wallpapers/color/backgrounddelegate.cpp | 131 + .../wallpapers/color/backgrounddelegate.h | 41 + .../wallpapers/color/backgroundlistmodel.cpp | 131 + .../wallpapers/color/backgroundlistmodel.h | 53 + plasma/generic/wallpapers/color/color.cpp | 236 + plasma/generic/wallpapers/color/color.h | 62 + plasma/generic/wallpapers/color/config.ui | 176 + plasma/generic/wallpapers/color/itemsview.cpp | 32 + plasma/generic/wallpapers/color/itemsview.h | 32 + .../color/plasma-wallpaper-color.desktop | 135 + .../generic/wallpapers/image/CMakeLists.txt | 22 + plasma/generic/wallpapers/image/Messages.sh | 5 + .../wallpapers/image/backgrounddelegate.cpp | 162 + .../wallpapers/image/backgrounddelegate.h | 42 + .../wallpapers/image/backgroundlistmodel.cpp | 428 + .../wallpapers/image/backgroundlistmodel.h | 118 + plasma/generic/wallpapers/image/image.cpp | 935 ++ plasma/generic/wallpapers/image/image.h | 142 + .../generic/wallpapers/image/imageconfig.ui | 194 + plasma/generic/wallpapers/image/itemsview.cpp | 32 + plasma/generic/wallpapers/image/itemsview.h | 32 + .../image/plasma-wallpaper-image.desktop | 341 + .../generic/wallpapers/image/removebutton.cpp | 230 + .../generic/wallpapers/image/removebutton.h | 90 + .../wallpapers/image/removebuttonmanager.cpp | 120 + .../wallpapers/image/removebuttonmanager.h | 68 + .../wallpapers/image/slideshowconfig.ui | 330 + .../generic/wallpapers/image/wallpaper.knsrc | 6 + plasma/netbook/CMakeLists.txt | 7 + plasma/netbook/applets/CMakeLists.txt | 5 + .../applets/currentappcontrol/CMakeLists.txt | 16 + .../applets/currentappcontrol/Messages.sh | 3 + .../currentappcontrol/currentappcontrol.cpp | 451 + .../currentappcontrol/currentappcontrol.h | 91 + .../applets/currentappcontrol/general.ui | 32 + .../plasma-applet-currentappcontrol.desktop | 146 + .../netbook/applets/searchbox/CMakeLists.txt | 15 + plasma/netbook/applets/searchbox/Messages.sh | 2 + .../searchbox/plasma-applet-searchbox.desktop | 142 + .../netbook/applets/searchbox/searchbox.cpp | 153 + plasma/netbook/applets/searchbox/searchbox.h | 63 + plasma/netbook/containments/CMakeLists.txt | 4 + .../containments/common/appletmovespacer.cpp | 57 + .../containments/common/appletmovespacer.h | 50 + .../common/linearappletoverlay.cpp | 298 + .../containments/common/linearappletoverlay.h | 77 + .../containments/netpanel/CMakeLists.txt | 13 + .../netbook/containments/netpanel/Messages.sh | 2 + .../containments/netpanel/dummytoolbox.cpp | 60 + .../containments/netpanel/dummytoolbox.h | 45 + .../netbook/containments/netpanel/panel.cpp | 535 + plasma/netbook/containments/netpanel/panel.h | 89 + .../plasma-containment-netpanel.desktop | 155 + .../netbook/containments/sal/CMakeLists.txt | 26 + plasma/netbook/containments/sal/Messages.sh | 2 + .../containments/sal/iconactioncollection.cpp | 79 + .../containments/sal/iconactioncollection.h | 50 + .../containments/sal/itemcontainer.cpp | 721 ++ .../netbook/containments/sal/itemcontainer.h | 140 + plasma/netbook/containments/sal/itemview.cpp | 213 + plasma/netbook/containments/sal/itemview.h | 102 + .../containments/sal/models/commonmodel.h | 41 + .../sal/models/favouritesmodel.cpp | 209 + .../containments/sal/models/favouritesmodel.h | 54 + .../containments/sal/models/krunnermodel.cpp | 228 + .../containments/sal/models/krunnermodel.h | 72 + .../containments/sal/models/kservicemodel.cpp | 299 + .../containments/sal/models/kservicemodel.h | 67 + .../sal/models/standarditemfactory.cpp | 37 + .../sal/models/standarditemfactory.h | 41 + .../sal/plasma-containment-sal.desktop | 128 + .../containments/sal/plasma-sal-menu.desktop | 139 + .../netbook/containments/sal/resultwidget.cpp | 94 + .../netbook/containments/sal/resultwidget.h | 56 + .../containments/sal/runnersconfig.cpp | 65 + .../netbook/containments/sal/runnersconfig.h | 55 + plasma/netbook/containments/sal/sal.cpp | 753 ++ plasma/netbook/containments/sal/sal.h | 135 + .../sal/services/plasma-sal-bookmarks.desktop | 169 + .../sal/services/plasma-sal-contacts.desktop | 146 + .../services/plasma-sal-development.desktop | 162 + .../sal/services/plasma-sal-education.desktop | 166 + .../sal/services/plasma-sal-games.desktop | 169 + .../sal/services/plasma-sal-graphics.desktop | 166 + .../sal/services/plasma-sal-internet.desktop | 165 + .../services/plasma-sal-multimedia.desktop | 166 + .../sal/services/plasma-sal-office.desktop | 165 + .../sal/services/plasma-sal-system.desktop | 165 + .../sal/services/plasma-sal-utility.desktop | 165 + .../netbook/containments/sal/stripwidget.cpp | 292 + plasma/netbook/containments/sal/stripwidget.h | 102 + plasma/netbook/dataengines/CMakeLists.txt | 1 + .../dataengines/searchlaunch/CMakeLists.txt | 19 + .../plasma-engine-searchlaunch.desktop | 140 + .../dataengines/searchlaunch/salengine.cpp | 48 + .../dataengines/searchlaunch/salengine.h | 40 + .../dataengines/searchlaunch/salservice.cpp | 40 + .../dataengines/searchlaunch/salservice.h | 44 + .../searchlaunch/searchlaunch.operations | 10 + plasma/netbook/desktoptheme/CMakeLists.txt | 2 + .../desktoptheme/air-netbook/CMakeLists.txt | 6 + .../netbook/desktoptheme/air-netbook/colors | 82 + .../desktoptheme/air-netbook/metadata.desktop | 148 + .../air-netbook/widgets/background.svgz | Bin 0 -> 5988 bytes .../air-netbook/widgets/panel-background.svgz | Bin 0 -> 9421 bytes plasma/netbook/shell/CMakeLists.txt | 41 + plasma/netbook/shell/Messages.sh | 2 + .../shell/data/layouts/00-defaultLayout.js | 6 + .../contents/layout.js | 13 + .../metadata.desktop | 139 + .../contents/layout.js | 12 + .../metadata.desktop | 78 + .../contents/layout.js | 8 + .../metadata.desktop | 77 + ...org.kde.plasma-netbook.defaultPage.desktop | 138 + ...rg.kde.plasma-netbook.defaultPanel.desktop | 77 + ...-org.kde.plasma-netbook.defaultSal.desktop | 77 + plasma/netbook/shell/main.cpp | 70 + plasma/netbook/shell/netcorona.cpp | 234 + plasma/netbook/shell/netcorona.h | 73 + plasma/netbook/shell/netdialogmanager.cpp | 83 + plasma/netbook/shell/netdialogmanager.h | 48 + plasma/netbook/shell/netpanelcontroller.cpp | 255 + plasma/netbook/shell/netpanelcontroller.h | 65 + .../netbook/shell/nettoolbox/CMakeLists.txt | 15 + plasma/netbook/shell/nettoolbox/Messages.sh | 2 + .../netbook/shell/nettoolbox/nettoolbox.cpp | 566 + plasma/netbook/shell/nettoolbox/nettoolbox.h | 109 + .../plasma-toolbox-nettoolbox.desktop | 124 + plasma/netbook/shell/netview.cpp | 338 + plasma/netbook/shell/netview.h | 89 + plasma/netbook/shell/plasmaapp.cpp | 1306 +++ plasma/netbook/shell/plasmaapp.h | 158 + .../shell/scripting/netbookscriptengine.cpp | 64 + .../shell/scripting/netbookscriptengine.h | 42 + plasma/netbook/shell/scripting/newspaper.cpp | 88 + plasma/netbook/shell/scripting/newspaper.h | 67 + plasma/netbook/shell/scripting/panel.cpp | 172 + plasma/netbook/shell/scripting/panel.h | 82 + plasma/screensaver/CMakeLists.txt | 6 + .../screensaver/containments/CMakeLists.txt | 2 + .../containments/screensaver/CMakeLists.txt | 10 + .../containments/screensaver/Messages.sh | 2 + .../containments/screensaver/desktop.cpp | 116 + .../containments/screensaver/desktop.h | 53 + .../plasma-containment-saverdesktop.desktop | 95 + plasma/screensaver/shell/BackgroundDialog.ui | 108 + plasma/screensaver/shell/CMakeLists.txt | 39 + plasma/screensaver/shell/Messages.sh | 5 + plasma/screensaver/shell/backgrounddialog.cpp | 211 + plasma/screensaver/shell/backgrounddialog.h | 52 + plasma/screensaver/shell/main.cpp | 68 + .../shell/org.kde.plasma-overlay.App.xml | 17 + plasma/screensaver/shell/plasma-overlayrc | 10 + plasma/screensaver/shell/plasmaapp.cpp | 514 + plasma/screensaver/shell/plasmaapp.h | 129 + plasma/screensaver/shell/savercorona.cpp | 269 + plasma/screensaver/shell/savercorona.h | 75 + plasma/screensaver/shell/saverview.cpp | 294 + plasma/screensaver/shell/saverview.h | 82 + powerdevil/.krazy | 3 + powerdevil/CMakeLists.txt | 11 + powerdevil/COPYING | 346 + powerdevil/PowerDevilSettings.kcfg | 45 + powerdevil/PowerDevilSettings.kcfgc | 5 + powerdevil/daemon/BackendConfig.cmake | 66 + powerdevil/daemon/CMakeLists.txt | 112 + powerdevil/daemon/Messages.sh | 5 + powerdevil/daemon/actions/CMakeLists.txt | 6 + .../daemon/actions/bundled/CMakeLists.txt | 19 + .../actions/bundled/brightnesscontrol.cpp | 191 + .../actions/bundled/brightnesscontrol.h | 79 + .../bundled/brightnesscontrolconfig.cpp | 75 + .../actions/bundled/brightnesscontrolconfig.h | 52 + .../daemon/actions/bundled/dimdisplay.cpp | 121 + .../daemon/actions/bundled/dimdisplay.h | 62 + .../actions/bundled/dimdisplayconfig.cpp | 75 + .../daemon/actions/bundled/dimdisplayconfig.h | 51 + .../actions/bundled/handlebuttonevents.cpp | 207 + .../actions/bundled/handlebuttonevents.h | 73 + .../bundled/handlebuttoneventsconfig.cpp | 145 + .../bundled/handlebuttoneventsconfig.h | 51 + .../bundled/keyboardbrightnesscontrol.cpp | 199 + .../bundled/keyboardbrightnesscontrol.h | 79 + .../keyboardbrightnesscontrolconfig.cpp | 75 + .../bundled/keyboardbrightnesscontrolconfig.h | 52 + ...erManagement.Actions.BrightnessControl.xml | 15 + ...rManagement.Actions.HandleButtonEvents.xml | 8 + ...ment.Actions.KeyboardBrightnessControl.xml | 15 + ...PowerManagement.Actions.SuspendSession.xml | 14 + .../powerdevilbrightnesscontrolaction.desktop | 106 + .../powerdevildimdisplayaction.desktop | 106 + ...powerdevilhandlebuttoneventsaction.desktop | 119 + ...vilkeyboardbrightnesscontrolaction.desktop | 98 + .../bundled/powerdevilrunscriptaction.desktop | 120 + .../powerdevilsuspendsessionaction.desktop | 118 + .../daemon/actions/bundled/runscript.cpp | 88 + powerdevil/daemon/actions/bundled/runscript.h | 58 + .../actions/bundled/runscriptconfig.cpp | 111 + .../daemon/actions/bundled/runscriptconfig.h | 58 + .../daemon/actions/bundled/suspendsession.cpp | 207 + .../daemon/actions/bundled/suspendsession.h | 89 + .../actions/bundled/suspendsessionconfig.cpp | 106 + .../actions/bundled/suspendsessionconfig.h | 52 + powerdevil/daemon/actions/dpms/CMakeLists.txt | 24 + .../actions/dpms/powerdevildpmsaction.cpp | 233 + .../actions/dpms/powerdevildpmsaction.desktop | 119 + .../actions/dpms/powerdevildpmsaction.h | 58 + .../dpms/powerdevildpmsactionconfig.cpp | 67 + .../actions/dpms/powerdevildpmsactionconfig.h | 43 + .../daemon/actions/powerdevilaction.desktop | 71 + .../daemon/backends/hal/halsuspendjob.cpp | 136 + .../daemon/backends/hal/halsuspendjob.h | 52 + .../backends/hal/powerdevilhalbackend.cpp | 519 + .../backends/hal/powerdevilhalbackend.desktop | 115 + .../backends/hal/powerdevilhalbackend.h | 93 + .../upower/backlight_helper_actions.actions | 369 + .../backends/upower/backlighthelper.cpp | 373 + .../daemon/backends/upower/backlighthelper.h | 72 + .../upower/dbus/com.ubuntu.Upstart.xml | 8 + .../dbus/org.freedesktop.UPower.Device.xml | 613 ++ .../org.freedesktop.UPower.KbdBacklight.xml | 101 + .../upower/dbus/org.freedesktop.UPower.xml | 395 + .../backends/upower/login1suspendjob.cpp | 107 + .../daemon/backends/upower/login1suspendjob.h | 55 + .../upower/powerdevilupowerbackend.cpp | 570 + .../upower/powerdevilupowerbackend.desktop | 115 + .../backends/upower/powerdevilupowerbackend.h | 109 + powerdevil/daemon/backends/upower/udevqt.h | 109 + powerdevil/daemon/backends/upower/udevqt_p.h | 82 + .../daemon/backends/upower/udevqtclient.cpp | 256 + .../daemon/backends/upower/udevqtdevice.cpp | 270 + .../backends/upower/upowersuspendjob.cpp | 88 + .../daemon/backends/upower/upowersuspendjob.h | 54 + .../daemon/backends/upower/xlibandxrandr.h | 36 + .../backends/upower/xrandrbrightness.cpp | 182 + .../daemon/backends/upower/xrandrbrightness.h | 46 + .../backends/upower/xrandrx11helper.cpp | 70 + .../daemon/backends/upower/xrandrx11helper.h | 49 + powerdevil/daemon/brightnessosdwidget.cpp | 135 + powerdevil/daemon/brightnessosdwidget.h | 65 + powerdevil/daemon/config-powerdevil.h.cmake | 2 + powerdevil/daemon/kdedpowerdevil.cpp | 112 + powerdevil/daemon/kdedpowerdevil.h | 47 + .../daemon/org.kde.Solid.PowerManagement.xml | 44 + powerdevil/daemon/powerdevil.desktop | 145 + powerdevil/daemon/powerdevilaction.cpp | 115 + powerdevil/daemon/powerdevilaction.h | 234 + powerdevil/daemon/powerdevilactionconfig.cpp | 60 + powerdevil/daemon/powerdevilactionconfig.h | 136 + powerdevil/daemon/powerdevilactionpool.cpp | 186 + powerdevil/daemon/powerdevilactionpool.h | 60 + .../daemon/powerdevilbackendinterface.cpp | 180 + .../daemon/powerdevilbackendinterface.h | 327 + powerdevil/daemon/powerdevilbackendloader.cpp | 61 + powerdevil/daemon/powerdevilbackendloader.h | 36 + powerdevil/daemon/powerdevilcore.cpp | 730 ++ powerdevil/daemon/powerdevilcore.h | 142 + powerdevil/daemon/powerdevilfdoconnector.cpp | 141 + powerdevil/daemon/powerdevilfdoconnector.h | 78 + powerdevil/daemon/powerdevilpolicyagent.cpp | 579 + powerdevil/daemon/powerdevilpolicyagent.h | 141 + .../daemon/powerdevilprofilegenerator.cpp | 359 + .../daemon/powerdevilprofilegenerator.h | 64 + powerdevil/kcmodule/CMakeLists.txt | 10 + powerdevil/kcmodule/activities/CMakeLists.txt | 24 + powerdevil/kcmodule/activities/Messages.sh | 5 + .../kcmodule/activities/activityWidget.ui | 192 + .../kcmodule/activities/activitypage.cpp | 219 + powerdevil/kcmodule/activities/activitypage.h | 57 + .../kcmodule/activities/activitywidget.cpp | 189 + .../kcmodule/activities/activitywidget.h | 61 + .../powerdevilactivitiesconfig.desktop | 147 + powerdevil/kcmodule/common/CMakeLists.txt | 19 + powerdevil/kcmodule/common/ErrorOverlay.cpp | 113 + powerdevil/kcmodule/common/ErrorOverlay.h | 44 + powerdevil/kcmodule/common/Messages.sh | 2 + .../kcmodule/common/actionconfigwidget.cpp | 88 + .../kcmodule/common/actionconfigwidget.h | 45 + .../kcmodule/common/actioneditwidget.cpp | 202 + powerdevil/kcmodule/common/actioneditwidget.h | 67 + powerdevil/kcmodule/global/CMakeLists.txt | 23 + powerdevil/kcmodule/global/GeneralPage.cpp | 214 + powerdevil/kcmodule/global/GeneralPage.h | 50 + powerdevil/kcmodule/global/Messages.sh | 5 + powerdevil/kcmodule/global/generalPage.ui | 301 + .../global/powerdevilglobalconfig.desktop | 148 + powerdevil/kcmodule/profiles/CMakeLists.txt | 24 + powerdevil/kcmodule/profiles/EditPage.cpp | 300 + powerdevil/kcmodule/profiles/EditPage.h | 69 + powerdevil/kcmodule/profiles/Messages.sh | 5 + .../profiles/powerdevilprofilesconfig.desktop | 148 + .../kcmodule/profiles/profileEditPage.ui | 63 + powerdevil/powerdevil.notifyrc | 1575 +++ qguiplatformplugin_kde/CMakeLists.txt | 15 + .../qguiplatformplugin_kde.cpp | 387 + qguiplatformplugin_kde/qguiplatformplugin_p.h | 125 + solid-actions-kcm/ActionEditor.cpp | 190 + solid-actions-kcm/ActionEditor.h | 62 + solid-actions-kcm/ActionEditor.ui | 335 + solid-actions-kcm/ActionItem.cpp | 158 + solid-actions-kcm/ActionItem.h | 76 + solid-actions-kcm/ActionModel.cpp | 121 + solid-actions-kcm/ActionModel.h | 48 + solid-actions-kcm/AddAction.ui | 43 + solid-actions-kcm/CMakeLists.txt | 49 + solid-actions-kcm/DesktopFileGenerator.cpp | 74 + solid-actions-kcm/Messages.sh | 4 + solid-actions-kcm/PredicateItem.cpp | 208 + solid-actions-kcm/PredicateItem.h | 56 + solid-actions-kcm/PredicateModel.cpp | 176 + solid-actions-kcm/PredicateModel.h | 56 + solid-actions-kcm/SolidActionData.cpp | 192 + solid-actions-kcm/SolidActionData.h | 57 + solid-actions-kcm/SolidActions.cpp | 231 + solid-actions-kcm/SolidActions.h | 65 + solid-actions-kcm/SolidActions.ui | 53 + .../device-actions/CMakeLists.txt | 3 + .../solid-device-AcAdapter.desktop | 120 + .../solid-device-AudioInterface.desktop | 430 + .../solid-device-Battery.desktop | 407 + .../device-actions/solid-device-Block.desktop | 286 + .../solid-device-Button.desktop | 281 + .../solid-device-Camera.desktop | 215 + .../solid-device-DvbInterface.desktop | 360 + .../solid-device-NetworkInterface.desktop | 360 + .../solid-device-OpticalDisc.desktop | 941 ++ .../solid-device-OpticalDrive.desktop | 723 ++ .../solid-device-PortableMediaPlayer.desktop | 215 + .../solid-device-Processor.desktop | 355 + .../solid-device-SerialInterface.desktop | 258 + .../solid-device-SmartCardReader.desktop | 142 + .../solid-device-StorageAccess.desktop | 217 + .../solid-device-StorageDrive.desktop | 434 + .../solid-device-StorageVolume.desktop | 507 + .../device-actions/solid-device-Video.desktop | 144 + .../solid-action-template.desktop | 9 + solid-actions-kcm/solid-actions.desktop | 178 + solid-actions-kcm/solid-device-type.desktop | 70 + startkde.cmake | 405 + statusnotifierwatcher/CMakeLists.txt | 26 + .../statusnotifierwatcher.cpp | 148 + .../statusnotifierwatcher.desktop | 128 + statusnotifierwatcher/statusnotifierwatcher.h | 69 + statusnotifierwatcher/systemtraytypedefs.h | 48 + systemsettings/CMakeLists.txt | 17 + systemsettings/Mainpage.dox | 7 + systemsettings/Messages.sh | 4 + systemsettings/app/BaseConfig.kcfgc | 5 + systemsettings/app/CMakeLists.txt | 22 + systemsettings/app/SettingsBase.cpp | 401 + systemsettings/app/SettingsBase.h | 96 + systemsettings/app/SystemSettingsApp.cpp | 47 + systemsettings/app/SystemSettingsApp.h | 49 + systemsettings/app/ToolTips/ktooltip.cpp | 102 + systemsettings/app/ToolTips/ktooltip.h | 46 + .../app/ToolTips/ktooltipwindow.cpp | 64 + .../app/ToolTips/ktooltipwindow_p.h | 40 + .../app/ToolTips/tooltipmanager.cpp | 249 + systemsettings/app/ToolTips/tooltipmanager.h | 84 + systemsettings/app/configDialog.ui | 45 + systemsettings/app/kdesystemsettings.desktop | 113 + systemsettings/app/main.cpp | 50 + systemsettings/app/org.kde.systemsettings.xml | 7 + systemsettings/app/systemsettings.desktop | 178 + systemsettings/app/systemsettings.kcfg | 17 + systemsettings/app/systemsettingsui.rc | 24 + systemsettings/categories/CMakeLists.txt | 38 + .../categories/settings-accessibility.desktop | 100 + .../settings-account-details.desktop | 73 + ...plication-and-system-notifications.desktop | 70 + ...pplication-appearance-and-behavior.desktop | 66 + .../settings-application-appearance.desktop | 70 + .../settings-audio-and-video.desktop | 100 + .../categories/settings-bluetooth.desktop | 93 + .../settings-desktop-appearance.desktop | 131 + .../categories/settings-display.desktop | 160 + .../categories/settings-hardware.desktop | 94 + .../categories/settings-input-devices.desktop | 73 + .../categories/settings-locale.desktop | 72 + .../settings-lost-and-found.desktop | 71 + .../settings-network-and-connectivity.desktop | 72 + .../settings-network-settings.desktop | 95 + .../categories/settings-permissions.desktop | 73 + .../settings-personal-information.desktop | 74 + .../settings-power-management.desktop | 83 + .../settings-removable-devices.desktop | 77 + .../categories/settings-sharing.desktop | 92 + .../settings-shortcuts-and-gestures.desktop | 71 + .../settings-startup-and-shutdown.desktop | 70 + .../settings-system-administration.desktop | 84 + .../settings-window-behaviour.desktop | 96 + ...-workspace-appearance-and-behavior.desktop | 70 + .../settings-workspace-behavior.desktop | 69 + .../categories/systemsettingscategory.desktop | 96 + systemsettings/classic/CMakeLists.txt | 14 + systemsettings/classic/CategoryList.cpp | 136 + systemsettings/classic/CategoryList.h | 53 + systemsettings/classic/ClassicMode.cpp | 265 + systemsettings/classic/ClassicMode.h | 65 + systemsettings/classic/configClassic.ui | 38 + systemsettings/classic/main.html | 59 + .../classic/settings-classic-view.desktop | 194 + .../classic/systemsettings-classic.css | 42 + systemsettings/core/BaseData.cpp | 70 + systemsettings/core/BaseData.h | 88 + systemsettings/core/BaseMode.cpp | 138 + systemsettings/core/BaseMode.h | 245 + systemsettings/core/CMakeLists.txt | 31 + systemsettings/core/ExternalAppModule.cpp | 57 + systemsettings/core/ExternalAppModule.h | 50 + systemsettings/core/Mainpage.dox | 17 + systemsettings/core/MenuItem.cpp | 138 + systemsettings/core/MenuItem.h | 165 + systemsettings/core/MenuModel.cpp | 204 + systemsettings/core/MenuModel.h | 172 + systemsettings/core/MenuProxyModel.cpp | 111 + systemsettings/core/MenuProxyModel.h | 104 + systemsettings/core/ModuleView.cpp | 400 + systemsettings/core/ModuleView.h | 156 + systemsettings/core/externalModule.ui | 86 + .../core/systemsettingsexternalapp.desktop | 71 + .../core/systemsettingsview.desktop | 74 + .../core/systemsettingsview_export.h | 40 + .../examples/external-application.txt | 11 + systemsettings/examples/native-kcm.txt | 14 + systemsettings/icons/CMakeLists.txt | 13 + systemsettings/icons/CategorizedView.cpp | 53 + systemsettings/icons/CategorizedView.h | 35 + systemsettings/icons/CategoryDrawer.cpp | 274 + systemsettings/icons/CategoryDrawer.h | 42 + systemsettings/icons/IconMode.cpp | 204 + systemsettings/icons/IconMode.h | 61 + .../icons/settings-icon-view.desktop | 205 + 5665 files changed, 827277 insertions(+) create mode 100644 .krazy create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 COPYING.DOC create mode 100644 COPYING.LIB create mode 100644 CTestConfig.cmake create mode 100644 ConfigureChecks.cmake create mode 100644 KDE4WorkspaceConfig.cmake.in create mode 100644 Mainpage.dox create mode 100644 README create mode 100644 README.pam create mode 100644 appmenu/CMakeLists.txt create mode 100644 appmenu/appmenu.cpp create mode 100644 appmenu/appmenu.desktop create mode 100644 appmenu/appmenu.h create mode 100644 appmenu/appmenu_dbus.cpp create mode 100644 appmenu/appmenu_dbus.h create mode 100644 appmenu/com.canonical.AppMenu.Registrar.xml create mode 100644 appmenu/glowbar.cpp create mode 100644 appmenu/glowbar.h create mode 100644 appmenu/gtkicons.h create mode 100644 appmenu/kdbusimporter.h create mode 100644 appmenu/menubar.cpp create mode 100644 appmenu/menubar.h create mode 100644 appmenu/menubutton.cpp create mode 100644 appmenu/menubutton.h create mode 100644 appmenu/menuimporter.cpp create mode 100644 appmenu/menuimporter.h create mode 100644 appmenu/menuwidget.cpp create mode 100644 appmenu/menuwidget.h create mode 100644 appmenu/org.kde.kded.appmenu.xml create mode 100644 appmenu/shadows.cpp create mode 100644 appmenu/shadows.h create mode 100644 appmenu/topmenubar.cpp create mode 100644 appmenu/topmenubar.h create mode 100644 appmenu/verticalmenu.cpp create mode 100644 appmenu/verticalmenu.h create mode 100644 cmake/CMakeLists.txt create mode 100644 cmake/modules/CMakeLists.txt create mode 100644 cmake/modules/COPYING-CMAKE-SCRIPTS create mode 100644 cmake/modules/FindCkConnector.cmake create mode 100644 cmake/modules/FindDBus.cmake create mode 100644 cmake/modules/FindLibXKlavier.cmake create mode 100644 cmake/modules/FindOpenGLES.cmake create mode 100644 cmake/modules/FindPAM.cmake create mode 100644 cmake/modules/FindPCIUTILS.cmake create mode 100644 cmake/modules/FindQJSON.cmake create mode 100644 cmake/modules/FindQalculate.cmake create mode 100644 cmake/modules/FindRAW1394.cmake create mode 100644 cmake/modules/FindSensors.cmake create mode 100644 cmake/modules/FindUDev.cmake create mode 100644 cmake/modules/FindWayland.cmake create mode 100644 cmake/modules/FindX11_XCB.cmake create mode 100644 cmake/modules/FindXCB.cmake create mode 100644 cmake/modules/PkgConfigGetVar.cmake create mode 100644 cmake/modules/UnixAuth.cmake create mode 100644 config-X11.h.cmake create mode 100644 config-unix.h.cmake create mode 100644 config-workspace.h.cmake create mode 100644 cursors/CMakeLists.txt create mode 120000 cursors/KDE_Classic/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/KDE_Classic/cursors/00008160000006810000408080010102 create mode 120000 cursors/KDE_Classic/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/KDE_Classic/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/KDE_Classic/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/KDE_Classic/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/KDE_Classic/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/KDE_Classic/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/KDE_Classic/cursors/X_cursor create mode 120000 cursors/KDE_Classic/cursors/all-scroll create mode 100644 cursors/KDE_Classic/cursors/bottom_left_corner create mode 100644 cursors/KDE_Classic/cursors/bottom_right_corner create mode 100644 cursors/KDE_Classic/cursors/bottom_side create mode 100644 cursors/KDE_Classic/cursors/center_ptr create mode 100644 cursors/KDE_Classic/cursors/closedhand create mode 120000 cursors/KDE_Classic/cursors/col-resize create mode 100644 cursors/KDE_Classic/cursors/cross create mode 120000 cursors/KDE_Classic/cursors/crossed_circle create mode 100644 cursors/KDE_Classic/cursors/crosshair create mode 120000 cursors/KDE_Classic/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/KDE_Classic/cursors/dnd-move create mode 120000 cursors/KDE_Classic/cursors/dnd-no-drop create mode 120000 cursors/KDE_Classic/cursors/dnd-none create mode 120000 cursors/KDE_Classic/cursors/e-resize create mode 120000 cursors/KDE_Classic/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/KDE_Classic/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/KDE_Classic/cursors/fleur create mode 100644 cursors/KDE_Classic/cursors/forbidden create mode 100644 cursors/KDE_Classic/cursors/half-busy create mode 100644 cursors/KDE_Classic/cursors/hand1 create mode 100644 cursors/KDE_Classic/cursors/hand2 create mode 100644 cursors/KDE_Classic/cursors/help create mode 100644 cursors/KDE_Classic/cursors/ibeam create mode 100644 cursors/KDE_Classic/cursors/left_ptr create mode 120000 cursors/KDE_Classic/cursors/left_ptr_watch create mode 100644 cursors/KDE_Classic/cursors/left_side create mode 120000 cursors/KDE_Classic/cursors/move create mode 120000 cursors/KDE_Classic/cursors/n-resize create mode 120000 cursors/KDE_Classic/cursors/not-allowed create mode 100644 cursors/KDE_Classic/cursors/openhand create mode 100644 cursors/KDE_Classic/cursors/pirate create mode 120000 cursors/KDE_Classic/cursors/pointer create mode 100644 cursors/KDE_Classic/cursors/pointing_hand create mode 120000 cursors/KDE_Classic/cursors/progress create mode 100644 cursors/KDE_Classic/cursors/question_arrow create mode 100644 cursors/KDE_Classic/cursors/right_ptr create mode 100644 cursors/KDE_Classic/cursors/right_side create mode 120000 cursors/KDE_Classic/cursors/row-resize create mode 120000 cursors/KDE_Classic/cursors/s-resize create mode 100644 cursors/KDE_Classic/cursors/sb_h_double_arrow create mode 100644 cursors/KDE_Classic/cursors/sb_v_double_arrow create mode 100644 cursors/KDE_Classic/cursors/size_all create mode 100644 cursors/KDE_Classic/cursors/size_bdiag create mode 100644 cursors/KDE_Classic/cursors/size_fdiag create mode 100644 cursors/KDE_Classic/cursors/size_hor create mode 100644 cursors/KDE_Classic/cursors/size_ver create mode 100644 cursors/KDE_Classic/cursors/split_h create mode 100644 cursors/KDE_Classic/cursors/split_v create mode 120000 cursors/KDE_Classic/cursors/text create mode 100644 cursors/KDE_Classic/cursors/top_left_corner create mode 100644 cursors/KDE_Classic/cursors/top_right_corner create mode 100644 cursors/KDE_Classic/cursors/top_side create mode 100644 cursors/KDE_Classic/cursors/up_arrow create mode 120000 cursors/KDE_Classic/cursors/v_double_arrow create mode 120000 cursors/KDE_Classic/cursors/w-resize create mode 100644 cursors/KDE_Classic/cursors/wait create mode 100644 cursors/KDE_Classic/cursors/watch create mode 120000 cursors/KDE_Classic/cursors/whats_this create mode 100644 cursors/KDE_Classic/cursors/xcursorconfig create mode 100644 cursors/KDE_Classic/cursors/xterm create mode 100644 cursors/KDE_Classic/index.theme create mode 100644 cursors/LICENSE create mode 120000 cursors/Oxygen_Black/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/Oxygen_Black/cursors/00008160000006810000408080010102 create mode 120000 cursors/Oxygen_Black/cursors/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/Oxygen_Black/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/Oxygen_Black/cursors/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/Oxygen_Black/cursors/3085a0e285430894940527032f8b26df create mode 120000 cursors/Oxygen_Black/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/Oxygen_Black/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/Oxygen_Black/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/Oxygen_Black/cursors/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/Oxygen_Black/cursors/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/Oxygen_Black/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/Oxygen_Black/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/Oxygen_Black/cursors/X_cursor create mode 120000 cursors/Oxygen_Black/cursors/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/Oxygen_Black/cursors/alias create mode 120000 cursors/Oxygen_Black/cursors/all-scroll create mode 120000 cursors/Oxygen_Black/cursors/b66166c04f8c3109214a4fbd64a50fc8 create mode 100644 cursors/Oxygen_Black/cursors/circle create mode 100644 cursors/Oxygen_Black/cursors/closedhand create mode 120000 cursors/Oxygen_Black/cursors/col-resize create mode 100644 cursors/Oxygen_Black/cursors/color-picker create mode 100644 cursors/Oxygen_Black/cursors/copy create mode 100644 cursors/Oxygen_Black/cursors/cross create mode 120000 cursors/Oxygen_Black/cursors/crossed_circle create mode 120000 cursors/Oxygen_Black/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/Oxygen_Black/cursors/dnd-copy create mode 120000 cursors/Oxygen_Black/cursors/dnd-link create mode 120000 cursors/Oxygen_Black/cursors/dnd-move create mode 120000 cursors/Oxygen_Black/cursors/dnd-no-drop create mode 120000 cursors/Oxygen_Black/cursors/dnd-none create mode 120000 cursors/Oxygen_Black/cursors/e-resize create mode 120000 cursors/Oxygen_Black/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/Oxygen_Black/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/Oxygen_Black/cursors/fleur create mode 100644 cursors/Oxygen_Black/cursors/forbidden create mode 100644 cursors/Oxygen_Black/cursors/half-busy create mode 120000 cursors/Oxygen_Black/cursors/hand1 create mode 120000 cursors/Oxygen_Black/cursors/hand2 create mode 100644 cursors/Oxygen_Black/cursors/help create mode 120000 cursors/Oxygen_Black/cursors/ibeam create mode 100644 cursors/Oxygen_Black/cursors/left_ptr create mode 120000 cursors/Oxygen_Black/cursors/left_ptr_watch create mode 100644 cursors/Oxygen_Black/cursors/link create mode 120000 cursors/Oxygen_Black/cursors/move create mode 120000 cursors/Oxygen_Black/cursors/n-resize create mode 120000 cursors/Oxygen_Black/cursors/not-allowed create mode 100644 cursors/Oxygen_Black/cursors/openhand create mode 100644 cursors/Oxygen_Black/cursors/pencil create mode 100644 cursors/Oxygen_Black/cursors/pirate create mode 100644 cursors/Oxygen_Black/cursors/plus create mode 120000 cursors/Oxygen_Black/cursors/pointer create mode 100644 cursors/Oxygen_Black/cursors/pointing_hand create mode 120000 cursors/Oxygen_Black/cursors/progress create mode 120000 cursors/Oxygen_Black/cursors/question_arrow create mode 120000 cursors/Oxygen_Black/cursors/row-resize create mode 120000 cursors/Oxygen_Black/cursors/s-resize create mode 120000 cursors/Oxygen_Black/cursors/sb_h_double_arrow create mode 120000 cursors/Oxygen_Black/cursors/sb_v_double_arrow create mode 120000 cursors/Oxygen_Black/cursors/size_all create mode 100644 cursors/Oxygen_Black/cursors/size_bdiag create mode 100644 cursors/Oxygen_Black/cursors/size_fdiag create mode 100644 cursors/Oxygen_Black/cursors/size_hor create mode 100644 cursors/Oxygen_Black/cursors/size_ver create mode 100644 cursors/Oxygen_Black/cursors/split_h create mode 100644 cursors/Oxygen_Black/cursors/split_v create mode 120000 cursors/Oxygen_Black/cursors/text create mode 100644 cursors/Oxygen_Black/cursors/up_arrow create mode 120000 cursors/Oxygen_Black/cursors/v_double_arrow create mode 120000 cursors/Oxygen_Black/cursors/w-resize create mode 100644 cursors/Oxygen_Black/cursors/wait create mode 120000 cursors/Oxygen_Black/cursors/watch create mode 120000 cursors/Oxygen_Black/cursors/whats_this create mode 100644 cursors/Oxygen_Black/cursors/xterm create mode 100644 cursors/Oxygen_Black/index.theme create mode 120000 cursors/Oxygen_Blue/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/Oxygen_Blue/cursors/00008160000006810000408080010102 create mode 120000 cursors/Oxygen_Blue/cursors/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/Oxygen_Blue/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/Oxygen_Blue/cursors/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/Oxygen_Blue/cursors/3085a0e285430894940527032f8b26df create mode 120000 cursors/Oxygen_Blue/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/Oxygen_Blue/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/Oxygen_Blue/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/Oxygen_Blue/cursors/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/Oxygen_Blue/cursors/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/Oxygen_Blue/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/Oxygen_Blue/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/Oxygen_Blue/cursors/X_cursor create mode 120000 cursors/Oxygen_Blue/cursors/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/Oxygen_Blue/cursors/alias create mode 120000 cursors/Oxygen_Blue/cursors/all-scroll create mode 120000 cursors/Oxygen_Blue/cursors/b66166c04f8c3109214a4fbd64a50fc8 create mode 100644 cursors/Oxygen_Blue/cursors/circle create mode 100644 cursors/Oxygen_Blue/cursors/closedhand create mode 120000 cursors/Oxygen_Blue/cursors/col-resize create mode 100644 cursors/Oxygen_Blue/cursors/color-picker create mode 100644 cursors/Oxygen_Blue/cursors/copy create mode 100644 cursors/Oxygen_Blue/cursors/cross create mode 120000 cursors/Oxygen_Blue/cursors/crossed_circle create mode 120000 cursors/Oxygen_Blue/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/Oxygen_Blue/cursors/dnd-copy create mode 120000 cursors/Oxygen_Blue/cursors/dnd-link create mode 120000 cursors/Oxygen_Blue/cursors/dnd-move create mode 120000 cursors/Oxygen_Blue/cursors/dnd-no-drop create mode 120000 cursors/Oxygen_Blue/cursors/dnd-none create mode 120000 cursors/Oxygen_Blue/cursors/e-resize create mode 120000 cursors/Oxygen_Blue/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/Oxygen_Blue/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/Oxygen_Blue/cursors/fleur create mode 100644 cursors/Oxygen_Blue/cursors/forbidden create mode 100644 cursors/Oxygen_Blue/cursors/half-busy create mode 120000 cursors/Oxygen_Blue/cursors/hand1 create mode 120000 cursors/Oxygen_Blue/cursors/hand2 create mode 100644 cursors/Oxygen_Blue/cursors/help create mode 120000 cursors/Oxygen_Blue/cursors/ibeam create mode 100644 cursors/Oxygen_Blue/cursors/left_ptr create mode 120000 cursors/Oxygen_Blue/cursors/left_ptr_watch create mode 100644 cursors/Oxygen_Blue/cursors/link create mode 120000 cursors/Oxygen_Blue/cursors/move create mode 120000 cursors/Oxygen_Blue/cursors/n-resize create mode 120000 cursors/Oxygen_Blue/cursors/not-allowed create mode 100644 cursors/Oxygen_Blue/cursors/openhand create mode 100644 cursors/Oxygen_Blue/cursors/pencil create mode 100644 cursors/Oxygen_Blue/cursors/pirate create mode 100644 cursors/Oxygen_Blue/cursors/plus create mode 120000 cursors/Oxygen_Blue/cursors/pointer create mode 100644 cursors/Oxygen_Blue/cursors/pointing_hand create mode 120000 cursors/Oxygen_Blue/cursors/progress create mode 120000 cursors/Oxygen_Blue/cursors/question_arrow create mode 120000 cursors/Oxygen_Blue/cursors/row-resize create mode 120000 cursors/Oxygen_Blue/cursors/s-resize create mode 120000 cursors/Oxygen_Blue/cursors/sb_h_double_arrow create mode 120000 cursors/Oxygen_Blue/cursors/sb_v_double_arrow create mode 120000 cursors/Oxygen_Blue/cursors/size_all create mode 100644 cursors/Oxygen_Blue/cursors/size_bdiag create mode 100644 cursors/Oxygen_Blue/cursors/size_fdiag create mode 100644 cursors/Oxygen_Blue/cursors/size_hor create mode 100644 cursors/Oxygen_Blue/cursors/size_ver create mode 100644 cursors/Oxygen_Blue/cursors/split_h create mode 100644 cursors/Oxygen_Blue/cursors/split_v create mode 120000 cursors/Oxygen_Blue/cursors/text create mode 100644 cursors/Oxygen_Blue/cursors/up_arrow create mode 120000 cursors/Oxygen_Blue/cursors/v_double_arrow create mode 120000 cursors/Oxygen_Blue/cursors/w-resize create mode 100644 cursors/Oxygen_Blue/cursors/wait create mode 120000 cursors/Oxygen_Blue/cursors/watch create mode 120000 cursors/Oxygen_Blue/cursors/whats_this create mode 100644 cursors/Oxygen_Blue/cursors/xterm create mode 100644 cursors/Oxygen_Blue/index.theme create mode 120000 cursors/Oxygen_White/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/Oxygen_White/cursors/00008160000006810000408080010102 create mode 120000 cursors/Oxygen_White/cursors/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/Oxygen_White/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/Oxygen_White/cursors/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/Oxygen_White/cursors/3085a0e285430894940527032f8b26df create mode 120000 cursors/Oxygen_White/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/Oxygen_White/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/Oxygen_White/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/Oxygen_White/cursors/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/Oxygen_White/cursors/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/Oxygen_White/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/Oxygen_White/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/Oxygen_White/cursors/X_cursor create mode 120000 cursors/Oxygen_White/cursors/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/Oxygen_White/cursors/alias create mode 120000 cursors/Oxygen_White/cursors/all-scroll create mode 120000 cursors/Oxygen_White/cursors/b66166c04f8c3109214a4fbd64a50fc8 create mode 100644 cursors/Oxygen_White/cursors/circle create mode 100644 cursors/Oxygen_White/cursors/closedhand create mode 120000 cursors/Oxygen_White/cursors/col-resize create mode 100644 cursors/Oxygen_White/cursors/color-picker create mode 100644 cursors/Oxygen_White/cursors/copy create mode 100644 cursors/Oxygen_White/cursors/cross create mode 120000 cursors/Oxygen_White/cursors/crossed_circle create mode 120000 cursors/Oxygen_White/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/Oxygen_White/cursors/dnd-copy create mode 120000 cursors/Oxygen_White/cursors/dnd-link create mode 120000 cursors/Oxygen_White/cursors/dnd-move create mode 120000 cursors/Oxygen_White/cursors/dnd-no-drop create mode 120000 cursors/Oxygen_White/cursors/dnd-none create mode 120000 cursors/Oxygen_White/cursors/e-resize create mode 120000 cursors/Oxygen_White/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/Oxygen_White/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/Oxygen_White/cursors/fleur create mode 100644 cursors/Oxygen_White/cursors/forbidden create mode 100644 cursors/Oxygen_White/cursors/half-busy create mode 120000 cursors/Oxygen_White/cursors/hand1 create mode 120000 cursors/Oxygen_White/cursors/hand2 create mode 100644 cursors/Oxygen_White/cursors/help create mode 120000 cursors/Oxygen_White/cursors/ibeam create mode 100644 cursors/Oxygen_White/cursors/left_ptr create mode 120000 cursors/Oxygen_White/cursors/left_ptr_watch create mode 100644 cursors/Oxygen_White/cursors/link create mode 120000 cursors/Oxygen_White/cursors/move create mode 120000 cursors/Oxygen_White/cursors/n-resize create mode 120000 cursors/Oxygen_White/cursors/not-allowed create mode 100644 cursors/Oxygen_White/cursors/openhand create mode 100644 cursors/Oxygen_White/cursors/pencil create mode 100644 cursors/Oxygen_White/cursors/pirate create mode 100644 cursors/Oxygen_White/cursors/plus create mode 120000 cursors/Oxygen_White/cursors/pointer create mode 100644 cursors/Oxygen_White/cursors/pointing_hand create mode 120000 cursors/Oxygen_White/cursors/progress create mode 120000 cursors/Oxygen_White/cursors/question_arrow create mode 120000 cursors/Oxygen_White/cursors/row-resize create mode 120000 cursors/Oxygen_White/cursors/s-resize create mode 120000 cursors/Oxygen_White/cursors/sb_h_double_arrow create mode 120000 cursors/Oxygen_White/cursors/sb_v_double_arrow create mode 120000 cursors/Oxygen_White/cursors/size_all create mode 100644 cursors/Oxygen_White/cursors/size_bdiag create mode 100644 cursors/Oxygen_White/cursors/size_fdiag create mode 100644 cursors/Oxygen_White/cursors/size_hor create mode 100644 cursors/Oxygen_White/cursors/size_ver create mode 100644 cursors/Oxygen_White/cursors/split_h create mode 100644 cursors/Oxygen_White/cursors/split_v create mode 120000 cursors/Oxygen_White/cursors/text create mode 100644 cursors/Oxygen_White/cursors/up_arrow create mode 120000 cursors/Oxygen_White/cursors/v_double_arrow create mode 120000 cursors/Oxygen_White/cursors/w-resize create mode 100644 cursors/Oxygen_White/cursors/wait create mode 120000 cursors/Oxygen_White/cursors/watch create mode 120000 cursors/Oxygen_White/cursors/whats_this create mode 100644 cursors/Oxygen_White/cursors/xterm create mode 100644 cursors/Oxygen_White/index.theme create mode 120000 cursors/Oxygen_Yellow/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/Oxygen_Yellow/cursors/00008160000006810000408080010102 create mode 120000 cursors/Oxygen_Yellow/cursors/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/Oxygen_Yellow/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/Oxygen_Yellow/cursors/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/Oxygen_Yellow/cursors/3085a0e285430894940527032f8b26df create mode 120000 cursors/Oxygen_Yellow/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/Oxygen_Yellow/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/Oxygen_Yellow/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/Oxygen_Yellow/cursors/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/Oxygen_Yellow/cursors/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/Oxygen_Yellow/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/Oxygen_Yellow/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/Oxygen_Yellow/cursors/X_cursor create mode 120000 cursors/Oxygen_Yellow/cursors/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/Oxygen_Yellow/cursors/alias create mode 120000 cursors/Oxygen_Yellow/cursors/all-scroll create mode 120000 cursors/Oxygen_Yellow/cursors/b66166c04f8c3109214a4fbd64a50fc8 create mode 100644 cursors/Oxygen_Yellow/cursors/circle create mode 100644 cursors/Oxygen_Yellow/cursors/closedhand create mode 120000 cursors/Oxygen_Yellow/cursors/col-resize create mode 100644 cursors/Oxygen_Yellow/cursors/color-picker create mode 100644 cursors/Oxygen_Yellow/cursors/copy create mode 100644 cursors/Oxygen_Yellow/cursors/cross create mode 120000 cursors/Oxygen_Yellow/cursors/crossed_circle create mode 120000 cursors/Oxygen_Yellow/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/Oxygen_Yellow/cursors/dnd-copy create mode 120000 cursors/Oxygen_Yellow/cursors/dnd-link create mode 120000 cursors/Oxygen_Yellow/cursors/dnd-move create mode 120000 cursors/Oxygen_Yellow/cursors/dnd-no-drop create mode 120000 cursors/Oxygen_Yellow/cursors/dnd-none create mode 120000 cursors/Oxygen_Yellow/cursors/e-resize create mode 120000 cursors/Oxygen_Yellow/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/Oxygen_Yellow/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/Oxygen_Yellow/cursors/fleur create mode 100644 cursors/Oxygen_Yellow/cursors/forbidden create mode 100644 cursors/Oxygen_Yellow/cursors/half-busy create mode 120000 cursors/Oxygen_Yellow/cursors/hand1 create mode 120000 cursors/Oxygen_Yellow/cursors/hand2 create mode 100644 cursors/Oxygen_Yellow/cursors/help create mode 120000 cursors/Oxygen_Yellow/cursors/ibeam create mode 100644 cursors/Oxygen_Yellow/cursors/left_ptr create mode 120000 cursors/Oxygen_Yellow/cursors/left_ptr_watch create mode 100644 cursors/Oxygen_Yellow/cursors/link create mode 120000 cursors/Oxygen_Yellow/cursors/move create mode 120000 cursors/Oxygen_Yellow/cursors/n-resize create mode 120000 cursors/Oxygen_Yellow/cursors/not-allowed create mode 100644 cursors/Oxygen_Yellow/cursors/openhand create mode 100644 cursors/Oxygen_Yellow/cursors/pencil create mode 100644 cursors/Oxygen_Yellow/cursors/pirate create mode 100644 cursors/Oxygen_Yellow/cursors/plus create mode 120000 cursors/Oxygen_Yellow/cursors/pointer create mode 100644 cursors/Oxygen_Yellow/cursors/pointing_hand create mode 120000 cursors/Oxygen_Yellow/cursors/progress create mode 120000 cursors/Oxygen_Yellow/cursors/question_arrow create mode 120000 cursors/Oxygen_Yellow/cursors/row-resize create mode 120000 cursors/Oxygen_Yellow/cursors/s-resize create mode 120000 cursors/Oxygen_Yellow/cursors/sb_h_double_arrow create mode 120000 cursors/Oxygen_Yellow/cursors/sb_v_double_arrow create mode 120000 cursors/Oxygen_Yellow/cursors/size_all create mode 100644 cursors/Oxygen_Yellow/cursors/size_bdiag create mode 100644 cursors/Oxygen_Yellow/cursors/size_fdiag create mode 100644 cursors/Oxygen_Yellow/cursors/size_hor create mode 100644 cursors/Oxygen_Yellow/cursors/size_ver create mode 100644 cursors/Oxygen_Yellow/cursors/split_h create mode 100644 cursors/Oxygen_Yellow/cursors/split_v create mode 120000 cursors/Oxygen_Yellow/cursors/text create mode 100644 cursors/Oxygen_Yellow/cursors/up_arrow create mode 120000 cursors/Oxygen_Yellow/cursors/v_double_arrow create mode 120000 cursors/Oxygen_Yellow/cursors/w-resize create mode 100644 cursors/Oxygen_Yellow/cursors/wait create mode 120000 cursors/Oxygen_Yellow/cursors/watch create mode 120000 cursors/Oxygen_Yellow/cursors/whats_this create mode 100644 cursors/Oxygen_Yellow/cursors/xterm create mode 100644 cursors/Oxygen_Yellow/index.theme create mode 120000 cursors/Oxygen_Zion/cursors/00000000000000020006000e7e9ffc3f create mode 120000 cursors/Oxygen_Zion/cursors/00008160000006810000408080010102 create mode 120000 cursors/Oxygen_Zion/cursors/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/Oxygen_Zion/cursors/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/Oxygen_Zion/cursors/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/Oxygen_Zion/cursors/3085a0e285430894940527032f8b26df create mode 120000 cursors/Oxygen_Zion/cursors/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/Oxygen_Zion/cursors/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/Oxygen_Zion/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/Oxygen_Zion/cursors/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/Oxygen_Zion/cursors/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/Oxygen_Zion/cursors/9081237383d90e509aa00f00170e968f create mode 120000 cursors/Oxygen_Zion/cursors/9d800788f1b08800ae810202380a0822 create mode 100644 cursors/Oxygen_Zion/cursors/X_cursor create mode 120000 cursors/Oxygen_Zion/cursors/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/Oxygen_Zion/cursors/alias create mode 120000 cursors/Oxygen_Zion/cursors/all-scroll create mode 120000 cursors/Oxygen_Zion/cursors/b66166c04f8c3109214a4fbd64a50fc8 create mode 100644 cursors/Oxygen_Zion/cursors/circle create mode 100644 cursors/Oxygen_Zion/cursors/closedhand create mode 120000 cursors/Oxygen_Zion/cursors/col-resize create mode 100644 cursors/Oxygen_Zion/cursors/color-picker create mode 100644 cursors/Oxygen_Zion/cursors/copy create mode 100644 cursors/Oxygen_Zion/cursors/cross create mode 120000 cursors/Oxygen_Zion/cursors/crossed_circle create mode 120000 cursors/Oxygen_Zion/cursors/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/Oxygen_Zion/cursors/dnd-copy create mode 120000 cursors/Oxygen_Zion/cursors/dnd-link create mode 120000 cursors/Oxygen_Zion/cursors/dnd-move create mode 120000 cursors/Oxygen_Zion/cursors/dnd-no-drop create mode 120000 cursors/Oxygen_Zion/cursors/dnd-none create mode 120000 cursors/Oxygen_Zion/cursors/e-resize create mode 120000 cursors/Oxygen_Zion/cursors/e29285e634086352946a0e7090d73106 create mode 120000 cursors/Oxygen_Zion/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 100644 cursors/Oxygen_Zion/cursors/fleur create mode 100644 cursors/Oxygen_Zion/cursors/forbidden create mode 100644 cursors/Oxygen_Zion/cursors/half-busy create mode 120000 cursors/Oxygen_Zion/cursors/hand1 create mode 120000 cursors/Oxygen_Zion/cursors/hand2 create mode 100644 cursors/Oxygen_Zion/cursors/help create mode 120000 cursors/Oxygen_Zion/cursors/ibeam create mode 100644 cursors/Oxygen_Zion/cursors/left_ptr create mode 120000 cursors/Oxygen_Zion/cursors/left_ptr_watch create mode 100644 cursors/Oxygen_Zion/cursors/link create mode 120000 cursors/Oxygen_Zion/cursors/move create mode 120000 cursors/Oxygen_Zion/cursors/n-resize create mode 120000 cursors/Oxygen_Zion/cursors/not-allowed create mode 100644 cursors/Oxygen_Zion/cursors/openhand create mode 100644 cursors/Oxygen_Zion/cursors/pencil create mode 100644 cursors/Oxygen_Zion/cursors/pirate create mode 100644 cursors/Oxygen_Zion/cursors/plus create mode 120000 cursors/Oxygen_Zion/cursors/pointer create mode 100644 cursors/Oxygen_Zion/cursors/pointing_hand create mode 120000 cursors/Oxygen_Zion/cursors/progress create mode 120000 cursors/Oxygen_Zion/cursors/question_arrow create mode 120000 cursors/Oxygen_Zion/cursors/row-resize create mode 120000 cursors/Oxygen_Zion/cursors/s-resize create mode 120000 cursors/Oxygen_Zion/cursors/sb_h_double_arrow create mode 120000 cursors/Oxygen_Zion/cursors/sb_v_double_arrow create mode 120000 cursors/Oxygen_Zion/cursors/size_all create mode 100644 cursors/Oxygen_Zion/cursors/size_bdiag create mode 100644 cursors/Oxygen_Zion/cursors/size_fdiag create mode 100644 cursors/Oxygen_Zion/cursors/size_hor create mode 100644 cursors/Oxygen_Zion/cursors/size_ver create mode 100644 cursors/Oxygen_Zion/cursors/split_h create mode 100644 cursors/Oxygen_Zion/cursors/split_v create mode 120000 cursors/Oxygen_Zion/cursors/text create mode 100644 cursors/Oxygen_Zion/cursors/up_arrow create mode 120000 cursors/Oxygen_Zion/cursors/v_double_arrow create mode 120000 cursors/Oxygen_Zion/cursors/w-resize create mode 100644 cursors/Oxygen_Zion/cursors/wait create mode 120000 cursors/Oxygen_Zion/cursors/watch create mode 120000 cursors/Oxygen_Zion/cursors/whats_this create mode 100644 cursors/Oxygen_Zion/cursors/xterm create mode 100644 cursors/Oxygen_Zion/index.theme create mode 100644 cursors/src/CMakeLists.txt create mode 100644 cursors/src/COPYING create mode 100644 cursors/src/LICENSE create mode 100644 cursors/src/README create mode 100644 cursors/src/TODO create mode 100644 cursors/src/config.cmake create mode 100644 cursors/src/config/Description create mode 100644 cursors/src/config/X_cursor.in create mode 100644 cursors/src/config/circle.in create mode 100644 cursors/src/config/closedhand.in create mode 100644 cursors/src/config/color-picker.in create mode 100644 cursors/src/config/copy.in create mode 100644 cursors/src/config/cross.in create mode 100644 cursors/src/config/fleur.in create mode 100644 cursors/src/config/forbidden.in create mode 100644 cursors/src/config/half-busy.in create mode 100644 cursors/src/config/help.in create mode 100644 cursors/src/config/left_ptr.in create mode 100644 cursors/src/config/link.in create mode 100644 cursors/src/config/openhand.in create mode 100644 cursors/src/config/pencil.in create mode 100644 cursors/src/config/pirate.in create mode 100644 cursors/src/config/plus.in create mode 100644 cursors/src/config/pointing_hand.in create mode 100644 cursors/src/config/size_bdiag.in create mode 100644 cursors/src/config/size_fdiag.in create mode 100644 cursors/src/config/size_hor.in create mode 100644 cursors/src/config/size_ver.in create mode 100644 cursors/src/config/split_h.in create mode 100644 cursors/src/config/split_v.in create mode 100644 cursors/src/config/up_arrow.in create mode 100644 cursors/src/config/wait.in create mode 100644 cursors/src/config/xterm.in create mode 100644 cursors/src/cursors.cmake create mode 100644 cursors/src/make_config.cmake create mode 100644 cursors/src/make_svg.cmake create mode 100644 cursors/src/setup.cmake create mode 100644 cursors/src/svg/busy.svg create mode 100644 cursors/src/svg/busy1.svg create mode 100644 cursors/src/svg/busy10.svg create mode 100644 cursors/src/svg/busy11.svg create mode 100644 cursors/src/svg/busy12.svg create mode 100644 cursors/src/svg/busy13.svg create mode 100644 cursors/src/svg/busy14.svg create mode 100644 cursors/src/svg/busy15.svg create mode 100644 cursors/src/svg/busy16.svg create mode 100644 cursors/src/svg/busy17.svg create mode 100644 cursors/src/svg/busy2.svg create mode 100644 cursors/src/svg/busy3.svg create mode 100644 cursors/src/svg/busy4.svg create mode 100644 cursors/src/svg/busy5.svg create mode 100644 cursors/src/svg/busy6.svg create mode 100644 cursors/src/svg/busy7.svg create mode 100644 cursors/src/svg/busy8.svg create mode 100644 cursors/src/svg/busy9.svg create mode 100644 cursors/src/svg/circle.svg create mode 100644 cursors/src/svg/copy.svg create mode 100644 cursors/src/svg/cross.svg create mode 100644 cursors/src/svg/dnd-move.svg create mode 100644 cursors/src/svg/fleur.svg create mode 100644 cursors/src/svg/forbidden.svg create mode 100644 cursors/src/svg/grab.svg create mode 100644 cursors/src/svg/grab_open.svg create mode 100644 cursors/src/svg/half-busy.svg create mode 100644 cursors/src/svg/half-busy1.svg create mode 100644 cursors/src/svg/half-busy10.svg create mode 100644 cursors/src/svg/half-busy11.svg create mode 100644 cursors/src/svg/half-busy12.svg create mode 100644 cursors/src/svg/half-busy13.svg create mode 100644 cursors/src/svg/half-busy14.svg create mode 100644 cursors/src/svg/half-busy15.svg create mode 100644 cursors/src/svg/half-busy16.svg create mode 100644 cursors/src/svg/half-busy17.svg create mode 100644 cursors/src/svg/half-busy2.svg create mode 100644 cursors/src/svg/half-busy3.svg create mode 100644 cursors/src/svg/half-busy4.svg create mode 100644 cursors/src/svg/half-busy5.svg create mode 100644 cursors/src/svg/half-busy6.svg create mode 100644 cursors/src/svg/half-busy7.svg create mode 100644 cursors/src/svg/half-busy8.svg create mode 100644 cursors/src/svg/half-busy9.svg create mode 100644 cursors/src/svg/hand.svg create mode 100644 cursors/src/svg/help.svg create mode 100644 cursors/src/svg/kill.svg create mode 100644 cursors/src/svg/left_ptr.svg create mode 100644 cursors/src/svg/link.svg create mode 100644 cursors/src/svg/pencil.svg create mode 100644 cursors/src/svg/picker.svg create mode 100644 cursors/src/svg/plus.svg create mode 100644 cursors/src/svg/size_diag-tl2br.svg create mode 100644 cursors/src/svg/size_diag-tr2bl.svg create mode 100644 cursors/src/svg/size_hor.svg create mode 100644 cursors/src/svg/size_ver.svg create mode 100644 cursors/src/svg/split_h.svg create mode 100644 cursors/src/svg/split_v.svg create mode 100644 cursors/src/svg/up_arrow.svg create mode 100644 cursors/src/svg/x.svg create mode 100644 cursors/src/svg/xterm.svg create mode 100644 cursors/src/symlinks/.directory create mode 120000 cursors/src/symlinks/00000000000000020006000e7e9ffc3f create mode 120000 cursors/src/symlinks/00008160000006810000408080010102 create mode 120000 cursors/src/symlinks/03b6e0fcb3499374a867c041f52298f0 create mode 120000 cursors/src/symlinks/08e8e1c95fe2fc01f976f1e063a24ccd create mode 120000 cursors/src/symlinks/1081e37283d90000800003c07f3ef6bf create mode 120000 cursors/src/symlinks/3085a0e285430894940527032f8b26df create mode 120000 cursors/src/symlinks/3ecb610c1bf2410f44200f48c40d3599 create mode 120000 cursors/src/symlinks/4498f0e0c1937ffe01fd06f973665830 create mode 120000 cursors/src/symlinks/5c6cd98b3f3ebcb1f9c7f1c204630408 create mode 120000 cursors/src/symlinks/6407b0e94181790501fd1e167b474872 create mode 120000 cursors/src/symlinks/640fb0e74195791501fd1ed57b41487f create mode 120000 cursors/src/symlinks/9081237383d90e509aa00f00170e968f create mode 120000 cursors/src/symlinks/9d800788f1b08800ae810202380a0822 create mode 120000 cursors/src/symlinks/a2a266d0498c3104214a47bd64ab0fc8 create mode 120000 cursors/src/symlinks/alias create mode 120000 cursors/src/symlinks/all-scroll create mode 120000 cursors/src/symlinks/b66166c04f8c3109214a4fbd64a50fc8 create mode 120000 cursors/src/symlinks/col-resize create mode 120000 cursors/src/symlinks/crossed_circle create mode 120000 cursors/src/symlinks/d9ce0ab605698f320427677b458ad60b create mode 120000 cursors/src/symlinks/dnd-copy create mode 120000 cursors/src/symlinks/dnd-link create mode 120000 cursors/src/symlinks/dnd-move create mode 120000 cursors/src/symlinks/dnd-no-drop create mode 120000 cursors/src/symlinks/dnd-none create mode 120000 cursors/src/symlinks/e-resize create mode 120000 cursors/src/symlinks/e29285e634086352946a0e7090d73106 create mode 120000 cursors/src/symlinks/fcf21c00b30f7e3f83fe0dfd12e71cff create mode 120000 cursors/src/symlinks/hand1 create mode 120000 cursors/src/symlinks/hand2 create mode 120000 cursors/src/symlinks/ibeam create mode 120000 cursors/src/symlinks/left_ptr_watch create mode 120000 cursors/src/symlinks/move create mode 120000 cursors/src/symlinks/n-resize create mode 120000 cursors/src/symlinks/not-allowed create mode 120000 cursors/src/symlinks/pointer create mode 120000 cursors/src/symlinks/progress create mode 120000 cursors/src/symlinks/question_arrow create mode 120000 cursors/src/symlinks/row-resize create mode 120000 cursors/src/symlinks/s-resize create mode 120000 cursors/src/symlinks/sb_h_double_arrow create mode 120000 cursors/src/symlinks/sb_v_double_arrow create mode 120000 cursors/src/symlinks/size_all create mode 120000 cursors/src/symlinks/text create mode 120000 cursors/src/symlinks/v_double_arrow create mode 120000 cursors/src/symlinks/w-resize create mode 120000 cursors/src/symlinks/watch create mode 120000 cursors/src/symlinks/whats_this create mode 100644 cursors/src/theme-black/CMakeLists.txt create mode 100644 cursors/src/theme-black/colors.in create mode 100644 cursors/src/theme-black/index.theme create mode 100644 cursors/src/theme-blue/CMakeLists.txt create mode 100644 cursors/src/theme-blue/colors.in create mode 100644 cursors/src/theme-blue/index.theme create mode 100644 cursors/src/theme-bluecurve/CMakeLists.txt create mode 100644 cursors/src/theme-bluecurve/colors.in create mode 100644 cursors/src/theme-bluecurve/index.theme create mode 100644 cursors/src/theme-brown/CMakeLists.txt create mode 100644 cursors/src/theme-brown/colors.in create mode 100644 cursors/src/theme-brown/index.theme create mode 100644 cursors/src/theme-cherry/CMakeLists.txt create mode 100644 cursors/src/theme-cherry/colors.in create mode 100644 cursors/src/theme-cherry/index.theme create mode 100644 cursors/src/theme-chrome/CMakeLists.txt create mode 100644 cursors/src/theme-chrome/colors.in create mode 100644 cursors/src/theme-chrome/index.theme create mode 100644 cursors/src/theme-desert/CMakeLists.txt create mode 100644 cursors/src/theme-desert/colors.in create mode 100644 cursors/src/theme-desert/index.theme create mode 100644 cursors/src/theme-emerald/CMakeLists.txt create mode 100644 cursors/src/theme-emerald/colors.in create mode 100644 cursors/src/theme-emerald/index.theme create mode 100644 cursors/src/theme-green/CMakeLists.txt create mode 100644 cursors/src/theme-green/colors.in create mode 100644 cursors/src/theme-green/index.theme create mode 100644 cursors/src/theme-grey/CMakeLists.txt create mode 100644 cursors/src/theme-grey/colors.in create mode 100644 cursors/src/theme-grey/index.theme create mode 100644 cursors/src/theme-honeycomb/CMakeLists.txt create mode 100644 cursors/src/theme-honeycomb/colors.in create mode 100644 cursors/src/theme-honeycomb/index.theme create mode 100644 cursors/src/theme-hot_orange/CMakeLists.txt create mode 100644 cursors/src/theme-hot_orange/colors.in create mode 100644 cursors/src/theme-hot_orange/index.theme create mode 100644 cursors/src/theme-lilac/CMakeLists.txt create mode 100644 cursors/src/theme-lilac/colors.in create mode 100644 cursors/src/theme-lilac/index.theme create mode 100644 cursors/src/theme-midnight_meadow/CMakeLists.txt create mode 100644 cursors/src/theme-midnight_meadow/colors.in create mode 100644 cursors/src/theme-midnight_meadow/index.theme create mode 100644 cursors/src/theme-navy/CMakeLists.txt create mode 100644 cursors/src/theme-navy/colors.in create mode 100644 cursors/src/theme-navy/index.theme create mode 100644 cursors/src/theme-norway/CMakeLists.txt create mode 100644 cursors/src/theme-norway/colors.in create mode 100644 cursors/src/theme-norway/index.theme create mode 100644 cursors/src/theme-obsidian-hc/CMakeLists.txt create mode 100644 cursors/src/theme-obsidian-hc/colors.in create mode 100644 cursors/src/theme-obsidian-hc/index.theme create mode 100644 cursors/src/theme-obsidian/CMakeLists.txt create mode 100644 cursors/src/theme-obsidian/colors.in create mode 100644 cursors/src/theme-obsidian/index.theme create mode 100644 cursors/src/theme-olympus-inv/CMakeLists.txt create mode 100644 cursors/src/theme-olympus-inv/colors.in create mode 100644 cursors/src/theme-olympus-inv/index.theme create mode 100644 cursors/src/theme-olympus/CMakeLists.txt create mode 100644 cursors/src/theme-olympus/colors.in create mode 100644 cursors/src/theme-olympus/index.theme create mode 100644 cursors/src/theme-orchid/CMakeLists.txt create mode 100644 cursors/src/theme-orchid/colors.in create mode 100644 cursors/src/theme-orchid/index.theme create mode 100644 cursors/src/theme-oxygen/CMakeLists.txt create mode 100644 cursors/src/theme-oxygen/colors.in create mode 100644 cursors/src/theme-oxygen/index.theme create mode 100644 cursors/src/theme-peach/CMakeLists.txt create mode 100644 cursors/src/theme-peach/colors.in create mode 100644 cursors/src/theme-peach/index.theme create mode 100644 cursors/src/theme-purple/CMakeLists.txt create mode 100644 cursors/src/theme-purple/colors.in create mode 100644 cursors/src/theme-purple/index.theme create mode 100644 cursors/src/theme-red-argentina/CMakeLists.txt create mode 100644 cursors/src/theme-red-argentina/colors.in create mode 100644 cursors/src/theme-red-argentina/index.theme create mode 100644 cursors/src/theme-red/CMakeLists.txt create mode 100644 cursors/src/theme-red/colors.in create mode 100644 cursors/src/theme-red/index.theme create mode 100644 cursors/src/theme-sea_blue/CMakeLists.txt create mode 100644 cursors/src/theme-sea_blue/colors.in create mode 100644 cursors/src/theme-sea_blue/index.theme create mode 100644 cursors/src/theme-steel/CMakeLists.txt create mode 100644 cursors/src/theme-steel/colors.in create mode 100644 cursors/src/theme-steel/index.theme create mode 100644 cursors/src/theme-terra/CMakeLists.txt create mode 100644 cursors/src/theme-terra/colors.in create mode 100644 cursors/src/theme-terra/index.theme create mode 100644 cursors/src/theme-terra_green/CMakeLists.txt create mode 100644 cursors/src/theme-terra_green/colors.in create mode 100644 cursors/src/theme-terra_green/index.theme create mode 100644 cursors/src/theme-violet/CMakeLists.txt create mode 100644 cursors/src/theme-violet/colors.in create mode 100644 cursors/src/theme-violet/index.theme create mode 100644 cursors/src/theme-viorange/CMakeLists.txt create mode 100644 cursors/src/theme-viorange/colors.in create mode 100644 cursors/src/theme-viorange/index.theme create mode 100644 cursors/src/theme-white/CMakeLists.txt create mode 100644 cursors/src/theme-white/colors.in create mode 100644 cursors/src/theme-white/index.theme create mode 100644 cursors/src/theme-whitewater/CMakeLists.txt create mode 100644 cursors/src/theme-whitewater/colors.in create mode 100644 cursors/src/theme-whitewater/index.theme create mode 100644 cursors/src/theme-wonton/CMakeLists.txt create mode 100644 cursors/src/theme-wonton/colors.in create mode 100644 cursors/src/theme-wonton/index.theme create mode 100644 cursors/src/theme-yellow/CMakeLists.txt create mode 100644 cursors/src/theme-yellow/colors.in create mode 100644 cursors/src/theme-yellow/index.theme create mode 100644 cursors/src/theme-zion/CMakeLists.txt create mode 100644 cursors/src/theme-zion/colors.in create mode 100644 cursors/src/theme-zion/index.theme create mode 100644 cursors/src/theme.cmake create mode 100644 cursors/src/wincursor.py create mode 100644 doc/CMakeLists.txt create mode 100644 doc/PolicyKit-kde/CMakeLists.txt create mode 100644 doc/PolicyKit-kde/authdialog_1.png create mode 100644 doc/PolicyKit-kde/authdialog_2.png create mode 100644 doc/PolicyKit-kde/authdialog_3.png create mode 100644 doc/PolicyKit-kde/authdialog_4.png create mode 100644 doc/PolicyKit-kde/authdialog_5.png create mode 100644 doc/PolicyKit-kde/authdialog_6.png create mode 100644 doc/PolicyKit-kde/authorization.docbook create mode 100644 doc/PolicyKit-kde/authorization_1.png create mode 100644 doc/PolicyKit-kde/authorization_2.png create mode 100644 doc/PolicyKit-kde/authorizationagent.docbook create mode 100644 doc/PolicyKit-kde/howitworks.docbook create mode 100644 doc/PolicyKit-kde/index.docbook create mode 100644 doc/PolicyKit-kde/introduction.docbook create mode 100644 doc/kcontrol/CMakeLists.txt create mode 100644 doc/kcontrol/autostart/CMakeLists.txt create mode 100644 doc/kcontrol/autostart/index.docbook create mode 100644 doc/kcontrol/bell/CMakeLists.txt create mode 100644 doc/kcontrol/bell/index.docbook create mode 100644 doc/kcontrol/clock/CMakeLists.txt create mode 100644 doc/kcontrol/clock/index.docbook create mode 100644 doc/kcontrol/colors/CMakeLists.txt create mode 100644 doc/kcontrol/colors/index.docbook create mode 100644 doc/kcontrol/cursortheme/CMakeLists.txt create mode 100644 doc/kcontrol/cursortheme/index.docbook create mode 100644 doc/kcontrol/desktop/CMakeLists.txt create mode 100644 doc/kcontrol/desktop/index.docbook create mode 100644 doc/kcontrol/desktopthemedetails/CMakeLists.txt create mode 100644 doc/kcontrol/desktopthemedetails/clicking-apply.png create mode 100644 doc/kcontrol/desktopthemedetails/customizing.png create mode 100644 doc/kcontrol/desktopthemedetails/index.docbook create mode 100644 doc/kcontrol/fontinst/CMakeLists.txt create mode 100644 doc/kcontrol/fontinst/index.docbook create mode 100644 doc/kcontrol/fonts/CMakeLists.txt create mode 100644 doc/kcontrol/fonts/adjust-all.png create mode 100644 doc/kcontrol/fonts/anti-aliasing.png create mode 100644 doc/kcontrol/fonts/index.docbook create mode 100644 doc/kcontrol/fonts/main.png create mode 100644 doc/kcontrol/joystick/CMakeLists.txt create mode 100644 doc/kcontrol/joystick/index.docbook create mode 100644 doc/kcontrol/joystick/joystick-calibration.png create mode 100644 doc/kcontrol/joystick/joystick-main.png create mode 100644 doc/kcontrol/kcmaccess/CMakeLists.txt create mode 100644 doc/kcontrol/kcmaccess/index.docbook create mode 100644 doc/kcontrol/kcmsmserver/CMakeLists.txt create mode 100644 doc/kcontrol/kcmsmserver/index.docbook create mode 100644 doc/kcontrol/kcmstyle/CMakeLists.txt create mode 100644 doc/kcontrol/kcmstyle/index.docbook create mode 100644 doc/kcontrol/keyboard/CMakeLists.txt create mode 100644 doc/kcontrol/keyboard/index.docbook create mode 100644 doc/kcontrol/keys/CMakeLists.txt create mode 100644 doc/kcontrol/keys/index.docbook create mode 100644 doc/kcontrol/khotkeys/CMakeLists.txt create mode 100644 doc/kcontrol/khotkeys/groups-comment.png create mode 100644 doc/kcontrol/khotkeys/index.docbook create mode 100644 doc/kcontrol/khotkeys/manage-export.png create mode 100644 doc/kcontrol/khotkeys/oxygen-22x22-edit-clear-locationbar-rtl.png create mode 100644 doc/kcontrol/khotkeys/settings.png create mode 100644 doc/kcontrol/khotkeys/shortcuts-action-command.png create mode 100644 doc/kcontrol/khotkeys/shortcuts-action-keyboard.png create mode 100644 doc/kcontrol/khotkeys/shortcuts-trigger-keyboard.png create mode 100644 doc/kcontrol/khotkeys/shortcuts-trigger-mouse.png create mode 100644 doc/kcontrol/kwincompositing/CMakeLists.txt create mode 100644 doc/kcontrol/kwincompositing/index.docbook create mode 100644 doc/kcontrol/kwindecoration/CMakeLists.txt create mode 100644 doc/kcontrol/kwindecoration/buttons.png create mode 100644 doc/kcontrol/kwindecoration/decoration.png create mode 100644 doc/kcontrol/kwindecoration/index.docbook create mode 100644 doc/kcontrol/kwindecoration/main.png create mode 100644 doc/kcontrol/kwinscreenedges/CMakeLists.txt create mode 100644 doc/kcontrol/kwinscreenedges/index.docbook create mode 100644 doc/kcontrol/kwintabbox/CMakeLists.txt create mode 100644 doc/kcontrol/kwintabbox/index.docbook create mode 100644 doc/kcontrol/mouse/CMakeLists.txt create mode 100644 doc/kcontrol/mouse/index.docbook create mode 100644 doc/kcontrol/paths/CMakeLists.txt create mode 100644 doc/kcontrol/paths/index.docbook create mode 100644 doc/kcontrol/paths/paths.png create mode 100644 doc/kcontrol/powerdevil/CMakeLists.txt create mode 100644 doc/kcontrol/powerdevil/activity.png create mode 100644 doc/kcontrol/powerdevil/advanced.png create mode 100644 doc/kcontrol/powerdevil/energy.png create mode 100644 doc/kcontrol/powerdevil/index.docbook create mode 100644 doc/kcontrol/screensaver/CMakeLists.txt create mode 100644 doc/kcontrol/screensaver/index.docbook create mode 100644 doc/kcontrol/solid-actions/CMakeLists.txt create mode 100644 doc/kcontrol/solid-actions/add-action.png create mode 100644 doc/kcontrol/solid-actions/edit-action.png create mode 100644 doc/kcontrol/solid-actions/index.docbook create mode 100644 doc/kcontrol/solid-actions/main.png create mode 100644 doc/kcontrol/splashscreen/CMakeLists.txt create mode 100644 doc/kcontrol/splashscreen/get-new-theme.png create mode 100644 doc/kcontrol/splashscreen/index.docbook create mode 100644 doc/kcontrol/splashscreen/splash-main.png create mode 100644 doc/kcontrol/windowbehaviour/CMakeLists.txt create mode 100644 doc/kcontrol/windowbehaviour/index.docbook create mode 100644 doc/kcontrol/windowspecific/CMakeLists.txt create mode 100644 doc/kcontrol/windowspecific/Face-smile.png create mode 100644 doc/kcontrol/windowspecific/akgregator-info.png create mode 100644 doc/kcontrol/windowspecific/akregator-attributes.png create mode 100644 doc/kcontrol/windowspecific/akregator-fav.png create mode 100644 doc/kcontrol/windowspecific/config-win-behavior.png create mode 100644 doc/kcontrol/windowspecific/emacs-attribute.png create mode 100644 doc/kcontrol/windowspecific/emacs-info.png create mode 100644 doc/kcontrol/windowspecific/focus-stealing-pop2top-attribute.png create mode 100644 doc/kcontrol/windowspecific/index.docbook create mode 100644 doc/kcontrol/windowspecific/knotes-attribute.png create mode 100644 doc/kcontrol/windowspecific/knotes-info.png create mode 100644 doc/kcontrol/windowspecific/kopete-attribute-2.png create mode 100644 doc/kcontrol/windowspecific/kopete-chat-attribute.png create mode 100644 doc/kcontrol/windowspecific/kopete-chat-info.png create mode 100644 doc/kcontrol/windowspecific/kopete-info.png create mode 100644 doc/kcontrol/windowspecific/kwin-detect-window.png create mode 100644 doc/kcontrol/windowspecific/kwin-kopete-rules.png create mode 100644 doc/kcontrol/windowspecific/kwin-rule-editor.png create mode 100644 doc/kcontrol/windowspecific/kwin-rules-main-n-akregator.png create mode 100644 doc/kcontrol/windowspecific/kwin-rules-main.png create mode 100644 doc/kcontrol/windowspecific/kwin-rules-ordering.png create mode 100644 doc/kcontrol/windowspecific/kwin-window-attributes.png create mode 100644 doc/kcontrol/windowspecific/kwin-window-matching.png create mode 100644 doc/kcontrol/windowspecific/pager-4-desktops.png create mode 100644 doc/kcontrol/windowspecific/tbird-compose-attribute.png create mode 100644 doc/kcontrol/windowspecific/tbird-compose-info.png create mode 100644 doc/kcontrol/windowspecific/tbird-main-attribute.png create mode 100644 doc/kcontrol/windowspecific/tbird-main-info.png create mode 100644 doc/kcontrol/windowspecific/tbird-reminder-attribute-2.png create mode 100644 doc/kcontrol/windowspecific/tbird-reminder-info.png create mode 100644 doc/kcontrol/windowspecific/window-matching-emacs.png create mode 100644 doc/kcontrol/windowspecific/window-matching-init.png create mode 100644 doc/kcontrol/windowspecific/window-matching-knotes.png create mode 100644 doc/kcontrol/windowspecific/window-matching-kopete-chat.png create mode 100644 doc/kcontrol/windowspecific/window-matching-kopete.png create mode 100644 doc/kcontrol/windowspecific/window-matching-ready-akregator.png create mode 100644 doc/kcontrol/windowspecific/window-matching-tbird-compose.png create mode 100644 doc/kcontrol/windowspecific/window-matching-tbird-main.png create mode 100644 doc/kcontrol/windowspecific/window-matching-tbird-reminder.png create mode 100644 doc/kcontrol/workspaceoptions/CMakeLists.txt create mode 100644 doc/kcontrol/workspaceoptions/index.docbook create mode 100644 doc/kdm/CMakeLists.txt create mode 100644 doc/kdm/index.docbook create mode 100644 doc/kdm/kdmrc-ref.docbook create mode 100644 doc/kdm/theme-ref.docbook create mode 100644 doc/kfontview/CMakeLists.txt create mode 100644 doc/kfontview/index.docbook create mode 100644 doc/kfontview/kfontview.png create mode 100644 doc/kinfocenter/CMakeLists.txt create mode 100644 doc/kinfocenter/index.docbook create mode 100644 doc/kinfocenter/kinfocenter.png create mode 100644 doc/kinfocenter/os_block.png create mode 100644 doc/kinfocenter/pro_block.png create mode 100644 doc/kinfocenter/sto_block.png create mode 100644 doc/klipper/CMakeLists.txt create mode 100644 doc/klipper/index.docbook create mode 100644 doc/klipper/screenshot.png create mode 100644 doc/kmenuedit/CMakeLists.txt create mode 100644 doc/kmenuedit/done.png create mode 100644 doc/kmenuedit/index.docbook create mode 100644 doc/kmenuedit/itemname.png create mode 100644 doc/kmenuedit/new.png create mode 100644 doc/kmenuedit/reset.png create mode 100644 doc/kmenuedit/selecticon.png create mode 100644 doc/kmenuedit/selectinternet.png create mode 100644 doc/ksysguard/CMakeLists.txt create mode 100644 doc/ksysguard/index.docbook create mode 100644 doc/plasma-desktop/CMakeLists.txt create mode 100644 doc/plasma-desktop/add-widgets.png create mode 100644 doc/plasma-desktop/desktop-settings.png create mode 100644 doc/plasma-desktop/device_notifier_widget.png create mode 100644 doc/plasma-desktop/device_notifier_widget_actions.png create mode 100644 doc/plasma-desktop/index.docbook create mode 100644 doc/plasma-desktop/panel-settings.png create mode 100644 doc/plasma-desktop/plasma-desktop-annotated.png create mode 100644 doc/plasma-desktop/system-tray-settings.png create mode 100644 doc/plasma-desktop/system-tray-up-arrow.png create mode 100644 doc/plasma-desktop/taskbar-settings.png create mode 100644 doc/systemsettings/CMakeLists.txt create mode 100644 doc/systemsettings/index.docbook create mode 100644 freespacenotifier/CMakeLists.txt create mode 100644 freespacenotifier/COPYING create mode 100644 freespacenotifier/Messages.sh create mode 100644 freespacenotifier/README create mode 100644 freespacenotifier/freespacenotifier.cpp create mode 100644 freespacenotifier/freespacenotifier.desktop create mode 100644 freespacenotifier/freespacenotifier.h create mode 100644 freespacenotifier/freespacenotifier.kcfg create mode 100644 freespacenotifier/freespacenotifier.notifyrc create mode 100644 freespacenotifier/freespacenotifier_prefs_base.ui create mode 100644 freespacenotifier/module.cpp create mode 100644 freespacenotifier/module.h create mode 100644 freespacenotifier/settings.kcfgc create mode 100644 kcheckpass/CMakeLists.txt create mode 100644 kcheckpass/README create mode 100644 kcheckpass/checkpass_aix.c create mode 100644 kcheckpass/checkpass_etcpasswd.c create mode 100644 kcheckpass/checkpass_osfc2passwd.c create mode 100644 kcheckpass/checkpass_pam.c create mode 100644 kcheckpass/checkpass_shadow.c create mode 100644 kcheckpass/config-kcheckpass.h.cmake create mode 100644 kcheckpass/kcheckpass-enums.h create mode 100644 kcheckpass/kcheckpass.c create mode 100644 kcheckpass/kcheckpass.h create mode 100644 kcminit/CMakeLists.txt create mode 100755 kcminit/Messages.sh create mode 100644 kcminit/main.cpp create mode 100644 kcminit/main.h create mode 100644 kcontrol/CMakeLists.txt create mode 100644 kcontrol/PURPOSE create mode 100644 kcontrol/access/CMakeLists.txt create mode 100644 kcontrol/access/Messages.sh create mode 100644 kcontrol/access/kaccess.cpp create mode 100644 kcontrol/access/kaccess.desktop create mode 100644 kcontrol/access/kaccess.h create mode 100644 kcontrol/access/kaccess.notifyrc create mode 100644 kcontrol/access/kcmaccess.cpp create mode 100644 kcontrol/access/kcmaccess.desktop create mode 100644 kcontrol/access/kcmaccess.h create mode 100644 kcontrol/access/main.cpp create mode 100644 kcontrol/autostart/AUTHORS create mode 100644 kcontrol/autostart/CMakeLists.txt create mode 100644 kcontrol/autostart/Messages.sh create mode 100644 kcontrol/autostart/addscriptdialog.cpp create mode 100644 kcontrol/autostart/addscriptdialog.h create mode 100644 kcontrol/autostart/advanceddialog.cpp create mode 100644 kcontrol/autostart/advanceddialog.h create mode 100644 kcontrol/autostart/autostart.cpp create mode 100644 kcontrol/autostart/autostart.desktop create mode 100644 kcontrol/autostart/autostart.h create mode 100644 kcontrol/autostart/autostartconfig.ui create mode 100644 kcontrol/autostart/autostartitem.cpp create mode 100644 kcontrol/autostart/autostartitem.h create mode 100644 kcontrol/bell/CMakeLists.txt create mode 100644 kcontrol/bell/Messages.sh create mode 100644 kcontrol/bell/bell.cpp create mode 100644 kcontrol/bell/bell.desktop create mode 100644 kcontrol/bell/bell.h create mode 100644 kcontrol/colors/CMakeLists.txt create mode 100644 kcontrol/colors/Messages.sh create mode 100644 kcontrol/colors/README.i18n create mode 100644 kcontrol/colors/TODO create mode 100644 kcontrol/colors/colors.desktop create mode 100644 kcontrol/colors/colorschemes.knsrc create mode 100644 kcontrol/colors/colorscm.cpp create mode 100644 kcontrol/colors/colorscm.h create mode 100644 kcontrol/colors/colorsettings.ui create mode 100644 kcontrol/colors/preview.ui create mode 100644 kcontrol/colors/previewwidget.cpp create mode 100644 kcontrol/colors/previewwidget.h create mode 100644 kcontrol/colors/schemes/Honeycomb.colors create mode 100644 kcontrol/colors/schemes/Norway.colors create mode 100644 kcontrol/colors/schemes/ObsidianCoast.colors create mode 100644 kcontrol/colors/schemes/Oxygen.colors create mode 100644 kcontrol/colors/schemes/OxygenCold.colors create mode 100644 kcontrol/colors/schemes/Steel.colors create mode 100644 kcontrol/colors/schemes/WontonSoup.colors create mode 100644 kcontrol/colors/schemes/Zion.colors create mode 100644 kcontrol/colors/schemes/ZionReversed.colors create mode 100644 kcontrol/colors/setpreview.ui create mode 100644 kcontrol/colors/setpreviewwidget.cpp create mode 100644 kcontrol/colors/setpreviewwidget.h create mode 100644 kcontrol/dateandtime/CMakeLists.txt create mode 100644 kcontrol/dateandtime/Messages.sh create mode 100644 kcontrol/dateandtime/clock.desktop create mode 100644 kcontrol/dateandtime/dateandtime.ui create mode 100644 kcontrol/dateandtime/dtime.cpp create mode 100644 kcontrol/dateandtime/dtime.h create mode 100644 kcontrol/dateandtime/helper.cpp create mode 100644 kcontrol/dateandtime/helper.h create mode 100644 kcontrol/dateandtime/kcmclock_actions.actions create mode 100644 kcontrol/dateandtime/main.cpp create mode 100644 kcontrol/dateandtime/main.h create mode 100644 kcontrol/desktoppaths/CMakeLists.txt create mode 100644 kcontrol/desktoppaths/Messages.sh create mode 100644 kcontrol/desktoppaths/desktoppath.desktop create mode 100644 kcontrol/desktoppaths/globalpaths.cpp create mode 100644 kcontrol/desktoppaths/globalpaths.h create mode 100644 kcontrol/desktoppaths/kcmdesktoppaths.cpp create mode 100644 kcontrol/desktoppaths/kcmdesktoppaths.h create mode 100644 kcontrol/desktoptheme/CMakeLists.txt create mode 100644 kcontrol/desktoptheme/DesktopTheme.ui create mode 100644 kcontrol/desktoptheme/DesktopThemeDetails.ui create mode 100755 kcontrol/desktoptheme/Messages.sh create mode 100644 kcontrol/desktoptheme/desktoptheme.desktop create mode 100644 kcontrol/desktoptheme/desktopthemedetails.cpp create mode 100644 kcontrol/desktoptheme/desktopthemedetails.h create mode 100644 kcontrol/desktoptheme/kcmdesktoptheme.cpp create mode 100644 kcontrol/desktoptheme/kcmdesktoptheme.h create mode 100644 kcontrol/desktoptheme/thememodel.cpp create mode 100644 kcontrol/desktoptheme/thememodel.h create mode 100644 kcontrol/fonts/CMakeLists.txt create mode 100644 kcontrol/fonts/Messages.sh create mode 100644 kcontrol/fonts/fonts.cpp create mode 100644 kcontrol/fonts/fonts.desktop create mode 100644 kcontrol/fonts/fonts.h create mode 100644 kcontrol/fonts/kxftconfig.cpp create mode 100644 kcontrol/fonts/kxftconfig.h create mode 100644 kcontrol/hardware/CMakeLists.txt create mode 100644 kcontrol/hardware/display/CMakeLists.txt create mode 100644 kcontrol/hardware/display/Messages.sh create mode 100644 kcontrol/hardware/display/display.cpp create mode 100644 kcontrol/hardware/display/display.desktop create mode 100644 kcontrol/hardware/display/display.h create mode 100644 kcontrol/hardware/joystick/CMakeLists.txt create mode 100644 kcontrol/hardware/joystick/Messages.sh create mode 100644 kcontrol/hardware/joystick/caldialog.cpp create mode 100644 kcontrol/hardware/joystick/caldialog.h create mode 100644 kcontrol/hardware/joystick/joydevice.cpp create mode 100644 kcontrol/hardware/joystick/joydevice.h create mode 100644 kcontrol/hardware/joystick/joystick.cpp create mode 100644 kcontrol/hardware/joystick/joystick.desktop create mode 100644 kcontrol/hardware/joystick/joystick.h create mode 100644 kcontrol/hardware/joystick/joywidget.cpp create mode 100644 kcontrol/hardware/joystick/joywidget.h create mode 100644 kcontrol/hardware/joystick/poswidget.cpp create mode 100644 kcontrol/hardware/joystick/poswidget.h create mode 100644 kcontrol/input/AUTHORS create mode 100644 kcontrol/input/CMakeLists.txt create mode 100644 kcontrol/input/ChangeLog create mode 100644 kcontrol/input/Messages.sh create mode 100644 kcontrol/input/config-kcontrol-input.h.cmake create mode 100755 kcontrol/input/consoleUserPerms create mode 100644 kcontrol/input/core/bitmaps.h create mode 100644 kcontrol/input/core/themepage.cpp create mode 100644 kcontrol/input/core/themepage.h create mode 100644 kcontrol/input/cursor_large.bdf create mode 100644 kcontrol/input/cursor_large_black.pcf.gz create mode 100644 kcontrol/input/cursor_large_white.pcf.gz create mode 100644 kcontrol/input/cursor_small_white.pcf.gz create mode 100644 kcontrol/input/cursortheme.desktop create mode 100644 kcontrol/input/kapplymousetheme.cpp create mode 100644 kcontrol/input/kcmcursortheme.cpp create mode 100644 kcontrol/input/kcmcursortheme.h create mode 100644 kcontrol/input/kmousedlg.ui create mode 100644 kcontrol/input/logitechmouse.cpp create mode 100644 kcontrol/input/logitechmouse.h create mode 100644 kcontrol/input/logitechmouse.usermap create mode 100644 kcontrol/input/logitechmouse_base.ui create mode 100644 kcontrol/input/main.cpp create mode 100644 kcontrol/input/mouse.cpp create mode 100644 kcontrol/input/mouse.desktop create mode 100644 kcontrol/input/mouse.h create mode 100644 kcontrol/input/pics/CMakeLists.txt create mode 100644 kcontrol/input/pics/mouse_lh.png create mode 100644 kcontrol/input/pics/mouse_lh.svgz create mode 100644 kcontrol/input/pics/mouse_rh.png create mode 100644 kcontrol/input/pics/mouse_rh.svgz create mode 100644 kcontrol/input/xcursor/cursortheme.cpp create mode 100644 kcontrol/input/xcursor/cursortheme.h create mode 100644 kcontrol/input/xcursor/itemdelegate.cpp create mode 100644 kcontrol/input/xcursor/itemdelegate.h create mode 100644 kcontrol/input/xcursor/previewwidget.cpp create mode 100644 kcontrol/input/xcursor/previewwidget.h create mode 100644 kcontrol/input/xcursor/sortproxymodel.cpp create mode 100644 kcontrol/input/xcursor/sortproxymodel.h create mode 100644 kcontrol/input/xcursor/thememodel.cpp create mode 100644 kcontrol/input/xcursor/thememodel.h create mode 100644 kcontrol/input/xcursor/themepage.cpp create mode 100644 kcontrol/input/xcursor/themepage.h create mode 100644 kcontrol/input/xcursor/themepage.ui create mode 100644 kcontrol/input/xcursor/xcursor.knsrc create mode 100644 kcontrol/input/xcursor/xcursortheme.cpp create mode 100644 kcontrol/input/xcursor/xcursortheme.h create mode 100644 kcontrol/keyboard/CMakeLists.txt create mode 100755 kcontrol/keyboard/Messages.sh create mode 100644 kcontrol/keyboard/README create mode 100644 kcontrol/keyboard/TODO create mode 100644 kcontrol/keyboard/bindings.cpp create mode 100644 kcontrol/keyboard/bindings.h create mode 100644 kcontrol/keyboard/flags.cpp create mode 100644 kcontrol/keyboard/flags.h create mode 100644 kcontrol/keyboard/iso_codes.cpp create mode 100644 kcontrol/keyboard/iso_codes.h create mode 100644 kcontrol/keyboard/kcm_add_layout_dialog.cpp create mode 100644 kcontrol/keyboard/kcm_add_layout_dialog.h create mode 100644 kcontrol/keyboard/kcm_add_layout_dialog.ui create mode 100644 kcontrol/keyboard/kcm_keyboard.cpp create mode 100644 kcontrol/keyboard/kcm_keyboard.desktop create mode 100644 kcontrol/keyboard/kcm_keyboard.h create mode 100644 kcontrol/keyboard/kcm_keyboard.ui create mode 100644 kcontrol/keyboard/kcm_keyboard_widget.cpp create mode 100644 kcontrol/keyboard/kcm_keyboard_widget.h create mode 100644 kcontrol/keyboard/kcm_view_models.cpp create mode 100644 kcontrol/keyboard/kcm_view_models.h create mode 100644 kcontrol/keyboard/kcmmisc.cpp create mode 100644 kcontrol/keyboard/kcmmisc.h create mode 100644 kcontrol/keyboard/kcmmiscwidget.ui create mode 100644 kcontrol/keyboard/keyboard.desktop create mode 100644 kcontrol/keyboard/keyboard_applet.cpp create mode 100644 kcontrol/keyboard/keyboard_applet.h create mode 100644 kcontrol/keyboard/keyboard_config.cpp create mode 100644 kcontrol/keyboard/keyboard_config.h create mode 100644 kcontrol/keyboard/keyboard_daemon.cpp create mode 100644 kcontrol/keyboard/keyboard_daemon.h create mode 100644 kcontrol/keyboard/keyboard_dbus.h create mode 100644 kcontrol/keyboard/keyboard_hardware.cpp create mode 100644 kcontrol/keyboard/keyboard_hardware.h create mode 100644 kcontrol/keyboard/layout_memory.cpp create mode 100644 kcontrol/keyboard/layout_memory.h create mode 100644 kcontrol/keyboard/layout_memory_persister.cpp create mode 100644 kcontrol/keyboard/layout_memory_persister.h create mode 100644 kcontrol/keyboard/layout_tray_icon.cpp create mode 100644 kcontrol/keyboard/layout_tray_icon.h create mode 100644 kcontrol/keyboard/layout_widget.cpp create mode 100644 kcontrol/keyboard/layout_widget.h create mode 100644 kcontrol/keyboard/layouts_menu.cpp create mode 100644 kcontrol/keyboard/layouts_menu.h create mode 100644 kcontrol/keyboard/numlockx.c create mode 100644 kcontrol/keyboard/pics/CMakeLists.txt create mode 100644 kcontrol/keyboard/pics/epo.png create mode 100644 kcontrol/keyboard/plasma_applet_keyboard.desktop create mode 100644 kcontrol/keyboard/preview/TODO create mode 100644 kcontrol/keyboard/preview/kbpreviewframe.cpp create mode 100644 kcontrol/keyboard/preview/kbpreviewframe.h create mode 100644 kcontrol/keyboard/preview/keyaliases.cpp create mode 100644 kcontrol/keyboard/preview/keyaliases.h create mode 100644 kcontrol/keyboard/preview/keyboardlayout.cpp create mode 100644 kcontrol/keyboard/preview/keyboardlayout.h create mode 100644 kcontrol/keyboard/preview/keyboardpainter.cpp create mode 100644 kcontrol/keyboard/preview/keyboardpainter.h create mode 100644 kcontrol/keyboard/preview/keysym2ucs.cpp create mode 100644 kcontrol/keyboard/preview/keysym2ucs.h create mode 100644 kcontrol/keyboard/preview/keysymbols.cpp create mode 100644 kcontrol/keyboard/preview/keysymbols.h create mode 100644 kcontrol/keyboard/preview/keysymhelper.cpp create mode 100644 kcontrol/keyboard/preview/keysymhelper.h create mode 100644 kcontrol/keyboard/tests/CMakeLists.txt create mode 100644 kcontrol/keyboard/tests/config/base.1.1.xml create mode 100644 kcontrol/keyboard/tests/config/base.bad.xml create mode 100644 kcontrol/keyboard/tests/config/base.xml create mode 100644 kcontrol/keyboard/tests/flags_test.cpp create mode 100644 kcontrol/keyboard/tests/iso_codes_test.cpp create mode 100644 kcontrol/keyboard/tests/keyboard_daemon_test.cpp create mode 100644 kcontrol/keyboard/tests/layout_memory_persister_test.cpp create mode 100644 kcontrol/keyboard/tests/xkb_rules_test.cpp create mode 100644 kcontrol/keyboard/x11_helper.cpp create mode 100644 kcontrol/keyboard/x11_helper.h create mode 100644 kcontrol/keyboard/xinput_helper.cpp create mode 100644 kcontrol/keyboard/xinput_helper.h create mode 100644 kcontrol/keyboard/xkb_helper.cpp create mode 100644 kcontrol/keyboard/xkb_helper.h create mode 100644 kcontrol/keyboard/xkb_rules.cpp create mode 100644 kcontrol/keyboard/xkb_rules.h create mode 100644 kcontrol/keys/CMakeLists.txt create mode 100644 kcontrol/keys/ChangeLog create mode 100644 kcontrol/keys/Messages.sh create mode 100644 kcontrol/keys/README create mode 100644 kcontrol/keys/export_scheme_dialog.cpp create mode 100644 kcontrol/keys/export_scheme_dialog.h create mode 100644 kcontrol/keys/export_scheme_dialog.ui create mode 100644 kcontrol/keys/globalshortcuts.cpp create mode 100644 kcontrol/keys/globalshortcuts.h create mode 100644 kcontrol/keys/keys.desktop create mode 100644 kcontrol/keys/kglobalshortcutseditor.cpp create mode 100644 kcontrol/keys/kglobalshortcutseditor.h create mode 100644 kcontrol/keys/kglobalshortcutseditor.ui create mode 100644 kcontrol/keys/schemes/kde3.kksrc create mode 100644 kcontrol/keys/schemes/kde4.kksrc create mode 100644 kcontrol/keys/schemes/mac4.kksrc create mode 100644 kcontrol/keys/schemes/old_kde3.kksrc create mode 100644 kcontrol/keys/schemes/old_kde4.kksrc create mode 100644 kcontrol/keys/schemes/old_mac4.kksrc create mode 100644 kcontrol/keys/schemes/old_unix3.kksrc create mode 100644 kcontrol/keys/schemes/old_win3.kksrc create mode 100644 kcontrol/keys/schemes/old_win4.kksrc create mode 100644 kcontrol/keys/schemes/old_wm3.kksrc create mode 100755 kcontrol/keys/schemes/split_kksrc create mode 100644 kcontrol/keys/schemes/unix3.kksrc create mode 100644 kcontrol/keys/schemes/win3.kksrc create mode 100644 kcontrol/keys/schemes/win4.kksrc create mode 100644 kcontrol/keys/schemes/wm3.kksrc create mode 100644 kcontrol/keys/select_scheme_dialog.cpp create mode 100644 kcontrol/keys/select_scheme_dialog.h create mode 100644 kcontrol/keys/select_scheme_dialog.ui create mode 100644 kcontrol/kfontinst/AUTHORS create mode 100644 kcontrol/kfontinst/CMakeLists.txt create mode 100644 kcontrol/kfontinst/ChangeLog create mode 100644 kcontrol/kfontinst/Messages.sh create mode 100644 kcontrol/kfontinst/apps/CMakeLists.txt create mode 100644 kcontrol/kfontinst/apps/CreateParent.h create mode 100644 kcontrol/kfontinst/apps/Installer.cpp create mode 100644 kcontrol/kfontinst/apps/Installer.h create mode 100644 kcontrol/kfontinst/apps/Printer.cpp create mode 100644 kcontrol/kfontinst/apps/Printer.h create mode 100644 kcontrol/kfontinst/apps/Viewer.cpp create mode 100644 kcontrol/kfontinst/apps/Viewer.h create mode 100644 kcontrol/kfontinst/apps/installfont.desktop create mode 100755 kcontrol/kfontinst/apps/kfontview.desktop create mode 100644 kcontrol/kfontinst/apps/kfontviewui.rc create mode 100644 kcontrol/kfontinst/apps/ox16-app-kfontview.png create mode 100644 kcontrol/kfontinst/apps/ox22-app-kfontview.png create mode 100644 kcontrol/kfontinst/apps/ox32-app-kfontview.png create mode 100644 kcontrol/kfontinst/apps/ox48-app-kfontview.png create mode 100644 kcontrol/kfontinst/apps/ox64-app-kfontview.png create mode 100644 kcontrol/kfontinst/apps/oxsc-app-kfontview.svgz create mode 100644 kcontrol/kfontinst/config-fontinst.h.cmake create mode 100644 kcontrol/kfontinst/dbus/CMakeLists.txt create mode 100644 kcontrol/kfontinst/dbus/FcConfig.cpp create mode 100644 kcontrol/kfontinst/dbus/FcConfig.h create mode 100644 kcontrol/kfontinst/dbus/Folder.cpp create mode 100644 kcontrol/kfontinst/dbus/Folder.h create mode 100644 kcontrol/kfontinst/dbus/FontInst.cpp create mode 100644 kcontrol/kfontinst/dbus/FontInst.h create mode 100644 kcontrol/kfontinst/dbus/FontinstIface.cpp create mode 100644 kcontrol/kfontinst/dbus/FontinstIface.h create mode 100644 kcontrol/kfontinst/dbus/Helper.cpp create mode 100644 kcontrol/kfontinst/dbus/Helper.h create mode 100644 kcontrol/kfontinst/dbus/Main.cpp create mode 100644 kcontrol/kfontinst/dbus/Utils.cpp create mode 100644 kcontrol/kfontinst/dbus/Utils.h create mode 100644 kcontrol/kfontinst/dbus/fontinst.actions create mode 100755 kcontrol/kfontinst/dbus/fontinst_x11 create mode 100644 kcontrol/kfontinst/dbus/org.kde.fontinst.service.cmake create mode 100644 kcontrol/kfontinst/dbus/org.kde.fontinst.system-service.cmake create mode 100644 kcontrol/kfontinst/dbus/org.kde.fontinst.xml create mode 100644 kcontrol/kfontinst/kcmfontinst/ActionLabel.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/ActionLabel.h create mode 100644 kcontrol/kfontinst/kcmfontinst/CMakeLists.txt create mode 100644 kcontrol/kfontinst/kcmfontinst/DuplicatesDialog.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/DuplicatesDialog.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FcQuery.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/FcQuery.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FontFilter.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/FontFilter.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FontFilterProxyStyle.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/FontFilterProxyStyle.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FontInstInterface.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FontList.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/FontList.h create mode 100644 kcontrol/kfontinst/kcmfontinst/FontsPackage.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/FontsPackage.h create mode 100644 kcontrol/kfontinst/kcmfontinst/GroupList.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/GroupList.h create mode 100644 kcontrol/kfontinst/kcmfontinst/JobRunner.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/JobRunner.h create mode 100644 kcontrol/kfontinst/kcmfontinst/KCmFontInst.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/KCmFontInst.h create mode 100644 kcontrol/kfontinst/kcmfontinst/PreviewList.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/PreviewList.h create mode 100644 kcontrol/kfontinst/kcmfontinst/PrintDialog.cpp create mode 100644 kcontrol/kfontinst/kcmfontinst/PrintDialog.h create mode 100644 kcontrol/kfontinst/kcmfontinst/fontinst.desktop create mode 100644 kcontrol/kfontinst/kcmfontinst/kfontinst.knsrc create mode 100644 kcontrol/kfontinst/kcmfontinst/ox16-action-addfont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox16-action-disablefont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox16-action-enablefont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox16-action-fontstatus.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox22-action-addfont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox22-action-disablefont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox22-action-enablefont.png create mode 100644 kcontrol/kfontinst/kcmfontinst/ox22-action-fontstatus.png create mode 100644 kcontrol/kfontinst/kcmfontinst/oxsc-action-addfont.svgz create mode 100644 kcontrol/kfontinst/kcmfontinst/oxsc-action-disablefont.svgz create mode 100644 kcontrol/kfontinst/kcmfontinst/oxsc-action-enablefont.svgz create mode 100644 kcontrol/kfontinst/kcmfontinst/oxsc-action-fontstatus.svgz create mode 100644 kcontrol/kfontinst/kio/CMakeLists.txt create mode 100644 kcontrol/kfontinst/kio/FontInstInterface.cpp create mode 100644 kcontrol/kfontinst/kio/FontInstInterface.h create mode 100644 kcontrol/kfontinst/kio/KioFonts.cpp create mode 100644 kcontrol/kfontinst/kio/KioFonts.h create mode 100644 kcontrol/kfontinst/kio/fonts.desktop create mode 100644 kcontrol/kfontinst/kio/fonts.protocol create mode 100644 kcontrol/kfontinst/kio/ox128-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/ox16-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/ox22-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/ox32-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/ox48-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/ox64-mimetypes-fonts-package.png create mode 100644 kcontrol/kfontinst/kio/oxsc-mimetypes-fonts-package.svgz create mode 100644 kcontrol/kfontinst/lib/CMakeLists.txt create mode 100644 kcontrol/kfontinst/lib/Family.cpp create mode 100644 kcontrol/kfontinst/lib/Family.h create mode 100644 kcontrol/kfontinst/lib/Fc.cpp create mode 100644 kcontrol/kfontinst/lib/Fc.h create mode 100644 kcontrol/kfontinst/lib/FcEngine.cpp create mode 100644 kcontrol/kfontinst/lib/FcEngine.h create mode 100644 kcontrol/kfontinst/lib/File.cpp create mode 100644 kcontrol/kfontinst/lib/File.h create mode 100644 kcontrol/kfontinst/lib/KfiConstants.h create mode 100644 kcontrol/kfontinst/lib/Misc.cpp create mode 100644 kcontrol/kfontinst/lib/Misc.h create mode 100644 kcontrol/kfontinst/lib/Style.cpp create mode 100644 kcontrol/kfontinst/lib/Style.h create mode 100644 kcontrol/kfontinst/lib/WritingSystems.cpp create mode 100644 kcontrol/kfontinst/lib/WritingSystems.h create mode 100644 kcontrol/kfontinst/lib/XmlStrings.h create mode 100644 kcontrol/kfontinst/lib/kfontinst_export.h create mode 100644 kcontrol/kfontinst/oxsc-app-preferences-desktop-font-installer.svgz create mode 100644 kcontrol/kfontinst/strigi-analyzer/CMakeLists.txt create mode 100644 kcontrol/kfontinst/strigi-analyzer/FontEngine.cpp create mode 100644 kcontrol/kfontinst/strigi-analyzer/FontEngine.h create mode 100644 kcontrol/kfontinst/strigi-analyzer/FontThroughAnalyzer.cpp create mode 100644 kcontrol/kfontinst/strigi-analyzer/FontThroughAnalyzer.h create mode 100644 kcontrol/kfontinst/thumbnail/CMakeLists.txt create mode 100644 kcontrol/kfontinst/thumbnail/FontThumbnail.cpp create mode 100644 kcontrol/kfontinst/thumbnail/FontThumbnail.h create mode 100644 kcontrol/kfontinst/thumbnail/fontthumbnail.desktop create mode 100644 kcontrol/kfontinst/viewpart/CMakeLists.txt create mode 100644 kcontrol/kfontinst/viewpart/COPYING.UNICODE create mode 100644 kcontrol/kfontinst/viewpart/CharTip.cpp create mode 100644 kcontrol/kfontinst/viewpart/CharTip.h create mode 100644 kcontrol/kfontinst/viewpart/FontPreview.cpp create mode 100644 kcontrol/kfontinst/viewpart/FontPreview.h create mode 100644 kcontrol/kfontinst/viewpart/FontViewPart.cpp create mode 100644 kcontrol/kfontinst/viewpart/FontViewPart.h create mode 100644 kcontrol/kfontinst/viewpart/PreviewSelectAction.cpp create mode 100644 kcontrol/kfontinst/viewpart/PreviewSelectAction.h create mode 100644 kcontrol/kfontinst/viewpart/UnicodeBlocks.h create mode 100644 kcontrol/kfontinst/viewpart/UnicodeCategories.h create mode 100644 kcontrol/kfontinst/viewpart/UnicodeScripts.h create mode 100644 kcontrol/kfontinst/viewpart/download-unicode-files.sh create mode 100644 kcontrol/kfontinst/viewpart/generate-unicode-tables.pl create mode 100644 kcontrol/kfontinst/viewpart/kfontviewpart.desktop create mode 100644 kcontrol/kfontinst/viewpart/kfontviewpart.rc create mode 100644 kcontrol/krdb/AUTHORS create mode 100644 kcontrol/krdb/CMakeLists.txt create mode 100644 kcontrol/krdb/Messages.sh create mode 100644 kcontrol/krdb/ad/AAAAAAGeneral.ad create mode 100644 kcontrol/krdb/ad/AAAMotif.ad create mode 100644 kcontrol/krdb/ad/AAATk.ad create mode 100644 kcontrol/krdb/ad/AAAXaw.ad create mode 100644 kcontrol/krdb/ad/AcroRead.ad create mode 100644 kcontrol/krdb/ad/CMakeLists.txt create mode 100644 kcontrol/krdb/ad/Editres.ad create mode 100644 kcontrol/krdb/ad/Emacs.ad create mode 100644 kcontrol/krdb/ad/GV.ad create mode 100644 kcontrol/krdb/ad/ML.ad create mode 100644 kcontrol/krdb/ad/Nedit.ad create mode 100644 kcontrol/krdb/ad/Netscape.ad create mode 100644 kcontrol/krdb/ad/README create mode 100644 kcontrol/krdb/ad/RVPlayer.ad create mode 100644 kcontrol/krdb/ad/WPerfect.ad create mode 100644 kcontrol/krdb/ad/XCalc.ad create mode 100644 kcontrol/krdb/ad/XOsview.ad create mode 100644 kcontrol/krdb/ad/XTerm.ad create mode 100644 kcontrol/krdb/ad/XV.ad create mode 100644 kcontrol/krdb/ad/Xawtv.ad create mode 100644 kcontrol/krdb/ad/Xdvi.ad create mode 100644 kcontrol/krdb/ad/Xpdf.ad create mode 100755 kcontrol/krdb/ad/krdb create mode 100644 kcontrol/krdb/krdb.cpp create mode 100644 kcontrol/krdb/krdb.h create mode 100644 kcontrol/krdb/krdb_clearlibrarypath.cpp create mode 100644 kcontrol/krdb/krdb_libpathwipe.upd create mode 100644 kcontrol/krdb/pics/CMakeLists.txt create mode 100644 kcontrol/krdb/pics/lo-energy.png create mode 100644 kcontrol/krdb/pics/logo.png create mode 100644 kcontrol/krdb/pics/mini-world.png create mode 100644 kcontrol/krdb/themes/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/HighContrastDark-big/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/HighContrastDark-big/HighContrastDark-big.preview.png create mode 100644 kcontrol/krdb/themes/HighContrastDark-big/HighContrastDark-big.xml create mode 100644 kcontrol/krdb/themes/HighContrastDark/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/HighContrastDark/HighContrastDark.preview.png create mode 100644 kcontrol/krdb/themes/HighContrastDark/HighContrastDark.xml create mode 100644 kcontrol/krdb/themes/HighContrastLight-big/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/HighContrastLight-big/HighContrastLight-big.preview.png create mode 100644 kcontrol/krdb/themes/HighContrastLight-big/HighContrastLight-big.xml create mode 100644 kcontrol/krdb/themes/HighContrastLight/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/HighContrastLight/HighContrastLight.preview.png create mode 100644 kcontrol/krdb/themes/HighContrastLight/HighContrastLight.xml create mode 100644 kcontrol/krdb/themes/KDE_Classic/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/KDE_Classic/KDE_Classic.preview.png create mode 100644 kcontrol/krdb/themes/KDE_Classic/KDE_Classic.xml create mode 100644 kcontrol/krdb/themes/Keramik/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/Keramik/Keramik.preview.png create mode 100644 kcontrol/krdb/themes/Keramik/Keramik.xml create mode 100644 kcontrol/krdb/themes/Plastik/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/Plastik/Plastik.preview.png create mode 100644 kcontrol/krdb/themes/Plastik/Plastik.xml create mode 100644 kcontrol/krdb/themes/Platinum/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/Platinum/Platinum.preview.png create mode 100644 kcontrol/krdb/themes/Platinum/Platinum.xml create mode 100644 kcontrol/krdb/themes/Redmond/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/Redmond/Redmond.preview.png create mode 100644 kcontrol/krdb/themes/Redmond/Redmond.xml create mode 100644 kcontrol/krdb/themes/Sunshine/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/Sunshine/Sunshine.preview.png create mode 100644 kcontrol/krdb/themes/Sunshine/Sunshine.xml create mode 100644 kcontrol/krdb/themes/YellowOnBlue-big/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/YellowOnBlue-big/YellowOnBlue-big.preview.png create mode 100644 kcontrol/krdb/themes/YellowOnBlue-big/YellowOnBlue-big.xml create mode 100644 kcontrol/krdb/themes/YellowOnBlue/CMakeLists.txt create mode 100644 kcontrol/krdb/themes/YellowOnBlue/YellowOnBlue.preview.png create mode 100644 kcontrol/krdb/themes/YellowOnBlue/YellowOnBlue.xml create mode 100644 kcontrol/launch/CMakeLists.txt create mode 100644 kcontrol/launch/Messages.sh create mode 100644 kcontrol/launch/interface_util.h create mode 100644 kcontrol/launch/kcmlaunch.cpp create mode 100644 kcontrol/launch/kcmlaunch.desktop create mode 100644 kcontrol/launch/kcmlaunch.h create mode 100644 kcontrol/randr/CMakeLists.txt create mode 100644 kcontrol/randr/ChangeLog create mode 100644 kcontrol/randr/Messages.sh create mode 100644 kcontrol/randr/TODO create mode 100644 kcontrol/randr/collapsiblewidget.cpp create mode 100644 kcontrol/randr/collapsiblewidget.h create mode 100644 kcontrol/randr/config-randr.h.cmake create mode 100644 kcontrol/randr/krandrapp.cpp create mode 100644 kcontrol/randr/krandrapp.h create mode 100644 kcontrol/randr/krandrmodule.cpp create mode 100644 kcontrol/randr/krandrmodule.h create mode 100644 kcontrol/randr/krandrpassivepopup.cpp create mode 100644 kcontrol/randr/krandrpassivepopup.h create mode 100755 kcontrol/randr/krandrstartup create mode 100644 kcontrol/randr/krandrtray.cpp create mode 100755 kcontrol/randr/krandrtray.desktop create mode 100644 kcontrol/randr/krandrtray.h create mode 100644 kcontrol/randr/ktimerdialog.cpp create mode 100644 kcontrol/randr/ktimerdialog.h create mode 100644 kcontrol/randr/layoutmanager.cpp create mode 100644 kcontrol/randr/layoutmanager.h create mode 100644 kcontrol/randr/legacyrandrconfig.cpp create mode 100644 kcontrol/randr/legacyrandrconfig.h create mode 100644 kcontrol/randr/legacyrandrconfigbase.ui create mode 100644 kcontrol/randr/legacyrandrscreen.cpp create mode 100644 kcontrol/randr/legacyrandrscreen.h create mode 100644 kcontrol/randr/main.cpp create mode 100644 kcontrol/randr/module/CMakeLists.txt create mode 100644 kcontrol/randr/module/Messages.sh create mode 100644 kcontrol/randr/module/TODO create mode 100644 kcontrol/randr/module/randrmonitor.cpp create mode 100644 kcontrol/randr/module/randrmonitor.desktop create mode 100644 kcontrol/randr/module/randrmonitor.h create mode 100644 kcontrol/randr/module/randrpolltest.cpp create mode 100644 kcontrol/randr/outputconfig.cpp create mode 100644 kcontrol/randr/outputconfig.h create mode 100644 kcontrol/randr/outputconfigbase.ui create mode 100644 kcontrol/randr/outputgraphicsitem.cpp create mode 100644 kcontrol/randr/outputgraphicsitem.h create mode 100644 kcontrol/randr/randr.cpp create mode 100644 kcontrol/randr/randr.desktop create mode 100644 kcontrol/randr/randr.h create mode 100644 kcontrol/randr/randrconfig.cpp create mode 100644 kcontrol/randr/randrconfig.h create mode 100644 kcontrol/randr/randrconfigbase.ui create mode 100644 kcontrol/randr/randrcrtc.cpp create mode 100644 kcontrol/randr/randrcrtc.h create mode 100644 kcontrol/randr/randrdisplay.cpp create mode 100644 kcontrol/randr/randrdisplay.h create mode 100644 kcontrol/randr/randrmode.cpp create mode 100644 kcontrol/randr/randrmode.h create mode 100644 kcontrol/randr/randroutput.cpp create mode 100644 kcontrol/randr/randroutput.h create mode 100644 kcontrol/randr/randrscreen.cpp create mode 100644 kcontrol/randr/randrscreen.h create mode 100644 kcontrol/screensaver/CMakeLists.txt create mode 100644 kcontrol/screensaver/Messages.sh create mode 100644 kcontrol/screensaver/category_list create mode 100644 kcontrol/screensaver/config-screensaver.h.cmake create mode 100644 kcontrol/screensaver/kssmonitor.h create mode 100644 kcontrol/screensaver/kswidget.cpp create mode 100644 kcontrol/screensaver/kswidget.h create mode 100644 kcontrol/screensaver/saverconfig.cpp create mode 100644 kcontrol/screensaver/saverconfig.h create mode 100644 kcontrol/screensaver/screensaver.desktop create mode 100644 kcontrol/screensaver/screensaver.ui create mode 100644 kcontrol/screensaver/scrnsave.cpp create mode 100644 kcontrol/screensaver/scrnsave.h create mode 100644 kcontrol/screensaver/testwin.cpp create mode 100644 kcontrol/screensaver/testwin.h create mode 100644 kcontrol/smartcard/CMakeLists.txt create mode 100644 kcontrol/smartcard/Messages.sh create mode 100644 kcontrol/smartcard/configure.in.in create mode 100644 kcontrol/smartcard/nosmartcardbase.ui create mode 100644 kcontrol/smartcard/smartcard.cpp create mode 100644 kcontrol/smartcard/smartcard.desktop create mode 100644 kcontrol/smartcard/smartcard.h create mode 100644 kcontrol/smartcard/smartcardbase.ui create mode 100644 kcontrol/standard_actions/CMakeLists.txt create mode 100644 kcontrol/standard_actions/Messages.sh create mode 100644 kcontrol/standard_actions/standard_actions.desktop create mode 100644 kcontrol/standard_actions/standard_actions_module.cpp create mode 100644 kcontrol/standard_actions/standard_actions_module.h create mode 100644 kcontrol/style/CMakeLists.txt create mode 100644 kcontrol/style/Messages.sh create mode 100644 kcontrol/style/finetuning.ui create mode 100644 kcontrol/style/kcmstyle.cpp create mode 100644 kcontrol/style/kcmstyle.h create mode 100644 kcontrol/style/kcmstyle.notifyrc create mode 100644 kcontrol/style/style.desktop create mode 100644 kcontrol/style/styleconfdialog.cpp create mode 100644 kcontrol/style/styleconfdialog.h create mode 100644 kcontrol/style/stylepreview.ui create mode 100644 kcontrol/workspaceoptions/CMakeLists.txt create mode 100644 kcontrol/workspaceoptions/Messages.sh create mode 100644 kcontrol/workspaceoptions/mainpage.ui create mode 100644 kcontrol/workspaceoptions/workspaceoptions.cpp create mode 100644 kcontrol/workspaceoptions/workspaceoptions.desktop create mode 100644 kcontrol/workspaceoptions/workspaceoptions.h create mode 100644 kde.pamd create mode 100644 kdm/CMakeLists.txt create mode 100644 kdm/ChangeLog create mode 100644 kdm/ConfigureChecks.cmake create mode 100644 kdm/README create mode 100644 kdm/TODO create mode 100644 kdm/backend/CMakeLists.txt create mode 100644 kdm/backend/access.c create mode 100644 kdm/backend/auth.c create mode 100644 kdm/backend/bootman.c create mode 100644 kdm/backend/choose.c create mode 100644 kdm/backend/client.c create mode 100644 kdm/backend/ctrl.c create mode 100644 kdm/backend/daemon.c create mode 100644 kdm/backend/dm.c create mode 100644 kdm/backend/dm.h create mode 100644 kdm/backend/dm_auth.h create mode 100644 kdm/backend/dm_error.h create mode 100644 kdm/backend/dm_socket.h create mode 100644 kdm/backend/dpylist.c create mode 100644 kdm/backend/error.c create mode 100644 kdm/backend/genauth.c create mode 100644 kdm/backend/greet.h create mode 100644 kdm/backend/inifile.c create mode 100644 kdm/backend/krb5auth.c create mode 100644 kdm/backend/netaddr.c create mode 100644 kdm/backend/policy.c create mode 100644 kdm/backend/printf.c create mode 100644 kdm/backend/process.c create mode 100644 kdm/backend/protodpy.c create mode 100644 kdm/backend/reset.c create mode 100644 kdm/backend/resource.c create mode 100644 kdm/backend/rpcauth.c create mode 100644 kdm/backend/server.c create mode 100644 kdm/backend/session.c create mode 100644 kdm/backend/sessreg.c create mode 100644 kdm/backend/socket.c create mode 100644 kdm/backend/streams.c create mode 100644 kdm/backend/util.c create mode 100644 kdm/backend/xdmauth.c create mode 100644 kdm/backend/xdmcp.c create mode 100644 kdm/config-kdm.h.cmake create mode 100644 kdm/config.def create mode 100755 kdm/confproc.pl create mode 100644 kdm/kcm/AUTHORS create mode 100644 kdm/kcm/CMakeLists.txt create mode 100644 kdm/kcm/Messages.sh create mode 100644 kdm/kcm/anchor.png create mode 100644 kdm/kcm/background.cpp create mode 100644 kdm/kcm/background.h create mode 100644 kdm/kcm/background/CMakeLists.txt create mode 100644 kdm/kcm/background/Messages.sh create mode 100644 kdm/kcm/background/background.knsrc create mode 100644 kdm/kcm/background/bgadvanced.cpp create mode 100644 kdm/kcm/background/bgadvanced.h create mode 100644 kdm/kcm/background/bgadvanced_ui.ui create mode 100644 kdm/kcm/background/bgdefaults.h create mode 100644 kdm/kcm/background/bgdialog.cpp create mode 100644 kdm/kcm/background/bgdialog.h create mode 100644 kdm/kcm/background/bgdialog_ui.ui create mode 100644 kdm/kcm/background/bgmonitor.cpp create mode 100644 kdm/kcm/background/bgmonitor.h create mode 100644 kdm/kcm/background/bgrender.cpp create mode 100644 kdm/kcm/background/bgrender.h create mode 100644 kdm/kcm/background/bgsettings.cpp create mode 100644 kdm/kcm/background/bgsettings.h create mode 100644 kdm/kcm/background/bgwallpaper.cpp create mode 100644 kdm/kcm/background/bgwallpaper.h create mode 100644 kdm/kcm/background/bgwallpaper_ui.ui create mode 100644 kdm/kcm/background/patterns/CMakeLists.txt create mode 100644 kdm/kcm/background/patterns/fish.desktop create mode 100644 kdm/kcm/background/patterns/fish.png create mode 100644 kdm/kcm/background/patterns/flowers.desktop create mode 100644 kdm/kcm/background/patterns/flowers.png create mode 100644 kdm/kcm/background/patterns/night-rock.desktop create mode 100644 kdm/kcm/background/patterns/night-rock.jpg create mode 100644 kdm/kcm/background/patterns/pavement.desktop create mode 100644 kdm/kcm/background/patterns/pavement.png create mode 100644 kdm/kcm/background/patterns/rattan.desktop create mode 100644 kdm/kcm/background/patterns/rattan.png create mode 100644 kdm/kcm/background/patterns/stonewall2.desktop create mode 100644 kdm/kcm/background/patterns/stonewall2.png create mode 100644 kdm/kcm/background/patterns/triangles.desktop create mode 100644 kdm/kcm/background/patterns/triangles.png create mode 100644 kdm/kcm/background/pics/CMakeLists.txt create mode 100644 kdm/kcm/background/pics/monitor.png create mode 100644 kdm/kcm/background/programs/CMakeLists.txt create mode 100644 kdm/kcm/background/programs/xearth.desktop create mode 100644 kdm/kcm/background/programs/xglobe.desktop create mode 100644 kdm/kcm/background/programs/xplanet.desktop create mode 100644 kdm/kcm/helper.cpp create mode 100644 kdm/kcm/helper.h create mode 100644 kdm/kcm/kbackedcombobox.cpp create mode 100644 kdm/kcm/kbackedcombobox.h create mode 100644 kdm/kcm/kcmkdm_actions.actions create mode 100644 kdm/kcm/kdm-conv.cpp create mode 100644 kdm/kcm/kdm-conv.h create mode 100644 kdm/kcm/kdm-dlg.cpp create mode 100644 kdm/kcm/kdm-dlg.h create mode 100644 kdm/kcm/kdm-gen.cpp create mode 100644 kdm/kcm/kdm-gen.h create mode 100644 kdm/kcm/kdm-shut.cpp create mode 100644 kdm/kcm/kdm-shut.h create mode 100644 kdm/kcm/kdm-theme.cpp create mode 100644 kdm/kcm/kdm-theme.h create mode 100644 kdm/kcm/kdm-users.cpp create mode 100644 kdm/kcm/kdm-users.h create mode 100644 kdm/kcm/kdm.desktop create mode 100644 kdm/kcm/kdm.knsrc create mode 100644 kdm/kcm/main.cpp create mode 100644 kdm/kcm/main.h create mode 100644 kdm/kcm/positioner.cpp create mode 100644 kdm/kcm/positioner.h create mode 100644 kdm/kfrontend/CMakeLists.txt create mode 100644 kdm/kfrontend/Messages.sh create mode 100644 kdm/kfrontend/genkdmconf.c create mode 100644 kdm/kfrontend/kchooser.cpp create mode 100644 kdm/kfrontend/kchooser.h create mode 100644 kdm/kfrontend/kconsole.cpp create mode 100644 kdm/kfrontend/kconsole.h create mode 100644 kdm/kfrontend/kdm_config.c create mode 100644 kdm/kfrontend/kdm_greet.c create mode 100644 kdm/kfrontend/kdm_greet.h create mode 100644 kdm/kfrontend/kdmclock.cpp create mode 100644 kdm/kfrontend/kdmclock.h create mode 100644 kdm/kfrontend/kdmconfig.cpp create mode 100644 kdm/kfrontend/kdmconfig.h create mode 100644 kdm/kfrontend/kdmctl.c create mode 100644 kdm/kfrontend/kdmshutdown.cpp create mode 100644 kdm/kfrontend/kdmshutdown.h create mode 100644 kdm/kfrontend/kfdialog.cpp create mode 100644 kdm/kfrontend/kfdialog.h create mode 100644 kdm/kfrontend/kgapp.cpp create mode 100644 kdm/kfrontend/kgapp.h create mode 100644 kdm/kfrontend/kgdialog.cpp create mode 100644 kdm/kfrontend/kgdialog.h create mode 100644 kdm/kfrontend/kgreeter.cpp create mode 100644 kdm/kfrontend/kgreeter.h create mode 100644 kdm/kfrontend/kgverify.cpp create mode 100644 kdm/kfrontend/kgverify.h create mode 100644 kdm/kfrontend/krootimage.cpp create mode 100644 kdm/kfrontend/krootimage.h create mode 100644 kdm/kfrontend/pics/CMakeLists.txt create mode 100644 kdm/kfrontend/pics/default1.png create mode 100644 kdm/kfrontend/pics/default2.png create mode 100644 kdm/kfrontend/pics/default3.png create mode 100644 kdm/kfrontend/pics/kdelogo.png create mode 100644 kdm/kfrontend/pics/root1.png create mode 100644 kdm/kfrontend/pics/shutdown.png create mode 100644 kdm/kfrontend/pics/stripes.png create mode 100644 kdm/kfrontend/pics/stripes.png.desktop create mode 100644 kdm/kfrontend/sessions/9wm.desktop create mode 100644 kdm/kfrontend/sessions/CMakeLists.txt create mode 100644 kdm/kfrontend/sessions/aewm++.desktop create mode 100644 kdm/kfrontend/sessions/aewm.desktop create mode 100644 kdm/kfrontend/sessions/afterstep.desktop create mode 100644 kdm/kfrontend/sessions/amaterus.desktop create mode 100644 kdm/kfrontend/sessions/amiwm.desktop create mode 100644 kdm/kfrontend/sessions/asclassic.desktop create mode 100644 kdm/kfrontend/sessions/awesome.desktop create mode 100644 kdm/kfrontend/sessions/blackbox.desktop create mode 100644 kdm/kfrontend/sessions/cde.desktop create mode 100644 kdm/kfrontend/sessions/ctwm.desktop create mode 100644 kdm/kfrontend/sessions/cwwm.desktop create mode 100644 kdm/kfrontend/sessions/e16.desktop create mode 100644 kdm/kfrontend/sessions/enlightenment.desktop create mode 100644 kdm/kfrontend/sessions/evilwm.desktop create mode 100644 kdm/kfrontend/sessions/fluxbox.desktop create mode 100644 kdm/kfrontend/sessions/flwm.desktop create mode 100644 kdm/kfrontend/sessions/fvwm.desktop create mode 100644 kdm/kfrontend/sessions/fvwm95.desktop create mode 100644 kdm/kfrontend/sessions/gnome.desktop create mode 100644 kdm/kfrontend/sessions/golem.desktop create mode 100644 kdm/kfrontend/sessions/icewm.desktop create mode 100644 kdm/kfrontend/sessions/ion.desktop create mode 100644 kdm/kfrontend/sessions/kde-plasma-safe.desktop.cmake create mode 100644 kdm/kfrontend/sessions/kde-plasma.desktop.cmake create mode 100644 kdm/kfrontend/sessions/larswm.desktop create mode 100644 kdm/kfrontend/sessions/lwm.desktop create mode 100644 kdm/kfrontend/sessions/lxde.desktop create mode 100644 kdm/kfrontend/sessions/matchbox.desktop create mode 100644 kdm/kfrontend/sessions/metacity.desktop create mode 100644 kdm/kfrontend/sessions/mwm.desktop create mode 100644 kdm/kfrontend/sessions/olvwm.desktop create mode 100644 kdm/kfrontend/sessions/olwm.desktop create mode 100644 kdm/kfrontend/sessions/openbox.desktop create mode 100644 kdm/kfrontend/sessions/oroborus.desktop create mode 100644 kdm/kfrontend/sessions/phluid.desktop create mode 100644 kdm/kfrontend/sessions/pwm.desktop create mode 100644 kdm/kfrontend/sessions/qvwm.desktop create mode 100644 kdm/kfrontend/sessions/ratpoison.desktop create mode 100644 kdm/kfrontend/sessions/sapphire.desktop create mode 100644 kdm/kfrontend/sessions/sawfish.desktop create mode 100644 kdm/kfrontend/sessions/subtle.desktop create mode 100644 kdm/kfrontend/sessions/twm.desktop create mode 100644 kdm/kfrontend/sessions/ude.desktop create mode 100644 kdm/kfrontend/sessions/vtwm.desktop create mode 100644 kdm/kfrontend/sessions/w9wm.desktop create mode 100644 kdm/kfrontend/sessions/waimea.desktop create mode 100644 kdm/kfrontend/sessions/wm2.desktop create mode 100644 kdm/kfrontend/sessions/wmaker.desktop create mode 100644 kdm/kfrontend/sessions/xfce.desktop create mode 100644 kdm/kfrontend/sessions/xfce4.desktop create mode 100644 kdm/kfrontend/themer/kdmbutton.cpp create mode 100644 kdm/kfrontend/themer/kdmbutton.h create mode 100644 kdm/kfrontend/themer/kdmitem.cpp create mode 100644 kdm/kfrontend/themer/kdmitem.h create mode 100644 kdm/kfrontend/themer/kdmlabel.cpp create mode 100644 kdm/kfrontend/themer/kdmlabel.h create mode 100644 kdm/kfrontend/themer/kdmlayout.cpp create mode 100644 kdm/kfrontend/themer/kdmlayout.h create mode 100644 kdm/kfrontend/themer/kdmlist.cpp create mode 100644 kdm/kfrontend/themer/kdmlist.h create mode 100644 kdm/kfrontend/themer/kdmpixmap.cpp create mode 100644 kdm/kfrontend/themer/kdmpixmap.h create mode 100644 kdm/kfrontend/themer/kdmrect.cpp create mode 100644 kdm/kfrontend/themer/kdmrect.h create mode 100644 kdm/kfrontend/themer/kdmthemer.cpp create mode 100644 kdm/kfrontend/themer/kdmthemer.h create mode 100644 kdm/kfrontend/themer/parse.cpp create mode 100644 kdm/kfrontend/themer/parse.h create mode 100644 kdm/kfrontend/themes/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/ariya/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/ariya/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/ariya/ariya.xml create mode 100644 kdm/kfrontend/themes/ariya/lineedit_active.png create mode 100644 kdm/kfrontend/themes/ariya/lineedit_normal.png create mode 100644 kdm/kfrontend/themes/ariya/lock.png create mode 100644 kdm/kfrontend/themes/ariya/login_active.png create mode 100644 kdm/kfrontend/themes/ariya/login_normal.png create mode 100644 kdm/kfrontend/themes/ariya/pw_icon.png create mode 100644 kdm/kfrontend/themes/ariya/rectangle.png create mode 100644 kdm/kfrontend/themes/ariya/rectangle_overlay.png create mode 100644 kdm/kfrontend/themes/ariya/screenshot.png create mode 100644 kdm/kfrontend/themes/ariya/session_normal.png create mode 100644 kdm/kfrontend/themes/ariya/system_normal.png create mode 100644 kdm/kfrontend/themes/ariya/user_icon.png create mode 100644 kdm/kfrontend/themes/circles/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/circles/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/circles/background.svg create mode 100644 kdm/kfrontend/themes/circles/circles.xml create mode 100644 kdm/kfrontend/themes/circles/flower.png create mode 100644 kdm/kfrontend/themes/circles/help.png create mode 100644 kdm/kfrontend/themes/circles/options.png create mode 100644 kdm/kfrontend/themes/circles/screenshot.png create mode 100644 kdm/kfrontend/themes/elarun/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/elarun/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/elarun/elarun.xml create mode 100644 kdm/kfrontend/themes/elarun/lineedit_active.png create mode 100644 kdm/kfrontend/themes/elarun/lineedit_normal.png create mode 100644 kdm/kfrontend/themes/elarun/lock.png create mode 100644 kdm/kfrontend/themes/elarun/login_active.png create mode 100644 kdm/kfrontend/themes/elarun/login_normal.png create mode 100644 kdm/kfrontend/themes/elarun/pw_icon.png create mode 100644 kdm/kfrontend/themes/elarun/rectangle.png create mode 100644 kdm/kfrontend/themes/elarun/rectangle_overlay.png create mode 100644 kdm/kfrontend/themes/elarun/screenshot.png create mode 100644 kdm/kfrontend/themes/elarun/session_normal.png create mode 100644 kdm/kfrontend/themes/elarun/system_normal.png create mode 100644 kdm/kfrontend/themes/elarun/user_icon.png create mode 100644 kdm/kfrontend/themes/greeter.dtd create mode 100644 kdm/kfrontend/themes/horos/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/horos/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/horos/horos.xml create mode 100644 kdm/kfrontend/themes/horos/lineedit_active.png create mode 100644 kdm/kfrontend/themes/horos/lineedit_normal.png create mode 100644 kdm/kfrontend/themes/horos/lock.png create mode 100644 kdm/kfrontend/themes/horos/login_active.png create mode 100644 kdm/kfrontend/themes/horos/login_normal.png create mode 100644 kdm/kfrontend/themes/horos/pw_icon.png create mode 100644 kdm/kfrontend/themes/horos/rectangle.png create mode 100644 kdm/kfrontend/themes/horos/rectangle_overlay.png create mode 100644 kdm/kfrontend/themes/horos/screenshot.png create mode 100644 kdm/kfrontend/themes/horos/session_normal.png create mode 100644 kdm/kfrontend/themes/horos/system_normal.png create mode 100644 kdm/kfrontend/themes/horos/user_icon.png create mode 100644 kdm/kfrontend/themes/oxygen-air/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/oxygen-air/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/oxygen-air/caps.png create mode 100644 kdm/kfrontend/themes/oxygen-air/icon-kde.png create mode 100644 kdm/kfrontend/themes/oxygen-air/oxygen-air.xml create mode 100644 kdm/kfrontend/themes/oxygen-air/pw-entry.png create mode 100644 kdm/kfrontend/themes/oxygen-air/screenshot.png create mode 100644 kdm/kfrontend/themes/oxygen-air/session_button-li.png create mode 100644 kdm/kfrontend/themes/oxygen-air/session_button.png create mode 100644 kdm/kfrontend/themes/oxygen-air/system_button-li.png create mode 100644 kdm/kfrontend/themes/oxygen-air/system_button.png create mode 100644 kdm/kfrontend/themes/oxygen-air/user-entry.png create mode 100644 kdm/kfrontend/themes/oxygen-air/win-login.png create mode 100644 kdm/kfrontend/themes/oxygen/CMakeLists.txt create mode 100644 kdm/kfrontend/themes/oxygen/KdmGreeterTheme.desktop create mode 100644 kdm/kfrontend/themes/oxygen/background.svg create mode 100644 kdm/kfrontend/themes/oxygen/branding-icon.png create mode 100644 kdm/kfrontend/themes/oxygen/oxygen-box.svg create mode 100644 kdm/kfrontend/themes/oxygen/oxygen.svg create mode 100644 kdm/kfrontend/themes/oxygen/oxygen.xml create mode 100644 kdm/kfrontend/themes/oxygen/screenshot.png create mode 100644 kdm/kfrontend/themes/oxygen/session.png create mode 100644 kdm/kfrontend/themes/oxygen/system.png create mode 100644 kdm/kfrontend/utils.cpp create mode 100644 kdm/kfrontend/utils.h create mode 100644 khotkeys/AUTHORS create mode 100644 khotkeys/CMakeLists.txt create mode 100644 khotkeys/ExtraDesktop.sh create mode 100644 khotkeys/Messages.sh create mode 100644 khotkeys/TODO create mode 100644 khotkeys/app/CMakeLists.txt create mode 100644 khotkeys/app/kded.cpp create mode 100644 khotkeys/app/kded.h create mode 100644 khotkeys/app/khotkeys.desktop create mode 100644 khotkeys/data/CMakeLists.txt create mode 100644 khotkeys/data/defaults.khotkeys create mode 100644 khotkeys/data/kde32b1.khotkeys create mode 100644 khotkeys/data/konqueror_gestures_kde321.khotkeys create mode 100644 khotkeys/data/printscreen.khotkeys create mode 100644 khotkeys/kcm_hotkeys/CMakeLists.txt create mode 100644 khotkeys/kcm_hotkeys/action_group_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/action_group_widget.h create mode 100644 khotkeys/kcm_hotkeys/actions/action_widget_base.cpp create mode 100644 khotkeys/kcm_hotkeys/actions/action_widget_base.h create mode 100644 khotkeys/kcm_hotkeys/actions/command_url_action_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/actions/command_url_action_widget.h create mode 100644 khotkeys/kcm_hotkeys/actions/command_url_action_widget.ui create mode 100644 khotkeys/kcm_hotkeys/actions/dbus_action_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/actions/dbus_action_widget.h create mode 100644 khotkeys/kcm_hotkeys/actions/dbus_action_widget.ui create mode 100644 khotkeys/kcm_hotkeys/actions/keyboard_input_action_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/actions/keyboard_input_action_widget.h create mode 100644 khotkeys/kcm_hotkeys/actions/keyboard_input_action_widget.ui create mode 100644 khotkeys/kcm_hotkeys/actions/menuentry_action_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/actions/menuentry_action_widget.h create mode 100644 khotkeys/kcm_hotkeys/actions/menuentry_action_widget.ui create mode 100644 khotkeys/kcm_hotkeys/conditions/condition_type_menu.cpp create mode 100644 khotkeys/kcm_hotkeys/conditions/condition_type_menu.h create mode 100644 khotkeys/kcm_hotkeys/conditions/conditions_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/conditions/conditions_widget.h create mode 100644 khotkeys/kcm_hotkeys/conditions/conditions_widget.ui create mode 100644 khotkeys/kcm_hotkeys/global_settings_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/global_settings_widget.h create mode 100644 khotkeys/kcm_hotkeys/global_settings_widget.ui create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/edit_gesture_dialog.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/edit_gesture_dialog.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_drawer.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_drawer.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_recorder.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_recorder.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_widget.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/gesture_widget.ui create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_list_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_list_widget.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_list_widget.ui create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_widget.h create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_definition_widget.ui create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_selector.cpp create mode 100644 khotkeys/kcm_hotkeys/helper_widgets/window_selector.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_context_menu.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_context_menu.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_export_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_export_widget.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_export_widget.ui create mode 100644 khotkeys/kcm_hotkeys/hotkeys_model.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_model.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_proxy_model.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_proxy_model.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_tree_view.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_tree_view.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_widget_base.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_widget_base.h create mode 100644 khotkeys/kcm_hotkeys/hotkeys_widget_base.ui create mode 100644 khotkeys/kcm_hotkeys/hotkeys_widget_iface.cpp create mode 100644 khotkeys/kcm_hotkeys/hotkeys_widget_iface.h create mode 100644 khotkeys/kcm_hotkeys/kcm_hotkeys.cpp create mode 100644 khotkeys/kcm_hotkeys/kcm_hotkeys.h create mode 100644 khotkeys/kcm_hotkeys/kcm_hotkeys.ui create mode 100644 khotkeys/kcm_hotkeys/kcm_module_factory.cpp create mode 100644 khotkeys/kcm_hotkeys/kcm_module_factory.h create mode 100644 khotkeys/kcm_hotkeys/khotkeys.desktop create mode 100644 khotkeys/kcm_hotkeys/simple_action_data_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/simple_action_data_widget.h create mode 100644 khotkeys/kcm_hotkeys/triggers/gesture_trigger_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/triggers/gesture_trigger_widget.h create mode 100644 khotkeys/kcm_hotkeys/triggers/gesture_trigger_widget.ui create mode 100644 khotkeys/kcm_hotkeys/triggers/shortcut_trigger_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/triggers/shortcut_trigger_widget.h create mode 100644 khotkeys/kcm_hotkeys/triggers/shortcut_trigger_widget.ui create mode 100644 khotkeys/kcm_hotkeys/triggers/trigger_widget_base.cpp create mode 100644 khotkeys/kcm_hotkeys/triggers/trigger_widget_base.h create mode 100644 khotkeys/kcm_hotkeys/triggers/window_trigger_widget.cpp create mode 100644 khotkeys/kcm_hotkeys/triggers/window_trigger_widget.h create mode 100644 khotkeys/kcm_hotkeys/triggers/window_trigger_widget.ui create mode 100644 khotkeys/libkhotkeysprivate/CMakeLists.txt create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_base.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_base.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_group.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_group.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_visitor.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/action_data_visitor.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/generic_action_data.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/generic_action_data.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/menuentry_shortcut_action_data.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/menuentry_shortcut_action_data.h create mode 100644 khotkeys/libkhotkeysprivate/action_data/simple_action_data.cpp create mode 100644 khotkeys/libkhotkeysprivate/action_data/simple_action_data.h create mode 100644 khotkeys/libkhotkeysprivate/actions/action.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/action_list.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/action_visitor.h create mode 100644 khotkeys/libkhotkeysprivate/actions/actions.h create mode 100644 khotkeys/libkhotkeysprivate/actions/activate_window_action.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/command_url_action.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/dbus_action.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/keyboard_input_action.cpp create mode 100644 khotkeys/libkhotkeysprivate/actions/menuentry_action.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/active_window_condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/active_window_condition.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/and_condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/condition.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_list.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_list.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_list_base.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_list_base.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_visitor.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/conditions_visitor.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/existing_window_condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/existing_window_condition.h create mode 100644 khotkeys/libkhotkeysprivate/conditions/not_condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/conditions/or_condition.cpp create mode 100644 khotkeys/libkhotkeysprivate/daemon/daemon.cpp create mode 100644 khotkeys/libkhotkeysprivate/daemon/daemon.h create mode 100644 khotkeys/libkhotkeysprivate/input.h create mode 100644 khotkeys/libkhotkeysprivate/khotkeysglobal.cpp create mode 100644 khotkeys/libkhotkeysprivate/khotkeysglobal.h create mode 100644 khotkeys/libkhotkeysprivate/libkhotkeysfwd.h create mode 100644 khotkeys/libkhotkeysprivate/settings.cpp create mode 100644 khotkeys/libkhotkeysprivate/settings.h create mode 100644 khotkeys/libkhotkeysprivate/settings_reader_v2.cpp create mode 100644 khotkeys/libkhotkeysprivate/settings_reader_v2.h create mode 100644 khotkeys/libkhotkeysprivate/settings_writer.cpp create mode 100644 khotkeys/libkhotkeysprivate/settings_writer.h create mode 100644 khotkeys/libkhotkeysprivate/shortcuts_handler.cpp create mode 100644 khotkeys/libkhotkeysprivate/shortcuts_handler.h create mode 100644 khotkeys/libkhotkeysprivate/sound.cpp create mode 100644 khotkeys/libkhotkeysprivate/sound.h create mode 100644 khotkeys/libkhotkeysprivate/soundrecorder.cpp create mode 100644 khotkeys/libkhotkeysprivate/soundrecorder.h create mode 100644 khotkeys/libkhotkeysprivate/triggers/gesture_trigger.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/gestures.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/gestures.h create mode 100644 khotkeys/libkhotkeysprivate/triggers/shortcut_trigger.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/trigger.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/trigger_list.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/triggers.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/triggers.h create mode 100644 khotkeys/libkhotkeysprivate/triggers/voice_trigger.cpp create mode 100644 khotkeys/libkhotkeysprivate/triggers/window_trigger.cpp create mode 100644 khotkeys/libkhotkeysprivate/voices.cpp create mode 100644 khotkeys/libkhotkeysprivate/voices.h create mode 100644 khotkeys/libkhotkeysprivate/voicesignature.cpp create mode 100644 khotkeys/libkhotkeysprivate/voicesignature.h create mode 100644 khotkeys/libkhotkeysprivate/windows_handler.cpp create mode 100644 khotkeys/libkhotkeysprivate/windows_handler.h create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_interface.cpp create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_interface.h create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_list.cpp create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_list.h create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_rules.cpp create mode 100644 khotkeys/libkhotkeysprivate/windows_helper/window_selection_rules.h create mode 100644 khotkeys/test/CMakeLists.txt create mode 100644 khotkeys/test/kdedmodule_daemon_test.cpp create mode 100644 khotkeys/test/kdedmodule_daemon_test.h create mode 100644 kinfocenter/CMakeLists.txt create mode 100644 kinfocenter/Categories/CMakeLists.txt create mode 100644 kinfocenter/Categories/deviceinfocategory.desktop create mode 100644 kinfocenter/Categories/graphicalinfocategory.desktop create mode 100644 kinfocenter/Categories/kinfocentercategory.desktop create mode 100644 kinfocenter/Categories/lostfoundcategory.desktop create mode 100644 kinfocenter/Categories/networkinfocategory.desktop create mode 100644 kinfocenter/Messages.sh create mode 100644 kinfocenter/Modules/CMakeLists.txt create mode 100644 kinfocenter/Modules/base/CMakeLists.txt create mode 100644 kinfocenter/Modules/base/Messages.sh create mode 100644 kinfocenter/Modules/base/config-infocenter.h.cmake create mode 100644 kinfocenter/Modules/base/info_aix.cpp create mode 100644 kinfocenter/Modules/base/info_fbsd.cpp create mode 100644 kinfocenter/Modules/base/info_generic.cpp create mode 100644 kinfocenter/Modules/base/info_hpux.cpp create mode 100644 kinfocenter/Modules/base/info_linux.cpp create mode 100644 kinfocenter/Modules/base/info_netbsd.cpp create mode 100644 kinfocenter/Modules/base/info_openbsd.cpp create mode 100644 kinfocenter/Modules/base/info_osx.cpp create mode 100644 kinfocenter/Modules/base/info_sgi.cpp create mode 100644 kinfocenter/Modules/base/info_solaris.cpp create mode 100644 kinfocenter/Modules/base/os_base.h create mode 100644 kinfocenter/Modules/base/os_current.cpp create mode 100644 kinfocenter/Modules/base/os_current.h create mode 100644 kinfocenter/Modules/devinfo/CMakeLists.txt create mode 100644 kinfocenter/Modules/devinfo/Messages.sh create mode 100644 kinfocenter/Modules/devinfo/devicelisting.cpp create mode 100644 kinfocenter/Modules/devinfo/devicelisting.h create mode 100644 kinfocenter/Modules/devinfo/devinfo.cpp create mode 100644 kinfocenter/Modules/devinfo/devinfo.desktop create mode 100644 kinfocenter/Modules/devinfo/devinfo.h create mode 100644 kinfocenter/Modules/devinfo/infopanel.cpp create mode 100644 kinfocenter/Modules/devinfo/infopanel.h create mode 100644 kinfocenter/Modules/devinfo/nicsignals.cpp create mode 100644 kinfocenter/Modules/devinfo/nicsignals.h create mode 100644 kinfocenter/Modules/devinfo/qvlistlayout.cpp create mode 100644 kinfocenter/Modules/devinfo/qvlistlayout.h create mode 100644 kinfocenter/Modules/devinfo/soldevice.cpp create mode 100644 kinfocenter/Modules/devinfo/soldevice.h create mode 100644 kinfocenter/Modules/devinfo/soldevicetypes.cpp create mode 100644 kinfocenter/Modules/devinfo/soldevicetypes.h create mode 100644 kinfocenter/Modules/devinfo/solidhelper.cpp create mode 100644 kinfocenter/Modules/devinfo/solidhelper.h create mode 100644 kinfocenter/Modules/info/AUTHORS create mode 100644 kinfocenter/Modules/info/CMakeLists.txt create mode 100644 kinfocenter/Modules/info/Messages.sh create mode 100644 kinfocenter/Modules/info/dma.desktop create mode 100644 kinfocenter/Modules/info/info.cpp create mode 100644 kinfocenter/Modules/info/info.h create mode 100644 kinfocenter/Modules/info/interrupts.desktop create mode 100644 kinfocenter/Modules/info/ioports.desktop create mode 100644 kinfocenter/Modules/info/main.cpp create mode 100644 kinfocenter/Modules/info/scsi.desktop create mode 100644 kinfocenter/Modules/info/xserver.desktop create mode 100644 kinfocenter/Modules/infosummary/CMakeLists.txt create mode 100644 kinfocenter/Modules/infosummary/Messages.sh create mode 100644 kinfocenter/Modules/infosummary/defaultboxwidget.cpp create mode 100644 kinfocenter/Modules/infosummary/defaultboxwidget.h create mode 100644 kinfocenter/Modules/infosummary/infosum.cpp create mode 100644 kinfocenter/Modules/infosummary/infosum.h create mode 100644 kinfocenter/Modules/infosummary/kcm_infosummary.desktop create mode 100644 kinfocenter/Modules/infosummary/osdepinfo.cpp create mode 100644 kinfocenter/Modules/infosummary/osdepinfo.h create mode 100644 kinfocenter/Modules/infosummary/osdepinfo_unix.cpp create mode 100644 kinfocenter/Modules/infosummary/progressboxwidget.cpp create mode 100644 kinfocenter/Modules/infosummary/progressboxwidget.h create mode 100644 kinfocenter/Modules/memory/CMakeLists.txt create mode 100644 kinfocenter/Modules/memory/Messages.sh create mode 100644 kinfocenter/Modules/memory/base.h create mode 100644 kinfocenter/Modules/memory/chartWidget.cpp create mode 100644 kinfocenter/Modules/memory/chartWidget.h create mode 100644 kinfocenter/Modules/memory/kcm_memory.desktop create mode 100644 kinfocenter/Modules/memory/memory.cpp create mode 100644 kinfocenter/Modules/memory/memory.h create mode 100644 kinfocenter/Modules/memory/memory_fbsd.cpp create mode 100644 kinfocenter/Modules/memory/memory_hpux.cpp create mode 100644 kinfocenter/Modules/memory/memory_linux.cpp create mode 100644 kinfocenter/Modules/memory/memory_netbsd.cpp create mode 100644 kinfocenter/Modules/memory/memory_osx.cpp create mode 100644 kinfocenter/Modules/memory/memory_sgi.cpp create mode 100644 kinfocenter/Modules/memory/memory_solaris.cpp create mode 100644 kinfocenter/Modules/memory/memory_tru64.cpp create mode 100644 kinfocenter/Modules/memory/physicalMemoryChart.cpp create mode 100644 kinfocenter/Modules/memory/physicalMemoryChart.h create mode 100644 kinfocenter/Modules/memory/swapMemoryChart.cpp create mode 100644 kinfocenter/Modules/memory/swapMemoryChart.h create mode 100644 kinfocenter/Modules/memory/totalMemoryChart.cpp create mode 100644 kinfocenter/Modules/memory/totalMemoryChart.h create mode 100644 kinfocenter/Modules/nics/AUTHORS create mode 100644 kinfocenter/Modules/nics/CMakeLists.txt create mode 100644 kinfocenter/Modules/nics/Messages.sh create mode 100644 kinfocenter/Modules/nics/config-nic.h.cmake create mode 100644 kinfocenter/Modules/nics/nic.cpp create mode 100644 kinfocenter/Modules/nics/nic.desktop create mode 100644 kinfocenter/Modules/nics/nic.h create mode 100644 kinfocenter/Modules/opengl/CMakeLists.txt create mode 100644 kinfocenter/Modules/opengl/Messages.sh create mode 100644 kinfocenter/Modules/opengl/opengl.cpp create mode 100644 kinfocenter/Modules/opengl/opengl.desktop create mode 100644 kinfocenter/Modules/opengl/opengl.h create mode 100644 kinfocenter/Modules/opengl/opengl.ui create mode 100644 kinfocenter/Modules/opengl/openglconfig.h.cmake create mode 100644 kinfocenter/Modules/pci/CMakeLists.txt create mode 100644 kinfocenter/Modules/pci/Messages.sh create mode 100644 kinfocenter/Modules/pci/kcm_pci.cpp create mode 100644 kinfocenter/Modules/pci/kcm_pci.desktop create mode 100644 kinfocenter/Modules/pci/kcm_pci.h create mode 100644 kinfocenter/Modules/pci/kpci.cpp create mode 100644 kinfocenter/Modules/pci/kpci.h create mode 100644 kinfocenter/Modules/pci/kpci_private.h create mode 100644 kinfocenter/Modules/samba/AUTHORS create mode 100644 kinfocenter/Modules/samba/CMakeLists.txt create mode 100644 kinfocenter/Modules/samba/Messages.sh create mode 100644 kinfocenter/Modules/samba/kcmsambaimports.cpp create mode 100644 kinfocenter/Modules/samba/kcmsambaimports.h create mode 100644 kinfocenter/Modules/samba/kcmsambalog.cpp create mode 100644 kinfocenter/Modules/samba/kcmsambalog.h create mode 100644 kinfocenter/Modules/samba/kcmsambastatistics.cpp create mode 100644 kinfocenter/Modules/samba/kcmsambastatistics.h create mode 100644 kinfocenter/Modules/samba/ksmbstatus.cpp create mode 100644 kinfocenter/Modules/samba/ksmbstatus.h create mode 100644 kinfocenter/Modules/samba/main.cpp create mode 100644 kinfocenter/Modules/samba/smbstatus.desktop create mode 100644 kinfocenter/Modules/usbview/CMakeLists.txt create mode 100644 kinfocenter/Modules/usbview/Messages.sh create mode 100644 kinfocenter/Modules/usbview/classes.i18n create mode 100644 kinfocenter/Modules/usbview/kcmusb.cpp create mode 100644 kinfocenter/Modules/usbview/kcmusb.desktop create mode 100644 kinfocenter/Modules/usbview/kcmusb.h create mode 100644 kinfocenter/Modules/usbview/usb.ids create mode 100644 kinfocenter/Modules/usbview/usbdb.cpp create mode 100644 kinfocenter/Modules/usbview/usbdb.h create mode 100644 kinfocenter/Modules/usbview/usbdevices.cpp create mode 100644 kinfocenter/Modules/usbview/usbdevices.h create mode 100644 kinfocenter/Modules/view1394/CMakeLists.txt create mode 100644 kinfocenter/Modules/view1394/Messages.sh create mode 100644 kinfocenter/Modules/view1394/README create mode 100644 kinfocenter/Modules/view1394/kcmview1394.desktop create mode 100644 kinfocenter/Modules/view1394/oui.db create mode 100644 kinfocenter/Modules/view1394/view1394.cpp create mode 100644 kinfocenter/Modules/view1394/view1394.h create mode 100644 kinfocenter/Modules/view1394/view1394widget.ui create mode 100644 kinfocenter/ToolTips/ktooltip.cpp create mode 100644 kinfocenter/ToolTips/ktooltip.h create mode 100644 kinfocenter/ToolTips/ktooltipwindow.cpp create mode 100644 kinfocenter/ToolTips/ktooltipwindow_p.h create mode 100644 kinfocenter/ToolTips/tooltipmanager.cpp create mode 100644 kinfocenter/ToolTips/tooltipmanager.h create mode 100644 kinfocenter/infocenter.cpp create mode 100644 kinfocenter/infocenter.h create mode 100644 kinfocenter/infokcmmodel.cpp create mode 100644 kinfocenter/infokcmmodel.h create mode 100644 kinfocenter/infokcmproxymodel.cpp create mode 100644 kinfocenter/infokcmproxymodel.h create mode 100644 kinfocenter/kcmcategoryitem.cpp create mode 100644 kinfocenter/kcmcategoryitem.h create mode 100644 kinfocenter/kcmcontainer.cpp create mode 100644 kinfocenter/kcmcontainer.h create mode 100644 kinfocenter/kcmtreeitem.cpp create mode 100644 kinfocenter/kcmtreeitem.h create mode 100755 kinfocenter/kinfocenter.desktop create mode 100644 kinfocenter/kinfocenterui.rc create mode 100644 kinfocenter/main.cpp create mode 100644 kinfocenter/main.h create mode 100644 kinfocenter/sidepanel.cpp create mode 100644 kinfocenter/sidepanel.h create mode 100644 klipper/CMakeLists.txt create mode 100644 klipper/Messages.sh create mode 100644 klipper/actionsconfig.ui create mode 100644 klipper/actionstreewidget.cpp create mode 100644 klipper/actionstreewidget.h create mode 100644 klipper/clipcommandprocess.cpp create mode 100644 klipper/clipcommandprocess.h create mode 100644 klipper/configdialog.cpp create mode 100644 klipper/configdialog.h create mode 100644 klipper/editactiondialog.cpp create mode 100644 klipper/editactiondialog.h create mode 100644 klipper/editactiondialog.ui create mode 100644 klipper/generalconfig.ui create mode 100644 klipper/history.cpp create mode 100644 klipper/history.h create mode 100644 klipper/historyimageitem.cpp create mode 100644 klipper/historyimageitem.h create mode 100644 klipper/historyitem.cpp create mode 100644 klipper/historyitem.h create mode 100644 klipper/historystringitem.cpp create mode 100644 klipper/historystringitem.h create mode 100644 klipper/historyurlitem.cpp create mode 100644 klipper/historyurlitem.h create mode 100644 klipper/klipper-kconfigxt.upd create mode 100644 klipper/klipper.cpp create mode 100755 klipper/klipper.desktop create mode 100644 klipper/klipper.h create mode 100644 klipper/klipper.kcfg create mode 100644 klipper/klipperpopup.cpp create mode 100644 klipper/klipperpopup.h create mode 100644 klipper/klipperrc.desktop create mode 100644 klipper/klippersettings.kcfgc create mode 100644 klipper/main.cpp create mode 100644 klipper/popupproxy.cpp create mode 100644 klipper/popupproxy.h create mode 100644 klipper/tray.cpp create mode 100644 klipper/tray.h create mode 100644 klipper/urlgrabber.cpp create mode 100644 klipper/urlgrabber.h create mode 100644 klipper/version.h create mode 100644 kmenuedit/CMakeLists.txt create mode 100644 kmenuedit/Messages.sh create mode 100644 kmenuedit/basictab.cpp create mode 100644 kmenuedit/basictab.h create mode 100644 kmenuedit/hi16-app-kmenuedit.png create mode 100644 kmenuedit/hi22-app-kmenuedit.png create mode 100644 kmenuedit/hi32-app-kmenuedit.png create mode 100644 kmenuedit/hi48-app-kmenuedit.png create mode 100644 kmenuedit/khotkeys.cpp create mode 100644 kmenuedit/khotkeys.h create mode 100644 kmenuedit/klinespellchecking.cpp create mode 100644 kmenuedit/klinespellchecking.h create mode 100644 kmenuedit/kmenuedit.cpp create mode 100755 kmenuedit/kmenuedit.desktop create mode 100644 kmenuedit/kmenuedit.h create mode 100644 kmenuedit/kmenueditui.rc create mode 100644 kmenuedit/main.cpp create mode 100644 kmenuedit/menufile.cpp create mode 100644 kmenuedit/menufile.h create mode 100644 kmenuedit/menuinfo.cpp create mode 100644 kmenuedit/menuinfo.h create mode 100644 kmenuedit/org.kde.kmenuedit.xml create mode 100644 kmenuedit/pixmaps/CMakeLists.txt create mode 100644 kmenuedit/pixmaps/hi22-action-menu_new.png create mode 100644 kmenuedit/pixmaps/hi22-action-menu_new_sep.png create mode 100644 kmenuedit/pixmaps/hi32-action-menu_new.png create mode 100644 kmenuedit/pixmaps/hi32-action-menu_new_sep.png create mode 100644 kmenuedit/preferencesdlg.cpp create mode 100644 kmenuedit/preferencesdlg.h create mode 100644 kmenuedit/treeview.cpp create mode 100644 kmenuedit/treeview.h create mode 100644 krunner/CMakeLists.txt create mode 100644 krunner/HACKING create mode 100644 krunner/Messages.sh create mode 100644 krunner/README create mode 100644 krunner/configdialog.cpp create mode 100644 krunner/configdialog.h create mode 100644 krunner/dbus/org.kde.krunner.App.xml create mode 100644 krunner/dbus/org.kde.krunner.service.in create mode 100644 krunner/interfaceOptions.ui create mode 100644 krunner/interfaces/default/interface.cpp create mode 100644 krunner/interfaces/default/interface.h create mode 100644 krunner/interfaces/default/krunnerhistorycombobox.cpp create mode 100644 krunner/interfaces/default/krunnerhistorycombobox.h create mode 100644 krunner/interfaces/default/resultitem.cpp create mode 100644 krunner/interfaces/default/resultitem.h create mode 100644 krunner/interfaces/default/resultscene.cpp create mode 100644 krunner/interfaces/default/resultscene.h create mode 100644 krunner/interfaces/default/resultview.cpp create mode 100644 krunner/interfaces/default/resultview.h create mode 100644 krunner/interfaces/default/selectionbar.cpp create mode 100644 krunner/interfaces/default/selectionbar.h create mode 100644 krunner/interfaces/quicksand/qs_completionbox.cpp create mode 100644 krunner/interfaces/quicksand/qs_completionbox.h create mode 100644 krunner/interfaces/quicksand/qs_dialog.cpp create mode 100644 krunner/interfaces/quicksand/qs_dialog.h create mode 100644 krunner/interfaces/quicksand/qs_matchitem.cpp create mode 100644 krunner/interfaces/quicksand/qs_matchitem.h create mode 100644 krunner/interfaces/quicksand/qs_matchview.cpp create mode 100644 krunner/interfaces/quicksand/qs_matchview.h create mode 100644 krunner/interfaces/quicksand/qs_queryactionitem.cpp create mode 100644 krunner/interfaces/quicksand/qs_queryactionitem.h create mode 100644 krunner/interfaces/quicksand/qs_querymatchitem.cpp create mode 100644 krunner/interfaces/quicksand/qs_querymatchitem.h create mode 100644 krunner/interfaces/quicksand/qs_statusbar.cpp create mode 100644 krunner/interfaces/quicksand/qs_statusbar.h create mode 100644 krunner/kcfg/klaunch.kcfg create mode 100644 krunner/kcfg/klaunchsettings.kcfgc create mode 100644 krunner/kcfg/krunner.kcfg create mode 100644 krunner/kcfg/krunnersettings.kcfgc create mode 100644 krunner/krunner.desktop create mode 100644 krunner/krunnerapp.cpp create mode 100644 krunner/krunnerapp.h create mode 100644 krunner/krunnerdialog.cpp create mode 100644 krunner/krunnerdialog.h create mode 100644 krunner/ksystemactivitydialog.cpp create mode 100644 krunner/ksystemactivitydialog.h create mode 100644 krunner/main.cpp create mode 100644 krunner/startupid.cpp create mode 100644 krunner/startupid.h create mode 100644 kscreensaver.pamd create mode 100644 kscreensaver/CMakeLists.txt create mode 100644 kscreensaver/README create mode 100644 kscreensaver/kblank_screensaver/CMakeLists.txt create mode 100755 kscreensaver/kblank_screensaver/Messages.sh create mode 100644 kscreensaver/kblank_screensaver/blankscrn.cpp create mode 100644 kscreensaver/kblank_screensaver/blankscrn.h create mode 100644 kscreensaver/kblank_screensaver/kblank.desktop create mode 100644 kscreensaver/krandom_screensaver/CMakeLists.txt create mode 100644 kscreensaver/krandom_screensaver/Messages.sh create mode 100644 kscreensaver/krandom_screensaver/krandom.desktop create mode 100644 kscreensaver/krandom_screensaver/random.cpp create mode 100644 kscreensaver/krandom_screensaver/random.h create mode 100644 kscreensaver/libkscreensaver/CMakeLists.txt create mode 100644 kscreensaver/libkscreensaver/Messages.sh create mode 100644 kscreensaver/libkscreensaver/kscreensaver-kde3to4-porting.py create mode 100644 kscreensaver/libkscreensaver/kscreensaver.cpp create mode 100644 kscreensaver/libkscreensaver/kscreensaver.h create mode 100644 kscreensaver/libkscreensaver/kscreensaver_export.h create mode 100644 kscreensaver/libkscreensaver/kscreensaver_vroot.h create mode 100644 kscreensaver/libkscreensaver/main.cpp create mode 100644 kscreensaver/libkscreensaver/screensaver.desktop create mode 100644 ksmserver/CMakeLists.txt create mode 100644 ksmserver/Copyright.txt create mode 100644 ksmserver/KSMServerInterface.h create mode 100644 ksmserver/LICENSE create mode 100644 ksmserver/Messages.sh create mode 100644 ksmserver/README create mode 100644 ksmserver/client.cpp create mode 100644 ksmserver/client.h create mode 100644 ksmserver/config-ksmserver.h.cmake create mode 100644 ksmserver/curtaineffect.cpp create mode 100644 ksmserver/curtaineffect.h create mode 100644 ksmserver/fadeeffect.cpp create mode 100644 ksmserver/fadeeffect.h create mode 100644 ksmserver/global.h create mode 100644 ksmserver/kcheckrunning.cpp create mode 100644 ksmserver/kcm/CMakeLists.txt create mode 100644 ksmserver/kcm/Messages.sh create mode 100644 ksmserver/kcm/kcmsmserver.cpp create mode 100644 ksmserver/kcm/kcmsmserver.desktop create mode 100644 ksmserver/kcm/kcmsmserver.h create mode 100644 ksmserver/kcm/smserverconfigdlg.ui create mode 100644 ksmserver/kcm/smserverconfigimpl.cpp create mode 100644 ksmserver/kcm/smserverconfigimpl.h create mode 100644 ksmserver/ksmserver_shortcuts.upd create mode 100644 ksmserver/legacy.cpp create mode 100644 ksmserver/logouteffect.cpp create mode 100644 ksmserver/logouteffect.h create mode 100644 ksmserver/main.cpp create mode 100644 ksmserver/org.kde.KSMServerInterface.xml create mode 100644 ksmserver/screenlocker/CMakeLists.txt create mode 100644 ksmserver/screenlocker/DESIGN create mode 100644 ksmserver/screenlocker/Messages.sh create mode 100644 ksmserver/screenlocker/autologout.cpp create mode 100644 ksmserver/screenlocker/autologout.h create mode 100644 ksmserver/screenlocker/data/CMakeLists.txt create mode 100644 ksmserver/screenlocker/data/force_krunner_lock_shortcut_unreg.cpp create mode 100644 ksmserver/screenlocker/data/kscreenlocker_locksession-shortcut.upd create mode 100644 ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml create mode 100644 ksmserver/screenlocker/dbus/org.kde.screensaver.xml create mode 100644 ksmserver/screenlocker/greeter/CMakeLists.txt create mode 100644 ksmserver/screenlocker/greeter/Messages.sh create mode 100644 ksmserver/screenlocker/greeter/greeter.cpp create mode 100644 ksmserver/screenlocker/greeter/greeter.h create mode 100644 ksmserver/screenlocker/greeter/greeterapp.cpp create mode 100644 ksmserver/screenlocker/greeter/greeterapp.h create mode 100644 ksmserver/screenlocker/greeter/main.cpp create mode 100644 ksmserver/screenlocker/greeter/screensaverwindow.cpp create mode 100644 ksmserver/screenlocker/greeter/screensaverwindow.h create mode 100644 ksmserver/screenlocker/greeter/sessions.cpp create mode 100644 ksmserver/screenlocker/greeter/sessions.h create mode 100644 ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/AccelButton.qml create mode 100644 ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/Greeter.qml create mode 100644 ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/SessionSwitching.qml create mode 100644 ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/main.qml create mode 100644 ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/metadata.desktop create mode 100644 ksmserver/screenlocker/interface.cpp create mode 100644 ksmserver/screenlocker/interface.h create mode 100644 ksmserver/screenlocker/kcfg/kscreensaversettings.kcfg create mode 100644 ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc create mode 100644 ksmserver/screenlocker/kscreenlocker.notifyrc create mode 100644 ksmserver/screenlocker/ksldapp.cpp create mode 100644 ksmserver/screenlocker/ksldapp.h create mode 100644 ksmserver/screenlocker/lockwindow.cpp create mode 100644 ksmserver/screenlocker/lockwindow.h create mode 100644 ksmserver/server.cpp create mode 100644 ksmserver/server.h create mode 100644 ksmserver/shutdown.cpp create mode 100644 ksmserver/shutdowndlg.cpp create mode 100644 ksmserver/shutdowndlg.h create mode 100644 ksmserver/startup.cpp create mode 100644 ksmserver/tests/CMakeLists.txt create mode 100644 ksmserver/tests/test.cpp create mode 100644 ksmserver/themes/contour/ContourButton.qml create mode 100644 ksmserver/themes/contour/main.qml create mode 100644 ksmserver/themes/contour/metadata.desktop create mode 100644 ksmserver/themes/contour/screenshot.png create mode 100644 ksmserver/themes/default/ContextMenu.qml create mode 100644 ksmserver/themes/default/KSMButton.qml create mode 100644 ksmserver/themes/default/MenuItem.qml create mode 100644 ksmserver/themes/default/helper.js create mode 100644 ksmserver/themes/default/main.qml create mode 100644 ksmserver/themes/default/metadata.desktop create mode 100644 ksmserver/themes/default/screenshot.png create mode 100644 ksplash/CMakeLists.txt create mode 100644 ksplash/README create mode 100644 ksplash/kcm/CMakeLists.txt create mode 100644 ksplash/kcm/Messages.sh create mode 100644 ksplash/kcm/installer.cpp create mode 100644 ksplash/kcm/installer.h create mode 100644 ksplash/kcm/ksplash.knsrc create mode 100644 ksplash/kcm/ksplashthememgr.desktop create mode 100644 ksplash/kcm/main.cpp create mode 100644 ksplash/kcm/pics/CMakeLists.txt create mode 100644 ksplash/kcm/pics/hi128-app-ksplash.png create mode 100644 ksplash/kcm/pics/hi16-app-ksplash.png create mode 100644 ksplash/kcm/pics/hi22-app-ksplash.png create mode 100644 ksplash/kcm/pics/hi32-app-ksplash.png create mode 100644 ksplash/kcm/pics/hi48-app-ksplash.png create mode 100644 ksplash/kcm/pics/hi64-app-ksplash.png create mode 100644 ksplash/ksplashqml/CMakeLists.txt create mode 100644 ksplash/ksplashqml/SplashApp.cpp create mode 100644 ksplash/ksplashqml/SplashApp.h create mode 100644 ksplash/ksplashqml/SplashWindow.cpp create mode 100644 ksplash/ksplashqml/SplashWindow.h create mode 100644 ksplash/ksplashqml/SystemInfo.h create mode 100644 ksplash/ksplashqml/main.cpp create mode 100644 ksplash/ksplashqml/themes/CMakeLists.txt create mode 100644 ksplash/ksplashqml/themes/Minimalistic/CMakeLists.txt create mode 100644 ksplash/ksplashqml/themes/Minimalistic/Preview.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/Theme.rc create mode 100644 ksplash/ksplashqml/themes/Minimalistic/images/kdegear.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/images/kdeletter.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/images/kdelogo-contrast.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/images/kdelogo.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/images/kdemask.png create mode 100644 ksplash/ksplashqml/themes/Minimalistic/main.qml create mode 100644 ksplash/ksplashx/CMakeLists.txt create mode 100644 ksplash/ksplashx/LICENSE create mode 100644 ksplash/ksplashx/README create mode 100644 ksplash/ksplashx/asm_scale.S create mode 100644 ksplash/ksplashx/defs.cpp create mode 100644 ksplash/ksplashx/defs.h create mode 100644 ksplash/ksplashx/kcpuinfo.cpp create mode 100644 ksplash/ksplashx/kcpuinfo.h create mode 100644 ksplash/ksplashx/main.cpp create mode 100644 ksplash/ksplashx/pixmap.cpp create mode 100644 ksplash/ksplashx/pixmap.h create mode 100644 ksplash/ksplashx/qcolor.cpp create mode 100644 ksplash/ksplashx/qcolor.h create mode 100644 ksplash/ksplashx/qcolor_p.cpp create mode 100644 ksplash/ksplashx/qcolor_p.h create mode 100644 ksplash/ksplashx/qcolor_x11.cpp create mode 100644 ksplash/ksplashx/qdatastream.h create mode 100644 ksplash/ksplashx/qglobal.cpp create mode 100644 ksplash/ksplashx/qglobal.h create mode 100644 ksplash/ksplashx/qimage.cpp create mode 100644 ksplash/ksplashx/qimage.h create mode 100644 ksplash/ksplashx/qjpegio.cpp create mode 100644 ksplash/ksplashx/qnamespace.h create mode 100644 ksplash/ksplashx/qpngio.cpp create mode 100644 ksplash/ksplashx/qpoint.h create mode 100644 ksplash/ksplashx/qrect.cpp create mode 100644 ksplash/ksplashx/qrect.h create mode 100644 ksplash/ksplashx/qshared.h create mode 100644 ksplash/ksplashx/qsize.cpp create mode 100644 ksplash/ksplashx/qsize.h create mode 100644 ksplash/ksplashx/qwindowdefs.h create mode 100644 ksplash/ksplashx/qwinexport.h create mode 100644 ksplash/ksplashx/scale.cpp create mode 100644 ksplash/ksplashx/scale.h create mode 100644 ksplash/ksplashx/scale/CMakeLists.txt create mode 100644 ksplash/ksplashx/scale/main.cpp create mode 100644 ksplash/ksplashx/splash.cpp create mode 100644 ksplash/ksplashx/splash.h create mode 100644 ksplash/ksplashx/utils/CMakeLists.txt create mode 100755 ksplash/ksplashx/utils/blend.py create mode 100755 ksplash/ksplashx/utils/fromksplashmldefault.sh create mode 100644 ksplash/ksplashx/utils/prepareanim.cpp create mode 100644 ksplash/ksplashx/utils/shade.cpp create mode 100644 ksplash/ksplashx/x11_defs.cpp create mode 100644 ksplash/ksplashx/x11_defs.h create mode 100644 ksplash/none/CMakeLists.txt create mode 100644 ksplash/none/Theme.rc create mode 100644 ksplash/simple/CMakeLists.txt create mode 100644 ksplash/simple/full/CMakeLists.txt create mode 100644 ksplash/simple/full/Preview.png create mode 100644 ksplash/simple/full/Theme.rc create mode 100644 ksplash/simple/main.cpp create mode 100644 ksplash/simple/small/CMakeLists.txt create mode 100644 ksplash/simple/small/Preview.png create mode 100644 ksplash/simple/small/Theme.rc create mode 100644 kstartupconfig/CMakeLists.txt create mode 100644 kstartupconfig/kdostartupconfig.cpp create mode 100644 kstartupconfig/kstartupconfig.c create mode 100644 kstyles/CMakeLists.txt create mode 100644 kstyles/Mainpage.dox create mode 100644 kstyles/Messages.sh create mode 100644 kstyles/oxygen/CMakeLists.txt create mode 100644 kstyles/oxygen/README create mode 100644 kstyles/oxygen/animations/oxygenanimationdata.cpp create mode 100644 kstyles/oxygen/animations/oxygenanimationdata.h create mode 100644 kstyles/oxygen/animations/oxygenanimations.cpp create mode 100644 kstyles/oxygen/animations/oxygenanimations.h create mode 100644 kstyles/oxygen/animations/oxygenbaseengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenbaseengine.h create mode 100644 kstyles/oxygen/animations/oxygendatamap.h create mode 100644 kstyles/oxygen/animations/oxygendockseparatordata.cpp create mode 100644 kstyles/oxygen/animations/oxygendockseparatordata.h create mode 100644 kstyles/oxygen/animations/oxygendockseparatorengine.cpp create mode 100644 kstyles/oxygen/animations/oxygendockseparatorengine.h create mode 100644 kstyles/oxygen/animations/oxygenenabledata.cpp create mode 100644 kstyles/oxygen/animations/oxygenenabledata.h create mode 100644 kstyles/oxygen/animations/oxygengenericdata.cpp create mode 100644 kstyles/oxygen/animations/oxygengenericdata.h create mode 100644 kstyles/oxygen/animations/oxygenheaderviewdata.cpp create mode 100644 kstyles/oxygen/animations/oxygenheaderviewdata.h create mode 100644 kstyles/oxygen/animations/oxygenheaderviewengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenheaderviewengine.h create mode 100644 kstyles/oxygen/animations/oxygenmdiwindowdata.cpp create mode 100644 kstyles/oxygen/animations/oxygenmdiwindowdata.h create mode 100644 kstyles/oxygen/animations/oxygenmdiwindowengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenmdiwindowengine.h create mode 100644 kstyles/oxygen/animations/oxygenmenubardata.cpp create mode 100644 kstyles/oxygen/animations/oxygenmenubardata.h create mode 100644 kstyles/oxygen/animations/oxygenmenubardata_imp.h create mode 100644 kstyles/oxygen/animations/oxygenmenubarengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenmenubarengine.h create mode 100644 kstyles/oxygen/animations/oxygenmenudata.cpp create mode 100644 kstyles/oxygen/animations/oxygenmenudata.h create mode 100644 kstyles/oxygen/animations/oxygenmenuengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenmenuengine.h create mode 100644 kstyles/oxygen/animations/oxygenprogressbardata.cpp create mode 100644 kstyles/oxygen/animations/oxygenprogressbardata.h create mode 100644 kstyles/oxygen/animations/oxygenprogressbarengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenprogressbarengine.h create mode 100644 kstyles/oxygen/animations/oxygenscrollbardata.cpp create mode 100644 kstyles/oxygen/animations/oxygenscrollbardata.h create mode 100644 kstyles/oxygen/animations/oxygenscrollbarengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenscrollbarengine.h create mode 100644 kstyles/oxygen/animations/oxygensliderdata.cpp create mode 100644 kstyles/oxygen/animations/oxygensliderdata.h create mode 100644 kstyles/oxygen/animations/oxygensliderengine.cpp create mode 100644 kstyles/oxygen/animations/oxygensliderengine.h create mode 100644 kstyles/oxygen/animations/oxygenspinboxdata.cpp create mode 100644 kstyles/oxygen/animations/oxygenspinboxdata.h create mode 100644 kstyles/oxygen/animations/oxygenspinboxengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenspinboxengine.h create mode 100644 kstyles/oxygen/animations/oxygensplitterengine.cpp create mode 100644 kstyles/oxygen/animations/oxygensplitterengine.h create mode 100644 kstyles/oxygen/animations/oxygentabbardata.cpp create mode 100644 kstyles/oxygen/animations/oxygentabbardata.h create mode 100644 kstyles/oxygen/animations/oxygentabbarengine.cpp create mode 100644 kstyles/oxygen/animations/oxygentabbarengine.h create mode 100644 kstyles/oxygen/animations/oxygentoolbardata.cpp create mode 100644 kstyles/oxygen/animations/oxygentoolbardata.h create mode 100644 kstyles/oxygen/animations/oxygentoolbarengine.cpp create mode 100644 kstyles/oxygen/animations/oxygentoolbarengine.h create mode 100644 kstyles/oxygen/animations/oxygentoolboxengine.cpp create mode 100644 kstyles/oxygen/animations/oxygentoolboxengine.h create mode 100644 kstyles/oxygen/animations/oxygenwidgetstatedata.cpp create mode 100644 kstyles/oxygen/animations/oxygenwidgetstatedata.h create mode 100644 kstyles/oxygen/animations/oxygenwidgetstateengine.cpp create mode 100644 kstyles/oxygen/animations/oxygenwidgetstateengine.h create mode 100644 kstyles/oxygen/config/CMakeLists.txt create mode 100644 kstyles/oxygen/config/main.cpp create mode 100644 kstyles/oxygen/config/oxygenanimationconfigwidget.cpp create mode 100644 kstyles/oxygen/config/oxygenanimationconfigwidget.h create mode 100644 kstyles/oxygen/config/oxygenconfigdialog.cpp create mode 100644 kstyles/oxygen/config/oxygenconfigdialog.h create mode 100644 kstyles/oxygen/config/oxygenfollowmouseanimationconfigitem.cpp create mode 100644 kstyles/oxygen/config/oxygenfollowmouseanimationconfigitem.h create mode 100644 kstyles/oxygen/config/oxygenstyleconfig.cpp create mode 100644 kstyles/oxygen/config/oxygenstyleconfig.h create mode 100644 kstyles/oxygen/config/ui/oxygenfollowmouseanimationconfigbox.ui create mode 100644 kstyles/oxygen/config/ui/oxygenstyleconfig.ui create mode 100644 kstyles/oxygen/debug/oxygenwidgetexplorer.cpp create mode 100644 kstyles/oxygen/debug/oxygenwidgetexplorer.h create mode 100644 kstyles/oxygen/demo/CMakeLists.txt create mode 100644 kstyles/oxygen/demo/main.cpp create mode 100644 kstyles/oxygen/demo/oxygenbenchmarkwidget.cpp create mode 100644 kstyles/oxygen/demo/oxygenbenchmarkwidget.h create mode 100644 kstyles/oxygen/demo/oxygenbuttondemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygenbuttondemowidget.h create mode 100644 kstyles/oxygen/demo/oxygendemodialog.cpp create mode 100644 kstyles/oxygen/demo/oxygendemodialog.h create mode 100644 kstyles/oxygen/demo/oxygendemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygendemowidget.h create mode 100644 kstyles/oxygen/demo/oxygenframedemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygenframedemowidget.h create mode 100644 kstyles/oxygen/demo/oxygeninputdemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygeninputdemowidget.h create mode 100644 kstyles/oxygen/demo/oxygenlistdemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygenlistdemowidget.h create mode 100644 kstyles/oxygen/demo/oxygenmdidemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygenmdidemowidget.h create mode 100644 kstyles/oxygen/demo/oxygensimulator.cpp create mode 100644 kstyles/oxygen/demo/oxygensimulator.h create mode 100644 kstyles/oxygen/demo/oxygensliderdemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygensliderdemowidget.h create mode 100644 kstyles/oxygen/demo/oxygentabdemowidget.cpp create mode 100644 kstyles/oxygen/demo/oxygentabdemowidget.h create mode 100644 kstyles/oxygen/demo/oxygentabwidget.h create mode 100644 kstyles/oxygen/demo/ui/oxygenbenchmarkwidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygenbuttondemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygenframedemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygeninputdemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygenlistdemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygenmdidemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygensliderdemowidget.ui create mode 100644 kstyles/oxygen/demo/ui/oxygentabdemowidget.ui create mode 100644 kstyles/oxygen/oxygen.kcfg create mode 100644 kstyles/oxygen/oxygen.themerc create mode 100644 kstyles/oxygen/oxygenaddeventfilter.h create mode 100644 kstyles/oxygen/oxygenanimationmodes.h create mode 100644 kstyles/oxygen/oxygenblurhelper.cpp create mode 100644 kstyles/oxygen/oxygenblurhelper.h create mode 100644 kstyles/oxygen/oxygenframeshadow.cpp create mode 100644 kstyles/oxygen/oxygenframeshadow.h create mode 100644 kstyles/oxygen/oxygenmdiwindowshadow.cpp create mode 100644 kstyles/oxygen/oxygenmdiwindowshadow.h create mode 100644 kstyles/oxygen/oxygenmetrics.h create mode 100644 kstyles/oxygen/oxygenmnemonics.cpp create mode 100644 kstyles/oxygen/oxygenmnemonics.h create mode 100644 kstyles/oxygen/oxygenpropertynames.cpp create mode 100644 kstyles/oxygen/oxygenpropertynames.h create mode 100644 kstyles/oxygen/oxygenshadowhelper.cpp create mode 100644 kstyles/oxygen/oxygenshadowhelper.h create mode 100644 kstyles/oxygen/oxygensplitterproxy.cpp create mode 100644 kstyles/oxygen/oxygensplitterproxy.h create mode 100644 kstyles/oxygen/oxygenstyle.cpp create mode 100644 kstyles/oxygen/oxygenstyle.h create mode 100644 kstyles/oxygen/oxygenstyleconfigdata.kcfgc create mode 100644 kstyles/oxygen/oxygenstylehelper.cpp create mode 100644 kstyles/oxygen/oxygenstylehelper.h create mode 100644 kstyles/oxygen/oxygenwindowmanager.cpp create mode 100644 kstyles/oxygen/oxygenwindowmanager.h create mode 100644 kstyles/oxygen/transitions/oxygencomboboxdata.cpp create mode 100644 kstyles/oxygen/transitions/oxygencomboboxdata.h create mode 100644 kstyles/oxygen/transitions/oxygencomboboxengine.cpp create mode 100644 kstyles/oxygen/transitions/oxygencomboboxengine.h create mode 100644 kstyles/oxygen/transitions/oxygenlabeldata.cpp create mode 100644 kstyles/oxygen/transitions/oxygenlabeldata.h create mode 100644 kstyles/oxygen/transitions/oxygenlabelengine.cpp create mode 100644 kstyles/oxygen/transitions/oxygenlabelengine.h create mode 100644 kstyles/oxygen/transitions/oxygenlineeditdata.cpp create mode 100644 kstyles/oxygen/transitions/oxygenlineeditdata.h create mode 100644 kstyles/oxygen/transitions/oxygenlineeditengine.cpp create mode 100644 kstyles/oxygen/transitions/oxygenlineeditengine.h create mode 100644 kstyles/oxygen/transitions/oxygenstackedwidgetdata.cpp create mode 100644 kstyles/oxygen/transitions/oxygenstackedwidgetdata.h create mode 100644 kstyles/oxygen/transitions/oxygenstackedwidgetengine.cpp create mode 100644 kstyles/oxygen/transitions/oxygenstackedwidgetengine.h create mode 100644 kstyles/oxygen/transitions/oxygentransitiondata.cpp create mode 100644 kstyles/oxygen/transitions/oxygentransitiondata.h create mode 100644 kstyles/oxygen/transitions/oxygentransitions.cpp create mode 100644 kstyles/oxygen/transitions/oxygentransitions.h create mode 100644 kstyles/oxygen/transitions/oxygentransitionwidget.cpp create mode 100644 kstyles/oxygen/transitions/oxygentransitionwidget.h create mode 100644 kstyles/themes/CMakeLists.txt create mode 100644 kstyles/themes/b3.themerc create mode 100644 kstyles/themes/beos.themerc create mode 100644 kstyles/themes/default.themerc create mode 100644 kstyles/themes/highcolor.themerc create mode 100644 kstyles/themes/keramik.themerc create mode 100644 kstyles/themes/light-v2.themerc create mode 100644 kstyles/themes/light-v3.themerc create mode 100644 kstyles/themes/mega.themerc create mode 100644 kstyles/themes/qtcde.themerc create mode 100644 kstyles/themes/qtcleanlooks.themerc create mode 100644 kstyles/themes/qtgtk.themerc create mode 100644 kstyles/themes/qtmacintosh.themerc create mode 100644 kstyles/themes/qtmotif.themerc create mode 100644 kstyles/themes/qtmotifplus.themerc create mode 100644 kstyles/themes/qtplastique.themerc create mode 100644 kstyles/themes/qtplatinum.themerc create mode 100644 kstyles/themes/qtsgi.themerc create mode 100644 kstyles/themes/qtwindows.themerc create mode 100644 kstyles/themes/qtwindowsvista.themerc create mode 100644 kstyles/themes/qtwindowsxp.themerc create mode 100644 ksysguard/CMakeLists.txt create mode 100644 ksysguard/README create mode 100644 ksysguard/example/CMakeLists.txt create mode 100644 ksysguard/example/ksysguard.notifyrc create mode 100644 ksysguard/example/ksysguarddrc create mode 100644 ksysguard/gui/CMakeLists.txt create mode 100644 ksysguard/gui/HostConnector.cpp create mode 100644 ksysguard/gui/HostConnector.h create mode 100644 ksysguard/gui/Messages.sh create mode 100644 ksysguard/gui/ProcessTable.sgrd create mode 100644 ksysguard/gui/SensorBrowser.cpp create mode 100644 ksysguard/gui/SensorBrowser.h create mode 100644 ksysguard/gui/SensorDisplayLib/BarGraph.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/BarGraph.h create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBars.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBars.h create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBarsSettings.h create mode 100644 ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/DummyDisplay.h create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotter.h create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.h create mode 100644 ksysguard/gui/SensorDisplayLib/ListView.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/ListView.h create mode 100644 ksysguard/gui/SensorDisplayLib/ListViewSettings.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/ListViewSettings.h create mode 100644 ksysguard/gui/SensorDisplayLib/ListViewSettingsWidget.ui create mode 100644 ksysguard/gui/SensorDisplayLib/LogFile.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/LogFile.h create mode 100644 ksysguard/gui/SensorDisplayLib/LogFileSettings.ui create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeter.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeter.h create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeterSettings.h create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeterSettingsWidget.ui create mode 100644 ksysguard/gui/SensorDisplayLib/ProcessController.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/ProcessController.h create mode 100644 ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/SensorDisplay.h create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLogger.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLogger.h create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.h create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerDlgWidget.ui create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.h create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerSettingsWidget.ui create mode 100644 ksysguard/gui/SensorDisplayLib/SensorModel.cpp create mode 100644 ksysguard/gui/SensorDisplayLib/SensorModel.h create mode 100644 ksysguard/gui/SharedSettings.h create mode 100644 ksysguard/gui/SignalIDs.h create mode 100644 ksysguard/gui/StyleEngine.cpp create mode 100644 ksysguard/gui/StyleEngine.h create mode 100644 ksysguard/gui/SystemLoad2.sgrd create mode 100644 ksysguard/gui/TimerSettings.cpp create mode 100644 ksysguard/gui/TimerSettings.h create mode 100644 ksysguard/gui/WorkSheet.cpp create mode 100644 ksysguard/gui/WorkSheet.h create mode 100644 ksysguard/gui/WorkSheetSettings.cpp create mode 100644 ksysguard/gui/WorkSheetSettings.h create mode 100644 ksysguard/gui/Workspace.cpp create mode 100644 ksysguard/gui/Workspace.h create mode 100644 ksysguard/gui/ksortfilterproxymodel.cpp create mode 100644 ksysguard/gui/ksortfilterproxymodel.h create mode 100644 ksysguard/gui/ksysguard.cpp create mode 100755 ksysguard/gui/ksysguard.desktop create mode 100644 ksysguard/gui/ksysguard.h create mode 100644 ksysguard/gui/ksysguard.knsrc create mode 100644 ksysguard/gui/ksysguardui.rc create mode 100644 ksysguard/gui/tests/CMakeLists.txt create mode 100644 ksysguard/gui/tests/ksysguarddtest.cpp create mode 100644 ksysguard/gui/tests/ksysguarddtest.h create mode 100644 ksysguard/ksysguardd/CContLib/ccont.c create mode 100644 ksysguard/ksysguardd/CContLib/ccont.h create mode 100644 ksysguard/ksysguardd/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/Command.c create mode 100644 ksysguard/ksysguardd/Command.h create mode 100644 ksysguard/ksysguardd/FreeBSD/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/FreeBSD/ChangeLog create mode 100644 ksysguard/ksysguardd/FreeBSD/Memory.c create mode 100644 ksysguard/ksysguardd/FreeBSD/Memory.h create mode 100644 ksysguard/ksysguardd/FreeBSD/ProcessList.c create mode 100644 ksysguard/ksysguardd/FreeBSD/ProcessList.h create mode 100644 ksysguard/ksysguardd/FreeBSD/TODO create mode 100644 ksysguard/ksysguardd/FreeBSD/acpi.c create mode 100644 ksysguard/ksysguardd/FreeBSD/acpi.h create mode 100644 ksysguard/ksysguardd/FreeBSD/apm.c create mode 100644 ksysguard/ksysguardd/FreeBSD/apm.h create mode 100644 ksysguard/ksysguardd/FreeBSD/cpuinfo.c create mode 100644 ksysguard/ksysguardd/FreeBSD/cpuinfo.h create mode 100644 ksysguard/ksysguardd/FreeBSD/diskstat.c create mode 100644 ksysguard/ksysguardd/FreeBSD/diskstat.h create mode 100644 ksysguard/ksysguardd/FreeBSD/loadavg.c create mode 100644 ksysguard/ksysguardd/FreeBSD/loadavg.h create mode 100644 ksysguard/ksysguardd/FreeBSD/logfile.c create mode 100644 ksysguard/ksysguardd/FreeBSD/logfile.h create mode 100644 ksysguard/ksysguardd/FreeBSD/netdev.c create mode 100644 ksysguard/ksysguardd/FreeBSD/netdev.h create mode 100644 ksysguard/ksysguardd/FreeBSD/stat.c create mode 100644 ksysguard/ksysguardd/FreeBSD/stat.h create mode 100644 ksysguard/ksysguardd/FreeBSD/uptime.c create mode 100644 ksysguard/ksysguardd/FreeBSD/uptime.h create mode 100644 ksysguard/ksysguardd/GNU/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/GNU/dummy.cpp create mode 100644 ksysguard/ksysguardd/Irix/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/Irix/LoadAvg.c create mode 100644 ksysguard/ksysguardd/Irix/LoadAvg.h create mode 100644 ksysguard/ksysguardd/Irix/Memory.c create mode 100644 ksysguard/ksysguardd/Irix/Memory.h create mode 100644 ksysguard/ksysguardd/Irix/NetDev.c create mode 100644 ksysguard/ksysguardd/Irix/NetDev.h create mode 100644 ksysguard/ksysguardd/Irix/ProcessList.c create mode 100644 ksysguard/ksysguardd/Irix/ProcessList.h create mode 100644 ksysguard/ksysguardd/Irix/cpu.c create mode 100644 ksysguard/ksysguardd/Irix/cpu.h create mode 100644 ksysguard/ksysguardd/Linux/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/Linux/Memory.c create mode 100644 ksysguard/ksysguardd/Linux/Memory.h create mode 100644 ksysguard/ksysguardd/Linux/ProcessList.c create mode 100644 ksysguard/ksysguardd/Linux/ProcessList.h create mode 100644 ksysguard/ksysguardd/Linux/acpi.c create mode 100644 ksysguard/ksysguardd/Linux/acpi.h create mode 100644 ksysguard/ksysguardd/Linux/apm.c create mode 100644 ksysguard/ksysguardd/Linux/apm.h create mode 100644 ksysguard/ksysguardd/Linux/cpuinfo.c create mode 100644 ksysguard/ksysguardd/Linux/cpuinfo.h create mode 100644 ksysguard/ksysguardd/Linux/diskstat.c create mode 100644 ksysguard/ksysguardd/Linux/diskstat.h create mode 100644 ksysguard/ksysguardd/Linux/diskstats.c create mode 100644 ksysguard/ksysguardd/Linux/diskstats.h create mode 100644 ksysguard/ksysguardd/Linux/i8k.c create mode 100644 ksysguard/ksysguardd/Linux/i8k.h create mode 100644 ksysguard/ksysguardd/Linux/lmsensors.c create mode 100644 ksysguard/ksysguardd/Linux/lmsensors.h create mode 100644 ksysguard/ksysguardd/Linux/loadavg.c create mode 100644 ksysguard/ksysguardd/Linux/loadavg.h create mode 100644 ksysguard/ksysguardd/Linux/logfile.c create mode 100644 ksysguard/ksysguardd/Linux/logfile.h create mode 100644 ksysguard/ksysguardd/Linux/netdev.c create mode 100644 ksysguard/ksysguardd/Linux/netdev.h create mode 100644 ksysguard/ksysguardd/Linux/netstat.c create mode 100644 ksysguard/ksysguardd/Linux/netstat.h create mode 100644 ksysguard/ksysguardd/Linux/softraid.c create mode 100644 ksysguard/ksysguardd/Linux/softraid.h create mode 100644 ksysguard/ksysguardd/Linux/stat.c create mode 100644 ksysguard/ksysguardd/Linux/stat.h create mode 100644 ksysguard/ksysguardd/Linux/uptime.c create mode 100644 ksysguard/ksysguardd/Linux/uptime.h create mode 100644 ksysguard/ksysguardd/NetBSD/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/NetBSD/CPU.c create mode 100644 ksysguard/ksysguardd/NetBSD/CPU.h create mode 100644 ksysguard/ksysguardd/NetBSD/Memory.c create mode 100644 ksysguard/ksysguardd/NetBSD/Memory.h create mode 100644 ksysguard/ksysguardd/NetBSD/ProcessList.c create mode 100644 ksysguard/ksysguardd/NetBSD/ProcessList.h create mode 100644 ksysguard/ksysguardd/NetBSD/apm.c create mode 100644 ksysguard/ksysguardd/NetBSD/apm.h create mode 100644 ksysguard/ksysguardd/NetBSD/diskstat.c create mode 100644 ksysguard/ksysguardd/NetBSD/diskstat.h create mode 100644 ksysguard/ksysguardd/NetBSD/loadavg.c create mode 100644 ksysguard/ksysguardd/NetBSD/loadavg.h create mode 100644 ksysguard/ksysguardd/NetBSD/logfile.c create mode 100644 ksysguard/ksysguardd/NetBSD/logfile.h create mode 100644 ksysguard/ksysguardd/NetBSD/netdev.c create mode 100644 ksysguard/ksysguardd/NetBSD/netdev.h create mode 100644 ksysguard/ksysguardd/OpenBSD/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/OpenBSD/ProcessList.c create mode 100644 ksysguard/ksysguardd/OpenBSD/ProcessList.h create mode 100644 ksysguard/ksysguardd/OpenBSD/cpu.c create mode 100644 ksysguard/ksysguardd/OpenBSD/cpu.h create mode 100644 ksysguard/ksysguardd/OpenBSD/memory.c create mode 100644 ksysguard/ksysguardd/OpenBSD/memory.h create mode 100644 ksysguard/ksysguardd/PWUIDCache.c create mode 100644 ksysguard/ksysguardd/PWUIDCache.h create mode 100644 ksysguard/ksysguardd/Porting-HOWTO create mode 100644 ksysguard/ksysguardd/Solaris/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/Solaris/LoadAvg.c create mode 100644 ksysguard/ksysguardd/Solaris/LoadAvg.h create mode 100644 ksysguard/ksysguardd/Solaris/Memory.c create mode 100644 ksysguard/ksysguardd/Solaris/Memory.h create mode 100644 ksysguard/ksysguardd/Solaris/NetDev.c create mode 100644 ksysguard/ksysguardd/Solaris/NetDev.h create mode 100644 ksysguard/ksysguardd/Solaris/ProcessList.c create mode 100644 ksysguard/ksysguardd/Solaris/ProcessList.h create mode 100644 ksysguard/ksysguardd/Tru64/CMakeLists.txt create mode 100644 ksysguard/ksysguardd/Tru64/LoadAvg.c create mode 100644 ksysguard/ksysguardd/Tru64/LoadAvg.h create mode 100644 ksysguard/ksysguardd/Tru64/Memory.c create mode 100644 ksysguard/ksysguardd/Tru64/Memory.h create mode 100644 ksysguard/ksysguardd/Tru64/NetDev.c create mode 100644 ksysguard/ksysguardd/Tru64/NetDev.h create mode 100644 ksysguard/ksysguardd/conf.c create mode 100644 ksysguard/ksysguardd/conf.h create mode 100644 ksysguard/ksysguardd/config-ksysguardd.h.cmake create mode 100644 ksysguard/ksysguardd/ksysguardd.c create mode 100644 ksysguard/ksysguardd/ksysguardd.h create mode 100644 ksysguard/ksysguardd/modules.h create mode 100644 ksysguard/pics/CMakeLists.txt create mode 100644 ksysguard/pics/ox16-app-computer.png create mode 100644 ksysguard/pics/ox16-app-daemon.png create mode 100644 ksysguard/pics/ox16-app-kdeapp.png create mode 100644 ksysguard/pics/ox16-app-kernel.png create mode 100644 ksysguard/pics/ox16-app-ksysguardd.png create mode 100644 ksysguard/pics/ox16-app-running.png create mode 100644 ksysguard/pics/ox16-app-shell.png create mode 100644 ksysguard/pics/ox16-app-unknownapp.png create mode 100644 ksysguard/pics/ox16-app-waiting.png create mode 100644 ksystraycmd/CMakeLists.txt create mode 100644 ksystraycmd/Messages.sh create mode 100644 ksystraycmd/README create mode 100644 ksystraycmd/ksystraycmd.cpp create mode 100644 ksystraycmd/ksystraycmd.h create mode 100644 ksystraycmd/main.cpp create mode 100644 ktouchpadenabler/CMakeLists.txt create mode 100644 ktouchpadenabler/COPYING create mode 100644 ktouchpadenabler/Messages.sh create mode 100644 ktouchpadenabler/ktouchpadenabler.desktop create mode 100644 ktouchpadenabler/ktouchpadenabler.kcfg create mode 100644 ktouchpadenabler/ktouchpadenabler_daemon.cpp create mode 100644 ktouchpadenabler/ktouchpadenabler_daemon.h create mode 100644 ktouchpadenabler/settings.kcfgc create mode 100644 kwin/CMakeLists.txt create mode 100644 kwin/COMPLIANCE create mode 100644 kwin/CONFIGURING create mode 100644 kwin/ExtraDesktop.sh create mode 100644 kwin/HACKING create mode 100644 kwin/Mainpage.dox create mode 100644 kwin/Messages.sh create mode 100644 kwin/README create mode 100644 kwin/activation.cpp create mode 100644 kwin/activities.cpp create mode 100644 kwin/activities.h create mode 100644 kwin/appmenu.cpp create mode 100644 kwin/appmenu.h create mode 100644 kwin/atoms.cpp create mode 100644 kwin/atoms.h create mode 100644 kwin/bridge.cpp create mode 100644 kwin/bridge.h create mode 100644 kwin/client.cpp create mode 100644 kwin/client.h create mode 100644 kwin/client_machine.cpp create mode 100644 kwin/client_machine.h create mode 100644 kwin/clients/CMakeLists.txt create mode 100644 kwin/clients/Messages.sh create mode 100644 kwin/clients/aurorae/AUTHORS create mode 100644 kwin/clients/aurorae/CMakeLists.txt create mode 100644 kwin/clients/aurorae/README create mode 100644 kwin/clients/aurorae/TODO create mode 100644 kwin/clients/aurorae/src/CMakeLists.txt create mode 100644 kwin/clients/aurorae/src/aurorae.cpp create mode 100644 kwin/clients/aurorae/src/aurorae.desktop create mode 100644 kwin/clients/aurorae/src/aurorae.h create mode 100644 kwin/clients/aurorae/src/aurorae.knsrc create mode 100644 kwin/clients/aurorae/src/colorhelper.cpp create mode 100644 kwin/clients/aurorae/src/colorhelper.h create mode 100644 kwin/clients/aurorae/src/decorationoptions.cpp create mode 100644 kwin/clients/aurorae/src/decorationoptions.h create mode 100644 kwin/clients/aurorae/src/decorationplugin.cpp create mode 100644 kwin/clients/aurorae/src/decorationplugin.h create mode 100644 kwin/clients/aurorae/src/kwindecoration.desktop create mode 100644 kwin/clients/aurorae/src/lib/auroraetheme.cpp create mode 100644 kwin/clients/aurorae/src/lib/auroraetheme.h create mode 100644 kwin/clients/aurorae/src/lib/themeconfig.cpp create mode 100644 kwin/clients/aurorae/src/lib/themeconfig.h create mode 100644 kwin/clients/aurorae/src/qml/AppMenuButton.qml create mode 100644 kwin/clients/aurorae/src/qml/AuroraeButton.qml create mode 100644 kwin/clients/aurorae/src/qml/AuroraeButtonGroup.qml create mode 100644 kwin/clients/aurorae/src/qml/AuroraeMaximizeButton.qml create mode 100644 kwin/clients/aurorae/src/qml/ButtonGroup.qml create mode 100644 kwin/clients/aurorae/src/qml/Decoration.qml create mode 100644 kwin/clients/aurorae/src/qml/DecorationButton.qml create mode 100644 kwin/clients/aurorae/src/qml/MenuButton.qml create mode 100644 kwin/clients/aurorae/src/qml/aurorae.qml create mode 100644 kwin/clients/aurorae/src/qml/qmldir create mode 100644 kwin/clients/aurorae/theme-description create mode 100644 kwin/clients/aurorae/themes/CMakeLists.txt create mode 100644 kwin/clients/aurorae/themes/plastik/CMakeLists.txt create mode 100644 kwin/clients/aurorae/themes/plastik/code/CMakeLists.txt create mode 100644 kwin/clients/aurorae/themes/plastik/code/plastikbutton.cpp create mode 100644 kwin/clients/aurorae/themes/plastik/code/plastikbutton.h create mode 100644 kwin/clients/aurorae/themes/plastik/code/plastikplugin.cpp create mode 100644 kwin/clients/aurorae/themes/plastik/code/plastikplugin.h create mode 100644 kwin/clients/aurorae/themes/plastik/code/qmldir create mode 100644 kwin/clients/aurorae/themes/plastik/package/contents/config/main.xml create mode 100644 kwin/clients/aurorae/themes/plastik/package/contents/ui/PlastikButton.qml create mode 100644 kwin/clients/aurorae/themes/plastik/package/contents/ui/config.ui create mode 100644 kwin/clients/aurorae/themes/plastik/package/contents/ui/main.qml create mode 100644 kwin/clients/aurorae/themes/plastik/package/metadata.desktop create mode 100644 kwin/clients/b2/CMakeLists.txt create mode 100644 kwin/clients/b2/b2.desktop create mode 100644 kwin/clients/b2/b2client.cpp create mode 100644 kwin/clients/b2/b2client.h create mode 100644 kwin/clients/b2/bitmaps.h create mode 100644 kwin/clients/b2/config/CMakeLists.txt create mode 100644 kwin/clients/b2/config/config.cpp create mode 100644 kwin/clients/b2/config/config.h create mode 100644 kwin/clients/laptop/CMakeLists.txt create mode 100644 kwin/clients/laptop/laptop.desktop create mode 100644 kwin/clients/laptop/laptopclient.cpp create mode 100644 kwin/clients/laptop/laptopclient.h create mode 100644 kwin/clients/oxygen/CMakeLists.txt create mode 100644 kwin/clients/oxygen/config/CMakeLists.txt create mode 100644 kwin/clients/oxygen/config/oxygenanimationconfigwidget.cpp create mode 100644 kwin/clients/oxygen/config/oxygenanimationconfigwidget.h create mode 100644 kwin/clients/oxygen/config/oxygenconfig.cpp create mode 100644 kwin/clients/oxygen/config/oxygenconfig.h create mode 100644 kwin/clients/oxygen/config/oxygenconfigwidget.cpp create mode 100644 kwin/clients/oxygen/config/oxygenconfigwidget.h create mode 100644 kwin/clients/oxygen/config/oxygendetectwidget.cpp create mode 100644 kwin/clients/oxygen/config/oxygendetectwidget.h create mode 100644 kwin/clients/oxygen/config/oxygenexceptiondialog.cpp create mode 100644 kwin/clients/oxygen/config/oxygenexceptiondialog.h create mode 100644 kwin/clients/oxygen/config/oxygenexceptionlistwidget.cpp create mode 100644 kwin/clients/oxygen/config/oxygenexceptionlistwidget.h create mode 100644 kwin/clients/oxygen/config/oxygenexceptionmodel.cpp create mode 100644 kwin/clients/oxygen/config/oxygenexceptionmodel.h create mode 100644 kwin/clients/oxygen/config/ui/oxygenconfigurationui.ui create mode 100644 kwin/clients/oxygen/config/ui/oxygendetectwidget.ui create mode 100644 kwin/clients/oxygen/config/ui/oxygenexceptiondialog.ui create mode 100644 kwin/clients/oxygen/config/ui/oxygenexceptionlistwidget.ui create mode 100644 kwin/clients/oxygen/data/CMakeLists.txt create mode 100644 kwin/clients/oxygen/data/oxygen.upd create mode 100755 kwin/clients/oxygen/data/update_oxygen.pl create mode 100644 kwin/clients/oxygen/demo/CMakeLists.txt create mode 100644 kwin/clients/oxygen/demo/main.cpp create mode 100644 kwin/clients/oxygen/demo/oxygenshadowdemodialog.cpp create mode 100644 kwin/clients/oxygen/demo/oxygenshadowdemodialog.h create mode 100644 kwin/clients/oxygen/demo/oxygenshadowdemowidget.cpp create mode 100644 kwin/clients/oxygen/demo/oxygenshadowdemowidget.h create mode 100644 kwin/clients/oxygen/demo/ui/oxygenshadowdemo.ui create mode 100644 kwin/clients/oxygen/oxygenbutton.cpp create mode 100644 kwin/clients/oxygen/oxygenbutton.h create mode 100644 kwin/clients/oxygen/oxygenclient.cpp create mode 100644 kwin/clients/oxygen/oxygenclient.desktop create mode 100644 kwin/clients/oxygen/oxygenclient.h create mode 100644 kwin/clients/oxygen/oxygenclientgroupitemdata.cpp create mode 100644 kwin/clients/oxygen/oxygenclientgroupitemdata.h create mode 100644 kwin/clients/oxygen/oxygenconfigdata.kcfg create mode 100644 kwin/clients/oxygen/oxygenconfiguration.kcfgc create mode 100644 kwin/clients/oxygen/oxygendecohelper.cpp create mode 100644 kwin/clients/oxygen/oxygendecohelper.h create mode 100644 kwin/clients/oxygen/oxygendecorationdefines.h create mode 100644 kwin/clients/oxygen/oxygenexceptionlist.cpp create mode 100644 kwin/clients/oxygen/oxygenexceptionlist.h create mode 100644 kwin/clients/oxygen/oxygenfactory.cpp create mode 100644 kwin/clients/oxygen/oxygenfactory.h create mode 100644 kwin/clients/oxygen/oxygensizegrip.cpp create mode 100644 kwin/clients/oxygen/oxygensizegrip.h create mode 100644 kwin/clients/oxygen/oxygentitleanimationdata.cpp create mode 100644 kwin/clients/oxygen/oxygentitleanimationdata.h create mode 100644 kwin/composite.cpp create mode 100644 kwin/composite.h create mode 100644 kwin/compositingprefs.cpp create mode 100644 kwin/compositingprefs.h create mode 100644 kwin/config-kwin.h.cmake create mode 100644 kwin/cursor.cpp create mode 100644 kwin/cursor.h create mode 100644 kwin/data/CMakeLists.txt create mode 100644 kwin/data/fsp_workarounds_1.kwinrules create mode 100644 kwin/data/kwin_fsp_workarounds_1.upd create mode 100755 kwin/data/kwin_remove_delay_focus.sh create mode 100644 kwin/data/kwin_remove_delay_focus.upd create mode 100644 kwin/data/kwin_remove_effects.upd create mode 100755 kwin/data/kwin_translate_activity_rule.sh create mode 100644 kwin/data/kwin_translate_activity_rule.upd create mode 100755 kwin/data/kwin_translate_confrequest_rule.sh create mode 100644 kwin/data/kwin_translate_confrequest_rule.upd create mode 100644 kwin/data/kwin_update_410.upd create mode 100644 kwin/data/kwin_update_411.upd create mode 100644 kwin/data/kwin_update_49.upd create mode 100644 kwin/data/kwin_update_tabbox_qml_settings.upd create mode 100644 kwin/data/kwin_update_tabbox_settings.upd create mode 100644 kwin/data/pop.wav create mode 100644 kwin/data/stripTitle.js create mode 100644 kwin/data/update_default_rules.cpp create mode 100644 kwin/data/update_kwin_410.cpp create mode 100644 kwin/data/update_kwin_411.cpp create mode 100644 kwin/data/update_kwin_49.cpp create mode 100644 kwin/data/update_kwin_49.h create mode 100644 kwin/data/update_kwin_49_main.cpp create mode 100644 kwin/data/update_tabbox_qml_settings.cpp create mode 100644 kwin/data/update_tabbox_settings.cpp create mode 100644 kwin/dbusinterface.cpp create mode 100644 kwin/dbusinterface.h create mode 100644 kwin/decorations.cpp create mode 100644 kwin/decorations.h create mode 100644 kwin/deleted.cpp create mode 100644 kwin/deleted.h create mode 100644 kwin/effects.cpp create mode 100644 kwin/effects.h create mode 100644 kwin/effects/CMakeLists.txt create mode 100644 kwin/effects/Messages.sh create mode 100644 kwin/effects/blur/CMakeLists.txt create mode 100644 kwin/effects/blur/blur.cpp create mode 100644 kwin/effects/blur/blur.desktop create mode 100644 kwin/effects/blur/blur.h create mode 100644 kwin/effects/blur/blur.kcfg create mode 100644 kwin/effects/blur/blur_config.cpp create mode 100644 kwin/effects/blur/blur_config.desktop create mode 100644 kwin/effects/blur/blur_config.h create mode 100644 kwin/effects/blur/blur_config.ui create mode 100644 kwin/effects/blur/blurconfig.kcfgc create mode 100644 kwin/effects/blur/blurshader.cpp create mode 100644 kwin/effects/blur/blurshader.h create mode 100644 kwin/effects/configs_builtins.cpp create mode 100644 kwin/effects/coverswitch/CMakeLists.txt create mode 100644 kwin/effects/coverswitch/coverswitch.cpp create mode 100644 kwin/effects/coverswitch/coverswitch.desktop create mode 100644 kwin/effects/coverswitch/coverswitch.h create mode 100644 kwin/effects/coverswitch/coverswitch.kcfg create mode 100644 kwin/effects/coverswitch/coverswitch_config.cpp create mode 100644 kwin/effects/coverswitch/coverswitch_config.desktop create mode 100644 kwin/effects/coverswitch/coverswitch_config.h create mode 100644 kwin/effects/coverswitch/coverswitch_config.ui create mode 100644 kwin/effects/coverswitch/coverswitchconfig.kcfgc create mode 100644 kwin/effects/coverswitch/shaders/1.10/coverswitch-reflection.glsl create mode 100644 kwin/effects/coverswitch/shaders/1.40/coverswitch-reflection.glsl create mode 100644 kwin/effects/cube/CMakeLists.txt create mode 100644 kwin/effects/cube/cube.cpp create mode 100644 kwin/effects/cube/cube.desktop create mode 100644 kwin/effects/cube/cube.h create mode 100644 kwin/effects/cube/cube.kcfg create mode 100644 kwin/effects/cube/cube_config.cpp create mode 100644 kwin/effects/cube/cube_config.desktop create mode 100644 kwin/effects/cube/cube_config.h create mode 100644 kwin/effects/cube/cube_config.ui create mode 100644 kwin/effects/cube/cube_inside.h create mode 100644 kwin/effects/cube/cube_proxy.cpp create mode 100644 kwin/effects/cube/cube_proxy.h create mode 100644 kwin/effects/cube/cubeconfig.kcfgc create mode 100644 kwin/effects/cube/cubeslide.cpp create mode 100644 kwin/effects/cube/cubeslide.desktop create mode 100644 kwin/effects/cube/cubeslide.h create mode 100644 kwin/effects/cube/cubeslide.kcfg create mode 100644 kwin/effects/cube/cubeslide_config.cpp create mode 100644 kwin/effects/cube/cubeslide_config.desktop create mode 100644 kwin/effects/cube/cubeslide_config.h create mode 100644 kwin/effects/cube/cubeslide_config.ui create mode 100644 kwin/effects/cube/cubeslideconfig.kcfgc create mode 100644 kwin/effects/cube/data/1.10/cube-cap.glsl create mode 100644 kwin/effects/cube/data/1.10/cube-reflection.glsl create mode 100644 kwin/effects/cube/data/1.10/cylinder.vert create mode 100644 kwin/effects/cube/data/1.10/sphere.vert create mode 100644 kwin/effects/cube/data/1.40/cube-cap.glsl create mode 100644 kwin/effects/cube/data/1.40/cube-reflection.glsl create mode 100644 kwin/effects/cube/data/1.40/cylinder.vert create mode 100644 kwin/effects/cube/data/1.40/sphere.vert create mode 100644 kwin/effects/cube/data/cubecap.png create mode 100644 kwin/effects/dashboard/CMakeLists.txt create mode 100644 kwin/effects/dashboard/dashboard.cpp create mode 100644 kwin/effects/dashboard/dashboard.desktop create mode 100644 kwin/effects/dashboard/dashboard.h create mode 100644 kwin/effects/dashboard/dashboard.kcfg create mode 100644 kwin/effects/dashboard/dashboard_config.cpp create mode 100644 kwin/effects/dashboard/dashboard_config.desktop create mode 100644 kwin/effects/dashboard/dashboard_config.h create mode 100644 kwin/effects/dashboard/dashboard_config.ui create mode 100644 kwin/effects/dashboard/dashboardconfig.kcfgc create mode 100644 kwin/effects/desktopgrid/CMakeLists.txt create mode 100644 kwin/effects/desktopgrid/desktopgrid.cpp create mode 100644 kwin/effects/desktopgrid/desktopgrid.desktop create mode 100644 kwin/effects/desktopgrid/desktopgrid.h create mode 100644 kwin/effects/desktopgrid/desktopgrid.kcfg create mode 100644 kwin/effects/desktopgrid/desktopgrid_config.cpp create mode 100644 kwin/effects/desktopgrid/desktopgrid_config.desktop create mode 100644 kwin/effects/desktopgrid/desktopgrid_config.h create mode 100644 kwin/effects/desktopgrid/desktopgrid_config.ui create mode 100644 kwin/effects/desktopgrid/desktopgridconfig.kcfgc create mode 100644 kwin/effects/desktopgrid/main.qml create mode 100644 kwin/effects/dialogparent/CMakeLists.txt create mode 100644 kwin/effects/dialogparent/package/CMakeLists.txt create mode 100644 kwin/effects/dialogparent/package/contents/code/main.js create mode 100644 kwin/effects/dialogparent/package/metadata.desktop create mode 100644 kwin/effects/diminactive/CMakeLists.txt create mode 100644 kwin/effects/diminactive/diminactive.cpp create mode 100644 kwin/effects/diminactive/diminactive.desktop create mode 100644 kwin/effects/diminactive/diminactive.h create mode 100644 kwin/effects/diminactive/diminactive.kcfg create mode 100644 kwin/effects/diminactive/diminactive_config.cpp create mode 100644 kwin/effects/diminactive/diminactive_config.desktop create mode 100644 kwin/effects/diminactive/diminactive_config.h create mode 100644 kwin/effects/diminactive/diminactive_config.ui create mode 100644 kwin/effects/diminactive/diminactiveconfig.kcfgc create mode 100644 kwin/effects/dimscreen/CMakeLists.txt create mode 100644 kwin/effects/dimscreen/dimscreen.cpp create mode 100644 kwin/effects/dimscreen/dimscreen.desktop create mode 100644 kwin/effects/dimscreen/dimscreen.h create mode 100644 kwin/effects/fade/CMakeLists.txt create mode 100644 kwin/effects/fade/package/contents/code/main.js create mode 100644 kwin/effects/fade/package/contents/config/main.xml create mode 100644 kwin/effects/fade/package/metadata.desktop create mode 100644 kwin/effects/fadedesktop/CMakeLists.txt create mode 100644 kwin/effects/fadedesktop/package/contents/code/main.js create mode 100644 kwin/effects/fadedesktop/package/metadata.desktop create mode 100644 kwin/effects/fallapart/CMakeLists.txt create mode 100644 kwin/effects/fallapart/fallapart.cpp create mode 100644 kwin/effects/fallapart/fallapart.desktop create mode 100644 kwin/effects/fallapart/fallapart.h create mode 100644 kwin/effects/flipswitch/CMakeLists.txt create mode 100644 kwin/effects/flipswitch/flipswitch.cpp create mode 100644 kwin/effects/flipswitch/flipswitch.desktop create mode 100644 kwin/effects/flipswitch/flipswitch.h create mode 100644 kwin/effects/flipswitch/flipswitch.kcfg create mode 100644 kwin/effects/flipswitch/flipswitch_config.cpp create mode 100644 kwin/effects/flipswitch/flipswitch_config.desktop create mode 100644 kwin/effects/flipswitch/flipswitch_config.h create mode 100644 kwin/effects/flipswitch/flipswitch_config.ui create mode 100644 kwin/effects/flipswitch/flipswitchconfig.kcfgc create mode 100644 kwin/effects/glide/CMakeLists.txt create mode 100644 kwin/effects/glide/glide.cpp create mode 100644 kwin/effects/glide/glide.desktop create mode 100644 kwin/effects/glide/glide.h create mode 100644 kwin/effects/glide/glide.kcfg create mode 100644 kwin/effects/glide/glide_config.cpp create mode 100644 kwin/effects/glide/glide_config.desktop create mode 100644 kwin/effects/glide/glide_config.h create mode 100644 kwin/effects/glide/glide_config.ui create mode 100644 kwin/effects/glide/glideconfig.kcfgc create mode 100644 kwin/effects/highlightwindow/CMakeLists.txt create mode 100644 kwin/effects/highlightwindow/highlightwindow.cpp create mode 100644 kwin/effects/highlightwindow/highlightwindow.desktop create mode 100644 kwin/effects/highlightwindow/highlightwindow.h create mode 100644 kwin/effects/invert/CMakeLists.txt create mode 100644 kwin/effects/invert/data/1.10/invert.frag create mode 100644 kwin/effects/invert/data/1.40/invert.frag create mode 100644 kwin/effects/invert/invert.cpp create mode 100644 kwin/effects/invert/invert.desktop create mode 100644 kwin/effects/invert/invert.h create mode 100644 kwin/effects/invert/invert_config.cpp create mode 100644 kwin/effects/invert/invert_config.desktop create mode 100644 kwin/effects/invert/invert_config.h create mode 100644 kwin/effects/kscreen/CMakeLists.txt create mode 100644 kwin/effects/kscreen/kscreen.cpp create mode 100644 kwin/effects/kscreen/kscreen.desktop create mode 100644 kwin/effects/kscreen/kscreen.h create mode 100644 kwin/effects/kscreen/kscreen.kcfg create mode 100644 kwin/effects/kscreen/kscreenconfig.kcfgc create mode 100644 kwin/effects/kwineffect.desktop create mode 100644 kwin/effects/login/CMakeLists.txt create mode 100644 kwin/effects/login/package/CMakeLists.txt create mode 100644 kwin/effects/login/package/contents/code/main.js create mode 100644 kwin/effects/login/package/contents/config/main.xml create mode 100644 kwin/effects/login/package/contents/ui/config.ui create mode 100644 kwin/effects/login/package/metadata.desktop create mode 100644 kwin/effects/logout/CMakeLists.txt create mode 100644 kwin/effects/logout/data/1.10/logout-blur.frag create mode 100644 kwin/effects/logout/data/1.10/vignetting.frag create mode 100644 kwin/effects/logout/data/1.40/logout-blur.frag create mode 100644 kwin/effects/logout/data/1.40/vignetting.frag create mode 100644 kwin/effects/logout/logout.cpp create mode 100644 kwin/effects/logout/logout.desktop create mode 100644 kwin/effects/logout/logout.h create mode 100644 kwin/effects/logout/logout.kcfg create mode 100644 kwin/effects/logout/logoutconfig.kcfgc create mode 100644 kwin/effects/lookingglass/CMakeLists.txt create mode 100644 kwin/effects/lookingglass/data/1.10/lookingglass.frag create mode 100644 kwin/effects/lookingglass/data/1.40/lookingglass.frag create mode 100644 kwin/effects/lookingglass/lookingglass.cpp create mode 100644 kwin/effects/lookingglass/lookingglass.desktop create mode 100644 kwin/effects/lookingglass/lookingglass.h create mode 100644 kwin/effects/lookingglass/lookingglass.kcfg create mode 100644 kwin/effects/lookingglass/lookingglass_config.cpp create mode 100644 kwin/effects/lookingglass/lookingglass_config.desktop create mode 100644 kwin/effects/lookingglass/lookingglass_config.h create mode 100644 kwin/effects/lookingglass/lookingglass_config.ui create mode 100644 kwin/effects/lookingglass/lookingglassconfig.kcfgc create mode 100644 kwin/effects/magiclamp/CMakeLists.txt create mode 100644 kwin/effects/magiclamp/magiclamp.cpp create mode 100644 kwin/effects/magiclamp/magiclamp.desktop create mode 100644 kwin/effects/magiclamp/magiclamp.h create mode 100644 kwin/effects/magiclamp/magiclamp.kcfg create mode 100644 kwin/effects/magiclamp/magiclamp_config.cpp create mode 100644 kwin/effects/magiclamp/magiclamp_config.desktop create mode 100644 kwin/effects/magiclamp/magiclamp_config.h create mode 100644 kwin/effects/magiclamp/magiclamp_config.ui create mode 100644 kwin/effects/magiclamp/magiclampconfig.kcfgc create mode 100644 kwin/effects/magnifier/CMakeLists.txt create mode 100644 kwin/effects/magnifier/magnifier.cpp create mode 100644 kwin/effects/magnifier/magnifier.desktop create mode 100644 kwin/effects/magnifier/magnifier.h create mode 100644 kwin/effects/magnifier/magnifier.kcfg create mode 100644 kwin/effects/magnifier/magnifier_config.cpp create mode 100644 kwin/effects/magnifier/magnifier_config.desktop create mode 100644 kwin/effects/magnifier/magnifier_config.h create mode 100644 kwin/effects/magnifier/magnifier_config.ui create mode 100644 kwin/effects/magnifier/magnifierconfig.kcfgc create mode 100644 kwin/effects/maximize/CMakeLists.txt create mode 100644 kwin/effects/maximize/package/CMakeLists.txt create mode 100644 kwin/effects/maximize/package/contents/code/maximize.js create mode 100644 kwin/effects/maximize/package/metadata.desktop create mode 100644 kwin/effects/minimizeanimation/CMakeLists.txt create mode 100644 kwin/effects/minimizeanimation/minimizeanimation.cpp create mode 100644 kwin/effects/minimizeanimation/minimizeanimation.desktop create mode 100644 kwin/effects/minimizeanimation/minimizeanimation.h create mode 100644 kwin/effects/mouseclick/CMakeLists.txt create mode 100644 kwin/effects/mouseclick/mouseclick.cpp create mode 100644 kwin/effects/mouseclick/mouseclick.desktop create mode 100644 kwin/effects/mouseclick/mouseclick.h create mode 100644 kwin/effects/mouseclick/mouseclick.kcfg create mode 100644 kwin/effects/mouseclick/mouseclick_config.cpp create mode 100644 kwin/effects/mouseclick/mouseclick_config.desktop create mode 100644 kwin/effects/mouseclick/mouseclick_config.h create mode 100644 kwin/effects/mouseclick/mouseclick_config.ui create mode 100644 kwin/effects/mouseclick/mouseclickconfig.kcfgc create mode 100644 kwin/effects/mousemark/CMakeLists.txt create mode 100644 kwin/effects/mousemark/mousemark.cpp create mode 100644 kwin/effects/mousemark/mousemark.desktop create mode 100644 kwin/effects/mousemark/mousemark.h create mode 100644 kwin/effects/mousemark/mousemark.kcfg create mode 100644 kwin/effects/mousemark/mousemark_config.cpp create mode 100644 kwin/effects/mousemark/mousemark_config.desktop create mode 100644 kwin/effects/mousemark/mousemark_config.h create mode 100644 kwin/effects/mousemark/mousemark_config.ui create mode 100644 kwin/effects/mousemark/mousemarkconfig.kcfgc create mode 100644 kwin/effects/presentwindows/CMakeLists.txt create mode 100644 kwin/effects/presentwindows/main.qml create mode 100755 kwin/effects/presentwindows/presentwindows.cpp create mode 100644 kwin/effects/presentwindows/presentwindows.desktop create mode 100644 kwin/effects/presentwindows/presentwindows.h create mode 100644 kwin/effects/presentwindows/presentwindows.kcfg create mode 100644 kwin/effects/presentwindows/presentwindows_config.cpp create mode 100644 kwin/effects/presentwindows/presentwindows_config.desktop create mode 100644 kwin/effects/presentwindows/presentwindows_config.h create mode 100644 kwin/effects/presentwindows/presentwindows_config.ui create mode 100644 kwin/effects/presentwindows/presentwindows_proxy.cpp create mode 100644 kwin/effects/presentwindows/presentwindows_proxy.h create mode 100644 kwin/effects/presentwindows/presentwindowsconfig.kcfgc create mode 100644 kwin/effects/resize/CMakeLists.txt create mode 100644 kwin/effects/resize/resize.cpp create mode 100644 kwin/effects/resize/resize.desktop create mode 100644 kwin/effects/resize/resize.h create mode 100644 kwin/effects/resize/resize.kcfg create mode 100644 kwin/effects/resize/resize_config.cpp create mode 100644 kwin/effects/resize/resize_config.desktop create mode 100644 kwin/effects/resize/resize_config.h create mode 100644 kwin/effects/resize/resize_config.ui create mode 100644 kwin/effects/resize/resizeconfig.kcfgc create mode 100644 kwin/effects/scalein/CMakeLists.txt create mode 100644 kwin/effects/scalein/package/CMakeLists.txt create mode 100644 kwin/effects/scalein/package/contents/code/main.js create mode 100644 kwin/effects/scalein/package/metadata.desktop create mode 100644 kwin/effects/screenedge/CMakeLists.txt create mode 100644 kwin/effects/screenedge/screenedgeeffect.cpp create mode 100644 kwin/effects/screenedge/screenedgeeffect.desktop create mode 100644 kwin/effects/screenedge/screenedgeeffect.h create mode 100644 kwin/effects/screenshot/CMakeLists.txt create mode 100644 kwin/effects/screenshot/screenshot.cpp create mode 100644 kwin/effects/screenshot/screenshot.desktop create mode 100644 kwin/effects/screenshot/screenshot.h create mode 100644 kwin/effects/sheet/CMakeLists.txt create mode 100644 kwin/effects/sheet/sheet.cpp create mode 100644 kwin/effects/sheet/sheet.desktop create mode 100644 kwin/effects/sheet/sheet.h create mode 100644 kwin/effects/sheet/sheet.kcfg create mode 100644 kwin/effects/sheet/sheetconfig.kcfgc create mode 100644 kwin/effects/showfps/CMakeLists.txt create mode 100644 kwin/effects/showfps/showfps.cpp create mode 100644 kwin/effects/showfps/showfps.desktop create mode 100644 kwin/effects/showfps/showfps.h create mode 100644 kwin/effects/showfps/showfps.kcfg create mode 100644 kwin/effects/showfps/showfps_config.cpp create mode 100644 kwin/effects/showfps/showfps_config.desktop create mode 100644 kwin/effects/showfps/showfps_config.h create mode 100644 kwin/effects/showfps/showfps_config.ui create mode 100644 kwin/effects/showfps/showfpsconfig.kcfgc create mode 100644 kwin/effects/showpaint/CMakeLists.txt create mode 100644 kwin/effects/showpaint/showpaint.cpp create mode 100644 kwin/effects/showpaint/showpaint.desktop create mode 100644 kwin/effects/showpaint/showpaint.h create mode 100644 kwin/effects/slide/CMakeLists.txt create mode 100644 kwin/effects/slide/slide.cpp create mode 100644 kwin/effects/slide/slide.desktop create mode 100644 kwin/effects/slide/slide.h create mode 100644 kwin/effects/slideback/CMakeLists.txt create mode 100644 kwin/effects/slideback/slideback.cpp create mode 100644 kwin/effects/slideback/slideback.desktop create mode 100644 kwin/effects/slideback/slideback.h create mode 100644 kwin/effects/slidingpopups/CMakeLists.txt create mode 100644 kwin/effects/slidingpopups/slidingpopups.cpp create mode 100644 kwin/effects/slidingpopups/slidingpopups.desktop create mode 100644 kwin/effects/slidingpopups/slidingpopups.h create mode 100644 kwin/effects/snaphelper/CMakeLists.txt create mode 100644 kwin/effects/snaphelper/snaphelper.cpp create mode 100644 kwin/effects/snaphelper/snaphelper.desktop create mode 100644 kwin/effects/snaphelper/snaphelper.h create mode 100644 kwin/effects/startupfeedback/CMakeLists.txt create mode 100644 kwin/effects/startupfeedback/data/blinking-startup-fragment.glsl create mode 100644 kwin/effects/startupfeedback/startupfeedback.cpp create mode 100644 kwin/effects/startupfeedback/startupfeedback.desktop create mode 100644 kwin/effects/startupfeedback/startupfeedback.h create mode 100644 kwin/effects/taskbarthumbnail/CMakeLists.txt create mode 100644 kwin/effects/taskbarthumbnail/taskbarthumbnail.cpp create mode 100644 kwin/effects/taskbarthumbnail/taskbarthumbnail.desktop create mode 100644 kwin/effects/taskbarthumbnail/taskbarthumbnail.h create mode 100644 kwin/effects/thumbnailaside/CMakeLists.txt create mode 100644 kwin/effects/thumbnailaside/thumbnailaside.cpp create mode 100644 kwin/effects/thumbnailaside/thumbnailaside.desktop create mode 100644 kwin/effects/thumbnailaside/thumbnailaside.h create mode 100644 kwin/effects/thumbnailaside/thumbnailaside.kcfg create mode 100644 kwin/effects/thumbnailaside/thumbnailaside_config.cpp create mode 100644 kwin/effects/thumbnailaside/thumbnailaside_config.desktop create mode 100644 kwin/effects/thumbnailaside/thumbnailaside_config.h create mode 100644 kwin/effects/thumbnailaside/thumbnailaside_config.ui create mode 100644 kwin/effects/thumbnailaside/thumbnailasideconfig.kcfgc create mode 100644 kwin/effects/trackmouse/CMakeLists.txt create mode 100644 kwin/effects/trackmouse/data/tm_inner.png create mode 100644 kwin/effects/trackmouse/data/tm_outer.png create mode 100644 kwin/effects/trackmouse/trackmouse.cpp create mode 100644 kwin/effects/trackmouse/trackmouse.desktop create mode 100644 kwin/effects/trackmouse/trackmouse.h create mode 100644 kwin/effects/trackmouse/trackmouse.kcfg create mode 100644 kwin/effects/trackmouse/trackmouse_config.cpp create mode 100644 kwin/effects/trackmouse/trackmouse_config.desktop create mode 100644 kwin/effects/trackmouse/trackmouse_config.h create mode 100644 kwin/effects/trackmouse/trackmouse_config.ui create mode 100644 kwin/effects/trackmouse/trackmouseconfig.kcfgc create mode 100644 kwin/effects/translucency/CMakeLists.txt create mode 100644 kwin/effects/translucency/package/CMakeLists.txt create mode 100644 kwin/effects/translucency/package/contents/code/main.js create mode 100644 kwin/effects/translucency/package/contents/config/main.xml create mode 100644 kwin/effects/translucency/package/contents/ui/config.ui create mode 100644 kwin/effects/translucency/package/metadata.desktop create mode 100644 kwin/effects/windowgeometry/CMakeLists.txt create mode 100644 kwin/effects/windowgeometry/windowgeometry.cpp create mode 100644 kwin/effects/windowgeometry/windowgeometry.desktop create mode 100644 kwin/effects/windowgeometry/windowgeometry.h create mode 100644 kwin/effects/windowgeometry/windowgeometry.kcfg create mode 100644 kwin/effects/windowgeometry/windowgeometry_config.cpp create mode 100644 kwin/effects/windowgeometry/windowgeometry_config.desktop create mode 100644 kwin/effects/windowgeometry/windowgeometry_config.h create mode 100644 kwin/effects/windowgeometry/windowgeometry_config.ui create mode 100644 kwin/effects/windowgeometry/windowgeometryconfig.kcfgc create mode 100644 kwin/effects/wobblywindows/CMakeLists.txt create mode 100644 kwin/effects/wobblywindows/wobblywindows.cpp create mode 100644 kwin/effects/wobblywindows/wobblywindows.desktop create mode 100644 kwin/effects/wobblywindows/wobblywindows.h create mode 100644 kwin/effects/wobblywindows/wobblywindows.kcfg create mode 100644 kwin/effects/wobblywindows/wobblywindows_config.cpp create mode 100644 kwin/effects/wobblywindows/wobblywindows_config.desktop create mode 100644 kwin/effects/wobblywindows/wobblywindows_config.h create mode 100644 kwin/effects/wobblywindows/wobblywindows_config.ui create mode 100644 kwin/effects/wobblywindows/wobblywindowsconfig.kcfgc create mode 100644 kwin/effects/zoom/CMakeLists.txt create mode 100644 kwin/effects/zoom/zoom.cpp create mode 100644 kwin/effects/zoom/zoom.desktop create mode 100644 kwin/effects/zoom/zoom.h create mode 100644 kwin/effects/zoom/zoom.kcfg create mode 100644 kwin/effects/zoom/zoom_config.cpp create mode 100644 kwin/effects/zoom/zoom_config.desktop create mode 100644 kwin/effects/zoom/zoom_config.h create mode 100644 kwin/effects/zoom/zoom_config.ui create mode 100644 kwin/effects/zoom/zoomconfig.kcfgc create mode 100644 kwin/egl_wayland_backend.cpp create mode 100644 kwin/egl_wayland_backend.h create mode 100644 kwin/eglonxbackend.cpp create mode 100644 kwin/eglonxbackend.h create mode 100644 kwin/events.cpp create mode 100644 kwin/focuschain.cpp create mode 100644 kwin/focuschain.h create mode 100644 kwin/geometry.cpp create mode 100644 kwin/geometrytip.cpp create mode 100644 kwin/geometrytip.h create mode 100644 kwin/glxbackend.cpp create mode 100644 kwin/glxbackend.h create mode 100644 kwin/group.cpp create mode 100644 kwin/group.h create mode 100644 kwin/kcmkwin/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwincompositing/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwincompositing/Messages.sh create mode 100644 kwin/kcmkwin/kwincompositing/dbus.h create mode 100644 kwin/kcmkwin/kwincompositing/interface_util.h create mode 100644 kwin/kcmkwin/kwincompositing/ktimerdialog.cpp create mode 100644 kwin/kcmkwin/kwincompositing/ktimerdialog.h create mode 100644 kwin/kcmkwin/kwincompositing/kwincompositing.desktop create mode 100644 kwin/kcmkwin/kwincompositing/kwineffect.knsrc create mode 100644 kwin/kcmkwin/kwincompositing/main.cpp create mode 100644 kwin/kcmkwin/kwincompositing/main.h create mode 100644 kwin/kcmkwin/kwincompositing/main.ui create mode 100644 kwin/kcmkwin/kwindecoration/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwindecoration/Messages.sh create mode 100644 kwin/kcmkwin/kwindecoration/auroraeconfig.ui create mode 100644 kwin/kcmkwin/kwindecoration/buttons.cpp create mode 100644 kwin/kcmkwin/kwindecoration/buttons.h create mode 100644 kwin/kcmkwin/kwindecoration/buttons.ui create mode 100644 kwin/kcmkwin/kwindecoration/buttonsconfigdialog.cpp create mode 100644 kwin/kcmkwin/kwindecoration/buttonsconfigdialog.h create mode 100644 kwin/kcmkwin/kwindecoration/config.ui create mode 100644 kwin/kcmkwin/kwindecoration/configdialog.cpp create mode 100644 kwin/kcmkwin/kwindecoration/configdialog.h create mode 100644 kwin/kcmkwin/kwindecoration/decoration.ui create mode 100644 kwin/kcmkwin/kwindecoration/decorationmodel.cpp create mode 100644 kwin/kcmkwin/kwindecoration/decorationmodel.h create mode 100644 kwin/kcmkwin/kwindecoration/kwindecoration.cpp create mode 100644 kwin/kcmkwin/kwindecoration/kwindecoration.desktop create mode 100644 kwin/kcmkwin/kwindecoration/kwindecoration.h create mode 100644 kwin/kcmkwin/kwindecoration/pixmaps.h create mode 100644 kwin/kcmkwin/kwindecoration/preview.cpp create mode 100644 kwin/kcmkwin/kwindecoration/preview.h create mode 100644 kwin/kcmkwin/kwindecoration/qml/AuroraeDecoration.qml create mode 100644 kwin/kcmkwin/kwindecoration/qml/AuroraePreview.qml create mode 100644 kwin/kcmkwin/kwindecoration/qml/DecorationPreview.qml create mode 100644 kwin/kcmkwin/kwindecoration/qml/main.qml create mode 100644 kwin/kcmkwin/kwindesktop/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwindesktop/Messages.sh create mode 100644 kwin/kcmkwin/kwindesktop/desktop.desktop create mode 100644 kwin/kcmkwin/kwindesktop/desktopnameswidget.cpp create mode 100644 kwin/kcmkwin/kwindesktop/desktopnameswidget.h create mode 100644 kwin/kcmkwin/kwindesktop/main.cpp create mode 100644 kwin/kcmkwin/kwindesktop/main.h create mode 100644 kwin/kcmkwin/kwindesktop/main.ui create mode 100644 kwin/kcmkwin/kwinoptions/AUTHORS create mode 100644 kwin/kcmkwin/kwinoptions/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwinoptions/ChangeLog create mode 100644 kwin/kcmkwin/kwinoptions/Messages.sh create mode 100644 kwin/kcmkwin/kwinoptions/actions.ui create mode 100644 kwin/kcmkwin/kwinoptions/advanced.ui create mode 100644 kwin/kcmkwin/kwinoptions/focus.ui create mode 100644 kwin/kcmkwin/kwinoptions/kwinactions.desktop create mode 100644 kwin/kcmkwin/kwinoptions/kwinadvanced.desktop create mode 100644 kwin/kcmkwin/kwinoptions/kwinfocus.desktop create mode 100644 kwin/kcmkwin/kwinoptions/kwinmoving.desktop create mode 100644 kwin/kcmkwin/kwinoptions/kwinoptions.desktop create mode 100644 kwin/kcmkwin/kwinoptions/main.cpp create mode 100644 kwin/kcmkwin/kwinoptions/main.h create mode 100644 kwin/kcmkwin/kwinoptions/mouse.cpp create mode 100644 kwin/kcmkwin/kwinoptions/mouse.h create mode 100644 kwin/kcmkwin/kwinoptions/mouse.ui create mode 100644 kwin/kcmkwin/kwinoptions/moving.ui create mode 100644 kwin/kcmkwin/kwinoptions/ox128-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/ox16-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/ox22-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/ox32-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/ox48-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/ox64-app-kcmkwm.png create mode 100644 kwin/kcmkwin/kwinoptions/oxsc-app-kcmkwm.svgz create mode 100644 kwin/kcmkwin/kwinoptions/windows.cpp create mode 100644 kwin/kcmkwin/kwinoptions/windows.h create mode 100644 kwin/kcmkwin/kwinrules/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwinrules/Messages.sh create mode 100644 kwin/kcmkwin/kwinrules/detectwidget.cpp create mode 100644 kwin/kcmkwin/kwinrules/detectwidget.h create mode 100644 kwin/kcmkwin/kwinrules/detectwidget.ui create mode 100644 kwin/kcmkwin/kwinrules/editshortcut.ui create mode 100644 kwin/kcmkwin/kwinrules/kcm.cpp create mode 100644 kwin/kcmkwin/kwinrules/kcm.h create mode 100644 kwin/kcmkwin/kwinrules/kwinrules.desktop create mode 100644 kwin/kcmkwin/kwinrules/kwinsrc.cpp create mode 100644 kwin/kcmkwin/kwinrules/main.cpp create mode 100644 kwin/kcmkwin/kwinrules/ruleslist.cpp create mode 100644 kwin/kcmkwin/kwinrules/ruleslist.h create mode 100644 kwin/kcmkwin/kwinrules/ruleslist.ui create mode 100644 kwin/kcmkwin/kwinrules/ruleswidget.cpp create mode 100644 kwin/kcmkwin/kwinrules/ruleswidget.h create mode 100644 kwin/kcmkwin/kwinrules/ruleswidgetbase.ui create mode 100644 kwin/kcmkwin/kwinrules/yesnobox.h create mode 100644 kwin/kcmkwin/kwinscreenedges/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwinscreenedges/Messages.sh create mode 100644 kwin/kcmkwin/kwinscreenedges/kwinscreenedges.desktop create mode 100644 kwin/kcmkwin/kwinscreenedges/main.cpp create mode 100644 kwin/kcmkwin/kwinscreenedges/main.h create mode 100644 kwin/kcmkwin/kwinscreenedges/main.ui create mode 100644 kwin/kcmkwin/kwinscreenedges/monitor.cpp create mode 100644 kwin/kcmkwin/kwinscreenedges/monitor.h create mode 100644 kwin/kcmkwin/kwinscripts/CMakeLists.txt create mode 100755 kwin/kcmkwin/kwinscripts/Messages.sh create mode 100644 kwin/kcmkwin/kwinscripts/kwinscripts.desktop create mode 100644 kwin/kcmkwin/kwinscripts/kwinscripts.knsrc create mode 100644 kwin/kcmkwin/kwinscripts/main.cpp create mode 100644 kwin/kcmkwin/kwinscripts/module.cpp create mode 100644 kwin/kcmkwin/kwinscripts/module.h create mode 100644 kwin/kcmkwin/kwinscripts/module.ui create mode 100644 kwin/kcmkwin/kwinscripts/version.h.cmake create mode 100644 kwin/kcmkwin/kwintabbox/CMakeLists.txt create mode 100644 kwin/kcmkwin/kwintabbox/Messages.sh create mode 100644 kwin/kcmkwin/kwintabbox/kwinswitcher.knsrc create mode 100644 kwin/kcmkwin/kwintabbox/kwintabbox.desktop create mode 100644 kwin/kcmkwin/kwintabbox/layoutpreview.cpp create mode 100644 kwin/kcmkwin/kwintabbox/layoutpreview.h create mode 100644 kwin/kcmkwin/kwintabbox/main.cpp create mode 100644 kwin/kcmkwin/kwintabbox/main.h create mode 100644 kwin/kcmkwin/kwintabbox/main.ui create mode 100644 kwin/kcmkwin/kwintabbox/qml/main.qml create mode 100644 kwin/kcmkwin/kwintabbox/thumbnailitem.cpp create mode 100644 kwin/kcmkwin/kwintabbox/thumbnailitem.h create mode 100644 kwin/kcmkwin/kwintabbox/thumbnails/dolphin.png create mode 100644 kwin/kcmkwin/kwintabbox/thumbnails/kmail.png create mode 100644 kwin/kcmkwin/kwintabbox/thumbnails/konqueror.png create mode 100644 kwin/kcmkwin/kwintabbox/thumbnails/systemsettings.png create mode 100644 kwin/killer/CMakeLists.txt create mode 100644 kwin/killer/killer.cpp create mode 100644 kwin/killwindow.cpp create mode 100644 kwin/killwindow.h create mode 100644 kwin/kwin.kcfg create mode 100644 kwin/kwin.notifyrc create mode 100644 kwin/kwinbindings.cpp create mode 100644 kwin/lanczosfilter.cpp create mode 100644 kwin/lanczosfilter.h create mode 100644 kwin/layers.cpp create mode 100644 kwin/libkdecorations/CMakeLists.txt create mode 100644 kwin/libkdecorations/Mainpage.dox create mode 100644 kwin/libkdecorations/Messages.sh create mode 100644 kwin/libkdecorations/kcommondecoration.cpp create mode 100644 kwin/libkdecorations/kcommondecoration.h create mode 100644 kwin/libkdecorations/kcommondecoration_p.cpp create mode 100644 kwin/libkdecorations/kcommondecoration_p.h create mode 100644 kwin/libkdecorations/kdecoration.cpp create mode 100644 kwin/libkdecorations/kdecoration.h create mode 100644 kwin/libkdecorations/kdecoration_p.cpp create mode 100644 kwin/libkdecorations/kdecoration_p.h create mode 100644 kwin/libkdecorations/kdecoration_plugins_p.cpp create mode 100644 kwin/libkdecorations/kdecoration_plugins_p.h create mode 100644 kwin/libkdecorations/kdecorationbridge.h create mode 100644 kwin/libkdecorations/kdecorationfactory.cpp create mode 100644 kwin/libkdecorations/kdecorationfactory.h create mode 100644 kwin/libkwineffects/CMakeLists.txt create mode 100644 kwin/libkwineffects/Mainpage.dox create mode 100644 kwin/libkwineffects/Messages.sh create mode 100644 kwin/libkwineffects/anidata.cpp create mode 100644 kwin/libkwineffects/anidata_p.h create mode 100644 kwin/libkwineffects/kwinanimationeffect.cpp create mode 100644 kwin/libkwineffects/kwinanimationeffect.h create mode 100644 kwin/libkwineffects/kwinconfig.h.cmake create mode 100644 kwin/libkwineffects/kwineffects.cpp create mode 100644 kwin/libkwineffects/kwineffects.h create mode 100644 kwin/libkwineffects/kwinglcolorcorrection.cpp create mode 100644 kwin/libkwineffects/kwinglcolorcorrection.h create mode 100644 kwin/libkwineffects/kwinglcolorcorrection_p.h create mode 100644 kwin/libkwineffects/kwinglobals.cpp create mode 100644 kwin/libkwineffects/kwinglobals.h create mode 100644 kwin/libkwineffects/kwinglplatform.cpp create mode 100644 kwin/libkwineffects/kwinglplatform.h create mode 100644 kwin/libkwineffects/kwingltexture.cpp create mode 100644 kwin/libkwineffects/kwingltexture.h create mode 100644 kwin/libkwineffects/kwingltexture_p.h create mode 100644 kwin/libkwineffects/kwinglutils.cpp create mode 100644 kwin/libkwineffects/kwinglutils.h create mode 100644 kwin/libkwineffects/kwinglutils_funcs.cpp create mode 100644 kwin/libkwineffects/kwinglutils_funcs.h create mode 100644 kwin/libkwineffects/kwinxrenderutils.cpp create mode 100644 kwin/libkwineffects/kwinxrenderutils.h create mode 100644 kwin/main.cpp create mode 100644 kwin/main.h create mode 100644 kwin/manage.cpp create mode 100644 kwin/netinfo.cpp create mode 100644 kwin/netinfo.h create mode 100644 kwin/opengltest/CMakeLists.txt create mode 100644 kwin/opengltest/opengltest.cpp create mode 100644 kwin/options.cpp create mode 100644 kwin/options.h create mode 100644 kwin/org.kde.KWin.xml create mode 100644 kwin/org.kde.kwin.Compositing.xml create mode 100644 kwin/org.kde.kwin.Effects.xml create mode 100644 kwin/outline.cpp create mode 100644 kwin/outline.h create mode 100644 kwin/overlaywindow.cpp create mode 100644 kwin/overlaywindow.h create mode 100644 kwin/ox16-app-kwin.png create mode 100644 kwin/ox32-app-kwin.png create mode 100644 kwin/ox48-app-kwin.png create mode 100644 kwin/oxsc-app-kwin.svgz create mode 100644 kwin/paintredirector.cpp create mode 100644 kwin/paintredirector.h create mode 100644 kwin/placement.cpp create mode 100644 kwin/placement.h create mode 100644 kwin/resources.qrc create mode 100644 kwin/rules.cpp create mode 100644 kwin/rules.h create mode 100644 kwin/scene.cpp create mode 100644 kwin/scene.h create mode 100644 kwin/scene_opengl.cpp create mode 100644 kwin/scene_opengl.h create mode 100644 kwin/scene_xrender.cpp create mode 100644 kwin/scene_xrender.h create mode 100644 kwin/screenedge.cpp create mode 100644 kwin/screenedge.h create mode 100644 kwin/screens.cpp create mode 100644 kwin/screens.h create mode 100644 kwin/scripting/CMakeLists.txt create mode 100644 kwin/scripting/Messages.sh create mode 100644 kwin/scripting/documentation-effect-global.xml create mode 100644 kwin/scripting/documentation-global.xml create mode 100644 kwin/scripting/genericscriptedconfig.cpp create mode 100644 kwin/scripting/genericscriptedconfig.h create mode 100644 kwin/scripting/kwinscript.desktop create mode 100644 kwin/scripting/meta.cpp create mode 100644 kwin/scripting/meta.h create mode 100644 kwin/scripting/scriptedeffect.cpp create mode 100644 kwin/scripting/scriptedeffect.h create mode 100644 kwin/scripting/scripting.cpp create mode 100644 kwin/scripting/scripting.h create mode 100644 kwin/scripting/scripting_model.cpp create mode 100644 kwin/scripting/scripting_model.h create mode 100644 kwin/scripting/scriptingutils.cpp create mode 100644 kwin/scripting/scriptingutils.h create mode 100644 kwin/scripting/timer.cpp create mode 100644 kwin/scripting/workspace_wrapper.cpp create mode 100644 kwin/scripting/workspace_wrapper.h create mode 100644 kwin/scripts/CMakeLists.txt create mode 100644 kwin/scripts/Messages.sh create mode 100644 kwin/scripts/desktopchangeosd/contents/ui/main.qml create mode 100644 kwin/scripts/desktopchangeosd/contents/ui/osd.qml create mode 100644 kwin/scripts/desktopchangeosd/metadata.desktop create mode 100644 kwin/scripts/synchronizeskipswitcher/contents/code/main.js create mode 100644 kwin/scripts/synchronizeskipswitcher/metadata.desktop create mode 100644 kwin/scripts/videowall/contents/code/main.js create mode 100644 kwin/scripts/videowall/metadata.desktop create mode 100644 kwin/settings.kcfgc create mode 100644 kwin/shaders/1.10/lanczos-fragment.glsl create mode 100644 kwin/shaders/1.10/scene-color-fragment.glsl create mode 100644 kwin/shaders/1.10/scene-color-vertex.glsl create mode 100644 kwin/shaders/1.10/scene-fragment.glsl create mode 100644 kwin/shaders/1.10/scene-generic-vertex.glsl create mode 100644 kwin/shaders/1.10/scene-vertex.glsl create mode 100644 kwin/shaders/1.40/lanczos-fragment.glsl create mode 100644 kwin/shaders/1.40/scene-color-fragment.glsl create mode 100644 kwin/shaders/1.40/scene-color-vertex.glsl create mode 100644 kwin/shaders/1.40/scene-fragment.glsl create mode 100644 kwin/shaders/1.40/scene-generic-vertex.glsl create mode 100644 kwin/shaders/1.40/scene-vertex.glsl create mode 100644 kwin/shadow.cpp create mode 100644 kwin/shadow.h create mode 100644 kwin/sm.cpp create mode 100644 kwin/sm.h create mode 100644 kwin/tabbox/CMakeLists.txt create mode 100644 kwin/tabbox/clientmodel.cpp create mode 100644 kwin/tabbox/clientmodel.h create mode 100644 kwin/tabbox/declarative.cpp create mode 100644 kwin/tabbox/declarative.h create mode 100644 kwin/tabbox/desktopchain.cpp create mode 100644 kwin/tabbox/desktopchain.h create mode 100644 kwin/tabbox/desktopmodel.cpp create mode 100644 kwin/tabbox/desktopmodel.h create mode 100644 kwin/tabbox/kwindesktopswitcher.desktop create mode 100644 kwin/tabbox/kwinwindowswitcher.desktop create mode 100644 kwin/tabbox/qml/CMakeLists.txt create mode 100644 kwin/tabbox/qml/IconTabBox.qml create mode 100644 kwin/tabbox/qml/ShadowedSvgItem.qml create mode 100644 kwin/tabbox/qml/clients/big_icons/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/big_icons/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/compact/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/compact/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/informative/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/informative/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/present_windows/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/present_windows/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/small_icons/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/small_icons/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/text/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/text/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/thumbnails/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/thumbnails/metadata.desktop create mode 100644 kwin/tabbox/qml/clients/window_strip/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/clients/window_strip/metadata.desktop create mode 100644 kwin/tabbox/qml/desktops/informative/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/desktops/informative/metadata.desktop create mode 100644 kwin/tabbox/qml/desktops/previews/contents/ui/main.qml create mode 100644 kwin/tabbox/qml/desktops/previews/metadata.desktop create mode 100644 kwin/tabbox/qml/tabbox.qml create mode 100644 kwin/tabbox/tabbox.cpp create mode 100644 kwin/tabbox/tabbox.h create mode 100644 kwin/tabbox/tabboxconfig.cpp create mode 100644 kwin/tabbox/tabboxconfig.h create mode 100644 kwin/tabbox/tabboxhandler.cpp create mode 100644 kwin/tabbox/tabboxhandler.h create mode 100644 kwin/tabbox/tests/CMakeLists.txt create mode 100644 kwin/tabbox/tests/mock_declarative.cpp create mode 100644 kwin/tabbox/tests/mock_tabboxclient.cpp create mode 100644 kwin/tabbox/tests/mock_tabboxclient.h create mode 100644 kwin/tabbox/tests/mock_tabboxhandler.cpp create mode 100644 kwin/tabbox/tests/mock_tabboxhandler.h create mode 100644 kwin/tabbox/tests/test_desktopchain.cpp create mode 100644 kwin/tabbox/tests/test_tabbox_clientmodel.cpp create mode 100644 kwin/tabbox/tests/test_tabbox_clientmodel.h create mode 100644 kwin/tabbox/tests/test_tabbox_config.cpp create mode 100644 kwin/tabbox/tests/test_tabbox_handler.cpp create mode 100644 kwin/tabgroup.cpp create mode 100644 kwin/tabgroup.h create mode 100644 kwin/tests/CMakeLists.txt create mode 100644 kwin/tests/test_client_machine.cpp create mode 100644 kwin/tests/test_screen_paint_data.cpp create mode 100644 kwin/tests/test_update_kwin_49.cpp create mode 100644 kwin/tests/test_virtual_desktops.cpp create mode 100644 kwin/tests/test_window_paint_data.cpp create mode 100644 kwin/tests/test_xcb_window.cpp create mode 100644 kwin/tests/test_xcb_wrapper.cpp create mode 100644 kwin/tests/testutils.h create mode 100644 kwin/thumbnailitem.cpp create mode 100644 kwin/thumbnailitem.h create mode 100644 kwin/toplevel.cpp create mode 100644 kwin/toplevel.h create mode 100644 kwin/unmanaged.cpp create mode 100644 kwin/unmanaged.h create mode 100755 kwin/useractions.cpp create mode 100644 kwin/useractions.h create mode 100644 kwin/utils.cpp create mode 100644 kwin/utils.h create mode 100644 kwin/virtualdesktops.cpp create mode 100644 kwin/virtualdesktops.h create mode 100644 kwin/workspace.cpp create mode 100644 kwin/workspace.h create mode 100644 kwin/xcbutils.cpp create mode 100644 kwin/xcbutils.h create mode 100644 kwrited/CMakeLists.txt create mode 100644 kwrited/config-kwrited.h.cmake create mode 100644 kwrited/kwrited-autostart.desktop create mode 100644 kwrited/kwrited.cpp create mode 100644 kwrited/kwrited.desktop create mode 100644 kwrited/kwrited.h create mode 100644 kwrited/kwrited.notifyrc create mode 100644 libs/CMakeLists.txt create mode 100644 libs/Mainpage.dox create mode 100644 libs/kdm/CMakeLists.txt create mode 100644 libs/kdm/Messages.sh create mode 100644 libs/kdm/kgreet_classic.cpp create mode 100644 libs/kdm/kgreet_classic.h create mode 100644 libs/kdm/kgreet_generic.cpp create mode 100644 libs/kdm/kgreet_generic.h create mode 100644 libs/kdm/kgreet_winbind.cpp create mode 100644 libs/kdm/kgreet_winbind.h create mode 100644 libs/kdm/kgreeterplugin.h create mode 100644 libs/kephal/CMakeLists.txt create mode 100644 libs/kephal/Mainpage.dox create mode 100644 libs/kephal/README create mode 100644 libs/kephal/client/CMakeLists.txt create mode 100644 libs/kephal/client/FindKephal.cmake create mode 100644 libs/kephal/client/dbusconfigurations.cpp create mode 100644 libs/kephal/client/dbusconfigurations.h create mode 100644 libs/kephal/client/dbusoutputs.cpp create mode 100644 libs/kephal/client/dbusoutputs.h create mode 100644 libs/kephal/client/dbusscreens.cpp create mode 100644 libs/kephal/client/dbusscreens.h create mode 100644 libs/kephal/client/libkephal.cpp create mode 100644 libs/kephal/client/noconfigurations.cpp create mode 100644 libs/kephal/client/noconfigurations.h create mode 100644 libs/kephal/kephal/config-kephal.h.cmake create mode 100644 libs/kephal/kephal/configurations.cpp create mode 100644 libs/kephal/kephal/configurations.h create mode 100644 libs/kephal/kephal/desktopwidgetoutputs.cpp create mode 100644 libs/kephal/kephal/desktopwidgetoutputs.h create mode 100644 libs/kephal/kephal/desktopwidgetscreens.cpp create mode 100644 libs/kephal/kephal/desktopwidgetscreens.h create mode 100644 libs/kephal/kephal/kephal.h create mode 100644 libs/kephal/kephal/kephal_export.h create mode 100644 libs/kephal/kephal/outputs.cpp create mode 100644 libs/kephal/kephal/outputs.h create mode 100644 libs/kephal/kephal/screens.cpp create mode 100644 libs/kephal/kephal/screens.h create mode 100644 libs/kephal/kephal/simpleoutput.cpp create mode 100644 libs/kephal/kephal/simpleoutput.h create mode 100644 libs/kephal/kephal/simplescreen.cpp create mode 100644 libs/kephal/kephal/simplescreen.h create mode 100644 libs/kephal/service/CMakeLists.txt create mode 100644 libs/kephal/service/README create mode 100644 libs/kephal/service/backend.h create mode 100644 libs/kephal/service/backendconfigurations.cpp create mode 100644 libs/kephal/service/backendconfigurations.h create mode 100644 libs/kephal/service/backendoutputs.cpp create mode 100644 libs/kephal/service/backendoutputs.h create mode 100644 libs/kephal/service/configurationscreens.cpp create mode 100644 libs/kephal/service/configurationscreens.h create mode 100644 libs/kephal/service/dbus/dbusapi_configurations.cpp create mode 100644 libs/kephal/service/dbus/dbusapi_configurations.h create mode 100644 libs/kephal/service/dbus/dbusapi_outputs.cpp create mode 100644 libs/kephal/service/dbus/dbusapi_outputs.h create mode 100644 libs/kephal/service/dbus/dbusapi_screens.cpp create mode 100644 libs/kephal/service/dbus/dbusapi_screens.h create mode 100644 libs/kephal/service/edid.h create mode 100644 libs/kephal/service/externalconfiguration.cpp create mode 100644 libs/kephal/service/externalconfiguration.h create mode 100644 libs/kephal/service/kephal.desktop create mode 100644 libs/kephal/service/kephald.cpp create mode 100644 libs/kephal/service/kephald.h create mode 100644 libs/kephal/service/kephalservice.cpp create mode 100644 libs/kephal/service/kephalservice.h create mode 100644 libs/kephal/service/outputscreens.cpp create mode 100644 libs/kephal/service/outputscreens.h create mode 100644 libs/kephal/service/standalonekephald.cpp create mode 100644 libs/kephal/service/xml/README create mode 100644 libs/kephal/service/xml/configurations_xml.cpp create mode 100644 libs/kephal/service/xml/configurations_xml.h create mode 100644 libs/kephal/service/xml/xmlnodehandler.cpp create mode 100644 libs/kephal/service/xml/xmlnodehandler.h create mode 100644 libs/kephal/service/xml/xmlnodehandler.h.cpp create mode 100644 libs/kephal/service/xml/xmltype.cpp create mode 100644 libs/kephal/service/xml/xmltype.h create mode 100644 libs/kephal/service/xmlconfiguration.cpp create mode 100644 libs/kephal/service/xmlconfiguration.h create mode 100644 libs/kephal/service/xmlconfigurations.cpp create mode 100644 libs/kephal/service/xmlconfigurations.h create mode 100644 libs/kephal/service/xrandr12/README create mode 100644 libs/kephal/service/xrandr12/randr.cpp create mode 100644 libs/kephal/service/xrandr12/randr.h create mode 100644 libs/kephal/service/xrandr12/randrcrtc.cpp create mode 100644 libs/kephal/service/xrandr12/randrcrtc.h create mode 100644 libs/kephal/service/xrandr12/randrdisplay.cpp create mode 100644 libs/kephal/service/xrandr12/randrdisplay.h create mode 100644 libs/kephal/service/xrandr12/randrmode.cpp create mode 100644 libs/kephal/service/xrandr12/randrmode.h create mode 100644 libs/kephal/service/xrandr12/randroutput.cpp create mode 100644 libs/kephal/service/xrandr12/randroutput.h create mode 100644 libs/kephal/service/xrandr12/randrscreen.cpp create mode 100644 libs/kephal/service/xrandr12/randrscreen.h create mode 100644 libs/kephal/service/xrandroutputs.cpp create mode 100644 libs/kephal/service/xrandroutputs.h create mode 100644 libs/kephal/tests/CMakeLists.txt create mode 100644 libs/kephal/tests/README create mode 100644 libs/kephal/tests/kephalapp.cpp create mode 100644 libs/kephal/tests/kephalapp.h create mode 100644 libs/ksysguard/CMakeLists.txt create mode 100644 libs/ksysguard/config-ksysguard.h.cmake create mode 100644 libs/ksysguard/ksgrd/CMakeLists.txt create mode 100755 libs/ksysguard/ksgrd/Messages.sh create mode 100644 libs/ksysguard/ksgrd/SensorAgent.cpp create mode 100644 libs/ksysguard/ksgrd/SensorAgent.h create mode 100644 libs/ksysguard/ksgrd/SensorClient.h create mode 100644 libs/ksysguard/ksgrd/SensorManager.cpp create mode 100644 libs/ksysguard/ksgrd/SensorManager.h create mode 100644 libs/ksysguard/ksgrd/SensorShellAgent.cpp create mode 100644 libs/ksysguard/ksgrd/SensorShellAgent.h create mode 100644 libs/ksysguard/ksgrd/SensorSocketAgent.cpp create mode 100644 libs/ksysguard/ksgrd/SensorSocketAgent.h create mode 100644 libs/ksysguard/lsofui/CMakeLists.txt create mode 100644 libs/ksysguard/lsofui/LsofSearchWidget.cpp create mode 100644 libs/ksysguard/lsofui/LsofSearchWidget.h create mode 100644 libs/ksysguard/lsofui/LsofSearchWidget.ui create mode 100755 libs/ksysguard/lsofui/Messages.sh create mode 100644 libs/ksysguard/lsofui/ksysguardlsof.widgets create mode 100644 libs/ksysguard/lsofui/lsof.cpp create mode 100644 libs/ksysguard/lsofui/lsof.h create mode 100644 libs/ksysguard/processcore/CMakeLists.txt create mode 100755 libs/ksysguard/processcore/Messages.sh create mode 100644 libs/ksysguard/processcore/actions.actions create mode 100644 libs/ksysguard/processcore/atop_p.h create mode 100644 libs/ksysguard/processcore/helper.cpp create mode 100644 libs/ksysguard/processcore/helper.h create mode 100644 libs/ksysguard/processcore/process.cpp create mode 100644 libs/ksysguard/processcore/process.h create mode 100644 libs/ksysguard/processcore/processes.cpp create mode 100644 libs/ksysguard/processcore/processes.h create mode 100644 libs/ksysguard/processcore/processes_atop_p.cpp create mode 100644 libs/ksysguard/processcore/processes_atop_p.h create mode 100644 libs/ksysguard/processcore/processes_base_p.cpp create mode 100644 libs/ksysguard/processcore/processes_base_p.h create mode 100644 libs/ksysguard/processcore/processes_dragonfly_p.cpp create mode 100644 libs/ksysguard/processcore/processes_freebsd_p.cpp create mode 100644 libs/ksysguard/processcore/processes_gnu_p.cpp create mode 100644 libs/ksysguard/processcore/processes_linux_p.cpp create mode 100644 libs/ksysguard/processcore/processes_local_p.cpp create mode 100644 libs/ksysguard/processcore/processes_local_p.h create mode 100644 libs/ksysguard/processcore/processes_netbsd_p.cpp create mode 100644 libs/ksysguard/processcore/processes_openbsd_p.cpp create mode 100644 libs/ksysguard/processcore/processes_remote_p.cpp create mode 100644 libs/ksysguard/processcore/processes_remote_p.h create mode 100644 libs/ksysguard/processcore/processes_solaris_p.cpp create mode 100644 libs/ksysguard/processui/CMakeLists.txt create mode 100644 libs/ksysguard/processui/KTextEditVT.cpp create mode 100644 libs/ksysguard/processui/KTextEditVT.h create mode 100755 libs/ksysguard/processui/Messages.sh create mode 100644 libs/ksysguard/processui/ProcessFilter.cpp create mode 100644 libs/ksysguard/processui/ProcessFilter.h create mode 100644 libs/ksysguard/processui/ProcessModel.cpp create mode 100644 libs/ksysguard/processui/ProcessModel.h create mode 100644 libs/ksysguard/processui/ProcessModel_p.h create mode 100644 libs/ksysguard/processui/ProcessWidgetUI.ui create mode 100644 libs/ksysguard/processui/ReniceDlg.cpp create mode 100644 libs/ksysguard/processui/ReniceDlg.h create mode 100644 libs/ksysguard/processui/ReniceDlgUi.ui create mode 100644 libs/ksysguard/processui/ksysguard.widgets create mode 100644 libs/ksysguard/processui/ksysguardprocesslist.cpp create mode 100644 libs/ksysguard/processui/ksysguardprocesslist.h create mode 100644 libs/ksysguard/processui/scripting.cpp create mode 100644 libs/ksysguard/processui/scripting.h create mode 100644 libs/ksysguard/scripts/README create mode 100644 libs/ksysguard/scripts/smaps/helper.js create mode 100644 libs/ksysguard/scripts/smaps/index.html create mode 100644 libs/ksysguard/scripts/smaps/main.js create mode 100644 libs/ksysguard/scripts/smaps/smaps.desktop create mode 100644 libs/ksysguard/scripts/smaps/sorttable.js create mode 100644 libs/ksysguard/scripts/smaps/style.css create mode 100644 libs/ksysguard/signalplotter/CMakeLists.txt create mode 100644 libs/ksysguard/signalplotter/kgraphicssignalplotter.cpp create mode 100644 libs/ksysguard/signalplotter/kgraphicssignalplotter.h create mode 100644 libs/ksysguard/signalplotter/ksignalplotter.cpp create mode 100644 libs/ksysguard/signalplotter/ksignalplotter.h create mode 100644 libs/ksysguard/signalplotter/ksignalplotter.widgets create mode 100644 libs/ksysguard/signalplotter/ksignalplotter_p.h create mode 100644 libs/ksysguard/tests/CMakeLists.txt create mode 100644 libs/ksysguard/tests/graphicssignalplotterbenchmark.cpp create mode 100644 libs/ksysguard/tests/graphicssignalplotterbenchmark.h create mode 100644 libs/ksysguard/tests/guitest.cpp create mode 100644 libs/ksysguard/tests/guitest.h create mode 100644 libs/ksysguard/tests/processtest.cpp create mode 100644 libs/ksysguard/tests/processtest.h create mode 100644 libs/ksysguard/tests/signalplotterbenchmark.cpp create mode 100644 libs/ksysguard/tests/signalplotterbenchmark.h create mode 100644 libs/ksysguard/tests/signalplottertest.cpp create mode 100644 libs/ksysguard/tests/signalplottertest.h create mode 100644 libs/kworkspace/CMakeLists.txt create mode 100644 libs/kworkspace/Mainpage.dox create mode 100644 libs/kworkspace/Messages.sh create mode 100644 libs/kworkspace/README create mode 100644 libs/kworkspace/interface_util.h create mode 100644 libs/kworkspace/kdisplaymanager.cpp create mode 100644 libs/kworkspace/kdisplaymanager.h create mode 100644 libs/kworkspace/kwindowlistmenu.cpp create mode 100644 libs/kworkspace/kwindowlistmenu.h create mode 100644 libs/kworkspace/kworkspace.cpp create mode 100644 libs/kworkspace/kworkspace.h create mode 100644 libs/kworkspace/kworkspace_export.h create mode 100644 libs/kworkspace/kworkspace_p.h create mode 100644 libs/kworkspace/org.kde.ActivityManager.xml create mode 100644 libs/kworkspace/screenpreviewwidget.cpp create mode 100644 libs/kworkspace/screenpreviewwidget.h create mode 100644 libs/oxygen/CMakeLists.txt create mode 100644 libs/oxygen/Messages.sh create mode 100644 libs/oxygen/oxygen_export.h create mode 100644 libs/oxygen/oxygenactiveshadowconfigdata.kcfg create mode 100644 libs/oxygen/oxygenactiveshadowconfiguration.kcfgc create mode 100644 libs/oxygen/oxygenanimation.cpp create mode 100644 libs/oxygen/oxygenanimation.h create mode 100644 libs/oxygen/oxygenanimationconfigitem.cpp create mode 100644 libs/oxygen/oxygenanimationconfigitem.h create mode 100644 libs/oxygen/oxygenbaseanimationconfigwidget.cpp create mode 100644 libs/oxygen/oxygenbaseanimationconfigwidget.h create mode 100644 libs/oxygen/oxygengenericanimationconfigitem.cpp create mode 100644 libs/oxygen/oxygengenericanimationconfigitem.h create mode 100644 libs/oxygen/oxygenhelper.cpp create mode 100644 libs/oxygen/oxygenhelper.h create mode 100644 libs/oxygen/oxygeninactiveshadowconfigdata.kcfg create mode 100644 libs/oxygen/oxygeninactiveshadowconfiguration.kcfgc create mode 100644 libs/oxygen/oxygenitemmodel.cpp create mode 100644 libs/oxygen/oxygenitemmodel.h create mode 100644 libs/oxygen/oxygenlistmodel.h create mode 100644 libs/oxygen/oxygenshadowcache.cpp create mode 100644 libs/oxygen/oxygenshadowcache.h create mode 100644 libs/oxygen/oxygenshadowconfigwidget.cpp create mode 100644 libs/oxygen/oxygenshadowconfigwidget.h create mode 100644 libs/oxygen/oxygentileset.cpp create mode 100644 libs/oxygen/oxygentileset.h create mode 100644 libs/oxygen/oxygenutil.cpp create mode 100644 libs/oxygen/oxygenutil.h create mode 100644 libs/oxygen/ui/oxygenanimationconfigitem.ui create mode 100644 libs/oxygen/ui/oxygenanimationconfigwidget.ui create mode 100644 libs/oxygen/ui/oxygengenericanimationconfigbox.ui create mode 100644 libs/oxygen/ui/oxygenshadowconfigurationui.ui create mode 100644 libs/plasmaclock/CMakeLists.txt create mode 100755 libs/plasmaclock/Messages.sh create mode 100644 libs/plasmaclock/calendar.cpp create mode 100644 libs/plasmaclock/calendar.h create mode 100644 libs/plasmaclock/calendarConfig.ui create mode 100644 libs/plasmaclock/calendarHolidaysConfig.ui create mode 100644 libs/plasmaclock/calendartable.cpp create mode 100644 libs/plasmaclock/calendartable.h create mode 100644 libs/plasmaclock/clockapplet.cpp create mode 100644 libs/plasmaclock/clockapplet.h create mode 100644 libs/plasmaclock/config-calendartable.h.cmake create mode 100644 libs/plasmaclock/generalConfig.ui create mode 100644 libs/plasmaclock/plasmaclock_export.h create mode 100644 libs/plasmaclock/timezonesConfig.ui create mode 100644 libs/plasmaclock/wheelytoolbutton.cpp create mode 100644 libs/plasmaclock/wheelytoolbutton.h create mode 100644 libs/plasmagenericshell/BackgroundDialog.ui create mode 100644 libs/plasmagenericshell/CMakeLists.txt create mode 100755 libs/plasmagenericshell/Messages.sh create mode 100644 libs/plasmagenericshell/MousePlugins.ui create mode 100644 libs/plasmagenericshell/TODO create mode 100644 libs/plasmagenericshell/backgrounddialog.cpp create mode 100644 libs/plasmagenericshell/backgrounddialog.h create mode 100644 libs/plasmagenericshell/mouseinputbutton.cpp create mode 100644 libs/plasmagenericshell/mouseinputbutton.h create mode 100644 libs/plasmagenericshell/mouseplugins.cpp create mode 100644 libs/plasmagenericshell/mouseplugins.h create mode 100644 libs/plasmagenericshell/mousepluginwidget.cpp create mode 100644 libs/plasmagenericshell/mousepluginwidget.h create mode 100644 libs/plasmagenericshell/panelshadows.cpp create mode 100644 libs/plasmagenericshell/panelshadows.h create mode 100644 libs/plasmagenericshell/plasma-layout-template.desktop create mode 100644 libs/plasmagenericshell/plasmagenericshell_export.h create mode 100644 libs/plasmagenericshell/scripting/appinterface.cpp create mode 100644 libs/plasmagenericshell/scripting/appinterface.h create mode 100644 libs/plasmagenericshell/scripting/applet.cpp create mode 100644 libs/plasmagenericshell/scripting/applet.h create mode 100644 libs/plasmagenericshell/scripting/backportglobal.h create mode 100644 libs/plasmagenericshell/scripting/configgroup.cpp create mode 100644 libs/plasmagenericshell/scripting/configgroup.h create mode 100644 libs/plasmagenericshell/scripting/containment.cpp create mode 100644 libs/plasmagenericshell/scripting/containment.h create mode 100644 libs/plasmagenericshell/scripting/i18n.cpp create mode 100644 libs/plasmagenericshell/scripting/i18n.h create mode 100644 libs/plasmagenericshell/scripting/layouttemplatepackagestructure.cpp create mode 100644 libs/plasmagenericshell/scripting/layouttemplatepackagestructure.h create mode 100644 libs/plasmagenericshell/scripting/rect.cpp create mode 100644 libs/plasmagenericshell/scripting/scriptengine.cpp create mode 100644 libs/plasmagenericshell/scripting/scriptengine.h create mode 100644 libs/plasmagenericshell/scripting/widget.cpp create mode 100644 libs/plasmagenericshell/scripting/widget.h create mode 100644 libs/plasmagenericshell/tests/CMakeLists.txt create mode 100644 libs/plasmagenericshell/tests/background.cpp create mode 100644 libs/plasmagenericshell/tests/main.cpp create mode 100644 libs/plasmagenericshell/toolbutton.cpp create mode 100644 libs/plasmagenericshell/toolbutton.h create mode 100644 libs/plasmagenericshell/wallpaperpreview.cpp create mode 100644 libs/plasmagenericshell/wallpaperpreview.h create mode 100644 libs/plasmagenericshell/widgetsexplorer/kcategorizeditemsviewmodels.cpp create mode 100644 libs/plasmagenericshell/widgetsexplorer/kcategorizeditemsviewmodels_p.h create mode 100644 libs/plasmagenericshell/widgetsexplorer/openwidgetassistant.cpp create mode 100644 libs/plasmagenericshell/widgetsexplorer/openwidgetassistant_p.h create mode 100644 libs/plasmagenericshell/widgetsexplorer/package/Messages.sh create mode 100644 libs/plasmagenericshell/widgetsexplorer/package/contents/ui/AppletDelegate.qml create mode 100644 libs/plasmagenericshell/widgetsexplorer/package/contents/ui/Tooltip.qml create mode 100644 libs/plasmagenericshell/widgetsexplorer/package/contents/ui/main.qml create mode 100644 libs/plasmagenericshell/widgetsexplorer/package/metadata.desktop create mode 100644 libs/plasmagenericshell/widgetsexplorer/plasmaappletitemmodel.cpp create mode 100644 libs/plasmagenericshell/widgetsexplorer/plasmaappletitemmodel_p.h create mode 100644 libs/plasmagenericshell/widgetsexplorer/widgetexplorer.cpp create mode 100644 libs/plasmagenericshell/widgetsexplorer/widgetexplorer.h create mode 100644 libs/taskmanager/CMakeLists.txt create mode 100644 libs/taskmanager/Mainpage.dox create mode 100644 libs/taskmanager/Messages.sh create mode 100644 libs/taskmanager/abstractgroupableitem.cpp create mode 100644 libs/taskmanager/abstractgroupableitem.h create mode 100644 libs/taskmanager/abstractgroupingstrategy.cpp create mode 100644 libs/taskmanager/abstractgroupingstrategy.h create mode 100644 libs/taskmanager/abstractsortingstrategy.cpp create mode 100644 libs/taskmanager/abstractsortingstrategy.h create mode 100644 libs/taskmanager/groupmanager.cpp create mode 100644 libs/taskmanager/groupmanager.h create mode 100644 libs/taskmanager/launcherconfig.cpp create mode 100644 libs/taskmanager/launcherconfig.h create mode 100644 libs/taskmanager/launcherconfig.ui create mode 100644 libs/taskmanager/launcheritem.cpp create mode 100644 libs/taskmanager/launcheritem.h create mode 100644 libs/taskmanager/launcherproperties.cpp create mode 100644 libs/taskmanager/launcherproperties.h create mode 100644 libs/taskmanager/launcherproperties.ui create mode 100644 libs/taskmanager/startup.cpp create mode 100644 libs/taskmanager/startup.h create mode 100644 libs/taskmanager/strategies/activitysortingstrategy.cpp create mode 100644 libs/taskmanager/strategies/activitysortingstrategy.h create mode 100644 libs/taskmanager/strategies/alphasortingstrategy.cpp create mode 100644 libs/taskmanager/strategies/alphasortingstrategy.h create mode 100644 libs/taskmanager/strategies/desktopsortingstrategy.cpp create mode 100644 libs/taskmanager/strategies/desktopsortingstrategy.h create mode 100644 libs/taskmanager/strategies/manualgroupingstrategy.cpp create mode 100644 libs/taskmanager/strategies/manualgroupingstrategy.h create mode 100644 libs/taskmanager/strategies/manualsortingstrategy.cpp create mode 100644 libs/taskmanager/strategies/manualsortingstrategy.h create mode 100644 libs/taskmanager/strategies/programgroupingstrategy.cpp create mode 100644 libs/taskmanager/strategies/programgroupingstrategy.h create mode 100644 libs/taskmanager/task.cpp create mode 100644 libs/taskmanager/task.h create mode 100644 libs/taskmanager/task_p.h create mode 100644 libs/taskmanager/task_win.cpp create mode 100644 libs/taskmanager/task_x11.cpp create mode 100644 libs/taskmanager/taskactions.cpp create mode 100644 libs/taskmanager/taskactions.h create mode 100644 libs/taskmanager/taskactions_p.h create mode 100644 libs/taskmanager/taskgroup.cpp create mode 100644 libs/taskmanager/taskgroup.h create mode 100644 libs/taskmanager/taskitem.cpp create mode 100644 libs/taskmanager/taskitem.h create mode 100644 libs/taskmanager/taskmanager.cpp create mode 100644 libs/taskmanager/taskmanager.h create mode 100644 libs/taskmanager/taskmanager_export.h create mode 100644 libs/taskmanager/taskmanagerrulesrc create mode 100644 libs/taskmanager/tasksmodel.cpp create mode 100644 libs/taskmanager/tasksmodel.h create mode 100755 mkpamserv create mode 100644 plasma/.emacs-dirvars create mode 100644 plasma/CMakeLists.txt create mode 100644 plasma/HACKING create mode 100644 plasma/Mainpage.dox create mode 100644 plasma/README create mode 100644 plasma/design/CHANGELOG-4.2 create mode 100644 plasma/design/CHANGELOG-4.3 create mode 100644 plasma/design/CHANGELOG-4.4 create mode 100644 plasma/design/CHANGELOG-4.5 create mode 100644 plasma/design/CHANGELOG-4.6 create mode 100644 plasma/design/CHANGELOG-template create mode 100644 plasma/design/README create mode 100644 plasma/design/activities create mode 100644 plasma/design/containmentactions create mode 100644 plasma/design/context create mode 100644 plasma/design/dataengine create mode 100644 plasma/design/ideas.txt create mode 100644 plasma/design/notifications create mode 100644 plasma/design/plasma-desktop-screen-handling create mode 100644 plasma/design/plasmoids create mode 100644 plasma/design/remotewidgets create mode 100644 plasma/design/screensaver create mode 100644 plasma/design/security create mode 100644 plasma/design/standardEffects create mode 100644 plasma/design/systemtraywidget create mode 100644 plasma/design/tooltips create mode 100644 plasma/design/wallpaper create mode 100644 plasma/design/widgets create mode 100644 plasma/desktop/CMakeLists.txt create mode 100644 plasma/desktop/applets/CMakeLists.txt create mode 100644 plasma/desktop/applets/kickoff/CMakeLists.txt create mode 100644 plasma/desktop/applets/kickoff/DESIGN-GOALS create mode 100644 plasma/desktop/applets/kickoff/Messages.sh create mode 100644 plasma/desktop/applets/kickoff/STATUS-TODO create mode 100644 plasma/desktop/applets/kickoff/applet/applet.cpp create mode 100644 plasma/desktop/applets/kickoff/applet/applet.h create mode 100644 plasma/desktop/applets/kickoff/applet/kickoffConfig.ui create mode 100644 plasma/desktop/applets/kickoff/applet/plasma-applet-launcher.desktop create mode 100644 plasma/desktop/applets/kickoff/core/applicationmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/applicationmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/favoritesmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/favoritesmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/itemhandlers.cpp create mode 100644 plasma/desktop/applets/kickoff/core/itemhandlers.h create mode 100644 plasma/desktop/applets/kickoff/core/kickoff_export.h create mode 100644 plasma/desktop/applets/kickoff/core/kickoffabstractmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/kickoffabstractmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/kickoffmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/kickoffmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/kickoffproxymodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/kickoffproxymodel.h create mode 100644 plasma/desktop/applets/kickoff/core/krunnermodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/krunnermodel.h create mode 100644 plasma/desktop/applets/kickoff/core/leavemodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/leavemodel.h create mode 100644 plasma/desktop/applets/kickoff/core/models.cpp create mode 100644 plasma/desktop/applets/kickoff/core/models.h create mode 100644 plasma/desktop/applets/kickoff/core/org.kde.kickoff.recent.xml create mode 100644 plasma/desktop/applets/kickoff/core/org.kde.kickoff.xml create mode 100644 plasma/desktop/applets/kickoff/core/recentapplications.cpp create mode 100644 plasma/desktop/applets/kickoff/core/recentapplications.h create mode 100644 plasma/desktop/applets/kickoff/core/recentlyusedmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/recentlyusedmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/systemmodel.cpp create mode 100644 plasma/desktop/applets/kickoff/core/systemmodel.h create mode 100644 plasma/desktop/applets/kickoff/core/urlitemlauncher.cpp create mode 100644 plasma/desktop/applets/kickoff/core/urlitemlauncher.h create mode 100644 plasma/desktop/applets/kickoff/main.cpp create mode 100644 plasma/desktop/applets/kickoff/simpleapplet/menuview.cpp create mode 100644 plasma/desktop/applets/kickoff/simpleapplet/menuview.h create mode 100644 plasma/desktop/applets/kickoff/simpleapplet/plasma-applet-simplelauncher.desktop create mode 100644 plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.cpp create mode 100644 plasma/desktop/applets/kickoff/simpleapplet/simpleapplet.h create mode 100644 plasma/desktop/applets/kickoff/ui/brandingbutton.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/brandingbutton.h create mode 100644 plasma/desktop/applets/kickoff/ui/contentareacap.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/contentareacap.h create mode 100644 plasma/desktop/applets/kickoff/ui/contextmenufactory.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/contextmenufactory.h create mode 100644 plasma/desktop/applets/kickoff/ui/flipscrollview.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/flipscrollview.h create mode 100644 plasma/desktop/applets/kickoff/ui/itemdelegate.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/itemdelegate.h create mode 100644 plasma/desktop/applets/kickoff/ui/launcher.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/launcher.h create mode 100644 plasma/desktop/applets/kickoff/ui/searchbar.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/searchbar.h create mode 100644 plasma/desktop/applets/kickoff/ui/tabbar.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/tabbar.h create mode 100644 plasma/desktop/applets/kickoff/ui/urlitemview.cpp create mode 100644 plasma/desktop/applets/kickoff/ui/urlitemview.h create mode 100644 plasma/desktop/applets/pager/CMakeLists.txt create mode 100755 plasma/desktop/applets/pager/Messages.sh create mode 100644 plasma/desktop/applets/pager/model.cpp create mode 100644 plasma/desktop/applets/pager/model.h create mode 100644 plasma/desktop/applets/pager/package/contents/ui/main.qml create mode 100644 plasma/desktop/applets/pager/package/contents/ui/utils.js create mode 100644 plasma/desktop/applets/pager/package/metadata.desktop create mode 100644 plasma/desktop/applets/pager/pager.cpp create mode 100644 plasma/desktop/applets/pager/pager.h create mode 100644 plasma/desktop/applets/pager/pagerConfig.ui create mode 100644 plasma/desktop/applets/pager/plasma-pager-default.desktop create mode 100644 plasma/desktop/applets/showActivityManager/CMakeLists.txt create mode 100644 plasma/desktop/applets/showActivityManager/Messages.sh create mode 100644 plasma/desktop/applets/showActivityManager/activities.svgz create mode 100644 plasma/desktop/applets/showActivityManager/package/contents/ui/main.qml create mode 100644 plasma/desktop/applets/showActivityManager/package/metadata.desktop create mode 100644 plasma/desktop/applets/tasks/CMakeLists.txt create mode 100755 plasma/desktop/applets/tasks/Messages.sh create mode 100644 plasma/desktop/applets/tasks/package/contents/code/layout.js create mode 100644 plasma/desktop/applets/tasks/package/contents/code/tools.js create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/GroupDialog.qml create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/GroupExpanderOverlay.qml create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/MouseHandler.qml create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/Task.qml create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/TaskList.qml create mode 100644 plasma/desktop/applets/tasks/package/contents/ui/main.qml create mode 100644 plasma/desktop/applets/tasks/package/metadata.desktop create mode 100644 plasma/desktop/applets/tasks/plasma-tasks-default.desktop create mode 100644 plasma/desktop/applets/tasks/support/declarativeitemcontainer.cpp create mode 100644 plasma/desktop/applets/tasks/support/declarativeitemcontainer_p.h create mode 100644 plasma/desktop/applets/tasks/support/draghelper.cpp create mode 100644 plasma/desktop/applets/tasks/support/draghelper.h create mode 100644 plasma/desktop/applets/tasks/support/textlabel.cpp create mode 100644 plasma/desktop/applets/tasks/support/textlabel.h create mode 100644 plasma/desktop/applets/tasks/support/tooltip.cpp create mode 100644 plasma/desktop/applets/tasks/support/tooltip.h create mode 100644 plasma/desktop/applets/tasks/tasks.cpp create mode 100644 plasma/desktop/applets/tasks/tasks.h create mode 100644 plasma/desktop/applets/tasks/tasksConfig.ui create mode 100644 plasma/desktop/applets/trash/CMakeLists.txt create mode 100755 plasma/desktop/applets/trash/Messages.sh create mode 100644 plasma/desktop/applets/trash/plasma-applet-trash.desktop create mode 100644 plasma/desktop/applets/trash/trash.cpp create mode 100644 plasma/desktop/applets/trash/trash.h create mode 100644 plasma/desktop/applets/windowlist/CMakeLists.txt create mode 100644 plasma/desktop/applets/windowlist/Messages.sh create mode 100644 plasma/desktop/applets/windowlist/WindowList.cpp create mode 100644 plasma/desktop/applets/windowlist/WindowList.h create mode 100644 plasma/desktop/applets/windowlist/plasma-applet-windowlist.desktop create mode 100644 plasma/desktop/containments/CMakeLists.txt create mode 100644 plasma/desktop/containments/desktop/CMakeLists.txt create mode 100755 plasma/desktop/containments/desktop/Messages.sh create mode 100644 plasma/desktop/containments/desktop/desktop.cpp create mode 100644 plasma/desktop/containments/desktop/desktop.h create mode 100644 plasma/desktop/containments/desktop/desktoplayout.cpp create mode 100644 plasma/desktop/containments/desktop/desktoplayout.h create mode 100644 plasma/desktop/containments/desktop/itemspace.cpp create mode 100644 plasma/desktop/containments/desktop/itemspace.h create mode 100644 plasma/desktop/containments/desktop/plasma-containment-desktop.desktop create mode 100644 plasma/desktop/containments/desktop/plasma-containment-desktopdashboard.desktop create mode 100644 plasma/desktop/containments/desktop/plasma_desktop_containment.kwinrules create mode 100644 plasma/desktop/containments/panel/CMakeLists.txt create mode 100755 plasma/desktop/containments/panel/Messages.sh create mode 100644 plasma/desktop/containments/panel/panel.cpp create mode 100644 plasma/desktop/containments/panel/panel.h create mode 100644 plasma/desktop/containments/panel/plasma-containment-panel.desktop create mode 100644 plasma/desktop/runners/CMakeLists.txt create mode 100644 plasma/desktop/runners/plasma-desktop/CMakeLists.txt create mode 100755 plasma/desktop/runners/plasma-desktop/Messages.sh create mode 100644 plasma/desktop/runners/plasma-desktop/plasma-desktop-runner.cpp create mode 100644 plasma/desktop/runners/plasma-desktop/plasma-desktop-runner.h create mode 100644 plasma/desktop/runners/plasma-desktop/plasma-runner-plasma-desktop.desktop create mode 100644 plasma/desktop/shell/CMakeLists.txt create mode 100755 plasma/desktop/shell/Messages.sh create mode 100644 plasma/desktop/shell/accessibility/accessiblefactory.cpp create mode 100644 plasma/desktop/shell/accessibility/accessiblefactory.h create mode 100644 plasma/desktop/shell/accessibility/accessibleplasmaview.cpp create mode 100644 plasma/desktop/shell/accessibility/accessibleplasmaview.h create mode 100644 plasma/desktop/shell/activity.cpp create mode 100644 plasma/desktop/shell/activity.h create mode 100644 plasma/desktop/shell/activitymanager/Messages.sh create mode 100644 plasma/desktop/shell/activitymanager/activities.knsrc create mode 100644 plasma/desktop/shell/activitymanager/activitymanager.cpp create mode 100644 plasma/desktop/shell/activitymanager/activitymanager.h create mode 100644 plasma/desktop/shell/activitymanager/kidenticongenerator.cpp create mode 100644 plasma/desktop/shell/activitymanager/kidenticongenerator.h create mode 100644 plasma/desktop/shell/activitymanager/package/contents/ui/.directory create mode 100644 plasma/desktop/shell/activitymanager/package/contents/ui/ActivityDelegate.qml create mode 100644 plasma/desktop/shell/activitymanager/package/contents/ui/main.qml create mode 100644 plasma/desktop/shell/activitymanager/package/metadata.desktop create mode 100644 plasma/desktop/shell/checkbox.cpp create mode 100644 plasma/desktop/shell/checkbox.h create mode 100644 plasma/desktop/shell/configupdates/CMakeLists.txt create mode 100644 plasma/desktop/shell/configupdates/addShowActivitiesManagerPlasmoid.js create mode 100644 plasma/desktop/shell/configupdates/notifications-to-orgkdenotifications.cpp create mode 100644 plasma/desktop/shell/configupdates/notifications-to-orgkdenotifications.upd create mode 100644 plasma/desktop/shell/configupdates/plasma-add-shortcut-to-menu.cpp create mode 100644 plasma/desktop/shell/configupdates/plasma-add-shortcut-to-menu.upd create mode 100644 plasma/desktop/shell/configupdates/plasma-to-plasma-desktop.cpp create mode 100644 plasma/desktop/shell/configupdates/plasma-to-plasmadesktop-shortcuts.upd create mode 100644 plasma/desktop/shell/configupdates/plasmarc-to-plasmadesktoprc.upd create mode 100644 plasma/desktop/shell/configupdates/set-hidden-single-vd-pager.js create mode 100644 plasma/desktop/shell/configupdates/systray-to-notifications-widget.js create mode 100644 plasma/desktop/shell/controllerwindow.cpp create mode 100644 plasma/desktop/shell/controllerwindow.h create mode 100644 plasma/desktop/shell/dashboardview.cpp create mode 100644 plasma/desktop/shell/dashboardview.h create mode 100644 plasma/desktop/shell/data/layouts/00-defaultLayout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.SaL/contents/layout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.SaL/metadata.desktop create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/contents/layout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.defaultPanel/metadata.desktop create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.desktopIcons/contents/layout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.desktopIcons/metadata.desktop create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.findWidgets/contents/layout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.findWidgets/metadata.desktop create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.photoActivity/contents/layout.js create mode 100644 plasma/desktop/shell/data/layouts/org.kde.plasma-desktop.photoActivity/metadata.desktop create mode 100644 plasma/desktop/shell/data/plasma-desktop-js.xml create mode 100644 plasma/desktop/shell/data/plasma-desktop.desktop create mode 100644 plasma/desktop/shell/data/plasma-desktop.notifyrc create mode 100644 plasma/desktop/shell/data/plasma-shell-desktop.kcfg create mode 100644 plasma/desktop/shell/data/plasma-shell-desktop.kcfgc create mode 100644 plasma/desktop/shell/data/plasma-themes.knsrc create mode 100644 plasma/desktop/shell/data/plasma.desktop create mode 100644 plasma/desktop/shell/dbus/org.kde.plasma.App.xml create mode 100644 plasma/desktop/shell/desktopcorona.cpp create mode 100644 plasma/desktop/shell/desktopcorona.h create mode 100644 plasma/desktop/shell/desktopview.cpp create mode 100644 plasma/desktop/shell/desktopview.h create mode 100644 plasma/desktop/shell/interactiveconsole.cpp create mode 100644 plasma/desktop/shell/interactiveconsole.h create mode 100644 plasma/desktop/shell/klistconfirmationdialog.cpp create mode 100644 plasma/desktop/shell/klistconfirmationdialog.h create mode 100644 plasma/desktop/shell/main.cpp create mode 100644 plasma/desktop/shell/panelapplethandle.cpp create mode 100644 plasma/desktop/shell/panelapplethandle.h create mode 100644 plasma/desktop/shell/panelappletoverlay.cpp create mode 100644 plasma/desktop/shell/panelappletoverlay.h create mode 100644 plasma/desktop/shell/panelcontroller.cpp create mode 100644 plasma/desktop/shell/panelcontroller.h create mode 100644 plasma/desktop/shell/panelview.cpp create mode 100644 plasma/desktop/shell/panelview.h create mode 100644 plasma/desktop/shell/panelview_win.cpp create mode 100644 plasma/desktop/shell/plasmaapp.cpp create mode 100644 plasma/desktop/shell/plasmaapp.h create mode 100644 plasma/desktop/shell/positioningruler.cpp create mode 100644 plasma/desktop/shell/positioningruler.h create mode 100644 plasma/desktop/shell/scripting/desktopscriptengine.cpp create mode 100644 plasma/desktop/shell/scripting/desktopscriptengine.h create mode 100644 plasma/desktop/shell/scripting/panel.cpp create mode 100644 plasma/desktop/shell/scripting/panel.h create mode 100644 plasma/desktop/shell/supportinformation.cpp create mode 100644 plasma/desktop/shell/supportinformation.h create mode 100644 plasma/desktop/toolboxes/CMakeLists.txt create mode 100644 plasma/desktop/toolboxes/Messages.sh create mode 100644 plasma/desktop/toolboxes/desktoptoolbox.cpp create mode 100644 plasma/desktop/toolboxes/desktoptoolbox.h create mode 100644 plasma/desktop/toolboxes/internaltoolbox.cpp create mode 100644 plasma/desktop/toolboxes/internaltoolbox.h create mode 100644 plasma/desktop/toolboxes/paneltoolbox.cpp create mode 100644 plasma/desktop/toolboxes/paneltoolbox.h create mode 100644 plasma/desktop/toolboxes/plasma-toolbox-desktoptoolbox.desktop create mode 100644 plasma/desktop/toolboxes/plasma-toolbox-paneltoolbox.desktop create mode 100644 plasma/generic/CMakeLists.txt create mode 100644 plasma/generic/animators/CMakeLists.txt create mode 100644 plasma/generic/animators/Mainpage.dox create mode 100644 plasma/generic/animators/default/CMakeLists.txt create mode 100644 plasma/generic/animators/default/defaultAnimator.cpp create mode 100644 plasma/generic/animators/default/defaultAnimator.h create mode 100644 plasma/generic/animators/default/plasma-animator-default.desktop create mode 100644 plasma/generic/applets/CMakeLists.txt create mode 100644 plasma/generic/applets/Mainpage.dox create mode 100644 plasma/generic/applets/activitybar/CMakeLists.txt create mode 100644 plasma/generic/applets/activitybar/Messages.sh create mode 100644 plasma/generic/applets/activitybar/activitybar.cpp create mode 100644 plasma/generic/applets/activitybar/activitybar.h create mode 100644 plasma/generic/applets/activitybar/plasma-applet-activitybar.desktop create mode 100644 plasma/generic/applets/analog-clock/CMakeLists.txt create mode 100644 plasma/generic/applets/analog-clock/Messages.sh create mode 100644 plasma/generic/applets/analog-clock/clock.cpp create mode 100644 plasma/generic/applets/analog-clock/clock.h create mode 100644 plasma/generic/applets/analog-clock/clockConfig.ui create mode 100644 plasma/generic/applets/analog-clock/plasma-applet-analogclock.desktop create mode 100644 plasma/generic/applets/batterymonitor/CMakeLists.txt create mode 100755 plasma/generic/applets/batterymonitor/Messages.sh create mode 100644 plasma/generic/applets/batterymonitor/README.txt create mode 100644 plasma/generic/applets/batterymonitor/battery-oxygen-inkscape.svgz create mode 100644 plasma/generic/applets/batterymonitor/battery-oxygen.svgz create mode 100644 plasma/generic/applets/batterymonitor/contents/code/logic.js create mode 100644 plasma/generic/applets/batterymonitor/contents/config/main.xml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/BatteryIcon.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/BatteryItem.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/BrightnessItem.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/CompactRepresentation.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/PopupDialog.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/PowerManagementItem.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/ScrollableListView.qml create mode 100644 plasma/generic/applets/batterymonitor/contents/ui/batterymonitor.qml create mode 100644 plasma/generic/applets/batterymonitor/metadata.desktop create mode 100644 plasma/generic/applets/calendar/CMakeLists.txt create mode 100644 plasma/generic/applets/calendar/calendar.cpp create mode 100644 plasma/generic/applets/calendar/calendar.h create mode 100644 plasma/generic/applets/calendar/mini-calendar.svgz create mode 100644 plasma/generic/applets/calendar/plasma-applet-calendar.desktop create mode 100644 plasma/generic/applets/devicenotifier/CMakeLists.txt create mode 100644 plasma/generic/applets/devicenotifier/Messages.sh create mode 100644 plasma/generic/applets/devicenotifier/package/contents/config/main.xml create mode 100644 plasma/generic/applets/devicenotifier/package/contents/ui/ActionItem.qml create mode 100644 plasma/generic/applets/devicenotifier/package/contents/ui/DeviceItem.qml create mode 100644 plasma/generic/applets/devicenotifier/package/contents/ui/StatusBar.qml create mode 100644 plasma/generic/applets/devicenotifier/package/contents/ui/config.ui create mode 100644 plasma/generic/applets/devicenotifier/package/contents/ui/devicenotifier.qml create mode 100644 plasma/generic/applets/devicenotifier/package/metadata.desktop create mode 100644 plasma/generic/applets/devicenotifier/test-predicate-openinwindow.desktop create mode 100644 plasma/generic/applets/digital-clock/CMakeLists.txt create mode 100755 plasma/generic/applets/digital-clock/Messages.sh create mode 100644 plasma/generic/applets/digital-clock/clock.cpp create mode 100644 plasma/generic/applets/digital-clock/clock.h create mode 100644 plasma/generic/applets/digital-clock/clockConfig.ui create mode 100644 plasma/generic/applets/digital-clock/plasma-applet-digitalclock.desktop create mode 100644 plasma/generic/applets/icon/CMakeLists.txt create mode 100755 plasma/generic/applets/icon/Messages.sh create mode 100644 plasma/generic/applets/icon/icon.cpp create mode 100644 plasma/generic/applets/icon/icon.h create mode 100644 plasma/generic/applets/icon/plasma-applet-icon.desktop create mode 100644 plasma/generic/applets/lock_logout/CMakeLists.txt create mode 100755 plasma/generic/applets/lock_logout/Messages.sh create mode 100644 plasma/generic/applets/lock_logout/contents/config/main.xml create mode 100644 plasma/generic/applets/lock_logout/contents/ui/config.ui create mode 100644 plasma/generic/applets/lock_logout/contents/ui/data.js create mode 100644 plasma/generic/applets/lock_logout/contents/ui/lockout.qml create mode 100644 plasma/generic/applets/lock_logout/metadata.desktop create mode 100644 plasma/generic/applets/notifications/CMakeLists.txt create mode 100644 plasma/generic/applets/notifications/Messages.sh create mode 100644 plasma/generic/applets/notifications/contents/config/main.xml create mode 100644 plasma/generic/applets/notifications/contents/ui/JobDelegate.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/Jobs.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/LastNotificationPopup.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/NotificationDelegate/NotificationDelegate.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/NotificationDelegate/qmldir create mode 100644 plasma/generic/applets/notifications/contents/ui/NotificationIcon.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/Notifications.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/Title.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/config.ui create mode 100644 plasma/generic/applets/notifications/contents/ui/main.qml create mode 100644 plasma/generic/applets/notifications/contents/ui/uiproperties.js create mode 100644 plasma/generic/applets/notifications/metadata.desktop create mode 100644 plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/NotificationDelegate.qml create mode 100644 plasma/generic/applets/notifications/platformcontents/touch/ui/NotificationDelegate/qmldir create mode 100644 plasma/generic/applets/notifications/platformcontents/touch/ui/uiproperties.js create mode 100644 plasma/generic/applets/panelspacer/CMakeLists.txt create mode 100755 plasma/generic/applets/panelspacer/Messages.sh create mode 100644 plasma/generic/applets/panelspacer/panelspacer.cpp create mode 100644 plasma/generic/applets/panelspacer/panelspacer.h create mode 100644 plasma/generic/applets/panelspacer/plasma-applet-panelspacer-internal.desktop create mode 100644 plasma/generic/applets/quicklaunch/CMakeLists.txt create mode 100755 plasma/generic/applets/quicklaunch/Messages.sh create mode 100644 plasma/generic/applets/quicklaunch/icongridlayout.cpp create mode 100644 plasma/generic/applets/quicklaunch/icongridlayout.h create mode 100644 plasma/generic/applets/quicklaunch/launcher.cpp create mode 100644 plasma/generic/applets/quicklaunch/launcher.h create mode 100644 plasma/generic/applets/quicklaunch/launcherdata.cpp create mode 100644 plasma/generic/applets/quicklaunch/launcherdata.h create mode 100644 plasma/generic/applets/quicklaunch/launchergrid.cpp create mode 100644 plasma/generic/applets/quicklaunch/launchergrid.h create mode 100644 plasma/generic/applets/quicklaunch/plasma-applet-quicklaunch.desktop create mode 100644 plasma/generic/applets/quicklaunch/popup.cpp create mode 100644 plasma/generic/applets/quicklaunch/popup.h create mode 100644 plasma/generic/applets/quicklaunch/popuplauncherlist.cpp create mode 100644 plasma/generic/applets/quicklaunch/popuplauncherlist.h create mode 100644 plasma/generic/applets/quicklaunch/quicklaunch.cpp create mode 100644 plasma/generic/applets/quicklaunch/quicklaunch.h create mode 100644 plasma/generic/applets/quicklaunch/quicklaunchConfig.ui create mode 100644 plasma/generic/applets/system-monitor/CMakeLists.txt create mode 100755 plasma/generic/applets/system-monitor/Messages.sh create mode 100644 plasma/generic/applets/system-monitor/applet.cpp create mode 100644 plasma/generic/applets/system-monitor/applet.h create mode 100644 plasma/generic/applets/system-monitor/cpu-config.ui create mode 100644 plasma/generic/applets/system-monitor/cpu.cpp create mode 100644 plasma/generic/applets/system-monitor/cpu.h create mode 100644 plasma/generic/applets/system-monitor/hdd-config.ui create mode 100644 plasma/generic/applets/system-monitor/hdd.cpp create mode 100644 plasma/generic/applets/system-monitor/hdd.h create mode 100644 plasma/generic/applets/system-monitor/hdd_activity-config.ui create mode 100644 plasma/generic/applets/system-monitor/hdd_activity.cpp create mode 100644 plasma/generic/applets/system-monitor/hdd_activity.h create mode 100644 plasma/generic/applets/system-monitor/hdd_panel.svgz create mode 100644 plasma/generic/applets/system-monitor/hwinfo.cpp create mode 100644 plasma/generic/applets/system-monitor/hwinfo.h create mode 100644 plasma/generic/applets/system-monitor/monitorbutton.cpp create mode 100644 plasma/generic/applets/system-monitor/monitorbutton.h create mode 100644 plasma/generic/applets/system-monitor/monitoricon.cpp create mode 100644 plasma/generic/applets/system-monitor/monitoricon.h create mode 100644 plasma/generic/applets/system-monitor/net-config.ui create mode 100644 plasma/generic/applets/system-monitor/net.cpp create mode 100644 plasma/generic/applets/system-monitor/net.h create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_cpu.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_hdd.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_hdd_activity.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_hwinfo.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_net.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_ram.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-sm_temperature.desktop create mode 100644 plasma/generic/applets/system-monitor/plasma-applet-system-monitor.desktop create mode 100644 plasma/generic/applets/system-monitor/plotter.cpp create mode 100644 plasma/generic/applets/system-monitor/plotter.h create mode 100644 plasma/generic/applets/system-monitor/ram-config.ui create mode 100644 plasma/generic/applets/system-monitor/ram.cpp create mode 100644 plasma/generic/applets/system-monitor/ram.h create mode 100644 plasma/generic/applets/system-monitor/sm_export.h create mode 100644 plasma/generic/applets/system-monitor/system-monitor.cpp create mode 100644 plasma/generic/applets/system-monitor/system-monitor.h create mode 100644 plasma/generic/applets/system-monitor/temperature-config.ui create mode 100644 plasma/generic/applets/system-monitor/temperature-offset-delegate.cpp create mode 100644 plasma/generic/applets/system-monitor/temperature-offset-delegate.h create mode 100644 plasma/generic/applets/system-monitor/temperature.cpp create mode 100644 plasma/generic/applets/system-monitor/temperature.h create mode 100644 plasma/generic/applets/systemtray/CMakeLists.txt create mode 100755 plasma/generic/applets/systemtray/Messages.sh create mode 100644 plasma/generic/applets/systemtray/TODO create mode 100644 plasma/generic/applets/systemtray/config.h.in create mode 100644 plasma/generic/applets/systemtray/core/manager.cpp create mode 100644 plasma/generic/applets/systemtray/core/manager.h create mode 100644 plasma/generic/applets/systemtray/core/protocol.cpp create mode 100644 plasma/generic/applets/systemtray/core/protocol.h create mode 100644 plasma/generic/applets/systemtray/core/task.cpp create mode 100644 plasma/generic/applets/systemtray/core/task.h create mode 100644 plasma/generic/applets/systemtray/package/contents/code/IconsList.js create mode 100644 plasma/generic/applets/systemtray/package/contents/code/TasksSet.js create mode 100644 plasma/generic/applets/systemtray/package/contents/code/main.js create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/ArrowArea.qml create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/IconsGrid.qml create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/TrayIcon.qml create mode 100644 plasma/generic/applets/systemtray/package/contents/ui/main.qml create mode 100644 plasma/generic/applets/systemtray/plasma-applet-systemtray.desktop create mode 100644 plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.h create mode 100644 plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdonotification.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdonotification.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdotask.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/fdotask.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.h create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.h create mode 100644 plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.h create mode 100644 plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp create mode 100644 plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h create mode 100644 plasma/generic/applets/systemtray/ui/applet.cpp create mode 100644 plasma/generic/applets/systemtray/ui/applet.h create mode 100644 plasma/generic/applets/systemtray/ui/autohide.ui create mode 100644 plasma/generic/applets/systemtray/ui/mouseredirectarea.cpp create mode 100644 plasma/generic/applets/systemtray/ui/mouseredirectarea.h create mode 100644 plasma/generic/applets/systemtray/ui/visibleitems.ui create mode 100644 plasma/generic/applets/systemtray/ui/widgetitem.cpp create mode 100644 plasma/generic/applets/systemtray/ui/widgetitem.h create mode 100644 plasma/generic/applets/webbrowser/CMakeLists.txt create mode 100755 plasma/generic/applets/webbrowser/Messages.sh create mode 100644 plasma/generic/applets/webbrowser/bookmarkitem.cpp create mode 100644 plasma/generic/applets/webbrowser/bookmarkitem.h create mode 100644 plasma/generic/applets/webbrowser/bookmarksdelegate.cpp create mode 100644 plasma/generic/applets/webbrowser/bookmarksdelegate.h create mode 100644 plasma/generic/applets/webbrowser/browserhistorycombobox.cpp create mode 100644 plasma/generic/applets/webbrowser/browserhistorycombobox.h create mode 100644 plasma/generic/applets/webbrowser/browsermessagebox.cpp create mode 100644 plasma/generic/applets/webbrowser/browsermessagebox.h create mode 100644 plasma/generic/applets/webbrowser/errorpage.cpp create mode 100644 plasma/generic/applets/webbrowser/errorpage.h create mode 100644 plasma/generic/applets/webbrowser/plasma-applet-webbrowser.desktop create mode 100644 plasma/generic/applets/webbrowser/webbrowser.cpp create mode 100644 plasma/generic/applets/webbrowser/webbrowser.h create mode 100644 plasma/generic/applets/webbrowser/webbrowserconfig.ui create mode 100644 plasma/generic/applets/webbrowser/webbrowserpage.cpp create mode 100644 plasma/generic/applets/webbrowser/webbrowserpage.h create mode 100644 plasma/generic/applets/webbrowser/webviewoverlay.cpp create mode 100644 plasma/generic/applets/webbrowser/webviewoverlay.h create mode 100644 plasma/generic/containmentactions/CMakeLists.txt create mode 100644 plasma/generic/containmentactions/applauncher/CMakeLists.txt create mode 100644 plasma/generic/containmentactions/applauncher/launch.cpp create mode 100644 plasma/generic/containmentactions/applauncher/launch.h create mode 100644 plasma/generic/containmentactions/applauncher/plasma-containmentactions-applauncher.desktop create mode 100644 plasma/generic/containmentactions/contextmenu/CMakeLists.txt create mode 100755 plasma/generic/containmentactions/contextmenu/Messages.sh create mode 100644 plasma/generic/containmentactions/contextmenu/menu.cpp create mode 100644 plasma/generic/containmentactions/contextmenu/menu.h create mode 100644 plasma/generic/containmentactions/contextmenu/plasma-containmentactions-contextmenu.desktop create mode 100644 plasma/generic/containmentactions/minimalcontextmenu/CMakeLists.txt create mode 100644 plasma/generic/containmentactions/minimalcontextmenu/menu.cpp create mode 100644 plasma/generic/containmentactions/minimalcontextmenu/menu.h create mode 100644 plasma/generic/containmentactions/minimalcontextmenu/plasma-containmentactions-minimalcontextmenu.desktop create mode 100644 plasma/generic/containmentactions/paste/CMakeLists.txt create mode 100644 plasma/generic/containmentactions/paste/paste.cpp create mode 100644 plasma/generic/containmentactions/paste/paste.h create mode 100644 plasma/generic/containmentactions/paste/plasma-containmentactions-paste.desktop create mode 100644 plasma/generic/containmentactions/switchactivity/CMakeLists.txt create mode 100755 plasma/generic/containmentactions/switchactivity/Messages.sh create mode 100644 plasma/generic/containmentactions/switchactivity/plasma-containmentactions-switchactivity.desktop create mode 100644 plasma/generic/containmentactions/switchactivity/switch.cpp create mode 100644 plasma/generic/containmentactions/switchactivity/switch.h create mode 100644 plasma/generic/containmentactions/switchdesktop/CMakeLists.txt create mode 100755 plasma/generic/containmentactions/switchdesktop/Messages.sh create mode 100644 plasma/generic/containmentactions/switchdesktop/desktop.cpp create mode 100644 plasma/generic/containmentactions/switchdesktop/desktop.h create mode 100644 plasma/generic/containmentactions/switchdesktop/plasma-containmentactions-switchdesktop.desktop create mode 100644 plasma/generic/containmentactions/switchwindow/CMakeLists.txt create mode 100755 plasma/generic/containmentactions/switchwindow/Messages.sh create mode 100644 plasma/generic/containmentactions/switchwindow/config.ui create mode 100644 plasma/generic/containmentactions/switchwindow/plasma-containmentactions-switchwindow.desktop create mode 100644 plasma/generic/containmentactions/switchwindow/switch.cpp create mode 100644 plasma/generic/containmentactions/switchwindow/switch.h create mode 100644 plasma/generic/dataengines/CMakeLists.txt create mode 100644 plasma/generic/dataengines/Mainpage.dox create mode 100644 plasma/generic/dataengines/activities/ActivityData.cpp create mode 100644 plasma/generic/dataengines/activities/ActivityData.h create mode 100644 plasma/generic/dataengines/activities/CMakeLists.txt create mode 100644 plasma/generic/dataengines/activities/activities.operations create mode 100644 plasma/generic/dataengines/activities/activityengine.cpp create mode 100644 plasma/generic/dataengines/activities/activityengine.h create mode 100644 plasma/generic/dataengines/activities/activityjob.cpp create mode 100644 plasma/generic/dataengines/activities/activityjob.h create mode 100644 plasma/generic/dataengines/activities/activityservice.cpp create mode 100644 plasma/generic/dataengines/activities/activityservice.h create mode 100644 plasma/generic/dataengines/activities/org.kde.ActivityManager.ActivityRanking.xml create mode 100644 plasma/generic/dataengines/activities/plasma-engine-activities.desktop create mode 100644 plasma/generic/dataengines/akonadi/CMakeLists.txt create mode 100644 plasma/generic/dataengines/akonadi/akonadiengine.cpp create mode 100644 plasma/generic/dataengines/akonadi/akonadiengine.h create mode 100644 plasma/generic/dataengines/akonadi/plasma-engine-akonadi.desktop create mode 100644 plasma/generic/dataengines/applicationjobs/CMakeLists.txt create mode 100755 plasma/generic/dataengines/applicationjobs/Messages.sh create mode 100644 plasma/generic/dataengines/applicationjobs/applicationjobs.operations create mode 100644 plasma/generic/dataengines/applicationjobs/jobaction.cpp create mode 100644 plasma/generic/dataengines/applicationjobs/jobaction.h create mode 100644 plasma/generic/dataengines/applicationjobs/jobcontrol.cpp create mode 100644 plasma/generic/dataengines/applicationjobs/jobcontrol.h create mode 100644 plasma/generic/dataengines/applicationjobs/kuiserverengine.cpp create mode 100644 plasma/generic/dataengines/applicationjobs/kuiserverengine.h create mode 100644 plasma/generic/dataengines/applicationjobs/plasma-dataengine-applicationjobs.desktop create mode 100644 plasma/generic/dataengines/apps/CMakeLists.txt create mode 100644 plasma/generic/dataengines/apps/appjob.cpp create mode 100644 plasma/generic/dataengines/apps/appjob.h create mode 100644 plasma/generic/dataengines/apps/apps.operations create mode 100644 plasma/generic/dataengines/apps/appsengine.cpp create mode 100644 plasma/generic/dataengines/apps/appsengine.h create mode 100644 plasma/generic/dataengines/apps/appservice.cpp create mode 100644 plasma/generic/dataengines/apps/appservice.h create mode 100644 plasma/generic/dataengines/apps/appsource.cpp create mode 100644 plasma/generic/dataengines/apps/appsource.h create mode 100644 plasma/generic/dataengines/apps/plasma-dataengine-apps.desktop create mode 100644 plasma/generic/dataengines/calendar/CMakeLists.txt create mode 100755 plasma/generic/dataengines/calendar/Messages.sh create mode 100644 plasma/generic/dataengines/calendar/calendar.operations create mode 100644 plasma/generic/dataengines/calendar/calendarengine.cpp create mode 100644 plasma/generic/dataengines/calendar/calendarengine.h create mode 100644 plasma/generic/dataengines/calendar/eventdatacontainer.cpp create mode 100644 plasma/generic/dataengines/calendar/eventdatacontainer.h create mode 100644 plasma/generic/dataengines/calendar/plasma-dataengine-calendar.desktop create mode 100644 plasma/generic/dataengines/devicenotifications/CMakeLists.txt create mode 100644 plasma/generic/dataengines/devicenotifications/devicenotificationsengine.cpp create mode 100644 plasma/generic/dataengines/devicenotifications/devicenotificationsengine.h create mode 100644 plasma/generic/dataengines/devicenotifications/org.kde.DeviceNotifications.xml create mode 100644 plasma/generic/dataengines/devicenotifications/plasma-dataengine-devicenotifications.desktop create mode 100644 plasma/generic/dataengines/dict/CMakeLists.txt create mode 100755 plasma/generic/dataengines/dict/Messages.sh create mode 100644 plasma/generic/dataengines/dict/buggywords create mode 100644 plasma/generic/dataengines/dict/dictengine.cpp create mode 100644 plasma/generic/dataengines/dict/dictengine.h create mode 100644 plasma/generic/dataengines/dict/plasma-dataengine-dict.desktop create mode 100644 plasma/generic/dataengines/executable/CMakeLists.txt create mode 100644 plasma/generic/dataengines/executable/executable.cpp create mode 100644 plasma/generic/dataengines/executable/executable.h create mode 100644 plasma/generic/dataengines/executable/plasma-dataengine-executable.desktop create mode 100644 plasma/generic/dataengines/favicons/CMakeLists.txt create mode 100644 plasma/generic/dataengines/favicons/faviconprovider.cpp create mode 100644 plasma/generic/dataengines/favicons/faviconprovider.h create mode 100644 plasma/generic/dataengines/favicons/favicons.cpp create mode 100644 plasma/generic/dataengines/favicons/favicons.h create mode 100644 plasma/generic/dataengines/favicons/plasma-dataengine-favicons.desktop create mode 100644 plasma/generic/dataengines/filebrowser/CMakeLists.txt create mode 100644 plasma/generic/dataengines/filebrowser/filebrowserengine.cpp create mode 100644 plasma/generic/dataengines/filebrowser/filebrowserengine.h create mode 100644 plasma/generic/dataengines/filebrowser/plasma-dataengine-filebrowser.desktop create mode 100644 plasma/generic/dataengines/geolocation/CMakeLists.txt create mode 100644 plasma/generic/dataengines/geolocation/cmake/modules/Findlibgps.cmake create mode 100644 plasma/generic/dataengines/geolocation/geolocation.cpp create mode 100644 plasma/generic/dataengines/geolocation/geolocation.h create mode 100644 plasma/generic/dataengines/geolocation/geolocation_export.h create mode 100644 plasma/generic/dataengines/geolocation/geolocationprovider.cpp create mode 100644 plasma/generic/dataengines/geolocation/geolocationprovider.h create mode 100644 plasma/generic/dataengines/geolocation/location_gps.cpp create mode 100644 plasma/generic/dataengines/geolocation/location_gps.h create mode 100644 plasma/generic/dataengines/geolocation/location_ip.cpp create mode 100644 plasma/generic/dataengines/geolocation/location_ip.h create mode 100644 plasma/generic/dataengines/geolocation/plasma-dataengine-geolocation.desktop create mode 100644 plasma/generic/dataengines/geolocation/plasma-geolocation-gps.desktop create mode 100644 plasma/generic/dataengines/geolocation/plasma-geolocation-ip.desktop create mode 100644 plasma/generic/dataengines/geolocation/plasma-geolocationprovider.desktop create mode 100644 plasma/generic/dataengines/hotplug/CMakeLists.txt create mode 100644 plasma/generic/dataengines/hotplug/hotplug.operations create mode 100644 plasma/generic/dataengines/hotplug/hotplugengine.cpp create mode 100644 plasma/generic/dataengines/hotplug/hotplugengine.h create mode 100644 plasma/generic/dataengines/hotplug/hotplugjob.cpp create mode 100644 plasma/generic/dataengines/hotplug/hotplugjob.h create mode 100644 plasma/generic/dataengines/hotplug/hotplugservice.cpp create mode 100644 plasma/generic/dataengines/hotplug/hotplugservice.h create mode 100644 plasma/generic/dataengines/hotplug/plasma-dataengine-hotplug.desktop create mode 100644 plasma/generic/dataengines/keystate/CMakeLists.txt create mode 100755 plasma/generic/dataengines/keystate/Messages.sh create mode 100644 plasma/generic/dataengines/keystate/keyservice.cpp create mode 100644 plasma/generic/dataengines/keystate/keyservice.h create mode 100644 plasma/generic/dataengines/keystate/keystate.cpp create mode 100644 plasma/generic/dataengines/keystate/keystate.h create mode 100644 plasma/generic/dataengines/keystate/modifierkeystate.operations create mode 100644 plasma/generic/dataengines/keystate/plasma-dataengine-keystate.desktop create mode 100644 plasma/generic/dataengines/metadata/CMakeLists.txt create mode 100644 plasma/generic/dataengines/metadata/Messages.sh create mode 100644 plasma/generic/dataengines/metadata/metadata_engine.cpp create mode 100644 plasma/generic/dataengines/metadata/metadata_engine.h create mode 100644 plasma/generic/dataengines/metadata/plasma-engine-metadata.desktop create mode 100644 plasma/generic/dataengines/mouse/CMakeLists.txt create mode 100644 plasma/generic/dataengines/mouse/cursornotificationhandler.cpp create mode 100644 plasma/generic/dataengines/mouse/cursornotificationhandler.h create mode 100644 plasma/generic/dataengines/mouse/mouseengine.cpp create mode 100644 plasma/generic/dataengines/mouse/mouseengine.h create mode 100644 plasma/generic/dataengines/mouse/plasma-dataengine-mouse.desktop create mode 100644 plasma/generic/dataengines/mpris2/CMakeLists.txt create mode 100755 plasma/generic/dataengines/mpris2/Messages.sh create mode 100644 plasma/generic/dataengines/mpris2/TODO create mode 100644 plasma/generic/dataengines/mpris2/mpris2.operations create mode 100644 plasma/generic/dataengines/mpris2/mpris2engine.cpp create mode 100644 plasma/generic/dataengines/mpris2/mpris2engine.h create mode 100644 plasma/generic/dataengines/mpris2/multiplexedservice.cpp create mode 100644 plasma/generic/dataengines/mpris2/multiplexedservice.h create mode 100644 plasma/generic/dataengines/mpris2/multiplexer.cpp create mode 100644 plasma/generic/dataengines/mpris2/multiplexer.h create mode 100644 plasma/generic/dataengines/mpris2/org.freedesktop.DBus.Properties.xml create mode 100644 plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.Player.xml create mode 100644 plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.xml create mode 100644 plasma/generic/dataengines/mpris2/plasma-dataengine-mpris2.desktop create mode 100644 plasma/generic/dataengines/mpris2/playeractionjob.cpp create mode 100644 plasma/generic/dataengines/mpris2/playeractionjob.h create mode 100644 plasma/generic/dataengines/mpris2/playercontainer.cpp create mode 100644 plasma/generic/dataengines/mpris2/playercontainer.h create mode 100644 plasma/generic/dataengines/mpris2/playercontrol.cpp create mode 100644 plasma/generic/dataengines/mpris2/playercontrol.h create mode 100644 plasma/generic/dataengines/network/CMakeLists.txt create mode 100755 plasma/generic/dataengines/network/Messages.sh create mode 100644 plasma/generic/dataengines/network/networkengine.cpp create mode 100644 plasma/generic/dataengines/network/networkengine.h create mode 100644 plasma/generic/dataengines/network/plasma-dataengine-network.desktop create mode 100644 plasma/generic/dataengines/notifications/CMakeLists.txt create mode 100755 plasma/generic/dataengines/notifications/Messages.sh create mode 100644 plasma/generic/dataengines/notifications/notificationaction.cpp create mode 100644 plasma/generic/dataengines/notifications/notificationaction.h create mode 100644 plasma/generic/dataengines/notifications/notifications.operations create mode 100644 plasma/generic/dataengines/notifications/notificationsengine.cpp create mode 100644 plasma/generic/dataengines/notifications/notificationsengine.h create mode 100644 plasma/generic/dataengines/notifications/notificationservice.cpp create mode 100644 plasma/generic/dataengines/notifications/notificationservice.h create mode 100644 plasma/generic/dataengines/notifications/org.freedesktop.Notifications.xml create mode 100644 plasma/generic/dataengines/notifications/plasma-dataengine-notifications.desktop create mode 100644 plasma/generic/dataengines/nowplaying/CMakeLists.txt create mode 100755 plasma/generic/dataengines/nowplaying/Messages.sh create mode 100644 plasma/generic/dataengines/nowplaying/TODO create mode 100644 plasma/generic/dataengines/nowplaying/config-nowplaying.cmake create mode 100644 plasma/generic/dataengines/nowplaying/nowplaying.operations create mode 100644 plasma/generic/dataengines/nowplaying/nowplayingengine.cpp create mode 100644 plasma/generic/dataengines/nowplaying/nowplayingengine.h create mode 100644 plasma/generic/dataengines/nowplaying/plasma-dataengine-nowplaying.desktop create mode 100644 plasma/generic/dataengines/nowplaying/playeractionjob.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playeractionjob.h create mode 100644 plasma/generic/dataengines/nowplaying/playercontainer.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playercontainer.h create mode 100644 plasma/generic/dataengines/nowplaying/playercontrol.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playercontrol.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/juk.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/juk.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/juk_p.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris_p.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.player.xml create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.root.xml create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.tracklist.xml create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2_p.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/org.kde.juk.player.xml create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/player.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/player.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/xmms.cpp create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/xmms.h create mode 100644 plasma/generic/dataengines/nowplaying/playerinterface/xmms_p.h create mode 100644 plasma/generic/dataengines/places/CMakeLists.txt create mode 100644 plasma/generic/dataengines/places/TODO create mode 100644 plasma/generic/dataengines/places/jobs.h create mode 100644 plasma/generic/dataengines/places/modeljob.h create mode 100644 plasma/generic/dataengines/places/org.kde.places.operations create mode 100644 plasma/generic/dataengines/places/placesengine.cpp create mode 100644 plasma/generic/dataengines/places/placesengine.h create mode 100644 plasma/generic/dataengines/places/placeservice.cpp create mode 100644 plasma/generic/dataengines/places/placeservice.h create mode 100644 plasma/generic/dataengines/places/plasma-dataengine-places.desktop create mode 100644 plasma/generic/dataengines/places/setupdevicejob.cpp create mode 100644 plasma/generic/dataengines/places/setupdevicejob.h create mode 100644 plasma/generic/dataengines/powermanagement/CMakeLists.txt create mode 100644 plasma/generic/dataengines/powermanagement/README.txt create mode 100644 plasma/generic/dataengines/powermanagement/plasma-dataengine-powermanagement.desktop create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementengine.cpp create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementengine.h create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementjob.cpp create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementjob.h create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementservice.cpp create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementservice.h create mode 100644 plasma/generic/dataengines/powermanagement/powermanagementservice.operations create mode 100644 plasma/generic/dataengines/rss/CMakeLists.txt create mode 100755 plasma/generic/dataengines/rss/Messages.sh create mode 100644 plasma/generic/dataengines/rss/plasma-dataengine-rss.desktop create mode 100644 plasma/generic/dataengines/rss/rss.cpp create mode 100644 plasma/generic/dataengines/rss/rss.h create mode 100644 plasma/generic/dataengines/share/CMakeLists.txt create mode 100755 plasma/generic/dataengines/share/Messages.sh create mode 100644 plasma/generic/dataengines/share/backends/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/im9/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/im9/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/im9/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/imgsusepasteorg/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/imgsusepasteorg/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/imgsusepasteorg/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/imgur/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/imgur/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/imgur/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/kde/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/kde/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/kde/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/pastebincom/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/pastebincom/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/pastebincom/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/pasteopensuseorg/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/pasteopensuseorg/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/pasteopensuseorg/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/pasteubuntucom/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/pasteubuntucom/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/pasteubuntucom/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/privatepaste/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/privatepaste/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/privatepaste/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/simplestimagehosting/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/simplestimagehosting/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/simplestimagehosting/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/wklej/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/wklej/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/wklej/metadata.desktop create mode 100644 plasma/generic/dataengines/share/backends/wstaw/CMakeLists.txt create mode 100644 plasma/generic/dataengines/share/backends/wstaw/contents/code/main.js create mode 100644 plasma/generic/dataengines/share/backends/wstaw/metadata.desktop create mode 100644 plasma/generic/dataengines/share/data/plasma-dataengine-share.desktop create mode 100644 plasma/generic/dataengines/share/data/plasma-packagestructure-share.desktop create mode 100644 plasma/generic/dataengines/share/data/plasma_shareprovider.desktop create mode 100644 plasma/generic/dataengines/share/plugin_share_package.cpp create mode 100644 plasma/generic/dataengines/share/share.operations create mode 100644 plasma/generic/dataengines/share/share_package.cpp create mode 100644 plasma/generic/dataengines/share/share_package.h create mode 100644 plasma/generic/dataengines/share/shareengine.cpp create mode 100644 plasma/generic/dataengines/share/shareengine.h create mode 100644 plasma/generic/dataengines/share/shareprovider.cpp create mode 100644 plasma/generic/dataengines/share/shareprovider.h create mode 100644 plasma/generic/dataengines/share/shareservice.cpp create mode 100644 plasma/generic/dataengines/share/shareservice.h create mode 100644 plasma/generic/dataengines/soliddevice/CMakeLists.txt create mode 100755 plasma/generic/dataengines/soliddevice/Messages.sh create mode 100644 plasma/generic/dataengines/soliddevice/devicesignalmapmanager.cpp create mode 100644 plasma/generic/dataengines/soliddevice/devicesignalmapmanager.h create mode 100644 plasma/generic/dataengines/soliddevice/devicesignalmapper.cpp create mode 100644 plasma/generic/dataengines/soliddevice/devicesignalmapper.h create mode 100644 plasma/generic/dataengines/soliddevice/hddtemp.cpp create mode 100644 plasma/generic/dataengines/soliddevice/hddtemp.h create mode 100644 plasma/generic/dataengines/soliddevice/plasma-dataengine-soliddevice.desktop create mode 100644 plasma/generic/dataengines/soliddevice/soliddevice.operations create mode 100644 plasma/generic/dataengines/soliddevice/soliddeviceengine.cpp create mode 100644 plasma/generic/dataengines/soliddevice/soliddeviceengine.h create mode 100644 plasma/generic/dataengines/soliddevice/soliddevicejob.cpp create mode 100644 plasma/generic/dataengines/soliddevice/soliddevicejob.h create mode 100644 plasma/generic/dataengines/soliddevice/soliddeviceservice.cpp create mode 100644 plasma/generic/dataengines/soliddevice/soliddeviceservice.h create mode 100644 plasma/generic/dataengines/statusnotifieritem/CMakeLists.txt create mode 100644 plasma/generic/dataengines/statusnotifieritem/plasma_engine_statusnotifieritem.desktop create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritem.operations create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritem_engine.cpp create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritem_engine.h create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.cpp create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.h create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.cpp create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.h create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp create mode 100644 plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.h create mode 100644 plasma/generic/dataengines/statusnotifieritem/systemtraytypes.cpp create mode 100644 plasma/generic/dataengines/statusnotifieritem/systemtraytypes.h create mode 100644 plasma/generic/dataengines/systemmonitor/CMakeLists.txt create mode 100755 plasma/generic/dataengines/systemmonitor/Messages.sh create mode 100644 plasma/generic/dataengines/systemmonitor/plasma-dataengine-systemmonitor.desktop create mode 100644 plasma/generic/dataengines/systemmonitor/sensorclient.h create mode 100644 plasma/generic/dataengines/systemmonitor/systemmonitor.cpp create mode 100644 plasma/generic/dataengines/systemmonitor/systemmonitor.h create mode 100644 plasma/generic/dataengines/tasks/CMakeLists.txt create mode 100644 plasma/generic/dataengines/tasks/plasma-dataengine-tasks.desktop create mode 100644 plasma/generic/dataengines/tasks/taskjob.cpp create mode 100644 plasma/generic/dataengines/tasks/taskjob.h create mode 100644 plasma/generic/dataengines/tasks/tasks.operations create mode 100644 plasma/generic/dataengines/tasks/tasksengine.cpp create mode 100644 plasma/generic/dataengines/tasks/tasksengine.h create mode 100644 plasma/generic/dataengines/tasks/taskservice.cpp create mode 100644 plasma/generic/dataengines/tasks/taskservice.h create mode 100644 plasma/generic/dataengines/tasks/tasksource.cpp create mode 100644 plasma/generic/dataengines/tasks/tasksource.h create mode 100644 plasma/generic/dataengines/tasks/virtualdesktopssource.cpp create mode 100644 plasma/generic/dataengines/tasks/virtualdesktopssource.h create mode 100644 plasma/generic/dataengines/time/CMakeLists.txt create mode 100644 plasma/generic/dataengines/time/plasma-dataengine-time.desktop create mode 100644 plasma/generic/dataengines/time/solarsystem.cpp create mode 100644 plasma/generic/dataengines/time/solarsystem.h create mode 100644 plasma/generic/dataengines/time/timeengine.cpp create mode 100644 plasma/generic/dataengines/time/timeengine.h create mode 100644 plasma/generic/dataengines/time/timesource.cpp create mode 100644 plasma/generic/dataengines/time/timesource.h create mode 100644 plasma/generic/dataengines/weather/CMakeLists.txt create mode 100755 plasma/generic/dataengines/weather/Messages.sh create mode 100644 plasma/generic/dataengines/weather/ions/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/bbcukmet/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/bbcukmet/ion-bbcukmet.desktop create mode 100644 plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp create mode 100644 plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h create mode 100644 plasma/generic/dataengines/weather/ions/data/bbcukmet_i18n.dat create mode 100644 plasma/generic/dataengines/weather/ions/data/envcan_i18n.dat create mode 100644 plasma/generic/dataengines/weather/ions/data/noaa_i18n.dat create mode 100644 plasma/generic/dataengines/weather/ions/dataengineconsumer.h create mode 100644 plasma/generic/dataengines/weather/ions/debianweather/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/debianweather/ion-debianweather.desktop create mode 100644 plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.cpp create mode 100644 plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.h create mode 100644 plasma/generic/dataengines/weather/ions/envcan/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/envcan/ion-envcan.desktop create mode 100644 plasma/generic/dataengines/weather/ions/envcan/ion_envcan.cpp create mode 100644 plasma/generic/dataengines/weather/ions/envcan/ion_envcan.h create mode 100644 plasma/generic/dataengines/weather/ions/includes/Ion create mode 100644 plasma/generic/dataengines/weather/ions/ion.cpp create mode 100644 plasma/generic/dataengines/weather/ions/ion.h create mode 100644 plasma/generic/dataengines/weather/ions/ion_export.h create mode 100644 plasma/generic/dataengines/weather/ions/noaa/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/noaa/ion-noaa.desktop create mode 100644 plasma/generic/dataengines/weather/ions/noaa/ion_noaa.cpp create mode 100644 plasma/generic/dataengines/weather/ions/noaa/ion_noaa.h create mode 100644 plasma/generic/dataengines/weather/ions/wetter.com/CMakeLists.txt create mode 100644 plasma/generic/dataengines/weather/ions/wetter.com/ion-wettercom.desktop create mode 100644 plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.cpp create mode 100644 plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.h create mode 100644 plasma/generic/dataengines/weather/plasma-dataengine-weather.desktop create mode 100644 plasma/generic/dataengines/weather/weatherengine.cpp create mode 100644 plasma/generic/dataengines/weather/weatherengine.h create mode 100644 plasma/generic/runners/CMakeLists.txt create mode 100644 plasma/generic/runners/activities/CMakeLists.txt create mode 100755 plasma/generic/runners/activities/Messages.sh create mode 100644 plasma/generic/runners/activities/activityrunner.cpp create mode 100644 plasma/generic/runners/activities/activityrunner.h create mode 100644 plasma/generic/runners/activities/plasma-runner-activityrunner.desktop create mode 100644 plasma/generic/runners/bookmarks/.gitignore create mode 100644 plasma/generic/runners/bookmarks/CMakeLists.txt create mode 100755 plasma/generic/runners/bookmarks/Messages.sh create mode 100644 plasma/generic/runners/bookmarks/bookmarkmatch.cpp create mode 100644 plasma/generic/runners/bookmarks/bookmarkmatch.h create mode 100644 plasma/generic/runners/bookmarks/bookmarksrunner.cpp create mode 100644 plasma/generic/runners/bookmarks/bookmarksrunner.h create mode 100644 plasma/generic/runners/bookmarks/bookmarksrunner_defs.h create mode 100644 plasma/generic/runners/bookmarks/browser.h create mode 100644 plasma/generic/runners/bookmarks/browserfactory.cpp create mode 100644 plasma/generic/runners/bookmarks/browserfactory.h create mode 100644 plasma/generic/runners/bookmarks/browsers/chrome.cpp create mode 100644 plasma/generic/runners/bookmarks/browsers/chrome.h create mode 100644 plasma/generic/runners/bookmarks/browsers/chromefindprofile.cpp create mode 100644 plasma/generic/runners/bookmarks/browsers/chromefindprofile.h create mode 100644 plasma/generic/runners/bookmarks/browsers/findprofile.h create mode 100644 plasma/generic/runners/bookmarks/browsers/firefox.cpp create mode 100644 plasma/generic/runners/bookmarks/browsers/firefox.h create mode 100644 plasma/generic/runners/bookmarks/browsers/kdebrowser.cpp create mode 100644 plasma/generic/runners/bookmarks/browsers/kdebrowser.h create mode 100644 plasma/generic/runners/bookmarks/browsers/opera.cpp create mode 100644 plasma/generic/runners/bookmarks/browsers/opera.h create mode 100644 plasma/generic/runners/bookmarks/favicon.cpp create mode 100644 plasma/generic/runners/bookmarks/favicon.h create mode 100644 plasma/generic/runners/bookmarks/faviconfromblob.cpp create mode 100644 plasma/generic/runners/bookmarks/faviconfromblob.h create mode 100644 plasma/generic/runners/bookmarks/fetchsqlite.cpp create mode 100644 plasma/generic/runners/bookmarks/fetchsqlite.h create mode 100644 plasma/generic/runners/bookmarks/plasma-runner-bookmarks.desktop create mode 100644 plasma/generic/runners/bookmarks/tests/CMakeLists.txt create mode 100644 plasma/generic/runners/bookmarks/tests/chrome-config-home/.config/chromium/Local State create mode 100644 plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-Sample.json create mode 100644 plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-SecondProfile.json create mode 100644 plasma/generic/runners/bookmarks/tests/testchromebookmarks.cpp create mode 100644 plasma/generic/runners/bookmarks/tests/testchromebookmarks.h create mode 100644 plasma/generic/runners/calculator/CMakeLists.txt create mode 100755 plasma/generic/runners/calculator/Messages.sh create mode 100644 plasma/generic/runners/calculator/calculatorrunner.cpp create mode 100644 plasma/generic/runners/calculator/calculatorrunner.h create mode 100644 plasma/generic/runners/calculator/plasma-runner-calculator.desktop create mode 100644 plasma/generic/runners/calculator/qalculate_engine.cpp create mode 100644 plasma/generic/runners/calculator/qalculate_engine.h create mode 100644 plasma/generic/runners/kill/CMakeLists.txt create mode 100644 plasma/generic/runners/kill/Messages.sh create mode 100644 plasma/generic/runners/kill/TODO create mode 100644 plasma/generic/runners/kill/killrunner.cpp create mode 100644 plasma/generic/runners/kill/killrunner.h create mode 100644 plasma/generic/runners/kill/killrunner_config.cpp create mode 100644 plasma/generic/runners/kill/killrunner_config.h create mode 100644 plasma/generic/runners/kill/killrunner_config.ui create mode 100644 plasma/generic/runners/kill/plasma-runner-kill.desktop create mode 100644 plasma/generic/runners/kill/plasma-runner-kill_config.desktop create mode 100644 plasma/generic/runners/locations/CMakeLists.txt create mode 100755 plasma/generic/runners/locations/Messages.sh create mode 100644 plasma/generic/runners/locations/locationrunner.cpp create mode 100644 plasma/generic/runners/locations/locationrunner.h create mode 100644 plasma/generic/runners/locations/plasma-runner-locations.desktop create mode 100644 plasma/generic/runners/nepomuksearch/CMakeLists.txt create mode 100755 plasma/generic/runners/nepomuksearch/Messages.sh create mode 100644 plasma/generic/runners/nepomuksearch/nepomuksearchrunner.cpp create mode 100644 plasma/generic/runners/nepomuksearch/nepomuksearchrunner.h create mode 100644 plasma/generic/runners/nepomuksearch/plasma-runner-nepomuksearch.desktop create mode 100644 plasma/generic/runners/places/CMakeLists.txt create mode 100755 plasma/generic/runners/places/Messages.sh create mode 100644 plasma/generic/runners/places/placesrunner.cpp create mode 100644 plasma/generic/runners/places/placesrunner.h create mode 100644 plasma/generic/runners/places/plasma-runner-places.desktop create mode 100644 plasma/generic/runners/powerdevil/CMakeLists.txt create mode 100755 plasma/generic/runners/powerdevil/Messages.sh create mode 100644 plasma/generic/runners/powerdevil/PowerDevilRunner.cpp create mode 100644 plasma/generic/runners/powerdevil/PowerDevilRunner.h create mode 100644 plasma/generic/runners/powerdevil/plasma-runner-powerdevil.desktop create mode 100644 plasma/generic/runners/recentdocuments/CMakeLists.txt create mode 100755 plasma/generic/runners/recentdocuments/Messages.sh create mode 100644 plasma/generic/runners/recentdocuments/README create mode 100644 plasma/generic/runners/recentdocuments/recentdocuments.cpp create mode 100644 plasma/generic/runners/recentdocuments/recentdocuments.desktop create mode 100644 plasma/generic/runners/recentdocuments/recentdocuments.h create mode 100644 plasma/generic/runners/services/CMakeLists.txt create mode 100755 plasma/generic/runners/services/Messages.sh create mode 100644 plasma/generic/runners/services/plasma-runner-services.desktop create mode 100644 plasma/generic/runners/services/servicerunner.cpp create mode 100644 plasma/generic/runners/services/servicerunner.h create mode 100644 plasma/generic/runners/sessions/CMakeLists.txt create mode 100755 plasma/generic/runners/sessions/Messages.sh create mode 100644 plasma/generic/runners/sessions/plasma-runner-sessions.desktop create mode 100644 plasma/generic/runners/sessions/sessionrunner.cpp create mode 100644 plasma/generic/runners/sessions/sessionrunner.h create mode 100644 plasma/generic/runners/shell/CMakeLists.txt create mode 100755 plasma/generic/runners/shell/Messages.sh create mode 100644 plasma/generic/runners/shell/plasma-runner-shell.desktop create mode 100644 plasma/generic/runners/shell/shellOptions.ui create mode 100644 plasma/generic/runners/shell/shell_config.cpp create mode 100644 plasma/generic/runners/shell/shell_config.h create mode 100644 plasma/generic/runners/shell/shellrunner.cpp create mode 100644 plasma/generic/runners/shell/shellrunner.h create mode 100644 plasma/generic/runners/solid/CMakeLists.txt create mode 100644 plasma/generic/runners/solid/Messages.sh create mode 100644 plasma/generic/runners/solid/devicewrapper.cpp create mode 100644 plasma/generic/runners/solid/devicewrapper.h create mode 100644 plasma/generic/runners/solid/plasma-runner-solid.desktop create mode 100644 plasma/generic/runners/solid/solidrunner.cpp create mode 100644 plasma/generic/runners/solid/solidrunner.h create mode 100644 plasma/generic/runners/webshortcuts/CMakeLists.txt create mode 100755 plasma/generic/runners/webshortcuts/Messages.sh create mode 100644 plasma/generic/runners/webshortcuts/plasma-runner-webshortcuts.desktop create mode 100644 plasma/generic/runners/webshortcuts/webshortcutrunner.cpp create mode 100644 plasma/generic/runners/webshortcuts/webshortcutrunner.h create mode 100644 plasma/generic/runners/windowedwidgets/CMakeLists.txt create mode 100644 plasma/generic/runners/windowedwidgets/Messages.sh create mode 100644 plasma/generic/runners/windowedwidgets/plasma-runner-windowedwidgets.desktop create mode 100644 plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.cpp create mode 100644 plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.h create mode 100644 plasma/generic/runners/windows/CMakeLists.txt create mode 100755 plasma/generic/runners/windows/Messages.sh create mode 100644 plasma/generic/runners/windows/plasma-runner-windows.desktop create mode 100644 plasma/generic/runners/windows/windowsrunner.cpp create mode 100644 plasma/generic/runners/windows/windowsrunner.h create mode 100644 plasma/generic/scriptengines/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/python/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/python/plasma-scriptengine-applet-python.desktop create mode 100644 plasma/generic/scriptengines/python/plasma-scriptengine-dataengine-python.desktop create mode 100644 plasma/generic/scriptengines/python/plasma-scriptengine-runner-python.desktop create mode 100644 plasma/generic/scriptengines/python/plasma-scriptengine-wallpaper-python.desktop create mode 100644 plasma/generic/scriptengines/python/plasma_importer.py create mode 100644 plasma/generic/scriptengines/python/plasmascript.py create mode 100644 plasma/generic/scriptengines/python/pyappletscript.py create mode 100644 plasma/generic/scriptengines/python/pydataengine.py create mode 100644 plasma/generic/scriptengines/python/pyrunner.py create mode 100644 plasma/generic/scriptengines/python/pywallpaper.py create mode 100644 plasma/generic/scriptengines/ruby/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/ruby/ChangeLog create mode 100644 plasma/generic/scriptengines/ruby/applet.rb create mode 100644 plasma/generic/scriptengines/ruby/data_engine.rb create mode 100644 plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-applet.desktop create mode 100644 plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-dataengine.desktop create mode 100644 plasma/generic/scriptengines/webkit/CMakeLists.txt create mode 100755 plasma/generic/scriptengines/webkit/Messages.sh create mode 100644 plasma/generic/scriptengines/webkit/README create mode 100644 plasma/generic/scriptengines/webkit/bundle.cpp create mode 100644 plasma/generic/scriptengines/webkit/bundle.h create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleAnimator.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleButton.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleInfoButton.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleScrollArea.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleScrollbar.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleSlider.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard/AppleClasses/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/webkit/dashboard/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/webkit/dashboard/button/CMakeLists.txt create mode 100644 plasma/generic/scriptengines/webkit/dashboard/button/genericButton.js create mode 100644 plasma/generic/scriptengines/webkit/dashboard_plugin.cpp create mode 100644 plasma/generic/scriptengines/webkit/dashboardapplet.cpp create mode 100644 plasma/generic/scriptengines/webkit/dashboardapplet.h create mode 100644 plasma/generic/scriptengines/webkit/dashboardjs.cpp create mode 100644 plasma/generic/scriptengines/webkit/dashboardjs.h create mode 100644 plasma/generic/scriptengines/webkit/plasma-packagestructure-dashboard.desktop create mode 100644 plasma/generic/scriptengines/webkit/plasma-packagestructure-web.desktop create mode 100644 plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-dashboard.desktop create mode 100644 plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-web.desktop create mode 100644 plasma/generic/scriptengines/webkit/plasmajs.cpp create mode 100644 plasma/generic/scriptengines/webkit/plasmajs.h create mode 100644 plasma/generic/scriptengines/webkit/plasmawebapplet.cpp create mode 100644 plasma/generic/scriptengines/webkit/plasmawebapplet.h create mode 100644 plasma/generic/scriptengines/webkit/tests/AppletAnimatorTest.html create mode 100644 plasma/generic/scriptengines/webkit/tests/HelloWorld.zip create mode 100644 plasma/generic/scriptengines/webkit/webapplet.cpp create mode 100644 plasma/generic/scriptengines/webkit/webapplet.h create mode 100644 plasma/generic/scriptengines/webkit/webapplet_package.cpp create mode 100644 plasma/generic/scriptengines/webkit/webapplet_package.h create mode 100644 plasma/generic/scriptengines/webkit/webapplet_plugin.cpp create mode 100644 plasma/generic/scriptengines/webkit/webpage.cpp create mode 100644 plasma/generic/scriptengines/webkit/webpage.h create mode 100644 plasma/generic/shells/CMakeLists.txt create mode 100644 plasma/generic/shells/plasma-windowed/CMakeLists.txt create mode 100755 plasma/generic/shells/plasma-windowed/Messages.sh create mode 100644 plasma/generic/shells/plasma-windowed/main.cpp create mode 100644 plasma/generic/shells/plasma-windowed/plasmaapp.cpp create mode 100644 plasma/generic/shells/plasma-windowed/plasmaapp.h create mode 100644 plasma/generic/shells/plasma-windowed/singleview.cpp create mode 100644 plasma/generic/shells/plasma-windowed/singleview.h create mode 100644 plasma/generic/wallpapers/CMakeLists.txt create mode 100644 plasma/generic/wallpapers/color/CMakeLists.txt create mode 100755 plasma/generic/wallpapers/color/Messages.sh create mode 100644 plasma/generic/wallpapers/color/backgrounddelegate.cpp create mode 100644 plasma/generic/wallpapers/color/backgrounddelegate.h create mode 100644 plasma/generic/wallpapers/color/backgroundlistmodel.cpp create mode 100644 plasma/generic/wallpapers/color/backgroundlistmodel.h create mode 100644 plasma/generic/wallpapers/color/color.cpp create mode 100644 plasma/generic/wallpapers/color/color.h create mode 100644 plasma/generic/wallpapers/color/config.ui create mode 100644 plasma/generic/wallpapers/color/itemsview.cpp create mode 100644 plasma/generic/wallpapers/color/itemsview.h create mode 100644 plasma/generic/wallpapers/color/plasma-wallpaper-color.desktop create mode 100644 plasma/generic/wallpapers/image/CMakeLists.txt create mode 100755 plasma/generic/wallpapers/image/Messages.sh create mode 100644 plasma/generic/wallpapers/image/backgrounddelegate.cpp create mode 100644 plasma/generic/wallpapers/image/backgrounddelegate.h create mode 100644 plasma/generic/wallpapers/image/backgroundlistmodel.cpp create mode 100644 plasma/generic/wallpapers/image/backgroundlistmodel.h create mode 100644 plasma/generic/wallpapers/image/image.cpp create mode 100644 plasma/generic/wallpapers/image/image.h create mode 100644 plasma/generic/wallpapers/image/imageconfig.ui create mode 100644 plasma/generic/wallpapers/image/itemsview.cpp create mode 100644 plasma/generic/wallpapers/image/itemsview.h create mode 100644 plasma/generic/wallpapers/image/plasma-wallpaper-image.desktop create mode 100644 plasma/generic/wallpapers/image/removebutton.cpp create mode 100644 plasma/generic/wallpapers/image/removebutton.h create mode 100644 plasma/generic/wallpapers/image/removebuttonmanager.cpp create mode 100644 plasma/generic/wallpapers/image/removebuttonmanager.h create mode 100644 plasma/generic/wallpapers/image/slideshowconfig.ui create mode 100644 plasma/generic/wallpapers/image/wallpaper.knsrc create mode 100644 plasma/netbook/CMakeLists.txt create mode 100644 plasma/netbook/applets/CMakeLists.txt create mode 100644 plasma/netbook/applets/currentappcontrol/CMakeLists.txt create mode 100644 plasma/netbook/applets/currentappcontrol/Messages.sh create mode 100644 plasma/netbook/applets/currentappcontrol/currentappcontrol.cpp create mode 100644 plasma/netbook/applets/currentappcontrol/currentappcontrol.h create mode 100644 plasma/netbook/applets/currentappcontrol/general.ui create mode 100644 plasma/netbook/applets/currentappcontrol/plasma-applet-currentappcontrol.desktop create mode 100644 plasma/netbook/applets/searchbox/CMakeLists.txt create mode 100644 plasma/netbook/applets/searchbox/Messages.sh create mode 100644 plasma/netbook/applets/searchbox/plasma-applet-searchbox.desktop create mode 100644 plasma/netbook/applets/searchbox/searchbox.cpp create mode 100644 plasma/netbook/applets/searchbox/searchbox.h create mode 100644 plasma/netbook/containments/CMakeLists.txt create mode 100644 plasma/netbook/containments/common/appletmovespacer.cpp create mode 100644 plasma/netbook/containments/common/appletmovespacer.h create mode 100644 plasma/netbook/containments/common/linearappletoverlay.cpp create mode 100644 plasma/netbook/containments/common/linearappletoverlay.h create mode 100644 plasma/netbook/containments/netpanel/CMakeLists.txt create mode 100644 plasma/netbook/containments/netpanel/Messages.sh create mode 100644 plasma/netbook/containments/netpanel/dummytoolbox.cpp create mode 100644 plasma/netbook/containments/netpanel/dummytoolbox.h create mode 100644 plasma/netbook/containments/netpanel/panel.cpp create mode 100644 plasma/netbook/containments/netpanel/panel.h create mode 100644 plasma/netbook/containments/netpanel/plasma-containment-netpanel.desktop create mode 100644 plasma/netbook/containments/sal/CMakeLists.txt create mode 100644 plasma/netbook/containments/sal/Messages.sh create mode 100644 plasma/netbook/containments/sal/iconactioncollection.cpp create mode 100644 plasma/netbook/containments/sal/iconactioncollection.h create mode 100644 plasma/netbook/containments/sal/itemcontainer.cpp create mode 100644 plasma/netbook/containments/sal/itemcontainer.h create mode 100644 plasma/netbook/containments/sal/itemview.cpp create mode 100644 plasma/netbook/containments/sal/itemview.h create mode 100644 plasma/netbook/containments/sal/models/commonmodel.h create mode 100644 plasma/netbook/containments/sal/models/favouritesmodel.cpp create mode 100644 plasma/netbook/containments/sal/models/favouritesmodel.h create mode 100644 plasma/netbook/containments/sal/models/krunnermodel.cpp create mode 100644 plasma/netbook/containments/sal/models/krunnermodel.h create mode 100644 plasma/netbook/containments/sal/models/kservicemodel.cpp create mode 100644 plasma/netbook/containments/sal/models/kservicemodel.h create mode 100644 plasma/netbook/containments/sal/models/standarditemfactory.cpp create mode 100644 plasma/netbook/containments/sal/models/standarditemfactory.h create mode 100644 plasma/netbook/containments/sal/plasma-containment-sal.desktop create mode 100644 plasma/netbook/containments/sal/plasma-sal-menu.desktop create mode 100644 plasma/netbook/containments/sal/resultwidget.cpp create mode 100644 plasma/netbook/containments/sal/resultwidget.h create mode 100644 plasma/netbook/containments/sal/runnersconfig.cpp create mode 100644 plasma/netbook/containments/sal/runnersconfig.h create mode 100644 plasma/netbook/containments/sal/sal.cpp create mode 100644 plasma/netbook/containments/sal/sal.h create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-bookmarks.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-contacts.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-development.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-education.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-games.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-graphics.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-internet.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-multimedia.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-office.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-system.desktop create mode 100644 plasma/netbook/containments/sal/services/plasma-sal-utility.desktop create mode 100644 plasma/netbook/containments/sal/stripwidget.cpp create mode 100644 plasma/netbook/containments/sal/stripwidget.h create mode 100644 plasma/netbook/dataengines/CMakeLists.txt create mode 100644 plasma/netbook/dataengines/searchlaunch/CMakeLists.txt create mode 100644 plasma/netbook/dataengines/searchlaunch/plasma-engine-searchlaunch.desktop create mode 100644 plasma/netbook/dataengines/searchlaunch/salengine.cpp create mode 100644 plasma/netbook/dataengines/searchlaunch/salengine.h create mode 100644 plasma/netbook/dataengines/searchlaunch/salservice.cpp create mode 100644 plasma/netbook/dataengines/searchlaunch/salservice.h create mode 100644 plasma/netbook/dataengines/searchlaunch/searchlaunch.operations create mode 100644 plasma/netbook/desktoptheme/CMakeLists.txt create mode 100644 plasma/netbook/desktoptheme/air-netbook/CMakeLists.txt create mode 100644 plasma/netbook/desktoptheme/air-netbook/colors create mode 100644 plasma/netbook/desktoptheme/air-netbook/metadata.desktop create mode 100644 plasma/netbook/desktoptheme/air-netbook/widgets/background.svgz create mode 100644 plasma/netbook/desktoptheme/air-netbook/widgets/panel-background.svgz create mode 100644 plasma/netbook/shell/CMakeLists.txt create mode 100644 plasma/netbook/shell/Messages.sh create mode 100644 plasma/netbook/shell/data/layouts/00-defaultLayout.js create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultPage/contents/layout.js create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultPage/metadata.desktop create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultPanel/contents/layout.js create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultPanel/metadata.desktop create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultSal/contents/layout.js create mode 100644 plasma/netbook/shell/data/layouts/org.kde.plasma-netbook.defaultSal/metadata.desktop create mode 100644 plasma/netbook/shell/data/layouts/plasma-layout-org.kde.plasma-netbook.defaultPage.desktop create mode 100644 plasma/netbook/shell/data/layouts/plasma-layout-org.kde.plasma-netbook.defaultPanel.desktop create mode 100644 plasma/netbook/shell/data/layouts/plasma-layout-org.kde.plasma-netbook.defaultSal.desktop create mode 100644 plasma/netbook/shell/main.cpp create mode 100644 plasma/netbook/shell/netcorona.cpp create mode 100644 plasma/netbook/shell/netcorona.h create mode 100644 plasma/netbook/shell/netdialogmanager.cpp create mode 100644 plasma/netbook/shell/netdialogmanager.h create mode 100644 plasma/netbook/shell/netpanelcontroller.cpp create mode 100644 plasma/netbook/shell/netpanelcontroller.h create mode 100644 plasma/netbook/shell/nettoolbox/CMakeLists.txt create mode 100644 plasma/netbook/shell/nettoolbox/Messages.sh create mode 100644 plasma/netbook/shell/nettoolbox/nettoolbox.cpp create mode 100644 plasma/netbook/shell/nettoolbox/nettoolbox.h create mode 100644 plasma/netbook/shell/nettoolbox/plasma-toolbox-nettoolbox.desktop create mode 100644 plasma/netbook/shell/netview.cpp create mode 100644 plasma/netbook/shell/netview.h create mode 100644 plasma/netbook/shell/plasmaapp.cpp create mode 100644 plasma/netbook/shell/plasmaapp.h create mode 100644 plasma/netbook/shell/scripting/netbookscriptengine.cpp create mode 100644 plasma/netbook/shell/scripting/netbookscriptengine.h create mode 100644 plasma/netbook/shell/scripting/newspaper.cpp create mode 100644 plasma/netbook/shell/scripting/newspaper.h create mode 100644 plasma/netbook/shell/scripting/panel.cpp create mode 100644 plasma/netbook/shell/scripting/panel.h create mode 100644 plasma/screensaver/CMakeLists.txt create mode 100644 plasma/screensaver/containments/CMakeLists.txt create mode 100644 plasma/screensaver/containments/screensaver/CMakeLists.txt create mode 100755 plasma/screensaver/containments/screensaver/Messages.sh create mode 100644 plasma/screensaver/containments/screensaver/desktop.cpp create mode 100644 plasma/screensaver/containments/screensaver/desktop.h create mode 100644 plasma/screensaver/containments/screensaver/plasma-containment-saverdesktop.desktop create mode 100644 plasma/screensaver/shell/BackgroundDialog.ui create mode 100644 plasma/screensaver/shell/CMakeLists.txt create mode 100755 plasma/screensaver/shell/Messages.sh create mode 100644 plasma/screensaver/shell/backgrounddialog.cpp create mode 100644 plasma/screensaver/shell/backgrounddialog.h create mode 100644 plasma/screensaver/shell/main.cpp create mode 100644 plasma/screensaver/shell/org.kde.plasma-overlay.App.xml create mode 100644 plasma/screensaver/shell/plasma-overlayrc create mode 100644 plasma/screensaver/shell/plasmaapp.cpp create mode 100644 plasma/screensaver/shell/plasmaapp.h create mode 100644 plasma/screensaver/shell/savercorona.cpp create mode 100644 plasma/screensaver/shell/savercorona.h create mode 100644 plasma/screensaver/shell/saverview.cpp create mode 100644 plasma/screensaver/shell/saverview.h create mode 100644 powerdevil/.krazy create mode 100644 powerdevil/CMakeLists.txt create mode 100644 powerdevil/COPYING create mode 100644 powerdevil/PowerDevilSettings.kcfg create mode 100644 powerdevil/PowerDevilSettings.kcfgc create mode 100644 powerdevil/daemon/BackendConfig.cmake create mode 100644 powerdevil/daemon/CMakeLists.txt create mode 100755 powerdevil/daemon/Messages.sh create mode 100644 powerdevil/daemon/actions/CMakeLists.txt create mode 100644 powerdevil/daemon/actions/bundled/CMakeLists.txt create mode 100644 powerdevil/daemon/actions/bundled/brightnesscontrol.cpp create mode 100644 powerdevil/daemon/actions/bundled/brightnesscontrol.h create mode 100644 powerdevil/daemon/actions/bundled/brightnesscontrolconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/brightnesscontrolconfig.h create mode 100644 powerdevil/daemon/actions/bundled/dimdisplay.cpp create mode 100644 powerdevil/daemon/actions/bundled/dimdisplay.h create mode 100644 powerdevil/daemon/actions/bundled/dimdisplayconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/dimdisplayconfig.h create mode 100644 powerdevil/daemon/actions/bundled/handlebuttonevents.cpp create mode 100644 powerdevil/daemon/actions/bundled/handlebuttonevents.h create mode 100644 powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.h create mode 100644 powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.cpp create mode 100644 powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.h create mode 100644 powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.h create mode 100644 powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml create mode 100644 powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml create mode 100644 powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml create mode 100644 powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml create mode 100644 powerdevil/daemon/actions/bundled/powerdevilbrightnesscontrolaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/powerdevildimdisplayaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/powerdevilhandlebuttoneventsaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/powerdevilkeyboardbrightnesscontrolaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/powerdevilrunscriptaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/powerdevilsuspendsessionaction.desktop create mode 100644 powerdevil/daemon/actions/bundled/runscript.cpp create mode 100644 powerdevil/daemon/actions/bundled/runscript.h create mode 100644 powerdevil/daemon/actions/bundled/runscriptconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/runscriptconfig.h create mode 100644 powerdevil/daemon/actions/bundled/suspendsession.cpp create mode 100644 powerdevil/daemon/actions/bundled/suspendsession.h create mode 100644 powerdevil/daemon/actions/bundled/suspendsessionconfig.cpp create mode 100644 powerdevil/daemon/actions/bundled/suspendsessionconfig.h create mode 100644 powerdevil/daemon/actions/dpms/CMakeLists.txt create mode 100644 powerdevil/daemon/actions/dpms/powerdevildpmsaction.cpp create mode 100644 powerdevil/daemon/actions/dpms/powerdevildpmsaction.desktop create mode 100644 powerdevil/daemon/actions/dpms/powerdevildpmsaction.h create mode 100644 powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.cpp create mode 100644 powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.h create mode 100644 powerdevil/daemon/actions/powerdevilaction.desktop create mode 100644 powerdevil/daemon/backends/hal/halsuspendjob.cpp create mode 100644 powerdevil/daemon/backends/hal/halsuspendjob.h create mode 100644 powerdevil/daemon/backends/hal/powerdevilhalbackend.cpp create mode 100644 powerdevil/daemon/backends/hal/powerdevilhalbackend.desktop create mode 100644 powerdevil/daemon/backends/hal/powerdevilhalbackend.h create mode 100644 powerdevil/daemon/backends/upower/backlight_helper_actions.actions create mode 100644 powerdevil/daemon/backends/upower/backlighthelper.cpp create mode 100644 powerdevil/daemon/backends/upower/backlighthelper.h create mode 100644 powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml create mode 100644 powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.Device.xml create mode 100644 powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml create mode 100644 powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.xml create mode 100644 powerdevil/daemon/backends/upower/login1suspendjob.cpp create mode 100644 powerdevil/daemon/backends/upower/login1suspendjob.h create mode 100644 powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp create mode 100644 powerdevil/daemon/backends/upower/powerdevilupowerbackend.desktop create mode 100644 powerdevil/daemon/backends/upower/powerdevilupowerbackend.h create mode 100644 powerdevil/daemon/backends/upower/udevqt.h create mode 100644 powerdevil/daemon/backends/upower/udevqt_p.h create mode 100644 powerdevil/daemon/backends/upower/udevqtclient.cpp create mode 100644 powerdevil/daemon/backends/upower/udevqtdevice.cpp create mode 100644 powerdevil/daemon/backends/upower/upowersuspendjob.cpp create mode 100644 powerdevil/daemon/backends/upower/upowersuspendjob.h create mode 100644 powerdevil/daemon/backends/upower/xlibandxrandr.h create mode 100644 powerdevil/daemon/backends/upower/xrandrbrightness.cpp create mode 100644 powerdevil/daemon/backends/upower/xrandrbrightness.h create mode 100644 powerdevil/daemon/backends/upower/xrandrx11helper.cpp create mode 100644 powerdevil/daemon/backends/upower/xrandrx11helper.h create mode 100644 powerdevil/daemon/brightnessosdwidget.cpp create mode 100644 powerdevil/daemon/brightnessosdwidget.h create mode 100644 powerdevil/daemon/config-powerdevil.h.cmake create mode 100644 powerdevil/daemon/kdedpowerdevil.cpp create mode 100644 powerdevil/daemon/kdedpowerdevil.h create mode 100644 powerdevil/daemon/org.kde.Solid.PowerManagement.xml create mode 100644 powerdevil/daemon/powerdevil.desktop create mode 100644 powerdevil/daemon/powerdevilaction.cpp create mode 100644 powerdevil/daemon/powerdevilaction.h create mode 100644 powerdevil/daemon/powerdevilactionconfig.cpp create mode 100644 powerdevil/daemon/powerdevilactionconfig.h create mode 100644 powerdevil/daemon/powerdevilactionpool.cpp create mode 100644 powerdevil/daemon/powerdevilactionpool.h create mode 100644 powerdevil/daemon/powerdevilbackendinterface.cpp create mode 100644 powerdevil/daemon/powerdevilbackendinterface.h create mode 100644 powerdevil/daemon/powerdevilbackendloader.cpp create mode 100644 powerdevil/daemon/powerdevilbackendloader.h create mode 100644 powerdevil/daemon/powerdevilcore.cpp create mode 100644 powerdevil/daemon/powerdevilcore.h create mode 100644 powerdevil/daemon/powerdevilfdoconnector.cpp create mode 100644 powerdevil/daemon/powerdevilfdoconnector.h create mode 100644 powerdevil/daemon/powerdevilpolicyagent.cpp create mode 100644 powerdevil/daemon/powerdevilpolicyagent.h create mode 100644 powerdevil/daemon/powerdevilprofilegenerator.cpp create mode 100644 powerdevil/daemon/powerdevilprofilegenerator.h create mode 100644 powerdevil/kcmodule/CMakeLists.txt create mode 100644 powerdevil/kcmodule/activities/CMakeLists.txt create mode 100644 powerdevil/kcmodule/activities/Messages.sh create mode 100644 powerdevil/kcmodule/activities/activityWidget.ui create mode 100644 powerdevil/kcmodule/activities/activitypage.cpp create mode 100644 powerdevil/kcmodule/activities/activitypage.h create mode 100644 powerdevil/kcmodule/activities/activitywidget.cpp create mode 100644 powerdevil/kcmodule/activities/activitywidget.h create mode 100644 powerdevil/kcmodule/activities/powerdevilactivitiesconfig.desktop create mode 100644 powerdevil/kcmodule/common/CMakeLists.txt create mode 100644 powerdevil/kcmodule/common/ErrorOverlay.cpp create mode 100644 powerdevil/kcmodule/common/ErrorOverlay.h create mode 100644 powerdevil/kcmodule/common/Messages.sh create mode 100644 powerdevil/kcmodule/common/actionconfigwidget.cpp create mode 100644 powerdevil/kcmodule/common/actionconfigwidget.h create mode 100644 powerdevil/kcmodule/common/actioneditwidget.cpp create mode 100644 powerdevil/kcmodule/common/actioneditwidget.h create mode 100644 powerdevil/kcmodule/global/CMakeLists.txt create mode 100644 powerdevil/kcmodule/global/GeneralPage.cpp create mode 100644 powerdevil/kcmodule/global/GeneralPage.h create mode 100755 powerdevil/kcmodule/global/Messages.sh create mode 100644 powerdevil/kcmodule/global/generalPage.ui create mode 100644 powerdevil/kcmodule/global/powerdevilglobalconfig.desktop create mode 100644 powerdevil/kcmodule/profiles/CMakeLists.txt create mode 100644 powerdevil/kcmodule/profiles/EditPage.cpp create mode 100644 powerdevil/kcmodule/profiles/EditPage.h create mode 100755 powerdevil/kcmodule/profiles/Messages.sh create mode 100644 powerdevil/kcmodule/profiles/powerdevilprofilesconfig.desktop create mode 100644 powerdevil/kcmodule/profiles/profileEditPage.ui create mode 100644 powerdevil/powerdevil.notifyrc create mode 100644 qguiplatformplugin_kde/CMakeLists.txt create mode 100644 qguiplatformplugin_kde/qguiplatformplugin_kde.cpp create mode 100644 qguiplatformplugin_kde/qguiplatformplugin_p.h create mode 100644 solid-actions-kcm/ActionEditor.cpp create mode 100644 solid-actions-kcm/ActionEditor.h create mode 100644 solid-actions-kcm/ActionEditor.ui create mode 100644 solid-actions-kcm/ActionItem.cpp create mode 100644 solid-actions-kcm/ActionItem.h create mode 100644 solid-actions-kcm/ActionModel.cpp create mode 100644 solid-actions-kcm/ActionModel.h create mode 100644 solid-actions-kcm/AddAction.ui create mode 100644 solid-actions-kcm/CMakeLists.txt create mode 100644 solid-actions-kcm/DesktopFileGenerator.cpp create mode 100644 solid-actions-kcm/Messages.sh create mode 100644 solid-actions-kcm/PredicateItem.cpp create mode 100644 solid-actions-kcm/PredicateItem.h create mode 100644 solid-actions-kcm/PredicateModel.cpp create mode 100644 solid-actions-kcm/PredicateModel.h create mode 100644 solid-actions-kcm/SolidActionData.cpp create mode 100644 solid-actions-kcm/SolidActionData.h create mode 100644 solid-actions-kcm/SolidActions.cpp create mode 100644 solid-actions-kcm/SolidActions.h create mode 100644 solid-actions-kcm/SolidActions.ui create mode 100644 solid-actions-kcm/device-actions/CMakeLists.txt create mode 100644 solid-actions-kcm/device-actions/solid-device-AcAdapter.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-AudioInterface.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Battery.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Block.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Button.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Camera.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-DvbInterface.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-NetworkInterface.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-OpticalDisc.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-OpticalDrive.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-PortableMediaPlayer.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Processor.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-SerialInterface.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-SmartCardReader.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-StorageAccess.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-StorageDrive.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-StorageVolume.desktop create mode 100644 solid-actions-kcm/device-actions/solid-device-Video.desktop create mode 100644 solid-actions-kcm/solid-action-template.desktop create mode 100644 solid-actions-kcm/solid-actions.desktop create mode 100644 solid-actions-kcm/solid-device-type.desktop create mode 100644 startkde.cmake create mode 100644 statusnotifierwatcher/CMakeLists.txt create mode 100644 statusnotifierwatcher/statusnotifierwatcher.cpp create mode 100644 statusnotifierwatcher/statusnotifierwatcher.desktop create mode 100644 statusnotifierwatcher/statusnotifierwatcher.h create mode 100644 statusnotifierwatcher/systemtraytypedefs.h create mode 100644 systemsettings/CMakeLists.txt create mode 100644 systemsettings/Mainpage.dox create mode 100644 systemsettings/Messages.sh create mode 100644 systemsettings/app/BaseConfig.kcfgc create mode 100644 systemsettings/app/CMakeLists.txt create mode 100644 systemsettings/app/SettingsBase.cpp create mode 100644 systemsettings/app/SettingsBase.h create mode 100644 systemsettings/app/SystemSettingsApp.cpp create mode 100644 systemsettings/app/SystemSettingsApp.h create mode 100644 systemsettings/app/ToolTips/ktooltip.cpp create mode 100644 systemsettings/app/ToolTips/ktooltip.h create mode 100644 systemsettings/app/ToolTips/ktooltipwindow.cpp create mode 100644 systemsettings/app/ToolTips/ktooltipwindow_p.h create mode 100644 systemsettings/app/ToolTips/tooltipmanager.cpp create mode 100644 systemsettings/app/ToolTips/tooltipmanager.h create mode 100644 systemsettings/app/configDialog.ui create mode 100755 systemsettings/app/kdesystemsettings.desktop create mode 100644 systemsettings/app/main.cpp create mode 100644 systemsettings/app/org.kde.systemsettings.xml create mode 100755 systemsettings/app/systemsettings.desktop create mode 100644 systemsettings/app/systemsettings.kcfg create mode 100644 systemsettings/app/systemsettingsui.rc create mode 100644 systemsettings/categories/CMakeLists.txt create mode 100644 systemsettings/categories/settings-accessibility.desktop create mode 100644 systemsettings/categories/settings-account-details.desktop create mode 100644 systemsettings/categories/settings-application-and-system-notifications.desktop create mode 100644 systemsettings/categories/settings-application-appearance-and-behavior.desktop create mode 100644 systemsettings/categories/settings-application-appearance.desktop create mode 100644 systemsettings/categories/settings-audio-and-video.desktop create mode 100644 systemsettings/categories/settings-bluetooth.desktop create mode 100644 systemsettings/categories/settings-desktop-appearance.desktop create mode 100644 systemsettings/categories/settings-display.desktop create mode 100644 systemsettings/categories/settings-hardware.desktop create mode 100644 systemsettings/categories/settings-input-devices.desktop create mode 100644 systemsettings/categories/settings-locale.desktop create mode 100644 systemsettings/categories/settings-lost-and-found.desktop create mode 100644 systemsettings/categories/settings-network-and-connectivity.desktop create mode 100644 systemsettings/categories/settings-network-settings.desktop create mode 100644 systemsettings/categories/settings-permissions.desktop create mode 100644 systemsettings/categories/settings-personal-information.desktop create mode 100644 systemsettings/categories/settings-power-management.desktop create mode 100644 systemsettings/categories/settings-removable-devices.desktop create mode 100644 systemsettings/categories/settings-sharing.desktop create mode 100644 systemsettings/categories/settings-shortcuts-and-gestures.desktop create mode 100644 systemsettings/categories/settings-startup-and-shutdown.desktop create mode 100644 systemsettings/categories/settings-system-administration.desktop create mode 100644 systemsettings/categories/settings-window-behaviour.desktop create mode 100644 systemsettings/categories/settings-workspace-appearance-and-behavior.desktop create mode 100644 systemsettings/categories/settings-workspace-behavior.desktop create mode 100644 systemsettings/categories/systemsettingscategory.desktop create mode 100644 systemsettings/classic/CMakeLists.txt create mode 100644 systemsettings/classic/CategoryList.cpp create mode 100644 systemsettings/classic/CategoryList.h create mode 100644 systemsettings/classic/ClassicMode.cpp create mode 100644 systemsettings/classic/ClassicMode.h create mode 100644 systemsettings/classic/configClassic.ui create mode 100644 systemsettings/classic/main.html create mode 100644 systemsettings/classic/settings-classic-view.desktop create mode 100644 systemsettings/classic/systemsettings-classic.css create mode 100644 systemsettings/core/BaseData.cpp create mode 100644 systemsettings/core/BaseData.h create mode 100644 systemsettings/core/BaseMode.cpp create mode 100644 systemsettings/core/BaseMode.h create mode 100644 systemsettings/core/CMakeLists.txt create mode 100644 systemsettings/core/ExternalAppModule.cpp create mode 100644 systemsettings/core/ExternalAppModule.h create mode 100644 systemsettings/core/Mainpage.dox create mode 100644 systemsettings/core/MenuItem.cpp create mode 100644 systemsettings/core/MenuItem.h create mode 100644 systemsettings/core/MenuModel.cpp create mode 100644 systemsettings/core/MenuModel.h create mode 100644 systemsettings/core/MenuProxyModel.cpp create mode 100644 systemsettings/core/MenuProxyModel.h create mode 100644 systemsettings/core/ModuleView.cpp create mode 100644 systemsettings/core/ModuleView.h create mode 100644 systemsettings/core/externalModule.ui create mode 100644 systemsettings/core/systemsettingsexternalapp.desktop create mode 100644 systemsettings/core/systemsettingsview.desktop create mode 100644 systemsettings/core/systemsettingsview_export.h create mode 100644 systemsettings/examples/external-application.txt create mode 100644 systemsettings/examples/native-kcm.txt create mode 100644 systemsettings/icons/CMakeLists.txt create mode 100644 systemsettings/icons/CategorizedView.cpp create mode 100644 systemsettings/icons/CategorizedView.h create mode 100644 systemsettings/icons/CategoryDrawer.cpp create mode 100644 systemsettings/icons/CategoryDrawer.h create mode 100644 systemsettings/icons/IconMode.cpp create mode 100644 systemsettings/icons/IconMode.h create mode 100644 systemsettings/icons/settings-icon-view.desktop diff --git a/.krazy b/.krazy new file mode 100644 index 00000000..83ba0507 --- /dev/null +++ b/.krazy @@ -0,0 +1,5 @@ +#kcheckpass is mostly C, so let's not check there. +IGNORESUBS kcheckpass + +#no code in these +IGNORESUBS cursors diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..3d4287c2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,360 @@ +project(KDEBASE_WORKSPACE) +# set_package_properties appeared in cmake 2.8.6 +# TODO: Remove when kdelibs >= 4.10 will be required +cmake_minimum_required(VERSION 2.8.6 FATAL_ERROR) + +# Used e.g. in KDE4WorkspaceConfig.cmake, Alex +set(KDE4WORKSPACE_VERSION_MAJOR 4) +set(KDE4WORKSPACE_VERSION_MINOR 11) +set(KDE4WORKSPACE_VERSION_PATCH 14) +set(KDE4WORKSPACE_VERSION ${KDE4WORKSPACE_VERSION_MAJOR}.${KDE4WORKSPACE_VERSION_MINOR}.${KDE4WORKSPACE_VERSION_PATCH} ) + +# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH} ) + +#search packages used by KDE +set(QT_MIN_VERSION "4.8.0") + +find_package(KDE4 4.9.4 REQUIRED) +include(KDE4Defaults) + +option(WITH_XINERAMA "Xinerama support for multi-headed X displays" ON) + +find_package(Strigi) + +set_package_properties(Strigi PROPERTIES DESCRIPTION "Desktop indexing and search support" + URL "http://strigi.sourceforge.net" + TYPE REQUIRED + ) + +find_package(ZLIB) +set_package_properties(ZLIB PROPERTIES DESCRIPTION "Support for gzip compressed files and data streams" + URL "http://www.zlib.net" + TYPE REQUIRED + ) + +find_package(KActivities 6.0.0 CONFIG) +set_package_properties(KActivities PROPERTIES DESCRIPTION "Interface library for the activity manager" + URL "https://projects.kde.org/kactivities" + TYPE REQUIRED + ) + +find_package(DBusMenuQt 0.6.0) +set_package_properties(DBusMenuQt PROPERTIES DESCRIPTION "Support for notification area menus via the DBusMenu protocol" + URL "https://launchpad.net/libdbusmenu-qt" + TYPE REQUIRED + ) + +find_package(QImageBlitz) +set_package_properties(QImageBlitz PROPERTIES DESCRIPTION "An image effects library" + URL "http://sourceforge.net/projects/qimageblitz" + TYPE REQUIRED + ) + +find_package(KDeclarative QUIET CONFIG) +set_package_properties(KDeclarative PROPERTIES DESCRIPTION "KDE Declarative (QML) support from kdelibs" + URL "http://www.kde.org" + TYPE REQUIRED + PURPOSE "Required for building ksmserver" + ) + +macro_optional_find_package(OpenGL) +set_package_properties(OpenGL PROPERTIES DESCRIPTION "The OpenGL libraries" + URL "http://www.opengl.org" + TYPE OPTIONAL + ) +macro_optional_find_package(OpenGLES) +set_package_properties(OpenGLES PROPERTIES DESCRIPTION "The OpenGLES libraries" + URL "http://www.khronos.org/opengles" + TYPE OPTIONAL + ) +macro_optional_find_package(UDev) +set_package_properties(UDev PROPERTIES DESCRIPTION "The UDev Libraries" + TYPE OPTIONAL + PURPOSE "Allows support for UPower backend in PowerDevil - STRONGLY RECOMMENDED" + ) + +macro_optional_find_package(Wayland) +set_package_properties(Wayland PROPERTIES DESCRIPTION "The Wayland Client and Server libraries" + URL "http://wayland.freedesktop.org" + TYPE OPTIONAL + PURPOSE "Required for building KWin with Wayland support" + ) +if(Q_WS_X11) + find_package(XCB REQUIRED) + set_package_properties(XCB PROPERTIES DESCRIPTION "X protocol C-language Binding" + URL "http://xcb.freedesktop.org" + TYPE REQUIRED + ) + + find_package(X11_XCB) + set_package_properties(X11_XCB PROPERTIES DESCRIPTION "XCB X11 protocol client library" + TYPE REQUIRED + ) + + find_package(X11 REQUIRED) + set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" + URL "http://www.x.org" + TYPE REQUIRED + ) + + add_feature_info("Automated testing of X clients" X11_XTest_FOUND + "The X11 Testing Resource extension library is useful for automated testing of X clients") + add_feature_info("libXau" X11_Xau_FOUND "The X11 Authorization Protocol library may be used by KDM") + add_feature_info("LibXdmcp" X11_Xdmcp_FOUND "The X Display Manager Control Protocol library may be used by KDM") + if(NOT X11_Xkbfile_FOUND) + message(FATAL_ERROR "The X11 keyboard layout library was not found. Required for building keyboard modules.") + endif() + if(NOT X11_Xcomposite_FOUND) + message(FATAL_ERROR "The X11 composite library was not found. Required for building the plasma tray and notifications widgets.") + endif() + if(NOT X11_Xdamage_FOUND) + message(FATAL_ERROR "The X11 damaged region extension library was not found. Required for compositing support in KWin.") + endif() + if(NOT X11_Xrender_FOUND) + message(FATAL_ERROR " The X Rendering Extension client library was not found. Required for XRender Compositing backend in KWin.") + endif() + if(NOT X11_Xfixes_FOUND) + message(FATAL_ERROR "The X11 miscellaneous 'fixes' extension library was not found. Required for XRender Compositing backend in KWin.") + endif() + if(NOT X11_Xrandr_FOUND) + message(FATAL_ERROR "The X11 RandR extension library was not found. Required for Multi Screen Support.") + endif() + if(NOT OPENGL_FOUND AND NOT OPENGLES_FOUND) + message(FATAL_ERROR "Either OpenGL or OpenGL ES 2.0 are required for Compositing support in KWin.") + endif() + if(NOT X11_Xcursor_FOUND) + message(FATAL_ERROR "The X11 cursor management library was not found. Required for desktop effects support in KWin.") + endif() +endif(Q_WS_X11) + +macro_optional_find_package(GLIB2 2.0) +set_package_properties(GLIB2 PROPERTIES DESCRIPTION "Low-level core library for data structure handling, portability wrappers, etc." + URL "http://www.gtk.org" + TYPE OPTIONAL + PURPOSE "Needed to build the kxkb keyboard map control program and provide XMMS support in the Now Playing Plasma data engine" + ) + +macro_optional_find_package(Fontconfig) +set_package_properties(Fontconfig PROPERTIES DESCRIPTION "Font access configuration library" + URL "http://www.freedesktop.org/wiki/Software/fontconfig" + TYPE OPTIONAL + PURPOSE "Needed to build font configuration and installation tools" + ) + +#### Python support ( plasma scriptengines ) #### +macro_optional_find_package(PythonLibrary) +set_package_properties(PythonLibrary PROPERTIES DESCRIPTION "Python scripting language" + URL "http://python.org" + TYPE OPTIONAL + PURPOSE "Needed to build plasma scriptengine for python." + ) + +macro_optional_find_package(Soprano 2.7.56) +set_package_properties(Soprano PROPERTIES DESCRIPTION "Semantic Desktop Storing" + URL "http://soprano.sourceforge.net" + TYPE OPTIONAL + PURPOSE "Required to build Nepomuk features." + ) + +macro_optional_find_package(NepomukCore QUIET CONFIG) +set_package_properties(NepomukCore PROPERTIES DESCRIPTION "Nepomuk Core Library" + URL "https://projects.kde.org/nepomuk-core" + TYPE OPTIONAL + PURPOSE "Required to build Nepomuk features." + ) + +macro_optional_find_package(Boost 1.34.0 MODULE) +set_package_properties(Boost PROPERTIES DESCRIPTION "Boost C++ Libraries" + URL "http://www.boost.org" + TYPE OPTIONAL + PURPOSE "Required to build certain Plasma DataEngines (Akonadi, RSS, Calendar)" + ) + +macro_optional_find_package(Akonadi QUIET CONFIG) +set_package_properties(Akonadi PROPERTIES DESCRIPTION "An extensible cross-desktop storage service for PIM data" + URL "http://pim.kde.org/akonadi" + TYPE OPTIONAL + PURPOSE "Required to build certain Plasma DataEngines (Akonadi, Calendar)" + ) + +macro_optional_find_package(KdepimLibs 4.10.68 QUIET CONFIG) +set_package_properties(KdepimLibs PROPERTIES DESCRIPTION "The KDEPIM libraries" + URL "http://pim.kde.org" + TYPE OPTIONAL + PURPOSE "Required to build certain Plasma DataEngines (Akonadi, Calendar)" + ) + +macro_optional_find_package(QJSON) +set_package_properties(QJSON PROPERTIES DESCRIPTION "Library to manage JSON objects with Qt" + URL "http://qjson.sourceforge.net/" + TYPE OPTIONAL + PURPOSE "Required to build Chrome/Chromium support for Plasma Bookmarks Runners" + ) + + +include(ConfigureChecks.cmake) +if(NOT WIN32) + configure_file(config-unix.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-unix.h ) + configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h ) + if(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr") + set(EXPORT_XCURSOR_PATH "XCURSOR_PATH=${CMAKE_INSTALL_PREFIX}/share/icons:$XCURSOR_PATH\":~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons\"; export XCURSOR_PATH") + endif(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr") + configure_file(startkde.cmake ${CMAKE_CURRENT_BINARY_DIR}/startkde @ONLY) +endif(NOT WIN32) +configure_file(config-workspace.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-workspace.h ) + +add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -DHAVE_CONFIG_H=1) +add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS) +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${KACTIVITIES_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libs) + +add_definitions(-DDISABLE_NEPOMUK_LEGACY) + +# libs +add_subdirectory(cmake) +add_subdirectory(libs) + +# system settings (kcontrol replacement) +if(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + macro_optional_add_subdirectory( systemsettings ) +endif(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + +# core apps +if(NOT WIN32) + macro_optional_add_subdirectory( kcheckpass ) + macro_optional_add_subdirectory( kwin ) + macro_optional_add_subdirectory( ksmserver ) + + find_package(JPEG REQUIRED) + find_package(PNG REQUIRED) + macro_optional_add_subdirectory( ksplash ) + + macro_optional_add_subdirectory( powerdevil ) + macro_optional_add_subdirectory( qguiplatformplugin_kde ) + if (NOT CMAKE_SYSTEM_NAME MATCHES Darwin) + macro_optional_add_subdirectory( ksysguard ) + endif (NOT CMAKE_SYSTEM_NAME MATCHES Darwin) +endif(NOT WIN32) + +if(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + macro_optional_add_subdirectory(kcontrol) + macro_optional_add_subdirectory(klipper) + macro_optional_add_subdirectory(kmenuedit) + macro_optional_add_subdirectory(krunner) + macro_optional_add_subdirectory(solid-actions-kcm) + macro_optional_add_subdirectory(kstartupconfig) + macro_optional_add_subdirectory(freespacenotifier) + macro_optional_add_subdirectory(kscreensaver) + macro_optional_add_subdirectory(kinfocenter) + + # data + macro_optional_add_subdirectory(doc) + + if (Q_WS_X11) + macro_optional_add_subdirectory(ktouchpadenabler) + endif (Q_WS_X11) + + if(NOT WIN32) + macro_optional_add_subdirectory(kcminit) + macro_optional_add_subdirectory(khotkeys) + macro_optional_add_subdirectory(kwrited) + macro_optional_add_subdirectory(ksystraycmd) + macro_optional_add_subdirectory(appmenu) + endif(NOT WIN32) + + if(X11_Xau_FOUND AND X11_Xdmcp_FOUND) + macro_optional_add_subdirectory( kdm ) + else(X11_Xau_FOUND AND X11_Xdmcp_FOUND) + message(STATUS "Xau lib or Xdmcp lib was missing. kdm will not compile") + endif(X11_Xau_FOUND AND X11_Xdmcp_FOUND) +endif(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + +if(NOT WIN32) + # data + macro_optional_add_subdirectory(cursors) +endif(NOT WIN32) + +macro_optional_add_subdirectory(plasma) +macro_optional_add_subdirectory(statusnotifierwatcher) +macro_optional_add_subdirectory(kstyles) + +########### install files ############### +if(NOT WIN32) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/startkde DESTINATION ${BIN_INSTALL_DIR}) +endif(NOT WIN32) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) + +# make the libraries installed from kdebase/workspace available to other projects +# by creating and installing a KDE4WorkspaceConfig.cmake file, which will +# be searched and found by kdelibs/cmake/modules/FindKDE4Workspace.cmake. Alex + +# now create the KDE4WorkspaceConfig.cmake file, which will be loaded by +# kdelibs/cmake/modules/FindKDE4Workspace.cmake and which has to contain all information +# about the libraries installed from kdebase/workspace/libs/ anybody would like to have. Alex + +# we need the absolute directories where stuff will be installed too +# but since the variables which contain the destinations can be relative +# or absolute paths, we need this macro to make them all absoulte, Alex +macro(MAKE_INSTALL_PATH_ABSOLUTE out in) + if (IS_ABSOLUTE "${in}") # IS_ABSOLUTE is new since cmake 2.4.8 + set(${out} "${in}") + else (IS_ABSOLUTE "${in}") + set(${out} "\${KDE4WORKSPACE_INSTALL_DIR}/${in}") + endif (IS_ABSOLUTE "${in}") +endmacro(MAKE_INSTALL_PATH_ABSOLUTE out in) + +make_install_path_absolute(KDE4WORKSPACE_LIB_DIR ${LIB_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_LIBEXEC_DIR ${LIBEXEC_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_INCLUDE_DIR ${INCLUDE_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_BIN_DIR ${BIN_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_SBIN_DIR ${SBIN_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_DATA_DIR ${DATA_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_HTML_DIR ${HTML_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_CONFIG_DIR ${CONFIG_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_ICON_DIR ${ICON_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_KCFG_DIR ${KCFG_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_LOCALE_DIR ${LOCALE_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_MIME_DIR ${MIME_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_SOUND_DIR ${SOUND_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_TEMPLATES_DIR ${TEMPLATES_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_WALLPAPER_DIR ${WALLPAPER_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_KCONF_UPDATE_DIR ${KCONF_UPDATE_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_AUTOSTART_DIR ${AUTOSTART_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_XDG_APPS_DIR ${XDG_APPS_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_XDG_DIRECTORY_DIR ${XDG_DIRECTORY_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_SYSCONF_DIR ${SYSCONF_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_MAN_DIR ${MAN_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_INFO_DIR ${INFO_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_DBUS_INTERFACES_DIR ${DBUS_INTERFACES_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_DBUS_SERVICES_DIR ${DBUS_SERVICES_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_SERVICES_DIR ${SERVICES_INSTALL_DIR}) +make_install_path_absolute(KDE4WORKSPACE_SERVICETYPES_DIR ${SERVICETYPES_INSTALL_DIR}) + +set(KDE4WORKSPACE_TARGET_PREFIX KDE4Workspace__) + +configure_file(KDE4WorkspaceConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/KDE4WorkspaceConfig.cmake" @ONLY) + +# this file will be installed too and will be used by cmake when searching for the Config.cmake file to check the version of kdepimlibs, Alex +macro_write_basic_cmake_version_file(${CMAKE_CURRENT_BINARY_DIR}/KDE4WorkspaceConfigVersion.cmake + ${KDE4WORKSPACE_VERSION_MAJOR} ${KDE4WORKSPACE_VERSION_MINOR} ${KDE4WORKSPACE_VERSION_PATCH}) + +set(_KDE4WorkspaceConfig_INSTALL_DIR ${LIB_INSTALL_DIR}/KDE4Workspace/cmake) +# places where find_package() looks for FooConfig.cmake files: +# CMake >= 2.6.0 looks in lib/Foo*/cmake/, CMake >= 2.6.3 also looks in +# lib/cmake/Foo*/, which packagers prefer. So they can set the KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR +# option to have kdepimlibs install its Config file there. Alex +if(KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) + set(_KDE4WorkspaceConfig_INSTALL_DIR ${LIB_INSTALL_DIR}/cmake/KDE4Workspace) +endif(KDE4_USE_COMMON_CMAKE_PACKAGE_CONFIG_DIR) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/KDE4WorkspaceConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/KDE4WorkspaceConfigVersion.cmake + DESTINATION ${_KDE4WorkspaceConfig_INSTALL_DIR}) + +install(EXPORT kdeworkspaceLibraryTargets + NAMESPACE ${KDE4WORKSPACE_TARGET_PREFIX} + DESTINATION ${_KDE4WorkspaceConfig_INSTALL_DIR} + FILE KDE4WorkspaceLibraryTargets.cmake ) + + diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..5185fd3f --- /dev/null +++ b/COPYING @@ -0,0 +1,346 @@ +NOTE! The GPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (the kde programs) are copyrighted +by the authors who actually wrote it. + +--------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.DOC b/COPYING.DOC new file mode 100644 index 00000000..4a0fe1c8 --- /dev/null +++ b/COPYING.DOC @@ -0,0 +1,397 @@ + GNU Free Documentation License + Version 1.2, November 2002 + + + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 00000000..2d2d780e --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/CTestConfig.cmake b/CTestConfig.cmake new file mode 100644 index 00000000..7db6e84d --- /dev/null +++ b/CTestConfig.cmake @@ -0,0 +1,13 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## # The following are required to uses Dart and the Cdash dashboard +## ENABLE_TESTING() +## INCLUDE(CTest) +set(CTEST_PROJECT_NAME "kdebase-workspace") +set(CTEST_NIGHTLY_START_TIME "20:00:00 CET") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=kdebase-workspace") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake new file mode 100644 index 00000000..6f53e4b8 --- /dev/null +++ b/ConfigureChecks.cmake @@ -0,0 +1,102 @@ +include(UnixAuth) +set_package_properties(PAM PROPERTIES DESCRIPTION "PAM Libraries" + URL "https://www.kernel.org/pub/linux/libs/pam/" + TYPE OPTIONAL + PURPOSE "Required for screen unlocking and optionally used by the KDM log in manager" + ) +include(CheckTypeSize) +include(FindPkgConfig) + +macro_optional_find_package(XKB) # kxkb, kdm + +if (PAM_FOUND) + set(KDE4_COMMON_PAM_SERVICE "kde" CACHE STRING "The PAM service to use unless overridden for a particular app.") + + macro(define_pam_service APP) + string(TOUPPER ${APP}_PAM_SERVICE var) + set(cvar KDE4_${var}) + set(${cvar} "${KDE4_COMMON_PAM_SERVICE}" CACHE STRING "The PAM service for ${APP}.") + mark_as_advanced(${cvar}) + set(${var} "\"${${cvar}}\"") + endmacro(define_pam_service) + + macro(install_pam_service APP) + string(TOUPPER KDE4_${APP}_PAM_SERVICE cvar) + install(CODE " + set(DESTDIR_VALUE \"\$ENV{DESTDIR}\") + if (NOT DESTDIR_VALUE) + exec_program(\"${KDEBASE_WORKSPACE_SOURCE_DIR}/mkpamserv\" ARGS ${${cvar}} RETURN_VALUE ret) + if (NOT ret) + exec_program(\"${KDEBASE_WORKSPACE_SOURCE_DIR}/mkpamserv\" ARGS -P ${${cvar}}-np) + endif (NOT ret) + endif (NOT DESTDIR_VALUE) + ") + endmacro(install_pam_service) + + define_pam_service(KDM) + define_pam_service(kscreensaver) + +else (PAM_FOUND) + + macro(install_pam_service APP) + endmacro(install_pam_service) + +endif (PAM_FOUND) + +find_program(some_x_program NAMES iceauth xrdb xterm) +if (NOT some_x_program) + set(some_x_program /usr/bin/xrdb) + message("Warning: Could not determine X binary directory. Assuming /usr/bin.") +endif (NOT some_x_program) +get_filename_component(proto_xbindir "${some_x_program}" PATH) +get_filename_component(XBINDIR "${proto_xbindir}" ABSOLUTE) +get_filename_component(xrootdir "${XBINDIR}" PATH) +set(XLIBDIR "${xrootdir}/lib/X11") + +check_function_exists(getpassphrase HAVE_GETPASSPHRASE) +check_function_exists(vsyslog HAVE_VSYSLOG) +check_function_exists(statvfs HAVE_STATVFS) + +check_include_files(limits.h HAVE_LIMITS_H) +check_include_files(sys/time.h HAVE_SYS_TIME_H) # ksmserver, ksplashml, sftp +check_include_files(stdint.h HAVE_STDINT_H) # kcontrol/kfontinst +check_include_files("sys/stat.h;sys/vfs.h" HAVE_SYS_VFS_H) # statvfs for plasma/solid +check_include_files("sys/stat.h;sys/statvfs.h" HAVE_SYS_STATVFS_H) # statvfs for plasma/solid +check_include_files(sys/param.h HAVE_SYS_PARAM_H) +check_include_files("sys/param.h;sys/mount.h" HAVE_SYS_MOUNT_H) +check_include_files("sys/types.h;sys/statfs.h" HAVE_SYS_STATFS_H) +check_include_files(unistd.h HAVE_UNISTD_H) +check_include_files(malloc.h HAVE_MALLOC_H) +check_function_exists(statfs HAVE_STATFS) +macro_bool_to_01(FONTCONFIG_FOUND HAVE_FONTCONFIG) # kcontrol/{fonts,kfontinst} +macro_bool_to_01(FREETYPE_FOUND HAVE_FREETYPE) # kcontrol/fonts +macro_bool_to_01(OPENGL_FOUND HAVE_OPENGL) # kwin +macro_bool_to_01(X11_XShm_FOUND HAVE_XSHM) # kwin, ksplash +macro_bool_to_01(X11_XTest_FOUND HAVE_XTEST) # khotkeys, kxkb, kdm +macro_bool_to_01(X11_Xcomposite_FOUND HAVE_XCOMPOSITE) # kicker, kwin +macro_bool_to_01(X11_Xcursor_FOUND HAVE_XCURSOR) # many uses +macro_bool_to_01(X11_Xdamage_FOUND HAVE_XDAMAGE) # kwin +macro_bool_to_01(X11_Xfixes_FOUND HAVE_XFIXES) # klipper, kicker, kwin +if(WITH_XINERAMA) + macro_bool_to_01(X11_Xinerama_FOUND HAVE_XINERAMA) +else(WITH_XINERAMA) + set(HAVE_XINERAMA 0) +endif(WITH_XINERAMA) +macro_bool_to_01(X11_Xrandr_FOUND HAVE_XRANDR) # kwin +macro_bool_to_01(X11_Xrender_FOUND HAVE_XRENDER) # kcontrol/style, kicker +macro_bool_to_01(X11_xf86misc_FOUND HAVE_XF86MISC) # kdesktop and kcontrol/lock +macro_bool_to_01(X11_dpms_FOUND HAVE_DPMS) # kdesktop +macro_bool_to_01(X11_XSync_FOUND HAVE_XSYNC) # kwin + +set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) +check_type_size("struct ucred" STRUCT_UCRED) # kio_fonts + +check_function_exists(getpeereid HAVE_GETPEEREID) # kdesu +check_function_exists(setpriority HAVE_SETPRIORITY) # kscreenlocker + +set(CMAKE_REQUIRED_INCLUDES ${X11_Xrandr_INCLUDE_PATH}/Xrandr.h) +set(CMAKE_REQUIRED_LIBRARIES ${X11_Xrandr_LIB}) +check_function_exists(XRRGetScreenSizeRange XRANDR_1_2_FOUND) +macro_bool_to_01(XRANDR_1_2_FOUND HAS_RANDR_1_2) +check_function_exists(XRRGetScreenResourcesCurrent XRANDR_1_3_FOUND) +macro_bool_to_01(XRANDR_1_3_FOUND HAS_RANDR_1_3) diff --git a/KDE4WorkspaceConfig.cmake.in b/KDE4WorkspaceConfig.cmake.in new file mode 100644 index 00000000..5f2e24e2 --- /dev/null +++ b/KDE4WorkspaceConfig.cmake.in @@ -0,0 +1,70 @@ +# KDE4WorkspaceConfig.cmake is generated by CMake from kdebase/workspace/KDE4WorkspaceConfig.cmake.in + +# Do we have a version number for kdebase/workspace ? Alex +set(KDE4WORKSPACE_VERSION_MAJOR @KDE4WORKSPACE_VERSION_MAJOR@) +set(KDE4WORKSPACE_VERSION_MINOR @KDE4WORKSPACE_VERSION_MINOR@) +set(KDE4WORKSPACE_VERSION_PATCH @KDE4WORKSPACE_VERSION_PATCH@) +set(KDE4WORKSPACE_VERSION "${KDE4WORKSPACE_VERSION_MAJOR}.${KDE4WORKSPACE_VERSION_MINOR}.${KDE4WORKSPACE_VERSION_PATCH}") + +# set the directories +if(NOT KDE4WORKSPACE_INSTALL_DIR) + set(KDE4WORKSPACE_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@") +endif(NOT KDE4WORKSPACE_INSTALL_DIR) + +set(KDE4WORKSPACE_LIB_DIR "@KDE4WORKSPACE_LIB_DIR@") +set(KDE4WORKSPACE_LIBEXEC_DIR "@KDE4WORKSPACE_LIBEXEC_DIR@") +set(KDE4WORKSPACE_INCLUDE_DIR "@KDE4WORKSPACE_INCLUDE_DIR@") +set(KDE4WORKSPACE_BIN_DIR "@KDE4WORKSPACE_BIN_DIR@") +set(KDE4WORKSPACE_SBIN_DIR "@KDE4WORKSPACE_SBIN_DIR@") +set(KDE4WORKSPACE_DATA_DIR "@KDE4WORKSPACE_DATA_DIR@") +set(KDE4WORKSPACE_HTML_DIR "@KDE4WORKSPACE_HTML_DIR@") +set(KDE4WORKSPACE_CONFIG_DIR "@KDE4WORKSPACE_CONFIG_DIR@") +set(KDE4WORKSPACE_ICON_DIR "@KDE4WORKSPACE_ICON_DIR@") +set(KDE4WORKSPACE_KCFG_DIR "@KDE4WORKSPACE_KCFG_DIR@") +set(KDE4WORKSPACE_LOCALE_DIR "@KDE4WORKSPACE_LOCALE_DIR@") +set(KDE4WORKSPACE_MIME_DIR "@KDE4WORKSPACE_MIME_DIR@") +set(KDE4WORKSPACE_SOUND_DIR "@KDE4WORKSPACE_SOUND_DIR@") +set(KDE4WORKSPACE_TEMPLATES_DIR "@KDE4WORKSPACE_TEMPLATES_DIR@") +set(KDE4WORKSPACE_WALLPAPER_DIR "@KDE4WORKSPACE_WALLPAPER_DIR@") +set(KDE4WORKSPACE_KCONF_UPDATE_DIR "@KDE4WORKSPACE_KCONF_UPDATE_DIR@") +set(KDE4WORKSPACE_AUTOSTART_DIR "@KDE4WORKSPACE_AUTOSTART_DIR@") +set(KDE4WORKSPACE_XDG_APPS_DIR "@KDE4WORKSPACE_XDG_APPS_DIR@") +set(KDE4WORKSPACE_XDG_DIRECTORY_DIR "@KDE4WORKSPACE_XDG_DIRECTORY_DIR@") +set(KDE4WORKSPACE_SYSCONF_DIR "@KDE4WORKSPACE_SYSCONF_DIR@") +set(KDE4WORKSPACE_MAN_DIR "@KDE4WORKSPACE_MAN_DIR@") +set(KDE4WORKSPACE_INFO_DIR "@KDE4WORKSPACE_INFO_DIR@") +set(KDE4WORKSPACE_DBUS_INTERFACES_DIR "@KDE4WORKSPACE_DBUS_INTERFACES_DIR@") +set(KDE4WORKSPACE_DBUS_SERVICES_DIR "@KDE4WORKSPACE_DBUS_SERVICES_DIR@") +set(KDE4WORKSPACE_SERVICES_DIR "@KDE4WORKSPACE_SERVICES_DIR@") +set(KDE4WORKSPACE_SERVICETYPES_DIR "@KDE4WORKSPACE_SERVICETYPES_DIR@") + +# the exports file exports +set(KDE4WORKSPACE_TARGET_PREFIX @KDE4WORKSPACE_TARGET_PREFIX@) + +# Make sure to load the exported targets only once +# For the rest of this script it doesn't matter that much +if(NOT TARGET @KDE4WORKSPACE_TARGET_PREFIX@plasmaclock) + get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH) + include("${_currentDir}/KDE4WorkspaceLibraryTargets.cmake") +endif(NOT TARGET @KDE4WORKSPACE_TARGET_PREFIX@plasmaclock) + +macro(_KDE4WORKSPACE_Set_Lib_Vars _prefix _lib) + set(KDE4WORKSPACE_${_prefix}_LIBRARY ${KDE4WORKSPACE_TARGET_PREFIX}${_lib}) + set(KDE4WORKSPACE_${_prefix}_LIBS ${KDE4WORKSPACE_TARGET_PREFIX}${_lib}) +endmacro(_KDE4WORKSPACE_Set_Lib_Vars) + + +_kde4workspace_set_lib_vars( TASKMANAGER taskmanager) +_kde4workspace_set_lib_vars( KWORKSPACE kworkspace) +_kde4workspace_set_lib_vars( PROCESSUI processui) +_kde4workspace_set_lib_vars( LSOFUI lsofui) +_kde4workspace_set_lib_vars( PLASMACLOCK plasmaclock) +_kde4workspace_set_lib_vars( NEPOMUKQUERYCLIENT nepomukqueryclient) +_kde4workspace_set_lib_vars( NEPOMUKQUERY nepomukquery) +_kde4workspace_set_lib_vars( KSCREENSAVER kscreensaver) +_kde4workspace_set_lib_vars( WEATHERION weather_ion) +_kde4workspace_set_lib_vars( KWINEFFECTS kwineffects) +_kde4workspace_set_lib_vars( KDECORATIONS kdecorations) +_kde4workspace_set_lib_vars( KSGRD ksgrd) +_kde4workspace_set_lib_vars( KEPHAL kephal) + diff --git a/Mainpage.dox b/Mainpage.dox new file mode 100644 index 00000000..332640ad --- /dev/null +++ b/Mainpage.dox @@ -0,0 +1,51 @@ +/** @mainpage The KDE Workspace + +This is where the components that are only used when KDE is providing +a complete desktop environment live. + +Of particular importance are KWin, the +KDE window manager, and Plasma, which +provides the workspace interface. + +If you are developing Plasma plugins (Plasmoids), you are probably interested +in the libplasma documentation. + +Other components that reside here are: +- KCheckPass, a simple program for checking whether a password is correct +- KCMInit, which allows KDE control modules to do initialization at the + start of a KDE session, for example setting the keyboard repeat rate +- KDM, the login manager for KDE +- KHotKeys, a daemon that allows actions to be performed when certain + combinations of keys are pressed +- Klipper, the KDE clipboard manager +- KMenuEdit, the manager for the desktop menu (the K menu) +- KRunner, which provides the launch ("run command") dialog, screensaver + activation and screen locking and control of application startup notification +- KScreenSaver, which provides pretty screensavers and is launched by + KRunner +- KSMServer, the KDE session manager +- KSplash, the KDE splashscreen program +- KStartupConfig, which allows configuration files to be used in startkde + without linking to KDE libraries +- KTip, that little window that pops up when you start KDE with the Tip of + the Day +- SystemSettings, the KDE configuration program +- Various Solid components useful in a + KDE session +- StartKDE, the script that starts a KDE session +- Some wallpapers, and a basic K menu setup + +@warning The applications and libraries in Workspace are only required to work +with X11. They will not be used on Windows or MacOS, or in other desktop +environments (such as GNOME). Applications should not depend on Workspace +unless they are a desktop component, such as a screensaver or a plasmoid. + + +@licenses +@gpl + + +*/ + +// DOXYGEN_SET_PROJECT_NAME = Workspace +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/README b/README new file mode 100644 index 00000000..fc6f1eae --- /dev/null +++ b/README @@ -0,0 +1 @@ +KDE Workspace consisting of what is the desktop. The applications and libraries included aren't required to be portable and probably will only work with X11. On other desktops such as OS X and Windows, users wouldn't run these applications, but use the native ones instead. The typical application shouldn't have dependencies in workspace unless they are a component such as a screen-saver or panel applet. diff --git a/README.pam b/README.pam new file mode 100644 index 00000000..2e302fe3 --- /dev/null +++ b/README.pam @@ -0,0 +1,72 @@ +KDE can be configured to support the PAM ("Pluggable Authentication +Modules") system for password checking by the display manager kdm and +by the screen saver kscreensaver (for unlocking the display). + +PAM is a flexible application-transparent configurable user-authentication +system found on FreeBSD, Solaris, and Linux (and maybe other unixes). + +Information about PAM may be found on its homepage + http://www.kernel.org/pub/linux/libs/pam/ +(Despite the location, this information is NOT Linux-specific.) + + +Known Solaris Issues: +-------------------- + +For compiling PAM support on Solaris, PAM_MESSAGE_CONST must NOT +be defined. This should now be handled automatically by the +configure script. + + +Using PAM +--------- + +By default, PAM is automatically used, if it is found. Use +./configure --without-pam to disable it. + +If PAM is found, KDE usually uses the PAM service "kde". You may +override it for all KDE programs by using --with-pam= and/or +individually by using --with--pam=, where is +one of kdm, kcp and kss (for kdm, kcheckpass and kscreensaver). + +"make install" will attempt to create suitable service definitions; either +by putting files into /etc/pam.d/ or by adding text to /etc/pam.conf. The +services are just copies of the "login" service. +You may want to edit these definitions to meet your needs. +There are also two example service definitions in this directory - +kde.pamd and kscreensaver.pamd - but don't just copy them! +If the services are misconfigured, you will NOT be able to login via KDM +and/or unlock a locked screen! + +If there is ever any doubt about which PAM service a program was +compiled with, it can be determined by examining the PAM-generated +entries in the system log associated with kdm logins or kscreensaver +authentication failures. + + +PAM configuration files have four types of entries for each service: + +type used by kdm used by kscreensaver +---- ----------- -------------------- +auth x x +account x +password x +session x + +There may be more than one entry of each type. Check existing PAM +configuration files and PAM documentation on your system for guidance as +to what entries to make. If you call a PAM service that is not +configured, the default action of PAM is likely to be denial of service. + +Note: kdm implements PAM "session" support, which is not implemented in +certain PAM-aware xdm's that it may be replacing (e.g., the Red Hat +Linux 5.x xdm did not implement it). This may be configured to carry out +actions when a user opens or closes an kdm session, if a suitable PAM +module is available (e.g., mount and unmount user-specific filesystems). + +Note 2: Screensavers typically only authenticate a user to allow her to +continue working. They may also renew tokens etc., where supported. +See the Linux PAM Administrators guide, which is part of the PAM +distribution, for more details. + + diff --git a/appmenu/CMakeLists.txt b/appmenu/CMakeLists.txt new file mode 100644 index 00000000..1b597c43 --- /dev/null +++ b/appmenu/CMakeLists.txt @@ -0,0 +1,37 @@ +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ) + +include_directories(${DBUSMENUQT_INCLUDE_DIR}) + +set(kded_appmenu_SRCS + appmenu.cpp + menuimporter.cpp + appmenu_dbus.cpp + menubutton.cpp + menuwidget.cpp + menubar.cpp + topmenubar.cpp + glowbar.cpp + verticalmenu.cpp + shadows.cpp + ) + +qt4_add_dbus_adaptor(kded_appmenu_SRCS com.canonical.AppMenu.Registrar.xml + menuimporter.h MenuImporter menuimporteradaptor MenuImporterAdaptor) + +qt4_add_dbus_adaptor(kded_appmenu_SRCS org.kde.kded.appmenu.xml + appmenu_dbus.h AppmenuDBus appmenuadaptor AppmenuAdaptor) + +kde4_add_plugin(kded_appmenu ${kded_appmenu_SRCS}) + +target_link_libraries(kded_appmenu ${KDE4_KIO_LIBS} ${X11_LIBRARIES} ${DBUSMENUQT_LIBRARIES} ${KDE4_PLASMA_LIBS}) + +install(TARGETS kded_appmenu DESTINATION ${PLUGIN_INSTALL_DIR} ) + +########### install files ############### + +install( FILES appmenu.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) +install( FILES com.canonical.AppMenu.Registrar.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR} ) +install( FILES org.kde.kded.appmenu.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR} ) diff --git a/appmenu/appmenu.cpp b/appmenu/appmenu.cpp new file mode 100644 index 00000000..4d2edd09 --- /dev/null +++ b/appmenu/appmenu.cpp @@ -0,0 +1,399 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "appmenu.h" +#include "kdbusimporter.h" +#include "menuimporteradaptor.h" +#include "appmenuadaptor.h" +#include "appmenu_dbus.h" +#include "topmenubar.h" +#include "verticalmenu.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +K_PLUGIN_FACTORY(AppMenuFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(AppMenuFactory("appmenu")) + +AppMenuModule::AppMenuModule(QObject* parent, const QList&) + : KDEDModule(parent), + m_parent(parent), + m_menuImporter(0), + m_appmenuDBus(new AppmenuDBus(parent)), + m_menubar(0), + m_menu(0), + m_screenTimer(new QTimer(this)), + m_waitingAction(0), + m_currentScreen(-1) +{ + reconfigure(); + + m_appmenuDBus->connectToBus(); + + m_currentScreen = currentScreen(); + + connect(m_appmenuDBus, SIGNAL(appShowMenu(int, int, WId)), SLOT(slotShowMenu(int, int, WId))); + connect(m_appmenuDBus, SIGNAL(moduleReconfigure()), SLOT(reconfigure())); + + // transfer our signals to dbus + connect(this, SIGNAL(showRequest(qulonglong)), m_appmenuDBus, SIGNAL(showRequest(qulonglong))); + connect(this, SIGNAL(menuAvailable(qulonglong)), m_appmenuDBus, SIGNAL(menuAvailable(qulonglong))); + connect(this, SIGNAL(clearMenus()), m_appmenuDBus, SIGNAL(clearMenus())); + connect(this, SIGNAL(menuHidden(qulonglong)), m_appmenuDBus, SIGNAL(menuHidden(qulonglong))); + connect(this, SIGNAL(WindowRegistered(qulonglong, const QString&, const QDBusObjectPath&)), + m_appmenuDBus, SIGNAL(WindowRegistered(qulonglong, const QString&, const QDBusObjectPath&))); + connect(this, SIGNAL(WindowUnregistered(qulonglong)), m_appmenuDBus, SIGNAL(WindowUnregistered(qulonglong))); +} + +AppMenuModule::~AppMenuModule() +{ + emit clearMenus(); + hideMenubar(); + if (m_menubar) { + delete m_menubar; + } + delete m_menuImporter; + delete m_appmenuDBus; +} + +void AppMenuModule::slotShowMenu(int x, int y, WId id) +{ + static KDBusMenuImporter *importer = 0; + + if (!m_menuImporter) { + return; + } + + // If menu visible, hide it + if (m_menu && m_menu->isVisible()) { + m_menu->hide(); + return; + } + + //dbus call by user (for khotkey shortcut) + if (x == -1 || y == -1) { + // We do not know kwin button position, so tell kwin to show menu + emit showRequest(KWindowSystem::self()->activeWindow()); + return; + } + + importer = getImporter(id); + + if (!importer) { + return; + } + + QMenu *menu = importer->menu(); + + // Window do not have menu + if (!menu) { + return; + } + + m_menu = new VerticalMenu(); + m_menu->setParentWid(id); + // Populate menu + foreach (QAction *action, menu->actions()) { + m_menu->addAction(action); + } + m_menu->popup(QPoint(x, y)); + // Activate waiting action if exist + if (m_waitingAction) { + m_menu->setActiveAction(m_waitingAction); + m_waitingAction = 0; + } + connect(m_menu, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); +} + +void AppMenuModule::slotAboutToHide() +{ + if (m_menu) { + emit menuHidden(m_menu->parentWid()); + m_menu->deleteLater(); + m_menu = 0; + } +} + +// New window registered +void AppMenuModule::slotWindowRegistered(WId id, const QString& service, const QDBusObjectPath& path) +{ + KDBusMenuImporter* importer = m_importers.take(id); + if (importer) { + delete importer; + } + + // Application already active so check if we need create menubar + if ( m_menuStyle == "TopMenuBar" && id == KWindowSystem::self()->activeWindow()) { + slotActiveWindowChanged(id); + } else if (m_menuStyle == "ButtonVertical") { + KWindowInfo info = KWindowSystem::windowInfo(id, 0, NET::WM2WindowClass); + // Tell Kwin menu is available + emit menuAvailable(id); + // FIXME: https://bugs.kde.org/show_bug.cgi?id=317926 + if (info.windowClassName() != "kmix") { + getImporter(id); + } + } + + // Send a signal on bus for others dbus interface registrars + emit WindowRegistered(id, service, path); +} + +// Window unregistered +void AppMenuModule::slotWindowUnregistered(WId id) +{ + KDBusMenuImporter* importer = m_importers.take(id); + + // Send a signal on bus for others dbus interface registrars + emit WindowUnregistered(id); + + if (importer) { + delete importer; + } + + if (m_menubar && m_menubar->parentWid() == id) { + hideMenubar(); + } +} + +// Keyboard activation requested, transmit it to menu +void AppMenuModule::slotActionActivationRequested(QAction* a) +{ + // If we have a topmenubar, activate action + if (m_menubar) { + m_menubar->setActiveAction(a); + m_menubar->show(); + } else { // else send request to kwin or others dbus interface registrars + m_waitingAction = a; + emit showRequest(KWindowSystem::self()->activeWindow()); + } +} + +// Current window change, update menubar +// See comments in slotWindowRegistered() for why we get importers here +void AppMenuModule::slotActiveWindowChanged(WId id) +{ + KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMWindowType); + unsigned long mask = NET::AllTypesMask; + + m_currentScreen = currentScreen(); + + if (id == 0) {// Ignore root window + return; + } else if (info.windowType(mask) & NET::Dock) { // Hide immediatly menubar for docks (krunner) + hideMenubar(); + return; + } + + if (!m_menuImporter->serviceExist(id)) { // No menu exist, check for another menu for application + WId recursiveId = m_menuImporter->recursiveMenuId(id); + if (recursiveId) { + id = recursiveId; + } + } + + KDBusMenuImporter *importer = getImporter(id); + if (!importer) { + hideMenubar(); + return; + } + + QMenu *menu = importer->menu(); + + if(menu) { + showMenuBar(menu); + m_menubar->setParentWid(id); + } else { + hideMenubar(); + } +} + +void AppMenuModule::slotShowCurrentWindowMenu() +{ + slotActiveWindowChanged(KWindowSystem::self()->activeWindow()); +} + +void AppMenuModule::slotCurrentScreenChanged() +{ + if (m_currentScreen != currentScreen()) { + if (m_menubar) { + m_menubar->setParentWid(0); + } + slotActiveWindowChanged(KWindowSystem::self()->activeWindow()); + } +} + +void AppMenuModule::slotBarNeedResize() +{ + if (m_menubar) { + m_menubar->updateSize(); + m_menubar->move(centeredMenubarPos()); + } +} + +// reload settings +void AppMenuModule::reconfigure() +{ + KConfig config( "kdeglobals", KConfig::FullConfig ); + KConfigGroup configGroup = config.group("Appmenu Style"); + m_menuStyle = configGroup.readEntry("Style", "InApplication"); + + m_waitingAction = 0; + + // hide menubar if exist + hideMenubar(); + if (m_menubar) { + delete m_menubar; + m_menubar = 0; + } + + slotAboutToHide(); // hide vertical menu if exist + + // Disconnect all options specifics signals + disconnect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(slotActiveWindowChanged(WId))); + disconnect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(slotShowCurrentWindowMenu())); + disconnect(m_screenTimer, SIGNAL(timeout()), this, SLOT(slotCurrentScreenChanged())); + + m_screenTimer->stop(); + + // Tell kwin to clean its titlebar + emit clearMenus(); + + if (m_menuStyle == "InApplication") { + if (m_menuImporter) { + delete m_menuImporter; + m_menuImporter = 0; + } + return; + } + + // Setup a menu importer if needed + if (!m_menuImporter) { + m_menuImporter = new MenuImporter(m_parent); + connect(m_menuImporter, SIGNAL(WindowRegistered(WId, const QString&, const QDBusObjectPath&)), + SLOT(slotWindowRegistered(WId, const QString&, const QDBusObjectPath&))); + connect(m_menuImporter, SIGNAL(WindowUnregistered(WId)), + SLOT(slotWindowUnregistered(WId))); + m_menuImporter->connectToBus(); + } + + if( m_menuStyle == "ButtonVertical" ) { + foreach(WId id, m_menuImporter->ids()) { + emit menuAvailable(id); + } + } + + // Setup top menubar if needed + if (m_menuStyle == "TopMenuBar") { + m_menubar = new TopMenuBar(); + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(slotActiveWindowChanged(WId))); + connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(slotShowCurrentWindowMenu())); + connect(m_screenTimer, SIGNAL(timeout()), this, SLOT(slotCurrentScreenChanged())); + connect(m_menubar, SIGNAL(needResize()), SLOT(slotBarNeedResize())); + m_screenTimer->start(1000); + slotShowCurrentWindowMenu(); + } +} + +KDBusMenuImporter* AppMenuModule::getImporter(WId id) +{ + KDBusMenuImporter* importer = 0; + if (m_importers.contains(id)) { // importer already exist + importer = m_importers.value(id); + } else if (m_menuImporter->serviceExist(id)) { // get importer + importer = new KDBusMenuImporter(id, m_menuImporter->serviceForWindow(id), &m_icons, + m_menuImporter->pathForWindow(id), this); + if (importer) { + QMetaObject::invokeMethod(importer, "updateMenu", Qt::DirectConnection); + connect(importer, SIGNAL(actionActivationRequested(QAction*)), + SLOT(slotActionActivationRequested(QAction*))); + m_importers.insert(id, importer); + } + } + return importer; +} + +void AppMenuModule::showMenuBar(QMenu *menu) +{ + if (!menu) { + return; + } + + m_menubar->setMenu(menu); + if (menu->actions().length()) { + m_menubar->enableMouseTracking(); + } +} + +void AppMenuModule::hideMenubar() +{ + if (!m_menubar) { + return; + } + + m_menubar->enableMouseTracking(false); + if (m_menubar->isVisible()) { + m_menubar->hide(); + } +} + +int AppMenuModule::currentScreen() +{ + KWindowInfo info = KWindowSystem::windowInfo(KWindowSystem::self()->activeWindow(), + NET::WMGeometry); + int x = info.geometry().x(); + int y = info.geometry().y(); + + QDesktopWidget *desktop = QApplication::desktop(); + return desktop->screenNumber(QPoint(x,y)); +} + + +QPoint AppMenuModule::centeredMenubarPos() +{ + QDesktopWidget *desktop = QApplication::desktop(); + m_currentScreen = currentScreen(); + QRect screen = desktop->availableGeometry(m_currentScreen); + int x = screen.center().x() - m_menubar->sizeHint().width()/2; + return QPoint(x, screen.topLeft().y()); +} + + +#include "appmenu.moc" diff --git a/appmenu/appmenu.desktop b/appmenu/appmenu.desktop new file mode 100644 index 00000000..242c5feb --- /dev/null +++ b/appmenu/appmenu.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Type=Service +Name=Application menus daemon +Name[bs]=Demon za aplikacijske menije +Name[ca]=Dimoni de menús d'aplicació +Name[ca@valencia]=Dimoni de menús d'aplicació +Name[cs]=Démon nabídky aplikací +Name[da]=Dæmon til programmenuer +Name[de]=Dienst für Anwendungsmenüs +Name[el]=Δαίμων για τα μενού των εφαρμογών +Name[en_GB]=Application menus daemon +Name[es]=Demonio de menús de aplicación +Name[et]=Rakenduste menüü deemon +Name[eu]=Aplikazio-menuen daimona +Name[fi]=Sovellusvalikkopalvelu +Name[fr]=Démon de menus des applications +Name[gl]=Daemon de menús do programa +Name[he]=תהליך רקע של תפריט היישומים +Name[hu]=Alkalmazás menük démon +Name[ia]=Demone de menus de application +Name[it]=Demone dei menu delle applicazioni +Name[kk]=Қолданба мәзірінің қызметі +Name[ko]=프로그램 메뉴 데몬 +Name[lt]=Programos meniu tarnyba +Name[mr]=अनुप्रयोग मेन्यू डीमन +Name[nb]=Daemon for programmenyer +Name[nds]=Programmmenü-Dämoon +Name[nl]=Daemon voor menu van toepassingen +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਮੈਨੂ ਡੈਮਨ +Name[pl]=Demon menu programów +Name[pt]=Servidor dos menus da aplicação +Name[pt_BR]=Servidor dos menus do aplicativo +Name[ro]=Demon pentru meniurile aplicațiilor +Name[ru]=Фоновая служба меню приложений +Name[sk]=Démon ponúk aplikácie +Name[sl]=Ozadnji program za programske menije +Name[sr]=Демон програмских менија +Name[sr@ijekavian]=Демон програмских менија +Name[sr@ijekavianlatin]=Demon programskih menija +Name[sr@latin]=Demon programskih menija +Name[sv]=Demon för programmenyer +Name[tr]=Uygulama menü araçları +Name[uk]=Фонова служба меню програм +Name[x-test]=xxApplication menus daemonxx +Name[zh_CN]=应用程序菜单守护程序 +Name[zh_TW]=應用程式選單伺服程式應用程式選單伺服程式 +Comment=Transfers application's menu to the desktop +Comment[bs]=Prebacuje aplikacijski meni na radnu površinu +Comment[ca]=Transfereix els menús d'aplicació a l'escriptori +Comment[ca@valencia]=Transfereix els menús d'aplicació a l'escriptori +Comment[cs]=Přesouvá nabídku aplikací na plochu +Comment[da]=Overfører programmets menu til skrivebordet +Comment[de]=Überträgt Anwendungsmenüs auf die Arbeitsfläche +Comment[el]=Μεταφέρει το μενού της εφαρμογής στην επιφάνεια εργασίας +Comment[en_GB]=Transfers application's menu to the desktop +Comment[es]=Transfiere el menú de aplicaciones al escritorio +Comment[et]=Rakenduste menüü paigutamine töölauale +Comment[eu]=Aplikazioen menua mahaigainera transferitzen du +Comment[fi]=Siirtää sovelluksen valikon työpöydälle +Comment[fr]=Transfère le menu des applications sur le bureau +Comment[gl]=Transfire o menú do programa ao escritorio +Comment[he]=מעביר את התפריטים של היישום אל שולחן העבודה +Comment[hu]=Átviszi az alkalmazás menüjét az asztalra +Comment[ia]=Il transfere menu de applicationes al scriptorio +Comment[it]=Trasferisce al desktop i menu delle applicazioni +Comment[kk]=Қолданбаның мәзірін үстел бетіне тапсыру +Comment[ko]=프로그램 메뉴를 데스크톱으로 보내기 +Comment[lt]=Perkelia programos meniu į darbastalį +Comment[mr]=अनुप्रयोग मेन्यूचे डेस्कटॉपवर स्थानान्तरण +Comment[nb]=Overfører programmets meny til skrivebordet +Comment[nds]=Dat Programmmenü na den Schriefdisch överdregen +Comment[nl]=Brengt het menu van de toepassing over naar het bureaublad +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ ਦੇ ਮੇਨੂ ਨੂੰ ਡੈਸਕਟਾਪ ਉੱਤੇ ਭੇਜੋ +Comment[pl]=Przenosi menu aplikacji na pulpit +Comment[pt]=Transfere o menu da aplicação para o ecrã +Comment[pt_BR]=Transfere o menu do aplicativo para a área de trabalho +Comment[ro]=Transferă meniul aplicațiilor către birou +Comment[ru]=Перемещает меню приложения на рабочий стол +Comment[sk]=Presunúť ponuky aplikácie na plochu +Comment[sl]=Prenese programski meni na namizje +Comment[sr]=Пребацује меније програма на површ +Comment[sr@ijekavian]=Пребацује меније програма на површ +Comment[sr@ijekavianlatin]=Prebacuje menije programa na površ +Comment[sr@latin]=Prebacuje menije programa na površ +Comment[sv]=Överför programmets meny till skrivbordet +Comment[tr]=Uygulamanın menüsünü masaüstüne aktarır +Comment[uk]=Передає меню програм на стільницю +Comment[x-test]=xxTransfers application's menu to the desktopxx +Comment[zh_CN]=将应用程序的菜单转移到桌面上 +Comment[zh_TW]=將應用程式選單傳送到桌面 +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=appmenu +X-KDE-DBus-ModuleName=appmenu +X-KDE-Kded-autoload=true +X-KDE-Kded-load-on-demand=false + diff --git a/appmenu/appmenu.h b/appmenu/appmenu.h new file mode 100644 index 00000000..b079d4cb --- /dev/null +++ b/appmenu/appmenu.h @@ -0,0 +1,154 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef APPMENUMODULE_H +#define APPMENUMODULE_H + +#include +#include "menuimporter.h" +#include "gtkicons.h" + +class QDBusPendingCallWatcher; +class KDBusMenuImporter; +class AppmenuDBus; +class TopMenuBar; +class VerticalMenu; + +class AppMenuModule : public KDEDModule, + protected QDBusContext +{ + Q_OBJECT +public: + AppMenuModule(QObject* parent, const QList& list); + virtual ~AppMenuModule(); + +Q_SIGNALS: + /** + * We do not know where is menu decoration button, so tell kwin to show menu + */ + void showRequest(qulonglong); + /** + * This signal is emitted whenever application menu becomes available + */ + void menuAvailable(qulonglong); + /** + * This signal is emitted whenever menus are unavailables + */ + void clearMenus(); + /** + * This signal is emitted whenever popup menu/menubar is hidden + * Useful for decorations to know if menu button should be release + */ + void menuHidden(qulonglong); + /** + * This signal is emitted whenever a window register to appmenu + */ + void WindowRegistered(qulonglong wid, const QString& service, const QDBusObjectPath&); + /** + * This signal is emitted whenever a window unregister from appmenu + */ + void WindowUnregistered(qulonglong wid); + +private Q_SLOTS: + /** + * Show menu at QPoint(x,y) for id + * if x or y == -1, show in application window + */ + void slotShowMenu(int x, int y, WId); + /** + * Send menuHidden signal over bus when menu is about to hide + */ + void slotAboutToHide(); + /** + * New window registered to appmenu + * Emit WindowRegistered signal over bus + */ + void slotWindowRegistered(WId id, const QString& service, const QDBusObjectPath& path); + /** + * Window unregistered from appmenu + * Emit WindowUnregistered signal over bus + */ + void slotWindowUnregistered(WId id); + /** + * Open a action in current menu + */ + void slotActionActivationRequested(QAction* a); + /** + * Active window changed, show menubar for id + */ + void slotActiveWindowChanged(WId id); + /** + * Update menubar with current window menu + */ + void slotShowCurrentWindowMenu(); + /** + * Current screen changed, update menubar + */ + void slotCurrentScreenChanged(); + /** + * Resize menubar + */ + void slotBarNeedResize(); + /** + * Reconfigure module + */ + void reconfigure(); + +private: + /** + * return an importer for window id + */ + KDBusMenuImporter* getImporter(WId id); + /** + * Show menubar and update it with menu + */ + void showMenuBar(QMenu *menu); + /** + * Hide menubar + */ + void hideMenubar(); + /** + * Return current screen + */ + int currentScreen(); + /** + * Return position of menubar for being centered on screen + */ + QPoint centeredMenubarPos(); + + QObject* m_parent; + MenuImporter* m_menuImporter; + AppmenuDBus* m_appmenuDBus; + QHash m_importers; + GtkIcons m_icons; + QString m_menuStyle; + TopMenuBar* m_menubar; + VerticalMenu* m_menu; + QTimer* m_screenTimer; + QAction *m_waitingAction; + int m_currentScreen; +}; + +#endif diff --git a/appmenu/appmenu_dbus.cpp b/appmenu/appmenu_dbus.cpp new file mode 100644 index 00000000..3b627323 --- /dev/null +++ b/appmenu/appmenu_dbus.cpp @@ -0,0 +1,69 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "appmenu_dbus.h" +#include "kdbusimporter.h" +#include "appmenuadaptor.h" + +#include +#include +#include +#include + +static const char* DBUS_SERVICE = "org.kde.kded"; +static const char* DBUS_OBJECT_PATH = "/modules/appmenu"; + +AppmenuDBus::AppmenuDBus(QObject* parent) +: QObject(parent) +{ +} + +AppmenuDBus::~AppmenuDBus() +{ +} + +bool AppmenuDBus::connectToBus(const QString& service, const QString& path) +{ + m_service = service.isEmpty() ? DBUS_SERVICE : service; + QString newPath = path.isEmpty() ? DBUS_OBJECT_PATH : path; + + if (!QDBusConnection::sessionBus().registerService(m_service)) { + return false; + } + new AppmenuAdaptor(this); + QDBusConnection::sessionBus().registerObject(newPath, this); + + return true; +} + +void AppmenuDBus::showMenu(int x, int y, WId id) +{ + emit appShowMenu(x, y, id); +} + +void AppmenuDBus::reconfigure() +{ + emit moduleReconfigure(); +} \ No newline at end of file diff --git a/appmenu/appmenu_dbus.h b/appmenu/appmenu_dbus.h new file mode 100644 index 00000000..2d5bb7e3 --- /dev/null +++ b/appmenu/appmenu_dbus.h @@ -0,0 +1,100 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef APPMENU_DBUS_H +#define APPMENU_DBUS_H + +// Qt +#include +#include +#include +#include +#include + +class KDBusMenuImporter; + +class AppmenuDBus : public QObject, protected QDBusContext +{ + Q_OBJECT + +public: + AppmenuDBus(QObject*); + ~AppmenuDBus(); + + bool connectToBus(const QString& service = QString(), const QString& path = QString()); + + /** + * DBus method showing menu at QPoint(x,y) for id + * if x or y == -1, show in application window + */ + void showMenu(int x, int y, WId id); + /** + * DBus method reconfiguring kded module + */ + void reconfigure(); + +Q_SIGNALS: + /** + * This signal is emitted on showMenu() request + */ + void appShowMenu(int x, int y, WId id); + /** + * This signal is emitted on reconfigure() request + */ + void moduleReconfigure(); + + // Dbus signals + /** + * This signal is emitted whenever kded want to show menu + * We do not know where is menu decoration button, so tell kwin to show menu + */ + void showRequest(qulonglong); + /** + * This signal is emitted whenever application menu becomes available + */ + void menuAvailable(qulonglong); + /** + * This signal is emitted whenever menus are unavailables + */ + void clearMenus(); + /** + * This signal is emitted whenever popup menu/menubar is hidden + * Useful for decorations to know if menu button should be release + */ + void menuHidden(qulonglong); + /** + * This signal is emitted whenever a window register to appmenu + */ + void WindowRegistered(qulonglong wid, const QString& service, const QDBusObjectPath&); + /** + * This signal is emitted whenever a window unregister from appmenu + */ + void WindowUnregistered(qulonglong wid); + +private: + QString m_service; +}; + +#endif // APPMENU_DBUS_H diff --git a/appmenu/com.canonical.AppMenu.Registrar.xml b/appmenu/com.canonical.AppMenu.Registrar.xml new file mode 100644 index 00000000..bc2be43c --- /dev/null +++ b/appmenu/com.canonical.AppMenu.Registrar.xml @@ -0,0 +1,56 @@ + + + + + + An interface to register a menu from an application's window to be displayed in another + window.  This manages that association between XWindow Window IDs and the dbus + address and object that provides the menu using the dbusmenu dbus interface. + + + + + The XWindow ID of the window + + + The object on the dbus interface implementing the dbusmenu interface + + + + + A method to allow removing a window from the database. Windows will also be removed + when the client drops off DBus so this is not required. It is polite though. And + important for testing. + + + The XWindow ID of the window + + + + Gets the registered menu for a given window ID. + + The XWindow ID of the window to get + + + The address of the connection on DBus (e.g. :1.23 or org.example.service) + + + The path to the object which implements the com.canonical.dbusmenu interface. + + + + diff --git a/appmenu/glowbar.cpp b/appmenu/glowbar.cpp new file mode 100644 index 00000000..680c8cda --- /dev/null +++ b/appmenu/glowbar.cpp @@ -0,0 +1,109 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "glowbar.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +GlowBar::GlowBar() + : QWidget(0), + m_svg(new Plasma::Svg(this)) +{ + m_svg->setImagePath("widgets/glowbar"); + + setWindowFlags(Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint); + setAttribute(Qt::WA_TranslucentBackground); + setAutoFillBackground(false); + KWindowSystem::setType(winId(), NET::Dock); + + QPalette pal = palette(); + pal.setColor(backgroundRole(), Qt::transparent); + setPalette(pal); + + setInputMask(); +} + +GlowBar::~GlowBar() +{ +} + +void GlowBar::paintEvent(QPaintEvent*) +{ + QPixmap l, r, c; + QPoint pixmapPosition(0, 0); + + m_buffer.fill(QColor(0, 0, 0, int(qreal(255)*0.3))); + QPainter p(&m_buffer); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + l = m_svg->pixmap("bottomleft"); + r = m_svg->pixmap("bottomright"); + c = m_svg->pixmap("bottom"); + p.drawPixmap(pixmapPosition, l); + p.drawTiledPixmap(QRect(l.width(), pixmapPosition.y(), width() - l.width() - r.width(), c.height()), c); + p.drawPixmap(QPoint(width() - r.width(), pixmapPosition.y()), r); + p.end(); + p.begin(this); + p.drawPixmap(QPoint(0, 0), m_buffer); +} + +void GlowBar::setPixmap(const QPoint pos, uint width) +{ + QRect zone = QRect(pos, QSize(width, 10)); + setGeometry(zone); + m_buffer = QPixmap(zone.size()); +} + +void GlowBar::setInputMask() +{ + // Create an empty input mask to achieve click-through effect + // Thanks to MacSlow for this! + Pixmap mask; + + mask = XCreatePixmap(QX11Info::display(), + winId(), + 1, /* width */ + 1, /* height */ + 1 /* depth */); + XShapeCombineMask(QX11Info::display(), + winId(), + ShapeInput, + 0, /* x-offset */ + 0, /* y-offset */ + mask, + ShapeSet); + XFreePixmap(QX11Info::display(), mask); +} +#include "glowbar.moc" diff --git a/appmenu/glowbar.h b/appmenu/glowbar.h new file mode 100644 index 00000000..2d86fc47 --- /dev/null +++ b/appmenu/glowbar.h @@ -0,0 +1,51 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef GLOWBAR__H +#define GLOWBAR__H + +#include + +namespace Plasma +{ + class Svg; +} + +class GlowBar : public QWidget +{ +Q_OBJECT +public: + GlowBar(); + ~GlowBar(); + + void paintEvent(QPaintEvent*); + + void setPixmap(const QPoint pos, uint width); +private: + void setInputMask(); + Plasma::Svg *m_svg; + QPixmap m_buffer; +}; +#endif \ No newline at end of file diff --git a/appmenu/gtkicons.h b/appmenu/gtkicons.h new file mode 100644 index 00000000..d11d73de --- /dev/null +++ b/appmenu/gtkicons.h @@ -0,0 +1,146 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef GTKICONS_H +#define GTKICONS_H + +#include + +class GtkIcons : public QMap +{ + public: + GtkIcons( void ) : QMap () + { + insert(QString("gnome-fs-directory"), QString("folder.png")); + insert(QString("gnome-fs-regular.png"), QString("application-x-zerosize.png")); + insert(QString("gtk-about"), QString("help-about.png")); + insert(QString("gtk-add"), QString("list-add.png")); + insert(QString("gtk-apply"), QString("dialog-ok-apply.png ok-apply.png apply.png")); + insert(QString("gtk-bold"), QString("format-text-bold.png")); + insert(QString("gtk-cancel"), QString("dialog-cancel.png cancel.png")); + insert(QString("gtk-cdrom"), QString("media-optical.png")); + insert(QString("gtk-clear"), QString("edit-clear.png")); + insert(QString("gtk-close"), QString("window-close.png")); + insert(QString("gtk-color-picker"), QString("color-picker.png")); + insert(QString("gtk-connect"), QString("network-connect.png")); + insert(QString("gtk-convert"), QString("document-export.png")); + insert(QString("gtk-copy"), QString("edit-copy.png")); + insert(QString("gtk-cut"), QString("edit-cut.png")); + insert(QString("gtk-delete"), QString("edit-delete.png")); + insert(QString("gtk-dialog-authentication"), QString("dialog-password.png document-encrypt.png object-locked.png")); + insert(QString("gtk-dialog-error"), QString("dialog-error.png")); + insert(QString("gtk-dialog-info"), QString("dialog-information.png")); + insert(QString("gtk-dialog-question"), QString("dialog-information.png")); + insert(QString("gtk-dialog-warning"), QString("dialog-warning.png")); + insert(QString("gtk-directory"), QString("folder.png")); + insert(QString("gtk-disconnect"), QString("network-disconnect.png")); + insert(QString("gtk-dnd"), QString("application-x-zerosize.png")); + insert(QString("gtk-dnd-multiple"), QString("document-multiple.png")); + insert(QString("gtk-edit"), QString("document-properties.png")); + insert(QString("gtk-execute"), QString("fork.png")); + insert(QString("gtk-file"), QString("application-x-zerosize.png")); + insert(QString("gtk-find"), QString("edit-find.png")); + insert(QString("gtk-find-and-replace"), QString("edit-find-replace.png")); + insert(QString("gtk-floppy"), QString("media-floppy.png")); + insert(QString("gtk-fullscreen"), QString("view-fullscreen.png")); + insert(QString("gtk-goto-bottom"), QString("go-bottom.png")); + insert(QString("gtk-goto-first"), QString("go-first.png")); + insert(QString("gtk-goto-last"), QString("go-last.png")); + insert(QString("gtk-goto-top"), QString("go-top.png")); + insert(QString("gtk-go-back"), QString("go-previous.png")); + insert(QString("gtk-go-back-ltr"), QString("go-previous.png")); + insert(QString("gtk-go-back-rtl"), QString("go-next.png")); + insert(QString("gtk-go-down"), QString("go-down.png")); + insert(QString("gtk-go-forward"), QString("go-next.png")); + insert(QString("gtk-go-forward-ltr"), QString("go-next.png")); + insert(QString("gtk-go-forward-rtl"), QString("go-previous.png")); + insert(QString("gtk-go-up"), QString("go-up.png")); + insert(QString("gtk-harddisk"), QString("drive-harddisk.png")); + insert(QString("gtk-help"), QString("help-contents.png")); + insert(QString("gtk-home"), QString("go-home.png")); + insert(QString("gtk-indent"), QString("format-indent-more.png")); + insert(QString("gtk-index"), QString("help-contents.png")); + insert(QString("gtk-info"), QString("help-about.png")); + insert(QString("gtk-italic"), QString("format-text-italic.png")); + insert(QString("gtk-jump-to"), QString("go-jump.png")); + insert(QString("gtk-justify-center"), QString("format-justify-center.png")); + insert(QString("gtk-justify-fill"), QString("format-justify-fill.png")); + insert(QString("gtk-justify-left"), QString("format-justify-left.png")); + insert(QString("gtk-justify-right"), QString("format-justify-right.png")); + insert(QString("gtk-leave-fullscreen"), QString("view-restore.png")); + insert(QString("gtk-media-forward"), QString("media-seek-forward.png")); + insert(QString("gtk-media-next"), QString("media-skip-forward.png")); + insert(QString("gtk-media-pause"), QString("media-playback-pause.png")); + insert(QString("gtk-media-play"), QString("media-playback-start.png")); + insert(QString("gtk-media-previous"), QString("media-skip-backward.png")); + insert(QString("gtk-media-record"), QString("media-record.png")); + insert(QString("gtk-media-rewind"), QString("media-seek-backward.png")); + insert(QString("gtk-media-stop"), QString("media-playback-stop.png")); + insert(QString("gtk-missing-image"), QString("unknown.png")); + insert(QString("gtk-network"), QString("network-server.png")); + insert(QString("gtk-new"), QString("document-new.png")); + insert(QString("gtk-no"), QString("edit-delete.png")); + insert(QString("gtk-ok"), QString("dialog-ok.png ok.png")); + insert(QString("gtk-open"), QString("document-open.png")); + insert(QString("gtk-paste"), QString("edit-paste.png")); + insert(QString("gtk-preferences"), QString("configure.png")); + insert(QString("gtk-print"), QString("document-print.png")); + insert(QString("gtk-print-preview"), QString("document-print-preview.png")); + insert(QString("gtk-properties"), QString("document-properties.png")); + insert(QString("gtk-quit"), QString("application-exit.png")); + insert(QString("gtk-redo"), QString("edit-redo.png")); + insert(QString("gtk-refresh"), QString("view-refresh.png")); + insert(QString("gtk-remove"), QString("edit-delete.png")); + insert(QString("gtk-revert-to-saved"), QString("document-revert.png")); + insert(QString("gtk-save"), QString("document-save.png")); + insert(QString("gtk-save-as"), QString("document-save-as.png")); + insert(QString("gtk-select-all"), QString("edit-select-all.png")); + insert(QString("gtk-select-color"), QString("color-picker.png")); + insert(QString("gtk-select-font"), QString("preferences-desktop-font.png")); + insert(QString("gtk-sort-ascending"), QString("view-sort-ascending.png")); + insert(QString("gtk-sort-descending"), QString("view-sort-descending.png")); + insert(QString("gtk-spell-check"), QString("tools-check-spelling.png")); + insert(QString("gtk-stop"), QString("process-stop.png")); + insert(QString("gtk-strikethrough"), QString("format-text-strikethrough.png")); + insert(QString("gtk-undelete"), QString("edit-undo.png")); + insert(QString("gtk-underline"), QString("format-text-underline.png")); + insert(QString("gtk-undo"), QString("edit-undo.png")); + insert(QString("gtk-unindent"), QString("format-indent-less.png")); + insert(QString("gtk-yes"), QString("dialog-ok.png ok.png")); + insert(QString("gtk-zoom-100"), QString("zoom-original.png")); + insert(QString("gtk-zoom-fit"), QString("zoom-fit-best.png")); + insert(QString("gtk-zoom-in"), QString("zoom-in.png")); + insert(QString("gtk-zoom-out"), QString("zoom-out.png")); + insert(QString("stock_edit-bookmark"), QString("bookmarks-organize.png")); + insert(QString("gimp-edit"), QString("edit.png")); + insert(QString("gimp-info"), QString("dialog-information.png")); + insert(QString("gimp-reset"), QString("reload.png")); + insert(QString("gimp-warning"), QString("dialog-warning.png")); + insert(QString("gimp-tool-options"), QString("tool.png")); + insert(QString("gimp-images"), QString("image.png")); + } +}; + +#endif // GTKICONS_H \ No newline at end of file diff --git a/appmenu/kdbusimporter.h b/appmenu/kdbusimporter.h new file mode 100644 index 00000000..986783b7 --- /dev/null +++ b/appmenu/kdbusimporter.h @@ -0,0 +1,75 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KDBUSMENUIMPORTER_H +#define KDBUSMENUIMPORTER_H + +#include "gtkicons.h" + +#include +#include + +#include + +#include + +class KDBusMenuImporter : public DBusMenuImporter +{ + +public: + KDBusMenuImporter(WId wid, const QString &service, GtkIcons *icons, const QString &path, QObject *parent) + : DBusMenuImporter(service, path, parent) + , m_service(service) + , m_path(path) + , m_WId(wid) + { + m_icons = icons; + } + + QString service() const { return m_service; } + QString path() const { return m_path; } + WId wid() const { return m_WId; } + +protected: + virtual QIcon iconForName(const QString &name) + { + KIcon icon; + if(m_icons->contains(name)){ + icon = KIcon(m_icons->value(name)); + } + else if(!KIconLoader::global()->iconPath(name, 1, true ).isNull()){ + icon = KIcon(name); + } + return icon; + } + +private: + GtkIcons *m_icons; + QString m_service; + QString m_path; + WId m_WId; +}; + +#endif //KDBUSMENUIMPORTER_H \ No newline at end of file diff --git a/appmenu/menubar.cpp b/appmenu/menubar.cpp new file mode 100644 index 00000000..4c20e201 --- /dev/null +++ b/appmenu/menubar.cpp @@ -0,0 +1,166 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "menubar.h" +#include "shadows.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +MenuBar::MenuBar() + : QGraphicsView(), + m_hideTimer(new QTimer(this)), + m_background(new Plasma::FrameSvg(this)), + m_shadows(new Shadows(this)), + m_scene(new QGraphicsScene(this)), + m_container(new MenuWidget(this)) +{ + qreal left, top, right, bottom; + + //Setup the window properties + setWindowFlags(Qt::Tool|Qt::X11BypassWindowManagerHint|Qt::WindowStaysOnTopHint); + setAttribute(Qt::WA_TranslucentBackground); + KWindowSystem::setType(winId(), NET::Dock); + setFrameStyle(QFrame::NoFrame); + viewport()->setAutoFillBackground(false); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + //Setup the widgets + m_background->setImagePath("widgets/tooltip"); + m_background->setEnabledBorders(Plasma::FrameSvg::BottomBorder|Plasma::FrameSvg::LeftBorder|Plasma::FrameSvg::RightBorder); + + m_container->initLayout(); + + m_scene->addItem(m_container); + + setScene(m_scene); + + m_background->getMargins(left, top, right, bottom); + m_container->layout()->setContentsMargins(left, top, right, bottom); + + resize(sizeHint()); + + connect(m_container, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); + connect(m_container, SIGNAL(needResize()), this, SIGNAL(needResize())); + connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(slotAboutToHide())); + + connect(KWindowSystem::self(), SIGNAL(compositingChanged(bool)), this, SLOT(slotCompositingChanged(bool))); +} + +MenuBar::~MenuBar() +{ +} + +QSize MenuBar::sizeHint() const +{ + QSizeF size = m_container->minimumSize(); + return QSize(size.width(), size.height() - m_container->contentBottomMargin()); +} + +void MenuBar::show() +{ + // Add shadow for better readability + if (! Plasma::WindowEffects::isEffectAvailable(Plasma::WindowEffects::BlurBehind)) { + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(); + shadow->setBlurRadius(5); + shadow->setOffset(QPointF(1, 1)); + shadow->setColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); + setGraphicsEffect(shadow); + } else { + setGraphicsEffect(0); + } + m_hideTimer->start(1000); + QGraphicsView::show(); + +} + +void MenuBar::hide() +{ + emit aboutToHide(); + m_hideTimer->stop(); + QGraphicsView::hide(); +} + +void MenuBar::slotAboutToHide() +{ + if (m_container->aMenuIsVisible()) { // MenuBar::m_hideTimer + m_hideTimer->stop(); // menu is visible, menubar will be hidden by another aboutToHide() signal + } + else if (!cursorInMenuBar()) { //MenuWidget::AboutToHide signal + hide(); + } else if (!m_hideTimer->isActive()){ //use click on menubar button while a popup was shown + m_hideTimer->start(1000); + } +} + +void MenuBar::slotCompositingChanged(bool) +{ + updateMask(); +} + +bool MenuBar::cursorInMenuBar() +{ + return QRect(pos(), size()).contains(QCursor::pos()); +} + +void MenuBar::drawBackground(QPainter *painter, const QRectF &/*rectF*/) +{ + painter->save(); + painter->setCompositionMode(QPainter::CompositionMode_Source); + m_background->paintFrame(painter); + painter->restore(); +} + +void MenuBar::resizeEvent(QResizeEvent*) +{ + m_background->resizeFrame(size()); + m_scene->setSceneRect(0, 0, width(), height()); + updateMask(); +} + +void MenuBar::updateMask() +{ + // Enable the mask only when compositing is disabled; + // As this operation is quite slow, it would be nice to find some + // way to workaround it for no-compositing users. + if (KWindowSystem::compositingActive()) { + clearMask(); + Plasma::WindowEffects::overrideShadow(winId(), true); + Plasma::WindowEffects::enableBlurBehind(winId(), true, m_background->mask()); + m_shadows->addWindow(this, Plasma::FrameSvg::BottomBorder|Plasma::FrameSvg::LeftBorder|Plasma::FrameSvg::RightBorder); + } else { + setMask(m_background->mask()); + } +} \ No newline at end of file diff --git a/appmenu/menubar.h b/appmenu/menubar.h new file mode 100644 index 00000000..69ca1ebe --- /dev/null +++ b/appmenu/menubar.h @@ -0,0 +1,87 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MENUBAR__H +#define MENUBAR__H + +#include "menuwidget.h" + +#include + +class QMenu; +class Shadows; + +namespace Plasma +{ + class FrameSvg; +} + +class MenuBar : public QGraphicsView +{ +Q_OBJECT +public: + MenuBar(); + ~MenuBar(); + + /** + * Set root menu + */ + void setMenu(QMenu *menu) { m_container->setMenu(menu); } + /** + * Auto open menu items on mouse over + */ + void autoOpen() { m_container->autoOpen(); } + /** + * Set action as active menubar action + */ + void setActiveAction(QAction *action) { m_container->setActiveAction(action); } + + virtual QSize sizeHint() const; + virtual void show(); + virtual void hide(); + +private Q_SLOTS: + void slotAboutToHide(); + void slotCompositingChanged(bool); +Q_SIGNALS: + void needResize(); + void aboutToHide(); +protected: + /** + * Return true if cursor in menubar + */ + virtual bool cursorInMenuBar(); + virtual void drawBackground(QPainter* painter, const QRectF &rectF); + virtual void resizeEvent(QResizeEvent* event); +private: + void updateMask(); + QTimer* m_hideTimer; + Plasma::FrameSvg* m_background; + Shadows *m_shadows; + QGraphicsScene* m_scene; + MenuWidget* m_container; +}; + +#endif diff --git a/appmenu/menubutton.cpp b/appmenu/menubutton.cpp new file mode 100644 index 00000000..10c143a3 --- /dev/null +++ b/appmenu/menubutton.cpp @@ -0,0 +1,85 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "menubutton.h" + +#include +#include +#include + +#include + +MenuButton::MenuButton(QGraphicsWidget *parent): + Plasma::ToolButton(parent), + m_enterEvent(false), + m_menu(0) +{ + QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(); + shadow->setBlurRadius(5); + shadow->setOffset(QPointF(1, 1)); + shadow->setColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); + setGraphicsEffect(shadow); +} + +void MenuButton::setHovered(bool hovered) +{ + if (hovered) { + hoverEnterEvent(0); + } else { + hoverLeaveEvent(0); + } +} + +QSizeF MenuButton::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const +{ + QSizeF sh = Plasma::ToolButton::sizeHint(which, constraint); + if (which == Qt::MinimumSize || which == Qt::PreferredSize) { + sh.setHeight(nativeWidget()->fontMetrics().height() + bottomMargin()); + } + return sh; +} + +qreal MenuButton::bottomMargin() const +{ + qreal left, right, top, bottom; + getContentsMargins(&left, &right, &top, &bottom); + return bottom; +} + +void MenuButton::hoverEnterEvent(QGraphicsSceneHoverEvent *e) +{ + m_enterEvent = true; + Plasma::ToolButton::hoverEnterEvent(e); +} + +void MenuButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) +{ + if (m_enterEvent) { + m_enterEvent = false; + Plasma::ToolButton::hoverLeaveEvent(e); + } +} + +#include "menubutton.moc" \ No newline at end of file diff --git a/appmenu/menubutton.h b/appmenu/menubutton.h new file mode 100644 index 00000000..a7702dcf --- /dev/null +++ b/appmenu/menubutton.h @@ -0,0 +1,54 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MENUBUTTON__H +#define MENUBUTTON__H + +#include +#include + +class QMenu; + +class MenuButton : public Plasma::ToolButton +{ +Q_OBJECT +public: + MenuButton(QGraphicsWidget *parent); + + void setHovered(bool hovered); + + QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const; + qreal bottomMargin() const; + + void setMenu(QMenu *menu) { m_menu = menu; } + QMenu* menu() { return m_menu; } +protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent *); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *); +private: + bool m_enterEvent; + QMenu *m_menu; +}; +#endif diff --git a/appmenu/menuimporter.cpp b/appmenu/menuimporter.cpp new file mode 100644 index 00000000..b55b7d3b --- /dev/null +++ b/appmenu/menuimporter.cpp @@ -0,0 +1,224 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "menuimporter.h" +#include "menuimporteradaptor.h" + +#include +#include +#include +#include + +#include +#include +#include + +static const char* DBUS_SERVICE = "com.canonical.AppMenu.Registrar"; +static const char* DBUS_OBJECT_PATH = "/com/canonical/AppMenu/Registrar"; + +// Marshalling code for DBusMenuLayoutItem +QDBusArgument &operator<<(QDBusArgument &argument, const DBusMenuLayoutItem &obj) +{ + argument.beginStructure(); + argument << obj.id << obj.properties; + argument.beginArray(qMetaTypeId()); + Q_FOREACH(const DBusMenuLayoutItem& child, obj.children) { + argument << QDBusVariant(QVariant::fromValue(child)); + } + argument.endArray(); + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, DBusMenuLayoutItem &obj) +{ + argument.beginStructure(); + argument >> obj.id >> obj.properties; + argument.beginArray(); + while (!argument.atEnd()) { + QDBusVariant dbusVariant; + argument >> dbusVariant; + QDBusArgument childArgument = dbusVariant.variant().value(); + + DBusMenuLayoutItem child; + childArgument >> child; + obj.children.append(child); + } + argument.endArray(); + argument.endStructure(); + return argument; +} + +MenuImporter::MenuImporter(QObject* parent) +: QObject(parent) +, m_serviceWatcher(new QDBusServiceWatcher(this)) +{ + qDBusRegisterMetaType(); + m_serviceWatcher->setConnection(QDBusConnection::sessionBus()); + m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + connect(m_serviceWatcher, SIGNAL(serviceUnregistered(const QString&)), SLOT(slotServiceUnregistered(const QString&))); + + QDBusConnection::sessionBus().connect("", "", "com.canonical.dbusmenu", "LayoutUpdated", + this, SLOT(slotLayoutUpdated(uint,int))); +} + +MenuImporter::~MenuImporter() +{ + QDBusConnection::sessionBus().unregisterService(DBUS_SERVICE); + QDBusConnection::sessionBus().disconnect("", "", "com.canonical.dbusmenu", "LayoutUpdated", + this, SLOT(slotLayoutUpdated(uint,int))); +} + +bool MenuImporter::connectToBus() +{ + if (!QDBusConnection::sessionBus().registerService(DBUS_SERVICE)) { + return false; + } + new MenuImporterAdaptor(this); + QDBusConnection::sessionBus().registerObject(DBUS_OBJECT_PATH, this); + + return true; +} + +WId MenuImporter::recursiveMenuId(WId id) +{ + KWindowInfo info = KWindowSystem::windowInfo(id, 0, NET::WM2WindowClass); + QString classClass = info.windowClassClass(); + WId classId = 0; + + // First look at transient windows + WId tid = KWindowSystem::transientFor(id); + while (tid) { + if (serviceExist(tid)) { + classId = tid; + break; + } + tid = KWindowSystem::transientFor(tid); + } + + if (classId == 0) { + // Look at friends windows + QHashIterator i(m_windowClasses); + while (i.hasNext()) { + i.next(); + if (i.value() == classClass) { + classId = i.key(); + } + } + } + + return classId; +} + +void MenuImporter::RegisterWindow(WId id, const QDBusObjectPath& path) +{ + KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMWindowType); + unsigned long mask = NET::AllTypesMask; + + // Menu can try to register, right click in gimp for exemple + if (info.windowType(mask) & (NET::Menu|NET::DropdownMenu||NET::PopupMenu)) { + return; + } + + if (path.path().isEmpty()) //prevent bad dbusmenu usage + return; + + QString service = message().service(); + + info = KWindowSystem::windowInfo(id, 0, NET::WM2WindowClass); + QString classClass = info.windowClassClass(); + m_windowClasses.insert(id, classClass); + m_menuServices.insert(id, service); + m_menuPaths.insert(id, path); + if (! m_serviceWatcher->watchedServices().contains(service)) { + m_serviceWatcher->addWatchedService(service); + } + emit WindowRegistered(id, service, path); +} + +void MenuImporter::UnregisterWindow(WId id) +{ + m_menuServices.remove(id); + m_menuPaths.remove(id); + m_windowClasses.remove(id); + + emit WindowUnregistered(id); +} + +QString MenuImporter::GetMenuForWindow(WId id, QDBusObjectPath& path) +{ + path = m_menuPaths.value(id); + return m_menuServices.value(id); +} + +void MenuImporter::slotServiceUnregistered(const QString& service) +{ + WId id = m_menuServices.key(service); + m_menuServices.remove(id); + m_menuPaths.remove(id); + m_windowClasses.remove(id); + emit WindowUnregistered(id); + m_serviceWatcher->removeWatchedService(service); +} + +void MenuImporter::slotLayoutUpdated(uint /*revision*/, int parentId) +{ + // Fake unity-panel-service weird behavior of calling aboutToShow on + // startup. This is necessary for Firefox menubar to work correctly at + // startup. + // See: https://bugs.launchpad.net/plasma-idget-menubar/+bug/878165 + + if (parentId == 0) { //root menu + fakeUnityAboutToShow(); + } +} + +void MenuImporter::fakeUnityAboutToShow() +{ + QDBusInterface iface(message().service(), message().path(), "com.canonical.dbusmenu"); + QDBusPendingCall call = iface.asyncCall("GetLayout", 0, 1, QStringList()); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(call, this); + watcher->setProperty("service", message().service()); + watcher->setProperty("path", message().path()); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(finishFakeUnityAboutToShow(QDBusPendingCallWatcher*))); +} + +void MenuImporter::finishFakeUnityAboutToShow(QDBusPendingCallWatcher* watcher) +{ + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + kWarning() << "Call to GetLayout failed:" << reply.error().message(); + return; + } + QString service = watcher->property("service").toString(); + QString path = watcher->property("path").toString(); + DBusMenuLayoutItem root = reply.argumentAt<1>(); + + QDBusInterface iface(service, path, "com.canonical.dbusmenu"); + Q_FOREACH(const DBusMenuLayoutItem& dbusMenuItem, root.children) { + iface.asyncCall("AboutToShow", dbusMenuItem.id); + } +} diff --git a/appmenu/menuimporter.h b/appmenu/menuimporter.h new file mode 100644 index 00000000..adfc5422 --- /dev/null +++ b/appmenu/menuimporter.h @@ -0,0 +1,98 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MENUIMPORTER_H +#define MENUIMPORTER_H + +// Qt +#include +#include +#include +#include // For WId + +class QDBusObjectPath; +class QDBusPendingCallWatcher; +class QDBusServiceWatcher; +class QMenu; + +/** + * Represents an item with its children. GetLayout() returns a + * DBusMenuLayoutItemList. + */ +struct DBusMenuLayoutItem +{ + int id; + QVariantMap properties; + QList children; +}; +Q_DECLARE_METATYPE(DBusMenuLayoutItem) + +class MenuImporter : public QObject, protected QDBusContext +{ + Q_OBJECT + +public: + MenuImporter(QObject*); + ~MenuImporter(); + + bool connectToBus(); + + bool serviceExist(WId id) { return m_menuServices.contains(id); } + QString serviceForWindow(WId id) { return m_menuServices.value(id); } + + bool pathExist(WId id) { return m_menuPaths.contains(id); } + QString pathForWindow(WId id) { return m_menuPaths.value(id).path(); } + + QList ids() { return m_menuServices.keys(); } + + /** + * Return id of first transient/friend window with a menu available + */ + WId recursiveMenuId(WId id); + +Q_SIGNALS: + void WindowRegistered(WId id, const QString& service, const QDBusObjectPath&); + void WindowUnregistered(WId id); + +public Q_SLOTS: + Q_NOREPLY void RegisterWindow(WId id, const QDBusObjectPath& path); + Q_NOREPLY void UnregisterWindow(WId id); + QString GetMenuForWindow(WId id, QDBusObjectPath& path); + +private Q_SLOTS: + void slotServiceUnregistered(const QString& service); + void slotLayoutUpdated(uint revision, int parentId); + void finishFakeUnityAboutToShow(QDBusPendingCallWatcher*); + +private: + QDBusServiceWatcher* m_serviceWatcher; + QHash m_menuServices; + QHash m_menuPaths; + QHash m_windowClasses; + + void fakeUnityAboutToShow(); +}; + +#endif /* MENUIMPORTER_H */ diff --git a/appmenu/menuwidget.cpp b/appmenu/menuwidget.cpp new file mode 100644 index 00000000..0a3b4f2a --- /dev/null +++ b/appmenu/menuwidget.cpp @@ -0,0 +1,387 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "menuwidget.h" + +#include +#include +#include +#include + +#include +#include +#include + +MenuWidget::MenuWidget(QGraphicsView *view) : + QGraphicsWidget(), + m_mouseTimer(new QTimer(this)), + m_actionTimer(new QTimer(this)), + m_view(view), + m_layout(new QGraphicsLinearLayout(this)), + m_currentButton(0), + m_contentBottomMargin(0), + m_mousePosition(-1, -1), + m_visibleMenu(0), + m_menu(0) +{ + connect(m_actionTimer, SIGNAL(timeout()), SLOT(slotUpdateActions())); + connect(m_mouseTimer, SIGNAL(timeout()), SLOT(slotCheckActiveItem())); +} + +MenuWidget::~MenuWidget() +{ + while (!m_buttons.isEmpty()) { + delete m_buttons.front(); + m_buttons.pop_front(); + } +} + +void MenuWidget::setMenu(QMenu *menu) +{ + if (m_menu) { + disconnect(m_menu, SIGNAL(destroyed()), this, SLOT(slotMenuDestroyed())); + m_menu->removeEventFilter(this); + } + if (menu) { + if (m_mouseTimer->isActive()) { + m_mouseTimer->stop(); + } + m_visibleMenu = 0; + m_menu = menu; + connect(m_menu, SIGNAL(destroyed()), SLOT(slotMenuDestroyed()), Qt::UniqueConnection); + m_menu->installEventFilter(this); + slotUpdateActions(); + } +} + +void MenuWidget::initLayout() +{ + MenuButton* button = 0; + + if (!m_menu) { + return; + } + + foreach (QAction* action, m_menu->actions()) + { + button = createButton(action); + if (button) { + m_layout->addItem(button); + button->setMenu(action->menu()); + m_buttons << button; + } + } + + //Assume all buttons have same margins + if (button) { + m_contentBottomMargin = button->bottomMargin(); + } +} + +bool MenuWidget::eventFilter(QObject* object, QEvent* event) +{ + bool filtered; + if (object == m_menu) { + filtered = menuEventFilter(event); + } else { + filtered = subMenuEventFilter(static_cast(object), event); + } + return filtered ? true : QGraphicsWidget::eventFilter(object, event); +} + +bool MenuWidget::menuEventFilter(QEvent* event) +{ + switch (event->type()) { + case QEvent::ActionAdded: + case QEvent::ActionRemoved: + case QEvent::ActionChanged: + // Try to limit layout updates + m_actionTimer->start(500); + break; + default: + break; + } + return false; +} + +bool MenuWidget::subMenuEventFilter(QObject* object, QEvent* event) +{ + QMenu *menu = static_cast(object); + + if (event->type() == QEvent::KeyPress) { + menu->removeEventFilter(this); + QApplication::sendEvent(menu, event); + menu->installEventFilter(this); + if (!event->isAccepted()) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + case Qt::Key_Left: + showLeftRightMenu(false); + break; + case Qt::Key_Right: + showLeftRightMenu(true); + break; + case Qt::Key_Escape: + menu->hide(); + break; + default: + break; + } + } + return true; + } + return false; +} + +void MenuWidget::slotMenuDestroyed() +{ + m_menu = 0; + m_visibleMenu = 0; + m_currentButton = 0; +} + +void MenuWidget::slotCheckActiveItem() +{ + MenuButton* buttonBelow = 0; + QPoint pos = m_view->mapFromGlobal(QCursor::pos()); + QGraphicsItem* item = m_view->itemAt(pos); + + if (pos == m_mousePosition) { + return; + } else { + m_mousePosition = pos; + } + + if (item) { + buttonBelow = qobject_cast(item->toGraphicsObject()); + } + + if (!buttonBelow) { + return; + } + + if (buttonBelow != m_currentButton) { + if (m_currentButton && m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(false); + m_currentButton->setHovered(false); + } + m_currentButton = buttonBelow; + if (m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(true); + } + m_visibleMenu = showMenu(); + } +} + +void MenuWidget::slotMenuAboutToHide() +{ + if (m_currentButton && m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(false); + } + + if (m_mouseTimer->isActive()) { + m_mouseTimer->stop(); + } + m_visibleMenu = 0; + emit aboutToHide(); +} + +void MenuWidget::slotButtonClicked() +{ + m_currentButton = qobject_cast(sender()); + + if (m_currentButton && m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(true); + } + m_visibleMenu = showMenu(); + // Start auto navigation after click + if (!m_mouseTimer->isActive()) + m_mouseTimer->start(100); +} + +void MenuWidget::slotUpdateActions() +{ + if (m_visibleMenu) { + return; // Later + } + + m_actionTimer->stop(); + m_currentButton = 0; + foreach (MenuButton *button, m_buttons) { + disconnect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked())); + m_layout->removeItem(button); + button->hide(); + m_buttons.removeOne(button); + delete button; + } + initLayout(); + // Menu may be empty on application startup + // slotUpdateActions will be called later by eventFilter() + if (m_menu && m_menu->actions().length()) { + emit needResize(); + } +} + +void MenuWidget::setActiveAction(QAction *action) +{ + if (!m_menu) { + return; + } + + m_currentButton = m_buttons.first(); + + if (action) { + QMenu *menu; + int i = 0; + foreach (MenuButton *button, m_buttons) { + menu = m_menu->actions()[i]->menu(); + if (menu && menu == action->menu()) { + m_currentButton = button; + break; + } + if (++i >= m_menu->actions().length()) { + break; + } + } + } + m_currentButton->nativeWidget()->animateClick(); +} + +void MenuWidget::hide() +{ + if (m_mouseTimer->isActive()) { + m_mouseTimer->stop(); + } + QGraphicsWidget::hide(); +} + +MenuButton* MenuWidget::createButton(QAction *action) +{ + if( action->isSeparator() || !action->menu() || !action->isVisible()) { + return 0; + } + + action->setShortcut(QKeySequence()); + MenuButton *button = new MenuButton(this); + button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + button->setText(action->text()); + connect(button, SIGNAL(clicked()), SLOT(slotButtonClicked())); + return button; +} + +QMenu* MenuWidget::showMenu() +{ + QMenu *menu = 0; + + if (m_visibleMenu) { + disconnect(m_visibleMenu, SIGNAL(aboutToHide()), this, SLOT(slotMenuAboutToHide())); + m_visibleMenu->hide(); + } + + if (m_currentButton && m_menu) { + menu = m_currentButton->menu(); + } + + // Last chance to get menu + // Some applications like Firefox have empties menus on layout updates + // They should populate this menu later but in fact, they use another object + // So, we check here directly the button name, may fail with menubar with buttons with same name (test apps) + if (menu && menu->actions().length() == 0) { + foreach (QAction *action, m_menu->actions()) { + if (action->text() == m_currentButton->text()) { + menu = action->menu(); + break; + } + } + } + + if (menu) { + QPoint globalPos = m_view->mapToGlobal(QPoint(0,0)); + QPointF parentPos = m_currentButton->mapFromParent(QPoint(0,0)); + QRect screen = KApplication::desktop()->screenGeometry(); + int x = globalPos.x() - parentPos.x(); + int y = globalPos.y() + m_currentButton->size().height() - parentPos.y(); + + menu->popup(QPoint(x, y)); + + // Fix offscreen menu + if (menu->size().height() + y > screen.height() + screen.y()) { + y = globalPos.y() - parentPos.y() - menu->size().height(); + if (menu->size().width() + x > screen.width() + screen.x()) + x = screen.width() + screen.x() - menu->size().width(); + else if (menu->size().width() + x < screen.x()) + x = screen.x(); + menu->move(x, y); + } + + connect(menu, SIGNAL(aboutToHide()), this, SLOT(slotMenuAboutToHide())); + + installEventFilterForAll(menu, this); + } + return menu; +} + +void MenuWidget::showLeftRightMenu(bool next) +{ + if (!m_currentButton) { + return; + } + + int index = m_buttons.indexOf(m_currentButton); + if (index == -1) { + kWarning() << "Couldn't find button!"; + return; + } + if (next) { + index = (index + 1) % m_buttons.count(); + } else { + index = (index == 0 ? m_buttons.count() : index) - 1; + } + + if (m_currentButton && m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(false); + } + m_currentButton = m_buttons.at(index); + if (m_currentButton && m_currentButton->nativeWidget()) { + m_currentButton->nativeWidget()->setDown(true); + } + m_visibleMenu = showMenu(); +} + +void MenuWidget::installEventFilterForAll(QMenu *menu, QObject *object) +{ + if (!menu) { + return; + } + + menu->installEventFilter(this); + + foreach (QAction *action, menu->actions()) { + if (action->menu()) + installEventFilterForAll(action->menu(), object); + } +} + +#include "menuwidget.moc" \ No newline at end of file diff --git a/appmenu/menuwidget.h b/appmenu/menuwidget.h new file mode 100644 index 00000000..1f47a83a --- /dev/null +++ b/appmenu/menuwidget.h @@ -0,0 +1,143 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MENUWIDGET__H +#define MENUWIDGET__H + +#include "menubutton.h" + +#include +#include + +class QGraphicsLinearLayout; +class QGraphicsView; + +class MenuWidget : public QGraphicsWidget +{ +Q_OBJECT +public: + MenuWidget(QGraphicsView *view = 0); + ~MenuWidget(); + + /** + * Set root menu + */ + void setMenu(QMenu *menu); + /** + * Init layout with root menu + */ + void initLayout(); + /** + * True if a menu is visible in menuwidget + */ + bool aMenuIsVisible() { return m_visibleMenu; } + /** + * Activate action, or first action if null + */ + void setActiveAction(QAction *action); + + /** + * Auto open menu items on mouse over + */ + void autoOpen() { m_mouseTimer->start(100); } + + /** + * Return content bottom margin + */ + qreal contentBottomMargin() { return m_contentBottomMargin; } + + void hide(); + +protected: + /** + * Use to get keyboard events + */ + virtual bool eventFilter(QObject*, QEvent*); + /** + * Filter events on main menu + */ + bool menuEventFilter(QEvent* event); + /** + * Filter events on submenus + */ + bool subMenuEventFilter(QObject* object, QEvent* event); +private Q_SLOTS: + /** + * Clean menu if destroyed + */ + void slotMenuDestroyed(); + /** + * Check hovered item and active it + */ + void slotCheckActiveItem(); + /** + * A menu is hidding + */ + void slotMenuAboutToHide(); + /** + * Menubar button clicked + */ + void slotButtonClicked(); + /** + * Update pending actions + */ + void slotUpdateActions(); +Q_SIGNALS: + void needResize(); + void aboutToHide(); +private: + /** + * Return a button based on action + */ + MenuButton* createButton(QAction *action); + /** + * Show current button menu + * return showed menu + */ + QMenu* showMenu(); + /** + * Show next menu if next, otherwise previous + */ + void showLeftRightMenu(bool next); + /** + * Install event filter for menu and it submenus + */ + void installEventFilterForAll(QMenu *menu, QObject *object); + + //Follow mouse position + QTimer *m_mouseTimer; + //Update actions + QTimer *m_actionTimer; + QGraphicsView *m_view; + QGraphicsLinearLayout *m_layout; + QList m_buttons; + MenuButton *m_currentButton; + qreal m_contentBottomMargin; + QPoint m_mousePosition; + QMenu *m_visibleMenu; + QMenu *m_menu; +}; + +#endif //MENUWIDGET__H diff --git a/appmenu/org.kde.kded.appmenu.xml b/appmenu/org.kde.kded.appmenu.xml new file mode 100644 index 00000000..8056fba3 --- /dev/null +++ b/appmenu/org.kde.kded.appmenu.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/appmenu/shadows.cpp b/appmenu/shadows.cpp new file mode 100644 index 00000000..bcf27d9d --- /dev/null +++ b/appmenu/shadows.cpp @@ -0,0 +1,381 @@ +/* +* Copyright 2011 by Aaron Seigo +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "shadows.h" + +#include +#include + +#ifdef Q_WS_X11 +#include +#include +#include +#include +#endif + +#include +#include + +class Shadows::Private +{ +public: + Private(Shadows *shadows) + : q(shadows), + m_managePixmaps(false) + { + } + + ~Private() + { + clearPixmaps(); + } + + void clearPixmaps(); + void setupPixmaps(); + void initPixmap(const QString &element); + QPixmap initEmptyPixmap(const QSize &size); + void updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders); + void clearShadow(const QWidget *window); + void updateShadows(); + void windowDestroyed(QObject *deletedObject); + void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders); + + Shadows *q; + QList m_shadowPixmaps; + + QPixmap m_emptyCornerPix; + QPixmap m_emptyCornerLeftPix; + QPixmap m_emptyCornerTopPix; + QPixmap m_emptyCornerRightPix; + QPixmap m_emptyCornerBottomPix; + QPixmap m_emptyVerticalPix; + QPixmap m_emptyHorizontalPix; + + QHash > data; + QHash m_windows; + bool m_managePixmaps; +}; + +class ShadowsSingleton +{ +public: + ShadowsSingleton() + { + } + + Shadows self; +}; + +K_GLOBAL_STATIC(ShadowsSingleton, privateShadowsSelf) + +Shadows::Shadows(QObject *parent, const QString &prefix) + : Plasma::Svg(parent), + d(new Private(this)) +{ + setImagePath(prefix); + connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows())); +} + +Shadows *Shadows::self() +{ + return &privateShadowsSelf->self; +} + +void Shadows::addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders) +{ + if (!window || !window->isWindow()) { + return; + } + + d->m_windows[window] = enabledBorders; + d->updateShadow(window, enabledBorders); + connect(window, SIGNAL(destroyed(QObject*)), + this, SLOT(windowDestroyed(QObject*)), Qt::UniqueConnection); +} + +void Shadows::removeWindow(const QWidget *window) +{ + if (!d->m_windows.contains(window)) { + return; + } + + d->m_windows.remove(window); + disconnect(window, 0, this, 0); + d->clearShadow(window); + + if (d->m_windows.isEmpty()) { + d->clearPixmaps(); + } +} + +void Shadows::Private::windowDestroyed(QObject *deletedObject) +{ + m_windows.remove(static_cast(deletedObject)); + + if (m_windows.isEmpty()) { + clearPixmaps(); + } +} + +void Shadows::Private::updateShadows() +{ + setupPixmaps(); + QHash::const_iterator i; + for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) { + updateShadow(i.key(), i.value()); + } +} + +void Shadows::Private::initPixmap(const QString &element) +{ +#ifdef Q_WS_X11 + QPixmap pix = q->pixmap(element); + if (!pix.isNull() && pix.handle() == 0) { + Pixmap xPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), pix.width(), pix.height(), 32); + QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared); + tempPix.fill(Qt::transparent); + QPainter p(&tempPix); + p.drawPixmap(QPoint(0, 0), pix); + m_shadowPixmaps << tempPix; + m_managePixmaps = true; + } else { + m_shadowPixmaps << pix; + } +#endif +} + +QPixmap Shadows::Private::initEmptyPixmap(const QSize &size) +{ + Pixmap emptyXPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), size.width(), size.height(), 32); + QPixmap tempEmptyPix = QPixmap::fromX11Pixmap(emptyXPix, QPixmap::ExplicitlyShared); + tempEmptyPix.fill(Qt::transparent); + return tempEmptyPix; +} + +void Shadows::Private::setupPixmaps() +{ + clearPixmaps(); + initPixmap("shadow-top"); + initPixmap("shadow-topright"); + initPixmap("shadow-right"); + initPixmap("shadow-bottomright"); + initPixmap("shadow-bottom"); + initPixmap("shadow-bottomleft"); + initPixmap("shadow-left"); + initPixmap("shadow-topleft"); + + m_emptyCornerPix = initEmptyPixmap(QSize(1,1)); + m_emptyCornerLeftPix = initEmptyPixmap(QSize(q->elementSize("shadow-topleft").width(), 1)); + m_emptyCornerTopPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-topleft").height())); + m_emptyCornerRightPix = initEmptyPixmap(QSize(q->elementSize("shadow-bottomright").width(), 1)); + m_emptyCornerBottomPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-bottomright").height())); + m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize("shadow-left").height())); + m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize("shadow-top").width(), 1)); + +} + + +void Shadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders) +{ +#ifdef Q_WS_X11 + //shadow-top + if (enabledBorders & Plasma::FrameSvg::TopBorder) { + data[enabledBorders] << m_shadowPixmaps[0].handle(); + } else { + data[enabledBorders] << m_emptyHorizontalPix.handle(); + } + + //shadow-topright + if (enabledBorders & Plasma::FrameSvg::TopBorder && + enabledBorders & Plasma::FrameSvg::RightBorder) { + data[enabledBorders] << m_shadowPixmaps[1].handle(); + } else if (enabledBorders & Plasma::FrameSvg::TopBorder) { + data[enabledBorders] << m_emptyCornerTopPix.handle(); + } else if (enabledBorders & Plasma::FrameSvg::RightBorder) { + data[enabledBorders] << m_emptyCornerRightPix.handle(); + } else { + data[enabledBorders] << m_emptyCornerPix.handle(); + } + + //shadow-right + if (enabledBorders & Plasma::FrameSvg::RightBorder) { + data[enabledBorders] << m_shadowPixmaps[2].handle(); + } else { + data[enabledBorders] << m_emptyVerticalPix.handle(); + } + + //shadow-bottomright + if (enabledBorders & Plasma::FrameSvg::BottomBorder && + enabledBorders & Plasma::FrameSvg::RightBorder) { + data[enabledBorders] << m_shadowPixmaps[3].handle(); + } else if (enabledBorders & Plasma::FrameSvg::BottomBorder) { + data[enabledBorders] << m_emptyCornerBottomPix.handle(); + } else if (enabledBorders & Plasma::FrameSvg::RightBorder) { + data[enabledBorders] << m_emptyCornerRightPix.handle(); + } else { + data[enabledBorders] << m_emptyCornerPix.handle(); + } + + //shadow-bottom + if (enabledBorders & Plasma::FrameSvg::BottomBorder) { + data[enabledBorders] << m_shadowPixmaps[4].handle(); + } else { + data[enabledBorders] << m_emptyHorizontalPix.handle(); + } + + //shadow-bottomleft + if (enabledBorders & Plasma::FrameSvg::BottomBorder && + enabledBorders & Plasma::FrameSvg::LeftBorder) { + data[enabledBorders] << m_shadowPixmaps[5].handle(); + } else if (enabledBorders & Plasma::FrameSvg::BottomBorder) { + data[enabledBorders] << m_emptyCornerBottomPix.handle(); + } else if (enabledBorders & Plasma::FrameSvg::LeftBorder) { + data[enabledBorders] << m_emptyCornerLeftPix.handle(); + } else { + data[enabledBorders] << m_emptyCornerPix.handle(); + } + + //shadow-left + if (enabledBorders & Plasma::FrameSvg::LeftBorder) { + data[enabledBorders] << m_shadowPixmaps[6].handle(); + } else { + data[enabledBorders] << m_emptyVerticalPix.handle(); + } + + //shadow-topleft + if (enabledBorders & Plasma::FrameSvg::TopBorder && + enabledBorders & Plasma::FrameSvg::LeftBorder) { + data[enabledBorders] << m_shadowPixmaps[7].handle(); + } else if (enabledBorders & Plasma::FrameSvg::TopBorder) { + data[enabledBorders] << m_emptyCornerTopPix.handle(); + } else if (enabledBorders & Plasma::FrameSvg::LeftBorder) { + data[enabledBorders] << m_emptyCornerLeftPix.handle(); + } else { + data[enabledBorders] << m_emptyCornerPix.handle(); + } +#endif + + int left, top, right, bottom = 0; + + QSize marginHint; + if (enabledBorders & Plasma::FrameSvg::TopBorder) { + marginHint = q->elementSize("shadow-hint-top-margin"); + if (marginHint.isValid()) { + top = marginHint.height(); + } else { + top = m_shadowPixmaps[0].height(); // top + } + } else { + top = 1; + } + + if (enabledBorders & Plasma::FrameSvg::RightBorder) { + marginHint = q->elementSize("shadow-hint-right-margin"); + if (marginHint.isValid()) { + right = marginHint.width(); + } else { + right = m_shadowPixmaps[2].width(); // right + } + } else { + right = 1; + } + + if (enabledBorders & Plasma::FrameSvg::BottomBorder) { + marginHint = q->elementSize("shadow-hint-bottom-margin"); + if (marginHint.isValid()) { + bottom = marginHint.height(); + } else { + bottom = m_shadowPixmaps[4].height(); // bottom + } + } else { + bottom = 1; + } + + if (enabledBorders & Plasma::FrameSvg::LeftBorder) { + marginHint = q->elementSize("shadow-hint-left-margin"); + if (marginHint.isValid()) { + left = marginHint.width(); + } else { + left = m_shadowPixmaps[6].width(); // left + } + } else { + left = 1; + } + + data[enabledBorders] << top << right << bottom << left; +} + +void Shadows::Private::clearPixmaps() +{ +#ifdef Q_WS_X11 + if (m_managePixmaps) { + foreach (const QPixmap &pixmap, m_shadowPixmaps) { + XFreePixmap(QX11Info::display(), pixmap.handle()); + } + + XFreePixmap(QX11Info::display(), m_emptyCornerPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyCornerBottomPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyCornerLeftPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyCornerRightPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyCornerTopPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyVerticalPix.handle()); + XFreePixmap(QX11Info::display(), m_emptyHorizontalPix.handle()); + + m_managePixmaps = false; + } +#endif + m_shadowPixmaps.clear(); + data.clear(); +} + +void Shadows::Private::updateShadow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders) +{ +#ifdef Q_WS_X11 + if (m_shadowPixmaps.isEmpty()) { + setupPixmaps(); + } + + if (!data.contains(enabledBorders)) { + setupData(enabledBorders); + } + + Display *dpy = QX11Info::display(); + Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False); + + //kDebug() << "going to set the shadow of" << winId() << "to" << data; + XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace, + reinterpret_cast(data[enabledBorders].constData()), data[enabledBorders].size()); +#endif +} + +void Shadows::Private::clearShadow(const QWidget *window) +{ +#ifdef Q_WS_X11 + Display *dpy = QX11Info::display(); + Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False); + XDeleteProperty(dpy, window->winId(), atom); +#endif +} + +bool Shadows::enabled() const +{ + return hasElement("shadow-left"); +} + +#include "shadows.moc" + diff --git a/appmenu/shadows.h b/appmenu/shadows.h new file mode 100644 index 00000000..afbc49ef --- /dev/null +++ b/appmenu/shadows.h @@ -0,0 +1,51 @@ +/* +* Copyright 2011 by Aaron Seigo +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef SHADOWS_H +#define SHADOWS_H + +#include + +#include "plasma/framesvg.h" +#include "plasma/svg.h" + + +class Shadows : public Plasma::Svg +{ + Q_OBJECT + +public: + explicit Shadows(QObject *parent = 0, const QString &prefix = "widgets/panel-background"); + + static Shadows *self(); + + void addWindow(const QWidget *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders); + void removeWindow(const QWidget *window); + + bool enabled() const; + +private: + class Private; + Private * const d; + + Q_PRIVATE_SLOT(d, void updateShadows()) + Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject)) +}; + +#endif + diff --git a/appmenu/topmenubar.cpp b/appmenu/topmenubar.cpp new file mode 100644 index 00000000..2ae19b38 --- /dev/null +++ b/appmenu/topmenubar.cpp @@ -0,0 +1,176 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "topmenubar.h" +#include "glowbar.h" + +//KDE +#include +#include + +// Qt +#include +#include +#include +#include +#include +#include + +TopMenuBar::TopMenuBar() + : MenuBar(), + m_prevCursorPos(-1, -1), + m_mouseTracker(new QTimer(this)), + m_hideGlowTimer(new QTimer(this)), + m_glowBar(new GlowBar()) +{ + connect(this, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); + connect(m_mouseTracker, SIGNAL(timeout()), this, SLOT(slotMouseTracker())); + connect(m_hideGlowTimer, SIGNAL(timeout()), this, SLOT(slotHideGlowBar())); +} + +TopMenuBar::~TopMenuBar() +{ + delete m_mouseTracker; + delete m_hideGlowTimer; + hideGlowBar(); + delete m_glowBar; +} + +void TopMenuBar::enableMouseTracking(bool enable) +{ + if (enable) { + if (!cursorInMenuBar()) { + showGlowBar(); + } + m_mouseTracker->start(250); + } else { + hideGlowBar(); + m_mouseTracker->stop(); + } +} + +void TopMenuBar::updateSize() +{ + // Enable mouse tracking on resize if needed + if (!m_mouseTracker->isActive() && !cursorInMenuBar()) { + enableMouseTracking(); + } + resize(sizeHint()); +} + +void TopMenuBar::move(QPoint p) +{ + MenuBar::move(p); + if (m_glowBar) { + m_glowBar->move(p); + m_glowBar->setPixmap(triggerRect().topLeft(), triggerRect().width()); + } +} + +bool TopMenuBar::cursorInMenuBar() +{ + if (m_mouseTracker->isActive()) { + return triggerRect().contains(QCursor::pos()); + } else { + return MenuBar::cursorInMenuBar(); + } +} + +void TopMenuBar::slotAboutToHide() +{ + enableMouseTracking(); +} + +void TopMenuBar::slotMouseTracker() +{ + QPoint cursorPos = QCursor::pos(); + + // reset timer + if (cursorPos != m_prevCursorPos && m_hideGlowTimer->isActive()) { + m_hideGlowTimer->stop(); + m_hideGlowTimer->start(10000); + } + + if (cursorInMenuBar()) { // show menubar + m_mouseTracker->stop(); + hideGlowBar(); + show(); + } else if(cursorPos != m_prevCursorPos) { // change glowbar opacity + qreal opacity = glowBarOpacity(); + QPropertyAnimation *anim = new QPropertyAnimation(m_glowBar, "windowOpacity"); + anim->setStartValue(m_glowBar->windowOpacity()); + anim->setEndValue(opacity); + anim->setDuration(200); + anim->start(QAbstractAnimation::DeleteWhenStopped); + // Show menubar if auto hidden + if (!m_glowBar->isVisible()) { + m_glowBar->show(); + } + } + m_prevCursorPos = cursorPos; +} + +void TopMenuBar::slotHideGlowBar() +{ + if (m_prevCursorPos == QCursor::pos()) { + hideGlowBar(); + } else { + m_hideGlowTimer->start(10000); + } +} + +void TopMenuBar::showGlowBar() +{ + if (m_glowBar) { + m_hideGlowTimer->start(10000); + m_glowBar->setWindowOpacity(glowBarOpacity()); + m_glowBar->show(); + } +} + +void TopMenuBar::hideGlowBar() +{ + if (m_glowBar) { + m_glowBar->hide(); + } +} + +qreal TopMenuBar::glowBarOpacity() +{ + QPoint cursorPos = QCursor::pos(); + QDesktopWidget *desktop = QApplication::desktop(); + int screen = desktop->screenNumber(cursorPos); + QRect desktopRect = desktop->availableGeometry(screen); + return 1.0 - ((cursorPos.y() - desktopRect.y())/qreal(desktopRect.height())*2.0); +} + +QRect TopMenuBar::triggerRect() +{ + QPoint triggerPoint = QPoint(x(), y()); + QSize triggerSize = QSize(sizeHint().width(), 5); + return QRect(triggerPoint, triggerSize); +} + +#include "topmenubar.moc" \ No newline at end of file diff --git a/appmenu/topmenubar.h b/appmenu/topmenubar.h new file mode 100644 index 00000000..8712cfd7 --- /dev/null +++ b/appmenu/topmenubar.h @@ -0,0 +1,81 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TOPMENUBAR__H +#define TOPMENUBAR__H + +#include "menubar.h" + +class QTimer; +class GlowBar; + +class TopMenuBar : public MenuBar +{ +Q_OBJECT +public: + TopMenuBar(); + ~TopMenuBar(); + + /** + * Start mouse tracking (hide/show on mouse event) + */ + void enableMouseTracking(bool enable = true); + + /** + * Set menubar parent window id + */ + void setParentWid(WId id) { m_wid = id; } + /** + * Get menubar parent window id + */ + WId parentWid() { return m_wid; } + /** + * resize menu bar to feet content + */ + void updateSize(); + /** + * Move menubar and glow bar at position + */ + void move(QPoint p); +protected: + bool cursorInMenuBar(); +private Q_SLOTS: + void slotAboutToHide(); + void slotMouseTracker(); + void slotHideGlowBar(); +private: + void showGlowBar(); + void hideGlowBar(); + qreal glowBarOpacity(); + QRect triggerRect(); + + WId m_wid; + QPoint m_prevCursorPos; + QTimer* m_mouseTracker; + QTimer* m_hideGlowTimer; + GlowBar* m_glowBar; +}; + +#endif diff --git a/appmenu/verticalmenu.cpp b/appmenu/verticalmenu.cpp new file mode 100644 index 00000000..17f0d9bc --- /dev/null +++ b/appmenu/verticalmenu.cpp @@ -0,0 +1,79 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "verticalmenu.h" + +#include +#include +#include +#include +#include + +VerticalMenu::VerticalMenu(QWidget* parent) : QMenu(parent) +{ +} + +VerticalMenu::~VerticalMenu() +{ +} + +QMenu *VerticalMenu::leafMenu() +{ + QMenu *leaf = this; + while (true) { + QAction *act = leaf->activeAction(); + if (act && act->menu() && act->menu()->isVisible()) { + leaf = act->menu(); + continue; + } + return leaf == this ? 0 : leaf; + } + return 0; // make gcc happy +} + +void VerticalMenu::paintEvent(QPaintEvent *pe) +{ + QMenu::paintEvent(pe); + if (QWidget::mouseGrabber() == this) + return; + if (QWidget::mouseGrabber()) + QWidget::mouseGrabber()->releaseMouse(); + grabMouse(); + grabKeyboard(); +} + +#define FORWARD(_EVENT_, _TYPE_) \ +void VerticalMenu::_EVENT_##Event(Q##_TYPE_##Event *e) \ +{ \ + if (QMenu *leaf = leafMenu()) \ + QCoreApplication::sendEvent(leaf, e); \ + else \ + QMenu::_EVENT_##Event(e); \ +} \ + +FORWARD(keyPress, Key) +FORWARD(keyRelease, Key) + +#include "verticalmenu.moc" \ No newline at end of file diff --git a/appmenu/verticalmenu.h b/appmenu/verticalmenu.h new file mode 100644 index 00000000..1b28ce27 --- /dev/null +++ b/appmenu/verticalmenu.h @@ -0,0 +1,56 @@ +/* + This file is part of the KDE project. + + Copyright (c) 2011 Lionel Chauvin + Copyright (c) 2011,2012 Cédric Bellegarde + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef VERTICALMENU_H +#define VERTICALMENU_H + +#include + +class VerticalMenu : public QMenu +{ +Q_OBJECT +public: + VerticalMenu(QWidget * parent = 0); + ~VerticalMenu(); + + /** + * Set menu parent window id + */ + void setParentWid(WId id) { m_wid = id; } + /** + * Get menu parent window id + */ + WId parentWid() { return m_wid; } +protected: + void keyPressEvent(QKeyEvent*); + void keyReleaseEvent(QKeyEvent*); + void paintEvent(QPaintEvent*); +private: + QMenu *leafMenu(); +private: + WId m_wid; +}; + +#endif //VERTICALMENU_H diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 00000000..38a9971a --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,3 @@ + +add_subdirectory(modules) + diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt new file mode 100644 index 00000000..117b3a55 --- /dev/null +++ b/cmake/modules/CMakeLists.txt @@ -0,0 +1,17 @@ +# install the cmake files + +# don't glob for the files, since we don't want to +# install e.g. FindLibKNotification-1.cmake +set(cmakeFiles FindCkConnector.cmake + FindDBus.cmake + FindLibXKlavier.cmake + FindOpenGLES.cmake + FindPAM.cmake + FindSensors.cmake + PkgConfigGetVar.cmake + UnixAuth.cmake ) + +set(module_install_dir ${DATA_INSTALL_DIR}/cmake/modules ) + +install( FILES ${cmakeFiles} DESTINATION ${module_install_dir} ) + diff --git a/cmake/modules/COPYING-CMAKE-SCRIPTS b/cmake/modules/COPYING-CMAKE-SCRIPTS new file mode 100644 index 00000000..4b417765 --- /dev/null +++ b/cmake/modules/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/modules/FindCkConnector.cmake b/cmake/modules/FindCkConnector.cmake new file mode 100644 index 00000000..5130ca0a --- /dev/null +++ b/cmake/modules/FindCkConnector.cmake @@ -0,0 +1,59 @@ +# - Try to find the ConsoleKit connector library (libck-connector) +# Once done this will define +# +# CKCONNECTOR_FOUND - system has the CK Connector +# CKCONNECTOR_INCLUDE_DIR - the CK Connector include directory +# CKCONNECTOR_LIBRARIES - the libraries needed to use CK Connector + +# Copyright (c) 2008, Kevin Kofler, +# modeled after FindLibArt.cmake: +# Copyright (c) 2006, Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +if (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES) + + # in cache already + SET(CKCONNECTOR_FOUND TRUE) + +else (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES) + + IF (NOT WIN32) + FIND_PACKAGE(PkgConfig) + IF (PKG_CONFIG_FOUND) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + pkg_check_modules(_CKCONNECTOR_PC QUIET ck-connector) + ENDIF (PKG_CONFIG_FOUND) + ENDIF (NOT WIN32) + + FIND_PATH(CKCONNECTOR_INCLUDE_DIR ck-connector.h + ${_CKCONNECTOR_PC_INCLUDE_DIRS} + ) + + FIND_LIBRARY(CKCONNECTOR_LIBRARIES NAMES ck-connector + PATHS + ${_CKCONNECTOR_PC_LIBDIR} + ) + + + if (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES) + set(CKCONNECTOR_FOUND TRUE) + endif (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES) + + + if (CKCONNECTOR_FOUND) + if (NOT CkConnector_FIND_QUIETLY) + message(STATUS "Found ck-connector: ${CKCONNECTOR_LIBRARIES}") + endif (NOT CkConnector_FIND_QUIETLY) + else (CKCONNECTOR_FOUND) + if (CkConnector_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find ck-connector") + endif (CkConnector_FIND_REQUIRED) + endif (CKCONNECTOR_FOUND) + + MARK_AS_ADVANCED(CKCONNECTOR_INCLUDE_DIR CKCONNECTOR_LIBRARIES) + +endif (CKCONNECTOR_INCLUDE_DIR AND CKCONNECTOR_LIBRARIES) diff --git a/cmake/modules/FindDBus.cmake b/cmake/modules/FindDBus.cmake new file mode 100644 index 00000000..f227cc29 --- /dev/null +++ b/cmake/modules/FindDBus.cmake @@ -0,0 +1,72 @@ +# - Try to find the low-level D-Bus library +# Once done this will define +# +# DBUS_FOUND - system has D-Bus +# DBUS_INCLUDE_DIR - the D-Bus include directory +# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory +# DBUS_LIBRARIES - the libraries needed to use D-Bus + +# Copyright (c) 2008, Kevin Kofler, +# modeled after FindLibArt.cmake: +# Copyright (c) 2006, Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + # in cache already + SET(DBUS_FOUND TRUE) + +else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + IF (NOT WIN32) + FIND_PACKAGE(PkgConfig) + IF (PKG_CONFIG_FOUND) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + pkg_check_modules(_DBUS_PC QUIET dbus-1) + ENDIF (PKG_CONFIG_FOUND) + ENDIF (NOT WIN32) + + FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/include + /usr/include/dbus-1.0 + /usr/local/include + ) + + FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/lib${LIB_SUFFIX}/include + /usr/lib${LIB_SUFFIX}/dbus-1.0/include + /usr/lib64/include + /usr/lib64/dbus-1.0/include + /usr/lib/include + /usr/lib/dbus-1.0/include + ) + + FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus + PATHS + ${_DBUS_PC_LIBDIR} + ) + + + if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + set(DBUS_FOUND TRUE) + endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + + if (DBUS_FOUND) + if (NOT DBus_FIND_QUIETLY) + message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}") + endif (NOT DBus_FIND_QUIETLY) + else (DBUS_FOUND) + if (DBus_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find D-Bus") + endif (DBus_FIND_REQUIRED) + endif (DBUS_FOUND) + + MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES) + +endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) diff --git a/cmake/modules/FindLibXKlavier.cmake b/cmake/modules/FindLibXKlavier.cmake new file mode 100644 index 00000000..7afd77a3 --- /dev/null +++ b/cmake/modules/FindLibXKlavier.cmake @@ -0,0 +1,29 @@ +# - Try to find LibXKlavier +# Once done this will define +# +# LIBXKLAVIER_FOUND - system has LibXKlavier +# LIBXKLAVIER_LDFLAGS - the libraries needed to use LibXKlavier +# LIBXKLAVIER_CFLAGS - Compiler switches required for using LibXKlavier +# LIBXKLAVIER_VERSION - Version of LibXKlavier + +if (LIBXKLAVIER_CFLAGS AND LIBXKLAVIER_LDFLAGS) + + # in cache already + SET(LIBXKLAVIER_FOUND TRUE) + +else (LIBXKLAVIER_CFLAGS AND LIBXKLAVIER_LDFLAGS) + + IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + INCLUDE(UsePkgConfig) + + pkg_check_modules(LIBXKLAVIER libxklavier>=3.0) + ENDIF (NOT WIN32) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXKlavier DEFAULT_MSG LIBXKLAVIER_CFLAGS LIBXKLAVIER_LDFLAGS) + + MARK_AS_ADVANCED(LIBXKLAVIER_CFLAGS LIBXKLAVIER_LDFLAGS LIBXKLAVIER_VERSION) + +endif (LIBXKLAVIER_CFLAGS AND LIBXKLAVIER_LDFLAGS) diff --git a/cmake/modules/FindOpenGLES.cmake b/cmake/modules/FindOpenGLES.cmake new file mode 100644 index 00000000..60b07e29 --- /dev/null +++ b/cmake/modules/FindOpenGLES.cmake @@ -0,0 +1,52 @@ +# - Try to find OpenGLES +# Once done this will define +# +# OPENGLES_FOUND - system has OpenGLES and EGL +# OPENGL_EGL_FOUND - system has EGL +# OPENGLES_INCLUDE_DIR - the GLES include directory +# OPENGLES_LIBRARY - the GLES library +# OPENGLES_EGL_INCLUDE_DIR - the EGL include directory +# OPENGLES_EGL_LIBRARY - the EGL library +# OPENGLES_LIBRARIES - all libraries needed for OpenGLES +# OPENGLES_INCLUDES - all includes needed for OpenGLES + +FIND_PATH(OPENGLES_INCLUDE_DIR GLES2/gl2.h + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include +) + +FIND_LIBRARY(OPENGLES_LIBRARY + NAMES GLESv2 + PATHS /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib +) + +FIND_PATH(OPENGLES_EGL_INCLUDE_DIR EGL/egl.h + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include +) + +FIND_LIBRARY(OPENGLES_EGL_LIBRARY + NAMES EGL + PATHS /usr/shlib /usr/X11R6/lib + /usr/lib +) + +SET(OPENGL_EGL_FOUND "NO") +IF(OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR) + SET(OPENGL_EGL_FOUND "YES") +ENDIF() + +SET(OPENGLES_FOUND "NO") +IF(OPENGLES_LIBRARY AND OPENGLES_INCLUDE_DIR AND + OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR) + SET(OPENGLES_LIBRARIES ${OPENGLES_LIBRARY} ${OPENGLES_LIBRARIES} + ${OPENGLES_EGL_LIBRARY}) + SET(OPENGLES_INCLUDES ${OPENGLES_INCLUDE_DIR} ${OPENGLES_EGL_INCLUDE_DIR}) + SET(OPENGLES_FOUND "YES") +ENDIF() + diff --git a/cmake/modules/FindPAM.cmake b/cmake/modules/FindPAM.cmake new file mode 100644 index 00000000..34998365 --- /dev/null +++ b/cmake/modules/FindPAM.cmake @@ -0,0 +1,74 @@ +# - Try to find the PAM libraries +# Once done this will define +# +# PAM_FOUND - system has pam +# PAM_INCLUDE_DIR - the pam include directory +# PAM_LIBRARIES - libpam library + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + # Already in cache, be silent + set(PAM_FIND_QUIETLY TRUE) +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +find_path(PAM_INCLUDE_DIR NAMES security/pam_appl.h pam/pam_appl.h) +find_library(PAM_LIBRARY pam) +find_library(DL_LIBRARY dl) + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + set(PAM_FOUND TRUE) + if (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY} ${DL_LIBRARY}) + else (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY}) + endif (DL_LIBRARY) + + if (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) + # darwin claims to be something special + set(HAVE_PAM_PAM_APPL_H 1) + endif (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) + + if (NOT DEFINED PAM_MESSAGE_CONST) + include(CheckCXXSourceCompiles) + # XXX does this work with plain c? + check_cxx_source_compiles(" +#if ${HAVE_PAM_PAM_APPL_H}+0 +# include +#else +# include +#endif + +static int PAM_conv( + int num_msg, + const struct pam_message **msg, /* this is the culprit */ + struct pam_response **resp, + void *ctx) +{ + return 0; +} + +int main(void) +{ + struct pam_conv PAM_conversation = { + &PAM_conv, /* this bombs out if the above does not match */ + 0 + }; + + return 0; +} +" PAM_MESSAGE_CONST) + endif (NOT DEFINED PAM_MESSAGE_CONST) + set(PAM_MESSAGE_CONST ${PAM_MESSAGE_CONST} CACHE BOOL "PAM expects a conversation function with const pam_message") + +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +if (PAM_FOUND) + if (NOT PAM_FIND_QUIETLY) + message(STATUS "Found PAM: ${PAM_LIBRARIES}") + endif (NOT PAM_FIND_QUIETLY) +else (PAM_FOUND) + if (PAM_FIND_REQUIRED) + message(FATAL_ERROR "PAM was not found") + endif(PAM_FIND_REQUIRED) +endif (PAM_FOUND) + +mark_as_advanced(PAM_INCLUDE_DIR PAM_LIBRARY DL_LIBRARY PAM_MESSAGE_CONST) diff --git a/cmake/modules/FindPCIUTILS.cmake b/cmake/modules/FindPCIUTILS.cmake new file mode 100644 index 00000000..0dd99660 --- /dev/null +++ b/cmake/modules/FindPCIUTILS.cmake @@ -0,0 +1,29 @@ +# - Try to find the pciutils directory library +# Once done this will define +# +# PCIUTILS_FOUND - system has PCIUtils +# PCIUTILS_INCLUDE_DIR - the PCIUTILS include directory +# PCIUTILS_LIBRARIES - The libraries needed to use PCIUtils + +if(PCIUTILS_INCLUDE_DIR AND PCIUTILS_LIBRARIES) + set(PCIUTILS_FIND_QUIETLY TRUE) +endif(PCIUTILS_INCLUDE_DIR AND PCIUTILS_LIBRARIES) + +FIND_PATH(PCIUTILS_INCLUDE_DIR pci/pci.h) + +FIND_LIBRARY(PCIUTILS_LIBRARY NAMES pci) +if(PCIUTILS_LIBRARY) + FIND_LIBRARY(RESOLV_LIBRARY NAMES resolv) + if(RESOLV_LIBRARY) + set(PCIUTILS_LIBRARIES ${PCIUTILS_LIBRARY} ${RESOLV_LIBRARY}) + else(RESOLV_LIBRARY) + set(PCIUTILS_LIBRARIES ${PCIUTILS_LIBRARY}) + endif(RESOLV_LIBRARY) +endif(PCIUTILS_LIBRARY) + + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCIUTILS DEFAULT_MSG PCIUTILS_LIBRARIES PCIUTILS_INCLUDE_DIR) + +MARK_AS_ADVANCED(PCIUTILS_INCLUDE_DIR PCIUTILS_LIBRARIES) + diff --git a/cmake/modules/FindQJSON.cmake b/cmake/modules/FindQJSON.cmake new file mode 100644 index 00000000..fad59050 --- /dev/null +++ b/cmake/modules/FindQJSON.cmake @@ -0,0 +1,36 @@ +# Find QJSON - JSON handling library for Qt +# +# This module defines +# QJSON_FOUND - whether the qsjon library was found +# QJSON_LIBRARIES - the qjson library +# QJSON_INCLUDE_DIR - the include path of the qjson library +# +# Copyright (C) 2012 Raphael Kubo da Costa +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# QJSON v0.7.2+ provides a QJSONConfig.cmake, which should be used if found. +find_package(QJSON QUIET NO_MODULE) + +if (QJSON_FOUND) + set(REQUIRED_LIBS QJSON_CONFIG) +else (QJSON_FOUND) + find_package(PkgConfig) + pkg_check_modules(PC_QJSON QJson>=0.5) + + find_library(QJSON_LIBRARIES + NAMES qjson + HINTS ${PC_QJSON_LIBDIR} ${PC_QJSON_LIBRARY_DIRS} + ) + + find_path(QJSON_INCLUDE_DIR + NAMES qjson/parser.h + HINTS ${PC_QJSON_INCLUDEDIR} ${PC_QJSON_INCLUDE_DIRS} + ) + + set(REQUIRED_LIBS QJSON_LIBRARIES QJSON_INCLUDE_DIR) +endif (QJSON_FOUND) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(QJSON DEFAULT_MSG ${REQUIRED_LIBS}) diff --git a/cmake/modules/FindQalculate.cmake b/cmake/modules/FindQalculate.cmake new file mode 100644 index 00000000..707a9f7c --- /dev/null +++ b/cmake/modules/FindQalculate.cmake @@ -0,0 +1,52 @@ +# - Try to find libqalculate +# Input variables +# +# QALCULATE_MIN_VERSION - minimal version of libqalculate +# QALCULATE_FIND_REQUIRED - fail if can't find libqalculate +# +# Once done this will define +# +# QALCULATE_FOUND - system has libqalculate +# QALCULATE_CFLAGS - libqalculate cflags +# QALCULATE_LIBRARIES - libqalculate libraries +# +# Copyright (c) 2007, Vladimir Kuznetsov, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if(QALCULATE_CFLAGS AND QALCULATE_LIBRARIES) + + # in cache already + set(QALCULATE_FOUND TRUE) + +else(QALCULATE_CFLAGS AND QALCULATE_LIBRARIES) + if(NOT WIN32) + include(UsePkgConfig) + + if(QALCULATE_MIN_VERSION) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS libqalculate --atleast-version=${QALCULATE_MIN_VERSION} RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull) + else(QALCULATE_MIN_VERSION) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS libqalculate --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull) + endif(QALCULATE_MIN_VERSION) + + if(_return_VALUE STREQUAL "0") + exec_program(${PKGCONFIG_EXECUTABLE} ARGS libqalculate --libs OUTPUT_VARIABLE QALCULATE_LIBRARIES) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS cln --libs OUTPUT_VARIABLE CLN_LIBRARIES) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS libqalculate --cflags OUTPUT_VARIABLE QALCULATE_CFLAGS) + set(QALCULATE_FOUND TRUE) + endif(_return_VALUE STREQUAL "0") + + else(NOT WIN32) + # XXX: currently no libqalculate on windows + set(QALCULATE_FOUND FALSE) + + endif(NOT WIN32) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qalculate DEFAULT_MSG QALCULATE_LIBRARIES ) + + mark_as_advanced(QALCULATE_CFLAGS QALCULATE_LIBRARIES) + +endif(QALCULATE_CFLAGS AND QALCULATE_LIBRARIES) + diff --git a/cmake/modules/FindRAW1394.cmake b/cmake/modules/FindRAW1394.cmake new file mode 100644 index 00000000..c6ce3568 --- /dev/null +++ b/cmake/modules/FindRAW1394.cmake @@ -0,0 +1,20 @@ +# - Try to find the raw1394 directory library +# Once done this will define +# +# RAW1394_FOUND - system has RAW1394 +# RAW1394_INCLUDE_DIR - the RAW1394 include directory +# RAW1394_LIBRARIES - The libraries needed to use FAM + +if(RAW1394_INCLUDE_DIR AND RAW1394_LIBRARIES) + set(RAW1394_FIND_QUIETLY TRUE) +endif(RAW1394_INCLUDE_DIR AND RAW1394_LIBRARIES) + +FIND_PATH(RAW1394_INCLUDE_DIR libraw1394/raw1394.h) + +FIND_LIBRARY(RAW1394_LIBRARIES NAMES raw1394 ) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(RAW1394 DEFAULT_MSG RAW1394_LIBRARIES RAW1394_INCLUDE_DIR) + +MARK_AS_ADVANCED(RAW1394_INCLUDE_DIR RAW1394_LIBRARIES) + diff --git a/cmake/modules/FindSensors.cmake b/cmake/modules/FindSensors.cmake new file mode 100644 index 00000000..6da908d8 --- /dev/null +++ b/cmake/modules/FindSensors.cmake @@ -0,0 +1,16 @@ +# - Try to find the sensors directory library +# Once done this will define +# +# SENSORS_FOUND - system has SENSORS +# SENSORS_INCLUDE_DIR - the SENSORS include directory +# SENSORS_LIBRARIES - The libraries needed to use SENSORS + +FIND_PATH(SENSORS_INCLUDE_DIR sensors/sensors.h) + +FIND_LIBRARY(SENSORS_LIBRARIES NAMES sensors) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sensors DEFAULT_MSG SENSORS_INCLUDE_DIR SENSORS_LIBRARIES ) + +MARK_AS_ADVANCED(SENSORS_INCLUDE_DIR SENSORS_LIBRARIES) + diff --git a/cmake/modules/FindUDev.cmake b/cmake/modules/FindUDev.cmake new file mode 100644 index 00000000..4c8390db --- /dev/null +++ b/cmake/modules/FindUDev.cmake @@ -0,0 +1,19 @@ +# - Try to find UDev +# Once done this will define +# +# UDEV_FOUND - system has UDev +# UDEV_INCLUDE_DIR - the libudev include directory +# UDEV_LIBS - The libudev libraries + +# Copyright (c) 2010, Rafael Fernández López, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +find_path(UDEV_INCLUDE_DIR libudev.h) +find_library(UDEV_LIBS udev) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UDev DEFAULT_MSG UDEV_INCLUDE_DIR UDEV_LIBS) + +mark_as_advanced(UDEV_INCLUDE_DIR UDEV_LIBS) diff --git a/cmake/modules/FindWayland.cmake b/cmake/modules/FindWayland.cmake new file mode 100644 index 00000000..00c17a3c --- /dev/null +++ b/cmake/modules/FindWayland.cmake @@ -0,0 +1,62 @@ +# Try to find Wayland on a Unix system +# +# This will define: +# +# WAYLAND_FOUND - True if Wayland is found +# WAYLAND_LIBRARIES - Link these to use Wayland +# WAYLAND_INCLUDE_DIR - Include directory for Wayland +# WAYLAND_DEFINITIONS - Compiler flags for using Wayland +# +# In addition the following more fine grained variables will be defined: +# +# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES +# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES +# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES +# +# Copyright (c) 2013 Martin Gräßlin +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) + # In the cache already + SET(WAYLAND_FIND_QUIETLY TRUE) + ENDIF () + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl) + + SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) + + FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + + FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + + set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR}) + + set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES}) + + list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) + + MARK_AS_ADVANCED( + WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES + WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES + WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES + WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES + ) + +ENDIF () diff --git a/cmake/modules/FindX11_XCB.cmake b/cmake/modules/FindX11_XCB.cmake new file mode 100644 index 00000000..6b9b8b4c --- /dev/null +++ b/cmake/modules/FindX11_XCB.cmake @@ -0,0 +1,31 @@ +# - Try to find libX11-xcb +# Once done this will define +# +# X11_XCB_FOUND - system has libX11-xcb +# X11_XCB_LIBRARIES - Link these to use libX11-xcb +# X11_XCB_INCLUDE_DIR - the libX11-xcb include dir +# X11_XCB_DEFINITIONS - compiler switches required for using libX11-xcb + +# Copyright (c) 2012 Fredrik Höglund +# Copyright (c) 2008 Helio Chissini de Castro, +# Copyright (c) 2007 Matthias Kretz, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_X11_XCB QUIET x11-xcb) + + SET(X11_XCB_DEFINITIONS ${PKG_X11_XCB_CFLAGS}) + + FIND_PATH(X11_XCB_INCLUDE_DIR NAMES X11/Xlib-xcb.h HINTS ${PKG_X11_XCB_INCLUDE_DIRS}) + FIND_LIBRARY(X11_XCB_LIBRARIES NAMES X11-xcb HINTS ${PKG_X11_XCB_LIBRARY_DIRS}) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(X11_XCB DEFAULT_MSG X11_XCB_LIBRARIES X11_XCB_INCLUDE_DIR) + + MARK_AS_ADVANCED(X11_XCB_INCLUDE_DIR X11_XCB_LIBRARIES) +ENDIF (NOT WIN32) diff --git a/cmake/modules/FindXCB.cmake b/cmake/modules/FindXCB.cmake new file mode 100644 index 00000000..a065468f --- /dev/null +++ b/cmake/modules/FindXCB.cmake @@ -0,0 +1,123 @@ +# Try to find XCB on a Unix system +# +# This will define: +# +# XCB_FOUND - True if xcb is available +# XCB_LIBRARIES - Link these to use xcb +# XCB_INCLUDE_DIR - Include directory for xcb +# XCB_DEFINITIONS - Compiler flags for using xcb +# +# In addition the following more fine grained variables will be defined: +# +# XCB_XCB_FOUND XCB_XCB_INCLUDE_DIR XCB_XCB_LIBRARIES +# XCB_COMPOSITE_FOUND XCB_COMPOSITE_INCLUDE_DIR XCB_COMPOSITE_LIBRARIES +# XCB_DAMAGE_FOUND XCB_DAMAGE_INCLUDE_DIR XCB_DAMAGE_LIBRARIES +# XCB_XFIXES_FOUND XCB_XFIXES_INCLUDE_DIR XCB_XFIXES_LIBRARIES +# XCB_RENDER_FOUND XCB_RENDER_INCLUDE_DIR XCB_RENDER_LIBRARIES +# XCB_RANDR_FOUND XCB_RANDR_INCLUDE_DIR XCB_RANDR_LIBRARIES +# XCB_SHAPE_FOUND XCB_SHAPE_INCLUDE_DIR XCB_SHAPE_LIBRARIES +# XCB_SHM_FOUND XCB_SHM_INCLUDE_DIR XCB_SHM_LIBRARIES +# XCB_SYNC_FOUND XCB_SYNC_INCLUDE_DIR XCB_SYNC_LIBRARIES +# XCB_IMAGE_FOUND XCB_IMAGE_INCLUDE_DIR XCB_IMAGE_LIBRARIES +# XCB_RENDERUTIL_FOUND XCB_RENDERUTIL_INCLUDE_DIR XCB_RENDERUTIL_LIBRARIES +# XCB_KEYSYMS_FOUND XCB_KEYSYMS_INCLUDE_DIR XCB_KEYSYMS_LIBRARIES +# XCB_XTEST_FOUND XCB_XTEST_INCLUDE_DIR XCB_XTEST_LIBRARIES +# +# Copyright (c) 2012 Fredrik Höglund +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +IF (NOT WIN32) + IF (XCB_INCLUDE_DIR AND XCB_LIBRARIES) + # In the cache already + SET(XCB_FIND_QUIETLY TRUE) + ENDIF (XCB_INCLUDE_DIR AND XCB_LIBRARIES) + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_XCB QUIET xcb xcb-util xcb-composite xcb-xfixes xcb-damage xcb-render xcb-randr + xcb-shape xcb-dri2 xcb-glx xcb-shm xcb-xv xcb-sync + xcb-xtest xcb-icccm xcb-ewmh xcb-image xcb-renderutil xcb-keysyms) + + SET(XCB_DEFINITIONS ${PKG_XCB_CFLAGS}) + + FIND_PATH(XCB_XCB_INCLUDE_DIR NAMES xcb/xcb.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_COMPOSITE_INCLUDE_DIR NAMES xcb/composite.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_XFIXES_INCLUDE_DIR NAMES xcb/xfixes.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_DAMAGE_INCLUDE_DIR NAMES xcb/damage.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_RENDER_INCLUDE_DIR NAMES xcb/render.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_RANDR_INCLUDE_DIR NAMES xcb/randr.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_SHAPE_INCLUDE_DIR NAMES xcb/shape.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_SHM_INCLUDE_DIR NAMES xcb/shm.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_SYNC_INCLUDE_DIR NAMES xcb/sync.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_IMAGE_INCLUDE_DIR NAMES xcb/xcb_image.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_RENDERUTIL_INCLUDE_DIR NAMES xcb/xcb_renderutil.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_KEYSYMS_INCLUDE_DIR NAMES xcb/xcb_keysyms.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + FIND_PATH(XCB_XTEST_INCLUDE_DIR NAMES xcb/xtest.h HINTS ${PKG_XCB_INCLUDE_DIRS}) + + FIND_LIBRARY(XCB_XCB_LIBRARIES NAMES xcb HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_COMPOSITE_LIBRARIES NAMES xcb-composite HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_DAMAGE_LIBRARIES NAMES xcb-damage HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_XFIXES_LIBRARIES NAMES xcb-xfixes HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_RENDER_LIBRARIES NAMES xcb-render HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_RANDR_LIBRARIES NAMES xcb-randr HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_SHAPE_LIBRARIES NAMES xcb-shape HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_SHM_LIBRARIES NAMES xcb-shm HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_SYNC_LIBRARIES NAMES xcb-sync HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_IMAGE_LIBRARIES NAMES xcb-image HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_RENDERUTIL_LIBRARIES NAMES xcb-render-util HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_KEYSYMS_LIBRARIES NAMES xcb-keysyms HINTS ${PKG_XCB_LIBRARY_DIRS}) + FIND_LIBRARY(XCB_XTEST_LIBRARIES NAMES xcb-xtest HINTS ${PKG_XCB_LIBRARY_DIRS}) + + set(XCB_INCLUDE_DIR ${XCB_XCB_INCLUDE_DIR} ${XCB_COMPOSITE_INCLUDE_DIR} ${XCB_XFIXES_INCLUDE_DIR} + ${XCB_DAMAGE_INCLUDE_DIR} ${XCB_RENDER_INCLUDE_DIR} ${XCB_RANDR_INCLUDE_DIR} + ${XCB_SHAPE_INCLUDE_DIR} ${XCB_SHM_INCLUDE_DIR} ${XCB_SYNC_INCLUDE_DIR} + ${XCB_IMAGE_INCLUDE_DIR} ${XCB_RENDERUTIL_INCLUDE_DIR} ${XCB_KEYSYMS_INCLUDE_DIR} + ${XCB_XTEST_INCLUDE_DIR}) + + set(XCB_LIBRARIES ${XCB_XCB_LIBRARIES} ${XCB_COMPOSITE_LIBRARIES} ${XCB_XFIXES_LIBRARIES} + ${XCB_DAMAGE_LIBRARIES} ${XCB_RENDER_LIBRARIES} ${XCB_RANDR_LIBRARIES} + ${XCB_SHAPE_LIBRARIES} ${XCB_SHM_LIBRARIES} ${XCB_SYNC_LIBRARIES} + ${XCB_IMAGE_LIBRARIES} ${XCB_RENDERUTIL_LIBRARIES} ${XCB_KEYSYMS_LIBRARIES} + ${XCB_XTEST_LIBRARIES}) + + list(REMOVE_DUPLICATES XCB_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_XCB DEFAULT_MSG XCB_XCB_LIBRARIES XCB_XCB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_COMPOSITE DEFAULT_MSG XCB_COMPOSITE_LIBRARIES XCB_COMPOSITE_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_DAMAGE DEFAULT_MSG XCB_DAMAGE_LIBRARIES XCB_DAMAGE_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_XFIXES DEFAULT_MSG XCB_XFIXES_LIBRARIES XCB_XFIXES_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_RENDER DEFAULT_MSG XCB_RENDER_LIBRARIES XCB_RENDER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_RANDR DEFAULT_MSG XCB_RANDR_LIBRARIES XCB_RANDR_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_SHAPE DEFAULT_MSG XCB_SHAPE_LIBRARIES XCB_SHAPE_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_SHM DEFAULT_MSG XCB_SHM_LIBRARIES XCB_SHM_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_SYNC DEFAULT_MSG XCB_SYNC_LIBRARIES XCB_SYNC_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_IMAGE DEFAULT_MSG XCB_IMAGE_LIBRARIES XCB_IMAGE_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_RENDERUTIL DEFAULT_MSG XCB_RENDERUTIL_LIBRARIES XCB_RENDERUTIL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_KEYSYMS DEFAULT_MSG XCB_KEYSYMS_LIBRARIES XCB_KEYSYMS_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB_XTEST DEFAULT_MSG XCB_XTEST_LIBRARIES XCB_XTEST_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB DEFAULT_MSG XCB_LIBRARIES XCB_INCLUDE_DIR) + + MARK_AS_ADVANCED( + XCB_INCLUDE_DIR XCB_LIBRARIES + XCB_XCB_INCLUDE_DIR XCB_XCB_LIBRARIES + XCB_COMPOSITE_INCLUDE_DIR XCB_COMPOSITE_LIBRARIES + XCB_DAMAGE_INCLUDE_DIR XCB_DAMAGE_LIBRARIES + XCB_XFIXES_INCLUDE_DIR XCB_XFIXES_LIBRARIES + XCB_RENDER_INCLUDE_DIR XCB_RENDER_LIBRARIES + XCB_RANDR_INCLUDE_DIR XCB_RANDR_LIBRARIES + XCB_SHAPE_INCLUDE_DIR XCB_SHAPE_LIBRARIES + XCB_SHM_INCLUDE_DIR XCB_SHM_LIBRARIES + XCB_SYNC_INCLUDE_DIR XCB_SYNC_LIBRARIES + XCB_IMAGE_INCLUDE_DIR XCB_IMAGE_LIBRARIES + XCB_RENDERUTIL_INCLUDE_DIR XCB_RENDERUTIL_LIBRARIES + XCB_KEYSYMS_INCLUDE_DIR XCB_KEYSYMS_LIBRARIES + XCB_XTEST_INCLUDE_DIR XCB_XTEST_LIBRARIES + ) + +ENDIF (NOT WIN32) diff --git a/cmake/modules/PkgConfigGetVar.cmake b/cmake/modules/PkgConfigGetVar.cmake new file mode 100644 index 00000000..7d03512e --- /dev/null +++ b/cmake/modules/PkgConfigGetVar.cmake @@ -0,0 +1,32 @@ +include(UsePkgConfig) + +MACRO(PKGCONFIG_GETVAR _package _var _output_variable) + SET(${_output_variable}) + + # if pkg-config has been found + IF(PKGCONFIG_EXECUTABLE) + + EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull ) + + # and if the package of interest also exists for pkg-config, then get the information + IF(NOT _return_VALUE) + + EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable ${_var} OUTPUT_VARIABLE ${_output_variable} ) + + ENDIF(NOT _return_VALUE) + + ENDIF(PKGCONFIG_EXECUTABLE) + +ENDMACRO(PKGCONFIG_GETVAR _package _var _output_variable) + +macro(dbus_add_activation_service _sources) + #PKGCONFIG_GETVAR(dbus-1 session_bus_services_dir _install_dir) + foreach (_i ${_sources}) + get_filename_component(_service_file ${_i} ABSOLUTE) + string(REGEX REPLACE "\\.service.*$" ".service" _output_file ${_i}) + set(_target ${CMAKE_CURRENT_BINARY_DIR}/${_output_file}) + configure_file(${_service_file} ${_target}) + install(FILES ${_target} DESTINATION ${DBUS_SERVICES_INSTALL_DIR} ) + #install(FILES ${_target} DESTINATION ${_install_dir}) + endforeach (_i ${ARGN}) +endmacro(dbus_add_activation_service _sources) diff --git a/cmake/modules/UnixAuth.cmake b/cmake/modules/UnixAuth.cmake new file mode 100644 index 00000000..0347251d --- /dev/null +++ b/cmake/modules/UnixAuth.cmake @@ -0,0 +1,55 @@ +macro_optional_find_package(PAM) + +include(CheckFunctionExists) +include(CheckLibraryExists) +include(CheckIncludeFiles) + +set(UNIXAUTH_LIBRARIES) +set(UNIXAUTH_INCLUDE_DIRS) + +set(SHADOW_LIBRARIES) +check_function_exists(getspnam found_getspnam) +if (found_getspnam) + set(HAVE_GETSPNAM 1) +else (found_getspnam) + macro_push_required_vars() + set(CMAKE_REQUIRED_LIBRARIES -lshadow) + check_function_exists(getspnam found_getspnam_shadow) + if (found_getspnam_shadow) + set(HAVE_GETSPNAM 1) + set(SHADOW_LIBRARIES shadow) + check_function_exists(pw_encrypt HAVE_PW_ENCRYPT) # ancient Linux shadow + else (found_getspnam_shadow) + set(CMAKE_REQUIRED_LIBRARIES -lgen) # UnixWare + check_function_exists(getspnam found_getspnam_gen) + if (found_getspnam_gen) + set(HAVE_GETSPNAM 1) + set(SHADOW_LIBRARIES gen) + endif (found_getspnam_gen) + endif (found_getspnam_shadow) + macro_pop_required_vars() +endif (found_getspnam) + +set(CRYPT_LIBRARIES) +check_library_exists(crypt crypt "" HAVE_CRYPT) +if (HAVE_CRYPT) + set(CRYPT_LIBRARIES crypt) + check_include_files(crypt.h HAVE_CRYPT_H) +endif (HAVE_CRYPT) + +if (PAM_FOUND) + + set(HAVE_PAM 1) + set(UNIXAUTH_LIBRARIES ${PAM_LIBRARIES}) + set(UNIXAUTH_INCLUDE_DIRS ${PAM_INCLUDE_DIR}) + +else (PAM_FOUND) + + if (HAVE_GETSPNAM) + set(UNIXAUTH_LIBRARIES ${SHADOW_LIBRARIES}) + endif (HAVE_GETSPNAM) + if (NOT HAVE_PW_ENCRYPT) + set(UNIXAUTH_LIBRARIES ${UNIXAUTH_LIBRARIES} ${CRYPT_LIBRARIES}) + endif (NOT HAVE_PW_ENCRYPT) + +endif (PAM_FOUND) diff --git a/config-X11.h.cmake b/config-X11.h.cmake new file mode 100644 index 00000000..b7975d5e --- /dev/null +++ b/config-X11.h.cmake @@ -0,0 +1,41 @@ +/* Define if you have the XRandR extension */ +#cmakedefine HAVE_XRANDR 1 + +/* Define if you have the XDamage extension */ +#cmakedefine HAVE_XDAMAGE 1 + +/* Define if you have the XKB extension */ +#cmakedefine HAVE_XKB 1 + +/* Define if you have the Xinerama extension */ +#cmakedefine HAVE_XINERAMA 1 + +/* Define if you have the XSHM (MIT SHM) extension */ +#cmakedefine HAVE_XSHM 1 + +/* Define if you have the XComposite extension */ +#cmakedefine HAVE_XCOMPOSITE 1 + +/* Define to 1 if you have Xcursor */ +#cmakedefine HAVE_XCURSOR 1 + +/* Define if you have the xf86misc extension */ +#cmakedefine HAVE_XF86MISC 1 + +/* Define if you have the XFixes extension */ +#cmakedefine HAVE_XFIXES 1 + +/* Define if you have the XTest extension */ +#cmakedefine HAVE_XTEST 1 + +/* Define if your system has XRender support */ +#cmakedefine HAVE_XRENDER 1 + +/* Define if you have OpenGL */ +#cmakedefine HAVE_OPENGL 1 + +/* Define if you have the XSync extension */ +#cmakedefine HAVE_XSYNC 1 + +/* Define if you have XRandR 1.3 */ +#cmakedefine HAS_RANDR_1_3 1 diff --git a/config-unix.h.cmake b/config-unix.h.cmake new file mode 100644 index 00000000..ddb49b68 --- /dev/null +++ b/config-unix.h.cmake @@ -0,0 +1,35 @@ +/* Defines if you have PAM (Pluggable Authentication Modules) */ +#cmakedefine HAVE_PAM 1 + +/* Define if your PAM headers are in pam/ instead of security/ */ +#cmakedefine HAVE_PAM_PAM_APPL_H 1 + +/* Define if your PAM expects a conversation function with const pam_message (Solaris) */ +#cmakedefine PAM_MESSAGE_CONST 1 + +/* The PAM service to be used by kdm */ +#cmakedefine KDM_PAM_SERVICE ${KDM_PAM_SERVICE} + +/* The PAM service to be used by kscreensaver */ +#cmakedefine KSCREENSAVER_PAM_SERVICE ${KSCREENSAVER_PAM_SERVICE} + +/* Defines if your system has the getspnam function */ +#cmakedefine HAVE_GETSPNAM 1 + +/* Defines if your system has the crypt function */ +#cmakedefine HAVE_CRYPT 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_CRYPT_H 1 + +/* Define to 1 if you have the `pw_encrypt' function. */ +#cmakedefine HAVE_PW_ENCRYPT 1 + +/* Define to 1 if you have the `getpassphrase' function. */ +#cmakedefine HAVE_GETPASSPHRASE 1 + +/* Define to 1 if you have the `vsyslog' function. */ +#cmakedefine HAVE_VSYSLOG 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIMITS_H 1 diff --git a/config-workspace.h.cmake b/config-workspace.h.cmake new file mode 100644 index 00000000..90959bf3 --- /dev/null +++ b/config-workspace.h.cmake @@ -0,0 +1,159 @@ +/* config-workspace.h. Generated by cmake from config-workspace.h.cmake */ + +#cmakedefine HAVE_QIMAGEBLITZ + +/* Define if you have DPMS support */ +#cmakedefine HAVE_DPMS 1 + +/* Define if you have the DPMSCapable prototype in */ +#cmakedefine HAVE_DPMSCAPABLE_PROTO 1 + +/* Define if you have the DPMSInfo prototype in */ +#cmakedefine HAVE_DPMSINFO_PROTO 1 + +/* Defines if your system has the libfontconfig library */ +#cmakedefine HAVE_FONTCONFIG 1 + +/* Defines if your system has the freetype library */ +#cmakedefine HAVE_FREETYPE 1 + +/* Define if you have gethostname */ +#cmakedefine HAVE_GETHOSTNAME 1 + +/* Define if you have the gethostname prototype */ +#cmakedefine HAVE_GETHOSTNAME_PROTO 1 + +/* Define to 1 if you have the `getpeereid' function. */ +#cmakedefine HAVE_GETPEEREID 1 + +/* Defines if you have Solaris' libkstat */ +/* #undef HAVE_KSTAT */ + +/* Define if you have long long as datatype */ +#cmakedefine HAVE_LONG_LONG 1 + +/* Define to 1 if you have the `nice' function. */ +#cmakedefine HAVE_NICE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SASL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SASL_SASL_H 1 + +/* Define to 1 if you have the `setpriority' function. */ +#cmakedefine HAVE_SETPRIORITY 1 + +/* Define to 1 if you have the `sigaction' function. */ +#cmakedefine HAVE_SIGACTION 1 + +/* Define to 1 if you have the `sigset' function. */ +#cmakedefine HAVE_SIGSET 1 + +/* Define to 1 if you have statvfs */ +#cmakedefine HAVE_STATVFS 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define if you have the struct ucred */ +#cmakedefine HAVE_STRUCT_UCRED 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_LOADAVG_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_MOUNT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STATFS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have statfs(). */ +#cmakedefine HAVE_STATFS 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_VFS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MALLOC_H 1 + +/* Define if you have unsetenv */ +#cmakedefine HAVE_UNSETENV 1 + +/* Define if you have the unsetenv prototype */ +#cmakedefine HAVE_UNSETENV_PROTO 1 + +/* Define if you have usleep */ +#cmakedefine HAVE_USLEEP 1 + +/* Define if you have the usleep prototype */ +#cmakedefine HAVE_USLEEP_PROTO 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#cmakedefine HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the Wayland libraries. */ +#cmakedefine WAYLAND_FOUND 1 + +/* KDE's default home directory */ +#cmakedefine KDE_DEFAULT_HOME "${KDE_DEFAULT_HOME}" + +/* KDE's binaries directory */ +#define KDE_BINDIR "${BIN_INSTALL_DIR}" + +/* KDE's configuration directory */ +#define KDE_CONFDIR "${CONFIG_INSTALL_DIR}" + +/* KDE's static data directory */ +#define KDE_DATADIR "${DATA_INSTALL_DIR}" + +/* Define where your java executable is */ +#undef PATH_JAVA + +/* Define to 1 if you can safely include both and . */ +#cmakedefine TIME_WITH_SYS_TIME 1 + +/* X binaries directory */ +#cmakedefine XBINDIR "${XBINDIR}" + +/* X libraries directory */ +#cmakedefine XLIBDIR "${XLIBDIR}" + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +/* type to use in place of socklen_t if not defined */ +#define kde_socklen_t socklen_t + +#define WORKSPACE_VERSION_STRING "${KDE4WORKSPACE_VERSION}" diff --git a/cursors/CMakeLists.txt b/cursors/CMakeLists.txt new file mode 100644 index 00000000..4b0da9dd --- /dev/null +++ b/cursors/CMakeLists.txt @@ -0,0 +1,13 @@ +set(cursors_folders + Oxygen_Black + Oxygen_Blue + Oxygen_White + Oxygen_Yellow + Oxygen_Zion + KDE_Classic + ) + +foreach(theme ${cursors_folders}) + install(DIRECTORY ${theme} DESTINATION ${ICON_INSTALL_DIR}) +endforeach(theme) + diff --git a/cursors/KDE_Classic/cursors/00000000000000020006000e7e9ffc3f b/cursors/KDE_Classic/cursors/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/KDE_Classic/cursors/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/00008160000006810000408080010102 b/cursors/KDE_Classic/cursors/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/KDE_Classic/cursors/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/KDE_Classic/cursors/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/KDE_Classic/cursors/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/3ecb610c1bf2410f44200f48c40d3599 b/cursors/KDE_Classic/cursors/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/KDE_Classic/cursors/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/4498f0e0c1937ffe01fd06f973665830 b/cursors/KDE_Classic/cursors/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/KDE_Classic/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/KDE_Classic/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/9081237383d90e509aa00f00170e968f b/cursors/KDE_Classic/cursors/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/9d800788f1b08800ae810202380a0822 b/cursors/KDE_Classic/cursors/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/KDE_Classic/cursors/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/X_cursor b/cursors/KDE_Classic/cursors/X_cursor new file mode 100644 index 0000000000000000000000000000000000000000..2bd051aad66022c9f4adf0a4a7d4d6c19d0e0911 GIT binary patch literal 1088 zcmbu7u?~YU3`A2F){YE}{epf?_x?d8J|6{NuqET>3=&3`$@%UnNPND_?^#d}c}f|| zS|^#a^vj*GgAYAwzh%}?BBd4V?I?k24S@l4cko6H9MujO=IiN^apuYP+0I{(`EZxm z>hG6FQc@*dv`FW@!1^8+NFk2X7sQI?J>XhB(8JGSZke7`P@b;7T;bNeh; z%p3Y1?&P?~=6OOt&`T;ne--5rSo`^~KK`X_CQi6#Zt{is)T+G|7qbwk-G~c|`aO&u z!bf`TL_ca-;{3>Wd@*vY$dQjF9+-AF`iMuJ&Lh3FW}H4%Jw0-Jrdj;TPjTIKlrOF_ XbAA_80FcwYv4Y9Evb(n<{gJr>`w8Q- literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/bottom_right_corner b/cursors/KDE_Classic/cursors/bottom_right_corner new file mode 100644 index 0000000000000000000000000000000000000000..87b5e29319b0d5cfc547289f4857c2a26f72e8cc GIT binary patch literal 1088 zcmbu5K@I{j2t}(0FfLuV^aP&9y*DuN_@=`*yausTtukQ<@ZV?ja=qX7MX|A`lx=y` zgVm$uDfHS&r`&m-t$S^gPkEsK#P_tl8GdfvzF%4e`+P6= zE`8&($C}@W&mK{WU!0-WE{Akct9_oqGw)UB+W#XBGx+CV@Ir@wKQ!G HP~>~;irOz* literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/closedhand b/cursors/KDE_Classic/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..051aa59d81fee8d95d71f0adcaa95627dde98b17 GIT binary patch literal 1088 zcmdr|F%Ezr46II$jt-8#z}L9@0~4Qb@UGf~h=llF);y`-h3q_KhjKmZg6QOGnlrC7z# z^uf%*sur8zP|^?f92NrTFPOiv$RdP5>TqF@DqM0fafC_av0&z4qbac;WFAaEK9>R2 YVE|-(KuMT680v5djOxb>aa>^q04(r-7XSbN literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/crossed_circle b/cursors/KDE_Classic/cursors/crossed_circle new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/KDE_Classic/cursors/crossed_circle @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/crosshair b/cursors/KDE_Classic/cursors/crosshair new file mode 100644 index 0000000000000000000000000000000000000000..c00bc799cafee9654f7777beeb4fe5855a6eaefc GIT binary patch literal 1088 zcmaz@E-eyZ00BlIWME)o`1@Z1NXr1R3KAbA2T}*Z>`-h3q;Y}&Kme2jQ6QRR0M$3D zpFsG50|*BJ40Iea2w{*KTo|MZmmEwSVG( literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/d9ce0ab605698f320427677b458ad60b b/cursors/KDE_Classic/cursors/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/KDE_Classic/cursors/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/dnd-move b/cursors/KDE_Classic/cursors/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/dnd-no-drop b/cursors/KDE_Classic/cursors/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/KDE_Classic/cursors/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/dnd-none b/cursors/KDE_Classic/cursors/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/e-resize b/cursors/KDE_Classic/cursors/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/KDE_Classic/cursors/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/e29285e634086352946a0e7090d73106 b/cursors/KDE_Classic/cursors/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/KDE_Classic/cursors/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/KDE_Classic/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/fleur b/cursors/KDE_Classic/cursors/fleur new file mode 100644 index 0000000000000000000000000000000000000000..d4332ba8505bed4c9ae397ab8c21399cdbf80e1d GIT binary patch literal 1088 zcmbV|u?~YU3`E^dj2#&|@&$Yid;g#kpI?E`%Avy~QmBz*Y~Q;eme2Zq8RFrO+0%a8 z==JS6Nsk?L$f4xywG~^6maa7i?z>1@wX}Jzta@Z!t*^1Y9)&ge-plt>lkeue+_T5s zdBz?dvGfD4(#H7ijQZZ1@9yQOBaiy;%()19lp6oV7so$=C~E?gLs@DIh8AA*5bFG@ a9ORnxI1|^d=F!X2O+D_i@BpJh-&}VdBxN%I literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/forbidden b/cursors/KDE_Classic/cursors/forbidden new file mode 100644 index 0000000000000000000000000000000000000000..b843aa083a6bd206ebf14a3dd521405c2eaab1f2 GIT binary patch literal 1664 zcma)3I}XAy3=ND-3=9m6oPg7?a|0xfkAh$Ei(VY3iYwR2`!#K!uh08jPzSq8IhJp| z+PqocWe@J+eX@yuSnpMx)Sf5f7-L+`TKLS~VbEq78Rpu~ubV6jm{!aMrx{#3-pyMw(2&q+*C`QVjc~sy$dmkY0FHfn6Edz;;WhPprFq@ z%4NJ^!?#k8uOVxtyn)zu|48|b{PXGg7^ZK50U x07NYyho|3_{OqhTb5*Cg@UVC$@;0XhkC995+G!Sv>>T-11casQ=pDqAJiZ|Py=Xy_s7H}oL-jXccs8+cgg2Rz_?iR7*S zm8-wuA4>mgqAF5#T2%I9{f` zNJyUv3=5cjt%q=VK|rb3NaoDyq#o#JuwE&eJ2<)z>)R;yU>g)Z=l~mzk!-J@CA7laYX8${39!MQZ|gtPwe*{$olzilW08fhzzo) z8TvxL-Clc7q_QJYV>#v0J0SovyPk^edLq_p;Td=E{O|g^bg#jFON|k-)E-Yyi;3#q z^Y0A$=~4B;eyz%&mc#Q_|G5j#*Ea0)2rB0p=Oxc&-)7S5xw0mM0y%17qDA0~uu?k! Df=~>F literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/hand2 b/cursors/KDE_Classic/cursors/hand2 new file mode 100644 index 0000000000000000000000000000000000000000..1e9cf9c04e06c0eeb13313ca203b791d1b92482f GIT binary patch literal 1088 zcmb79%MHR%3=2%akpo92U>fdhP>JzTiPM+LjZB_MmF8zVdC%8-xftx^pV`?y>(%4U z{Z2Jzz-?Hd%^vQsbz&Pz|3QUB=L4e!=IcZImqxcAvozcXQ%6)x)-`q-&;=eL{U3gE zD~Ic`LcYOg?SA5hB=BtAe#h|{@xFm)iNpRRRBr7b1PF|j%A`fizDH>Q`C#X$ToS2S YHMk~Nn-)&o(-Oq6Xb8l-H8dpf3l|E&$N&HU literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/help b/cursors/KDE_Classic/cursors/help new file mode 100644 index 0000000000000000000000000000000000000000..5bcc999e9a05d7006b5fcd646f730de1cde89670 GIT binary patch literal 4160 zcmeH`F%H5o3`GkkU}Rum-~^n8of{x=d{koNZ~cVCDkv2U2?9H@^WU#kF4y~QH_6(h z&ophP$GlJRkiI9{OYLai6m*?mVYcnBg76o6n1l7@1E}H>57KCT)oArkZ783#tM{qy z{Yco8^;I<*hmg@|T3M@U`ZF^ls%0YWjdJ;?^bj$kS{s>F80|TGh!{~VqqH~9EE9N$ z7*VZ_%qk@|+p`B0aJvIrq#)aj@Bl6@*}1-#=7n39=2b3hQ?8oEs{S9ALaERB!oiZ9 zda`s4KJj1y&zG@f)05JaO`XlH3*=?OfIy*Cg%zQh^H!;p9bHw>Hkuz}6CpT`(njZO${xZ&i;`4nj#vg?JRd`@93}n~SrM+DT@~-7UilXOnqhHi1rKFGc;$wZ&~+!#Hs1YW1r?4 S$ECO0-#HP^!|jT=wcZ!5*j70J literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/move b/cursors/KDE_Classic/cursors/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/KDE_Classic/cursors/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/n-resize b/cursors/KDE_Classic/cursors/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/KDE_Classic/cursors/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/not-allowed b/cursors/KDE_Classic/cursors/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/KDE_Classic/cursors/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/openhand b/cursors/KDE_Classic/cursors/openhand new file mode 100644 index 0000000000000000000000000000000000000000..953b8e7eb78612a78c0e7b05e468f093dc8cbd4b GIT binary patch literal 1088 zcmb`Cu@1s83`A2V#*Pe(d;wp>&L33b^HI2qa@DmmsfD;Ib#32s+{g2^%!QiplyWNX zdO^J6+$?90KAv+wcfQ#Zf)MrKe$dcuwT{bh61oyXAu#1qk zgOWY(_5LHP-@WpA^gh2wxpUF?o~Os>MT}~lMQBnv9YOIfSDK{};Lm)(YLCq=s@^ zql|yv%DarJ>6eSPQ}#cMpHvi#{T&$`$SIQB?ZcRQ={Mityvi{&XT3A-l4IRfuV}Pg f^&r^~ifdhP>JzTiPM+LjZB_MmF8zVdC%8-xftx^pV`?y>(%4U z{Z2Jzz-?Hd%^vQsbz&Pz|3QUB=L4e!=IcZImqxcAvozcXQ%6)x)-`q-&;=eL{U3gE zD~Ic`LcYOg?SA5hB=BtAe#h|{@xFm)iNpRRRBr7b1PF|j%A`fizDH>Q`C#X$ToS2S YHMk~Nn-)&o(-Oq6Xb8l-H8dpf3l|E&$N&HU literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/progress b/cursors/KDE_Classic/cursors/progress new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/KDE_Classic/cursors/progress @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/question_arrow b/cursors/KDE_Classic/cursors/question_arrow new file mode 100644 index 0000000000000000000000000000000000000000..f2ea8eccdc00893efc8009411b408db9f9831e91 GIT binary patch literal 768 zcmaivK@NgY3`C0w35gq*E?9a3PQ%_Cn0S1GGqpqd>sN;~ZKtmV*8B5uF>1hLcCu~1 zBF~6h>Nz_j$c~5!u^_Vcj`CbJG1MOszA*d7X;*yZ*h^xWC3);oABx_;tFnOH5?opO z|GeG}y(jNhj<>1Ggw_0mgB><@HEy!*mfSFGIHy!9heyOE22I13{teTNn^F2sst-;@ M=6`XOk3HF*Utz5kdjJ3c literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/right_ptr b/cursors/KDE_Classic/cursors/right_ptr new file mode 100644 index 0000000000000000000000000000000000000000..368a2a01140751eb8dc5ddcf3a3c1a2156b5b241 GIT binary patch literal 704 zcma*kF$#b%3>3$sW#f#M*va fyH{5+`XkU}E6=Mr4p0=GXY?ZT`0L8~W<=h8me|{& literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/right_side b/cursors/KDE_Classic/cursors/right_side new file mode 100644 index 0000000000000000000000000000000000000000..c9e333ea97ce02b386feaaaf0c843521999d2dcf GIT binary patch literal 1024 zcmb_ZK@Nj34C{8`w(ZD)BQM}JyYB~+c>YxEDxRXM9RbZKBx&pz(dTP@KN4}llhQSP z@`yYkX4i8@-W_p642T7B6uH6~Jv5m?^z^c+=cWniTOLt8eZ{q0K1FA(-GxxS#Mch> z(zB1i^I5lgo&U=8(mdiTPRq}BVbq6l${MoNTiLyT&-Ff0y?9>hckcO9M^NKoXW#$t LXOa3JdhQT5DYjNd literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/row-resize b/cursors/KDE_Classic/cursors/row-resize new file mode 120000 index 00000000..e3aa7487 --- /dev/null +++ b/cursors/KDE_Classic/cursors/row-resize @@ -0,0 +1 @@ +split_h \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/s-resize b/cursors/KDE_Classic/cursors/s-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/KDE_Classic/cursors/s-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/sb_h_double_arrow b/cursors/KDE_Classic/cursors/sb_h_double_arrow new file mode 100644 index 0000000000000000000000000000000000000000..e97017121a3dbcfc453e3ec336cc74260eff96a4 GIT binary patch literal 604 zcmb78%L;%n467oDCp~)b=ok1k-u(l?&zG5&MXD4Z9a+|vEc%dJh($ literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/sb_v_double_arrow b/cursors/KDE_Classic/cursors/sb_v_double_arrow new file mode 100644 index 0000000000000000000000000000000000000000..a7a28081e54f92c7fe5c896f855ed838c2e70528 GIT binary patch literal 604 zcmchRI}U&_3_}A#LQF6+FmeJ;!_EzmI6f+NzflS+Ms8^Qnsz^~a}uh-C(_F8X4C~< z)t=b^k8lU~@CIu+2zwURO0n-5gcWCVGMf9!HRp%MMV-~{{I)dDR2(ZZnV(bA@b?Gf gFOCatP4Cd{+++S`0(^0-6_au@l;vz5sKVL&0bUj7l>h($ literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/size_all b/cursors/KDE_Classic/cursors/size_all new file mode 100644 index 0000000000000000000000000000000000000000..d4332ba8505bed4c9ae397ab8c21399cdbf80e1d GIT binary patch literal 1088 zcmbV|u?~YU3`E^dj2#&|@&$Yid;g#kpI?E`%Avy~QmBz*Y~Q;eme2Zq8RFrO+0%a8 z==JS6Nsk?L$f4xywG~^6maa7i?z>1@wX}Jzta@Z!t*^1Y9)&ge-plt>lkeue+_T5s zdBz?dvGfD4(#H7ijQZZ1@9yQOBaiy;%()19lp6oV7so$=C~E?gLs@DIh8AA*5bFG@ a9ORnxI1|^d=F!X2O+D_i@BpJh-&}VdBxN%I literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/size_bdiag b/cursors/KDE_Classic/cursors/size_bdiag new file mode 100644 index 0000000000000000000000000000000000000000..403b892f85611927d7b062c65c7f35cb03e7825b GIT binary patch literal 1088 zcmd5%I}XAy40V|p85tORf}Vz*8&u->sP&8dq9-dM85nTo`jhubp0D?QGsNPb*~LD` z-Rr}1l^JKiA+M2}*ME&;B1U(Igkzc+XCn#gY0UCr(9+2KJo92LZb;%?HGo6Zg*P$R z_v_rla^1KgOG`bFBmo5 zD@^>KqT_c49WDlq2pX&C+{5caug3j8_kgWfC$k=)Dp(%*eAS+8EtVTluFfy9ExaF4 Jc_kP9C~lde42%E( literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/size_hor b/cursors/KDE_Classic/cursors/size_hor new file mode 100644 index 0000000000000000000000000000000000000000..05ef64f7e2905b0e1f6996de2842154c287cb519 GIT binary patch literal 1088 zcmd5&I}!pR3`HwTOAAX+;A!l=fioW8+0A3~;F%2+R)&Ej?-Ljv&-d$G5C>bO9Ls09 zSiai6Ne>P>?33@i<$sOELf;m9SAR^98P=?5$?}=^ud5nbU_#^7+N)y+a zb5U>fFozs+u3W#2q@r~XP-dPKO|3(-tqzZ^bwq5*Avfx38Qsgfc*Kv~fA#-h{F}G8 fdHd~*y<9Um!Ao&iR^E}L#72%<)^oJ7+EHR}F)S-> literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/split_h b/cursors/KDE_Classic/cursors/split_h new file mode 100644 index 0000000000000000000000000000000000000000..2fc7ea9f56bd60c4d0a1b1be5d2644d2b20bd93b GIT binary patch literal 4160 zcmeH@F%AMT3F_->njTd!!3&;JAG3CGI+xM0wwS0fA zDdHedA1%u4IrGHzjP*!|@F#CE`kL=Ep->z4Z1*T(2FMe0PI>Ri-CWETQTAB7J!`F3 zbLJ^@Tk#z{hqt(tN8&;XP~LlThfBRglr1SHPrNllK8ka={87hD;(Eq-pVVP2&IzK7$IV0OiWWOx(uYxyM$pzBxE z@Jru!0aseo#@(*aV-kBA@aBnEa_Kn${MJRc*v{yo$IRQ81M2%oXB z{bgTl$q%0b zUI0gnBmK7%7dzAj(ip+G@rxI?4iKO7qn9R?A#TsVmvPje%gFiJ1AHFy_P>vs#sByE M(yTo7l77v90TgiKrT_o{ literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/top_right_corner b/cursors/KDE_Classic/cursors/top_right_corner new file mode 100644 index 0000000000000000000000000000000000000000..c28d128c45214fe3fb2a5bf0304468cd41012a7c GIT binary patch literal 1088 zcmb`DK@P$|3=t z<1z9n;+!}==7=Ezeu)@20BhESPp|R*^Xk6G{iuI}JoS6CpZXg(#0*JgyPtLUb5{SO zpP3%sfgbf+KfMgi*L9&gFY;$^uGw#%ccL5aE4TTc$2?N|fB3~;^jcSv z!MPx}Vg(>K0VTjr!>Ry>AWR=fFDd$A`f$)VY=bxuW)HGnWHvU<=<BKQ!G HP~>~;irOz* literal 0 HcmV?d00001 diff --git a/cursors/KDE_Classic/cursors/v_double_arrow b/cursors/KDE_Classic/cursors/v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/KDE_Classic/cursors/v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/w-resize b/cursors/KDE_Classic/cursors/w-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/KDE_Classic/cursors/w-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/KDE_Classic/cursors/wait b/cursors/KDE_Classic/cursors/wait new file mode 100644 index 0000000000000000000000000000000000000000..e9cc6b096600dd0fcd0b2d4adc2b0dd1a0d5bdde GIT binary patch literal 1088 zcmc&wF%E+;5DRQfbY$q*7xXpV`9Y;VA5k0O$V8WtrNZcR&c${TUi0UDOGJk+r9Lg| zgnmaoY|TCDSR-mcJyF66fd8yrBg>&*>2En(Z!6#6UUCOLj!MS%&s-;7`Z@Out)(w} z&*>2En(Z!6#6UUCOLj!MS%&s-;7`Z@Out)(w} z5JaO`XlH3*=?OfIy*Cg%zQh^H!;p9bHw>Hkuz}6CpT`(njZO${xZ&i;`4nj#vg?JRd`@93}n~SrM+DT@~-7UilXOnqhHi1rKFGc + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/cursors/Oxygen_Black/cursors/00000000000000020006000e7e9ffc3f b/cursors/Oxygen_Black/cursors/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Black/cursors/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/00008160000006810000408080010102 b/cursors/Oxygen_Black/cursors/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/03b6e0fcb3499374a867c041f52298f0 b/cursors/Oxygen_Black/cursors/03b6e0fcb3499374a867c041f52298f0 new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Black/cursors/03b6e0fcb3499374a867c041f52298f0 @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/Oxygen_Black/cursors/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Black/cursors/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/1081e37283d90000800003c07f3ef6bf b/cursors/Oxygen_Black/cursors/1081e37283d90000800003c07f3ef6bf new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Black/cursors/1081e37283d90000800003c07f3ef6bf @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/3085a0e285430894940527032f8b26df b/cursors/Oxygen_Black/cursors/3085a0e285430894940527032f8b26df new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/3085a0e285430894940527032f8b26df @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/3ecb610c1bf2410f44200f48c40d3599 b/cursors/Oxygen_Black/cursors/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Black/cursors/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/4498f0e0c1937ffe01fd06f973665830 b/cursors/Oxygen_Black/cursors/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/Oxygen_Black/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Black/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/6407b0e94181790501fd1e167b474872 b/cursors/Oxygen_Black/cursors/6407b0e94181790501fd1e167b474872 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Black/cursors/6407b0e94181790501fd1e167b474872 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/640fb0e74195791501fd1ed57b41487f b/cursors/Oxygen_Black/cursors/640fb0e74195791501fd1ed57b41487f new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/640fb0e74195791501fd1ed57b41487f @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/9081237383d90e509aa00f00170e968f b/cursors/Oxygen_Black/cursors/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/9d800788f1b08800ae810202380a0822 b/cursors/Oxygen_Black/cursors/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/X_cursor b/cursors/Oxygen_Black/cursors/X_cursor new file mode 100644 index 0000000000000000000000000000000000000000..f6865b594a95780c38ad50fdd5648f442d7aec06 GIT binary patch literal 32416 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 Wo+rlZe0;h6iSC=IFWh?m@&5sqh%9OV literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/a2a266d0498c3104214a47bd64ab0fc8 b/cursors/Oxygen_Black/cursors/a2a266d0498c3104214a47bd64ab0fc8 new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/a2a266d0498c3104214a47bd64ab0fc8 @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/alias b/cursors/Oxygen_Black/cursors/alias new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/alias @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/all-scroll b/cursors/Oxygen_Black/cursors/all-scroll new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/all-scroll @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/b66166c04f8c3109214a4fbd64a50fc8 b/cursors/Oxygen_Black/cursors/b66166c04f8c3109214a4fbd64a50fc8 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Black/cursors/b66166c04f8c3109214a4fbd64a50fc8 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/circle b/cursors/Oxygen_Black/cursors/circle new file mode 100644 index 0000000000000000000000000000000000000000..057ce294fe1bc255186dbfcead6aa321318c0470 GIT binary patch literal 32416 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 CFTS(@ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/closedhand b/cursors/Oxygen_Black/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..587d8d11db7d41a2ec37e505669ba41caee26e0e GIT binary patch literal 32416 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 KF5~}&-24~NIw*bs literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/cross b/cursors/Oxygen_Black/cursors/cross new file mode 100644 index 0000000000000000000000000000000000000000..71c82470aa4f41690965f65e25d07e5763af377b GIT binary patch literal 32416 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 vHtDF~Ia`pAK=T`S2 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 V=PwDK9E@dTU}RuqU`;dd{{eaGGxY!f literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/hand1 b/cursors/Oxygen_Black/cursors/hand1 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/hand1 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/hand2 b/cursors/Oxygen_Black/cursors/hand2 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/hand2 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/help b/cursors/Oxygen_Black/cursors/help new file mode 100644 index 0000000000000000000000000000000000000000..286a8eeb8d7fc6864b53edaf8efdbdbaa34a194b GIT binary patch literal 32416 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 ArT_o{ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/move b/cursors/Oxygen_Black/cursors/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/n-resize b/cursors/Oxygen_Black/cursors/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/not-allowed b/cursors/Oxygen_Black/cursors/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/openhand b/cursors/Oxygen_Black/cursors/openhand new file mode 100644 index 0000000000000000000000000000000000000000..7502f911f86082bdba8ebcb0a67536cf7893450c GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/pencil b/cursors/Oxygen_Black/cursors/pencil new file mode 100644 index 0000000000000000000000000000000000000000..43c29d9095982b187b1295f0eccb0b4dcfcde2d2 GIT binary patch literal 32416 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 R9N9ix#e#hwZp#EO{{w&GWuyQA literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/pirate b/cursors/Oxygen_Black/cursors/pirate new file mode 100644 index 0000000000000000000000000000000000000000..a7f82c4ca40772856d94b85843c6d3ac7b6c1748 GIT binary patch literal 32416 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 J1V#dZe*@DYlOzBD literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/pointer b/cursors/Oxygen_Black/cursors/pointer new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/pointer @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/pointing_hand b/cursors/Oxygen_Black/cursors/pointing_hand new file mode 100644 index 0000000000000000000000000000000000000000..dc9f77e89484d89ccf35894ade9849c442320dfb GIT binary patch literal 32416 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 HdItUlqOiHy literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/size_fdiag b/cursors/Oxygen_Black/cursors/size_fdiag new file mode 100644 index 0000000000000000000000000000000000000000..92d0527986fdf502e561a43b8e27d5a944f11110 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/split_h b/cursors/Oxygen_Black/cursors/split_h new file mode 100644 index 0000000000000000000000000000000000000000..28df4a5bafcfaa5976d4cc6b1e4e52ba518932f9 GIT binary patch literal 32416 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 F{{WC9VV?j1 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/split_v b/cursors/Oxygen_Black/cursors/split_v new file mode 100644 index 0000000000000000000000000000000000000000..553261d9d8671b7b642373c8087edf30542516f2 GIT binary patch literal 32416 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 A3IG5A literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/text b/cursors/Oxygen_Black/cursors/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/up_arrow b/cursors/Oxygen_Black/cursors/up_arrow new file mode 100644 index 0000000000000000000000000000000000000000..cb6d683faa402aaf0dba5b6a08651e390beb532b GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/v_double_arrow b/cursors/Oxygen_Black/cursors/v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Black/cursors/v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/w-resize b/cursors/Oxygen_Black/cursors/w-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Black/cursors/w-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/wait b/cursors/Oxygen_Black/cursors/wait new file mode 100644 index 0000000000000000000000000000000000000000..a5920b57056e5f452f1eec2907841fdddc2e5ff4 GIT binary patch literal 1034800 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

Q}C_m%h|nOO7919OBf=&XIt7aM9hI}I;- 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 DFsfJ7 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/cursors/watch b/cursors/Oxygen_Black/cursors/watch new file mode 120000 index 00000000..fd80437a --- /dev/null +++ b/cursors/Oxygen_Black/cursors/watch @@ -0,0 +1 @@ +wait \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/whats_this b/cursors/Oxygen_Black/cursors/whats_this new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Black/cursors/whats_this @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Black/cursors/xterm b/cursors/Oxygen_Black/cursors/xterm new file mode 100644 index 0000000000000000000000000000000000000000..14bb5da59756c3a8de184031f6b63e8e8d1e975e GIT binary patch literal 32416 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 U3``lAGB9Oe%D|L?i^#zL0h=nQvH$=8 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Black/index.theme b/cursors/Oxygen_Black/index.theme new file mode 100644 index 00000000..a2a6d246 --- /dev/null +++ b/cursors/Oxygen_Black/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Black +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/Oxygen_Blue/cursors/00000000000000020006000e7e9ffc3f b/cursors/Oxygen_Blue/cursors/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/00008160000006810000408080010102 b/cursors/Oxygen_Blue/cursors/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/03b6e0fcb3499374a867c041f52298f0 b/cursors/Oxygen_Blue/cursors/03b6e0fcb3499374a867c041f52298f0 new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/03b6e0fcb3499374a867c041f52298f0 @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/Oxygen_Blue/cursors/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/1081e37283d90000800003c07f3ef6bf b/cursors/Oxygen_Blue/cursors/1081e37283d90000800003c07f3ef6bf new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/1081e37283d90000800003c07f3ef6bf @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/3085a0e285430894940527032f8b26df b/cursors/Oxygen_Blue/cursors/3085a0e285430894940527032f8b26df new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/3085a0e285430894940527032f8b26df @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/3ecb610c1bf2410f44200f48c40d3599 b/cursors/Oxygen_Blue/cursors/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/4498f0e0c1937ffe01fd06f973665830 b/cursors/Oxygen_Blue/cursors/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/Oxygen_Blue/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/6407b0e94181790501fd1e167b474872 b/cursors/Oxygen_Blue/cursors/6407b0e94181790501fd1e167b474872 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/6407b0e94181790501fd1e167b474872 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/640fb0e74195791501fd1ed57b41487f b/cursors/Oxygen_Blue/cursors/640fb0e74195791501fd1ed57b41487f new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/640fb0e74195791501fd1ed57b41487f @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/9081237383d90e509aa00f00170e968f b/cursors/Oxygen_Blue/cursors/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/9d800788f1b08800ae810202380a0822 b/cursors/Oxygen_Blue/cursors/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/X_cursor b/cursors/Oxygen_Blue/cursors/X_cursor new file mode 100644 index 0000000000000000000000000000000000000000..215d1b2f93927fe9d549a1f6450ac9c51fc485ac GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/a2a266d0498c3104214a47bd64ab0fc8 b/cursors/Oxygen_Blue/cursors/a2a266d0498c3104214a47bd64ab0fc8 new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/a2a266d0498c3104214a47bd64ab0fc8 @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/alias b/cursors/Oxygen_Blue/cursors/alias new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/alias @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/all-scroll b/cursors/Oxygen_Blue/cursors/all-scroll new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/all-scroll @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/b66166c04f8c3109214a4fbd64a50fc8 b/cursors/Oxygen_Blue/cursors/b66166c04f8c3109214a4fbd64a50fc8 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/b66166c04f8c3109214a4fbd64a50fc8 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/circle b/cursors/Oxygen_Blue/cursors/circle new file mode 100644 index 0000000000000000000000000000000000000000..057ce294fe1bc255186dbfcead6aa321318c0470 GIT binary patch literal 32416 zcmeI52V7Ohw*NVt1Lpt-5D<`#VvRcHWH~9YYuS_zYHk`edl?-S?^B;ND--4vUBvP?48c zhfSS3?^0d6?pGcj-Oo{OK__3fLf%9fq=K(BWV%K2XI=@;jE^(I_t)M&eU{q^H2GV+kBT6Mna&|$BtU3;Fg zvn!J?pGuW#IkQEJ?W$hA4a(WM!PvaY?$c+Iqf1?oGU+!yA(6TRdx_D$}-B0k@QQq6y zI=Th~#9s9G&rsgpHE9S9|;5(9)%sDO=kF-j6(%^IgvS zQl)yPnoP;c$te}t9KPGjEAEbi!*0sHLD_eeo7*!}^*3d`X=hjc7aN$zSYx=0ON&e=rzT$-jW0hm z7%Dz=bZqpcvvc!I2Z!pzbEhx)yJ#G+u90N@Bx@wO3ao3Tk~I>{DEXCepo9bYaX{3D z;7|W!ZSHGl=ReeBs=mw7@zskVAsznSrp>sYyLO%WOY`P~zph?A@}{R}*gk{7XDI70 z-#L1Jq_h4U@W^a_^*no>9<<|y^pC;d6~X*}rB0pUs$IL8s%OtN>diL~sd@80R>{eq zs>H;5YT?4W8Wt?L1KoGjj2Tzez=7|vuUMp-G#SM{iHGB3)r29}qZ0s%ec1Kl%1_`QB zqfzX=I?CE}C0$|nJllbcyE{8aWQK)JWS^6u#*8_GyjbWI8V3zJsv0(2s>+w2pnQA= zvL^4!wZE!dc`|#KMB2L!x({gk;;B=wt0_~isp#na?2+fN7wgBqpE zJ?eI|W--*4s%FjlK;vah%q=xwz(ExhG+Md4_tfC#7X84*rQL_l&doAd3!ZRw?f5sI zv9^uoeYC1lWh(7Bq{ffGq+!gM3$%No5?OS1ZgHD76v<}r+wHYAuqQj#s8OtH-FkzX zIrAoViW~6nGX1cGebWH;M1B74_WM3QL+HzG@Zq=yv5WNS zlZn0NFt&&UZQPJHUwcP><>z{?^YrX{u}+=&*l9Anz6OY*nVrxSx=fy1CL9 z_$RidFi+2c_x=4xtClU_rp)8$-DB9IGE|QqN1*+P>elTr`gkXD8OJ`l-Pr;Q{Ee6F zHKVIlo2SCVSF2&e&S)~)xbZ6N98(!*;W=y+zflmcjYi*k{{AEHmn}OP{_cd%6X>2y zY+XmOH3`kTG+R?t)B$wz`{=4P=7&+})pD=@cIkPi@bnyTqDGA*c$C4sb5eEcv>O}B zEac|R%SDkHN5{Yh5fKZ&>)(GPeBZC4qE18ONs!50mI1AMu<=dBhBF#ot)ne_N%xLw z(ISDd6?r0W>I!~}ZOEfsx%t0@hOW@$QtW&oA&JW0KlVrDpjyGXpS(4jgTo^uQy)y5 zCVKv$>e%rt_QKQ9cmiZX<9_U7@yPoGO(uhbXF>Z;4V^lzmNxx@4b0<7iG{m!a;np- zQl-V{oUNK%zV_Nq6&Sbx{oOgOa3x^NHHQ^j_Eelyg|FE7FVy+wtEZKRJP*7cYy+c193kgZ3zxQLm-N%|BP3ZrZ z*r4)CpYs{CH|W+a{lV8}w^7$|% zB#C}mi)^JcKdfYa?47S&F=xFw?*jwpd|av0TKao8{k-&b^#z^13&hLmEUz zZu)NW0c)@e$6&); zD0XY;kIUBvYBGh?D_3s$H}&dmRTV3qW{&&dG0K;}fsVPzSlWvmrZO)z8d?|DGLqC5Wn8z>_d%tw!{Wvs2fpI3TpvJHZQ(!Q-) zbqnc^L*F&@)D6bnP53OhNZxd?iu+cR@+!mn%-1*JYfsN5TAfn2kIy3HX9l*^qWzG& zv;O`YDJLE*WFA?q(SU8Xbk35n?KTPwO#3b%U<118C~3t;dlTFOA1Q<38Z>O8|Ah9o zGjit5eJ|fS{QQWv_}*zje)Z&h?(RP9pqJNMd^cE58OgLGf%+0zOE-F~V{@i2=-$@W z+1uMY`Il0q=MGSRIrG=bJ!Qfv3@XnThkTg>f!O1+vJBHX+s*TQ2EzE-wB4?&Q=5+T@$h24r&`ypjGr05XBl ze}(5~Xs6K76WUvEDr_C>nTI+#z46Gwp)X|!?Hi~oiL!dYi|+qf*mCkq=ipGSztPwd zS?NUCtHCxP-z}feuhSjneKcbs0{UBQ&#$bU&uwiTTwGndWSUGZ$=3>+mt~i|nzF-EvpRz&8yyxuPaE_Z>+dDd45PAGSckm97vZTy*z*l7cD@6Ax8_W}WihjrU*#M*Q zm492>AoWNe$eeW&YzAF{AAKIg+Oaw7wdjX+>h$}eYSkX!*Q(X+VWUP}SqpYx%^XI$ zNFa1eUMXV-hycFiuko+KehV&YE96_PgG2r7eyBlxDd0G;>L8iN=7TYyD}54}yvoH|FxSLT>ZVgF+pj~1GAxE&E^L8ot$d@Xm20#NUsliWM^0HN7~4< zMxQ!4g{_dZx%2-?{}$fxa&4Kc?Ui_`auUZs^Tm|x6Pz#j&N;pu$ zff5dsaG-<(B^)T>KnVw4BnQN<^=xfhFS0eot($KO)$HtoCK`>E((w7*XEN2fjBV>n zPtTSQ1=t(EG?{8$HX5t#v$rpwW-$0q#HXUreiOx|>&4~M>G7j%Y&2F*#+G&0-MtNd z1bv7Ri&sfWTh;E}r|==YtG@W+ztlJ1JW&7r-`}X4H}9!^`%bIHi?`#uH5=cvK78*8 zzlYr;+1A#zF>?0Ie9&GbU+nAx2b#^z|K{x6mhVCx_zpc4KhG^{)274fop+9_ZQIVO z_3JOH)YL0#`SNQ#|3vNFc@Lg_qB1f*R%g%N!WZ|l+O_Khaf<2q4~*u!TpMhL_5X%H z@xcFA`Gh}W2l#T!#ib*@5hGRq{)x!Te0+cA;g|Ieeva3WoqL);ulV%Jz4-O!_U)ZJ z_cnf*XYoVZp}KTg#5ESg@x3=vzNcW1uX{_cFWuqA$w1L+=37H$v$@I1Ql+98LqqW$ zdy77g!Ivf-A7%?ra`Hg@oW;L6r~k0khuG?$o70zg?AWvT0WHHHEe;>J7{2Sj&Ns7` z@G0~pw#CXtqxO$YjlX(Z`0`Ep@&l2VMfm5$;%Bv9^OLsnASWNhk6L(O<%9VBiZ69; zpK9@~7Qbro2bMGfiQkp7TeqHuAJJsKXSRV)5#JaLo^AiwRu`@|zJX74ckl7AZrus^ zG$t^nlJU2_qWP3t`CyfU*w_#8>pO^lQVM>LGx;twlJD(rpntpY-MI_j>3icZH<))* z@f}-iK z^yh43KL-7>^H;w0R{#2e12gb@N~Zk-;6wLpbmJ8hGI@rs5C6D~8}wj)Q=@e3P?EOlVK)k??uWqke|D7Xe^=f)fG>xC!D z_<&D`{v(g$46Nf}AOU}t4>4KvozfxKKL_c+|>HHabxkz8A#jugMOgzFX)Ps_%Dyw>s=}oOrcKC zTCyy0{F7W=JACTq*5k3ke!8g-UfiCO5CHyIm(LCAf?4r2c+6^|kv2ORjd zadvLH-x{mo?*0aT+T-yJKdpui&C(#T3_W{_AAKxzjgYbWkhO-GmH)7xUhh`X%WKH} z(9l@MyR1hJ{7NTC{6kRCMC4`|kQj(A7xAkul0SZajd66W86&z5-+xUmJ9XNn#YYSp zbcz_AQ<^Wj_@j5|@UAw01_bnnN3Y*!-BB^WGN1KxclRzwDps6|FY-cY*s4T7{^c*1 zHGLp4DZakr(7~gC=*pIxM29~M8XO&K#YntNnKFa$ryIhWYA5kOC(wB(9>-!xOolZc zBRo8fHKq8C_hMdaPF&3M{~3+JEyW+cY11V1amr)eC~-!E2cN{3cRKWs17jcIcV3`B zXi=!eXFf)BouA(@*3Ki@r|i^XY9ua2&ib&P_aU(WJ$oKSrZY4&Zv2)u*3f(SmH8IR zKfNe){W`7Ambi**)vCqg6CY2%9e=DBB}Sx56^WgZ__GPD{lljII&bm+a&me#hIk*= zH>1H=))Bkm!3o-*34R>|V~vB6SeWSOL&(@3=GM26>A{S%$ZPD^9-r?~e2VhU>F8L! zm!IEs)^*8REQs*L3h|lej1Uc_N_E(rcL_y%s^jPCT0hp`e=L6C6VPcB@Dblj%*9D9 z#->}hOs>b^!x4CJh;`{f#(X;Kq!h;00WG#c;%yo>lvsy_+FXG@Nw1<&QTWvO(tldB z=0fK31)A(wW5;^-Ji>Z+7P3Db8U|g}=?tdAmzsA(sXG9{95d-ldT@g*k5oezcyo ze;F|1^ z#yhjQUR=?r`t8&{KI5*}sIi2&ixh2su+9;op=%gh^Wcwmh7+f!75^u^2?}bT5EZqS z{rUlPzqCzwa1NYB4zkeAr@=|q6~{p)dx>`#@A1$umGLv_k*jOVG~ztCpUCq>=B{@i zW6+>2?1d-OkG-xJpUS6m8Vv4bgMyM-k1l6TzX_dqSVMI5VPaAiLEAzZ_rwJj|0lc& z4(^Z;9la5IM+WPLeb|kJ2N%G3Wau2Sa0Y&z1}A}>DYb)rT_SCs#k??$^+c_qLV>sU zu+LIjT>)gJZ@r~CBeH1`0l!vEk3os&PgoP(BR<3%;{;`+$!^g%nuO} z??OW|^GY)N!Inje`OH~^@TP3p$b@d)He(Mt4sYH=CkqcQQO8Aa0bZR$4#YNgns=vI zx9>rA7PH=(EpeOhrjEuNDc9At`2v|Me0`^rW)t)6)@*FRuChU!W1XB{d7M5cEycO# z%(Vp-Dx@MSVz-ks4BpeOwQH|~KPg}_zPo-ki&M5mZaOD)?Yfn72aXdbe1QHw4Ii$+ z2Z=Gi#NQXed2o*Y&tm@G&wUy?XC68yR?dU?Ra<2)kyuwj_3EkERMIt6t-6{q`;Iox zy0|niR9s47+T`WcKfQA0Rm7C9(BcgxZc^f4t5#jh{%{%clZdZt(SO35prFq4yL8!x zO(c{3<@@N`Gqn90e7MS-bcMCcWpEK(;N3ZRbC9vNj=qw(HHk?H`xS32ROp!hVt*#4 zjdX9JhgOq!J$sPdtS8eozPY(|#y<3He!jjFGAmV*vk2ERzV@IGc5A3yc`fpt2Awe< z7PThfO<-WuJh5v{n|74>@ICa&S=w;}TxUF3;vVbQzk=`iWyZ-xY!(^JTj}&uGCD5- z-qg*5Hx^3J&z}bb%!Svh&|90JeJMWSG0g8`+n>!ktzTwQY0fWwP|!T$JvXqXSdUJy z#2-gQ>?W3Q4Klu(@jU)$etGkHF6&}{|ERfb+ipYGNL>6L+AguHH{p>5VPQ8I6W7r* z*T5CzCX;pG+titYye1JRRX<zyU4!8m99m8*RiH}v(Pa&Ql6)0r?`dKKBAV zka*Ku@WF}?cz%;u)a&r+G<%4hv~`*2I(QRaAaA6O(xu>*3Ev`eMX8g{{Zky<=>J3Tx0W+Zi|8 zSu}1s8;P3<=#L~TtUa3;{1iZ*i=_g-_l1eE{%s5rY_>5w+00*h7XJ2 z%UocQq0*%j;7>ARY)-LsW?pqOe}7!Q{8sp|O6vnlT<2u%$=^3wtIK+4hc=Fhu|;m0kI7wTet&y=k2@V0 zxP(4k49yakBC)Vy&lH(jOk1Wsv+?EQ6LYF;*=>}$hB_o>Smbp9dS^Xt*-SfE-p`Lt z>vO(C%oBMNRH?ERyV)uBL6?z7i8;9ju7exdxQ=c81pO>=$*Z`ol(@_Z*0Kt7_3?@O zG$3FZYvm=Bxc~^wvFPVT^ryt_jy_eGatf2i%WM3O;NUIrV;yyfoX!Iasawtgkl5&S zVuhZL+p?C;x0?llf$M4KdT85#&HM!UC5}k=B0P~87l~Q6#Jo5-oF?5G`dQ-sg*UCI zSj#HhRcGt#yZ8q`zh&5bgg+9`EHuXRF`7?2hixEWg0>2Hx! zkylIHb3lN^UvDJlrAp(xO5&SglEl{w{QNesjuhUA%!s^Lk4?&uE^_hzIU|r^<74PF2j#O_#<&#^XbEQo-NVf>Ka|>vpVu>SI%cHF6}2tze^0b z$t3eZ0+6`sWjvF!1=cce4qBHpkKFT}VUfg#`}xVaGi%^YCiz5eth~t?>vfN^FEEBz zkTwl0hd1qK=Pt7_f4jT)*&wmoWy++m&l3J5g9OT-ujwO^A$%L2ne7*QNqJx2RgVCA zL-d`DXIWP)rM{K4MX>aN#420q$0nX4ZI!t6GG*jk!I3)0VKDuYp-Ga&}&O743 zS9^I0@8#?R8Dk99QS+6(s-f2@gaZqt#I>F8yV@zp?ROyTc1o=??aXBWabbI<i`D7wD69tL6DPuEW1Bek}#(B*q>;fzi}4n)TaE>KFNyHRDEf$O4{^ zLYBrM%M!k8*A-lI!Efb!ad-ETe|2^qifj*o z7Lo6bKxj+jZ#lDVhz9)ep4q&W2UXgc5oU8g`g;IG*;F7+R{n_2$(uj6w&|pg0L?Tw zIW_%V>w7ypk6>5V9$(tqH-QID&}Z%7jmWalV38laewg-7-a9(BelFhy^I{|G#ZY_u zu%8WvSK!Yp&?UANp($_v$Qd67Lmg041A1&h(1l&w>c* z-U6g=Ed0^wVzb}XfOnzL>JeI)@}E^2=KEnfT`;@}0u`W3_GL1@c7ykTtO;fQO5uG- zcDf*RPK(dcr}jmsgHxBB>yP04n{O?3O1%Q%%`PByO5H-kJf2s2T&K|(GOXzJ{r(&d z4t4PFv!2T!=QfBO39b9VA#eU)+y##rPI!ZF>N;%>w(tK_IlteqH*t z3-ANhw7#s9Dzn!LXK(V_FPvS&+NI-P@iY9~*}2s}-Q8RKRJn3n?5=IF)pz8(e+2VS zMe<7>-N9ZUWlJ4Wm()20$a_m24i2wE+l&6`jKtgI;E|m5(H{uC);Zp~MwEGNBB%v? z*^^YqR@NAsd^^7XMPn=M&iAe^e81>~{WS_(bZhL0^)xwIKH2BWdQ-|g4x|p@ zRbTLg|D3M^O}b~|xArVJ%)SsCz3|2=A9c820c4EH9^)*y2xOgj1DphJgC#)vy*Fq9 zgm=w=$lDN*0;G(aK=Mi%QkIk{&t(l(16b?zXZ*fWr0)gKqWy&_1D!omuP^^FC#^O% z{h(d+LKcvIzXYxUY43;NV{ixD1^2Qc_wr2MNg7Ejc_gotA!SLKU4fM^zN}ZvKQtQ4 zk1PzWFDeb^Qa3>VewCAMi%#fFTUG(tYglco((YS8_GGt#@IxT?@=V@Yc_Vp5ZWe=f zAg8Q~&JX>Hbw`62)$XF!i!6;c8f$U(>68Ao+}EXTGHwYI~kjdcA`~%_KX!sz2s#*OR}4X>)zh1c?554YUOf z!IOFVNqP%^?Cf6pku#o>pj-c(X#XRN)${+0baiqH&$PF%{)4rxc#5&t2w|NY$hta^ zb#5>^)CDOx{`2gr!TKJPZ53_0T|b1tq@{4wP`9gaaiUDB(Z}2TC|l!hsjWf&T^H CFTS(@ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/closedhand b/cursors/Oxygen_Blue/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..61d924c3f3d357871d7a83127b32313b88b7509f GIT binary patch literal 32416 zcmeI5ceGd4vBwWhn%F=@0l9RfOA(|<5tWXB2m)e50j2j2N=HG8pnysh5KwwmKz=jdp5HlVm)WytX3w6zXWw2A zj2U@Z#FZz?r@wile}+=JH%R@it9!4)@%y&=J-JpCRZ4v$T^<2<;9@~hK|Mk4^@At? zS%JK%JHOA?MOhaKiV3a|T#|aG`@LTMJfn;J1&du2HEdNj+V)WGynojHrTSMz^Ltc@ z-q(F&z3iX$5r{>OW(Mu+G7RSF-j9v?p5FgJrF-~fxVQ9c}IymJ}Y-h0lqxO^b#%mJGBqUmSL0 z*fz3x*f#2>uzlRk;iWMx?fn}|2dZroto{?5W`^O7iu_Gw(*|gqybN#ZU)H;7*!O7n zuD6W(1hJnWg$F&xqF*PeVJyfU}9-FfEy{ztop zT@%}eb^U9KZj-`H>H>dBuHt!$oR;o3QS|nqjNxv1?*GwWX_-d-REW!)pug z58SDT_dCYls(!iA(!aHAa2VhG63VY3$XY(n)kiceAlkMH8wb@3FO6;)_D=0=WgUC6 zzxDOo%ZJ#VXX@ZP=|~Ta;E9uzUt>gr{OZS>!sa2347Y!*Y-w#^T}+_~89JoBD@ z-v3zFaCrXR;hBDQ0{JONkRAV&D3mYi+`V%2)y&&Ugxym*8(+S+a+GBCvGC=tCE>S+ zp0)cY(i!hRJ0`rP{y4hefv~t|wLm`dtLzejZ24dBugRMyYSyfDw0CgbJb$0xrEGY4 zLWl7B(uc#RFU}6XedRfm*|(n--#*$SEbdh;46UF4@1!Rm`32uAzxoCrF%(xQkT+^m z?TTng`|{E8UR9&t_pcfKb;$L3{>hzZ-t(Pwq)+7||Ecs3Z6n>Kf--{2f|`Q*f<~!3 z&%Eb5=}1q$la;N{>5FuvN5>Zs(B>in%meN`^PcZHDObs}y{IoMWSj8Ed|64AVM}2@ zfgE=LI|(J5Ya@vWxmPX)aw+grra)G`>(3W@n;cKZpX|WDUx@7hH*m%dVr(uX&xG3|A!{85X+b)$cbZ&oDi zp4QFgCHMmN&+HW@HorIwua_r0H=wcRLc_z`&x{DG2R5;H18PTqDPA~gu0B~p-xM!o zX4sD*FW^r-*wYmnmWozES9}*Azc5{XjK^$#_4$^$;o#hRg6Ty)QD|dsdBpc6HI{W|e!c`o(#N@|hpiy01p`r?E|nh7X<}Z}a|j{cD8v57jn* z488<>G0f@qPw#5;^k1kQpQ&x58yB*^cxT1P@Xm@+VXgcK!_-&(Yej!7cS+Q<={3=! zlgNvzKBLQd2OWt&r~$NptX*m0KTh++{$W+`Ys0gB%ZFo{C*yx%KKJf3!^7GKsvF>! z`T5HW!fQ*0s6Q5kFEv-CPrll{)O=0}Iq|-6dFi0~=y%s$`kCVk{Lvfe%d&zd)c0uH zYiu6NTpvHxn)|AT7vxLWJ*9*BNBF&AKwX3PR*ec@y!3eZTzx`24m{Rf{nE|aa$@uB zFsf0(uxa?s;oX&^O=ed0Z0plFATrfrol1bEBk!wJi{Nq96lWK&@ae|^-Drl=$EbIJ6T^;FCL9d)t%FR z0B_n1?F&nX*As895^MqgX}6Y=k7|VQzt4CdKMpwKZ^3W0Wq8vxyga70`C|^u=&tXL z&F6!>ys35}C-e<>(&4lD#rB2b!8u{1d{&b0PgOtTBf1YA2wtbU9QTW)vpb->g>zD$ zhpD$*B|nRNMZzC?gEu(iD|~5G3-jx|EPob&kB4`BBMoWEvvou>`6s8C%(jI^)TJ%a`1ihciiE%OW-|t<*DA+g#$D02(Qe!EA7wRJi1*tAwM#F z4Ikq_g_iUQ?fH1aG#eWjANc)_^btNp(vX%s=wI4%cz!=?Kfb@WmWiiCd;Dp$I%PQi zEa#y6(1GyK_g&zh9%tdb;q~(x-S9O}#jx-sV*|D7Cf1~iiAB7G) z75?dQ7TV*t-8HG5)%RS#il)!$3-?>&^L6~;0lpoab!RvOKFRKK-bs(MG5*C2zwKjN8*R`Vn+M;ZHnkTn zU94^3gU=d&JNUjjudn#5pYa-gRDSc0Z=@mZw{2);GL7z{Y{n7#s% z{ISbVhCh9iX`CG=zcYRN^5|AZAN0HNk=7%4j}IA|8t(FogD*N28YY2ve8YEcZBQQa zQU+@qlu6l)*`&qC%NP$0g;P%OhsWTx8_A2E1MR_o{e!inD;gNR=zH|Z-f3NgPY?5l zqdUMEeS?qu&8HrYLBDy&H`3rcCl7fkgR;=8luaG*Br?DlpF{lJPN1)vl6TCFg=76K z9nSa)uR^aK<8KiUbTV7O^im3U@J7#|gOF_l{pKCtyba{Rj-U+6qD;!B4*H4wjPYlH zKRgEh&B=?+$hrr>7|S}G(;mJ-$DmW-S;zfd(eC|cN2m2azj^0vAT4>wOBv}tU>#0% z9G0x0M;YUP2>zO*{2#W}mZ41ye`E}O!8#PY3;p0{_?7iK@T1?cOKnV8H(C0Aa!S{a zvu~s!EqTaG8I(ntluaGr|AzQ&YMYV)9H3>2rl*o$=O66MrUPq7|1-RPK8^J^m>rOo zTiGbAUm=Ik5uU(CL+^t-I5Tds_5$#mcYGraX~{!g%AhRl9(aiUWexGD`ef!_XPW4zwQoCUD8 zFTLX%X-G>R@-jBWJk-|8Mz1oqY}eWlb%TR&KArK)$6nW;^&4IlZKRAzEsBM$!(+Zd z)^U)G|DX+XJ6@Bf4|)&2#r`thk*qOCIWGD#j|X4ozS!{qzj?;g}X7ftw1_$9@L%`hibnG|gD%h&!1x;l?&l*%G`d`{Gwbi9z zo5lg`7W5zee@u2JGHJXc+YDY|j`h`^r^0UztT5m=@A!uOW;~=k@DMm7&-BNuvf~!^ zsA7CWozx8uDO|t_+@SOKT}d8dnF+sBYxz0G_NyNKkv5EObWvD4@CMm4Jxzx&2QfQZ z<30TGnfQeH`mgsb*P7<@2K=P;0KYk~Qhc;Teei^}&*VV%^Wi7%4{HWB4O3bdH-4d9>Yy&_Ow|nz-~vwI zb~60+*}jtwJCuCP-Kq#~5VWm*WwiRPYSHh#9o(n1x-6``Uvu7(w}gH2VZHg(VDq8; zYR~cju-^n<*1@^`0{dR@o6Kx~O~5wyawwCssUuYvby7DtfXnINu4H!6MsEZ9w77sV znZ9TuXs7-i)#RFJpUb!7;dkb2;K%sEZ-1Y>lb13mi!xJXQwMcXCw1o(cV)55+rW5% z+~a?M4>JVR!FqRVL8sCeN7L(G8Ew$qet+AH=zaDB+*3XJ(<61FzXSZ{9p6YpTJn%L zRR(2IW`=+|sEazOJ12Bk@=O@c&aUGDe?Q5Wu(B37}`q6!4pO zd?O8M$wOYspe)LyZ0hj(^z*D;UM6>FL*K%i^fSI0aDaZSU$CzZ{sljP-@M}+X-G>R z@=`{UPrM$zK4+KL;cbCt-~j!=$J+&d4*s4rq$N+1M=0xjT*2`+VVY zA=K+M$jSXe!28F*AxRUThr5pf-$BxUkkyAk-hb6AD_x+2`&{s|;KOoo-;n!ToQ}yd z{*`Fu?V_FV3hjml?ptI1179CLH10eX6BHFdGxwvpUn)Dk`l-?@NgH^^>4Gm2-{Mt* z(gOUr_(r+&jQ=11BecTjh;P^V%H{B<&R5ydhPJ{dv_C_8emh=YGMaa5xoD5}G=0Wh z&-3*j-*|Zev?{3>+VWa+>r}f$G+g)gdL}=7^;4EX=tCbn-#{C9ri|7`Yd0?)tsioI z^v~qFjQ{3+i!#xsQbnWQq8od{zq5{`_aBOmtZn@iWiZJ*^fS5y+LYBA;0=AQi+=5G z9$ruD@XZQ^`JGCINzDs~5%sfQ)AIDm`y+Lu|81byY?b>{lffkKpgYhb#IaUub8WQC z+c>-3RoXYuKi{-s2zdE$18o_If)Wfj{ngo2iSgF_7xCk&c4G>H_x;)1K^{#)&4z?^|G~l_E4}lI*yCbK76h7vk!m& zoPOWYOJ2U;hlqBP!ADhpPGnHY&)Jn#w$M8nf_lBH#d>G*%_X#7M|*=)d%)H`Si|;M zv&W7-RqWMZpZKTZC-yzC@0Y#6+eWsqJ$Ozh_HJ;#z|iaSNak(|#}*IN-nen$;OyRE zQIB|!v(u@;l?07l4(4~SYWtZu|AD<^ zD|(dDT* zo@L<;$tLGJKqKu(`>zLTM*r^g@_T9=Y$*KTb#Qh&)aj&GXZ3RWpc~<7Y?W$)W{%Sn zJ+8Aokeu^zXm(Gd3vn*b-Cfc446^^6cpdg7!AtCEV*f1hJlx;VxfICU&$Wl__`2z_ ze%i4pQw)sLYVXY6r`r0=(NzzW&<5|0s^ubPMzd&_C3#ZTHcU03}EbS8& z9~_$1OLVCap1-HE@yA-xfPHF*=iP0*#qSL|n}j{meuq95yCJ#r*c$kWy_xJOWnY-b z3&CS!ZY&apU7uI+0M!+%c9-$v5uHJ?dO)MB4SW+ z*N**a>~mawZx!tiuNL!&VsK(wD8^`DDsD%6XNe1OU|-wk+v2z#*H6$I-l81JgEyfK zx(a?}JaE14GRQdi*79Mt7Z}_gsvZ4jkpi|KBs&_Z2|ws^d3Bo^yN9_1bE?{cHcp>; z-KyBWV&Yv6&6eyC$E5RUoG#zSGBvPRCid;KN7@0I_PMR)??}8TWE4G*^?fp&0O|j>d{i*Dy1rE%-!}iFN-(*nb zu?N&;kb6w4Cv0CPWfQj%^VcG~$K#;($R&HLW8Ojz=b4>Aj1jR~%N48j)a{qs{z>OCWDq2BOrAhLc_$zcMF$mCyHX%bV4vpjMj4r7?-Epj%;xrUXks0FnHE2e9 zqm%Me4&}j1#2_;M5q}Gxt-iOi?1(bq={rk>W!*~HetOeivay!-Ymgr2)DFfIY+87T zcG35=_jIr9XmhdVK@TPAu%u_Duw`V+u!l3F6a)A4-8F2yAigW!dpufvG}LfM7jd@N zD|7F%*dS=JeQX=!1LA<#yN=G~&NKYMcZ;b|oD_13-lm+_MGN*iBZtHlY<#$Z(TkWH zbQgP&iOVX#Y+E+<{ zjG?E|8?^Uyt|aduo94Sf?>q0TxVMhQUlVHt{uUReI3M=-!{gb7=aSJjY$MtZUqDl0yNDCy&bf8)4BttI+#z$E zT}L^46st{I_TRsu{r`;h(1ZAt&C=nk@2R3Ov!>CFc?q`UqTY3q^kI)WI>`5^yN*5; zakBCbw1o#Np!cEAq?T8Nor(!TKkO8)%p0(cvE2@cpO7(PAKoFBHl<65K_ZsYV@dX< zVpNDnLeAhr;(ZvC?as4)^WEc6h(RGgZ(|>U2l#*&I*UF1#O*wJ zSM4NyTB%Jn1ki^$Ku+nC)jqE7vNfg6mDW%21YAF=D&GQoEqs!Pd@S!^W`)mrirnQaS=VuxDOuS177Gi_>g(> z!d|tK^l2@c)D&O`K_7JN>FA%VvX%B-r0FBy1$;waB3sTo^c~~w?#YT_QhN@m{~2R; zPH1awGTKN!JPz0Cf$l=Tn~s+Z`EQGBP0=eIqpSRxXe7N%{5oSl_7U|bc?cRKo5=Hm zo*G-l|A1)W^kIxY6Z)Xf(aXpddcLujJ-JnJi(Mr)dE1Da)K^vQTmy6v_8Ybwbc5#^ zTTG^=cCy%AXai3mGp5r;4`PvyE{M;uv=}bwc%FHmj{jA9@{!+SfK?vlQa<%iAN5i{ zcyP`FctIc6@lV`YJxQON)h1#H&XhjLBf1Cuj-F5ZF3>-mR|;Q%7xM1BLm$HL@IAH& zb8Ym7$rQAaZG!%VM`*u|chcwRbY#+jXMpddBR%=ZZ#0suQ7+|EkIPwB9)dpTckF=2 z?}+W^6#twJ`mo0N9pA;o7MGcBw75y}5Au%OBmcxuV((&)q;(E4cPYN1jqpUwFR`9t z?D04>V$lGeEk;c=L!Xh}cnKP%_z1s9S{JE4>ZSgq9zyps?gRJ~Tn5yxvq2x^68fO$ zTY1@>2W$L6Y_j-=xhJu`-{Bp}AG!h^g#JLLV%o$u0PTks#H^ynu~{5=<~`p@2QT6K zAwT6%9_3O#a{e725kd0*x z3@>a2%EzXj+qLq!pbz>h6MgU#Ko{`gjy}ZpU<`q;uubSw=N;sMSXA_g(+1u!+GtJy z?=z>0^#r;?pl9AgC(@BVO(T^&k)C|y zryP^B1P`Hyd@N&pFg-09J2<09T2AM5Nw0T&qxSqz{p0dw{3E02X8AP!0sY4)c72o1 z`oZpC{*2AxvW3iH2f5N50)0Y%8f{Yk>3CiipAlnoEX~h+F3Q+!XB0|nb@^rr3-=GiYBE0Z$ zL*dcfaPe^qdZ8z=OZHCdY`CE(zU7^Gj)cq@->B`-hI6BB4xlwe<^ilF^2~d_8;!(A z(DiD@%6eMTN@tITP+6HgDFn712^l%9Mh zXYdf?8G1$`E@Q5P@ZFLQemkW2WcVKZX@}a@QgEj8FXkc82m6P$EnB;3SvERI z`M|<%<*bjuh4USZR?^q;xFy-r{4^k(0%c`^UV90 zMpG<3a`r6`J!Iu#gPWdKeb|dWj)4y}gErVt+a`2Q>t@=aHu?OW_R-Fq%uk&@N&C5J zmCK_AP9I|Z*AJ|3wDGyL>mJ4}=9Ad2jOpOV*kgJJ-jQ6PU-0!9ZRFd-$LD@x?mTlo z2H#0Xdh+>ME0jmMlutd>XSPsE2Qdfa{5^aLuV|fZM*A{p`p^#1qp5&-K~DWY5>1=O z`uvMMa1{lO1fAuR|JrFZt8K{?-^f-LUd%UaT+gI?;&XkFE$k5V4s%809i2GG}_yKKSGDjS-t%PEc2Hi}rg>6@6@+CwBkwE@fnMv`Wd9?7?aBLAXsQJJ)oN zcpUpBmaQ?SPtd>U8P*@51?zgO<*}yDooC+LUKph#J$eY+$Yf0A**GR0WcIXdMP&M@ z&KFAB+b`(sLdKI+pMC@Wv?J9X+C}?v;(vxdKt6$wVazeE6Tp*Q^nXo`IuEgj2^zgD z+YJ5adWSU&){hy7UH34iqnD8t^a{RV)~(kH~XKlJI}o5JLyPoGN$~L6OUu) zpm?5tOna-akIa{7s!rNvKCTt$lJ=*hv%&=FAwNLz?oI~>U z!Ik#E9Juq$d%ly7^vQFE7{~B4Lo580W*eFPI3OIDbyrw;XH`3&!f^y&@CN@>J2G^4 z*>c@XyHDpL9Xc8rV_z0DM$cCkG!V2A^w9rRIp+0q_p=UnOwd{kb5Zd=G7z8BqB%r* zOpj&jvy^PHRu12AW(#MYaOau#X&IBB9X-vO#__eObEQ&aK6HYg4(nXMwU6AS{})o! z<;m{g3BD=3!Jl@}9@<6wXeaH>34NSK=&d3G*4eQ&s|e}~=!e^DmWZC$z8kX}omRtS zAI(SR#OwOQ@>;rTWHqpUZeZum7wbS;E;{jga2c9W>!5jQ(2koI73Oiv?Y=xH14wdTXz?BJZfcAoFFHYGCcU-7!Z2fV;9g(vue zH~7;I^aky6y^|B#D4Si*L-1dcM(}2a0K2iFprxSWwZ)>DIuG@PaLjZbs^dJeL4hz` z?OD*RqMgaJQDe*Q>H1$gi?nBM^`!8H>>kc_f*v2PnXLc+@<`Y(-q<>}y`3erv`@`2 zr_;4zy!;2l>V11YkC#uq)DIrulfn!9z%xSt-bvczRIZdg(*=E;M$Si!g~%z0{w= z1AM>>{J;}@!5jRYZ_Y%nls(gxl}5-b<01TcnSe8Wh^wd~s4c*bY$<4`|Lt>!&H{Q& z>#lor2K*ngw(EyHQy%3~KJ`#vs$S{`5AXpm@B>fq1#j@Dug?Z;RE%9tBj+Xfl0Kj> zn1jHx@GkfuC!PN1(Ms}>pK>TKRW9XI5A{(m^@E4Y68JgKB<0E5q|ayV@-m@4kfc*F zJwqq@i!(;c3#tjgnQ;StZ!Vxcw+iTQWPx^e6?7AH7r+bLdFDOeNk@9}k)LuXk8&xW zdZ>?jsUJMRCo5gR+1sF>=j8J8xl34wWe6yrdZ>?jsUJMR2fVV%5_ta@7xg$K>4e-B5+LvN zAvhNoTq&R(r3LVRhMl9b zIgPkOCjk5k2%J{*XOdp%OXh{NkA6oc0DKJ&{*LdYBR%<&^q^d)3H4F0Jb$vyv_{)ByAErCFQ!-6N}c`9@n_7Hh-L ztTNzhjo9DOcmH?opY%QvIOqF^d0TnYsYqVF$(9$cHRERk^>~Wis2|*Q*i-a9=w15P z9?Cq9`I>$IFt~Krbmu=RA{*mrEiSJ!9{D;-R1bus=GqU>u z5Spg{X%qT((3IS8o;@YU%R>9Av##>ztEaI)ub(dY!A*y~MBh&6OdayheY-EvJ?mgG zEq&&Al|nad_N&=y?6O3{K0}|nkdY90khjN#^!8tDQs8Q9mSw1>dV0xZcAxr2U)GSx zkbw{t$lJ`h`>AU zGe$k^&^Ouk+ssM4UDk&6VN-)Fr`)NjEPruudu*fE%(3sSZ~6;bBUGK8b$i#YTQR%N z)o{=w=v|20RuK9w-&t>bR%kXFeUGlx?{`&i7)uz_pM~J28Dt{lUF<~YQ~nl(ghp+E9{B=oyNH!(({_=%LID+xI(a*FRWMnZS*t*I)p z0kD+-h~KDw%uHhlTWL6wg%40=6(rtQ%A56tZm<}H({J4$z~+qW3SHREr;;6 z#_WIRjAeWArxnq5B$)T{q;u3vRer=>pBHVki*y!LPqzme?0FT~pNNK<9*s?DTOhSrszvIqI8 z<00J>$ljA3H2A&D&4}4I@kZ>E?jByvD|fEsm*PL;)qC9e^_|ZAa>5dx=B+8%zlUu9 zF%$~Wckm&a9PXODB|CvXI1|sMnK8T}buGWK$Bmb6Sip-S=J503GkHNM?Ll;Tx~ICJ zf0z;b8!ii+=WgYX&TZwbIdS}6dL+M@;>Am2t#~nXr#;`f5F=sV zm*uO$Qz*HK z4Bhp4wx1S1?mU4^)_r4*dEq{`CAF{wRMNZ-wpLIuO7w z#K>%ha2IsPo;ZhecbUkeXZ8|wHy^{Yp}RJO?1y5kZfS_|`iB^@KgQ1P3*C3~XC-_2 zlfs?&4wCpC_?qIV`MhZTEZB@`o6YEV)?JO|Ls^PF)geP5-8FwD`omcuVV@Ua%b%0( zMY{#;?;Hx`MUj}N>&$t6*mRy3Y$({fU^DW#tFa>JYXQ-RP^ydkC#_-K(Uj(oV~0uq z!f0Fm1h(^}U|L}Owe~%&5tOC4U&OvU)-NUG0eUS` zXGNrcqSY{dW48w{+i1fJkoU<)en!BYY~5d*XZcKdo$d>vvk62ULVFAHJKYgKNJw{c zHMYxJk9`qt%>IwYu-#@b&xM`jttMN6-oQNDPm^bQPv%Egj>BA)`5AnUatWk6h5C~r z!y)}3wC=voy%DVVm_po*keg%+X9>o{3!35l6Ll zAK9k64SE%ICx1ixMN#*zjGNrayEx}&@+l{u9z6&>&2xCZ?--jP_8qL$( z#`EMQ!+4aLip)pK<|^fI$Yu!l532jhc{-<7EHFH>VfoZASIrpowW|*M3OQO~3}jCc z(tgRGX+ua z?$zC(w=}}bt}rsdId84EeUa6)@uv+&DWwtaq&vQwukjs~x7m!S`=mDAyK9c(&k5~S z+^6=DZVYrPi3|5DjtTZCTVk%AGks$J4D)fSB|oA&`9{*cJN=7H^A0xSIjvvImT>R# z?Xh8Hi4m(R;3v<)=CkK(3@mlgmb?!4AJbjzzbmh=;7+>lj1H=@cw68Gl*Pb@wqI*m`tF z?9KE;yKkM?xBc!K&*kN?n_`DqnpY9)C^YUqCWBf}?b~waY}%o^%ws8yk*i!PU^k_1 z3#MLo*HiiBYy8ZIwD(uyNFS5IEm?-co1DDUOao6vqh`OtaF@eA7u-5Zg$E8;<7CyRM zocA<2A@X))pi5Plv&|h3gWig!JNaKF%GJP@rKEdl?y1)5D`n5BE|=eMq3etGi1j;5{AA$MX|IW;J#?gIAU z`?wMI5%y+x>Tgwj-f*YttL)VMQrJyhe5gmG=d`|xh`YFME8*NMkg!h(SXSF``^HQ7 z8tI{(o9nl(^K0@l?5Ak{UDR8+Dk0y2T+bwU2#CvHphS$k^>HOzTdNu-@P@nkLi*Y3*p(_bZ&UujOkWZoYQeuOK^k&)= ze_*`Ad?8*L?&&Bi3I6I+fT80UCH+;|Smb?=5T~2Y2j~pSOOHMC)n_l)nXn(|Ua%qi zgV`9C)JvHSZo{r)KOfugf_)f{U~5HO2nSL2I%@IUC_8>;oh?7?VTf}f*?An{q}HF! z|Hv^SY?O=2^9D|gv+D+?fiaDJa5j3=Jntb z-aZt-E4DcBt+t~Dd~jy^S12uiKGz*%=&HZb37a^J!TjdIFxW;kZvZ}bkA?^wp$BIZ z_`@?vT$&LJo??WIn|LsgS0{V&ONkCVe!&m{AMpDgLs>fW7WXJ!rF&QR+X)-uA>TT- zUf??3I~@hSV7O4fb^CxnZ$O<`fqh|ea12fZ2V z_6EThU)>^yO~h=04^8!?GTxtFJ74jH>mk@ z#KDMZ&TSEFhvpXfoy$qf1b-vgjXX92e-_+d;&OtAn(8)*$0HsfTu2->Su?QF?rHcK zk7QBe7!s|9b7@YJz$1Pt@Q5+D&dF@23GwiiM8d`b{$_6boD%GYupyo+c$b9D2{(0~ zU?GcnsP6y+_IuPxE(JD}78(s9|D)*sSps{v5OWc<2asZK`J!|me~$eEag~YVPO+af zBZgNbE)~|Ol8CwBT*DW4`ZwMMQntRvd&QEE8??n`8c7j=1C#2LGI=rd~x~4g|fK>KU1(qW-}shpK2wjzJ~bk zw1&S1o7MOmHV~21Oy{j)+$`D-okJ;F6Kn@csb~#l-XcCxrb@i_Xeh5oKBsDzD{9kZ zK1PNM#e9Z>&Cqi`XpPGDmDMz)x=w_@`PUkbb&BkUuvrKppJM<~htN4G#f0LSF4+$0 zqDZYB8~7fxmD;Rctm`1066W{gxgjR9S|Ez`sICUM(6c^h?G|i?Vq&b{8D8o<)nx*w ze20kfYp|hn`pFRTIdqmxXR%^lgLF|OeB`m2DRPLAulk!fJ^`Zz{ei_)VO?s+1^Xz9 z`N(EyzmS1?lH=HO#vxB8e)bL6hHR)@_K-h{HbK`-b5!|>m1Fp6j|n{8Z7e@zKUz4;5#IxB zDE6cH#u`HF6#3%GkRFYVn|_}LCkunasGB7KZ-rnGwb=DL9%S~7E(npW|P8`2@ zjWJU~-JJ@L0A}L7Hf;QX1#!L1Ao>t>i0F%HPARa3D{75mc1r>fIY`Iz~P@F79FoRL;el+n)JM?xe%fm=t77K*Q2p~Bz5gTW40ddax9ctMA5N62!j=gI;PQj>Y!}F!` zl_kP_BAX#!qY0sUHj4cyz7f|ch4#gr>}FcOde23ssi=uN>bhuV8r8*pW~z~)KT>kk zZVGEAyAiR$9Qy_}ufMaI$m)8jupsmmjpy$9W9&4S$j=a;kMcO`5XyB?4HV@oL~dD+ z!^Uf|d8((~oa3lxNC!sQi)U(O5;j!7W;K!3bi`&MumLy47h`sS*h1z&OdvFu$OltB z9@z}VeUz)9J%e~Is<3N#C%ZB1-{8A+&PmksrJ^SBG%(6RtxcAQ4e&|FnM*6pDba4^ zu(8LO#dTZceo}sd_6oFi6DN^uM)bq9XXsJb_%ENAhI+@7zV-_;spfIn9KCFLY{1{C z#xrkzD~HWp*bU`tmP0zO+ccMG|4nm={0!mJ(PkvLrznkdq3=rtc4IE?8EBpIFdEPh zywWBk(AhRUz|op&LUWhTGspop$7oKG-4Hf-@2^o?`5W>#u$zw9bX>Q|X5{CRyq{4d zTF+a?6*?HH6X6L4kRyp3$ZU`I5*Ouei%?@))v>S?P$k)j4 zy%pJJ-i*!kVGSFD-3nquz4BvLdlW~ma=rkcQ)n`w-$}!qa2RPXjn`;bBpD}4bhROK8S=Q<*H-XEqKQ(Op zW{zsy9u-u&BQ~sb+lJsvRI3cXb78*zn9SMQ!?R~j8JuII(dU!EW>jA`3(u3Lx|$Y9 ztDpJkrsU0QFC`~Ll<(fW?h0zTuZ8=rD6=-2m}6m}c4n^bsN6-`{cAo2yXlCH|LieM z`;sCn4s73aC1uNoO4Q(0MF+W6EH=~3wK17=&eCvv-eSGMw>n@`^KX1{kMuVku~{{D zT+@-An<`O*e*N&yxElwyZ@h`;{a#x>S3eJXhkV-^Qwo<&8-DvW*wCIqjQzxQN*(uT zo%$%S37j{+DRpn+4LnD<`gqFLnxlIXZ*PeVs&cY4E<_A?-fp&Tk-hQgJ8y}N{2Jb4 z)~Swm6F7guz4U`SYEVCa3(o+!lXh@d-HzBb)!1_uBVSSMU}0F|G-Djq@5--JG^gHV zH$4@b+48=4wS{_f_OZQp&ZHfx%{g(PKJ$1=V{&5DEyOq%+&?ofMPBEk^Q=kayFWQ> zLae4V=cXO3E66_4ke6|+DfiUjX84?1#5iR>%Pq=1m&_@5pQ};#DPj|9qbV)OI^I~6 zo8EN(%qjeQqUC6EQhl)7l1q4&&t>dAE4&uy)PIWDgaMmkJoDmWLAJCsKkI&R?&$}3 z7C_@#Z-*<00j~tPe0J5xTEF2F!RD3NZ;h?C^kP9)%jJ^1`QNA=W8clZCqcb&K^{u9oIMym__kX;sCAXH}O~;O3?<@0)mzRZZ}+nN$b=v9431-6-MN|NZd)a+I`T(-LZ<(R}?<@nbx5OED$gCq4z$@$Yf^~IwYr;? z&+*)sm-V-+zPem|?%BRAF?aXGudmx4yQVI}&AP=+NAjs)BjnXFw=RnKoISDsE}kj# zMPqICSJ%qUKR>c7zJA}(RK(QRqKf?i{=*Oe!;1O&GgJ2_@8H~ zDO>6e?TjOQ8a8+@ZgJC=P_Fpj<%`wPXUBZ8qVF{ckB&{qulH49YKzrbv53#sfF%!T zO~-z`2DVeXe_PDm(Bn_)^eU&R{b>!S=S>L$Y;Is5PP~a_5G#n7zj@s`Lr=6D3`uB`aRZno#w|R{2R@fD zYK1(6Jb^rid=7aD`H}?KTn9F8`1BG8@dOAPJ&1@+Ps(jU?Kd|(OKLmDE#TvCHcaYn zpi1jDJ#*?2gq}MkVC1aDUQEMzC+h0yEPNqEe6)wix#?+nzc&NZ_A35=k2qjJ_y`!` zD&*V2HL1jFhs;K^li+V}8>q@$@DU3LagoSo3?W*O*Kuxo@|?nu{?$-7Gas1H{z=3~ zinYFMa4$9s@0twJfe`=5s7>f+x<{`Ow?upn74auTPBE>CyJ%5}Fq@PU0952Y~n^gcI4w z$TlI47UA+HZV6ug=$br6boNhkg>WK%4RJ|CA>8O5y+-d*be;fId~Z#}i2MiH5{;eg ziExk?x<{{lG=3Okd7CDWlZX{zAqw3SeK5WEQ*9znKX(08art@NKO^un0&ju9{{zV) BC(-}_ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/copy b/cursors/Oxygen_Blue/cursors/copy new file mode 100644 index 0000000000000000000000000000000000000000..62b899b97c93e5ac572615fbe63820f4d17ef1cf GIT binary patch literal 32416 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 T_^WH)s9UY(`lS8eu$%u4EEvN$ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/cross b/cursors/Oxygen_Blue/cursors/cross new file mode 100644 index 0000000000000000000000000000000000000000..7657e2416a24df9818328521ec30fcffae7e06ac GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/crossed_circle b/cursors/Oxygen_Blue/cursors/crossed_circle new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/crossed_circle @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/d9ce0ab605698f320427677b458ad60b b/cursors/Oxygen_Blue/cursors/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/dnd-copy b/cursors/Oxygen_Blue/cursors/dnd-copy new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/dnd-copy @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/dnd-link b/cursors/Oxygen_Blue/cursors/dnd-link new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/dnd-link @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/dnd-move b/cursors/Oxygen_Blue/cursors/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/dnd-no-drop b/cursors/Oxygen_Blue/cursors/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/dnd-none b/cursors/Oxygen_Blue/cursors/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/e-resize b/cursors/Oxygen_Blue/cursors/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/e29285e634086352946a0e7090d73106 b/cursors/Oxygen_Blue/cursors/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/Oxygen_Blue/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/fleur b/cursors/Oxygen_Blue/cursors/fleur new file mode 100644 index 0000000000000000000000000000000000000000..26ce80eed6e98f2eddc36f04bd495fcd5357c158 GIT binary patch literal 57504 zcmeI51$bS_k?)Vp%*;53G2@t-nVDhCY#C*inVFfHnLYN*crXJQN@kKt_U*piY?2LZ z_HB~s_y6_1eRU>fUqubXRv*S6BV3s_TG><1%<0AzotrP2~O4rDJ+j?FR|8LwEqO*Yiq@46RE9iXEBXJ@x#gmrtIM1s+i8>VZZVoOJ z@*kN~c%>evj3;@fR2J{;?ZaxDdz&Vh&Tn|{QlBR&FD}ofNbF@AQa17LzB<0#{BUuz zS<$7qDVx*8sHZ}LROfXj#b~hjG3Nu5>h5RXPGB59wlpC98v!?XQ zO{taUA9q#{F+2JfH=DZVHaC~|H+x6cF|7)DXJS*vlibs>sCQ@QkjiFP{}N_-(`05v z^HgSat90hZ(tc)ooph#XMz8aelpoWx#WQ)mX4X$<_6#m#wsg;Hb`N~he%{gd4YO}( zMRRCu9W$`B_kWWmw$nSNq8{tF7KOa?GioO{I|h_CXTw^Vi*q}ei*t0&?WAi*vuj8d zGoflylO?5B`LSLQ^Ftw-Q+m}~6!fkRFX#PzPUEcR-iFcUA)6J9{dxo$gDn6IN>v-Ipm< z5-+FwKQ7l)NxdA+3wp=Y*8eS#&g-UU1Lf*-;zS`{?#em54UO`9r?aK<>gl^AQOZx< zqqz6Y*h)$MQ7gB%EJ-3SRg~W!`fth1UjMhtc)wrOrHI)*w5sV^%==0=$BED9OY8NX zQ9pw@F{!ax(yoB%`=HH_%44KWT|fUSG9;$D5hG0f|GrWI<)8X&oKulHaCMb zM}zr<#`Lk3-AbCz4u+en3ws#m^TCl-ZN1-FGt_*p?=LUzXWAC=KGZvsrcB~x8(lHc zKTb_;W_AsD(_C55%}lDE@~1ROy*!yxc(vy>&uP9mG~e7_ImjFxU)yZ#lFO`Yk=h&` zSI7MP*b>9Kv8Y`k13#h8U5a_{A5y)(I=h2}YvB}NNoJN_b+XcSYk*rX9Zvyl=7TVbCA6Ch%>yXWy zozdFdSu@{7x=Znz~LRmOLF#9!oy_C>uL;mvcH!{h2&+U|Y3tQl81iOG}3>#sWl zb0}#dFLkBt-elgZc{nXuA}?)3NnV=zdA(zcTIDo*hm;yK#*9VEZKTs%~ahqb%^af2)wqo2$}XePdT} zEbnSr$h$bFej2m)?egZ-lqMR}t;{)%YsU7unQiQtolrHI(RxrNmPN+tw*2Y5rc-OD zHhU$1Z0eHR@+st?tvw5hU%h4a46kPTl=Ob7JweJi6�~MT3*u239cphgUL78YVJJ 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/forbidden b/cursors/Oxygen_Blue/cursors/forbidden new file mode 100644 index 0000000000000000000000000000000000000000..f467d7b271366426ff6850f20a2e5f9ecb361fdc GIT binary patch literal 32416 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�T7#GqY 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 C_1mcc literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/half-busy b/cursors/Oxygen_Blue/cursors/half-busy new file mode 100644 index 0000000000000000000000000000000000000000..d37fe7c36a618ee73ffa930c802aaf829fbf14a3 GIT binary patch literal 1034800 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�&cyJDEv7Y%MI=fFl5DdG9ZgjeH1PI^P5j=b> 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/watch b/cursors/Oxygen_Blue/cursors/watch new file mode 120000 index 00000000..fd80437a --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/watch @@ -0,0 +1 @@ +wait \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/whats_this b/cursors/Oxygen_Blue/cursors/whats_this new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/whats_this @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/xterm b/cursors/Oxygen_Blue/cursors/xterm new file mode 100644 index 0000000000000000000000000000000000000000..5db9b7d351ae7559389f97bb5f612aa1c6b046e6 GIT binary patch literal 32416 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 I+(QQb44~bxj zzZSwM`QRLL@v{l%2K({r1^B$uAPDMn$?FuYdh( zdj0j+$NKyGUzOmPc<)r7V`F1G9(?dY;^$7EK7H2R-Tkum(Vz0<$&)|5@WKo9?6c2a zf`=b|nDFfE@iw`iEBlg4rJ)B89{lO~=bxvWZ@!rf21D~yI3y=0FS_TRd+3QLo)F>j zC!eIpo_cC**S>wP12j!df~vkg zt+wm-V`pxnJMX@m8X6k@fY$&nyZYhn7ZkI0_rdc!A9;lK-G4uwzU?+TeakJhbMJoA zh8k+kc=K6rG&QW+e}HxX_h~(g&$&sJsaJ0qzu39C2{8u`2ISoS^0xhl>F9|QbnMtM zI(qad9X@aY%UB~b9 z2?2x=+`PR7CHk=S^17@K3%o1k(2%hC+&RJT_;C!x&fniZX>iq=vGwaW(E9c3Y2CVY zG%~V|_*z?A+as&itf%2M>&O%t^?xiaEyrn&4}#3!-%elOAXwYkUFyTu-(Tqd`fH)* zyYB?cpU0P#m9=MJXf0vR(25l+XaICrvwjQh+IN^%tsbHHq|^&8E-rDG+Tjn@;Hi-4 zXlEajNsw4r2oj9Ty{k*O_567u>Xlan$df=;-G!Yn#7VSXfBByuCdlv$7>t*4Bb0+KWAL!vDF^QNer14ncxz6Apz! zQQkIp0nM5TGqcc?wP5YwAml#y zVE7wo-*L?v0WWIe&1nC*=;R!VNzS7D$|ln5^%N2kLSbQH6d9K?nwXODDNweV_zbt} zmYkK1*NQm^nU}J0qwWu5V=jhgpOsi*ZeEl(etv$7LZUNBZ;B^VT-pzD$(i424bh`2 zZ3t=fVWbZ;Qeti;_qXe^_R+3;N_MV@Ki+{(++t^s^ZD-F~X(A(8o;f)=8Ff+V z=d@926rEi|;HNgg;<)@O3etp;TyG#%n2EFz@nh-5bw6P~M2dZ2FqSeOUpHe+9A2%J z0G_hZ8Vu#XJ$tr!lqkCUjyo(}y?hO^X`kuSs>zTygCZg#ZZ_i=9h>lyI=N&lAjCvL zVNs-vh@-HKiqVve+_!L#M1slTnvj}q=PAWJ8<&L=OKa7$`zWop_eb!z&WyYHtkvokg;mWZSwsQ_ zplx|#7HM;<$1>(FJ?o!aI^Dt!?{Ly#VQFRMq6x`}Sa9=Cs^f2x{-FKFj1BYod0 z(#+_hkm_cNowthQ3dI%cOGIq)UTxn|@*TO2Oba&r#Y!6%ZLQXaI;Cdixirn}@R-xP zNY>W9z^|#J%d2H}mwQ=lqj7rM8TG(^3M_9RRb?aTYo}9q`$Ec`)%T5!oxNGc@qBI2 z_yxvG92`Oq`G^9SKeU@9`f}0AkB7E-tR4 zu&{9BwV=Gbd}~TdO7r;K{0}>w;&E=by1IJNL>!#~!0or%s7*3-q+#|Ni$>TwL6JtuAKFm~q=f z&>uhl{B!#4Z-0ADc;}sWXv2mLqd`GI3D;`#Mt_5D(Yj^J7JBo|H|gDX-xcA54?dt1 z&TneU+Yh=9#Mk_wfk!6WBYRg}!%jJvXnntfN9NhGIFs{*LP$S3{t*v~(Zq+rRk5 zFU0Ubc_0&`JB=%BM!4tUtJob%y@qSy| zXFV@roz%+RU9k4?5v-xRTL%OP*1o=im8Yj*&QIX)Cl_hv4B?+$BKR95&YJ>4vIXk<$dn%VMU;fpR zBS*x&t+^lA0I066?!D{b`KiVNRonq{^M9Bh`8_-cx%43RllKAc25oM`IBo*&r|{b; zyz>or+)d4^4}NEB=vyvmhld3%_GQ{div%t9INI5>1?`+Uf@3wbe)@^h@w+~=`92y#;#>U2f!d7sFjyV;sSG%TEDs#ZwbjMwH(cKR`KoG8U z8toqi?gxPTJ^-H&xfJ@3NPpw?PnNB_Q zFdal6dqI1K{TRz(^mh#F*h$zB&R~oOkDs7{RclBS5?(FtpLh?&_6%#Bd0%S_{&&JW zaFQ0@g-kdIT#wy;JDtF~cna(EX~?+KXU@;+tauBFRQm~r9-gI?1gP-+dcPE#;iFMUpxCV3-6eC!9F-xu*7)(oiSKo ze`}BVDX>Ial#@zv94{mD{G9G+TDF5gqA?ms3;)-^^*}rl#9Xfh~j-X$b7d*Ea4jnpl z31Cm7E!%dmO=Bz|ARuXS^9czFOW5AAW7nRGZ5*NgWdjry7e~r)L$4qO-Q@A{f~u@c z@Buht?pT87z{``{y5c+YjGdpKht6-s?YBF)7uU`2UH;v=jhpEJ zaO5?8-@bh!?A^PUCc^H$`)Fu*HQP3R!`pCkKUi1dVbeRmX5B{Gck%gk8@Iwv5Xv@{ z`&uYq-D#N6Kt15j6ZMx zVW<6gU~m;=%r5b{&D(a7!DwQ=>~oBBT({vlVuSha?(HoJj*7BSS5;g2mzG&NDOD12 zPMfJQ>1=_$xf|qL?9rpb+&}+W82a%?q4IaX6TFu!5iI2Li}oE!Q&ZC~m#-M2O~8-! z#Lb&Gi@@`ifpsSl@Oj1XdS3s}LN5!gs;atcDaNyA!?y8fVB^coEh3FZ!#0%g%dip0 z0QrOWV4;jpu+~>q+xTZ@S=zG=ZVEmU`6ehxQ1+umpBH{h2d@b!;r# z1pM3v4Ex}QjiP;U+(tM;YuB#53|7OYH?(>!zmG3j&s#pc3BQlf2-fw+ z);R?GGbt2`UUS=*op}u4C5bd3z&bQD%Q39F#?ISduwWbW?`0x$Ha72S;aTD|uL$LsV&*lQuKk+EFSM=ZX17=6hS{Si$q> z3l;CbFYE{I>tQbqz5RBtt!-u#%auWtfu{-X;9MrhIE#RQ%r*10Z&Wy7@R z;Bo37-XdOKw0H?Mv~^QbQWCkjxka1Xy5^bRfwPN?wZ>p@i7O~{R!2o!Ik>HjK6uBqu~CptbhH;zw_j(Xm5;ertV>Z^hy#sp*5m5u#;1+Uf#HvLZ*!hYS^-AA)$ z&mM=)PU;)pPQ#n`QCsJ{OV{Bmqt3bWsIqA`VGjKS8|L+yp`b*wZPzg}A;HaobiiL-#r@bLE z(k&_}*$(zjh)hdyO}4?@)h}HtEdJA<+};`+i?|K`2*Wea2(~FHlWqEwdq5L5n1^3@ z`UFyRda-ERH^ygCdv`x27fv?iJrbYY8Td zU8uq69-ES8C-V=Gz-~N_Ki29H;J@he&t2ai8%uu_{BL^kMZpgHC4qI=s~_-5JZfj} zNa1M}6w3HTL{ofT9TnF!Q+RA9>GUBY=%F7lgoK9SzHkZ)H;^GJp3;iyDJ?DSdj|&x z`PF;DFTmfz&E4HT++_M0e@pmFc&&!cpqV?@V&NyBIDa%YR`c4}m__Q_Zwt;jKQ%lv36PUq}e4wR#aWx)9RpLrE6`{|N34 z4L6c0qnt8w3JEs9=dRMt_+`9kOZb)?B4T3Pq7svBy<|Qj|M0Ky?^!4t8y)6-@PW%` z!2jd1F>U8(pGmxXdnFcFuh|#H{+tPiv$L~Kp-}!55S~st_*t}!Pg*U77^BE&G`J$h ziH+eg>#(r!Kl-U6NtaSbny?5`$K;VQwH&mM{t9}U7ls>PG)8JSRlhEtHvK*4$=DMC%83XdXk)bO+EFqdQN=2KyD$(WCiPtnA7 z*ym~E7Z}LCH}}}&R9kPBouK)|1HLNT`UMMuANcUY((gt`J&0%%#*lmDkADoz8XR;| zM@Ku!m5C8a$vze=zt0Kn!e^&T%gFp8x_UnOghZ2{ zE`t1ke*o|g3XdVV5qmCE0%@X>NSjeX>9y^Yos;(|X6v|)X<=z;e-QXreRS@e--_p+vx%A3Y)UWqC^V&- z6a{^xicFxOgldYZT1wg3xnJAc+XqfS`?8Oi%R_lZ#iXh1BOk31`uUkOH71d;nh}g?GS~@s7*()?!cksP?Oj3%i)YosKf709$Zk0%&)7fX& z*N4CG;fJkX{Pa`P*|D+u|2g+l#Nv0})8_AeD>AK(6xF-Lz7#R(6wc z{Zj1$x84;O_(c z{iBj8Fea6Pndhb_RL<&uAlb4M{H__XA1ZRK0zy2H+S}FPi|Y>3&2pv z@5Kpo+1Ay^$G&~Vim2`rCnMIp@}}nWr=!7V{z{rvuTkiX9i*AIpK^gmZhq05kPMft z3s%|be;K#_ng5hRd{CJiL|x>k`KR1y0v$c z`oOcKy6aO)JM%1sF5GylcWP<5vr->w=j!2QWou{8GJvPil>B+I1DVVxy=lhGF>TjQ zl0~JEZ(=_GK`XuRF`bjruh?HAjr?kV5QN;c`f9tb)*B+m~RcmC^+B>|`a`Rn7j3x)4 zz(6|}cXw-hM<**=dwWa7+gM=T=W$_)1Xx>J+SuA9re&V2ncGi6vo}+4aUH4aJ1At< zA_|{BNMQ?yDQw;{3T>T7;k7Lo!)~f+nodfUs^c;|ul5D>b8z#}@yr#xX#lbPQxrs+@z=8m~}OQf2S5zbCK1m9+CmNY}HHbPEPa+r6AL?Y*R( zHj8wOdsQ=qL1xAGZKd+++OO>F?AY~wt%GAN>~r!9UPP$=dv`5bBAv5vv2<2gE%ILK7=-a}Ts|b@Q|G57gPHby4=F=yb=ltTLD4ie|UU`gV`1#tx6# z<~g1tvLSgN&5S`p0D749fZ(x+fTV{}WdmAmKJ|=7b zz&M*=WwMP@lWwEYXWHsQvu*VNtv<^}rOCi=nKl8zg;p}(YV1W?96ddU(#opN>E`aH z;CXvV4p8>&BjtQR?_N?Z*h^}hbqn{9YUM2yz3?#BiJS+3XBr>`AO$e~9ssswRJ+Oo zj;d3N&Z=~}^D3SGg3=guUY=I=7b{cz5uthR31R;538B4jolsOeOGwSH$5=`QO=y}R z^D_y~u6n`FUWFJICAR%agu|%-YVos;jS_m82Bsv~lC9DqC(0mGT0OjFXAmd#E&BRN zrPrTVa=&{01%`{C&x2imQtHFbDZ(Q^v2}3j0-o5{3R(c;%?I-o>r4Dy1>mt{0$3N$ zLSONMt9!Iyj4Kdw${U4(>S;o5S&fiUR3Rj17YR{`S%S_OF9gU#F$RCEk#4|^_4A)W z5IA;{!41IuFzq-FmisdRI94znkOyG>lOY?x_V);Y2H*#92QaVmy2*G?Ja~QJxxnij z^B3DZ`D~3bSPQoHj)JR)C+zb9LV!{wD0F(n_k;>coP$(qyn_J2$;A!$^Yh&HwSfEL z-_89oKIT4|mgc_sI=9F7@%@*rVQTT>C~=@6|G;MkzRnN@_}}AyDe%7(`2R8@Kh1;9hS%g9I$%5Yhu`k^d-m-4+2>{U zeOJ0qs@X37xd!g@*^!?wyx4F6bPLAQ@T#&mEyTI{-4D45X z#x6NU+8l;(l26j4sxsu=f!;a<(KsF#~llM{lZrtF)}i8o@2^B{q$2Yo{!_jTQFKz?=*U$eQIe0?|Pq-P&f<64Fzu~@l9&tSDMEp7S zlw%9P1Dt!ce!`>I{gGoT;g|i8{rep2cs((leBVU)-S2)U#<_4Ch;h7rpXYUBIrWVd z6%~iMPtK8I+DycW-y6s2u&=+pz5NB4O<2GFw+@9ukq#L<#(i;|?{m*RcPR(&*$Mf0 zSNqKOzxUpI;(J0n9FLs%Zy|C655a#}$9%y!^E{u3Gk<3p%`pV<#s3}aG<^8~*@1ZX zLmV5zaZ)_iYsJ(~^&8JIUOTuA_}SlsEpS{XVteByV1MjnnD9F`l-Dx~m|_*kN&ANT z;yyVB+l&+Q5XZN2i~{0v#?)$c$@R4PukL|u$rbsaf8rQgZlC+)^Nqk8h&SK5Z5#6b z)>3+A){ubQCNYQ25}`uc=`dGiGS_IAM!zxmeJ3qFYRlpM!`X;6zmWi zVZ%J<;Gk4%3swyej|~Gq&M$Zz{hD!m`st^|c)V7`Z$Qua8Zzgq{;>aqV8~6BL9Tr@ zJUlGMN%Q+*U75igpM5{({C&_XIYt{vD0BPYr=a`=B>I zigDio8r=$<&VYALfNu^1%<=IYBfk%HIsiC?>xXd9O`y>#jgKBMsUNtag)mhcYudNA$X}&f;X8*sWC^qJAtPURJq$ki%+`~QW^nTlTS9-itY11rBD7+ynX5LeE0 zIRc!pVWWMZ!5#p|;P1or1Hh5v@Q-4Tdz@qO@jg#OpS>B+4XhbK%;*TmdejOwSf{M9 zPH`N*4bC!1OC!qisRs1ly2iQ+ud!B+j?pQFt9pmFP~WDV$e(zU zb^)KApb^LT?*T0iV9$3Lv^a`=@(IM~pF+I9ShD~*UuUqFzLn$l5re&QXchJJF8m`x zmdE1~%sxmyvp>)b?0ben&w2Fh{&#^sOAj8V zq}pamtDHF&6q?p0*dT6|bp_75zfN81hR7z;hH*nYpmS)bM4FkMH*5RvT2>=I{?KXA zUJtp>0QP#juZhnjx>eQI z-Zg;rdL{I!FI)lPA6C)W)BXj{|b$mHmtvLzKK^xhM18PSU2$Tf`a_$cK0b z)9IS_Sj2#ZAxGi|&hgl~eWytCqudYocj`1vZ||U}loU!TEc(Gwtxpt!p)0AOXYu+M zfc4HZCr5Ay4;QQ;$He&E>)W?X`O-wbft<8Q9JUnkz#)T!Le?XX2sIymC{!XxA?clW zEaV3c71r(feEyyvN|6mFmUV!AIM9Ol?1ibgI>uvXh5#yIytA*UBo)TI<{Zwc}?n4FgW{fYqAb1TAO9RU1 z^eq}5Tef@!;?a+Z<7S(Y890|_Vm{5}yc+(#WyfBTKG^5|h+I_7R5U`I@*$?pij{-3 z8+By3O>-Zcw(W)uZafA!Iwt0{DA(CH-~gG7d^Euy`hgPqq)4O2Mu}H(G4gIA1Z(6! z{5$f9*D0389@q=%moFD`AAek!`PpZ}eB>s~0DU;dHt@g!!5;6#A~-lVx8yMA+pIu- z&Hls3#e5>R?X&&c4CZ<@6VK)xo;~{y(kj%I;XDTDx>wYq!2Yk+oa3-z>(6a++dK9g zB-H=lTo{hs{Ycbv%<`PqJdT%i!&v-~_X!$Fpl4bHH#J#E3kxMqdcB1AbK<%-)mxe3 z8t?h6@r*0xF6U%sBJX6z#~%y*|NN&gA5emvF*R~$oT2Mm;k^isj)<;vLtgRcY*!iC zyn}Y_*>@>-$(*yq=WW=-Uk$eGI!K%Y#BCtXx6O9zwLu)sSxn<@yckJFv zC6#p~m&>_c3fCP`n4c5ROefY2F40J*lc+K>EOqtumWqZ3D`|R$CHBb(CWPO7e4l&S z^OL`r$FpZ{99*+2ZB8@QDB!OXJmb%1(k4|kLTCZ+k6RiFhZr4Rieo)VV+{to1Z7vV+zjcg@_!Aoxs< zxNg`B3Hs2dqRhGKz%Ks4G-7##oG^(jFwjaHpI~P!uW$;hskIMGNwIeF_vbj=$z!_I zEXy5R@DAs=NABG#G$LPY<`w^MJ13=SDCNKA!%KVoU6tC zOK5P@J{pESgn{?{W?);@M3|Tt$8vf-a+|m&9NQ>1Vy+Ia+w}9ZYd2D2W--Cu!ufsY z;D5Ya=3E-k6dyoHG2g+}!^0v-tFtv^WjmRwYMk}?g?3VXh@~y|c~kL_S?)MNzm!8J z=Yn_okpFrZ`8WqLx4QA!bk9A4GxEADk?Sbtwp`9T6S1kOsd>3VYW@FGkT&UNCL#T!4EMywmTxVc$Dk+hFU&v1z@DRt4OrQ3N0%PrZC zFiCERx}bevpx_4^Rq|bT3G*OpPJnlA0ex0NE+;}4^yuvstiWGlKJ3+b$BZ!YIr`Wh zzM!uk`E)zPS{}?(W?=YakB zx@3+SnaO8f^C7D(kP~1V8Xe;tTTtj`%E@yK2nn@v;M!pmf*rW{rI&>D z$g{l*v^fRY)Bd-=2_bjiEjU3pw}8Gbu33{iyz)C{*KkL7#)*q3TaQ z5#)yt3-+9oiM{Vdedl_xL0uUm#{Lu2W!}o|)ZNo7=9h{&rl@%Uo$?aQ?p;djb{?f& z`;XA<{*g=9`5wNX{W7zcZbH6So|p@X{eI8&;4tMqOdm{A333*!f)q-J$fRVqc#b8H ziL>+Y@wH$((W^^K4@e9TMjJ;SV*yDA z01=z<4OoCj%7cErc9u z@9JZ}HzD`;63kk*jdo(MuxQ-@n$g}VUgvvIGeM*!=h$+6%SzO@%&MG8DOm*~4`Cnj z$aSJ|#uS@>{85tnt6vGyfdRo9_Hh*QyHWaZ7uXvOz<&ncTm#j1j}VWS0d%8j z^H$Ob>eQ^h;xW}UnS<`f)>0l!*>%USI$Q5i4?9sF$Vp)mixHj zLzF?tuSD*sZAf^yOI&K2t0_Lg-Zv;1Ie_p#n)wIxaez(}2p>z)6HiF?e*3NC%cG;3 zSI5Rem_7-wy(V~~4uuuxVotI4{R_mPQ~S&1@^g?y$U93T1M+S-51I3kQIC`AQR}g5 z{$h&GZ@!eTY|dTgdl>kB2F_h(8X00!k+(TR%wfj-{WEwJe0_rl(}(j^JW(e{7aHb* z979*+e>nKd6;`l|V0vAgUl-}aHC;-dep+(uyYC!-H8vLd`q)_X4$QB3@Q(-hhxenH zus6a#K*18@`H1y78&_X37aIAkA{|1ISDaWeN0c==&B(*y++pMtGjPomGq7D}+_u9s zWjY~0+F+!pJmh$17Z7TyF%3`MAa!^cG;0Yh674{VZ%b$yMy$*!%&QE}U$j;G? zw3*Yy{BOEI*IQD@MCo|pn6=)pr6j+mn!l8{TOWit?uA=W?m5JSFl zZ}2lkF8{>z0b^Tw%VhS*KNjhO`DO1X${)mxnCBO-U+_)%l$J`eZ@I;K>la@*ygxds z_?)Qsr3)9N^{^WTpgxFgVd1z<1M4Cm*NANf&ji5c_XE@~;~!n#zi>hR1ySe!jE!Zl`{o;)(1#up9Hvi~SR&4Z_ohe+##Eb9CgQbN!shUS z6m}U;c@$~WTSLUecqR^l&0O+Db zZau@q`T*t{0XpR7bB%xyQyj(D^iekSM$qUi_VeM_pvuobL8wa{ot$g}gXK=q35lGC z>}rULu|p2H1=mpy(9LLCIJ_;~x+_3M3>z5l+?Tj$RQe@#^W4bjN6KmFvL`NkVI z(v>T1?4zSCtg$~u^6t+aUH%C&=dgc30LcQ?q{v&0IsvE`5NZ_bA7~4@$$*?))ED4& z`$6-Qc<(RrwZzt!k248S~}CmMQ@0(@xcB<)SoXl!S|vbxx_`M za|rM03GRCF#gJe8@PqsxsEd7;=;Rk;W4TNJ{AZc*^l2Bb%1X<8#8CKf?VT$R*gC5; zS}g?zD<~*;8L5rQ7z^qVU`)#7dNO1+Q&cqSc*Mtl4)q>u;rIbDAUByJzl(~Fq4@ef z3Ji;#TLNc zs#;`jd&)D$%yk>AAbT9bB21`jp5q>$mf@(->a3ixKb>4d06L5pDj(*|TXaue~O%*tJVC6Y)7y=s{4`{V>LVDpYFnPw6COLX9{E z9*e@50sL1|Y3PUAL41!9xM4c|KnI!HD_~M$~_Z zAUWo!xdwz9v@zF#&?2usrg0hN7ZyS0=l%mC;OcQuoR^CtR5pQfg>zIwqDM+rF6%ya zzR;c727764jmvNWI)LEd;bG&Gkl>fIWlP$Q4?oQO{KAExQKA^sDmVgKExP^he|NqA zcfYgNK+i^EB$f(mR6r2(n(;O)V`5_8N!jYjaGj%IvRQRXP^0pu3YI1KfH^p zpPxPQt+5PPKxf;}wQV%UBnqlRo<8bgsDQf?b0D~M6(!_1Qfhhz|4)vmF6(#F7p!~X zDJiKxrlx0-Y5HpN)uV0&YH#?1cLGqmA`tZ-0=a$#YCr^sM}se8#aj1ju493^61u1a z3dM8zrIl0!y$UrynkRK3I$|xsJGOyxxl2@hBGOQ$RKHWTSJiPREe~^a)I#Ns+aKl!>)BJw4;E*l%-=<~0wsTC+YgJDV~K%Sm3l zf_&9s;dU144!9OBm;*n3khU6Ku zfM+7=l0d#jW|L<6LCP&Cq`dt63s}c9u1T1SKLR~V>^*;*3ptzEyo6*)HK-k8ARo}j z7qsyUjVAvv&>nRxf{gJb2k$6A8)Y=s0@M-F#Uzuab}?nu&q9q4)TN1uxk+pq4fEWw zLV%aOQlsVnci@To0lcTMXWnsgak)Y+PePb~w{gP%*-&R>XzR9b&-~3-U+ujxHntbE z836zEetP~w;fBxu{6?=umg2KY{`NgHE4YGrzm}fH3#|O0W1#S3$JOqF?fvEEl6q!VF)SFPC zRtf*l2TfcW>EhE#-?^QNP;aHQykZQxSU%U8;I+vP`zx2oxCC)tC8TFKX~V+BHGQJa zb2aRkw=A(IiAqhizvGD~VxRfogVr~{{Id9m(b24LM@O^&J~~?S@HgK^_P_Oxy7JEV zB63%gF=H6pd!i51P)278%ELobc`N^kZKltXG zuKWMb-}9gS_8pTG2tutDIqJkH zKpPcmmWZ`tlCntEzK(KR=2FG97K+R%IO+m=u)M*%DsaWRZVz6vbaolncbGS>b-f^MMI;EE6UH4OULlf21)s6Z3`4wHO%YXG7Y+v~`b@f!)h+1BAkAOZ= zB<1=um{&fSSALjN0iaDF-b+w?ruaWklu0?jBbW5)1r(B1N})?nQ0eS0D(P8#A-J$| z9@EB+*DKUEvU2nALF(k+T1X83GkQ%jmw0Y$e zQc_1@ox_y0_8658tf8ER%l-hlobG_a4PxD%iFVYfI-lYi(+9kbd>Zf@{2Y?V_;{Pd zf&$-^=IMr62VRU^^%UuLyiNW$eM!MLy-%vczarhHCrCT;8l?_CLbW}ssGzF(4I2j+ z5B8IYHGa6QfAher^Qf+^{aa(p3<_Ovj6CCu$LSNDN<*(jBW&JBCEVponwWpUi?=PnGC0{R|y#Hri61G`OSV;XN z(>v4KR*fbsJVe3UKPAo97fF5iRZ^b%72q8TIrAyy?S6ntRvr4mKe1?xgt>+TV!%(Tpmle0?+MQ{Og+e0tB2H*_B<=9UlE1V7BDfRsE6hEHCRS3#Q6 zMha;_y&?S198=E#nHCO_sc$uf?|hibPzSVhdg~9)o?hYq5p6`?f!!6c4uVFfvkM3| zX4SWRnKh%E6#dTu?j!xcDbj6zfHbJBq`2>|6n{7P=a%P4KeYE=-)Y^w-kIf<9)|ct zrvR1O&fQyT?cn5$xZ@~m4$Qp_!1rcHVg1?N_f zvZR5uwKFNS1vY}YOHqeuh>W0%0ri+7Iv3*q8SSJ*)Mct{o{rkfdC!_@|8Jem^ns5W z^`_Jbbxp5l!FOrsK19+bPm#WL5$U^DQ|RIy6nyAIN<8rbrQZBB8IRoifzR4~2Yd!L zZS|eIbh)gywcRtbsKgz1Cuh_oaX@WPJ9jTH8?HM%v5pfq^GI{F6zL|?j_C*B&-j6V zgX*GcXm0s#8tT9+2k#@_tZE7bUF4y3l_=hX0&-1R8)IF zpLdIhjdxLpggK!$l)bmFAOBAdHoudxpOtGZHCQD^)bXyg+VTvXaRYcywGAGvRRpX3X-kP3aPx|X0u z7wS-r{EEsJEThuJD}R&~RCc(P);D-e@0{Z~w{Nj`--c6aEidO3IDKfbcrQU;%Z=udKTIuNAFr6tL_$^6S5qREt)V zV(B{2X)U?z`jB!Kucoqj3!s;!^jpgzXF^Sp4)7y6=arPXRZna7Z0YFq?C9?G>giwV z-8ZmOx?tG~X;1$$k*8*M&6hQ`cgkv7X3EM@tE;%CUY1){Da$GS>pkG)Q+c>|=HvxpS47mytMqG*~$in>-(p?;SZ z^}Mv0S0P-J3}8TAuSk3k-0%=pwsue*^oD@IK+Xv>k9(XquKdftvwn^EGQkO~ z^#ap4u45m0FL|EAXZ4U4wa^qxN62~K`(#*u2W6pNxT${nlM-KlmBho-*V5C=*UCRY zVWZK7qxM&VV^VsKb8b<&OL@&Sw}u%V9@FuE+S=y!dbf8i@NS>iCqi4-LTT%qURg`$ zeAJxl@@bekM^@k3>0Q^-A+4D{%e$&^rnIbXx>s@aG_QinMvwf`dQ;ond&-7JC~Ngz z^4anj1!3HQm_tF;(v6vX`_;+`Q)+kU5W*7ni^Xvw7r|WS3N?$ zJ6@;6^}8u%#riL;((>mEp{8QNH^3ygxyum~;g1?&L6%aP#yTL_V6D-{*oGTZ>|^3{ zosu(3oip>QUGj<>U5hGOTuWeNAa<6KfjoN7pogNkS9q#3I?d~O2t!{izZqYQ? zjJyWaPOEW@Nvw7-L{>V48XEH2I{sAIjhc09A0S!FO33PB3WiNYQBY2*BCPYpRirDe zrjQEgh?TJIRyR^aZ4>M*O&HHKQm(v-GJDrkM|CiHCP6{M%s`-qLVOA77JoKv0aeLX~8r)u+Sf zon;puk#BE|DzrzuPlgiUDdLz$ktx@PDEw}|H=?wK zjP(mBD82ecjJpEB{K2Kin3uRVp9H`%2eHgz-MD0&`MwVSpx{@6)#~r$O66I=Ik{4G zPOeg&4GxR`+9M?9Nx?68L`ccoDm2d7FLVzc5qbu93+;>62vsfJLSE$zA-%9ch|j1H zOz{PR&X6GlD&qxjAEV&vrbld>6930T0sUN#u?EAwD~B&rAp(D9u(p=N2ctkuJQZ|} z5co4q0K_0kasXWKq>=IT4UKs@$Qb*BLZ$ivIQ|F#z9Nj{%y{EF{04meN1Pe>{_o{_ z<2SHLK4atV*N(PQ0TBQdfaeopbj5>dgm@{jwjs+Y9f0|aY03NVY5@NaFvh12PzijC zQCF`BHRx)Dl$@EEUmZeaOP5g5+#wX!G^55|y^vK>i#mZ7LPBP-5Sf@Gghb$fFKMIk zzk2nkWe0korlqAN@+tRTtyTYZ2qfxN>bK zwm&oQ_gX+D+A0R*;4{;M$I1RgHGtb@8O-y^7QnK4;=%D8e2rxj*PLRzE#t+sWV)F_ zCgN*tBSQ>mpdbs-2q+?s`4lA>ViUkGNuWoH5S5fFLPUJB5FQ;59*V?#3lscu-=0T<8woqyx8@V!h2ewKNJ z>A`KXJZ2g&zg+9!-_5}HPYu`rV0@etYRj>ps9%T}Mvl`%ESfLkL7*RFPN_sdOa!h4 p2~t0Q&_;@TT`|8nMvK=6b6+=lo*J*q@#XfXx^Jq!aO>sA{{^QANVNa} literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/a2a266d0498c3104214a47bd64ab0fc8 b/cursors/Oxygen_White/cursors/a2a266d0498c3104214a47bd64ab0fc8 new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/a2a266d0498c3104214a47bd64ab0fc8 @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/alias b/cursors/Oxygen_White/cursors/alias new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/alias @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/all-scroll b/cursors/Oxygen_White/cursors/all-scroll new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/Oxygen_White/cursors/all-scroll @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/b66166c04f8c3109214a4fbd64a50fc8 b/cursors/Oxygen_White/cursors/b66166c04f8c3109214a4fbd64a50fc8 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_White/cursors/b66166c04f8c3109214a4fbd64a50fc8 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/circle b/cursors/Oxygen_White/cursors/circle new file mode 100644 index 0000000000000000000000000000000000000000..057ce294fe1bc255186dbfcead6aa321318c0470 GIT binary patch literal 32416 zcmeI52V7Ohw*NVt1Lpt-5D<`#VvRcHWH~9YYuS_zYHk`edl?-S?^B;ND--4vUBvP?48c zhfSS3?^0d6?pGcj-Oo{OK__3fLf%9fq=K(BWV%K2XI=@;jE^(I_t)M&eU{q^H2GV+kBT6Mna&|$BtU3;Fg zvn!J?pGuW#IkQEJ?W$hA4a(WM!PvaY?$c+Iqf1?oGU+!yA(6TRdx_D$}-B0k@QQq6y zI=Th~#9s9G&rsgpHE9S9|;5(9)%sDO=kF-j6(%^IgvS zQl)yPnoP;c$te}t9KPGjEAEbi!*0sHLD_eeo7*!}^*3d`X=hjc7aN$zSYx=0ON&e=rzT$-jW0hm z7%Dz=bZqpcvvc!I2Z!pzbEhx)yJ#G+u90N@Bx@wO3ao3Tk~I>{DEXCepo9bYaX{3D z;7|W!ZSHGl=ReeBs=mw7@zskVAsznSrp>sYyLO%WOY`P~zph?A@}{R}*gk{7XDI70 z-#L1Jq_h4U@W^a_^*no>9<<|y^pC;d6~X*}rB0pUs$IL8s%OtN>diL~sd@80R>{eq zs>H;5YT?4W8Wt?L1KoGjj2Tzez=7|vuUMp-G#SM{iHGB3)r29}qZ0s%ec1Kl%1_`QB zqfzX=I?CE}C0$|nJllbcyE{8aWQK)JWS^6u#*8_GyjbWI8V3zJsv0(2s>+w2pnQA= zvL^4!wZE!dc`|#KMB2L!x({gk;;B=wt0_~isp#na?2+fN7wgBqpE zJ?eI|W--*4s%FjlK;vah%q=xwz(ExhG+Md4_tfC#7X84*rQL_l&doAd3!ZRw?f5sI zv9^uoeYC1lWh(7Bq{ffGq+!gM3$%No5?OS1ZgHD76v<}r+wHYAuqQj#s8OtH-FkzX zIrAoViW~6nGX1cGebWH;M1B74_WM3QL+HzG@Zq=yv5WNS zlZn0NFt&&UZQPJHUwcP><>z{?^YrX{u}+=&*l9Anz6OY*nVrxSx=fy1CL9 z_$RidFi+2c_x=4xtClU_rp)8$-DB9IGE|QqN1*+P>elTr`gkXD8OJ`l-Pr;Q{Ee6F zHKVIlo2SCVSF2&e&S)~)xbZ6N98(!*;W=y+zflmcjYi*k{{AEHmn}OP{_cd%6X>2y zY+XmOH3`kTG+R?t)B$wz`{=4P=7&+})pD=@cIkPi@bnyTqDGA*c$C4sb5eEcv>O}B zEac|R%SDkHN5{Yh5fKZ&>)(GPeBZC4qE18ONs!50mI1AMu<=dBhBF#ot)ne_N%xLw z(ISDd6?r0W>I!~}ZOEfsx%t0@hOW@$QtW&oA&JW0KlVrDpjyGXpS(4jgTo^uQy)y5 zCVKv$>e%rt_QKQ9cmiZX<9_U7@yPoGO(uhbXF>Z;4V^lzmNxx@4b0<7iG{m!a;np- zQl-V{oUNK%zV_Nq6&Sbx{oOgOa3x^NHHQ^j_Eelyg|FE7FVy+wtEZKRJP*7cYy+c193kgZ3zxQLm-N%|BP3ZrZ z*r4)CpYs{CH|W+a{lV8}w^7$|% zB#C}mi)^JcKdfYa?47S&F=xFw?*jwpd|av0TKao8{k-&b^#z^13&hLmEUz zZu)NW0c)@e$6&); zD0XY;kIUBvYBGh?D_3s$H}&dmRTV3qW{&&dG0K;}fsVPzSlWvmrZO)z8d?|DGLqC5Wn8z>_d%tw!{Wvs2fpI3TpvJHZQ(!Q-) zbqnc^L*F&@)D6bnP53OhNZxd?iu+cR@+!mn%-1*JYfsN5TAfn2kIy3HX9l*^qWzG& zv;O`YDJLE*WFA?q(SU8Xbk35n?KTPwO#3b%U<118C~3t;dlTFOA1Q<38Z>O8|Ah9o zGjit5eJ|fS{QQWv_}*zje)Z&h?(RP9pqJNMd^cE58OgLGf%+0zOE-F~V{@i2=-$@W z+1uMY`Il0q=MGSRIrG=bJ!Qfv3@XnThkTg>f!O1+vJBHX+s*TQ2EzE-wB4?&Q=5+T@$h24r&`ypjGr05XBl ze}(5~Xs6K76WUvEDr_C>nTI+#z46Gwp)X|!?Hi~oiL!dYi|+qf*mCkq=ipGSztPwd zS?NUCtHCxP-z}feuhSjneKcbs0{UBQ&#$bU&uwiTTwGndWSUGZ$=3>+mt~i|nzF-EvpRz&8yyxuPaE_Z>+dDd45PAGSckm97vZTy*z*l7cD@6Ax8_W}WihjrU*#M*Q zm492>AoWNe$eeW&YzAF{AAKIg+Oaw7wdjX+>h$}eYSkX!*Q(X+VWUP}SqpYx%^XI$ zNFa1eUMXV-hycFiuko+KehV&YE96_PgG2r7eyBlxDd0G;>L8iN=7TYyD}54}yvoH|FxSLT>ZVgF+pj~1GAxE&E^L8ot$d@Xm20#NUsliWM^0HN7~4< zMxQ!4g{_dZx%2-?{}$fxa&4Kc?Ui_`auUZs^Tm|x6Pz#j&N;pu$ zff5dsaG-<(B^)T>KnVw4BnQN<^=xfhFS0eot($KO)$HtoCK`>E((w7*XEN2fjBV>n zPtTSQ1=t(EG?{8$HX5t#v$rpwW-$0q#HXUreiOx|>&4~M>G7j%Y&2F*#+G&0-MtNd z1bv7Ri&sfWTh;E}r|==YtG@W+ztlJ1JW&7r-`}X4H}9!^`%bIHi?`#uH5=cvK78*8 zzlYr;+1A#zF>?0Ie9&GbU+nAx2b#^z|K{x6mhVCx_zpc4KhG^{)274fop+9_ZQIVO z_3JOH)YL0#`SNQ#|3vNFc@Lg_qB1f*R%g%N!WZ|l+O_Khaf<2q4~*u!TpMhL_5X%H z@xcFA`Gh}W2l#T!#ib*@5hGRq{)x!Te0+cA;g|Ieeva3WoqL);ulV%Jz4-O!_U)ZJ z_cnf*XYoVZp}KTg#5ESg@x3=vzNcW1uX{_cFWuqA$w1L+=37H$v$@I1Ql+98LqqW$ zdy77g!Ivf-A7%?ra`Hg@oW;L6r~k0khuG?$o70zg?AWvT0WHHHEe;>J7{2Sj&Ns7` z@G0~pw#CXtqxO$YjlX(Z`0`Ep@&l2VMfm5$;%Bv9^OLsnASWNhk6L(O<%9VBiZ69; zpK9@~7Qbro2bMGfiQkp7TeqHuAJJsKXSRV)5#JaLo^AiwRu`@|zJX74ckl7AZrus^ zG$t^nlJU2_qWP3t`CyfU*w_#8>pO^lQVM>LGx;twlJD(rpntpY-MI_j>3icZH<))* z@f}-iK z^yh43KL-7>^H;w0R{#2e12gb@N~Zk-;6wLpbmJ8hGI@rs5C6D~8}wj)Q=@e3P?EOlVK)k??uWqke|D7Xe^=f)fG>xC!D z_<&D`{v(g$46Nf}AOU}t4>4KvozfxKKL_c+|>HHabxkz8A#jugMOgzFX)Ps_%Dyw>s=}oOrcKC zTCyy0{F7W=JACTq*5k3ke!8g-UfiCO5CHyIm(LCAf?4r2c+6^|kv2ORjd zadvLH-x{mo?*0aT+T-yJKdpui&C(#T3_W{_AAKxzjgYbWkhO-GmH)7xUhh`X%WKH} z(9l@MyR1hJ{7NTC{6kRCMC4`|kQj(A7xAkul0SZajd66W86&z5-+xUmJ9XNn#YYSp zbcz_AQ<^Wj_@j5|@UAw01_bnnN3Y*!-BB^WGN1KxclRzwDps6|FY-cY*s4T7{^c*1 zHGLp4DZakr(7~gC=*pIxM29~M8XO&K#YntNnKFa$ryIhWYA5kOC(wB(9>-!xOolZc zBRo8fHKq8C_hMdaPF&3M{~3+JEyW+cY11V1amr)eC~-!E2cN{3cRKWs17jcIcV3`B zXi=!eXFf)BouA(@*3Ki@r|i^XY9ua2&ib&P_aU(WJ$oKSrZY4&Zv2)u*3f(SmH8IR zKfNe){W`7Ambi**)vCqg6CY2%9e=DBB}Sx56^WgZ__GPD{lljII&bm+a&me#hIk*= zH>1H=))Bkm!3o-*34R>|V~vB6SeWSOL&(@3=GM26>A{S%$ZPD^9-r?~e2VhU>F8L! zm!IEs)^*8REQs*L3h|lej1Uc_N_E(rcL_y%s^jPCT0hp`e=L6C6VPcB@Dblj%*9D9 z#->}hOs>b^!x4CJh;`{f#(X;Kq!h;00WG#c;%yo>lvsy_+FXG@Nw1<&QTWvO(tldB z=0fK31)A(wW5;^-Ji>Z+7P3Db8U|g}=?tdAmzsA(sXG9{95d-ldT@g*k5oezcyo ze;F|1^ z#yhjQUR=?r`t8&{KI5*}sIi2&ixh2su+9;op=%gh^Wcwmh7+f!75^u^2?}bT5EZqS z{rUlPzqCzwa1NYB4zkeAr@=|q6~{p)dx>`#@A1$umGLv_k*jOVG~ztCpUCq>=B{@i zW6+>2?1d-OkG-xJpUS6m8Vv4bgMyM-k1l6TzX_dqSVMI5VPaAiLEAzZ_rwJj|0lc& z4(^Z;9la5IM+WPLeb|kJ2N%G3Wau2Sa0Y&z1}A}>DYb)rT_SCs#k??$^+c_qLV>sU zu+LIjT>)gJZ@r~CBeH1`0l!vEk3os&PgoP(BR<3%;{;`+$!^g%nuO} z??OW|^GY)N!Inje`OH~^@TP3p$b@d)He(Mt4sYH=CkqcQQO8Aa0bZR$4#YNgns=vI zx9>rA7PH=(EpeOhrjEuNDc9At`2v|Me0`^rW)t)6)@*FRuChU!W1XB{d7M5cEycO# z%(Vp-Dx@MSVz-ks4BpeOwQH|~KPg}_zPo-ki&M5mZaOD)?Yfn72aXdbe1QHw4Ii$+ z2Z=Gi#NQXed2o*Y&tm@G&wUy?XC68yR?dU?Ra<2)kyuwj_3EkERMIt6t-6{q`;Iox zy0|niR9s47+T`WcKfQA0Rm7C9(BcgxZc^f4t5#jh{%{%clZdZt(SO35prFq4yL8!x zO(c{3<@@N`Gqn90e7MS-bcMCcWpEK(;N3ZRbC9vNj=qw(HHk?H`xS32ROp!hVt*#4 zjdX9JhgOq!J$sPdtS8eozPY(|#y<3He!jjFGAmV*vk2ERzV@IGc5A3yc`fpt2Awe< z7PThfO<-WuJh5v{n|74>@ICa&S=w;}TxUF3;vVbQzk=`iWyZ-xY!(^JTj}&uGCD5- z-qg*5Hx^3J&z}bb%!Svh&|90JeJMWSG0g8`+n>!ktzTwQY0fWwP|!T$JvXqXSdUJy z#2-gQ>?W3Q4Klu(@jU)$etGkHF6&}{|ERfb+ipYGNL>6L+AguHH{p>5VPQ8I6W7r* z*T5CzCX;pG+titYye1JRRX<zyU4!8m99m8*RiH}v(Pa&Ql6)0r?`dKKBAV zka*Ku@WF}?cz%;u)a&r+G<%4hv~`*2I(QRaAaA6O(xu>*3Ev`eMX8g{{Zky<=>J3Tx0W+Zi|8 zSu}1s8;P3<=#L~TtUa3;{1iZ*i=_g-_l1eE{%s5rY_>5w+00*h7XJ2 z%UocQq0*%j;7>ARY)-LsW?pqOe}7!Q{8sp|O6vnlT<2u%$=^3wtIK+4hc=Fhu|;m0kI7wTet&y=k2@V0 zxP(4k49yakBC)Vy&lH(jOk1Wsv+?EQ6LYF;*=>}$hB_o>Smbp9dS^Xt*-SfE-p`Lt z>vO(C%oBMNRH?ERyV)uBL6?z7i8;9ju7exdxQ=c81pO>=$*Z`ol(@_Z*0Kt7_3?@O zG$3FZYvm=Bxc~^wvFPVT^ryt_jy_eGatf2i%WM3O;NUIrV;yyfoX!Iasawtgkl5&S zVuhZL+p?C;x0?llf$M4KdT85#&HM!UC5}k=B0P~87l~Q6#Jo5-oF?5G`dQ-sg*UCI zSj#HhRcGt#yZ8q`zh&5bgg+9`EHuXRF`7?2hixEWg0>2Hx! zkylIHb3lN^UvDJlrAp(xO5&SglEl{w{QNesjuhUA%!s^Lk4?&uE^_hzIU|r^<74PF2j#O_#<&#^XbEQo-NVf>Ka|>vpVu>SI%cHF6}2tze^0b z$t3eZ0+6`sWjvF!1=cce4qBHpkKFT}VUfg#`}xVaGi%^YCiz5eth~t?>vfN^FEEBz zkTwl0hd1qK=Pt7_f4jT)*&wmoWy++m&l3J5g9OT-ujwO^A$%L2ne7*QNqJx2RgVCA zL-d`DXIWP)rM{K4MX>aN#420q$0nX4ZI!t6GG*jk!I3)0VKDuYp-Ga&}&O743 zS9^I0@8#?R8Dk99QS+6(s-f2@gaZqt#I>F8yV@zp?ROyTc1o=??aXBWabbI<i`D7wD69tL6DPuEW1Bek}#(B*q>;fzi}4n)TaE>KFNyHRDEf$O4{^ zLYBrM%M!k8*A-lI!Efb!ad-ETe|2^qifj*o z7Lo6bKxj+jZ#lDVhz9)ep4q&W2UXgc5oU8g`g;IG*;F7+R{n_2$(uj6w&|pg0L?Tw zIW_%V>w7ypk6>5V9$(tqH-QID&}Z%7jmWalV38laewg-7-a9(BelFhy^I{|G#ZY_u zu%8WvSK!Yp&?UANp($_v$Qd67Lmg041A1&h(1l&w>c* z-U6g=Ed0^wVzb}XfOnzL>JeI)@}E^2=KEnfT`;@}0u`W3_GL1@c7ykTtO;fQO5uG- zcDf*RPK(dcr}jmsgHxBB>yP04n{O?3O1%Q%%`PByO5H-kJf2s2T&K|(GOXzJ{r(&d z4t4PFv!2T!=QfBO39b9VA#eU)+y##rPI!ZF>N;%>w(tK_IlteqH*t z3-ANhw7#s9Dzn!LXK(V_FPvS&+NI-P@iY9~*}2s}-Q8RKRJn3n?5=IF)pz8(e+2VS zMe<7>-N9ZUWlJ4Wm()20$a_m24i2wE+l&6`jKtgI;E|m5(H{uC);Zp~MwEGNBB%v? z*^^YqR@NAsd^^7XMPn=M&iAe^e81>~{WS_(bZhL0^)xwIKH2BWdQ-|g4x|p@ zRbTLg|D3M^O}b~|xArVJ%)SsCz3|2=A9c820c4EH9^)*y2xOgj1DphJgC#)vy*Fq9 zgm=w=$lDN*0;G(aK=Mi%QkIk{&t(l(16b?zXZ*fWr0)gKqWy&_1D!omuP^^FC#^O% z{h(d+LKcvIzXYxUY43;NV{ixD1^2Qc_wr2MNg7Ejc_gotA!SLKU4fM^zN}ZvKQtQ4 zk1PzWFDeb^Qa3>VewCAMi%#fFTUG(tYglco((YS8_GGt#@IxT?@=V@Yc_Vp5ZWe=f zAg8Q~&JX>Hbw`62)$XF!i!6;c8f$U(>68Ao+}EXTGHwYI~kjdcA`~%_KX!sz2s#*OR}4X>)zh1c?554YUOf z!IOFVNqP%^?Cf6pku#o>pj-c(X#XRN)${+0baiqH&$PF%{)4rxc#5&t2w|NY$hta^ zb#5>^)CDOx{`2gr!TKJPZ53_0T|b1tq@{4wP`9gaaiUDB(Z}2TC|l!hsjWf&T^H CFTS(@ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/closedhand b/cursors/Oxygen_White/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..985c0abb8bc8a8c74fa89c98aaaefbdaf316ac72 GIT binary patch literal 32416 zcmeI*3Cw0yc?WRz)nVTe`38nB%Rpw}NfO6;`f)S6boaZnH}F80_y_={wf^|NOVr{@?Aq!U{76 z=agHqAcZ#+)-LQ;nA%>I0%V1i2C4lewW({h!nDE$g>?qUxEwtFP{!dFGk!8{hawcj={B=71)K>g8C`i%-U$9jk?Dlf4sZ*-g~?I@4vtM$xnXLr%ylqboZOz{ARqZ&wcK5 z9Uh{i*wBKl@n+4?g%{pUT(1_Uvo3`s%qs9W-vY z@V@Nqv(N7CyYIg4qKhu-uc6Chk3BYCmpVcIBab}N{qmQ;?9V^<+;iO)TWrCGZ3{GR zx4utTTWz)HaQX3%f80Iv&_li5KmYm9yI=k4S3T61efjEU4?gVJY_rYOKeNEM+pX`@ zwbojzd*Fcw`ttfx9okXvqmMq?*DZA{U)}me{ZBmcM7PN%o2Y+QVYq(BGuK#SjlO>T zY5j{|{GzXmKCTZOYr}cvl&2Y=SU~-=N}t{@aKerK^xz-#rh(M4{OF@RyZFQc>Yusd ziYq>L{q@)PZG?OJ(l~qe*=KwI*M|JohI{V0r(0!}RgCqC^xvk=edT@cd*8S=IN{3o ze*4?scF#Zme4jd&@4S9^_~D1U(@r}L_pcPxGs=H9s{FSX?mh0f46EFB!ncV0Q= zUFZ5yv7xg2%{jIyw{GE$h3yKn3%eKg9;A-tJFlGbu3J#ub$WbDJL2xD1val$Fg=hu zmhb#z>aF4irETLRj_@_eV#j&OBlh>kO!kzB8gV|8^|#%2TergwJ9MkB zzIylZkAJ*>9`nq1{`u$kd3DW`g#!!b&ickQ?6nv#_-n^}dYi(D=`s=UXKVy03@x0|ZnGKFT zf8zg8J--1PJd4#DL*EykU*WvJ2S6o^OBq+r2INBe>*}ONRTyamLFLwXfe3yJ~mR8~);kc)3+! zze2auPCNDdamL+RlC=cS?qEOgyo-NQYXj*Q&%xG4F1zfqe$BvmIrrRi(=W!0^*VjO zI5yx8p7+F^vBE)xew^ZifBYwWtpl~d(bxdj@U^yIzVn^$^!<{tqHhLkX8Pi!g0?5y z4|ubg_IyXIFmA6XblYvW-S}DyKDgs-y#=fT1T>{NIHzpZmGn!HH9B^%dCfJ~#Q&~> zm?!p$fp{%!3wJj2L9x4y=iRp3ZadCDyz#{$z#DQbRfY|&v2VS`m@%Gz@Pi+8ci(;Y zxS#E@#~v9QVxHKC&%*eJJD=lwPu6-%chX5GbvNI9b06bB@{x~p+i$;p&p&Hk#w%a4 zro;b@Yv;heJm-{A7OY{#7URJ=>rQOqYYl%fPwdM$sNIoUxU-Yb@xAV&AN^?G_u5lG zKA-*UXZzT%9q|RS_NDLL&syLsUzwC=TR6uiW%v^x+HJSpqQ96Y_VHsrG|`5Cd!N0l z*7bVb=|d|%piMCcKkd>L*cTqkSi1xJ$yX-jjR)s|{}>bESmM;KyY3qP`xY2;FH}2b0KhENYcJ+aE%(Trv*yvn%52wy4qpbRjjf@9lTHV@Ew?5ismtDgD zfa3I~0e|si)E3`q@3TGsv_%^l8GAIuMH=qm8$aV~fxMg_WrI4SKTY`7?Af!!-<%15 z^YR7p*EjRsXE)q%!*Q+XL#Ox=yIStyt$iA{kjIwT(b~W#)tNpB|5>wUEe?M^#@F~< zXP%Qd8141Byz~LT2={R2TP>0w8{$jqh##d7@HYnB<8de~s{WZL=&Su*YtBU zm^;p5NXBbYdCsw;wIO4n?E~jsXD+@N{P`IEZ0@E_n>K#`!GBnLKCL~Pg*)va@ju70 zA-?3=jG^>_HuR;k?(wgZ|4VDHy>=fL=%at}kKaf8VeWY6evo)Cj~%TIc&a0Ppl)r% z7v1BF|4Rcc7iIj$f6O!a&$HtHop;{Z_rdVEjrM#3FMWc?q9k0CVqM+bGbV9-h1ypzVT7Igui}{?}R^{@y#5-JixxZwhxRI z*Qz7@anIN|_Sj>?9|v3(Hh&ntf6c0Ejx9W1=uSNG#NIcxp}qJ%t@s1qj`lQf=koUD zr4KR=T$?c{I!h(E{i&U^Q>b2Fuh<5{6pdSLU+Ic2XuGcb=Np|T7`f7 zKH7T*dFiE>de|TCgNy-#TQ@f-)VZUX@9s6*xQZ;>lV%ZR$JQCHV(LC?zu4jp1IgLt-$B> z-JHU^3wIQHzubKD&AT(sIHSAcjyvY_9Xit+=T}~NrH6iK`yhT~uJ*}KezNC1@E3J! zLtEO^HV(MpgxiAn*XjPea^|6~^X#^LVXuNus4giyQ0VQDdd@iSyz{y*e({T)ckt#J zd;({%FRtHsoI+QtEwMd4n>`i+gTVeQ)A zu;Bhd59<$y7yh>JUxj{rSK4yveR$=SSME7B+Rj&IaIHGjrA~EgLtEO^_GG!&CH)o~ z+%L?jJ&$ct7%OPQ`|f##qY9@NE-PGJxUq0=;nBhi1K5}6oHELuUU02C)TPd`f;P0J z%~cAM(Y=b#x3M91@IPZn-C~*h;dX_c3!d-9iGvG=7HDa$7C*2r&pBn3b&YG)p)Pf* zTN|qu!dv^Vc2ft4P3rcZ!aQ%if_9BDeZEbB-|keP=j;LO%X3Z{WnJT1b*M|7>efcu ztKB8GrA{er^ex}i&ubNMpx^q14GR1hKd>*)Ic1b}jce7>`bpZU?4`D)jo3mn9O#En z?7}ZdzB0O{aGu(x6qr(A zN`WZ_rWBY`U`l~01*Q~OMhdjgOxa&XRF;coqrqg-<%0NYK%&(o&*52Puy)X{9}KS{ zxc2vT8`gymS#z<@Vht3!}>1T={zyUXNptHql2vizT!%e%N$hp|`pICcJy=Ti@E9a>^;) z;fEjIInKF7NT07Vrx$4ddK!b#hVS4lj%-obv2bOf*WjJ+d}senf_LBEAA|S%?|ILA z#x?Q{=fxLa+`rrOt%C1td;=*z^;G&7h3N%j@UIHSpuSih$KbH<=v#lkvQ6PH3%y-@ z#e4F6Q_^ZA@93kC?!VEZhj;AlcMsnE`liG;T!Z?2%ai>!y}t6jgIu1*VDxc6cF*BE z;_S@A*9!eRV&4n5-wV;I)rc;B>%n_{h(@hW{tjDx3jyuUC`@JyR`I2_(I;`)*b;Zf z3YPu*xU==vTleq&eHR113;6!`zu%7?zGIxpH=d%8Z{hfiG+NQu?+X}f#++{ne1D>@ zv(7rJ^Paxi4BlP)-c`P(aB^Xy`(XN4x-_=v2mS_L|}uNVVML!(w7^JL!(h&^)(J=cQ{I%qz9d=C`gFxDQbZ>0DY z&`Vy6=tCpE6|MN5Z}g0@Xk`qF<9;XP!yo=||95M?9i!`KKJ%I3Z+ZT#IO@}-rBSpQ zj?J^H&3Vzs_+l6Ejc9{&bTBqrh%EtqG9QrAhcCK5bs4`IgZ%aO+ixHL?y2=JbvF0G zCyL`vg;5$+_N&_Bi*0Q7EMXpEzAP^G{re;K8RZ+~03kI{$*U{2{e*Qc&lpXel&PiNOhtK0_%{BEe!T-LnA{kM%pbvUUl z+R)gTqK!Ju$!;mM{W8A4*Is+|`nZ4lesz>C(SsHfA!XuM(N=xp*07J|-f!;pz3+W* zzWIYOINpSHduL&5rH8-wa_puU1)*_K6tsF@9|G-bodW&aHX>f^zjTZS$&4*$F%P2 zo<4p0xSe?A*#S3PGse=VIJVmGIrc__Xc8@?$%}T%x^7q_?TgX5ukm9%=!2KK_#Pa3 z=%LX@I_^dPln=QkG5+9#4{r52r0m(bu(=X8aTXs^UL1rubLK2*eZ=+OS-bFis;xe)??juN z7cca8#v2>i8$XFAxd*jr&ZVsDMrouU;zQc!!-+$!J_jCn;F8wIxTKFbFW&d{Z@THG zBlVfccSdOw+Y`exUl~rFPuciVt5F-TTOVrm$((Wj{r6vz`iSTB5#Pmm@xHI$?;>RU z=&yEc$)Ct~;y3J#pU@-xN2SiEtm~rD@HlIIC~*ic<*g;c+&~hcd?KleYY=aQe8?R~w(>KlBmj`Ohnb z{&x|yPaB%hCu3`r@3b)|`ovf05M6Q~mL|{nl+9R+52?4k=f{U|!Ur$sbKRbM?iqd9 zu_X23Kk9ptKGrI&A4DHo;S--~=g9hx9c+p=`ZIn*hv<@LENSxMOYx)Fs=iTiC~-Pt zEc!@y-+lM!!w&YaOaCv<{3rgC_@ln(3Z36Y@Vf#TPxQ(DsIk??ol)9Em-ZPodGV$A zk?ZLkA4(jWXpGTNd40Cyjypylc0`}Woj;rZwD+&Mb$m~ue;;t=l~<1Y%dkGVr^k2b z6WU%v+OYB$Cp|^iVwAMD04>r6Tjv|+68}$-K^2GgFTD;{N*`>KIT8(ZF%;Z zQ@Ezk_krJ4iqC}4aO{ab8C$LI@QYR(&-ufkSF6z|AIcbO^}z!-d9=~KzwZwBfgS8& z7yH;bndj5!^M<-E^XL6*|NKJVj^EGl`-q7-IKgo2$=K58^hrFXPyB{1?fQE5{Mo@CcCpWM=Ay124nMzp z-@kQX*TSKN(+d54-fvO(Eqgvho5UUb@NMsaGdzWzdrrxPxtqe;!GpF@n;8n*u}odtUuESRxaco<{87-)h*~{)l+2TXSB;VtMV+ERs?J(rPqn zjL|1(V|KLhJ1)ll&~Iqqi#Pu47%OCKCH72KAMd<;mqlZ7e!IdRg|`&6^*@Dijr>-| z$tR!Ozn5#r7T)ZM@3i{FcW6Qzzk3pm=+=(0#G!Vqwfcy|e8%s#wY&yA@x>c|cCd$C z>|>{U(q!~e)-|gZ)+%_NL2OL{GpH!d^I z)M>s+e?Dr>>}`b;3%3au=|5AnZNBfdFSFu&TfFt>1I;q1bl1^0n``?kh?z-#x@hE2TE1F2fc<+h5gEY7M#3w${xepw6*kS$eEKTscH`>)c z9{9{H;D_f}0q<6u$&RbKe7=o7(I|f8UTEBkZTxgbVdug=1wM?|-xRJZJX`o3ord%D zzjxK%OZ)w8zw2y_PN2c4`n01x?P?zneDJ~#PkiylKYp`P?Z?L2U92tFtBXd)tNT9x zT(7W6;Z23@3%eA|yXF=SFZ^-g%)(WL2MeQYTiiVLsaO5l(cavG_VK_6FZ}St7jOL8 zu~H$n)$Xg>Qjb)w}R_juO9WOSN+=2o_4j5N5&F<@fo~ZUD&fEx9Fq|Xmy%a$8^$P zZ!AnN>{!6reS^OrSYXd#1^ser6;w5xqQ z@EO(x=h#rYOJz&_Qtk0oI`Lh6^w+wDjSBh@=dpr*WykD-dkNdbPIm5B-~(_#voGIy z<&<}w>(!&av4Z-wqdo0v9}j%+8Xik{zZRQzf>x*1Du0cF@vaYX-mtK7fgM{G`2Sd8 zo5G9&TemOl(7>^L=am~PxX$(JQJ;F%uO01aSNqFSmuh~#EgDJb1o*95h*tWu)l0nG zpuj%;ZcM~1|)kD3}M0?r|hn81mFY~SCGptps7r$o{+st3-2FArOa!$Eu z;d;79kBKzFVR_vq(n{YZUa>2>u{Hk2_Sm2Nl$9o)jPjG^S(BnZavRpFJ&uiwlD5|k X?~iPFDsxJKDFvn!m{Q>PQ-S{j5{kn5 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/col-resize b/cursors/Oxygen_White/cursors/col-resize new file mode 120000 index 00000000..179b52be --- /dev/null +++ b/cursors/Oxygen_White/cursors/col-resize @@ -0,0 +1 @@ +split_v \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/color-picker b/cursors/Oxygen_White/cursors/color-picker new file mode 100644 index 0000000000000000000000000000000000000000..afd7d42d9ebdcd0200a99374783812cdafb792fc GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/copy b/cursors/Oxygen_White/cursors/copy new file mode 100644 index 0000000000000000000000000000000000000000..9cebec32e83e25d3c8d2c9a83fb37b1ff8f26979 GIT binary patch literal 32416 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 Qo7?rQ`;f4V{}*=iU$Ktw{r~^~ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/cross b/cursors/Oxygen_White/cursors/cross new file mode 100644 index 0000000000000000000000000000000000000000..1cb3765218e043961d256f61d433a1890521901d GIT binary patch literal 32416 zcmeI4SyL2A5P)&l5D7yBIRtMMML`4v@xCumAv}2SegDBm?A!jX{T<4!;)T};9y4kL zu@6RCU((6+vW$W=19q4lQS{7oPfhmMSy`FcS={;KuRkkF*jAPN9{&DT@DQS$3ao(!X*wad*b|~y~ZKb89scqY~W!UFBC!f#hJ8ZIj`}Rye z{p9-Y=FOWkZ{NO^EnBt}rT@CRx=bpSlKT4kqV!)=Q0i}@V=fHiW`*T#(-(-jpJ>F|E${{8#h-kwl z^7QFbdHC?5jE;`Vy?ghB{(1l8$rE|;;)T3<^G4pke=q5DdeQgYvx z_pXG`XZWnPwl>2#Tq`Z#aZy=WnI0YeixR#{JzkmOJAwIz;=30^_e^XPFyn6LY zUcY`VTuajA-?L|r5Wf+Za4kubf7h;E^6c3&nVg&yt|e*m@7%dl<3eJ_-Me=uPW})# z%f!Tl5Cb(dG_17z3;8o~-)8>nFCp(D4<0a zX;FK!ckfum` zOZXc_n6DRF3G#59^EjXHaeUvteRDe0+S;o6iH?Sx zL80Ye^7sw;5tW}D7~^4u$8Y%gC2cA0gN=od3oA6wB?GAUaM zdy4&G3}aJ+;E9qSdyn1W8qlSr$z435CqSV&pTGew)P~VMfBvkjoR1D0)t?(TZs@aMo(J<>7+rEc zSw8*!{raq#=jODVH*Y#0#iRB`u3x{dwSV?p9$v0LS^eql?bW&kYC5RDfS2>h^0|EZ zvetG`pF+EO^{VqxJhS8L;>C+v3q(B-H84FrJ$~5be^XOU@_8=ggTi zx~9%*Y~d9S)7(D{98R7*sWo=g*->kD_Uu{b6VspL$B%1mFtvoV)2B~6pBSGbM~-Oy zfz?o>Pd>gBkj59()KXtUqfX=4v186Bra!Ftp>~D(4;Z0Ou0L7*p+=e7Dyxx?)_B1v zsq@$O@_t;`V%opx33bF)_YI?H4HA(6+%K;C=S0Z`jXeI%Tsn)kf> zjme0-%eg5ZYK4iFhzIa_@$2wiPMta>%-Khe9@X^>=mXb0e@z5yWvIO*{xUw)k&;8S zbq-x!U22c8+01Lq{pZe|6Jip+M{G+xOUzFmiCi1`Bl?JHnc=)5eERzOH0~y*w6zrY zcldd%M_?|(=3;xTewK9=)G=EF^$O;Z{%3!%1s5({ zQ2T?8IC0{H+Mn+3Zk>-hp>fwm&WU8Ez64OPo%r1!#}*oPNPHEBKFZ5#~%e}ec0*>s$;evSFe>`{!*a^LrYTvP!&Q9i8k!|oU()^mj4pgEtw0somf-x#r8 z#QCTes{XK^6aUZ{vEI}9Wce`f$9>1>eG$ z n0#3jQH~}Z%1e|~qZ~{)i2{-{K-~^n26L11fzzH~kViNcYa{i7T literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/crossed_circle b/cursors/Oxygen_White/cursors/crossed_circle new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_White/cursors/crossed_circle @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/d9ce0ab605698f320427677b458ad60b b/cursors/Oxygen_White/cursors/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_White/cursors/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/dnd-copy b/cursors/Oxygen_White/cursors/dnd-copy new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_White/cursors/dnd-copy @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/dnd-link b/cursors/Oxygen_White/cursors/dnd-link new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/dnd-link @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/dnd-move b/cursors/Oxygen_White/cursors/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_White/cursors/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/dnd-no-drop b/cursors/Oxygen_White/cursors/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_White/cursors/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/dnd-none b/cursors/Oxygen_White/cursors/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_White/cursors/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/e-resize b/cursors/Oxygen_White/cursors/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_White/cursors/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/e29285e634086352946a0e7090d73106 b/cursors/Oxygen_White/cursors/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_White/cursors/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/Oxygen_White/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_White/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/fleur b/cursors/Oxygen_White/cursors/fleur new file mode 100644 index 0000000000000000000000000000000000000000..eb7c8f092f892031087cc0083f1faeb550b29943 GIT binary patch literal 57504 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 wym{= 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%0DVp*F# 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/ibeam b/cursors/Oxygen_White/cursors/ibeam new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_White/cursors/ibeam @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/left_ptr b/cursors/Oxygen_White/cursors/left_ptr new file mode 100644 index 0000000000000000000000000000000000000000..24fac724a61e1a0bd04230ba51f7180b9c93f725 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/left_ptr_watch b/cursors/Oxygen_White/cursors/left_ptr_watch new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_White/cursors/left_ptr_watch @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/link b/cursors/Oxygen_White/cursors/link new file mode 100644 index 0000000000000000000000000000000000000000..13c98bf4cb0273434246a3901dc82b041a1e2c09 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/move b/cursors/Oxygen_White/cursors/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_White/cursors/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/n-resize b/cursors/Oxygen_White/cursors/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/not-allowed b/cursors/Oxygen_White/cursors/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_White/cursors/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/openhand b/cursors/Oxygen_White/cursors/openhand new file mode 100644 index 0000000000000000000000000000000000000000..e0ab243ae985db51538183bbcf4454f0b4a8abb2 GIT binary patch literal 32416 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 Mat6v7*wYyJU){&5QUCw| literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/pencil b/cursors/Oxygen_White/cursors/pencil new file mode 100644 index 0000000000000000000000000000000000000000..69705123646982b5043fead51bf31ea6e0a653c0 GIT binary patch literal 32416 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 H!OMRDmhXn= literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/pirate b/cursors/Oxygen_White/cursors/pirate new file mode 100644 index 0000000000000000000000000000000000000000..a24d75416341bd24c23d2430fe62adf0c6c65f5f GIT binary patch literal 32416 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 TTAaGv`9PeDFX+bnKs){y*e^wR literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/plus b/cursors/Oxygen_White/cursors/plus new file mode 100644 index 0000000000000000000000000000000000000000..a60e981fe7710187cfa55292c6a1a634a9106e66 GIT binary patch literal 32416 zcmeI4ON&%T6oAKMB?O&imM*ez6VV|*!c8DcS0ZL3?i_HJKO*Qx0`3(24Wc3gDvIy- z+wuJ#ALC7b<$TS_rQ6#z(>>icDdAY%_txW_ugZivZRzvoPP%RFx9eLwpa1%GYU-Dzd*oZw5mMx*C7J1@#y@hSJ*s!_^^8X_;K~&!-v!lTt{;IgZ!sYpRQiNeqFtJ^Cq!@&$DOGsuwR_r1}>Y z7E;Rfix)3u^#?jp4?OPQzhBMI&sWc%KTqwwefzdTXq#(Ko;*o9P-f8nATMR_-Md#k zdh{si{p!`L#OTwfPZa_$u8|KLbLxlBnKNgqmoHzYveX3+Y)#Bn}_4)JX^qqTG zu3X9D)2n~!Q|kKo@nfnReU;q)t#hOv`q93ojT|2J`s&}Qi~fWc%xPJXR?53xfBD{C0?v_`KQTulMVu>@IZ_8k`Bw-O0);>!Pzbb~!1VO=9~(Dr zoa@YA7n#G>WRZL1nM5zZe@(Lf*nrLm`#y;M z(FXm|_13LhNp9c1T_J7LpS>`IeHvsE^lup7|K1aelaHG+{=d5 z)E{4kJ>#S7@ppWNzCl0qL2vv8ztMNN#yxGI3}shKfBo9A-QOkj8{!&2PRbi=yYWk#^nqg#Z5zA9r8>f#z5cIXzb0YtUpu%LW0*RqbIDJKKEHGP zJb3V6iZ|NQS753B`U{NJ-`_3j`fDd;sq4s*BO@C>2Yr6Q6utEyKI=pDh2ucKbX3nT z#!PzV$Pg+L)t2owT^ zKp{{FEQ7$>wQDzT*s$U6&UwAZ{-)S3B@cNivy7%%S7hC~bz3{XlP&b)(eFBCDBC)N zGZe-LmcvG7l>IOJ5pkle+qZA8jvYIeeoyAz1KtaX!Zm&`KXKwjwPVK)e;co;Bcn@N zl{Jnx$B!THzL(+q8U50eCr@_yP)Dnb&QMn0A;mZP@u*)XZ!DY9WUI198+}I%7MxMw zY`enQ3;$jP_sJW}w#w)XWuuMQEF*YuCPndlNA#muHlxW_WsNpQKJl!Jf9oXr51eAz zRvDe4Y_u`*frV#keD^(`tNB0kffFovpI-6&PKmE?=iz+c-SbSG4?>&|wcUSm)>Fn< zj4yd`o}t&dsX8C)=#@^|dTqJuDfk#aoRdH}XXDu{|DKaR)QiRUu1&&vZ6)g|*^t5_ zo>${c3*vj*F!~;ge)q<`UW@CgojZ4?wGwBQct6+oih1YT_r869J^BuOC<719*&xi9 z5&4+vOOdT{O5MB%eD>_wYWMElU7q7yuhrL6o@S{CNaJuA7U$xJI?uf`HnG#kI02HkDeLivz*8ygI;mwy-DYT-@qrvRvdSF`3^n; z2hW3Yp0$3al|21?i2j*mKKKaZf#VSUTOW6^4RMUYU-;~I_~18i@!T@0oVXYLDaM`L z@JIN^v2mz_ZboHset7ECsqVO|e?&g$EgN|lPki??3^)@lpXf*Z_)wm@X#=@%;X;?s zIOm6PeX(oTu4-;>E#1CObMvocy@vlx!g?y#=G^?tU9U~jdMelE-26G~wKlJ(a=DcJg+L)t2owT^ ZKp{{F6as}nAy5bu0);>!Pza2Iz(1C@w^{%I literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/pointer b/cursors/Oxygen_White/cursors/pointer new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_White/cursors/pointer @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/pointing_hand b/cursors/Oxygen_White/cursors/pointing_hand new file mode 100644 index 0000000000000000000000000000000000000000..dbe5e6c9eed8f046dd908b83adf57404adbda485 GIT binary patch literal 32416 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 E11Y~yjsO4v literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/progress b/cursors/Oxygen_White/cursors/progress new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_White/cursors/progress @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/question_arrow b/cursors/Oxygen_White/cursors/question_arrow new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_White/cursors/question_arrow @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/row-resize b/cursors/Oxygen_White/cursors/row-resize new file mode 120000 index 00000000..e3aa7487 --- /dev/null +++ b/cursors/Oxygen_White/cursors/row-resize @@ -0,0 +1 @@ +split_h \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/s-resize b/cursors/Oxygen_White/cursors/s-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/s-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/sb_h_double_arrow b/cursors/Oxygen_White/cursors/sb_h_double_arrow new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_White/cursors/sb_h_double_arrow @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/sb_v_double_arrow b/cursors/Oxygen_White/cursors/sb_v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/sb_v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/size_all b/cursors/Oxygen_White/cursors/size_all new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/Oxygen_White/cursors/size_all @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/size_bdiag b/cursors/Oxygen_White/cursors/size_bdiag new file mode 100644 index 0000000000000000000000000000000000000000..b3aa9b27077a772ec1762cdecfd07c2fc49a838d GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/size_fdiag b/cursors/Oxygen_White/cursors/size_fdiag new file mode 100644 index 0000000000000000000000000000000000000000..0933e0cbf28a0fc61248f28cdb9b6c7443028787 GIT binary patch literal 32416 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 H5@O&#!{V%E literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/size_hor b/cursors/Oxygen_White/cursors/size_hor new file mode 100644 index 0000000000000000000000000000000000000000..87e1d01a066ecce09c37644598517d8cef90d239 GIT binary patch literal 32416 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 U2n+-U0t118z(8Q&|CWLO0ifch6#xJL literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/size_ver b/cursors/Oxygen_White/cursors/size_ver new file mode 100644 index 0000000000000000000000000000000000000000..93cb3fb0946c690d3beb0670a99219e8f1078f07 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/text b/cursors/Oxygen_White/cursors/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_White/cursors/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/up_arrow b/cursors/Oxygen_White/cursors/up_arrow new file mode 100644 index 0000000000000000000000000000000000000000..e7dc00654c8548f96649e2f33cee55413fd33bc0 GIT binary patch literal 32416 zcmeI4du*0h9mmT}5M3>oaoJp9Z7COl0UOhCan!m|A}paUt|3emMwAhpG0tFgT*4m` zRJQ0uC4ukE^7L>jSigDtXZ?mTK-V9tm%n0I1ZCCTDNX}`OKL!E-fwXhSsx1^BSD{ zd52&+(k))HWQn_d`?g!Ze!bKBKLt{-|4GUhbaHN1R#w@C3m4ph0|#7DQIQ)pY82n` zj$nUX3-)u%wys&T#+^EK${jm)%$+=W(j7j0*tKlg@{0EL5Ovk5tOrUcGwNYg1TQ=&oG3;`Z&^=i0Vy z`#{G$QM47lXx9;z@jnb7@l+l=wq~`{Sue4D_(^-^P%{!m?v0|XCW34 zC%G=mc*O=?DshXAkr+R5vseP1E~S=Zq=zSc{$IX|*#5M5Q~XC97T*=<&v+=FzN5>< ztxzwj(u}-)hJ9hXnRe5>2A0x6& zFm9t6GCrp*BtpS&G{Z_s7gI$=ety2Yd-txpe*L;*Y+F`V=H}0zZ}(u0j(JvaPD961 zv~MLCk27XH(V|5QcjU+sck|{=cktjrKNi1r>z2E5Ve;h3X2VjQ(@iu)Of|phpzo(W{#&@^%a{B48}rfQ$B(-cCr)_y%snVB zF81@ucJ10>1M|Caq9I}`?T$HOrkExwa&mGU^K|C9)cf@5)BaxIN6de*iG8%`6)RTQ zJvgd!@gw@Y`iiNheJ6eAE8-Y!cGIR!UR&yE^L6Ixmo8oMb}^43-u?SGN-T4 z`ZI>g z*~I;x;>Ut9L$UDnV(i0xxOeZK?|bQs18tULiUjxWEkO)G`}*t$@FC(wszAGM2^f&xEwb1M7y?{|8>O1@BzMp!~m-Q3$NxuF(GX&W}8^wmV1!E1y4Gp2W zzV6Rpq|+6(&RN7bLX z8RO=t{t_Y1CDK36g4XhKk^Z$5EY62V`o~$&T3#;Fzm|f<`S3{pI15_K%SHOvQm{B5 z9_b%vL2G%rWYC{EInN^e{KcOAX#Q*S$C28{94!&&FU;eamk$*7yrKG%xiL0!uM(|L zf1agei0z_!-S=r5xdS}6=Ga6lJcHm}63@c1f%i$w*MZmNnF8%OhGP@4m<`+qp3Pwk z;8$!*)W?)P@|t}AMafl zyD@f7c7149yi=uJ4HW+pUXN|tw(&~S=UCV_Eepj_i>Bx^ehwkzIa^%Cz2|9&wq zFVDa8C1;N^W5$f253SL0-38-OVo@@-Gi)M;U}JZ|yFmXwTuYzV!tX4|2?XBjckbNT zG(y97#4`fl!w0!uvJ`xW*g*^-cjE=|k?{7DMvUWx6AcpXcezdqLT!#)FeBKTIf;Qwel9OZkA>+r74{Eej=MdA0?a9*TTf3r< zCf|g)`9FlWd*#ZNUKg|>_igv?-Cm z=+Ggb%S%2luugj;uNPS7HxrfT-_tT*bQ8?q8r#^~VsdZ}LH<#(;J3W~H>+`uciCQcs+gPWkDw-n>2%jgqZrwT`Z!Ril+U!RY@~4SI z2J7g8ZfJzBS)MX^zFe=8Em|^eWIo3|N#t>3(07Q*jCE)O-j<0ICwhC$cI-B7$SudG z4D@3g$D$Eh63c;eD)YBZqnY{+#+~$&Hb2wHgew+z@OAp%JaJ99_U+sIu^+bL7ud^Z z>_-c7sx4l##9!EE8gabk=d*9ss#T^9OTJ@}VD6I0aR_~ATjXi--0SDU+dE;m^73syPg~^oTY<5&U4v&r`@{!=u{pkz=+9uS zf5(TIuM-cLOTI2D@_)TNbM%DDi{D?YJcWiiGFpk5vx5fM76X7-B_q{wbq@WYOQL}wo775yE zz8EI@2*!iVU+6Cx6DGRfsEVOt8c}z~B-nyYw1-^reeo;db>Mep7JFE-Zu_*PAAD21 zBC-U}SZPoAD89;fL1QacZ)~97r@eI*Xf#s%NYq51pXj&|qK9}|(1$ms_N3}QwwNzj zOu~=o+wh4;=~HU^wETgfZ8G1rKB}>`CsqBi1�{8(%Yid|fT4e`ou^Q+7Rgzk|Sm%(kDie(1u8#kQ^~9kv=h!gf>L_ zgye`>iS&t)B(x#YCnQJAN~BMWB%uwFJ|Q_`Rw8|3BnfSZ^a;rkvl8hOBS~mOq)$kW zn3YJM7)e4KB7H(~#H>X6#7Gj_5a|<=BW9&G`rOvp{@st3(ffJ4)`mVKzooi9ypQI+bW?bLiay=NH-(Qe{NMTo3l>zN^)lP1C3#W2kLJBJ@281l z$yl(9d?|99$W44%SPXvLaSELJzJ;|E;BNKh$-s1!0Ibkz7VdNB&bJ<_u zD=hIXwv%f{UJJ)3yYI+EUrZx%5{X6V)KSpp4A#+w{TxT!;yh>y#Wcch+8Y|+BL?ei pXMa=i8<`p^<`2Y_M`6c=PHe&}kseL>=0~PS3PcJ-3e-e_{{cw60UQ7T literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/v_double_arrow b/cursors/Oxygen_White/cursors/v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_White/cursors/v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/w-resize b/cursors/Oxygen_White/cursors/w-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_White/cursors/w-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/wait b/cursors/Oxygen_White/cursors/wait new file mode 100644 index 0000000000000000000000000000000000000000..a9fd0cd0f846891d3da3c1a8d5d2a11957dd05b4 GIT binary patch literal 1034800 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 a{_B+_V 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/cursors/watch b/cursors/Oxygen_White/cursors/watch new file mode 120000 index 00000000..fd80437a --- /dev/null +++ b/cursors/Oxygen_White/cursors/watch @@ -0,0 +1 @@ +wait \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/whats_this b/cursors/Oxygen_White/cursors/whats_this new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_White/cursors/whats_this @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_White/cursors/xterm b/cursors/Oxygen_White/cursors/xterm new file mode 100644 index 0000000000000000000000000000000000000000..2e2ce6114c98ab45974beb44bcf4a833c3d1fc7e GIT binary patch literal 32416 zcmeI&+mD@983yojuq`dv)&mthbb6YWV^5Sb1cU+#1quZVcwsa~kbDg zR|X#o)(0CJxYyKs-IrU8d0lXQK%{-a?%>mb=iaa68^-v2@cZ@a*Dq|@vSmS?`(F;8 ze>}DMEq4xRe;`<>a^}n#()UtIqwegD(Wv1}m{I{c+Ka?N8%>ildd- znDP0~-)`Q#d4ccQv}qIhe-rEq*!D`s$FFt71)aQqP|v02JK5Mu_|cdDWyAE{eALGE zZR@{W-e9*!5>C>l6e)Y*CO*ucF3{`n-fKP~?8W*>=1e&=UF zX9Kn8G>O5!lkDdA)8MASoXx%V>eH}ae#7_4u_F+c*}?lGNo$ zk1t!Hv*kl?%=K--)4_Wq<{CF@*{&xrOw9!_d zY1nK&yI63BKRUz@vdhPUaq@e|?`zv~pWCUFlAkQ}nQTkRe=P6$eQoJo=}s=EQpit- zN`A7DaUB2NnPbVXuQ8@oTKUC+xqyuCj_{xK-`bS?=Db?urwb+jqq!a>KmSjDHnN)Z zABU65|3upIKjJR_SBw5nDnI`}Kaii#T5a;nfgTCQ>5tefewF|4tNdd1YKmWUnNOSx zma^aDc`rw*{DIz0(+BxB9jN%bE7!+@ar*O2-pSwOdYgl3+c4R2cugQ5-Wxm~jEZ0U z=ZWAzAlJ5D)7ByR7w#v`pY3~(1or#pJMA^F{vbn$Zg zBKnI%T)r4w$obD)+S|iVQ-?}^{^ZWU`AB#Evu)e9u67pWdg%P;uC&Adv~7U?$R)`^ zo}UEW98#CQx3zaa4&-pwOdOu3{;*%ZQ$9l%%;Ane40cxHEa;^`+!EK027HgRYPxUk z)7;04T{QbJold5 zVs^ONYcdYrYp1<_b6~7FAg@lm@zP8V8+0Vff)mrnt?s}fZqr`ky;>9gCt0Dd^kv{7*(;X z;_vz5^l|vukF|%i zU#a~GzKW|>pIUoMlT}~Hj+@$_;l*Cloc$l3tJ)dt4fY2&H`q6LK9|}V2M&uXKrMR)~#S0xNUT(@YSAK8sQ1HkAUmVe@| zbDdA%#`(lE!COIlK6Jk8U#0!AK!3W&E?bVQ1&&%@l-pHZtSwt$7sbu)T>mRLA0MOM zznOk}0_Q!&5x-;&_@lD3zUWZt4nJEqbu!nZ=H5N?8^ERB=N;SI6}0DJ?2NAVk)Jxh zWEXVj`$5M+`+H93_-D_a?T+=;?nj*M>-X(oKG+dBPh@9wh_1FaRp{oQxZjJ`|31`1za7=@)j+Hh_xS7Lr_NK$2las;_SN#kcU&rd`lvtFRE*(&_zU*+ zm7vofwg1t;(W6IOwdw9XZ~k{veU7JJ#e4R}_lp6=k36U^{+Y}bzs!YA$a($|)O@>o z-@bk4@Z)~CP4533+#0Y`{!C1ypX2;+2+f|O&|PDMDGe&TOG3Ia-p5UoxwA~ z`S|(gpq=)+0{xA%F`%2R-t>u^h~Ax@TUR<{t@#VKF&EqsJRMBJ&+$R~xzze^4vg1F zpA)gqDa8*PGcPe&d_EGG_ayv0m3Csge)_X5>z0w$(SAisUcfyZM>ta{1w#@zdH?ZhKpX`7uBI(1+#d&syfkx|^RI zamG(bNNM%wV)DaYE9dDx)YCusF%R=;`8k;TN$pFVtN7LW=e5qylbQD<@k^d0AF%hr z4?n+_;#aFb_89h1^k))&@OZgxC z*fX{Kd^z{$voHE{BC!A384UA7H~U;J7C-j;y8>rO_9^sdE#!z7gP-TZh4T&k*uP&J zYzSuje6)XkK3q6Y+Y{9J##-X1&VYvf^Q8XAIV^tm2F};~&xkMUdkibvDt_cGwZFKK z`2IrrIbWR*oFDS>xULw+NBdUaO7X)_m`k1iT*&_Pt@L{_xIfq*_}>MNaXoBfedEZw zmhP|zepP&y=N$H!U4wWD3iynzD ze1vtj-f}zk!QZ|eEEJab|8li?BW>|1#@oLcYgmV@M{$(PRbS{1ySgs0-qzjv|2wF8 zcl8APX!pBdU%#c!rRle948)IA6S4?MHbHQst$Imi<{3;v!YOenp zTnI;hO#7Du{L&p`8B=WRtADQCu<{@K0&#gRpa)|0Q^CpLYXRR=6)zR+`#?q!A$|3;g8vrzQ!1}j!n|;0j`*4c+Jb)i z8^@TV^rjEG6Vbap5MPO-mZ##X_%hc?pgpv_7`OZ}Ui!jKMD1iHFZl~CSJwVQQT>aT zzH*bPccs>}t&6Lb)a`h#*FqVd)5W-73%tzcFk@iGz>I+z12YC@49pmqF)(9b#=wk$ K83UJ)f&T-l&Zcw# literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_White/index.theme b/cursors/Oxygen_White/index.theme new file mode 100644 index 00000000..6e4470ac --- /dev/null +++ b/cursors/Oxygen_White/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen White +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/Oxygen_Yellow/cursors/00000000000000020006000e7e9ffc3f b/cursors/Oxygen_Yellow/cursors/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/00008160000006810000408080010102 b/cursors/Oxygen_Yellow/cursors/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/03b6e0fcb3499374a867c041f52298f0 b/cursors/Oxygen_Yellow/cursors/03b6e0fcb3499374a867c041f52298f0 new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/03b6e0fcb3499374a867c041f52298f0 @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/Oxygen_Yellow/cursors/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/1081e37283d90000800003c07f3ef6bf b/cursors/Oxygen_Yellow/cursors/1081e37283d90000800003c07f3ef6bf new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/1081e37283d90000800003c07f3ef6bf @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/3085a0e285430894940527032f8b26df b/cursors/Oxygen_Yellow/cursors/3085a0e285430894940527032f8b26df new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/3085a0e285430894940527032f8b26df @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/3ecb610c1bf2410f44200f48c40d3599 b/cursors/Oxygen_Yellow/cursors/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/4498f0e0c1937ffe01fd06f973665830 b/cursors/Oxygen_Yellow/cursors/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/Oxygen_Yellow/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/6407b0e94181790501fd1e167b474872 b/cursors/Oxygen_Yellow/cursors/6407b0e94181790501fd1e167b474872 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/6407b0e94181790501fd1e167b474872 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/640fb0e74195791501fd1ed57b41487f b/cursors/Oxygen_Yellow/cursors/640fb0e74195791501fd1ed57b41487f new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/640fb0e74195791501fd1ed57b41487f @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/9081237383d90e509aa00f00170e968f b/cursors/Oxygen_Yellow/cursors/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/9d800788f1b08800ae810202380a0822 b/cursors/Oxygen_Yellow/cursors/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/X_cursor b/cursors/Oxygen_Yellow/cursors/X_cursor new file mode 100644 index 0000000000000000000000000000000000000000..80d67f7ced59bbd3c498bfb26e010b43f170f06d GIT binary patch literal 32416 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 CFTS(@ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/closedhand b/cursors/Oxygen_Yellow/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..eb99172f6430b650e3dc164d46ddf7e9c461ef7d GIT binary patch literal 32416 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 tCtc~u2N{!y-sRC5tM=g2@@c)5i-~<2w literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/col-resize b/cursors/Oxygen_Yellow/cursors/col-resize new file mode 120000 index 00000000..179b52be --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/col-resize @@ -0,0 +1 @@ +split_v \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/color-picker b/cursors/Oxygen_Yellow/cursors/color-picker new file mode 100644 index 0000000000000000000000000000000000000000..9546544a999c9bed5839b0824d3f0219a1de022e GIT binary patch literal 32416 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�X6kn{rt>nkjal>Y+CtQ$T-S?~1 z0y<*^X`20CsaCw^Y#eRMBag8krJx`-BtCRTHJJ=w%EDL#92;nPMEc&^Yo=5uX|^yx#9V&CAe3|E%TDvx&?dVrd&NbjfNz zoHq>`G;djO=kcEhK9U<-mgUf3SXP5li~d7rFy2*O#`ZNn|r zhJd5+Zd2xNH|R6Ot&HA~8=j|_YQ6g*o09d0F%5l_2(CA6O~ymqr2m00uB`s%0d8K|7?W?|6P&!tJ17O`LerLR@!gI4 zes{JXGcCB4>6DP>CX>P%&0M?Z5!^6mkYhi2o-)E~oTsV;H%%R5@>d3gr&$Mt?pos; zl)lnCaL-g*=TzK}5Y}Pr^zgQynnk=Y%R2K3xzV1(E7Lr6UvIEp{Ho)Qee1SIr{ny5 zhD~5t=K6rpoLL*)b|L4C>@sn7B-Xs5UYTpdwfAoza(qLZ`aQj=q}+7sS?Y_yjnSsq z0=uv{+%FK5kP} zb&ZV6-yE@{VCh!BtbubaV*AZn9EZF-u7$aM&a=o(OJ`-FTkOs}uehE0p0P=V;HU_9 zgX}e4xKjE4yk+soJrmk2b=>=`a^sPZy3ao;wa_miwZvPQydQS~J*MHJv(6UKnaxSJ)Vv!!!h z73KyZhbkA>7tK38z)f3MWnoZSW=Z7ktb@3_<4{Oy#$l(>n4-_D>{3VJ{*IB$t<&CK z<(mHtaHA()ZPi)5wxuk@c#GS)#utU`&N&d9m3ugPPY&(|$v%cVW%f_DaoRo3%3=4I zHFoLUSGn;Vd{v#NWWCYD-T$@3BKIhamE07y*sLsw%*^{DK4;$%Wp@5C{J#k&JmYqL zG1I{{19@i#?%mnb%W7*u73bzYKfOQt3}eN38<5i@1cDPZmt1tH4q2dSe@y4jc?6ks?FLxE~KNY?!^Qfg~ z;9l^v7kPQ^AY1Qeg&SFS$d93zY3HX|%PHBUOe+9CCn7VlkF56Hp2Pc^7Q6Z64z~9t zH_WBveCl!Q#YX6}38XURQ-E8hsn^%*Hhc+tyO9_->nci&{gd|xrKFdv^xBqg=^2o< zc#BVVkF{GF-<(zp?)Q28TDlQFr7Cbkvef)cSm}gut9�fgF6rKC-a4wa2cvES*wo zFZ0429?$#LAb6Z=orXM|brVA&??L4Cn@8<4==vH3;6Ju0MEf57F>cjeKCqnv)qO;^ z$^&@q5ag(^jXRFlPGE29Bz`^#Zc@O_X!K|dVVwZEX$O(HsZ48Ifc*z;wE0>UKe%tI zA?|B3w2R}s%{!+KLU8XCIZ_@MHnGRV;0f-CleicDK19CSL$0}@O;s&!NZs(+%Q1fH zk4lGBJ{ofv>P(WwC!aeBlezAq?_kA-59M=a`W-obA*gS3IL{^$*j@Ht=Od#o*y@1c@wZmJG97@Vs0Fdl*U z&_T?w^}_$*Fda6;{eRX+&}LqN(6^8e%4-n5#`m;qOCGMDz}r=(DKHWWzk808HAbuf zVEqVrqK-VT5!Pstm*1-`!P`}?X>-KAf7YjwC)U@nmP8iv#@G1X!!>N|qbfI`V$y|{OS@;@7{=GlZWtIFDdHj!itdfKNcToQ_@Gk>T Hmx2ESUJ7@A literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/copy b/cursors/Oxygen_Yellow/cursors/copy new file mode 100644 index 0000000000000000000000000000000000000000..4fd7f17eb765b1b7768250f360d145ed193d5354 GIT binary patch literal 32416 zcmeHw1$b50*6j|&6FhDN2?T;A1QI9~NYDuG?hZwYhY%qS1PBCzySqbh_u^1WOR3)W zuVDpB=Nn_4v(vx@?k#`bYfIn$zHzplv-etK&o%d2bImzV+a4o_71X$xXnFCOM|&<# zSo<5dD`DN%%5c0Pw#S#(w35bi{GJKGHK8wl+!()frxvv;OUqZNh<-d**X!>|ziSUf zOWJW(v(8r_SFg>B;rb^YiFCbsU$n^^k7*XxHo19^JnKID?cf8EZ9o1d&CdTUiYqe< z%iOw0-i`Nu+ws$H()9W-vi67PQt#9cqK#X!Lo+oq&y9PSZuso^>i>BzrOrK+pv#YB z$#>5s@c93THgfKIEw8ER|Mnhcxc;1Pf0e=~9*Et^2U7LJ$CB}{U!}rf++)b}WtvHz zJpY?}p!~nafALK69KA0lNA8Om))g*1lGLw$mD2ma6|G-VreS1y0zLY)xP@?ZWm7@FpC0h4MX)pYIh;}*o-b&f_ z^pbF`VgH5mId;s~fBGyE*C`ABea=5p&%y2VL&<%SfP0j^@KA<*`a~Rd zeJxt6A(8mGNuH#GVbmiS^BSCk|)XZwb!>?fA{J5&z?#I)(4OU2i{; zz8^o4K0wEho=B5xkEIIk;f{Ln*$1I+-EKY>Eqd(<%SriV#+}8|^Wqqpd1t9uPA>4; z>sxQU`-J5m^2t*fhc&m~|MaPJ#ytX$?U5qOYKiSkN3l(`7n>M6v6*Nu))VX`_2wMu zaC(TO-pUl4IGjsx5ZhFIZ@QD@%WxK(DErH%Wi3LiHyEzZYo~nmOwzvoRVG7Tc@Ov1 zA<}+VPnmFPvP?J!T$n5qFD6OUr4$)|DM?x$?;{f~Crk9zX%c;Ts>EIb&Lzp11LLLM z(gso>*6p&@`cIyW!L_3yqnT(|%fEjvbFt>W{jxGL_~1xsurWgFZfPv_c7#g(JuRg1 z{`L}fsEf2b)<>Ej=`CRgyGo7iO~iAtw`j?lSVUXMdvo3shvj9(68sNCS(CneCd;5F z_T2wXHb4(eLp{oFZ7DvpDoN0yAPHVmUm9%*ldv7FrPq-Af!&%Usrm&pu$W`3rH}{k4=i_?^^&ew+T)Q&op+PnblU8Y+%4<-{qeg1Aig71z1`;=VLMoTpa0 zVpXYN2=rtbt#sucTJ_LqEv(l?OBjqfcxzyk=-%GXFSnS1Vjt+PK#)l)x-NzA(2 zIL=qFHDKb{+ea#Ft}CT?HIn*g28%~RwKrX#x{ErJy4V7600Qtn9;kI1dr<2`uG>^@AMp4<_-7cDEg6M z=YBHOVa2V7TA3;}{ua*xeP9!m|M)|ZV?glf9}RU_cKs)p6w&^>=&A&NAbU89oByOE6cwd<=uv{8vCN`>#;7I zF)l30aR}>>apF_W&c*#NR|k|I<4jd{_U)>oU(NnI`+OXGu125IV=u-ati#O1x6t3n zX(ssdtFz{lXQrF($@(9k%Sx2B9L7;ZMT|QVPzOGPCExujP8{Q~4%4!(X!#4XzxLNy zP=2#bpUVoAebKkir8vek1jlIJ7#DK9uny0K{dzl&p;(8Mo#!>1{009K6+oZC9DVqO zupP|)20UY|tiu&!+2Us(N*wCI`lX>=6x{x$p$_qzPiU4l?En3_3(LRh3sv^1U;e7b z-W-4D2MS`mUj%jw_cIUFm})WVn22$ME$XYDL-d*hnz<#%0Ds=H`py%Mp{9QQO!1r- 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%0DJIMhwgP`QRNArSN;RQhj#*4ec{A z2yrOy*dTT%ALQdJ(jQ{0FOQ1z>tv6dPsE2j8aW>6PQVE`0Vm)DoWP_L_ykbI(mDVD literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/crossed_circle b/cursors/Oxygen_Yellow/cursors/crossed_circle new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/crossed_circle @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/d9ce0ab605698f320427677b458ad60b b/cursors/Oxygen_Yellow/cursors/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/dnd-copy b/cursors/Oxygen_Yellow/cursors/dnd-copy new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/dnd-copy @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/dnd-link b/cursors/Oxygen_Yellow/cursors/dnd-link new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/dnd-link @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/dnd-move b/cursors/Oxygen_Yellow/cursors/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/dnd-no-drop b/cursors/Oxygen_Yellow/cursors/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/dnd-none b/cursors/Oxygen_Yellow/cursors/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/e-resize b/cursors/Oxygen_Yellow/cursors/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/e29285e634086352946a0e7090d73106 b/cursors/Oxygen_Yellow/cursors/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/Oxygen_Yellow/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/fleur b/cursors/Oxygen_Yellow/cursors/fleur new file mode 100644 index 0000000000000000000000000000000000000000..71ff1dd623a8032b74489c4e6a9503c9a9330136 GIT binary patch literal 57504 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/forbidden b/cursors/Oxygen_Yellow/cursors/forbidden new file mode 100644 index 0000000000000000000000000000000000000000..5c1decd228eac5af52fe0e1fc5b25b4b2aae4183 GIT binary patch literal 32416 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¥1Hg|L}``_Bd&6 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

Bd{v2-p@YHW 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 S-H)KMMaI(NQ6do+!vdMU$R@!Od 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/hand1 b/cursors/Oxygen_Yellow/cursors/hand1 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/hand1 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/hand2 b/cursors/Oxygen_Yellow/cursors/hand2 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/hand2 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/help b/cursors/Oxygen_Yellow/cursors/help new file mode 100644 index 0000000000000000000000000000000000000000..1bba2fc4f1704452d03236015149e58e407c01fe GIT binary patch literal 32416 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 C6&RTS literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/ibeam b/cursors/Oxygen_Yellow/cursors/ibeam new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/ibeam @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/left_ptr b/cursors/Oxygen_Yellow/cursors/left_ptr new file mode 100644 index 0000000000000000000000000000000000000000..33d6b6f2413a559965c64c74894257c0fe82a827 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/left_ptr_watch b/cursors/Oxygen_Yellow/cursors/left_ptr_watch new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/left_ptr_watch @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/link b/cursors/Oxygen_Yellow/cursors/link new file mode 100644 index 0000000000000000000000000000000000000000..ad47bcf5cb9da4b22164b7a566fb5cea95dbf769 GIT binary patch literal 32416 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 U?%($(+2+{^5+-Ck_^%!R2O2S{rvLx| literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/move b/cursors/Oxygen_Yellow/cursors/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/n-resize b/cursors/Oxygen_Yellow/cursors/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/not-allowed b/cursors/Oxygen_Yellow/cursors/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/openhand b/cursors/Oxygen_Yellow/cursors/openhand new file mode 100644 index 0000000000000000000000000000000000000000..cb8b74128c29393c4dc7553b3ae8fd811d8451db GIT binary patch literal 32416 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 Dx-VZU literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/pencil b/cursors/Oxygen_Yellow/cursors/pencil new file mode 100644 index 0000000000000000000000000000000000000000..1bcdb79eee31451d858fe0bf77a76a11f38127c4 GIT binary patch literal 32416 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

Wm}KxyLioP=4egZ@>dy@bvt3dP#qtFERqm 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/progress b/cursors/Oxygen_Yellow/cursors/progress new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/progress @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/question_arrow b/cursors/Oxygen_Yellow/cursors/question_arrow new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/question_arrow @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/row-resize b/cursors/Oxygen_Yellow/cursors/row-resize new file mode 120000 index 00000000..e3aa7487 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/row-resize @@ -0,0 +1 @@ +split_h \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/s-resize b/cursors/Oxygen_Yellow/cursors/s-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/s-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/sb_h_double_arrow b/cursors/Oxygen_Yellow/cursors/sb_h_double_arrow new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/sb_h_double_arrow @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/sb_v_double_arrow b/cursors/Oxygen_Yellow/cursors/sb_v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/sb_v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/size_all b/cursors/Oxygen_Yellow/cursors/size_all new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/size_all @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/size_bdiag b/cursors/Oxygen_Yellow/cursors/size_bdiag new file mode 100644 index 0000000000000000000000000000000000000000..2abf1eed4dba1225d8286eceb5d23360f8b98931 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/size_fdiag b/cursors/Oxygen_Yellow/cursors/size_fdiag new file mode 100644 index 0000000000000000000000000000000000000000..1d2b226ce6d9bdb504b2a376c1287c9474b16615 GIT binary patch literal 32416 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

nr3hM2iepx86F6wD-zes#ML>`}VV#OJa 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 Kyh0!wA@E;SLHrp2 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/cursors/text b/cursors/Oxygen_Yellow/cursors/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Yellow/cursors/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Yellow/cursors/up_arrow b/cursors/Oxygen_Yellow/cursors/up_arrow new file mode 100644 index 0000000000000000000000000000000000000000..ec3c35686f3091c2397dad7b3e4279be7df60d55 GIT binary patch literal 32416 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%0As+vI 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Yellow/index.theme b/cursors/Oxygen_Yellow/index.theme new file mode 100644 index 00000000..c0a16cd6 --- /dev/null +++ b/cursors/Oxygen_Yellow/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Yellow +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/Oxygen_Zion/cursors/00000000000000020006000e7e9ffc3f b/cursors/Oxygen_Zion/cursors/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/00008160000006810000408080010102 b/cursors/Oxygen_Zion/cursors/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/03b6e0fcb3499374a867c041f52298f0 b/cursors/Oxygen_Zion/cursors/03b6e0fcb3499374a867c041f52298f0 new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/03b6e0fcb3499374a867c041f52298f0 @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/Oxygen_Zion/cursors/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/1081e37283d90000800003c07f3ef6bf b/cursors/Oxygen_Zion/cursors/1081e37283d90000800003c07f3ef6bf new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/1081e37283d90000800003c07f3ef6bf @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/3085a0e285430894940527032f8b26df b/cursors/Oxygen_Zion/cursors/3085a0e285430894940527032f8b26df new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/3085a0e285430894940527032f8b26df @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/3ecb610c1bf2410f44200f48c40d3599 b/cursors/Oxygen_Zion/cursors/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/4498f0e0c1937ffe01fd06f973665830 b/cursors/Oxygen_Zion/cursors/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/Oxygen_Zion/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/6407b0e94181790501fd1e167b474872 b/cursors/Oxygen_Zion/cursors/6407b0e94181790501fd1e167b474872 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/6407b0e94181790501fd1e167b474872 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/640fb0e74195791501fd1ed57b41487f b/cursors/Oxygen_Zion/cursors/640fb0e74195791501fd1ed57b41487f new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/640fb0e74195791501fd1ed57b41487f @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/9081237383d90e509aa00f00170e968f b/cursors/Oxygen_Zion/cursors/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/9d800788f1b08800ae810202380a0822 b/cursors/Oxygen_Zion/cursors/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/X_cursor b/cursors/Oxygen_Zion/cursors/X_cursor new file mode 100644 index 0000000000000000000000000000000000000000..ade77fa9005929eab027961f2037db2805b1e566 GIT binary patch literal 32416 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 CFTS(@ literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/closedhand b/cursors/Oxygen_Zion/cursors/closedhand new file mode 100644 index 0000000000000000000000000000000000000000..147feaa3e4e4b9bb8ab3a52af9593670b86bed9d GIT binary patch literal 32416 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 OOn)QrHv;91!2bhYh0lus literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/copy b/cursors/Oxygen_Zion/cursors/copy new file mode 100644 index 0000000000000000000000000000000000000000..2ef4bffb81f3d529cc70a5e191912b94ff3b9a42 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/crossed_circle b/cursors/Oxygen_Zion/cursors/crossed_circle new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/crossed_circle @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/d9ce0ab605698f320427677b458ad60b b/cursors/Oxygen_Zion/cursors/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/dnd-copy b/cursors/Oxygen_Zion/cursors/dnd-copy new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/dnd-copy @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/dnd-link b/cursors/Oxygen_Zion/cursors/dnd-link new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/dnd-link @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/dnd-move b/cursors/Oxygen_Zion/cursors/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/dnd-no-drop b/cursors/Oxygen_Zion/cursors/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/dnd-none b/cursors/Oxygen_Zion/cursors/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/e-resize b/cursors/Oxygen_Zion/cursors/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/e29285e634086352946a0e7090d73106 b/cursors/Oxygen_Zion/cursors/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/Oxygen_Zion/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/fleur b/cursors/Oxygen_Zion/cursors/fleur new file mode 100644 index 0000000000000000000000000000000000000000..7cec7472ca67ee0e2643aa0223cf1920e6539734 GIT binary patch literal 57504 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/forbidden b/cursors/Oxygen_Zion/cursors/forbidden new file mode 100644 index 0000000000000000000000000000000000000000..dceaf88e83f522d5eea2641b0ef600a1b513c820 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/half-busy b/cursors/Oxygen_Zion/cursors/half-busy new file mode 100644 index 0000000000000000000000000000000000000000..bac0338add69ee071094bb16833a00a3b9b89db7 GIT binary patch literal 1034800 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≀xmf5D; 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

FUpkraQJ6Y^VGuPD63J@7qZ)8>w3 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 LODs4|H7C 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 AVE_OC literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/hand1 b/cursors/Oxygen_Zion/cursors/hand1 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/hand1 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/hand2 b/cursors/Oxygen_Zion/cursors/hand2 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/hand2 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/help b/cursors/Oxygen_Zion/cursors/help new file mode 100644 index 0000000000000000000000000000000000000000..3da67a2a8407df367a649525d9210e09051c5012 GIT binary patch literal 32416 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 AXaE2J literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/ibeam b/cursors/Oxygen_Zion/cursors/ibeam new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/ibeam @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/left_ptr b/cursors/Oxygen_Zion/cursors/left_ptr new file mode 100644 index 0000000000000000000000000000000000000000..e546bf79800e254378757659a3c5fc8c8f5cad79 GIT binary patch literal 32416 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 SNAnPvhrm1p<{>a61pW^?8kGD1 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/left_ptr_watch b/cursors/Oxygen_Zion/cursors/left_ptr_watch new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/left_ptr_watch @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/link b/cursors/Oxygen_Zion/cursors/link new file mode 100644 index 0000000000000000000000000000000000000000..2c02a5a1831896ffdbfd455216a647238d58987d GIT binary patch literal 32416 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 h6{&H&4CHX^H+bM@gN6B9{geD{{S2f^9%q0 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/move b/cursors/Oxygen_Zion/cursors/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/n-resize b/cursors/Oxygen_Zion/cursors/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/not-allowed b/cursors/Oxygen_Zion/cursors/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/openhand b/cursors/Oxygen_Zion/cursors/openhand new file mode 100644 index 0000000000000000000000000000000000000000..a8dfbeed13861c52580781205158c85cecae10a8 GIT binary patch literal 32416 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 DQt>Jp literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/pirate b/cursors/Oxygen_Zion/cursors/pirate new file mode 100644 index 0000000000000000000000000000000000000000..d5d0c0e0ee51a348b42b5983b9e078bfb32d5d86 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/size_fdiag b/cursors/Oxygen_Zion/cursors/size_fdiag new file mode 100644 index 0000000000000000000000000000000000000000..d4732f6da1d8134553164c3fe6441da27bb92688 GIT binary patch literal 32416 zcmeI535=E16~||Wy@2e?unY|Qu$3Judl~k9EtO3ajFe%wP{>#$&_Wu-254hSLX$#6 z*d-K&0-+U&35(dGSOQ5ypjrrquqd+V?f-X~GkwmC;_xQC?>)bh-1#1F`QEwzckbEm zW&HC$pI%%e}{sAMZwu8s+-;@9%o{?CG9<`f1m(V@J1X(E0}j$0qn6Hf)$HR;-w-QKNE&4eJ(96t&47)^4K@m2f6={ zAwxVqO`A4#ojZ5-{4ZIu#OZfg7|p%;EcYKgc(BKN?b@~O;K73~D=W*bS+mAXn>H;g z+WWsFTDNYUJAeNC72WSQty{MqlAWFX>cWK!f2rT3WVH9!{aR0$FkzD91Qk{M5%)u- zLHs7AB*)#Fi2O5A{uwc1#6-<+q2#xHuU@^Ty#4muXSQ$O?miMldFv$IFLT$fU2f5$ zMNZ4n%N8;>V88(PUs1I8A2evtv{kECc^T-^rHgCXvZbp~p@NsQPd@o1+WRM0tXQ$- zsZ*!i@ZrNJMQS7wN!m7nk1=gmjLe?p;fWmL}@p^qdWLJAQG z5eN|o5y*#t{I&tV6TMzY`jzMhqI@@ef=~QZkkx3Bkmi9dVy?(O5_6K+&HeGZ_0 z{rawPIvf?xj}vu+c?FZKEF_@QYFuO!-frg z4g>tjm&}?FRA*=;*K9??C z0{eTyzPG+x8N=9-@lQ^NIS_}Ddm&z}UAwkZIPYbiwLl(*Tt<%E?-kdn8ZpBj)Qo?0 z4(pbjSMlP-9kNrmZe5?BBDV(a%yHw!jh=t4;mP`VrJ(Q+@90e9pLGz)KRGt|pE+}; z=U--HnRu_F5wo?c@6N@ac%B#=xhGeE{2)8++qd^RM>!Y&I`f2NHjp1u;U&0FtjOdC z{*|}!`Uf4VG?>pFpmWI2_UO^W=X3h>>EjgZyEA9b{98N|qFN3tCR2#yADd;l6kDb@uhkBN6*ZiJJ(&ga>dJu{gJ+O zMq4Ce!oHc8fmkk(1zsogvL%2^>Zh8Ij} z5dB9azSoOyRo%Q#VEJp-rwwdXOxNpooOn_2XmgIdQXeR*oFnNL9YN5@oFOuQa>AP$8$Y`MkF)Ov`A@XhgYd5wBfK={X=RTRck z;D7n@<+=5F{3Yt=)TxN2se3cvAAgtMD**Bj{^f*i$Gdm$KA@&aEXQwP^~ZYk>iK$o zsZymp|M;=Q8v)@TyNpd*0RCIIZq3y($UZ#=dGRNfCYE^c;6V`Z$6nQwem@WYV6VA& zJ%rqoccBkMu8NPXiLrT|_XU7|WT(9NnFa6CL0-3@BZ+~C;lRFX)v7)>Kx{{E39?1b zCII{+JJp2!hwx910-eK}MOP9-qc6$Jkk>%|S;xGOeAE5=_hT+U!hRsU6PJ-&M9r0K!J0Cy^ESB^JGX`?iyh=j|8smkh>?v>wasQPoF z7mJ8q5UEF}M*ycl-~txb3rNo;b#`iD^b}Yvn|chj4Qd?JI;eSQf2!S$HuOb;54{TX9#ZR}XOg;)VFaE=+MBt*Pz(j^&3W-b zcBsRthT?mUwVlM*8L2f==cNyp+Nso*uSL>_-=IMQU*Ds)O`Y%X;llB}U| z8F!QyA7lre0|wNM>77VUPWC+@U_)(|+Bmp0YShRzYu3!yolTzT>o$_;92X#I8tmDL zY2W$d{xFgFAUCWrbTR$v$P4v#_CHXs=6nUihB`boZTbmVZ}gu~3qEk*fWd?8Och`3 zhoH|d?&Sx381xy?J7KZ|PV~pqPegA5{T1x7N8g~MsY5f+Af4SEU#)4wWS z3PpM42b+bhMqZE`^bS4v$PW8A&^6d7u%VZUz8U(i7@VnLB-xoRMrvrpt?U3~BtGaJ z{2Tli>;C{F^bmT7-VkI5JC41=mVpa>QGCuwvO|AnhQ?DG^!mi*+7jRS@L_FXpKad; zYmBvKYl|~d&^gEs{t(!J=ZY083?5`^v2LBNL9cGyt}XGN40rA|emFA(-HhEb`N3Y{KUz#-0BH}! zK4F7yuAq@n>kFS5ox+-;_mzPz!XF}T0Gr5jO7N|bA#hbsn}_Iw4?egkTv}+bU#)~j zLdXxc3*AE>HvSK?gACE1hp)q$!k!a*;q#!M(LvU`y=>VskB|DZzS3v93YW?`_~;U! z6luS}2U$QSu;<`{k8J&b*eu)A1y1_U zFEi*P^wKM@yuwSKBuf(oOkB$jKkPT*LoNfId*sNGoEd-fMQ1*_x88ay_YK-}a#gx3 zru(>yN@yeT!GFfK9x3D zSDJ$-%`r`T0v;F^kyrJ%A5(5{ir&~n15EITOXUpK4|yF1kI}`%5($Hi=HlrOqDWk% zOAg8w4c3cwG>E~m)8ImmD{_E`{To~o4jawMlk$Mgbk;)x;OdE*rtCo6`w%vtZ@C%<1zo{|{57#0YrMLA_7Ug{n&%*kZc^cq)W0$JfP`o+Y6W3!sV>JZdY(2)+3HK;!K1@0Y~TbX4|}o*Vv1dm-Ku-pJVUdy*>t{7Jwg1 z9L-)XC{gfHzP~i*&oZZL*RJ_}nZ*9=dp~jF1W)H9YDTs5*LG&_RZy<5ny{4$q|5$)}7DcB_KYfm3M1F{tS%3f%#fZpL#wRfS2t@ zjfWj zE(wMY{tR(SL(cL7AHqK5fVpCekRx)qov||0NT_XdMutA?dji16^5hAG4{`y+Q4j zx(VxyxubKaVW;aXMfzy0R|0&%iSWE_r81{ZuEu%X6g{jc=W;0t2A zkQsXXsOKU}_}KJu5u;kYEso^}*&&}(O|mn?WM|KwJzf`6r$*;czeeX!<7ZuA*Qwvq zM?w#htu1UBc;Xk(i^KUMP@LmK{;#%V=Y7KmokJV}HYPLZWBftG#`;6`*<9J7PlEWA zK2rK5696AgFDXf~)7P-EbARvy(Z|*kg56^9Z`K-mnm$LKWBpl?OH7P&Y%atpac>C?Q-&LVP1x!CrDki#9w0G~`laD_7sCo9; zXVTm^6)Q3xs|<4^sZ>Zf(531`}U?)t5)Wtk3LE-U%q@p z)nRy^Me*_RH9q;|leE^YTbrw|zS^u=v&OtGx>V!}$B2F{+O}<5`VBYSU|O_jVQSW_ zXSFfJ=?z`{O;^N{exH8%A2?+_c4jw$1PT9_#JDZIgH~uJl zT6&2nds+9t%GTSkVMFTHty|60Pe1*#z7OK=in)8_+O=z6U%!66*|KHJcIm9G`ys!3 z)22c=8B%1Uv#B z0gr%3z$4%hIIj^Ad&ed;DwEpTml$Bu9$EVXin&-+zhV#qGu$Z?rKiVn@V; zjvYJ3_unXtRZ{%JX@fekis^iuo}O+xbm(B?Qt+lPX=!ORZHSR6epaWTeNZg20&y=} zS%2otnPa+k?P@x9>}X?6#IlI55&MD$4jh;)-WTb@jtbfj#(qqjHf?&sEbW)@^-=yLq)ytKLaegnN&d!}X&Gpw`Z@PEyZe=HiSgl$$8^6YVrs$y{V*%M?6~}C?SmYP*7&>&QY1giujXe_IBo;?Zlo;WdF=MbL ziW%u@hhnR|7CD26nG!pt47$Ak{`+lAQ?V<{i`b^ds+GNQ+1>%#d*qQvtbU36fgPE8tJu8ho6t6{@tcSNecV!-fqr`}glhRHHchUX8`pABeyZpQ2c< z)g|%i=;&x8mv2g!E^TAC#8?|OYGm60E9^>s+YA{p#LSyF&+=5fv2Gr+^HXHmvSn*i z_=zW;uyx^q{Mfw4gHdeL>Y#e{>LxKU(I`G{WnlbaXIu*9+V-#+;?(@}_~VaTEWs1o zAXZ(XLQTaDG%u??hgu&ZN@?HS! zB{EgbHzJj{Avop;+0JmjC$eLs*vtFxzt7L+3z7T;{y8L~4t3$7*K=0S%mdgeq(1ByL%mtI zYw3buA8bELYmWrkpq(!npKk7QzFy-zP4BU0NLOdQg9$7|J1TU6x*wp;_^R4{T zr%#`&x_Qp&dGXe7(Hc9eV8)z@U(tMSd28*k9^aBr{R01-`EF~2Wv)N6tD~|b#($`| z2iuI2op;r6%W!-@6KPK9A1qXqpXGOY=-uZ7dT-cCeDODhk)OITnp;Pwq@+C08cp*9 z_IM!?eJBhD7gArntR4Z6fJeY1;1Tc$cmzBG7dQg7B|rPE*;maXmOEEc=4AsE`s~Rg z;1Tc$cmzBG9s!SlN5CWC5%36j1Uv#B0gr%3z$4%h@CbMWJOUnp3l;%h0kDsaJyk!~ zo)-2;bNyWHtLd{zTi8l!&*Jpet5>hne)F~3N5|O~1=(+THnZ@)iPApFk|Rfs9II{W z$=ZL_Qf$r(jI{r?yK+MIxjksywYTsyrEsv-bk59(u^89NC|hFEL7OGRDq@FMwyX_6zrQvT&Xa zGLUEU)KgEnukBrVBq!Y2I)%j{dwu!7Naa|J)&AVm8+0>U=6oXdGb0aszRBTW&$`Pc zQ;Ngi#4EVRxhQdBY{e=MV4VYkoCst<7GxsFA)9MtzxNj9X*A8=$8i7G-tqc>6*(EW zD?P>LtdK)Mz6Lon?9oOp?k~Ock}XbdoXncn{Ny6yhrp+>7*QW=qU8c>D*fsQ8dH9v zZJV41&SN4E1Kp9k!kJW=X?j*JatO4)d-_Ep@d=BRgA@Ir=m(Kysz0 zgAchy8hSS0!krc6>S(|DN(oR#7k1>_l z&*ZCc_L9plbag%!Nyi<;D*tfLMFyOcwtxa&so){ zOqnuI0+iRqUVn#CNHS#>#%|Dg8RcD#km}NCMBD!@2DHuiLKgB#$eTbGc#&g5z8N`nw1M4_2SQ$s!-o75ayL3kXZ)^n zyw0%c#~yoZnc8DM!;Zq4^TCF3T25)cW0gv5^K6h4zf7B4--`o5p|=SVrN^K=XuIh;0M34Gv>jc}G4`Df%oB`JT2+!peS_zir} zSGR86Y)&1ytd0czay4F7SEy@i#uav#prysHf;kbw-L^%W;KR5=PmFmmB4>#6+psBq z=iD{$AqR)NKGp<5%4uDx^VSvz%aAuj?k4$k?lIo* zi$PtH6Y1s<>{2;YSE-+&`bF@GQ9fKfKQW&Nf7>>;yis^2atYjdeO}F3#?wpV&6`itW0& z6n&vL{D89|$u$xfu z!G6Gp`3@fF*x{p`b>{o9@OkpdCs!jYycoA!=m2~e(?NXj)8K>sbU+E)jF2Ih+gJn#(zF`mWA}1ODqji}b&pG)Y=2*(Rxq|jT{LrRaS~bY- z`v{*<#}~E~CqI+ybcxG^H@+5KfDg9I`iD85@#TCpaw?u+$Cc)BD?fgUHIWlNJ&X~ zUCmY16;9lvgdTHhNKE@IimaqIlgkV?ZvJA9aJIwPVt!@qN}fD<+h9gn^ar+#uW8D+ zb@mNk_pAmsj^tyCDJOoM?B@_=9I>_lAI1!QXMBSPI0e@~tT`C-_(yDr^=xoWuejMJ zjd_kBET@aLOsK?~=@PZsP0#B#uN4`;`syn?evys20oy@W$mrII$jN7H%jph(b;~Wc zoaK|1o4!W&#u+m?lKOoKXPL6DbQo#6vty2a(}tTv8P`FK&>Q+g&OmkZ%rnpYS@1Vk zgXGY&hQ{B9O4diKQgyZ2OBmVnLy(aiX!Pdf!fqTkj4j5R(;GOV@7G>?&2`V-#c#L# zLbrkn#WM!ax#i3V2|ztS`7&m$AMWJ$iIjHKk&26E+RhE@%DXms#h9 zON`6Xx~d7I&U#M%+BJm#a5AAcCa zM$c0Jf0z*bUfDyU#*fcV|_~MIM?Q8D5Q|+>5=D7kH!m%Ayv*eyJz&TOp z3ZFhKLai-Xvc$@QOm5AJzOWti$lUGD$8f^QAEs#D&-Yx2%(ipAl@ZAgEszh(dM?wM zM|O?P{0TPLGkOCrHy!f)sQH4i%yUy=o=bzWff2l7weD--`ic*5vT#RF_(W`m*k+J; z_SQJ-5M){upQVRp?mP_F-dk_IW&JkuKXWK+2uHG`RQjQdJ{87pg5tx63yk7)PWN`# z9&;^o6+Q(*t3^RVeLYP+yw zDmU@LsDxtkSpi+fJB0L7p#}W6o9Mq3~54WH9rA*4`Tv@ETO;D`usgGJ?7XVp@7wvV?*F{+ z_3QWk-IJX&;o&N!kd#to^tW`WbFPlI?F0L5w9QVv@Oe+|Pi|SNR94^^=cTByrKAPQ zwc3U%S4iHI{8>_366$rKp7*e1^5n^G&YU^!AxWs$g>v3ilFgep=l1K@&kYHF4OZ@Fu(xyH3?*UsH=!ws%$*RHNZhYqe|$BypRS6}739+%%e@;g?mR;~KW zmoImy57N@o8tB>zAzUBIDJl9Ystb!}#*G^{wS4*VRYSQbc~0CQkdm63TJw=d z9(i{3=+RHgd}4ybA(-{DvJ2O~`|i7&9)J9CH+AY%_sT1;yjiYXIrP44Q67?!k?!EWkkqZ|tbd4J~ z_V(?%>#lQ@Hf`E?`><-&DmQ4*puvT`zc5eTv}x1V*q*DezS`Tk%*;$jk!^B2cI?=x zQz{nr{#>X2WZ=s$zwDYeZR#pluIyxQ-1XOA?>_qIBX_f;DEGE&W&c;-dFP$p{$op} zM^3mcwBtqHs_soc{P4rG*iW9L{_&7(URZ6=?$o)^!N)pAY z75L~B$$ANRXJ==-yYIf+*MH>5k$mKMha)k*D6nE7o*+Me1ofObbEfw->91tw-QdB4 z-LhrNIOKjK3GsHtdYbyCboJ#2j~qGTdiLz;Zn@86{Us_5i@IQinPS+i#D_S(;GX*N=JG zH~;F^TW|HgmCTc)f2b)b;MNg8%s3f9XV0GPWFEb)G-%MkHEPtzk98UEW@TkL`Ma)d z+qPb}@S_pN_7SgOJ`cdJ`L~33wq?tfeteGJQ)j7^_m%ONIff64Z;O86gKpcl&9^~* zd+&T65z#|WN~lCmPL6+HsUzDFD#({rJdx#NWkB|);Hf&TSanFif6kk|* z_Uu_Ve*Ad<&JrJK-@d(%WnhD_{S<|1{QFCcqf@6&u3NWmZsNp=-k$E+v*&A7oUmPS zON#u1v3hUMdm!}(`$K#L+fN_BIEcd7u6y_HPA11KUAolKX5`y%zs*(q2B_lEz@KMU zP|T>e-1^rJA3l7{S4w~6Hv2j=UZF5{nLd5G9d?RqeW`xpx9Zz6bdM{F8~C8-(FV#D zWy+LEmwg-23mp|B3vGdO9c8z6bQByy{k0se>`9`(f(Km~6<9AwKpN2#=FFN7&F>d<3y+Yrcq_4_ip8JVN3XzLd3j&=e@PUxh(_G%N02F3luf1J zhw*-*>&o5x_&+%Sa_`ig__^Xl^vU1ry=eQR8%6O0V(7F1dr#~Tu7J{EzVHr{zo0)x z(77m9^^%Vc&SAglDt5rVxa3Wu{GsKL9(?dYcgG!fcw1?_2gTle z{nd}%9OY{M(;HKIT7KtT(SaT_z>GD%+DErLwSznVYqFv-U1#Gwnq7irRtCI zlOrNHAMmYvYKs%amXaALk>m*J5g`kGHTgFB8F&C{*oWBz;%GH!4_R&d;0Wgj}i7; zaUjk7DjD)ui75y6hH*9VRCsB``s5z^F%o=v6LE<)#4^7$T;Ck?60FVQIrvyJV|HSn zdWI7QK3>9U6y__K#43L^T-XqsP!3@a?S=13%t%9iU*zg|PAt4wVq?5(aAU#9XjFRg=n)cngS)*j|KSpE+jz=n5-JQ{uvIVuYKoCi+i+xQ=hu;+|H zOyHLjS1!)>g!5VY{xirE(w@&h|J-9iyJ@ds!~eWzaLak`&@1+BJ^(nPN4#g)b2!`z zi5f)YWulftEh<*5*pLr_0hvd!CF>u13bBsJE?rFM&W;(BY{oE?wIaqUbp9s zljAqh*eyHW^hfJ9q$xCbVZxR*L|ghFa@F`V=n3tIQ-ZH-{xah+3VsjA;nENTVXS|# zy!6sbOTxHrKw;IPFxREZ2hLKCY~#gkvj5>FfC*SIhR1J2KN!n1uE2Lz`^o9sC3)LV zKmBxzI7btO4eK4mmF)@C7kdCNFIE0cD}DdZh<33luYrLba?{`gHgMjcLy*5_Y--#$ zyXM4+6W^)3dQCQ{yY5TBPA)zscpR!nVTA9M0#3w8uTZ%A&dqEV+1DH8pB3$`!njt?$WuuOR>uD z4d?d&KG+Mm&a4BHDUAARKIuMtmu&mZH{X0G+nu9xu)j9{i0ey&U^mbQ*1)MHSF)jO z@~_ob{YAdyGOg$Iq&VSOI)>hqG;Gx5q$CkYB9KHNi9iy8BmzkUk_aRbNFtC#Ac;T{ zftW%dF9xex5&yD6+>~)U@i1ZS@F_G=F)iV$V5> zyR)P`co7Ey$C7{%Z3G+igZ0rHYYy3?ilLsexR`CXY}v9~Ip|J0hgc)==0wK`Y-pp! z4zq;KB+*!X@&*naaaEgl1Ww{aeJ#!=xnqkxC$bLFHuQj)VSQmUJ{TM3!ohuJ8(8kr ztCI9+m$*;`Mh~&^@rV(1P7}|kt89qp^ZuZrfq&L(%|r6*C%Zd))TugW>b z@3ni#PMuRu@jc-tu+_5K~c*66);5xyfgCoY;AhaJ|7=?Wb zTp#|2`x4A;;e6)zK!r7(63^u%zgH4h;Ha{)BYE=(SQi2gFZ?LDWAN+X&%qC)z;}Z8 z1UC#W6#L)@kBal)QGpGgb1t9RIvK+0y!hnU?YOc-s&n4_E;v8%QQ;hdkMViYB{+75 zgW*N{(J{DqTnEpU^Ne>FSn|TZV&Z>ni#Kdc*MsK=!ij=X27fG5d|r6Z;ALyW(0;gv z6!@%m9y$k}*eWZct(y74FBoLci^r|jA6-jhuou`~bOPOAE)y7`8{h^`=o4G;<1=uP zZ|L7OvrG1y2HX?=XFOsOTxVg?f;C-e4|A35eL_!|XTdxIc=BKYRuuO6jALMByiGV} zCgKDg*E#Tk;$F0##)So|)VK#8c);6Nc&WTQ%uQh~3ica3*ivkc3VK67PhZBo78CXB zBjX;JKm)W!P~`&>+Q!^uxTy3=6!A2CVI3jGIecNCc~01E^NslJBNN_P)&fZsd}xQ( z3mH1t6Z`e99T>Gdb(Xg@h$meS#J@5<2W2?~*3c95A3>~;o=-<&9 z?D5#KV+~UGiA2X4yCydx~1&pvcj7?c~f>;p0S6~v0>!w9YiS;|9qpaQhwu#}vI|av=7-Eio zcf&+6lI_fWj#PbO?Y^?Zr9YNf`;8ZFYfFGpz#Z`Om*oF+i?udHx;`3fc3|ucMs#a* z|F%8}bA3$o8xQj%U6)wBzj9p*3zS}2rZid1VLG3DYA%!h$5CnkYN&r`F$^ae!N9gRKu*_Xcw)6Gsjg~ zM{AvZx-t+*NlCeDH@-8wO5g zv+*z2y?ggm@jKV0OBd6)abwe}RVyQ`%=-1~&pjq8Eux>*t5>f_=3c#enaY(bn`^GQ z#x!r<+;AQ3Kl|*nvuc`NiLdyN`3Otos&>^(UC(#s#BqoZT8@h`8xj|~_w!15O)mOrvdH_XEiKg_+a z)pb@s?h;APqr$>8ZQ9f%CMGhr=D>jir<0PBdPt1uZ2Y5z$KZYY_N5_5!-fs5Ox%z3 z_v{};WktyE=$E3ui{{UtZ^u{qX=cux`KEriGGyb=Wo2J_>7{q?x#u3!qD2ey!V52$ z|A-oi9M4c^jazr|+P!n<&WsKnI`njHLhz3g_9+?%vu)e9pMEQHZSy-<5H)Giq?y_U z^f?rN{a!)%bm!jlpP^nsxXwl7R5ZN5DtGN5DrQVhAYiOd@XQc|-AiyNEF^21dx9mX?;D zk&$7}pFgitMuuX|uEo%GM7mI1J`>rmyY4zuw{Bf?>eQ)>e~BW(ycn3Q5b0U+g1Rys zJg@HBwQFxNbRCf{{wwNuX^p394rH=1@q1i$B=d(P&($d$Ei+t#dIyVjgJb0$3@A)%&t2kC7A<&Rcg zEB4^QgNLO%HU|f9@<9t0ETBvClPH|Lin~YUmRfx-f`|OJ89aEfx$(vuP5bukjnY5% zOwJ9`P(QBgl-XCxKZ^<=KlfW+IlB~iJoC&mmM3|;PMta#r6LV^r{l+u^Rr>@t1fc< zb32z2DR(#NtcdGo&6;KNg5=!D@zt(f+tjaL-(saSl}S%eM_#x7w<~89DPUtAPMDn!I4Rxv|<_D9LlTEj7-OSLTL(R#PC%K0-jZcbrmxq5o@|Th9EhYOt`ckUU z@=~tO=1m!2aFShH?69{79(cfU4Xgmw%csZ zHZCsCsJZ1y9+zAw_<%n-RqXE2p+iRM_O*D%7C`=r@4x^4a>aG%p5+17;NQA+YnumU z49K;TPwU*dvl%pKkd^17k3K>~^Q}nub#wP19p8oB%T}xpKz=YURjQPc>oirWRI&M6 zg_ZW6$ju@@`Ca74wjs@HwF)4A+_`h-&cFKVt2W0@&KCKRlXwpsAfH>aW=)&Vu2`|6 z&41Gm`C;r1z5Pn$rcg-xKh^iO)V|Cge0c-Z+kANgaR zefHTmxaPIjUb8&F0!(jojZ4lSS0GO?^^PazqD{`w0QAiiUvG+ZU)9uCNYe90-G7T{i(TG*_uY2B!hd2{yeGkiu@z{^k|i5t zCk@05+bxLyq~AE{MJvsL+u?yuV7u_g$I%x)qId7!MmcMmm~TXyFL-raAd(HIVCP(` zxXSWlZ1F*i!5eQ_6+r*Vhod)vI4B?d>7Q}BS~@WX{({ut8{o}YqeoMwOySwn$kxvh z2gnXX#)>e@jT9Rs$e+$8ZbPlGeRPOtLgq&1F0myQY;kvd3Lro2OY7R|@Hlbegq^#< zp7&^9eDMXh#k;ok8tb6Hl{Kh?$d+)vX ztW(!}4Wsu}20tiljuV4QF9R`2IP!*Si?4cIrXA^Fe-imk>d#_FdID(DE(9Xbs|ewxRO8Z~O7u%D~>q(5I2Bju2t zzQdG1B#&aeha6pnDSwXZFZCB!y8Ps?6dwojKUxc5c3naFE5)NWAZ3jObDd)MjDLzQ zwO$mof63g4c?qA0YvdVPu}tTJUVk~XQ!G=Td7oUa;u&7q`s5?vBj6+8Bj6(tQ3M)_ z8|$rkI3}3o%uz4v@Ye_l2%mfed<1+1d<1+1d<1+1d<1+1d<1+1N(ch1$70RHpG3Ed z@~Q-aQ}6iOX>HjK_YRJ;-hCfZ4J7M=N;IK2UToYtATZJz>$L1^fl3-!*c4bm z6DCYBdQEKCl(<*A`ffr=!^C^PtUCo8*8FIBo?Q>F-|dKJ?FeD9)D^ zY0H2ZE#I1?<#hA3=Kp#9%^JuYYqzos9YK65Xx;WrTE{y~>wBAI@8?qfExD4l?$)lw zWG;fVu5*QA8P*o&iBSabL04k6rN`4+FL^$*cVpfbX+Mw3ml7A&{5>V|%Hu*G^ui`xaNWfYeV(_eTA@>#g*vw<^oKXEo`a9Nv|6Zgu`sq#pmEjoei)8m*VQnz$ z&LQd21+5EDk_@@}%p&5$64-=2d-fcpKkB|%TTT6ui!b>eQeE3__5g}B9$tRZ4`v-M;>|PDe+*9Ft)%EL`A>{US;(7Hqdn@A7uNdzJ~SZ ztoavq?q}AbWl$5%o<>1J6!8z9v9(5joSv;Si)_>*AIFXzYuE6zj*t2T#?8r=wX~hJ z+B?-fHpZNv1EWIX10QrUhAo2t0KZ4gi|ZeGkc+XS*1=2ErU<|Gy1vMyI-Eq-V|w|s z9+R3AYCx!?pvHoF2Wk_jgW#AkV@BW-$vHrRfDw8Wv?e@Ed>p=DT|q9TuGZz-F{4Hp zodFltTw>?QMlBmD0&2BXs~3=oIfYzYQSxwFcRh-=?vAO_F?MY|*ih3#zl;|(102*> zphMtA-H#)sx{j!Jdw^{Tw+2BzwTAj$>}8}9DO>NP>C*NCHuO)8kHf~*N4ar({q@%a zEM#v#=yx!R)8T9_Tzs&piV7=gFI>2Ag<~$)YsU&(!Us~Pf(}uG22PA2V@f>?wMf+D z96o&5T~0k%x_3`B^^q${4~J5}pt;C)(?eYU*Hp?TFl8#M%*HGa*P?a!?@sssHI}hHuM{t zN57Gk{S*0}Yna=pDI7g|wE6MJA012Pozu)k%t`7mK-9jtMwB!w#If~!)Ej~kz8G8t zqdmL5_!u9jJIF=<)TLqX)RrO#^~KZxL#jnOB_37OF}4zp{($GzDl_^TKGfa97e9wC zU_00swVR9)W5t*;c8nqQqSUF%r(1nz+_*39kMYl@8b&eaROEA{`gdCZuc^=adTf+> za{NAXfy%*ceh+-;gTByPY~0~P?1Swgr^APPfQN>J+p?sxutfD6uKv(I-tnOBmpBXl z;Di2PU+6A1kH}07u=7L6N*yWnyn1%Fb)~dLHfoi*SN0U7mJIq@L^(uF|no7$yP=Rn^O?P$;S_#SM9+Cu7S zsY#|LHkAKiu5k8+&T}1ggYJEV>K>^zWu7k#KJh9evE#@T;&caFp)dRo@elSzjVSXN zb3OJ&JuN-~AAv5RYuF|}h$IjK-B(S!&z^dK)G_#07OE%hNndIp&N#ayj1vHpqhR zARD@apGGDyBo;v5*x$iR)R4=Ewh2Zg^k2fhvF6Ve-s_1M&`W$U^AuPxe`4DXBjzx^ z_dcU)%1oEdkqc_5BSDAt&GZ~5K8z_juO#`>zj$S19zrH;3tdJo?23cAjCl?GuzhN? zdEe%UnsjQ@bJH2*%#D<{7$Lhj;&>4&5X&=HfrXn#u{r!8dd0y$5RTOTkK$ifMCC+d$J$lXO@4x@v_RoAHzt~Kj^IU;_1le_%_;3$gPky43=A)L*7tx=S z1zeDUal%i78GC$CW9~@LJKt(vO@U#gNONc})lu$peek@h{Eqd5j2SvjJcMmK5{|3Y zzsql6S3z-UA@JdPFaqm%xqv`Eia8!Rzz5&VSYc0Y4+3PuZ%NnYP@AvoBTnqqq&aB@ ze%@g~EPyUCPvDF6{=)r)El!jWE6D{HGA z+k_f_`RGnCxY#7$(;9#8WCJdhTiW@|<$sB%G;Gb&@%OAhQ9eF1Auq7BXSjn5z22bygZy!Jd5VA!tiY(e zwlxa8Cm^Tdjq{j;nTxacTbzH(=OpTV*OCA*`XIeNr}*nG$q~r)gp#R<_`tG^V&GBU zzWL0YTbRAOLdh7Z@AMopNc%j@Qfh6PVkDPS4a7R3`iTHO@Q+o#VY;TI!{j^J$6m2A zF~H?a$X!-PNWbF*j{rW_#>5Xh{@GE4@cG%{;%+Dc_&8QS%d?M9-oxtSrvJaOBU)c{<`&AI*ba;55 z4R~(3SkKv466VU&w9x+#w9#S2nf(y;e({p5{kmMSBlpXD1Lco;M{@7K%k_SJxqJkC c1bhU11bhU11bhU11bhU11bhU11aczqfAHJEs{jB1 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/split_v b/cursors/Oxygen_Zion/cursors/split_v new file mode 100644 index 0000000000000000000000000000000000000000..e38085ce574e0788c9be2f4ba0eb0bac8fdb876e GIT binary patch literal 32416 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 B$Wj0R literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/text b/cursors/Oxygen_Zion/cursors/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/up_arrow b/cursors/Oxygen_Zion/cursors/up_arrow new file mode 100644 index 0000000000000000000000000000000000000000..ea3521c92282f8804fecf5b9cddd9712799e356e GIT binary patch literal 32416 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 vpd(H==Q{U`i{7ZI0m#cL@RMk1B&i~YA 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Zion/cursors/watch b/cursors/Oxygen_Zion/cursors/watch new file mode 120000 index 00000000..fd80437a --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/watch @@ -0,0 +1 @@ +wait \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/whats_this b/cursors/Oxygen_Zion/cursors/whats_this new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/Oxygen_Zion/cursors/whats_this @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/Oxygen_Zion/cursors/xterm b/cursors/Oxygen_Zion/cursors/xterm new file mode 100644 index 0000000000000000000000000000000000000000..739f9733f2a97347ca73d1120dfe4f2519a041a6 GIT binary patch literal 32416 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 +Copyright (C) 2007-2008 by David Miller +Copyright (C) 2007-2008 by Matthew Woehlke + +This cursor theme and the associated scripts are free software: +you can redistribute them and/or modify them under the terms of +the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) +any later version. + +This cursor theme and the associated scripts are distributed in +the hope that they 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. If not, see . diff --git a/cursors/src/LICENSE b/cursors/src/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/cursors/src/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/cursors/src/README b/cursors/src/README new file mode 100644 index 00000000..f1638748 --- /dev/null +++ b/cursors/src/README @@ -0,0 +1,17 @@ +How to generate all the pngs and the SVGs and the cursor files: + +mkdir build +cd build +cmake ../src +make [-j ] [theme-|package-] + +Where is the number of jobs to run in parallel (man make), and is the color you want generated if you want just one of them. + +The build system is still young, with rough edges (e.g. doesn't check if inkscape is found). Hopefully it will work, +but there may still be problems. + +All of what you see here is to be considered a work in progress, and therefore must be considered as unreleased. + +Information on the graphics: Riccardo "ruphy" Iaconelli +Information on the build system: Matthew Woehlke and Diego 'Flameeyes' Pettenò. +Preferred place to get help: #oxygen on irc.freenode.net (http://freenode.net/) diff --git a/cursors/src/TODO b/cursors/src/TODO new file mode 100644 index 00000000..3472fe7a --- /dev/null +++ b/cursors/src/TODO @@ -0,0 +1 @@ +* fix hotspot for clock diff --git a/cursors/src/config.cmake b/cursors/src/config.cmake new file mode 100644 index 00000000..dfadfe75 --- /dev/null +++ b/cursors/src/config.cmake @@ -0,0 +1,8 @@ +file(GLOB SVGS svg/*.svg) +file(GLOB CONFIGS config/*.in) +file(GLOB SYMLINKS_PATHS symlinks/*) + +set(SVGDIR ${CMAKE_SOURCE_DIR}/svg) +set(CONFIGDIR ${CMAKE_SOURCE_DIR}/config) +set(MAKE_CONFIG ${CMAKE_SOURCE_DIR}/make_config.cmake) +set(MAKE_SVG ${CMAKE_SOURCE_DIR}/make_svg.cmake) diff --git a/cursors/src/config/Description b/cursors/src/config/Description new file mode 100644 index 00000000..84be4aab --- /dev/null +++ b/cursors/src/config/Description @@ -0,0 +1,5 @@ +== Namespec Description == + +WriteMe! + + diff --git a/cursors/src/config/X_cursor.in b/cursors/src/config/X_cursor.in new file mode 100644 index 00000000..04f86c3d --- /dev/null +++ b/cursors/src/config/X_cursor.in @@ -0,0 +1 @@ +24 12 12 x.png diff --git a/cursors/src/config/circle.in b/cursors/src/config/circle.in new file mode 100644 index 00000000..3d69e87e --- /dev/null +++ b/cursors/src/config/circle.in @@ -0,0 +1 @@ +24 12 12 circle.png diff --git a/cursors/src/config/closedhand.in b/cursors/src/config/closedhand.in new file mode 100644 index 00000000..cf73de12 --- /dev/null +++ b/cursors/src/config/closedhand.in @@ -0,0 +1 @@ +24 12 11 grab.png diff --git a/cursors/src/config/color-picker.in b/cursors/src/config/color-picker.in new file mode 100644 index 00000000..cdfe33b9 --- /dev/null +++ b/cursors/src/config/color-picker.in @@ -0,0 +1 @@ +24 2 20 picker.png diff --git a/cursors/src/config/copy.in b/cursors/src/config/copy.in new file mode 100644 index 00000000..ee8d91a0 --- /dev/null +++ b/cursors/src/config/copy.in @@ -0,0 +1 @@ +24 0 0 copy.png diff --git a/cursors/src/config/cross.in b/cursors/src/config/cross.in new file mode 100644 index 00000000..545353cf --- /dev/null +++ b/cursors/src/config/cross.in @@ -0,0 +1 @@ +24 7 7 cross.png diff --git a/cursors/src/config/fleur.in b/cursors/src/config/fleur.in new file mode 100644 index 00000000..470d84eb --- /dev/null +++ b/cursors/src/config/fleur.in @@ -0,0 +1 @@ +32 16 15 fleur.png diff --git a/cursors/src/config/forbidden.in b/cursors/src/config/forbidden.in new file mode 100644 index 00000000..1e7cf6b5 --- /dev/null +++ b/cursors/src/config/forbidden.in @@ -0,0 +1 @@ +24 0 0 forbidden.png diff --git a/cursors/src/config/half-busy.in b/cursors/src/config/half-busy.in new file mode 100644 index 00000000..97c8476b --- /dev/null +++ b/cursors/src/config/half-busy.in @@ -0,0 +1,18 @@ +32 0 0 half-busy17.png 40 +32 0 0 half-busy16.png 40 +32 0 0 half-busy15.png 40 +32 0 0 half-busy14.png 40 +32 0 0 half-busy13.png 40 +32 0 0 half-busy12.png 40 +32 0 0 half-busy11.png 40 +32 0 0 half-busy10.png 40 +32 0 0 half-busy9.png 40 +32 0 0 half-busy8.png 40 +32 0 0 half-busy7.png 40 +32 0 0 half-busy6.png 40 +32 0 0 half-busy5.png 40 +32 0 0 half-busy4.png 40 +32 0 0 half-busy3.png 40 +32 0 0 half-busy2.png 40 +32 0 0 half-busy1.png 40 +32 0 0 half-busy.png 40 \ No newline at end of file diff --git a/cursors/src/config/help.in b/cursors/src/config/help.in new file mode 100644 index 00000000..50dbbaf6 --- /dev/null +++ b/cursors/src/config/help.in @@ -0,0 +1 @@ +24 0 0 help.png diff --git a/cursors/src/config/left_ptr.in b/cursors/src/config/left_ptr.in new file mode 100644 index 00000000..f38772f2 --- /dev/null +++ b/cursors/src/config/left_ptr.in @@ -0,0 +1 @@ +24 5 0 left_ptr.png diff --git a/cursors/src/config/link.in b/cursors/src/config/link.in new file mode 100644 index 00000000..68d8bebb --- /dev/null +++ b/cursors/src/config/link.in @@ -0,0 +1 @@ +24 0 0 link.png diff --git a/cursors/src/config/openhand.in b/cursors/src/config/openhand.in new file mode 100644 index 00000000..561f8247 --- /dev/null +++ b/cursors/src/config/openhand.in @@ -0,0 +1 @@ +24 12 11 grab_open.png diff --git a/cursors/src/config/pencil.in b/cursors/src/config/pencil.in new file mode 100644 index 00000000..cf73a68b --- /dev/null +++ b/cursors/src/config/pencil.in @@ -0,0 +1 @@ +24 3 20 pencil.png diff --git a/cursors/src/config/pirate.in b/cursors/src/config/pirate.in new file mode 100644 index 00000000..dff24cdd --- /dev/null +++ b/cursors/src/config/pirate.in @@ -0,0 +1 @@ +24 12 12 kill.png diff --git a/cursors/src/config/plus.in b/cursors/src/config/plus.in new file mode 100644 index 00000000..177737af --- /dev/null +++ b/cursors/src/config/plus.in @@ -0,0 +1 @@ +24 12 12 plus.png diff --git a/cursors/src/config/pointing_hand.in b/cursors/src/config/pointing_hand.in new file mode 100644 index 00000000..e9f3bce1 --- /dev/null +++ b/cursors/src/config/pointing_hand.in @@ -0,0 +1 @@ +24 9 1 hand.png diff --git a/cursors/src/config/size_bdiag.in b/cursors/src/config/size_bdiag.in new file mode 100644 index 00000000..0c2de7b1 --- /dev/null +++ b/cursors/src/config/size_bdiag.in @@ -0,0 +1 @@ +24 11 11 size_diag-tr2bl.png diff --git a/cursors/src/config/size_fdiag.in b/cursors/src/config/size_fdiag.in new file mode 100644 index 00000000..70ec1457 --- /dev/null +++ b/cursors/src/config/size_fdiag.in @@ -0,0 +1 @@ +24 11 11 size_diag-tl2br.png diff --git a/cursors/src/config/size_hor.in b/cursors/src/config/size_hor.in new file mode 100644 index 00000000..e3640ac5 --- /dev/null +++ b/cursors/src/config/size_hor.in @@ -0,0 +1 @@ +24 11 11 size_hor.png diff --git a/cursors/src/config/size_ver.in b/cursors/src/config/size_ver.in new file mode 100644 index 00000000..1277ad78 --- /dev/null +++ b/cursors/src/config/size_ver.in @@ -0,0 +1 @@ +24 11 11 size_ver.png diff --git a/cursors/src/config/split_h.in b/cursors/src/config/split_h.in new file mode 100644 index 00000000..b551623b --- /dev/null +++ b/cursors/src/config/split_h.in @@ -0,0 +1 @@ +24 11 11 split_h.png diff --git a/cursors/src/config/split_v.in b/cursors/src/config/split_v.in new file mode 100644 index 00000000..70edff01 --- /dev/null +++ b/cursors/src/config/split_v.in @@ -0,0 +1 @@ +24 11 11 split_v.png diff --git a/cursors/src/config/up_arrow.in b/cursors/src/config/up_arrow.in new file mode 100644 index 00000000..11d4efbb --- /dev/null +++ b/cursors/src/config/up_arrow.in @@ -0,0 +1 @@ +24 12 0 up_arrow.png diff --git a/cursors/src/config/wait.in b/cursors/src/config/wait.in new file mode 100644 index 00000000..bf83b522 --- /dev/null +++ b/cursors/src/config/wait.in @@ -0,0 +1,18 @@ +32 16 16 busy17.png 40 +32 16 16 busy16.png 40 +32 16 16 busy15.png 40 +32 16 16 busy14.png 40 +32 16 16 busy13.png 40 +32 16 16 busy12.png 40 +32 16 16 busy11.png 40 +32 16 16 busy10.png 40 +32 16 16 busy9.png 40 +32 16 16 busy8.png 40 +32 16 16 busy7.png 40 +32 16 16 busy6.png 40 +32 16 16 busy5.png 40 +32 16 16 busy4.png 40 +32 16 16 busy3.png 40 +32 16 16 busy2.png 40 +32 16 16 busy1.png 40 +32 16 16 busy.png 40 \ No newline at end of file diff --git a/cursors/src/config/xterm.in b/cursors/src/config/xterm.in new file mode 100644 index 00000000..c5f341dd --- /dev/null +++ b/cursors/src/config/xterm.in @@ -0,0 +1 @@ +24 4 9 xterm.png diff --git a/cursors/src/cursors.cmake b/cursors/src/cursors.cmake new file mode 100644 index 00000000..19f6bb58 --- /dev/null +++ b/cursors/src/cursors.cmake @@ -0,0 +1,120 @@ +# This macro produces a "themed" version of the SVG, using the spcified colors. +# Than, it renders this themed SVG to PNG files. +# You can specify one or more dpi values when you call this macro. +macro(add_cursor cursor color theme dpi) + # Produce a "themed" SVG + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/svg/${cursor}.svg + DEPENDS ${MAKE_SVG} ${CMAKE_CURRENT_SOURCE_DIR}/colors.in ${SVGDIR}/${cursor}.svg + COMMAND ${CMAKE_COMMAND} -Dconfig=${CMAKE_CURRENT_SOURCE_DIR}/colors.in + -Dinput=${SVGDIR}/${cursor}.svg + -Doutput=${CMAKE_BINARY_DIR}/oxy-${theme}/svg/${cursor}.svg + -P ${MAKE_SVG} + ) + # Prepare a list of resolutions in dpi + set(resolutions ${ARGV}) + list(REMOVE_AT resolutions 0) + list(REMOVE_AT resolutions 0) + list(REMOVE_AT resolutions 0) + # Render the SVG + foreach(resolution ${resolutions}) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/png/${resolution}/${cursor}.png + DEPENDS ${CMAKE_BINARY_DIR}/oxy-${theme}/svg/${cursor}.svg + COMMAND ${INKSCAPE} --without-gui --export-dpi=${resolution} + --export-png=${CMAKE_BINARY_DIR}/oxy-${theme}/png/${resolution}/${cursor}.png + ${CMAKE_BINARY_DIR}/oxy-${theme}/svg/${cursor}.svg + ) + endforeach(resolution) +endmacro(add_cursor) + +macro(add_x_cursor theme cursor dpi) + # Prepare a list of resolutions in dpi + set(resolutions ${ARGV}) + list(REMOVE_AT resolutions 0) + list(REMOVE_AT resolutions 0) + # Prepare a list of the png files that are necessary + set(inputs) + foreach(png ${${cursor}_inputs}) + foreach(resolution ${resolutions}) + list(APPEND inputs ${CMAKE_BINARY_DIR}/oxy-${theme}/png/${resolution}/${png}) + endforeach(resolution) + endforeach(png) + # Make a coma-separated list (normal lists can't be passed as argument) + string(REPLACE ";" "," resolutions_coma_separated "${resolutions}") + # Adopt the x cursor config file to the requested resolutions + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + DEPENDS ${MAKE_CONFIG} ${CONFIGDIR}/${cursor}.in + COMMAND ${CMAKE_COMMAND} -Dconfig=${CONFIGDIR}/${cursor}.in + -Doutput=${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + -Dresolutions=${resolutions_coma_separated} + -P ${MAKE_CONFIG} + ) + # Use the adopted x cursor config file and the png files to produce the cursor file + if(NOT WIN32) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors/${cursor} + DEPENDS ${inputs} ${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + COMMAND ${XCURSORGEN} -p ${CMAKE_BINARY_DIR}/oxy-${theme}/png + ${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors/${cursor} + ) + else(NOT WIN32) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors/${cursor} + DEPENDS ${inputs} ${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + COMMAND "${CMAKE_SOURCE_DIR}/wincursor.py" ${CMAKE_BINARY_DIR}/oxy-${theme}/png + ${CMAKE_BINARY_DIR}/oxy-${theme}/config/${cursor}.in + ${CMAKE_BINARY_DIR}/wincursors/oxy-${theme} + ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors/${cursor} + ) + endif(NOT WIN32) +endmacro(add_x_cursor) + +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/packages) + +# Macro that adds a theme. You can specify more than one dpi value (overloaded macro). +macro(add_theme color theme dpi) + # Prepare a list of resolutions in dpi + set(resolutions ${ARGV}) + list(REMOVE_AT resolutions 0) + list(REMOVE_AT resolutions 0) + # Make missing directories + foreach (resolution ${resolutions}) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/oxy-${theme}/png/${resolution}) + endforeach(resolution) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/oxy-${theme}/svg) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/oxy-${theme}/config) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors) + if(WIN32) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/wincursors/oxy-${theme}) + endif(WIN32) + set(${theme}_cursors) + # render SVG to PNG files + foreach(svg ${SVGS}) + string(REGEX REPLACE ".*/" "" cursor ${svg}) # use relative paths + string(REGEX REPLACE "[.]svg" "" cursor ${cursor}) # remove ".svg" from the path + add_cursor(${cursor} ${color} ${theme} ${resolutions}) # Render a "themed" version of the SVG to PNG files. + endforeach(svg) + # produce cursor files from the png files + foreach(cursor ${CURSORS}) + add_x_cursor(${theme} ${cursor} ${resolutions}) + list(APPEND ${theme}_cursors ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors/${cursor}) + endforeach(cursor) + # add the symbolic links + foreach(symlink ${SYMLINKS_PATHS}) + file(COPY ${symlink} DESTINATION ${CMAKE_BINARY_DIR}/oxy-${theme}/cursors) + endforeach(symlink) + # packaging + add_custom_target(theme-${theme} ALL DEPENDS ${${theme}_cursors}) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/oxy-${theme}/index.theme + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/index.theme + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/index.theme + ${CMAKE_BINARY_DIR}/oxy-${theme}/index.theme + ) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/packages/oxy-${theme}.tar.bz2 + DEPENDS ${${theme}_cursors} ${CMAKE_BINARY_DIR}/oxy-${theme}/index.theme + COMMAND ${TAR} cjf ${CMAKE_BINARY_DIR}/packages/oxy-${theme}.tar.bz2 + oxy-${theme}/cursors + oxy-${theme}/index.theme + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + add_custom_target(package-${theme} ALL DEPENDS ${CMAKE_BINARY_DIR}/packages/oxy-${theme}.tar.bz2) +endmacro(add_theme) diff --git a/cursors/src/make_config.cmake b/cursors/src/make_config.cmake new file mode 100644 index 00000000..b9f6132a --- /dev/null +++ b/cursors/src/make_config.cmake @@ -0,0 +1,33 @@ +macro(adjust in_size in_xhot in_yhot) + #math(EXPR out_size "( ${in_size} * ${resolution} ) / 90") + # The Oxygen cursors have different default sizes at 90 dpi: + # Some have 24x24 px, others have 32x32 px. This causes some + # side-effects when you want to choose your cursor size. + # Instead of the real in_size, we use 24 as convenience value. + # Xcursorlib interpretats this as a _nominal_ size; it is legal + # that the nominal size is different from the real size of the + # png image. + math(EXPR out_size "( 24 * ${resolution} ) / 90") + math(EXPR out_xhot "( ${in_xhot} * ${resolution} ) / 90") + math(EXPR out_yhot "( ${in_yhot} * ${resolution} ) / 90") + set(out_line "${out_size} ${out_xhot} ${out_yhot} ${resolution}/${ARGN}") + string(REPLACE ";" " " out_line "${out_line}") + list(APPEND out_contents "${out_line}") +endmacro(adjust) + +# load config file +file(READ "${config}" in_contents) +set(out_contents) +string(REPLACE "\n" ";" in_contents "${in_contents}") +# convert the coma separated list in a standard list +string(REPLACE "," ";" resolutions ${resolutions}) +# adjust the config file +foreach(resolution ${resolutions}) + foreach(in_line ${in_contents}) + string(REGEX REPLACE "[ \t]+" ";" in_line "${in_line}") + adjust(${in_line}) + endforeach(in_line) +endforeach(resolution) +# save the adjusted config file +string(REPLACE ";" "\n" out_contents "${out_contents}") +file(WRITE "${output}" "${out_contents}\n") diff --git a/cursors/src/make_svg.cmake b/cursors/src/make_svg.cmake new file mode 100644 index 00000000..7aa192c2 --- /dev/null +++ b/cursors/src/make_svg.cmake @@ -0,0 +1,20 @@ +include(${config}) + +if(NOT altLighterColor) + set(altLighterColor ${lighterColor}) +endif(NOT altLighterColor) +if(NOT altMediumColor) + set(altMediumColor ${mediumColor}) +endif(NOT altMediumColor) +if(NOT altDarkerColor) + set(altDarkerColor ${darkerColor}) +endif(NOT altDarkerColor) + +file(READ "${input}" contents) +string(REPLACE "#ff80ff;" "${lighterColor};" contents "${contents}") +string(REPLACE "#804080;" "${mediumColor};" contents "${contents}") +string(REPLACE "#201020;" "${darkerColor};" contents "${contents}") +string(REPLACE "#c080ff;" "${altLighterColor};" contents "${contents}") +string(REPLACE "#604080;" "${altMediumColor};" contents "${contents}") +string(REPLACE "#181020;" "${altDarkerColor};" contents "${contents}") +file(WRITE "${output}" "${contents}") diff --git a/cursors/src/setup.cmake b/cursors/src/setup.cmake new file mode 100644 index 00000000..aedb7772 --- /dev/null +++ b/cursors/src/setup.cmake @@ -0,0 +1,32 @@ +find_program(TAR tar) +# TODO abort if tar not found (or does not understand cjf?) +if(NOT WIN32) +find_program(INKSCAPE inkscape) +# TODO abort if inkscape not found + +find_program(XCURSORGEN xcursorgen) +# TODO abort if xcursorgen not found +else(NOT WIN32) +find_program(INKSCAPE inkscape "$ENV{PROGRAMFILES}/Inkscape" "$ENV{INKSCAPE_DIR}") +endif(NOT WIN32) + +# For a given cursor, this macro defines a variable ${cursor}_inputs that contains +# a list of the necessary png files. +macro(set_dependencies cursor) + file(READ ${CONFIGDIR}/${cursor}.in config_contents) + string(REPLACE "\n" ";" config_contents ${config_contents}) + set(${cursor}_inputs) + foreach(png ${config_contents}) + string(REGEX REPLACE "[0-9]* [0-9]* [0-9]* " "" png ${png}) + string(REGEX REPLACE "[.]png [0-9]*$" ".png" png ${png}) + list(APPEND ${cursor}_inputs ${png}) + endforeach(png) +endmacro(set_dependencies) + +set(CURSORS) +foreach(config ${CONFIGS}) + string(REGEX REPLACE ".*/" "" cursor ${config}) + string(REGEX REPLACE "[.]in" "" cursor ${cursor}) + list(APPEND CURSORS ${cursor}) + set_dependencies(${cursor}) +endforeach(config) \ No newline at end of file diff --git a/cursors/src/svg/busy.svg b/cursors/src/svg/busy.svg new file mode 100644 index 00000000..5348f4fc --- /dev/null +++ b/cursors/src/svg/busy.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy1.svg b/cursors/src/svg/busy1.svg new file mode 100644 index 00000000..a00f18ca --- /dev/null +++ b/cursors/src/svg/busy1.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy10.svg b/cursors/src/svg/busy10.svg new file mode 100644 index 00000000..9b7c2a0b --- /dev/null +++ b/cursors/src/svg/busy10.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy11.svg b/cursors/src/svg/busy11.svg new file mode 100644 index 00000000..42a3c0b9 --- /dev/null +++ b/cursors/src/svg/busy11.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy12.svg b/cursors/src/svg/busy12.svg new file mode 100644 index 00000000..c4b1108f --- /dev/null +++ b/cursors/src/svg/busy12.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy13.svg b/cursors/src/svg/busy13.svg new file mode 100644 index 00000000..2c18a098 --- /dev/null +++ b/cursors/src/svg/busy13.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy14.svg b/cursors/src/svg/busy14.svg new file mode 100644 index 00000000..f0255095 --- /dev/null +++ b/cursors/src/svg/busy14.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy15.svg b/cursors/src/svg/busy15.svg new file mode 100644 index 00000000..e712da9d --- /dev/null +++ b/cursors/src/svg/busy15.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy16.svg b/cursors/src/svg/busy16.svg new file mode 100644 index 00000000..c7465c6d --- /dev/null +++ b/cursors/src/svg/busy16.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy17.svg b/cursors/src/svg/busy17.svg new file mode 100644 index 00000000..045c554a --- /dev/null +++ b/cursors/src/svg/busy17.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy2.svg b/cursors/src/svg/busy2.svg new file mode 100644 index 00000000..5257eb01 --- /dev/null +++ b/cursors/src/svg/busy2.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy3.svg b/cursors/src/svg/busy3.svg new file mode 100644 index 00000000..c4e4ec60 --- /dev/null +++ b/cursors/src/svg/busy3.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy4.svg b/cursors/src/svg/busy4.svg new file mode 100644 index 00000000..76e87c4a --- /dev/null +++ b/cursors/src/svg/busy4.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy5.svg b/cursors/src/svg/busy5.svg new file mode 100644 index 00000000..7fea7b17 --- /dev/null +++ b/cursors/src/svg/busy5.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy6.svg b/cursors/src/svg/busy6.svg new file mode 100644 index 00000000..fbcc072b --- /dev/null +++ b/cursors/src/svg/busy6.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy7.svg b/cursors/src/svg/busy7.svg new file mode 100644 index 00000000..87dcb5b4 --- /dev/null +++ b/cursors/src/svg/busy7.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy8.svg b/cursors/src/svg/busy8.svg new file mode 100644 index 00000000..573acd94 --- /dev/null +++ b/cursors/src/svg/busy8.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/busy9.svg b/cursors/src/svg/busy9.svg new file mode 100644 index 00000000..6e58ac34 --- /dev/null +++ b/cursors/src/svg/busy9.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/cursors/src/svg/circle.svg b/cursors/src/svg/circle.svg new file mode 100644 index 00000000..67c0b4d9 --- /dev/null +++ b/cursors/src/svg/circle.svg @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/copy.svg b/cursors/src/svg/copy.svg new file mode 100644 index 00000000..eaf56371 --- /dev/null +++ b/cursors/src/svg/copy.svg @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/cross.svg b/cursors/src/svg/cross.svg new file mode 100644 index 00000000..c927f3ff --- /dev/null +++ b/cursors/src/svg/cross.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cursors/src/svg/dnd-move.svg b/cursors/src/svg/dnd-move.svg new file mode 100644 index 00000000..916dffd9 --- /dev/null +++ b/cursors/src/svg/dnd-move.svg @@ -0,0 +1,717 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/cursors/src/svg/fleur.svg b/cursors/src/svg/fleur.svg new file mode 100644 index 00000000..3b25aada --- /dev/null +++ b/cursors/src/svg/fleur.svg @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/forbidden.svg b/cursors/src/svg/forbidden.svg new file mode 100644 index 00000000..63fc5a35 --- /dev/null +++ b/cursors/src/svg/forbidden.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/grab.svg b/cursors/src/svg/grab.svg new file mode 100644 index 00000000..1a97be9b --- /dev/null +++ b/cursors/src/svg/grab.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/grab_open.svg b/cursors/src/svg/grab_open.svg new file mode 100644 index 00000000..b8b1cdf0 --- /dev/null +++ b/cursors/src/svg/grab_open.svg @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy.svg b/cursors/src/svg/half-busy.svg new file mode 100644 index 00000000..d27601c2 --- /dev/null +++ b/cursors/src/svg/half-busy.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy1.svg b/cursors/src/svg/half-busy1.svg new file mode 100644 index 00000000..0cc73e8c --- /dev/null +++ b/cursors/src/svg/half-busy1.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy10.svg b/cursors/src/svg/half-busy10.svg new file mode 100644 index 00000000..4140457f --- /dev/null +++ b/cursors/src/svg/half-busy10.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy11.svg b/cursors/src/svg/half-busy11.svg new file mode 100644 index 00000000..f8883fe6 --- /dev/null +++ b/cursors/src/svg/half-busy11.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy12.svg b/cursors/src/svg/half-busy12.svg new file mode 100644 index 00000000..d0c2acf6 --- /dev/null +++ b/cursors/src/svg/half-busy12.svg @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy13.svg b/cursors/src/svg/half-busy13.svg new file mode 100644 index 00000000..b3f5a556 --- /dev/null +++ b/cursors/src/svg/half-busy13.svg @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy14.svg b/cursors/src/svg/half-busy14.svg new file mode 100644 index 00000000..e5530a62 --- /dev/null +++ b/cursors/src/svg/half-busy14.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy15.svg b/cursors/src/svg/half-busy15.svg new file mode 100644 index 00000000..f33a7c9b --- /dev/null +++ b/cursors/src/svg/half-busy15.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy16.svg b/cursors/src/svg/half-busy16.svg new file mode 100644 index 00000000..5266f2a1 --- /dev/null +++ b/cursors/src/svg/half-busy16.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy17.svg b/cursors/src/svg/half-busy17.svg new file mode 100644 index 00000000..42d4f228 --- /dev/null +++ b/cursors/src/svg/half-busy17.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy2.svg b/cursors/src/svg/half-busy2.svg new file mode 100644 index 00000000..a624f925 --- /dev/null +++ b/cursors/src/svg/half-busy2.svg @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy3.svg b/cursors/src/svg/half-busy3.svg new file mode 100644 index 00000000..abb5af86 --- /dev/null +++ b/cursors/src/svg/half-busy3.svg @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy4.svg b/cursors/src/svg/half-busy4.svg new file mode 100644 index 00000000..2f4311a9 --- /dev/null +++ b/cursors/src/svg/half-busy4.svg @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy5.svg b/cursors/src/svg/half-busy5.svg new file mode 100644 index 00000000..2cc12b94 --- /dev/null +++ b/cursors/src/svg/half-busy5.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy6.svg b/cursors/src/svg/half-busy6.svg new file mode 100644 index 00000000..e711c940 --- /dev/null +++ b/cursors/src/svg/half-busy6.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy7.svg b/cursors/src/svg/half-busy7.svg new file mode 100644 index 00000000..fd495239 --- /dev/null +++ b/cursors/src/svg/half-busy7.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy8.svg b/cursors/src/svg/half-busy8.svg new file mode 100644 index 00000000..63b21ac8 --- /dev/null +++ b/cursors/src/svg/half-busy8.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/half-busy9.svg b/cursors/src/svg/half-busy9.svg new file mode 100644 index 00000000..bdd7fbf9 --- /dev/null +++ b/cursors/src/svg/half-busy9.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/hand.svg b/cursors/src/svg/hand.svg new file mode 100644 index 00000000..0ae210dd --- /dev/null +++ b/cursors/src/svg/hand.svg @@ -0,0 +1,516 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/help.svg b/cursors/src/svg/help.svg new file mode 100644 index 00000000..3566f4ef --- /dev/null +++ b/cursors/src/svg/help.svg @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/kill.svg b/cursors/src/svg/kill.svg new file mode 100644 index 00000000..8fcc071c --- /dev/null +++ b/cursors/src/svg/kill.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/left_ptr.svg b/cursors/src/svg/left_ptr.svg new file mode 100644 index 00000000..de8c93bf --- /dev/null +++ b/cursors/src/svg/left_ptr.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/cursors/src/svg/link.svg b/cursors/src/svg/link.svg new file mode 100644 index 00000000..d1fba913 --- /dev/null +++ b/cursors/src/svg/link.svg @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/pencil.svg b/cursors/src/svg/pencil.svg new file mode 100644 index 00000000..d3a152e2 --- /dev/null +++ b/cursors/src/svg/pencil.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/picker.svg b/cursors/src/svg/picker.svg new file mode 100644 index 00000000..898be9b6 --- /dev/null +++ b/cursors/src/svg/picker.svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/plus.svg b/cursors/src/svg/plus.svg new file mode 100644 index 00000000..2bdf5384 --- /dev/null +++ b/cursors/src/svg/plus.svg @@ -0,0 +1,799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/cursors/src/svg/size_diag-tl2br.svg b/cursors/src/svg/size_diag-tl2br.svg new file mode 100644 index 00000000..3be88d69 --- /dev/null +++ b/cursors/src/svg/size_diag-tl2br.svg @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/size_diag-tr2bl.svg b/cursors/src/svg/size_diag-tr2bl.svg new file mode 100644 index 00000000..08a16650 --- /dev/null +++ b/cursors/src/svg/size_diag-tr2bl.svg @@ -0,0 +1,573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/size_hor.svg b/cursors/src/svg/size_hor.svg new file mode 100644 index 00000000..9ce3e800 --- /dev/null +++ b/cursors/src/svg/size_hor.svg @@ -0,0 +1,570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/size_ver.svg b/cursors/src/svg/size_ver.svg new file mode 100644 index 00000000..9d4055c0 --- /dev/null +++ b/cursors/src/svg/size_ver.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/split_h.svg b/cursors/src/svg/split_h.svg new file mode 100644 index 00000000..64034bc4 --- /dev/null +++ b/cursors/src/svg/split_h.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/split_v.svg b/cursors/src/svg/split_v.svg new file mode 100644 index 00000000..e33dfd3e --- /dev/null +++ b/cursors/src/svg/split_v.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/up_arrow.svg b/cursors/src/svg/up_arrow.svg new file mode 100644 index 00000000..f1e3946a --- /dev/null +++ b/cursors/src/svg/up_arrow.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/x.svg b/cursors/src/svg/x.svg new file mode 100644 index 00000000..81c1b0c8 --- /dev/null +++ b/cursors/src/svg/x.svg @@ -0,0 +1,1130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cursors/src/svg/xterm.svg b/cursors/src/svg/xterm.svg new file mode 100644 index 00000000..321a94f3 --- /dev/null +++ b/cursors/src/svg/xterm.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/cursors/src/symlinks/.directory b/cursors/src/symlinks/.directory new file mode 100644 index 00000000..9fea84a3 --- /dev/null +++ b/cursors/src/symlinks/.directory @@ -0,0 +1,5 @@ +[Dolphin] +AdditionalInfoV2=Details_Size,Details_Date,CustomizedDetails +Timestamp=2011,9,4,15,13,34 +Version=2 +ViewMode=1 diff --git a/cursors/src/symlinks/00000000000000020006000e7e9ffc3f b/cursors/src/symlinks/00000000000000020006000e7e9ffc3f new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/src/symlinks/00000000000000020006000e7e9ffc3f @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/src/symlinks/00008160000006810000408080010102 b/cursors/src/symlinks/00008160000006810000408080010102 new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/src/symlinks/00008160000006810000408080010102 @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/src/symlinks/03b6e0fcb3499374a867c041f52298f0 b/cursors/src/symlinks/03b6e0fcb3499374a867c041f52298f0 new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/src/symlinks/03b6e0fcb3499374a867c041f52298f0 @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/src/symlinks/08e8e1c95fe2fc01f976f1e063a24ccd b/cursors/src/symlinks/08e8e1c95fe2fc01f976f1e063a24ccd new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/src/symlinks/08e8e1c95fe2fc01f976f1e063a24ccd @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/src/symlinks/1081e37283d90000800003c07f3ef6bf b/cursors/src/symlinks/1081e37283d90000800003c07f3ef6bf new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/src/symlinks/1081e37283d90000800003c07f3ef6bf @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/src/symlinks/3085a0e285430894940527032f8b26df b/cursors/src/symlinks/3085a0e285430894940527032f8b26df new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/src/symlinks/3085a0e285430894940527032f8b26df @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/src/symlinks/3ecb610c1bf2410f44200f48c40d3599 b/cursors/src/symlinks/3ecb610c1bf2410f44200f48c40d3599 new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/src/symlinks/3ecb610c1bf2410f44200f48c40d3599 @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/src/symlinks/4498f0e0c1937ffe01fd06f973665830 b/cursors/src/symlinks/4498f0e0c1937ffe01fd06f973665830 new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/4498f0e0c1937ffe01fd06f973665830 @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/5c6cd98b3f3ebcb1f9c7f1c204630408 b/cursors/src/symlinks/5c6cd98b3f3ebcb1f9c7f1c204630408 new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/src/symlinks/5c6cd98b3f3ebcb1f9c7f1c204630408 @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/src/symlinks/6407b0e94181790501fd1e167b474872 b/cursors/src/symlinks/6407b0e94181790501fd1e167b474872 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/src/symlinks/6407b0e94181790501fd1e167b474872 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/src/symlinks/640fb0e74195791501fd1ed57b41487f b/cursors/src/symlinks/640fb0e74195791501fd1ed57b41487f new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/src/symlinks/640fb0e74195791501fd1ed57b41487f @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/src/symlinks/9081237383d90e509aa00f00170e968f b/cursors/src/symlinks/9081237383d90e509aa00f00170e968f new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/9081237383d90e509aa00f00170e968f @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/9d800788f1b08800ae810202380a0822 b/cursors/src/symlinks/9d800788f1b08800ae810202380a0822 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/src/symlinks/9d800788f1b08800ae810202380a0822 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/src/symlinks/a2a266d0498c3104214a47bd64ab0fc8 b/cursors/src/symlinks/a2a266d0498c3104214a47bd64ab0fc8 new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/src/symlinks/a2a266d0498c3104214a47bd64ab0fc8 @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/src/symlinks/alias b/cursors/src/symlinks/alias new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/src/symlinks/alias @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/src/symlinks/all-scroll b/cursors/src/symlinks/all-scroll new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/src/symlinks/all-scroll @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/src/symlinks/b66166c04f8c3109214a4fbd64a50fc8 b/cursors/src/symlinks/b66166c04f8c3109214a4fbd64a50fc8 new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/src/symlinks/b66166c04f8c3109214a4fbd64a50fc8 @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/src/symlinks/col-resize b/cursors/src/symlinks/col-resize new file mode 120000 index 00000000..179b52be --- /dev/null +++ b/cursors/src/symlinks/col-resize @@ -0,0 +1 @@ +split_v \ No newline at end of file diff --git a/cursors/src/symlinks/crossed_circle b/cursors/src/symlinks/crossed_circle new file mode 120000 index 00000000..031757cf --- /dev/null +++ b/cursors/src/symlinks/crossed_circle @@ -0,0 +1 @@ +circle \ No newline at end of file diff --git a/cursors/src/symlinks/d9ce0ab605698f320427677b458ad60b b/cursors/src/symlinks/d9ce0ab605698f320427677b458ad60b new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/src/symlinks/d9ce0ab605698f320427677b458ad60b @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/src/symlinks/dnd-copy b/cursors/src/symlinks/dnd-copy new file mode 120000 index 00000000..88740b2c --- /dev/null +++ b/cursors/src/symlinks/dnd-copy @@ -0,0 +1 @@ +copy \ No newline at end of file diff --git a/cursors/src/symlinks/dnd-link b/cursors/src/symlinks/dnd-link new file mode 120000 index 00000000..c150ede2 --- /dev/null +++ b/cursors/src/symlinks/dnd-link @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/cursors/src/symlinks/dnd-move b/cursors/src/symlinks/dnd-move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/dnd-move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/dnd-no-drop b/cursors/src/symlinks/dnd-no-drop new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/src/symlinks/dnd-no-drop @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/src/symlinks/dnd-none b/cursors/src/symlinks/dnd-none new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/dnd-none @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/e-resize b/cursors/src/symlinks/e-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/src/symlinks/e-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/src/symlinks/e29285e634086352946a0e7090d73106 b/cursors/src/symlinks/e29285e634086352946a0e7090d73106 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/src/symlinks/e29285e634086352946a0e7090d73106 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/src/symlinks/fcf21c00b30f7e3f83fe0dfd12e71cff b/cursors/src/symlinks/fcf21c00b30f7e3f83fe0dfd12e71cff new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/fcf21c00b30f7e3f83fe0dfd12e71cff @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/hand1 b/cursors/src/symlinks/hand1 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/src/symlinks/hand1 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/src/symlinks/hand2 b/cursors/src/symlinks/hand2 new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/src/symlinks/hand2 @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/src/symlinks/ibeam b/cursors/src/symlinks/ibeam new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/src/symlinks/ibeam @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/src/symlinks/left_ptr_watch b/cursors/src/symlinks/left_ptr_watch new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/src/symlinks/left_ptr_watch @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/src/symlinks/move b/cursors/src/symlinks/move new file mode 120000 index 00000000..3e941780 --- /dev/null +++ b/cursors/src/symlinks/move @@ -0,0 +1 @@ +closedhand \ No newline at end of file diff --git a/cursors/src/symlinks/n-resize b/cursors/src/symlinks/n-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/src/symlinks/n-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/src/symlinks/not-allowed b/cursors/src/symlinks/not-allowed new file mode 120000 index 00000000..74313ca4 --- /dev/null +++ b/cursors/src/symlinks/not-allowed @@ -0,0 +1 @@ +forbidden \ No newline at end of file diff --git a/cursors/src/symlinks/pointer b/cursors/src/symlinks/pointer new file mode 120000 index 00000000..76c78220 --- /dev/null +++ b/cursors/src/symlinks/pointer @@ -0,0 +1 @@ +pointing_hand \ No newline at end of file diff --git a/cursors/src/symlinks/progress b/cursors/src/symlinks/progress new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/src/symlinks/progress @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/src/symlinks/question_arrow b/cursors/src/symlinks/question_arrow new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/src/symlinks/question_arrow @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/src/symlinks/row-resize b/cursors/src/symlinks/row-resize new file mode 120000 index 00000000..e3aa7487 --- /dev/null +++ b/cursors/src/symlinks/row-resize @@ -0,0 +1 @@ +split_h \ No newline at end of file diff --git a/cursors/src/symlinks/s-resize b/cursors/src/symlinks/s-resize new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/src/symlinks/s-resize @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/src/symlinks/sb_h_double_arrow b/cursors/src/symlinks/sb_h_double_arrow new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/src/symlinks/sb_h_double_arrow @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/src/symlinks/sb_v_double_arrow b/cursors/src/symlinks/sb_v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/src/symlinks/sb_v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/src/symlinks/size_all b/cursors/src/symlinks/size_all new file mode 120000 index 00000000..147f7449 --- /dev/null +++ b/cursors/src/symlinks/size_all @@ -0,0 +1 @@ +fleur \ No newline at end of file diff --git a/cursors/src/symlinks/text b/cursors/src/symlinks/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/src/symlinks/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/src/symlinks/v_double_arrow b/cursors/src/symlinks/v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/src/symlinks/v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/src/symlinks/w-resize b/cursors/src/symlinks/w-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/src/symlinks/w-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/src/symlinks/watch b/cursors/src/symlinks/watch new file mode 120000 index 00000000..fd80437a --- /dev/null +++ b/cursors/src/symlinks/watch @@ -0,0 +1 @@ +wait \ No newline at end of file diff --git a/cursors/src/symlinks/whats_this b/cursors/src/symlinks/whats_this new file mode 120000 index 00000000..4cea3acc --- /dev/null +++ b/cursors/src/symlinks/whats_this @@ -0,0 +1 @@ +help \ No newline at end of file diff --git a/cursors/src/theme-black/CMakeLists.txt b/cursors/src/theme-black/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-black/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-black/colors.in b/cursors/src/theme-black/colors.in new file mode 100644 index 00000000..e8a38469 --- /dev/null +++ b/cursors/src/theme-black/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#aaaaaa") +set(mediumColor "#000000") +set(darkerColor "#000000") diff --git a/cursors/src/theme-black/index.theme b/cursors/src/theme-black/index.theme new file mode 100644 index 00000000..a2a6d246 --- /dev/null +++ b/cursors/src/theme-black/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Black +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-blue/CMakeLists.txt b/cursors/src/theme-blue/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-blue/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-blue/colors.in b/cursors/src/theme-blue/colors.in new file mode 100644 index 00000000..e8f807ba --- /dev/null +++ b/cursors/src/theme-blue/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#a4c0e4") +set(mediumColor "#00438a") +set(darkerColor "#00316e") diff --git a/cursors/src/theme-blue/index.theme b/cursors/src/theme-blue/index.theme new file mode 100644 index 00000000..61f96a37 --- /dev/null +++ b/cursors/src/theme-blue/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Blue +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-bluecurve/CMakeLists.txt b/cursors/src/theme-bluecurve/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-bluecurve/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-bluecurve/colors.in b/cursors/src/theme-bluecurve/colors.in new file mode 100644 index 00000000..3758c2e9 --- /dev/null +++ b/cursors/src/theme-bluecurve/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#565D9D") +set(mediumColor "#000000") +set(darkerColor "#FFFFFF") diff --git a/cursors/src/theme-bluecurve/index.theme b/cursors/src/theme-bluecurve/index.theme new file mode 100644 index 00000000..a3e8de52 --- /dev/null +++ b/cursors/src/theme-bluecurve/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Bluecurve (Red Hat) +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-brown/CMakeLists.txt b/cursors/src/theme-brown/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-brown/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-brown/colors.in b/cursors/src/theme-brown/colors.in new file mode 100644 index 00000000..900e9683 --- /dev/null +++ b/cursors/src/theme-brown/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#debc85") +set(mediumColor "#57401e") +set(darkerColor "#382509") diff --git a/cursors/src/theme-brown/index.theme b/cursors/src/theme-brown/index.theme new file mode 100644 index 00000000..9a2e0b4c --- /dev/null +++ b/cursors/src/theme-brown/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Brown +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-cherry/CMakeLists.txt b/cursors/src/theme-cherry/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-cherry/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-cherry/colors.in b/cursors/src/theme-cherry/colors.in new file mode 100644 index 00000000..39df6cda --- /dev/null +++ b/cursors/src/theme-cherry/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#EFE9E8") +set(mediumColor "#D8A6AB") +set(darkerColor "#91454F") +set(altLighterColor "#D9E8C3") +set(altMediumColor "#B3D28F") +set(altDarkerColor "#55803A") diff --git a/cursors/src/theme-cherry/index.theme b/cursors/src/theme-cherry/index.theme new file mode 100644 index 00000000..61ecaa97 --- /dev/null +++ b/cursors/src/theme-cherry/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Cherry Blossom +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-chrome/CMakeLists.txt b/cursors/src/theme-chrome/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-chrome/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-chrome/colors.in b/cursors/src/theme-chrome/colors.in new file mode 100644 index 00000000..7d25b7bf --- /dev/null +++ b/cursors/src/theme-chrome/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#FFFFFF") +set(mediumColor "#AEB7C0") +set(darkerColor "#334050") +set(altLighterColor "#C1CFE0") +set(altMediumColor "#6080A0") +set(altDarkerColor "#263340") diff --git a/cursors/src/theme-chrome/index.theme b/cursors/src/theme-chrome/index.theme new file mode 100644 index 00000000..b1e46776 --- /dev/null +++ b/cursors/src/theme-chrome/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Chrome +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-desert/CMakeLists.txt b/cursors/src/theme-desert/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-desert/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-desert/colors.in b/cursors/src/theme-desert/colors.in new file mode 100644 index 00000000..462144d2 --- /dev/null +++ b/cursors/src/theme-desert/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#F0ECE5") +set(mediumColor "#B0ABA0") +set(darkerColor "#000000") +set(altLighterColor "#CA706D") +set(altMediumColor "#7D0909") +set(altDarkerColor "#000000") diff --git a/cursors/src/theme-desert/index.theme b/cursors/src/theme-desert/index.theme new file mode 100644 index 00000000..67d35bd2 --- /dev/null +++ b/cursors/src/theme-desert/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Desert +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-emerald/CMakeLists.txt b/cursors/src/theme-emerald/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-emerald/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-emerald/colors.in b/cursors/src/theme-emerald/colors.in new file mode 100644 index 00000000..3d6a3797 --- /dev/null +++ b/cursors/src/theme-emerald/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#99dcc6") +set(mediumColor "#00734d") +set(darkerColor "#00583f") diff --git a/cursors/src/theme-emerald/index.theme b/cursors/src/theme-emerald/index.theme new file mode 100644 index 00000000..865e7115 --- /dev/null +++ b/cursors/src/theme-emerald/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Emerald +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-green/CMakeLists.txt b/cursors/src/theme-green/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-green/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-green/colors.in b/cursors/src/theme-green/colors.in new file mode 100644 index 00000000..4d38ee2c --- /dev/null +++ b/cursors/src/theme-green/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#d8e8c2") +set(mediumColor "#00892c") +set(darkerColor "#006e29") diff --git a/cursors/src/theme-green/index.theme b/cursors/src/theme-green/index.theme new file mode 100644 index 00000000..2152cbf0 --- /dev/null +++ b/cursors/src/theme-green/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Green +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-grey/CMakeLists.txt b/cursors/src/theme-grey/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-grey/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-grey/colors.in b/cursors/src/theme-grey/colors.in new file mode 100644 index 00000000..eb2024ee --- /dev/null +++ b/cursors/src/theme-grey/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#eeeeec") +set(mediumColor "#555753") +set(darkerColor "#2e3436") diff --git a/cursors/src/theme-grey/index.theme b/cursors/src/theme-grey/index.theme new file mode 100644 index 00000000..39d45328 --- /dev/null +++ b/cursors/src/theme-grey/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Grey +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-honeycomb/CMakeLists.txt b/cursors/src/theme-honeycomb/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-honeycomb/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-honeycomb/colors.in b/cursors/src/theme-honeycomb/colors.in new file mode 100644 index 00000000..2f795f2f --- /dev/null +++ b/cursors/src/theme-honeycomb/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#E5E8E1") +set(mediumColor "#BABDB7") +set(darkerColor "#2F302E") +set(altLighterColor "#FFF299") +set(altMediumColor "#E3A700") +set(altDarkerColor "#403000") diff --git a/cursors/src/theme-honeycomb/index.theme b/cursors/src/theme-honeycomb/index.theme new file mode 100644 index 00000000..9a6a9308 --- /dev/null +++ b/cursors/src/theme-honeycomb/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Honeycomb +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-hot_orange/CMakeLists.txt b/cursors/src/theme-hot_orange/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-hot_orange/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-hot_orange/colors.in b/cursors/src/theme-hot_orange/colors.in new file mode 100644 index 00000000..5bf06978 --- /dev/null +++ b/cursors/src/theme-hot_orange/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#ffd9b0") +set(mediumColor "#cf4913") +set(darkerColor "#ac4311") diff --git a/cursors/src/theme-hot_orange/index.theme b/cursors/src/theme-hot_orange/index.theme new file mode 100644 index 00000000..6253db2c --- /dev/null +++ b/cursors/src/theme-hot_orange/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Hot Orange +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-lilac/CMakeLists.txt b/cursors/src/theme-lilac/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-lilac/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-lilac/colors.in b/cursors/src/theme-lilac/colors.in new file mode 100644 index 00000000..7e002acd --- /dev/null +++ b/cursors/src/theme-lilac/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#D9D2E7") +set(mediumColor "#625C6E") +set(darkerColor "#393540") +set(altLighterColor "#D2F4E7") +set(altMediumColor "#4F7464") +set(altDarkerColor "#2B4037") diff --git a/cursors/src/theme-lilac/index.theme b/cursors/src/theme-lilac/index.theme new file mode 100644 index 00000000..1e649672 --- /dev/null +++ b/cursors/src/theme-lilac/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Evening Lilac +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-midnight_meadow/CMakeLists.txt b/cursors/src/theme-midnight_meadow/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-midnight_meadow/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-midnight_meadow/colors.in b/cursors/src/theme-midnight_meadow/colors.in new file mode 100644 index 00000000..f5c19a64 --- /dev/null +++ b/cursors/src/theme-midnight_meadow/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#108010") +set(mediumColor "#001C00") +set(darkerColor "#80F080") diff --git a/cursors/src/theme-midnight_meadow/index.theme b/cursors/src/theme-midnight_meadow/index.theme new file mode 100644 index 00000000..9f682973 --- /dev/null +++ b/cursors/src/theme-midnight_meadow/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Midnight Meadow +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-navy/CMakeLists.txt b/cursors/src/theme-navy/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-navy/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-navy/colors.in b/cursors/src/theme-navy/colors.in new file mode 100644 index 00000000..61c8e3d9 --- /dev/null +++ b/cursors/src/theme-navy/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#c3b4da") +set(mediumColor "#34176e") +set(darkerColor "#1d0a55") diff --git a/cursors/src/theme-navy/index.theme b/cursors/src/theme-navy/index.theme new file mode 100644 index 00000000..811868da --- /dev/null +++ b/cursors/src/theme-navy/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Navy +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-norway/CMakeLists.txt b/cursors/src/theme-norway/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-norway/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-norway/colors.in b/cursors/src/theme-norway/colors.in new file mode 100644 index 00000000..571eb1e9 --- /dev/null +++ b/cursors/src/theme-norway/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#F7F3E9") +set(mediumColor "#C5B399") +set(darkerColor "#807060") +set(altLighterColor "#90C1E8") +set(altMediumColor "#176CA5") +set(altDarkerColor "#0F4B70") diff --git a/cursors/src/theme-norway/index.theme b/cursors/src/theme-norway/index.theme new file mode 100644 index 00000000..a676e056 --- /dev/null +++ b/cursors/src/theme-norway/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Norway +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-obsidian-hc/CMakeLists.txt b/cursors/src/theme-obsidian-hc/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-obsidian-hc/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-obsidian-hc/colors.in b/cursors/src/theme-obsidian-hc/colors.in new file mode 100644 index 00000000..4839dd13 --- /dev/null +++ b/cursors/src/theme-obsidian-hc/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#787775") +set(mediumColor "#201F1F") +set(darkerColor "#E8E7E4") +set(altLighterColor "#184880") +set(altMediumColor "#122F50") +set(altDarkerColor "#5177A6") diff --git a/cursors/src/theme-obsidian-hc/index.theme b/cursors/src/theme-obsidian-hc/index.theme new file mode 100644 index 00000000..6ea3c87a --- /dev/null +++ b/cursors/src/theme-obsidian-hc/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Obsidian High Contrast +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-obsidian/CMakeLists.txt b/cursors/src/theme-obsidian/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-obsidian/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-obsidian/colors.in b/cursors/src/theme-obsidian/colors.in new file mode 100644 index 00000000..23688fe1 --- /dev/null +++ b/cursors/src/theme-obsidian/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#787775") +set(mediumColor "#201F1F") +set(darkerColor "#0F0E0E") +set(altLighterColor "#5177A6") +set(altMediumColor "#184880") +set(altDarkerColor "#122F50") diff --git a/cursors/src/theme-obsidian/index.theme b/cursors/src/theme-obsidian/index.theme new file mode 100644 index 00000000..c4808d4d --- /dev/null +++ b/cursors/src/theme-obsidian/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Obsidian +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-olympus-inv/CMakeLists.txt b/cursors/src/theme-olympus-inv/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-olympus-inv/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-olympus-inv/colors.in b/cursors/src/theme-olympus-inv/colors.in new file mode 100644 index 00000000..4ae74b23 --- /dev/null +++ b/cursors/src/theme-olympus-inv/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#0000B0") +set(mediumColor "#000060") +set(darkerColor "#FFEE80") diff --git a/cursors/src/theme-olympus-inv/index.theme b/cursors/src/theme-olympus-inv/index.theme new file mode 100644 index 00000000..50488e88 --- /dev/null +++ b/cursors/src/theme-olympus-inv/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Olympus (Reversed) +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-olympus/CMakeLists.txt b/cursors/src/theme-olympus/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-olympus/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-olympus/colors.in b/cursors/src/theme-olympus/colors.in new file mode 100644 index 00000000..9b67e02c --- /dev/null +++ b/cursors/src/theme-olympus/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#FFEE80") +set(mediumColor "#E0C000") +set(darkerColor "#0000B0") diff --git a/cursors/src/theme-olympus/index.theme b/cursors/src/theme-olympus/index.theme new file mode 100644 index 00000000..e4f25f5c --- /dev/null +++ b/cursors/src/theme-olympus/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Olympus +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-orchid/CMakeLists.txt b/cursors/src/theme-orchid/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-orchid/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-orchid/colors.in b/cursors/src/theme-orchid/colors.in new file mode 100644 index 00000000..b25192ec --- /dev/null +++ b/cursors/src/theme-orchid/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#CACEE2") +set(mediumColor "#A9ADBE") +set(darkerColor "#33166E") +set(altLighterColor "#D2E1F0") +set(altMediumColor "#718BA5") +set(altDarkerColor "#33166E") diff --git a/cursors/src/theme-orchid/index.theme b/cursors/src/theme-orchid/index.theme new file mode 100644 index 00000000..542512e9 --- /dev/null +++ b/cursors/src/theme-orchid/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Stone Orchid +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-oxygen/CMakeLists.txt b/cursors/src/theme-oxygen/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-oxygen/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-oxygen/colors.in b/cursors/src/theme-oxygen/colors.in new file mode 100644 index 00000000..6b53161d --- /dev/null +++ b/cursors/src/theme-oxygen/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#FFFFFF") +set(mediumColor "#B5B4B3") +set(darkerColor "#403F3F") +set(altLighterColor "#7FB9FF") +set(altMediumColor "#2B74C7") +set(altDarkerColor "#132A40") diff --git a/cursors/src/theme-oxygen/index.theme b/cursors/src/theme-oxygen/index.theme new file mode 100644 index 00000000..7ba8379d --- /dev/null +++ b/cursors/src/theme-oxygen/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Default +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-peach/CMakeLists.txt b/cursors/src/theme-peach/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-peach/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-peach/colors.in b/cursors/src/theme-peach/colors.in new file mode 100644 index 00000000..163253eb --- /dev/null +++ b/cursors/src/theme-peach/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#F4E6CF") +set(mediumColor "#EACDA0") +set(darkerColor "#E1646D") +set(altLighterColor "#DAE8C4") +set(altMediumColor "#75B150") +set(altDarkerColor "#5D6E4B") diff --git a/cursors/src/theme-peach/index.theme b/cursors/src/theme-peach/index.theme new file mode 100644 index 00000000..b9715ee7 --- /dev/null +++ b/cursors/src/theme-peach/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen White Peach +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-purple/CMakeLists.txt b/cursors/src/theme-purple/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-purple/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-purple/colors.in b/cursors/src/theme-purple/colors.in new file mode 100644 index 00000000..1fb0b41c --- /dev/null +++ b/cursors/src/theme-purple/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#f9cade") +set(mediumColor "#bf0361") +set(darkerColor "#9c0f56") diff --git a/cursors/src/theme-purple/index.theme b/cursors/src/theme-purple/index.theme new file mode 100644 index 00000000..19bf2d7d --- /dev/null +++ b/cursors/src/theme-purple/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Purple +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-red-argentina/CMakeLists.txt b/cursors/src/theme-red-argentina/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-red-argentina/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-red-argentina/colors.in b/cursors/src/theme-red-argentina/colors.in new file mode 100644 index 00000000..63593b9b --- /dev/null +++ b/cursors/src/theme-red-argentina/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#ff2929") +set(mediumColor "#cc0000") +set(darkerColor "#930000") diff --git a/cursors/src/theme-red-argentina/index.theme b/cursors/src/theme-red-argentina/index.theme new file mode 100644 index 00000000..01fabdde --- /dev/null +++ b/cursors/src/theme-red-argentina/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Red Argentina (Tango) +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-red/CMakeLists.txt b/cursors/src/theme-red/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-red/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-red/colors.in b/cursors/src/theme-red/colors.in new file mode 100644 index 00000000..a875cd87 --- /dev/null +++ b/cursors/src/theme-red/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#f9ccca") +set(mediumColor "#bf0303") +set(darkerColor "#9c0f0f") diff --git a/cursors/src/theme-red/index.theme b/cursors/src/theme-red/index.theme new file mode 100644 index 00000000..c4229357 --- /dev/null +++ b/cursors/src/theme-red/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Red +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-sea_blue/CMakeLists.txt b/cursors/src/theme-sea_blue/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-sea_blue/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-sea_blue/colors.in b/cursors/src/theme-sea_blue/colors.in new file mode 100644 index 00000000..c21456ba --- /dev/null +++ b/cursors/src/theme-sea_blue/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#a8dde0") +set(mediumColor "#006066") +set(darkerColor "#00484d") diff --git a/cursors/src/theme-sea_blue/index.theme b/cursors/src/theme-sea_blue/index.theme new file mode 100644 index 00000000..75ba3cd8 --- /dev/null +++ b/cursors/src/theme-sea_blue/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Sea Blue +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-steel/CMakeLists.txt b/cursors/src/theme-steel/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-steel/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-steel/colors.in b/cursors/src/theme-steel/colors.in new file mode 100644 index 00000000..dfc42eec --- /dev/null +++ b/cursors/src/theme-steel/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#FAF9F2") +set(mediumColor "#AFAEA9") +set(darkerColor "#393837") +set(altLighterColor "#89B2C0") +set(altMediumColor "#597E90") +set(altDarkerColor "#273840") diff --git a/cursors/src/theme-steel/index.theme b/cursors/src/theme-steel/index.theme new file mode 100644 index 00000000..b78f4f3d --- /dev/null +++ b/cursors/src/theme-steel/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Steel +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-terra/CMakeLists.txt b/cursors/src/theme-terra/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-terra/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-terra/colors.in b/cursors/src/theme-terra/colors.in new file mode 100644 index 00000000..5b8dc14d --- /dev/null +++ b/cursors/src/theme-terra/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#CBC2BF") +set(mediumColor "#9A987F") +set(darkerColor "#404642") +set(altLighterColor "#FFFFFF") +set(altMediumColor "#6A8FD2") +set(altDarkerColor "#3E538E") diff --git a/cursors/src/theme-terra/index.theme b/cursors/src/theme-terra/index.theme new file mode 100644 index 00000000..4b3ce6a5 --- /dev/null +++ b/cursors/src/theme-terra/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Terra Sky +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-terra_green/CMakeLists.txt b/cursors/src/theme-terra_green/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-terra_green/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-terra_green/colors.in b/cursors/src/theme-terra_green/colors.in new file mode 100644 index 00000000..aa6721a7 --- /dev/null +++ b/cursors/src/theme-terra_green/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#CBC2BF") +set(mediumColor "#9A987F") +set(darkerColor "#404642") +set(altLighterColor "#008929") +set(altMediumColor "#004D00") +set(altDarkerColor "#0C2607") diff --git a/cursors/src/theme-terra_green/index.theme b/cursors/src/theme-terra_green/index.theme new file mode 100644 index 00000000..9854e38a --- /dev/null +++ b/cursors/src/theme-terra_green/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Terra Earth +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-violet/CMakeLists.txt b/cursors/src/theme-violet/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-violet/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-violet/colors.in b/cursors/src/theme-violet/colors.in new file mode 100644 index 00000000..e37a7937 --- /dev/null +++ b/cursors/src/theme-violet/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#e8b7d7") +set(mediumColor "#85026c") +set(darkerColor "#6a0056") diff --git a/cursors/src/theme-violet/index.theme b/cursors/src/theme-violet/index.theme new file mode 100644 index 00000000..e2a2efa7 --- /dev/null +++ b/cursors/src/theme-violet/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Violet +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-viorange/CMakeLists.txt b/cursors/src/theme-viorange/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-viorange/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-viorange/colors.in b/cursors/src/theme-viorange/colors.in new file mode 100644 index 00000000..032f2ecd --- /dev/null +++ b/cursors/src/theme-viorange/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#fcaf3e") +set(mediumColor "#f57900") +set(darkerColor "#ce5c00") diff --git a/cursors/src/theme-viorange/index.theme b/cursors/src/theme-viorange/index.theme new file mode 100644 index 00000000..87a5d20f --- /dev/null +++ b/cursors/src/theme-viorange/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Vibrant Orange (Tango) +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-white/CMakeLists.txt b/cursors/src/theme-white/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-white/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-white/colors.in b/cursors/src/theme-white/colors.in new file mode 100644 index 00000000..f263f583 --- /dev/null +++ b/cursors/src/theme-white/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#ffffff") +set(mediumColor "#d0d0d0") +set(darkerColor "#000000") diff --git a/cursors/src/theme-white/index.theme b/cursors/src/theme-white/index.theme new file mode 100644 index 00000000..6e4470ac --- /dev/null +++ b/cursors/src/theme-white/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen White +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-whitewater/CMakeLists.txt b/cursors/src/theme-whitewater/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-whitewater/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-whitewater/colors.in b/cursors/src/theme-whitewater/colors.in new file mode 100644 index 00000000..feaab867 --- /dev/null +++ b/cursors/src/theme-whitewater/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#E0DFDC") +set(mediumColor "#787775") +set(darkerColor "#302F2E") +set(altLighterColor "#2966A4") +set(altMediumColor "#153E6D") +set(altDarkerColor "#102C50") diff --git a/cursors/src/theme-whitewater/index.theme b/cursors/src/theme-whitewater/index.theme new file mode 100644 index 00000000..225cab4f --- /dev/null +++ b/cursors/src/theme-whitewater/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Whitewater +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-wonton/CMakeLists.txt b/cursors/src/theme-wonton/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-wonton/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-wonton/colors.in b/cursors/src/theme-wonton/colors.in new file mode 100644 index 00000000..f5bd7341 --- /dev/null +++ b/cursors/src/theme-wonton/colors.in @@ -0,0 +1,6 @@ +set(lighterColor "#494E58") +set(mediumColor "#282C30") +set(darkerColor "#D2DEF0") +set(altLighterColor "#78889C") +set(altMediumColor "#3D4650") +set(altDarkerColor "#D2E2F4") diff --git a/cursors/src/theme-wonton/index.theme b/cursors/src/theme-wonton/index.theme new file mode 100644 index 00000000..da6bd6a5 --- /dev/null +++ b/cursors/src/theme-wonton/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Wonton Soup +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-yellow/CMakeLists.txt b/cursors/src/theme-yellow/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-yellow/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-yellow/colors.in b/cursors/src/theme-yellow/colors.in new file mode 100644 index 00000000..2c3843fc --- /dev/null +++ b/cursors/src/theme-yellow/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#fff6c8") +set(mediumColor "#f3c300") +set(darkerColor "#e3ad00") diff --git a/cursors/src/theme-yellow/index.theme b/cursors/src/theme-yellow/index.theme new file mode 100644 index 00000000..c0a16cd6 --- /dev/null +++ b/cursors/src/theme-yellow/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Yellow +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme-zion/CMakeLists.txt b/cursors/src/theme-zion/CMakeLists.txt new file mode 100644 index 00000000..5e1a072e --- /dev/null +++ b/cursors/src/theme-zion/CMakeLists.txt @@ -0,0 +1 @@ +add_theme(${color} ${color} 90 180 270) diff --git a/cursors/src/theme-zion/colors.in b/cursors/src/theme-zion/colors.in new file mode 100644 index 00000000..32dc4a61 --- /dev/null +++ b/cursors/src/theme-zion/colors.in @@ -0,0 +1,3 @@ +set(lighterColor "#606060") +set(mediumColor "#000000") +set(darkerColor "#ffffff") diff --git a/cursors/src/theme-zion/index.theme b/cursors/src/theme-zion/index.theme new file mode 100644 index 00000000..241e15b1 --- /dev/null +++ b/cursors/src/theme-zion/index.theme @@ -0,0 +1,3 @@ +[Icon Theme] +Name = Oxygen Zion +Comment = Oxygen mouse theme. Oxygenize your desktop! diff --git a/cursors/src/theme.cmake b/cursors/src/theme.cmake new file mode 100644 index 00000000..b79259ab --- /dev/null +++ b/cursors/src/theme.cmake @@ -0,0 +1,2 @@ +add_theme(${color} ${color} 90) +add_theme(${color} ${color}-big 180) diff --git a/cursors/src/wincursor.py b/cursors/src/wincursor.py new file mode 100644 index 00000000..ddb5e528 --- /dev/null +++ b/cursors/src/wincursor.py @@ -0,0 +1,50 @@ +import sys +import os + +configs = ["left_ptr.in", "help.in", "progress.in", "wait.in", "cross.in", "text.in", "pencil.in", "circle.in", "size_ver.in", "size_hor.in", "size_fdiag.in", "size_bdiag.in", "fleur.in", "up_arrow.in", "pointer.in"] + +if len(sys.argv) < 4: + print "too few arguments for wincursor" + sys.exit(1) + +pngdir = sys.argv[1] +conf = sys.argv[2] +outdir = sys.argv[3] +dummy = sys.argv[4] + +f = open(dummy, "w") +f.close() + +if not configs.count(conf[conf.rfind("/")+1:]): + sys.exit(0) +else: + conffile = conf[conf.rfind("/")+1:] + +f = open(conf) +r = f.read() +f.close() + +ls = r.split("\n") +imglist = [] + +for l in ls: + if l and not l.startswith("#"): + v = l.split(" ") + if len(v) == 4: + imglist += [(v[3], v[1], v[2])] + elif len(v) == 5: + imglist += [(v[3], v[1], v[2], v[4])] + +if len(imglist) > 1: + pngls = [os.path.join(pngdir, i[0]) for i in imglist] + pngstr = "" + for p in pngls: + pngstr += " %s" % p + + img = imglist[0] + jiffie = int((float(img[3]) / 1000) * 60) + + print os.popen4("png2ico %s --hotspotx %s --hotspoty %s --framerate %s %s" % (os.path.join(outdir, conffile.replace(".in", ".ani")), img[1], img[2], jiffie, pngstr))[1].read() +elif len(imglist) == 1: + img = imglist[0] + print os.popen4("png2ico %s --hotspotx %s --hotspoty %s %s" % (os.path.join(outdir, conffile.replace(".in", ".cur")), img[1], img[2], os.path.join(pngdir, img[0])))[1].read() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 00000000..af00f4cd --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,12 @@ +add_subdirectory(kdm) +add_subdirectory(klipper) +add_subdirectory(kfontview) +add_subdirectory(kmenuedit) +add_subdirectory(ksysguard) +add_subdirectory(plasma-desktop) +add_subdirectory(kcontrol) +add_subdirectory(systemsettings) +add_subdirectory(kinfocenter) +if(POLKITQT_FOUND) + add_subdirectory(PolicyKit-kde) +endif(POLKITQT_FOUND) diff --git a/doc/PolicyKit-kde/CMakeLists.txt b/doc/PolicyKit-kde/CMakeLists.txt new file mode 100644 index 00000000..dd75aec8 --- /dev/null +++ b/doc/PolicyKit-kde/CMakeLists.txt @@ -0,0 +1 @@ +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) diff --git a/doc/PolicyKit-kde/authdialog_1.png b/doc/PolicyKit-kde/authdialog_1.png new file mode 100644 index 0000000000000000000000000000000000000000..55e4d5288b5597ab22efbba5ff4b768bff34849a GIT binary patch literal 35345 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 z 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ðJ)5Y)M`oz@wgHa5@NS*H4rpn#E71Q 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 X1HEx%JN?k_6v9Y~$%>W>>-qj4`9bX8 literal 0 HcmV?d00001 diff --git a/doc/PolicyKit-kde/authorization.docbook b/doc/PolicyKit-kde/authorization.docbook new file mode 100644 index 00000000..5405926e --- /dev/null +++ b/doc/PolicyKit-kde/authorization.docbook @@ -0,0 +1,112 @@ + +Authorization manager + + +Manual + + +The Authorization manager is the application that system administrators can +use to easily change the default behavior of any actions. This page does not +aim to explain how to create new actions or define new .policy +files. + + +The Authorization screen is divided in two parts, at the left we have all the +actions that PolicyKit knows, you are able to search the actions using the search +bar at the top, and at the right we have the selected action. +This screenshot shows the main Authorization screen: + + + + + + +Main window with source device + + + + + +When you select an action it's details will be shown at the right side, +the action might have an icon, a description and the vendor name. Next +in the view we have the Implicit Authorizations and +Explicit Authorizations. + + + +The Implicit Authorizations are authorizations automatically +given to users based on certain criteria such as if they are on the local +console. These authorizations are read from the .policy files +that the given application defined, they are the defaults settings of the action. +These are the valid values + + + +no +auth_self_one_shot +auth_self +auth_self_keep_session +auth_self_keep_always +auth_admin_one_shot +auth_admin +auth_admin_keep_session +auth_admin_keep_always +yes + + + +You can change these defaults values simply by changing it on the combo box, +the not bold value is the default one so if you want to change one value back +you can select it, to make you selection take effect you have to click on the +Modify button. The Revert to defaults can be used +to change all Implicit Authorizations to it's defaults values. +Note that both Modify and Revert to defaults +requires you to issue the PolicyKit org.freedesktop.policykit.modify-defaults +action which might ask a password. + + + +The Explicit Authorizations are authorizations that are either +obtained through authentication process or specifically given to the action +in question. The default behavior is to only show the current user explicit +authorizations; if you want to see others users explicit authorizations +click on the Show authorizations from all users, note that this +requires you to issue the PolicyKit org.freedesktop.policykit.read +action which might ask a password. +Blocked authorizations are marked with a STOP sign. + + + +The Revoke button is used to revoke an explicit authorization. +Note that this requires you to issue the PolicyKit +org.freedesktop.policykit.revoke action which might ask a password. + + + +If you want to specifically grant or block a given user of performing a given action +you can click on the Grant or Block. +The following screenshot you see the Grant/Block dialog: + + + + + + +Grant/Block explicit authorizations dialog + + + + + +To grant/block explicit authorizations you have to select the user that will +receive the authorization. You can also select the Constraints +to limit the authorization such that it only applies under certain circumstances. +Be aware that explicit blocking and authorization might self lock you +of performing the given action so be sure of what you are doing +Note that this requires you to issue the PolicyKit +org.freedesktop.policykit.grant action which might ask a password. + + + + + diff --git a/doc/PolicyKit-kde/authorization_1.png b/doc/PolicyKit-kde/authorization_1.png new file mode 100644 index 0000000000000000000000000000000000000000..dbd9a864142379b7a92fda47de4d26756f4f7469 GIT binary patch literal 101385 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 +Authorization Agent + + +Manual + + +The Authorization Agent is the application that is called whenever an user +wants to obtain a given authorization. It's a &DBus; activated daemon which +uses libpolkit-grant that in turn uses PAM for authentication +services (however, other authentication back-ends can be plugged in as required). + + + + +Authorization Agent dialog + + +The appearance of the authentication dialog depends on the result from PolicyKit +and also whether administrator authentication is defined as authenticate as +the root user or authenticate as one of the users from UNIX group +wheel or however the PolicyKit library is configured (see the +PolicyKit.conf(5) manual page for details). Note that some of the screenshots below +were made on a system set up to use the +ThinkFinger +PAM module. The text shown in the authentication dialogs stems from the PolicyKit +.policy XML files residing in /usr/share/PolicyKit/policy and is read by the +authentication daemon when an applications asks to obtain an authorization. +Thus, what the user sees is not under application control +(e.g. it's not passed from the application) which rules out a class of attacks +where applications are trying to fool the user into gaining a privilege. + + +The authentication dialog where the user is asked to authenticate as root +using the password or swiping the finger. +The details shows the application that's requesting the action, the action +itself and the action vendor. If clicking in the action link it will open the +authorization manager pointing to the given action, and the vendor might also +provide a link for the given action that will be fired when clicking on the +Vendor link: + + + + + +The authentication dialog asking for root, swipe finger and showing descriptions + + + + + +Authentication dialog where the user is asked to authenticate as an administrative +user and PolicyKit is configured to use the root password for this: + + + + + +The authentication dialog asking for root + + + + + +Authentication dialog where the user is asked to authenticate as an administrative +user and PolicyKit is configured to use a group for this: + + + + + +The authentication dialog asking for a user of the administrative group + + + + + +Same authentication dialog, showing drop down box where the user can be selected: + + + + + +Same authentication dialog, showing drop down box where the user can be selected + + + + + + +Authentication dialog showing an Action where the privilege can be retained indefinitely: + + + + + +Authentication dialog showing an Action where the privilege can be retained indefinitely + + + + + + +Authentication dialog showing an Action where the privilege can be retained only +for the remainder of the desktop session: + + + + + +Authentication dialog showing an Action where the privilege can be retained only +for the remainder of the desktop session + + + + + + + + diff --git a/doc/PolicyKit-kde/howitworks.docbook b/doc/PolicyKit-kde/howitworks.docbook new file mode 100644 index 00000000..90e4d331 --- /dev/null +++ b/doc/PolicyKit-kde/howitworks.docbook @@ -0,0 +1,53 @@ + +How it works + + +Overview + +PolicyKit has a simple way of working, but it requires some +design changes from the applications that want to use it to request +passwords. + + + +The problem + +In GUI applications the common way to gain root privileges is to start +it as root, but there are several security risks in doing this method and +it does not allow a good actions mapping. There is no way to separate actions +like package-install of system-upgrading. +All the users who want to use it must have the root password. Another common +approach is using sudo but once you start an application with sudo you will +have all the rights the root user will have. +If for example the GUI application has a dialog to select files that dialog +is running as root which means that the user might be able to delete any file +on his machine or even coping others user files. + + + + +The solution + +With PolicyKit this problem is solved. The application in question +just need to separate the privileged code into another application, +often called helper (which will not have a GUI), then maps the desired +actions into a .policy file. PolicyKit then loads this file +and it can now authenticate applications to use those actions. +The use of &DBus; activated applications is the best if not the only, +way of putting an helper application to run with root privileges. + +With this design the GUI application calls an action of the helper +application through &DBus;, which will start the helper with root privileges, +and informing it which action was requested and which application has requested +it. The helper application now calls the PolicyKit agent to see if that application +can do the given task, the helper should report if it could do the requested action. +In case the helper saw that the application didn't have enough rights the GUI +will then need to ask PolicyKit to obtain an authorization. + +When PolicyKit receives the request to obtain an authorization it issues an +available Agent, which might happen to be &policykit-kde; if available. After a successful +authentication the GUI application needs to call the helper repeating the +same operation again. + + + diff --git a/doc/PolicyKit-kde/index.docbook b/doc/PolicyKit-kde/index.docbook new file mode 100644 index 00000000..a1173d32 --- /dev/null +++ b/doc/PolicyKit-kde/index.docbook @@ -0,0 +1,88 @@ + +PolicyKit-kde"> + PolicyKit"> + + + + + + + +]> + + + + +The &policykit-kde; manual + + + +Daniel +Nicoletti + + + + + +2008-2009 +Daniel Nicoletti + + +&FDLNotice; + +2009-01-25 +0.9.0 + + +&policykit-kde; is a &kde; front end to the PolicyKit +system that is used to manages authentication. +&policykit; is a toolkit designed to allow unprivileged processes +to speak to privileged processes. It does that by centralizing information of +actions and authorized applications. + + + +KDE +System +Password +Admin +Authentication +polkit +policykit +policy +policies + + + + +&policykit-kde-introduction; +&policykit-kde-howitworks; +&policykit-kde-authorization; +&policykit-kde-authorizationagent; + + +Credits and License + + +&policykit-kde; + + +Program copyright 2008-2009 Daniel Nicoletti + + +Documentation copyright 2008-2009 Daniel Nicoletti + + + +&underFDL; + + + +&documentation.index; + + + + diff --git a/doc/PolicyKit-kde/introduction.docbook b/doc/PolicyKit-kde/introduction.docbook new file mode 100644 index 00000000..ea94ac13 --- /dev/null +++ b/doc/PolicyKit-kde/introduction.docbook @@ -0,0 +1,28 @@ + +Overview + +&policykit-kde; is a implementation of PolicyKit tool to the look and feel +of KDE. + +PolicyKit allows easy and secure password management, it can be used by +applications to ask their users for a password. Each application defines a set +of actions that can be executed by their program. +The application will call PolicyKit to see if the user can perform a given +action, if not, the application can issue the auth dialog where the user +can enter his/her password, root password, the password of a given group +of users or even swipe the finger. + +&policykit-kde; consists of two applications: +The Authorization agent that receives requests for authentication, and shows +a dialog asking for a password. +The Authorization manager that is used to manage the authorizations, it is +mainly used by system administrators that may want to change the default behavior +of a program policies. + +For Qt/KDE developers there is Qt library to allow easy integration with +you application and PolicyKit. + +For more information of how PolicyKit works, it's design and API visit +PolicyKit Library Reference Manual + + diff --git a/doc/kcontrol/CMakeLists.txt b/doc/kcontrol/CMakeLists.txt new file mode 100644 index 00000000..87f836a3 --- /dev/null +++ b/doc/kcontrol/CMakeLists.txt @@ -0,0 +1,32 @@ +add_subdirectory(clock) +add_subdirectory(colors) +add_subdirectory(desktopthemedetails) +add_subdirectory(joystick) +add_subdirectory(kcmaccess) +add_subdirectory(kcmstyle) +add_subdirectory(solid-actions) +add_subdirectory(splashscreen) +add_subdirectory(powerdevil) +add_subdirectory(kwincompositing) +add_subdirectory(kwinscreenedges) + +if ( Q_WS_X11 ) +add_subdirectory(autostart) +add_subdirectory(bell) +add_subdirectory(cursortheme) +add_subdirectory(fonts) +add_subdirectory(fontinst) +add_subdirectory(keys) +add_subdirectory(keyboard) +add_subdirectory(kwindecoration) +add_subdirectory(desktop) +add_subdirectory(mouse) +add_subdirectory(paths) +add_subdirectory(screensaver) +add_subdirectory(windowspecific) +add_subdirectory(windowbehaviour) +add_subdirectory(kwintabbox) +add_subdirectory(kcmsmserver) +add_subdirectory(workspaceoptions) +add_subdirectory(khotkeys) +endif ( Q_WS_X11 ) diff --git a/doc/kcontrol/autostart/CMakeLists.txt b/doc/kcontrol/autostart/CMakeLists.txt new file mode 100644 index 00000000..635f1ebf --- /dev/null +++ b/doc/kcontrol/autostart/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/autostart) diff --git a/doc/kcontrol/autostart/index.docbook b/doc/kcontrol/autostart/index.docbook new file mode 100644 index 00000000..0f715c25 --- /dev/null +++ b/doc/kcontrol/autostart/index.docbook @@ -0,0 +1,183 @@ + + + +]> +

+ +Autostart + +&Anne-Marie.Mahfouf; + + + +2013-12-05 +&kde; 4.12 + + +KDE +System Settings +autostart +desktop file +script file + + + + +Autostart Manager + +This module is a configuration tool for managing what programs start up with your personal &kde;. It allows you to add programs or scripts so they automatically start during the startup of your &kde; session and to manage them. + +Please note that in this module all changes are immediately applied. + +The program scans ~/.config/autostart/, your KDE Autostart folder ($KDEHOME/Autostart as default), $KDEHOME/env and $KDEHOME/shutdown folders to check what programs and scripts are already there and displays them. It allows you to manage them easily. + + +Note that you can change the location of your Autostart +folder in Account Details Paths +in the Common Appearance and Behaviour category of the &systemsettings; and set a different folder +than $KDEHOME/Autostart. + + +Files display +The main part of the module displays the programs that are loaded when &kde; starts and scripts that are run when &kde; starts, shutdowns or before &kde; starts. + + +Name + + +You cannot amend this column. It states the name of the program or script you want to start with &kde;. The name is extracted from the Desktop file from the Name key for a program and is the filename for a script. + + + + +Command + + +This column lists the commands that are run to start the program. Commands can be modified through the Properties button or by double clicking the program/script row. The command is extracted from the Desktop file from the Exec key. + + +For a script the command is the path to the script. + + + + +Status + + +This setting is only available for programs through Desktop files. You can keep a program in the Autostart folder but disable it from being run at &kde; start. Setting the program to Disabled will not run it on start. + + +Setting a program to Disabled sets the Desktop file Hidden property to true in the Autostart folder. + + + + +Run On + + +Programs (Desktop files) can only be run on startup. Scripts can be run on Startup, Shutdown or Pre-KDE Startup. This column allows you to change when your script is run. Startup is when &kde; starts, shutdown is when you log out of &kde; and pre-KDE startup is before &kde; starts. + + +Scripts and desktop files set to run on Startup are copied or symlinked in $KDEHOME/Autostart and will be run during &kde; startup. + + +Scripts set on to be ran on Shutdown are copied or symlinked in the $KDEHOME/shutdown directory and will be automatically run during &kde; shutdown after the user has logged out. + + +Scripts set to run at Pre-&kde; Startup are copied or symlinked in $KDEHOME/env and are sourced during &kde; startup (the startkde script will look for scripts here). + + +Only scripts with the sh extension can be read by &kde; for Pre-&kde; startup and Shutdown modes. + + + + + + + +Actions + +On the right you have some buttons to change the way Autostart is configure. You can add programs or scripts, remove them or change their properties. + + + +Add Program + + +Clicking this button displays the standard &kde; Choose Application dialog and allows you to choose which program you want to start. After choosing the program, clicking OK brings you the properties for this program. + + +This will copy the program Desktop file in your Autostart folder. + + + + +Add Script + + +This button opens a dialog which asks you for the location of the script you want to add. If you keep Create as symlink checked (default) then the script will be added as a symlink. If you uncheck this option then the script will be copied in the corresponding local folder. + + + +Remove + + +Remove will immediately remove the Desktop file for the program or the script or symbolic link in the Autostart folder. + + + +Properties + + +This button (only enabled for programs &ie; Desktop files) allows you to change the properties of the program or script. You have general properties, permissions properties, a preview when applicable and properties related to the application for programs. + + + +Advanced + + +This button only applies to programs (&ie; Desktop files). A dialog asks you if you only want the program to autostart only in &kde; (and not in other desktop environments you might run). By default, the program will autostart in all desktop environments you might run. Checking Autostart only in KDE will autostart the program only if you start the &kde; desktop environment. + + +This sets the value KDE to the OnlyShowIn key of the program Desktop file. + + + + + + +
+ + + diff --git a/doc/kcontrol/bell/CMakeLists.txt b/doc/kcontrol/bell/CMakeLists.txt new file mode 100644 index 00000000..bb5c3b37 --- /dev/null +++ b/doc/kcontrol/bell/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/bell) diff --git a/doc/kcontrol/bell/index.docbook b/doc/kcontrol/bell/index.docbook new file mode 100644 index 00000000..f904df75 --- /dev/null +++ b/doc/kcontrol/bell/index.docbook @@ -0,0 +1,64 @@ + + + +]> + +
+System Bell + + +PatDowler +MatthiasHoelzer +MikeMcBride + + + +2011-11-28 +&kde; 4.8 + + +The system bell or beep is a feature of the X server, which +attempts to make good use of the available hardware. + +&kde; normally does not use the system bell; instead using its +own system notifications, which could include log entries, message +popups, or its own beep. You can configure these in the +Manage Notifications &systemsettings; module. + +It is not always possible for the X server to actually make +a beep sound with exactly the parameters selected due to hardware +limitations. For example, on most PCs, volume control is not very good +so the X server seems to fake low volume with a reduced duration of +the sound. Thus, if the settings do not seem to do anything, this is +because the X server and/or the hardware do not support anything +better. + + Select Use system bell instead of system notification +then you are able to set the following parameters for the bell: + + + + +Volume (percentage of maximum volume) +Here you can customize the volume of the system bell. + + + +Pitch (in Hz) +Here you can customize the pitch of the system bell. + + + +Duration (in milliseconds) +Here you can customize the duration of the system bell. + + + + +For further customization of the bell, see the Accessibility &systemsettings; module. + +You can use the Test button to hear how +the current settings will sound. + +
diff --git a/doc/kcontrol/clock/CMakeLists.txt b/doc/kcontrol/clock/CMakeLists.txt new file mode 100644 index 00000000..3cc3bc20 --- /dev/null +++ b/doc/kcontrol/clock/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/clock) diff --git a/doc/kcontrol/clock/index.docbook b/doc/kcontrol/clock/index.docbook new file mode 100644 index 00000000..5779367e --- /dev/null +++ b/doc/kcontrol/clock/index.docbook @@ -0,0 +1,90 @@ + + + +]> + +
+ +Date & Time + +&Mike.McBride; &Mike.McBride.mail; + + + +2013-12-05 +4.12 + + +KDE +Systemsettings +clock +date +time +set +configure + + + + + +Date & Time + +You can use this module to alter the system date and time, using a +convenient graphical interface. + +As these settings do not only affect you as a user, +but rather the whole system, you must have system administrator (root) access to change the system date and +time. If you do not have this access level, this module will only show +you the current settings, but your changes will not be saved. + + +Date and Time + +If you check Set date and time automatically you are able +to select a Time server from the drop down box and all other +settings in this dialog are disabled. + + +The applications rdate or ntpdate are used in +this module to fetch date and time from a time server. This happens when you log in to &kde; +while being online or when you later connect to the Internet and access to time +servers is possible. +Both applications are simple NTP clients that set a system's clock +to match the time obtained by communicating with one or more NTP servers. +This is not sufficient, however, for maintaining an accurate clock in the long run. +This is useful for occasionally setting the time on machines that do not have full-time +network access, such as laptops. + + +If you do not use a time server, you are able to set the date manually +using the lower half of the tab. Simply +choose your month and year using the controls at the top of the calendar +and the day of the month by clicking on the day in the +calendar. +Use the controls at the bottom of the calendar +to select the current date, enter the date in the edit box or select the +week of the year from the drop down box. + +You set the time using the spin boxes at the bottom of the analog clock. +You can also directly enter your value. + + + + +Time Zone +To set a new time zone, simply select your area from the list below. +Use the filter box to find the desired Area or Region. + + + + +
diff --git a/doc/kcontrol/colors/CMakeLists.txt b/doc/kcontrol/colors/CMakeLists.txt new file mode 100644 index 00000000..a8b87056 --- /dev/null +++ b/doc/kcontrol/colors/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/colors) diff --git a/doc/kcontrol/colors/index.docbook b/doc/kcontrol/colors/index.docbook new file mode 100644 index 00000000..6b6def0c --- /dev/null +++ b/doc/kcontrol/colors/index.docbook @@ -0,0 +1,399 @@ + + + + +]> + +
+ +Colors + +&Matthew.Woehlke; &Matthew.Woehlke.mail; + + + +2013-11-05 +4.12 + + +KDE +KControl +color +kcm + + + + +Colors + + + Introduction + + The Color Selection module is comprised of several sections: + + + + The Scheme tab, + used to manage schemes. + + + The Options tab, + used to change the options of the current scheme. + + + The Colors tab, + used to change the colors of the current scheme. + + + The state effects tabs + (Inactive, Disabled), used to + change the state effects of the current scheme. + + + + Note: This documentation will sometimes refer to the + "current" scheme, or the "active" scheme. + The "current" scheme is the set of colors and color scheme options + that was most recently applied, &ie; what you would get if you choose + Cancel. The "active" scheme is the set of + colors as has been most recently edited by you, &ie; what you would get if + you choose Apply. + + + + Scheme Management + + The Scheme tab lets you manage the color schemes + on your machine. Only one scheme is active at once, but you may save schemes, + allowing you to quickly change the scheme later. When you have created a + scheme you like, you can save it with Save Scheme.... + You can remove schemes using Remove Scheme. + Note that system schemes cannot be removed; trying to do so will display an + error. + + &kde; ships with several schemes. If you have an Internet connection, + you can also browse and retrieve user-created schemes using Get + New Schemes.... + + + Importing Schemes + + You can also import schemes that you have downloaded or otherwise + obtained, as well as import &kde; 3 schemes. &kde; 4 color schemes are + named like "*.colors", while &kde; 3 schemes are named like + "*.kcsrc". + + Because &kde; 4 has many more color roles than &kde;, importing a + &kde; 3 scheme is different from importing a &kde; 4 scheme. When a + &kde; 4 scheme is imported, it becomes part of your saved scheme + collection. When a &kde; 3 scheme is imported, the colors that exist in + &kde; 3 are overlaid onto the active scheme, and the result is not + automatically saved into your collection. After importing a &kde; 3 scheme, + you will likely need to adjust the colors that are new in &kde; 4, as well + as the state effects. For best results, before importing a &kde; 3 scheme, + select a similar &kde; 4 scheme (you do not need to apply the scheme before + importing). + + + + + Color Scheme Options + + The Options tab allows you to change some + properties that deal with how the color scheme is used, as well as some + options that change the color scheme that are different from actually + assigning colors. + + + Apply inactive window color effects + — If checked, state effects (see below) will be applied to inactive + windows. This can help visually identify active versus inactive windows, + and may have aesthetic value, depending on your taste. However, some + users feel that it causes distracting "flickering" since + windows must be repainted when they become inactive. Unlike desktop + effects, color state effects do not require compositing support and will + work on all systems, however they will only work on &kde; 4 applications. + + Inactive selection changes color + — If checked, the current selection in elements which do not have + input focus will be drawn using a different color. This can assist visual + identification of the element with input focus in some applications, + especially those which simultaneously display several lists. + + Shade sorted column in lists + — If checked, multi-column lists will use a slightly different + color to paint the column whose information is being used to sort the + items in the list. + + Apply colors to non-KDE4 applications + — If checked, &kde; will attempt to export its color scheme so that + non-&kde; 4 applications will use the same colors. Most applications will + honor the exported scheme to varying degrees, though some may have bugs + or otherwise not honor the exported scheme. + + Contrast + — This slider controls the contrast of shaded elements, such as + frame borders and the "3D" effects used by most styles. A lower + value gives less contrast and therefore softer edges, while a higher + value makes such edges "stand out" more. + + + + + + + Colors + + The Colors tab allows you to change the colors in + the active color scheme. + + Creating or changing a scheme is a simple matter of clicking on the + swatch in the color list and selecting a new color. You can check your + changes at any time by pressing Apply. It is suggested + that you save your scheme (via the Scheme tab) when you + are done. + + The Common Colors set, which is displayed + initially, is not actually a "set" in the sense used by &kde; (see + next section), but presents a number of color roles in a way that makes it + easier to edit the scheme as a whole. When creating a new color scheme, you + will usually change these colors first, and use the other sets to tweak + specific colors if needed. + + Note that Common Colors makes available roles from + all sets. For example, "View Background" here is shorthand for the + Normal Background role from the View set. Also, setting colors that do not + refer to a specific set will change that color in all + sets. (As an exception, "Inactive Text" will change the color for + all sets except for Selection; there is a separate + "Selection Inactive Text" for Inactive Text in the Selection set.) + Some roles may not be visible under Common Colors at + all, and can only be changed (if needed) by selecting the appropriate + set. + + + Color Sets + + &kde; 4 breaks the color scheme into several sets based on the type + of user interface element, as follows: + + View — + information presentation elements, such as lists, trees, text input boxes, etc. + + Window — + window elements that are not buttons or views. + + Button — + buttons and similar elements. + + Selection — + selected text and items. + + Tooltip — + tool tips, "What's This" tips, and similar elements. + + Window Manager — + window title bars and related elements. + + + + Each set contains a number of color roles. Except for the Window + Manager colors, each set has the same roles. All colors are associated with + one of the above sets. + + + + Color Roles + + Each color set is made up of a number of roles which are available in + all other sets. (The Window Manager set is an exception; it has its own + unique roles that do not exist in any other set, and does not use the same + roles as the other sets.) In addition to the obvious Normal Text and Normal + Background, these roles are as follows: + + + Alternate Background — + used when there is a need to subtly change the background to aid in + item association. This might be used ⪚ as the background of a + heading, but is mostly used for alternating rows in lists, especially + multi-column lists, to aid in visually tracking rows. + + Link Text — + used for hyperlinks or to otherwise indicate "something which may + be visited", or to show relationships. + + Visited Text — + used for "something (⪚ a hyperlink) that has been + visited", or to indicate something that is "old". + + Active Text — + used to indicate an active element or attract attention, ⪚ alerts, + notifications; also for hovered hyperlinks. + + Inactive Text — + used for text which should be unobtrusive, ⪚ comments, + "subtitles", unimportant information, etc. + + Negative Text — + used for errors, failure notices, notifications that an action may be + dangerous (⪚ unsafe web page or security context), etc. + + Neutral Text — + used to draw attention when another role is not appropriate; ⪚ + warnings, to indicate secure/encrypted content, etc. + + Positive Text — + used for success notices, to indicate trusted content, etc. + + + + As well as the text roles, there are a few additional + "decoration" roles that are used for drawing lines or shading + UI elements (while the above may, in appropriate circumstances, also be + used for this purpose, the following are specifically + not meant for drawing text). These are: + + + Focus Decoration — + used to indicate the item which has active input focus. + + Hover Decoration — + used for mouse-over effects, ⪚ the "illumination" effects for + buttons. + + + + In addition, except for Inactive Text, there is a corresponding + background role for each of the text roles. Currently (except for Normal + and Alternate Background), these colors are not chosen by the user, but are + automatically determined based on Normal Background and the corresponding + Text color. These colors may be previewed by selecting one of the sets + other than "Common Colors". + + The choice of color role is left to the developer; the above are + guidelines intended to represent typical usage. + + + + Window Manager Colors + + As previously stated, the Window Manager set has its own roles, + independent of those in other sets. These are (currently) only accessible + via Common Colors, and are as follows: + + + Active Titlebar — + used to draw the title bar background, borders, and/or decorations for + the active window (that is, the one with input focus). Not all window + decorations will use this in the same way, and some may even use the + Normal Background from the Window set to draw the title bar. + + Active Titlebar Text — + used to draw the title bar text when Active Titlebar is used to draw + the title bar background. May also be used for other foreground + elements which use Active Titlebar as the background. + + + + The Inactive Titlebar [Text] roles are the same as the above, but for + inactive windows, rather than active windows. + + + + + + Color State Effects + + Color state effects are applied to interface elements in the inactive + (windows that do not have focus; only if Apply inactive window + color effects is enabled) or disabled states. By changing the + effects, the appearance of elements in these states can be changed. Usually, + inactive elements will have reduced contrast (text fades slightly into the + background) and may have slightly reduced intensity, while disabled elements + will have strongly reduced contrast and are often notably darker or lighter. + + + Three types of effect may be applied to each state (with the effects + of the two states being independent). These are Intensity, Color and + Contrast. The first two (Intensity, Color) control the overall color, while + the last (Contrast) deals with the foreground colors relative to the + background. + + + Intensity + + Intensity allows the overall color to be lightened or darkened. + Setting the slider to the middle produces no change. The available effects + are: + + + Shade — + makes everything lighter or darker in a controlled manner. Each + "tick" on the slider increases or decreases the overall + intensity (&ie; perceived brightness) by an absolute amount. + + Darken — + changes the intensity to a percentage of the initial value. A slider + setting halfway between middle and maximum results in a color half as + intense as the original. The minimum gives a color twice as intense as + the original. + + Lighten — + conceptually the opposite of darken; lighten can be thought of as + working with "distance from white", where darken works with + "distance from black". The minimum is a color twice as + "far" from white as the original, while halfway between + middle and maximum gives an intensity halfway between the original + color and white. + + + + + + Color + + Color also changes the overall color, but is not limited to + intensity. The available effects are: + + + Desaturate — + changes the relative chroma. The middle setting produces no change; + maximum gives a gray whose perceptual intensity equals that of the + original color. Lower settings increase the chroma, giving a color that + is less gray / more "vibrant" than the original. + + Fade — + smoothly blends the original color into a reference color. The minimum + setting on the slider produces no change; maximum gives the reference + color. + + Tint — + similar to Fade, except that the color (hue and chroma) changes more + quickly while the intensity changes more slowly as the slider value is + increased. + + + + + + Contrast + + The contrast effects are similar to the color effects, except they + apply to the text, using the background color as the reference color, and + desaturate is not available. Fade produces text that "fades out" + more quickly, but keeps its color longer, while Tint produces text that + changes color to match the background more quickly while keeping a greater + intensity contrast for longer (where "longer" means higher + settings on the slider). For Contrast effects, the minimum setting on the + slider produces no change, while maximum causes the text to completely + disappear into the background. + + + + + + +
+ diff --git a/doc/kcontrol/cursortheme/CMakeLists.txt b/doc/kcontrol/cursortheme/CMakeLists.txt new file mode 100644 index 00000000..ad525ad4 --- /dev/null +++ b/doc/kcontrol/cursortheme/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/cursortheme) diff --git a/doc/kcontrol/cursortheme/index.docbook b/doc/kcontrol/cursortheme/index.docbook new file mode 100644 index 00000000..e316df8c --- /dev/null +++ b/doc/kcontrol/cursortheme/index.docbook @@ -0,0 +1,59 @@ + + + +]> + +
+ +Cursor Theme + +&Mike.McBride; &Mike.McBride.mail; +&Brad.Hards; &Brad.Hards.mail; + + + +2013-06-02 +&kde; 4.11 + + +This is the documentation for the &kde; &systemsettings; module to +customize the mouse cursor appearance. + + + + +KDE +Systemsettings +mouse +cursor + + + + +This module allows you to select from a number of installed cursor themes. +A preview of the cursor display is shown above the list box. + + +The features provided by this module may not be available on some systems. +Your system may need to be updated to support cursor themes. + + + +If you have additional cursor themes available, you can install and remove +them using the buttons right to the list box. Note that you cannot remove the default themes. + + +Use the Get New Themes button to launch the Get Hot New Stuff dialog and +download additional themes from the Internet. + +Some themes allow to +choose the cursor size using the combobox below to the label Size. + + + +The size can be set to the resolution dependent or one of the sizes available for your system. + + +
diff --git a/doc/kcontrol/desktop/CMakeLists.txt b/doc/kcontrol/desktop/CMakeLists.txt new file mode 100644 index 00000000..2728822f --- /dev/null +++ b/doc/kcontrol/desktop/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/desktop) diff --git a/doc/kcontrol/desktop/index.docbook b/doc/kcontrol/desktop/index.docbook new file mode 100644 index 00000000..e4a08926 --- /dev/null +++ b/doc/kcontrol/desktop/index.docbook @@ -0,0 +1,141 @@ + + + +]> + +
+Virtual Desktops + + + +&Mike.McBride; &Mike.McBride.mail; +&Jost.Schenck; &Jost.Schenck.mail; + + + +2013-06-02 +4.11 + + +KDE +Systemsettings +desktop + + + + + + +Virtual Desktops + + +<guilabel>Desktops</guilabel> + +&kde; offers you the possibility to have several virtual +desktops. In this tab you can configure the number of desktops, the number of rows in the Pager icon +as well as their names. Just use the input box to adjust the number of +desktops. You can assign names to the desktops by entering text into the +text fields below. + +Enable Different widgets for each desktop +to use independent widgets and wallpapers on each individual desktop. + + + + + +<guilabel>Switching</guilabel> + + + +Desktop navigation wraps around +Enable this option if you want keyboard or active desktop border navigation +beyond the edge of a desktop to take you to the opposite edge of the new desktop. + + + + +Desktop Effect Animation +Select No Animation, Slide, +Desktop Cube Animation or Fade Desktop +from the drop down box. If the selected animation has settings options, click on the +tools icon on the right of the drop down box to launch a configuration dialog. + + + + +Desktop Switch On-Screen Display +Enable this option if you want to have an on-screen display for desktop switching. + + + + +Show desktop layout indicators +Enabling this option will show a small preview of the desktop layout +indicating the selected desktop. + + + + +Shortcuts +This section displays the configured shortcuts for switching the desktops +and allows you to edit them. + + + + + +Scrolling the mouse wheel over an empty space on the +desktop or on the Pager icon in the panel will change to the next +virtual desktop numerically, in the direction you scrolled (either up or down). + + + + +
diff --git a/doc/kcontrol/desktopthemedetails/CMakeLists.txt b/doc/kcontrol/desktopthemedetails/CMakeLists.txt new file mode 100644 index 00000000..0714fb27 --- /dev/null +++ b/doc/kcontrol/desktopthemedetails/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/desktopthemedetails) diff --git a/doc/kcontrol/desktopthemedetails/clicking-apply.png b/doc/kcontrol/desktopthemedetails/clicking-apply.png new file mode 100644 index 0000000000000000000000000000000000000000..f57723b4db0cfdbb13eef0ab30d0449291f49b7b GIT binary patch literal 124555 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

!OxYq$r%CVom$EKZO5dV7^s>GfRheRLrMyz^ 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/desktopthemedetails/index.docbook b/doc/kcontrol/desktopthemedetails/index.docbook new file mode 100644 index 00000000..adc35ceb --- /dev/null +++ b/doc/kcontrol/desktopthemedetails/index.docbook @@ -0,0 +1,182 @@ + + + +]> +

+ +Desktop Theme + + +Andrew +Lake + + + +2013-06-02 +&kde; 4.11 + + +KDE +System Settings +desktop +theme +plasma + + + + +Theme tab + +A list of available themes is displayed on this tab. Select a theme by clicking on an item in the list. + +Use the Get New Themes button to launch the Get Hot New Stuff dialog and +download additional themes from the Internet. + + + + +Details tab + +A &kde; plasma desktop theme is made up of several components or items, +consisting mostly in svg backgrounds and colors schemes. This module allows you +to customize your desktop Plasma theme and to replace theme items +with items from other themes or from files. + + +Desktop theme items consist in panel theme item, kickoff theme item, +analog clock, ... + + +If you want to change your current theme for a full new theme (for example from +Air to Glassified) then you can do so in the Theme tab. + + + +Quick start +First download one or several themes you want to use to customize your +desktop items by clicking the Get New Themes... +button in the Theme tab. + +All the available themes will be displayed on top, the current one being highlighted. + +In the theme list, select a base theme that will be used for most widgets and start +customizing each item you want to change with a new theme, for example you can +have the panel in Glassified theme, the widget +backgrounds in Air and so on. + +Here Air is the theme for most widgets and we changed the panel background +to Glassified, the Analog clock to Glassified and the Notes to Oxygen. + + + +Customizing your plasma theme + + + + + + Customizing your plasma theme + + + + + + +Clicking the Apply will create a new theme named +(Customized) and will apply it to your desktop. + + + + +Creating a custom theme +When the module is opened, it will show items from the current desktop +theme. If you would like to start customizing with a different theme, select it +from the box above the list of theme items. This theme from the box is the +starting theme, the base for your new customized desktop theme. + + +In the list of items, for each item you would like to replace, select +replacement item from the drop list for that item. You may select the +corresponding item from another theme, or you may select a file. &plasma; +desktop theme items are svg files, except for the color scheme which is a &kde; +color scheme file. + + + +Click Apply when all the changes have been made. This +will create a new theme named (Customized) which you can +select from the Appearance Settings dialog on the desktop. + + + + +Your custom theme + + + + + + Customized + + + + + + +The theme items listed are the most visible components of the plasma +desktop theme. Other theme components are not listed. Your newly created +theme will use these unlisted components from the theme that you selected at +the start of creating the customized theme. + + + + +Naming a custom theme + +To provide a name for your customized theme, click on the +More checkbox and +enter the name of the theme. You may also provide your name (author), a theme +version and a description of your theme. Click Apply +when done. + + + + +Removing a theme + +Select the theme you would like to remove from the box above the list of +theme items. Click on the More check box. Click the +Remove Theme button to +remove the selected theme. + + + + +Exporting a theme to a file + +You can share your newly customized theme with the community by exporting the +theme to a file. Select your customized theme from the box above the list +of theme items. Click on the More check box. Click the +Export Theme to +File.... Enter the name of the zip file to which the theme will be +saved. + + + + +
+ + diff --git a/doc/kcontrol/fontinst/CMakeLists.txt b/doc/kcontrol/fontinst/CMakeLists.txt new file mode 100644 index 00000000..bd208d21 --- /dev/null +++ b/doc/kcontrol/fontinst/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/fontinst) diff --git a/doc/kcontrol/fontinst/index.docbook b/doc/kcontrol/fontinst/index.docbook new file mode 100644 index 00000000..cfeff1c4 --- /dev/null +++ b/doc/kcontrol/fontinst/index.docbook @@ -0,0 +1,109 @@ + + + +]> + +
+Font Management + + +&Craig.Drummond; &Craig.Drummond.Mail; + + + + +2013-06-19 +&kde; 4.11 + + +KDE +Systemsettings +fonts + + + + +Font Management + +This module is responsible for installing, un-installing, previewing and managing your fonts. + + +Font Groups +There are 4 special pre-defined font groups: + + + All Fonts This will display all fonts, both personal and system-wide. + Personal Fonts The fonts shown will be your personal fonts, and will not be available to other users. + System Fonts The fonts shown will be those available to all users. Installing a font system-wide, or removing a system-wide font, will require administrator privileges. + Unclassified This will list all fonts that have not been placed into any user-defined groups. This group will only appear if you have some user-defined groups. + +To add a font to a group, drag it from the list of fonts onto a group. To remove a font from a group, drag the font onto the All Fonts group. +Below this list you find buttons to create a new group, remove a group and enable or disable the fonts in the current group. +In the context menu of this list you have additional menuitems to print font samples and export a font to a zip archive. + + +Enabling and Disabling +Users with many fonts may find it useful to only have certain fonts enabled (or active) at certain times. To facilitate this, this module will allow you to disable individual fonts, or whole groups of fonts. Disabling a font does not remove the font from the system, it simply hides it so that it no longer appears within applications. Re-enabling a font will then allow it to be used. + + + + + +Font List + +The main display is a list of the installed fonts, grouped via the fonts' family name - the number in square brackets represents the number of installed styles for that family. e.g. The Times font may be listed as: + + + Times [4] + + Regular + Italic + Bold + Bold Italic + + + + + +To install a font, press the Add... button, and select the desired fonts from within the file dialog. The selected font group will control where the fonts will be installed. +To un-install fonts, select the appropriate fonts from the list, and press the Delete... button. + +Click with the &RMB; to open a context menu with some additional actions like Enable, Disable, Print, Open in Font Viewer and Reload. + + +Font Filtering +A text field on top of the font preview allows you to filter the list of fonts. You can filter fonts based upon different categories: + + Family. + Style. + Foundry. + FontConfig match. This allows you to enter a family name, and see the family that fontconfig would actually use. + Font file type. + Font file name. + Font file location. + Writing system. + + + + +Get New Fonts +New fonts may be installed from local files, or downloaded from kde-look.org. The Get New Fonts entry in the tool button (located above the group list), allows you to install fonts from kde-look.org. The fonts downloaded in this manner will be installed into your Personal Fonts group. To install system-wide, you will need to move them to the System Fonts group - this may be achieved by dragging the fonts over the System Fonts group entry and will require administrator privileges. + + + + + +Duplicate Fonts +If you have lots of fonts installed on your system it is possible that you may have duplicates. +Click on the tools icon above the group list and select the Scan For Duplicate Fonts... tool, a simple tool that will scan your system looking for fonts that have multiple files associated with them. For example, if you have times.ttf and times.TTF installed in /usr/local/share/fonts the underlying font mechanism (called FontConfig) will only see one of these. So, if you un-installed the font, it would re-appear, as only one of the files would have been removed. Running this tool will produce a dialog listing each font that has multiple files, and the corresponding list of files. To select a file for deletion, click on the column containing the trash can icon. + + + +Preview +This displays a preview text in different font sizes. +Using the context menu enables you to zoom in and out, select a preview type (Standard Preview or All Characters) and change the preview text. + + +
diff --git a/doc/kcontrol/fonts/CMakeLists.txt b/doc/kcontrol/fonts/CMakeLists.txt new file mode 100644 index 00000000..6238f15e --- /dev/null +++ b/doc/kcontrol/fonts/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/fonts) diff --git a/doc/kcontrol/fonts/adjust-all.png b/doc/kcontrol/fonts/adjust-all.png new file mode 100644 index 0000000000000000000000000000000000000000..506a6179c871767b4442d039198304aa11738de4 GIT binary patch literal 32155 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/fonts/anti-aliasing.png b/doc/kcontrol/fonts/anti-aliasing.png new file mode 100644 index 0000000000000000000000000000000000000000..d88cacaed1afcfc947291b3b0616b48014ff7900 GIT binary patch literal 21340 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/fonts/index.docbook b/doc/kcontrol/fonts/index.docbook new file mode 100644 index 00000000..1bb5e2e2 --- /dev/null +++ b/doc/kcontrol/fonts/index.docbook @@ -0,0 +1,169 @@ + + + +]> + +
+ +Fonts + +&Mike.McBride; &Mike.McBride.mail; +&Anne-Marie.Mahfouf; &Anne-Marie.Mahfouf.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +KControl +fonts + + + + + +Fonts + +This module is designed to allow you to easily select different +fonts for different parts of the &kde; Desktop. + + + +Here's a screenshot of the fonts settings module + + + + + + The fonts settings module + + + + + +The panel consists of different font groups to give you a lot of +flexibility in configuring your fonts: + + +General: Used everywhere when the other font +groups do not apply + +Fixed width: Anywhere a +non-proportional font is specified + +Small: When small fonts are used + +Toolbar: Font used in &kde; application +toolbars + +Menu: Font used in &kde; application +menus + +Window title: Font used in the window +title + +Taskbar: Font used in the taskbar +panel applet + +Desktop: Font used on the desktop +to label icons + + + +Each font has a corresponding Choose... +button. By clicking on this button, a dialog box appears. You can +use this dialog box to choose a new font, a font style and size. +Then press Ok. + +An example of the font you have chosen will be displayed in the space +between the font group name and the Choose... +button. + +When you are done, simply click OK and +all the necessary components of &kde; will be restarted so your changes +can take affect immediately. + +The Adjust All Fonts... button allows you to +quickly set properties for all the fonts selected +above. A font selection dialog similar to the standard one will +appear, but you will notice checkboxes that allow you to change the +Font, Font style or +Size independently of each other. You can +choose any one, two, or three of these options, and they will be +applied to all the font groups. + + + +Adjusting all fonts + + + + + + The Adjust All Fonts... dialog + + + + + +For example, if you have selected several different font faces +above, and realize they are all a size too big (this often happens +when you change screen resolution, for instance), you can apply a new +font size to all the fonts, without affecting your customized font +faces and styles. + + +Anti-aliasing text + +Default anti-aliasing settings are those used system wide by your distribution and labelled System Settings. You can disable all anti-aliasing by choosing Disabled in the drop down box. + +To use and set up anti-aliasing, simply choose Enabled from the box on the right of Use anti-aliasing:. The Configure... button will then get enabled and clicking on it will bring you a dialog to configure anti-aliasing. + + + +Anti-aliasing properties + + + + + + The anti-aliasing properties dialog + + + + + +Placing a mark in the Exclude range: checkbox will allow you to specify which range of fonts will not be anti-aliased. This range is specified +with the two combo boxes on the same line. + +You can also choose the method that &kde; uses to create an anti-alias +look to your fonts, and how strongly it should be applied. If you are not +familiar with the individual methods, you should leave this option +alone. + + + + +The ability to use anti-aliased fonts and icons requires that you have +support in both X and the &Qt; toolkit, that you have suitable fonts +installed, and that you are using the built-in font serving capabilities +of the X server. If you still are having problems, please contact the +appropriate &kde; mailing list, or check the +FAQ. + + + + +Fonts DPI + +Force fonts DPI: proposes you an alternate DPI other than your system one which is used as default when this setting is on Disabled. You can check what DPI your X server is set to by running xdpyinfo | grep resolution in a terminal window and then change the DPI using the drop down box. This will be applied to newly started applications only. + + + + +
diff --git a/doc/kcontrol/fonts/main.png b/doc/kcontrol/fonts/main.png new file mode 100644 index 0000000000000000000000000000000000000000..2c0346c4a41c28d81f0334029ab5211846a0eeac GIT binary patch literal 33765 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�fGUb)VQ;B7 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/joystick/CMakeLists.txt b/doc/kcontrol/joystick/CMakeLists.txt new file mode 100644 index 00000000..eb9c4901 --- /dev/null +++ b/doc/kcontrol/joystick/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/joystick) diff --git a/doc/kcontrol/joystick/index.docbook b/doc/kcontrol/joystick/index.docbook new file mode 100644 index 00000000..36a496c5 --- /dev/null +++ b/doc/kcontrol/joystick/index.docbook @@ -0,0 +1,137 @@ + + + +]> +
+ +Joystick + + +Michael +Anderson + +
nosrednaekim@gmail.com
+
+
+ +
+ +2013-12-05 +4.12 + + +KDE +System Settings +joystick +calibrate + +
+ + +Joystick configuration module + +This module provides an interface to calibrate your joystick device as well as +see which functions on your joystick are mapped to which logical button or +axis. + + + +Here's a screenshot of the joystick module + + + + + + The joystick module + + + + + + +Device + + +Here you can see the logical location of the device. If you have more +than one joystick device, you can also select which one to configure. + + + + +Position + + +The plotted location of the X and Y axes of the joystick. Enable Show trace +to plot the path of the joystick from one point to another. + + +If the joystick cannot reach every point on this graph, or if it does not center correctly, you need to calibrate your device. + + + + +Buttons + + +A place to see the pressed state of buttons on your joystick and if the buttons +are mapped correctly. When a joystick button is pressed, PRESSED will appear +next to the logical number (as the computer sees it) of the button which was +pressed. + + + + +Axes + + +This displays the numerical values of the axis positions. 0 is centered and the +maximum and minimum values depend on the joystick and the particular axis. + + + + +Calibrate + + +Clicking on Calibrate will open a dialog to calibrate every axis on your joystick. + + + + +Calibrating your joystick + + + + + + Calibrating your joystick + + + + + + +Each axis will have to be moved to the minimum position, then the center, and finally the +maximum position. A meter in the bottom left corner of the dialog will help +determine which way increases and which way decreases the values. + + + + + +
+ + diff --git a/doc/kcontrol/joystick/joystick-calibration.png b/doc/kcontrol/joystick/joystick-calibration.png new file mode 100644 index 0000000000000000000000000000000000000000..5ff3bda13cccc337ec98efe2c69648734ab88251 GIT binary patch literal 25142 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 z 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 LG!(zen+E+K08s;U literal 0 HcmV?d00001 diff --git a/doc/kcontrol/kcmaccess/CMakeLists.txt b/doc/kcontrol/kcmaccess/CMakeLists.txt new file mode 100644 index 00000000..3f3a11cc --- /dev/null +++ b/doc/kcontrol/kcmaccess/CMakeLists.txt @@ -0,0 +1,4 @@ +########### install files ############### +# +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kcmaccess) diff --git a/doc/kcontrol/kcmaccess/index.docbook b/doc/kcontrol/kcmaccess/index.docbook new file mode 100644 index 00000000..99b6b5a9 --- /dev/null +++ b/doc/kcontrol/kcmaccess/index.docbook @@ -0,0 +1,264 @@ + + + +]> + +
+Accessibility + + +&Mike.McBride; &Mike.McBride.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +Systemsettings +accessibility +keys +bell + + + + +Accessibility + + +Introduction + +This module is designed to help users who have difficulty hearing +audible cues, or who have difficulty using a keyboard. + + +The module is divided into four tabs: Bell, Modifier keys, Keyboard Filters and Activation Gestures. + + + +<guilabel>Bell</guilabel> + + +This panel is divided into an Audible Bell section +and a Visible Bell section. + + + +The top check box labeled Use System Bell, determines +whether the normal System bell rings. If this option is disabled, the +System bell will be silenced. + + + +The next check box down can be used to play a different sound whenever +the system bell is triggered. To activate, place a mark in the check +box labeled Use customized bell, and enter the +complete pathname to the sound file in the text box labeled +Sound to play. If you want, you can select the +Browse button to navigate through your filesystem +to find the exact file. + + + +For those users who have difficulty hearing the System bell, or those +users who have a silent computer, &kde; offers the visible bell. This +provides a visual signal (inverting the screen or flashing a color +across it) when the system bell would normally sound. + + + +To use the visible bell, first place a mark in the check box labeled +Use visible bell. + + + +You can then select between Invert screen, or +Flash screen. If you select Invert +screen, all colors on the screen will be reversed. If you +choose Flash screen, you can choose the color by +clicking the button to the right of the Flash +screen selection. + + + +The slider bar can be used to adjust the duration of the visible +bell. The default value is 500ms, or half a second. + + + + + +<guilabel>Modifier keys</guilabel> + +There are the two sections Sticky Keys +and Locking Keys to this panel. + + + +Use Sticky Keys + + +If this option is enabled, you can press and release the &Shift;, +&Alt; or &Ctrl; keys, and then press another key to get a key combo +(example: &Ctrl; &Alt; +Del could be done with &Ctrl; then &Alt; +then Del). + + + +Also in this section is a check box labeled Lock Sticky +Keys. If this check box is enabled, the &Alt;, &Ctrl; +and &Shift; keys stay selected until you +de-selected them. + + + +As an example: + + + +With Lock Sticky Keys disabled: + +If you press the &Shift; key then press the +F key, the computer interprets this as &Shift;F. Now if you +type a P, the computer interprets this as the letter p +(no shift). + + + + + +With Lock Sticky Keys enabled: + + +If you press the &Shift; key twice then press the F key, +the computer interprets this as &Shift;F. Now if you +type a P, the computer interprets this as the letter P +(&Shift;P). To +de-select the &Shift; key, press it again. + + + + + + + + + + + + + +<guilabel>Keyboard Filters</guilabel> + +There are two sections to this panel. + + + +Use slow keys + + +If this option is enabled, you must hold the key down for a +specified length of time (adjustable with the slider) before the +keystroke will be accepted. This helps prevent accidental key strokes. + + + + + +Use bounce keys + + +If this option is enabled, you must wait for a specified length of time +(configurable with the slider) before the next key press can be +accepted. This prevents accidental multiple key strokes. + + + + + + + + + + +<guilabel>Activation Gestures</guilabel> + +There are two sections to this panel. + + + +Activation Gestures with these options: + + + +Use gestures for activating sticky keys and slow keys +Here you can activate keyboard gestures that turn on the following features: +Mouse Keys: Press &Shift;+NumLock +Sticky keys: Press &Shift; key 5 consecutive times +Slow keys: Hold down &Shift; for 8 seconds +Turn sticky keys and slow keys off after a certain period of inactivity + + + + + + +Notification with these options: + + + +Use the system bell whenever a gesture is used to turn an accessibility +feature on or off + +Show a confirmation dialog whenever a keyboard accessibility feature is +turned on or off +If this option is checked, &kde; will show a confirmation dialog whenever a +keyboard accessibility feature is turned on or off. +Ensure you know what you are doing if you uncheck it, as the keyboard +accessibility settings will then always be applied without confirmation. + +Use &kde;'s system notification mechanism whenever a keyboard accessibility +feature is turned on or off + + + + + +Click the Configure Notifications button to open a dialog +which allows you to edit the notifications for status changes of all keys. + + + + + + +
diff --git a/doc/kcontrol/kcmsmserver/CMakeLists.txt b/doc/kcontrol/kcmsmserver/CMakeLists.txt new file mode 100644 index 00000000..954e9f31 --- /dev/null +++ b/doc/kcontrol/kcmsmserver/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +#KDE_LANG = en +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kcmsmserver) diff --git a/doc/kcontrol/kcmsmserver/index.docbook b/doc/kcontrol/kcmsmserver/index.docbook new file mode 100644 index 00000000..fe387e04 --- /dev/null +++ b/doc/kcontrol/kcmsmserver/index.docbook @@ -0,0 +1,122 @@ + + + +]> + +
+ +Session Management + +&Jost.Schenck; &Jost.Schenck.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +KControl +session +System Settings + + + + +Session Management + + +Use + +In this &systemsettings; module you can configure &kde;'s session +manager and logout settings. + +Session management refers to &kde;'s ability to save the state +of applications and windows when you log out of &kde; and restore them +when you log back in. + + +General + + +Confirm logout + +If this option is checked, when logging out, &kde; will display a +dialog asking for confirmation. In this dialog you can also choose +whether you want to restore your current session when you login the next +time. + + + +Offer shutdown options + +If this option is checked, &kde; will offer a choice of actions during +logout. These include simply ending the current session (the +action performed if shutdown options are not enabled) turning off the +computer, or restarting the computer. + + + + + + +Default Leave Option +You can configure what should happen by default when you log out of +&kde;. These options are not possible on all operating systems, and some of +them may not appear unless you are using &kdm; as your login manager. + +The options available are self explanatory, if you are in doubt, +leave the default settings. They are: + + +End current session (this is the default) +Turn off computer +Restart computer + + + + +On Login +You may choose one of three options on what should happen when +you log into &kde;: + + + +Restore previous session +If this option is checked, &kde; will save your current +session's state when you logout. &kde; will restore your session on the +next login, so you can continue to work with a desktop just like you +left it. + + + +Restore manually saved session +Instead of restoring &kde; to the state it was when +you logged out last, it will be restored to a specific state that you +have saved manually. +If this option is checked, the start menu offers an additional item +LeaveSave Session. + + + +Start with an empty session + +If you choose this option, &kde; will never restore sessions that it has saved. + + + +Finally, you can enter a colon (:) or comma (,) +separated list of applications that should not be saved in sessions, +and therefore will not be started when restoring a session. For example +xterm:konsole or xterm,konsole. + + + + + + + +
+ diff --git a/doc/kcontrol/kcmstyle/CMakeLists.txt b/doc/kcontrol/kcmstyle/CMakeLists.txt new file mode 100644 index 00000000..6a3947ea --- /dev/null +++ b/doc/kcontrol/kcmstyle/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kcmstyle) diff --git a/doc/kcontrol/kcmstyle/index.docbook b/doc/kcontrol/kcmstyle/index.docbook new file mode 100644 index 00000000..faf1a682 --- /dev/null +++ b/doc/kcontrol/kcmstyle/index.docbook @@ -0,0 +1,238 @@ + + + +]> + +
+ + +Style + +&Mike.McBride; &Mike.McBride.mail; + + + +2013-06-02 +&kde; 4.11 + + +KDE +System Settings +style + + + +Style + + +Introduction + +This module is used to configure how the individual widgets are +drawn by &kde;. + +A Widget is a commonly-used +programmer's term for referring to User Interface elements such as +buttons, menus, and scroll bars. You can think of them as the +fundamental pieces that are assembled to make your +application. + +You can configure how the widgets are drawn with this module, +but to change the color of the widgets, you should refer to the +section entitled Colors. + +This panel is divided into two tabs: Applications +and Fine Tuning. + + +<guilabel>Applications</guilabel> tab + +The top drop down box, labeled Widget Style +contains a list of the pre-defined styles. +Each style has a name, and a brief description. + +To change styles, simply click on the style name, and a preview +of the style will be displayed in the preview box below the style list. + + If a style is configurable, the Configure... button +at the right side of the drop down box is enabled and can be used to open +a dialog to select further settings. + + + + + + +<guilabel>Fine Tuning</guilabel> tab + + + + +Graphical effects + +&kde; applications will run internal animations with the selected display resolution and CPU usage. + + + + +Show icons on buttons + +If this option is selected, action buttons (like OK and +Apply) will have a small icon located within them to act +as a visual reference. If this option is not selected, then only text +will appear on the button. + + + + +Show icons in menus + +If this option is selected, &kde; applications will show small icons alongside +most menu items. If this option is not selected, then only text +will appear in the menus. Changes to the visibility of menu icons will only affect newly started +applications. + + + + +Main toolbar text, Secondary toolbar text + +These drop down boxes lets you determine where on the button in both toolbars the +text name of the button will appear as the default. +If No Text is selected, then there is no text on the toolbar buttons. +If Text Only is selected, then the button's icon is replaced with a text name of +the button. If Text Beside Icons is selected, then the name of the button +will be placed to the right of the icon. +If Text Below Icons is selected, the default will be to have the text +of the button below the icon. + +This option only specifies the default location. +Each application can override the setting used in this panel. + + + + +Menubar style + +In application: The classic menubar at the top of the application window. +Title bar button: The window has an additional menu button top left. +All changes will take effect only for newly started applications. +Top screen menubar: This will turn on a menubar at the top of the screen that +is hidden by default and revealed on mouse over or a menu button on the window decoration. +This menubar will reflect the menu options of the active application. +Only export: for use by plasma runners + applets. +To use this feature you need a KRunner plugin like Appmenu action launcher. +Select an application, press &Alt;F2 +and type the menu action you want to perform. + + + + + + + + + + + +
diff --git a/doc/kcontrol/keyboard/CMakeLists.txt b/doc/kcontrol/keyboard/CMakeLists.txt new file mode 100644 index 00000000..23797c03 --- /dev/null +++ b/doc/kcontrol/keyboard/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/keyboard) diff --git a/doc/kcontrol/keyboard/index.docbook b/doc/kcontrol/keyboard/index.docbook new file mode 100644 index 00000000..31c9dcdc --- /dev/null +++ b/doc/kcontrol/keyboard/index.docbook @@ -0,0 +1,218 @@ + + + +]> + +
+Keyboard + + + +&Mike.McBride; &Mike.McBride.mail; +&Anne-Marie.Mahfouf; &Anne-Marie.Mahfouf.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +System Settings +keyboard + + + +This module allows you to choose how your keyboard works. + +There are three tabs in this module. + + +The Hardware tab +The actual effect of setting these options depends upon the +features provided by your keyboard hardware and the X server on which +&kde; is running. As an example, you may find that changing the key +click volume has no effect because that feature is not available on your +system. + + + +Keyboard model: + + +Here you can set your keyboard model. This setting is independent of your +keyboard layout and refers to the "hardware" model, i.e. the way your +keyboard is manufactured. Modern keyboards that come with your computer usually +have two extra keys and are referred to as "104-key" models, which is +probably what you want if you do not know what kind of keyboard you have. + + + + + +NumLock on KDE Startup + +You can choose to either always Turn on or +Turn off the NumLock when &kde; starts, or you can +choose to have &kde; leave NumLock at whatever it was set to before &kde; +started up. + + + + +Keyboard Repeat + +When this option is turned on, pressing and holding down a key +emits the same character repeatedly until the key is released. Pressing +and holding the key will have the same effect as pressing it multiple +times in succession. + Almost all users will want to have this option enabled, because it +makes navigating through documents with the arrow keys significantly +easier. + + + +Delay + +This option allows you to set the delay after which a pressed +key will start generating keycodes. + + + +Rate + +This option allows you to set the rate at which keycodes are +generated while a key is pressed. + + + +Key click volume + +If supported, this option allows you to hear audible clicks from +your computer's speakers when you press the keys on your keyboard. In +essence, this simulates the click of a mechanical +type-writer. You can change the loudness of the key click feedback by +dragging the slider button. Setting the volume to 0% by moving the slider +to the left turns off the key click. +Type some characters into the Test area text box to +verify the volume you selected. +Many computers won't support this function. +Very few people would choose to enable this option, since it +generally annoys everyone else in the room. However, if your heart +yearns for the pre-soft-key era, this may help you to re-experience the +warm sentimentality of days-gone-by. + + + + + + + + + + + +The Layouts tab +This tab lets you choose what keyboard layouts you want to use, what +indicator you want in the system tray, how you want to switch and which +shortcuts you will use. + + + +Layout Indicator + +You can choose to Show layout indicator +which will show the language iso name in the system tray. You can choose to +show the indicator even if you have a single layout enabled +and you can show the language flag instead of only the ISO code by checking +Show flag. + + + + +Switching Policy + +If you select Application or +Window switching policy, changing the keyboard layout will +only affect the current application or window. Global will +change the keyboard layout globally and Desktop will change +it only for the current virtual desktop. + + + + + +Shortcuts for Switching Layout + +Main shortcuts is a shortcut for switching +layouts which is handled by X.org. 3rd level shortcuts is a +shortcut for switching to a third level of the active layout (if it has one) +which is handled by X.org. It allows modifier-only shortcuts. +Alternative shortcut is a shortcut for switching layouts +which is handled by &kde;. It does not support modifier-only shortcuts and also +may not work in some situations (⪚ if popup is active or from screensaver). + + + + + +Configure layouts + +If you check Configure layouts you will be able to +add and remove keyboard layouts in order to switch between them when you need. + +Clicking on Add will open a dialog where you +will be able to choose the new keyboard layout you want to add as well as its +variant, label and shortcut. + + +The list of layouts right to the Layout label in the +Add Layout dialog can be narrowed down using +Limit selection by language drop-down list. You +can click on Preview button to preview chosen layout +in a separate window. + +You can order the layouts with the up and down buttons, the top one being +the default one. + + + + +Spare layouts + +This option can be enabled only if you have more than two layouts. +Spare layouts allow to toggle between small number of layouts easily +while keeping more layouts handy close by. For example you might use 3 +languages: English, Ukrainian and German but first two are used often +and third one just occasionally. In this case you can configure first +two as main layouts (setting Main layout count: 2) +and German one as spare one - when you toggle with +keyboard and left mouse button the switch will happen between main +layouts only but you can always choose 3rd layout with context menu. +When spare layout is chosen it replaces the last main layout (this is +done for technical reasons, usually global shortcuts work based on the +1st active layout so it's more reliable to preserve the 1st layout when +allowing to activate spare layouts). + +As X.org only allows to have 4 layouts to switch spare layouts feature +also allows to overcome this limitation: user can have up to 4 main +layouts (managed by X.org) but 4 more spare layouts allowed (managed by +layout switcher). Thus user can conveniently work with up to total of 8 +layouts (although the 4 spare layouts limit can be raised in the future). + + + + + + + + +The Advanced tab +In this tab, if you check Configure keyboard options +you will then be able to set a few options regarding some keys settings. You can +expand these options by clicking on the > symbol on the left of the option +then you choose your setting in the expanded list. + +
diff --git a/doc/kcontrol/keys/CMakeLists.txt b/doc/kcontrol/keys/CMakeLists.txt new file mode 100644 index 00000000..2fe4a4ef --- /dev/null +++ b/doc/kcontrol/keys/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/keys) diff --git a/doc/kcontrol/keys/index.docbook b/doc/kcontrol/keys/index.docbook new file mode 100644 index 00000000..f06fff13 --- /dev/null +++ b/doc/kcontrol/keys/index.docbook @@ -0,0 +1,202 @@ + + + +]> + +
+Shortcuts + + +&Mike.McBride; &Mike.McBride.mail; +&Jost.Schenck; &Jost.Schenck.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +KControl +key bindings +bindings +shortcuts + + + + +Shortcuts + + +Introduction + +While most of the functionality offered by &kde; can be accessed +using a simple point and click interface, many people +prefer using the keyboard for some tasks. Pressing something like + &Ctrl;F is often +just faster than moving your hands off the keyboard to the mouse, +opening the Edit menu and selecting +Find. + + As different people have different preferences about keyboard +shortcuts, &kde; offers full customization of key +bindings. A key binding or shortcut is a combination of an +action with a key or a combination of keys. + + + + +Standard Shortcuts and Global Shortcuts + +Standard shortcuts and Global shortcuts work just the same. +Actually, in a certain way standard or application shortcuts are +global as well. The only +difference is: + + +Standard keyboard shortcuts refer to actions +that are often available in applications, such as Save, Print, Copy +&etc; +Global keyboard shortcuts are shortcuts for +actions that make sense even when no application is opened. These +shortcuts usually refer to actions like switching desktops, manipulating +windows &etc; + + +Please note, that the application shortcuts configured here are +only the standard actions often found in +applications. Most applications will define their own actions as well, +for which you have to customize key bindings using the application's +key bindings dialog. + + +Standard Keyboard Shortcuts page +At the top of this dialog you see an input box, where you can +search interactively for shortcut names (⪚ Copy) or combination of keys +(⪚ Ctrl+C) by typing them literally here. +Below the search box you can see a list of key bindings, &ie; associations between actions +(⪚ Copy) shown in the Actions column and keys or combination of keys +(⪚ &Ctrl;C ) shown in the +Shortcut or Alternate column. + + + + + +Global Keyboard Shortcuts page +At the top of this page is a drop down box which allows you +to select a KDE component like KWin, Plasma Desktop &etc; +The defined shortcuts for the selected component are displayed in the +Action and Global column in the list view. +Click the File drop down box at the right to import/export a +Scheme, set all shortcuts to none and remove a component. +This page has the same search box as the Standard Keyboard +Shortcuts tab. + + + + +Configuring Key Bindings + +Configuring key bindings is pretty easy. In the middle of +these &systemsettings; modules you will find a list of available +actions. If there's a key binding configured for that action you will +find it in the columns right to it. Just select the action you want to +configure. + +After you have selected an action in the list you will notice that +this item is highlighted and you see two additional check boxes below +this item in the list view. There you can configure a +combination of keys or maybe no key binding at all for the selected +action. + + + +Default: the selected action +will be associated with &kde;'s default value. This is a good choice +for most actions, as &kde; comes with reasonable key bindings we have +thought about. + +Custom: if this option is +enabled, you can create a key combination for the selected +action. Click on the button labeled either None +or labeled with the previously selected custom shortcut. Now the button label +changes to Input. Then press any modifier key +(&ie; &Shift;, &Ctrl;, or &Alt;) and then normal key or a function key (⪚ F11) +you want to assign to this key combination. +Clicking on the Alternate column of a row in the list +allows to edit the second shortcut for the action. + + + + + + + + +
diff --git a/doc/kcontrol/khotkeys/CMakeLists.txt b/doc/kcontrol/khotkeys/CMakeLists.txt new file mode 100644 index 00000000..cf166228 --- /dev/null +++ b/doc/kcontrol/khotkeys/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/khotkeys) diff --git a/doc/kcontrol/khotkeys/groups-comment.png b/doc/kcontrol/khotkeys/groups-comment.png new file mode 100644 index 0000000000000000000000000000000000000000..8ef80c3ad0e376366627d1c98c3894cf9e93ef70 GIT binary patch literal 63546 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

~3nkyjaUcHH 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ⅆ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 + + +]> +

+Custom Shortcuts + + + +Subhashish Pradhan +&TC.Hollingsworth; &TC.Hollingsworth.mail; + + + + +2011 +Subhashish Pradhan + + +2012 +&TC.Hollingsworth; + +&FDLNotice; + +2013-12-05 +&kde; 4.12 + + +KDE +Systemsettings +shortcuts +hotkeys +Custom Shortcuts +khotkeys + + + + +Introduction + +The Custom Shortcuts &systemsettings; module +allows you to configure custom keyboard shortcuts and mouse gestures. You can +use them to control applications, run specific commands, and more. + + + + + +Managing Shortcuts and Groups + + +Adding Groups + +The module allows to you to sort related shortcuts into Groups. For +instance, if you have some shortcuts that relate to your music player, you +could create a group for them called Music Player. + + +To add a new group, click on the Edit button below +the left pane and select the New Group option. + + + + +Adding Shortcuts + +To add a new shortcut, click on the Edit button +below the left pane and select the New option. + +The first menu that appears allows you to select the type of trigger. The +following options are available: + + + + +Global Shortcut +These are standard keyboard shortcuts that will be recognized +anywhere, as long as a &kde; &plasma; Workspace is running. + + + +Window Action +Window Actions are triggers that occur when something happens +to a particular window, like when it appears, gains focus, or is closed. + + + + +Mouse Gesture Action +A mouse gesture action is triggered when a particular movement +of the mouse (or touchpad or touchscreen) is performed. + + + + +Once you've selected the type of trigger, another submenu appears that allows +you to select an action type. The following types are available: + + + + +Command/&URL; +This action will launch a command or open a &URL; when the +shortcut is triggered. + + + +&DBus; Command +This action will call a &DBus; method in a running application or +system daemon. For more information on &DBus;, see the +&DBus; +Introduction on &kde; TechBase. + + + +Send Keyboard Input +This action will send keyboard input to the currently +running application, just as if you had typed it in yourself. + + + + +Once you've selected the action type, you can then edit the shortcut to +your liking. See for more information. + + + + +Deleting Shortcuts and Groups + +To delete a shortcut or group, select it, then click on the +Edit button below the left pane, and select the +Delete option. + + + + +Exporting Groups + +You can export a group, so you can save the shortcuts contained within and +use them on another computer or maintain a backup. + +To export a group, select the group to be exported, then click on the +Edit button below the left pane and select the +Export Group... option, which opens a new window that +lets you define some options about the exported group. The following options +are available: + + + + +Export Actions +This allows you to select the state the shortcuts will be in +when they are imported later. Select Actual State to +maintain their current state, Enabled to ensure they are +all enabled, or Disabled to ensure they are all disabled. + + + + +Id +Here you may enter text to identify the group. If the group is +included by default, this text may be filled in by default. + + + +Allow Merging +This defines what happens if the group already exists on the +system the exported group is imported to. When enabled, any new actions will +be added to the group on the target system, while actions that have the same +name but a different configuration will updated with the configuration from the +imported file. When disabled, the module will refuse to import the file. + + + + +Filename +Here you may enter the filename you wish to export the +shortcut to. You may also select the Browse button to +the right of the text box to open the File dialog and select a file from there. + + +Exported files use the extension .khotkeys by +default. + + + + + + +Exporting a Group + + +The Export Group dialog. +Exporting a group of shortcuts. + + + + + + +Importing Groups + +To import a group, click the Edit button below the +left pane and select Import.... A file selection dialog +opens that permits you to locate a file previously created using the Export +function. + + + + + + + +Modifying Groups + +In the left section of the window, the default shortcuts are categorized +into groups. These groups can be expanded by clicking the arrow beside them to +reveal the shortcuts. + +When you click on a group, you are presented with two tabs to configure +the group itself. The Comment allows you to store notes +about the group, and are not actually used by the system for anything. The +Conditions tab allows you to restrict which windows a group +of shortcuts works with. + + +The Comment Tab + + +The Comment tab in a group. +Modifying a group's comment. + + + +Conditions are displayed in a tree, the top level of which is +And. All conditions beneath And must +be satisfied for shortcuts in the group to be triggered. + +You may add additional groups of conditions by clicking the +New drop down box to the right of the tree of conditions. Types +of groups include the aforementioned And, +Or, in which only one member of the group must be +satisfied, or Not, in which the inverse of all +members will trigger the shortcuts in the group. + +To add a window definition to the list, press the New +button. You may select Active Window... if you want +the shortcut to be triggered only if the specified window currently has focus, +or you may select Existing Window... if you want the +shortcut to be triggered as long as that window is open , regardless of +whether or not you are using it. Selecting either of these options opens a +window where you can edit the window definitions. + +Click the Edit... button to edit an existing set +of window definitions. A window opens with the window definition editor. For +more information, see . + +To remove a window definition from the conditions list, click the +Delete button. + + + + + +Modifying Shortcuts + +In the left section of the window, the default shortcuts are categorized +into groups. These groups can be expanded by clicking the arrow beside them to +reveal the shortcuts. + +The Preset Actions group, when expanded, reveals a +shortcut configuration named PrintScreen which, when +selected, reveals section on the right side, with three tabs: + + +The Comment Tab + +The Comment tab allows you to describe how to use the +shortcut, what it does, or anything else you might want to include. + + + + +The Trigger Tab +The Trigger tab contains the trigger configuration, +which depends on the type of trigger specified: + + + + +Global (Keyboard) Shortcut + + +To modify a keyboard shortcut, click on the button that contains a wrench, +and then enter the desired keyboard shortcut. To erase the shortcut, click on +the button with the icon to the right of the +change shortcut button. + + +Modifying a Keyboard Trigger + + +The Trigger tab for a keyboard shortcut. +Modifying a trigger for a keyboard shortcut. + + + + + + + +Window Action + + +Window actions contain several options: + + + + +Trigger When + + +This configures the particular window action that must occur for the +shortcut to be triggered. The following options are available: + + + +Window appears - +Triggered when a window is opened. + +Window disappears - +Triggered when a window is closed. + +Window gets focus - +Triggered when you switch to a window. + +Window loses focus - +Triggered when you switch away from a window. + + + + + + + +Window +This is where you define the actual window or windows the trigger applies +to. For more information, see + + + + + + + + +Mouse Gesture + + +A mouse gesture can be changed by clicking the Edit +button below the area that displays the mouse gesture, which will open a window. +Hold down the &LMB; and draw the desired mouse gesture in the area provided. +The gesture will be saved when you release the &LMB;. + + +Modifying a Mouse Gesture Trigger + + +The Trigger tab for a mouse gesture shortcut. +Modifying a trigger for a mouse gesture. + + + + + + + + + + + +The Action Tab + +The Action tab is where you configure the action that +will be performed when the shortcut is triggered. There are several types of +actions that have different configuration options: + + + + +Command/&URL; + + +When using a Command or &URL; is a trigger, a text box is provided where +you may enter the command to run or &URL; to open when the shortcut is triggered. +You may also click the Browse button to the right of the +text box to open a file selection dialog in which you can select a file on your +local or a remote system. + + +Modifying a Command Action + + +The Action tab for a command. +Modifying a command action. + + + + + + + +&DBus; Command + + +The following options are provided that allow you to specify a &DBus; +method to be performed: + + + + +Remote application +The service name of the remote application the method is to +be performed on, for instance org.kde.kate if you wanted +to perform it on the &kate; Advanced Text Editor. + + + +Remote object +The path to the remote object the method is to be performed on, +for instance /Document/1, if you wanted to perform it on +the first document opened in &kate;. + + + +Function +The name of the &DBus; method to be called, for instance +print if you wanted to print the document. + + + + +For more information on &DBus;, see the +&DBus; +Introduction on &kde; TechBase. + + + + + +Send Keyboard Input + + +At the top of the Action tab, there is a large text +entry where you may enter the keystrokes you wish to be sent when the shortcut +is triggered. + +Most keys contain a single character, and to enter them here you just +enter that character. For instance, to type an A, just enter +A. Some keys have longer names, and you can also use +those names. For instance, to press the &Alt; key, simply enter +Alt. + + +Individual keystrokes should be separated by a colon +(:). For instance, to type foo, enter +F:O:O. + +Keys that need to pressed at the same time should be separated by a plus +sign. For instance, to press +&Ctrl;C, enter +Ctrl+C. + + +Remember, you must enter keystrokes here exactly as you would on a keyboard. +To capitalize letters, you must enter the &Shift; key. For instance, to type +Hello, enter Shift+H:E:L:L:O. + +This also applies to special characters. For instance, to type the +at-sign on the U.S. English keyboard layout, enter Shift+2. + + + + +The action that is performed is dependent on the currently selected +keyboard layout. If you change keyboard layouts and trigger a shortcut, it +may have undesired consequences. + + +Beneath the keystroke entry text box, you may select which window the +keystrokes will be directed to. You may choose from the following options: + + + +Active window - +The window that is currently open. + +Specific window - +The window that you describe using the form below. For more information on +describing windows, see . + +Action window - +When using the Window Actions trigger type, enter the keystrokes in the window +that triggered the shortcut. + + + + +Modifying a Keyboard Input Action + + +The Action tab for keyboard input. +Modifying the keyboard input action for a shortcut. + + + + + + + + + + + + + + +Defining Windows + +Several areas of the module allow you to define a list of windows. They +all use the same interface, which contains the following options: + + + + +Comment +This is merely an informational text box you can use to explain +what the trigger applies to or save other useful information. It is not +actually used by the system for anything. + + + +Window List +Beneath the Comment box on the left is the +list of all window definitions currently present in the trigger. Simply click +on one to perform an operation on it. + + + +Edit... + + +Press this button to modify the currently selected window definition. A +new window is opened that allows you to edit it. This window contains the +following options: + + + + +Window Data + + +This is where you describe the window the trigger should apply to. + +At the top, there is a Comment field, which is +informational just like the one in the main Trigger tab. + +Three window characteristics are available: + + + +Window title - +The title that appears at the top of the window. + +Window class - +Usually the name of the application. + +Window role - +Usually the name of the &Qt; class that makes up the window. + + + +Each window characteristic provides a drop-down box, and a text box below +it. Enter the value you wish to test windows for in the text box. From the +drop-down box, select which kind of test you wish to apply. You can use +Is to require an exact match, Contains +to require that the text entered be somewhere inside the full value, or +Matches Regular Expression to use a regular expression to +define the match. You may also perform the inverse of all these operations. +Select Is Not Important if you do not wish for that +particular characteristic to be examined. + +The easiest way to fill in this information is to open the desired window, +then click the Autodetect button at the bottom of this +section, and finally click on the desired trigger window. All three window +characteristics will be populated with the information from that window, and +you can then adjust the settings as necessary. + + + + + +Window Types + + +This lets you restrict the match to a particular type of window. The +following options are available: + + + +Normal - +A regular application window. + +Desktop - +The main desktop is actually a special window all its own. + +Dialog - +A small window that is part of a normal application, such as a message box or +a configuration screen. + +Dock - +A small window that can be attached or detached from a main application window. + + + + + + + + + + + + + +New... +Create a new window definition. This opens the edit dialog +described above. + + + +Duplicate... +This creates a new window definition with the exact same +specifications as the currently selected window definition. It will open the +edit dialog described above so you may make further changes. + + + +Delete +Removes the currently selected window definition. + + + + + + + + +Settings + +When you first enter the module, or when you click the +Settings button below the left pane, there will be +several configuration options in the right pane: + + + + +Start the Input Actions daemon on login +This configures whether or not to activate the background +application that monitors for keyboard shortcuts and triggers configured +actions. It is enabled by default. + + + +Gestures + +Select this check box to enable mouse gestures. + +There are two options specific to mouse gestures: + + + + +Timeout +This specifies the maximum time interval during which the mouse +gesture will be monitored and recognized by the system, in milliseconds. + + + + +Mouse Button +This specifies the mouse button to be used for mouse gestures. +Usually, 1 is the &LMB;, 2 is the +&RMB;, and 3 is the middle or wheel button. If your +mouse has more buttons, you can also use those instead. + + +Button 1 is unavailable, so mouse gestures do not interfere with the +normal operation of your system. + + + + + + + + + + + +Settings + + +The Settings screen. +Editing Custom Shortcuts settings. + + + + + + + +Credits and License + +Special thanks to Google Code-In 2011 participant Subhashish Pradhan for +writing much of this article. + + + +&underFDL; +&underGPL; + + + +
+ + diff --git a/doc/kcontrol/khotkeys/manage-export.png b/doc/kcontrol/khotkeys/manage-export.png new file mode 100644 index 0000000000000000000000000000000000000000..20a6fd89aad911af0e95f8db42578df9945f8446 GIT binary patch literal 68149 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

XSqFK3(IQ8 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/kwincompositing/CMakeLists.txt b/doc/kcontrol/kwincompositing/CMakeLists.txt new file mode 100644 index 00000000..877a45ce --- /dev/null +++ b/doc/kcontrol/kwincompositing/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kwincompositing) diff --git a/doc/kcontrol/kwincompositing/index.docbook b/doc/kcontrol/kwincompositing/index.docbook new file mode 100644 index 00000000..dce55c39 --- /dev/null +++ b/doc/kcontrol/kwincompositing/index.docbook @@ -0,0 +1,82 @@ + + + +]> + +

+ + +Desktop Effects + +&Mike.McBride; &Mike.McBride.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +KControl +desktop +effects + + + +Desktop Effects + + +Introduction + +This module is used to configure desktop effects +for &kde;. + + +This panel is divided into three tabs: General, +All Effects and Advanced. + + +<guilabel>General</guilabel> tab + +At the top of this tab in the section Activation is a checkbox labeled Enable +desktop effects at startup. If there is no mark in front of this checkbox, then all +visual effects are disabled. +All desktop effects can be turned on and off using the global shortcut +&Alt;&Shift;F12. + +Below that section there are some settings for the simple desktop effects like +improved window management, various animations, effects for desktop switching and +the animation speed. + + + +<guilabel>All Effects</guilabel> tab + +The main part of this page is a list of all available effects grouped +by Accessibility, Appearance, +Candy, Focus, Tools +and Window Management. +Use the incremental search bar above the list window to find items in the list. + +Check an effect in the list to enable it. Display the About +dialog by clicking the info button at the right side of the list item. +Some effects have settings options, in this case there is a tool button +at the left of the info button. Click it to open a configuration dialog. + + + +<guilabel>Advanced</guilabel> tab + +On this tab you can select a Compositing type and the Qt graphics system. +In the next two sections you can configure General Options and OpenGL Options. + + + + + + + + +
diff --git a/doc/kcontrol/kwindecoration/CMakeLists.txt b/doc/kcontrol/kwindecoration/CMakeLists.txt new file mode 100644 index 00000000..ab136bcf --- /dev/null +++ b/doc/kcontrol/kwindecoration/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kwindecoration) diff --git a/doc/kcontrol/kwindecoration/buttons.png b/doc/kcontrol/kwindecoration/buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..1c4fdf7c7ecef1121a937d9fa66ba062dc52bc0f GIT binary patch literal 38993 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 Av;Y7A literal 0 HcmV?d00001 diff --git a/doc/kcontrol/kwindecoration/decoration.png b/doc/kcontrol/kwindecoration/decoration.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc84e542503d7a8a82d789f5b1e998e7fa04852 GIT binary patch literal 41641 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 E0Wy>b5&!@I literal 0 HcmV?d00001 diff --git a/doc/kcontrol/kwindecoration/index.docbook b/doc/kcontrol/kwindecoration/index.docbook new file mode 100644 index 00000000..17ea824d --- /dev/null +++ b/doc/kcontrol/kwindecoration/index.docbook @@ -0,0 +1,150 @@ + + + +]> + +
+ +Window Decorations + +&Rik.Hemsley; &Rik.Hemsley.mail; +&Anne-Marie.Mahfouf; &Anne-Marie.Mahfouf.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +Systemsettings +kwin +window +border +theme +style + + + +Window Decoration + +This module allows you to select a style for the buttons and borders around +windows. + + +Window Decorations + + + +Window Decoration Configuration Module + + + + + + Window Decoration Configuration Module + + + + + +Choose a window decoration style from the preview list, using the +search field at the top of the screen. + +The &kde; default window decoration is called "Oxygen". + +Each style has a different look, but also a different +feel. Some have (sometimes invisible) +resize borders all around the edge, which make resizing +easier but moving more difficult. Some have no borders on certain +edges. One (BII) even has a dynamically sized and +positioned title element. + +You are encouraged to experiment with the different styles until +you find one which best suits your pattern of work. + +Below the preview pane you find three buttons to open configuration dialogs +for decoration and buttons of the selected style or to download additional +styles. + + + + +Decorations + +In this dialog you can change the decoration of the window. + +The available options depend on the selected style. + + + +Oxygen Decoration Options + + + + + + Oxygen Decoration Options + + + + + + + +Buttons + +This dialog allows you to customize the buttons location on the titlebar. You can move Close button to the left for example. Check the Use custom titlebar button positions option in order to customize your titlebars. Then use the &kde; titlebar below and the buttons on its left and right to rearrange them as you want them. + + + + +Window Decoration Configuration Module + + + + + + Window Decoration Configuration Module + + + + + + By default, Show window button tooltips is checked and tooltips are shown. + + +This page has instructions directly on it - just drag around the +buttons until you have the order that makes you comfortable. + + +Not all the window decorations are able to comply with your custom +set button order. The ones that cannot are being converted, but at the +time of this release they have not been all been changed. + + +Apart from choosing the window decoration itself, you can choose +here two further options: if there should be a tooltip while you hover +your mouse over a window decoration button, and if the window +decoration should attempt to use a custom set button order. + + +The tooltips can be quite useful if you have set a custom button +order, and then changed to an unfamiliar window decoration. + + + +For accessibility purposes, some window decorations support +extra wide borders. If this is available, you can also choose a +border size here. These large borders are easier to see for low +vision users, and easier to grab for people with limited mobility or +difficulty using a mouse. + + + + + + +
diff --git a/doc/kcontrol/kwindecoration/main.png b/doc/kcontrol/kwindecoration/main.png new file mode 100644 index 0000000000000000000000000000000000000000..1946aa3ef9d7ea82fc781ee8103be45d661433fc GIT binary patch literal 78857 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 + + +]> + +
+ + +Screen Edges + +&Mike.McBride; &Mike.McBride.mail; + + + +2014-03-05 +&kde; 4.11 + + +KDE +Systemsettings +desktop +effects + + + +Active screen edges allow you to activate effects by pushing your mouse +cursor against the edge of the screen. Here you can configure which effect +will get activated on each edge and corner of the screen. + + +Click with any mouse button onto a square and select an effect +in the context menu. Edges with a black square have already an attached effect, +a grey colored square indicates that no effect is selected for this edge. + +The number of accessible items in the context menu depends on the settings in the module + +Desktop Effects in the Workspace Appearance and Behavior +category. Enable desktop effects to activate compositing, select the compositing type, +and then choose your favorite effects on the +All Effects tab from the Windows Management +group. This activates the corresponding items in the context menu. + +If you are looking for the setting to enable switching of +desktops by pushing your mouse cursor against the edge of +the screen choose one of the above mentioned +Window Management effects from the context menu. + +The section Window Management has two additional options when moving windows to screen edges: + +Maximize windows by dragging them to the top of the screen. + +Tile windows by dragging them to the side of the screen. The windows will be tiled to a quarter of the screen if dragged to the upper or lower part of the screen height determined by the value in the spinbox, otherwise to the full height of the screen. + + + + +The Other Settings configure the behavior pushing the mouse cursor to a screen edge. +Switch desktop on edge: Change desktop when the mouse cursor is pushed against the edge of the screen. +If Always Enabled is selected all effects configured for screen edges in the first section of this module will be disabled. + +Activation delay: The amount of time required for the mouse cursor to be pushed against the edge +of the screen before the action is triggered + +Reactivation delay: The amount of time required after triggering an action until the next trigger can occur. + + +
diff --git a/doc/kcontrol/kwintabbox/CMakeLists.txt b/doc/kcontrol/kwintabbox/CMakeLists.txt new file mode 100644 index 00000000..d170cde3 --- /dev/null +++ b/doc/kcontrol/kwintabbox/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/kwintabbox) diff --git a/doc/kcontrol/kwintabbox/index.docbook b/doc/kcontrol/kwintabbox/index.docbook new file mode 100644 index 00000000..9bd26c96 --- /dev/null +++ b/doc/kcontrol/kwintabbox/index.docbook @@ -0,0 +1,101 @@ + + + +]> +
+ +Task Switcher + +&Martin.Graesslin;&Martin.Graesslin.mail; + + + +2014-03-10 +&kde; 4.11 + + +KDE +System Settings +desktop +window +navigation + + + + +Navigating through Windows + +This module offers the possibility to configure the behaviour for Navigating through windows often referred to as &Alt; . There are two independent sets of effects which can have different settings. For each of this sets there is an own tab (Main and Alternative) in this module. + + + +The first set of effects on the Main tab has predefined shortcuts. If you want to use the second set of effects on the Alternative tab, you have to set a shortcut for these effects in the Shortcut Editor manually. + + +For navigating through windows without &Alt; , you can define screen edge actions in the &systemsettings; module Screen Edges. + + +The following documentation of options applies to the general settings and the alternative settings as well. + + +Visualization + +There are several effects which can be used instead of the normal window list when compositing is enabled. By default the Thumbnails effect is used. This effect displays a small thumbnail of each window inside a box and the currently selected window is highlighted. +There are several additional predefined layouts which provide an informative or compact view, small or large icons, a grid and window title only. +Selecting one of these layouts you will have a button to show a preview. +If you enable Show selected window it will be shown as background of the task switcher window. + + +Cover Switch and Flip Switch effect are more fancy effects which require OpenGL. Cover Switch displays the windows in a gallery with a large thumbnail of the currently selected window in the center of the screen while all other windows are rotated on the left and right. Flip Switch displays all windows on a 3D stack. The selected window is on top of the stack and navigating through the windows will move the stack so that the new selected window is on the top. + + +If the effect provides additional settings the configure button will be activated. By clicking this button a configuration dialog will be shown. + + +When compositing is not active or gets suspended the normal window list will be shown. There is no loss in functionality if an effect is selected and compositing is not active. + + + +Shortcuts + +The shortcut editor provides the configuration interface for the keyboard shortcuts for navigating through windows. Each of the two possible sets of effects has two shortcuts: one for the forward direction and one for the reverse direction. Please note that the window list can only be shown if you select a shortcut with a keyboard modifier such as the &Alt; or &Ctrl; key. This modifier has to be hold while switching. Selecting a shortcut without a modifier key can break the behaviour of navigating through windows. + + + + +Content +It is possible to influence the sort order, you can either use a sort order based on the last usage of the windows or the stacking order of the windows. + +If you check Include "Show Desktop" icon an entry for the desktop will be added to list with application windows. Then you can select this entry in the list to minimize all windows. +If Only one window per application is selected then only the last used instance of an application is contained in the list. Switching to other instances is possible only via the panel then. + + + +Filter windows + +You can configure which windows should be shown in the list initiated by pressing &Alt; (predefined for the settings on the Main tab) or the user defined shortcut for the alternative settings. + +So it is possible to only show windows on the current virtual desktop or windows from all other desktops. Additionally you can apply similar rules for windows in activities or on screens for a multimonitor setup. + +The last option allows you to filter on the minimization status of windows. + + + + +
+ + + diff --git a/doc/kcontrol/mouse/CMakeLists.txt b/doc/kcontrol/mouse/CMakeLists.txt new file mode 100644 index 00000000..36a0d843 --- /dev/null +++ b/doc/kcontrol/mouse/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/mouse) diff --git a/doc/kcontrol/mouse/index.docbook b/doc/kcontrol/mouse/index.docbook new file mode 100644 index 00000000..20f8610f --- /dev/null +++ b/doc/kcontrol/mouse/index.docbook @@ -0,0 +1,472 @@ + + + +]> + +
+ +Mouse + +&Mike.McBride; &Mike.McBride.mail; +&Brad.Hards; &Brad.Hards.mail; + + + +2013-12-05 +&kde; 4.12 + + +This is the documentation for the &kde; &systemsettings; module that configures mice and other pointing devices. + + + + +KDE +Systemsettings +mouse + + + + +Mouse + +This module allows you to configure your pointing device. Your +pointing device may be a mouse, a track ball, a touch-pad, or another piece +of hardware that performs a similar function. + +This module is divided into several tabs: +General, +Advanced and +Mouse Navigation. +There may also be one or more additional tabs if you have a Logitech mouse +or trackball, providing access to special features. + + + +General + + + +Button Order + +If you are left-handed, you may +prefer to swap the functions of the left and +right buttons on your pointing device by choosing the +Left handed option. If your pointing device has more than two +buttons, only those that function as the left and +right buttons are affected. For example, if you have +a three-button mouse, the middle button is +unaffected. + + + + +Reverse scroll direction + +With this check box selected, the scroll wheel (if any) will work in the opposite direction (so that if rolling the top of the scroll wheel towards you previously causes a scroll down, then it will now cause a scroll up). This may be useful to handle a unusual setup of the X server. + + + + + +Double-click to open files and folders (select icons on first click) + + If this option is not checked, icons/files will be opened with a +single click of the left mouse-button. This +default behavior is consistent with what you would expect when you click +links in most web browsers. If checked however, icons/files will be +opened with a double click, while a single click will only select the +icon or file. This is the behavior you may know from other desktops or +operating systems. + +This option can be changed in the configuration dialogs of &dolphin; and &konqueror; +on the Navigation tab as well. + + + + + +Single-click to open files and folders + +This is the default setting for &kde;. Clicking once on an icon +will open it. To select you can drag around the icon(s) or &Ctrl;Right click, +or simply click and hold to drag it. You can also enable automatic selection of icons using the Automatically select icons check box, discussed below. + + + + +Change pointer shape over icons + +When this option is checked, the shape of the mouse pointer +changes whenever it is over an icon. + +This option should be checked in most situations. It gives +more visual feedback and says, in essence, if you click here, something +will happen. + + + + + +Automatically select icons + + +As noted above, if you have Single-click to open files and folders selected, you can select icons by dragging around them, or by using &Ctrl;Right click. If you routinely need to select icons, you may want to enable this check box, which will allow icons to be selected automatically by pausing over the icon. The Delay: slider determines how long is required before the automatic selection takes effect. + + + + + + + + +Advanced + + + + +Pointer acceleration + +This option allows you to change the relationship +between the distance that the mouse pointer moves on the +screen and the relative movement of the physical device +itself (which may be a mouse, track-ball, or some other +pointing device.) + +A high value for the acceleration multiplier will lead to large +movements of the mouse pointer on the screen, even when +you only make a small movement with the physical device. + +A multiplier between 1x and +3x will works well for many systems. With a multiplier +over 3x the mouse pointer may become difficult to +control. + + + + +Pointer threshold + +The threshold is the smallest distance that the mouse pointer must +move on the screen before acceleration has any effect. If the movement +is within the threshold, the mouse pointer moves as if the acceleration +were set to 1x. + +Thus, when you make small movements with the physical device (⪚ +mouse), you still have fine control of the mouse pointer on the screen, +whereas larger movements of the physical device will move the mouse +pointer rapidly to different areas on the screen. + +You can set the threshold by entering a value into the edit box or +by clicking the up/down arrows to the right of the box. + +In general, the higher you set the Pointer +acceleration value, the higher you will want to set the +Pointer threshold value. For example, a +Pointer threshold of 4 pixels may +be appropriate for a Pointer Acceleration of +2x, but 10 pixels might be +better for 3x. + + + + +Double click interval + +This is the maximum amount of time between clicks for &kde; to +register a double click. If you click twice, and the time between those +two clicks is less than this number, &kde; recognizes that as a double +click. If the time between these two clicks is greater than this +number, &kde; recognizes those as two separate +single clicks. + + + + +Drag start time and Drag start +distance + + +If you + +click with the mouse +drag within the time specified in Drag start +time, and +move a distance equal to or greater than the number (of +pixels) specified in Drag start distance + + + +&kde; will drag the selected item. + + + + +Mouse wheel scrolls by + +If you have a wheel mouse, use the spin box to determine how many +lines of text one step of the mouse wheel will +scroll. + + + + + + + + +Mouse Navigation + + +This tab allows you to configure the keyboard number pad keys as a mouse-type device. This may be useful when you are working on a device without another pointing device, or where you have no other use for the number pad. + + + + + +Move pointer with keyboard (using the num pad) + + +To enable keyboard mouse mode, you need to select the check box labeled Move pointer with keyboard (using the num pad). When you do this, the other settings will become enabled, and you can customize the keyboard pointer behavior further, if required. + + +The various keys on the number pad move in the direction you would expect. Note that you can move diagonally as well as up, down, left and right. The 5 key emulates a click to a pointer button, typically &LMB;. You change which button is emulated by using the / key (which makes it &LMB;), * key (which makes it &MMB;) and - (which makes it &RMB;). Using the + emulates a double click to the selected pointer button. You can use the 0 key to emulate holding down the selected pointer button (for easy dragging), and then use the . to emulate releasing the selected pointer button. + + + + + +Acceleration delay + + +This is the time (in milliseconds) between the initial key press and the first repeated motion event for mouse key acceleration. + + + + + +Repeat interval + + +This is the time in milliseconds between repeated motion events for mouse key acceleration. + + + + + +Acceleration time + + +This is the time in milliseconds before the pointer reaches a maximum speed for mouse key acceleration. + + + + + +Maximum speed + + +This is the maximum speed in pixels per second the pointer can reach for mouse key acceleration. + + + + + +Acceleration profile + + +This is the slope of the acceleration curve for mouse key acceleration. + + + + + + + + + +Logitech Support + + +Some Logitech USB mice support special features, such as switching to a higher resolution, or +providing cordless status. If &kde; was built with libusb support, then you will get an additional +tab for each supported mouse that is plugged in. + + + +The supported devices are: + + +Wheel Mouse Optical +MouseMan Traveler +MouseMan Dual Optical +MX310 Optical Mouse +MX510 Optical Mouse +MX300 Optical Mouse +MX500 Optical Mouse +iFeel Mouse +Mouse Receiver +Dual Receiver +Cordless Freedom Optical +Cordless Elite Duo +MX700 Optical Mouse +Cordless Optical Trackman +Cordless MX Duo Receiver +MX100 Laser Mouse +Receiver for Cordless Presenter + + + +Not all devices support all capabilities (typically cordless devices do not +provide resolution switching, and of course only cordless devices support +cordless status reporting), so some parts of the tab will not be enabled for +some mouse types. + + + +If the mouse supports resolution switching, the Sensor Resolution +radio button group will be enabled, and you can switch from 400 counts per +inch to 800 counts per inch and back. If you use +800 counts per inch, the same physical movement of the mouse +will cause a greater (roughly double) amount of motion of the cursor. This tends +to be popular amongst gamers. + + + +If the mouse supports cordless reporting, the Battery Level +and RF Channel widgets will be enabled. You can only change +the RF Channel if your mouse has two channel support. + + + + + + +
diff --git a/doc/kcontrol/paths/CMakeLists.txt b/doc/kcontrol/paths/CMakeLists.txt new file mode 100644 index 00000000..a521e4f5 --- /dev/null +++ b/doc/kcontrol/paths/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/paths) diff --git a/doc/kcontrol/paths/index.docbook b/doc/kcontrol/paths/index.docbook new file mode 100644 index 00000000..b4da78ce --- /dev/null +++ b/doc/kcontrol/paths/index.docbook @@ -0,0 +1,91 @@ + + + +]> + +
+Paths + + + + +Michael +Anderson + +
nosrednaekim@gmail.com
+
+
+Anne-Marie +Mahfouf + +
annma@kde.org
+
+ +
+ +2009-11-17 +&kde; 4.4 + + +KDE +KControl +desktop +paths + +
+ +This is a module to configure essential paths for the &kde; desktop. + + + +Configure some &kde; paths + + + + + + Configure some &kde; paths + + + + + + + +Desktop path: +The Desktop folder contains all the files which you see on your desktop. The default path is usually ~/Desktop but you can change here the location of this folder. + + + +Autostart path: + +The Autostart folder contains applications or links to applications or scripts you want to start whenever &kde; starts. You can change the location of this folder if you want to. + + + +Documents path: +This folder will be used by default to load or save documents from or to. + + +Download path: +This folder will be used by default to save your downloaded items. + + +Movies path: +This folder will be used by default to load or save movies from or to. + + +Pictures path: +This folder will be used by default to load or save pictures from or to. + + +Music path: +This folder will be used by default to load or save music from or to. + + +If you change a path and click Apply a dialog appears where you can choose to move the content to the +new folder or use the new folder without moving the files. + +
diff --git a/doc/kcontrol/paths/paths.png b/doc/kcontrol/paths/paths.png new file mode 100644 index 0000000000000000000000000000000000000000..eff8756d5c691363570166e2ec611d24f4dafa82 GIT binary patch literal 11152 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
2O>&r* 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/powerdevil/energy.png b/doc/kcontrol/powerdevil/energy.png new file mode 100644 index 0000000000000000000000000000000000000000..1998a57f36ee4964459dd1b5f924a353cb7d09f6 GIT binary patch literal 68729 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/powerdevil/index.docbook b/doc/kcontrol/powerdevil/index.docbook new file mode 100644 index 00000000..6ab5f009 --- /dev/null +++ b/doc/kcontrol/powerdevil/index.docbook @@ -0,0 +1,317 @@ + + + +]> +
+ +Power Management + +&Dario.Freddi;&Dario.Freddi.mail; + + + +2013-08-18 +&kde; 4.11 + + +KDE +System Settings +powerdevil +power management +laptop power + + + + +PowerDevil, a Power Management Daemon + +This module is a configuration tool for managing Power Management in &kde;. It is a configurator for the PowerDevil daemon, that you can start or stop from the Service Manager module. + +Through this module, you can define your computer's behavior in various situations, allowing you to save as much energy as possible. + + +Powerdevil works with Solid only and it's integrated in your desktop. You won't even notice it is running, apart from notifications. Moreover, Powerdevil checks your system capabilities first, so you'll see only options available for your system in this module. + + +Note that PowerDevil does not poll your system. This means that it will not waste energy while trying to save it, as some other power managers do. + +Energy Saving Settings + +This page shows the actual energy saving settings. If a battery is detected you have three tabs with different settings for On AC Power, On Battery and On Low Battery profiles. + + + +Energy Saving Settings + + + + + + Energy Saving Settings + + + Energy Saving Settings + + + + + +There are a lot of options you can configure for each profile: + + + +Screen Brightness + +Sets the screen's brightness using a slider. + + + +Dim Screen + +If checked, the display will be progressively dimmed, until reaching +brightness 0, in the amount of time you specify in the spin box. + + + + +Screen Energy Saving + +Here you can define power saving for your monitor. +The check box defines if DPMS support should be enabled or disabled. +If you choose to activate it, set the timeouts in the spin boxes below. + + + + +Suspend Session + +Suspends the session after the selected time to the status +Sleep, Hibernate, +Shutdown or Lock screen. + + + +Button events handling + +Select actions to perform whenever the laptop lid is closed or a button is pressed. + + +Run Script + +Activate this option to run a custom script when a profile is loaded, unloaded +or after a given amount of time. + + + + + + + + +Activity Settings +Here you can configure the Power Management settings per activity. The settings for each activity can be configured on its own tab. + + +Activity Settings + + + + + + Activity Settings + + + Activity Settings + + + + + + +Don't use special settings + + +Use the settings defined on Energy Saving page. + + + + +Act like + + +Here you can choose a predefined profile from the drop-down box: PC running on AC power, PC running on battery power or PC running on low battery. + + + + +Define a special behavior + + +If this option is chosen, a special behavior for activity can be chosen. If this is a presentation activity, you can check the Never shutdown the screen and Never suspend or shutdown the computer boxes. It is also possible to define the time interval for the computer to switch to a suspension mode for the power saving activities. + + + + +Use separate settings (advanced users only) + + +This option allows users to choose the detail power saving settings for a separate activity. The settings are similar to the settings from the Energy Saving page. + + + + + + + +Advanced Settings + + +Advanced Settings + + + + + + Advanced Settings + + + Advanced Settings + + + + + +Battery levels + +These items are only displayed if a battery is detected. + + +Battery is at low level at + + +Here you can set the percentage after which the battery will be considered low. + + + +Battery is at critical level at + + +Here you can set the percentage after which the battery will be considered at critical level. + + + +When battery is at critical level + + +Defines the action that will be done when battery reaches the critical level. + + + + + + +Events + + +Lock screen on resume + + +When this box is checked, every time the PC gets suspended, the screen will be locked when resuming. You will be asked for a password when resuming from sleep state. + + +Never prevent an action on lid close + + +When this option is selected, applications will not be allowed to inhibit sleep when the lid is closed. + + + +Configure Notifications + + +If you want a deeper control over your notifications, you can refine them by clicking this button. + + + + + + + + + + + + +PowerDevil Runner + +PowerDevil can be manually controlled through &krunner; (&Alt;F2). This makes changing profile, brightness, governor and more much easier and faster. The runner has various keywords you can enter to access its functions + + +Runner Keywords + +Here comes a list of keywords you can enter in &krunner; to perform PowerDevil related actions. + + +Power Profile + + +You can manually choose a profile using this keyword. All available profiles will be shown in form of &krunner; matches. + + + + +Screen Brightness + + +You can control screen brightness through this keyword. In this form, some &krunner; matches that let you do some common actions will be shown. If you enter a value after the keyword (⪚: Screen Brightness 50), the brightness will be set to that value. + + + +Suspend + + +You can suspend your pc through this keyword. Available suspend methods will be shown as &krunner; matches. + + + + + + +
+ + + diff --git a/doc/kcontrol/screensaver/CMakeLists.txt b/doc/kcontrol/screensaver/CMakeLists.txt new file mode 100644 index 00000000..57ded656 --- /dev/null +++ b/doc/kcontrol/screensaver/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/screensaver) diff --git a/doc/kcontrol/screensaver/index.docbook b/doc/kcontrol/screensaver/index.docbook new file mode 100644 index 00000000..02395bf1 --- /dev/null +++ b/doc/kcontrol/screensaver/index.docbook @@ -0,0 +1,110 @@ + + + +]> + +
+ +Screen Locker + +&Mike.McBride; &Mike.McBride.mail; + + + +2013-12-05 +&kde; 4.12 + + +KDE +systemsettings +screensaver +screen saver + + + + + +Screen Locker + +Using this module, you can choose your screen saver, determine +how much time must pass before the screen saver is activated, and add +or remove password protection to your screen saver. + + +Setting the time, priority and passwords for screen +savers. + +At the top is a check box to have the screen saver Start automatically after, +and a spin box which determines the period of inactivity before the screen saver should be started. +You can enter any positive number of minutes in this box. + +Below that is a check box labeled Require password +after. If it is checked, when you click a key +or click a mouse button to end the screen saver after the time in the spinbox and return to your +work, you must enter a password. The password used is the same +password you used to login to your machine. If there is no mark in +the check box, no password is required to return to your +desktop. + +Locking the desktop manually causes the password protection to engage immediately. + + + + +Choosing the screen saver, and configuring its options + +Use the Simple locker option for a basic unlock dialog that prompts for a password. + +If you would like to have some interactive widgets like notes or a player +on the locked screen saver, select Desktop Widgets +and click the Configure... button to select your +favorite widgets. + + +To enable the selection of all available screen savers select the Screen +saver option. You can select a screen saver by simply clicking on its name. +Once you have selected a screen saver, you will see a small preview on the +monitor on the right. + +The preview monitor will often show the screen saver +larger than it is when the screen saver is activated. This is done on +purpose, since many of the details of the screen savers would be +unintelligible if actually scaled down to such a small +size. + +Each screen saver has a different set of setup options. By +clicking on Setup..., a dialog box will appear with +all available options. As you adjust the options, the preview box in +the dialog box will show you what effect you will achieve with the +current settings. + +When you are done setting up your screen saver, click +OK. Clicking Cancel +will erase any changes you made in this dialog box, and return you to the +screen saver module. + +For most screen savers a description, Copyright and Author information +is shown directly in the dialog, for others you need to click the +About button to read this information. + +When you think you have all the options set the way you want, +simply click on Test to immediately start the +screen saver exactly as it will appear. + + + + +Using a non-&kde; screen saver + +&kde; does not prevent another screen saver from working. To use a +different screen saver, such as xscreensaver, simply +disable the &kde; Screen Saver, and set up your other screen saver program +normally. + + + + + +
diff --git a/doc/kcontrol/solid-actions/CMakeLists.txt b/doc/kcontrol/solid-actions/CMakeLists.txt new file mode 100644 index 00000000..05eb12aa --- /dev/null +++ b/doc/kcontrol/solid-actions/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/solid-actions) diff --git a/doc/kcontrol/solid-actions/add-action.png b/doc/kcontrol/solid-actions/add-action.png new file mode 100644 index 0000000000000000000000000000000000000000..67b4ea98b0511585db4740a35d190866ba3bfa5a GIT binary patch literal 13822 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 Z*@~#gjUGm10TBNV1sPT8dP&pZ{|}-j+u;BJ literal 0 HcmV?d00001 diff --git a/doc/kcontrol/solid-actions/edit-action.png b/doc/kcontrol/solid-actions/edit-action.png new file mode 100644 index 0000000000000000000000000000000000000000..aa2731b2c77aaaf69e23f6b0667fc7499f12fc06 GIT binary patch literal 49373 zcmV){Kz+Z7P)0b^sv2_M@eW59qh z7#rIplO%*d5>XNgBn1#Cx4K(W=b(;KjyQ;eO-oN_3 zUAzBH{qOb7Rd{CY(es?=Jm)#jdCqg5^JK`>U#jqLiT-`GvlfdES+U`C0Gk>@$Y~0w z2>$catR(kWCp0{?=(8g!;o+w>F?k}9;lY%MsDhotL7STHq~xD%%#5Cl+4U=tpA~2S zyzMk3s>F2m$9h|EOU(Er zzZM$d`mx4|ljcsC%oem;+H^2;I;>gHZb4^8SYvc3v87CVj7}wXLpqe$v^W%W#;_}K zirADmw758S38xmf)1k$s#>w%>ajS80ymCBh+zNbgym34l{BeA7yc)U~euht%0HcfH zPe?G(m6T90keE=A6HZ77k#Hiyh(uyUHAG@WV{|KsN_0!~h;&QzNc3`gl=Ld;>+Mz2 zC#MhnYWn5$a|YxL#2FA7lrtD-P{A2FXBcO6`A3|8F#d6tkUsZJVidoQOy?P9#oPK_pI?5z-|bVgz*w z2_&hThV`22eiCABM^{2(ZI53UPYiDipDykgo)}&YE+uXWkBC!=OTsPUP~y}=eSsE- z92=Z^*wu7$9BOQFIz;SxbgF4jicL*N9BWE+s%ej7Nt+HL8>eZv#A(x|$!x_5@~XAf zPRx;u*O#SMCS3B3heo{GEy=`7IEXg(cle~sSiFp-i_l6JCtc|xGLtSM6X_z-l`cYG zy0RCqE<^FkRJsUb=?W*7uHT$^5o+-wwBn_eudD@3k}!>oanh42j<&orNf|T}Eo0f@ zsLq`vTfaHsBJ_nT73m5ZNLMz(MPx5rguZa4CtdDLrOT0-bU8ASu1*1c;i5i|^`X2k zbYvx5TIr%bT<`(wuP$9$m(bFYnRM}Tt!5L^CJL7kwWdxiEH%fZi{%_Q)CY7UT+K}l zDM?ptbrs6W4xzQBDP8H}<+e08;#A!UG&MHBLgmw6zD(=+>ymVxd(kdOR?)7^q>IQz zx(JPQr5)|^oqN%)^WvpMBVNYxm1X41Sim@E^hN9}quq}|W6{b!vSln=ghsZ`3)eXt z48Ycux;W8u=5u2ftiW9cHv;yzS&vKEaE^{|-R_}{t{wPBu>FE-d~OG7}j(edNQ5C{ZNR$i7=y0&iFjAnKcPoG9X!EQ9x zpGrB!Xg0N=y6QN;(9Tff_7Bz|67-iZ(}hH@A7k5{k9HYISGMBiJuhBEC|>8Zd>N-5 zjRlM|n6`*XoJoZ<2^chHkdeM%aRv-T%OH(-Zp+qr;TmG$A`FD&5-RD^~hB0yerj<#?9SBQ3HKeo&C3&#HbcewEPf5JACdO1m&v28P+ z7Pi~omUfzP_{FPpJD%bD{}l2%hd{iDNDA^5%_{0OWb$P!VBTGrz|Y^)DD)o3 zU7{)FC|7H9BfY0QrLrq4%9sNsl&)RPewlPN`E@rsR9cM5uTF-=VqxJ%jdbPj%tLv3 zIedN}j*$traoapbp~I8O4upTXWrs@O^LW_KCaX}qvU|NAl+nIW4s{r!UBj4WY}q6T zlbR>7wKaiwnYLrR(0T4?qvbaFGF5PrFx>{gENz!(W{t(rikHu{8P8rM9M44)NC-Wt ziC0HluEt~8jEDqopK zz6dT~*$J2^UC)qoC6q9gbR~+0sbtJAyhj6-;UA#aNwQ?igX-mhw2{gnuAWi^Prpp0 z`rOzv<#O3R^lRkGSg?#GD|^wB=t(=Wm6>b>P5Jm@(jB-m{vC}Ng_|FK52Y?0*~(0@6n(PQV#drF({bJCtMTqTGgwMZ(I=Oel~R9hF%mA`=U0@Mrq|yeDrUZ6 z6y@ShP@bkskk>E=F%&L}xUu~Z%ck#0w_I8;mR(wMfC;9)bTt`D7l)hP%dfml;>Gj2 z3h`RG@*DiTejV2QuokB%N4s(32CP`IjPjf{Ne_l1XM7x3psR~rbcWD&JbXvx{%fTf zTek|8bsY8v}}cxfaCF_PuMQV@79J=yj*DAG!B=D zo$mbRZetpVo`0E?5^Ycv0{5$#ktoQKzvy)_HAEEPDm7R1EJjyj=`V6$1OlWGXXTrq? z!|mO>2UDg^#gZk9afqyU)#_FF=)(^T?9qe+`}d%e#K&pxNJ*5OwoX2n@8E&G%xs4< z&3JajOO&psk=v@DYIK^*uxiS^xJn&G;L@c^FP;?sFCj&|+T;;17rbIfT*;+3J&jNE z8{rZfAWz2;d_V0zozEYG97_W6a@S-1*gx>?Zg^-k|9jEcpU~uyr5n9%C|@-l<8Hqk zBUpKt-;dW9e2PajpTi?wx)HFTw;2UW1lths(bL4x%p`I3i2i1bt@Tl^EiB7 zXhxS_hZ1bZu9q*R?JmT`Eggt%W@A2ybbbnL)5P5Gnn(3?Nt zq$ebGenBgWmrTLq*Nx!YjJWb%ys~f)+Ji#p>B_@6z5TppJm&4|KtxBt{1r2C1KaN2 zrDzOOSiEx!CXQft_T!Lai=sDDkLCBWa<0LwN)mHVzId$_n1%ljed21Dpx_boS+=cN8kKK-LQLZ9rR+aOox4y*@ zS5%a&9)BIy|MdY}ttoFTc6)^HG2DTYrBjvH#g}{05fTK;t#@6F#V%KdW44@ycyS~v z;{mL04DjnZO4n51Kp(mzA^563$6f3*E}4X_=C0TcNcCLY&DP!YA&z;NZ24g+nunL~ zA1&NeU4+~IG!2XM>fr8F)i?EU0Iv!A7fr@v*T#?c9=tSfH%uO0pQSpk-~wEI^BuVL z@(W_im)(!)n@+)_mr88ki5G<9TXo9K+nGQhNZ(sGf<9SWG zGrT`*7G{$LFD3b+Z4C#d@E@_##{I|EPj*=%oP(?;IJ)>sH+CQ%=ruzHue7ZArj!}MO6gMfumpC&G+Rler_Ce zZf@ht_kVr_Zq~@#=sk&!@rL(N>DEa*x(;IcX!f3mv9`5Kk#-EVevil5dq=;GGB-(= zGfyo4j#+zP4cNr*=k^aP;N_j34=28SfUmo5>J~K9u~*KIEkClT76I0Iy7QCl=ihPE zuM+|DmE#?@pCg~eZdU}3ozG&F&@jJ{?;w%e73*L}Pe-MnM8G3OwhFuy_0n7?6aiyG zLE9zXmk)3}D2)^2=tsvSG_UJzAI9m$59*$yN0*#Jq(51iW3X~Ad+&qzrjdlBaTyo) zN9Hca)2e;yi?(9RCv&m2+Kxz17aBLc#HHw}*LK6rj@@f;>;WNa6=|k&zR;F4c{g0$ zEQ;mF@lS5itvCGqGwJFMpl(ru>*A{u2t=cb>*CfKJJ1>$pzmpb-m5EG#slO%rTm)V z`!VtsJU#hcELgQ2!N=-~t5_)GT1?Mt zMIhoqOUY08_@(LCYY(Geb6xcdk!csI7u>IVybmup26vZV7UjMGPp&utTjfW%l`sDu zPb{y6{qP*z!IrO`juM-WblDEbj_+nX_3{kNUGWQwPj|vAwof)3op+zGADfl?G4C)O z-T?Y^+R&h{OLu+1qiS2Zge7ZRXQIT)q|1zw**9sg5qW=LF2vuiR-WtTgFoQI7ypX< z)|97*;6ap~xj6~@-FM+d+)*BcifIUZ@U$CJCAxP%FfxgMR!nrzDBytCL?&EYk&9wHMO;v zGiMGKQs{B>rj7gqJE+i9XsSPj?OT7LlV(P9<7o}^KL2ktHJnnf=egtUTYlkRP^Z;Q zSYos*v89AnNrw`9LfW-->f;dUkg#cSayljKB9e6J-RZR0sL~Z-#x-pDA$-?JmDx!m z)VK4%v7w+4}qrT6UCR)^)M{U(@18C=fufWp(V_TsISCPD#4>F`B6S zU;yFxfcy)_A>XE#9@&NGMhM4eQ$@jSLfT=(pHb)tBI1Zk*MnGN3Zgp_LAX`ehil$J z1&elh%JKK>W5>FLCztVu@uMX|*AAB}eZm|TwMaq`*1TDGe3bfox(d&(tc91v%X4T3uH)D5+c;o3 zg3oV@b^5apdt&v&u?LecW$W(2r&|u-SbYb&!cp}0_aegN%BH+I3dYlg&JxUyAMYtY z)%h-jtQ&>neHUd8s_SAMe+=tQRL8Abg~->V__@_bW#?hy1+n%i&&s0e3b=Tgb&u~# zOj>pn4%R+(9>lEpe$=t3JGE=(4Z?oRL}`aQjp&5eO}L!eHk8(B+E)H>ldNrRrq85p zylrCJ%7w~p-ivpHYh+cUi^_Mw(;&62xg=FCQ$Ai5&h?xP1t_a(hSTdO(T~9A5c&|C z9Q{6srfOjFlBiGS5w1-e)-fs7^vO9}H>0(wLASrO5j3!zNr=2`o=%-KaXg-Q^bs6C zT8VLE$6(BpPmm`XTy^B|t1y4= z=ZdnoZQjIOBwbJ8$MoLJnYd)+2uyu#GVAL#=VU9D-FUiA<4^gGD(NCyHKeBcI3Kt5 zI+<$aVai?Z{|M#l-+)!LIYaoA5*ye5#4WYHt`?_H)+nILp(oZYl8ou{J6R-bJ0@MoQwqEi@(7qZIwq5@ToYeb zHULh6wnPK)sR1(!4M^KIRWvLY&t52$9Upuzl|#~{Gu?!v8p|JwrF|xCYvbc3%v;9C z!s8Epjgw9feAYY?8{xRD9#x7US1f;LyKL;2TE;r^BsrqxSb8E?l%n082?pP5*AX)5 za+P4lXhG(hyozyPfu_}Xj7Perqs&bb=E##e7`reI#<3%|4;M~Ep_8Q`;}WOCA10u{ z$)bEa#eLfC5+WB)**drWzcufA=I$bxzyw ziABbg(xqMQVW`%-1<7#Bx7CgzUdR-DA&2kZ*Pk4?dqKHeA9CaBX)Xlp? ze9ztU>kw8;Wp4!b;;%66(Hn7vynI2ZXd9)7x`i=UZuNNz!*(!nIlJ9adQSnK6Y9-Q zmyjxS=3%_-`|NfV;Q6H21($K@vt45JN*lp)kQnNu^>#Y6Paa0QDazUFLvv*weq1me zhbk`vHCma?^AHIbiE68#f94C6LG!lvqoI^1ZHn(fVWF8A}!FF zm$V+_ckntco+GOJye*iZzf97lKSrx7)Qx`Kh8ywL7x<%*+jLtO$I z>5^|JWGzhFl9ItCSAX5T%V{< zCgEDo+g_3!RiE69Ur5GCtP=K@&GZ@xo4joLyauW#J$QEF1d2#qhNu4YM?@kK*2gRQ zdwL(2F6l|bIA#vH0CNI)**wZsUB#!RV9Pwh*U->_#a}Lv%5G`m4ni)HmZzLLQBA4E z*LZ}B=ICOnMvBfokGk3_McEtH{e%XRF10`HYD!bOjvYCSbu?)H{s-=*RN`!GUV1ZN#CQF#rdE7hkST{?sCJBl%jfBu75dBVmAjXG;+ zkg`U)B=K@qEy4rrbzSbol4=Kh_CxsaMz(w>79O+9pL|qHmo)7}yGptorP99Dxwx45 zPA!j}o9o|4g;U!B@J_>K^c18GMUzMIPG|i3W^{>BFdtgiKOGy>HMtOukX*VRz_$%P z-l+u|zKQL_weRvsSJ+#Lk8Tw1daeB=B1$RgVV$R3x_IZRFJhdi3}+F)6TXzj9bEeR z%kaiQ54;Db;wnlp-gU=FTzKhA*c0#c6_ORzN>?{SPsTLsw1fJ!Q8Nkc>)PeOQGA^6 z9G!`Y8Utj@E%H9&TbaP z@>Sw};o4l?9N>~1YFL4X;SNeSC=oW!F6u;cRWWkEdJdy`WNbQ09eUCw+%!4M z@nOQ_?MKM3zTr|Wvzs%kY=FBp*&JKcUUUWN7<&*EkMB9`wz}Z89ZIqveR}CaX+XSI zy0mSp$)OaiMABuUh?~&1uc(Q&?VZP$;30){+2IRPR8@VhN56%=rqqOs;Qf2vj_uSZ zm+JP(KdkuI!)QR^gfyq zK_Oh)6yR1x+0@stfQ4dTsjp|(n8GEdyH(#TNAZFE>3$L8D`iyqA0 ziF#8tw*K`7T2@Ux;fX`r&$}}=`1pka_|6E8*%>biU$}^`zh~YNIDIahqU(tX%;n=2 zVSfXipVo4$|6~sKHx^>5u>VVs+tm>;NxHgRv~Rb?&duz6Gt5XN+U zaui

G{#H;&F^*4;4)L5mlXD_?*o+mbV=5J^wcLI{DZzsdII*PE}vTBq9QK?0#;f z@M!!*?6lK5`wmPRAq?DoZWo;K$e0wd;nA3G?|$(-FR$}UPf)7mtUHmQ8Hkz;<0xAQ zjq!6dbsbJP0|^Clx3&a^Qx~B8G?+~V6#g=czNBi30bJZj7{k!Dj zthC22$*Lq&Bwc@#m*YH*9jqLA6f5dS^{26VbI(V6VRkkmZ#s?5R7i9X4dOBXgc_R< zeivOAJ68zTMHmrzw9~0GorB?%h7uu$qX2J@pNfU+_Mz6q>Xr?4Ti(J=^cfeA-vCor zAQtuYR0yd+f<;UB*%6A@4_hH-O`d}dC8uHcdC*zAJ!S8B?xt2xep zC4!ViVJ>3mDc?z+LMh3OaM z;+~>?V%guWSWW}*_c9^OT)N5*mEy}qU*eWqZ^DEL6Y%B2h2m?KWTWLv{tE*gBN46{ ziK0(0ruD5x;>91u{Q0M~SpV~nI8k#9WySjvL9ZXjI@)#}ZL6A!!dSfisiR&*OX4wI zTUwZS*-2{Zu`byK?J0fq*l75b^5d3haw1@3$b|W z|h{U5}Ou7_e;6)8T&+@0@ zqFOoAh=+EX3$3ikNkO{0S;WjMoFjfc5SQWZr|BH+F`=v5Q1qnr3HK=i`@S#m=UYao z>zj039@Vi&3C(#6!=_h`Dk|9>Y|_>ndDJSxo{06Rj(HRvvv6Igu7O=nQLyBamEIg$ z?j!i>FOT4^(HG;Q`2JjcJ)W4h4CM}bU;O$HcAu7(v}+-zJ$5}V z6`mfw;i1V`UT&lJGQo0a>u)<-@2CB7YwE#WW8cE^!X~(V+Q^pAK)N&&nRb@r%NHNU zoqET|q?S+d;D$e-vmZ~rg=GbeaPm}Qhja|`iKz9~w;D)StDbb(`1mHTN55^AZo;i- z*f}3l9=#5iD9$wrpWR5f+U4-MHP=%*ZT-5RG<`Dlt@L-lqEB8=eKKv!ri0KIu67BU zdV=-!w0*k$eXUBkw2%|9ZPRjzp9yjhLr*y&c*;7VY+A?0n=8t!XUE^!E-U*7Hf4ma zOYLg*8A=z~Z!wMG+K5{yq;~)P_v5QYi5OWAMh0aA4F^aFN!|?f3&_S zY1GRsOggq=*;4$tW;Ko-E=NV_0hI15!ofYeQ9^%dnXmtT^-8{7d09!KM?8lx-8jr+ zy+}TK#n85TOqUS(a<~xej^D-WjQetW(JL%>@p)Yw@P~RasGjr7<&);~;$so~s%7n* zUv56Ty%(XLe)01Moxj8eosN11g;tmH_Z>YxLxZF$2ZsoF9XV!SH zAJIOso{9CgzbA}g`MAHV-D zd7u22JDwzG%IEJ`{p~kcK#z28*|ZTQ6wcdQu$%wgOd-2@UwqDA zr|_iSoMz~&3M96Ek^Y-lb`0{c+>t7YUAHUbZ0k-sf0sA@`+4a^YOuqr6{VUzOVHt zw$6&Tt-E3BOm(2Vv2byO=^YN06q7)Fi-mJ($`e(eyoLH?dJ2#U25omx9LuFITZHO& zmP?Bd;=5HVv4G0Z?eA&*ca(-KIe0Lw{+_mFjv%;1g0jgm=ymQK0wdBC9V4SQS8ji;qvv>!ued{=r5P8yd61wCVF!Q{XIDXcLj2W z1TL|iy9PN&iozv9lExn-q=yEWTq(+?Wxk$X=iAZtsY%zaX8rWyS2ULElaD_ZPqGnZ z#d}auTqIv-BwwOUQXZ7gNK3!T$p6x^V2#4h4p}+b$d@EuzXACo4CL!>20ub=hqo)DXj^;3 zK6vaMzq)KmSjET`{R|J62}&cfzkJy&JWXgUTlxr*DLxkK$dO7)4Ibh@gnhEMMvOqE z)3>+Bv6z`F7`TMVShn=x!bnqN@Sg=bTv5hRYtIPt zzm|L%kNFz<)T43qON&d5lNcfa8-58h7BS<9SQ-Qjgv?ONIN^*5DGBQn`Hc`xL`Y3A zBSINSl_XX}B3H(#!eNuF;TJ9As8)8eHCDFWF8Os)tkyBVD zhT4C$(v{!j1{>3H^llVH+7b$&oWhyBOkupXrQu;VWJT4;~ z5{YF>+kQDDTncPj>;jTV>0?unsJ&LU>B(-)JJeV?wq&%cu_UBZ533rpAsuQgaoWtK)%utFo%F7UuR3e2x9@`7z-FDGXcw9 z!U$2qvK29785;^AOEG#DG9nnrif~#4&k})@31x@j`3+_xRmNhKgh_T&W7zdFdL0)FY9dd}W`0JTG9z0+zLe4Y7y~zl;%y$B$($W?DJR zSk$s7be0MJx@2??16c_bVKBaG802bb1uJ{WIxkvhD~)(Qm8ge$$_O7DeShv?HgT*O z(I%4pfPEtKX)1=~r-?Y}4%W~93CRqfl+1R(K4COq-+0izgjjC_n#4<*B5@R4_ z1}LN~d$^#TJ7h0+=i2f7THlktIAuSOT_TBGc^O#_Y?p8;}3UKUt{8 zrbh-(7-lfoy;F~N1(^?Um&jz0d-em}&2mg>V-Yx4ye3~EUH_lGyW4Hlio!5_|Mya< zt?H=i4OEqS(snZOF9wXUJ;|J;%6}A5gsN`2JFsA0wim?f;JtuBqtTnFG7kqJmby>z|UrO#Az(OHR4`MRL*q4 zDFQ1TvfNjN?8`!V5k3gCl5WuQv8C}vVVMUliY-GI!k6Cl3j!?G2AI|rj3bO+!(@oH zo3r2;;}rJaGpg5xB;ZT0D;BimU7yubS8HAa`8MvNd!1)aYMgU6qD&;T*Km||* zVI|{AzF-N!0#_^rWGP&;6reS*tCox{{U$BYW!JAW0hm6*IK=p?Ns2K5G67`(X9Ca| z*jzVf*0qbm$%mATDTFEjD~2onijV_K30VfM6I`_nT_523#Q~=CpYW9tHe`qi7^5JA z7cv=U6lX5^i%bqSjy&F1mA(jg5)dVJ0HBgDRvcC$u7(XPbz}wn&+r^tcGWt2be$o< z_!UeUVfql`7?VN9P*!yi5+*PJ(g56K$jOBQkleKw024rzFtKpmsy#rJ1S^ayePHP$ zi(j)0TH{35WLlzYwfIm~e^7-9jtDpU=J(EE|!DJhcd}U1G)@g4FF4e0~lJ-9~r_p#9Si80$@x8 z8A6$B2XKaw#_=XMHWXnjaYS)UxpIUm8CHRC)plT%18YRc0)wMHLn|?88M+h!#;;%l zMHq*ed=cXq3kNd!LMD|r=3qu}#-Zl7w-}l*pyYBP4^tATz{Lu}Dm<>-1&aYoA6fjG zWzaHoDF96UHKfY{ECj;zA;zy_!7wI(44@3a3|-D-r~$mG27m(sSOS0omni@$fGPo2 z0dR$`SNgyTjjY&1mi}u)4z2N{>!)LM8Ne986c8rH5ym0LuVPhcc#z2#GFJ{@Cg2Pq z&4-$6Puf`wOMbiK4h&I#IR=&A7F?_ltm;a@^$G#2XJkdgL6$+Q*Cx{&Ll=4tIevuc zLX2OlGqieldSoMXOwZKKL*afC8T!~lTzdz|B`(tJD^hNr9Sxx=~Mt$3ce4I6xcdbGi zYu8tKV~3Hn7u)tzjuQS}i1P{ZR+Us%n>Vdc+omRIY9Xzy{lr3;-yQUedl(aS3B#i5 za|~zigxU;UsBqh2Jb*9&F-45=LD;mutRWd?t}VhDM;b>PZ#R;15I_?~6vvb+6B0lr zqbj9Cp$fQSz~abS^^GipmL|F;Geeg;!dw9m77}8iF@`|~QO05B+5n&ds6n*p<8Ig( z;%Fj(;*fHs0YD|7ioi+%S7Ct_2wBn6kTrlVW&zQ)TFi?1^mB3f*B@uu=TCn&wwPTN z(Q@7eVJZ;Q#~240M;V8i!x=;x$C{5efHw`?>0=0D$ww2%6GxP513*Pl#bKp|D}7)Y zvPOWeFs~OYY%S)q;_mM6;`Q~_@++UsU9nuuD}43xTJr2MCV-5ftSW&QGaqLhX|7zr z8iN~e*H0~B!^=aJeQT))D2gb*1Yf9JF+df7)$nm;z&hh5$LP8#*2_6=QG)C0@>B8l z_Ex++KNrtWkCtEcY|3X;J*(yHD$MK!YUNtj#|L4B_-el^>0Z{V*e~tg_Nb(NoBql- zX_&H+wF!_18(7*p>8m}t#0z}ACltfA_15vB(4?uzHRQR4^>S{VsLAo`#eUHB`)|J% zx3{;&bBT(lr$?)ymzU@2S(VT1zvrj0Kc=`OJMSV zA&O&4E)I$+4l9l;1D16%bX6CdUw*!*UY|WZK3Xk$eR-*#S^4a|=NTAcIv7Jm3}qTH z4GJR(U1d zxZ>9<1J)TgnFd7HTCSFdaB)aY`Ie;$Q;D1D%qfCYwF9JwoSmUkRmskKt97`NeyfuIn02M+N zhn3;V>Kk2dG9p^eQL_>bKm3cXhlhJhuKLQed}h_NbI($>)9sc-%cJ5Tt&Us!B_}QN zi@&|}L$y9p(T6D^t>0^Pvf}rO{@=3q*2kUf-@9lzx6ZtaX-IV4-&WNhhaB$P42Q#g9nL=F3>Q)2ro~bU*P-Edb=`ZNIos8Qn6C@gLK_jwr0E1r9x&w z%(6?$f~4&xCbuT7WLJ(Xh|=zrDC;6+U8q#76qT;u{N}#06;CEzDrMHi%(|TIyr>y6 z`;N({Oln_|wj@wH&(!8ZrBbCl$I=xM=}N>b5etWKJ4L!a5$U>rPuT`Wx}0`%c5;UM znWy}v#>5|z+MM(=CHdJ*ZcRqn)1Tx8V8B?D{ax>yji+%s^tn%!ri!Q2ksdTBB z?G;J0PICK9T3~<4k99HHz9^|gsZc4;iF8R}IjhojUxZ>On23b1IV!Q)1!om@!QraL zE;!vbxwhl1amcm(_qf~+TvF$7*#v3ts5X6U4%6RY6QumRaRr$}%7$Dnt| zW?j;@mNi3qUy$6TB%XVwwv?wWB}#=#Q9dW$=+X{K*S(Lk&h1+(oI0J$`3oO#q2N51 zu6#sM$z`sV6;WPULPd2M)%J2kl#Emv+%{9LvXxU&RZ7{lVoJ)2q+cP0#g`~7x=7)b z0xkfJQ7cxi5}r?tJ2w$2the64hLwbSW0 z&@Sb+j%J$MnrLdNr@pC{x`rA&Ubo=FUF*Q( zf1sT}&_}SZi{Acj`Ubk`AL%6{K#khu*$!g1vsz$KTyy`nUU9XzdUw zYxUx7tf5BcvAZg%tS;qBaRH&ws7jaedD!>A#Jo;o7o)!puJWWPdsMpaeS9}-+`6^Q z)zTu|9vk&d9@;t@=?Jvo54O`4?4Y~PM^As3$W%}StCykCen!Ry85BMIwY)!!GscUqL=-DWhHOOnmZ0=2^OHpxC zRG1WHAK;BG?SAR{`0gEQy)L|s9wR^<{uYdA_4*0+`;Bb%4F*KEdPJc5j7W`zh6ssV zg(G8xVqDeX#_N`G{dD*E@XK5>r_9}8)=*ntqtd0Q z&?zcLilSJNu0>K(X@%$p>AI5@;;}H^h8pwK$=BURcV8z)v<3q7iX8O~1sNFWF;BOK zMV!o&t;i@7v2h}6vXzJsOGb#NV(TQM#H2nF4;v{9iF}QPM?}1a*2PQ4?HTMcVi)M` z#2;vrH8h*G$eOaXzemz#&Q8uyQ4~c{l;@DTos=$lLS+^6DzC=tqAMt(C4x0F)-Pft zga#!KFgh`0uE!*gM@E>4juMWKi)c-VXoX3nq9i6`B&Xt}(rYA;EM-CJ0(mpKx zLWD)sLNd;Hc$m?(ISd14uECLBf+BnJl+CQ^_U)A{>`|plQ4~c{_MLQjrI3n8EfJj< z$L+9XO}aXKts+6gWM(Frxt?KWF3t4Z6q&h6(zBA+m=mt2G56=EnVp|u?#2w)Z_WyH z%rC5QeG}%)eQ9UfOFz?p`g%r~GV`Q`>9sk3H~y^LpUNZ{6DgCmWly>sHgk4zhKiyn zilRJ+)J1nxx^7!y{`xG8A489Up5CrUNLg6RrW`PN zL!A%|O1%&ac4Kl+K-LhHdxGRPUkeL2uUp-xN|&N2ilXd0>567oy6)b&ZHZJWNvE&f zNKRf}E{Bi2%ezMoap zdh9)pzJHWsIY)Uv=NLJ;?;CRSa?G50$MZOT!oZ1>#|`H%oFg8OF*Y_rCY`ppPn9l3 zQ4~el57b2#cdv9!XVP?Zv=WI-@bshZSqd!aOQ(kAG|KmL(P! zZc^V+M>H1UuMXJxVG+D(hm&nk&<(O=N(Z506l@`Ig~1bp`Xtnj-r>OO2YB${!Q(J( znnHK*O+!Zp+NYp31uaQvibG=zyb-9I0M9tM#^B|*YFS*oX}&wQytH6(pWBzNf!-ix zB}H5j6AL88kd_F2D*c7>E+B8pr zZw5N1p*;<)lhB-m#`coN`UlcqGBuAL$G^oJZfesVL+y|Z;Qbj^Wp79(A4X=s^(#w66oku!ms z32=qLF$%U}_}c4*EG{k3($bWTJ#I_7>{S(v3=i`0-Mg%=t}2S6D2lRkn9tkc;X&+G zm3!kmUGl@Gma#jk#W-WU^y9OF^cm!O8G?%t zxCy>_Fw!**O;b>xg4#ILM8G)#wlSz2hHC>4dHLT@u(Z60x4t$Td)$_EHHhGS`st@U zkMYGX{83iN($LV*(9p<2n9totZ|xqDu9aoWRNKWcQwjd@wOn4iwu*VRSPO4A!r?Z^ z@x!Sgd^i9XN8w5s%HmKp365#-T!-5EbsBC!>jHExLiaNC2m!hFNqzeqM!FiOz-zu2 z2CgvJLr^seG&EGYc1XG+3nXI^OGH9rxE$4dBGM&aGPjJ)QNiS7lJEUT z4zHH|--cI<@3li-7o6#Z{2|O!u97HJB*C76nmHp{kEKp%5b9?o&j=YIE%hmI$G{PW zs&ObEfzm<9_y3k3ym5k+l_flN&aCWFq|2O{oZV-hYkghKA4r$q*U3vS{tbbyF7DsE zM|U8=OMm;Kso%X}UAi_8>(cejmtQvjqZKe&$|_wN8X6k=T)O0;hebD9#~WSPN$Fa$ zOtqtusi_n{d^49HmHaRN?S@}?;hknU+5ve1IMWaL!w*He9&$DEfbzsD_Ni4|(*~TG zRUCpn^IL;lOWpc?_slA`^eW}a2b4q}QatgH(g`RJflYG77?ce|@c^7`{e*x0`AH*P z?iyz{_V~G_>tBBGeVQ5@Hq#im+9O`DcaWi+kD(tzWuF7PrFS1?svYusUUvokH28{CUU#Qd2QVx#^zqwE*N^VKhtEI%9OgrgP5yO1&IckQ`0~rk zgzw+S+iTV^7hxeG6z1p4_1$%K{Bq@r>*^hhjO5CdE0nriEPLc%Stv}qA{u67NF?C< zfBQX-rleT)B>&pAYu_M7ey$b3^rD~sE!eIZF_h7*t5>f|YDNwhl050_Nsou+%O3U9 z2mkffyuSLnzt1A?U&?LXxIx5BLqkJDL!~P?(p8kl`SYVBrzVhWTRfS$8RQk_2>C@{ z;SlDI=gyn5$Npb!+tN~GO_%d{(JdieUwrWefTZ``{ZGurkMFzpI&rz{dw=uwdh#~} zg8lQ~?&?=xVeNbG^7?D9 za$|dqjSbSrzrXA6B;N?8pFa4lCt`Z}^5wa|kKg;h@$agkp`oF1%Su;prx*Wd#3WD( z90iPzj}a4pl=YECY(L^+XS|DDi7s|0x!9B9VqdC@aGQ(BG<>}URGUlGC`yq6#i1>( zr9jaF#oeJ$Cu|fEN^s1XLu1yErm$iCvb!qQo$Wo)E>6e!ZKRctHj%4uVoOIX-f2~ z4FR2L8N-K9?VA`m~@%+=;OK(=-M})B$O##biHUls)(`!Tn&jRy_-jrboSm z$!{>c?=Pn`j$F>pvPGq>6vLIQ+;w!f<~LXQ+nB^I`II?)@LyZfs;P5NPjh8n*hn)m z3PA~9rG7;%w~!TZ5v0JH>(~hvOQ<(hWB@$g?Q|>$$&G#Um=IQsReGA*>R2H!GkCN6 z`sPS1&I zVzM%!PvI?3C+Mrdr++PYBM8U_XMFRG8zx=?66l;cr@sl3DgXFju)U(cq=xnGAZFoN zbK4pTDny{TD$s&(*UZpvkUI2}6TTIT7KT9Mc!EV%P@hF{cHp8zjLnZR&JLWISs&t; zF2AE{%3ca)jEpF$Y5=GrMA>z~BaP$dCOM5KPxFHcq4yrM%zwH1!8Qy(x!F_}{Ahn7 z`MYV)O4@!%sVMv7z1^IUVXYU%E76LeK;D5}|9eq;opm1n5Y1WCnNM$^&l1x&!W{TH zpCuB-eM}|#S*ZOzC2JMA*zqOv7_BZ+;`#7vaXLM;q$PKwytDDsx3_~O4ol9n60nW+ zf?;cv{3++V-lcU9_h&gpE#x?ePh`3o`LDNn)3dIe15;aADTRH{&CH8RN-DNb<~hER z|H7%k!9T44E!*;M`b8*9w}!E53kDB--Qu57qCMSe*xcP4`2iJV)P15M|CUYScWM-K z;CtJ-fPw~yaeeLB8nb|F)T~(yD%rfhX2Q8}?u2dR<_`mOdkqaL%cZ9OiA^T77TIB zoGC$y3f$nnBigC?HxUDkM4TnhO;l#?6c%R*rcn?E`&lyaQ%q z%g@+J+O+gNl%oy0g0j8xWET}IlbxRxG7x5izs{YEOp#t!v%Pg>zM1xB`QVVhHgIZo zl^ow2K*^8Q5eLF*{~@p;(mOMQTBMR~tbI*y<&;W(5LXX?vc!szT=9(9d1bC(qCKpU z_-`aBMbaRDl-ng(po1xuX!x9yS6!5Au28m__8ug6r>GHM3$9 z-6aikhUb&=knFA0RP(FI@rI)A@WxT8qDH_!FTn*;K6ajLe|C>>$V|NYSFAc;5w)t`=?lxM*vywrbQ=vn74B>@YW4D6)+En!M0_3&9ODMIc>( z)4+S|{)(Bdp~kT*TIj>3^BdjAZ<%N<#0!`GE`(onX`4yc$^Z1eA#zjZbttUOoL*5w z2rqJ~;GekPM&2U($OBHsmFhQP)zf*B2n4jgCx4HEvMn2oPD)0#W-jFEE`s8djADdV zwSt+hN2l-fMxSezWCa6V2mdClzNZAGhOK0m=Uk#ak<5_|OxuE0BS?G3N^vHcrcs3R zMI>eh8S@i91WDET*!mpb=AgoDF%7;eN)#a)223?)7#|as`ukp~YAa@&01EF+WM8%Z z9g#u)`h+Z-WFyDM{Q47FtA$)4Ddg2}IY@YN`N<*x{Z6|5+mI^iz9CCbedi>%;Sp*M z3K#1nm%Bw#=NxW{P0YRXf@NU0E&pc}&$6}9hvhm?kr_Vq>D5)DK+*qR1Sx;CwlxJ# z@esY=>6e8a!hi3iZ+Eg$WvTcjPyabka$6;=l$37eO&TEM(AMk7dl6fyvS%2rE8FpH z*TFX+pUxy$hZg=apCk@S1E;5Nko3ap;gPULp>UK^XOmX%J|wDYqxgC#$~L8;3K%+` z5PyGL{4dX$0e%V)v{j|wN}r+}7NHEDl%h?OqZ^@B%&+tbP9$Ypzm-n+q7}E>doE zT+$erhuN=rtHZzioo^BHuW2tx04>0Oq^6M+%})39hKo`yy7`+r981&Pf9%0p8IqoJ z3)=2RmpP7gQf~jYsffD2@gla$omoj=z|lwXoi(#WJFsIRUuekCATfu~Mf>!tc;lkbPOd`)zV|3`Q9+`!go@q1b&`!(qkD;G&@q^BMzeF zgF#!m!{5Jyy0dId%q%7Uoz+P=(g%ChPD|v}ltz@mF{z+>JrC&kCmtVgeNvIe3x0?5 zx*eoMc#IAvM|f2bJqy6Y*`ss{`IhQMz!qB#BL4>&QUA>3B47&5WaQg%a7A4r#>A89ep6k= zMU|y2SxD|1|8oG6?n1ysTA`DUb+jWfa6!UJG)bu7srwBp6?Bi69+FW`>B)-g@i4z_1qK;xJ$n1DcX}tgxvip6EsJ%Bg}i$dG0tG5>vLmv3^b?v>Begu zvqOi2{@h(Z#^evF)1igh_FxDB6`%9h6!36&ky}sQ1^4u}%B6k{h!&F8a;QknsP^rU zk@ru`e{(|NgQ?s7a3dyasDb|X=CQ=d8vRP}uSD*ECq#YK7 z`vEdv+Xb>YOwYm)%gkz$5f34Tz+AVx|30izzkK&H$+Sy~hyGPWoy0=wN$B0na9D zE*;s4!%<~>MIDS7{x4;;Uz&Qir)zy zP9Sr@`6+Yytm*)eU*g0f0w(12S>E|cfW0t8nduH9rnY^4X68jO7F1R7xOJxYS!`Iw zo&a%hm?3*EmNYRE5)C+n9SO-EYckOx1n~$7Nh!dH=imQExWMQA`f^_{WJeqo(4-}w zi-m$ZqClPEc7+XRyr@V>SWKUQ|G=7?H2trQlAjS@=s$4q0sjm9U#Ry^z=B!gU<9mE zW(wXf3O72H!*B(bV+rTXS{Fsj`m_}#n;jbrB&64$`%VPFlC!yr|^utFlov9?#mXm@)J7 zeq$vL@}J8 zKc4uJuY)iWy8%>wlB~6tesAI+Qh7iZEQ3o*>%dL@Ocw@5d=;42xyh z=wTlUT>&2olspAH6tr^WP0IUZTooL-Fcug*S$&wgD)D@9i!z7;$*y&q>3c6N#7*SA z9o%tp^zuSQ68{V{H-MeQZMszAR%VV~O&tI?TUUu1p_A>tLh&;mU*fFF92d&0zbfl| zdhp&T_B{9A)%VRErUO4>g=$HM_4+q0gEWtS+g*+cGY@%0Zp>O#JMAXz-1f5#2XW!B zNT~JTs1gKq;i!U&Ug_a(vq>mCXAgQok{Ih;ug4zpg6=&sGr_t)S?&PWb9raA81MPE zw0FB#qGuG_8Aj*MNS)!QUgI|zu6J$YE$_KIj_$L}^-(48!B|UIrlzKJf{rc5VyQ)g zohvGEz<xFR?mbFx|SfcM*SWB-v-hbV@q1(Q z0$wI>tXddkB^ay-6k2uj?HLNWVC#EyV&}=}{7J8z3xk7M3d13;G4S=9yQ!YH3_T{r zz4+L*Rll=(r1g{CPwC4mWRJjCKj8|ISF%es-6 zROSdzArg9hmF%Mt)3grzKghhcO9N1{y*<_YJG-j12GsEOQU6{g1Mdis9oR)Wu-kI} zv$U+WjPf=ng_1%aa^qDG&^b94geaZ2xA;J|xxHO;LI=lw^<>$nMHT*fH{!J~_w8c~ zPKvODWErT!H+#onqYvjVvc&~lTwI0%GlYn#dPyxU680}(4tn}PocZ0^GIs%9-lWDW zzP(kmX^p&!Z_kC;O*c%xf!%ucrV142$*7`UgI!+5ub%of=Ov5ELihm6QMeeZt*Q>5 zi+&F&vNq50yfCL%?0aGZO4yV}8QYm#Eg!jl;=1GLwyz@jCgSOnTSr0I*s9p}R}U=9 z?4Be$+N-EIGa_^Tc=#GnM{)a)7)#H;hBZ;5|XDPv)biG?jle`{+iWk--0W#pFpFz>^7zk}xyAO(*M!xPNd zEFi$P=uLV1O5fcbzi0-Rir>(Ze&Cy)0X6mh*RmW<$$Q&kudhspd0v2_!tk}5?qFP_ z`=)BWDtDn-2;_{X!MIK}I-gjEE_OgXG!)bA@n&ajZ4F6NQ*(1`OX5k7wO*%!Tkl@G zeAe>M=4PON+v6gFeE^M4?38`KN225(J$bs{8k*j>m%vMHhnxX}gM%59A#dW7NvNa4 ziOG(MozT4_#y$WNDUI=ewsMiA_WOQWI{cXV6lSVFAn1@0InpY?&K41I)W0Gu*#K|3 zAh}-0YRy<~6}GK&_FUZkQ#AaAmdb|QS&d@FuDj!XpU1awCk^k`jPb;==HWG*b)j0pKFE^r!X0D-o=#SzwRZ{A+v9#=3-5Kkgd?RNsEJ6u#(sRo^6&-?@vT`|DH(>CV zMX42iPUC!5DBTwqZR2M1ZSIDr!@j*`>{!7jL!O@S-S@NYQMcWaB10=HEIB#3c__4d zVS&_qJZnodN_1nvp69~{!`pLsRdsb|UbHBJj|CO1<|Ee2lV=x=IhAlra4EO0rUR%6 zTR@DM?hg1&d24e+I_Wu_bU|Log-~W^_*k4n(K`Z{2XJ?K*bZM;-c^?s99I*fO6B?> zo>s1uH4fQas=GIS@;R^=E*Zn*-Dv8ISX}1Cjr_TMs%Nn{t3;em&V~Q6Fm$}5x|)FA zhhVymcd2hrM|axvWS6D2Jb23d=fO4Fr**!F6JE5`2wgQmB<6;VAz$a~*;yU6J0^qV znt6KV`s|VI;i|D=E!EgqFRFUk4!YUwozfpjnVc`D-y$sT3y;eMb0Z6jK{LylV%4ge z8e>T*spcaZU|)Fh=*Y19}CpxutExfdp$@I}o1P|}LTFSKG^+KB0X58Rn;}etr z8(cc(GBTmsx{&R6-TOlzS<6WtY3eEah$tRFW{keqv=MVxqqSuteBFI(>#}aEjy97h zy=*_8v~YciyU@z_;|pSIVq#*~2DmXdKwG;cLD@=R3V7!;DaGgvGkX zu~js?7q=`m8j6if&S|h-Dd+YTUaFv>`jr0xl*0bkfaAXcoej(qsR;WqW_uB;h&_DR z-`@wm0o(^Q-$BG1UA#DQs5vBz)eon#Kgf@gSXpI=8F&q!uM^YKHpw?Te&lYD=U}&Y zm9jUa*=g1_NfFJzleHIlRlpNDZ5_t>9FMGLr;w(%NquwRjiN;`p3`phRIzYcVO{j8 z^E(y~^Ot6$DL%u39Bu8|SM>_rGJQ!$h^z&7FA(8ECv9F55e4*9`%**;pJGt?TpQ&V z73GzdzUcQ6d`_IaAg`#nv6ZnzalQwMhStp@M&)bnY46->=3B92=+_^1>~$gIv=t8LS!Sf15^e`^Y~&J3O={5gdsd z)zm>@!nrk793cc)2(;jh7M z&G6EFm6hQ8X)?VIADq8*5jryhI$UsWmWUaa=YS<9F1fAcFEzFbtW%OIpus;fJJi@T zY400}yP^wO8XhF44Zb&%rd`phFa7*wAr2&H4QTvTnu}dfu;c8|3v_0zQT|5rFkp1= zQi$|qV@-eNO!-eI%l+%^hms~JJ|gks-ZT%zpQ^L(1^CF{Dcr^UiYo9XyK%sqbnsj| zcoL{x;y@ktl3FX!K~c#z^s1wa$#K`0gEmFBd+Qm$pw^`%?{;|Co&q|QRyKRCOd;f7 z9s!iVN0orF+pi|4yLWvPb3eUS30WlYD?T8&AIKrAc&+3NEkZ-PnJ1`D+)!P@h4;sw zvh)Bk{b?}#?T_M<(<4nRg7GPvDGe$gkjq3b>^NG*djGh+)Kp4F)Ij{ko~-*WyE5^h zDTHDk1YH&JdvwoA6e>=I|1G3hGT*dvoPS?Wyl6mO7O$k)F3cr~zy}{SXXDR#ZVLNf z*JE_o4^SmLHE?RdVk6j+i#M>pSzl&=MB1ta(PNKeyjc}@KTj!Xrs!Nz;cnnRWlYdhJNVq%`Yr0N*Ej(ncLO<-Td^c zws7jBTQHS=RI+nBhtzYN{JL6m>%|{V3;Au9wt`1aJ391_Dj)e zJ^1LIAf4XMiCB;dnOKs?#lD29Q8(;fWv6)4jP~MiOQkpHMhACC;@KmUlO6Yy4tpf& z1Lp;7PQ$<)I%~R0DJV|REvd@*P26{}&0Dwj(zl*D6#3zy*zU943?RLZ@bcn_NQp73 zkc8M>pYhw0MG1}$75V&{9}2ABM2=KsfBuixL22Sk7=)qA zn}(@6Y_8@Bd7r9MEDwxwq5`ZbQJ?ZQWaAnJD_c0Cn4>v|2Oa+`O>+*8wkuUns!qf= z0Ygth!{Yp`t(87(ZRv5|DjTe}I-mf{9F9j;MdSMh2_6w4B6Ut>p!(ow-VOzL3V2rRwlc(DuGT zVv2ZTfedi-H)7x9@>%y!Y_q$tR_&rBr=I7de3R{ zBB8LKPLLp=ReDoAN1OJqvp$zsS{T7{GE?`>POzC1>WE9t@gb$wNaFncqaW&vr?9a)X45kjYpa4cvO)l>D zU&-e{62~zs&yrZ_`+o_zO-&SHiaYWt zVWB?t%J1f?ck4#<>=Mg=LfK&!j0Q**6YIHp#fE|v-FoQ6pxX4(({GJ$P-L-J1cmFWJYo;G$Jjox49WNOP@7O zEV@f7n2s8h^?Bs!6icVZu)P{!CAtQfC>YBbf3F`iSu-Si*S@ipc^RHm%P~CeS>%1# zvvhvmXxWX<>uYd%SAOl?sox_5a7 zg1b$A$D*w2KvC5gm45}k4X=X1tqNT_GPu(nYq(BO+1M^V9Ij+)H3k2~&h1`3lrzw* zRFY2BX5_VDJ;j~>;iBd%9Eu~3_KL~m{Jn|!6nYA8Dp)o<SGQwo3@u5J|zF))3g$f(}4(%J~ z(B#G=;=Yau*1Uk!E9JYT&}KN?ZgvyJ)`kn(d!_BqE)nx<`0E7P4BuO~pxQU?ig~BT z&V0mT-eiZcnc!j!os~qRN%HwhjtP~R^6=3}E6rK-qP!}j-MvDWSpyZiYqd&&leBkR z6B3NbR7)qNkY8Hr9Xgr$!%Bh#ze)sS>`HL%Tn>J%{YKg)rjWLZ`}!+lvO6MEf!c8K z+b)^6@u8ExayNS48%%1F=&)||{=Xz{fZd)seObu2k$QAA`?>rJi~KyKSRSVR;mD4k z7gD*UNW6y!ufE~>zmV6x*aJ1~7#~nXV!${Mgq2#o1Ug?oBR~~e0x{)PLMrp3W&6Me z$wfp62Zu}!g!@v|cjJZ7xP?51kf}IvPfgRq2ob)`8Wm8#tDxyz@UK^0W1ag|2Krm^ zualKbN0iPc{_7(ByPL>-r!T7hccIm@|-Uxp~ht zM^vsXjPyk)!Dj|ZraNI|QU4;bg1nym$Kr~>tzLOTJO30hemiH%k%i-m?? za)a$kk8Pb!aGYOxX#n`p^qpLkcw^1%`{zo!t!)`pV~tex&H^mqKjmb)T%{zRPo_>6 zr61h2w|O#6tVZ9Wq30cDEw{X1MZeq&Uk&5@z2ki9G~bT1)M|A8-YF$j?JsXODJ3+U zi9QejHIjtH&m<=h1a_vRKz+ z2T(YCx+uXNPAG$o)$3gUPO3w>#9Vp0>*lODG;oyLeebo$>89^|l~^{+Wq4tu7 zErl<7YAn+V1F1T;7dM)gq4Q@YpRM$7i@HRJ%`Q6fblkdeSQtj*Ktr)ul~aF%O_kb$ z6*hRu)V#l+k6E``_?bkM5%zV1nD#NM&ui@(X0gdTP3F4`wPwB;W_V`(%7jQ~> zXnedvQN(#2Lv^8rTH!=N1ojsNN{*?z!FY1EH4gpO-#2@Z$`irQZ>=#nV`JwjX7(h6 z(XO|WJ!ho5C?7Zaqa7Y$lW&&(K(WC}mo#YT&wuIV4U?oBhRZdag0+RPUYwo;%A$2L z?M=Z^!mYz^1Byr%m7PDJ0S;?mc?BaMp8ssn`j;*XEWf_uSn8?We0pY9re6$%eC>0> zd&HT1dx06;yeT`8M!08AAOA}4u~kCT2B3=u&{ChBe$HC=WPY@-lN-{-|EL-kh!5V4 zl=r;B2r>eyp=vL`l+B&}G>KkZ%+6e;c!%8FHecY!p&+mjr1`}^M^m2!VpL`GXJ^$c+Y zK26#?z>VvhnIlwmI9H>MNKwsLa406=-p9r|rIM{(>=AMONB%I(u7)z%q@-qhcye;W z^;Vsv)o0Z7zQ>{RDqi_zdb$U@d3u(~JQZJWLAZcE(!|(Q0Uqn&4Z8Wx(`vy_dp$oj@^pV^9541~CUS82?*PK=16*I@--l6g~P3psB(0ks* zDj!gJv9u|TM5HUGv%}~?S({B+Hdu}5NmOV2!PC_S&fFmORqQOk?6Ka$y?X7W24Z@p z*+Y$Q*9bx3#ACsN<)PloRPaaOP z)tZe&58*cVIcz9ncpI-*H0X)^`e4Y*~f{$Ui)3H+M&cr8h1i}cW!hP;l zsLLHpY#1rK<%yB%z`&a(Rm6_d?23vC`?EenEj>N#i75k%-wG&ZlEBo~mh2$kl({N++YF$?{P!8ss|0pNzK{8P&KCuW25ip|PksPt z0ni-Gu@jRk>B7&lsC~#tK!0GQ`7ot{{yo1yNqoJr(#K7=aaHg94yPK53mx`4D77wq zFsmHWcPY3>0FdC=d9s$;^{~>$aR<#4C3TSLow`pe5Kw1 z<@~+r2q`P@zfGPkqJAg(g@a@&pPWuUTVwf=_}?c8XwMdrK5N6L%5THu|L4PZaI$e9 z^)Fxy1l<2Rc#f1`hWbDID`f=?JN&7WvuZ%}g!4@R8A+UUYHM5eB3pkZfWsk23OZ<) z&nQlgKpE*c?k__MSi+}xgbpS{o*^=BKV1I7*HoUE5FNoF(~rpvZnS_=KsHZkMvS$w z+mC7_BpY_XWNi#+3c1b(PDh^}V=Y-TXodP?EFSbO`X`X|+2T(iLEPvvjwE6wHPZJ_ z@KeV(`DL3(2g3iWHs;`8#JQ$45|Iwh%_VCv2O0i?L4uLM)1IhA$CU)?UVPNNdA0~2 z5Bx?H_mJMkViZ+6)Ft*UBduTvhtj!E8#v@(PU0$K{|-OmS*Wx_p9G~W>yRl4>O$^D z1eS>amLL;GK9OHcAS*qsxL_#0ACiJRhBkQG^J?$F+etXFP`_<(w4fX7oPMY5wsf`a z=%RUN>Fzdzqp|F4lXl@W#@bIj#xr-A(?(iQQ5w?g{ezc!SgL00pCWhp2637crQ9+t zX^4#5|E~mplIQhMC2_6$4_?auPa8c04i{DPOrnhQTt%8ER<%b;KXDp-rI(W$I~a;- zLejv{5TXzmAqFaPXAm&}#~JstbTXm>2C6?MEtq0j_N{F?Oi(^^=Mw=SYCg}RJMAk9 zUQ=t+M!0CsXC}nSO2j{|h&`)-21rLdwJ=8|@@8q^7N~8OjZ;{CT}Gn9kC;p?FYb3G z?xd||%3Z=m$H3Xi)#ZnKhaWU&%r76aog|!JURm$;tC^yVg@Lw}2>{KOM~??oBb8xB zs@{Zoeq-kPl#HFBS1N9V44e1(46y65yA4jIa*>3%@u1KA&#w1Z_|1~hzC-rT-NHc1 zyGwhhGQi9Zk(G5lc`Q3diP@c(2QEQme;X72)7S)=DPcVEGe51?XQJ+Qqme!qDYLjL`vkU;U7h!N57vX`y&WA&uC z+@u|kEbhC$9tLl30!9D7b^lK|!WN0u{)RNfSCX>5(efugiD#gpdZD8D&Leahh z?S)t$MfjH1GH+-AC(+(Z2Q7<$z9?QFfR|*BeTIOY3Tmw@dY>-PIRrMuIeGDttu-?+ z_O^KK?Xl7))FVpXrepIlp7WyPNxoHvJ&d^qG8k@AvoAfb=NBdhp&%aBCNLq*_XG88 z1>>{9o`t=J2?q^3LKlPd=W6QrgiOWTmnrush{Ybz_?oN@hwN4IARa1kR3(QMfq`3hHhqY-b8_q7I7$G+uX~qRAexkULz>Rkw-=CQCswlZ18#!742f5K zSm&<}Nwzg*s+vTHuHp{_(Q2b)_M#JSdK%MAU>f~7RXNpph?}yqKQmF7i)s^eZM1kr zg@fW=x4=qQ_mE_Ok;X@QgSl49?j$aRvirl8nEylu>04<}J1%LUhOHX9gbdtTg{k>@e+9^6_T33v+Gq;qR56#y_-VwsN= z*4SK?Tr0E9Sv`Ee#^EjJ)C$#v@h4c7)FQ~B{)ddQ70RABLO;3wS_Jhe>sJ6<0)Rln zw9H2#3?WRgs8u@ARaYrKwbcNcaEE{87R0IkZ1nRBnF`g`X|fHIGU~6;GvZA8(Ui(5WV$c1Ycig?KcMgF=Bm5pecxA!dL3MIz#CfX4>oaUCKgf{oq;83n&`%px7{1lwngb{VpcdNl#RiESs|ozyd8a*3Ed zVeAv%^!vnhA;qhwBC74xh$FopP*CG zo((wb?Z(meDS;GK1v^r2sS;et-CUyWl#Z6|`H=~2;(gjO>5Znw{XR1ZGsdlv_0&~( zH#twcg|RmxOlnPI`B<<){4v-SibOSk*a=KV=Psrhrx(@P?cFeN=d=nYt_^i^@rZ4- z!niT5%d1Ow5gQ8rEUu^ZN6M%GZ(Q}nH|tum9xvSL-Yxdpv4UFh^7iCoCbi-ovesAX z-&Q!!TB|vJ@R0}9k>mHgSRX=>C>JE@Nh`#kYnEcN#Qn3Jg#RdcuWLne+s=j;#5?`gkj**)OFfdb-VhqFVcZ ze3g74$q)C@s^*DV4qt&hnROu`210;y{og2q=yLrXQDxk58dy6k;4LDQko*(0uD+f- z)cMDpqd_P?azA&NEq70Ho(K_~AY!9h!)3|aAYepoZn#esQ?3g0Dn% zEW(jZ?1w}LX8!@(#h*-!zvNFX<6p^Dl!i9-4j!eS2c@r%+W4MlcbA*M_xF4JZ_bW4 ztSUPT#O|M&DQ8D5o0^_#6JapK!q)p9!DNgG_)Gf^j)|G<1b}#-L-shBBYjefFE`HK z9LNu{At6j9C*>`Ym2np6^%c#3=_Me_BG33rfdD`x1FSG;e64BVj%ItkprWd(A7x~3 zJU;G8s0M1Hm_BSp8MWn8=XWl}x>|MO1GVmdDc5>rY!FJL%pMQ60;M5WLc)!XPwF)d zdUwi?jt&lb%loM}I`(;7O9Tc~E+HO=d3d60*BwvGicOV>T?x@6ZX{~#9oW%h z8Gh3uB4oNBv(-23p+ivHW>PqijP$eWmX(m8V9jfQL1L2e?m^>8#>44PgSF{M@&iZ> z9^bOto6@q&-{5%1)n(UrbDS+V>^dE|Vrh%3$w9 z>(4i3Ee5lXupMO%@QnA4@c6mFmgjWTEf_p`n9aJa%IWiZj~O2!kBrvlo4vXZWYL5c#Unr>@8ray!S2JB0JJC5qkW$|*4+1x$pb~4^g~7K=-1DT6X;M&j8O?fb5}wP z2@*(DIq*Y6G?_?Rdsw6`!jX;hWmJE6q4~dD?7~4N{@|4&j`7FMt1FE!K8r#*rQygn z%YX}h*bYtQu8nui%1q4+4*3kcsDbUqJ#-w7#V~=nNc4kcAc-uR$JdDMa9nP`ZN3=I z9Jhp_pn^!($ghL2h^0FX61Fy-Hjj;(kFr`g@xOO%bVN}onDjR8p6!e)O45t!ar6WW zdp3P#tvw|hnzK7q);Cl7DqtbP86w8(K=&N6I-t_TY<<4krA*XK1Y0PH+g%$Qrde7QT?0PX+9)o3>}V2?P{ceS9xAs-f)3u+#O1q|d6v9Z%N>BuCwDV-H4w=g~0B(O4$% z&>OJ5$y^}$-D;7t(L$%Tevi1i7U<-(Gp^^{LM^s^6s{6QeP^rZTe8zml@SSccr8FM9{JhrPL7oEW9l;p<92lLD^AynNj`*;#cfwA;uaqT2OCcNDcDAUP@u4sc!M+p_UF zuP`fHk*Nm7>W%ulGRo*#7j2njYQ7|2)%Gyaklt|!D6yYW#PT9rOK5RR4M>38mCKUO zYbh!|sj-)fMZV~)f??(koPPg2cS6=fj2avHYE|epW-S(^JK`>7ayMH9b)}K8o($C!zK)HL_d3tp$<^S2UAKiR}0zSoMW(^#~hGcl8*r4yb zRXpzYn$!aj`*8aorpGe*86>a17|B{5X6zKSwE=!i{?(yGl}Q=-W@*i${b^!50aakE z{;P~FvC=ifQo^aK?>Q7A9_qIQJtteY&Zi?0r2EtbJx5}JF^GfL7wS}}{glJl5kH^^ zbzU`@QJSuHag2A3FiXolc^OT`DD})-7BPMc9lOmc z(m^&b71gAmUbc@(2WCqF-uH0jDp;UlQwWE3^r5{NjT{olgq-vAB?$k#Oh%p zVKy1mP3>UpY-qT>FFC%YR{j~N3M7#9004PR-grv@4`zwE^Gja?JYIa*7kIJud;AwB ztMK!S2#So3Jae=^F?~N^H8|PT27*|kY9W&V_ohv{F=QnbAhpH zyTZyb>Ur`+RNS#p_l^nd)on(uH*OP_Nv7#peQR3eaBJ4%ljRVOTw1kH*NZ% zC8~ezio6I9>K%qJIhm+P&Qq@nyg=Qz?290K*Kx2A5MMU?v6rVpIhEU!_kQ~2LyOGz zNZM97`>N1;2C!qAaS>IRPr1*6MMgVmb+-8ueX|Zu1B&c$;R%p*6tuy4{m=*RcFCp- z{L7{bgcNZ!&FSokzK)A~c}Ce^?rSfd$9LjAuX~^auNTfY%Op1zv02JeR7SIbOP39y zl`S?YdZM*^ZrCmzCo;qb_87F@OknVr$$A#K(xAxmCWk#o{3PDoa)T?hk?`==S|Fyr zYmd}Gl|bivqcP(!8#2v)lU^sp^}iAGh@_Fpv^VlnfgQt*TPS00C+Q0gB6L%;^6N>hv$Ds@q77|3G=ug9Q;vNucX? zoPsWikpmmz0H@*EyT{`HRoxueZa^wX`KHZT^QZKr3_^Ef((nPPb*gk=GAN>5U~UZl zKeccsom-i}kHgnHtO^17uw7jgo5j%tr@>gW?Lho5vwtmyKaANnzX--`>P4bnF$2vF zZ~sZUtB%Zl_Qgk^Q6(z@qMyo!Z7Jah0qI`NsX3Vmf+NSr=N+L(OH;5 zXTQcWg&1F*b1KU~tgd~hnV@5htqda$8@n}Wsh&4okSbWuuUriGY<>qiUGnd(-_cJt zsuxGNo?neja}M*`d|V#Aya=goo84K4Y?y6b@er0D@A7Z0*{f= z8_ag(MXg72`*C?%!?~Zj@o+{C7KR0==CT4jx2b=FypheJCogikokI7W-BN?T`(sP} z$CQWl-H)c*E-eB}A@^2 zLqv={ZN}2G?@YID1(2>uBq0F{KLREa&u<_1{$K!}aak=Zes8F~-c8(>&GP-@ig$B! z)Z3f;wb!+%PPZa(fdd3mGqY`Ep*4k!WfE$gekl@G(AL)v+ea~ScIH`b@s#VjC4Tb; zJ_1*h5z%ifU{g67y{NC}f#?xiSGRHQB#uASI9^a71^xt8S$~*ZxrT%v@WB-xtBwLD zUg;XNA}x@D_g!$k&z!*`m!4OHA@{6WIf{0T`k1u_dVtE2C0os;W5-`H$Tlo)dnty3iX*rFj!<_PM^CDeBuc2Us4CKiBk8==n z3}L}#L>@(J-_F+1IDf9&qix{1S_s{-iJk>I<}us>KS`_kL~>@z+z5d8w0TVjmYmiZ36=p zF$w|1ab(J*V6qEJ1p4nNh3#pcAz||at6Sw^$ntO7h{v}qCOyY^c7?VX)oQ$6AiZy$ zxM1ZI<|DGl2V?wALVUsis4j#|$o$>i@&k_moHTvE1niN3NxI=6r60XL6#Eg)4Gc2P ztG*=6!TQ6~wKwl`8g2Dh#_e7SyPYk226>UH`H3XnW3Rg3ZvssmMhB#A{Rx{$jBU$3 zRbD?ee}Ys3-sD@iP4qsXPaIForlrkOfcv0i68FC%3i6 zM#l=54ZKSLWml=QM;{+9TRphMsA<3;eLWDQY!&^hNSdJ#Gw^1o#%GMe{71zYjU=Qw zo^k3POOm*2FD(etV68($1@-^dQP3zz?MQdBkqt~6S6l|BBV@x@i;td}r0HZP>5Yli}C2Zbu zdp~8iC5Wq9#|T`2Ox-OXs#PRmOgcZTJGSZXiB9ZIqCq)T!1qoI{6*2+NcmjApv~O5 zO=+Jhu_wp`!w$HSz_V?AnfcMd-X>s zEmVLifC=nNKPghe#H=s-t*d)=t$Q}8|3-QhJxB4gxZ6R@z2LWL$1&Q(%a7?7d-J*9 ztyoR94<@^Vd&AFnwe}utA$Bu_2*v^aGH#T-jOtSrCGlV61T~|$g-%hJa`w)2ITv8= zcNVuB2SSpN7>R#?8sxjm7c5Vi9SAlsEw0o^tXMENM7;0QfxDLZcYo`vQT0Jx7VF#y~AD8GZX^z{aEtO{Qt^b(+I8Z$AAFZRb= zsKK={XssRTM`0kS;Qaq->Mg*cY@+^Q6cLaH2|+>-q>&EkZlrTTK)PY+Qo6fSx@3`t zrBtM)V`-$9?%E~3o9BJs|MhWk!5!y5Q)lM<=FB-WjDcj%DFs*sJP(48vVS*4mz}hg zJK0);@@ck!g@J+qim&KIUvNG+s5swj)d2T3_e(u0zl<~~zQyzP{4p<$-{*3B^TPN= z9x-+CTBDwDmD>15aYYB5-tb5tN$&mCol*i=ny(XC`^{mnxB?iF_EE^>E3(9!O z?NQ!#H9sI^?+H&7#H4WO8@M@m!pXR6&;$v;iyh4ngPp#yC>ld68q54A`s;>t1pNmH z9IFp(AvxW03g=>U_=splFPXFp6wR-P1)SWm39e^7egORb^8bAnzKz;nSY<$Q5MDNZ zai#{Qv^DYuze?d_T=Mt`6^7n>S_4g6rw*T}$hj6>y*WF3qC7ONT^+ks1I(Z#c9zjg zk{dX#R<{^L@~>bpQ!xF>D;O>lMJRh5c=uV z=F7tF1>^va5b|_jl=F#z*g7;&01U+!;PXI2p9n!fd>@b;Iq-}I+7tn~b9o62jj=_0 zZvj~xZ&U#1K2lG@p~N7RpKqajkr2~I0^qBFdQUMHOli~CVKorPw=htq)cd>flrYBM ziSuv&Vq|7zJAT6w*wKe-2oUA^7<*lNaJC@SD<<+OKFq0!Z2DUT zE+{TJsBxTLAt?r;+WFkt?2+PbAI==hu8{N+cqXg6Lh`AC^50JN)$o#kF>U!=>*$N`H4e^?oV( z&Xiacv3LD*p#%dZA-csxHQJpqOuLNwRU+66_;9Ia3k9WaoW;^Nm}M9~|8OXSg3>Eh zgoQ$LHa>leBz=bR4QulcP_OTSx{3kTaO0>!n++<6?jyP2k2sLuE{r-jUTs#K)9}!3v<1A;Y$> zjPuJ@H+Kk7Xh>bU>}Q5rteV;whVx0=$UvL?zMfZvGB0~wZp9RauKfCF=~R-THPMX0 z#nFY)f2Up$VA4jg*G2qMo|433mbUlpZkWF8nfab=i;7urpImlAKx#QlH_2tLa@KME zgWET6j=LUrDBcZseM3`UA&}nr3CfqBh|`;*?|y1_kP}9*cUwZhFU8>aKH2Z9t=cyY z8Nf(|!D?5j?lv5RUIgM04iKmu@sGpB>93ilE_jdvzW;=5g;uuq4)TWpRr5tW1dN5arE~5 z3JsqtFAUPJG2begs?Y{kkNFW1j`yHyyKMn)BE)C&X_uujj419Wp^aB$|AyXIjmZFY7IODg_H zC5{!WEUELAim%$;lziAd6gEe=Dyk~d5`TSFc9=roeDK-$k&^yW$*o(|o9pEL!bOIy z$~GASiAe({fTCnbr85cGjI~V7y*cr8DrqZPdIi1rDrO$+2HRE*DfAD&g6>Ttt~OOwyAV8Fm-kQh|6+zRJO${*WmcvMEvt?khme3_b7t zGC8?aAtAGZtRE|}E2(4|EP+4=5jpHu)U8u(^ClVIbPm;hFp{~wpxdv8{Pm#tinK8_ ze5g?vd!9TV3d+ABqMd3BqyNN_4Fjai0pPyR1UX}kIWed}Aartm0ZWo1(W4Gd>BHL5 zv@wL6sXWF)3rPZhQ3|3%&jC3OJ)e^##o7TpR&Gt?k4)e%?gAMA?+l48b9fYM3FafN z9NgRKar(bh0z?xTFmpiRrIy(r z9AxrJW;z9Yj$(#+P_nq{S7a@#|Fn-V%8_F1eMeb_s!sf6oqI-mSVV zyE=9FG%h=J`GC-XNcci77g4XJO_wL{ORtx3PlXoxrze2ub`(ZuzXSnOaydz6=4gZm1|;vsPE(i+|DoU?CB-Q&xYK@d!_G zxR{$oLp(@PO#6-+CWl!z&x69_kzIRe9A9l}ZfypSP*Hwvgi`Y>F8;eVjbS2^0B3e3 z<~c3@{=PG5y;=7es;>J#uelBK zQZUBRBpILxA8O{~`}78+={x_-WEGb5cS_#&i2<=bts5aF=f&G!Qv_4%dj5}JuPk^v zObv{A;K0UXwS~yAIDj9oj9+p_%)hM6VQ&c%(a8 zyoej_=3M@PtI>Z^~vn`|n9R2q=mu z#VXtycrN0aM9}tSh zwyj;MN(B>-Z}0g}zPEwb`TFx0Z~a@1G>WHzMr|o-Y)#v53j5a7R4P=*52M)YW`OEh z#m2%<1rIFgK(x|>QCLi(jxW}Hab&p;P zgeNQ4*2Xi`ffpdTAK=ROEbi;Ypj#fv)s%vZkf&aT{;y_=Ng3*+!?_Ph_> zu=#8Q5dbfI;B%7Sqz=a#nDNrBaDvnn$Y7bD`?{l;(?fl_h05$?TnRxOUEdcJ+5PD0 z`0a`EU)6L}vTpz2RamYRizXaEE~%R9pTtIGl+C%v(Ane|9BU)2Wx$aim5m7B6(+8J zY6+=yGU9HcXNrFxGxfifa)sI@`Sa!-ouu}P7BgRdo65;{qI$>3o^4ToMC-3xdJB^! z5?-<2UNJzCVLLZfo9SSJo_;}N&+W7|Cp}e1t`Cz<6KSz~1GC0ACA0=ObABTmnO8OZUQIDID$0MqlG;;|GJ{5eKK4Qse$)j;>L2BZip5DqR9l z!98}uV!I&DU?Je;>~+a=^SXM&(Lu*gP>eiKX;YqrvuXYV-GwJlr;gv}hQ0mBbuB&T ztcfOjjoX|i*#S4^!XcokA8ej;`;G8*dPUvPA{2-)fF{3aN6U`DkFS?GJ;;%D75r(^ z>@wI1Rf$tKbnDo>AlsXT*l(G>1@7-Y+Kv((z5fhNj}D8twGF<`_2*w7HgwdS;Z>kUlX(5%9H^ zHz(crn!R0ct_SRd2uy|GUvvUoh;_3kjmY3Gmd+gN*shXO-wzW!8?~RzRT?j^Rhwn(i|hi1H6$KF8aO4wR{aZbW=!% zYU)y^oz$l9ssoALk8#1qo{jqFXJ`mo|%dE}5J@81rOyL5gQ|UPpS^oVz ziI2meY;BO(n?n~r5CnF){b;VpC_@@ZWUVZtYka8g&07DSIjN58Dl?jK?>=qtveYM2 zsi*7ILh^p@R(Q!HVPW&<+k1viou=Ui5!q+3t&6>>`vGZ0{8NUB=#TXi=n)WYqrtQNvo^86CT>gbji3>nUhaYhC$hoC_Q37E&syj^?%Wl1g#og?h{asr+j`b)so! zlC{+qzk1?v=$#5iOD}Frw)))(hhPH*sK_3mL|cdtT!XzumQne6x{uB0cw=h)C5~z! z&G)=^k;B^SI5X3UOa^8y16~b=nTCaPSxmT3Uno{%pPVPj=%xclt6!6aes{>P3LT9; z@G~|V9|RPe?5|NV-0=u`WA6_GM<5f$V|KurA zo@#oqt)o#<)usi{d3!!bc^p&VIsi3j7=_J#@!tA?pm@ z=w*fcW#sdMbI*VMvV;MMj&SaB2*YXd{XAa{JwC$2S5!G0aj zbj9cwJ6cTFo6@1Ub$Y@y)qi`|% zn=|lsoeT$K&6U9=h#>fn%L>X9H2Pp%={e}vWjN&+26H5hq#2jOR(^}yiip*2@$ydT zy5QLGDS(eE9hY`}rf2p#S30$YpO95!*TR3hJt90{3Y)V-zQzrbXvX@I@mM44KN9N) z07Qsl{Rox__~NkdGT9^8-!mlQX^yRzQa{fd=MZ~%L{rwn51l3e{)vW1vj+&@;pgwT zKEWsQQ>E|*;UbP|#3p~%8}IJjkpQG)|F2f@Pd=CDPoj;Z^-|5u*HmsDm4~+j4YaPYT2MxQX=^*-2zV10+UU{2U9Ov8VkCB1Nac8>tKmkw-1Z;Z! za*JxT8Vu#`~b;bz}p&FxQcOc#x@g=50tNfUGSs{y3etL?2)Z`x^~;_~CucgLN*btMDm1FNVT zR{|Ah0ST4NLpFP*v4f*_9Gmi+MIh>r%j0wg3$=@M6I6v=H~xS;U`R|!r>l{Iy6Qzm&Mw& zYD(?FzOS+NKC_|zyy$#3sRsnxA@cii+C3fv?Ov%PY7EA+Ly8a)2 zUrh1#-nprT5!H0d!lI+4!6JwIV;P*A?yfxiic29tUBn_4`Rti%))7UA&d*hORm+49j_DGSHz-*)f-Hs=J1s^z~P4=M6cZ1CGmTp2=R20lO?FT$@HQnJa+>zsL6S#n*WjI~4`BkIF2* z%oDS-mrz9Jdmeu4M%HU}NzDOvwcMj5@4pT<6gEeYuB3$-R*w)Dx)DzIO;;iJH7tv5 z>fsVfr?RSmIqIV~y2+uJ2Xn);cHN&~6jx@9B!zpc{0`)Ou42SbYUv$NEe@Adh+z=h z0AtPJkj#u zl}fX1#`nm+jQgG1*c~57DyTzJX+>U3lzYJ|C#g_LgM+D^as587HEYk*Kin(sAb=m# z>MSdoZH6@LQ8j9ynaFv9LQ`r#|06CCd$hE)x6Pof@gA4{ZyvoEiAqgmA$*ryzmO#l zmG(;AxmSGNX^F9{m3w{QsDVQM?lSfTS3FZDwo-5%T?~awoJFWEqs_SFfCnd`bX6C$ z0&#LXjr?ba=h5N95oY!VDs+U_AJaFdEaMmN`dn^?`-5A}>4|}je{4*A%`}61%}{TU zL)46}pBYvXrlNv@WHN&){zFww`***|oBQLo1C4E%4J;~Obl9(pF&~p4Dto3T)rUNN zvqYxL>ao>L>3SYH^OrQaju28 zVAASfoE0~ybTPc&n`wB9HKDen+#dI3oeX1BBri*v!px4=y-P(nndVapCqd>9r!9%w z8BkZWT&DgqB`Z};L@7@-HI{IN8xsuIMFihM`0^ot$A?|g^t};Zbgkpy7Vq>e>u2ml z26z5+7yE34?c2Y3OhJ(0ZNew#*`ltLHB~aZ!lhf>bxwSC9d&dkmac@v#=`IBN=S36 zB8q$^;-`X*%eFKxC_+F7EWoiY%of@C8y?rJu^*;MgZ&p zj393S6$FJx8I(pN4JtNHWd!8|Z|egYAKDfsaW<5-)?w3t;ovm)gTDAsdMU>C{Y{Ct zvMEJ$Va!rne^C=DU7VdPN!X~B%^bUEdXJ=&pmwTBI-i4Y?ObIODSGR2%c!`F*yKgd zA-V{8uVCAY5o|OOT-Swcz{S0$`jo=XsiIo_a;5>t^?q>AzF@;H5lwZoPXAKPe zeIHbF=|f`Fn-(|2u_1vthILCI$RZ%PfmO1rJ@rZSn`{mPQ^nOvo2dWzQy;|B418-T z?5bi-wadoa6wp(#qjPHV6c zppYT8tx7EKEAZ5@?Q^T1K;#{*TZijC4|P<0`rn1s9M<8o-PHqmx92Ed2!37NsqLH< zwVvi?1PaGLNBDGK#4cZ&y_ANP_w_{|FH<*9cCk2-@%@=(Bm_Aa_eFGX+iqbS;#M2q zr{*dj7cC9)R`~Klu_oUI1qH|9OHB!hbX@p`g%df^Y8omUG2;UBX;Y z9@Hwet7sW%!bu}O8p<_Tr>=2c{xIKDrmXU!5vtBT+4YL1Nk`Xfrz{~$O8D@Gl$PpS z;TH^JZKRs8|5YY*l0R8of=?d6N!-Z8L!{+$UF2xGfBMUU$6Safk8LJPk#;6h0XJW4 z$e_D-7$AJ_2PK;LB}LU_Ab;YtyTKaofHkXSqQDGCpT+a`E2a+bI{+(+pRVcS!7w4D zrg$Jd;}DG1M#F)1@YsrziRRHH`|hC+fTCy!F23%Cl#?nhiNl|g#e_i(c6W9P^A1&g zCQk5y*X7HHxVr~CTD#BFNQup5{a;?Zd3rCF-z}SNH*#9NJ|cG|M;K5O%?3cq@da2- zi(>?$zyW^R9L52r|I?FH^oxeFp5nr9(Q=Fq{3}6Z$o*1_zT;+(UL;_anc#?iIly`2 z<_U`Ub%f7J)LvLQbs`aTCZH?J!;vE;?tpc%^mSh@``BA><4PCZ|DRmi5{@_1;7g5n?iC(Zyc4(WO6cmBa%=MJaF(0NzxJLO3G0(3Qxb7FAFj;&md_hs?qY`m84f z!}6J(rzH^cY;@qAo@`g+wn=IcMa$-s-%h!#`Oq}}*(FyqnQ&)+NAV)3+pIVT?aX_z zFm!ICflq$@@&FOr7jcD0ea1U)bEB)otpK zJnG-T1r4P{=2Q?r*SlXr8y;kR2qaz0_pdn}(}^idN}^qh&s1V@D(t#z@-W&hr;idEF)V2Y(F^dq-(Xf6D^%X%RimT?&M4?vyUvD z@@sf2B%V@z9Az5<6`pUq7@h@|rh2zdv^3i3B==cp$NM+i(i2mPihE{tX!%2f>bNFK zU@y2Hi&k7hYgNpkLSKIp23{<#DN3n`yj61kN5%^vDe^$N4v&IpDWz}Rn^AI}F6?Yv-H?ZD`K||3 zZflUziTnlQbQPm*GMmM&ZLJfR+OJ2bHn@u>dBE_9odjEw$4p*ln0@`y3YkC94nwpRl2Vl5y1L2zZ2WO#;m_NN8d+PJsJfwVw0y7$I78 zcdYf<5`!SPC!rRSw(uqt*9kRO3GVMLs!kmg#tn}A`IZ1C=fLu{Z?DdEVZA|qyM@y4 zbvXNY{(@s|F70J-y!q=+2L}ItF7CLu2B)uqS*-JQ4FQgih*(o%J&oZr4sNy_v3Tl} z9~mlB5FE)fs)9p{iMSe+S+L@{Wm*(yl;X>Vy0f!zHZ4+KWo}@ zN*M9)Fnh(l=akTSnWeWpL?I6+hZ{*Ah3BbFp%*%bLq70}5W4tJHPuaZsIcyM=js?U zY`D30eM5RHk+6)KoV2h}z$Q-@=?i*moph@|sYZYO8zzLX+&ukQbKwXCrM8D3j(Ai; zgo-}nOt)r{-y1_{?&vtd12UX$9^|bLXVjjbjvS4{GReh4Uu?XmZ%qC0aRBq=B`LRr z_cxG`74HMxWsg)VHn(sX5=MF_sHQ@ZezQ{;Pu}H zZw-L>@D2)Ked1_Gf0Ssx-k0=5C2!?Q-N{q8yz>@zNayd(xl0WXGxbl%I|B3iQr?}m zvNpKMJ+TNB)ty5}`GRqB>W#N#>$v4WefRr{rlZsox~Tfac^z+`PJ&{|?qpIW zUgYHk9(@WrD@T5nMjSBoef}ptz3gGwKv{q|4nD`5H)sXM&^NFYf|t<3fK03~w16XZyf=xyXx}>kX$@Asr2O<5IhRuBpbd8Omqi| ztBNWIUFW+zN$)iD0G0E9`oV}lXo?6&Djlx?ifmO{A)P4Zano4hkJ?_7(S^k+V5ZQCp(Mr4!p3#eBGqc zT|0Q%?X1UkhXj)8UGl+#fZBS;05{V=-^X}Q7oz)iZNcOY9J0N60cP|~?M;|j%`XOO z9LHj1jODyJ_+C$cOvsMCaa+gPR>|jj6>2N&^@k(+A!~Xx99f|tdNS*}$n8sFZ_xt{ zsM^F|vmE}zttPtsko6{n9aG(Z`Xat#({hoN8qYIz=sh?U2znVHtxP=wv9$b%ksV(4xc9$f2R@#lMHv^5xt8^zhCH$<;`j4v|%G8W&1f~XDqI&Zm7(WajnaCb zSxUgAqntMfi3KQeSwTq{fUh|=2&MwBth(5F%oi#>*xSg%yL!IU&0_D^cbKk* zw?>Jdgny5{xT;GjwuYH-rZ6CH+7*9c#g}4;O8!sfb{@`^x?4&aff5_ZoM^!LYPi;M z-D;wR5~s|PVBNxZYg>DG;P8)7_U1OlL)8j#cJoSh>}|)DCLBBtUwkLWr6}8G3jc(k z;^WKIq5s<8uDsr1r8DUy&QuLgj2lUOP<*|408AM3(p9J~w$#KF(uk$%ic^Fb$>$lb-0q^<3Ld`v^ciuv3oAC-#_qId>s$xwD{YW3$_d@xKF&mY8&%gZzKP%xQk$AU_#d4SmtBYPwX}sQ%ZZ7pDnVDkSp@ zS<`Df4=dr=h!yP0pVQ+$gvdJXk~A$91&3Gq8Ofpf-ZOxMem_di-eJ;1arU|07iBDv znS~AJ<>6c`0C}GI88`6c;;Zr9^`{+(SCbv<((ziPPbE~+S5#P2u@1_`_QifIM+Z8a ze4wO=$XI2S^SAO(&m`0NFAIjYze{_cJo#K&+W+LTxv5=t=TmBydLtcgv8~O|vCX=) zUplV%zsSYd^B&MTI^F2y6Eq(7{b|G4~Vma&wCNwPyT8v{7-^XfTqe? zeecB43mma6$OvdLMY*b4Y>-6Q|0*$iju}p{x+2qEbcb7@?XL3rbzq%C#|km)MUZYg z46=|-3A1VT*iV~t-%Xp>ScsdSHmI()AVz!kHG*cDAQYuF{B4LG;ZKyHa>_k3V3vwJ zR!+|R{%+&%j-dSStMJi{oc5z3-!zSy>y195j#y*j`Vm_RrB^%99?;oKt{i&f-lQx_o zgQ^jhwjY-%ybr`d@{5~6kEMN3zLG3b+Hp%)pZR08$zR$N*%~o7!ax92CJ@aXz z5PJ6wzHejDW*ZtKu{A-T@{pg;GiCLU@I8Ey0qI=+V(aCS4$J%W;qLm*^KsKe zLH_3zYT7=Y-(usaMU*M(X5b%dR_{2IGQO20A96v^I}t&*#_2H^)4S29quEW|sXm>~Zo(qf} z7U@rx$&MOkQ8t((4S76glm`tOlWZZ{a+8WtBV$>qnXajyZF#~vW08U0q{;t?MLd-#Be`SXnfu^eTR1aE z${-T6R~0OJeQ_@jB_lu7YzNA@dH>*OoNFGd){rY>r8*vEp)_@++nQrEusCYtAj-da zh?G9Hz5Tw&8|cmpvNXYX>~5Wu$sci5;S5C{9MzQKcu^k^NL;1KbBCq~?Q-JPVt84)-HE@vq(f z1#ab>*}~(^j5qlz-!WM46u13z*RKdMe_?Wy`14MGWI4oK*LVGeMKN2_zrX!12g58U z2;AIM0=jiKmJM~s=3D=ZJ8gD;r%TpWu7SP@(UGdVdPtrN4`>z`F346yK!kqYwc3%- z-gvtk44+$dZmMVGlPV%TI9G}=JU`$^e_XCQRnf1_arNgcR~eNzdCO4H(L;$z zUc1?_tt+a#LXG1+-7UdV_l_a)Fw13uf}XMJRU6>3zoxPxrV+4==lZ(rXv`ZM*tw0- zLFa?$xZA-UvA@4#_Uro9G@jUe_uQ=`>A=s@<|6#<31QC>{o4(|6z(N|4S_{ZD9`Bz zC)#{FAT#_v`_`33o9%LcEO>`*kVp6KF9n-3>~@?!cuJpHo|Ud33}F?)r1!f~Tyrow z8}syJ5xQ7UTf#;;%!;DA_7FdI3jf>qc(c>f+RNL)ZE{3Wj&3XNMU3;9nS+dZ2YBVa z*W|PPe7owY0IO@Z^Kg{1wz=o!l)`+2s1l>V-K3s>_{iW7OSFcKO)yt32dx;zyR!p| z249#j^L#}|ms3|~Z0GD%WC~K)%IU4jkQJ!;#`j_Q%Qg8WzmM2!-s0#TsGfnc)Sc<6 zpgrJ6*5k1H&sQ~w!yS>W-Hqk+_a;%wWOBrFInCVoi^a*NN`Kwgv>JQqGyjK!E;;^_ zL8{E@%%O^7a9(?U`D+dY;m_jb>jU+Tjgul*iqD)*5z7zys>;TqGkGRAMpA(<&zNBa zR5RzK<7vDzDpzYklMU{ZVd{4q%zfDl#_PkA=~FSeWQ{TBJOxYJiae@gg1FxA;s)~S zb~KF(H%;8saWAeSYcdl`hvxJ+4n2Mx zvES_L0Bd_|j<(K-&4mJC+2q{>r zztPgr60c?xC4UVk4Le-rZ8b)l8IzJh1KjlNu$E4;T+jGlzlZ{Ap_vqi8RG2_#nS?L$Pa3YEsm;!-bTDWS+!2(Fh_5hGn!zX{Y*_laiHC`f2?KgCCT8!i;Xlt32L4EZV#sKpC%B@g zxSqp7CSOQ+J5!p2qEfEagzpj2Sjwe0pvg8QZhlG;{i-+l@8%uebQs8-7P@bbGM?)7 zpsE;Zzi-lmit@#oh1eBpm&FZDn&jf;WA4e({Q!7HU{t5()U?T7#LmI%gt^BpV35EK zE3*e_z`5GlaKsV}%ZOkf!lQv&GW1z6t@qwX0;Y}Crj1spU5s41(0fAAz@Lx}?w$Fv zN0WynOIOAW$eaPHXjwF*-K8~%pb>;c`cpopKGcc@wOh1|Ww-KCybaYlumeo~W2d<( zhve(y7FO=ySFQJjM}K=dAI(NB-e(F#Fwm5J;ItQb=SqaTVs2JU9jN6g@Mt-NlNzMs z!FxFb$OuM|%%jf-j}Y`$W1ker0{*iFmd8VuP=JsEAh_TWiajoGe0xEkBJNs;3>-M!UqL}ja-1e)4=^QM5kKz=yF?C zX0&3<;@z)Bs^$7jc-9txi^QJ^aHq9Y6yMI(RQ{Yz8MGAqkBdl6R(39r<*2)?ZX#d_ zk{;TCN7(D~eJ-nGH{4sHRU59TXq{6qzcLC0&rtzc#AptErL^4cQ?Nof&lngPd$$Y8 zGaRPwSDiWS6o5enrRBok&M#P0)@u@Ok3_kx`y7Z~-cqy1Kl0u;f~1e;D_mT0=s(=g zwe%<(P>E0_O(;rG^GEM4Kk{+%d#5B7%r!AV>z2+jpy*VSf<#(4d=iiH_vczzVso1I z-vzebCkYaP5rcYWA8MbX6cT|pYw}~V@;!?WZXH^YpQT5PT9|q^gYE-}1n^NAJT<(8 z7`yx86$-ZV{QR!P8KBV5Esff}s?7?!gEIP^D|FGGjstr|a_8pLqalO9rlPw`ZX)j{ zh(JG0E)Q>+Dp}&6dNIq&a9hSisG3c+P)MjJ(33Urq?yJDy~t?!gOeU3#QwIIa!SGl zk1);B#`+}z+S3TW2^A;SVcKujW){rc3M#{5u3IC`teJ9&g@zQ&(>c_l(~G_$sIqe2i-)@kpBaU_d&=Z@woQtL(4$I$>BoeGT z>g(d&LjwEEe#@oylRur)zy41oHS71EA;aE=2xc;>VAG7t=&G^RKOW;o}P-A zmIih`A}~9RBiMX_FT+e{sBxDn{c@(H#LQ(wjyZWi51%TkA%%r&rR%LPznkR_EiJ9& zRnW=4O}L>dec7koLV^9+{PN7^g=!4FI#l$UMOh#1XaVONK3drRp8IGv>$1p#}O#Sb>vR3BKm z9;7>Fo)61_{xZ*+nK|>@G9A|3zNEjO+@ykWVM>n2`hkVPzsy>6shPQ$K@kxZ zYRZ_k9lu+H+iz61gq_T6bg(ef-D>~JmPCfe8~zDirY1WV^s%)sRr%D7%hzD?GuP%_ z7=nEX5VZYzC-5A%O7$k$Y3TQZxJz3ob!Ms&EpL(a5TywLCMub>qdStr;x3F1_ z$s$iD472Wplj@Oy$65astqd&UKeb!;uN*WB7A7*u8}1(AZq>v0MalN0miSqCp+^x& z)i%00WMCvo!XRV+CwGD?{W5o53`^yLZ#aj1s6B@G;$OO?Gn1e~FNXvm9jOY4{zS$b zfu{&e^KoOtSUDXcTTA4+`nhXEcxVBqnJA=P5W9&;uHcFyvH{b4gX)TVXD&I8-{-eiEi5R85T9{oc&^_%TZX=NPvc5Wz~OK zF*k}T*j7A0Fd-u?ZEOI|Yv6CQM=ld#M9jzX`i`2fCxY!&`X&0KaP(TY1w3*&KlRy& zH08^87aupa=xgooc51xO!Hu?5jkUPH(WAQU(@Mm^%tEiP)!14r{!fsym_O>u;z*5@ z^N+ihVO&i=%<;MK%-`OQ@dWU&Kh!wW=gNl9MbNGgwD7IrwD#R8H#lxsn4d`Aw5NaO zcAr3IeV@fN)t@2 zBd!~EDe*U`u2YS>dB#_FJhrb~-EF#BsR(&=XQ=rE$F!Uh{h$`plX|I;Ol#+iwxf6S zqqfkRT-fpva~eA>ZDHOESvkAl1s%vru)dNxzCR6-q3W{i;ttpMWlw^m5yPOxcHjiA zp&`|DT6YmKiV>*6V*hAjZC1Lw4At#umrf6h@r>PJ`p~RQ7T3QDW$bagZ<;d9ZpV9! z)cmhWv|9|8$z!l8oij(?_VZTrYQI;>{W9^UMoP@}$Ks?NgWxNSZ0cu#FN|U;@wB$Z zY^VEV^u^CF`iwjq-^SIWyAGD=Z@@#9eJ9Yy@rac!^kE#GVP3;dJ&yfG*^DZdTJLV? z;Z@sUuvkaG7^<|i^s**&!=XI=MB%T;vzqJI;S<%@d!dGv&TP`9>_;V6ZLX`VBq5<@ z^BW4MJ{P|QhoS8jGrVa>UZH5{s}j>!TpnLbvAvj+b=-K9{QOPH_JRquTlNE_T;{Ft zJ6D=XN7^jj_Z)>=^h(dJkOyhF$3k@uT`Z1Ll(q?85wK@UhlE;lshbQL2L1Z#=6wFK zePhy1XTEkokBNFh*VlH7vT^#OjM8!dHXf#|!Qdv4^Ic*kU34W<0s?P~ouuY6W7(?7 zIQl9+IvyWxz*-P86=R?IKsgDBf~D)xt$xlcE)4o3#LvBF8FhX|bT&0MjyabLPI zK|lP;m6JrfsYcg$(letSt~x*-6G>AcGqMXxb~ZoOW-HFd_Hb(I;{D#0kh(6hOaMHs zG%|BSh&ns_uPCCjTtuy@`LWejC~(6y1T4$HSJ(+BgnvHqy;Lk2>VNE)%R120dUvnO zbxm*+|4{J6&_IpO^{P!-j$v+>8kft=qSSoWw1A*Ld0d7)R9>J3{u>it{^G;p&&gXEh&g8R7H*O-eu6vIWRuItmxM!$~ zEG!bLvgAplZwJ*-eV7FEh01btbF(wg)&7U%!G!CtHZday`)@X>JebCIvRmaDSMvQ( z=HoD0-X?U0dUG4wtg&s*aF<;lu1Fe4Cj#_qb(66)2s(}fswh67>k2!+`RM5GR8}}q z9)HDu?DlBW^-#t1icasJ=#oG_rbw0Dhe0Jn`_8!6;t{|PBB*s_P8(`_fb)MGKGpKK zGlFbCiv2@<1F+o1((wi9?$pii|38BIg*L_XVM~htNy0m;qVg$URbv%+jxFs8^$P-m zyXM>vdJ^~;zXc8_)0)eb#3x4g~s z7aQxFU7W)JZ;k&ef+OokM_#DM(5P!*yEH#YN-dJ27BI4*T!&kD;ZJIsrDR^)9AN># zbLcSSU7<_)0P(VyLMYO4W0Z99;kZVDH=Z(d)Rf`?BNPQ0RcVOi Hr=b52o600- literal 0 HcmV?d00001 diff --git a/doc/kcontrol/solid-actions/index.docbook b/doc/kcontrol/solid-actions/index.docbook new file mode 100644 index 00000000..5cd818b0 --- /dev/null +++ b/doc/kcontrol/solid-actions/index.docbook @@ -0,0 +1,222 @@ + + + +]> +

+ +Device Actions + +BenCooksley +&Anne-Marie.Mahfouf; + + + +2013-12-05 +&kde; 4.12 + + +KDE +System Settings +Solid +actions +devices +hardware + + + + +Actions for new devices + +Introduction + +This module allows you to set up the actions you want to associate when +you plug new devices. + + +Screenshot of the Device Actions Manager + + + + + + Screenshot of the Device Actions Manager + + + + + +You will see listed all of the possible actions that are available when +devices are plugged in. +Please note that they will only be available under certain conditions. + + +Add + This will ask you to supply a name for your new action, then will open that +action for editing. + If you do not supply all the required details in that dialog, then your +action will be deleted. + + +Edit + This will allow you to change the Name, Icon, command to execute + and the conditions the action must match to be shown. + + +Discard / Cannot be deleted / Remove + This will do different actions, depending on if it was supplied with your +system or created by you. + You can only discard changes to system wide actions, if there are no changes +then these actions cannot be deleted. + User created actions are completely removed, including all changes. + + + + + + +Add Action + + +The Add button brings you a dialog to enter the +new action name. + + + +Screenshot of the Add Action dialog + + + + + + Screenshot of the Add Action dialog + + + + + +The action name should correctly describe the action. After entering a name and +clicking OK, the Edit Action dialog will show to allow +you to set up the action properties. + + + + +Edit Action + +This dialog allows you to change the settings of the action you +selected. + + +Screenshot of the Edit Action dialog + + + + + + Screenshot of the Edit Action dialog + + + + + +This includes the icon, the action name, the action command and the various +parameters. +You can change the icon by clicking on it. +The parameters are displayed in a +tree, the top item having to be true in order for the action to be shown. + + +Edit parameter + + +Parameter type + +This controls what can be contained inside it, or +what matching is performed to check if it is true. + + +Property Match + +Compares the specified property of the Device (using +Device type and Value name) and using the evaluator, compares it against the +text provided. + + + +Content Conjunction + +All sub-properties of this must be true for +it to be true itself. + + + +Content Disjunction + +Any sub-property of this may be true for it +to be true itself. + + + +Device interface match + +Checks to see if the Device can be +classed as the selected Device type. + + + + + + + + +Device type + +These are the possible device types supported by &kde; on +your system. +They are used in both Property and Device interface matches. + + + + +Value name + +This is a list of all possible property names for the +selected device type. +It also provides the selection of the value evaluator (which is either +Equals or Contains), and allows +entry of the text to be compared with. + + + +Reset Parameter + +Reverts any unsaved changes you have made to this parameter. + + + +Save Parameter changes + +Saves the changes you have made to the parameter. + + + + + + + +
+ + diff --git a/doc/kcontrol/solid-actions/main.png b/doc/kcontrol/solid-actions/main.png new file mode 100644 index 0000000000000000000000000000000000000000..19c91c6abbf90dc399328e8b94929fb64ac3a54b GIT binary patch literal 65245 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/splashscreen/CMakeLists.txt b/doc/kcontrol/splashscreen/CMakeLists.txt new file mode 100644 index 00000000..72d242cc --- /dev/null +++ b/doc/kcontrol/splashscreen/CMakeLists.txt @@ -0,0 +1,3 @@ +########### install files ############### +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/splashscreen) diff --git a/doc/kcontrol/splashscreen/get-new-theme.png b/doc/kcontrol/splashscreen/get-new-theme.png new file mode 100644 index 0000000000000000000000000000000000000000..dc631ed73b6f8a17a0e1aef6f0d9bdbbd8031559 GIT binary patch literal 67741 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 z%0D%|{{*h1GkiYqq4f_3#BTrTauV$oa(*Z)LBO~8g#J6E8v_9h$E2{q&GE?bi+D{G)DBj@g|Ah*5Am9iK7+8Ylm`etG23U)c|b1q zOL}xmZ{U8S@Nq#QH(j}RX_BKgFfPg7`RCm+XP;C56BsWoQP<}86vN7D@UzerQFH-6 z0ygN-u;XPoC_==wn;qLf@}jR438&;GY*VkfCR=0dz7Afsla1UHKu0-W=R6Fx{p7YN0+C0VW%g!XP1t-{i5)zeG#aa`hvYLm3#A4(#Ag+_VL<0O*e`XL5o z_ot3+R5BiXzkFDPjbeB=J9L*@m`VtDGn}flZ=sqoRyOW!-0tr#^B6kVB?KtvPx5@d z;{Iz@ca>_Bi@#e6qUwHwi~{c+Tom;3Z`$+oV+gV5V*uvcnPbpD6#8iTVe3!Vt)ZIA zvT77dBW}AbxR=TJNrk`2>t`fsy8=foHlM>4EN;4DMMAsz9tul8cWJr^615@kcK^^!a+ z*`Bh%=jK>)TmFxNnLrj2R|3yBMk)SoR9vrvYlHKlNJLAT!LGL$%1fQfUi@gx9|X}O zP1cTv!cvYX60(w@+CWKZNv@Q1Pg*)Q&?rYchnbt@!a-2YeBt2NAhN;8n20?haH>>( ztQY_eRyhBNFM|)I$lXQDR{!O!FW~Nv2-G&GyZ&ePX2(*MW`plGzt7@o{8Y|9ltKTK z=r4@8t;_6`fPWId11)~{u8n9QnM>#whX1ahUY~zY=^+0J1OIO^rvk|veixP&`nPDo z{!@7T-!h~0Z=0b1?)Kjei2u8^$>#=v+6@1FZupeKcn;qAQUj#vPV(Q6M+LO6IrURR zo(~2E1c3kVHN)io2knUd{(czHpn&D5;fX4`Kl>jA|F#%q%nGt!F6e&T=+V;FCzFbZ zr0CW3R?}MJy%Zq&_YL5qI}+{hvub29aiyiD^eOOC@+;39YPx~>9vi+g|9%QKPHN(p zfShL#xj30t&yxavA)^T@e3fkKF2C^>xoiEb{r9t&SsCHkJbff3>vkwIQ~Ik8Pn=6u k{`Ux(ZPcpjh>uK)l5 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/splashscreen/index.docbook b/doc/kcontrol/splashscreen/index.docbook new file mode 100644 index 00000000..09777dc2 --- /dev/null +++ b/doc/kcontrol/splashscreen/index.docbook @@ -0,0 +1,117 @@ + + + +]> +

+Splash Screen + + + +Anne-Marie +Mahfouf + +
&Anne-Marie.Mahfouf.mail;
+
+
+ +
+ +2010-09-25 +&kde; 4.5 + + +KDE +System Settings +splash screen +theme + +
+ + +This module provides an interface to install and view splash screen themes. + + + +Here's a screenshot of the splash screen manager + + + + + + The splash screen manager module + + + + + +On the left you can see the list of already installed splash screens. The current splash screen name is highlighted. +On the right is displayed a preview of the current splash screen with some information about it below the preview. + + +Get New Themes... + + +You need to be connected to the Internet to use this action. A dialog will display a list of themes from the http://www.kde-look.org website. Clicking the Install button associated with a theme will install this theme locally. + + + +Installing a new theme + + + + + + Installing a new theme + + + + + +This new theme is immediately available after you close the System Settings Add-On Installer dialog and is highlighted. The preview displays the picture. You need to click the Apply biutton to make this theme your current splash-screen theme. + + + + +Install Theme File... + + +Instead of installing a theme directly as above you might have a tarball of a theme locally that you want to install. Clicking on this button will open a file dialog and you choose the tarball of the theme you want to install. The installer then unpacks the theme locally and makes it immediately available in the themes list. + + + + +Remove Theme + + +Removing a theme means removing the theme files from your disk. A message box warns you before doing anything and indicates to you what it will remove. Clicking on Delete in this message box will remove the splash screen theme from your disk. Clicking Cancel will abort the remove action. If you choose Delete, the theme is then no longer available in the list. + + + + +Test Theme + + +This shows you the theme and the associated icons as they will be displayed as splash screen when &kde; starts. Clicking on the splash screen hides it. + + + + + +
+ + diff --git a/doc/kcontrol/splashscreen/splash-main.png b/doc/kcontrol/splashscreen/splash-main.png new file mode 100644 index 0000000000000000000000000000000000000000..375455e9c17f6ca021968339ddfc50813297bcd5 GIT binary patch literal 66684 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 + + +]> + + + +
+ +Window Behavior + +&Mike.McBride; &Mike.McBride.mail; +&Jost.Schenck; &Jost.Schenck.mail; + + + +2013-11-15 +&kde; 4.12 + + +KDE +KControl +system settings +actions +window placement +window size + + + +Window Behavior + + In the upper part of this control module you can see several +tabs: Focus, Titlebar Actions, +Window Actions, Moving and +Advanced. In the +Focus panel you can configure how windows gain or +lose focus, &ie; become active or inactive. Using +Titlebar Actions and Window Actions +you can configure how titlebars and windows react to +mouse clicks. Moving allows you to configure how +windows move and place themselves when started. The +Advanced options cover some specialized options +like window tabbing and window +shading. + + + + +Please note that the configuration in this module will not take effect +if you do not use &kde;'s native window manager, &kwin;. If you do use a +different window manager, please refer to its documentation for how to +customize window behavior. + + + + +Focus + + +The focus of the desktop refers to the window which the +user is currently working on. The window with focus is often referred to +as the active window. + + +Focus does not necessarily mean the window is the one at the +front — this is referred to as raised, and +although this is configured here as well, focus and raising of windows +are configured independently. + + +Focus Policy + + +There are six methods &kde; can use to determine the current focus: + + + + +Click To Focus + + +A window becomes active when you click into it. +This behaviour is common on other operating systems and likely what you want. + + + + +Click To Focus - Mouse Precedence + + +This is mostly the same as Click To Focus. +If an active window has to be chosen by the system +(⪚ because the currently active one was closed) +the window under the mouse is the preferred candidate. +Unusual, but possible variant of Click To Focus. + + + + + +Focus Follows Mouse + + +Moving the mouse pointer actively over a normal window activates it. New +windows such as the mini command line invoked with +&Alt;F2 will receive the focus, +without you having to point the mouse at them explicitly. +⪚ windows randomly appearing under the mouse will not gain the focus. +Focus stealing prevention takes place as usual. +Think as Click To Focus just without having to actually click. + + + +In other window managers, this is sometimes known as Sloppy focus +follows mouse. + + + + + +Focus Follows Mouse - Mouse Precedence + + +This is mostly the same as Focus Follows Mouse. +If an active window has to be chosen by the system +(⪚ because the currently active one was closed) +the window under the mouse is the preferred candidate. +Choose this, if you want a hover controlled focus. + + + + + +Focus Under Mouse + + +The window that happens to be under the mouse pointer becomes active. If +the mouse is not over a window (for instance, it's on the desktop) the last +window that was under the mouse has focus. New windows such as the mini +command line invoked with &Alt;F2 will +not receive the focus, you must move the mouse over them to type. + + + + + +Focus Strictly Under Mouse + +Similar to Focus Under Mouse, but even more +strict with its interpretation. Only the window under the mouse pointer is +active. If the mouse pointer is not over a window, no window has focus. +New windows such as the mini command line invoked with +&Alt;F2 will not receive the focus, +you must move the mouse over them to type. + + + + + + +Note that Focus Under Mouse and +Focus Strictly Under Mouse prevent certain +features, such as Focus stealing prevention and the +&Alt; +walk-through-windows dialog, from working properly. + + + + + +Focus stealing prevention level + +This option specifies how much KWin will try to prevent unwanted focus +stealing caused by unexpected activation of new windows. + + + +None +Prevention is turned off and new windows always become activated. + + +Low +Prevention is enabled; when some window does not have support +for the underlying mechanism and KWin cannot reliably decide whether to activate +the window or not, it will be activated. This setting may have both worse and better +results than the medium level, depending on the applications. + + +Medium +Prevention is enabled. + + + +High +New windows get activated only +if no window is currently active or if they belong to the currently active +application. This setting is probably not really usable when not using mouse +focus policy. + + +Extreme +All windows must be explicitly activated by the user. + + +Windows that are prevented from stealing focus are marked as demanding +attention, which by default means their taskbar entry will be highlighted. +This can be changed in the Notifications control module. + + + +Raising window + +Once you have determined the focus policy, there are the window +raising options. + + + +By placing a mark in front of Raise on hover, delayed by, &kde; can +bring a window to the front if the mouse is over that window for a +specified period of time. You can determine the delay for this option by using the spin box control. + + + + +Setting the delay too short will cause a rapid fire changing of +windows, which can be quite distracting. Most people will like a delay +of 100-300 ms. This is responsive, but it will let you slide over the +corners of a window on your way to your destination without bringing +that window to the front. + + + + +If you do not use auto raise, make sure the +Click raises active window option has a mark in front of it. You +will not be happy with both auto raise and +Click raise active window disabled, the net effect is that +windows are not raised at all. + + + + + + + +Titlebar Actions + + +In this panel you can configure what happens to windows when a mousebutton is +clicked on their titlebars. + + + +Titlebar double-click + + +In this drop down box you can select either +Shade, several variations of +Maximize or Lower. + + + +Selecting Maximize causes &kde; to maximize the +window whenever you doubleclick on the titlebar. You can further +choose to maximize windows only horizontally or only +vertically. + +Shade, on the other hand, causes the window to be +reduced to simply the titlebar. Double clicking on the titlebar again, +restores the window to its normal size. + + + + + + +You can have windows automatically unshade when you simply place the +mouse over their shaded titlebar. Just check the Enable +hover check box in the Advanced tab of +this module. This is a great way to reclaim desktop space when you are +cutting and pasting between a lot of windows, for example. + + + + + + +<guilabel>Titlebar & Frame</guilabel> + + +This section allows you to determine what happens when you single click +on the titlebar or frame of a window. Notice that you can have +different actions associated with the same click depending on whether +the window is active or not. + + + For each combination of mousebuttons, Active and +Inactive, you can select the most appropriate choice. The actions are +as follows: + + + +Activate + + +Make this window active. + + + + + +Lower + + +Will move this window to the bottom of the display. This will get the +window out of the way. + + + + + +Nothing + + +Just like it says. Nothing happens. + + + + + +Operations Menu + + +Will bring up a small submenu, where you can choose window related +commands (&ie; Maximize, Minimize, Close, &etc;). + + + + + +Raise + + +Will bring the window to the top of the display. All other windows +which overlap with this one, will be hidden below it. + + + + + +Toggle Raise & Lower + + +This will raise windows which are not on top, and lower windows which +are already on top. + + + + + + + + +<guilabel>Maximize Button</guilabel> + +This section allows you to determine the behavior of the three mouse buttons +onto the maximize button. You have the choice between vertical only, horizontal +only or both directions. + + + + + + +Window Actions + + +<guilabel>Inactive Inner Window</guilabel> + + +This part of the module, allows you to configure what happens when you +click on an inactive window, with any of the three mouse buttons or use +the mouse wheel. + + + +Your choices are as follows: + + + + +Activate, Raise & Pass Click + + +This makes the clicked window active, raises it to the top of the +display, and passes a mouse click to the application within the window. + + + + + +Activate & Pass Click + + +This makes the clicked window active and passes a mouse click to the +application within the window. + + + + + +Activate + + +This simply makes the clicked window active. The mouse click is not +passed on to the application within the window. + + + + + +Activate & Raise + + +This makes the clicked window active and raises the window to the top of +the display. The mouse click is not passed on to the application within +the window. + + + + + + + + + + +<guilabel>Inner Window, Titlebar & Frame</guilabel> + + +This bottom section, allows you to configure additional actions, when +a modifier key (by default &Alt;) is pressed, and a mouse click is +made on a window. + + +Once again, you can select different actions for +Left, Middle and +Right button clicks and the Mouse +wheel. + + +Your choices are: + + + +Lower + + +Will move this window to the bottom of the display. This will get the +window out of the way. + + + + + +Move + + +Allows you to drag the selected window around the desktop. + + + + + +Nothing + + +Just like it says. Nothing happens. + + + + + +Raise + + +Will bring the window to the top of the display. All other windows +which overlap with this one, will be hidden below it. + + + + + +Resize + + +Allows you to change the size of the selected window. + + + + + +Toggle Raise & Lower + + +This will raise windows which are not on top, and lower windows which +are already on top. + + + + + + + + + + + + +Moving + + +<guilabel>Windows</guilabel> + +The options here determine how windows appear on screen when you +are moving them. + + + +Display window geometry when moving or resizing + +Enable this option if you want a window's geometry to be displayed +while it is being moved or resized. The window position relative to the top-left +corner of the screen is displayed together with its size. + + + + + + + +<guilabel>Snap Zones</guilabel> + +The rest of this page allows you to configure the Snap +Zones. These are like a magnetic field along the side of +the desktop and each window, which will make windows snap alongside +when moved near. + + + +Border snap zone: + + +Here you can set the snap zone for screen borders. Moving a +window within the configured distance will make it snap to the edge of +the desktop. + + + + +Window snap zone: + + +Here you can set the snap zone for windows. As with screen +borders, moving a window near to another will make it snap to the edge +as if the windows were magnetized. + + + + +Center snap zone: + + +Here you can set the snap zone for the screen center, &ie; the +strength of the magnetic field which will make windows snap +to the center of the screen when moved near it. + + + + + +Snap windows only when overlapping + + +If checked, windows will not snap together if they are only near +each other, they must be overlapping, by the configured amount or +less. + + + + + + + + +Advanced + + +In the Advanced panel you can do more advanced fine +tuning to the window behavior. + + + +Shading + + +Enable hover + + +If this option is enabled, a shaded window will un-shade automatically +when the mouse pointer has been over the titlebar for some time. Use +the spinbox to configure the delay un-shading. + + + + + + +Window Tabbing + + +Automatically group similar windows +When turned on attempt to automatically detect when a newly opened window is +related to an existing one and place them in the same window group. + + + +Switch to automatically grouped windows immediately +When turned on immediately switch to any new window tabs that were +automatically added to the current group. + + + +Placement +The placement policy determines where a new window will appear +on the desktop. Smart will try to achieve a minimum +overlap of windows, Cascade will cascade the +windows, and Random will use a random +position. Centered will open all new windows in +the center of the screen, and Zero-Cornered will +open all windows with their top left corner in the top left corner of +the screen. + + + + + +Special Window + +Hide utility windows for inactive applications +When turned on, utility windows (tool windows, torn-off menus,...) of +inactive applications will be hidden and will be shown only when the +application becomes active. Note that applications have to mark the windows +with the proper window type for this feature to work. + + + + + + + + +
diff --git a/doc/kcontrol/windowspecific/CMakeLists.txt b/doc/kcontrol/windowspecific/CMakeLists.txt new file mode 100644 index 00000000..69d7e2e9 --- /dev/null +++ b/doc/kcontrol/windowspecific/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/windowspecific) diff --git a/doc/kcontrol/windowspecific/Face-smile.png b/doc/kcontrol/windowspecific/Face-smile.png new file mode 100644 index 0000000000000000000000000000000000000000..501cc796a4c4d3350bc54e5b9db44e5a5ef5bd4e GIT binary patch literal 1233 zcmV;?1TOoDP)J2(Y|dwPHGf4hw-aoe;1?|#4MdG7iD-}n6=1Moy> zcG}6S5?$h}4|^5V9hYg_FUT!*S$^8uA7usCzw?T(Ip8WM-c)$3(VV~>ig(Ua4HPf6 z;`d?CgNsym(ib>PYh1RCg;XcG>Tz`?(6$cf+y?aQ1Nx5v z#%u!B)T5c;G-k;3RbRV=OleG}y6+cESSyzUt!ue33h4btG8-xZ9@G-3rXJ0RBe=aq zeiM~@=T9=X-F{{49Q|nd3gB)M(6yVVN&pPU0aGD2tO3Su6R4)1H0w{}S0&K24)tlC z`nF_yhe^hH;Y?*d`y9}%2JR*EBs+MbgHkf{FOu0v6M<^#(M;kPG656sRlkNyvCb-+ z@s%A+u1lF|eRS&(PpOs`t1AZROMx;j0Lu7Pz_5l41(bWw)n<6M>sNiEa}oe+l#^LAlFcq{iUSfJr5w+#MwK`i~NaxRU0d zbd0H2qGFe0fn*%Xw8o#DFjn#s(C{X3=R=?~66lT>iKMNTY1?j8Q;%lEAuef1OCIVt zN3AffiD4E)<~)oPF9vGf09xJy^x>3*c80V-ecy7kBLu3cM>FCOmo%gm9u4~(Ew;pc zKiI>f@&u~n7;g+lOR)mz*h(i&O4XA{w@sj$dScd6z8d4VdD=hTCav%&i=M5uJ>#A< zJDAV7;ZdnCP#cJbvq8{guHfcd=n#+zEfRrh(bJp^K!Yk6xV4&V0!S-7E=N66VA~a4 zsSL)f`FN1O2-YjF0xcil+UZq@4RuD&9v{@_DRBShdVYNiISDevu5rP&b3EnU&A^Qy z(vVhoke_WI-`&rwJ;&z2l)F$oC#z-|&>Dt;wg{A+2u5nei`Ww6gw#kMlx4qzf!k5Q zU!MSVfy5OW^EnUbQf67nZ_>%@PM;0K2^VoYBSqerQ2X&T3T_Y%+^2<%13IDs-RD4K z2vF@$9KjvR_l6<+S&+|T?+W#HrtdrD4&x~|k=%08OKkY@idQHVEe?Td>d}li+;lMp z3uPcZ`8@IM*1q3v!dUn+Oqb;t$Z-|vEqTw2=l8Ji1p?KgH+0?u!&enBsb5F?ff*B| z|KIm11seU_EIiPfsYSx0p=8@=!;>&yycza0u?XTts2R?d@gICDHTjq#)( vn91S9;m+aB;mhH}v4~?K$6Su5r_%oi_kJ@#1rdiF00000NkvXXu0mjfmYY*6 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/akgregator-info.png b/doc/kcontrol/windowspecific/akgregator-info.png new file mode 100644 index 0000000000000000000000000000000000000000..c05311f76a0965a06edd59b6b622e042f9ead39c GIT binary patch literal 12229 zcmZ{K2UJr**KI=Y0jbi91w@*N1nB~Tgi}cWg2%$;n zK?o3vgc6EC=z$l%|Nq~5Z>{&%O0w>qIrp41d-gsvH}}3ZGSFpa;AH>+0L%~cv`qj2 zAcFjTKu1GvS)&4j005cz2ilruLDK{*B!$CL0OdU&$#s)(iK6G{tWLsDH(Os#EjlW8 z=5O?T_ii|sj`KYJqPFv3|7|1BwoK=4{mvD0VRs;;+av(5Hs<^E&Lf6mfZ*xi=6qXG zXgGd~78 zyXE4i%w?zeYAG)~cVd8;A`=#dCS}X@@XV}_BRAC#8qn=xUa_i4ZK5uMs^7HQCskMC zRnp{ouKmn%3~?}iETAGCpceFao;xWpX(nR708C6mXxIh2X; zUW!g55}B({7rX|XE<3r44u%nRhJ#vtr>Y5 zi5~CtinD3-q@VRZJrGcYqI>@nl@PM3BzL;#_2mN!rC^u|5j^#^qzpWYQ8V>4cg9U( zFx{z=mOn>FNA)hwag={cexthULi>Wy`Iu#XGGY~*C!>v6p_-0_hk`;Fl^2!4SoBjF z=x!i{TgHxqj}N0$HsN!DWyMt4AHJWNnI&x!leFte$wyEpEd#Z`^G8`klohPvJmaW? zujk7&X=l&zV0rsrGGN04h@jk;LH1VWJmvPj=jo^IE5EW7yPJIR&1@}xYac?dHr`}- zGdjHf(!jPo?8!|TnRgM{6|o&1^MrG0PgJB=uM!1O7w79dys;C0)?EA{TMMsp$;K<< z@mT^z{HKDfzbgjqe5opeL-IU9xde=gqjruiED^0L4prYx-iGuebJQd3%x;(mU&Z&h z|4zVmgh|_4t$SYJM{9yEesC^;{S~2x{p27qyHiI>x%0faW8o}lz>HKoSGa)F&8W4i zFx^3^bF~}6XT8D8J1R7L&l_A2_m$$&PX(s`&1Wy4-7f5x1J0)@>J(2c_091K;Rx%X zr2ARFs|Dn~r+R;nF9OC3wI6Qw!(*N#_1zsl(XG&O4eyzv8%qk~CdpbhvIU3P?pc*z z{sHNU)Y|*pn@tBAxQdgz^_(0-R46RwEx!2uv zAigKxbMJ9WUT0?Ln(7<=ey3EGIb{&VO0|_dV3G-K&NAi;;%O!)>UlBd8n!I6wY>d% zC|6Zd?fj@=SRil<%c-m$VKv0oEC1tw+QU@v)p4hqtl|`H!{v&nEYPqUryn&>d7MOC zxVXBpCF)e`py|R7s8_*s8K{@P#G?B$yM{1fg1r5{VOx=rr`71Ws*Y=gf`0bSyF@~6LPhE&gC>rOoxg`cY0uB;f62g^J*x0EmHK z?t70T>;zH(W_q>b=trMtogZqpUgFeXgiVc_#BLLvx|z*^W<
DkCE*#xG|30lgd~3OsdHt6{(rFWfw(@X0 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 RjN}WZAw>RhV&`2Eaodkuf%GL>xq5;Y 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 Hu0mjf4%Wbx literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/config-win-behavior.png b/doc/kcontrol/windowspecific/config-win-behavior.png new file mode 100644 index 0000000000000000000000000000000000000000..afe9ebb48b8286a6f32d2f5404a84808a908d63d GIT binary patch literal 31261 zcmY&DU&|t+S#oZk$xJxKbTigo- zm$%RR%=gW_f85N?&fe|b-tNra{`Nk?bk)g-9}oio05VMt6*vF@ME@I_g!um`GS9_~ z005sgO%=uG-t&7)Lt_?3DG7gF`oY6nMC{Y--zj-@f)&Z2#dw4sFZe2-ex%{+?DgW) z{cV=@pLyIL)5_$+Qg~{mvsQjy9>Jpo%3{2ol-%pCU)4eOLGk{!qUDPChgJ?N!kf{x ztW^!O%ZJOseR_iNtiGO7-doeh{XI5AHXp{oRSsAMS$Ee*3jRl1{R(Xlz5P?zeD*H( zB(Gw8dN2N{1n!@F28L!}`yY%_KLp@$7KDIGbFHZjYq`xfaX1mTU zPIQyTX80S|jHlJ~?dk+qf&Z}CRcRf=x<^)DcH>G5!?ierl=lT`$+F~yyqji)_=c2# z`2qz?i^xLnd4JiIF1f6ywa@QL?dW@P;WjkICsc9C7hl>Yaz|d&_tUN5uw~*b#QhN)>usT4Oy`xH z&t8iMg6Chgbcx5FQ$^6m97Eym^6vTY07GA<8-?wtN8m=^GR7l2 zK=aMwMYbD;#ckw00Yy%O!KS&++eBRJK6G<@k6EH;pP_+M8wF zeyiFA8EkKz?6hvuY_2c{2$gYdusL?B)yMh>r@Nq5jHe73Rvz9vummG)EwO!&5TiY9Rd=Dzt*DeJHwyrVr_lqQlTlN(bn>!}*a+5Th7M9r^-gYcO z2WYR}efcMyn{y;aYWI%2nVS~=Ui~r!W497|F#+kD z(_2BF^`@gDmV77do|HwVX83r#6yhe5UNe-HN8=SPIsXIq;TF5dds6uPv#Ir=zG zR~#>QaO4OYEqBzJU2mxmEwBYPw)_2wUeDsVs&JY;NYX!Vky@KQ#ZKrhx5{s}NW*Pb zI`6iRHyYY{lSB_wcRrMF|D1|XIhVg1^xe>$9&6;dn#++tJHD%^iWTkq9C$h~roJR; z)0Go{JUf)p`R7(|_82=c>-EWFSY7;n^h3^Ngy=!pdZ>&-O-g&CN4%u`rDwlh>UkgI z?zY=*w51T+;_X11{ekk;uZ|o+w#B=@KfjHoFrRl;-1pzRw*+1@*B;z|lPOrqa#8DY z*;n@2cRQ)ex$YJ1lPtLH!&>exw@F;ZVh?V%j4+a(aZHX(LD$hMY(XnyrsVTSoe%NB9EvlcJu+Ct$-@FH^**8;Fk`X^6YM z3oe?`ugopbwfqCcMHQ|St(UUdx$MEB7$RMW;XCU+)-SB$3rokq_P0g$ zHuVpjO{{oM@q-`Kf>s{HtbLRM0J(>MG5e3zh*!Z*!+uNZ21S_$E)5xQxy1Y(?ETz# zqZeYl%bLD|CKdYL-Wl#Hp@+p(TK+z?`4@*>!FT&awx=)DeY6)ooJqw8rYa6dmPoQj zBEPdDZTxXyA=lBgPelgerD6i!OUdWvcLidT;h4VO3qFFFm^un5`>M*{99Av!gI-%xQ?W<$EJ^Ot}Rt2oe3E4Z#Zw^Kz{cv{C0 zHG7jgZ2{0^1%Umd9un5$DckJ_?<@f!9vCtFuz3R?t);-&#Lq@@Pc=iyyB8U4LTCW< zY){SD+;+<-j*y|ZgER@aB94o=-EAwMZ3-2#x^MOv1~<|I6j%aW^xomUSUvS>J6W&t zr(kz5y$(9vZi4$+p0}wx=&=Wnl+b#M<%$6$pp<~_NLK=8dR#niy_(Ydo?tFGF%>01 zHxQ%e_^RLGtCBSyVxe`zkV0g&K!N>9T=>fo3<(^mnpYDS8HnVN5XMtm3*bWUwSkrV z$Vhhrid;Zkki4Iena)JmF&0n4NqIotp3JV~a=k8cc!jm03@4nn#pS4?oN(2K18<03 z0+a1?ed2|_>DgijmVcYl%0I$7>TPhW!k6dQD>hwd1qT;YgEd&YyCXdc;*z;} zt`H0Dj@Lg@SL_iEL((SbGq-QQYbpFN42%f-Gf2?opt>Nt7`umC_=Ka&61Npy4B&M? zcvo_#8<$Yy9e~3p39W*HOqLw5>&uFcmYFU$p1Y7%_b)`t0;9`I*q`(PW3XKh zuma=!2DJz{suR2S!}uN3tpd^W9<}s_p5weUv?7srZOkbFuNdaq8ho4++@C-c5wDP= z#Y$q+B>A9suw5-C5?vz8H&(d1n&U|>WQK{IJ18S$knAt? zs6_>tZW#LUqc4BW{ZN6G{FFp0Ee-rd)sW^zFO<}eG*fL0VvAmaA~T;BVny&p@s!#C zDDHBXz$CZ##q9h}9p=iaoL7#ZdSfJ14$8TF__6Xnaf?bvhOTQ0Bs_)uj&pn>|#FJIAH4P`@D z1J4KuKXxKh@VG{(LEJVF=UcFYmW7`iC{%*k(&9npS}YD4i3=kKX0RIP&c@WYkGx5@`u5$`q>Ym>}A>k_kz4Y27U#m#^R^7S${) zRpu}opkBb9YZV2NX*FRqed!~>=w}%1-%n4{$X>*PB5K0^Q zd&xj3iz9dR2Rd68x8j1M*u=3|2KPwO9k*LNQoj=?LGEsn&R$~%+K-oeE7_6Kx9bbc zv)OV?LrS%*>`Pb2sb>vm3qwk|vIw2v5b6q2eu$$JEteyY$X1!o%Uzn+ps$DW$Mrs^ zWKZW2QiC(hB*q9T?w?yYp2stG9qX+_4eBVIIWW$*OaVgR^ZiMr%HUW)wZ(?ldZ$4u z9euZJtbQ&+TTsx)iTQj{htGSD=4~mC()yx%ci~%#ZZbGj5UrvetobH;)F}l2hs(;@ z%PzBzRI3Lz$`qT3wD#}T0(SI#a7bEw2tHtUebkZFCOI_6_kJ+d6|KLV1*tI^9-!vv zWva@C<42eUcH=PimR0G!gJIOu8wxYaMj2N)_3%Xu+21GQao?_oG9Ja8NzO0{H!%3U zUXpTVv&d4|9(o`~aRf|k8H;Q81-RGOJvbbmk1kF*(BL^B`ItG97^3GSQkVGiNzR z0U8*)BFU-Rn^-J!1x=)}X7~7tGHc{84s-)RvQjWIzk$n?Laon-_W(17Ti~(w0h!nm zW5jp=D{ZCSYF27;sp<}z({S+TWzW987T(i-uQ(N6T3tI108zMwl`;m02)c?(I|yG7 zc>V6t$SRTbBVq~-*9H9pxRn@#Pv-UBMZGa$csbkp(AR3u6v6>%xE>Kf7J#4a6buUh z+8*@GVcbVX0(8Nbol)8F=pEHXYNLTY^`t#K*DLX0$;RL|j5Y`F3tVR%J zZGMaZQmLz)=Qnfn!8Dt~iPlOQ$t0_^9=uT=UE1ZZNR`EfC%Jm$^+Gs75pi#&aU&pq zo-LaD36Hm{!S+-?mF|m0XE&j}7T#lA-a&c&Q91i%I($C$mBmo?-bI8Qpj3fzi-3L* z#NR#nFyw)2!S**!u`U#ep1EO6AmYvO#u8}cYE!t2fVG^*YLd-3!oz*3z2(qY5uTEG zIr4H0!22}6lU-Hq)_5rUER@S4V3%H_8U=oRM5u=H+0?T7A-(fflRdOikZRRh{{;bb zW9rLjd$|afw&M=?k+BYsJlqtCSF(cRENgYiE3$q!^#Myui2~x%8b+^fP`+lS);C~@(x9UhLqBP(qZ z_5j$BYJX%Tk>6Qw0FJjV%NL$b5llB9@9A9)NZyY=Shb10luW}sbQ~}fP~N z8q>;uF2fABvLz)r$J5=z<22ZwEQDjHZ>HwKhZqF`Voy-1K~jZ0vJ$(gjz4 zuKf<>8>$pV$j@)i^Qm@K007)45L1Pw)wDk`o&aJ}%(m<^mI=v=0edO^wX?5UNt>0Q z4Dk~y!oRo#(_gPVHV=WS{x#^YNOYw1b}b`%2Ox5D3&5ixX07l3Sd1flAPiEOEKd=i zGSMGZf;9J-L0`vj7_t2%ZiJERxLNWkx`EWC9Mz<>3Ap#j{6kV25K^i*Cc9q&$pC^| z!e}t%6JhQC_RSAGh1q~qT2#G)EW7%Jj$FzS*7RrzHfYxhjY``LMx7-WUx9>d9hC|DwAr1vru zlxhwns#73bV%73(U8n~})uN7B#ejD4(ADeiP;`E#fbQ~5E|(9-(d3tK@3<0(Y6Q%LSsJi=6VIh61TY z3WsNk3T5>25*&r6Gmv;hk9%)cyTvyO{0~3)$4g+1s&q4IeW9SL^6Ibc!0>g|_pczD z4ZAC?z3!dQmyP|1@@Z`h*>l%gaVT!rNr;3?MZAGjl4h4??(iUHk)7e&y0B~)hx4dMG!NQ$b382^jUXrgk|XH042cx`EcVHg>EP2jCI% zpj%Ozqsin2-jm4T48TBm-{28hIpglDNAK5x`7NhpvVuH5emK02_D*)9+Z0M?Oh0Sg zL1dH-sb~S));FnxlTw~20V|Ab^D{XCB zlqU}3;KLa3Ys!LE#TXsvGb{aL)nUy~-6^K!uVoB1PvQg5o;*S?x=-fsg3Wv!Ln)0O z;#sbla{R`$NYTE>BznI5&2Fb_1!G&=>ys};=n67J1_E9S2OCiW31JtjuL58TCi-xZ zK`mnV>P)A!@{XCN$x;QCIe|3bo7hf__F7gaZtlS-<=>Guw&2tX5m2!-eHw z`d_4Im$~smBrTmA%zP>qme|?hMufGu@LGfhp3?;ekV$JO_e+*8h}}R~!7il#uGXsX zYV(T#fSt#MZ9W+XwN*8m=8wb3R3(=-;_^8~!%)|6U>}n`qshE`?K-yJxf@8$Lq^$? z_G24>3Z) zPnG0$@daIHnT8}b7wQtqNpz6YbBTA|&sko2KnMzzdXjPSyK=B+U>1Q< zC2T8%qc9f)od49 zZ5|L!pK5-tbU)&H+tBw##$!C?vyU=@b1XGOaB?gXIl^U?H^U zghT>2s|tzw}RAddNr_J?5GsU`tb~1mm9%n#usA%`lVg{R7YU<<#@d+QUo#G5e(QWpMtQ&jFqGRzIsHX@yEujoc%p`5 ze=?8&O8&!k&6X>aH?_AG6`yM#V@-t}{Cd`azt3J}9+Z^4cKE|JKL(*SnhJ%G z^meYb$&$cLNrqZgXYC##i~<56J4~_Oog~#8jeJ@G_0K3B#9ioLGI)U zUzyN#99s!tTehWB`Nc+?eU>+L-hwLG@uM=@D#4OI2_*jT+gemertdqkFXKl$U`#om zp9lqGFtzFmBFPg5`ZOgjO*TO1`3}ndadlo6T!;!1#=dodMb@ro6oulB2NwI zlkHbJSQT%+{W@l5a~-RB4gi@gIuWbD_g9lue~3-Gm@umjIOQL>j(PB+8m!631^V;q z@~rG`w*Xx zps|Wuc>`c#ZZdW>xi|0(d@nSz(Kw`~6%3z-Y~>G>I_elE%P)!MUxZRVeLrHyq_2y3 zjz#~Bu5^4fXx0T)Qv~WE2f~ZYem2#oa)LhjL{mQ(Ldg`bTab`WIuUw1S8-lO)#IoS zvJ_8i&*&jR%Ffb;gT$a+{YW`s6znUlj}S~)%GTk5BvACxu+V@OaG*Iijd^?pnoj$J zffiZR_H1WgZ~1QBFW@Ef6&Zf7yI%3PAO|2ZFoqhVP>j?|G4ev)khvn(&+5i{(?Zv+ zg|E12G^S!x=>TH$weXGf1yWxC!){p_#rQ>p;3uSw9LFmARO{7r)9r()*2R}d>lo<( z6iGyNU$!(c@ec1+M6tm1f-xlAiKRM;fRZ=|ZD{Nh(18KS1BWffbel|5EIGCTGi8*x zw7w-ktMZAKc%z5B^%gA_38BaQ494nbQia|4j+(K2*`lD_a#4>g#Cq@4iUm%Yhs8sy z{H>N_D1mI_%T)wy(RL>U0Q|!F7l~sAtvKO_S1VRFZHyfATRvv@Vi7U#`f+=93H!a` zd?-;fo+LElsqk7M%#YuSeG*?*=_^TFw&7&`^X5Zi4FFzLI9h<9akLVko>9llZYAmw zh(}${?MP3`@nVH%Zq>Fu0I9C`Aeg$?U4cj^hHfi2$A64qz-^W;eD(*z&lZ@jr?7jT zg(smA9v(^qZ0{)NhK$3CA>s#3Af`f1y~BR5v!u3Y-0Ww#EC5@Hb;E+2)8ys&Re{%5 zCwDA%nu!7TiQh28JbYE=_lvd&kKmyurd^Qp0n`yoR@mRlUQf}}qN^3?D2kVJC)DAR zI-@do=7lPHr-&EU&Hh@${`>OYr)1k_0e%B{kxyp2O2T*+D<7R7H0U zRICg~>vO-j=SiHW`5S(anqgoET4j;oS*Iihcm%HH^QW30$a>J;KNLSVVR8pg9dHip ze)@sSPy0I2c}I1jChnB$iV}8Qb#y?(#Go-VB3_0#ScdhG*+zJU&eta(!2shTn43q| zLbXt#qE>)mSm$UGt`w~_x%`q$(&+mtM3v-$Yy7srS903g80r9Qx|Qs$7&5Ku$+ZXt zA>Asw3tNXN`I?~LjjncjvV{rfxuV- zA_#j)YSXJ!D?G7bd2w9%S(a@N{NGX>?EJ?odnd6+Xdqt@1;;Nz zwAH5!T@{NSa&uIGNb56`i-vm1JuSsZIu!Q#5l%EDGUk3l`1OK`vf_X&`wMRKTi0K6 z@f`%5w;(~s{xq|<6?`LC+xc%3J+nSIy?pTwXRBCTaEHD9 ztW5nBe5NHU@GwhEw|9ZXwmAe4>L%}ybH@yFexFp3A8-w zK+r@cN%_V+bRvuMpyN^d8jqhvW!~xGf=(zg<)rh!tM|nb z=5abuY6;GFO#$`O{_2f2BJ{r=;W5;ZUSD=olZ%=6^ICkhV=Q(&Ir?c&fFVz!r$0M- zYl`Bb^gY$I6?qCAyGdZ?t70exuBm2?Sv+w9ysoSu(R+t~G`P@rHaxIy25Y<7c($o+ z9!Dl^_4S`ccFu!}3X#<~Z3v#B(>|E;E%+6keJnbZvnm08%{D~fC_ z|FXI&II!~SLH4 zQix0=7`k%5!ooobDiHcn8#g>Lr&%RIX+>;tjNo8@ZWUS!JD3L=03&#X`FiH z-#s0l{G3t+qX&ERg71;7iBz+P7m1bc^b1qy0)7}SW&;=GF=+tqi#9fD!+giB9W-gN(Q1^i35T~=y$8(gl-<8Uh%ovhfq zIy4qo(B=77i*~D{ImGY4gF?G@+0RIS5Nlyj8?^$^Zr>$s5J*ef_>}~e-@ei#;6q1j z#8REOj!F8DX*qN`7(+!#=P>I?e(m^-M8mwY-7IWp_(gM*7=uNXd)ZWqYGD?2lkK&n9Jpe>^P#5OgOHNdLj&F^`eX(Fl;5 zL5tsC*^<5C>ZM;N5Syvm)E|p4`cST1+df^Fds-8Bye`n~P7vApv@PJQNSyOBo0$_} zn|U?4-OKDS@n&HapMB88n(j3Y*HJobFex!dWPpVbRGy*KwXgoby*p$bwNNRewVL~g zq|_&iBVC517#bGxaBr%!9(_~iT8~$Z zw=Euw^RerH0T_gtQ&e~gO>6%dR8hdPPca9qCep#u%i`P{ZI_W5Nd!Y*JL<$hIz6DX zS7r>>O@@;<2SkZ?76$Lf+BAT?47OG;$*}IQ)E8(By1DM5U*D*Ae!LsEkJG|x#Oi<& z|6rxjLt-pBc)kfpaAj=NQsf6xf^k@lkLmwQ#iEN^&AfUDR7em_meo71)g*NY&5eEQ z@_IKeVv}sxMLFL-uy~fD_4|X|H#j6oJYTY9s_Igf^9}I7EQWU6RCIPCpm@@!F?ueT zbcLt3>ubdISe@ zBbIM;?6puX!XdjZ6+->4bNbWWh0cEZlBuRgVpR>HnX}AMcQn}4nUo=svf{t0e;sx& z*|7~W$~&1QVA*Rx8T$)ALz=W2WK{VlFNG2)0g%izdT8bMa=V5M4vR0=^mDWTU~O~= zu7&W@H!#U@e*$j*J!wi!A+`vc~1 zv<<2{;kw-MBWpj&&7GHue>_xpxc%3#q_tN&HhH7cV9W_aqujC_>A8ItsP8PD65-*t zVkhOHu9>kJ2IX-i`guiGAT*F-LJ~=+s`jz&F%&A#h_E4nT?C*HJHugZ3V(Sg2g9jYR;rkmzyq)?iKg=$g8sLjSUXl>J zDQ2%bd^7Lf5DpD*+XflUtF&+4*a{og++x9M4iW4)zcE00!i%DlG*O!>5*g(lH+?9Z zKGX>uWDE!}ve($KVo8^zL=^dAQl(Qc%(DkTxV;)h=W;?as%`X#8EifRMG(ne`0veF zG@6ZT>@KPKCI&2<3j$FmfQ@0Ci%~7dQAxXtnnC%NskTioe?n<#Hy+x^u3NI>fHhmb zww}I`cLOG!VFr_pBYmnK7dNS;+SaAHR^ai1L{u!~cDEFvmr_xSo@a=097y$7Z`fez z=a;`|ROGx0bEH$?n~K@%BKF@Soo5ZN*#dn$rlb)u3pX_Ni(>9qSKiRL~4=i zq-J(75Y`?NXZmQFEC&Kfyhkj#v$5+V2DgU9lWCXY2(^u&<016yGVk}0$uP~lpA^dm zpv=GmNbysdT1kLde5+DPkLIAsj-X~jXnSXeSx^4ZAc+p@g}s)dawmWwLGTDD5~7&5 zqB>C%=9-S>&91$bwh^mxD=g=80~sWGh5IsiTUA&+f2ZWEP;zDFhw^cmTkkwU!4iX7 z4lR5Z;3lA=h($1 zwe#83*kA9VbUV?~Otp*syQ0c;6PD(79vm$deZytueMbKL%q~7l;62l4?IjJxLlc(` zk4{{eIN+s)=RO_bHUr~_uZ%hQX}zrk8e z{!r4)$eNZTjq}pTK+KZbE}|>Cb`(V%KW6>;90e{9G|U(0TIW1$oG`Xrl26pw!44bsD`yYL zNq2$JZff7{BR}Zbw1{(y3wgyT44_Kr34}rexP5Gj+=oJx2Tw zug!B`0Fsl`z$Pj$&G?Q|$-aLuUiArjxpSB2gWz{Ti3zW=AN71tWYVZ=>M?3e zYtn*kU69gHPa$a8{6UmVKURDbeYHlvc$eu*Z{RY6RSqc3{UBJJ{beG^uTP6*pmwJd zJ`vn;M8?>0k(Fe`fYgF`o?!CDP`p2Y z)T9vq8g0!x)sDX6lJk9YI~qki!5dtWJWNfSo1UZ?Im>I!-ZkkF;}xPjHdQAp+A3j=PO8-K z`B)?2i`>60KLIuVUEqbPnX_TND&%auhf+Do^X~k`hlL%qFMf7P+wc?q<`!`d9B7n7 zl8|U3UM;sfO9I$@NW4ewEF7Hi zp;nmGyv2z9-;Ex|gYd`>6@YAZ8(aWUqS>c+g3b<}Gvl@-_?|ZTZEYwIb zyzDM?0hKBm%p<5T)|B=>eo2?qgoOZ=@5>ujOXZQTJn&iqM+~c#Q(s+A zK-XE#_itW1LhKZ=@Fsr@jMy^A;Uji=>2p_*p5}7eVhHUV>2&k>m`XLQ+=*;*;oU~+ zET1-^F?{b|?SyynEy~8LZQ4{lt05LLKlZbGL3L566Mj|k;-X1edZGx5 zzsvB-!h8jHD|Er^M2*+Z7+k= zximO4bFaW5-`HD{31X-gWz+7p2=2Rkwbb6U<}&4`I-26T;?bw|rgIbp%4(>vJG3fx z$@@+7>bi%rTu9-;#bk2)tV9m8ofXHT3qqk~zcv#&sAu~YhxdxC2&$?wx7`(6`-%U2 z^x;tCZzGqthf8>wm)4gZbcVrYB1dIYBS!U0VY;{dOPCC2x$DsY^VYhLFhUJare8Z2$dQt8SFYsX+;X7e0cjNHN%ZV>w}g~^RGlUv>r}M#N}3+RNs&m# zlUS?Wl{pBw{V-(F^=VpQamiq37@Y$(n(f+a>Y^ukOmMbP7fDQXc%HbZ3MbIH@_m~8 zW9F8FV*$t)e)m0-%Qz8=uM(_jQEHhmm#yruaCf7Uu-;f!-l1KV6_5OlAuC=iBica@ z{oFqk!-^>lw%-Eq&dmQ|7+6#+7iTRILlZvjXoq$e z`)MkEJjMzCOSW03JFUH0Q0&+RA_onJ#fkHJV78t;P4wh$GS_z&r~EDd*p+GnuI(F~ z@zqIqKj`FJ5d2?4EactubC9;Pz8i?mnp)%K>Q;R(qg<<(@GHNdK5HP&Ck z*h{h%EtNk9;>GUQ?J9hWdKNMP+jVHCOf*yc&j#gc3M*KYZ2Odnr@7`oZE3|8Zq$U>K~! zUtxu^u=!vwFTu;ljUY#cavP7}mX}acIH)cHjJPJ&-MP*n;)F3I)Fy#4rAUZU2~yc@M>k01*(GMv zZyPD9YCWgxAeYP! znqoKVJa>t_Dc2Gf%C9xx)rkbM4kBVMZU8OkHbCli-HP61{Eu-LUaa{sZOzS@e{s_m zv49bN0tlip@ox1Csmk}K#BH}B!2ae>+%6-F?^}p~yZLUcev8e=$dYTVD_n;Bx2$=q zJtg933%tXJkmeG%Ks>Fb7dv(z7(T4KIdr2X|7Hj6t0^*-a|1rJXYIaOkl%T8cAo`{M4Cq8FazmL5tb^>^dEl5>dlz54Z4x|`KjU_!f8ux9#N zZNU}}l~(;RG#DzyE+NnGK;)EWy8=fIGk-S5|Cr+Z;RQF6 zW3n=Jpe|0M`)%C5@IWo9zKkN~wwI=cj~*_Zei*Fb4BkFVHIWg}g6wEBd7W!$LAiGa zF6LPY{b4JPa|pI99!(-+tY@b0q(!X>c-ToK?99TI9cdeIOLIizPE$P<&JYQ4vhfou zw#+B1>|JPjF7xv(Pg$w|;IbF3vqis`-|q2Vc}Dj(DPI}*-0as%VJfp(1oqMGyKHHQ z2B`EglBuZ6|Nfb#^H;Ob`Aj+w-Wj_rIH08k-8g`n^W5s&xnq=Qg67O6CWJe) z2TAdh7C```t?HotKJF`bSyv&M^1?d6ZE#n6g8nK?6`g5XvDJd>-#i9CSP(B48ph{+ z_b$%1V!08gQ0W`9LhrNgwa-b1A1-SXTx$?*?8NKkoa_!&lcPzek4XLfFjFL(;l8GP zsm2N~$mInKE$%Uvov&r-wNgy%Eqn1xFs~YnadJaM1j++VSDy}nxC5dahvxqbPW6_; zJtJ&a0JyMn0lVE`2@Q_}_w5FX=KiY=o=q9mB09UK06MdIpTy2@pIg;~i3|J1;KC9V z+XMt?6?1#z)fZhtv$YA`+$1HDGLvI3Xekpz#yWm#6JEu%j=p{s1X7bL<O>u?}O&=L7LU z9ecOfmAk$nUC-K2S$np8D|mC)1QcCO|E4l?1G=8a<_R4ucUjv1he784_uhZm|M7S! zp52|D#|i&0`#-8bgYBWqZCz1H&_xH%P>|e}>5!$|_4sjW5v$4F*!G8%d$~2?v-Poo znhz-ozQ-h z&OJR!STRpgxSJh1R=;;ebYA|G{A;<^Y{B&I+Q#qy$mK<4{uBFa6*N$q^nJyFaMCQSdx?^dyR(9OpvzVzo_}k-FPZG*^|Bc3#P}7(&44kVB0aS|!#_dQ+qQ{dx2m(bcAmy4g)zmE)v zWaWwb$*gDwx}RlU9_o0V4@(v~{j>pCe(`^`8l#=(-sEtPPf0a#|D8>GHHi?tVhK3l z4z3Bz4PqOw#eZrB+LJ^Es7a@Fii~%TAd71R3QBHkh3yZX><86osG#^%z#UQ1oTxY_ zz~?8RO;5mV8e!xvn-&1|ZH&|muI(&^iZ`JuDlMtR==CbJ^7hdi zD^7fsI6#pAvaBz7=n$uiY1`^bXk7s35gEQpEK4n9!7zTtsV-pJ#6yS0tIkqRn3K~r zo)Ep?%&xS(Dz^IFq`QfL@#4W2nBY#1;-Li6QWcCg(kg0vKq=wb|K;rhOU9dyDYsg` z%whR|D--n_i|G}*9+O>^5I0{y-mP+2{bpPJ9@?FyB8?(1^#63+68z;6{wv|7$jQ$m zX*JeuJaf}diVo-HpHQzhTPoi0$&A{rd_%dr*B7AC;gQ4|etvCfU2CGsVcJeV47{rX z$vvGuf4FLOoqleV7l`HDTZBiL3#a@J9jQAy_#*b!SU(P}&0o`8`hYI^g?GO7iyci1 zNxO;R-eeQz0D7BRsfTXOU2f*~W1O_a*8ctvX=rGglXa-|fz1JappV`Ud!T?NbNe6u zyzz|UhMmB_mIN~x!(Wr(Cyb|-YW|O7Uat~Mn`YEl4=Bl+8jy?9@7$7bad91y;ZFD; zKju%xC{1T1j?|C&FF03x&0n5N`*h1f6YT!y3LH@oN=Sf1NPbGA4`hl86A^p(V`~fC z+Sc~Ho%j4B%$Mft@15kQ=js$+L-kc6s`9E7ke`Z7Yrr$YeVoeQ2-Vfa`cx_)a|bhg z8CjwOg)LHF&JbAzHhC}&+@v#_jN)-~7FHz@M%t6lvR1=pSo*L@J7F8eeG|bd)98p^ zwQ0E~R+1dVhoto?cDJ{V%E}vQ#UnDc>qD21B_%kd(_omMO=Dak}>#qI_iHw-l&V;doT=_6LcTspN>bhse%d1& zFm=z3j~!)?``*^e2>9}cB&v@9`RR;8v%y5q&%PGGs@lv z3-BC2cN~HUmXvqfpm{D{-Ur?U{At~4V$kZea80!XBe3>?FIt#z;qnnl`$xJT;5rz3 zF&Rn1H#whtC7lWP_KI%57uAn88b-3s$w_$$=}JicnV%`nl8%69e@JSLcg`z3sL}?P z30;b?wn8~(P*(3+h}%)`qw_x;eTo4KjbUwM)Ht^e%u9Gv&uUw~)R>(@>rDbK#b zTg3NdsyS-%3o16|Z&qM1t2io(9ktfDwh^vk_vDp_JnKKJoL5D_Wm##0UTMwoEfefp z;N4;Vxo2qXLIDR`JL#Q1oksD4!5^@kxpGYA!(1K8nS+PmkS_lJyKnLYoODKA#7 z8pfLdqkr!C-NuHLNBAAueT7j=<(~#sPNe7%a!ozPZ=cg|jQ>e8+CTeIYhuXk*FruV?K%``! zEs9Y)Z-jI2tjV-LzGs1$Z|~qHZ#$Gkt}v67o^MIp=9n?|PN3blx+z}2E>^d(!I?p5 zsl0L!ziSpF>$>H~+i0)j#p%=jY$wcOpAPZxYUBbxrPM-G&kqtS8rJHGkp3Zr=dTR7 zJ|n^vi$nML6)=>Rmgdg9Au2UsHWxqCwpr&v&pA%LJAKOx=a*rBmEy-=>Ar0%%&MM} zB*I0!)JR9SIl5|jfAB+^f?|%3KH@zsB=Pwd@8+1a#kW2s=Vd|P|5#~qkvo3o*cj3K zGd_j>bQ`TFa8nM?pQB2qD;lEg<#zrik<~6!#F7 z-Dm1?(Z`R&uFns@W&Zm0lK)X7&0~DPk9T+e4rQoiGs@Vsw~wsd$~ZQ#mx)`iAamSk zfu&Xkt)@yG+?lC(wDm;(n0}yIXeBF)Y=9;>>!#3(U@{Zl(AM( z6p13iz?Zr@nvRZ+X3zZx?$Rv2zP?9);uZ268t9gmmU6GKyR$Ea_yDxZ^6;zm6)$$~ z655voc9bVO?Fl)iS|~=Ai{%iM>DoI5d9ub%YAG{Lgk|>__|=(+p-R+ARw7B!$F` z32dQe+V(98dA_K-Pz((h;p_Y-5s7r6yxWD(;bvigprCQlr%#_wl=uH8{g^8X0OS8~ z{ca}EfwIV8hf`yXkAKp)-&xi@_z`|N{Ui}po~&dJm5r;O&iT>X zZ=#jXw4IC4S5?K^5=qzLW@`Jd{QNYUbp>rF>NOdMlk$uUgoFPvM9?@jQgRa?y1IUT zTMgl5mVfVaA#XtzvJ=(O;=OGy+>cN8t(8JGf-n~CgQpFu$OR_8NQqx&-X|H=v3C;q~Uw%0w#U1am z=f4sc5Nb7NQut7|zvML*hC+<)0fFg}##i-RBl|Db=B!A9#D)ls6+!Lkoyf z72QuwTED|^OE_IFjaXAZl8v<-LwrDYeyHJmN>=u@wwjld!qJPaTP`2461M&lVf94* zuWs*NGSS7NfhQHU_Q2hB)H`y>M+Rxy(i2J=I-=64Cp>|j zov^FR;FL%MQw!ZElT&b&Kjm5j%YE;Ey9N69Rik?6QYi^K92f&`y^gjfY+~Z#I0Xbq z-ZVT&6*5=y^OM=x-BlF-QfEJwk4ED?*5)K8CWgV`A${>VqOC?QfJ-LSyY zjf8Ywq?YbZ>25^2VOhFimk#L$2|+{}Bn3fI>2ALD_r33X|G59`IcMk0ndg}~bLZUq zfh?a@)x3A>-JPd2&x%PCF7LxutX_WWbiKJh+_KBa53D%j)B}62Ob6~V6+%#GnH^8b zPH5|dh>3PA$cI$-O7_Kw{85_c(Wv)c``Aj&>0zo1SVMSTzWqG<(6Q6ui5@E5U+{Y{ zo_xZVuV8ca%qM|rdh&bJpBXuxA_A27!a5`{7U)5kc_c_#nbM#&#V>gu>j@9pVh5!1 z*#hu2qh2rZ>yo;XRnm?9%06;qTk^unzusIg=0`vJW_*Lmj6SYZcRU4(cI~8pTBQKc@nyMnidx{Lp_NI} z=@S=+>lnW5Tz~&bteNZ}`Sle`BU){D7ar!V*7`Ao^9^495+}zlvGAKt7{+2<$hZAM zT4wR;-q{tZfR-`oi|BAO3P}K0j%xkj?c0F~?6UH5%<%B=K8I+ea^~3L3w19PhaZN# z*H3p%c4(~M&#T-$6wlINUhmaLLOe+yDu^6}X2Rkzn|z!VX}a(Hy7pQqT{Xec$Co-% zg=!O#HsM45&2h!lB=5h9DRQ5fPcY}g9!`(ApJU5m?7U<=Gww+E{Fw$L-^B0gh*na| zzWDu2hdgv&`w{S32Sxoz z8>wIQ8oeS8DhXe0}Gh)}* zHR{t7;vvv`PM-c&EJjQO-_6;A`LiNTjfjTd4fHpA_=-`@gglXpJ7g$-lq|xI2}iCG zmVfP2?jxZ`7elLbbsI!DX{-JIu>qd~ZL0Qk*5*-^qRk970FAMi(Z{X@(#~8(MfC)H z*Yt`+|11vV&cVGTE>Sa8JNA6i!q{HH#pLsO%B15B$ zxaY%g8Q%O#o!X};iq;U60un+cV~Bm%a$I<~`qgOF7h4D0q%McOB!YXqX%UJDvm8oH z1Prf*n1Gs4LkvRKxXoEmUk_XqnSr^nmFz0oLcI1%N0Yq|Fw(JNc9$X04lZ2)yZ;>o zs2_J^1Emr4bNzRRn3D{?1D+#ewc*$BnaM$}xEH28J9+>ch$$T!f*3%yia>18KzPW` z8o62exi~%~Blx-??V1MhGaK}8GDs3pZwXwEBGJsN#t>+r|F4jo)j_4gAls^ULVjqT zP5de8ke^@3;Ea@VLB=>^uymfO-&hcWLoBh>H}$HvaU%+f7j2^if0iBKWjMtTkWqNE zi`&TCZO(qD}{o=BBR?*>CnC zQym4cDwE zUeK)#UmDfw@%Jb*aGUAMOjFCcgC2O1Lr{?sq!e6T4}&KY+(!yA{qDodU2;*LVPtXa zMDKq?@o05u7+hS|_hwJLaMF2@lYtDx7?g|#n&i}y(f?e)NSAJFUPK%Aft`K-qPY>~ z1}+H0WoVpmI+U$prz1>OvTM=V35PhPuB6Fn@|m8v8`sOXq%7@g^97>upj8l_3P%=wb;14az|!DqGso5PvQI3BG~jEOuF_aMbJUVR zdj!1Fc@T;vARxR7Uh+O!q|*my4zoa_F=5bq?sfqRlkZVRaK6{?fWjH&UbvI6#qF3O z@H3aB^9SqK5Q5i}o1;T4Hr}lex`8~%)SO^+@(=ljfGOno=^5?9r%ozRtPg6uP0xXV;jCctKB=VkCRe?v zcT#;wFbz`WK=i0NcvN}x^I+&)QrcXM)w61a5$7+F3*u%gI-41{cBIDlaO_%4eUo)o z>U6WUn|>d&6?>WKyx;>p$+^V$8skb}(t_?^L=2@x3)h8WiN9Y^DFy_jyn;bG;b-f2 zd)O~T_`;Q+|En?V$B=319(0=Dk#EFLn8tqkezeeukYc}+YK1^^ z^5DtP@jOV8OjHVj&)}`b8*Sh|@a>uz0|K#&?sB}cYD;zZvea2LY@!Hr$F>$1p)B|b z;e{tl_T^(wPqixsLjG_)G;l}pP`6%?AKAtTI$mR$^!O2lfo zHs#^*cXB$%2Zrq+z>;RXqjDC^9-WrZju0?8x{UP{GF!sE{A8c9;F`I^F3F{OKRn{;s80V>LKIvID10=WtpIJ6fC|I%`cr>AqQJ;R>*+a*hgNx754%0;HjuTF z4qIoBe>SBv`N5k<#cZs@WIzWAr#j}Xs@3k4*w%56ojr;G3VUcu*6(g0(-4T(evQO~T}?^4@)kN7w@{)5O7_ZKxrTBh!e zFiV3`j3Hv~e;DLVehtOgz5PbSmnV!HZVcE8d6Q=U^iS4mMbADNNlMm*MO-`!EB_?K1sTr^*%X~2GOv!?^iy#|8sX?Hjxn`Ou4Q51G`qUeQ3~~wB zz($ArI5AL2C?i6pR%g?K6XDr0E)~qQ`;JHk;}Vhsf3ZPWzMWhi{-F)Ynt;#DuE=53J$Yqu2}UraLioJvn{I5>S8GaO z7_>0RIxzf76X55cEvu-=N*2*n4{2Z2-;I>g^saZjYU3mvW+pHM9_zhpy3{qzC@wFa z#2w1S^|BtnxEjPY4XBn$u80QS!DtFFAS*tJ%52Xu@JD1r_|*1BiTnx?OF#FmI@r4= zh_GP$#s-pDbi}BOCJy!Uu}w2!n{o2u(vyM3?{N*LB%gcvF)Wm)O)Y8_D5n3$6w4Mte$i z=A}zG?1+{M^En3X!H^F^1}p>ueRA#JK3Sh4hPSmTrine~z?>IhomaH4htJy%EVJWb zGrHtDJGGrT=@1j|bPC6^)WQB)eSNaO@bSOk>l9SlXE1_rO$_jt->$wE3p~BJf!Ep2 z3UtX5%WOgimhbg|iv0bYY8{}z_d{AxzPxY(->|8P>L92*G%#q_)($EbENG8Oi^G#1 zr2&LP2{Q8X(ndEo39!Psnx$$)7KGVBvJVJY)X0%U50SG?2ln};lyJ!#{GHd%^5n>l zW0GJY29U^CPbPy>I2=F49dhFBDIuUO@zQ=@F0fAdRl}X1^(pXxra)8$V`d-*z;n3{ zxiDyvDTHk2TrZWt9t#WtLXqYQeF>>QjK)Du`hB2K>v=d%!g6c%$92(+-&1 z&*2}Ak0gHJXE%*GRMbr@3^N5koLr_c9ZEH5k#UV5g*< zh^_o(^JdhbC~F^5VP~7_x%s-@YZ~`tc<|8b{P|ICmHuOOz}(IW}?l>lh7n%q`M$&XLCL5Ml8*OdUE@DXRHD>5=a`c_l&3{k`oSfbW3r zps(;%d7uas{E_CLWLO-C;M$*QMu#mUOSlirR=AoaPm!~zVTJSYb8`@HTW_8X497`H zjeS`N%gLkQyncm73nM^is(~eWOu7TqX!5+NYG9PC3Bad|I8*GW{2EbaI2Id4C7&UE zua#Bh#`3a~Mov%NP6uDIpPr^$+PgjFe?hvet@LaQ!<7{|l1Ff*U#&7tHZJuNZKX(N!4?q#W4%;V=THhBe8`up~Mfd<2Xc(Xk)kg443;@){lnQvrZ?Uu9p~ zBLgc8BWQ$MAdr`BQN=&DN~lDn!1#~>Q+258wq7$q>eQl**9$b> zA7t&EV%`V!G&t*}93WL%V%Hg>BLMvIZ4w5p><8%7PdV;Q4d7*X3e*lto)#d@m0qMH z+tkw+91DG|+hLh*h+(8Y{Z*Etsiek@&^Dr*gP47jgxWYD3f=!c3~x>voS96p%p)e8 zLskvL>G%aG(u2O*{G0|9KGQH3!_K65XjuZQ>uTYIiE<3{f0@DvpSZ4ck1&H;tpYY= zggqc`hx;AkrL`Cvp~n?N-dG8yv#)v>VuyWhRXB@74M&yBWS7lG2J&av=wzt*X`YE)%ZIFegznNk56x5@dfeSZZ#tjJkzOzA;%!666Z0A~k$D z-`*)nlbxFAl)iGqEy*TI`D#GImgOVKR#GU5Jrc)ACm{U;B31q00ON0HYiRz(8!^4j zicP0g1Q1~`n46ZEzl^;K)=9;#@#?oWB8+TC_$5P8g4ZCXUXqN|KQyL0vXVVpFAwOV zvdD!I{1<3-@MuO`48CRm(-+{4jV=0$h_vRaX z2LJBGUcL!|s%bgkijV2cMaH48@(MDh98(6%-`F199UR6HMh!tW+pB*ez(we)n!TEY5HUVVguCJXIAm(aJkenlyXgDzWV^}NUdEJzS2FLs< zZw#@l=v!`UOKxFS-5pm~0f>qMiy&RbWD8+z0XywR@)PhTGol`1uXPeV?@EK%;G1Ix zeciT^Z%mSi&iD?gPmWgCL}V~D8vt`d-|G2@Q~-w0%k3BqXuIBx1tBe-gjxPt z8w`?%=ts#pl+l8Bqj5^R50dkPz7tF(Qj0Uy)xmASYa~yn%!NHWl~q0FYhmxWZ6M#a zKivq@4%{Xe9 zYkI)2=ZpG3tRNsdiOeD#;>L(r_(UlOcKsW}VhmP}k7tf}W>C0_GWXQY0_|$^hU*C2 z>Gt+l>hb5Kxa-&5w4~=Rzm<8beKKGtAtn1nvX{PA8AvdJeHIg3ARlmld3@o;+HQ$) z<}qxlT8i!E{Z(sXmIJk*L0KX=QvODwL*8%6fPGOPJ~Yi%(9vWUDYxseP}n9ZoK>sf zKaCUrtG3QWLEDNVK)>BlLA%!CpWvm+Z*h_NHI-AqBHQ0 zZTrV=xqQ?!ar-B_o*}~O=Tq-PZY0?YOVkX?xMOPsX7VbeC%|QjGbO}lEH~}X3WDyj zX87#M3s#=kn!t7c>$~!k$zP2!(!2yOSfnH~UqqsP zmzUBmm8bthIga{kcejiUoVIOV&nM0_5_8qp$v{Mm#*j`V8`^X>b!-(YW5_ccW+}-6 zZu0=#z_P;Z*YEVPXtH}D@>h>*ht@HjRYX|zHM$0R$>+0L3u+EE)x(1~Sq?1C0zY1p zyS;F5`c_@dzM#F_?WuI&;GFU&L`=fum(ZIJVp73R&T?lHvCejHzG29wyPgyn4uNgi z^b2Gl2KFad@9N>OUT35K4A51?QU|#H+C0-Ez}6G+r>HwH(qh0R;lC^k46=zh z8^?WMCpLZw%ij4wu>k?Xk|O0oke&|+KkMN1mr=zOKmC>z)-hFNMd+YPTjHH3%dx1b z10eV7llW3me+ywbN?^-KNnrmV1@aU3?&(73!x}G?#Duu>;o+eNjr*wAuV3hsm zTL1RpqCP#&5n7w2EruOQaje@Ktfd>fg(2sF6!d}~L6xq!yRG`epkw3)t7Cm>q2uG5 z`FEW<0a(cR$ML)drirg=`~na8uZRr^2DOMW@k{Bs{IN=We>3uDwXurr znxc!w8|(7SZi6nNS*6B}4`odV;aOoo&TQrNVJaCuAjZ}#hD^q=`hcI zB>_^=2-7!oL0EDknU8qr;6=I2I~4@n3ZkM}((E;)4>ZwHNPv^Ge%Y&*1{_?Ee=8Nc zZtV2DNgPAKN?_lV%4LU{Y$MhGk)F4RH||N@g_hr*D3bINyA9YF`}ajcVL2l)$f-st zVX7)C@N~0r2As2=%+wX1ESWsUK>RWwSm=)b!+|{u$oGTPg?XI(_N*5UmT!c)U_Y_r z&JC)Q|33}{nCgy-vwLx`x)RQ}&G+0cz6l0KrUWoO5=l8=s;Xf8IJzBc=>ZMpy`ih^ zxe3f9xgcHIm{LSi;^JG7;fo#kB0->tdyB_~(e7&I8O#MJe~RS!L`7gL!2M3r4Gdb3 z%KTgW(Iyd@mEwKMZ6q9=h7_LaZcUHNxW`rm6i@-Kv9JxDcwiFFa1U`ULXGh;A2_r= zLS1oj_}VZ$IlnRg#dA-xI~0$8zGn04g~=<7UECh=@Yi4VPydm2{s^|&_5y0dcQpU6>pFrZL<#<$4Gkjk+1K~u*KB;#0N*gZ_UF9W)Kr3 zCOq^XSf1&z-f}r6!vdV1i7)S)f7!mcUC;}7T$TKq=OG~Y%{@OzJ1=mH6!R(os;}=d z!;udB+sswA)JWjZRlv?%xm6bJze|Bf1&4s&FamC#iCJ1E;~+)4LOcO%k7bT*I4noe zZV;y!);hdOp9B#|{d_SJmV_#EG}wA~ebFpqT|!kr2`4Ot|b){NaL8>YG{EAqlWIK!;;8oQglmT z6bfLntmb|ign+jqcs=oNu1!^&r05*XLw~bD*l~Mqcnh88L?f{8FYVxf{?c~(87t9Tkb?A zgR)(=B7|c<{WNzr^G)BP!~WNL#OhdpTxElemD2X*()ixNg8Lsypp=@o1QF#AxrEh@ zIZ7*md7Ik2$^X{p+j|x%=!p4(~%MN1xAurs5K`vx_h(*+*TP z`FbTC;y*2M^sNNo@57_{FlI|K9i_;61>6?1G_&jW=M$dSD9JQ6e01E`{-vg^N!!;svqz5@U5-&u9D`k?6KtL?7kh_m z(lJ&-rg-Y;Dj?q(tXV+COyfr@Z3b^1dn7HfqZLS^ZAqplUBAC$Hpl-ySd}G!1FH`=1Z>y1e0|fhXsCWZ+MCj zFXeK7)}2?Y;uRqL8~1uJE+(Hsu~hRNcuL7M&MH0L$70X5jCzpH0$SIWW0^zn^ZomX zy6+j*4&>ZoyjBCE7UJB)hBU(B8LTm7$s(`t-?3(BU=m>R&S{Q;`-l7Kj#vgo+9J^sinV_)6kc#Qps76-V+Pnoy~&qj<-uBF!S+Aqda> zdsmc$(sR2K(Im?_zRO++TRO$SWB`6%n#xUHgo^)*ryN7cOjNI&Kn-zs7ew`$gmf1D z70Y^;=nRrH4=N(UO9mrKc3N;vNpPFxpO|mv90-A>WTu?Cg@nIzwQHy2;zQL2EqJ+6 zMaSzME{y^|?t2yR_`Z+wK-Mkr=n%KSFk&NxIkFsP3GMl#7>!Frrcqsj>h^2u_aAXK3`q<^JsqV%~s6>Apl3iE;yP? zlfI>ZufeA{cUS-UO(@7e94*X z`y}}K_sGs4Tbuh722exjwJQ{QU3tDb{U;Ni`3vVXck?7yVfO`KS3!XcX4CTHKd#&P z*eeic0?{x2ITLN4$$o4~YOpJOyxgZxT#4 z<^v4#_!GY!UX9dolHwHf5}&N+**NuiQF9njCD>4tw=q7Ym+)L-w_VSO*br2k=bY9oZnxrQEK|W$;{UmGoE;*LdJWue-*Xv;da)ii*@vyry;jrx zhAQteJmebV(1BFCbtA}xHCR%SZeU&T01Fu=Ya`&H-(t!DV%}&iS)liTV_;p~u+@c1 zRs5cB#pm?p5rOfvh_i<7i9`hrg$j`4sRw6(+&qqW&z(?fhz)iExctYnx{vm!#@v~P z-MqYJ+RZ z$Hnb2cF*P<=9Nt%(+K9kH0&jF!4t(I!W5c-wH10Q!S-XV0^Jv6DiEXZcX39P{KWFi z=VXeCq#3POSzncX@VMkvkm z)Y0zq(DM|!!~~`8-(p+^+B!OY=;%Tm;BtICk|kAZBgIYp$9+Gj^FXhv7wV1rUQr4e z4F*o25{+K4s&7*B_FG)DcZH>z~D+gU*H?%3uX~-PWN0%tjnrk zUo{!x>Ux8)(Kkx{kRuvF)qwyxGDB}T}-@_ zQ6l_azkL$scSnQz)9CpV>Kjz!v)fn?-wF8ur!(K5JLjH7bCqhY6UAI|VZZo@2QYg^ z%qGm_(+3xD^85bUY8ZYTGKP1(c9KPUY2hXP&!mn<=?c8U`i?P-9*unc3sY$5b^Lu! z9T@(nvW+Q>Q#6{{*3Fo9XiH!1-a{M*n=M4hS~>7%$FQ2440@X{nd5x8%=@=(bs9ss zrAfqt`ZE4_eBdT>5xEqd*p{ zD*z5tKD^9(aUNDvYvjStsjfd^zc(P!JYMJX;s#iGA^vgE3hdR9D{^l}f1B z_lHN3HeK5?tu9S5bk&MITfGRR=hBEZM%blNuW z;C)W=f;`4^Fv2{yt}jFVIE8)}76X>`!;GujtH*ba>)L}5#K{gaShx!fzX3I{1PxZdo$8yXmgbkFc4VRl;>!K$;XRQkV_hN@%)Q_ z;0)e#G5{R{QnS~Y_(FWQ!$cnahuP2HG>G<|4O$E)!sIDQq>tc~j#otbuua&jcBQKY zYA^Z#yC?c`#m&BHyO}n6>94MV(^#o*bq4hhD zlLcj(Ykmb_rwnJn;P2O$L(&cllwue;LQ~Q=Ma5XfanX@LStK~3URzXLFCt!|8g(oBbJt=Bx&;puDxafqsD13 zrxAi~|6mJMczVZNoBa);Fgcbiw`izmpuD^T|@`v!LU|F-O{~8KNrN-((*&<%9_A zPgj44q+>KvYk_^=SDN{Wl3us`jL3?l>LUk(cNUsoDp%?hE4*hlzE*Bk21OiNl2}_q z$V|b<3gAyL1u>BxA7zCgb4V%_79CS|H<_ZViP)&qQ*${?H|w}{irZU?^kygO6pVi% zD{DI?<7v4jHA5|Cd6f`hrVE&*L3HHt%+D@R zsaYZz5e>0HU#@zFZ<+Bz3lA1Z$WrCNMk|0Hn1WAO`E3*Q6 zJ9x+x!6G4o4{s7)w|~cPO#GB7=o1zyX?g2S`U{ff9&&n4r@oyR;GLg!&vfMExH3{g zyWtGF>+5QFU0QtA-_C`Tc0a)~GO?nLoKq5c@AV$ggd-7zTHq#hdM`MGQXk@j7aRNM ziR06US?`B@-eIVVw8HSVy+oncQjM^an2NJu$VxwH!PRAC`ebS|{)$NedAeML1oxua zi^Dl;Nq4EIC%=EMl~+ytMe~6V$VdZ)7?DU*)&-L9PuSGG%S3DyTmSC3F363mvu~$; zzqz2KMR;(0gt$%GD4uQ=UTcSh%;w8@pU`}gF3u4zpGkEH&^vO@Vst-mOnx#&-EwD2=6;XY2@UD?~SWEz2kmJkTT^n$@ zLV3emj2p;0f|ZU7QdE9TpL(aP<)yjo_9AQjnI9FQt!@L!;Y(#qyP}~Gv1unY!~0uV zpPcSg-wwL!oN)p_lksgyZG*rN8_= zo~Sqykt}n#{ILsJD^@L{2R|7@3-N3BY;j}_C`=2hB<6D|L{*BO=m>K10#6o&c2cyf zBx#huXNcnFQ>HdFPHm)S5FR%&sxl%^^e+}3ep|MNOCT5-mk2`It)AvNV>VX5wtX!8 z@Yn3gZ7CXAxI~~i9XqY#)mVxdVL_@hvhEd;6wVM`0<-l!iDFW*h(~2$Gzk#35C0&W zqH$eKmKDX8k5@+YR4hK?^{PbI>^pk4es2NnVw6o@B}GZV*{k`PoDT4#Oc4x~g32fZ zT|aZx74x>*$#jj!A~as9p7woF;K5g#R;e=eFx#F9xFcdj~#?2hPgI5Q&8%LLC{0{9k=L$IK-9cBW28?x*ewGWv#6AX~z{ccE1 za2}reTH9rr3!J%C0kc$WrSeeOfk4DdW>kpX!oOgX-LweIl8g0{S|>v{^` zAUt*_$It1X!{HB`dLI{ebeTbGH;^gLFg2EhD`|CnH+OgB2`*_uBEk=$2*L}yh&MIS z&`=W-9GtYNz0mN1+^x}@EP}g5HxjWpMi3Se0Xp(hiVppENvi{nD>OR_!)E-GQ%#)# zLj7FWuZX^aH_{FSoRP;Ju=}~*Z6IdI;&v46=8^@f9*ti8u;DX9JvJbQ1h1N13C5d| zL?8&CfvXp+2H%fT|1$l3`)1>Y{6v)6^k*I!6voIZNHu-6YLO;aLawMsmPxfIx@d7F znD$>cYi*~uap{#zM^_@`EjOxPCl`$;=MDH19EQ+%94)?t+md>oO>quzHObrH2jb=a^hqAS zXJPWM)b4-DQg|fL4T;4ClC=#ywwP3t_V(T&kH>8B&Ay0`N3OwLdY8L@d~wY0D;l~e zA74D`fw`>p?5mB?W?M-1>)$81A%xw2ab+x zZToXYW+E(WdgYcDw8tl4jE9`nPv|B6d0X2HyqP~U4+R6>G}v%t<_ay03pF$>dYFO(G%<$-N3r3}mD>f*zK@Mdu^+eLb4(6og$W7?SQ1cIvh(yz^}E@^PwIEl01Api`6~q9F0k8I^t=wX z_b4Apj2kFz;6FZ@rfRKlTtA|nr)~Ahn37pzuK5z1Ebc0+wvl!%iyI|)?LdThnc$%Z zp*f463-e3JMcgg?UD>f20L?L9yMA(-7j$;mBHH)!W#7_mNHt%Hfso&Dom2qBYNdzf zD(NvkGVtvYssh`UWabQ@QV<@RWRgJo6dF8?2IHe{+Ef^8eoTUoA~GvCKRcQd@ zBTW)yfF3k-9E%B&!b7v;1se&QOyV(tpUEo)9pvJI^{|6kD0^My@D#v!^1S+32{{?2 zx%57gN68z+q$`JGK2%%C_2bXxG%=oCSY|R9ic*S#cr8!peSkG$CPbWll?N)03%6O5 zAm8PPj-k*1O5|aUPFD*3)G2dWX@5X5PCNl+Rbf~HC|ZGL;r!rc^sF%c)agYnJB^j# zLd}26C??jN0G|Hl+hJnocCZ0~Qj3%CD{_Du_AA}G1fC;}wI<-3u(==vsx*viXMVKK zX{@sPX>(-w?`)&xt-z&0P{79Dt5W4>rA15K;qG+l1VdB4b-r;9&1P{hJOxDt5dV0A zBv#E(Y#MJmG^hhBp#a z`)Rck;@0~koo_Rn98XuvMZ}PY5okcFz-)blkD_9Ni2}BmOf+tq zz$(WW)5kD6#4}3nbm&GsRj4tkUquqZN2JwouKings3vd)6-Oq&;f`>^!MVcUe`lYd z&}4qnfYKxM--|~(v!S4TQirtb8ch_XPhIA+BM`yqI~$1Fom7jZo#DLFo!*1UoweM= zi4tj}#>b5(EO+W*FccKiP{e>!n{MVDzAD)0;g+WhwkS3B9(Ng60TXHEh$F;6F@4&Y zg@1lQu|}X~n+Brt(GanEXk6Gv?#?Hgj@T9tdIEWhL@U@3oO`nmV}i?HimIFnZWsHg zMvMEK`v+>}U&*~h`2Z6JfS=dBnsgA?ID?4(eIKrPp+0o$KJvl zyJ2}jr=)36GLT|0wy}pfvKrJ&L=V7wE~v;X<45Sv zT>FdPEyB2{GA6tS|9QkXLxdNRG{fpfB9`x6h8by(8p~nP2LcWLFb)d|inCB%Yh%0= zF%#y$=;uZTzfzwIUWB^Kj0ASvk#O2ZKnu?-QX&4#Yb3_DE~0{*`8rP!GI@=vC}2|9 zy8iZC@j(M|WTTD!jzP7)R4KztT+kl%&sP;Kzbv?CvC^e+L64Cby!=$5;qK#;ts{#DXs+y1Zj)AOL2F1LUAbWP$W>?-K}VFcM25u;t~k(ruW|W z`{R4w=bYqZH+yzwXJ=+-_P0?gO468Uq-bz(aG0_(pVZ*s5CE``H3|}}CW`5sHym6p zitHx|4e!;{^))9AFa`1j6gl;K9VQ~4gu`68ILF{b5g%$$>z{1_;s|-01W9W}g;|X< zjUVN*YxIRjXLZ<`ntN56?=-9Ct?=l$j5EJ+;{B<<2W~dSqPOnD18=i)zMijao{nec zG+1eGY$`uSHn>fWXA1dwJ}=aVKV991-R6j+(1haD8?0*^RGRGMZ{kbB%53^<=gYxU zkGU{pdbXSQ2c4MhZ~X^Nu3 zX8n=&cc%y0{{FtPi3$AQ-@3+uS7#rccfM2y{JleuC}ZoL0mvV2)db#lHaXgJxnu@u)o^*q&SI@f8D{?57DpbcSX2OkF`9KE<0 z$|WFR+w^L|g%(ID*FW*P5n8PHQP&7Iro#NH-<{|JH&BAryBEo|a8agwn=y`-p-b1v z+ip+Q2O(QncOMGXY+Buq@M7ZP`j?kOCx(X)xSE&6t{{RKu`#+}0SDip|BiWel)WRr z>OMWy^m&~WJSMdCyz27cbElcLFWpXq7u9=l5lMHtTpZD%^FP}Dg=DL~ftoCfoBtEc zy6!`p-#v$5mEZl}Hd3H>{@ss0H+|3VI=^)u>hWMDNT4 zCzHy}$z8I1&qg^#I6aTU2SwH{W4W)2X`kJDmJ_ z{>@Zsn=9>ERW9aaDD2Qw+}+|_R-H_AAM|8ax+dyVb!q#+xsvoa1J%K9JooE?QF6`p zF9Vl7XESIX2|m>Mp8dSI4uFlTM^gZ5&;z7kWMb+)xbCgeZ=p_=li(r_?RD$FP`QUY zF(Txg|9c~7cnmxS^Ay{a_C7QLI5``DtyPYfl53>#UG3N+ZLiUCi*c<`poGj5Y4dBAvh^!OH1o?`*wET_I_$RXgyW_n9En{xwMP+RQI>E82)qek;Cf62n9GygUQ;KQw{FM}JJSq3+HgtCE z!bRXuUj3B-_~@_<{`~WT7XZMfqod>E=I-sodewYzxhuKNGTB^yrPHy>DKwH%89X}_ z91-|AvlJ3A>acFNyDy^nsO`5=S|v9X#nP$t3^|EYO?~>7e#HOjNi>k6Jf3cVmtEg4 z|G7vVg|#uZ?!}utpt5Hrn>$B{b!k-2>nzx{(-X=m0@!q#yLxD$!Hex3A6JkN$O@Y) zQHJSf#=CEmIUkYd=H|36NJvS8qlq~6o;-W51gMaAitG;<);Q$#j@?>&l)GYwB#K8{XUc%ZrZELHxS9THLSiHTDslj{ZaYx5?+dN6LVZ z>w~HOO#lSh9}?x%HxtzI=X9lkOGE@C@bRH$dgY1n|FWl*^CrGTEaK_OIbTfe@jyMs zM6CG-3jlqYyjGRUK^z9Ha0LYg&X6k$Vsi4(yXu|J9%4?5 zkDMz4+s+~@LJD_BVrkqtOnqa|b=-4pZLj`iOV#}$PvX8YS@#u%icf~(4wPMs=4+wz zS)n6MZ&xP*d8hi3I zp3K2zlXU*$LPF9E*Na&Z5dQMUnoIsaXO82F3;T=L47PJc!X-ydTs~qRHL=z`cMsVc zCo_h{_dRnvD3>sb*plF&O^xrjUUuZ12L|VM;H`t8947LU(`mZ1s0&5vdM(~I};?&Q#_=DY5DlZm;A|2nOw z)vzt;weV_u=bK%sKW*uOix(e+pQ&p&I}d$vC2fPB0cxk{&1V56#yh>6LW?tA-=DSc z{&`{kY_~J8Y6OVLkO{T|M9MGLzp9z6;p$x9rc;=KH(yWdY-7})gqDE+oCngsHD=f~ ztbZ!xE5LlYruDyT5ShqMWIy&t>OWbP)n%^)h#ruDG?mZAt_VUV>@V5Wgf8?6_;}H@ z5*-&wIugSi!Gm-r9i=h@NyE{p`0O(KgP%YWossjfp{|to-9`xbCOv&^?&`fYf>QX zv8??hAzX$ht%jONJhTBwU?v=sUH&xiQ|L07i?Gh*yg;W_V;Ya0@cp~ms1*G1Yu2#O z2tMj@VOLNeF$W2ydn;dK*`@~Mu@C$x0Ae(8el&>~Ad2a@6izXQgdq~m7djMfK@=ej zDHo@H9IQ`z`PS`d`6$SA_FA0unaGUfdB-_-KP+#VK_MiW_CwUWGIy!WamWIugs3G+1rvNj?yMa%YT%m(+N4t6%L~>(GVqi(e(4&w<&?o>f%HAaUF!Nx4Ax4va z8~`!nT3s-4GdkCDV+-!nNK?4S^eK&toEneT_UG4{5qbw#BU4T?Ut~m3f+z{RW2B~D zS3b7fhV2WMEB!d_$R4V$ zhY9X*G_^im0$JT36ng388Chv};;uvUv~{1fKDw!^%9NYktK>^|ZXba|pD3I+wDhf_ zj0rRno-%Bo?${D_zMq;Ry6$F(BFN&Q;$Q8(bCvowJlqyuspwyAA551{?k6D4Ask#8 zr{HPc(mw{g6v4i7YOxvbGmVvV1u9S(ZcIH8JT;JGM}#(9lsE;~-JfPt z$CXK^^ttOJVNB^%i72wT-&O8fhDl$dx_Nva?i{Z8C?PSau58TUvh+Z96)^@KF%c03 zaEB7Ilwc6Gs05PidpTxBPb48`4umLN6ijn_djquHAx1%6Ii<9pA$f;vuUdq3kcvnH z@A@>V_T%D8@yi?Qy*9y*X>LF~71w?DFRIEy0#sgJ*{103L#b#>l%#Ui$uV+{< zAt(^x1A&0Ifv@ox;vMIFqy~4X#6hiP*Y5`G}Dy5 z^D*>X<(pK+llm#nWO}VLZ*Y04k=UN*%9kob-H+z2N1cV9;z1Dbo>6Yo4a*zp(1W24 z$I@drGpDfOW7|b#ICMHINeSmZ#e_K4|I1V%d5xNoCu>wh#FK2*_Dqoc2o?p!siLEk z(-FPnL$X2;js@N4;jhiEH{hGwuB^ZJr@Ja`lEop$4XPlt+2`Gw&-L=kBx%aBY04FP zjE^F(7Y#tnQ8w`};h!?nAZD*AzldWSSi!+pEOV~(?5M(GYIj-m+$)uF2A=dQIR@Tp z2~-CasiX6Mq7ST+XLjg{05;CK{AZR3jmPjgVbZFZC$m=Okk5zk z+GFO{##Rb!IE+n5nQm%7V z=@@*OL7hV^HtPd}X(@=dtaikCN1_n==d*3X%e0H8uLHXZX#h_h`tCn3HwByIAPf>b zi5N{nm|m4F5{Dtmy1D&*903nd@C)#aBH)mY(YGV>l7RuZbj?p`$}MG{BtR*u1oZEb zK<0a;4s`XGsrisYjv(||!eRBOby_a&FOLnGHG4c35AluQi5CG1(gMq(74Ga@jPggU z*l%&MX|e5+WIBhR;`s=&l^#6Hm2TSo{Y94Ftl&l~`PL_+PrV;gUSL%Oz8t;zN;AV5 zWhmmmsjDP}%31Z^|dgYYXcgC8QlA|71LWdyVwFTDZ_ z=i3iMmJ!Rjah0%s;LGA)I`u>EPQc>!rAjS9c}^2y-zDjAMc6$kH1YQyGzd!w!|p{H zn96-09v(nPc4}{f633L-({q*>0fuFQx_(dnyDq*-U4kEd0&aDls8MWcxur8tVX1k@*F5wD}7mEP1N2i8{3U%+XHRvVXxiAqM-w!6M zC8_&-_P)$V?+6U^rZPta5z>pi zW>zwNbG1V)+;-YY3Muog%h#8%bCLnRWRstrn~(OqK(OCy|Jdo{5LJ4gyhV+d2KvyO zO0ysf#Au+NGgHswG;}=@$NqDcx!)NSpst_{zzgh>P{Erf?3Mg-b!}qC{(z$zz(>2q ziI_dOCuoD^sutP+ob+UP2FcE><~VLsM_eo z1)K(io$3h1pjtjJ%KGOU6`S=~nXQdV^j%yx-NG|dR<@80E=m$eB4%E?MujpEWe-E9I+qVdUeS=D4V}8W`G-0GvysG`8GXhg7-6dOo;;! zHH@8taks!Z2R^+my>)oJ|iATW*Cte1<@;o zLtlY{lSM8aF|>lVQ2gMl9a^Eb!`&;hR4R3?;Ejx8H6nSg>Ka~`C*iX!?i-gt!#nI2 zL!foIUSZX2W)x=ncP`bB8pzC!huE|8_dyPCU8<%0Hfr#HIWWZ0ey-EGl+gh`ShZ6w zFkG40;xpqIw1ZVST4T!Xmiosr2X-vnY5@b79uYdb*FhPWMnJ9;tgm|ptbPDYlxHvZp(Kz!>0jJX$ssh>d+iXHU0!-;3^IfpJY4L}$viZSK7r&^J z<&zkXO$80Ak!yq$><^>Z%1M@C%>Z_NiIH1lVDebpX7McCU9Shh3W7>^?F4txfQPWe zNa>|xM6W=Mb|A{}_HfklX34 z9(aQ=KG|h1n(Izq0|=)`C7o#6Opq_>QZJvZRezT-y@c@npCFSPf_o?aqr+=|-WB|{#jn0gSG$F=Z!S^%iPq@$%V zIc6;_a}oFN+Dqr&+7}(5wL;$x!rb_^xr4Ja)}Z1TP4TyYV4K@EEC<9TFpSqFsieVM z=P%LUh?nYOnek=tGy?fRa5T*#klt3(HO5xTlxmkxJ#p1NEc>e+9t={da&pCuntj`sU66K|vr8ne^oeq5<9L+pb$vYVT^ zCq3ROiu@H*d~)9W(5yHm4fRiyfkXj3{3;Uh6vLE0qU+Ti4$;{njFf_wXLWj~JcNqb zLhf?oFAsi2Ahz^-AZ_FDE}fm2kUjELuhlyMsxqROAv3p{LoA^@;W0daR|PqqUPO_` zV4IT24$D+SIHzXo*h5WfNG6h0AW76pldzb zT(#PsEudi6YQ|>X2K24jsUQvBBTS1|y|0HLQ|(7(1C*TT&deo=V~g8WrzYY0gP+yQ zd^7IgWne+3!t3%)247~OjciFKBTk&Nkr0jaTBA+rCCeI4j1W0ja~ruoJiMfp;j^Yl z?yprnc?33}O>B_v`JC8bK}n_9uyFaqiRyVJXhE2t99zF{iI49!%*>L*0%B5lWp+H# z>2316U(wVukQN7rAuIZII=Gb`HiaJ?h?SNVXg3OSIGtZ&a=pF!>0@zw9@NgW2(=MaKEeu zFx>b$5MwV4*@EU2Ktzmjn9cjrot%j-R2P^cB_qdmhyJ@ID#PmjVqXR&;hiKFh5js} zRz>-i)5!d!AF((ptrwjMe)D;?pU?)owTLbkedg+NWYD2bC)DcK$7~vanN&!M0^{Xd z7b}cyj2%*mdQJsL(@T3DPilFq!C*TXwne%Pg%nUl#x*=JC?alh^3$bY`u>=*vK8_> zw6}y*;S930icNb_syM2KyLkO-{mj_8&uMEbG$5<;wyO~2FI^el-y6h6iNZ{D+r<-2 z%WS_FF5?lVk%ZS_Z&V?le+$eQ`PhPQN}s~zTwx&D>ocY*bQJciw0 zE5gmjiP3)rySUgiG33$uYoUD90Pj%0{(;fghyJOn5HT}2%7loscbIlOTv$7)o0j7~ zXCX90T^G<_r5L-&8$qwgu?KZfKIDMmKQ^d(9;s@+BP=$@&qEaJNTC?aJ_*jaS#2 zZo5pBb{Wg|jZlX0qn#JA$CyZ-5QpLAP2>W- zNV!2;hw2iRuIABJ;`v$)w!Gq52+d(u@#I~{%~aM0g4j>Q5h21J9>1m5Q$Q`pF10<_ z|B;j#q|LfBx9r%+?&L_L-`KxSMZEiJEupRhySu0=*5g#$o04b_q0(wmMSXs;_Kr^K zc{l5BdVdHhH(^YWe17EQa{6%k+toGUSbTJ^Ix|RFWFc^Lv@pq%<$!{Q>O>W&&*OR5 z%Y@_H`59zGBR42wYbOYZ!NgW$%qi~b5*=bNS7Vu1gtSHPfjuJE4lXW!%^sZ<6iAg5 z=t3MubT*N}(h+4DV_W<<)qAT8=Mq)j^#o`_r0L_>$;wpfVjyip=HH0Nx6l>*y#tOk z5Md%n!*!5N4btX+RDn-zNw}-II_I)?vSfSJ&`Df_;PQYlup0@HR7f%l>@qcq%UDCJ zh5q*vGz3;ct2q;?*82MD3(}z3kx~d4k33w4-B{e<7vI5da_%LUP$~HDX=P1pcxWl8 zXqS>3KcF}Fx0>9M=-f15x$2C9&eMOLH8w)&wec+L=m32r`NA%ZUtC-=iOpPGqo9Aj z3cjO;w>}xVAki?r9r~HNo266Y|8;+neaZu)wZG(SQE?Wb8~-w4Q`!Nrk(c{KAsP1; zQpQ02#f3Ubf7Ig01Y!bF{RFHun6_2~?z%JxL3wrUhOr%^tAj%Tdfde=`{3`~x}A%{ z3?RiDhRrpb@rjA)Dzc@cNlpiXh2Y2|t6*T)dNJ6{twAzwkQcDHD;+~pl{^@+7qKUO z`$qXQ(3+vnobY-HI$VTO3uS%}aN|vUp8(frS~)uk{_bPit!hxOwAG+$B!1OJflS#) zI3wx4v#M#^;}_8<0cd*ljBqr34YH&qO+yzF*p(*0d%B`~(mlNqd|8Qx(J0y5JNWZ! zbe%kQSh=gU5?cpIkPKRh)Ow5eO)ExI52C}ZJpSQ3x*6hti0I8(6$xGfBHQzL2){PZPK&as*nrI3tTg}VR?m;7_SB-V2l%J`XMxjttDF_4tQ z$t1S%c2w`%DLk6Q;iOE1G%B~NH#VBUzvalgRtC%GMYT`^`c~%4DQ(W9%L12Y)Q+-U zTPaTC5az7~LToTNA^w)Rhn?i)>bjI|`W%0Zz>kQA{f`AX)_^5Yz*Z26(?fxc{b#cp zWMt1Z_BW7YXcxhZf#`xCfOLBLA5Cqg`rR%pGOhgPxr-orkU49;I-zQ9Xn()7<{thk zp#~~oev0;h{*2M<%NVOZI64-#7W9ypRzTNZ%5G~<5AZgc*CkJZ*iXEzYpa`t`O_WX z#RkQBkNRWuvE!?MbobNUcY>IHZ^$&1REIzoe=E08-yVvsh!IB`~FT1Igi^GbMmi2Oo#T%v)?)G}H{avSrFNBm+i0 zek`5v<72S^oa&&BSl;hh8Cgk)?*V>Ruk!=AL$Fmo=cS=JCvHL2#zq=UWLOv+PD}W1 zQ%^Vqfu@F@J}5yPgJw7yQ-b&%(ARgd$qayfq2xpVSA^t4VMUtItGOg7o4Gz?dT#Q}7S1lR$A56_WQ40XFhA}cRq(%7 zZW_P~{?W7%y+G(o;8lpQ3p_v~9`Zwez&(%Zkqlt9TR7Rvj0%edBS*x6e<&UR)}nD& zZoa-Z%B0^ zKmFX*Qh2bBd31h~8npHdr*B?+Ba7OvAV?z>nGu@r4 zsT**X*&p&|z>Iw7Aj#boD{iGlUT*BIYxr{2Idx0*NxzJ>%wmP+&Ic?^yc0V+tqo>C z3g}n<LCAE068xVK!RrDLRfkXFXiN~t|yj^C<EIgWYdX5y&hw&;Z@7@_i%o&Fw4p;|W;BOqdGR zSk){*nwBupoUObuq|k#6S3Ayw9v~GGB5vbl?RLERx3x6z`{k?@M92X$Vxh;FC8wvn zO$k%1Z7x6pXjZP5HGyitEPE;z8{%Ro?UP~#CL;#X;ZOGBo{*R8UNt1-I3b{lAI*n@ zF;%>dqt)=wO%$GWHij0#kKx_9WV7oYx~7RMW@j_7T(sL2)hI~I)E?rZOZDqv`ORk_ zH7Wb|=<1EXttk{>@0zTVW2CLcIcHS4W9KT3 z2sSHb-=PHP(S}DFzy~F4Ax6NFc_%78T+!+x^KC%Rw#qSB6RfVfTq+&Ji4+LY4=j$)o4m z3}X-VdJ9tv*p}Tv8Xf&}CwVgIu6T*!`GOFcJtnvnMVzCx!KzP(+j>ucY&@vc{yR>ht6QuIBjEx;0XfcGgw90>mBKjG7S0HpyyfK=oHI<=YwHh8@>sHqnEr?PJK zdH4faB&OK(=_)c9T|RoaN(orYQvOnLva$9t z_P`2AUbK&Pe$nti8k35?xf?7Q{e{lewa z>ZcOct7or+e-4xm>#`bjY4b~8cL3Lb>s*&sbb6C1>QiT%*KgalahQLM1e?unE`?;% zwp6!)yk8VtGaFCO&(-}Ae!aZpvNzy!=92X|ssbk?;TU#QGogNxxp9EmAmE|X;H4)K z#1(-u_?wq5!poTuo^e8d!pk6TZ6L3;=W%Km#n9TB!^+wkuOXK|%9ZJ!l{{KBx@Wgq zRL12A;obp8T}BSrwCK%q42abg4}r37;E_|lmMZB_Fga~Hdyk+TlNlbmGHmI&;`H)t|sooII=x$ZB?xd<_%rKSC8BJm*c zSN!ELkh~uo7Z;Zs$_2$x+?f8MsL!%8N{^{NCz~3gA!*SxbbHnrlc<c(e6qtzabEUrmfB zNadSN?}NN5wm-eo7h{new~>YcHw2y67Vp)OARmZ2fe(iNEtSv5lj z(b9Hjr@C8Qn2=9}rGxZ;oL(u%IH)}_z;)n-oGSa(0-o{Kv-H{HljN49#! z4)-J3zxCg{B2EjZ2#`0;b2rA%%XY9cf#cK#g^<>_UQXv-fWGe!tehE%4&V-4ec+vG zw9{cn!D`^12)>TQwhLUJ>j@u!5zZlNJ98&*p=j&q^7y?zBKo_(OXSxZkzqQKz5@Sm z*i`e<4-cvV!O9?lo(Fz8qm1OVNzEcRouh1^#-u@DZ7tH@)CPgSzp9BUDLUfZ6+Ik( zRr0qYH6U%Fjjx8vxBmLkG&!Lc&g%h0DjBT~yg@iamGcXeJfEig+1R493`c7JY7=xO zA7T9T&NuyzD{P~Y>GR%K>GPg`lKsx0ZwbS=F}dJP!6Q6*}y z(rx%&-0-{c(<|1lTREJ*?ys(pd*yJd|JX@5$iCfaImG;t6BA~Juqsl*P^w+5-FS&1 zZYU1Sbo#OXKMVSQ7GX_hyhB0$0_!b}kS%qkhhFY~RkhSmYA@=*8$jIF!P7`l@}uuy zL89S>h)CeJ5ijW?ImX)Y@x6&%`mxWz>wcmv{zmhi9YskGN4P2%B(Sd2O*1Zq+;$lsI2>uw@&TU;_ znCR-F|2>Rd9UVrfea1@g5PTgW#1!E%iQlux1Shck8RoT!&B^(7oU64a7fNY|(DK<)J$y z*D1cv3_Wmfju$#0(1&;7Q|RGM4KZkUs#^5xOb))B0-ghaueX^yKuqAI{uds?&(E`N z;eh~w%lr5LbS6IxZppcG@nZyRQwQJv#V4GfaJM%x#RjZFGx9Q~FE*xl7 zX?10l)oWg0=8Ak&LcJWu4~1GUk?R{3m9ZxCxx7@a0c9^Inv!iTVcRe!5Y!MTpY6M^ z(Bb&Xcjkv(+!nd;!78%*Wx!(l?p8wz)(ZU|j_0;x(t&mG~98q>ce@A=OHTKQ(y1^zW1nFn( z6{~Tm^{lg|l z?j6Uk&-lvxY&1jhP~+#CkDQnF328B@>km0O4m3UAnDG#j(z60eV9vCgv zY(>R)T6$Fd+bd!NNWf5bmZP5uR1UJJ;y{1d32*`x8#0U54in&6Y>$@(4z@oRR+q2E zuT2=Cm7_h*L_1XWNa_)R{rh4-V9DkI0TeS>x}Q>OD9!+QSiavuMo$^D6lr_E&)eM# zVKSq~jTaHVD#&J?R9(VoE7PQC=MFf-zARfRCr)1&hfPfZ1EAJwGehcX=Z<9LE@(hw zw3);4H|}<#^f;ikRSrCOdx$65Yu4LHbNf z{X~}FWoj9E%C?<|3^5nS3$@7SjI&w#?YMY&ziBw*SR-E(_=@Qixmc>JN0m?&4drKx z5eE*O{3LCHh4K^*2ehE}JBrZ?W1rVXtzwV_A<;m*J{&S8WN*flwh+I*F;5cf_ zUD&YchAT;TVQ7}*h!7m8h~t(Co<|&B*P!?H`Z0#Ds>5r zbalO<t3lohZiZ+dInLdLnpQToPjLuG=5&rT8Hj z7+0;VJa;vVr~9}4yZY7Y-X6n`Zh_B4Q#peos3dmQjFPt%JV zB;h8+;U)+>fnYEUSc*_0|6j|0-37vHiJdsqDDYGxTyp`g)?!c(i4_JiF2km<|8+U# z{U@h#9D(BWd}ggcD!u@JRU7#!BffPQ1|0QMgh1H3@ol5;9y`W~8yePoy9dN5AYaBK zox)$kI?wR*z z8y|LQC@3h^DpVKt&(=OfO6Lwc$y^Tt(i+TUMX>6$J*Gk zR-{xR8|NT*)R@(HGO2I$Rf2pwgtqht-Rp4$OK@wGgqvThH$5{MuR_;KSW`a?UL zs?s2QQ9G@yp=nQ)g+=!*gST$gx-AXXr36Km#3DJwZpsGfsvz*I##sC!(dnLxX#f)- z@wL7;xfy%6MAfZP$p4!3a+q$P${;VuT!Bb7`>xa2t<>#%z%#kE@&vcwhXhc)1p=H4 zF_M|>fVYVPF0Z6vm&h^c5Y_NhHWd0NQEA{Xy@{xCZ9QL&`<%!Nn7(KzBHhV%Uxa=@ zA3$+qH(8WiFb}ozkbcqQ{~`_yJ^2Ykx#O7tx3;?Js(Va2eVi~r#7YKuYDx)PG&*aL zu07n0yMP-rcBup5(Xe3S$eer(;S24T@Kz-jfH(fd>J_i6T(cLiMV8PepRMNm6~gUA zCKSj_wa-pE5ub-e65}N3c6H)*;r|9e5P;tS762}O=9o|P0u0p0VV zsGZh9m*ft!Tgh9?5q?J(#qDLKHO}*`AVGu4EiP*C;%DJ5D&RF9wIMNMP((bv+T;HI z!EWfWyhV>U58&~z5ne8*jEZbf#b!10rMSCmqch`?FMciC>90D4`q~eWB*z&X{aff)74UoP>aQ(@69)0r%%rI49+N4olK7!6jDlz(V?V$?l<0i>C*bN!#--oK9@1EqY0i2kDS2H z0*&zinrufni9P_tofyYG_MgK8#1ukb4K|CF;_a^koq(>HDQ`GlB5iYGUe?MzihUJ9 zs}2B*xmNu+wKDM!HD8PTyc|{EQzm-I;<^M$2NY>&xGL-;-#&MVUJV_p84`z9?q&WQ z-rQXK3}YyRisAUqjw^oUyR@-4L8ZCE2g{!Qh)rD6>;C-`l6|W(wVUV<*Jc}@1tUG* zVCR@bv4w1(2cK?ik=DKW!yN2@^;*B-8R1l`8VcH~IIw5rdy2&t90GKEx&EdV=uN6~ zWTg?^MBJaN@(}(6oo}WR{gD)79alCS;r>Cz%5v}2wUIDH4U+XK))=0)ON{WpDabJ^ zPgI%q|GjH9Zu(IXu->NVxO4qygJS*!Y){FWMI`{>xK38|W6X+C-<)IO0x5W16SWWVaI{AA9g)u@(y$Ohh z>hOBOHz4p)q{c!W#E$NGm4g;Dh7KJ!hr<>-TqT`QrpfskmEJ#pf67u-Js;48-_&eS zvXRR)EDZoo#OrCD_{aM+b<+pZT3h+)zaUP#c5MfYKVH^BOs?rBu>U6AD1|s$euFYGH9G}ZPo*kLmG@Q>t2LrDs8xy)7hw6Q5u= zJAW5~uLgM~>pe5KR4S$=jJPr)fpseQ7_Lk@^lc zYpgeLQaM<5#HBaI^}V?en`D`+V!}k@99NB>Ch-65bwBCw0|SvceL|&3Bf-ViRZ>hV za1Zn<{;~1CT=W<$^IoolF*b9P!Rp!#_u9;dF*znm!hLNYY|8fse3vwXGokp_+TD8? zaW!A`O88}&JDvA6__|@9&PdiM|Gejkcdq*n`L@A!w(lZJV{{mi&CMXS2kK5JS@|o6 zp>@E0I)LV9jPI#*2jMj3rkQ2eDTe*^9Omm5>y$l^C(Vin6%5TAC;o+x;=^i#a0Z)8 z?sW8hO&;>XwqJ;`SeQI#=#w;)43lN&KHr$kO<@>5fF!SOi^f-IIX;r-xUT2ze#JSr z7xeKjJ^6KVBxKm^x}VGbR~7v~whZq?#M>zLIeKKwm;V=z?H{O(E7QP+dBy|yIsTsz zZ4UP4o7XMT_=*3*Om1VO)<)5W#;UHiZV~Oi*c!NCQN+L?k&5{rdXT52}>^ zMr}Xdj$`{HLnGov1pXKL!L08;Z(;nK&Gg9Yb%L@`DWwF(L6)pW*?~_ns*E&|bYDKl zd^aP{cdx{)(#fc_rYrurjHUV>@25E;x6H@|6@6cH3Pu#M?`IbrM0BMX_FxE7%|6Tf z%;Zmmh}R7~;ka+N+DOnQls{~r^1VGMCUYTl`5qiRNYZ;#7#Vy7*X7E~kdd7i#?rgn zYAy!%i+DmYW(GP?8q*NDL&x_~OpZ6wjE;}@Zq~%tec8kovD0~w=7&Ejl8vjk43`Xi z@4yAzTSJWL0UTOWKrFgB`6)i%HZid`$6=A`01)>r9o&tmS;pd-(EGSmAGwMj0~=rs5nNgOT<6@Fjr4pKMm=As?_bxhO=AIU5kY0!Xl^m z#wbpfhwC_@gE)<+uO2*|NdnIYE|PF`NYY!F=79e>&qr3~5%*UX)7^&Fl(rFNBGgk- zYW)XVY*Ukfxt-H;)rezN+G>vMw+t!5Wnb*GsV%)feUKMg)|JbpaVJyY)lrHS+a=g< zka}`zO4ah^%~H<(ZK!){oLJam8Bz| z-2J`9!P3a?q2Aui&Aqr?qK+4T+2O!9FBIPLOy|8Hg@t^isp!v-Zr%vy&&}Zre|)C? z`NAvQyFvDdJBvc#FR8TdNN#r|f$a3HrNqXEQ_ zF@`790+5^JIv~p)Y5K;$rAPG#(GJ-T#SYcj!6eqCDvBRDt`6y}DYD6j4d?O@#g5Pz zGnyF(*N)7N+>XNdjOv@Hb#MXpG@A4Wdy1gq)@8)F7xCz3hBzhJiPe-!i7~iFOj6`3 zH+O8(Xoqa!8^DI;_nBBJri!_T9F6#=i56U)gc(ldEm$3Ui2Z z5Z;bjMrtdgA3a1(6|+hchp`A^4vDD0(#1aS!~IwV^ioHD%m-`-dlOPy-Uww(6dpOZ zO6zxFZAcF&a4m;NJozmbFE?u;Y!xkz+>;+Sf3OJ@%xj5=_<3sI%zR*3D}o?tlJmcG zZ(gRl>Q9*ec1*{T4av1-N4($w7)bGdD0}OuwwmZ&m={#ibxrRL7BTvxho9^n5FC~%G&qv7&ptMT*d=L|q-Y1J32#*r5Xm zl9o29bcx3)HK48W9(UpTxAhey-0vrytYgd6K3Il7illJJvVMtFQ^9)uC&9c1-sUrc zqt%qu)qehS*mV?T_fXlM)5r(taTA9puzjodLpAtD2|R~`b?Wetp0ep03sl{ND;$wR zP0=nDpgv)FB^rB*c5)%j6_$a z4#8Bi41U-bicXj;ezz}_u5^BQL}5X5Y?^)|X%bN~AU8JNaU$xOtg-{YF&w-@Ggu(X z(Xau@i6`R7k?JhAq~*7nmYk8Cv{4;9`0KfPhvM}2UXj^d3SzlR7{*_Dpugvs&O{VP zMc|*fER7^=F*%P)kBg_N#hT|f{|KtpRq1zhm#X!}@W8mtl_Ios_$@x+%<;8{Qnm20 z)$fxBM-)=-XQ1pC6vnAP7kCh+M-OX71jVx(;CItzc^>AN8Q#xEI{Rir?ivbS7&8u}D<=Kmbxlenc90|U2wolwb!4B-XIk#uIlN!t@7WZqL0yS_qF?Q^|RRq%N!7-z{RZffqU{i{kPZyst__5UqCF|g0s zmVF_yU?Xgh)Y`N$eVV zbM~*V2|(7!dzWaKuh5NOVzVKBr`3$!H?dozT?v4$rHhQ&aZYs|OxFmw@%*h=FX*so z7y=r%pBQk_Ky(2(-t#q(Vh?p(0Ez_{FzGQA-$8%dC0v7kH`R&pmJFyog^@Og#9h4A*-juqHiaOf zh~TNF(OCHeU+NxBBf@ocizUgbTe-t7vxurmKFa|(|?UaPlysg5#N$o3B@A|{U%e$bihvJ1Jm({2j|bM#AAVEgiC zkN-6p9+yYCPkUq?%ada+-yH@3Fur!}4uAC*BAoNm3A;>OVkxXqPfoz&CVOdb_#zB% zx@r~xq6)d|1btK4^!cO|J_k@$;x^F+F*A6$eLz_nF~PFUhcgsbC;#%FO3m{jHfo$B z(H0p19hmVg2-d!hyHL-ms7gLKmIU+7!9)*(oxbumR$^Z!l01)*rg?ZdKR~@EKzYPt zE1KFT&Fr`O@i5|zt*WhVmXDJ2UeI)I+U+*`C)e}0!oF95GC?#G%w)*H|0QlZkRZ0ji^m@O;V{2o(~gh#vDCU^A5UMsfBO$v5RD}-&}&?^Rj6B zM%eFP)9s{r`ce``t|JIgZ4AJLg$c^PcZ99>J4-tN^=BhCRi| zcZ>3>0;Q6Ltq&)ce7)aCffuE|3CxxX-9MQSKur5KX+ssnq25E^(@49A{O=ka{EaWW zNLFIVn1S53Z7c(nr#L$=A$$%)@EyZ04wiwHN-D5YiT56&SdtzajRB_KfBPj)HhRb% zOzru9!_@y4UhTS2JyUN+vKJhL|JFPk&AaI~4x~~PLAR2HH$$NX=t&i}peH((`#&Bs z6^p%mEyGmHX9I`V^10CWV|@c1vxa$g7m2^t!`$!linGw{S4llO+?9q?;jEO3zS z{@9DivE`cjr3{b7`c3Ik+c*C529EXzDrPL9AiN1<^T%BbF68A`fyz z2q9tF-dF?=DpEvHG=4gqPl~l2GREB4s%r;kn~XnsytDW96)#KXA15|2*RWqgDRhQ} zJdQBCRQ}XUl{#gZPw3uJ7S;k`pIv7X?Efg{wwM-O?AV8L!A9MlDKQ(fJpRx95Mq?t(&$m<}ZVI=(ABl_+*9QV5weHyBIX z9=g(LbzJa~YOH%zIYCzIv=@s1Xg+5CPZ~bjTgu*``L)fNdcJznNnRIqS^x?Slwo`;J$H*{{HuTXp?kJ=RBe}=Y?e=;uwgVnPhWQ~dCES}Ua z;9l`4d1Ys*0IkkR!?yS9fr zC#Ib6odHqaEw2CBX#f+6;oqkXfw`x`-xiO-O~SYkWEwX%I}Rkv z7%=}hTP}w%L?3@tJGsY)r7b(1|LCTU!vJUQF1!LDr2U($@(Cc?Hn@x4j>K(17yrvC zI2Zw#Ysr7+`oBjJA1_-4BZ^wVA|nKlyq??L1uIqR9!k(5JVs5#q3o!nQDim9b!E=T z9&fmKg!So*A9%DM=95}^&U5sxZ=`R%*4We~%Y`wOi82r!a2-xLch`tIFq$}o!Ze(N z=PeF|z5j5v044%(CL+yN(T68z%#oD9N1c+AK`@Vg2?zlMxS?1*Y+JTC?Y~`)4*958 zAvXF3%!uDB%~5fjVNNP0^x7<3lvt+gSv>Km%J)%a9A%jb>53Slm(N92{@jy!*Zr6f zi9PZF9ZRgojV)K&f=emZ-z=xxY#S?y~}ui#7k-wp4d9!hPZ0j++crm16Ur z_U>|%L<`-4?zT8BhBkNuWD}$<*stTCa=)Mxe=?&rC6MZ+4OylecH)2zLuQq<=)=mP z$FWM(^2X)n1d~eR<4`;G$|^%Ib=E-&BK0z-FBF+Mg;cPRkGI_PK^jW8h%Q?s_leFQ z#Xn3!wV2C{tuG|dKNGIJWAsvFWP)Xo_z5T4ui<7^rmRxbK@O~I`DFw)YOE>NDt^{4 zwQ@h#zT)P=kjarr<|+IwDnG(wLp@%ATZzjZq|x|VEpH)DCS6iKPt}5ys$!xD@24Gi z-rW2z16fPn{JAG~xlDHMI-`RcbK`qEu9nr+FZa&sMsKPtgV5=8dk5#6Mi!|AZpI-5 z7gg9J`v)>o*IuJXep_pfu*jgeEX*S1o3=TO8@IjA5h~ zU-k*-GTQ6P(d~6ZZWO{%5+>5Z&jcRYT3H3vU7p5>v~@6!;QmD4hp}%~vmYkkpsBr$ zZSlRI*pRUOmMql(O_k{Nk>8)>ndCES^o`$3p2quvzUK@-y}(a1VmDSab})`QqwQ&Q z$CYwcJiplRtJTEb)!#g@sBA8sy5|K}!c!tuqW%~`bmb~OK|CIx&Xzg(DUipSFz<8V zY#>#T&IFlKJw{~_W~vybb)M%Js#j_QDL8paMw1FZSZwkO3d<&cZuHKEQQ1zeJj)Yc zwdPrqcoZ^kWG7WDHIP)<93N1j7HErmm~t<}7hUo6&(IX~@>|_j*K!D;L8dfNKGYlF z8s0`20=~O?K1J1B5%Hi*rcM~&qC9RexBls*PIDMw)csJ)4dDNtbGk$x9Fn@Tn7(g+ z!9Wak?Eg=7%`cPR-#Cs%wGrN_D<8`7()dnOL%{z>V-cgy55*VZ@4MjvJC2Qr14`-v zs_+ohZqCY8iwX@?k`x;2)b*Bw7z#~T26gQc?yHI<{8}&|zkOg}*CHzs-FhKIfd%*?P0?j@( zCU`kD{?M{QbpT>q-KPa4Dv4Pb|1~&YhfTS9tkc4}r>ai5-P4Ub6=E@T;NqaP z3_`YfLM)cM99d}b!ldO++oD>7aadTp#U^aWJIq=6CuifAeq=Qx4xZLiHEW4S=tyAg zJhOW|HSL~h!1Rr%!VfWNTpX$7;hL=TlfboF=cjLS?~do|l>i<*PksaV*b~duTTv`&Cyo`tgY*f@A|TEB&IzI?fY3lY@9ht9 zI{8Ktoad{&u5t7J9dffR-PCh)jDUDTh4tpB(ojL4)1MS0IC&?F!8f=(T^WIh$3uJI zNf3(9(#$C%@!wNS+3O8cS93Nbv(b<@K-pmngmM;=Skcm!g>%sVn|t?GrJ z>PsY7bCEuXuI4%Lj{fICrsvKH{Di61h#jmDa3CyjSxcbc4`F2T`c2+p08G6;`wwAf zX(Ze~a${brB~7TAuEgq50U#TUWPuoSrowt~aNBGbx<(ULm~-IK!p_bZXlxiJB_=lQ z+%%QA+*KvAc1Y0sho%@&ew>=GC$LPh=*hM=wi)FV91%5aJJ9@S*cs59c!53nUJKQD`3~APLD_V3Of&%30Skr#b;M&Dn?b=07s%x+!UMEi z@-Mf+E2Iu$(62jenK9`re`08Gd)NuEa^N!;-yc$S@+E?X+VEEsL5IPs_|#y(Kc0mL z7AIPjZl-*~2gox=I~&L2QhdnPd%4yyh|UiGOkK0a(vm==tK5KTS67{9RQl&)F?WaC z4^edUZGytbX~Yjlv##COkpns%qo8Hb5Nn3%^_9?5-x=XlnXj2fe8D?jx~!+w)LOaVqoFq%#;Smaa`WOX6F546CBWrILZQf zbag=ouWFqym+zJ$xX}YRHB9Arm=XyclfRWdo==1b`a?VSOm>kkmuWtVfVZr^_w_-q$Fu z9vl$R1AV0%Hgz{fONNz3ycs31G1G5KT|ND6RbKLrNVPREz@h-TmNqb8lMhTKBT9!dBWk@g4B&N!OXJ3CC9-(9MYO zZ>_?h>^qF{;NSJg$Q%Z6bUJV2L0gXnr&#Z`geHSCz$7)2lm3B`RH@Hok!!hvN9RN> zmsZX<^;<~Wn}i8su0bU`by#r^2p8RO2Y4Q5h6W>jh`!UKweKktxO?PyVpNp{Q@0(* zB!H7=<>KXPmUsAyyW{I@673v?t3?7*7kVDDIWfvvP_}v?p?S7o_ zba|Z=ShfUtuBGyAo?s@q!K{6A(2Ny8hdjEDt`%_O5w|IM2Qk$71#kx?#y&LYg$rIv zT!_1~!G!f&=1n5m^)YA9AFu++64Jr;F&ThKu4>H9I@b1~C#ntCgxB8xk?X!SxOXrD zc2X`G$a7Xearm|YWWx%XG%YC2SaeQi?iTVL;24xt>fef=)ymBd;=dXZj&4ToOg#gv zJ8{S*bMtw}UQYXv=x9&Pee}sZ{(wB>hpl9mMix)z;Cf90eQvhZ#*yN8)&Amfew=E5 zM-JEPYv19ub}YaZcGUDdSH-#EcwvtB^zcTw?rfoYGvwx`mht}2e*UAb>qnq}f#BU; zr6})OO#b?M`BVo@tF!e`93bFYBszKM^@#mq?5e=>4wVI3J&^hKI_#` zADLzv-AJ>&4?^D(y;sR>pwlf-@qdHYIPO0cTSsPQ!-?Q%8sPJE3iO22Tf z;%ywdz%j?WjQ5Tuo{|1Qt>IhYQffk<2>)+yE5qymU`nz715-99f%Q|w%!lMn=zxg! z|EL`w@z*TqZhnve0RKO9vv24(>MyMOS5G~Alh8ku^v-wt^S|);yI%SC)E%w&B*e&! zbMaAL}{z>drQYch&3@OeoIV@IQ@RNovu&{J=4wx==49c^UhDe1 z5!0&f1*+sz#KlA=2l(az{vOnbExh@tWOBCn0e8VmEBbe61M>f=gC0szu3V^8x%P(l zOO9aDfF!L8Gi!^N?m^>;4BTrIS1qXbWvWc11X*>v2RcjKnwNT$JRpp1Jq;-qb7zj& z{wg;B&cqSq4ATVjbuT@^5w=KPvQ0^AToyq>`ZE`o7Kwy$=P^f}WJgoh6oh@${JU}QkvGlg!OcS6BOb0smnE9%#b(2~_q z;6Y(csBPb=A0NIS51C}g54OPv20)l#u4+~q@um_mv{wY=`Z z6cJe9d@bPmsVmvI%iz}5&YIBcgLW8WC&&WK7E~=5N)u&Z69(CpUPy1ba+pKNQiXE18xdTjq0yzwrhLWhy*{mXW-kp zukk!jerpOqT_rJ5CaxjEEMHlsSd}0p)Je%L^6O~>npN z`#8WOoYUI-gOt|w8{;`F4jD8lWUAC4;Dj>+AVJg-zQ8d1Kz(yAD*TIG#;L(WZl-j+ z^GR1{FpL~wxt$yGYi}=eKWlG)IIbt;)YeIah%*{?c!Ft<*PvtY)4p2XZSj*SzLg_$ zzSp#vQ0GHkLn2T!jrEDB{xDnmNzmn`93=Ty1HFZD({e52%{;N@gJaGexR*4LNgy5- zzw7_{8Sf5Y%Cq7y?o2^&St%5M+ z^l}6@OrNoafEGQCT97(XEjB~(; zN;49ylH;I7Ba`f8)*0UeI>Yd9Fa^;qh*)xOj zZf-z;OpoJDIi(dnNwGP)>%~xiP+GbA#R}b}$ zVZS});@8M%*r)Y3) zwCYP-5OPdwtT*k3;;mY(zf1Y~bO#7vX4_ zwGlNFWmw%bc0O=Eb1EVz0Ji~7B5`a^ZZIQ;t`vK;7A9ZGzv?P|It!lhilYyN_N zXd`4mQL4pv;O`J9#E_u-A|=!Cb}NIlDCDe^wyL?%w6#lhYU`R~JL~~!iT&eYhszA^ z<&i#a)_05DDx6D&;g)h=6FH75Ubtug=JAEY?K4F%njY_@e52awZBO7gJQq6TQAmjM zZ7RgHv2%8eU{7eHX~_MKbtX`75BIaCnbjogzEjd&g~{EY5R5?En-kzoHBt+Brqjng zbUWCSiOPl*PM@DGq4%hfSAFbjfV1&^``i7lRW0~JWiD-3|L2~&UlH<$496pERyj>t zZqKeIpR*F(LEQABuD0$)A6<37T+PQ>ZvU@l^HE)M!sK&K{XVcITj(^3D8>a-0jSGk z>I9>2;f*`;Sq$(d5TJd>RlUos02FXUk&~dCNNkb&(bG*Q(IV$#&-^4GXFgXQF{2srJf!cwoT8SKwb(}PPEIFl-0E9i zZu5>FjyBFMlA$4ttha*8W#OymdHr(X-TjweYbN@qf7f)KR&`prczu{Jd7A9Db-Za4 zA^skgDoj2wUx9c%j(D^2maE^16XAN}g-=e;8~q%^ZGZfvXOMkO$8?|7zo$o9Q0g8M zuiI>`qQ{PTscpQUcG&D~WZ{>H*OPEorO7r+>w6wg-q>uAC~ z&!})jnP*+gO5L6XXa496ZUq^AUR)j3c zKPEc;lNj#SuicNaDsqK#GNIbCOsPD*wc+v3R40@!Uc9gb=cml|k_xYb8r0m>MnWe{ zTBn)wS0W|V*?OU#Qs?f(vQ)CpO7~t-S6XWm6xKV}fXLJnve2Po^PG`{ER3LQ=OP8` z?ZbBpHru~*xacO#kJ>eyP7qY!QE;LFOn>mjHIt~ABHy$y2*Tmkou!Fyf2=;dv z-g9}3aiTfnLP@+^8~K&yO|8<az&`INX$^-m9eK*0JK^o-0^>9hzcb zVJ&PeV%^M&ea?TM1INer=Hoxb0Tk)$*RRv4-^iyx5`{Yh0NmaM|A2prpj}kgY=`S* z06qL#x>n<2JM-_cT)hY^p6rUaxPaag<-)gax`EE6UrO7*JI{MD^F-P$O|bwf`iXhu zi=scZLH?flN5<3`+t;G{_@-Kg8gFtabR)eE?jB>~fi#}PU@l$#TAH8rmvVEaWcsKQ zD{Zez*rN61#44P%tI@ry>cECP6-Ia2{qzZLZ!1({P$4q>M6taMEnGBIEwVLv7*?iQ zLd>7HFY}r%d(kgS`b`yuX`~lCl647fd@?ow<_|=PoG|BQi)kEh{Q~S61J2x0v0|O; zs_^kxCen5OJ@YZrp=&|rNdjp zIlnz3;g~;PL&ke2ZoddQ6B%gB_msQEr?|#mkVVkWh5XueG3tcl^gd#v%X5D2HVsH% z6O(plq{gVh{AuYlvOHuCWFik%bzz?@1{7InDwf}mf1073bZ`ZGpa3dP0~let$p?jL z`ft~D-4}uD+-^ccHV{0ki^l?kb91HXpUwV_!qyGxP@clyvDMkzvkqPq|KCjuxi1jZ zjeBv?+{Nm`)_~&2K8Ln%IHf&4HFj;zajwL)RSw3m!E0-~rNKG3@R%ufv%fQ{GkS(? zWdqesuh}z%V@9UnBC{KrDrJh%c9a*B2le*Nw1@NV>(gaOB)b>lJPk+-yX;##AbuTd z1r|tuVQ<@&G+w$|#hENeI~CdbMRYz8!>=YF!ol_SyDBYzmT@OZ2)CtV(o!35U&(n9 zIqeTL)_rlP2|c8G>f@xV`U|A-vSUm~JFCT977K)kQv%6E=FHZB;j}fhMaEiY(?luL12wBy@L%36-2P=+QB)jNcLZqR)ot>=t~ z^h32vLNi>tn&~0T#E-ib{nw=GyXy|c+OsuNReODeSLapeG%3bbOMTG~|1^k86q3LKUsfkb+y1YHDxgNQRrE@vCuc-HK~^e1=q@(j5Oq}#7XmFPx`X^V}W@4`r)y^*ZW+_pFKat9w}?32R{-z z{7SlwdqO~~UnpT-J{a~(cFtC%+V1li`I<$31M{xK(*ruQ6{R88HPA6B7@5CgrmnW$ zB}+68IX^x);FXLvJuA~EeO70@m8HmsR{esdMn6-3*(Yh3L>Vv-4cvp&q1k~IQ z#qtU=bE*jxYrb5ijjFDlYrK*@f|_1cdfLTpFjo#uiuVkh#qS?DY+YHug~Naj?yDb< zN}i(g_W{@bPuGC6RMcK-A(b7-uh=*ePt(>)=^-ZuSzZVE+J#CZ&@}0E|LC?bLw&g8 z)?Dtd^*n=OM|=LRZZ9F1yPnoPsr;f6gkHw=HBy<6hTXX&UY#-l2P)p?d{}t^OMaVw_}BED|CQtIl6vVvzQ(wsxd65eTUwa?<*b}Fl6n218KJ9DdEd^V$c3hB zmDi<32J3^M;>gw#Z0iITLSN@dz@L<+x+a`a8+7>&y5cg?IHYL^Y5oN^^k)BqKF>0~ zz0_hdq3955j>GwhhamElvVRIBvHPI!+IDjfIIXaou%yoT7WfBa4RrU4ag2HQ+D-W1 zZ8W%>@a~=-5)Hn)z5|5%?)nAw4toEp7`$jW>nY=Zz03=J7u`jV!^j7Giu^{{06UG9 z94q7yo?j9`@#Z$v)~(&pBwhM|G~DqM@yN#yw7F;r>5}o4C5t`=`-Hh5cTdFSy~0_| zRn+((tFb%F*Muv_X-9@bcWwQx!n&3hKQyD_A{AhtDqt?|e_e{@MAO9x1^cf@wThjm zA0$dRp~%p&(`&8A8QC)?wHZO$ZjKHWO}LbrdA zx4;#@9M#Ha&=p3-;)#FU^)f;SyZvinPq#4S14)bs^7s`|qBIabOZepVzQqNEK!?Hq zJ0}*-F(&e1pU)HU(!p@E`_#Dgc)Vv#+4-!Y9?*X?dPQk7cjN!RU~yk7poK*xn146K9_UNm!Z?a%zHb15TfYAEsUNW%DW!W%u0?SGwj6f z&$up{^pQMKtzgA%hAB^V$4}x`{IT0p(P3BONCIMRwgQny=_k$}F=Fhnv6EcIy!st% ziRZFY>ns~m{ZZdx7~f&3-nj=;sLefdowuLxD{RB()7l3%bV#X*#&PS#rMyrC)=}( z?R_O3uCH}W982LmkSV zI=J~R#dYW6ul8*sr?#=rsSU2DdDdvTfEeG#&qv_~AqFvIVR=>t+^oiALTGfG3>0ytao=PbH{~BtokRX z7Ux(gjtOWkdvi1vvdEinB^^GCKaP^f+{Vy@t6TXL50i{VB3o}3j-OC}dpwi>ey->v z%Pfid^OyEYM3p~J{2 z+=foh4&>e7C|P^e$5)Z`UVc=0qJG|M;1jU{QWVbc{&0i{K$!3^X#B=OzgkZxG~YL2SnAYv1j9ttFa zq%);{gk4jzC&>?=W^!fJ;xVOkwinc_{i}VaUo z3d7>R1cU&2KXs9fm5>5uax%`JJoRcQt5Pg+R3rT7GWOHIEz?CCWlBRLe8c3mL%(kv z*U&dngoLAGT~Wi}jeF!OzE7Cxe$X6r?X4)%p~Lxv-9VdagU3o*91s(z{}(dtpMDwk z+m9N57NzHG8_XEHcd5E;JwE%?_?~73O-JPSJ+!_@o^%*B%kx*<;q%dBJ&t#V7&U|0 z4Zs%{Gpa;rUh?JKy7CHN9f<3Fcw`!c7dSx~_t9J1ilM`Fjq`CB+Xy>EMqmiT2G9|I%L`2E2v+KAzm{>SnW1gY;Jr%6F9^GLrn4&T@tM1Vu!HQu85 z63FXRmX$sKio|5~v@Z%W+}!N-Zpr7G@Kx1FBzlwl%j~M4MSjwqC}So3v|D~$8S|6H z!e5(rNzp9UhDQto*h`;o$LTAIpZUZZ z=GGrSaPYtV5ZA`$0J2=!qsPQXb8(C-u8L!FiChL(8WP>upX#Z(ke;Zm_8SYsIJ)%5 z)4*oxdECoy@jVv45NA$~dTA7~f-DBO;i5%7o|45QOq2Oe1JAOiDh+n_XJP5%XBd^O z_u#H*qqG!~^f6b-DcW)R2;D4_lI>aSKPLm+gZZBJk1CW%_2;SbZE|QaiOEYUi<0>q ztsQtutV_dGvr=t%tZNvuhtCWqp!21jd8Yn$_h^{c*myV~7qCiOozfSp&1o9SQS<-XgQf^iitS&HV>jxeM~a zt`6nD@@z$aP^-->W^VI*igOJsSeGx@dsnShJ+X7O&oklPThwomeD0pyNNb*S&MY{d zw=1AVOHknTNvn9+IHHoEcvN}8thrMsYZWcfHv46A>sP5FBM5_QGyd%Kx2S~_s0bu8 z6h*Lwx{Mx-jEc{I(TsF(xH#`RewG6(DAEinY_87auaJBm{Olx|gs}L8-N=_)NZ8+j z?Q`|__$Xk7&=IM8!dO%H3j)y}HPr0SWxfJmuEx=$_KetWu-{0*ODHt@7tG&O>z9ZW zAS024X_c9i584VQaaT*g7Ob^4cs6oy-l8_rPVG1?*gLp3sK~4`=j^Ie2cj`fsSYso z=4X|#^C<22lq#{fvH8xj|LBPBDRX}{R_`2Tv##p1E8EV^-YqHbt=Z=KG^J zb*68~qLlZvgX)T}UhX~k+4l^HdGKJl&Hz^w6CurWEcyTDo>i*P&TH|`Xc>xs`tZ?T zHf)2>YVPUKkY+TDgPt~Ow27`UIz_broS3iE-}e{FBAV8P%vcIBx-@-LB9S*|rBbPv zsnUwU7TooF&i?qj3?gK6P&EZsC&k~EsZjrjh9GJTbt)Wc2RTDEU?ZLQ>whqgTk+;; zu&QQ9@1%aN6x-8CKM@8t1czOJjkDh;s6>X=;!|K2pw5@Al?5Oy*Bh@KK5i{l12mwn zsFvkJzV&iSI^Lln-Dog*Tk~>REy=Hwa@E)5_-2=HDS#BL=OBDw3$PyReU1@MEVY;O z30iXi%jJa|0_QrzzQ}r75Cxbj6HI*rND6i0bU;Y4O@V(! zo;PM49V1)7@rW8m#(D>(jOtiduGdBy^Z(77$@h935tv`CAGWJkp*W2GvXnSxHKD%N z#rDkEDTb9$hrA3E00cZF?y?NM&WZx_-?P%UWtpXHB8;tApjBgb=#z+=*=J?-CEjun;K%Cnl^EhIhlmF15tj>;bO zxCus@Je4grPiHt-{2{SKW94PcsUVM%+0%%_MHaDIyhCo8aUEwFkS8_V^)|da$|+jS zOm9ufO`K=&)cYxNq*DK`TdH`NWv)Yy`FeL|cV#F*nz7 z*6xXB>$4U})M%7^C~O@%1l7xxL@SMx16xl&V1u7_9fGL-0xMXLMQ(mJhb;1XVzB*h1Dh;%cD+b!d?wG>?gOH)KJ!&m51eUn+TZw z7-4l&Tr0W;f^ZUw{Slwby!t?km_6u=2^)t)(#&7JFgGm1grF_`%=^7UH)ur>} z&%Z^HpF$CqU!(B;f_c{&eZ&cQg&+>1(9ZW?NMhdD2}3^+YHEITgzOJ_W-PfIeY)S& ze*b3G?&@Z;x~1cgg6#~s{wjY@!KA)t#(y0>(g=WEIT)j*5{J)`;nErF|3CIq zvMS8n&`c8Z8-G89oW_4g=z$++D+&OSEWH1s<7X6=F7hN07K{wOPzE}%E6_)t&?UbS z+JJnIaOv}q`sD6q+Bh}O4 z>XM!#@Psy9MK!w2*{$HLUfNV_KR*?|qG&7{FRapQd1S4wPWJMJAKya-F&$hir8uIl zkfJ@lDqfL}dtlNJ_wy=fUVOf{Lfo|BP@w*6;0+zSm0RO&7_5_1aLJ=`$@&~2?7;*P ze&ooxIA#SJBFM=W%44-1EdkH%K5K zz6tsyV?Q|56BpoKzcOk0B#ze;3O;kE&WrYZ_86);QJ2u-iq@j9Y z(CFdU5Cq--iNZpOgxQS69edpVP?MD~&Da$d6FNXY%{XtZ-ICs_N;M&O_FG>Gf&tkc z6r#uY2T+bKP>sb#FY?bna7enRijlR$L;CSB<7il8NI=@`Wbcp#40>P9E{D%47pn^IAnx`{4@%r5QVW`UYC<_^#n^>` z;|zx0^bXNaonFU+UAIo}mGG?d?Nj(Phzth(Y*u|end*!X1*QOQ&<6||32G6+%#uyu z>YJ|)< zf4W=A3-Oh`+#8cG$-B{J0oxuBPbV(4=bmchO)835Cven>AZ;1aZ{~9-Q7-$wSHh42 z6HwdtzL8xH8yK2P8EYz(NjZ91#B6+IX%q0q(tFBKfH8N%tz)5;>d|92m82MpGL~xu zb-7h!inh9WPZ-{pz6>w9P}6`@2T(m;sKZv^#RAL(aU{K62jbrIESSQeuLM3kNRtJq zN@3%vSFl#k)8o*E2&GX#YvkwJ7VWaxh!*D`QXX$rnhJAGs=>C?8n^Kd zFj-yp{QA)hX@z4Nd~&of`LtZ~^Qw0r(qy|4%Vlxq@B%Mi(ZQ0k(h1YOYY6`U+_b&E ze}LSFA{kG@SC?d&NpiIl6+}2V>#j{Uh-~>9j=D$;6f`K1J2||O zO<&0XI=1*$X+{OT8ZG^oKM34e25S(pLkMX#j$UzLcVeo!Y_cAZppB!iRgZ^H?M2q| zWJYVrH9f!l__$Ho65SWPD0woiIZ%zO*h=8Z(~qL?)mJ}m@Bn+I1^Kh>;o;p}E}Gsu z5Tri)x_0%%7b?Hb)6xO-!>nyUFnr#5*P&0f-}7#dB$#jt+%-90P$;o{GpZJf1Dq>3vz5G^d z$X}?`_oZ+Es7dXvfsqHf5>`nCDtf@5-w*Pro@8WaXb^LbmAI|IlH{7llU_ahJ;*pC z!MRRj*a6Bl7?EW->1N75cSBNQ&PR6o zy>@+{g5i6>?q#V6Eu>BM1y$5FaM${MyL=mMt`|Z~d_fM?d3x=LMUECL zEo0h|ln;JM^U&&3xe;drmue)xiSu2fj=UuaX{)4Ew_4lbgb9iJn%M%%z==W_|2+7G z4$(G4&hcc%-iV2h!ZCWYB!*yu_3!D0au&r=MGt#9RhFXC0#V!?Kpun_Fz62z*VVv8?us$N-ZSfBn9Y#cPSI}{ArLl zFjaWS8m*;mR(nsy1B0sJRh0%f+T}>jvH0S?!id-BzA(NRU=>U?50D%4>H7N7j%eh5 z1967xa`rh#-VgCaelSNDf?Uat)g4X58J!0K@r5y}f6>r%G$+2%MZn`P#=6wZr5nLE zb_4d5QS^^oi|M|lJ7nNZZsSL}XAI+6@$YQrbNYhtOE;8SWh^I}I2#qS;Y&KF2vAuZ zO6jAUPplu|oA+ARSzDVr=Up&YSr5RNRl4DgOL;ztrAh35V;YMiQm?K^^k3~^PA%HB zyyZF`EmoPRN|29J`(js2-YF(F}Sk~MG4=;dyEXIEDkWb>9gB;bSS z;twY58v!WjCTrm5S8S$3mNrvkb;i+vK|p0Ep`1Ldp`?YDu?Hopy_c?Ym8{ND6G%-i z@NM~3Pl*g&F4mP7#1*x=PN{Aa8tB2S>$xnmmwkI+Gso43d`0+5+Zw|*jh=04!q53K zE$ISwZJ~sht+;l~u>nN-R%iOK<9h;IT`pmo?8$FUjJ6_Ofp4b4)t6glTqA7`2lGhun!I+)LpqGIK&knDZu3;`Qg)uDfrGiITNg+N%=$PYO( zNd8sA)*KdfgwaEN^UUgSad=1k@j9A9?!i(Q#=o0*0i8+U>eht%Mq`D<;1|SlEy(loe z*n1L@-FJLbD~4`GSuJY6dK};Nl^m?INEStNOZDl}u%(UpDR7!&HIbY5n+8}ISD6R8 zZ{NJTU%x(0X4_GjG+8TwYIDBMoaE3=R2ZppEg=l zsI&DVbGJw#Pu50VbefjdkhK{D&V(U6-L|&AW_=4UXAKWaWhe6MgcDt&7;ql%!2nmz zEL+_FAcRf!m*01K)axm}&V98;Ipb3=0o;L*wa<0HMuLu3_zvNEzpPh#atpLrita}- zDlC)8!1cc?(&Ddr?HtM*!orY5wPrH9mW;!l!E!s%2{)mBkYj5tl0h|?^yGJg5Jssm z%^axZyyP=wJ~8mPOx5|WdPxR9Zhh&Yrb3rtHv(oiP%6oAQ_0c>nSuWlycMXP$49j! zS9Hh$SbJ4Mxhkw~?H5u-#9gQ(&U6qY;`+O14iUPqC=zkoF9D(>7Lkd`qeW+1O_;Wu zgeTij_f%?5;~Yo{oUhZVsjZPdc|?Jj;ah5M~x%XM3NV;99hJKlc(6@W`Z#r#5t63edZ; z_pAnN60&YTR!2G8G3BLo(-`R_#F-d|kYS0|6;JzG<;7-A8T&r3zv>}2($UX*-i9!o zOJ&sI#GMwe?V<2VAmN;XC?Be~V>WJ{)@8msb+u5^?wl@QM`WIT`JgT51rzWrk#br8Z z$tog_9yUWqMQNg)ql5V@V!IEAGq5}-{(uSD1x1$B#3nHQb-ghK{<@O9#HduifpTz8 z6ux!!xMS0}1V4r}C@_DAtaXXV95?~`3PI2ss~=P>v3@6I=u>sX`kjIL74 zR0;kxg@j7Uah8(6_{aKuIgu}gcN5nds^1nZ_ej^CJXS9fdSkAIs-3yayrunRnXCTl zr|V-9O}=~%BU99T2n8+ff8my$xNpGbo|ba}9)-WXIlL<1z5&kN-+mqH+_i|49)HFI zbb?a-<2xt8A|TwcyXIMT6VokY(_2cWCzoCf5xA99G94oJ=mW%mK|1aCcX#0Ozjyq{ z*ni9pbid-ioNyASa@*qguD)i1z7QE@4-H6c%Mk_w{hNjyWDj%#dWR9nKw>~Z%N!WE z{NK&`ZD88}J`kuqt^_K#iaL9u17#B0Uv1;|zZCUfO7QFob3gFOt;z`tw$V>P8W9tM@v#bae)cG9%%LPpQK5?9`C zXk0Q%5xY_07tUeuiZYR#&Y6mff>z3B;>Su<{^CRb?f1ReApw0=lGWK*scP10U;jRz zI`&AN4(1)r20ZoG0;;g*$p>>>z_Z{ zItU?1=km7SAhiNIT#Lf6cX!u)-)wvwwG$Pv>3E=$EjM@&F*Z)D%jjJiK135|p?rUS z^T$wcX9>AwAZq^p#Qme+p2U{7jgMe}<34CtxVSGKa^M3n5@uB_S}a*CT`b=akFo}- zXNx?xCEk9vD+MrGZDD8Og8SBfxZfG08MNvv1JH(BeEW@4_6zn!P02uESEBX-t~h|R z3OW(gVDXQ*C$fr;phU*ef(z?wf_zfRy=I$1e?36~^1uExdTne&8SPx@D%>}PtTm?0 zuTAY8@sPrXj+4(f?`i?cx;toKXF(3IZJBN^mHk5puVGo90kci7Wb*u}vKtmU#Ruq+ zU-6ALW2#nuN=Am6o1h`GqTv02q*mswDMb!+$Ymu^*nq?@Ml;P!I{-TRm7Y$DpQQD1{7O3tpkJ{zOYqFOIt;)`Z0oqQ15q09>HEljDjURVH zSa&r22yHg2^0eRQvcW6jWjH#ei1jyU^HnIyA!yQcCHr2;R*T>c3-OMljrq+-YsGId z#irXktFgmF0{6D6CfqUQ^QAKSN;^*1_vlWP7LSUkwS*(us0ISJ-{(wK=m$Y%@Q7u- z>UT>ehmRMwUhByxOY8{W_I$dm3`Gx5zJL=BccPB6$`oeuHx&I=$8x)emT%%GZ9kXV z=DO?M@ekSl$`rDwZc{W`@cR|>}KU;hi|MH!Jg{$5hOC4_NzUh>UmW~f!1aYTeF;+{&M~^nKYkd&~1qD{BeV%}q0sJDvVIxVdkip;YuU>o4tKYjA{sHb(ec>6jFKDC|6#x&CA6^tr0lGUa=_QXazI zDvOL02`-0ve$#|v73+i2;VJpqjUl#Bd|{djp+7SmT+(m2FqJ@|z2p!G28)rf99c!S zZGNPn^sb&3eM=^p>hEVY)n$dw_dnFqO}SNJb{*V1uR;v+h|D1{D-8n)W}KW7FhcFJ z&yDdXuP+x#BWJ=@bw><`VjKD7Hrw)48tlyC!r_YiZXfNBHyIT6=FI&3{EHflAycDm zvxVZCF#sDG;Q{o$hK4eX^`Pu>D)F%iil8y=4WYPpCzUg6`7KzF7w6;0+ycF~v3ISx zUvZ%l0Y1DTqzXeO^Nga{zctaO>Ajp(eRRpTb0VVmfs4UkpC}?yS4Rv-BM|XboG$v* zMiP@>TczTb4sjdVp4O$zzA5}E>_@VnN-W8Jb@+wKc}LQCnrXeig+JL6Tf8Cb(yVG< zRuI`!zq5G%A}=(qFWtcM9Ws1(i%D|y;e)(#+bz~Y3m|8pV}G_C>%Ul4KFu-k2&zU( zlv*jMj|`zU^Nu zS%jV!l`*R3^88h%6A@r|m69RTskGRz^R^=Uj?d@Xr6(0YzENU%HzEi~#3z8$M%UNA zj1ed9bXp(=?J^!H7$8DfxAtp(HVU=^hZpSbNY31>@*Vx-EJEOHPL0?_9yNPEE&9A< zu1zbob6MIt5}I?AN#Wm__tN0#fU~dox`Fg1CN%Mv|K!Dy=;nBQm&VP^@mbRGoj1g@ zIjW(mif-7M@7b3i=1J#`wWv1uWzS%tX>`rA89j-$U!R}uwiQg|vt3K`Azcl&RygXO zK@z(3shE%cu3%73GK=+3Si1E58|T(XCao>6d7*6WcGlM&@j@0`PA91zj+=EX`){hj z$Uc9CS0q!?3j$isVAeft^eoIENMp0!+uLT9@j+R|ye#IcVz9QtD$5+lUVhRaw&Mo< z$ypg+^}CTM*Jv5@@?oTQoM`SWMLjiftcL`K1i_Iqk*$*L5rC^Y~&BPX{!^Z;(L3%R*uW68$x}I98 Iiv9Ed0=tX0EdT%j literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/emacs-info.png b/doc/kcontrol/windowspecific/emacs-info.png new file mode 100644 index 0000000000000000000000000000000000000000..c1a106e5f36137db36f3c2c9d720b77b54f67b99 GIT binary patch literal 12201 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%0DD}72H!rw$|;Q!a3;YB?B)P#qTh!*m;-=T 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 J#RI#@{|^td0}=oL literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/focus-stealing-pop2top-attribute.png b/doc/kcontrol/windowspecific/focus-stealing-pop2top-attribute.png new file mode 100644 index 0000000000000000000000000000000000000000..187e713d9fa9a1b3303e01f590632105afdd11e5 GIT binary patch literal 35461 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/index.docbook b/doc/kcontrol/windowspecific/index.docbook new file mode 100644 index 00000000..27df810b --- /dev/null +++ b/doc/kcontrol/windowspecific/index.docbook @@ -0,0 +1,1025 @@ + + + +]> + + +Window Rules + +&Lauri.Watts; &Lauri.Watts.mail; + + + Parts of this documentation was converted from the KDE UserBase KWin Rules page. + + + + + +&FDLNotice; +2012-06-02 + &kde; SC 4.9 + +Here you can customize window settings specifically only for +some windows. + + +KDE +KControl +window settings +window placement +window size + + + +Window Specific Settings: Quick Start + +Here you can customize window settings specifically only for +some windows. + + +Please note that this configuration will not take effect if you +do not use &kwin; as your window manager. If you do use a different +window manager, please refer to its documentation for how to customize +window behavior. + + +Many of the settings you can configure here are those you can +configure on a global basis in the Window Behavior +&systemsettings; module, however some of them are even more detailed. + +They encompass geometry, placement, whether a window should be +kept above or below others, focus stealing prevention, and translucency +settings. + +You can access this module in two ways: from the titlebar of the +application you wish to configure, or from the &systemsettings;. If you +start it from within &systemsettings; you can use the +New... to create a window profile, and the +Detect Window Properties button on the resulting dialog to +partially fill in the required information for the application +you wish to configure. + +You can also at any time Modify... or +Delete any stored settings profile, and +reorder the list. Reordering the list using the Move Up +and Move Down buttons effects on how they are applied. + + + + + +Overview +&kwin; allows the end-user to define rules to alter an application's window attributes. + +For example, when an application is started, it can be forced to always run on Virtual Desktop 2. Or a defect in an application can be worked-around to force the window above others. + +Step-by-step examples are provided along with detailed information on using the &kwin; Rule Editor to specify Window Matching and Window Attributes. + + +Examples and Application Workaround +To see what's possible, detailed examples are provided which can also be used to model your own rules. + +A special page is to dedicated to address Application Workaround. + + +KWin Rule Editor +Invoking the KWin Rule Editor + + + + + + + + + + + + + +There are several ways to invoke the &kwin; Rule Editor. Below are two: + + +Right-click on the title-bar of any window, choose More ActionsWindow Manager Settings... and in the Configure window, select Window Rules or + + +System SettingsWindow BehaviorWindow Rules + +The main window is used to: + + +Affect rules with New..., Modify... and Delete +Share rules with others via Import and Export +Ensure desired rule evaluation using Move Up and Move Down + +Rule Evaluation +When an application starts (or the rules are modified), &kwin; evaluates the rules from the top of the list to the bottom. For all rules which match a window, the collective set of attributes are applied to the window, then the window is displayed. + +Should two or more matching rules enable the same attribute, the setting in the first rule in the list is used. + +You can tailor children windows for the application by placing the more restrictive rules first - see the Kopete and Kopete Chat Window example. + + + +Rule Editor + + + + + + + + + + + + + +The editor is composed of four tabs: + + +Window matching +Size & Position +Arrangement & Access +Appearance & Fixes + +As the name implies, Window matching is used to specify criteria to match one or more windows. The other three tabs are used to alter the attributes of the matching windows. + +Panels can also be affected. + +Window Matching +Each window rule has user specified Window Matching criteria. &kwin; uses the criteria to determine whether the rule is applicable for an application. + + +Window Attributes +Along with Window Matching criteria, each window rule has a set of Window Attributes. The attributes override the corresponding application's settings and are applied before the window is displayed by &kwin;. + + + + + +Window Matching + + + + + + + + + + + + + +The Window Matching tab is used to specify the criteria &kwin; uses to evaluate whether the rule is applicable for a given window. + +Zero (match any window) or more of the following may be specified: + + +Window class (application) - match the class. +Match whole window class - include matching the secondary class. + + +Window role - restrict the match to the function of the window (⪚ a main window, a chat window, &etc;) +Window types - restrict the match to the type of window: Normal Window, Dialog Window, &etc; +Window title - restrict the match to the title of the window. +Machine (hostname) - restrict the match to the host name associated with the window. + +While it's possible to manually enter the above information, the preferred method is to use the Detect Window Properties button. + +For each field, the following operators can be applied against the field value: + + +Unimportant - ignore the field. +Exact Match +Substring Match + +Both Exact Match and Substring Match implement case insensitive matching. For example, AB matches the string AB, ab, Ab and aB. + + +Regular Expression - Qt's regular expressions are implemented - see pattern matching using regular expressions. + +Detect Window Properties + + + + + + + + + + + + + +The Detect Window Properties function simplifies the process of entering the matching-criteria. + + +For the application you'd like to create a rule, start the application. +Next, in the Window matching tab, set the number of seconds of delay before the Detect Window Properties function starts. The default is zero seconds. +Click on Detect Window Properties and +When the mouse-cursor turns to cross-hairs, place it inside the application window (not the title bar) and left-click. +A new window is presented with information about the selected window. Select the desired fields: +Secondary class name - some applications have a secondary class name. This value can be used to restrict windows by this value. +Window role +Window type +Window title + + + +Click the OK button to back-fill the Window Matching criteria. + +By using a combination of the information, a rule can apply to an entire application (by Class) or a to a specific window Type within the Class - say a Toolbar. + + + +Window Attributes + + + + + + + + + + + + + +The attributes which can be set are grouped by function in three tabs: + + +Size & Position +Arrangement & Access +Appearance & Fixes + +Each attribute has a set of parameters which determines its disposition. + +Parameters +Each attribute, minimally, accepts one of the following parameters. Additional, attribute-specific arguments are listed within each attribute definition. + + + Do Not Affect + + Ensure a subsequent rule, which matches the window, does not affect the attribute. + + + Apply Initially + + Start the window with the attribute and allow it to be changed at run-time. + + + Remember + + Use the attribute setting as defined in the rule and if changed at run-time, save and use the new value instead. + + + Force + + The setting cannot be changed at run-time. + + + Apply Now, Force Temporarily + + Apply/Force the setting once and unset the attribute.The difference between the two is at run-time, Apply Now allows the attribute to be changed and Force Temporarily prohibits it to be altered until all affected windows exit. + + + +For Apply Now, if the rule has no other attributes set, the rule is deleted after evaluation whereas Force Temporarily, the rule is deleted after the last affected window terminates. + + +Attributes +The Detect Window Properties button back-fills attribute-specific values - for more information see Window Matching. For example the height and width values of the Size attribute is set to the height and width of the detected window. + +Yes/No arguments are used to toggle on or off attributes. Leniency with grammar helps one understand how a setting will be processed. For example, the attribute Skip taskbar, when set to No means do not skip the taskbar. In other words, show the window in the taskbar. + +Size & Position + + Position + + Position the window's upper left corner at the specified x,y coordinate. + + + +&kwin;'s origin, (0,0), is the upper left of the desktop. + + + Size + + The width and height of the window. + + + Maximized horizontally, Maximized vertically, Fullscreen + + These attributes are used to toggle the maximum horizontal/minimum horizontal/full-screen window attribute. + + + Desktop + + Place the window on the specified (Virtual) Desktop. Use All Desktops to place the window on all Virtual Desktops. + + + Minimized, Shaded + + Toggle the Minimize and Shading window attribute. For example, a window can be started Minimized or if it is started Minimized, it can be forced to not. + + + +Maximized attribute is emulated by using both Maximized horizontally and Maximized vertically or Initial placement with the Maximizing argument. + + + Initial placement + + Override the global window placement strategy with one of the following: + +Default - use the global window placement strategy. +No Placement - top-left corner. +Smart - place where no other window exists. +Maximizing - start the window maximized. +Cascade - staircase-by-title. +Centered - center of the desktop. +Random +Top-Left Corner +Under Mouse +On Main Window - restrict placement of a child window to the boundaries of the parent window. + + + + + Ignore requested geometry + + Toggle whether to accept or ignore the window's requested geometry position. To avoid conflicts between the default placement strategy and the window's request, the placement strategy is ignored when the window's request is accepted. + + + Minimum size, Maximum size + + The minimum and maximum size allowed for the window. + + + Obey geometry restrictions + + Toggle whether to adhere to the window's requested aspect ratio or base increment.In order to understand this attribute, some background is required. Briefly, windows must request from the Window Manager, a base increment: the minimum number of height X width pixels per re-size request. Typically, it's 1x1. Other windows though, for example terminal emulators or editors, use fixed-fonts and request their base-increment according to the size of one character. + + + + +Arrangement & Access + + Keep above, Keep below + + Toggle whether to keep the window above/below all others. + + + Autogroup with identical + + Toggle the grouping (commonly known as tabbing) of windows. + + + Autogroup in foreground + + Toggle whether to make the window active when it is added to the current Autogroup. + + + Autogroup by ID + + Create a group via a user-defined ID. More than one rule can share the same ID to allow for seemingly unrelated windows to be grouped. + + + Tiling + + Override the default window behavior to either Tiled or Floating. + + + Skip taskbar + + Toggle whether to display the window in the taskbar. + + + Skip pager + + Toggle whether to display the window in pager: + + + + + + + + + + + + + + + + + + Skip switcher + + Toggle whether to display the window in the ALT+TAB list. + + + Shortcut + + Assign a shortcut to the window. When Edit... is clicked, additional instructions are presented. + + + + +Appearance & Fixes + + No titlebar and frame + + Toggle whether to display the titlebar and frame around the window. + + + Active/Inactive opacity + + When the window is active/inactive, set its opacity to the percentage specified. + + + +Active/Inactive opacity can only be affected when Desktop Effects are enabled. + + + Moving/resizing + + Deprecated as of >4.8 + + + + Focus stealing prevention + + When a window wants focus, control on a scale (from None to Extreme) whether to honor the request and place above all other windows, or ignore its request (potentially leaving the window behind other windows): + +None - Always grant focus to the window. +Low +Normal +High +Extreme - The window's focus request is denied. Focus is only granted by explicitly requesting via the mousing. + + + + + +See Accept focus to make a window read-only - not accept any keyboard input. + + + Accept focus + + Toggle whether the window accepts keyboard input. Make the window read-only. + + + Ignore global shortcuts + + Toggle whether to ignore global shortcuts (as defined by System SettingsShortcuts and GesturesGlobal Shortcuts or by running kcmshell4 keys in konsole) while the window is active. + + + Closeable + + Toggle whether to display the Close button on the title bar. + + + +A terminal window may still be closed by the end user by ending the shell session however using Accept focus to disable keyboard input will make it more difficult to close the window. + + + Window type + + Change the window to another type and inherit the characteristics of that window: + +Normal Window +Dialog Window +Utility Window +Dock (panel) +Toolbar +Torn-Off Menu +Splash Screen +Desktop +Standalone Menubar + + + + + +Use with care because unwanted results may be introduced. For example, a Splash Screen is a automatically closed by &kwin; when clicked. + + + Block compositing + + Toggle whether to disable compositing while the window exists. If compositing is enabled and the rule specifies to disable compositing, while any matching window exists, compositing will be disabled. Compositing is re-enabled when the last matching window terminates. + + + + + + +Examples +The first example details all the necessary steps to create the rules. In order to keep this page a manageable size, subsequent examples only list steps specific to the example. + +The Pager attribute refers to the Virtual Desktop Manager: + + + + + + + + + + + + +Pin a Window to a Desktop and set other Attributes +Pin &akregator; to Virtual Desktop 2. Additionally, start the application with a preferred size and position. For each attribute, use the Apply Initially parameter so it can be overridden at run-time. + +The &kwin; rule is created as follows: + + +Start &akregator; on desktop two, size and position it to suit: + + + + + + + + + + + +Right-click on the titlebar and select More ActionsWindow Manager Settings...: + + + + + + + + + + + +Select the Window Rules in the left column and click on New...: + + + + + + + + + + + +The Edit Window-Specific Settings window is displayed. Window matching is the default tab: + + + + + + + + + + + +Click Detect Window Properties with 0s delay the cursor immediately turns into cross-hairs. Click (anywhere) inside the &akregator; window (but not the title bar). The window criteria are presented. Match only by primary class name so leave the check boxes unchecked - for additional information see window matching: + + + + + + + + + + + +Clicking OK the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description field (which is displayed in the KWin Rule window): + + + + + + + + + + + +Enable the window attributes: Position, Size and Desktop. The initial values are set by Detect Window Properties and can be overridden: + + + + + + + + + + + +Clicking OK in the previous window returns to the main KWin Rules. The new rule with its description is listed: + + + + + + + + + + + +Click OK to close the window. +Done. + + +Application on all Desktops and Handle One Child Window Uniquely +Except for conversation windows, display &kopete; and its children windows on all desktops and skip the systray and pager. For children conversation windows, treat them as the parent window except show them in systray. + +For each attribute, use the Force parameter so it can not be overridden. + +In order to implement the above, two rules need to be created: + + +A rule for Kopete Chat and +A rule for &kopete; + +The Kopete Chat rule's matching-criteria is more restrictive than the Kopete rule as it needs to match a specific Window Role: the chat window. Due to rule evaluation processing, the Kopete Chat rule must precede the &kopete; rule in the KWin Rule list for Kopete. + +Kopete Chat Rule +Assuming a Kopete Chat window is open: + + +Use Detect Window Properties and select the Kopete Chat window. Check the Window role box to restrict the criteria to chat windows - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the following attributes: + + + + + + + + + + + +Click through to complete entry of the rule. + +The Skip taskbar attribute is set to No to display the window in the taskbar which loosely translates to: no do not skip taskbar . + + +Kopete Rule +Assuming &kopete; is open: + + +Use Detect Window Properties and select the &kopete; window. Match only by primary class name so leave the check boxes unchecked - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the following attributes: + + + + + + + + + + + +Click through to complete entry of the rule. + + +Kopete KWin Rule List +As mentioned, due to rule evaluation processing, the Kopete Chat rule must precede the &kopete; rule: + + + + + + + + + + + + + + +Suppress a Window from showing on Pager +KNotes currently does not allow for its notes to skip the pager however a rule easily solves this shortcoming. + +Assuming a sticky note' window is available: + + +Use Detect Window Properties and select any sticky note window. Match only by primary class name so leave the check boxes unchecked - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the Skip Pager attribute with the Force parameter: + + + + + + + + + + + +Click through to complete entry of the rule. + + +Force a Window to the Top +To pop an active window to the top, set its Focus stealing prevention attribute to None, typically, in conjunction with the Force parameter: + + + + + + + + + + + + + +Multiple Rules per Application +Thunderbird has several different child windows. This example: + + +Pin Thunderbird's main window on Virtual Desktop 1 with a specific size and location on the desktop. +Allow the Thunderbird composer window to reside on any desktop and when activated, force focus and pop it to the top of all windows. +Pop the Thunderbird reminder to the top and do not give it focus so it isn't inadvertently dismissed. + +Each rule's matching criteria is sufficiently restrictive so their order within the main &kwin; window is not important to affect rule evaluation. + +Thunderbird - Main +Assuming the Thunderbird Main window is open, sized and position to suit: + + +Use Detect Window Properties and select the Thunderbird Main window. Check the Window role box to restrict the criteria to the main window - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the following attributes: + + + + + + + + + + + +Click through to complete entry of the rule. + + +Thunderbird - Composer +Assuming a Thunderbird Composer window is open: + + +Use Detect Window Properties and select the Thunderbird Compose window. Check the Window role and Window type boxes to restrict the criteria to composition windows - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the following attributes: + + + + + + + + + + + +Click through to complete entry of the rule. + + +Thunderbird - Reminder +Assuming a Thunderbird Reminder window is open: + + +Use Detect Window Properties and select the Thunderbird Reminder window. Check the Secondary class name and Window Type boxes to restrict the criteria to reminder windows - for additional information see window matching: + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description box: + + + + + + + + + + + +Enable the following attributes: + + + + + + + + + + + +Click through to complete entry of the rule. + + + + + +Application Workarounds +Below are Workarounds for misbehaving applications. + +If you are unfamiliar with creating &kwin; Rules, see this detailed example to base your new rule. + +Full-screen Re-size Error +&Emacs; and gVim, when maximized (full-screen mode) and under certain conditions may encounter window re-sizing issues - see Emacs window resizes ... A &kwin; Rule will work-around the issue. + +Assuming an &Emacs; window is open: + + +Use Detect Window Properties and select the &Emacs; window. Match only by primary class name so leave the check boxes unchecked - for additional information see window matching + + + + + + + + + + + +Clicking OK in the previous window back-fills the results in the Window Matching tab. Enter a meaningful text in the Description text box: + + + + + + + + + + + +Ignore &Emacs;'s full-screen request by enabling the Obey geometry restrictions attribute, toggling it to off (No) to ignore and selecting the Force parameter: + + + + + + + + + + + +Click through to complete entry of the rule. + + + + + + +Credits and License + +Documentation Copyright see the UserBase + KWin Rules page history + +&underFDL; + +&documentation.index; + diff --git a/doc/kcontrol/windowspecific/knotes-attribute.png b/doc/kcontrol/windowspecific/knotes-attribute.png new file mode 100644 index 0000000000000000000000000000000000000000..3f15cc9abe218e628826b2367b91c0db09a42631 GIT binary patch literal 35132 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

EOdN>Phxaen4pkuyOa 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 Gp$Pz8=viX` literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/knotes-info.png b/doc/kcontrol/windowspecific/knotes-info.png new file mode 100644 index 0000000000000000000000000000000000000000..522b984cc325ebd9f380a969e910584f699077d8 GIT binary patch literal 12304 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 NqNwqr{P~;E{{!djWkvu1 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kopete-attribute-2.png b/doc/kcontrol/windowspecific/kopete-attribute-2.png new file mode 100644 index 0000000000000000000000000000000000000000..95dc5b00da403da208cbc83b1ac88a5ccc03109b GIT binary patch literal 35206 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 a9{ZQ80dv(R$khPbEDWBmelF{r5}E-2N_L$9 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kopete-chat-info.png b/doc/kcontrol/windowspecific/kopete-chat-info.png new file mode 100644 index 0000000000000000000000000000000000000000..4569419a8dc42b4db4d2574376461225021d371e GIT binary patch literal 12436 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 G%>M@)M4QY2 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kopete-info.png b/doc/kcontrol/windowspecific/kopete-info.png new file mode 100644 index 0000000000000000000000000000000000000000..ca4dfe7708efbd2c0df10d68d8f499e00814ad2b GIT binary patch literal 12195 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

  • d-!*Ap98V>JoSZYb*XqSwHelql!RjIF%*apg5j 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 D(c4+E literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-kopete-rules.png b/doc/kcontrol/windowspecific/kwin-kopete-rules.png new file mode 100644 index 0000000000000000000000000000000000000000..489013125f03ee781cba243512ffdd5fbed6bd39 GIT binary patch literal 86327 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 V=;bh52D$(M002ovPDHLkV1kVkMs5HA literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-rule-editor.png b/doc/kcontrol/windowspecific/kwin-rule-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..e42b7b26a07e0a14e066826a770bd740323b84f3 GIT binary patch literal 54825 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≪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 R1(<>%EA>jUQ2gzu{|6-pr4;}G literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-rules-main.png b/doc/kcontrol/windowspecific/kwin-rules-main.png new file mode 100644 index 0000000000000000000000000000000000000000..fa290fab1f412e8b853435242ae3dbbd33af754a GIT binary patch literal 31500 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-rules-ordering.png b/doc/kcontrol/windowspecific/kwin-rules-ordering.png new file mode 100644 index 0000000000000000000000000000000000000000..1397150df0255dd46e7ff5b6822a0040c53e32c5 GIT binary patch literal 50306 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 B(*pni literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-window-attributes.png b/doc/kcontrol/windowspecific/kwin-window-attributes.png new file mode 100644 index 0000000000000000000000000000000000000000..b62235228c347961345c10e9c90c5ef975746789 GIT binary patch literal 72244 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/kwin-window-matching.png b/doc/kcontrol/windowspecific/kwin-window-matching.png new file mode 100644 index 0000000000000000000000000000000000000000..50162f9805d98583a6de57481ab3f624cd4d1b4e GIT binary patch literal 53362 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

    @)OkR`h*hIK2U-XQdsDPojySmEjeVL-Xbn>DuQ_ z$cCcdGXARq4+tX_UHfm>IuCO!zEN{cER{|mjo`>W)`qF3VP zC|u$9=ftI@nY@k_6>fMInwGt>fXgeE7`7UoyUS=wubWSvs0siu$s)h`c0}|GL4h8K zH_H1N>Bdz4#uc9~6Nt9^TU$z%t*i}Cz(;zxVU$ zieP@>;`{mNwockaW@Y=+L5Eu}-h2+H?z9Dbh+y%)B9L17Z}-o2{5zkw0~Rk%7OLGQ z?7S};bS@KX_k*w8&Nbe!+}e%>qHL$G{+PW#a;T2dL-%JKcQ5(ANV>nqWp!!M?i-Ra zZ~nH_iV(U305jcTYirC*QOSDk5%?~zMd8{mD}+RN7hoP{x6Tk48{s$Iop$0m znodFNgYKLyBUAP(2Ep5#UPv>Wzr8vl@XlHx@8CVK>% z+VNDiA;*3k%`EvrvgIz}a1IGJoNp>JlNRy2Lm=aI43xg)Oc^B_4llU(`%iz=1 VmHqx(fX8<*c)I$ztaD0e0sy5KLwW!J literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/tbird-reminder-attribute-2.png b/doc/kcontrol/windowspecific/tbird-reminder-attribute-2.png new file mode 100644 index 0000000000000000000000000000000000000000..9110bc65c3a7afea31d9231e0e2b3190bc89d0b4 GIT binary patch literal 35434 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'ey0Q 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/window-matching-emacs.png b/doc/kcontrol/windowspecific/window-matching-emacs.png new file mode 100644 index 0000000000000000000000000000000000000000..d0404b1b97c93ff725a79ec272bf2c6827cd7b91 GIT binary patch literal 24891 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 E17imxL;wH) literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/window-matching-init.png b/doc/kcontrol/windowspecific/window-matching-init.png new file mode 100644 index 0000000000000000000000000000000000000000..0bdbcf3f386b2df8517715209a4eecceed6348ed GIT binary patch literal 24334 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/window-matching-kopete-chat.png b/doc/kcontrol/windowspecific/window-matching-kopete-chat.png new file mode 100644 index 0000000000000000000000000000000000000000..a232d3b9f705b5c9079bc9f6536778c42ffc334d GIT binary patch literal 24781 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 AIsgCw literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/window-matching-tbird-compose.png b/doc/kcontrol/windowspecific/window-matching-tbird-compose.png new file mode 100644 index 0000000000000000000000000000000000000000..30e8494dff853516ffa1b7963256c630efee1067 GIT binary patch literal 24221 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%0AFSxbbD;H~nu>wTZVmTE&I7-0HBHo{#0(T9E=i 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 E5C1=A9{>OV literal 0 HcmV?d00001 diff --git a/doc/kcontrol/workspaceoptions/CMakeLists.txt b/doc/kcontrol/workspaceoptions/CMakeLists.txt new file mode 100644 index 00000000..f8c96f80 --- /dev/null +++ b/doc/kcontrol/workspaceoptions/CMakeLists.txt @@ -0,0 +1,2 @@ +########### install files ############### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kcontrol/workspaceoptions) diff --git a/doc/kcontrol/workspaceoptions/index.docbook b/doc/kcontrol/workspaceoptions/index.docbook new file mode 100644 index 00000000..cfad4e1d --- /dev/null +++ b/doc/kcontrol/workspaceoptions/index.docbook @@ -0,0 +1,104 @@ + + + +]> +

    + +Workspace + +&Marco.Martin;&Marco.Martin.mail; + + + +2011-08-24 +&kde; 4.7 + + +KDE +System Settings +desktop +workspace +netbook + + + + +Workspace + +This is a module to configure global options for the Plasma workspace. + + + +Workspace Type +In this section you can configure the type of workspace you will be +using. Right now there are two options: + + + +Desktop + +A workspace optimized for traditional desktops and laptop computers. + + + + +Netbook + +A workspace optimized for netbooks and in general for devices with +a smaller screen resolution. + + + + + + + +Dashboard + +In the dashboard section you can configure the behavior of the Plasma dashboard. +Right now there are two options: + + + + +Show Desktop Widgets + +The dashboard will show the same widgets present on the desktop. + + + + +Show an Independent Widget Set + +The dashboard will present an independent +set of widget that is different from the ones in the desktop. + + + + + + + +Informational Tips + +Show Informational Tips are displayed hovering items in the +Plasma panel or on the desktop. + + +
    + + + diff --git a/doc/kdm/CMakeLists.txt b/doc/kdm/CMakeLists.txt new file mode 100644 index 00000000..312e2ec2 --- /dev/null +++ b/doc/kdm/CMakeLists.txt @@ -0,0 +1,6 @@ +set(confproc ${KDEBASE_WORKSPACE_SOURCE_DIR}/kdm/confproc.pl) +set(confdef ${KDEBASE_WORKSPACE_SOURCE_DIR}/kdm/config.def) +set(confdoc ${CMAKE_CURRENT_SOURCE_DIR}/kdmrc-ref.docbook) +add_custom_target(ref + COMMAND ${PERL_EXECUTABLE} -w ${confproc} --doc ${confdef} ${confdoc}) +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) diff --git a/doc/kdm/index.docbook b/doc/kdm/index.docbook new file mode 100644 index 00000000..e84ee008 --- /dev/null +++ b/doc/kdm/index.docbook @@ -0,0 +1,1786 @@ + + + + kdmrc"> + ksmserver"> + kdesktop"> + XDMCP"> + xdm"> + + + + +]> + + + +The &kdm; Handbook + + + +&Oswald.Buddenhagen; &Oswald.Buddenhagen.mail; + + + + + + + +2000 +&Neal.Crook; + + + +20022007 +&Oswald.Buddenhagen; + + + +2003 +&Lauri.Watts; + + +&FDLNotice; + +2007-12-07 +0.06.00 + + +This document describes &kdm; the &kde; Display Manager. &kdm; +is also known as the Login Manager. + + + +KDE +kdm +xdm +display manager +desktop manager +login manager + + + + + +Introduction + +&kdm; provides a graphical interface that allows you to log in to a +system. It prompts for login (username) and password, authenticates the user +and starts a session. &kdm; is superior to &xdm;, the X +Display Manager, in a number of ways. + + + + + + + +Quick Start Guide + +This is a quick start guide for users who fit the following +pattern: + + + +X is configured and works with the command +startx from the commandline. + + +Each user will generally only use a single window manager or +desktop environment, and does not change this choice very +often, or is comfortable editing a single text file in order to change +their choice. + + + +This scenario will be sufficient for many environments where a single +user or several users normally boot the computer and log into their +preferred environment. + + +Setting up a Default Session + +Create or open the file ~/.xinitrc +If you already have a working ~/.xinitrc, go to +the next step + + +If one does not already exist, add a line to the +~/.xinitrc to start your preferred window manager +or desktop environment. +For &kde; you should enter: +startkde +For other window managers or desktop environments, you should +look in their documentation for the correct command. + +Make a link as follows: +ln ~/.xinitrc ~/.xsession + + + +At this point, typing startx +on the commandline should start X, with a &kde; session. The next task is +to try &kdm;. + +As root, type +kdm at the prompt. + +You should see a login window, which is described more fully in . + +Typing your normal username and password in the fields provided, and +leaving selected as the session type should now +open a &kde; session for your user. + +If you have other users to configure, you should repeat the procedure +above for each of them. + + +This is a quick guide to getting up and running only. You probably +will want to customize &kdm; further, for example, to hide the names of the +system accounts, to allow further sessions, and much more. Please read +through the rest of this manual to find out how to do these things. + + + + + +The Login Window + + The user interface to &kdm; consists of dialog boxes. The main +dialog box contains: + + + +Widgets allowing you to authenticate. When the "classic" authentication +method is chosen, these are: + + + +A Username: field for you to enter your +username. + + + +A Password: field for you to enter your +password. + + + + + + +(Optionally) a list containing entries with the name and graphical +image of each user (for example, a digitized photograph). +Clicking a list entry is equivalent to typing the associated username +into the Username: field. + + + +(Optionally) a region to the right of or above the +authentication area which can be used to display either a static image or an +analog clock. + + + +A Login button that validates the +username/password combination and attempts to start a session of the +selected type. + + + +A Menu button that opens an action menu +with the following items: + + + +(Optionally) A Session Type item +to choose the type of session (desktop environment, window manager) to start. +See to find out +how to configure different session types. + + + +(Optionally) A Authentication Method item +to switch between different authentication methods like the classical +username+password, smartcard, biometry, &etc; The actual authenticators +are combinations of PAM modules and matching frontend +modules (conversation plugins). See +. + + + +(Optionally on local displays) A +Switch User... item to switch between local +sessions running on different virtual terminals of this computer. + + + +(Optionally on local displays) A +Restart X Server item +that terminates the currently running &X-Server;, starts a new one and +displays the login dialog again. You can use this if the display content +seems to be broken somehow. + + + +(Optionally on remote displays) A +Close Connection +item that closes the connection to the &XDMCP; server you are currently +connected to. If you got to this server through a host chooser, this will +bring you back to the chooser, otherwise it will only reset the &X-Server; +and bring up the login dialog again. + + + +(Optionally on local displays) A +Remote Login item that displays a host chooser +dialog with &XDMCP; servers one can log into remotely. + + + +(Optionally on local displays) A Console Mode +item that terminates graphical login and leaves you at the console. See + and +. + + + +(Optionally) A Shutdown... item that displays +the Shutdown dialog box. + + + + + + + +The Shutdown dialog box presents a set of +buttons that allow one of these actions to be executed: + + + +Turn Off Computer + +Shut the system down in a controlled manner, ready for +power-down. + + + +Restart Computer + +Shut the system down and reboot. For systems that use +Lilo or Grub, +an optional drop down box allows you to select a particular operating system +to be used for the reboot. + + + +Schedule... + +If this option is enabled, you may use it to enter a more complex +shutdown dialog. See for details. + + + + +Pressing the Cancel button returns to the +main &kdm; dialog box. + + + + + +Configuring &kdm; + +This chapter assumes that &kdm; is already up and running on your +system, and that you simply want to change its behavior in some way. + +When &kdm; starts up, it reads its configuration from the folder +$KDEDIR/share/config/kdm/ +(this may +be /etc/kde4/kdm/ or something else +on your system). + +The main configuration file is &kdmrc;; all other files are +referenced from there and could be stored under any name anywhere on +the system - but usually that would not make much sense for obvious +reasons (one particular exception is referencing configuration files +of an already installed &xdm; - however when a new &kdm; is installed, +it will import settings from those files if it finds an already installed +&xdm;). + +Since &kdm; must run before any user is logged in, it is not +associated with any particular user. Therefore, it is not possible to have +user-specific configuration files; all users share the common &kdmrc;. It +follows from this that the configuration of &kdm; can only be altered by +those users that have write access to +$KDEDIR/share/config/kdm/kdmrc (normally +restricted to system administrators logged in as root). + +You can view the &kdmrc; file currently in use on your system, and you +can configure &kdm; by editing this file. Alternatively, you can use the +graphical configuration tool provided by the &systemsettings; (the +Login Screen module in the System Administration category). + + +The remainder of this chapter describes configuration of &kdm; +via the &systemsettings; module, and the next +chapter describes the options available in &kdmrc; itself. If +you only need to configure for local users, the &systemsettings; module +should be sufficient for your needs. If you need to configure remote +logins, or have multiple &kdm; sessions running, you will need to read +on. + + + + + +&Thomas.Tanghus; &Thomas.Tanghus.mail; +&Steffen.Hansen; &Steffen.Hansen.mail; +&Mike.McBride; &Mike.McBride.mail; + + + +The Login Manager &systemsettings; Module + +Using this module, you can configure the &kde; graphical login +manager, &kdm;. You can change how the login screen looks, who has +access using the login manager and who can shutdown the +computer. + +All settings will be written to the configuration file +&kdmrc;, which in its original state has many comments to help you +configure &kdm;. Using this &systemsettings; module will strip these +comments from the file. All available options in &kdmrc; are covered +in . + +The options listed in this chapter are cross referenced with +their equivalents in &kdmrc;. All options available in the &systemsettings; +module are also available directly in &kdmrc; but the reverse is not +true. + +In order to organize all of these options, this module is +divided into several sections: General, +Dialog, Background, +Theme, +Shutdown, +Users and +Convenience. + +You can switch between the sections using the tabs at the top of +the window. + +You can only make changes if you run this module with superuser rights. + + +General + +First you have a drop down box to choose the language for +your login box, corresponding to setting in +&kdmrc;. + +In the Appearance section you have an option to use +&kdm; in themed mode. If Use themed greeter is checked, +the settings on the Dialog and Background +pages cannot be configured separately. + +While &kde;'s style depends on the settings of the user logged +in, the style used by &kdm; can be configured using the GUI +style: and Color scheme: options. +These correspond to the keys and in +&kdmrc; respectively. + +From the Fonts section of this page you can change the fonts used in the +login window. Only fonts available to all users are available here, not +fonts you have installed on a per user basis. + +You can select three different font styles in this section +(General:, Failure:, +Greeting:). When you click on the +Choose... button a dialog appears from which you can +select the new characteristics for the font style. + + + +The General: font is used in all other places in the +login window. + + +The Failure: font is used when a login +fails. + + +The Greeting: font is the font used for the title +(Greeting String). + + + +You can also check the box labeled Use anti-aliasing for +fonts if you want smoothed fonts in the login dialog. + + + + +Dialog + +From this page you can change the visual appearance of &kdm;, +&kde;'s graphical login manager in non themed mode. + +The Greeting: is the title of the login + screen. Setting this is especially useful if you have many servers users + may log in to. You may use various placeholders, which are described + along with the corresponding key + + in &kdmrc;. + + +You can then choose to show either the current system time, a logo or +nothing special in the login box. Make your choice in the radio buttons +labeled Logo area:. This corresponds to in &kdmrc; + +If you chose Show logo you can now choose a +logo: + + + +Drop an image file on the image button. + + +Click on the image button and select a new image from the image chooser +dialog. + + + +If you do not specify a logo, the default +$KDEDIR/share/apps/kdm/pics/kdelogo.xpm +will be displayed. + +Normally the login box is centered on the screen. +Drag the anchor to move the center of the dialog to the desired position. +Keyboard control is possible as well: Use the arrow keys or Home to center. +Note that the actual proportions of the dialog are probably different. +These correspond to the key + +in &kdmrc;. + + + + +Background + +Here you can change the desktop background which will be displayed +before a user logs in. Selecting Enable background +allows you to edit the options on this tab. + +This tab is comprised of three areas: + + + +An area for selecting background images + + +The background Preview Monitor + + +An area for determining the background color + + + + + +Preview Monitor + +This is a preview window. It will give you a sense of what to +expect with each change. + + + + +Background + +This section allows you to load a wallpaper on top of the color +gradient chosen in the section below. + +There are three choices available here: + + + +No Picture + +No picture background will be shown. The color and pattern +choices below will still take effect. + + + + +Picture + +A single picture will be used as the background for the selected +desktops. +How this picture is positioned and scaled can be fine tuned +below. + + + + +Slide show + +&kde; allows you to have an automatic slide show of wallpaper +images. To enable this option, press the Setup... +button. In the resulting dialog you may choose any +image or folder of images available on your computer, using the +Add... button to navigate your file system. +Remove will remove the currently selected +entry from the list. + +You may choose the length of time any image is displayed in the +Change picture after: box, and you may choose +Show pictures in random order if you don't want +them displayed in the order they are listed. + +Displaying wallpaper requires that the image be kept in +memory. If you are low on memory, using a small, tiled image or none +at all is recommended. + +Scaling or centering a small image still requires an image the +size of your display to be maintained in memory. + + + + + + + +Options + + + +<guilabel>Position:</guilabel> + +Centered +The image will be centered on the screen without changing the +size of the image. The background colors will be present anywhere the image +does not cover. + + +Tiled +The image will be duplicated until it fills the entire +desktop. The first image will be placed in the upper left corner of the screen, +and duplicated downward and to the right. + + +Center Tiled +The image will be duplicated until it +fills the entire desktop. The first image will be placed in the center of the +screen, and duplicated upward, downward to the right, and to the left. + + +Centered Maxpect +The image will be placed in the center of the screen. It will +be scaled to fit the desktop, but it will not change the aspect ratio of the +original image. This will provide you with an image that is not distorted. + + + +Tiled Maxpect + +The image will be placed in the corner of the screen. It will +be scaled to fit the desktop, but it will not change the aspect ratio +of the original image. This will provide you with an image that is +not distorted. If there is any space over, the image will be +duplicated to fill it. + + + +Scaled +The image will be scaled to fit the desktop. It will be +stretched to fit to all four corners. This may distort the image. + + +Centered Auto fit + +If the picture fits the desktop size, this mode works like the +centered option. If the picture is larger than the desktop then it is +scaled down to fit while keeping the aspect ratio. + + + + +Scale & Crop + +Magnify the picture without distorting it until it fills both the +width and height of the desktop (cropping the picture if necessary), and +then center it on the desktop. + + + + + + +Colors: + +The first drop down box allows you to choose the type of color, +gradient, or pattern to display under (or in place of) wallpaper. +If you are going to be using a picture as a wallpaper, you +can skip this section of the dialog box. +However, if your chosen wallpaper does not cover the entire +desktop, the chosen colors will still show in the remaining +space. + + + +Single Color +By choosing this mode, you select one color using the +first color bar, and the entire background is covered with this one +color. + + +Horizontal Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the primary color selected with the left +button on the left edge of the screen, and slowly transform into the blend color +selected with the right button by the time it gets to the +right edge of the screen. + + +Vertical Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the primary color selected with the left +button on the top edge of the screen, and slowly transform into the blend color +selected with the right button as it moves to the bottom of +the screen. + + +Pyramid Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the primary color selected with the left +button in each corner of the screen, and slowly transform into the blend color +selected with the right button as it moves to the center of the +screen. + + +Pipecross Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the primary color selected with the left +button in each corner of the screen, and slowly transform into the blend color +selected with the right button as it moves to the center of the screen. +The shape of this gradient is different than the pyramid gradient. + + +Elliptic Gradient +By choosing this mode, you select two colors (using both color +buttons). &kde; will then start with the blend color selected with the right +button in the center of the screen, and slowly +transform into the primary color selected by the left button +as it moves to the edges, in an elliptical pattern. + + + +Pattern + +The rest of the list are the names of various patterns +or textures you can choose. +For more on patterns, see +the section Adding, Removing and +Modifying Patterns. + +Select the primary color with the first color bar. If you have +chosen a pattern that requires two colors to be set the secondary +color can be set by pressing the appropriate button. + + + + + + + + + + +Blending: + +The drop down box labeled Blending: contains the +options to make a smooth transition (blend) from the wallpaper as it +changes to the background. + + +A drop down box allows you to select the blending mode. +Many of the modes are similar to blending modes for background colors. Select +your mode from the list, and the preview window shows you what it will look +like. +The Balance slider adjusts the +blending. The results can be seen immediately in the preview +window. +The Reverse roles can reverse the +role of the picture and the background for some types of +blending. + + + + + + + + + + +Advanced options +Located below the preview monitor is a button labeled +Advanced Options. + +To use an external program to determine and change the +background of &kde;, simply select Use the following program +for drawing the background. Available &kde; programs are +listed, select one to enable it. + + + + + +Adding, Removing and Modifying Wallpapers and Patterns + +There is a button under the preview monitor labeled Get +New Wallpapers that helps you fetch new wallpaper images from a +selection of popular images from the KDE-Look website. You can of course +select any image you have available to use as wallpaper, and it may be +stored in any location on your hard drive. To have a wallpaper show up in +the list automatically for all users, you should save it to the $KDEDIR/share/wallpapers +folder. + +A pattern is a picture file which &kde; uses as a template to +draw your background. The picture file provides the shapes, but &kde; +provides the colors. &kde; is packaged with several patterns, and you also +can add new patterns. + +To add a new pattern that is available to every user on your +computer, simply place the file in $KDEDIR/share/apps/kdm/patterns/. + +Copy a .desktop file from +this folder, and name it the same as your new pattern image file. +Modify the contents to suit your new pattern. + +To add a new pattern for a single user, add the files to +$KDEHOME/share/apps/kdm/patterns/. + +For best results, the pattern should be a grayscale PNG file. + + + + + + +Theme +This page consists of three sections: + +A list of installed themes, where you can select the one to be used. + +A screenshot with a preview of the selected theme and additional +information like Copyright and Description. + +Three buttons to install or remove a theme and a button to launch +the Get Hot New Stuff dialog where you can download new themes. + +The settings on this page are only available in themed mode. + + + + +Shutdown + +Allow Shutdown +Use this drop down box to choose who is allowed to shut down: + + +Nobody: No one can shutdown the computer using +&kdm;. You must be logged in, and execute a command. + + +Everybody: Everyone can shutdown the computer using +&kdm;. + +Only Root: &kdm; requires that the +root password be entered before shutting down the +computer. + + +You can independently configure who is allowed to issue a +shutdown command for the Local: and +Remote: users. + +Commands Use these text fields to +define the exact shutdown command. The +Halt: command defaults to +/sbin/halt. The Reboot: command +defaults to +/sbin/reboot. + +When Boot manager is set to Grub +or Lilo, &kdm; +will on reboot offer you options for these boot managers. Note that this +option is not available on all operating systems. + + + + +Users + +From here you can change the way users are represented in the +login window. + +Independently of the users you specify by name, you can use the +System UIDs to specify a range of valid +UIDs that are shown in the list. By default user +id's under 1000, which are often system or daemon users, and user id's +over 30000, are not shown. + +You may disable the user list in &kdm; entirely in the +Users section. You can choose from: + + + +Show list + +Only show users you have specifically not excluded in the list +alongside +If you do not check this box, no list will be shown. This is the most secure setting, since an +attacker would then have to guess a valid login name as well as a +password. It is also the preferred option if you have more than a +handful of users to list, or the list itself would become +unwieldy. + + + +Autocompletion + +If this option is checked, &kdm; will automatically complete user names while +they are typed in the line edit. + + + +Inverse selection + +Allows you to instead select a list of users that should +be shown, and all other users will not be +listed. + + + + +You can also enable the Sort users +checkbox, to have the user list sorted alphabetically. If this is +disabled, users will appear in the order they are listed in the +password file. &kdm; will also autocomplete user names if you enable the +Autocompletion option. + +If you choose to show users, then the login window will show +images (which you select), of a list of users. When someone is ready +to login, they may select their user name/image, enter their password, +and they are granted access. + +If you permit a user image, then you can configure the +User Image Source: + +Here you can specify where &kdm; will obtain the images that represent users. +System represents the global folder; these are the pictures you can set +below. User means that &kdm; should read the user's +$HOME/.face.icon file. +The two selections in the middle define the order of preference if both +sources are available. + + +If you choose not to show users, then the login window will be +more traditional. Users will need to type their username and password +to gain entrance. This is the preferred way if you have many users on +this terminal. + + + + +Convenience + +In the Convenience tab you can configure +some options that make life easier for lazy people, like automatic +login or disabling passwords. + +Please think more than twice before using these +options. Every option in the Convenience tab is +well-suited to seriously compromise your system security. Practically, +these options are only to be used in a completely non-critical +environment, ⪚ a private computer at home. + + +Automatic Login + +Automatic login will give anyone access to a certain account on +your system without doing any authentication. You can enable it using +the option Enable Auto-Login. + +You can choose the account to be used for automatic login from +the list labeled User:. + +With Lock session the automatically started session +will be locked immediately (provided it is a &kde; session). This can be used +to obtain a super-fast login restricted to one user. + + +Automatic login can be suppressed by pressing the &Shift; key immediately +after the &X-Server; switches to graphics mode and releasing it when &kdm;'s +hourglass cursor appears. + + + +<guilabel>Preselected User</guilabel> + +You can also choose which user is preselected +when &kdm; starts. The default is None, but you +can choose Previous to have &kdm; default to the +last successfully logged in user, or you can +Specify a particular user to always be selected +from the list. You can also have &kdm; set the focus to the password +field, so that when you reach the &kdm; login screen, you can type the +password immediately. + + + + +<guilabel>Password-Less Login</guilabel> + +Using this feature, you can allow certain users to login without +having to provide their password. Enable this feature using the +Enable Password-Less Logins option. + +Below this option you'll see a list of users on the system. +Enable password-less login for specific users by checking the checkbox +next to the login names. By default, this feature is disabled for +all users. + +Again, this option should only be used in a safe +environment. If you enable it on a rather public system you should +take care that only users with heavy access restrictions are granted +password-less login, ⪚ +guest. + +The Automatically login after X server crash +option allows you to skip the authentication procedure when your X +server accidentally crashed. + + + + + + + + + +&kdmrc-ref; + +&theme-ref; + + + +Configuring your system to use &kdm; + +This chapter assumes that your system is already configured to +run the &X-Window;, and that you only need to reconfigure it to +allow graphical login. + + +Setting up &kdm; + +The fundamental thing that controls whether your computer boots to a +terminal prompt (console mode) or a graphical login prompt is the default +runlevel. The runlevel is set by the program /sbin/init under the control of the +configuration file /etc/inittab. The default runlevels +used by different &UNIX; systems (and different &Linux; distributions) vary, +but if you look at /etc/inittab the start of it should +be something like this: + +# Default runlevel. The runlevels used by RHS are: +# 0 - halt (Do NOT set initdefault to this) +# 1 - Single user mode +# 2 - Multiuser, without NFS +# 3 - Full multiuser mode +# 4 - unused +# 5 - X11 +# 6 - reboot (Do NOT set initdefault to this) + +id:3:initdefault: + + +All but the last line of this extract are comments. The comments +show that runlevel 5 is used for X11 and that runlevel 3 is used for +multi-user mode without X11 (console mode). The final line specifies +that the default runlevel of the system is 3 (console mode). If your +system currently uses graphical login (for example, using &xdm;) its +default runlevel will match the runlevel specified for X11. + +The runlevel with graphical login (&xdm;) for some common &Linux; +distributions is: + + +5 for &RedHat; 3.x and later, and for &Mandrake; +4 for Slackware +3 for &SuSE;. 4.x and 5.x + + +The first step in configuring your system is to ensure that you +can start &kdm; from the command line. Once this is working, you can +change your system configuration so that &kdm; starts automatically +each time you reboot your system. + +To test &kdm;, you must first bring your system to a runlevel +that does not run &xdm;. To do so, issue a command like this: + +/sbin/init + +Instead of the number you should specify the +appropriate runlevel for console mode on your system. + +If your system uses Pluggable Authentication Modules +(PAM), which is normal with recent &Linux; and &Solaris; +systems, you should check that your PAM configuration permits +login through the service named kde. If you previously used +&xdm; successfully, you should not need to make any +changes to your PAM configuration in order to use +&kdm;. /etc/pam.conf or +/etc/pam.d/kde. Information on configuring +PAM is beyond the scope of this handbook, but +PAM comes with comprehensive documentation (try looking in +/usr/share/doc/*pam*/html/). + +Now it's time for you to test &kdm; by issuing the following +command: + +kdm + + +If you get a &kdm; login dialog and you are able to log in, +things are going well. The main thing that can go wrong here is that +the run-time linker might not find the shared &Qt; or &kde; libraries. +If you have a binary distribution of the &kde; libraries, make sure +&kdm; is installed where the libraries believe &kde; is installed and +try setting some environment variables to point to your &kde; and &Qt; +libraries. + +For example: + +export + +export + +export + +export + + + +If you are still unsuccessful, try starting &xdm; instead, to +make sure that you are not suffering from a more serious X +configuration problem. + +When you are able to start &kdm; successfully, you can start to +replace &xdm; by &kdm;. Again, this is distribution-dependent. + + + +For &RedHat;, edit /etc/inittab, look for this + line: +x:5:respawn:/usr/X11/bin/xdm -nodaemon +and replace with: +x:5:respawn:/opt/kde/bin/kdm +This tells init(8) to respawn &kdm; when the +system is in run level 5. Note that &kdm; does not need the + option. + + +For &Mandrake;, the X11 runlevel in +/etc/inittab invokes the shell script +/etc/X11/prefdm, which is set up to select from +amongst several display managers, including &kdm;. Make sure that all +the paths are correct for your installation. + + +For &SuSE;, edit /sbin/init.d/xdm to add a +first line: + +. /etc/rc.config +DISPLAYMANAGER=kdm +export DISPLAYMANAGER + +For FreeBSD, edit /etc/ttys and find +the line like this: +ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure +and edit it to this: +ttyv8 "/opt/kde/bin/kdm" xterm on secure + + +Most other distributions are a variation of one of +these. + + +At this stage, you can test &kdm; again by bringing your system +to the runlevel that should now run &kdm;. To do so, issue a command +like this: + +/sbin/init + + +Instead of the number you should specify the +appropriate runlevel for running X11 on your system. + +The final step is to edit the initdefault +entry in /etc/inittab to specify the appropriate +runlevel for X11. + +Before you make this change, ensure that you have a way +to reboot your system if a problem occurs. This might be a +rescue floppy-disk provided by your operating system +distribution or a specially-designed rescue +floppy-disk, such as tomsrtbt. Ignore this advice +at your peril. + +This usually involves changing the line: +id:3:initdefault: +to +id:5:initdefault: + +When you reboot your system, you should end up with the +graphical &kdm; login dialog. + +If this step is unsuccessful the most likely problem is that the +environment used at boot time differs from the environment that you used for +testing at the command line. If you are trying to get two versions of &kde; +to co-exist, be particularly careful that the settings you use for your +PATH and LD_LIBRARY_PATH environment variables +are consistent, and that the startup scripts are not over-riding them in +some way. + + + + + + +Supporting multiple window managers + +&kdm; detects most available window managers and desktop environments when +it is run. Installing a new one should make it automatically available in +the &kdm; main dialog's Session Type submenu. + +If you have a very new window manager, or something that &kdm; does +not support, the first thing you should check is that the executable to be +run is in the PATH and has not been renamed by the distributor +into something unexpected. + +If the case is that the session type is not supported by &kdm; yet +(maybe because it is too new), you can quite easily add it. + +The session types are defined by .desktop files +located in the directories listed in . The +last named directory contains the system-provided default session types +and is $KDEDIR/share/apps/kdm/sessions +in an installation from source. Software upgrades will typically overwrite +anything in here, so it is unwise to use it for configuration purposes. +Instead, a separate configuration directory should be listed first. It is +set to $KDEDIR/share/config/kdm/sessions +in an installation from source, but distributors often change it to something +like /etc/kde4/kdm/sessions. +You can simply add an appropriately named .desktop files here. The fields are: + +[Desktop Entry] +Encoding=UTF-8 This is fixed to and +may be omitted +Type=XSession This is fixed to and +may be omitted +Exec=executable name Passed to +eval exec in a Bourne shell +TryExec=executable name Supported +but not required +Name=name to show in the &kdm; session list + +There are also three magic types: + + + +default + + +The default session for &kdm; is normally &kde; but can be configured by the +system administrator. + + + + +custom + + +The Custom session will run the user's ~/.xsession if it exists, falling +back to the default session otherwise. + + + + +failsafe + + +Failsafe will run a very plain session, and is useful only for debugging +purposes. + + + + + +To override a session type, copy the .desktop file from the data dir +to the config dir and edit it at will. Removing the shipped session types +can be accomplished by shadowing them with .desktop files +containing Hidden=true. For the magic session types no .desktop files exist +by default, but &kdm; pretends they would, so you can override them like any +other type. + + + + +Using &kdm; for Remote Logins (&XDMCP;) + +&XDMCP; is the Open Group standard, the X Display Manager +Control Protocol. This is used to set up connections between +remote systems over the network. + +&XDMCP; is useful in multiuser situations where there are users +with workstations and a more powerful server that can provide the +resources to run multiple X sessions. For example, &XDMCP; is a good +way to reuse old computers - a Pentium or even 486 computer with 16 Mb +RAM is sufficient to run X itself, and using &XDMCP; such a computer can +run a full modern &kde; session from a server. For the server part, +once a single &kde; (or other environment) session is running, running +another one requires very few extra resources. + +However, allowing another method of login to your machine +obviously has security implications. You should run this service only +if you need to allow remote X Servers to start login sessions on your +system. Users with a single &UNIX; computer should not need to run +this. + + + + +Advanced Topics + + +Command Sockets + +This is a feature you can use to remote-control &kdm;. It's mostly +intended for use by &ksmserver; and &kdesktop; from a running session, but +other applications are possible as well. + +The sockets are &UNIX; domain sockets which live in subdirectories of the +directory specified by =. The subdir is the key to +addressing and security; the sockets all have the file name +socket and file permissions +rw-rw-rw- (0666). This is because some systems don't care +for the file permission of the socket files. + +There are two types of sockets: the global one (dmctl) and the +per-display ones (dmctl-<display>). + +The global one's subdir is owned by root, the subdirs of the per-display +ones' are owned by the user currently owning the session (root or the +logged in user). Group ownership of the subdirs can be set via FifoGroup=, +otherwise it's root. The file permissions of the subdirs are rwxr-x--- +(0750). + +The fields of a command are separated by tabs (\t), the +fields of a list are separated by spaces, literal spaces in list fields are +denoted by \s. + +The command is terminated by a newline (\n). + +The same applies to replies. The reply on success is +ok, possibly followed by the requested +information. The reply on error is an errno-style word (⪚ +perm, noent, &etc;) +followed by a longer explanation. + + +Global commands: + + +login +(now | schedule) user password +[session_arguments] + +login user at specified display. if now is +specified, a possibly running session is killed, otherwise the login is done +after the session exits. session_arguments are printf-like escaped contents +for .dmrc. Unlisted keys will default to previously saved values. + + + + +resume + +Force return from console mode, even if TTY logins are still +active. + + + + +manage display +[display_class +[auth_name auth_data]] + +Start managing the named foreign display. +display_class, if specified and non-empty, +will be used for configuration matching; see . + +auth_name and auth_data +need to be passed if the display requires X authorization. The format is +the same as the 2nd and 3rd column of the xauth list +output. + + + + +unmanage display + +Stop managing the named foreign display. + + + + + + +Per-display commands: + +lock + +The display is marked as locked. If the &X-Server; crashes in this +state, no auto-relogin will be performed even if the option is on. + + + +unlock + +Reverse the effect of lock, and re-enable +auto-relogin. + + + +suicide + +The currently running session is forcibly terminated. No auto-relogin +is attempted, but a scheduled "login" command will be executed. + + + + + +Commands for all sockets + + +caps + +Returns a list of this socket's capabilities: + + + +kdm + +identifies &kdm;, in case some other DM implements this protocol, +too + + + +list, lock, +suicide, login, +resume, manage + + +The respective command is supported + + + +bootoptions + +The listbootoptions command and the + to shutdown are supported + + + +shutdown <list> + +shutdown is supported and allowed for the listed +users (a comma separated list.) * means all +authenticated users. + + + +nuke <list> + +Forced shutdown may be performed by the listed users. + + + +nuke + +Forced shutdown may be performed by everybody + + + +reserve <number> + +Reserve displays are configured, and number +are available at this time + + + + + + + + +list [all | +alllocal] + +Return a list of running sessions. By default all active sessions are +listed (this is useful for a shutdown warning). If all +is specified, passive sessions are listed as well. +If alllocal is specified, passive +sessions are listed as well, but all incoming remote sessions are +skipped (this is useful for a fast user switching agent). +Each session entry is a comma separated tuple of: + +Display or TTY name +VT name for local sessions, remote host name prefixed by +@ for remote TTY sessions, otherwise empty +Logged in user's name, empty for passive sessions and +outgoing remote sessions (local chooser mode) +Session type for active local sessions, remote hostname for +outgoing remote sessions, empty for passive sessions. +A Flag field: +* for the display belonging +to the requesting socket. +! for sessions that cannot be killed by the +requesting socket. +t for TTY sessions. + + + +New fields may be added in the future. + + + + +reserve + +Start a reserve login screen. If nobody logs in within some +time, the display is removed again. When the session on the display +exits, the display is removed, too. +Permitted only on sockets of local displays and the global +socket. + + + + +activate +(vt|display) + +Switch to a particular VT (virtual terminal). The VT may be specified +either directly (⪚ vt3) or by a display using it +(eg; :2). +Permitted only on sockets of local displays and the global +socket. + + + + +listbootoptions + +List available boot options. +The return value contains these tokens: + + +A list of boot options (as shown in &kdm; itself). + + +The default boot option. + + +The current boot option. + + +The default and current option are zero-based indices into the list +of boot options. If either one is unset or not determinable, it is -1. + + + + +shutdown (reboot | +halt) +[=bootchoice] +(ask|trynow|forcenow|schedule|start +(-1|end +(force|forcemy|cancel)))) + +Request a system shutdown, either a reboot or a halt/poweroff. +An OS choice for the next boot may be specified from the list returned +by listbootoptions +Shutdowns requested from per-display sockets are executed when the +current session on that display exits. Such a request may pop up a dialog +asking for confirmation and/or authentication +start is the time for which the shutdown is +scheduled. If it starts with a plus-sign, the current time is added. Zero +means immediately. +end is the latest time at which the shutdown +should be performed if active sessions are still running. If it starts with +a plus-sign, the start time is added. -1 means wait infinitely. If end is +through and active sessions are still running, &kdm; can do one of the +following: + +cancel - give up the +shutdown +force - shut down +nonetheless +forcemy - shut down nonetheless if +all active sessions belong to the requesting user. +Only for per-display sockets. + +start and end are +specified in seconds since the &UNIX; epoch. +trynow is a synonym for 0 0 +cancel, forcenow for 0 0 +force and schedule for 0 +-1. +ask attempts an immediate shutdown and +interacts with the user if active sessions are still running. Only for +per-display sockets. + + + + +shutdown cancel +[local|global} + +Cancel a scheduled shutdown. The global socket always cancels the +currently pending shutdown, while per-display sockets default to cancelling +their queued request. + + + + +shutdown status + +Return a list with information about shutdowns. +The entries are a comma-separated tuples of: + + +(global|local) - +pending vs. queued shutdown. A local entry can be returned only by a +per-display socket. + +(halt|reboot) +start +end +("ask"|"force"|"forcemy"|"cancel") +Numeric user ID of the requesting user, -1 for the global +socket. +The next boot OS choice or "-" for none. + +New fields might be added later + + + + + +There are two ways of using the sockets: + + +Connecting them directly. FifoDir is exported as +$DM_CONTROL; the name of per-display sockets can be derived +from $DISPLAY. + + +By using the kdmctl command (⪚ from within a +shell script). Try kdmctl to find out +more. + + + +Here is an example bash script reboot into FreeBSD: + +if kdmctl | grep -q shutdown; then + IFS=$'\t' + set -- `kdmctl listbootoptions` + if [ "$1" = ok ]; then + fbsd=$(echo "$2" | tr ' ' '\n' | sed -ne 's,\\s, ,g;/freebsd/I{p;q}') + if [ -n "$fbsd" ]; then + kdmctl shutdown reboot "=$fbsd" ask > /dev/null + else + echo "FreeBSD boot unavailable." + fi + else + echo "Boot options unavailable." + fi +else + echo "Cannot reboot system." +fi + + + + + +Other sources of information + +Since &kdm; is descended from &xdm;, the xdm man page may provide useful background +information. For X-related problems try the man pages X and startx. If you have +questions about &kdm; that are not answered by this handbook, take advantage of +the fact the &kdm; is provided under the terms of the &GNU; +General Public License: look at the source code. + + + + + +Credits and License + +&kdm; is derived from, and includes code from, +&xdm; © Keith Packard, MIT X Consortium. + +&kdm; 0.1 was written by &Matthias.Ettrich;. Later versions till &kde; +2.0.x were written by &Steffen.Hansen;. Some new features for &kde; 2.1.x and +a major rewrite for &kde; 2.2.x made by &Oswald.Buddenhagen;. + +Other parts of the &kdm; code are copyright by the authors, and +licensed under the terms of the &GNU; +GPL. Anyone is allowed to change &kdm; and redistribute the result +as long as the names of the authors are mentioned. + +&kdm; requires the &Qt; library, which is copyright Troll Tech AS. + +Documentation contributors: + + +Documentation written by &Steffen.Hansen; +&Steffen.Hansen.mail; + +Documentation extended by Gregor +Zumsteinzumstein@ssd.ethz.ch. Last update August 9, +1998 + +Documentation revised for &kde; 2 by &Neal.Crook; +&Neal.Crook.mail;. Last update August 6, +2000 + +Documentation extended and revised for &kde; 2.2 and 4.0 by +&Oswald.Buddenhagen; &Oswald.Buddenhagen.mail;. Last update December 7, +2007 + + + +Documentation copyright &Steffen.Hansen;, Gregor Zumstein, &Neal.Crook; +and &Oswald.Buddenhagen;. +This document also includes large parts of the &xdm; man page, +which is © Keith Packard. +The theme format documentation is heavily based on the GDM manual, +which is © Martin K. Petersen, George Lebl, &RedHat;, Inc. and +Sun Microsystems, Inc. + + + +&underFDL; + + + + +Glossary + + +greeter +The greeter is the login dialog, &ie; the part of &kdm; +which the user sees. + + + + +entropy +The entropy of a system is the measure of its +unpredictability. This is used during the generation of random numbers. + + + + + + + diff --git a/doc/kdm/kdmrc-ref.docbook b/doc/kdm/kdmrc-ref.docbook new file mode 100644 index 00000000..e83f8743 --- /dev/null +++ b/doc/kdm/kdmrc-ref.docbook @@ -0,0 +1,2402 @@ + + + +The Files &kdm; Uses for Configuration + +This chapter documents the files that control &kdm;'s behavior. +Some of this can be also controlled from the &systemsettings; module, but +not all. + + +&kdmrc; - The &kdm; master configuration file + +The basic format of the file is INI-like. +Options are key/value pairs, placed in sections. +Everything in the file is case sensitive. +Syntactic errors and unrecognized key/section identifiers cause &kdm; to +issue non-fatal error messages. + +Lines beginning with # are comments; empty lines +are ignored as well. + +Sections are denoted by +[Name of Section]. + + +You can configure every X-display individually. +Every display has a display name, which consists of a host name +(which is empty for local displays specified in +or ), a colon, and a display number. +Additionally, a display belongs to a +display class (which can be ignored in most cases). + +Sections with display-specific settings have the formal syntax +[X- host [ : number [ _ class ] ] - sub-section ] + +All sections with the same sub-section +make up a section class. + +You can use the wildcard * (match any) for +host, number, +and class. You may omit trailing components; +they are assumed to be * then. The host part may be a +domain specification like .inf.tu-dresden.de +or the wildcard + (match non-empty). + +From which section a setting is actually taken is determined by +these rules: + + + +An exact match takes precedence over a partial match (for the +host part), which in turn takes precedence over a wildcard +(+ taking precendence over *). + + + +Precedence decreases from left to right for equally exact matches. + + + + + +Example: display name myhost.foo:0, class dpy + + + +[X-myhost.foo:0_dpy] precedes + + +[X-myhost.foo:0_*] (same as [X-myhost.foo:0]) precedes + + +[X-myhost.foo:*_dpy] precedes + + +[X-myhost.foo:*_*] (same as [X-myhost.foo]) precedes + + +[X-.foo:*_*] (same as [X-.foo]) precedes + + +[X-+:0_dpy] precedes + + +[X-*:0_dpy] precedes + + +[X-*:0_*] (same as [X-*:0]) precedes + + +[X-*:*_*] (same as [X-*]). + + +These sections do not match this display: +[X-hishost], [X-myhost.foo:0_dec], [X-*:1], [X-:*] + + + + + + + +Common sections are [X-*] (all displays), [X-:*] (all local displays) +and [X-:0] (the first local display). + +The format for all keys is + = value. +Keys are only valid in the section class they are defined for. +Some keys do not apply to particular displays, in which case they are ignored. + + +If a setting is not found in any matching section, the default +is used. + +Special characters need to be backslash-escaped (leading and trailing +spaces (\s), tab (\t), linefeed +(\n), carriage return (\r) and the +backslash itself (\\)). +In lists, fields are separated with commas without whitespace in between. + +Some command strings are subject to simplified sh-style word splitting: +single quotes (') and double quotes (") +have the usual meaning; the backslash quotes everything (not only special +characters). Note that the backslashes need to be doubled because of the +two levels of quoting. + +A pristine &kdmrc; is very thoroughly commented. +All comments will be lost if you change this file with the +&systemsettings; frontend. + + + +The [General] section of &kdmrc; + + +This section contains global options that do not fit into any specific section. + + + + + + + + +This option exists solely for the purpose of clean automatic upgrades. +Do not change it, you may interfere with future +upgrades and this could result in &kdm; failing to run. + + + + + + + + +List of displays (&X-Server;s) permanently managed by &kdm;. Displays with a +hostname are foreign displays which are expected to be already running, +the others are local displays for which &kdm; starts an own &X-Server;; +see . Each display may belong to a display class; +append it to the display name separated by an underscore. +See for the details. + +The default is :0. + + + + + + + +List of on-demand displays. See for syntax. + +Empty by default. + + + + + + + +List of Virtual Terminals to allocate to &X-Server;s. For negative numbers the +absolute value is used, and the VT will be allocated only +if the kernel says it is free. If &kdm; exhausts this list, it will allocate +free VTs greater than the absolute value of the last entry +in this list. +Currently Linux only. + +Empty by default. + + + + + + + +This option is for operating systems (OSs) with support +for virtual terminals (VTs), by both &kdm; and the +OSs itself. +Currently this applies only to Linux. + +When &kdm; switches to console mode, it starts monitoring all +TTY lines listed here (without the leading +/dev/). +If none of them is active for some time, &kdm; switches back to the X login. + +Empty by default. + + + + + + + +The filename specified will be created to contain an ASCII representation +of the process ID of the main &kdm; process; the PID will not be stored +if the filename is empty. + +Empty by default. + + + + + + + +This option controls whether &kdm; uses file locking to keep multiple +display managers from running onto each other. + +The default is true. + + + + + + + +This names a directory under which &kdm; stores &X-Server; authorization +files while initializing the session. &kdm; expects the system to clean up +this directory from stale files on reboot. + +The authorization file to be used for a particular display can be +specified with the option in [X-*-Core]. + +The default is /var/run/xauth. + + + + + + + +This boolean controls whether &kdm; automatically re-reads its +configuration files if it finds them to have changed. + +The default is true. + + + + + + + +Additional environment variables &kdm; should pass on to all programs it runs. +LD_LIBRARY_PATH and XCURSOR_THEME are good candidates; +otherwise, it should not be necessary very often. + +Empty by default. + + + + + + + +If the system has no native entropy source like /dev/urandom (see +) and no entropy daemon like EGD (see + and ) is running, +&kdm; will fall back to its own pseudo-random number generator +that will, among other things, successively checksum parts of this file +(which, obviously, should change frequently). + +This option does not exist on Linux and various BSDs. + +The default is /dev/mem. + + + + + + + +If the system has no native entropy source like /dev/urandom (see +), read random data from a Pseudo-Random +Number Generator Daemon, +like EGD (http://egd.sourceforge.net) via this UNIX domain socket. + +This option does not exist on Linux and various BSDs. + +Empty by default. + + + + + + + +Same as , only use a TCP socket on localhost. + + + + + + + + +The path to a character device which &kdm; should read random data from. +Empty means to use the system's preferred entropy device if there is one. + +This option does not exist on OpenBSD, as it uses the arc4_random +function instead. + +Empty by default. + + + + + + + +The directory in which the command sockets should +be created; make it empty to disable them. + +The default is /var/run/xdmctl. + + + + + + + +The group to which the global command socket should belong; +can be either a name or a numerical ID. + + + + + + + + +The user the greeter should run as. Empty results in root. +Consider the impact on when setting it. + +Empty by default. + + + + + + + +The directory in which &kdm; should store persistent working data; such data +is, for example, the previous user that logged in on a particular display. + +The default is /var/lib/kdm. + + + + + + + +The directory in which &kdm; should store users' .dmrc files. This is only +needed if the home directories are not readable before actually logging in +(like with AFS). + +Empty by default. + + + + + + + + +The [Xdmcp] section of &kdmrc; + + +This section contains options that control &kdm;'s handling of +&XDMCP; requests. + + + + + + + + +Whether &kdm; should listen to incoming &XDMCP; requests. + +The default is true. + + + + + + + +This indicates the UDP port number which &kdm; uses to listen for incoming +&XDMCP; requests. Unless you need to debug the system, leave this with its +default value. + +The default is 177. + + + + + + + +XDM-AUTHENTICATION-1 style &XDMCP; authentication requires a private +key to be shared between &kdm; and the terminal. This option specifies +the file containing those values. Each entry in the file consists of a +display name and the shared key. + +Empty by default. + + + + + + + +To prevent unauthorized &XDMCP; service and to allow forwarding of &XDMCP; +IndirectQuery requests, this file contains a database of hostnames which +are either allowed direct access to this machine, or have a list of hosts +to which queries should be forwarded to. The format of this file is +described in . + +The default is ${kde_confdir}/kdm/Xaccess. + + + + + + + +Number of seconds to wait for the display to respond after the user has +selected a host from the chooser. If the display sends an &XDMCP; +IndirectQuery within this time, the request is forwarded to the chosen +host; otherwise, it is assumed to be from a new session and the chooser +is offered again. + +The default is 15. + + + + + + + +When computing the display name for &XDMCP; clients, the name resolver will +typically create a fully qualified host name for the terminal. As this is +sometimes confusing, &kdm; will remove the domain name portion of the host +name if it is the same as the domain name of the local host when this option +is enabled. + +The default is true. + + + + + + + +Use the numeric IP address of the incoming connection on multihomed hosts +instead of the host name. This is to avoid trying to connect on the wrong +interface which might be down at this time. + +The default is false. + + + + + + + +This specifies a program which is run (as +root) when an &XDMCP; +DirectQuery or BroadcastQuery is received and this host is configured +to offer &XDMCP; display management. The output of this program may be +displayed in a chooser window. If no program is specified, the string +Willing to manage is sent. + +Empty by default. + + + + + + + + +The [Shutdown] section of &kdmrc; + + +This section contains global options concerning system shutdown. + + + + + + + + +The command (subject to word splitting) to run to halt/poweroff the system. + +The default is something reasonable for the system on which &kdm; was built, like +/sbin/shutdown  now. + + + + + + + + +The command (subject to word splitting) to run to reboot the system. + +The default is something reasonable for the system &kdm; on which was built, like +/sbin/shutdown  now. + + + + + + + + +Whether it is allowed to shut down the system via the global command socket. + +The default is false. + + + + + + + +Whether it is allowed to abort active sessions when shutting down the +system via the global command socket. + +This will have no effect unless is enabled. + +The default is true. + + + + + + + +The boot manager &kdm; should use for offering boot options in the +shutdown dialog. + + + +None +no boot manager + + +Grub +Grub boot manager + + +Grub2 +Grub2 boot manager + + +Lilo +Lilo boot manager (Linux on i386 & x86-64 only) + + +The default is None. + + + + + + + + +The [X-*-Core] section class of &kdmrc; + + +This section class contains options concerning the configuration +of the &kdm; backend (core). + + + + + + + + +See . + +The default is 15. + + + + + + + +See . + +The default is 120. + + + + + + + +These options control the behavior of &kdm; when attempting to open a +connection to an &X-Server;. is the length +of the pause (in seconds) between successive attempts, + is the number of attempts to make and + is the amount of time to spend on a +connection attempt. After attempts have been +made, or if seconds elapse in any particular +connection attempt, the start attempt is considered failed. + +The default is 5. + + + + + + + +How many times &kdm; should attempt to start a foreign +display listed in before giving up +and disabling it. +Local displays are attempted only once, and &XDMCP; displays are retried +indefinitely by the client (unless the option +was given to the &X-Server;). + +The default is 4. + + + + + + + +How many times &kdm; should attempt to start up a local &X-Server;. +Starting up includes executing it and waiting for it to come up. + +The default is 1. + + + + + + + +How many seconds &kdm; should wait for a local &X-Server; to come up. + +The default is 30. + + + + + + + +The command line to start the &X-Server;, without display number and VT spec. +Note that with some &X-Server;s (in particular, OpenSolaris') it is necessary +to put most additional arguments into and + even if they are the same for both. +This string is subject to word splitting. + +The default is something reasonable for the system on which &kdm; was built, +like /usr/X11R6/bin/X. + + + + + + + + +Additional arguments for the &X-Server;s for local sessions. +This string is subject to word splitting. + +Empty by default. + + + + + + + +Additional arguments for the &X-Server;s for remote sessions. +This string is subject to word splitting. + +Empty by default. + + + + + + + +The VT the &X-Server; should run on. + should be used instead of this option. +Leave it zero to let &kdm; assign a VT automatically. +Set it to -1 to avoid assigning a VT +alltogether - this is required for setups with multiple physical consoles. +Currently Linux only. + + + + + + + + +This option is for OSs without support for +VTs, either by &kdm; or the OS itself. +Currently this applies to all OSs but Linux. + +When &kdm; switches to console mode, it starts monitoring this +TTY line (specified without the leading +/dev/) for activity. If the line is not used for some time, +&kdm; switches back to the X login. + +Empty by default. + + + + + + + +The user the &X-Server; should run as. Empty results in root. + +Empty by default. + + + + + + + +See . + +The default is 5. + + + + + + + +To discover when remote displays disappear, &kdm; +regularly pings them. + specifies the time (in minutes) between the +pings and specifies the maximum amount of +time (in minutes) to wait for the terminal to respond to the request. If +the terminal does not respond, the session is declared dead and terminated. + +If you frequently use X terminals which can become isolated from +the managing host, you may wish to increase the timeout. The only worry +is that sessions will continue to exist after the terminal has been +accidentally disabled. + +The default is 5. + + + + + + + +Whether &kdm; should restart the local &X-Server; after session exit instead +of resetting it. Use this if the &X-Server; leaks memory or crashes the system +on reset attempts. + +The default is false. + + + + + + + +Controls whether &kdm; generates and uses authorization for +local &X-Server; connections. +For &XDMCP; displays the authorization requested by the display is used; +foreign non-&XDMCP; displays do not support authorization at all. + +The default is true. + + + + + + + +If is true, use the authorization mechanisms +listed herein. The MIT-MAGIC-COOKIE-1 authorization is always available; +XDM-AUTHORIZATION-1, SUN-DES-1 and MIT-KERBEROS-5 might be available as well, +depending on the build configuration. + +The default is DEF_AUTH_NAME. + + + + + + + +Some old &X-Server;s re-read the authorization file +at &X-Server; reset time, instead of when checking the initial connection. +As &kdm; generates the authorization information just before connecting to +the display, an old &X-Server; would not get up-to-date authorization +information. This option causes &kdm; to send SIGHUP to the &X-Server; +after setting up the file, causing an additional &X-Server; reset to occur, +during which time the new authorization information will be read. + +The default is false. + + + + + + + +This file is used to communicate the authorization data from &kdm; to +the &X-Server;, using the &X-Server; command line +option. It should be kept in a directory which is not world-writable +as it could easily be removed, disabling the authorization mechanism in +the &X-Server;. If not specified, a random name is generated from + and the name of the display. + +Empty by default. + + + + + + + +This option specifies the name of the file to be loaded by +xrdb as the resource database onto the root window +of screen 0 of the display. KDE programs generally do not use +X-resources, so this option is only needed if the +program needs some X-resources. + +Empty by default. + + + + + + + +The xrdb program to use to read the X-resources file +specified in . +The command is subject to word splitting. + +The default is ${x_bindir}/xrdb. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) before offering the +greeter window. This may be used to change the appearance of the screen +around the greeter window or to put up other windows (e.g., you may want +to run xconsole here). +Usually, a script named Xsetup is used here. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) after the user +authentication process succeeds. +Usually, a script named Xstartup is used here. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies a program which is run (as +root) after the session +terminates. +Usually, a script named Xreset is used here. +See . + +Empty by default. + + + + + + + +This string is subject to word splitting. +It specifies the session program to be executed (as the user owning +the session). +Usually, a script named Xsession is used here. +See . + +The default is ${x_bindir}/xterm -ls -T. + + + + + + + +If the program fails to execute, &kdm; will +fall back to this program. This program is executed with no arguments, +but executes using the same environment variables as the session would +have had (see ). + +The default is ${x_bindir}/xterm. + + + + + + + +The PATH environment variable for +non-root s. + +The default depends on the system &kdm; was built on. + + + + + + + + +The PATH environment variable for all programs but +non-root +s. Note that it is good practice not to include +. (the current directory) into this entry. + +The default depends on the system &kdm; was built on. + + + + + + + + +The SHELL environment variable for all programs but the +. + +The default is /bin/sh. + + + + + + + +When &kdm; is unable to write to the usual user authorization file +($HOME/.Xauthority), it creates a unique file name in this +directory and points the environment variable XAUTHORITY +at the created file. + +The default is /tmp. + + + + + + + +If true, will be used unconditionally. + +The default is false. + + + + + + + +If enabled, &kdm; will automatically restart a session after an &X-Server; +crash (or if it is killed by Alt-Ctrl-BackSpace). Note that enabling this +feature opens a security hole: a secured display lock can be circumvented +(unless &kde;'s built-in screen locker is used). + +The default is false. + + + + + + + +If disabled, do not allow root +(and any other user with UID = 0) to log in directly. + +The default is true. + + + + + + + +If disabled, only users that have passwords assigned can log in. + +The default is true. + + + + + + + +Who is allowed to shut down the system. This applies both to the +greeter and to the command sockets. + + + +None +no Shutdown... menu entry is shown at all + + +Root +the root password must be entered to shut down + + +All +everybody can shut down the machine + + +The default is All. + + + + + + + +Who is allowed to abort active sessions when shutting down. + + + +None +no forced shutdown is allowed at all + + +Root +the root password must be entered to shut down forcibly + + +All +everybody can shut down the machine forcibly + + +The default is All. + + + + + + + +The default choice for the shutdown condition/timing. + + + +Schedule +shut down after all active sessions exit (possibly at once) + + +TryNow +shut down, if no active sessions are open; otherwise, do nothing + + +ForceNow +shut down unconditionally + + +The default is Schedule. + + + + + + + +How to offer shutdown scheduling options: + + + +Never +not at all + + +Optional +as a button in the simple shutdown dialogs + + +Always +instead of the simple shutdown dialogs + + +The default is Never. + + + + + + + +Enable password-less logins on this display. Use with extreme care! + +The default is false. + + + + + + + +The users that do not need to provide a password to log in. +Items which are prefixed with @ represent all users in the +user group named by that item. +* means all users but +root +(and any other user with UID = 0). +Never list root. + +Empty by default. + + + + + + + +Enable automatic login. Use with extreme care! + +The default is false. + + + + + + + +If true, auto-login after logout. If false, auto-login is performed only +when a display session starts up. + +The default is false. + + + + + + + +The delay in seconds before automatic login kicks in. This is also known as +Timed Login. + + + + + + + + +The user to log in automatically. Never specify root! + +Empty by default. + + + + + + + +The password for the user to log in automatically. This is not required +unless the user is logged into a NIS or Kerberos domain. If you use this +option, you should chmod  kdmrc for obvious reasons. + +Empty by default. + + + + + + + +Immediately lock the automatically started session. This works only with +KDE sessions. + +The default is false. + + + + + + + +A list of directories containing session type definitions. +Ordered by falling priority. + +The default is ${kde_datadir}/kdm/sessions. + + + + + + + +The file (relative to the user's home directory) to redirect the session +output to. + +The following character pairs are replaced by their value: + + +%d +name of the current display + + +%u +login name of the current user + + +%r +empty at first. See below. + + +%% +a single % + + +When the constructed filename cannot be used safely and the specification +contains +%stuffr, +other names will be tried - this time expanding +%stuffr +to stuff followed by a random number. + +The default is .xsession-errors. + + + + + + + +Fallback when cannot be used. The same expansions are +supported. Do not use relative paths here. + +The default is /tmp/xerr-%u-%d%-r. + + + + + + + +Specify whether &kdm;'s built-in utmp/wtmp/lastlog registration should +be used. If it is not, the tool sessreg should be used +in the and scripts, or, +alternatively, the pam_lastlog module should be used on +PAM-enabled systems. + +The default is true. + + + + + + + + +The [X-*-Greeter] section class of &kdmrc; + + +This section class contains options concerning the configuration +of the &kdm; frontend (greeter). + + + + + + + + +Specify the widget style for the greeter. Empty means to use the +built-in default which currently is Oxygen-air. + +Empty by default. + + + + + + + +Specify the widget color scheme for the greeter. Empty means to use the +built-in default which currently is Oxygen-air. + +Empty by default. + + + + + + + +What should be shown in the greeter righthand of the input lines (if + is disabled) or above them (if + is enabled): + + + +None +nothing + + +Logo +the image specified by + + +Clock +a neat analog clock + + +The default is Clock. + + + + + + + +The image to show in the greeter if is +Logo. + +Empty by default. + + + + + + + +The relative coordinates (percentages of the screen size; X,Y) at which +the center of the greeter is put. &kdm; aligns the greeter to the edges +of the screen it would cross otherwise. + +The default is 50,50. + + + + + + + +The screen the greeter should be displayed on in multi-headed and Xinerama +setups. The numbering starts with 0. For Xinerama, it corresponds to the +listing order in the active ServerLayout section of XF86Config; -1 means +to use the upper-left screen, -2 means to use the upper-right screen. + + + + + + + + +The headline in the greeter. An empty greeting means none at all. + +The following character pairs are replaced by their value: + + +%d +name of the current display + + +%h +local host name, possibly with the + domain name + + +%n +local node name, most probably the host name without the + domain name + + +%s +operating system + + +%r +operating system version + + +%m +machine (hardware) type + + +%% +a single % + + + +The default is Welcome to %s at %n. + + + + + + + +Whether the fonts used in the greeter should be antialiased. + +The default is false. + + + + + + + +The font for the greeter headline. The value is encoded. + +The default is Serif 20pt bold. + + + + + + + +The normal font used in the greeter. The value is encoded. + +The default is Sans Serif 10pt. + + + + + + + +The font used for the Login Failed message. The value is encoded. + +The default is Sans Serif 10pt bold. + + + + + + + +What to do with the Num Lock modifier for the time the greeter is running: + + + +Off +turn off + + +On +turn on + + +Keep +do not change the state + + +The default is Keep. + + + + + + + +Language and locale to use in the greeter, encoded like $LANGUAGE. +If empty, the settings from the environment are used. + +Empty by default. + + + + + + + +Enable autocompletion in the username line edit. + +The default is false. + + + + + + + +Show a user list with unix login names, real names, and images in the greeter. + +The default is true. + + + + + + + +This option controls which users will be shown in the user view +() and/or offered for autocompletion +(). +If it is Selected, contains +the final list of users. +If it is NotHidden, the initial user list contains all +users found on the system. Users contained in are +removed from the list, just like all users with a UID greater than specified +in and users with a non-zero UID less than +specified in . +Items in and +which are prefixed with @ represent all users in the +user group named by that item. +Finally, the user list will be sorted alphabetically, if + is enabled. + +The default is NotHidden. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + + + + + + + + +See . + +The default is 65535. + + + + + + + +See . + +The default is true. + + + + + + + +If is enabled, this specifies where &kdm; gets the +images from: + + + +AdminOnly +from <>/$USER.face[.icon] + + +PreferAdmin +prefer <>, fallback on $HOME + + +PreferUser +... and the other way round + + +UserOnly +from the user's $HOME/.face[.icon] + + + + +The images can be in any format Qt recognizes, but the filename +must match &kdm;'s expectations: .face.icon should be a +48x48 icon, while .face should be a 300x300 image. +Currently the big image is used only as a fallback and is scaled down, +but in the future it might be displayed full-size in the logo area or a +tooltip. +To be accessible to &kdm;, the images must be world readable and their +parent directories must be world executable. + +The default is AdminOnly. + + + + + + + +See . + +The default is ${kde_datadir}/kdm/faces. + + + + + + + +Specify, if/which user should be preselected for log in: + + + +None +do not preselect any user + + +Previous +the user which successfully logged in last time + + +Default +the user specified in the option + + + + +If is enabled and a user was preselected, +the cursor is placed in the password input field automatically. + +Enabling user preselection can be considered a security hole, +as it presents a valid login name to a potential attacker, so he +only needs to guess the password. On the other hand, +one could set to a fake login name. + + +The default is None. + + + + + + + +See . + +Empty by default. + + + + + + + +See . + +The default is false. + + + + + + + +If this is true, the entered password is echoed as bullets. Otherwise, +no feedback is given at all. + +The default is true. + + + + + + + +If enabled, &kdm; will automatically start the krootimage +program to set up the background; otherwise, the +program is responsible for the background. + +The default is true. + + + + + + + +The configuration file to be used by krootimage. +It contains a section named [Desktop0] like +kdesktoprc does. Its options are not described +herein; guess their meanings or use the control center. + +The default is ${kde_confdir}/kdm/backgroundrc. + + + + + + + +To improve security, the greeter may grab mouse and keyboard input so +no other X clients can eavesdrop it. However, the X authorization +mechanism will usually prevent malicious X clients from connecting +in the first place. Consequently, enabling grabs for local displays +is pointless and only marginally improves security for remote displays. + +The mouse grab will make on-screen keyboards unusable. + + + + + +Never +never grab + + +IfNoAuth +grab if the display requires no X authorization + + +Always +always grab + + +The default is IfNoAuth. + + + + + + + +To improve security, the greeter grabs the &X-Server; and then the input +when it starts up. This option specifies if the &X-Server; grab should be held +for the duration of the name/password reading. When disabled, the &X-Server; +is ungrabbed after the input grabs succeed; otherwise, the &X-Server; is +grabbed until just before the session begins. + +Enabling this option disables and +. + + +The default is false. + + + + + + + +This option specifies the maximum time &kdm; will wait for the grabs to +succeed. A grab may fail if some other X-client has the &X-Server; or the +keyboard grabbed, or possibly if the network latencies are very high. You +should be cautious when raising the timeout, as a user can be spoofed by +a look-alike window on the display. If a grab fails, &kdm; kills and +restarts the &X-Server; (if possible) and the session. + +The default is 3. + + + + + + + +Warn, if a display has no X-authorization. This will be the case if + + + the authorization file for a local &X-Server; could not be created, + + + a remote display from &XDMCP; did not request any authorization or + + + the display is a foreign display specified in + . + + + +The default is true. + + + + + + + +Specify whether the greeter of local displays should start up in host chooser +(remote) or login (local) mode and whether it is allowed to switch to the +other mode. + + + +LocalOnly +only local login possible + + +DefaultLocal +start up in local mode, but allow switching to remote mode + + +DefaultRemote +... and the other way round + + +RemoteOnly +only choice of remote host possible + + +The default is LocalOnly. + + + + + + + +A list of hosts to be automatically added to the remote login menu. +The special name * means broadcast. +Has no effect if is LocalOnly. + +The default is *. + + + + + + + +Use this number as a random seed when forging saved session types, etc. of +unknown users. This is used to avoid telling an attacker about existing users +by reverse conclusion. This value should be random but constant across the +login domain. + + + + + + + + +Enable &kdm;'s built-in xconsole. +Note that this can be enabled for only one display at a time. +This option is available only if &kdm; was configured +with . + +The default is false. + + + + + + + +The data source for &kdm;'s built-in xconsole. +If empty, a console log redirection is requested from +/dev/console. +Has no effect if is disabled. + +Empty by default. + + + + + + + +Specify conversation plugins for the login dialog; the first in the list +is selected initially. +Each plugin can be specified as a base name (which expands to +$kde_modulesdir/kgreet_base) +or as a full pathname. + +Conversation plugins are modules for the greeter which obtain authentication +data from the user. Currently only the classic plugin is +shipped with &kde;; it presents the well-known username and password form. + +The default is classic. + + + + + + + +Same as , but for the shutdown dialog. + +The default is classic. + + + + + + + +A list of options of the form +Key=Value. +The conversation plugins can query these settings; it is up to them what +possible keys are. + +Empty by default. + + + + + + + +Show the Console Login action in the greeter (if / +is configured). + +The default is true. + + + + + + + +Show the Restart X Server/Close Connection action in the greeter. + +The default is true. + + + + + + + +A program to run while the greeter is visible. It is supposed to preload +as much as possible of the session that is going to be started (most +probably). + +Empty by default. + + + + + + + +Whether the greeter should be themed. +Note that the themed greeter is challenged accessibility-wise, and themes +may lack support for features like a user list or alternative +authentication methods. + +The default is false. + + + + + + + +The theme to use for the greeter. Can point to either a directory or an XML +file. + +Empty by default. + + + + + + + +Enable the Alt-Ctrl-D shortcut to toggle greeter theme debugging. + +The default is false. + + + + + + + + + + + +Specifying permanent &X-Server;s + +Each entry in the list indicates a +display which should constantly be +managed and which is not using &XDMCP;. This method is typically used only for +local &X-Server;s that are started by &kdm;, but &kdm; can manage externally +started (foreign) &X-Server;s as well, may they run on the +local machine or rather remotely. + +The formal syntax of a specification is + +display name [_display class] + +for all &X-Server;s. Foreign displays differ in having +a host name in the display name, may it be localhost. + +The display name must be something that can +be passed in the option to an X program. This string +is used to generate the display-specific section names, so be careful to match +the names. +The display name of &XDMCP; displays is derived from the display's address by +reverse host name resolution. For configuration purposes, the +localhost prefix from locally running &XDMCP; displays is +not stripped to make them distinguishable from local +&X-Server;s started by &kdm;. + +The display class portion is also used in the +display-specific sections. This is useful if you have a large collection of +similar displays (such as a corral of X terminals) and would like to set +options for groups of them. +When using &XDMCP;, the display is required to specify the display class, +so the manual for your particular X terminal should document the display +class string for your device. If it does not, you can run &kdm; in debug +mode and grep the log for class. + +The displays specified in will not be +started when &kdm; starts up, but when it is explicitly requested via +the command socket. +If reserve displays are specified, the &kde; menu will have a +Start New Session item near the bottom; use that to +activate a reserve display with a new login session. The monitor will switch +to the new display, and you will have a minute to login. If there are no more +reserve displays available, the menu item will be disabled. + +When &kdm; starts a session, it sets up authorization data for the +&X-Server;. For local servers, &kdm; passes + filename +on the &X-Server;'s command line to point it at its authorization data. +For &XDMCP; displays, &kdm; passes the authorization data to the &X-Server; +via the Accept &XDMCP; message. + + + + +&XDMCP; access control + +The file specified by the option provides +information which &kdm; uses to control access from displays requesting service +via &XDMCP;. +The file contains four types of entries: entries which control the response +to Direct and Broadcast queries, entries which +control the response to Indirect queries, macro definitions, +and entries which control on which network interfaces &kdm; listens for &XDMCP; +queries. +Blank lines are ignored, # is treated as a comment +delimiter causing the rest of that line to be ignored, and \ +causes an immediately following newline to be ignored, allowing host lists +to span multiple lines. + + +The format of the Direct entries is simple, either a +host name or a pattern, which is compared against the host name of the display +device. Alternatively, a macro may be used to make the entry match everything +the macro expands to. +Patterns are distinguished from host names by the inclusion of one or more +meta characters; * matches any sequence of 0 or more +characters, and ? matches any single character. +If the entry is a host name, all comparisons are done using network addresses, +so any name which converts to the correct network address may be used. Note +that only the first network address returned for a host name is used. +For patterns, only canonical host names are used in the comparison, so ensure +that you do not attempt to match aliases. +Host names from &XDMCP; queries always contain the local domain name +even if the reverse lookup returns a short name, so you can use +patterns for the local domain. +Preceding the entry with a ! character causes hosts which +match that entry to be excluded. Preceding it with an = has +no effect but is required when specifying a macro to distinguish the entry +from a macro definition. +To only respond to Direct queries for a host or pattern, +it can be followed by the optional NOBROADCAST keyword. +This can be used to prevent a &kdm; server from appearing on menus based on +Broadcast queries. + +An Indirect entry also contains a host name, pattern or +macro, but follows it with a list of host names or macros to which the queries +should be forwarded. Indirect entries can be excluding as well, +in which case a (valid) dummy host name must be supplied to make the entry +distinguishable from a Direct entry. +If compiled with IPv6 support, multicast address groups may also be included +in the list of addresses the queries are forwarded to. + +If the indirect host list contains the keyword CHOOSER, +Indirect queries are not forwarded, but instead a host chooser +dialog is displayed by &kdm;. The chooser will send a Direct +query to each of the remaining host names in the list and offer a menu of +all the hosts that respond. The host list may contain the keyword +BROADCAST, to make the chooser send a +Broadcast query as well; note that on some operating systems, +UDP packets cannot be broadcast, so this feature will not work. + + +When checking access for a particular display host, each entry is scanned +in turn and the first matching entry determines the response. +Direct and Broadcast entries are ignored when +scanning for an Indirect entry and vice-versa. + +A macro definition contains a macro name and a list of host names and +other macros that the macro expands to. To distinguish macros from hostnames, +macro names start with a % character. + +The last entry type is the LISTEN directive. +The formal syntax is + + LISTEN [interface [multicast list]] + +If one or more LISTEN lines are specified, &kdm; listens +for &XDMCP; requests only on the specified interfaces. +interface may be a hostname or IP address +representing a network interface on this machine, or the wildcard +* to represent all available network interfaces. +If multicast group addresses are listed on a LISTEN line, +&kdm; joins the multicast groups on the given interface. For IPv6 multicasts, +the IANA has assigned ff0X:0:0:0:0:0:0:12b as the +permanently assigned range of multicast addresses for &XDMCP;. The +X in the prefix may be replaced by any valid scope +identifier, such as 1 for Node-Local, 2 for Link-Local, 5 for Site-Local, and +so on (see IETF RFC 2373 or its replacement for further details and scope +definitions). &kdm; defaults to listening on the Link-Local scope address +ff02:0:0:0:0:0:0:12b to most closely match the IPv4 subnet broadcast behavior. +If no LISTEN lines are given, &kdm; listens on all +interfaces and joins the default &XDMCP; IPv6 multicast group (when +compiled with IPv6 support). +To disable listening for &XDMCP; requests altogether, a +LISTEN line with no addresses may be specified, but using +the [Xdmcp] option is preferred. + + + + + +Supplementary programs + + +The following programs are run by &kdm; at various stages of a session. +They typically are shell scripts. + + + +The Setup, Startup and Reset programs are run as +root, so they should be careful +about security. +Their first argument is auto if the session results +from an automatic login; otherwise, no arguments are passed to them. + + + +Setup program + + +The Xsetup program is run after the &X-Server; is +started or reset, but before the greeter is offered. +This is the place to change the root background (if + is disabled) or bring up other windows that +should appear on the screen along with the greeter. Resources for this +program can be put into the file named by . + + + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + + can make &kdm; grab the +keyboard and mouse, making any other windows unable to receive input. +If is set, Xsetup +will not be able to connect to the display at all. + + + + +Startup program + +The Xstartup program is run as +root when the user logs in. +This is the place to put commands which add entries to +utmp (the sessreg program +may be useful here), mount users' home directories from file servers, +or abort the session if some requirements are not met (but note that on +modern systems, many of these tasks are already taken care of by +PAM modules). + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + + + SHELL + the value of + + + XAUTHORITY + may be set to an authority file + + + DM_CONTROL + the value of + + + +&kdm; waits until this program exits before starting the user session. +If the exit value of this program is non-zero, &kdm; discontinues the session +and starts another authentication cycle. + + + + +Session program + +The Xsession program is the command which is run +as the user's session. It is run with the permissions of the authorized user. +One of the keywords failsafe, default +or custom, or a string to eval by a +Bourne-compatible shell is passed as the first argument. + +In addition to any specified by , +the following environment variables are passed: + + + DISPLAY + the associated display name + + + HOME + the initial working directory of the user + + + LOGNAME + the username + + + USER + the username + + + PATH + the value of + (or for + root user sessions) + + + + SHELL + the user's default shell + + + XAUTHORITY + may be set to a non-standard authority file + + + KRBTKFILE + may be set to a Kerberos4 credentials cache name + + + + KRB5CCNAME + may be set to a Kerberos5 credentials cache name + + + + DM_CONTROL + the value of + + + XDM_MANAGED + will contain a comma-separated list of parameters the + session might find interesting, like which conversation + plugin was used for the login + + + + DESKTOP_SESSION + the name of the session the user has chosen to run + + + + + + + +Reset program + +Symmetrical with Xstartup, the +Xreset program is run after the user session has +terminated. Run as root, it should +contain commands that undo the effects of commands in +Xstartup, removing entries from utmp +or unmounting directories from file servers. + +The environment variables that were passed to +Xstartup are also passed to Xreset. + + + + + + + diff --git a/doc/kdm/theme-ref.docbook b/doc/kdm/theme-ref.docbook new file mode 100644 index 00000000..931483c0 --- /dev/null +++ b/doc/kdm/theme-ref.docbook @@ -0,0 +1,1348 @@ + + Creating themes for the &kdm; greeter + + + This section describes the creation of themes for the themed + greeter. For examples including screenshots, see the installed + standard themes and the themes from + + the theme website. + + + + Theme Overview + + + &kdm; themes can be created by creating an XML file that follows the + specification in + $KDEDIR/share/apps/doc/kdm/greeter.dtd. + Theme files are stored in the directory + $KDEDIR/share/apps/kdm/themes/theme_name. + The theme directory should contain a file called + KdmGreeterTheme.desktop which has similar format + to other .desktop files and looks + like: + + +[KdmGreeterTheme] +Greeter=circles.xml +Name=Circles +Description=Theme with blue circles +Author=Bond, James Bond +Copyright=(c) 2002 Bond, James Bond +Screenshot=screenshot.png + + + + + The Name, Description, + Author and Copyright fields can + be translated just like in other + .desktop files. All the files + that are mentioned should be in the theme directory itself. The + Screenshot field points to a file which should be a + 200x150 screenshot of the theme in action (it is OK not to have one, + but it makes it nicer for the user). The Greeter + entry points to an XML file that contains the description of the theme. + + + + + + Once a theme has been fully tested, make a tarball that contains + the directory as it would be installed to the + $KDEDIR/share/apps/kdm/themes + directory. This is the standard format for distributing &kdm; themes. + + + + + Detailed Description of Theme XML format + + + Toplevel Node + + + &kdm; themes are XML files with the <greeter> tag at their root. + The toplevel node is an item node + of type rect with an implicit + fixed layout. + + + + + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE greeter SYSTEM "greeter.dtd"> +<greeter> +[...] +</greeter> + + + + Contained within the greeter tag can be the nodes described + in the next sections of this document. Some of these nodes are + containers (layout nodes, item nodes) which can contain other + nodes again. + + + + + Item Nodes + + + A &kdm; theme is created by specifying a hierarchy of item and layout + nodes. Item nodes can have the following value for the + type attribute: + + + + + + button + + + A button field. This field uses a Qt button. + + + It is also possible to make any other item act like a button + by setting its button attribute to + true. However, it is better to use + Qt buttons in &kdm; themes since these are accessible to + users with disabilities. + + + + + + entry + + An input widget like a line edit or combo box. + Note that this is merely a placeholder for Qt widgets. + + + + + label + + + A text label. Must contain either a + text node + or a + stock node + to specify the text. + + + + + + list + + A face browser widget. + + + + + pixmap + + A raster image in a format that Qt supports, ⪚ + PNG, JPEG, Tiff, etc. + + + + + rect + + A plain rectangle. + + + + + svg + + A vector image in SVG format. + + + + + + For example: + +<item type="label"> + + + An item that acts as a button: + + <item type="rect" id="disconnect_button" button="true">. + + + + + By default, the &kdm; login screen will disappear after authentication. + This can result in flicker between the login screen and the session. + The background attribute allows users to specify + what elements of the theme are the background image. When used, this + will cause &kdm; to remove all non-background items from the display + and render the remaining background items to the root + window. This can be used to create a smooth transition between the + login screen and the session: + + +<item type="rect" background="true"> + <normal file="background.svg"/> + <pos x="0" y="0" width="100%" height="-75"/> +</item> + + + To use a different background for login transition than the one + used for login, the theme should specify two item nodes (which + could contain pixmaps or svg images, for example). The item + which corresponds to the greeter background should not have the + background property while the item which corresponds + to the transition background should have the + background property. For instance : + + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE greeter SYSTEM "greeter.dtd"> +<greeter> + <item type="rect" background="true"> + <normal file="background_for_login.svg" element="background"/> + <pos x="0" y="0" width="100%" height="100%"/> + </item> + <item type="rect"> + <normal file="background_for_greeter.svg"/> + <pos x="0" y="0" width="100%" height="100%"/> + </item> + [...] +</greeter> + + + + + + In multi-screen setups, themes may also specify the look of other + screens than the one the greeter is on - but typically only background + items will appear there. To specify which screen(s) an item should + appear on, the screen attribute can be used with the + value being one of greeter, other + or all, meaning the screen the greeter is on, all + screens the greeter is not on and all screens, resp. + + + + + Each item can be given a name via the id + attribute. Certain ids are recognized by &kdm; to give those + items a special function: + + + + + + button items and items with the + button="true" attribute. + + + + Buttons typically trigger certain actions. + Addionally, &kdm; will hide buttons whose actions are + not available for some reason. + + + + + IdAction + + + chooser_button + Runs the XDMCP chooser. + + + + + + disconnect_button + Disconnect from remote session. + + + + + + + + session_button + Open the session type selection menu. + + + + system_button + Open a catch-all menu with various options and actions, + depending on the configuration. + + + + + + + label items + + + + &kdm; will show/hide these labels and set their text depending + on the state of the login dialog. + + + + + IdFunction + + + + + pam-error + This displays the Login failed. + message. + + + + + + + + Widget embedding items + + + + &kdm; will embed particular Qt widgets into these items. + + + + + IdFunction + + + user-entry + Entry field for username entry. + + + + pw-entry + Entry field for password entry. + + + + domain-entry + Some conversation plugins use this field + to query a domain name. If this field is present, the related + enclosing items should have + show nodes with the type + plugin-domain-entry. + + + + talker + This item should be of type rect. + It represents the hot area of the + greeter: it contains the label and + entry items which concern the + authentication process. If a given + conversation plugin cannot match the + existing items with its needs, it tries to embed a complex + widget with an own layout into this item, thus completely + overriding the theme's talker. + Strictily speaking, &kdm; themes do not need to provide + own talker designs at all, as all &kdm; + authentication plugins are able make use of the + talker item. + + + + + userlist + This item must be of type list. + If the user list feature is enabled, &kdm; will embed + the user list widget here. Otherwise, this item is + hidden. + + + + xconsole + This item should be of type rect. + If the built-in xconsole feature is + compiled in and enabled, &kdm; will embed + the console log widget here. Otherwise, this item is + hidden. + + + + + + + + Other items + + + + &kdm; will show/hide these items depending on the configuration + and the current state of the greeter. &kdm; does not impose + type requirements on them, but they usually lend themselves + to a particular type. + + + + + IdShown only when ... + + + timed-label + ... timed login is in progress. + + + + caps-lock-warning + ... Caps Lock is active. + + + + xauth-warning + ... the &X-Server; requires no X authorization to + connect. + + + + + + userlist-rect + ... the user list is enabled. By nesting the + userlist item into this one, it is possible + to create something like a frame around the list and have + it shown only when the user list itself if shown. + + + + xconsole-rect + ... the built-in xconsole is enabled. + Analogous to userlist-rect. + + + + + + + + + + + + Layout Container Nodes + + + Layout nodes appear inside item nodes and contain item nodes again. + The type of the layout node determines the arrangement of its + child nodes. An item node can contain one layout node of each type. + + + + Box Nodes + + + Box nodes automatically arrange their children in a row. + They are specified as follows: + +<box orientation="alignment" min-width="num" min-height="num" + xpadding="num" ypadding="num" spacing="num" + homogeneous="bool"> + + Where num means number of pixels and + bool means either true + or false. + The alignment value can be either + horizontal or vertical. + If you leave any attribute off, it will default to zero for numbers, + false for bools and vertical + for the orientation. + + + + The spacing is the distance between neighboring child items. + The padding is the box' outer margin. + If the box is homogeneous, the same amount of space is allocated + to each child item. + + + + + Fixed Nodes + + + Fixed is a container that has its children + laid out at precise coordinates. The size of this container + is the smallest rectangle that contains all the children. Fixed + has no extra attributes and so you just use: + +<fixed> + + Then you put other items with proper position nodes inside it. + + + + + + + Position Nodes + + + Each item can specify its position and size via the pos + node. For example: + +<pos x="0" y="4" width="100%" height="100%"/> + + + + + If the size is not specified, it will be the item's + natural size, called the size hint. + Note that not all items have a useful size hint. + + + + Both position and size can be given in percent and will be calculated + relative to the size of the enclosing container in this case. + For toplevel items it is the percentage of the whole screen. + By appending circumflexes (^) to the size + specification it is possible to modify it to be relative to the + size of the enclosing item's enclosing item and so on. + + + + If the item contains a box, width and + height can be specified to be + box to mean that they are supposed to be the width + and height of the box, that is the items in the box plus the padding. + + + + One of width and height can + be specified to be scale + to mean that it should be scaled according to the other dimension's + scale relative to its size hint. Use this to preserve the aspect + ratio of scaled images automatically. + + + + If the expand attribute is specified and + true, this item will be expanded in the + enclosing box as much as possible (that is it will be given + more space if available). + + + + If width or height is a + plain number, a negative value represents + an offset from the enclosing container's size. Note that it is + possible to specify a positive offset by writing two minus signs. + + + + In either case it is possible to constrain the final size with the + min-width, min-height, + max-width and max-height + attributes which can be specified in the same ways as + width and height. + + + + If x or y is a plain number, + a negative value represents an offset from the right resp. bottom edge, + unlike the default which is the left resp. top edge. + + + + It is also possible to specify which point within the item the + position refers to. This is called the anchor and can be + either c for center or one of + n, ne, e, + se, s, sw, + w and nw + which stand for the different edges/corners corresponding the + directions on a topographical map. + The default is nw, which is the upper left corner. + For example: + +<pos x="10%" y="50%" anchor="w" width="80%" height="95"/> + + + + + + + Show Nodes + + + + + You can specify the type attribute to indicate that + certain items should only be displayed if the type is set. + Prefixing the type with an exclamation mark (!) + reverses the condition. + Valid values include the following: + + + + TypeDisplay if ... + + + chooser + switching to remote login is permitted. + + + + + + halt and reboot + system shutdown is permitted. + + + + + + system + no condition (always set in &kdm;). + + + + + + plugin-entry-name + the conversation plugin provides a + corresponding input field. + + + + + + + For example: + +<show type="chooser"/> + + + + + Alternatively, you can specify a min-screen-width or + min-screen-height value to indicate that certain + items should be displayed only if the screen resolution is the + at least the specified size. + For example: + +<show min-screen-height="768"/> + + + + + + + Normal/Active/Prelight Nodes + + + The look of most item types can be parametrized via the following + tags: + + + + + normal + + Normal state. + + + + prelight + + When the mouse is hovering over the item. + + + + active + + When a mouse button is clicked on the item. + + + + + + + + The exact set of available attributes depends on the item type: + + + + rect + + + +<normal color="#000000" alpha="0.0"/> + + Either of the attributes may be omitted, in which case the + default is used (the example represents the defaults). + alpha is a floating point number between + zero (transparent) and one (opaque). + color is a hashmark followed by a six-digit + hex number; the format is + #rrggbb. + Alternatively, color may be specified as an + eight-digit hex number, in which case the first two digits are + the alpha value. + + + + + + label + + + +<normal color="#ffffff" alpha="1.0" font="Sans 14"/> + + alpha and color are + specified like in rect items. + + + font follows the format + family-list style-options size. + Each part is optional. + + + family-list is a comma-separated + list of font families like helvetica, + monospace, etc. + + + style-options is a space-delimited + list of keywords from the categories style, weight and stretch; + from each category at most one. + The style can be normal, + italic or oblique. + Weight can be ultra-light, + light, medium, + semi-bold, bold, + ultra-bold or heavy. + Allowable stretches comprise ultra-condensed, + extra-condensed, condensed, + semi-condensed, normal, + semi-expanded, expanded, + extra-expanded and ultra-expanded. + + + size is either a floating point + number representing the size in points (1/72 inch) or an + integer followed by px representing the + size in pixels. Point sizes are preferable, as they are + independent from the display resolution. + + + If either attribute is left out, the values from the + style node are used. + If this yields no window-text color specification, white + is used. The default font is the one configured in &kdmrc;. + + + + + + pixmap + svg + + + +<normal file="picture.png" tint="#dddddd" alpha="1.0"/> + + + + + file specifies the file containing the image. + Relative pathnames are relative to the theme's directory. + + + + wallpaper can be used instead of + file to have &kdm; look for images in the + usual locations for &kde; wallpapers. Plasma wallpaper packages + are supported. + + + + element specifies the element id of a SVG file. + If empty, the whole SVG image will be rendered. + + + + For pixmap nodes, it is possible to provide + multiple images, so the best-quality image for a given resolution + can be used. Size-tagged file names have the format + basename-widthxheight.extension. + If the not size-tagged file exists and it is no Plasma + wallpaper package, &kdm; will accept only a perfect match + for a given size and otherwise fall back to the original file. + Otherwise it will try to find an image whose dimensions come + closest to the required size if no perfect match is found. + + + + + + scalemode specifies how to adjust the size of + images which do not match the element's size. + free (the default) means to simply scale the + image to the right size, possibly distorting its aspect ratio. + The other two modes maintain the image's aspect ratio: + fit means to zoom the image to the maximal size + which fits into the element's geometry. The image will be centered. + The remaining area will not be painted by this element, so it should + be placed on top of a solid-filled rect. + crop means to zoom the image to the minimal size + which completely fills the element's geometry. The image will be + clipped symmetrically. + + + + tint and alpha form a + color specification like in rect items. + Each pixel of the image is multiplied with this color + component-wise. + + + + + + + + + + Widget Style Nodes + + + This tag makes it possible to change the appearance of labels and + Qt widgets embedded into the theme, e.g., line edits, buttons or + the user list. + The style settings are inherited by child items, but can be + overridden individually. The defaults are taken from &kdmrc;. + + + + The font attribute defines the font for all widgets. + For widgets with an input function it can be overridden with the + edit-font attribute. + Fonts are specified the same way as in + normal/active/prelight nodes. + + + + Usually, the theming engine tries hard to remove any frames from + Qt widgets, so they melt into the theme seamlessly. In cases + where this is not desired, the frame attribute can + be set to true. + + + + The guistyle attribute can be used to override the + Qt GUI style for embedded widgets. The default is given by + in &kdmrc; + + + + It is possible to specify almost the entire palette for the widgets + as documented at + Trolltech's site. + Attribute names are composed from a scope, a color role and a suffix. + + Possible scopes are - in order of increasing precedence - + all- for all color groups, + no scope for the active and inactive color groups and + active-, inactive- and + disabled- for the respective color group. + + Supported color roles are + window, window-text, + base, alternate-base, + text, bright-text, + highlight, highlighted-text, + button and button-text. + + The suffix can be -color or + -alpha with the respective meaning as in + normal/active/prelight nodes. + + + + As an alternative to specifying the palette inline, the + colorscheme attribute can be used to load + a complete &kde; color scheme. The default is given by + in &kdmrc;. + Individual color specifications will override + the colors from the scheme. + + + + Example: + +<style edit-font="Comic 16" text-color="#dddddd" frame="true"/> + + + + + + Face Browser Color Nodes + + + Color nodes permit overriding the background color of the items + in the face browser. labelcolor and + altlabelcolor are essentially equivalent to + all-base-color resp. + all-alternate-base-color in + style nodes. + If only labelcolor is specified, alternating + item backgrounds are disabled. + + + + +<color labelcolor="#80ffffff" altlabelcolor="#80f0f0f0"/> + + + + + + Text Nodes + + + Text tags are used by labels. They can be used to display + localized text as follows (if the xml:lang + attribute is omitted, the POSIX locale is assumed): + +<text xml:lang="fr">Option</text> + + + + + + + Text nodes can contain the following special character sequences + which will be translated as follows: + + + + + SequenceExpansion + + + %% + A literal % character + + + + %c + Wall clock time and date + + + + %d + Display name (DISPLAY environment variable) + + + + %h + Hostname (gethostname output) + + + + %m + Machine name (machine part of + uname output) + + + + %n + Node name (nodename part of + uname output) + + + + %o + Domain name (getdomainname output) + + + + %r + Release name (release part of + uname output) + + + + %s + System name (sysname part of + uname output) + + + + %t + Remaining number of seconds until timed login is performed, + plus the appropriate i18n plural form of second + + + + %u + Username for timed login + + + + + + _ + Causes the following character to be an accelerator + + + + + + %t and %u are intended to be + used only internally to display the timed-label + message, which is automatically updated every second. + + + + + Stock Nodes + + + Certain common localized labels can be specified via the stock + tags. The text tag is ignored if the + stock tag is used. You really should use the + stock labels rather than just putting all the translations into + the themes. This yields faster load times and likely better + translations. The following values are valid: + + + + + TypeExpansion + + + + caps-lock-warning + Caps Lock is enabled + + + chooser + XDMCP Choose_r + + + quit + _Quit + + + disconnect + Disconn_ect + + + halt + Power o_ff + + + language + Lan_guage + + + login + _Login + + + session + Session _Type + + + reboot + Re_boot + + + + system + _Menu + + + timed-label + User %u will login in %t + + + domain-label + _Domain: + + + username-label + _Username: + + + password-label + _Password: + + + welcome-label + Welcome to %h + + + + + + For example: + +<stock type="welcome-label"/> + + + + + + Buddy Nodes + + + Items which do not directly cause an action can be assigned a buddy. + The buddy is given input focus when the item is activated (clicked + or a label's accelerator pressed). + + + + The buddy is referenced by id with the idref + attribute. Obviously, it must be given an id. Example: + +<item type="label"> + <stock type="username-label"/> + <buddy idref="user-entry"/> + [...] +</item> +[...] +<item type="entry" id="user-entry"> + [...] +</item> + + + + + + + diff --git a/doc/kfontview/CMakeLists.txt b/doc/kfontview/CMakeLists.txt new file mode 100644 index 00000000..dd75aec8 --- /dev/null +++ b/doc/kfontview/CMakeLists.txt @@ -0,0 +1 @@ +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) diff --git a/doc/kfontview/index.docbook b/doc/kfontview/index.docbook new file mode 100644 index 00000000..77dae585 --- /dev/null +++ b/doc/kfontview/index.docbook @@ -0,0 +1,124 @@ + +KFontview"> + + + + +]> + +
    + + +Font Viewer + +&Burkhard.Lueck; &Burkhard.Lueck.mail; + + + + +2013-06-19 +1.1 (&kde; 4.11) + + +KDE +fontview +fonts + + + + +&kfontview; is an application to view and install different types of fonts: + +TrueType (.ttf) +OpenType (otf, .ttf) +Postscript type 1 (file extension on &Windows; & OS/2 .pfb/.pfm; on &UNIX;/&Linux; .pfa/.afm) +BDF (Bitmap Distribution Format, file extension .bdf) +PCF (Portable Compiled Format, file extension .pcf) + + +You can use it as standalone program to preview and install a font +downloaded from the Internet. In the preview you can check that the font +has all characters you need. + + +Additionally &kfontview; can be launched from +the &systemsettings; module +Font Installer to use the extended preview capabilities +of &kfontview;. +To use &kfontview; in &konqueror; select Services in +the sidebar and go to the folders Fonts/Personal + or Fonts/System. +Then open the context menu with a &RMB; click on a font and start &kfontview; +by selecting it from the context menu. + + + + +&kfontview; application + + + + + + &kfontview; application + + + + + + +&kfontview;'s Standard Preview displays your font in several +different sizes using a pangram (a sentence using every letter of the alphabet at least once). +So you can get a good idea of what it will look like. +From the drop down box in the toolbar you can choose additional preview types: + +All Characters displays all characters +provided by the font in one size. +Unicode Block: The Unicode standard arranges groups of characters +together in blocks +Unicode Script: In Unicode, a script is a collection of letters +and other written signs used to represent textual information in one or more +writing systems +Change Text: Using this button opens the Preview +String dialog where you can insert a user defined text. +This feature enables you to check that a font supports the characters you need. + + +You can use the zoom buttons or the mousewheel to change the font size in all preview types. +In Unicode Block and Unicode Script +preview mode additional tooltip info's are displayed hovering a character with the +mouse pointer: +The character's Unicode Category and the value in +UCS-4, UTF-16, UTF-8 and +as XML Decimal Entity. + + +To install a font you downloaded from the Internet, click the +Install button in the lower-right corner. + + +You can install the font for personal us only available to you or system-wide available +for all users, the latter will require administrator privileges. + +Fonts are often provided in an archive format like zip. +Open these archives with &ark; which provides a simple previewer for fonts. +To make use of the extended capabilities of &kfontview; extract the fonts and open them in +&kfontview;. + +Applications need to be restarted to use of the newly installed fonts. +
    + + diff --git a/doc/kfontview/kfontview.png b/doc/kfontview/kfontview.png new file mode 100644 index 0000000000000000000000000000000000000000..fa205993ba4fd503b8b43c35182a2086c17092c6 GIT binary patch literal 66103 zcmX_n18^ko7j1UqY;4=MvBAdJiM6q9+s4Gs#WS_3=EtT4D1^o4Aj>im|YaVuNADFq=q9H7~;Tx%eN#t zM7*z^SWdsxoy3i89G#3EEUok%9gV>(O>AwPT+EGKo!q_kzd}g=3sE+AGPVK}b}-ks zq9;}~Hg&ercOVub7XJz*R{e@Kc38*d`HCh6lM)kFcFR1^a?PCIe;n#gtK-ws;5}!Q zk?;UO6h=VS(*5atbf}L0@iA|CWgyYZ_*msfO>3ZrY(-7|J)ma3(Au_MDPfC{P-XB^h!^d5#9-MY&T*HK$&W-#2h5cx>jc4S!01mz7d} z?*nWSw?FTpe48KuYa0Fi$tp^*5yc=p&Eb%3!8dRcqZ9qH84sa+hu~Xo{%x3G;sBA!c3PN=OUjP|X08l}yT+9?BUA@K8=|9lMA)%9iK) z8kl-=``6Zf$ZOrXOSe6VQVAQGI?aXxtr*EO_L@{gn|uUv!hpB|^r7jjYZwt!v0wDo z2o|A~-Ri3h^}gw{^a79etF)_@jnNL7p_{8b+)dF#m3x_32DM8k`LIAH%YR9HQa~He zNtObr@{&gntAtU4{K~S<0>)yU zyqFC*G&CWK^m$F?Ke1mLIPDR1trwX)0gydbb#d`&lQW1q6^DV2pHpWKA^2_q#Cn`~ z6!~Hzz=Hh!Q1SqBhrly=jDRe3<40-W@!KH zW7R@lzN-l4SY~T563kZ9iSlY5$1T{ww%wMMuQXX_R6$L;-=nXJ6P^2OmMb+A)6zPu6wt0!8=so7 zNG64Ge}7-hs=A~^Z}{<|!Ez}kF%dm~btZAAJF>!Ksk=0{wu~kkAO*ON9F(Zf!F+{K zb~Cy_)1$Mj{%au8LnVzN7Hi!H${&DHz`uvXU1}1_q=OTF!6jn6>EdFE=tq6R6lsr}CXHRxyf|*4F09rTTX4YHYUzzcMB2 z;lV3kj27At=x)(w{7TO8Tr-pB)8*if9ll~2pN3hoVF}mHjOa#~Pc6C7%Xjj_zNJjG zypmDrha=guLIG1j_M0tG-2t!J?ISuI!vhh#o^^Rhe(sGN3-Ey2%QXGv%su*CMvx7kul;& z79*HmYdE~?#H-P)|D)=D>i&Ew*0QQA0v2t^F?URC=aE1VH6dK1-UJ8)qBfFk)A3+n zVA!i)^&|g6k}n2N84q8(DAUzur26_%y(C)QkCqIFKWAS zR{(GpvNRrNLkBfAwbB2+%y;E)rj?bvo>n^C9lwDto}48$Hq7I*gv%DBjg2XEs#6}b zcmWsJNpWCBa#>>|@nrcfVnFh-v9Xb{DRESa({sdi#^&AK5=UaN6C9kcp+$gt%C}+` z#Ukq#1OW@dBmYM`n!@Hj0s(TXAR>bsNIpm|OYs-(51nG$ErKd!#K2TiM{8Y!pm5Sb z3i$}`^eaUndWu(1_zEoxJNXp~Y*mFH?xW6YHJSW` z2$fNwk3Z@Z1(i=8lmCfD7Yhv|EWJ!>TvAV23^|#2-?O3z^U3+8UzV-zyZnfD-&fNpxjR>gCq zPIhBn6iua=0gOdTDo6Sfv)@!JH3z4=Kg6XP@kW88UEZ(xfS{hU2SortIJC*ScI~2N zH1(g`~C;eeNm+H>< z)q87%7WIc0S9It^xvzmscPu76!Wum7>N}QZtvS~;Y3`-z%e6JxbR?gft0V}Sb$c@J zNL{RR$6rn-wh`{@y%zY^Ay36f6G%uUUxd`-KZ(xwE|_hgI`PW2_v%W@)J*p59lHY@ zPFBKq5|u7nn^ch+xd>a0O4}%M2r4c*~>+ zXF3hCy(u0(*egTP67`O2+%8~bAqx=lKSVa`pRap9pYGh@thEO+ZR+Q9fA%sh@7>y_ zSSxw9!DscoZ=vs%Y7Z6kPnlAH(Y0RJAUY)yfYbe%;!fH0a~v%9(%n6)SFg)lQswsF z%ybktrBCwTJGc+o8&sNza8F_L`8gw)aYry{qsw$&{yCi6p?w?U4iw=EqlipfZ2q))8@ya2$~H(Ay0MkVUrv*Mc1OSGOO_!*;zc|y7JW&Pe|EZ6 zC{_+46h^B-(k+}5+|D0Xwf#;IJHjj$EnfxUKnpE{`1F_9;-_Hore;gh>FH@4e_K&e zNTpWu=~(H)?ZeZiXG%EQ^lmWL;c#O0xc!#PE5Y0I5wA`Ag(^NG^wWkb(U#90!_#DT zW#k$}$)-0NITK-Z%H->*`okF%CX>!YUvT7#)*sQQb*cAl#jCTg^PrrR;=fEoMJr#NykH6A=c_gDl!v z#=JFsUM?%?e_|X^`WFH9K_#*W8=7OJx#j8l%zwrQi?J)g@#D%-dXRXthJ|0Msx8kP z76(1;!nwlJiS^Uto=tmh({SVQp@VC35-avSvNZNXIEy^Ep|ro@NJFJ1LH8&}>gDoa zBIAMkOi_L}u#f9{k^n|IWS>stP`=pC#Oi^b`BBPDNKtLy(k-hW~hJJlg;yxZ68 z+?2}tZj(I{p*2hsrcK?ue=@(m*igIw&gwI2eCkZAMQO+74+PVdXu2iG8 zkEEINdyUz%^R3JWuqzggb>Nl~odS`gx3xSqKF}oU>Y32vP0irI^DxfTIne#-&6AXb z(Xzp4VQHDlbJxv(Gr<3cr%|!%nm&+t)|1y6c6Osq;SX((6wQp8!KNl8|;^ z2m)Rz_YHm5rw=3%y@tqmCcfPIH?hiPqh-aDIMwhK@>=6pn`9>4-l1qb^CW#zm5O}p zwWe8W5#$z`qlbtV?aQ!(HQVm~9Xs)gCy!t2HqAGga^F$Bh{@yTpA>e}5{5569po(d z0=(E?AsHDpy#vnA)XZ-d&ZrElSH%V1(yau}-%sUyl6t)6pYhi|#TfBzzMFH{`m{nT zguR1RrE&Os)q{Ihf>&#|SN=(LSdx=HPYK+XD_jGa-$PrdGV165=_+*iUet9#!lLS6 zzr_#N_IMCwI{ed+TIBp_GEJP70eDr5(r$@KCyElY4*9QEm zqZ{wIzwi_1*IHsz)Z4W2J#6^Nrxx?CPZ1=W_ChwL%eJ&p@HIV@e1ASQ%k!7qA|L6sjOvnpOhv$nHGFC#vesTFB#Jij$anVZ6PGroN@?Iowg z2PCF;J<;mVo>jarONDijTG8$T+-Q#=GqL) zXs@e7Egm0?mmrh^08qf85&Mi#shO&01_>T`x%GO$tft=KEw1!`+iqp`b-cwiu%(b~ z7q+x;M#$p_K6$ zBC)48FF3f{(JN1saxe?&5`@vP{K(9aN-}qAOP2OU?*Z%lxxc%H*)Mv0j6WSxYAez8 zemup}5;F;(i?1TS-I1jaP)`&YF=@oK8ypoma9Fge$tq*(g$PmM>uj7=tS*V) z8i={(f~dn&SslH-8PTmB+9+}WYYQS*BVcnki?_omSV|5(k zZtqyIL1a9ipqN{%;caiuI=_yN7~xl|9~3rmlEt6*??2i{jVAVe3c!KIQ5O%x{=T%UxlmJzuGjHNa-mUB0(f)J`LjB+61|u_YkHoo zHM|$#f^`?M0d8-*m{iduLGXaRVtywvgps591r?Q!=S8gsv)KUixuV@0H}#fd@AF5^ zFKWW)>S@1X$j#05yI5CbC>NMo0IC6SCs_vIRVmDZ-Ee*a;{5Cy+&?N*^|Q|tyHm)9@^Q}24EIn;jk zZJqvenz+s7q%V$6Z5vAc6EWw~2~wA5L6`b>d-`j&S8Abedg|?|Mbib{7m-Xm7!g+? zQ`FAIt-EK+o4G@z2>Bq1LWXlFOdZ8)!d6tCY(nJ{)%$J`B_5|JYImff)d|-%6*$WH zNk1yL2?Ooa&I?HSOTgR&THck8)>VFyaFR?Wl9#*(dw$*#=Tsz|xr(LC-^HFMfQVZz zd}?b|YpCmCStUkBE$+ z7H^NEW9u-PiJVFHRx?PSs>%HelTHQkuC5%1dT64g1BJ44`mq)?@V!NdUb5}jHB@p~ zOh1U?I3sAl*}UZ%n*cjr-5(TK{`I$O>2n_iJ9Wa77%o>PzN{XPH z;+&C*i2qg+bdSMw*n?Ju7v=Y>+>f@GsI3h#FltHD!xxKC{V#vfWl-Z+ zvwI5jD{DRp4!u2z#_4)SlW3dQg{a z0nuqf(6N|oiqX_Yc5gfX@fwBqnVt>vBzSv!p9Ej6=+@^XF@auIFV^o)EF-NF)>~=Q z{+XqH`#rP>PTO5cDfQEGNawixG0Bz@{EH^-;49-vV?<%&{=IOW*SBvOO?J_K3VH@u z7Ef-k(dz03os-BC#0OX&A!;x7^Ay_hntLnghYgO#5HKo=%Nk1l1QkB+^=4ni!xMxX%3?A;hT~8wO+Zn#7 z+yWJ;Fte?#ETU5D<1k50x6o{fk(Q3u>1f_zeXYsH_-QJOgy&^5kF?2Z6QAoT4228? zN+@i}Vsx=u6F2_FL*)AgyEha)H%u_?ceuZAH*`{L*t|wVPrrYp>l6M0AGKmtB$vVI zbUx$XXC17rq-58+5g{Wj4VS_BDOW6?Wj0q74XBkO1v1zGNkrmE(c;AHhe?&4nkkZR zV9|a>liD><%EJi)_DYvSE1WUvjPyz3rfQFfgr(&;zCQEwMXdJ$hEmXQSYDF)VRf)J zO3N=%WUU8jI8jqu!*_E~v-Q(vjGpf07VW1(T2|_bw7d_N0Uwx}EVsZt$^PCY1^V0> z>%!NhA0W3!9w#kNygg{AV$U4IR)Y^HIL6G;Yk1fKWvGvHLW>ernfLRM z|D&QZs37$5)BTsbERQqmoiop6zC=`RQ&ULi>*KCNJCEHq*x(>Ex5+y9pY^_d=&rb; zn2Y{Y##zYzuj*uguDVOw#Dvn{S6BC?sIbMf@xDA>$h-R@tNm&2sXX6Zj)LQoF1xj0#VK|C$GaKia)?))Cca zZVV825zi$^UIY^ga=kD5cCLv@^lA(BIsBJ2LfQ6vnTSlK-#_BwI&}DLxNNGA`Lf@J zbNesjd`;;6s25_3PV_wtgT4;!e~+dDTd*mgNRI5KJ6%u zTYJ;p^|~odPE!EJO=VTpI~4vny)dL z#QiE_H`<()_Sw>83yO;k>sLz3Dh!?@uFU7!I4U(8$tO+7CbUSy8wC=)6h;N;dkqAI%e=e7|ylg z5Gl2cz(ZwX#?_h_IK$hmW)tRwnCv~`5|ab}PqC-E%t}H%YfdpMUw*s4o3`3&l5<%b z2uG{c#LGU_{u*3g5+c4mXa~S|aN|}|R<_&Y53a1DR$p8K6WZ_p^`CPw#hzEtuQpmr zxVSWtSRj(Z`=gC+6a-6Gu%KxVN|o7a?@HA!76XQ)ZP1XRauL}jahpvhi$YF!|ChYr)1#NNIUvqWdW`KqkF zJqbNTmyIL{Y(fH({tSxqMIB}m^P0~p6X%pm$>H1@aS?w?cnUWt9A>skauJg20=z4G zR3GCR7v$672$;|^2g@q~$;GO>0}2jsiI#e+r+F5CzbGYf1M#w|;tv5Z?6xr}61_kF z?384Tr2NcNvRpHvAn5+}7hM`qtNWd&S}#wCivBZO9K3Z1ls*^< zg|@JiIzVQC&P53rIbM$Y&5}Q-u%c$FLTw|QkP0ri5~FmYl8FhH?F&ugDyq z3xU84_ksl(Q3?novmu66(h@=Q@)z?-f^J-4vde4M5r#MpFCJ&2&L&QH8{VcG(HgBr z*@yh;C(02WzNA)E9pB|3K9*P5tE*3};?>WSN13&A6j0=i#Ry_=Gv~QVpL?>0$BIpD z$C|Du=53vajEFfEX1i6{4|86}+i_1t-V%=}j_giTQGy4cA^ivPKbL_zwJbAlaTTX> zisd4H=+pI#fEI8Ss>$`*CK?b&wTD+=H$lKE?tK69PIGqCIG#jE^CQD_DBqeD^$ zWjfbdv{9?YkxGN)Yg2=~ibVF+;EGwok!A|U*OEZO``FVSsP|HRAxLNTmznZKR}5$# zMQs|}g__q!_0yR0aEW)~f4yiD7z@bUPQaRwY*zHb^IUs6$j}$DsP|{<*xxQi0aq1dW?VP2rsIa# zd#SiM*tH6Y39~hfQ7pEIb$~%h`p|LpC1xn`H_;hvZffSBX#eGSF#mi{I5lwp&z#@> z`B_x+Ld#NGo{5l>+zQ7<;>bJ^*07j7K4cpDm_QD((nE65GQKhgle9e#sE65 z@^U^@wd@)MKQE?${Oh_{GM!pPw9){53~Mp6K*gcqFCZu!kvyN3%(Q|*V`22KT1Ux{ z;+1-S7o{dA{9O^YD z79Sw9GkSY)41$BlsmvP}S_Wi{05ECcR9Q)>6c>VW;_KYoWd}=r8cBs~I+clJf7d=} zNJAh+wRKK&@=N@#J_SAHXtP$8@CJx0?$FUIUXNU1JJ06Vv5^T%3wP-cH;gS=jZl)j z#AC?~(+tmU&nWA*=M0cbrfK{$Ko3^<*O}v`V*y<}G?MOxF_571P_(LT{5n!8%|*5U z5oNPhBVAq@V2n<&>SiF0ClO>E^>KR{lFKsFfJ|eBY9F;wv7KJ}Bkg5VTile=Z~EsR zS++NJ^-n2f45|^O3}(RNQkTk*vU-kNw+#4(tAO=0R*lb;TD{R9wX9FzN6*1p&(eb!k>rILlM#oENMDD-817QzJU7 zF?%w|-z^dIeN@wxE2O&@PU(RZm;l~VYxv!kmeQl$)fSaOtBMa?EfflrC6l7fq3aB+ zbT6mX&{L5M=-@}w+`ew`g>#N(@)0g!35yQf3qDB$a+H7(KYuf3jyIaWC-)T^y&Q%^ z%(O<&OmvUc+vy3P;}PivjVdVF?^|r2LqE8U*RjQ;afVM))~6!JU6qOtI!eEQwCF5{ zA#H7aE-0z^o_BMsxDNw5JA|SV^}Wc@*_(0IYGVp00&{Ua&}pTAzlAb>_gTyH|9`tc7b zFt`=R_`R>>1{L{sbPRycgy=08nZ(cemx8A0{ULeFH?#F1$I>RDF~J|Jwh;nLwbS_- zqtC${Y`dvS+%(^PSobPShBs%yj` zYZdkW7xtBM^R^4b69cU-D5ZAHHmt;9v_W){K0pF)4M%!|y3(vcRJB?1y|tZ2^enutzW!28+NDxx5qV|R(7r7ijBrW z1zl^fh6FEBD_3g5%+G`9;YXYskI^$Ku}IWb0n1FPDDu$>lIpV(1@(1eleR;I7k$=fKJA-VeGo z`&)*JZ;P4yP}qIvkO>;h6jmGmTB9gieCbkI4vb&qE+&wEbQ@T56gcBf4mNL2Gzj9r z_!({W?S@_*wpKS8HoNF8pOEofo0Ft4WsV=qB0(n$4SOs2jM%>7$8AKSF?D5Ym=cPM ze-9C3Yq(5F$CyZcBi&Fi?;k_*F{$PYtQ!8z;Hwe}yfo*f3WxOW9efkbRGbMu*9*so zjCqmMFB*fbaH&Nf&8K%FWg-(ckPto|pVr^dpmEUuF8l7D zm8$^P2buRHW#p`GVxNOym&(d{`FNB}Hd+j8drS;gGAXeHEwJEFs5bs=4&0s`c$;RP ziO>6Hh{CLI0)UL7uO!sZBZ&xz3%_)X3ywl0R1p-Nz~&wRqf`-t#a@zWS{lRTc4~+*m#1Z~E}rcGN`)MU>r$*_91UV^4MzKCzHH!qlfQnhxH! zM%ggc%U|N4yzQt_aos3Bl=8QM9J}1EIAhjt zXx1)#w%UZ;4&$p&u5+-|Ulx|=Gkht$UA#t3B)$)cvN>I1d6MLy6HYN)c~4d;WV8bNA4xqau5kuDoH;6ivR5r&e<>e7X%uS z>ke;7F*>I(S|wwHAtCG?4z>vG&kL3%B6Tv6O^lys@04*?pq9&z*ayh#VI(t~GQ6Qg zPWXiL2Fpz6wUPjmAsQv@Z&MG8Acz7zRa5cROA=A3|u8% zM#rL&g+6b}?a;>tVWXN2&>=m4pUA0u;(8^Tlf7d2$WoI5_{+R_zp%c$ZDuC^z3K!C z{#XoTj=!cgYq4l|H)!_=nURC6EdL@D5a`L3nq_aU3jl7+iU7QmMuvrOGmezFsa6uak zLz=Q+N?&6cZ)l)}^)FTEllrA?ihK*F-)Gx1(}jOV$O9x6dA~t7k{H0Va}01|FgV)n zvvG24)&HDYR2r=UUjuEw?YYsobutIx+RDz7>6vq7-d$l&JxjKXH`l#AytaNO%eL{m zazc(q*h&{WhqU@n0V6aV_8_m7YpWSE@-?~Os|%g6G_`#0ylWl~B0N6^9hn5D5$>7+ z*$X-0pPgCdvDP^)t^RPYW<$!KI{)|>lU1E8(dKhFH_QOdF|-PKxa)pm5%|O*&GqJ3 z5T{-{8sZfq62NCAJheb6?$D+aW0K^uT?*E^bT@$PFY;in$Y)LnUpT5LtLgyTQVUM)d%|>&Al@S*dgd_KZ z_lZ`;^Jv#Bb9r0jHmPi|V$hyy0;5q9M{JKJT6@)c!Og$SiOjK6kckvVDF3F z@Knq%Mp+ZKy|E*LBJqjhV-+$SmvjD#NbJ4e{;o3G)gjKq83T|l>qb+_cKu!Kglr%X*p zxOZjuxWolF?cjgV<>3A555uDTzKcQfas@d+kHgU@fn|#?LfL>5&a(s0Vwl@X{2W`h z=HW18Pq^v6FXywa61}#Udw+G%!Rkray+G;L?ZSby^#UQ|vmqQj7ufDWMYrW0+s6q$ z(r6xLD_>mL2(*4BK+uJ7ICFYv<)cEX*56Tze6F7eufJEo6nOqp<)&xmKZf?6x`!hA z95M~I*L0tZ$pnu#m|`|M?)FJP=pP9Nh`d<^P?-_r=ukO*xtN!<6f*%;hwC-$ z{2j=7Yz>Z3cVZ4SVk+ARwkd*wG;Y=dVjq$*P~9^}TJv7GUI*FXu%1QY#W{7hMhXu? z3i-?i!ieeF?%~S>4xYm1L_x!m7O3cKO`pnZ#irrd>jU()pT+j)4cKK(ELPF9Dxl~5 z2^@@cyI>;yG-StAv1_ygR85wn-4_odtu&V7p3) z!N5w5|3mSZC>^IDOlY6Wa(CwNZ>-XmI&}o8_pHh~nj<0h_n{u4Z~tFhF8RK7P*>H& z^Y-2NF3|Jrhqjjt2UjO+WLLEMfh3GYm+4Rgq^!3qWB&do@)86}{Y*Hy1?WrfHS?tm zQs^bs&wO$Fn)Aj}p7#Aps22A%t^&CN-`GTM?8PHX_>}VnbRFaV%9&cYN=x(YqT%ll zIn|evFW->Au6j4BkvCY&`W=TQu<-_y7{OypqW@#{3O^akBE9l?Qp+_k#9xOEeRn2)-{PxNeOoBX2YipQV8^X-qAE)iR!0 z?#7!jM;W-GzgbD83G<(5a`)6Pv@a44BW~i?BW@Bt5!;b88LC)faJBQ2jZ^`nA`Ktx z`DZa9MMLzzl??|;)JgGGrqffofq(vu?@9Jx~VHKMJ8U!|98Jr9SBwaAYXW{Hih{sJ6H+oaDO~tcZDIm z*Bfy$cxeRXv!t3XxmhT0YO|2+;Znn*L&8|}a%o8Ia3Q8b#NFu9zkyF8g{O5T>(%Bv zp(r8q&+_Ce6#t`j+ux(P8CO3Go7>JCs^*e+V!W7M4ib$p$wieguG~e8aSTX`r+dz| z_fY8zl_7bKrjtjvFC3+ivNwoGIWChL30aolO(TVZCo$~t!~7B{{JtSb%Bn!4>aGai zh|tqCFp&gE92!pKNi6bsB#AbI0M7sL6e3F^Dn0URxEgU!&1BA1Ve_Tbvy%(N1XRh} zrSn;0Oq$7uBS(3s)B&Bl@6lM+L|)?I@YNZ01FAy_KPNasU1b%K zq}Ug+SVnsaiCmH*V1}2Kw+coj272d0MoW&hB8jBKSO$8!c%Z{0UXJIwwPcS|VJZS1 ziA&w!j{yd~`4e~)!=9f?fq+^TJz{^!kmY!E2(diK*i|Gpu!5dJ$d z>)%)B=`VZ5Oz1#3fthwM8ZQ&0%Pe?Xa4eMK#YQ3;32&!!Ole)~81>NoLOI|&XIq_l z-ctPXIF^+ECH1K5%w-zHYyp!=UKvIBk=3?M-jV+|@J~GmSiC(5cD>x%T&G@{qV1cT z;i0rQxTs_}$@3(vKemnuf%3-4?D@=$1MD{TsW>wsEun1oNUh|x=#%j6nQIhLUmlGqI~iH@Rsa3;A@hSeEu&2@ezwVMXsUQcl~5yCl{14HJ2gi2Yw zUAXmL$P`oinJgzJ;rMh7^6@ordf|7L%YOc%-&h0;>rJn89xpe3m~|_WzsBMFUib|P)13>*2jvg6|UjCrRbrmNj+h;NyLlDJlg3p5=pG!NwBOhmzlu}wFh6aw|^6@<--cB;Dt+?l6Hm}K)PbkNnFD35;w*4bz z3!IpU8anM0!UU27G<9M&P7d33o9>2-48|@HSrsds#>e&6YpR^AmLgOc>R2+O&rA(P zQfk}})X=mdHqN)sjn8jrzU~u6w#WlO1`(d_5s$X-OFbou@oTn4)L=W8SanwE6cyBt zso6BKv)Zrq%9z|3W5hoDKSK~TF~`D?vqaOu-yDjMs!H-<+PECb&rTgBrT)v#SJ3tv zLB+~WkyiB-zO%zOd6crqa`m>RI3^#BK}f2n0@IY32AhSlc+b0Oe{w0Swbq2JSBtdI zUdjrFRlAAW{F)z_nnhY5`vu*%w-;S}S2xW3*kjpd`R9-pb20TES3~MJa4Fj6aF=9H zZf|vH&f-_6>c# zBQ_t$Os=9ektvL>ErvJjiJS6jb|3&Q^^a1)7yem#e0#n#$=0e%l96{|F42Wc!x2BA z#5`Z`jFbz0b>B&Nzb9e|`_}II1ORw~`IV!hZB9mH+7h@7=cNSQl z{1_(X&ze=KWyz3Dl|=|B)R`ZF$@G(B7JoFKB;wFP4CcXqY~#iM>hn(d5jhwzXmAs) z5!ZwA3q=Ze?Z(fYDSz(lTu@v{FrZ3BNI_Bf*7WFFW@&-imy(n=x)TUJTO?=c9m7GF z=Ke@Z*)0$XNP{&W6T)mHq;}94m1I#;J@^Skyp0Y!wQV_1Z00^nc#ayk5Yhh60v2b) zeR|$tksutuCS5s9VOj4z%m^1*rcp1md+!)B+oVM2pjlAoEWx6a0rGh>;}Gsg9X zb{zz!_bth&%@uAC@-|t@m=wi(u|wU%;zi;#tMy$Z;fl$omcUlaLPX*f( zdTL=^aOqv~a&P+mN|VjBp?GP#|73QRmI-U)RsF%3WFv-17`pLjxncEW;B;$|*=+>b z!O;<|ui12(Q1!DZ1a>brcAa`<<>jP)!u#RJ2lw{CdKnUx4tHd^{E2WvCzDD&Fs*oF zNOL7Ru=RicE?_c1=B2Fs(_aq%873Wg7iv|2^x0(VNWlgzz z?0-p(IVtwrKUr*=@yfHI*B7eP(uQw9p3Tf4z4Z+10lbvgCoCn6GkxFaV13ax;&e!{ zgn@4<(De%wKCvn62|=Q9W=TsCi;x#9by7)U$9+Rq;1hgh- z<`>;d93uo-(8w)hKTNHO>lD#I=XMe5ij%}Nuy{-qx>JX%SQJyO7tVy2DZd^<6jD8> zAJ!9Y`JeEYLW+20W-o4PjL%fTDpcucXlTCL<-a=ZztZ_N23D-9u>64gGBsaWC5(k` z-;j5Ahb$~K=FXD;a5lWm~u7Lixe z@sE$Hv)*m;2PPY%sQsJj?#K5^r#?$-+q@U-w>yr!Fznx8Ro!lns}j$z`=0IxU4Qor zS61F%m*~B&R2C6CgLix+q@?}8V9gc2yDzkm!?MP1$H!(HM^y$y|FGFf=hM}nZ&#b6 zqnK*>W)!uvVmkx|OGx(R#$^9-zS)T zO{V*3N240ZV+jRreS0Cpi+l5;qpB+Yt5HlRR$K8OJ^%Z>+6*aCZ+c9#3DIT*f!i4^ z3IWDMhbLy1M^mwv45Z4!!prKS@-Xk_|4n;Dv>qqm487Db+%K2bVxLgH$}uvPOMhwsxbBTJAO3|4@YJ|VYcyC3kJ17LsDhQp^zdwD0jQe9#(ItLSMz7YUSD(f)v%%tI`;qIANN#_CnlZ)DTT;WJ9a+jXR6APC>3! z*3$anH)ue@!GRIlFKlgX-C4tuF?B2PZZ z%ATma>n#%V&%fnnZ=uFbPI$g5yx^@DIu=lqsjKu~Gf!A~CCn@+g28Q(0HAq^G zCJ3|s8rbm4^@75}+T-_NtCd?W%KEe^$gDJ8<8&LuUv3fVkB=rXEjz|V2&303)w~GC zV-tV7E;#&@M{Swji5&MIeJ7<&vM;;&fGb&ZRaui0hF{(EHko|M%&&`7&sEe(n`kkA zZQM~(I`_~hBZl*aKE_^<5<%vd)?SN8lr{o1SagJsj2V-i-35TV$>MXc#cUsX=2Xv= z0bdC*cudYIR+j}Az4M^IPGe1AE9me736`PRupC?0S9>8}yR02M zp4xMhk8WY+ibvnMdnim8AH0sQ09?6|yl>zol1l7?T`*y{I7bsF^{KMOo3R8?_i|u)^#!SA??yd#bzW?A2hlOTB`W2l5B(e8 zG=2%4X68ie7>xf&fuHQHeNio%z#Dl>Df-v7@69OmgeLEK$1`Qo8ZI&26Vy|{3(?uSvD!IX+pcJ zQ&PebznRB@>Bvw}v{S|cP*Vy$z6Sy=DCwvWgzdH+Mis2*;7V=SY&SpP7fgjFoJH$S z>DH5p*1B5mTVmR2WK2 zO<3#aYKztFKb3|wEwc%|5;*PV9tWl9GcU*MQPYZp$Rv%$Qshl~MH-a`E^o`asDDbW z&$o)vQzk{$Ix_htI`0SRqzTWJL9lv8lULu%JaYd9>#0qMwkA4iEX-PdSVUOoJ(3BT zIqjCWj(0=tKzT5#I;|Iln6Agi$eRY3a`GFSFcfpSXik zttYe!4NpND7|OM3?b1S^{xE@*O9brtD>eM%jjECfPkJpCg2Z}vG6vp9QC|N~aaru- z#8R`~RCasT?zdaEMRdAAXap(xR!63@F<#~_iMCrbZHrf-IbT;X2c;$x!OyHaL|-Cr zgwBOG`q$_4cr0q(N0d#WcC_}*w(L*dI`7&J+Tpz9_D|Xm30;l^Yp#vKj?CAVkvB|N z#|0dnw#~L%yU1UR!w_#OA1+j;vOoaPo^_#}4 zyT#ZEu*9US>BT;vZ{%Es|kux51fiV0KmV#)e{T$Sh&1LR{$xD(}IaRCK44 zMPw=Ywg10ffUqjsj~6G{;FZwXAyU$|{g$Wt^JJ=J&#^r(UZ&X9oI{5P@M_kVhab;N zai(ccJDil-s|a*9P2M2N_K=DH!`54eRh6}I!ypJKA}T1-7Tw*TC?G8$-QC?SNT+lj zknZm8?(Re9p}Tq4nVIMN-ap>C=9&?Kv-e*6-uL>|T3bU5pG_2rVZOt~t|;gMe`>f) zgWZv&Z$^_3>tYjKQN8SS*QP+C%cvbI2YPijq(-v|>}mgex3+{5IDSp<0b@Yi4ppZcNssYpkClphzy~!(+Fu<2>~b-w@~2 zo08^;FB4lrlSNR+D-j1(^F`}C$#|=AmScQtZueo+j!+19!y3^%74b&A{-WN=2-6l8 zjlQT>VN6oAAk2gfUo;Wz5%*OQ)V=EK&KxSDJ(guZX$w!oT#~05S`CG{Yq}PjKyl`8p~=) zZz}!xtpQ{KX$_x97TLrI;Q|hiN)60MYfUx3#3IpI|g%izJ!=Ue8I}5mG}N? z4;S9PNQ*oJs-ZM`rgzmuUrNRT{rn;)L#;_MGi?J9zIKiDH2O)$;EXgx9oXAw^)B3X z3$ui|PX4^6R@m4K?wpAUq$3iFp~ec|5-82H^tP494l{CFbtfah_-wRqG1#z8P^(z) z_nc#&#^r8KLhkmGuCa!$I5b2fnF*q~NfdhHZhm}Ip1_gFQeV?PaEXc<_WpjJUQp!z zIUP@#6FoZ&W76ayaFMTYxwqRBjZtg0 zol@;;!{loR<=hMwr^G(A2HNba{2IeOB^ANAvgnKEIAv6xt}P0GUZaQ>j$4Kx0ApJ% znDv%@>+xi<0Y9cqd@7n0Iej|ISCr-U>e#fty@T6LlaJAJZfm*)vkpDhs_U~-MqGCs zv$v+uwu{ufJr+FRj@t+-g2S*q~}ZCzn}2VZ;3*Gz=_&t|KP z+mh~XdeR@$#`ux@qoFByU`Ke7KXLe`p1XGz@H6Ts!(WL1WPz>N6}q4dF^m)qR})LI zhT+Mh%^-?*JPSU^erjyEm66@sdW>X$U$iSIZ?@``{!rZ0SjMdTpq*i-^Es~}e^#Z< zvJJ`TN2=ZlWq{Hd8Jp}QU+i|gL-W{TvRNnk)u^nv>G##YNWTOlhsR-Ce4f_E9Jt0wHY0t>ODrTz<}@t&O1^iX2-U|Jlss^CRJAYG#Y4 z(wAOcnWqQ=cxxdL*Zf)OzLKv@I?n~7?hX`&0#D>d9XHVXiIPN}&ZbnXTcjUKQtalv zLK)DMLIfsw4Ub|hV$AgAE3oQnA{pyY>BE9t-%6Jpwau4u2@#AzK8A3_l}T^~J*d?C zoykAbt$x@uJR7SgfH{~AT5+o1JiQ=>2sur}sMzk4HSY1g4iWg{g4r(e%5yD{Q{#$oG&pjoBs<{pl!$6`oII+VwLMX~M}AYt-`OXoO2*-_D3HUF?y7 zeKo=jOFZ9czWy}-%7MhffrL_I@0rQRrJO>r!kq5GuVgYZ>m~pP(Y*)OOvS8LheX6 z-{m%s!d>@Q>f5xpbzLnUwg)FmADc#uuN|yt?o+box}8NQWj3-k7JLJzquiMvv;Hwr z#htRIGjF&gQO->q-@ggACvpo|G+G~X$++((%uB5j@#+PefuQcO)p8o%m~7WW#`^6c zMvcdPcr$V^sC%xZwZr{~9^HEA#iFh@#65v_kX+?uU{KR+Wn>}2oH3m__XDoG{J2!z zCJxj|gSJU7@O$Pt0oxw^z1x{%lDjRsuQ*rqdFG*8?q#4{Ex}CmKwu;3-FU=Syjn9w zmd@dVuXj0NqG*5#esG6EPzDEe#l!@_2FQa=OOK3L5`9GeImw3)Vk!#idxS!=oEwb+1tG2XPd-vSyAlHJVcL9;!V_M5gxa z`S##;N6#h7o*U)s%0)?DXeqPdBOUrV2NkU5bUvTyIhh>Eg2bcx)+&Cc$*O(xZSG z4um~%bNqa)nYm}lc2a!8u`$s2CrgAoR{2b`)tiZ<2W47TW$ebf#Zk3-+oy;6cw_h> za>S-`Z~R3mA(@)}%RKX%X#b)N%jqMbh!{D4S%iK7jx+bkFXu$A?mcRD*{^8zLQQve>2=UX z>l|Hbmh3m?i?#mMPi9=^+>%VO&V04W=z|BX!Bdb9e)H!@5`^OVbF}WZ0>>veRG3=B z`Y9M)>h=_Ti!LG2U!rT&%vV0xcCEeUUEToS9W$hm+bOM=fBK} z?>3br%C1bTd>{kej!aixGO=v=-c83?^O7v?9{ov3hRH^Hqt)kVss86(5;{v%=8S(u zYw4E#&8P6_HJ09`rq&1Hn^k*I$YhSzSR?9^bd=gz(P@R3;j;hbGj@CU-Dr4I5-&qh zR4#4A@?PZ62Q-^w&hFxrphN@K*Qz8*Jrz@oo}r+bEPQZ%08RU zeu11%>cL!;ux$98)$}$jL-}5>x7@JYbRqt@^p(#cg7}g@o-vc{Bi9ve#Cd%8qD;*N3|s6C{=%`+@{ymP z8V*g_7`;HE#g`^UtW!6em_C7E8RV9r39VEMNnD~B$Xw{jUwj}S+X4ZZrGi+AIqtip zxdShd$d~N$Zq-7c0mkI*vf0C0A67=U3T1kZ+9@;`<8Fin6^*Dhy1qKM--rm#- z#lQUZ6QjK*I}s&W5_qeB8ATror_vXm4SIuS+W&4xSb^=W{{?WX3XO4c3J0!fW^Q zeJ<);W8V}*b zq|WYy{G1^;fi)vtpMnV5^c8Wgia?$AS!ub%5UI;)WkAJC`TM30!G!9*=AmESCkYk@ z9BT~XU(-Yc803meze^sOY*isY9)6oc&m@yFlK$sUG(Qp3$9Jz~u-;)1nD&2m3~cWF zk+9m-+=oNQzWySkD0E#O+TIVBU=vIr}VyF!tep8<)NSCNMO3TPN;^GML z^FOkyWK~d9G<2Uf$H8u&+~b-qF~yfm;%;g3A-*tM?40Z*l`pVdIVj<$uv$HFyfWYh>q{nYtOw#S z8w~#uVz}rr*3Dt6N^#(`ih3;$A;bL`h3nY=j)aBBqDQ;17vwS+>ryEKJVm4&UMBw% zs4PtA?A*>EC}2jpI7<=1{5D#5l#!Vk&Q`=iOFIav+{54BpS8Ltv7gyEy^#E=nVGt(84o+?;IXI#M|)$7)O1n*=t~RLh9YdWUOdbS5S-alWNS z*aLq}{NJ&`4==H_twBwJT?EV>{T<)l$Z`GD^z!$AS}{>K(0XmYy0Mdbas`Y%Y$~~D zqN1Wf!NKbI(~;y-o+q0_tFpQ2c8)C%pZWUvAEO^jL6ja&HT~E$a-|Q;S;$yOqE4!c zMo$EJlVa;<62&R5~! zLXNgtT%WGl{i*AI9VH@gW+YouUb-?gXFvUlNMgb1Y&bn5JUY^=<_eWvv%g7D?>78i zr2vN%@2UB2!TaQlmyXBv&dHwzq`LLvzJKXs#)cLYx|ex*A&>8zx)mrQCG`I#b=HU= zlO%fe>J@a%oPocdNBd(jvy_yCsc;K7X{1wFbJ@4M^bg>a?>SlDkg~501j?u}^@|5F zZlE|e<>wb1UE~esFzGv99=;a}CCac`?``Mx&-k^cEI~E=SF z!bmnK=x403#tC#S_pYyhJeKon&=NKe2_i9n$jXq$JqpW1&+IHTSMBm`9xQxeXJ;3i zkN|tk;xj!rcS7!K6Uu+PAQsg8{ju5AfaRdR#13i_1UxCc%$H6cl1l4o9?8Q&Y2lrVy<4-AEEox(gO^ zo!8XX{wUV)n8IO@#v{Hqi; zxSY56xY{}S_x1qu9JBa zAF%J5NqvbQiv@`n_goO&%simpsO0?6)H3k|XZyzPe0pxC$vNY}1Eyo5^Nq+F{W!L% zi~9%EH%eaq_l0{IwMVcQ^Z&l(oqCc4vl;sT zevw4mh)sfxBlObPI>_;hs&k+WD-ehGbft}**__<1;YO6 z6#w>%fB)-FcYttpypa(Qis`-k)G(&OQX@h}sNDHNyV~+Zl2SHDq{Z{GH9qE(f3K(= z-#<8b{Q@>6EG2FEgKNzwL8W3kJ>8(%g(QB*4Y9hWCXCG-YR~!O-yiqt?g_-9D=sNn zR#?+~`kLI!e;d~J#`K8*8%B9ZVuHv$D#{&i?slQDOXMjBNTk0y3rb_fEV} zXd;*Mc|+7qmMeJ|#Xp19?(S=Ldkh`rse1Y>J>3@-D6d5{Tqc(miK;5lsY1l;*Drph zDFvq~i9fNo=XAeixHwpJFS_}6MEP&I8e*C^CJU4kd2ItcAETEVZw?alWu&Jgyuc>7 zjnR=y;4&ww+Mm~4^g!ZvI`sqlFf?4a*3-pJ{qL^rLq#>p%=VNXJ$i)p^ts;NYy~H* zH;STdp2ON;`Y)ob@f38@ z(+73|;BeUb1Fc-|jaqGP`K@xZig|r@Fr?4p9RBCeVdW-LIw}K~{ciKz9R4q`9V+ks z_>-YxTD7D^un3x18ERR!BsNLE{&QQo0G(-_MXH*YwYf(+#qdjB`b z>SilgcW)9BKO_*OCag+H%>$t(6p#6DY#kR75s{bae6~!c^2L5^d^}zvOS$k^=Gss) zF=+cgEa)FU#a=pI@2lbKqrN`h{tfP8M!;(ZCN_N&LHY7B{h?#9|0$!^+IP?vEG;bl zf;~^cS$WHlNv5V}j8rJIA-K4>WXn|TEAR2KZJy-*Z*;mzV@iYzM|qkkOBHWUhQ@Pc z16{6;5r^vq&?oP2nRxha#FRH=R}I~6mr>=Y)g^XUyJFwsV_{)^RZ&q1Sy$J+_k3J# zv=9%@V6?>5`9ml{io`(TZ4K#TU(cMH$wwg zx39GW|9!|W&7C@Q5@zb%o({=>7Zdx$&7C+t{u7iA(q}6xMsSN(M>9kn93301Zq(iH zqQKs$WwtQ6fEaSbU+QN&6%_d&^XUFIA2&;TaUT1g1u{c&d+Z<(5VaZ@1sxt>r3@&PV&qot{a1FuJ_OqZB)U| zP6AFVuZEk8GW!R&=Y$;m6GjsXF*N?a-qWc!ehT$|Oj}rp@a@|-3!c7T5BWYAgd)k% z25VOnz<1W54bHm@bvOsTQ6&S($=hR@py{JEpBYcF+n-ZIqo{t1bX@dBBU&7<2|wRm zERu};Q}vG!f4vuilH`mbL=)xfll+p2@BeX@aNQ+Ri!50=aOMnqtppP$dl zPZg@pRBN^w%izi9{`40N#+RXb_lvbasYL(6jGKoCBN|*Y;2pd*ysQAV@a~OzJ6dmQ z>FBge=E&Eir>4^B;f^u>w`WhdS))(C+g)uQV`jf=VHU{8SL6k{z z^wS#}mG8epc~|o2n$qo_;|@UAT>fj+2mEYqQWbHfLQjq_(v6l+-+clLEgHnbUtw`r zpFbny-S(`hxmvVMR|1<0kLM~zxZYf7>*<}x926-}6<%Inj}|yzG`Xn%*Gyc6g@yC) zEjeEI$~Vuq@|!p4LQfg)r7px2?6;;aBKEI}^h`|pmp=;Km;T)t&ynGFJVyTYQ7FXX zu-U`DH;DA#lX9>(4=+~ab8O}#?6^gu6%snxCQJT1Vo+RBq1)LXhfSk&n#@c6Z=d)^ ztE>clw{YSvpB2iNIo3t|Fy{MT2N{m2>lSqPl=$z<%jWMIAOEY|CE@@7kGOBOBb-Bw zZZ2#I{=Evn2Y@z+>dz_jd+9t!KXO0%^ociCdJ_!iVbNEJA%uw#{#q!_bn-ap;&p1b4i{HY& zqwxN7_D7ke$gDNN-q1wnkyL7>>cfVq8^@uf@~6*S(o8|m6+O`#u&}kuREnakne8n5 z_GDuKawDi)ntTG=AzxW(4etoFw&i}%1r1bVYpDf*+<#8M&z)!CoWN9`c`tMgrE7Yv z_!g<$W?Om?!qe9+m1bdQ=VpF(jf(su{rk&3ec-lVC_Ov`yzYyMh>bjzB=-5IJ6^JN z6R2xj5aBNj)evc)ETS1NZAXwfI5>^w*&kde9oUP;?6}-(uJ>LjHT~O89|G?y8CZvs z`8NBc(hduMK9Seg?{#uySPP`{3k)2ixLE7Ks)gbIcB%N|JhxNu*q(8Vya0>9NOmnal3?}GF_s6oWMXAN1 z>1}A>Qg>twq_|JU7p?>I{`S$ev~!_D=^D5j&c6aME0 z=ksC`Zk3yb?sCI1Qi2JiN-tj~vt0!+c&Q@>Hs@2c?6L6uy-(s<*mEaP)cNiYf44Z( z{PVa$7r0Palikm8o$U@b@+5O%*;^jgx~q?#oiGEjBtcqP)2rhMf#?IGvIsxZa#<$|$^555{e46$q?$SbhX1 z`r#QNgYVz3+iYQzx8-^mwmXv<`k_Q%YZHuL$#O-RhGlvVPEJ;r-7mo&Gd+J1k*15? zc+v!eSLQkbYpic7TYl**w|WCLgF$~^rPlsn5R*!--fmu8LeTx}H5b?!uq%p+LOq2) zWSvwZ_Lq7v-ZuhXvAXlUCm2ssWc#9#A3wHaXAF;LF=i}wcTeJWOf3@!$b{p?%NEe+ z6z|3)IlDM?4mH3PiB|0|C{{SJob60#cjKtTixiPscQJb`8P0){a4743gnfGNe( zy(;QNK6SFUdy7THpz5`NUYM`c5D%LwEYZ5MYOs!FaODJ>XX$Q%2LaUOAhEj`gT1}n z{V5heGOH`z=q{6GWC&ne^7h5WWJ=jQ_y`aX5U4rRAR!^uxb5MMjEv0c0&u)GKT}q2 zG!ZasyYs?v&ChP3MBVL+6n2P^fMJZlw{IGHdV(14?(r<<5^aLPXc$kHk5;?dJ3Eip zyTd>LEnIIP0SlX;zbs1D2W0?kG=9^+1K{XLj=ni70}>cr^pqm+S*0WBB{8zKzF^^x5>!P23bp zJc-?I!*VBb8%j;U=0sazN5hL*=IR?m2|~YpFbpSZSrG27FZ2g?CRFMjUb?%xBN$B; z7VPP5f*yT+2J;UJ(mDL|UZu${IC&~xbEn+UWwfU3oRf@{^!O|Y*XI6I=6J0K=`;AO zt8&qpQ{z2Y-onFXgOlavAYrBHLhroeiNQ=M2|`~q9b0Tr%hXWl%a1~jEVwBHz;>P2 zr+cC~(isRp@+Jtl9sU5UMu3jf+1vY68w(4dvamduV%s7y7Z(?JwqIA0^s(b3h{*Q3o9dxY{{qx~94U=5>F=iQks2n4_d2q;rTi=dUU z+wT*=*i1eb$ZhT<{?j|Yy{REMc#xoBot&IBd5)Roc6UABVC@SUU9{T;Vbk3?emwO; zG6E>d5Rr^gHz0{J00nWmYSC>KY`+LZfSuda0_mLTw{JR!HQU%NZ`l#f7(K~;0pRf? z&(3sj6RRsUZ3HNw)eInyIx7!YL5>`|+l!2Xa(uilN}I@6q$&pt0th4M`l|pL!!=1PGKut<9;@fk(b3}t@{$Jxy-`$I zclJHf8QsZze1x+V+Pkp~-w3$BlbD+ZKo7mVINwe9X$2B%KPGv0YO7TMj!=AUGRv^b@H_tBjaEhg=so8&d zZ4A*MA!m| zEu08M`ZirgfL_u{NX*KI?k^zvIUas4f&wW@)5s_n;|1f)?CefdMQQ2iRlal%lwD>% zBM>J?wvKfGiLvsev+TW8Dc>=7alV6B_Z5jI%K_mIdU5h7+nEe?MPeZw^)T z0q&J0(@D9C$K!k*sn0P_2kN_FwI_kCNCJ}3+6LFl`3jT->MBhsWNMjDHV2&7IT|E1 z^5j%*?(AvR8~efDg)JTEI0h5BuMxm-j2~WXZiRj1cD;_=+A?r)bv-Ini34JMp-N5b z-Oa_BXDO+8JiJvlx?E+47m(!2!X^!v@xXqW9Tki2o3}OAV`_U%9AejkGyAc+lO*)I1Gf37&Lwhd1I6gK9|X}e=_I?dqLE#QS|9KIwx2BdgfNuMGj`9V-idSyI76BB6m3I{ zuZMQ8xpAOi+K92EWBeXFG-jX2>98%7Z$&8`?V}II%^X>3Kd82V)GgI6a5E4!B1mF; z)HXB)H59Ucyx+U?8jqyI7ArehO3^MWMsKN3vyM}vm^*VeEjGi5YRd}7^1bm|MTLEWM`V;xxlv{ z`3em4^Yb=4iS%yVjwc%(V08?5!Ng8}Sy@?{UV)Oyb9BI^1^@xTHa9oly9R=2t<8QA z2%|9R4>;|y{7VPTCGeYcxTRtC0)6pRoW_Pon9J~9O+ypx@f$^|+(7ClWU=eQ7l{XiAOfF~8FmQgLa>RNa z{tP7r?-t3itZKT8I#drHgBAi><{_nwV4Vq&DLHjPJ}f|cxfR>mKFg@W=q)~e8Oz)q zd#vu~hWDWEWio9HlXzSMfc7}y>KaFH`2oS6vF>T^PtJ?p(b40FsW2jD9pa|P+Y8%v z2hahKj5Qod^_HmW0_AhK)Pm%uR3kk{lJ8Vuq|)dT2YT?f%~vEpFz0|K6ok*0RI=Jx zqIYKWoRBkJhLoHfTq+v;vZs`o9ERVSLF;=)b^A`0uK%gjc6@s5gtg%hCp&K9MPVEY z&Hy{x>`exDm6Y^DxMD6Z9e^@z(`z|r#KJCbfF^PGsidBwbm#HJS;+yL*VuU8@l zA#w3XGkIdTm1Z-oabsCCZ{PTU%ZJZ%ouT+bU+t)%tqsWKrFl0z3I&bBF>kVmLNhVA23JuMpJcp+}!~G>LQ4MMP&2+?T>HB zZ9dO46i+q?cy0WW@< z2Fz){-w$SIO--}Ga1v3VHokxNvB3^>26o341*6a3TOzFakR3Oul^w+dWz8|7NXJA@2RPS-0p6yH}_S|7HTt8 z^^4?I*Vm)+oJs!0>it~e!-_f5B>ene=9P{>$IB%|5|K!atAN*+Izi^K%#Ms; z4tL?vMgamR94}Vx&03!A$eI#jfgyx2sCSQ3$dLccexX`xr+ex5l0)qmE|Wf^+dMm| zWW1MPT8gg5JAhbg99IPkX_w~k_$)slg02I;ztOn*HiGTwtUr#OgX3tye(~rXsm}*9 zGqD7Q-x3hc?MT>28JW9ElSI~YLJJ!ko%2MF*&rK))y~ka&Q71JlZ}@+I6^R1)648H zNJ+ZeM6nR1f{m<+yf{Eak}r1s!@^!dq0oHgCbhYSy;Vux_s88YJA;VCw?{LcJi#Dg zVTt|iaB+6e(p>a^hN%8K`IuHoF3|ae0K7Yl{NZmi2Ad@srShc&6YJxDNqi#33{+iULa&!7Be;o-cjvT+RGr&3Ri2!K!yiQAk1S*M zQBcd>v$eFfXR7S!Fz}e0N&7xuM$;%Q?e6y9nnd_D!YO!X5TWP=5f8L0<-UMhH1e-` zliO(@V~MVr3$%<3lZaPGJ6ibbLmqHdvVRm3sD}_0;9&n_C-~XNL`Jsvu8UI0R}$!< zX#J_b8pG0p1TknYEa&;urmm0coh)h_8TDp|eVi#b!~!?CW4zr9Xl)iNmw?aWoypm% z)mwOgcEgN^QK;zFgY$qfl*Frhb-Ydx90VHjw**)5f3Edb)+!=TaqcyZ=<)-k+6PFU zB~}xZ{9nIr&opoe3JLW^q+75KZOUD5`JXWJ`dn*01A9<-a-n^k!Do3ND zq5}UkFsD1T>)XOvA%q;!rrao>EfQD( z8%73n^C+AA6&4m?@|$3j&2r#-J)vhocyez*cPAS;?th@RI;rd zJ^rO?YBmRx;s>=rNeDr~Et}G}Ki!f7%o}2&0;G^Gse(za3$cPnNQTh-xWTi1Korz! zfYUA0I~DuK9J!*FB&43W)A9r69IIYvz_rC z2AIm_#z6V=XX##bb?00x#v5Xg8?=W9!k%l&jSUpsCs@x0=BzIdHD@2A%8a%l0W}0J zbIgwCa8l%=o*q2(9z>)m4WxRbS9A@hOMU#k8Ft6@YP^;O8b!GtD|ic_4;VZXg{Gwa zg<7eF&xef~_b%Z2ug~`KstUDzpEDZ`|C*~ZmjU9<607Oyc~o??V1ishwpsnNls-%ifH7y=-Cuc0DuA`DKwAfw| zm=DC!pXiPHnXfRSQ3Lw+Xo|MbJD!STuqFN#D5yg9y3P>QI-A}QFv}do(0qLN?pI2i z4*=0EfG}&Wcs=<>$kkc8-e=3G13)TV#D8~(2m`)_$rH>hu(7R6l?_EO9@}Kj;>-+3 zR}WSnfcYmgP-s%)-8C+Cf~|Ca$D&(bb%{0wKqQ1*wyDJtSitltvus0&XEW^$KWI$T ze2$sx?h7P<5ms`)N5J*bTov5i+gmhnjuPqESFQUlEZp*GPA6rq%5*Hj8s!}WL)h|H z-{TX&Zf3iJw#TlVI-m7M(McZgx&l#k9kgp|#rjwb*i@NW8%n?%np~RXvqt@W^P&BP zXICreLBT-=Q;iLF3(bf~@MkJlwrFta{nuj9^MJO|AI}j1=G9`iJ10N|E7k+w(DW8l z_mGW_j#eLa5xZ3BJTd+4c?lw>3F7l7Rs@xgn}4V_RldG}bpgI~baXVL+yqACcw<0x zl~ml}{+0vmL{7rWDhKw50f5frcyrUD@^sSB&=3HY#Di?~Ps!!eNs68=6$-P@>Dr%fI9StatY3 zu0s$eUw}Lt{N3PO=tw=w;32Du)Y-R;Rpy-B_=7oR(}SJt)m>FyZyZ+FshU*S%ieH- zlPJ)}NXS;Zf@N-9T%*9JN(bOjWdgZrJ1S@UpvdLAhs>!@zEC9xEE}N0p;H;AovXG? zThTBt>Q82qEV>1r1I6?6^WNGDL)Qgg&YjuPn+E0xZlnm#K zHA6NdCbE)UQpZm(+)Zl$uOtVL`)HQExj@>;R=%i&gq%`^Ne)merNbj4UJFP?+L_K# z5>FJF7Z(C%-O&P7^9L}OHi6eP9)1Gy_Ls66JUr0{BCGqv}{Et0b6=!x!Bm0!!IjCZJ|~KaKcn_j>U_$ zHJy$sC)*5(0;O49zI=rg_-Mh^LMr#$OUsT11E~yKjlXs?d5s^PFLtHiM?V}$sOXzT zc}!so8y~6T1BeEGOx;Cj0}AZ;_36gw4_t|d9~9=ch;MkkwF1{ zO+~5xj3AplAocbdRs=u6Qm|IjG!ER&44_t@JKJ3y>+aP8F4%CO-SwO>63D>4K#0Ny zqdJx)Nd@?A@2+B*&3S|7ofCXy6{|Ho>=eQEjDnsAA3_m+e$SSZK4#FR8k+3ka{uiG z2`MS%qAQcSe?SoZ+ccd{I(S)`X6{No6C1t?kbe$x3{U2&!@%4LmRgIhtgg<~8_E=} z(r2}LBhoXnPSPsVyYps<#$<+i&@w>y?jix$TBrP)kdZ+GV9zEH?wled8qLALWdVT) zPW~GvpUKF`2!;{{+JhuWXXkxJmu5F0v`>r{@T{4bSbe;gmzECY&ai=N`}8$svFjWw zWWA)Mgn-K~2q=Fr(^cXZpFe*Fs48TABu%I&-+g~~CX!k)oUZ9wL_b{o7XU*?>suo# z^%lz&5!vza@zMoGviFy(n0uwb*jm}#6avlYwD;!nlHOwY9UzDtuGgnjFqCq`{<6WT z)6*Fy(BRJYUB~nWwxDUgEj5u)GGL71u^F~TA6hg-mt|{rRa>|#sn{=PZpx=jOiZ~t>FU0x0DC&5oxM$-D#oie<&c#ob4Va4vuAcygI;t>57PKqHk1yI?s?v?@w%O_ZD4Ke+hJRC>ah+0cJ|a8P_oyNqr2^DgnF2 zQbiZ=G~A`h(_o_qO?RE(ecKLH_&=NqnYC8p-{II@CkxC<#6;uBN_zR?Od} z(T+f;uJG;4o`~w|Y6Cv?Cc6QR8AzR-R3ramqW1PbfByWctE(Hl26VIm@c@JZ%U2nJ ztdzLQP>(s3#Fu4iK|kg8KnR9Q8Y9TVQ3igOM%(>4wK)JMKJNXS@;&UsGeXuNe=O2r zQgXlAvz_gz8tcvHU|!?IQq$Ad)%6B!Wr*)#oK{psY@Cz|!Qp-v7oXK+3A`cl838le zXXSfYTO2#9*7Z9Y>~wMtvKJ0l$0Wd$ z`TOt-k$WiC7Fr~T0hIB!+$btsK21*vKsu>L-J22i8sUxs&`}LX>N)V+TFK=b>(6l( z%Y)SG7g4{)wFlJHF*%(Y{9Z@b#ZTV_lgpv}YX6sAL)Vw13QG%F5Ntt*UNMke9YNA*khs% ztnJ^Mt6W}PZ3A-wQ1?H5VvYoE##*)N&=BuOK*g8ad|p~!7DJuHtr-8hW0Wxg>GUco ziPu$$j{RrOPoNhwZUxfWMB`t(=`Yg4?gL}UTfBk}4#5Km9GDb9fT)!lRp=(lL^8C1 zb8xyh6{_8I+X|Lwu{#{T`{;wYIcMIe+144%u4hx%Uy!I&XhoSOodaH|f&tJjI2~+l zZEYYFb)D!Bf%MPh%;3}%T)Y9M`|8?mKhRup`P{hwKwarU1RA7LRyH;|0S?YtJ}9a> zxVhN3Bu#@sL6~;yb~}p$+62VJ7nPPD$s`gr_O8!nm!N-uWbo;Fl*A2CkS+~jIEj03 zeY!nl?vuQ16VqTFH~`ea@87>`02=IsxdNLiSOpHDt(&QA-h`84i;`}74ur+{%_5z8 zNLd*ZV0fHOiTW2^#O_O5Td{fSEfEnBAotb5FjpOZ%gS0a_(Kn*uzE{D!Xh><&hqZs z7P4*&n^^UYqC)&WVz3oY@*6w73i>veEjd`cFa%~hZo~p(GfM{#Sx_>)#}_12Msp}P ziVkv&c^-)I+}7)1Xm*HGtWZ^h?(kKrIV!(ME&zFToO$ov8?+2Odp>q+zynbb|_8O2YqXeFr zPcc12{<{HrC^4TN7|f!Aw%*==mHqwsMpyjrm>=Lj(%9gP5e<$V%4Pc@+ZLumsJ#~U z(SSL=$tLJG@QCga5y4BVzUqIj0sZId=r7 zQc_ZsUqH(JB@ZPdCME`0qvhOm4y|w0^%$_DYECZe;pS;#V7+Do`vPYWP#tJu_Jq;C z-m~hV{f&VHglS!_DWHP`RS2um5DO%fbS?^2Idjs>j!#ZjPq)Xu2?|PAD6v3@-`^rV zVh1#~E0j13$kK21h4&G+a|SR8IopGZnlfDhCpI7PoGH_5m~hmqb-7|}^TkL5(vwqx z=|9;LMcq*KXQx8Ft|H}J_WOr@bWLDRK~q;(hfI+{xPUdAto_O(AH<3Jqp0M`lXP7~ zfKv^`!wt|xMyMY4*cL7JE*2|Jmg_}aT)0zGQnDv@2qIqA(}9(?O90lK9!!M-VBBzq zdVb(;egpc#8`xyQSjZxX1ubs`;}`AiFt5UjO3KUAfgywv%1{NSS-9V7?0z5j_2oFewBf8{@&#CXf>mnUBYmjN3{yNsJ22B$~TC}eZ7&z=R1I704`P+tKt z1K2iWw8~9pgtC+5H|PCm~F;mRr&nbZwZLqo%0B5xdUuxCK13?3x}lO3oc zy!=JrtbzcD6);wT;lGoQj)n$L`6Y7N2H+tga>7#6(%=SY2qBlzLt&;EMCAVVYI`mV zvj=zK>0&!jX||yS_#h<>U<0ZypyHv*Z9(H*wfq0F z0GvQJ7sucp$HT`T1F$NZR<#$j;)(?g;Ci-zgipnK5}*5^&lzkC75!p2M-`fDYka;7 z9RNxK{2famZ2)q~ULXci3>XYZZ00i^eP{;J`wH8v^mK~@C{LyNoFHgUz&xIURh|RG z0HWQKtI^_F-m4qZ8!g>Yn&-6buWnR3=L@$%6cYC!jyQ^4Wjcq_*a= z<%@{GSpSvj3Sl;!jRc2#0aAw=8cS4F))p2T0QteI#8SJ95vZMewYwLBbwvRB@^Z5o zj(T~czxh$`UAX@NK>k(a}Ec zl}jCb?|#MJT)?&Qvd#VxT1gR+RLLSWc6N4p-afB*;2*<9Ygz~w7Tzl@i{0rwFCQ<9 zyIB@ayWMVpQ!%1*6!W6h`2WR3RqNyZAnDp%bFwLwIO?ps9a`e}yIT)f*q1+ZJe3Mq zs~cq#SmE{w+_jiKT>gCh_mTk@>0FlbH89sQz>*g+2rnUU(ja>{)Josr8Obs|jQ0^_ z5#iyUb#+`=q~fU{q~nBX1APDCNmCsiFF>L|Cefu%$6sv$p~`%5GJ0sRuMZZCg#Qaj zESaUDnBbks7&q{o?r+q!fdsfeHeBWIu2gPtB!P6n^xE29e}rxE1s|eY{9ry-s}6IU*`8Ev=8d+0K&p{4t#@eZEfAkYOdFLy1hHokN~h4ApIfoaf~iaT91Je##{{%zrS@E|BI+x zWum!}ugEc}4xG*1-96zEgYxZ3Cg5#L&-Mj^N~plaL z5^q51K)m?t$Oi#~nbgN*l1crR>Htbz%H?%t_j5=va=YIX2vsN@OzJ$I zBwv0Mis5E@dHsoJFx&#Po zftKlG0v#QmN6X0q(iPCKIVt{tDcTE&-I?METcGnNk%$;fRXl&DBP!Uto)3pn6~>e8 z;HXx*z4UhdZ-K{B4$ruYM)gJ+;t=#N)Y$`(j|hnUj#tMS5)y? z(Pi?Y&)tCR>;r<;0C0@avMX?Hd>s2j*Qg;K-Eyo54?ln!MPX|Aa&2$fz0?wEVV?!o z8h}Rau&0w^P6g0CAi%?%^nXT4L|0bUy!8EFF`G{Y!OKuZWu9w7y~M@w!*e3!cOO1@ zmKODVxTplQKGZ%#1e-?M%L57JN4)|AsgBsY_#Blu#@QwgV&Km=xhs^c&~cFd!{8c5 z$+lc%gN`4DWJnd+9Poi&{tTbd>x;U}m#AFXE5iv&PTQ^K!G$_o6apj_cK0Nrg<4z} zut?SF6F!@XMtgTyIM2Cq&4c?p z6jVK5AFo3|6Sn#tA6am4;{AG=CKxs~t5i47(bpan78V8DyJI_}H8Gd!H_iOf|(eyx)Y<$Zd3vyjA0lNXGsJ-BW0m9FZhU?_% z&JX6g{-k^b(ZEN*@J|zmO`6P?_h^j%uCfJB!}-DD5M5WuOG3f{u;U0l18e7KZvaSX zhXw`)wyYrmfTq3bg8^swPhV46fvFVKI0##{ZZT*-+lQM5DtBk{N>zq!Ex%FE_C4MM z`7Z10%{ekMvH=z{P*LLnX8{>(dtey01JD+Wht~@t`wGPt?*meYfudz;X{&nyZ74UN ziyqFA0cu`6P_>w7SHCEvjSQzLvw@%hd@g^>tA)I=v60Ab$$+aA=X!na zRL=lH@!4!t)zE333j!c7D*k||>n|IIdtd1~YNtuc%9efmMpwR_9KGRt$THv4Z{M-2 zu{XVz{+4M~`d}@u?ceSDj$gbro!yn@^nGuoAM>i%s>d8>FBy%%d&RQF8K8M>5`wxH zP~_tnAMK+6sz#0qb@Q@zi9(=YClwGs5vQa+9s*{-R zH1ztkBxLy470CM`ZhP_a?OS#*x8o}~gJS&R;@Hn|Do=j#p%qRhx3*T247?ccMa?E+ z^d~Jw%Kz}hgrtT>aHrinN-pE~1O;f+`gFS29|sn%dHTI!#qZxMBv6w#u_S2bWi>=Q zJ{TW_yXAXrv)b_b^5Bao`br>lu>>v-g@I07GF}kIB*ed3>RR+hugv>nNhbi#CLZg2dNbiVWJl2&hS8vQI`KK+DU?)tJ;zpcU4W%QJ ziBCnvW6t@|?C;;d1dKmkunL6-K@qgg7YMCNPg35Il#x;Sq@0|1Q72!WK{qQgZ6z*Z zu5xL4g>l=;VzbM_;;a(1-Nv5_)rjX+Qc|)%ncsTAOYvv53m7yK{03jwmQy+gz~xG2Cu{rfm>p#L$BN_`${0Z0 zDQRUj!<5aWo%Ue{I`g(#kl88(6#?C3n}I<=zTa?T?C`xof(KDAT$7QN`iF~%;9gh$ zb+`79KD2tEj9$&PASzV&f$Gg8_DUuk2Crsh_3vTUaw(c$lTZVlV`#>Oz<@eCF5V41 zDeMvo5dww4o!#5gZ5~603{fhM#v54E*UG55X~M(X=68`&zXu?{w7g89JriAdyFPR&0n?HsXZ4AT zi_;nD?C!n=VXg>&tD?y5D4kL9X7fKw^VwaW;m`Z^i~L4JA6EkCTQ(GwBw#F;@H$a) z-wWy$5QcyT_El@}1=kfW+t1JeoW8QM*gw@%N`MAW+JW>00yt^gxvMc*n;-4iC$%!D zKGs(krqMb8)Bgb;XsW_MO57axZe?!dI^-26cw7X)LPMc+7!rc%Waa1HRNTawAIxq3 zGqE+DL9Niq=g-Lg_$_O~Y0j%w-~yeqQDa+H93i zsxe@42*M>&)I&Z;@f<8b)s0>fhUrog67`+BByYW3FPL&#Si1k$Z2H-TORg7})qM!( zwNYB_eI-mXXQ<2yM2L{j-YnZD_5AQTP_{1!PI}DaZ+Ca`m+9V2j8(LoY`YE>@g**< z@3?(v9`+u)xVsouWa5|rzH^@bvbs@Tyi)8fGqY-=2v_r|FRbF?Z$tgAL4-hv4N&}C zGWmN=QBjfPi`6na3A9Xvhyb-9&G(la*cthg>GIy`x)MMeWJb+5JNf9J0bYSD?HWP@ zgi~&o4mZY`5PHlk3hiX}^7K2opqZidwOXt>`DB&pW*QxeaNrQGjAz^$baXiHwa7ab zpoO^sd<%5Lpq0ncC1XVrf?ol82eT|U1c^GV`eFxdw zcN{jncyIvg3GN}?sOEKOs5E441bRPvoR^aA^g z&$N}dkCk=mzf8TRuw`GEeuVH-=ZP=d$fP)ztNBx;@(cdFYi$)wx8|4)n~)U!YFHEQ z{puB2Q$T=LftCAo(b`tGNiPa;1~<&73^E=1CE=5hh%9j*{ySbx*xwunyefqd)3^`p z)kBAeb-5}`=$+nY6(^n_9v;3XE?&jzmTl4bW0Hf)O*8A>mXjx4Xt-YBY=TBpx+PNd zXE2B7o+B4#+Wi>D{-k@p@MnySjxG&K)o(3u%oZRU#tFalGw3Vo?3{(6%QM)iSeXyoJ-r8s_khMHj@@Sd&$tsYV{Q`{*4Nzv6*VV~)2Jl$u%+1d~f9bt` zt685&Bs1=>R$^^MUbe*+Wg4OGP1kAH*#&0zm*n*=rZcA#)RO+< z1W4SoUwQSOdy(*4cA5`6Nhv=xh*|+5RZY?OUbt-+r^mWK-E**iupjG)c~L*dyVTRu zb5T3(Dc;anh<*~(CYxu5p)U&8(b-SI=LdM>*vhirty{%EB3xA^IL@E&aA^*sS}|WbeC&9&l<)491hV+?HuJ`rt}XGajp1{)i5Lrvb6z2%LN z(fjNBPyR7P-!1&vxq$4)bHr)ygh0fZQzeI$0G|A6;J+D}FwE zV{KNh&5%Miw&T8n&fG_kFXW6`>iT@B&jxX*j_ux4f8z6&PBPI1&Fth3P30mN=Kxks zF$afS)g$H5uvX}j(GuvP!`#^OIL}?eq$k`wJw40B(r{ut8f}_hn%3{o%;?UWEYzK0QUornhvLqc*^SP%q=YG#th?j0d zVh+yRtrNbQi|oEQ;>*0KJgv*N2^I%g_CE7^_PUk_ny-o@7uey_$2q2+Z+r;lVI0<) zbOg6I$`OUg+t+0y_+kz#e116nmw4*$yKmWtJZMhF_WGRJ!TQim%PnllAmVA=% zB6SCI-D}N~>DM4h+`ap~c6%1K^ZU~cF=Vl<#Jg4Edeu(!hjKe>#N00}`rhV=L_J%M zuH%&rZ==24U0jw{mN2s8lD*G0RY**BcGk{5^M0-u89|H2(-5Lqyk_+=rfT*rvcV!( z5u}6t+G%rracFqhMC)m)LbO=o{@vXZVf^Iu@+59$GQl6m8sF=QHl=8m;|D-f=9@j) zT0muV{CKA4gsECe8r+*(Rg?V&QU$68YLZR9Cw)bXfn zY;AKu>7s2|zO{jU@Dv0a@UAPdN5{otYgOJTPK6GFoK+`OCWME>;TQceR*h>Bh0eSV zV<)gT$AFvEAm_2Rp1s%j^2Lk4DMcGmQq9TIK+8Q2P|D{>9!*S4REHvGaq>^JSamR? zAO{Il>M?i4SgTMWAYOd0@B!){AM2wf!edNQjC$uCzmZR< z&yy$H1RWOqggqC@Hu@_A)mkyJf(XB1P>9+N-l%V*z>zq=W29@Nqw9bFj&X9|Tf92; z3r|2@UH#*Jj*P5Sy2j?o!Sewfje(8{goc4opeU#M?9kcb7 zDpo>8NFgM2*E<+w0x}<%YTGN6W2Gsuqo&-xec5j81UA;F;OMjdOsXHOzP}){3S_>1 zRZdoa1HbAF?gRIZT?sPWwV|&=gV0ib1o^QQ4PYBkVrcHK3bcIiK#f1*r$hY6 z(8sg_JO>zXr-tg!VgX=zc%`*1%=GjO(O)5qO?hpMXTj8sk>BU2Xz$CCXo`u+R&KRkLw zG}UWa+ns&jlmY3@pB0%2YDli}r)td2&AoUt*UvXblI?>2Wz7NkWVirk7iR}&M%C~1 zc``{oKf^4O>=|{l&{5BmRL@NRY_qAn{6SC)jNZYaOS`srcYZoLk)&bS-F=l5X0pzF z`*%gRw(KIM>C5)IvK??m+yi9LT(*4?Qx!11RDTv*>3f6O0j)3hAEDmbNk)0i_QC~j z^Oh@E06F)E592BKMH-Njk}ff8{iyJAJ6?$-ktLJvE6bi+uO8ff_29;?JB{25I<-4F znd{z_GBH7Cc5i%4`Iw;}-E(*q6mh0%`9DBMop@mXH`nibv8~51EVuJmoZxWa1W&2l zN@F>8!o$OZ=x&BN3=wRSIFt7I^LvT6=K&(=BNKu6$3pi`@TXtnX~(1Na@`apHK>%& z(&B|XZcl}8^P5sn2JKu9Lv>L!hNT<1OrOhiZc%9 zxpG!>if+VxW-4yHtiDv$)`qpQ*a=!m9U*hN1ETsVt>CA$b&$R|B7ayvMByNAW5cPG zesOB|$BPT^hP%H$$#-52$Qp0kGU-@@XS1ys66ZH`&(BCcI+6A^hg(ru*)KmyK2n6! ztd0C3ZN=HV9}n6Xb@DGmqSOoY6d5GGc>VoJNYq$#4QFFzlz$E-<)F{99{gF6C9ZsA z*REZ+bqbg*s%MnDCq3VE7Cn%o5n=rA?9erDJ5T8m)qmcJWIqLa z-@4?yq2ZS=xoHsV67Ypc%*X=98Av6oja8iRArdQx9-?`%Utg?*`L(R^l1B+$Ivr8Dl8O&3w$5NsF1atEw27BY=erKT#RLGM(De_=E3aT%g zv0u-@rc@Ltpg0njlY52tiUTlc0L#tCi)6xeQ3h3H194+m3~Ql>GP?1t4Ei6=@rWfSFB10T|VS4@|Cr>{4Kiw>R>LohWrNu zi&szI^eip8QFVg-LXn)*S&Pnm0In}f_4KSRk0eeC7Ub`4`|<|okn8=2?X(o-vD+E6 z!v9YTU~rSQZ~E;8YSMkZgBKNg{7&v8D=%+WGs}Z?Zh_+K5zZY?f7s0ZIP`*?;c-X^ z6>-*r$<45NKDy8(e`p=f+ce z%ZZZ_1?qQcT3Q^)b_)x43$6ly9~vG_5Ln{5_v@KY7+-yHwfEtHfs3`fZ4sscIm zS8TWwb>*C&6ynKnKU5dX^0X zdXYqpbdQtm+38@ppig`UOF3-G{iqp1%0wLI{mD@|hXWsmCWeqhe!WnZwC)`GA!`>| zkscivC!VXgnI;lRQpZT*PShT|Hyv%-mOUiQw8tzjZfpeBH?!(~9QO+jF8Mv$JX{}F z)OP!MNp|$35GwJK(*9i&iIabDNw<{g_Wh2o9%3n_uZoj~M4s z_ULEMpK!2PcNcFNSY58Clj`1Q0Hq7Dv2nq0>s;jR zGnDHk{^aU!weMedXOD=Gbi4k&V0b+rJzB{hD*4{E zYa(}Pgg@*0pL+6%n@cZY^ z@!oFJC9VE&!3QkRJI_tD9`W?rp#>R=+?zAkZz$0dlF{QVTBkVmYpRm#>a^w)HyXjf zRAHZBDI831Jn|wk4my* zq+8P%XI;|@cip$NjI=~u`SaPu`J{K;wv2GIKQ&8vYFc%Tq}VSS0P%w5g^TD zZgVDuW-#*#XW4*C#b7mjVRRc728Rm^1_`huSmE@VL z`bzgNg|KgR7jRiyV)9r0w==Mc`fe^CjEOX!Ci!MU{UV?e@nl2wgW_!DGQ`)3&4YDf zU7pjm(ujjR>6rjIbJ2)Ar@fE4-PQVQp5Fi78{*Z;xYu^(CORR`W8Z&%TT&uD{@*um zzxsN8U0@~p)o&{w?}3S6xeE3F{n+iNFKiZ_8uavh^?b+a|NF;F%~eCG3Y1?0{!nA& z)Bk?It47xBx(d$=n*aY-8}ppo$qwq(|Nn10cEh;+Sp7kPQ>%14{_p!XB--p!e~8x8 zF`PY?5qsQNIw>TZhg(%uT~kA`+T*iCN44@UaK)!{O=urXBo z$TcIMcepirm%$k10FH~|annhmRe^pe=(~iR-Q@VY5NWtFH?hw9G9U?6>zqWh%D?OF zah0_jKQg@8&iby}52%A77*G;{hf^f1a&jy>xpc0_T;_)2=)#z|?*1zN`n89)YEnu9 zpJGTGb4U4B9-CKBV+xu#|YQuZr zqWjILGK34ok|P1S-!t;}al*@e(c<2|*;VIW(-CoD+jw{c+A_Z8nW{nNl(aDFFu>Yv zR2$wu_~z`EAf5*-w%S@BNB@?H2n%PjGY1JrKvx5jKWd@1_kx`9pHD|?V2hsp@rIs! zZwV4Go!hg1eNuP=Medevv@$F;HD50Ca{#GsXlx|dcZl2Vb(6PjBdSsoqCGGTWI;J6 z$zs z)fMjUoy?TRnF{Rd#ZGhcUx_*=@l(N&mY~lJ<~9*&JTG(K(k|A|eMd^~-xHkoPvP7S zd}T2@T;aa&xN^hK{8!qcVJ71fH4$Vqed@xH(y8xBjap)QzOU7pQ<=5zjU3mfit|JXYY>H}mK*co5gxIaeW^ocs# zwM)pntFXEU1_`aa0AQG={<_z$ZO19Oo8RhbsrV}^)Ppqig3`%4nJ=J5PD6?=h}VxN zH_@l4CaPZr8X(}f;DsV^+x^uAvl1U_J>Vx}d-wGGY)yYk%P)5A4jtJ4Q>jLD-SxoA9FVEGS zaLI&IUd-#nqplKn@{8*72`dVAlM~uG7d5#p$})8Xv&_3>-CrCf47Vh5;X>ch*ECtQ zTmkk^2%XxSk}mV{TG9!Gy1zVT`S;tN%#8GeXb9Gh96r3Y7znk5r1Xc|F_OHUM=EVo z?p6MZCu)vRqvg zH*xP3MJsmu*?uM72`FDVEjpHl-?EK<{#Wva{f3 zp%X81{2-pYzc`_ds;i>@thjoP1D9(@p$zVQzu1im-*fh>12S2IzS=^j2PZ3g-GBqZ}xoTrFQ6fon1Ko)Fv zggA?xQ%X)!)<8GShM~9o)gbDqr(+$@)$;6$S9#@wC-$Hb^v|uWDDO0V2UElo)MKV_ ztv{Hg0YQA>`JO#9gG%RRO7gGm!H;E_+=K^?uqb3DX%ft=MleK8A5eM#EF+RCC^_#1 z>8~TX*o&KnW@vO&>EnGppt=iRXOI2&Y$D!YckFvR(Bky$(Z=S5l;~)b^dI8l8l#Qm zmLDzIYEkDpI53tElb|x+)cxUQWAjir|H9kY)AuUFh3rK@?rfn~%%B%4ER+tq^ysYk ztGi>VZ1Qcf2?vO-Gc8H{+!EK2x6SD4iWcz;uv?fm6)U1e%YA_DJwfZ81nJM()8vd?=1(_k=fR}4dcY@OINpmgjxgO@bqefRdhMXA4YzM{}l{q^Xp3@8;UE zi*@Q*1nKAJw;chcyDXD5)%2Hfj!4|S%edG5agt`1JlZ96-9#(_EXPrHi5;;?OK*l_SUa%-fB zeSt3H5JeO1T`{eLBWoZ z=D@11kCys~gm6y^JBj)dl9R_`6tkvQOnFW&6vE+R-joV4l1B}fRvMyia$xP<0MY%c zVM*TE`3A_S;eqk$Q63B9rbLRQ_Kefm`QR1%%tW{S`J%OU8tHgdybt>EuXzt9`%Y`W zUKcz>ap;X%E8NsCunC|R37ToQpj@mU(5d?MyFKLelbwf-QdBHL3I=D(D;nYRmoB}A ztvFvmppPce{pE3`0wkgbg(!jBLVn8!wrYYJgFSsDFGt}=oqVBK>+e?pDpBx!&#^ND z@-3En`@6Ekq5tmx)6Kxl^{B=g9_hQI_r&{ePY$Yl6BAbBr)OsNhvTI#VNu3a~w zZVS@HUPZ^pM@dFT1_;%-f1(C00ljWyi4lG3zxuhPND3lJQ`L*nTCHhAqX}|y^mp%V zE$(l5d{5X#yiuOBr|TY0LN8h#9~dT`#-rBa#{Z=68f?p?;BuHVGWkV$MEc1TR09M*%HKQa(KnTfxraZoVuI=J9WebP8|Wxd=N8g z)tF0#P0-D}jgyYF9c|+E(5*S3#E~u+oG`0PPDQnviE)fXd3EYeiJm

    yRh*Nm76G;;^B*1B4m%wju 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 JFP1WT@jsDHt7`xN literal 0 HcmV?d00001 diff --git a/doc/kinfocenter/CMakeLists.txt b/doc/kinfocenter/CMakeLists.txt new file mode 100644 index 00000000..dd75aec8 --- /dev/null +++ b/doc/kinfocenter/CMakeLists.txt @@ -0,0 +1 @@ +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) diff --git a/doc/kinfocenter/index.docbook b/doc/kinfocenter/index.docbook new file mode 100644 index 00000000..62a8b333 --- /dev/null +++ b/doc/kinfocenter/index.docbook @@ -0,0 +1,931 @@ + + + + +]> + + + +The &infocenter; + + + +Michael +McBride +

    &Mike.McBride.mail;
    + + + + +&FDLNotice; +2013-06-22 +&kde; SC 4.11 + + +This documentation describes &kde;’s information center. + + + +KDE +kinfocenter +system +information +module + + + + + +The &infocenter; + + +The &infocenter; provides you with a centralized and convenient +overview of your system and desktop environment. + + + +The information center is made up of multiple modules. Each module is a +separate application, but the information center organizes all of these +programs into a convenient location. + + + +This next section details the use of the information center itself. For +information on individual modules, please see Default KInfo +Center Modules. + + + +Starting the &infocenter; + + +The &infocenter; can be started in three ways: + + + + + +By selecting Applications +SystemInfo +Center from the application launcher in the panel. + + + + + +By pressing &Alt;F2. +This will bring up &krunner;. Type +kinfocenter, and press &Enter;. + + + + + +You can type kinfocenter & at any command prompt. + + + + + +All three of these methods are equivalent, and produce the same result. + + + + + +The &infocenter; Screen + + +When you start the information center, you are presented with a window, +which can be divided into three functional parts. + + + + The &infocenter; Screen. + + + + + + The &infocenter; Screen + + + + + +Across the top is a toolbar. The toolbar will provide you with quick +access to most of &infocenter;’s features like export, get help on the current +module and a help menu. + + + +Along the left hand side, is a column with a filter field at the top. +This is a where you choose which module to investigate. To navigate through the various KCM modules, left click on +the module in the tree view. You can also use the arrow keys to scroll though the KCM's and pressing &Enter; will select the module. The module will +now appear of the main panel of the &infocenter; window. Some items within the tree view are categories, you can left click or again press &Enter; to expand and collapsed these items. This +will show the modules under the category. +You can right click on the module listing to show the following options: + + Collapse All Categories: Collapses the tree to show only top level modules and categories. + Expand All Categories: Expands the tree to show modules. + Clear Search: This will clear any filter you have applied on the module listing via the search box + + + + +The main panel shows you the system information about the selected module. + + + + + + + + + + +The &infocenter; Toolbar + +This next section gives you a brief description of what each toolbar item does. + + + + +Module Help button + + +This button opens khelpcenter with the current help page for the information module. + + + + +Help Menu button + +&kinfocenter; has the common &kde; Help +menu items, for more information read the section about the Help Menu +of the &kde; Fundamentals. + + + + + + +Exiting The &kde; Information Center + +You can exit the info center one of two ways: + + + +Type &Ctrl;Q on the keyboard. + + + + +Click on the Close button on the frame surrounding the info center. + + + + + + + + +The Default &infocenter; Modules + + + + +Summary Information Module + + +The summary information KCM provides a quick way to display important information. +The module has three categories; OS Information, CPU Information and Hard Drive Information. + +You may have more than one of these information boxes per category. + + +<acronym>OS</acronym> Information Box + + +Screenshot of OS Information box + + + + + + OS Information Box + + + + +The OS information box has the following information: + + +OS Version: This is the version information of the Operating System KInfoCenter is present on. +KDE SC Version: This is the version of the KDE Software Collection KInfoCenter was compiled on. +Hostname: This is the hostname of the computer KInfoCenter is present on. + + + + + +<acronym>CPU</acronym> Information Box + + +Screenshot of CPU Information box + + + + + + CPU Information Box + + + + +The CPU information box has the following information: + + +Processor: This is the vendors name for your CPU +Processor Number: This is the ID number of your CPU, starting from zero. +Processor Max Speed: This is the processors maximum speed. + + + + + +Hard Drive Information Box + + +Screenshot of Hard Drive Information box + + + + + + Hard Drive Information Box + + + + +The Hard Drive information box has the following information: + + +Drive Title: This is the vendors name for the hard drive. +Storage Size: This is the current size of your hard drive. +Bus: This is the bus your hard drive uses. + + + + + + + +Memory Information Module + +This module displays the current memory usage. It is updated +constantly, and can be very useful for pinpointing bottlenecks when certain +applications are executed. + + +Memory Types + +The first thing you must understand, is there are two types of +memory, available to the operating system and the programs +that run within it. + +The first type, is called physical memory. This is the memory located +within the memory chips, within your computer. This is the +RAM (for Random Access Memory) you bought when you +purchased your computer. + +The second type of memory, is called virtual or swap memory. This +block of memory, is actually space on the hard drive. The operating +system reserves a space on the hard drive for swap space. +The operating system can use this virtual memory (or swap space), if it +runs out of physical memory. The reason this is called +swap memory, is the operating system takes some data that +it doesn't think you will want for a while, and saves that to disk in +this reserved space. The operating system then loads the new data you +need right now. It has swapped the not needed data, for +the data you need right now. Virtual or swap memory is not as fast as +physical memory, so operating systems try to keep data (especially often +used data), in the physical memory. + +The total memory, is the combined total of physical memory and +virtual memory. + + + + +Memory Information Module + +This window is divided into a top and bottom section + +The top section shows you the total physical memory, total free + physical memory, shared memory, and buffered memory. + +All four values are represented as the total number of bytes, and + as the number of megabytes (1 megabyte = slightly more than 1,000,000 + bytes) + +The bottom section shows you three graphs: + + +Total Memory (this is the combination of physical and virtual memory). +Physical Memory +Virtual memory, or Swap Space. + + +The grey areas are free, and the blue and green areas are used. +The exact values of each type of memory are not critical, and + they change regularly. When you evaluate this page, look at + trends. + +Does your computer have plenty of free space (grey areas)? If + not, you can increase the swap size or increase the physical + memory. + +Also, if your computer seems sluggish: is your physical memory + full, and does the hard drive always seem to be running? This suggests + that you do not have enough physical memory, and your computer is + relying on the slower virtual memory for commonly used data. Increasing + your physical memory will improve the responsiveness of your + computer. + + + + + + + +Device Information Module + +Device Information is a device viewer module. It shows all relevant devices that are present within your PC. It has three sections, +a device viewer, a information panel and a UDI listing for the currently selected device. + +Device Listing +The device viewer displays all the current devices detected on your PC in a tree. The main topics at the beginning of the tree +are the device categories, left click on a collapsed category to expand it and vice versa to collapse it. +To display information about a device, left click on the device in the viewer, the information will display on the right side information panel. +You can right click on the device viewer to show the following options: + +Collapse All: Collapses the tree to show only the main categories. +Expand All: Expands the tree to show all the children devices. +Show All Devices: Show all the categories no matter if devices are present in those categories +Show Relevant Devices: Only show categories that have devices present. + +The default display is to collapse all while showing only relevant devices. Please note that the devices shown +in the device listing are not all devices within your PC, they are just devices that have been detected via the Solid. + The device viewer can show the following devices: + +Processors: These are your computers CPUs ( Central Processing Units ). +Storage Drives: Devices that are used to store your PCs files and data. +Network Interfaces: Devices that allow you to connect to a network or to another PC. +Audio Interfaces: Devices that allow your PC to play Sound. They are split into 2 categories, ALSA and OSS sound architectures. +Video Devices: Devices that allow you to stream live video. +Serial Devices: Devices that are connected to your serial port in your PC. +Smart Card Devices: Devices that are smart card readers. +Digital Video Broadcasting Devices: Devices that use the open standards for digital television. +Device Buttons: These are buttons that are present on your PC or external devices. +Batteries: These are battery devices that are plugged into your laptop. +AC Adapters: These devices will be present when you plug in your AC Adapter. +Multimedia Players: Devices that play media files, like a music player. +Camera Devices: These are digital camera that are connected to your PC. + + +Video devices do not include your video card adapter + + + +Information Panel +The information panel is where device information is shown when you select a device. The first two information topics are always: + +Product: The name of the device. +Vendor: The vendors name of the device. + +The following information topics are dependent on the device chosen. They are labeled with easy to understand names. +The information labels have the ability to be selected and copied from. + +Processor Max Speed and Supported Instruction sets topics are usual not set by solid. + + +Top categories in the device listing do not show any information. + + + +<acronym>UDI</acronym> Information +The bottom information panel shows the current selected devices UDI. This is the unique device identifier. +The label has the ability to be selected and copied from. + + + + + + +Interrupt Request (<abbrev>IRQ</abbrev>) Information Module + +This page displays information about the Interrupt Request +Lines in use, and the devices that use them. + +An IRQ is a hardware line used in a +PC by (ISA bus) devices like +keyboards, modems, sound cards, &etc;, to send interrupt signals to the +processor to tell it that the device is ready to send or accept data. +Unfortunately, there are only sixteen IRQ's (0-15) +available in the i386 (PC) architecture for sharing among +the various ISA devices. + +Many hardware problems are the result of IRQ +conflicts, when two devices try to use the same IRQ, or +software is misconfigured to use a different IRQ from the +one a device is actually configured for. + +The exact information displayed is system-dependent. On some +systems, IRQ information cannot be displayed + yet. + +On &Linux;, this information is read from +/proc/interrupts, which is only +available if the /proc +pseudo-filesystem is compiled into the kernel. + +The first column, is the IRQ number. The second +column, is the number of interrupts that have been received since the last +reboot. The third column shows the type of interrupt. The fourth, +identifies the device assigned to that interrupt. + +The user cannot modify any settings on this page. + + + + + +<acronym>DMA</acronym> Channel Information Module + + This page displays information about the DMA +(Direct Memory Access) Channels. A DMA channel is a +direct connection that allows devices to transfer data to and from +memory without going through the processor. Typically, i386-architecture +systems (PC's) have eight DMA +channels (0-7). + + The exact information displayed is system-dependent. On +some systems, DMA Channel information cannot be +displayed yet. + + On &Linux;, this information is read from /proc/dma, which is only available if the +/proc pseudo-filesystem is +compiled into the kernel. + + A list of all currently-registered (ISA bus) +DMA channels that are in use is shown. The first +column shows the DMA channel, and the second column +shows the device which uses that channel. + + +Unused DMA channels are not listed. + + + +The user cannot modify any settings on this page. + + + + + + +IEEE 1394 Device Information Module + +The IEEE 1394 interface, also known as FireWire, +is a serial bus interface standard for high-speed +communications and isochronous real-time data transfer. + +The list in this module displays all devices attached to IEEE 1394 bus and +allows you to reset the bus by clicking the Generate 1394 Bus Reset +button. + +The meaning of the columns in this list: + +Name: port or node name, the number can change with each bus reset +GUID: the 64 bit GUID of the node +Local: checked if the node is an IEEE 1394 port of your computer +IRM: checked if the node is isochronous resource manager capable +CRM: checked if the node is cycle master capable +ISO: checked if the node supports isochronous transfers +BM: checked if the node is bus manager capable +PM: checked if the node is power management capable +Acc: the cycle clock accuracy of the node, valid from 0 to 100 +Speed: the speed of the node +Vendor: the vendor of the device + + + + + + +<acronym>PCI</acronym>-bus/Installed <acronym>PCI</acronym> Cards Information Module + +This page displays information about the +PCI-bus and installed PCI cards, +and other devices that use the Peripheral Component Interconnect +(PCI) bus. + +The exact information displayed is system-dependent. On some +systems, PCI-information can not yet be +displayed. + +On &Linux;, this information is read from /proc/pci which is only available if the +/proc pseudo-filesystem is +compiled into the kernel. A listing of all PCI +devices found during kernel initialization, and their configuration, is +shown. + +Each entry begins with a bus, device and function number. +The user cannot modify any settings on this page. + + + + + +Input/Output Port Information Module + +This page displays information about the I/O ports. + +I/O Ports are memory addresses used by the processor for direct +communication with a device that has sent an +interrupt signal to the processor. + +The exchange of commands or data between the processor and the device +takes place through the I/O port address of the device, which is a + hexadecimal +number. No two devices can share the same I/O port. Many devices use + multiple +I/O port addresses, which are expressed as a range of hexadecimal +numbers. + +The exact information displayed is system-dependent. On some +systems, I/O port information can not yet be displayed. + +On &Linux;, this information is read from /proc/ioports which is only available if +the /proc pseudo-filesystem is +compiled into the kernel. A list of all currently-registered I/O port +regions that are in use is shown. + +The first column is the I/O port (or the range of I/O ports), the +second column identifies the device that uses these I/O ports. + +The user cannot modify any settings on this page. + + + + + +<acronym>SCSI</acronym> Interface Information Module + +This page displays information about Small Computer Systems +Interface (SCSI) Interfaces and the attached +SCSI devices. + +The exact information displayed is system-dependent. On +some systems SCSI information cannot be displayed +yet. + +On &Linux;, this information is read from /proc/scsi/scsi, which is only available +if the /proc pseudo-filesystem is +compiled into the kernel. A listing of all SCSI +devices known to the kernel is shown. + +The devices are sorted numerically by their host, channel, and +ID numbers. + +The user cannot modify any settings on this page. + + + + + +<acronym>USB</acronym> Controller/<acronym>USB</acronym> Devices Information Module + +This module allows you to see the devices attached to your +USB bus(es). + +This module is for information only, you cannot edit any +information you see here. + + + + + +Samba Status Information Module + +The Samba and NFS Status Monitor is a front end +to the programs smbstatus and +showmount. Smbstatus reports on current Samba +connections, and is part of the suite of Samba tools, which implements +the SMB (Session Message Block) protocol, also called +the NetBIOS or LanManager protocol. + +This protocol can be used to provide printer sharing or drive +sharing services on a network including machines running the various +flavors of &Microsoft; &Windows;. + +showmount is part of the NFS +software package. NFS stands for Network File System +and is the traditional &UNIX; way to share folders over the +network. In this case the output of showmount + is parsed. On some systems showmount is in +/usr/sbin, check if you have +showmount in your PATH. + + +Exports + +On this page you can see a big list which shows the currently +active connections to Samba shares and NFS exports of +your machine. The first column shows you whether the resource is a Samba +(SMB) share or a NFS export. The +second column contains the name of the share, the third the name of the +remote host, which accesses this share. The remaining columns have only +a meaning for Samba-shares. + +The fourth column contains the User ID of the +user, who accesses this share. Note that this does not have to be equal +to the &UNIX; user ID of this user. The same applies +for the next column, which displays the group ID of the +user. + +Each connection to one of your shares is handled by a single +process (smbd), the next column shows the process +ID (pid) of this +smbd. If you kill this process the connected user +will be disconnected. If the remote user works from &Windows;, as soon +as this process is killed a new one will be created, so he will almost +not notice it. + +The last column shows how many files this user has currently open. +Here you see only, how many files he has open just +now, you don't see how many he copied or formerly opened &etc; + + + + +Imports + + Here you see which Samba- and NFS-shares from +other hosts are mounted on your local system. The first column shows +whether it is a Samba- or NFS-share, the second column +displays the name of the share, and the third shows where it is +mounted. + +The mounted NFS-shares you should see on +&Linux; (this has been tested), and it should also work on &Solaris; +(this has not been tested). + + + + +Log + +This page presents the contents of your local samba log file in a +nice way. If you open this page, the list will be empty. You have to +press the Update button, then the samba log file +will be read and the results displayed. Check whether the samba log file +on your system is really at the location as specified in the input +line. If it is somewhere else or if it has another name, correct +it. After changing the file name you have to press +Update again. + +Samba logs its actions according to the log level (see +smb.conf). If loglevel = 1, samba logs only when +somebody connects to your machine and when this connection is closed +again. If log level = 2, it logs also if somebody opens a file and if he +closes the file again. If the log level is higher than 2, yet more +stuff is logged. + +If you are interested in who accesses your machine, and which +files are accessed, you should set the log level to 2 and regularly +create a new samba log file (⪚ set up a cron task +which once a week moves your current samba log file into another +folder or something like that). Otherwise your samba log file may +become very big. + +With the four checkboxes below the big list you can decide, which +events are displayed in the list. You have to press +Update to see the results. If the log level of +your samba is too low, you won't see everything. + +By clicking on the header of one column you can sort the list by +this column. + + + +Statistics + +On this page you can filter the contents of the third page for +certain contents. + +Let's say the Event field (not the one in the +list) is set to Connection, +Service/File is set to *, +Host/User is set to *, +Show expanded service info is disabled and +Show expanded host info is disabled. + +If you press Update now, you will see how +often a connection was opened to share * (&ie; to any +share) from host * (&ie; from any host). Now enable +Show expanded host info and press +Update again. Now you will see for every host +which matches the wildcard *, how many connections +were opened by him. + +Now press clear. + +Now set the Event field to File Access and +enable Show expanded service info and press +Update again. + +Now you will see how often every single file was accessed. If you +enable Show expanded host info too, you will see +how often every single user opened each file. + +In the input lines Service/File and +Host/User you can use the wildcards +* and ? in the same way you use +them at the command line. Regular expressions are not +recognized. + +By clicking on the header of a column you can sort the list by +this column. This way you can check out which file was opened most +often, or which user opened the most files or whatever. + + + + + +Section Author + +Module copyright 2000: Michael Glauche and &Alexander.Neundorf; &Alexander.Neundorf.mail; + +Originally written by: Michael Glauche + +Currently maintained by: &Alexander.Neundorf; &Alexander.Neundorf.mail; + + +Contributors +Conversion to kcontrol applet: +&Matthias.Hoelzer-Kluepfel; &Matthias.Hoelzer-Kluepfel.mail; +Use of K3Process instead of popen, and more error checking: +&David.Faure; &David.Faure.mail; +Conversion to kcmodule, added tab pages 2,3,4, bug +fixed: +&Alexander.Neundorf; &Alexander.Neundorf.mail; + + +Documentation copyright 2000 &Alexander.Neundorf; &Alexander.Neundorf.mail; + +Documentation translated to docbook by &Mike.McBride; &Mike.McBride.mail; + + + + + + + + + +Network Interfaces Information Module + + +This page displays information about the network interfaces +installed in your computer. + + +The exact information displayed is system-dependent. On +some systems, this information can not yet be displayed. + +The user cannot modify any settings on this page. + + + + + +OpenGL Information Module + +This page displays information about installed OpenGL implementation. +OpenGL (for "Open Graphics Library") is a cross-platform, +hardware independent interface for 3D graphics. + +GLX is the binding for OpenGL to X Window system. + + DRI (Direct Rendering Infrastucture) provides hardware acceleration for OpenGL. +You must have a videocard with 3D accelerator and properly installed driver for this. + + +Read more at the official OpenGL site http://www.opengl.org + + + + + +X Server Information Module + +This screen is useful for getting specific information about your +X server and the current session of X. + +When you open this module, you are presented with some +information. The left hand side of the window is organized into a +tree. Some of the elements have a plus sign in front of the label. +Clicking this sign opens a submenu related to the +label. Clicking on a minus sign in front of a label hides the +submenu. + +The right hand side of the window contains the individual +values for each of the parameters on the left. + +The information presented will vary depending on your +setup. + +Some setups may not be able to determine some or all of the +parameters. + +You can not change any values from this menu. It is for +information only. + + + + + + + +Credits and License + +&infocenter; +Program copyright 1997-2001 The &infocenter; Developers +Contributors: + + +Matthias Hoelzer-Kluepfel +&Matthias.Hoelzer-Kluepfel.mail; +&Matthias.Elter; &Matthias.Elter.mail; + + +Documentation copyright 2000 Michael +McBride &Mike.McBride.mail; + +Contributors: + + +&Paul.Campbell; &Paul.Campbell.mail; +&Helge.Deller; &Helge.Deller.mail; +&Mark.Donohoe; +&Patrick.Dowler; +&Duncan.Haldane; duncan@kde.org +&Steffen.Hansen; stefh@mip.ou.dk. +Matthias Hoelzer-Kluepfel &Matthias.Hoelzer-Kluepfel.mail; +Martin Jones &Martin.R.Jones.mail; +&Jost.Schenck; &Jost.Schenck.mail; +&Jonathan.Singer; &Jonathan.Singer.mail; +&Thomas.Tanghus; &Thomas.Tanghus.mail; +&Krishna.Tateneni; &Krishna.Tateneni.mail; +Ellis Whitehead ewhitehe@uni-freiburg.de + + + + + +&underFDL; +&underGPL; + + + + diff --git a/doc/kinfocenter/kinfocenter.png b/doc/kinfocenter/kinfocenter.png new file mode 100644 index 0000000000000000000000000000000000000000..29176c92663d6d79e265b4b9620f8287232d62ce GIT binary patch literal 110663 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%0DAVWz4 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

    x+7iM%{~@yG)?ZwyqCZ~6 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 Uu%|)g_Niby9WxM;PFxtKW7zLaT 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�rhQs_kY9v$ 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 literal 0 HcmV?d00001 diff --git a/doc/kinfocenter/sto_block.png b/doc/kinfocenter/sto_block.png new file mode 100644 index 0000000000000000000000000000000000000000..079f460dd71e0a3530c451428496aabe2786d1ec GIT binary patch literal 10708 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 + + + + +]> + + + +The &klipper; Handbook + + +&Philip.Rodrigues; &Philip.Rodrigues.mail; + + +&Carsten.Pfeiffer; &Carsten.Pfeiffer.mail; + + + + + + + + +2000-2003 +&Philip.Rodrigues; + + +&FDLNotice; + +2013-06-02 +0.9.7 (&kde; 4.11) + + +&klipper; is the &kde; clipboard cut & paste utility. + + + +KDE +Klipper +kdebase +clipboard + + + + +Introduction +&klipper; is the &kde; clipboard utility. It stores clipboard +history, and allows you to link clipboard contents to application +actions. Please report any problems or feature requests to KDEs bugzilla or use the Report Bug +item in the Help menu. + + + + +Using &klipper; + + +Basic Usage + +The &klipper; icon. + + + + + +The &klipper; icon + + + + +To display the clipboard history, click on the &klipper; icon in + the &kde; panel, or press &Ctrl;&Alt;V . Previous + clipboard entries are shown at the top of the popup menu which + appears. Selecting one of these copies it to the clipboard, from + where it can be pasted into any &kde; or X application as + usual. + +The shortcut for this action has to be configured in the +System Tray Settings on the Entries +page. + +You can search through the clipboard history by opening it +(click on &klipper;) and typing your query. The results are updated as +you type. In case you're wondering how to use the accelerator keys in +the &klipper; menu, just press &Alt; and the accelerator you want. For +example, to clear the clipboard history when the &klipper; menu is +open, press &Alt; and the underlined letter in Clear Clipboard History +. + +Select Show Barcode from the &klipper; popup menu to open a +dialog with a QRCode and a +DataMatrix barcode. +Use &ksnapshot; to capture the barcodes and save them. + + +To disable &klipper;, click on its icon and +from the menu that appears, select +Quit. + + + + +Actions + +&klipper; can perform actions on the contents of the clipboard, +based on whether they match a particular regular expression. For +example, any clipboard contents starting with http:// can +be passed to Firefox or &konqueror; as &URL;s to open. In addition, if the +contents matches a path, similar actions can be performed according to the file's +type. E.g, if the path to a PDF file is copied to the clipboard, the file can be +viewed in &okular;. + +To use this feature, just select a &URL; or path. +If there is a matching regular expression in &klipper;'s +list, a menu will appear showing you the programs for your selection. +Use the mouse or cursor keys to select a program, and &klipper; will run +this program, opening the address pointed to by the +selection. + +If you do not want to perform any actions on the clipboard +contents, select Disable This Popup on the pop-up menu +to return to what you were doing before. If you leave the menu, it will +disappear, leaving you to continue your work. You can change the time +that the menu remains for in the Configure Klipper... +dialog, with the option Timeout for action popups +under the General page. You can separately disable the +file path part using the option Enable MIME-based actions under +the Actions page. + +Actions can be disabled completely by clicking on &klipper; and +deselecting Enable Clipboard Actions, or by pressing +&Ctrl;&Alt;X. + +Clipboard contents which match a regular expression can also be +edited before performing an action on them. Select Edit +contents... on the &klipper; pop-up menu, and you can +change the clipboard contents in the dialog which appears, before +clicking the OK button to run the appropriate +action. + +Pressing &Ctrl;&Alt;R shows the pop-up +menu to repeat the last action which &klipper; performed. + + + + +Clipboard/Selection Behavior + + +General + +&klipper; can be used to set the behavior of the clipboard and selection in +&kde;. + + +The &X-Window; uses two separate clipboard buffers: the +selection and the clipboard. Text is +placed in the selection buffer by simply selecting it, and can be +pasted with the middle mouse button. To place text in +the clipboard buffer, select it and press +&Ctrl;X or +&Ctrl;C . Text from the +clipboard buffer is pasted using &Ctrl;V + or by selecting +EditPaste +. + + + + + + +Changing Clipboard/Selection Behavior + +In order to change clipboard/selection behavior, select +Configure &klipper;... from the &klipper; pop-up menu, +and in the dialog box that appears, select the +General page. Unchecking Synchronize contents of the clipboard and the +selection makes the clipboard and selection function as completely +separate buffers as described above. With this option set, the option +Ignore selection will prevent &klipper; from +including the contents of the selection in its clipboard history and from +performing actions on the contents of the selection. Selecting +Synchronize contents of the clipboard and the selection +causes the clipboard and selection buffers to always be the same, meaning that +text in the selection can be pasted with either the +middle mouse button or the key combination &Ctrl;V +, and similarly for text in the clipboard buffer. + + + + + + + + + + + + +Configuring &klipper; + + + +Viewing the Configuration Dialog + +To view or change &klipper;'s settings, open the &klipper; +pop-up menu, and select Configure Klipper.... The &klipper; +configuration dialog will appear. Its contents are described +below. + + + + +General Options + + + + +Save clipboard contents on +exit If this option is on, the clipboard +history will be saved when &klipper; exits, allowing you to use it next time +&klipper; starts. + + + + +Prevent empty clipboard +If selected, the clipboard will never be empty: &klipper; will +insert the most recent item from the clipboard history into the clipboard +instead of allowing it to be empty. + + + +Ignore images +When an area of the screen is selected with mouse or keyboard, +this is called the selection. If this option is selected, only text +selections are stored in the history, while images and other selections are not. + + + + + +Ignore selection +Sets the clipboard mode. This option will prevent &klipper; from +including the contents of the selection in its clipboard history and from +performing actions on the contents of the selection. See . + + + + + +Text selection only +When an area of the screen is selected with mouse or keyboard, this is +called the selection. If this option is selected, only text selections +are stored in the history, while images and other selections are not. +See . + + + + + +Synchronize contents of the clipboard and the +selection +Sets the clipboard mode. +When an area of the screen is selected with mouse or keyboard, this is +called the selection. If this option is selected, the selection and the +clipboard is kept the same, so that anything in the selection is immediately +available for pasting elsewhere using any method, including the traditional +middle mouse button. Otherwise, the selection is recorded in the clipboard +history, but the selection can only be pasted using the middle mouse button. +Also see the Ignore selection option. +See . + + + + + +Timeout for Action pop-ups +Set the time that a popup menu will remain for if you do +nothing with it. + + +Clipboard history +size +Sets the number of items that are stored +in the clipboard history. + + + + + + + +Actions Options + + + +Replay actions on an item selected from +history +If this is switched on, selecting an item from the history +causes &klipper; to display the actions pop-up on that item, if +appropriate. + + + + +Remove white space when executing actions +If selected, any white space (spaces, tabs, &etc;) at the +beginning and end of the clipboard contents will be removed before passing the +clipboard contents to an application. This is useful, for example, if the +clipboard contains a &URL; with spaces which, if opened by a web browser, would +cause an error. + + + + +Enable MIME-based actions +If selected, in addition to the actions you defined +a list of applications for the detected MIME type will appear in the popup menu. + + + + +Editing Expressions/Actions +On the Actions page, double-click +the regular expression or action that you want to edit or select it and +press the Edit Action button. A dialog will appear in which the +expression text can be edited as you wish. + + + +Adding Expressions/Actions +Click the Add Action button +to add a regular expression for &klipper; to match. &klipper; uses +&Qt;'s QRegExp, which understands most regular +expressions as you would use in grep or +egrep for instance. +You can add a description of the regular expression type (⪚ +HTTP URL) by left clicking in the +Description column. + +You can find detailed information about the use of +QRegExp regular expressions at http://qt-project.org/doc/qt-4.8/qregexp.html#details. +Note that &klipper; does not support the wildcard mode mentioned on this +page. + +Edit the regular expression as described above. To add a command +to execute, click Add Command and edit the command +in an in-place text editing box. Double-clicking on a command allows you to edit it. + +Note that %s in the command line is replaced with +the clipboard contents, ⪚ if your command definition is +kwrite %s and +your clipboard contents are /home/phil/textfile, +the command kwrite +/home/phil/textfile will be run. To +include %s in the command line, escape it with a +backslash, as so: \%s. + + +Advanced +Brings up the Disable Actions for windows of type +WM_CLASS dialog. +Some programs, such as &konqueror;, +use the clipboard internally. If you get unwanted &klipper; pop-ups all the time +when using a certain application, do the following: + + +Open the application. +From a terminal, run xprop +| grep WM_CLASS +and then click on the window of the application you are +running. +The first string after the equals sign is the one to +enter. + + +Once the WM_CLASS is added, no more actions will be generated for +windows of that application. + + + + + + + +Shortcuts Options + +The shortcuts page allows you to change the keyboard shortcuts +which are used to access &klipper; functions. You can change the +shortcut to one of three things: + + + +None +The selected action cannot be accessed directly from the +keyboard + + +Default +The selected action uses &klipper;'s default key. These are the +shortcuts referred to in this manual. + + +Custom +The selected action is assigned to the keys you choose. +To choose a custom key for the action you have selected, click on +Custom and then None. +Now type the desired key combination on your keyboard, as in any &kde; application. + + + + +If you define a shortcut for Open Klipper at Mouse Position +pressing this shortcut will open the &klipper; popup menu at the position of +the mouse cursor, instead of their default position (in the &kde; Panel). +Useful if you use the mouse more than the keyboard. + + + + + +Credits and License + + +&klipper; + + +Program copyright 1998 &Andrew.Stanley-Jones; asj@cban.com + + +Program copyright 1998-2000 &Carsten.Pfeiffer; &Carsten.Pfeiffer.mail; + +Currently maintained by Esben Mose Hansen. See http://mosehansen.dk/about +for contact details. + + + +Documentation copyright 2000-2003, 2005 &Philip.Rodrigues; +&Philip.Rodrigues.mail; + + +&underFDL; +&underGPL; + + + + +Installation + + +How to obtain &klipper; + +&install.intro.documentation; + + + + +Compilation and Installation +&install.compile.documentation; + + + + + + +&documentation.index; + + + + + + + + + + + + + diff --git a/doc/klipper/screenshot.png b/doc/klipper/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6c66057649367403d5f273c5debbc2915b7acf96 GIT binary patch literal 807 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

    1um%qVc#RRf6e=Yw{An2vYF6wp!G) zw8Sxyk@H0#@~^)I${`-K$*P3NVQNSgSmMbI-Te`9nr(3(+z_WcVst-JasGtP=+R_V=D_ zbm7ADO$0W)-JQuR8El<_DR+8a=FbmKqzahpzw>@VDFFeyd76MQ%G3R z=KP>+({XEv0&BbD>LHvvV^)r#xGNy+U}szIoitgVxRY4+ri7>{uN)3rTu1;AphF>= z|5W@mmxifRXv5?nYfz@aayE*J@fTw-O6p4D%JdwS{vSC2Az)-oWazI;j&!}pp;qd6 zV=6qisNcWMNkvkE0?s*X*GMpRW&B4PI->dId}JUxlj zr~*$!&bfK3Xhbwv*pw;imwCAcNF?r*u5!1My&g6Z?76uom%;%0mIju7A%w&0gbHXq zHQ<9AYI+VXtjahFiJUTZ+sn5iIvU)d8QFgK3Gpux zLOStL=>M~(G=Ah7keutg>lNdR-z@v?aqyG+7Yet?tO$*V}W53 ziQ>$_EICs8`Aiu#7ouzJ9L(3?Kg2V>gwcIneSPn}PRFlgs=>|fdkuMcEFhQGudseF z(d6~5TJJj?L4YtRv?z$Z&L?G{+nEwH0u|vynQus8f;lNhRj0w~Y zpXyk*9uC)wsC&O&`0!-Ys}XijpZPlV?w`?O1DU@f6s~Gju=#iM^N*RPfS}WRTeKc_ zW)PY-RPVE*^jFZkdKM8@46CxT{R)^>W2n_k4tqogdxX;$x`E^Z>CYIff^RzaKE zVM5a;4G}|qp73wLjNUZ}nepN-o=2o)Dfm4V6tL-+%DUlvH38tt6*V7AM~;!E8FIn8 z-OKUcggUuLbMuB@DAU+3)FY4Oh|V2MEluI>=EO*@VTz7BlL`AC#s>GIWpwFUNR6Ci zbhyaseBmJYlM`+%onti683%O!jsMK{^mU;HB?1yVgfBJnD zxd4<*9PcRZj-od6slVfI?+qW!LjW$br)&N}8zynxKE;F>9)y%-^+Xp%cN=NT0j}hs zkUCK^2@NUG`cHN=9XuqHmNymdV_ng|RL*ZlPZGe|r~6>tM*E@st``W2?e56wINavW z0Tqj%t<#k`u8ywmMyns0-(sCiNzBwwGfR8>S$8sD-=7R&F((vJ5PGSf9FxHAX?TXX zmV%0HCgMZucvwQEDC(s2IZKKFIJ6T@J-`Mc+}~+ z8L|0bM3!yi2`lHPS(eDdme_U?ZD>vHiv+gwQL3~QY3kzEKwdD}td(_X|7)A~`NO^n z`-97e*$N#-{emw^!%>^62}s18hnx$EoIOK0X;x+W*8bBsSkiH%fp2}E20WX!(;T&a z0*ZS?l7%I2-J+CL42oC6#Od&){7$&`F_U!Xaf4vkDAhO-;Pd{fiahN8u~$`eE8iVrgUGT2IC> zhZ!_K|5^sNvQ{%~iU9f^{pb;(Wp7UtL=1gsF0E(^QyldP2DZtaq%!M(C(EUyy@|sO|QMU*YmC;9^{9TU7RBu|b_&#<7#mbJ*5EBfV74iJy&jor79D znEfvaN%P7$Rj{!QC*t76L_X^c)#$<H^6)yHjHYwDllD{+SvX$YGu8NZOw{d`IWlK*c4`t&3 zH|3*Z73%MU8bS}w4E+sCo(i36YHM8$pv%uiD%gvwI-061lb7!_DKF`xDZ(>H(7-O9 zR>+?EE{o$DT=7*CY8#1Sa4pmArIZ~#P8utvlu9v*Bs-5Vnz7NS$B!h@K9CyNN&>{3 z_?40zoDAZ$rz)@riC9y|YMvwes8SVv0x-`wODGS$viKtg2@D4=khl6apPQ!!WEDSs z@nP2BX9+HN0jX%7nyfA_D2Inr3NwU2g;t6 zXxMoUlJX{P)Y}n^Bg5EMZ&_TVGU1UUvUsoaI8c5axwZJJN@OWMZHMsr2=}Kqis-CbVN;v;rt31*ZSvgiy}6cry_E zc_PlY4czuzczXHcR-KrR6%}t@EI>_fKt?r5>t?B&Et|MrVDoEfj_+zh83Ex_A?|d1 zf=qt}r-_ER_vyYxgfU?EucAaunAFG<6DU1H7ua{m6>aNdTrWhLsPDY4diiGJW(-U3 z3XQO;5oEZi4>|tQWfYEumU$4ETT@O6YkVVtcxu(st?R&W)$AxH($4`yL!X-+Q!f%- zUdiZHkzPIzT_TvuV30yXhNs(qBWic&_0bRswOjm>7H``;s$P60+fLLzn!oi=mY9?$ zBk_^-hv_PY%`YD!Awd-`QoA~1(1~EtsCv@I+HAVXOO5K|Y18;(z8Hzv61u(#4d4Pv z0x5}t(@^5@JGKX-;$%AE#(IRbeVJ=2EKiiVnLubP7T6^lyr?pt2K?AX9cBzet2T9* z={G52cM)nr1$sSUyCuZu?FMa_K`K>xOf67IgSkJn|3wL9sm5M9NBh`gWAyt9B}^a` zG=*sm+cQKVV5_^~Bi^cHu^aOZMZ+>pYC1--+rCVZjo8UeaWzd1N+DVZ!SDP(8JsM2 z@$uZ+`{%3HBlzwNF(htCslJ*}(%y__-u z@IjmC1>7GTb0|bDzZzy?qIn1 ztdyYfH=@ixvt-O3`zqk0{?{Wo@Whr_+&=Bun|G&2)%e3Se+=%PW?|B*KLu2a~>W21cH5*Y?e#0|*2dH`8D6ZR!!4!mrp?0uLCvif2f6dP1GxG%+*k6@e zHIsj|wi0e75W+?F#pF%^q>w)#MS}86b18#9q99qqzg2-Em||<=zke?lKTvE5uVNzXx8uC(1bEsDx&QC^DK!wv_A{FKJ~J0BPuYY+igto90erLIOk z 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�YScH%2-ap8`f@Vutf_5^UlhihlgHePE<&T9*Pn4-09_u|8~gdx#ej!2=hWCpRR3SG5A)4PloPb}ULPq~;`i2Z)u zR^#BVH*DF#QEE_S4eQogFEYmELz$pvQfMGex#QYX6{coR7Je*z?d!ugQd)xg9AXIO z&f_Y51vlrLE~c1m#`|f}r0yRfN*UUDDfK1PHA_n7V_O3=H5zmCd&3%o1(w)##MKJW z5m~I90@MAfu8JI(biH9Aenl~-2rtp-=;$XFR<`HO0@FqBt-HN+%R=^Qfcw?db_E;< zijj)JPr}DDa9O9n3$FJha&~HWRo_kp21=~3U;pS^qw;+S-Rp@p+E5`IlW|qQnCPjb z_wNh3NXJH+Bvf0X*H6Cu`vfzTRULo0>Y8)QA57)m2>2BaB?2>cAR)+8roaA0oPXoO5Av$H{}XrqhLvIP+dr$~{}(gb zTtQXJtQw3=r+?mjYgvGubqThiby$BVl$$zkgF=w4t0XBm)-^55Ern)jp{lvWfGm?uZonP2KwzIR7>~`NhU6=Q^>z1a&*dI-l zpZts|zm^3>T{PBr2wRwYoXTneUi9r4v>)7GX|q**S|g(hv}h1T;3%WI zU-0Z*Q{IhUK2%6CnnyC--`y!Y!@k z+bOI&*4~8%6D^j1zNE~TL`k$@Fs$sAGj(L7(^GCanK~DDTd)8On;~WYy?(BKp8oPT zV>(7Kmx3nspUr(aHb%)few>au4I+B;-rd->Rm9w&O@3ya%F};ixJp(xqL;p<8?Tzso{dt3Bcrfw)D02L|3=t zfD3veKuAhH^$9lq7X!L_lA2*VdwY&I!4E#0od(J8;Y5ZxQ9$D>S%Y#k(&^$P*?5F( zCwmYL0iGd^_-nUwl{=ViRP6Lf>7rv$OGly^(PgL~ zF(IHcx`EEa9lx{rMj0f$4sRkS=f=8lZt;guc)&n!heMgj;bcLI^vt;eaHaC9v3oA~ z+<#Fvjr%`2A-(Kq+i_{2k?tJkB7zp{u=bJ`W9FU_>>f1UOczK9A%p}a)> zqTi#|y~Hn~J5jq{=gmPNLi9D!&kP8+a*wbbAX)@aD~pv3nB8-Z7pp!_s$4 z4ZJQPWnnoC)vH-;=OlcU*ReIyfP7}H#eSBq6dlVA)qG&j*$xJk8V8l$`HwL!W2=1% z8rHs=<{ZED`Bd^qXfDbhwQwY29-WC=I})3VZbt1KNtnmXqmGZH=3*`rFgfX=NM)mG zBFkNe3shr+kMz=-^X~RO!Rj(C(bOnUm2*rB9JKW{C@A9`i{*J|PTp}hPky5a`@p#e$1m=)Bi zm-L0ktviGwA)rcSn^7X!`I6@~-r2Kq}j>{#rs8{aThfLKonM8gY97aoZfZ?9qY+2Kw9_WmkJre$R+NbJ(B$|8^i%}}) z>N5DfxD0te8sP_t6)i;a>V)sXrrR;f>VUCMnhEZ~=VP!Fa2$0Qt;e@=_$VzD6rtDSkP)58x0_fIIt+igI$;}NN#d2! z*Tf*}i~7QcywlbdPC*n9s*y?=C+ezxv^u%lwxLn~zX*_+OKSyU#);~8cU`+(9G}e4 z;hl?|6bLD$v5VTI87P-5P7G$nhgvFnnS!!iZ7Z8)`<8FKS54`Wf0m{AKc4u{mv_g# zQaX=5B;p(D7rhou?HEi(-N3BWUtXi990;jWx6)pnaV%6?SXE~p_!AVfP7z^)do>5c znkVZ6N7)0|aob{Vk}f(#;+cUoH3x%L44N(jyTPWlswU~2dEvarSWOhGqsIlCRJ9Eo zKQ=Zuwl=mmb~ex(yBm8O`*ghLf)%j$yz3g4->2bzI!68_#i6RvIcO&{DUw2+WQnTR z7IY6wpFKa?IVHrvc{y(3bVRY8NCug*kF&j7sZ#>4Stu8aO5VS~;vqce;yzWW5|o#@$fvOD>@XIveny zI4p_cFJR~&-aI81#5i+ozNLr(eEvH3pN+nsMXVIBig)$>fB!tCFkya2B~HdpdR0zI MP90Jz^DyB501G;s9RL6T literal 0 HcmV?d00001 diff --git a/doc/kmenuedit/index.docbook b/doc/kmenuedit/index.docbook new file mode 100644 index 00000000..b02f6851 --- /dev/null +++ b/doc/kmenuedit/index.docbook @@ -0,0 +1,645 @@ + + + + Firefox"> + + +]> + + + + + +The &kde; Menu Editor Handbook + + +&Milos.Prudek; &Milos.Prudek.mail; +&Anne-Marie.Mahfouf; &Anne-Marie.Mahfouf.mail; + +&Lauri.Watts; &Lauri.Watts.mail; + + + + + + +2000 +&Milos.Prudek; + + +2008 +&Anne-Marie.Mahfouf; + + +&FDLNotice; + +2013-09-07 +0.9 (&kde; 4.11) + +&kmenuedit; allows editing one of the &kde; application launchers: &kickoff;, the classic &kmenu; or Lancelot Launcher. + + + +KDE +KDE Menu Editor +kmenuedit +application +program +menu +kickoff +Lancelot + + + + +Introduction + +&kmenuedit; allows editing the menu of &kde; application launchers: &kickoff;, classic &kmenu; or Lancelot Launcher. + +&kmenuedit; can be started either by &RMB; clicking the application launcher +button on the panel and choosing Edit +Applications..., or +by typing kmenuedit in the &krunner; line. + +&kmenuedit; allows you to: + + +View and edit the menu used by the current application launcher (&kickoff;, classic menu or Lancelot Launcher) +Cut, Copy +and Paste submenus and items +Create and delete submenus and items +Change the order of submenus and items +Hide items and add new submenus and items + + +By default all applications installed on the computer appear in the application launchers menu of all users. +Applications may appear more than once in several different menus. +Empty submenu categories defined in the desktop menu specification will show up as well, +but are not visible in application launchers unless you install applications belonging to these categories. + + +The tree view has three different entry types: + +Submenu: Only Name, Comment and +Description fields and the button to select an icon +are enabled, the Advanced tab is disabled. +Any submenu can hold additional submenus and/or items. + +Items: Use this entry to enter the data for the application you want to add. +For detailed information see Using &kmenuedit;. + +Separator: A visual entry to structure the menu. It cannot be modified +and all editing actions are disabled. + + + +&kmenuedit; has two tree view modes - normal and with hidden entries. To see the latter check the option +Show hidden entries in the configuration dialog on the General options page. + +Many additional entries appear in hidden view mode in the tree. Several hidden entries seem to be just duplicates +but have different command options. Usually you should never change these hidden entries or you risk to break some +functionality of the system. + +In hidden mode you will have a special submenu .hidden [Hidden] as top level +item in the tree. This special submenu is not editable. In this submenu all deleted items will be shown at the next +start of &kmenuedit;. +It is not possible to delete entries using the &GUI; in this special submenu. They will reappear at the +next start of &kmenuedit;. + + + +Use Cases + + +Adapt the Menu for a User + + +Reorder Items + +This should be done in hidden view mode where only the submenus and items visible in the application +launcher menu are displayed. + +By default the menu is sorted alphabetically using the English names or descriptions. Using another language +than English some submenus and items therefore will appear in an unsorted order. + +Use the options in EditSort +to sort either by name or description. If you use the classic application launcher you have to select the +corresponding Format option in the settings dialog. In the &kickoff; launcher check +Show applications by name if you sort them by name here. + +Grouping your frequently used submenus or items together ⪚ at the top of the menu makes selecting them easier. +To change the order of particular items or submenus in the tree use the Move Up or +Move Down button in the toolbar or these actions in the menu. + +All application launchers will use the order of submenus defined in &kmenuedit;. + + + + +Remove Items from the Menu View + +Having shown all applications installed on a computer may be confusing for some users so you may +want to hide some less frequently used items or submenus. There are two different ways to do that: + + +Switch to normal view mode without hidden entries. If you delete items they are moved to the +.hidden [Hidden] submenu. You can move them back into the tree to have them in the menu again. + +If you delete a submenu it will be really deleted with all its submenus and items. +To recreate them you can use EditRestore to System +Menu, but this will remove all your custom submenus and items +and the corresponding .desktop files are deleted too. This action cannot be reverted. + + +The preferred way to remove submenus and items in the menu of an application launcher is to check Hidden +entry on the General tab and switch to the hidden view mode. +In this mode it is easy to revert changes without destroying the menu structure. +The only drawback is that you have to hide all entries in a submenu manually to +hide the whole submenu from the view. + + + + + + +Adding Custom Items + +To add custom items (submenu, item or separator) use the actions in the menu or toolbar. +Items need a Name and a Command, without a command entry an item will not be saved and your addition gets lost. + +If you add an entry it is inserted as sub entry at the actual highlighted position in the tree. +Move an entry by dragging it with the mouse or using the Move Down button +to the bottom of the tree to make it a top level entry. + + + + + +Transfer application launcher settings + +There is no way to transfer menu settings using the &GUI;, you have to do that manually +and copy the following files to the target user: +&kmenuedit; stores the menu hierarchy in +$HOME/.config/menus/applications-kmenuedit.menu +and $HOME/.local/share/desktop-directories +contains desktop files for submenus you created. +In $HOME/.local/share/applications/ you +find the desktop files for the custom items you created. + +The shortcuts for each application are stored in ~/.kde/share/config/kglobalshortcutsrc, +but export/import does not work because the UUIDs of the shortcuts do not match up between systems, even though the +.desktop files are the same. You have to assign all shortcuts manually again. + + + + + + + + + + +&Virgil.J.Nisly; &Virgil.J.Nisly.mail; + + +Adding a Menu Entry + + In this example, we will add &firefox; to the Internet submenu. + To start off, we need to open &kmenuedit;, so &RMB; on the application +launcher menu, click Edit Applications... to start +&kmenuedit;. After &kmenuedit; has started, select Internet as shown in picture below. + +Select Internet + + + + + +Select Internet + + + + + Once you have selected Internet, click on FileNew Item..., opening the New Item dialog, as shown below. Type the name of the program you want to add, in this case, type firefox. + +New Item dialog + + + + + +The New Item dialog. + + + + + +Press return, and you should see something like the picture below in the main window. + +New Item + + + + + +The new item created. + + + + + +Now lets fill in the Description:, in this case type Web Browser. +The appearance how description and name will be displayed depends on the settings in the application +launcher ⪚ Web Browser (Firefox) or Firefox (Web Browser). +We will need to fill in the executable name in the Command: field, in this instance we will type firefox. +The command has to be in your PATH variable or you have to specify the full path to the executable. +If you do not know the executable name of an application use the locate +command to search for the desktop file and enter the string from the Exec line as command here. + +Following the command, you can have several place holders which will be replaced with actual values when the program is run: + +%f - a single file name +%F - a list of files; use for applications that can open several local files at once +%u - a single &URL; +%U - a list of &URL;s +%d - the folder of a file to open +%D - a list of folders +%i - the icon +%m - the mini icon +%c - the caption + +For example: if you want to firefox to start your web browsing at www.kde.org - instead of firefox you would type firefox %u www.kde.org. +Most applications accept additional options ⪚ the name of a defined profile like &konqueror; or &konsole;. +To see all options for an application launch applicationname in &konsole;. +We would like to have a more creative icon, so we will click the generic icon sitting beside Name: (note, the default icon may be blank, in which case click in the area to the right of the name entry box.) It will bring the Select Icon dialog which will let us choose the new icon, as shown below. + +Select Icon dialog + + + + + +The Select Icon dialog. + + + + + We choose the firefox icon from the list, and press &Enter;. Your finished screen should probably look something like the screenshot below. + +Done screenshot + + + + + +This is what the completed menu item should looks like. + + + + +The place of the new menu item can now be changed using Move Up and Move Down buttons on the &kmenuedit; toolbar or by dragging with the mouse. + The submenu items can be sorted using Sort button on the &kmenuedit; toolbar or EditSort submenu items. + +Click FileSave, wait for the Updating System Configuration dialog to get finished, you should find &firefox; in the application launcher Internet submenu. + + + + +Using &kmenuedit; + +The left application panel shows the application launcher structure. When +you browse items in the left panel, the right panel shows detailed +information for the highlighted menu item. + + +General tab + + + +Name: +This is the name of your program as it appears in the +application launcher menu. It can be different from the real executable +name. For instance the name of mc executable is +"Midnight Commander". + + +Description: +The description will be displayed together with the name in the application launcher. This is entirely optional. + + +Comment: +Describe the program in greater detail in this field. This is +entirely optional. + + +Command: +This is the name of the executable program. Make sure that you +have permission to run the program. + + +Enable launch feedback +If this box is checked, this will display feedback when an application is started. + + + +Place in system tray +When checked, the application's icon will show up in the panel system tray. +You will then be able to hide or show the application by clicking on the system +tray icon. Clicking on it using the &RMB; will allow also you to undock, or quit the +application. + + + +Only show in &kde; +When checked, the application entry will only be visible in all &kde; application launchers but not in other desktops environments. + + + +Hidden entry +Remove an entry from the menu view in the application launcher. + + + + + +Advanced tab + + + +Work path: +Specify the work path of the program. This will be the current +path when the program launches. It does not need to be the same as the +executable location. + + +Run in terminal +You must check this if your program requires terminal emulator +in order to run. This mainly applies to console +applications. + + +Terminal options: +Put all terminal options in this field. + + +Run as a different user +If you want to run this program as a different user (not you), +check this checkbox, and provide the username in the +Username: field. + + + +Current shortcut key: +You can assign a special keyboard shortcut to launch your program. + +Click the None button to the right of the Current +shortcut key: checkbox. + +The button text will change to Input... +and you can press the key combination on your keyboard that you want to be assigned to your program. + +You can reset the shortcut to None by using this button: . + + +Don't forget to save your setting by clicking the toolbar Save icon or using the +FileSave + menu item. + + + + + + + + + +Menu Reference + +Most actions in the menubar are also available in the context menu opened with a &RMB; +click on an item in the tree view. + + + + +&Ctrl;N +File New Item... + Adds new menu +item. + + + + +File +New Submenu... + +Adds new submenu. + + + +FileNew +Separator + +Adds a new separator to the menu. + + + + + +&Ctrl;S +FileSave + + +Saves the menu + + + + + + +&Ctrl;Q + +File +Quit + +Quits &kmenuedit;. + + + + +Edit +Move Up + +Moves the selected item up in its submenu. + + + + +Edit +Move Down + +Moves the selected item down in its submenu. + + + + + + +&Ctrl;X + + +Edit Cut + +Cuts the current menu item to the clipboard. If +you want to move menu item, you should first cut it to the clipboard, move to +the destination place using the left panel, and use the +Paste function to paste the menu item from the +clipboard. + + + + + +&Ctrl;C + + +Edit Copy + +Copies the current menu item to the +clipboard. You can later use the Paste +function to paste the copied menu item from the clipboard to its destination. You +can paste the same item many times. + + + + + +&Ctrl;V + +Edit +Paste +Paste menu item from the clipboard to currently +selected place in the main menu. You must first use +Cut or Copy before you can +Paste. + + + + +Del +Edit Delete + +Deletes currently selected menu +item. + + + + +Edit +Sort + +Opens submenu to sort selected submenu or all menu tree. There are two sorting methods implemented, namely, by the name and by the description. + + + + +Edit Restore to System Menu + +This will restore the application launcher as it was as default and remove all your custom settings. A message box will ask you if you really want to do that. + + + + + +&kmenuedit; has the common &kde; Settings and Help +menu items, for more information read the sections about the Settings Menu and Help Menu +of the &kde; Fundamentals. + + + + + + +Credits and License + + +&kmenuedit; + +Program copyright © 2002, &Raffaele.Sandrini; + +Contributors: + +&Matthias.Elter; &Matthias.Elter.mail; - Original +Author + +&Matthias.Ettrich; &Matthias.Ettrich.mail; + +&Daniel.M.Duley; &Daniel.M.Duley.mail; + +&Preston.Brown; &Preston.Brown.mail; + + + +Documentation copyright © 2000 &Milos.Prudek; +Documentation copyright © 2008 &Anne-Marie.Mahfouf; +Updated for &kde; 3.0 by &Lauri.Watts; &Lauri.Watts.mail; +2002 + + + +&underFDL; +&underGPL; + + + + +Glossary + + +Console Application + + +Application originally written for non-graphic, text oriented +environment. Such applications run fine in &kde;. They must run within +console emulator, like &konsole;. They are not warned automatically +when you shut down your &kde; session. You therefore must not forget +to save documents open in these applications before you log out from +the &kde;. + +Console applications support copying and pasting from +&kde;-compliant applications.Simply mark the text in the console +application with your mouse, switch to the &kde;-compliant application +and press &Ctrl; +V to paste the text. If you want to copy +from &kde; application to a console application, first mark the text +with your mouse, press &Ctrl; +C, switch to the console application and +press the middle button on your mouseIf your mouse +does not have a middle button, you must press +left and right +button at the same time. This is called middle button +emulation and it must be supported by your operating system to +work.. + + + + + + +&documentation.index; + + + + diff --git a/doc/kmenuedit/itemname.png b/doc/kmenuedit/itemname.png new file mode 100644 index 0000000000000000000000000000000000000000..5d0abffa9702640588f76dd2d8bece1de0234e40 GIT binary patch literal 19030 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

    sIJz!REsVavOh^bScsZEj-Q<> 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 SXyd=!l@ga1D;4?V{l5ShSRcy( literal 0 HcmV?d00001 diff --git a/doc/kmenuedit/selectinternet.png b/doc/kmenuedit/selectinternet.png new file mode 100644 index 0000000000000000000000000000000000000000..45ce5fdf1e3e32b1d168db803ec175d8995488c4 GIT binary patch literal 26896 zcma&Nb8w_l_bxiIF~P*P)3GzLZ6_Vu*2K1L+nHD$V`3WSe6nMQuSCn z&vAD_AL$u!-Qpc1y2^fgxa^kNlKB&7A>X1J9h6M&p_o^~d=Z_nEZAwxZd~X^W%%?aAqBSom9) zE{}H|T0tz@^UB*b7s0x6nepYSd_9m&$9C;NZ+WpXW^+}!amuOMN-eN-{GQfI1y1FV z0(3!3p{6WU6_ehWcL1dJ_08FZs~u&6@@fXB;bh8GH)MfEmV~Lc6?%C zo~ms`z^|#9P@`FeT+o&d{nA#-lD5D>t9fRkEm@Rrc1r<3r2^EZ6>-q5FcDME#Dr_+ z6frMI^Ti|n3n7_0H6yU8kTKi@XK0#*bq^7^6CGnwLOv_~g=jtBj1~m_copV5gRp#Y zmXb815KGV6YYpw_Ff|#&dWnqdUg+pNzfu4VD4;ZC+6yfd?kKuXS`O5-%E7r3rTt;M zdAo|8r6eNY;XnK4sefsgvqkkQ$%pI}iaxoD1~*!`|eR?aDhV`wMsEh-#`u zqXhc|?C|eVHkY5v+_U2nnS@Wv140b#d>6*NB|C4ce^62!p{egnSyD8f;j_w8xuaENoSJU*w}aX!k?Oa=iurcg*w%C=v34Fk7eE7i!~tsE^@b7Gbr zr;`ECCY5MeWY58NA{}cw(UqGE&QZ55_Wgs*1g^7I39wCBHiTceLDrCK?aJrpCn^(Z z^zw4jlZvA~D~+BrPrOqy4aO443S~+UlvirG|tZrMG+A_0% zIaDyvDKn_i`x3}^402HeIPNf0Z=z>7<*w80iu9Z#>DUBnumz8y!))H2!7CQysS#oh z6o%=G;?#0wdyL#Op@)Bmoxq z!=;Y+1;f7CxHQ9x?84O|iz^c4LgXjMLRQVv(G}^weYg=_k<+2|uEGG8V559Lzw51U z$M0b8-^07d*y{%!*czKp>BmF+g#odNGILMoYrjo)eU@BY{uRMcAe7&>*(b7K0jJm)+hWTKTgKR~li zf!ajc+-{!j3*>oU%TK_4LPieI#Ay_-^bTiuRs`mi2ZZRbq;eq_K7a#L=qk9t#buq{ zJ{-tVixKqt3z@*B)37ULu({&0mhtEUOXM}mt2}JP+#_6kt8aB)P%8%8&Z!e^p^q7` z!ROIzImn|VjV9AEIx!ojSB&lO+jl)p)#=Zf;PZQc>hl!d@(yDG0q2BKXx@|F|7`8JpB(LUvBoYN&*$Ohd8PQ54d zk$G&5fY$Y8gLm|zu?}7aR0Y7q5RQAH5ajG6GW(_OzJO+1e2!fg({NN8)OVykVYVjW z7~W;spILBqq}Lexpozwar3=OVY4%HteR0lQU{^b>LfPS>tK$GZ5_{BNT=!-nkRC+# zx0xO9s%v^0jjCZn4yGnLCaNqf2|#1B1hoIp-^tj~`^?*%H1qm0zdGRife;U7kt8te z8Pex>uY8UjwT2mwx`CH}J&Jhn(gvfVra^y$N1M+T_jw9y%6^L%PF1@Y!{}a>VvE;N zmjM5>C#xg2eqyY{qC~y&@+X=a2h(MwvWbCoq0lhpWzZV^FKb0Y^Nt3HS`8J%{o~?_ zv6a71o_wxy*8{(pdu~=Pz(@U}W;_?w%@un6emcbv*k&IO!#Q+k0MlE@*hzkP&-c_$ zC=o^SGQV9iR|!^!J|j2u7`IRzz2fIoV*SO&jaF_E3K!4F`=Oob@FY}PFR)+CNXM^} zlTtHX{FDr4sfv^Sn_i=8cM&t9iOt-&$tZmz2s-18BG^t0PjzMU7a2{f-2<+7=a@>F z>WK8HVsE}Z&uwW6A0j$?DxvDAv>ro(}C<-rKpy<7CA=YpFt8Gmn;v z9ws{NQ0^OSHZ3C!0|Ol$odkhsN_AyzMSzu+we{I4tuW;6!vQq7JR+P2=oQ zZ!V4MPM-MMwybTp^uaE&MGa4BXTLp(Np0QW6uNEU<0&an&om@+Zf-77kTZRur@sFB za!KI!5-e@0+4+d%*6Kx=+q@F94t?g&ecL2inH zVll4OFP1xAFpI-Avjl0fqNV~F;TrUX7K4s~4yK>>{##Y)KQ#>lgU_9QlszJScW>Vk zpF_&2Ow;~(n#dZItR7bPDQ(dBvakL&QFogLvMD%-+=`*J%vQzB%JWa{(SaJ%Vvs>< z&%7pgCG!L)9bHhObe*i4y1Keqs4nBvy~E77;?GK1u~zYrj8{(_6)!r_%0BUDOvJtg zyECnV#F>D`VJqDy6RjbZ6rfWo-P~xSEYF6vyd0(sT&0=b%F@4`{qpwFKGNlbIy1xzv>_2b1o68MPq@o|&mM`r)I z-y*1wcg|hjrYu{{QqEj1cd&(_?R-=+Jz7qc4TTZA@vUJwM zMe|6kYHDU8sCjjjgrr|n+KBMjJ@sny>7Vl2rK4#bSI4+-0dfJPhc%TrYZ^L9^=l-Fc=sLTLkxbJX4Ncgv9#?)0baU^017-7BMFE; z9JgI>_dfi9_ovY3r7K|*tIGSHzO5P=c2MJ-ay0=b0h_4PaZ?+w3Z;VGntwx=AqG27k`c4bu)aWzp~O(ao3}x))bko#E(I%Oh%Li+Ff=L8W=7nrke zM(`@KOVNFV=yHHtGKIEvTi7DKdUZd3-_q^SFchq3_>Z$h!)v*KDJEO4EKeooc^RTx zq9@3~piox%@V6XhH(7^#LEq8$4@b1nS>M8!l$l{GkQVb=iAc9{vAQUsy)vOS&C05B z_rB5CN3n^i!?>~0Eg3blc3PT2I<0!7NrvSdVgef(h2GJg7hcmE?rFE*6;Pn?n;_8( zs(0**#qd2@7_#ARIep2-Yb+M!npuRb-mGwP=_C(&$@nZbW@8QsIw4egw`QZpsh!70 zvN5&ONBOINq*OzL@o=^NZ>y=w#mvIf#M7|z9!)>3oQ{0>gd0pQN0Yz?K5c0rAENSt zG~aP>=hwcBalQX@J8PjBkPJPoe8ZAlM)pc>Q(tEe(bl;4PWVnIR+LB+|$SPkOA{4 z8NHln3GTmNQa5AH%HG-sa3|^MpSYgkATK?8o`U%P;kWnnxOJ1r77Y?tGyUkZrh8U~ ze^gmAu^a+iFU+6nVo=(#UKOgedP;i2(@o@hS!j)CdK*`XsJ}ffmqYH30O{b+1-Q}J zJRZXfG+=%`u>S@JZTq`^FG!>h;CZiTdLgUqvrKb4ttiqfj3CpmG&elG>WyBn5>1J! z&j(1L5DC+OT(FDFmSOv@h{X$0Do*Nx z61$a~k|*E2-HerTxtjzA+AM@|RQ(lrAn$tj6$l2#xE4ql@PX|3#nwZANMwF68Y9Zk*6B1v4@493-_OFToF69Qc1wsaT2L=GHEL*fp9EF?|m-shzk)jYXf@MPx z55FZ4D7*)kEXIEo1Lg7ZzJS|cmtZoOCu5{C9eK{3zk|cvMhZE66;ZIpiqT4*s)@;w z=?0mu8kv!PmX-Y5ihh;U62Y}THcmJ^FJ}-3F+$_R#2^GoYVVx`FD!QpYE>IK_2Fik z$2NOzl`z%kGCWRQK7VA-y(1@t-(je#(BHrlzJ5MHIC}A0{U{;k02h@2c=c}J#fu&9 zin#~FT&Sbrm0h;a_NAV+dTl-g%H?`cZyIN#NPfW?N1ydzH|AMDIa>B<0_Y_2_oHPU_m&u#`7qt5J*~h~jEN564=% zW~|0D^ma1j__pQnTp<{Aj$zDAVx#JWO??>3aob7QYm2dm0tS8FiqcqMVrDo<4eCU3usCkQRc%h;YUPvt)o&-M)7a;?0a921v`Ao-bRe zVog~f34ZyOh35JfRh_#ZJSY6$;Ot;|0QCsM(X5amw&gKPsi9lQ6KsD6JR zp}!MP^+$9%!7vF;Xp`w^33D9THSh%ZL%?CdOTxN_Xr#I5ecZ}IFYdLQJU zKM9jBC&rW-o{V;n>fZdo!sw-b?f*XOv{#ZbD#ACMD%j-hJxd1CQ;9f$#BXfaB|Lxw4vjL(0!6*aDpW(;=W z9$LCxzA%-*%S71JqhF+-2KS zccA!2=&xaELx%qprdxD{$dLb=XeLlM+g_0*&wdM%q--t`eYY+%4QPnXb6?TJ3~xk# z2#wb>my-LO|4s0|Y%iVyt~c+~_D|o_PR3v;1j_46$^`viQEysqlGwvwvtsN}mH^;b z1W?*AgG-JwNqS;pTpA=a<024qxD~S~faD66(orAy`ee$2v-OMmk3H8wYTVT3=9K2t zQ@1-z4~K8K5DzML@JE^)-jYf{@B4YUU@tXuz5m-T*SQSVbdu;#9kjFZi4veHp$k;u zp3?5I)Ni+ciK_HG?f!KnpvS9!`lQn9ukZ5Bp(`}QPTnT6##p9GjjE2c_*~XWB-7C? zjB*wlnVnyO(&{!lltG$%vCyRAqgiP9q@FY%C02kn38+pcsLSl03)k4tdI|fZHtJ|b zOaY0j+v;EAakv95{)IVW?@vxzcp~4Z=ZZgVFuM|k!heh!4(H{5F-F4TA|I7t;{%#0 zDlUCqP>5rgZ<+M5XrOmjIgqsyf5loIzzGzR_JvZ-I87UeJ@}4skt>Xb08Qk$@RFwT zv6GX3QDn_EHnN>KDq&i-;n5lEt4gph(88O3C`)+>3;URviCbAo<8lni$n+nbpCgV8 zDMGw-%dAuT-;;Rx2x|2rR}5bHJc=l`(94>Q!NoCN- zz}Qg;;Wg;xSu?|U@l_f>LFoVKo3H*B4Ua-`71=ztZX6+{zfhihD;n{ps@dr-9>F`> z(el42Gr1D@Hl+M+85BKlB-W=8wB?)qJ80`YVNhZ+;{iaCAXyA(+#Opm=^R^9Z~wci zYO;f3&_>;$Qa$y(Xf0736&hj}W1l+m0k=Vgo@iXU9(fIvg$}z(QER+i7)Tesf-g$>7SHdcI4t-#=haERjg$5M#D6*@m7>XjmQ~ zgBme=nfeP5Yqt_#z*;twkAaK(k}x<~@u*@p^TM@iC?hQ$85O0|0zAC0n765}t{5c? zMH*aYkY)po#_?^~&F8$h=**!SJ!90TN|ImG$8YuZ^^Jxz`!p*tHH-pP!>~Bl^h%$S+lL##HiR(8Y+k$Qn2RCDeHxE`ikpWA5I%iw zZZ5*nR34BM2T5v3x6|q&|7m;Vi~W{Gwe)##?_07igok7c`MFr^^XF#|c%$PRxcj?) z4X>n8B}vsFF@=Wc$Jum6j#ISLRNd0WBS~`Q22CdH#Ps@NL%|Z^Eonf8Wb&6iB&TKv zv(KRK184IFCeq^tcO4@n-j&Gy=(XI$|BEe{StAi>;k>UX-?mIe(z1B^pa2tv~ljwT7X z41blB)O1vm@`#4}hGB@5VHX+XxecMBeg7UXn4D}PnCBh7okjyqW1`%3t~cA7vQLyN z12k*c+XGIoo&>zZXd)3AS(_pmdU|Vcc&{?#7hpPF&QAEzzK^z{Pu=fJ=;4Uio$Rb&l7y|ao3QF;hWQ6IMHoMhcE?^!ho`PD9wFGtqrSlX{6)OVOpXq+Hz|I8Nr+vpU)f2SrGR9edhtM!}yrM*nPw!@_`|;rDyTp z|2*eOLv^ep^vb|txkGR}X(q#YgbnzO;xBQ(tfCMF&C#zS@W@|a--SelP$9?IxXVH* zVc6O^lT1 zz{x==mO@b(5pR(yvMXc}UQuh&EYXRLih_2%Kg){$kQbjm_MaT^cuu8xwXlr!q8Fbo zfYR6ir9gL##XB*pdcB_L$CF_vR@^X&j-#!EuU1-1i_un|?o*bGgkFLxUCDgBvZ{gcu|+TX zrNvqQI3b+K*^M20=NC}~RxdEJ z@;RpM3QqYo6Wym7YWJ|ABUnhw&Hs zk^g7-Ul*)Xu&k2SpgMUOJYB=Pa*qq&Z|*0tpnB6!EK?)ego`rIZhf^P7cFrNqY2^} ztRl({l9XdYZuzwOgZC`7zwLCOBz$p$&a_7Cb;e|7lsB08~bTx9>9Xb)Ag5?bV;-NvI) zG#lCE4O4A-?2za}Z2BB$sH+#))*C2!OK5tPVo{-`2q*zGuC_#WGtYe62QkexlpiCa z#f3C8QWjS{U;W6EPrhgqC248)S=Z->h0^H#R=LGQsjsiHzBcyT*KC@TCp8)2IR^1b z3ORa$;SUEFaaGUM;h2iP8qz)zYCj0$CtUSU#EqXQh(c(5LYOu}>G_l^{X|+n8G}`V zWZ|e{bC*(HU=Wj5Q~uQ8E+Uhmy8`Y942@`PRTf2>T=*lUL8(GZ6iI7vK`>2}aR)P~ zIAw^qp55*Eiyp^DzaJm?kY06>I&E@v{;gkOT-+WS!>DhId(M-x%;ccW6>Cig|6JV% zzZsVGEGpF^qs$ltcZ4C?j}92L^bJ$-Mxk`Y8E(6Xvtxs;TfNZ9zsN1Mc~Vsok&;#t zla@+BTVrm`?0l&7epPdIQ({;2e3jW0p`=#i&3Cv>bR|y<6LylSFt_jk8Ue;R0O9ju2uTEV748P!-OV-K%n1oFhM9LY>;z{82Bz52O znC5bc=H#jSj&Ql7blI2Ctlv~Dzu&$jqT~bdxwlEEixftD&r+O{T!N`aU4WDn7!{Z2 zt{Lorl<7N@<*snYPm_g}p_Gl5)|-jU!Hh+IGJ7@*4(;p=&CUOo%Dkn{g2YtN|$(?L)hf+ATvu}N~xT%{k7;q z-1|2fH&2H}g22V(!(xn-5)9Sp8p9HozJKj zXBZKNn{c^ls<55}8kt)oktH*z#2rlo{W~0lD<|6rm$BYy>E!-7lQxcKVa`<*{bmI} zltoD9cP00}g|#2xv&Ltcz{d>d1!i(sByt#LZ+KG|%u|;>d<*M+lDdh7(N*gtrhu}P zk`1GyRuRT49mlfY*fTLvV&~l8pO>L~BxFlfQd;KZh#H^#DEa7tfsTkJ)TiElychr1 zu`ZGbbHCpUgKyX=;R9;Y^1G{;;*ax;j9mTs=bbcOn!i+lty+3)b@TL!MJ>d znY)ZvH|tWcf;pwQLqe4rrwc^W48U#=AjA$N_Xwn231k+Ms}B-v{G}UT91lsNG7wQz zhWT4RfhUtQDx+$~8BqNr#6I8gE6 zd|8y%G>_8TsTEA?c@(`3RT(>V^Q6UMeH5_mCvn*gRwZfwH+8)c#(5>!D&Nyql}?sI zUcPx91#;~o$bDzNdlWJHCUPBPYGf#vzf*GF5;Z z%EF+w9$>THU~`@f=A~5}W;V$daN%nCbddh+FD4vpk9}8~f;MvP^o?x3Dx)(%NKV=6 z5R-RopmMPo^lb6jHBUyiyEMIE0zjy3%(<L(J;f#Q#A6>*HoH@XC3Ur|{L(Sif7dnzjMfq;LZzR>sTbzP(mGnWM zcmhp5M*Hjkj9`|D48UaeGar^na$1TlhK{|N4Ie){Xa`8iU6&s;Hi#CwJ2!$x4^cV$ z-CL8{Fzt43rA~aLM)zF$QX$RrjDeNIV3hf>a>I>5W1`w@~a>!qiE5_6vgQ=?a zN6xAJD={}>czaJ3!56~L9Qt&IQ~$KB2leOcJFzB2b7KMg^_0?cobNbyr6FvtT-M6@ zlW+m;`(f?IVJzY(C2>Dt=0k~#7K8>5{057AAmBD%fol(BnJyyMZGwy&N2#TTc*G%B z;c03ZX==cha+Cl6xF@MB85mEqJ2X2Vsaq#Wa3ps%f&FQNC4zy4`Th^()B9{ z(t}Tmju=-kqi!H=He))8>D|W3@|EBs!qqnK-G}lRow9%$bC5n}%lbc3C$7QObmS4Y z5*ll1(c?US<)a~?OD>aS07sqD;QjZ(W~0FclH;G_zkZHEyrOwOQQTt>xt@x(Tq4=8 z5ayK13!fEfwp(9GiDyr>c%%4HB?(4ldg=--8fY%ZR(v{ou%^<3bah)U}{< zXBdoi)c9yYS89^&YIbf6+YYa*(4B7#8qRF^QOS&E7VWA#s9%mK0o7sRNAs*_%()D~RvJq)lP4;RBrYm-gMna= z1XHaJ=h0zqcwtfGP$egM1^CF%wBxC$Hs^aXET23OytD!1|kb@<^2g}_8Rlya!tW3Spa;?xto=0D9;5;}< zh-M+@3cxJd-qopk#uqtISynA3v0E=k*e0wIQ;b*vYPM-xyr#74!2u2s{LGM2*N|%U zP)327q;d4bSmZS1LZitJd&ibywHn2brLh;1xTK8G`=o`sHovd1)^k{-i_uq`#>l+} zE0U3x_zuHTIN_l;^Wu2Z;tZGwxzo1j{K{P3OD0`M_L8sE65mh$D>*O!kE#<+qVhCv zWeMLivyQUu-Cg66gU)qKmB}#lFNfYcKCW~dUhhVM;;%dx|1%=!&vbBr=fhR>)%tgs zhs*GbRl@mh{tjzzmoj;iFpe@c-YzZH^t$hgHAgzN2h&Ne(d)p&UUhZXP0EOeM5pQ> z^J{W@)+USp!xH;(n)~q&{+o9H$Nfk)2G3I^YJEx6O5--%Z7;t(Dq&`bwG;d3>a!&3 zLK45A_+PQqi%n&)ZEm~DNl*9^@rMhs|BKLJyOC;E@O)E@x)z!`-}&$<9<`CC<~n+) z0F9qwemhvs%7^Cz9L6SsrNonkgsZiLo28hWl_L+^;CgFFs|6%yCCoyVfM>yNyKX;& z&Wrj$Y8A;@Ox^o)(n@B`o;9eg7Cj9}LC>t!Ersv1l(q6da=jo{iy-dNB#d~M_yuAK za;L zYKi04DEeR&|3ljxplz99JQKkakrQzfDGy}0d_SGWz?<(wp=Dn~q-#x0SUV*sD1eQoSj^5G|l0~FJ~2VeP{vrl2Yh}Tzv2A zi{<@(Ik;E|SUmPaWT2sO^g0aUF@0Mn?|x2UQz75 z`vYt1NM{VMPAozz?9FA?e{)7ba~6ta=YMlvJF>sfpTC?}Ky>^8QO@vWP@s!rYWRUhiw{fh>5v1yOSH@`WWaF);=Ezgi_aj4dLM z)$_Fq{gqTyRMgbe#)gH#{vT?^d4R-lx%u#|#FHH>je0gXVC~QTXvx`D9&ZOdLE>p^t%zQ>Wo7eyLc-GjgbYx17AvQfLm&fy9W3?!)hRM^z9P0;zTjEPc2hy4Uo|#Gh z*bcPf(eiQ<(fh@W|G=Y4MvQ-16v-dI@Pu8JW>Ut`SO|9Bud%RloLPhxVL)0#gUA2F zH#-@0?pF{v8X7jZ2qLazJ>EN~|1AdGJXMS9 z?v|u*I``W~@@>mos_t?4;QQdx#M1c#q9!wT01OTJL{GtJ@BI0Lno0VCVUc>Q>*DHK z5Yc1uAIh%(UoS(>45x`|<^UKU(8Mx!0vvte+<#baOYjsEIMLeu9b$=@0!ML}{Z{x> ze`|gce;YB^o%YEHm}za3C}Wdoz+-DQ zZ9lbjiCb~+dEUMKlZXK!#atn;!_I!D1G_0|7A9o~bi4_O4*C=KQ)Q?=+#@63V0d^B zOkk+@e|3LO2mpIP(m|;uP`a*7##xk-xBSfX%k6C~q~m0c?xYAP zajTt?-nnzx@NtmzcQP_(lW;JO4>eRpVoIRV{qDgW707RyQM||8<3E26;1l?+qrIDx zX=G_`?L7bSre-}+wUkCso73{!XKd@SF^B>FS;>%xv#7D7rR=Hd3AE$x-24~%^C_;^ z7!B#=Ebk+nzrnO@IF*&1a)SV!g9Q@D5V`R`s&m6+gn)h--jD?RLWzwv+w0Jfd|N&r396oAH8C;BNU0PbM({t{!Gxc8_-}=#EVs8A`WxoGT$wObs)cGus zirdaHnS;r!K@>|RKBeFZgmHMttZ|nRbBIKn5p#~kWNd6H^cJ-`u(Er=q8sh#3pgsb zupKdtaoqchZtz68o##YV{9 zL9id1sz%p0D8iBzwnxaGGBuD5cVHJqF_1-`;t`RTZu;B~&ED;b_!Di{_tm$D|7n+$ z7nb$#aWPc&(DaGEGp>t5A>@~oW-32qa?6d5cEJ<_^?n}Ctn4vhm1`A7k&L)!+u37o zM~@`*#1W~?P`|&wG4qDvaJpie@_D>Je>JU3g($jt#W`6jB`8l#ZJ41qd;1)O5Q^M~ ze&ESBGO8o^);wLBYpC)-IbVtmZ^1>mz{7=IhB|JL7H*IhWe<{G&jHBa++f|pJJHb+ z)U^FGq-8bhxLQCFVF{W3I zUg@-^?V0p?BNUQ-P4;;&V`oQF5XD2&4fmbFhp_1p!H#Ss&hgr@>q&8vqJ=0>{ymQl zKm7&XUt+V@7USU@nvzqlYHBME{Zv>PI5w6_h{ZkwBK+3WLmH~J?8jYA!&$BCijFCP z+U(Utcm>A_a{T_ju7@~fTHRLBRuX8CxT2KB$vziS8E50u#yHGZTO1vIX=+2yjr|s- zi9M*9=-RNo1{&_DvYOY+a@xRaBwD&7yuN$m($~m>58Ceae*Zdg{3Uj`g!ol*gWDtM zNbD*w;(lNyc7@X!z?SgXIGWgpfPyhJP>r+>PlU7#X>LB`>E$KuE=J&8?Bu#k!^ z2(|vVdmSbNa#sA#T7R^T^L^lzIdc3XsWRM0EAWipIZE?yy)9NDMTIYyoENdf! zZBY6$mT_$B_(Hacysw&(ajt|~qO)zLjQ8$f0qy5*X5a2w{+3g3KxIDK^x$8)+KUd6pRgVVKyD-O-UiWxSA#|`B?pArs1V1Lq1 zP}1}DBaqR|3>YYY>se7-sjR9Q{%PX@5qptBm*&^=^CA>Q{&5Nh{z+G_+{;--B^%$l z%I-<`KX0-mAC3)i+V#c%@VDjP+{9vvmw6+Mi5{DvmiUkNaRB^BHWLmFhc!$~%gVQW zFNt?0d7s`XivYbv1PM1!9zBJ-hI1xY%Ojq9wP)AVXAV=IHuFvTea%$Ukoh{X)WTBr z<~ zU1-DWs}!8A_PKA+>&*UXFD$DvHZXmS*9I~MImgfEmj_{bBj)=*$~UQrL<4$83rA&+ z4#%zuD31FhYILGZ{p&|ztW5^=hk4eVvZF2yszVr-L8-kxnsS6xg2%Fs>88rZzCOy; z%ty#fI}0J`KUzoPQbjeZXz8dYWR@s&X^;f}UU_|2X!^kiSK5*L{LH+L1n1INNJ`cq z`3)_O!B6@ss^HgVx?Z%WCrf35aYp_W-jI4%)ND+2{{*W2s;2%gk|6)@2wwxfS&&r~ zNl0CDkEV*6U+PuE^D7MAsr7Xu>ETw>we#Eg>!K7gdxN@s+M_j%9X*2JmH&KuQFqKP zZ#*+P7A{(#mvk%P!O4J z=u@FReW*01+$ctNWm;20r_@>L2&BDY{u?_wD!d=mL(Y7P*y&HXH%l?u4&kCyoO9+2 zabcmgoYiTSWWO-HiUE~#+is<(t~{C@I{tSCpsM>YL*)0iOXTJKgz*D|-a@3Sn!b8J z(scA%^}CA3bHymDG$My>b+w`MB;#-wpO&x>er;esWv=R;(LkjCK2%T|U=;^1k7!b| zKf9&gw0(tTt5cz8If_eIe+BbN$D7>c6YaoE8`n+XrFK_I?{HxV(j?qB?!&(_t>K0} z@S*N%4OIS<#fel;c?0E$pZ~l2%;=^xQz|;@!Ik?%H{r{6xU9T(vJW zAUArK1pNd(G#>X|P<pJxXy#a^x*#dZY(ac*>B zaY#7GjewQus><{iGMIS(YDz~Ga&6r&p`b&SS~lwJE?pd5KYw@Oju@RViE4|-`&HBc zWjl*~D}hf$0=2!468_s~gO6R0#&(U%)BN1ro?oSe&9=xVm=xPB7a0TDJFX@zB{T!) z`q4T=+&j&f!>0io|7ZJkA!yJ*4XMXrVfL^JX=OI@j4W+seURXoGa-d;Z0yLal)23i z2JV0x^9S@RQiyxjK1FOAPKX&~ga%Q0die)1TB+!M+2?juRIvNkHF49Q3~{13!90hS zhKv3=%&LLHy<(&ssj&(cv1;80U|AUz$0eE7#Q0>e-kyCSkP9+)!q+j@YF^wugrMFE ztTT#GLf|G`ylV(2mNE;HCas)ST{)Pvus6LA8-ffSeV*pSzQ^=_x*cwq$)8%S67!wWM8VUM-rXx<^4*JZDIr*JZ(0?KOas&HpNZ7tVh{(brgr84_uThC1=^{pO-M-Fw|!6Q-_vF6wwfK+4y1;~L-Cfl;c~-AmEq(uVXL|1 zF~2x@+iAKgQUn>^zuZ)&a3RL2WGmuus14z(^iWM(k`4e}@wbMGn0frU=%TdLQc?ya z#3#$|jnN}zG#Z95_aIe^kFv)DX;ySsqRsyZu1y$+j!;0Ru~ z^LR%~Yg@5kaDwlXy$jAr`|05Yg^HjZJ(3h@rGU7Q%?<8nxqR!|X@jvR(Meb^uX_x9 z>5-zyK_NAx@K6?Qa}3;@y16(h)ZjJR;U}zpR$y>$)7>(UceCx^6-yMnif+U9o)1kr z>-98!Tt5GgHxiLhX3YH{OZqvJH)5!5=V0xDm(s3C$3QZ!ep*$)K_zp6@xxFsWY(%W z?2zFdlL{pLr*UCXQBk3yk}ub@$-O2{zGgJ>kOrXVOWvM$SkqZ;*RJ+*2oq2AwziWs zX1sn4emBZto^FroSF7?F0(Y8*@v`5o1wQanDZhsj_cwc|aVDx%698$+qj%QHCLI#4 zh1U=YNS$Oyw{O&k*9+> zu!uv(VxHV{pW(0BOSNh*0JuO!8PEb%+1Xq|C_!mYXsLmM@9YhVN?C@M_G*{4k*zK3 z$k)ZhKYtW;baX^SM6~EbrSMxLjGC~kt9E^1X}*_gjJ`C1cvY{dA?Y;(P24eZ5RrDP zuyr6sw~%Iku-uFTXOKErQhtGIV3+nNB;gHJ zcJwmN(|S zDl51P>&K|)%?SAk$;n^?k2PrBzTO9JzcO&62N?X}bJ{x;TI*!fZzeE#YaMf8y|Xks zif1kb#@9>Dn?d9AlKf{+Nn}b2MoL5(utF`O2n8`S`}tLE>LrTKW#rYO)3ZI7-R zXn%Y2k<>IbHTCg%OTrU}4J3ZaiZuF2&q_=4IfVBa^6FaH+VZn2w+X)Z6m&^IwQhAVr8ey}I$1rv70M!6i441i=O> z3W0|1um)WvW&wbh7`c@iMz+%8Qr+lYY(ht#S8a7!Sr-cnNmo~PgJ|j>WU#_&nCP1Z zh?aH1LqnBT`25vCWRCDzzAnDEH(!O&9KIcYVsbV}UWRAj(9OCs$c~=6|0?XOqvC3syd#7F!DS#g0TO~{ za3{Eg;O-0#fk1E@g3BPmodgfg;1VRj;O_43?($up?|FC6p0nrdU$>{Fy1S~n>eqE^ zW;{HcXlZCFs;VIJiS#p!AKomicz@+;XUw%zIEv4C`&t#QQJZ5Y=-@SB0xSCBwXG@CgpHQNxyK+4A0F8 zw0woCH>&mc8&(su-uKMs9~gm`Ag>aP7bR#Pr%*!3z|a(cX$lGoUU3r}aJG&j5LdTX zC-1@TC1hmtn!oMj^R?Z_)+Y9uRaHV)su321P}{k9eUWurgD3RJz8@Z`NIg0OTNPPP zN<%0Vs+=RI*Wkv1dsXxOd2Q+N@}EB+8r+o{&PjcbVHA$ebIOW{)w`<8y%wxAK9W~L zs=e%RrNqcIW?=nK3KBHjFTkFyV#k3L&;)*ysD=gsn%(ognU+sesPE83^(+R4>y$t2 zUi*t<9V|rRAPJu`5VY=x^u)7tw70vtxwVAlb{I;_?hms-^=*~PnXGLk?-v6qm;ea| zL9-z>Pw8lBv$L|0a07nHraQ{7XLrt079~wi6wpZj+eKGbcM>1;`gK>;E(21>lVUfj~S0{?s zQV6Gmc~AOXl`pcp!VjXkEiDv6Zllw~N?J-H7uNu-PXxZU@C>T=z41X=5Rb*sODkt* z;96rNXXD_2?nS~xc>(sJ+-5UL6A({y1uq<`MaB@#d}N@w70K+FDh!OyJ{?Hf4G`aG& zVg-XLk2?xAld6+}x0#cgj{)Ym7)k^pMvGuedDBd`&VAfPtVzX0jRIGZ_3#3>7lr() z`#FO4%^pWPk1(sbha!i#5PCbQ7`WE6y|Ys~yYUSb+n?ChhW6CM{{)hrBO^2$z%f&uSeU&R@g9lmyg4 z^94kHFap3|SlzAJOzP!(PBcLD5a& z>+pQ%$Gf>BWwk)b7dfV^JmY*kWEkAIwyTE$j&j{@`8cq2A14CUP@#<5%=zDufWD8a zf^&3feL{lwS=5~Du6$J*a>{)N$Wpqu+VwNV@Y|y{fn50W;o#V9tGtKPXo&R%hbim<(j3Nk4sLu=u>>QiU=+ypR$$83BXqL9oNoXOd19AGjcM zY2R|cFs8o#I~_uokhFA-Mf0b0@p9KQzI0d;8ExwKMUj~is;Wj(+cG5pPXT$Bkz2)R zSk9JN;IZn{=M#B}UEOP7G>5$FV?Y%lCBU;gfSS2mx4Nd*t4m0W=t~JyYv!<4guy6L z&Qur)#l_;=a#kX2scJC{f#>dZCdoB?k$hP4atNS7bo|j9K)r?;F%e`{AI$#p&|AK3M5Z|3`}y4n)@M8;J~-Z& z2|3bagO0aEEN~2>P(sjiPJ?sZLe?NMbkq1Js84Z`kwkD|NY4zVDJciptA*^@oXrXJ z+1J}a(HDu%?D1B1hq-3+?)yAVqS*U3;Qb-o^0@@!4j=h)*KU3Rqr_Abz~3TOC&=V| zMCE450Tb=K%%N>qUlw$ixX{V8JWY-zn3?r4gy1qv3`H*Sp$lWTwKKNYeWI;F40;7; z`)&|#gpW-MF;sggSt>i7GCFnMW5mU)$Hl3s#U1Hbz%@+sH~`sF!nzbiiU>u2sxnZV z7NzoO*a#_D&O{58Dd;yX+ZHzK<0cO3;BC_>wR*L_penInAjqcS(gnX$-E5guCI=JN!s^-qn)v;~Xr=zjAd%4f+ixGge zJvx6iGc#PpS%b|3le*+}ZTafEq(8ap*P(hEqA|99u+f2y1ea!dYtTrD0saweg<#89$K^C1)^#lDUc-h8o8ba3}E^?dFDOJSc>!6K370 z;g#;L#dI?{Ni=|xa3v!xbFBxX+AH{7id_U+-#QGw0SGSZ6^&1f8OnuGp+NAo3h`)x z&1qG&wJQ#gT1mr_tQyz%^QlT|Ysbp8!~V$Ia$_U0*=3}V@?S5BKPhYFel5(-F{bLG z(zZ)t9Qa7@_~={$|BX!xgqu4YAUUE@7|j%+C;sknvkuZnv6cf4(c>T5IrSALPbq#@ zX`AjkC0BkbX6n_iF5gk3KUxiPz0QT+B&W^@%xGy(-8gUW45?BDJjBN9w|IbPD*qmq zC`qFtxADpR$!l|e{>V(oziP9W>Bll$fS-1BH_TkwXPTN^K4r!`bkUNQvCGVoqmO2QGt62xa234%sDdSmjkMGc0-}T4yKO$o z-@lOa|E}a@AKh3BW@Q_(>*i8o2H1|`Tt$>KaHC#ZFSFn|`eXvoHNR5Oj-tb_@oFNV z%%_RI4C%>~ocG4kn);RuRRSO2p*^#+y2P8krV9Ib4o0wX-xg{ATc%e>H*B zHesJx)*^1#G=LIiIh_&N4o+K&*x#xTE85x)AzCZ?U;?Js(Zros#UG|^%%b}ErHJbMl5rln-;RE_zQ5ewr&S{|;2Q z54|A<2R8~t6!i`Ii+_}V@|sfMPG8^|%#dA)M)(T^h8oMlIW&>ggh!%Fila^(t?)Wt zC-sL`a*SGXidwSYj$g>+kM9^xdm|so5MHB%Bn1wVW@vfBhbzeS{>=2W zmEy9k-6!Ef8s5fRHyOu_8d{3`5SDtVC~mCs&qSR>TOO`e8;e7Y1M3O@XQlEeM|>!l ztrqiKD=UW__nc_&r*I4nHP#|#!ANmOG%-9Ep0h8U_+Gq7>ChKjg6t_SO(iCFwl~*3 zT+H8fEG|-tVz(KUY4FMX_JA9@j(yZT42#-4c9NC>ej!5CNln)+EQ7UxnW;n(-;v=@ zMkaeD{d*d|()vX|InA{?L~~^j%C3J~dfeOSt=3e&@yf}wgiS1`FI+_Eo%pZN&=;lY zR$e2Kw^49-j|maKChrHnuR}Cx819*=IPpec!7G9aWjRu-FqJ97#`T{ic%PTuA7i`F zH=eeS-41qUlzvNGb(6-wE;*f!3G!hO|9nMjUHxoipu60YeXm+4g>dB=Q>lG&gTz63 zF=F0jPc;n`{E2RbV)aa@sq8#r`Jvgn{My8HeF&1@0}CKlWiXRYkYF#qbhGt$*xK%mrtE(MlrF8@N=@YF@|{XiNC(I zob0MRUF*>sm)Nb_n2_Ag@AhU>&M`I35yoI2TP|3af=JQa1VhN$RN&|`3x?G4HQajU2c}psFOo2~rffIJ z3~YFeNJ(VZZvU*D8d7YxLbF0laWGBrZRr^%atEtAX-37@2tvT39({yWeo_=!gYmHO z8jgmCS5|bjhrVs+u%)Rvd4s<3=flQG6A-V`o2w&WIJ@)kgs=O)L+N#8zZcfh*0Ocs zt{0$Gr-1-Wnguj}@_5rSKEtn@(B4!kcOrC?WX4#O+KsR}=HPHPph3{BA+5eOny||0 z)zChcP_vrM?G8Ls(#O}w#iuz%5;#+cjeEbaqfLx3JiL1-6yRaR%p-?V5J;Vb_U)GC z5poI06?HkBiO^YYUjtRb=5m_zPmQ-NCj+y)td@DS4cyI47lIhyH z=yxokPEQ#rRbwGDa4@t*qDH~;BoR3 zJVKLSpgzZVFtmA^^Zw+x8|}Fcas)i#?Mm0Hl|sKPG=9!Hmzu~EbADf2kDI;fGe<`k z*KR-p2~3>mc5sB|m&_|jKYBzzCms3`?REi=^}Tf2$@@K3rBut#-olQi^ZmaC((E$a z(<|RL#bu+9R{ibNWTfRJu!&e(Y&$!FVBAI^)``YH!twai5E&bkTsrw_KnOrbOXDEC zpp@>vg`if7e)ju)8*iK6)zE4|5weYj zr+tZVp1)_9FFyYNbY*C1%|{NgL%3qOJ^ZLpTEZCLT8W}IIxSf0|FN^WEOglmeHT?Q^qDukDeWZ&`m^-3M1nuPZ-% zR%5}U7$-Ea&4QjOv_BX1pv%iZrV*n zRlrv#?y$2enjRk2BXEx1RO63o!5|No@Fk82$tg2dTxI=5NpH!yen__(WySr1$Bh3e z?Nc%$8ziy*C0y)Kv}cAy0iu`$_-bu^b>Q>+M7{c1GV^zXQ^ZjR>iUiiPzw}^7O7+lrY`UKueuY=FBe?pI|1Fqd9-VF(MypAoU38I(-&^@6q0?OBWVA|{T)l(|a zHKCjJkEv2OOO>%^=QeG~%*1vbz44hOSK33*>S!1L!=6TLNCl{a2G_Vhub?264wUH^ zj+Fi!M4}G`YkZlmuwZHAwjPI2N0-V)|KOZKS^L`GpO{p1VUwMBc3UT?AdgNIB}zZEeDZW_MBi=8 z#IrSQec7h`5cA|PT-Dp#Eiqb8YOp+BTZ6#k&`0*`xAE1sg5YTl^d8n9D!$gDs*@X& zneCR*Cg!#uN8MW|3i+DZk1H?*EEC+9%yxISg9Fm@~w44s7kNva)iV z!n$RS?i$C1>|TH3R_T=eJ0&y-!5mA4)XRbldrd^to5Ew2H-woS?aBGhW-6t|+Wq)^ zT-n)4Vqpqru3n&SKzh97j*)x4=tDjGbg4hE0f+BY=<4dh9gr1SRn8N6wzR#DTp2l; z7Hq7XcDuHo%MJ+O{$0WmxG~s-B!DmJ0VZP7C^b0Wonqkh_(JG7u|Jw>9oZ1Hr|5Y; zE+1)cr1uB$W6vCRwD#!cK>%?<|a`MjWy6m;J#!KHaN=MI1yOL}3h9^83Dn_;9UJVLp_?Q&Plw z_r=PXBEY~&LBseU+z>W5=Xkx}0lu5xx^U(6wdaETp7K6}EUSi%)jAnlHux zdu``%sptSPhrsSa{@HIp?o*fLu2c{K2*Ms%%g@h-*a>xdO`PfZzKlrN+z_tB3EV)d zoG3urWyW1QB~6X(5EdZ6i@Iv$SX8vt z5T?1$M(C_5Hmf3(vwJHwY~qN|b~nfQ&h3xVK_n2_1QdsonbWVD$Ywu|S@*h|q2$lq zl1<^9KE-SmRaPHOg{P5upoK=D=H=&CcDZIUESf-+=t#RTzfhy3?hig-;}2CZPj(>i z$*C#CoKOo(&g6wdy1aw;!Pc`THh*t;cKR@yw9;o&3+fw`M;t~J4P*wHWWTkt2I99U zbLASUd4opaT;+J#hHtV0_PyBTgjgy027sl88pC2K{mK%Co?2+^f86w+KZJQk-99y% za3Ja%Wf+)c_V9vvDesg4)HnRFGSbsd{@6_@1F9e)t4T_euwRc`zg(sMY} ztOePn^mMHiU_;{^A8(wWp9~0FJD|gDv@T#Wp`bxo_5y-Q1>YtiCbTH&jGXpsoSB~B z>viF;8sx66tS(jXjSa)s;`!;%)_ill&kZzZTBDK|Ow<_?BR^K9q^GBwxw{NQ|7z+S zW*sd{PrOjCtK&BMi5J)ZlN%aZ-}t8xJ+^r&`{79GJpgQ&HA5ZMO=Y5*LFKl=dArwU zdM9^2al&Ga$HHoN4TGU^tzCWIU46nRj?^@|uam}Vq4lrWaO2iZCxd*&N_4Q~r&+A` z>8?f`4Hq&}i~6iNIFq^TCyXBOI9pro=5%$#F);yjS7!$A#x3fA-2TNoZ7z72eAxHa)@i<_y{gabDxvn+x)_}`YKZ?eM> zmm`i;*bZxHs~Kj&XPXSOloobbvl#x$zt+87X>rdT}( z6l;(PMo>;wijdXCdp@G&iAMkpMx!{VQ!dSIG%v^SleMGCJZast={@{Trf(FBM~EqP5YV2v2_TQsqsIKgwLwb8d4YFxoHOv$zP1LwQmqlbE>M3&uPAWEmx z4$0dSWTkD<&pC~L|9n(ZpLEE#-7CD$`?aoDC5bB|vXwz15eW8IvXeEa%Q3A&KgqSe zMwy8TS+|axXSw!WNS2sipdHWsfLWH&Y2eLg{yZ@bYyck2RS=CIQ2UilmPKTabDI`9 zNtqeNie3}5Pp)`%XiezcIo7`>d;a?Mf^JnP!14_yAU*=HsE}XznbP!!(c@^2n}P^) zA@}W*3O2e1`xQByOcKg24sv}bM<)nvV09-92uF!%%7%Z8rv%x<=y7R(&#vH;n-SR9 zp>1&c*A<0x`+rJl;Rv_p3O3$*WA`kR#GoBxs@P6)YuClLW)Vdg8?PDijT5O#1KMR0 z@qK0gz60}0M#qzec^*ejZz(*@Fgz{Yd=WqO5{J3j#FcjJ@ouI7%De@_&p!Y=M%f7z zu!VXdw8#0lfYrpt>jf?yByN*9deXqlO-ROL#OOJQLFBP>f;or*BB~8LdRd(t=;PzF z+yTR3k}v`c(pz-E%TPk2Kn%?JjBjB$NZ`Lfs3^}Dxbn7%RcnabQTaR;+scUA5XgWj zM0uR5O@0I-pT-Y8U8J~}zE;h?V?toLCsSa|-P|8FJw~(0swSfk0625H*l!@O`*p>? zKc8*y*ubPQ;>|?vlF!!_1U1tdIMtEIna?s1*+$@g9|yqCU_DsZD;%q3f4Iiij77W2h7vDJ{6&Zy>II83UQ(n+)!fT(|B)x&D)nr zrLE$1KUk@o!c_!PWhV~7RdUke}vCc#9ZZl)qbLd0ALq{$PqJH}Wq4tiBiuqBScE);dJ5v)Q zZ+fy{mgEAdjLw0b#aXUnrZ3fK>p)`r-RRXasO+)V9+%l2Hxp|cX$(o_aCi^Kg0Ny| z7|A#n2M7Fa&BWw4PO#i9ogTeO$*PayNWM~f+**q(^1m?iS%a3A>_a6FT|ibgM(wlp zOQtGF4)+@m|8%N+ZC+CD!^0)feaNYiN8k|-zN_q;zb}26S=3d*mcK|Mb32x~7Q}ve zkF*CMqepVr{_dxf*>PaBtkPbO}kpeETiqmsnUP5bP#=Nfx1slNV#VU={w zfm#0tvjrYoOfwgu8~y>!bRd4fn0R=wYDN%+4W$r(qxxa&qRG26q$lAeUb(X)m15wg>0xokx_FL(tGx z4LqIB8{DbGs*vfBcW~|o7Y)EqhDgcXq4rT6ijnT!-L_yFZj?sQb2ol+bhQ+bBlXUn zF)U2XZU*}DptbkYuZ7yQ^dsc%(s}=wX)u9?1{Tr^8e5Y&zhHMO>wTbl2u6%1lkyDC zjB4SGolB>j*qT@sHQpE;S65x!B$dzQFclFD^+lrE zPK{LLrf%&w6Gs;pN%#6r2`~;Z{b!=@CEH0qJjHk)6R09E^)h^?Nuw(DoA+im7qh$Z zLk#YMJPnLvHC5sQxnJdoYJ^y~?Mjg!>G{lJF96bE#Zd!9(^yK>Mw=ADjMP3pF2O&?aBN6{99pzc8OI(vKmvb1E?Squ5AWi%lrqK(b z4@Iihw^zo?NDB@|^*~%$!in~!jkPll9Ju3NFbh)#Jp19Miyq7r=e<3-%=KJM;q8zC zxRMSv{l}1k_3vU4Dca)B_v}8ZRDol-u=h4byLHa_=Lh~qU4EAeNJC2}=TBX8=f?9i z8F}8LIrW_!gNU2yvm>?O}_L z2a{w*FsinKNDEuLqDu>FDQBBQU7J`K=;n8YidrG|;;+HCJ%+Gnpp33(i7ogM-ty2z zb6gy}mYS$k1YLAq@0>y`Eqb1*6OFNZK*!sB0I2kq1b!g`uID(r%S#WrC13w65o z6@ENemYK(rQEg-Rt@4yZIScsM#Ag~G+1gA;piqtUL9i!`eGxk0B!RU~wnTmYngY?*?CtjhjE`Z3vo2G#}u-vmnla#hkrMc$o+p%@3vNGNy?FwAs)61N`HpzPh-?6EhJch^*23-!z{5r}ZDw&1wHV9Ows32DCGp z0&|Vpkdc58AS5}rNkAU7~3>sT)rVfA?+#Ui)4p@-GOG z+4Tzol>e!4&i$_ z#jc-L|EW5ovr61fhiG?xi(HdqW3zIqZK?9xBVc2@DalJn)HTzm*La~ + + + + +]> + + + +The &ksysguard; Handbook + + + +&Chris.Schlaeger;&Chris.Schlaeger.mail; + + + +&John.Tapsell; &John.Tapsell.mail; + + + + +&Chris.Schlaeger;&Chris.Schlaeger.mail; + + + + +&Tobias.Koenig;&Tobias.Koenig.mail; + + + + + + + +2000 +&Chris.Schlaeger; + + +&FDLNotice; + +2010-10-24 +&kde; 4.5 + +&ksysguard; is a network enabled task and system monitor +application. + + +KDE +KSysGuard +process monitor +performance monitor +system monitor +top +ps + + + + +Introduction + +&ksysguard; is the &kde; Task and Performance Monitor. + + +It features +a client/server architecture that allows monitoring of local as well as remote +hosts. The graphical front end uses so-called sensors to retrieve the +information it displays. A sensor can return simple values or more complex +information like tables. For each type of information, one or more displays are +provided. Displays are organized in worksheets that can be saved and loaded +independently from each other. So, &ksysguard; is not only a simple task manager +but also a very powerful tool to control large server farms. + + + + +Using &ksysguard; + + +Getting started + +&ksysguard; can be started from the application launcher menu, using the entry +System Monitor in the +ApplicationsSystem menu. Alternatively, you +can start it by typing ksysguard in a terminal. + +The &ksysguard; main window consists of a menu bar, an optional tool bar +and status bar, and the work space. Custom worksheets will also show the sensor +browser. + + + +By default &ksysguard; shows two worksheets: Process Table +and System Load. The Process Table +lists the running processes and lets the user control them. +Multiple processes can be selected and controlled at once. +The System Load worksheet shows graphs of system utilization: +CPU History, Memory and Swap History, +and the Network History. + + +This default setup is sufficient enough for an inexperienced user to do +some system management. An experienced user or even a system administrator of a +large computer lab has different needs. To address a wide range of users, +&ksysguard; +is highly flexible. + + + +Process Table + +The Process Table gives you a list of processes on your +system. The list can be sorted by each column. Just press the left +mouse button at the head of the column. + +Use the What's This help for the columns titles +to get additional information about the value displayed here. + +In the context menu of a process in the list view you find additional actions +like changing the priority, sending signals to the process, switching to the +application window, showing detailed memory information and killing the process. + +The list shows the following information about each process. Please note +that not all properties are available on every operating system. + + +Default Columns in the Process Table + + + +Name +The name of the executable that started the process + + +Username +The user who owns this process + + +CPU % +The current total CPU usage of the process, divided by the number of +processor cores in the machine + + +Memory +This is the amount of real physical memory that this process is using by +itself, and approximates the Private memory usage of the process. +It does not include any swapped out memory, nor the code size of its shared +libraries. +This is often the most useful figure to judge the memory use +of a program. + + +Shared Mem +This is approximately the amount of real physical memory that this +process's shared libraries are using. This memory is shared among all +processes that use this library + + + +
    + + +Additional Columns in the Process Table + + + +PID +The unique Process ID that identifies this process + + +TTY +The controlling terminal on which this process is running + + +Niceness +The priority with which this process is being run. For the normal scheduler, +this ranges from 19 (very nice, least priority) to -19 (top priority) + + +CPU Time +The total user and system time that this process has been running for, +displayed as minutes:seconds + + +IO Read +The number of bytes read. The Display Units +and the Displayed Information can be changed using +the context menu of this column header + + +IO Write +The number of bytes written. The Display Units +and the Displayed Information can be changed using +the context menu of this column header + + +Virtual Size +This is the amount of virtual memory space that the process is using, +included shared libraries, graphics memory, files on disk, and so on. This +number is almost meaningless. Use the context menu to select the +Display Units + + +Command +The command with which this process was launched + + + +
    + +At the top of the table you find three controls which will be described now +from left to right. + + +End Processes + +If you have selected one or more processes you can press the End +Process button to kill them. A so called SIGKILL +is sent to the processes which causes them to terminate immediately. +If these applications still have unsaved data this data +will be lost. So use this button with care. + + + +Filter Bar + +Filter which processes are shown by the text given here. The text can be a +partial string match of the Name, Command +or Window Title of the process. +It can also be a Username or a Process ID number. + + + + +Process Filter + +The Process Filter can be used to reduce the number of processes displayed +in the table. You can filter out processes you are not interested in. Currently +you can display All Processes in a flat or tree view, System +Processes only, User Processes only, your +Own Processes only or Programs Only. + +The tree view has been designed to show the relationships between the +running processes. A process that is started by another process is called the +child of that process. A tree is an elegant way to show this parent-child +relationship. The init process is the ancestor of all +processes. + +If you are not interested in the children of a particular process you can +click on the little box to the left of the parent and the subtree will +collapse. Another click on that box will unfold the subtree again. + +You can launch the Process Table from &krunner; +using the Show System Activities button or using +the global shortcut &Ctrl;&Esc; at any time. +The process table is displayed in a window titled System Activities. + + + +
    + + +Work Space + +The work space is organized as worksheets. Select +New Tab... from the File menu to create a +new worksheet. A dialog will appear where you can set the name, the +dimension and the update interval of the worksheet. To remove a worksheet +again, select +Close Tab from the File menu. Any +modifications will be saved to the worksheet file. If a worksheet has +never been saved, you will be asked for a file name. Worksheets consist of +cells +organized as a grid. + +Each cell can be filled with a display for one or more sensors. You can +fill a cell by dragging a sensor from the sensor browser and dropping it over +the cell. If there is more than one type of display available for that type +of sensor, a popup menu will appear. You can then select which display you +prefer to use. Certain types of displays can display more than one sensor. Add more +sensors to a display by dragging them over from the sensor browser and dropping +them over the already existing display. + +Worksheets can be configured by clicking Tab Properties +at the View menu. In the appearing dialog +you can set the dimension and the update interval. + + +Displays can be configured by clicking with the right mouse button on +them. A popup menu appear where you can select whether you want to change the +properties of that display or remove it from the worksheet. + + +Sensor Browser +The sensor browser exposes &ksysguard;'s advanced functionality. To +use it, you must first go to the File menu and create a new worksheet. +It is shown whenever a custom worksheet is selected. +The sensor browser displays the registered hosts and their sensors in a +tree form. Click on the tree handles to open or close a branch. Each sensor +monitors a certain system value. +After you have configured your custom worksheet use the splitter and move +it to the right edge of the window to hide the sensor browser. +If the sensor browser does not appear on a custom worksheet, it is +probably hidden. To unhide it, select the right edge of the window and +drag it to the left. + + + +Line Graph + +The line graph prints samples of one or more sensors over time. If, +several sensors are displayed, the values are piled in different colors. If +the display is large enough a grid will be displayed to show the range of the +plotted samples. By default, the automatic range mode is active so the minimum +and maximum values will be set automatically. Sometimes you want fixed +minimum and maximum values. In that case, you can deactivate automatic range +mode and set the values in the properties dialog. + + + +Digital Display + +The multimeter displays the sensor values as a digital meter. In the +properties dialog you can specify a lower and upper limit. If the range +is exceeded, the display is colored in the alarm color. + + + +Bar Graph + +The bar graph displays the sensor values as dancing bars. In the +properties dialog you can specify minimum and maximum values of range and +a lower and upper limit. If the range is exceeded, the display is +colored in the alarm color. + + + +Log to a File + +The sensor logger does not display any values, but logs them in +a file with additional date and time information. For each sensor +you can specify a lower and upper limit in the properties dialog. +If the range is exceeded, the entry of the sensor table is colored in +the alarm color. + + + +Partition Table + +The Partition Usage has a special table +sensor showing information about all mounted partitions + + + +Connecting to other hosts + +To connect to a new host use Monitor Remote Machine... +from the File menu. A dialog box will appear and allows you +to enter the name of the host you want to connect to. Below the name you can choose +the connection method. The default is ssh, the secure +shell. Alternatively the rsh, the remote shell, +the daemon mode or a custom command can be used. Click OK to +establish the connection. Shortly afterwards the new host will appear in the +sensor browser and you can browse the list of sensors. + + + +To establish a connection, a program called +ksysguardd, that can be started in the following +two modes, must be installed on the new host. + + + +daemon mode + +You can start ksysguardd at boot time in +Daemon mode by adding -d as the +argument. In this case, you have to select daemon mode at the connection +dialog of ksysguard. +A disadvantage of this connection type is that you won't be able to kill or +renice a process in the Process Table and +the data exchange over network won't be encrypted. As a result, daemon +mode is not recommended. + + + +shell mode + +In this mode ksysguardd is started at +connecting time by ksysguard. To make that possible, +its location needs to be included in your PATH. +Unfortunately the ssh does not source your .profile file, +so your regular PATH setting will not be available. +Instead it uses a default PATH like +/bin:/usr/bin. +Since it is very likely that &kde; is not installed in these folders you need +to create or update a file in your home folder. The file is called +environment and needs to be in a hidden folder called +.ssh. See the manual page for +ssh for more details. The file needs to contain a +line similar to: + + +PATH=/bin:/usr/bin:/opt/kde/bin + + +assuming that ksysguardd can be found under +/opt/kde/bin/ksysguardd. + +When using ssh you should make sure that +you have your identity.pub installed on the remote machine +and the host key of the remote machine is already registered on your machine. +If you don't set up identity.pub correctly, you will be asked +for your password every time you start ksysguard. +The easiest way to make sure that everything is working is to run ssh in a shell. If you are greeted by +ksysguardd, then everything is working correctly +and you can type quit to exit ksysguardd. + + + + +For experts: ksysguardd is a +very small program that is only linked against the libc. So it can +also be used on machines that do not have a full blown &kde; +installed, such as servers. Many major distributions provide a separate +ksysguardd package for your convenience. +If you choose the custom command option in +the host connector you need to specify the complete command to start +ksysguardd. + + + + + + +
    + + +Configuring <application>ksysguardd</application> + +The graphical front-end is available on any platform that &kde; runs +on. The back-end is at the moment available on the following flavors of +&UNIX;: + + + +&Linux; 2.x + For ksysguardd to work it +is necessary to compile the &Linux; Kernel +with the /proc File system enabled. This is the default +setting and most &Linux; Distributions have it already. + + +FreeBSD +The ksysguardd program +needs to be owned by the kmem group and needs to have the setgid +bit set. + + +&Solaris; +To be written + + + +Support for other platforms is in progress. Your help is greatly +appreciated. + + + +Credits and License + +&ksysguard; is currently developed and maintained by &John.Tapsell; +&John.Tapsell.mail;. &ksysguard; is a rewrite of +KTop, the &kde; 1.x task manager. Several other people +have worked on KTop: + + + A. Sanda alex@darkstar.ping.at + Ralf Mueller ralf@bj-ig.de + &Bernd.Johannes.Wuebben; +wuebben@math.cornell.edu + Nicolas Leclercq +nicknet@planete.net + + +The porting to other platforms than &Linux; was done by: + + + FreeBSD: Hans Petter Bieker +zerium@traad.lavvu.no + + + +&underFDL; +&underGPL; + + + +
    + + diff --git a/doc/plasma-desktop/CMakeLists.txt b/doc/plasma-desktop/CMakeLists.txt new file mode 100644 index 00000000..1d646fe0 --- /dev/null +++ b/doc/plasma-desktop/CMakeLists.txt @@ -0,0 +1,5 @@ +########### install files ############### +# +# +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) + diff --git a/doc/plasma-desktop/add-widgets.png b/doc/plasma-desktop/add-widgets.png new file mode 100644 index 0000000000000000000000000000000000000000..7c062760ebce7baee7892a9ca26dc1edb1a55272 GIT binary patch literal 28524 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 literal 0 HcmV?d00001 diff --git a/doc/plasma-desktop/desktop-settings.png b/doc/plasma-desktop/desktop-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..03732de504ee3de816f8c586c935f7e8d1949381 GIT binary patch literal 96709 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 z�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

    2%{UuTZF}0(9MYSJ%41UC@AGv_`RJTSP2M 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∾$q9XsHX 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

    U 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 + + + + +]> + + + +The &plasma; Handbook + + + + +Sebastian +Kügler + +sebas@kde.org + +Claus Christensen + + + + +2008–2010 +Sebastian Kügler + + +&FDLNotice; + +2013-06-19 +&kde; 4.11 + + + +&plasma;, the most visible pillar of &kde;, is the core interface to the desktop. + + + + +KDE +Plasma +Plasmoid +Widget +Containments +Desktop +Runner +Kicker + + + + + +Introduction + + +&plasma; is one of the key technologies of &kde; Software Compilation 4 (also known as the +“Pillars of &kde;”), and one of the most visible to users. As &plasma; +treats the user interface differently than a traditional desktop, there may be +confusion on what &plasma; is, what it does, and how to perform common tasks. + + + +This document attempts to address these problems by providing answers to the +most common questions. + + + + +Using &plasma; + + +&plasma; Components + + +&plasma; Widgets and Containments + + +The essence of &plasma; revolves around two basic concepts: + + + + +&plasma; Widgets + + +Applets, or small applications that live on the desktop. + + + + +Containments + + +Applets that act as the container for the &plasma; widgets + + + + + + +On a default desktop, there are two main elements: the Panel and the Desktop +itself. Both are containments in the &plasma; sense. + + + + + +Default &plasma; Desktop + +The &plasma; Desktop can be configured in countless ways. The screenshot seen below shows a fairly standard desktop. Some distributions apply extensive customizations, so your desktop may look different. + +Similarly, the graphical appearance of the interface elements can be styled. These screenshots uses the &kde; default style, Oxygen. + + + +A fairly standard &plasma; Desktop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +The program starter. Usually this will be &kickoff;. +A couple of icons giving easy access to often used applications +The Pager widget +The Task Manager, which shows the titles of windows belonging to the applications currently running. No application had opened a window, when the screenshot was taken +The System Tray +The Digital Clock widget +The Panel Toolbox +The Desktop Toolbox (previously known as a Cashew) +A Folder View widget, showing the content of the Desktop folder + + + + + + +The Panel + + +The default panel holds a few &plasma; widgets: starting from the left, there is the +&kickoff; application launcher. You can use it to start applications, open recently +opened files and the usual logout/shutdown options. There is also a structure +that allows you to browse through your applications. The layout has been +optimized for the use case that is most common: starting an application. The +default tab is the Favorites tab that holds the most-used +entries. In the beginning, you'll probably find yourself using the +Applications tab more often. +Once you have found out what your most frequently started applications are, +right click on the items and select the +Add to Favorites to add them to your +Favorites (or directly into the panel or on the desktop. +Note that you need to unlock &plasma; by means of right +clicking on the desktop for any kind of modification). If you prefer the +traditional menu-style application launcher, change it by +right clicking on the menu button and selecting +Switch to Classic Menu Style. + + + +The taskbar is another widget on the panel. It shows an area for all open windows on +all desktops by default. You can make it show all open windows on the current +desktop only by checking Only show tasks from the +current desktop when you right click on the task manager, between +two windows. The size of the text on the taskbar items can be set +in &systemsettings; under the +Application AppearanceFonts +Taskbar. Right-clicking on the taskbar +brings the Settings dialog where you can choose several options to customize +your taskbar. + +Here is a screenshot of the taskbar settings dialog + + + + + + Taskbar settings dialog + + + + + + +Another default panel item is the System Tray, which +is used by traditional applications and widgets as a dock. Right clicking on the +System Tray allows you to open the settings dialog, +where you can set entries to display and their visibility. + + +System Tray settings dialog + + + + + + System Tray settings dialog + + + + +An icon located usually in the system tray is the Device Notifier. +Plug in a USB disk and a dialog will open that allows you to +open the device in &dolphin; or another associated application. + + + + + + + + + + + + + + +The Device Notifier is used for handling pluggable devices such as USB pendrives (also called flash drives or thumb drives), digital cameras, external USB hard drives, &etc; It also comes into play when a medium such as a &CD; or DVD is loaded into an optical drive. + +When you plug in an external device, or load a new medium into a drive, the Notifier window pops up (you can also open it explicitly by clicking on its Panel icon.) It stays open while the cursor is over it, otherwise it hides itself after a few seconds. + +The Notifier window shows a list of all the devices it currently knows about. Moving the mouse cursor over a device will highlight how many possible actions are associated with that device. + + + + + + + + + + + + + + +Clicking anywhere in the shaded box around the device name (but not on the eject/unmount icon if present) expands the entry to show the list of possible actions for that device. The set of actions depends on the device; it is configurable from the Device Notifier's context menu or from the &systemsettings; modules Device Actions and Removable Devices. Simply select one with the mouse or keyboard to launch that action. + +There is also a small icon to the right of each entry showing whether that device is currently accessible (or mounted) or not. Only when a device is not mounted is it safe to physically disconnect it from the computer. Clicking on the icon causes the device to be unmounted and/or the medium to be ejected if it is currently mounted, and will mount it if it is not. Note that unmounting/ejecting might fail if the device still has open files on it, ⪚ if a large file copy hasn't finished. In most cases you can just wait a while and try again. When an unmounting has succeeded, a success icon will be shown on the Device Notifier's icon. + + +The System Tray normally holds some more entries like +&klipper;, &kmix; &etc; + +Some of the default entries in the System Tray are hidden +to save space in the bar. To display these entries click on the small white triangle + +, then use +the &LMB; to launch a widget or the &RMB; to open its settings dialog. + + +The right-most &plasma; widget in the default panel holds the Digital +Clock. +This clock can display the time in different timezones as well as have its size +changed. The clock will adjust its font size to the area it is given by the +surrounding containment (that is the panel in this case). If you choose to +display the date, this date will be rendered using the Small +font option from the &systemsettings; Font +dialog. The time will take the rest of the space. So in the end, you'll choose +yourself the amount of information displayed, and if that fits. If you want to +display more information, make the panel larger or put the clock on the desktop +where it can grow freely. + + + +An optional item on your panel is the Pager. +It allows you to switch between your virtual desktops. +If you change the layout of the Pager +through the Number of rows option, +which will also affect the layout and animations that are shown in &kwin;’s +Desktop Grid effect. +For larger pagers, selecting Display windows icons +typically makes sense. + + + + + + + + + + +The Panel Toolboxes + +If your desktop is unlocked (you can do that by +right clicking on the desktop, or when no +application has the focus, with &Alt;D, L), a small &plasma; +logo will appear in the bottom right corner in the panel (it is commonly named the +“cashew”). Click on this cashew, and the panel controller opens. + + +Panel Settings + + + + + + Panel Settings + + + + +The panel controller allows you to reposition, resize and realign the panel. The +&plasma; widgets living in this panel will adjust their size automatically. +&plasma; widgets have basic knowledge about sizing, provided by the containment. They +are programmed to take advantage of that size, and inform the applet about how +much space they possibly need. In the end, the containment gives a possible size +to the applets, the applets obey. + + + + +Adding Applets + + +Unlock the desktop and you'll be able to add and remove &plasma; widgets from panel +or desktop. You add &plasma; widgets by simply dragging them where you want them. +Right click on an widget to remove it. + + +Add Widgets + + + + + + Add Widgets + + + + +The Get New Widgets button allows you to add widgets +you've previously downloaded and download new &plasma; widgets. +Currently it supports native &plasmagik; packages +and some &Mac; OS X dashboard widgets. Widgets you install this way can then be +accessed just like regular, preinstalled widgets. + + + + +The Desktop + + +The desktop is in fact another containment. One that does not put size +constraints on the applets. Applets can be moved and sized freely. On the +unlocked desktop, &plasma; widgets will show a frame when you move the mouse over +them. This applet handle allows you to move, resize, relocate and realign the +panel. It also allows you to drag &plasma; widgets on the desktop. The buttons in the +corner are used to resize, rotate configure and remove the applet. When +rotated, a &plasma; widget will act magnetic towards 12 o'clock, so it is easy to get +them back into sensible position. By default, most applets keep their aspect +ratio when they are being resized. If you want to freely resize an applet, +hold the &Ctrl; key pressed while resizing. + + + +Right clicking on the desktop also offers you to configure aspects such as the +wallpaper and the layout used, and the mouse actions. It offers to download new +wallpapers through &knewstuff;. + + + +Desktop Settings + + + + + + Desktop Settings + + + + +To change the &plasma; theme or download a new one through &knewstuff; +open the Workspace Appearance Desktop +Theme page in the &systemsettings;. + + +With open applications, it quickly gets hard to see the &plasma; widgets on your +desktop. The Dashboard gets those &plasma; widgets +in front of you, much like the Show desktop functionality +you are used to from traditional desktops. + + + + + +&krunner; + + +&krunner; is a versatile mini command-line. You can use it to start applications, +open web pages, access bookmarks, search through your desktop data, calculate +short equations, and many more.Pressing &Alt;F2 opens the &krunner; dialog. +You just start typing and &krunner; will start searching matches as soon as +you've entered more than two characters. You can open the settings dialog to +learn about &krunner;’s functionality, provided by plugins. You can +navigate through the matches using the tab and arrow keys. + + + +If you want to know what is going on on your system, there is the Show +System Activity button, giving you quick access to a list of windows +and processes, with options to monitor their output and kill processes. + + + + + +Activities + + +The desktop toolbox, accessed via the upper right corner has a button for +displaying your activities, of which &plasma; allows you to have more than one. +Basically, that is multiple desktop containments hosting multiple sets of &plasma; widgets. +Display the Activities bar, select one of the predefined activities +or choose Create Activity +to create a new containment, select your new containment and customize suiting your taste. +&plasma;’s activities and &kwin;’s desktop grid are similar in that respect, but there +is a fundamental difference. While virtual desktop are used to group and organize windows, +&plasma;’s activities are used to group and organize &plasma; widgets. This way, you can +switch between activities and have relevant &plasma; widgets supporting the task you are +currently trying to accomplish. You can create a Free time activity, with +comic strips, a puzzle and other &plasma; widgets, and a Work activity, +with relevant RSS feeds, calculator and calendar, for example. + + + +To delete an activity, press the Stop Activity button on +Activities bar (press &Alt;D then &Alt;A to open this bar) then click +the red 'X' (or press &Alt;D +then &Alt;R) and confirm the +deletion. + + + + + + +Shortcuts + + +Most of &plasma;’s functionality is also accessible through keyboard +shortcuts. The various combinations should be pressed in sequence, that +is for example &Alt;D, A +means: Press &Alt; and D, release and press A. + +Currently, the following default shortcuts can be used: + + + + +&Alt;D, A +Add Widgets + + + +&Alt;D, R +Remove Widget + + + +&Alt;D, L +Lock/Unlock Widgets + + + + +&Alt;D, N +Next Widget + + + +&Alt;D, P +Previous Widget + + + +&Alt;D, S +Widget settings + + + +&Alt;D, &Alt;A +Activities + + + +&Alt;D, &Alt;R +Remove this Activity + + + +&Alt;D, &Alt;S +Activities Settings + + + +Meta +Next Activity + + + +Meta&Shift; +Previous Activity + + + +&Ctrl;F12 +Show Dashboard + + + +&Alt;D, T +Run the Associated Application + + + + + +To change shortcuts, click with the &LMB; on the desktop Toolbox +(the cashew usually at the top right of the desktop) and select Shortcut Settings. + + + + + + +Credits and License + + +&plasma; + + +Program copyright 2008 &Aaron.J.Seigo; &Aaron.J.Seigo.mail; + + + +Documentation Copyright © 2008–2010 Sebastian Kügler sebas@kde.org + + + + +&underFDL; + + + +&documentation.index; + + + diff --git a/doc/plasma-desktop/panel-settings.png b/doc/plasma-desktop/panel-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..49fe1dc48caa6b56ffd6e8fb27ec3eea53b6a891 GIT binary patch literal 35520 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%0Ao}nL) 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 literal 0 HcmV?d00001 diff --git a/doc/plasma-desktop/plasma-desktop-annotated.png b/doc/plasma-desktop/plasma-desktop-annotated.png new file mode 100644 index 0000000000000000000000000000000000000000..8ab73438f9f93000ad8bdac85c0e8a2525f1bc50 GIT binary patch literal 387050 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

    ~0fx$EK`I1kQ& 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�L*S+KI&S3gBiAnLwD*X*PaP(zHW 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 eF*Q0eH!CnQIxsLxBVX_U0000#L>! literal 0 HcmV?d00001 diff --git a/doc/plasma-desktop/system-tray-settings.png b/doc/plasma-desktop/system-tray-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..e3ff1c3a59337853d425b17ba2a9b145b56b32cd GIT binary patch literal 44856 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 literal 0 HcmV?d00001 diff --git a/doc/plasma-desktop/system-tray-up-arrow.png b/doc/plasma-desktop/system-tray-up-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..6de1abb999695eb6d91c80367cd723e97b4c3f56 GIT binary patch literal 428 zcmeAS@N?(olHy`uVBq!ia0vp^;vmccBp8l5cGmzY&H|6fVg?4j!ywFfJby(BNU*HH zF&#*QRWtB4aqj_gn3BBRT^Rni_n+AhdGatf+YT^S;NUe81_3j>s?Qh}UnQdAaK2tEb)1&&{#ek^OmDZTsra94S21$?&!TD(=<%vb94CUqJdYO6I#mR{U Zse1WE>9gP2NC6cwc)I$ztaD0e0s#IardI#} literal 0 HcmV?d00001 diff --git a/doc/plasma-desktop/taskbar-settings.png b/doc/plasma-desktop/taskbar-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..47c61e979372ffe9a664b01d1de0cbd190f0291b GIT binary patch literal 47842 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

    utbw7&(s8yR!>9Iu^Pnm061 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 FKLF=xb7BAh literal 0 HcmV?d00001 diff --git a/doc/systemsettings/CMakeLists.txt b/doc/systemsettings/CMakeLists.txt new file mode 100644 index 00000000..2757f627 --- /dev/null +++ b/doc/systemsettings/CMakeLists.txt @@ -0,0 +1,4 @@ +##### Install Systems Settings Documentation ##### +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en) + +##### Install System Settings Modules Documentation ##### diff --git a/doc/systemsettings/index.docbook b/doc/systemsettings/index.docbook new file mode 100644 index 00000000..5feb5d2b --- /dev/null +++ b/doc/systemsettings/index.docbook @@ -0,0 +1,473 @@ + + + + + +]> + + + +The &systemsettings; Handbook + + + +&Richard.Johnson; +&Richard.Johnson.mail; + + + + + +2007 +&Richard.Johnson; + +&FDLNotice; + +2013-12-05 +4.12 (&kde; 4.12) + + + +This documentation describes &kde;'s system configuration and administration center. + + + + +KDE +System +Settings +configuration +administration +config +admin + + + + + +Introduction + + +The &kde; &systemsettings; provides the user with a centralized and convenient way to configure all of the &kde; settings. + + + +&systemsettings; is made up of multiple modules. Each module is a separate application, however the &kde; &systemsettings; organizes all of these applications into a single location. + + + + +Each &systemsettings; module can be executed individually + + +See section entitled Running +individual &systemsettings; modules for more information. + + + + +&systemsettings; groups all of the configuration modules into several categories: + +Common Appearance and Behavior +Workspace Appearance and Behavior +Network and Connectivity +Hardware +System Administration + + + + +The modules that make up &systemsettings; fall under one of the above categories, making it easier to locate the correct configuration module. + + + + + +Using &systemsettings; + + +This section details the use of &systemsettings; itself. For information on each individual module, please see &systemsettings; Modules. + + + +Starting &systemsettings; + + +The &kde; &systemsettings; can be started in one of three ways: + + + + + +By selecting K ButtonApplicationsSystem Settings. + + + + + By pressing &Alt;F2. This will bring up the &krunner; dialog. Type systemsettings, and press &Enter;. + + + + +Type systemsettings & at any command prompt. + + + + + +All three of these methods are equivalent, and produce the same result. + + + + +The &kde; &systemsettings; Screen + + +When you start &systemsettings;, you are presented with a window, which is divided into three functional parts. + + + +Across the top is a toolbar. The toolbar provides the user with the ability to go back into the main view from within a module using the Overview. +You can also find a Help menu as well as a Configure button which provides you a dialog with alternate view settings. + +To search for something within all of the modules, start to type keywords into the search field at the right of the toolbar in the Overview. When you start typing, a list of matching topics will popup. Select one and only the groups with settings for this keyword are enabled, the other are greyed out. +When the icon window has the focus, you can type the first letter of +any module or module group name to select it. Typing this letter again the +selection moves to the next match. + + +Underneath the toolbar is an icon view of the individual modules or module groups that +make up &systemsettings; grouped by different categories. By default, +if your mouse stays a few seconds over an icon, a detailed tooltip +appears, explaining the purpose of the module or the modules in this group. + + + + +&systemsettings; Categories and Modules +A brief overview of all categories and their modules: + + + +Common Appearance and Behavior + + + +Account Details (Password & User Account, Paths, KDE Wallet, Social Desktop, Web Shortcuts) + + +Application Appearance (Style, Colors, Icons, Fonts, Emoticons) + + +Application and System Notifications (Manage Notifications, System Bell, Launch Feedback) + + +File Associations + + +Locale (Country/Region & Language, Spell Checker) + + +Personal Information (Akonadi Resources Configuration) + + +Shortcuts and Gestures (Custom Shortcuts, Standard Keyboard Shortcuts, Global Keyboard Shortcuts) + + + + + + + +Workspace Appearance and Behavior + + + +Desktop Effects + + +Workspace Appearance (Window Decorations, Cursor Theme, Desktop Theme, Splash Screen) + + +Accessibility (Accessibility, Text-to-Speech) + + +Default Applications + + +Desktop Search + + +Window Behavior (Task Switcher, Window Behavior, KWin Scripts, Window Rules) + + +Workspace Behavior (Activities, Virtual Desktops, Screen Edges, Workspace) + + + + + + + +Network and Connectivity + + + +Network Settings (Proxy, Connection Preferences, Service Discovery) + + +Sharing (Windows Shares) + + +SSL Preferences + + + + + + + +Hardware + + + +Device Actions + + +Digital Camera + + +Display and Monitor (Size & Orientation, Screen Locker, Gamma) + + +Input Devices (Keyboard, Mouse, Joystick, Remote Controls) + + +Power Management (Energy Savings Settings, Activity Settings, Advanced Settings) + + +Printers + + +Removable Devices + + +Multimedia (Audio CDs, Audio and Video Settings, CDDB Retrieval) + + + + + + + +System Administration + + + +Date & Time + + +Font Management + + +Login Screen + + +Startup and Shutdown (Autostart, Service Manager, Session Management) + + +Task Scheduler + + + + + + + + +Use the search field in Overview to find all matching modules for a given keyword. + + +Exiting the &kde; &systemsettings; + + +&systemsettings; can be exited in one of two ways: + + + + + +Press &Ctrl;Q on the keyboard. + + + + +Click on the Close button located in the toolbar. + + + + + + +Configuring &systemsettings; + + +The Configure icon in the toolbar allows you to change some &systemsettings; parameters. +You can change from Icon View (default view) to Classic Tree View. + + + +You can also turn off the detailed tooltips by unchecking Show detailed tooltips. +You will then get only normal tooltips and not the content of a module group. + + + + +Running Individual &systemsettings; Modules + + +Individual modules can be run without running &systemsettings; using the command kcmshell4 from the command line. Type kcmshell4 --list to see a list of the available &kde; &systemsettings; modules. + + + + + + +The &kde; &systemsettings; Modules + + +In order to make it as easy as possible, the &kde; &systemsettings; has organized options into five categories. Under each category, there are icons grouped together under subcategories. Each icon is called a module. When you double click on a module icon, you will be presented with the options of the module in the main window. + + + +Each module will have some or all of the following buttons: + + + + +Help + + +This button will provide help specific to the current module. Clicking the button will open &khelpcenter; in a new window providing detailed information on the module. + + + + + +Defaults + + +Clicking this button will restore this module to its default values. You must click Apply to save the options. + + + + + +Reset + + +This button will "Reset" the module to the previous settings. + + + + + +Apply + + +Clicking this button will save all changes to &kde;. If you have changed anything, clicking Apply will cause the changes to take effect. + + + + + + + +You must either "Reset" or "Apply" the changes before changing to another module. + + +If you try to change without saving or resetting your options, you will be asked if you want to save your changes, or discard them. + + + + + + + +Credits and License + + +&systemsettings; + + +Program copyright 2007 Benjamin C. Meyer. + + +Program copyright 2009 Ben Cooksley. + + +Contributors: + + + +Will Stephenson wstepheson@kde.org + + + +Michael D. Stemle, Jr. manchicken@notsosoft.net + + + + +Matthias Kretz kretz@kde.org + + + + +&Daniel.Molkentin; &Daniel.Molkentin.mail; + + + + +&Matthias.Elter; &Matthias.Elter.mail; + + + + +Frans Englich englich@kde.org + + + + +Michael Jansen kde@michael-jansen.biz + + + + + + +Documentation Copyright © 2008 &Richard.Johnson; &Richard.Johnson.mail; + + + + +&underFDL; +&underGPL; + + +&documentation.index; + + + diff --git a/freespacenotifier/CMakeLists.txt b/freespacenotifier/CMakeLists.txt new file mode 100644 index 00000000..2ce73eb8 --- /dev/null +++ b/freespacenotifier/CMakeLists.txt @@ -0,0 +1,28 @@ +project (freespacenotifier) + +find_package(KDE4 REQUIRED) +include (KDE4Defaults) + +add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) + +########### next target ############### + +set(kded_freespacenotifier_SRCS freespacenotifier.cpp module.cpp) + +kde4_add_ui_files(kded_freespacenotifier_SRCS freespacenotifier_prefs_base.ui) + +kde4_add_kcfg_files(kded_freespacenotifier_SRCS settings.kcfgc) + +kde4_add_plugin(kded_freespacenotifier ${kded_freespacenotifier_SRCS}) + +target_link_libraries(kded_freespacenotifier ${KDE4_KIO_LIBS} ) + +install(TARGETS kded_freespacenotifier DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES freespacenotifier.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) +install( FILES freespacenotifier.notifyrc DESTINATION ${DATA_INSTALL_DIR}/freespacenotifier ) +install( FILES freespacenotifier.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) diff --git a/freespacenotifier/COPYING b/freespacenotifier/COPYING new file mode 100644 index 00000000..5185fd3f --- /dev/null +++ b/freespacenotifier/COPYING @@ -0,0 +1,346 @@ +NOTE! The GPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (the kde programs) are copyrighted +by the authors who actually wrote it. + +--------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/freespacenotifier/Messages.sh b/freespacenotifier/Messages.sh new file mode 100644 index 00000000..858cfc3b --- /dev/null +++ b/freespacenotifier/Messages.sh @@ -0,0 +1,3 @@ +#! /bin/sh +$EXTRACTRC *.ui *.kcfg >> rc.cpp +$XGETTEXT *.cpp -o $podir/freespacenotifier.pot diff --git a/freespacenotifier/README b/freespacenotifier/README new file mode 100644 index 00000000..208f817d --- /dev/null +++ b/freespacenotifier/README @@ -0,0 +1,3 @@ +This is a small KDED module that monitors free disk space on the home dir +partition and shows a warning dialog when it runs too low, +with a configurable limit and the possibility to postpone. diff --git a/freespacenotifier/freespacenotifier.cpp b/freespacenotifier/freespacenotifier.cpp new file mode 100644 index 00000000..a977d0c3 --- /dev/null +++ b/freespacenotifier/freespacenotifier.cpp @@ -0,0 +1,182 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + Copyright (c) 2009 Ivo Anjo + + 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. If not, see . +*/ + +#include "freespacenotifier.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "settings.h" +#include "ui_freespacenotifier_prefs_base.h" + +FreeSpaceNotifier::FreeSpaceNotifier( QObject* parent ) + : QObject( parent ) + , lastAvailTimer( NULL ) + , notification( NULL ) + , lastAvail( -1 ) +{ + // If we are running, notifications are enabled + FreeSpaceNotifierSettings::setEnableNotification( true ); + + connect( &timer, SIGNAL(timeout()), SLOT(checkFreeDiskSpace()) ); + timer.start( 1000 * 60 /* 1 minute */ ); +} + +FreeSpaceNotifier::~FreeSpaceNotifier() +{ + // The notification is automatically destroyed when it goes away, so we only need to do this if + // it is still being shown + if ( notification ) notification->deref(); +} + +void FreeSpaceNotifier::checkFreeDiskSpace() +{ + if ( notification || !FreeSpaceNotifierSettings::enableNotification() ) + return; + KDiskFreeSpaceInfo fsInfo = KDiskFreeSpaceInfo::freeSpaceInfo( QDir::homePath() ); + if ( fsInfo.isValid() ) + { + int limit = FreeSpaceNotifierSettings::minimumSpace(); // MiB + int availpct = int( 100 * fsInfo.available() / fsInfo.size() ); + qint64 avail = fsInfo.available() / ( 1024 * 1024 ); // to MiB + bool warn = false; + if( avail < limit ) // avail disk space dropped under a limit + { + if( lastAvail < 0 ) // always warn the first time + { + lastAvail = avail; + warn = true; + } + else if( avail > lastAvail ) // the user freed some space + lastAvail = avail; // so warn if it goes low again + else if( avail < lastAvail / 2 ) // available dropped to a half of previous one, warn again + { + warn = true; + lastAvail = avail; + } + // do not change lastAvail otherwise, to handle free space slowly going down + } + if ( warn ) + { + notification = new KNotification( "freespacenotif", 0, KNotification::Persistent ); + + notification->setText( i18nc( "Warns the user that the system is running low on space on his home folder, indicating the percentage and absolute MiB size remaining, and asks if the user wants to do something about it", "You are running low on disk space on your home folder (currently %2%, %1 MiB free).\nWould you like to run a file manager to free some disk space?", avail, availpct ) ); + notification->setActions( QStringList() << i18nc( "Opens a file manager like dolphin", "Open File Manager" ) << i18nc( "Closes the notification", "Do Nothing" ) << i18nc( "Allows the user to configure the warning notification being shown", "Configure Warning" ) ); + //notification->setPixmap( ... ); // TODO: Maybe add a picture here? + + connect( notification, SIGNAL(action1Activated()), SLOT(openFileManager()) ); + connect( notification, SIGNAL(action2Activated()), SLOT(cleanupNotification()) ); + connect( notification, SIGNAL(action3Activated()), SLOT(showConfiguration()) ); + connect( notification, SIGNAL(closed()), SLOT(cleanupNotification()) ); + + notification->setComponentData( KComponentData( "freespacenotifier" ) ); + notification->sendEvent(); + } + } +} + +void FreeSpaceNotifier::openFileManager() +{ + cleanupNotification(); + new KRun( KUrl( QDir::homePath() ), 0 ); +} + +void FreeSpaceNotifier::showConfiguration() +{ + cleanupNotification(); + + if ( KConfigDialog::showDialog( "settings" ) ) { + return; + } + + KConfigDialog *dialog = new KConfigDialog( 0, "settings", FreeSpaceNotifierSettings::self() ); + QWidget *generalSettingsDlg = new QWidget(); + + Ui::freespacenotifier_prefs_base preferences; + preferences.setupUi( generalSettingsDlg ); + + dialog->addPage( generalSettingsDlg, i18nc( "The settings dialog main page name, as in 'general settings'", "General" ), "system-run" ); + connect( dialog, SIGNAL(finished()), this, SLOT(configDialogClosed()) ); + dialog->setAttribute( Qt::WA_DeleteOnClose ); + dialog->show(); +} + +void FreeSpaceNotifier::cleanupNotification() +{ + notification = NULL; + + // warn again if constantly below limit for too long + if( lastAvailTimer == NULL ) + { + lastAvailTimer = new QTimer( this ); + connect( lastAvailTimer, SIGNAL(timeout()), SLOT(resetLastAvailable()) ); + } + lastAvailTimer->start( 1000 * 60 * 60 /* 1 hour*/ ); +} + +void FreeSpaceNotifier::resetLastAvailable() +{ + lastAvail = -1; + lastAvailTimer->deleteLater(); + lastAvailTimer = NULL; +} + +void FreeSpaceNotifier::configDialogClosed() +{ + if ( !FreeSpaceNotifierSettings::enableNotification() ) + disableFSNotifier(); +} + +/* The idea here is to disable ourselves by telling kded to stop autostarting us, and + * to kill the current running instance. + */ +void FreeSpaceNotifier::disableFSNotifier() +{ + QDBusInterface iface( "org.kde.kded", "/kded", "org.kde.kded" ); + if ( dbusError( iface ) ) return; + + // Disable current module autoload + iface.call( "setModuleAutoloading", "freespacenotifier", false ); + if ( dbusError( iface ) ) return; + + // Unload current module + iface.call( "unloadModule", "freespacenotifier" ); + if ( dbusError( iface ) ) return; +} + +bool FreeSpaceNotifier::dbusError( QDBusInterface &iface ) +{ + QDBusError err = iface.lastError(); + if ( err.isValid() ) + { + kError() << "Failed to perform operation on kded [" << err.name() << "]:" << err.message(); + return true; + } + return false; +} diff --git a/freespacenotifier/freespacenotifier.desktop b/freespacenotifier/freespacenotifier.desktop new file mode 100644 index 00000000..37167833 --- /dev/null +++ b/freespacenotifier/freespacenotifier.desktop @@ -0,0 +1,131 @@ +[Desktop Entry] +Name=Free Space Notifier +Name[ar]=منبه المساحة الحرة +Name[ast]=Notificador d'espaciu llibre +Name[bg]=Уведомяване за свободно пространство +Name[bs]=Izvještač o slobodnom prostoru +Name[ca]=Notificador d'espai lliure +Name[ca@valencia]=Notificador d'espai lliure +Name[cs]=Oznamování volného místa +Name[da]=Bekendtgørelse om ledig plads +Name[de]=Speicherplatzbenachrichtigung +Name[el]=Ειδοποίηση ελεύθερου χώρου +Name[en_GB]=Free Space Notifier +Name[es]=Notificador de espacio libre +Name[et]=Vaba ruumi teavitaja +Name[eu]=Leku askearen jakinarazlea +Name[fi]=Vapaan tilan ilmoitin +Name[fr]=Notification d'espace libre +Name[ga]=Fógróir Spáis Shaoir +Name[gl]=Notificador de espazo libre +Name[he]=Free Space Notifier +Name[hi]=खाली स्थान सूचक +Name[hr]=Glasnik slobodnog prostora +Name[hu]=Szabad hely értesítő +Name[ia]=Notificator de spatio libere +Name[id]=Notifikasi Ruang Kosong +Name[is]=Tilkynningar um laust pláss +Name[it]=Notificatore dello spazio libero +Name[ja]=空き領域の通知 +Name[kk]=KDE-нің бос орын туралы құлақтандыруы +Name[km]=កម្មវិធី​ជូនដំណឹង​​ទំហំ​ទំនេរ +Name[kn]=ಖಾಲಿ ಜಾಗ ಸೂಚಕ +Name[ko]=남은 공간 알림이 +Name[lt]=Laisvos vietos pranešėjas +Name[lv]=Brīvās vietas ziņotājs +Name[ml]=ലഭ്യമായ സ്ഥലം അറിയിക്കുന്നതിനുള്ള സംവിധാനം +Name[mr]=मोकळी जागा निदर्शक +Name[nb]=Ledig plass-varsler +Name[nds]=Freeruumbescheden +Name[nl]=Vrije ruimte-melder +Name[nn]=Varsel om lite ledig plass +Name[pa]=ਖਾਲੀ ਥਾਂ ਨੋਟੀਫਾਇਰ +Name[pl]=Powiadomienie o wolnym miejscu +Name[pt]=Notificação de Espaço Livre +Name[pt_BR]=Notificação de espaço livre +Name[ro]=Notificare spațiu liber +Name[ru]=Слежение за свободным местом на диске +Name[si]=හිස් ඉඩ දැනුම් දෙන්නා +Name[sk]=Monitor voľného miesta +Name[sl]=Obvestilnik o neporabljenem prostoru +Name[sr]=Извештавач о слободном простору +Name[sr@ijekavian]=Извјештавач о слободном простору +Name[sr@ijekavianlatin]=Izvještavač o slobodnom prostoru +Name[sr@latin]=Izveštavač o slobodnom prostoru +Name[sv]=Information om ledigt utrymme +Name[th]=ตัวแจ้งพื้นที่ว่าง +Name[tr]=Boş Alan Bildirici +Name[ug]=بىكار بوشلۇق خەۋەرچىسى +Name[uk]=Сповіщення про вільне місце +Name[vi]=Trình thông báo không gian trống +Name[wa]=Notifieu del plaece di libe +Name[x-test]=xxFree Space Notifierxx +Name[zh_CN]=空闲空间通知器 +Name[zh_TW]=剩餘空間通知 +Comment=Warns when running out of space on your home folder +Comment[ar]=يحذر عندما توشك مساحة مجلد المنزل على النفاد +Comment[ast]=Avisa cuando te quedes ensin espaciu na carpeta personal +Comment[bg]=Предупреждение при твърде малко пространство в домашната директория +Comment[bn]=ব্যক্তিগত ফোল্ডারে জায়গা কমে গেলে সতর্ক করে +Comment[bs]=Upozorava kada vam ponestaje prostora u ličnom direktoriju +Comment[ca]=Avisa quan s'exhaureix l'espai de la carpeta personal +Comment[ca@valencia]=Avisa quan s'exhaureix l'espai de la carpeta personal +Comment[cs]=Varování při blížícím se nedostatku místa v domácí složce +Comment[da]=Advarer når du er ved at løbe tør for plads i din hjemmemappe +Comment[de]=Gibt eine Warnung aus, wenn der freie Speicherplatz in Ihrem Persönlichen Ordner knapp wird +Comment[el]=Προειδοποιεί όταν τελειώνει ο ελεύθερος χώρος στον 'Προσωπικό φάκελό' σας +Comment[en_GB]=Warns when running out of space on your home folder +Comment[es]=Le avisa cuando se está quedando sin espacio en su carpeta personal +Comment[et]=Hoiatus, kui kodukataloogis hakkab ruumi nappima +Comment[eu]=Abisua ematen du etxeko karpetan lekurik gabe gelditzen ari zarenean +Comment[fi]=Varoittaa kun kotikansiosta on tila loppumassa +Comment[fr]=Avertit lorsque l'espace vient à manquer dans votre dossier utilisateur +Comment[ga]=Tugann sé rabhadh duit nuair atá d'fhillteán baile ag éirí lán +Comment[gl]=Avisa cando se está a quedar sen espazo no cartafol persoal +Comment[he]=משמש לאזהרה כאשר המקום הפנוי בתיקיית הבית מועט +Comment[hr]=Upozori kada nestaje prostora u mojoj korisničkoj mapi +Comment[hu]=Figyelmeztet, ha kezd elfogyni a szabad lemezterület a saját könyvtárában +Comment[ia]=Il avisa quando il termina le spatio sur tu dossier domo +Comment[id]=Memperingatkan jika kehabisan ruang kosong di folder rumah anda +Comment[is]=Varar við þegar lítið pláss er eftir í heimamöppunni þinni +Comment[it]=Avvisa quando si sta finendo lo spazio nella tua cartella Home +Comment[ja]=ホームフォルダの空き領域が少なくなったとき警告します +Comment[kk]=Мекен қапшығыңызда орын тапшылығы туралы ескерту +Comment[km]=ព្រមាន នៅពេល​ដំណើរការ​អស់ទំហំ​នៅ​លើ​ក្នុង​​ផ្ទះ​របស់​អ្នក +Comment[kn]=ನೆಲೆ ಕೋಶದಲ್ಲಿ ಖಾಲಿ ಸ್ಥಳವು ಇದಕ್ಕಿಂತ ಕಡಿಮೆಯಾದರೆ ಎಚ್ಚರಿಸುತ್ತದೆ +Comment[ko]=홈 폴더에 공간이 없을 때 알려 줍니다 +Comment[lt]=Įspėja, kai namų aplanke baigiasi laisva vieta +Comment[lv]=Brīdina, kad mājas mapē beidzas brīvā vieta +Comment[mr]=तुमच्या मुख्य संचयीकेतील जागा संपत आल्याची सूचना देतो +Comment[nb]=Varsler når det er lite plass igjen i hjemmemappa +Comment[nds]=Wohrschoen bi to minn free Ruum binnen Dien Tohuusorner +Comment[nl]=Geeft een waarschuwing bij een lage stand van de vrije ruimte voor uw persoonlijke map +Comment[nn]=Varslar når det er lite plass i heimemappa +Comment[pa]=ਚੇਤਾਵਨੀ ਦਿਉ, ਜਦੋਂ ਤੁਹਾਡੇ ਘਰ ਫੋਲਡਰ ਉੱਤੇ ਥਾਂ ਖਤਮ ਹੋ ਰਹੀ ਹੋਵੇ +Comment[pl]=Ostrzega, kiedy zaczyna brakować miejsca w katalogu domowym +Comment[pt]=Avisa de estiver com falta de espaço na sua pasta pessoal +Comment[pt_BR]=Avisa quando ficar sem espaço na sua pasta pessoal +Comment[ro]=Atenționează cînd spațiul de stocare din dosarul acasă este pe cale să se termine +Comment[ru]=Предупреждает о нехватке дискового пространства в домашней папке +Comment[si]=ඔබගේ නිවාස බහාලුමේ ඉඩ අඩුවෙන් ධාවනය වෙන විට ඇනතුරු අඟවයි +Comment[sk]=Upozorňuje, keď dochádza voľné miesto v domovskom priečinku +Comment[sl]=Opozori, ko v domači mapi primanjkuje prostora +Comment[sr]=Упозорава када вам понестаје простора у домаћој фасцикли +Comment[sr@ijekavian]=Упозорава када вам понестаје простора у домаћој фасцикли +Comment[sr@ijekavianlatin]=Upozorava kada vam ponestaje prostora u domaćoj fascikli +Comment[sr@latin]=Upozorava kada vam ponestaje prostora u domaćoj fascikli +Comment[sv]=Varnar när utrymmet i hemkatalogen håller på att ta slut +Comment[th]=เตือนเมื่อพื้นที่ในโฟลเดอร์บ้านเหลือน้อย +Comment[tr]=Ev dizininizde boş alan azaldığı zaman uyarır +Comment[ug]=ماكان قىسقۇچىڭىزدىكى دىسكا بوشلۇقى ئاز قالغاندا ئەسكەرتىدۇ +Comment[uk]=Попереджає, якщо у домашній теці залишається мало місця +Comment[vi]=Cảnh báo khi sắp hết không gian cho thư mục chính của bạn +Comment[wa]=Advierti cwand i gn a cåzu pupont d' plaece dins vosse ridant måjhon +Comment[x-test]=xxWarns when running out of space on your home folderxx +Comment[zh_CN]=在您主目录磁盘空间过低时发出警告 +Comment[zh_TW]=當您的家目錄剩餘空間快不足時警告您 +Type=Service +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=freespacenotifier +X-KDE-DBus-ModuleName=freespacenotifier +X-KDE-Kded-autoload=true diff --git a/freespacenotifier/freespacenotifier.h b/freespacenotifier/freespacenotifier.h new file mode 100644 index 00000000..7e9bed53 --- /dev/null +++ b/freespacenotifier/freespacenotifier.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + Copyright (c) 2009 Ivo Anjo + + 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. If not, see . +*/ + +#ifndef _FREESPACENOTIFIER_H_ +#define _FREESPACENOTIFIER_H_ + +#include +#include + +#include + +class FreeSpaceNotifier +: public QObject +{ + Q_OBJECT + public: + FreeSpaceNotifier( QObject* parent = NULL ); + virtual ~FreeSpaceNotifier(); + private slots: + void checkFreeDiskSpace(); + void resetLastAvailable(); + void openFileManager(); + void showConfiguration(); + void cleanupNotification(); + void configDialogClosed(); + private: + QTimer timer; + QTimer* lastAvailTimer; + KNotification *notification; + qint64 lastAvail; // used to suppress repeated warnings when available space hasn't changed + + void disableFSNotifier(); + bool dbusError( QDBusInterface &iface ); +}; + +#endif diff --git a/freespacenotifier/freespacenotifier.kcfg b/freespacenotifier/freespacenotifier.kcfg new file mode 100644 index 00000000..51e02b3d --- /dev/null +++ b/freespacenotifier/freespacenotifier.kcfg @@ -0,0 +1,19 @@ + + + + + + + 200 + 1 + 100000 + + + + 1 + + + diff --git a/freespacenotifier/freespacenotifier.notifyrc b/freespacenotifier/freespacenotifier.notifyrc new file mode 100644 index 00000000..0b86e25c --- /dev/null +++ b/freespacenotifier/freespacenotifier.notifyrc @@ -0,0 +1,423 @@ +[Global] +IconName=drive-harddisk +Comment=KDE Free Space Notifier Daemon +Comment[ar]=مراقب كدي لمنبه المساحة الحرّة +Comment[ast]=Degorriu de notificaciones d'espaciu llibre de KDE +Comment[bg]=Демон на KDE за свободно пространство +Comment[bn]=কে.ডি.ই. ফ্রী স্পেস বিজ্ঞপ্তি ডিমন +Comment[bs]=KDE‑ov demon izveštavača o slobodnom prostoru +Comment[ca]=Dimoni de notificacions d'espai lliure del KDE +Comment[ca@valencia]=Dimoni de notificacions d'espai lliure del KDE +Comment[cs]=Upozorňovací démon volného místa KDE +Comment[da]=KDE dæmon til bekendtgørelse om ledig plads +Comment[de]=KDE-Dienst für Speicherplatzbenachrichtigung +Comment[el]=Δαίμονας ειδοποιήσεων ελευθέρου χώρου του KDE +Comment[en_GB]=KDE Free Space Notifier Dæmon +Comment[es]=Demonio de notificaciones de espacio libre de KDE +Comment[et]=KDE vaba ruumi teavitamise deemon +Comment[eu]=KDEren leku askea jakinarazteko daimona +Comment[fi]=KDE:n vapaan tilan ilmoitustaustaprosessi +Comment[fr]=Démon de notification d'espace libre de KDE +Comment[ga]=Fógróir Spáis Shaoir KDE +Comment[gl]=Daemon notificador do espazo libre de KDE +Comment[he]=KDE Free Space Notifier Daemon +Comment[hi]=केडीई खाली स्थान सूचना डेमन +Comment[hr]=KDE-ov servis za obavještavanje o slobodnom prostoru +Comment[hu]=KDE szabad hely értesítő szolgáltatás +Comment[ia]=Demone de notification de spatio libere de KDE +Comment[id]=Jurik Notifikasi RUang Kosong KDE +Comment[is]=KDE tilkynningaþjónn fyrir laust pláss +Comment[it]=Demone di notifica dello spazio libero di KDE +Comment[ja]=KDE 空き領域デーモン +Comment[kk]=KDE-нің бос орын туралы құлақтандыру қызметі +Comment[km]=ដេមិន​​ជូន​ដំណឹង​​ទំហំ​ទំនេរ​របស់ KDE +Comment[kn]=ಕೆಡಿಇ ಖಾಲಿ ಜಾಗ ಸೂಚನಾ ನೇಪಥಿಕ (ಡೀಮನ್) +Comment[ko]=KDE 남은 공간 알림 데몬 +Comment[lt]=KDE laisvos vietos pranešimų tarnyba +Comment[lv]=KDE brīvās vietas paziņošanas dēmons +Comment[ml]=കെഡിഇയിലെ ലഭ്യമായ സ്ഥലം അറിയിയ്ക്കുന്നതിനുള്ള നിരന്തര പ്രവൃത്തി +Comment[mr]=केडीई मोकळी जागा निदर्शक डीमन +Comment[nb]=KDEs varslingsdaemon for ledig plass +Comment[nds]=KDE-Dämoon för Freeruumbescheden +Comment[nl]=KDE-daemon voor het melden van vrije ruimte +Comment[nn]=KDE-varsel om lite plass +Comment[pa]=KDE ਖਾਲੀ ਥਾਂ ਨੋਟੀਫਿਕੇਸ਼ਨ ਡੈਮਨ +Comment[pl]=Demon powiadomień o wolnym miejscu KDE +Comment[pt]=Servidor de Notificação de Espaço Livre do KDE +Comment[pt_BR]=Serviço de notificação de espaço livre do KDE +Comment[ro]=Demon de notificare KDE a spațiului liber +Comment[ru]=Служба уведомлений о свободном месте на диске +Comment[si]=KDE හිස් ඉඩ දැනුම්දීමේ ඩීමනය +Comment[sk]=Monitor voľného miesta KDE +Comment[sl]=KDE-jev obvestilnik o neporabljenem prostoru +Comment[sr]=КДЕ‑ов демон извештавача о слободном простору +Comment[sr@ijekavian]=КДЕ‑ов демон извјештавача о слободном простору +Comment[sr@ijekavianlatin]=KDE‑ov demon izvještavača o slobodnom prostoru +Comment[sr@latin]=KDE‑ov demon izveštavača o slobodnom prostoru +Comment[sv]=KDE:s demon för information om ledigt utrymme +Comment[th]=ดีมอนการแจ้งพื้นที่ว่างของ KDE +Comment[tr]=KDE Boş Alan Bildirme Servisi +Comment[ug]=KDE بىكار بوشلۇق خەۋەرچى نازارەتچىسى +Comment[uk]=Фонова служба сповіщення про переповнення диска KDE +Comment[vi]=Trình nền thông báo không gian trống KDE +Comment[wa]=Démon KDE notifieu del plaece di libe +Comment[x-test]=xxKDE Free Space Notifier Daemonxx +Comment[zh_CN]=KDE 空闲空间通知守护程序 +Comment[zh_TW]=KDE 剩餘空間通知伺服程式 +Name=Low Disk Space +Name[ar]=مساحة القرص منخفضة +Name[ast]=Pocu espaciu en discu +Name[bg]=Дисковото пространство е твърде малко +Name[bn]=ডিস্ক-এ জায়গা কম +Name[bs]=Malo prostora na disku +Name[ca]=Espai escàs al disc +Name[ca@valencia]=Espai escàs al disc +Name[cs]=Málo místa na disku +Name[da]=Lav diskplads +Name[de]=Wenig Speicherplatz +Name[el]=Χαμηλή χωρητικότητα δίσκου +Name[en_GB]=Low Disk Space +Name[es]=Poco espacio en disco +Name[et]=Kettaruumi napib +Name[eu]=Leku gutxi diskoan +Name[fi]=Vähäinen levytila +Name[fr]=Espace disque faible +Name[ga]=Easpa Spáis ar an Diosca +Name[gl]=Pouco espazo no disco +Name[he]=שטח מועט פנוי בדיסק +Name[hi]=डिस्क जगह कम +Name[hr]=Malo prostora na disku +Name[hu]=Kevés a lemezterület +Name[ia]=Spatio de disco basse +Name[id]=Ruang Kosong Tinggal Sedikit +Name[is]=Lítið diskpláss +Name[it]=Poco spazio su disco +Name[ja]=ディスクの空き領域が少ないです +Name[kk]=Дискіде орын тапшылығы +Name[km]=ទំហំ​ថាស​ទាប +Name[kn]=ಕಡಿಮೆ ಡಿಸ್ಕ್‌ ಜಾಗ +Name[ko]=디스크 공간 부족 +Name[lt]=Mažai vietos diske +Name[lv]=Maz diska vietas +Name[mai]=कम डिस्क स्थान +Name[ml]=ഡിസ്കില്‍ സഥലം കുറവാണു് +Name[mr]=डिस्कवर कमी जागा शिल्लक आहे +Name[nb]=Lite diskplass +Name[nds]=To minn free Ruum op de Fastplaat +Name[nl]=Schijf bijna vol +Name[nn]=Lite diskplass +Name[pa]=ਘੱਟ ਡਿਸਕ ਥਾਂ +Name[pl]=Mało miejsca na dysku +Name[pt]=Pouco Espaço em Disco +Name[pt_BR]=Pouco espaço em disco +Name[ro]=Spațiu pe disc scăzut +Name[ru]=Недостаточно места на диске +Name[si]=පහත් තැටි ඉඩ +Name[sk]=Nedostatok miesta na disku +Name[sl]=Prostora na disku je malo +Name[sr]=Мало простора на диску +Name[sr@ijekavian]=Мало простора на диску +Name[sr@ijekavianlatin]=Malo prostora na disku +Name[sr@latin]=Malo prostora na disku +Name[sv]=Ont om diskutrymme +Name[th]=พื้นที่ดิสก์เหลือน้อย +Name[tr]=Düşük Disk Alanı +Name[ug]=دىسكىدىكى بوشلۇق ئاز +Name[uk]=Замало місця на диску +Name[vi]=Dung lượng đĩa trống thấp +Name[wa]=Pus bråmint d' plaece sol plake +Name[x-test]=xxLow Disk Spacexx +Name[zh_CN]=低磁盘空间 +Name[zh_TW]=磁碟空間過低 + +[Context/warningnot] +Name=Warning +Name[af]=Waarskuwing +Name[ar]=إنذار +Name[as]=সতৰ্কবাণী +Name[ast]=Avisu +Name[be]=Папярэджанне +Name[be@latin]=Uvaha +Name[bg]=Предупреждение +Name[bn]=সতর্কবার্তা +Name[bn_IN]=সতর্কবার্তা +Name[bs]=Upozorenje +Name[ca]=Avís +Name[ca@valencia]=Avís +Name[cs]=Varování +Name[csb]=Bôczënk +Name[da]=Advarsel +Name[de]=Warnung +Name[el]=Προειδοποίηση +Name[en_GB]=Warning +Name[eo]=Averto +Name[es]=Aviso +Name[et]=Hoiatus +Name[eu]=Abisua +Name[fi]=Varoitus +Name[fr]=Avertissement +Name[fy]=Warskôging +Name[ga]=Rabhadh +Name[gl]=Aviso +Name[gu]=ચેતવણી +Name[he]=אזהרה +Name[hi]=चेतावनी +Name[hne]=चेतावनी +Name[hr]=Upozorenje +Name[hsb]=Kedźbu +Name[hu]=Figyelmeztetés +Name[ia]=Aviso +Name[id]=Peringatan +Name[is]=Aðvörun +Name[it]=Avviso +Name[ja]=警告 +Name[kk]=Ескерту +Name[km]=ការ​ព្រមាន +Name[kn]=ಎಚ್ಚರಿಕೆ +Name[ko]=경고 +Name[ku]=Hişyarî +Name[lt]=Dėmesio +Name[lv]=Brīdinājums +Name[mai]=चेतावनी +Name[mk]=Предупредување +Name[ml]=മുന്നറിയിപ്പു് +Name[mr]=इशारा +Name[nb]=Advarsel +Name[nds]=Wohrschoen +Name[ne]=चेतावनी +Name[nl]=Waarschuwing +Name[nn]=Åtvaring +Name[oc]=Alèrta +Name[or]=ଚେତାବନୀ +Name[pa]=ਚੇਤਾਵਨੀ +Name[pl]=Ostrzeżenie +Name[pt]=Aviso +Name[pt_BR]=Aviso +Name[ro]=Atenționare +Name[ru]=Предупреждение +Name[se]=Várrehus +Name[si]=අවවාදය +Name[sk]=Varovanie +Name[sl]=Opozorilo +Name[sr]=Упозорење +Name[sr@ijekavian]=Упозорење +Name[sr@ijekavianlatin]=Upozorenje +Name[sr@latin]=Upozorenje +Name[sv]=Varning +Name[ta]=எச்சரிக்கை +Name[te]=హెచ్చరిక +Name[tg]=Огоҳинома +Name[th]=คำเตือน +Name[tr]=Uyarı +Name[ug]=ئاگاھلاندۇرۇش +Name[uk]=Попередження +Name[uz]=Ogohnoma +Name[uz@cyrillic]=Огоҳнома +Name[vi]=Cảnh báo +Name[wa]=Adviertixhmint +Name[x-test]=xxWarningxx +Name[zh_CN]=警告 +Name[zh_TW]=警告 +Comment=Used for warning notifications +Comment[ar]=يُستخدم للتنبيهات التحذيرية +Comment[ast]=Usáu pa notificaciones d'avisu +Comment[be@latin]=Dla aścierahalnych paviedamleńniaŭ +Comment[bg]=Използва се за предупреждения +Comment[bn]=সতর্কীকরণ বিজ্ঞপ্তির জন্য ব্যবহৃত হয় +Comment[bs]=Koristi se za obavještenja o upozorenjima +Comment[ca]=S'usa per a les notificacions d'avís +Comment[ca@valencia]=S'usa per a les notificacions d'avís +Comment[cs]=Použito pro varování a upozornění +Comment[da]=Bruges til advarselsbekendtgørelser +Comment[de]=Verwendet für Warnmeldungen +Comment[el]=Χρησιμοποιείται για τις προειδοποιήσεις +Comment[en_GB]=Used for warning notifications +Comment[eo]=Uzita por avertmesaĝoj +Comment[es]=Usado para notificaciones de advertencia +Comment[et]=Hoiatuste jaoks +Comment[eu]=Abisu-jakinarazpenetarako erabiltzen da +Comment[fi]=Käytetään varoitusilmoituksiin +Comment[fr]=Utilisé pour les notifications d'avertissements +Comment[fy]=Brûkt faor warskôging notifikaasjes +Comment[ga]=Úsáidte do rabhaidh +Comment[gl]=Emprégase para as notificacións de aviso +Comment[gu]=ચેતવણી નોંધણીઓ આપવા માટે વપરાય છે +Comment[he]=משמש להתרעות אזהרה +Comment[hi]=चेतावनियाँ देने के लिए उपयोग में लिया जाता है +Comment[hne]=चेतावनी सूचना बर उपयोग होथे +Comment[hr]=Korišten za upozoravajuće obavijesti +Comment[hu]=Kezelőprogram figyelmeztető üzenetekhez +Comment[ia]=Usate pro notificationes de avisos +Comment[id]=Digunakan untuk notifikasi peringatan +Comment[is]=Notað fyrir aðvaranir +Comment[it]=Usato per notifiche di avviso +Comment[ja]=警告の通知に使用 +Comment[kk]=Ескерту хабарларға қолданылады +Comment[km]=បានប្រើ​សម្រាប់​ការ​ជូន​ព្រមាន +Comment[kn]=ಎಚ್ಚರಿಕೆ ಸೂಚನೆಗಳಿಗೆ ಬಳಸಲಾಗುತ್ತದೆ +Comment[ko]=경고 알림에 사용됨 +Comment[lt]=Naudojama perspėjimams +Comment[lv]=Izmanto brīdinājumu paziņojumiem +Comment[ml]=താക്കീത് അറിയിപ്പുകള്‍ക്കായി ഉപയോഗിക്കുന്നു +Comment[mr]=इशारा सूचना करिता वापरले जाते +Comment[nb]=Brukt til varselsmeldinger +Comment[nds]=Bi Wohrschoen bruukt +Comment[nl]=Wordt gebruikt voor waarschuwingsmeldingen +Comment[nn]=Er brukt til åtvaringsvarsel +Comment[or]=ଚେତାବନୀ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଇଁ ବ୍ୟବହୃତ ହୋଇଥାଏ +Comment[pa]=ਚੇਤਾਵਨੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ +Comment[pl]=Używane do ostrzeżeń +Comment[pt]=Usado para as notificações de aviso +Comment[pt_BR]=Usado para as notificações de aviso +Comment[ro]=Utilizat pentru notificări de avertizare +Comment[ru]=Используется для системных уведомлений +Comment[si]=අවවාද පණිවුඩ සඳහා යොදාගනී +Comment[sk]=Používa sa pre varovné upozornenia +Comment[sl]=Uporabljeno za obvestila z opozorili +Comment[sr]=Користи се за позорна обавештења +Comment[sr@ijekavian]=Користи се за позорна обавјештења +Comment[sr@ijekavianlatin]=Koristi se za pozorna obavještenja +Comment[sr@latin]=Koristi se za pozorna obaveštenja +Comment[sv]=Används för varningsmeddelanden +Comment[ta]=Used for warning notifications +Comment[te]=హెచ్చరిక నోటీసుల కొరకు వుపయోగించబడింది +Comment[tg]=Используется для надписей под значками на рабочем столе. +Comment[th]=ใช้สำหรับการแจ้งเตือนให้ทราบ +Comment[tr]=Uyarı bildirimleri için kullanılır +Comment[ug]=ئاگاھلاندۇرۇش ئۇقتۇرۇشلىرى ئۈچۈن ئىشلىتىلىدۇ. +Comment[uk]=Використовується для попереджень +Comment[vi]=Sử dụng cho thông tin cảnh báo +Comment[wa]=Eployî po des notifiaedjes d' adviertixhmint +Comment[x-test]=xxUsed for warning notificationsxx +Comment[zh_CN]=用于发出警告通知 +Comment[zh_TW]=用於警告通知 + +[Event/freespacenotif] +Name=Running low on disk space +Name[ar]=قارب القرص على الامتلاء +Name[ast]=Queda poco espaciu en discu +Name[bg]=Дисковото пространство е твърде малко +Name[bn]=ডিস্ক-এ বেশী জায়গা বাকি নেই +Name[bs]=Ponestaje prostora na disku +Name[ca]=S'està exhaurint l'espai del disc +Name[ca@valencia]=S'està exhaurint l'espai del disc +Name[cs]=Dochází místo na disku +Name[da]=Ved at løbe tør for diskplads +Name[de]=Speicherplatz wird knapp +Name[el]=Τρέχον χωρητικότητα δίσκου χαμηλή +Name[en_GB]=Running low on disk space +Name[es]=Queda poco espacio en disco +Name[et]=Kettaruumi napib +Name[eu]=Leku gutxi gelditzen da diskoan +Name[fi]=Levytila alkaa olla lopussa +Name[fr]=L'espace disque commence à manquer +Name[ga]=Tá an diosca ag éirí lán +Name[gl]=Esgotando o espazo no disco +Name[he]=השטח הפנוי בדיסק מועט +Name[hi]=डिस्क में जगह कम हो गया है +Name[hr]=Ponestajanje diskovnog prostora +Name[hu]=Kezd fogyni a lemezterület +Name[ia]=Exhauriente le spatio de disco +Name[id]=Berjalan pada ruang kosong yang tinggal sedikit +Name[is]=Lítið pláss eftir á diski +Name[it]=Lo spazio su disco si sta esaurendo +Name[ja]=ディスクの空き領域が少ないです +Name[kk]=Диск орын тапшылығы +Name[km]=ដំណើរការ​ទាប​លើ​ទំហំ​ថាស +Name[kn]=ಮುದ್ರಿಕೆಯಲ್ಲಿ (ಡಿಸ್ಕ್) ಜಾಗ ಕಮ್ಮಿಯಾಗುತ್ತಿದೆ. +Name[ko]=디스크 공간 거의 없음 +Name[lt]=Diske liko mažai vietos +Name[lv]=Ir palicis maz brīvas vietas +Name[mr]=डिस्कवर कमी जागा शिल्लक आहे +Name[nb]=Det er nå lite diskplass +Name[nds]=De free Ruum op de Fastplaat geiht op de Neeg. +Name[nl]=Bijna geen vrije schijfruimte meer +Name[nn]=Det er lite diskplass att +Name[pa]=ਡਿਸਕ ਥਾਂ ਖਤਮ ਹੋ ਰਹੀ ਹੈ +Name[pl]=Zaczyna brakować miejsca na dysku +Name[pt]=Pouco espaço livre em disco +Name[pt_BR]=Pouco espaço livre em disco +Name[ro]=Spațiu pe disc este scăzut +Name[ru]=Недостаточно места на диске +Name[si]=පහත් තැටි ඉඩෙන් ධාවනය කරමි +Name[sk]=Dochádza voľné miesto na disku +Name[sl]=Razpoložljivega prostora na disku je malo +Name[sr]=Понестаје простора на диску +Name[sr@ijekavian]=Понестаје простора на диску +Name[sr@ijekavianlatin]=Ponestaje prostora na disku +Name[sr@latin]=Ponestaje prostora na disku +Name[sv]=Diskutrymmet håller på att ta slut +Name[th]=พื้นที่ดิสก์กำลังเหลือน้อย +Name[tr]=Düşük disk alanı üzerinde çalışıyor +Name[ug]=دىسكىدىكى بوشلۇق ئاز ھالەتتە ئىجرا قىلىۋاتىدۇ +Name[uk]=Замало місця на диску +Name[vi]=Không gian đĩa trống sắp hết +Name[wa]=Gn a pus bråmint d' plaece sol plake +Name[x-test]=xxRunning low on disk spacexx +Name[zh_CN]=磁盘空间过低 +Name[zh_TW]=磁碟空間快用完了 +Comment=You are running low on disk space +Comment[ar]=إن مساحة التخزين المتوفرة على القرص توشك على النفاذ +Comment[ast]=Tas quedando ensin espaciu en discu +Comment[bg]=Дисковото Ви пространство е твърде малко +Comment[bn]=আপনার ডিস্ক-এ বেশী জায়গা বাকি নেই +Comment[bs]=Ponestaje vam prostora na disku +Comment[ca]=L'espai del disc s'està exhaurint +Comment[ca@valencia]=L'espai del disc s'està exhaurint +Comment[cs]=Dochází vám místo na disku +Comment[da]=Du er ved at løbe tør for diskplads +Comment[de]=Ihr freier Speicherplatz wird knapp +Comment[el]=Η τρέχουσα χωρητικότητα του δίσκου σας είναι χαμηλή +Comment[en_GB]=You are running low on disk space +Comment[es]=Se está quedando sin espacio en disco +Comment[et]=Kettaruumi on vähe järele jäänud +Comment[eu]=Diskoan lekurik gabe gelditzen ari zara +Comment[fi]=Levytilasi alkaa loppua +Comment[fr]=Vous manquez d'espace disque +Comment[ga]=Tá an diosca ag éirí lán +Comment[gl]=Está a quedar sen espazo no disco +Comment[he]=השטח הפנוי בדיסק מועט +Comment[hi]=आप कम डिस्क जगह पर चल रहे हैं +Comment[hr]=Ponestaje vam diskovnog prostora +Comment[hu]=A lemezterület kezd elfogyni +Comment[ia]=Tu es exhauriente le spatio de disco +Comment[id]=Anda berjalan pada ruang kosong yang tinggal sedikit +Comment[is]=Þú ert að verða uppiskroppa með diskpláss +Comment[it]=Stai esaurendo lo spazio su disco +Comment[ja]=ディスクの空き領域が少なくなりました +Comment[kk]=Диск орын тапшылықтасыз +Comment[km]=អ្នក​កំពុង​ដំណើរការ​ទាប​​លើ​ទំហំ​ថាស +Comment[kn]=ನಿಮ್ಮಲ್ಲಿ ಕಡಿಮೆ ಡಿಸ್ಕ್‍ ಸ್ಥಳವಿದೆ +Comment[ko]=디스크 공간이 거의 없습니다 +Comment[lt]=Jūsų diske liko mažai vietos +Comment[lv]=Uz diska ir maz brīvas vietas +Comment[mr]=तुमच्या डिस्कवर कमी जागा शिल्लक आहे +Comment[nb]=Du har lite diskplass igjen +Comment[nds]=De free Ruum op Dien Fastplaat geiht op de Neeg. +Comment[nl]=U hebt bijna geen vrije schijfruimte meer +Comment[nn]=Du har lite diskplass att +Comment[pa]=ਤੁਹਾਡੇ ਕੋਲ ਡਿਸਕ ਖਾਲੀ ਥਾਂ ਘੱਟ ਰਹੀ ਹੈ +Comment[pl]=Zaczyna brakować miejsca na dysku +Comment[pt]=Está a ficar com pouco espaço livre em disco +Comment[pt_BR]=Você tem pouco espaço livre em disco +Comment[ro]=Spațiul dumneavoastră de stocare este pe cale să se termine +Comment[ru]=На диске осталось мало свободного места +Comment[si]=ඔබගේ තැටි ඉඩ අඩු වෙමින් පවතී +Comment[sk]=Dochádza vám voľné miesto na disku +Comment[sl]=Na disku imate malo razpoložljivega prostora +Comment[sr]=Понестаје вам простора на диску +Comment[sr@ijekavian]=Понестаје вам простора на диску +Comment[sr@ijekavianlatin]=Ponestaje vam prostora na disku +Comment[sr@latin]=Ponestaje vam prostora na disku +Comment[sv]=Diskutrymmet håller på att ta slut +Comment[th]=คุณกำลังทำงานด้วยพื้นที่ดิสก์ที่เหลือน้อย +Comment[tr]=Düşük disk alanı üzerinde çalışıyorsunuz +Comment[ug]=دىسكىدىكى بوشلۇق ئاز ھالەتتە ئىجرا قىلىۋاتىسىز +Comment[uk]=На вашому диску залишилося замало місця +Comment[vi]=Bạn đang dùng sắp hết không gian đĩa +Comment[wa]=Vos estoz k' n' a pus bråmint d' plaece sol plake +Comment[x-test]=xxYou are running low on disk spacexx +Comment[zh_CN]=您现在的磁盘空间过低 +Comment[zh_TW]=您的磁碟空間快用完了 +Contexts=warningnot +Action=Popup diff --git a/freespacenotifier/freespacenotifier_prefs_base.ui b/freespacenotifier/freespacenotifier_prefs_base.ui new file mode 100644 index 00000000..7f93d49c --- /dev/null +++ b/freespacenotifier/freespacenotifier_prefs_base.ui @@ -0,0 +1,91 @@ + + + freespacenotifier_prefs_base + + + + 0 + 0 + 320 + 217 + + + + + + + Enable low disk space warning + + + true + + + + + + + Warn when free space is below: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + MiB + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + kcfg_enableNotification + toggled(bool) + kcfg_minimumSpace + setEnabled(bool) + + + 114 + 15 + + + 272 + 44 + + + + + kcfg_enableNotification + toggled(bool) + label_minimumSpace + setEnabled(bool) + + + 114 + 15 + + + 114 + 44 + + + + + diff --git a/freespacenotifier/module.cpp b/freespacenotifier/module.cpp new file mode 100644 index 00000000..abbc3f11 --- /dev/null +++ b/freespacenotifier/module.cpp @@ -0,0 +1,36 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + Copyright (c) 2009 Ivo Anjo + + 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. If not, see . +*/ + +#include "module.h" + +#include +#include + +K_PLUGIN_FACTORY(FreeSpaceNotifierModuleFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(FreeSpaceNotifierModuleFactory("freespacenotifier")) + + +FreeSpaceNotifierModule::FreeSpaceNotifierModule(QObject* parent, const QList&) + : KDEDModule(parent) +{ +} + +#include "module.moc" diff --git a/freespacenotifier/module.h b/freespacenotifier/module.h new file mode 100644 index 00000000..37592c9e --- /dev/null +++ b/freespacenotifier/module.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + Copyright (c) 2009 Ivo Anjo + + 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. If not, see . +*/ + +#ifndef MODULE_H +#define MODULE_H + +#include +#include +#include + +#include "freespacenotifier.h" + +class FreeSpaceNotifierModule + : public KDEDModule + { + Q_OBJECT + public: + FreeSpaceNotifierModule(QObject* parent, const QList&); + private: + FreeSpaceNotifier notifier; + }; + +#endif diff --git a/freespacenotifier/settings.kcfgc b/freespacenotifier/settings.kcfgc new file mode 100644 index 00000000..3997ce98 --- /dev/null +++ b/freespacenotifier/settings.kcfgc @@ -0,0 +1,6 @@ +# Code generation options for kconfig_compiler +File=freespacenotifier.kcfg +ClassName=FreeSpaceNotifierSettings +Singleton=true +Mutators=minimumSpace,enableNotification +# will create the necessary code for setting those variables diff --git a/kcheckpass/CMakeLists.txt b/kcheckpass/CMakeLists.txt new file mode 100644 index 00000000..375e4f8e --- /dev/null +++ b/kcheckpass/CMakeLists.txt @@ -0,0 +1,31 @@ + +include_directories( ${UNIXAUTH_INCLUDE_DIRS} ) +check_include_files(paths.h HAVE_PATHS_H) +configure_file (config-kcheckpass.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcheckpass.h ) + +set(kcheckpass_SRCS + kcheckpass.h + kcheckpass.c + checkpass_etcpasswd.c + checkpass_pam.c + checkpass_shadow.c + checkpass_osfc2passwd.c + checkpass_aix.c +) + +kde4_add_executable(kcheckpass NOGUI ${kcheckpass_SRCS}) + +if (KDE4_ENABLE_FPIE) + macro_add_compile_flags(kcheckpass ${KDE4_CXX_FPIE_FLAGS}) + macro_add_link_flags(kcheckpass ${KDE4_PIE_LDFLAGS}) +endif (KDE4_ENABLE_FPIE) + +macro_add_compile_flags(kcheckpass -U_REENTRANT) +target_link_libraries(kcheckpass ${KDE4_KDEFAKES_LIBS} ${UNIXAUTH_LIBRARIES} ${SOCKET_LIBRARIES}) +install(TARGETS kcheckpass DESTINATION ${LIBEXEC_INSTALL_DIR}) +install(CODE " + set(KCP_PATH \"\$ENV{DESTDIR}${LIBEXEC_INSTALL_DIR}/kcheckpass\") + EXECUTE_PROCESS(COMMAND sh -c \"chown root '\${KCP_PATH}' && chmod +s '\${KCP_PATH}'\") +") + +#EXTRA_DIST = README diff --git a/kcheckpass/README b/kcheckpass/README new file mode 100644 index 00000000..ba7cb471 --- /dev/null +++ b/kcheckpass/README @@ -0,0 +1,50 @@ +The KCheckPass authentication software: +----------------------------------------- + +KCheckPass is KDE's authentication program. It is meant to be +used by any software in need of user authentication, most +notably screensavers. + +It enhances security be the following means: + +- It's only a small program, which is hopefully simple enough to + allow it to be SUID root. Setting it to SUID root is necessary + on Shadow Password systems. +- No other program in need of user authentication, must be + SUID root. +- It provides a single implementation to check passwords. So one + only must take a closer look at KCheckPass to ensure password + security. It's much easier for programs using KCheckPass to + preserve security. + + +Technique: +---------- +KCheckPass is a simple password checker. Just invoke and +send it the password on stdin. + +If the password was accepted, the program exits with 0; +if it was rejected, it exits with 1. Any other exit +code signals an error. + + + +Compilation hints: +------------------ +Compile with -DHAVE_VSYSLOG if you have vsyslog(). +Compile with -DHAVE_PAM if you have a PAM system, and link with -lpam -ldl + (If libdl is present). +Compile with -DHAVE_SHADOW if you have a shadow password system. + +Copyright, Author and License notice: +------------------------------------- +Copyright (C) 1998, Caldera, Inc. +Released under the GNU General Public License + +Olaf Kirch General Framework and PAM support +Christian Esken Shadow and /etc/passwd support + +Some parts were taken from kscreensaver's passwd.cpp + +Currently this Software is maintained by Oswald Buddenhagen . +Please send new authentication modules (checkpass_*.cpp) to me. diff --git a/kcheckpass/checkpass_aix.c b/kcheckpass/checkpass_aix.c new file mode 100644 index 00000000..8f06cfe6 --- /dev/null +++ b/kcheckpass/checkpass_aix.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001 Reza Arbab + * Copyright (c) 2003 Oswald Buddenhagen + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "kcheckpass.h" + +#ifdef HAVE_AIX_AUTH +#include +#include +#include +#include + +/* + * The AIX builtin authenticate() uses whichever method the system + * has been configured for. (/etc/passwd, DCE, etc.) + */ +int authenticate(const char *, const char *, int *, char **); + +AuthReturn Authenticate(const char *method, + const char *login, char *(*conv) (ConvRequest, const char *)) +{ + int result; + int reenter; /* Tells if authenticate is done processing or not. */ + char *passwd; + char *msg; /* Contains a prompt message or failure reason. */ + + if (!strcmp(method, "classic")) { + + if (!(passwd = conv(ConvGetHidden, 0))) + return AuthAbort; + + if ((result = authenticate(login, passwd, &reenter, &msg))) { + if (msg) { + conv(ConvPutError, msg); + free(msg); + } + dispose(passwd); + return AuthBad; + } + if (reenter) { + char buf[256]; + snprintf(buf, sizeof(buf), "More authentication data requested: %s\n", msg); + conv(ConvPutError, buf); + free(msg); + dispose(passwd); + return result == ENOENT || result == ESAD ? AuthBad : AuthError; + } + dispose(passwd); + return AuthOk; + + } else if (!strcmp(method, "generic")) { + + for (passwd = 0;;) { + if ((result = authenticate(login, passwd, &reenter, &msg))) { + if (msg) { + conv(ConvPutError, msg); + free(msg); + } + if (passwd) + dispose(passwd); + return result == ENOENT || result == ESAD ? AuthBad : AuthError; + } + if (passwd) + dispose(passwd); + if (!reenter) + break; + passwd = conv(ConvGetHidden, msg); + free(msg); + if (!passwd) + return AuthAbort; + } + return AuthOk; + + } else + return AuthError; + +} + +#endif diff --git a/kcheckpass/checkpass_etcpasswd.c b/kcheckpass/checkpass_etcpasswd.c new file mode 100644 index 00000000..e261b7c4 --- /dev/null +++ b/kcheckpass/checkpass_etcpasswd.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1998 Christian Esken + * Copyright (c) 2003 Oswald Buddenhagen + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 1998, Christian Esken + */ + +#include "kcheckpass.h" + +#ifdef HAVE_ETCPASSWD + +/******************************************************************* + * This is the authentication code for /etc/passwd passwords + *******************************************************************/ + +#include +#include + +AuthReturn Authenticate(const char *method, + const char *login, char *(*conv) (ConvRequest, const char *)) +{ + struct passwd *pw; + char *passwd; + char *crpt_passwd; + + if (strcmp(method, "classic")) + return AuthError; + + /* Get the password entry for the user we want */ + if (!(pw = getpwnam(login))) + return AuthBad; + + if (!*pw->pw_passwd) + return AuthOk; + + if (!(passwd = conv(ConvGetHidden, 0))) + return AuthAbort; + + if ((crpt_passwd = crypt(passwd, pw->pw_passwd)) && !strcmp(pw->pw_passwd, crpt_passwd)) { + dispose(passwd); + return AuthOk; /* Success */ + } + dispose(passwd); + return AuthBad; /* Password wrong or account locked */ +} + +#endif diff --git a/kcheckpass/checkpass_osfc2passwd.c b/kcheckpass/checkpass_osfc2passwd.c new file mode 100644 index 00000000..d1812336 --- /dev/null +++ b/kcheckpass/checkpass_osfc2passwd.c @@ -0,0 +1,204 @@ +/* + * + * Copyright (C) 1999 Mark Davies + * Copyright (C) 2003 Oswald Buddenhagen + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "kcheckpass.h" + +#ifdef HAVE_OSF_C2_PASSWD + +static char *osf1c2crypt(const char *pw, char *salt); +static int osf1c2_getprpwent(char *p, char *n, int len); + +/******************************************************************* + * This is the authentication code for OSF C2 security passwords + *******************************************************************/ + +#include +#include +#include + +AuthReturn Authenticate(const char *method, + const char *login, char *(*conv) (ConvRequest, const char *)) +{ + char *passwd; + char *crpt_passwd; + char c2passwd[256]; + + if (strcmp(method, "classic")) + return AuthError; + + if (!osf1c2_getprpwent(c2passwd, login, sizeof(c2passwd))) + return AuthBad; + + if (!*c2passwd) + return AuthOk; + + if (!(passwd = conv(ConvGetHidden, 0))) + return AuthAbort; + + if ((crpt_passwd = osf1c2crypt(passwd, c2passwd)) && !strcmp(c2passwd, crpt_passwd)) { + dispose(passwd); + return AuthOk; /* Success */ + } + dispose(passwd); + return AuthBad; /* Password wrong or account locked */ +} + + +/* +The following code was lifted from the file osfc2.c from the ssh 1.2.26 +distribution. Parts of the code that were not needed by kcheckpass +(notably the osf1c2_check_account_and_terminal() function and the code +to set the external variable days_before_password_expires have been +removed). The original copyright from the osfc2.c file is included +below. +*/ + +/* + +osfc2.c + +Author: Christophe Wolfhugel + +Copyright (c) 1995 Christophe Wolfhugel + +Free use of this file is permitted for any purpose as long as +this copyright is preserved in the header. + +This program implements the use of the OSF/1 C2 security extensions +within ssh. See the file COPYING for full licensing information. + +*/ + +#include +#include +#include + +static int c2security = -1; +static int crypt_algo; + +static void +initialize_osf_security(int ac, char **av) +{ + FILE *f; + char buf[256]; + char siad[] = "siad_ses_init="; + + if (access(SIAIGOODFILE, F_OK) == -1) + { + /* Broken OSF/1 system, better don't run on it. */ + fprintf(stderr, SIAIGOODFILE); + fprintf(stderr, " does not exist. Your OSF/1 system is probably broken\n"); + exit(1); + } + if ((f = fopen(MATRIX_CONF, "r")) == NULL) + { + /* Another way OSF/1 is probably broken. */ + fprintf(stderr, "%s unreadable. Your OSF/1 system is probably broken.\n" + + MATRIX_CONF); + exit(1); + } + + /* Read matrix.conf to check if we run C2 or not */ + while (fgets(buf, sizeof(buf), f) != NULL) + { + if (strncmp(buf, siad, sizeof(siad) - 1) == 0) + { + if (strstr(buf, "OSFC2") != NULL) + c2security = 1; + else if (strstr(buf, "BSD") != NULL) + c2security = 0; + break; + } + } + fclose(f); + if (c2security == -1) + { + fprintf(stderr, "C2 security initialization failed : could not determine security level.\n"); + exit(1); + } + if (c2security == 1) + set_auth_parameters(ac, av); +} + + +static int +osf1c2_getprpwent(char *p, char *n, int len) +{ + time_t pschg, tnow; + + if (c2security == 1) + { + struct es_passwd *es; + struct pr_passwd *pr = getprpwnam(n); + if (pr) + { + strlcpy(p, pr->ufld.fd_encrypt, len); + crypt_algo = pr->ufld.fd_oldcrypt; + + tnow = time(NULL); + if (pr->uflg.fg_schange == 1) + pschg = pr->ufld.fd_schange; + else + pschg = 0; + if (pr->uflg.fg_template == 0) + { + /** default template, system values **/ + if (pr->sflg.fg_lifetime == 1) + if (pr->sfld.fd_lifetime > 0 && + pschg + pr->sfld.fd_lifetime < tnow) + return 1; + } + else /** user template, specific values **/ + { + es = getespwnam(pr->ufld.fd_template); + if (es) + { + if (es->uflg->fg_expire == 1) + if (es->ufld->fd_expire > 0 && + pschg + es->ufld->fd_expire < tnow) + return 1; + } + } + } + } + else + { + struct passwd *pw = getpwnam(n); + if (pw) + { + strlcpy(p, pw->pw_passwd, len); + return 1; + } + } + return 0; +} + +static char * +osf1c2crypt(const char *pw, char *salt) +{ + if (c2security == 1) { + return(dispcrypt(pw, salt, crypt_algo)); + } else + return(crypt(pw, salt)); +} + +#endif diff --git a/kcheckpass/checkpass_pam.c b/kcheckpass/checkpass_pam.c new file mode 100644 index 00000000..e2ccaf24 --- /dev/null +++ b/kcheckpass/checkpass_pam.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 1998 Caldera, Inc. + * Copyright (C) 2003 Oswald Buddenhagen + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcheckpass.h" + +#ifdef HAVE_PAM + +#include +#include +#include +#include + +#ifdef HAVE_PAM_PAM_APPL_H +#include +#else +#include +#endif + +struct pam_data { + char *(*conv) (ConvRequest, const char *); + int abort:1; + int classic:1; +}; + +#ifdef PAM_MESSAGE_CONST +typedef const struct pam_message pam_message_type; +typedef const void *pam_gi_type; +#else +typedef struct pam_message pam_message_type; +typedef void *pam_gi_type; +#endif + +static int +PAM_conv (int num_msg, pam_message_type **msg, + struct pam_response **resp, + void *appdata_ptr) +{ + int count; + struct pam_response *repl; + struct pam_data *pd = (struct pam_data *)appdata_ptr; + + if (!(repl = calloc(num_msg, sizeof(struct pam_response)))) + return PAM_CONV_ERR; + + for (count = 0; count < num_msg; count++) + switch (msg[count]->msg_style) { + case PAM_TEXT_INFO: + pd->conv(ConvPutInfo, msg[count]->msg); + break; + case PAM_ERROR_MSG: + pd->conv(ConvPutError, msg[count]->msg); + break; + default: + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + repl[count].resp = pd->conv(ConvGetNormal, msg[count]->msg); + break; + case PAM_PROMPT_ECHO_OFF: + repl[count].resp = + pd->conv(ConvGetHidden, pd->classic ? 0 : msg[count]->msg); + break; +#ifdef PAM_BINARY_PROMPT + case PAM_BINARY_PROMPT: + repl[count].resp = pd->conv(ConvGetBinary, msg[count]->msg); + break; +#endif + default: + /* Must be an error of some sort... */ + goto conv_err; + } + if (!repl[count].resp) { + pd->abort = 1; + goto conv_err; + } + repl[count].resp_retcode = PAM_SUCCESS; + break; + } + *resp = repl; + return PAM_SUCCESS; + + conv_err: + for (; count >= 0; count--) + if (repl[count].resp) + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + dispose(repl[count].resp); + break; +#ifdef PAM_BINARY_PROMPT + case PAM_BINARY_PROMPT: /* handle differently? */ +#endif + case PAM_PROMPT_ECHO_ON: + free(repl[count].resp); + break; + } + free(repl); + return PAM_CONV_ERR; +} + +static struct pam_data PAM_data; + +static struct pam_conv PAM_conversation = { + &PAM_conv, + &PAM_data +}; + +#ifdef PAM_FAIL_DELAY +static void +fail_delay(int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED, + void *appdata_ptr ATTR_UNUSED) +{} +#endif + + +AuthReturn Authenticate(const char *caller, const char *method, + const char *user, char *(*conv) (ConvRequest, const char *)) +{ + const char *tty; + pam_handle_t *pamh; + pam_gi_type pam_item; + const char *pam_service; + char pservb[64]; + int pam_error; + + openlog("kcheckpass", LOG_PID, LOG_AUTH); + + PAM_data.conv = conv; + if (strcmp(method, "classic")) { + sprintf(pservb, "%.31s-%.31s", caller, method); + pam_service = pservb; + } else { + /* PAM_data.classic = 1; */ + pam_service = caller; + } + pam_error = pam_start(pam_service, user, &PAM_conversation, &pamh); + if (pam_error != PAM_SUCCESS) + return AuthError; + + tty = ttyname(0); + if (!tty) + tty = getenv ("DISPLAY"); + + pam_error = pam_set_item (pamh, PAM_TTY, tty); + if (pam_error != PAM_SUCCESS) { + pam_end(pamh, pam_error); + return AuthError; + } + +# ifdef PAM_FAIL_DELAY + pam_set_item (pamh, PAM_FAIL_DELAY, (void *)fail_delay); +# endif + + pam_error = pam_authenticate(pamh, 0); + if (pam_error != PAM_SUCCESS) { + if (PAM_data.abort) { + pam_end(pamh, PAM_SUCCESS); + return AuthAbort; + } + pam_end(pamh, pam_error); + switch (pam_error) { + case PAM_USER_UNKNOWN: + case PAM_AUTH_ERR: + case PAM_MAXTRIES: /* should handle this better ... */ + case PAM_AUTHINFO_UNAVAIL: /* returned for unknown users ... bogus */ + return AuthBad; + default: + return AuthError; + } + } + + /* just in case some module is stupid enough to ignore a preset PAM_USER */ + pam_error = pam_get_item (pamh, PAM_USER, &pam_item); + if (pam_error != PAM_SUCCESS) { + pam_end(pamh, pam_error); + return AuthError; + } + if (strcmp((const char *)pam_item, user)) { + pam_end(pamh, PAM_SUCCESS); /* maybe use PAM_AUTH_ERR? */ + return AuthBad; + } + + pam_error = pam_setcred(pamh, PAM_REFRESH_CRED); + /* ignore errors on refresh credentials. If this did not work we use the old ones. */ + + pam_end(pamh, PAM_SUCCESS); + return AuthOk; +} + +#endif diff --git a/kcheckpass/checkpass_shadow.c b/kcheckpass/checkpass_shadow.c new file mode 100644 index 00000000..c0f6913f --- /dev/null +++ b/kcheckpass/checkpass_shadow.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 1998 Christian Esken + * Copyright (C) 2003 Oswald Buddenhagen + * + * This is a modified version of checkpass_shadow.cpp + * + * Modifications made by Thorsten Kukuk + * Mathias Kettner + * + * ------------------------------------------------------------ + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcheckpass.h" + +/******************************************************************* + * This is the authentication code for Shadow-Passwords + *******************************************************************/ + +#ifdef HAVE_SHADOW +#include +#include +#include + +#ifndef __hpux +#include +#endif + +AuthReturn Authenticate(const char *method, + const char *login, char *(*conv) (ConvRequest, const char *)) +{ + char *typed_in_password; + char *crpt_passwd; + char *password; + struct passwd *pw; + struct spwd *spw; + + if (strcmp(method, "classic")) + return AuthError; + + if (!(pw = getpwnam(login))) + return AuthAbort; + + spw = getspnam(login); + password = spw ? spw->sp_pwdp : pw->pw_passwd; + + if (!*password) + return AuthOk; + + if (!(typed_in_password = conv(ConvGetHidden, 0))) + return AuthAbort; + +#if defined( __linux__ ) && defined( HAVE_PW_ENCRYPT ) + crpt_passwd = pw_encrypt(typed_in_password, password); /* (1) */ +#else + crpt_passwd = crypt(typed_in_password, password); +#endif + + if (crpt_passwd && !strcmp(password, crpt_passwd )) { + dispose(typed_in_password); + return AuthOk; /* Success */ + } + dispose(typed_in_password); + return AuthBad; /* Password wrong or account locked */ +} + +/* + (1) Deprecated - long passwords have known weaknesses. Also, + pw_encrypt is non-standard (requires libshadow.a) while + everything else you need to support shadow passwords is in + the standard (ELF) libc. + */ +#endif diff --git a/kcheckpass/config-kcheckpass.h.cmake b/kcheckpass/config-kcheckpass.h.cmake new file mode 100644 index 00000000..a8a4ee50 --- /dev/null +++ b/kcheckpass/config-kcheckpass.h.cmake @@ -0,0 +1,3 @@ +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PATHS_H 1 + diff --git a/kcheckpass/kcheckpass-enums.h b/kcheckpass/kcheckpass-enums.h new file mode 100644 index 00000000..58387ff6 --- /dev/null +++ b/kcheckpass/kcheckpass-enums.h @@ -0,0 +1,70 @@ +/***************************************************************** + * + *· kcheckpass + * + *· Simple password checker. Just invoke and send it + *· the password on stdin. + * + *· If the password was accepted, the program exits with 0; + *· if it was rejected, it exits with 1. Any other exit + *· code signals an error. + * + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *· Copyright (C) 1998, Caldera, Inc. + *· Released under the GNU General Public License + * + *· Olaf Kirch General Framework and PAM support + *· Christian Esken Shadow and /etc/passwd support + *· Oswald Buddenhagen Binary server mode + * + * Other parts were taken from kscreensaver's passwd.cpp + *****************************************************************/ + +#ifndef KCHECKPASS_ENUMS_H +#define KCHECKPASS_ENUMS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* these must match kcheckpass' exit codes */ +typedef enum { + AuthOk = 0, + AuthBad = 1, + AuthError = 2, + AuthAbort = 3 +} AuthReturn; + +typedef enum { + ConvGetBinary, + ConvGetNormal, + ConvGetHidden, + ConvPutInfo, + ConvPutError +} ConvRequest; + +/* these must match the defs in kgreeterplugin.h */ +typedef enum { + IsUser = 1, /* unused in kcheckpass */ + IsPassword = 2 +} DataTag; + +#ifdef __cplusplus +} +#endif + +#endif /* KCHECKPASS_ENUMS_H */ diff --git a/kcheckpass/kcheckpass.c b/kcheckpass/kcheckpass.c new file mode 100644 index 00000000..fd2d2215 --- /dev/null +++ b/kcheckpass/kcheckpass.c @@ -0,0 +1,458 @@ +/***************************************************************** + * + * kcheckpass - Simple password checker + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * + * kcheckpass is a simple password checker. Just invoke and + * send it the password on stdin. + * + * If the password was accepted, the program exits with 0; + * if it was rejected, it exits with 1. Any other exit + * code signals an error. + * + * It's hopefully simple enough to allow it to be setuid + * root. + * + * Compile with -DHAVE_VSYSLOG if you have vsyslog(). + * Compile with -DHAVE_PAM if you have a PAM system, + * and link with -lpam -ldl. + * Compile with -DHAVE_SHADOW if you have a shadow + * password system. + * + * Copyright (C) 1998, Caldera, Inc. + * Released under the GNU General Public License + * + * Olaf Kirch General Framework and PAM support + * Christian Esken Shadow and /etc/passwd support + * Roberto Teixeira other user (-U) support + * Oswald Buddenhagen Binary server mode + * + * Other parts were taken from kscreensaver's passwd.cpp. + * + *****************************************************************/ + +#include "kcheckpass.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Compatibility: accept some options from environment variables */ +#define ACCEPT_ENV + +#define THROTTLE 3 + +static int havetty, sfd = -1, nullpass; + +static char * +conv_legacy (ConvRequest what, const char *prompt) +{ + char *p, *p2; + int len; + char buf[1024]; + + switch (what) { + case ConvGetBinary: + break; + case ConvGetNormal: + /* there is no prompt == 0 case */ + if (!havetty) + break; + /* i guess we should use /dev/tty ... */ + fputs(prompt, stdout); + fflush(stdout); + if (!fgets(buf, sizeof(buf), stdin)) + return 0; + len = strlen(buf); + if (len && buf[len - 1] == '\n') + buf[--len] = 0; + return strdup(buf); + case ConvGetHidden: + if (havetty) { +#ifdef HAVE_GETPASSPHRASE + p = getpassphrase(prompt ? prompt : "Password: "); +#else + p = getpass(prompt ? prompt : "Password: "); +#endif + p2 = strdup(p); + memset(p, 0, strlen(p)); + return p2; + } else { + if (prompt) + break; + if ((len = read(0, buf, sizeof(buf) - 1)) < 0) { + message("Cannot read password\n"); + return 0; + } else { + if (len && buf[len - 1] == '\n') + --len; + buf[len] = 0; + p2 = strdup(buf); + memset(buf, 0, len); + return p2; + } + } + case ConvPutInfo: + message("Information: %s\n", prompt); + return 0; + case ConvPutError: + message("Error: %s\n", prompt); + return 0; + } + message("Authentication backend requested data type which cannot be handled.\n"); + return 0; +} + + +static int +Reader (void *buf, int count) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = read (sfd, (void *)((char *)buf + rlen), count - rlen); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +static void +GRead (void *buf, int count) +{ + if (Reader (buf, count) != count) { + message ("Communication breakdown on read\n"); + exit(15); + } +} + +static void +GWrite (const void *buf, int count) +{ + if (write (sfd, buf, count) != count) { + message ("Communication breakdown on write\n"); + exit(15); + } +} + +static void +GSendInt (int val) +{ + GWrite (&val, sizeof(val)); +} + +static void +GSendStr (const char *buf) +{ + unsigned len = buf ? strlen (buf) + 1 : 0; + GWrite (&len, sizeof(len)); + GWrite (buf, len); +} + +static void +GSendArr (int len, const char *buf) +{ + GWrite (&len, sizeof(len)); + GWrite (buf, len); +} + +static int +GRecvInt (void) +{ + int val; + + GRead (&val, sizeof(val)); + return val; +} + +static char * +GRecvStr (void) +{ + unsigned len; + char *buf; + + if (!(len = GRecvInt())) + return (char *)0; + if (len > 0x1000 || !(buf = malloc (len))) { + message ("No memory for read buffer\n"); + exit(15); + } + GRead (buf, len); + buf[len - 1] = 0; /* we're setuid ... don't trust "them" */ + return buf; +} + +static char * +GRecvArr (void) +{ + unsigned len; + char *arr; + unsigned const char *up; + + if (!(len = (unsigned) GRecvInt())) + return (char *)0; + if (len < 4) { + message ("Too short binary authentication data block\n"); + exit(15); + } + if (len > 0x10000 || !(arr = malloc (len))) { + message ("No memory for read buffer\n"); + exit(15); + } + GRead (arr, len); + up = (unsigned const char *)arr; + if (len != (unsigned)(up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24))) { + message ("Mismatched binary authentication data block size\n"); + exit(15); + } + return arr; +} + + +static char * +conv_server (ConvRequest what, const char *prompt) +{ + GSendInt (what); + switch (what) { + case ConvGetBinary: + { + unsigned const char *up = (unsigned const char *)prompt; + int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); + GSendArr (len, prompt); + return GRecvArr (); + } + case ConvGetNormal: + case ConvGetHidden: + { + char *msg; + GSendStr (prompt); + msg = GRecvStr (); + if (msg && (GRecvInt() & IsPassword) && !*msg) + nullpass = 1; + return msg; + } + case ConvPutInfo: + case ConvPutError: + default: + GSendStr (prompt); + return 0; + } +} + +void +message(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + +static void ATTR_NORETURN +usage(int exitval) +{ + message( + "usage: kcheckpass {-h|[-c caller] [-m method] [-U username|-S handle]}\n" + " options:\n" + " -h this help message\n" + " -U username authenticate the specified user instead of current user\n" + " -S handle operate in binary server mode on file descriptor handle\n" + " -c caller the calling application, effectively the PAM service basename\n" + " -m method use the specified authentication method (default: \"classic\")\n" + " exit codes:\n" + " 0 success\n" + " 1 invalid password\n" + " 2 cannot read password database\n" + " Anything else tells you something's badly hosed.\n" + ); + exit(exitval); +} + +int +main(int argc, char **argv) +{ +#ifdef HAVE_PAM + const char *caller = KSCREENSAVER_PAM_SERVICE; +#endif + const char *method = "classic"; + const char *username = 0; +#ifdef ACCEPT_ENV + char *p; +#endif + struct passwd *pw; + int c, nfd, lfd; + uid_t uid; + time_t nexttime; + AuthReturn ret; + struct flock lk; + char fname[64], fcont[64]; + +#ifdef HAVE_OSF_C2_PASSWD + initialize_osf_security(argc, argv); +#endif + + /* Make sure stdout/stderr are open */ + for (c = 1; c <= 2; c++) { + if (fcntl(c, F_GETFL) == -1) { + if ((nfd = open("/dev/null", O_WRONLY)) < 0) { + message("cannot open /dev/null: %s\n", strerror(errno)); + exit(10); + } + if (c != nfd) { + dup2(nfd, c); + close(nfd); + } + } + } + + havetty = isatty(0); + + while ((c = getopt(argc, argv, "hc:m:U:S:")) != -1) { + switch (c) { + case 'h': + usage(0); + break; + case 'c': +#ifdef HAVE_PAM + caller = optarg; +#endif + break; + case 'm': + method = optarg; + break; + case 'U': + username = optarg; + break; + case 'S': + sfd = atoi(optarg); + break; + default: + message("Command line option parsing error\n"); + usage(10); + } + } + +#ifdef ACCEPT_ENV +# ifdef HAVE_PAM + if ((p = getenv("KDE_PAM_ACTION"))) + caller = p; +# endif + if ((p = getenv("KCHECKPASS_USER"))) + username = p; +#endif + + uid = getuid(); + if (!username) { + if (!(p = getenv("LOGNAME")) || !(pw = getpwnam(p)) || pw->pw_uid != uid) + if (!(p = getenv("USER")) || !(pw = getpwnam(p)) || pw->pw_uid != uid) + if (!(pw = getpwuid(uid))) { + message("Cannot determinate current user\n"); + return AuthError; + } + if (!(username = strdup(pw->pw_name))) { + message("Out of memory\n"); + return AuthError; + } + } + + /* + * Throttle kcheckpass invocations to avoid abusing it for bruteforcing + * the password. This delay belongs to the *previous* invocation, where + * we can't enforce it reliably (without risking giving away the result + * before it is due). We don't differentiate between success and failure - + * it's not expected to have a noticeable adverse effect. + */ + if ( uid != geteuid() ) { + sprintf(fname, "/var/run/kcheckpass.%d", uid); + if ((lfd = open(fname, O_RDWR | O_CREAT | O_NOFOLLOW, 0600)) < 0) { + message("Cannot open lockfile\n"); + return AuthError; + } + + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = lk.l_len = 0; + if (fcntl(lfd, F_SETLKW, &lk)) { + message("Cannot obtain lock\n"); + return AuthError; + } + + if ((c = read(lfd, fcont, sizeof(fcont)-1)) > 0 && + (fcont[c] = '\0', sscanf(fcont, "%ld", &nexttime) == 1)) + { + time_t ct = time(0); + if (nexttime > ct && nexttime < ct + THROTTLE) + sleep(nexttime - ct); + } + + lseek(lfd, 0, SEEK_SET); + write(lfd, fcont, sprintf(fcont, "%lu\n", time(0) + THROTTLE)); + + close(lfd); + } + + /* Now do the fandango */ + ret = Authenticate( +#ifdef HAVE_PAM + caller, +#endif + method, + username, + sfd < 0 ? conv_legacy : conv_server); + + if (ret == AuthBad) { + message("Authentication failure\n"); + if (!nullpass) { + openlog("kcheckpass", LOG_PID, LOG_AUTH); + syslog(LOG_NOTICE, "Authentication failure for %s (invoked by uid %d)", username, uid); + } + } + + return ret; +} + +void +dispose(char *str) +{ + memset(str, 0, strlen(str)); + free(str); +} + +/***************************************************************** + The real authentication methods are in separate source files. + Look in checkpass_*.c +*****************************************************************/ diff --git a/kcheckpass/kcheckpass.h b/kcheckpass/kcheckpass.h new file mode 100644 index 00000000..d75341c8 --- /dev/null +++ b/kcheckpass/kcheckpass.h @@ -0,0 +1,123 @@ +/***************************************************************** + * + * kcheckpass + * + * Simple password checker. Just invoke and send it + * the password on stdin. + * + * If the password was accepted, the program exits with 0; + * if it was rejected, it exits with 1. Any other exit + * code signals an error. + * + * + * 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; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 1998, Caldera, Inc. + * Released under the GNU General Public License + * + * Olaf Kirch General Framework and PAM support + * Christian Esken Shadow and /etc/passwd support + * Oswald Buddenhagen Binary server mode + * + * Other parts were taken from kscreensaver's passwd.cpp + *****************************************************************/ + +#ifndef KCHECKPASS_H_ +#define KCHECKPASS_H_ + +#include +#include +#include + +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifdef HAVE_PATHS_H +#include +#endif + +#include +#include + +#ifndef _PATH_TMP +#define _PATH_TMP "/tmp/" +#endif + + +#ifdef ultrix +#include +#endif + +#include + +#ifdef OSF1_ENH_SEC +#include +#include +#endif + +/* Make sure there is only one! */ +#if defined(HAVE_PAM) +# undef HAVE_OSF_C2_PASSWD +#elif defined(HAVE_OSF_C2_PASSWD) +#elif defined(_AIX) +# define HAVE_AIX_AUTH +#elif defined(HAVE_GETSPNAM) +# define HAVE_SHADOW +#else +# define HAVE_ETCPASSWD +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +# define ATTR_UNUSED __attribute__((unused)) +# define ATTR_NORETURN __attribute__((noreturn)) +# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) +#else +# define ATTR_UNUSED +# define ATTR_NORETURN +# define ATTR_PRINTFLIKE(fmt,var) +#endif + +#include "kcheckpass-enums.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************** + * Authenticates user + *****************************************************************/ +AuthReturn Authenticate( +#ifdef HAVE_PAM + const char *caller, +#endif + const char *method, + const char *user, + char *(*conv) (ConvRequest, const char *)); + +/***************************************************************** + * Output a message to stderr + *****************************************************************/ +void message(const char *, ...) ATTR_PRINTFLIKE(1, 2); + +/***************************************************************** + * Overwrite and free the passed string + *****************************************************************/ +void dispose(char *); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/kcminit/CMakeLists.txt b/kcminit/CMakeLists.txt new file mode 100644 index 00000000..029990c1 --- /dev/null +++ b/kcminit/CMakeLists.txt @@ -0,0 +1,26 @@ +########### next target ############### + +set(kcminit_KDEINIT_SRCS main.cpp) + + +kde4_add_kdeinit_executable( kcminit ${kcminit_KDEINIT_SRCS}) + +target_link_libraries(kdeinit_kcminit ${KDE4_KCMUTILS_LIBS} ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES}) + +install(TARGETS kdeinit_kcminit ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(TARGETS kcminit ${INSTALL_TARGETS_DEFAULT_ARGS} ) + +########### next target ############### + +# TODO might be simpler to make _startup to be a symlink to + +set(kcminit_startup_KDEINIT_SRCS main.cpp) + + +kde4_add_kdeinit_executable( kcminit_startup ${kcminit_startup_KDEINIT_SRCS}) + +target_link_libraries(kdeinit_kcminit_startup ${KDE4_KCMUTILS_LIBS} ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES}) + +install(TARGETS kdeinit_kcminit_startup ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(TARGETS kcminit_startup ${INSTALL_TARGETS_DEFAULT_ARGS} ) + diff --git a/kcminit/Messages.sh b/kcminit/Messages.sh new file mode 100755 index 00000000..59f7b2dd --- /dev/null +++ b/kcminit/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/kcminit.pot diff --git a/kcminit/main.cpp b/kcminit/main.cpp new file mode 100644 index 00000000..856d8b74 --- /dev/null +++ b/kcminit/main.cpp @@ -0,0 +1,270 @@ +/* + Copyright (c) 1999 Matthias Hoelzer-Kluepfel + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include + +#include "main.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef Q_WS_X11 +#include +#include +#endif + +#include +#include + +static int ready[ 2 ]; +static bool startup = false; + +static void sendReady() +{ + if( ready[ 1 ] == -1 ) + return; + char c = 0; + write( ready[ 1 ], &c, 1 ); + close( ready[ 1 ] ); + ready[ 1 ] = -1; +} + +static void waitForReady() +{ + char c = 1; + close( ready[ 1 ] ); + read( ready[ 0 ], &c, 1 ); + close( ready[ 0 ] ); +} + +bool KCMInit::runModule(const QString &libName, KService::Ptr service) +{ + KLibrary lib(libName); + if (lib.load()) { + QVariant tmp = service->property("X-KDE-Init-Symbol", QVariant::String); + QString kcminit; + if( tmp.isValid() ) + { + kcminit = tmp.toString(); + if( !kcminit.startsWith( QLatin1String( "kcminit_" ) ) ) + kcminit = "kcminit_" + kcminit; + } + else + kcminit = "kcminit_" + libName; + + // get the kcminit_ function + KLibrary::void_function_ptr init = lib.resolveFunction(kcminit.toUtf8()); + if (init) { + // initialize the module + kDebug(1208) << "Initializing " << libName << ": " << kcminit; + + void (*func)() = (void(*)())init; + func(); + return true; + } else { + kDebug(1208) << "Module" << libName << "does not actually have a kcminit function"; + } + } + return false; +} + +void KCMInit::runModules( int phase ) +{ + for(KService::List::Iterator it = list.begin(); + it != list.end(); + ++it) { + KService::Ptr service = (*it); + + QVariant tmp = service->property("X-KDE-Init-Library", QVariant::String); + QString library; + if( tmp.isValid() ) + { + library = tmp.toString(); + if( !library.startsWith( QLatin1String( "kcminit_" ) ) ) + library = QLatin1String( "kcminit_" ) + library; + } + else + { + library = service->library(); + } + + if (library.isEmpty()) + continue; // Skip + + // see ksmserver's README for the description of the phases + QVariant vphase = service->property("X-KDE-Init-Phase", QVariant::Int ); + int libphase = 1; + if( vphase.isValid() ) + libphase = vphase.toInt(); + + if( phase != -1 && libphase != phase ) + continue; + + // try to load the library + if (!alreadyInitialized.contains(library)) { + runModule(library, service); + alreadyInitialized.append(library); + } + } +} + +KCMInit::KCMInit( KCmdLineArgs* args ) +{ + QDBusConnection::sessionBus().registerObject("/kcminit", this, + QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportScriptableSignals); + QString arg; + if (args->count() == 1) { + arg = args->arg(0); + } + + if (args->isSet("list")) + { + list = KServiceTypeTrader::self()->query( "KCModuleInit" ); + + for(KService::List::Iterator it = list.begin(); + it != list.end(); + ++it) + { + KService::Ptr service = (*it); + if (service->library().isEmpty()) + continue; // Skip + printf("%s\n", QFile::encodeName(service->desktopEntryName()).data()); + } + return; + } + + if (!arg.isEmpty()) { + + QString module = arg; + if (!module.endsWith(".desktop")) + module += ".desktop"; + + KService::Ptr serv = KService::serviceByStorageId( module ); + if ( !serv || serv->library().isEmpty() ) { + kError(1208) << i18n("Module %1 not found", module) << endl; + return; + } else + list.append(serv); + + } else { + + // locate the desktop files + list = KServiceTypeTrader::self()->query( "KCModuleInit" ); + + } + // This key has no GUI apparently + KConfig _config( "kcmdisplayrc" ); + KConfigGroup config(&_config, "X11"); +#ifdef Q_WS_X11 + bool multihead = !config.readEntry( "disableMultihead", false) && + (ScreenCount(QX11Info::display()) > 1); +#else + bool multihead = false; +#endif + // Pass env. var to kdeinit. + QString name = "KDE_MULTIHEAD"; + QString value = multihead ? "true" : "false"; + KToolInvocation::klauncher()->setLaunchEnv(name, value); + setenv( name.toLatin1().constData(), value.toLatin1().constData(), 1 ); // apply effect also to itself + + if( startup ) + { + runModules( 0 ); + XEvent e; + e.xclient.type = ClientMessage; + e.xclient.message_type = XInternAtom( QX11Info::display(), "_KDE_SPLASH_PROGRESS", False ); + e.xclient.display = QX11Info::display(); + e.xclient.window = QX11Info::appRootWindow(); + e.xclient.format = 8; + strcpy( e.xclient.data.b, "kcminit" ); + XSendEvent( QX11Info::display(), QX11Info::appRootWindow(), False, SubstructureNotifyMask, &e ); + sendReady(); + QTimer::singleShot( 300 * 1000, qApp, SLOT(quit())); // just in case + qApp->exec(); // wait for runPhase1() and runPhase2() + } + else + runModules( -1 ); // all phases +} + +KCMInit::~KCMInit() +{ + sendReady(); +} + +void KCMInit::runPhase1() +{ + runModules( 1 ); + emit phase1Done(); +} + +void KCMInit::runPhase2() +{ + runModules( 2 ); + emit phase2Done(); + qApp->exit( 0 ); +} + +extern "C" KDE_EXPORT int kdemain(int argc, char *argv[]) +{ + // kdeinit waits for kcminit to finish, but during KDE startup + // only important kcm's are started very early in the login process, + // the rest is delayed, so fork and make parent return after the initial phase + pipe( ready ); + if( fork() != 0 ) + { + waitForReady(); + return 0; + } + close( ready[ 0 ] ); + + startup = ( strcmp( argv[ 0 ], "kcminit_startup" ) == 0 ); // started from startkde? + KAboutData aboutData( "kcminit", "kcminit", ki18n("KCMInit"), + "", + ki18n("KCMInit - runs startup initialization for Control Modules.")); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("list", ki18n("List modules that are run at startup")); + options.add("+module", ki18n("Configuration module to run")); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + + KApplication app; + QDBusConnection::sessionBus().interface()->registerService( "org.kde.kcminit", + QDBusConnectionInterface::DontQueueService ); + KLocale::setMainCatalog(0); + KCMInit kcminit( KCmdLineArgs::parsedArgs()); + return 0; +} + +#include "main.moc" diff --git a/kcminit/main.h b/kcminit/main.h new file mode 100644 index 00000000..51358bb4 --- /dev/null +++ b/kcminit/main.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 1999 Matthias Hoelzer-Kluepfel + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef MAIN_H +#define MAIN_H + +#include + +class KCmdLineArgs; + +class KCMInit : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.KCMInit") + public Q_SLOTS: //dbus + Q_SCRIPTABLE void runPhase1(); + Q_SCRIPTABLE void runPhase2(); + Q_SIGNALS: //dbus signal + Q_SCRIPTABLE void phase1Done(); + Q_SCRIPTABLE void phase2Done(); + public: + KCMInit( KCmdLineArgs* args ); + virtual ~KCMInit(); + private: + bool runModule(const QString &libName, KService::Ptr service); + void runModules( int phase ); + KService::List list; + QStringList alreadyInitialized; +}; + +#endif // MAIN_H diff --git a/kcontrol/CMakeLists.txt b/kcontrol/CMakeLists.txt new file mode 100644 index 00000000..fc666b11 --- /dev/null +++ b/kcontrol/CMakeLists.txt @@ -0,0 +1,52 @@ + +macro_optional_find_package(Freetype) +set_package_properties(Freetype PROPERTIES DESCRIPTION "A font rendering engine" + URL "http://www.freetype.org" + TYPE OPTIONAL + PURPOSE "Needed to build kfontinst, a simple font installer." + ) + + +set(libkxftconfig_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/fonts/kxftconfig.cpp ) + + +if( X11_Xrandr_FOUND ) + add_subdirectory( randr ) +endif(X11_Xrandr_FOUND ) + +if(X11_Xkb_FOUND) + add_subdirectory( keyboard ) +endif(X11_Xkb_FOUND) + +if(NOT WIN32) +add_subdirectory( bell ) +add_subdirectory( input ) +add_subdirectory( access ) +add_subdirectory( screensaver ) +add_subdirectory( dateandtime ) +add_subdirectory( autostart ) +endif(NOT WIN32) + +add_subdirectory( launch ) +add_subdirectory( colors ) +add_subdirectory( krdb ) +add_subdirectory( style ) +add_subdirectory( desktoptheme ) +add_subdirectory( standard_actions ) +add_subdirectory( keys ) +add_subdirectory( workspaceoptions ) + +# TODO needs porting +#add_subdirectory( smartcard ) + +add_subdirectory( hardware ) +add_subdirectory( desktoppaths ) + +if( FREETYPE_FOUND ) + if( WIN32 OR FONTCONFIG_FOUND ) + add_subdirectory( fonts ) + endif( WIN32 OR FONTCONFIG_FOUND ) +endif( FREETYPE_FOUND ) +if(FONTCONFIG_FOUND AND FREETYPE_FOUND AND NOT WIN32) + add_subdirectory( kfontinst ) +endif(FONTCONFIG_FOUND AND FREETYPE_FOUND AND NOT WIN32) diff --git a/kcontrol/PURPOSE b/kcontrol/PURPOSE new file mode 100644 index 00000000..ef03e579 --- /dev/null +++ b/kcontrol/PURPOSE @@ -0,0 +1,10 @@ +System Settings is: +-Desktop Configuration +-User System Configuration + +System Settings is not: +-Application Configuration +-System Administration/Configuration +-Tools/Utilities + +On other environments the already provided equivalent should be used. In KDE the other environment equivalents should not be needed. diff --git a/kcontrol/access/CMakeLists.txt b/kcontrol/access/CMakeLists.txt new file mode 100644 index 00000000..1fbcd78a --- /dev/null +++ b/kcontrol/access/CMakeLists.txt @@ -0,0 +1,33 @@ + + + +########### next target ############### + +set(kcm_access_PART_SRCS kcmaccess.cpp ) + + +kde4_add_plugin(kcm_access ${kcm_access_PART_SRCS}) + + +target_link_libraries(kcm_access ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBS} ${KDE4_KNOTIFYCONFIG_LIBS} ${X11_LIBRARIES}) + +install(TARGETS kcm_access DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### next target ############### + +set(kaccess_KDEINIT_SRCS kaccess.cpp main.cpp ) + + +kde4_add_kdeinit_executable( kaccess ${kaccess_KDEINIT_SRCS}) + +target_link_libraries(kdeinit_kaccess ${KDE4_KDEUI_LIBS} ${KDE4_PHONON_LIBS} ${X11_LIBRARIES}) + +install(TARGETS kdeinit_kaccess ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(TARGETS kaccess ${INSTALL_TARGETS_DEFAULT_ARGS} ) + +########### install files ############### + +install( FILES kcmaccess.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES kaccess.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES kaccess.notifyrc DESTINATION ${DATA_INSTALL_DIR}/kaccess/ ) diff --git a/kcontrol/access/Messages.sh b/kcontrol/access/Messages.sh new file mode 100644 index 00000000..3834cc09 --- /dev/null +++ b/kcontrol/access/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +### TODO: why do we need 2 POT files for a single directory? +$XGETTEXT kaccess.cpp main.cpp rc.cpp -o $podir/kaccess.pot +$XGETTEXT kcmaccess.cpp rc.cpp -o $podir/kcmaccess.pot diff --git a/kcontrol/access/kaccess.cpp b/kcontrol/access/kaccess.cpp new file mode 100644 index 00000000..24beed3d --- /dev/null +++ b/kcontrol/access/kaccess.cpp @@ -0,0 +1,918 @@ +#include + + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#define XK_MISCELLANY +#define XK_XKB_KEYS +#include + + +#include "kaccess.moc" +#include +#include + +struct ModifierKey { + const unsigned int mask; + const KeySym keysym; + const char *name; + const char *lockedText; + const char *latchedText; + const char *unlatchedText; +}; + +static ModifierKey modifierKeys[] = { + { ShiftMask, 0, "Shift", + I18N_NOOP("The Shift key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Shift key is now active."), + I18N_NOOP("The Shift key is now inactive.") }, + { ControlMask, 0, "Control", + I18N_NOOP("The Control key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Control key is now active."), + I18N_NOOP("The Control key is now inactive.") }, + { 0, XK_Alt_L, "Alt", + I18N_NOOP("The Alt key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Alt key is now active."), + I18N_NOOP("The Alt key is now inactive.") }, + { 0, 0, "Win", + I18N_NOOP("The Win key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Win key is now active."), + I18N_NOOP("The Win key is now inactive.") }, + { 0, XK_Meta_L, "Meta", + I18N_NOOP("The Meta key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Meta key is now active."), + I18N_NOOP("The Meta key is now inactive.") }, + { 0, XK_Super_L, "Super", + I18N_NOOP("The Super key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Super key is now active."), + I18N_NOOP("The Super key is now inactive.") }, + { 0, XK_Hyper_L, "Hyper", + I18N_NOOP("The Hyper key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Hyper key is now active."), + I18N_NOOP("The Hyper key is now inactive.") }, + { 0, 0, "Alt Graph", + I18N_NOOP("The Alt Graph key has been locked and is now active for all of the following keypresses."), + I18N_NOOP("The Alt Graph key is now active."), + I18N_NOOP("The Alt Graph key is now inactive.") }, + { 0, XK_Num_Lock, "Num Lock", + I18N_NOOP("The Num Lock key has been activated."), + "", + I18N_NOOP("The Num Lock key is now inactive.") }, + { LockMask, 0, "Caps Lock", + I18N_NOOP("The Caps Lock key has been activated."), + "", + I18N_NOOP("The Caps Lock key is now inactive.") }, + { 0, XK_Scroll_Lock, "Scroll Lock", + I18N_NOOP("The Scroll Lock key has been activated."), + "", + I18N_NOOP("The Scroll Lock key is now inactive.") }, + { 0, 0, "", "", "", "" } +}; + + +/********************************************************************/ + + +KAccessApp::KAccessApp(bool allowStyles, bool GUIenabled) + : KUniqueApplication(allowStyles, GUIenabled), + overlay(0), _player(0) +{ + _activeWindow = KWindowSystem::activeWindow(); + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId))); + + features = 0; + requestedFeatures = 0; + dialog = 0; + + initMasks(); + XkbStateRec state_return; + XkbGetState (QX11Info::display(), XkbUseCoreKbd, &state_return); + unsigned char latched = XkbStateMods (&state_return); + unsigned char locked = XkbModLocks (&state_return); + state = ((int)locked)<<8 | latched; +} + +int KAccessApp::newInstance() +{ + KGlobal::config()->reparseConfiguration(); + readSettings(); + return 0; +} + +void KAccessApp::readSettings() +{ + KSharedConfig::Ptr _config = KGlobal::config(); + KConfigGroup cg(_config, "Bell"); + + // bell --------------------------------------------------------------- + _systemBell = cg.readEntry("SystemBell", true); + _artsBell = cg.readEntry("ArtsBell", false); + _currentPlayerSource = cg.readPathEntry("ArtsBellFile", QString()); + _visibleBell = cg.readEntry("VisibleBell", false); + _visibleBellInvert = cg.readEntry("VisibleBellInvert", false); + _visibleBellColor = cg.readEntry("VisibleBellColor", QColor(Qt::red)); + _visibleBellPause = cg.readEntry("VisibleBellPause", 500); + + // select bell events if we need them + int state = (_artsBell || _visibleBell) ? XkbBellNotifyMask : 0; + XkbSelectEvents(QX11Info::display(), XkbUseCoreKbd, XkbBellNotifyMask, state); + + // deactivate system bell if not needed + if (!_systemBell) + XkbChangeEnabledControls(QX11Info::display(), XkbUseCoreKbd, XkbAudibleBellMask, 0); + else + XkbChangeEnabledControls(QX11Info::display(), XkbUseCoreKbd, XkbAudibleBellMask, XkbAudibleBellMask); + + // keyboard ------------------------------------------------------------- + KConfigGroup keyboardGroup(_config,"Keyboard"); + + // get keyboard state + XkbDescPtr xkb = XkbGetMap(QX11Info::display(), 0, XkbUseCoreKbd); + if (!xkb) + return; + if (XkbGetControls(QX11Info::display(), XkbAllControlsMask, xkb) != Success) + return; + + // sticky keys + if (keyboardGroup.readEntry("StickyKeys", false)) + { + if (keyboardGroup.readEntry("StickyKeysLatch", true)) + xkb->ctrls->ax_options |= XkbAX_LatchToLockMask; + else + xkb->ctrls->ax_options &= ~XkbAX_LatchToLockMask; + if (keyboardGroup.readEntry("StickyKeysAutoOff", false)) + xkb->ctrls->ax_options |= XkbAX_TwoKeysMask; + else + xkb->ctrls->ax_options &= ~XkbAX_TwoKeysMask; + if (keyboardGroup.readEntry("StickyKeysBeep", false)) + xkb->ctrls->ax_options |= XkbAX_StickyKeysFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_StickyKeysFBMask; + xkb->ctrls->enabled_ctrls |= XkbStickyKeysMask; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbStickyKeysMask; + + // toggle keys + if (keyboardGroup.readEntry("ToggleKeysBeep", false)) + xkb->ctrls->ax_options |= XkbAX_IndicatorFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_IndicatorFBMask; + + // slow keys + if (keyboardGroup.readEntry("SlowKeys", false)) { + if (keyboardGroup.readEntry("SlowKeysPressBeep", false)) + xkb->ctrls->ax_options |= XkbAX_SKPressFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_SKPressFBMask; + if (keyboardGroup.readEntry("SlowKeysAcceptBeep", false)) + xkb->ctrls->ax_options |= XkbAX_SKAcceptFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_SKAcceptFBMask; + if (keyboardGroup.readEntry("SlowKeysRejectBeep", false)) + xkb->ctrls->ax_options |= XkbAX_SKRejectFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_SKRejectFBMask; + xkb->ctrls->enabled_ctrls |= XkbSlowKeysMask; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbSlowKeysMask; + xkb->ctrls->slow_keys_delay = keyboardGroup.readEntry("SlowKeysDelay", 500); + + // bounce keys + if (keyboardGroup.readEntry("BounceKeys", false)) { + if (keyboardGroup.readEntry("BounceKeysRejectBeep", false)) + xkb->ctrls->ax_options |= XkbAX_BKRejectFBMask; + else + xkb->ctrls->ax_options &= ~XkbAX_BKRejectFBMask; + xkb->ctrls->enabled_ctrls |= XkbBounceKeysMask; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbBounceKeysMask; + xkb->ctrls->debounce_delay = keyboardGroup.readEntry("BounceKeysDelay", 500); + + // gestures for enabling the other features + _gestures = keyboardGroup.readEntry("Gestures", false); + if (_gestures) + xkb->ctrls->enabled_ctrls |= XkbAccessXKeysMask; + else + xkb->ctrls->enabled_ctrls &= ~XkbAccessXKeysMask; + + // timeout + if (keyboardGroup.readEntry("AccessXTimeout", false)) + { + xkb->ctrls->ax_timeout = keyboardGroup.readEntry("AccessXTimeoutDelay", 30)*60; + xkb->ctrls->axt_opts_mask = 0; + xkb->ctrls->axt_opts_values = 0; + xkb->ctrls->axt_ctrls_mask = XkbStickyKeysMask | XkbSlowKeysMask; + xkb->ctrls->axt_ctrls_values = 0; + xkb->ctrls->enabled_ctrls |= XkbAccessXTimeoutMask; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask; + + // gestures for enabling the other features + if (keyboardGroup.readEntry("AccessXBeep", true)) + xkb->ctrls->ax_options |= XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask; + else + xkb->ctrls->ax_options &= ~(XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask); + + _gestureConfirmation = keyboardGroup.readEntry("GestureConfirmation", false); + + _kNotifyModifiers = keyboardGroup.readEntry("kNotifyModifiers", false); + _kNotifyAccessX = keyboardGroup.readEntry("kNotifyAccessX", false); + + // mouse-by-keyboard ---------------------------------------------- + + KConfigGroup mouseGroup(_config,"Mouse"); + + if (mouseGroup.readEntry("MouseKeys", false)) + { + xkb->ctrls->mk_delay = mouseGroup.readEntry("MKDelay", 160); + + // Default for initial velocity: 200 pixels/sec + int interval = mouseGroup.readEntry("MKInterval", 5); + xkb->ctrls->mk_interval = interval; + + // Default time to reach maximum speed: 5000 msec + xkb->ctrls->mk_time_to_max = mouseGroup.readEntry("MKTimeToMax", + (5000+interval/2)/interval); + + // Default maximum speed: 1000 pixels/sec + // (The old default maximum speed from KDE <= 3.4 + // (100000 pixels/sec) was way too fast) + xkb->ctrls->mk_max_speed = mouseGroup.readEntry("MKMaxSpeed", interval); + + xkb->ctrls->mk_curve = mouseGroup.readEntry("MKCurve", 0); + xkb->ctrls->mk_dflt_btn = mouseGroup.readEntry("MKDefaultButton", 0); + + xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask; + } + else + xkb->ctrls->enabled_ctrls &= ~XkbMouseKeysMask; + + features = xkb->ctrls->enabled_ctrls & (XkbSlowKeysMask | XkbBounceKeysMask | XkbStickyKeysMask | XkbMouseKeysMask); + if (dialog == 0) + requestedFeatures = features; + // set state + XkbSetControls(QX11Info::display(), XkbControlsEnabledMask | XkbMouseKeysAccelMask | XkbStickyKeysMask | XkbSlowKeysMask | XkbBounceKeysMask | XkbAccessXKeysMask | XkbAccessXTimeoutMask, xkb); + + // select AccessX events + XkbSelectEvents(QX11Info::display(), XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask); + + // do we need to stay running to perform notifications? + if (!_artsBell && !_visibleBell && !(_gestures && _gestureConfirmation) + && !_kNotifyModifiers && !_kNotifyAccessX) { + + // We will exit, but the features need to stay configured + uint ctrls = XkbStickyKeysMask | XkbSlowKeysMask | XkbBounceKeysMask | XkbMouseKeysMask | XkbAudibleBellMask | XkbControlsNotifyMask; + uint values = xkb->ctrls->enabled_ctrls & ctrls; + XkbSetAutoResetControls(QX11Info::display(), ctrls, &ctrls, &values); + exit(0); + } else { + // reset them after program exit + uint ctrls = XkbStickyKeysMask | XkbSlowKeysMask | XkbBounceKeysMask | XkbMouseKeysMask | XkbAudibleBellMask | XkbControlsNotifyMask; + uint values = XkbAudibleBellMask; + XkbSetAutoResetControls(QX11Info::display(), ctrls, &ctrls, &values); + } + + delete overlay; + overlay = 0; +} + +static int maskToBit (int mask) { + for (int i = 0; i < 8; i++) + if (mask & (1 << i)) + return i; + return -1; +} + +void KAccessApp::initMasks() { + for (int i = 0; i < 8; i++) + keys [i] = -1; + state = 0; + + for (int i = 0; strcmp (modifierKeys[i].name, "") != 0; i++) { + int mask = modifierKeys[i].mask; + if (mask == 0) { + if (modifierKeys[i].keysym != 0) { + mask = XkbKeysymToModifiers (QX11Info::display(), modifierKeys[i].keysym); + } else { + if (!strcmp(modifierKeys[i].name, "Win")) { + mask = KKeyServer::modXMeta(); + } else { + mask = XkbKeysymToModifiers (QX11Info::display(), XK_Mode_switch) + | XkbKeysymToModifiers (QX11Info::display(), XK_ISO_Level3_Shift) + | XkbKeysymToModifiers (QX11Info::display(), XK_ISO_Level3_Latch) + | XkbKeysymToModifiers (QX11Info::display(), XK_ISO_Level3_Lock); + } + } + } + + + int bit = maskToBit (mask); + if (bit != -1 && keys[bit] == -1) + keys[bit] = i; + } +} + + +bool KAccessApp::x11EventFilter(XEvent *event) +{ + // handle XKB events + if (event->type == xkb_opcode) + { + XkbAnyEvent *ev = (XkbAnyEvent*) event; + + switch (ev->xkb_type) { + case XkbStateNotify: + xkbStateNotify(); + break; + case XkbBellNotify: + xkbBellNotify((XkbBellNotifyEvent*)event); + break; + case XkbControlsNotify: + xkbControlsNotify((XkbControlsNotifyEvent*)event); + break; + } + return true; + } + + // process other events as usual + return KApplication::x11EventFilter(event); +} + + +void VisualBell::paintEvent(QPaintEvent *event) +{ + QWidget::paintEvent(event); + QTimer::singleShot(_pause, this, SLOT(hide())); +} + + +void KAccessApp::activeWindowChanged(WId wid) +{ + _activeWindow = wid; +} + + +void KAccessApp::xkbStateNotify () { + XkbStateRec state_return; + XkbGetState (QX11Info::display(), XkbUseCoreKbd, &state_return); + unsigned char latched = XkbStateMods (&state_return); + unsigned char locked = XkbModLocks (&state_return); + int mods = ((int)locked)<<8 | latched; + + if (state != mods) { + if (_kNotifyModifiers) + for (int i = 0; i < 8; i++) { + if (keys[i] != -1) { + if ( !strcmp(modifierKeys[keys[i]].latchedText, "") + && ( (((mods >> i) & 0x101) != 0) != (((state >> i) & 0x101) != 0) )) + { + if ((mods >> i) & 1) { + KNotification::event ("lockkey-locked", i18n(modifierKeys[keys[i]].lockedText)); + } + else { + KNotification::event ("lockkey-unlocked", i18n(modifierKeys[keys[i]].unlatchedText)); + } + } + else if (strcmp(modifierKeys[keys[i]].latchedText, "") + && ( ((mods >> i) & 0x101) != ((state >> i) & 0x101) )) + { + if ((mods >> i) & 0x100) { + KNotification::event ("modifierkey-locked", i18n(modifierKeys[keys[i]].lockedText)); + } + else if ((mods >> i) & 1) { + KNotification::event ( "modifierkey-latched", i18n(modifierKeys[keys[i]].latchedText)); + } + else { + KNotification::event ("modifierkey-unlatched", i18n(modifierKeys[keys[i]].unlatchedText)); + } + } + } + } + state = mods; + } +} + +void KAccessApp::xkbBellNotify(XkbBellNotifyEvent *event) +{ + // bail out if we should not really ring + if (event->event_only) + return; + + // flash the visible bell + if (_visibleBell) + { + // create overlay widget + if (!overlay) + overlay = new VisualBell(_visibleBellPause); + + WId id = _activeWindow; + + NETRect frame, window; + NETWinInfo net(QX11Info::display(), id, desktop()->winId(), 0); + + net.kdeGeometry(frame, window); + + overlay->setGeometry(window.pos.x, window.pos.y, window.size.width, window.size.height); + + if (_visibleBellInvert) + { + QPixmap screen = QPixmap::grabWindow(id, 0, 0, window.size.width, window.size.height); +#ifdef __GNUC__ +#warning is this the best way to invert a pixmap? +#endif +// QPixmap invert(window.size.width, window.size.height); + QImage i = screen.toImage(); + i.invertPixels(); + QPalette pal = overlay->palette(); + pal.setBrush(overlay->backgroundRole(), QBrush(QPixmap::fromImage(i))); + overlay->setPalette(pal); +/* + QPainter p(&invert); + p.setRasterOp(QPainter::NotCopyROP); + p.drawPixmap(0, 0, screen); + overlay->setBackgroundPixmap(invert); +*/ + } + else + { + QPalette pal = overlay->palette(); + pal.setColor(overlay->backgroundRole(), _visibleBellColor); + overlay->setPalette(pal); + } + + // flash the overlay widget + overlay->raise(); + overlay->show(); + flush(); + } + + // ask Phonon to ring a nice bell + if (_artsBell) { + if (!_player) { // as creating the player is expensive, delay the creation + _player = Phonon::createPlayer(Phonon::AccessibilityCategory); + _player->setParent(this); + _player->setCurrentSource(_currentPlayerSource); + } + _player->play(); + } +} + +QString mouseKeysShortcut (Display *display) { + // Calculate the keycode + KeySym sym = XK_MouseKeys_Enable; + KeyCode code = XKeysymToKeycode(display, sym); + if (code == 0) { + sym = XK_Pointer_EnableKeys; + code = XKeysymToKeycode(display, sym); + if (code == 0) + return ""; // No shortcut available? + } + + // Calculate the modifiers by searching the keysym in the X keyboard mapping + XkbDescPtr xkbdesc = XkbGetMap(display, XkbKeyTypesMask | XkbKeySymsMask, XkbUseCoreKbd); + + if (!xkbdesc) + return ""; // Failed to obtain the mapping from server + + bool found = false; + unsigned char modifiers = 0; + int groups = XkbKeyNumGroups(xkbdesc, code); + for (int grp = 0; grp < groups && !found; grp++) + { + int levels = XkbKeyGroupWidth(xkbdesc, code, grp); + for (int level = 0; level < levels && !found; level++) + { + if (sym == XkbKeySymEntry(xkbdesc, code, level, grp)) + { + // keysym found => determine modifiers + int typeIdx = xkbdesc->map->key_sym_map[code].kt_index[grp]; + XkbKeyTypePtr type = &(xkbdesc->map->types[typeIdx]); + for (int i = 0; i < type->map_count && !found; i++) + { + if (type->map[i].active && (type->map[i].level == level)) + { + modifiers = type->map[i].mods.mask; + found = true; + } + } + } + } + } + XkbFreeClientMap (xkbdesc, 0, true); + + if (!found) + return ""; // Somehow the keycode -> keysym mapping is flawed + + XEvent ev; + ev.type = KeyPress; + ev.xkey.display = display; + ev.xkey.keycode = code; + ev.xkey.state = 0; + int key; + KKeyServer::xEventToQt(&ev, &key); + QString keyname = QKeySequence(key).toString(); + + unsigned int AltMask = KKeyServer::modXAlt(); + unsigned int WinMask = KKeyServer::modXMeta(); + unsigned int NumMask = KKeyServer::modXNumLock(); + unsigned int ScrollMask= KKeyServer::modXScrollLock(); + + unsigned int MetaMask = XkbKeysymToModifiers (display, XK_Meta_L); + unsigned int SuperMask = XkbKeysymToModifiers (display, XK_Super_L); + unsigned int HyperMask = XkbKeysymToModifiers (display, XK_Hyper_L); + unsigned int AltGrMask = XkbKeysymToModifiers (display, XK_Mode_switch) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Shift) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Latch) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Lock); + + unsigned int mods = ShiftMask | ControlMask | AltMask | WinMask + | LockMask | NumMask | ScrollMask; + + AltGrMask &= ~mods; + MetaMask &= ~(mods | AltGrMask); + SuperMask &= ~(mods | AltGrMask | MetaMask); + HyperMask &= ~(mods | AltGrMask | MetaMask | SuperMask); + + if ((modifiers & AltGrMask) != 0) + keyname = i18n("AltGraph") + '+' + keyname; + if ((modifiers & HyperMask) != 0) + keyname = i18n("Hyper") + '+' + keyname; + if ((modifiers & SuperMask) != 0) + keyname = i18n("Super") + '+' + keyname; + if ((modifiers & WinMask) != 0) + keyname = i18n("Meta") + '+' + keyname; + if ((modifiers & WinMask) != 0) + keyname = QKeySequence(Qt::META).toString() + '+' + keyname; + if ((modifiers & AltMask) != 0) + keyname = QKeySequence(Qt::ALT).toString() + '+' + keyname; + if ((modifiers & ControlMask) != 0) + keyname = QKeySequence(Qt::CTRL).toString() + '+' + keyname; + if ((modifiers & ShiftMask) != 0) + keyname = QKeySequence(Qt::SHIFT).toString() + '+' + keyname; + + return keyname; +} + +void KAccessApp::createDialogContents() { + if (dialog == 0) { + dialog = new KDialog( 0 ); + dialog->setCaption( i18n("Warning") ); + dialog->setButtons( KDialog::Yes | KDialog::No ); + dialog->setButtonGuiItem( KDialog::Yes, KStandardGuiItem::yes() ); + dialog->setButtonGuiItem( KDialog::No, KStandardGuiItem::no() ); + dialog->setDefaultButton( KDialog::No ); + dialog->setEscapeButton( KDialog::Close ); + dialog->setObjectName( "AccessXWarning" ); + dialog->setModal( true ); + + KVBox *topcontents = new KVBox (dialog); + topcontents->setSpacing(KDialog::spacingHint()*2); +#ifdef __GNUC__ +#warning "kde4 fixme" +#endif + //topcontents->setMargin(KDialog::marginHint()); + + QWidget *contents = new QWidget(topcontents); + QHBoxLayout * lay = new QHBoxLayout(contents); + lay->setSpacing(KDialog::spacingHint()); + + QLabel *label1 = new QLabel( contents); + QPixmap pixmap = KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, KIconLoader::SizeMedium, KIconLoader::DefaultState, QStringList(), 0, true); + if (pixmap.isNull()) + pixmap = QMessageBox::standardIcon(QMessageBox::Warning); + label1->setPixmap(pixmap); + + lay->addWidget( label1, 0, Qt::AlignCenter ); + lay->addSpacing(KDialog::spacingHint()); + + QVBoxLayout * vlay = new QVBoxLayout(); + lay->addItem( vlay ); + + featuresLabel = new QLabel( "", contents ); + featuresLabel->setAlignment( Qt::AlignVCenter ); + featuresLabel->setWordWrap( true ); + vlay->addWidget( featuresLabel ); + vlay->addStretch(); + + QHBoxLayout * hlay = new QHBoxLayout(); + vlay->addItem(hlay); + + QLabel *showModeLabel = new QLabel( i18n("&When a gesture was used:"), contents ); + hlay->addWidget( showModeLabel ); + + showModeCombobox = new KComboBox (contents); + hlay->addWidget( showModeCombobox ); + showModeLabel->setBuddy(showModeCombobox); + showModeCombobox->insertItem ( 0, i18n("Change Settings Without Asking")); + showModeCombobox->insertItem ( 1, i18n("Show This Confirmation Dialog")); + showModeCombobox->insertItem ( 2, i18n("Deactivate All AccessX Features & Gestures")); + showModeCombobox->setCurrentIndex (1); + + dialog->setMainWidget(topcontents); + + connect (dialog, SIGNAL(yesClicked()), this, SLOT(yesClicked())); + connect (dialog, SIGNAL(noClicked()), this, SLOT(noClicked())); + connect (dialog, SIGNAL(closeClicked()), this, SLOT(dialogClosed())); + } +} + +void KAccessApp::xkbControlsNotify(XkbControlsNotifyEvent *event) +{ + unsigned int newFeatures = event->enabled_ctrls & (XkbSlowKeysMask | XkbBounceKeysMask | XkbStickyKeysMask | XkbMouseKeysMask); + + if (newFeatures != features) { + unsigned int enabled = newFeatures & ~features; + unsigned int disabled = features & ~newFeatures; + + if (!_gestureConfirmation) { + requestedFeatures = enabled | (requestedFeatures & ~disabled); + notifyChanges(); + features = newFeatures; + } + else { + // set the AccessX features back to what they were. We will + // apply the changes later if the user allows us to do that. + readSettings(); + + requestedFeatures = enabled | (requestedFeatures & ~disabled); + + enabled = requestedFeatures & ~features; + disabled = features & ~requestedFeatures; + + QStringList enabledFeatures; + QStringList disabledFeatures; + + if (enabled & XkbStickyKeysMask) + enabledFeatures << i18n("Sticky keys"); + else if (disabled & XkbStickyKeysMask) + disabledFeatures << i18n("Sticky keys"); + + if (enabled & XkbSlowKeysMask) + enabledFeatures << i18n("Slow keys"); + else if (disabled & XkbSlowKeysMask) + disabledFeatures << i18n("Slow keys"); + + if (enabled & XkbBounceKeysMask) + enabledFeatures << i18n("Bounce keys"); + else if (disabled & XkbBounceKeysMask) + disabledFeatures << i18n("Bounce keys"); + + if (enabled & XkbMouseKeysMask) + enabledFeatures << i18n("Mouse keys"); + else if (disabled & XkbMouseKeysMask) + disabledFeatures << i18n("Mouse keys"); + + QString question; + switch (enabledFeatures.count()) { + case 0: switch (disabledFeatures.count()) { + case 1: question = i18n("Do you really want to deactivate \"%1\"?", + disabledFeatures[0]); + break; + case 2: question = i18n("Do you really want to deactivate \"%1\" and \"%2\"?", + disabledFeatures[0], disabledFeatures[1]); + break; + case 3: question = i18n("Do you really want to deactivate \"%1\", \"%2\" and \"%3\"?", + disabledFeatures[0], disabledFeatures[1], + disabledFeatures[2]); + break; + case 4: question = i18n("Do you really want to deactivate \"%1\", \"%2\", \"%3\" and \"%4\"?", + disabledFeatures[0], disabledFeatures[1], + disabledFeatures[2], disabledFeatures[3]); + break; + } + break; + case 1: switch (disabledFeatures.count()) { + case 0: question = i18n("Do you really want to activate \"%1\"?", + enabledFeatures[0]); + break; + case 1: question = i18n("Do you really want to activate \"%1\" and to deactivate \"%2\"?", + enabledFeatures[0], disabledFeatures[0]); + break; + case 2: question = i18n("Do you really want to activate \"%1\" and to deactivate \"%2\" and \"%3\"?", + enabledFeatures[0], disabledFeatures[0], + disabledFeatures[1]); + break; + case 3: question = i18n("Do you really want to activate \"%1\" and to deactivate \"%2\", \"%3\" and \"%4\"?", + enabledFeatures[0], disabledFeatures[0], + disabledFeatures[1], disabledFeatures[2]); + break; + } + break; + case 2: switch (disabledFeatures.count()) { + case 0: question = i18n("Do you really want to activate \"%1\" and \"%2\"?", + enabledFeatures[0], enabledFeatures[1]); + break; + case 1: question = i18n("Do you really want to activate \"%1\" and \"%2\" and to deactivate \"%3\"?", + enabledFeatures[0], enabledFeatures[1], + disabledFeatures[0]); + break; + case 2: question = i18n("Do you really want to activate \"%1\", and \"%2\" and to deactivate \"%3\" and \"%4\"?", + enabledFeatures[0], enabledFeatures[1], + enabledFeatures[0], disabledFeatures[1]); + break; + } + break; + case 3: switch (disabledFeatures.count()) { + case 0: question = i18n("Do you really want to activate \"%1\", \"%2\" and \"%3\"?", + enabledFeatures[0], enabledFeatures[1], + enabledFeatures[2]); + break; + case 1: question = i18n("Do you really want to activate \"%1\", \"%2\" and \"%3\" and to deactivate \"%4\"?", + enabledFeatures[0], enabledFeatures[1], + enabledFeatures[2], disabledFeatures[0]); + break; + } + break; + case 4: question = i18n("Do you really want to activate \"%1\", \"%2\", \"%3\" and \"%4\"?", + enabledFeatures[0], enabledFeatures[1], + enabledFeatures[2], enabledFeatures[3]); + break; + } + QString explanation; + if (enabledFeatures.count()+disabledFeatures.count() == 1) { + explanation = i18n("An application has requested to change this setting."); + + if (_gestures) { + if ((enabled | disabled) == XkbSlowKeysMask) + explanation = i18n("You held down the Shift key for 8 seconds or an application has requested to change this setting."); + else if ((enabled | disabled) == XkbStickyKeysMask) + explanation = i18n("You pressed the Shift key 5 consecutive times or an application has requested to change this setting."); + else if ((enabled | disabled) == XkbMouseKeysMask) { + QString shortcut = mouseKeysShortcut(QX11Info::display()); + if (!shortcut.isEmpty() && !shortcut.isNull()) + explanation = i18n("You pressed %1 or an application has requested to change this setting.", shortcut); + } + } + } + else { + if (_gestures) + explanation = i18n("An application has requested to change these settings, or you used a combination of several keyboard gestures."); + else + explanation = i18n("An application has requested to change these settings."); + } + + createDialogContents(); + featuresLabel->setText ( question+"\n\n"+explanation + +" "+i18n("These AccessX settings are needed for some users with motion impairments and can be configured in the KDE System Settings. You can also turn them on and off with standardized keyboard gestures.\n\nIf you do not need them, you can select \"Deactivate all AccessX features and gestures\".") ); + + KWindowSystem::setState( dialog->winId(), NET::KeepAbove ); + kapp->updateUserTimestamp(); + dialog->show(); + } + } +} + +void KAccessApp::notifyChanges() { + if (!_kNotifyAccessX) + return; + + unsigned int enabled = requestedFeatures & ~features; + unsigned int disabled = features & ~requestedFeatures; + + if (enabled & XkbSlowKeysMask) + KNotification::event ("slowkeys", i18n("Slow keys has been enabled. From now on, you need to press each key for a certain length of time before it gets accepted.")); + else if (disabled & XkbSlowKeysMask) + KNotification::event ("slowkeys", i18n("Slow keys has been disabled.")); + + if (enabled & XkbBounceKeysMask) + KNotification::event ("bouncekeys", i18n("Bounce keys has been enabled. From now on, each key will be blocked for a certain length of time after it was used.")); + else if (disabled & XkbBounceKeysMask) + KNotification::event ("bouncekeys", i18n("Bounce keys has been disabled.")); + + if (enabled & XkbStickyKeysMask) + KNotification::event ("stickykeys", i18n("Sticky keys has been enabled. From now on, modifier keys will stay latched after you have released them.")); + else if (disabled & XkbStickyKeysMask) + KNotification::event ("stickykeys", i18n("Sticky keys has been disabled.")); + + if (enabled & XkbMouseKeysMask) + KNotification::event ("mousekeys", i18n("Mouse keys has been enabled. From now on, you can use the number pad of your keyboard in order to control the mouse.")); + else if (disabled & XkbMouseKeysMask) + KNotification::event ("mousekeys", i18n("Mouse keys has been disabled.")); +} + +void KAccessApp::applyChanges() { + notifyChanges(); + unsigned int enabled = requestedFeatures & ~features; + unsigned int disabled = features & ~requestedFeatures; + + KConfigGroup config(KGlobal::config(), "Keyboard"); + + if (enabled & XkbSlowKeysMask) + config.writeEntry("SlowKeys", true); + else if (disabled & XkbSlowKeysMask) + config.writeEntry("SlowKeys", false); + + if (enabled & XkbBounceKeysMask) + config.writeEntry("BounceKeys", true); + else if (disabled & XkbBounceKeysMask) + config.writeEntry("BounceKeys", false); + + if (enabled & XkbStickyKeysMask) + config.writeEntry("StickyKeys", true); + else if (disabled & XkbStickyKeysMask) + config.writeEntry("StickyKeys", false); + + KConfigGroup mousegrp(KGlobal::config(),"Mouse"); + + if (enabled & XkbMouseKeysMask) + mousegrp.writeEntry("MouseKeys", true); + else if (disabled & XkbMouseKeysMask) + mousegrp.writeEntry("MouseKeys", false); + mousegrp.sync(); + config.sync(); +} + +void KAccessApp::yesClicked() { + if (dialog != 0) + dialog->deleteLater(); + dialog = 0; + + KConfigGroup config(KGlobal::config(), "Keyboard"); + switch (showModeCombobox->currentIndex()) { + case 0: + config.writeEntry("Gestures", true); + config.writeEntry("GestureConfirmation", false); + break; + default: + config.writeEntry("Gestures", true); + config.writeEntry("GestureConfirmation", true); + break; + case 2: + requestedFeatures = 0; + config.writeEntry("Gestures", false); + config.writeEntry("GestureConfirmation", true); + } + config.sync(); + + if (features != requestedFeatures) { + notifyChanges(); + applyChanges(); + } + readSettings(); +} + +void KAccessApp::noClicked() { + if (dialog != 0) + dialog->deleteLater(); + dialog = 0; + requestedFeatures = features; + + KConfigGroup config(KGlobal::config(), "Keyboard"); + switch (showModeCombobox->currentIndex()) { + case 0: + config.writeEntry("Gestures", true); + config.writeEntry("GestureConfirmation", false); + break; + default: + config.writeEntry("Gestures", true); + config.writeEntry("GestureConfirmation", true); + break; + case 2: + requestedFeatures = 0; + config.writeEntry("Gestures", false); + config.writeEntry("GestureConfirmation", true); + } + config.sync(); + + if (features != requestedFeatures) + applyChanges(); + readSettings(); +} + +void KAccessApp::dialogClosed() { + if (dialog != 0) + dialog->deleteLater(); + dialog = 0; + + requestedFeatures = features; +} + +void KAccessApp::setXkbOpcode(int opcode) { + xkb_opcode = opcode; +} diff --git a/kcontrol/access/kaccess.desktop b/kcontrol/access/kaccess.desktop new file mode 100644 index 00000000..3e0262ea --- /dev/null +++ b/kcontrol/access/kaccess.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Type=Service +Name=KDE Accessibility Tool +Name[af]=KDE toeganklikheid program +Name[ar]=أداة كدي للإتاحة +Name[ast]=Ferramienta d'accesibilidad de KDE +Name[be]=Інструмент даступнасці KDE +Name[be@latin]=Pryłada dastupnaści KDE +Name[bg]=Равностоен достъп +Name[bn]=কে.ডি.ই. সহায়ক প্রযুক্তি টুল +Name[br]=Ostilh haezadusted KDE +Name[bs]=KDE alat za pristupačnost +Name[ca]=Eina d'accessibilitat KDE +Name[ca@valencia]=Eina d'accessibilitat KDE +Name[cs]=Nástroj pro zpřístupnění prostředí KDE +Name[csb]=Pòmòce przëstãpù KDE +Name[cy]=Erfyn Hygyrchedd KDE +Name[da]=KDE Tilgængelighedsværktøj +Name[de]=KDE-Zugangshilfen +Name[el]=Εργαλείο προσιτότητας του KDE +Name[en_GB]=KDE Accessibility Tool +Name[eo]=KDE-ilo por alirebleco +Name[es]=Herramienta de accesibilidad de KDE +Name[et]=KDE hõlbustustööriist +Name[eu]=KDEren erabilerraztasun-tresna +Name[fa]=ابزار دستیابی‌پذیری KDE +Name[fi]=KDE:n esteettömyystyökalu +Name[fr]=Outil d'accessibilité de KDE +Name[fy]=KDE Tagonklikens +Name[ga]=Uirlis Inrochtaineachta KDE +Name[gl]=Utilidade de accesibilidade de KDE +Name[gu]=KDE ઉપયોગિતા સાધન +Name[he]=כלי הנגישות של KDE +Name[hi]=केडीई पहुँच औज़ार +Name[hne]=केडीई पहुंच औजार +Name[hr]=KDE pristupačnost +Name[hsb]=KDE pomocnik za přistupnosć +Name[hu]=KDE kezelési segédeszköz +Name[ia]=Instrumento de Accessibilitate de KDE +Name[id]=Alat Aksesibilitas KDE +Name[is]=KDE aðgengistól +Name[it]=Strumento per l'accessibilità di KDE +Name[ja]=KDE アクセシビリティ支援ツール +Name[ka]=KDE-ს სპეცეციალური შესაძლებლობების ხელსაწყოები +Name[kk]=KDE арнайы мүмкіндіктер құралы +Name[km]=ឧបករណ៍​មធ្យោបាយ​ងាយស្រួល​របស់ KDE +Name[kn]=ಕೆಡಿಇ ನಿಲುಕಣೆ (ಅಕ್ಸೆಸಿಬಲಿಟಿ) ಸಲಕರಣೆ +Name[ko]=KDE 접근성 도구 +Name[ku]=KDE Amûra Xwegihandinê +Name[lt]=KDE pritaikymo neįgaliesiems įrankis +Name[lv]=KDE pieejamības rīks +Name[mai]=केडीई पहुँच अओजार +Name[mk]=Алатка за пристапливост во KDE +Name[ml]=കെഡിഇ സാമീപ്യതാ ഉപകരണം +Name[mr]=केडीई सुलभता साधन +Name[ms]=Alat Keaksesan KDE +Name[nb]=Tilgjengelighetsverktøy for KDE +Name[nds]=KDE-Togangwarktüüch +Name[ne]=केडीई पहुँचयोग्य उपकरण +Name[nl]=KDE Toegankelijkheid +Name[nn]=Tilgjengeverktøy for KDE +Name[oc]=Esplech d'accessibilitat de KDE +Name[or]=KDE ଅଭିଗମ୍ୟତା ଉପକରଣ +Name[pa]=KDE ਸਹਾਇਕ ਟੂਲ +Name[pl]=Narzędzie ułatwień dostępu KDE +Name[pt]=Ferramenta de Acessibilidade do KDE +Name[pt_BR]=Ferramenta de Acessibilidade do KDE +Name[ro]=Utilitar de accesibilitate pentru KDE +Name[ru]=Специальные возможности +Name[se]=KDE reaidu álkkibut geavaheami várás +Name[si]=KDE ප්‍රවේශන මෙවලම +Name[sk]=Nástroj na sprístupnenie KDE +Name[sl]=Orodje za dostopnost KDE +Name[sr]=КДЕ‑ова алатка за приступачност +Name[sr@ijekavian]=КДЕ‑ова алатка за приступачност +Name[sr@ijekavianlatin]=KDE‑ova alatka za pristupačnost +Name[sr@latin]=KDE‑ova alatka za pristupačnost +Name[sv]=Handikappverktyg för KDE +Name[ta]=KDE அணுகும் கருவி +Name[te]=KDE అందుబాటు సాధనం +Name[tg]=Имкониятҳои KDE +Name[th]=เครื่องมือปรับการช่วยการใช้งานของ KDE +Name[tr]=KDE Erişilebilirlik Aracı +Name[ug]=ك د ئې(KDE) ياردەمچى ئىقتىدار قوراللىرى +Name[uk]=Утиліта керування доступності KDE +Name[uz]=KDE qulaylik vositasi +Name[uz@cyrillic]=KDE қулайлик воситаси +Name[vi]=Công cụ hỗ trợ truy cập của KDE +Name[wa]=Usteye d' accessibilité di KDE +Name[x-test]=xxKDE Accessibility Toolxx +Name[zh_CN]=KDE 辅助工具 +Name[zh_TW]=KDE 無障礙工具 +Exec=kaccess +X-DBUS-StartupType=None +X-KDE-Library=kcm_access +X-KDE-ParentApp=kcontrol +X-DocPath=kcontrol/kcmaccess/index.html diff --git a/kcontrol/access/kaccess.h b/kcontrol/access/kaccess.h new file mode 100644 index 00000000..c364b251 --- /dev/null +++ b/kcontrol/access/kaccess.h @@ -0,0 +1,115 @@ +#ifndef __K_ACCESS_H__ +#define __K_ACCESS_H__ + + +#include +#include +//Added by qt3to4: +#include +#include + + +#include +#include + +#include + +#include +#define explicit int_explicit // avoid compiler name clash in XKBlib.h +#include +#undef explicit + +class KDialog; +class QLabel; +class KComboBox; + +class KAccessApp : public KUniqueApplication +{ + Q_OBJECT + +public: + + explicit KAccessApp(bool allowStyles=true, bool GUIenabled=true); + + bool x11EventFilter(XEvent *event); + + int newInstance(); + + void setXkbOpcode(int opcode); + +protected: + + void readSettings(); + + void xkbStateNotify(); + void xkbBellNotify(XkbBellNotifyEvent *event); + void xkbControlsNotify(XkbControlsNotifyEvent *event); + + +private Q_SLOTS: + + void activeWindowChanged(WId wid); + void notifyChanges(); + void applyChanges(); + void yesClicked(); + void noClicked(); + void dialogClosed(); + + +private: + void createDialogContents(); + void initMasks(); + + int xkb_opcode; + unsigned int features; + unsigned int requestedFeatures; + + bool _systemBell, _artsBell, _visibleBell, _visibleBellInvert; + QColor _visibleBellColor; + int _visibleBellPause; + + bool _gestures, _gestureConfirmation; + bool _kNotifyModifiers, _kNotifyAccessX; + + QWidget *overlay; + + Phonon::MediaObject *_player; + QString _currentPlayerSource; + + WId _activeWindow; + + KDialog *dialog; + QLabel *featuresLabel; + KComboBox *showModeCombobox; + + int keys[8]; + int state; +}; + + +class VisualBell : public QWidget +{ + Q_OBJECT + +public: + + VisualBell(int pause) + : QWidget(( QWidget* )0, Qt::X11BypassWindowManagerHint), _pause(pause) + {} + + +protected: + + void paintEvent(QPaintEvent *); + + +private: + + int _pause; + +}; + + + + +#endif diff --git a/kcontrol/access/kaccess.notifyrc b/kcontrol/access/kaccess.notifyrc new file mode 100644 index 00000000..06c80cdf --- /dev/null +++ b/kcontrol/access/kaccess.notifyrc @@ -0,0 +1,1532 @@ +[Global] +IconName=preferences-desktop-accessibility +Comment=Accessibility +Comment[af]=Toeganklikheid +Comment[ar]=الإتاحة +Comment[as]=অভিগম্যতা +Comment[ast]=Accesibilidá +Comment[be]=Даступнасць +Comment[be@latin]=Dastupnaść +Comment[bg]=Равностоен достъп +Comment[bn]=সহায়ক প্রযুক্তি +Comment[bn_IN]=বিশেষ ব্যবহারের সহায়তা +Comment[br]=Haezadusted +Comment[bs]=Pristupačnost +Comment[ca]=Accessibilitat +Comment[ca@valencia]=Accessibilitat +Comment[cs]=Zpřístupnění +Comment[csb]=Pòmòce przëstãpù +Comment[cy]=Hygyrchedd +Comment[da]=Tilgængelighed +Comment[de]=Zugangshilfen +Comment[el]=Προσβασιμότητα +Comment[en_GB]=Accessibility +Comment[eo]=Alirebleco +Comment[es]=Accesibilidad +Comment[et]=Hõlbustus +Comment[eu]=Erabilerraztasuna +Comment[fa]=دستیابی‌پذیری +Comment[fi]=Esteettömyys +Comment[fr]=Accessibilité +Comment[fy]=Tagonklikens +Comment[ga]=Inrochtaineacht +Comment[gl]=Accesibilidade +Comment[gu]=ઉપયોગિતા +Comment[he]=נגישות +Comment[hi]=पहुँच +Comment[hne]=पहुंच +Comment[hr]=Pristupačnost +Comment[hsb]=Přistupnosć +Comment[hu]=Kezelési segítség +Comment[ia]=Accessibilitate +Comment[id]=Aksesibilitas +Comment[is]=Auðveldað aðgengi +Comment[it]=Accessibilità +Comment[ja]=アクセシビリティ +Comment[kk]=Арнайы мүмкіндіктер +Comment[km]=មធ្យោបាយ​ងាយស្រួល +Comment[kn]=ನಿಲುಕಣೆ (ಆಕ್ಸೆಸಿಬಿಲಿಟಿ) +Comment[ko]=내게 필요한 설정 +Comment[ku]=Gihîştin +Comment[lt]=Pritaikymas neįgaliesiems +Comment[lv]=Pieejamība +Comment[mai]=अभिगम्यता +Comment[mk]=Пристапливост +Comment[ml]=സാമീപ്യത +Comment[mr]=सुलभता +Comment[ms]=Kebolehcapaian +Comment[nb]=Tilgjengelighet +Comment[nds]=Toganghülp +Comment[ne]=पहुँचता +Comment[nl]=Toegankelijkheid +Comment[nn]=Tilgjenge +Comment[oc]=Accessibilitat +Comment[or]=ଅଭିଗମ୍ୟତା +Comment[pa]=ਸਹੂਲਤਾਂ +Comment[pl]=Ułatwienia dostępu +Comment[pt]=Acessibilidade +Comment[pt_BR]=Acessibilidade +Comment[ro]=Accesibilitate +Comment[ru]=Специальные возможности +Comment[se]=Álkkibut geavaheapmi +Comment[si]=ප්‍රවේශණය +Comment[sk]=Prístupnosť +Comment[sl]=Dostopnost +Comment[sr]=Приступачност +Comment[sr@ijekavian]=Приступачност +Comment[sr@ijekavianlatin]=Pristupačnost +Comment[sr@latin]=Pristupačnost +Comment[sv]=Handikappstöd +Comment[ta]=அணுகுத்தன்மை +Comment[te]=అందుబాటు +Comment[tg]=Имкониятҳо +Comment[th]=ช่วยการใช้งานให้ง่ายขึ้น +Comment[tr]=Erişilebilirlik +Comment[ug]=قوشۇمچە ئىقتىدار +Comment[uk]=Доступність +Comment[uz]=Qulayliklar +Comment[uz@cyrillic]=Қулайликлар +Comment[vi]=Hỗ trợ truy cập +Comment[wa]=Accessibilité +Comment[x-test]=xxAccessibilityxx +Comment[zh_CN]=辅助 +Comment[zh_TW]=無障礙輔助 + +[Event/modifierkey-latched] +Name=A modifier key has become active +Name[af]='n Verandering sleutel was geaktiveer +Name[ar]=تم تفعيل مفتاح مغيِّر +Name[ast]=Activosé una tecla modificadora +Name[be@latin]=Klavišny madyfikatar prycisnuty +Name[bg]=Включен е клавиш-модификатор +Name[bn]=একটি মডিফায়ার কী সক্রিয় হয়েছে +Name[bs]=Modifikatorski taster je aktiviran +Name[ca]=Alguna tecla modificadora ha esdevingut activa +Name[ca@valencia]=Alguna tecla modificadora ha esdevingut activa +Name[cs]=Modifikátor klávesnice je aktivní +Name[csb]=Klawisza zjinaczi òsta aktiwòwónô +Name[da]=En ændringstast er blevet aktiv +Name[de]=Eine Modifikator-Taste ist aktiviert worden +Name[el]=Ένα πλήκτρο τροποποιητή έγινε ενεργό +Name[en_GB]=A modifier key has become active +Name[eo]=Modifigita klavo aktiviĝis +Name[es]=Se ha activado una tecla modificadora +Name[et]=Muuteklahv muutus aktiivseks +Name[eu]=Tekla aldatzaile bat aktibatu da +Name[fi]=Muunnosnäppäin on aktivoitunut +Name[fr]=Une touche de modification est devenue active +Name[fy]=In modifkaasjetoets wurdt aktyf +Name[ga]=Tá eochair mhionathraithe gníomhach anois +Name[gl]=Activouse unha tecla modificadora +Name[gu]=બદલવાની કળ સક્રિય બની છે +Name[he]=מקש משנה מצב הפך לפעיל +Name[hi]=कोई मॉडिफ़ायर कुंजी सक्रिय हो गया है +Name[hne]=कोई माडिफायर कुंजी सक्रिय हो गे हे +Name[hr]=Tipka modifikatora je aktivirana +Name[hsb]=Modifikowaca tasta je so aktiwizowała. +Name[hu]=Egy módosító billentyű aktívvá vált +Name[ia]=Un clave de modificator ha devenite active +Name[id]=Sebuah tombol pengubah telah menjadi aktif +Name[is]=Breytilykill er nú virkur +Name[it]=Un tasto modificatore è stato attivato +Name[ja]=修飾キーがアクティブになりました +Name[kk]=Түрлендіргіш перне белсендірілді +Name[km]=គ្រាប់​ចុច​កែប្រែ​ក្លាយ​ជា​សកម្ម +Name[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿ ಸಕ್ರಿಯಗೊಂಡಿದೆ +Name[ko]=수정자 키가 활성화됨 +Name[ku]=Bişkojkeke Guherker hat çalakirin +Name[lt]=Modifikavimo klavišas tapo aktyvus +Name[lv]=Modifikatora taustiņš tika aktivizēts +Name[mk]=Некое копче за модификација стана активно +Name[ml]=ഒരു മോഡിഫയര്‍ കീ സജീവമായിരിക്കുന്നു +Name[mr]=परिवर्तक कि सक्रिय झाली आहे +Name[nb]=En valgtast er slått på +Name[nds]=En Sünnertast is nu aktiev +Name[ne]=परिमार्जक कुञ्जी सक्रिय भएको छ +Name[nl]=Een modificatietoets is geactiveerd +Name[nn]=Ein valtast er no aktiv +Name[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି ସକ୍ରିୟ ହୋଇଯାଇଛି +Name[pa]=ਮੋਡੀਫਾਇਰ ਸਵਿੱਚ ਐਕਟਿਵ ਕੀਤੀ ਗਈ +Name[pl]=Klawisz modyfikujący został włączony +Name[pt]=Ficou activa uma tecla modificadora +Name[pt_BR]=Uma tecla modificadora se tornou ativa +Name[ro]=Un modificator de taste a devenit activ +Name[ru]=Нажата клавиша-модификатор +Name[se]=Válljenboallu lea šaddan aktiiva +Name[si]=වෙනස්කිරීම් යතුර සක්‍රීයයි +Name[sk]=Modifikačný kláves je aktívny +Name[sl]=Spremenilna tipka se je omogočila +Name[sr]=Модификаторски тастер је активиран +Name[sr@ijekavian]=Модификаторски тастер је активиран +Name[sr@ijekavianlatin]=Modifikatorski taster je aktiviran +Name[sr@latin]=Modifikatorski taster je aktiviran +Name[sv]=En väljartangent har aktiverats +Name[ta]=A modifier key has become active +Name[te]=సవరింపు కీ క్రియాశీలం కాబోతోంది +Name[tg]=Нажата клавиша модификатора +Name[th]=ปุ่มพิมพ์ประกอบถูกเปิดการทำงาน +Name[tr]=Bir değiştirici tuş etkinleştirildi +Name[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا ئاكتىپلاندى +Name[uk]=Клавіша модифікатора стала активною +Name[wa]=Ene modifieuse tape a divnou active +Name[x-test]=xxA modifier key has become activexx +Name[zh_CN]=修饰键已经激活 +Name[zh_TW]=組合鍵已啟動 +Comment=A modifier key (e.g. Shift or Ctrl) has changed its state and is now active +Comment[af]='n Veranderingsleutel (bv. Shift of Control) se toestand het verander en is nou aktief +Comment[ar]=مفتاح مغيِّر (شفت او كنترول) غيّر حالته وأصبح مفعلاً +Comment[ast]=Una tecla modificadora (Mayús o Ctrl) camudó l'estáu y ta activa +Comment[be@latin]=Klavišny madyfikatar (naprykład, „Shift” ci „Ctrl”) źmianiŭ svajo stanovišča j ciapier prycisnuty. +Comment[bg]=Клавиш-модификатор (напр. Shift или Ctrl) промени състоянието си и е активен +Comment[bn]=একটি মডিফায়ার কী (e.g. Shift বা Ctrl) অবস্থা পরিবর্তন করে এখন সক্রিয় হয়েছে +Comment[bs]=Modifikatorski taster (npr. Shift ili Ctrl) promijenio je stanje i sada je aktivan +Comment[ca]=Ha canviat l'estat d'una tecla modificadora (p.ex. Majúscules o Control) i ara està activa +Comment[ca@valencia]=Ha canviat l'estat d'una tecla modificadora (p.ex. Majúscules o Control) i ara està activa +Comment[cs]=Modifikátor klávesnice (Shift nebo Ctrl) změnil stav a je právě aktivní +Comment[csb]=Klawisza zjinaczi (Shift abò Control) zmienia swój sztatus ë je aktiwòwónô +Comment[da]=En ændringstast (f.eks. Skift eller Ctrl) har ændret sin tilstand og er nu aktiv +Comment[de]=Eine Modifikator-Taste (Umschalt oder Strg) hat ihren Status verändert und ist nun aktiv +Comment[el]=Ένα πλήκτρο τροποποιητή (π.χ., Shift ή Ctrl) άλλαξε την κατάστασή του και είναι τώρα ενεργό +Comment[en_GB]=A modifier key (e.g. Shift or Ctrl) has changed its state and is now active +Comment[eo]=Modifa klavo (ekz. majuskliga klavo aŭ stirklavo) ŝanĝis sian staton kaj nun estas aktiva +Comment[es]=Una tecla modificadora (Mayús o Ctrl) ha cambiado su estado y está activa +Comment[et]=Muuteklahv (nt. Shift või Ctrl) muutis oma olekut ning on nüüd aktiivne +Comment[eu]=Tekla aldatzaile bat (adibidez, Maius edo Ktrl) egoeraz aldatu da, eta orain aktibo dago +Comment[fi]=Muunnosnäppäin (esim. Shift tai Ctrl) on vaihtanut tilaa ja on nyt aktiivinen +Comment[fr]=Une touche de modification (ex : « Maj. » ou « Ctrl. ») a changé d'état et est maintenant active +Comment[fy]=De tastân fan in modifikaasjetoets (lykas Shift of Control) is feroare en is no aktyf +Comment[ga]=Athraíodh staid eochrach mionathraithe (m.sh. Shift nó Ctrl) agus tá sí gníomhach anois +Comment[gl]=Unha tecla modificadora (por ex. Maiúsc ou Control) mudou de estado e agora está activa +Comment[gu]=બદલવાની કળે (દા.ત., શીફ્ટ અથવા કંટ્રોલ) હવે તેની સ્થિતિ બદલી છે અને હવે સક્રિય છે +Comment[he]=מקש משנה מצב (למשל Shift או Ctrl) שינה את מצבו וכרגע פעיל +Comment[hne]=कोई माडिफायर कुंजी (जइसन कि शिफ्ट या कंट्रोल) हर अपन स्थिति ल बदल दे हे अउ अब वो हर सक्रिय हो गे हे +Comment[hr]=Tipka modifikatora (npr. SHIFT ili CTRL) promijenila je svoje stanje i aktivna je +Comment[hsb]=Modifikowaca tasta (na př. Wulkopis abo Strg) je status změniła a je nětko aktiwna. +Comment[hu]=Egy módosító billentyű (pl. a Shift vagy a Ctrl) aktívvá vált +Comment[ia]=Un clave modificator (p.ex. Shift o Ctrl) ha cambiate su stato e ora es active +Comment[id]=Sebuah tombol pengubah (misalnya Shift atau Ctrl) telah diubah keadaannya dan sekarang aktif +Comment[is]=Breytilykill (t.d. Shift eða Ctrl) hefur breytt um stöðu og er nú virkur +Comment[it]=Un tasto modificatore (come Shift o Ctrl) ha cambiato stato ed è ora attivo +Comment[ja]=修飾キー (Shift や Ctrl) の状態が変更され、アクティブになりました +Comment[kk]=Түрлендіргіш перне (мыс. Shift не Ctrl) күйін ауыстырып енді белсенді +Comment[km]=គ្រាប់ចុច​កែប្រែ (ឧ. ប្ដូរ (Shift) ឬ​ជំនួស (Control)) បាន​ផ្លាស់ប្ដូរ​សភាព​របស់​វា ឥឡូវ​នេះ​សកម្ម +Comment[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿ (ಉ.ದಾ Shift ಅಥವಾ Ctrl) ನ ಸ್ಥಿತಿಯು ಬದಲಾಗಿದ್ದು ಈಗ ಸಕ್ರಿಯಗೊಂಡಿದೆ +Comment[ko]=Shift나 Control 키 같은 수정자 키의 상태가 바뀌었고 현재 사용 가능함 +Comment[ku]=Bişkojkeke Guherker (mînak Shift an jî Ctrl) ciyê xwe guherand û niha çalak e +Comment[lt]=Klavišo – modifikatoriaus (pvz., Lyg2(Shift) arba Vald(Ctrl)) būsena pakito ir jis dabar – aktyvus +Comment[lv]=Modifikatora taustiņš (piem. Shift vai Control) ir mainījis stāvokli un tagad ir aktīvs +Comment[mk]=Некое копче за модификација (пр. Shift или Ctrl) си ја смени состојбата и сега е активно +Comment[ml]=ഒരു മോഡിഫയര്‍ കീ (ഉദാ. ഷിഫ്ട് അല്ലെങ്കില്‍ കണ്ട്രോള്‍) അവസ്ഥ മാറി സജീവമായിരിക്കുന്നു +Comment[mr]=परिवर्तक कि (उ.दा. Shift किंवा Ctrl) याने स्तर बदलविले आहे व आता सक्रिय आहे +Comment[nb]=En valgtast (f.eks. Shift eller Ctrl) har endret status og er nå slått på +Comment[nds]=En Sünnertast (Ümschalt oder Stüern (Strg) a.B.) hett sien Tostand ännert un is nu aktiev +Comment[nl]=Een modificatietoets (bijv. Shift of Ctrl) is nu actief +Comment[nn]=Ein valtast (som «Shift» eller «Ctrl») har endra status, og er no aktiv +Comment[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି (ଯେପରିକି Shift କିମ୍ବା Ctrl) ସେମାନଙ୍କର ସ୍ଥିତି ପରିବର୍ତ୍ତନ କରିଅଛି ଏବଂ ବର୍ତ୍ତମାନ ସକ୍ରିୟ ଅଛି +Comment[pl]=Klawisz modyfikujący (np. Shift lub Ctrl) zmienił stan i jest teraz włączony +Comment[pt]=Uma tecla modificadora (p.ex., o Shift ou o Control) mudou o seu estado e ficou agora activa +Comment[pt_BR]=Uma tecla modificadora (p.ex. Shift ou Ctrl) teve seu estado alterado e agora está ativa +Comment[ro]=Un modificator de taste (cum ar fi Shift sau Ctrl) și-a schimbat starea și este acum activ +Comment[ru]=Клавиша-модификатор (например, Shift или Ctrl) изменила состояние и сейчас активна +Comment[si]=වෙනස් කරීමේ යතුරේ (උදා. Shift හෝ Ctrl) තත්වය වෙනස් වී ඇති අතර එය දැන් සක්‍රීයයි +Comment[sk]=Modifikačný kláves (napr. Shift alebo Ctrl) zmenil svoj stav a je teraz aktívny. +Comment[sl]=Spremenilna tipka (npr. Shift ali Ctrl) je spremenila stanje in je sedaj dejavna +Comment[sr]=Модификаторски тастер (нпр. Shift или Ctrl) променио је стање и сада је активан +Comment[sr@ijekavian]=Модификаторски тастер (нпр. Shift или Ctrl) промијенио је стање и сада је активан +Comment[sr@ijekavianlatin]=Modifikatorski taster (npr. Shift ili Ctrl) promijenio je stanje i sada je aktivan +Comment[sr@latin]=Modifikatorski taster (npr. Shift ili Ctrl) promenio je stanje i sada je aktivan +Comment[sv]=En väljartangent (t.ex. Skift eller Ctrl) har ändrat tillstånd och är nu aktiv +Comment[ta]=A modifier key (e.g. Shift or Ctrl) has changed its state and is now active +Comment[te]=సవరింపు కీ (ఉ.దా. Shift లేదా Ctrl) దానియొక్క స్థితి మార్చుకుంది మరియు ఇప్పుడు క్రియాశీలంగా ఉంది +Comment[tg]=Клавиша модификатора (например, Shift или Ctrl) изменила состояние и сейчас активна +Comment[th]=ปุ่มพิมพ์ประกอบ (เช่น Shift หรือ Ctrl) มีการเปลี่ยนสถานะของตัวมัน และตอนนี้กำลังทำงานอยู่ +Comment[tr]=Bir değiştirici tuşun (Shift veya Ctrl gibi) durumu değiştirildi ve etkinleştirildi +Comment[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا (مەسىلەن، Shift ياكى Ctrl) ئۇنىڭ ھالىتىنى ئۆزگەرتىپ ھازىر ئاكتىپلاشتۇرۇلدى +Comment[uk]=Клавіша модифікатора (наприклад Shift або Ctrl) змінила свій стан і тепер активна +Comment[wa]=Ene modifieuse tape (metans MAJ oudonbén CTRL) a candjî si estat eyet est asteure active +Comment[x-test]=xxA modifier key (e.g. Shift or Ctrl) has changed its state and is now activexx +Comment[zh_CN]=修饰键(如 Shift 或 Ctrl)更改了其状态,现已激活 +Comment[zh_TW]=一個組合鍵(如 Shift 或 Ctrl 等)已改變了它的狀態成為啟動 +Sound=KDE-Sys-Special.ogg + +nopresentation=236 + +[Event/modifierkey-unlatched] +Name=A modifier key has become inactive +Name[af]='n Verandering sleutel was gedeaktiveer +Name[ar]=تم إلغاء مفتاح مغيِّر +Name[ast]=Desactivóse una tecla modificadora +Name[be@latin]=Klavišny madyfikatar adcisnuty +Name[bg]=Изключен е клавиш-модификатор +Name[bn]=একটি মডিফায়ার কী নিষ্ক্রীয় হয়েছে +Name[bs]=Modifikatorski taster je deaktiviran +Name[ca]=Alguna tecla modificadora ha esdevingut inactiva +Name[ca@valencia]=Alguna tecla modificadora ha esdevingut inactiva +Name[cs]=Modifikátor klávesnice je neaktivní +Name[csb]=Klawisza zjiaczi òsta deaktiwòwónô +Name[da]=En ændringstast er blevet deaktiveret +Name[de]=Eine Modifikator-Taste ist deaktiviert worden +Name[el]=Ένα πλήκτρο τροποποιητή έγινε ανενεργό +Name[en_GB]=A modifier key has become inactive +Name[eo]=Modifigita klavo malaktiviĝis +Name[es]=Se ha desactivado una tecla modificadora +Name[et]=Muuteklahv muutus mitteaktiivseks +Name[eu]=Tekla aldatzaile bat inaktibatu da +Name[fi]=Muunnosnäppäin ei ole enää aktiivinen +Name[fr]=Une touche de modification est devenue inactive +Name[fy]=In modifikaasjetoets wurdt ynaktief +Name[ga]=Tá eochair mhionathraithe neamhghníomhach anois +Name[gl]=Desactivouse unha tecla modificadora +Name[gu]=બદલવાની કળ નિષ્ક્રિય બની છે +Name[he]=מקש משנה מצב הפך ללא פעיל +Name[hi]=कोई मॉडिफ़ायर कुंजी अक्रिय हो गया है +Name[hne]=कोई माडिफायर कुंजी हर अक्रिय हो गे हे +Name[hr]=Tipka modifikatora je deaktivirana +Name[hsb]=Modifikowaca tasta je so stała njeaktiwna +Name[hu]=Egy módosító billentyű inaktívvá vált +Name[ia]=Un clave modificator ha devenite inactive +Name[id]=Sebuah tombol pengubah telah menjadi tidak aktif +Name[is]=Breytilykill er nú óvirkur +Name[it]=Un tasto modificatore è stato disattivato +Name[ja]=修飾キーが非アクティブになりました +Name[kk]=Түрлендіргіш перне белсенсіздірілді +Name[km]=គ្រាប់​ចុច​កែប្រែ​បាន​ក្លាយ​ជា​អសកម្ម +Name[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ +Name[ko]=수정자 키가 비활성화됨 +Name[ku]=Bişkojkeke Guherker hat neçalakirin +Name[lt]=Klavišas – modifikatorius tapo neaktyvus +Name[lv]=Modifikatora taustiņš tika deaktivizēts +Name[mk]=Некое копче за модификација стана неактивно +Name[ml]=ഒരു മോഡിഫയര്‍ കീ നിര്‍ജീവമായിരിക്കുന്നു +Name[mr]=परिवर्तक कि निष्क्रिय झाली आहे +Name[nb]=En valgtast er slått av +Name[nds]=En Sünnertast is nich mehr aktiev +Name[ne]=परिमार्जक कुञ्जी निष्क्रिय भएको छ +Name[nl]=Een modificatietoets is inactief geworden +Name[nn]=Ein valtast er no inaktiv +Name[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି ନିଷ୍କ୍ରିୟ ହୋଇଯାଇଛି +Name[pa]=ਮੋਡੀਫਾਇਰ ਸਵਿੱਚ ਇਨ-ਐਕਟਿਵ ਕੀਤੀ ਗਈ +Name[pl]=Klawisz modyfikujący został wyłączony +Name[pt]=Ficou inactiva uma tecla modificadora +Name[pt_BR]=Uma tecla modificadora se tornou inativa +Name[ro]=Un modificator de taste a devenit inactiv +Name[ru]=Клавиша модификатора отпущена +Name[se]=Válljenboallu ii leat šat aktiiva +Name[si]=වෙනස්කිරීම් යතුර අක්‍රීයයි +Name[sk]=Modifikačný kláves je neaktívny +Name[sl]=Spremenilna tipka se je onemogočila +Name[sr]=Модификаторски тастер је деактивиран +Name[sr@ijekavian]=Модификаторски тастер је деактивиран +Name[sr@ijekavianlatin]=Modifikatorski taster je deaktiviran +Name[sr@latin]=Modifikatorski taster je deaktiviran +Name[sv]=En väljartangent har inaktiverats +Name[ta]=A modifier key has become inactive +Name[te]=సవరింపు కీ క్రియాహీనం కాబోతోంది +Name[tg]=Клавиша модификатора не активна +Name[th]=ปุ่มพิมพ์ประกอบถูกปิดการทำงาน +Name[tr]=Bir değiştirici tuş pasifleştirildi +Name[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا پاسسىپلاشتۇرۇلدى +Name[uk]=Клавіша модифікатора стала неактивною +Name[wa]=Ene modifieuse tape a divnou nén active +Name[x-test]=xxA modifier key has become inactivexx +Name[zh_CN]=修饰键现已停用 +Name[zh_TW]=組合鍵已放開 +Comment=A modifier key (e.g. Shift or Ctrl) has changed its state and is now inactive +Comment[af]='n Veranderingsleutel (bv. Shift of Contorl) se toestand het verander en is nou onaktief +Comment[ar]=مفتاح مغيِّر (شفت او كنترول) غيّر حالته وأصبح ملغى +Comment[ast]=Una tecla modificadora (Shift o Ctrl) camudó l'estáu y nun ta activa +Comment[be@latin]=Klavišny madyfikatar (naprykład, „Shift” ci „Ctrl”) źmianiŭ svajo stanovišča j ciapier adcisnuty. +Comment[bg]=Клавиш-модификатор (напр. Shift или Ctrl) промени състоянието си и е изключен +Comment[bn]=একটি মডিফায়ার কী (e.g. Shift বা Ctrl) অবস্থা পরিবর্তন করে এখন নিষ্ক্রীয় হয়েছে +Comment[bs]=Modifikatorski taster (npr. Shift ili Ctrl) je promijenio stanje i nije više aktivan +Comment[ca]=Ha canviat l'estat d'una tecla modificadora (p.ex. Majúscules o Control) i ara està inactiva +Comment[ca@valencia]=Ha canviat l'estat d'una tecla modificadora (p.ex. Majúscules o Control) i ara està inactiva +Comment[cs]=Modifikátor klávesnice (Shift nebo Ctrl) změnil stav a je právě neaktivní +Comment[csb]=Klawisza zjinaczi (Shift abò Control) zmienia swój sztatus ë nie je ju aktiwnô +Comment[da]=En ændringstast (f.eks. Skift eller Ctrl) har ændret sin tilstand og er nu inaktiv +Comment[de]=Eine Modifikator-Taste (Umschalt oder Strg) hat ihren Status verändert und ist nun inaktiv +Comment[el]=Ένα πλήκτρο τροποποιητή (π.χ., Shift ή Ctrl) άλλαξε την κατάστασή του και είναι τώρα ανενεργό +Comment[en_GB]=A modifier key (e.g. Shift or Ctrl) has changed its state and is now inactive +Comment[eo]=Modifa klavo (ekz. majuskliga klavo aŭ stirklavo) ŝanĝis sian staton kaj nun estas malaktiva +Comment[es]=Una tecla modificadora (Mayus o Ctrl) ha cambiado su estado y no está activa +Comment[et]=Muuteklahv (nt. Shift või Ctrl) muutis oma olekut ning on nüüd mitteaktiivne +Comment[eu]=Tekla aldatzaile bat (adibidez, Maius edo Ktrl) egoeraz aldatu da, eta orain inaktibo dago +Comment[fi]=Muunnosnäppäin (esim. Shift tai Ctrl) on vaihtanut tilaa eikä ole enää aktiivinen +Comment[fr]=Une touche de modification (ex : « Maj. » ou « Ctrl. ») a changé d'état et est maintenant inactive +Comment[fy]=De tastân fan in modifikaasjetoets (lykas Shift of Control) is feroare en is no ynaktyf +Comment[ga]=Athraíodh staid eochrach mionathraithe (m.sh. Shift nó Ctrl) agus tá sí neamhghníomhach anois +Comment[gl]=Unha tecla modificadora (por ex. Maiúsc ou Control) mudou de estado e agora está inactiva +Comment[gu]=બદલવાની કળે (દા.ત., શીફ્ટ અથવા કંટ્રોલ) હવે તેની સ્થિતિ બદલી છે અને હવે નિષ્ક્રિય છે +Comment[he]=מקש משנה מצב (למשל Shift או Ctrl) שינה את מצבו וכרגע לא פעיל +Comment[hne]=कोई माडिफायर कुंजी (जइसन कि शिफ्ट या कंट्रोल) हर अपन स्थिति ल बदल दे हे अउ अब वो हर अक्रिय हो गे हे +Comment[hr]=Tipka modifikatora (npr. SHIFT ili CTRL) promijenila je svoje stanje i više nije aktivna +Comment[hsb]=Modifikowaca tasta (na př. Wulkopis abo Strg) je swój status změniła a je nětko njeaktiwna +Comment[hu]=Egy módosító billentyű (pl. a Shift vagy a Ctrl) inaktívvá vált +Comment[ia]=Un clave modificator (p.ex.Shift o Ctrl) ha cambiate su stato e ora es inactive +Comment[id]=Sebuah tombol pengubah (misalnya Shift atau Ctrl) tekah diubah keadaannya dan sekarang tidak aktif +Comment[is]=Breytilykill (t.d. Shift eða Ctrl) hefur breytt um stöðu og er nú óvirkur +Comment[it]=Un tasto modificatore (come Shift o Ctrl) ha cambiato stato ed è ora inattivo +Comment[ja]=修飾キー (Shift や Ctrl) の状態が変更され、非アクティブになりました +Comment[kk]=Түрлендіргіш перне (мыс. Shift не Ctrl) күйін ауыстырып енді белсенді емес +Comment[km]=គ្រាប់​ចុច​កែប្រែ (ឧ. ប្ដូរ (Shift) ឬ បញ្ជា (Control)) បាន​ផ្លាស់ប្ដូរ​សភាព​របស់​វា ហើយ​ឥឡូវ​នេះ​អសកម្ម +Comment[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿ (ಉ.ದಾ Shift ಅಥವಾ Ctrl) ನ ಸ್ಥಿತಿಯು ಬದಲಾಗಿದ್ದು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ +Comment[ko]=Shift나 Control 키 같은 수정자 키의 상태가 바뀌었고 현재 사용 불가능함 +Comment[ku]=Bişkojkeke Guherker (mînak Shift an jî Ctrl) ciyê xwe guherand û niha neçalak e +Comment[lt]=Klavišo – modifikatoriaus (pvz., Lyg2(Shift) arba Vald(Ctrl)) būsena pakito ir jis dabar – neaktyvus +Comment[lv]=Modifikatora taustiņš (piem. Shift vai Control) ir mainījis stāvokli un tagad ir neaktīvs +Comment[mk]=Некое копче за модификација (пр. Shift или Ctrl) си ја смени состојбата и сега е неактивно +Comment[ml]=ഒരു മോഡിഫയര്‍ കീ (ഉദാ. ഷിഫ്ട് അല്ലെങ്കില്‍ കണ്ട്രോള്‍) അവസ്ഥ മാറി നിര്‍ജീവമായിരിക്കുന്നു +Comment[mr]=परिवर्तक कि (उ.दा. Shift किंवा Ctrl) याने स्तर बदलविले आहे व आता निष्क्रिय आहे +Comment[nb]=En valgtast (f.eks. Shift eller Ctrl) har endret status og er nå slått av +Comment[nds]=En Sünnertast (Ümschalt oder Stüern (Strg) a.B.) hett sien Tostand ännert un is nu nich mehr aktiev +Comment[nl]=Een modificatietoets (bijv. Shift of Ctrl) is nu inactief +Comment[nn]=Ein valtast (som «Shift» eller «Ctrl») har endra status, og er no inaktiv +Comment[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି (ଯେପରିକି Shift କିମ୍ବା Ctrl) ସେମାନଙ୍କର ସ୍ଥିତି ପରିବର୍ତ୍ତନ କରିଛନ୍ତି ଏବଂ ବର୍ତ୍ତମାନ ନିଷ୍କ୍ରିୟ ହୋଇଯାଇଛନ୍ତି +Comment[pl]=Klawisz modyfikujący (np. Shift lub Ctrl) zmienił stan i jest teraz wyłączony +Comment[pt]=Uma tecla modificadora (p.ex., o Shift ou o Control) mudou o seu estado e ficou agora inactiva +Comment[pt_BR]=Uma tecla modificadora (p.ex. Shift ou Ctrl) teve seu estado alterado e agora está inativa +Comment[ro]=Un modificator de taste (cum ar fi Shift sau Ctrl) și-a schimbat starea și este acum inactiv +Comment[ru]=Клавиша-модификатор (например, Shift или Ctrl) изменила своё состояние и сейчас неактивна +Comment[si]=වෙනස් කරීමේ යතුරේ (උදා. Shift හෝ Ctrl) තත්වය වෙනස් වී ඇති අතර එය දැන් අක්‍රීයයි +Comment[sk]=Modifikačný kláves (napr. Shift alebo Ctrl) zmenil svoj stav a je teraz neaktívny. +Comment[sl]=Spremenilna tipka (npr. Shift ali Ctrl) je spremenila stanje in je sedaj nedejavna +Comment[sr]=Модификаторски тастер (нпр. Shift или Ctrl) је променио стање и није више активан +Comment[sr@ijekavian]=Модификаторски тастер (нпр. Shift или Ctrl) је промијенио стање и није више активан +Comment[sr@ijekavianlatin]=Modifikatorski taster (npr. Shift ili Ctrl) je promijenio stanje i nije više aktivan +Comment[sr@latin]=Modifikatorski taster (npr. Shift ili Ctrl) je promenio stanje i nije više aktivan +Comment[sv]=En väljartangent (t.ex. Skift eller Ctrl) har ändrat tillstånd och är nu inaktiv +Comment[ta]=A modifier key (e.g. Shift or Ctrl) has changed its state and is now inactive +Comment[te]=సవరింపు కీ (ఉ.దా. Shift లేదా Ctrl) దాని స్థితి మార్చుకుంది మరియు ఇప్పుడు క్రియాహీనంగా ఉంది +Comment[tg]=Клавиша модификатора (например, Shift или Ctrl) изменила своё состояние и сейчас не активна +Comment[th]=ปุ่มพิมพ์ประกอบ (เช่น Shift หรือ Ctrl) มีการเปลี่ยนสถานะของตัวมัน และตอนนี้ได้ปิดการทำงาน +Comment[tr]=Bir değiştirici tuşun (Shift veya Ctrl gibi) durumu değiştirildi ve pasifleştirildi +Comment[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا (مەسىلەن، Shift ياكى Ctrl) ئۇنىڭ ھالىتىنى ئۆزگەرتىپ ھازىر پاسسىپلاشتۇرۇلدى +Comment[uk]=Клавіша модифікатора (наприклад Shift або Ctrl) змінила свій стан і тепер неактивна +Comment[wa]=Ene modifieuse tape (metans MAJ oudonbén CTRL) a candjî si estat eyet n' est asteure pus active +Comment[x-test]=xxA modifier key (e.g. Shift or Ctrl) has changed its state and is now inactivexx +Comment[zh_CN]=修饰键(如 Shift 或 Ctrl)更改了其状态,现已停用 +Comment[zh_TW]=一個組合鍵(如 Shift 或 Ctrl 等)已改變了它的狀態成為放開 +Sound=KDE-Sys-Special.ogg + +nopresentation=236 + +[Event/modifierkey-locked] +Name=A modifier key has been locked +Name[af]='n Verandering sleutel was gesluit +Name[ar]=تم قفل مفتاح مغيِّر +Name[ast]=Bloquióse una tecla modificadora +Name[be@latin]=Klavišny madyfikatar zamacavany +Name[bg]=Клавиш-модификатор е заключен +Name[bn]=একটি মডিফায়ার কী লক করা হয়েছে +Name[bs]=Modifikatorski taster je zaključan +Name[ca]=S'ha fixat alguna tecla modificadora +Name[ca@valencia]=S'ha fixat alguna tecla modificadora +Name[cs]=Modifikátor klávesnice je zamčený +Name[csb]=Klawisza zjinaczi òsta zablokòwónô +Name[da]=En ændringstast er blevet låst +Name[de]=Eine Modifikator-Taste ist gesperrt worden +Name[el]=Ένα πλήκτρο τροποποιητή κλειδώθηκε +Name[en_GB]=A modifier key has been locked +Name[eo]=Modifigita klavo ŝlosiĝis +Name[es]=Se ha bloqueado una tecla modificadora +Name[et]=Muuteklahv on lukustatud +Name[eu]=Tekla aldatzaile bat blokeatu da +Name[fi]=Muunnosnäppäin on lukittu +Name[fr]=Une touche de modification a été verrouillée +Name[fy]=In modifikaasjetoets is beskoattele +Name[ga]=Tá eochair mhionathraithe faoi ghlas anois +Name[gl]=Trancouse unha tecla modificadora +Name[gu]=બદલવાની કળને તાળું મારવામાં આવ્યું છે +Name[he]=מקש משנה מצב ננעל +Name[hi]=कोई मॉडिफ़ायर कुंजी तालाबंद हो गया है +Name[hne]=कोई माडिफायर कुंजी हर तालाबंद हो गे हे +Name[hr]=Tipka modifikatora je zaključana +Name[hsb]=Modifikowaca tasta bu stajnje zaswěćena +Name[hu]=Egy módosító billentyű zárolódott +Name[ia]=Un clave modificator ha essite blocate +Name[id]=Sebuah tombol pengubah telah dikunci +Name[is]=Breytilykli hefur verið læst +Name[it]=Un tasto modificatore è stato bloccato +Name[ja]=修飾キーがロックされました +Name[kk]=Түрлендіргіш перне басылды +Name[km]=គ្រាប់​ចុច​កែប្រែ​បាន​ត្រូវ​ចាក់​សោ +Name[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿಯನ್ನು ಬಂಧಿಸಲಾಗಿದೆ (ಲಾಕ್) +Name[ko]=수정자 키가 잠김 +Name[ku]=Bişkojkeke Guherker hat kilîtkirin +Name[lt]=Klavišas – modifikatorius buvo užrakintas +Name[lv]=Modifikatora taustiņš tika fiskēts +Name[mk]=Некое копче за модификација е заклучено +Name[ml]=ഒരു മോഡിഫയര്‍ കീ പൂട്ടിയിരിക്കുന്നു +Name[mr]=परिवर्तक कि कुलूपबंद केली गेली आहे +Name[nb]=En valgtast er blitt låst +Name[nds]=En Sünnertast wöör fastsett +Name[ne]=परिमार्जक कुञ्जी ताल्चा लगाइएको छ +Name[nl]=Een modificatietoets is vergrendeld +Name[nn]=Ein valtast er no låst +Name[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି ଅପରିବର୍ତ୍ତିତ ହୋଇଯାଇଛି +Name[pa]=ਮੋਡੀਫਾਇਰ ਸਵਿੱਚ ਲਾਕ ਕੀਤੀ ਗਈ +Name[pl]=Klawisz modyfikujący został zablokowany +Name[pt]=Uma tecla modificadora ficou bloqueada +Name[pt_BR]=Uma tecla modificadora foi bloqueada +Name[ro]=Un modificator de taste a fost blocat +Name[ru]=Клавиша-модификатор зафиксирована +Name[se]=Válljenboallu lea dál lohkkaduvvon +Name[si]=වෙනස්කිරීම් යතුර අගුළු දමා ඇත +Name[sk]=Modifikačný kláves je zamknutý +Name[sl]=Spremenilna tipka se je zaklenila +Name[sr]=Модификаторски тастер је закључан +Name[sr@ijekavian]=Модификаторски тастер је закључан +Name[sr@ijekavianlatin]=Modifikatorski taster je zaključan +Name[sr@latin]=Modifikatorski taster je zaključan +Name[sv]=En väljartangent har låsts +Name[ta]=A modifier key has been locked +Name[te]=సవరింపు కీ అప్రవేశంగా ఉంది +Name[tg]=Клавиша модификатора зафиксирована +Name[th]=ปุ่มพิมพ์ประกอบถูกล็อคอยู่ +Name[tr]=Bir değiştirici tuş kilitlendi +Name[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا قۇلۇپلاندى +Name[uk]=Клавішу модифікатора було заблоковано +Name[wa]=Ene modifieuse tape a stî eclawêye +Name[x-test]=xxA modifier key has been lockedxx +Name[zh_CN]=修饰键现已锁定 +Name[zh_TW]=組合鍵已鎖定 +Comment=A modifier key (e.g. Shift or Ctrl) has been locked and is now active for all of the following keypresses +Comment[af]='n Veranderingsleutel (bv. Shift of Control) is gesluit en is nou aktief vir al die volgende sleuteldrukke +Comment[ar]=تم قفل مفتاح مغيِّر (شفت أو كنترول) وأصبح مفعّلاً لكل الكتابات التالية +Comment[ast]=Bloquióse una tecla modificadora (Mayús o Ctrl) y afectará a toles tecles calcaes +Comment[be@latin]=Klavišny madyfikatar (naprykład, „Shift” ci „Ctrl”) zamacavaŭsia j ciapier prycisnuty dla ŭsich nastupnych klavišaŭ. +Comment[bg]=Клавиш-модификатор (напр. Shift или Ctrl) е заключен и е активен за всички последващи натискания на клавиши +Comment[bn]=একটি মডিফায়ার কী (e.g. Shift বা Ctrl) লক করা হয়েছে এবং পরবর্তী সবকটি কী-র (key) জন্য সক্রিয় থাকবে +Comment[bs]=Modifikatorski taster (npr. Shift ili Ctrl) upravo je zaključan i od sada aktivan za sve pritiske na tastere +Comment[ca]=S'ha fixat alguna tecla modificadora (p.ex. Majúscules o Control) i ara està activa per a totes les tecles que es premin a continuació +Comment[ca@valencia]=S'ha fixat alguna tecla modificadora (p.ex. Majúscules o Control) i ara està activa per a totes les tecles que es premen a continuació +Comment[cs]=Modifikátor klávesnice (např. Shift nebo Ctrl) je zamčený a je nyní aktivní pro všechny následující stisknuté klávesy +Comment[csb]=Klawisza zjinaczi (Shift abò Control) òsta zablokòwónô ë je terô dlô pòsobnegò wcësniącô klawiszów aktiwnô +Comment[da]=En ændringstast (f.eks. Skift eller Ctrl) er blevet låst og er nu aktiv for alle følgende tastetryk +Comment[de]=Eine Modifikator-Taste (Umschalt oder Strg) ist festgesetzt worden und ist nun für alle folgenden Tastendrücke aktiv +Comment[el]=Ένα πλήκτρο τροποποιητή (π.χ., Shift ή Ctrl) κλειδώθηκε και τώρα είναι ενεργό για όλα τα ακόλουθα πατήματα πλήκτρων +Comment[en_GB]=A modifier key (e.g. Shift or Ctrl) has been locked and is now active for all of the following keypresses +Comment[eo]=Modifa klavo (ekz. majuskliga klavo aŭ stirklavo) ŝlosiĝis kaj nun estas aktiva por la sekvaj klavpremoj +Comment[es]=Se ha bloqueado una tecla modificadora (Mayús o Ctrl) y afectará a todas las teclas que se pulsen +Comment[et]=Muuteklahv (nt. Shift või Ctrl) on lukustatud ja on nüüd aktiivne kõikide järgnevate klahvivajutuste jaoks +Comment[eu]=Tekla aldatzaile bat (adibidez, Maius edo Ktrl) blokeatu da, eta orain aktibo dago sakatzen diren tekla guztietarako +Comment[fi]=Muunnosnäppäin (esim. Shift tai Ctrl) on lukittu ja on nyt aktiivinen kaikille seuraaville näppäinpainalluksille +Comment[fr]=Une touche de modification (ex : « Maj. » ou « Ctrl. ») a été verrouillée et est maintenant active pour tous les appuis suivants de touches +Comment[fy]=In modifikaasjetoets (lykas Shift of Control) is beskoattele en is no aktyf foar de neikommende toetsoanslaggen +Comment[ga]=Cuireadh eochair mhionathraithe (m.sh., Shift nó Ctrl) faoi ghlas tá sí gníomhach anois le haghaidh na n-eochairbhrúnna seo a leanas +Comment[gl]=Unha tecla modificadora (por ex. Maiúsc ou Control) foi trancada e agora está activa +Comment[gu]=બદલવાની કળને (દા.ત., શીફ્ટ અથવા કંટ્રોલ) હવે તાળું મારવામાં આવ્યું છે અને હવે તે નીચેની કળ દબાવવા માટે સક્રિય છે +Comment[he]=מקש משנה מצב (למשל Shift או Ctrl) ננעל וכרגע פעיל עבור לחיצות המקשים הבאות +Comment[hne]=कोई माडिफायर कुंजी (जइसन कि शिफ्ट या कंट्रोल) हर तालाबंद हो गे हे अउ अब वो हर नीचे के सब्बो कुंजीदबाव मं सक्रिय रहिही +Comment[hr]=Tipka modifikatora (npr. SHIFT ili CTRL) zaključana je i aktivna je tijekom svih sljedećih pritisaka tipki +Comment[hsb]=Modifikowaca tasta (na př. Wulkopis abo Strg) bu stajnje zaswěćena a je nětko za wšě přichodne tasty aktiwna +Comment[hu]=Egy módosító billentyű (pl. a Shift vagy a Ctrl) zárolódott, és ezután minden billentyűlenyomásnál aktív lesz +Comment[ia]=Un clave modificator (p.ex.Shift o CTRL) ha essite blocate e ora es active pro tote le sequente keypresses +Comment[id]=Sebuah tombol pengubah (misalnya Shift atau Ctrl) telah dikunci dan sekarang aktif untuk semua penekanan tombol berikut +Comment[is]=Breytilykli (t.d. Shift eða Ctrl) hefur verið læst og er nú virkur fyrir eftirfarandi lyklaborðsaðgerðir +Comment[it]=Un tasto modificatore (come Shift o Ctrl) è stato bloccato ed è ora attivo per tutte le battute successive +Comment[ja]=修飾キー (Shift や Ctrl) がロックされ、続くキー押下のすべてに対してアクティブになりました +Comment[kk]=Түрлендіргіш перне (мыс. Shift не Ctrl) басылып енді барлық басылмақ пернелер үшін белсенді +Comment[km]=គ្រាប់​ចុច​កែប្រែ (ឧ. ប្ដូរ (Shift) ឬ​បញ្ជា (Control)) ត្រូវ​បាន​ចាក់​សោ ហើយ​ឥឡូវ​នេះ​សកម្ម​សម្រាប់​ការ​ចុច​គ្រាប់​ចុច​ខាង​ក្រោម +Comment[kn]=ಒಂದು ಪರಿವರ್ತಕ (ಮಾಡಿಫಯರ್) ಕೀಲಿಯನ್ನು (ಉ.ದಾ Shift ಅಥವಾ Ctrl) ಬಂಧಿಸಲಾಗಿದ್ದು (ಲಾಕ್), ಮುಂದಿನ ಎಲ್ಲಾ ಕೀಲಿಮಣೆ ಒತ್ತುಗಳಿಗೆ ಈಗ ಸಕ್ರಿಯವಾಗಿದೆ +Comment[ko]=Shift나 Control 키 같은 수정자 키의 상태가 바뀌었고 현재 모든 키 입력에 대해서 활성화됨 +Comment[ku]=Bişkojka guhêrker (wekî Shift an jî Ctrl) hate qufl kirin û niha ji bo çalak kirina hemû bişkojkên jêr çalak e +Comment[lt]=Klavišas – modifikatorius (pvz., Lyg2(Shift) arba Vald(Ctrl)) buvo užrakintas ir dabar visiems būsimiems klavišų paspaudimams yra aktyvus +Comment[lv]=Modifikatora taustiņš (piem. Shift vai Control) tika fiksēts un ir aktīvs visiem nākamajiem taustiņu nospiedieniem +Comment[mk]=Некое копче за модификација (пр. Shift или Ctrl) беше заклучено и сега е активно за сите наредни притиснати копчиња +Comment[ml]=ഒരു മോഡിഫയര്‍ കീ (ഉദാ. ഷിഫ്ട് അല്ലെങ്കില്‍ കണ്ട്രോള്‍) പൂട്ടിയിരിക്കുന്നു. നിലവില്‍ താഴെ പറയുന്ന കീപ്രെസ്സുകള്‍ക്കു് ഇതു് സജീവമാണു് +Comment[mr]=परिवर्तक कि (उ.दा. Shift किंवा Ctrl) कुलूपबंद झाली आहे व खालील किप्रेस् करिता सक्रिय झाली आहे +Comment[nb]=En valgtast (f.eks. Shift eller Ctrl) har blitt låst og er nå skrudd på for alle etterfølgende tastetrykk +Comment[nds]=En Sünnertast (Ümschalt oder Stüern (Strg) a.B.) wöör fastsett un is nu för all nakamen Tasten aktiev +Comment[nl]=Een modificatietoets (bijv. Shift of Ctrl) is vergrendeld en nu actief voor alle volgende toetsaanslagen +Comment[nn]=Ein valtast (som «Shift» eller «Ctrl») er vorten låst, og er no aktiv for alle etterfølgjande tastetrykk +Comment[or]=ଗୋଟିଏ ପରିବର୍ତ୍ତକ କି (ଯେପରିକି Shift କିମ୍ବା Ctrl) ଅପରିବର୍ତ୍ତିତ ହୋଇଯାଇଛି ଏବଂ ବର୍ତ୍ତମାନ ନିମ୍ନଲିଖିତ ସମସ୍ତ କି ଚାପ ପାଇଁ ସକ୍ରିୟ ହୋଇଛି +Comment[pl]=Klawisz modyfikujący (np. Shift lub Ctrl) został zablokowany i będzie włączony przy następnych naciśnięciach klawiszy +Comment[pt]=Uma tecla modificadora (p.ex., o Shift ou o Control) foi bloqueada e ficou agora activa para todas as combinações de teclas seguintes +Comment[pt_BR]=Uma tecla modificadora (p.ex. Shift ou Ctrl) foi bloqueada e agora está ativa, para todos os pressionamentos de tecla seguintes +Comment[ro]=Un modificator de taste (cum ar fi Shift sau Ctrl) a fost blocat și este acum activ pentru următoarele apăsări de taste +Comment[ru]=Клавиша-модификатор (например, Shift или Ctrl) зафиксирована и активна при нажатии любых других клавиш +Comment[si]=වෙනස් කිරීමේ යතුර (උදා. Shift හෝ Ctrl) අගුළු දමා ඇති අතර පහත සියළුම යතුරු එබීම් සඳහා එය සක්‍රීයයි +Comment[sk]=Modifikačný kláves (napr. Shift alebo Ctrl) je zamknutý a je teraz aktívny pre všetky nasledujúce stlačenia kláves +Comment[sl]=Spremenilna tipka (npr. Shift ali Ctrl) se je zaklenila in je sedaj dejavna za vse prihodnje pritiske tipk +Comment[sr]=Модификаторски тастер (нпр. Shift или Ctrl) управо је закључан и од сада активан за све притиске на тастере +Comment[sr@ijekavian]=Модификаторски тастер (нпр. Shift или Ctrl) управо је закључан и од сада активан за све притиске на тастере +Comment[sr@ijekavianlatin]=Modifikatorski taster (npr. Shift ili Ctrl) upravo je zaključan i od sada aktivan za sve pritiske na tastere +Comment[sr@latin]=Modifikatorski taster (npr. Shift ili Ctrl) upravo je zaključan i od sada aktivan za sve pritiske na tastere +Comment[sv]=En väljartangent (t.ex. Skift eller Ctrl) har låsts och är nu aktiv för alla följande tangentnertryckningar +Comment[ta]=A modifier key (e.g. Shift or Ctrl) has been locked and is now active for all of the following keypresses +Comment[te]=సవరింపు కీ (ఉ.దా. Shift లేదా Ctrl) అప్రవేశం చేయబడింది మరియు ఇప్పుడు క్రింది అన్ని కీవత్తులకు క్రియాశీలంగా ఉంది +Comment[tg]=Клавиша модификатора (например, Shift или Ctrl) зафиксирована и активна при нажатии любых других клавиш +Comment[th]=ปุ่มพิมพ์ประกอบ (เช่น Shift หรือ Cntrl) ถูกล็อคอยู่ และขณะนี้อยู่ในสถานะทำงาน สำหรับใช้ร่วมกับการกดแป้นต่อจากนี้ +Comment[tr]=Bir değiştirici tuş (Shift ya da Ctrl gibi) kilitlendi ve bundan sonraki tüm tuş basma eylemleri için etkinleştirildi +Comment[ug]=بىر ئۆزگەرتكۈچى كۇنۇپكا (مەسىلەن، Shift ياكى Ctrl) قۇلۇپلاندى، بۇندىن كېيىنكى كۇنۇپكا بېسىشقا ئىشلىتىلىدۇ +Comment[uk]=Клавішу модифікатора (наприклад Shift або Ctrl) було зафіксовано і тепер вона активна для всіх наступних натискань клавіш +Comment[wa]=Ene modifieuse tape (metans MAJ oudonbén CTRL) a stî eclawêye eyet est asteure active po tos les tapes tchôkeyes ki shuront +Comment[x-test]=xxA modifier key (e.g. Shift or Ctrl) has been locked and is now active for all of the following keypressesxx +Comment[zh_CN]=修饰键(如 Shift 或 Ctrl)已被锁定,现在将适用于后续按键 +Comment[zh_TW]=一個組合鍵(如 Shift 或 Ctrl 等)已被鎖定,現在再按任何鍵都視為快捷鍵組合 +Sound=KDE-Sys-Special.ogg + +nopresentation=236 + +[Event/lockkey-locked] +Name=A lock key has been activated +Name[af]='n Sluitsleutel is geaktiveer +Name[ar]=تم تفعيل مفتاح قفل +Name[ast]=Activóse una tecla de bloquéu +Name[be@latin]=Klaviša macavańnia prycisnutaja +Name[bg]=Включен е клавиш за превключване на режим +Name[bn]=একটি লক কী (lock key) সক্রিয় হয়েছে +Name[bs]=Zaključavajući taster je aktiviran +Name[ca]=S'ha activat alguna tecla de fixació +Name[ca@valencia]=S'ha activat alguna tecla de fixació +Name[cs]=Klávesa pro přepnutí stavu byla aktivována +Name[csb]=Klawisza blokadë òsta aktiwòwónô +Name[da]=En låsetast er blevet aktiveret +Name[de]=Eine Sperrtaste ist aktiviert worden +Name[el]=Ένα πλήκτρο κλειδώματος έχει ενεργοποιηθεί +Name[en_GB]=A lock key has been activated +Name[eo]=Baskula klavo aktiviĝis +Name[es]=Se ha activado una tecla de bloqueo +Name[et]=Lukustusklahv on aktiveeritud +Name[eu]=Blokeo-tekla bat aktibatu da +Name[fi]=Lukitusnäppäin on aktivoitu +Name[fr]=Une touche de verrouillage a été activée +Name[fy]=In beskoatteltoets is aktivearre +Name[ga]=Tá eochair ghlasála gníomhach anois +Name[gl]=Activouse unha tecla de bloqueo +Name[gu]=તાળાં કળ સક્રિય કરવામાં આવી છે +Name[he]=מקש נועל הפך לפעיל +Name[hi]=कोई तालाबंद कुंजी सक्रिय किया जा चुका है +Name[hne]=कोई ताला कुंजी सक्रिय हो गे हे +Name[hr]=Tipka zaključavanja je aktivirana +Name[hsb]=Tasta za stajne zaswěćene je nětko aktiwna +Name[hu]=Egy zároló billentyű aktívvá vált +Name[ia]=Un clave de bloco ha essite activate +Name[id]=Sebuah tombol pengunci telah diaktifkan +Name[is]=Læsilykill hefur verið virkjaður +Name[it]=Un tasto di blocco è stato attivato +Name[ja]=ロックキーがアクティブになりました +Name[ka]=დაბლოკვის ღილაკი გააქტივებულია +Name[kk]=Қосқыш перне белсендірілді +Name[km]=គ្រាប់​ចុច​ចាក់​សោ​បាន​ត្រូវ​ធ្វើ​ឲ្យ​សកម្ម +Name[kn]=ಒಂದು ಭಂಧನ ಕೀಲಿಯನ್ನು (ಲಾಕ್) ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=잠금 키가 활성화됨 +Name[ku]=Bişkojkeke Mifteyê hat çalakirin +Name[lt]=Užrakto klavišas buvo aktyvuotas +Name[lv]=Slēga taustiņš tika aktivizēts +Name[mk]=Некое копче за заклучување беше активирано +Name[ml]=ഒരു ലോക്ക് കീ സജീവമാക്കിയിരിക്കുന്നു +Name[mr]=कुलूपबंद कि सक्रिय केली गेली +Name[nb]=En låsetast er blitt slått på +Name[nds]=En Tastrast is nu inleggt +Name[ne]=एउटा ताल्चा कुञ्जी सक्रिय बनाइएको छ +Name[nl]=Een vergrendeltoets is geactiveerd +Name[nn]=Ein låstetast er no aktiv +Name[or]=ଗୋଟିଏ ଅପରିବର୍ତ୍ତନୀୟ କିକୁ ସକ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਇੱਕ ਲਾਕ ਸਵਿੱਚ ਐਕਟਿਵੇਟ ਕੀਤੀ ਗਈ +Name[pl]=Klawisz blokujący został włączony +Name[pt]=Uma tecla de bloqueio foi activada +Name[pt_BR]=Uma tecla de bloqueio foi ativada +Name[ro]=O tastă de blocare a fost activată +Name[ru]=Активирована клавиша переключения режимов +Name[se]=Lohkkadanboallu lea aktiivalaš +Name[si]=අගුළු යතුර සක්‍රීයයි +Name[sk]=Zamykací kláves je aktívny +Name[sl]=Zaklepna tipka je bila omogočena +Name[sr]=Закључавајући тастер је активиран +Name[sr@ijekavian]=Закључавајући тастер је активиран +Name[sr@ijekavianlatin]=Zaključavajući taster je aktiviran +Name[sr@latin]=Zaključavajući taster je aktiviran +Name[sv]=En låstangent har aktiverats +Name[ta]=A lock key has been activated +Name[te]=అప్రవేశపు కీ క్రియాశీలం చేయబడింది +Name[tg]=Активирована клавиша переключения режимов +Name[th]=ปุ่มล็อคถูกเปิดการทำงาน +Name[tr]=Bir kilitleme tuşu etkinleştirildi +Name[ug]=بىر قۇلۇپلاش كۇنۇپكىسى ئاكتىپلاندى +Name[uk]=Було активовано клавішу фіксації +Name[wa]=Ene eclawåve tape a stî metowe en alaedje +Name[x-test]=xxA lock key has been activatedxx +Name[zh_CN]=锁定键现已激活 +Name[zh_TW]=已啟動鎖定鍵 +Comment=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now active +Comment[af]='n Sluitsleutel (bv. Caps Lock of Num Lock) se toestand het verander en is nou aktief +Comment[ar]=تغيرت حالة مفتاح قفل (Caps Lock أو Num Lock) وأصبح مفعلاً +Comment[ast]=Una tecla de bloquéu (como Bloq Mayús o Bloq Num) camudó l'estáu y ta activa +Comment[be@latin]=Klaviša macavańnia (naprykład, „Caps Lock” ci „Num Lock”) źmianiła svajo stanovišča j ciapier prycisnutaja. +Comment[bg]=Клавиш за превключване на режим (напр. Caps Lock или Num Lock) промени състоянието си и е активен +Comment[bn]=একটি লক কী (e.g. Caps Lock বা Num Lock) অবস্থা পরিবর্তন করে এখন সক্রিয় হয়েছে +Comment[bs]=Zaključavajući taster (npr. CapsLock ili NumLock) promijenio je stanje i sada je aktivan +Comment[ca]=Alguna tecla de fixació (p.ex. Bloq Maj o Bloq Núm) ha canviat el seu estat i ara està activa +Comment[ca@valencia]=Alguna tecla de fixació (p.ex. Bloq Maj o Bloq Núm) ha canviat el seu estat i ara està activa +Comment[cs]=Klávesa pro přepnutí stavu (např. CapsLock nebo NumLock) byla stisknuta a je nyní aktivní +Comment[csb]=Klawisza blokadë (Caps Lock abò Num Lock) zmienia swój sztatus ë je terô aktiwnô +Comment[da]=En låsetast (f.eks. Caps Lock eller Num Lock) har ændret sin tilstand og er nu aktiv +Comment[de]=Eine Sperrtaste (Feststelltaste oder Nummernblocksperre) hat ihren Status geändert und ist nun aktiv +Comment[el]=Ένα πλήκτρο κλειδώματος (π.χ., Caps Lock ή Num Lock) άλλαξε την κατάστασή του και είναι τώρα ενεργό +Comment[en_GB]=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now active +Comment[eo]=Baskula klavo (ekz. majuskla baskulo aŭ nombra baskulo) ŝanĝis sian staton kaj nun estas aktiva +Comment[es]=Una tecla de bloqueo (como Bloq Mayús o Bloq Num) ha cambiado su estado y está activa +Comment[et]=Lukustusklahv (nt. Caps Lock või Num Lock) muutis oma seisundit ning on nüüd aktiivne +Comment[eu]=Blokeo-tekla bat (adibidez, Blok Maius edo Blok Zenb) egoeraz aldatu da, eta orain aktibo dago +Comment[fi]=Lukitusnäppäin (esim. CapsLock tai NumLock) on vaihtanut tilaansa ja on nyt aktiivinen +Comment[fr]=Une touche de verrouillage (ex : « Verr. Maj. » ou « Verr. Num. ») a changé d'état et est maintenant active +Comment[fy]=De tastân fan in beskoatteltoets (lykas kaptaalskoattel of Nûm skoattel) is feroare en is no aktyf +Comment[ga]=Athraíodh staid eochrach glasála (m.sh. Caps Lock nó Num Lock) agus tá sí gníomhach anois +Comment[gl]=Unha tecla de bloqueo (por ex., Bloq Maiúsc ou Bloq Num) mudou de estado e agora está activa +Comment[gu]=તાળાં કળે (દા.ત., કેપ્સ લોક અથવા નમ લોક) હવે તેની સ્થિતિ બદલી છે અને હવે સક્રિય છે +Comment[he]=מקש נועל (למשל Caps Lock או Num Lock) שינה את מצבו וכרגע פעיל +Comment[hne]=कोई ताला कुंजी (जइसन कि कैप्स लाक या न्यूम लाक) हर अपन स्थिति ल बदल दे हे अउ अब वो हर सक्रिय हो गे हे +Comment[hr]=Tipka zaključavanja (npr. CapsLock ili NumLock) promijenila je svoje stanje i aktivna je +Comment[hsb]=Tasta za stajne zaswěćene (na př. Stajny Wulkopis) je status změniła a je nětko aktiwna +Comment[hu]=Egy zároló billentyű (pl. a Caps Lock vagy a Num Lock) aktívvá vált +Comment[ia]=Un clave de bloco (p.ex. Caps Lock o Num Lock) ha cambiate su stato e ora es active +Comment[id]=Sebuah tombol kunci (misalnya Caps Lock atau Num Lock) telah diubah keadaannya dan sekarang aktif +Comment[is]=Læsilykill (t.d. Caps Lock eða Num Lock) hefur breytt um stöðu og er nú virkur +Comment[it]=Un tasto di blocco (ad es. Bloc Maiusc o Bloc Num) ha cambiato stato ed è ora attivo +Comment[ja]=ロックキー (Caps Lock や Num Lock) の状態が変更され、非アクティブになりました +Comment[kk]=Қосқыш перне (мыс. Caps Lock не Num Lock) күйін ауыстырып енді белсенді +Comment[km]=គ្រាប់ចុច​ចាក់សោ (ឧ. ប្ដូរ​ជាប់(Caps Lock) ឬ​គ្រាប់ចុច​លេខ) បាន​ផ្លាស់ប្ដូរ​ស្ថានភាព​របស់វា ហើយ​តឡូវ​សកម្ម +Comment[kn]=ಒಂದು ಭಂಧನ (ಲಾಕ್) ಕೀಲಿ (ಉ.ದಾ Shift ಅಥವಾ Ctrl) ನ ಸ್ಥಿತಿಯು ಬದಲಾಗಿದ್ದು ಈಗ ಸಕ್ರಿಯಗೊಂಡಿದೆ +Comment[ko]=Caps Lock이나 Num Lock 키 같은 잠금 키의 상태가 바뀌었고 현재 활성화됨 +Comment[ku]=Rewşa Bişkojkeke Mifteyê (wekî Caps Lock an jî Num Lock) hate guhertin û niha çalak e +Comment[lt]=Užrakto klavišo (pvz., Didž(Caps Lock) arba Sk(Num Lock)) būsena pakito ir jis dabar – aktyvus +Comment[lv]=Slēga taustiņš (piem. Caps Lock vai Num Lock) ir mainījis stāvokli un tagad ir aktīvs +Comment[mk]=Некое копче за заклучување (пр. Caps Lock или Num Lock) си ја смени состојбата и сега е активно +Comment[ml]=ഒരു ലോക്ക് കീ (ഉദാ. കാപ്സ് ലോക്ക് അല്ലെങ്കില്‍ നം ലോക്ക്) അവസ്ഥ മാറി സജീവമാക്കിയിരിക്കുന്നു +Comment[mr]=कुलूपबंद कि (उ.दा. Caps Lock किंवा Num Lock) ने स्तर बदलविले आहे व आता सक्रिय आहे +Comment[nb]=En låsetast (f.eks. Caps Lock eller Num Lock) har endret status og er nå slått på +Comment[nds]=En Tastrast (Tallen- oder Grootschriev-Rast a.B.) hett sien Tostand ännert un is nu inleggt +Comment[nl]=Een vergrendeltoets (bijv. Caps Lock of Num Lock ) is nu actief +Comment[nn]=Ein låsetast (som «Caps Lock» eller «Num Lock») har endra status, og er no aktiv +Comment[or]=ଗୋଟିଏ ଅପରିବର୍ତ୍ତନୀୟ କି (ଯେପରିକି Caps Lock କିମ୍ବା Num Lock) ସେମାନଙ୍କର ସ୍ଥିତି ପରିବର୍ତ୍ତନ କରିଛନ୍ତି ଏବଂ ବର୍ତ୍ତମାନ ସକ୍ରିୟ ଅଛନ୍ତି +Comment[pl]=Klawisz blokujący (np. Caps Lock lub Num Lock) zmienił stan i jest teraz włączony +Comment[pt]=Uma tecla de bloqueio (p.ex., a Caps Lock ou a Num Lock) alterou o seu estado e ficou agora activa +Comment[pt_BR]=Uma tecla de bloqueio (p.ex. Caps Lock ou Num Lock) teve seu estado alterado e agora está ativa +Comment[ro]=O tastă de blocare (cum ar fi Caps Lock sau Num Lock) și-a schimbat starea și este acum activă +Comment[ru]=Клавиша переключения режимов (например, Caps Lock или Num Lock) изменила своё состояние и сейчас активна +Comment[si]=අගුළු යතුරේ (උදා. Caps Lock හෝ Num Lock) තත්වය වෙනස් වී ඇති අතර එය දැන් සක්‍රීයයි +Comment[sk]=Zamykací kláves (napr. Caps Lock alebo Num Lock) zmenil svoj stav a je teraz aktívny +Comment[sl]=Zaklepna tipka (npr. Caps Lock ali Num Lock) je spremenila stanje in je sedaj dejavna +Comment[sr]=Закључавајући тастер (нпр. CapsLock или NumLock) променио је стање и сада је активан +Comment[sr@ijekavian]=Закључавајући тастер (нпр. CapsLock или NumLock) промијенио је стање и сада је активан +Comment[sr@ijekavianlatin]=Zaključavajući taster (npr. CapsLock ili NumLock) promijenio je stanje i sada je aktivan +Comment[sr@latin]=Zaključavajući taster (npr. CapsLock ili NumLock) promenio je stanje i sada je aktivan +Comment[sv]=En låstangent (t.ex. Caps Lock eller Num Lock) har ändrat tillstånd och är nu aktiv +Comment[ta]=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now active +Comment[te]=అప్రవేశపు కీ (ఉ.దా. Caps Lock లేదా Num Lock) దాని స్థితి మార్చుకుంది మరియు ఇప్పుడు క్రియాశీలంగా ఉంది +Comment[tg]=Клавиша переключения режимов (например, Caps Lock или Num Lock) изменила своё состояние и сейчас активна +Comment[th]=ปุ่มล็อค (เช่น Caps Lock หรือ Num Lock) ได้มีการเปลี่ยนสถานะของมันและขณะนี้กำลังทำงานอยู่ +Comment[tr]=Bir kilitleme tuşunun (Caps Lock ya da Num Lock gibi.) durumu değiştirildi ve etkinleştirildi +Comment[ug]=بىر قۇلۇپلاش كۇنۇپكىسى (مەسىلەن، Caps Lock ياكى Num Lock) ئۇنىڭ ھالىتىنى ئۆزگەرتتى، ھازىر ئاكتىپلاندى +Comment[uk]=Клавіша фіксації (наприклад Caps Lock або Num Lock) змінила свій стан і тепер активна +Comment[wa]=Ene eclawåve tape ki sere (metans CAPS LOCK oudonbén NUM LOCK) a candjî si estat eyet est asteure ovrante +Comment[x-test]=xxA lock key (e.g. Caps Lock or Num Lock) has changed its state and is now activexx +Comment[zh_CN]=锁定键(如 Caps Lock 或 Num Lock)更改了其状态,现已激活 +Comment[zh_TW]=一個鎖定鍵(如 CapsLock 或 NumLock)已改變它的狀態為啟用 +Sound=KDE-Sys-Special.ogg + +nopresentation=236 + +[Event/lockkey-unlocked] +Name=A lock key has been deactivated +Name[af]='n Sluit sleutel was gedeaktiveer +Name[ar]=تم إلغاء تفعيل مفتاح قفل +Name[ast]=Desactivóse una tecla de bloquéu +Name[be@latin]=Klaviša macavańnia adcisnutaja +Name[bg]=Изключен е клавиш за превключване на режим +Name[bn]=একটি লক কী (lock key) নিষ্ক্রীয় হয়েছে +Name[bs]=Zaključavajući taster je deaktiviran +Name[ca]=S'ha desactivat alguna tecla de fixació +Name[ca@valencia]=S'ha desactivat alguna tecla de fixació +Name[cs]=Klávesa pro přepnutí stavu byla deaktivována +Name[csb]=Klawisza blokadë òsta deaktiwòwónô +Name[da]=En låsetast er blevet deaktiveret +Name[de]=Eine Sperrtaste ist deaktiviert worden +Name[el]=Ένα πλήκτρο κλειδώματος απενεργοποιήθηκε +Name[en_GB]=A lock key has been deactivated +Name[eo]=Baskula klavo malaktiviĝis +Name[es]=Se ha desactivado una tecla de bloqueo +Name[et]=Lukustusklahv on nüüd mitteaktiivne +Name[eu]=Blokeo-tekla bat desaktibatu da +Name[fi]=Lukitusnäppäin on nyt deaktivoitu +Name[fr]=Une touche de verrouillage a été désactivée +Name[fy]=In beskoatteltoets is ûntaktivearre +Name[ga]=Tá eochair ghlasála neamhghníomhach anois +Name[gl]=Desactivouse unha tecla de bloqueo +Name[gu]=તાળાં કળ નિષ્ક્રિય કરવામાં આવી છે +Name[he]=מקש נועל הפך ללא פעיל +Name[hi]=कोई तालाबंद कुंजी अक्रिय किया जा चुका है +Name[hne]=कोई ताला कुंजी हर अक्रिय हो गे हे +Name[hr]=Tipka zaključavanja je deaktivirana +Name[hsb]=Tasta za stajne zaswěćene je nětko njeaktiwna +Name[hu]=Egy zároló billentyű inaktívvá vált +Name[ia]=Un clave de bloco ha essite deactivate +Name[id]=Sebuah tombol kunci telah dinonaktifkan +Name[is]=Læsilykill hefur verið aftengdur +Name[it]=Un tasto di blocco è stato disattivato +Name[ja]=ロックキーが非アクティブになりました +Name[ka]=დაბლოკვის ღილაკი ამორთულია +Name[kk]=Қосқыш перне белсенсіздірілді +Name[km]=គ្រាប់​ចុច​ចាក់​សោ​ត្រូវ​បាន​​​ធ្វើ​ឲ្យ​អសកម្ម +Name[kn]=ಒಂದು ಭಂಧನ ಕೀಲಿಯನ್ನು (ಲಾಕ್) ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=잠금 키가 비활성화됨 +Name[ku]=Bişkojkeke Mifteyê hate neçalakirin +Name[lt]=Užrakto klavišas buvo išjungtas +Name[lv]=Slēga taustiņš tika deaktivizēts +Name[mk]=Некое копче за заклучување беше активирано +Name[ml]=ഒരു ലോക്ക് കീ നിര്‍ജ്ജീവമാക്കിയിരിക്കുന്നു +Name[mr]=कुलूपबंद कि निष्क्रिय केली गेली +Name[nb]=En låsetast er blitt slått av +Name[nds]=En Tastrast is nich mehr inleggt +Name[ne]=लक कुञ्जी निष्क्रिय भएको छ +Name[nl]=Een vergrendeltoets is gedeactiveerd +Name[nn]=Ein låsetast er no inaktiv +Name[or]=ଗୋଟିଏ ଅପରିବର୍ତ୍ତନୀୟ କିକୁ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਇੱਕ ਲਾਕ ਸਵਿੱਚ ਡਿਐਕਟਿਵੇਟ ਕੀਤੀ ਗਈ +Name[pl]=Klawisz blokujący został wyłączony +Name[pt]=Uma tecla de bloqueio foi desactivada +Name[pt_BR]=Uma tecla de bloqueio foi desativada +Name[ro]=O tastă de blocare a fost dezactivată +Name[ru]=Деактивирована клавиша переключения режимов +Name[se]=Lohkkadanboallu ii leat šat aktiivalaš +Name[si]=අගුළු යතුර අක්‍රීයයි +Name[sk]=Zamykací kláves je neaktívny +Name[sl]=Zaklepna tipka je bila onemogočena +Name[sr]=Закључавајући тастер је деактивиран +Name[sr@ijekavian]=Закључавајући тастер је деактивиран +Name[sr@ijekavianlatin]=Zaključavajući taster je deaktiviran +Name[sr@latin]=Zaključavajući taster je deaktiviran +Name[sv]=En låstangent har inaktiverats +Name[ta]=A lock key has been deactivated +Name[te]=అప్రవేశపు కీ క్రియాహీనం చేయబడింది +Name[tg]=Деактивирована клавиша переключения режимов +Name[th]=ปุ่มล็อคถูกปิดการทำงาน +Name[tr]=Bir kilitleme tuşu pasifleştirildi +Name[ug]=بىر قۇلۇپلاش كۇنۇپكىسى پاسسىپلاشتۇرۇلدى +Name[uk]=Було деактивовано клавішу фіксації +Name[wa]=Ene eclawåve tape a stî dismetowe +Name[x-test]=xxA lock key has been deactivatedxx +Name[zh_CN]=锁定键现已停用 +Name[zh_TW]=已解除鎖定鍵 +Comment=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now inactive +Comment[af]='n Sluitsleutel (bv. Caps Lock of Num Lock) se toestand het verander en is nou onaktief +Comment[ar]=تغيرت حالة مفتاح قفل (Caps Lock أو Num Lock) وألغي تفعيله +Comment[ast]=Una tecla de bloquéu (como Bloq Mayús o Bloq Num) camudó l'estáu y non ta activada +Comment[be@latin]=Klaviša macavańnia (naprykład, „Caps Lock” ci „Num Lock”) źmianiła svajo stanovišča j ciapier adcisnutaja. +Comment[bg]=Клавиш за превключване на режим (напр. Caps Lock или Num Lock) промени състоянието си и е неактивен +Comment[bn]=একটি লক কী (e.g. Caps Lock বা Num Lock) অবস্থা পরিবর্তন করে এখন নিষ্ক্রীয় হয়েছে +Comment[bs]=Zaključavajući taster (npr. CapsLock ili NumLock) promijenio je stanje i više nije aktivan +Comment[ca]=Alguna tecla de fixació (p.ex. Bloq Maj o Bloq Núm) ha canviat el seu estat i ara està inactiva +Comment[ca@valencia]=Alguna tecla de fixació (p.ex. Bloq Maj o Bloq Núm) ha canviat el seu estat i ara està inactiva +Comment[cs]=Klávesa pro přepnutí stavu (např. CapsLock nebo NumLock) byla stisknuta a je nyní neaktivní +Comment[csb]=Klawisza blokadë (Caps Lock abò Num Lock) zmienia swój sztatus ë nie je ju aktiwnô +Comment[da]=En låsetast (f.eks. Caps Lock eller Num Lock) har ændret sin tilstand og er nu inaktiv +Comment[de]=Eine Sperrtaste (Feststelltaste oder Nummernblocksperre) hat ihren Status geändert und ist nun inaktiv +Comment[el]=Ένα πλήκτρο κλειδώματος (π.χ. Caps Lock ή Num Lock) άλλαξε την κατάστασή του και είναι τώρα ανενεργό +Comment[en_GB]=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now inactive +Comment[eo]=Baskula klavo (ekz. majuskla baskulo aŭ nombra baskulo) ŝanĝis sian staton kaj nun estas malaktiva +Comment[es]=Una tecla de bloqueo (como Bloq Mayús o Bloq Num) ha cambiado su estado y no está activa +Comment[et]=Lukustusklahv (nt. Caps Lock või Num Lock) muutis oma seisundit ning on nüüd mitteaktiivne +Comment[eu]=Blokeo-tekla bat (adibidez, Blok Maius edo Blok Zenb) egoeraz aldatu da, eta orain inaktibo dago +Comment[fi]=Lukitusnäppäin (esim. CapsLock tai NumLock) on vaihtanut tilaansa ja ei ole enää aktiivinen +Comment[fr]=Une touche de verrouillage (ex : « Verr. Maj. » ou « Verr. Num. ») a changé d'état et est maintenant inactive +Comment[fy]=De tastân fan in beskoatteltoets (lykas kaptaalskoattel of Nûm skoattel) is feroare en is no ynaktyf +Comment[ga]=Athraíodh staid eochrach glasála (m.sh. Caps Lock nó Num Lock) agus tá sí neamhghníomhach anois +Comment[gl]=Unha tecla de bloqueo (por ex., Bloq Maiúsc ou Bloq Num) mudou de estado e agora está inactiva +Comment[gu]=તાળાં કળે (દા.ત., કેપ્સ લોક અથવા નમ લોક) હવે તેની સ્થિતિ બદલી છે અને હવે તે નિષ્ક્રિય છે +Comment[he]=מקש נועל (למשל Caps Lock או Num Lock) שינה את מצבו וכרגע לא פעיל +Comment[hne]=कोई ताला कुंजी (जइसन कि कैप्स लाक या न्यूम लाक) हर अपन स्थिति ल बदल दे हे अउ अब वो हर अक्रिय हो गे हे +Comment[hr]=Tipka zaključavanja (npr. CapsLock ili NumLock) promijenila je svoje stanje i više nije aktivna +Comment[hsb]=Tasta za stajne zaswěćene (na př. Stajny Wulkopis) je status změniła a je nětko njeaktiwna +Comment[hu]=Egy zároló billentyű (pl. a Caps Lock vagy a Num Lock) inaktívvá vált +Comment[ia]=Un clave de bloco (p.ex. Caps Lock o Num Lock) ha cambiate su stato e ora es inactive +Comment[id]=Sebuah tombol kunci (misalnya Caps Lock atau Num Lock) telah diubah keadaannya dan sekarang tidak aktif +Comment[is]=Læsilykill (t.d. Caps Lock eða Num Lock) hefur breytt um stöðu og er nú óvirkur +Comment[it]=Un tasto di blocco (ad es. Bloc Maiusc o Bloc Num) ha cambiato stato ed è ora disattivo +Comment[ja]=ロックキー (Caps Lock や Num Lock) の状態が変更され、非アクティブになりました +Comment[kk]=Қосқыш перне (мыс. Caps Lock не Num Lock) күйін ауыстырып енді белсенді емес +Comment[km]=គ្រាប់​ចុច​ចាក់​សោ (ឧ. ប្ដូរ​ជាប់ (Caps Lock) ឬ​គ្រាប់ចុច​លេខ (Num Lock)) បាន​ត្រូវ​ផ្លាស់ប្ដូរ​ស្ថានភាព​​របស់​​វា ហើយ​ឥឡូវ​នេះ​អសកម្ម +Comment[kn]=ಒಂದು ಭಂಧನ (ಲಾಕ್) ಕೀಲಿ (ಉ.ದಾ Shift ಅಥವಾ Ctrl) ನ ಸ್ಥಿತಿಯು ಬದಲಾಗಿದ್ದು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ +Comment[ko]=Caps Lock이나 Num Lock 키 같은 잠금 키의 상태가 바뀌었고 현재 비활성화됨 +Comment[ku]=Rewşa bişkojkeke mifteyê (wekî Caps Lock an jî Num Lock) hate guhertin û niha neçalak e +Comment[lt]=Užrakto klavišo (pvz., Didž(Caps Lock) arba Sk(Num Lock)) būsena pakito ir jis dabar – neaktyvus +Comment[lv]=Slēga taustiņš (piem. Caps Lock vai Num Lock) ir mainījis stāvokli un tagad ir neaktīvs +Comment[mk]=Некое копче за заклучување (пр. Caps Lock или Num Lock) си ја смени состојбата и сега е неактивно +Comment[ml]=ഒരു ലോക്ക് കീ (ഉദാ. കാപ്സ് ലോക്ക് അല്ലെങ്കില്‍ നം ലോക്ക്) അവസ്ഥ മാറി നിര്‍ജീവമായിരിക്കുന്നു +Comment[mr]=कुलूपबंद कि (उ.दा. Caps Lock किंवा Num Lock) ने स्तर बदलविले आहे व आता निष्क्रिय आहे +Comment[nb]=En låsetast (f.eks. Caps Lock eller Num Lock) har endret status og er nå slått av +Comment[nds]=En Tastrast (Tallen- oder Grootschriev-Rast a.B.) hett sien Tostand ännert un is nu nich mehr inleggt +Comment[nl]=Een vergrendeltoets (bijv. Caps Lock of Num Lock ) is nu inactief +Comment[nn]=Ein låsetast (som «Caps Lock» eller «Num Lock») har endra status, og er no inaktiv +Comment[or]=ଗୋଟିଏ ଅପରିବର୍ତ୍ତନୀୟ କି (ଯେପରିକି Caps Lock କିମ୍ବା Num Lock) ସେମାନଙ୍କର ସ୍ଥିତି ପରିବର୍ତ୍ତନ କରିଛନ୍ତି ଏବଂ ବର୍ତ୍ତମାନ ନିଷ୍କ୍ରିୟ ଅଛି +Comment[pl]=Klawisz blokujący (np. Caps Lock lub Num Lock) zmienił stan i jest teraz wyłączony +Comment[pt]=Uma tecla de bloqueio (p.ex., a Caps Lock ou a Num Lock) alterou o seu estado e ficou agora inactiva +Comment[pt_BR]=Uma tecla de bloqueio (p.ex. Caps Lock ou Num Lock) teve seu estado alterado e agora está inativa +Comment[ro]=O tastă de blocare (cum ar fi Caps Lock sau Num Lock) și-a schimbat starea și este acum inactivă +Comment[ru]=Клавиша переключения режимов (например, Caps Lock или Num Lock) изменила своё состояние и сейчас не активна +Comment[si]=අගුළු යතුරේ (උදා. Caps Lock හෝ Num Lock) තත්වය වෙනස් වී ඇති අතර එය දැන් අක්‍රීයයි +Comment[sk]=Zamykací kláves (napr. Caps Lock alebo Num Lock) zmenil svoj stav a je teraz neaktívny +Comment[sl]=Zaklepna tipka (npr. Caps Lock ali Num Lock) je spremenila stanje in je sedaj nedejavna +Comment[sr]=Закључавајући тастер (нпр. CapsLock или NumLock) променио је стање и више није активан +Comment[sr@ijekavian]=Закључавајући тастер (нпр. CapsLock или NumLock) промијенио је стање и више није активан +Comment[sr@ijekavianlatin]=Zaključavajući taster (npr. CapsLock ili NumLock) promijenio je stanje i više nije aktivan +Comment[sr@latin]=Zaključavajući taster (npr. CapsLock ili NumLock) promenio je stanje i više nije aktivan +Comment[sv]=En låstangent (t.ex. Caps Lock eller Num Lock) har ändrat tillstånd och är nu inaktiv +Comment[ta]=A lock key (e.g. Caps Lock or Num Lock) has changed its state and is now inactive +Comment[te]=అప్రవేశపు కీ (ఉ.దా. Caps Lock లేదా Num Lock) దాని స్థితిని మార్చుకుంది మరియు ఇప్పుడు క్రియాహీనంగా ఉంది +Comment[tg]=Клавиша переключения режимов (например, Caps Lock или Num Lock) изменила своё состояние и сейчас не активна +Comment[th]=ปุ่มล็อค (เช่น Caps Lock หรือ Num Lock) ได้มีการเปลี่ยนสถานะของมันและขณะนี้ได้ปิดการทำงาน +Comment[tr]=Bir kilitleme tuşunun (Caps Lock ya da Num Lock gibi.) durumu değiştirildi ve pasifleştirildi +Comment[ug]=بىر قۇلۇپلاش كۇنۇپكىسى (مەسىلەن، Caps Lock ياكى Num Lock) ئۇنىڭ ھالىتىنى ئۆزگەرتتى، ھازىر پاسسىپلاشتۇرۇلدى +Comment[uk]=Клавіша фіксації (наприклад Caps Lock або Num Lock) змінила свій стан і тепер неактивна +Comment[wa]=Ene eclawåve tape (metans CAPS LOCK oudonbén NUM LOCK) a candjî si estat eyet n' est asteure pus ovrante +Comment[x-test]=xxA lock key (e.g. Caps Lock or Num Lock) has changed its state and is now inactivexx +Comment[zh_CN]=锁定键(如 Caps Lock 或 Num Lock)更改了其状态,现已停用 +Comment[zh_TW]=一個鎖定鍵(如 CapsLock 或 NumLock)已改變它的狀態成為未啟用 +Sound=KDE-Sys-Special.ogg + +nopresentation=236 + +[Event/stickykeys] +Name=Sticky keys has been enabled or disabled +Name[af]=Sticky sleutels was geaktiveer of gedeaktiveer +Name[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح المثبتة +Name[ast]=Les tecles pegañoses activáronse o desactiváronse +Name[be@latin]=Lipučyja klavišy źmianili svajo stanovišča +Name[bg]="Лепкави" клавиши са включени или изключени +Name[bs]=Ljepljivi tasteri su uključeni ili isključeni +Name[ca]=Les tecles apegaloses s'han activat o desactivat +Name[ca@valencia]=Les tecles apegaloses s'han activat o desactivat +Name[cs]=Lepivé klávesy byly povoleny nebo zakázány +Name[csb]=Klawisze przëlepieniô òstałë aktiwòwòné abò deaktiwòwóné +Name[da]=Klæbende taster er aktiveret eller deaktiveret +Name[de]=Klebende Tasten sind aktiviert oder deaktiviert worden +Name[el]=Τα κολλημένα πλήκτρα ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Name[en_GB]=Sticky keys has been enabled or disabled +Name[eo]=Fiksaj klavoj validiĝis aŭ malvalidiĝis +Name[es]=Las teclas pegajosas se han activado o desactivado +Name[et]=Kleepuvad klahvid on keelatud või lubatud +Name[eu]=Tekla itsaskorrak gaitu edo desgaitu dira +Name[fi]=Tahmeat näppäimet on otettu käyttöön tai poistettu käytöstä +Name[fr]=L'auto-maintien des touches a été activé ou désactivé +Name[fy]=Plakkende toetsen binne aktivearre of deaktivearre +Name[ga]=Cumasaíodh nó díchumasaíodh eochracha greamaitheacha +Name[gl]=As teclas pegañentas activáronse ou desactiváronse +Name[gu]=સ્થિત કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Name[he]=מקשים דביקים הופעלו או בוטלו +Name[hi]=चिपकती कुंजियों को सक्षम या अक्षम किया गया है +Name[hne]=स्टिकी कुंजी सक्रिय या अक्रिय हो गे हे +Name[hr]=Ljepljive tipke su omogućene ili onemogućene +Name[hsb]=Lěpjate tasty zaswěćene abo hasnjene +Name[hu]=Ragadós billentyűk átkapcsolva +Name[ia]=Le claves collate ha essite habilitate o dishabilitate +Name[id]=Tombol lekat telah diaktifkan atau dinonaktifkan +Name[is]=Slökkt eða kveikt hefur verið á klístruðum lyklum +Name[it]=I tasti permanenti sono stati attivati o disattivati +Name[ja]=スティッキーキーが有効または無効になりました +Name[kk]=Жабысқақ пернелер рұқсат етілді/етілмеді +Name[km]=គ្រាប់​ចុច​ស្អិត​​ត្រូវ​បាន​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Name[kn]=ಅಂಟು (ಸ್ಟಿಕಿ) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=끈적이 키가 활성화되거나 비활성화됨 +Name[ku]=Bişkojkên Mezeloqî hatin çalakirin an jî neçalakirin +Name[lt]=Lipnūs klavišai buvo įgalinti arba išjungti +Name[lv]=Lipīgie taustiņi tika ieslēgti vai izslēgti +Name[mk]=„Лепливи копчиња“ е овозможено или оневозможено +Name[ml]=സ്റ്റിക്കി കീ പ്രവര്‍ത്തന സജ്ജം അല്ലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതം ആക്കിയിരിക്കുന്നു +Name[mr]=स्टिकी कि कार्यन्वीत किंवा अकार्यान्वित केली गेली आहे +Name[nb]=Faste valgtaster er blitt slått på eller av +Name[nds]="Backig Tasten" wöör an- oder utmaakt +Name[ne]=स्टिकी कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Name[nl]=Plakkende toetsen is geactiveerd of gedeactiveerd +Name[nn]=Faste valtastar er no slått på eller av +Name[or]=Sticky କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਸਟਿੱਕੀ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Name[pl]=Lepkie klawisze zostały włączone lub wyłączone +Name[pt]=As teclas fixas foram activadas ou desactivadas +Name[pt_BR]=Teclas de aderência foram habilitadas ou desabilitadas +Name[ro]=Taste lipicioase au fost activate sau dezactivate +Name[ru]=Включены или отключены «залипающие» клавиши +Name[se]=Giddes válljenboallu lea rievdadan stáhtusa +Name[si]=ඇළෙන යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Name[sk]=Lepkavé klávesy zmenili svoj stav +Name[sl]=Lepljive tipke so bile omogočene ali onemogočene +Name[sr]=Лепљиви тастери су укључени или искључени +Name[sr@ijekavian]=Љепљиви тастери су укључени или искључени +Name[sr@ijekavianlatin]=Ljepljivi tasteri su uključeni ili isključeni +Name[sr@latin]=Lepljivi tasteri su uključeni ili isključeni +Name[sv]=Klistriga tangenter har aktiverats eller inaktiverats +Name[ta]=Sticky keys has been enabled or disabled +Name[te]=స్టికీ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Name[tg]=Тугмаҳои часпанда фаъол ё ғайрифаъол шудаанд +Name[th]=การกดปุ่มพิมพ์ค้างได้ถูกเปิดหรือปิดการทำงาน +Name[tr]=Yapışkan tuşlar etkinleştirildi ya da pasifleştirildi +Name[ug]=چاپلىشاڭغۇ(Sticky) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Name[uk]=Було активовано або деактивовано липкі клавіші +Name[wa]=Les aclapantès tapes on stî metowes oudonbén dismetowes +Name[x-test]=xxSticky keys has been enabled or disabledxx +Name[zh_CN]=启用或禁用了粘滞键 +Name[zh_TW]=相黏鍵已改變狀態 +Comment=Sticky keys has been enabled or disabled +Comment[af]=Sticky sleutels was geaktiveer of gedeaktiveer +Comment[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح المثبتة +Comment[ast]=Les tecles pegañoses activáronse o desactiváronse +Comment[be@latin]=Lipučyja klavišy źmianili svajo stanovišča. +Comment[bg]="Лепкави" клавиши са включени или изключени +Comment[bs]=Ljepljivi tasteri su uključeni ili isključeni +Comment[ca]=Les tecles apegaloses s'han activat o desactivat +Comment[ca@valencia]=Les tecles apegaloses s'han activat o desactivat +Comment[cs]=Lepivé klávesy byly povoleny nebo zakázány +Comment[csb]=Klawisze przëlepieniô òstałë aktiwòwòné abò deaktiwòwóné +Comment[da]=Klæbende taster er aktiveret eller deaktiveret +Comment[de]=Die Funktion „Klebende Tasten“ ist aktiviert oder deaktiviert worden +Comment[el]=Τα κολλημένα πλήκτρα ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Comment[en_GB]=Sticky keys has been enabled or disabled +Comment[eo]=Fiksaj klavoj validiĝis aŭ malvalidiĝis +Comment[es]=Las teclas pegajosas se han activado o desactivado +Comment[et]=Kleepuvad klahvid on keelatud või lubatud +Comment[eu]=Tekla itsaskorrak gaitu edo desgaitu dira +Comment[fi]=Tahmeat näppäimet on otettu käyttöön tai poistettu käytöstä +Comment[fr]=L'auto-maintien des touches a été activé ou désactivé +Comment[fy]=Plakkende toetsen binne aktivearre of deaktivearre +Comment[ga]=Cumasaíodh nó díchumasaíodh eochracha greamaitheacha +Comment[gl]=As teclas pegañentas foron ou activadas ou desactivadas +Comment[gu]=સ્થિત કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Comment[he]=מקשים דביקים הופעלו או בוטלו +Comment[hi]=चिपकती कुंजियों को सक्षम या अक्षम किया गया है +Comment[hne]=स्टिकी कुंजी सक्रिय या अक्रिय हो गे हे +Comment[hr]=Ljepljive tipke su omogućene ili onemogućene +Comment[hsb]=Lěpjate tasty zaswěćene abo hasnjene +Comment[hu]=A ragadós billentyűk használatát ki- vagy bekapcsolták +Comment[ia]=Le claves collate ha essite habilitate o dishabilitate +Comment[id]=Tombol lekat telah diaktifkan atau dinonaktifkan +Comment[is]=Slökkt eða kveikt hefur verið á klístruðum lyklum +Comment[it]=I tasti permanenti sono stati attivati o disattivati +Comment[ja]=スティッキーキーが有効または無効になりました +Comment[kk]=Жабысқақ пернелер рұқсат етілді/етілмеді +Comment[km]=គ្រាប់​ចុច​ស្អិត​​ត្រូវ​បាន​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Comment[kn]=ಅಂಟು (ಸ್ಟಿಕಿ) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Comment[ko]=끈적이 키가 활성화되거나 비활성화됨 +Comment[ku]=Bişkojkên Mezeloqî hatin çalakirin an jî neçalakirin +Comment[lt]=Lipnūs klavišai buvo įjungti arba išjungti +Comment[lv]=Lipīgie taustiņi tika ieslēgti vai izslēgti +Comment[mk]=„Лепливи копчиња“ е овозможено или оневозможено +Comment[ml]=സ്റ്റിക്കി കീ പ്രവര്‍ത്തന സജ്ജം അല്ലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതം ആക്കിയിരിക്കുന്നു +Comment[mr]=स्टिकी कि कार्यन्वीत किंवा अकार्यान्वित केली गेली आहे +Comment[nb]=Faste valgtaster er blitt slått på eller av +Comment[nds]="Backig Tasten" wöör an- oder utmaakt +Comment[ne]=स्टिकी कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Comment[nl]=Plakkende toetsen is geactiveerd of gedeactiveerd +Comment[nn]=Faste valtastar er no slått på eller av +Comment[or]=Sticky କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Comment[pa]=ਸਟਿੱਕੀ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Comment[pl]=Lepkie klawisze zostały włączone lub wyłączone +Comment[pt]=As teclas fixas foram activadas ou desactivadas +Comment[pt_BR]=Teclas de aderência foram habilitadas ou desabilitadas +Comment[ro]=Taste lipicioase au fost activate sau dezactivate +Comment[ru]=Включены или отключены «залипающие» клавиши +Comment[se]=Giddes válljenboallu lea rievdadan stáhtusa +Comment[si]=ඇළෙන යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Comment[sk]=Lepkavé klávesy zmenili svoj stav +Comment[sl]=Lepljive tipke so bile omogočene ali onemogočene +Comment[sr]=Лепљиви тастери су укључени или искључени +Comment[sr@ijekavian]=Љепљиви тастери су укључени или искључени +Comment[sr@ijekavianlatin]=Ljepljivi tasteri su uključeni ili isključeni +Comment[sr@latin]=Lepljivi tasteri su uključeni ili isključeni +Comment[sv]=Klistriga tangenter har aktiverats eller inaktiverats +Comment[ta]=Sticky keys has been enabled or disabled +Comment[te]=స్టికీ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Comment[tg]=Тугмаҳои часпанда фаъол ё ғайрифаъол шудаанд +Comment[th]=การกดปุ่มพิมพ์ค้างได้ถูกเปิดหรือปิดการทำงาน +Comment[tr]=Yapışkan tuşlar etkinleştirildi ya da pasifleştirildi +Comment[ug]=چاپلىشاڭغۇ(Sticky) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Comment[uk]=Було активовано або деактивовано липкі клавіші +Comment[wa]=Les aclapantès tapes on stî metowes oudonbén dismetowes +Comment[x-test]=xxSticky keys has been enabled or disabledxx +Comment[zh_CN]=启用或禁用了粘滞键 +Comment[zh_TW]=相黏鍵已啟動或關閉。 +Sound=KDE-Sys-Special.ogg +Action=Popup +nopresentation=236 + +[Event/slowkeys] +Name=Slow keys has been enabled or disabled +Name[af]=Stadige sleutels was geaktiveer of gedeaktiveer +Name[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح البطيئة +Name[ast]=Les tecles lentes activáronse o desactiváronse +Name[be@latin]=Pavolnyja klavišy źmianili svajo stanovišča +Name[bg]="Бавни" клавиши са включени или изключени +Name[bs]=Spori tasteri su uključeni ili isključeni +Name[ca]=Les tecles lentes s'han activat o desactivat +Name[ca@valencia]=Les tecles lentes s'han activat o desactivat +Name[cs]=Pomalé klávesy byly povoleny nebo zakázány +Name[csb]=Pòwòlné klawisze òstałë aktiwòwòné abò deaktiwòwóné +Name[da]=Langsomme taster er aktiveret eller deaktiveret +Name[de]=Langsame Tasten sind aktiviert oder deaktiviert worden +Name[el]=Τα αργά πλήκτρα ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Name[en_GB]=Slow keys has been enabled or disabled +Name[eo]=Malrapidklavoj validiĝis aŭ malvalidiĝis +Name[es]=Las teclas lentas se han activado o desactivado +Name[et]=Aeglased klahvid on keelatud või lubatud +Name[eu]=Tekla motelak gaitu edo desgaitu dira +Name[fi]=Hitaat näppäimet on otettu käyttöön tai poistettu käytöstä +Name[fr]=Les touches lentes ont été activées ou désactivées +Name[fy]=Trage toetsen binne aktivearre of ûntaktivearre +Name[ga]=Cumasaíodh nó díchumasaíodh eochracha malla +Name[gl]=As teclas lentas activáronse ou desactiváronse +Name[gu]=ધીમી કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Name[he]=תגובה איטית של המקשים הופעלה או הופסקה +Name[hi]=धीमी कुंजियों को सक्षम या अक्षम किया गया है +Name[hne]=धीमा कुंजी सक्रिय या अक्रिय हो गे हे +Name[hr]=Spore tipke su omogućene ili onemogućene +Name[hsb]=Pomałe tasty zaswěćene abo hasnjene +Name[hu]=A lassú billentyűk használata átkapcsolva +Name[ia]=Le claves lente ha essite activate o disactivate +Name[id]=Tombol pelan telah diaktifkan atau dinonaktifkan +Name[is]=Slökkt eða kveikt hefur verið á hægum lyklum +Name[it]=Il rallentamento dei tasti è stato attivato o disattivato +Name[ja]=スローキーが有効または無効になりました +Name[kk]=Баяу пернелер рұқсат етілді/етілмеді +Name[km]=គ្រាប់​ចុច​យឺត​​ត្រូវ​បាន​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Name[kn]=ನಿಧಾನ (ಸ್ಲೋ) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=느린 키가 활성화되거나 비활성화됨 +Name[ku]=Bişkojkên Hêdî hatin çalakirin an jî neçalakirin +Name[lt]=Lėti klavišai buvo įgalinti arba išjungti +Name[lv]=Lēnie taustiņi tika ieslēgti vai izslēgti +Name[mk]=„Спори копчиња“ е овозможено или оневозможено +Name[ml]=സ്ലോ കീ പ്രവര്‍ത്തന സജ്ജമലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതമാക്കിയിരിക്കുന്നു +Name[mr]=हळु कार्यरत कि आता कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Name[nb]=Trege taster er blitt slått på eller av +Name[nds]="Langsam Tasten" wöör an- oder utmaakt +Name[ne]=शो कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Name[nl]=Langzame toetsen is geactiveerd of gedeactiveerd +Name[nn]=Trege tastar er no slått på eller av +Name[or]=Slow କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਸਲੋਅ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Name[pl]=Powolne klawisze zostały włączone lub wyłączone +Name[pt]=As teclas lentas foram activadas ou desactivadas +Name[pt_BR]=Teclas lentas foram habilitadas ou desabilitadas +Name[ro]=Taste lente (Slow keys) au fost activate sau dezactivate +Name[ru]=Включены или отключены замедленные клавиши +Name[si]=වේගය අඩු යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Name[sk]=Pomalé klávesy zmenili svoj stav +Name[sl]=Počasne tipke so bile omogočene ali onemogočene +Name[sr]=Спори тастери су укључени или искључени +Name[sr@ijekavian]=Спори тастери су укључени или искључени +Name[sr@ijekavianlatin]=Spori tasteri su uključeni ili isključeni +Name[sr@latin]=Spori tasteri su uključeni ili isključeni +Name[sv]=Långsamma tangenter har aktiverats eller inaktiverats +Name[ta]=Slow keys has been enabled or disabled +Name[te]=స్లో కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Name[tg]=Тугмаҳои суст фаъол ё ғайрифаъол шудаанд +Name[th]=การกดปุ่มพิมพ์ช้าได้ถูกเปิดหรือปิดการทำงาน +Name[tr]=Yavaş tuşlar etkinleştirildi ya da pasifleştirildi +Name[ug]=ئاستا(Slow) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Name[uk]=Було активовано або деактивовано повільні клавіші +Name[wa]=Des londjinnès tapes ont stî metowe en alaedje oudonbén dismetowes +Name[x-test]=xxSlow keys has been enabled or disabledxx +Name[zh_CN]=启用或禁用了筛选键 +Name[zh_TW]=慢速鍵已改變狀態 +Comment=Slow keys has been enabled or disabled +Comment[af]=Stadige sleutels was geaktiveer of gedeaktiveer +Comment[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح البطيئة +Comment[ast]=Les tecles lentes activáronse o desactiváronse +Comment[be@latin]=Pavolnyja klavišy źmianili svajo stanovišča. +Comment[bg]="Бавни" клавиши са включени или изключени +Comment[bs]=Spori tasteri su uključeni ili isključeni +Comment[ca]=Les tecles lentes s'han activat o desactivat +Comment[ca@valencia]=Les tecles lentes s'han activat o desactivat +Comment[cs]=Pomalé klávesy byly povoleny nebo zakázány +Comment[csb]=Pòwòlné klawisze òstałë aktiwòwòné abò deaktiwòwóné +Comment[da]=Langsomme taster er aktiveret eller deaktiveret +Comment[de]=Die Funktion „Langsame Tasten“ ist aktiviert oder deaktiviert worden +Comment[el]=Τα αργά πλήκτρα ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Comment[en_GB]=Slow keys has been enabled or disabled +Comment[eo]=Malrapidklavoj validiĝis aŭ malvalidiĝis +Comment[es]=Las teclas lentas se han activado o desactivado +Comment[et]=Aeglased klahvid on keelatud või lubatud +Comment[eu]=Tekla motelak gaitu edo desgaitu dira +Comment[fi]=Hitaat näppäimet on otettu käyttöön tai poistettu käytöstä +Comment[fr]=Les touches lentes ont été activées ou désactivées +Comment[fy]=Trage toetsen binne aktivearre of ûntaktivearre +Comment[ga]=Cumasaíodh nó díchumasaíodh eochracha malla +Comment[gl]=As teclas lentas foron ou activadas ou desactivadas +Comment[gu]=ધીમી કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Comment[he]=תגובה איטית של המקשים הופעלה או הופסקה +Comment[hi]=धीमी कुंजियों को सक्षम या अक्षम किया गया है +Comment[hne]=धीमा कुंजी सक्छम या अक्छम हो गे हे +Comment[hr]=Spore tipke su omogućene ili onemogućene +Comment[hsb]=Pomałe tasty zaswěćene abo hasnjene +Comment[hu]=A lassú billentyűk használatát ki- vagy bekapcsolták +Comment[ia]=Le claves lente ha essite activate o disactivate +Comment[id]=Tombol pelan telah diaktifkan atau dinonaktifkan +Comment[is]=Slökkt eða kveikt hefur verið á hægum lyklum +Comment[it]=Il rallentamento dei tasti è stato attivato o disattivato +Comment[ja]=スローキーが有効または無効になりました +Comment[kk]=Баяу пернелер рұқсат етілді/етілмеді +Comment[km]=គ្រាប់​ចុច​យឺត​ត្រូវ​បាន​​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Comment[kn]=ನಿಧಾನ (ಸ್ಲೋ) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Comment[ko]=느린 키가 활성화되거나 비활성화됨 +Comment[ku]=Bişkojkên Hêdî hatin çalakirin an jî neçalakirin +Comment[lt]=Lėti klavišai buvo įgalinti arba išjungti +Comment[lv]=Lēnie taustiņi tika ieslēgti vai izslēgti +Comment[mk]=„Спори копчиња“ е овозможено или оневозможено +Comment[ml]=സ്ലോ കീ പ്രവര്‍ത്തന സജ്ജമലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതമാക്കിയിരിക്കുന്നു +Comment[mr]=हळु कार्यरत कि आता कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Comment[nb]=Trege taster er blitt slått på eller av +Comment[nds]="Langsam Tasten" wöör an- oder utmaakt +Comment[ne]=शो कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Comment[nl]=Langzame toetsen is geactiveerd of gedeactiveerd +Comment[nn]=Trege tastar er no slått på eller av +Comment[or]=Slow କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Comment[pa]=ਸਲੋਅ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Comment[pl]=Powolne klawisze zostały włączone lub wyłączone +Comment[pt]=As teclas lentas foram activadas ou desactivadas +Comment[pt_BR]=Teclas lentas foram habilitadas ou desabilitadas +Comment[ro]=Taste lente (Slow keys) au fost activate sau dezactivate +Comment[ru]=Включены или отключены замедленные клавиши +Comment[si]=වේගය අඩු යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Comment[sk]=Pomalé klávesy zmenili svoj stav +Comment[sl]=Počasne tipke so bile omogočene ali onemogočene +Comment[sr]=Спори тастери су укључени или искључени +Comment[sr@ijekavian]=Спори тастери су укључени или искључени +Comment[sr@ijekavianlatin]=Spori tasteri su uključeni ili isključeni +Comment[sr@latin]=Spori tasteri su uključeni ili isključeni +Comment[sv]=Långsamma tangenter har aktiverats eller inaktiverats +Comment[ta]=Slow keys has been enabled or disabled +Comment[te]=స్లో కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Comment[tg]=Тугмаҳои суст фаъол ё ғайрифаъол шудаанд +Comment[th]=การกดปุ่มพิมพ์ช้าได้ถูกเปิดหรือปิดการทำงาน +Comment[tr]=Yavaş tuşlar etkinleştirildi ya da pasifleştirildi +Comment[ug]=ئاستا(Slow) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Comment[uk]=Було активовано або деактивовано повільні клавіші +Comment[wa]=Des londjinnès tapes ont stî metowe en alaedje oudonbén dismetowes +Comment[x-test]=xxSlow keys has been enabled or disabledxx +Comment[zh_CN]=启用或禁用了筛选键 +Comment[zh_TW]=慢速鍵已啟動或關閉。 +Sound=KDE-Sys-Special.ogg +Action=Popup +nopresentation=236 + +[Event/bouncekeys] +Name=Bounce keys has been enabled or disabled +Name[af]=Hopsleutels is geaktiveer of gedeaktiveer +Name[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح المكررة +Name[ast]=Les tecles de rebote activáronse o desactiváronse +Name[bg]="Подскачащи" клавиши са включени или изключени +Name[bs]=Odskačući tasteri su uključeni ili isključeni +Name[ca]=Les tecles de repetició s'han activat o desactivat +Name[ca@valencia]=Les tecles de repetició s'han activat o desactivat +Name[cs]=Zdvojené klávesy byly povoleny nebo zakázány +Name[csb]=Òdbijającé klawisze òstałë aktiwòwòné abò deaktiwòwóné +Name[da]=Elastiske taster er aktiveret eller deaktiveret +Name[de]=Zurückschnellende Tasten sind aktiviert oder deaktiviert worden +Name[el]=Τα πλήκτρα αναπήδησης ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Name[en_GB]=Bounce keys has been enabled or disabled +Name[eo]=Prokrastaj klavoj validiĝis aŭ malvalidiĝis +Name[es]=Se ha activado o desactivado el rebote de teclas +Name[et]=Põrkavad klahvid on keelatud või lubatud +Name[eu]=Errebote-teklak gaitu edo desgaitu dira +Name[fi]=Kimpoavat näppäimet on otettu käyttöön tai poistettu käytöstä +Name[fr]=Les touches non répétées ont été activées ou désactivées +Name[fy]=Stuiterjende toetsen binne aktivearre of ûntaktivearre +Name[ga]=Cumasaíodh nó díchumasaíodh eochracha preabtha +Name[gl]=A anulación temporal de teclas activouse ou desactivouse +Name[gu]=ઉછાળ કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Name[he]=מניעת לחיצה על מספר מקשים בו־זמנית הופעלה או הופסקה +Name[hi]=बाउंस कुंजियों को सक्षम या अक्षम किया गया है +Name[hne]=बाउन्स कुंजी सक्छम या अक्छम हो गे हे +Name[hr]=Obijanje tipki je omogućeno ili onemogućeno +Name[hsb]=Zamkane tasty zaswěćene abo hasnjene +Name[hu]=A visszaugró billentyűk átkapcsolva +Name[ia]=Le claves elastic ha essite activate o disactivate +Name[id]=Tombol pantul telah diaktifkan atau dinonaktifkan +Name[is]=Slökkt eða kveikt hefur verið á skoppandi lyklum +Name[it]=I tasti ravvicinati sono stati abilitati o disattivati +Name[ja]=バウンスキーが有効または無効になりました +Name[kk]=Қалшылға қарсы пернелер рұқсат етілді/етілмеді +Name[km]=គ្រាប់​ចុច​លោត​​ត្រូវ​បាន​​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Name[kn]=ಪುಟಿಯುವ (ಬೌನ್ಸ್) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=튕김 키가 활성화되거나 비활성화됨 +Name[ku]=Bişkojkên Zindî hatin çalakirin an jî neçalakirin +Name[lt]=Tamprūs klavišai buvo įgalinti arba išjungti +Name[lv]=Atlecošie taustiņi tika ieslēgti vai izslēgti +Name[mk]=„Скокачки копчиња“ е овозможено или оневозможено +Name[ml]=ബൌണ്‍സ് കീ പ്രവര്‍ത്തന സജ്ജം അല്ലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതം ആക്കിയിരിക്കുന്നു +Name[mr]=बाउन्स् कि कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Name[nb]=Filtertaster er blitt slått på eller av +Name[nds]="Jumpen Tasten" wöör an- oder utmaakt +Name[ne]=बाउन्स कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Name[nl]=Stuiterende toetsen is geactiveerd of gedeactiveerd +Name[nn]=Filtertastar er no slått på eller av +Name[or]=Bounce କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਬਾਊਂਸ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Name[pl]=Odbijające klawisze zostały włączone lub wyłączone +Name[pt]=As teclas sonoras foram activadas ou desactivadas +Name[pt_BR]=As teclas de repercussão foram ativadas ou desativadas +Name[ro]=Taste săltărețe (Bounce keys) au fost activate sau dezactivate +Name[ru]=Включены или отключены «прыгающие» клавиши +Name[se]=Sillenboallu lea rievdadan stáhtusa +Name[si]=පොළාපැනුම් යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Name[sk]=Bounce klávesy zmenili svoj stav +Name[sl]=Odbijajoče tipke so bile omogočene ali onemogočene +Name[sr]=Одскачући тастери су укључени или искључени +Name[sr@ijekavian]=Одскачући тастери су укључени или искључени +Name[sr@ijekavianlatin]=Odskačući tasteri su uključeni ili isključeni +Name[sr@latin]=Odskačući tasteri su uključeni ili isključeni +Name[sv]=Studsande tangenter har aktiverats eller inaktiverats +Name[ta]=Bounce keys has been enabled or disabled +Name[te]=బౌన్‍స్ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Name[tg]=Тугмаҳои ҷаҳиш фаъол ё ғайрифаъол шудаанд +Name[th]=การกดปุ่มพิมพ์รัวได้ถูกเปิดหรือปิดการทำงาน +Name[tr]=Sıçrama tuşları etkinleştirildi ya da pasifleştirildi +Name[ug]=سەكرىمە(Bounce) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Name[uk]=Було активовано або деактивовано пружні клавіші +Name[vi]=Phím nảy đã được bật hoặc tắt +Name[wa]=Des dimey-eclawåvès tapes ont stî metowe en alaedje oudonbén dismetowes +Name[x-test]=xxBounce keys has been enabled or disabledxx +Name[zh_CN]=启用或禁用了撞击键 +Name[zh_TW]=彈回鍵已改變狀態 +Comment=Bounce keys has been enabled or disabled +Comment[af]=Hop sleutels was geaktiveer of gedeaktiveer +Comment[ar]=تم تفعيل أو إلغاء تفعيل المفاتيح المكررة +Comment[ast]=Les tecles de rebote activáronse o desactiváronse +Comment[bg]="Подскачащи" клавиши са включени или изключени +Comment[bs]=Odskačući tasteri su uključeni ili isključeni +Comment[ca]=Les tecles de repetició s'han activat o desactivat +Comment[ca@valencia]=Les tecles de repetició s'han activat o desactivat +Comment[cs]=Zdvojené klávesy byly povoleny nebo zakázány +Comment[csb]=Òdbijającé klawisze òstałë aktiwòwòné abò deaktiwòwóné +Comment[da]=Elastiske taster er aktiveret eller deaktiveret +Comment[de]=Die Funktion „Zurückschnellende Tasten“ ist aktiviert oder deaktiviert worden +Comment[el]=Τα πλήκτρα αναπήδησης ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Comment[en_GB]=Bounce keys has been enabled or disabled +Comment[eo]=Prokrastaj klavoj validiĝis aŭ malvalidiĝis +Comment[es]=Se ha activado o desactivado el rebote de teclas +Comment[et]=Põrkavad klahvid on keelatud või lubatud +Comment[eu]=Errebote-teklak gaitu edo desgaitu dira +Comment[fi]=Kimpoavat näppäimet on otettu käyttöön tai poistettu käytöstä +Comment[fr]=Les touches non répétées ont été activées ou désactivées +Comment[fy]=Stuiterjende toetsen binne aktivearre of ûntaktivearre +Comment[ga]=Cumasaíodh nó díchumasaíodh eochracha preabtha +Comment[gl]=A anulación temporal de teclas foi ou activada ou desactivada +Comment[gu]=ઉછાળ કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Comment[he]=מניעת לחיצה על מספר מקשים בו־זמנית הופעלה או הופסקה +Comment[hi]=बाउंस कुंजियों को सक्षम या अक्षम किया गया है +Comment[hne]=बाउन्स कुंजी सक्छम या अक्छम हो गे हे +Comment[hr]=Obijanje tipki je omogućeno ili onemogućeno +Comment[hsb]=Zamkane tasty zaswěćene abo hasnjene +Comment[hu]=A visszaugró billentyűk használatát ki- vagy bekapcsolták +Comment[ia]=Le claves elastic ha essite activate o disactivate +Comment[id]=Tombol pantul telah diaktifkan atau dinonaktifkan +Comment[is]=Slökkt eða kveikt hefur verið á skoppandi lyklum +Comment[it]=I tasti ravvicinati sono stati abilitati o disattivati +Comment[ja]=バウンスキーが有効または無効になりました +Comment[kk]=Қалшылға қарсы пернелер рұқсат етілді/етілмеді +Comment[km]=គ្រាប់​ចុច​លោត​​ត្រូវបាន​​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Comment[kn]=ಪುಟಿಯುವ (ಬೌನ್ಸ್) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Comment[ko]=튕김 키가 활성화되거나 비활성화됨 +Comment[ku]=Bişkojkên Zindî hatin çalakirin an jî neçalakirin +Comment[lt]=Tamprūs klavišai buvo įgalinti arba išjungti +Comment[lv]=Atlecošie taustiņi tika ieslēgti vai izslēgti +Comment[mk]=„Скокачки копчиња“ е овозможено или оневозможено +Comment[ml]=ബൌണ്‍സ് കീ പ്രവര്‍ത്തന സജ്ജം അല്ലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതം ആക്കിയിരിക്കുന്നു +Comment[mr]=बाउन्स् कि कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Comment[nb]=Filtertaster er blitt slått på eller av +Comment[nds]="Jumpen Tasten" wöör an- oder utmaakt +Comment[ne]=बाउन्स कुञ्जीहरू सक्षम वा अक्षम बनाइएको छ +Comment[nl]=Stuiterende toetsen is geactiveerd of gedeactiveerd +Comment[nn]=Filtertastar er no slått på eller av +Comment[or]=Bounce କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Comment[pa]=ਬਾਊਂਸ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Comment[pl]=Powolne klawisze zostały włączone lub wyłączone +Comment[pt]=As teclas sonoras foram activadas ou desactivadas +Comment[pt_BR]=As teclas de repercussão foram ativadas ou desativadas +Comment[ro]=Taste săltărețe (Bounce keys) au fost activate sau dezactivate +Comment[ru]=Включены или отключены «прыгающие» клавиши +Comment[se]=Sillenboallu lea rievdadan stáhtusa +Comment[si]=පොළාපැනුම් යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Comment[sk]=Bounce klávesy zmenili svoj stav +Comment[sl]=Odbijajoče tipke so bile omogočene ali onemogočene +Comment[sr]=Одскачући тастери су укључени или искључени +Comment[sr@ijekavian]=Одскачући тастери су укључени или искључени +Comment[sr@ijekavianlatin]=Odskačući tasteri su uključeni ili isključeni +Comment[sr@latin]=Odskačući tasteri su uključeni ili isključeni +Comment[sv]=Studsande tangenter har aktiverats eller inaktiverats +Comment[ta]=Bounce keys has been enabled or disabled +Comment[te]=బౌన్‍స్ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Comment[tg]=Тугмаҳои ҷаҳиш фаъол ё ғайрифаъол шудаанд +Comment[th]=การกดปุ่มพิมพ์รัวได้ถูกเปิดหรือปิดการทำงาน +Comment[tr]=Sıçrama tuşları etkinleştirildi ya da pasifleştirildi +Comment[ug]=سەكرىمە(Bounce) كۇنۇپكىلار ئىناۋەتلىك ياكى چەكلەنگەن +Comment[uk]=Було активовано або деактивовано пружні клавіші +Comment[vi]=Phím nảy đã được bật hoặc tắt +Comment[wa]=Des dimey-eclawåvès tapes ont stî metowes en alaejde oudonbén essoctêyes +Comment[x-test]=xxBounce keys has been enabled or disabledxx +Comment[zh_CN]=启用或禁用了撞击键 +Comment[zh_TW]=彈回鍵已啟動或關閉。 +Sound=KDE-Sys-Special.ogg +Action=PassivePopup +nopresentation=236 + +[Event/mousekeys] +Name=Mouse keys has been enabled or disabled +Name[af]=Muis sleutels was geaktiveer of gedeaktiveer +Name[ar]=تم تفعيل أو إلغاء تفعيل فأرة لوحة المفاتيح +Name[ast]=Tecles de mur activáronse o desactiváronse +Name[be@latin]=Klavišy kiravańnia kursoram źmianili svajo stanovišča +Name[bg]=Клавишите за управление на курсора са включени или изключени +Name[bs]=Miš‑tasteri su uključeni ili isključeni +Name[ca]=Les tecles del ratolí s'han activat o desactivat +Name[ca@valencia]=Les tecles del ratolí s'han activat o desactivat +Name[cs]=Klávesy myší byly povoleny nebo zakázány +Name[csb]=Knąpë mëszë òstałë aktiwòwòné abò deaktiwòwóné +Name[da]=Musetaster er aktiveret eller deaktiveret +Name[de]=Maustasten sind aktiviert oder deaktiviert worden +Name[el]=Τα πλήκτρα ποντικιού ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Name[en_GB]=Mouse keys has been enabled or disabled +Name[eo]=Musklavoj validiĝis aŭ malvalidiĝis +Name[es]=Se han activado o desactivado los botones del ratón +Name[et]=Hiire klahvid on keelatud või lubatud +Name[eu]=Saguaren botoiak gaitu edo desgaitu dira +Name[fi]=Hiirinäppäimet on otettu käyttöön tai poistettu käytöstä +Name[fr]=Les touches gérant la souris ont été activées ou désactivées +Name[fy]=Mûstoetsen binne aktivearre of ûntaktivearre +Name[ga]=Cumasaíodh nó díchumasaíodh eochracha luiche +Name[gl]=O control do rato co teclado activouse ou desactivouse +Name[gu]=માઉસ કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Name[he]=חיקוי כפתורי העכבר הופעל או הופסק +Name[hi]=माउस कुंजियों को सक्षम या अक्षम किया गया है +Name[hne]=मुसुवा कुंजी सच्छम या अच्छम हो गिस +Name[hr]=Mišolike tipke su omogućene ili onemogućene +Name[hsb]=Myšace tasty zaswěćene abo hasnjene +Name[hu]=Az egérmozgató billentyűk átkapcsolva +Name[ia]=Le claves de mus ha essite activate o disactivate +Name[id]=Tombol tetikus telah diaktifkan atau dinonaktifkan +Name[is]=Slökkt eða kveikt hefur verið á músarlyklum +Name[it]=Il mouse da tastiera è stato attivato o disattivato +Name[ja]=マウスキーが有効または無効になりました +Name[kk]=Тышқан пернелер рұқсат етілді/етілмеді +Name[km]=គ្រាប់​ចុច​កណ្ដុរ​ត្រូវ​បាន​​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Name[kn]=ಮೂಷಕ (ಮೌಸ್) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Name[ko]=마우스 키가 활성화되거나 비활성화됨 +Name[ku]=Bişkojkên Mişkî hatin çalakirin an jî neçalakirin +Name[lt]=Pelės klavišai buvo įgalinti arba išjungti +Name[lv]=Peles taustiņi tika ieslēgti vai izslēgti +Name[mk]=„Копчиња на глушецот“ е овозможено или оневозможено +Name[ml]=മൌസ് കീ പ്രവര്‍ത്തന സജ്ജം അല്ലെങ്കില്‍ പ്രവര്‍ത്തന രഹിതം ആക്കിയിരിക്കുന്നു +Name[mr]=माऊस कि कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Name[nb]=Musetaster er blitt slått på eller av +Name[nds]="Muustasten" wöör an- oder utmaakt +Name[ne]=माउस कुञ्जी सक्षम वा अक्षम बानइएको छ +Name[nl]=Muistoetsen is geactiveerd of gedeactiveerd +Name[nn]=Musetastar er no slått på eller av +Name[or]=ମାଉସ କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Name[pa]=ਮਾਊਸ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Name[pl]=Klawisze myszy zostały włączone lub wyłączone +Name[pt]=As teclas do rato foram activadas ou desactivadas +Name[pt_BR]=Teclas de mouse foram habilitadas ou desabilitadas +Name[ro]=Taste de maus au fost activate sau dezactivate +Name[ru]=Нажаты или отжаты клавиши мыши +Name[se]=Sáhppánboalut leat rievdadan stáhtusa +Name[si]=මවුස යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Name[sk]=Klávesy myši zmenili svoj stav +Name[sl]=Miškine tipke so bile omogočene ali onemogočene +Name[sr]=Миш‑тастери су укључени или искључени +Name[sr@ijekavian]=Миш‑тастери су укључени или искључени +Name[sr@ijekavianlatin]=Miš‑tasteri su uključeni ili isključeni +Name[sr@latin]=Miš‑tasteri su uključeni ili isključeni +Name[sv]=Mustangenter har aktiverats eller inaktiverats +Name[ta]=Mouse keys has been enabled or disabled +Name[te]=మౌస్ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Name[tg]=Тугмаҳои муш фаъол ё ғайрифаъол шудаанд +Name[th]=การจำลองเมาส์ด้วยแป้นพิมพ์ได้ถูกเปิดหรือปิดการทำงาน +Name[tr]=Fare tuşları etkinleştirildi ya da pasifleştirildi +Name[ug]=چاشقىنەك كۇنۇپكىلىرى ئىناۋەتلىك ياكى چەكلەنگەن +Name[uk]=Було активовано або деактивовано клавіші мишки +Name[wa]=Des tapes di soris ont stî metowe en alaedje oudonbén essoctêyes +Name[x-test]=xxMouse keys has been enabled or disabledxx +Name[zh_CN]=启用或禁用了鼠标键 +Name[zh_TW]=滑鼠鍵已改變狀態 +Comment=Mouse keys has been enabled or disabled +Comment[af]=Muis sleutels was geaktiveer of gedeaktiveer +Comment[ar]=تم تفعيل أو إلغاء تفعيل فأرة لوحة المفاتيح +Comment[ast]=Tecles de mur activáronse o desactiváronse +Comment[be@latin]=Klavišy kiravańnia kursoram źmianili svajo stanovišča +Comment[bg]=Клавишите за управление на курсора са включени или изключени +Comment[bs]=Miš‑tasteri su uključeni ili isključeni +Comment[ca]=Les tecles del ratolí s'han activat o desactivat +Comment[ca@valencia]=Les tecles del ratolí s'han activat o desactivat +Comment[cs]=Klávesy myší byly povoleny nebo zakázány +Comment[csb]=Knąpë mëszë òstałë aktiwòwòné abò deaktiwòwóné +Comment[da]=Musetaster er aktiveret eller deaktiveret +Comment[de]=Die Funktion „Maustasten“ ist aktiviert oder deaktiviert worden +Comment[el]=Τα πλήκτρα ποντικιού ενεργοποιήθηκαν ή απενεργοποιήθηκαν +Comment[en_GB]=Mouse keys has been enabled or disabled +Comment[eo]=Musklavoj validiĝis aŭ malvalidiĝis +Comment[es]=Se han activado o desactivado los botones del ratón +Comment[et]=Hiire klahvid on keelatud või lubatud +Comment[eu]=Saguaren botoiak gaitu edo desgaitu dira +Comment[fi]=Hiirinäppäimet on otettu käyttöön tai poistettu käytöstä +Comment[fr]=Les touches gérant la souris ont été activées ou désactivées +Comment[fy]=Mûstoetsen binne aktivearre of ûntaktivearre +Comment[ga]=Cumasaíodh nó díchumasaíodh eochracha luiche +Comment[gl]=O control do rato co teclado foi ou activado ou desactivado +Comment[gu]=માઉસ કળો સક્રિય અથવા નિષ્ક્રિય કરવામાં આવી છે +Comment[he]=חיקוי כפתורי העכבר הופעל או הופסק +Comment[hi]=माउस कुंजियों को सक्षम या अक्षम किया गया है +Comment[hne]=मुसुवा कुंजी सच्छम या अच्छम हो गिस +Comment[hr]=Mišolike tipke su omogućene ili onemogućene +Comment[hsb]=Myšace tasty zaswěćene abo hasnjene +Comment[hu]=Az egérmozgató billentyűk használatát ki- vagy bekapcsolták +Comment[ia]=Le claves de mus ha essite activate o disactivate +Comment[id]=Tombol tetikus telah diaktifkan atau dinonaktifkan +Comment[is]=Slökkt eða kveikt hefur verið á músarlyklum +Comment[it]=Il mouse da tastiera è stato attivato o disattivato +Comment[ja]=マウスキーが有効または無効になりました +Comment[kk]=Тышқан пернелер рұқсат етілді/етілмеді +Comment[km]=គ្រាប់​ចុច​កណ្ដុរ​ត្រូវ​បាន​​​អនុញ្ញាត ឬ​មិន​អនុញ្ញាត +Comment[kn]=ಮೂಷಕ (ಮೌಸ್) ಕೀಲಿಯನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ +Comment[ko]=마우스 키가 활성화되거나 비활성화됨 +Comment[ku]=Bişkojkên Mişkî hatin çalakirin an jî neçalakirin +Comment[lt]=Pelės mygtukai buvo įgalinti arba išjungti +Comment[lv]=Peles taustiņi tika ieslēgti vai izslēgti +Comment[mk]=„Копчиња на глушецот“ е овозможено или оневозможено +Comment[ml]=മൌസ് കീ പ്രവര്‍ത്തന സജ്ജം അല്ല്ലെങ്കില്‍ പ്രവര്‍ത്തനരഹിതം ആക്കിയിരിക്കുന്നു +Comment[mr]=माऊस कि कार्यान्वित किंवा अकार्यान्वित केली गेली आहे +Comment[nb]=Musetaster er blitt slått på eller av +Comment[nds]="Muustasten" wöör an- oder utmaakt +Comment[ne]=माउस कुञ्जी सक्षम वा अक्षम बनाइएको छ +Comment[nl]=Muistoetsen is geactiveerd of gedeactiveerd +Comment[nn]=Musetastar er no slått på eller av +Comment[or]=ମାଉସ କିଗୁଡ଼ିକୁ ସକ୍ରିୟ ଅଥବା ନିଷ୍କ୍ରିୟ କରାଯାଇଛି +Comment[pa]=ਮਾਊਸ ਸਵਿੱਚਾਂ ਯੋਗ ਜਾਂ ਆਯੋਗ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ +Comment[pl]=Klawisze myszy zostały włączone lub wyłączone +Comment[pt]=As teclas do rato foram activadas ou desactivadas +Comment[pt_BR]=Teclas de mouse foram habilitadas ou desabilitadas +Comment[ro]=Taste de maus au fost activate sau dezactivate +Comment[ru]=Нажаты или отжаты клавиши мыши +Comment[se]=Sáhppánboalut leat rievdadan stáhtusa +Comment[si]=මවුස යතුරු සක්‍රීය හෝ අක්‍රීය කර ඇත +Comment[sk]=Klávesy myši zmenili svoj stav +Comment[sl]=Miškine tipke so bile omogočene ali onemogočene +Comment[sr]=Миш‑тастери су укључени или искључени +Comment[sr@ijekavian]=Миш‑тастери су укључени или искључени +Comment[sr@ijekavianlatin]=Miš‑tasteri su uključeni ili isključeni +Comment[sr@latin]=Miš‑tasteri su uključeni ili isključeni +Comment[sv]=Mustangenter har aktiverats eller inaktiverats +Comment[ta]=Mouse keys has been enabled or disabled +Comment[te]=మౌస్ కీలు చేతనంకాబడినవి లేదా అచేతనంకాబడినవి +Comment[tg]=Тугмаҳои муш фаъол ё ғайрифаъол шудаанд +Comment[th]=การจำลองเมาส์ด้วยแป้นพิมพ์ได้ถูกเปิดหรือปิดการทำงาน +Comment[tr]=Fare tuşları etkinleştirildi ya da pasifleştirildi +Comment[ug]=چاشقىنەك كۇنۇپكىلىرى ئىناۋەتلىك ياكى چەكلەنگەن +Comment[uk]=Було активовано або деактивовано клавіші мишки +Comment[wa]=Des tapes di soris ont stî metowe en alaedje oudonbén essoctêyes +Comment[x-test]=xxMouse keys has been enabled or disabledxx +Comment[zh_CN]=启用或禁用了鼠标键 +Comment[zh_TW]=滑鼠鍵已啟動或關閉。 +Sound=KDE-Sys-Special.ogg +Action=PassivePopup +nopresentation=236 diff --git a/kcontrol/access/kcmaccess.cpp b/kcontrol/access/kcmaccess.cpp new file mode 100644 index 00000000..45e9d604 --- /dev/null +++ b/kcontrol/access/kcmaccess.cpp @@ -0,0 +1,783 @@ +/** + * kcmaccess.cpp + * + * Copyright (c) 2000 Matthias H�zer-Klpfel + * + */ + + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + +//Added by qt3to4: +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#define XK_MISCELLANY +#define XK_XKB_KEYS +#include +#include + +#include "kcmaccess.moc" + +K_PLUGIN_FACTORY(KAccessConfigFactory, registerPlugin();) +K_EXPORT_PLUGIN(KAccessConfigFactory("kcmaccess")) + +QString mouseKeysShortcut (Display *display) { + // Calculate the keycode + KeySym sym = XK_MouseKeys_Enable; + KeyCode code = XKeysymToKeycode(display, sym); + if (code == 0) { + sym = XK_Pointer_EnableKeys; + code = XKeysymToKeycode(display, sym); + if (code == 0) + return ""; // No shortcut available? + } + + // Calculate the modifiers by searching the keysym in the X keyboard mapping + XkbDescPtr xkbdesc = XkbGetMap(display, XkbKeyTypesMask | XkbKeySymsMask, XkbUseCoreKbd); + if (!xkbdesc) + return ""; // Failed to obtain the mapping from server + + bool found = false; + unsigned char modifiers = 0; + int groups = XkbKeyNumGroups(xkbdesc, code); + for (int grp = 0; grp < groups && !found; grp++) + { + int levels = XkbKeyGroupWidth(xkbdesc, code, grp); + for (int level = 0; level < levels && !found; level++) + { + if (sym == XkbKeySymEntry(xkbdesc, code, level, grp)) + { + // keysym found => determine modifiers + int typeIdx = xkbdesc->map->key_sym_map[code].kt_index[grp]; + XkbKeyTypePtr type = &(xkbdesc->map->types[typeIdx]); + for (int i = 0; i < type->map_count && !found; i++) + { + if (type->map[i].active && (type->map[i].level == level)) + { + modifiers = type->map[i].mods.mask; + found = true; + } + } + } + } + } + XkbFreeClientMap (xkbdesc, 0, true); + + if (!found) + return ""; // Somehow the keycode -> keysym mapping is flawed + + XEvent ev; + ev.type = KeyPress; + ev.xkey.display = display; + ev.xkey.keycode = code; + ev.xkey.state = 0; + int key; + KKeyServer::xEventToQt(&ev, &key); + QString keyname = QKeySequence(key).toString(); + + unsigned int AltMask = KKeyServer::modXAlt(); + unsigned int WinMask = KKeyServer::modXMeta(); + unsigned int NumMask = KKeyServer::modXNumLock(); + unsigned int ScrollMask= KKeyServer::modXScrollLock(); + + unsigned int MetaMask = XkbKeysymToModifiers (display, XK_Meta_L); + unsigned int SuperMask = XkbKeysymToModifiers (display, XK_Super_L); + unsigned int HyperMask = XkbKeysymToModifiers (display, XK_Hyper_L); + unsigned int AltGrMask = XkbKeysymToModifiers (display, XK_Mode_switch) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Shift) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Latch) + | XkbKeysymToModifiers (display, XK_ISO_Level3_Lock); + + unsigned int mods = ShiftMask | ControlMask | AltMask | WinMask + | LockMask | NumMask | ScrollMask; + + AltGrMask &= ~mods; + MetaMask &= ~(mods | AltGrMask); + SuperMask &= ~(mods | AltGrMask | MetaMask); + HyperMask &= ~(mods | AltGrMask | MetaMask | SuperMask); + + if ((modifiers & AltGrMask) != 0) + keyname = i18n("AltGraph") + '+' + keyname; + if ((modifiers & HyperMask) != 0) + keyname = i18n("Hyper") + '+' + keyname; + if ((modifiers & SuperMask) != 0) + keyname = i18n("Super") + '+' + keyname; + if ((modifiers & WinMask) != 0) + keyname = QKeySequence(Qt::META).toString() + '+' + keyname; + if ((modifiers & AltMask) != 0) + keyname = QKeySequence(Qt::ALT).toString() + '+' + keyname; + if ((modifiers & ControlMask) != 0) + keyname = QKeySequence(Qt::CTRL).toString() + '+' + keyname; + if ((modifiers & ShiftMask) != 0) + keyname = QKeySequence(Qt::SHIFT).toString() + '+' + keyname; + + QString result; + if ((modifiers & ScrollMask) != 0) + if ((modifiers & LockMask) != 0) + if ((modifiers & NumMask) != 0) + result = i18n("Press %1 while NumLock, CapsLock and ScrollLock are active", keyname); + else + result = i18n("Press %1 while CapsLock and ScrollLock are active", keyname); + else if ((modifiers & NumMask) != 0) + result = i18n("Press %1 while NumLock and ScrollLock are active", keyname); + else + result = i18n("Press %1 while ScrollLock is active", keyname); + else if ((modifiers & LockMask) != 0) + if ((modifiers & NumMask) != 0) + result = i18n("Press %1 while NumLock and CapsLock are active", keyname); + else + result = i18n("Press %1 while CapsLock is active", keyname); + else if ((modifiers & NumMask) != 0) + result = i18n("Press %1 while NumLock is active", keyname); + else + result = i18n("Press %1", keyname); + + return result; +} + +KAccessConfig::KAccessConfig(QWidget *parent, const QVariantList& args) + : KCModule(KAccessConfigFactory::componentData(), parent, args) +{ + + KAboutData *about = + new KAboutData(I18N_NOOP("kaccess"), 0, ki18n("KDE Accessibility Tool"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 2000, Matthias Hoelzer-Kluepfel")); + + about->addAuthor(ki18n("Matthias Hoelzer-Kluepfel"), ki18n("Author") , "hoelzer@kde.org"); + + setAboutData( about ); + + QVBoxLayout *main = new QVBoxLayout(this); + main->setMargin(0); + QTabWidget *tab = new QTabWidget(this); + main->addWidget(tab); + + // bell settings --------------------------------------- + QWidget *bell = new QWidget(this); + + QVBoxLayout *vbox = new QVBoxLayout(bell); + + QGroupBox *grp = new QGroupBox(i18n("Audible Bell"), bell); + QHBoxLayout *layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + QVBoxLayout *vvbox = new QVBoxLayout(); + layout->addLayout( vvbox ); + + systemBell = new QCheckBox(i18n("Use &system bell"), grp); + vvbox->addWidget(systemBell); + customBell = new QCheckBox(i18n("Us&e customized bell"), grp); + vvbox->addWidget(customBell); + systemBell->setWhatsThis( i18n("If this option is checked, the default system bell will be used. See the" + " \"System Bell\" control module for how to customize the system bell." + " Normally, this is just a \"beep\".") ); + customBell->setWhatsThis( i18n("

    Check this option if you want to use a customized bell, playing" + " a sound file. If you do this, you will probably want to turn off the system bell.

    Please note" + " that on slow machines this may cause a \"lag\" between the event causing the bell and the sound being played.

    ") ); + + QHBoxLayout *hbox = new QHBoxLayout(); + vvbox->addLayout( hbox ); + hbox->addSpacing(24); + soundEdit = new QLineEdit(grp); + soundLabel = new QLabel(i18n("Sound &to play:"), grp); + soundLabel->setBuddy(soundEdit); + hbox->addWidget(soundLabel); + hbox->addWidget(soundEdit); + soundButton = new QPushButton(i18n("Browse..."), grp); + hbox->addWidget(soundButton); + QString wtstr = i18n("If the option \"Use customized bell\" is enabled, you can choose a sound file here." + " Click \"Browse...\" to choose a sound file using the file dialog."); + soundEdit->setWhatsThis( wtstr ); + soundLabel->setWhatsThis( wtstr ); + soundButton->setWhatsThis( wtstr ); + + connect(soundButton, SIGNAL(clicked()), this, SLOT(selectSound())); + + connect(customBell, SIGNAL(clicked()), this, SLOT(checkAccess())); + + connect(systemBell, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(customBell, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(soundEdit, SIGNAL(textChanged(QString)), this, SLOT(configChanged())); + + // ----------------------------------------------------- + + // visible bell ---------------------------------------- + grp = new QGroupBox(i18n("Visible Bell"), bell); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout( vvbox ); + + visibleBell = new QCheckBox(i18n("&Use visible bell"), grp); + vvbox->addWidget(visibleBell); + visibleBell->setWhatsThis( i18n("This option will turn on the \"visible bell\", i.e. a visible" + " notification shown every time that normally just a bell would occur. This is especially useful" + " for deaf people.") ); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + invertScreen = new QRadioButton(i18n("I&nvert screen"), grp); + hbox->addWidget(invertScreen); + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + invertScreen->setWhatsThis( i18n("All screen colors will be inverted for the amount of time specified below.") ); + hbox->addSpacing(24); + flashScreen = new QRadioButton(i18n("F&lash screen"), grp); + hbox->addWidget(flashScreen); + flashScreen->setWhatsThis( i18n("The screen will turn to a custom color for the amount of time specified below.") ); + hbox->addSpacing(12); + colorButton = new KColorButton(grp); + colorButton->setFixedWidth(colorButton->sizeHint().height()*2); + hbox->addWidget(colorButton); + hbox->addStretch(); + colorButton->setWhatsThis( i18n("Click here to choose the color used for the \"flash screen\" visible bell.") ); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + + durationSlider = new KDoubleNumInput(grp); + durationSlider->setRange(100, 2000, 100); + durationSlider->setExponentRatio(2); + durationSlider->setDecimals(0); + durationSlider->setLabel(i18n("Duration:")); + durationSlider->setSuffix(i18n(" msec")); + hbox->addWidget(durationSlider); + durationSlider->setWhatsThis( i18n("Here you can customize the duration of the \"visible bell\" effect being shown.") ); + + connect(invertScreen, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(flashScreen, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(visibleBell, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(visibleBell, SIGNAL(clicked()), this, SLOT(checkAccess())); + connect(colorButton, SIGNAL(clicked()), this, SLOT(changeFlashScreenColor())); + + connect(invertScreen, SIGNAL(clicked()), this, SLOT(invertClicked())); + connect(flashScreen, SIGNAL(clicked()), this, SLOT(flashClicked())); + + connect(durationSlider, SIGNAL(valueChanged(double)), this, SLOT(configChanged())); + + vbox->addStretch(); + + // ----------------------------------------------------- + + tab->addTab(bell, i18n("&Bell")); + + + // modifier key settings ------------------------------- + QWidget *modifiers = new QWidget(this); + + vbox = new QVBoxLayout(modifiers); + + grp = new QGroupBox(i18n("S&ticky Keys"), modifiers); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout(vvbox); + + stickyKeys = new QCheckBox(i18n("Use &sticky keys"), grp); + vvbox->addWidget(stickyKeys); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + stickyKeysLock = new QCheckBox(i18n("&Lock sticky keys"), grp); + hbox->addWidget(stickyKeysLock); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + stickyKeysAutoOff = new QCheckBox(i18n("Turn sticky keys off when two keys are pressed simultaneously"), grp); + hbox->addWidget(stickyKeysAutoOff); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + stickyKeysBeep = new QCheckBox(i18n("Use system bell whenever a modifier gets latched, locked or unlocked"), grp); + hbox->addWidget(stickyKeysBeep); + + grp = new QGroupBox(i18n("Locking Keys"), modifiers); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout(vvbox); + + toggleKeysBeep = new QCheckBox(i18n("Use system bell whenever a locking key gets activated or deactivated"), grp); + vvbox->addWidget(toggleKeysBeep); + + kNotifyModifiers = new QCheckBox(i18n("Use KDE's system notification mechanism whenever a modifier or locking key changes its state"), grp); + vvbox->addWidget(kNotifyModifiers); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addStretch(1); + kNotifyModifiersButton = new QPushButton(i18n("Configure &Notifications..."), grp); + kNotifyModifiersButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + hbox->addWidget(kNotifyModifiersButton); + + connect(stickyKeys, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(stickyKeysLock, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(stickyKeysAutoOff, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(stickyKeys, SIGNAL(clicked()), this, SLOT(checkAccess())); + + connect(stickyKeysBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(toggleKeysBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(kNotifyModifiers, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(kNotifyModifiers, SIGNAL(clicked()), this, SLOT(checkAccess())); + connect(kNotifyModifiersButton, SIGNAL(clicked()), this, SLOT(configureKNotify())); + + vbox->addStretch(); + + tab->addTab(modifiers, i18n("&Modifier Keys")); + + // key filter settings --------------------------------- + QWidget *filters = new QWidget(this); + + vbox = new QVBoxLayout(filters); + grp = new QGroupBox(i18n("Slo&w Keys"), filters); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout(vvbox); + + slowKeys = new QCheckBox(i18n("&Use slow keys"), grp); + vvbox->addWidget(slowKeys); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + slowKeysDelay = new KDoubleNumInput(grp); + slowKeysDelay->setRange(50, 10000, 100); + slowKeysDelay->setExponentRatio(2); + slowKeysDelay->setDecimals(0); + slowKeysDelay->setSuffix(i18n(" msec")); + slowKeysDelay->setLabel(i18n("Acceptance dela&y:"), Qt::AlignVCenter|Qt::AlignLeft); + hbox->addWidget(slowKeysDelay); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + slowKeysPressBeep = new QCheckBox(i18n("&Use system bell whenever a key is pressed"), grp); + hbox->addWidget(slowKeysPressBeep); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + slowKeysAcceptBeep = new QCheckBox(i18n("&Use system bell whenever a key is accepted"), grp); + hbox->addWidget(slowKeysAcceptBeep); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + slowKeysRejectBeep = new QCheckBox(i18n("&Use system bell whenever a key is rejected"), grp); + hbox->addWidget(slowKeysRejectBeep); + + grp = new QGroupBox(i18n("Bounce Keys"), filters); + layout= new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout( vvbox ); + + bounceKeys = new QCheckBox(i18n("Use bou&nce keys"), grp); + vvbox->addWidget(bounceKeys); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + bounceKeysDelay = new KDoubleNumInput(grp); + bounceKeysDelay->setRange(100, 5000, 100); + bounceKeysDelay->setExponentRatio(2); + bounceKeysDelay->setDecimals(0); + bounceKeysDelay->setSuffix(i18n(" msec")); + bounceKeysDelay->setLabel(i18n("D&ebounce time:"), Qt::AlignVCenter|Qt::AlignLeft);; + hbox->addWidget(bounceKeysDelay); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + bounceKeysRejectBeep = new QCheckBox(i18n("Use the system bell whenever a key is rejected"), grp); + hbox->addWidget(bounceKeysRejectBeep); + + connect(slowKeysDelay, SIGNAL(valueChanged(double)), this, SLOT(configChanged())); + connect(slowKeys, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(slowKeys, SIGNAL(clicked()), this, SLOT(checkAccess())); + + connect(slowKeysPressBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(slowKeysAcceptBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(slowKeysRejectBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + + connect(bounceKeysDelay, SIGNAL(valueChanged(double)), this, SLOT(configChanged())); + connect(bounceKeys, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(bounceKeysRejectBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(bounceKeys, SIGNAL(clicked()), this, SLOT(checkAccess())); + + vbox->addStretch(); + + tab->addTab(filters, i18n("&Keyboard Filters")); + + // gestures -------------------------------------------- + QWidget *features = new QWidget(this); + + vbox = new QVBoxLayout(features); + + grp = new QGroupBox(i18n("Activation Gestures"), features); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout( vvbox ); + + gestures = new QCheckBox(i18n("Use gestures for activating sticky keys and slow keys"), grp); + vvbox->addWidget(gestures); + QString shortcut = mouseKeysShortcut(x11Info().display()); + if (shortcut.isEmpty()) + gestures->setWhatsThis( i18n("Here you can activate keyboard gestures that turn on the following features: \n" + "Sticky keys: Press Shift key 5 consecutive times\n" + "Slow keys: Hold down Shift for 8 seconds")); + else + gestures->setWhatsThis( i18n("Here you can activate keyboard gestures that turn on the following features: \n" + "Mouse Keys: %1\n" + "Sticky keys: Press Shift key 5 consecutive times\n" + "Slow keys: Hold down Shift for 8 seconds", shortcut)); + + timeout = new QCheckBox(i18n("Turn sticky keys and slow keys off after a certain period of inactivity."), grp); + vvbox->addWidget(timeout); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addSpacing(24); + timeoutDelay = new KIntNumInput(grp); + timeoutDelay->setSuffix(i18n(" min")); + timeoutDelay->setRange(1, 30, 4); + timeoutDelay->setLabel(i18n("Timeout:"), Qt::AlignVCenter|Qt::AlignLeft);; + hbox->addWidget(timeoutDelay); + + grp = new QGroupBox(i18n("Notification"), features); + layout = new QHBoxLayout; + grp->setLayout(layout); + vbox->addWidget(grp); + + vvbox = new QVBoxLayout(); + layout->addLayout(vvbox); + + accessxBeep = new QCheckBox(i18n("Use the system bell whenever a gesture is used to turn an accessibility feature on or off"), grp); + vvbox->addWidget(accessxBeep); + + gestureConfirmation = new QCheckBox(i18n("Show a confirmation dialog whenever a keyboard accessibility feature is turned on or off"), grp); + vvbox->addWidget(gestureConfirmation); + gestureConfirmation->setWhatsThis( i18n("If this option is checked, KDE will show a confirmation dialog whenever a keyboard accessibility feature is turned on or off.\nEnsure you know what you are doing if you uncheck it, as the keyboard accessibility settings will then always be applied without confirmation.") ); + + kNotifyAccessX = new QCheckBox(i18n("Use KDE's system notification mechanism whenever a keyboard accessibility feature is turned on or off"), grp); + vvbox->addWidget(kNotifyAccessX); + + hbox = new QHBoxLayout(); + vvbox->addLayout(hbox); + hbox->addStretch(1); + kNotifyAccessXButton = new QPushButton(i18n("Configure &Notifications..."), grp); + kNotifyAccessXButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + hbox->addWidget(kNotifyAccessXButton); + + connect(gestures, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(timeout, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(timeout, SIGNAL(clicked()), this, SLOT(checkAccess())); + connect(timeoutDelay, SIGNAL(valueChanged(int)), this, SLOT(configChanged())); + connect(accessxBeep, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(gestureConfirmation, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(kNotifyAccessX, SIGNAL(clicked()), this, SLOT(configChanged())); + connect(kNotifyAccessX, SIGNAL(clicked()), this, SLOT(checkAccess())); + connect(kNotifyAccessXButton, SIGNAL(clicked()), this, SLOT(configureKNotify())); + + vbox->addStretch(); + + tab->addTab(features, i18n("Activation Gestures")); +} + + +KAccessConfig::~KAccessConfig() +{ +} + +void KAccessConfig::configureKNotify() +{ + KNotifyConfigWidget::configure (this, "kaccess"); +} + +void KAccessConfig::changeFlashScreenColor() +{ + invertScreen->setChecked(false); + flashScreen->setChecked(true); + configChanged(); +} + +void KAccessConfig::selectSound() +{ + QStringList list = KGlobal::dirs()->findDirs("sound", ""); + QString start; + if (list.count()>0) + start = list[0]; + // TODO: Why only wav's? How can I find out what artsd supports? + QString fname = KFileDialog::getOpenFileName(start, i18n("*.wav|WAV Files")); + if (!fname.isEmpty()) + soundEdit->setText(fname); +} + + +void KAccessConfig::configChanged() +{ + emit changed(true); +} + + +void KAccessConfig::load() +{ + KConfigGroup cg(KSharedConfig::openConfig("kaccessrc"), "Bell"); + + systemBell->setChecked(cg.readEntry("SystemBell", true)); + customBell->setChecked(cg.readEntry("ArtsBell", false)); + soundEdit->setText(cg.readPathEntry("ArtsBellFile", QString())); + + visibleBell->setChecked(cg.readEntry("VisibleBell", false)); + invertScreen->setChecked(cg.readEntry("VisibleBellInvert", true)); + flashScreen->setChecked(!invertScreen->isChecked()); + colorButton->setColor(cg.readEntry("VisibleBellColor", QColor(Qt::red))); + + durationSlider->setValue(cg.readEntry("VisibleBellPause", 500)); + + KConfigGroup keyboardGroup(KSharedConfig::openConfig("kaccessrc"),"Keyboard"); + + stickyKeys->setChecked(keyboardGroup.readEntry("StickyKeys", false)); + stickyKeysLock->setChecked(keyboardGroup.readEntry("StickyKeysLatch", true)); + stickyKeysAutoOff->setChecked(keyboardGroup.readEntry("StickyKeysAutoOff", false)); + stickyKeysBeep->setChecked(keyboardGroup.readEntry("StickyKeysBeep", true)); + toggleKeysBeep->setChecked(keyboardGroup.readEntry("ToggleKeysBeep", false)); + kNotifyModifiers->setChecked(keyboardGroup.readEntry("kNotifyModifiers", false)); + + slowKeys->setChecked(keyboardGroup.readEntry("SlowKeys", false)); + slowKeysDelay->setValue(keyboardGroup.readEntry("SlowKeysDelay", 500)); + slowKeysPressBeep->setChecked(keyboardGroup.readEntry("SlowKeysPressBeep", true)); + slowKeysAcceptBeep->setChecked(keyboardGroup.readEntry("SlowKeysAcceptBeep", true)); + slowKeysRejectBeep->setChecked(keyboardGroup.readEntry("SlowKeysRejectBeep", true)); + + bounceKeys->setChecked(keyboardGroup.readEntry("BounceKeys", false)); + bounceKeysDelay->setValue(keyboardGroup.readEntry("BounceKeysDelay", 500)); + bounceKeysRejectBeep->setChecked(keyboardGroup.readEntry("BounceKeysRejectBeep", true)); + + gestures->setChecked(keyboardGroup.readEntry("Gestures", false)); + timeout->setChecked(keyboardGroup.readEntry("AccessXTimeout", false)); + timeoutDelay->setValue(keyboardGroup.readEntry("AccessXTimeoutDelay", 30)); + + accessxBeep->setChecked(keyboardGroup.readEntry("AccessXBeep", true)); + gestureConfirmation->setChecked(keyboardGroup.readEntry("GestureConfirmation", false)); + kNotifyAccessX->setChecked(keyboardGroup.readEntry("kNotifyAccessX", false)); + + checkAccess(); + + emit changed(false); +} + + +void KAccessConfig::save() +{ + KConfigGroup cg(KSharedConfig::openConfig("kaccessrc"), "Bell"); + + cg.writeEntry("SystemBell", systemBell->isChecked()); + cg.writeEntry("ArtsBell", customBell->isChecked()); + cg.writePathEntry("ArtsBellFile", soundEdit->text()); + + cg.writeEntry("VisibleBell", visibleBell->isChecked()); + cg.writeEntry("VisibleBellInvert", invertScreen->isChecked()); + cg.writeEntry("VisibleBellColor", colorButton->color()); + + cg.writeEntry("VisibleBellPause", durationSlider->value()); + + KConfigGroup keyboardGroup(KSharedConfig::openConfig("kaccessrc"),"Keyboard"); + + keyboardGroup.writeEntry("StickyKeys", stickyKeys->isChecked()); + keyboardGroup.writeEntry("StickyKeysLatch", stickyKeysLock->isChecked()); + keyboardGroup.writeEntry("StickyKeysAutoOff", stickyKeysAutoOff->isChecked()); + keyboardGroup.writeEntry("StickyKeysBeep", stickyKeysBeep->isChecked()); + keyboardGroup.writeEntry("ToggleKeysBeep", toggleKeysBeep->isChecked()); + keyboardGroup.writeEntry("kNotifyModifiers", kNotifyModifiers->isChecked()); + + keyboardGroup.writeEntry("SlowKeys", slowKeys->isChecked()); + keyboardGroup.writeEntry("SlowKeysDelay", slowKeysDelay->value()); + keyboardGroup.writeEntry("SlowKeysPressBeep", slowKeysPressBeep->isChecked()); + keyboardGroup.writeEntry("SlowKeysAcceptBeep", slowKeysAcceptBeep->isChecked()); + keyboardGroup.writeEntry("SlowKeysRejectBeep", slowKeysRejectBeep->isChecked()); + + + keyboardGroup.writeEntry("BounceKeys", bounceKeys->isChecked()); + keyboardGroup.writeEntry("BounceKeysDelay", bounceKeysDelay->value()); + keyboardGroup.writeEntry("BounceKeysRejectBeep", bounceKeysRejectBeep->isChecked()); + + keyboardGroup.writeEntry("Gestures", gestures->isChecked()); + keyboardGroup.writeEntry("AccessXTimeout", timeout->isChecked()); + keyboardGroup.writeEntry("AccessXTimeoutDelay", timeoutDelay->value()); + + keyboardGroup.writeEntry("AccessXBeep", accessxBeep->isChecked()); + keyboardGroup.writeEntry("GestureConfirmation", gestureConfirmation->isChecked()); + keyboardGroup.writeEntry("kNotifyAccessX", kNotifyAccessX->isChecked()); + + + cg.sync(); + keyboardGroup.sync(); + + if (systemBell->isChecked() || + customBell->isChecked() || + visibleBell->isChecked()) + { + KConfig _cfg("kdeglobals", KConfig::NoGlobals); + KConfigGroup cfg(&_cfg, "General"); + cfg.writeEntry("UseSystemBell", true); + cfg.sync(); + } + + // make kaccess reread the configuration + // turning a11y features off needs to be done by kaccess + // so run it to clear any enabled features and it will exit if it should + KToolInvocation::startServiceByDesktopName("kaccess"); + + emit changed(false); +} + + +void KAccessConfig::defaults() +{ + systemBell->setChecked(true); + customBell->setChecked(false); + soundEdit->setText(""); + + visibleBell->setChecked(false); + invertScreen->setChecked(true); + flashScreen->setChecked(false); + colorButton->setColor(QColor(Qt::red)); + + durationSlider->setValue(500); + + slowKeys->setChecked(false); + slowKeysDelay->setValue(500); + slowKeysPressBeep->setChecked(true); + slowKeysAcceptBeep->setChecked(true); + slowKeysRejectBeep->setChecked(true); + + bounceKeys->setChecked(false); + bounceKeysDelay->setValue(500); + bounceKeysRejectBeep->setChecked(true); + + stickyKeys->setChecked(false); + stickyKeysLock->setChecked(true); + stickyKeysAutoOff->setChecked(false); + stickyKeysBeep->setChecked(true); + toggleKeysBeep->setChecked(false); + kNotifyModifiers->setChecked(false); + + gestures->setChecked(false); + timeout->setChecked(false); + timeoutDelay->setValue(30); + + accessxBeep->setChecked(true); + gestureConfirmation->setChecked(true); + kNotifyAccessX->setChecked(false); + + checkAccess(); + + emit changed(true); +} + + +void KAccessConfig::invertClicked() +{ + flashScreen->setChecked(false); +} + + +void KAccessConfig::flashClicked() +{ + invertScreen->setChecked(false); +} + + +void KAccessConfig::checkAccess() +{ + bool custom = customBell->isChecked(); + soundEdit->setEnabled(custom); + soundButton->setEnabled(custom); + soundLabel->setEnabled(custom); + + bool visible = visibleBell->isChecked(); + invertScreen->setEnabled(visible); + flashScreen->setEnabled(visible); + colorButton->setEnabled(visible); + durationSlider->setEnabled(visible); + + bool sticky = stickyKeys->isChecked(); + stickyKeysLock->setEnabled(sticky); + stickyKeysAutoOff->setEnabled(sticky); + stickyKeysBeep->setEnabled(sticky); + + bool slow = slowKeys->isChecked(); + slowKeysDelay->setEnabled(slow); + slowKeysPressBeep->setEnabled(slow); + slowKeysAcceptBeep->setEnabled(slow); + slowKeysRejectBeep->setEnabled(slow); + + bool bounce = bounceKeys->isChecked(); + bounceKeysDelay->setEnabled(bounce); + bounceKeysRejectBeep->setEnabled(bounce); + + bool useTimeout = timeout->isChecked(); + timeoutDelay->setEnabled(useTimeout); +} + +extern "C" +{ + /* This one gets called by kcminit + + */ + KDE_EXPORT void kcminit_access() + { + KConfig config("kaccessrc", KConfig::NoGlobals); + KToolInvocation::startServiceByDesktopName("kaccess"); + } +} + + diff --git a/kcontrol/access/kcmaccess.desktop b/kcontrol/access/kcmaccess.desktop new file mode 100644 index 00000000..936d3e2a --- /dev/null +++ b/kcontrol/access/kcmaccess.desktop @@ -0,0 +1,237 @@ +[Desktop Entry] +Exec=kcmshell4 kcmaccess +Icon=preferences-desktop-accessibility +Type=Service +X-KDE-ServiceTypes=KCModule,KCModuleInit +X-DocPath=kcontrol/kcmaccess/index.html + +X-KDE-Library=kcm_access +X-KDE-Init-Symbol=kcminit_access +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=accessibility + +Name=Accessibility +Name[af]=Toeganklikheid +Name[ar]=الإتاحة +Name[as]=অভিগম্যতা +Name[ast]=Accesibilidá +Name[be]=Даступнасць +Name[be@latin]=Dastupnaść +Name[bg]=Равностоен достъп +Name[bn]=সহায়ক প্রযুক্তি +Name[bn_IN]=বিশেষ ব্যবহারের সহায়তা +Name[br]=Haezadusted +Name[bs]=Pristupačnost +Name[ca]=Accessibilitat +Name[ca@valencia]=Accessibilitat +Name[cs]=Zpřístupnění +Name[csb]=Pòmòce przëstãpù +Name[cy]=Hygyrchedd +Name[da]=Tilgængelighed +Name[de]=Zugangshilfen +Name[el]=Προσιτότητα +Name[en_GB]=Accessibility +Name[eo]=Alirebleco +Name[es]=Accesibilidad +Name[et]=Hõlbustus +Name[eu]=Erabilerraztasuna +Name[fa]=دستیابی‌پذیری +Name[fi]=Esteettömyys +Name[fr]=Accessibilité +Name[fy]=Tagonklikens +Name[ga]=Inrochtaineacht +Name[gl]=Accesibilidade +Name[gu]=ઉપયોગિતા +Name[he]=נגישות +Name[hi]=पहुँच +Name[hne]=पहुंच +Name[hr]=Pristupačnost +Name[hsb]=Přistupnosć +Name[hu]=Kezelési segítség +Name[ia]=Accessibilitate +Name[id]=Aksesibilitas +Name[is]=Aðgengi +Name[it]=Accessibilità +Name[ja]=アクセシビリティ +Name[ka]=სპეციალური შესაძლბლობები +Name[kk]=Арнайы мүмкіндіктер +Name[km]=មធ្យោបាយ​ងាយស្រួល +Name[kn]=ನಿಲುಕಣೆ (ಆಕ್ಸೆಸಿಬಿಲಿಟಿ) +Name[ko]=내게 필요한 설정 +Name[ku]=Gihîştin +Name[lt]=Pritaikymas neįgaliesiems +Name[lv]=Pieejamība +Name[mai]=अभिगम्यता +Name[mk]=Пристапливост +Name[ml]=സാമീപ്യത +Name[mr]=सुलभता +Name[ms]=Kebolehcapaian +Name[nb]=Tilgjengelighet +Name[nds]=Toganghülp +Name[ne]=पहुँचता +Name[nl]=Toegankelijkheid +Name[nn]=Tilgjenge +Name[oc]=Accessibilitat +Name[or]=ଅଭିଗମ୍ୟତା +Name[pa]=ਸਹੂਲਤਾਂ +Name[pl]=Ułatwienia dostępu +Name[pt]=Acessibilidade +Name[pt_BR]=Acessibilidade +Name[ro]=Accesibilitate +Name[ru]=Специальные возможности +Name[se]=Álkkibut geavaheapmi +Name[si]=ප්‍රවේශණය +Name[sk]=Prístupnosť +Name[sl]=Dostopnost +Name[sr]=Приступачност +Name[sr@ijekavian]=Приступачност +Name[sr@ijekavianlatin]=Pristupačnost +Name[sr@latin]=Pristupačnost +Name[sv]=Handikappstöd +Name[ta]=அணுகல் +Name[te]=అందుబాటు +Name[tg]=Имкониятҳо +Name[th]=ช่วยการใช้งาน +Name[tr]=Erişilebilirlik +Name[ug]=قوشۇمچە ئىقتىدار +Name[uk]=Доступність +Name[uz]=Qulayliklar +Name[uz@cyrillic]=Қулайликлар +Name[vi]=Hỗ trợ truy cập +Name[wa]=Accessibilité +Name[xh]=Unikezelo +Name[x-test]=xxAccessibilityxx +Name[zh_CN]=辅助 +Name[zh_TW]=無障礙輔助 + +Comment=Improve accessibility for disabled persons +Comment[af]=Verbeter toeganklikheid vir gestremde persone +Comment[ar]=تحسين إمكانية الوصول للمعوقين +Comment[ast]=Ameyorar accesibilidá pa discapacitaos +Comment[be]=Павялічвае даступнасць для людзей з фізічнымі адхіленнямі +Comment[be@latin]=Palapšeńnie dastupnaści prahramaŭ dla invalidaŭ +Comment[bg]=Настройки на достъпа за хора с увреждания +Comment[bn]=অসমর্থ ব্যবহারকারীদের সহায়তা করার প্রযুক্তি +Comment[bs]=Poboljšava pristupačnost hendikepiranim osobama +Comment[ca]=Accessibilitat millorada per a persones discapacitades +Comment[ca@valencia]=Accessibilitat millorada per a persones discapacitades +Comment[cs]=Zlepšení přístupnosti pro osoby s postižením +Comment[csb]=Pòprôwionô przëstãpnosc dlô niefùlsprôwnëch lëdzi +Comment[cy]=Gwella hygyrchedd i bobl anabl +Comment[da]=Forbedr tilgængelighed for handicappede personer +Comment[de]=Verbesserte Benutzbarkeit für Menschen mit Behinderung +Comment[el]=Βελτίωση της προσιτότητας για άτομα με ειδικές ανάγκες +Comment[en_GB]=Improve accessibility for disabled persons +Comment[eo]=Plibonigita alirebleco por handikapitoj +Comment[es]=Mejorar accesibilidad para discapacitados +Comment[et]=Puuetega inimestele mõeldud seaded +Comment[eu]=Ezinduentzako erabilerraztasuna handitzen du +Comment[fa]=بهبود دستیابی‌پذیری برای اشخاص ناتوان +Comment[fi]=Esteettömyysasetukset +Comment[fy]=Ferbeterde tagonklikens foar brûkers mei in handikap +Comment[ga]=Feabhsaigh an inrochtaineacht do dhaoine míchumasaithe +Comment[gl]=Accesibilidade mellorada para persoas con discapacidades +Comment[gu]=અસક્ષમ વ્યક્તિઓ માટે ઉપયોગિતામાં સુધારો કરો +Comment[he]=שיפור הנגישות עבור אנשים עם מוגבלויות +Comment[hi]=विकलांग व्यक्तियों के लिए पहुँच बेहतर बनाए +Comment[hne]=विकलांग मनखे बर पहुंच बेहतर बनाए +Comment[hr]=Unaprijedite pristupačnost osobama s invaliditetom +Comment[hsb]=Přistupnosć za zbrašenych zlěpšić +Comment[hu]=A számítógép kezelését segítő eszközök fogyatékosoknak +Comment[ia]=Il meliora le accessibilitate pro personas invalide +Comment[id]=Tingkatkan aksesibilitas bagi orang cacat +Comment[is]=Endurbætt aðgengi fyrir þá sem þurfa +Comment[ka]=ფიზიკური ნაკლოვანებბის მქონი ხალხისთვის სპეციალური შესაძლბლობები +Comment[kk]=Мүмкіншіліктері шектеулі адамдарға көмек +Comment[km]=បង្កើន​មធ្យោបាយ​ងាយស្រួល​សម្រាប់​មនុស្ស​ពិការ +Comment[kn]=ದುರ್ಬಲೀನರಾದ ವ್ಯಕ್ತಿಗಳಿಗೆ ನಿಲುಕಣೆಯನ್ನು (ಅಕ್ಸೆಸಿಬಲಿಟಿ) ಸುಧಾರಿಸಿ +Comment[ko]=장애인들을 위하여 접근성을 향상시킵니다 +Comment[ku]=Ji bo kesên neçalak gihîştinê biguherîne +Comment[lt]=Pagerintas prieinamumas neįgaliems asmenims +Comment[lv]=Uzlabo pieejamību cilvēkiem ar īpašām vajadzībām +Comment[mai]=विकलांग लोकनिसभक लेल पहुँच बेहतर बनाएल जाए +Comment[mk]=Ја подобрува пристапливоста за хендикепирани лица +Comment[ml]=അംഗവൈകല്യമുള്ളവര്‍ക്കുള്ള സാമീപ്യത നന്നാക്കുക +Comment[mr]=विकलांग व्यक्तिं करिता सुधारित सुलभता +Comment[ms]=Tingkatkan keaksesan bagi orang kurang upaya +Comment[nb]=Forbedre tilgjengelighet for funksjonshemmede +Comment[nds]=Verbetert den Togang för behinnert Lüüd +Comment[ne]=अक्षम व्यक्तिका लागि पहुँच क्षमता सुधार गर्नुहोस् +Comment[nl]=Verbeterde toegankelijkheid voor gebruikers met een handicap +Comment[nn]=Forbetra tilgjenge for funksjonshemma personar +Comment[or]=ନିଷ୍କ୍ରିୟ ବ୍ୟକ୍ତିମାନଙ୍କ ପାଇଁ ଅଭିଗମ୍ୟତା ଉନ୍ନତ କରନ୍ତୁ +Comment[pa]=ਅਪੰਗ ਵਿਅਕਤੀ ਲਈ ਸੁਧਾਰੀਆਂ ਸਹੂਲਤਾਂ +Comment[pl]=Poprawiona dostępność dla osób niepełnosprawnych +Comment[pt]=Acessibilidade melhorada para pessoas com necessidades especiais +Comment[pt_BR]=Melhora a acessibilidade para pessoas com deficiência +Comment[ro]=Îmbunătățește accesibilitate KDE pentru persoanele cu handicap +Comment[ru]=Специальные возможности для людей с физическими ограничениями +Comment[se]=Álkkibut geavaheapmi doaimmahehttejuvvon olbmuide +Comment[si]=අබාධිත අයෙකුට පහසුවෙන් පිවිසීමට ඉඩදෙයි +Comment[sk]=Zlepšenie prístupnosti pre postihnutých užívateľov +Comment[sl]=Izboljšana dostopnost za prizadete osebe +Comment[sr]=Побољшава приступачност хендикепираним особама +Comment[sr@ijekavian]=Побољшава приступачност хендикепираним особама +Comment[sr@ijekavianlatin]=Poboljšava pristupačnost hendikepiranim osobama +Comment[sr@latin]=Poboljšava pristupačnost hendikepiranim osobama +Comment[sv]=Förbättrad tillgänglighet för handikappade personer +Comment[ta]=பார்க்க முடியாதவர்களுக்கு அணுகலை அதிகப்படுத்தவும் +Comment[te]=వికలాంగులైన వ్యక్తులకు అందుబాటును మెరుగుపరుచుము +Comment[tg]=Специальные возможности для людей с физическими недостатками +Comment[th]=ช่วยให้ผู้พิการหรือผู้บกพร่องทางร่างกายด้านอื่นๆ สามารถใช้งานได้สะดวกสบายมากขึ้น +Comment[tr]=Görme sorunu olanlar için erişilebilirlik seçenekleri +Comment[ug]=مېيىپلەر ئۈچۈن ئىشلىتىلىدىغان ياردەمچى ئىقتىدارلار +Comment[uk]=Підвищення зручності для інвалідів +Comment[uz]=Nogiron kishilar uchun qulayliklar +Comment[uz@cyrillic]=Ногирон кишилар учун қулайликлар +Comment[vi]=Cải thiện khả năng truy cập cho người khuyết tật +Comment[wa]=Rind pus åjhey l' accessibilité po les sakîs k' ont des andicapes +Comment[xh]=Phucula unikekezeleko lwabantu abakhubazekileyo +Comment[x-test]=xxImprove accessibility for disabled personsxx +Comment[zh_CN]=方便残疾人使用的辅助功能 +Comment[zh_TW]=方便傷殘人士使用 + +X-KDE-Keywords=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys +X-KDE-Keywords[bs]=pristup,pristupačnost,gluh,oštećen,sluh,gubitak sluha,zvono,zvučno zvono,vidljivo zvono,tastatura,tipke,ljepljive tipke,odskočne tipke,usporene tipke,navigacija uz pomoć miša,numerički dio, +X-KDE-Keywords[ca]=accés,accessibilitat,sord,discapacitat,oïda,pèrdua d'oïda,campana,campana audible,campana visible,Teclat,tecles apegaloses,repetició de tecles,tecles lentes,navegació de ratolí,teclat numèric,activació de gestos,gestors,apegalós,tecles modificadores,modificador,tecles bloquejadores +X-KDE-Keywords[ca@valencia]=accés,accessibilitat,sord,discapacitat,oïda,pèrdua d'oïda,campana,campana audible,campana visible,Teclat,tecles apegaloses,repetició de tecles,tecles lentes,navegació de ratolí,teclat numèric,activació de gestos,gestors,apegalós,tecles modificadores,modificador,tecles bloquejadores +X-KDE-Keywords[da]=tilgang,tilgængelighed,døv,hæmmet,handicappet,hørelse,hørehæmmet,klokke,hørbar klokke,synlig klokke,tastatur,taster,sticky keys,elastiske taster,bounce,langsomme taster,musenavigation,numerisk tastatur,aktiveringsgestusser,gestusser,klæbende,ændringstaster,låsetaster +X-KDE-Keywords[de]=Behinderung,Maussteuerung,Signale,Tastatur,Tasten,Klebende Tasten,Taubheit,Verlangsamte Tasten,Zahlenblock,Zugang,Zugangshilfen,Zahlentasten,Gesten aktivieren,Sondertasten,Sperrtasten +X-KDE-Keywords[el]=πρόσβαση,προσβασιμότητα,βαρήκοος,πρόβλημα,ακοής,απώλεια ακοής,κουδούνι,ηχητικό κουδούνι,οπτικό κουδούνι,πληκτρολόγιο,πλήκτρα,κολλημένα πλήκτρα,πλήκτρα αναπήδησης,αργά πλήκτρα,πλοήγηση με ποντίκι,αριθμητικό πληκτρολόγιο,numpad,νεύματα ενεργοποίησης,νεύματα,κολλημένο,πλήκτρα τροποποιητή,τροποποιητής,πλήκτρα κλειδώματος +X-KDE-Keywords[en_GB]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys +X-KDE-Keywords[es]=acceso,accesibilidad,sordera,descapacitado,oído,pérdida de oído,campana,campana audible,campana visible,teclado,teclas,teclas pegajosas,repetición de teclas,teclas lentas,navegación con ratón,teclado numérico,gestos de activación,gestos,pegajoso,teclas modificadoras,modificador,teclas de bloqueo +X-KDE-Keywords[et]=hõlbustus,kasutusmugavus,kurdid,tummad,kuulmine,kuulmiskaotus,puuetega,kell,kuuldav kell,nähtav kell,klaviatuur,klahvid,kleepuvad klahvid,põrkuvad klahvid,aeglased klahvid,hiirega liikumine,numbriklahvistik,aktiveerimisžestid,žestid,muuteklahvid,lukustusklahvid +X-KDE-Keywords[eu]=sarbide,erabilerraztasun,gor,baliaezintasun,entzumen,entzumena galdu,kanpai,kanpai entzungarri,kanpai ikusgarri,teklatu,tekla,tekla itsaskor,errebote-teklak,tekla motel,sagu bidezko nabigazio,zenbakizko teklatu,zk teklatu,aktibazio-keinu,keinu,itsaskor,tekla aldatzaile,aldatzaile,blokeo-tekla +X-KDE-Keywords[fi]=esteettömyys,kuuro,heikentynyt,heikko,kuulo,varoitus,äänimerkki,visuaalinen äänimerkki,näppäimistö,näppäimet,alas jäävät näppäimet,tahmeat näppäimet,ponnahdusnäppäimet,hitaat näppäimet,hiirinäppäimet,numeronäppäimistö +X-KDE-Keywords[fr]=accès, accessibilité, sourd, affaiblis, audition, perte d'audition, cloche, cloche audible, cloche visuelle, clavier, touches, touches collantes, touche rebondissante, touches lentes, navigation de la souris, pavé numérique, gestes d'activation, gestes, collant, touches modifiantes, modificateur, touche de verrouillage +X-KDE-Keywords[ga]=rochtain,inrochtaineacht,bodhar,lagaithe,cloigín,cloigín inchloiste,clog infheicthe,Méarchlár,eochracha,eochracha greamaitheacha,eochracha preabtha,eochracha go mall,nascleanúint luiche,eochaircheap uimhriúil,gothaí,greamaitheach,mionthraitheoir,eochracha glasála +X-KDE-Keywords[gl]=acceso, accesibilidade, xordo, discapacitado, minusválido, audición, auditiva, campá audíbel, campá visíbel, teclado, tecla pegañentas, teclas lentas, navegación co rato, teclado numérico, acenos, teclas modificadoras +X-KDE-Keywords[hu]=kezelés,akadálymentesítés,süket,károsodott,hallás,halláskárosodás,csengő,hallható csengő,látható csengő,Billentyűzet,billentyűk,ragadós billentyűk,pattogó billentyűk,lassú billentyűk,egérnavigáció,numerikus billentyűzet +X-KDE-Keywords[ia]=accesso,accessibilitate,surde,debilitate,audito, perdita de audito,campana,campana audibile,campana visibile,Claviero,claves,claves collose,claves saltante,claves lente,navigation de mus,pad numeric, gestos de activation,gestos,collose, claves modificator, modificator, claves blocante +X-KDE-Keywords[it]=accesso,accessibilità,sordo,handicap,udito,sordità,campanella,campanella udibile,campanella visiva,tastiera,tasti,permanenza dei tasti,pressione ravvicinata dei tasti,rallentamento dei tasti,navigazione col mouse,tastierino numerico,attivazione gesti,gesti,tasti modificatori,modificatore,tasti di blocco +X-KDE-Keywords[kk]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys +X-KDE-Keywords[km]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys +X-KDE-Keywords[ko]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,접근,접근성,청각장애,청각 장애,시각장애,시각 장애,키보드,키,고정키,튕김키,느린키,마우스키,숫자패드 +X-KDE-Keywords[mr]=एक्सेस, एक्सेसिबिलिटी, कर्णबधीर, विकलांग, ऐकणे, कमी ऐकू येणे, घंटा, घंटानाद , दृश्यघंटा, कि-बोर्ड, कीज, स्टिकी किज, बाउन्स किज, स्लो किज, माऊस दिशानिर्देश, न्यूम पॅड, एक्टिव्हेशन गेस्चर्स, गेस्चर्स, स्टिकी, मॉडीफायर कीज, मॉडीफायर, लॉकिंग किज, +X-KDE-Keywords[nb]=tilgang,tilgjengelighet,døv,hemmet,hørsel, hørselstap,bjelle,hørbar bjelle,synlig bjelle,Tastatur,låsetaster,faste taster,trege taster,musnavigering, talltastatur,tallboks,aktiveringsbevegelser,bevegelser,valgtaster +X-KDE-Keywords[nds]=Togang,Toganghülp,doof,kiekbehinnert,Hören,Pingel,Ogenpingel,Tastatuur,Tasten,backige Tasten,jumpen Tasten,langsame Tasten,Muusstüern,Tallenblock,Tekens,Anmaaktekens,backig,Sünnertasten,Wesseltekens,Fastsetttasten +X-KDE-Keywords[nl]=toegang,toegankelijkheid,doof,gehandicapt,gehoor,gehoorverlies,bel,hoorbare bel,zichtbare bel,toetsenbord,toetsen,dode toetsen,herhaaltoetsen,langzame toetsen,muisnavigatie,numeriek toetsenbord,activeringsgebaren,gebaren,plakkerig,modificatietoetsen,modificator,vergrendeltoets +X-KDE-Keywords[pl]=dostęp,dostępność,głuchota,upośledzenie,dzwonek,słyszalny dzwonek,widoczny dzwonek,Klawiatura,klawisze,lepkie klawisze,odbijające klawisze,powolne klawisze, ruchy myszą,klawiatura numeryczna +X-KDE-Keywords[pt]=acesso,acessibilidade,surdo,deficiente,campainha,campainha audível,campainha visível,teclado,teclas,teclas fixas,teclas lentas,teclas sonoras,navegação do rato,teclado numérico,numérico,gestos de activação,gestos,fixo,teclas modificadoras,modificadora,teclas de bloqueio +X-KDE-Keywords[pt_BR]=acesso,acessibilidade,surdo,deficiente,audição,campainha,campainha audível,campainha visível,Teclado,teclas,teclas de aderência,teclas lentas,teclas de repercussão,navegação do mouse,teclado numérico numérico,gestos de ativação,gestos,fixo,teclas modificadoras,modificadora,teclas de bloqueio +X-KDE-Keywords[ru]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,доступ,доступность,глухота,слух,ослабленный,слабый,потеря слуха,звонок,сигнал,звуковой сигнал,визуальный сигнал,видимый сигнал,клавиатура,кнопки,клавиши,залипание,залипающие клавиши,липкие клавиши,прыгающие клавиши,«прыгающие» клавиши,замедленные клавиши,навигация с помощью мыши,управление мышью,цифровая клавиатура,жесты активации,жесты,клавиши-модификаторы,модификаторы,модификатор,клавиши индикаторов +X-KDE-Keywords[sk]=prístup,prístupnosť,hluchý,opitý,sluch,strata sluchu,zvonček,hlasný zvonček,viditeľný zvonček,Klávesnica,klávesy,lepkavé klávesy,skákajúce klávesy,pomalé klávesy,navigácia myšou,numerická klávesnica,numpad,aktivačné gestá,lepkavé,modifikačné klávesy,modifikátor,zamykacie klávesy +X-KDE-Keywords[sl]=dostop,dostopnost,gluh,oviran,sluh,slušno,izguba sluha,zvonec,slišen zvonec,viden zvonec,tipkovnica,tipke,lepljive tipke,odbijajoče tipke,počasne tipke,krmarjenje z miško,številčnica,številske tipke,kretnje za vklop,kretnje,lepljivo,spremenilne tipke,zaklepne tipke +X-KDE-Keywords[sr]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,приступ,приступачност,глув,оштећен,слух,губитак,звоно,чујно,видно,тастатура,тастери,лепљиви,одскачући,спори,нумеричка,активација,гестови,лепљив,модификаторски,тастери,закључавање +X-KDE-Keywords[sr@ijekavian]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,приступ,приступачност,глув,оштећен,слух,губитак,звоно,чујно,видно,тастатура,тастери,лепљиви,одскачући,спори,нумеричка,активација,гестови,лепљив,модификаторски,тастери,закључавање +X-KDE-Keywords[sr@ijekavianlatin]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,pristup,pristupačnost,gluv,oštećen,sluh,gubitak,zvono,čujno,vidno,tastatura,tasteri,lepljivi,odskačući,spori,numerička,aktivacija,gestovi,lepljiv,modifikatorski,tasteri,zaključavanje +X-KDE-Keywords[sr@latin]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,pristup,pristupačnost,gluv,oštećen,sluh,gubitak,zvono,čujno,vidno,tastatura,tasteri,lepljivi,odskačući,spori,numerička,aktivacija,gestovi,lepljiv,modifikatorski,tasteri,zaključavanje +X-KDE-Keywords[sv]=åtkomst,handikappstöd,döva,funktionshindrade,hörsel,hörselförlust,summer,hörbar summer,synlig summer,Tangentbord,tangenter,klistriga tangenter,studsande tangenter,långsamma tangenter,musnavigering,numeriskt tangentbord,aktiveringsgester,gester,klistrig,väljartangenter,väljare,låstangenter +X-KDE-Keywords[tr]=erişim,erişebilirlik,sağır,bozukluk,işitme,kayıp,zil,işitilebilir zil,görünen zil,Klayve,tuşlar,yapışkan tuşlar,sıçrama tuşları,yavaş tuşlar,fare gezinmesi,rakamlar klavyesi,jestler,yapışkan,hızlandırma tuşları,hızlandırıcı,kilitleme tuşları +X-KDE-Keywords[uk]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,доступ,доступність,спеціальні можливості,глухий,слух,враження,вади,звук,сповіщення,видиме сповіщення,візуальне сповіщення,клавіатура,клавіші,клавіша,липкі клавіші,утримування,повільні клавіші,миша,навігація,цифри,цифровий блок,слух,втрата слуху,жести активування,жести,липка,липкі клавіші,клавіші-модифікатори,модифікатори,клавіші фіксування,фіксування,блокування +X-KDE-Keywords[x-test]=xxaccess,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keysxx +X-KDE-Keywords[zh_CN]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys,访问,可访问性,耳聋,聋,听力,听力丧失,铃声,可视铃声,按键,残疾人,残疾,聋哑,键盘,粘滞键,鼠标,小键盘,撞击键,鼠标导航,数字键盘,激活手势,手势,粘滞,修饰键,锁定键 +X-KDE-Keywords[zh_TW]=access,accessibility,deaf,impaired,hearing,hearing loss,bell,audible bell,visible bell,Keyboard,keys,sticky keys,bounce keys,slow keys,mouse navigation,num pad,numpad,activation gestures,gestures,sticky,modifier keys,modifier,locking keys + +Categories=Qt;KDE;X-KDE-settings-accessibility; diff --git a/kcontrol/access/kcmaccess.h b/kcontrol/access/kcmaccess.h new file mode 100644 index 00000000..d3cb40f3 --- /dev/null +++ b/kcontrol/access/kcmaccess.h @@ -0,0 +1,76 @@ +/** + * kcmaccess.h + * + * Copyright (c) 2000 Matthias H�zer-Klpfel + * + */ + +#ifndef __kcmaccess_h__ +#define __kcmaccess_h__ + + +#define KDE3_SUPPORT +#include +#undef KDE3_SUPPORT +#include + + +class QCheckBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class KColorButton; +class QSlider; + +class KAccessConfig : public KCModule +{ + Q_OBJECT + +public: + + KAccessConfig( QWidget *parent, const QVariantList& ); + virtual ~KAccessConfig(); + + void load(); + void save(); + void defaults(); + +protected Q_SLOTS: + + void configChanged(); + void checkAccess(); + void invertClicked(); + void flashClicked(); + void selectSound(); + void changeFlashScreenColor(); + void configureKNotify(); + +private: + + QCheckBox *systemBell, *customBell, *visibleBell; + QRadioButton *invertScreen, *flashScreen; + QLabel *soundLabel, *colorLabel; + QLineEdit *soundEdit; + QPushButton *soundButton; + KColorButton *colorButton; + KDoubleNumInput *durationSlider; + + QCheckBox *stickyKeys, *stickyKeysLock, *stickyKeysAutoOff; + QCheckBox *stickyKeysBeep, *toggleKeysBeep, *kNotifyModifiers; + QPushButton *kNotifyModifiersButton; + + QCheckBox *slowKeys, *bounceKeys; + KDoubleNumInput *slowKeysDelay, *bounceKeysDelay; + QCheckBox *slowKeysPressBeep, *slowKeysAcceptBeep; + QCheckBox *slowKeysRejectBeep, *bounceKeysRejectBeep; + + QCheckBox *gestures, *gestureConfirmation; + QCheckBox *timeout; + KIntNumInput *timeoutDelay; + QCheckBox *accessxBeep, *kNotifyAccessX; + QPushButton *kNotifyAccessXButton; +}; + + +#endif diff --git a/kcontrol/access/main.cpp b/kcontrol/access/main.cpp new file mode 100644 index 00000000..9dc1ae59 --- /dev/null +++ b/kcontrol/access/main.cpp @@ -0,0 +1,52 @@ + +#include "kaccess.h" +#include +#include +#include +#include +extern "C" KDE_EXPORT int kdemain(int argc, char * argv[] ) +{ + KAboutData about(I18N_NOOP("kaccess"), 0, ki18n("KDE Accessibility Tool"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 2000, Matthias Hoelzer-Kluepfel")); + + about.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"), ki18n("Author") , "hoelzer@kde.org"); + + KCmdLineArgs::init( argc, argv, &about ); + + if (!KAccessApp::start()) + return 0; + + // verify the Xlib has matching XKB extension + int major = XkbMajorVersion; + int minor = XkbMinorVersion; + if (!XkbLibraryVersion(&major, &minor)) + { + kError() << "Xlib XKB extension does not match" << endl; + return 1; + } + kDebug() << "Xlib XKB extension major=" << major << " minor=" << minor; + + // we need an application object for QX11Info + KAccessApp app; + + // verify the X server has matching XKB extension + // if yes, the XKB extension is initialized + int opcode_rtrn; + int error_rtrn; + int xkb_opcode; + if (!XkbQueryExtension(QX11Info::display(), &opcode_rtrn, &xkb_opcode, &error_rtrn, + &major, &minor)) + { + kError() << "X server has not matching XKB extension" << endl; + return 1; + } + kDebug() << "X server XKB extension major=" << major << " minor=" << minor; + + //Without that, the application dies when the dialog is closed only once. + app.setQuitOnLastWindowClosed(false); + + app.setXkbOpcode(xkb_opcode); + app.disableSessionManagement(); + return app.exec(); +} diff --git a/kcontrol/autostart/AUTHORS b/kcontrol/autostart/AUTHORS new file mode 100644 index 00000000..ab559c90 --- /dev/null +++ b/kcontrol/autostart/AUTHORS @@ -0,0 +1,2 @@ +Stephen Leaf +Montel Laurent diff --git a/kcontrol/autostart/CMakeLists.txt b/kcontrol/autostart/CMakeLists.txt new file mode 100644 index 00000000..e05ac65c --- /dev/null +++ b/kcontrol/autostart/CMakeLists.txt @@ -0,0 +1,25 @@ +PROJECT (autostart) + +INCLUDE (KDE4Defaults) + +ADD_DEFINITIONS (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +INCLUDE_DIRECTORIES (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) + +########### next target ############### + +SET(kcm_autostart_PART_SRCS + autostartitem.cpp + addscriptdialog.cpp + advanceddialog.cpp + autostart.cpp ) + +KDE4_ADD_UI_FILES(kcm_autostart_PART_SRCS autostartconfig.ui ) + +KDE4_ADD_PLUGIN(kcm_autostart ${kcm_autostart_PART_SRCS}) + +TARGET_LINK_LIBRARIES(kcm_autostart ${KDE4_KIO_LIBS} ) + +########### install files ############### + +INSTALL(TARGETS kcm_autostart DESTINATION ${PLUGIN_INSTALL_DIR} ) +INSTALL( FILES autostart.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcontrol/autostart/Messages.sh b/kcontrol/autostart/Messages.sh new file mode 100644 index 00000000..8f32b9b7 --- /dev/null +++ b/kcontrol/autostart/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcm_autostart.pot +rm -f rc.cpp diff --git a/kcontrol/autostart/addscriptdialog.cpp b/kcontrol/autostart/addscriptdialog.cpp new file mode 100644 index 00000000..8a4ef796 --- /dev/null +++ b/kcontrol/autostart/addscriptdialog.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2007 by Stephen Leaf * + * smileaf@gmail.com * + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "addscriptdialog.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +AddScriptDialog::AddScriptDialog (QWidget* parent) + : KDialog( parent ) { + QWidget *w = new QWidget( this ); + setButtons( Cancel|Ok ); + QVBoxLayout *lay= new QVBoxLayout; + w->setLayout( lay ); + QLabel *lab = new QLabel( i18n( "Shell script path:" ), w ); + lay->addWidget( lab ); + m_url = new KUrlRequester( w ); + lay->addWidget( m_url ); + m_symlink = new QCheckBox( i18n( "Create as symlink" ), w ); //TODO fix text + m_symlink->setChecked( true ); + lay->addWidget( m_symlink ); + connect( m_url->lineEdit(), SIGNAL(textChanged(QString)), SLOT(textChanged(QString)) ); + m_url->lineEdit()->setFocus(); + enableButtonOk(false); + + setMainWidget( w ); +} + +AddScriptDialog::~AddScriptDialog() +{ +} + +void AddScriptDialog::textChanged(const QString &text) +{ + enableButtonOk(!text.isEmpty()); +} + +void AddScriptDialog::accept() +{ + if ( doBasicSanityCheck() ) + KDialog::accept(); +} + +bool AddScriptDialog::doBasicSanityCheck() +{ + const QString& path = KShell::tildeExpand(m_url->text()); + + QFileInfo file(path); + + if ( ! file.isAbsolute() ) { + KMessageBox::sorry( 0, i18n("\"%1\" is not an absolute path.", path) ); + return false; + } else if ( ! file.exists() ) { + KMessageBox::sorry( 0, i18n("\"%1\" does not exist.", path) ); + return false; + } else if ( !file.isFile() ) { + KMessageBox::sorry( 0, i18n("\"%1\" is not a file.", path) ); + return false; + } else if ( ! file.isReadable() ) { + KMessageBox::sorry( 0, i18n("\"%1\" is not readable.", path) ); + return false; + } + + return true; +} + +KUrl AddScriptDialog::importUrl() const +{ + return m_url->lineEdit()->text(); +} + +bool AddScriptDialog::symLink() const +{ + return m_symlink->isChecked(); +} + +#include "addscriptdialog.moc" diff --git a/kcontrol/autostart/addscriptdialog.h b/kcontrol/autostart/addscriptdialog.h new file mode 100644 index 00000000..4064bf10 --- /dev/null +++ b/kcontrol/autostart/addscriptdialog.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2007 by Stephen Leaf * + * smileaf@gmail.com * + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef ADDSCRIPTDIALOG_H +#define ADDSCRIPTDIALOG_H + +#include + +class KUrlRequester; +class QCheckBox; + +class AddScriptDialog : public KDialog +{ + Q_OBJECT + +public: + explicit AddScriptDialog(QWidget* parent=0); + ~AddScriptDialog(); + // Returns the Url of the script to be imported + KUrl importUrl() const; + bool symLink() const; + +public slots: + // reimplemented + virtual void accept(); + +protected: + virtual bool doBasicSanityCheck(); + +private slots: + void textChanged(const QString &text); + +private: + KUrlRequester *m_url; + QCheckBox* m_symlink; +}; + +#endif diff --git a/kcontrol/autostart/advanceddialog.cpp b/kcontrol/autostart/advanceddialog.cpp new file mode 100644 index 00000000..2fb11c5d --- /dev/null +++ b/kcontrol/autostart/advanceddialog.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "advanceddialog.h" + +#include +#include + +#include + +AdvancedDialog::AdvancedDialog( QWidget *parent, bool status ) + :KDialog( parent ) +{ + QWidget *w = new QWidget( this ); + setButtons( Cancel|Ok ); + QVBoxLayout *lay= new QVBoxLayout; + w->setLayout( lay ); + m_onlyInKde = new QCheckBox( i18n( "Autostart only in KDE" ), w ); + m_onlyInKde->setChecked( status ); + lay->addWidget( m_onlyInKde ); + setMainWidget( w ); +} + +AdvancedDialog::~AdvancedDialog() +{ +} + +bool AdvancedDialog::onlyInKde() const +{ + return m_onlyInKde->isChecked(); +} + + +#include "advanceddialog.moc" + diff --git a/kcontrol/autostart/advanceddialog.h b/kcontrol/autostart/advanceddialog.h new file mode 100644 index 00000000..28631a75 --- /dev/null +++ b/kcontrol/autostart/advanceddialog.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef ADVANCEDDIALOG_H +#define ADVANCEDDIALOG_H + +#include +class QCheckBox; + +class AdvancedDialog : public KDialog +{ + Q_OBJECT + +public: + AdvancedDialog(QWidget* parent, bool status); + ~AdvancedDialog(); + + bool onlyInKde() const; + +private: + QCheckBox *m_onlyInKde; +}; + +#endif diff --git a/kcontrol/autostart/autostart.cpp b/kcontrol/autostart/autostart.cpp new file mode 100644 index 00000000..4ed67648 --- /dev/null +++ b/kcontrol/autostart/autostart.cpp @@ -0,0 +1,440 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 by Stephen Leaf * + * smileaf@gmail.com * + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "autostart.h" +#include "autostartitem.h" +#include "addscriptdialog.h" +#include "advanceddialog.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +K_PLUGIN_FACTORY(AutostartFactory, registerPlugin();) + K_EXPORT_PLUGIN(AutostartFactory( "kcmautostart", "kcm_autostart" )) + + Autostart::Autostart( QWidget* parent, const QVariantList& ) + : KCModule( AutostartFactory::componentData(), parent ) +{ + widget = new Ui_AutostartConfig(); + widget->setupUi(this); + + QStringList lstHeader; + lstHeader << i18n( "Name" ) + << i18n( "Command" ) + << i18n( "Status" ) + << i18nc("@title:column The name of the column that decides if the program is run on kde startup, on kde shutdown, etc", "Run On" ); + widget->listCMD->setHeaderLabels(lstHeader); + widget->listCMD->setFocus(); + + setButtons(Help); + + connect( widget->btnAddScript, SIGNAL(clicked()), SLOT(slotAddScript()) ); + connect( widget->btnAddProgram, SIGNAL(clicked()), SLOT(slotAddProgram()) ); + connect( widget->btnRemove, SIGNAL(clicked()), SLOT(slotRemoveCMD()) ); + connect( widget->btnAdvanced, SIGNAL(clicked()), SLOT(slotAdvanced()) ); + connect( widget->listCMD, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(slotEditCMD(QTreeWidgetItem*)) ); + connect( widget->listCMD, SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(slotItemClicked(QTreeWidgetItem*,int)) ); + connect( widget->btnProperties, SIGNAL(clicked()), SLOT(slotEditCMD()) ); + connect( widget->listCMD, SIGNAL(itemSelectionChanged()), SLOT(slotSelectionChanged()) ); + + + KAboutData* about = new KAboutData("Autostart", 0, ki18n("KDE Autostart Manager"), "1.0", + ki18n("KDE Autostart Manager Control Panel Module"), + KAboutData::License_GPL, + ki18n("Copyright © 2006–2010 Autostart Manager team")); + about->addAuthor(ki18n("Stephen Leaf"), KLocalizedString(), "smileaf@gmail.com"); + about->addAuthor(ki18n("Montel Laurent"), ki18n( "Maintainer" ), "montel@kde.org"); + setAboutData( about ); + +} + +Autostart::~Autostart() +{ + delete widget; +} + + +void Autostart::slotItemClicked( QTreeWidgetItem *item, int col) +{ + if ( item && col == COL_STATUS ) { + DesktopStartItem *entry = dynamic_cast( item ); + if ( entry ) { + bool disable = ( item->checkState( col ) == Qt::Unchecked ); + KDesktopFile kc(entry->fileName().path()); + KConfigGroup grp = kc.desktopGroup(); + if ( grp.hasKey( "Hidden" ) && !disable) { + grp.deleteEntry( "Hidden" ); + } + else + grp.writeEntry("Hidden", disable); + + kc.sync(); + if ( disable ) + item->setText( COL_STATUS, i18nc( "The program won't be run", "Disabled" ) ); + else + item->setText( COL_STATUS, i18nc( "The program will be run", "Enabled" ) ); + } + } +} + +void Autostart::addItem( DesktopStartItem* item, const QString& name, const QString& run, const QString& command, bool disabled ) +{ + Q_ASSERT( item ); + item->setText( COL_NAME, name ); + item->setText( COL_RUN, run ); + item->setText( COL_COMMAND, command ); + item->setCheckState( COL_STATUS, disabled ? Qt::Unchecked : Qt::Checked ); + item->setText( COL_STATUS, disabled ? i18nc( "The program won't be run", "Disabled" ) : i18nc( "The program will be run", "Enabled" )); +} + +void Autostart::addItem(ScriptStartItem* item, const QString& name, const QString& command, ScriptStartItem::ENV type ) +{ + Q_ASSERT( item ); + item->setText( COL_NAME, name ); + item->setText( COL_COMMAND, command ); + item->changeStartup( type ); +} + + +void Autostart::load() +{ + // share/autostart may *only* contain .desktop files + // shutdown and env may *only* contain scripts, links or binaries + // autostart on the otherhand may contain all of the above. + // share/autostart is special as it overrides entries found in $KDEDIR/share/autostart + m_paths << KGlobalSettings::autostartPath() // All new entries should go here + << componentData().dirs()->localkdedir() + "shutdown/" + << componentData().dirs()->localkdedir() + "env/" + << componentData().dirs()->localkdedir() + "share/autostart/" // For Importing purposes + << componentData().dirs()->localxdgconfdir() + "autostart/" ; //xdg-config autostart dir + + // share/autostart shouldn't be an option as this should be reserved for global autostart entries + m_pathName << i18n("Startup") + << i18n("Shutdown") + << i18n("Pre-KDE startup") + ; + widget->listCMD->clear(); + + m_programItem = new QTreeWidgetItem( widget->listCMD ); + m_programItem->setText( 0, i18n( "Desktop File" )); + m_programItem->setFlags(m_programItem->flags()^Qt::ItemIsSelectable ); + + QFont boldFont = m_programItem->font(0); + boldFont.setBold( true ); + m_programItem->setData ( 0, Qt::FontRole, boldFont ); + + m_scriptItem = new QTreeWidgetItem( widget->listCMD ); + m_scriptItem->setText( 0, i18n( "Script File" )); + m_scriptItem->setFlags(m_scriptItem->flags()^Qt::ItemIsSelectable); + m_scriptItem->setData ( 0, Qt::FontRole, boldFont); + + widget->listCMD->expandItem( m_programItem ); + widget->listCMD->expandItem( m_scriptItem ); + + foreach (const QString& path, m_paths) { + if (! KStandardDirs::exists(path)) + KStandardDirs::makeDir(path); + + QDir autostartdir( path ); + autostartdir.setFilter( QDir::Files ); + const QFileInfoList list = autostartdir.entryInfoList(); + for (int i = 0; i < list.size(); ++i) { + QFileInfo fi = list.at(i); + QString filename = fi.fileName(); + bool desktopFile = filename.endsWith(".desktop"); + if ( desktopFile ) + { + KDesktopFile config(fi.absoluteFilePath()); + //kDebug() << fi.absoluteFilePath() << "trying" << config.desktopGroup().readEntry("Exec"); + QStringList commandLine = KShell::splitArgs(config.desktopGroup().readEntry("Exec")); + if (commandLine.isEmpty()) { + continue; + } + + const QString exe = commandLine.first(); + if (exe.isEmpty() || KStandardDirs::findExe(exe).isEmpty()) { + continue; + } + + DesktopStartItem *item = new DesktopStartItem( fi.absoluteFilePath(), m_programItem, this ); + + const KConfigGroup grp = config.desktopGroup(); + const bool hidden = grp.readEntry("Hidden", false); + const QStringList notShowList = grp.readXdgListEntry("NotShowIn"); + const QStringList onlyShowList = grp.readXdgListEntry("OnlyShowIn"); + + const bool disabled = hidden || + notShowList.contains("KDE") || + (!onlyShowList.isEmpty() && !onlyShowList.contains("KDE")); + + int indexPath = m_paths.indexOf((item->fileName().directory()+'/' ) ); + if ( indexPath > 2 ) + indexPath = 0; //.kde/share/autostart and .config/autostart load destkop at startup + addItem(item, config.readName(), m_pathName.value(indexPath), grp.readEntry("Exec"), disabled ); + } + else + { + ScriptStartItem *item = new ScriptStartItem( fi.absoluteFilePath(), m_scriptItem,this ); + int typeOfStartup = m_paths.indexOf((item->fileName().directory()+'/') ); + ScriptStartItem::ENV type = ScriptStartItem::START; + switch( typeOfStartup ) + { + case 0: + type =ScriptStartItem::START; + break; + case 1: + type = ScriptStartItem::SHUTDOWN; + break; + case 2: + type = ScriptStartItem::PRE_START; + break; + default: + kDebug()<<" type is not defined :"<listCMD->resizeColumnToContents(COL_NAME); + //widget->listCMD->resizeColumnToContents(COL_COMMAND); + widget->listCMD->resizeColumnToContents(COL_STATUS); + widget->listCMD->resizeColumnToContents(COL_RUN); +} + +void Autostart::slotAddProgram() +{ + KOpenWithDialog owdlg( this ); + if (owdlg.exec() != QDialog::Accepted) + return; + + KService::Ptr service = owdlg.service(); + + Q_ASSERT(service); + if (!service) { + return; // Don't crash if KOpenWith wasn't able to create service. + } + + // It is important to ensure that we make an exact copy of an existing + // desktop file (if selected) to enable users to override global autostarts. + // Also see + // https://bugs.launchpad.net/ubuntu/+source/kde-workspace/+bug/923360 + QString desktopPath; + KUrl desktopTemplate; + if ( service->desktopEntryName().isEmpty() ) { + // Build custom desktop file (e.g. when the user entered an executable + // name in the OpenWithDialog). + desktopPath = m_paths[4] + service->name() + ".desktop"; + desktopTemplate = KUrl( desktopPath ); + KConfig kc(desktopTemplate.path(), KConfig::SimpleConfig); + KConfigGroup kcg = kc.group("Desktop Entry"); + kcg.writeEntry("Exec",service->exec()); + kcg.writeEntry("Icon","system-run"); + kcg.writeEntry("Path",""); + kcg.writeEntry("Terminal",false); + kcg.writeEntry("Type","Application"); + kc.sync(); + + KPropertiesDialog dlg( desktopTemplate, this ); + if ( dlg.exec() != QDialog::Accepted ) + { + return; + } + } + else + { + // Use existing desktop file and use same file name to enable overrides. + desktopPath = m_paths[4] + service->desktopEntryName() + ".desktop"; + desktopTemplate = KUrl( KStandardDirs::locate("apps", service->entryPath()) ); + + KPropertiesDialog dlg( desktopTemplate, KUrl(m_paths[4]), service->desktopEntryName() + ".desktop", this ); + if ( dlg.exec() != QDialog::Accepted ) + return; + } + DesktopStartItem * item = new DesktopStartItem( desktopPath, m_programItem,this ); + addItem( item, service->name(), m_pathName[0], service->exec() , false); +} + +void Autostart::slotAddScript() +{ + AddScriptDialog * addDialog = new AddScriptDialog(this); + int result = addDialog->exec(); + if (result == QDialog::Accepted) { + if (addDialog->symLink()) + KIO::link(addDialog->importUrl(), m_paths[0]); + else + KIO::copy(addDialog->importUrl(), m_paths[0]); + + ScriptStartItem * item = new ScriptStartItem( m_paths[0] + addDialog->importUrl().fileName(), m_scriptItem,this ); + addItem( item, addDialog->importUrl().fileName(), addDialog->importUrl().fileName(),ScriptStartItem::START ); + } + delete addDialog; +} + +void Autostart::slotRemoveCMD() +{ + QTreeWidgetItem* item = widget->listCMD->currentItem(); + if (!item) + return; + DesktopStartItem *startItem = dynamic_cast( item ); + if ( startItem ) + { + m_programItem->takeChild( m_programItem->indexOfChild( startItem ) ); + KIO::del(startItem->fileName().path() ); + delete item; + } + else + { + ScriptStartItem * scriptItem = dynamic_cast( item ); + if ( scriptItem ) + { + m_scriptItem->takeChild( m_scriptItem->indexOfChild( scriptItem ) ); + KIO::del(scriptItem->fileName().path() ); + delete item; + } + } +} + +void Autostart::slotEditCMD(QTreeWidgetItem* ent) +{ + if (!ent) return; + AutoStartItem *entry = dynamic_cast( ent ); + if ( entry ) + { + const KFileItem kfi = KFileItem( KFileItem::Unknown, KFileItem::Unknown, KUrl( entry->fileName() ), true ); + if (! slotEditCMD( kfi )) + return; + DesktopStartItem *desktopEntry = dynamic_cast( entry ); + if (desktopEntry) { + KService service(desktopEntry->fileName().path()); + addItem( desktopEntry, service.name(), m_pathName.value(m_paths.indexOf((desktopEntry->fileName().directory()+'/') )), service.exec(),false ); + } + } +} + +bool Autostart::slotEditCMD( const KFileItem &item) +{ + KPropertiesDialog dlg( item, this ); + bool c = ( dlg.exec() == QDialog::Accepted ); + return c; +} + +void Autostart::slotEditCMD() +{ + if ( widget->listCMD->currentItem() == 0 ) + return; + slotEditCMD( (AutoStartItem*)widget->listCMD->currentItem() ); +} + +void Autostart::slotAdvanced() +{ + if ( widget->listCMD->currentItem() == 0 ) + return; + + DesktopStartItem *entry = static_cast( widget->listCMD->currentItem() ); + KDesktopFile kc(entry->fileName().path()); + KConfigGroup grp = kc.desktopGroup(); + bool status = false; + QStringList lstEntry; + if (grp.hasKey("OnlyShowIn")) + { + lstEntry = grp.readXdgListEntry("OnlyShowIn"); + status = lstEntry.contains("KDE"); + } + + AdvancedDialog *dlg = new AdvancedDialog( this,status ); + if ( dlg->exec() ) + { + status = dlg->onlyInKde(); + if ( lstEntry.contains( "KDE" ) && !status ) + { + lstEntry.removeAll( "KDE" ); + grp.writeXdgListEntry( "OnlyShowIn", lstEntry ); + } + else if ( !lstEntry.contains( "KDE" ) && status ) + { + lstEntry.append( "KDE" ); + grp.writeXdgListEntry( "OnlyShowIn", lstEntry ); + } + } + delete dlg; +} + +void Autostart::slotChangeStartup( ScriptStartItem* item, int index ) +{ + Q_ASSERT(item); + + if ( item ) + { + item->setPath(m_paths.value(index)); + widget->listCMD->setCurrentItem( item ); + if ( ( index == 2 ) && !item->fileName().path().endsWith( ".sh" )) + KMessageBox::information( this, i18n( "Only files with “.sh” extensions are allowed for setting up the environment." ) ); + + } +} + +void Autostart::slotSelectionChanged() +{ + const bool hasItems = ( dynamic_cast( widget->listCMD->currentItem() )!=0 ) ; + widget->btnRemove->setEnabled(hasItems); + + const bool isDesktopItem = (dynamic_cast(widget->listCMD->currentItem() ) != 0) ; + widget->btnProperties->setEnabled(isDesktopItem); + widget->btnAdvanced->setEnabled(isDesktopItem) ; +} + +void Autostart::defaults() +{ +} + +void Autostart::save() +{ +} + +#include "autostart.moc" diff --git a/kcontrol/autostart/autostart.desktop b/kcontrol/autostart/autostart.desktop new file mode 100644 index 00000000..0c7a0536 --- /dev/null +++ b/kcontrol/autostart/autostart.desktop @@ -0,0 +1,190 @@ +[Desktop Entry] +Exec=kcmshell4 autostart +Icon=system-run +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/autostart/index.html + +X-KDE-Library=kcm_autostart +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=startup-and-shutdown + +Name=Autostart +Name[af]=Outomatiese begin +Name[ar]=البدء التلقائي +Name[ast]=Autoarranque +Name[be]=Аўтаматычны запуск +Name[be@latin]=Aŭtamatyčnaje ŭklučeńnie +Name[bg]=Автоматично стартиране +Name[bn]=অটো-স্টার্ট +Name[bn_IN]=স্বয়ং-আরম্ভ +Name[br]=Emloc'h +Name[bs]=Samopokretanje +Name[ca]=Inici automàtic +Name[ca@valencia]=Inici automàtic +Name[cs]=Automatické spuštění +Name[csb]=Aùtomatné zrëszanié +Name[cy]=Hunan-gychwyn +Name[da]=Autostart +Name[de]=Autostart +Name[el]=Αυτόματη εκκίνηση +Name[en_GB]=Autostart +Name[eo]=Aŭtomata lanĉo +Name[es]=Autoarranque +Name[et]=Autostart +Name[eu]=Hasiera automatikoa +Name[fa]=آغاز خودکار +Name[fi]=Automaattikäynnistys +Name[fr]=Démarrage automatique +Name[fy]=Auto-úteinsette +Name[ga]=Tosú uathoibríoch +Name[gl]=Inicio automático +Name[gu]=આપમેળેશરૂ +Name[he]=הפעלה אוטומטית +Name[hi]=स्वतःप्रारंभ +Name[hne]=खुद से चालू +Name[hr]=Automatsko pokretanje +Name[hsb]=Awtostart +Name[hu]=Automatikus indítás +Name[ia]=Auto starta +Name[id]=Start Otomatis +Name[is]=Sjálfræsing +Name[it]=Avvio automatico +Name[ja]=自動起動 +Name[ka]=ავტოგაშვება +Name[kk]=Автобастау +Name[km]=ចាប់ផ្ដើម​ស្វ័យប្រវត្តិ +Name[kn]=ಸ್ವಯಮಾರಂಭ +Name[ko]=자동 시작 +Name[ku]=Bixweber Bide Destpêkirin +Name[lt]=Autostartas +Name[lv]=Autopalaišana +Name[mai]=स्वतः चालू +Name[mk]=Автостарт +Name[ml]=ഓട്ടോസ്റ്റാര്‍ട്ട് +Name[mr]=स्वप्रारंभ +Name[ms]=Automula +Name[nb]=Autostart +Name[nds]=Autostart +Name[nl]=Autostart +Name[nn]=Autostart +Name[or]=ସ୍ୱୟଂଚାଳନ +Name[pa]=ਆਟੋ-ਸਟਾਰਟ +Name[pl]=Samoczynne uruchamianie +Name[pt]=Arranque +Name[pt_BR]=Iniciar automaticamente +Name[ro]=Pornire automată +Name[ru]=Автозапуск +Name[si]=ක්‍ෂණික ඇරඹුම +Name[sk]=Automatické spustenie +Name[sl]=Samodejni zagon +Name[sr]=Самопокретање +Name[sr@ijekavian]=Самопокретање +Name[sr@ijekavianlatin]=Samopokretanje +Name[sr@latin]=Samopokretanje +Name[sv]=Automatisk start +Name[ta]=சுயதுவக்கம் +Name[te]=స్వయంచాలకప్రారంభం +Name[tg]=Худоғозӣ +Name[th]=เริ่มอัตโนมัติ +Name[tr]=Otomatik Başlat +Name[ug]=ئۆزلۈكىدىن قوزغات +Name[uk]=Автозапуск +Name[uz]=Avto-boshlash +Name[uz@cyrillic]=Авто-бошлаш +Name[vi]=Tự khởi chạy +Name[wa]=Enondaedje tot seu +Name[xh]=Isiqalo esizenzekelayo +Name[x-test]=xxAutostartxx +Name[zh_CN]=自动启动 +Name[zh_TW]=自動啟動 + +Comment=Manage which programs start up automatically with KDE. +Comment[bs]=Upravljanje koji će se programi automatski pokretati pomoću KDE. +Comment[ca]=Gestiona quins programes s'iniciaran automàticament amb el KDE. +Comment[ca@valencia]=Gestiona quins programes s'iniciaran automàticament amb el KDE. +Comment[cs]=Spravujte automatické spouštění programů při startu KDE. +Comment[da]=Håndtér hvilke programmer der automatisk starter op med KDE. +Comment[de]=Verwaltung der automatisch mit KDE zu startenden Anwendungen. +Comment[el]=Διαχείριση των προγραμμάτων που θα ξεκινούν αυτόματα με το KDE. +Comment[en_GB]=Manage which programs start up automatically with KDE. +Comment[es]=Gestionar qué programas se inician automáticamente con KDE. +Comment[et]=Määramine, millised programmid käivituvad automaatselt koos KDE-ga. +Comment[eu]=KDErekin automatikoki abiatuko diren programak kudeatu. +Comment[fi]=Aseta, mitkä ohjelmat käynnistetään automaattisesti KDE:n käynnistyessä. +Comment[ga]=Bainistigh na ríomhchláir a thosaíonn nuair a thosaíonn KDE. +Comment[gl]=Xestiona os programas que se inician xunto con KDE. +Comment[he]=נהל אילו תוכניות מופעלות ביחד עם KDE. +Comment[hu]=Annak kezelése, hogy mely programok induljanak automatikusan a KDE-vel. +Comment[ia]=Gere qual programma debe startar automaticamente con KDE. +Comment[is]=Stjórntæki til að stilla hvaða forrit eigi að ræsast sjálfkrafa með KDE. +Comment[kk]=KDE бастағанда автожегілетін бағдарламаларды басқару. +Comment[ko]=KDE를 시작할 때 같이 시작될 프로그램을 관리합니다. +Comment[lt]=Konfigūravimo įrankis valdyti programas, kurios paleidžiamos automatiškai kartu su KDE. +Comment[mr]=केडीई सह कोणते कार्यक्रम स्वप्रारंभ होतील ते नियंत्रीत करा. +Comment[nb]=Styr hvilke program som skal starte automatisk med KDE. +Comment[nds]=Programmen fastleggen, de automaatsch mit KDE opropen warrt +Comment[nl]=Beheren van programma's die automatisch met KDE opstarten. +Comment[pa]=ਪਰਬੰਧ ਕਰਦੀ ਹੈ ਕਿ ਕਿਹੜੇ ਪਰੋਗਰਾਮ ਕੇਡੀਈ (KDE) ਨਾਲ ਆਪਣੇ-ਆਪਣ ਚੱਲਣ। +Comment[pl]=Zdecyduj, które programy mają się uruchamiać wraz ze startem KDE. +Comment[pt]=Gerir os programas que são arrancados automaticamente com o KDE. +Comment[pt_BR]=Gerencia os programas que são carregados automaticamente com o KDE. +Comment[ro]=Gestionează ce programe se pornesc automat împreună cu KDE. +Comment[ru]=Управление программами, запускаемыми автоматически в начале сеанса KDE +Comment[sk]=Spravovať, ktoré programy spustiť automaticky s KDE. +Comment[sl]=Upravljanje programov, ki se samodejno zaženejo ob zagonu KDE. +Comment[sr]=Одредите који се програми покрећу са КДЕ‑ом по пријављивању. +Comment[sr@ijekavian]=Одредите који се програми покрећу са КДЕ‑ом по пријављивању. +Comment[sr@ijekavianlatin]=Odredite koji se programi pokreću sa KDE‑om po prijavljivanju. +Comment[sr@latin]=Odredite koji se programi pokreću sa KDE‑om po prijavljivanju. +Comment[sv]=Hantera vilka program som startas automatiskt när KDE startas. +Comment[tr]=Hangi programların KDE açılırken otomatik olarak başlatılacağını yönetin. +Comment[uk]=Керування програмами, які будуть запускатися разом з графічним середовищем KDE автоматично. +Comment[x-test]=xxManage which programs start up automatically with KDE.xx +Comment[zh_CN]=管理随 KDE 自动启动的程序 +Comment[zh_TW]=管理 KDE 要自動啟動哪些程式。 + +X-KDE-Keywords=Autostart Manager,autostart,startup,system startup,kde start,cron +X-KDE-Keywords[bs]=automatsko pokretanje upravitelja,automatsko pokretanje,pokretanje,sustav za pokretanje,početak kde,kompjuter izvodi zadatak za određeno vrijeme. +X-KDE-Keywords[ca]=Gestor d'inici automàtic,inici automàtic,inici,inici del sistema,inici del kde,cron +X-KDE-Keywords[ca@valencia]=Gestor d'inici automàtic,inici automàtic,inici,inici del sistema,inici del kde,cron +X-KDE-Keywords[da]=autostart,opstart,systemstart,kde start,cron +X-KDE-Keywords[de]=Autostartverwaltung,Autostart,Startvorgang,Systemstart,KDE-Start,Cron +X-KDE-Keywords[el]=διαχειριστής αυτόματης εκκίνησης,αυτόματη εκκίνηση,έναρξη,έναρξη συστήματος,έναρξη kde,cron +X-KDE-Keywords[en_GB]=Autostart Manager,autostart,startup,system startup,kde start,cron +X-KDE-Keywords[es]=Gestor de inicio automático,inicio automático,inicio,inicio del sistema,inicio de kde,cron +X-KDE-Keywords[et]=Autostardi haldur,autostart,käivitamine,süsteemi käivitamine,kde käivitamine,cron +X-KDE-Keywords[eu]=Hasiera automatikoaren kudeatzailea,hasiera automatikoa,abiarazi,sistema abiarazi,kde hasi,cron +X-KDE-Keywords[fi]=automaattikäynnistys,hallinta,käynnistys,järjestelmän käynnistys, järjestelmän käynnistyminen,kde:n käynnistys,kde:n käynnistyminen,cron +X-KDE-Keywords[fr]=Gestionnaire de démarrage, démarrage automatique, démarrage, démarrage du système, démarrage de kde, cron +X-KDE-Keywords[gl]=Xestor de inicio, inicio automático, inicio, sistema de arranque, inicio de kde, cron +X-KDE-Keywords[he]=Autostart Manager,autostart,startup,system startup,kde start,cron,הפעלה,התחלה +X-KDE-Keywords[hu]=Automatikus indítás kezelő,automatikus indítás,indulás,rendszerindulás,kde indulás,cron +X-KDE-Keywords[ia]=Gestor de autoinitio,autoinitio,initio,initio de systema.initio de kde,crom +X-KDE-Keywords[it]=Gestore avvio,avvio automatico,avvio,avvio del sistema,avvio di kde,cron +X-KDE-Keywords[kk]=Autostart Manager,autostart,startup,system startup,kde start,cron +X-KDE-Keywords[km]=ចាប់ផ្ដើម​កម្មវិធី​គ្រប់គ្រង​ដោយ​ស្វ័យ​ប្រវត្តិ ចាប់ផ្ដើម​ស្វ័យ​ប្រវត្តិ ចាប់ផ្ដើម ចាប់ផ្ដើម​ប្រព័ន្ធ ចាប់ផ្ដើម kde cron +X-KDE-Keywords[ko]=Autostart Manager,autostart,startup,system startup,kde start,cron,자동 시작,자동시작,시작프로그램,시스템 시작 +X-KDE-Keywords[lt]=Automatinio paleidimo tvarkyklė,automatinis paleidimas, sistemos paleidimas,kde paleidimas,cron +X-KDE-Keywords[mr]=स्वप्रारंभ व्यवस्थापक, स्वप्रारंभ, सुरुवात, सुरुवात प्रणाली, kde सुरुवात, क्रॉन +X-KDE-Keywords[nb]=Autostartbehandler,autostart,oppstart,systemstart,kde-start,cron +X-KDE-Keywords[nds]=Autostartpleger,Autostart,Starten,Hoochfohren,KDE-Start,Cron +X-KDE-Keywords[nl]=Autostartbeheerder,autostarten,opstarten,opstarten systeem,opstarten kde,cron +X-KDE-Keywords[pl]=Menadżer autostartu,autostart,uruchamianie,uruchamianie systemu,kde start,cron +X-KDE-Keywords[pt]=Gestor de arranque,arranque,início,arranque do sistema,início do kde,cron +X-KDE-Keywords[pt_BR]=Gerenciado de inicialização,inicialização,início,inicialização do sistema,início do kde,cron +X-KDE-Keywords[ru]=Autostart Manager,autostart,startup,system startup,kde start,cron,диспетчер автоматического запуска,автоматический запуск,автозапуск,загрузка системы,запуск kde +X-KDE-Keywords[sk]=Správca automatického spustenia,autostart,spustenie,spustenie systému,štart kde,cron +X-KDE-Keywords[sl]=upravljalnik samodejnega zagona,samodejni zagon,zagon,sistemski zagon,zagon kde,zagon sistema,cron +X-KDE-Keywords[sr]=Autostart Manager,autostart,startup,system startup,kde start,cron,самопокретање,менаџер самопокретања,покретање система +X-KDE-Keywords[sr@ijekavian]=Autostart Manager,autostart,startup,system startup,kde start,cron,самопокретање,менаџер самопокретања,покретање система +X-KDE-Keywords[sr@ijekavianlatin]=Autostart Manager,autostart,startup,system startup,kde start,cron,samopokretanje,menadžer samopokretanja,pokretanje sistema +X-KDE-Keywords[sr@latin]=Autostart Manager,autostart,startup,system startup,kde start,cron,samopokretanje,menadžer samopokretanja,pokretanje sistema +X-KDE-Keywords[sv]=Hantering av autostart,autostart,start,systemstart,kde-start,cron +X-KDE-Keywords[tr]=Otomatik Başlatma Yöneticisi, otomatik,başlatma,sistem başlangıcı,kde başlangıcı,görevler,cron +X-KDE-Keywords[uk]=Autostart Manager,autostart,startup,system startup,kde start,cron,керування автозапуском,автозапуск,запуск,запуск системи,запуск kde +X-KDE-Keywords[vi]=trình quản lý tự động chạy,tự động chạy,khởi động,khởi động hệ thống,chạy kde,cron +X-KDE-Keywords[x-test]=xxAutostart Manager,autostart,startup,system startup,kde start,cronxx +X-KDE-Keywords[zh_CN]=Autostart Manager,autostart,startup,system startup,kde start,cron,自动启动管理器,自动启动,启动,系统启动,kde 启动,任务调度 +X-KDE-Keywords[zh_TW]=Autostart Manager,autostart,startup,system startup,kde start,cron diff --git a/kcontrol/autostart/autostart.h b/kcontrol/autostart/autostart.h new file mode 100644 index 00000000..f429b71e --- /dev/null +++ b/kcontrol/autostart/autostart.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 by Stephen Leaf * + * smileaf@gmail.com * + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + + +#ifndef AUTOSTART_H +#define AUTOSTART_H + +#include +#include + +#include +#include + +#include "ui_autostartconfig.h" +#include "autostartitem.h" + +class Autostart: public KCModule +{ + Q_OBJECT + +public: + Autostart( QWidget* parent, const QVariantList& ); + ~Autostart(); + enum COL_TYPE { COL_NAME = 0, COL_COMMAND=1, COL_STATUS=2,COL_RUN=3 }; + void load(); + void save(); + void defaults(); + + QStringList listPathName() const { return m_pathName;} + +public slots: + void slotChangeStartup( ScriptStartItem* item, int index ); + +protected: + void addItem(DesktopStartItem *item, const QString& name, const QString& run, const QString& command, bool disabled ); + void addItem(ScriptStartItem *item, const QString& name, const QString& command, ScriptStartItem::ENV type ); + +private slots: + void slotAddProgram(); + void slotAddScript(); + void slotRemoveCMD(); + void slotEditCMD(QTreeWidgetItem*); + bool slotEditCMD(const KFileItem&); + void slotEditCMD(); + void slotSelectionChanged(); + void slotItemClicked( QTreeWidgetItem *, int); + void slotAdvanced(); + +private: + QTreeWidgetItem *m_programItem, *m_scriptItem; + QStringList m_paths; + QStringList m_pathName; + + Ui_AutostartConfig *widget; +}; + +#endif diff --git a/kcontrol/autostart/autostartconfig.ui b/kcontrol/autostart/autostartconfig.ui new file mode 100644 index 00000000..6dfdb8b8 --- /dev/null +++ b/kcontrol/autostart/autostartconfig.ui @@ -0,0 +1,82 @@ + + AutostartConfig + + + + 0 + 0 + 553 + 384 + + + + + + + false + + + false + + + + + + + Add Program... + + + + + + + Add Script... + + + + + + + &Remove + + + + + + + &Properties... + + + + + + + Qt::Vertical + + + + 79 + 141 + + + + + + + + Qt::Horizontal + + + + + + + Advanced... + + + + + + + + diff --git a/kcontrol/autostart/autostartitem.cpp b/kcontrol/autostart/autostartitem.cpp new file mode 100644 index 00000000..f052d709 --- /dev/null +++ b/kcontrol/autostart/autostartitem.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "autostartitem.h" +#include "autostart.h" + +#include +#include +#include +#include + +#include +#include +#include + +AutoStartItem::AutoStartItem( const QString &service, QTreeWidgetItem *parent, Autostart* ) + : QTreeWidgetItem( parent ) +{ + m_fileName = KUrl(service); +} + +AutoStartItem::~AutoStartItem() +{ + +} + +KUrl AutoStartItem::fileName() const +{ + return m_fileName; +} + +void AutoStartItem::setPath(const QString &path) +{ + Q_ASSERT( path.endsWith(QDir::separator()) ); + + if (path == m_fileName.directory(KUrl::AppendTrailingSlash)) + return; + + const QString& newFileName = path + m_fileName.fileName(); + KIO::move(m_fileName, KUrl(newFileName)); + + m_fileName = KUrl(newFileName); +} + +DesktopStartItem::DesktopStartItem( const QString &service, QTreeWidgetItem *parent, Autostart*autostart ) + : AutoStartItem( service, parent,autostart ) +{ + setCheckState ( Autostart::COL_STATUS,Qt::Checked ); +} + +DesktopStartItem::~DesktopStartItem() +{ +} + +ScriptStartItem::ScriptStartItem( const QString &service, QTreeWidgetItem *parent, Autostart* autostart ) + : AutoStartItem( service, parent,autostart ) +{ + m_comboBoxStartup = new QComboBox; + m_comboBoxStartup->addItems( autostart->listPathName() ); + + setText( 2, i18nc( "The program will be run", "Enabled" ) ); + QObject::connect( m_comboBoxStartup,SIGNAL(activated(int)),this,SLOT(slotStartupChanged(int)) ); + QObject::connect( this,SIGNAL(askChangeStartup(ScriptStartItem*,int)),autostart,SLOT(slotChangeStartup(ScriptStartItem*,int)) ); + treeWidget()->setItemWidget ( this, Autostart::COL_RUN, m_comboBoxStartup ); +} + +ScriptStartItem::~ScriptStartItem() +{ +} + +void ScriptStartItem::slotStartupChanged(int index) +{ + emit askChangeStartup(this, index); +} + +void ScriptStartItem::changeStartup(ScriptStartItem::ENV type ) +{ + switch( type ) + { + case ScriptStartItem::START: + m_comboBoxStartup->setCurrentIndex( 0 ); + break; + case ScriptStartItem::SHUTDOWN: + m_comboBoxStartup->setCurrentIndex( 1 ); + break; + case ScriptStartItem::PRE_START: + m_comboBoxStartup->setCurrentIndex( 2 ); + break; + default: + kWarning() << " startup type is not defined :" << type; + break; + } +} + +#include "autostartitem.moc" diff --git a/kcontrol/autostart/autostartitem.h b/kcontrol/autostart/autostartitem.h new file mode 100644 index 00000000..85622e87 --- /dev/null +++ b/kcontrol/autostart/autostartitem.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef AUTOSTARTITEM_H +#define AUTOSTARTITEM_H + +#include +#include +#include + +class QComboBox; +class QTreeWidget; +class Autostart; + +class AutoStartItem : public QTreeWidgetItem, public QObject +{ +public: + AutoStartItem( const QString &service, QTreeWidgetItem *parent, Autostart* ); + ~AutoStartItem(); + + KUrl fileName() const; + + void setPath(const QString &path); + +private: + KUrl m_fileName; +}; + +class DesktopStartItem : public AutoStartItem +{ +public: + DesktopStartItem( const QString &service, QTreeWidgetItem *parent, Autostart* ); + ~DesktopStartItem(); +}; + + +class ScriptStartItem : public AutoStartItem +{ + Q_OBJECT + +public: + enum ENV { START=0, SHUTDOWN=1, PRE_START=2}; //rename + ScriptStartItem( const QString &service, QTreeWidgetItem *parent, Autostart* ); + ~ScriptStartItem(); + + void changeStartup( ScriptStartItem::ENV type ); + +signals: + void askChangeStartup(ScriptStartItem* item, int index); + +private slots: + + void slotStartupChanged(int index); + +private: + QComboBox *m_comboBoxStartup; +}; + +#endif diff --git a/kcontrol/bell/CMakeLists.txt b/kcontrol/bell/CMakeLists.txt new file mode 100644 index 00000000..8665c78d --- /dev/null +++ b/kcontrol/bell/CMakeLists.txt @@ -0,0 +1,21 @@ + + + +########### next target ############### + +set(kcm_bell_PART_SRCS bell.cpp ) + + +kde4_add_plugin(kcm_bell ${kcm_bell_PART_SRCS}) + + +target_link_libraries(kcm_bell ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY} ${X11_X11_LIB}) + +install(TARGETS kcm_bell DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES bell.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + +kde4_install_icons( ${ICON_INSTALL_DIR} ) diff --git a/kcontrol/bell/Messages.sh b/kcontrol/bell/Messages.sh new file mode 100644 index 00000000..cb6a4782 --- /dev/null +++ b/kcontrol/bell/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/kcmbell.pot diff --git a/kcontrol/bell/bell.cpp b/kcontrol/bell/bell.cpp new file mode 100644 index 00000000..3d9395f6 --- /dev/null +++ b/kcontrol/bell/bell.cpp @@ -0,0 +1,253 @@ +/* + Copyright (c) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) + 1998 Bernd Wuebben + 2000 Matthias Elter + 2001 Carsten PFeiffer + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include + + +//Added by qt3to4: +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bell.h" +#include "bell.moc" + +#include +#include +#include +#include + + + +K_PLUGIN_FACTORY(KBellConfigFactory, registerPlugin();) +K_EXPORT_PLUGIN(KBellConfigFactory("kcmbell")) + + + +extern "C" +{ + KDE_EXPORT void kcminit_bell() + { + XKeyboardState kbd; + XKeyboardControl kbdc; + + XGetKeyboardControl(QX11Info::display(), &kbd); + + KConfig _config( "kcmbellrc", KConfig::NoGlobals ); + KConfigGroup config(&_config, "General"); + + kbdc.bell_percent = config.readEntry("Volume", kbd.bell_percent); + kbdc.bell_pitch = config.readEntry("Pitch", kbd.bell_pitch); + kbdc.bell_duration = config.readEntry("Duration", kbd.bell_duration); + XChangeKeyboardControl(QX11Info::display(), + KBBellPercent | KBBellPitch | KBBellDuration, + &kbdc); + } +} + +KBellConfig::KBellConfig(QWidget *parent, const QVariantList &args): + KCModule(KBellConfigFactory::componentData(), parent, args) +{ + QBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + + QGroupBox *box = new QGroupBox(i18n("Bell Settings"), this ); + QFormLayout *form = new QFormLayout(); + box->setLayout(form); + layout->addWidget(box); + + m_useBell = new QCheckBox( i18n("&Use system bell instead of system notification" ), box ); + m_useBell->setWhatsThis( i18n("You can use the standard system bell (PC speaker) or a " + "more sophisticated system notification, see the " + "\"System Notifications\" control module for the " + "\"Something Special Happened in the Program\" event.")); + connect(m_useBell, SIGNAL(toggled(bool)), SLOT(useBell(bool))); + form->addRow(m_useBell); + + setQuickHelp( i18n("

    System Bell

    Here you can customize the sound of the standard system bell," + " i.e. the \"beep\" you always hear when there is something wrong. Note that you can further" + " customize this sound using the \"Accessibility\" control module; for example, you can choose" + " a sound file to be played instead of the standard bell.")); + + m_volume = new KIntNumInput(50, box); + m_volume->setRange(0, 100, 5); + m_volume->setSuffix("%"); + m_volume->setSteps(5,25); + form->addRow(i18n("&Volume:"), m_volume); + m_volume->setWhatsThis( i18n("Here you can customize the volume of the system bell. For further" + " customization of the bell, see the \"Accessibility\" control module.") ); + + m_pitch = new KIntNumInput(800, box); + m_pitch->setRange(20, 2000, 20); + m_pitch->setSuffix(i18n(" Hz")); + m_pitch->setSteps(40,200); + form->addRow(i18n("&Pitch:"), m_pitch); + m_pitch->setWhatsThis( i18n("Here you can customize the pitch of the system bell. For further" + " customization of the bell, see the \"Accessibility\" control module.") ); + + m_duration = new KIntNumInput(100, box); + m_duration->setRange(1, 1000, 50); + m_duration->setSuffix(i18n(" msec")); + m_duration->setSteps(20,100); + form->addRow(i18n("&Duration:"), m_duration); + m_duration->setWhatsThis( i18n("Here you can customize the duration of the system bell. For further" + " customization of the bell, see the \"Accessibility\" control module.") ); + + m_testButton = new QPushButton(i18n("&Test"), box); + m_testButton->setObjectName("test"); + form->addRow(QString(), m_testButton); + connect( m_testButton, SIGNAL(clicked()), SLOT(ringBell())); + m_testButton->setWhatsThis( i18n("Click \"Test\" to hear how the system bell will sound using your changed settings.") ); + + // watch for changes + connect(m_volume, SIGNAL(valueChanged(int)), SLOT(changed())); + connect(m_pitch, SIGNAL(valueChanged(int)), SLOT(changed())); + connect(m_duration, SIGNAL(valueChanged(int)), SLOT(changed())); + + KAboutData *about = + new KAboutData(I18N_NOOP("kcmbell"), 0, ki18n("KDE Bell Control Module"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 1997 - 2001 Christian Czezatke, Matthias Elter")); + + about->addAuthor(ki18n("Christian Czezatke"), ki18n("Original author"), "e9025461@student.tuwien.ac.at"); + about->addAuthor(ki18n("Bernd Wuebben"), KLocalizedString(), "wuebben@kde.org"); + about->addAuthor(ki18n("Matthias Elter"), ki18n("Current maintainer"), "elter@kde.org"); + about->addAuthor(ki18n("Carsten Pfeiffer"), KLocalizedString(), "pfeiffer@kde.org"); + setAboutData(about); +} + +void KBellConfig::load() +{ + XKeyboardState kbd; + XGetKeyboardControl(QX11Info::display(), &kbd); + + m_volume->setValue(kbd.bell_percent); + m_pitch->setValue(kbd.bell_pitch); + m_duration->setValue(kbd.bell_duration); + + KConfig _cfg("kdeglobals", KConfig::NoGlobals); + KConfigGroup cfg(&_cfg, "General"); + m_useBell->setChecked(cfg.readEntry("UseSystemBell", false)); + useBell(m_useBell->isChecked()); + emit changed(false); +} + +void KBellConfig::save() +{ + XKeyboardControl kbd; + + int bellVolume = m_volume->value(); + int bellPitch = m_pitch->value(); + int bellDuration = m_duration->value(); + + kbd.bell_percent = bellVolume; + kbd.bell_pitch = bellPitch; + kbd.bell_duration = bellDuration; + XChangeKeyboardControl(QX11Info::display(), + KBBellPercent | KBBellPitch | KBBellDuration, + &kbd); + + KConfig _config("kcmbellrc", KConfig::NoGlobals); + KConfigGroup config(&_config, "General"); + config.writeEntry("Volume",bellVolume); + config.writeEntry("Pitch",bellPitch); + config.writeEntry("Duration",bellDuration); + + config.sync(); + + KConfig _cfg("kdeglobals", KConfig::NoGlobals); + KConfigGroup cfg(&_cfg, "General"); + cfg.writeEntry("UseSystemBell", m_useBell->isChecked()); + cfg.sync(); + + if (!m_useBell->isChecked()) + { + KConfig config("kaccessrc"); + + KConfigGroup group = config.group("Bell"); + group.writeEntry("SystemBell", false); + group.writeEntry("ArtsBell", false); + group.writeEntry("VisibleBell", false); + } +} + +void KBellConfig::ringBell() +{ + if (!m_useBell->isChecked()) { + KNotification::beep(QString(), this); + return; + } + + // store the old state + XKeyboardState old_state; + XGetKeyboardControl(QX11Info::display(), &old_state); + + // switch to the test state + XKeyboardControl kbd; + kbd.bell_percent = m_volume->value(); + kbd.bell_pitch = m_pitch->value(); + if (m_volume->value() > 0) + kbd.bell_duration = m_duration->value(); + else + kbd.bell_duration = 0; + XChangeKeyboardControl(QX11Info::display(), + KBBellPercent | KBBellPitch | KBBellDuration, + &kbd); + // ring bell + XBell(QX11Info::display(),0); + + // restore old state + kbd.bell_percent = old_state.bell_percent; + kbd.bell_pitch = old_state.bell_pitch; + kbd.bell_duration = old_state.bell_duration; + XChangeKeyboardControl(QX11Info::display(), + KBBellPercent | KBBellPitch | KBBellDuration, + &kbd); +} + +void KBellConfig::defaults() +{ + m_volume->setValue(100); + m_pitch->setValue(800); + m_duration->setValue(100); + m_useBell->setChecked( false ); + useBell( false ); +} + +void KBellConfig::useBell( bool on ) +{ + m_volume->setEnabled( on ); + m_pitch->setEnabled( on ); + m_duration->setEnabled( on ); + m_testButton->setEnabled( on ); + changed(); +} diff --git a/kcontrol/bell/bell.desktop b/kcontrol/bell/bell.desktop new file mode 100644 index 00000000..16d8ac08 --- /dev/null +++ b/kcontrol/bell/bell.desktop @@ -0,0 +1,239 @@ +[Desktop Entry] +Exec=kcmshell4 bell +Icon=preferences-desktop-notification-bell +Type=Service +X-KDE-ServiceTypes=KCModule,KCModuleInit +X-DocPath=kcontrol/bell/index.html +Categories=Qt;KDE;X-KDE-settings-sound; + +X-KDE-Library=kcm_bell +X-KDE-Init-Symbol=bell +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=application-and-system-notifications +X-KDE-Weight=60 + +Name=System Bell +Name[af]=Stelsel Klok +Name[ar]=جرس النظام +Name[ast]=Pitíu del sistema +Name[be]=Сістэмны званок +Name[be@latin]=Systemny hukavy syhnał +Name[bg]=Системен звук +Name[bn]=সিস্টেম ঘণ্টা +Name[bn_IN]=সিস্টেমের ঘন্টা +Name[br]=Kloc'h ar reizhiad +Name[bs]=Sistemsko zvono +Name[ca]=Timbre del sistema +Name[ca@valencia]=Timbre del sistema +Name[cs]=Systémový zvonek +Name[csb]=Systemowi brzãczk +Name[cy]=Cloch Cysawd +Name[da]=Systemklokke +Name[de]=Signalton +Name[el]=Μεγαφωνάκι συστήματος +Name[en_GB]=System Bell +Name[eo]=Sistempepo +Name[es]=Timbre del sistema +Name[et]=Süsteemne signaal +Name[eu]=Sistemaren soinua +Name[fa]=زنگ سیستم +Name[fi]=Järjestelmän varoitus +Name[fr]=Cloche du système +Name[fy]=Systeembel +Name[ga]=Cloigín an Chórais +Name[gl]=Badalada do sistema +Name[gu]=સિસ્ટમ ઘંટડી +Name[he]=פעמון המערכת +Name[hi]=तंत्र घंटी +Name[hne]=तंत्र घंटी +Name[hr]=Sistemsko zvono +Name[hsb]=Systemowy zwónčk +Name[hu]=Rendszercsengő +Name[ia]=Campana de systema +Name[id]=Bel Sistem +Name[is]=Kerfisbjalla +Name[it]=Campanella di sistema +Name[ja]=システムベル +Name[ka]=სისტემის ხმოვანი სიგნალი +Name[kk]=Жүйелік қоңырау +Name[km]=កណ្ដឹង​ប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥಾ ಗಂಟೆ +Name[ko]=시스템 종소리 +Name[ku]=Zingila Pergalê +Name[lt]=Sistemos skambutis +Name[lv]=Sistēmas zvans +Name[mai]=तंत्र घंटी +Name[mk]=Системско ѕвонче +Name[ml]=സിസ്റ്റം മണി +Name[mr]=प्रणाली घंटी +Name[ms]=Loceng Sistem +Name[nb]=Systemlyd +Name[nds]=Systeempingel +Name[ne]=प्रणाली बेल +Name[nl]=Systeembel +Name[nn]=Systemlyd +Name[or]=ତନ୍ତ୍ର ଘଣ୍ଟି +Name[pa]=ਸਿਸਟਮ ਘੰਟੀ +Name[pl]=Brzęczyk systemowy +Name[pt]=Campainha do Sistema +Name[pt_BR]=Campainha do sistema +Name[ro]=Clopoțel de sistem +Name[ru]=Системный звуковой сигнал +Name[se]=Vuogádatjietna +Name[si]=පද්ධති සීනුව +Name[sk]=Zvonček +Name[sl]=Sistemski zvonec +Name[sr]=Системско звоно +Name[sr@ijekavian]=Системско звоно +Name[sr@ijekavianlatin]=Sistemsko zvono +Name[sr@latin]=Sistemsko zvono +Name[sv]=Systemsummer +Name[ta]=அமைப்பு மணி +Name[te]=వ్యవస్థ గంట +Name[tg]=Системаи занг +Name[th]=ออดระบบ +Name[tr]=Sistem Zili +Name[ug]=سىستېما قوڭغۇراق ئاۋازى +Name[uk]=Системний дзвінок +Name[uz]=Tizim tovush signali +Name[uz@cyrillic]=Тизим товуш сигнали +Name[vi]=Chuông hệ thống +Name[wa]=Xhuflet do sistinme +Name[xh]=Indlela yokusebenza Yentsimbi +Name[x-test]=xxSystem Bellxx +Name[zh_CN]=系统铃声 +Name[zh_TW]=系統鈴聲 + +Comment=System Bell Configuration +Comment[af]=Stelsel Klok Opstelling +Comment[ar]=إعداد جرس النظام +Comment[ast]=Configuración del pitíu del sistema +Comment[be]=Настаўленне сістэмнага званка +Comment[be@latin]=Nałady systemnaha hukavoha syhnału +Comment[bg]=Настройване звуковия сигнал на системата +Comment[bn]=সিস্টেম ঘণ্টা কনফিগারেশন +Comment[bn_IN]=সিস্টেমের ঘন্টা সংক্রান্ত কনফিগারেশন +Comment[br]=Kefluniañ kloc'h ar reizhiad +Comment[bs]=Postava sistemskog zvona +Comment[ca]=Configuració del timbre del sistema +Comment[ca@valencia]=Configuració del timbre del sistema +Comment[cs]=Nastavení systémového zvonku +Comment[csb]=Kònfigùracëjô systemòwégò brzãczka +Comment[cy]=Gosodiadau'r Cloch Cysawd +Comment[da]=Systemklokkeindstilling +Comment[de]=Einstellungen zum Signalton +Comment[el]=Διαμόρφωση για το μεγαφωνάκι του συστήματός σας +Comment[en_GB]=System Bell Configuration +Comment[eo]=Agordo de la sistempepo +Comment[es]=Configuración del timbre del sistema +Comment[et]=Süsteemse signaali seadistamine +Comment[eu]=Sistemaren soinuaren konfigurazioa +Comment[fa]=پیکربندی زنگ سیستم +Comment[fi]=Järjestelmän varoitusäänen asetus +Comment[fy]=Systeemlûden ynstelle +Comment[ga]=Cumraíocht Chloigín an Chórais +Comment[gl]=Configuración da badalada do sistema +Comment[gu]=સિસ્ટમ ઘંટડી રૂપરેખાંકન +Comment[he]=הגדרות פעמון המערכת +Comment[hi]=तंत्र घंटी कॉन्फ़िगरेशन +Comment[hne]=तंत्र घंटी कान्फिगरेसन +Comment[hr]=Konfiguracija sistemskog zvona +Comment[hsb]=Připrawjenje systemoweho zwónčka +Comment[hu]=A rendszercsengő beállításai +Comment[ia]=Configuration del campana de systema +Comment[id]=Konfigurasi Bel Sistem +Comment[is]=Stillingar kerfishljóða +Comment[ka]=სისტემის ხმოვანი სიგნალის კონფიგურაცია +Comment[kk]=Жүйелік қоңырауды баптау +Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​កណ្ដឹង​ប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥಾ ಗಂಟೆ ಸಂರಚನೆ +Comment[ko]=시스템 종소리 설정 +Comment[ku]=Veavakirina Zingila Pergalê +Comment[lt]=Sistemos skambučio derinimas +Comment[lv]=Sistēmas zvana konfigurācija +Comment[mai]=तंत्र घंटी कान्फिगरेशन +Comment[mk]=Конфигурација на системското ѕвонче +Comment[ml]=സിസ്റ്റത്തിന്റെ മണിയ്ക്കുള്ള ക്രമീകരണം +Comment[mr]=प्रणाली घंटी संयोजना +Comment[ms]=Konfigurasi Loceng Sistem +Comment[nb]=Systemlydoppsett +Comment[nds]=Systeempingel instellen +Comment[ne]=प्रणाली बेल कन्फिगरेसन +Comment[nl]=Systeemgeluiden instellen +Comment[nn]=Systemlydoppsett +Comment[or]=ତନ୍ତ୍ର ଘଣ୍ଟି ସଂରଚନା +Comment[pa]=ਸਿਸਟਮ ਘੰਟੀ ਸੰਰਚਨਾ +Comment[pl]=Ustawienia brzęczka systemowego +Comment[pt]=Configuração da Campainha do Sistema +Comment[pt_BR]=Configuração da campainha do sistema +Comment[ro]=Configurare Clopoțel de sistem +Comment[ru]=Настройка системного звукового сигнала +Comment[se]=Vuogádatjietnaheivehusat +Comment[si]=පද්ධති සීනු සැකසුම් +Comment[sk]=Nastavenie zvončeka +Comment[sl]=Nastavitve sistemskega zvonca +Comment[sr]=Постава системског звона +Comment[sr@ijekavian]=Постава системског звона +Comment[sr@ijekavianlatin]=Postava sistemskog zvona +Comment[sr@latin]=Postava sistemskog zvona +Comment[sv]=Anpassa systemets summer +Comment[ta]=அமைப்பின் மணி வடிவமைப்பு +Comment[te]=సిస్టమ్ బెల్ సాధనం +Comment[tg]=Танзимоти системаи занг +Comment[th]=ปรับแต่งออดระบบ +Comment[tr]=Sistem Zili Yapılandırması +Comment[ug]=سىستېما قوڭغۇرىقى سەپلىمىسى +Comment[uk]=Налаштування системного дзвінка +Comment[uz]=Tizim tovush signalini moslash +Comment[uz@cyrillic]=Тизим товуш сигналини мослаш +Comment[vi]=Cấu hình Chuông Hệ thống +Comment[wa]=Apontiaedje do xhuflet do sistinme +Comment[xh]=Uqwalaselo Lwendlela Yentsimbi +Comment[x-test]=xxSystem Bell Configurationxx +Comment[zh_CN]=系统铃声配置 +Comment[zh_TW]=系統鈴聲組態 + +X-KDE-Keywords=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker +X-KDE-Keywords[bs]=zvono,zvučni,zvuk,glasnoća,igralište,trajanje,visina tona,trajanje,PC zvučnici,unutarnji zvučnik,zvučnik,sustav zvona,sustav zvučnika,unutarnji PC zvučnik +X-KDE-Keywords[ca]=Campana,Àudio,So,Volum,To,Durada,Altaveu del PC,Altaveu intern,Altaveu,Campana del sistema,Altaveu del sistema,Altaveu intern del PC +X-KDE-Keywords[ca@valencia]=Campana,Àudio,So,Volum,To,Durada,Altaveu del PC,Altaveu intern,Altaveu,Campana del sistema,Altaveu del sistema,Altaveu intern del PC +X-KDE-Keywords[da]=Klokke,lyd,lydstyrke,volume,tone,varighed,pc-højtaler,intern højtaler,højtaler,systemklokke,systemhøjtaler,intern pc-højtaler +X-KDE-Keywords[de]=Signalton,Systemton,Klänge,Audio,Sound,Dauer,Lautstärke,Höhen,PC-Lautsprecher,Interner Lautsprecher,Lautsprecher,Systemsignalton,System-Lautsprecher,Interner PC-Lautsprecher +X-KDE-Keywords[el]=μεγαφωνάκι,ήχος,ήχος,ένταση,τόνος,διάρκεια,ηχείο PC,εσωτερικό ηχείο,ηχείο,κουδούνι συστήματος,ηχείο συστήματος,εσωτερικό ηχείο PC +X-KDE-Keywords[en_GB]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker +X-KDE-Keywords[es]=Campana,Audio,Sonido,Volumen,Pitch,Duración,Altavoz del PC,Altavoz interno,Altavoz,Campana del sistema,Altavoz del sistema,Altavoz interno del PC +X-KDE-Keywords[et]=Kell,audio,heli,helitugevus,toon,kestus,arvutikõlar,PC kõlar,kõlar,sisemine kõlar,süsteemne piiks,süsteemi piiks,süsteemi kõlar,PC sisemine kõlar +X-KDE-Keywords[eu]=kanpai,audio,soinu,bolumen,tonu,iraupen,PC bozgorailu,barneko bozgorailu,bozgorailu,sistemaren soinu,sistemaren bozgorailu, PC barneko bozgorailu +X-KDE-Keywords[fi]=varoitus,äänimerkki,ääni,äänenvoimakkuus,äänenkorkeus,kesto,PC-kaiutin,sisäinen kaiutin,kaiutin,järjestelmän äänimerkki,järjestelmäkaiutin,sisäinen PC-kaiutin +X-KDE-Keywords[fr]=Cloche, Audio, Son, Volume, Pas, Durée, Haut-parleur du PC, Haut-parleur interne, Haut parleur, Cloche du système, Haut-parleur du système, Haut-parleur interne du PC +X-KDE-Keywords[gl]=Badalada, campá, son, volume, altofalante, badalada do sistema +X-KDE-Keywords[he]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,ספיקר, שמע, משך, פעמון, גובה +X-KDE-Keywords[hu]=Csengő,Audio,Hang,Hangerő,Hangmagasság,Időtartam,PC hangszóró,Belső hangszóró,Hangszóró,Rendszercsengő,Rendszer hangszóró,Belső PC hangszóró +X-KDE-Keywords[ia]=Campana,Audio,Sono,Volumine,Accordatura,Duration,altoparlator de PC,altoparlator interne, Altoparlator,Campana de systema,altoparlator de systema,Altoparlator de PC interne +X-KDE-Keywords[it]=Campanella,Audio,Suono,Volume,Altezza,Durata,Altoparlanti PC,Altoparlanti interni,Altoparlante,Campanella di sistema,Altoparlanti di sistema,Altoparlanti interni pc +X-KDE-Keywords[kk]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker +X-KDE-Keywords[km]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker +X-KDE-Keywords[ko]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,오디오,사운드,음량,시간,스피커 +X-KDE-Keywords[mr]=घंटी, श्राव्य, ध्वनी, आवाज, आवाजाचा स्तर, अवधी, पी.सी.स्पीकर , इंटर्नल स्पीकर, स्पीकर प्रणाली घंटी, प्रणाली स्पीकर, अंतर्गत पी.सी. स्पीकर +X-KDE-Keywords[nb]=Bjelle, Lyd,Lydstyrke,Tone,Varighet,PC-høyttaler,Intern høyttaler,Høyttaler,Systembjelle,Systemhøyttaler, Intern PC-høyttaler +X-KDE-Keywords[nds]=Pingel,Kläng,Klang,Luutstärk,Toonhööchd,Duer,PC-Luutspreker,intern Luutspreker,Luutspreker,Systempingel,System-Luutspreker,intern PC-Luutspreker +X-KDE-Keywords[nl]=Bel,audio,geluid,volume,toonhoogte,duur,PC-speaker,interne speaker,speaker,systeembel,systeemspeaker,interne PC-speaker +X-KDE-Keywords[pl]=Dzwonek,Audio,Dźwięk,Głośność,Ton,Czas trwania +X-KDE-Keywords[pt]=Campainha,Áudio,Som,Volume,Frequência,Duração,Altifalante do PC,Altifalante Interno,Altifalante,Campainha do Sistema,Altifalante do Sistema,Altifalante Interno do PC +X-KDE-Keywords[pt_BR]=Campainha,Áudio,Som,Volume,Frequência,Duração,Alto-falante do PC,Alto-falante interno,Alto-falante,Campainha do sistema,Alto-falante do sistema,Alto-falante interno do PC +X-KDE-Keywords[ru]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,сигнал,аудио,звук,громкость,высота тона,длительность,колонки,динамики,встроенный динамик,сигнал системы,акустическая система,встроенная акустическая система +X-KDE-Keywords[sk]=Zvonček,zvuk,audio,hlasitosť,výška tónu,trvanie,PC speaker,vnútorný reproduktor,speaker,systémový zvonček,systémový reproduktor,vnútorný PC speaker +X-KDE-Keywords[sl]=zvonec,audio,avdio,zvok,glasnost,ton,višina tona,trajanje,zvočnik,notranji zvočnik,sistemski zvonec,sistemski zvočnik,piskanje,notranji PC zvočnik +X-KDE-Keywords[sr]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,звоно,аудио,звук,јачина,висина,трајање,системско звоно,системски звучник,унутрашњи звучник +X-KDE-Keywords[sr@ijekavian]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,звоно,аудио,звук,јачина,висина,трајање,системско звоно,системски звучник,унутрашњи звучник +X-KDE-Keywords[sr@ijekavianlatin]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,zvono,audio,zvuk,jačina,visina,trajanje,sistemsko zvono,sistemski zvučnik,unutrašnji zvučnik +X-KDE-Keywords[sr@latin]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,zvono,audio,zvuk,jačina,visina,trajanje,sistemsko zvono,sistemski zvučnik,unutrašnji zvučnik +X-KDE-Keywords[sv]=Summer,Ljud,Volym,Tonhöjd,Längd,PC-högtalare,Intern högtalare,Högtalare,Systemsummer,Systemhögtalare,Intern PC-högtalare +X-KDE-Keywords[tr]=Zil,Ses,Ses Düzeyi,Akort,Süre,PC Hoparlörü,İç Hoparlör,Hoparlör,Sistem Zili,Sistem Hoparlörü,Dahili PC Hoparlörü +X-KDE-Keywords[uk]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,дзвінок,гудок,звук,гучність,тон,тривалість,гучномовець,колонки,вбудовані колонки,системний дзвінок,вбудований гучномовець +X-KDE-Keywords[vi]=Chuông,âm thanh,âm lượng,thời lượng,loa PC,loa trong,loa,chuông hệ thống,loa hệ thống, loa PC trong +X-KDE-Keywords[x-test]=xxBell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speakerxx +X-KDE-Keywords[zh_CN]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker,铃声,声音,音量,音调,持续时间,PC 扬声器,内部扬声器,扬声器,PC 喇叭,内部喇叭,喇叭,系统铃声,系统扬声器,系统喇叭,内部 PC 扬声器,内部 PC 喇叭 +X-KDE-Keywords[zh_TW]=Bell,Audio,Sound,Volume,Pitch,Duration,PC Speaker,Internal Speaker,Speaker,System Bell,System Speaker,Internal PC Speaker + diff --git a/kcontrol/bell/bell.h b/kcontrol/bell/bell.h new file mode 100644 index 00000000..fda09b55 --- /dev/null +++ b/kcontrol/bell/bell.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) + 1998 Bernd Wuebben + 2000 Matthias Elter + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __bell_h__ +#define __bell_h__ + +#include "kcmodule.h" + +class QCheckBox; +class KIntNumInput; +class QPushButton; + +class KBellConfig : public KCModule +{ + Q_OBJECT + + public: + KBellConfig(QWidget *parent, const QVariantList &args); + + void load(); + void save(); + void defaults(); + + protected Q_SLOTS: + void ringBell(); + void useBell( bool ); + + private: + QPushButton *m_testButton; + KIntNumInput *m_volume; + KIntNumInput *m_pitch; + KIntNumInput *m_duration; + QCheckBox *m_useBell; +}; + +#endif diff --git a/kcontrol/colors/CMakeLists.txt b/kcontrol/colors/CMakeLists.txt new file mode 100644 index 00000000..9c20d1bc --- /dev/null +++ b/kcontrol/colors/CMakeLists.txt @@ -0,0 +1,16 @@ +KDE4_NO_ENABLE_FINAL(colors) + +set(kcm_colors_PART_SRCS ../krdb/krdb.cpp colorscm.cpp previewwidget.cpp setpreviewwidget.cpp) + +kde4_add_ui_files(kcm_colors_PART_SRCS colorsettings.ui preview.ui setpreview.ui) + +kde4_add_plugin(kcm_colors ${kcm_colors_PART_SRCS}) +target_link_libraries(kcm_colors ${KDE4_KIO_LIBS} ${KDE4_KNEWSTUFF3_LIBS} ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES}) + +install(TARGETS kcm_colors DESTINATION ${PLUGIN_INSTALL_DIR}) +install( FILES colors.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES colorschemes.knsrc DESTINATION ${CONFIG_INSTALL_DIR} ) + +# built-in color schemes +FILE(GLOB schemefiles schemes/*.colors) +install( FILES ${schemefiles} DESTINATION ${DATA_INSTALL_DIR}/color-schemes ) diff --git a/kcontrol/colors/Messages.sh b/kcontrol/colors/Messages.sh new file mode 100644 index 00000000..71fb50be --- /dev/null +++ b/kcontrol/colors/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcmcolors.pot +rm -f rc.cpp diff --git a/kcontrol/colors/README.i18n b/kcontrol/colors/README.i18n new file mode 100644 index 00000000..1033fcb9 --- /dev/null +++ b/kcontrol/colors/README.i18n @@ -0,0 +1,54 @@ +There are two sets of preview strings in the color kcm, with special translation needs. In general, length of the translations, and "gist"-level clarity is more important than precise translation. It should be easy to identify what color role a string represents, but there are size considerations that should be taken into account. The tooltips should be translated normally. + + + +When translating the color kcm, it is helpful to understand the intended meaning of the various color roles in order to chose the best possible translation if more than one would be possible. Hopefully the sets (view, window, button, selection, tooltip) are obvious, as well as normal background/foreground. The others are as follows: + +Alternate [Background]: used in lists when every other row uses a different color; "different". +Inactive: comments, something which is old, unimportant/uninteresting/secondary text +Active: e.g. something new, something active (currently engaged in activity), something requesting attention, a hovered hyperlink +Link: hyperlink, somewhere the user can go, new history +Visited: visited hyperlinks, somewhere the user has been, old history +Negative: "bad", untrusted, unreliable, a mistake, an error the user made, an error that occurred +Neutral: warning, encrypted, anything "between" negative and positive +Positive: success, completion messages, trusted content + +For Link, although other uses are possible, translate as referring to hyperlinks to minimize user confusion. + + + +The "generic" preview uses these strings (all with disambiguation "color-kcm-preview"): +- Window Text +- Push Button +- Normal Text +- Selected Text +- link +- visited +- a +- i +- ! +- = +- + + +The two-word strings may be translated normally, though it is suggested to omit the translation of "Text" if the strings would be excessively (around 20+ characters) long and doing so does not cause confusion (i.e. substantially change the conveyed meaning). The "link" and "visited" strings should be translated according to the notes above, ideally keeping the length to four to eight characters; abbreviation (to not less than four characters if possible) is acceptable as the tooltips will provide more complete descriptions. + +The remaining one-character strings represent (respectively) the text roles active (a), inactive (i), negative (!), neutral (=) and positive (+). These should be translated as one- or two-character strings which uniquely correspond to the aforementioned text roles, ideally taking the first letter of the corresponding translation, or maintaining the symbols (!, =, +) as-is if culturally appropriate. + +Ideographic languages (e.g. Japanese, Mandarin, etc.) where the single-character strings can be replaced with one or two characters representing the full word should do so. These should also, if needed, consider a phonetic representation or relevant phrase for the longer elements, to keep the translations close to the same number of characters as the English. + + + +The "set" preview uses these strings (all with disambiguation "color-kcm-set-preview"): +- normal +- link +- visited +- active +- inactive +- alternate +- negative +- neutral +- positive +- hover +- focus + +These live in a preview widget that is two rows tall by nine items wide, and is often the determining factor in the minimum width of the dialog. For this reason, it is important to keep the strings SHORT. To ensure each text block is of sufficient size to provide an adequate preview, each should be at least a few characters long, but please try to limit them to no more than eight or ten characters on average. Abbreviation is fine and encouraged if necessary to achieve this average. In particular, PLEASE avoid adding the translated equivalent of " text" to these strings if at all possible; the tooltips will disambiguate if required. If these objectives cannot be achieved via direct translation, semantic translation (e.g. "negative" -> i18n("oops!"), "neutral" -> i18n("meh")) would be better. (Ideographic languages, which may need to ADD text to achieve a minimum length, should ignore the previous two sentences.) Note also that "hover" and "focus" are actually "decoration" roles, so e.g. "hover text" is incorrect (should be "hover decoration"). diff --git a/kcontrol/colors/TODO b/kcontrol/colors/TODO new file mode 100644 index 00000000..a0695b9f --- /dev/null +++ b/kcontrol/colors/TODO @@ -0,0 +1,3 @@ +query kwin for what WM colors should be shown for configuring(?) +options (i.e. "things on the first tab") not saved in schemes (in kdeglobals only) +sort schemes list, 'current' at 0, 'default' at 1, everything else sorted (possibly kde3-style, user schemes on top?) diff --git a/kcontrol/colors/colors.desktop b/kcontrol/colors/colors.desktop new file mode 100644 index 00000000..b73ee87f --- /dev/null +++ b/kcontrol/colors/colors.desktop @@ -0,0 +1,194 @@ +[Desktop Entry] +Exec=kcmshell4 colors +Icon=preferences-desktop-color +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/colors/index.html + +X-KDE-Library=kcm_colors +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=application-appearance +X-KDE-Weight=60 + +Name=Colors +Name[af]=Kleure +Name[ar]=الألوان +Name[ast]=Colores +Name[be]=Колеры +Name[be@latin]=Kolery +Name[bg]=Цветове +Name[bn]=রং +Name[bn_IN]=রং +Name[br]=Livioù +Name[bs]=Boje +Name[ca]=Colors +Name[ca@valencia]=Colors +Name[cs]=Barvy +Name[csb]=Farwë +Name[cy]=Lliwiau +Name[da]=Farver +Name[de]=Farben +Name[el]=Χρώματα +Name[en_GB]=Colours +Name[eo]=Koloroj +Name[es]=Colores +Name[et]=Värvid +Name[eu]=Koloreak +Name[fa]=رنگها +Name[fi]=Värit +Name[fr]=Couleurs +Name[fy]=Kleuren +Name[ga]=Dathanna +Name[gl]=Cores +Name[gu]=રંગો +Name[he]=צבעים +Name[hi]=रंग +Name[hne]=रंग +Name[hr]=Boje +Name[hsb]=Barby +Name[hu]=Színek +Name[ia]=Colores +Name[id]=Warna +Name[is]=Litir +Name[it]=Colori +Name[ja]=色 +Name[ka]=ცვეტები +Name[kk]=Түстер +Name[km]=ពណ៌ +Name[kn]=ಬಣ್ಣಗಳು +Name[ko]=색 +Name[ku]=Reng +Name[lt]=Spalvos +Name[lv]=Krāsas +Name[mai]=रँग +Name[mk]=Бои +Name[ml]=നിറങ്ങള്‍ +Name[mr]=रंग +Name[ms]=Warna +Name[nb]=Farger +Name[nds]=Klören +Name[ne]=रङ +Name[nl]=Kleuren +Name[nn]=Fargar +Name[oc]=Colors +Name[or]=ରଙ୍ଗ +Name[pa]=ਰੰਗ +Name[pl]=Kolory +Name[pt]=Cores +Name[pt_BR]=Cores +Name[ro]=Culori +Name[ru]=Цвета +Name[se]=Ivnnit +Name[si]=වර්‍ණ +Name[sk]=Farby +Name[sl]=Barve +Name[sr]=Боје +Name[sr@ijekavian]=Боје +Name[sr@ijekavianlatin]=Boje +Name[sr@latin]=Boje +Name[sv]=Färger +Name[ta]=வண்ணங்கள் +Name[te]=రంగులు +Name[tg]=Рангҳо +Name[th]=สี +Name[tr]=Renkler +Name[ug]=رەڭلەر +Name[uk]=Кольори +Name[uz]=Ranglar +Name[uz@cyrillic]=Ранглар +Name[vi]=Màu sắc +Name[wa]=Coleurs +Name[xh]=Imibala +Name[x-test]=xxColorsxx +Name[zh_CN]=颜色 +Name[zh_TW]=顏色 + +Comment=Change the colors used in applications +Comment[bs]=Promjeni boje koristene u aplikaciji +Comment[ca]=Canvia els colors utilitzats en les aplicacions +Comment[ca@valencia]=Canvia els colors utilitzats en les aplicacions +Comment[cs]=Změňte barvy použité v aplikacích +Comment[da]=Ændr de farver der bruges i programmer +Comment[de]=Änderung der von Programmen verwendeten Farben +Comment[el]=Αλλαγή των χρωμάτων που χρησιμοποιούνται στις εφαρμογές +Comment[en_GB]=Change the colours used in applications +Comment[es]=Cambiar los colores que usan las aplicaciones +Comment[et]=Rakendustes kasutatavate värvide muutmine +Comment[eu]=Aldatu aplikazioetan erabiltzen diren koloreak +Comment[fi]=Sovellusten värien asetukset +Comment[gl]=Cambia as cores usadas nos programas +Comment[he]=שנה את הצבעים בשימוש ביישומים +Comment[hu]=Az alkalmazásokban használt színek megváltoztatása +Comment[ia]=Modifica le colores usate in applicationes +Comment[kk]=Қолданбада пайдаланатын түстерін өзгерту +Comment[km]=ផ្លាស់ប្ដូរ​ពណ៌​ដែល​បាន​ប្រើ​ក្នុង​កម្មវិធី +Comment[ko]=프로그램에 사용되는 색을 변경합니다 +Comment[lt]=Keisti spalvas naudojamas programose +Comment[mr]=अनुप्रयोगांत वापरण्यात आलेले रंग बदला +Comment[nb]=Endre fargene som brukes i programmer +Comment[nds]=De Programmklören ännern +Comment[nl]=De in toepassingen gebruikte kleuren wijzigen +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਵਰਤੇ ਜਾਂਦੇ ਰੰਗ ਬਦਲੋ +Comment[pl]=Zmiana kolorów używanych w programach +Comment[pt]=Mudar as cores usadas nas aplicações +Comment[pt_BR]=Alterar as cores usadas nos aplicativos +Comment[ro]=Schimbă culorile folosite în aplicații +Comment[ru]=Изменение цветов, используемых в приложениях +Comment[sk]=Zmeniť farby použité v aplikáciách +Comment[sl]=Spremenite barve, ki se uporabljajo v programih +Comment[sr]=Промените боје коришћене у програмима +Comment[sr@ijekavian]=Промените боје коришћене у програмима +Comment[sr@ijekavianlatin]=Promenite boje korišćene u programima +Comment[sr@latin]=Promenite boje korišćene u programima +Comment[sv]=Ändra färgerna som används av program +Comment[tr]=Uygulamalarda kullanılacak renkleri yapılandır +Comment[uk]=Зміна кольорів, що використовуються у інтерфейсах програм +Comment[vi]=Thay đổi màu sắc được sử dụng trong các ứng dụng +Comment[x-test]=xxChange the colors used in applicationsxx +Comment[zh_CN]=更改应用程序所使用的颜色 +Comment[zh_TW]=變更用於應用程式的顏色 + +X-KDE-Keywords=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme +X-KDE-Keywords[bs]=boje,boje,tema,kontrast,dodatak bojama,tema u boji,stil boja,tema boja +X-KDE-Keywords[ca]=colors,esquema,contrast,colors d'estris,Esquema de color,estil de color, tema de color +X-KDE-Keywords[ca@valencia]=colors,esquema,contrast,colors d'estris,Esquema de color,estil de color, tema de color +X-KDE-Keywords[da]=farver,tema,kontrast,widget-farver,farvetema,farvestil,farveskema +X-KDE-Keywords[de]=Farben,Schema,Kontrast,Farbschema,Elemente +X-KDE-Keywords[el]=χρώματα,χρώματα,σχήμα,αντίθεση,χρώματα γραφικών συστατικών,χρωματικό σχήμα,χρωματικό στιλ,θέμα χρώματος +X-KDE-Keywords[en_GB]=colours,scheme,contrast,Widget colours,Colour Scheme,colour style,colour theme +X-KDE-Keywords[es]=colores,esquema,contraste,colores de elementos gráficos,Esquema de color,estilo de color,tema de color +X-KDE-Keywords[et]=värv,värvid,skeem,kontrast,vidina värvid,värviskeem,värvistiil,värviteema +X-KDE-Keywords[eu]=kolore,koloreak,eskema,kontraste,trepetaren koloreak,kolore-eskema,kolore-estilo, kolorearen gai +X-KDE-Keywords[fi]=värit,teema,kontrasti,käyttöliittymäelementtien värit,elementtien värit,väriteema,värityyli +X-KDE-Keywords[fr]=couleurs, couleurs, schéma, contraste, couleur des composants graphiques, schéma de couleur, style de couleur, thème de couleur +X-KDE-Keywords[ga]=dathanna,scéim,codarsnacht,dathanna Giuirléidí,Scéim Datha,téama datha +X-KDE-Keywords[gl]=cores,esquema,contraste,cores do widget,esquema de cores, tema de cores +X-KDE-Keywords[hu]=színek,színek,séma,kontraszt,Grafikai elemek színei,Színséma,színstílus,színtéma +X-KDE-Keywords[ia]=colores,colores,schema,contrasto,colores de Widget,Schema de Color,stilo de color, thema de color +X-KDE-Keywords[it]=colori,schema,contrasto,colore degli oggetti,schema di colore,stile colore,tema colore +X-KDE-Keywords[kk]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme +X-KDE-Keywords[km]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme +X-KDE-Keywords[ko]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,색,색 배열,고대비 +X-KDE-Keywords[mr]=रंग, रंग, योजना, कॉन्ट्रास्ट, विजेट रंग, रंगयोजना, रंगप्रकार, रंगशैली +X-KDE-Keywords[nb]=farger,oppsett,kontrast,elementfarger,fargeoppsett,fargestil,fargetema +X-KDE-Keywords[nds]=Klöör,Klören,Schema,Kontrast,Lüttprogramm-Klören,Klöörschema,Klöörstil,Klöörmuster +X-KDE-Keywords[nl]=colors,colours, kleuren,scheme,schema,contrast,Widget colors,Widgetkleuren,Color Scheme,kleurschema,kleurstijl,kleurthema +X-KDE-Keywords[pl]=kolory,schemat,kontrast,kolory elementów interfejsu,zestaw kolorów,styl kolorów,motyw kolorów +X-KDE-Keywords[pt]=cores,esquema,contraste,cores dos elementos,esquema de cores,estilo de cores,tema de cores +X-KDE-Keywords[pt_BR]=cor,cores,esquema,contraste,Cores do widget,Esquema de cores,estilo de cores,tema de cores +X-KDE-Keywords[ru]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,цвет,цвета,схема,контраст,цвета виджета,цветовая схема,цветовой стиль,цветовая тема +X-KDE-Keywords[sk]=farba,farby,schéma,kontrast,farby widgetov,Farebná schéma,štýl farieb,téma farieb +X-KDE-Keywords[sl]=barve,shema,tema,kontrast,barve gradnikov,barvna shema,barvna tema,barvni slog +X-KDE-Keywords[sr]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,боје,шема,контраст,боје виџета,шема боја,стил боја,тема боја +X-KDE-Keywords[sr@ijekavian]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,боје,шема,контраст,боје виџета,шема боја,стил боја,тема боја +X-KDE-Keywords[sr@ijekavianlatin]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,boje,šema,kontrast,boje vidžeta,šema boja,stil boja,tema boja +X-KDE-Keywords[sr@latin]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,boje,šema,kontrast,boje vidžeta,šema boja,stil boja,tema boja +X-KDE-Keywords[sv]=färger,schema,kontrast,Komponentfärger,Färgschema,färgstil,färgtema +X-KDE-Keywords[tr]=renkler,renk,şema,karşıtlık,kontrast,Parçacık renkleri,RenkŞeması,renk biçimi,renk teması +X-KDE-Keywords[uk]=кольори,кольори,схема,контраст,кольори віджетів,схема кольорів,стиль кольорів,тема кольорів,colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme +X-KDE-Keywords[x-test]=xxcolors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color themexx +X-KDE-Keywords[zh_CN]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme,颜色,配色方案,对比度,部件颜色,颜色方案,颜色风格,颜色主题 +X-KDE-Keywords[zh_TW]=colors,colours,scheme,contrast,Widget colors,Color Scheme,color style,color theme + +Categories=Qt;KDE;X-KDE-settings-looknfeel; diff --git a/kcontrol/colors/colorschemes.knsrc b/kcontrol/colors/colorschemes.knsrc new file mode 100644 index 00000000..cc4852d6 --- /dev/null +++ b/kcontrol/colors/colorschemes.knsrc @@ -0,0 +1,6 @@ +[KNewStuff3] +ProvidersUrl=http://download.kde.org/ocs/providers.xml +TargetDir=color-schemes +Uncompress=archive +Categories=KDE Color Scheme KDE4 +UploadCategories=KDE Color Scheme KDE4 diff --git a/kcontrol/colors/colorscm.cpp b/kcontrol/colors/colorscm.cpp new file mode 100644 index 00000000..b9b911f9 --- /dev/null +++ b/kcontrol/colors/colorscm.cpp @@ -0,0 +1,1469 @@ +/* KDE Display color scheme setup module + * Copyright (C) 2007 Matthew Woehlke + * Copyright (C) 2007 Jeremy Whiting + * + * 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 "colorscm.h" + +#include "../krdb/krdb.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +K_PLUGIN_FACTORY( KolorFactory, registerPlugin(); ) +K_EXPORT_PLUGIN( KolorFactory("kcmcolors") ) + +//BEGIN WindecoColors +KColorCm::WindecoColors::WindecoColors(const KSharedConfigPtr &config) +{ + load(config); +} + +void KColorCm::WindecoColors::load(const KSharedConfigPtr &config) +{ + // NOTE: keep this in sync with kdelibs/kdeui/kernel/kglobalsettings.cpp + KConfigGroup group(config, "WM"); + m_colors[ActiveBackground] = group.readEntry("activeBackground", QColor(48, 174, 232)); + m_colors[ActiveForeground] = group.readEntry("activeForeground", QColor(255, 255, 255)); + m_colors[InactiveBackground] = group.readEntry("inactiveBackground", QColor(224, 223, 222)); + m_colors[InactiveForeground] = group.readEntry("inactiveForeground", QColor(75, 71, 67)); + m_colors[ActiveBlend] = group.readEntry("activeBlend", m_colors[ActiveForeground]); + m_colors[InactiveBlend] = group.readEntry("inactiveBlend", m_colors[InactiveForeground]); +} + +QColor KColorCm::WindecoColors::color(WindecoColors::Role role) const +{ + return m_colors[role]; +} +//END WindecoColors + +KColorCm::KColorCm(QWidget *parent, const QVariantList &) + : KCModule( KolorFactory::componentData(), parent ), m_disableUpdates(false), + m_loadedSchemeHasUnsavedChanges(false), m_dontLoadSelectedScheme(false), + m_previousSchemeItem(0) +{ + KAboutData* about = new KAboutData( + "kcmcolors", 0, ki18n("Colors"), 0, KLocalizedString(), + KAboutData::License_GPL, + ki18n("(c) 2007 Matthew Woehlke") + ); + about->addAuthor( ki18n("Matthew Woehlke"), KLocalizedString(), + "mw_triad@users.sourceforge.net" ); + about->addAuthor( ki18n("Jeremy Whiting"), KLocalizedString(), "jpwhiting@kde.org"); + setAboutData( about ); + + m_config = KSharedConfig::openConfig("kdeglobals"); + + setupUi(this); + schemeKnsButton->setIcon( KIcon("get-hot-new-stuff") ); + schemeKnsUploadButton->setIcon( KIcon("get-hot-new-stuff") ); + connect(colorSet, SIGNAL(currentIndexChanged(int)), this, SLOT(updateColorTable())); + connect(schemeList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(loadScheme(QListWidgetItem*,QListWidgetItem*))); + connect(applyToAlien, SIGNAL(toggled(bool)), this, SLOT(emitChanged())); + + // only needs to be called once + setupColorTable(); +} + +KColorCm::~KColorCm() +{ + m_config->markAsClean(); +} + +void KColorCm::populateSchemeList() +{ + // clear the list in case this is being called from reset button click + schemeList->clear(); + + // add entries + QIcon icon; + const QStringList schemeFiles = KGlobal::dirs()->findAllResources("data", "color-schemes/*.colors", KStandardDirs::NoDuplicates); + for (int i = 0; i < schemeFiles.size(); ++i) + { + // get the file name + const QString filename = schemeFiles.at(i); + const QFileInfo info(filename); + + // add the entry + KSharedConfigPtr config = KSharedConfig::openConfig(filename); + icon = createSchemePreviewIcon(config); + KConfigGroup group(config, "General"); + const QString name = group.readEntry("Name", info.baseName()); + QListWidgetItem * newItem = new QListWidgetItem(icon, name); + // stash the file basename for use later + newItem->setData(Qt::UserRole, info.baseName()); + schemeList->addItem(newItem); + } + schemeList->sortItems(); + + // add default entry (do this here so that the current and default entry appear at the top) + m_config->setReadDefaults(true); + icon = createSchemePreviewIcon(m_config); + schemeList->insertItem(0, new QListWidgetItem(icon, i18nc("Default color scheme", "Default"))); + m_config->setReadDefaults(false); + + // add current scheme entry + icon = createSchemePreviewIcon(m_config); + QListWidgetItem *currentitem = new QListWidgetItem(icon, i18nc("Current color scheme", "Current")); + schemeList->insertItem(0, currentitem); + schemeList->blockSignals(true); // don't emit changed signals + schemeList->setCurrentItem(currentitem); + schemeList->blockSignals(false); +} + +void KColorCm::updatePreviews() +{ + schemePreview->setPalette(m_config); + colorPreview->setPalette(m_config); + setPreview->setPalette(m_config, (KColorScheme::ColorSet)(colorSet->currentIndex() - 1)); + inactivePreview->setPalette(m_config, QPalette::Inactive); + disabledPreview->setPalette(m_config, QPalette::Disabled); +} + +void KColorCm::updateEffectsPage() +{ + m_disableUpdates = true; + + // NOTE: keep this in sync with kdelibs/kdeui/colors/kcolorscheme.cpp + KConfigGroup groupI(m_config, "ColorEffects:Inactive"); + inactiveIntensityBox->setCurrentIndex(abs(groupI.readEntry("IntensityEffect", 0))); + inactiveIntensitySlider->setValue(int(groupI.readEntry("IntensityAmount", 0.0) * 20.0) + 20); + inactiveColorBox->setCurrentIndex(abs(groupI.readEntry("ColorEffect", 2))); + if (inactiveColorBox->currentIndex() > 1) + { + inactiveColorSlider->setValue(int(groupI.readEntry("ColorAmount", 0.025) * 40.0)); + } + else + { + inactiveColorSlider->setValue(int(groupI.readEntry("ColorAmount", 0.05) * 20.0) + 20); + } + inactiveColorButton->setColor(groupI.readEntry("Color", QColor(112, 111, 110))); + inactiveContrastBox->setCurrentIndex(abs(groupI.readEntry("ContrastEffect", 2))); + inactiveContrastSlider->setValue(int(groupI.readEntry("ContrastAmount", 0.1) * 20.0)); + + // NOTE: keep this in sync with kdelibs/kdeui/colors/kcolorscheme.cpp + KConfigGroup groupD(m_config, "ColorEffects:Disabled"); + disabledIntensityBox->setCurrentIndex(groupD.readEntry("IntensityEffect", 2)); + disabledIntensitySlider->setValue(int(groupD.readEntry("IntensityAmount", 0.1) * 20.0) + 20); + disabledColorBox->setCurrentIndex(groupD.readEntry("ColorEffect", 0)); + if (disabledColorBox->currentIndex() > 1) + { + disabledColorSlider->setValue(int(groupD.readEntry("ColorAmount", 0.0) * 40.0)); + } + else + { + disabledColorSlider->setValue(int(groupD.readEntry("ColorAmount", 0.0) * 20.0) + 20); + } + disabledColorButton->setColor(groupD.readEntry("Color", QColor(56, 56, 56))); + disabledContrastBox->setCurrentIndex(groupD.readEntry("ContrastEffect", 1)); + disabledContrastSlider->setValue(int(groupD.readEntry("ContrastAmount", 0.65) * 20.0)); + + m_disableUpdates = false; + + // enable/disable controls + inactiveIntensitySlider->setDisabled(inactiveIntensityBox->currentIndex() == 0); + disabledIntensitySlider->setDisabled(disabledIntensityBox->currentIndex() == 0); + inactiveColorSlider->setDisabled(inactiveColorBox->currentIndex() == 0); + disabledColorSlider->setDisabled(disabledColorBox->currentIndex() == 0); + inactiveColorButton->setDisabled(inactiveColorBox->currentIndex() < 2); + disabledColorButton->setDisabled(disabledColorBox->currentIndex() < 2); + inactiveContrastSlider->setDisabled(inactiveContrastBox->currentIndex() == 0); + disabledContrastSlider->setDisabled(disabledContrastBox->currentIndex() == 0); +} + +void KColorCm::loadScheme(KSharedConfigPtr config) // const QString &path) +{ + KSharedConfigPtr temp = m_config; + m_config = config; + + updateColorSchemes(); + updateEffectsPage(); // intentionally before swapping back m_config + updatePreviews(); + + m_config = temp; + updateFromColorSchemes(); + updateFromEffectsPage(); + updateFromOptions(); + updateColorTable(); + + m_loadedSchemeHasUnsavedChanges = false; + //m_changed = false; +} + +void KColorCm::selectPreviousSchemeAgain() +{ + m_dontLoadSelectedScheme = true; + schemeList->setCurrentItem(m_previousSchemeItem); + m_dontLoadSelectedScheme = false; +} + +void KColorCm::loadScheme(QListWidgetItem *currentItem, QListWidgetItem *previousItem) +{ + m_previousSchemeItem = previousItem; + + if (m_dontLoadSelectedScheme) + { + return; + } + + if (currentItem != NULL) + { + if (m_loadedSchemeHasUnsavedChanges) // if changes made to loaded scheme + { + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(this, + i18n("Selecting another scheme will discard any changes you have made"), + i18n("Are you sure?"), + KStandardGuiItem::cont(), + KStandardGuiItem::cancel(), + "noDiscardWarning")) // if the user decides to cancel + { + QTimer::singleShot(0, this, SLOT(selectPreviousSchemeAgain())); + return; + } + } + + // load it + + const QString name = currentItem->text(); + m_currentColorScheme = name; + const QString fileBaseName = currentItem->data(Qt::UserRole).toString(); + if (name == i18nc("Default color scheme", "Default")) + { + schemeRemoveButton->setEnabled(false); + schemeKnsUploadButton->setEnabled(false); + + KSharedConfigPtr config = m_config; + config->setReadDefaults(true); + loadScheme(config); + config->setReadDefaults(false); + // load the default scheme + emit changed(true); + } + else if (name == i18nc("Current color scheme", "Current")) + { + schemeRemoveButton->setEnabled(false); + schemeKnsUploadButton->setEnabled(false); + loadInternal(false); + } + else + { + const QString path = KGlobal::dirs()->findResource("data", + "color-schemes/" + fileBaseName + ".colors"); + + const int permissions = QFile(path).permissions(); + const bool canWrite = (permissions & QFile::WriteUser); + kDebug() << "checking permissions of " << path; + schemeRemoveButton->setEnabled(canWrite); + schemeKnsUploadButton->setEnabled(true); + + KSharedConfigPtr config = KSharedConfig::openConfig(path); + loadScheme(config); + + emit changed(true); + } + } +} + +void KColorCm::on_schemeRemoveButton_clicked() +{ + if (schemeList->currentItem() != NULL) + { + const QString path = KGlobal::dirs()->findResource("data", + "color-schemes/" + schemeList->currentItem()->data(Qt::UserRole).toString() + + ".colors"); + if (KIO::NetAccess::del(path, this)) + { + delete schemeList->takeItem(schemeList->currentRow()); + } + else + { + // deletion failed, so show an error message + KMessageBox::error(this, i18n("You do not have permission to delete that scheme"), i18n("Error")); + } + } +} + +void KColorCm::on_schemeImportButton_clicked() +{ + // get the path to the scheme to import + KUrl url = KFileDialog::getOpenUrl(KUrl(), QString(), this, i18n("Import Color Scheme")); + + if(url.isValid()) + { + // TODO: possibly untar or uncompress it + // open it + + // load the scheme + KSharedConfigPtr config = KSharedConfig::openConfig(url.path()); + + if (config->groupList().contains("Color Scheme")) + { + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(this, + i18n("The scheme you have selected appears to be a KDE3 scheme.\n\n" + "KDE will attempt to import this scheme, however many color roles have been added since KDE3. " + "Some manual work will likely be required.\n\n" + "This scheme will not be saved automatically."), + i18n("Notice"))) + { + return; + } + + // convert KDE3 scheme to KDE4 scheme + KConfigGroup g(config, "Color Scheme"); + + colorSet->setCurrentIndex(0); + contrastSlider->setValue(g.readEntry("contrast", KGlobalSettings::contrast())); + shadeSortedColumn->setChecked(g.readEntry("shadeSortColumn", KGlobalSettings::shadeSortColumn())); + + m_commonColorButtons[0]->setColor(g.readEntry("windowBackground", m_colorSchemes[KColorScheme::View].background().color())); + m_commonColorButtons[1]->setColor(g.readEntry("windowForeground", m_colorSchemes[KColorScheme::View].foreground().color())); + m_commonColorButtons[2]->setColor(g.readEntry("background", m_colorSchemes[KColorScheme::Window].background().color())); + m_commonColorButtons[3]->setColor(g.readEntry("foreground", m_colorSchemes[KColorScheme::Window].foreground().color())); + m_commonColorButtons[4]->setColor(g.readEntry("buttonBackground", m_colorSchemes[KColorScheme::Button].background().color())); + m_commonColorButtons[5]->setColor(g.readEntry("buttonForeground", m_colorSchemes[KColorScheme::Button].foreground().color())); + m_commonColorButtons[6]->setColor(g.readEntry("selectBackground", m_colorSchemes[KColorScheme::Selection].background().color())); + m_commonColorButtons[7]->setColor(g.readEntry("selectForeground", m_colorSchemes[KColorScheme::Selection].foreground().color())); + m_commonColorButtons[8]->setColor(KColorUtils::mix(m_colorSchemes[KColorScheme::Selection].foreground().color(), + m_colorSchemes[KColorScheme::Selection].background().color())); + m_commonColorButtons[9]->setColor(KColorUtils::mix(m_colorSchemes[KColorScheme::View].foreground().color(), + m_colorSchemes[KColorScheme::View].background().color())); + // doesn't exist in KDE3: 10 ActiveText + m_commonColorButtons[11]->setColor(g.readEntry("linkColor", m_colorSchemes[KColorScheme::View].foreground(KColorScheme::LinkText).color())); + m_commonColorButtons[12]->setColor(g.readEntry("visitedLinkColor", m_colorSchemes[KColorScheme::View].foreground(KColorScheme::VisitedText).color())); + // doesn't exist in KDE3: 13-15 PositiveText, NeutralText, NegativeText + m_commonColorButtons[16]->setColor(g.readEntry("windowForeground", m_colorSchemes[KColorScheme::View].decoration(KColorScheme::FocusColor).color())); + m_commonColorButtons[17]->setColor(g.readEntry("selectBackground", m_colorSchemes[KColorScheme::View].decoration(KColorScheme::HoverColor).color())); + m_commonColorButtons[18]->setColor(g.readEntry("windowBackground", m_colorSchemes[KColorScheme::Tooltip].background().color())); + m_commonColorButtons[19]->setColor(g.readEntry("windowForeground", m_colorSchemes[KColorScheme::Tooltip].foreground().color())); + m_commonColorButtons[20]->setColor(g.readEntry("activeBackground", m_wmColors.color(WindecoColors::ActiveBackground))); + m_commonColorButtons[21]->setColor(g.readEntry("activeForeground", m_wmColors.color(WindecoColors::ActiveForeground))); + m_commonColorButtons[22]->setColor(g.readEntry("activeBlend", m_wmColors.color(WindecoColors::ActiveBlend))); + m_commonColorButtons[23]->setColor(g.readEntry("inactiveBackground", m_wmColors.color(WindecoColors::InactiveBackground))); + m_commonColorButtons[24]->setColor(g.readEntry("inactiveForeground", m_wmColors.color(WindecoColors::InactiveForeground))); + m_commonColorButtons[25]->setColor(g.readEntry("inactiveBlend", m_wmColors.color(WindecoColors::InactiveBlend))); + + colorSet->setCurrentIndex(1); + m_backgroundButtons[KColorScheme::AlternateBackground]->setColor(g.readEntry("alternateBackground", + m_colorSchemes[KColorScheme::View].background(KColorScheme::AlternateBackground).color())); + colorSet->setCurrentIndex(0); + } + else + { + // load KDE4 scheme + loadScheme(config); + + // save it + saveScheme(url.fileName()); + } + } +} + +void KColorCm::on_schemeKnsButton_clicked() +{ + KNS3::DownloadDialog dialog("colorschemes.knsrc", this); + dialog.exec(); + if ( ! dialog.changedEntries().isEmpty() ) + { + populateSchemeList(); + } +} + +void KColorCm::on_schemeKnsUploadButton_clicked() +{ + if (schemeList->currentItem() != NULL) + { + // check if the currently loaded scheme has unsaved changes + if (m_loadedSchemeHasUnsavedChanges) + { + KMessageBox::sorry(this, i18n("Please save the color scheme before uploading it."), + i18n("Please save")); + return; + } + + // find path + const QString basename = schemeList->currentItem()->data(Qt::UserRole).toString(); + const QString path = KGlobal::dirs()->findResource("data", + "color-schemes/" + basename + ".colors"); + if (path.isEmpty() ) // if the color scheme file wasn't found + { + kDebug() << "path for color scheme " << basename << " couldn't be found"; + return; + } + + // upload + KNS3::UploadDialog dialog("colorschemes.knsrc", this); + dialog.setUploadFile(KUrl(path) ); + dialog.exec(); + } +} + +void KColorCm::on_schemeSaveButton_clicked() +{ + QString previousName; + if (schemeList->currentItem() != NULL && schemeList->currentRow() > 1) + { + previousName = schemeList->currentItem()->data(Qt::DisplayRole).toString(); + } + // prompt for the name to save as + bool ok; + QString name = KInputDialog::getText(i18n("Save Color Scheme"), + i18n("&Enter a name for the color scheme:"), previousName, &ok, this); + if (ok) + { + saveScheme(name); + } +} + +void KColorCm::saveScheme(const QString &name) +{ + QString filename = name; + filename.remove('\''); // So Foo's does not become FooS + QRegExp fixer("[\\W,.-]+(.?)"); + int offset; + while ((offset = fixer.indexIn(filename)) >= 0) + filename.replace(offset, fixer.matchedLength(), fixer.cap(1).toUpper()); + filename.replace(0, 1, filename.at(0).toUpper()); + + // check if that name is already in the list + const QString path = KGlobal::dirs()->saveLocation("data", "color-schemes/") + + filename + ".colors"; + + QFile file(path); + const int permissions = file.permissions(); + const bool canWrite = (permissions & QFile::WriteUser); + // or if we can overwrite it if it exists + if (path.isEmpty() || !file.exists() || canWrite) + { + if(canWrite){ + int ret = KMessageBox::questionYesNo(this, + i18n("A color scheme with that name already exists.\nDo you want to overwrite it?"), + i18n("Save Color Scheme"), + KStandardGuiItem::overwrite(), + KStandardGuiItem::cancel()); + //on don't overwrite, select the already existing name. + if(ret == KMessageBox::No){ + QList foundItems = schemeList->findItems(name, Qt::MatchExactly); + if (foundItems.size() == 1) + schemeList->setCurrentRow(schemeList->row(foundItems[0])); + return; + } + } + + // go ahead and save it + QString newpath = KGlobal::dirs()->saveLocation("data", "color-schemes/"); + newpath += filename + ".colors"; + KSharedConfigPtr temp = m_config; + m_config = KSharedConfig::openConfig(newpath); + // then copy current colors into new config + updateFromColorSchemes(); + updateFromEffectsPage(); + KConfigGroup group(m_config, "General"); + group.writeEntry("Name", name); + // sync it + m_config->sync(); + + m_loadedSchemeHasUnsavedChanges = false; + + QList foundItems = schemeList->findItems(name, Qt::MatchExactly); + QIcon icon = createSchemePreviewIcon(m_config); + if (foundItems.size() < 1) + { + // add it to the list since it's not in there already + populateSchemeList(); + + // then select the new item + schemeList->setCurrentItem(schemeList->findItems(name, Qt::MatchExactly).at(0)); + } + else + { + // update the icon of the one that's in the list + foundItems[0]->setIcon(icon); + schemeList->setCurrentRow(schemeList->row(foundItems[0])); + } + + // set m_config back to the system one + m_config = temp; + + // store colorscheme name in global settings + m_currentColorScheme = name; + group = KConfigGroup(m_config, "General"); + group.writeEntry("ColorScheme", m_currentColorScheme); + + emit changed(true); + } + else if (!canWrite && file.exists()) + { + // give error message if !canWrite && file.exists() + KMessageBox::error(this, i18n("You do not have permission to overwrite that scheme"), i18n("Error")); + } +} + +void KColorCm::createColorEntry(const QString &text, const QString &key, QList &list, int index) +{ + KColorButton *button = new KColorButton(this); + button->setObjectName(QString::number(index)); + connect(button, SIGNAL(changed(QColor)), this, SLOT(colorChanged(QColor))); + list.append(button); + + m_colorKeys.insert(index, key); + + QTableWidgetItem *label = new QTableWidgetItem(text); + colorTable->setItem(index, 0, label); + colorTable->setCellWidget(index, 1, button); + colorTable->setRowHeight(index, button->sizeHint().height()); +} + +void KColorCm::variesClicked() +{ + // find which button was changed + const int row = sender()->objectName().toInt(); + + QColor color; + if(KColorDialog::getColor(color, this ) != QDialog::Rejected ) + { + changeColor(row, color); + m_stackedWidgets[row - 9]->setCurrentIndex(0); + } +} + +QPixmap KColorCm::createSchemePreviewIcon(const KSharedConfigPtr &config) +{ + const WindecoColors wm(config); + const uchar bits1[] = { 0xff, 0xff, 0xff, 0x2c, 0x16, 0x0b }; + const uchar bits2[] = { 0x68, 0x34, 0x1a, 0xff, 0xff, 0xff }; + const QSize bitsSize(24,2); + const QBitmap b1 = QBitmap::fromData(bitsSize, bits1); + const QBitmap b2 = QBitmap::fromData(bitsSize, bits2); + + QPixmap pixmap(23, 16); + pixmap.fill(Qt::black); // ### use some color other than black for borders? + + QPainter p(&pixmap); + + KColorScheme windowScheme(QPalette::Active, KColorScheme::Window, config); + p.fillRect( 1, 1, 7, 7, windowScheme.background()); + p.fillRect( 2, 2, 5, 2, QBrush(windowScheme.foreground().color(), b1)); + + KColorScheme buttonScheme(QPalette::Active, KColorScheme::Button, config); + p.fillRect( 8, 1, 7, 7, buttonScheme.background()); + p.fillRect( 9, 2, 5, 2, QBrush(buttonScheme.foreground().color(), b1)); + + p.fillRect(15, 1, 7, 7, wm.color(WindecoColors::ActiveBackground)); + p.fillRect(16, 2, 5, 2, QBrush(wm.color(WindecoColors::ActiveForeground), b1)); + + KColorScheme viewScheme(QPalette::Active, KColorScheme::View, config); + p.fillRect( 1, 8, 7, 7, viewScheme.background()); + p.fillRect( 2, 12, 5, 2, QBrush(viewScheme.foreground().color(), b2)); + + KColorScheme selectionScheme(QPalette::Active, KColorScheme::Selection, config); + p.fillRect( 8, 8, 7, 7, selectionScheme.background()); + p.fillRect( 9, 12, 5, 2, QBrush(selectionScheme.foreground().color(), b2)); + + p.fillRect(15, 8, 7, 7, wm.color(WindecoColors::InactiveBackground)); + p.fillRect(16, 12, 5, 2, QBrush(wm.color(WindecoColors::InactiveForeground), b2)); + + p.end(); + + return pixmap; +} + +void KColorCm::updateColorSchemes() +{ + m_colorSchemes.clear(); + + m_colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::View, m_config)); + m_colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Window, m_config)); + m_colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Button, m_config)); + m_colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Selection, m_config)); + m_colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Tooltip, m_config)); + + m_wmColors.load(m_config); +} + +void KColorCm::updateFromColorSchemes() +{ + // store colorscheme name in global settings + KConfigGroup group(m_config, "General"); + group.writeEntry("ColorScheme", m_currentColorScheme); + + for (int i = KColorScheme::View; i <= KColorScheme::Tooltip; ++i) + { + KConfigGroup group(m_config, colorSetGroupKey(i)); + group.writeEntry("BackgroundNormal", m_colorSchemes[i].background(KColorScheme::NormalBackground).color()); + group.writeEntry("BackgroundAlternate", m_colorSchemes[i].background(KColorScheme::AlternateBackground).color()); + group.writeEntry("ForegroundNormal", m_colorSchemes[i].foreground(KColorScheme::NormalText).color()); + group.writeEntry("ForegroundInactive", m_colorSchemes[i].foreground(KColorScheme::InactiveText).color()); + group.writeEntry("ForegroundActive", m_colorSchemes[i].foreground(KColorScheme::ActiveText).color()); + group.writeEntry("ForegroundLink", m_colorSchemes[i].foreground(KColorScheme::LinkText).color()); + group.writeEntry("ForegroundVisited", m_colorSchemes[i].foreground(KColorScheme::VisitedText).color()); + group.writeEntry("ForegroundNegative", m_colorSchemes[i].foreground(KColorScheme::NegativeText).color()); + group.writeEntry("ForegroundNeutral", m_colorSchemes[i].foreground(KColorScheme::NeutralText).color()); + group.writeEntry("ForegroundPositive", m_colorSchemes[i].foreground(KColorScheme::PositiveText).color()); + group.writeEntry("DecorationFocus", m_colorSchemes[i].decoration(KColorScheme::FocusColor).color()); + group.writeEntry("DecorationHover", m_colorSchemes[i].decoration(KColorScheme::HoverColor).color()); + } + + KConfigGroup WMGroup(m_config, "WM"); + WMGroup.writeEntry("activeBackground", m_wmColors.color(WindecoColors::ActiveBackground)); + WMGroup.writeEntry("activeForeground", m_wmColors.color(WindecoColors::ActiveForeground)); + WMGroup.writeEntry("inactiveBackground", m_wmColors.color(WindecoColors::InactiveBackground)); + WMGroup.writeEntry("inactiveForeground", m_wmColors.color(WindecoColors::InactiveForeground)); + WMGroup.writeEntry("activeBlend", m_wmColors.color(WindecoColors::ActiveBlend)); + WMGroup.writeEntry("inactiveBlend", m_wmColors.color(WindecoColors::InactiveBlend)); +} + +void KColorCm::updateFromOptions() +{ + KConfigGroup groupK(m_config, "KDE"); + groupK.writeEntry("contrast", contrastSlider->value()); + + KConfigGroup groupG(m_config, "General"); + groupG.writeEntry("shadeSortColumn", shadeSortedColumn->isChecked()); + + KConfigGroup groupI(m_config, "ColorEffects:Inactive"); + groupI.writeEntry("Enable", useInactiveEffects->isChecked()); + // only write this setting if it is not the default; this way we can change the default more easily in later KDE + // the setting will still written by explicitly checking/unchecking the box + if (inactiveSelectionEffect->isChecked()) + { + groupI.writeEntry("ChangeSelectionColor", true); + } + else + { + groupI.deleteEntry("ChangeSelectionColor"); + } +} + +void KColorCm::updateFromEffectsPage() +{ + if (m_disableUpdates) + { + // don't write the config as we are reading it! + return; + } + + KConfigGroup groupI(m_config, "ColorEffects:Inactive"); + KConfigGroup groupD(m_config, "ColorEffects:Disabled"); + + // intensity + groupI.writeEntry("IntensityEffect", inactiveIntensityBox->currentIndex()); + groupD.writeEntry("IntensityEffect", disabledIntensityBox->currentIndex()); + groupI.writeEntry("IntensityAmount", qreal(inactiveIntensitySlider->value() - 20) * 0.05); + groupD.writeEntry("IntensityAmount", qreal(disabledIntensitySlider->value() - 20) * 0.05); + + // color + groupI.writeEntry("ColorEffect", inactiveColorBox->currentIndex()); + groupD.writeEntry("ColorEffect", disabledColorBox->currentIndex()); + if (inactiveColorBox->currentIndex() > 1) + { + groupI.writeEntry("ColorAmount", qreal(inactiveColorSlider->value()) * 0.025); + } + else + { + groupI.writeEntry("ColorAmount", qreal(inactiveColorSlider->value() - 20) * 0.05); + } + if (disabledColorBox->currentIndex() > 1) + { + groupD.writeEntry("ColorAmount", qreal(disabledColorSlider->value()) * 0.025); + } + else + { + groupD.writeEntry("ColorAmount", qreal(disabledColorSlider->value() - 20) * 0.05); + } + groupI.writeEntry("Color", inactiveColorButton->color()); + groupD.writeEntry("Color", disabledColorButton->color()); + + // contrast + groupI.writeEntry("ContrastEffect", inactiveContrastBox->currentIndex()); + groupD.writeEntry("ContrastEffect", disabledContrastBox->currentIndex()); + groupI.writeEntry("ContrastAmount", qreal(inactiveContrastSlider->value()) * 0.05); + groupD.writeEntry("ContrastAmount", qreal(disabledContrastSlider->value()) * 0.05); + + // enable/disable controls + inactiveIntensitySlider->setDisabled(inactiveIntensityBox->currentIndex() == 0); + disabledIntensitySlider->setDisabled(disabledIntensityBox->currentIndex() == 0); + inactiveColorSlider->setDisabled(inactiveColorBox->currentIndex() == 0); + disabledColorSlider->setDisabled(disabledColorBox->currentIndex() == 0); + inactiveColorButton->setDisabled(inactiveColorBox->currentIndex() < 2); + disabledColorButton->setDisabled(disabledColorBox->currentIndex() < 2); + inactiveContrastSlider->setDisabled(inactiveContrastBox->currentIndex() == 0); + disabledContrastSlider->setDisabled(disabledContrastBox->currentIndex() == 0); +} + +void KColorCm::setupColorTable() +{ + // first setup the common colors table + commonColorTable->verticalHeader()->hide(); + commonColorTable->horizontalHeader()->hide(); + commonColorTable->setShowGrid(false); + commonColorTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); + int minWidth = QPushButton(i18n("Varies")).minimumSizeHint().width(); + commonColorTable->horizontalHeader()->setMinimumSectionSize(minWidth); + commonColorTable->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents); + + for (int i = 0; i < 26; ++i) + { + KColorButton * button = new KColorButton(this); + commonColorTable->setRowHeight(i, button->sizeHint().height()); + button->setObjectName(QString::number(i)); + connect(button, SIGNAL(changed(QColor)), this, SLOT(colorChanged(QColor))); + m_commonColorButtons << button; + + if (i > 8 && i < 18) + { + // Inactive Text row through Positive Text role all need a varies button + KPushButton * variesButton = new KPushButton(NULL); + variesButton->setText(i18n("Varies")); + variesButton->setObjectName(QString::number(i)); + connect(variesButton, SIGNAL(clicked()), this, SLOT(variesClicked())); + + QStackedWidget * widget = new QStackedWidget(this); + widget->addWidget(button); + widget->addWidget(variesButton); + m_stackedWidgets.append(widget); + + commonColorTable->setCellWidget(i, 1, widget); + } + else + { + commonColorTable->setCellWidget(i, 1, button); + } + } + + // then the colorTable that the colorSets will use + colorTable->verticalHeader()->hide(); + colorTable->horizontalHeader()->hide(); + colorTable->setShowGrid(false); + colorTable->setRowCount(12); + colorTable->horizontalHeader()->setMinimumSectionSize(minWidth); + colorTable->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents); + + createColorEntry(i18n("Normal Background"), "BackgroundNormal", m_backgroundButtons, 0); + createColorEntry(i18n("Alternate Background"), "BackgroundAlternate", m_backgroundButtons, 1); + createColorEntry(i18n("Normal Text"), "ForegroundNormal", m_foregroundButtons, 2); + createColorEntry(i18n("Inactive Text"), "ForegroundInactive", m_foregroundButtons, 3); + createColorEntry(i18n("Active Text"), "ForegroundActive", m_foregroundButtons, 4); + createColorEntry(i18n("Link Text"), "ForegroundLink", m_foregroundButtons, 5); + createColorEntry(i18n("Visited Text"), "ForegroundVisited", m_foregroundButtons, 6); + createColorEntry(i18n("Negative Text"), "ForegroundNegative", m_foregroundButtons, 7); + createColorEntry(i18n("Neutral Text"), "ForegroundNeutral", m_foregroundButtons, 8); + createColorEntry(i18n("Positive Text"), "ForegroundPositive", m_foregroundButtons, 9); + createColorEntry(i18n("Focus Decoration"), "DecorationFocus", m_decorationButtons, 10); + createColorEntry(i18n("Hover Decoration"), "DecorationHover", m_decorationButtons, 11); + + colorTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); + colorTable->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents); + + updateColorSchemes(); + updateColorTable(); +} + +void KColorCm::setCommonForeground(KColorScheme::ForegroundRole role, int stackIndex, + int buttonIndex) +{ + QColor color = m_colorSchemes[KColorScheme::View].foreground(role).color(); + for (int i = KColorScheme::Window; i < KColorScheme::Tooltip; ++i) + { + if (i == KColorScheme::Selection && role == KColorScheme::InactiveText) + break; + + if (m_colorSchemes[i].foreground(role).color() != color) + { + m_stackedWidgets[stackIndex]->setCurrentIndex(1); + return; + } + } + + m_stackedWidgets[stackIndex]->setCurrentIndex(0); + m_commonColorButtons[buttonIndex]->setColor(color); + m_loadedSchemeHasUnsavedChanges = true; +} + +void KColorCm::setCommonDecoration(KColorScheme::DecorationRole role, int stackIndex, + int buttonIndex) +{ + QColor color = m_colorSchemes[KColorScheme::View].decoration(role).color(); + for (int i = KColorScheme::Window; i < KColorScheme::Tooltip; ++i) + { + if (m_colorSchemes[i].decoration(role).color() != color) + { + m_stackedWidgets[stackIndex]->setCurrentIndex(1); + return; + } + } + + m_stackedWidgets[stackIndex]->setCurrentIndex(0); + m_commonColorButtons[buttonIndex]->setColor(color); + m_loadedSchemeHasUnsavedChanges = true; +} + +void KColorCm::updateColorTable() +{ + // subtract one here since the 0 item is "Common Colors" + const int currentSet = colorSet->currentIndex() - 1; + + if (currentSet == -1) + { + // common colors is selected + stackColors->setCurrentIndex(0); + stackPreview->setCurrentIndex(0); + + KColorButton * button; + foreach (button, m_commonColorButtons) + { + button->blockSignals(true); + } + + m_commonColorButtons[0]->setColor(m_colorSchemes[KColorScheme::View].background(KColorScheme::NormalBackground).color()); + m_commonColorButtons[1]->setColor(m_colorSchemes[KColorScheme::View].foreground(KColorScheme::NormalText).color()); + m_commonColorButtons[2]->setColor(m_colorSchemes[KColorScheme::Window].background(KColorScheme::NormalBackground).color()); + m_commonColorButtons[3]->setColor(m_colorSchemes[KColorScheme::Window].foreground(KColorScheme::NormalText).color()); + m_commonColorButtons[4]->setColor(m_colorSchemes[KColorScheme::Button].background(KColorScheme::NormalBackground).color()); + m_commonColorButtons[5]->setColor(m_colorSchemes[KColorScheme::Button].foreground(KColorScheme::NormalText).color()); + m_commonColorButtons[6]->setColor(m_colorSchemes[KColorScheme::Selection].background(KColorScheme::NormalBackground).color()); + m_commonColorButtons[7]->setColor(m_colorSchemes[KColorScheme::Selection].foreground(KColorScheme::NormalText).color()); + m_commonColorButtons[8]->setColor(m_colorSchemes[KColorScheme::Selection].foreground(KColorScheme::InactiveText).color()); + + setCommonForeground(KColorScheme::InactiveText, 0, 9); + setCommonForeground(KColorScheme::ActiveText, 1, 10); + setCommonForeground(KColorScheme::LinkText, 2, 11); + setCommonForeground(KColorScheme::VisitedText, 3, 12); + setCommonForeground(KColorScheme::NegativeText, 4, 13); + setCommonForeground(KColorScheme::NeutralText, 5, 14); + setCommonForeground(KColorScheme::PositiveText, 6, 15); + + setCommonDecoration(KColorScheme::FocusColor, 7, 16); + setCommonDecoration(KColorScheme::HoverColor, 8, 17); + + m_commonColorButtons[18]->setColor(m_colorSchemes[KColorScheme::Tooltip].background(KColorScheme::NormalBackground).color()); + m_commonColorButtons[19]->setColor(m_colorSchemes[KColorScheme::Tooltip].foreground(KColorScheme::NormalText).color()); + + m_commonColorButtons[20]->setColor(m_wmColors.color(WindecoColors::ActiveBackground)); + m_commonColorButtons[21]->setColor(m_wmColors.color(WindecoColors::ActiveForeground)); + m_commonColorButtons[22]->setColor(m_wmColors.color(WindecoColors::ActiveBlend)); + m_commonColorButtons[23]->setColor(m_wmColors.color(WindecoColors::InactiveBackground)); + m_commonColorButtons[24]->setColor(m_wmColors.color(WindecoColors::InactiveForeground)); + m_commonColorButtons[25]->setColor(m_wmColors.color(WindecoColors::InactiveBlend)); + + foreach (button, m_commonColorButtons) + { + button->blockSignals(false); + } + } + else + { + // a real color set is selected + setPreview->setPalette(m_config, (KColorScheme::ColorSet)currentSet); + stackColors->setCurrentIndex(1); + stackPreview->setCurrentIndex(1); + + for (int i = KColorScheme::NormalBackground; i <= KColorScheme::AlternateBackground; ++i) + { + m_backgroundButtons[i]->blockSignals(true); + m_backgroundButtons[i]->setColor(m_colorSchemes[currentSet].background(KColorScheme::BackgroundRole(i)).color()); + m_backgroundButtons[i]->blockSignals(false); + } + + for (int i = KColorScheme::NormalText; i <= KColorScheme::PositiveText; ++i) + { + m_foregroundButtons[i]->blockSignals(true); + m_foregroundButtons[i]->setColor(m_colorSchemes[currentSet].foreground(KColorScheme::ForegroundRole(i)).color()); + m_foregroundButtons[i]->blockSignals(false); + } + + for (int i = KColorScheme::FocusColor; i <= KColorScheme::HoverColor; ++i) + { + m_decorationButtons[i]->blockSignals(true); + m_decorationButtons[i]->setColor(m_colorSchemes[currentSet].decoration(KColorScheme::DecorationRole(i)).color()); + m_decorationButtons[i]->blockSignals(false); + } + } +} + +void KColorCm::colorChanged( const QColor &newColor ) +{ + // find which button was changed + const int row = sender()->objectName().toInt(); + changeColor(row, newColor); +} + +void KColorCm::changeColor(int row, const QColor &newColor) +{ + // update the m_colorSchemes for the selected colorSet + const int currentSet = colorSet->currentIndex() - 1; + + if (currentSet == -1) + { + // common colors is selected + switch (row) + { + case 0: + // View Background button + KConfigGroup(m_config, "Colors:View").writeEntry("BackgroundNormal", newColor); + break; + case 1: + // View Text button + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundNormal", newColor); + break; + case 2: + // Window Background Button + KConfigGroup(m_config, "Colors:Window").writeEntry("BackgroundNormal", newColor); + break; + case 3: + // Window Text Button + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundNormal", newColor); + break; + case 4: + // Button Background button + KConfigGroup(m_config, "Colors:Button").writeEntry("BackgroundNormal", newColor); + break; + case 5: + // Button Text button + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundNormal", newColor); + break; + case 6: + // Selection Background Button + KConfigGroup(m_config, "Colors:Selection").writeEntry("BackgroundNormal", newColor); + break; + case 7: + // Selection Text Button + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundNormal", newColor); + break; + case 8: + // Selection Inactive Text Button + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundInactive", newColor); + break; + + // buttons that could have varies in their place + case 9: + // Inactive Text Button (set all but Selection Inactive Text color) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundInactive", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundInactive", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundInactive", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundInactive", newColor); + break; + case 10: + // Active Text Button (set all active text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundActive", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundActive", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundActive", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundActive", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundActive", newColor); + break; + case 11: + // Link Text Button (set all link text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundLink", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundLink", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundLink", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundLink", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundLink", newColor); + break; + case 12: + // Visited Text Button (set all visited text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundVisited", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundVisited", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundVisited", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundVisited", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundVisited", newColor); + break; + case 13: + // Negative Text Button (set all negative text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundNegative", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundNegative", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundNegative", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundNegative", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundNegative", newColor); + break; + case 14: + // Neutral Text Button (set all neutral text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundNeutral", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundNeutral", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundNeutral", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundNeutral", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundNeutral", newColor); + break; + case 15: + // Positive Text Button (set all positive text colors) + KConfigGroup(m_config, "Colors:View").writeEntry("ForegroundPositive", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("ForegroundPositive", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("ForegroundPositive", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("ForegroundPositive", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundPositive", newColor); + break; + + case 16: + // Focus Decoration Button (set all focus decoration colors) + KConfigGroup(m_config, "Colors:View").writeEntry("DecorationFocus", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("DecorationFocus", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("DecorationFocus", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("DecorationFocus", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("DecorationFocus", newColor); + break; + case 17: + // Hover Decoration Button (set all hover decoration colors) + KConfigGroup(m_config, "Colors:View").writeEntry("DecorationHover", newColor); + KConfigGroup(m_config, "Colors:Window").writeEntry("DecorationHover", newColor); + KConfigGroup(m_config, "Colors:Selection").writeEntry("DecorationHover", newColor); + KConfigGroup(m_config, "Colors:Button").writeEntry("DecorationHover", newColor); + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("DecorationHover", newColor); + break; + + case 18: + // Tooltip Background button + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("BackgroundNormal", newColor); + break; + case 19: + // Tooltip Text button + KConfigGroup(m_config, "Colors:Tooltip").writeEntry("ForegroundNormal", newColor); + break; + case 20: + // Active Title Background + KConfigGroup(m_config, "WM").writeEntry("activeBackground", newColor); + break; + case 21: + // Active Title Text + KConfigGroup(m_config, "WM").writeEntry("activeForeground", newColor); + break; + case 22: + // Active Title Secondary + KConfigGroup(m_config, "WM").writeEntry("activeBlend", newColor); + break; + case 23: + // Inactive Title Background + KConfigGroup(m_config, "WM").writeEntry("inactiveBackground", newColor); + break; + case 24: + // Inactive Title Text + KConfigGroup(m_config, "WM").writeEntry("inactiveForeground", newColor); + break; + case 25: + // Inactive Title Secondary + KConfigGroup(m_config, "WM").writeEntry("inactiveBlend", newColor); + break; + } + m_commonColorButtons[row]->blockSignals(true); + m_commonColorButtons[row]->setColor(newColor); + m_commonColorButtons[row]->blockSignals(false); + } + else + { + QString group = colorSetGroupKey(currentSet); + KConfigGroup(m_config, group).writeEntry(m_colorKeys[row], newColor); + } + + QIcon icon = createSchemePreviewIcon(m_config); + schemeList->item(0)->setIcon(icon); + updateColorSchemes(); + updatePreviews(); + + m_loadedSchemeHasUnsavedChanges = true; + m_currentColorScheme = i18nc("Current color scheme", "Current"); + KConfigGroup group(m_config, "General"); + group.writeEntry("ColorScheme", m_currentColorScheme); + schemeRemoveButton->setEnabled(false); + schemeKnsUploadButton->setEnabled(false); + schemeList->blockSignals(true); // don't emit changed signals + schemeList->setCurrentRow(0); + schemeList->blockSignals(false); + + emit changed(true); +} + +QString KColorCm::colorSetGroupKey(int colorSet) +{ + QString group; + switch (colorSet) { + case KColorScheme::Window: + group = "Colors:Window"; + break; + case KColorScheme::Button: + group = "Colors:Button"; + break; + case KColorScheme::Selection: + group = "Colors:Selection"; + break; + case KColorScheme::Tooltip: + group = "Colors:Tooltip"; + break; + default: + group = "Colors:View"; + } + return group; +} + +void KColorCm::on_contrastSlider_valueChanged(int value) +{ + KConfigGroup group(m_config, "KDE"); + group.writeEntry("contrast", value); + + updatePreviews(); + + emit changed(true); +} + +void KColorCm::on_shadeSortedColumn_stateChanged(int state) +{ + KConfigGroup group(m_config, "General"); + group.writeEntry("shadeSortColumn", bool(state != Qt::Unchecked)); + + emit changed(true); +} + +void KColorCm::on_useInactiveEffects_stateChanged(int state) +{ + KConfigGroup group(m_config, "ColorEffects:Inactive"); + group.writeEntry("Enable", bool(state != Qt::Unchecked)); + + m_disableUpdates = true; + printf("re-init\n"); + inactiveSelectionEffect->setChecked(group.readEntry("ChangeSelectionColor", bool(state != Qt::Unchecked))); + m_disableUpdates = false; + + emit changed(true); +} + +void KColorCm::on_inactiveSelectionEffect_stateChanged(int state) +{ + if (m_disableUpdates) + { + // don't write the config as we are reading it! + return; + } + + KConfigGroup group(m_config, "ColorEffects:Inactive"); + group.writeEntry("ChangeSelectionColor", bool(state != Qt::Unchecked)); + + emit changed(true); +} + +void KColorCm::load() +{ + loadInternal(true); + + // get colorscheme name from global settings + KConfigGroup group(m_config, "General"); + m_currentColorScheme = group.readEntry("ColorScheme"); + if (m_currentColorScheme == i18nc("Current color scheme", "Current")) + { + m_loadedSchemeHasUnsavedChanges = true; + } + QList itemList = schemeList->findItems(m_currentColorScheme, Qt::MatchExactly); + if(!itemList.isEmpty()) // "Current" is already selected, so don't handle the case that itemList is empty + schemeList->setCurrentItem(itemList.at(0)); + + KConfig cfg("kcmdisplayrc", KConfig::NoGlobals); + group = KConfigGroup(&cfg, "X11"); + + applyToAlien->blockSignals(true); // don't emit SIGNAL(toggled(bool)) which would call SLOT(emitChanged()) + applyToAlien->setChecked(group.readEntry("exportKDEColors", true)); + applyToAlien->blockSignals(false); +} + +void KColorCm::loadOptions() +{ + contrastSlider->setValue(KGlobalSettings::contrast()); + shadeSortedColumn->setChecked(KGlobalSettings::shadeSortColumn()); + + KConfigGroup group(m_config, "ColorEffects:Inactive"); + useInactiveEffects->setChecked(group.readEntry("Enable", false)); + // NOTE: keep this in sync with kdelibs/kdeui/colors/kcolorscheme.cpp + // NOTE: remove extra logic from updateFromOptions and on_useInactiveEffects_stateChanged when this changes! + inactiveSelectionEffect->setChecked(group.readEntry("ChangeSelectionColor", group.readEntry("Enable", true))); +} + +void KColorCm::loadInternal(bool loadOptions_) +{ + // clean the config, in case we have changed the in-memory kconfig + m_config->markAsClean(); + m_config->reparseConfiguration(); + + // update the color table + updateColorSchemes(); + updateColorTable(); + + // fill in the color scheme list + populateSchemeList(); + + if (loadOptions_) + loadOptions(); + + updateEffectsPage(); + + updatePreviews(); + + m_loadedSchemeHasUnsavedChanges = false; + + emit changed(false); +} + +void KColorCm::save() +{ + QIcon icon = createSchemePreviewIcon(m_config); + schemeList->item(0)->setIcon(icon); + + KConfigGroup groupI(m_config, "ColorEffects:Inactive"); + + groupI.writeEntry("Enable", useInactiveEffects->isChecked()); + groupI.writeEntry("IntensityEffect", inactiveIntensityBox->currentIndex()); + groupI.writeEntry("ColorEffect", inactiveColorBox->currentIndex()); + groupI.writeEntry("ContrastEffect", inactiveContrastBox->currentIndex()); + + m_config->sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::PaletteChanged); +#ifdef Q_WS_X11 + // Send signal to all kwin instances + QDBusMessage message = + QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); + QDBusConnection::sessionBus().send(message); +#endif + + KConfig cfg("kcmdisplayrc", KConfig::NoGlobals); + KConfigGroup displayGroup(&cfg, "X11"); + + displayGroup.writeEntry("exportKDEColors", applyToAlien->isChecked()); + cfg.sync(); + + runRdb(KRdbExportQtColors | KRdbExportGtkTheme | ( applyToAlien->isChecked() ? KRdbExportColors : 0 ) ); + + emit changed(false); +} + +void KColorCm::defaults() +{ + // Switch to default scheme + for(int i = 0; i < schemeList->count(); ++i) { + QListWidgetItem *item = schemeList->item(i); + if(item->text() == i18nc("Default color scheme", "Default")) { + // If editing the default scheme, force a reload, else select the default scheme + if(schemeList->currentItem() == item) + loadScheme(item, item); + else + schemeList->setCurrentItem(item); + m_currentColorScheme = item->text(); + break; + } + } + + // Reset options (not part of scheme) + m_config->setReadDefaults(true); + loadOptions(); + m_config->setReadDefaults(false); + applyToAlien->setChecked(Qt::Checked); + + KCModule::defaults(); + emit changed(true); +} + +void KColorCm::emitChanged() +{ + emit changed(true); +} + +// inactive effects slots +void KColorCm::on_inactiveIntensityBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveIntensitySlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveColorBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveColorSlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveColorButton_changed(const QColor& color) +{ + Q_UNUSED( color ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveContrastBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_inactiveContrastSlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + inactivePreview->setPalette(m_config, QPalette::Inactive); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +// disabled effects slots +void KColorCm::on_disabledIntensityBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledIntensitySlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledColorBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledColorSlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledColorButton_changed(const QColor& color) +{ + Q_UNUSED( color ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledContrastBox_currentIndexChanged(int index) +{ + Q_UNUSED( index ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +void KColorCm::on_disabledContrastSlider_valueChanged(int value) +{ + Q_UNUSED( value ); + + updateFromEffectsPage(); + disabledPreview->setPalette(m_config, QPalette::Disabled); + + m_loadedSchemeHasUnsavedChanges = true; + + emit changed(true); +} + +#include "colorscm.moc" diff --git a/kcontrol/colors/colorscm.h b/kcontrol/colors/colorscm.h new file mode 100644 index 00000000..c88567ae --- /dev/null +++ b/kcontrol/colors/colorscm.h @@ -0,0 +1,216 @@ +/* KDE Display color scheme setup module + * Copyright (C) 2007 Matthew Woehlke + * Copyright (C) 2007 Jeremy Whiting + * + * 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 __COLORSCM_H__ +#define __COLORSCM_H__ + +#include +#include +#include + +#include "ui_colorsettings.h" + +class QStackedWidget; +class QListWidgetItem; + +/** + * The Desktop/Colors tab in kcontrol. + */ +class KColorCm : public KCModule, public Ui::colorSettings +{ + Q_OBJECT + +public: + KColorCm(QWidget *parent, const QVariantList &); + ~KColorCm(); + +public Q_SLOTS: + + /// load the settings from the config + virtual void load(); + + /// save the current settings + virtual void save(); + + /// sets the configuration to sensible default values. + virtual void defaults(); + +private slots: + + /** set the colortable color buttons up according to the current colorset */ + void updateColorTable(); + + /** slot called when color on a KColorButton changes */ + void colorChanged( const QColor &newColor ); + + /** slot called when any varies button is clicked */ + void variesClicked(); + + /** slot called when the schemeList selection changes */ + void loadScheme(QListWidgetItem *currentItem, QListWidgetItem *previousItem); + + /** reselect the previously selected scheme in schemeList without loading it */ + void selectPreviousSchemeAgain(); + + /** slot called when the remove button is clicked*/ + void on_schemeRemoveButton_clicked(); + + /** slot called when the save button is clicked */ + void on_schemeSaveButton_clicked(); + + /** slot called when the import button is clicked */ + void on_schemeImportButton_clicked(); + + /** slot called when the get new schemes button is clicked */ + void on_schemeKnsButton_clicked(); + + /** slot called when the upload scheme button is clicked */ + void on_schemeKnsUploadButton_clicked(); + + /** null slot to emit changed(true) */ + void emitChanged(); + + // options slots + void on_contrastSlider_valueChanged(int value); + void on_shadeSortedColumn_stateChanged(int state); + void on_inactiveSelectionEffect_stateChanged(int state); + void on_useInactiveEffects_stateChanged(int state); + + // effects page slots + void on_inactiveIntensityBox_currentIndexChanged(int index); + void on_inactiveIntensitySlider_valueChanged(int value); + void on_inactiveColorBox_currentIndexChanged(int index); + void on_inactiveColorSlider_valueChanged(int value); + void on_inactiveColorButton_changed(const QColor & color); + void on_inactiveContrastBox_currentIndexChanged(int index); + void on_inactiveContrastSlider_valueChanged(int value); + + void on_disabledIntensityBox_currentIndexChanged(int index); + void on_disabledIntensitySlider_valueChanged(int value); + void on_disabledColorBox_currentIndexChanged(int index); + void on_disabledColorSlider_valueChanged(int value); + void on_disabledColorButton_changed(const QColor & color); + void on_disabledContrastBox_currentIndexChanged(int index); + void on_disabledContrastSlider_valueChanged(int value); + +private: + class WindecoColors { + public: + enum Role { + ActiveForeground = 0, + ActiveBackground = 1, + InactiveForeground = 2, + InactiveBackground = 3, + ActiveBlend = 4, + InactiveBlend = 5 + }; + + WindecoColors() {} + WindecoColors(const KSharedConfigPtr&); + virtual ~WindecoColors() {} + + void load(const KSharedConfigPtr&); + QColor color(Role) const; + private: + QColor m_colors[6]; + }; + + /** create a preview of a color scheme */ + static QPixmap createSchemePreviewIcon(const KSharedConfigPtr &config); + + /** load options from global */ + void loadOptions(); + + /** load from global */ + void loadInternal(bool loadOptions); + + /** load a scheme from a config file at a given path */ + void loadScheme(KSharedConfigPtr config); + + /** populate the schemeList with color schemes found on the system */ + void populateSchemeList(); + + /** update m_colorSchemes contents from the values in m_config */ + void updateColorSchemes(); + + /** update the effects page from the values in m_config */ + void updateEffectsPage(); + + /** update all preview panes from the values in m_config */ + void updatePreviews(); + + /** setup the colortable with its buttons and labels */ + void setupColorTable(); + + /** helper to create color entries */ + void createColorEntry(const QString &text, + const QString &key, + QList &list, + int index); + + /** copy color entries from color schemes into m_config */ + void updateFromColorSchemes(); + + /** copy effects page entries from controls into m_config */ + void updateFromEffectsPage(); + + /** copy options from controls into m_config */ + void updateFromOptions(); + + void changeColor(int row, const QColor &newColor); + + /** get the groupKey for the given colorSet */ + static QString colorSetGroupKey(int colorSet); + + /** save the current scheme with the given name + @param name name to save the scheme as + */ + void saveScheme(const QString &name); + + void setCommonForeground(KColorScheme::ForegroundRole role, + int stackIndex, + int buttonIndex); + void setCommonDecoration(KColorScheme::DecorationRole role, + int stackIndex, + int buttonIndex); + + QList m_backgroundButtons; + QList m_foregroundButtons; + QList m_decorationButtons; + QList m_commonColorButtons; + QList m_stackedWidgets; + QStringList m_colorKeys; + + QList m_colorSchemes; + WindecoColors m_wmColors; + QString m_currentColorScheme; + + KSharedConfigPtr m_config; + + bool m_disableUpdates; + bool m_loadedSchemeHasUnsavedChanges; + // don't (re)load the scheme, only select it in schemeList + bool m_dontLoadSelectedScheme; + + // the item previously selected in schemeList + QListWidgetItem *m_previousSchemeItem; +}; + +#endif diff --git a/kcontrol/colors/colorsettings.ui b/kcontrol/colors/colorsettings.ui new file mode 100644 index 00000000..cbc2e84d --- /dev/null +++ b/kcontrol/colors/colorsettings.ui @@ -0,0 +1,1298 @@ + + + colorSettings + + + + 0 + 0 + 477 + 422 + + + + + 0 + + + + + 0 + + + + &Scheme + + + + + + + 0 + 0 + + + + + 23 + 16 + + + + + + + + + + Get new color schemes from the Internet + + + Get &New Schemes... + + + + + + + false + + + Share the selected scheme on the Internet + + + &Upload Scheme... + + + + + + + Import a color scheme from a file + + + Import Scheme... + + + + + + + Save the current color scheme + + + Save Scheme... + + + + + + + false + + + Remove the selected scheme + + + Remove Scheme + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + Preview + + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + + + + + + + + Options + + + + + + Apply inactive window color &effects + + + + + + + In&active selection changes color + + + + + + + Shade sorted column &in lists + + + + + + + true + + + Apply colors to &non-KDE4 applications + + + + + + + Shading of frames and lighting ("3D") effects + + + Shading + + + + 12 + + + 0 + + + + + Minimum + + + + + + + Qt::Horizontal + + + + 198 + 20 + + + + + + + + Maximum + + + + + + + Contrast + + + + + + + 10 + + + 5 + + + Qt::Horizontal + + + + + + + + + + Qt::Vertical + + + + 20 + 141 + + + + + + + + + Colors + + + + + + + 0 + 0 + + + + Color set: + + + + + + + + 0 + 0 + + + + Colorset to view/modify + + + + Common Colors + + + + + View + + + + + Window + + + + + Button + + + + + Selection + + + + + Tooltip + + + + + + + + 0 + + + + + 0 + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + 2 + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + 0 + + + + + 1 + + + + + View Background + + + + + View Text + + + + + Window Background + + + + + Window Text + + + + + Button Background + + + + + Button Text + + + + + Selection Background + + + + + Selection Text + + + + + Selection Inactive Text + + + + + Inactive Text + + + + + Active Text + + + + + Link Text + + + + + Visited Text + + + + + Negative Text + + + + + Neutral Text + + + + + Positive Text + + + + + Focus Decoration + + + + + Hover Decoration + + + + + Tooltip Background + + + + + Tooltip Text + + + + + Active Titlebar + + + + + Active Titlebar Text + + + + + Active Titlebar Secondary + + + + + Inactive Titlebar + + + + + Inactive Titlebar Text + + + + + Inactive Titlebar Secondary + + + + + + + + + + 0 + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + 2 + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Preview + + + + + + 0 + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + + + + + + + + + + + + Inactive + + + + + + Intensity: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Inactive intensity effect type + + + + None + + + + + Shade + + + + + Darken + + + + + Lighten + + + + + + + + false + + + Inactive intensity effect amount + + + 40 + + + 10 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 69 + 22 + + + + + + + + Color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Inactive color effect type + + + + None + + + + + Desaturate + + + + + Fade + + + + + Tint + + + + + + + + false + + + Inactive color amount + + + 40 + + + 10 + + + Qt::Horizontal + + + + + + + false + + + Inactive color + + + + + + + Contrast: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Inactive contrast effect type + + + + None + + + + + Fade + + + + + Tint + + + + + + + + false + + + Inactive contrast effect amount + + + 20 + + + 5 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 69 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Preview + + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + + + + + + + + Disabled + + + + + + Intensity: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Disabled intensity effect type + + + + None + + + + + Shade + + + + + Darken + + + + + Lighten + + + + + + + + false + + + Disabled intensity effect amount + + + 40 + + + 10 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 69 + 22 + + + + + + + + Color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Disabled color effect type + + + + None + + + + + Desaturate + + + + + Fade + + + + + Tint + + + + + + + + false + + + Disabled color effect amount + + + 40 + + + 10 + + + Qt::Horizontal + + + + + + + false + + + Disabled color + + + + + + + Contrast: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Disabled contrast type + + + + None + + + + + Fade + + + + + Tint + + + + + + + + false + + + Disabled contrast amount + + + 20 + + + 10 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 69 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Preview + + + + + + + 0 + 0 + + + + + 0 + 10 + + + + + + + + + + + + + + + + KListWidget + QListWidget +
    klistwidget.h
    +
    + + KPushButton + QPushButton +
    kpushbutton.h
    +
    + + KColorButton + QPushButton +
    kcolorbutton.h
    +
    + + PreviewWidget + QWidget +
    previewwidget.h
    + 1 +
    + + SetPreviewWidget + QWidget +
    setpreviewwidget.h
    + 1 +
    +
    + + tabWidget + schemeList + schemeKnsButton + schemeImportButton + schemeSaveButton + schemeRemoveButton + useInactiveEffects + inactiveSelectionEffect + shadeSortedColumn + applyToAlien + contrastSlider + colorSet + commonColorTable + inactiveIntensityBox + inactiveIntensitySlider + inactiveColorBox + inactiveColorSlider + inactiveContrastBox + inactiveContrastSlider + inactiveColorButton + disabledIntensityBox + disabledIntensitySlider + disabledColorBox + disabledColorSlider + disabledContrastBox + disabledContrastSlider + disabledColorButton + colorTable + + + +
    diff --git a/kcontrol/colors/preview.ui b/kcontrol/colors/preview.ui new file mode 100644 index 00000000..8dde5c13 --- /dev/null +++ b/kcontrol/colors/preview.ui @@ -0,0 +1,336 @@ + + + preview + + + + 0 + 0 + 467 + 100 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + Window text on Window Background + + + Window text + + + + + + + true + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + 0 + + + + + + 2 + + + + + View Normal Text against View Normal Background + + + Normal text + + + + + + + + true + + + + View Link Text against View Normal Background + + + link + + + + + + + + true + + + + View Visited Text against View Normal Background + + + visited + + + + + + + View Active Text against View Normal Background + + + a + + + + + + + View Inactive Text against View Normal Background + + + i + + + + + + + View Negative Text against View Normal Background + + + ! + + + + + + + View Neutral Text against View Normal Background + + + = + + + + + + + View Positive Text against View Normal Background + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 4 + 51 + + + + + + + + true + + + + 2 + + + + + Selection Normal Text against Selection Normal Background + + + Selected text + + + + + + + + true + + + + Selection Link Text against Selection Normal Background + + + link + + + + + + + + true + + + + Selection Visited Text against Selection Normal Background + + + visited + + + + + + + Selection Active Text against Selection Normal Background + + + a + + + + + + + Selection Inactive Text against Selection Normal Background + + + i + + + + + + + Selection Negative Text against Selection Normal Background + + + ! + + + + + + + Selection Neutral Text against Selection Normal Background + + + = + + + + + + + Selection Positive Text against Selection Normal Background + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 141 + 0 + + + + + + + + + + + Button text on Button Background + + + Push Button + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 0 + + + + + + + + + diff --git a/kcontrol/colors/previewwidget.cpp b/kcontrol/colors/previewwidget.cpp new file mode 100644 index 00000000..5be7567a --- /dev/null +++ b/kcontrol/colors/previewwidget.cpp @@ -0,0 +1,168 @@ +/* Preview widget for KDE Display color scheme setup module + * Copyright (C) 2007 Matthew Woehlke + * eventFilter code Copyright (C) 2007 Urs Wolfer + * + * 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 "previewwidget.h" + +#include +#include + +#include + +PreviewWidget::PreviewWidget(QWidget *parent) : QFrame(parent) +{ + setupUi(this); + + // set correct colors on... lots of things + setAutoFillBackground(true); + frame->setBackgroundRole(QPalette::Base); + viewWidget->setBackgroundRole(QPalette::Base); + labelView0->setBackgroundRole(QPalette::Base); + labelView3->setBackgroundRole(QPalette::Base); + labelView4->setBackgroundRole(QPalette::Base); + labelView2->setBackgroundRole(QPalette::Base); + labelView1->setBackgroundRole(QPalette::Base); + labelView5->setBackgroundRole(QPalette::Base); + labelView6->setBackgroundRole(QPalette::Base); + labelView7->setBackgroundRole(QPalette::Base); + selectionWidget->setBackgroundRole(QPalette::Highlight); + labelSelection0->setBackgroundRole(QPalette::Highlight); + labelSelection3->setBackgroundRole(QPalette::Highlight); + labelSelection4->setBackgroundRole(QPalette::Highlight); + labelSelection2->setBackgroundRole(QPalette::Highlight); + labelSelection1->setBackgroundRole(QPalette::Highlight); + labelSelection5->setBackgroundRole(QPalette::Highlight); + labelSelection6->setBackgroundRole(QPalette::Highlight); + labelSelection7->setBackgroundRole(QPalette::Highlight); + + QList widgets = findChildren(); + foreach (QWidget* widget, widgets) + { + widget->installEventFilter(this); + widget->setFocusPolicy(Qt::NoFocus); + } +} + +PreviewWidget::~PreviewWidget() +{ +} + +bool PreviewWidget::eventFilter(QObject *, QEvent *ev) +{ + switch (ev->type()) + { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::Enter: + case QEvent::Leave: + case QEvent::Wheel: + case QEvent::ContextMenu: + return true; // ignore + default: + break; + } + return false; +} + +inline void copyPaletteBrush(QPalette &palette, QPalette::ColorGroup state, + QPalette::ColorRole role) +{ + palette.setBrush(QPalette::Active, role, palette.brush(state, role)); + if (state == QPalette::Disabled) + // ### hack, while Qt has no inactive+disabled state + // TODO copy from Inactive+Disabled to Inactive instead + palette.setBrush(QPalette::Inactive, role, + palette.brush(QPalette::Disabled, role)); +} + +void PreviewWidget::setPaletteRecursive(QWidget *widget, + const QPalette &palette) +{ + widget->setPalette(palette); + + const QObjectList children = widget->children(); + foreach (QObject *child, children) { + if (child->isWidgetType()) + setPaletteRecursive((QWidget*)child, palette); + } +} + +inline void adjustWidgetForeground(QWidget *widget, QPalette::ColorGroup state, + const KSharedConfigPtr &config, + QPalette::ColorRole color, + KColorScheme::ColorSet set, + KColorScheme::ForegroundRole role) +{ + QPalette palette = widget->palette(); + KColorScheme::adjustForeground(palette, role, color, set, config); + copyPaletteBrush(palette, state, color); + widget->setPalette(palette); +} + +void PreviewWidget::setPalette(const KSharedConfigPtr &config, + QPalette::ColorGroup state) +{ + QPalette palette = KGlobalSettings::createNewApplicationPalette(config); + + if (state != QPalette::Active) { + copyPaletteBrush(palette, state, QPalette::Base); + copyPaletteBrush(palette, state, QPalette::Text); + copyPaletteBrush(palette, state, QPalette::Window); + copyPaletteBrush(palette, state, QPalette::WindowText); + copyPaletteBrush(palette, state, QPalette::Button); + copyPaletteBrush(palette, state, QPalette::ButtonText); + copyPaletteBrush(palette, state, QPalette::Highlight); + copyPaletteBrush(palette, state, QPalette::HighlightedText); + copyPaletteBrush(palette, state, QPalette::AlternateBase); + copyPaletteBrush(palette, state, QPalette::Link); + copyPaletteBrush(palette, state, QPalette::LinkVisited); + copyPaletteBrush(palette, state, QPalette::Light); + copyPaletteBrush(palette, state, QPalette::Midlight); + copyPaletteBrush(palette, state, QPalette::Mid); + copyPaletteBrush(palette, state, QPalette::Dark); + copyPaletteBrush(palette, state, QPalette::Shadow); + } + + setPaletteRecursive(this, palette); + +#define ADJUST_WIDGET_FOREGROUND(w,c,s,r) \ + adjustWidgetForeground(w, state, config, QPalette::c, KColorScheme::s, KColorScheme::r); + + ADJUST_WIDGET_FOREGROUND(labelView1, Text, View, InactiveText); + ADJUST_WIDGET_FOREGROUND(labelView2, Text, View, ActiveText); + ADJUST_WIDGET_FOREGROUND(labelView3, Text, View, LinkText); + ADJUST_WIDGET_FOREGROUND(labelView4, Text, View, VisitedText); + ADJUST_WIDGET_FOREGROUND(labelView5, Text, View, NegativeText); + ADJUST_WIDGET_FOREGROUND(labelView6, Text, View, NeutralText); + ADJUST_WIDGET_FOREGROUND(labelView7, Text, View, PositiveText); + + ADJUST_WIDGET_FOREGROUND(labelSelection1, HighlightedText, Selection, InactiveText); + ADJUST_WIDGET_FOREGROUND(labelSelection2, HighlightedText, Selection, ActiveText); + ADJUST_WIDGET_FOREGROUND(labelSelection3, HighlightedText, Selection, LinkText); + ADJUST_WIDGET_FOREGROUND(labelSelection4, HighlightedText, Selection, VisitedText); + ADJUST_WIDGET_FOREGROUND(labelSelection5, HighlightedText, Selection, NegativeText); + ADJUST_WIDGET_FOREGROUND(labelSelection6, HighlightedText, Selection, NeutralText); + ADJUST_WIDGET_FOREGROUND(labelSelection7, HighlightedText, Selection, PositiveText); +} + +#include "previewwidget.moc" diff --git a/kcontrol/colors/previewwidget.h b/kcontrol/colors/previewwidget.h new file mode 100644 index 00000000..730b2f29 --- /dev/null +++ b/kcontrol/colors/previewwidget.h @@ -0,0 +1,49 @@ +/* Preview widget for KDE Display color scheme setup module + * Copyright (C) 2007 Matthew Woehlke + * + * 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 __SCHEMEPREVIEW_H__ +#define __SCHEMEPREVIEW_H__ + +#include +#include + +#include + +#include "ui_preview.h" + +/** + * The Desktop/Colors tab in kcontrol. + */ +class PreviewWidget : public QFrame, Ui::preview +{ + Q_OBJECT + +public: + PreviewWidget(QWidget *parent); + virtual ~PreviewWidget(); + + void setPalette(const KSharedConfigPtr &config, + QPalette::ColorGroup state = QPalette::Active); + +protected: + void setPaletteRecursive(QWidget*, const QPalette&); + bool eventFilter(QObject *, QEvent *); +}; + +#endif diff --git a/kcontrol/colors/schemes/Honeycomb.colors b/kcontrol/colors/schemes/Honeycomb.colors new file mode 100644 index 00000000..2db8c570 --- /dev/null +++ b/kcontrol/colors/schemes/Honeycomb.colors @@ -0,0 +1,96 @@ +[ColorEffects:Disabled] +Color=48,43,30 +ColorAmount=0.125 +ColorEffect=2 +ContrastAmount=0.5 +ContrastEffect=1 +IntensityAmount=0.05 +IntensityEffect=0 + +[ColorEffects:Inactive] +Color=227,170,0 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.25 +ContrastEffect=1 +IntensityAmount=0.05 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=136,138,133 +BackgroundNormal=186,189,183 +DecorationFocus=85,85,85 +DecorationHover=243,195,0 +ForegroundActive=191,92,0 +ForegroundInactive=117,80,25 +ForegroundLink=232,82,144 +ForegroundNegative=191,3,3 +ForegroundNeutral=43,116,199 +ForegroundNormal=0,0,0 +ForegroundPositive=0,137,43 +ForegroundVisited=100,74,155 + +[Colors:Selection] +BackgroundAlternate=243,195,0 +BackgroundNormal=227,170,0 +DecorationFocus=85,85,85 +DecorationHover=243,195,0 +ForegroundActive=191,92,0 +ForegroundInactive=255,235,85 +ForegroundLink=232,82,144 +ForegroundNegative=191,3,3 +ForegroundNeutral=43,116,199 +ForegroundNormal=255,255,255 +ForegroundPositive=0,137,43 +ForegroundVisited=100,74,155 + +[Colors:Tooltip] +BackgroundAlternate=255,235,85 +BackgroundNormal=255,242,153 +DecorationFocus=85,85,85 +DecorationHover=243,195,0 +ForegroundActive=191,92,0 +ForegroundInactive=117,80,25 +ForegroundLink=232,82,144 +ForegroundNegative=191,3,3 +ForegroundNeutral=43,116,199 +ForegroundNormal=64,48,0 +ForegroundPositive=0,137,43 +ForegroundVisited=100,74,155 + +[Colors:View] +BackgroundAlternate=255,251,231 +BackgroundNormal=255,255,255 +DecorationFocus=85,85,85 +DecorationHover=243,195,0 +ForegroundActive=191,92,0 +ForegroundInactive=117,80,25 +ForegroundLink=232,82,144 +ForegroundNegative=191,3,3 +ForegroundNeutral=43,116,199 +ForegroundNormal=0,0,0 +ForegroundPositive=0,137,43 +ForegroundVisited=100,74,155 + +[Colors:Window] +BackgroundAlternate=186,189,183 +BackgroundNormal=212,215,208 +DecorationFocus=85,85,85 +DecorationHover=243,195,0 +ForegroundActive=191,92,0 +ForegroundInactive=117,80,25 +ForegroundLink=232,82,144 +ForegroundNegative=191,3,3 +ForegroundNeutral=43,116,199 +ForegroundNormal=0,0,0 +ForegroundPositive=0,137,43 +ForegroundVisited=100,74,155 + +[General] +Name=Honeycomb + +[WM] +activeBackground=227,170,0 +activeForeground=255,255,255 +inactiveBackground=136,138,133 +inactiveForeground=46,52,54 diff --git a/kcontrol/colors/schemes/Norway.colors b/kcontrol/colors/schemes/Norway.colors new file mode 100644 index 00000000..abf78bcd --- /dev/null +++ b/kcontrol/colors/schemes/Norway.colors @@ -0,0 +1,96 @@ +[ColorEffects:Disabled] +Color=197,179,153 +ColorAmount=0.5 +ColorEffect=2 +ContrastAmount=0.25 +ContrastEffect=1 +IntensityAmount=0.25 +IntensityEffect=0 + +[ColorEffects:Inactive] +Color=213,198,176 +ColorAmount=0.1 +ColorEffect=2 +ContrastAmount=0.25 +ContrastEffect=1 +IntensityAmount=-0.05 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=246,240,227 +BackgroundNormal=247,242,232 +DecorationFocus=128,112,96 +DecorationHover=29,135,205 +ForegroundActive=0,197,204 +ForegroundInactive=197,179,153 +ForegroundLink=0,87,174 +ForegroundNegative=232,87,82 +ForegroundNeutral=227,170,0 +ForegroundNormal=0,0,0 +ForegroundPositive=120,183,83 +ForegroundVisited=100,74,155 + +[Colors:Selection] +BackgroundAlternate=27,131,196 +BackgroundNormal=29,132,205 +DecorationFocus=128,112,96 +DecorationHover=29,135,205 +ForegroundActive=0,197,204 +ForegroundInactive=144,192,232 +ForegroundLink=0,87,174 +ForegroundNegative=232,87,82 +ForegroundNeutral=227,170,0 +ForegroundNormal=255,255,255 +ForegroundPositive=120,183,83 +ForegroundVisited=100,74,155 + +[Colors:Tooltip] +BackgroundAlternate=250,248,241 +BackgroundNormal=253,252,251 +DecorationFocus=128,112,96 +DecorationHover=29,135,205 +ForegroundActive=0,197,204 +ForegroundInactive=197,179,153 +ForegroundLink=0,87,174 +ForegroundNegative=232,87,82 +ForegroundNeutral=227,170,0 +ForegroundNormal=0,0,0 +ForegroundPositive=120,183,83 +ForegroundVisited=100,74,155 + +[Colors:View] +BackgroundAlternate=250,246,239 +BackgroundNormal=253,252,250 +DecorationFocus=128,112,96 +DecorationHover=29,135,205 +ForegroundActive=0,197,204 +ForegroundInactive=197,179,153 +ForegroundLink=0,87,174 +ForegroundNegative=232,87,82 +ForegroundNeutral=227,170,0 +ForegroundNormal=0,0,0 +ForegroundPositive=120,183,83 +ForegroundVisited=100,74,155 + +[Colors:Window] +BackgroundAlternate=233,223,206 +BackgroundNormal=235,226,210 +DecorationFocus=128,112,96 +DecorationHover=29,135,205 +ForegroundActive=0,197,204 +ForegroundInactive=197,179,153 +ForegroundLink=0,87,174 +ForegroundNegative=232,87,82 +ForegroundNeutral=227,170,0 +ForegroundNormal=0,0,0 +ForegroundPositive=120,183,83 +ForegroundVisited=100,74,155 + +[General] +Name=Norway + +[WM] +activeBackground=29,135,205 +activeForeground=255,255,255 +inactiveBackground=128,112,96 +inactiveForeground=253,252,251 diff --git a/kcontrol/colors/schemes/ObsidianCoast.colors b/kcontrol/colors/schemes/ObsidianCoast.colors new file mode 100644 index 00000000..0245ee18 --- /dev/null +++ b/kcontrol/colors/schemes/ObsidianCoast.colors @@ -0,0 +1,95 @@ +[ColorEffects:Disabled] +ColorAmount=-0.8 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.25 +IntensityEffect=2 + +[ColorEffects:Inactive] +Color=0,0,0 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.4 +ContrastEffect=2 +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=66,65,64 +BackgroundNormal=64,63,62 +DecorationFocus=39,94,160 +DecorationHover=87,129,176 +ForegroundActive=150,191,240 +ForegroundInactive=120,119,117 +ForegroundLink=80,142,216 +ForegroundNegative=232,88,72 +ForegroundNeutral=192,162,95 +ForegroundNormal=232,230,227 +ForegroundPositive=120,183,83 +ForegroundVisited=142,121,165 + +[Colors:Selection] +BackgroundAlternate=22,68,120 +BackgroundNormal=24,72,128 +DecorationFocus=39,94,160 +DecorationHover=87,129,176 +ForegroundActive=150,191,240 +ForegroundInactive=81,119,166 +ForegroundLink=80,142,216 +ForegroundNegative=232,88,72 +ForegroundNeutral=192,162,95 +ForegroundNormal=255,255,255 +ForegroundPositive=120,183,83 +ForegroundVisited=142,121,165 + +[Colors:Tooltip] +BackgroundAlternate=17,51,86 +BackgroundNormal=16,48,80 +DecorationFocus=39,94,160 +DecorationHover=87,129,176 +ForegroundActive=150,191,240 +ForegroundInactive=120,119,117 +ForegroundLink=80,142,216 +ForegroundNegative=232,88,72 +ForegroundNeutral=192,162,95 +ForegroundNormal=196,209,224 +ForegroundPositive=120,183,83 +ForegroundVisited=142,121,165 + +[Colors:View] +BackgroundAlternate=36,35,35 +BackgroundNormal=32,31,31 +DecorationFocus=39,94,160 +DecorationHover=87,129,176 +ForegroundActive=150,191,240 +ForegroundInactive=120,119,117 +ForegroundLink=80,142,216 +ForegroundNegative=232,88,72 +ForegroundNeutral=192,162,95 +ForegroundNormal=212,210,207 +ForegroundPositive=120,183,83 +ForegroundVisited=142,121,165 + +[Colors:Window] +BackgroundAlternate=52,51,50 +BackgroundNormal=48,47,47 +DecorationFocus=39,94,160 +DecorationHover=87,129,176 +ForegroundActive=150,191,240 +ForegroundInactive=120,119,117 +ForegroundLink=80,142,216 +ForegroundNegative=232,88,72 +ForegroundNeutral=192,162,95 +ForegroundNormal=224,222,219 +ForegroundPositive=120,183,83 +ForegroundVisited=142,121,165 + +[General] +Name=Obsidian Coast + +[WM] +activeBackground=19,47,80 +activeForeground=255,255,255 +inactiveBackground=64,63,62 +inactiveForeground=128,127,125 diff --git a/kcontrol/colors/schemes/Oxygen.colors b/kcontrol/colors/schemes/Oxygen.colors new file mode 100644 index 00000000..da9116b3 --- /dev/null +++ b/kcontrol/colors/schemes/Oxygen.colors @@ -0,0 +1,103 @@ +[ColorEffects:Disabled] +Color=56,56,56 +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +ChangeSelectionColor=true +Color=112,111,110 +ColorAmount=-0.9 +ColorEffect=1 +ContrastAmount=0.25 +ContrastEffect=2 +Enable=true +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=224,223,222 +BackgroundNormal=223,220,217 +DecorationFocus=58,167,221 +DecorationHover=110,214,255 +ForegroundActive=146,76,157 +ForegroundInactive=137,136,135 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=34,31,30 +ForegroundPositive=0,110,40 +ForegroundVisited=100,74,155 + +[Colors:Selection] +BackgroundAlternate=62,138,204 +BackgroundNormal=67,172,232 +DecorationFocus=58,167,221 +DecorationHover=110,214,255 +ForegroundActive=108,36,119 +ForegroundInactive=199,226,248 +ForegroundLink=0,49,110 +ForegroundNegative=156,14,14 +ForegroundNeutral=255,221,0 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=69,40,134 + +[Colors:Tooltip] +BackgroundAlternate=196,224,255 +BackgroundNormal=24,21,19 +DecorationFocus=58,167,221 +DecorationHover=110,214,255 +ForegroundActive=255,128,224 +ForegroundInactive=137,136,135 +ForegroundLink=88,172,255 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=231,253,255 +ForegroundPositive=0,110,40 +ForegroundVisited=150,111,232 + +[Colors:View] +BackgroundAlternate=248,247,246 +BackgroundNormal=255,255,255 +DecorationFocus=58,167,221 +DecorationHover=110,214,255 +ForegroundActive=146,76,157 +ForegroundInactive=137,136,135 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=31,28,27 +ForegroundPositive=0,110,40 +ForegroundVisited=100,74,155 + +[Colors:Window] +BackgroundAlternate=218,217,216 +BackgroundNormal=214,210,208 +DecorationFocus=58,167,221 +DecorationHover=110,214,255 +ForegroundActive=146,76,157 +ForegroundInactive=137,136,135 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=34,31,30 +ForegroundPositive=0,110,40 +ForegroundVisited=100,74,155 + +[General] +ColorScheme=Oxygen +Name=Oxygen +shadeSortColumn=true + +[KDE] +contrast=7 + +[WM] +activeBackground=48,174,232 +activeForeground=255,255,255 +inactiveBackground=224,223,222 +inactiveForeground=75,71,67 diff --git a/kcontrol/colors/schemes/OxygenCold.colors b/kcontrol/colors/schemes/OxygenCold.colors new file mode 100644 index 00000000..53d7777b --- /dev/null +++ b/kcontrol/colors/schemes/OxygenCold.colors @@ -0,0 +1,95 @@ +[ColorEffects:Disabled] +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +Color=112,111,110 +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.1 +ContrastEffect=2 +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=224,223,222 +BackgroundNormal=232,231,230 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=136,135,134 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=69,40,134 + +[Colors:Selection] +BackgroundAlternate=62,138,204 +BackgroundNormal=65,139,212 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=165,193,228 +ForegroundLink=0,49,110 +ForegroundNegative=156,14,14 +ForegroundNeutral=255,221,0 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=69,40,134 + +[Colors:Tooltip] +BackgroundAlternate=196,224,255 +BackgroundNormal=192,218,255 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=96,112,128 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=69,40,134 + +[Colors:View] +BackgroundAlternate=248,247,246 +BackgroundNormal=255,255,255 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=136,135,134 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=69,40,134 + +[Colors:Window] +BackgroundAlternate=218,217,216 +BackgroundNormal=224,223,222 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=136,135,134 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=69,40,134 + +[General] +Name=Oxygen Cold + +[WM] +activeBackground=96,148,207 +activeForeground=255,255,255 +inactiveBackground=224,223,222 +inactiveForeground=20,19,18 diff --git a/kcontrol/colors/schemes/Steel.colors b/kcontrol/colors/schemes/Steel.colors new file mode 100644 index 00000000..3ebd8b4c --- /dev/null +++ b/kcontrol/colors/schemes/Steel.colors @@ -0,0 +1,95 @@ +[ColorEffects:Disabled] +ColorAmount=-0.9 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.25 +IntensityEffect=2 + +[ColorEffects:Inactive] +Color=135,133,129 +ColorAmount=0.05 +ColorEffect=2 +ContrastAmount=0.25 +ContrastEffect=2 +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=224,223,216 +BackgroundNormal=232,231,223 +DecorationFocus=69,98,112 +DecorationHover=74,139,163 +ForegroundActive=232,87,82 +ForegroundInactive=148,133,111 +ForegroundLink=41,111,190 +ForegroundNegative=139,83,127 +ForegroundNeutral=191,165,103 +ForegroundNormal=0,0,0 +ForegroundPositive=67,102,46 +ForegroundVisited=100,74,155 + +[Colors:Selection] +BackgroundAlternate=118,154,165 +BackgroundNormal=123,160,173 +DecorationFocus=69,98,112 +DecorationHover=74,139,163 +ForegroundActive=232,87,82 +ForegroundInactive=178,197,204 +ForegroundLink=41,111,190 +ForegroundNegative=139,83,127 +ForegroundNeutral=191,165,103 +ForegroundNormal=255,255,255 +ForegroundPositive=67,102,46 +ForegroundVisited=100,74,155 + +[Colors:Tooltip] +BackgroundAlternate=216,228,231 +BackgroundNormal=219,231,235 +DecorationFocus=69,98,112 +DecorationHover=74,139,163 +ForegroundActive=232,87,82 +ForegroundInactive=148,133,111 +ForegroundLink=41,111,190 +ForegroundNegative=139,83,127 +ForegroundNeutral=191,165,103 +ForegroundNormal=37,34,28 +ForegroundPositive=67,102,46 +ForegroundVisited=100,74,155 + +[Colors:View] +BackgroundAlternate=250,250,248 +BackgroundNormal=255,255,255 +DecorationFocus=69,98,112 +DecorationHover=74,139,163 +ForegroundActive=232,87,82 +ForegroundInactive=148,133,111 +ForegroundLink=41,111,190 +ForegroundNegative=139,83,127 +ForegroundNeutral=191,165,103 +ForegroundNormal=0,0,0 +ForegroundPositive=67,102,46 +ForegroundVisited=100,74,155 + +[Colors:Window] +BackgroundAlternate=212,211,204 +BackgroundNormal=224,223,216 +DecorationFocus=69,98,112 +DecorationHover=74,139,163 +ForegroundActive=232,87,82 +ForegroundInactive=148,133,111 +ForegroundLink=41,111,190 +ForegroundNegative=139,83,127 +ForegroundNeutral=191,165,103 +ForegroundNormal=0,0,0 +ForegroundPositive=67,102,46 +ForegroundVisited=100,74,155 + +[General] +Name=Steel + +[WM] +activeBackground=74,139,163 +activeForeground=255,255,255 +inactiveBackground=208,206,192 +inactiveForeground=100,92,72 diff --git a/kcontrol/colors/schemes/WontonSoup.colors b/kcontrol/colors/schemes/WontonSoup.colors new file mode 100644 index 00000000..34ebaa99 --- /dev/null +++ b/kcontrol/colors/schemes/WontonSoup.colors @@ -0,0 +1,94 @@ +[ColorEffects:Disabled] +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.25 +IntensityEffect=2 + +[ColorEffects:Inactive] +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.25 +ContrastEffect=2 +IntensityAmount=0.05 +IntensityEffect=2 + +[Colors:Button] +BackgroundAlternate=90,98,109 +BackgroundNormal=82,88,99 +DecorationFocus=125,141,153 +DecorationHover=119,149,179 +ForegroundActive=255,255,255 +ForegroundInactive=135,143,154 +ForegroundLink=156,212,255 +ForegroundNegative=225,150,209 +ForegroundNeutral=218,198,115 +ForegroundNormal=210,222,240 +ForegroundPositive=145,221,100 +ForegroundVisited=64,128,255 + +[Colors:Selection] +BackgroundAlternate=111,126,144 +BackgroundNormal=120,136,156 +DecorationFocus=125,141,153 +DecorationHover=119,149,179 +ForegroundActive=255,255,255 +ForegroundInactive=174,192,218 +ForegroundLink=156,212,255 +ForegroundNegative=225,150,209 +ForegroundNeutral=218,198,115 +ForegroundNormal=209,225,244 +ForegroundPositive=145,221,100 +ForegroundVisited=64,128,255 + +[Colors:Tooltip] +BackgroundAlternate=171,181,195 +BackgroundNormal=182,193,208 +DecorationFocus=125,141,153 +DecorationHover=119,149,179 +ForegroundActive=255,255,255 +ForegroundInactive=112,118,128 +ForegroundLink=87,161,218 +ForegroundNegative=99,66,92 +ForegroundNeutral=86,78,45 +ForegroundNormal=42,44,48 +ForegroundPositive=57,86,38 +ForegroundVisited=46,95,185 + +[Colors:View] +BackgroundAlternate=67,71,80 +BackgroundNormal=60,64,72 +DecorationFocus=125,141,153 +DecorationHover=119,149,179 +ForegroundActive=255,255,255 +ForegroundInactive=135,143,154 +ForegroundLink=156,212,255 +ForegroundNegative=225,150,209 +ForegroundNeutral=218,198,115 +ForegroundNormal=210,222,240 +ForegroundPositive=145,221,100 +ForegroundVisited=64,128,255 + +[Colors:Window] +BackgroundAlternate=78,83,94 +BackgroundNormal=73,78,88 +DecorationFocus=125,141,153 +DecorationHover=119,149,179 +ForegroundActive=255,255,255 +ForegroundInactive=135,143,154 +ForegroundLink=156,212,255 +ForegroundNegative=225,150,209 +ForegroundNeutral=218,198,115 +ForegroundNormal=182,193,208 +ForegroundPositive=145,221,100 +ForegroundVisited=64,128,255 + +[General] +Name=Wonton Soup + +[WM] +activeBackground=138,151,166 +activeForeground=224,237,255 +inactiveBackground=82,89,99 +inactiveForeground=140,152,168 diff --git a/kcontrol/colors/schemes/Zion.colors b/kcontrol/colors/schemes/Zion.colors new file mode 100644 index 00000000..4427567d --- /dev/null +++ b/kcontrol/colors/schemes/Zion.colors @@ -0,0 +1,96 @@ +[ColorEffects:Disabled] +Color=210,205,218 +ColorAmount=-0.9 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0 +IntensityEffect=0 + +[ColorEffects:Inactive] +Color=0,0,0 +ColorAmount=0.5 +ColorEffect=1 +ContrastAmount=0.25 +ContrastEffect=1 +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=252,252,252 +BackgroundNormal=255,255,255 +DecorationFocus=128,128,128 +DecorationHover=0,0,0 +ForegroundActive=0,102,255 +ForegroundInactive=112,112,112 +ForegroundLink=0,0,192 +ForegroundNegative=128,0,0 +ForegroundNeutral=112,96,0 +ForegroundNormal=0,0,0 +ForegroundPositive=0,96,0 +ForegroundVisited=88,0,176 + +[Colors:Selection] +BackgroundAlternate=171,188,248 +BackgroundNormal=176,192,255 +DecorationFocus=128,128,128 +DecorationHover=0,0,0 +ForegroundActive=0,102,255 +ForegroundInactive=64,64,192 +ForegroundLink=0,0,192 +ForegroundNegative=128,0,0 +ForegroundNeutral=112,96,0 +ForegroundNormal=0,0,0 +ForegroundPositive=0,96,0 +ForegroundVisited=88,0,176 + +[Colors:Tooltip] +BackgroundAlternate=250,250,250 +BackgroundNormal=255,255,255 +DecorationFocus=128,128,128 +DecorationHover=0,0,0 +ForegroundActive=0,102,255 +ForegroundInactive=112,112,112 +ForegroundLink=0,0,192 +ForegroundNegative=128,0,0 +ForegroundNeutral=112,96,0 +ForegroundNormal=0,0,0 +ForegroundPositive=0,96,0 +ForegroundVisited=88,0,176 + +[Colors:View] +BackgroundAlternate=252,252,252 +BackgroundNormal=255,255,255 +DecorationFocus=128,128,128 +DecorationHover=0,0,0 +ForegroundActive=0,102,255 +ForegroundInactive=112,112,112 +ForegroundLink=0,0,192 +ForegroundNegative=128,0,0 +ForegroundNeutral=112,96,0 +ForegroundNormal=0,0,0 +ForegroundPositive=0,96,0 +ForegroundVisited=88,0,176 + +[Colors:Window] +BackgroundAlternate=248,248,248 +BackgroundNormal=252,252,252 +DecorationFocus=128,128,128 +DecorationHover=0,0,0 +ForegroundActive=0,102,255 +ForegroundInactive=112,112,112 +ForegroundLink=0,0,192 +ForegroundNegative=128,0,0 +ForegroundNeutral=112,96,0 +ForegroundNormal=0,0,0 +ForegroundPositive=0,96,0 +ForegroundVisited=88,0,176 + +[General] +Name=Zion + +[WM] +activeBackground=176,193,255 +activeForeground=0,0,0 +inactiveBackground=255,255,255 +inactiveForeground=0,0,0 diff --git a/kcontrol/colors/schemes/ZionReversed.colors b/kcontrol/colors/schemes/ZionReversed.colors new file mode 100644 index 00000000..36131d4a --- /dev/null +++ b/kcontrol/colors/schemes/ZionReversed.colors @@ -0,0 +1,96 @@ +[ColorEffects:Disabled] +Color=56,56,56 +ColorAmount=0.5 +ColorEffect=2 +ContrastAmount=0.5 +ContrastEffect=1 +IntensityAmount=0.05 +IntensityEffect=0 + +[ColorEffects:Inactive] +Color=0,0,0 +ColorAmount=0.5 +ColorEffect=1 +ContrastAmount=0.25 +ContrastEffect=2 +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate=12,12,12 +BackgroundNormal=0,0,0 +DecorationFocus=192,192,192 +DecorationHover=255,255,255 +ForegroundActive=192,255,255 +ForegroundInactive=160,160,160 +ForegroundLink=128,181,255 +ForegroundNegative=255,128,172 +ForegroundNeutral=255,212,128 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=192,128,255 + +[Colors:Selection] +BackgroundAlternate=0,52,116 +BackgroundNormal=0,49,110 +DecorationFocus=192,192,192 +DecorationHover=255,255,255 +ForegroundActive=192,255,255 +ForegroundInactive=96,148,207 +ForegroundLink=128,181,255 +ForegroundNegative=255,128,172 +ForegroundNeutral=255,212,128 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=192,128,255 + +[Colors:Tooltip] +BackgroundAlternate=12,12,12 +BackgroundNormal=0,0,0 +DecorationFocus=192,192,192 +DecorationHover=255,255,255 +ForegroundActive=192,255,255 +ForegroundInactive=160,160,160 +ForegroundLink=128,181,255 +ForegroundNegative=255,128,172 +ForegroundNeutral=255,212,128 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=192,128,255 + +[Colors:View] +BackgroundAlternate=12,12,12 +BackgroundNormal=0,0,0 +DecorationFocus=192,192,192 +DecorationHover=255,255,255 +ForegroundActive=192,255,255 +ForegroundInactive=160,160,160 +ForegroundLink=128,181,255 +ForegroundNegative=255,128,172 +ForegroundNeutral=255,212,128 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=192,128,255 + +[Colors:Window] +BackgroundAlternate=20,20,20 +BackgroundNormal=16,16,16 +DecorationFocus=192,192,192 +DecorationHover=255,255,255 +ForegroundActive=192,255,255 +ForegroundInactive=160,160,160 +ForegroundLink=128,181,255 +ForegroundNegative=255,128,172 +ForegroundNeutral=255,212,128 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=192,128,255 + +[General] +Name=Zion (Reversed) + +[WM] +activeBackground=0,49,110 +activeForeground=255,255,255 +inactiveBackground=64,64,64 +inactiveForeground=128,128,128 diff --git a/kcontrol/colors/setpreview.ui b/kcontrol/colors/setpreview.ui new file mode 100644 index 00000000..09ae55de --- /dev/null +++ b/kcontrol/colors/setpreview.ui @@ -0,0 +1,347 @@ + + + setpreview + + + + 0 + 0 + 550 + 96 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + + + + + + Normal Text on Normal Background + + + normal + + + + + + + + + + + + + + true + + + + Link Text on Normal Background + + + link + + + + + + + + + + + + + + true + + + + Visited Text on Normal Background + + + visited + + + + + + + + + + Active Text on Normal Background + + + + + + active + + + + + + + + + + + + + Inactive Text on Normal Background + + + inactive + + + + + + + + + + + + + Negative Text on Normal Background + + + negative + + + + + + + + + + + + + Neutral Text on Normal Background + + + neutral + + + + + + + + + + + + + Positive Text on Normal Background + + + positive + + + + + + + + + + Hover on Normal Background + + + + + + hover + + + + + + + + + + + + + Normal Text on Normal Background + + + normal + + + + + + + + + + + + + + true + + + + Link Text on Link Background +(Note: Link Background is derived from Link Text and cannot be separately configured at this time) + + + link + + + + + + + + + + + + + + true + + + + Visited Text on Visited Background +(Note: Visited Background is derived from Visited Text and cannot be separately configured at this time) + + + visited + + + + + + + + + + + + + Active Text on Active Background +(Note: Active Background is derived from Active Text and cannot be separately configured at this time) + + + active + + + + + + + + + + + + + Inactive Text on Alternate Background + + + alternate + + + + + + + + + + + + + Negative Text on Negative Background +(Note: Negative Background is derived from Negative Text and cannot be separately configured at this time) + + + negative + + + + + + + + + + + + + Neutral Text on Neutral Background +(Note: Neutral Background is derived from Neutral Text and cannot be separately configured at this time) + + + neutral + + + + + + + + + + + + + Positive Text on Positive Background +(Note: Positive Background is derived from Positive Text and cannot be separately configured at this time) + + + positive + + + + + + + + + + + + + Focus on Normal Background + + + focus + + + + + + + + + + + diff --git a/kcontrol/colors/setpreviewwidget.cpp b/kcontrol/colors/setpreviewwidget.cpp new file mode 100644 index 00000000..98413c55 --- /dev/null +++ b/kcontrol/colors/setpreviewwidget.cpp @@ -0,0 +1,138 @@ +/* Preview widget for KDE Display color scheme setup module + * Copyright (C) 2007 Matthew Woehlke + * eventFilter code Copyright (C) 2007 Urs Wolfer + * + * 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 "setpreviewwidget.h" + +#include + +void setAutoFill(QWidget* widget) +{ + widget->setAutoFillBackground(true); + widget->setBackgroundRole(QPalette::Base); +} + +SetPreviewWidget::SetPreviewWidget(QWidget *parent) : QFrame(parent) +{ + setupUi(this); + + // set correct colors on... lots of things + setAutoFillBackground(true); + setBackgroundRole(QPalette::Base); + setAutoFill(widgetBack0); + setAutoFill(widgetBack1); + setAutoFill(widgetBack2); + setAutoFill(widgetBack3); + setAutoFill(widgetBack4); + setAutoFill(widgetBack5); + setAutoFill(widgetBack6); + setAutoFill(widgetBack7); + setAutoFillBackground(true); +/* + frame->setBackgroundRole(QPalette::Base); + viewWidget->setBackgroundRole(QPalette::Base); + labelView0->setBackgroundRole(QPalette::Base); + labelView3->setBackgroundRole(QPalette::Base); + labelView4->setBackgroundRole(QPalette::Base); + labelView2->setBackgroundRole(QPalette::Base); + labelView1->setBackgroundRole(QPalette::Base); + labelView5->setBackgroundRole(QPalette::Base); + labelView6->setBackgroundRole(QPalette::Base); + labelView7->setBackgroundRole(QPalette::Base); + selectionWidget->setBackgroundRole(QPalette::Highlight); + labelSelection0->setBackgroundRole(QPalette::Highlight); + labelSelection3->setBackgroundRole(QPalette::Highlight); + labelSelection4->setBackgroundRole(QPalette::Highlight); + labelSelection2->setBackgroundRole(QPalette::Highlight); + labelSelection1->setBackgroundRole(QPalette::Highlight); + labelSelection5->setBackgroundRole(QPalette::Highlight); + labelSelection6->setBackgroundRole(QPalette::Highlight); + labelSelection7->setBackgroundRole(QPalette::Highlight); +*/ + + QList widgets = findChildren(); + foreach (QWidget* widget, widgets) + { + widget->installEventFilter(this); + widget->setFocusPolicy(Qt::NoFocus); + } +} + +SetPreviewWidget::~SetPreviewWidget() +{ +} + +bool SetPreviewWidget::eventFilter(QObject *, QEvent *ev) +{ + switch (ev->type()) + { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::Enter: + case QEvent::Leave: + case QEvent::Wheel: + case QEvent::ContextMenu: + return true; // ignore + default: + break; + } + return false; +} + +void SetPreviewWidget::setPalette(const KSharedConfigPtr &config, + KColorScheme::ColorSet set) +{ + QPalette palette = KGlobalSettings::createApplicationPalette(config); + KColorScheme::adjustBackground(palette, KColorScheme::NormalBackground, + QPalette::Base, set, config); + QFrame::setPalette(palette); + +#define SET_ROLE_PALETTE(n, f, b) \ + KColorScheme::adjustForeground(palette, KColorScheme::f, QPalette::Text, set, config); \ + labelFore##n->setPalette(palette); \ + KColorScheme::adjustBackground(palette, KColorScheme::b, QPalette::Base, set, config); \ + labelBack##n->setPalette(palette); \ + widgetBack##n->setPalette(palette); + + SET_ROLE_PALETTE(0, NormalText, NormalBackground); + SET_ROLE_PALETTE(1, InactiveText, AlternateBackground); + SET_ROLE_PALETTE(2, ActiveText, ActiveBackground); + SET_ROLE_PALETTE(3, LinkText, LinkBackground); + SET_ROLE_PALETTE(4, VisitedText, VisitedBackground); + SET_ROLE_PALETTE(5, NegativeText, NegativeBackground); + SET_ROLE_PALETTE(6, NeutralText, NeutralBackground); + SET_ROLE_PALETTE(7, PositiveText, PositiveBackground); + + KColorScheme kcs(QPalette::Active, set, config); + QBrush deco; + +#define SET_DECO_PALETTE(n, d) \ + deco = kcs.decoration(KColorScheme::d); \ + palette.setBrush(QPalette::Text, deco); \ + labelFore##n->setPalette(palette); \ + + SET_DECO_PALETTE(8, HoverColor); + SET_DECO_PALETTE(9, FocusColor); +} + +#include "setpreviewwidget.moc" diff --git a/kcontrol/colors/setpreviewwidget.h b/kcontrol/colors/setpreviewwidget.h new file mode 100644 index 00000000..78982a14 --- /dev/null +++ b/kcontrol/colors/setpreviewwidget.h @@ -0,0 +1,49 @@ +/* Colorset Preview widget for KDE Display color scheme setup module + * Copyright (C) 2008 Matthew Woehlke + * + * 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 __SCHEMEPREVIEWSET_H__ +#define __SCHEMEPREVIEWSET_H__ + +#include +#include + +#include +#include + +#include "ui_setpreview.h" + +/** + * The Desktop/Colors tab in kcontrol. + */ +class SetPreviewWidget : public QFrame, Ui::setpreview +{ + Q_OBJECT + +public: + SetPreviewWidget(QWidget *parent); + virtual ~SetPreviewWidget(); + + void setPalette(const KSharedConfigPtr &config, KColorScheme::ColorSet); + +protected: + void setPaletteRecursive(QWidget*, const QPalette&); + bool eventFilter(QObject *, QEvent *); +}; + +#endif diff --git a/kcontrol/dateandtime/CMakeLists.txt b/kcontrol/dateandtime/CMakeLists.txt new file mode 100644 index 00000000..31a57d9c --- /dev/null +++ b/kcontrol/dateandtime/CMakeLists.txt @@ -0,0 +1,24 @@ +########### next target ############### + +set(kcm_clock_PART_SRCS dtime.cpp main.cpp ) + +kde4_add_ui_files(kcm_clock_PART_SRCS dateandtime.ui) +kde4_add_plugin(kcm_clock ${kcm_clock_PART_SRCS}) + +target_link_libraries(kcm_clock ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS} ) + +install(TARGETS kcm_clock DESTINATION ${PLUGIN_INSTALL_DIR} ) + +########### next target ############### + +kde4_add_executable(kcmdatetimehelper helper.cpp ${helper_mocs}) +target_link_libraries(kcmdatetimehelper ${KDE4_KDECORE_LIBS}) +install(TARGETS kcmdatetimehelper DESTINATION ${LIBEXEC_INSTALL_DIR}) + +kde4_install_auth_helper_files(kcmdatetimehelper org.kde.kcontrol.kcmclock root) + +kde4_install_auth_actions(org.kde.kcontrol.kcmclock kcmclock_actions.actions) + +########### install files ############### + +install( FILES clock.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcontrol/dateandtime/Messages.sh b/kcontrol/dateandtime/Messages.sh new file mode 100644 index 00000000..749f1801 --- /dev/null +++ b/kcontrol/dateandtime/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcmkclock.pot diff --git a/kcontrol/dateandtime/clock.desktop b/kcontrol/dateandtime/clock.desktop new file mode 100644 index 00000000..b7b59a7a --- /dev/null +++ b/kcontrol/dateandtime/clock.desktop @@ -0,0 +1,196 @@ +[Desktop Entry] +Exec=kcmshell4 clock +Icon=preferences-system-time +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/clock/index.html + +X-KDE-Library=kcm_clock +X-KDE-ParentApp=kcontrol + +#should this be in system settings when we can get to it through the panel? +#Answer: Yes. +X-KDE-System-Settings-Parent-Category=system-administration + +Name=Date & Time +Name[af]=Datum & Tyd +Name[ar]=التاريخ و الوقت +Name[ast]=Data y hora +Name[be]=Дата і час +Name[be@latin]=Data j čas +Name[bg]=Дата и час +Name[bn]=তারিখ এবং সময় +Name[bn_IN]=তারিখ ও সময় +Name[br]=Deiziad hag eur +Name[bs]=Datum i vrijeme +Name[ca]=Data i hora +Name[ca@valencia]=Data i hora +Name[cs]=Datum a čas +Name[csb]=Datum ë czas +Name[cy]=Dyddiad ac Amser +Name[da]=Dato og tid +Name[de]=Datum & Zeit +Name[el]=Ημερομηνία & Ώρα +Name[en_GB]=Date & Time +Name[eo]=Dato kaj Tempo +Name[es]=Fecha y hora +Name[et]=Kuupäev ja kellaaeg +Name[eu]=Data eta ordua +Name[fa]=تاریخ و زمان +Name[fi]=Aika ja päiväys +Name[fr]=Date et heure +Name[fy]=Datum en Tiid +Name[ga]=Dáta agus Am +Name[gl]=Data e hora +Name[gu]=તારીખ & સમય +Name[he]=תאריך ושעה +Name[hi]=तारीख़ व समय +Name[hne]=तारीक अउ समय +Name[hr]=Datum i vrijeme +Name[hsb]=Datum & čas +Name[hu]=Dátum és idő +Name[ia]=Data & Tempore +Name[id]=Tanggal & Waktu +Name[is]=Dagsetning og tími +Name[it]=Data e ora +Name[ja]=日付と時刻 +Name[ka]=თარიღი და დრო +Name[kk]=Күн мен уақыт +Name[km]=កាល​បរិច្ឆេទ និង​ពេលវេលា +Name[kn]=ದಿನಾಂಕ ಮತ್ತು ಸಮಯ +Name[ko]=날짜와 시간 +Name[ku]=Roj & Dem +Name[lt]=Data ir laikas +Name[lv]=Datums un laiks +Name[mai]=दिनाँक आ समय +Name[mk]=Датум и време +Name[ml]=തീയതിയും സമയവും +Name[mr]=दिनांक व वेळ +Name[ms]=Tarikh & Masa +Name[nb]=Dato og klokkeslett +Name[nds]=Datum & Tiet +Name[ne]=मिति र समय +Name[nl]=Datum en Tijd +Name[nn]=Dato og klokkeslett +Name[oc]=Data e ora +Name[or]=ତାରିଖ ଏବଂ ସମୟ +Name[pa]=ਮਿਤੀ ਅਤੇ ਟਾਈਮ +Name[pl]=Data i czas +Name[pt]=Data e Hora +Name[pt_BR]=Data e hora +Name[ro]=Data și ora +Name[ru]=Дата и время +Name[se]=Dáhton ja áigi +Name[si]=දිනය සහ වේලාව +Name[sk]=Dátum a čas +Name[sl]=Datum in čas +Name[sr]=Датум и време +Name[sr@ijekavian]=Датум и вријеме +Name[sr@ijekavianlatin]=Datum i vrijeme +Name[sr@latin]=Datum i vreme +Name[sv]=Datum och tid +Name[ta]=தேதி & நேரம் +Name[te]=తేది & సమయం +Name[tg]=Сана ва вақт +Name[th]=วันและเวลา +Name[tr]=Tarih ve Saat +Name[ug]=چېسلا & ۋاقىت +Name[uk]=Дата і час +Name[uz]=Sana va vaqt +Name[uz@cyrillic]=Сана ва вақт +Name[vi]=Ngày & giờ +Name[wa]=Date et eure +Name[xh]=Umhla & Ixesha +Name[x-test]=xxDate & Timexx +Name[zh_CN]=日期和时间 +Name[zh_TW]=日期和時間 + +Comment=Configure date and time settings +Comment[bs]=Podesi datum i vrijeme +Comment[ca]=Configuració de l'arranjament de la data i de l'hora +Comment[ca@valencia]=Configuració de l'arranjament de la data i de l'hora +Comment[cs]=Nastavení voleb data a času +Comment[da]=Indstilling af dato og tid +Comment[de]=Einstellungen für Datum und Zeit ändern +Comment[el]=Διαμόρφωση ρυθμίσεων ώρας και ημερομηνίας +Comment[en_GB]=Configure date and time settings +Comment[es]=Configurar las preferencias de fecha y hora +Comment[et]=Kuupäeva ja kellaaja seadistamine +Comment[eu]=Konfiguratu data- eta ordu-ezarpenak +Comment[fi]=Aika-asetukset +Comment[ga]=Cumraigh socruithe dáta agus ama +Comment[gl]=Configurar as opcións da data e hora +Comment[he]=הגדר זמן ותאריך +Comment[hu]=Dátum- és időbeállítások +Comment[ia]=Configura preferentias de data e tempore +Comment[is]=Stilla dagsetningu og tíma +Comment[kk]=Күн мен уақыт параметрлерін баптау +Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​ការ​កំណត់កាលបរិច្ឆេទ និង​ពេលវេលា +Comment[ko]=날짜 및 시간 설정 변경 +Comment[lt]=Konfigūruoti datos ir laiko nustatymus +Comment[mr]=दिनांक व वेळ संयोजीत करा +Comment[nb]=Innstillinger for dato og tid +Comment[nds]=Instellen vun Datum un Tiet fastleggen +Comment[nl]=Instellingen van datum en tijd instellen +Comment[pa]=ਮਿਤੀ ਅਤੇ ਸਮਾਂ ਸੈਟਿੰਗ ਸੰਰਚਨਾ +Comment[pl]=Konfiguruj ustawienia daty i czasu +Comment[pt]=Configuração das opções da data e hora +Comment[pt_BR]=Configuração das opções de data e hora +Comment[ro]=Configurează opțiunile de dată și oră +Comment[ru]=Настройка даты и времени +Comment[sk]=Nastaviť nastavenia dátumu a času +Comment[sl]=Nastavi datum in čas +Comment[sr]=Поставке датума и времена +Comment[sr@ijekavian]=Поставке датума и времена +Comment[sr@ijekavianlatin]=Postavke datuma i vremena +Comment[sr@latin]=Postavke datuma i vremena +Comment[sv]=Anpassa inställningar av datum och tid +Comment[tr]=Tarih ve saat ayarlarını yapılandır +Comment[uk]=Налаштування параметрів дати і часу +Comment[vi]=Cấu hình thiết lập ngày giờ +Comment[x-test]=xxConfigure date and time settingsxx +Comment[zh_CN]=配置日期和时间设置 +Comment[zh_TW]=設定日期與時間 + +X-KDE-Keywords=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time +X-KDE-Keywords[bs]=sat,datum,vrijeme,vremenska zona,ntp,sinkronizirati,kalendar,lokalno vrijeme,regionalno vrijeme +X-KDE-Keywords[ca]=rellotge,data,hora,zona horària,ntp,sincronització,calendari,hora local,hora de la regió +X-KDE-Keywords[ca@valencia]=rellotge,data,hora,zona horària,ntp,sincronització,calendari,hora local,hora de la regió +X-KDE-Keywords[da]=ur,dato,tid,tidszone,ntp,synkroniser,kalender,lokal tid,regional tid +X-KDE-Keywords[de]=Uhr,Datum,Zeit,Zeitzone,ntp,synchronisation,abgleich,Kalender, +X-KDE-Keywords[el]=ρολόι,ημερομηνία,ώρα,ζώνη ώρας,ntp,συγχρονισμός,ημερολόγιο,τοπική ώρα,ώρα περιοχής +X-KDE-Keywords[en_GB]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time +X-KDE-Keywords[es]=reloj,fecha,hora,zona horaria,ntp,sincronizar,calendario,hora local,hora regional +X-KDE-Keywords[et]=kell,kuupäev,kellaaeg,ajavöönd,ntp,sünkroonimine,sünkroniseerimine,kalender,kohalik aeg,vööndiaeg +X-KDE-Keywords[eu]=erloju,data,ordu,ordu-zona,ntp,sinkronizatu,egutegi,ordu lokal,eskualdeko ordu +X-KDE-Keywords[fi]=kello,päivä,päiväys,päivämäärä,aika,aikavyöhyke,ntp,synkronointi,kalenteri,paikallinen aika,alueellinen aika +X-KDE-Keywords[fr]=horloge, date, heure, zone horaire, ntp, synchronisation, calendrier, heure locale, heure régionale +X-KDE-Keywords[gl]=reloxo, data, hora, fuso, fuso horario, ntp, sincronizar, calendario, almanaque, hora local +X-KDE-Keywords[hu]=óra,dátum,idő,időzóna,ntp,szinkronizáció,naptár,helyi idő,régió idő +X-KDE-Keywords[ia]=horologio,data,tempore,fuso horari,ntp,synchronisa,calendario,tempore local,tempore de region +X-KDE-Keywords[it]=orologio,data,ora,fuso orario,ntp,sincronizza,calendario,ora locale,ora regionale +X-KDE-Keywords[kk]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time +X-KDE-Keywords[km]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time +X-KDE-Keywords[ko]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,시간,날짜,시간대,동기화 +X-KDE-Keywords[mr]=घड्याळ, दिनांक, वेळ, समय क्षेत्र, एन टी पी , सिन्क्रोनाइज़, दिनदर्शिका, स्थानिक वेळ, क्षेत्रीय वेळ +X-KDE-Keywords[nb]=klokke,dato,tid,tidssone,ntp,synkronisere,kalender,lokal tid,regiontid +X-KDE-Keywords[nds]=Klock,Datum,Tiet,Tietrebeet,NTP,synkroniseren,Kalenner,lokaal Tiet +X-KDE-Keywords[nl]=klok,datum,tijd,tijdzone,ntp,synchroniseren,agenda,lokale tijd,tijd in regio +X-KDE-Keywords[pl]=zegar,data,czas,strefa czasowa,ntp,synchronizuj,kalendarz,czas lokalny,czas regionalny +X-KDE-Keywords[pt]=relógio,data,hora,fuso-horário,ntp,sincronizar,calendário,hora local,hora regional +X-KDE-Keywords[pt_BR]=relógio,data,hora,fuso horário,ntp,sincronizar,calendário,hora local,hora regional +X-KDE-Keywords[ru]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,время,дата,часы,часовой пояс,синхронизировать,календарь,местное время,локальное время,региональное время +X-KDE-Keywords[sk]=hodiny,dátum,čas,časové pásmo,ntp,synchronizácia,kalendár,miestny čas,regionálny čas +X-KDE-Keywords[sl]=ura,datum,čas,časovni pas,ntp,uskladitev,koledar,krajevni čas,območni čas +X-KDE-Keywords[sr]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,сат,часовник,датум,време,временска зона,НТП,синхронизовати,календар,локално време +X-KDE-Keywords[sr@ijekavian]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,сат,часовник,датум,време,временска зона,НТП,синхронизовати,календар,локално време +X-KDE-Keywords[sr@ijekavianlatin]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,sat,časovnik,datum,vreme,vremenska zona,NTP,sinhronizovati,kalendar,lokalno vreme +X-KDE-Keywords[sr@latin]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,sat,časovnik,datum,vreme,vremenska zona,NTP,sinhronizovati,kalendar,lokalno vreme +X-KDE-Keywords[sv]=klocka,datum,tid,tidszon,ntp,synkronisera,kalender,lokal tid,områdestid +X-KDE-Keywords[tr]=saat,tarih,zaman,zaman dilimi,ntp,eşzamanlama,takvim,yerel saat,bölge saati +X-KDE-Keywords[uk]=годинник,дата,час,часовий пояс,синхронізація,календар,місцевий час,clock,date,time,time zone,ntp,synchronize,calendar,local time,region time +X-KDE-Keywords[x-test]=xxclock,date,time,time zone,ntp,synchronize,calendar,local time,region timexx +X-KDE-Keywords[zh_CN]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time,时钟,日期,时间,时区,同步,日历,本地时间,区域时间 +X-KDE-Keywords[zh_TW]=clock,date,time,time zone,ntp,synchronize,calendar,local time,region time + +Categories=Qt;KDE;X-KDE-settings-system; diff --git a/kcontrol/dateandtime/dateandtime.ui b/kcontrol/dateandtime/dateandtime.ui new file mode 100644 index 00000000..ec3cd727 --- /dev/null +++ b/kcontrol/dateandtime/dateandtime.ui @@ -0,0 +1,198 @@ + + + Davide Bettio <davide.bettio@kdemail.net> + DateAndTime + + + + 0 + 0 + 613 + 463 + + + + + + + 0 + + + + Date and Time + + + + + + + + Set date and time &automatically: + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 21 + + + + + + + + Time server: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + timeServerList + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + Here you can change the system date's day of the month, month and year. + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Time Zone + + + + + + To change the local time zone, select your area from the list below. + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + Current local time zone: + + + + + + + true + + + Search + + + + + + + + + + + + + + + + KTimeZoneWidget + QTreeWidget +
    ktimezonewidget.h
    +
    + + KTreeWidgetSearchLine + KLineEdit +
    ktreewidgetsearchline.h
    +
    + + KLineEdit + QLineEdit +
    klineedit.h
    +
    + + KSeparator + QFrame +
    kseparator.h
    +
    + + KDatePicker + QFrame +
    kdatepicker.h
    +
    +
    + + +
    diff --git a/kcontrol/dateandtime/dtime.cpp b/kcontrol/dateandtime/dtime.cpp new file mode 100644 index 00000000..68485bb6 --- /dev/null +++ b/kcontrol/dateandtime/dtime.cpp @@ -0,0 +1,463 @@ +/* + * dtime.cpp + * + * Copyright (C) 1998 Luca Montecchiani + * + * Plasma analog-clock drawing code: + * + * Copyright 2007 by Aaron Seigo + * Copyright 2007 by Riccardo Iaconelli + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include "dtime.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dtime.moc" + +#include "helper.h" + +Dtime::Dtime(QWidget * parent) + : QWidget(parent) +{ + KGlobal::locale()->insertCatalog( "timezones4" ); + setupUi(this); + + connect(setDateTimeAuto, SIGNAL(toggled(bool)), this, SLOT(serverTimeCheck())); + connect(setDateTimeAuto, SIGNAL(toggled(bool)), SLOT(configChanged())); + + timeServerList->setEditable(false); + connect(timeServerList, SIGNAL(activated(int)), SLOT(configChanged())); + connect(timeServerList, SIGNAL(editTextChanged(QString)), SLOT(configChanged())); + connect(setDateTimeAuto, SIGNAL(toggled(bool)), timeServerList, SLOT(setEnabled(bool))); + timeServerList->setEnabled(false); + timeServerList->setEditable(true); + findNTPutility(); + if (ntpUtility.isEmpty()) { + setDateTimeAuto->setEnabled(false); + setDateTimeAuto->setToolTip(i18n("No NTP utility has been found. " + "Install 'ntpdate' or 'rdate' command to enable automatic " + "updating of date and time.")); + } + + QVBoxLayout *v2 = new QVBoxLayout( timeBox ); + v2->setMargin( 0 ); + + kclock = new Kclock( timeBox ); + kclock->setObjectName("Kclock"); + kclock->setMinimumSize(150,150); + v2->addWidget( kclock ); + + v2->addSpacing( KDialog::spacingHint() ); + + QHBoxLayout *v3 = new QHBoxLayout( ); + v2->addLayout( v3 ); + + v3->addStretch(); + + timeEdit = new QTimeEdit( timeBox ); + timeEdit->setWrapping(true); + timeEdit->setDisplayFormat(KGlobal::locale()->use12Clock() ? "hh:mm:ss ap" : "HH:mm:ss"); + v3->addWidget(timeEdit); + + v3->addStretch(); + + QString wtstr = i18n("Here you can change the system time. Click into the" + " hours, minutes or seconds field to change the relevant value, either" + " using the up and down buttons to the right or by entering a new value."); + timeEdit->setWhatsThis( wtstr ); + + connect( timeEdit, SIGNAL(timeChanged(QTime)), SLOT(set_time()) ); + connect( cal, SIGNAL(dateChanged(QDate)), SLOT(changeDate(QDate))); + + connect( &internalTimer, SIGNAL(timeout()), SLOT(timeout()) ); + + kclock->setEnabled(false); + + //Timezone + connect( tzonelist, SIGNAL(itemSelectionChanged()), SLOT(configChanged()) ); + tzonesearch->setTreeWidget(tzonelist); +} + +void Dtime::currentZone() +{ + KTimeZone localZone = KSystemTimeZones::local(); + + if (localZone.abbreviations().isEmpty()) { + m_local->setText(i18nc("%1 is name of time zone", "Current local time zone: %1", + KTimeZoneWidget::displayName(localZone))); + } else { + m_local->setText(i18nc("%1 is name of time zone, %2 is its abbreviation", + "Current local time zone: %1 (%2)", + KTimeZoneWidget::displayName(localZone), + QString::fromUtf8(localZone.abbreviations().first()))); + } +} + +void Dtime::serverTimeCheck() { + bool enabled = !setDateTimeAuto->isChecked(); + cal->setEnabled(enabled); + timeEdit->setEnabled(enabled); + //kclock->setEnabled(enabled); +} + +void Dtime::findNTPutility() +{ + const QString exePath = QLatin1String("/usr/sbin:/usr/bin:/sbin:/bin"); + foreach(const QString &possible_ntputility, QStringList() << "ntpdate" << "rdate" ) { + ntpUtility = KStandardDirs::findExe(possible_ntputility, exePath); + if (!ntpUtility.isEmpty()) { + return; + } + } +} + +void Dtime::set_time() +{ + if( ontimeout ) + return; + + internalTimer.stop(); + + time = timeEdit->time(); + kclock->setTime( time ); + + emit timeChanged( true ); +} + +void Dtime::changeDate(const QDate &d) +{ + date = d; + emit timeChanged( true ); +} + +void Dtime::configChanged(){ + emit timeChanged( true ); +} + +void Dtime::load() +{ + // The config is actually written to the system config, but the user does not have any local config, + // since there is nothing writing it. + KConfig _config( "kcmclockrc", KConfig::NoGlobals ); + KConfigGroup config(&_config, "NTP"); + timeServerList->clear(); + timeServerList->addItems(config.readEntry("servers", + i18n("Public Time Server (pool.ntp.org),\ +asia.pool.ntp.org,\ +europe.pool.ntp.org,\ +north-america.pool.ntp.org,\ +oceania.pool.ntp.org")).split(',', QString::SkipEmptyParts)); + setDateTimeAuto->setChecked(config.readEntry("enabled", false)); + + // Reset to the current date and time + time = QTime::currentTime(); + date = QDate::currentDate(); + cal->setDate(date); + + // start internal timer + internalTimer.start( 1000 ); + + timeout(); + + //Timezone + currentZone(); + + // read the currently set time zone + tzonelist->setSelected(KSystemTimeZones::local().name(), true); +} + +void Dtime::save( QVariantMap& helperargs ) +{ + // Save the order, but don't duplicate! + QStringList list; + if( timeServerList->count() != 0) + list.append(timeServerList->currentText()); + for ( int i=0; icount();i++ ) { + QString text = timeServerList->itemText(i); + if( !list.contains(text) ) + list.append(text); + // Limit so errors can go away and not stored forever + if( list.count() == 10) + break; + } + + helperargs["ntp"] = true; + helperargs["ntpServers"] = list; + helperargs["ntpEnabled"] = setDateTimeAuto->isChecked(); + + if(setDateTimeAuto->isChecked() && !ntpUtility.isEmpty()){ + // NTP Time setting - done in helper + timeServer = timeServerList->currentText(); + kDebug() << "Setting date from time server " << timeServer; + } + else { + // User time setting + QDateTime dt(date, QTime(timeEdit->time())); + + kDebug() << "Set date " << dt; + + helperargs["date"] = true; + helperargs["newdate"] = QString::number(dt.toTime_t()); + helperargs["olddate"] = QString::number(::time(0)); + } + + // restart time + internalTimer.start( 1000 ); + + QStringList selectedZones(tzonelist->selection()); + + if (selectedZones.count() > 0) { + QString selectedzone(selectedZones[0]); + helperargs["tz"] = true; + helperargs["tzone"] = selectedzone; + } else { + helperargs["tzreset"] = true; // // make the helper reset the timezone + } + + currentZone(); +} + +void Dtime::processHelperErrors( int code ) +{ + if( code & ClockHelper::NTPError ) { + KMessageBox::error( this, i18n("Unable to contact time server: %1.", timeServer) ); + setDateTimeAuto->setChecked( false ); + } + if( code & ClockHelper::DateError ) { + KMessageBox::error( this, i18n("Can not set date.")); + } + if( code & ClockHelper::TimezoneError) + KMessageBox::error( this, i18n("Error setting new time zone."), + i18n("Time zone Error")); +} + +void Dtime::timeout() +{ + // get current time + time = QTime::currentTime(); + + ontimeout = true; + timeEdit->setTime(time); + ontimeout = false; + + kclock->setTime( time ); +} + +QString Dtime::quickHelp() const +{ + return i18n("

    Date & Time

    This system settings module can be used to set the system date and" + " time. As these settings do not only affect you as a user, but rather the whole system, you" + " can only change these settings when you start the System Settings as root. If you do not have" + " the root password, but feel the system time should be corrected, please contact your system" + " administrator."); +} + +Kclock::Kclock(QWidget *parent) + : QWidget(parent) +{ + m_theme = new Plasma::Svg(this); + m_theme->setImagePath("widgets/clock"); + m_theme->setContainsMultipleImages(true); +} + +Kclock::~Kclock() +{ + delete m_theme; +} + +void Kclock::showEvent( QShowEvent *event ) +{ + setClockSize( size() ); + QWidget::showEvent( event ); +} + +void Kclock::resizeEvent( QResizeEvent * ) +{ + setClockSize( size() ); +} + +void Kclock::setClockSize(const QSize &size) +{ + int dim = qMin(size.width(), size.height()); + QSize newSize = QSize(dim, dim); + + if (newSize != m_faceCache.size()) { + m_faceCache = QPixmap(newSize); + m_handsCache = QPixmap(newSize); + m_glassCache = QPixmap(newSize); + + m_theme->resize(newSize); + m_repaintCache = RepaintAll; + } +} + +void Kclock::setTime(const QTime &time) +{ + if (time.minute() != this->time.minute() || time.hour() != this->time.hour()) { + if (m_repaintCache == RepaintNone) { + m_repaintCache = RepaintHands; + } + } + this->time = time; + update(); +} + +void Kclock::drawHand(QPainter *p, const QRect &rect, const qreal verticalTranslation, const qreal rotation, const QString &handName) +{ + // this code assumes the following conventions in the svg file: + // - the _vertical_ position of the hands should be set with respect to the center of the face + // - the _horizontal_ position of the hands does not matter + // - the _shadow_ elements should have the same vertical position as their _hand_ element counterpart + + QRectF elementRect; + QString name = handName + "HandShadow"; + if (m_theme->hasElement(name)) { + p->save(); + + elementRect = m_theme->elementRect(name); + if( rect.height() < 64 ) + elementRect.setWidth( elementRect.width() * 2.5 ); + static const QPoint offset = QPoint(2, 3); + + p->translate(rect.x() + (rect.width() / 2) + offset.x(), rect.y() + (rect.height() / 2) + offset.y()); + p->rotate(rotation); + p->translate(-elementRect.width()/2, elementRect.y()-verticalTranslation); + m_theme->paint(p, QRectF(QPointF(0, 0), elementRect.size()), name); + + p->restore(); + } + + p->save(); + + name = handName + "Hand"; + elementRect = m_theme->elementRect(name); + if (rect.height() < 64) { + elementRect.setWidth(elementRect.width() * 2.5); + } + + p->translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); + p->rotate(rotation); + p->translate(-elementRect.width()/2, elementRect.y()-verticalTranslation); + m_theme->paint(p, QRectF(QPointF(0, 0), elementRect.size()), name); + + p->restore(); +} + +void Kclock::paintInterface(QPainter *p, const QRect &rect) +{ + const bool m_showSecondHand = true; + + // compute hand angles + const qreal minutes = 6.0 * time.minute() - 180; + const qreal hours = 30.0 * time.hour() - 180 + + ((time.minute() / 59.0) * 30.0); + qreal seconds = 0; + if (m_showSecondHand) { + static const double anglePerSec = 6; + seconds = anglePerSec * time.second() - 180; + } + + // paint face and glass cache + QRect faceRect = m_faceCache.rect(); + if (m_repaintCache == RepaintAll) { + m_faceCache.fill(Qt::transparent); + m_glassCache.fill(Qt::transparent); + + QPainter facePainter(&m_faceCache); + QPainter glassPainter(&m_glassCache); + facePainter.setRenderHint(QPainter::SmoothPixmapTransform); + glassPainter.setRenderHint(QPainter::SmoothPixmapTransform); + + m_theme->paint(&facePainter, m_faceCache.rect(), "ClockFace"); + + glassPainter.save(); + QRectF elementRect = QRectF(QPointF(0, 0), m_theme->elementSize("HandCenterScrew")); + glassPainter.translate(faceRect.width() / 2 - elementRect.width() / 2, faceRect.height() / 2 - elementRect.height() / 2); + m_theme->paint(&glassPainter, elementRect, "HandCenterScrew"); + glassPainter.restore(); + + m_theme->paint(&glassPainter, faceRect, "Glass"); + + // get vertical translation, see drawHand() for more details + m_verticalTranslation = m_theme->elementRect("ClockFace").center().y(); + } + + // paint hour and minute hands cache + if (m_repaintCache == RepaintHands || m_repaintCache == RepaintAll) { + m_handsCache.fill(Qt::transparent); + + QPainter handsPainter(&m_handsCache); + handsPainter.drawPixmap(faceRect, m_faceCache, faceRect); + handsPainter.setRenderHint(QPainter::SmoothPixmapTransform); + + drawHand(&handsPainter, faceRect, m_verticalTranslation, hours, "Hour"); + drawHand(&handsPainter, faceRect, m_verticalTranslation, minutes, "Minute"); + } + + // reset repaint cache flag + m_repaintCache = RepaintNone; + + // paint caches and second hand + QRect targetRect = faceRect; + if (targetRect.width() < rect.width()) { + targetRect.moveLeft((rect.width() - targetRect.width()) / 2); + } + + p->drawPixmap(targetRect, m_handsCache, faceRect); + if (m_showSecondHand) { + p->setRenderHint(QPainter::SmoothPixmapTransform); + drawHand(p, targetRect, m_verticalTranslation, seconds, "Second"); + } + p->drawPixmap(targetRect, m_glassCache, faceRect); +} + +void Kclock::paintEvent( QPaintEvent * ) +{ + QPainter paint(this); + + paint.setRenderHint(QPainter::Antialiasing); + paintInterface(&paint, rect()); +} + diff --git a/kcontrol/dateandtime/dtime.h b/kcontrol/dateandtime/dtime.h new file mode 100644 index 00000000..1a90698c --- /dev/null +++ b/kcontrol/dateandtime/dtime.h @@ -0,0 +1,121 @@ +/* + * dtime.h + * + * Copyright (C) 1998 Luca Montecchiani + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef dtime_included +#define dtime_included + +#include "ui_dateandtime.h" + +#include +#include +#include +#include +#include +//Added by qt3to4: +#include + +#include +#include + +class Kclock; +class QTimeEdit; + +namespace Plasma { + class Svg; +} + +class Dtime : public QWidget, public Ui::DateAndTime +{ + Q_OBJECT + public: + Dtime( QWidget *parent=0 ); + + void save( QVariantMap &helperargs ); + void processHelperErrors( int code ); + void load(); + + QString quickHelp() const; + +Q_SIGNALS: + void timeChanged(bool); + + private Q_SLOTS: + void configChanged(); + void serverTimeCheck(); + void timeout(); + void set_time(); + void changeDate(const QDate&); + +private: + void currentZone(); + void findNTPutility(); + QString ntpUtility; + + QTimeEdit *timeEdit; + + Kclock *kclock; + + QTime time; + QDate date; + QTimer internalTimer; + + QString timeServer; + int BufI; + bool refresh; + bool ontimeout; +}; + +class Kclock : public QWidget +{ + Q_OBJECT + +public: + Kclock( QWidget *parent=0 ); + ~Kclock(); + + void setTime(const QTime&); + +protected: + virtual void paintEvent( QPaintEvent *event ); + virtual void showEvent( QShowEvent *event ); + virtual void resizeEvent( QResizeEvent *event ); + +private: + void setClockSize(const QSize &size); + void drawHand(QPainter *p, const QRect &rect, const qreal verticalTranslation, const qreal rotation, const QString &handName); + void paintInterface(QPainter *p, const QRect &rect); + +private: + QTime time; + Plasma::Svg *m_theme; + enum RepaintCache { + RepaintNone, + RepaintAll, + RepaintHands + }; + RepaintCache m_repaintCache; + QPixmap m_faceCache; + QPixmap m_handsCache; + QPixmap m_glassCache; + qreal m_verticalTranslation; +}; + +#endif // dtime_included diff --git a/kcontrol/dateandtime/helper.cpp b/kcontrol/dateandtime/helper.cpp new file mode 100644 index 00000000..21fc51a6 --- /dev/null +++ b/kcontrol/dateandtime/helper.cpp @@ -0,0 +1,266 @@ +/* + * tzone.cpp + * + * Copyright (C) 1998 Luca Montecchiani + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + + A helper that's run using KAuth and does the system modifications. + +*/ + +#include "helper.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(USE_SOLARIS) +#include +#include +#include +#include +#endif + +// We cannot rely on the $PATH environment variable, because D-Bus activation +// clears it. So we have to use a reasonable default. +static const QString exePath = QLatin1String("/usr/sbin:/usr/bin:/sbin:/bin"); + +static QString findNtpUtility() +{ + foreach(const QString &possible_ntputility, QStringList() << "ntpdate" << "rdate" ) { + const QString ntpUtility = KStandardDirs::findExe(possible_ntputility, exePath); + if (!ntpUtility.isEmpty()) { + return ntpUtility; + } + } + return QString(); +} + +int ClockHelper::ntp( const QStringList& ntpServers, bool ntpEnabled ) +{ + int ret = 0; + + // write to the system config file + QFile config_file(KDE_CONFDIR "/kcmclockrc"); + if(!config_file.exists()) { + config_file.open(QIODevice::WriteOnly); + config_file.close(); + config_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther); + } + KConfig _config(config_file.fileName(), KConfig::SimpleConfig); + KConfigGroup config(&_config, "NTP"); + config.writeEntry("servers", ntpServers ); + config.writeEntry("enabled", ntpEnabled ); + + QString ntpUtility(findNtpUtility()); + + if ( ntpEnabled && !ntpUtility.isEmpty() ) { + // NTP Time setting + QString timeServer = ntpServers.first(); + if( timeServer.indexOf( QRegExp(".*\\(.*\\)$") ) != -1 ) { + timeServer.replace( QRegExp(".*\\("), "" ); + timeServer.replace( QRegExp("\\).*"), "" ); + // Would this be better?: s/^.*\(([^)]*)\).*$/\1/ + } + + KProcess proc; + proc << ntpUtility << timeServer; + if ( proc.execute() != 0 ) { + ret |= NTPError; + } + } else if( ntpEnabled ) { + ret |= NTPError; + } + + return ret; +} + +int ClockHelper::date( const QString& newdate, const QString& olddate ) +{ + struct timeval tv; + + tv.tv_sec = newdate.toULong() - olddate.toULong() + time(0); + tv.tv_usec = 0; + if (settimeofday(&tv, 0)) { + return DateError; + } + + QString hwclock = KStandardDirs::findExe("hwclock", exePath); + if (!hwclock.isEmpty()) { + KProcess::execute(hwclock, QStringList() << "--systohc"); + } + return 0; +} + +// on non-Solaris systems which do not use /etc/timezone? +int ClockHelper::tz( const QString& selectedzone ) +{ + int ret = 0; + + //only allow letters, numbers hyphen underscore plus and forward slash + //allowed pattern taken from time-util.c in systemd + if (!QRegExp("[a-zA-Z0-9-_+/]*").exactMatch(selectedzone)) { + return ret; + } + +#if defined(USE_SOLARIS) // MARCO + + KTemporaryFile tf; + tf.setPrefix("kde-tzone"); + tf.open(); + QTextStream ts(&tf); + + QFile fTimezoneFile(INITFILE); + bool updatedFile = false; + + if (fTimezoneFile.open(QIODevice::ReadOnly)) + { + bool found = false; + + QTextStream is(&fTimezoneFile); + + for (QString line = is.readLine(); !line.isNull(); + line = is.readLine()) + { + if (line.find("TZ=") == 0) + { + ts << "TZ=" << selectedzone << endl; + found = true; + } + else + { + ts << line << endl; + } + } + + if (!found) + { + ts << "TZ=" << selectedzone << endl; + } + + updatedFile = true; + fTimezoneFile.close(); + } + + if (updatedFile) + { + ts.device()->reset(); + fTimezoneFile.remove(); + + if (fTimezoneFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + QTextStream os(&fTimezoneFile); + + for (QString line = ts->readLine(); !line.isNull(); + line = ts->readLine()) + { + os << line << endl; + } + + fchmod(fTimezoneFile.handle(), + S_IXUSR | S_IRUSR | S_IRGRP | S_IXGRP | + S_IROTH | S_IXOTH); + fTimezoneFile.close(); + } + } + + + QString val = selectedzone; +#else + QString tz = "/usr/share/zoneinfo/" + selectedzone; + + QString zic = KStandardDirs::findExe("zic", exePath); + if (!zic.isEmpty()) { + KProcess::execute(zic, QStringList() << "-l" << selectedzone); + } else if (!QFile::remove("/etc/localtime")) { + ret |= TimezoneError; + } else if (!QFile::copy(tz, "/etc/localtime")) { + ret |= TimezoneError; + } + + QFile fTimezoneFile("/etc/timezone"); + + if (fTimezoneFile.exists() && fTimezoneFile.open(QIODevice::WriteOnly | QIODevice::Truncate) ) { + QTextStream t(&fTimezoneFile); + t << selectedzone; + fTimezoneFile.close(); + } + + QString val = ':' + tz; +#endif // !USE_SOLARIS + + setenv("TZ", val.toAscii(), 1); + tzset(); + + return ret; +} + +int ClockHelper::tzreset() +{ +#if !defined(USE_SOLARIS) // Do not update the System! + unlink( "/etc/timezone" ); + unlink( "/etc/localtime" ); + + setenv("TZ", "", 1); + tzset(); +#endif // !USE SOLARIS + return 0; +} + +ActionReply ClockHelper::save(const QVariantMap &args) +{ + bool _ntp = args.value("ntp").toBool(); + bool _date = args.value("date").toBool(); + bool _tz = args.value("tz").toBool(); + bool _tzreset = args.value("tzreset").toBool(); + + KComponentData data( "kcmdatetimehelper" ); + + int ret = 0; // error code +// The order here is important + if( _ntp ) + ret |= ntp( args.value("ntpServers").toStringList(), args.value("ntpEnabled").toBool()); + if( _date ) + ret |= date( args.value("newdate").toString(), args.value("olddate").toString() ); + if( _tz ) + ret |= tz( args.value("tzone").toString() ); + if( _tzreset ) + ret |= tzreset(); + + if (ret == 0) { + return ActionReply::SuccessReply; + } else { + ActionReply reply(ActionReply::HelperError); + reply.setErrorCode(ret); + return reply; + } +} + +KDE4_AUTH_HELPER_MAIN("org.kde.kcontrol.kcmclock", ClockHelper) diff --git a/kcontrol/dateandtime/helper.h b/kcontrol/dateandtime/helper.h new file mode 100644 index 00000000..fea71bae --- /dev/null +++ b/kcontrol/dateandtime/helper.h @@ -0,0 +1,51 @@ +/* + * main.h + * + * Copyright (C) 1998 Luca Montecchiani + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef CLOCK_HELPER_H +#define CLOCK_HELPER_H + +#include + +using namespace KAuth; + +class ClockHelper : public QObject +{ + Q_OBJECT + + public: + enum + { + CallError = 1 << 0, + TimezoneError = 1 << 1, + NTPError = 1 << 2, + DateError = 1 << 3 + }; + + public slots: + ActionReply save(const QVariantMap &map); + + private: + int ntp(const QStringList& ntpServers, bool ntpEnabled); + int date(const QString& newdate, const QString& olddate); + int tz(const QString& selectedzone); + int tzreset(); +}; + +#endif // CLOCK_HELPER_H diff --git a/kcontrol/dateandtime/kcmclock_actions.actions b/kcontrol/dateandtime/kcmclock_actions.actions new file mode 100644 index 00000000..14b4433b --- /dev/null +++ b/kcontrol/dateandtime/kcmclock_actions.actions @@ -0,0 +1,209 @@ +[Domain] +Name=Date and Time Control Module +Name[ar]=وحدة التحكم بالتاريخ والوقت +Name[ast]=Módulu de control de data y hora +Name[bg]=Управление на дата и час +Name[bn]=তারিখ এবং সময় নিয়ন্ত্রণ মডিউল +Name[bs]=Kontrolni modul datuma i vremena +Name[ca]=Mòdul de control de data i hora +Name[ca@valencia]=Mòdul de control de data i hora +Name[cs]=Ovládací modul data a času +Name[csb]=Mòduł kòntrolë datuma ë czasu +Name[da]=Kontrolmodul til dato og tid +Name[de]=Kontrollmodul für Datum und Zeit +Name[el]=Μονάδα ελέγχου ημερομηνίας και ώρας +Name[en_GB]=Date and Time Control Module +Name[eo]=Kontrol-Modulo de Dato kaj Tempo +Name[es]=Módulo de control de fecha y hora +Name[et]=Kuupäeva ja kellaaja juhtimismoodul +Name[eu]=Data eta ordua kontrolatzeko modulua +Name[fi]=Aika-asetukset +Name[fr]=Module de contrôle de la date et de l'heure +Name[fy]=Datum en tiid kontrôle module +Name[ga]=Modúl Rialaithe Dáta agus Am +Name[gl]=Módulo de control da data e hora +Name[gu]=તારીખ અને સમય નિયંત્રણ મોડ્યુલ +Name[he]=מודול הגדרות תאריך ושעה +Name[hi]=तारीख़ और समय तंत्र मोड्यूल +Name[hr]=Upravljački modul za datum i vrijeme +Name[hu]=Dátum és idő beállítómodul +Name[ia]=Modulo de controlo de data e tempore +Name[id]=Modul Kontrol Tanggal dan Waktu +Name[is]=Stjórneining fyrir dagsetningu og tíma +Name[it]=Modulo di controllo di data e ora +Name[ja]=日付と時刻の設定モジュール +Name[kk]=Күні мен уақытын басқару модулі +Name[km]=ម៉ូឌុល​ត្រួតពិនិត្យ​ពេលវេលា និងកាលបរិច្ឆេទ +Name[kn]=ದಿನಾಂಕ ಮತ್ತು ಸಮಯ ನಿಯಂತ್ರಣ ಘಟಕ +Name[ko]=날짜와 시간 제어 모듈 +Name[lt]=Datos ir laiko valdymo modulis +Name[lv]=Datuma un laika kontroles modulis +Name[mk]=Контролен модул за датум и време +Name[ml]=തീയതിയും സമയവും നിയന്ത്രിയ്ക്കുന്ന ഭാഗം +Name[mr]=दिनांक व वेळ नियंत्रण विभाग +Name[nb]=Styremodul for dato og tid +Name[nds]=Datum- un Tiet-Kuntrullmoduul +Name[nl]=Controlemodule van datum en tijd +Name[nn]=Kontrollmodul for dato og klokkeslett +Name[pa]=ਮਿਤੀ ਅਤੇ ਟਾਈਮ ਕੰਟਰੋਲ ਮੋਡੀਊਲ +Name[pl]=Moduł sterowania datą i czasem +Name[pt]=Módulo de Controlo da Data e Hora +Name[pt_BR]=Módulo de controle da data e hora +Name[ro]=Modul de control dată și oră +Name[ru]=Модуль настройки даты и времени +Name[si]=දිනය සහ වේලා පාලක මොඩියුලය +Name[sk]=Modul pre nastavenie dátumu a času +Name[sl]=Nadzorni modul za datum in čas +Name[sr]=Контролни модул датума и времена +Name[sr@ijekavian]=Контролни модул датума и времена +Name[sr@ijekavianlatin]=Kontrolni modul datuma i vremena +Name[sr@latin]=Kontrolni modul datuma i vremena +Name[sv]=Inställningsmodul för datum och tid +Name[tg]=Сана ва вақт +Name[th]=มอดูลควบคุมสำหรับวันและเวลา +Name[tr]=Tarih ve Saat Denetim Modülü +Name[ug]=چېسلا ۋە ۋاقىت تىزگىن بۆلىكى +Name[uk]=Модуль керування датою і часом +Name[vi]=Mô-đun điều khiển ngày giờ +Name[wa]=Module di controle del date eyet d' l' eure +Name[x-test]=xxDate and Time Control Modulexx +Name[zh_CN]=日期和时间控制模块 +Name[zh_TW]=日期與時間控制模組 +Icon=preferences-system-time + +[org.kde.kcontrol.kcmclock.save] +Name=Save the date/time settings +Name[ar]=احفظ إعدادات التاريخ والوقت +Name[ast]=Guardar les preferencies de data/hora +Name[bg]=Запазване настройките за дата и час +Name[bn]=তারিখ এবং সময় সেটিংস সংরক্ষণ করো +Name[bs]=Sačuvaj postavke datuma i vremena +Name[ca]=Desa la configuració de data i hora +Name[ca@valencia]=Guarda la configuració de data i hora +Name[cs]=Uložit nastavení data a času +Name[csb]=Zapiszë nastôw datuma ë czasu +Name[da]=Gem dato- og tidsindstillinger +Name[de]=Einstellungen für Datum und Zeit speichern +Name[el]=Αποθήκευση ρυθμίσεων ημερομηνίας και ώρας +Name[en_GB]=Save the date/time settings +Name[eo]=Konservu Agordon de dato kaj tempo +Name[es]=Guardar las preferencias de fecha/hora +Name[et]=Kuupäeva ja kellaaja seadistuste salvestamine +Name[eu]=Gorde data- eta ordu-ezarpenak +Name[fi]=Tallenna päiväyksen ja ajan asetukset +Name[fr]=Enregistrer les paramètres de date et d'heure +Name[fy]=Datum en tiid ynstellings bewarje +Name[ga]=Sábháil na socruithe dáta/ama +Name[gl]=Garda a configuración da data e hora +Name[gu]=તારીખ/સમય ગોઠવણીઓ સંગ્રહો +Name[he]=שמירת הגדרות התאריך והשעה +Name[hi]=तारीख़ तथा समय विन्यास सहेजें +Name[hr]=Spremi datumske/vremenske postavke +Name[hu]=A dátum- és időbeállítások mentése +Name[ia]=Salveguarda le preferentias de data & tempore +Name[id]=Simpan pengaturan tanggal/waktu +Name[is]=Vista stillingar dagssetningar og tíma +Name[it]=Salva le impostazioni di data e ora +Name[ja]=日付と時刻の設定を保存 +Name[kk]=Күн/уақыт параметрлерін сақтау +Name[km]=រក្សាទុកការកំណត់​ពេលវេលា/កាលបរិច្ឆេទ +Name[kn]=ದಿನಾಂಕ/ಸಮಯ ಸಂಯೋಜನೆಗಳನ್ನು ಉಳಿಸಿ +Name[ko]=날짜와 시간 설정 저장 +Name[lt]=Duomenų ir laiko nustatymai +Name[lv]=Saglabāt datuma/laika iestatījumus +Name[mk]=Зачувување на поставувања за датум и време +Name[ml]=തീയതിയുടെ/സമയത്തിന്റെ സജ്ജീകരണങ്ങള്‍ സൂക്ഷിയ്ക്കുക +Name[mr]=दिनांक व वेळ संयोजना साठवा +Name[nb]=Lagre dato og klokkeslett-innstillinger +Name[nds]=Instellen vun Datum un Tiet sekern +Name[nl]=Datum- en tijdinstellingen opslaan +Name[nn]=Lagra innstillingane for dato og klokkeslett +Name[pa]=ਮਿਤੀ/ਸਮਾਂ ਸੈਟਿੰਗ ਸੰਭਾਲੋ +Name[pl]=Zapisz ustawienia daty/czasu +Name[pt]=Mudar a configuração da data/hora +Name[pt_BR]=Salvar as configurações de data e hora +Name[ro]=Salvează configurările datei și orei +Name[ru]=Сохранить параметры даты и времени +Name[si]=දිනය/වේලාව සිටුවම් සුරකින්න +Name[sk]=Uložiť nastavenia dátumu a času +Name[sl]=Shranjevanje nastavitev datuma in časa +Name[sr]=Сачувај поставке датума и времена +Name[sr@ijekavian]=Сачувај поставке датума и времена +Name[sr@ijekavianlatin]=Sačuvaj postavke datuma i vremena +Name[sr@latin]=Sačuvaj postavke datuma i vremena +Name[sv]=Spara inställningar av datum och tid +Name[tg]=Танзимоти сана ва вақт +Name[th]=จัดเก็บการตั้งค่าวันและเวลา +Name[tr]=Tarih ve saat ayarlarını kaydet +Name[ug]=چېسلا/ۋاقىت تەڭشىكىنى ساقلايدۇ +Name[uk]=Зберегти параметри дати/часу +Name[wa]=Schaper ls apontiaedjes del date et d' l' eure +Name[x-test]=xxSave the date/time settingsxx +Name[zh_CN]=保存日期和时间设置 +Name[zh_TW]=儲存日期和時間設定值 +Description=System policies prevent you from saving the date/time settings. +Description[ar]=إن سياسات النظام لا تسمح لك بحفظ إعدادات الوقت والتاريخ +Description[ast]=Les polítiques del sistema impiden guardar les preferencies de data/hora. +Description[bg]=Системните правила не позволяват запазване на настройките за дата и час. +Description[bn]=সিস্টেম পলিসি আপনাকে তারিখ এবং সময় সেটিংস সংরক্ষণ করতে দিচ্ছে না। +Description[bs]=Sistemske smjernice sprečavaju upisivanje postavki datuma i vremena. +Description[ca]=Les polítiques del sistema impedeixen que deseu la configuració de data i hora. +Description[ca@valencia]=Les polítiques del sistema impedeixen que guardeu la configuració de data i hora. +Description[cs]=Nastavení systému vám znemožňuje uložit datum/čas. +Description[csb]=Przez systemòwi nastôw nié mòżé zapisac nastôwù datuma ë czasu. +Description[da]=Systempolitikker forhindrer dig i at gemme dato- og tidsindstillinger. +Description[de]=Die Einstellungen für Datum und Zeit können aufgrund einer Systemrichtlinie nicht gespeichert werden. +Description[el]=Οι πολιτικές του συστήματος αποτρέπουν την αποθήκευση των ρυθμίσεων ώρας/ημερομηνίας. +Description[en_GB]=System policies prevent you from saving the date/time settings. +Description[es]=Las políticas del sistema le impiden guardar las preferencias de fecha/hora. +Description[et]=Süsteemi reeglid takistavad kuupäeva ja kellaaja seadistuste salvestamist. +Description[eu]=Sistemako gidalerroek data- eta ordu-ezarpenak gordetzea eragozten dizute +Description[fi]=Järjestelmämenettelytavat estävät sinua tallentamasta päivämäärä/aika-asetuksia. +Description[fr]=La stratégie système vous empêche d'enregistrer les paramètres de date et d'heure. +Description[fy]=Systeem belied foarkomt dat jo datum en tiid ynstellings bewarje kinne. +Description[ga]=De bharr polasaí an chórais, níl cead agat socruithe an dáta/ama a shábháil. +Description[gl]=As políticas do sistema non permiten que garde a configuración da data e hora. +Description[he]=מדיניות המערכת מונעת ממך שמירת הגדרות התאריך והשעה. +Description[hr]=Pravila sustava vam brane spremanje datumskih/vremenskih postavki. +Description[hu]=A rendszer házirendjei nem engedik Önnek a dátum- és időbeállítások mentését. +Description[ia]=Le politicas de systema preveni te ex salveguardar le preferentias de tempore/data. +Description[id]=Kebijakan sistem menghalangi anda untuk menyimpan pengaturan tanggal/waktu. +Description[is]=Öryggisstillingar kerfisins koma í veg fyrir að þú getir vistað tíma/dagsetningu. +Description[it]=Le regole di condotta del sistema impediscono di salvare le impostazioni di data e ora. +Description[ja]=システムポリシーにより、日時設定を保存することができません。 +Description[kk]=Күн/уақыт параметрлерін сақтауды болдырмайтын жүйелік ережелері. +Description[km]=គោលនយោបាយ​ប្រព័ន្ធ​ ការពារ​អ្នក​​មិន​ឲ្យ​រក្សាទុក​ការកំណត់​កាលបរិច្ឆេទ/ពេលវេលា ។ +Description[kn]=ವ್ಯವಸ್ಥೆಯ ಕಾರ್ಯನೀತಿ ನಿಮ್ಮನ್ನು ಸಮಯ/ದಿನಾಂಕ ಸಂಯೋಜನೆಗಳನ್ನು ಉಳಿಸಿಕೊಳ್ಳುವುದರಿಂದ ತಡೆಯುತ್ತಿವೆ +Description[ko]=시스템 정책 때문에 날짜와 시간 설정을 저장할 수 없습니다. +Description[lt]=Sistemos taisyklės neleidžia jums įrašyti datos/laiko. +Description[lv]=Sistēmas politikas neļauj jums saglabāt datuma/laika iestatījumus. +Description[mk]=Политиката на системот Ве спречува да ги зачувате поставувањата за датум и време. +Description[ml]=സിസ്റ്റത്തിലെ നയങ്ങള്‍ തിയ്യതി/സമയം ക്രമീകരിയ്ക്കുന്നതില്‍ നിന്നും നിങ്ങളെ തടയുന്നു. +Description[mr]=प्रणाली धोरण दिनांक व वेळ संयोजना संचयीत करण्यास प्रतिबंध करत आहे. +Description[nb]=Systembestemmelser gjør at du ikke kan lagre dato/tid-innstillingene +Description[nds]=De Systeemregeln verlöövt nich, dat Du de Instellen för Datum un Tiet sekerst. +Description[nl]=Systeembeleid voorkwam dat u de datum- en tijdinstellingen kon opslaan. +Description[nn]=Systemreglane hindrar deg i å lagra innstillingane for dato og klokkeslett. +Description[pa]=ਸਿਸਟਮ ਪਾਲਸੀ ਤੁਹਾਨੂੰ ਮਿਤੀ/ਸਮਾਂ ਸੈਟਿੰਗ ਬਦਲਣ ਤੋਂ ਤੁਹਾਨੂੰ ਰੋਕਦੀ ਹੈ। +Description[pl]=Polityka systemu nie pozwala ci na zapisanie ustawień daty/czasu. +Description[pt]=As políticas do sistema proíbem a modificação da configuração de data/hora. +Description[pt_BR]=As políticas do sistema não permitem a modificação das configurações de data e hora. +Description[ro]=Politicile sistemului vă interzic salvarea configurărilor de dată și oră. +Description[ru]=Правила безопасности запрещают вам управлять системной датой и временем. +Description[si]=පද්ධති ප්‍රතිපත්තො ඔබව දිනය/වේලාව සැකසුම් සුරැකිම වලකාලයි. +Description[sk]=Systémové politiky vám zabránili uložiť nastavenie dátumu a času. +Description[sl]=Sistemski pravilniki vam onemogočajo, da bi shranili nastavitve datuma in časa. +Description[sr]=Системске смернице спречавају уписивање поставки датума и времена. +Description[sr@ijekavian]=Системске смјернице спречавају уписивање поставки датума и времена. +Description[sr@ijekavianlatin]=Sistemske smjernice sprečavaju upisivanje postavki datuma i vremena. +Description[sr@latin]=Sistemske smernice sprečavaju upisivanje postavki datuma i vremena. +Description[sv]=Systemets policy förhindrar att du sparar inställningar av datum och tid. +Description[th]=นโยบายของระบบเพื่อป้องกันจากการจัดเก็บการตั้งค่าต่าง ๆ ของวันและเวลา +Description[tr]=Sistem politikaları tarih saat ayarlarını kaydetmenizi engelliyor. +Description[ug]=سىستېما بىخەتەرلىك تەدبىرىڭىز چېسلا/ۋاقىت تەڭشەكلەرنى ساقلاشقا يول قويمايدۇ. +Description[uk]=Відповідно до загальносистемних правил, ви не можете зберігати параметри дати/часу. +Description[wa]=Les politikes do sistinme vos espaitchèt d' schaper les apontiaedjes del date/eure. +Description[x-test]=xxSystem policies prevent you from saving the date/time settings.xx +Description[zh_CN]=系统安全策略不允许您保存日期/时间设置。 +Description[zh_TW]=系統政策不允許您儲存日期與時間的設定 +Policy=auth_admin diff --git a/kcontrol/dateandtime/main.cpp b/kcontrol/dateandtime/main.cpp new file mode 100644 index 00000000..2fa0f3ec --- /dev/null +++ b/kcontrol/dateandtime/main.cpp @@ -0,0 +1,122 @@ +/* + * main.cpp + * + * Copyright (C) 1998 Luca Montecchiani + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include "main.h" + +#include + +//Added by qt3to4: +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.moc" + +#include "dtime.h" +#include "helper.h" + +#include + +K_PLUGIN_FACTORY(KlockModuleFactory, registerPlugin();) +K_EXPORT_PLUGIN(KlockModuleFactory("kcmkclock")) + + +KclockModule::KclockModule(QWidget *parent, const QVariantList &) + : KCModule(KlockModuleFactory::componentData(), parent/*, name*/) +{ + KAboutData *about = + new KAboutData(I18N_NOOP("kcmclock"), 0, ki18n("KDE Clock Control Module"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 1996 - 2001 Luca Montecchiani")); + + about->addAuthor(ki18n("Luca Montecchiani"), ki18n("Original author"), "m.luca@usa.net"); + about->addAuthor(ki18n("Paul Campbell"), ki18n("Current Maintainer"), "paul@taniwha.com"); + about->addAuthor(ki18n("Benjamin Meyer"), ki18n("Added NTP support"), "ben+kcmclock@meyerhome.net"); + setAboutData( about ); + setQuickHelp( i18n("

    Date & Time

    This control module can be used to set the system date and" + " time. As these settings do not only affect you as a user, but rather the whole system, you" + " can only change these settings when you start the System Settings as root. If you do not have" + " the root password, but feel the system time should be corrected, please contact your system" + " administrator.")); + + KGlobal::locale()->insertCatalog("timezones4"); // For time zone translations + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(KDialog::spacingHint()); + + dtime = new Dtime(this); + layout->addWidget(dtime); + connect(dtime, SIGNAL(timeChanged(bool)), this, SIGNAL(changed(bool))); + + setButtons(Help|Apply); + + setNeedsAuthorization(true); + + process = NULL; +} + +void KclockModule::save() +{ + setDisabled(true); + + QVariantMap helperargs; + dtime->save( helperargs ); + + Action *action = authAction(); + action->setArguments(helperargs); + + ActionReply reply = action->execute(); + + if (reply.failed()) { + if (reply.type() == ActionReply::KAuthError) { + KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1, %2", reply.errorCode(), reply.errorDescription())); + } else { + dtime->processHelperErrors(reply.errorCode()); + } + } + else { + QDBusMessage msg = QDBusMessage::createSignal("/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated"); + QDBusConnection::sessionBus().send(msg); + } + + // NOTE: super nasty hack #1 + // Try to work around time mismatch between KSystemTimeZones' update of local + // timezone and reloading of data, so that the new timezone is taken into account. + // The Ultimate solution to this would be if KSTZ emitted a signal when a new + // local timezone was found. + QTimer::singleShot(5000, this, SLOT(load())); + + // setDisabled(false) happens in load(), since QTimer::singleShot is non-blocking +} + +void KclockModule::load() +{ + dtime->load(); + setDisabled(false); +} diff --git a/kcontrol/dateandtime/main.h b/kcontrol/dateandtime/main.h new file mode 100644 index 00000000..c1e52340 --- /dev/null +++ b/kcontrol/dateandtime/main.h @@ -0,0 +1,47 @@ +/* + * main.h + * + * Copyright (C) 1998 Luca Montecchiani + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef main_included +#define main_included + +#include + +class Dtime; +class QTabWidget; +class KProcess; + + +class KclockModule : public KCModule +{ + Q_OBJECT + +public: + KclockModule(QWidget *parent, const QVariantList &); + + void save(); + void load(); + +private: + QTabWidget *tab; + Dtime *dtime; + KProcess *process; +}; + +#endif // main_included diff --git a/kcontrol/desktoppaths/CMakeLists.txt b/kcontrol/desktoppaths/CMakeLists.txt new file mode 100644 index 00000000..0d94c9f6 --- /dev/null +++ b/kcontrol/desktoppaths/CMakeLists.txt @@ -0,0 +1,12 @@ +set(kcm_desktoppaths_PART_SRCS + globalpaths.cpp + kcmdesktoppaths.cpp +) + +kde4_add_plugin(kcm_desktoppaths ${kcm_desktoppaths_PART_SRCS}) + +target_link_libraries(kcm_desktoppaths ${KDE4_KCMUTILS_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS kcm_desktoppaths DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES desktoppath.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/kcontrol/desktoppaths/Messages.sh b/kcontrol/desktoppaths/Messages.sh new file mode 100644 index 00000000..fe3c1740 --- /dev/null +++ b/kcontrol/desktoppaths/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/kcm_desktoppaths.pot diff --git a/kcontrol/desktoppaths/desktoppath.desktop b/kcontrol/desktoppaths/desktoppath.desktop new file mode 100644 index 00000000..2be2d092 --- /dev/null +++ b/kcontrol/desktoppaths/desktoppath.desktop @@ -0,0 +1,236 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/paths/index.html +Icon=system-file-manager +Exec=kcmshell4 desktoppath + +X-KDE-Library=kcm_desktoppaths +X-KDE-PluginKeyword=dpath +X-KDE-ParentApp=kcontrol +X-KDE-System-Settings-Parent-Category=account-details +X-KDE-Weight=60 + +Name=Paths +Name[af]=Soekgidse +Name[ar]=المسارات +Name[as]=পথ +Name[ast]=Caminos +Name[be]=Шляхі +Name[be@latin]=Ściežki +Name[bg]=Пътища +Name[bn]=পাথ (Paths) +Name[bn_IN]=পাথ +Name[br]=Hentoù +Name[bs]=Putanje +Name[ca]=Camins +Name[ca@valencia]=Camins +Name[cs]=Cesty +Name[csb]=Stegnë +Name[cy]=Llwybrau +Name[da]=Stier +Name[de]=Pfade +Name[el]=Κατάλογοι +Name[en_GB]=Paths +Name[eo]=Vojoj +Name[es]=Rutas +Name[et]=Otsinguteed +Name[eu]=Bide-izenak +Name[fa]=مسیرها +Name[fi]=Polut +Name[fr]=Emplacements +Name[fy]=Paden +Name[ga]=Conairí +Name[gl]=Rutas +Name[gu]=માર્ગો +Name[he]=נתיבים +Name[hi]=पथ +Name[hne]=पथ +Name[hr]=Putanje +Name[hsb]=Puće +Name[hu]=Elérési utak +Name[ia]=Percursos +Name[id]=Alamat +Name[is]=Slóðir +Name[it]=Percorsi +Name[ja]=パス +Name[ka]=ბილიკი +Name[kk]=Жолдар +Name[km]=ផ្លូវ +Name[kn]=ಪಥಗಳು (ಪಾತ್) +Name[ko]=경로 +Name[ku]=Rêç +Name[lt]=Keliai +Name[lv]=Ceļi +Name[mai]=पथ +Name[mk]=Патеки +Name[ml]=വഴികള്‍ +Name[mr]=मार्ग +Name[ms]=Laluan +Name[nb]=Stier +Name[nds]=Padden +Name[ne]=मार्ग +Name[nl]=Paden +Name[nn]=Stiar +Name[oc]=Camins +Name[or]=ପଥଗୁଡ଼ିକ +Name[pa]=ਮਾਰਗ +Name[pl]=Ścieżki +Name[pt]=Localizações +Name[pt_BR]=Caminhos +Name[ro]=Căi +Name[ru]=Пути +Name[se]=Bálgát +Name[si]=මාර්‍ග +Name[sk]=Cesty +Name[sl]=Poti +Name[sr]=Путање +Name[sr@ijekavian]=Путање +Name[sr@ijekavianlatin]=Putanje +Name[sr@latin]=Putanje +Name[sv]=Sökvägar +Name[ta]=பாதைகள் +Name[te]=దారులు +Name[tg]=Роҳчаҳо +Name[th]=พาธ +Name[tr]=Yollar +Name[ug]=يول +Name[uk]=Шляхи +Name[uz]=Yoʻllar +Name[uz@cyrillic]=Йўллар +Name[vi]=Đường dẫn +Name[wa]=Tchimins +Name[xh]=Umendo +Name[x-test]=xxPathsxx +Name[zh_CN]=路径 +Name[zh_TW]=路徑 + +Comment=Change the location important files are stored +Comment[af]=Verander die ligging belangrik lêers word gestoor +Comment[ar]=غيّر المكان المُستخدم لتخزين الملفات المهمة +Comment[as]=গুৰুত্বপূৰ্ণ নথিপত্ৰ সংৰক্ষণ কৰাৰ স্থান সলনি কৰক +Comment[ast]=Camudar l'allugamientu de ficheros importantes +Comment[be]=Змена тэчак для захавання важных файлаў +Comment[be@latin]=Źmiani miescy, dzie zachoŭvajucca važnyja fajły +Comment[bg]=Настройване местоположението на важните файлове +Comment[bn]=বিভিন্ন গুরুত্বপূর্ণ ফাইল কোন অবস্থানে থাকবে তা পরিবর্তন করুন +Comment[bn_IN]=গুরুত্বপূর্ণ ফাইল সংরক্ষণের স্থান পরিবর্তন করুন +Comment[bs]=Promijenite lokaciju gdje su smješteni važni datoteke +Comment[ca]=Canvia la localització d'on seran desats els fitxers importants +Comment[ca@valencia]=Canvia la localització d'on seran guardats els fitxers importants +Comment[cs]=Změna umístění důležitých souborů +Comment[csb]=Môl trzëmaniô wôżnëch lopków +Comment[cy]=Newid lle mae ffeiliau pwysig yn cael eu cadw +Comment[da]=Ændr stedet hvor vigtige filer gemmes +Comment[de]=Ordner für wichtige Dateien ändern +Comment[el]=Αλλάξτε την τοποθεσία στην οποία αποθηκεύονται σημαντικά αρχεία +Comment[en_GB]=Change the location important files are stored +Comment[eo]=Ŝanĝi la lokon, kie oni konservas gravajn dosierojn +Comment[es]=Cambiar la ubicación de archivos importantes +Comment[et]=Oluliste failide asukoha muutmine +Comment[eu]=Aldatu fitxategi garrantzitsuak gordetzen diren kokalekua +Comment[fa]=تغییر محل ذخیره پرونده‌های مهم +Comment[fi]=Tärkeiden tiedostojen tallennuspaikkojen asetukset +Comment[fy]=Hjir kinne jo de lokaasje fan it bewarjen fan belangrike triemmen wizigje +Comment[ga]=Athraigh an suíomh ina stóráiltear comhaid thábhachtacha +Comment[gl]=Muda o lugar onde se gardan os ficheiros importantes +Comment[gu]=મહત્વની ફાઇલો સંગ્રહ થાય તે સ્થાન બદલો +Comment[he]=שינוי המיקומים בהם מאוחסנים קבצים חשובים +Comment[hi]=महत्वपूर्ण फ़ाइलों के रखने का स्थान बदलें +Comment[hne]=जरूरी फाइल मन के रखे के जगह बदलव +Comment[hr]=Promijenite lokaciju za smještaj važnih datoteka +Comment[hsb]=Městna změnić, hdźež so wažne dataje namakaja +Comment[hu]=Néhány fontosabb elérési utat lehet itt beállítani +Comment[ia]=Modifica le location ubi files importante es immagazinate +Comment[id]=Ubah lokasi berkas penting disimpan +Comment[is]=Breyta staðsetningu mikilvægra skráa +Comment[ka]=მნიშვნელოვანი ფაილბის გეზის ცვლილება შენახულია +Comment[kk]=Маңызды файлдар орналасатын орындарын өзгерту +Comment[km]=ផ្លាស់ប្ដូរ​​ទីតាំង​ដែល​ត្រូវ​ទុក​ឯកសារ​សំខាន់ៗ +Comment[kn]=ಮಖ್ಯ ಕಡತಗಳನ್ನು ಸಂಗ್ರಹಿಸಲಾಗುವ ಸ್ಥಳವನ್ನು ಬದಲಾಯಿಸು +Comment[ko]=중요한 파일이 저장되는 곳 설정 +Comment[ku]=Ciyê ku pelên girîng lê tomar dibin biguherîne +Comment[lt]=Pakeiskite svarbių failų saugojimo vietą +Comment[lv]=Mainīt nozīmīgu failu atrašanās vietas +Comment[mai]=महत्वपूर्ण फाइलसभ केर रखबाक स्थान बदलू +Comment[mk]=Сменете ја локацијата каде што се чуваат важни датотеки +Comment[ml]=പ്രധാനപ്പെട്ട ഫയലുകള്‍ സൂക്ഷിച്ച സ്ഥാനം മാറ്റുക +Comment[mr]=महत्वपूर्ण फाईल संयोजनाचे स्थान बदला +Comment[ms]=Ubah lokasi fail penting disimpan +Comment[nb]=Endre plasseringa av viktige filer +Comment[nds]=Den Oort för wichtige Dateien ännern +Comment[ne]=महत्वपूर्ण फाइल भण्डारण गरिएको स्थान परिवर्तन गर्नुहोस् +Comment[nl]=Hier kunt u de locatie voor het opslaan van belangrijke bestanden wijzigen +Comment[nn]=Endra plasseringa av viktige filer +Comment[or]=ଦରକାରି ଫାଇଲଗୁଡ଼ିକୁ ସଂରକ୍ଷିତ କରାଯାଇଥିବା ସ୍ଥାନକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ +Comment[pa]=ਜ਼ਰੂਰੀ ਫਾਇਲਾਂ ਸੰਭਾਲਣ ਲਈ ਟਿਕਾਣਾ ਤਬਦੀਲ +Comment[pl]=Zmiana miejsca przechowywania ważnych plików +Comment[pt]=Alterar as localizações onde os ficheiros importantes estão guardados +Comment[pt_BR]=Altera o local de armazenamento dos arquivos importantes +Comment[ro]=Modifică locul de stocare a fișierelor importante +Comment[ru]=Пути к важным файлам +Comment[se]=Rievdat báikkiid gosa dehálaš fiillat bidjut +Comment[si]=වැදගත් ගොනු ගබඩා කර ඇති ස්ථානය වෙනස් කරන්න +Comment[sk]=Zmena umiestnenia dôležitých súborov +Comment[sl]=Spremenite mesta shranjevanja pomembnih datotek +Comment[sr]=Промените локацију где су смештени важни фајлови +Comment[sr@ijekavian]=Промијените локацију гдје су смјештени важни фајлови +Comment[sr@ijekavianlatin]=Promijenite lokaciju gdje su smješteni važni fajlovi +Comment[sr@latin]=Promenite lokaciju gde su smešteni važni fajlovi +Comment[sv]=Ändra plats för lagring av viktiga filer +Comment[ta]=முக்கிய கோப்புகள் சேகரிக்கப்பட்டுள்ள இடத்தை மாற்று +Comment[te]=ముఖ్యమైన దస్త్రములు నిల్వవుంచు స్థానమును మార్చుము +Comment[tg]=Ҷойгиршавии файлҳои лозимӣ +Comment[th]=เปลี่ยนตำแหน่งที่เก็บแฟ้มที่สำคัญต่าง ๆ +Comment[tr]=Önemli dosyaların kaydedildiği yerleri düzenle +Comment[ug]=مۇھىم ھۆججەت ساقلايدىغان ئورۇننى ئۆزگەرت +Comment[uk]=Зміна адреси зберігання важливих файлів +Comment[uz]=Muhim fayllarning joylashgan joyini oʻzgartirish +Comment[uz@cyrillic]=Муҳим файлларнинг жойлашган жойини ўзгартириш +Comment[vi]=Thay đổi đường dẫn tới các tập tin quan trọng +Comment[wa]=Candjî l' eplaeçmint ki les fitchîs impôrtants sont wårdés +Comment[xh]=Tshintsha indawo apho zibekwa kona iifayile ezibalulekileyo +Comment[x-test]=xxChange the location important files are storedxx +Comment[zh_CN]=更改重要文件存储的位置 +Comment[zh_TW]=改變儲存重要檔案的位置 +X-KDE-Keywords=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures +X-KDE-Keywords[bs]=konqueror, delfin, datoteke, menadžer datoteka, put, putevi, desktop, upute, autostart, preuuzimanja, muzika, dokumenti, filmovi, slike +X-KDE-Keywords[ca]=konqueror,dolphin,fitxers,gestor de fitxers,camí,camins,escriptori,directoris,inici automàtic,baixades,música,documents,pel·lícules,imatges +X-KDE-Keywords[ca@valencia]=konqueror,dolphin,fitxers,gestor de fitxers,camí,camins,escriptori,directoris,inici automàtic,baixades,música,documents,pel·lícules,imatges +X-KDE-Keywords[da]=konqueror,dolphin,filhåndtering,stifinder,stier,skrivebord,mapper,autostart,downoad,hentninger,musik,dokumenter,film,billeder,filer,sti +X-KDE-Keywords[de]=Konqueror,Dolphin,Dateien,Dateimanager,Dateiverwaltung,Pfade,Arbeitsfläche,Verzeichnisse,Ordner,Autostart,Download,Herunterladen,Musik,Dokumente,Filme,Bilder +X-KDE-Keywords[el]=konqueror,dolphin,αρχεία,διαχειριστής αρχείων,διαδρομή, διαδρομές,επιφάνεια εργασίας,κατάλογοι,αυτόματη εκκίνηση,λήψεις,μουσική,έγγραφα,κινηματογραφία,εικόνες +X-KDE-Keywords[en_GB]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures +X-KDE-Keywords[es]=konqueror,dolphin,archivos,gestor de archivos,ruta,rutas,escritorio,directorios,autoinicio,descargas,música,documentos,películas,imágenes +X-KDE-Keywords[et]=konqueror,dolphin,failid,failihaldur,asukohad,töölaud,kataloogid,autostart,allalaadimised,muusika,dokumendid,filmid,pildid +X-KDE-Keywords[eu]=konqueror,dolphin,fitxategi,fitxategi-kudeatzaile,bide-izen, bide-izenak,mahaigain,direktorio,hasi automatikoki,deskargak,musika,dokumentuak,filmak,irudiak +X-KDE-Keywords[fi]=konqueror,dolphin,tiedostot,tiedostonhallinta,polku,polut,työpöytä,hakemistot,kansiot,automaattikäynnistys,lataukset,musiikki,asiakirjat,elokuvat,kuvat +X-KDE-Keywords[fr]=konqueror, dolphin, fichiers, gestionnaire de fichiers, emplacement, emplacements, bureau, dossiers, démarrage automatique, téléchargements, musique, documents, films, images +X-KDE-Keywords[ga]=konqueror,dolphin,comhaid,bainisteoir comhad,conairí,cosáin,deasc,comhadlanna,tosú uathoibríoch,íosluchtuithe,ceol,cáipéisí,scannáin,pictiúir,grianghraif +X-KDE-Keywords[gl]=konqueror, dolphin, ficheiros, xestor de ficheiros, ruta, rutas, escritorio, cartafoles, inicio automático, descargas, música, documentos, películas, imaxes +X-KDE-Keywords[hu]=konqueror,dolphin,fájlok,fájlkezelő,elérési út, elérési utak,asztal,mappák, automatikus indítás,letöltések,zene,dokumentumok,filmek,képek +X-KDE-Keywords[ia]=konqueror,dolphin,files,gerente de file,percurso,percursos,scriptorio,directorios,autoinitio,discargamentos, musica,documentos,pelliculas,photos +X-KDE-Keywords[it]=konqueror,dolphin,file,gestore dei file,percorso,percorsi,desktop,cartelle,avvio automatico,scaricamenti,musica,documenti,film,immagini +X-KDE-Keywords[kk]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures +X-KDE-Keywords[km]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures +X-KDE-Keywords[ko]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,파일,파일 관리자,탐색기,디렉터리,다운로드,음악,문서,비디오,그림 +X-KDE-Keywords[mr]=कॉन्करर , डॉल्फीन, फाईल्स, फाईल मेनेजर, पाथस , डेस्कटॉप , डीरेक्टरिज , ऑटोस्टार्ट, डाउनलोडस,म्युझिक, डॉक्युमेंट, मूव्हीज, पिक्चर्स +X-KDE-Keywords[nb]=konqueror,dolphin,filer,filbehandler,sti,stier,skrivebord,mapper,autostart,nedlastinger,musikk,dokumenter,filmer,bilder +X-KDE-Keywords[nds]=Konqueror,Dolphin,Dateien,Dateipleger,Padden,Schriefdisch,Ornern,Vertekens,Autostart,Daalladen,Musik,Dokmenten,Filmen,Biller +X-KDE-Keywords[nl]=konqueror,dolphin,bestanden,bestandsbeheerder,pad,paden,bureaublad,mappen,autostart,downloads,muziek,documenten,films,afbeeldingen +X-KDE-Keywords[pl]=konqueror,dolphin,pliki,menadżer plików,ścieżka,ścieżki,pulpit,katalogi,auto-uruchamianie, pobierania,muzyka,dokumenty,filmy,zdjęcia,autostart +X-KDE-Keywords[pt]=konqueror,gestor de ficheiros,localizações,ecrã,pastas,arranque,transferências,música,documentos,filmes,imagens +X-KDE-Keywords[pt_BR]=konqueror,dolphin,arquivos,gerenciador de arquivos,localização,localizações,caminho,caminhos,área de trabalho,pastas,inicialização,downloads,música,documentos,filmes,imagens +X-KDE-Keywords[ru]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,файлы,диспетчер файлов,путь,местоположение,рабочий стол,директории,каталоги,папки,автозапуск,загрузки,музыка,документы,фильмы,видео,картинки +X-KDE-Keywords[sk]=konqueror,dolphin,súbory,správca súborov,cesta,cesty,plocha,adresáre,automatické spustenie,sťahovania,hudba,dokumenty,filmy,obrázky +X-KDE-Keywords[sl]=konqueror,dolphin,datoteke,upravljalnik datotek,datotečni upravljalnik,poti,namizje,mape,samodejni zagon,prejeto,prejemi,glasba,dokumenti,filmi,slike +X-KDE-Keywords[sr]=konqueror,dolphin,files,filemanager,path,paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,К‑освајач,Делфин,фајлови,менаџер фајлова,путање,путања,површ,фасцикле,самопокретање,преузимање,музика,документи,филмови,слике +X-KDE-Keywords[sr@ijekavian]=konqueror,dolphin,files,filemanager,path,paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,К‑освајач,Делфин,фајлови,менаџер фајлова,путање,путања,површ,фасцикле,самопокретање,преузимање,музика,документи,филмови,слике +X-KDE-Keywords[sr@ijekavianlatin]=konqueror,dolphin,files,filemanager,path,paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,K‑osvajač,Dolphin,fajlovi,menadžer fajlova,putanje,putanja,površ,fascikle,samopokretanje,preuzimanje,muzika,dokumenti,filmovi,slike +X-KDE-Keywords[sr@latin]=konqueror,dolphin,files,filemanager,path,paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,K‑osvajač,Dolphin,fajlovi,menadžer fajlova,putanje,putanja,površ,fascikle,samopokretanje,preuzimanje,muzika,dokumenti,filmovi,slike +X-KDE-Keywords[sv]=konqueror,dolphin,filer,filhanterare,sökväg,sökvägar,skrivbord,kataloger,automatisk start,nerladdningar,musik,dokument,filmer,bilder +X-KDE-Keywords[tr]=konqueror,dolphin,dosyalar,dosya yöneticisi,yol, yollar,masaüstü,dizinler,otomatik başlat,indirmeler,müzik,belgeler,filmler,resimler +X-KDE-Keywords[uk]=konqueror,dolphin,files,filemanager,paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,файл,дельфін,керування,менеджер,шляхи,стільниця,каталог,каталоги,автоматично,автоматичний,запуск,звантаження,завантаження,музика,документи,фільми,відео,зображення,знімки,фотографії +X-KDE-Keywords[x-test]=xxkonqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,picturesxx +X-KDE-Keywords[zh_CN]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures,文件,文件管理器,路径,桌面,目录,自动启动,下载,音乐,文档,电影,图片 +X-KDE-Keywords[zh_TW]=konqueror,dolphin,files,filemanager,path, paths,desktop,directories,autostart,downloads,music,documents,movies,pictures diff --git a/kcontrol/desktoppaths/globalpaths.cpp b/kcontrol/desktoppaths/globalpaths.cpp new file mode 100644 index 00000000..845757af --- /dev/null +++ b/kcontrol/desktoppaths/globalpaths.cpp @@ -0,0 +1,419 @@ +/** + * Copyright (c) Martin R. Jones 1996 + * Copyright (c) Bernd Wuebben 1998 + * Copyright (c) Christian Tibirna 1998 + * Copyright 1998-2007 David Faure + * Copyright (c) 2010 Matthias Fuchs + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// +// +// "Desktop Options" Tab for KDesktop configuration +// +// (c) Martin R. Jones 1996 +// (c) Bernd Wuebben 1998 +// +// Layouts +// (c) Christian Tibirna 1998 +// Port to KControl, split from Misc Tab, Port to KControl2 +// (c) David Faure 1998 +// Desktop menus, paths +// (c) David Faure 2000 + + +// Own +#include "globalpaths.h" + +// Qt +#include +#include +#include +#include +#include +#include +#include +#include + +// KDE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcmdesktoppaths.h" + +//----------------------------------------------------------------------------- + +DesktopPathConfig::DesktopPathConfig(QWidget *parent, const QVariantList &) + : KCModule( KcmDesktopPaths::componentData(), parent ) +{ + QFormLayout *lay = new QFormLayout(this); + lay->setMargin(0); + + setQuickHelp( i18n("

    Paths

    \n" + "This module allows you to choose where in the filesystem the " + "files on your desktop should be stored.\n" + "Use the \"Whats This?\" (Shift+F1) to get help on specific options.")); + + urDesktop = addRow(lay, i18n("Desktop path:"), + i18n("This folder contains all the files" + " which you see on your desktop. You can change the location of this" + " folder if you want to, and the contents will move automatically" + " to the new location as well.")); + + urAutostart = addRow(lay, i18n("Autostart path:"), + i18n("This folder contains applications or" + " links to applications (shortcuts) that you want to have started" + " automatically whenever KDE starts. You can change the location of this" + " folder if you want to, and the contents will move automatically" + " to the new location as well.")); + + urDocument = addRow(lay, i18n("Documents path:"), + i18n("This folder will be used by default to " + "load or save documents from or to.")); + + urDownload = addRow(lay, i18n("Downloads path:"), + i18n("This folder will be used by default to " + "save your downloaded items.")); + + urMovie = addRow(lay, i18n("Movies path:"), + i18n("This folder will be used by default to " + "load or save movies from or to.")); + + urPicture = addRow(lay, i18n("Pictures path:"), + i18n("This folder will be used by default to " + "load or save pictures from or to.")); + + urMusic = addRow(lay, i18n("Music path:"), + i18n("This folder will be used by default to " + "load or save music from or to.")); +} + +KUrlRequester* DesktopPathConfig::addRow(QFormLayout *lay, const QString& label, const QString& whatsThis) +{ + KUrlRequester* ur = new KUrlRequester(this); + ur->setMode(KFile::Directory | KFile::LocalOnly); + lay->addRow(label, ur); + connect(ur, SIGNAL(textChanged(QString)), this, SLOT(changed())); + lay->labelForField(ur)->setWhatsThis(whatsThis); + ur->setWhatsThis(whatsThis); + return ur; +} + +void DesktopPathConfig::load() +{ + // Desktop Paths + urDesktop->setUrl( KGlobalSettings::desktopPath() ); + urAutostart->setUrl( KGlobalSettings::autostartPath() ); + urDocument->setUrl( KGlobalSettings::documentPath() ); + urDownload->setUrl( KGlobalSettings::downloadPath() ); + urMovie->setUrl( KGlobalSettings::videosPath() ); + urPicture->setUrl( KGlobalSettings::picturesPath() ); + urMusic->setUrl( KGlobalSettings::musicPath() ); + emit changed(false); +} + +void DesktopPathConfig::defaults() +{ + // Desktop Paths - keep defaults in sync with kglobalsettings.cpp + urDesktop->setUrl( QString(QDir::homePath() + "/Desktop") ); + urAutostart->setUrl( QString(KGlobal::dirs()->localkdedir() + "Autostart/") ); + urDocument->setUrl( QString(QDir::homePath() + "/Documents") ); + urDownload->setUrl( QString(QDir::homePath() + "/Downloads") ); + urMovie->setUrl( QString(QDir::homePath() + "/Movies") ); + urPicture->setUrl( QString(QDir::homePath() + "/Pictures") ); + urMusic->setUrl( QString(QDir::homePath() + "/Music") ); +} + +// the following method is copied from kdelibs/kdecore/config/kconfiggroup.cpp +static bool cleanHomeDirPath( QString &path, const QString &homeDir ) +{ +#ifdef Q_WS_WIN //safer + if (!QDir::convertSeparators(path).startsWith(QDir::convertSeparators(homeDir))) + return false; +#else + if (!path.startsWith(homeDir)) + return false; +#endif + + int len = homeDir.length(); + // replace by "$HOME" if possible + if (len && (path.length() == len || path[len] == '/')) { + path.replace(0, len, QString::fromLatin1("$HOME")); + return true; + } else + return false; +} + +// TODO this functionality is duplicated in libkonq - keep it only there and export + +static QString translatePath( QString path ) // krazy:exclude=passbyvalue +{ + // keep only one single '/' at the beginning - needed for cleanHomeDirPath() + while (path[0] == '/' && path[1] == '/') + path.remove(0,1); + + // we probably should escape any $ ` and \ characters that may occur in the path, but the Qt code that reads back + // the file doesn't unescape them so not much point in doing so + + // All of the 3 following functions to return the user's home directory + // can return different paths. We have to test all them. + const QString homeDir0 = QFile::decodeName(qgetenv("HOME")); + const QString homeDir1 = QDir::homePath(); + const QString homeDir2 = QDir(homeDir1).canonicalPath(); + if (cleanHomeDirPath(path, homeDir0) || + cleanHomeDirPath(path, homeDir1) || + cleanHomeDirPath(path, homeDir2) ) { + // kDebug() << "Path was replaced\n"; + } + + return path; +} + +void DesktopPathConfig::save() +{ + KSharedConfig::Ptr config = KGlobal::config(); + KConfigGroup configGroup( config, "Paths" ); + + bool pathChanged = false; + bool autostartMoved = false; + + KUrl desktopURL( KGlobalSettings::desktopPath() ); + + KUrl autostartURL( KGlobalSettings::autostartPath() ); + KUrl newAutostartURL = urAutostart->url(); + + if ( !urDesktop->url().equals( desktopURL, KUrl::CompareWithoutTrailingSlash ) ) + { + // Test which other paths were inside this one (as it is by default) + // and for each, test where it should go. + // * Inside destination -> let them be moved with the desktop (but adjust name if necessary) + // * Not inside destination -> move first + // !!! + kDebug() << "desktopURL=" << desktopURL; + QString urlDesktop = urDesktop->url().toLocalFile(); + if ( !urlDesktop.endsWith('/')) + urlDesktop+='/'; + + if ( desktopURL.isParentOf( autostartURL ) ) + { + kDebug() << "Autostart is on the desktop"; + + // Either the Autostart field wasn't changed (-> need to update it) + if ( newAutostartURL.equals( autostartURL, KUrl::CompareWithoutTrailingSlash ) ) + { + // Hack. It could be in a subdir inside desktop. Hmmm... Argl. + urAutostart->setUrl( QString(urlDesktop + "Autostart/") ); + kDebug() << "Autostart is moved with the desktop"; + autostartMoved = true; + } + // or it has been changed (->need to move it from here) + else + { + KUrl futureAutostartURL; + futureAutostartURL.setUrl( urlDesktop + "Autostart/" ); + if ( newAutostartURL.equals( futureAutostartURL, KUrl::CompareWithoutTrailingSlash ) ) + autostartMoved = true; + else + autostartMoved = moveDir( KUrl( KGlobalSettings::autostartPath() ), KUrl( urAutostart->url() ), i18n("Autostart") ); + } + } + + if ( moveDir( KUrl( KGlobalSettings::desktopPath() ), KUrl( urlDesktop ), i18n("Desktop") ) ) + { + //save in XDG path + const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs")); + KConfig xdgUserConf( userDirsFile, KConfig::SimpleConfig ); + KConfigGroup g( &xdgUserConf, "" ); + g.writeEntry( "XDG_DESKTOP_DIR", QString("\"" + translatePath( urlDesktop ) + "\"") ); + pathChanged = true; + } + } + + if ( !newAutostartURL.equals( autostartURL, KUrl::CompareWithoutTrailingSlash ) ) + { + if (!autostartMoved) + autostartMoved = moveDir( KUrl( KGlobalSettings::autostartPath() ), KUrl( urAutostart->url() ), i18n("Autostart") ); + if (autostartMoved) + { + configGroup.writePathEntry( "Autostart", urAutostart->url().toLocalFile(), KConfigBase::Normal | KConfigBase::Global ); + pathChanged = true; + } + } + + config->sync(); + + if (xdgSavePath(urDocument, KGlobalSettings::documentPath(), "XDG_DOCUMENTS_DIR", i18n("Documents"))) + pathChanged = true; + + if (xdgSavePath(urDownload, KGlobalSettings::downloadPath(), "XDG_DOWNLOAD_DIR", i18n("Downloads"))) + pathChanged = true; + + if (xdgSavePath(urMovie, KGlobalSettings::videosPath(), "XDG_VIDEOS_DIR", i18n("Movies"))) + pathChanged = true; + + if (xdgSavePath(urPicture, KGlobalSettings::picturesPath(), "XDG_PICTURES_DIR", i18n("Pictures"))) + pathChanged = true; + + if (xdgSavePath(urMusic, KGlobalSettings::musicPath(), "XDG_MUSIC_DIR", i18n("Music"))) + pathChanged = true; + + if (pathChanged) { + kDebug() << "sending message SettingsChanged"; + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_PATHS); + } +} + +bool DesktopPathConfig::xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type) +{ + KUrl newUrl = ur->url(); + //url might be empty, use QDir::homePath (the default for xdg) then + if (!newUrl.isValid()) { + newUrl = KUrl(QDir::homePath()); + } + if (!newUrl.equals(currentUrl, KUrl::CompareWithoutTrailingSlash)) { + const QString path = newUrl.toLocalFile(); + if (!QDir(path).exists()) { + // Check permissions + if (KStandardDirs::makeDir(path)) { + QDir().rmdir(path); // rmdir again, so that we get a fast rename + } else { + KMessageBox::sorry(this, KIO::buildErrorString(KIO::ERR_COULD_NOT_MKDIR, path)); + ur->setUrl(currentUrl); // revert + return false; + } + } + if (moveDir(currentUrl, newUrl, type)) { + //save in XDG user-dirs.dirs config file, this is where KGlobalSettings/QDesktopServices reads from. + const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs")); + KConfig xdgUserConf(userDirsFile, KConfig::SimpleConfig); + KConfigGroup g(&xdgUserConf, ""); + g.writeEntry(xdgKey, QString("\"" + translatePath(path) + "\"")); + return true; + } + } + return false; +} + +bool DesktopPathConfig::moveDir( const KUrl & src, const KUrl & dest, const QString & type ) +{ + if (!src.isLocalFile() || !dest.isLocalFile()) + return true; + if (!QFile::exists(src.toLocalFile())) + return true; + // Do not move $HOME! #193057 + const QString translatedPath = translatePath(src.toLocalFile()); + if (translatedPath == "$HOME" || translatedPath == "$HOME/") { + return true; + } + + m_ok = true; + + QString question; + KGuiItem yesItem; + KGuiItem noItem; + if (QFile::exists(dest.toLocalFile())) { + // TODO: check if the src dir is empty? Nothing to move, then... + question = i18n("The path for '%1' has been changed.\nDo you want the files to be moved from '%2' to '%3'?", + type, src.toLocalFile(), + dest.toLocalFile()); + yesItem = KGuiItem(i18nc("Move files from old to new place", "Move")); + noItem = KGuiItem(i18nc("Use the new directory but do not move files", "Do not Move")); + } else { + question = i18n("The path for '%1' has been changed.\nDo you want to move the directory '%2' to '%3'?", + type, src.toLocalFile(), + dest.toLocalFile()); + yesItem = KGuiItem(i18nc("Move the directory", "Move")); + noItem = KGuiItem(i18nc("Use the new directory but do not move anything", "Do not Move")); + } + + // Ask for confirmation before moving the files + if (KMessageBox::questionYesNo(this, question, i18n("Confirmation Required"), + yesItem, noItem) + == KMessageBox::Yes ) + { + if (QFile::exists(dest.toLocalFile())) { + // Destination already exists -- should always be the case, for most types, + // but maybe not for the complex autostart case (to be checked...) + m_copyToDest = dest; + m_copyFromSrc = src; + KIO::ListJob* job = KIO::listDir( src ); + job->setAutoDelete(false); // see below + job->ui()->setWindow(this); + job->ui()->setAutoErrorHandlingEnabled(true); + connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), + this, SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList))); + // slotEntries will move every file/subdir individually into the dest + job->exec(); + if (m_ok) { + QDir().rmdir(src.toLocalFile()); // hopefully it's empty by now + } + delete job; + } + else + { + kDebug() << "Direct move from" << src << "to" << dest; + KIO::Job * job = KIO::move( src, dest ); + job->ui()->setWindow(this); + connect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*))); + job->exec(); + } + } + kDebug() << "DesktopPathConfig::slotResult returning " << m_ok; + return m_ok; +} + +void DesktopPathConfig::slotEntries(KIO::Job*, const KIO::UDSEntryList& list) +{ + QListIterator it(list); + while (it.hasNext()) { + KFileItem file(it.next(), m_copyFromSrc, true, true); + kDebug() << file.url(); + if (file.url() == m_copyFromSrc || file.url().fileName() == "..") { + continue; + } + + KIO::Job * moveJob = KIO::move(file.url(), m_copyToDest); + moveJob->ui()->setWindow(this); + connect(moveJob, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*))); + moveJob->exec(); // sub-event loop here. : the main job is not autodeleted because it would be deleted here + } +} + +void DesktopPathConfig::slotResult( KJob * job ) +{ + if (job->error()) { + if ( job->error() != KIO::ERR_DOES_NOT_EXIST ) + m_ok = false; + + // If the source doesn't exist, no wonder we couldn't move the dir. + // In that case, trust the user and set the new setting in any case. + + static_cast(job)->ui()->showErrorMessage(); + } +} + +#include "globalpaths.moc" diff --git a/kcontrol/desktoppaths/globalpaths.h b/kcontrol/desktoppaths/globalpaths.h new file mode 100644 index 00000000..2833a66b --- /dev/null +++ b/kcontrol/desktoppaths/globalpaths.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) Martin R. Jones 1996 + * Copyright 1998-2007 David Faure + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// Summarized history: +// +// "Desktop Icons Options" Tab for KDesktop configuration +// Martin Jones +// +// Port to KControl, split from "Misc" Tab, Port to KControl2 +// (c) David Faure 1998 +// Desktop menus, paths +// (c) David Faure 2000 + +#ifndef __GLOBALPATHS_H +#define __GLOBALPATHS_H + +#include +#include +#include +#include + +class QFormLayout; +class KJob; +class KUrlRequester; +class QStringList; + +namespace KIO { class Job; } + +//----------------------------------------------------------------------------- +// The "Path" Tab contains : +// The paths for Desktop, Autostart and Documents + +class DesktopPathConfig : public KCModule +{ + Q_OBJECT +public: + DesktopPathConfig( QWidget *parent, const QVariantList &args ); + virtual void load(); + virtual void save(); + virtual void defaults(); + +private Q_SLOTS: + void slotEntries( KIO::Job * job, const KIO::UDSEntryList& list); + +private: + KUrlRequester* addRow(QFormLayout *lay, const QString& label, const QString& whatsThis); + bool xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type); + + // Desktop Paths + KUrlRequester *urDesktop; + KUrlRequester *urAutostart; + KUrlRequester *urDocument; + KUrlRequester *urDownload; + KUrlRequester *urMovie; + KUrlRequester *urPicture; + KUrlRequester *urMusic; + + bool moveDir( const KUrl & src, const KUrl & dest, const QString & type ); + bool m_ok; + KUrl m_copyToDest; // used when the destination directory already exists + KUrl m_copyFromSrc; + +private Q_SLOTS: + void slotResult( KJob * job ); +}; + +#endif + diff --git a/kcontrol/desktoppaths/kcmdesktoppaths.cpp b/kcontrol/desktoppaths/kcmdesktoppaths.cpp new file mode 100644 index 00000000..e7809fe8 --- /dev/null +++ b/kcontrol/desktoppaths/kcmdesktoppaths.cpp @@ -0,0 +1,29 @@ +/* This file is part of the KDE project + Copyright (C) 2006-2007 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "kcmdesktoppaths.h" +#include "globalpaths.h" + +#include +#include + +K_PLUGIN_FACTORY_DEFINITION(KcmDesktopPaths, + registerPlugin("dpath"); + ) +K_EXPORT_PLUGIN(KcmDesktopPaths("kcm_desktoppaths")) diff --git a/kcontrol/desktoppaths/kcmdesktoppaths.h b/kcontrol/desktoppaths/kcmdesktoppaths.h new file mode 100644 index 00000000..0c6295cb --- /dev/null +++ b/kcontrol/desktoppaths/kcmdesktoppaths.h @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2006-2007 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef KCMDESKTOPPATHS_H +#define KCMDESKTOPPATHS_H + +#include + +K_PLUGIN_FACTORY_DECLARATION(KcmDesktopPaths) + +#endif // KCMDESKTOPPATHS_H diff --git a/kcontrol/desktoptheme/CMakeLists.txt b/kcontrol/desktoptheme/CMakeLists.txt new file mode 100644 index 00000000..a93fb41d --- /dev/null +++ b/kcontrol/desktoptheme/CMakeLists.txt @@ -0,0 +1,16 @@ +# Project Needs a name ofcourse +project(desktoptheme) + +set(kcmdesktoptheme_SRCS kcmdesktoptheme.cpp desktopthemedetails.cpp thememodel.cpp) +kde4_add_ui_files(kcmdesktoptheme_SRCS DesktopTheme.ui DesktopThemeDetails.ui) + +kde4_add_plugin(kcm_desktoptheme ${kcmdesktoptheme_SRCS}) +target_link_libraries(kcm_desktoptheme ${X11_LIBRARIES} + ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} ${KDE4_KNEWSTUFF3_LIBS} + ${KDE4_KCMUTILS_LIBRARY} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS kcm_desktoptheme DESTINATION ${PLUGIN_INSTALL_DIR} ) + +########### install files ############### +install( FILES desktoptheme.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/kcontrol/desktoptheme/DesktopTheme.ui b/kcontrol/desktoptheme/DesktopTheme.ui new file mode 100644 index 00000000..7fe2bf6f --- /dev/null +++ b/kcontrol/desktoptheme/DesktopTheme.ui @@ -0,0 +1,81 @@ + + + DesktopTheme + + + + 0 + 0 + 669 + 460 + + + + + + + 0 + + + + Theme + + + + + + + + + Qt::Horizontal + + + + 462 + 20 + + + + + + + + true + + + Get New Themes... + + + + + + + + Details + + + + + + + + + + + + + + KPushButton + QPushButton +
    kpushbutton.h
    +
    + + DesktopThemeDetails + QWidget +
    desktopthemedetails.h
    + 1 +
    +
    + + +
    diff --git a/kcontrol/desktoptheme/DesktopThemeDetails.ui b/kcontrol/desktoptheme/DesktopThemeDetails.ui new file mode 100644 index 00000000..9df3536e --- /dev/null +++ b/kcontrol/desktoptheme/DesktopThemeDetails.ui @@ -0,0 +1,395 @@ + + + DesktopThemeItems + + + + 0 + 0 + 661 + 487 + + + + + 0 + 0 + + + + + 200 + 700 + + + + Desktop Theme Details + + + + + + + + + + 0 + 0 + + + + Choose an item and customize it by assigning it a theme + + + You can set any theme to any item. The available themes for the item are in the dropdown box on the right. + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + false + + + false + + + + + + + + 0 + 0 + + + + + + + Enable more options + + + This will expand the dialog and give you options to export your custom theme as well as to remove a theme. + + + More + + + + + + + + + true + + + Remove the selected theme + + + Clicking this button will remove the selected theme. You will be asked for confirmation. + + + Remove Theme + + + + + + + true + + + Save your theme in a zip archive + + + You can save your theme in a zip archive in order to share it with the community. + + + Export Theme to File... + + + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + Qt::Horizontal + + + + + + + + + New theme name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_newThemeName + + + + + + + Custom theme name + + + Give a name to your custom theme. + + + + + + + Author: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_newThemeAuthor + + + + + + + Custom theme author + + + Enter the author name of your custom theme. + + + + + + + Version: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_newThemeVersion + + + + + + + Custom theme version number + + + Enter the version number of your custom theme. + + + + + + + + + + + Description: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_newThemeDescription + + + + + + + + 0 + 0 + + + + Custom theme description + + + Enter a description which will explain your custom theme. + + + + + + + + + + + + Qt::Vertical + + + + + + + Select theme from above to customize + + + + + + + + 0 + 0 + + + + + + + + + Theme Author + + + Qt::AlignLeading + + + + + + + + 75 + true + + + + Theme Name + + + Qt::AlignCenter + + + + + + + Theme Version + + + Qt::AlignRight + + + + + + + + + The theme description goes here... + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 130 + + + + + + + + + 187 + 187 + 187 + + + + + + + + + 187 + 187 + 187 + + + + + + + + + 255 + 255 + 255 + + + + + + + + Available themes + + + Choose a start theme in this list then customize some items below. All less important items not listed below will use this start theme. + + + Qt::ScrollBarAlwaysOff + + + false + + + QListView::IconMode + + + + + + + + KLineEdit + QLineEdit +
    klineedit.h
    +
    +
    + + +
    diff --git a/kcontrol/desktoptheme/Messages.sh b/kcontrol/desktoptheme/Messages.sh new file mode 100755 index 00000000..14b32ad9 --- /dev/null +++ b/kcontrol/desktoptheme/Messages.sh @@ -0,0 +1,4 @@ +#! /bin/sh +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcm_desktopthemedetails.pot +rm -f rc.cpp diff --git a/kcontrol/desktoptheme/desktoptheme.desktop b/kcontrol/desktoptheme/desktoptheme.desktop new file mode 100644 index 00000000..756bd032 --- /dev/null +++ b/kcontrol/desktoptheme/desktoptheme.desktop @@ -0,0 +1,187 @@ +[Desktop Entry] +Exec=kcmshell4 desktoptheme +Icon=preferences-desktop +Type=Service + +X-KDE-ServiceTypes=KCModule +X-KDE-Library=kcm_desktoptheme +X-KDE-ParentApp=kcontrol +X-KDE-System-Settings-Parent-Category=desktop-appearance +X-DocPath=kcontrol/desktopthemedetails/index.html + +Name=Desktop Theme +Name[ar]=سمة سطح المكتب +Name[ast]=Tema d'escritoriu +Name[bg]=Тема за работния плот +Name[bn]=ডেস্কটপ থীম +Name[bs]=Tema površi +Name[ca]=Tema d'escriptori +Name[ca@valencia]=Tema d'escriptori +Name[cs]=Motiv plochy +Name[da]=Skrivebordstema +Name[de]=Arbeitsflächen-Design +Name[el]=Θέμα επιφάνειας εργασίας +Name[en_GB]=Desktop Theme +Name[es]=Tema de escritorio +Name[et]=Töölauateema +Name[eu]=Mahaigaineko gaia +Name[fi]=Työpöytäteema +Name[fr]=Thème de bureau +Name[ga]=Téama Deisce +Name[gl]=Tema do escritorio +Name[gu]=ડેસ્કટોપ થીમ +Name[he]=ערכת־הנושא לשולחן־העבודה +Name[hi]=डेस्कटॉप प्रसंग +Name[hr]=Tema radne površine +Name[hu]=Asztali téma +Name[ia]=Thema de scriptorio +Name[id]=Tema Desktop +Name[is]=Skjáborðsþema +Name[it]=Tema del desktop +Name[ja]=デスクトップテーマ +Name[kk]=Үстел нақышы +Name[km]=ស្បែក​ផ្ទៃតុ +Name[kn]=ಗಣಕತೆರೆ ಪರಿಸರವಿನ್ಯಾಸ +Name[ko]=데스크톱 테마 +Name[lt]=Darbastalio tema +Name[lv]=Darbvirsmas tēma +Name[mr]=डेस्कटॉप शैली +Name[nb]=Skrivebordstema +Name[nds]=Schriefdischmuster +Name[nl]=Bureaubladthema +Name[nn]=Skrivebordstema +Name[pa]=ਡੈਸਕਟਾਪ ਥੀਮ +Name[pl]=Wystrój pulpitu +Name[pt]=Tema do Ambiente de Trabalho +Name[pt_BR]=Tema da área de trabalho +Name[ro]=Tematica de birou +Name[ru]=Тема рабочего стола +Name[si]=වැඩතල තේමාව +Name[sk]=Téma plochy +Name[sl]=Namizna tema +Name[sr]=Тема површи +Name[sr@ijekavian]=Тема површи +Name[sr@ijekavianlatin]=Tema površi +Name[sr@latin]=Tema površi +Name[sv]=Skrivbordstema +Name[tg]=Мавзӯъи мизи корӣ +Name[th]=ชุดตกแต่งพื้นที่ทำงาน +Name[tr]=Masaüstü Teması +Name[ug]=ئۈستەلئۈستى ئۆرنىكى +Name[uk]=Тема стільниці +Name[vi]=Sắc thái màn hình +Name[wa]=Tinme do scribanne +Name[x-test]=xxDesktop Themexx +Name[zh_CN]=桌面主题 +Name[zh_TW]=桌面主題 +Comment=Customize the desktop theme +Comment[ar]=خصص عناصر السمة سطح المكتب بشكل منفرد +Comment[ast]=Personalizar el tema d'escritoriu +Comment[bg]=Настройки на теми за работния плот +Comment[bn]=ডেস্কটপ থীম পছন্দমত বদলান +Comment[bs]=Prilagodite temu površi +Comment[ca]=Personalitza el tema d'escriptori +Comment[ca@valencia]=Personalitza el tema d'escriptori +Comment[cs]=Upravit vzhled plochy +Comment[da]=Tilpas skrivebordstemaet +Comment[de]=Arbeitsflächen-Design anpassen +Comment[el]=Προσαρμογή θέματος της επιφάνειας εργασίας +Comment[en_GB]=Customise the desktop theme +Comment[es]=Personalizar el tema de escritorio +Comment[et]=Töölauateema kohandamine +Comment[eu]=Pertsonalizatu mahaigaineko gaia +Comment[fi]=Työpöytäteeman asetukset +Comment[ga]=Saincheap an téama deisce +Comment[gl]=Personaliza o tema do escritorio +Comment[he]=התאמה אישית של ערכת־הנושא לשולחן־העבודה +Comment[hi]=डेस्कटॉप प्रसंग मनपसंद बनाएँ +Comment[hr]=Prilagodba teme radne površine +Comment[hu]=Az asztali téma testreszabása +Comment[ia]=Personalisar le thema de scriptorio +Comment[id]=Sesuaikan tema desktop +Comment[is]=Sérsníða skjáborðsþema +Comment[kk]=Үстел нақышын өзінше баптап алу +Comment[km]=ប្ដូរ​ស្បែក​ផ្ទៃតុ​តាមបំណង +Comment[kn]=ಗಣಕತೆರೆ ಪರಿಸರವಿನ್ಯಾಸವನ್ನು ಇಚ್ಛೆಗೆ ತಕ್ಕಂತೆ ಹೊಂದಿಸಿ +Comment[ko]=테마 사용자 정의 +Comment[lt]=Derinti darbastalio temą +Comment[lv]=Pielāgot darbivrsmas tēmu +Comment[mr]=डेस्कटॉप शैलीत ऐच्छिक बदल करा +Comment[nb]=Still inn temaet for skrivebordet +Comment[nds]=Dat Schriefdischmuster topassen +Comment[nl]=Pas het bureaubladthema aan +Comment[nn]=Tilpass skrivebordstemaet +Comment[pa]=ਡੈਸਕਟਾਪ ਥੀਮ ਕਸਟਮਾਈਜ਼ ਕਰੋ +Comment[pl]=Dostosowywanie wystroju pulpitu +Comment[pt]=Personalizar o tema do ambiente de trabalho +Comment[pt_BR]=Personaliza o tema da área de trabalho +Comment[ro]=Particularizează tematica de birou +Comment[ru]=Настройка темы рабочего стола +Comment[si]=වැඩතල තේමාව රිසිකරණය කරන්න +Comment[sk]=Prispôsobenie témy plochy +Comment[sl]=Prilagodite namizno temo +Comment[sr]=Прилагодите тему површи +Comment[sr@ijekavian]=Прилагодите тему површи +Comment[sr@ijekavianlatin]=Prilagodite temu površi +Comment[sr@latin]=Prilagodite temu površi +Comment[sv]=Anpassa skrivbordstemat +Comment[tg]=Танзимоти мавзӯъи мизи корӣ +Comment[th]=ปรับแต่งชุดตกแต่งพื้นที่ทำงานด้วยตนเอง +Comment[tr]=Masaüstü temasını özelleştir +Comment[ug]=ئۈستەلئۈستى ئۆرنىكىنى ئۆزلەشتۈرىدۇ +Comment[uk]=Налаштування теми стільниці +Comment[vi]=Tuỳ chỉnh sắc thái màn hình +Comment[wa]=Mete a vosse môde li tinme do scribanne +Comment[x-test]=xxCustomize the desktop themexx +Comment[zh_CN]=定制桌面主题 +Comment[zh_TW]=自訂桌面主題 +X-KDE-Keywords=Desktop Theme +X-KDE-Keywords[ar]=سمة سطح المكتب +X-KDE-Keywords[bs]=Tema površi +X-KDE-Keywords[ca]=Tema d'escriptori +X-KDE-Keywords[ca@valencia]=Tema d'escriptori +X-KDE-Keywords[cs]=Motiv plochy +X-KDE-Keywords[da]=Skrivebordstema +X-KDE-Keywords[de]=Arbeitsflächen-Design +X-KDE-Keywords[el]=Θέμα επιφάνειας εργασίας +X-KDE-Keywords[en_GB]=Desktop Theme +X-KDE-Keywords[es]=Tema de escritorio +X-KDE-Keywords[et]=Töölauateema +X-KDE-Keywords[eu]=Mahaigaineko gaia +X-KDE-Keywords[fi]=Työpöytäteema +X-KDE-Keywords[fr]=Thème du bureau +X-KDE-Keywords[ga]=Téama Deisce +X-KDE-Keywords[gl]=Tema do escritorio +X-KDE-Keywords[he]=ערכת־הנושא +X-KDE-Keywords[hu]=Asztali téma +X-KDE-Keywords[ia]=Thema de scriptorio +X-KDE-Keywords[is]=Skjáborðsþema +X-KDE-Keywords[it]=Tema del desktop +X-KDE-Keywords[kk]=Desktop Theme,Үстел нақышы +X-KDE-Keywords[km]=រូបរាង​ផ្ទៃតុ +X-KDE-Keywords[ko]=데스크톱 테마 +X-KDE-Keywords[lt]=Darbastalio tema +X-KDE-Keywords[mr]=डेस्कटॉप शैली +X-KDE-Keywords[nb]=Skrivebordstema +X-KDE-Keywords[nds]=Schriefdischmuster +X-KDE-Keywords[nl]=Bureaubladthema +X-KDE-Keywords[pa]=ਡੈਸਕਟਾਪ ਥੀਮ +X-KDE-Keywords[pl]=Wystrój pulpitu +X-KDE-Keywords[pt]=Tema do Ambiente de Trabalho +X-KDE-Keywords[pt_BR]=Tema da área de trabalho +X-KDE-Keywords[ro]=Tematica de birou +X-KDE-Keywords[ru]=Тема рабочего стола +X-KDE-Keywords[sk]=Téma plochy +X-KDE-Keywords[sl]=Namizna tema +X-KDE-Keywords[sr]=Desktop Theme,тема површи +X-KDE-Keywords[sr@ijekavian]=Desktop Theme,тема површи +X-KDE-Keywords[sr@ijekavianlatin]=Desktop Theme,tema površi +X-KDE-Keywords[sr@latin]=Desktop Theme,tema površi +X-KDE-Keywords[sv]=Skrivbordstema +X-KDE-Keywords[tr]=Masaüstü Teması +X-KDE-Keywords[ug]=ئۈستەلئۈستى ئۆرنىكى +X-KDE-Keywords[uk]=тема,стільниця +X-KDE-Keywords[vi]=Sắc thái màn hình +X-KDE-Keywords[x-test]=xxDesktop Themexx +X-KDE-Keywords[zh_CN]=Desktop Theme,桌面主题 +X-KDE-Keywords[zh_TW]=Desktop Theme diff --git a/kcontrol/desktoptheme/desktopthemedetails.cpp b/kcontrol/desktoptheme/desktopthemedetails.cpp new file mode 100644 index 00000000..295edd92 --- /dev/null +++ b/kcontrol/desktoptheme/desktopthemedetails.cpp @@ -0,0 +1,582 @@ +/* + Copyright (c) 2008 Andrew Lake + Copyright (c) 2010 Jeremy Whiting + + 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. +*/ + +#include "desktopthemedetails.h" + +#include "thememodel.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ThemeItemNameType { + const char* m_type; + const char* m_displayItemName; + const char* m_themeItemPath; + const char* m_iconName; +}; + +const ThemeItemNameType themeCollectionName[] = { + { "Color Scheme", I18N_NOOP2("plasma name", "Color Scheme"),"colors", "preferences-desktop-color"}, + { "Panel Background", I18N_NOOP2("plasma name", "Panel Background"),"widgets/panel-background", "plasma"}, + { "Kickoff", I18N_NOOP2("plasma name", "Kickoff"), "dialogs/kickoff", "kde"}, + { "Task Items", I18N_NOOP2("plasma name", "Task Items"), "widgets/tasks", "preferences-system-windows"}, + { "Widget Background", I18N_NOOP2("plasma name", "Widget Background"), "widgets/background", "plasma"}, + { "Translucent Background", I18N_NOOP2("plasma name", "Translucent Background"), "widgets/translucentbackground", "plasma"}, + { "Dialog Background", I18N_NOOP2("plasma name", "Dialog Background"), "dialogs/background", "plasma"}, + { "Analog Clock", I18N_NOOP2("plasma name", "Analog Clock"), "widgets/clock", "chronometer"}, + { "Notes", I18N_NOOP2("plasma name", "Notes"), "widgets/notes", "view-pim-notes"}, + { "Tooltip", I18N_NOOP2("plasma name", "Tooltip"), "widgets/tooltip", "plasma"}, + { "Pager", I18N_NOOP2("plasma name", "Pager"), "widgets/pager", "plasma"}, + { "Run Command Dialog", I18N_NOOP2("plasma name", "Run Command Dialog"), "dialogs/krunner", "system-run"}, + { "Shutdown Dialog", I18N_NOOP2("plasma name", "Shutdown Dialog"), "dialogs/shutdowndialog", "system-shutdown"}, + { "Icons", I18N_NOOP2("plasma name", "Icons"), "icons/", "preferences-desktop-icons"}, + { 0, 0,0,0 } // end of data +}; + + +DesktopThemeDetails::DesktopThemeDetails(QWidget* parent) + : QWidget(parent), + m_themeModel(0) + +{ + setWindowIcon(KIcon("preferences-desktop")); + setupUi(this); + + QFont font = QFont(); + font.setBold(true); + font.setPointSize(1.2*font.pointSize()); + m_themeInfoName->setFont(font); + + m_enableAdvanced->setChecked(false); + toggleAdvancedVisible(); + + + m_themeModel = new ThemeModel(this); + m_theme->setModel(m_themeModel); + m_theme->setItemDelegate(new ThemeDelegate(m_theme)); + + reloadConfig(); + + connect(m_theme->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(themeSelectionChanged(QItemSelection,QItemSelection))); + + connect(m_enableAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleAdvancedVisible())); + connect(m_removeThemeButton, SIGNAL(clicked()), this, SLOT(removeTheme())); + connect(m_exportThemeButton, SIGNAL(clicked()), this, SLOT(exportTheme())); + + connect(m_newThemeName, SIGNAL(editingFinished()), this, SLOT(newThemeInfoChanged())); + + m_baseTheme = "default"; + m_themeCustomized = false; + resetThemeDetails(); + adjustSize(); +} + +DesktopThemeDetails::~DesktopThemeDetails() +{ + cleanup(); +} + +void DesktopThemeDetails::cleanup() +{ +} + +void DesktopThemeDetails::reloadConfig() +{ + // Theme + KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme"); + const QString theme = cfg.readEntry("name", "default"); + m_theme->setCurrentIndex(m_themeModel->indexOf(theme)); + +} + +void DesktopThemeDetails::save() +{ + QString themeRoot; + KStandardDirs dirs; + if (m_newThemeName->text().isEmpty()) { + themeRoot = ".customized"; + //Toggle customized theme directory name to ensure theme reload + if (QDir(dirs.locateLocal("data", "desktoptheme/" + themeRoot + '/', false)).exists()) { + themeRoot = themeRoot + '1'; + } + } else { + themeRoot = m_newThemeName->text().replace(' ',"_").remove(QRegExp("[^A-Za-z0-9_]")); + } + + //Save theme items + QFile customSettingsFile; + bool customSettingsFileOpen = false; + + if (m_themeCustomized || !m_newThemeName->text().isEmpty()) { + + clearCustomized(themeRoot); + + //Copy all files from the base theme + QString baseSource = dirs.locate("data", "desktoptheme/" + m_baseTheme + "/metadata.desktop"); + baseSource = baseSource.left(baseSource.lastIndexOf('/', -1)); + KIO::CopyJob *copyBaseTheme = KIO::copyAs(KUrl(baseSource), KUrl(dirs.locateLocal("data", "desktoptheme/" + themeRoot, true)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(copyBaseTheme, this); + + //Prepare settings file for customized theme + if (isCustomized(themeRoot)) { + customSettingsFile.setFileName(dirs.locateLocal("data", "desktoptheme/" + themeRoot + "/settings")); + customSettingsFileOpen = customSettingsFile.open(QFile::WriteOnly); + if (customSettingsFileOpen) { + QTextStream out(&customSettingsFile); + out << "baseTheme=" + m_baseTheme + "\r\n";; + } + } + QString settingsSource; + + //Copy each item theme file to new theme folder + QHashIterator i(m_itemThemeReplacements); + while (i.hasNext()) { + i.next(); + //Get root directory where item should reside (relative to theme root) + QString itemRoot = ""; + if (m_itemPaths[i.key()].lastIndexOf('/', -1) != -1) { + itemRoot= m_itemPaths[i.key()].left(m_itemPaths[i.key()].lastIndexOf('/', -1)); + } + //Setup source and destination + QString source; + QString dest; + if (i.value() != -1) { + //Source is a theme + source = "desktoptheme/" + m_themeRoots[i.value()] + '/' + m_itemPaths[i.key()] + '*'; + dest = "desktoptheme/" + themeRoot + '/' + itemRoot + '/'; + settingsSource = m_themeRoots[i.value()]; + } else { + //Source is a file + source = m_itemFileReplacements[i.key()]; + dest = "desktoptheme/" + themeRoot + '/' + itemRoot + '/'; + settingsSource = m_itemFileReplacements[i.key()]; + } + + + //Delete item files at destination before copying (possibly there from base theme copy) + const QStringList deleteFiles = dirs.findAllResources("data", "desktoptheme/" + themeRoot + '/' + m_itemPaths[i.key()] + '*', + KStandardDirs::NoDuplicates); + for (int j = 0; j < deleteFiles.size(); ++j) { + KIO::DeleteJob *dj = KIO::del(KUrl(deleteFiles.at(j)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(dj, this); + } + + //Copy item(s) + dest = dirs.locateLocal("data", dest, true); + QStringList copyFiles; + if (i.value() != -1) { + copyFiles = dirs.findAllResources("data", source, KStandardDirs::NoDuplicates); //copy from theme + } else { + copyFiles << source; //copy from file + } + for (int j = 0; j < copyFiles.size(); ++j) { + KIO::CopyJob *cj = KIO::copy(KUrl(copyFiles.at(j)), KUrl(dest), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(cj, this); + } + + //Record settings file + if (customSettingsFileOpen) { + QTextStream out(&customSettingsFile); + out << m_items.key(i.key()) + "=" + settingsSource +"\r\n"; + } + } + if (customSettingsFileOpen) customSettingsFile.close(); + + // Create new theme FDO desktop file + QFile::remove(dirs.locateLocal("data", "desktoptheme/" + themeRoot + "/metadata.desktop", false)); + KDesktopFile df(dirs.locateLocal("data", "desktoptheme/" + themeRoot + "/metadata.desktop")); + KConfigGroup cg = df.desktopGroup(); + if (isCustomized(themeRoot)) { + cg.writeEntry("Name",i18n("(Customized)")); + cg.writeEntry("Comment", i18n("User customized theme")); + cg.writeEntry("X-KDE-PluginInfo-Name", themeRoot); + } else { + cg.writeEntry("Name", m_newThemeName->text()); + cg.writeEntry("Comment", m_newThemeDescription->text()); + cg.writeEntry("X-KDE-PluginInfo-Author", m_newThemeAuthor->text()); + cg.writeEntry("X-KDE-PluginInfo-Version", m_newThemeVersion->text()); + } + cg.sync(); + + m_themeCustomized = false; + } + + m_themeModel->reload(); + if (m_themeModel->indexOf(themeRoot).isValid()) { + m_theme->setCurrentIndex(m_themeModel->indexOf(themeRoot)); + QString themeName = m_theme->currentIndex().data(Qt::DisplayRole).toString(); + setDesktopTheme(themeRoot); + } + resetThemeDetails(); +} + +void DesktopThemeDetails::removeTheme() +{ + bool removeTheme = true; + KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme"); + QString activeTheme = cfg.readEntry("name", "default"); + const QString theme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + const QString themeName = m_theme->currentIndex().data(Qt::DisplayRole).toString(); + + + if (m_themeCustomized) { + if(KMessageBox::questionYesNo(this, i18n("Theme items have been changed. Do you still wish remove the \"%1\" theme?", themeName), i18n("Remove Desktop Theme")) == KMessageBox::No) { + removeTheme = false; + } + } else { + if (theme == "default") { + KMessageBox::information(this, i18n("Removal of the default desktop theme is not allowed."), i18n("Remove Desktop Theme")); + removeTheme = false; + } else { + if(KMessageBox::questionYesNo(this, i18n("Are you sure you wish remove the \"%1\" theme?", themeName), i18n("Remove Desktop Theme")) == KMessageBox::No) { + removeTheme = false; + } + } + + } + KStandardDirs dirs; + if (removeTheme) { + if (theme == activeTheme) { + setDesktopTheme("default"); + activeTheme = "default"; + } + if (QDir(dirs.locateLocal("data", "desktoptheme/" + theme, false)).exists()) { + KIO::DeleteJob *deleteTheme = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/" + theme, false)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(deleteTheme, this); + } + } + m_themeModel->reload(); + reloadConfig(); + m_theme->setCurrentIndex(m_themeModel->indexOf(activeTheme)); +} + +void DesktopThemeDetails::exportTheme() +{ + const QString theme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + + if (m_themeCustomized || + (isCustomized(theme) && m_newThemeName->text() == "")) { + KMessageBox::information(this, i18n("Please apply theme item changes (with a new theme name) before attempting to export theme."), i18n("Export Desktop Theme")); + } else { + QString themeStoragePath = theme; + + KStandardDirs dirs; + const QString themePath = dirs.findResource("data", "desktoptheme/" + themeStoragePath + "/metadata.desktop"); + if (!themePath.isEmpty()){ + QString expFileName = KFileDialog::getSaveFileName(KUrl(), "*.zip", this, i18n("Export theme to file")); + if (!expFileName.endsWith(".zip")) + expFileName = expFileName + ".zip"; + if (!expFileName.isEmpty()) { + KUrl path(themePath); + KZip expFile(expFileName); + expFile.open(QIODevice::WriteOnly); + expFile.addLocalDirectory(path.directory (), themeStoragePath); + expFile.close(); + } + } + } + +} + +void DesktopThemeDetails::loadThemeItems() +{ + // Set up items, item paths and icons + m_items.clear(); // clear theme items + m_itemPaths.clear(); // clear theme item paths + m_itemIcons.clear(); + for (int i = 0; themeCollectionName[i].m_type; ++i) { + m_items[themeCollectionName[i].m_type] = i; + m_itemPaths[i] = themeCollectionName[i].m_themeItemPath; + m_itemIcons[i] = themeCollectionName[i].m_iconName; + } + + // Get installed themes + m_themes.clear(); // clear installed theme list + m_themeRoots.clear(); // clear installed theme root paths + KStandardDirs dirs; + QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop", + KStandardDirs::NoDuplicates); + themes.sort(); + int j=0; + for (int i = 0; i < themes.size(); ++i) { + QString theme = themes.at(i); + int themeSepIndex = theme.lastIndexOf('/', -1); + QString themeRoot = theme.left(themeSepIndex); + int themeNameSepIndex = themeRoot.lastIndexOf('/', -1); + QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1); + KDesktopFile df(theme); + QString name = df.readName(); + if (name.isEmpty()) { + name = packageName; + } + + if (!isCustomized(packageName) && (m_themeRoots.key(packageName, -1) == -1)) { + m_themes[name] = j; + m_themeRoots[j] = packageName; + ++j; + } + } + + // Set up default item replacements + m_itemThemeReplacements.clear(); + m_itemFileReplacements.clear(); + QString currentTheme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + + if (!isCustomized(currentTheme)) { + // Set default replacements to current theme + QHashIterator i(m_items); + while (i.hasNext()) { + i.next(); + m_itemThemeReplacements[i.value()] = m_themeRoots.key(currentTheme); + } + m_baseTheme = currentTheme; + } else { + // Set default replacements to customized theme settings + QFile customSettingsFile(dirs.locateLocal("data", "desktoptheme/" + currentTheme +"/settings")); + if (customSettingsFile.open(QFile::ReadOnly)) { + QTextStream in(&customSettingsFile); + QString line; + QStringList settingsPair; + while (!in.atEnd()) { + line = in.readLine(); + settingsPair = line.split('='); + if (settingsPair.at(0) == "baseTheme") { + m_baseTheme = settingsPair.at(1); + } else { + if (m_themeRoots.key(settingsPair.at(1), -1) != -1) { // theme for current item exists + m_itemThemeReplacements[m_items[settingsPair.at(0)]] = m_themeRoots.key(settingsPair.at(1)); + } else if (QFile::exists(settingsPair.at(1))) { + m_itemThemeReplacements[m_items[settingsPair.at(0)]] = -1; + m_itemFileReplacements[m_items[settingsPair.at(0)]] = settingsPair.at(1); + } + } + } + customSettingsFile.close(); + } + } + + // Build displayed list of theme items + m_themeItemList->setRowCount(m_items.size()); + m_themeItemList->setColumnCount(2); + m_themeItemList->setHorizontalHeaderLabels(QStringList()<< i18n("Theme Item")< i(m_items); + while (i.hasNext()) { + i.next(); + displayedItem = displayedItemText(i.value()); + m_themeItemList->setItem(i.value(), 0, new QTableWidgetItem(displayedItem)); + m_themeItemList->item(i.value(),0)->setIcon(KIcon(m_itemIcons[i.value()])); + m_themeItemList->setCellWidget(i.value(), 1, new QComboBox()); + updateReplaceItemList(i.value()); + m_themeItemList->resizeColumnToContents(1); + } + m_themeItemList->setSelectionBehavior(QAbstractItemView::SelectRows); + m_themeItemList->verticalHeader()->hide(); + m_themeItemList->horizontalHeader()->setStretchLastSection(true); + m_themeItemList->horizontalHeader()->setMinimumSectionSize(120); + m_themeItemList->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);; + m_themeItemList->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);; + m_themeItemList->setCurrentCell(0, 1); +} + +void DesktopThemeDetails::updateReplaceItemList(const int& item) +{ + QString currentTheme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + + + // Repopulate combobox droplist + QComboBox *itemComboBox = static_cast(m_themeItemList->cellWidget(item,1)); + disconnect(itemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged())); + itemComboBox->clear(); + for (int i = 0; i < m_themes.size(); ++i) { + QString displayedDropListItem = i18n("%1 %2", m_themes.key(i), displayedItemText(item)); + itemComboBox->addItem(displayedDropListItem); + } + itemComboBox->addItem(i18n("File...")); + + // Set combobox value to current replacement + if (m_itemThemeReplacements[item] != -1) { + itemComboBox->setCurrentIndex(m_itemThemeReplacements[item]); + } else { + itemComboBox->addItem(m_itemFileReplacements[item]); + itemComboBox->setCurrentIndex(itemComboBox->findText(m_itemFileReplacements[item])); + } + connect(itemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged())); +} + +void DesktopThemeDetails::replacementItemChanged() +{ + //Check items to see if theme has been customized + m_themeCustomized = true; + QHashIterator i(m_items); + while (i.hasNext()) { + i.next(); + QComboBox *itemComboBox = static_cast(m_themeItemList->cellWidget(i.value(), 1)); + int replacement = itemComboBox->currentIndex(); + if (replacement <= (m_themes.size() - 1)) { + // Item replacement source is a theme + m_itemThemeReplacements[i.value()] = itemComboBox->currentIndex(); + } else if (replacement > (m_themes.size() - 1)) { + // Item replacement source is a file + if (itemComboBox->currentText() == i18n("File...")) { + //Get the filename for the replacement item + QString translated_key = i18nc("plasma name", qPrintable( i.key() ) ); + QString fileReplacement = KFileDialog::getOpenFileName(KUrl(), QString(), this, i18n("Select File to Use for %1",translated_key)); + if (!fileReplacement.isEmpty()) { + m_itemFileReplacements[i.value()] = fileReplacement; + int index = itemComboBox->findText(fileReplacement); + if (index == -1) itemComboBox->addItem(fileReplacement); + disconnect(itemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged())); + itemComboBox->setCurrentIndex(itemComboBox->findText(fileReplacement)); + connect(itemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged())); + m_itemThemeReplacements[i.value()] = -1; //source is not a theme + m_itemFileReplacements[i.value()] = itemComboBox->currentText(); + } else { + // Reset combobox to previous value if no file is selected + if (m_itemThemeReplacements[i.value()] != -1) { + itemComboBox->setCurrentIndex(m_itemThemeReplacements[i.value()]); + } else { + itemComboBox->setCurrentIndex(itemComboBox->findText(m_itemFileReplacements[i.value()])); + } + m_themeCustomized = false; + } + } else { + m_itemThemeReplacements[i.value()] = -1; //source is not a theme + m_itemFileReplacements[i.value()] = itemComboBox->currentText(); + } + } + } + + if (m_themeCustomized) emit changed(); +} + +void DesktopThemeDetails::newThemeInfoChanged() +{ + emit changed(); +} + +void DesktopThemeDetails::resetThemeDetails() +{ + QString theme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + + m_themeInfoName->setText(m_theme->currentIndex().data(Qt::DisplayRole).toString()); + m_themeInfoDescription->setText(m_theme->currentIndex().data(ThemeModel::PackageDescriptionRole).toString()); + QString author = m_theme->currentIndex().data(ThemeModel::PackageAuthorRole).toString(); + + if (!author.isEmpty()) { + m_themeInfoAuthor->setText(i18n(" Author: %1",author)); + } else { + m_themeInfoAuthor->setText(""); + } + QString version = m_theme->currentIndex().data(ThemeModel::PackageVersionRole).toString(); + if (!version.isEmpty()) { + m_themeInfoVersion->setText(i18n("Version: %1",version)); + } else { + m_themeInfoVersion->setText(""); + } + + loadThemeItems(); + + m_newThemeName->clear(); + m_newThemeAuthor->clear(); + m_newThemeVersion->clear(); + m_newThemeDescription->clear(); + m_themeCustomized = false; + } + +void DesktopThemeDetails::toggleAdvancedVisible() +{ + m_newThemeNameLabel->setVisible(m_enableAdvanced->isChecked()); + m_newThemeName->setVisible(m_enableAdvanced->isChecked()); + m_newThemeAuthor->setVisible(m_enableAdvanced->isChecked()); + m_newThemeAuthorLabel->setVisible(m_enableAdvanced->isChecked()); + m_newThemeVersion->setVisible(m_enableAdvanced->isChecked()); + m_newThemeVersionLabel->setVisible(m_enableAdvanced->isChecked()); + m_newThemeDescriptionLabel->setVisible(m_enableAdvanced->isChecked()); + m_newThemeDescription->setVisible(m_enableAdvanced->isChecked()); + m_exportThemeButton->setVisible(m_enableAdvanced->isChecked()); + m_removeThemeButton->setVisible(m_enableAdvanced->isChecked()); + m_advancedLine->setVisible(m_enableAdvanced->isChecked()); +} + +bool DesktopThemeDetails::isCustomized(const QString& theme) { + if (theme == ".customized" || theme == ".customized1") { + return true; + } else { + return false; + } +} + +void DesktopThemeDetails::clearCustomized(const QString& themeRoot) { + KStandardDirs dirs; + + if ((isCustomized(themeRoot))) { + // Remove both possible unnamed customized directories + if (QDir(dirs.locateLocal("data", "desktoptheme/.customized", false)).exists()) { + KIO::DeleteJob *clearCustom = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized", false)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(clearCustom, this); + } + if (QDir(dirs.locateLocal("data", "desktoptheme/.customized1", false)).exists()) { + KIO::DeleteJob *clearCustom1 = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized1", false)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(clearCustom1, this); + } + } else { + if (QDir(dirs.locateLocal("data", "desktoptheme/" + themeRoot, false)).exists()) { + KIO::DeleteJob *clearCustom = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/" + themeRoot, false)), KIO::HideProgressInfo); + KIO::NetAccess::synchronousRun(clearCustom, this); + } + } +} + +QString DesktopThemeDetails::displayedItemText(int item) { + QString displayedText = m_items.key(item); + for (int i = 0; themeCollectionName[i].m_type; ++i) { + if (themeCollectionName[i].m_type == m_items.key(item)) { + displayedText = i18nc("plasma name", themeCollectionName[i].m_displayItemName); + } + } + return displayedText; +} + +void DesktopThemeDetails::themeSelectionChanged(const QItemSelection newSelection, const QItemSelection oldSelection) +{ + QString theme = m_theme->currentIndex().data(ThemeModel::PackageNameRole).toString(); + if (theme == "default") { + m_removeThemeButton->setEnabled(false); + } else { + m_removeThemeButton->setEnabled(true); + } + resetThemeDetails(); + Q_UNUSED(newSelection); + Q_UNUSED(oldSelection); +} + +void DesktopThemeDetails::setDesktopTheme(QString themeRoot) +{ + KConfig config(KStandardDirs::locate("config", "plasmarc")); + KConfigGroup cg = KConfigGroup(&config, "Theme"); + if (themeRoot == "default") { + cg.deleteEntry("name"); + } else { + cg.writeEntry("name", themeRoot); + } + cg.sync(); +} diff --git a/kcontrol/desktoptheme/desktopthemedetails.h b/kcontrol/desktoptheme/desktopthemedetails.h new file mode 100644 index 00000000..241ea029 --- /dev/null +++ b/kcontrol/desktoptheme/desktopthemedetails.h @@ -0,0 +1,68 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2008 by Petri Damsten + + 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. +*/ + +#ifndef DESKTOPTHEMEDETAILS_H +#define DESKTOPTHEMEDETAILS_H + +#include "ui_DesktopThemeDetails.h" + +#include + +class ThemeModel; + +class DesktopThemeDetails : public QWidget, public Ui::DesktopThemeItems +{ + Q_OBJECT +public: + DesktopThemeDetails(QWidget* parent); + ~DesktopThemeDetails(); + + void reloadConfig(); + +public slots: + void replacementItemChanged(); + void resetThemeDetails(); + void toggleAdvancedVisible(); + void save(); + void removeTheme(); + void exportTheme(); + void newThemeInfoChanged(); + +Q_SIGNALS: + void changed(); + +private: + void updateReplaceItemList(const int& item); + void loadThemeItems(); + QString displayedItemText(int item); + bool isCustomized(const QString& theme); + void clearCustomized(const QString& themeRoot); + void setDesktopTheme(QString themeRoot); + +private slots: + void cleanup(); + void themeSelectionChanged(const QItemSelection newSelection, const QItemSelection oldSelection); + +private: + ThemeModel* m_themeModel; + + QHash m_items; // theme items + QHash m_itemPaths; // theme item paths + QHash m_itemIcons; //theme item icons + QHash m_themes; // installed themes + QHash m_themeRoots; // installed themes root paths + QHash m_itemThemeReplacements; // source theme for item replacements + QHashm_itemFileReplacements; //non-theme source files for item replacements + + bool m_themeCustomized; + QString m_baseTheme; +}; + +#endif // DESKTOPTHEMEDETAILS_H diff --git a/kcontrol/desktoptheme/kcmdesktoptheme.cpp b/kcontrol/desktoptheme/kcmdesktoptheme.cpp new file mode 100644 index 00000000..9657fe59 --- /dev/null +++ b/kcontrol/desktoptheme/kcmdesktoptheme.cpp @@ -0,0 +1,183 @@ +/* + * KCMDesktopTheme + * Copyright (C) 2002 Karol Szwed + * Copyright (C) 2002 Daniel Molkentin + * Copyright (C) 2007 Urs Wolfer + * Copyright (C) 2009 by Davide Bettio + + * Portions Copyright (C) 2007 Paolo Capriotti + * Portions Copyright (C) 2007 Ivan Cukic + * Portions Copyright (C) 2008 by Petri Damsten + * Portions Copyright (C) 2000 TrollTech AS. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 "kcmdesktoptheme.h" + +#include "thememodel.h" + + +#include +#include +#include +#include + +#include + +/**** DLL Interface for kcontrol ****/ + +#include +#include + +K_PLUGIN_FACTORY(KCMDesktopThemeFactory, registerPlugin();) +K_EXPORT_PLUGIN(KCMDesktopThemeFactory("kcmdesktoptheme","kcm_desktopthemedetails")) + + +KCMDesktopTheme::KCMDesktopTheme( QWidget* parent, const QVariantList& ) + : KCModule( KCMDesktopThemeFactory::componentData(), parent ) +{ + setQuickHelp( i18n("

    Desktop Theme

    " + "This module allows you to modify the visual appearance " + "of the desktop.")); + + setupUi(this); + + m_bDesktopThemeDirty = false; + m_bDetailsDirty = false; + + KAutostart plasmaNetbookAutoStart("plasma-netbook"); + m_isNetbook = plasmaNetbookAutoStart.autostarts(); + + KGlobal::dirs()->addResourceType("themes", "data", "kstyle/themes"); + + KAboutData *about = + new KAboutData( I18N_NOOP("KCMDesktopTheme"), 0, + ki18n("KDE Desktop Theme Module"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 2002 Karol Szwed, Daniel Molkentin")); + + about->addAuthor(ki18n("Karol Szwed"), KLocalizedString(), "gallium@kde.org"); + about->addAuthor(ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org"); + about->addAuthor(ki18n("Ralf Nolden"), KLocalizedString(), "nolden@kde.org"); + setAboutData( about ); + + m_newThemeButton->setIcon(KIcon("get-hot-new-stuff")); + + m_themeModel = new ThemeModel(this); + m_theme->setModel(m_themeModel); + m_theme->setItemDelegate(new ThemeDelegate(m_theme)); + m_theme->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + connect(m_detailsWidget, SIGNAL(changed()), this, SLOT(detailChanged())); + + connect(m_theme->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(setDesktopThemeDirty())); + connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes())); +} + + +KCMDesktopTheme::~KCMDesktopTheme() +{ +} + +void KCMDesktopTheme::load() +{ + KConfig config( "kdeglobals", KConfig::FullConfig ); + + loadDesktopTheme(); + + m_bDesktopThemeDirty = false; + m_bDetailsDirty = false; + + emit changed( false ); +} + + +void KCMDesktopTheme::save() +{ + // Don't do anything if we don't need to. + if ( !( m_bDesktopThemeDirty) && !(m_bDetailsDirty) ) + return; + + //Desktop theme + if ( m_bDesktopThemeDirty ) + { + QString theme = m_themeModel->data(m_theme->currentIndex(), ThemeModel::PackageNameRole).toString(); + if (m_isNetbook) { + KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-netbook"); + cg.writeEntry("name", theme); + } else { + Plasma::Theme::defaultTheme()->setThemeName(theme); + } + } + + if (m_bDetailsDirty) + { + m_detailsWidget->save(); + } + + // Clean up + m_bDesktopThemeDirty = false; + m_bDetailsDirty = false; + emit changed( false ); +} + +void KCMDesktopTheme::defaults() +{ + // TODO: reset back to default theme? +} + +void KCMDesktopTheme::setDesktopThemeDirty() +{ + m_bDesktopThemeDirty = true; + emit changed(true); +} + +void KCMDesktopTheme::getNewThemes() +{ + KNS3::DownloadDialog dialog("plasma-themes.knsrc", this); + dialog.exec(); + KNS3::Entry::List entries = dialog.changedEntries(); + + if (entries.size() > 0) { + loadDesktopTheme(); + } +} + +void KCMDesktopTheme::loadDesktopTheme() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + m_themeModel->reload(); + QString themeName; + if (m_isNetbook) { + KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-netbook"); + themeName = cg.readEntry("name", "air-netbook"); + } else { + themeName = Plasma::Theme::defaultTheme()->themeName(); + } + m_theme->setCurrentIndex(m_themeModel->indexOf(themeName)); + QApplication::restoreOverrideCursor(); +} + +void KCMDesktopTheme::detailChanged() +{ + m_bDetailsDirty = true; + emit changed(true); +} + +#include "kcmdesktoptheme.moc" + +// vim: set noet ts=4: diff --git a/kcontrol/desktoptheme/kcmdesktoptheme.h b/kcontrol/desktoptheme/kcmdesktoptheme.h new file mode 100644 index 00000000..873eac79 --- /dev/null +++ b/kcontrol/desktoptheme/kcmdesktoptheme.h @@ -0,0 +1,71 @@ +/* + * KCMDesktopTheme + * Copyright (C) 2002 Karol Szwed + * Copyright (C) 2002 Daniel Molkentin + * Copyright (C) 2007 Urs Wolfer + * + * Portions Copyright (C) TrollTech AS. + * + * Based on kcmstyle which is based on kcmdisplay + * Copyright (C) 1997-2002 kcmdisplay Authors. + * (see Help -> About Style Settings) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 KCMDESKTOPTHEME_H +#define KCMDESKTOPTHEME_H + +#include + +#include "ui_DesktopTheme.h" + +class ThemeModel; + +class KCMDesktopTheme : public KCModule, public Ui::DesktopTheme +{ + Q_OBJECT + +public: + KCMDesktopTheme( QWidget* parent, const QVariantList& ); + ~KCMDesktopTheme(); + + virtual void load(); + virtual void save(); + virtual void defaults(); + +protected Q_SLOTS: + void loadDesktopTheme(); + + void setDesktopThemeDirty(); + + void getNewThemes(); + + void detailChanged(); +private: + static QString toolbarButtonText(int index); + static int toolbarButtonIndex(const QString &text); + + bool m_bDesktopThemeDirty; + bool m_bDetailsDirty; + + ThemeModel* m_themeModel; + + bool m_isNetbook; +}; + +#endif // KCMDESKTOPTHEME_H + +// vim: set noet ts=4: diff --git a/kcontrol/desktoptheme/thememodel.cpp b/kcontrol/desktoptheme/thememodel.cpp new file mode 100644 index 00000000..4d679149 --- /dev/null +++ b/kcontrol/desktoptheme/thememodel.cpp @@ -0,0 +1,209 @@ +/* + * ThemeModel + * Copyright (C) 2002 Karol Szwed + * Copyright (C) 2002 Daniel Molkentin + * Copyright (C) 2007 Urs Wolfer + * Copyright (C) 2009 by Davide Bettio + + * Portions Copyright (C) 2007 Paolo Capriotti + * Portions Copyright (C) 2007 Ivan Cukic + * Portions Copyright (C) 2008 by Petri Damsten + * Portions Copyright (C) 2000 TrollTech AS. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 "thememodel.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include + +ThemeModel::ThemeModel( QObject *parent ) +: QAbstractListModel( parent ) +{ + reload(); +} + +ThemeModel::~ThemeModel() +{ + clearThemeList(); +} + +void ThemeModel::clearThemeList() +{ + foreach (const ThemeInfo& themeInfo, m_themes) { + delete themeInfo.svg; + } + m_themes.clear(); +} + +void ThemeModel::reload() +{ + reset(); + clearThemeList(); + + // get all desktop themes + KStandardDirs dirs; + const QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop", + KStandardDirs::NoDuplicates); + foreach (const QString &theme, themes) { + int themeSepIndex = theme.lastIndexOf('/', -1); + QString themeRoot = theme.left(themeSepIndex); + int themeNameSepIndex = themeRoot.lastIndexOf('/', -1); + QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1); + + KDesktopFile df(theme); + + if (df.noDisplay()) { + continue; + } + + QString name = df.readName(); + if (name.isEmpty()) { + name = packageName; + } + const QString comment = df.readComment(); + const QString author = df.desktopGroup().readEntry("X-KDE-PluginInfo-Author",QString()); + const QString version = df.desktopGroup().readEntry("X-KDE-PluginInfo-Version",QString()); + + + Plasma::FrameSvg *svg = new Plasma::FrameSvg(this); + const QString svgFile = themeRoot + "/widgets/background.svg"; + if (QFile::exists(svgFile)) { + svg->setImagePath(svgFile); + } else { + svg->setImagePath(svgFile + "z"); + } + svg->setEnabledBorders(Plasma::FrameSvg::AllBorders); + ThemeInfo info; + info.package = packageName; + info.description = comment; + info.author = author; + info.version = version; + info.svg = svg; + info.themeRoot = themeRoot; + m_themes[name] = info; + } + + beginInsertRows(QModelIndex(), 0, m_themes.size()); + endInsertRows(); +} + +int ThemeModel::rowCount(const QModelIndex &) const +{ + return m_themes.size(); +} + +QVariant ThemeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= m_themes.size()) { + return QVariant(); + } + + QMap::const_iterator it = m_themes.constBegin(); + for (int i = 0; i < index.row(); ++i) { + ++it; + } + + switch (role) { + case Qt::DisplayRole: + return it.key(); + case PackageNameRole: + return (*it).package; + case SvgRole: + return qVariantFromValue((void*)(*it).svg); + case PackageDescriptionRole: + return (*it).description; + case PackageAuthorRole: + return (*it).author; + case PackageVersionRole: + return (*it).version; + default: + return QVariant(); + } +} + +QModelIndex ThemeModel::indexOf(const QString &name) const +{ + QMapIterator it(m_themes); + int i = -1; + while (it.hasNext()) { + ++i; + if (it.next().value().package == name) { + return index(i, 0); + } + } + + return QModelIndex(); +} + +ThemeDelegate::ThemeDelegate(QObject* parent) +: QAbstractItemDelegate(parent) +{ +} + +void ThemeDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString title = index.model()->data(index, Qt::DisplayRole).toString(); + QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString(); + + QStyleOptionViewItemV4 opt(option); + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + + // draw image + Plasma::FrameSvg *svg = static_cast( + index.model()->data(index, ThemeModel::SvgRole).value()); + svg->resizeFrame(QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN))); + QRect imgRect = QRect(option.rect.topLeft(), + QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN))) + .translated(MARGIN, MARGIN); + svg->paintFrame(painter, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN)); + + // draw text + painter->save(); + QFont font = painter->font(); + font.setWeight(QFont::Bold); + const QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors"); + if (!colorFile.isEmpty()) { + KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile); + KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors); + painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color()); + } + painter->setFont(font); + painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title); + painter->restore(); +} + +QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const +{ + return QSize(152, 100); +} + + diff --git a/kcontrol/desktoptheme/thememodel.h b/kcontrol/desktoptheme/thememodel.h new file mode 100644 index 00000000..0dfc5051 --- /dev/null +++ b/kcontrol/desktoptheme/thememodel.h @@ -0,0 +1,87 @@ +/* + * ThemeModel + * Copyright (C) 2002 Karol Szwed + * Copyright (C) 2002 Daniel Molkentin + * Copyright (C) 2007 Urs Wolfer + * Copyright (C) 2009 by Davide Bettio + + * Portions Copyright (C) 2007 Paolo Capriotti + * Portions Copyright (C) 2007 Ivan Cukic + * Portions Copyright (C) 2008 by Petri Damsten + * Portions Copyright (C) 2000 TrollTech AS. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 THEMEMODEL_H +#define THEMEMODEL_H + +#include + +namespace Plasma +{ + class FrameSvg; +} + +//Theme selector code by Andre Duffeck (modified to add package description) +class ThemeInfo +{ +public: + QString package; + Plasma::FrameSvg *svg; + QString description; + QString author; + QString version; + QString themeRoot; +}; + +class ThemeModel : public QAbstractListModel +{ +public: + enum { PackageNameRole = Qt::UserRole, + SvgRole = Qt::UserRole + 1, + PackageDescriptionRole = Qt::UserRole + 2, + PackageAuthorRole = Qt::UserRole + 3, + PackageVersionRole = Qt::UserRole + 4 + }; + + ThemeModel(QObject *parent = 0); + virtual ~ThemeModel(); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QModelIndex indexOf(const QString &path) const; + void reload(); + void clearThemeList(); +private: + QMap m_themes; +}; + +class ThemeDelegate : public QAbstractItemDelegate +{ +public: + ThemeDelegate(QObject * parent = 0); + + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; +private: + static const int MARGIN = 10; +}; + + +#endif diff --git a/kcontrol/fonts/CMakeLists.txt b/kcontrol/fonts/CMakeLists.txt new file mode 100644 index 00000000..9aabb974 --- /dev/null +++ b/kcontrol/fonts/CMakeLists.txt @@ -0,0 +1,35 @@ + +KDE4_NO_ENABLE_FINAL(fonts) + +if(FONTCONFIG_FOUND) + include_directories(${FONTCONFIG_INCLUDE_DIR}) +endif(FONTCONFIG_FOUND) +include_directories(${FREETYPE_INCLUDE_DIRS}) + +########### next target ############### + +set(kcm_fonts_PART_SRCS ../krdb/krdb.cpp fonts.cpp) + +if(Q_WS_X11) + set(kcm_fonts_PART_SRCS ${kcm_fonts_PART_SRCS} ${libkxftconfig_SRCS}) +endif(Q_WS_X11) + +kde4_add_plugin(kcm_fonts ${kcm_fonts_PART_SRCS}) + + +target_link_libraries(kcm_fonts ${KDE4_KDEUI_LIBS} ${FREETYPE_LIBRARIES} ${QT_QTXML_LIBRARY}) + +if(Q_WS_X11) + if(FONTCONFIG_FOUND) + target_link_libraries(kcm_fonts ${FONTCONFIG_LIBRARIES}) + endif(FONTCONFIG_FOUND) + + target_link_libraries(kcm_fonts ${X11_LIBRARIES}) +endif(Q_WS_X11) + +install(TARGETS kcm_fonts DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES fonts.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcontrol/fonts/Messages.sh b/kcontrol/fonts/Messages.sh new file mode 100644 index 00000000..c49832c6 --- /dev/null +++ b/kcontrol/fonts/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/kcmfonts.pot diff --git a/kcontrol/fonts/fonts.cpp b/kcontrol/fonts/fonts.cpp new file mode 100644 index 00000000..67eccd47 --- /dev/null +++ b/kcontrol/fonts/fonts.cpp @@ -0,0 +1,851 @@ +// KDE Display fonts setup tab +// +// Copyright (c) Mark Donohoe 1997 +// lars Knoll 1999 +// Rik Hemsley 2000 +// +// Ported to kcontrol2 by Geert Jansen. + +#include + +#include "fonts.h" +#include "fonts.moc" + +#include + +#include +#include +#include +#include +#include +#include + +//Added by qt3to4: +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../krdb/krdb.h" + +#ifdef HAVE_FREETYPE +#include +#ifdef FT_LCD_FILTER_H +#include FT_FREETYPE_H +#include FT_LCD_FILTER_H +#endif +#endif + +#ifdef Q_WS_X11 +#include +#endif + +#ifdef Q_WS_X11 +// X11 headers +#undef Bool +#undef Unsorted +#undef None +#endif + +static const char * const aa_rgb_xpm[]={ +"12 12 3 1", +"a c #0000ff", +"# c #00ff00", +". c #ff0000", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa"}; +static const char * const aa_bgr_xpm[]={ +"12 12 3 1", +". c #0000ff", +"# c #00ff00", +"a c #ff0000", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa"}; +static const char * const aa_vrgb_xpm[]={ +"12 12 3 1", +"a c #0000ff", +"# c #00ff00", +". c #ff0000", +"............", +"............", +"............", +"............", +"############", +"############", +"############", +"############", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa"}; +static const char * const aa_vbgr_xpm[]={ +"12 12 3 1", +". c #0000ff", +"# c #00ff00", +"a c #ff0000", +"............", +"............", +"............", +"............", +"############", +"############", +"############", +"############", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa"}; + +static const char* const * const aaPixmaps[]={ aa_rgb_xpm, aa_bgr_xpm, aa_vrgb_xpm, aa_vbgr_xpm }; + +/**** DLL Interface ****/ +K_PLUGIN_FACTORY(FontFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(FontFactory("kcmfonts")) + +/**** FontUseItem ****/ + +FontUseItem::FontUseItem( + QWidget * parent, + const QString &name, + const QString &grp, + const QString &key, + const QString &rc, + const QFont &default_fnt, + bool f +) + : KFontRequester(parent, f), + _rcfile(rc), + _rcgroup(grp), + _rckey(key), + _default(default_fnt) +{ + KAcceleratorManager::setNoAccel( this ); + setTitle( name ); + readFont(); +} + +void FontUseItem::setDefault() +{ + setFont( _default, isFixedOnly() ); +} + +void FontUseItem::readFont() +{ + KConfig *config; + + bool deleteme = false; + if (_rcfile.isEmpty()) + config = KGlobal::config().data(); + else + { + config = new KConfig(_rcfile); + deleteme = true; + } + + KConfigGroup group(config, _rcgroup); + QFont tmpFnt(_default); + setFont( group.readEntry(_rckey, tmpFnt), isFixedOnly() ); + if (deleteme) delete config; +} + +void FontUseItem::writeFont() +{ + KConfig *config; + + if (_rcfile.isEmpty()) { + config = KGlobal::config().data(); + KConfigGroup(config, _rcgroup).writeEntry(_rckey, font(), KConfig::Normal|KConfig::Global); + } else { + config = new KConfig(KStandardDirs::locateLocal("config", _rcfile)); + KConfigGroup(config, _rcgroup).writeEntry(_rckey, font()); + config->sync(); + delete config; + } +} + +void FontUseItem::applyFontDiff( const QFont &fnt, int fontDiffFlags ) +{ + QFont _font( font() ); + + if (fontDiffFlags & KFontChooser::FontDiffSize) { + _font.setPointSizeF( fnt.pointSizeF() ); + } + if (fontDiffFlags & KFontChooser::FontDiffFamily) { + if (!isFixedOnly() || QFontInfo(fnt).fixedPitch()) _font.setFamily( fnt.family() ); + } + if (fontDiffFlags & KFontChooser::FontDiffStyle) { + _font.setWeight( fnt.weight() ); + _font.setStyle( fnt.style() ); + _font.setUnderline( fnt.underline() ); +#if QT_VERSION >= 0x040800 + _font.setStyleName( fnt.styleName() ); +#endif + } + + setFont( _font, isFixedOnly() ); +} + +/**** FontAASettings ****/ +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) +FontAASettings::FontAASettings(QWidget *parent) + : KDialog( parent ), + changesMade(false) +{ + setObjectName( "FontAASettings" ); + setModal( true ); + setCaption( i18n("Configure Anti-Alias Settings") ); + setButtons( Ok|Cancel ); + + QWidget *mw=new QWidget(this); + QFormLayout *layout=new QFormLayout(mw); + layout->setMargin(0); + + excludeRange=new QCheckBox(i18n("E&xclude range:"), mw); + QHBoxLayout *rangeLayout = new QHBoxLayout(); + excludeFrom=new KDoubleNumInput(0, 72, 8.0, mw, 1, 1); + excludeFrom->setSuffix(i18n(" pt")); + rangeLayout->addWidget(excludeFrom); + excludeToLabel=new QLabel(i18n(" to "), mw); + rangeLayout->addWidget(excludeToLabel); + excludeTo=new KDoubleNumInput(0, 72, 15.0, mw, 1, 1); + excludeTo->setSuffix(i18n(" pt")); + rangeLayout->addWidget(excludeTo); + layout->addRow(excludeRange, rangeLayout); + + QString subPixelWhatsThis = i18n("

    If you have a TFT or LCD screen you" + " can further improve the quality of displayed fonts by selecting" + " this option.
    Sub-pixel rendering is also known as ClearType(tm).
    " + " In order for sub-pixel rendering to" + " work correctly you need to know how the sub-pixels of your display" + " are aligned.

    " + "

    On TFT or LCD displays a single pixel is actually composed of" + " three sub-pixels, red, green and blue. Most displays" + " have a linear ordering of RGB sub-pixel, some have BGR.
    " + " This feature does not work with CRT monitors.

    " ); + + useSubPixel=new QCheckBox(i18n("&Use sub-pixel rendering:"), mw); + useSubPixel->setWhatsThis( subPixelWhatsThis ); + + subPixelType=new QComboBox(mw); + layout->addRow(useSubPixel, subPixelType); + + subPixelType->setEditable(false); + subPixelType->setWhatsThis( subPixelWhatsThis ); + + for(int t=KXftConfig::SubPixel::None+1; t<=KXftConfig::SubPixel::Vbgr; ++t) + subPixelType->addItem(QPixmap(aaPixmaps[t-1]), i18n(KXftConfig::description((KXftConfig::SubPixel::Type)t).toUtf8())); + + QLabel *hintingLabel=new QLabel(i18n("Hinting style: "), mw); + hintingStyle=new QComboBox(mw); + hintingStyle->setEditable(false); + layout->addRow(hintingLabel, hintingStyle); + for(int s=KXftConfig::Hint::NotSet+1; s<=KXftConfig::Hint::Full; ++s) + hintingStyle->addItem(i18n(KXftConfig::description((KXftConfig::Hint::Style)s).toUtf8())); + + QString hintingText(i18n("Hinting is a process used to enhance the quality of fonts at small sizes.")); + hintingStyle->setWhatsThis( hintingText); + hintingLabel->setWhatsThis( hintingText); + load(); + enableWidgets(); + setMainWidget(mw); + + connect(excludeRange, SIGNAL(toggled(bool)), SLOT(changed())); + connect(useSubPixel, SIGNAL(toggled(bool)), SLOT(changed())); + connect(excludeFrom, SIGNAL(valueChanged(double)), SLOT(changed())); + connect(excludeTo, SIGNAL(valueChanged(double)), SLOT(changed())); + connect(subPixelType, SIGNAL(activated(QString)), SLOT(changed())); + connect(hintingStyle, SIGNAL(activated(QString)), SLOT(changed())); +} + +bool FontAASettings::load() +{ + double from, to; + KXftConfig xft; + + if(xft.getExcludeRange(from, to)) + excludeRange->setChecked(true); + else + { + excludeRange->setChecked(false); + from=8.0; + to=15.0; + } + + excludeFrom->setValue(from); + excludeTo->setValue(to); + + KXftConfig::SubPixel::Type spType; + + if(!xft.getSubPixelType(spType) || KXftConfig::SubPixel::None==spType) + useSubPixel->setChecked(false); + else + { + int idx=getIndex(spType); + + if(idx>-1) + { + useSubPixel->setChecked(true); + subPixelType->setCurrentIndex(idx); + } + else + useSubPixel->setChecked(false); + } + + KXftConfig::Hint::Style hStyle; + + if(!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet==hStyle) + { + KConfig kglobals("kdeglobals", KConfig::NoGlobals); + + hStyle=KXftConfig::Hint::Medium; + xft.setHintStyle(hStyle); + xft.apply(); // Save this setting + KConfigGroup(&kglobals, "General").writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); + kglobals.sync(); + runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); + } + + hintingStyle->setCurrentIndex(getIndex(hStyle)); + + enableWidgets(); + + return xft.getAntiAliasing(); +} + +bool FontAASettings::save( bool useAA ) +{ + KXftConfig xft; + KConfig kglobals("kdeglobals", KConfig::NoGlobals); + KConfigGroup grp(&kglobals, "General"); + + xft.setAntiAliasing( useAA ); + + if(excludeRange->isChecked()) + xft.setExcludeRange(excludeFrom->value(), excludeTo->value()); + else + xft.setExcludeRange(0, 0); + + KXftConfig::SubPixel::Type spType(useSubPixel->isChecked() + ? getSubPixelType() + : KXftConfig::SubPixel::None); + + xft.setSubPixelType(spType); + grp.writeEntry("XftSubPixel", KXftConfig::toStr(spType)); + grp.writeEntry("XftAntialias", useAA); + + bool mod=false; + KXftConfig::Hint::Style hStyle(getHintStyle()); + + xft.setHintStyle(hStyle); + + QString hs(KXftConfig::toStr(hStyle)); + + if(!hs.isEmpty() && hs!=grp.readEntry("XftHintStyle")) + { + grp.writeEntry("XftHintStyle", hs); + mod=true; + } + kglobals.sync(); + + if(!mod) + mod=xft.changed(); + + xft.apply(); + + return mod; +} + +void FontAASettings::defaults() +{ + excludeRange->setChecked(false); + excludeFrom->setValue(8.0); + excludeTo->setValue(15.0); + useSubPixel->setChecked(false); + hintingStyle->setCurrentIndex(getIndex(KXftConfig::Hint::Medium)); + enableWidgets(); +} + +int FontAASettings::getIndex(KXftConfig::SubPixel::Type spType) +{ + int pos=-1; + int index; + + for(index=0; indexcount(); ++index) + if(subPixelType->itemText(index)==i18n(KXftConfig::description(spType).toUtf8())) + { + pos=index; + break; + } + + return pos; +} + +KXftConfig::SubPixel::Type FontAASettings::getSubPixelType() +{ + int t; + + for(t=KXftConfig::SubPixel::None; t<=KXftConfig::SubPixel::Vbgr; ++t) + if(subPixelType->currentText()==i18n(KXftConfig::description((KXftConfig::SubPixel::Type)t).toUtf8())) + return (KXftConfig::SubPixel::Type)t; + + return KXftConfig::SubPixel::None; +} + +int FontAASettings::getIndex(KXftConfig::Hint::Style hStyle) +{ + int pos=-1; + int index; + + for(index=0; indexcount(); ++index) + if(hintingStyle->itemText(index)==i18n(KXftConfig::description(hStyle).toUtf8())) + { + pos=index; + break; + } + + return pos; +} + + +KXftConfig::Hint::Style FontAASettings::getHintStyle() +{ + int s; + + for(s=KXftConfig::Hint::NotSet; s<=KXftConfig::Hint::Full; ++s) + if(hintingStyle->currentText()==i18n(KXftConfig::description((KXftConfig::Hint::Style)s).toUtf8())) + return (KXftConfig::Hint::Style)s; + + return KXftConfig::Hint::Medium; +} + +void FontAASettings::enableWidgets() +{ + excludeFrom->setEnabled(excludeRange->isChecked()); + excludeTo->setEnabled(excludeRange->isChecked()); + excludeToLabel->setEnabled(excludeRange->isChecked()); + subPixelType->setEnabled(useSubPixel->isChecked()); +#ifdef FT_LCD_FILTER_H + static int ft_has_subpixel = -1; + if( ft_has_subpixel == -1 ) { + FT_Library ftLibrary; + if(FT_Init_FreeType(&ftLibrary) == 0) { + ft_has_subpixel = ( FT_Library_SetLcdFilter(ftLibrary, FT_LCD_FILTER_DEFAULT ) + == FT_Err_Unimplemented_Feature ) ? 0 : 1; + FT_Done_FreeType(ftLibrary); + } + } + useSubPixel->setEnabled(ft_has_subpixel); + subPixelType->setEnabled(ft_has_subpixel); +#endif +} +#endif + +void FontAASettings::changed() +{ +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + changesMade=true; + enableWidgets(); +#endif +} + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) +int FontAASettings::exec() +{ + int i=KDialog::exec(); + + if(!i) + load(); // Reset settings... + + return i && changesMade; +} +#endif + +/**** KFonts ****/ + +KFonts::KFonts(QWidget *parent, const QVariantList &args) + : KCModule(FontFactory::componentData(), parent, args) +{ + QStringList nameGroupKeyRc; + + nameGroupKeyRc + << i18nc("font usage", "General") << "General" << "font" << "" + << i18nc("font usage", "Fixed width") << "General" << "fixed" << "" + << i18nc("font usage", "Small") << "General" << "smallestReadableFont" << "" + << i18nc("font usage", "Toolbar") << "General" << "toolBarFont" << "" + << i18nc("font usage", "Menu") << "General" << "menuFont" << "" + << i18nc("font usage", "Window title") << "WM" << "activeFont" << "" + << i18nc("font usage", "Taskbar") << "General" << "taskbarFont" << "" + << i18nc("font usage", "Desktop") << "General" << "desktopFont" << ""; + + QList defaultFontList; + + // NOTE: keep in sync with kdelibs/kdeui/kernel/kglobalsettings.cpp + +#ifdef Q_WS_MAC + QFont f0("Lucida Grande", 13); // general/menu/desktop + QFont f1("Monaco", 10); + QFont f2("Lucida Grande", 11); // toolbar +#elif defined(Q_WS_MAEMO_5) || defined(MEEGO_EDITION_HARMATTAN) + QFont f0("Sans Serif", 16); // general/menu/desktop + QFont f1("Monospace", 16; + QFont f2("Sans Serif", 16); // toolbar +#else + QFont f0("Sans Serif", 9); // general/menu/desktop + QFont f1("Monospace", 9); + QFont f2("Sans Serif", 8); // toolbar +#endif + QFont f3("Sans Serif", 8); // window title + QFont f4("Sans Serif", 9); // taskbar + QFont f5("Sans Serif", 8); // smallestReadableFont + + defaultFontList << f0 << f1 << f5 << f2 << f0 << f3 << f4 << f0; + + QList fixedList; + + fixedList + << false + << true + << false + << false + << false + << false + << false + << false; + + QStringList quickHelpList; + + quickHelpList + << i18n("Used for normal text (e.g. button labels, list items).") + << i18n("A non-proportional font (i.e. typewriter font).") + << i18n("Smallest font that is still readable well.") + << i18n("Used to display text beside toolbar icons.") + << i18n("Used by menu bars and popup menus.") + << i18n("Used by the window titlebar.") + << i18n("Used by the taskbar.") + << i18n("Used for desktop icons."); + + QVBoxLayout * layout = new QVBoxLayout(this ); + layout->setMargin(0); + + QGridLayout * fontUseLayout = new QGridLayout( ); + layout->addLayout( fontUseLayout ); + fontUseLayout->setColumnStretch(0, 0); + fontUseLayout->setColumnStretch(1, 1); + fontUseLayout->setColumnStretch(2, 0); + + QList::ConstIterator defaultFontIt(defaultFontList.begin()); + QList::ConstIterator fixedListIt(fixedList.begin()); + QStringList::ConstIterator quickHelpIt(quickHelpList.begin()); + QStringList::ConstIterator it(nameGroupKeyRc.begin()); + + unsigned int count = 0; + + while (it != nameGroupKeyRc.constEnd()) { + + QString name = *it; it++; + QString group = *it; it++; + QString key = *it; it++; + QString file = *it; it++; + + FontUseItem * i = + new FontUseItem( + this, + name, + group, + key, + file, + *defaultFontIt++, + *fixedListIt++ + ); + + fontUseList.append(i); + connect(i, SIGNAL(fontSelected(QFont)), SLOT(fontSelected())); + + QLabel * fontUse = new QLabel(i18nc("Font role", "%1: ", name), this); + fontUse->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + fontUse->setWhatsThis( *quickHelpIt++); + + fontUseLayout->addWidget(fontUse, count, 0); + fontUseLayout->addWidget(i, count, 1); + + ++count; + } + + QHBoxLayout *hblay = new QHBoxLayout(); + layout->addLayout(hblay); + hblay->addStretch(); + QPushButton * fontAdjustButton = new QPushButton(i18n("Ad&just All Fonts..."), this); + fontAdjustButton->setWhatsThis( i18n("Click to change all fonts")); + hblay->addWidget( fontAdjustButton ); + connect(fontAdjustButton, SIGNAL(clicked()), SLOT(slotApplyFontDiff())); + + layout->addSpacing(KDialog::spacingHint()); + + QGridLayout* lay = new QGridLayout(); + layout->addLayout(lay); + lay->setColumnStretch( 3, 10 ); +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + QLabel* label=0L; + label = new QLabel( i18n( "Use a&nti-aliasing:" ), this ); + label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + lay->addWidget( label, 0, 0 ); + cbAA = new QComboBox( this ); + cbAA->insertItem( AAEnabled, i18nc( "Use anti-aliasing", "Enabled" )); // change AASetting type if order changes + cbAA->insertItem( AASystem, i18nc( "Use anti-aliasing", "System Settings" )); + cbAA->insertItem( AADisabled, i18nc( "Use anti-aliasing", "Disabled" )); + cbAA->setWhatsThis(i18n("If this option is selected, KDE will smooth the edges of curves in fonts.")); + + aaSettingsButton = new QPushButton( i18n( "Configure..." ), this); + connect(aaSettingsButton, SIGNAL(clicked()), SLOT(slotCfgAa())); + label->setBuddy( cbAA ); + lay->addWidget( cbAA, 0, 1 ); + lay->addWidget( aaSettingsButton, 0, 2 ); + // Initialize aaSettingsButton state based on the current cbAA->currentIndex value, will be eventually updated at load() + slotUseAntiAliasing(); + + connect(cbAA, SIGNAL(currentIndexChanged(int)), SLOT(slotUseAntiAliasing())); +#endif +#ifdef Q_WS_X11 + checkboxForceDpi = new QCheckBox( i18n( "Force fonts DPI:" ), this ); + lay->addWidget( checkboxForceDpi, 1, 0 ); + spinboxDpi = new QSpinBox( this ); + spinboxDpi->setRange(1, 1000); + spinboxDpi->setSingleStep(24); // The common DPI values 72, 96 and 120 are multiples of 24 + QString whatsthis = i18n( + "

    This option forces a specific DPI value for fonts. It may be useful" + " when the real DPI of the hardware is not detected properly and it" + " is also often misused when poor quality fonts are used that do not" + " look well with DPI values other than 96 or 120 DPI.

    " + "

    The use of this option is generally discouraged. For selecting proper DPI" + " value a better option is explicitly configuring it for the whole X server if" + " possible (e.g. DisplaySize in xorg.conf or adding -dpi value to" + " ServerLocalArgs= in $KDEDIR/share/config/kdm/kdmrc). When fonts do not render" + " properly with real DPI value better fonts should be used or configuration" + " of font hinting should be checked.

    " ); + spinboxDpi->setWhatsThis(whatsthis); + checkboxForceDpi->setChecked(false); + spinboxDpi->setEnabled(false); + connect( spinboxDpi, SIGNAL( valueChanged(int)), SLOT( changed())); + connect( checkboxForceDpi, SIGNAL( toggled(bool)), SLOT( changed())); + connect( checkboxForceDpi, SIGNAL( toggled(bool)), spinboxDpi, SLOT( setEnabled(bool))); + lay->addWidget( spinboxDpi, 1, 1 ); +#endif + layout->addStretch(1); + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + aaSettings=new FontAASettings(this); +#endif + +} + +KFonts::~KFonts() +{ + QList::Iterator it(fontUseList.begin()), + end(fontUseList.end()); + + for(; it!=end; ++it) + delete (*it); + fontUseList.clear(); +} + +void KFonts::fontSelected() +{ + emit changed(true); +} + +void KFonts::defaults() +{ + for ( int i = 0; i < (int) fontUseList.count(); i++ ) + fontUseList.at( i )->setDefault(); + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + useAA = AASystem; + cbAA->setCurrentIndex( useAA ); + aaSettings->defaults(); +#endif +#ifdef Q_WS_X11 + checkboxForceDpi->setChecked( false ); + spinboxDpi->setValue( 96 ); +#endif + emit changed(true); +} + +void KFonts::load() +{ + QList::Iterator it(fontUseList.begin()), + end(fontUseList.end()); + + for(; it!=end; ++it) + (*it)->readFont(); + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + useAA_original = useAA = aaSettings->load() ? AAEnabled : AADisabled; + cbAA->setCurrentIndex( useAA ); +#endif + + KConfig _cfgfonts( "kcmfonts" ); + KConfigGroup cfgfonts(&_cfgfonts, "General"); +#ifdef Q_WS_X11 + int dpicfg = cfgfonts.readEntry( "forceFontDPI", 0 ); + if (dpicfg <= 0) { + checkboxForceDpi->setChecked(false); + spinboxDpi->setValue(96); + dpi_original = 0; + } else { + checkboxForceDpi->setChecked(true); + spinboxDpi->setValue(dpicfg); + dpi_original = dpicfg; + }; +#endif +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + if( cfgfonts.readEntry( "dontChangeAASettings", true )) { + useAA_original = useAA = AASystem; + cbAA->setCurrentIndex( useAA ); + } +#endif + + emit changed(false); +} + +void KFonts::save() +{ + QList::Iterator it(fontUseList.begin()), + end(fontUseList.end()); + + for(; it!=end; ++it) + (*it)->writeFont(); + + KGlobal::config()->sync(); + + KConfig _cfgfonts( "kcmfonts" ); + KConfigGroup cfgfonts(&_cfgfonts, "General"); +#ifdef Q_WS_X11 + int dpi = ( checkboxForceDpi->isChecked() ? spinboxDpi->value() : 0 ); + cfgfonts.writeEntry( "forceFontDPI", dpi ); +#endif +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + cfgfonts.writeEntry( "dontChangeAASettings", cbAA->currentIndex() == AASystem ); +#endif + cfgfonts.sync(); +#ifdef Q_WS_X11 + // if the setting is reset in the module, remove the dpi value, + // otherwise don't explicitly remove it and leave any possible system-wide value + if( dpi == 0 && dpi_original != 0 ) { + KProcess proc; + proc << "xrdb" << "-quiet" << "-remove" << "-nocpp"; + proc.start(); + if (proc.waitForStarted()) { + proc.write( QByteArray( "Xft.dpi\n" ) ); + proc.closeWriteChannel(); + proc.waitForFinished(); + } + } +#endif + + KGlobalSettings::self()->emitChange(KGlobalSettings::FontChanged); + + kapp->processEvents(); // Process font change ourselves + + + // Don't overwrite global settings unless explicitly asked for - e.g. the system + // fontconfig setup may be much more complex than this module can provide. + // TODO: With AASystem the changes already made by this module should be reverted somehow. +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + bool aaSave = false; + if( cbAA->currentIndex() != AASystem ) + aaSave = aaSettings->save( useAA == AAEnabled ); + + if( aaSave || (useAA != useAA_original) || dpi != dpi_original) { + KMessageBox::information(this, + i18n( + "

    Some changes such as anti-aliasing or DPI will only affect newly started applications.

    " + ), i18n("Font Settings Changed"), "FontSettingsChanged"); + useAA_original = useAA; + dpi_original = dpi; + } +#else +#ifdef Q_WS_X11 + if(dpi != dpi_original) { + KMessageBox::information(this, + i18n( + "

    Some changes such as DPI will only affect newly started applications.

    " + ), i18n("Font Settings Changed"), "FontSettingsChanged"); + dpi_original = dpi; + } +#endif +#endif + runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); + + emit changed(false); +} + + +void KFonts::slotApplyFontDiff() +{ + QFont font = QFont(fontUseList.first()->font()); + KFontChooser::FontDiffFlags fontDiffFlags = 0; + int ret = KFontDialog::getFontDiff(font,fontDiffFlags,KFontChooser::NoDisplayFlags,this); + + if (ret == KDialog::Accepted && fontDiffFlags) + { + for ( int i = 0; i < (int) fontUseList.count(); i++ ) + fontUseList.at( i )->applyFontDiff( font,fontDiffFlags ); + emit changed(true); + } +} + +void KFonts::slotUseAntiAliasing() +{ +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + useAA = static_cast< AASetting >( cbAA->currentIndex()); + aaSettingsButton->setEnabled(useAA == AAEnabled); + emit changed(true); +#endif +} + +void KFonts::slotCfgAa() +{ +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + if(aaSettings->exec()) + { + emit changed(true); + } +#endif +} + +// vim:ts=2:sw=2:tw=78 diff --git a/kcontrol/fonts/fonts.desktop b/kcontrol/fonts/fonts.desktop new file mode 100644 index 00000000..0a97f8b7 --- /dev/null +++ b/kcontrol/fonts/fonts.desktop @@ -0,0 +1,239 @@ +[Desktop Entry] +Exec=kcmshell4 fonts +Icon=preferences-desktop-font +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/fonts/index.html + +X-KDE-Library=kcm_fonts +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=application-appearance +X-KDE-Weight=80 + +Name=Fonts +Name[af]=Skriftipes +Name[ar]=الخطوط +Name[ast]=Tribes de lletra +Name[be]=Шрыфты +Name[be@latin]=Šryfty +Name[bg]=Шрифтове +Name[bn]=ফন্ট +Name[bn_IN]=ফন্ট +Name[br]=Fontoù +Name[bs]=Fontovi +Name[ca]=Tipus de lletra +Name[ca@valencia]=Tipus de lletra +Name[cs]=Písma +Name[csb]=Fòntë +Name[cy]=Ffontiau +Name[da]=Skrifttyper +Name[de]=Schriftarten +Name[el]=Γραμματοσειρές +Name[en_GB]=Fonts +Name[eo]=Tiparoj +Name[es]=Tipos de letra +Name[et]=Fondid +Name[eu]=Letra-tipoak +Name[fa]=قلمها +Name[fi]=Fontit +Name[fr]=Polices de caractères +Name[fy]=Lettertypen +Name[ga]=Clónna +Name[gl]=Tipos de letra +Name[gu]=ફોન્ટ્સ +Name[he]=גופנים +Name[hi]=फ़ॉन्ट्स +Name[hne]=फोंट +Name[hr]=Fontovi +Name[hsb]=Pisma +Name[hu]=Betűtípusok +Name[ia]=Fontes +Name[id]=Fonta +Name[is]=Letur +Name[it]=Caratteri +Name[ja]=フォント +Name[ka]=ფონტები +Name[kk]=Қаріптер +Name[km]=ពុម្ព​អក្សរ +Name[kn]=ಅಕ್ಷರಶೈಲಿಗಳು +Name[ko]=글꼴 +Name[ku]=Curenivîs +Name[lt]=Šriftai +Name[lv]=Fonti +Name[mai]=फान्ट +Name[mk]=Фонтови +Name[ml]=അക്ഷരസഞ്ചയങ്ങള്‍ +Name[mr]=फॉन्ट +Name[ms]=Fon +Name[nb]=Skrifttyper +Name[nds]=Schriftoorden +Name[ne]=फन्ट +Name[nl]=Lettertypen +Name[nn]=Skrifter +Name[oc]=Poliças +Name[or]=ଅକ୍ଷର ରୂପ +Name[pa]=ਫੋਂਟ +Name[pl]=Czcionki +Name[pt]=Tipos de Letra +Name[pt_BR]=Fontes +Name[ro]=Fonturi +Name[ru]=Шрифты +Name[se]=Fonttat +Name[si]=අකුරු +Name[sk]=Písma +Name[sl]=Pisave +Name[sr]=Фонтови +Name[sr@ijekavian]=Фонтови +Name[sr@ijekavianlatin]=Fontovi +Name[sr@latin]=Fontovi +Name[sv]=Teckensnitt +Name[ta]=எழுத்துருக்கள் +Name[te]=ఫాంట్‍స్ +Name[tg]=Ҳарфҳо +Name[th]=แบบอักษรต่างๆ +Name[tr]=Yazı Tipleri +Name[ug]=خەت نۇسخا +Name[uk]=Шрифти +Name[uz]=Shriftlar +Name[uz@cyrillic]=Шрифтлар +Name[vi]=Phông chữ +Name[wa]=Fontes +Name[xh]=Uhlobo lwamagama +Name[x-test]=xxFontsxx +Name[zh_CN]=字体 +Name[zh_TW]=字型 + +Comment=Font settings +Comment[af]=Skrif tipe instellings +Comment[ar]=إعدادات الخطوط +Comment[ast]=Preferencies de les tribes de lletra +Comment[be]=Настаўленні шрыфтоў +Comment[be@latin]=Nałady šryftoŭ +Comment[bg]=Настройки на системните шрифтове +Comment[bn]=ফন্ট সেটিংস +Comment[bn_IN]=ফন্ট সংক্রান্ত বৈশিষ্ট্য +Comment[br]=Kefluniañ ar fontoù +Comment[bs]=Postavke fonta +Comment[ca]=Arranjament del tipus de lletra +Comment[ca@valencia]=Arranjament del tipus de lletra +Comment[cs]=Nastavení písem +Comment[csb]=Nastôw fòntów +Comment[cy]=Gosodiadau Ffontiau +Comment[da]=Skrifttypeindstillinger +Comment[de]=Schriftarten-Einstellungen +Comment[el]=Ρυθμίσεις γραμματοσειρών +Comment[en_GB]=Font settings +Comment[eo]=Tiparagordo +Comment[es]=Preferencias de los tipos de letra +Comment[et]=Fontide seadistused +Comment[eu]=Letra-tipoen ezarpenak +Comment[fa]=تنظیمات قلم +Comment[fi]=Fonttiasetukset +Comment[fy]=Lettertypen ynstellings +Comment[ga]=Socruithe na gclónna +Comment[gl]=Configuración dos tipos de letra +Comment[gu]=ફોન્ટ ગોઠવણીઓ +Comment[he]=הגדרות גופנים +Comment[hi]=फ़ॉन्ट्स विन्यास +Comment[hne]=फोंट सेटिंग +Comment[hr]=Postavke fontova +Comment[hsb]=Nastajenja za pisma +Comment[hu]=Betűtípus-beállítások +Comment[ia]=Preferentias de font +Comment[id]=Pengaturan fonta +Comment[is]=Stillingar leturs +Comment[ka]=ფონტების კონფიგურაცია +Comment[kk]=Қаріптерін орнату +Comment[km]=ការ​កំណត់​ពុម្ព​អក្សរ +Comment[kn]=ಅಕ್ಷರಶೈಲಿ ಸಂಯೋಜನೆಗಳು +Comment[ko]=글꼴 설정 +Comment[ku]=Mîhengên curenivîsan +Comment[lt]=Šriftų nustatymai +Comment[lv]=Fontu parametri +Comment[mai]=फान्ट्स बिन्यास +Comment[mk]=Поставувања на фонтовите +Comment[ml]=അക്ഷരസഞ്ചയത്തിന്റെ സജ്ജീകരണങ്ങള്‍ +Comment[mr]=फॉन्ट संयोजना +Comment[ms]=Seting Fon +Comment[nb]=Skriftinnstillinger +Comment[nds]=Schriftoorden instellen +Comment[ne]=फन्ट सेटिङ +Comment[nl]=Lettertypeninstellingen +Comment[nn]=Skriftinnstillingar +Comment[oc]=Paramètres de poliça +Comment[or]=ଅକ୍ଷର ରୂପ ସଂଚଚନା +Comment[pa]=ਫੋਂਟ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia czcionek +Comment[pt]=Configuração dos tipos de letra +Comment[pt_BR]=Configurações das fontes +Comment[ro]=Configurări font +Comment[ru]=Настройка шрифтов +Comment[se]=Fontaheivehusat +Comment[si]=අකුරු සැකසුම් +Comment[sk]=Nastavenie písiem +Comment[sl]=Nastavitve pisav +Comment[sr]=Поставке фонтова +Comment[sr@ijekavian]=Поставке фонтова +Comment[sr@ijekavianlatin]=Postavke fontova +Comment[sr@latin]=Postavke fontova +Comment[sv]=Anpassa teckensnitt +Comment[ta]=எழுத்துரு அமைப்புகள் +Comment[te]=ఫాంట్ అమరికలు +Comment[tg]=Танзимоти ҳарфҳо +Comment[th]=ตั้งค่าแบบอักษรต่างๆ +Comment[tr]=Yazı tipi ayarları +Comment[ug]=خەت نۇسخا تەڭشەك +Comment[uk]=Налаштування шрифтів +Comment[uz]=Shriftlarni moslash +Comment[uz@cyrillic]=Шрифтларни мослаш +Comment[vi]=Thiết lập phông chữ +Comment[wa]=Apontiaedje des fontes +Comment[xh]=Izicwangciso zohlobo lwamagama +Comment[x-test]=xxFont settingsxx +Comment[zh_CN]=字体设置 +Comment[zh_TW]=字型設定 + +X-KDE-Keywords=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts +X-KDE-Keywords[bs]=slova,veličina slova,stil,znakovi,postaviti znakove,ploča,kontrolna ploča,pozadina,upravitelj datoteka,alatne trake,meni,naslov prozora,naslov,DPI,niskopropusni,slova pozadine,slova na alatnoj traci,obilježja,opći fontovi +X-KDE-Keywords[ca]=tipus de lletres,mida de tipus de lletra,estils,joc de caràcters,jocs de caràcters,plafó,plafó de control,escriptoris,Gestor de fitxers,Barres d'eines,Menú,Títol de finestra,Títol,DPI,antialiàsing,tipus de lletra d'escriptori,tipus de lletra de barra d'eines,caràcter,tipus de lletra general +X-KDE-Keywords[ca@valencia]=tipus de lletres,mida de tipus de lletra,estils,joc de caràcters,jocs de caràcters,plafó,plafó de control,escriptoris,Gestor de fitxers,Barres d'eines,Menú,Títol de finestra,Títol,DPI,antialiàsing,tipus de lletra d'escriptori,tipus de lletra de barra d'eines,caràcter,tipus de lletra general +X-KDE-Keywords[da]=skrifttyper,skriftstørrelse,stile,tegnsæt,panel,kontrolpanel,skriveborde,filhåndtering,værktøjslinjer,menu,vinduestitel,titel,DPI,anti-aliasing,værktøjslinjer,tegn +X-KDE-Keywords[de]=Schriftarten,Schriftgrößen,Stile,Zeichensätze,Kontrollleiste,Stile,Dateiverwaltung,Arbeitsflächen,Werkzeugleisten,Menüs,Fenstertitel,Titel,DPI,Antialiasing,Arbeitsflächeschriften,Werkzeugleistenschriften,Zeichen,Allgemeine Schriftarten +X-KDE-Keywords[el]=γραμματοσειρές,μέγεθος γραμματοσειράς,στιλ,σύνολα χαρακτήρων,πίνακας,πίνακας ελέγχου,επιφάνειες εργασίας,διαχειριστής αρχείων,γραμμές εργαλείων,μενού,τίτλος παραθύρου,τίτλος,DPI,εξομάλυνση,γραμματοσειρές επιφάνειας εργασίας,γραμματοσειρές γραμμής εργαλείων,χαρακτήρας,γενικές γραμματοσειρές +X-KDE-Keywords[en_GB]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts +X-KDE-Keywords[es]=tipos de letra,tamaño del tipo de letra,estilos,juegos de caracteres,panel,panel de control panel,escritorios,Gestor de archivos,Barras de herramientas,Menú,Título de la ventana,Título,DPI,suavizado de texto,tipos de letra del escritorio,tipos de letra de las barras de herramientas,carácter,tipos de letra generales +X-KDE-Keywords[et]=fondid,fondi suurus,kodeering,kooditabel,paneel,juhtpaneel,töölauad,failihaldur,tööriistaribad,menüü,aken,tiitel,nimetus,nimi,DPI,antialias,töölaua fondid,tööriistariba fondid,märk,märgid,sümbolid,üldised fondid +X-KDE-Keywords[eu]=letra-tipoak,letra-tamaina,estiloak,karaktere-jokoak,panela,kontrol-panela,mahaigain,fitxategi-kudeatzaile,tresna-barra,menu,leihoaren titulu,titulu,DPI,antialiasing,mahaigaineko letra-tripo,tresna-barrako letra-tipo,karaktere,letra-tipo orokor +X-KDE-Keywords[fi]=kirjasimet,fontit,kirjasinkoko,fonttikoko,tyylit,merkistöt,paneeli,ohjauskeskus,työpöydät,Tiedostonhallinta,Työkalurivit,Työkalupalkit,Valikko,Ikkunan otsikko,Otsikko,DPI,antialiasointi,työpöytäkirjasimet,työpöytäfontit,työkalurivikirjasimet, työkalurivien kirjasimet, työkalurivifontit, työkalurivien fontit,merkki,yleiskirjasimet,yleiset kirjasimet,yleisfontit,yleiset fontit +X-KDE-Keywords[fr]=polices, taille de police, styles, tables de caractères, jeux de caractères, tableau de bord, bureaux, Gestionnaire de Fichiers, Barre d'outils, Menu, Titre de fenêtre, Titre, DPI, anti crénelage, polices du bureau, police de barre d'outils, caractère, polices générales +X-KDE-Keywords[ga]=clónna,clófhoirne,clómhéid,stíleanna,tacair charachtar,painéal,painéal rialaithe,deasca,Bainisteoir Comhad,Barraí Uirlisí,Roghchlár,Teideal Fuinneoige,Teideal,PSO,frithailiasáil,clónna deisce,clófhoirne deisce,clónna barra uirlisí,carachtar,clónna ginearálta,clófhoirne ginearálta +X-KDE-Keywords[gl]=tipo de letra, letra, tamaño da letra, carácter, caracteres, conxunto de caracteres, glifo, panel, control, panel de control, antialiasing, suavizado +X-KDE-Keywords[hu]=betűkészletek,betűméret,stílusok,karakterkészletek,karakterkészletek,panel,beállítópanel,asztalok,Fájlkezelő,Eszköztárak,Menü,Ablakcím,Cím,DPI,élsimítás,asztal betűkészletek,eszköztár betűkészletek,karakter,általános betűkészletek +X-KDE-Keywords[ia]=fonts,grandor de font,stilos,insimules de characteres,insimules de characteres,pannello,pannello de controlo,scriptorios,Gerente de File,Barra de instrumentos,menu,Titulo de Fenestra,Titulo,DPI,anti-aliasing,fonts de scriptorio, fonts de barra de titulo, character,fonts general +X-KDE-Keywords[it]=caratteri,dimensione dei caratteri,stili,codifiche,insiemi di caratteri,pannello,pannello di controllo,desktop,gestore dei file,barre degli strumenti,menu,titolo della finestra,titolo,DPI,anti-aliasing,caratteri del desktop,caratteri della barra degli strumenti,carattere,caratteri generali +X-KDE-Keywords[kk]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts +X-KDE-Keywords[km]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts +X-KDE-Keywords[ko]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,글꼴,스타일,창 제목,글자 +X-KDE-Keywords[mr]=फॉन्ट्स, फॉन्ट साईज, कॅरेक्टर, कॅरेक्टर सेटस, पँनल, कन्ट्रोल पँनल, डेस्कटॉप्स, फाईल मेनेजर, टूलबार्स, मेन्यू, चौकट टाईटल, टाईटल, डी पी आय , अन्टी अलायझिंग, डेस्कटॉप फॉन्टस, टूलबार फॉन्टस, कॅरेक्टर, जनरल फॉन्ट्स +X-KDE-Keywords[nb]=skrifter,skriftstørrelse,stiler,tegnsett,panel,kontrollpanel,skrivebord,filbehandler,Verktøylinje,Meny,Vindiustittel,tittel,DPI,kantutjevning,skrivebordsskrifter,verktøylinjeskrifter,generelle skrifter +X-KDE-Keywords[nds]=Schriftoorden,Schrift,Stilen,Tekensetten,Paneel,Stüerpaneel,Schriefdisch,Dateipleger,Warktüüchbalkens,Menü,Finstertitel,Titel,DPI,Kantstreken,anti-aliasing,Schriefdisch,Teken +X-KDE-Keywords[nl]=lettertypes,lettertype,tekengrootte,stijlen,tekensets,paneel,besturingspaneel,bureaubladen,bestandsbeheerder,werkbalken,menu,venstertitel,titel,DPI,anti-aliasing,lettertypen van bureaublad,lettertypen van werkbalk,teken,algemene lettertypes +X-KDE-Keywords[pl]=czcionki,rozmiar czcionki,style,zestaw znaków,panel,panel sterowania,pulpity,Menadżer plików,Paski narzędzi,Menu,Tytuł okna,Tytuł,DPI,wygładzanie,czcionki pulpitu,czcionki pasków narzędzi,znak,czcionki ogólne +X-KDE-Keywords[pt]=tipos de letra,tamanho de letra,estilos,codificações,codificações de caracteres,painel,painel de controlo,ecrãs,gestor de ficheiros,barras de ferramentas,menu,título da janela,título,PPP,suavização,tipos de letra do ecrã,tipos de letra da barra de ferramentas,carácter,tipos de letra gerais +X-KDE-Keywords[pt_BR]=fontes,tamanho da fonte,estilos,codificações,codificações de caracteres,painel,painel de controle,áreas de trabalho,gerenciador de arquivos,barras de ferramentas,Menu,Título da janela,Título,PPP,anti-aliasing,fontes da área de trabalho,fontes da barra de ferramentas,caractere,fontes gerais +X-KDE-Keywords[ru]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,шрифты,размер шрифтов,стили,кодировки,панель,панель управления,рабочие столы,диспетчер файлов,панель инструментов,меню,заголовок окна,заголовок,сглаживание,шрифты рабочего стола,шрифты панели инструментов,символы,общие шрифты +X-KDE-Keywords[sk]=písmo,veľkosť písma,štýly,znakové sady,sady znakov,panel,ovládací panel,plochy,Správca súborov,Panely nástrojov,Ponuka,Titulok okna,Titulok,DPI,anti-aliasing,písma plochy,písma nástrojových panelov,znak,všeobecné písma +X-KDE-Keywords[sl]=pisave,velikost pisav,slogi,nabori znakov,znakovni nabori,pult,nadzorna plošča,namizja,upravljalnik datotek,datotečni upravljalnik,orodjarne,orodne vrstice,meni,naslov okna,naslovna vrstica,naslov,ločljivost,točk na palec,glajenje robov,namizne pisave,pisave namizja,pisave orodjarne, pisave orodne vrstice,znak,splošne pisave +X-KDE-Keywords[sr]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,фонт,величина фонта,стил,кодирање,панел,контролни панел,површ,менаџер фајлова,траке алатки,мени,наслов прозора,тпи,омекшавање,фонт површи,фонт траке алатки,знакови,општи фонт +X-KDE-Keywords[sr@ijekavian]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,фонт,величина фонта,стил,кодирање,панел,контролни панел,површ,менаџер фајлова,траке алатки,мени,наслов прозора,тпи,омекшавање,фонт површи,фонт траке алатки,знакови,општи фонт +X-KDE-Keywords[sr@ijekavianlatin]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,font,veličina fonta,stil,kodiranje,panel,kontrolni panel,površ,menadžer fajlova,trake alatki,meni,naslov prozora,tpi,omekšavanje,font površi,font trake alatki,znakovi,opšti font +X-KDE-Keywords[sr@latin]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,font,veličina fonta,stil,kodiranje,panel,kontrolni panel,površ,menadžer fajlova,trake alatki,meni,naslov prozora,tpi,omekšavanje,font površi,font trake alatki,znakovi,opšti font +X-KDE-Keywords[sv]=teckensnitt,teckenstorlek,stil,teckenuppsättningar,panel,kontrollpanel,skrivbord,Filhanterare,Verktygsrader,Meny,Fönsternamn,Namn,Punkter/tum,kantutjämning,skrivbordsteckensnitt,verktygsradsteckensnitt,tecken,allmänna teckensnitt +X-KDE-Keywords[tr]=yazı tipi,yazı tipi boyutu,karakterler,karakter setleri,panel,denetim paneli,masaüstleri,Dosya Yöneticisi,Araç Çubukları,Menü,Pencere Başlığı,Başlık,DPI,yumuşatma,anti-aliasing,masaüstü yazı tipleri,araç çubuğu yazı tipleri,karakter,genel yazı tipleri +X-KDE-Keywords[uk]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,шрифт,шрифти,розмір,розмір шрифту,стиль,стилі,гарнітура,гарнітури,кодування,набір,символ,символи,набір символів,панель,панель керування,стільниця,стільниці,файл,керування,керування файлами,менеджер,панель інструментів,меню,заголовок,заголовок вікна,роздільність,згладжування,шрифти стільниці,шрифти панелі,символ,загальні шрифти +X-KDE-Keywords[x-test]=xxfonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fontsxx +X-KDE-Keywords[zh_CN]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts,字体字体大小,样式,字符集,面板,控制面板,桌面,文件管理器,工具栏,菜单,窗口标题,标题,反锯齿,桌面字体,工具栏字体,字符,常规字体 +X-KDE-Keywords[zh_TW]=fonts,font size,styles,charsets,character sets,panel,control panel,desktops,FileManager,Toolbars,Menu,Window Title,Title,DPI,anti-aliasing,desktop fonts,toolbar fonts,character,general fonts + +Categories=Qt;KDE;X-KDE-settings-looknfeel; diff --git a/kcontrol/fonts/fonts.h b/kcontrol/fonts/fonts.h new file mode 100644 index 00000000..e98d0604 --- /dev/null +++ b/kcontrol/fonts/fonts.h @@ -0,0 +1,127 @@ +//----------------------------------------------------------------------------- +// +// kdisplay, fonts tab +// +// Copyright (c) Mark Donohoe 1997 +// Lars Knoll 1999 + +#ifndef FONTS_H +#define FONTS_H + +#include +#include + +#include +#include +#include + +#include "kxftconfig.h" + +class QCheckBox; +class QComboBox; +class QSpinBox; +class KDoubleNumInput; +class FontAASettings; + +class FontUseItem : public KFontRequester +{ + Q_OBJECT + +public: + FontUseItem(QWidget * parent, const QString &name, const QString &grp, + const QString &key, const QString &rc, const QFont &default_fnt, + bool fixed = false); + + void readFont(); + void writeFont(); + void setDefault(); + void applyFontDiff(const QFont &fnt, int fontDiffFlags); + + const QString& rcFile() { return _rcfile; } + const QString& rcGroup() { return _rcgroup; } + const QString& rcKey() { return _rckey; } + +private: + QString _rcfile; + QString _rcgroup; + QString _rckey; + QFont _default; +}; + +class FontAASettings : public KDialog +{ + Q_OBJECT + +public: + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + FontAASettings(QWidget *parent); + + bool save( bool useAA ); + bool load(); + void defaults(); + int getIndex(KXftConfig::SubPixel::Type spType); + KXftConfig::SubPixel::Type getSubPixelType(); + int getIndex(KXftConfig::Hint::Style hStyle); + KXftConfig::Hint::Style getHintStyle(); + void enableWidgets(); + int exec(); +#endif + +protected Q_SLOTS: + + void changed(); + +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) +private: + + QCheckBox *excludeRange; + QCheckBox *useSubPixel; + KDoubleNumInput *excludeFrom; + KDoubleNumInput *excludeTo; + QComboBox *subPixelType; + QComboBox *hintingStyle; + QLabel *excludeToLabel; + bool changesMade; +#endif +}; + +/** + * The Desktop/fonts tab in kcontrol. + */ +class KFonts : public KCModule +{ + Q_OBJECT + +public: + KFonts(QWidget *parent, const QVariantList &); + ~KFonts(); + + virtual void load(); + virtual void save(); + virtual void defaults(); + +protected Q_SLOTS: + void fontSelected(); + void slotApplyFontDiff(); + void slotUseAntiAliasing(); + void slotCfgAa(); + +private: +#if defined(HAVE_FONTCONFIG) && defined (Q_WS_X11) + enum AASetting { AAEnabled, AASystem, AADisabled }; + AASetting useAA, useAA_original; + QComboBox *cbAA; + QPushButton *aaSettingsButton; + FontAASettings *aaSettings; +#endif +#ifdef Q_WS_X11 + int dpi_original; + QCheckBox *checkboxForceDpi; + QSpinBox* spinboxDpi; +#endif + QList fontUseList; +}; + +#endif + diff --git a/kcontrol/fonts/kxftconfig.cpp b/kcontrol/fonts/kxftconfig.cpp new file mode 100644 index 00000000..410bf015 --- /dev/null +++ b/kcontrol/fonts/kxftconfig.cpp @@ -0,0 +1,847 @@ +/* + Copyright (c) 2002 Craig Drummond + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kxftconfig.h" +#ifdef HAVE_FONTCONFIG + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +using namespace std; + +static int point2Pixel(double point) +{ + return (int)(((point*QX11Info::appDpiY())/72.0)+0.5); +} + +static int pixel2Point(double pixel) +{ + return (int)(((pixel*72.0)/(double)QX11Info::appDpiY())+0.5); +} + +static bool equal(double d1, double d2) +{ + return (fabs(d1 - d2) < 0.0001); +} + +static QString dirSyntax(const QString &d) +{ + if(!d.isNull()) + { + QString ds(d); + + ds.replace("//", "/"); + + int slashPos=ds.lastIndexOf('/'); + + if(slashPos!=(((int)ds.length())-1)) + ds.append('/'); + + return ds; + } + + return d; +} + +static bool check(const QString &path, unsigned int fmt, bool checkW=false) +{ + KDE_struct_stat info; + QByteArray pathC(QFile::encodeName(path)); + + return 0==KDE_lstat(pathC, &info) && (info.st_mode&S_IFMT)==fmt && + (!checkW || 0==::access(pathC, W_OK)); +} + +inline bool fExists(const QString &p) +{ + return check(p, S_IFREG, false); +} + +inline bool dWritable(const QString &p) +{ + return check(p, S_IFDIR, true); +} + +static QString getDir(const QString &f) +{ + QString d(f); + + int slashPos=d.lastIndexOf('/'); + + if(-1!=slashPos) + d.remove(slashPos+1, d.length()); + + return dirSyntax(d); +} + +static time_t getTimeStamp(const QString &item) +{ + KDE_struct_stat info; + + return !item.isNull() && 0==KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0; +} + +// +// Obtain location of config file to use. +QString getConfigFile() +{ + FcStrList *list=FcConfigGetConfigFiles(FcConfigGetCurrent()); + QStringList files; + FcChar8 *file; + QString home(dirSyntax(QDir::homePath())); + + while((file=FcStrListNext(list))) + { + QString f((const char *)file); + + if(fExists(f) && 0==f.indexOf(home)) + files.append(f); + } + FcStrListDone(list); + + // + // Go through list of files, looking for the preferred one... + if(files.count()) + { + QStringList::const_iterator it(files.begin()), + end(files.end()); + + for(; it!=end; ++it) + if(-1!=(*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) + return *it; + return files.front(); // Just return the 1st one... + } + else // Hmmm... no known files? + { + if(FcGetVersion() >= 21000) + { + QString targetPath(KGlobal::dirs()->localxdgconfdir()+"fontconfig"); + QDir target(targetPath); + if(!target.exists()) + target.mkpath(targetPath); + return targetPath+"/fonts.conf"; + } + else + return home+"/.fonts.conf"; + } +} + +static QString getEntry(QDomElement element, const char *type, unsigned int numAttributes, ...) +{ + if(numAttributes==element.attributes().length()) + { + va_list args; + unsigned int arg; + bool ok=true; + + va_start(args, numAttributes); + + for(arg=0; arg"; + static const char qtDocTypeLine[] = ""; + static const char docTypeLine[] = ""; + + QString str(m_doc.toString()); + int idx; + + if(0!=str.indexOf("=0 || to>=0) && foundFalse) + { + m_excludeRange.from=from < to ? from : to; + m_excludeRange.to =from < to ? to : from; + m_excludeRange.node=n; + } + else if((pixelFrom>=0 || pixelTo>=0) && foundFalse) + { + m_excludePixelRange.from=pixelFrom < pixelTo ? pixelFrom : pixelTo; + m_excludePixelRange.to =pixelFrom < pixelTo ? pixelTo : pixelFrom; + m_excludePixelRange.node=n; + } + } + break; + default: + break; + } + } + } + n=n.nextSibling(); + } +} + +void KXftConfig::applySubPixelType() +{ + QDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("const"), + editNode = m_doc.createElement("edit"); + QDomText typeText = m_doc.createTextNode(toStr(m_subPixel.type)); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "rgba"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_subPixel.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_subPixel.node); + m_subPixel.node=matchNode; +} + +void KXftConfig::applyHintStyle() +{ + applyHinting(); + + if(Hint::NotSet==m_hint.style || m_hint.toBeRemoved) + { + if(!m_hint.node.isNull()) + { + m_doc.documentElement().removeChild(m_hint.node); + m_hint.node.clear(); + } + } + else + { + QDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("const"), + editNode = m_doc.createElement("edit"); + QDomText typeText = m_doc.createTextNode(toStr(m_hint.style)); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "hintstyle"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_hint.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_hint.node); + m_hint.node=matchNode; + } +} + +void KXftConfig::applyHinting() +{ + QDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("bool"), + editNode = m_doc.createElement("edit"); + QDomText typeText = m_doc.createTextNode(m_hinting.set ? "true" : "false"); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "hinting"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_hinting.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_hinting.node); + m_hinting.node=matchNode; +} + +void KXftConfig::applyExcludeRange(bool pixel) +{ + Exclude &range=pixel ? m_excludePixelRange : m_excludeRange; + + if(equal(range.from, 0) && equal(range.to, 0)) + { + if(!range.node.isNull()) + { + m_doc.documentElement().removeChild(range.node); + range.node.clear(); + } + } + else + { + QString fromString, + toString; + + fromString.setNum(range.from); + toString.setNum(range.to); + + QDomElement matchNode = m_doc.createElement("match"), + fromTestNode = m_doc.createElement("test"), + fromNode = m_doc.createElement("double"), + toTestNode = m_doc.createElement("test"), + toNode = m_doc.createElement("double"), + editNode = m_doc.createElement("edit"), + boolNode = m_doc.createElement("bool"); + QDomText fromText = m_doc.createTextNode(fromString), + toText = m_doc.createTextNode(toString), + boolText = m_doc.createTextNode("false"); + + matchNode.setAttribute("target", "font"); // CPD: Is target "font" or "pattern" ???? + fromTestNode.setAttribute("qual", "any"); + fromTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); + fromTestNode.setAttribute("compare", "more_eq"); + fromTestNode.appendChild(fromNode); + fromNode.appendChild(fromText); + toTestNode.setAttribute("qual", "any"); + toTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); + toTestNode.setAttribute("compare", "less_eq"); + toTestNode.appendChild(toNode); + toNode.appendChild(toText); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "antialias"); + editNode.appendChild(boolNode); + boolNode.appendChild(boolText); + matchNode.appendChild(fromTestNode); + matchNode.appendChild(toTestNode); + matchNode.appendChild(editNode); + + if(!m_antiAliasing.node.isNull()) + m_doc.documentElement().removeChild(range.node); + m_doc.documentElement().appendChild(matchNode); + range.node=matchNode; + } +} + +bool KXftConfig::getAntiAliasing() const +{ + return m_antiAliasing.set; +} + +void KXftConfig::setAntiAliasing( bool set ) +{ + if(set!=m_antiAliasing.set) + { + m_antiAliasing.set = set; + m_madeChanges = true; + } +} + +void KXftConfig::applyAntiAliasing() +{ + QDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("bool"), + editNode = m_doc.createElement("edit"); + QDomText typeText = m_doc.createTextNode(m_antiAliasing.set ? "true" : "false"); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "antialias"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(!m_antiAliasing.node.isNull()) + m_doc.documentElement().removeChild(m_antiAliasing.node); + m_doc.documentElement().appendChild(matchNode); + m_antiAliasing.node=matchNode; +} + +// KXftConfig only parses one config file, user's .fonts.conf usually. +// If that one doesn't exist, then KXftConfig doesn't know if antialiasing +// is enabled or not. So try to find out the default value from the default font. +// Maybe there's a better way *shrug*. +bool KXftConfig::aliasingEnabled() +{ + FcPattern *pattern = FcPatternCreate(); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + FcResult result; + FcPattern *f = FcFontMatch( 0, pattern, &result ); + FcBool antialiased = FcTrue; + FcPatternGetBool( f, FC_ANTIALIAS, 0, &antialiased ); + FcPatternDestroy( f ); + FcPatternDestroy( pattern ); + return antialiased == FcTrue; +} + +#endif diff --git a/kcontrol/fonts/kxftconfig.h b/kcontrol/fonts/kxftconfig.h new file mode 100644 index 00000000..0df61645 --- /dev/null +++ b/kcontrol/fonts/kxftconfig.h @@ -0,0 +1,167 @@ +#ifndef __KXFTCONFIG_H__ +#define __KXFTCONFIG_H__ + +/* + Copyright (c) 2002 Craig Drummond + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#ifdef HAVE_FONTCONFIG + +#include + +#include +#include + +class KXftConfig +{ + public: + + struct Item + { + Item(QDomNode &n) : node(n), toBeRemoved(false) {} + Item() : toBeRemoved(false) {} + virtual void reset() { node.clear(); toBeRemoved=false; } + bool added() { return node.isNull(); } + + QDomNode node; + + virtual ~Item() {} + bool toBeRemoved; + }; + + struct SubPixel : public Item + { + enum Type + { + None, + Rgb, + Bgr, + Vrgb, + Vbgr + }; + + SubPixel(Type t, QDomNode &n) : Item(n), type(t) {} + SubPixel(Type t=None) : type(t) {} + + void reset() { Item::reset(); type=None; } + + Type type; + }; + + struct Exclude : public Item + { + Exclude(double f, double t, QDomNode &n) : Item(n), from(f), to(t) {} + Exclude(double f=0, double t=0) : from(f), to(t) {} + + void reset() { Item::reset(); from=to=0; } + + double from, + to; + }; + + struct Hint : public Item + { + enum Style + { + NotSet, + None, + Slight, + Medium, + Full + }; + + Hint(Style s, QDomNode &n) : Item(n), style(s) {} + Hint(Style s=NotSet) : style(s) {} + + void reset() { Item::reset(); style=NotSet; } + + Style style; + }; + + struct Hinting : public Item + { + Hinting(bool s, QDomNode &n) : Item(n), set(s) {} + Hinting(bool s=true) : set(s) {} + + void reset() { Item::reset(); set=true; } + + bool set; + }; + + struct AntiAliasing : public Item + { + AntiAliasing(bool s, QDomNode &n) : Item(n), set(s) {} + AntiAliasing(bool s=true) : set(s) {} + + void reset() { Item::reset(); set=true; } + + bool set; + }; + + public: + + explicit KXftConfig(); + + virtual ~KXftConfig(); + + bool reset(); + bool apply(); + bool getSubPixelType(SubPixel::Type &type); + void setSubPixelType(SubPixel::Type type); // SubPixel::None => turn off sub-pixel rendering + bool getExcludeRange(double &from, double &to); + void setExcludeRange(double from, double to); // from:0, to:0 => turn off exclude range + bool getHintStyle(Hint::Style &style); + void setHintStyle(Hint::Style style); + void setAntiAliasing(bool set); + bool getAntiAliasing() const; + bool changed() { return m_madeChanges; } + static QString description(SubPixel::Type t); + static const char * toStr(SubPixel::Type t); + static QString description(Hint::Style s); + static const char * toStr(Hint::Style s); + + private: + + void readContents(); + void applySubPixelType(); + void applyHintStyle(); + void applyAntiAliasing(); + void setHinting(bool set); + void applyHinting(); + void applyExcludeRange(bool pixel); + bool aliasingEnabled(); + + private: + + SubPixel m_subPixel; + Exclude m_excludeRange, + m_excludePixelRange; + Hint m_hint; + Hinting m_hinting; + AntiAliasing m_antiAliasing; + QDomDocument m_doc; + QString m_file; + bool m_madeChanges; + time_t m_time; +}; + +#endif + +#endif diff --git a/kcontrol/hardware/CMakeLists.txt b/kcontrol/hardware/CMakeLists.txt new file mode 100644 index 00000000..d938c974 --- /dev/null +++ b/kcontrol/hardware/CMakeLists.txt @@ -0,0 +1,9 @@ + +add_subdirectory( display ) + +if (CMAKE_SYSTEM_NAME MATCHES Linux) + # this one doesn't seem to be very portable, Alex + add_subdirectory( joystick ) +endif (CMAKE_SYSTEM_NAME MATCHES Linux) + + diff --git a/kcontrol/hardware/display/CMakeLists.txt b/kcontrol/hardware/display/CMakeLists.txt new file mode 100644 index 00000000..59174bae --- /dev/null +++ b/kcontrol/hardware/display/CMakeLists.txt @@ -0,0 +1,19 @@ + + + +########### next target ############### + +set(kcm_display_PART_SRCS display.cpp ) + + +kde4_add_plugin(kcm_display ${kcm_display_PART_SRCS}) + + +target_link_libraries(kcm_display ${KDE4_KCMUTILS_LIBS} ${QT_QTGUI_LIBRARY} ${KDE4_KDEUI_LIBS}) + +install(TARGETS kcm_display DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES display.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcontrol/hardware/display/Messages.sh b/kcontrol/hardware/display/Messages.sh new file mode 100644 index 00000000..561ccd0d --- /dev/null +++ b/kcontrol/hardware/display/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/display.pot diff --git a/kcontrol/hardware/display/display.cpp b/kcontrol/hardware/display/display.cpp new file mode 100644 index 00000000..8746d098 --- /dev/null +++ b/kcontrol/hardware/display/display.cpp @@ -0,0 +1,118 @@ +/* This file is part of the KDE project + Copyright (C) 2003-2004 Nadeem Hasan + + 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 +#include +#include +#include + +#include +#include +#include + +#include "display.h" +#include +#include + +K_PLUGIN_FACTORY(DisplayFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(DisplayFactory("display")) + +KCMDisplay::KCMDisplay( QWidget *parent, const QVariantList & ) + : KCModule( DisplayFactory::componentData(), parent ) + , m_changed(false) +{ + m_tabs = new QTabWidget( this ); + + addTab( "randr", i18n( "Size && Orientation" ) ); + addTab( "nvidiadisplay", i18n( "Graphics Adaptor" ) ); + addTab( "nvidia3d", i18n( "3D Options" ) ); + addTab( "kgamma", i18n( "Monitor Gamma" ) ); + if ( QApplication::desktop()->isVirtualDesktop() ) + addTab( "xinerama", i18n( "Multiple Monitors" ) ); + addTab( "energy", i18n( "Power Control" ) ); + + QVBoxLayout *top = new QVBoxLayout( this ); + top->setMargin( 0 ); + top->setSpacing( KDialog::spacingHint() ); + top->addWidget( m_tabs ); + + setButtons( Apply ); + load(); +} + +void KCMDisplay::addTab( const QString &name, const QString &label ) +{ + QWidget *page = new QWidget( m_tabs ); + QVBoxLayout *top = new QVBoxLayout( page ); + top->setMargin( KDialog::marginHint() ); + + KCModule *kcm = KCModuleLoader::loadModule( name, KCModuleLoader::None,page ); + + if ( kcm ) + { + top->addWidget( kcm ); + m_tabs->addTab( page, label ); + + connect( kcm, SIGNAL(changed(bool)), SLOT(moduleChanged(bool)) ); + m_modules.insert(kcm, false); + } + else + delete page; +} + +void KCMDisplay::load() +{ + for (QMap::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it) + it.key()->load(); +} + +void KCMDisplay::save() +{ + for (QMap::Iterator it = m_modules.begin(); it != m_modules.end(); ++it) + if (it.value()) + it.key()->save(); +} + +void KCMDisplay::moduleChanged( bool isChanged ) +{ + QMap::Iterator currentModule = m_modules.find(static_cast(const_cast(sender()))); + Q_ASSERT(currentModule != m_modules.end()); + if (currentModule.value() == isChanged) + return; + + currentModule.value() = isChanged; + + bool c = false; + + for (QMap::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it) { + if (it.value()) { + c = true; + break; + } + } + + if (m_changed != c) { + m_changed = c; + emit changed(c); + } +} + +#include "display.moc" diff --git a/kcontrol/hardware/display/display.desktop b/kcontrol/hardware/display/display.desktop new file mode 100644 index 00000000..5b434ceb --- /dev/null +++ b/kcontrol/hardware/display/display.desktop @@ -0,0 +1,187 @@ +[Desktop Entry] +Exec=kcmshell4 display +Icon=preferences-desktop-display +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kcm_display +X-KDE-ParentApp=kcontrol + +Name=Display +Name[af]=Skerm +Name[ar]=العرض +Name[ast]=Pantalla +Name[be]=Экран +Name[be@latin]=Ekran +Name[bg]=Екран +Name[bn]=ডিসপ্লে +Name[bn_IN]=প্রদর্শন +Name[br]=Diskwel +Name[bs]=Ekran +Name[ca]=Pantalla +Name[ca@valencia]=Pantalla +Name[cs]=Obrazovka +Name[csb]=Ekran +Name[cy]= Arddangos +Name[da]=Skærm +Name[de]=Anzeige +Name[el]=Οθόνη +Name[en_GB]=Display +Name[eo]=Vidigilo +Name[es]=Pantalla +Name[et]=Monitor +Name[eu]=Pantaila +Name[fa]=نمایش +Name[fi]=Näyttö +Name[fy]=Byldskerm +Name[ga]=Scáileán +Name[gl]=Pantalla +Name[gu]=ડિસ્પ્લે +Name[he]=תצוגה +Name[hi]=प्रदर्शक +Name[hne]=प्रदर्सक +Name[hr]=Zaslon +Name[hsb]=Wobrazowka +Name[hu]=Megjelenítés +Name[ia]=Monstrator +Name[id]=Tampilan +Name[is]=Skjár +Name[ka]=ჩვენება +Name[kk]=Дисплей +Name[km]=ការ​បង្ហាញ +Name[kn]=ಪ್ರದರ್ಶಕ +Name[ko]=표시 +Name[ku]=Dîmender +Name[lt]=Ekranas +Name[lv]=Ekrāns +Name[mai]=देखाबू +Name[mk]=Приказ +Name[ml]=പ്രദര്‍ശനം +Name[mr]=डिस्प्ले +Name[ms]=Paparan +Name[nb]=Bildeskjerm +Name[nds]=Schirm +Name[ne]=प्रदर्शन गर्नुहोस् +Name[nl]=Beeldscherm +Name[oc]=Visualizar +Name[or]=ପ୍ରଦର୍ଶକ +Name[pa]=ਡਿਸਪਲੇਅ +Name[pl]=Wyświetlanie +Name[pt]=Ecrã +Name[pt_BR]=Tela +Name[ro]=Afișare +Name[ru]=Экран +Name[se]=Šearbma +Name[si]=සංදර්ශනය +Name[sk]=Obrazovka +Name[sl]=Zaslon +Name[sr]=Екран +Name[sr@ijekavian]=Екран +Name[sr@ijekavianlatin]=Ekran +Name[sr@latin]=Ekran +Name[sv]=Bildskärm +Name[ta]=காட்சி +Name[te]=ప్రదర్శన +Name[tg]=Экран +Name[th]=การแสดงผล +Name[tr]=Ekran +Name[ug]=كۆرسەت +Name[uk]=Дисплей +Name[uz]=Displey +Name[uz@cyrillic]=Дисплей +Name[vi]=Màn hình +Name[wa]=Håynaedje +Name[x-test]=xxDisplayxx +Name[zh_CN]=显示 +Name[zh_TW]=顯示 +Comment=Display Settings +Comment[af]=Skerm Instellings +Comment[ar]=إعدادات العرض +Comment[ast]=Preferencies de la pantalla +Comment[be]=Настаўленні экрану +Comment[be@latin]=Nałady ekrana +Comment[bg]=Настройки на екрана +Comment[bn]=ডিসপ্লে সেটিংস +Comment[bn_IN]=প্রদর্শন সংক্রান্ত বৈশিষ্ট্য +Comment[br]=Kefluniañ an diskwel +Comment[bs]=Postavke ekrana +Comment[ca]=Arranjament de la pantalla +Comment[ca@valencia]=Arranjament de la pantalla +Comment[cs]=Nastavení obrazovky +Comment[csb]=Ùstôw ekranu +Comment[cy]=Gosodiadau Arddangos +Comment[da]=Skærmindstillinger +Comment[de]=Anzeige-Einstellungen +Comment[el]=Ρυθμίσεις οθόνης +Comment[en_GB]=Display Settings +Comment[eo]=Vidigila agordo +Comment[es]=Preferencias de la pantalla +Comment[et]=Monitoride seadistused +Comment[eu]=Pantailaren ezarpenak +Comment[fa]=نمایش تنظیمات +Comment[fi]=Näytön asetukset +Comment[fr]=Configuration de l'affichage +Comment[fy]=Byldskerm ynstellings +Comment[ga]=Socruithe an Scáileáin +Comment[gl]=Configuración da pantalla +Comment[gu]=ડિસ્પ્લે ગોઠવણીઓ +Comment[he]=הגדרות תצוגה +Comment[hi]=प्रकटन विन्यास +Comment[hne]=देखइया सेटिंग +Comment[hr]=Postavke zaslona +Comment[hsb]=Nastajenja za wobrazowku +Comment[hu]=Megjelenési beállítások +Comment[ia]=Monstra preferentias +Comment[id]=Pengaturan Tampilan +Comment[is]=Stillingar skjás +Comment[it]=Impostazioni dello schermo +Comment[ja]=ディスプレイの設定 +Comment[ka]=დისპლეის კონფიგურირება +Comment[kk]=Дисплей баптаулары +Comment[km]=កំណត់​ការ​បង្ហាញ +Comment[kn]=ಪ್ರದರ್ಶಕದ ಸಂಯೋಜನೆಗಳು +Comment[ko]=디스플레이 설정 +Comment[ku]=Mîhengên Dîmenderê +Comment[lt]=Ekrano parametrai +Comment[lv]=Ekrāna parametri +Comment[mai]=जमावट देखाबू +Comment[mk]=Поставувања на приказот +Comment[ml]=പ്രദര്‍ശനത്തിന്റെ സജ്ജീകരണങ്ങള്‍ +Comment[mr]=डिस्प्ले संयोजना +Comment[ms]=Seting Paparan +Comment[nb]=Skjerminnstillinger +Comment[nds]=Dorstellen inrichten +Comment[ne]=सेटिङ प्रदर्शन गर्नुहोस् +Comment[nl]=Beeldscherminstellingen +Comment[nn]=Skjerminnstillingar +Comment[or]=ପ୍ରଦର୍ଶକ ସଂରଚନା +Comment[pa]=ਡਿਸਪਲੇਅ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia ekranu +Comment[pt]=Configuração do ecrã +Comment[pt_BR]=Configurações da tela +Comment[ro]=Configurări afișare +Comment[ru]=Настройка экрана +Comment[se]=Šearbmaheivehusat +Comment[si]=සංදර්ශන සැකසුම් +Comment[sk]=Nastavenie obrazovky +Comment[sl]=Nastavitve zaslona +Comment[sr]=Поставке екрана +Comment[sr@ijekavian]=Поставке екрана +Comment[sr@ijekavianlatin]=Postavke ekrana +Comment[sr@latin]=Postavke ekrana +Comment[sv]=Anpassa bildskärm +Comment[ta]=அமைப்புகளை காட்டு +Comment[te]=ప్రదర్శన అమరికలు +Comment[tg]=Танзимоти экран +Comment[th]=ตั้งค่าต่าง ๆ ของการแสดงผล +Comment[tr]=Ekran Ayarları +Comment[ug]=كۆرۈنمە يۈز تەڭشىكى +Comment[uk]=Налаштування дисплея +Comment[uz]=Displeyning moslamalari +Comment[uz@cyrillic]=Дисплейнинг мосламалари +Comment[vi]=Thiết lập hiển thị +Comment[wa]=Apontiaedjes do Håynaedje +Comment[x-test]=xxDisplay Settingsxx +Comment[zh_CN]=显示设置 +Comment[zh_TW]=顯示設定 +Categories=Qt;KDE;X-KDE-settings-hardware; diff --git a/kcontrol/hardware/display/display.h b/kcontrol/hardware/display/display.h new file mode 100644 index 00000000..7e0c3422 --- /dev/null +++ b/kcontrol/hardware/display/display.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Nadeem Hasan + + 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 DISPLAY_H +#define DISPLAY_H + +#include + +class QTabWidget; + +class KCMDisplay : public KCModule +{ + Q_OBJECT + + public: + KCMDisplay( QWidget *parent, const QVariantList & ); + void load(); + void save(); + + private Q_SLOTS: + void moduleChanged(bool isChanged); + + private: + void addTab( const QString &name, const QString &label ); + + QTabWidget *m_tabs; + QMap m_modules; + bool m_changed; +}; + +#endif // DISPLAY_H + diff --git a/kcontrol/hardware/joystick/CMakeLists.txt b/kcontrol/hardware/joystick/CMakeLists.txt new file mode 100644 index 00000000..6028a2d8 --- /dev/null +++ b/kcontrol/hardware/joystick/CMakeLists.txt @@ -0,0 +1,26 @@ + + + +########### next target ############### + +set(kcm_joystick_PART_SRCS + joystick.cpp + joywidget.cpp + poswidget.cpp + joydevice.cpp + caldialog.cpp ) + + +kde4_add_plugin(kcm_joystick ${kcm_joystick_PART_SRCS}) + + +target_link_libraries(kcm_joystick ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${QT_QTGUI_LIBRARY}) + +install(TARGETS kcm_joystick DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES joystick.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + +# diff --git a/kcontrol/hardware/joystick/Messages.sh b/kcontrol/hardware/joystick/Messages.sh new file mode 100644 index 00000000..1d116ceb --- /dev/null +++ b/kcontrol/hardware/joystick/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/joystick.pot diff --git a/kcontrol/hardware/joystick/caldialog.cpp b/kcontrol/hardware/joystick/caldialog.cpp new file mode 100644 index 00000000..23accecb --- /dev/null +++ b/kcontrol/hardware/joystick/caldialog.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller + * kollix@aon.at + * This file is part of the KDE Control Center Module for Joysticks + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "caldialog.h" +#include "joydevice.h" + +#include +#include +#include + +#include +#include +#include +#include +//-------------------------------------------------------------- + +CalDialog::CalDialog(QWidget *parent, JoyDevice *joy) + : KDialog( parent ), + joydev(joy) +{ + setObjectName( "calibrateDialog" ); + setModal( true ); + setCaption( i18n("Calibration") ); + setButtons( Cancel | User1 ); + setDefaultButton( User1 ); + setButtonGuiItem( User1, KGuiItem( i18n("Next") ) ); + + KVBox *main = new KVBox( this ); + setMainWidget( main ); + + text = new QLabel(main); + text->setMinimumHeight(200); + valueLbl = new QLabel(main); + connect(this,SIGNAL(user1Clicked()),this,SLOT(slotUser1())); +} + +//-------------------------------------------------------------- + +void CalDialog::calibrate() +{ + text->setText(i18n("Please wait a moment to calculate the precision")); + setResult(-1); + show(); + + // calibrate precision (which min,max delivers the joystick in its center position) + // get values through the normal idle procedure + QTimer ti; + ti.setSingleShot(true); // single shot + ti.start(2000); // in 2 seconds + + // normally I'd like to hide the 'Next' button in this step, + // but it does not work - which means: in the steps after the first, + // the 'Next' button does not have the focus (to be the default button) + + do + { + qApp->processEvents(QEventLoop::AllEvents, 2000); + } + while ( ti.isActive() && (result() != QDialog::Rejected) ); + + if ( result() == QDialog::Rejected ) return; // user cancelled the dialog + + joydev->calcPrecision(); + + int i, lastVal; + int min[2], center[2], max[2]; + QString hint; + + for (i = 0; i < joydev->numAxes(); i++) + { + if ( i == 0 ) + hint = i18n("(usually X)"); + else if ( i == 1 ) + hint = i18n("(usually Y)"); + else + hint = ""; + + // minimum position + text->setText(i18n("Calibration is about to check the value range your device delivers.

    " + "Please move axis %1 %2 on your device to the minimum position.

    " + "Press any button on the device or click on the 'Next' button " + "to continue with the next step.
    ", i+1, hint)); + waitButton(i, true, lastVal); + + if ( result() == QDialog::Rejected ) return; // user cancelled the dialog + + joydev->resetMinMax(i, lastVal); + if ( result() != -2 ) waitButton(i, false, lastVal); + + if ( result() == QDialog::Rejected ) return; // user cancelled the dialog + + min[0] = joydev->axisMin(i); + min[1] = joydev->axisMax(i); + + // center position + text->setText(i18n("Calibration is about to check the value range your device delivers.

    " + "Please move axis %1 %2 on your device to the center position.

    " + "Press any button on the device or click on the 'Next' button " + "to continue with the next step.
    ", i+1, hint)); + waitButton(i, true, lastVal); + + if ( result() == QDialog::Rejected ) return; // user cancelled the dialog + + joydev->resetMinMax(i, lastVal); + if ( result() != -2 ) waitButton(i, false, lastVal); + + if ( result() == QDialog::Rejected ) return; // user canceled the dialog + + center[0] = joydev->axisMin(i); + center[1] = joydev->axisMax(i); + + // maximum position + text->setText(i18n("Calibration is about to check the value range your device delivers.

    " + "Please move axis %1 %2 on your device to the maximum position.

    " + "Press any button on the device or click on the 'Next' button " + "to continue with the next step.
    ", i+1, hint)); + waitButton(i, true, lastVal); + + if ( result() == QDialog::Rejected ) return; // user cancelled the dialog + + joydev->resetMinMax(i, lastVal); + if ( result() != -2 ) waitButton(i, false, lastVal); + + if ( result() == QDialog::Rejected ) return; // user canceled the dialog + + max[0] = joydev->axisMin(i); + max[1] = joydev->axisMax(i); + + joydev->calcCorrection(i, min, center, max); + } + + JoyDevice::ErrorCode ret = joydev->applyCalibration(); + + if ( ret != JoyDevice::SUCCESS ) + { + KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error")); + reject(); + } + + KMessageBox::information(this, i18n("You have successfully calibrated your device"), i18n("Calibration Success")); + accept(); +} + +//-------------------------------------------------------------- + +void CalDialog::waitButton(int axis, bool press, int &lastVal) +{ + JoyDevice::EventType type; + int number, value; + bool button = false; + lastVal = 0; + + setResult(-1); + // loop until the user presses a button on the device or on the dialog + do + { + qApp->processEvents(QEventLoop::AllEvents, 100); + + if ( joydev->getEvent(type, number, value) ) + { + button = ( (type == JoyDevice::BUTTON) && (press ? (value == 1) : (value == 0)) ); + + if ( (type == JoyDevice::AXIS) && (number == axis) ) + valueLbl->setText(i18n("Value Axis %1: %2", axis+1, lastVal = value)); + } + } + while ( !button && (result() == -1) ); +} + +//-------------------------------------------------------------- +// Next button + +void CalDialog::slotUser1() +{ + setResult(-2); +} + +//-------------------------------------------------------------- + +#include "caldialog.moc" + +//-------------------------------------------------------------- diff --git a/kcontrol/hardware/joystick/caldialog.h b/kcontrol/hardware/joystick/caldialog.h new file mode 100644 index 00000000..1e4202c5 --- /dev/null +++ b/kcontrol/hardware/joystick/caldialog.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _CALDIALOG_H_ +#define _CALDIALOG_H_ + +#include + +#include + +class JoyDevice; + +// the dialog which tells the user all steps to calibrate the device + +class CalDialog : public KDialog +{ + Q_OBJECT + + public: + CalDialog(QWidget *parent, JoyDevice *joy); + + void calibrate(); + + private: + void waitButton(int axis, bool press, int &lastVal); + + private slots: + virtual void slotUser1(); + + private: + JoyDevice *joydev; + + QLabel *text; + QLabel *valueLbl; +}; + +#endif diff --git a/kcontrol/hardware/joystick/joydevice.cpp b/kcontrol/hardware/joystick/joydevice.cpp new file mode 100644 index 00000000..bbe7527a --- /dev/null +++ b/kcontrol/hardware/joystick/joydevice.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "joydevice.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//-------------------------------------------------------------- + +JoyDevice::JoyDevice(const QString &devicefile) + : devName(devicefile), joyFd(-1), buttons(0), axes(0), + amin(0), amax(0), corr(0), origCorr(0) +{ +} + +//-------------------------------------------------------------- + +QString JoyDevice::errText(ErrorCode code) const +{ + switch ( code ) + { + case SUCCESS: return ""; + + case OPEN_FAILED: + { + return i18n("The given device %1 could not be opened: %2", + devName, strerror(errno)); + } + + case NO_JOYSTICK: + { + return i18n("The given device %1 is not a joystick.", devName); + } + + case ERR_GET_VERSION: + { + return i18n("Could not get kernel driver version for joystick device %1: %2", + devName, strerror(errno)); + } + + case WRONG_VERSION: + { + int version = 0; + int fd = ::open(devName.toLatin1(), O_RDONLY); + if ( fd != -1 ) + { + ::ioctl(fd, JSIOCGVERSION, &version); + ::close(fd); + } + + KLocalizedString loc = ki18n("The current running kernel driver version (%1.%2.%3) is not the one this module was compiled for (%4.%5.%6)."); + loc.subs(version >> 16); + loc.subs((version >> 8) & 0xFF); + loc.subs(version & 0xFF); + loc.subs(JS_VERSION >> 16); + loc.subs((JS_VERSION >> 8) & 0xFF); + loc.subs(JS_VERSION & 0xFF); + return loc.toString(); + } + + case ERR_GET_BUTTONS: + { + return i18n("Could not get number of buttons for joystick device %1: %2", + devName, strerror(errno)); + } + + case ERR_GET_AXES: + { + return i18n("Could not get number of axes for joystick device %1: %2", + devName, strerror(errno)); + } + + case ERR_GET_CORR: + { + return i18n("Could not get calibration values for joystick device %1: %2", + devName, strerror(errno)); + } + + case ERR_RESTORE_CORR: + { + return i18n("Could not restore calibration values for joystick device %1: %2", + devName, strerror(errno)); + } + + case ERR_INIT_CAL: + { + return i18n("Could not initialize calibration values for joystick device %1: %2", + devName, strerror(errno)); + } + + case ERR_APPLY_CAL: + { + return i18n("Could not apply calibration values for joystick device %1: %2", + devName, strerror(errno)); + } + + default: return i18n("internal error - code %1 unknown", int(code)); + } +} + +//-------------------------------------------------------------- + +JoyDevice::ErrorCode JoyDevice::open() +{ + if ( joyFd != -1 ) return JoyDevice::SUCCESS; // already open + + int fd = ::open(devName.toLatin1(), O_RDONLY); + + if ( fd == -1 ) + return JoyDevice::OPEN_FAILED; + + // we could open the devicefile, now check if a joystick is attached + char name[128]; + + if ( ::ioctl(fd, JSIOCGNAME(sizeof(name)), &name) == -1 ) + { + ::close(fd); + return JoyDevice::NO_JOYSTICK; + } + + // check the kernel driver version + int version; + if ( ::ioctl(fd, JSIOCGVERSION, &version) == -1 ) + { + ::close(fd); + return JoyDevice::ERR_GET_VERSION; + } + + if ( version != JS_VERSION ) + { + ::close(fd); + return JoyDevice::WRONG_VERSION; + } + + char bt = 0, ax = 0; + if ( ::ioctl(fd, JSIOCGBUTTONS, &bt) == -1 ) + { + ::close(fd); + return JoyDevice::ERR_GET_BUTTONS; + } + + if ( ::ioctl(fd, JSIOCGAXES, &ax) == -1 ) + { + ::close(fd); + return JoyDevice::ERR_GET_AXES; + } + + struct js_corr *oldCorr = new struct js_corr[ax]; + + if ( ::ioctl(fd, JSIOCGCORR, oldCorr) == -1 ) + { + ::close(fd); + delete [] oldCorr; + return JoyDevice::ERR_GET_CORR; + } + + descr = name; + joyFd = fd; + axes = ax; + buttons = bt; + origCorr = oldCorr; + corr = new struct js_corr[axes]; + + amin = new int[axes]; + amax = new int[axes]; + + int i; + + for (i = 0; i < axes; i++) + resetMinMax(i); + + return JoyDevice::SUCCESS; +} + +//-------------------------------------------------------------- + +void JoyDevice::close() +{ + if ( joyFd == -1 ) return; + + ::close(joyFd); + + joyFd = -1; + descr = ""; + + delete [] amin; + delete [] amax; + amin = 0; + amax = 0; + + delete [] corr; + corr = 0; + delete [] origCorr; + origCorr = 0; +} + +//-------------------------------------------------------------- + +int JoyDevice::axisMin(int axis) const +{ + if ( (axis < 0) || (axis >= axes) ) return 0; + + return amin[axis]; +} + +//-------------------------------------------------------------- + +int JoyDevice::axisMax(int axis) const +{ + if ( (axis < 0) || (axis >= axes) ) return 0; + + return amax[axis]; +} + +//-------------------------------------------------------------- + +JoyDevice::ErrorCode JoyDevice::initCalibration() +{ + if ( joyFd == -1 ) return JoyDevice::ERR_INIT_CAL; + + int i; + + // Reset all current correction values + for (i = 0; i < axes; i++) + { + corr[i].type = JS_CORR_NONE; + corr[i].prec = 0; + } + + if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 ) + return JoyDevice::ERR_INIT_CAL; + + for (i = 0; i < axes; i++) + corr[i].type = JS_CORR_BROKEN; + + return JoyDevice::SUCCESS; +} + +//-------------------------------------------------------------- + +JoyDevice::ErrorCode JoyDevice::applyCalibration() +{ + if ( joyFd == -1 ) return JoyDevice::ERR_APPLY_CAL; + + if ( ::ioctl(joyFd, JSIOCSCORR, corr) == -1 ) + return JoyDevice::ERR_APPLY_CAL; + + return JoyDevice::SUCCESS; +} + +//-------------------------------------------------------------- + +void JoyDevice::resetMinMax(int axis, int value) +{ + amin[axis] = value; + amax[axis] = value; +} + +//-------------------------------------------------------------- + +void JoyDevice::calcPrecision() +{ + if ( !corr ) return; + + int i; + + for (i = 0; i < axes; i++) + { + corr[i].prec = amax[i] - amin[i]; + kDebug() << "Precision for axis: " << i << ": " << corr[i].prec; + } +} + +//-------------------------------------------------------------- + +JoyDevice::ErrorCode JoyDevice::restoreCorr() +{ + if ( joyFd == -1 ) return JoyDevice::SUCCESS; + + if ( ::ioctl(joyFd, JSIOCSCORR, origCorr) == -1 ) + return JoyDevice::ERR_RESTORE_CORR; + else + return JoyDevice::SUCCESS; +} + +//-------------------------------------------------------------- + +JoyDevice::~JoyDevice() +{ + close(); +} + +//-------------------------------------------------------------- + +bool JoyDevice::getEvent(JoyDevice::EventType &type, int &number, int &value) +{ + number = value = 0; + + int ret; + + fd_set readSet; + + FD_ZERO(&readSet); + FD_SET(joyFd, &readSet); + + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + + ret = ::select(joyFd + 1, &readSet, 0, 0, &timeout); + + if ( ret == 1 ) // got an event from the joystick + { + struct js_event e; + + if ( ::read(joyFd, &e, sizeof(struct js_event)) == sizeof(struct js_event) ) + { + if ( e.type & JS_EVENT_BUTTON ) + { + type = JoyDevice::BUTTON; + value = e.value; + number = e.number; + + return true; + } + + if ( e.type & JS_EVENT_AXIS ) + { + type = JoyDevice::AXIS; + value = e.value; + number = e.number; + + // store min, max values + if ( e.value < amin[number] ) amin[number] = e.value; + if ( e.value > amax[number] ) amax[number] = e.value; + + return true; + } + } + } + + return false; // no event +} + +//-------------------------------------------------------------- + +void JoyDevice::calcCorrection(int axis, int *min, int *center, int *max) +{ + const int MIN = 0; + const int MAX = 1; + + double a, b, c, d; + + a = center[MIN]; // inputs.cmin[1]; + b = center[MAX]; // inputs.cmax[1]; + c = 32767.0 / (center[MIN] - min[MAX]); // (inputs.cmin[1] - inputs.cmax[0]); + d = 32767.0 / (max[MIN] - center[MAX]); // (inputs.cmin[2] - inputs.cmax[1]); + + corr[axis].coef[0] = (int)rint(a); + corr[axis].coef[1] = (int)rint(b); + corr[axis].coef[2] = (int)rint(c*16384.0); + corr[axis].coef[3] = (int)rint(d*16384.0); + + kDebug() << "min min: " << min[0] << " max: " << min[1] ; + kDebug() << "max min: " << max[0] << " max: " << max[1] ; + kDebug() << "Correction values for axis: " << axis << ": " + << corr[axis].coef[0] << ", " + << corr[axis].coef[1] << ", " + << corr[axis].coef[2] << ", " + << corr[axis].coef[3] << endl; +} + +//-------------------------------------------------------------- diff --git a/kcontrol/hardware/joystick/joydevice.h b/kcontrol/hardware/joystick/joydevice.h new file mode 100644 index 00000000..4c26581e --- /dev/null +++ b/kcontrol/hardware/joystick/joydevice.h @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _JOYDEVICE_H_ +#define _JOYDEVICE_H_ + +#include + +#include + +#ifdef Q_OS_LINUX +#undef __STRICT_ANSI__ +#include +#define __STRICT_ANSI__ +#endif + +#ifdef Q_OS_FREEBSD +#include +#endif + +// helper class which holds all current values, file descriptor, etc. for +// one device +class JoyDevice +{ + public: + enum ErrorCode + { + SUCCESS, + OPEN_FAILED, + NO_JOYSTICK, + WRONG_VERSION, + ERR_GET_VERSION, + ERR_GET_BUTTONS, + ERR_GET_AXES, + ERR_GET_CORR, + ERR_RESTORE_CORR, + ERR_INIT_CAL, + ERR_APPLY_CAL + }; + + enum EventType + { + BUTTON, + AXIS + }; + + // devicefile to use, e.g. "/dev/js0" + JoyDevice(const QString &devicefile); + ~JoyDevice(); + + // returns one of the error-codes from above + ErrorCode open(); + + // return descriptive error text for given error code + QString errText(ErrorCode code) const; + + int fd() const { return joyFd; } + void close(); + ErrorCode restoreCorr(); + + // return devicefilename from constructor + const QString &device() const { return devName; } + + // descriptive text for this device read from the driver + QString text() const { return descr; } + + int numButtons() const { return buttons; } + int numAxes() const { return axes; } + int axisMin(int axis) const; + int axisMax(int axis) const; + + // read next event from device; returns true if there was an event during the short timeout + bool getEvent(JoyDevice::EventType &type, int &number, int &value); + + // methods for calibration + ErrorCode initCalibration(); // must be called first + void calcPrecision(); + + void resetMinMax(int axis, int value = 0); + + // calculate correction values + // min[2], center[2], max[2], index 0 == minimum, index 1 == maximum + void calcCorrection(int axis, int *min, int *center, int *max); + ErrorCode applyCalibration(); + + private: + QString devName; // device filename + QString descr; // descriptive text + int joyFd; + + int buttons; + int axes; + int *amin; // axes min values + int *amax; // axes max values + + struct js_corr *corr; // calibration values during the calib. steps + struct js_corr *origCorr; // original calibration correction values +}; + +#endif diff --git a/kcontrol/hardware/joystick/joystick.cpp b/kcontrol/hardware/joystick/joystick.cpp new file mode 100644 index 00000000..7009643d --- /dev/null +++ b/kcontrol/hardware/joystick/joystick.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "joystick.h" +#include "joywidget.h" +#include "joydevice.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +//--------------------------------------------------------------------------------------------- + +K_PLUGIN_FACTORY(JoystickFactory, registerPlugin();) +K_EXPORT_PLUGIN(JoystickFactory("joystick")) + +//--------------------------------------------------------------------------------------------- + +Joystick::Joystick(QWidget *parent, const QVariantList &) + : KCModule(JoystickFactory::componentData(), parent) +{ + setButtons(Help); + setAboutData(new KAboutData("kcmjoystick", 0, ki18n("KDE Joystick Control Module"), "1.0", + ki18n("KDE System Settings Module to test Joysticks"), + KAboutData::License_GPL, ki18n("(c) 2004, Martin Koller"), + KLocalizedString(), "kollix@aon.at")); + + setQuickHelp( i18n("

    Joystick

    " + "This module helps to check if your joystick is working correctly.
    " + "If it delivers wrong values for the axes, you can try to solve this with " + "the calibration.
    " + "This module tries to find all available joystick devices " + "by checking /dev/js[0-4] and /dev/input/js[0-4]
    " + "If you have another device file, enter it in the combobox.
    " + "The Buttons list shows the state of the buttons on your joystick, the Axes list " + "shows the current value for all axes.
    " + "NOTE: the current Linux device driver (Kernel 2.4, 2.6) can only autodetect" + "
      " + "
    • 2-axis, 4-button joystick
    • " + "
    • 3-axis, 4-button joystick
    • " + "
    • 4-axis, 4-button joystick
    • " + "
    • Saitek Cyborg 'digital' joysticks
    • " + "
    " + "(For details you can check your Linux source/Documentation/input/joystick.txt)" + )); + + joyWidget = new JoyWidget(this); + + QVBoxLayout *top = new QVBoxLayout(this); + top->setMargin(0); + top->setSpacing(KDialog::spacingHint()); + top->addWidget(joyWidget); +} + +//--------------------------------------------------------------------------------------------- + +void Joystick::load() +{ + joyWidget->init(); +} + +//--------------------------------------------------------------------------------------------- + +void Joystick::defaults() +{ + joyWidget->resetCalibration(); + + emit changed(true); +} + +//--------------------------------------------------------------------------------------------- + +#include "joystick.moc" diff --git a/kcontrol/hardware/joystick/joystick.desktop b/kcontrol/hardware/joystick/joystick.desktop new file mode 100644 index 00000000..a0aef4ac --- /dev/null +++ b/kcontrol/hardware/joystick/joystick.desktop @@ -0,0 +1,226 @@ +[Desktop Entry] +Exec=kcmshell4 joystick + +X-DocPath=kcontrol/joystick/index.html +Terminal=false +Type=Service +Icon=preferences-desktop-gaming +Categories=Qt;KDE;X-KDE-settings-hardware; + +X-KDE-ServiceTypes=KCModule +X-KDE-Library=kcm_joystick +X-KDE-Test-Module=true +X-KDE-System-Settings-Parent-Category=input-devices +X-KDE-ParentApp=kcontrol +X-KDE-Weight=70 + +Comment=Joystick settings +Comment[ar]=إعدادات عصى الألعاب +Comment[ast]=Preferencies del Joystick +Comment[be@latin]=Nałady džojstyka +Comment[bg]=Настройки на джойстик +Comment[bn]=জয়স্টিক সেটিংস +Comment[bn_IN]=জয়-স্টিক সংক্রান্ত বৈশিষ্ট্য +Comment[bs]=Postavke džojstika +Comment[ca]=Arranjament de la palanca de control +Comment[ca@valencia]=Arranjament de la palanca de control +Comment[cs]=Nastavení joysticku +Comment[csb]=Nastôw joysticka +Comment[da]=Joystick-indstillinger +Comment[de]=Joystick-Einstellungen +Comment[el]=Ρυθμίσεις χειριστηρίου +Comment[en_GB]=Joystick settings +Comment[eo]=Ludbastonaj agordoj +Comment[es]=Preferencias del Joystick +Comment[et]=Juhtpuldi seadistused +Comment[eu]=Kontrol-palankaren ezarpenak +Comment[fi]=Peliohjainten asetukset +Comment[fy]=Joystick ynstellings +Comment[ga]=Socruithe an luamháin stiúrtha +Comment[gl]=Configuración do joystick +Comment[gu]=જોયસ્ટિક ગોઠવણીઓ +Comment[he]=הגדרות ג'ויסטיק +Comment[hi]=जॉयस्टिक विन्यास +Comment[hne]=जायस्टिक सेटिंग +Comment[hr]=Postavke igraće palice (joysticka) +Comment[hsb]=Nastajenja za joystick +Comment[hu]=Botkormány-beállítások +Comment[ia]=Preferentias de Joystick +Comment[id]=Pengaturan tongkat ria +Comment[is]=Stillingar stýripinna +Comment[kk]=Джойстик параметрлері +Comment[km]=ការ​កំណត់ Joystick +Comment[kn]=ಅಂಕೆಗೋಲು (ಜಾಯ್ ಸ್ಟಿಕ್) ಸಂಯೋಜನೆಗಳು +Comment[ko]=조이스틱 설정 +Comment[ku]=Mîhengên joystik +Comment[lt]=Valdymo svirties nustatymai +Comment[lv]=Kursorsviras iestatījumi +Comment[mai]=ज्वायस्टिक सेटिंग +Comment[mk]=Поставувања за палката за играње +Comment[ml]=ജോയ്സ്റ്റിക് സജ്ജീകരണങ്ങള്‍ +Comment[mr]=जॉयस्टीक् संयोजना +Comment[nb]=Styrespakinnstillinger +Comment[nds]=Joystick instellen +Comment[nl]=Joystick instellen +Comment[nn]=Innstillingar for styrespakar +Comment[or]=Joystick ସଂରଚନା +Comment[pa]=ਜਾਏਸਟਿੱਕ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia joysticka +Comment[pt]=Configuração do 'joystick' +Comment[pt_BR]=Configurações do joystick +Comment[ro]=Configurări joystick +Comment[ru]=Настройка джойстика +Comment[si]=Joystick සැකසුම් +Comment[sk]=Nastavenie joysticku +Comment[sl]=Nastavitve igralne palice +Comment[sr]=Поставке џојстика +Comment[sr@ijekavian]=Поставке џојстика +Comment[sr@ijekavianlatin]=Postavke džojstika +Comment[sr@latin]=Postavke džojstika +Comment[sv]=Anpassa styrspak +Comment[ta]=ஜாய்ஸ்டிக் அமைப்புகள் +Comment[te]=Joystick అమరికలు +Comment[tg]=Танзимоти ҷойстик +Comment[th]=ตั้งค่าต่าง ๆ ของแท่งควบคุม +Comment[tr]=Oyun çubuğu ayarları +Comment[ug]=ئويۇن دەستە تەڭشەكلەر +Comment[uk]=Параметри джойстика +Comment[vi]=Thiết lập tay điều khiển trò chơi +Comment[wa]=Apontiaedje del djîsse di djeu +Comment[x-test]=xxJoystick settingsxx +Comment[zh_CN]=游戏杆设置 +Comment[zh_TW]=搖桿設定 +Name=Joystick +Name[af]=Joystick +Name[ar]=عصا الألعاب +Name[ast]=Joystick +Name[be]=Джойстык +Name[be@latin]=Džojstyk +Name[bg]=Джойстик +Name[bn]=জয়-স্টিক +Name[bn_IN]=জয়-স্টিক +Name[br]=Lanker-c'hoari +Name[bs]=Džojstik +Name[ca]=Palanca de control +Name[ca@valencia]=Palanca de control +Name[cs]=Joystick +Name[csb]=Joystick +Name[cy]=Ffôn reoli +Name[da]=Joystick +Name[de]=Joystick +Name[el]=Χειριστήριο +Name[en_GB]=Joystick +Name[eo]=Stirstango +Name[es]=Joystick +Name[et]=Juhtpult +Name[eu]=Kontrol-palanka +Name[fa]=اهرم کنترل +Name[fi]=Peliohjain +Name[fr]=Joystick +Name[fy]=Joystick +Name[ga]=Luamhán Stiúrtha +Name[gl]=Joystick +Name[gu]=જોયસ્ટિક +Name[he]=ג'ויסטיק +Name[hi]=जॉयस्टिक +Name[hne]=जायस्टिक +Name[hr]=Igraća palica +Name[hsb]=Joystick +Name[hu]=Botkormány +Name[ia]=Joystick +Name[id]=Tongkat Ria +Name[is]=Stýripinnar +Name[it]=Joystick +Name[ja]=ジョイスティック +Name[ka]=ჯოისტიკი +Name[kk]=Джойстик +Name[km]=យ៉យស្ទីក +Name[kn]=ಅಂಕೆಗೋಲು (ಜಾಯ್ ಸ್ಟಿಕ್) +Name[ko]=조이스틱 +Name[ku]=Joystîk +Name[lt]=Valdymo svirtis +Name[lv]=Kursorsvira +Name[mai]=जायस्टिक +Name[mk]=Џојстик +Name[ml]=ജോയ്സ്റ്റിക് +Name[mr]=जॉयस्टिक +Name[ms]=Kayu Bidik +Name[nb]=Styrespak +Name[nds]=Joystick +Name[ne]=जोयस्टिक +Name[nl]=Joystick +Name[nn]=Styrespak +Name[or]=Joystick +Name[pa]=ਜਾਏਸਟਿੱਕ +Name[pl]=Joystick +Name[pt]=Joystick +Name[pt_BR]=Joystick +Name[ro]=Joystick +Name[ru]=Джойстик +Name[se]=Stivrensággi +Name[si]=ජෝයිස්ටික් +Name[sk]=Joystick +Name[sl]=Igralna palica +Name[sr]=Џојстик +Name[sr@ijekavian]=Џојстик +Name[sr@ijekavianlatin]=Džojstik +Name[sr@latin]=Džojstik +Name[sv]=Styrspak +Name[ta]=இயக்கு கருவி +Name[te]=జాయ్ స్టిక్ +Name[tg]=Ҷойстик +Name[th]=แท่งควบคุม +Name[tr]=Oyun Çubuğu +Name[ug]=ئويۇن دەستىسى(رول) +Name[uk]=Джойстик +Name[uz]=Joystik +Name[uz@cyrillic]=Жойстик +Name[vi]=Tay điều khiển +Name[wa]=Djîsse di djeu +Name[xh]=Uvuyo +Name[x-test]=xxJoystickxx +Name[zh_CN]=游戏杆 +Name[zh_TW]=搖桿 + +X-KDE-Keywords=joystick,gamepad,controller +X-KDE-Keywords[bs]=dzojstik +X-KDE-Keywords[ca]=palanca de control,comandament de joc,controlador +X-KDE-Keywords[ca@valencia]=palanca de control,comandament de joc,controlador +X-KDE-Keywords[da]=joystick,gamepad,controller +X-KDE-Keywords[de]=Joystick,Gamepad,Spielsteuerung +X-KDE-Keywords[el]=χειριστήριο,πληκτρολόγιο παιχνιδιών,ελεγκτής +X-KDE-Keywords[en_GB]=joystick,gamepad,controller +X-KDE-Keywords[es]=joystick,gamepad,controlador +X-KDE-Keywords[et]=juhtpult,juhtkang,kontroller +X-KDE-Keywords[eu]=kontrol-palanka,joko-teklatua,kontroladorea +X-KDE-Keywords[fi]=peliohjain,sauvaohjain,ohjain +X-KDE-Keywords[fr]=joystick, gamepad, contrôleur +X-KDE-Keywords[ga]=luamhán stiúrtha,ceap cluiche,rialaitheoir +X-KDE-Keywords[gl]=joystick, gamepad, controlador +X-KDE-Keywords[hu]=botkormány,játéktábla,vezérlő +X-KDE-Keywords[ia]=joystick,gamepad,controlator +X-KDE-Keywords[it]=joystick,gamepad,controller +X-KDE-Keywords[kk]=joystick,gamepad,controller +X-KDE-Keywords[km]=joystick,gamepad,controller +X-KDE-Keywords[ko]=joystick,gamepad,controller,조이스틱,컨트롤러 +X-KDE-Keywords[mr]=जॉयस्टिक, गेमपॅड, कन्ट्रोलर +X-KDE-Keywords[nb]=styrespak,spillepute,kontroller +X-KDE-Keywords[nds]=Stüerknüppel,Speelknüppel,Speelstüer-Reedschap,Speelstüern,Stüern,Kontroller,Speelkuntrull +X-KDE-Keywords[nl]=joystick,spelpad,besturing +X-KDE-Keywords[pa]=ਜਾਏਸਟਿੱਕ,ਗੇਮਪੈਡ,ਕੰਟਰੋਲਰ +X-KDE-Keywords[pl]=joystick,gamepad,kontroler +X-KDE-Keywords[pt]=joystick,comando,controlador +X-KDE-Keywords[pt_BR]=joystick,gamepad,controle +X-KDE-Keywords[ru]=joystick,gamepad,controller,джойстик,геймпад,контроллер +X-KDE-Keywords[sk]=joystick,gamepad,ovládač +X-KDE-Keywords[sl]=igralna palica,igralni plošček,igralne naprave,krmilnik +X-KDE-Keywords[sr]=joystick,gamepad,controller,џојстик,гејмпад,управљач +X-KDE-Keywords[sr@ijekavian]=joystick,gamepad,controller,џојстик,гејмпад,управљач +X-KDE-Keywords[sr@ijekavianlatin]=joystick,gamepad,controller,džojstik,gejmpad,upravljač +X-KDE-Keywords[sr@latin]=joystick,gamepad,controller,džojstik,gejmpad,upravljač +X-KDE-Keywords[sv]=styrspak,handkontroll,styrning +X-KDE-Keywords[tr]=oyun çubuğu, denetleyici,joystick, oyun oynama kolu +X-KDE-Keywords[uk]=joystick,gamepad,джойстик,геймпад,контролер +X-KDE-Keywords[x-test]=xxjoystick,gamepad,controllerxx +X-KDE-Keywords[zh_CN]=joystick,gamepad,controller,手柄,摇杆,控制器 +X-KDE-Keywords[zh_TW]=joystick,gamepad,controller diff --git a/kcontrol/hardware/joystick/joystick.h b/kcontrol/hardware/joystick/joystick.h new file mode 100644 index 00000000..fedf3a4b --- /dev/null +++ b/kcontrol/hardware/joystick/joystick.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2003 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _JOYSTICK_H_ +#define _JOYSTICK_H_ + +#define KDE3_SUPPORT +#include +#undef KDE3_SUPPORT + +class JoyWidget; + + +/* on FreeBSD the header already has a struct joystick, so we can't use the same name here, Alex */ +class Joystick: public KCModule +{ + Q_OBJECT + + public: + explicit Joystick(QWidget *parent = 0, const QVariantList &list = QVariantList()); + + virtual void load(); + virtual void defaults(); + + private: + JoyWidget *joyWidget; +}; + +#endif diff --git a/kcontrol/hardware/joystick/joywidget.cpp b/kcontrol/hardware/joystick/joywidget.cpp new file mode 100644 index 00000000..8c4cfa5d --- /dev/null +++ b/kcontrol/hardware/joystick/joywidget.cpp @@ -0,0 +1,418 @@ +/*************************************************************************** + * Copyright (C) 2003,2012 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "joywidget.h" +#include "joydevice.h" +#include "poswidget.h" +#include "caldialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//-------------------------------------------------------------- +static QString PRESSED = I18N_NOOP("PRESSED"); +//-------------------------------------------------------------- + +class TableWidget : public QTableWidget +{ + public: + TableWidget(int row, int col) : QTableWidget(row, col) {} + + virtual QSize sizeHint() const + { + return QSize(150, 100); // return a smaller size than the Qt default(256, 192) + } +}; + +//-------------------------------------------------------------- + +JoyWidget::JoyWidget(QWidget *parent) + : QWidget(parent), idle(0), joydev(0) +{ + QVBoxLayout *mainVbox = new QVBoxLayout(this); + mainVbox->setSpacing(KDialog::spacingHint()); + mainVbox->setMargin(0); + + // create area to show an icon + message if no joystick was detected + { + messageBox = new KMessageWidget(this); + messageBox->setMessageType(KMessageWidget::Error); + messageBox->setCloseButtonVisible(false); + messageBox->hide(); + + mainVbox->addWidget(messageBox); + } + + QHBoxLayout *devHbox = new QHBoxLayout; + devHbox->setSpacing(KDialog::spacingHint()); + devHbox->addWidget(new QLabel(i18n("Device:"))); + devHbox->addWidget(device = new KComboBox(true)); + + device->setInsertPolicy(QComboBox::NoInsert); + KUrlCompletion *kc = new KUrlCompletion(KUrlCompletion::FileCompletion); + device->setCompletionObject(kc); + device->setAutoDeleteCompletionObject(true); + connect(device, SIGNAL(activated(QString)), this, SLOT(deviceChanged(QString))); + connect(device, SIGNAL(returnPressed(QString)), this, SLOT(deviceChanged(QString))); + devHbox->setStretchFactor(device, 3); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->setSpacing(KDialog::spacingHint()); + + mainVbox->addLayout(devHbox); + mainVbox->addLayout(hbox); + + QVBoxLayout *vboxLeft = new QVBoxLayout; + vboxLeft->setSpacing(KDialog::spacingHint()); + vboxLeft->addWidget(new QLabel(i18nc("Cue for deflection of the stick", "Position:"))); + vboxLeft->addWidget(xyPos = new PosWidget); + + vboxLeft->addWidget(trace = new QCheckBox(i18n("Show trace"))); + connect(trace, SIGNAL(toggled(bool)), this, SLOT(traceChanged(bool))); + + QVBoxLayout *vboxMid = new QVBoxLayout; + vboxMid->setSpacing(KDialog::spacingHint()); + + QVBoxLayout *vboxRight = new QVBoxLayout; + vboxRight->setSpacing(KDialog::spacingHint()); + + // calculate the column width we need + QFontMetrics fm(font()); + int colWidth = qMax(fm.width(PRESSED), fm.width("-32767")) + 10; // -32767 largest string + + vboxMid->addWidget(new QLabel(i18n("Buttons:"))); + buttonTbl = new TableWidget(0, 1); + buttonTbl->setSelectionMode(QAbstractItemView::NoSelection); + buttonTbl->setEditTriggers(QAbstractItemView::NoEditTriggers); + buttonTbl->setHorizontalHeaderLabels(QStringList(i18n("State"))); + buttonTbl->setSortingEnabled(false); + buttonTbl->horizontalHeader()->setClickable(false); + buttonTbl->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + buttonTbl->horizontalHeader()->resizeSection(0, colWidth); + buttonTbl->verticalHeader()->setClickable(false); + vboxMid->addWidget(buttonTbl); + + vboxRight->addWidget(new QLabel(i18n("Axes:"))); + axesTbl = new TableWidget(0, 1); + axesTbl->setSelectionMode(QAbstractItemView::NoSelection); + axesTbl->setEditTriggers(QAbstractItemView::NoEditTriggers); + axesTbl->setHorizontalHeaderLabels(QStringList(i18n("Value"))); + axesTbl->setSortingEnabled(false); + axesTbl->horizontalHeader()->setClickable(false); + axesTbl->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + axesTbl->horizontalHeader()->resizeSection(0, colWidth); + axesTbl->verticalHeader()->setClickable(false); + vboxRight->addWidget(axesTbl); + + hbox->addLayout(vboxLeft); + hbox->addLayout(vboxMid); + hbox->addLayout(vboxRight); + + // calibrate button + calibrate = new QPushButton(i18n("Calibrate")); + connect(calibrate, SIGNAL(clicked()), this, SLOT(calibrateDevice())); + calibrate->setEnabled(false); + + vboxLeft->addStretch(); + vboxLeft->addWidget(calibrate); + + // set up a timer for idle processing of joystick events + idle = new QTimer(this); + connect(idle, SIGNAL(timeout()), this, SLOT(checkDevice())); + + // check which devicefiles we have + init(); +} + +//-------------------------------------------------------------- + +JoyWidget::~JoyWidget() +{ + delete joydev; +} + +//-------------------------------------------------------------- + +void JoyWidget::init() +{ + // check which devicefiles we have + int i; + bool first = true; + char dev[30]; + + device->clear(); + buttonTbl->setRowCount(0); + axesTbl->setRowCount(0); + + for (i = 0; i < 5; i++) // check the first 5 devices + { + sprintf(dev, "/dev/js%d", i); // first look in /dev + JoyDevice *joy = new JoyDevice(dev); + + if ( joy->open() != JoyDevice::SUCCESS ) + { + delete joy; + sprintf(dev, "/dev/input/js%d", i); // then look in /dev/input + joy = new JoyDevice(dev); + + if ( joy->open() != JoyDevice::SUCCESS ) + { + delete joy; + continue; // try next number + } + } + + // we found one + + device->addItem(QString("%1 (%2)").arg(joy->text()).arg(joy->device())); + + // display values for first device + if ( first ) + { + showDeviceProps(joy); // this sets the joy object into this->joydev + first = false; + } + else + delete joy; + } + + /* KDE 4: Remove this check(and i18n) when all KCM wrappers properly test modules */ + if ( device->count() == 0 ) + { + messageBox->show(); + messageBox->setText(QString("%1").arg( + i18n("No joystick device automatically found on this computer.
    " + "Checks were done in /dev/js[0-4] and /dev/input/js[0-4]
    " + "If you know that there is one attached, please enter the correct device file."))); + } +} + +//-------------------------------------------------------------- + +void JoyWidget::traceChanged(bool state) +{ + xyPos->showTrace(state); +} + +//-------------------------------------------------------------- + +void JoyWidget::restoreCurrDev() +{ + if ( !joydev ) // no device open + { + device->setEditText(""); + calibrate->setEnabled(false); + } + else + { + // try to find the current open device in the combobox list + int index = device->findText(joydev->device(), Qt::MatchContains); + + if ( index == -1 ) // the current open device is one the user entered (not in the list) + device->setEditText(joydev->device()); + else + device->setEditText(device->itemText(index)); + } +} + +//-------------------------------------------------------------- + +void JoyWidget::deviceChanged(const QString &dev) +{ + // find "/dev" in given string + int start, stop; + QString devName; + + if ( (start = dev.indexOf("/dev")) == -1 ) + { + KMessageBox::sorry(this, + i18n("The given device name is invalid (does not contain /dev).\n" + "Please select a device from the list or\n" + "enter a device file, like /dev/js0."), i18n("Unknown Device")); + + restoreCurrDev(); + return; + } + + if ( (stop = dev.indexOf(")", start)) != -1 ) // seems to be text selected from our list + devName = dev.mid(start, stop - start); + else + devName = dev.mid(start); + + if ( joydev && (devName == joydev->device()) ) return; // user selected the current device; ignore it + + JoyDevice *joy = new JoyDevice(devName); + JoyDevice::ErrorCode ret = joy->open(); + + if ( ret != JoyDevice::SUCCESS ) + { + KMessageBox::error(this, joy->errText(ret), i18n("Device Error")); + + delete joy; + restoreCurrDev(); + return; + } + + showDeviceProps(joy); +} + +//-------------------------------------------------------------- + +void JoyWidget::showDeviceProps(JoyDevice *joy) +{ + joydev = joy; + + buttonTbl->setRowCount(joydev->numButtons()); + + axesTbl->setRowCount(joydev->numAxes()); + if ( joydev->numAxes() >= 2 ) + { + axesTbl->setVerticalHeaderItem(0, new QTableWidgetItem(i18n("1(x)"))); + axesTbl->setVerticalHeaderItem(1, new QTableWidgetItem(i18n("2(y)"))); + } + + calibrate->setEnabled(true); + idle->start(0); + + // make both tables use the same space for header; this looks nicer + // TODO: Don't know how to do this in Qt4; the following does no longer work + // Probably by setting a sizeHint for every single header item ? + /* + buttonTbl->verticalHeader()->setFixedWidth(qMax(buttonTbl->verticalHeader()->width(), + axesTbl->verticalHeader()->width())); + axesTbl->verticalHeader()->setFixedWidth(buttonTbl->verticalHeader()->width()); + */ +} + +//-------------------------------------------------------------- + +void JoyWidget::checkDevice() +{ + if ( !joydev ) return; // no open device yet + + JoyDevice::EventType type; + int number, value; + + if ( !joydev->getEvent(type, number, value) ) + return; + + if ( type == JoyDevice::BUTTON ) + { + if ( ! buttonTbl->item(number, 0) ) + buttonTbl->setItem(number, 0, new QTableWidgetItem()); + + if ( value == 0 ) // button release + buttonTbl->item(number, 0)->setText("-"); + else + buttonTbl->item(number, 0)->setText(PRESSED); + } + + if ( type == JoyDevice::AXIS ) + { + if ( number == 0 ) // x-axis + xyPos->changeX(value); + + if ( number == 1 ) // y-axis + xyPos->changeY(value); + + if ( ! axesTbl->item(number, 0) ) + axesTbl->setItem(number, 0, new QTableWidgetItem()); + + axesTbl->item(number, 0)->setText(QString("%1").arg(int(value))); + } +} + +//-------------------------------------------------------------- + +void JoyWidget::calibrateDevice() +{ + if ( !joydev ) return; // just to be save + + JoyDevice::ErrorCode ret = joydev->initCalibration(); + + if ( ret != JoyDevice::SUCCESS ) + { + KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error")); + return; + } + + if ( KMessageBox::messageBox(this, KMessageBox::Information, + i18n("Calibration is about to check the precision.

    " + "Please move all axes to their center position and then " + "do not touch the joystick anymore.

    " + "Click OK to start the calibration.
    "), + i18n("Calibration"), + KStandardGuiItem::ok(), KStandardGuiItem::cancel()) != KMessageBox::Ok ) + return; + + idle->stop(); // stop the joystick event getting; this must be done inside the calibrate dialog + + CalDialog dlg(this, joydev); + dlg.calibrate(); + + // user canceled somewhere during calibration, therefore the device is in a bad state + if ( dlg.result() == QDialog::Rejected ) + joydev->restoreCorr(); + + idle->start(0); // continue with event getting +} + +//-------------------------------------------------------------- + +void JoyWidget::resetCalibration() +{ + if ( !joydev ) return; // just to be save + + JoyDevice::ErrorCode ret = joydev->restoreCorr(); + + if ( ret != JoyDevice::SUCCESS ) + { + KMessageBox::error(this, joydev->errText(ret), i18n("Communication Error")); + } + else + { + KMessageBox::information(this, + i18n("Restored all calibration values for joystick device %1.", joydev->device()), + i18n("Calibration Success")); + } +} + +//-------------------------------------------------------------- + +#include "joywidget.moc" diff --git a/kcontrol/hardware/joystick/joywidget.h b/kcontrol/hardware/joystick/joywidget.h new file mode 100644 index 00000000..74e99d17 --- /dev/null +++ b/kcontrol/hardware/joystick/joywidget.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2003,2005,2006 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _JOYWIDGET_H_ +#define _JOYWIDGET_H_ + +#include + +class JoyDevice; + +class PosWidget; +class QLabel; +class QTableWidget; +class QTimer; +class KComboBox; +class KMessageWidget; +class QPushButton; +class QCheckBox; +class QFrame; + +// the widget which displays all buttons, values, etc. +class JoyWidget : public QWidget +{ + Q_OBJECT + + public: + JoyWidget(QWidget *parent = 0); + + ~JoyWidget(); + + // initialize list of possible devices and open the first available + void init(); + + public Q_SLOTS: + // reset calibration values to their value when this KCM was started + void resetCalibration(); + + private Q_SLOTS: + void checkDevice(); + void deviceChanged(const QString &dev); + void traceChanged(bool); + void calibrateDevice(); + + private: + void showDeviceProps(JoyDevice *joy); // fill widgets with given device parameters + void restoreCurrDev(); // restores the content of the combobox to reflect the current open device + + private: + KMessageWidget *messageBox; // in case of no device, show here a message rather than in a dialog + KComboBox *device; + PosWidget *xyPos; + QTableWidget *buttonTbl; + QTableWidget *axesTbl; + QCheckBox *trace; + QPushButton *calibrate; + + QTimer *idle; + + JoyDevice *joydev; +}; + +#endif diff --git a/kcontrol/hardware/joystick/poswidget.cpp b/kcontrol/hardware/joystick/poswidget.cpp new file mode 100644 index 00000000..50b3b0fb --- /dev/null +++ b/kcontrol/hardware/joystick/poswidget.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2003,2005,2006 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "poswidget.h" + +#include + +#define XY_WIDTH 220 +#define MARK_WIDTH 10 +#define MAX_POINTS 500 + +//----------------------------------------------------------------- + +PosWidget::PosWidget(QWidget *parent) + : QWidget(parent), x(0), y(0), trace(false) +{ + setMinimumSize(XY_WIDTH, XY_WIDTH); + setMaximumSize(XY_WIDTH, XY_WIDTH); + + QPalette palette; + palette.setColor(backgroundRole(), Qt::white); + setPalette(palette); +} + +//----------------------------------------------------------------- + +void PosWidget::paintEvent(QPaintEvent *) +{ + QPainter paint(this); + + // draw a frame + paint.drawRect(0, 0, width()-1, height()-1); + paint.setPen(Qt::gray); + + // draw a center grid + paint.drawLine(XY_WIDTH/2, 1, + XY_WIDTH/2, XY_WIDTH - 2); + + paint.drawLine(1, XY_WIDTH/2, + XY_WIDTH - 2, XY_WIDTH/2); + + // draw the trace of previous points + if ( trace ) + { + paint.setPen(Qt::black); + + for (int i = 0; i < tracePoints.count()-2; i++) + paint.drawLine(tracePoints[i], tracePoints[i+1]); + + if ( tracePoints.count() > 0 ) + paint.drawLine(tracePoints[tracePoints.count()-1], QPoint(x, y)); + } + + // draw the current position marker + paint.setPen(Qt::blue); + + paint.drawLine(x - MARK_WIDTH/2, y - MARK_WIDTH/2, + x + MARK_WIDTH/2, y + MARK_WIDTH/2); + + paint.drawLine(x - MARK_WIDTH/2, y + MARK_WIDTH/2, + x + MARK_WIDTH/2, y - MARK_WIDTH/2); +} + +//----------------------------------------------------------------- + +void PosWidget::changeX(int newX) +{ + // transform coordinates from joystick to widget coordinates + newX = int((newX/65535.0)*XY_WIDTH + XY_WIDTH/2); + + if ( x == newX ) return; // avoid unnecessary redraw + + if ( trace ) + { + tracePoints.append(QPoint(x, y)); + if ( tracePoints.count() == MAX_POINTS ) + tracePoints.removeFirst(); + } + + x = newX; + update(); +} + +//----------------------------------------------------------------- + +void PosWidget::changeY(int newY) +{ + // transform coordinates from joystick to widget coordinates + newY = int((newY/65535.0)*XY_WIDTH + XY_WIDTH/2); + + if ( y == newY ) return; // avoid unnecessary redraw + + if ( trace ) + { + tracePoints.append(QPoint(x, y)); + if ( tracePoints.count() == MAX_POINTS ) + tracePoints.removeFirst(); + } + + y = newY; + update(); +} + +//----------------------------------------------------------------- + +void PosWidget::showTrace(bool t) +{ + trace = t; + tracePoints.clear(); + + update(); +} + +//----------------------------------------------------------------- + +#include "poswidget.moc" diff --git a/kcontrol/hardware/joystick/poswidget.h b/kcontrol/hardware/joystick/poswidget.h new file mode 100644 index 00000000..671cfedf --- /dev/null +++ b/kcontrol/hardware/joystick/poswidget.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2003,2005,2006 by Martin Koller * + * kollix@aon.at * + * This file is part of the KDE Control Center Module for Joysticks * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _POSWIDGET_H_ +#define _POSWIDGET_H_ + +#include +#include +class QPaintEvent; + +/** + Widget to display the joystick-selected (x,y) position +*/ +class PosWidget : public QWidget +{ + Q_OBJECT + + public: + PosWidget(QWidget *parent = 0); + + void changeX(int x); + void changeY(int y); + + // define if a trace of the moving joystick shall be displayed + // changing it will erase all previous marks from the widget + void showTrace(bool t); + + protected: + virtual void paintEvent(QPaintEvent *); + + private: + int x, y; + bool trace; + QList tracePoints; +}; + +#endif diff --git a/kcontrol/input/AUTHORS b/kcontrol/input/AUTHORS new file mode 100644 index 00000000..2ab4353d --- /dev/null +++ b/kcontrol/input/AUTHORS @@ -0,0 +1,7 @@ +Mouse & Keyboard Configuration Modules: + + Pat Dowler (dowler@pt1B1106.FSH.UVic.CA) + +Conversion to kcontrol applet: + + Matthias Hoelzer (hoelzer@physik.uni-wuerzburg.de) diff --git a/kcontrol/input/CMakeLists.txt b/kcontrol/input/CMakeLists.txt new file mode 100644 index 00000000..394c551e --- /dev/null +++ b/kcontrol/input/CMakeLists.txt @@ -0,0 +1,107 @@ + +add_subdirectory( pics ) +KDE4_NO_ENABLE_FINAL(input) + +macro_optional_find_package(USB) +macro_bool_to_01(LIBUSB_FOUND HAVE_LIBUSB) +set_package_properties(USB PROPERTIES DESCRIPTION "User level access to USB devices" + URL "http://libusb.sourceforge.net" + TYPE OPTIONAL + PURPOSE "Provides Logitech mouse support in KControl." + ) + +configure_file (config-kcontrol-input.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcontrol-input.h ) + +include_directories( ${KDE4_INCLUDES} ) + + +if (LIBUSB_FOUND) + include_directories( ${LIBUSB_INCLUDE_DIR} ) +endif (LIBUSB_FOUND) + + +if(X11_Xcursor_FOUND) + set( libnoinst_SRCS + xcursor/themepage.cpp + xcursor/thememodel.cpp + xcursor/cursortheme.cpp + xcursor/xcursortheme.cpp + xcursor/previewwidget.cpp + xcursor/itemdelegate.cpp + xcursor/sortproxymodel.cpp + ../krdb/krdb.cpp ) + kde4_add_ui_files( libnoinst_SRCS xcursor/themepage.ui ) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/xcursor/ ) +else(X11_Xcursor_FOUND) + set( libnoinst_SRCS core/themepage.cpp ) + include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/core/ ) +endif(X11_Xcursor_FOUND) + + + +########### next target ############### + +set(kapplymousetheme_SRCS kapplymousetheme.cpp ) + + +kde4_add_executable(kapplymousetheme ${kapplymousetheme_SRCS}) + +target_link_libraries(kapplymousetheme +${KDE4_KDEUI_LIBS} ${X11_Xrender_LIB} ${X11_X11_LIB}) +if (X11_Xcursor_FOUND) + target_link_libraries(kapplymousetheme ${X11_Xcursor_LIB}) +endif (X11_Xcursor_FOUND) + +install(TARGETS kapplymousetheme ${INSTALL_TARGETS_DEFAULT_ARGS}) + + +########### next target ############### + +set(kcm_input_PART_SRCS mouse.cpp main.cpp logitechmouse.cpp) + + +kde4_add_ui_files(kcm_input_PART_SRCS kmousedlg.ui logitechmouse_base.ui ) + +kde4_add_plugin(kcm_input ${kcm_input_PART_SRCS}) + + +target_link_libraries(kcm_input ${KDE4_KIO_LIBS} ${X11_LIBRARIES}) +if (LIBUSB_FOUND) + target_link_libraries(kcm_input ${LIBUSB_LIBRARIES}) +endif (LIBUSB_FOUND) +if (X11_Xcursor_FOUND) + target_link_libraries(kcm_input ${X11_Xcursor_LIB}) +endif (X11_Xcursor_FOUND) +if (X11_Xfixes_FOUND) + target_link_libraries(kcm_input ${X11_Xfixes_LIB}) +endif (X11_Xfixes_FOUND) + +install(TARGETS kcm_input DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### next target ############### + +set(kcm_cursortheme_PART_SRCS kcmcursortheme.cpp ${libnoinst_SRCS}) + +kde4_add_plugin(kcm_cursortheme ${kcm_cursortheme_PART_SRCS}) + + +target_link_libraries(kcm_cursortheme ${KDE4_KIO_LIBS} ${KDE4_KNEWSTUFF3_LIBS} ${X11_LIBRARIES}) + +if (X11_Xcursor_FOUND) + target_link_libraries(kcm_cursortheme ${X11_Xcursor_LIB}) +endif (X11_Xcursor_FOUND) +if (X11_Xfixes_FOUND) + target_link_libraries(kcm_cursortheme ${X11_Xfixes_LIB}) +endif (X11_Xfixes_FOUND) + +install(TARGETS kcm_cursortheme DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES mouse.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES cursortheme.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES cursor_large_black.pcf.gz cursor_large_white.pcf.gz cursor_small_white.pcf.gz DESTINATION ${DATA_INSTALL_DIR}/kcminput ) +install( FILES xcursor/xcursor.knsrc DESTINATION ${CONFIG_INSTALL_DIR} ) + diff --git a/kcontrol/input/ChangeLog b/kcontrol/input/ChangeLog new file mode 100644 index 00000000..2d9b8d54 --- /dev/null +++ b/kcontrol/input/ChangeLog @@ -0,0 +1,11 @@ +2002-07-01 Fabian Wolf + * added option to select a white cursor + +2000-03-14 David Faure + + * mouse.cpp: Added global settings for SC/DC/AutoSelect/ChangeCursor + * mousedefaults.h: New file, to store default values + +1998-11-30 Alex Zepeda + + * Makefile.am: Move all the icons into pics/ && pics/mini/ diff --git a/kcontrol/input/Messages.sh b/kcontrol/input/Messages.sh new file mode 100644 index 00000000..b039def2 --- /dev/null +++ b/kcontrol/input/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC `find -name \*.ui` >> rc.cpp || exit 11 +$XGETTEXT *.cpp */*.cpp -o $podir/kcminput.pot +rm -f rc.cpp diff --git a/kcontrol/input/config-kcontrol-input.h.cmake b/kcontrol/input/config-kcontrol-input.h.cmake new file mode 100644 index 00000000..ce817d8e --- /dev/null +++ b/kcontrol/input/config-kcontrol-input.h.cmake @@ -0,0 +1,3 @@ +/* Defined if you have libusb */ +#cmakedefine HAVE_LIBUSB 1 + diff --git a/kcontrol/input/consoleUserPerms b/kcontrol/input/consoleUserPerms new file mode 100755 index 00000000..015df642 --- /dev/null +++ b/kcontrol/input/consoleUserPerms @@ -0,0 +1,42 @@ +#!/bin/bash +# +# /etc/hotplug/usb/consoleUserPerms +# +# Sets up newly plugged in USB device so that the user who owns +# the console according to pam_console can access it from user space +# +# Note that for this script to work, you'll need all of the following: +# a) a line in the file /etc/hotplug/usb.usermap or another usermap file +# in /etc/hotplug/usb/ that corresponds to the device you are using. +# b) a setup using pam_console creates the respective lock files +# containing the name of the respective user. You can check for that +# by executing "echo `cat /var/{run,lock}/console.lock`" and +# verifying the appropriate user is mentioned somewhere there. +# c) a Linux kernel supporting hotplug and usbdevfs +# d) the hotplug package (http://linux-hotplug.sourceforge.net/) +# +# In the usermap file, the first field "usb module" should be named +# "consoleUserPerms" to invoke this script. +# + +if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ] +then + # New code, using lock files instead of copying /dev/console permissions + # This also works with non-kdm logins (e.g. on a virtual terminal) + # Idea and code from Nalin Dahyabhai + if [ -f /var/run/console.lock ] + then + CONSOLEOWNER=`cat /var/run/console.lock` + elif [ -f /var/lock/console.lock ] + then + CONSOLEOWNER=`cat /var/lock/console.lock` + else + CONSOLEOWNER= + fi + if [ -n "$CONSOLEOWNER" ] + then + chmod 0000 "${DEVICE}" + chown "$CONSOLEOWNER" "${DEVICE}" + chmod 0600 "${DEVICE}" + fi +fi diff --git a/kcontrol/input/core/bitmaps.h b/kcontrol/input/core/bitmaps.h new file mode 100644 index 00000000..1a8e272e --- /dev/null +++ b/kcontrol/input/core/bitmaps.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2003 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 __BITMAPS_H +#define __BITMAPS_H + + +static const char* const arrow_large_black_xpm[] = { +"24 24 3 1", +"# c None", +"a c #000000", +". c #ffffff", +"#####..#################", +"#####.a.################", +"#####.aa.###############", +"#####.aaa.##############", +"#####.aaaa.#############", +"#####.aaaaa.############", +"#####.aaaaaa.###########", +"#####.aaaaaaa.##########", +"#####.aaaaaaaa.#########", +"#####.aaaaaaaaa.########", +"#####.aaaaaaaaaa.#######", +"#####.aaaaaaaaaaa.######", +"#####.aaaaaaaaaaaa.#####", +"#####.aaaaaaaa....######", +"#####.aaaaaaa.##########", +"#####.aaa.aaaa.#########", +"#####.aa.#.aaa.#########", +"#####.a.##.aaaa.########", +"#####..####.aaa.########", +"###########.aaaa.#######", +"############.aaa.#######", +"############.aaa.#######", +"#############...########", +"########################"}; + + +static const char* const arrow_small_black_xpm[]={ +"24 24 3 1", +"# c None", +"a c #000000", +". c #ffffff", +"########################", +"########################", +"########################", +"########################", +"#######..###############", +"#######.a.##############", +"#######.aa.#############", +"#######.aaa.############", +"#######.aaaa.###########", +"#######.aaaaa.##########", +"#######.aaaaaa.#########", +"#######.aaaaaaa.########", +"#######.aaaaaaaa.#######", +"#######.aaaaa....#######", +"#######.aa.aa.##########", +"#######.a.#.aa.#########", +"#######..##.aa.#########", +"############.aa.########", +"############.aa.########", +"#############..#########", +"########################", +"########################", +"########################", +"########################"}; + + +static const char* const arrow_large_white_xpm[] = { +"24 24 3 1", +"# c None", +"a c #ffffff", +". c #000000", +"#####..#################", +"#####.a.################", +"#####.aa.###############", +"#####.aaa.##############", +"#####.aaaa.#############", +"#####.aaaaa.############", +"#####.aaaaaa.###########", +"#####.aaaaaaa.##########", +"#####.aaaaaaaa.#########", +"#####.aaaaaaaaa.########", +"#####.aaaaaaaaaa.#######", +"#####.aaaaaaaaaaa.######", +"#####.aaaaaaaaaaaa.#####", +"#####.aaaaaaaa....######", +"#####.aaaaaaa.##########", +"#####.aaa.aaaa.#########", +"#####.aa.#.aaa.#########", +"#####.a.##.aaaa.########", +"#####..####.aaa.########", +"###########.aaaa.#######", +"############.aaa.#######", +"############.aaa.#######", +"#############...########", +"########################"}; + + +static const char* const arrow_small_white_xpm[]={ +"24 24 3 1", +"# c None", +"a c #ffffff", +". c #000000", +"########################", +"########################", +"########################", +"########################", +"#######..###############", +"#######.a.##############", +"#######.aa.#############", +"#######.aaa.############", +"#######.aaaa.###########", +"#######.aaaaa.##########", +"#######.aaaaaa.#########", +"#######.aaaaaaa.########", +"#######.aaaaaaaa.#######", +"#######.aaaaa....#######", +"#######.aa.aa.##########", +"#######.a.#.aa.#########", +"#######..##.aa.#########", +"############.aa.########", +"############.aa.########", +"#############..#########", +"########################", +"########################", +"########################", +"########################"}; + +#endif diff --git a/kcontrol/input/core/themepage.cpp b/kcontrol/input/core/themepage.cpp new file mode 100644 index 00000000..5e8ffc42 --- /dev/null +++ b/kcontrol/input/core/themepage.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2003 Fredrik Höglund + * + * Based on the large cursor code written by Rik Hemsley, + * Copyright (c) 2000 Rik Hemsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "themepage.h" +#include +#include "themepage.moc" + +#include "bitmaps.h" + + + +ThemePage::ThemePage( QWidget* parent, const char* name ) + : QWidget( parent ) +{ + setObjectName(name); + QBoxLayout *layout = new QVBoxLayout( this ); + layout->setMargin( KDialog::marginHint() ); + layout->setSpacing( KDialog::spacingHint() ); + + layout->addWidget(new QLabel( i18n("Select the cursor theme you want to use:"), this )); + + // Create the theme list view + listview = new QTreeWidget( this ); + QStringList lstHeader; + lstHeader<setHeaderLabels( lstHeader ); + listview->setSelectionMode( QAbstractItemView::SingleSelection ); + listview->setRootIsDecorated( false ); + connect( listview, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)) + , this, SLOT(selectionChanged(QTreeWidgetItem*,QTreeWidgetItem*)) ); + layout->addWidget( listview ); + insertThemes(); +} + + +ThemePage::~ThemePage() +{ +} + + +void ThemePage::selectionChanged( QTreeWidgetItem*current,QTreeWidgetItem*previous ) +{ + Q_UNUSED( previous ); + selectedTheme = current->data( 0, Qt::UserRole + 1 ).toString(); + emit changed( selectedTheme != currentTheme ); +} + + +void ThemePage::save() +{ + if ( currentTheme == selectedTheme ) + return; + + bool whiteCursor = selectedTheme.right( 5 ) == "White"; + bool largeCursor = selectedTheme.left( 5 ) == "Large"; + + KConfig config( "kcminputrc" ); + KConfigGroup c( &config, "Mouse" ); + c.writeEntry( "LargeCursor", largeCursor ); + c.writeEntry( "WhiteCursor", whiteCursor ); + + currentTheme = selectedTheme; + + fixCursorFile(); + + KMessageBox::information( this, i18n("You have to restart KDE for these " + "changes to take effect."), i18n("Cursor Settings Changed"), + "CursorSettingsChanged" ); +} + + +void ThemePage::load() +{ + bool largeCursor, whiteCursor; + + KConfig config( "kcminputrc" ); + KConfigGroup c( &config, "Mouse" ); + largeCursor = c.readEntry( "LargeCursor", false); + whiteCursor = c.readEntry( "WhiteCursor", false); + + if ( largeCursor ) + currentTheme = whiteCursor ? "LargeWhite" : "LargeBlack"; + else + currentTheme = whiteCursor ? "SmallWhite" : "SmallBlack"; + + selectedTheme = currentTheme; + for ( int i = 0;i topLevelItemCount();++i ) + { + QTreeWidgetItem *item = listview->topLevelItem( i ); + if ( item && item->data(0, Qt::UserRole + 1 ) == currentTheme ) + { + listview->setCurrentItem( item ); + } + } +} + + +void ThemePage::defaults() +{ + currentTheme = selectedTheme = "SmallBlack"; + for ( int i = 0;i topLevelItemCount();++i ) + { + QTreeWidgetItem *item = listview->topLevelItem( i ); + if ( item && item->data(0, Qt::UserRole + 1 ) == currentTheme ) + { + listview->setCurrentItem( item ); + } + } +} + + +void ThemePage::insertThemes() +{ + QList lstChildren; + QTreeWidgetItem *item = new QTreeWidgetItem(listview ); + + item->setData( 0, Qt::DisplayRole,i18n("Small black") ); + item->setData( 1, Qt::DisplayRole, i18n("Small black cursors") ); + item->setData( 0, Qt::DecorationRole, QPixmap( arrow_small_black_xpm ) ); + item->setData( 0, Qt::UserRole + 1,"SmallBlack" ); + lstChildren<setData( 0, Qt::DisplayRole, i18n("Large black") ); + item->setData( 1, Qt::DisplayRole, i18n("Large black cursors") ); + item->setData( 0, Qt::DecorationRole, QPixmap( arrow_large_black_xpm ) ); + item->setData( 0, Qt::UserRole + 1,"LargeBlack" ); + lstChildren<setData( 0, Qt::DisplayRole, i18n("Small white") ); + item->setData( 1, Qt::DisplayRole, i18n("Small white cursors") ); + item->setData( 0, Qt::DecorationRole, QPixmap(arrow_small_white_xpm ) ); + item->setData( 0, Qt::UserRole + 1,"SmallWhite" ); + lstChildren<setData( 0, Qt::DisplayRole, i18n("Large white") ); + item->setData( 1, Qt::DisplayRole, i18n("Large white cursors") ); + item->setData( 0, Qt::DecorationRole, QPixmap( arrow_large_white_xpm ) ); + item->setData( 0, Qt::UserRole + 1, "LargeWhite" ); + lstChildren<addTopLevelItems( lstChildren ); +} + + +void ThemePage::fixCursorFile() +{ + // Make sure we have the 'font' resource dir registered and can find the + // override dir. + // + // Next, if the user wants large cursors, copy the font + // cursor_large.pcf.gz to (localkdedir)/share/fonts/override/cursor.pcf.gz. + // Else remove the font cursor.pcf.gz from (localkdedir)/share/fonts/override. + // + // Run mkfontdir to update fonts.dir in that dir. + + KGlobal::dirs()->addResourceType( "font", 0, "share/fonts/" ); + KIO::mkdir( QDir::homePath() + "/.fonts/kde-override" ); + QString overrideDir = QDir::homePath() + "/.fonts/kde-override/"; + + KUrl installedFont; + installedFont.setPath( overrideDir + "cursor.pcf.gz" ); + + if ( currentTheme == "SmallBlack" ) + KIO::NetAccess::del( installedFont, this ); + else { + KUrl source; + + if ( currentTheme == "LargeBlack" ) + source.setPath( KStandardDirs::locate("data", "kcminput/cursor_large_black.pcf.gz") ); + else if ( currentTheme == "LargeWhite" ) + source.setPath( KStandardDirs::locate("data", "kcminput/cursor_large_white.pcf.gz") ); + else if ( currentTheme == "SmallWhite" ) + source.setPath( KStandardDirs::locate("data", "kcminput/cursor_small_white.pcf.gz") ); + + KIO::Job* job = KIO::file_copy( source, installedFont, -1, KIO::Overwrite ); + job->exec(); + } + + QString cmd = KGlobal::dirs()->findExe( "mkfontdir" ); + if ( !cmd.isEmpty() ) + { + KProcess p; + p << cmd << overrideDir; + p.execute(); + } +} + +// vim: set noet ts=4 sw=4: diff --git a/kcontrol/input/core/themepage.h b/kcontrol/input/core/themepage.h new file mode 100644 index 00000000..b264422a --- /dev/null +++ b/kcontrol/input/core/themepage.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2003 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 __THEMEPAGE_H +#define __THEMEPAGE_H + +class QTreeWidget; +class QTreeWidgetItem; + +class ThemePage : public QWidget +{ + Q_OBJECT + + public: + explicit ThemePage( QWidget* parent = 0, const char* name = 0 ); + ~ThemePage(); + + // Called by the KCM + void save(); + void load(); + void defaults(); + + Q_SIGNALS: + void changed( bool ); + + private Q_SLOTS: + void selectionChanged( QTreeWidgetItem *,QTreeWidgetItem* ); + + private: + void insertThemes(); + void fixCursorFile(); + + QTreeWidget *listview; + QString currentTheme, selectedTheme; +}; + +#endif // __THEMEPAGE_H + +// vim: set noet ts=4 sw=4: diff --git a/kcontrol/input/cursor_large.bdf b/kcontrol/input/cursor_large.bdf new file mode 100644 index 00000000..24118928 --- /dev/null +++ b/kcontrol/input/cursor_large.bdf @@ -0,0 +1,4447 @@ +STARTFONT 2.1 +FONT cursor +SIZE 47 78 78 +FONTBOUNDINGBOX 45 42 -21 -23 +STARTPROPERTIES 13 +COPYRIGHT "(C) 2000 Rik Hemsley " +POINT_SIZE 470 +FONT "cursor" +WEIGHT 10 +RESOLUTION 107 +RESOLUTION_X 78 +RESOLUTION_Y 78 +X_HEIGHT -1 +QUAD_WIDTH 20 +DEFAULT_CHAR 0 +FONT_ASCENT 23 +FONT_DESCENT 24 +_XMBDFED_INFO "Edited with xmbdfed 4.3." +ENDPROPERTIES +CHARS 154 +STARTCHAR D +ENCODING 0 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 1 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C002 +ENCODING 2 +SWIDTH 1139 0 +DWIDTH 58 0 +BBX 12 21 -10 -22 +BITMAP +0010 +0030 +0070 +00F0 +01F0 +03F0 +07F0 +0FF0 +1FF0 +3FF0 +7FF0 +FFF0 +0FF0 +07F0 +0F70 +0E30 +1E10 +1C00 +3C00 +3800 +3800 +ENDCHAR +STARTCHAR C003 +ENCODING 3 +SWIDTH 1414 0 +DWIDTH 72 0 +BBX 14 23 -11 -23 +BITMAP +000C +001C +003C +007C +00FC +01FC +03FC +07FC +0FFC +1FFC +3FFC +7FFC +FFFC +7FFC +07FC +0FFC +0FBC +1F9C +1F0C +3F00 +3E00 +3E00 +1C00 +ENDCHAR +STARTCHAR C004 +ENCODING 4 +SWIDTH 137 0 +DWIDTH 7 0 +BBX 11 15 -4 -2 +BITMAP +FFE0 +FFE0 +FFE0 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +FFE0 +7FC0 +3F80 +1F00 +0E00 +0400 +ENDCHAR +STARTCHAR C004 +ENCODING 5 +SWIDTH 176 0 +DWIDTH 9 0 +BBX 15 17 -6 -3 +BITMAP +3FF8 +7FFC +7FFC +7FFC +3FF8 +07C0 +07C0 +07C0 +07C0 +FFFE +7FFC +3FF8 +1FF0 +0FE0 +07C0 +0380 +0100 +ENDCHAR +STARTCHAR C004 +ENCODING 6 +SWIDTH 137 0 +DWIDTH 7 0 +BBX 11 15 -4 -16 +BITMAP +0400 +0E00 +1F00 +3F80 +7FC0 +FFE0 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +FFE0 +FFE0 +FFE0 +ENDCHAR +STARTCHAR C004 +ENCODING 7 +SWIDTH 176 0 +DWIDTH 9 0 +BBX 15 17 -6 -17 +BITMAP +0100 +0380 +07C0 +0FE0 +1FF0 +3FF8 +7FFC +FFFE +07C0 +07C0 +07C0 +07C0 +3FF8 +7FFC +7FFC +7FFC +3FF8 +ENDCHAR +STARTCHAR D +ENCODING 8 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 9 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 10 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 11 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C014 +ENCODING 12 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 21 0 -3 +BITMAP +E00000 +E00000 +E00000 +E00100 +E00380 +E087C0 +E0CF80 +E0FF00 +E0FE00 +E0FC00 +E0FC00 +E0FE00 +E0FF00 +E00000 +E00000 +E00000 +E00000 +E00000 +FFFFF8 +FFFFF8 +FFFFF8 +ENDCHAR +STARTCHAR C014 +ENCODING 13 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 23 23 -1 -4 +BITMAP +700000 +F80000 +F80000 +F80080 +F881C0 +F8C3E0 +F8E7F0 +F8FFE0 +F8FFC0 +F8FF80 +F8FF00 +F8FF00 +F8FF80 +F8FFC0 +F8FFE0 +F80000 +F80000 +F80000 +FFFFFC +FFFFFE +FFFFFE +FFFFFE +FFFFFC +ENDCHAR +STARTCHAR C014 +ENCODING 14 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 21 -18 -3 +BITMAP +000038 +000038 +000038 +040038 +0E0038 +1F0838 +0F9838 +07F838 +03F838 +01F838 +01F838 +03F838 +07F838 +000038 +000038 +000038 +000038 +000038 +FFFFF8 +FFFFF8 +FFFFF8 +ENDCHAR +STARTCHAR C014 +ENCODING 15 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 23 23 -19 -4 +BITMAP +00001C +00003E +00003E +02003E +07023E +0F863E +1FCE3E +0FFE3E +07FE3E +03FE3E +01FE3E +01FE3E +03FE3E +07FE3E +0FFE3E +00003E +00003E +00003E +7FFFFE +FFFFFE +FFFFFE +FFFFFE +7FFFFE +ENDCHAR +STARTCHAR C020 +ENCODING 16 +SWIDTH 216 0 +DWIDTH 11 0 +BBX 19 20 -8 -3 +BITMAP +00E000 +00E000 +00E000 +00E000 +00E000 +00E000 +00E000 +0FFE00 +07FC00 +03F800 +01F000 +00E000 +004000 +000000 +000000 +000000 +000000 +FFFFE0 +FFFFE0 +FFFFE0 +ENDCHAR +STARTCHAR C020 +ENCODING 17 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 21 22 -9 -4 +BITMAP +007000 +00F800 +00F800 +00F800 +00F800 +00F800 +00F800 +1FFFC0 +0FFF80 +07FF00 +03FE00 +01FC00 +00F800 +007000 +002000 +000000 +000000 +7FFFF0 +FFFFF8 +FFFFF8 +FFFFF8 +7FFFF0 +ENDCHAR +STARTCHAR D +ENCODING 18 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 19 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 20 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 21 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C026 +ENCODING 22 +SWIDTH 137 0 +DWIDTH 7 0 +BBX 11 20 -4 -21 +BITMAP +0400 +0400 +0E00 +0E00 +1F00 +1F00 +3F80 +3F80 +7FC0 +7FC0 +FFE0 +CE60 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0400 +ENDCHAR +STARTCHAR C026 +ENCODING 23 +SWIDTH 157 0 +DWIDTH 8 0 +BBX 13 22 -5 -22 +BITMAP +0200 +0700 +0700 +0F80 +0F80 +1FC0 +1FC0 +3FE0 +3FE0 +7FF0 +7FF0 +FFF8 +FFF8 +6FB0 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0700 +0200 +ENDCHAR +STARTCHAR D +ENCODING 24 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 25 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 26 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 27 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 28 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 29 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR quotedbl +ENCODING 30 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 24 23 -10 -13 +BITMAP +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +002800 +FFC7FF +FF83FF +FFC7FF +002800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +ENDCHAR +STARTCHAR numbersign +ENCODING 31 +SWIDTH 294 0 +DWIDTH 15 0 +BBX 26 25 -11 -14 +BITMAP +001C0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +7FF7FF80 +FFE3FFC0 +FFC1FFC0 +FFE3FFC0 +7FF7FF80 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +001C0000 +ENDCHAR +STARTCHAR D +ENCODING 32 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 33 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 24 23 -10 -13 +BITMAP +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +002800 +FFC7FF +FF83FF +FFC7FF +002800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 294 0 +DWIDTH 15 0 +BBX 26 25 -11 -14 +BITMAP +001C0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +7FF7FF80 +FFE3FFC0 +FFC1FFC0 +FFE3FFC0 +7FF7FF80 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +001C0000 +ENDCHAR +STARTCHAR D +ENCODING 36 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 37 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 38 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 39 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 40 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 41 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 15 23 -6 -13 +BITMAP +0100 +0380 +07C0 +0FE0 +1FF0 +3FF8 +7BBC +F39E +638C +0380 +0380 +0380 +0380 +0380 +E38C +F39E +7BBC +3FF8 +1FF0 +0FE0 +07C0 +0380 +0100 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 196 0 +DWIDTH 10 0 +BBX 17 25 -7 -14 +BITMAP +008000 +01C000 +03E000 +07F000 +0FF800 +1FFC00 +3FFE00 +7FFF00 +FFFF80 +7BEF00 +33E600 +03E000 +03E000 +03E000 +33E600 +7BEF00 +FFFF80 +7FFF00 +3FFE00 +1FFC00 +0FF800 +07F000 +03E000 +01C000 +008000 +ENDCHAR +STARTCHAR C002 +ENCODING 44 +SWIDTH 1139 0 +DWIDTH 58 0 +BBX 12 21 -10 -22 +BITMAP +0010 +0030 +0070 +00F0 +01F0 +03F0 +07F0 +0FF0 +1FF0 +3FF0 +7FF0 +FFF0 +0FF0 +07F0 +0F70 +0E30 +1E10 +1C00 +3C00 +3800 +3800 +ENDCHAR +STARTCHAR C003 +ENCODING 45 +SWIDTH 1414 0 +DWIDTH 72 0 +BBX 14 23 -11 -23 +BITMAP +000C +001C +003C +007C +00FC +01FC +03FC +07FC +0FFC +1FFC +3FFC +7FFC +FFFC +7FFC +07FC +0FFC +0FBC +1F9C +1F0C +3F00 +3E00 +3E00 +1C00 +ENDCHAR +STARTCHAR C002 +ENCODING 46 +SWIDTH 1139 0 +DWIDTH 58 0 +BBX 12 21 -10 -22 +BITMAP +0010 +0030 +0070 +00F0 +01F0 +03F0 +07F0 +0FF0 +1FF0 +3FF0 +7FF0 +FFF0 +0FF0 +07F0 +0F70 +0E30 +1E10 +1C00 +3C00 +3800 +3800 +ENDCHAR +STARTCHAR C003 +ENCODING 47 +SWIDTH 1414 0 +DWIDTH 72 0 +BBX 14 23 -11 -23 +BITMAP +000C +001C +003C +007C +00FC +01FC +03FC +07FC +0FFC +1FFC +3FFC +7FFC +FFFC +7FFC +07FC +0FFC +0FBC +1F9C +1F0C +3F00 +3E00 +3E00 +1C00 +ENDCHAR +STARTCHAR D +ENCODING 48 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 49 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR 2 +ENCODING 50 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 23 -9 -13 +BITMAP +00F800 +C3FE00 +E7FF80 +FFC3C0 +DF00E0 +CE0060 +C60020 +C30000 +FF8000 +FF8000 +000000 +000000 +000000 +000FF8 +000FF8 +000618 +200318 +300398 +3C07D8 +1E1FF8 +0FFF38 +03FE18 +00F800 +ENDCHAR +STARTCHAR 2 +ENCODING 51 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 23 -9 -13 +BITMAP +00F800 +C3FE00 +E7FF80 +FFC3C0 +FF00E0 +FE0060 +FE0020 +FF0000 +FF8000 +FF8000 +000000 +000000 +000000 +000FF8 +000FF8 +0007F8 +2003F8 +3003F8 +3C07F8 +1E1FF8 +0FFF38 +03FE18 +00F800 +ENDCHAR +STARTCHAR 4 +ENCODING 52 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 27 27 -12 -15 +BITMAP +00040000 +000E0000 +001F0000 +003F8000 +007FC000 +007FC000 +000E0000 +000E0000 +000E0000 +0C0E0600 +1C0E0700 +3C0E0780 +7FFFFFC0 +FFFFFFE0 +7FFFFFC0 +3C0E0780 +1C0E0700 +0C0E0600 +000E0000 +000E0000 +000E0000 +007FC000 +007FC000 +003F8000 +001F0000 +000E0000 +00040000 +ENDCHAR +STARTCHAR 4 +ENCODING 53 +SWIDTH 314 0 +DWIDTH 16 0 +BBX 29 29 -13 -16 +BITMAP +00020000 +00070000 +000F8000 +001FC000 +003FE000 +007FF000 +007FF000 +003FE000 +000F8000 +060F8300 +0F0F8780 +1F0F87C0 +3FFFFFE0 +7FFFFFF0 +FFFFFFF8 +7FFFFFF0 +3FFFFFE0 +1F0F87C0 +0F0F8780 +060F8300 +000F8000 +003FE000 +007FF000 +007FF000 +003FE000 +001FC000 +000F8000 +00070000 +00020000 +ENDCHAR +STARTCHAR D +ENCODING 54 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 55 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 56 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 57 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR less +ENCODING 58 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 23 21 -21 -21 +BITMAP +001FFC +00FFFE +01E006 +0307FC +060FF8 +0C0060 +0C07C0 +0C0FC0 +0C0060 +1E07C0 +330FC0 +6180C0 +C0C780 +C06F00 +603C00 +318C00 +199800 +0C3000 +066000 +03C000 +018000 +ENDCHAR +STARTCHAR equal +ENCODING 59 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 23 21 -21 -21 +BITMAP +001FFC +00FFFE +01FFFE +03FFFC +07FFF8 +0FFFE0 +0FFFC0 +0FFFC0 +0FFFE0 +1FFFC0 +3FFFC0 +7FFFC0 +FFFF80 +FFFF00 +7FFC00 +3FFC00 +1FF800 +0FF000 +07E000 +03C000 +018000 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 962 0 +DWIDTH 49 0 +BBX 23 21 1 -21 +BITMAP +7FF000 +FFFE00 +C00F00 +7FC180 +3FE0C0 +0C0060 +07C060 +07E060 +0C0060 +07C0F0 +07E198 +06030C +03C606 +01EC06 +00780C +006318 +003330 +001860 +000CC0 +000780 +000300 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 923 0 +DWIDTH 47 0 +BBX 23 21 1 -21 +BITMAP +7FF000 +FFFE00 +FFFF00 +7FFF80 +3FFFC0 +0FFFE0 +07FFE0 +07FFE0 +0FFFE0 +07FFF0 +07FFF8 +07FFFC +03FFFE +01FFFE +007FFC +007FF8 +003FF0 +001FE0 +000FC0 +000780 +000300 +ENDCHAR +STARTCHAR D +ENCODING 62 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 63 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 64 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 65 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 66 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 67 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C020 +ENCODING 70 +SWIDTH 216 0 +DWIDTH 11 0 +BBX 20 19 0 -11 +BITMAP +E00000 +E00000 +E00000 +E00000 +E00800 +E01800 +E03800 +E07800 +E0FFF0 +E1FFF0 +E0FFF0 +E07800 +E03800 +E01800 +E00800 +E00000 +E00000 +E00000 +E00000 +ENDCHAR +STARTCHAR C020 +ENCODING 71 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 22 21 -1 -12 +BITMAP +700000 +F80000 +F80000 +F80200 +F80600 +F80E00 +F81E00 +F83E00 +F87FF8 +F8FFFC +F9FFFC +F8FFFC +F87FF8 +F83E00 +F81E00 +F80E00 +F80600 +F80200 +F80000 +F80000 +700000 +ENDCHAR +STARTCHAR D +ENCODING 72 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 73 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 74 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 75 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 76 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 77 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 78 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 79 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 80 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 81 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 82 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 83 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 84 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 85 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +D800 +CC00 +CC00 +6600 +6600 +3300 +3300 +1980 +1980 +0CC0 +0CC0 +0660 +0660 +03F0 +0330 +01F0 +00E0 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FC00 +7E00 +7E00 +3F00 +3F00 +1F80 +1F80 +0FC0 +0FC0 +07E0 +07E0 +03F0 +03F0 +01F0 +00E0 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 353 0 +DWIDTH 18 0 +BBX 17 17 1 -2 +BITMAP +003F80 +007F00 +00FC00 +01F000 +03C000 +07FE00 +01FC00 +03F000 +07C000 +0F0000 +1FF000 +07E000 +0F8000 +1E0000 +380000 +600000 +800000 +ENDCHAR +STARTCHAR X +ENCODING 89 +SWIDTH 392 0 +DWIDTH 20 0 +BBX 20 19 0 -3 +BITMAP +001FF0 +003FE0 +007FC0 +00FF80 +01FE00 +03FFC0 +07FF80 +0FFF00 +03FE00 +07F800 +0FFE00 +1FFC00 +3FF800 +0FF000 +0FC000 +3F0000 +7C0000 +F00000 +C00000 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 15 15 -6 -9 +BITMAP +0380 +0380 +0380 +0380 +0380 +0380 +FFFE +FFFE +FFFE +0380 +0380 +0380 +0380 +0380 +0380 +ENDCHAR +STARTCHAR Z +ENCODING 91 +SWIDTH 196 0 +DWIDTH 10 0 +BBX 17 17 -7 -10 +BITMAP +01C000 +03E000 +03E000 +03E000 +03E000 +03E000 +7FFF00 +FFFF80 +FFFF80 +FFFF80 +7FFF00 +03E000 +03E000 +03E000 +03E000 +03E000 +01C000 +ENDCHAR +STARTCHAR D +ENCODING 92 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 93 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C002 +ENCODING 94 +SWIDTH 1139 0 +DWIDTH 58 0 +BBX 12 21 -10 -22 +BITMAP +0010 +0030 +0070 +00F0 +01F0 +03F0 +07F0 +0FF0 +1FF0 +3FF0 +7FF0 +FFF0 +0FF0 +07F0 +0F70 +0E30 +1E10 +1C00 +3C00 +3800 +3800 +ENDCHAR +STARTCHAR C003 +ENCODING 95 +SWIDTH 1414 0 +DWIDTH 72 0 +BBX 14 23 -11 -23 +BITMAP +000C +001C +003C +007C +00FC +01FC +03FC +07FC +0FFC +1FFC +3FFC +7FFC +FFFC +7FFC +07FC +0FFC +0FBC +1F9C +1F0C +3F00 +3E00 +3E00 +1C00 +ENDCHAR +STARTCHAR C020 +ENCODING 96 +SWIDTH 216 0 +DWIDTH 11 0 +BBX 20 19 -17 -11 +BITMAP +000070 +000070 +000070 +000070 +010070 +018070 +01C070 +01E070 +FFF070 +FFF870 +FFF070 +01E070 +01C070 +018070 +010070 +000070 +000070 +000070 +000070 +ENDCHAR +STARTCHAR C020 +ENCODING 97 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 22 21 -18 -12 +BITMAP +000038 +00007C +00007C +01007C +01807C +01C07C +01E07C +01F07C +7FF87C +FFFC7C +FFFE7C +FFFC7C +7FF87C +01F07C +01E07C +01C07C +01807C +01007C +00007C +00007C +000038 +ENDCHAR +STARTCHAR D +ENCODING 98 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 99 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 100 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 101 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 102 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 103 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 104 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 105 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 157 0 +DWIDTH 8 0 +BBX 13 20 -5 -2 +BITMAP +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +FFF8 +7FF0 +3FE0 +1FC0 +0F80 +0700 +0200 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 176 0 +DWIDTH 9 0 +BBX 15 22 -6 -3 +BITMAP +06C0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +7FFC +FFFE +7FFC +3FF8 +1FF0 +0FE0 +07C0 +0380 +0100 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 25 13 -12 -7 +BITMAP +02002000 +06003000 +0E003800 +1E003C00 +3FFFFE00 +7FFFFF00 +FE003F80 +7FFFFF00 +3FFFFE00 +1E003C00 +0E003800 +06003000 +02002000 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 274 0 +DWIDTH 14 0 +BBX 27 15 -13 -8 +BITMAP +01001000 +03803800 +07803C00 +0F803E00 +1FFFFF00 +3FFFFF80 +7FFFFFC0 +FFFFFFE0 +7FFFFFC0 +3FFFFF80 +1FFFFF00 +0F803E00 +07803C00 +03803800 +01001000 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 412 0 +DWIDTH 21 0 +BBX 20 13 1 -8 +BITMAP +020000 +060000 +0E0000 +1E0000 +3FFFF0 +7FFFF0 +FE0000 +7FFFF0 +3FFFF0 +1E0000 +0E0000 +060000 +020000 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 22 15 0 -9 +BITMAP +010000 +038000 +078000 +0F8000 +1FFFF8 +3FFFFC +7FFFFC +FFFFF8 +7FFFFC +3FFFFC +1FFFF8 +0F8000 +078000 +038000 +010000 +ENDCHAR +STARTCHAR n +ENCODING 112 +SWIDTH 412 0 +DWIDTH 21 0 +BBX 20 13 -18 -8 +BITMAP +000400 +000600 +000700 +000780 +FFFFC0 +FFFFE0 +0007F0 +FFFFE0 +FFFFC0 +000780 +000700 +000600 +000400 +ENDCHAR +STARTCHAR o +ENCODING 113 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 22 15 -19 -9 +BITMAP +000200 +000700 +000780 +0007C0 +7FFFE0 +FFFFF0 +FFFFF8 +7FFFFC +FFFFF8 +FFFFF0 +7FFFE0 +0007C0 +000780 +000700 +000200 +ENDCHAR +STARTCHAR j +ENCODING 114 +SWIDTH 157 0 +DWIDTH 8 0 +BBX 13 20 -5 -21 +BITMAP +0200 +0700 +0F80 +1FC0 +3FE0 +7FF0 +FFF8 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +ENDCHAR +STARTCHAR k +ENCODING 115 +SWIDTH 176 0 +DWIDTH 9 0 +BBX 15 22 -6 -22 +BITMAP +0100 +0380 +07C0 +0FE0 +1FF0 +3FF8 +7FFC +FFFE +7FFC +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +06C0 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 137 0 +DWIDTH 7 0 +BBX 13 25 -5 -14 +BITMAP +0200 +0700 +0F80 +1FC0 +3FE0 +7FF0 +FFF8 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +0D80 +FFF8 +7FF0 +3FE0 +1FC0 +0F80 +0700 +0200 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 157 0 +DWIDTH 8 0 +BBX 15 27 -6 -15 +BITMAP +0100 +0380 +07C0 +0FE0 +1FF0 +3FF8 +7FFC +FFFE +7FFC +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +0FE0 +7FFC +FFFE +7FFC +3FF8 +1FF0 +0FE0 +07C0 +0380 +0100 +ENDCHAR +STARTCHAR D +ENCODING 118 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 119 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 120 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 121 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 122 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 123 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 39 0 +DWIDTH 2 0 +BBX 15 26 -13 -22 +BITMAP +000A +0054 +00A0 +0000 +1CAA +1D54 +1C00 +1C20 +3E14 +7F0A +FF80 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +FF80 +FF80 +FF80 +FF80 +C180 +FF80 +FF80 +FF80 +ENDCHAR +STARTCHAR bar +ENCODING 125 +SWIDTH 39 0 +DWIDTH 2 0 +BBX 15 26 -13 -22 +BITMAP +000E +007C +00E0 +0000 +1CFE +1DFE +1C00 +1C60 +3E3C +7F0E +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +FF80 +ENDCHAR +STARTCHAR D +ENCODING 126 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 127 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 128 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 129 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR quotedbl +ENCODING 130 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 24 23 -10 -13 +BITMAP +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +002800 +FFC7FF +FF83FF +FFC7FF +002800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +003800 +ENDCHAR +STARTCHAR numbersign +ENCODING 131 +SWIDTH 294 0 +DWIDTH 15 0 +BBX 26 25 -11 -14 +BITMAP +001C0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +7FF7FF80 +FFE3FFC0 +FFC1FFC0 +FFE3FFC0 +7FF7FF80 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +001C0000 +ENDCHAR +STARTCHAR D +ENCODING 132 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 133 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C014 +ENCODING 134 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 21 0 -21 +BITMAP +FFFFF8 +FFFFF8 +FFFFF8 +E00000 +E00000 +E00000 +E00000 +E00000 +E0FF00 +E0FE00 +E0FC00 +E0FC00 +E0FE00 +E0FF00 +E0CF80 +E087C0 +E00380 +E00100 +E00000 +E00000 +E00000 +ENDCHAR +STARTCHAR C014 +ENCODING 135 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 23 23 -1 -22 +BITMAP +FFFFFC +FFFFFE +FFFFFE +FFFFFE +FFFFFC +F80000 +F80000 +F80000 +F8FFE0 +F8FFC0 +F8FF80 +F8FF00 +F8FF00 +F8FF80 +F8FFC0 +F8FFE0 +F8E7F0 +F8C3E0 +F881C0 +F80080 +F80000 +F80000 +700000 +ENDCHAR +STARTCHAR C014 +ENCODING 136 +SWIDTH 510 0 +DWIDTH 26 0 +BBX 21 21 -18 -21 +BITMAP +FFFFF8 +FFFFF8 +FFFFF8 +000038 +000038 +000038 +000038 +000038 +07F838 +03F838 +01F838 +01F838 +03F838 +07F838 +0F9838 +1F0838 +0E0038 +040038 +000038 +000038 +000038 +ENDCHAR +STARTCHAR C014 +ENCODING 137 +SWIDTH 432 0 +DWIDTH 22 0 +BBX 23 23 -19 -22 +BITMAP +7FFFFE +FFFFFE +FFFFFE +FFFFFE +7FFFFE +00003E +00003E +00003E +0FFE3E +07FE3E +03FE3E +01FE3E +01FE3E +03FE3E +07FE3E +0FFE3E +1FCE3E +0F863E +07023E +02003E +00003E +00003E +00001C +ENDCHAR +STARTCHAR C020 +ENCODING 138 +SWIDTH 216 0 +DWIDTH 11 0 +BBX 19 20 -8 -20 +BITMAP +FFFFE0 +FFFFE0 +FFFFE0 +000000 +000000 +000000 +000000 +004000 +00E000 +01F000 +03F800 +07FC00 +0FFE00 +00E000 +00E000 +00E000 +00E000 +00E000 +00E000 +00E000 +ENDCHAR +STARTCHAR C020 +ENCODING 139 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 21 22 -9 -21 +BITMAP +7FFFF0 +FFFFF8 +FFFFF8 +FFFFF8 +7FFFF0 +000000 +000000 +002000 +007000 +00F800 +01FC00 +03FE00 +07FF00 +0FFF80 +1FFFC0 +00F800 +00F800 +00F800 +00F800 +00F800 +00F800 +007000 +ENDCHAR +STARTCHAR D +ENCODING 140 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 141 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 142 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 143 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 144 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 145 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 146 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 147 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR D +ENCODING 148 +SWIDTH 255 0 +DWIDTH 13 0 +BBX 12 21 1 -22 +BITMAP +8000 +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FF00 +FE00 +EF00 +C700 +8780 +0380 +03C0 +01C0 +01C0 +ENDCHAR +STARTCHAR E +ENCODING 149 +SWIDTH 530 0 +DWIDTH 27 0 +BBX 14 23 0 -23 +BITMAP +C000 +E000 +F000 +F800 +FC00 +FE00 +FF00 +FF80 +FFC0 +FFE0 +FFF0 +FFF8 +FFFC +FFF8 +FF80 +FFC0 +F7C0 +E7E0 +C3E0 +03F0 +01F0 +01F0 +00E0 +ENDCHAR +STARTCHAR C226 +ENCODING 150 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 23 37 -10 -20 +BITMAP +007C00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +03FF80 +0FFFE0 +1F01F0 +3C0078 +383838 +70381C +70381C +60380C +E0380E +E0380E +E0380E +E03C0E +E01E0E +600F0C +70079C +70031C +380038 +3C0078 +1F01F0 +0FFFE0 +03FF80 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +007C00 +ENDCHAR +STARTCHAR C226 +ENCODING 151 +SWIDTH 235 0 +DWIDTH 12 0 +BBX 23 37 -10 -20 +BITMAP +007C00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +03FF80 +0FFFE0 +1FFFF0 +3FFFF8 +3FFFF8 +7FFFFC +7FFFFC +7FFFFC +FFFFFE +FFFFFE +FFFFFE +FFFFFE +FFFFFE +7FFFFC +7FFFFC +7FFFFC +3FFFF8 +3FFFF8 +1FFFF0 +0FFFE0 +03FF80 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +00FE00 +007C00 +ENDCHAR +STARTCHAR C230 +ENCODING 152 +SWIDTH 373 0 +DWIDTH 19 0 +BBX 11 21 -4 -12 +BITMAP +FBE0 +FFE0 +1F00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +0E00 +1F00 +FFE0 +FBE0 +ENDCHAR +STARTCHAR C231 +ENCODING 153 +SWIDTH 157 0 +DWIDTH 8 0 +BBX 13 23 -5 -13 +BITMAP +7DF0 +FFF8 +FFF8 +7FF0 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +7FF0 +FFF8 +FFF8 +7DF0 +ENDCHAR +ENDFONT diff --git a/kcontrol/input/cursor_large_black.pcf.gz b/kcontrol/input/cursor_large_black.pcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..c9b458390cf7326545ccb6b8cdf25c5c4de45f03 GIT binary patch literal 3339 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 literal 0 HcmV?d00001 diff --git a/kcontrol/input/cursor_small_white.pcf.gz b/kcontrol/input/cursor_small_white.pcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..618905ea70bbcb363d84aad2597357aa2da802c4 GIT binary patch literal 3524 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 literal 0 HcmV?d00001 diff --git a/kcontrol/input/cursortheme.desktop b/kcontrol/input/cursortheme.desktop new file mode 100644 index 00000000..15b2d45a --- /dev/null +++ b/kcontrol/input/cursortheme.desktop @@ -0,0 +1,167 @@ +[Desktop Entry] +Exec=kcmshell4 cursortheme +Icon=edit-select +Type=Service + +X-KDE-ServiceTypes=KCModule +X-KDE-Library=kcm_cursortheme +X-KDE-ParentApp=kcontrol +X-KDE-System-Settings-Parent-Category=desktop-appearance +X-DocPath=kcontrol/cursortheme/index.html + +Name=Cursor Theme +Name[ar]=سِمة المؤشر +Name[ast]=Tema de cursores +Name[bg]=Тема за курсора +Name[bn]=কার্সর থীম +Name[bs]=Tema pokazivača +Name[ca]=Tema de cursor +Name[ca@valencia]=Tema de cursor +Name[cs]=Motiv kurzorů +Name[da]=Markørtema +Name[de]=Zeigerdesigns +Name[el]=Θέμα δρομέα +Name[en_GB]=Cursor Theme +Name[es]=Tema de cursores +Name[et]=Kursoriteema +Name[eu]=Kurtsorearen gaia +Name[fi]=Osoitinteema +Name[fr]=Thème du pointeur de la souris +Name[ga]=Téama Cúrsóra +Name[gl]=Tema do cursor +Name[he]=ערכת־נושא למצביע העכבר +Name[hi]=संकेतक प्रसंग +Name[hr]=Tema pokazivača +Name[hu]=Kurzortéma +Name[ia]=Thema de cursor +Name[is]=Bendilþema +Name[it]=Tema dei cursori +Name[ja]=カーソルテーマ +Name[kk]=Меңзер нақышы +Name[km]=ស្បែក​ទស្សន៍ទ្រនិច +Name[kn]=ಸ್ಥಳಸೂಚಕ (ಕರ್ಸರ್) ಪರಿಸರವಿನ್ಯಾಸ +Name[ko]=커서 테마 +Name[lt]=Žymeklių tema +Name[lv]=Kursora tēma +Name[mr]=कर्सर शैली +Name[nb]=Pekertema +Name[nds]=Wieserutsehn +Name[nl]=Cursorthema +Name[pa]=ਕਰਸਰ ਥੀਮ +Name[pl]=Zestawy kursorów +Name[pt]=Tema de Cursores +Name[pt_BR]=Tema de cursores +Name[ro]=Tematica de cursor +Name[ru]=Тема курсоров +Name[sk]=Téma kurzora +Name[sl]=Tema kazalke +Name[sr]=Тема показивача +Name[sr@ijekavian]=Тема показивача +Name[sr@ijekavianlatin]=Tema pokazivača +Name[sr@latin]=Tema pokazivača +Name[sv]=Muspekartema +Name[th]=ชุดเคอร์เซอร์ +Name[tr]=İmleç Teması +Name[ug]=نۇربەلگە ئۆرنىكى +Name[uk]=Тема вказівника +Name[vi]=Sắc thái con trỏ +Name[wa]=Tinme do cursoe +Name[x-test]=xxCursor Themexx +Name[zh_CN]=光标主题 +Name[zh_TW]=游標主題 + +Comment=Customize the mouse cursor appearance +Comment[ar]=خصص مظهر سِمة مؤشر الفأرة +Comment[ast]=Personalizar l'apariencia del cursor del mur +Comment[bg]=Настройки на изгледа на курсора на мишката +Comment[bn]=মাউস কার্সর-এর চেহারা পছন্দমত বদলান +Comment[bs]=Prilagodite izgled pokazivača miša +Comment[ca]=Personalitza l'aparença del cursor del ratolí +Comment[ca@valencia]=Personalitza l'aparença del cursor del ratolí +Comment[cs]=Upravit vzhled kurzoru myši +Comment[da]=Tilpas musemarkørens udseende +Comment[de]=Das Erscheinungsbild des Mauszeigers anpassen +Comment[el]=Προσαρμογή εμφάνισης του δείκτη ποντικιού +Comment[en_GB]=Customise the mouse cursor appearance +Comment[es]=Personalizar la apariencia del cursor del ratón +Comment[et]=Hiirekursori välimuse kohandamine +Comment[eu]=Pertsonalizatu saguaren kurtsorearen itxura +Comment[fi]=Hiiren osoittimen ulkoasuasetukset +Comment[gl]=Personaliza o tema do cursor +Comment[he]=התאמה אישית של מראה מצביע העכבר +Comment[hr]=Podesi izgled pokazivača miša +Comment[hu]=Az egérmutató megjelenésének testreszabása +Comment[ia]=Personalisa le apparentia de cursor de mus +Comment[is]=Sérsníða útlit músarbendilsins +Comment[kk]=Меңзер нақышын өзінше баптап алу +Comment[km]=ប្ដូរ​រូបរាង​ទស្សន៍ទ្រនិច​កណ្ដុរ​តាម​បំណង +Comment[ko]=마우스 커서 모양 사용자 정의 +Comment[lt]=Derinti pelės žymeklio išvaizdą +Comment[lv]=Pielāgot peles kursora izskatu +Comment[mr]=कर्सर शैलीत ऐच्छिक बदल करा +Comment[nb]=Sett opp utseende for musepekeren +Comment[nds]=Dat Muuswieser-Utsehn topassen +Comment[nl]=Het uiterlijk van de muiscursor aanpassen +Comment[pa]=ਮਾਊਸ ਕਰਸਰ ਦਿੱਖ ਆਪਣੀ ਪਸੰਦ ਦੀ ਬਣਾਉ +Comment[pl]=Dostosowywanie wyglądu kursora myszy +Comment[pt]=Personalizar a aparência do cursor do rato +Comment[pt_BR]=Personaliza a aparência do cursor do mouse +Comment[ro]=Particularizează tematica de cursor +Comment[ru]=Настройка внешнего вида курсора мыши +Comment[sk]=Prispôsobenie vzhľadu kurzora myši +Comment[sl]=Prilagodite videz kazalke miške +Comment[sr]=Прилагодите изглед показивача миша +Comment[sr@ijekavian]=Прилагодите изглед показивача миша +Comment[sr@ijekavianlatin]=Prilagodite izgled pokazivača miša +Comment[sr@latin]=Prilagodite izgled pokazivača miša +Comment[sv]=Anpassa muspekarens utseende +Comment[th]=ปรับแต่งชุดเคอร์เซอร์ของเมาส์เอง +Comment[tr]=Fare işaretçisi görünümünü özelleştir +Comment[ug]=چاشقىنەك نۇربەلگە قىياپىتىنى ئۆزلەشتۈر +Comment[uk]=Налаштування вигляду вказівника миші на екрані +Comment[vi]=Tuỳ chỉnh diện mạo con trỏ chuột +Comment[wa]=Mete a vosse môde li rivnance do cursoe del sori +Comment[x-test]=xxCustomize the mouse cursor appearancexx +Comment[zh_CN]=定制鼠标指针外观 +Comment[zh_TW]=自訂滑鼠游標外觀 + +X-KDE-Keywords=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance +X-KDE-Keywords[bs]=miš,kursor,tema,pojavljivanje kurosra,boja kursora,tema kursora,tema miša,pojavljivanje miša,površina miša,pokazatelj boja,pojava boja +X-KDE-Keywords[ca]=Ratolí,Cursor,Tema,Aparença de cursor,Color de cursor,Tema de cursor,Tema de ratolí,Aparença de ratolí,Pells de ratolí,Colors d'apuntador,Aparença d'apuntador +X-KDE-Keywords[ca@valencia]=Ratolí,Cursor,Tema,Aparença de cursor,Color de cursor,Tema de cursor,Tema de ratolí,Aparença de ratolí,Pells de ratolí,Colors d'apuntador,Aparença d'apuntador +X-KDE-Keywords[da]=Mus,markør,cursor,tema,markørens udseende,markørfarve,markørtema,musetema,musens udseende,museskin +X-KDE-Keywords[de]=Maus,Zeiger,Mauszeiger,Zeigerfarbe,Zeigerdesign +X-KDE-Keywords[el]=ποντίκι,δρομέας,θέμα,εμφάνιση δρομέα,χρώμα δρομέα,θέμα δρομέα,θέμα ποντικιού,εμφάνιση ποντικιού,θέματα ποντικιού,χρώματα δείκτη,εμφάνιση δείκτη +X-KDE-Keywords[en_GB]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Colour,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colours,Pointer Appearance +X-KDE-Keywords[es]=Ratón,Cursor,Tema,Apariencia del cursor,Color del cursor,Tema del cursor,Tema del ratón,Apariencia del ratón,Pieles del ratón,Colores del puntero,Apariencia del puntero +X-KDE-Keywords[et]=Hiir,Kursor,Teema,Kursori välimus,Kursori värv,Kursori teema,Hiireteema,Hiire välimus,Hiire nahad,Osutusseadme värvid,Osutusseadme välimus +X-KDE-Keywords[eu]=sagu,kurtsore,gai,kurtsorearen itsura,kurtsorearen kolorea,saguaren gaia,saguaren itxura,saguaren azalak,erakuslearen koloreak,erakuslearen itxura +X-KDE-Keywords[fi]=hiiri,osoitin,teema,osoittimen ulkoasu,osoittimen väri,osoitinteema,hiiren teema,hiiriteema,hiiren ulkoasu,hiiriteemat,osoitinvärit +X-KDE-Keywords[fr]=Souris, Curseur, Thème, Apparence du curseur, Couleur du curseur, Thème de curseurs, Thème de la souris, Apparence de la souris, Revêtement de la souris, Couleur du pointeur, Apparence du pointeur +X-KDE-Keywords[gl]=rato, cursor, tema, aparencia do cursor, cor do cursor, tema do cursor, tema do rato, aparencia do rato, cor do rato, punteiro, cor do punteiro, aparencia do punteiro, tema do punteiro +X-KDE-Keywords[hu]=Egér,Kurzor,Téma,Kurzormegjelenés,Kurzorszín,Kurzortéma,Egértéma,Egérmegjelenés,Egérfelületek,Mutató színek,Mutató megjelenés +X-KDE-Keywords[ia]=Mus,Cursor,Thema,Apparentia,Cursor,Color,Thema de Cursor,Thema de Mus, Apparentia de Mus,Pelles de Mus,Colores de punctator,Apparentia de punctator +X-KDE-Keywords[it]=Mouse,Cursore,Aspetto cursore,Colore cursore,Tema cursore,Tema mouse,Aspetto mouse,Skin mouse,Colore puntatore,Aspetto puntatore +X-KDE-Keywords[kk]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance +X-KDE-Keywords[km]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance +X-KDE-Keywords[ko]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,마우스,커서,커서 테마,포인터 +X-KDE-Keywords[mr]=माऊस, कर्सर, थीम, कर्सर, अपिरिअन्स, कर्सर, कलर, कर्सर थीम, माऊस थीम, माऊस अपिरिअन्स, माऊस स्कीन्स, पॉईटर अपिरिअन्स +X-KDE-Keywords[nb]=Mus,peker,tema,pekerutseende,pekerfarge,pekertema,musetema,musutseende,museskins,pekerfarger,pekeerutseende +X-KDE-Keywords[nds]=Muus,Wieser,Muster, Wieserutsehn,Klöör,Utsehn +X-KDE-Keywords[nl]=Muis,Cursor,Thema,Uiterlijk van cursor,kleur van cursor,Thema van cursor,Thema van muis,uiterlijk van muis,Muisoppervlak,Kleuren van aanwijzer,Uiterlijk van aanwijzer +X-KDE-Keywords[pl]=Mysz,Kursor,Motyw,Wygląd kursora,Kolor kursora,Motyw kursora,Motyw myszy,Wygląd myszy,Skórki myszy,Kolory wskaźnika,Wygląd wskaźnika +X-KDE-Keywords[pt]=Rato,Cursor,Tema,Aparência do Cursor,Cor do Cursor,Tema do Cursor,Tema do Rato,Aparência do Rato,Visuais do Rato,Cores do Cursor +X-KDE-Keywords[pt_BR]=Mouse,Cursor,Tema,Aparência do cursor,Cor do cursor,Tema do cursor,Tema do mouse,Aparência do mouse,Visuais do mouse,Cores do ponteiro,Aparência do ponteiro +X-KDE-Keywords[ru]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,мышь,курсор,тема,внешний вид курсора мыши,цвет указателя,внешний вид указателя +X-KDE-Keywords[sk]=Myš, kurzor,téma,vzhľad kurzora,farba kurzora,téma kurzora,téma myši,vzhľad myši,skiny myši,farby ukazovateľa,vzhľad ukazovateľa +X-KDE-Keywords[sl]=miška,kazalec,kurzor,kazalka,tema,videz kazalca,videz kazalke,barva kazalca,barva kazalke,tema kazalcev,tema kazalk,tema miške,videz miške,preobleke miške,teme miške +X-KDE-Keywords[sr]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,миш,показивач,курсор,тема,изглед показивача,боја показивача,тема показивача,тема миша,изглед миша,пресвлаке миша,боје показивача +X-KDE-Keywords[sr@ijekavian]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,миш,показивач,курсор,тема,изглед показивача,боја показивача,тема показивача,тема миша,изглед миша,пресвлаке миша,боје показивача +X-KDE-Keywords[sr@ijekavianlatin]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,miš,pokazivač,kursor,tema,izgled pokazivača,boja pokazivača,tema pokazivača,tema miša,izgled miša,presvlake miša,boje pokazivača +X-KDE-Keywords[sr@latin]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,miš,pokazivač,kursor,tema,izgled pokazivača,boja pokazivača,tema pokazivača,tema miša,izgled miša,presvlake miša,boje pokazivača +X-KDE-Keywords[sv]=Mus,Pekare,Tema,Utseende,Färg,Pekartema,Mustema,Musutseende,Musskal,Pekarfärger,Pekarutseende +X-KDE-Keywords[tr]=Fare,İşaretçi,Tema,İşaretçi Görünümü,İşaretçi Rengi,İşaretçi Teması,Fare Teması,Fare Görünümü,Fare Kabuğu,İşaretçi Renkleri,İşaretçi Görünümü +X-KDE-Keywords[uk]=миша,вказівник,тема,вигляд вказівника,колір вказівника,тема вказівника,тема миші,вигляд миші,Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance +X-KDE-Keywords[x-test]=xxMouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearancexx +X-KDE-Keywords[zh_CN]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,鼠标,指针,主题,指针外观,指针颜色,指针主题,鼠标主题,鼠标外观,鼠标皮肤,指针外观 +X-KDE-Keywords[zh_TW]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance diff --git a/kcontrol/input/kapplymousetheme.cpp b/kcontrol/input/kapplymousetheme.cpp new file mode 100644 index 00000000..c9bc511b --- /dev/null +++ b/kcontrol/input/kapplymousetheme.cpp @@ -0,0 +1,91 @@ +/* + * main.cpp + * + * Copyright (c) 1999 Matthias Hoelzer-Kluepfel + * Copyright (c) 2005 Lubos Lunak + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include + +#ifdef HAVE_XCURSOR +# include +#endif + +static Display* dpy; +Display* QX11Info::display() { return dpy; } +Qt::HANDLE QX11Info::appRootWindow(int) { return DefaultRootWindow( dpy ); } + +static bool isEmpty( const char* str ) + { + if( str == NULL ) + return true; + while( isspace( *str )) + ++str; + return *str == '\0'; + } + +int main( int argc, char* argv[] ) + { + if( argc != 3 ) + return 1; + dpy = XOpenDisplay( NULL ); + if( dpy == NULL ) + return 2; + int ret = 0; +#ifdef HAVE_XCURSOR + const char* theme = argv[ 1 ]; + const char* size = argv[ 2 ]; + + // Note: If you update this code, update kapplymousetheme as well. + + // use a default value for theme only if it's not configured at all, not even in X resources + if( isEmpty( theme ) + && isEmpty( XGetDefault( QX11Info::display(), "Xcursor", "theme" )) + && isEmpty( XcursorGetTheme( QX11Info::display()))) + { + theme = "default"; + ret = 10; // means to switch to default + } + + // Apply the KDE cursor theme to ourselves + if( !isEmpty( theme )) + XcursorSetTheme(QX11Info::display(), theme ); + + if (!isEmpty( size )) + XcursorSetDefaultSize(QX11Info::display(), atoi( size )); + + // Load the default cursor from the theme and apply it to the root window. + Cursor handle = XcursorLibraryLoadCursor(QX11Info::display(), "left_ptr"); + XDefineCursor(QX11Info::display(), QX11Info::appRootWindow(), handle); + XFreeCursor(QX11Info::display(), handle); // Don't leak the cursor + +#else + ( void ) QX11Info::display(); + ( void ) QX11Info::appRootWindow(); + ( void ) argv; +#endif + XCloseDisplay( dpy ); + return ret; + } diff --git a/kcontrol/input/kcmcursortheme.cpp b/kcontrol/input/kcmcursortheme.cpp new file mode 100644 index 00000000..19d22d66 --- /dev/null +++ b/kcontrol/input/kcmcursortheme.cpp @@ -0,0 +1,69 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcmcursortheme.h" + +#include +#include + +K_PLUGIN_FACTORY(CursorThemeConfigFactory, + registerPlugin(); +) +K_EXPORT_PLUGIN(CursorThemeConfigFactory("kcm_cursortheme", "kcminput")) + + +CursorThemeConfig::CursorThemeConfig(QWidget *parent, const QVariantList &args) + : KCModule(CursorThemeConfigFactory::componentData(), parent, args) +{ + QLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + + themepage = new ThemePage(this); + connect(themepage, SIGNAL(changed(bool)), SLOT(changed())); + layout->addWidget(themepage); + + KAboutData* aboutData = new KAboutData("kcm_cursortheme", 0, ki18n("Cursor Theme"), + 0, KLocalizedString(), KAboutData::License_GPL, ki18n("(c) 2003-2007 Fredrik Höglund")); + aboutData->addAuthor(ki18n("Fredrik Höglund")); + setAboutData(aboutData); +} + +CursorThemeConfig::~CursorThemeConfig() +{ + /* */ +} + +void CursorThemeConfig::load() +{ + themepage->load(); + emit changed(false); +} + +void CursorThemeConfig::save() +{ + themepage->save(); + emit changed(false); +} + +void CursorThemeConfig::defaults() +{ + themepage->defaults(); + changed(); +} + +#include "kcmcursortheme.moc" diff --git a/kcontrol/input/kcmcursortheme.h b/kcontrol/input/kcmcursortheme.h new file mode 100644 index 00000000..f955f4d1 --- /dev/null +++ b/kcontrol/input/kcmcursortheme.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KCMCURSORTHEME_H +#define KCMCURSORTHEME_H + +#include +#include "themepage.h" + +class CursorThemeConfig : public KCModule +{ + Q_OBJECT + +public: + CursorThemeConfig(QWidget *parent, const QVariantList &); + ~CursorThemeConfig(); + +public: + void load(); + void save(); + void defaults(); + +private: + ThemePage *themepage; +}; + +#endif diff --git a/kcontrol/input/kmousedlg.ui b/kcontrol/input/kmousedlg.ui new file mode 100644 index 00000000..b48a6065 --- /dev/null +++ b/kcontrol/input/kmousedlg.ui @@ -0,0 +1,295 @@ + + + KMouseDlg + + + + 0 + 0 + 416 + 329 + + + + + + + + + + + + 0 + 0 + + + + Button Order + + + true + + + + + + Righ&t handed + + + true + + + + + + + Le&ft handed + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 1 + 1 + + + + + + + + + + + Change the direction of scrolling for the mouse wheel or the 4th and 5th mouse buttons. + + + Re&verse scroll direction + + + + + + + + + + 0 + 0 + + + + + 96 + 80 + + + + true + + + + + + + + + Icons + + + + + + Dou&ble-click to open files and folders (select icons on first click) + + + false + + + + + + + &Single-click to open files and folders + + + true + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Cha&nge pointer shape over icons + + + true + + + + + + + A&utomatically select icons + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + false + + + + 0 + 0 + + + + Delay + + + 0 + + + 2000 + + + 125 + + + ms + + + true + + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 1 + + + + + + + + + KIntNumInput + QWidget +
    knuminput.h
    +
    +
    + + rightHanded + leftHanded + cbScrollPolarity + doubleClick + singleClick + cb_pointershape + cbAutoSelect + + + kdialog.h + + + + + singleClick + toggled(bool) + cb_pointershape + setEnabled(bool) + + + 40 + 209 + + + 69 + 240 + + + + + singleClick + toggled(bool) + cbAutoSelect + setEnabled(bool) + + + 40 + 209 + + + 69 + 264 + + + + +
    diff --git a/kcontrol/input/logitechmouse.cpp b/kcontrol/input/logitechmouse.cpp new file mode 100644 index 00000000..8010406a --- /dev/null +++ b/kcontrol/input/logitechmouse.cpp @@ -0,0 +1,421 @@ +/* + * logitechmouse.cpp + * + * Copyright (C) 2004 Brad Hards + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#ifdef HAVE_LIBUSB +#include + +#include "logitechmouse.h" + +LogitechMouse::LogitechMouse( struct usb_device *usbDev, int mouseCapabilityFlags, QWidget* parent, const char* name ) + : LogitechMouseBase( parent ) + , m_resolution( 0 ) +{ + if ( !name ) + setObjectName( "LogitechMouse" ); + + cordlessNameLabel->setText( i18n("Mouse type: %1", objectName() ) ); + + m_mouseCapabilityFlags = mouseCapabilityFlags; + + m_usbDeviceHandle = usb_open( usbDev ); + + if ( !m_usbDeviceHandle ) { + kWarning() << "Error opening usbfs file: " << usb_strerror() ; + return; + } + + if ( mouseCapabilityFlags & USE_CH2 ) { + m_useSecondChannel = 0x0100; + } else { + m_useSecondChannel = 0x0000; + } + + permissionProblemText->hide(); + + if ( mouseCapabilityFlags & HAS_RES ) { + updateResolution(); + resolutionSelector->setEnabled( true ); + + connect( button400cpi, SIGNAL(clicked()), parent, SLOT(changed()) ); + connect( button800cpi, SIGNAL(clicked()), parent, SLOT(changed()) ); + + if ( 4 == resolution() ) { + button800cpi->setChecked( true ); + } else if ( 3 == resolution() ) { + button400cpi->setChecked( true ); + } else { + // it must have failed, try to help out + resolutionSelector->setEnabled(false); + permissionProblemText->show(); + } + } + + if ( mouseCapabilityFlags & HAS_CSR ) { + + initCordlessStatusReporting(); + + // Do a name + cordlessNameLabel->setText( i18n("Mouse type: %1", cordlessName() ) ); + cordlessNameLabel->setEnabled( true ); + + // Display the battery power level - the level gets updated in updateGUI() + batteryBox->setEnabled( true ); + + // Channel + channelSelector->setEnabled( true ); + // if the channel is changed, we need to turn off the timer, otherwise it + // just resets the button to reflect the current status. The timer is + // started again when we applyChanges() + connect( channel1, SIGNAL(clicked()), this, SLOT(stopTimerForNow()) ); + connect( channel1, SIGNAL(clicked()), parent, SLOT(changed()) ); + if ( isDualChannelCapable() ) { + channel2->setEnabled( true ); + connect( channel2, SIGNAL(clicked()), this, SLOT(stopTimerForNow()) ); + connect( channel2, SIGNAL(clicked()), parent, SLOT(changed()) ); + } + + updateGUI(); + } + +} + +LogitechMouse::~LogitechMouse() +{ + if ( m_usbDeviceHandle ) + usb_close( m_usbDeviceHandle ); +} + +void LogitechMouse::initCordlessStatusReporting() +{ + updateCordlessStatus(); + doUpdate = new QTimer( this ); // will be automatically deleted + connect( doUpdate, SIGNAL(timeout()), this, SLOT(updateGUI()) ); + doUpdate->start( 20000 ); +} + +void LogitechMouse::updateCordlessStatus() +{ + QByteArray status(8, '\0'); + + int result = -1; + + if ( m_usbDeviceHandle ) + result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR | USB_ENDPOINT_IN,0x09, + (0x0003 | m_useSecondChannel), + (0x0000 | m_useSecondChannel), + status.data(), + 0x0008, + 1000); + + if (0 > result) { + // We probably have a permission problem + m_channel = 0; + channelSelector->setEnabled( false ); + batteryBox->setEnabled( false ); + cordlessNameLabel->hide(); + permissionProblemText->show(); + } else { + // kDebug() << "P6 (connect status): " << (status[0] & 0xFF); + if ( status[0] & 0x20 ) { // mouse is talking + m_connectStatus = ( status[0] & 0x80 ); + m_mousePowerup = ( status[0] & 0x40 ); + m_receiverUnlock = ( status[0] & 0x10 ); + m_waitLock = ( status[0] & 0x08 ); + } + + // kDebug() << "P0 (receiver type): " << (status[1] & 0xFF); + /* + 0x38 = pid C501 + 0x39 = pid C502 + 0x3B = pid C504 + 0x3C = pid C508 + 0x3D = pid C506 + 0x3E = pid C505 + */ + + m_cordlessNameIndex = (status[2] & 0xFF); + + m_batteryLevel = (status[3] & 0x07 ); + if ( status[3] & 0x08 ) { + m_channel = 2; + } else { + m_channel = 1; + } + + m_cordlessSecurity = ( ( status[4] ) & ( status[5] << 8 ) ); + + m_caseShape = ( status[6] & 0x7F ); + + // kDebug() << "PB1 (device Capabilities): " << (status[7] & 0xFF); + m_numberOfButtons = 2 + ( status[7] & 0x07 ); // 9 means something more than 8 + m_twoChannelCapable = ( status[7] & 0x40 ); + m_verticalRoller = ( status[7] & 0x08 ); + m_horizontalRoller = ( status[7] & 0x10 ); + m_has800cpi = ( status[7] & 0x20 ); + } + +} + +void LogitechMouse::updateGUI() +{ + updateCordlessStatus(); + + batteryBar->setValue( batteryLevel() ); + + if ( isDualChannelCapable() ) { + if ( 2 == channel() ) { + channel2->setChecked( true ); + } else if ( 1 == channel() ) { + channel1->setChecked( true ); + } // else it might have failed - we don't do anything + } +} + +void LogitechMouse::stopTimerForNow() +{ + doUpdate->stop(); +} + +void LogitechMouse::applyChanges() +{ + if ( m_mouseCapabilityFlags & HAS_RES ) { + if ( ( resolution() == 4 ) && ( button400cpi->isChecked() ) ) { + // then we are in 800cpi mode, but want 400cpi + setLogitechTo400(); + } else if ( ( resolution() == 3 ) && (button800cpi->isChecked() ) ) { + // then we are in 400 cpi mode, but want 800 cpi + setLogitechTo800(); + } + } + + if ( isDualChannelCapable() ) { + if ( ( channel() == 2 ) && ( channel1->isChecked() ) ) { + // we are on channel 2, but want channel 1 + setChannel1(); + KMessageBox::information(this, i18n("RF channel 1 has been set. Please press Connect button on mouse to re-establish link"), i18n("Press Connect Button") ); + } else if ( ( channel() == 1 ) && ( channel2->isChecked() ) ) { + // we are on channel 1, but want channel 2 + setChannel2(); + KMessageBox::information(this, i18n("RF channel 2 has been set. Please press Connect button on mouse to re-establish link"), i18n("Press Connect Button") ); + } + + initCordlessStatusReporting(); + } +} + +void LogitechMouse::save(KConfig * /*config*/) +{ + kDebug() << "Logitech mouse settings not saved - not implemented yet"; +} + +quint8 LogitechMouse::resolution() +{ + // kDebug() << "resolution: " << m_resolution; + if ( 0 == m_resolution ) { + updateResolution(); + } + return m_resolution; +} + +void LogitechMouse::updateResolution() +{ + char resolution; + + int result = -1; + + if ( m_usbDeviceHandle ) + result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR | USB_ENDPOINT_IN, + 0x01, + 0x000E, + 0x0000, + &resolution, + 0x0001, + 100); + + // kDebug() << "resolution is: " << resolution; + if (0 > result) { + kWarning() << "Error getting resolution from device : " << usb_strerror() ; + m_resolution = 0; + } else { + m_resolution = resolution; + } +} + +void LogitechMouse::setLogitechTo800() +{ + int result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR, + 0x02, + 0x000E, + 4, + NULL, + 0x0000, + 100); + if (0 > result) { + kWarning() << "Error setting resolution on device: " << usb_strerror() ; + } +} + +void LogitechMouse::setLogitechTo400() +{ + int result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR, + 0x02, + 0x000E, + 3, + NULL, + 0x0000, + 100); + if (0 > result) { + kWarning() << "Error setting resolution on device: " << usb_strerror() ; + } +} + +quint8 LogitechMouse::batteryLevel() const +{ + return m_batteryLevel; +} + + +quint8 LogitechMouse::channel() const +{ + return m_channel; +} + +bool LogitechMouse::isDualChannelCapable() const +{ + return m_twoChannelCapable; +} + +void LogitechMouse::setChannel1() +{ + int result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR, + 0x02, + (0x0008 | m_useSecondChannel), + (0x0000 | m_useSecondChannel), + NULL, + 0x0000, + 1000); + + if (0 > result) { + kWarning() << "Error setting mouse to channel 1 : " << usb_strerror() ; + } + +} + +void LogitechMouse::setChannel2() +{ + int result = usb_control_msg( m_usbDeviceHandle, + USB_TYPE_VENDOR, + 0x02, + (0x0008 | m_useSecondChannel), + (0x0001 | m_useSecondChannel), + NULL, + 0x0000, + 1000); + + if (0 > result) { + kWarning() << "Error setting mouse to channel 2 : " << usb_strerror() ; + } + +} + +QString LogitechMouse::cordlessName() const +{ + switch ( m_cordlessNameIndex ) { + case 0x00: + return i18nc( "no cordless mouse", "none" ); + break; + case 0x04: + return i18n( "Cordless Mouse" ); + break; + case 0x05: + return i18n( "Cordless Wheel Mouse" ); + break; + case 0x06: + return i18n( "Cordless MouseMan Wheel" ); + break; + case 0x07: + return i18n( "Cordless Wheel Mouse" ); + break; + case 0x08: + return i18n( "Cordless Wheel Mouse" ); + break; + case 0x09: + return i18n( "Cordless TrackMan Wheel" ); + break; + case 0x0A: + return i18n( "TrackMan Live" ); + break; + case 0x0C: + return i18n( "Cordless TrackMan FX" ); + break; + case 0x0D: + return i18n( "Cordless MouseMan Optical" ); + break; + case 0x0E: + return i18n( "Cordless Optical Mouse" ); + break; + case 0x0F: + return i18n( "Cordless Mouse" ); + break; + case 0x12: + return i18n( "Cordless MouseMan Optical (2ch)" ); + break; + case 0x13: + return i18n( "Cordless Optical Mouse (2ch)" ); + break; + case 0x14: + return i18n( "Cordless Mouse (2ch)" ); + break; + case 0x82: + return i18n( "Cordless Optical TrackMan" ); + break; + case 0x8A: + return i18n( "MX700 Cordless Optical Mouse" ); + break; + case 0x8B: + return i18n( "MX700 Cordless Optical Mouse (2ch)" ); + break; + default: + return i18n( "Unknown mouse"); + } +} + +#include "logitechmouse.moc" + +#endif + diff --git a/kcontrol/input/logitechmouse.h b/kcontrol/input/logitechmouse.h new file mode 100644 index 00000000..cc4f5f62 --- /dev/null +++ b/kcontrol/input/logitechmouse.h @@ -0,0 +1,107 @@ +/* + * logitechmouse.h + * + * Copyright (C) 2004 Brad Hards + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef __LOGITECHMOUSE_H__ +#define __LOGITECHMOUSE_H__ + +#include + +#include + +#include + +#include "ui_logitechmouse_base.h" + +#include + +#define VENDOR_LOGITECH 0x046D +#define HAS_RES 0x01 /* mouse supports variable resolution */ +#define HAS_SS 0x02 /* mouse supports smart scroll control */ +#define HAS_CSR 0x04 /* mouse supports cordless status reporting and control */ +#define HAS_SSR 0x08 /* mouse supports smart scroll reporting */ +#define USE_CH2 0x10 /* mouse needs to use the second channel */ + +class LogitechMouseBase : public QWidget, public Ui::LogitechMouseBase +{ +public: + LogitechMouseBase( QWidget *parent ) : QWidget( parent ) { + setupUi( this ); + } +}; + + + +class LogitechMouse : public LogitechMouseBase +{ + Q_OBJECT + +public: + LogitechMouse( struct usb_device *usbDev, int mouseCapabilityFlags, QWidget* parent = 0, const char* name=0); + ~LogitechMouse(); + void applyChanges(); + void save(KConfig *config); + +protected Q_SLOTS: + void setChannel1(); + void setChannel2(); + void updateGUI(); + void stopTimerForNow(); + +private: + void initCordlessStatusReporting(); + void updateCordlessStatus(); + + void setLogitechTo400(); + void setLogitechTo800(); + + QString cordlessName() const ; + quint8 resolution(); + void updateResolution(); + quint8 batteryLevel() const; + quint8 channel() const; + bool isDualChannelCapable() const; + + QTimer *doUpdate; + + struct usb_dev_handle *m_usbDeviceHandle; + bool m_connectStatus; // true if the CONNECT button on the mouse is pressed + bool m_mousePowerup; // true if we are doing "just out of the box" auto-locking + bool m_receiverUnlock; // true if mouse has been disconnected by a long press + // of the receiver's CONNECT button + bool m_waitLock; // true if receiver searching for new mouse because the + // CONNECT button on the receiver was pressed + quint8 m_batteryLevel; + quint8 m_channel; + quint8 m_cordlessNameIndex; // this gets convered into a QString in cordlessName() + quint16 m_cordlessSecurity; + quint16 m_useSecondChannel; + quint8 m_caseShape; + quint8 m_numberOfButtons; + quint8 m_resolution; + bool m_twoChannelCapable; // true if the mouse supports dual channels + bool m_verticalRoller; // true if the mouse has a vertical roller (wheel) + bool m_horizontalRoller; // true if the mouse has a horizontal roller (wheel) + bool m_has800cpi; // true if the mouse does 800cpi resolution + int m_mouseCapabilityFlags; +}; + +#endif + diff --git a/kcontrol/input/logitechmouse.usermap b/kcontrol/input/logitechmouse.usermap new file mode 100644 index 00000000..65da520c --- /dev/null +++ b/kcontrol/input/logitechmouse.usermap @@ -0,0 +1,35 @@ +# script match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info +# Wheel Mouse Optical +consoleUserPerms 0x0003 0x046d 0xc00e 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MouseMan Traveler +consoleUserPerms 0x0003 0x046d 0xc00f 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MouseMan Dual Optical +consoleUserPerms 0x0003 0x046d 0xc012 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX310 Optical Mouse +consoleUserPerms 0x0003 0x046d 0xc01b 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX510 Optical Mouse +consoleUserPerms 0x0003 0x046d 0xc01d 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX300 Optical Mouse +consoleUserPerms 0x0003 0x046d 0xc024 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX500 Optical Mouse +consoleUserPerms 0x0003 0x046d 0xc025 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# iFeel Mouse +consoleUserPerms 0x0003 0x046d 0xc031 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Mouse Receiver +consoleUserPerms 0x0003 0x046d 0xc501 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Dual Receiver +consoleUserPerms 0x0003 0x046d 0xc502 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Cordless Freedom Optical +consoleUserPerms 0x0003 0x046d 0xc504 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Cordless Elite Duo +consoleUserPerms 0x0003 0x046d 0xc505 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX700 Optical Mouse +consoleUserPerms 0x0003 0x046d 0xc506 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Cordless Optical Trackman +consoleUserPerms 0x0003 0x046d 0xc508 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Cordless MX Duo Receiver +consoleUserPerms 0x0003 0x046d 0xc50b 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# MX100 Laser Mouse +consoleUserPerms 0x0003 0x046d 0xc50e 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Receiver for Cordless Presenter +consoleUserPerms 0x0003 0x046d 0xc702 0x0000 0xffff 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 diff --git a/kcontrol/input/logitechmouse_base.ui b/kcontrol/input/logitechmouse_base.ui new file mode 100644 index 00000000..13ac59e5 --- /dev/null +++ b/kcontrol/input/logitechmouse_base.ui @@ -0,0 +1,134 @@ + + LogitechMouseBase + + + + + + Cordless Name + + + false + + + + + + + false + + + Sensor Resolution + + + + + + 400 counts per inch + + + 1 + + + + + + + 800 counts per inch + + + 1 + + + + + + + + + + false + + + Battery Level + + + + + + 7 + + + + + + + + + + false + + + RF Channel + + + + + + Channel 1 + + + true + + + 3 + + + + + + + false + + + Channel 2 + + + 3 + + + + + + + + + + You have a Logitech Mouse connected, and libusb was found at compile time, but it was not possible to access this mouse. This is probably caused by a permissions problem - you should consult the manual on how to fix this. + + + Qt::AlignVCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/kcontrol/input/main.cpp b/kcontrol/input/main.cpp new file mode 100644 index 00000000..0f9f33a6 --- /dev/null +++ b/kcontrol/input/main.cpp @@ -0,0 +1,91 @@ +/* + * main.cpp + * + * Copyright (c) 1999 Matthias Hoelzer-Kluepfel + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include + +#include "mouse.h" +#include + +#include +#include + +#include +#ifdef HAVE_XCURSOR +# include +#endif + +extern "C" +{ + KDE_EXPORT void kcminit_mouse() + { + KConfig *config = new KConfig("kcminputrc", KConfig::NoGlobals ); + MouseSettings settings; + settings.load(config); + settings.apply(true); // force + +#ifdef HAVE_XCURSOR + KConfigGroup group = config->group("Mouse"); + QString theme = group.readEntry("cursorTheme", QString()); + QString size = group.readEntry("cursorSize", QString()); + + // Note: If you update this code, update kapplymousetheme as well. + + // use a default value for theme only if it's not configured at all, not even in X resources + if( theme.isEmpty() + && QByteArray( XGetDefault( QX11Info::display(), "Xcursor", "theme" )).isEmpty() + && QByteArray( XcursorGetTheme( QX11Info::display())).isEmpty()) + { + theme = "default"; + } + + // Apply the KDE cursor theme to ourselves + if( !theme.isEmpty()) + XcursorSetTheme(QX11Info::display(), QFile::encodeName(theme)); + + if (!size.isEmpty()) + XcursorSetDefaultSize(QX11Info::display(), size.toUInt()); + + // Load the default cursor from the theme and apply it to the root window. + Cursor handle = XcursorLibraryLoadCursor(QX11Info::display(), "left_ptr"); + XDefineCursor(QX11Info::display(), QX11Info::appRootWindow(), handle); + XFreeCursor(QX11Info::display(), handle); // Don't leak the cursor + + // Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment + // variables when launching applications. + if(!theme.isEmpty()) + KToolInvocation::klauncher()->setLaunchEnv("XCURSOR_THEME", theme); + if( !size.isEmpty()) + KToolInvocation::klauncher()->setLaunchEnv("XCURSOR_SIZE", size); + +#endif + + delete config; + } +} + + diff --git a/kcontrol/input/mouse.cpp b/kcontrol/input/mouse.cpp new file mode 100644 index 00000000..cebb1747 --- /dev/null +++ b/kcontrol/input/mouse.cpp @@ -0,0 +1,821 @@ +/* + * mouse.cpp + * + * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca + * + * Layout management, enhancements: + * Copyright (c) 1999 Dirk A. Mueller + * + * SC/DC/AutoSelect/ChangeCursor: + * Copyright (c) 2000 David Faure + * + * Double click interval, drag time & dist + * Copyright (c) 2000 Bernd Gehrmann + * + * Large cursor support + * Visual activation TODO: speed + * Copyright (c) 2000 Rik Hemsley + * + * White cursor support + * TODO: give user the option to choose a certain cursor font + * -> Theming + * + * General/Advanced tabs + * Copyright (c) 2000 Brad Hughes + * + * redesign for KDE 2.2 + * Copyright (c) 2001 Ralf Nolden + * + * Logitech mouse support + * Copyright (C) 2004 Brad Hards + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#undef Below +#undef Above +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mouse.h" + +#include +#include +#include +#include +#include + +#undef Below + + +K_PLUGIN_FACTORY(MouseConfigFactory, + registerPlugin(); // mouse + ) +K_EXPORT_PLUGIN(MouseConfigFactory("kcminput")) + +MouseConfig::MouseConfig(QWidget *parent, const QVariantList &args) + : KCModule(MouseConfigFactory::componentData(), parent, args) +{ + + + setQuickHelp( i18n("

    Mouse

    This module allows you to choose various" + " options for the way in which your pointing device works. Your" + " pointing device may be a mouse, trackball, or some other hardware" + " that performs a similar function.")); + + QString wtstr; + + QBoxLayout *top = new QVBoxLayout(this); + top->setMargin(0); + + tabwidget = new QTabWidget(this); + top->addWidget(tabwidget); + + generalTab = new KMouseDlg(this); + QButtonGroup *group = new QButtonGroup( generalTab ); + group->setExclusive( true ); + group->addButton( generalTab->singleClick ); + group->addButton( generalTab->doubleClick ); + + tabwidget->addTab(generalTab, i18n("&General")); + + group = new QButtonGroup( generalTab ); + group->setExclusive( true ); + group->addButton( generalTab->rightHanded,RIGHT_HANDED ); + group->addButton( generalTab->leftHanded,LEFT_HANDED ); + + connect(group, SIGNAL(buttonClicked(int)), this, SLOT(changed())); + connect(group, SIGNAL(buttonClicked(int)), this, SLOT(slotHandedChanged(int))); + + wtstr = i18n("If you are left-handed, you may prefer to swap the" + " functions of the left and right buttons on your pointing device" + " by choosing the 'left-handed' option. If your pointing device" + " has more than two buttons, only those that function as the" + " left and right buttons are affected. For example, if you have" + " a three-button mouse, the middle button is unaffected."); + generalTab->handedBox->setWhatsThis( wtstr ); + + connect(generalTab->doubleClick, SIGNAL(clicked()), SLOT(changed())); + + wtstr = i18n("The default behavior in KDE is to select and activate" + " icons with a single click of the left button on your pointing" + " device. This behavior is consistent with what you would expect" + " when you click links in most web browsers. If you would prefer" + " to select with a single click, and activate with a double click," + " check this option."); + generalTab->doubleClick->setWhatsThis( wtstr ); + + wtstr = i18n("Activates and opens a file or folder with a single click."); + generalTab->singleClick->setWhatsThis( wtstr ); + + + connect(generalTab->cbAutoSelect, SIGNAL(clicked()), this, SLOT(changed())); + + wtstr = i18n("If you check this option, pausing the mouse pointer" + " over an icon on the screen will automatically select that icon." + " This may be useful when single clicks activate icons, and you" + " want only to select the icon without activating it."); + generalTab->cbAutoSelect->setWhatsThis( wtstr ); + + wtstr = i18n("If you have checked the option to automatically select" + " icons, this slider allows you to select how long the mouse pointer" + " must be paused over the icon before it is selected."); + generalTab->slAutoSelect->setWhatsThis( wtstr ); + + connect(generalTab->slAutoSelect, SIGNAL(valueChanged(int)), this, SLOT(changed())); + + connect(generalTab->cb_pointershape, SIGNAL(clicked()), this, SLOT(changed())); + + connect(generalTab->singleClick, SIGNAL(clicked()), this, SLOT(changed())); + connect(generalTab->singleClick, SIGNAL(clicked()), this, SLOT(slotClick())); + connect(generalTab->singleClick, SIGNAL(clicked()), this, SLOT(slotSmartSliderEnabling())); + + connect( generalTab->doubleClick, SIGNAL(clicked()), this, SLOT(slotClick()) ); + connect( generalTab->cbAutoSelect, SIGNAL(clicked()), this, SLOT(slotClick()) ); + connect(generalTab->cbAutoSelect, SIGNAL(clicked()), this, SLOT(slotSmartSliderEnabling())); + + + // Only allow setting reversing scroll polarity if we have scroll buttons + unsigned char map[20]; + if ( XGetPointerMapping(QX11Info::display(), map, 20) >= 5 ) + { + generalTab->cbScrollPolarity->setEnabled( true ); + generalTab->cbScrollPolarity->show(); + } + else + { + generalTab->cbScrollPolarity->setEnabled( false ); + generalTab->cbScrollPolarity->hide(); + } + connect(generalTab->cbScrollPolarity, SIGNAL(clicked()), this, SLOT(changed())); + connect(generalTab->cbScrollPolarity, SIGNAL(clicked()), this, SLOT(slotScrollPolarityChanged())); + + // Advanced tab + advancedTab = new QWidget(0); + advancedTab->setObjectName("Advanced Tab"); + tabwidget->addTab(advancedTab, i18n("Advanced")); + + QFormLayout *lay = new QFormLayout(advancedTab); + + accel = new KDoubleNumInput(0.1, 20, 2, advancedTab, 0.1, 1); + accel->setSuffix(i18n(" x")); + lay->addRow(i18n("Pointer acceleration:"), accel); + connect(accel, SIGNAL(valueChanged(double)), this, SLOT(changed())); + + wtstr = i18n("

    This option allows you to change the relationship" + " between the distance that the mouse pointer moves on the" + " screen and the relative movement of the physical device" + " itself (which may be a mouse, trackball, or some other" + " pointing device.)

    " + " A high value for the acceleration will lead to large" + " movements of the mouse pointer on the screen even when" + " you only make a small movement with the physical device." + " Selecting very high values may result in the mouse pointer" + " flying across the screen, making it hard to control.

    "); + accel->setWhatsThis( wtstr ); + + thresh = new KIntNumInput(20, advancedTab); + thresh->setRange(0,20,1); + thresh->setSteps(1,1); + lay->addRow(i18n("Pointer threshold:"), thresh); + connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(slotThreshChanged(int))); + slotThreshChanged(thresh->value()); + + wtstr = i18n("

    The threshold is the smallest distance that the" + " mouse pointer must move on the screen before acceleration" + " has any effect. If the movement is smaller than the threshold," + " the mouse pointer moves as if the acceleration was set to 1X;

    " + " thus, when you make small movements with the physical device," + " there is no acceleration at all, giving you a greater degree" + " of control over the mouse pointer. With larger movements of" + " the physical device, you can move the mouse pointer" + " rapidly to different areas on the screen.

    "); + thresh->setWhatsThis( wtstr ); + + // It would be nice if the user had a test field. + // Selecting such values in milliseconds is not intuitive + doubleClickInterval = new KIntNumInput(2000, advancedTab); + doubleClickInterval->setRange(0, 2000, 100); + doubleClickInterval->setSuffix(i18n(" msec")); + doubleClickInterval->setSteps(100, 100); + lay->addRow(i18n("Double click interval:"), doubleClickInterval); + connect(doubleClickInterval, SIGNAL(valueChanged(int)), this, SLOT(changed())); + + wtstr = i18n("The double click interval is the maximal time" + " (in milliseconds) between two mouse clicks which" + " turns them into a double click. If the second" + " click happens later than this time interval after" + " the first click, they are recognized as two" + " separate clicks."); + doubleClickInterval->setWhatsThis( wtstr ); + + dragStartTime = new KIntNumInput(2000, advancedTab); + dragStartTime->setRange(0, 2000, 100); + dragStartTime->setSuffix(i18n(" msec")); + dragStartTime->setSteps(100, 100); + lay->addRow(i18n("Drag start time:"), dragStartTime); + connect(dragStartTime, SIGNAL(valueChanged(int)), this, SLOT(changed())); + + wtstr = i18n("If you click with the mouse (e.g. in a multi-line" + " editor) and begin to move the mouse within the" + " drag start time, a drag operation will be initiated."); + dragStartTime->setWhatsThis( wtstr ); + + dragStartDist = new KIntNumInput(20, advancedTab); + dragStartDist->setRange(1, 20, 1); + dragStartDist->setSteps(1,1); + lay->addRow(i18n("Drag start distance:"), dragStartDist); + connect(dragStartDist, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(dragStartDist, SIGNAL(valueChanged(int)), this, SLOT(slotDragStartDistChanged(int))); + slotDragStartDistChanged(dragStartDist->value()); + + wtstr = i18n("If you click with the mouse and begin to move the" + " mouse at least the drag start distance, a drag" + " operation will be initiated."); + dragStartDist->setWhatsThis( wtstr ); + + wheelScrollLines = new KIntNumInput(3, advancedTab); + wheelScrollLines->setRange(1, 12, 1); + wheelScrollLines->setSteps(1,1); + lay->addRow(i18n("Mouse wheel scrolls by:"), wheelScrollLines); + connect(wheelScrollLines, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(wheelScrollLines, SIGNAL(valueChanged(int)), SLOT(slotWheelScrollLinesChanged(int))); + slotWheelScrollLinesChanged(wheelScrollLines->value()); + + wtstr = i18n("If you use the wheel of a mouse, this value determines the number of lines to scroll for each wheel movement. Note that if this number exceeds the number of visible lines, it will be ignored and the wheel movement will be handled as a page up/down movement."); + wheelScrollLines->setWhatsThis(wtstr); + +{ + QWidget *mouse = new QWidget(this); + mouse->setObjectName("Mouse Navigation"); + tabwidget->addTab(mouse, i18n("Mouse Navigation")); + + QFormLayout *form = new QFormLayout(mouse); + + mouseKeys = new QCheckBox(i18n("&Move pointer with keyboard (using the num pad)"), mouse); + form->addRow(mouseKeys); + + mk_delay = new KIntNumInput(mouse); + mk_delay->setRange(1, 1000, 50); + mk_delay->setSuffix(i18n(" msec")); + form->addRow(i18n("&Acceleration delay:"), mk_delay); + + mk_interval = new KIntNumInput(0, mouse); + mk_interval->setRange(1, 1000, 10); + mk_interval->setSuffix(i18n(" msec")); + form->addRow(i18n("R&epeat interval:"), mk_interval); + + mk_time_to_max = new KIntNumInput(0, mouse); + mk_time_to_max->setRange(100, 10000, 200); + mk_time_to_max->setSuffix(i18n(" msec")); + form->addRow(i18n("Acceleration &time:"), mk_time_to_max); + + mk_max_speed = new KIntNumInput(0, mouse); + mk_max_speed->setRange(1, 2000, 20); + mk_max_speed->setSuffix(i18n(" pixel/sec")); + form->addRow(i18n("Ma&ximum speed:"), mk_max_speed); + + mk_curve = new KIntNumInput(0, mouse); + mk_curve->setRange(-1000, 1000, 100); + form->addRow(i18n("Acceleration &profile:"), mk_curve); + + connect(mouseKeys, SIGNAL(clicked()), this, SLOT(checkAccess())); + connect(mouseKeys, SIGNAL(clicked()), this, SLOT(changed())); + connect(mk_delay, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(mk_interval, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(mk_time_to_max, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(mk_max_speed, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(mk_curve, SIGNAL(valueChanged(int)), this, SLOT(changed())); +} + + settings = new MouseSettings; + + // This part is for handling features on Logitech USB mice. + // It only works if libusb is available. +#ifdef HAVE_LIBUSB + + static const + struct device_table { + int idVendor; + int idProduct; + const char* Model; + const char* Name; + int flags; + } device_table[] = { + { VENDOR_LOGITECH, 0xC00E, "M-BJ58", "Wheel Mouse Optical", HAS_RES }, + { VENDOR_LOGITECH, 0xC00F, "M-BJ79", "MouseMan Traveler", HAS_RES }, + { VENDOR_LOGITECH, 0xC012, "M-BL63B", "MouseMan Dual Optical", HAS_RES }, + { VENDOR_LOGITECH, 0xC01B, "M-BP86", "MX310 Optical Mouse", HAS_RES }, + { VENDOR_LOGITECH, 0xC01D, "M-BS81A", "MX510 Optical Mouse", HAS_RES | HAS_SS | HAS_SSR }, + { VENDOR_LOGITECH, 0xC024, "M-BP82", "MX300 Optical Mouse", HAS_RES }, + { VENDOR_LOGITECH, 0xC025, "M-BP81A", "MX500 Optical Mouse", HAS_RES | HAS_SS | HAS_SSR }, + { VENDOR_LOGITECH, 0xC031, "M-UT58A", "iFeel Mouse (silver)", HAS_RES }, + { VENDOR_LOGITECH, 0xC501, "C-BA4-MSE", "Mouse Receiver", HAS_CSR }, + { VENDOR_LOGITECH, 0xC502, "C-UA3-DUAL", "Dual Receiver", HAS_CSR | USE_CH2}, + { VENDOR_LOGITECH, 0xC504, "C-BD9-DUAL", "Cordless Freedom Optical", HAS_CSR | USE_CH2 }, + { VENDOR_LOGITECH, 0xC505, "C-BG17-DUAL", "Cordless Elite Duo", HAS_SS | HAS_SSR | HAS_CSR | USE_CH2}, + { VENDOR_LOGITECH, 0xC506, "C-BF16-MSE", "MX700 Optical Mouse", HAS_SS | HAS_CSR }, + { VENDOR_LOGITECH, 0xC508, "C-BA4-MSE", "Cordless Optical TrackMan", HAS_SS | HAS_CSR }, + { VENDOR_LOGITECH, 0xC50B, "967300-0403", "Cordless MX Duo Receiver", HAS_SS|HAS_CSR }, + { VENDOR_LOGITECH, 0xC50E, "M-RAG97", "MX1000 Laser Mouse", HAS_SS | HAS_CSR }, + { VENDOR_LOGITECH, 0xC702, "C-UF15", "Receiver for Cordless Presenter", HAS_CSR }, + { 0, 0, 0, 0, 0 } + }; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + struct usb_bus *bus; + struct usb_device *dev; + + for (bus = usb_busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + for (int n = 0; device_table[n].idVendor; n++) + if ( (device_table[n].idVendor == dev->descriptor.idVendor) && + (device_table[n].idProduct == dev->descriptor.idProduct) ) { + // OK, we have a device that appears to be one of the ones we support + LogitechMouse *mouse = new LogitechMouse( dev, device_table[n].flags, this, device_table[n].Name ); + settings->logitechMouseList.append(mouse); + tabwidget->addTab( (QWidget*)mouse, device_table[n].Name ); + } + } + } + +#endif + + KAboutData* about = new KAboutData("kcmmouse", 0, ki18n("Mouse"), 0, KLocalizedString(), + KAboutData::License_GPL, ki18n("(c) 1997 - 2005 Mouse developers")); + about->addAuthor(ki18n("Patrick Dowler")); + about->addAuthor(ki18n("Dirk A. Mueller")); + about->addAuthor(ki18n("David Faure")); + about->addAuthor(ki18n("Bernd Gehrmann")); + about->addAuthor(ki18n("Rik Hemsley")); + about->addAuthor(ki18n("Brad Hughes")); + about->addAuthor(ki18n("Ralf Nolden")); + about->addAuthor(ki18n("Brad Hards")); + setAboutData( about ); +} + +void MouseConfig::checkAccess() +{ + mk_delay->setEnabled(mouseKeys->isChecked()); + mk_interval->setEnabled(mouseKeys->isChecked()); + mk_time_to_max->setEnabled(mouseKeys->isChecked()); + mk_max_speed->setEnabled(mouseKeys->isChecked()); + mk_curve->setEnabled(mouseKeys->isChecked()); +} + + +MouseConfig::~MouseConfig() +{ + delete settings; +} + +double MouseConfig::getAccel() +{ + return accel->value(); +} + +void MouseConfig::setAccel(double val) +{ + accel->setValue(val); +} + +int MouseConfig::getThreshold() +{ + return thresh->value(); +} + +void MouseConfig::setThreshold(int val) +{ + thresh->setValue(val); +} + + +int MouseConfig::getHandedness() +{ + if (generalTab->rightHanded->isChecked()) + return RIGHT_HANDED; + else + return LEFT_HANDED; +} + +void MouseConfig::setHandedness(int val) +{ + generalTab->rightHanded->setChecked(false); + generalTab->leftHanded->setChecked(false); + if (val == RIGHT_HANDED){ + generalTab->rightHanded->setChecked(true); + generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + } + else{ + generalTab->leftHanded->setChecked(true); + generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); + } + settings->m_handedNeedsApply = true; +} + +void MouseConfig::load() +{ + KConfig config( "kcminputrc" ); + settings->load(&config); + + generalTab->rightHanded->setEnabled(settings->handedEnabled); + generalTab->leftHanded->setEnabled(settings->handedEnabled); + if ( generalTab->cbScrollPolarity->isEnabled() ) + generalTab->cbScrollPolarity->setEnabled(settings->handedEnabled); + generalTab->cbScrollPolarity->setChecked( settings->reverseScrollPolarity ); + + setAccel(settings->accelRate); + setThreshold(settings->thresholdMove); + setHandedness(settings->handed); + + doubleClickInterval->setValue(settings->doubleClickInterval); + dragStartTime->setValue(settings->dragStartTime); + dragStartDist->setValue(settings->dragStartDist); + wheelScrollLines->setValue(settings->wheelScrollLines); + + generalTab->singleClick->setChecked( settings->singleClick ); + generalTab->doubleClick->setChecked(!settings->singleClick); + generalTab->cb_pointershape->setChecked(settings->changeCursor); + generalTab->cbAutoSelect->setChecked( settings->autoSelectDelay >= 0 ); + if ( settings->autoSelectDelay < 0 ) + generalTab->slAutoSelect->setValue( 0 ); + else + generalTab->slAutoSelect->setValue( settings->autoSelectDelay ); + slotClick(); + + + KConfig ac("kaccessrc"); + + KConfigGroup group = ac.group("Mouse"); + mouseKeys->setChecked(group.readEntry("MouseKeys", false)); + mk_delay->setValue(group.readEntry("MKDelay", 160)); + + int interval = group.readEntry("MKInterval", 5); + mk_interval->setValue(interval); + + // Default time to reach maximum speed: 5000 msec + int time_to_max = group.readEntry("MKTimeToMax", (5000+interval/2)/interval); + time_to_max = group.readEntry("MK-TimeToMax", time_to_max*interval); + mk_time_to_max->setValue(time_to_max); + + // Default maximum speed: 1000 pixels/sec + // (The old default maximum speed from KDE <= 3.4 + // (100000 pixels/sec) was way too fast) + long max_speed = group.readEntry("MKMaxSpeed", interval); + max_speed = max_speed * 1000 / interval; + if (max_speed > 2000) + max_speed = 2000; + max_speed = group.readEntry("MK-MaxSpeed", int(max_speed)); + mk_max_speed->setValue(max_speed); + + mk_curve->setValue(group.readEntry("MKCurve", 0)); + + checkAccess(); + + emit changed(false); +} + +void MouseConfig::save() +{ + settings->accelRate = getAccel(); + settings->thresholdMove = getThreshold(); + settings->handed = getHandedness(); + + settings->doubleClickInterval = doubleClickInterval->value(); + settings->dragStartTime = dragStartTime->value(); + settings->dragStartDist = dragStartDist->value(); + settings->wheelScrollLines = wheelScrollLines->value(); + settings->singleClick = !generalTab->doubleClick->isChecked(); + settings->autoSelectDelay = generalTab->cbAutoSelect->isChecked()? generalTab->slAutoSelect->value():-1; +// settings->changeCursor = generalTab->singleClick->isChecked(); + settings->changeCursor = generalTab->cb_pointershape->isChecked(); + settings->reverseScrollPolarity = generalTab->cbScrollPolarity->isChecked(); + + settings->apply(); + KConfig config( "kcminputrc" ); + settings->save(&config); + + KConfig ac("kaccessrc"); + + KConfigGroup group = ac.group("Mouse"); + + int interval = mk_interval->value(); + group.writeEntry("MouseKeys", mouseKeys->isChecked()); + group.writeEntry("MKDelay", mk_delay->value()); + group.writeEntry("MKInterval", interval); + group.writeEntry("MK-TimeToMax", mk_time_to_max->value()); + group.writeEntry("MKTimeToMax", + (mk_time_to_max->value() + interval/2)/interval); + group.writeEntry("MK-MaxSpeed", mk_max_speed->value()); + group.writeEntry("MKMaxSpeed", + (mk_max_speed->value()*interval + 500)/1000); + group.writeEntry("MKCurve", mk_curve->value()); + group.sync(); + group.writeEntry("MKCurve", mk_curve->value()); + + // restart kaccess + KToolInvocation::startServiceByDesktopName("kaccess"); + + emit changed(false); +} + +void MouseConfig::defaults() +{ + setThreshold(2); + setAccel(2); + setHandedness(RIGHT_HANDED); + generalTab->cbScrollPolarity->setChecked( false ); + doubleClickInterval->setValue(400); + dragStartTime->setValue(500); + dragStartDist->setValue(4); + wheelScrollLines->setValue(3); + generalTab->doubleClick->setChecked( !KDE_DEFAULT_SINGLECLICK ); + generalTab->cbAutoSelect->setChecked( KDE_DEFAULT_AUTOSELECTDELAY != -1 ); + generalTab->slAutoSelect->setValue( KDE_DEFAULT_AUTOSELECTDELAY == -1 ? 50 : KDE_DEFAULT_AUTOSELECTDELAY ); + generalTab->singleClick->setChecked( KDE_DEFAULT_SINGLECLICK ); + generalTab->cb_pointershape->setChecked(KDE_DEFAULT_CHANGECURSOR); + slotClick(); + + mouseKeys->setChecked(false); + mk_delay->setValue(160); + mk_interval->setValue(5); + mk_time_to_max->setValue(5000); + mk_max_speed->setValue(1000); + mk_curve->setValue(0); + + checkAccess(); + + changed(); +} + +void MouseConfig::slotClick() +{ + // Autoselect has a meaning only in single-click mode + generalTab->cbAutoSelect->setEnabled(!generalTab->doubleClick->isChecked() || generalTab->singleClick->isChecked()); + // Delay has a meaning only for autoselect + bool bDelay = generalTab->cbAutoSelect->isChecked() && ! generalTab->doubleClick->isChecked(); + generalTab->slAutoSelect->setEnabled( bDelay ); +} + +/** No descriptions */ +void MouseConfig::slotHandedChanged(int val){ + if(val==RIGHT_HANDED) + generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + else + generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); + settings->m_handedNeedsApply = true; +} + +void MouseSettings::load(KConfig *config) +{ + int accel_num, accel_den, threshold; + double accel; + XGetPointerControl( QX11Info::display(), + &accel_num, &accel_den, &threshold ); + accel = float(accel_num) / float(accel_den); + + // get settings from X server + int h = RIGHT_HANDED; + unsigned char map[20]; + num_buttons = XGetPointerMapping(QX11Info::display(), map, 20); + + handedEnabled = true; + + // ## keep this in sync with KGlobalSettings::mouseSettings + if( num_buttons == 1 ) + { + /* disable button remapping */ + handedEnabled = false; + } + else if( num_buttons == 2 ) + { + if ( (int)map[0] == 1 && (int)map[1] == 2 ) + h = RIGHT_HANDED; + else if ( (int)map[0] == 2 && (int)map[1] == 1 ) + h = LEFT_HANDED; + else + /* custom button setup: disable button remapping */ + handedEnabled = false; + } + else + { + middle_button = (int)map[1]; + if ( (int)map[0] == 1 && (int)map[2] == 3 ) + h = RIGHT_HANDED; + else if ( (int)map[0] == 3 && (int)map[2] == 1 ) + h = LEFT_HANDED; + else + { + /* custom button setup: disable button remapping */ + handedEnabled = false; + } + } + + KConfigGroup group = config->group("Mouse"); + double a = group.readEntry("Acceleration",-1.0); + if (a == -1) + accelRate = accel; + else + accelRate = a; + + int t = group.readEntry("Threshold",-1); + if (t == -1) + thresholdMove = threshold; + else + thresholdMove = t; + + QString key = group.readEntry("MouseButtonMapping"); + if (key == "RightHanded") + handed = RIGHT_HANDED; + else if (key == "LeftHanded") + handed = LEFT_HANDED; +#ifdef __GNUC__ +#warning was key == NULL how was this working? is key.isNull() what the coder meant? +#endif + else if (key.isNull()) + handed = h; + reverseScrollPolarity = group.readEntry( "ReverseScrollPolarity", false); + m_handedNeedsApply = false; + + // SC/DC/AutoSelect/ChangeCursor + group = config->group("KDE"); + doubleClickInterval = group.readEntry("DoubleClickInterval", 400); + dragStartTime = group.readEntry("StartDragTime", 500); + dragStartDist = group.readEntry("StartDragDist", 4); + wheelScrollLines = group.readEntry("WheelScrollLines", 3); + + singleClick = group.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK); + autoSelectDelay = group.readEntry("AutoSelectDelay", KDE_DEFAULT_AUTOSELECTDELAY); + changeCursor = group.readEntry("ChangeCursor", KDE_DEFAULT_CHANGECURSOR); +} + +void MouseConfig::slotThreshChanged(int value) +{ + thresh->setSuffix(i18np(" pixel", " pixels", value)); +} + +void MouseConfig::slotDragStartDistChanged(int value) +{ + dragStartDist->setSuffix(i18np(" pixel", " pixels", value)); +} + +void MouseConfig::slotWheelScrollLinesChanged(int value) +{ + wheelScrollLines->setSuffix(i18np(" line", " lines", value)); +} + +void MouseSettings::apply(bool force) +{ + XChangePointerControl( QX11Info::display(), + true, true, int(qRound(accelRate*10)), 10, thresholdMove); + + // 256 might seems extreme, but X has already been known to return 32, + // and we don't want to truncate things. Xlib limits the table to 256 bytes, + // so it's a good uper bound.. + unsigned char map[256]; + num_buttons = XGetPointerMapping(QX11Info::display(), map, 256); + + int remap=(num_buttons>=1); + if (handedEnabled && (m_handedNeedsApply || force)) { + if( num_buttons == 1 ) + { + map[0] = (unsigned char) 1; + } + else if( num_buttons == 2 ) + { + if (handed == RIGHT_HANDED) + { + map[0] = (unsigned char) 1; + map[1] = (unsigned char) 3; + } + else + { + map[0] = (unsigned char) 3; + map[1] = (unsigned char) 1; + } + } + else // 3 buttons and more + { + if (handed == RIGHT_HANDED) + { + map[0] = (unsigned char) 1; + map[1] = (unsigned char) middle_button; + map[2] = (unsigned char) 3; + } + else + { + map[0] = (unsigned char) 3; + map[1] = (unsigned char) middle_button; + map[2] = (unsigned char) 1; + } + if( num_buttons >= 5 ) + { + // Apps seem to expect logical buttons 4,5 are the vertical wheel. + // With mice with more than 3 buttons (not including wheel) the physical + // buttons mapped to logical 4,5 may not be physical 4,5 , so keep + // this mapping, only possibly reversing them. + int pos; + for( pos = 0; pos < num_buttons; ++pos ) + if( map[pos] == 4 || map[pos] == 5 ) + break; + if( pos < num_buttons - 1 ) + { + map[pos] = reverseScrollPolarity ? (unsigned char) 5 : (unsigned char) 4; + map[pos+1] = reverseScrollPolarity ? (unsigned char) 4 : (unsigned char) 5; + } + } + } + int retval; + if (remap) + while ((retval=XSetPointerMapping(QX11Info::display(), map, + num_buttons)) == MappingBusy) + /* keep trying until the pointer is free */ + { }; + m_handedNeedsApply = false; + } + + // This iterates through the various Logitech mice, if we have support. + #ifdef HAVE_LIBUSB + LogitechMouse *logitechMouse; + Q_FOREACH( logitechMouse, logitechMouseList ) { + logitechMouse->applyChanges(); + } + #endif +} + +void MouseSettings::save(KConfig *config) +{ + KConfigGroup group = config->group("Mouse"); + group.writeEntry("Acceleration",accelRate); + group.writeEntry("Threshold",thresholdMove); + if (handed == RIGHT_HANDED) + group.writeEntry("MouseButtonMapping",QString("RightHanded")); + else + group.writeEntry("MouseButtonMapping",QString("LeftHanded")); + group.writeEntry( "ReverseScrollPolarity", reverseScrollPolarity ); + + group = config->group("KDE"); + group.writeEntry("DoubleClickInterval", doubleClickInterval, KConfig::Persistent|KConfig::Global); + group.writeEntry("StartDragTime", dragStartTime, KConfig::Persistent|KConfig::Global); + group.writeEntry("StartDragDist", dragStartDist, KConfig::Persistent|KConfig::Global); + group.writeEntry("WheelScrollLines", wheelScrollLines, KConfig::Persistent|KConfig::Global); + group.writeEntry("SingleClick", singleClick, KConfig::Persistent|KConfig::Global); + group.writeEntry("AutoSelectDelay", autoSelectDelay, KConfig::Persistent|KConfig::Global); + group.writeEntry("ChangeCursor", changeCursor,KConfig::Persistent|KConfig::Global); + // This iterates through the various Logitech mice, if we have support. +#ifdef HAVE_LIBUSB + LogitechMouse *logitechMouse; + Q_FOREACH( logitechMouse, logitechMouseList ) { + logitechMouse->save(config); + } +#endif + config->sync(); + KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); +} + +void MouseConfig::slotScrollPolarityChanged() +{ + settings->m_handedNeedsApply = true; +} + +void MouseConfig::slotSmartSliderEnabling() +{ + bool enabled = generalTab->singleClick->isChecked() ? generalTab->cbAutoSelect->isChecked() : false; + generalTab->slAutoSelect->setEnabled(enabled); +} + +#include "mouse.moc" diff --git a/kcontrol/input/mouse.desktop b/kcontrol/input/mouse.desktop new file mode 100644 index 00000000..81c029e9 --- /dev/null +++ b/kcontrol/input/mouse.desktop @@ -0,0 +1,237 @@ +[Desktop Entry] +Exec=kcmshell4 mouse +Icon=preferences-desktop-mouse +Type=Service +X-KDE-ServiceTypes=KCModule,KCModuleInit +X-DocPath=kcontrol/mouse/index.html + +X-KDE-Library=kcm_input +X-KDE-Init-Symbol=mouse +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=input-devices +X-KDE-Weight=60 + +Name=Mouse +Name[af]=Muis +Name[ar]=الفأرة +Name[ast]=Mur +Name[be]=Мыш +Name[be@latin]=Myš +Name[bg]=Мишка +Name[bn]=মাউস +Name[bn_IN]=মাউস +Name[br]=Logodenn +Name[bs]=Miš +Name[ca]=Ratolí +Name[ca@valencia]=Ratolí +Name[cs]=Myš +Name[csb]=Mësz +Name[cy]=Llygoden +Name[da]=Mus +Name[de]=Maus +Name[el]=Ποντίκι +Name[en_GB]=Mouse +Name[eo]=Muso +Name[es]=Ratón +Name[et]=Hiir +Name[eu]=Sagua +Name[fa]=موشی +Name[fi]=Hiiri +Name[fr]=Souris +Name[fy]=Mûs +Name[ga]=Luch +Name[gl]=Rato +Name[gu]=માઉસ +Name[he]=עכבר +Name[hi]=माउस +Name[hne]=मुसुवा +Name[hr]=Miš +Name[hsb]=Myš +Name[hu]=Egér +Name[ia]=Mus +Name[id]=Tetikus +Name[is]=Mús +Name[it]=Mouse +Name[ja]=マウス +Name[ka]=თაგვი +Name[kk]=Тышқан +Name[km]=កណ្ដុរ +Name[kn]=ಮೂಷಕ (ಮೌಸ್) +Name[ko]=마우스 +Name[ku]=Mişk +Name[lt]=Pelė +Name[lv]=Pele +Name[mai]=माउस +Name[mk]=Глушец +Name[ml]=മൌസ് +Name[mr]=माऊस +Name[ms]=Tetikus +Name[nb]=Mus +Name[nds]=Muus +Name[ne]=माउस +Name[nl]=Muis +Name[nn]=Mus +Name[oc]=Mirga +Name[or]=ମାଉସ +Name[pa]=ਮਾਊਸ +Name[pl]=Mysz +Name[pt]=Rato +Name[pt_BR]=Mouse +Name[ro]=Maus +Name[ru]=Мышь +Name[se]=Sáhpán +Name[si]=මවුසය +Name[sk]=Myš +Name[sl]=Miška +Name[sr]=Миш +Name[sr@ijekavian]=Миш +Name[sr@ijekavianlatin]=Miš +Name[sr@latin]=Miš +Name[sv]=Mus +Name[ta]=சுட்டி +Name[te]=మౌస్ +Name[tg]=Муш +Name[th]=เมาส์ +Name[tr]=Fare +Name[ug]=چاشقىنەك +Name[uk]=Мишка +Name[uz]=Sichqoncha +Name[uz@cyrillic]=Сичқонча +Name[vi]=Chuột +Name[wa]=Sori +Name[xh]=Mouse +Name[x-test]=xxMousexx +Name[zh_CN]=鼠标 +Name[zh_TW]=滑鼠 + +Comment=Mouse settings +Comment[af]=Muis instellings +Comment[ar]=إعدادات الفأرة +Comment[ast]=Preferencies sobre'l mur +Comment[be]=Настаўленні мышы +Comment[be@latin]=Nałady myšy +Comment[bg]=Настройки на мишка +Comment[bn]=মাউস সেটিংস +Comment[bn_IN]=মাউস সংক্রান্ত বৈশিষ্ট্য +Comment[br]=Kefluniañ al logodenn +Comment[bs]=Postavke miša +Comment[ca]=Arranjament del ratolí +Comment[ca@valencia]=Arranjament del ratolí +Comment[cs]=Nastavení myši +Comment[csb]=Nastôw mëszë +Comment[cy]=Gosodiadau Llygoden +Comment[da]=Indstilling af mus +Comment[de]=Einstellung der Maus +Comment[el]=Ρυθμίσεις Ποντικιού +Comment[en_GB]=Mouse settings +Comment[eo]=Agordo de la muso +Comment[es]=Preferencias sobre el ratón +Comment[et]=Hiire seadistused +Comment[eu]=Saguaren ezarpenak +Comment[fa]=تنظیمات موشی +Comment[fi]=Hiiren asetukset +Comment[fy]=Mûsynstellings +Comment[ga]=Socruithe luiche +Comment[gl]=Configuración do rato +Comment[gu]=માઉસ ગોઠવણીઓ +Comment[he]=הגדרות העכבר +Comment[hi]=माउस विन्यास +Comment[hne]=मुसुवा सेटिंग +Comment[hr]=Postavke miša +Comment[hsb]=Nastajenja za myš +Comment[hu]=Az egér beállításai +Comment[ia]=Preferentias de mus +Comment[id]=Pengaturan tetikus +Comment[is]=Stillingar músar +Comment[ka]=თაგვის კონფიგურაცია +Comment[kk]=Тышқан параметрлері +Comment[km]=ការ​កំណត់​កណ្ដុរ +Comment[kn]=ಮೂಷಕದ (ಮೌಸ್) ಸಂಯೋಜನೆಗಳು +Comment[ko]=마우스 설정 +Comment[ku]=Mîhengên Mişkî +Comment[lt]=Pelės parametrai +Comment[lv]=Peles parametri +Comment[mai]=माउस बिन्यास +Comment[mk]=Поставувања на глушецот +Comment[ml]=മൌസിന്റെ സജ്ജീകരണങ്ങള്‍ +Comment[mr]=माऊस संयोजना +Comment[ms]=Seting tetikus +Comment[nb]=Musinnstillinger +Comment[nds]=De Muus instellen +Comment[ne]=माउस सेटिङ +Comment[nl]=Muisinstellingen +Comment[nn]=Musinnstillingar +Comment[or]=ମାଉସ ବିନ୍ୟାସ +Comment[pa]=ਮਾਊਸ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia myszy +Comment[pt]=Configuração do rato +Comment[pt_BR]=Configurações do mouse +Comment[ro]=Configurări maus +Comment[ru]=Настройка мыши +Comment[se]=Sáhpánheivehusat +Comment[si]=මවුසයේ සැකසුම් +Comment[sk]=Nastavenie myši +Comment[sl]=Nastavitve miške +Comment[sr]=Поставке миша +Comment[sr@ijekavian]=Поставке миша +Comment[sr@ijekavianlatin]=Postavke miša +Comment[sr@latin]=Postavke miša +Comment[sv]=Anpassa mus +Comment[ta]=சுட்டி அமைப்புகள் +Comment[te]=మౌస్ అమరికలు +Comment[tg]=Танзимоти муш +Comment[th]=ตั้งค่าต่างๆ ของเมาส์ +Comment[tr]=Fare ayarları +Comment[ug]=چاشقىنەك تەڭشەك +Comment[uk]=Налаштування миші +Comment[uz]=Sichqonchaning moslamalari +Comment[uz@cyrillic]=Сичқончанинг мосламалари +Comment[vi]=Thiết lập con chuột +Comment[wa]=Apontiaedjes del sori +Comment[xh]=Izicwangciso ze mouse +Comment[x-test]=xxMouse settingsxx +Comment[zh_CN]=鼠标设置 +Comment[zh_TW]=滑鼠設定 + +X-KDE-Keywords=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation +X-KDE-Keywords[bs]=Miš, Brzina kretanja miša, Prag osjetljivosti miša, Tasteri miša, Oblik kursora, Ulazni Uređaji, Mapiranje tastera, Klik, Ikone, feedback (povratna veza), Pokazivači, Vuči (drag), Dupli klik, Jedan Klik, Mapiranje, Dešnjak, Ljevak, Uređaj koji je Pokazivač (miš, Trackball, Joystick), Točkić za pomicanje (gore ili dolje), Emulatija Miša, Navigacija Miša, Miš Povucite i ispustite(drag and drop), Skrolanje Mišem, Osjetljivost Miša, Pomjeranje miša pomoću brojevne tastature, Emulacija miša pomoću brojevne tastature +X-KDE-Keywords[ca]=Ratolí,Acceleració de ratolí,Llindar de ratolí,Botons de ratolí,Selecció,Ombra de cursor,Dispositius d'entrada,Mapatge de boton,Clic,icones,reacció,Apuntadors,Arrossegar,Clic doble,Clic normal,mapatge,dretà,esquerrà,Dispositiu apuntador,Roda de ratolí,Emulació de ratolí,Navegació amb ratolí,Arrossegar i deixar anar de ratolí,Desplaçament amb ratolí,Sensitivitat de ratolí,Moure el ratolí amb teclat numèric,Emulació de ratolí amb teclat numèric +X-KDE-Keywords[ca@valencia]=Ratolí,Acceleració de ratolí,Llindar de ratolí,Botons de ratolí,Selecció,Ombra de cursor,Dispositius d'entrada,Mapatge de boton,Clic,icones,reacció,Apuntadors,Arrossegar,Clic doble,Clic normal,mapatge,dretà,esquerrà,Dispositiu apuntador,Roda de ratolí,Emulació de ratolí,Navegació amb ratolí,Arrossegar i deixar anar de ratolí,Desplaçament amb ratolí,Sensitivitat de ratolí,Moure el ratolí amb teclat numèric,Emulació de ratolí amb teclat numèric +X-KDE-Keywords[da]=Mus,Museacceleration,musetærskel,museknapper,markering,markørform,Input-enheder,knapkobling,klik,ikoner,feedback,Pointers,træk,dobbeltklik,enkeltklik,kobling,højrehåndet,venstrehåndet,pegeenhed,musehjul,museemulering,musenavigation,træk og slip,muserulning,scrolling,musefølsomhed,bevæg mus med numerisk tastatur,markører,cursor,rulning +X-KDE-Keywords[de]=Maus,Mausbeschleunigung,Mausschwellwert,Maustasten,Auswahl,Cursor,Cursor-Form,Eingabegeräte,Knöpfe,Buttons,Zuordnungen,Klicks,Zeigegeräte,Doppelklick,Rechtshänder,Linkshänder,Ziehen,Mausrad,Maus-Emulation,Maus-Navigation,Ziehen und Ablegen mit der Maus,Blättern mit der Maus,Maus-Empfindlichkeit,Mauszeiger mit der Zahlentastatur verschieben,Maus-Emulation mit der Zahlentastatur +X-KDE-Keywords[el]=ποντίκι,επιτάχυνση ποντικιού,κατώφλι ποντικιού,κουμπιά ποντικιού,επιλογή,σχήμα δρομέα,συσκευές εισόδου,χαρτογράφηση κουμπιών,κλικ,εικονίδια,ανάδραση,δείκτες,έλξη,διπλό κλικ,μονό κλικ,χαρτογράφηση,δεξιόχειρας,αριστερόχειρας,συσκευή δείκτη,τροχός ποντικιού,εξομοίωση ποντικιού,πλοήγηση ποντικιού,έλξη και απόθεση ποντικιού,κύλιση ποντικιού,ευαισθησία ποντικιού,κίνηση ποντικιού με το αριθμητικό πληκτρολόγιο,εξομοίωση ποντικιού αριθμητικού πληκτρολογίου +X-KDE-Keywords[en_GB]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation +X-KDE-Keywords[es]=Ratón,Aceleración de ratón,Umbral del ratón,Botones del ratón,Selección,Forma del cursor,Dispositivos de entrada,Mapeo de botones,Clic,iconos,reacción,Punteros,Arrastrar,Doble clic,clic sencillo,mapeo,diestro,zurdo,Dispositivo apuntador,Rueda del ratón,Emulación del ratón,Navegación con el ratón,Arrastrar y soltar con el ratón,Desplazamiento con el ratón,Sensibilidad del ratón,Mover el ratón con el teclado numérico,Emulación del ratón con el teclado numérico +X-KDE-Keywords[et]=hiir,hiire kiirendamine,hiire lävi,hiirenupud,valik,kursori kuju,sisendseadmed,nuppude seostamine,klõps,klõpsamine,ikoonid,tagasiside,lohistamine,topeltklõps,ühekordne klõps,seostamine,paremakäelised,vasakukäelised,osutusseade,hiireratas,hiire emuleerimine,hiirega liikumine,hiirega lohistamine,hiirega kerimine,hiire tundlikkus,hiire liigutamine numbriklahvistikuga,hiire numbriklahvistiku emuleerimine +X-KDE-Keywords[eu]=sagu,saguaren azelerazio,saguaren atalase,saguaren botoiak,hautapena,kurtsorearen forma,sarrerako gailuak,botoiak mapatzea,klik,ikonoak,oharrak,erakusle,arrastatu,klik bikoitza,klik bakarra,mapatze,eskuina,ezkerra,erakuslearen gailu,saguaren gurpil,saguaren emulazio,sagu bidezko nabigazio,saguaren bidez arrastatu eta jaregin,saguaren bidez korritu,saguaren sentikortasuna,sagua zenbakizko teklatuarekin mugitzea,sagua emulatzea zenbakizko teklatuarekin +X-KDE-Keywords[fi]=Hiiri,Osoittimen kiihdytys,Osoittimen raja-arvo,Hiiripainikkeet,Valinta,Osoittimen muoto,Syöttölaitteet,Syötelaitteet,Painikkeiden kuvaus,Napsauta,Napsautus,kuvakkeet,tuntuma,Osoittimet,Raahaus,Kaksoisnapsautus,kuvaus,oikeakätinen,oikeakätisyys,vasenkätinen,vasenkätisyys,osoitinlaite,hiiren rulla,hiiren emulointi,hiirinavigointi,hiiren vedä ja pudota,hiiren vieritys,hiiren herkkyys,hiiren liikuttaminen numeronäppäimistöltä +X-KDE-Keywords[fr]=Souris, Accélération de la souris, Seuil de la souris, Boutons de la souris, Sélection, Forme du curseur, Périphériques d'entrée, affectation des boutons, Clic, icônes, réaction, Pointeurs, Glisser, Double clic, Simple clic, affectation, droitier, gaucher, Périphérique de pointage, Roulette de la souris, Émulation de la souris, Navigation de la souris, Glisser-déposer, Défilement de la souris, Sensibilité de la souris, Déplacement de la souris avec le pavé numérique, Émulation de la souris du pavé numérique +X-KDE-Keywords[gl]=rato, aceleración do rato, limiar do rato, botóns do rato, selección, escolla, forma do rato, dispositivos de entrada, mapas de botóns, premer, clic, iconas, punteiro, arrastrar, duplo clic, dobre clic, dereito, zurdo, dispositivo do punteiro, roda do rato, emulación do rato, navegación co rato, arrastrar e soltar co rato, sensibilidade do rato, mover o rato co teclado numérico, teclado numérico +X-KDE-Keywords[hu]=Egér,Egérgyorsítás,Egérküszöb,Egérgombok,Kijelölés,Kurzorforma,Beviteli eszközök,Gombhozzárendelés,Kattintás,ikonok,visszajelzés,Mutatók,Fogás,Dupla kattintás,Egyszeres kattintás,leképezés,jobb kezes,bal kezes,Mutató eszköz,Egérgörgő,Egéremuláció,Egérnavigáció,Egér fogd és vidd,Egérgörgetés,Egér érzékenység,Egér mozgatása numerikus billentyűkkel,Egér numerikus billentyűzet emuláció +X-KDE-Keywords[ia]=Mus,Acceleration de mus,Limine de mus,Buttones de mus,Selection,Forma de cursor, Dispositivos de ingresso,Mappatura de button,Click,icones,retro-information,Punctatores,Trahe,DupleClick,Singule click,mappar,con mano dextere, con mano sinistre,Dispositivo punctator,Rota de Mus,Emulation de mus,Navigation de mus,Traher e Poner con Mus, Rolar con Mus,Sensibilitate de mus, Move Mus con NumPad,Emulation Mus con NumPad +X-KDE-Keywords[it]=mouse,accelerazione del mouse,soglia del mouse,pulsanti del mouse,selezione,forma del cursore,dispositivi di ingresso,mappatura dei pulsanti,clic,icone,segnale di avvio,puntatori,trascinamento,doppio clic,singolo clic,mappatura,destrorso,mancino,dispositivo di puntamento,rotellina del mouse,emulazione del mouse,navigazione con il mouse, trascinamento con il mouse, scorrimento con il mouse, sensibilità del mouse,muovi il mouse con il tastierino numerico,emulazione mouse con il tastierino numerico +X-KDE-Keywords[kk]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation +X-KDE-Keywords[km]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation +X-KDE-Keywords[ko]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,마우스,마우스 가속,시간,커서 모양,입력 장치,클릭,드래그,왼손잡이,오른손잡이,마우스 휠,마우스 탐색, 마우스 스크롤,감도,스크롤,휠 +X-KDE-Keywords[mr]=माऊस, माऊस एक्सलरेशन, माऊस थ्रेशहोल्ड, माऊस बटन्स, सिलेक्शन, कर्सर शेप, इनपुट डिव्हाईस, बटन मेपिंग, क्लिक, आयकॉनस, फीडबेक, पॉईटर, ड्रग डबल, क्लिक, सिंगल क्लिक, मेपिंग, राईट हेन्डेड ,पॉईटर डिव्हाईस,माऊस, व्हील, माऊस इम्यूलेशन, माऊस,नेव्हीगेशन, माऊस ड्रेग व ड्रोप,न्यूम पॅड, माऊस न्यूम पॅड इम्यूलेशन +X-KDE-Keywords[nb]=Mus,Pekerakselerasjon,Pekerterskel,knapper,valg,pekerform,Inndataenheter,knappeavbildning,Klikk, ikoner,oppstartsmelding,Pekere,Dra,Dobbeltklikk,Enkeltklikk,Knapperekkefølge,høyrehendt,venstrehendt,Pekerenhet,Musehjul,Musemulering,Musenavigasjon,Dra og slipp med Mus, Muserulling,Flytt mus med talltastatur,Museemulering med talltastatur +X-KDE-Keywords[nds]=Muus,Muusbeslünigen,Wieser-Süll,Muusgauheit,Muusknööp,Köör,Blinkerform,Ingaavreedschappen,Knoop-Toornen,Klick,Lüttbiller,Rückmellen,Wiesers,Dregen,Dubbelklick,Towiesen,Rechtepoot,Linkepoot,Wiesreedschap,Muusrad,Muusemuleren,Muusstüern,Dregen un Droppen,Trecken,Afsetten,Fallenlaten,Rullen,Föhlsamkeit,Tallenblock +X-KDE-Keywords[nl]=muis,muisversnelling,muisdrempel,muisknoppen,selectie,cursorvorm,invoerapparaten,knoppenmapping,klik,pictogrammen,terugkoppeling,aanwijzer,slepen,dubbelklik,klik,mapping,rechtshandig,linkshandig,aanwijsapparaat,muiswiel,muisemulatie,muisnavigatie,slepen en laten vallen met muis,schuiven met de muis,muisgevoeligheid,muis bewegen met num-pad,emulatie van num-pad met muis +X-KDE-Keywords[pl]=Mysz,Przyspieszenie myszy,Próg myszy,Przyciski myszy,Zaznaczenie, Kształt kursora,Urządzenia wejścia,Mapowanie przycisków,Kliknięcie,ikony,odczucie,Wskaźniki,Przeciągnięcie,Podwójne kliknięcie,mapowanie,praworęczny,leworęczny, Urządzenie wskazujące,Rolka myszy,Emulacja myszy,Nawigacja myszą,Przeciąganie i upuszczanie myszą,Przewijanie myszą,Czułość myszy,Przemieszczaj myszą przy użyciu klawiatury numerycznej,Emulacja myszy klawiaturą numeryczną +X-KDE-Keywords[pt]=Rato,aceleração do rato,limiar do rato,botões do rato,selecção,forma do cursor,dispositivos de entrada,associação de botões,click,ícones,reacção,cursores,arrastar,duplo-click,associação,destro,esquerdino,ponteiro,roda do rato,emulação do rato,navegação do rato,arrastamento com o rato,deslocamento do rato,sensibilidade do rato,mover o rato com cursores,emulação do rato com teclado numérico +X-KDE-Keywords[pt_BR]=Mouse,aceleração do mouse,limiar do mouse,botões do mouse,seleção,forma do cursor,dispositivos de entrada,associação de botões,clique,ícones,feedback,ponteiros,arrastar,clique duplo,clique simples,associação,destro,canhoto, ponteiro,roda do mouse,emulação do mouse,navegação do mouse,arrastar e soltar com o mouse,deslocamento do mouse,sensibilidade do mouse,mover o mouse com o teclado numérico,emulação do mouse com o teclado numérico +X-KDE-Keywords[ru]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,мышь,ускорение мыши,границы мыши,кнопки мыши,выбор,форма курсора,устройство ввода,назначение клавиш,клик,значки,обратная связь,указатели,перемещение,двойной клик,двойной щелчок,одиночный клик,одиночный щелчок,правая рука,левая рука,праворукая,леворукая,колесо мыши,эмуляция мыши,управление мышью, навигация мыши,прокрутка,чувствительность,управление мышью через цифровую клавиатуру +X-KDE-Keywords[sk]=Myš,Zrýchlenie myši,Prah myši,Tlačidlá myši,Výber,Tvar kurzora,Vstupné zariadenia,Mapovanie tlačidiel,Klik,ikony,odozva,Ukazovatele,Drag,Dvojklik,Jednoduchý klik,mapovanie,pre pravákov,pre ľavákov,ukazovacie zariadenie,koliesko myši,emulácia myši,navigácia myši,drag and drop myši,rolovanie myši,citlivosť myši,pohyb myši numerickou klávesnicou,emulácia myši numerickou klávesnicou +X-KDE-Keywords[sl]=miška,pospešek miške,prag miške,gumbi miške,miškini gumbi,izbor,oblika kazalca,oblika kazalke,vhodne naprave,preslikava gumbov,klik,ikone,povratne informacije,odziv,kazalci,kazalke,vleka,dvojni klik,dvoklik,enojni klik,preslikava,desničar,levičar,kazalna naprava,kolešček miške,miškin kolešček,posnemanje miške,krmarjenje z miško,vleka in spuščanje z miško,pomikanje z miško,občutljivost miške,miškina občutljivost,premikanje miške s številčnico,posnemanje s številčnico +X-KDE-Keywords[sr]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,миш,убрзање миша,праг миша,дугмад миша,избор,облик показивача,облик курсора,улазни уређаји,мапирање дугмади,клик,иконе,одзив,превлачење,двоклик,десноруки,леворуки,показивачки уређај,точкић миша,осетљивост миша,кретање мишем,емулација миша,емулација миша преко нумеричке тастатуре +X-KDE-Keywords[sr@ijekavian]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,миш,убрзање миша,праг миша,дугмад миша,избор,облик показивача,облик курсора,улазни уређаји,мапирање дугмади,клик,иконе,одзив,превлачење,двоклик,десноруки,леворуки,показивачки уређај,точкић миша,осетљивост миша,кретање мишем,емулација миша,емулација миша преко нумеричке тастатуре +X-KDE-Keywords[sr@ijekavianlatin]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,miš,ubrzanje miša,prag miša,dugmad miša,izbor,oblik pokazivača,oblik kursora,ulazni uređaji,mapiranje dugmadi,klik,ikone,odziv,prevlačenje,dvoklik,desnoruki,levoruki,pokazivački uređaj,točkić miša,osetljivost miša,kretanje mišem,emulacija miša,emulacija miša preko numeričke tastature +X-KDE-Keywords[sr@latin]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,miš,ubrzanje miša,prag miša,dugmad miša,izbor,oblik pokazivača,oblik kursora,ulazni uređaji,mapiranje dugmadi,klik,ikone,odziv,prevlačenje,dvoklik,desnoruki,levoruki,pokazivački uređaj,točkić miša,osetljivost miša,kretanje mišem,emulacija miša,emulacija miša preko numeričke tastature +X-KDE-Keywords[sv]=Mus,Musacceleration,Muströskel,Musknappar,Val,Pekarform,Indataenheter,Knappavbildning,Klick,ikoner,återmatning,Pekare,Dra,Dubbelklick,avbildning,högerhänt,vänsterhänt,pekarenhet,mushjul,musemulering,musnavigering,mus drag och släpp,musrullning,muskänslighet,flytta musen med numeriskt tangentbord,emulering av mus med numeriskt tangentbord +X-KDE-Keywords[tr]=Fare,Fare Hızlandırma,Fare Eşiği,Fare Düğmeleri,Seçim,İşaretçi Şekli,Girdi Aygıtları,Düğme Haritalama,Tıklama,simgeler,geri bildirim,İşaretçiler,Sürükle,Çift Tıklama,Tek Tıklama,haritalama,sağlak,solak,İşaretçi Aygıtı,Fare Tekeri,Fare Benzetimi,Fare Gezinmesi,Fare Sürükle Bırak,Fare Kaydırması,Fare Hassasiyeti,Fareyi Sayısal Tuşlarla Hareket Ettir,Fare Sayısal Tuş Benzetimi +X-KDE-Keywords[uk]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,DoubleClick,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,миша,прискорення,поріг,порогове значення,кнопка,вибір,вказівник,форма,введення,кнопки,клацання,піктограми,значки,іконки,супровід,вказівники,перетягування,подвійне клацання,відповідність,праворукий,шульга,лівша,пристрій вказівника,коліщатко миші,емуляція миші,імітація миші,навігація за допомогою миші,перетягування зі скиданням мишею,гортання мишею,чутливість миші,миша з цифровою панеллю,емуляція цифрової панелі миші +X-KDE-Keywords[x-test]=xxMouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulationxx +X-KDE-Keywords[zh_CN]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation,鼠标,鼠标加速,鼠标阀值,鼠标按键,选择,光标形状,输入设备,按键映射,点击,图标,反馈,指针,拖拽,双击,映射,右手习惯,左手习惯,光标设备,指针设备,鼠标滚轮,鼠标模拟,鼠标导航,鼠标拖拽,鼠标滚动,鼠标灵敏度,小键盘移动鼠标,小键盘鼠标模拟 +X-KDE-Keywords[zh_TW]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation +Categories=Qt;KDE;X-KDE-settings-hardware; diff --git a/kcontrol/input/mouse.h b/kcontrol/input/mouse.h new file mode 100644 index 00000000..d926a991 --- /dev/null +++ b/kcontrol/input/mouse.h @@ -0,0 +1,160 @@ +/* + * mouse.h + * + * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca + * + * Layout management, enhancements: + * Copyright (c) 1999 Dirk A. Mueller + * + * SC/DC/AutoSelect/ChangeCursor: + * Copyright (c) 2000 David Faure + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef __MOUSECONFIG_H__ +#define __MOUSECONFIG_H__ + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#ifdef HAVE_LIBUSB +#include "logitechmouse.h" +#endif + +#include +#include "ui_kmousedlg.h" + +#define RIGHT_HANDED 0 +#define LEFT_HANDED 1 + +class QCheckBox; +class QSlider; +class QTabWidget; + +class KMouseDlg : public QWidget, public Ui::KMouseDlg +{ +public: + KMouseDlg( QWidget *parent ) : QWidget( parent ) { + setupUi( this ); + } +}; + + +class MouseSettings +{ +public: + void save(KConfig *); + void load(KConfig *); + void apply(bool force=false); +public: + int num_buttons; + int middle_button; + bool handedEnabled; + bool m_handedNeedsApply; + int handed; + double accelRate; + int thresholdMove; + int doubleClickInterval; + int dragStartTime; + int dragStartDist; + bool singleClick; + int autoSelectDelay; + bool changeCursor; + int wheelScrollLines; + bool reverseScrollPolarity; + + #ifdef HAVE_LIBUSB + // TODO: In Qt4, replace with a better container. + QList logitechMouseList; + #endif +}; + +class MouseConfig : public KCModule +{ + Q_OBJECT +public: + MouseConfig(QWidget *parent, const QVariantList &args); + ~MouseConfig(); + + void save(); + void load(); + void defaults(); + +private Q_SLOTS: + + void slotClick(); + /** No descriptions */ + void slotHandedChanged(int val); + void slotScrollPolarityChanged(); + void checkAccess(); + void slotThreshChanged(int value); + void slotDragStartDistChanged(int value); + void slotWheelScrollLinesChanged(int value); + void slotSmartSliderEnabling(); + +private: + + double getAccel(); + int getThreshold(); + int getHandedness(); + + void setAccel(double); + void setThreshold(int); + void setHandedness(int); + + KDoubleNumInput *accel; + KIntNumInput *thresh; + KIntNumInput *doubleClickInterval; + KIntNumInput *dragStartTime; + KIntNumInput *dragStartDist; + KIntNumInput *wheelScrollLines; + +// QRadioButton *leftHanded, *rightHanded; +// QCheckBox *doubleClick; +// QCheckBox *cbAutoSelect; + QLabel *lDelay; +// QSlider *slAutoSelect; +// QCheckBox *cbVisualActivate; +// QCheckBox *cbCursor; +// QCheckBox *cbLargeCursor; + + QTabWidget *tabwidget; + QWidget *advancedTab; + KMouseDlg* generalTab; + MouseSettings *settings; + + QCheckBox *mouseKeys; + KIntNumInput *mk_delay, *mk_interval, *mk_time_to_max, *mk_max_speed, + *mk_curve; + + +}; + +#endif + diff --git a/kcontrol/input/pics/CMakeLists.txt b/kcontrol/input/pics/CMakeLists.txt new file mode 100644 index 00000000..4ef49ea1 --- /dev/null +++ b/kcontrol/input/pics/CMakeLists.txt @@ -0,0 +1 @@ +install( FILES mouse_rh.png mouse_lh.png DESTINATION ${DATA_INSTALL_DIR}/kcminput/pics ) diff --git a/kcontrol/input/pics/mouse_lh.png b/kcontrol/input/pics/mouse_lh.png new file mode 100644 index 0000000000000000000000000000000000000000..796d5994252bad45f8f076f1cb1e3621efd9cc4f GIT binary patch literal 10704 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 literal 0 HcmV?d00001 diff --git a/kcontrol/input/pics/mouse_rh.svgz b/kcontrol/input/pics/mouse_rh.svgz new file mode 100644 index 0000000000000000000000000000000000000000..fc2b069a8d842c03af188c03d808f3dfb621ce93 GIT binary patch literal 4528 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 O;QtM-4PW0)MgRa0Bl0l- literal 0 HcmV?d00001 diff --git a/kcontrol/input/xcursor/cursortheme.cpp b/kcontrol/input/xcursor/cursortheme.cpp new file mode 100644 index 00000000..2c8c260d --- /dev/null +++ b/kcontrol/input/xcursor/cursortheme.cpp @@ -0,0 +1,155 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include +#include + +#include "themepage.h" +#include "cursortheme.h" + +#include + +#ifdef HAVE_XFIXES +# include +# include +#endif + + +CursorTheme::CursorTheme(const QString &title, const QString &description) +{ + setTitle(title); + setDescription(description); + setSample("left_ptr"); + setIsHidden(false); + setIsWritable(false); +} + + +QPixmap CursorTheme::icon() const +{ + if (m_icon.isNull()) + m_icon = createIcon(); + + return m_icon; +} + + +QImage CursorTheme::autoCropImage(const QImage &image) const +{ + // Compute an autocrop rectangle for the image + QRect r(image.rect().bottomRight(), image.rect().topLeft()); + const quint32 *pixels = reinterpret_cast(image.bits()); + + for (int y = 0; y < image.height(); y++) + { + for (int x = 0; x < image.width(); x++) + { + if (*(pixels++)) + { + if (x < r.left()) r.setLeft(x); + if (x > r.right()) r.setRight(x); + if (y < r.top()) r.setTop(y); + if (y > r.bottom()) r.setBottom(y); + } + } + } + + // Normalize the rectangle + return image.copy(r.normalized()); +} + + +QPixmap CursorTheme::loadPixmap(const QString &name, int size) const +{ + QImage image = loadImage(name, size); + if (image.isNull()) + return QPixmap(); + + return QPixmap::fromImage(image); +} + + +static int nominalCursorSize(int iconSize) +{ + for (int i = 512; i > 8; i /= 2) + { + if (i < iconSize) + return i; + + if ((i * .75) < iconSize) + return int(i * .75); + } + + return 8; +} + + +QPixmap CursorTheme::createIcon() const +{ + int iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize); + int cursorSize = nominalCursorSize(iconSize); + QSize size = QSize(iconSize, iconSize); + + QPixmap pixmap = createIcon(cursorSize); + + if (!pixmap.isNull()) + { + // Scale the pixmap if it's larger than the preferred icon size + if (pixmap.width() > size.width() || pixmap.height() > size.height()) + pixmap = pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + + return pixmap; +} + + +QPixmap CursorTheme::createIcon(int size) const +{ + QPixmap pixmap; + QImage image = loadImage(sample(), size); + + if (image.isNull() && sample() != "left_ptr") + image = loadImage("left_ptr", size); + + if (!image.isNull()) + { + pixmap = QPixmap::fromImage(image); + } + + return pixmap; +} + + +void CursorTheme::setCursorName(QCursor &cursor, const QString &name) const +{ +#ifdef HAVE_XFIXES + static bool haveXfixes = ThemePage::haveXfixes(); + + if (haveXfixes) + { + XFixesSetCursorName(QX11Info::display(), cursor.handle(), + QFile::encodeName(name)); + } +#endif +} + diff --git a/kcontrol/input/xcursor/cursortheme.h b/kcontrol/input/xcursor/cursortheme.h new file mode 100644 index 00000000..672239b6 --- /dev/null +++ b/kcontrol/input/xcursor/cursortheme.h @@ -0,0 +1,143 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 CURSORTHEME_H +#define CURSORTHEME_H + +#include +#include + +/** + * This is the abstract base class for all cursor themes stored in a + * CursorThemeModel and previewed in a PreviewWidget. + * + * All cursor themes have a title, a description, an icon, and an internal + * name, all of which, except for the internal name, CursorThemeModel + * supplies to item views. + * + * A cursor theme may also have a path to the directory where the theme + * is located in the filesystem. If isWritable() returns true, This directory + * may be deleted in order to remove the theme at the users request. + * + * Subclasses must reimplement loadImage() and loadCursor(), which are + * called by PreviewWidget to load cursors and cursor images. Subclasses may + * optionally reimplement loadPixmap(), which in the default implementation + * calls loadImage(), and converts the returned image to a pixmap. + * Subclasses may also reimplement the protected function createIcon(), + * which creates the icon pixmap that's supplied to item views. The default + * implementation calls loadImage() to load the sample cursor, and creates + * the icon from that. + */ +class CursorTheme +{ + public: + enum ItemDataRole { + // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) + // to define additional roles. + DisplayDetailRole = 0x24A3DAF8 + }; + + CursorTheme() {} + CursorTheme(const QString &title, const QString &description = QString()); + virtual ~CursorTheme() {} + + const QString title() const { return m_title; } + const QString description() const { return m_description; } + const QString sample() const { return m_sample; } + const QString name() const { return m_name; } + const QString path() const { return m_path; } + /** @returns A list of the available sizes in this cursor theme, + @warning This list may be empty if the engine doesn't support + the recognition of the size. */ + const QList availableSizes() const + { return m_availableSizes; } + bool isWritable() const { return m_writable; } + bool isHidden() const { return m_hidden; } + QPixmap icon() const; + + /// Hash value for the internal name + uint hash() const { return m_hash; } + + /// Loads the cursor image @p name, with the nominal size @p size. + /// The image should be autocropped to the smallest possible size. + /// If the theme doesn't have the cursor @p name, it should return a null image. + virtual QImage loadImage(const QString &name, int size = 0) const = 0; + + /// Convenience function. Default implementation calls + /// QPixmap::fromImage(loadImage()); + virtual QPixmap loadPixmap(const QString &name, int size = 0) const; + + /// Loads the cursor @p name, with the nominal size @p size. + /// If the theme doesn't have the cursor @p name, it should return + /// the default cursor from the active theme instead. + virtual QCursor loadCursor(const QString &name, int size = 0) const = 0; + + /** Creates the icon returned by @ref icon(). Don't use this function + directly but use @ref icon() instead, because @ref icon() caches + the icon. + @returns A pixmap with a cursor (usually left_ptr) that can + be used as icon for this theme. The size is adopted to + standard icon sizes.*/ + virtual QPixmap createIcon() const; + /** @returns A pixmap with a cursor (usually left_ptr) that can + be used as icon for this theme. */ + virtual QPixmap createIcon(int size) const; + + protected: + void setTitle( const QString &title ) { m_title = title; } + void setDescription( const QString &desc ) { m_description = desc; } + void setSample( const QString &sample ) { m_sample = sample; } + inline void setName( const QString &name ); + void setPath( const QString &path ) { m_path = path; } + void setAvailableSizes( const QList &availableSizes ) + { m_availableSizes = availableSizes; } + void setIcon( const QPixmap &icon ) { m_icon = icon; } + void setIsWritable( bool val ) { m_writable = val; } + void setIsHidden( bool val ) { m_hidden = val; } + + /// Convenience function for cropping an image. + QImage autoCropImage( const QImage &image ) const; + + // Convenience function that uses Xfixes to tag a cursor with a name + void setCursorName(QCursor &cursor, const QString &name) const; + + QString m_title; + QString m_description; + QString m_path; + QList m_availableSizes; + QString m_sample; + mutable QPixmap m_icon; + bool m_writable:1; + bool m_hidden:1; + + private: + QString m_name; + uint m_hash; + + friend class CursorThemeModel; +}; + +void CursorTheme::setName(const QString &name) +{ + m_name = name; + m_hash = qHash(name); +} + +#endif // CURSORTHEME_H + diff --git a/kcontrol/input/xcursor/itemdelegate.cpp b/kcontrol/input/xcursor/itemdelegate.cpp new file mode 100644 index 00000000..e7370056 --- /dev/null +++ b/kcontrol/input/xcursor/itemdelegate.cpp @@ -0,0 +1,174 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 "itemdelegate.h" +#include "cursortheme.h" + +#include +#include +#include + +namespace +{ + const int decorationMargin = 8; +} + + +ItemDelegate::ItemDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ +} + + +ItemDelegate::~ItemDelegate() +{ +} + + +QString ItemDelegate::firstLine(const QModelIndex &index) const +{ + if (index.isValid()) + return index.model()->data(index, Qt::DisplayRole).toString(); + + return QString(); +} + + +QString ItemDelegate::secondLine(const QModelIndex &index) const +{ + if (index.isValid()) + return index.model()->data(index, CursorTheme::DisplayDetailRole).toString(); + + return QString(); +} + + +QPixmap ItemDelegate::decoration(const QModelIndex &index) const +{ + if (index.isValid()) + return qvariant_cast(index.model()->data(index, Qt::DecorationRole)); + + return QPixmap(); +} + + +QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (!index.isValid()) + return QSize(); + + QFont normalfont = option.font; + QFont boldfont = normalfont; + boldfont.setBold(true); + + // Extract the items we want to measure + QString firstRow = firstLine(index); + QString secondRow = secondLine(index); + + // Compute the height + QFontMetrics fm1(boldfont); + QFontMetrics fm2(normalfont); + int height = fm1.lineSpacing() + fm2.lineSpacing(); + height = qMax(height, option.decorationSize.height()); + + // Compute the text width + int width = fm1.width(firstRow); + width = qMax(width, fm2.width(secondRow)); + + // Add decoration width + margin + width += option.decorationSize.width() + decorationMargin; + + return QSize(width, height + 16); +} + + +QPalette::ColorRole ItemDelegate::foregroundRole(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + + if (option.state & QStyle::State_Selected) + return QPalette::HighlightedText; + + return QPalette::Text; +} + + +void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (!index.isValid()) + return; + + painter->save(); + + QFont normalfont = option.font; + QFont boldfont = normalfont; + boldfont.setBold(true); + + QString firstRow = firstLine(index); + QString secondRow = secondLine(index); + QPixmap pixmap = decoration(index); + + QColor textcol = option.palette.color(foregroundRole(option, index)); + + // Draw the background + QStyleOptionViewItemV4 opt = option; + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + + // Draw the icon + int x = option.rect.left() + (option.decorationSize.width() - pixmap.width() + decorationMargin) / 2; + int y = option.rect.top() + (option.rect.height() - pixmap.height()) / 2; + + QRect pixmapRect = QStyle::visualRect(option.direction, option.rect, + QRect(x, y, pixmap.width(), pixmap.height())); + + painter->drawPixmap(pixmapRect.x(), pixmapRect.y(), pixmap); + + // Draw the text + QFontMetrics fm1(boldfont); + QFontMetrics fm2(normalfont); + + int textAreaHeight = fm1.lineSpacing(); + if (!secondRow.isEmpty()) { + textAreaHeight += fm2.lineSpacing(); + } + + x = option.rect.left() + option.decorationSize.width() + decorationMargin; + int y1 = option.rect.top() + (option.rect.height() - textAreaHeight) / 2; + int y2 = y1 + fm1.lineSpacing(); + + QRect firstRowRect = QStyle::visualRect(option.direction, option.rect, + QRect(x, y1, fm1.width(firstRow), fm1.lineSpacing())); + + QRect secondRowRect = QStyle::visualRect(option.direction, option.rect, + QRect(x, y2, fm2.width(secondRow), fm2.lineSpacing())); + + painter->setPen(textcol); + + // First line + painter->setFont(boldfont); + painter->drawText(firstRowRect, Qt::AlignCenter, firstRow); + + // Second line + painter->setFont(normalfont); + painter->drawText(secondRowRect, Qt::AlignCenter, secondRow); + + painter->restore(); +} + diff --git a/kcontrol/input/xcursor/itemdelegate.h b/kcontrol/input/xcursor/itemdelegate.h new file mode 100644 index 00000000..9acb0e97 --- /dev/null +++ b/kcontrol/input/xcursor/itemdelegate.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 ITEMDELEGATE_H +#define ITEMDELEGATE_H + +#include + +class QPainter; + +class ItemDelegate : public QAbstractItemDelegate +{ + public: + ItemDelegate(QObject *parent = 0); + ~ItemDelegate(); + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + private: + QString firstLine(const QModelIndex &index) const; + QString secondLine(const QModelIndex &index) const; + QPixmap decoration(const QModelIndex &index) const; + QPalette::ColorRole foregroundRole(const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif diff --git a/kcontrol/input/xcursor/previewwidget.cpp b/kcontrol/input/xcursor/previewwidget.cpp new file mode 100644 index 00000000..aff149bc --- /dev/null +++ b/kcontrol/input/xcursor/previewwidget.cpp @@ -0,0 +1,229 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 +#include + +#include "previewwidget.h" + +#include +#include + +#include "cursortheme.h" + + + +namespace { + + // Preview cursors + const char * const cursor_names[] = + { + "left_ptr", + "left_ptr_watch", + "wait", + "pointing_hand", + "whats_this", + "ibeam", + "size_all", + "size_fdiag", + "cross", + "split_h", + "size_ver", + "size_hor", + "size_bdiag", + "split_v", + }; + + const int numCursors = 9; // The number of cursors from the above list to be previewed + const int cursorSpacing = 20; // Spacing between preview cursors + const int widgetMinWidth = 10; // The minimum width of the preview widget + const int widgetMinHeight = 48; // The minimum height of the preview widget +} + + +class PreviewCursor +{ + public: + PreviewCursor( const CursorTheme *theme, const QString &name, int size ); + ~PreviewCursor() {} + + const QPixmap &pixmap() const { return m_pixmap; } + Cursor handle() const { return m_cursor.handle(); } + int width() const { return m_pixmap.width(); } + int height() const { return m_pixmap.height(); } + inline QRect rect() const; + void setPosition( const QPoint &p ) { m_pos = p; } + void setPosition( int x, int y ) { m_pos = QPoint(x, y); } + QPoint position() const { return m_pos; } + operator const QCursor& () const { return m_cursor; } + operator const QPixmap& () const { return pixmap(); } + + private: + QPixmap m_pixmap; + QCursor m_cursor; + QPoint m_pos; +}; + + +PreviewCursor::PreviewCursor(const CursorTheme *theme, const QString &name, int size) +{ + // Create the preview pixmap + QImage image = theme->loadImage(name, size); + + if (image.isNull()) + return; + + m_pixmap = QPixmap::fromImage(image); + + // Load the cursor + m_cursor = theme->loadCursor(name, size); + // ### perhaps we should tag the cursor so it doesn't get + // replaced when a new theme is applied +} + + +QRect PreviewCursor::rect() const +{ + return QRect(m_pos, m_pixmap.size()) + .adjusted(-(cursorSpacing / 2), -(cursorSpacing / 2), + cursorSpacing / 2, cursorSpacing / 2); +} + + + +// ------------------------------------------------------------------------------ + + + +PreviewWidget::PreviewWidget(QWidget *parent) : QWidget(parent) +{ + setMouseTracking(true); + current = NULL; +} + + +PreviewWidget::~PreviewWidget() +{ + qDeleteAll(list); + list.clear(); +} + + +QSize PreviewWidget::sizeHint() const +{ + int totalWidth = 0; + int maxHeight = 0; + + foreach (const PreviewCursor *c, list) + { + totalWidth += c->width(); + maxHeight = qMax(c->height(), maxHeight); + } + + totalWidth += (list.count() - 1) * cursorSpacing; + maxHeight = qMax(maxHeight, widgetMinHeight); + + return QSize(qMax(totalWidth, widgetMinWidth), qMax(height(), maxHeight)); +} + + +void PreviewWidget::layoutItems() +{ + if (!list.isEmpty()) + { + QSize size = sizeHint(); + int cursorWidth = size.width() / list.count(); + int nextX = (width() - size.width()) / 2; + + foreach (PreviewCursor *c, list) + { + c->setPosition(nextX + (cursorWidth - c->width()) / 2, + (height() - c->height()) / 2); + nextX += cursorWidth; + } + } + + needLayout = false; +} + + +void PreviewWidget::setTheme(const CursorTheme *theme, const int size) +{ + qDeleteAll(list); + list.clear(); + + if (theme) + { + for (int i = 0; i < numCursors; i++) + list << new PreviewCursor(theme, cursor_names[i], size); + + needLayout = true; + updateGeometry(); + } + + current = NULL; + update(); +} + + +void PreviewWidget::paintEvent(QPaintEvent *) +{ + QPainter p(this); + + if (needLayout) + layoutItems(); + + foreach(const PreviewCursor *c, list) + { + if (c->pixmap().isNull()) + continue; + + p.drawPixmap(c->position(), *c); + } +} + + +void PreviewWidget::mouseMoveEvent(QMouseEvent *e) +{ + if (needLayout) + layoutItems(); + + foreach (const PreviewCursor *c, list) + { + if (c->rect().contains(e->pos())) + { + if (c != current) + { + setCursor(*c); + current = c; + } + return; + } + } + + setCursor(Qt::ArrowCursor); + current = NULL; +} + + +void PreviewWidget::resizeEvent(QResizeEvent *) +{ + if (!list.isEmpty()) + needLayout = true; +} + diff --git a/kcontrol/input/xcursor/previewwidget.h b/kcontrol/input/xcursor/previewwidget.h new file mode 100644 index 00000000..4a11e2d2 --- /dev/null +++ b/kcontrol/input/xcursor/previewwidget.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 PREVIEWWIDGET_H +#define PREVIEWWIDGET_H + +#include + +class CursorTheme; +class PreviewCursor; + +class PreviewWidget : public QWidget +{ + public: + PreviewWidget(QWidget *parent); + ~PreviewWidget(); + + void setTheme(const CursorTheme *theme, const int size); + void setUseLables(bool); + QSize sizeHint() const; + + protected: + void paintEvent(QPaintEvent *); + void mouseMoveEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); + + private: + void layoutItems(); + + QList list; + const PreviewCursor *current; + bool needLayout:1; +}; + +#endif // PREVIEWWIDGET_H + diff --git a/kcontrol/input/xcursor/sortproxymodel.cpp b/kcontrol/input/xcursor/sortproxymodel.cpp new file mode 100644 index 00000000..b9d63092 --- /dev/null +++ b/kcontrol/input/xcursor/sortproxymodel.cpp @@ -0,0 +1,50 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 +#include "sortproxymodel.h" +#include "cursortheme.h" + + +int SortProxyModel::compare(const QModelIndex &left, const QModelIndex &right, int role) const +{ + const QAbstractItemModel *model = sourceModel(); + + QString first = model->data(left, role).toString(); + QString second = model->data(right, role).toString(); + + if (filterCaseSensitivity() == Qt::CaseSensitive) + { + first = first.toLower(); + second = second.toLower(); + } + + return QString::localeAwareCompare(first, second); +} + + +bool SortProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + const int result = compare(left, right, Qt::DisplayRole); + + if (result != 0) + return (result < 0); + else + return compare(left, right, CursorTheme::DisplayDetailRole) < 0; +} diff --git a/kcontrol/input/xcursor/sortproxymodel.h b/kcontrol/input/xcursor/sortproxymodel.h new file mode 100644 index 00000000..95c9646c --- /dev/null +++ b/kcontrol/input/xcursor/sortproxymodel.h @@ -0,0 +1,77 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 SORTPROXYMODEL_H +#define SORTPROXYMODEL_H + +#include +#include + +/** + * SortProxyModel is a sorting proxy model intended to be used in combination + * with the ItemDelegate class. + * + * First it compares the Qt::DisplayRoles, and if they match it compares + * the CursorTheme::DisplayDetailRoles. + * + * The model assumes both display roles are QStrings. + */ +class SortProxyModel : public QSortFilterProxyModel +{ + public: + SortProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {} + ~SortProxyModel() {} + inline const CursorTheme *theme(const QModelIndex &index) const; + inline QModelIndex findIndex(const QString &name) const; + inline QModelIndex defaultIndex() const; + inline void removeTheme(const QModelIndex &index); + + private: + int compare(const QModelIndex &left, const QModelIndex &right, int role) const; + + protected: + bool lessThan(const QModelIndex &left, const QModelIndex &right) const; +}; + + +const CursorTheme *SortProxyModel::theme(const QModelIndex &index) const +{ + CursorThemeModel *model = static_cast(sourceModel()); + return model->theme(mapToSource(index)); +} + +QModelIndex SortProxyModel::findIndex(const QString &name) const +{ + CursorThemeModel *model = static_cast(sourceModel()); + return mapFromSource(model->findIndex(name)); +} + +QModelIndex SortProxyModel::defaultIndex() const +{ + CursorThemeModel *model = static_cast(sourceModel()); + return mapFromSource(model->defaultIndex()); +} + +void SortProxyModel::removeTheme(const QModelIndex &index) +{ + CursorThemeModel *model = static_cast(sourceModel()); + model->removeTheme(mapToSource(index)); +} + +#endif // SORTPROXYMODEL_H diff --git a/kcontrol/input/xcursor/thememodel.cpp b/kcontrol/input/xcursor/thememodel.cpp new file mode 100644 index 00000000..bb6effb9 --- /dev/null +++ b/kcontrol/input/xcursor/thememodel.cpp @@ -0,0 +1,413 @@ +/* + * Copyright © 2005-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include + +#include "thememodel.h" +#include "thememodel.moc" +#include "xcursortheme.h" + +#include +#include + +// Check for older version +#if !defined(XCURSOR_LIB_MAJOR) && defined(XCURSOR_MAJOR) +# define XCURSOR_LIB_MAJOR XCURSOR_MAJOR +# define XCURSOR_LIB_MINOR XCURSOR_MINOR +#endif + + + +CursorThemeModel::CursorThemeModel(QObject *parent) + : QAbstractTableModel(parent) +{ + insertThemes(); +} + +CursorThemeModel::~CursorThemeModel() +{ + qDeleteAll(list); + list.clear(); +} + +void CursorThemeModel::refreshList() +{ + beginResetModel(); + qDeleteAll(list); + list.clear(); + endResetModel(); + insertThemes(); +} + +QVariant CursorThemeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + // Only provide text for the headers + if (role != Qt::DisplayRole) + return QVariant(); + + // Horizontal header labels + if (orientation == Qt::Horizontal) + { + switch (section) + { + case NameColumn: + return i18n("Name"); + + case DescColumn: + return i18n("Description"); + + default: return QVariant(); + } + } + + // Numbered vertical header lables + return QString(section); +} + + +QVariant CursorThemeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() >= list.count()) + return QVariant(); + + const CursorTheme *theme = list.at(index.row()); + + // Text label + if (role == Qt::DisplayRole) + { + switch (index.column()) + { + case NameColumn: + return theme->title(); + + case DescColumn: + return theme->description(); + + default: return QVariant(); + } + } + + // Description for the first name column + if (role == CursorTheme::DisplayDetailRole && index.column() == NameColumn) + return theme->description(); + + // Icon for the name column + if (role == Qt::DecorationRole && index.column() == NameColumn) + return theme->icon(); + + return QVariant(); +} + + +void CursorThemeModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + Q_UNUSED(order); + + // Sorting of the model isn't implemented, as the KCM currently uses + // a sorting proxy model. +} + + +const CursorTheme *CursorThemeModel::theme(const QModelIndex &index) +{ + if (!index.isValid()) + return NULL; + + if (index.row() < 0 || index.row() >= list.count()) + return NULL; + + return list.at(index.row()); +} + + +QModelIndex CursorThemeModel::findIndex(const QString &name) +{ + uint hash = qHash(name); + + for (int i = 0; i < list.count(); i++) + { + const CursorTheme *theme = list.at(i); + if (theme->hash() == hash) + return index(i, 0); + } + + return QModelIndex(); +} + + +QModelIndex CursorThemeModel::defaultIndex() +{ + return findIndex(defaultName); +} + + +const QStringList CursorThemeModel::searchPaths() +{ + if (!baseDirs.isEmpty()) + return baseDirs; + +#if XCURSOR_LIB_MAJOR == 1 && XCURSOR_LIB_MINOR < 1 + // These are the default paths Xcursor will scan for cursor themes + QString path("~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons"); + + // If XCURSOR_PATH is set, use that instead of the default path + char *xcursorPath = std::getenv("XCURSOR_PATH"); + if (xcursorPath) + path = xcursorPath; +#else + // Get the search path from Xcursor + QString path = XcursorLibraryPath(); +#endif + + // Separate the paths + baseDirs = path.split(':', QString::SkipEmptyParts); + + // Remove duplicates + QMutableStringListIterator i(baseDirs); + while (i.hasNext()) + { + const QString path = i.next(); + QMutableStringListIterator j(i); + while (j.hasNext()) + if (j.next() == path) + j.remove(); + } + + // Expand all occurrences of ~/ to the home dir + baseDirs.replaceInStrings(QRegExp("^~\\/"), QDir::home().path() + '/'); + return baseDirs; +} + + +bool CursorThemeModel::hasTheme(const QString &name) const +{ + const uint hash = qHash(name); + + foreach (const CursorTheme *theme, list) + if (theme->hash() == hash) + return true; + + return false; +} + + +bool CursorThemeModel::isCursorTheme(const QString &theme, const int depth) +{ + // Prevent infinite recursion + if (depth > 10) + return false; + + // Search each icon theme directory for 'theme' + foreach (const QString &baseDir, searchPaths()) + { + QDir dir(baseDir); + if (!dir.exists() || !dir.cd(theme)) + continue; + + // If there's a cursors subdir, we'll assume this is a cursor theme + if (dir.exists("cursors")) + return true; + + // If the theme doesn't have an index.theme file, it can't inherit any themes. + if (!dir.exists("index.theme")) + continue; + + // Open the index.theme file, so we can get the list of inherited themes + KConfig config(dir.path() + "/index.theme", KConfig::NoGlobals); + KConfigGroup cg(&config, "Icon Theme"); + + // Recurse through the list of inherited themes, to check if one of them + // is a cursor theme. + QStringList inherits = cg.readEntry("Inherits", QStringList()); + foreach (const QString &inherit, inherits) + { + // Avoid possible DoS + if (inherit == theme) + continue; + + if (isCursorTheme(inherit, depth + 1)) + return true; + } + } + + return false; +} + + +bool CursorThemeModel::handleDefault(const QDir &themeDir) +{ + QFileInfo info(themeDir.path()); + + // If "default" is a symlink + if (info.isSymLink()) + { + QFileInfo target(info.symLinkTarget()); + if (target.exists() && (target.isDir() || target.isSymLink())) + defaultName = target.fileName(); + + return true; + } + + // If there's no cursors subdir, or if it's empty + if (!themeDir.exists("cursors") || QDir(themeDir.path() + "/cursors") + .entryList(QDir::Files | QDir::NoDotAndDotDot ).isEmpty()) + { + if (themeDir.exists("index.theme")) + { + XCursorTheme theme(themeDir); + if (!theme.inherits().isEmpty()) + defaultName = theme.inherits().at(0); + } + return true; + } + + defaultName = QLatin1String("default"); + return false; +} + + +void CursorThemeModel::processThemeDir(const QDir &themeDir) +{ + bool haveCursors = themeDir.exists("cursors"); + + // Special case handling of "default", since it's usually either a + // symlink to another theme, or an empty theme that inherits another + // theme. + if (defaultName.isNull() && themeDir.dirName() == "default") + { + if (handleDefault(themeDir)) + return; + } + + // If the directory doesn't have a cursors subdir and lacks an + // index.theme file it can't be a cursor theme. + if (!themeDir.exists("index.theme") && !haveCursors) + return; + + // Create a cursor theme object for the theme dir + XCursorTheme *theme = new XCursorTheme(themeDir); + + // Skip this theme if it's hidden. + if (theme->isHidden()) { + delete theme; + return; + } + + // If there's no cursors subdirectory we'll do a recursive scan + // to check if the theme inherits a theme with one. + if (!haveCursors) + { + bool foundCursorTheme = false; + + foreach (const QString &name, theme->inherits()) + if ((foundCursorTheme = isCursorTheme(name))) + break; + + if (!foundCursorTheme) { + delete theme; + return; + } + } + + // Append the theme to the list + beginInsertRows(QModelIndex(), list.size(), list.size()); + list.append(theme); + endInsertRows(); +} + + +void CursorThemeModel::insertThemes() +{ + // Scan each base dir for Xcursor themes and add them to the list. + foreach (const QString &baseDir, searchPaths()) + { + QDir dir(baseDir); + if (!dir.exists()) + continue; + + // Process each subdir in the directory + foreach (const QString &name, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + // Don't process the theme if a theme with the same name already exists + // in the list. Xcursor will pick the first one it finds in that case, + // and since we use the same search order, the one Xcursor picks should + // be the one already in the list. + if (hasTheme(name) || !dir.cd(name)) + continue; + + processThemeDir(dir); + dir.cdUp(); // Return to the base dir + } + } + + // The theme Xcursor will end up using if no theme is configured + if (defaultName.isNull() || !hasTheme(defaultName)) + defaultName = QLatin1String("KDE_Classic"); +} + + +bool CursorThemeModel::addTheme(const QDir &dir) +{ + XCursorTheme *theme = new XCursorTheme(dir); + + // Don't add the theme to the list if it's hidden + if (theme->isHidden()) { + delete theme; + return false; + } + + // ### If the theme is hidden, the user will probably find it strange that it + // doesn't appear in the list view. There also won't be a way for the user + // to delete the theme using the KCM. Perhaps a warning about this should + // be issued, and the user be given a chance to undo the installation. + + // If an item with the same name already exists in the list, + // we'll remove it before inserting the new one. + for (int i = 0; i < list.count(); i++) + { + if (list.at(i)->hash() == theme->hash()) { + removeTheme(index(i, 0)); + break; + } + } + + // Append the theme to the list + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + list.append(theme); + endInsertRows(); + + return true; +} + + +void CursorThemeModel::removeTheme(const QModelIndex &index) +{ + if (!index.isValid()) + return; + + beginRemoveRows(QModelIndex(), index.row(), index.row()); + delete list.takeAt(index.row()); + endRemoveRows(); +} + diff --git a/kcontrol/input/xcursor/thememodel.h b/kcontrol/input/xcursor/thememodel.h new file mode 100644 index 00000000..bcf046a9 --- /dev/null +++ b/kcontrol/input/xcursor/thememodel.h @@ -0,0 +1,114 @@ +/* + * Copyright © 2005-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 THEMEMODEL_H +#define THEMEMODEL_H + +#include +#include + +class QDir; +class CursorTheme; + +// The two TableView/TreeView columns provided by the model +enum Columns { NameColumn = 0, DescColumn }; + + +/** + * The CursorThemeModel class provides a model for all locally installed + * Xcursor themes, and the KDE/Qt legacy bitmap theme. + * + * This class automatically scans the locations in the file system from + * which Xcursor loads cursors, and creates an internal list of all + * available cursor themes. + * + * The model provides this theme list to item views in the form of a list + * of rows with two columns; the first column has the theme's descriptive + * name and its sample cursor as its icon, and the second column contains + * the theme's description. + * + * Additional Xcursor themes can be added to a model after it's been + * created, by calling addTheme(), which takes QDir as a parameter, + * with the themes location. The intention is for this function to be + * called when a new Xcursor theme has been installed, after the model + * was instantiated. + * + * The KDE legacy theme is a read-only entry, with the descriptive name + * "KDE Classic", and the internal name "#kde_legacy#". + * + * Calling defaultIndex() will return the index of the theme Xcursor + * will use if the user hasn't explicitly configured a cursor theme. + */ +class CursorThemeModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + CursorThemeModel(QObject *parent = 0); + ~CursorThemeModel(); + inline int columnCount(const QModelIndex &parent = QModelIndex()) const; + inline int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role) const; + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /// Returns the CursorTheme at @p index. + const CursorTheme *theme(const QModelIndex &index); + + /// Returns the index for the CursorTheme with the internal name @p name, + /// or an invalid index if no matching theme can be found. + QModelIndex findIndex(const QString &name); + + /// Returns the index for the default theme. + QModelIndex defaultIndex(); + + /// Adds the theme in @p dir, and returns @a true if successful or @a false otherwise. + bool addTheme(const QDir &dir); + void removeTheme(const QModelIndex &index); + + /// Returns the list of base dirs Xcursor looks for themes in. + const QStringList searchPaths(); + + /// Refresh the list of themes by checking what's on disk. + void refreshList(); + + private: + bool handleDefault(const QDir &dir); + void processThemeDir(const QDir &dir); + void insertThemes(); + bool hasTheme(const QString &theme) const; + bool isCursorTheme(const QString &theme, const int depth = 0); + + private: + QList list; + QStringList baseDirs; + QString defaultName; +}; + +int CursorThemeModel::rowCount(const QModelIndex &) const +{ + return list.count(); +} + +int CursorThemeModel::columnCount(const QModelIndex &) const +{ + return 2; +} + +#endif // THEMEMODEL_H diff --git a/kcontrol/input/xcursor/themepage.cpp b/kcontrol/input/xcursor/themepage.cpp new file mode 100644 index 00000000..53880d5a --- /dev/null +++ b/kcontrol/input/xcursor/themepage.cpp @@ -0,0 +1,581 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include "../../krdb/krdb.h" + +#include +#include +#include +#include + +#include "themepage.h" +#include "themepage.moc" + +#include "thememodel.h" +#include "itemdelegate.h" +#include "sortproxymodel.h" +#include "cursortheme.h" + +#include +#include + +#ifdef HAVE_XFIXES +# include +#endif + + +ThemePage::ThemePage(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + installKnsButton->setIcon(KIcon("get-hot-new-stuff")); + installButton->setIcon(KIcon("document-import")); + removeButton->setIcon(KIcon("edit-delete")); + + model = new CursorThemeModel(this); + + proxy = new SortProxyModel(this); + proxy->setSourceModel(model); + proxy->setFilterCaseSensitivity(Qt::CaseSensitive); + proxy->sort(NameColumn, Qt::AscendingOrder); + + // Get the icon size for QListView + int size = style()->pixelMetric(QStyle::PM_LargeIconSize); + + view->setModel(proxy); + view->setItemDelegate(new ItemDelegate(this)); + view->setIconSize(QSize(size, size)); + view->setSelectionMode(QAbstractItemView::SingleSelection); + + // Make sure we find out about selection changes + connect(view->selectionModel(), + SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + SLOT(selectionChanged())); + + // Make sure we find out about size changes + connect(sizeComboBox, + SIGNAL(currentIndexChanged(int)), + SLOT(sizeChanged())); + + // Make sure we find out about user activity + connect(sizeComboBox, + SIGNAL(activated(int)), + SLOT(preferredSizeChanged())); + + // Disable the install button if we can't install new themes to ~/.icons, + // or Xcursor isn't set up to look for cursor themes there. + if (!model->searchPaths().contains(QDir::homePath() + "/.icons") || !iconsIsWritable()) { + installButton->setEnabled(false); + installKnsButton->setEnabled(false); + } + + connect(installKnsButton, SIGNAL(clicked()), SLOT(getNewClicked())); + connect(installButton, SIGNAL(clicked()), SLOT(installClicked())); + connect(removeButton, SIGNAL(clicked()), SLOT(removeClicked())); +} + + +ThemePage::~ThemePage() +{ +} + + +bool ThemePage::iconsIsWritable() const +{ + const QFileInfo icons = QFileInfo(QDir::homePath() + "/.icons"); + const QFileInfo home = QFileInfo(QDir::homePath()); + + return ((icons.exists() && icons.isDir() && icons.isWritable()) || + (!icons.exists() && home.isWritable())); +} + + +void ThemePage::updateSizeComboBox() +{ + // clear the combo box + sizeComboBox->clear(); + + // refill the combo box and adopt its icon size + QModelIndex selected = selectedIndex(); + int maxIconWidth = 0; + int maxIconHeight = 0; + if (selected.isValid()) + { + const CursorTheme *theme = proxy->theme(selected); + const QList sizes = theme->availableSizes(); + QIcon m_icon; + if (sizes.size() > 1) // only refill the combobox if there is more that 1 size + { + int i; + QList comboBoxList; + QPixmap m_pixmap; + + // insert the items + m_pixmap = theme->createIcon(0); + if (m_pixmap.width() > maxIconWidth) + maxIconWidth = m_pixmap.width(); + if (m_pixmap.height() > maxIconHeight) + maxIconHeight = m_pixmap.height(); + sizeComboBox->addItem( + QIcon(m_pixmap), + i18nc("@item:inlistbox size", "resolution dependent"), + 0); + comboBoxList << 0; + foreach (i, sizes) + { + m_pixmap = theme->createIcon(i); + if (m_pixmap.width() > maxIconWidth) + maxIconWidth = m_pixmap.width(); + if (m_pixmap.height() > maxIconHeight) + maxIconHeight = m_pixmap.height(); + sizeComboBox->addItem(QIcon(m_pixmap), QString::number(i), i); + comboBoxList << i; + }; + + // select an item + int selectItem = comboBoxList.indexOf(preferredSize); + if (selectItem < 0) // preferredSize not available for this theme + { + /* Search the value next to preferredSize. The first entry (0) + is ignored. (If preferredSize would have been 0, then we + would had found it yet. As preferredSize is not 0, we won't + default to "automatic size".)*/ + int j; + int distance; + int smallestDistance; + selectItem = 1; + j = comboBoxList.value(selectItem); + smallestDistance = j < preferredSize ? preferredSize - j : j - preferredSize; + for (int i = 2; i < comboBoxList.size(); ++i) + { + j = comboBoxList.value(i); + distance = j < preferredSize ? preferredSize - j : j - preferredSize; + if (distance < smallestDistance || (distance == smallestDistance && j > preferredSize)) + { + smallestDistance = distance; + selectItem = i; + }; + } + }; + sizeComboBox->setCurrentIndex(selectItem); + }; + }; + sizeComboBox->setIconSize(QSize(maxIconWidth, maxIconHeight)); + + // enable or disable the combobox + KConfig c("kcminputrc"); + KConfigGroup cg(&c, "Mouse"); + if (cg.isEntryImmutable("cursorSize")) { + sizeComboBox->setEnabled(false); + sizeLabel->setEnabled(false); + } else { + sizeComboBox->setEnabled(sizeComboBox->count() > 0); + sizeLabel->setEnabled(sizeComboBox->count() > 0); + }; +} + + +int ThemePage::selectedSize() const +{ + if (sizeComboBox->isEnabled() && sizeComboBox->currentIndex() >= 0) + return sizeComboBox->itemData(sizeComboBox->currentIndex(), Qt::UserRole).toInt(); + return 0; +} + + +void ThemePage::updatePreview() +{ + QModelIndex selected = selectedIndex(); + + if (selected.isValid()) { + const CursorTheme *theme = proxy->theme(selected); + preview->setTheme(theme, selectedSize()); + removeButton->setEnabled(theme->isWritable()); + } else { + preview->setTheme(NULL, 0); + removeButton->setEnabled(false); + }; +} + + +bool ThemePage::haveXfixes() +{ + bool result = false; + +#ifdef HAVE_XFIXES + int event_base, error_base; + if (XFixesQueryExtension(QX11Info::display(), &event_base, &error_base)) + { + int major, minor; + XFixesQueryVersion(QX11Info::display(), &major, &minor); + result = (major >= 2); + } +#endif + + return result; +} + + +bool ThemePage::applyTheme(const CursorTheme *theme, const int size) +{ + // Require the Xcursor version that shipped with X11R6.9 or greater, since + // in previous versions the Xfixes code wasn't enabled due to a bug in the + // build system (freedesktop bug #975). +#if HAVE_XFIXES && XFIXES_MAJOR >= 2 && XCURSOR_LIB_VERSION >= 10105 + if (!theme) + return false; + + if (!haveXfixes()) + return false; + + QByteArray themeName = QFile::encodeName(theme->name()); + + // Set up the proper launch environment for newly started apps + KToolInvocation::klauncher()->setLaunchEnv("XCURSOR_THEME", themeName); + + // Update the Xcursor X resources + runRdb(0); + + // Notify all applications that the cursor theme has changed + KGlobalSettings::self()->emitChange(KGlobalSettings::CursorChanged); + + // Reload the standard cursors + QStringList names; + + // Qt cursors + names << "left_ptr" << "up_arrow" << "cross" << "wait" + << "left_ptr_watch" << "ibeam" << "size_ver" << "size_hor" + << "size_bdiag" << "size_fdiag" << "size_all" << "split_v" + << "split_h" << "pointing_hand" << "openhand" + << "closedhand" << "forbidden" << "whats_this" << "copy" << "move" << "link"; + + // X core cursors + names << "X_cursor" << "right_ptr" << "hand1" + << "hand2" << "watch" << "xterm" + << "crosshair" << "left_ptr_watch" << "center_ptr" + << "sb_h_double_arrow" << "sb_v_double_arrow" << "fleur" + << "top_left_corner" << "top_side" << "top_right_corner" + << "right_side" << "bottom_right_corner" << "bottom_side" + << "bottom_left_corner" << "left_side" << "question_arrow" + << "pirate"; + + foreach (const QString &name, names) + { + QCursor cursor = theme->loadCursor(name, size); + XFixesChangeCursorByName(x11Info().display(), cursor.handle(), QFile::encodeName(name)); + } + + return true; +#else + Q_UNUSED(theme) + return false; +#endif +} + + +void ThemePage::save() +{ + const CursorTheme *theme = selectedIndex().isValid() ? proxy->theme(selectedIndex()) : NULL; + const int size = selectedSize(); + + KConfig config("kcminputrc"); + KConfigGroup c(&config, "Mouse"); + if (theme) + { + c.writeEntry("cursorTheme", theme->name()); + }; + c.writeEntry("cursorSize", size); + preferredSize = size; + c.sync(); + + if (!applyTheme(theme, size)) + { + KMessageBox::information(this, + i18n("You have to restart KDE for these changes to take effect."), + i18n("Cursor Settings Changed"), "CursorSettingsChanged"); + } + + appliedIndex = selectedIndex(); + appliedSize = size; +} + + +void ThemePage::load() +{ + view->selectionModel()->clear(); + // Get the name of the theme libXcursor currently uses + QString currentTheme = XcursorGetTheme(x11Info().display()); + + // Get the name of the theme KDE is configured to use + KConfig c("kcminputrc"); + KConfigGroup cg(&c, "Mouse"); + currentTheme = cg.readEntry("cursorTheme", currentTheme); + + // Find the theme in the listview + if (!currentTheme.isEmpty()) + appliedIndex = proxy->findIndex(currentTheme); + else + appliedIndex = proxy->defaultIndex(); + + // Disable the listview and the buttons if we're in kiosk mode + if (cg.isEntryImmutable("cursorTheme")) + { + view->setEnabled(false); + installButton->setEnabled(false); + removeButton->setEnabled(false); + } + + // Load cursor size + int size = cg.readEntry("cursorSize", 0); + if (size <= 0) + preferredSize = 0; + else + preferredSize = size; + updateSizeComboBox(); // This handles also the kiosk mode + + appliedSize = size; + + const CursorTheme *theme = proxy->theme(appliedIndex); + + if (appliedIndex.isValid()) + { + // Select the current theme + view->setCurrentIndex(appliedIndex); + view->scrollTo(appliedIndex, QListView::PositionAtCenter); + + // Update the preview widget as well + preview->setTheme(theme, size); + } + + if (!theme || !theme->isWritable()) + removeButton->setEnabled(false); +} + + +void ThemePage::defaults() +{ + view->selectionModel()->clear(); + QModelIndex defaultIndex = proxy->findIndex("Oxygen_Black"); + view->setCurrentIndex(defaultIndex); + preferredSize = 0; + updateSizeComboBox(); +} + + +void ThemePage::selectionChanged() +{ + updateSizeComboBox(); + updatePreview(); + + emit changed(appliedIndex != selectedIndex()); +} + +QModelIndex ThemePage::selectedIndex() const +{ + QModelIndexList selection = view->selectionModel()->selectedIndexes(); + if (!selection.isEmpty()) { + return (selection.at(0)); + } + return QModelIndex(); +} + +void ThemePage::sizeChanged() +{ + updatePreview(); + emit changed(selectedSize() != appliedSize); +} + +void ThemePage::preferredSizeChanged() +{ + int index = sizeComboBox->currentIndex(); + if (index >= 0) + preferredSize = sizeComboBox->itemData(index, Qt::UserRole).toInt(); + else + preferredSize = 0; +} + +void ThemePage::getNewClicked() +{ + KNS3::DownloadDialog dialog("xcursor.knsrc", this); + if (dialog.exec()) { + KNS3::Entry::List list = dialog.changedEntries(); + if (list.count() > 0) + model->refreshList(); + } +} + +void ThemePage::installClicked() +{ + // Get the URL for the theme we're going to install + KUrl url = KUrlRequesterDialog::getUrl(QString(), this, i18n("Drag or Type Theme URL")); + + if (url.isEmpty()) + return; + + QString tempFile; + if (!KIO::NetAccess::download(url, tempFile, this)) + { + QString text; + + if (url.isLocalFile()) + text = i18n("Unable to find the cursor theme archive %1.", + url.prettyUrl()); + else + text = i18n("Unable to download the cursor theme archive; " + "please check that the address %1 is correct.", + url.prettyUrl()); + + KMessageBox::sorry(this, text); + return; + } + + if (!installThemes(tempFile)) + KMessageBox::error(this, i18n("The file %1 does not appear to be a valid " + "cursor theme archive.", url.fileName())); + + KIO::NetAccess::removeTempFile(tempFile); +} + + +void ThemePage::removeClicked() +{ + // We don't have to check if the current index is valid, since + // the remove button will be disabled when there's no selection. + const CursorTheme *theme = proxy->theme(selectedIndex()); + + // Don't let the user delete the currently configured theme + if (selectedIndex() == appliedIndex) { + KMessageBox::sorry(this, i18n("You cannot delete the theme you are currently " + "using.
    You have to switch to another theme first.
    ")); + return; + } + + // Get confirmation from the user + QString question = i18n("Are you sure you want to remove the " + "%1 cursor theme?
    " + "This will delete all the files installed by this theme.
    ", + theme->title()); + + int answer = KMessageBox::warningContinueCancel(this, question, + i18n("Confirmation"), KStandardGuiItem::del()); + + if (answer != KMessageBox::Continue) + return; + + // Delete the theme from the harddrive + KIO::del(KUrl(theme->path())); // async + + // Remove the theme from the model + proxy->removeTheme(selectedIndex()); + + // TODO: + // Since it's possible to substitute cursors in a system theme by adding a local + // theme with the same name, we shouldn't remove the theme from the list if it's + // still available elsewhere. We could add a + // bool CursorThemeModel::tryAddTheme(const QString &name), and call that, but + // since KIO::del() is an asynchronos operation, the theme we're deleting will be + // readded to the list again before KIO has removed it. +} + + +bool ThemePage::installThemes(const QString &file) +{ + KTar archive(file); + + if (!archive.open(QIODevice::ReadOnly)) + return false; + + const KArchiveDirectory *archiveDir = archive.directory(); + QStringList themeDirs; + + // Extract the dir names of the cursor themes in the archive, and + // append them to themeDirs + foreach(const QString &name, archiveDir->entries()) + { + const KArchiveEntry *entry = archiveDir->entry(name); + if (entry->isDirectory() && entry->name().toLower() != "default") + { + const KArchiveDirectory *dir = static_cast(entry); + if (dir->entry("index.theme") && dir->entry("cursors")) + themeDirs << dir->name(); + } + } + + if (themeDirs.isEmpty()) + return false; + + // The directory we'll install the themes to + QString destDir = QDir::homePath() + "/.icons/"; + KStandardDirs::makeDir(destDir); // Make sure the directory exists + + // Process each cursor theme in the archive + foreach (const QString &dirName, themeDirs) + { + QDir dest(destDir + dirName); + if (dest.exists()) + { + QString question = i18n("A theme named %1 already exists in your icon " + "theme folder. Do you want replace it with this one?", dirName); + + int answer = KMessageBox::warningContinueCancel(this, question, + i18n("Overwrite Theme?"), + KStandardGuiItem::overwrite()); + + if (answer != KMessageBox::Continue) + continue; + + // ### If the theme that's being replaced is the current theme, it + // will cause cursor inconsistencies in newly started apps. + } + + // ### Should we check if a theme with the same name exists in a global theme dir? + // If that's the case it will effectively replace it, even though the global theme + // won't be deleted. Checking for this situation is easy, since the global theme + // will be in the listview. Maybe this should never be allowed since it might + // result in strange side effects (from the average users point of view). OTOH + // a user might want to do this 'upgrade' a global theme. + + const KArchiveDirectory *dir = static_cast + (archiveDir->entry(dirName)); + dir->copyTo(dest.path()); + model->addTheme(dest); + } + + archive.close(); + return true; +} + diff --git a/kcontrol/input/xcursor/themepage.h b/kcontrol/input/xcursor/themepage.h new file mode 100644 index 00000000..3b21dd9d --- /dev/null +++ b/kcontrol/input/xcursor/themepage.h @@ -0,0 +1,99 @@ +/* + * Copyright © 2003-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * + * 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 THEMEPAGE_H +#define THEMEPAGE_H + +#include +#include + +#include "ui_themepage.h" + +class CursorThemeModel; +class SortProxyModel; +class CursorTheme; + +class ThemePage : public QWidget, private Ui::ThemePage +{ + Q_OBJECT + + public: + ThemePage(QWidget* parent = 0); + ~ThemePage(); + + // Called by the KCM + void save(); + void load(); + void defaults(); + + static bool haveXfixes(); + + signals: + void changed(bool); + + private slots: + void selectionChanged(); + /** Updates the preview. If the size has changed, it also emits changed() */ + void sizeChanged(); + /** Sets #preferredSize to the item that is currently selected in sizeComboBox. + If none is selected, it is set to 0. */ + void preferredSizeChanged(); + /** Updates the size combo box. It loads the size list of the selected cursor + theme with the corresponding icons and chooses an appropriate entry. It + enables the combo box and the label if the theme provides more than one + size, otherwise it disables it. If the size setting is looked in kiosk + mode, it stays always disabled. */ + void updateSizeComboBox(); + void getNewClicked(); + void installClicked(); + void removeClicked(); + + private: + /** @returns 0 if in the UI "automatic size" is selected, otherwise + returns the custom size. */ + int selectedSize() const; + /** Holds the last size that was choosen by the user. Example: The user chooses + theme1 which provides the sizes 24 and 36. He chooses 36. preferredSize gets + set to 36. Now, he switchs to theme2 which provides the sizes 30 and 40. + preferredSize still is 36, so the UI will default to 40, which is next to 36. + Now, he chooses theme3 which provides the sizes 34 and 44. preferredSize is + still 36, so the UI defaults to 34. Now the user changes manually to 44. This + will also change preferredSize. */ + int preferredSize; + void updatePreview(); + QModelIndex selectedIndex() const; + bool installThemes(const QString &file); + /** Applies a given theme, using XFixes, XCursor and KGlobalSettings. + @param theme The cursor theme to be applied. It is save to pass 0 here + (will result in \e false as return value). + @param size The size hint that is used to select the cursor size. + @returns If the changes could be applied. Will return \e false if \e theme is + 0 or if the XFixes and XCursor libraries aren't available in the required + version, otherwise returns \e true. */ + bool applyTheme(const CursorTheme *theme, const int size); + bool iconsIsWritable() const; + + CursorThemeModel *model; + SortProxyModel *proxy; + + int appliedSize; + // This index refers to the CursorThemeModel, not the proxy or the view + QPersistentModelIndex appliedIndex; +}; + +#endif // THEMEPAGE_H diff --git a/kcontrol/input/xcursor/themepage.ui b/kcontrol/input/xcursor/themepage.ui new file mode 100644 index 00000000..be736638 --- /dev/null +++ b/kcontrol/input/xcursor/themepage.ui @@ -0,0 +1,120 @@ + + + ThemePage + + + + 0 + 0 + 541 + 360 + + + + + + + Select the cursor theme you want to use (hover preview to test cursor): + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + + + + + 0 + 1 + + + + true + + + QAbstractItemView::ScrollPerPixel + + + + + + + Get new color schemes from the Internet + + + Get New Theme... + + + + + + + Install From File... + + + + + + + Remove Theme + + + + + + + + 0 + 0 + + + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + + 0 + 0 + + + + + + + + Size: + + + + + + + + KPushButton + QPushButton +
    kpushbutton.h
    +
    + + PreviewWidget + QWidget +
    previewwidget.h
    + 1 +
    +
    + + +
    diff --git a/kcontrol/input/xcursor/xcursor.knsrc b/kcontrol/input/xcursor/xcursor.knsrc new file mode 100644 index 00000000..27f5b765 --- /dev/null +++ b/kcontrol/input/xcursor/xcursor.knsrc @@ -0,0 +1,6 @@ +[KNewStuff3] +ProvidersUrl=http://download.kde.org/ocs/providers.xml +Categories=X11 Mouse Theme +InstallPath=.icons +Uncompress=archive + diff --git a/kcontrol/input/xcursor/xcursortheme.cpp b/kcontrol/input/xcursor/xcursortheme.cpp new file mode 100644 index 00000000..7f6ae00b --- /dev/null +++ b/kcontrol/input/xcursor/xcursortheme.cpp @@ -0,0 +1,231 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published + * by the Free Software Foundation. + * + * 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 +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "xcursortheme.h" + + +// Static variable holding alternative names for some cursors +QHash XCursorTheme::alternatives; + +XCursorTheme::XCursorTheme(const QDir &themeDir) + : CursorTheme(themeDir.dirName()) +{ + // Directory information + setName(themeDir.dirName()); + setPath(themeDir.path()); + setIsWritable(QFileInfo(themeDir.path()).isWritable()); // ### perhaps this shouldn't be cached + + if (themeDir.exists("index.theme")) + parseIndexFile(); + + QString cursorFile = path() + "/cursors/left_ptr"; + QList sizeList; + XcursorImages *images = XcursorFilenameLoadAllImages(qPrintable(cursorFile)); + if (images) + { + for (int i = 0; i < images->nimage; ++i) + { + if (!sizeList.contains(images->images[i]->size)) + sizeList.append(images->images[i]->size); + }; + XcursorImagesDestroy(images); + qSort(sizeList.begin(), sizeList.end()); + m_availableSizes = sizeList; + }; + if (!sizeList.isEmpty()) + { + QString sizeListString = QString::number(sizeList.takeFirst()); + while (!sizeList.isEmpty()) + { + sizeListString.append(", "); + sizeListString.append(QString::number(sizeList.takeFirst())); + }; + QString tempString = i18nc( + "@info/plain The argument is the list of available sizes (in pixel). Example: " + "'Available sizes: 24' or 'Available sizes: 24, 36, 48'", + "(Available sizes: %1)", + sizeListString); + if (m_description.isEmpty()) + m_description = tempString; + else + m_description = m_description + ' ' + tempString; + }; +} + + +void XCursorTheme::parseIndexFile() +{ + KConfig config(path() + "/index.theme", KConfig::NoGlobals); + KConfigGroup cg(&config, "Icon Theme"); + + m_title = cg.readEntry("Name", m_title); + m_description = cg.readEntry("Comment", m_description); + m_sample = cg.readEntry("Example", m_sample); + m_hidden = cg.readEntry("Hidden", false); + m_inherits = cg.readEntry("Inherits", QStringList()); +} + + +QString XCursorTheme::findAlternative(const QString &name) const +{ + if (alternatives.isEmpty()) + { + alternatives.reserve(18); + + // Qt uses non-standard names for some core cursors. + // If Xcursor fails to load the cursor, Qt creates it with the correct name using the + // core protcol instead (which in turn calls Xcursor). We emulate that process here. + // Note that there's a core cursor called cross, but it's not the one Qt expects. + alternatives.insert("cross", "crosshair"); + alternatives.insert("up_arrow", "center_ptr"); + alternatives.insert("wait", "watch"); + alternatives.insert("ibeam", "xterm"); + alternatives.insert("size_all", "fleur"); + alternatives.insert("pointing_hand", "hand2"); + + // Precomputed MD5 hashes for the hardcoded bitmap cursors in Qt and KDE. + // Note that the MD5 hash for left_ptr_watch is for the KDE version of that cursor. + alternatives.insert("size_ver", "00008160000006810000408080010102"); + alternatives.insert("size_hor", "028006030e0e7ebffc7f7070c0600140"); + alternatives.insert("size_bdiag", "fcf1c3c7cd4491d801f1e1c78f100000"); + alternatives.insert("size_fdiag", "c7088f0f3e6c8088236ef8e1e3e70000"); + alternatives.insert("whats_this", "d9ce0ab605698f320427677b458ad60b"); + alternatives.insert("split_h", "14fef782d02440884392942c11205230"); + alternatives.insert("split_v", "2870a09082c103050810ffdffffe0204"); + alternatives.insert("forbidden", "03b6e0fcb3499374a867c041f52298f0"); + alternatives.insert("left_ptr_watch", "3ecb610c1bf2410f44200f48c40d3599"); + alternatives.insert("hand2", "e29285e634086352946a0e7090d73106"); + alternatives.insert("openhand", "9141b49c8149039304290b508d208c40"); + alternatives.insert("closedhand", "05e88622050804100c20044008402080"); + } + + return alternatives.value(name, QString()); +} + + +XcursorImage *XCursorTheme::xcLoadImage(const QString &image, int size) const +{ + QByteArray cursorName = QFile::encodeName(image); + QByteArray themeName = QFile::encodeName(name()); + + return XcursorLibraryLoadImage(cursorName, themeName, size); +} + + +XcursorImages *XCursorTheme::xcLoadImages(const QString &image, int size) const +{ + QByteArray cursorName = QFile::encodeName(image); + QByteArray themeName = QFile::encodeName(name()); + + return XcursorLibraryLoadImages(cursorName, themeName, size); +} + + +int XCursorTheme::autodetectCursorSize() const +{ + /* This code is basically borrowed from display.c of the XCursor library + We can't use "int XcursorGetDefaultSize(Display *dpy)" because if + previously the cursor size was set to a custom value, it would return + this custom value. */ + int size = 0; + int dpi = 0; + Display *dpy = QX11Info::display(); + // The string "v" is owned and will be destroyed by Xlib + char *v = XGetDefault(dpy, "Xft", "dpi"); + if (v) + dpi = atoi(v); + if (dpi) + size = dpi * 16 / 72; + if (size == 0) + { + int dim; + if (DisplayHeight(dpy, DefaultScreen(dpy)) < + DisplayWidth(dpy, DefaultScreen(dpy))) + { + dim = DisplayHeight(dpy, DefaultScreen(dpy)); + } else { + dim = DisplayWidth(dpy, DefaultScreen(dpy)); + }; + size = dim / 48; + } + return size; +} + + +QCursor XCursorTheme::loadCursor(const QString &name, int size) const +{ + if (size <= 0) + size = autodetectCursorSize(); + + // Load the cursor images + XcursorImages *images = xcLoadImages(name, size); + + if (!images) + images = xcLoadImages(findAlternative(name), size); + + if (!images) + return QCursor(); + + // Create the cursor + Cursor handle = XcursorImagesLoadCursor(QX11Info::display(), images); + QCursor cursor = QCursor(Qt::HANDLE(handle)); // QCursor takes ownership of the handle + XcursorImagesDestroy(images); + + setCursorName(cursor, name); + return cursor; +} + + +QImage XCursorTheme::loadImage(const QString &name, int size) const +{ + if (size <= 0) + size = autodetectCursorSize(); + + // Load the image + XcursorImage *xcimage = xcLoadImage(name, size); + + if (!xcimage) + xcimage = xcLoadImage(findAlternative(name), size); + + if (!xcimage) { + return QImage(); + } + + // Convert the XcursorImage to a QImage, and auto-crop it + QImage image((uchar *)xcimage->pixels, xcimage->width, xcimage->height, + QImage::Format_ARGB32_Premultiplied ); + + image = autoCropImage(image); + XcursorImageDestroy(xcimage); + + return image; +} + diff --git a/kcontrol/input/xcursor/xcursortheme.h b/kcontrol/input/xcursor/xcursortheme.h new file mode 100644 index 00000000..310dd55a --- /dev/null +++ b/kcontrol/input/xcursor/xcursortheme.h @@ -0,0 +1,71 @@ +/* + * Copyright © 2006-2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2 or at your option version 3 as published by + * the Free Software Foundation. + * + * 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 XCURSORTHEME_H +#define XCURSORTHEME_H + +#include + +#include "cursortheme.h" + +class QDir; + +struct _XcursorImage; +struct _XcursorImages; + +typedef _XcursorImage XcursorImage; +typedef _XcursorImages XcursorImages; + +/** + * The XCursorTheme class is a CursorTheme implementation for Xcursor themes. + */ +class XCursorTheme : public CursorTheme +{ + public: + /** + * Initializes itself from the @p dir information, and parses the + * index.theme file if the dir has one. + */ + XCursorTheme(const QDir &dir); + virtual ~XCursorTheme() {} + + const QStringList inherits() const { return m_inherits; } + QImage loadImage(const QString &name, int size = 0) const; + QCursor loadCursor(const QString &name, int size = 0) const; + + protected: + XCursorTheme(const QString &title, const QString &desc) + : CursorTheme(title, desc) {} + void setInherits(const QStringList &val) { m_inherits = val; } + + private: + XcursorImage *xcLoadImage(const QString &name, int size) const; + XcursorImages *xcLoadImages(const QString &name, int size) const; + void parseIndexFile(); + QString findAlternative(const QString &name) const; + /** Returns the size that the XCursor library would use if no + cursor size is given. This depends mainly on Xft.dpi. */ + int autodetectCursorSize() const; + + QStringList m_inherits; + static QHash alternatives; +}; + +#endif // XCURSORTHEME_H + diff --git a/kcontrol/keyboard/CMakeLists.txt b/kcontrol/keyboard/CMakeLists.txt new file mode 100644 index 00000000..973a39d4 --- /dev/null +++ b/kcontrol/keyboard/CMakeLists.txt @@ -0,0 +1,146 @@ +SET(CMAKE_REQUIRED_LIBRARIES -lXi) +CHECK_FUNCTION_EXISTS(_XiGetDevicePresenceNotifyEvent XiGetDevicePresenceNotifyEvent_EXISTS) + +if( X11_Xinput_FOUND AND XiGetDevicePresenceNotifyEvent_EXISTS ) + set(XiGetDevicePresence_FOUND 1) + ADD_DEFINITIONS(-DHAVE_XINPUT_AND_DEVICE_NOTIFY=1) +else( X11_Xinput_FOUND AND XiGetDevicePresenceNotifyEvent_EXISTS ) + MESSAGE(STATUS "_XiGetDevicePresenceNotifyEvent is not found, libXi version 1.2.0 or later is required to keep layouts with keyboard hotplugging") +endif( X11_Xinput_FOUND AND XiGetDevicePresenceNotifyEvent_EXISTS ) + +set ( text_paint_LIB ${KDE4_PLASMA_LIBS} ) + + + +### kded daemon ### + +set( kded_keyboard_SRCS + keyboard_daemon.cpp + layout_memory.cpp + layout_memory_persister.cpp + x11_helper.cpp + xinput_helper.cpp + xkb_helper.cpp + keyboard_config.cpp + keyboard_hardware.cpp + numlockx.c + bindings.cpp +# next are temporary for sys tray UI + layout_tray_icon.cpp + layouts_menu.cpp + flags.cpp + xkb_rules.cpp +) + +kde4_add_plugin(kded_keyboard ${kded_keyboard_SRCS}) + +target_link_libraries(kded_keyboard + ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES} + ${text_paint_LIB} + ${QT_QTXML_LIBRARY} ${X11_Xkbfile_LIB} + ) + +if(X11_XTest_FOUND) + target_link_libraries(kded_keyboard ${X11_XTest_LIB}) +endif(X11_XTest_FOUND) + +if(XiGetDevicePresence_FOUND) + target_link_libraries(kded_keyboard ${X11_Xinput_LIB}) +endif(XiGetDevicePresence_FOUND) + +install( TARGETS kded_keyboard DESTINATION ${PLUGIN_INSTALL_DIR} ) +install( FILES keyboard.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) + + +### plasma applet ### + +set( plasma_applet_keyboard_SRCS + keyboard_applet.cpp + flags.cpp + keyboard_config.cpp + xkb_rules.cpp + x11_helper.cpp + xkb_helper.cpp + layouts_menu.cpp +) + +kde4_add_plugin(plasma_applet_keyboard ${plasma_applet_keyboard_SRCS}) + +target_link_libraries(plasma_applet_keyboard + ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${X11_Xkbfile_LIB} ${X11_LIBRARIES} + ${text_paint_LIB} +) + +install( TARGETS plasma_applet_keyboard DESTINATION ${PLUGIN_INSTALL_DIR} ) +install( FILES plasma_applet_keyboard.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + +### widget lib ### + +set( keyboard_layout_widget_SRCS + layout_widget.cpp + keyboard_config.cpp + flags.cpp + x11_helper.cpp + xkb_helper.cpp +) + +# MODULE? +kde4_add_plugin(keyboard_layout_widget ${keyboard_layout_widget_SRCS}) + +target_link_libraries(keyboard_layout_widget + ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES} + ${text_paint_LIB} + ${QT_QTXML_LIBRARY} ${X11_Xkbfile_LIB} +) + +install( TARGETS keyboard_layout_widget DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +### kcm keyboard ### +include_directories("preview") + +set(kcm_keyboard_PART_SRCS + kcm_keyboard.cpp + kcm_keyboard_widget.cpp + kcm_view_models.cpp + kcm_add_layout_dialog.cpp + keyboard_config.cpp + x11_helper.cpp + xkb_helper.cpp + xkb_rules.cpp + flags.cpp + iso_codes.cpp + kcmmisc.cpp + bindings.cpp + preview/keyaliases.cpp + preview/keyboardlayout.cpp + preview/keyboardpainter.cpp + preview/keysymbols.cpp + preview/keysymhelper.cpp + preview/kbpreviewframe.cpp + preview/keysym2ucs.cpp +) + + +kde4_add_ui_files(kcm_keyboard_PART_SRCS kcm_keyboard.ui kcm_add_layout_dialog.ui kcmmiscwidget.ui) + +kde4_add_plugin(kcm_keyboard ${kcm_keyboard_PART_SRCS}) + +target_link_libraries(kcm_keyboard + ${KDE4_KIO_LIBS} ${X11_Xkbfile_LIB} ${X11_LIBRARIES} + ${text_paint_LIB} +) + +install(TARGETS kcm_keyboard DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install( FILES kcm_keyboard.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + +# Images + +add_subdirectory( pics ) + + +# Unit tests + +add_subdirectory( tests ) diff --git a/kcontrol/keyboard/Messages.sh b/kcontrol/keyboard/Messages.sh new file mode 100755 index 00000000..8d527522 --- /dev/null +++ b/kcontrol/keyboard/Messages.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash +$EXTRACTRC kcm*.ui >> rc.cpp +$XGETTEXT rc.cpp kcmmisc.cpp preview/*.cpp -o $podir/kcmkeyboard.pot +$XGETTEXT kcm_*.cpp keyboard_*.cpp layout_*.cpp flags.cpp layouts_menu.cpp bindings.cpp -o $podir/kxkb.pot +rm -f rc.cpp diff --git a/kcontrol/keyboard/README b/kcontrol/keyboard/README new file mode 100644 index 00000000..25c50b47 --- /dev/null +++ b/kcontrol/keyboard/README @@ -0,0 +1,44 @@ +This is new project to replace keyboard (kcmmisc) and kxkb +to manage keyboard harware configuration and layouts. + +Components: + +kcm_init: +* no kcm_init - all initialization (including after keyboard hot-plug) is done by kded daemon + +Keyboard daemon: +* configures keyboard layouts on start +* provides DBUS API "org.kde.KXKB/kxkb" +* listens to window/desktop switching if layout switch mode is not global +* listens to new keyboard devices and reinitializes keyboard layouts and hardware settings +* listens to Global KDE Shortcut to switch layouts +* listens to Global Shortcut settings change +* listens to keyboard configuration changes +* provides systray icon for layout + +Keyboard applet: +* displays current layout with text and (optionally flag) +* allows to toggle layouts by click or set them with context menu + +Layout widget: +* displays current layout with text embedded in another widget (e.g. lock dialog) +* currently only short text (no flag or long text) +* dynamically loaded as a plugin + +KCM Module: +* allows to configure keyboard hardware, layouts and xkb options (advanced) + +Advantages (over old code): +* One UI module to configure keyboard layouts and hardware +* Allows to configure keyboard model/xkb options without configuring layouts +* Less cluttered layout configuration control (add layout is separate) +* Layout control/DBus interface is separate from the indicator +* Does not require libxklvier +* Takes language names from iso-codes project +* Takes country names/translations from xkeyboard-config project +* Information about current layouts is always taken from X server, so should be more robust +* Cleaner code (rewritten from scratch) +* Due to many points above should start faster (though no benchmarks performed) + +New features: +* Allow selection of keyboard layout by language diff --git a/kcontrol/keyboard/TODO b/kcontrol/keyboard/TODO new file mode 100644 index 00000000..2e58efb2 --- /dev/null +++ b/kcontrol/keyboard/TODO @@ -0,0 +1,37 @@ +Tests: +* tests + +Core: +* better handling when layouts set manually and not present in config + +KCM UI: +* use listboxes instead of combos in add layout dialog +* allow multiple layouts to be added in same dialog? + +KCM UI cleanup: +* layouts, sizes, alignment etc in kcm + +plasma applet: + +kxkb part: +* tooltip (currently does not work in lockdlg for some reason) + +tray icon: + +Code cleanup: +* rules, iso_codes: + better error handling + +Improvement: +* remove XInput libs from plasma applet and layout widget (find a nicer way) +* optimize fetching groups and layouts (cache them) / fetch current group directly +* refactor/optimize/clean the code +* refactor client code for D-BUS API to use library instead? + +External improvements: +* Add KSharedConfig::configChanged() signal +* make iso-codes external package +* make flags external package + +Documentation: +* update documentation for keyboard module diff --git a/kcontrol/keyboard/bindings.cpp b/kcontrol/keyboard/bindings.cpp new file mode 100644 index 00000000..1e5cbe87 --- /dev/null +++ b/kcontrol/keyboard/bindings.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "bindings.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "x11_helper.h" +#include "flags.h" + + +static const char* actionName = I18N_NOOP("Switch to Next Keyboard Layout"); +static const char* COMPONENT_NAME = I18N_NOOP("KDE Keyboard Layout Switcher"); + + +KeyboardLayoutActionCollection::KeyboardLayoutActionCollection(QObject* parent, bool configAction_): + KActionCollection(parent, KComponentData(KAboutData(COMPONENT_NAME, 0, ki18n(COMPONENT_NAME), 0))), + configAction(configAction_) +{ + KAction* toggleAction = addAction( actionName ); + toggleAction->setText( i18n(actionName) ); + toggleAction->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_K)); + if( configAction ) { + toggleAction->setProperty("isConfigurationAction", true); + } + kDebug() << "Keyboard layout toggle shortcut" << toggleAction->globalShortcut().toString(); +} + +KeyboardLayoutActionCollection::~KeyboardLayoutActionCollection() +{ + clear(); +} + +KAction* KeyboardLayoutActionCollection::getToggeAction() +{ + return static_cast(action(0)); +} + +KAction* KeyboardLayoutActionCollection::createLayoutShortcutActon(const LayoutUnit& layoutUnit, const Rules* rules, bool autoload) +{ + QString longLayoutName = Flags::getLongText( layoutUnit, rules ); + QString actionName = "Switch keyboard layout to "; + actionName += longLayoutName; + KAction* action = addAction( actionName ); + action->setText( i18n("Switch keyboard layout to %1", longLayoutName) ); + KAction::GlobalShortcutLoading loading = autoload ? KAction::Autoloading : KAction::NoAutoloading; + KShortcut shortcut = autoload ? KShortcut() : KShortcut(layoutUnit.getShortcut()); + action->setGlobalShortcut(shortcut, KAction::ShortcutTypes(KAction::ActiveShortcut /*| KAction::DefaultShortcut*/), loading); + action->setData(layoutUnit.toString()); + if( configAction ) { + action->setProperty("isConfigurationAction", true); + } + kDebug() << "Registered layout shortcut" << action->globalShortcut(KAction::ActiveShortcut).primary().toString() << "for" << action->text() << "lu.shortcut" << layoutUnit.getShortcut().toString(); + return action; +} + +void KeyboardLayoutActionCollection::setToggleShortcut(const QKeySequence& keySequence) +{ + KShortcut shortcut(keySequence); + getToggeAction()->setGlobalShortcut(shortcut, KAction::ActiveShortcut, KAction::NoAutoloading); + kDebug() << "Saving keyboard layout KDE shortcut" << shortcut.toString(); +} + +//KAction* KeyboardLayoutActionCollection::setShortcut(LayoutUnit& layoutUnit, const QKeySequence& keySequence, const Rules* rules) +//{ +// KAction* action = getAction(layoutUnit); +// if( action == NULL && ! keySequence.isEmpty() ) { +// action = createLayoutShortcutActon(layoutUnit, rules, false); +// } +// else if( action != NULL && keySequence.isEmpty() ){ +//// action->setGlobalShortcut(KShortcut(keySequence), KAction::ActiveShortcut, KAction::NoAutoloading); // do we need this? +// removeAction(action); +// action = NULL; +// } +//// if( configAction ) { +//// layoutUnit.setShortcut(keySequence); // shortcut was restored +//// } +// return action; +//} + +void KeyboardLayoutActionCollection::setLayoutShortcuts(QList& layoutUnits, const Rules* rules) +{ + for (QList::iterator i = layoutUnits.begin(); i != layoutUnits.end(); ++i) { + LayoutUnit& layoutUnit = *i; + if( ! layoutUnit.getShortcut().isEmpty() ) { + createLayoutShortcutActon(layoutUnit, rules, false); + } + } + kDebug() << "Cleaning component shortcuts on save" << KGlobalAccel::cleanComponent(COMPONENT_NAME); +} + +void KeyboardLayoutActionCollection::loadLayoutShortcuts(QList& layoutUnits, const Rules* rules) +{ + for (QList::iterator i = layoutUnits.begin(); i != layoutUnits.end(); ++i) { + LayoutUnit& layoutUnit = *i; + KAction* action = createLayoutShortcutActon(layoutUnit, rules, true); + QKeySequence shortcut = action->globalShortcut(KAction::ActiveShortcut).primary(); // shortcut was restored + if( ! shortcut.isEmpty() ) { + kDebug() << "Restored shortcut for" << layoutUnit.toString() << shortcut; + layoutUnit.setShortcut(shortcut); + } + else { + kDebug() << "Skipping empty shortcut for" << layoutUnit.toString(); + removeAction(action); + } + } + kDebug() << "Cleaning component shortcuts on load" << KGlobalAccel::cleanComponent(COMPONENT_NAME); +} + +//KAction* KeyboardLayoutActionCollection::getAction(const LayoutUnit& layoutUnit) +//{ +// for(int i=1; idata() == layoutUnit.toString() ) +// return static_cast(action(i)); +// } +// return NULL; +//} + +void KeyboardLayoutActionCollection::resetLayoutShortcuts() +{ + for(int i=1; i(action(i))->setGlobalShortcut(KShortcut(), KAction::ShortcutTypes(KAction::ActiveShortcut | KAction::DefaultShortcut), KAction::NoAutoloading); + } +} diff --git a/kcontrol/keyboard/bindings.h b/kcontrol/keyboard/bindings.h new file mode 100644 index 00000000..09a9bdc7 --- /dev/null +++ b/kcontrol/keyboard/bindings.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef BINDINGS_H_ +#define BINDINGS_H_ + +#include + + +//class QObject; +class KAction; +class Rules; +class LayoutUnit; +template class QList; + + +class KeyboardLayoutActionCollection : public KActionCollection { +public: + KeyboardLayoutActionCollection(QObject* parent, bool configAction); + virtual ~KeyboardLayoutActionCollection(); + + KAction* getToggeAction(); +// KAction* getAction(const LayoutUnit& layoutUnit); + KAction* createLayoutShortcutActon(const LayoutUnit& layoutUnit, const Rules* rules, bool autoload); +// KAction* setShortcut(LayoutUnit& layoutUnit, const QKeySequence& keySequence, const Rules* rules); + void setLayoutShortcuts(QList& layoutUnits, const Rules* rules); + void setToggleShortcut(const QKeySequence& keySequence); + void loadLayoutShortcuts(QList& layoutUnits, const Rules* rules); + void resetLayoutShortcuts(); + +private: + bool configAction; +}; + +//KActionCollection* createGlobalActionCollection(QObject *parent, KAction** mainAction); +//KAction* createLayoutShortcutActon(KActionCollection* actionCollection, const LayoutUnit& layoutUnit, const Rules* rules); + +#endif /* BINDINGS_H_ */ diff --git a/kcontrol/keyboard/flags.cpp b/kcontrol/keyboard/flags.cpp new file mode 100644 index 00000000..582e376d --- /dev/null +++ b/kcontrol/keyboard/flags.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "flags.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "x11_helper.h" + +//for text handling +#include "keyboard_config.h" +#include "xkb_rules.h" + + +static const int FLAG_MAX_WIDTH = 21; +static const int FLAG_MAX_HEIGHT = 14; +static const char flagTemplate[] = "l10n/%1/flag.png"; + +Flags::Flags(): + svg(NULL) +{ + transparentPixmap = new QPixmap(FLAG_MAX_WIDTH, FLAG_MAX_HEIGHT); + transparentPixmap->fill(Qt::transparent); +} + +Flags::~Flags() +{ + if( svg != NULL ) { + disconnect(svg, SIGNAL(repaintNeeded()), this, SLOT(themeChanged())); + delete svg; + } + delete transparentPixmap; +} + +const QIcon Flags::getIcon(const QString& layout) +{ + if( ! iconMap.contains(layout) ) { + iconMap[ layout ] = createIcon(layout); + } + return iconMap[ layout ]; +} + +QIcon Flags::createIcon(const QString& layout) +{ + QIcon icon; + if( ! layout.isEmpty() ) { + if( layout == "epo" ) { + QString file = KStandardDirs::locate("data", "kcmkeyboard/pics/epo.png"); + icon.addFile(file); + } + else { + QString countryCode = getCountryFromLayoutName( layout ); + if( ! countryCode.isEmpty() ) { + QString file = KStandardDirs::locate("locale", QString(flagTemplate).arg(countryCode)); + // kDebug() << "Creating icon for" << layout << "with" << file; + icon.addFile(file); + } + } + } + return icon; +} + + +//static +//const QStringList NON_COUNTRY_LAYOUTS = QString("ara,brai,epo,latam,mao").split(","); + +QString Flags::getCountryFromLayoutName(const QString& layout) const +{ + QString countryCode = layout; + + if( countryCode == "nec_vndr/jp" ) + return "jp"; + +// if( NON_COUNTRY_LAYOUTS.contain(layout) ) + if( countryCode.length() > 2 ) + return ""; + + return countryCode; +} + +//TODO: move this to some other class? + +QString Flags::getShortText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig) +{ + if( layoutUnit.isEmpty() ) + return QString("--"); + + QString layoutText = layoutUnit.layout; + + foreach(const LayoutUnit& lu, keyboardConfig.layouts) { + if( layoutUnit.layout == lu.layout && layoutUnit.variant == lu.variant ) { + layoutText = lu.getDisplayName(); + break; + } + } + +//TODO: good autolabel +// if( layoutText == layoutUnit.layout && layoutUnit.getDisplayName() != layoutUnit.layout ) { +// layoutText = layoutUnit.getDisplayName(); +// } + + return layoutText; +} + +QString Flags::getFullText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig, const Rules* rules) +{ + QString shortText = Flags::getShortText(layoutUnit, keyboardConfig); + QString longText = Flags::getLongText(layoutUnit, rules); + return i18nc("short layout label - full layout name", "%1 - %2", shortText, longText); +} + +static QString getDisplayText(const QString& layout, const QString& variant, const Rules* rules) +{ + if( variant.isEmpty() ) + return layout; + if( rules == NULL || rules->version == "1.0" ) + return i18nc("layout - variant", "%1 - %2", layout, variant); + return variant; +} + +QString Flags::getLongText(const LayoutUnit& layoutUnit, const Rules* rules) +{ + if( rules == NULL ) { + return getDisplayText(layoutUnit.layout, layoutUnit.variant, rules); + } + + QString layoutText = layoutUnit.layout; + const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutUnit.layout); + if( layoutInfo != NULL ) { + layoutText = layoutInfo->description; + + if( ! layoutUnit.variant.isEmpty() ) { + const VariantInfo* variantInfo = layoutInfo->getVariantInfo(layoutUnit.variant); + QString variantText = variantInfo != NULL ? variantInfo->description : layoutUnit.variant; + + layoutText = getDisplayText(layoutText, variantText, rules); + } + } + + return layoutText; +} + +static +QString getPixmapKey(const KeyboardConfig& keyboardConfig) +{ + switch(keyboardConfig.indicatorType) { + case KeyboardConfig::SHOW_FLAG: + return "_fl"; + case KeyboardConfig::SHOW_LABEL_ON_FLAG: + return "_bt"; + case KeyboardConfig::SHOW_LABEL: + return "_lb"; + } + return "_"; // should not happen +} + +void Flags::drawLabel(QPainter& painter, const QString& layoutText, bool flagShown) +{ + QFont font = painter.font(); + + QRect rect = painter.window(); +// int fontSize = layoutText.length() == 2 +// ? height * 7 / 10 +// : height * 5 / 10; + + int fontSize = rect.height();// * 7 /10; + + font.setPixelSize(fontSize); + font.setWeight(QFont::DemiBold); + + QFontMetrics fm = painter.fontMetrics(); + int width = fm.width(layoutText); + + if( width > rect.width() * 2 / 3 ) { + fontSize = round( (double)fontSize * ((double)rect.width()*2/3) / width ); + } + + int smallestReadableSize = KGlobalSettings::smallestReadableFont().pixelSize(); + if( fontSize < smallestReadableSize ) { + fontSize = smallestReadableSize; + } + font.setPixelSize(fontSize); + +#ifdef DONT_USE_PLASMA + painter.setFont(font); + painter.setPen(Qt::white); + painter.drawText(QRect(rect).adust(1,1,0,0), Qt::AlignCenter | Qt::AlignHCenter, layoutText); + painter.setPen(Qt::black); + painter.drawText(rect, Qt::AlignCenter | Qt::AlignHCenter, layoutText); +#else + // we init svg so that we get notification about theme change + getSvg(); + + QColor textColor = flagShown ? Qt::black : Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); + QColor shadowColor = flagShown ? Qt::white : Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor); + QPoint offset = QPoint(0, 0); + + // QPixmap pixmap = Plasma::PaintUtils::texturedText(layoutText, font, svg); + QPixmap labelPixmap = Plasma::PaintUtils::shadowText(layoutText, font, textColor, shadowColor, offset, 3); + + int y = round((rect.height() - labelPixmap.height()) / 2.0); + int x = round((rect.width() - labelPixmap.width()) / 2.0); + painter.drawPixmap(QPoint(x, y), labelPixmap); +#endif +} + +const QIcon Flags::getIconWithText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig) +{ + QString keySuffix(getPixmapKey(keyboardConfig)); + QString key(layoutUnit.toString() + keySuffix); + if( iconOrTextMap.contains(key) ) { + return iconOrTextMap[ key ]; + } + + if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_FLAG ) { + QIcon icon = getIcon(layoutUnit.layout); + if( ! icon.isNull() ) { + iconOrTextMap[ key ] = icon; + return icon; + } + } + + QString layoutText = Flags::getShortText(layoutUnit, keyboardConfig); + + const QSize TRAY_ICON_SIZE(21, 14); + QPixmap pixmap = QPixmap(TRAY_ICON_SIZE); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); +// p.setRenderHint(QPainter::SmoothPixmapTransform); +// p.setRenderHint(QPainter::Antialiasing); + + if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_LABEL_ON_FLAG ) { + QIcon iconf = createIcon(layoutUnit.layout); + iconf.paint(&painter, painter.window(), Qt::AlignCenter); + } + + drawLabel(painter, layoutText, keyboardConfig.isFlagShown()); + + painter.end(); + + QIcon icon(pixmap); + iconOrTextMap[ key ] = icon; + + return icon; +} + +Plasma::Svg* Flags::getSvg() +{ + if( svg == NULL ) { + svg = new Plasma::Svg; + svg->setImagePath("widgets/labeltexture"); + svg->setContainsMultipleImages(true); + connect(svg, SIGNAL(repaintNeeded()), this, SLOT(themeChanged())); + } + return svg; +} + +void Flags::themeChanged() +{ +// kDebug() << "Theme changed, new text color" << Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); + clearCache(); + emit pixmapChanged(); +} + +void Flags::clearCache() +{ +// kDebug() << "Clearing flag pixmap cache"; + iconOrTextMap.clear(); +} diff --git a/kcontrol/keyboard/flags.h b/kcontrol/keyboard/flags.h new file mode 100644 index 00000000..06ec831b --- /dev/null +++ b/kcontrol/keyboard/flags.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef FLAGS_H_ +#define FLAGS_H_ + +#include +#include +#include + +class QPixmap; +class QIcon; +class LayoutUnit; +class KeyboardConfig; +class Rules; +class QPainter; +namespace Plasma { + class Svg; +} + +class Flags : public QObject +{ + Q_OBJECT + +public: + Flags(); + virtual ~Flags(); + + const QIcon getIcon(const QString& layout); + const QIcon getIconWithText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig); + const QPixmap& getTransparentPixmap() const { return *transparentPixmap; } + + static QString getLongText(const LayoutUnit& layoutUnit, const Rules* rules); + static QString getShortText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig); + static QString getFullText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig, const Rules* rules); + +public Q_SLOTS: + void themeChanged(); + void clearCache(); + +Q_SIGNALS: + void pixmapChanged(); + +private: + QIcon createIcon(const QString& layout); + QString getCountryFromLayoutName(const QString& fullLayoutName) const; + void drawLabel(QPainter& painter, const QString& layoutText, bool flagShown); + Plasma::Svg* getSvg(); + + QMap iconMap; + QMap iconOrTextMap; + QPixmap* transparentPixmap; + Plasma::Svg* svg; +}; + +#endif /* FLAGS_H_ */ diff --git a/kcontrol/keyboard/iso_codes.cpp b/kcontrol/keyboard/iso_codes.cpp new file mode 100644 index 00000000..0ffbbd92 --- /dev/null +++ b/kcontrol/keyboard/iso_codes.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "iso_codes.h" + +#include +#include +#include + +#include + + +class IsoCodesPrivate { +public: + IsoCodesPrivate(const QString& isoCode_, const QString& isoCodesXmlDir_): + isoCode(isoCode_), + isoCodesXmlDir(isoCodesXmlDir_), + loaded(false) + {} + void buildIsoEntryList(); + + const QString isoCode; + const QString isoCodesXmlDir; + QList isoEntryList; + bool loaded; +}; + +class XmlHandler : public QXmlDefaultHandler +{ +public: + XmlHandler(const QString& isoCode_, QList& isoEntryList_): + isoCode(isoCode_), + qName("iso_"+isoCode+"_entry"), + isoEntryList(isoEntryList_) {} + + bool startElement(const QString &namespaceURI, const QString &localName, + const QString &qName, const QXmlAttributes &attributes); +// bool fatalError(const QXmlParseException &exception); +// QString errorString() const; + +private: + const QString isoCode; + const QString qName; + QList& isoEntryList; +}; + +bool XmlHandler::startElement(const QString &/*namespaceURI*/, const QString &/*localName*/, + const QString &qName, const QXmlAttributes &attributes) +{ + if( qName == this->qName ) { + IsoCodeEntry entry; + for(int i=0; iinsertCatalog(QString("iso_")+d->isoCode); +} + +IsoCodes::~IsoCodes() +{ + KGlobal::locale()->removeCatalog(QString("iso_")+d->isoCode); + delete d; +} + +QList IsoCodes::getEntryList() +{ + if( ! d->loaded ) { + d->buildIsoEntryList(); + } + return d->isoEntryList; +} + +//const char* IsoCodes::iso_639="639"; +const char* IsoCodes::iso_639_3="639_3"; +const char* IsoCodes::attr_name="name"; +//const char* IsoCodes::attr_iso_639_2B_code="iso_639_2B_code"; +//const char* IsoCodes::attr_iso_639_2T_code="iso_639_2T_code"; +//const char* IsoCodes::attr_iso_639_1_code="iso_639_1_code"; +const char* IsoCodes::attr_iso_639_3_id="id"; + +const IsoCodeEntry* IsoCodes::getEntry(const QString& attributeName, const QString& attributeValue) +{ + if( ! d->loaded ) { + d->buildIsoEntryList(); + } + for(QList::Iterator it = d->isoEntryList.begin(); it != d->isoEntryList.end(); ++it) { + const IsoCodeEntry* isoCodeEntry = &(*it); + if( isoCodeEntry->value(attributeName) == attributeValue ) + return isoCodeEntry; + } + return NULL; +} + +void IsoCodesPrivate::buildIsoEntryList() +{ + loaded = true; + + QFile file(QString("%1/iso_%2.xml").arg(isoCodesXmlDir, isoCode)); + if( !file.open(QFile::ReadOnly | QFile::Text) ) { + kError() << "Can't open the xml file" << file.fileName(); + return; + } + + XmlHandler xmlHandler(isoCode, isoEntryList); + + QXmlSimpleReader reader; + reader.setContentHandler(&xmlHandler); + reader.setErrorHandler(&xmlHandler); + + QXmlInputSource xmlInputSource(&file); + + if( ! reader.parse(xmlInputSource) ) { + kError() << "Failed to parse the xml file" << file.fileName(); + return; + } + + kDebug() << "Loaded" << isoEntryList.count() << ("iso entry definitions for iso"+isoCode) << "from" << file.fileName(); +} diff --git a/kcontrol/keyboard/iso_codes.h b/kcontrol/keyboard/iso_codes.h new file mode 100644 index 00000000..6a337392 --- /dev/null +++ b/kcontrol/keyboard/iso_codes.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef ISO_CODES_H_ +#define ISO_CODES_H_ + +#include +#include +#include + + +/** + * Represents an item for iso-* standards which consists of attributes and their values + */ +struct IsoCodeEntry: public QMap +{ +}; + +class IsoCodesPrivate; + +/** + * Represents a set of codes for iso-* standards. + * Uses iso-codes project to read and localize the values. + */ +class IsoCodes +{ +public: +// static const char* iso_639; + static const char* iso_639_3; + + static const char* attr_name; +// static const char* attr_iso_639_2B_code; +// static const char* attr_iso_639_2T_code; +// static const char* attr_iso_639_1_code; + static const char* attr_iso_639_3_id; + + /** + * @param isoCode Code for iso standard, i.e. "639", for convenience there's iso_* constants defined + */ + explicit IsoCodes(const QString& isoCode, const QString& isoCodesXmlDir="/usr/share/xml/iso-codes"); + ~IsoCodes(); + + /** + * @return Returns the list of items for this iso-* standard + */ + QList getEntryList(); + /** + * @return Returns the item for which given attribute has specified value + */ + const IsoCodeEntry* getEntry(const QString& attributeName, const QString& attributeValue); + +private: + IsoCodesPrivate* const d; +}; + +#endif /* ISO_CODES_H_ */ diff --git a/kcontrol/keyboard/kcm_add_layout_dialog.cpp b/kcontrol/keyboard/kcm_add_layout_dialog.cpp new file mode 100644 index 00000000..444da8ea --- /dev/null +++ b/kcontrol/keyboard/kcm_add_layout_dialog.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcm_add_layout_dialog.h" +#include +#include + +#include "xkb_rules.h" +#include "flags.h" +#include "iso_codes.h" + +#include "ui_kcm_add_layout_dialog.h" + + +AddLayoutDialog::AddLayoutDialog(const Rules* rules_, Flags* flags_, bool showLabel, QWidget* parent): + QDialog(parent), + rules(rules_), + flags(flags_), + selectedLanguage("no_language") +{ + layoutDialogUi = new Ui_AddLayoutDialog(); + layoutDialogUi->setupUi(this); + + QSet languages; + foreach(const LayoutInfo* layoutInfo, rules->layoutInfos) { + QSet langs = QSet::fromList(layoutInfo->languages); + languages.unite( langs ); + } + IsoCodes isoCodes(IsoCodes::iso_639_3); + foreach(const QString& lang, languages) { + const IsoCodeEntry* isoCodeEntry = isoCodes.getEntry(IsoCodes::attr_iso_639_3_id, lang); +// const IsoCodeEntry* isoCodeEntry = isoCodes.getEntry(IsoCodes::attr_iso_639_2B_code, lang); +// if( isoCodeEntry == NULL ) { +// isoCodeEntry = isoCodes.getEntry(IsoCodes::attr_iso_639_2T_code, lang); +// } + QString name = isoCodeEntry != NULL ? i18n(isoCodeEntry->value(IsoCodes::attr_name).toUtf8()) : lang; + layoutDialogUi->languageComboBox->addItem(name, lang); + } + layoutDialogUi->languageComboBox->model()->sort(0); + layoutDialogUi->languageComboBox->insertItem(0, i18n("Any language"), ""); + layoutDialogUi->languageComboBox->setCurrentIndex(0); + + if( showLabel ) { + layoutDialogUi->labelEdit->setMaxLength(LayoutUnit::MAX_LABEL_LENGTH); + } + else { + layoutDialogUi->labelLabel->setVisible(false); + layoutDialogUi->labelEdit->setVisible(false); + } + + languageChanged(0); + connect(layoutDialogUi->languageComboBox, SIGNAL(activated(int)), this, SLOT(languageChanged(int))); + connect(layoutDialogUi->layoutComboBox, SIGNAL(activated(int)), this, SLOT(layoutChanged(int))); + connect(layoutDialogUi->prevbutton,SIGNAL(clicked()),this,SLOT(preview())); +} + +void AddLayoutDialog::languageChanged(int langIdx) +{ + QString lang = layoutDialogUi->languageComboBox->itemData(langIdx).toString(); + if( lang == selectedLanguage ) + return; + + QPixmap emptyPixmap(layoutDialogUi->layoutComboBox->iconSize()); + emptyPixmap.fill(Qt::transparent); + + layoutDialogUi->layoutComboBox->clear(); + int defaultIndex = -1; + int i = 0; + foreach(const LayoutInfo* layoutInfo, rules->layoutInfos) { + if( lang.isEmpty() || layoutInfo->isLanguageSupportedByLayout(lang) ) { + if( flags ) { + QIcon icon(flags->getIcon(layoutInfo->name)); + if( icon.isNull() ) { + icon = QIcon(emptyPixmap); // align text with no icons + } + layoutDialogUi->layoutComboBox->addItem(icon, layoutInfo->description, layoutInfo->name); + } + else { + layoutDialogUi->layoutComboBox->addItem(layoutInfo->description, layoutInfo->name); + } + + // try to guess best default layout selection for given language + if( ! lang.isEmpty() && defaultIndex == -1 && layoutInfo->isLanguageSupportedByDefaultVariant(lang) ) { + defaultIndex = i; + } + i++; + } + } + if( defaultIndex == -1 ) { + defaultIndex = 0; + } + + layoutDialogUi->layoutComboBox->model()->sort(0); + layoutDialogUi->layoutComboBox->setCurrentIndex(defaultIndex); + layoutChanged(defaultIndex); + + selectedLanguage = lang; +} + +void AddLayoutDialog::layoutChanged(int layoutIdx) +{ + QString layoutName = layoutDialogUi->layoutComboBox->itemData(layoutIdx).toString(); + if( layoutName == selectedLayout ) + return; + + QString lang = layoutDialogUi->languageComboBox->itemData(layoutDialogUi->languageComboBox->currentIndex()).toString(); + + layoutDialogUi->variantComboBox->clear(); + const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutName); + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + if( lang.isEmpty() || layoutInfo->isLanguageSupportedByVariant(variantInfo, lang) ) { + layoutDialogUi->variantComboBox->addItem(variantInfo->description, variantInfo->name); + } + } + + layoutDialogUi->variantComboBox->model()->sort(0); + + if( lang.isEmpty() || layoutInfo->isLanguageSupportedByDefaultVariant(lang) ) { + layoutDialogUi->variantComboBox->insertItem(0, i18nc("variant", "Default"), ""); + } + layoutDialogUi->variantComboBox->setCurrentIndex(0); + + layoutDialogUi->labelEdit->setText(layoutName); + + selectedLayout = layoutName; +} + +void AddLayoutDialog::accept() +{ + selectedLayoutUnit.layout = layoutDialogUi->layoutComboBox->itemData(layoutDialogUi->layoutComboBox->currentIndex()).toString(); + selectedLayoutUnit.variant = layoutDialogUi->variantComboBox->itemData(layoutDialogUi->variantComboBox->currentIndex()).toString(); + QString label = layoutDialogUi->labelEdit->text(); + if( label == selectedLayoutUnit.layout ) { + label = ""; + } + selectedLayoutUnit.setDisplayName( label ); + selectedLayoutUnit.setShortcut(layoutDialogUi->kkeysequencewidget->keySequence()); + QDialog::accept(); +} + + +void AddLayoutDialog::preview(){ + int index = layoutDialogUi->variantComboBox->currentIndex(); + QString variant = layoutDialogUi->variantComboBox->itemData(index).toString(); + KeyboardPainter* layoutPreview = new KeyboardPainter(); + layoutPreview->generateKeyboardLayout(selectedLayout, variant); + layoutPreview->setModal(true); + layoutPreview->exec(); + delete layoutPreview; +} diff --git a/kcontrol/keyboard/kcm_add_layout_dialog.h b/kcontrol/keyboard/kcm_add_layout_dialog.h new file mode 100644 index 00000000..5273347d --- /dev/null +++ b/kcontrol/keyboard/kcm_add_layout_dialog.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KCM_ADD_LAYOUT_DIALOG_H_ +#define KCM_ADD_LAYOUT_DIALOG_H_ + +#include + +#include "keyboard_config.h" +#include "preview/keyboardpainter.h" + +class Rules; +class Flags; +class Ui_AddLayoutDialog; + +class AddLayoutDialog: public QDialog +{ + Q_OBJECT + +public: + AddLayoutDialog(const Rules* rules, Flags* flags, bool showLabel, QWidget* parent=NULL); + + LayoutUnit getSelectedLayoutUnit() { return selectedLayoutUnit; } + QString getvariant(QString variant); + void accept(); + +public Q_SLOTS: + void languageChanged(int langIdx); + void layoutChanged(int layoutIdx); + void preview(); + +private: + const Rules* rules; + Flags* flags; + Ui_AddLayoutDialog* layoutDialogUi; + QString selectedLanguage; + QString selectedLayout; + LayoutUnit selectedLayoutUnit; +}; + + +#endif /* KCM_ADD_LAYOUT_DIALOG_H_ */ diff --git a/kcontrol/keyboard/kcm_add_layout_dialog.ui b/kcontrol/keyboard/kcm_add_layout_dialog.ui new file mode 100644 index 00000000..78304fbc --- /dev/null +++ b/kcontrol/keyboard/kcm_add_layout_dialog.ui @@ -0,0 +1,149 @@ + + + AddLayoutDialog + + + + 0 + 0 + 525 + 270 + + + + Add Layout + + + + + + + 0 + 0 + + + + + + + + Layout: + + + + + + + + 0 + 0 + + + + + + + + Shortcut: + + + + + + + Variant: + + + + + + + + + + Label: + + + + + + + Limit selection by language: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + Preview + + + + + + + + KKeySequenceWidget + QWidget +
    kkeysequencewidget.h
    +
    +
    + + + + buttonBox + accepted() + AddLayoutDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddLayoutDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
    diff --git a/kcontrol/keyboard/kcm_keyboard.cpp b/kcontrol/keyboard/kcm_keyboard.cpp new file mode 100644 index 00000000..da75d28b --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "kcm_keyboard.h" + +#include +#include +#include +#include + +#include +#include +//#include + +#include "kcm_keyboard_widget.h" +#include "x11_helper.h" +#include "keyboard_config.h" +#include "xkb_rules.h" +#include "keyboard_dbus.h" + +#include "xkb_helper.h" + +//temp hack +#include "kcmmisc.h" + + +K_PLUGIN_FACTORY(KeyboardModuleFactory, registerPlugin();) +K_EXPORT_PLUGIN(KeyboardModuleFactory("kcmkeyboard")) + +KCMKeyboard::KCMKeyboard(QWidget *parent, const QVariantList &args) + : KCModule(KeyboardModuleFactory::componentData(), parent/*, name*/) +{ + KGlobal::locale()->insertCatalog("kxkb"); + KGlobal::locale()->insertCatalog("kcmmisc"); + + KAboutData *about = + new KAboutData("kcmkeyboard", 0, ki18n("KDE Keyboard Control Module"), + 0, KLocalizedString(), KAboutData::License_GPL, + ki18n("(c) 2010 Andriy Rysin")); + + setAboutData( about ); + setQuickHelp( i18n("

    Keyboard

    This control module can be used to configure keyboard" + " parameters and layouts.")); + + + rules = Rules::readRules(Rules::READ_EXTRAS); + + keyboardConfig = new KeyboardConfig(); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(KDialog::spacingHint()); + + widget = new KCMKeyboardWidget(rules, keyboardConfig, componentData(), args, parent); + layout->addWidget(widget); + + connect(widget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + + setButtons(Help|Default|Apply); +} + +KCMKeyboard::~KCMKeyboard() +{ + delete keyboardConfig; + delete rules; +} + +void KCMKeyboard::defaults() +{ + keyboardConfig->setDefaults(); + widget->updateUI(); + widget->getKcmMiscWidget()->defaults(); + emit changed(true); +} + +void KCMKeyboard::load() +{ + keyboardConfig->load(); + widget->updateUI(); + widget->getKcmMiscWidget()->load(); +} + +//static void initializeKeyboardSettings(); +void KCMKeyboard::save() +{ + keyboardConfig->save(); + widget->save(); + widget->getKcmMiscWidget()->save(); + + QDBusMessage message = QDBusMessage::createSignal(KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE); + QDBusConnection::sessionBus().send(message); +} diff --git a/kcontrol/keyboard/kcm_keyboard.desktop b/kcontrol/keyboard/kcm_keyboard.desktop new file mode 100644 index 00000000..258cc28f --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard.desktop @@ -0,0 +1,238 @@ +[Desktop Entry] +Exec=kcmshell4 kcm_keyboard +Icon=preferences-desktop-keyboard +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/keyboard/index.html +Categories=Qt;KDE;X-KDE-settings-hardware; + +X-KDE-Library=kcm_keyboard +X-KDE-Init-Symbol=keyboard +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=input-devices +X-KDE-Weight=50 +OnlyShowIn=KDE; + +Name=Keyboard +Name[af]=Sleutelbord +Name[ar]=لوحة المفاتيح +Name[ast]=Tecláu +Name[be]=Клавіятура +Name[be@latin]=Klavijatura +Name[bg]=Клавиатура +Name[bn]=কীবোর্ড +Name[bn_IN]=কি-বোর্ড +Name[br]=Stokellaoueg +Name[bs]=Tastatura +Name[ca]=Teclat +Name[ca@valencia]=Teclat +Name[cs]=Klávesnice +Name[csb]=Klawiatura +Name[cy]=Bysellfwrdd +Name[da]=Tastatur +Name[de]=Tastatur +Name[el]=Πληκτρολόγιο +Name[en_GB]=Keyboard +Name[eo]=Klavaro +Name[es]=Teclado +Name[et]=Klaviatuur +Name[eu]=Teklatua +Name[fa]=صفحه کلید +Name[fi]=Näppäimistö +Name[fr]=Clavier +Name[fy]=Toetseboerd +Name[ga]=Méarchlár +Name[gl]=Teclado +Name[gu]=કીબોર્ડ +Name[he]=מקלדת +Name[hi]=कुंजीपट +Name[hne]=कुंजीपट +Name[hr]=Tipkovnica +Name[hsb]=Tastatura +Name[hu]=Billentyűzet +Name[ia]=Claviero +Name[id]=Papan Ketik +Name[is]=Lyklaborð +Name[it]=Tastiera +Name[ja]=キーボード +Name[ka]=კლავიატურა +Name[kk]=Перенетақта +Name[km]=ក្ដារ​ចុច +Name[kn]=ಕೀಲಿಮಣೆ +Name[ko]=키보드 +Name[ku]=Klavye +Name[lt]=Klaviatūra +Name[lv]=Tastatūra +Name[mai]=कुँजीपटल +Name[mk]=Тастатура +Name[ml]=കീബോര്‍ഡ് +Name[mr]=कळफलक +Name[nb]=Tastatur +Name[nds]=Tastatuur +Name[ne]=कुञ्जीपाटी +Name[nl]=Toetsenbord +Name[nn]=Tastatur +Name[oc]=Clavièr +Name[or]=କିବୋର୍ଡ଼ +Name[pa]=ਕੀਬੋਰਡ +Name[pl]=Klawiatura +Name[pt]=Teclado +Name[pt_BR]=Teclado +Name[ro]=Tastatură +Name[ru]=Клавиатура +Name[se]=Boallobeavdi +Name[si]=යතුරුපුවරුව +Name[sk]=Klávesnica +Name[sl]=Tipkovnica +Name[sr]=Тастатура +Name[sr@ijekavian]=Тастатура +Name[sr@ijekavianlatin]=Tastatura +Name[sr@latin]=Tastatura +Name[sv]=Tangentbord +Name[ta]=விசைப்பலகை +Name[te]=కీబోర్డ్ +Name[tg]=Клавиатура +Name[th]=แป้นพิมพ์ +Name[tr]=Klavye +Name[ug]=ھەرپتاختا +Name[uk]=Клавіатура +Name[uz]=Tugmatag +Name[uz@cyrillic]=Тугматаг +Name[vi]=Bàn phím +Name[wa]=Taprece +Name[xh]=Ibhodi enezitshixo +Name[x-test]=xxKeyboardxx +Name[zh_CN]=键盘 +Name[zh_TW]=鍵盤 + +Comment=Keyboard settings +Comment[af]=Sleutelbord instellings +Comment[ar]=إعدادات لوحة المفاتيح +Comment[ast]=Preferencies del tecláu +Comment[be]=Настаўленні клавіятуры +Comment[be@latin]=Nałady klavijatury +Comment[bg]=Настройки на клавиатура +Comment[bn]=কীবোর্ড সেটিংস +Comment[bn_IN]=কি-বোর্ড সংক্রান্ত বৈশিষ্ট্য +Comment[br]=Kefluniañ ar stokellaoueg +Comment[bs]=Postavke tastature +Comment[ca]=Arranjament del teclat +Comment[ca@valencia]=Arranjament del teclat +Comment[cs]=Nastavení klávesnice +Comment[csb]=Nastôw klawiaturë +Comment[cy]=Gosodiadau Bysellfwrdd +Comment[da]=Tastaturindstillinger +Comment[de]=Einstellung der Tastatur +Comment[el]=Ρυθμίσεις πληκτρολογίου +Comment[en_GB]=Keyboard settings +Comment[eo]=Agordo de la klavaro +Comment[es]=Preferencias del teclado +Comment[et]=Klaviatuuri seadistused +Comment[eu]=Teklatuaren ezarpenak +Comment[fa]=تنظیمات صفحه کلید +Comment[fi]=Näppäimistön asetukset +Comment[fy]=Toetseboerd ynstelle +Comment[ga]=Socruithe Méarchláir +Comment[gl]=Configuración do teclado +Comment[gu]=કીબોર્ડ ગોઠવણીઓ +Comment[he]=הגדרות המקלדת +Comment[hi]=कुंजीपट विन्यास +Comment[hne]=कुंजीपट सेटिंग +Comment[hr]=Postavke tipkovnice +Comment[hsb]=Nastajenja za tastaturu +Comment[hu]=A billentyűzet beállításai +Comment[ia]=Preferentias de claviero +Comment[id]=Pengaturan Papan Ketik +Comment[is]=Stillingar lyklaborðs +Comment[ka]=კლავიატურის კონფიგურაცია +Comment[kk]=Перенетақтаны баптау +Comment[km]=ការ​កំណត់​ក្ដារចុច +Comment[kn]=ಕೀಲಿಮಣೆ ಸಂಯೋಜನೆಗಳು +Comment[ko]=키보드 설정 +Comment[ku]=Mîhengên Klavyeyê +Comment[lt]=Klaviatūros parametrai +Comment[lv]=Tastatūras parametri +Comment[mai]=कुंजीपट बिन्यास +Comment[mk]=Поставувања на тастатурата +Comment[ml]=കീബോര്‍ഡിന്റെ സജ്ജീകരണങ്ങള്‍ +Comment[mr]=कळफलक संयोजना +Comment[nb]=Tastaturinnstillinger +Comment[nds]=De Tastatuur instellen +Comment[ne]=कुञ्जीपाटी सेटिङ +Comment[nl]=Toetsenbord instellen +Comment[nn]=Tastaturinnstillingar +Comment[oc]=Paramètres de clavièr +Comment[or]=କିବୋର୍ଡ଼ ସଂରଚନା +Comment[pa]=ਕੀਬੋਰਡ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia klawiatury +Comment[pt]=Configuração do teclado +Comment[pt_BR]=Configurações do teclado +Comment[ro]=Configurări tastatură +Comment[ru]=Настройка клавиатуры +Comment[se]=Boallobeavdeheivehusat +Comment[si]=යතුරුපුවරු සැකසුම් +Comment[sk]=Nastavenie klávesnice +Comment[sl]=Nastavitve tipkovnice +Comment[sr]=Поставке тастатуре +Comment[sr@ijekavian]=Поставке тастатуре +Comment[sr@ijekavianlatin]=Postavke tastature +Comment[sr@latin]=Postavke tastature +Comment[sv]=Anpassa tangentbordets inställningar +Comment[ta]=விசைப்பலகை அமைப்புகள் +Comment[te]=కీబోర్డ్ అమరికలు +Comment[tg]=Танзимоти клавиатура +Comment[th]=ตั้งค่าต่าง ๆ ของแป้นพิมพ์ +Comment[tr]=Klavye ayarları +Comment[ug]=ھەرپتاختا تەڭشەك +Comment[uk]=Параметри клавіатури +Comment[uz]=Tugmatagning moslamalari +Comment[uz@cyrillic]=Тугматагнинг мосламалари +Comment[vi]=Thiết lập bàn phím +Comment[wa]=Apontiaedje del taprece +Comment[xh]=Izicwangciso zebhodi enezitshixo +Comment[x-test]=xxKeyboard settingsxx +Comment[zh_CN]=键盘设置 +Comment[zh_TW]=鍵盤設定 + +X-KDE-Keywords=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key +X-KDE-Keywords[bs]=tastatura,ponavljanje tastature,kliknute glasnoću,umetnuti uređaj,ponoviti,glasnoća,NumLock,NumPad,tip tastature,model tastature,izgled tastature,izgled tipki,jezik,rezervna tastatura,uključivanje tastature,Ctrl tipka,velika slova,esperanto,cirkumfleks,ukloniti X server,LED tastatura,sastavljene tipke +X-KDE-Keywords[ca]=Teclat,Repetició de teclat,Volum de clic,Dispositius d'entrada,repetició,volum,BloqNum,NumPad,Tipus de teclat,Model de teclat,Disposició de teclat,Idioma,Teclat alternatiu,Commutació de teclat,Tecla Ctrl,Bloq Maj,Esperanto,Circumflex,Matar servidor X,LED de teclat,Tecla compose +X-KDE-Keywords[ca@valencia]=Teclat,Repetició de teclat,Volum de clic,Dispositius d'entrada,repetició,volum,BloqNum,NumPad,Tipus de teclat,Model de teclat,Disposició de teclat,Idioma,Teclat alternatiu,Commutació de teclat,Tecla Ctrl,Bloq Maj,Esperanto,Circumflex,Matar servidor X,LED de teclat,Tecla compose +X-KDE-Keywords[da]=Tastatur,keyboard,tastaturgentagelse,klikvolume,inputenheder,gentag,lydstyrke,NumLock,numerisk tastatur,tastaturtype,tastaturmodel,tastaturlayout,tastelayout,sprog,alternativt tastatur,skift af tastatur,Ctrl-tast,lås skift,caps lock,Esperanto,Circumflex,dræb X Server,LED-tastatur,Compose-tast +X-KDE-Keywords[de]=Tastatur,Tastenwiederholung,Klicklautstärke,Eingabegeräte,Wiederholung,Lautstärke,Zahlen-Feststelltaste,Zahlenblock,Tastaturtyp,Tastaturmodell,Tastaturlayout,Tastenlayout,Sprache,Alternative Tastatur,Tastaturwechsel,Tastaturbelegung,Strg-Taste,Umschalttaste,Esperanto,Zirkumflex,X-Server beenden,Tastatur LED,Compose-Taste +X-KDE-Keywords[el]=πληκτρολόγιο,επανάληψη πληκτρολογίου,ένταση κλικ,συσκευές εισόδου,επανάληψη,ένταση,NumLock,αριθμητικό πληκτρολόγιο,τύπος πληκτρολογίου,μοντέλο πληκτρολογίου,διάταξη πληκτρολογίου,γλώσσα,εναλλακτικό πληκτρολόγιο,εναλλαγή πληκτρολογίου,πλήκτρο Ctrl,Caps Lock,Esperanto,Circumflex,Kill X Server,LED πληκτρολόγιο,πλήκτρο σύνθεσης +X-KDE-Keywords[en_GB]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key +X-KDE-Keywords[es]=Teclado,Repetición del teclado,Volumen del clic,Dispositivos de entrada,repetición,volumen,Bloqueo numérico,Teclado numérico,Tipo de teclado,Modelo de teclado,Disposición del teclado,Disposición de las teclas,Idioma,Teclado alternativo,Cambiar de teclado,Tecla Ctrl,Bloqueo de mayúsculas,Esperanto,Circunflejo,Matar el servidor X,LED del teclado,Tecla de composición +X-KDE-Keywords[et]=Klaviatuur,Klaviatuurikordus,Klõpsu helitugevus,Sisendseadmed,kordus,helitugevus,NumLock,NumPad,numbriklahvistik,Klaviatuurimudel,Klaviatuuri mudel,Klaviatuuripaigutus,Klaviatuuri paigutus,Paigutus,Keel,Alternatiivne klaviatuur,Klaviatuuri vahetamine,Ctrl,Caps Lock,Esperanto,Tsirkumfleks,Katus,X-serveri tapmine,LDE-klaviatuur,Muuteklahv +X-KDE-Keywords[eu]=teklatu, teklatuaren errepikapen,klikaren bolumena,sarrerako gailuak,errepikatu,bolumena,BlokZenb,zenbakizko teklatu,teklatu mota,teklatuaren modeloa,teklatu-diseinua,teklen diseinua,hizkuntza, teklatu alternatiboa,teklatua aldatzea,ktrl tekla,BlokMaius,esperanto,zirkunflexua,hil X zerbitzaria,LED teklatua,tekla konposatua +X-KDE-Keywords[fi]=näppäimistö,näppäimistön toisto,näppäilyäänen voimakkuus,syöttölaitteet,toisto,numlock,numerolukko,numpad,numeronäppäimistö,näppäimistön tyyppi,näppäimistön malli,näppäimistöasettelu,näppäinasettelu,kieli,vaihtoehtoinen näppäimistö,näppäimistön vaihto,näppäimistön vaihtaminen,Ctrl-näppäin,caps lock,Esperanto,tapa X-palvelin,LED-näppäimistö,compose-näppäin +X-KDE-Keywords[fr]=Clavier, Répétition du clavier, Volume du clic, Périphériques d'entrée, répétition, volume, Verrouillage numérique, Pavé numérique, Type de clavier, Modèle de clavier, Disposition du clavier, Disposition des touches, Langue, Clavier alternatif, Changement de clavier, Touche Ctrl, Verrouillage des majuscule, Espéranto, Circonflexe, Tuer le serveur X, Voyants du clavier, Touche de composition +X-KDE-Keywords[gl]=teclado, repetición de teclas, volume do clic, dispositivo de entrada, repetición, volume, Bloq núm, Bloq num, tipo de teclado, modelo, disposición idioma, teclado alternativo, troco de teclado, Ctrl, Bloq maiús, til, circunflexo, matar o servidor X, LED +X-KDE-Keywords[hu]=Billentyűzet,Billentyűzet ismétlés,Kattintási hangerő,Beviteli eszközök,ismétlés,hangerő,NumLock,Numerikus billentyűzet,Billentyűzet típus,Billentyűzet modell,Billentyűzetkiosztás,Nyelv,Alternatív billentyűzet,Billentyűzetváltó,Ctrl billentyű,Caps Lock,Eszperantó,Ékezet,X kiszolgáló kilövése,LED billentyűzet,Levélírás billentyű +X-KDE-Keywords[ia]=Claviero,Repetition de claviero,Volumine de click,Dispositivos de ingresso,volumine, NumLock,Typo de claviero,modello de Claviero,disposition de claviero, Disposition de clave, Linguage,Claviero alternate,commutation de claviero,Clave Ctrl,Caps Lock,Esperanto, Circumflexe,Occide X Server, Claviero LED, Clave composite +X-KDE-Keywords[it]=tastiera,ripetizione tastiera,clic volume,dispositivi di ingresso,ripetizione,volume,bloc num,tastierino numerico,tipo tastiera, modello tastiera,mappatura tastiera,mappatura tasto,lingua,tastiera alternativa,cambio tastiera, tasto ctrl,maiusc,esperanto,circonflesso,uccidi server x,led tastiera,tasto composizione +X-KDE-Keywords[kk]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key +X-KDE-Keywords[km]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key +X-KDE-Keywords[ko]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,키보드,키보드 반복,입력 장치, 숫자패드,키보드 종류,레이아웃,입력,언어 +X-KDE-Keywords[mr]=की-बोर्ड,की-बोर्ड रिपीट, क्लिक व्हॉल्यूम, इनपुट डिव्हाइस, रिपीट, व्हॉल्यूम,न्यूम.लॉक,न्यूम.पॅड,की-बोर्ड टाईप, की-बोर्ड मॉडेल, की-बोर्ड लेआउट, कि लेआउट, कि लेआउट, भाषा, वैकल्पिक की-बोर्ड,की-बोर्ड स्विचिंग,सी.टी.आर.एल.की, कॅप्स लॉक, एस्परांटो,सर्कम्फलेकस,किल एक्स सर्व्हर, एल.इ.डी की बोर्ड, कंपोज की +X-KDE-Keywords[nb]=Tastatur,Tasterepetisjon,Klikklydstyrke,Inndataenheter,repeter,lydstyrke,NumLock,NumPad.Tastaturtype,Tastaturmodell,Tastaturutforming,Tateutlegg,Språk,Alternativt tastatur,Tastaturbytte,CTRL-tast,Caps Lock,Esperanto,circumflex,Drep X-tjener,LED-tastatur,Sammensett-tast +X-KDE-Keywords[nds]=Tastatuur,Tastwedderhalen,Tastluutstärk,Ingaavreedschappen, wedderhalen,Luutstärk,NumLock,TallenRast,Tallenblock,Tastatuurtyp,Tastatuurmodell,Tasttoornen,Layout,Spraak,Anner Tastatuur,Tastatuurwesseln,Ctrl,Strg,GrootschrRast, Grootschriev-Rast,Caps Lock,capslock,butenlannsch,Bookstaven,Akzent,Sünnertekens,X-Server afscheten +X-KDE-Keywords[nl]=Toetsenbord,Toetsenbordherhaling,Klikvolume,Invoerapparaten,herhaling,volume,NumLock,NumPad,Type toetsenbord,Model toetsenbord,Toetsenbordindeling,Toetsenindeling,Taal,Toetsenbord alterneren,Toetsenbord omschakelen,Ctrl-toets,Caps Lock,Esperanto,Circumflex,Kill X Server,LED-toetsenbord,Compositietoets +X-KDE-Keywords[pl]=Klawiatura,Powtórzenia klawiatury,Głośność kliknięcia,Urządzenia wejścia,powtórzenie,głośność +X-KDE-Keywords[pt]=Teclado,repetição do teclado,volume do 'click',dispositivos de entrada,repetição,volume,NumLock,NumPad,Tipo de teclado,Modelo de teclado,Disposição do teclado,Disposição das teclas,Língua,Teclado alternativo,Mudança de teclado,Ctrl,Caps Lock,Esperanto,Circunflexo,Matar o Servidor X,LED do Teclado,Tecla Compose +X-KDE-Keywords[pt_BR]=Teclado,repetição do teclado,volume do clique,dispositivos de entrada,repetição,volume,NumLock,NumPad,Tipo de teclado,Modelo de teclado,Leiaute do teclado,Leiaute das teclas,Idioma,Teclado alternativo,Mudança de teclado,Tecla Ctrl,Caps Lock,Esperanto,Circunflexo,Finalizar o servidor X,LED do teclado,Tecla Compose +X-KDE-Keywords[ru]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,клавиатура,повтор клавиши,громкость щелчка,громкость клика,устройство ввода,повтор,громкость,цифровая клавиатура,тип клавиатуры,модель клавиатуры,раскладка клавиатуры,расположение клавиш,язык,альтернативная клавиатура,переключение клавиатуры +X-KDE-Keywords[sk]=Klávesnica,opakovanie klávesnice,hlasitosť kliknutia,vstupné zariadenia,opakovanie, halsitosť,NumLock, NumPad,typ klávesnice,model klávesnice,rozloženie klávesnice,rozloženie kláves,jazyk, alternatívna klávesnica,prepínanie klávesnice,Ctrl,Caps Lock,Esperanto, Circumflex,zabiť X server,LED klávesnica,zložená klávesa +X-KDE-Keywords[sl]=tipkovnica,ponavljanje tipkovnice,tipkovno ponavljanje,glasnost klika,vhodne naprave,ponavljanje,glasnost,numlock,številčnica,vrsta tipkovnice,model tipkovnice,razporeditev tipk,razporeditev tipkovnice,jezik,nadomestna tipkovnica,alternativna tipkovnica,preklapljanje tipkovnice,ctrl,tipka ctrl,capslock,esperanto,cirkumfleks,končaj strežnik x,led,lučke,tipka za sestavljanje +X-KDE-Keywords[sr]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,тастатура,понављање тастатуре,јачина клика,улазни уређаји,понављање,јачина,NumLock,нумеричка тастатура,тип тастатуре,модел тастатуре,распоред тастатуре,распоред тастера,језик,алтернативна тастатура,мењач тастатуре,Ctrl,CapsLock,есперанто,циркумфлекс,ЛЕД тастатура,укини икс сервер +X-KDE-Keywords[sr@ijekavian]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,тастатура,понављање тастатуре,јачина клика,улазни уређаји,понављање,јачина,NumLock,нумеричка тастатура,тип тастатуре,модел тастатуре,распоред тастатуре,распоред тастера,језик,алтернативна тастатура,мењач тастатуре,Ctrl,CapsLock,есперанто,циркумфлекс,ЛЕД тастатура,укини икс сервер +X-KDE-Keywords[sr@ijekavianlatin]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,tastatura,ponavljanje tastature,jačina klika,ulazni uređaji,ponavljanje,jačina,NumLock,numerička tastatura,tip tastature,model tastature,raspored tastature,raspored tastera,jezik,alternativna tastatura,menjač tastature,Ctrl,CapsLock,esperanto,cirkumfleks,LED tastatura,ukini X server +X-KDE-Keywords[sr@latin]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,tastatura,ponavljanje tastature,jačina klika,ulazni uređaji,ponavljanje,jačina,NumLock,numerička tastatura,tip tastature,model tastature,raspored tastature,raspored tastera,jezik,alternativna tastatura,menjač tastature,Ctrl,CapsLock,esperanto,cirkumfleks,LED tastatura,ukini X server +X-KDE-Keywords[sv]=Tangentbord,Tangentbordsupprepning,Klickvolym,Indataenheter,upprepa,volym,NumLock,Numeriskt tangentbord,Tangentbordstyp,Tangentbordsmodell,Tangentbordslayout,Språk,Alternativt tangentbord,Tangentbordsbyte,Ctrl-tangent,Caps Lock,Esperanto,Circumflex,Döda X-server,LED-tangentbord,Compose-tangent +X-KDE-Keywords[tr]=Klavye,Klavye tekrarlaması,Tıklama sesi,Girdi Aygıtları,tekrarla,ses,NumLock,Sayısal Tuşlar,Klavye tipi,Klavye modeli,Klavye düzeni,Tuş düzeni,Dil,Klavyeyi Değiştir,Klavye Seçimi,Ctrl Tuşu,Caps Lock,Esperanto,İnceltme İşareti,X Sunucuyu Sonlandır,LED Klavye,Tuş Düzeni Oluştur +X-KDE-Keywords[uk]=клавіатура,повторення натискань,гучність клацання,пристрої введення,повторення,гучність,тип клавіатури,розкладка клавіатури,мова,інша клавіатура,інша розкладка,перемикання розкладок,клавіша Ctrl,есперанто,циркумфлекс,лампочки на клавіатурі,клавіша перемикання,Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key +X-KDE-Keywords[vi]=Bàn phím, lặp bàn phím, âm lượng nhấn nút,thiết bị nhập,lặp lại,âm lượng,NumLock,NumPad, kiểu bàn phím,mẫu bàn phím,loại bàn phím, bố trí phím,ngôn ngữ,bàn phím thay thế,chuyển đổi bàn phím,phím Ctrl,Caps Lock, Esperanto,Circumflex,tắt máy chủ X,bàn phím LED,phím tổ hợp +X-KDE-Keywords[x-test]=xxKeyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Keyxx +X-KDE-Keywords[zh_CN]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key,键盘,键盘重复,按键音量,输入设备,重复,音量,数字锁定,数字键盘,小键盘,键盘类型,键盘模型,键盘布局,按键布局,语言,额外键盘,键盘切换,Ctrl 键,大写锁定,杀死 X 服务器,LED 键盘灯,Compose 键,死键 +X-KDE-Keywords[zh_TW]=Keyboard,Keyboard repeat,Click volume,Input Devices,repeat,volume,NumLock,NumPad,Keyboard type,Keyboard model,Keyboard layout,Key layout,Language,Alternate Keyboard,Keyboard switching,Ctrl Key,Caps Lock,Esperanto,Circumflex,Kill X Server,LED Keyboard,Compose Key diff --git a/kcontrol/keyboard/kcm_keyboard.h b/kcontrol/keyboard/kcm_keyboard.h new file mode 100644 index 00000000..c88fe3dd --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KCM_KEYBOARD_H_ +#define KCM_KEYBOARD_H_ + +#include + +class KCMKeyboardWidget; +class KeyboardConfig; +class Rules; + +class KCMKeyboard: public KCModule +{ +Q_OBJECT + +public: + KCMKeyboard(QWidget *parent, const QVariantList &); + virtual ~KCMKeyboard(); + + void save(); + void load(); + void defaults(); + +private: + Rules* rules; + KeyboardConfig* keyboardConfig; + KCMKeyboardWidget *widget; +}; + +#endif /* KCM_KEYBOARD_H_ */ diff --git a/kcontrol/keyboard/kcm_keyboard.ui b/kcontrol/keyboard/kcm_keyboard.ui new file mode 100644 index 00000000..f64eeea4 --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard.ui @@ -0,0 +1,478 @@ + + + TabWidget + + + + 0 + 0 + 677 + 485 + + + + 1 + + + + Hardware + + + + + + + 1 + 0 + + + + Keyboard &model: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + keyboardModelComboBox + + + + + + + + 2 + 0 + + + + Here you can choose a keyboard model. This setting is independent of your keyboard layout and refers to the "hardware" model, i.e. the way your keyboard is manufactured. Modern keyboards that come with your computer usually have two extra keys and are referred to as "104-key" models, which is probably what you want if you do not know what kind of keyboard you have. + + + + 15 + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + + 1 + 1 + + + + + 0 + 100 + + + + + 0 + 0 + + + + + 0 + + + + + + + + + Layouts + + + + + + + + Layout Indicator + + + + + + Show layout indicator + + + + + + + Show for single layout + + + + + + + Show flag + + + + + + + Show label + + + + + + + Show label on flag + + + + + + + + + + If you select "Application" or "Window" switching policy, changing the keyboard layout will only affect the current application or window. + + + Switching Policy + + + + + + &Global + + + true + + + + + + + &Desktop + + + + + + + &Application + + + + + + + &Window + + + + + + + + + + Shortcuts for Switching Layout + + + + + + Main shortcuts: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + xkbGrpShortcutBtn + + + + + + + This is a shortcut for switching layouts which is handled by X.org. It allows modifier-only shortcuts. + + + None + + + + + + + ... + + + + + + + 3rd level shortcuts: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + xkb3rdLevelShortcutBtn + + + + + + + This is a shortcut for switching to a third level of the active layout (if it has one) which is handled by X.org. It allows modifier-only shortcuts. + + + None + + + + + + + ... + + + + + + + Alternative shortcut: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kdeKeySequence + + + + + + + This is a shortcut for switching layouts which is handled by KDE. It does not support modifier-only shortcuts and also may not work in some situations (e.g. if popup is active or from screensaver). + + + false + + + + + + + + + + + + true + + + Configure layouts + + + false + + + true + + + + + + + + Add + + + + + + + false + + + Remove + + + + + + + false + + + Move Up + + + + + + + false + + + Move Down + + + + + + + false + + + Preview + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QAbstractItemView::SelectRows + + + false + + + false + + + + + + + Spare layouts + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 15 + 20 + + + + + + + + + + + true + + + + + + Main layout count: + + + + + + + + + + Qt::Horizontal + + + + 431 + 20 + + + + + + + + + + + + + + + Advanced + + + + + + &Configure keyboard options + + + + + + + false + + + QAbstractItemView::NoSelection + + + true + + + + + + + + + KButtonGroup + QGroupBox +
    kbuttongroup.h
    + 1 +
    + + KKeySequenceWidget + QWidget +
    kkeysequencewidget.h
    +
    +
    + + + + changed(bool) + +
    diff --git a/kcontrol/keyboard/kcm_keyboard_widget.cpp b/kcontrol/keyboard/kcm_keyboard_widget.cpp new file mode 100644 index 00000000..c9a69103 --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard_widget.cpp @@ -0,0 +1,691 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcm_keyboard_widget.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "keyboard_config.h" +#include "preview/keyboardpainter.h" +#include "xkb_rules.h" +#include "flags.h" +#include "x11_helper.h" +#include "kcm_view_models.h" +#include "kcm_add_layout_dialog.h" +#include "bindings.h" + +#include "kcmmisc.h" + +#include "ui_kcm_add_layout_dialog.h" + + +static const QString GROUP_SWITCH_GROUP_NAME("grp"); +static const QString LV3_SWITCH_GROUP_NAME("lv3"); +//static const QString RESET_XKB_OPTIONS("-option"); + +static const int TAB_HARDWARE = 0; +static const int TAB_LAYOUTS = 1; +static const int TAB_ADVANCED = 2; + +static const int MIN_LOOPING_COUNT = 2; + + +KCMKeyboardWidget::KCMKeyboardWidget(Rules* rules_, KeyboardConfig* keyboardConfig_, + const KComponentData componentData_, const QVariantList &args, QWidget* /*parent*/): + rules(rules_), + componentData(componentData_), + actionCollection(NULL), + uiUpdating(false) +{ + flags = new Flags(); + keyboardConfig = keyboardConfig_; + + uiWidget = new Ui::TabWidget; + uiWidget->setupUi(this); + + kcmMiscWidget = new KCMiscKeyboardWidget(uiWidget->lowerHardwareWidget); + uiWidget->lowerHardwareWidget->layout()->addWidget( kcmMiscWidget ); + connect(kcmMiscWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + + if( rules != NULL ) { + initializeKeyboardModelUI(); + initializeXkbOptionsUI(); + initializeLayoutsUI(); + } + else { + uiWidget->tabLayouts->setEnabled(false); + uiWidget->tabAdvanced->setEnabled(false); + uiWidget->keyboardModelComboBox->setEnabled(false); + } + + handleParameters(args); +} + +KCMKeyboardWidget::~KCMKeyboardWidget() +{ + delete flags; +} + +void KCMKeyboardWidget::handleParameters(const QVariantList &args) +{ + // TODO: improve parameter handling + setCurrentIndex(TAB_HARDWARE); + foreach(const QVariant& arg, args) { + if( arg.type() == QVariant::String ) { + QString str = arg.toString(); + if( str == "--tab=layouts" ) { + setCurrentIndex(TAB_LAYOUTS); + } + else if( str == "--tab=advanced" ) { + setCurrentIndex(TAB_ADVANCED); + } + } + } +} + +void KCMKeyboardWidget::save() +{ + if( rules == NULL ) + return; + + if( actionCollection != NULL ) { + actionCollection->resetLayoutShortcuts(); + actionCollection->clear(); + delete actionCollection; + } + actionCollection = new KeyboardLayoutActionCollection(this, true); + actionCollection->setToggleShortcut(uiWidget->kdeKeySequence->keySequence()); + actionCollection->setLayoutShortcuts(keyboardConfig->layouts, rules); + + //TODO: skip if no change in shortcuts? + KGlobalSettings::emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_SHORTCUTS); +} + +void KCMKeyboardWidget::updateUI() +{ + if( rules == NULL ) + return; + + uiWidget->layoutsTableView->setModel(uiWidget->layoutsTableView->model()); + layoutsTableModel->refresh(); + uiWidget->layoutsTableView->resizeRowsToContents(); + + uiUpdating = true; + updateHardwareUI(); + updateXkbOptionsUI(); + updateSwitcingPolicyUI(); + updateLayoutsUI(); + updateShortcutsUI(); + uiUpdating = false; +} + +void KCMKeyboardWidget::uiChanged() +{ + if( rules == NULL ) + return; + + ((LayoutsTableModel*)uiWidget->layoutsTableView->model())->refresh(); +// this collapses the tree so use more fine-grained updates +// ((LayoutsTableModel*)uiWidget->xkbOptionsTreeView->model())->refresh(); + + if( uiUpdating ) + return; + + keyboardConfig->showIndicator = uiWidget->showIndicatorChk->isChecked(); + keyboardConfig->showSingle = uiWidget->showSingleChk->isChecked(); + + keyboardConfig->configureLayouts = uiWidget->layoutsGroupBox->isChecked(); + keyboardConfig->keyboardModel = uiWidget->keyboardModelComboBox->itemData(uiWidget->keyboardModelComboBox->currentIndex()).toString(); + + if( uiWidget->showFlagRadioBtn->isChecked() ) { + keyboardConfig->indicatorType = KeyboardConfig::SHOW_FLAG; + } + else + if( uiWidget->showLabelRadioBtn->isChecked() ) { + keyboardConfig->indicatorType = KeyboardConfig::SHOW_LABEL; + } + else { +// if( uiWidget->showFlagRadioBtn->isChecked() ) { + keyboardConfig->indicatorType = KeyboardConfig::SHOW_LABEL_ON_FLAG; + } + + keyboardConfig->resetOldXkbOptions = uiWidget->configureKeyboardOptionsChk->isChecked(); + + if( uiWidget->switchByDesktopRadioBtn->isChecked() ) { + keyboardConfig->switchingPolicy = KeyboardConfig::SWITCH_POLICY_DESKTOP; + } + else + if( uiWidget->switchByApplicationRadioBtn->isChecked() ) { + keyboardConfig->switchingPolicy = KeyboardConfig::SWITCH_POLICY_APPLICATION; + } + else + if( uiWidget->switchByWindowRadioBtn->isChecked() ) { + keyboardConfig->switchingPolicy = KeyboardConfig::SWITCH_POLICY_WINDOW; + } + else { + keyboardConfig->switchingPolicy = KeyboardConfig::SWITCH_POLICY_GLOBAL; + } + + updateXkbShortcutsButtons(); + + updateLoopCount(); + int loop = uiWidget->layoutLoopCountSpinBox->text().isEmpty() + ? KeyboardConfig::NO_LOOPING + : uiWidget->layoutLoopCountSpinBox->value(); + keyboardConfig->layoutLoopCount = loop; + + layoutsTableModel->refresh(); + + emit changed(true); +} + +void KCMKeyboardWidget::initializeKeyboardModelUI() +{ + foreach(ModelInfo* modelInfo, rules->modelInfos) { + QString vendor = modelInfo->vendor; + if( vendor.isEmpty() ) { + vendor = i18nc("unknown keyboard model vendor", "Unknown"); + } + uiWidget->keyboardModelComboBox->addItem(i18nc("vendor | keyboard model", "%1 | %2", vendor, modelInfo->description), modelInfo->name); + } + uiWidget->keyboardModelComboBox->model()->sort(0); + connect(uiWidget->keyboardModelComboBox, SIGNAL(activated(int)), this, SLOT(uiChanged())); +} + +void KCMKeyboardWidget::addLayout() +{ + if( keyboardConfig->layouts.count() >= X11Helper::ARTIFICIAL_GROUP_LIMIT_COUNT ) { // artificial limit now + QMessageBox msgBox; + msgBox.setText(i18np("Only up to %1 keyboard layout is supported", "Only up to %1 keyboard layouts are supported", X11Helper::ARTIFICIAL_GROUP_LIMIT_COUNT)); + // more information https://bugs.freedesktop.org/show_bug.cgi?id=19501 + msgBox.exec(); + return; + } + + AddLayoutDialog dialog(rules, keyboardConfig->isFlagShown() ? flags : NULL, keyboardConfig->isLabelShown(), this); + dialog.setModal(true); + if( dialog.exec() == QDialog::Accepted ) { + keyboardConfig->layouts.append( dialog.getSelectedLayoutUnit() ); + layoutsTableModel->refresh(); + uiWidget->layoutsTableView->resizeRowsToContents(); + uiChanged(); + } + + updateLoopCount(); +} + +static +inline int min(int x, int y) { return x < y ? x : y; } + +void KCMKeyboardWidget::updateLoopCount() +{ + int maxLoop = min(X11Helper::MAX_GROUP_COUNT, keyboardConfig->layouts.count() - 1); + uiWidget->layoutLoopCountSpinBox->setMaximum(maxLoop); + + bool layoutsConfigured = uiWidget->layoutsGroupBox->isChecked(); + + if( maxLoop < MIN_LOOPING_COUNT ) { + uiWidget->layoutLoopingCheckBox->setEnabled(false); + uiWidget->layoutLoopingCheckBox->setChecked(false); + } + else if( maxLoop >= X11Helper::MAX_GROUP_COUNT ) { + uiWidget->layoutLoopingCheckBox->setEnabled(false); + uiWidget->layoutLoopingCheckBox->setChecked(true); + } + else { + uiWidget->layoutLoopingCheckBox->setEnabled(layoutsConfigured); + } + + uiWidget->layoutLoopingGroupBox->setEnabled( + layoutsConfigured && uiWidget->layoutLoopingCheckBox->isChecked()); + + if( uiWidget->layoutLoopingCheckBox->isChecked() ) { + if( uiWidget->layoutLoopCountSpinBox->text().isEmpty() ) { + uiWidget->layoutLoopCountSpinBox->setValue(maxLoop); +// keyboardConfig->layoutLoopCount = maxLoop; + } + } + else { + uiWidget->layoutLoopCountSpinBox->clear(); +// keyboardConfig->layoutLoopCount = KeyboardConfig::NO_LOOPING; + } +} + +void KCMKeyboardWidget::initializeLayoutsUI() +{ + layoutsTableModel = new LayoutsTableModel(rules, flags, keyboardConfig, uiWidget->layoutsTableView); + uiWidget->layoutsTableView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed | QAbstractItemView::AnyKeyPressed); + uiWidget->layoutsTableView->setModel(layoutsTableModel); + uiWidget->layoutsTableView->setIconSize( flags->getTransparentPixmap().size() ); + + //TODO: do we need to delete this delegate or parent will take care of it? + VariantComboDelegate* variantDelegate = new VariantComboDelegate(keyboardConfig, rules, uiWidget->layoutsTableView); + uiWidget->layoutsTableView->setItemDelegateForColumn(LayoutsTableModel::VARIANT_COLUMN, variantDelegate); + + LabelEditDelegate* labelDelegate = new LabelEditDelegate(keyboardConfig, uiWidget->layoutsTableView); + uiWidget->layoutsTableView->setItemDelegateForColumn(LayoutsTableModel::DISPLAY_NAME_COLUMN, labelDelegate); + + KKeySequenceWidgetDelegate* shortcutDelegate = new KKeySequenceWidgetDelegate(keyboardConfig, uiWidget->layoutsTableView); + uiWidget->layoutsTableView->setItemDelegateForColumn(LayoutsTableModel::SHORTCUT_COLUMN, shortcutDelegate); + + //TODO: is it ok to hardcode sizes? any better approach? + uiWidget->layoutsTableView->setColumnWidth(LayoutsTableModel::MAP_COLUMN, 70); + uiWidget->layoutsTableView->setColumnWidth(LayoutsTableModel::LAYOUT_COLUMN, 200); + uiWidget->layoutsTableView->setColumnWidth(LayoutsTableModel::VARIANT_COLUMN, 200); + uiWidget->layoutsTableView->setColumnWidth(LayoutsTableModel::DISPLAY_NAME_COLUMN, 50); + uiWidget->layoutsTableView->setColumnWidth(LayoutsTableModel::SHORTCUT_COLUMN, 130); + + connect(layoutsTableModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(uiChanged())); + + uiWidget->layoutLoopCountSpinBox->setMinimum(MIN_LOOPING_COUNT); + +#ifdef DRAG_ENABLED + uiWidget->layoutsTableView->setDragEnabled(true); + uiWidget->layoutsTableView->setAcceptDrops(true); +#endif + + uiWidget->moveUpBtn->setIcon(KIcon("arrow-up")); + uiWidget->moveDownBtn->setIcon(KIcon("arrow-down")); + uiWidget->addLayoutBtn->setIcon(KIcon("list-add")); + uiWidget->removeLayoutBtn->setIcon(KIcon("list-remove")); + + KIcon clearIcon = qApp->isLeftToRight() ? KIcon("edit-clear-locationbar-rtl") : KIcon("edit-clear-locationbar-ltr"); + uiWidget->xkbGrpClearBtn->setIcon(clearIcon); + uiWidget->xkb3rdLevelClearBtn->setIcon(clearIcon); + + KIcon configIcon = KIcon("configure"); + uiWidget->xkbGrpShortcutBtn->setIcon(configIcon); + uiWidget->xkb3rdLevelShortcutBtn->setIcon(configIcon); + + uiWidget->kdeKeySequence->setModifierlessAllowed(false); + + connect(uiWidget->addLayoutBtn, SIGNAL(clicked(bool)), this, SLOT(addLayout())); + connect(uiWidget->removeLayoutBtn, SIGNAL(clicked(bool)), this, SLOT(removeLayout())); +// connect(uiWidget->layoutsTable, SIGNAL(itemSelectionChanged()), this, SLOT(layoutSelectionChanged())); + connect(uiWidget->layoutsTableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(layoutSelectionChanged())); + +// connect(uiWidget->moveUpBtn, SIGNAL(triggered(QAction*)), this, SLOT(moveUp())); +// connect(uiWidget->moveDownBtn, SIGNAL(triggered(QAction*)), this, SLOT(moveDown())); + connect(uiWidget->moveUpBtn, SIGNAL(clicked(bool)), this, SLOT(moveUp())); + connect(uiWidget->moveDownBtn, SIGNAL(clicked(bool)), this, SLOT(moveDown())); + + connect(uiWidget->previewbutton,SIGNAL(clicked(bool)),this,SLOT(previewLayout())); + + connect(uiWidget->xkbGrpClearBtn, SIGNAL(clicked(bool)), this, SLOT(clearGroupShortcuts())); + connect(uiWidget->xkb3rdLevelClearBtn, SIGNAL(clicked(bool)), this, SLOT(clear3rdLevelShortcuts())); + +// connect(uiWidget->xkbGrpClearBtn, SIGNAL(triggered(QAction*)), this, SLOT(uiChanged())); +// connect(uiWidget->xkb3rdLevelClearBtn, SIGNAL(triggered(QAction*)), this, SLOT(uiChanged())); + connect(uiWidget->kdeKeySequence, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(uiChanged())); + connect(uiWidget->switchingPolicyButtonGroup, SIGNAL(clicked(int)), this, SLOT(uiChanged())); + + connect(uiWidget->xkbGrpShortcutBtn, SIGNAL(clicked(bool)), this, SLOT(scrollToGroupShortcut())); + connect(uiWidget->xkb3rdLevelShortcutBtn, SIGNAL(clicked(bool)), this, SLOT(scrollTo3rdLevelShortcut())); + + // connect(uiWidget->configureLayoutsChk, SIGNAL(toggled(bool)), uiWidget->layoutsGroupBox, SLOT(setEnabled(bool))); + connect(uiWidget->layoutsGroupBox, SIGNAL(toggled(bool)), this, SLOT(configureLayoutsChanged())); + + connect(uiWidget->showIndicatorChk, SIGNAL(clicked(bool)), this, SLOT(uiChanged())); + connect(uiWidget->showIndicatorChk, SIGNAL(toggled(bool)), uiWidget->showSingleChk, SLOT(setEnabled(bool))); + connect(uiWidget->showFlagRadioBtn, SIGNAL(clicked(bool)), this, SLOT(uiChanged())); + connect(uiWidget->showLabelRadioBtn, SIGNAL(clicked(bool)), this, SLOT(uiChanged())); + connect(uiWidget->showLabelOnFlagRadioBtn, SIGNAL(clicked(bool)), this, SLOT(uiChanged())); + connect(uiWidget->showSingleChk, SIGNAL(toggled(bool)), this, SLOT(uiChanged())); + + connect(uiWidget->layoutLoopingCheckBox, SIGNAL(clicked(bool)), this, SLOT(uiChanged())); + connect(uiWidget->layoutLoopCountSpinBox, SIGNAL(valueChanged(int)), this, SLOT(uiChanged())); +} + +void KCMKeyboardWidget::previewLayout(){ + QMessageBox q; + QModelIndex index = uiWidget->layoutsTableView->currentIndex() ; + QModelIndex idcountry = index.sibling(index.row(),0) ; + QString country=uiWidget->layoutsTableView->model()->data(idcountry).toString(); + QModelIndex idvariant = index.sibling(index.row(),2) ; + QString variant=uiWidget->layoutsTableView->model()->data(idvariant).toString(); + if(index.row()==-1 || index.column()==-1){ + q.setText(i18n("No layout selected ")); + q.exec(); + } + else{ + KeyboardPainter* layoutPreview = new KeyboardPainter(); + const LayoutInfo* layoutInfo = rules->getLayoutInfo(country); + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + if(variant==variantInfo->description){ + variant=variantInfo->name; + break; + } + } + layoutPreview->generateKeyboardLayout(country,variant); + layoutPreview->exec(); + layoutPreview->setModal(true); + } +} + +void KCMKeyboardWidget::configureLayoutsChanged() +{ + if( uiWidget->layoutsGroupBox->isChecked() && keyboardConfig->layouts.isEmpty() ) { + populateWithCurrentLayouts(); + } + uiChanged(); +} + +static QPair getSelectedRowRange(const QModelIndexList& selected) +{ + if( selected.isEmpty() ) { + return QPair(-1, -1); + } + + QList rows; + foreach(const QModelIndex& index, selected) { + rows << index.row(); + } + qSort(rows); + return QPair(rows[0], rows[rows.size()-1]); +} + +void KCMKeyboardWidget::layoutSelectionChanged() +{ + QModelIndexList selected = uiWidget->layoutsTableView->selectionModel()->selectedIndexes(); + uiWidget->removeLayoutBtn->setEnabled( ! selected.isEmpty() ); + QPair rowsRange( getSelectedRowRange(selected) ); + uiWidget->moveUpBtn->setEnabled( ! selected.isEmpty() && rowsRange.first > 0); + uiWidget->previewbutton->setEnabled(! selected.isEmpty()); + uiWidget->moveDownBtn->setEnabled( ! selected.isEmpty() && rowsRange.second < keyboardConfig->layouts.size()-1 ); +} + +void KCMKeyboardWidget::removeLayout() +{ + if( ! uiWidget->layoutsTableView->selectionModel()->hasSelection() ) + return; + + QModelIndexList selected = uiWidget->layoutsTableView->selectionModel()->selectedIndexes(); + QPair rowsRange( getSelectedRowRange(selected) ); + foreach(const QModelIndex& idx, selected) { + if( idx.column() == 0 ) { + keyboardConfig->layouts.removeAt(rowsRange.first); + } + } + layoutsTableModel->refresh(); + uiChanged(); + + if( keyboardConfig->layouts.size() > 0 ) { + int rowToSelect = rowsRange.first; + if( rowToSelect >= keyboardConfig->layouts.size() ) { + rowToSelect--; + } + + QModelIndex topLeft = layoutsTableModel->index(rowToSelect, 0, QModelIndex()); + QModelIndex bottomRight = layoutsTableModel->index(rowToSelect, layoutsTableModel->columnCount(topLeft)-1, QModelIndex()); + QItemSelection selection(topLeft, bottomRight); + uiWidget->layoutsTableView->selectionModel()->select(selection, QItemSelectionModel::SelectCurrent); + uiWidget->layoutsTableView->setFocus(); + } + + layoutSelectionChanged(); + + updateLoopCount(); +} + +void KCMKeyboardWidget::moveUp() +{ + moveSelectedLayouts(-1); +} + +void KCMKeyboardWidget::moveDown() +{ + moveSelectedLayouts(1); +} + +void KCMKeyboardWidget::moveSelectedLayouts(int shift) +{ + QItemSelectionModel* selectionModel = uiWidget->layoutsTableView->selectionModel(); + if( selectionModel == NULL || !selectionModel->hasSelection() ) + return; + + QModelIndexList selected = selectionModel->selectedRows(); + if( selected.count() < 1 ) + return; + + int newFirstRow = selected[0].row() + shift; + int newLastRow = selected[ selected.size()-1 ].row() + shift; + + if( newFirstRow >= 0 && newLastRow <= keyboardConfig->layouts.size() - 1 ) { + QList selectionRows; + foreach(const QModelIndex& index, selected) { + int newRowIndex = index.row() + shift; + keyboardConfig->layouts.move(index.row(), newRowIndex); + selectionRows << newRowIndex; + } + uiChanged(); + + QItemSelection selection; + foreach(int row, selectionRows) { + QModelIndex topLeft = layoutsTableModel->index(row, 0, QModelIndex()); + QModelIndex bottomRight = layoutsTableModel->index(row, layoutsTableModel->columnCount(topLeft)-1, QModelIndex()); + selection << QItemSelectionRange(topLeft, bottomRight); + } + uiWidget->layoutsTableView->selectionModel()->select(selection, QItemSelectionModel::SelectCurrent); + uiWidget->layoutsTableView->setFocus(); + } +} + +void KCMKeyboardWidget::scrollToGroupShortcut() +{ + this->setCurrentIndex(TAB_ADVANCED); + if( ! uiWidget->configureKeyboardOptionsChk->isChecked() ) { + uiWidget->configureKeyboardOptionsChk->setChecked(true); + } + ((XkbOptionsTreeModel*)uiWidget->xkbOptionsTreeView->model())->gotoGroup(GROUP_SWITCH_GROUP_NAME, uiWidget->xkbOptionsTreeView); +} + +void KCMKeyboardWidget::scrollTo3rdLevelShortcut() +{ + this->setCurrentIndex(TAB_ADVANCED); + if( ! uiWidget->configureKeyboardOptionsChk->isChecked() ) { + uiWidget->configureKeyboardOptionsChk->setChecked(true); + } + ((XkbOptionsTreeModel*)uiWidget->xkbOptionsTreeView->model())->gotoGroup(LV3_SWITCH_GROUP_NAME, uiWidget->xkbOptionsTreeView); +} + +void KCMKeyboardWidget::clearGroupShortcuts() +{ + clearXkbGroup(GROUP_SWITCH_GROUP_NAME); +} + +void KCMKeyboardWidget::clear3rdLevelShortcuts() +{ + clearXkbGroup(LV3_SWITCH_GROUP_NAME); +} + +void KCMKeyboardWidget::clearXkbGroup(const QString& groupName) +{ + for(int ii=keyboardConfig->xkbOptions.count()-1; ii>=0; ii--) { + if( keyboardConfig->xkbOptions[ii].startsWith(groupName + Rules::XKB_OPTION_GROUP_SEPARATOR) ) { + keyboardConfig->xkbOptions.removeAt(ii); + } + } + ((XkbOptionsTreeModel*)uiWidget->xkbOptionsTreeView->model())->reset(); + uiWidget->xkbOptionsTreeView->update(); + updateXkbShortcutsButtons(); + emit changed(true); +} + +static +bool xkbOptionGroupLessThan(const OptionGroupInfo* og1, const OptionGroupInfo* og2) +{ + return og1->description.toLower() < og2->description.toLower(); +} +static +bool xkbOptionLessThan(const OptionInfo* o1, const OptionInfo* o2) +{ + return o1->description.toLower() < o2->description.toLower(); +} + +void KCMKeyboardWidget::initializeXkbOptionsUI() +{ + qSort(rules->optionGroupInfos.begin(), rules->optionGroupInfos.end(), xkbOptionGroupLessThan); + foreach(OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { + qSort(optionGroupInfo->optionInfos.begin(), optionGroupInfo->optionInfos.end(), xkbOptionLessThan); + } + + XkbOptionsTreeModel* model = new XkbOptionsTreeModel(rules, keyboardConfig, uiWidget->xkbOptionsTreeView); + uiWidget->xkbOptionsTreeView->setModel(model); + connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(uiChanged())); + + connect(uiWidget->configureKeyboardOptionsChk, SIGNAL(toggled(bool)), this, SLOT(configureXkbOptionsChanged())); + // connect(uiWidget->configureKeyboardOptionsChk, SIGNAL(toggled(bool)), this, SLOT(uiChanged())); + connect(uiWidget->configureKeyboardOptionsChk, SIGNAL(toggled(bool)), uiWidget->xkbOptionsTreeView, SLOT(setEnabled(bool))); +} + +void KCMKeyboardWidget::configureXkbOptionsChanged() +{ + if( uiWidget->configureKeyboardOptionsChk->isChecked() && keyboardConfig->xkbOptions.isEmpty() ) { + populateWithCurrentXkbOptions(); + } + ((LayoutsTableModel*)uiWidget->xkbOptionsTreeView->model())->refresh(); + uiChanged(); +} + +void KCMKeyboardWidget::updateSwitcingPolicyUI() +{ + switch (keyboardConfig->switchingPolicy){ + case KeyboardConfig::SWITCH_POLICY_DESKTOP: + uiWidget->switchByDesktopRadioBtn->setChecked(true); + break; + case KeyboardConfig::SWITCH_POLICY_APPLICATION: + uiWidget->switchByApplicationRadioBtn->setChecked(true); + break; + case KeyboardConfig::SWITCH_POLICY_WINDOW: + uiWidget->switchByWindowRadioBtn->setChecked(true); + break; + default: + case KeyboardConfig::SWITCH_POLICY_GLOBAL: + uiWidget->switchByGlobalRadioBtn->setChecked(true); + } +} + +void KCMKeyboardWidget::updateXkbShortcutButton(const QString& groupName, QPushButton* button) +{ + QStringList grpOptions; + if( keyboardConfig->resetOldXkbOptions ) { + QRegExp regexp = QRegExp("^" + groupName + Rules::XKB_OPTION_GROUP_SEPARATOR); + grpOptions = keyboardConfig->xkbOptions.filter(regexp); + } + switch( grpOptions.size() ) { + case 0: + button->setText(i18nc("no shortcuts defined", "None")); + break; + case 1: { + const QString& option = grpOptions.first(); + const OptionGroupInfo* optionGroupInfo = rules->getOptionGroupInfo(groupName); + const OptionInfo* optionInfo = optionGroupInfo->getOptionInfo(option); + if( optionInfo == NULL || optionInfo->description == NULL ) { + kError() << "Could not find option info for " << option; + button->setText(grpOptions.first()); + } + else { + button->setText(optionInfo->description); + } + } + break; + default: + button->setText(i18np("%1 shortcut", "%1 shortcuts", grpOptions.size())); + } +} + +void KCMKeyboardWidget::updateXkbShortcutsButtons() +{ + updateXkbShortcutButton(GROUP_SWITCH_GROUP_NAME, uiWidget->xkbGrpShortcutBtn); + updateXkbShortcutButton(LV3_SWITCH_GROUP_NAME, uiWidget->xkb3rdLevelShortcutBtn); +} + +void KCMKeyboardWidget::updateShortcutsUI() +{ + updateXkbShortcutsButtons(); + + delete actionCollection; + actionCollection = new KeyboardLayoutActionCollection(this, true); + KAction* toggleAction = actionCollection->getToggeAction(); + uiWidget->kdeKeySequence->setKeySequence(toggleAction->globalShortcut().primary()); + actionCollection->loadLayoutShortcuts(keyboardConfig->layouts, rules); + layoutsTableModel->refresh(); +} + +void KCMKeyboardWidget::updateXkbOptionsUI() +{ + uiWidget->configureKeyboardOptionsChk->setChecked(keyboardConfig->resetOldXkbOptions); +} + +void KCMKeyboardWidget::updateLayoutsUI() { + uiWidget->layoutsGroupBox->setChecked(keyboardConfig->configureLayouts); + uiWidget->showIndicatorChk->setChecked(keyboardConfig->showIndicator); + uiWidget->showSingleChk->setChecked(keyboardConfig->showSingle); + uiWidget->showFlagRadioBtn->setChecked(keyboardConfig->indicatorType == KeyboardConfig::SHOW_FLAG); + uiWidget->showLabelRadioBtn->setChecked(keyboardConfig->indicatorType == KeyboardConfig::SHOW_LABEL); + uiWidget->showLabelOnFlagRadioBtn->setChecked(keyboardConfig->indicatorType == KeyboardConfig::SHOW_LABEL_ON_FLAG); + + bool loopingOn = keyboardConfig->configureLayouts && keyboardConfig->layoutLoopCount + != KeyboardConfig::NO_LOOPING; + uiWidget->layoutLoopingCheckBox->setChecked(loopingOn); + uiWidget->layoutLoopingGroupBox->setEnabled(loopingOn); + if( loopingOn ) { + uiWidget->layoutLoopCountSpinBox->setValue(keyboardConfig->layoutLoopCount); + } + else { + uiWidget->layoutLoopCountSpinBox->clear(); + } +} + +void KCMKeyboardWidget::updateHardwareUI() +{ + int idx = uiWidget->keyboardModelComboBox->findData(keyboardConfig->keyboardModel); + if( idx != -1 ) { + uiWidget->keyboardModelComboBox->setCurrentIndex(idx); + } +} + +void KCMKeyboardWidget::populateWithCurrentLayouts() +{ + QList layouts = X11Helper::getLayoutsList(); + foreach(LayoutUnit layoutUnit, layouts) { + keyboardConfig->layouts.append(layoutUnit); + } +} + +void KCMKeyboardWidget::populateWithCurrentXkbOptions() +{ + XkbConfig xkbConfig; + if( X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::ALL) ) { + foreach(QString xkbOption, xkbConfig.options) { + keyboardConfig->xkbOptions.append(xkbOption); + } + } +} diff --git a/kcontrol/keyboard/kcm_keyboard_widget.h b/kcontrol/keyboard/kcm_keyboard_widget.h new file mode 100644 index 00000000..58256dfe --- /dev/null +++ b/kcontrol/keyboard/kcm_keyboard_widget.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KCM_KEYBOARD_WIDGET_H_ +#define KCM_KEYBOARD_WIDGET_H_ + +#include "ui_kcm_keyboard.h" + +#include +#include + +class QWidget; +class KeyboardConfig; +class Rules; +class Flags; +class KComponentData; +class QString; +class QPushButton; +class LayoutsTableModel; +class KCMiscKeyboardWidget; +class KeyboardLayoutActionCollection; + +class KCMKeyboardWidget: public QTabWidget +{ + Q_OBJECT + +public: + KCMKeyboardWidget(Rules* rules, KeyboardConfig* keyboardConfig, + const KComponentData componentData, const QVariantList &args, QWidget* parent=0); + virtual ~KCMKeyboardWidget(); + + void updateUI(); + void save(); + + //temp hack + KCMiscKeyboardWidget* getKcmMiscWidget() const { return kcmMiscWidget; } + +Q_SIGNALS: + void changed(bool state); + +private Q_SLOTS: + void addLayout(); + void removeLayout(); + void layoutSelectionChanged(); + void uiChanged(); + void scrollToGroupShortcut(); + void scrollTo3rdLevelShortcut(); + void clearGroupShortcuts(); + void clear3rdLevelShortcuts(); + void updateXkbShortcutsButtons(); + void moveUp(); + void moveDown(); + void configureLayoutsChanged(); + void configureXkbOptionsChanged(); + void previewLayout(); + +private: + Rules *rules; + Flags *flags; + Ui::TabWidget *uiWidget; + KeyboardConfig *keyboardConfig; + const KComponentData componentData; + KeyboardLayoutActionCollection* actionCollection; + LayoutsTableModel* layoutsTableModel; + KCMiscKeyboardWidget* kcmMiscWidget; + bool uiUpdating; + + void initializeLayoutsUI(); + void initializeXkbOptionsUI(); + void initializeKeyboardModelUI(); + void updateHardwareUI(); + void updateLayoutsUI(); + void updateShortcutsUI(); + void updateXkbOptionsUI(); + void updateSwitcingPolicyUI(); + void updateXkbShortcutButton(const QString& groupName, QPushButton* button); + void clearXkbGroup(const QString& groupName); + void moveSelectedLayouts(int shift); + void populateWithCurrentLayouts(); + void populateWithCurrentXkbOptions(); + void updateLoopCount(); + void handleParameters(const QVariantList &args); +}; + + +#endif /* KCM_KEYBOARD_WIDGET_H_ */ diff --git a/kcontrol/keyboard/kcm_view_models.cpp b/kcontrol/keyboard/kcm_view_models.cpp new file mode 100644 index 00000000..c2241940 --- /dev/null +++ b/kcontrol/keyboard/kcm_view_models.cpp @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcm_view_models.h" + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef DRAG_ENABLED +#include +#endif + +#include "keyboard_config.h" +#include "xkb_rules.h" +#include "flags.h" +#include "x11_helper.h" +#include "bindings.h" + +const int LayoutsTableModel::MAP_COLUMN = 0; +const int LayoutsTableModel::LAYOUT_COLUMN = 1; +const int LayoutsTableModel::VARIANT_COLUMN = 2; +const int LayoutsTableModel::DISPLAY_NAME_COLUMN = 3; +const int LayoutsTableModel::SHORTCUT_COLUMN = 4; +static const int COLUMN_COUNT = 5; + +LayoutsTableModel::LayoutsTableModel(Rules* rules_, Flags *flags_, KeyboardConfig* keyboardConfig_, QObject* parent): + QAbstractTableModel(parent), + keyboardConfig(keyboardConfig_), + rules(rules_), + countryFlags(flags_) +{ +} + +void LayoutsTableModel::refresh() +{ + beginResetModel(); + endResetModel(); +} + +int LayoutsTableModel::rowCount(const QModelIndex &/*parent*/) const +{ + return keyboardConfig->layouts.count(); +} + +int LayoutsTableModel::columnCount(const QModelIndex&) const +{ + return COLUMN_COUNT; +} + +Qt::ItemFlags LayoutsTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + if( index.column() == DISPLAY_NAME_COLUMN + || index.column() == VARIANT_COLUMN + || index.column() == SHORTCUT_COLUMN ) { + flags |= Qt::ItemIsEditable; + } + +#ifdef DRAG_ENABLED + flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; +#endif + + return flags; +} + +#ifdef DRAG_ENABLED +QStringList LayoutsTableModel::mimeTypes() const +{ + QStringList types; + types << "application/keyboard-layout-item"; + return types; +} + +QMimeData *LayoutsTableModel::mimeData(const QModelIndexList &indexes) const + { + QMimeData *mimeData = new QMimeData(); + QByteArray encodedData; + + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + QSet rows; + foreach (const QModelIndex& index, indexes) { + if (index.isValid()) { + rows << index.row(); + } + } + foreach (int row, rows) { + stream << row; + } + + mimeData->setData("application/keyboard-layout-item", encodedData); + return mimeData; +} +#endif + +QVariant LayoutsTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= keyboardConfig->layouts.size()) + return QVariant(); + + const LayoutUnit& layoutUnit = keyboardConfig->layouts.at(index.row()); + + if (role == Qt::DecorationRole) { + switch( index.column() ) { + case DISPLAY_NAME_COLUMN: { +// if( keyboardConfig->isFlagShown() ) { + QIcon icon = countryFlags->getIconWithText(layoutUnit, *keyboardConfig); + return icon.isNull() ? countryFlags->getTransparentPixmap() : icon; +// } + } +//TODO: show the cells are editable +// case VARIANT_COLUMN: { +// case DISPLAY_NAME_COLUMN: { +// int sz = 5; +// QPixmap pm = QPixmap(sz, sz+5); +// pm.fill(Qt::transparent); +// QPainter p(&pm); +// QPoint points[] = { QPoint(0, 0), QPoint(0, sz), QPoint(sz, 0) }; +// p.drawPolygon(points, 3); +// return pm; +// } + break; + } + } + else + if( role == Qt::BackgroundRole ) { + if( keyboardConfig->layoutLoopCount != KeyboardConfig::NO_LOOPING + && index.row() >= keyboardConfig->layoutLoopCount ) { + return QBrush(Qt::lightGray); + } + } + else + if (role == Qt::DisplayRole) { + switch( index.column() ) { + case MAP_COLUMN: + return layoutUnit.layout; + break; + case LAYOUT_COLUMN: { + const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutUnit.layout); + return layoutInfo != NULL ? layoutInfo->description : layoutUnit.layout; + } + case VARIANT_COLUMN: { + if( layoutUnit.variant.isEmpty() ) + return QVariant(); + const LayoutInfo* layoutInfo = rules->getLayoutInfo(layoutUnit.layout); + if( layoutInfo == NULL ) + return QVariant(); + const VariantInfo* variantInfo = layoutInfo->getVariantInfo(layoutUnit.variant); + return variantInfo != NULL ? variantInfo->description : layoutUnit.variant; + } + break; + case DISPLAY_NAME_COLUMN: +// if( keyboardConfig->indicatorType == KeyboardConfig::SHOW_LABEL ) { +// return layoutUnit.getDisplayName(); +// } + break; + case SHORTCUT_COLUMN: { + return layoutUnit.getShortcut().toString(); + } + break; + } + } + else if (role==Qt::EditRole ) { + switch( index.column() ) { + case DISPLAY_NAME_COLUMN: + return layoutUnit.getDisplayName(); + break; + case VARIANT_COLUMN: + return layoutUnit.variant; + break; + case SHORTCUT_COLUMN: + return layoutUnit.getShortcut().toString(); + break; + default:; + } + } + else if( role == Qt::TextAlignmentRole ) { + switch( index.column() ) { + case MAP_COLUMN: + case DISPLAY_NAME_COLUMN: + case SHORTCUT_COLUMN: + return Qt::AlignCenter; + break; + default:; + } + } + return QVariant(); +} + +QVariant LayoutsTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + const QString headers[] = {i18nc("layout map name", "Map"), i18n("Layout"), i18n("Variant"), i18n("Label"), i18n("Shortcut")}; + return headers[section]; + } + + return QVariant(); +} + +bool LayoutsTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role != Qt::EditRole + || (index.column() != DISPLAY_NAME_COLUMN && index.column() != VARIANT_COLUMN && index.column() != SHORTCUT_COLUMN) ) + return false; + + if (index.row() >= keyboardConfig->layouts.size()) + return false; + + LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()]; + + switch( index.column() ) { + case DISPLAY_NAME_COLUMN: { + QString displayText = value.toString().left(3); + layoutUnit.setDisplayName(displayText); + countryFlags->clearCache(); // regenerate the label + } + break; + case VARIANT_COLUMN: { + QString variant = value.toString(); + layoutUnit.variant = variant; + } + break; + case SHORTCUT_COLUMN: { + QString shortcut = value.toString(); + layoutUnit.setShortcut(QKeySequence(shortcut)); + } + break; + } + emit dataChanged(index, index); + + return true; +} + +// +// LabelEditDelegate +// +LabelEditDelegate::LabelEditDelegate(const KeyboardConfig* keyboardConfig_, QObject *parent): + QStyledItemDelegate(parent), + keyboardConfig(keyboardConfig_) +{} + +QWidget *LabelEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , + const QModelIndex & index ) const +{ + if( keyboardConfig->indicatorType == KeyboardConfig::SHOW_FLAG ) + return NULL; + + QWidget* widget = QStyledItemDelegate::createEditor(parent, option, index); + QLineEdit* lineEdit = static_cast(widget); + if( lineEdit != NULL ) { + lineEdit->setMaxLength(LayoutUnit::MAX_LABEL_LENGTH); + } + return widget; +} + +//void LabelEditDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const +//{ +// QStyleOptionViewItem option2(option); +//// option2.decorationPosition = QStyleOptionViewItem::Right; +// option2.decorationAlignment = Qt::AlignHCenter | Qt::AlignVCenter; +// QStyledItemDelegate::paint(painter, option2, index); +//} + + +// +// VariantComboDelegate +// +//TODO: reuse this function in kcm_add_layout_dialog.cpp +static void populateComboWithVariants(QComboBox* combo, const QString& layout, const Rules* rules) +{ + combo->clear(); + const LayoutInfo* layoutInfo = rules->getLayoutInfo(layout); + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + combo->addItem(variantInfo->description, variantInfo->name); + } + combo->model()->sort(0); + combo->insertItem(0, i18nc("variant", "Default"), ""); + combo->setCurrentIndex(0); +} + +VariantComboDelegate::VariantComboDelegate(const KeyboardConfig* keyboardConfig_, const Rules* rules_, QObject *parent): + QStyledItemDelegate(parent), + keyboardConfig(keyboardConfig_), + rules(rules_) +{} + +QWidget *VariantComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, + const QModelIndex & index ) const +{ + QComboBox *editor = new QComboBox(parent); + const LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()]; + populateComboWithVariants(editor, layoutUnit.layout, rules); + return editor; +} + +void VariantComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QComboBox *combo = static_cast(editor); + QString variant = index.model()->data(index, Qt::EditRole).toString(); + int itemIndex = combo->findData(variant); + if( itemIndex == -1 ) { + itemIndex = 0; + } + combo->setCurrentIndex(itemIndex); +} + +void VariantComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + QComboBox *combo = static_cast(editor); + QString variant = combo->itemData(combo->currentIndex()).toString(); + model->setData(index, variant, Qt::EditRole); +} + +void VariantComboDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &/* index */) const +{ + editor->setGeometry(option.rect); +} + +// +// KKeySequenceWidgetDelegate +// +KKeySequenceWidgetDelegate::KKeySequenceWidgetDelegate(const KeyboardConfig* keyboardConfig_, QObject *parent): + QStyledItemDelegate(parent), + keyboardConfig(keyboardConfig_) +{} + +QWidget *KKeySequenceWidgetDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & /*option*/, + const QModelIndex & index ) const +{ + itemsBeingEdited.insert(index); + + KKeySequenceWidget *editor = new KKeySequenceWidget(parent); + editor->setFocusPolicy(Qt::StrongFocus); + editor->setModifierlessAllowed(false); + + const LayoutUnit& layoutUnit = keyboardConfig->layouts[index.row()]; + editor->setKeySequence(layoutUnit.getShortcut()); + + editor->captureKeySequence(); + + return editor; +} + +//void KKeySequenceWidgetDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +//{ +// KKeySequenceWidget *kkeysequencewidget = static_cast(editor); +// QString shortcut = index.model()->data(index, Qt::EditRole).toString(); +// kkeysequencewidget->setKeySequence(QKeySequence(shortcut)); +// kkeysequencewidget->captureKeySequence(); +//// kDebug() << "set editor data"; +//} + +void KKeySequenceWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + KKeySequenceWidget *kkeysequencewidget = static_cast(editor); + QString shortcut = kkeysequencewidget->keySequence().toString(); + model->setData(index, shortcut, Qt::EditRole); + itemsBeingEdited.remove(index); +} + +void KKeySequenceWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + if (itemsBeingEdited.contains(index)) { +// StyledBackgroundPainter::drawBackground(painter,option,index); + } + else { + QStyledItemDelegate::paint(painter,option,index); + } +} +// +// Xkb Options Tree View +// + +int XkbOptionsTreeModel::rowCount(const QModelIndex& parent) const { + if( ! parent.isValid() ) + return rules->optionGroupInfos.count(); + if( ! parent.parent().isValid() ) + return rules->optionGroupInfos[parent.row()]->optionInfos.count(); + return 0; +} + +QVariant XkbOptionsTreeModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + int row = index.row(); + + if (role == Qt::DisplayRole) { + if( ! index.parent().isValid() ) { + return rules->optionGroupInfos[row]->description; + } + else { + int groupRow = index.parent().row(); + const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow]; + return xkbGroup->optionInfos[row]->description; + } + } + else if (role==Qt::CheckStateRole ) { + if( index.parent().isValid() ) { + int groupRow = index.parent().row(); + const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow]; + const QString& xkbOptionName = xkbGroup->optionInfos[row]->name; + return keyboardConfig->xkbOptions.indexOf(xkbOptionName) == -1 + ? Qt::Unchecked : Qt::Checked; + } + else { + int groupRow = index.row(); + const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow]; + foreach(const OptionInfo* optionInfo, xkbGroup->optionInfos) { + if( keyboardConfig->xkbOptions.indexOf(optionInfo->name) != -1 ) + return Qt::PartiallyChecked; + } + return Qt::Unchecked; + } + } + return QVariant(); +} + +bool XkbOptionsTreeModel::setData(const QModelIndex & index, const QVariant & value, int role) { + int groupRow = index.parent().row(); + if( groupRow < 0 ) return false; + + const OptionGroupInfo* xkbGroup = rules->optionGroupInfos[groupRow]; + const OptionInfo* option = xkbGroup->optionInfos[index.row()]; + + if( value.toInt() == Qt::Checked ) { + if( xkbGroup->exclusive ) { + // clear if exclusive (TODO: radiobutton) + int idx = keyboardConfig->xkbOptions.indexOf(QRegExp(xkbGroup->name + ".*")); + if( idx >= 0 ) { + for(int i=0; ioptionInfos.count(); i++) + if( xkbGroup->optionInfos[i]->name == keyboardConfig->xkbOptions[idx] ) { + setData(createIndex(i, index.column(), (quint32)index.internalId()-index.row()+i), Qt::Unchecked, role); + break; + } + // m_kxkbConfig->m_options.removeAt(idx); + // idx = m_kxkbConfig->m_options.indexOf(QRegExp(xkbGroupNm+".*")); + } + } + if( keyboardConfig->xkbOptions.indexOf(option->name) < 0 ) { + keyboardConfig->xkbOptions.append(option->name); + } + } + else { + keyboardConfig->xkbOptions.removeAll(option->name); + } + + emit dataChanged(index, index); + emit dataChanged(index.parent(), index.parent()); + return true; +} + +void XkbOptionsTreeModel::gotoGroup(const QString& groupName, QTreeView* view) { + const OptionGroupInfo* optionGroupInfo = rules->getOptionGroupInfo(groupName); + int index = rules->optionGroupInfos.indexOf((OptionGroupInfo*)optionGroupInfo); + if( index != -1 ) { + QModelIndex modelIdx = createIndex(index,0); +// view->selectionModel()->setCurrentIndex(createIndex(index,0), QItemSelectionModel::NoUpdate); + view->setExpanded(modelIdx, true); + view->scrollTo(modelIdx, QAbstractItemView::PositionAtTop); + view->selectionModel()->setCurrentIndex(modelIdx, QItemSelectionModel::Current); + view->setFocus(Qt::OtherFocusReason); + } +// else { +// kDebug() << "can't scroll to group" << group; +// } +} + diff --git a/kcontrol/keyboard/kcm_view_models.h b/kcontrol/keyboard/kcm_view_models.h new file mode 100644 index 00000000..001d3a5a --- /dev/null +++ b/kcontrol/keyboard/kcm_view_models.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KCM_VIEW_MODELS_H_ +#define KCM_VIEW_MODELS_H_ + +#include +#include +#include +#include + +class QTreeView; +class KeyboardConfig; +class Rules; +class Flags; +class KeyboardLayoutActionCollection; + +class LayoutsTableModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + LayoutsTableModel(Rules* rules, Flags *flags, KeyboardConfig* keyboardConfig, QObject *parent = 0); + + int columnCount(const QModelIndex&) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); +#ifdef DRAG_ENABLED + Qt::DropActions supportedDropActions() const { + return Qt::MoveAction; + } + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &indexes) const; +#endif + void refresh(); + + static const int MAP_COLUMN; + static const int LAYOUT_COLUMN; + static const int VARIANT_COLUMN; + static const int DISPLAY_NAME_COLUMN; + static const int SHORTCUT_COLUMN; + + private: + KeyboardConfig* keyboardConfig; + const Rules *rules; + Flags *countryFlags; +}; + +class LabelEditDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit LabelEditDelegate(const KeyboardConfig* keyboardConfig, QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +// void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + const KeyboardConfig* keyboardConfig; +}; + +class VariantComboDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + VariantComboDelegate(const KeyboardConfig* keyboardConfig, const Rules* rules, QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + const KeyboardConfig* keyboardConfig; + const Rules* rules; +}; + +class KKeySequenceWidgetDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + KKeySequenceWidgetDelegate(const KeyboardConfig* keyboardConfig_, QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; +// void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + +private: + const KeyboardConfig* keyboardConfig; + mutable QSet itemsBeingEdited; +}; + + +class XkbOptionsTreeModel: public QAbstractItemModel +{ +public: + XkbOptionsTreeModel(Rules* rules_, KeyboardConfig* keyboardConfig_, QObject *parent) + : QAbstractItemModel(parent), + keyboardConfig(keyboardConfig_), + rules(rules_) { } + + int columnCount(const QModelIndex& /*parent*/) const { return 1; } + int rowCount(const QModelIndex& parent) const; + QModelIndex parent(const QModelIndex& index) const { + if (!index.isValid() ) + return QModelIndex(); + if( index.internalId() < 100 ) + return QModelIndex(); + return createIndex(((index.internalId() - index.row())/100) - 1, index.column()); + } + QModelIndex index(int row, int column, const QModelIndex& parent) const { + if(!parent.isValid()) return createIndex(row, column); + return createIndex(row, column, (100 * (parent.row()+1)) + row); + } + Qt::ItemFlags flags ( const QModelIndex & index ) const { + if( ! index.isValid() ) + return 0; + + if( !index.parent().isValid() ) + return Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + } + + bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); + QVariant data(const QModelIndex& index, int role) const; + void reset() { QAbstractItemModel::reset(); } + void gotoGroup(const QString& group, QTreeView* view); + +private: + KeyboardConfig* keyboardConfig; + Rules *rules; +}; + +#endif /* KCM_VIEW_MODELS_H_ */ diff --git a/kcontrol/keyboard/kcmmisc.cpp b/kcontrol/keyboard/kcmmisc.cpp new file mode 100644 index 00000000..382f026f --- /dev/null +++ b/kcontrol/keyboard/kcmmisc.cpp @@ -0,0 +1,237 @@ +/* + * kcmmisc.cpp + * + * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca + * + * Layout management, cleanups: + * Copyright (c) 1999 Dirk A. Mueller + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kcmmisc.h" +#include "ui_kcmmiscwidget.h" + +#include + +#include +#include +#include + +#include +#include +#include + +#include + + +KCMiscKeyboardWidget::KCMiscKeyboardWidget(QWidget *parent) + : QWidget(parent), + ui(*new Ui_KeyboardConfigWidget) +{ + ui.setupUi(this); + + ui.delay->setRange(100, 5000, 50); + ui.delay->setSliderEnabled(false); + ui.rate->setRange(0.2, 50, 5, false); + + sliderMax = (int)floor (0.5 + 2*(log(5000.0L)-log(100.0L)) / (log(5000.0L)-log(4999.0L))); + ui.delaySlider->setRange(0, sliderMax); + ui.delaySlider->setSingleStep(sliderMax/100); + ui.delaySlider->setPageStep(sliderMax/10); + ui.delaySlider->setTickInterval(sliderMax/10); + + ui.rateSlider->setRange(20, 5000); + ui.rateSlider->setSingleStep(30); + ui.rateSlider->setPageStep(500); + ui.rateSlider->setTickInterval(498); + + connect(ui.keyboardRepeatButtonGroup, SIGNAL(clicked()), this, SLOT(changed())); + connect(ui.keyboardRepeatButtonGroup, SIGNAL(changed(int)), this, SLOT(keyboardRepeatStateChanged(int))); + connect(ui.delay, SIGNAL(valueChanged(int)), this, SLOT(delaySpinboxChanged(int))); + connect(ui.delaySlider, SIGNAL(valueChanged(int)), this, SLOT(delaySliderChanged(int))); + connect(ui.rate, SIGNAL(valueChanged(double)), this, SLOT(rateSpinboxChanged(double))); + connect(ui.rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateSliderChanged(int))); + + connect(ui.click, SIGNAL(valueChanged(int)), this, SLOT(changed())); + connect(ui.numlockButtonGroup, SIGNAL(released(int)), this, SLOT(changed())); + +// Not sure why we need this - if XKB is not found the whole keyboard module won't be compiled +//#if !defined(HAVE_XTEST) && !defined(HAVE_XKB) +// ui.numlockButtonGroup->setDisabled( true ); +//#endif +//#if !defined(HAVE_XKB) && !defined(HAVE_XF86MISC) +// ui.delay->setDisabled( true ); +// ui.rate->setDisabled( true ); +//#endif +} + +KCMiscKeyboardWidget::~KCMiscKeyboardWidget() +{ + delete &ui; +} + +int KCMiscKeyboardWidget::getClick() +{ + return ui.click->value(); +} + +// set the slider and LCD values +void KCMiscKeyboardWidget::setRepeat(TriState keyboardRepeat, int delay_, double rate_) +{ + TriStateHelper::setTriState( ui.keyboardRepeatButtonGroup, keyboardRepeat ); +// ui.repeatBox->setChecked(r == AutoRepeatModeOn); + ui.delay->setValue(delay_); + ui.rate->setValue(rate_); + delaySpinboxChanged(delay_); + rateSpinboxChanged(rate_); +} + +void KCMiscKeyboardWidget::setClickVolume(int v) +{ + ui.click->setValue(v); +} + +TriState TriStateHelper::getTriState(const KButtonGroup* group) +{ + int selected = group->selected(); + return selected < 0 ? STATE_UNCHANGED : getTriState(selected); +} + +void TriStateHelper::setTriState(KButtonGroup* group, TriState state) +{ + group->setSelected( getInt(state) ); +} + +void KCMiscKeyboardWidget::load() +{ + KConfigGroup config(KSharedConfig::openConfig("kcminputrc", KConfig::NoGlobals), "Keyboard"); + + ui.delay->blockSignals(true); + ui.rate->blockSignals(true); + ui.click->blockSignals(true); + + // need to read as string to support old "true/false" parameter + QString key = config.readEntry("KeyboardRepeating", TriStateHelper::getString(STATE_ON)); + if( key == "true" || key == TriStateHelper::getString(STATE_ON)) { + keyboardRepeat = STATE_ON; + } + else if( key == "false" || key == TriStateHelper::getString(STATE_OFF)) { + keyboardRepeat = STATE_OFF; + } + else { + keyboardRepeat = STATE_UNCHANGED; + } + +// keyboardRepeat = (key ? AutoRepeatModeOn : AutoRepeatModeOff); + float delay = config.readEntry( "RepeatDelay", 660 ); + float rate = config.readEntry( "RepeatRate", 25. ); + setRepeat(keyboardRepeat, delay, rate); + + XKeyboardState kbd; + XGetKeyboardControl(QX11Info::display(), &kbd); + + clickVolume = config.readEntry("ClickVolume", kbd.key_click_percent); + setClickVolume(clickVolume); + // setRepeat(kbd.global_auto_repeat, ui.delay->value(), ui.rate->value()); + + numlockState = TriStateHelper::getTriState(config.readEntry( "NumLock", TriStateHelper::getInt(STATE_UNCHANGED) )); + TriStateHelper::setTriState( ui.numlockButtonGroup, numlockState ); + + ui.delay->blockSignals(false); + ui.rate->blockSignals(false); + ui.click->blockSignals(false); +} + +void KCMiscKeyboardWidget::save() +{ + KConfigGroup config(KSharedConfig::openConfig("kcminputrc", KConfig::NoGlobals), "Keyboard"); + + clickVolume = getClick(); + keyboardRepeat = TriStateHelper::getTriState(ui.keyboardRepeatButtonGroup); + numlockState = TriStateHelper::getTriState(ui.numlockButtonGroup); + + config.writeEntry("ClickVolume",clickVolume); + config.writeEntry("KeyboardRepeating", TriStateHelper::getInt(keyboardRepeat)); + config.writeEntry("RepeatRate", ui.rate->value() ); + config.writeEntry("RepeatDelay", ui.delay->value() ); + config.writeEntry("NumLock", TriStateHelper::getInt(numlockState) ); + config.sync(); +} + +void KCMiscKeyboardWidget::defaults() +{ + setClickVolume(50); + setRepeat(STATE_ON, 660, 25); + TriStateHelper::setTriState( ui.numlockButtonGroup, STATE_UNCHANGED ); + emit changed(true); +} + +QString KCMiscKeyboardWidget::quickHelp() const +{ + return QString(); + + /* "

    Keyboard

    This module allows you to choose options" + " for the way in which your keyboard works. The actual effect of" + " setting these options depends upon the features provided by your" + " keyboard hardware and the X server on which KDE is running.

    " + " For example, you may find that changing the key click volume" + " has no effect because this feature is not available on your system." */ +} + +void KCMiscKeyboardWidget::delaySliderChanged (int value) { + double alpha = sliderMax / (log(5000.0L) - log(100.0L)); + double linearValue = exp (value/alpha + log(100.0L)); + + ui.delay->setValue((int)floor(0.5 + linearValue)); + + emit changed(true); +} + +void KCMiscKeyboardWidget::delaySpinboxChanged (int value) { + double alpha = sliderMax / (log(5000.0L) - log(100.0L)); + double logVal = alpha * (log((double)value)-log(100.0L)); + + ui.delaySlider->setValue ((int)floor (0.5 + logVal)); + + emit changed(true); +} + +void KCMiscKeyboardWidget::rateSliderChanged (int value) { + ui.rate->setValue(value/100.0); + + emit changed(true); +} + +void KCMiscKeyboardWidget::rateSpinboxChanged (double value) { + ui.rateSlider->setValue ((int)(value*100)); + + emit changed(true); +} + +void KCMiscKeyboardWidget::changed() +{ + emit changed(true); +} + +void KCMiscKeyboardWidget::keyboardRepeatStateChanged(int selection) +{ + bool enabled = selection == TriStateHelper::getInt(STATE_ON); + ui.keyboardRepeatParamsGroupBox->setEnabled(enabled); + changed(); +} diff --git a/kcontrol/keyboard/kcmmisc.h b/kcontrol/keyboard/kcmmisc.h new file mode 100644 index 00000000..b1c0a535 --- /dev/null +++ b/kcontrol/keyboard/kcmmisc.h @@ -0,0 +1,91 @@ +/* + * keyboard.h + * + * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KCMMISC_H__ +#define __KCMMISC_H__ + +#include +#include + +class Ui_KeyboardConfigWidget; + +enum TriState { + STATE_ON = 0, STATE_OFF = 1, STATE_UNCHANGED = 2 +}; + +class KButtonGroup; +class TriStateHelper { +public: + static void setTriState(KButtonGroup* group, TriState state); + static TriState getTriState(const KButtonGroup* group); + + static TriState getTriState(int state) { return static_cast(state); } + static int getInt(TriState state) { return static_cast(state); } + static const char* getString(TriState state) { + return state == STATE_ON ? "0" : state == STATE_OFF ? "1" : "2"; + } +}; + +class KCMiscKeyboardWidget : public QWidget +{ + Q_OBJECT +public: + KCMiscKeyboardWidget(QWidget *parent); + ~KCMiscKeyboardWidget(); + + void save(); + void load(); + void defaults(); + + QString quickHelp() const; + +private slots: + void changed(); + + void delaySliderChanged (int value); + void delaySpinboxChanged (int value); + void rateSliderChanged (int value); + void rateSpinboxChanged (double value); + void keyboardRepeatStateChanged(int selection); + +Q_SIGNALS: + void changed(bool state); + +private: + void setClickVolume( int ); + void setRepeat( TriState flag, int delay, double rate); + void setRepeatRate( int ); + + int getClick(); + int getRepeatRate(); + + int sliderMax; + int clickVolume; + enum TriState keyboardRepeat; + enum TriState numlockState; + + Ui_KeyboardConfigWidget& ui; +}; + +#endif + diff --git a/kcontrol/keyboard/kcmmiscwidget.ui b/kcontrol/keyboard/kcmmiscwidget.ui new file mode 100644 index 00000000..37fbaf4b --- /dev/null +++ b/kcontrol/keyboard/kcmmiscwidget.ui @@ -0,0 +1,335 @@ + + + KeyboardConfigWidget + + + + 0 + 0 + 577 + 361 + + + + + + + If supported, this option allows you to setup the state of NumLock after KDE startup.<p>You can configure NumLock to be turned on or off, or configure KDE not to set NumLock state. + + + NumLock on KDE Startup + + + + + + true + + + + + + T&urn on + + + + + + + Turn o&ff + + + + + + + Leave unchan&ged + + + + + + + + + + + + + Keyboard Repeat + + + + + + true + + + + + + T&urn on + + + + + + + Turn o&ff + + + + + + + Leave unchan&ged + + + + + + + + + + Qt::Horizontal + + + + 159 + 20 + + + + + + + + + + + false + + + + + + + 0 + 0 + + + + &Delay: + + + delay + + + + + + + If supported, this option allows you to set the delay after which a pressed key will start generating keycodes. The 'Repeat rate' option controls the frequency of these keycodes. + + + 0 + + + 10000 + + + 1000 + + + 1000 + + + 5000 + + + Qt::Horizontal + + + 1000 + + + + + + + If supported, this option allows you to set the delay after which a pressed key will start generating keycodes. The 'Repeat rate' option controls the frequency of these keycodes. + + + ms + + + + + + + + 0 + 0 + + + + &Rate: + + + rate + + + + + + + If supported, this option allows you to set the rate at which keycodes are generated while a key is pressed. + + + 0 + + + 10000 + + + 1000 + + + 1000 + + + 5000 + + + Qt::Horizontal + + + 1000 + + + + + + + If supported, this option allows you to set the rate at which keycodes are generated while a key is pressed. + + + repeats/s + + + + + + + + + + + + + + + + + + Test area: + + + + + + + Allows to test keyboard repeat and click volume (just don't forget to apply the changes). + + + + + + + + + Key Click + + + + + + + + If supported, this option allows you to hear audible clicks from your computer's speakers when you press the keys on your keyboard. This might be useful if your keyboard does not have mechanical keys, or if the sound that the keys make is very soft.<p>You can change the loudness of the key click feedback by dragging the slider button or by clicking the up/down arrows on the spin box. Setting the volume to 0% turns off the key click. + + + Key click &volume: + + + click + + + + + + + 100 + + + 10 + + + Qt::Horizontal + + + QSlider::NoTicks + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + KDoubleNumInput + QWidget +

    knuminput.h
    + 1 + + + KButtonGroup + QGroupBox +
    kbuttongroup.h
    + 1 +
    + + KIntNumInput + QWidget +
    knuminput.h
    + 1 +
    + + + + diff --git a/kcontrol/keyboard/keyboard.desktop b/kcontrol/keyboard/keyboard.desktop new file mode 100644 index 00000000..a2a4654c --- /dev/null +++ b/kcontrol/keyboard/keyboard.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=Service +Icon=preferences-desktop-keyboard +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=keyboard +X-KDE-DBus-ModuleName=keyboard +X-KDE-Kded-autoload=true +X-KDE-Kded-load-on-demand=false +X-KDE-Kded-phase=1 +OnlyShowIn=KDE; + +Name=Keyboard Daemon +Name[ar]=مراقب لوحة المفاتيح +Name[ast]=Degorriu de tecláu +Name[bg]=Демон на клавиатурата +Name[bn]=কীবোর্ড ডীমন +Name[bs]=Demon tastature +Name[ca]=Dimoni del teclat +Name[ca@valencia]=Dimoni del teclat +Name[cs]=Démon klávesnice +Name[da]=Tastatur-dæmon +Name[de]=Tastatur-Dienst +Name[el]=Δαίμονας Πληκτρολογίου +Name[en_GB]=Keyboard Dæmon +Name[es]=Demonio de teclado +Name[et]=Klaviatuurideemon +Name[eu]=Teklatuaren daimona +Name[fi]=Näppäimistötaustaprosessi +Name[fr]=Démon du clavier +Name[ga]=Deamhan Méarchláir +Name[gl]=Daemon do teclado +Name[gu]=કીબોર્ડ ડિમન +Name[he]=תהליך רקע של המקלדת +Name[hi]=कुंजीपट डेमन +Name[hr]=Tipkovnički servis +Name[hu]=Billentyűzetszolgáltatás +Name[ia]=Demone de claviero +Name[id]=Jurik Papan Ketik +Name[is]=Lyklaborðspúki +Name[it]=Demone della tastiera +Name[ja]=キーボードデーモン +Name[kk]=Перенетақта қызметі +Name[km]=ដេមិន​​ក្ដារចុច +Name[kn]=ಕೀಲಿಮಣೆ ನೇಪಥಿಕ +Name[ko]=키보드 데몬 +Name[lt]=Klaviatūros tarnyba +Name[lv]=Tastatūras dēmons +Name[mr]=कळफलक डीमन +Name[nb]=Tastatur-daemon +Name[nds]=Tastatuur-Dämoon +Name[nl]=Toetsenbord-daemon +Name[nn]=Tastaturteneste +Name[pa]=ਕੀ-ਬੋਰਡ ਡੈਮਨ +Name[pl]=Demon klawiatury +Name[pt]=Servidor do Teclado +Name[pt_BR]=Daemon de teclado +Name[ro]=Demon de tastatură +Name[ru]=Фоновая служба клавиатуры +Name[si]=යතුරුපුවරු ඩීමනය +Name[sk]=Démon klávesnice +Name[sl]=Ozadnji program za tipkovnico +Name[sr]=Демон тастатуре +Name[sr@ijekavian]=Демон тастатуре +Name[sr@ijekavianlatin]=Demon tastature +Name[sr@latin]=Demon tastature +Name[sv]=Tangentbordsdemon +Name[th]=ดีมอนแป้นพิมพ์ +Name[tr]=Klavye Servisi +Name[ug]=ھەرپتاختا نازارەتچى +Name[uk]=Фонова служба клавіатури +Name[vi]=Trình nền bàn phím +Name[wa]=Démon del taprece +Name[x-test]=xxKeyboard Daemonxx +Name[zh_CN]=键盘守护进程 +Name[zh_TW]=鍵盤伺服程式 diff --git a/kcontrol/keyboard/keyboard_applet.cpp b/kcontrol/keyboard/keyboard_applet.cpp new file mode 100644 index 00000000..85422d8b --- /dev/null +++ b/kcontrol/keyboard/keyboard_applet.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboard_applet.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "x11_helper.h" +#include "xkb_rules.h" +#include "keyboard_config.h" +#include "keyboard_dbus.h" +#include "layouts_menu.h" +//#include "utils.h" + + +K_EXPORT_PLASMA_APPLET(keyboard, KeyboardApplet) + +KeyboardApplet::KeyboardApplet(QObject *parent, const QVariantList &args): + Plasma::Applet(parent, args), + xEventNotifier(), + rules(Rules::readRules(Rules::READ_EXTRAS)), + keyboardConfig(new KeyboardConfig()), + layoutsMenu(new LayoutsMenu(*keyboardConfig, *rules, flags)) +{ + if( ! X11Helper::xkbSupported(NULL) ) { + setFailedToLaunch(true, i18n("XKB extension failed to initialize")); + return; + } + + m_svg = new Plasma::Svg(this); + m_svg->setImagePath("widgets/labeltexture"); + m_svg->setContainsMultipleImages(true); + resize(48,48); + + setHasConfigurationInterface(false); + + setAspectRatioMode(Plasma::KeepAspectRatio); + //setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + setBackgroundHints(DefaultBackground); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeChanged())); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.connect(QString(), KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE, this, SLOT(configChanged())); +} + +KeyboardApplet::~KeyboardApplet() +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.disconnect(QString(), KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE, this, SLOT(configChanged())); + + delete layoutsMenu; + delete rules; +} + +void KeyboardApplet::keyboardConfigChanged() +{ + readConfig(); + update(); +} + +void KeyboardApplet::readConfig() +{ +// KConfigGroup config = Plasma::Applet::config("KeyboardLayout"); + keyboardConfig->load(); +// drawFlag = keyboardConfig->readEntry("ShowFlag", true); +} + +void KeyboardApplet::configChanged() +{ + Applet::configChanged(); + readConfig(); +} + +void KeyboardApplet::init() +{ + Applet::init(); + + readConfig(); + connect(&xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + connect(&xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged())); + xEventNotifier.start(); + + layoutChanged(); +} + +void KeyboardApplet::destroy() +{ + xEventNotifier.stop(); + disconnect(&xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged())); + disconnect(&xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + Applet::destroy(); +} + +void KeyboardApplet::layoutChanged() +{ + generatePixmap(); + updateTooltip(); + update(); +} + +void KeyboardApplet::updateTooltip() +{ + LayoutUnit layoutUnit = X11Helper::getCurrentLayout(); + if( layoutUnit.isEmpty() ) + return; + + const QIcon icon(getFlag(layoutUnit.layout)); + Plasma::ToolTipContent data(name(), flags.getLongText(layoutUnit, rules), icon); + Plasma::ToolTipManager::self()->setContent(this, data); +} + +const QIcon KeyboardApplet::getFlag(const QString& layout) +{ + return keyboardConfig->isFlagShown() ? flags.getIcon(layout) : QIcon(); +} + +void KeyboardApplet::paintInterface(QPainter *p, const QStyleOptionGraphicsItem */*option*/, const QRect &contentsRect) +{ + LayoutUnit layoutUnit = X11Helper::getCurrentLayout(); + if( layoutUnit.isEmpty() ) + return; + + const QIcon icon(getFlag(layoutUnit.layout)); + if( ! icon.isNull() ) { + p->save(); + p->setRenderHint(QPainter::SmoothPixmapTransform); + p->setRenderHint(QPainter::Antialiasing); + QPixmap pixmap = icon.pixmap(contentsRect.size()); + p->drawPixmap(contentsRect, pixmap); + p->restore(); + } + if( icon.isNull() || keyboardConfig->isLabelShown() ) { + QRect finalRect(m_pixmap.rect()); + finalRect.moveCenter(contentsRect.center()); + p->drawPixmap(finalRect, m_pixmap); + } +} + +void KeyboardApplet::mousePressEvent ( QGraphicsSceneMouseEvent * event ) +{ + if( event->button() == Qt::LeftButton ) { + X11Helper::switchToNextLayout(); + } + event->ignore(); +} + +void KeyboardApplet::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::FormFactorConstraint) { + int iconSize; + if (formFactor() == Plasma::Planar || + formFactor() == Plasma::MediaCenter) { + iconSize = IconSize(KIconLoader::Desktop); + } else { + iconSize = IconSize(KIconLoader::Small); + } + setMinimumSize(iconSize, iconSize); + } + if (constraints & Plasma::SizeConstraint) { + generatePixmap(); + } +} + +void KeyboardApplet::generatePixmap() +{ + LayoutUnit layoutUnit = X11Helper::getCurrentLayout(); + QRect contentsRect = KeyboardApplet::contentsRect().toRect(); + QString shortText = Flags::getShortText(layoutUnit, *keyboardConfig); + + QPixmap pixmap(contentsRect.size()); + pixmap.fill(Qt::transparent); + + QFont font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont); + int height = qMin(contentsRect.height(), contentsRect.width()); + int fontSize = shortText.length() == 2 + ? height * 13 / 15 + : height * 5 / 15; + + int smallestReadableSize = KGlobalSettings::smallestReadableFont().pixelSize(); + if( fontSize < smallestReadableSize ) { + fontSize = smallestReadableSize; + } + font.setPixelSize(fontSize); + if( keyboardConfig->isFlagShown() ) { + m_pixmap = Plasma::PaintUtils::shadowText(shortText, font, Qt::black, Qt::white, QPoint(), 3); + } + else { + m_pixmap = Plasma::PaintUtils::texturedText(shortText, font, m_svg); + } +} + +QList KeyboardApplet::contextualActions() +{ + return layoutsMenu->contextualActions(); +} diff --git a/kcontrol/keyboard/keyboard_applet.h b/kcontrol/keyboard/keyboard_applet.h new file mode 100644 index 00000000..2fb9c98f --- /dev/null +++ b/kcontrol/keyboard/keyboard_applet.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_APPLET_H_ +#define KEYBOARD_APPLET_H_ + +#include + +#include + +#include "x11_helper.h" +#include "flags.h" + +class QGraphicsSceneMouseEvent; +class QAction; +class KConfigDialog; +class QActionGroup; +class Rules; +class KeyboardConfig; +class LayoutsMenu; + +class KeyboardApplet : public Plasma::Applet +{ + Q_OBJECT + +public Q_SLOTS: + void init(); + void destroy(); + +private Q_SLOTS: + void configChanged(); + void layoutChanged(); + +public: + KeyboardApplet(QObject *parent, const QVariantList &args); + virtual ~KeyboardApplet(); + + void constraintsEvent(Plasma::Constraints constraints); + void paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect); + +protected: + void mousePressEvent ( QGraphicsSceneMouseEvent *event ); + QList contextualActions(); + void generatePixmap(); +// void createConfigurationInterface(KConfigDialog *parent); + +private Q_SLOTS: + void keyboardConfigChanged(); + +private: + void readConfig(); + const QIcon getFlag(const QString& layout); + void updateTooltip(); + +// bool drawFlag; + Flags flags; + XEventNotifier xEventNotifier; + const Rules* rules; + KeyboardConfig* keyboardConfig; + LayoutsMenu* layoutsMenu; + Plasma::Svg *m_svg; + QPixmap m_pixmap; +}; + +#endif /* KEYBOARD_APPLET_H_ */ diff --git a/kcontrol/keyboard/keyboard_config.cpp b/kcontrol/keyboard/keyboard_config.cpp new file mode 100644 index 00000000..f3ff97ca --- /dev/null +++ b/kcontrol/keyboard/keyboard_config.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboard_config.h" + +#include +#include +#include + + +static const char* SWITCHING_POLICIES[] = {"Global", "Desktop", "WinClass", "Window", NULL }; +static const char* LIST_SEPARATOR = ","; +//static const char* DEFAULT_LAYOUT = "us"; +static const char* DEFAULT_MODEL = "pc104"; + +static const QString CONFIG_FILENAME("kxkbrc"); +static const QString CONFIG_GROUPNAME("Layout"); + +const int KeyboardConfig::NO_LOOPING = -1; + +KeyboardConfig::KeyboardConfig() +{ + setDefaults(); +} + +QString KeyboardConfig::getSwitchingPolicyString(SwitchingPolicy switchingPolicy) { + return SWITCHING_POLICIES[switchingPolicy]; +} + +static int findStringIndex(const char* strings[], const QString& toFind, int defaultIndex) +{ + for(int i=0; strings[i] != NULL; i++) { + if( toFind == strings[i] ) { + return i; + } + } + return defaultIndex; +} + +void KeyboardConfig::setDefaults() +{ + keyboardModel = DEFAULT_MODEL; + resetOldXkbOptions = false; + xkbOptions.clear(); + + // init layouts options + configureLayouts = false; + layouts.clear(); +// layouts.append(LayoutUnit(DEFAULT_LAYOUT)); + layoutLoopCount = NO_LOOPING; + + // switch cotrol options + switchingPolicy = SWITCH_POLICY_GLOBAL; +// stickySwitching = false; +// stickySwitchingDepth = 2; + + // display options + showIndicator = true; + indicatorType = SHOW_LABEL; + showSingle = false; +} + +static +KeyboardConfig::IndicatorType getIndicatorType(bool showFlag, bool showLabel) +{ + if( showFlag ) { + if( showLabel ) + return KeyboardConfig::SHOW_LABEL_ON_FLAG; + else + return KeyboardConfig::SHOW_FLAG; + } + else { + return KeyboardConfig::SHOW_LABEL; + } +} + + +void KeyboardConfig::load() +{ + KConfigGroup config(KSharedConfig::openConfig( CONFIG_FILENAME, KConfig::NoGlobals ), CONFIG_GROUPNAME); + + keyboardModel = config.readEntry("Model", ""); + + resetOldXkbOptions = config.readEntry("ResetOldOptions", false); + QString options = config.readEntry("Options", ""); + xkbOptions = options.split(LIST_SEPARATOR, QString::SkipEmptyParts); + + configureLayouts = config.readEntry("Use", false); + QString layoutsString = config.readEntry("LayoutList", ""); + QStringList layoutStrings = layoutsString.split(LIST_SEPARATOR, QString::SkipEmptyParts); +// if( layoutStrings.isEmpty() ) { +// layoutStrings.append(DEFAULT_LAYOUT); +// } + layouts.clear(); + foreach(const QString& layoutString, layoutStrings) { + layouts.append(LayoutUnit(layoutString)); + } + if( layouts.isEmpty() ) { + configureLayouts = false; + } + + layoutLoopCount = config.readEntry("LayoutLoopCount", NO_LOOPING); + + QString layoutMode = config.readEntry("SwitchMode", "Global"); + switchingPolicy = static_cast(findStringIndex(SWITCHING_POLICIES, layoutMode, SWITCH_POLICY_GLOBAL)); + + showIndicator = config.readEntry("ShowLayoutIndicator", true); + + bool showFlag = config.readEntry("ShowFlag", false); + bool showLabel = config.readEntry("ShowLabel", true); + indicatorType = getIndicatorType(showFlag, showLabel); + + showSingle = config.readEntry("ShowSingle", false); + + QString labelsStr = config.readEntry("DisplayNames", ""); + QStringList labels = labelsStr.split(LIST_SEPARATOR, QString::KeepEmptyParts); + for(int i=0; i KeyboardConfig::getDefaultLayouts() const +{ + QList defaultLayoutList; + int i = 0; + foreach(const LayoutUnit& layoutUnit, layouts) { + defaultLayoutList.append(layoutUnit); + if( layoutLoopCount != KeyboardConfig::NO_LOOPING && i >= layoutLoopCount-1 ) + break; + i++; + } + return defaultLayoutList; +} + +QList KeyboardConfig::getExtraLayouts() const +{ + if( layoutLoopCount == KeyboardConfig::NO_LOOPING ) + return QList(); + + return layouts.mid(layoutLoopCount, layouts.size()); +} diff --git a/kcontrol/keyboard/keyboard_config.h b/kcontrol/keyboard/keyboard_config.h new file mode 100644 index 00000000..b86418de --- /dev/null +++ b/kcontrol/keyboard/keyboard_config.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_CONFIG_H_ +#define KEYBOARD_CONFIG_H_ + +#include "x11_helper.h" + +#include +#include +#include +#include +#include + +/** + * This class provides configuration options for keyboard module + */ +class KeyboardConfig +{ +public: + static const int MAX_LABEL_LEN = 3; + static const int NO_LOOPING; // = -1; + + enum SwitchingPolicy { + SWITCH_POLICY_GLOBAL = 0, + SWITCH_POLICY_DESKTOP = 1, + SWITCH_POLICY_APPLICATION = 2, + SWITCH_POLICY_WINDOW = 3 + }; + + enum IndicatorType { + SHOW_LABEL = 0, + SHOW_FLAG = 1, + SHOW_LABEL_ON_FLAG = 2 + }; + + QString keyboardModel; + // resetOldXkbOptions is now also "set xkb options" + bool resetOldXkbOptions; + QStringList xkbOptions; + + // init layouts options + bool configureLayouts; + QList layouts; + int layoutLoopCount; + + // switch cotrol options + SwitchingPolicy switchingPolicy; +// bool stickySwitching; +// int stickySwitchingDepth; + + // display options + bool showIndicator; + IndicatorType indicatorType; + bool showSingle; + + KeyboardConfig(); + bool isSpareLayoutsEnabled() const { + return layoutLoopCount != KeyboardConfig::NO_LOOPING; + } + QList getDefaultLayouts() const; + QList getExtraLayouts() const; + bool isFlagShown() const { + return indicatorType == SHOW_FLAG || indicatorType == SHOW_LABEL_ON_FLAG; + } + bool isLabelShown() const { + return indicatorType == SHOW_LABEL || indicatorType == SHOW_LABEL_ON_FLAG; + } + + void setDefaults(); + void load(); + void save(); + + static QString getSwitchingPolicyString(SwitchingPolicy switchingPolicy); +}; + +#endif /* KEYBOARD_CONFIG_H_ */ diff --git a/kcontrol/keyboard/keyboard_daemon.cpp b/kcontrol/keyboard/keyboard_daemon.cpp new file mode 100644 index 00000000..eb9061f3 --- /dev/null +++ b/kcontrol/keyboard/keyboard_daemon.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboard_daemon.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "x11_helper.h" +#include "xinput_helper.h" +#include "xkb_helper.h" +#include "keyboard_dbus.h" +#include "xkb_rules.h" +#include "bindings.h" +#include "keyboard_hardware.h" +#include "layout_tray_icon.h" +#include "layout_memory_persister.h" +#include "layouts_menu.h" + + +K_PLUGIN_FACTORY(KeyboardFactory, registerPlugin();) +K_EXPORT_PLUGIN(KeyboardFactory("keyboard", "kxkb")) + +KeyboardDaemon::KeyboardDaemon(QObject *parent, const QList&) + : KDEDModule(parent), + actionCollection(NULL), + xEventNotifier(NULL), + layoutTrayIcon(NULL), + layoutMemory(keyboardConfig), + rules(Rules::readRules(Rules::READ_EXTRAS)) +{ + if( ! X11Helper::xkbSupported(NULL) ) + return; //TODO: shut down the daemon? + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerService(KEYBOARD_DBUS_SERVICE_NAME); + dbus.registerObject(KEYBOARD_DBUS_OBJECT_PATH, this, QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableSignals); + dbus.connect(QString(), KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE, this, SLOT(configureKeyboard())); + + configureKeyboard(); + registerListeners(); + + LayoutMemoryPersister layoutMemoryPersister(layoutMemory); + if( layoutMemoryPersister.restore(KGlobal::mainComponent().componentName()) ) { + if( layoutMemoryPersister.getGlobalLayout().isValid() ) { + X11Helper::setLayout(layoutMemoryPersister.getGlobalLayout()); + } + } +} + +KeyboardDaemon::~KeyboardDaemon() +{ + LayoutMemoryPersister layoutMemoryPersister(layoutMemory); + layoutMemoryPersister.setGlobalLayout(X11Helper::getCurrentLayout()); + layoutMemoryPersister.save(KGlobal::mainComponent().componentName()); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.disconnect(QString(), KEYBOARD_DBUS_OBJECT_PATH, KEYBOARD_DBUS_SERVICE_NAME, KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE, this, SLOT(configureKeyboard())); + dbus.unregisterObject(KEYBOARD_DBUS_OBJECT_PATH); + dbus.unregisterService(KEYBOARD_DBUS_SERVICE_NAME); + + unregisterListeners(); + unregisterShortcut(); + + delete xEventNotifier; + delete layoutTrayIcon; + delete rules; +} + +void KeyboardDaemon::configureKeyboard() +{ + kDebug() << "Configuring keyboard"; + init_keyboard_hardware(); + + keyboardConfig.load(); + XkbHelper::initializeKeyboardLayouts(keyboardConfig); + layoutMemory.configChanged(); + + setupTrayIcon(); + + unregisterShortcut(); + registerShortcut(); +} + +void KeyboardDaemon::configureMouse() +{ + QStringList modules; + modules << "mouse"; + QProcess::startDetached("kcminit", modules); +} + +void KeyboardDaemon::setupTrayIcon() +{ + bool show = keyboardConfig.showIndicator + && ( keyboardConfig.showSingle || X11Helper::getLayoutsList().size() > 1 ); + + if( show && ! layoutTrayIcon ) { + layoutTrayIcon = new LayoutTrayIcon(rules, keyboardConfig); + } + else if( ! show && layoutTrayIcon ) { + delete layoutTrayIcon; + layoutTrayIcon = NULL; + } +} + +void KeyboardDaemon::registerShortcut() +{ + if( actionCollection == NULL ) { + actionCollection = new KeyboardLayoutActionCollection(this, false); + + KAction* toggleLayoutAction = actionCollection->getToggeAction(); + connect(toggleLayoutAction, SIGNAL(triggered()), this, SLOT(switchToNextLayout())); + actionCollection->loadLayoutShortcuts(keyboardConfig.layouts, rules); + connect(actionCollection, SIGNAL(actionTriggered(QAction*)), this, SLOT(setLayout(QAction*))); + + connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), this, SLOT(globalSettingsChanged(int))); + } +} + +void KeyboardDaemon::unregisterShortcut() +{ + // register KDE keyboard shortcut for switching layouts + if( actionCollection != NULL ) { + disconnect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), this, SLOT(globalSettingsChanged(int))); + + disconnect(actionCollection, SIGNAL(actionTriggered(QAction*)), this, SLOT(setLayout(QAction*))); + disconnect(actionCollection->getToggeAction(), SIGNAL(triggered()), this, SLOT(switchToNextLayout())); + + delete actionCollection; + actionCollection = NULL; + } +} + +void KeyboardDaemon::registerListeners() +{ + if( xEventNotifier == NULL ) { + xEventNotifier = new XInputEventNotifier(); + } + connect(xEventNotifier, SIGNAL(newPointerDevice()), this, SLOT(configureMouse())); + connect(xEventNotifier, SIGNAL(newKeyboardDevice()), this, SLOT(configureKeyboard())); + connect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutMapChanged())); + connect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + xEventNotifier->start(); +} + +void KeyboardDaemon::unregisterListeners() +{ + if( xEventNotifier != NULL ) { + xEventNotifier->stop(); + disconnect(xEventNotifier, SIGNAL(newPointerDevice()), this, SLOT(configureMouse())); + disconnect(xEventNotifier, SIGNAL(newKeyboardDevice()), this, SLOT(configureKeyboard())); + disconnect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + disconnect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutMapChanged())); + } +} + +void KeyboardDaemon::globalSettingsChanged(int category) +{ + if ( category == KGlobalSettings::SETTINGS_SHORTCUTS) { +//TODO: optimize this? seems like we'll get configReload and globalShortcuts from kcm so we'll reconfigure twice + unregisterShortcut(); + registerShortcut(); + } +} + +void KeyboardDaemon::layoutChanged() +{ + //TODO: pass newLayout into layoutTrayIcon? + LayoutUnit newLayout = X11Helper::getCurrentLayout(); + + layoutMemory.layoutChanged(); + if( layoutTrayIcon != NULL ) { + layoutTrayIcon->layoutChanged(); + } + + if( newLayout != currentLayout ) { + currentLayout = newLayout; + emit currentLayoutChanged(newLayout.toString()); + } +} + +void KeyboardDaemon::layoutMapChanged() +{ + keyboardConfig.load(); + layoutMemory.layoutMapChanged(); + emit layoutListChanged(); + if( layoutTrayIcon != NULL ) { + layoutTrayIcon->layoutMapChanged(); + } +} + +void KeyboardDaemon::switchToNextLayout() +{ + kDebug() << "Toggling layout"; + X11Helper::switchToNextLayout(); +} + +bool KeyboardDaemon::setLayout(QAction* action) +{ + if( action == actionCollection->getToggeAction() ) + return false; + + LayoutUnit layoutUnit(action->data().toString()); + return LayoutsMenu::switchToLayout(layoutUnit, keyboardConfig); // need this to be able to switch to spare layouts +// return X11Helper::setLayout(LayoutUnit(action->data().toString())); +} + +bool KeyboardDaemon::setLayout(const QString& layout) +{ + return X11Helper::setLayout(LayoutUnit(layout)); +} + +QString KeyboardDaemon::getCurrentLayout() +{ + return X11Helper::getCurrentLayout().toString(); +} + +QStringList KeyboardDaemon::getLayoutsList() +{ + return X11Helper::getLayoutsListAsString( X11Helper::getLayoutsList() ); +} diff --git a/kcontrol/keyboard/keyboard_daemon.h b/kcontrol/keyboard/keyboard_daemon.h new file mode 100644 index 00000000..5b778663 --- /dev/null +++ b/kcontrol/keyboard/keyboard_daemon.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_DAEMON_H_ +#define KEYBOARD_DAEMON_H_ + +#include +#include + +#include "layout_memory.h" +#include "keyboard_dbus.h" +#include "bindings.h" + + +class KActionCollection; +class XInputEventNotifier; +class LayoutTrayIcon; +class KeyboardConfig; +class KAction; +class Rules; + +class KDE_EXPORT KeyboardDaemon : public KDEDModule +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.KeyboardLayouts") + + KeyboardConfig keyboardConfig; + KeyboardLayoutActionCollection *actionCollection; + XInputEventNotifier* xEventNotifier; + LayoutTrayIcon* layoutTrayIcon; + LayoutMemory layoutMemory; + LayoutUnit currentLayout; + const Rules* rules; + + void registerListeners(); + void registerShortcut(); + void unregisterListeners(); + void unregisterShortcut(); + void setupTrayIcon(); + +private Q_SLOTS: + void switchToNextLayout(); + void globalSettingsChanged(int category); + void configureKeyboard(); + void configureMouse(); + void layoutChanged(); + void layoutMapChanged(); + bool setLayout(QAction* action); + +public Q_SLOTS: + Q_SCRIPTABLE bool setLayout(const QString& layout); + Q_SCRIPTABLE QString getCurrentLayout(); + Q_SCRIPTABLE QStringList getLayoutsList(); + +Q_SIGNALS: + Q_SCRIPTABLE void currentLayoutChanged(QString layout); + Q_SCRIPTABLE void layoutListChanged(); + +public: + KeyboardDaemon(QObject *parent, const QList&); + virtual ~KeyboardDaemon(); +}; + +#endif /* KEYBOARD_DAEMON_H_ */ diff --git a/kcontrol/keyboard/keyboard_dbus.h b/kcontrol/keyboard/keyboard_dbus.h new file mode 100644 index 00000000..4ea39668 --- /dev/null +++ b/kcontrol/keyboard/keyboard_dbus.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_DBUS_H_ +#define KEYBOARD_DBUS_H_ + +#define KEYBOARD_DBUS_SERVICE_NAME "org.kde.keyboard" +#define KEYBOARD_DBUS_OBJECT_PATH "/Layouts" +#define KEYBOARD_DBUS_CONFIG_RELOAD_MESSAGE "reloadConfig" + +#endif /* KEYBOARD_DBUS_H_ */ diff --git a/kcontrol/keyboard/keyboard_hardware.cpp b/kcontrol/keyboard/keyboard_hardware.cpp new file mode 100644 index 00000000..d116eb2a --- /dev/null +++ b/kcontrol/keyboard/keyboard_hardware.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include // WTF? - otherwise compiler complains + +#include + +#include + +#include "x11_helper.h" +#include "kcmmisc.h" + +// from numlockx.c +extern "C" void numlockx_change_numlock_state(Display* dpy, int state); + +#include +#include + + +// This code is taken from xset utility from XFree 4.3 (http://www.xfree86.org/) + +static +void set_repeatrate(int delay, double rate) +{ + if( !X11Helper::xkbSupported(NULL) ) { + kError() << "Failed to set keyboard repeat rate: xkb is not supported"; + return; + } + + XkbDescPtr xkb = XkbAllocKeyboard(); + if (xkb) { + Display* dpy = QX11Info::display(); + int res = XkbGetControls(dpy, XkbRepeatKeysMask, xkb); + xkb->ctrls->repeat_delay = delay; + xkb->ctrls->repeat_interval = (int)floor(1000/rate + 0.5); + res = XkbSetControls(dpy, XkbRepeatKeysMask, xkb); + XkbFreeKeyboard(xkb, 0, true); + return; + } +} + +static +int set_volume(int clickVolumePercent, TriState keyboardRepeatMode) +{ + XKeyboardState kbd; + XKeyboardControl kbdc; + + XGetKeyboardControl(QX11Info::display(), &kbd); + + int flags = 0; + if( clickVolumePercent != -1 ) { + flags |= KBKeyClickPercent; + kbdc.key_click_percent = clickVolumePercent; + } + if( keyboardRepeatMode != STATE_UNCHANGED ) { + flags |= KBAutoRepeatMode; + kbdc.auto_repeat_mode = (keyboardRepeatMode==STATE_ON ? AutoRepeatModeOn : AutoRepeatModeOff); + } + + return XChangeKeyboardControl(QX11Info::display(), flags, &kbdc); +} + +void init_keyboard_hardware() +{ + KConfigGroup config(KSharedConfig::openConfig( "kcminputrc" ), "Keyboard"); + + QString keyRepeatStr = config.readEntry("KeyboardRepeating", TriStateHelper::getString(STATE_ON)); + TriState keyRepeat = STATE_UNCHANGED; + if( keyRepeatStr == "true" || keyRepeatStr == TriStateHelper::getString(STATE_ON) ) { + keyRepeat = STATE_ON; + } + else if( keyRepeatStr == "false" || keyRepeatStr == TriStateHelper::getString(STATE_OFF) ) { + keyRepeat = STATE_OFF; + } + + int clickVolumePercent = config.readEntry("ClickVolume", -1); + if( clickVolumePercent != -1 && keyRepeat != STATE_UNCHANGED ) { + set_volume(clickVolumePercent, keyRepeat); + } + + if( keyRepeat == STATE_ON ) { + int delay_ = config.readEntry("RepeatDelay", 250); + double rate_ = config.readEntry("RepeatRate", 30.); + set_repeatrate(delay_, rate_); + } + + + TriState numlockState = TriStateHelper::getTriState( config.readEntry( "NumLock", TriStateHelper::getInt(STATE_UNCHANGED) ) ); + if( numlockState != STATE_UNCHANGED ) { + numlockx_change_numlock_state(QX11Info::display(), numlockState == STATE_ON ); + } +} diff --git a/kcontrol/keyboard/keyboard_hardware.h b/kcontrol/keyboard/keyboard_hardware.h new file mode 100644 index 00000000..e3daa80b --- /dev/null +++ b/kcontrol/keyboard/keyboard_hardware.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_HARDWARE_H_ +#define KEYBOARD_HARDWARE_H_ + +void init_keyboard_hardware(); + +#endif /* KEYBOARD_HARDWARE_H_ */ diff --git a/kcontrol/keyboard/layout_memory.cpp b/kcontrol/keyboard/layout_memory.cpp new file mode 100644 index 00000000..6940245a --- /dev/null +++ b/kcontrol/keyboard/layout_memory.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "layout_memory.h" + +#include +#include + +#include +#include + +#include "x11_helper.h" +#include "xkb_helper.h" + + +LayoutMemory::LayoutMemory(const KeyboardConfig& keyboardConfig_): + prevLayoutList(X11Helper::getLayoutsList()), + keyboardConfig(keyboardConfig_) +{ + registerListeners(); +} + +LayoutMemory::~LayoutMemory() +{ + unregisterListeners(); +} + +void LayoutMemory::configChanged() +{ +// this->layoutMap.clear(); // if needed this will be done on layoutMapChanged event + unregisterListeners(); + registerListeners(); +} + +void LayoutMemory::registerListeners() +{ + if( keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_WINDOW + || keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_APPLICATION ) { + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(windowChanged(WId))); +// connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId))); + } + if( keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_DESKTOP ) { + connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, SLOT(desktopChanged(int))); + } +} + +void LayoutMemory::unregisterListeners() +{ + disconnect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(windowChanged(WId))); + disconnect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, SLOT(desktopChanged(int))); +// disconnect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId))); +} + +QString LayoutMemory::getCurrentMapKey() { + switch(keyboardConfig.switchingPolicy) { + case KeyboardConfig::SWITCH_POLICY_WINDOW: { + WId wid = KWindowSystem::self()->activeWindow(); + KWindowInfo winInfo = KWindowSystem::windowInfo(wid, NET::WMWindowType); + NET::WindowType windowType = winInfo.windowType( NET::NormalMask | NET::DesktopMask | NET::DialogMask ); + kDebug() << "window type" << windowType; + + // we ignore desktop type so that our keybaord layout applet on desktop could change layout properly + if( windowType == NET::Desktop ) + return previousLayoutMapKey; + if( windowType != NET::Unknown && windowType != NET::Normal && windowType != NET::Dialog ) + return QString(); + + return QString::number(wid); + } + case KeyboardConfig::SWITCH_POLICY_APPLICATION: { + WId wid = KWindowSystem::self()->activeWindow(); + KWindowInfo winInfo = KWindowSystem::windowInfo(wid, NET::WMWindowType, NET::WM2WindowClass); + NET::WindowType windowType = winInfo.windowType( NET::NormalMask | NET::DesktopMask | NET::DialogMask ); + kDebug() << "window type" << windowType; + + // we ignore desktop type so that our keybaord layout applet on desktop could change layout properly + if( windowType == NET::Desktop ) + return previousLayoutMapKey; + if( windowType != NET::Unknown && windowType != NET::Normal && windowType != NET::Dialog ) + return QString(); + + // shall we use pid or window class ??? - class seems better (see e.g. https://bugs.kde.org/show_bug.cgi?id=245507) + // for window class shall we use class.class or class.name? (seem class.class is a bit better - more app-oriented) + kDebug() << "New active window with class.class: " << winInfo.windowClassClass(); + return QString(winInfo.windowClassClass()); +// NETWinInfo winInfoForPid( QX11Info::display(), wid, QX11Info::appRootWindow(), NET::WMPid); +// return QString::number(winInfoForPid.pid()); + } + case KeyboardConfig::SWITCH_POLICY_DESKTOP: + return QString::number(KWindowSystem::self()->currentDesktop()); + default: + return QString(); + } +} + +static +bool isExtraSubset(const QList& allLayouts, const QList& newList) +{ + if( allLayouts.first() != newList.first() ) + return false; + foreach(const LayoutUnit& layoutUnit, newList) { + if( ! allLayouts.contains(layoutUnit) ) + return false; + } + return true; +} + +void LayoutMemory::layoutMapChanged() +{ + QList newLayoutList(X11Helper::getLayoutsList()); + + if( prevLayoutList == newLayoutList ) + return; + + kDebug() << "Layout map change: " << LayoutSet::toString(prevLayoutList) << "-->" << LayoutSet::toString(newLayoutList); + prevLayoutList = newLayoutList; + + //TODO: need more thinking here on how to support external map resetting + if( keyboardConfig.configureLayouts + && keyboardConfig.isSpareLayoutsEnabled() + && isExtraSubset(keyboardConfig.layouts, newLayoutList) ) { + kDebug() << "Layout map change for extra layout"; + layoutChanged(); // to remember new map for active "window" + } + else { +// if( newLayoutList != keyboardConfig.getDefaultLayouts() ) { + // layoutList = newLayoutList; + kDebug() << "Layout map change from external source: clearing layout memory"; + layoutMap.clear(); +// } + } +} + +void LayoutMemory::layoutChanged() +{ + QString layoutMapKey = getCurrentMapKey(); + if( layoutMapKey.isEmpty() ) + return; + + layoutMap[ layoutMapKey ] = X11Helper::getCurrentLayouts(); +} + +void LayoutMemory::setCurrentLayoutFromMap() +{ + QString layoutMapKey = getCurrentMapKey(); + if( layoutMapKey.isEmpty() ) + return; + + if( ! layoutMap.contains(layoutMapKey) ) { +// kDebug() << "new key for layout map" << layoutMapKey; + + if( ! X11Helper::isDefaultLayout() ) { +// kDebug() << "setting default layout for container key" << layoutMapKey; + if( keyboardConfig.configureLayouts && keyboardConfig.isSpareLayoutsEnabled() + && X11Helper::getLayoutsList() != keyboardConfig.getDefaultLayouts() ) { + XkbHelper::initializeKeyboardLayouts(keyboardConfig.getDefaultLayouts()); + } + X11Helper::setDefaultLayout(); + } + } + else { + LayoutSet layoutFromMap = layoutMap[layoutMapKey]; + kDebug() << "Setting layout map item" << layoutFromMap.currentLayout.toString() + << "for container key" << layoutMapKey; + + LayoutSet currentLayouts = X11Helper::getCurrentLayouts(); + if( layoutFromMap.layouts != currentLayouts.layouts ) { + if( keyboardConfig.configureLayouts && keyboardConfig.isSpareLayoutsEnabled() ) { + XkbHelper::initializeKeyboardLayouts(layoutFromMap.layouts); + } + X11Helper::setLayout( layoutFromMap.currentLayout ); + } + else if( layoutFromMap.currentLayout != currentLayouts.currentLayout ) { + X11Helper::setLayout( layoutFromMap.currentLayout ); + } + } + + previousLayoutMapKey = layoutMapKey; +} + +//#include +//#include + +void LayoutMemory::windowChanged(WId /*wId*/) +{ +// KPluginInfo::List plugins = Plasma::Containment::listContainments(); +// foreach(KPluginInfo info, plugins) { +// kDebug() << "applets" << info.name(); +// } + setCurrentLayoutFromMap(); +} + +void LayoutMemory::desktopChanged(int /*desktop*/) +{ + setCurrentLayoutFromMap(); +} diff --git a/kcontrol/keyboard/layout_memory.h b/kcontrol/keyboard/layout_memory.h new file mode 100644 index 00000000..df8568c2 --- /dev/null +++ b/kcontrol/keyboard/layout_memory.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef LAYOUT_MEMORY_H_ +#define LAYOUT_MEMORY_H_ + +#include +#include +#include //For WId + +#include "x11_helper.h" +#include "keyboard_config.h" + +class LayoutMemoryPersister; + +class LayoutMemory : public QObject +{ + Q_OBJECT + + // if there's some transient windows coming up we'll need to either ignore it + // or in case of layout switcher popup menu to apply new layout to previous key + QString previousLayoutMapKey; + QList prevLayoutList; + const KeyboardConfig& keyboardConfig; + + void registerListeners(); + void unregisterListeners(); + QString getCurrentMapKey(); + void setCurrentLayoutFromMap(); + +public Q_SLOTS: + void layoutMapChanged(); + void layoutChanged(); + void windowChanged(WId wId); + void desktopChanged(int desktop); + +public: + LayoutMemory(const KeyboardConfig& keyboardConfig); + virtual ~LayoutMemory(); + + void configChanged(); + +protected: + //QVariant does not support long for WId so we'll use QString for key instead + QMap layoutMap; + + friend class LayoutMemoryPersister; +}; + +#endif /* LAYOUT_MEMORY_H_ */ diff --git a/kcontrol/keyboard/layout_memory_persister.cpp b/kcontrol/keyboard/layout_memory_persister.cpp new file mode 100644 index 00000000..8a6118aa --- /dev/null +++ b/kcontrol/keyboard/layout_memory_persister.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "layout_memory_persister.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "keyboard_config.h" +#include "layout_memory.h" + + +static const char* VERSION = "1.0"; +static const char* DOC_NAME = "LayoutMap"; +static const char* ROOT_NODE = "LayoutMap"; +static const char* VERSION_ATTRIBUTE = "version"; +static const char* SWITCH_MODE_ATTRIBUTE = "SwitchMode"; +static const char* ITEM_NODE = "item"; +static const QString CURRENT_LAYOUT_ATTRIBUTE("currentLayout"); +static const char* OWNER_KEY_ATTRIBUTE = "ownerKey"; +static const char* LAYOUTS_ATTRIBUTE = "layouts"; + +static const char* LIST_SEPARATOR_LM = ","; + +static const char* REL_SESSION_FILE_PATH = "/session/keyboard/layout_memory.xml"; + +QString LayoutMemoryPersister::getLayoutMapAsString() +{ + if( ! canPersist() ) + return ""; + + QDomDocument doc(DOC_NAME); + QDomElement root = doc.createElement(ROOT_NODE); + root.setAttribute(VERSION_ATTRIBUTE, VERSION); + root.setAttribute(SWITCH_MODE_ATTRIBUTE, KeyboardConfig::getSwitchingPolicyString(layoutMemory.keyboardConfig.switchingPolicy)); + doc.appendChild(root); + + if( layoutMemory.keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_GLOBAL ) { + if( ! globalLayout.isValid() ) + return ""; + + QDomElement item = doc.createElement(ITEM_NODE); + item.setAttribute(CURRENT_LAYOUT_ATTRIBUTE, globalLayout.toString()); + root.appendChild(item); + } + else { + foreach(const QString& key , layoutMemory.layoutMap.keys()) { + QDomElement item = doc.createElement(ITEM_NODE); + item.setAttribute(OWNER_KEY_ATTRIBUTE, key); + item.setAttribute(CURRENT_LAYOUT_ATTRIBUTE, layoutMemory.layoutMap[key].currentLayout.toString()); + + QString layoutSetString; + foreach(const LayoutUnit& layoutUnit, layoutMemory.layoutMap[key].layouts) { + if( ! layoutSetString.isEmpty() ) { + layoutSetString += LIST_SEPARATOR_LM; + } + layoutSetString += layoutUnit.toString(); + } + item.setAttribute(LAYOUTS_ATTRIBUTE, layoutSetString); + root.appendChild(item); + } + } + + return doc.toString(); +} + +static bool isRestoreSession() +{ + KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General"); + kDebug() << "loginMode:" << c.readEntry("loginMode"); + QString loginMode = c.readEntry("loginMode"); + return loginMode != "default" && loginMode != "restoreSavedSession"; // we don't know how to restore saved session - only previous one +} + +bool LayoutMemoryPersister::save(const QString& moduleName) +{ + if( isRestoreSession() ) { + QString relPath = moduleName + REL_SESSION_FILE_PATH; + QFile file(KStandardDirs::locateLocal("data", relPath)); + return saveToFile(file); + } + return false; +} + +bool LayoutMemoryPersister::restore(const QString& moduleName) +{ + if( isRestoreSession() ) { + QString relPath = moduleName + REL_SESSION_FILE_PATH; + QFile file(KStandardDirs::locateLocal("data", relPath)); + return restoreFromFile(file); + } + return false; +} + + +bool LayoutMemoryPersister::saveToFile(const QFile& file_) +{ + QString xml = getLayoutMapAsString(); + if( xml.isEmpty() ) + return false; + + QFile file(file_.fileName()); // so we don't expose the file we open/close to the caller + if( ! file.open( QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) ) { + kWarning() << "Failed to open layout memory xml file for writing" << file.fileName(); + return false; + } + + QTextStream out(&file); + out << xml; + out.flush(); + + if( file.error() != QFile::NoError ) { + kWarning() << "Failed to store keyboard layout memory, error" << file.error(); + file.close(); + file.remove(); + return false; + } + else { + kDebug() << "Keyboard layout memory stored into" << file.fileName() << "written" << file.pos(); + return true; + } +} + + +class MapHandler : public QXmlDefaultHandler +{ +public: + MapHandler(const KeyboardConfig::SwitchingPolicy& switchingPolicy_): + verified(false), + switchingPolicy(switchingPolicy_) {} + + bool startElement(const QString &/*namespaceURI*/, const QString &/*localName*/, + const QString &qName, const QXmlAttributes &attributes) { + + if( qName == ROOT_NODE ) { + if( attributes.value(VERSION_ATTRIBUTE) != VERSION ) + return false; + if( attributes.value(SWITCH_MODE_ATTRIBUTE) != KeyboardConfig::getSwitchingPolicyString(switchingPolicy) ) + return false; + + verified = true; + } + if( qName == ITEM_NODE ) { + if( ! verified ) + return false; + + if( switchingPolicy == KeyboardConfig::SWITCH_POLICY_GLOBAL ) { + globalLayout = LayoutUnit(attributes.value(CURRENT_LAYOUT_ATTRIBUTE)); + } + else { + QStringList layoutStrings = attributes.value(LAYOUTS_ATTRIBUTE).split(LIST_SEPARATOR_LM); + LayoutSet layoutSet; + foreach(const QString& layoutString, layoutStrings) { + layoutSet.layouts.append(LayoutUnit(layoutString)); + } + layoutSet.currentLayout = LayoutUnit(attributes.value(CURRENT_LAYOUT_ATTRIBUTE)); + QString ownerKey = attributes.value(OWNER_KEY_ATTRIBUTE); + + if( ownerKey.trimmed().isEmpty() || ! layoutSet.isValid() ) + return false; + + layoutMap[ownerKey] = layoutSet; + } + } + return verified; + } + + bool verified; + QMap layoutMap; + LayoutUnit globalLayout; + +private: + const KeyboardConfig::SwitchingPolicy& switchingPolicy; +}; + +template +static +bool containsAll(QList set1, QList set2) +{ + foreach(const T& t, set2) { + if( ! set1.contains(t) ) + return false; + } + return true; +} + +bool LayoutMemoryPersister::restoreFromFile(const QFile& file_) +{ + globalLayout = LayoutUnit(); + + if( ! canPersist() ) + return false; + + QFile file(file_.fileName()); // so we don't expose the file we open/close to the caller + if( ! file.open( QIODevice::ReadOnly | QIODevice::Text ) ) { + kWarning() << "Failed to open layout memory xml file for reading" << file.fileName() << "error:" << file.error(); + return false; + } + + MapHandler mapHandler(layoutMemory.keyboardConfig.switchingPolicy); + + QXmlSimpleReader reader; + reader.setContentHandler(&mapHandler); + reader.setErrorHandler(&mapHandler); + + QXmlInputSource xmlInputSource(&file); + kDebug() << "Restoring keyboard layout map from" << file.fileName(); + + if( ! reader.parse(xmlInputSource) ) { + kWarning() << "Failed to parse the layout memory file" << file.fileName(); + return false; + } + + if( layoutMemory.keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_GLOBAL ) { + if( mapHandler.globalLayout.isValid() && layoutMemory.keyboardConfig.layouts.contains(mapHandler.globalLayout)) { + globalLayout = mapHandler.globalLayout; + kDebug() << "Restored global layout" << globalLayout.toString(); + } + } + else { + layoutMemory.layoutMap.clear(); + foreach(const QString& key, mapHandler.layoutMap.keys()) { + if( containsAll(layoutMemory.keyboardConfig.layouts, mapHandler.layoutMap[key].layouts) ) { + layoutMemory.layoutMap.insert(key, mapHandler.layoutMap[key]); + } + } + kDebug() << "Restored layouts for" << layoutMemory.layoutMap.size() << "containers"; + } + return true; +} + +bool LayoutMemoryPersister::canPersist() { + // we can't persist per window - as we're using window id which is not preserved between sessions + bool windowMode = layoutMemory.keyboardConfig.switchingPolicy == KeyboardConfig::SWITCH_POLICY_WINDOW; + if( windowMode ) { + kDebug() << "Not saving session for window mode"; + } + return !windowMode; +} diff --git a/kcontrol/keyboard/layout_memory_persister.h b/kcontrol/keyboard/layout_memory_persister.h new file mode 100644 index 00000000..8c4b3c5f --- /dev/null +++ b/kcontrol/keyboard/layout_memory_persister.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef LAYOUT_MEMORY_PERSISTER_H_ +#define LAYOUT_MEMORY_PERSISTER_H_ + +#include + +#include "x11_helper.h" + +class LayoutMemory; +class QFile; + +class LayoutMemoryPersister { +public: + LayoutMemoryPersister(LayoutMemory& layoutMemory_): + layoutMemory(layoutMemory_) {} + + bool saveToFile(const QFile& file); + bool restoreFromFile(const QFile& file); + + bool save(const QString& moduleName); + bool restore(const QString& moduleName); + + LayoutUnit getGlobalLayout() const { return globalLayout; } + void setGlobalLayout(const LayoutUnit& layout) { globalLayout = layout; } + +private: + LayoutMemory& layoutMemory; + LayoutUnit globalLayout; + + QString getLayoutMapAsString(); + + bool canPersist(); +}; + +#endif /* LAYOUT_MEMORY_PERSISTER_H_ */ diff --git a/kcontrol/keyboard/layout_tray_icon.cpp b/kcontrol/keyboard/layout_tray_icon.cpp new file mode 100644 index 00000000..85eac9e4 --- /dev/null +++ b/kcontrol/keyboard/layout_tray_icon.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "layout_tray_icon.h" + +//#include +#include +#include +#include + +#include "xkb_rules.h" +#include "x11_helper.h" +#include "xkb_helper.h" +#include "keyboard_config.h" +#include "flags.h" +#include "layouts_menu.h" + + +// +// Layout Tray Icon +// +LayoutTrayIcon::LayoutTrayIcon(const Rules* rules_, const KeyboardConfig& keyboardConfig_): + keyboardConfig(keyboardConfig_), + rules(rules_), + flags(new Flags()), + layoutsMenu(new LayoutsMenu(keyboardConfig_, *rules, *flags)) +{ + m_notifierItem = new KStatusNotifierItem(this); + m_notifierItem->setCategory(KStatusNotifierItem::SystemServices); + m_notifierItem->setStatus(KStatusNotifierItem::Active); + m_notifierItem->setToolTipTitle(i18nc("tooltip title", "Keyboard Layout")); + m_notifierItem->setTitle(i18nc("tooltip title", "Keyboard Layout")); + + KMenu* menu = new KMenu(""); + m_notifierItem->setContextMenu(menu); + m_notifierItem->setStandardActionsEnabled(false); + + layoutMapChanged(); + + m_notifierItem->setStatus(KStatusNotifierItem::Active); + + init(); +} + +LayoutTrayIcon::~LayoutTrayIcon() +{ + destroy(); + delete flags; + delete layoutsMenu; +} + +void LayoutTrayIcon::init() +{ + connect(m_notifierItem, SIGNAL(activateRequested(bool,QPoint)), this, SLOT(toggleLayout())); + connect(m_notifierItem, SIGNAL(scrollRequested(int,Qt::Orientation)), this, SLOT(scrollRequested(int,Qt::Orientation))); + connect(flags, SIGNAL(pixmapChanged()), this, SLOT(layoutChanged())); +} + +void LayoutTrayIcon::destroy() +{ + disconnect(flags, SIGNAL(pixmapChanged()), this, SLOT(layoutChanged())); + disconnect(m_notifierItem, SIGNAL(scrollRequested(int,Qt::Orientation)), this, SLOT(scrollRequested(int,Qt::Orientation))); + disconnect(m_notifierItem, SIGNAL(activateRequested(bool,QPoint)), this, SLOT(toggleLayout())); +} + +void LayoutTrayIcon::layoutMapChanged() +{ + flags->clearCache(); + + KMenu* menu = m_notifierItem->contextMenu(); + menu->clear(); + QList actions = layoutsMenu->contextualActions(); + menu->addActions(actions); + + layoutChanged(); +} + +void LayoutTrayIcon::layoutChanged() +{ + LayoutUnit layoutUnit = X11Helper::getCurrentLayout(); + if( layoutUnit.isEmpty() ) + return; + +// QString shortText = Flags::getShortText(layoutUnit, *keyboardConfig); +// kDebug() << "systray: LayoutChanged" << layoutUnit.toString() << shortText; + QString longText = Flags::getLongText(layoutUnit, rules); + + m_notifierItem->setToolTipSubTitle(longText); + + const QIcon icon(getFlag(layoutUnit.layout)); + m_notifierItem->setToolTipIconByPixmap(icon); + + QIcon textOrIcon = flags->getIconWithText(layoutUnit, keyboardConfig); + m_notifierItem->setIconByPixmap( textOrIcon ); +} + +void LayoutTrayIcon::toggleLayout() +{ + X11Helper::switchToNextLayout(); +} + +void LayoutTrayIcon::scrollRequested(int delta, Qt::Orientation /*orientation*/) +{ + X11Helper::scrollLayouts(delta > 0 ? 1 : -1); +} + +const QIcon LayoutTrayIcon::getFlag(const QString& layout) const +{ + return keyboardConfig.isFlagShown() ? flags->getIcon(layout) : QIcon(); +} diff --git a/kcontrol/keyboard/layout_tray_icon.h b/kcontrol/keyboard/layout_tray_icon.h new file mode 100644 index 00000000..1ed4dda6 --- /dev/null +++ b/kcontrol/keyboard/layout_tray_icon.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef LAYOUT_TRAY_ICON_H_ +#define LAYOUT_TRAY_ICON_H_ + +#include +#include + +#include "flags.h" +#include "x11_helper.h" + +class KeyboardConfig; +class LayoutsMenu; + +/** + * System tray icon to show layouts + */ +class KStatusNotifierItem; +class QActionGroup; +class Rules; +class Flags; +class LayoutTrayIcon : public QObject +{ + Q_OBJECT + +public: + LayoutTrayIcon(const Rules* rules, const KeyboardConfig& keyboardConfig); + ~LayoutTrayIcon(); + + void layoutMapChanged(); + +public Q_SLOTS: + void layoutChanged(); + +private Q_SLOTS: + void toggleLayout(); + void scrollRequested(int, Qt::Orientation); + +private: + void init(); + void destroy(); + const QIcon getFlag(const QString& layout) const; + + const KeyboardConfig& keyboardConfig; + const Rules* rules; + Flags* flags; + KStatusNotifierItem *m_notifierItem; + LayoutsMenu* layoutsMenu; +}; + + +#endif /* LAYOUT_WIDGET_H_ */ diff --git a/kcontrol/keyboard/layout_widget.cpp b/kcontrol/keyboard/layout_widget.cpp new file mode 100644 index 00000000..07ef0a56 --- /dev/null +++ b/kcontrol/keyboard/layout_widget.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "layout_widget.h" + +//#include +#include + +#include + +#include "xkb_rules.h" +#include "x11_helper.h" +#include "xkb_helper.h" +#include "keyboard_config.h" +#include "flags.h" + + +K_PLUGIN_FACTORY(LayoutWidgetFactory, registerPlugin();) +K_EXPORT_PLUGIN(LayoutWidgetFactory("keyboard_layout_widget")) + + +LayoutWidget::LayoutWidget(QWidget* parent, const QList& /*args*/): + QWidget(parent), + xEventNotifier(), + keyboardConfig(new KeyboardConfig()), + flags(new Flags()) +{ + if( ! X11Helper::xkbSupported(NULL) ) { +// setFailedToLaunch(true, "XKB extension failed to initialize"); + hide(); + return; + } + + keyboardConfig->load(); + bool show = // keyboardConfig->showIndicator && + ( keyboardConfig->showSingle || X11Helper::getLayoutsList().size() > 1 ); + if( ! show ) { + hide(); + return; + } + + widget = new QPushButton(this); + widget->setFlat(true); + + layoutChanged(); + init(); +} + +LayoutWidget::~LayoutWidget() +{ + destroy(); +} + +void LayoutWidget::init() +{ + connect(widget, SIGNAL(clicked(bool)), this, SLOT(toggleLayout())); + connect(&xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + connect(&xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged())); + xEventNotifier.start(); +} + +void LayoutWidget::destroy() +{ + xEventNotifier.stop(); + disconnect(&xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged())); + disconnect(&xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); +} + +void LayoutWidget::toggleLayout() +{ + X11Helper::switchToNextLayout(); +} + +void LayoutWidget::layoutChanged() +{ + LayoutUnit layoutUnit = X11Helper::getCurrentLayout(); + if( layoutUnit.isEmpty() ) + return; + + QIcon icon; + if( keyboardConfig->isFlagShown() ) { + icon = flags->getIcon(layoutUnit.layout); + } + + QString longText = Flags::getLongText(layoutUnit, NULL); + if( ! icon.isNull() ) { + widget->setIcon(icon); + widget->setText(""); + widget->setToolTip(longText); + } + else { + QString shortText = Flags::getShortText(layoutUnit, *keyboardConfig); + widget->setIcon(icon); + widget->setText(shortText); + widget->setToolTip(longText); +// widget->setShortcut(QKeySequence()); + } +} + diff --git a/kcontrol/keyboard/layout_widget.h b/kcontrol/keyboard/layout_widget.h new file mode 100644 index 00000000..77d50a20 --- /dev/null +++ b/kcontrol/keyboard/layout_widget.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef LAYOUT_WIDGET_H_ +#define LAYOUT_WIDGET_H_ + +#include +#include + +#include "flags.h" +#include "x11_helper.h" + +class QPushButton; +class KeyboardConfig; +class LayoutsMenu; + +/** + * Note: does not listen to configuration changes as currently we only use it in screen lock dialog + */ +class LayoutWidget : public QWidget +{ + Q_OBJECT + +public: + explicit LayoutWidget(QWidget* parent = 0, const QList& args = QList()); + virtual ~LayoutWidget(); + +private Q_SLOTS: + void toggleLayout(); + void layoutChanged(); + // void configChanged(); + +private: + void init(); + void destroy(); + + XEventNotifier xEventNotifier; + QPushButton* widget; + KeyboardConfig* keyboardConfig; + Flags* flags; +}; + +#endif /* LAYOUT_WIDGET_H_ */ diff --git a/kcontrol/keyboard/layouts_menu.cpp b/kcontrol/keyboard/layouts_menu.cpp new file mode 100644 index 00000000..5b9a62e5 --- /dev/null +++ b/kcontrol/keyboard/layouts_menu.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "layouts_menu.h" + +#include +#include +#include +#include + +#include +#include + +#include "keyboard_config.h" +#include "x11_helper.h" +#include "xkb_helper.h" +#include "flags.h" + + +LayoutsMenu::LayoutsMenu(const KeyboardConfig& keyboardConfig_, const Rules& rules_, Flags& flags_): + keyboardConfig(keyboardConfig_), + rules(rules_), + flags(flags_), + actionGroup(NULL) +{ +} + +LayoutsMenu::~LayoutsMenu() +{ + delete actionGroup; +} + +const QIcon LayoutsMenu::getFlag(const QString& layout) const +{ + return keyboardConfig.isFlagShown() ? flags.getIcon(layout) : QIcon(); +} + +void LayoutsMenu::actionTriggered(QAction* action) +{ + QString data = action->data().toString(); + if( data == "config" ) { + QStringList args; + args << "--args=--tab=layouts"; + args << "kcm_keyboard"; + KToolInvocation::kdeinitExec("kcmshell4", args); + } + else { + LayoutUnit layoutUnit(LayoutUnit(action->data().toString())); + switchToLayout(layoutUnit, keyboardConfig); + } +} + +int LayoutsMenu::switchToLayout(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig) +{ + QList layouts = X11Helper::getCurrentLayouts().layouts; + + bool res; + if( layouts.contains(layoutUnit) ) { + res = X11Helper::setLayout(layoutUnit); + } + else if ( keyboardConfig.isSpareLayoutsEnabled() && keyboardConfig.layouts.contains(layoutUnit) ) { + QList layouts(keyboardConfig.getDefaultLayouts()); + layouts.removeLast(); + layouts.append(layoutUnit); + XkbHelper::initializeKeyboardLayouts(layouts); + res = X11Helper::setLayout(layoutUnit); + } + else { + kWarning() << "switchToLayout with unknown layout" << layoutUnit.toString(); + res = -1; + } + return res; +} + +QAction* LayoutsMenu::createAction(const LayoutUnit& layoutUnit) const +{ + QString menuText = Flags::getFullText(layoutUnit, keyboardConfig, &rules); + QAction* action = new QAction(getFlag(layoutUnit.layout), menuText, actionGroup); + action->setData(layoutUnit.toString()); + //FIXME: tooltips don't work on dbusmenus??? +// if( ! layoutUnit.getShortcut().isEmpty() ) { +// action->setToolTip(layoutUnit.getShortcut().toString()); +// } + return action; +} + +QList LayoutsMenu::contextualActions() +{ + if( actionGroup ) { + disconnect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); + delete actionGroup; + } + actionGroup = new QActionGroup(this); + + X11Helper::getLayoutsList(); //UGLY: seems to be more reliable with extra call + QList currentLayouts = X11Helper::getLayoutsList(); + foreach(const LayoutUnit& layoutUnit, currentLayouts) { + QAction* action = createAction(layoutUnit); + actionGroup->addAction(action); + } + + if( keyboardConfig.configureLayouts ) { + QList extraLayouts = keyboardConfig.layouts; + foreach(const LayoutUnit& layoutUnit, currentLayouts) { + extraLayouts.removeOne(layoutUnit); + } + if( extraLayouts.size() > 0 ) { + QAction* separator = new QAction(actionGroup); + separator->setSeparator(true); + actionGroup->addAction(separator); + + foreach(const LayoutUnit& layoutUnit, extraLayouts) { + QAction* action = createAction(layoutUnit); + actionGroup->addAction(action); + } + } + } + + QAction* separator = new QAction(actionGroup); + separator->setSeparator(true); + actionGroup->addAction(separator); + QAction* configAction = new QAction(i18n("Configure..."), actionGroup); + actionGroup->addAction(configAction); + configAction->setData("config"); + connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); + return actionGroup->actions(); +} diff --git a/kcontrol/keyboard/layouts_menu.h b/kcontrol/keyboard/layouts_menu.h new file mode 100644 index 00000000..db2f3ff5 --- /dev/null +++ b/kcontrol/keyboard/layouts_menu.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef LAYOUTS_MENU_H_ +#define LAYOUTS_MENU_H_ + +#include +#include + +class QAction; +class KeyboardConfig; +class Flags; +class Rules; +class QActionGroup; +class LayoutUnit; + +class LayoutsMenu : public QObject +{ + Q_OBJECT + +public: + LayoutsMenu(const KeyboardConfig& keyboardConfig, const Rules& rules, Flags& flags); + virtual ~LayoutsMenu(); + + QList contextualActions(); + static int switchToLayout(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig); + +private Q_SLOTS: + void actionTriggered(QAction* action); + +private: + const QIcon getFlag(const QString& layout) const; + QAction* createAction(const LayoutUnit& layoutUnit) const; + + const KeyboardConfig& keyboardConfig; + const Rules& rules; + Flags& flags; + QActionGroup* actionGroup; +}; + +#endif /* LAYOUTS_MENU_H_ */ diff --git a/kcontrol/keyboard/numlockx.c b/kcontrol/keyboard/numlockx.c new file mode 100644 index 00000000..0ac7cfbd --- /dev/null +++ b/kcontrol/keyboard/numlockx.c @@ -0,0 +1,305 @@ +/**************************************************************************** + + NumLockX + + $Id: main.c,v 1.10 2001/04/30 20:55:20 seli Exp $ + + Copyright (C) 2000-2001 Lubos Lunak + Copyright (C) 2001 Oswald Buddenhagen + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +****************************************************************************/ + +#include + +#include + +#include + +#ifdef HAVE_XTEST +#include +#endif + +#ifdef HAVE_XKB +#include +#endif + +#include + +static +Display* dpy; + +/* the XKB stuff is based on code created by Oswald Buddenhagen */ +#ifdef HAVE_XKB +static +int xkb_init() + { + int xkb_opcode, xkb_event, xkb_error; + int xkb_lmaj = XkbMajorVersion; + int xkb_lmin = XkbMinorVersion; + return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin ) + && XkbQueryExtension( dpy, &xkb_opcode, &xkb_event, &xkb_error, + &xkb_lmaj, &xkb_lmin ); + } + +static +unsigned int xkb_mask_modifier( XkbDescPtr xkb, const char *name ) + { + int i; + if( !xkb || !xkb->names ) + return 0; + for( i = 0; + i < XkbNumVirtualMods; + i++ ) + { + char* modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] ); + if( modStr != NULL && strcmp(name, modStr) == 0 ) + { + unsigned int mask; + XkbVirtualModsToReal( xkb, 1 << i, &mask ); + return mask; + } + } + return 0; + } + +static +unsigned int xkb_numlock_mask() + { + XkbDescPtr xkb; + if(( xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd )) != NULL ) + { + unsigned int mask = xkb_mask_modifier( xkb, "NumLock" ); + XkbFreeKeyboard( xkb, 0, True ); + return mask; + } + return 0; + } + +static +int xkb_set_on() + { + unsigned int mask; + if( !xkb_init()) + return 0; + mask = xkb_numlock_mask(); + if( mask == 0 ) + return 0; + XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, mask); + return 1; + } + +static +int xkb_set_off() + { + unsigned int mask; + if( !xkb_init()) + return 0; + mask = xkb_numlock_mask(); + if( mask == 0 ) + return 0; + XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, 0); + return 1; + } + +#ifdef NUMLOCKX_STANDALONE +static +int xkb_toggle() + { + unsigned int mask; + unsigned int numlockState; + XkbStateRec xkbState; + if( !xkb_init()) + return 0; + mask = xkb_numlock_mask(); + if( mask == 0 ) + return 0; + XkbGetState( dpy, XkbUseCoreKbd, &xkbState); + numlockState = xkbState.locked_mods & mask; + if (numlockState) + XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, 0); + else + XkbLockModifiers ( dpy, XkbUseCoreKbd, mask, mask); + return 1; + } +#endif + +#endif + +#ifdef HAVE_XTEST +static +int xtest_get_numlock_state() + { + int i; + int numlock_mask = 0; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + unsigned int mask; + XModifierKeymap* map = XGetModifierMapping( dpy ); + KeyCode numlock_keycode = XKeysymToKeycode( dpy, XK_Num_Lock ); + if( numlock_keycode == NoSymbol ) + return 0; + for( i = 0; + i < 8; + ++i ) + { + if( map->modifiermap[ map->max_keypermod * i ] == numlock_keycode ) + numlock_mask = 1 << i; + } + XQueryPointer( dpy, DefaultRootWindow( dpy ), &dummy1, &dummy2, + &dummy3, &dummy4, &dummy5, &dummy6, &mask ); + XFreeModifiermap( map ); + return mask & numlock_mask; + } + +static +void xtest_change_numlock() + { + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, XK_Num_Lock ), True, CurrentTime ); + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, XK_Num_Lock ), False, CurrentTime ); + } + +static +void xtest_set_on() + { + if( !xtest_get_numlock_state()) + xtest_change_numlock(); + } + +static +void xtest_set_off() + { + if( xtest_get_numlock_state()) + xtest_change_numlock(); + } + +#ifdef NUMLOCKX_STANDALONE +static +void xtest_toggle() + { + xtest_change_numlock(); + } +#endif + +#endif + +static +void numlock_set_on() + { +#ifdef HAVE_XKB + if( xkb_set_on()) + return; +#endif +#ifdef HAVE_XTEST + xtest_set_on(); +#endif + } + +static +void numlock_set_off() + { +#ifdef HAVE_XKB + if( xkb_set_off()) + return; +#endif +#ifdef HAVE_XTEST + xtest_set_off(); +#endif + } + + +#ifndef NUMLOCKX_STANDALONE + +void numlockx_change_numlock_state(Display* dpy_, int state) +{ +#ifndef HAVE_XTEST +#ifdef __GNUC__ + #warning "XTEST extension not found - numlock setting may not work reliably" +#endif +#endif + + dpy = dpy_; + if( state ) { + numlock_set_on(); + } + else { + numlock_set_off(); + } +} + +#else + +static +void numlock_toggle() + { +#ifdef HAVE_XKB + if( xkb_toggle()) + return; +#endif +#ifdef HAVE_XTEST + xtest_toggle(); +#endif + } + +void usage( const char* argv0 ) + { + printf( "NumLockX " VERSION "\n" + "(C) 2000-2001 Lubos Lunak \n" + "(C) 2001 Oswald Buddenhagen \n\n" + "Usage : %s [on|off]\n" + "on - turns NumLock on in X ( default )\n" + "off - turns NumLock off in X\n" + "toggle - toggles the NumLock on and off in X\n" + "\n" + , argv0 ); + } + +int main( int argc, char* argv[] ) + { + if( argc > 2 ) + { + usage( argv[ 0 ] ); + return 1; + } + dpy = XOpenDisplay( NULL ); + if( dpy == NULL ) + { + fprintf( stderr, "Error opening display!\n" ); + return 1; + } + if( argc == 1 ) + numlock_set_on(); + else if( strcmp( argv[ 1 ], "on" ) == 0 ) + numlock_set_on(); + else if( strcmp( argv[ 1 ], "off" ) == 0 ) + numlock_set_off(); + else if( strcmp( argv[ 1 ], "toggle" ) == 0 ) + numlock_toggle(); + else + { + usage( argv[ 0 ] ); + XCloseDisplay( dpy ); + return 2; + } + XCloseDisplay( dpy ); + return 0; + } + +#endif diff --git a/kcontrol/keyboard/pics/CMakeLists.txt b/kcontrol/keyboard/pics/CMakeLists.txt new file mode 100644 index 00000000..6d5b7cae --- /dev/null +++ b/kcontrol/keyboard/pics/CMakeLists.txt @@ -0,0 +1 @@ +install( FILES epo.png DESTINATION ${DATA_INSTALL_DIR}/kcmkeyboard/pics ) diff --git a/kcontrol/keyboard/pics/epo.png b/kcontrol/keyboard/pics/epo.png new file mode 100644 index 0000000000000000000000000000000000000000..a8ed2943810dcbdf62c3456b115bae749b6dfe8c GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{Y!2~4zQx41oQq09po*^6@9Je3(KLBz$3p^r= zfl7{mFymBhK53v}pQnpsh{nX^KmY&RGqWYkIohGwA!=|iGFmQAF^JzNAu%Cg$FFy< zHs_x&>VLY)c(Zq*cP4k1@cQ|kjg5{i&P)C}{cb+be@lN$cR|O5oc$KlcUbM;rL$c} zoO`;(atqI2lK&xqJzh@Zlh(ceHSvw^jT0wM{P7`qiNPO9$uyzYA!`~sH%torYjTC3 Y!E3Kt@gFHAkXINyUHx3vIVCg!0Bep~LI3~& literal 0 HcmV?d00001 diff --git a/kcontrol/keyboard/plasma_applet_keyboard.desktop b/kcontrol/keyboard/plasma_applet_keyboard.desktop new file mode 100644 index 00000000..711c977f --- /dev/null +++ b/kcontrol/keyboard/plasma_applet_keyboard.desktop @@ -0,0 +1,161 @@ +[Desktop Entry] +Name=Keyboard Layout +Name[af]=Sleutelbord Uitleg +Name[ar]=تخطيط لوحة المفاتيح +Name[ast]=Disposición del tecláu +Name[be]=Раскладка клавіятуры +Name[be@latin]=Vykład klavijatury +Name[bg]=Клавиатурни подредби +Name[bn]=কীবোর্ড বিন্যাস +Name[bn_IN]=কি-বোর্ড বিন্যাস +Name[br]=Reizhadur ar stokellaoueg +Name[bs]=Raspored tastera +Name[ca]=Disposició del teclat +Name[ca@valencia]=Disposició del teclat +Name[cs]=Rozvržení klávesnice +Name[csb]=Ùstôw klawiaturë +Name[cy]=Cynllun Bysellfwrdd +Name[da]=Tastaturlayout +Name[de]=Tastaturbelegung +Name[el]=Διάταξη πληκτρολογίου +Name[en_GB]=Keyboard Layout +Name[eo]=Klavararanĝo +Name[es]=Disposición del teclado +Name[et]=Klaviatuuri paigutus +Name[eu]=Teklatu-diseinua +Name[fa]=طرح‌بندی صفحه کلید +Name[fi]=Näppäimistöasettelu +Name[fy]=Toetseboerdyndieling +Name[ga]=Leagan Amach Méarchláir +Name[gl]=Disposición do teclado +Name[gu]=કીબોર્ડ દેખાવ +Name[he]=פריסת מקלדת +Name[hi]=कुंजीपट ख़ाका +Name[hne]=कुंजीपट खाका +Name[hr]=Raspored tipkovnice +Name[hsb]=Tastaturowy layout +Name[hu]=Billentyűzetkiosztás +Name[ia]=Disposition de claviero +Name[id]=Tata Letak Papan Ketik +Name[is]=Lyklaborð +Name[ja]=キーボード配列 +Name[ka]=კლავიატურის განლაგება +Name[kk]=Перенетақта сәйкестігі +Name[km]=ប្លង់​ក្ដារចុច +Name[kn]=ಕೀಲಿಮಣೆ ವಿನ್ಯಾಸ +Name[ko]=키보드 레이아웃 +Name[ku]=Rengê Klavyeyê +Name[lt]=Klaviatūros išdėstymas +Name[lv]=Tastatūras izkārtojums +Name[mai]=कीबोर्ड लेआउट +Name[mk]=Распоред на тастатура +Name[ml]=കീബോര്‍ഡ് വിന്യാസം +Name[mr]=कळफलक रचना +Name[nb]=Tastaturutforming +Name[nds]=Tasttoornen +Name[ne]=कुञ्जीपाटी सजावट +Name[nl]=Toetsenbordindeling +Name[nn]=Taste­oppsett +Name[oc]=Disposicion del clavièr +Name[or]=କିବୋର୍ଡ଼ ବିନ୍ୟାସ +Name[pa]=ਕੀ-ਬੋਰਡ ਲੇਆਉਟ +Name[pl]=Układ klawiatury +Name[pt]=Disposição do Teclado +Name[pt_BR]=Leiaute do teclado +Name[ro]=Aranjament de tastatură +Name[ru]=Раскладка клавиатуры +Name[se]=Boallobeavdehápmi +Name[si]=යතුරුපුවරු ආකෘතිය +Name[sk]=Rozloženie klávesnice +Name[sl]=Razporeditev tipk +Name[sr]=Распоред тастатуре +Name[sr@ijekavian]=Распоред тастатуре +Name[sr@ijekavianlatin]=Raspored tastature +Name[sr@latin]=Raspored tastature +Name[sv]=Tangentbordslayout +Name[ta]=விசைப்பலகை உருவரை +Name[te]=కీబోర్డ్ కూర్పు +Name[tg]=Тугмабандии клавиатура +Name[th]=ผังแป้นพิมพ์ +Name[tr]=Klavye Düzeni +Name[ug]=ھەرپتاختا جايلاشتۇرۇلۇشى +Name[uk]=Розкладка клавіатури +Name[uz]=Tugmalar tartibi +Name[uz@cyrillic]=Тугмалар тартиби +Name[vi]=Bố trí bàn phím +Name[wa]=Adjinçmint del taprece +Name[xh]=Ubeko Lwebhodi yezitshixo +Name[x-test]=xxKeyboard Layoutxx +Name[zh_CN]=键盘布局 +Name[zh_TW]=鍵盤配置 +Comment=View and switch between active keyboard layouts +Comment[ar]=إعرض وبدل بين مخططات لوحة المفاتيح +Comment[ast]=Ver y camudar ente les distribuciones de tecláu actives +Comment[bg]=Преглед и превключване на клавиатурната подредба +Comment[bn]=সক্রিয় কীবোর্ড বিন্যাসগুলি দেখুন এবং অদলবদল করুন +Comment[bs]=Prikaz i prebacivanje između aktivnih rasporeda tastature +Comment[ca]=Vista i commutació entre disposicions actives de teclat +Comment[ca@valencia]=Vista i commutació entre disposicions actives de teclat +Comment[cs]=Zobrazí a přepne mezi aktivními rozloženími klávesnice +Comment[da]=Vis og skift mellem aktive tastaturlayouts +Comment[de]=Aktive Tastaturbelegungen anzeigen und zwischen ihnen umschalten +Comment[el]=Εμφάνιση και εναλλαγή μεταξύ των ενεργών διατάξεων πληκτρολογίου +Comment[en_GB]=View and switch between active keyboard layouts +Comment[es]=Ver y cambiar entre las distribuciones de teclado activas +Comment[et]=Aktiivsete klaviatuuripaigutuste näitamine ja nende vahel lülitamine +Comment[eu]=Ikusi eta aldatu teklatu-diseinu aktibo batetik bestera +Comment[fi]=Katsele ja vaihda aktiivisten näppäinasetteluiden välillä +Comment[gl]=Mostra e troca a disposición de teclado activa +Comment[he]=משמש להצגת והחלפה בין פריסות מקלדת +Comment[hr]=Prikaži i prebaci između aktivnih tipkovničkih rasporeda +Comment[hu]=Aktív billentyűzetkiosztások megjelenítése és váltás köztük +Comment[ia]=Monstra e commuta inter dispositiones de claviero active +Comment[is]=Skoða og skipta á milli virkra lyklaborðsframsetninga +Comment[ja]=アクティブキーボードレイアウトを表示して切り替える +Comment[kk]=Белсенді пернетақталарды көру және біріне ауысу +Comment[km]=មើល ហើយ​ប្ដូរ​ប្លង់​ក្ដារចុច​សកម្ម +Comment[ko]=활성 키보드 레이아웃을 보고 바꾸기 +Comment[lt]=Peržiūrėti ir persijungti tarp aktyvių klaviatūros maketų +Comment[lv]=Skatīt un pārslēgties starp aktīvajiem tastatūras izkārtojumumiem +Comment[mr]=चालू कळफलक रचना बघा व बदला +Comment[nb]=Vis aktive tastaturutforminger og bytt mellom dem +Comment[nds]=Aktiv Tasttoornen ankieken un wesseln +Comment[nl]=Bekijk en schakel tussen actieve toetsenbordindelingen +Comment[nn]=Vis og byt mellom aktive tastaturoppsett +Comment[pa]=ਸਰਗਰਮ ਕੀਬੋਰਡ ਲੇਆਉਟ ਵੇਖੋ ਅਤੇ ਬਦਲੋ +Comment[pl]=Przeglądanie i przełączanie między aktywnymi układami klawiatury +Comment[pt]=Ver e mudar a disposição de teclado activa +Comment[pt_BR]=Visualiza e troca o leiaute de teclado ativo +Comment[ro]=Vizualizează și schimbă între aranjamentele de tastatură active +Comment[ru]=Просмотр и переключение между активными раскладками клавиатуры +Comment[sk]=Zobrazenie a prepínanie medzi aktívnymi rozloženiami klávesnice +Comment[sl]=Oglejte si in preklopite med dejavnimi razporeditvami tipk +Comment[sr]=Приказ и мењање активних распореда тастатуре +Comment[sr@ijekavian]=Приказ и мењање активних распореда тастатуре +Comment[sr@ijekavianlatin]=Prikaz i menjanje aktivnih rasporeda tastature +Comment[sr@latin]=Prikaz i menjanje aktivnih rasporeda tastature +Comment[sv]=Visa och byt mellan aktiva tangentbordslayouter +Comment[th]=ดูและสลับการจัดวางแป้นพิมพ์ที่ใช้งานอยู่ +Comment[tr]=Etkin klavye düzenlerini görüntüle ve geçiş yap +Comment[ug]=ئاكتىپ ھەرپتاختا جايلاشتۇرۇشى ئارىسىدا ئالماشتۇر ۋە كۆرسەت +Comment[uk]=Перегляд і перемикання між активними розкладками клавіатури +Comment[wa]=Vey eyet discandjî etur les adjinçmints del taprece ovrants +Comment[x-test]=xxView and switch between active keyboard layoutsxx +Comment[zh_CN]=查看和切换键盘布局 +Comment[zh_TW]=檢視並在可用的鍵盤佈局中切換 + +Icon=preferences-desktop-keyboard +Type=Service + +X-KDE-ServiceTypes=Plasma/Applet +X-KDE-Library=plasma_applet_keyboard +X-KDE-PluginInfo-Author=Andriy Rysin +X-KDE-PluginInfo-Email=rysin@kde.org +X-KDE-PluginInfo-Name=keyboard_applet +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-NotificationArea=true diff --git a/kcontrol/keyboard/preview/TODO b/kcontrol/keyboard/preview/TODO new file mode 100644 index 00000000..784924fe --- /dev/null +++ b/kcontrol/keyboard/preview/TODO @@ -0,0 +1,10 @@ +Important: +* display tooltip for each key with key description from symbol file + +Good to have: +* read keyboard geometry and show it properly instead of default keyboard +* use some common parser to parse symbol and geometry descriptions +* replace symkey2ucs with something more reliable (e.g. XLookupString?) + +Cleanup: +* clean up the code (especially kbpreviewframe.cpp) diff --git a/kcontrol/keyboard/preview/kbpreviewframe.cpp b/kcontrol/keyboard/preview/kbpreviewframe.cpp new file mode 100644 index 00000000..8ecc4f24 --- /dev/null +++ b/kcontrol/keyboard/preview/kbpreviewframe.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "kbpreviewframe.h" + +#include +#include + +#include +#include + + +static const QColor keyBorderColor("#d4d4d4"); +static const QColor lev12color("#d4d4d4"); +static const QColor lev34color("#FF3300"); +static const int sz=20, kszx=70, kszy=70; + +static const int xOffset[] = {15, 15, 40, 40 }; +static const int yOffset[] = {10, 40, 10, 40 }; +static const QColor color[] = { lev12color, lev12color, lev34color, lev34color }; + + +// TODO: parse geometry files and display keyboard according to current keyboard model + +KbPreviewFrame::KbPreviewFrame(QWidget *parent) : + QFrame(parent) +{ + setFrameStyle( QFrame::Box ); + setFrameShadow(QFrame::Sunken); +} + +void KbPreviewFrame::paintTLDE(QPainter &painter,int &x,int &y) +{ + painter.setPen(keyBorderColor); + painter.drawRect(x, y, kszx, kszy); + + const QList symbols = keyboardLayout.TLDE.symbols; + + for(int level=0; level symbols = keyboardLayout.AE[i].symbols; + + for(int level=0; level")); + x+=tabszx; + + + for(int i=0; i symbols = keyboardLayout.AD[i].symbols; + + painter.setPen(keyBorderColor); + painter.drawRect(x, y,kszx,kszy); + + for(int level=0; level symbols = keyboardLayout.BKSL.symbols; + + for(int level=0; level symbols = keyboardLayout.AC[i].symbols; + + for(int level=0; level symbols = keyboardLayout.AB[i].symbols; + + for(int level=0; level symstr = content.split("xkb_symbols "); + + if( layoutVariant.isEmpty() ) { + keyboardLayout.generateLayout(symstr.at(1), layout); + } + else { + for(int i=1;i +#include + +class KbPreviewFrame : public QFrame +{ + Q_OBJECT + +private: + void paintTLDE(QPainter &painter, int &x, int &y); + void paintAERow(QPainter &painter, int &x, int &y); + void paintADRow(QPainter &painter, int &x, int &y); + void paintACRow(QPainter &painter, int &x, int &y); + void paintABRow(QPainter &painter, int &x, int &y); + void paintBottomRow(QPainter &painter, int &x, int &y); + void paintFnKeys(QPainter &painter, int &x, int &y); + + KeySymHelper symbol; + Aliases alias; + KeyboardLayout keyboardLayout; + +public: + explicit KbPreviewFrame(QWidget *parent = 0); + + void paintEvent(QPaintEvent * event); + void generateKeyboardLayout(const QString &country, const QString &layoutVariant); + QString getLayoutName() const { + return keyboardLayout.getLayoutName(); + } +}; + +#endif // KBPREVIEWFRAME_H diff --git a/kcontrol/keyboard/preview/keyaliases.cpp b/kcontrol/keyboard/preview/keyaliases.cpp new file mode 100644 index 00000000..3eb45ec4 --- /dev/null +++ b/kcontrol/keyboard/preview/keyaliases.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyaliases.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + + +Aliases::Aliases() +{ + QString filename=findaliasdir(); + QFile file(filename); + file.open(QIODevice::ReadOnly | QIODevice::Text); + QString content = file.readAll(); + file.close(); + QListals; + als=content.split("xkb_keycodes"); + for(int i=1;i"); + temp=temp.remove("<"); + temp=temp.remove(";"); + temp=temp.remove("}"); + temp=temp.remove("{"); + QListalskeys; + alskeys=temp.split("alias"); + if(temp.startsWith("qwerty")){ + for(int k=1;k= 3 ) { + // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb + QString delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11"; + QDir baseDir(base + delta); + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + else { + QDir baseDir(base + "/X11"); // .../usr/X11/lib/X11/xkb (old XFree) + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + } + } + + if( xkbParentDir.isEmpty() ) { + xkbParentDir = "/usr/share/X11"; + } + aliasdir=QString("%1/xkb/keycodes/aliases").arg(xkbParentDir); + return(aliasdir); +} diff --git a/kcontrol/keyboard/preview/keyaliases.h b/kcontrol/keyboard/preview/keyaliases.h new file mode 100644 index 00000000..3769e4eb --- /dev/null +++ b/kcontrol/keyboard/preview/keyaliases.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef ALIASES_H +#define ALIASES_H + +#include + +class Aliases +{ +private: + QMapqwerty; + QMapazerty; + QMapqwertz; + QString findaliasdir(); +public: + Aliases(); + QString getAlias(const QString &type, const QString &name); +}; + +#endif // ALIASES_H diff --git a/kcontrol/keyboard/preview/keyboardlayout.cpp b/kcontrol/keyboard/preview/keyboardlayout.cpp new file mode 100644 index 00000000..6ac2f3f7 --- /dev/null +++ b/kcontrol/keyboard/preview/keyboardlayout.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "keyboardlayout.h" +#include "keysymbols.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +//TODO: replace this with grammar parser (e.g. antlr) + + +KeyboardLayout::KeyboardLayout() +{ +} + +void KeyboardLayout::generateLayout(QString a,const QString& cname) +{ + includeSymbol(a,cname); + int i=a.indexOf("name[Group1]="); + i+=13; + + QString n=a.mid(i); + n=n.simplified(); + i=n.indexOf("\"",1); + layoutName=n.left(i); + layoutName.remove("\""); + layoutName.simplified(); + i=n.indexOf("key"); + n=n.mid(i); + + QList st; + st=n.split("key"); + + KeySymbols dum; + QString r,y; + + for(int k=0;ktobeinclude; + tobeinclude=a.split("include"); + + QString r; + for(int o=1;o incfile; + incfile=incsym.split("("); + for(int i=0;i symstrlist; + + symstrlist=content.split("xkb_symbols "); + for(int u=1;u= 3 ) { + // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb + QString delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11"; + QDir baseDir(base + delta); + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + else { + QDir baseDir(base + "/X11"); // .../usr/X11/lib/X11/xkb (old XFree) + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + } + } + + if( xkbParentDir.isEmpty() ) { + xkbParentDir = "/usr/share/X11"; + } + + return QString("%1/xkb/symbols/").arg(xkbParentDir); +} diff --git a/kcontrol/keyboard/preview/keyboardlayout.h b/kcontrol/keyboard/preview/keyboardlayout.h new file mode 100644 index 00000000..4844382e --- /dev/null +++ b/kcontrol/keyboard/preview/keyboardlayout.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYBOARDLAYOUT_H +#define KEYBOARDLAYOUT_H + +#include "keysymbols.h" +#include "keyaliases.h" + +#include + +class KeyboardLayout +{ + QString layoutName; + Aliases alias; + +public: + KeyboardLayout(); + + KeySymbols TLDE; + KeySymbols BKSL; + KeySymbols AE[12]; + KeySymbols AD[12]; + KeySymbols AC[11]; + KeySymbols AB[11]; + + void generateLayout(QString a, const QString &cname); + QString findSymbolBaseDir(); + void includeSymbol(QString a, const QString &cname); + QString getLayoutName() const { + return layoutName; + } +}; + +#endif // KEYBOARDLAYOUT_H diff --git a/kcontrol/keyboard/preview/keyboardpainter.cpp b/kcontrol/keyboard/preview/keyboardpainter.cpp new file mode 100644 index 00000000..b9fbf242 --- /dev/null +++ b/kcontrol/keyboard/preview/keyboardpainter.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboardpainter.h" + +#include +#include +#include + +#include + + +KeyboardPainter::KeyboardPainter(): + kbframe(new KbPreviewFrame(this)), + exitButton(new QPushButton(i18n("Close"),this)) +{ + kbframe->setFixedSize( 1030, 490 ); + exitButton->setFixedSize(120, 30); + + QVBoxLayout* vLayout = new QVBoxLayout( this ); + vLayout->addWidget(kbframe); + vLayout->addWidget(exitButton); + + connect(exitButton, SIGNAL(clicked()), this, SLOT(close())); + + setWindowTitle(kbframe->getLayoutName()); +} + +void KeyboardPainter::generateKeyboardLayout(const QString& layout, const QString& variant) +{ + kbframe->generateKeyboardLayout(layout, variant); +} + +KeyboardPainter::~KeyboardPainter() +{ + delete kbframe; + delete exitButton; +} diff --git a/kcontrol/keyboard/preview/keyboardpainter.h b/kcontrol/keyboard/preview/keyboardpainter.h new file mode 100644 index 00000000..39382be7 --- /dev/null +++ b/kcontrol/keyboard/preview/keyboardpainter.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARDPAINTER_H +#define KEYBOARDPAINTER_H + +#include "kbpreviewframe.h" + +#include + +class QPushButton; + +class KeyboardPainter : public QDialog +{ + Q_OBJECT + +public: + explicit KeyboardPainter(); + ~KeyboardPainter(); + + void generateKeyboardLayout(const QString& layout, const QString& variant); + +private: + KbPreviewFrame *kbframe; + QPushButton *exitButton; +}; + +#endif // KEYBOARDPAINTER_H diff --git a/kcontrol/keyboard/preview/keysym2ucs.cpp b/kcontrol/keyboard/preview/keysym2ucs.cpp new file mode 100644 index 00000000..37afb082 --- /dev/null +++ b/kcontrol/keyboard/preview/keysym2ucs.cpp @@ -0,0 +1,899 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* $XFree86$ + * This module converts keysym values into the corresponding ISO 10646-1 + * (UCS, Unicode) values. + * + * The array keysymtab[] contains pairs of X11 keysym values for graphical + * characters and the corresponding Unicode value. The function + * keysym2ucs() maps a keysym onto a Unicode value using a binary search, + * therefore keysymtab[] must remain SORTED by keysym value. + * + * The keysym -> UTF-8 conversion will hopefully one day be provided + * by Xlib via XmbLookupString() and should ideally not have to be + * done in X applications. But we are not there yet. + * + * We allow to represent any UCS character in the range U+00000000 to + * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. + * This admittedly does not cover the entire 31-bit space of UCS, but + * it does cover all of the characters up to U+10FFFF, which can be + * represented by UTF-16, and more, and it is very unlikely that higher + * UCS codes will ever be assigned by ISO. So to get Unicode character + * U+ABCD you can directly use keysym 0x1000abcd. + * + * NOTE: The comments in the table below contain the actual character + * encoded in UTF-8, so for viewing and editing best use an editor in + * UTF-8 mode. + * + * Author: Markus G. Kuhn , University of Cambridge, June 1999 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + */ + +#include + +struct codepair { + unsigned short keysym; + unsigned short ucs; +} keysymtab[] = { + { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ + { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ + { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ + { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ + { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ + { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ + { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ + { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ + { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ + { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ + { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ + { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ + { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ + { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ + { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ + { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ + { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ + { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ + { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ + { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ + { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ + { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ + { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ + { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + { 0x08a1, 0x23b7 }, /* leftradical ⎷ RADICAL SYMBOL BOTTOM */ + { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ LEFT SQUARE BRACKET UPPER CORNER */ + { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ LEFT SQUARE BRACKET LOWER CORNER */ + { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ RIGHT SQUARE BRACKET UPPER CORNER */ + { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ RIGHT SQUARE BRACKET LOWER CORNER */ + { 0x08ab, 0x239b }, /* topleftparens ⎛ LEFT PARENTHESIS UPPER HOOK */ + { 0x08ac, 0x239d }, /* botleftparens ⎝ LEFT PARENTHESIS LOWER HOOK */ + { 0x08ad, 0x239e }, /* toprightparens ⎞ RIGHT PARENTHESIS UPPER HOOK */ + { 0x08ae, 0x23a0 }, /* botrightparens ⎠ RIGHT PARENTHESIS LOWER HOOK */ + { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ LEFT CURLY BRACKET MIDDLE PIECE */ + { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ RIGHT CURLY BRACKET MIDDLE PIECE */ +/* 0x08b1 topleftsummation ? ??? */ +/* 0x08b2 botleftsummation ? ??? */ +/* 0x08b3 topvertsummationconnector ? ??? */ +/* 0x08b4 botvertsummationconnector ? ??? */ +/* 0x08b5 toprightsummation ? ??? */ +/* 0x08b6 botrightsummation ? ??? */ +/* 0x08b7 rightmiddlesummation ? ??? */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ + { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ + { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ + { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ + { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ + { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ + { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ + { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ + { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 */ + { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 */ + { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ + { 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ + { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ + { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ + { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ +/* 0x0abf marker ? ??? */ + { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ +/* 0x0acb trademarkincircle ? ??? */ + { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ + { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ + { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ +/* 0x0ad5 permille ? ??? */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ +/* 0x0ada hexagram ? ??? */ + { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ + { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ + { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x0af1, 0x2020 }, /* dagger † DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ +/* 0x0aff cursor ? ??? */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x0bc2, 0x22a5 }, /* downtack ⊥ UP TACK */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ + { 0x0bce, 0x22a4 }, /* uptack ⊤ DOWN TACK */ + { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */ + { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ + { 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ + { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ + { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + + /* Combining symbols */ + { 0xfe50, 0x0300 }, /* dead_grave */ + { 0xfe51, 0x0301 }, /* dead_acute" */ + { 0xfe52, 0x0302 }, /* dead_circumflex" */ + { 0xfe53, 0x0303 }, /* dead_tilde" */ + { 0xfe54, 0x0304 }, /* dead_macron" */ + { 0xfe55, 0x0306 }, /* dead_breve" */ + { 0xfe56, 0x0307 }, /* dead_abovedot" */ + { 0xfe57, 0x0308 }, /* dead_diaeresis" */ + { 0xfe58, 0x030A }, /* dead_abovering" */ + { 0xfe59, 0x030B }, /* dead_doubleacute" */ + { 0xfe5a, 0x030C }, /* dead_caron" */ + { 0xfe5b, 0x0327 }, /* dead_cedilla" */ + { 0xfe5c, 0x0328 }, /* dead_ogonek" */ + { 0xfe60, 0x0323 }, /* dead_belowdot */ + + /* Special function keys. */ + + { 0xff08, 0x0008 }, /* XK_BackSpace */ + { 0xff09, 0x0009 }, /* XK_Tab */ + { 0xff0a, 0x000a }, /* XK_Linefeed */ + { 0xff0d, 0x000d }, /* XK_Return */ + { 0xff13, 0x0013 }, /* XK_Pause */ + { 0xff1b, 0x001b }, /* XK_Escape */ + { 0xff50, 0x0001 }, /* XK_Home */ + { 0xff51, 0x001c }, /* XK_Left */ + { 0xff52, 0x001e }, /* XK_Up */ + { 0xff53, 0x001d }, /* XK_Right */ + { 0xff54, 0x001f }, /* XK_Down */ + { 0xff55, 0x000b }, /* XK_Prior */ + { 0xff56, 0x000c }, /* XK_Next */ + { 0xff57, 0x0004 }, /* XK_End */ + { 0xff6a, 0x0005 }, /* XK_Help */ + { 0xffff, 0x007f }, /* XK_Delete */ +}; + +long keysym2ucs(KeySym keysym) +{ + int min = 0; + int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + int mid; + + /* first check for Latin-1 characters (1:1 mapping) */ + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + return keysym; + + /* also check for directly encoded 24-bit UCS characters */ + if ((keysym & 0xff000000) == 0x01000000) + return keysym & 0x00ffffff; + + /* binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (keysymtab[mid].keysym < keysym) + min = mid + 1; + else if (keysymtab[mid].keysym > keysym) + max = mid - 1; + else { + /* found it */ + return keysymtab[mid].ucs; + } + } + + /* no matching Unicode value found */ + return -1; +} diff --git a/kcontrol/keyboard/preview/keysym2ucs.h b/kcontrol/keyboard/preview/keysym2ucs.h new file mode 100644 index 00000000..6e50c764 --- /dev/null +++ b/kcontrol/keyboard/preview/keysym2ucs.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Andriy Rysin (arysin@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYSYM2UCS_H +#define KEYSYM2UCS_H + +#include +#include + +extern long keysym2ucs(KeySym keysym); + +#endif diff --git a/kcontrol/keyboard/preview/keysymbols.cpp b/kcontrol/keyboard/preview/keysymbols.cpp new file mode 100644 index 00000000..af43f621 --- /dev/null +++ b/kcontrol/keyboard/preview/keysymbols.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "keysymbols.h" + +#include +#include + + +static const int MAX_GROUPS_SUPPORTED = 4; + +KeySymbols::KeySymbols() +{ +} + +void KeySymbols::setKey(const QString& a) +{ + int i=a.indexOf("<"); + i++; + keyname=a.mid(i,4); + keyname.remove(" "); + i=a.indexOf("["); + i++; + + QString str=a.mid(i); + i=str.indexOf("]"); + + QString st=str.left(i); + st=st.remove(" "); + //QStringList klst; + symbols=st.split(","); + + if( symbols.size() > MAX_GROUPS_SUPPORTED ) { + symbols = symbols.mid(0, MAX_GROUPS_SUPPORTED); + } + + for(int k=0;k +#include + +class KeySymbols +{ +public: + KeySymbols(); + + QString keyname; + QList symbols; + + void setKey(const QString& opton); +}; + +#endif // KEYSYMBOLS_H diff --git a/kcontrol/keyboard/preview/keysymhelper.cpp b/kcontrol/keyboard/preview/keysymhelper.cpp new file mode 100644 index 00000000..67beb80d --- /dev/null +++ b/kcontrol/keyboard/preview/keysymhelper.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keysymhelper.h" +#include "keysym2ucs.h" + +#include +#include + +#include + +#include + + +KeySymHelper::KeySymHelper() +{ + nill = 0; +} + +QString KeySymHelper::getKeySymbol(const QString& opton) +{ + if( keySymbolMap.contains(opton) ) + return keySymbolMap[opton]; + + const char* str = opton.toAscii().data(); + +#if 0 + //TODO: figure out how to use this so we don't need our own symkey2ucs mapping + int res = Xutf8LookupString(XIC ic, XKeyPressedEvent *event, char *buffer_return, int bytes_buffer, KeySym *keysym_return, Status *status_return); + +#else + + KeySym keysym = XStringToKeysym(str); + long ucs = keysym2ucs(keysym); + +// if( ucs == -1 && (keysym >= 0xFE50 && keysym <= 0xFE5F) ) { +// ucs = 0x0300 + (keysym & 0x000F); +// kWarning() << "Got dead symbol" << QString("0x%1").arg(keysym, 0, 16) << "named" << opton << "will use" << QString("0x%1").arg(ucs, 0, 16) << "as UCS"; +// } + + if( ucs == -1 ) { + nill++; + kWarning() << "No mapping from keysym:" << QString("0x%1").arg(keysym, 0, 16) << "named:" << opton << "to UCS"; + } + + QString ucsStr = QString(QChar((int)ucs)); + + // Combining Diacritical Marks + if( ucs >= 0x0300 && ucs <= 0x036F ) { + ucsStr = " " + ucsStr + " "; + } + +// kWarning() << "--" << opton << "keysym: " << keysym << QString("0x%1").arg(keysym, 0, 16) << "keysym2string" << XKeysymToString(keysym) +// << "---" << QString("0x%1").arg(ucs, 0, 16) << ucsStr; + + keySymbolMap[opton] = ucsStr; + + return ucsStr; + +#endif + +} + diff --git a/kcontrol/keyboard/preview/keysymhelper.h b/kcontrol/keyboard/preview/keysymhelper.h new file mode 100644 index 00000000..763e872e --- /dev/null +++ b/kcontrol/keyboard/preview/keysymhelper.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYSYMHELPER_H +#define KEYSYMHELPER_H + +#include +#include + +class KeySymHelper +{ +public: + KeySymHelper(); + + QString getKeySymbol(const QString &opton); + bool isFailed() const { + return nill >= 120; + } + +private: + QMap keySymbolMap; + int nill; +}; + +#endif // KEYSYMHELPER_H diff --git a/kcontrol/keyboard/tests/CMakeLists.txt b/kcontrol/keyboard/tests/CMakeLists.txt new file mode 100644 index 00000000..b2bbedc5 --- /dev/null +++ b/kcontrol/keyboard/tests/CMakeLists.txt @@ -0,0 +1,30 @@ +set ( text_paint_LIB ${KDE4_PLASMA_LIBS} ) + +MACRO(KEYBOARD_DAEMON_UNIT_TESTS _testname) + kde4_add_unit_test(${_testname}_test TESTNAME kcm-keyboard-${_testname} NOGUI ${_testname}_test.cpp ../${_testname}.cpp) + target_link_libraries(${_testname}_test ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} ${X11_Xkbfile_LIB} ${X11_LIBRARIES}) +ENDMACRO(KEYBOARD_DAEMON_UNIT_TESTS) + +MACRO(KEYBOARD_DAEMON_UNIT_TESTS2 _testname _src1 _src2 _src3) + kde4_add_unit_test(${_testname}_test TESTNAME kcm-keyboard-${_testname} NOGUI ${_testname}_test.cpp ../${_testname}.cpp ../${_src1} ../${_src2} ../${_src3}) + target_link_libraries(${_testname}_test ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} ${X11_Xkbfile_LIB}) +ENDMACRO(KEYBOARD_DAEMON_UNIT_TESTS2) + + +KEYBOARD_DAEMON_UNIT_TESTS(xkb_rules) +KEYBOARD_DAEMON_UNIT_TESTS(iso_codes) + +kde4_add_unit_test(flags_test TESTNAME kcm-keyboard-flags_test NOGUI flags_test.cpp ../flags.cpp ../x11_helper.cpp ../keyboard_config.cpp ../xkb_rules.cpp) +target_link_libraries(flags_test ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} ${X11_Xkbfile_LIB} ${X11_LIBRARIES} ${text_paint_LIB}) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/base.1.1.xml ${CMAKE_CURRENT_BINARY_DIR}/config/base.1.1.xml COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/base.bad.xml ${CMAKE_CURRENT_BINARY_DIR}/config/base.bad.xml COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/base.xml ${CMAKE_CURRENT_BINARY_DIR}/config/base.xml COPYONLY) + +if( X11_XTest_FOUND ) + kde4_add_unit_test(keyboard_daemon_test TESTNAME kcm-keyboard-keyboard_daemon_test NOGUI keyboard_daemon_test.cpp ../keyboard_daemon.cpp ../layout_memory.cpp ../layout_memory_persister.cpp ../flags.cpp ../x11_helper.cpp ../xkb_helper.cpp ../xinput_helper.cpp ../layout_tray_icon.cpp ../keyboard_config.cpp ../xkb_rules.cpp ../keyboard_hardware.cpp ../bindings.cpp ../layouts_menu.cpp ../numlockx.c) + target_link_libraries(keyboard_daemon_test ${KDE4_KDEUI_LIBS} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} ${X11_Xkbfile_LIB} ${X11_XTest_LIB} ${X11_LIBRARIES} ${text_paint_LIB}) + if(XiGetDevicePresence_FOUND) + target_link_libraries(keyboard_daemon_test ${X11_Xinput_LIB}) + endif(XiGetDevicePresence_FOUND) +endif( X11_XTest_FOUND ) diff --git a/kcontrol/keyboard/tests/config/base.1.1.xml b/kcontrol/keyboard/tests/config/base.1.1.xml new file mode 100644 index 00000000..97206a0b --- /dev/null +++ b/kcontrol/keyboard/tests/config/base.1.1.xml @@ -0,0 +1,68 @@ + + + + + + + pc101 + Generic 101-key PC + Generic + + + + + + + us + USA + USA + eng + + + + + chr + Cherokee + chr + + + chr + Cherokee2 + + + + bad + Bad Variant Missing configItem tag + chr + + + + + + tw + + zh + Taiwanese + + fox + + + + + + + + + grp + Key(s) to change layout + + + + + + \ No newline at end of file diff --git a/kcontrol/keyboard/tests/config/base.bad.xml b/kcontrol/keyboard/tests/config/base.bad.xml new file mode 100644 index 00000000..75bacdd2 --- /dev/null +++ b/kcontrol/keyboard/tests/config/base.bad.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/kcontrol/keyboard/tests/config/base.xml b/kcontrol/keyboard/tests/config/base.xml new file mode 100644 index 00000000..ddab0561 --- /dev/null +++ b/kcontrol/keyboard/tests/config/base.xml @@ -0,0 +1,48 @@ + + + + + + + pc101 + Generic 101-key PC + Generic + + + + + + + us + USA + USA + eng + + + + + chr + Cherokee + chr + + + + + + + + + + grp + Key(s) to change layout + + + + + + \ No newline at end of file diff --git a/kcontrol/keyboard/tests/flags_test.cpp b/kcontrol/keyboard/tests/flags_test.cpp new file mode 100644 index 00000000..59f73716 --- /dev/null +++ b/kcontrol/keyboard/tests/flags_test.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "../flags.h" +#include "../xkb_rules.h" +#include "../keyboard_config.h" + + +static QImage image(const QIcon& icon) { + return icon.pixmap(QSize(16,16), QIcon::Normal, QIcon::On).toImage(); +} + +class FlagsTest : public QObject +{ + Q_OBJECT + + Flags* flags; + const Rules* rules; + +private Q_SLOTS: + void initTestCase() { + flags = new Flags(); + rules = NULL; + } + + void cleanupTestCase() { + delete flags; + delete rules; + } + + void testRules() { + QVERIFY( flags != NULL ); + + QVERIFY( ! flags->getTransparentPixmap().isNull() ); + + const QIcon iconUs(flags->getIcon("us")); + QVERIFY( ! iconUs.isNull() ); + QVERIFY( flags->getIcon("--").isNull() ); + + KeyboardConfig keyboardConfig; + LayoutUnit layoutUnit("us"); + LayoutUnit layoutUnit1("us", "intl"); + layoutUnit1.setDisplayName("usi"); + LayoutUnit layoutUnit2("us", "other"); + + keyboardConfig.indicatorType = KeyboardConfig::SHOW_FLAG; + const QIcon iconUsFlag = flags->getIconWithText(layoutUnit, keyboardConfig); + QVERIFY( ! iconUsFlag.isNull() ); + QCOMPARE( image(iconUsFlag), image(iconUs) ); + + keyboardConfig.indicatorType = KeyboardConfig::SHOW_LABEL; + const QIcon iconUsText = flags->getIconWithText(layoutUnit, keyboardConfig); + QVERIFY( ! iconUsText.isNull() ); + QVERIFY( image(iconUsText) != image(iconUs) ); + + keyboardConfig.layouts.append(layoutUnit1); + QCOMPARE( flags->getShortText(layoutUnit, keyboardConfig), QString("us") ); + QCOMPARE( flags->getShortText(layoutUnit1, keyboardConfig), QString("usi") ); + QCOMPARE( flags->getShortText(layoutUnit2, keyboardConfig), QString("us") ); + + const Rules* rules = Rules::readRules(Rules::NO_EXTRAS); + QCOMPARE( flags->getLongText(layoutUnit, rules), QString("English (US)") ); + QVERIFY( flags->getLongText(layoutUnit1, rules).startsWith("English (US, international with dead keys)") ); + QCOMPARE( flags->getLongText(layoutUnit2, rules), QString("other") ); + + rules = NULL; // when no rules found + QCOMPARE( flags->getLongText(layoutUnit1, rules), QString("us - intl") ); + + flags->clearCache(); + } + +// void loadRulesBenchmark() { +// QBENCHMARK { +// Flags* flags = new Flags(); +// delete flags; +// } +// } + +}; + +// need GUI for xkb protocol in xkb_rules.cpp +QTEST_KDEMAIN( FlagsTest, GUI ) + +#include "flags_test.moc" diff --git a/kcontrol/keyboard/tests/iso_codes_test.cpp b/kcontrol/keyboard/tests/iso_codes_test.cpp new file mode 100644 index 00000000..14f16be8 --- /dev/null +++ b/kcontrol/keyboard/tests/iso_codes_test.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "../iso_codes.h" + + +class IsoCodesTest : public QObject +{ + Q_OBJECT + + IsoCodes* isoCodes; + +private Q_SLOTS: + void initTestCase() { +// isoCodes = new IsoCodes(IsoCodes::iso_639); + isoCodes = new IsoCodes(IsoCodes::iso_639_3); + } + + void cleanupTestCase() { + delete isoCodes; + } + + void testIsoCodes() { + QVERIFY( isoCodes != NULL ); + QVERIFY( ! isoCodes->getEntryList().isEmpty() ); +// const IsoCodeEntry* isoEntry = isoCodes->getEntry(IsoCodes::attr_iso_639_2T_code, "eng"); + const IsoCodeEntry* isoEntry = isoCodes->getEntry(IsoCodes::attr_iso_639_3_id, "eng"); + QVERIFY( isoEntry != NULL ); + QVERIFY( ! isoEntry->empty() ); +// QCOMPARE( isoEntry->value(IsoCodes::attr_iso_639_2T_code), QString("eng") ); +// QCOMPARE( isoEntry->value(IsoCodes::attr_iso_639_2B_code), QString("eng") ); +// QCOMPARE( isoEntry->value(IsoCodes::attr_iso_639_1_code), QString("en") ); + QCOMPARE( isoEntry->value("name"), QString("English") ); +// QCOMPARE( isoEntry->value("status"), QString("Active") ); + } + + void testIso639_3_Codes() { + QVERIFY( isoCodes != NULL ); + QVERIFY( ! isoCodes->getEntryList().isEmpty() ); + const IsoCodeEntry* isoEntry = isoCodes->getEntry(IsoCodes::attr_iso_639_3_id, "ant"); + QVERIFY( isoEntry != NULL ); + QVERIFY( ! isoEntry->empty() ); + QVERIFY( isoEntry->value("name") != QString("ant") ); + QCOMPARE( isoEntry->value("name"), QString("Antakarinya") ); + } + + void loadIsoCodesBenchmark() { + QBENCHMARK { + IsoCodes* isoCodes = new IsoCodes(IsoCodes::iso_639_3); + delete isoCodes; + } + } + +}; + +//TODO: something lighter than KDEMAIN ? +QTEST_KDEMAIN( IsoCodesTest, NoGUI ) + +#include "iso_codes_test.moc" diff --git a/kcontrol/keyboard/tests/keyboard_daemon_test.cpp b/kcontrol/keyboard/tests/keyboard_daemon_test.cpp new file mode 100644 index 00000000..8879daf9 --- /dev/null +++ b/kcontrol/keyboard/tests/keyboard_daemon_test.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +//#include + +#include +#include + +#include "../flags.h" +#include "../xkb_rules.h" +#include "../keyboard_config.h" +#include "../keyboard_daemon.h" + + +class KeyboardDaemonTest : public QObject +{ + Q_OBJECT + + KeyboardDaemon* keyboardDaemon; +// KApplication* kapplication; + +private Q_SLOTS: + void initTestCase() { +// kapplication = new KApplication(); +// const KAboutData* kAboutData = new KAboutData(i18n("a").toAscii(), i18n("a").toAscii(), KLocalizedString(), i18n("a").toAscii()); +// KCmdLineArgs::init(kAboutData); + keyboardDaemon = new KeyboardDaemon(this, QList()); + } + + void cleanupTestCase() { + delete keyboardDaemon; +// delete kapplication; + } + + void testDaemon() { + QVERIFY( keyboardDaemon != NULL ); + +// QVERIFY( ! flags->getTransparentPixmap().isNull() ); +// +// const QIcon iconUs(flags->getIcon("us")); +// QVERIFY( ! iconUs.isNull() ); +// QVERIFY( flags->getIcon("--").isNull() ); +// +// KeyboardConfig keyboardConfig; +// LayoutUnit layoutUnit("us"); +// LayoutUnit layoutUnit1("us", "intl"); +// layoutUnit1.setDisplayName("usi"); +// LayoutUnit layoutUnit2("us", "other"); +// +// keyboardConfig.showFlag = true; +// const QIcon iconUsFlag = flags->getIconWithText(layoutUnit, keyboardConfig); +// QVERIFY( ! iconUsFlag.isNull() ); +// QCOMPARE( image(iconUsFlag), image(iconUs) ); +// +// keyboardConfig.showFlag = false; +// const QIcon iconUsText = flags->getIconWithText(layoutUnit, keyboardConfig); +// QVERIFY( ! iconUsText.isNull() ); +// QVERIFY( image(iconUsText) != image(iconUs) ); +// +// keyboardConfig.layouts.append(layoutUnit1); +// QCOMPARE( flags->getShortText(layoutUnit, keyboardConfig), QString("us") ); +// QCOMPARE( flags->getShortText(layoutUnit1, keyboardConfig), QString("usi") ); +// QCOMPARE( flags->getShortText(layoutUnit2, keyboardConfig), QString("us") ); +// +// const Rules* rules = Rules::readRules(); +// QCOMPARE( flags->getLongText(layoutUnit, rules), QString("USA") ); +// QVERIFY( flags->getLongText(layoutUnit1, rules).startsWith("USA - International") ); +// QCOMPARE( flags->getLongText(layoutUnit2, rules), QString("USA - other") ); +// +// flags->clearCache(); + } + +// void loadRulesBenchmark() { +// QBENCHMARK { +// Flags* flags = new Flags(); +// delete flags; +// } +// } + +}; + +// need GUI for xkb protocol in xkb_rules.cpp +QTEST_KDEMAIN( KeyboardDaemonTest, GUI ) + +#include "keyboard_daemon_test.moc" diff --git a/kcontrol/keyboard/tests/layout_memory_persister_test.cpp b/kcontrol/keyboard/tests/layout_memory_persister_test.cpp new file mode 100644 index 00000000..0dd0c74c --- /dev/null +++ b/kcontrol/keyboard/tests/layout_memory_persister_test.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "../layout_memory_persister.h" +#include "../layout_memory.h" +#include "../keyboard_config.h" + + +class TestLayoutMemory: public LayoutMemory { +public: + TestLayoutMemory(const KeyboardConfig& keyboardConfig): + LayoutMemory(keyboardConfig) {} + QMap& getLayoutMap() { return layoutMap; } +}; + +class LayoutMemoryPersisterTest : public QObject +{ + Q_OBJECT + + QString path; + KeyboardConfig keyboardConfig; + TestLayoutMemory* layoutMemory; + LayoutMemoryPersister* layoutMemoryPersister; + + const LayoutUnit layoutUnit1; + const LayoutUnit layoutUnit2; + const LayoutUnit layoutUnit3; + + +public: + LayoutMemoryPersisterTest(): + layoutUnit1("xx"), + layoutUnit2("yy", "var1"), + layoutUnit3("zz", "var2") + {} + +private Q_SLOTS: + void initTestCase() { + path = "keyboard_memory_test.xml"; + QFile(path).remove(); + + layoutMemory = new TestLayoutMemory(keyboardConfig); + layoutMemoryPersister = new LayoutMemoryPersister(*layoutMemory); + +// QFile(path).remove(); + } + + void cleanupTestCase() { + delete layoutMemoryPersister; + delete layoutMemory; + } + + void testSaveNA() { + QFile file(path); + + keyboardConfig.switchingPolicy = KeyboardConfig::SWITCH_POLICY_WINDOW; + QVERIFY( ! layoutMemoryPersister->saveToFile(file) ); + QVERIFY(QFile(path).size() == 0); + + QVERIFY( ! layoutMemoryPersister->restoreFromFile(file) ); + } + + void testSaveGlobal() { + QFile file(path); + + keyboardConfig.switchingPolicy = KeyboardConfig::SWITCH_POLICY_GLOBAL; + layoutMemoryPersister->setGlobalLayout(layoutUnit1); + QVERIFY( layoutMemoryPersister->saveToFile(file) ); + QVERIFY(QFile(path).size() > 0); +// file.close(); + + keyboardConfig.layouts.clear(); + + QVERIFY( layoutMemoryPersister->restoreFromFile(file) ); + QVERIFY( !layoutMemoryPersister->getGlobalLayout().isValid() ); + +// file.close(); + keyboardConfig.layouts << layoutUnit1; + QVERIFY( layoutMemoryPersister->restoreFromFile(file) ); + QVERIFY( layoutUnit1.isValid() ); + QVERIFY( layoutMemoryPersister->getGlobalLayout().isValid() ); + QCOMPARE( layoutMemoryPersister->getGlobalLayout(), layoutUnit1); + } + + void testSaveByApp() { + QFile file(path); + + keyboardConfig.switchingPolicy = KeyboardConfig::SWITCH_POLICY_APPLICATION; + + layoutMemoryPersister->setGlobalLayout(LayoutUnit()); + layoutMemory->getLayoutMap().clear(); + + keyboardConfig.layouts.clear(); + keyboardConfig.layouts << layoutUnit1 << layoutUnit2; + + LayoutSet layoutSet1; + layoutSet1.layouts << layoutUnit1 << layoutUnit2; + layoutSet1.currentLayout = layoutUnit1; + layoutMemory->getLayoutMap().insert(QString("app1"), layoutSet1); + + LayoutSet layoutSet2; + layoutSet2.layouts << layoutUnit2 << layoutUnit1 << layoutUnit3; + layoutSet2.currentLayout = layoutUnit2; + layoutMemory->getLayoutMap().insert(QString("app2"), layoutSet2); + + QVERIFY( layoutMemoryPersister->saveToFile(file) ); + QVERIFY(QFile(path).size() > 0); + file.close(); + + layoutMemory->getLayoutMap().clear(); + QVERIFY( ! layoutMemory->getLayoutMap().value("app1").isValid() ); + QVERIFY( ! layoutMemory->getLayoutMap().value("app2").isValid() ); + + QVERIFY( layoutMemoryPersister->restoreFromFile(file) ); + QVERIFY( ! layoutMemoryPersister->getGlobalLayout().isValid() ); + QCOMPARE( layoutMemory->getLayoutMap().value("app1"), layoutSet1 ); + QVERIFY( ! layoutMemory->getLayoutMap().value("app2").isValid() ); + + keyboardConfig.layouts << layoutUnit3; + + file.close(); + QVERIFY( layoutMemoryPersister->restoreFromFile(file) ); + QVERIFY( ! layoutMemoryPersister->getGlobalLayout().isValid() ); + QCOMPARE( layoutMemory->getLayoutMap().value("app1"), layoutSet1 ); + QCOMPARE( layoutMemory->getLayoutMap().value("app2"), layoutSet2 ); + } + +// void layoutMemroyPersisterBenchmark() { +// QBENCHMARK { +// //TODO: generate big map +// layoutMemoryPersister->save(); +// layoutMemoryPersister->restore(); +// } +// } + +}; + +// need GUI for xkb protocol +QTEST_KDEMAIN( LayoutMemoryPersisterTest, GUI ) + +#include "layout_memory_persister_test.moc" diff --git a/kcontrol/keyboard/tests/xkb_rules_test.cpp b/kcontrol/keyboard/tests/xkb_rules_test.cpp new file mode 100644 index 00000000..9cee188d --- /dev/null +++ b/kcontrol/keyboard/tests/xkb_rules_test.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2011 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "../xkb_rules.h" + +#include +#include + +static const Rules::ExtrasFlag readExtras = Rules::NO_EXTRAS; + +class RulesTest : public QObject +{ + Q_OBJECT + + Rules* rules; + +private Q_SLOTS: + void initTestCase() { + rules = Rules::readRules(readExtras); + } + + void cleanupTestCase() { + delete rules; + } + + void testRules() { + QVERIFY( rules != NULL ); + QVERIFY( rules->modelInfos.size() > 0 ); + QVERIFY( rules->layoutInfos.size() > 0 ); + QVERIFY( rules->optionGroupInfos.size() > 0 ); + } + + void testModel() { + foreach(const ModelInfo* modelInfo, rules->modelInfos) { + QVERIFY( modelInfo != NULL); + QVERIFY( modelInfo->name.length() > 0 ); + QVERIFY( modelInfo->description.length() > 0 ); +// QVERIFY( ! modelInfo->vendor.isEmpty() ); + } + } + + void testLayouts() { + foreach(const LayoutInfo* layoutInfo, rules->layoutInfos) { + QVERIFY( layoutInfo != NULL); + QVERIFY( ! layoutInfo->name.isEmpty() ); +// const char* desc = layoutInfo->name.toUtf8() ; +// qDebug() << layoutInfo->name; + QVERIFY( ! layoutInfo->description.isEmpty() ); + + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + QVERIFY( variantInfo != NULL ); + QVERIFY( ! variantInfo->name.isEmpty() ); + QVERIFY( ! variantInfo->description.isEmpty() ); + } + foreach(const QString& language, layoutInfo->languages) { + QVERIFY( ! language.isEmpty() ); + } + } + } + + void testOptionGroups() { + foreach(const OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { + QVERIFY( optionGroupInfo != NULL); + QVERIFY( ! optionGroupInfo->name.isEmpty() ); + QVERIFY( ! optionGroupInfo->description.isEmpty() ); + // optionGroupInfo->exclusive + + foreach(const OptionInfo* optionInfo, optionGroupInfo->optionInfos) { + QVERIFY( optionInfo != NULL ); + QVERIFY( ! optionInfo->name.isEmpty() ); + QVERIFY( ! optionInfo->description.isEmpty() ); + } + } + } + + void testExtras() { + Rules* rulesWithExtras = Rules::readRules(Rules::READ_EXTRAS); + QVERIFY2(rulesWithExtras->layoutInfos.size() > rules->layoutInfos.size(), "Rules with extras should have more layouts"); + + foreach(const LayoutInfo* layoutInfo, rules->layoutInfos) { + QVERIFY( ! layoutInfo->fromExtras ); + } + + bool foundFromExtras = false, foundNonExtras = false; + foreach(const LayoutInfo* layoutInfo, rulesWithExtras->layoutInfos) { + if( layoutInfo->fromExtras ) foundFromExtras = true; + if( ! layoutInfo->fromExtras ) foundNonExtras = true; + layoutInfo->languages.size(); // make sure we can access all merged objects + layoutInfo->variantInfos.size(); // make sure we can access all merged objects + } + QVERIFY( foundNonExtras ); + QVERIFY( foundFromExtras ); + } + + void testWriteNewXml() { + QDomDocument doc("xkbConfigRegistry"); + QDomElement root = doc.createElement("xkbConfigRegistry"); + root.setAttribute("version", "2.0"); + doc.appendChild(root); + + QDomElement modelList = doc.createElement("modelList"); + root.appendChild(modelList); + foreach(const ModelInfo* modelInfo, rules->modelInfos) { + QDomElement model = doc.createElement("model"); + model.setAttribute("name", modelInfo->name); + model.setAttribute("description", modelInfo->description); + model.setAttribute("vendor", modelInfo->vendor); + modelList.appendChild(model); + } + + QDomElement layoutList = doc.createElement("layoutList"); + foreach(const LayoutInfo* layoutInfo, rules->layoutInfos) { + QDomElement layout = doc.createElement("layout"); + layout.setAttribute("name", layoutInfo->name); + layout.setAttribute("description", layoutInfo->description); + + QDomElement langList = doc.createElement("languageList"); + foreach(const QString& lang, layoutInfo->languages) { + QDomElement langNode = doc.createElement("lang"); + langNode.setAttribute("iso639Id", lang); + langList.appendChild(langNode); + } + if( langList.hasChildNodes() ) { + layout.appendChild(langList); + } + + QDomElement variantList = doc.createElement("variantList"); + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + QDomElement variant = doc.createElement("variant"); + variant.setAttribute("name", variantInfo->name); + variant.setAttribute("description", variantInfo->description); + + QDomElement langList = doc.createElement("languageList"); + foreach(const QString& lang, variantInfo->languages) { + QDomElement langNode = doc.createElement("lang"); + langNode.setAttribute("iso639Id", lang); + langList.appendChild(langNode); + } + if( langList.hasChildNodes() ) { + variant.appendChild(langList); + } + + variantList.appendChild(variant); + } + if( variantList.hasChildNodes() ) { + layout.appendChild(variantList); + } + + layoutList.appendChild(layout); + } + root.appendChild(layoutList); + + QDomElement optionGroupList = doc.createElement("optionList"); + foreach(const OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { + QDomElement optionGroup = doc.createElement("optionGroup"); + optionGroup.setAttribute("name", optionGroupInfo->name); + optionGroup.setAttribute("description", optionGroupInfo->description); + optionGroup.setAttribute("exclusive", optionGroupInfo->exclusive); + + foreach(const OptionInfo* optionGroupInfo, optionGroupInfo->optionInfos) { + QDomElement option = doc.createElement("option"); + option.setAttribute("name", optionGroupInfo->name); + option.setAttribute("description", optionGroupInfo->description); + optionGroup.appendChild(option); + } + + optionGroupList.appendChild(optionGroup); + } + root.appendChild(optionGroupList); + + QFile file("base2.xml"); + if( ! file.open( QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text) ) { + kWarning() << "Failed to open layout memory xml file for writing" << file.fileName(); + QFAIL("failed"); + } + + QTextStream out(&file); + out << doc.toString(); + } + + void testRulesVersion() { + QVERIFY(!rules->version.isEmpty()); + + Rules* rules10 = new Rules(); + Rules::readRules(rules10, QString("config/base.xml"), false); + QCOMPARE(rules10->version, QString("1.0")); + delete rules10; + + Rules* rules11 = new Rules(); + Rules::readRules(rules11, QString("config/base.1.1.xml"), false); + QCOMPARE(rules11->version, QString("1.1")); + + foreach(const LayoutInfo* layoutInfo, rules11->layoutInfos) { + QVERIFY( layoutInfo != NULL); + QVERIFY( ! layoutInfo->name.isEmpty() ); + QVERIFY( ! layoutInfo->description.isEmpty() ); + + foreach(const VariantInfo* variantInfo, layoutInfo->variantInfos) { + QVERIFY( variantInfo != NULL ); + QVERIFY( ! variantInfo->name.isEmpty() ); + QVERIFY( ! variantInfo->description.isEmpty() ); + } + } + + delete rules11; + } + + void loadRulesBenchmark() { + QBENCHMARK { + Rules* rules = Rules::readRules(readExtras); + delete rules; + } + } + +}; + +// need kde libs for config-workspace.h used in xkb_rules.cpp +// need GUI for xkb protocol +QTEST_KDEMAIN( RulesTest, GUI ) + +#include "xkb_rules_test.moc" diff --git a/kcontrol/keyboard/x11_helper.cpp b/kcontrol/keyboard/x11_helper.cpp new file mode 100644 index 00000000..f8060fb2 --- /dev/null +++ b/kcontrol/keyboard/x11_helper.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "x11_helper.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + + +// more information about the limit https://bugs.freedesktop.org/show_bug.cgi?id=19501 +int X11Helper::MAX_GROUP_COUNT = 4; +int X11Helper::ARTIFICIAL_GROUP_LIMIT_COUNT = 8; + +const char* X11Helper::LEFT_VARIANT_STR = "("; +const char* X11Helper::RIGHT_VARIANT_STR = ")"; + +bool X11Helper::xkbSupported(int* xkbOpcode) +{ + // Verify the Xlib has matching XKB extension. + + int major = XkbMajorVersion; + int minor = XkbMinorVersion; + + if (!XkbLibraryVersion(&major, &minor)) + { + kWarning() << "Xlib XKB extension " << major << '.' << minor << + " != " << XkbMajorVersion << '.' << XkbMinorVersion; + return false; + } + + // Verify the X server has matching XKB extension. + + int opcode_rtrn; + int error_rtrn; + int xkb_opcode; + if( ! XkbQueryExtension(QX11Info::display(), &opcode_rtrn, &xkb_opcode, &error_rtrn, &major, &minor)) { + kWarning() << "X server XKB extension " << major << '.' << minor << + " != " << XkbMajorVersion << '.' << XkbMinorVersion; + return false; + } + + if( xkbOpcode != NULL ) { + *xkbOpcode = xkb_opcode; + } + + return true; +} + +void X11Helper::switchToNextLayout() +{ + int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count + int group = (X11Helper::getGroup() + 1) % size; + X11Helper::setGroup(group); +} + +void X11Helper::scrollLayouts(int delta) +{ + int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count + int group = X11Helper::getGroup() + delta; + group = group < 0 ? size - ((-group) % size) : group % size; + + X11Helper::setGroup(group); +} + +QStringList X11Helper::getLayoutsListAsString(const QList& layoutsList) +{ + QStringList stringList; + foreach(const LayoutUnit& layoutUnit, layoutsList) { + stringList << layoutUnit.toString(); + } + return stringList; +} + +bool X11Helper::setLayout(const LayoutUnit& layout) +{ + QList currentLayouts = getLayoutsList(); + int idx = currentLayouts.indexOf(layout); + if( idx == -1 || idx >= X11Helper::MAX_GROUP_COUNT ) { + kWarning() << "Layout" << layout.toString() << "is not found in current layout list" + << getLayoutsListAsString(currentLayouts); + return false; + } + + return X11Helper::setGroup((unsigned int)idx); +} + +bool X11Helper::setDefaultLayout() { + return X11Helper::setGroup(0); +} + +bool X11Helper::isDefaultLayout() { + return X11Helper::getGroup() == 0; +} + +LayoutUnit X11Helper::getCurrentLayout() +{ + QList currentLayouts = getLayoutsList(); + unsigned int group = X11Helper::getGroup(); + if( group < (unsigned int)currentLayouts.size() ) + return currentLayouts[group]; + + kWarning() << "Current group number" << group << "is outside of current layout list" << + getLayoutsListAsString(currentLayouts); + return LayoutUnit(); +} + +LayoutSet X11Helper::getCurrentLayouts() +{ + LayoutSet layoutSet; + + QList currentLayouts = getLayoutsList(); + layoutSet.layouts = currentLayouts; + + unsigned int group = X11Helper::getGroup(); + if( group < (unsigned int)currentLayouts.size() ) { + layoutSet.currentLayout = currentLayouts[group]; + } + else { + kWarning() << "Current group number" << group << "is outside of current layout list" << getLayoutsListAsString(currentLayouts); + layoutSet.currentLayout = LayoutUnit(); + } + + return layoutSet; +} + + +//static QString addNum(const QString& str, int n) +//{ +// QString format("%1%2"); +// if( str.length() >= 3 ) return format.arg(str.left(2)).arg(n); +// return format.arg(str).arg(n); +//} + +QList X11Helper::getLayoutsList() +{ + XkbConfig xkbConfig; + QList layouts; + if( X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::LAYOUTS_ONLY) ) { + for(int i=0; i 0) || (real_prop_type != XA_STRING) || (fmt != 8)) { + if (prop_data) + XFree(prop_data); + kWarning() << "Failed to fetch layouts from server:" << "Wrong property format"; + return false; + } + +// qDebug() << "prop_data:" << nitems << prop_data; + QStringList names; + for(char* p=prop_data; p-prop_data < (long)nitems && p != NULL; p += strlen(p)+1) { + names.append( p ); +// kDebug() << " " << p; + } + + if( names.count() < 4 ) { //{ rules, model, layouts, variants, options } + XFree(prop_data); + return false; + } + + if( fetchType == ALL || fetchType == LAYOUTS_ONLY ) { + QStringList layouts = names[2].split(OPTIONS_SEPARATOR); + QStringList variants = names[3].split(OPTIONS_SEPARATOR); + + for(int ii=0; iilayouts << (layouts[ii] != NULL ? layouts[ii] : ""); + xkbConfig->variants << (ii < variants.count() && variants[ii] != NULL ? variants[ii] : ""); + } + kDebug() << "Fetched layout groups from X server:" + << "\tlayouts:" << xkbConfig->layouts + << "\tvariants:" << xkbConfig->variants; + } + + if( fetchType == ALL || fetchType == MODEL_ONLY ) { + xkbConfig->keyboardModel = (names[1] != NULL ? names[1] : ""); + kDebug() << "Fetched keyboard model from X server:" << xkbConfig->keyboardModel; + } + + if( fetchType == ALL ) { + if( names.count() >= 5 ) { + QString options = (names[4] != NULL ? names[4] : ""); + xkbConfig->options = options.split(OPTIONS_SEPARATOR); + kDebug() << "Fetched xkbOptions from X server:" << options; + } + } + + XFree(prop_data); + return true; +} + +XEventNotifier::XEventNotifier(QWidget* parent): + QWidget(parent), + xkbOpcode(-1) +{ + if( KApplication::kApplication() == NULL ) { + kWarning() << "Layout Widget won't work properly without KApplication instance"; + } +} + +void XEventNotifier::start() +{ + if( KApplication::kApplication() != NULL && X11Helper::xkbSupported(&xkbOpcode) ) { + registerForXkbEvents(QX11Info::display()); + + // start the event loop + KApplication::kApplication()->installX11EventFilter(this); + } +} + +void XEventNotifier::stop() +{ + if( KApplication::kApplication() != NULL ) { + //TODO: unregister + // XEventNotifier::unregisterForXkbEvents(QX11Info::display()); + + // stop the event loop + KApplication::kApplication()->removeX11EventFilter(this); + } +} + +bool XEventNotifier::isXkbEvent(XEvent* event) +{ + return event->type == xkbOpcode; +} + +bool XEventNotifier::processOtherEvents(XEvent* /*event*/) +{ + return true; +} + +bool XEventNotifier::processXkbEvents(XEvent* event) +{ + if( XEventNotifier::isGroupSwitchEvent(event) ) { + emit(layoutChanged()); + } + else if( XEventNotifier::isLayoutSwitchEvent(event) ) { + emit(layoutMapChanged()); + } + return true; +} + +bool XEventNotifier::x11Event(XEvent * event) +{ + // qApp->x11ProcessEvent ( event ); + if( isXkbEvent(event) ) { + processXkbEvents(event); + } + else { + processOtherEvents(event); + } + return QWidget::x11Event(event); +} + +bool XEventNotifier::isGroupSwitchEvent(XEvent* event) +{ + XkbEvent *xkbEvent = (XkbEvent*) event; +#define GROUP_CHANGE_MASK \ + ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask ) + + return xkbEvent->any.xkb_type == XkbStateNotify && (xkbEvent->state.changed & GROUP_CHANGE_MASK); +} + +bool XEventNotifier::isLayoutSwitchEvent(XEvent* event) +{ + XkbEvent *xkbEvent = (XkbEvent*) event; + + return //( (xkbEvent->any.xkb_type == XkbMapNotify) && (xkbEvent->map.changed & XkbKeySymsMask) ) || +/* || ( (xkbEvent->any.xkb_type == XkbNamesNotify) && (xkbEvent->names.changed & XkbGroupNamesMask) || )*/ + (xkbEvent->any.xkb_type == XkbNewKeyboardNotify); +} + +int XEventNotifier::registerForXkbEvents(Display* display) +{ + int eventMask = XkbNewKeyboardNotifyMask | XkbStateNotifyMask; + if( ! XkbSelectEvents(display, XkbUseCoreKbd, eventMask, eventMask) ) { + kWarning() << "Couldn't select desired XKB events"; + return false; + } + return true; +} + + +static const char* LAYOUT_VARIANT_SEPARATOR_PREFIX = "("; +static const char* LAYOUT_VARIANT_SEPARATOR_SUFFIX = ")"; + +static QString& stripVariantName(QString& variant) +{ + if( variant.endsWith(LAYOUT_VARIANT_SEPARATOR_SUFFIX) ) { + int suffixLen = strlen(LAYOUT_VARIANT_SEPARATOR_SUFFIX); + return variant.remove(variant.length()-suffixLen, suffixLen); + } + return variant; +} + +LayoutUnit::LayoutUnit(const QString& fullLayoutName) +{ + QStringList lv = fullLayoutName.split(LAYOUT_VARIANT_SEPARATOR_PREFIX); + layout = lv[0]; + variant = lv.size() > 1 ? stripVariantName(lv[1]) : ""; +} + +QString LayoutUnit::toString() const +{ + if( variant.isEmpty() ) + return layout; + + return layout + LAYOUT_VARIANT_SEPARATOR_PREFIX+variant+LAYOUT_VARIANT_SEPARATOR_SUFFIX; +} + +const int LayoutUnit::MAX_LABEL_LENGTH = 3; diff --git a/kcontrol/keyboard/x11_helper.h b/kcontrol/keyboard/x11_helper.h new file mode 100644 index 00000000..69490d64 --- /dev/null +++ b/kcontrol/keyboard/x11_helper.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef X11_HELPER_H_ +#define X11_HELPER_H_ + +#include +#include +#include +#include + + +class XEventNotifier : public QWidget { + Q_OBJECT + +Q_SIGNALS: + void layoutChanged(); + void layoutMapChanged(); + +public: + XEventNotifier(QWidget* parent=NULL); + virtual ~XEventNotifier() {} + + virtual void start(); + virtual void stop(); + +protected: + bool x11Event(XEvent * e); + virtual bool processOtherEvents(XEvent* e); + virtual bool processXkbEvents(XEvent* e); + +private: + int registerForXkbEvents(Display* display); + bool isXkbEvent(XEvent* event); + bool isGroupSwitchEvent(XEvent* event); + bool isLayoutSwitchEvent(XEvent* event); + + int xkbOpcode; +}; + +struct XkbConfig { + QString keyboardModel; + QStringList layouts; + QStringList variants; + QStringList options; + + bool isValid() { return ! layouts.empty(); } +}; + + +struct LayoutUnit { + static const int MAX_LABEL_LENGTH; + + //TODO: move these to private? + QString layout; + QString variant; + + LayoutUnit() {} + explicit LayoutUnit(const QString& fullLayoutName); + LayoutUnit(const QString& layout_, const QString& variant_) { + layout = layout_; + variant = variant_; + } + /*explicit*/ LayoutUnit(const LayoutUnit& layoutUnit) { + layout = layoutUnit.layout; + variant = layoutUnit.variant; + displayName = layoutUnit.displayName; + shortcut = layoutUnit.shortcut; + } + + QString getRawDisplayName() const { return displayName; } + QString getDisplayName() const { return !displayName.isEmpty() ? displayName : layout; } + void setDisplayName(const QString& name) { displayName = name; } + + void setShortcut(const QKeySequence& shortcut) { this->shortcut = shortcut; } + QKeySequence getShortcut() const { return shortcut; } + + bool isEmpty() const { return layout.isEmpty(); } + bool isValid() const { return ! isEmpty(); } + bool operator==(const LayoutUnit& layoutItem) const { + return layout==layoutItem.layout && variant==layoutItem.variant; + } + bool operator!=(const LayoutUnit& layoutItem) const { + return ! (*this == layoutItem); + } + QString toString() const; + +private: + QString displayName; + QKeySequence shortcut; +}; + +struct LayoutSet { + QList layouts; + LayoutUnit currentLayout; + + LayoutSet() {} + + LayoutSet(const LayoutSet& currentLayouts) { + this->layouts = currentLayouts.layouts; + this->currentLayout = currentLayouts.currentLayout; + } + + bool isValid() const { + return currentLayout.isValid() && layouts.contains(currentLayout); + } + + bool operator == (const LayoutSet& currentLayouts) const { + return this->layouts == currentLayouts.layouts + && this->currentLayout == currentLayouts.currentLayout; + } + + LayoutSet& operator = (const LayoutSet& currentLayouts) { + this->layouts = currentLayouts.layouts; + this->currentLayout = currentLayouts.currentLayout; + return *this; + } + + QString toString() const { + QString str(currentLayout.toString()); + str += ": "; + foreach(const LayoutUnit& layoutUnit, layouts) { + str += layoutUnit.toString() + " "; + } + return str; + } + + static QString toString(const QList& layoutUnits) { + QString str; + foreach(const LayoutUnit& layoutUnit, layoutUnits) { + str += layoutUnit.toString() + ","; + } + return str; + } +}; + +class X11Helper +{ +public: + static int MAX_GROUP_COUNT; + static int ARTIFICIAL_GROUP_LIMIT_COUNT; + + static const char* LEFT_VARIANT_STR; + static const char* RIGHT_VARIANT_STR; + + static bool xkbSupported(int* xkbOpcode); + + static void switchToNextLayout(); + static void scrollLayouts(int delta); + static bool isDefaultLayout(); + static bool setDefaultLayout(); + static bool setLayout(const LayoutUnit& layout); + static LayoutUnit getCurrentLayout(); + static LayoutSet getCurrentLayouts(); + static QList getLayoutsList(); + static QStringList getLayoutsListAsString(const QList& layoutsList); + + enum FetchType { ALL, LAYOUTS_ONLY, MODEL_ONLY }; + static bool getGroupNames(Display* dpy, XkbConfig* xkbConfig, FetchType fetchType); + +private: + static unsigned int getGroup(); + static bool setGroup(unsigned int group); +}; + +#endif /* X11_HELPER_H_ */ diff --git a/kcontrol/keyboard/xinput_helper.cpp b/kcontrol/keyboard/xinput_helper.cpp new file mode 100644 index 00000000..2a10f340 --- /dev/null +++ b/kcontrol/keyboard/xinput_helper.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "xinput_helper.h" + +#include +#include + +#include + +#include +#include +#include + +#ifdef HAVE_XINPUT_AND_DEVICE_NOTIFY +#include +#endif + +#include + +#include "x11_helper.h" + +#include + +static int DEVICE_NONE = 0; +static int DEVICE_KEYBOARD = 1; +static int DEVICE_POINTER = 2; + +XInputEventNotifier::XInputEventNotifier(QWidget* parent): + XEventNotifier(parent), + xinputEventType(-1) +{ +} + +void XInputEventNotifier::start() +{ + if( KApplication::kApplication() != NULL ) { + registerForNewDeviceEvent(QX11Info::display()); + } + + XEventNotifier::start(); +} + +void XInputEventNotifier::stop() +{ + XEventNotifier::stop(); + + if( KApplication::kApplication() != NULL ) { + // XEventNotifier::unregisterForNewDeviceEvent(QX11Info::display()); + } +} + +bool XInputEventNotifier::processOtherEvents(XEvent* event) +{ + int newDeviceType = getNewDeviceEventType(event); + if( newDeviceType == DEVICE_KEYBOARD ) { + emit(newKeyboardDevice()); + } + else if( newDeviceType == DEVICE_POINTER ) { + emit(newPointerDevice()); + emit(newKeyboardDevice()); // arghhh, looks like X resets xkb map even when only pointer device is connected + } + return true; +} + + +#ifdef HAVE_XINPUT_AND_DEVICE_NOTIFY + +extern "C" { + extern int _XiGetDevicePresenceNotifyEvent(Display *); +} + +// This is ugly but allows to skip multiple execution of setxkbmap +// for all keyboard devices that don't care about layouts +static bool isRealKeyboard(const char* deviceName) +{ + return strstr(deviceName, "Video Bus") == NULL + && strstr(deviceName, "Sleep Button") == NULL + && strstr(deviceName, "Power Button") == NULL + && strstr(deviceName, "WMI hotkeys") == NULL; +} + +int XInputEventNotifier::getNewDeviceEventType(XEvent* event) +{ + int newDeviceType = DEVICE_NONE; + + if( xinputEventType != -1 && event->type == xinputEventType ) { + XDevicePresenceNotifyEvent *xdpne = (XDevicePresenceNotifyEvent*) event; + if( xdpne->devchange == DeviceEnabled ) { + int ndevices; + XDeviceInfo *devices = XListInputDevices(xdpne->display, &ndevices); + if( devices != NULL ) { +// kDebug() << "New device id:" << xdpne->deviceid; + for(int i=0; ideviceid ) { + if( devices[i].use == IsXKeyboard || devices[i].use == IsXExtensionKeyboard ) { + if( isRealKeyboard(devices[i].name) ) { + newDeviceType = DEVICE_KEYBOARD; + kDebug() << "new keyboard device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use; + break; + } + } + if( devices[i].use == IsXPointer || devices[i].use == IsXExtensionPointer ) { + newDeviceType = DEVICE_POINTER; + kDebug() << "new pointer device, id:" << devices[i].id << "name:" << devices[i].name << "used as:" << devices[i].use; + break; + } + } + } + XFreeDeviceList(devices); + } + } + } + return newDeviceType; +} + +int XInputEventNotifier::registerForNewDeviceEvent(Display* display) +{ + int xitype; + XEventClass xiclass; + + DevicePresence(display, xitype, xiclass); + XSelectExtensionEvent(display, DefaultRootWindow(display), &xiclass, 1); + kDebug() << "Registered for new device events from XInput, class" << xitype; + xinputEventType = xitype; + return xitype; +} + +#else + +#ifdef __GNUC__ +#warning "Keyboard daemon is compiled without XInput, keyboard settings will be reset when new keyboard device is plugged in!" +#endif + +int XInputEventNotifier::registerForNewDeviceEvent(Display* /*display*/) +{ + kWarning() << "Keyboard kded daemon is compiled without XInput, xkb configuration will be reset when new keyboard device is plugged in!"; + return -1; +} + +int XInputEventNotifier::getNewDeviceEventType(XEvent* /*event*/) +{ + return DEVICE_NONE; +} + +#endif diff --git a/kcontrol/keyboard/xinput_helper.h b/kcontrol/keyboard/xinput_helper.h new file mode 100644 index 00000000..92f1eb65 --- /dev/null +++ b/kcontrol/keyboard/xinput_helper.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef XINPUT_HELPER_H_ +#define XINPUT_HELPER_H_ + +#include "x11_helper.h" + + +class XInputEventNotifier: public XEventNotifier { + Q_OBJECT + +public: + XInputEventNotifier(QWidget* parent=NULL); + + void start(); + void stop(); + + int registerForNewDeviceEvent(Display* dpy); + +Q_SIGNALS: + void newKeyboardDevice(); + void newPointerDevice(); + +protected: + bool processOtherEvents(XEvent* event); + +private: + int getNewDeviceEventType(XEvent* event); + + int xinputEventType; +}; + +#endif /* XINPUT_HELPER_H_ */ diff --git a/kcontrol/keyboard/xkb_helper.cpp b/kcontrol/keyboard/xkb_helper.cpp new file mode 100644 index 00000000..60bf5a8f --- /dev/null +++ b/kcontrol/keyboard/xkb_helper.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "xkb_helper.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "keyboard_config.h" + + +static const char* SETXKBMAP_EXEC = "setxkbmap"; +static const char* XMODMAP_EXEC = "xmodmap"; + +static bool setxkbmapNotFound = false; +static QString setxkbmapExe; + +static bool xmodmapNotFound = false; +static QString xmodmapExe; + +static const QString COMMAND_OPTIONS_SEPARATOR(","); + +static +QString getSetxkbmapExe() +{ + if( setxkbmapNotFound ) + return ""; + + if( setxkbmapExe.isEmpty() ) { + setxkbmapExe = KGlobal::dirs()->findExe(SETXKBMAP_EXEC); + if( setxkbmapExe.isEmpty() ) { + setxkbmapNotFound = true; + kError() << "Can't find" << SETXKBMAP_EXEC << "- keyboard layouts won't be configured"; + return ""; + } + } + return setxkbmapExe; +} + +static +void executeXmodmap(const QString& configFileName) +{ + if( xmodmapNotFound ) + return; + + if( QFile(configFileName).exists() ) { + if( xmodmapExe.isEmpty() ) { + xmodmapExe = KGlobal::dirs()->findExe(XMODMAP_EXEC); + if( xmodmapExe.isEmpty() ) { + xmodmapNotFound = true; + kError() << "Can't find" << XMODMAP_EXEC << "- xmodmap files won't be run"; + return; + } + } + + KProcess xmodmapProcess; + xmodmapProcess << xmodmapExe; + xmodmapProcess << configFileName; + kDebug() << "Executing" << xmodmapProcess.program().join(" "); + if( xmodmapProcess.execute() != 0 ) { + kError() << "Failed to execute " << xmodmapProcess.program(); + } + } +} + +static +void restoreXmodmap() +{ + // TODO: is just home .Xmodmap enough or should system be involved too? + // QString configFileName = QDir("/etc/X11/xinit").filePath(".Xmodmap"); + // executeXmodmap(configFileName); + QString configFileName = QDir::home().filePath(".Xmodmap"); + executeXmodmap(configFileName); +} + +//TODO: make private +bool XkbHelper::runConfigLayoutCommand(const QStringList& setxkbmapCommandArguments) +{ + QTime timer; + timer.start(); + + KProcess setxkbmapProcess; + setxkbmapProcess << getSetxkbmapExe() << setxkbmapCommandArguments; + int res = setxkbmapProcess.execute(); + + if( res == 0 ) { // restore Xmodmap mapping reset by setxkbmap + kDebug() << "Executed successfully in " << timer.elapsed() << "ms" << setxkbmapProcess.program().join(" "); + restoreXmodmap(); + kDebug() << "\t and with xmodmap" << timer.elapsed() << "ms"; + return true; + } + else { + kError() << "Failed to run" << setxkbmapProcess.program().join(" ") << "return code:" << res; + } + return false; +} + +bool XkbHelper::initializeKeyboardLayouts(const QList& layoutUnits) +{ + QStringList layouts; + QStringList variants; + foreach (const LayoutUnit& layoutUnit, layoutUnits) { + layouts.append(layoutUnit.layout); + variants.append(layoutUnit.variant); + } + + QStringList setxkbmapCommandArguments; + setxkbmapCommandArguments.append("-layout"); + setxkbmapCommandArguments.append(layouts.join(COMMAND_OPTIONS_SEPARATOR)); + if( ! variants.join("").isEmpty() ) { + setxkbmapCommandArguments.append("-variant"); + setxkbmapCommandArguments.append(variants.join(COMMAND_OPTIONS_SEPARATOR)); + } + + return runConfigLayoutCommand(setxkbmapCommandArguments); +} + +bool XkbHelper::initializeKeyboardLayouts(KeyboardConfig& config) +{ + QStringList setxkbmapCommandArguments; + if( ! config.keyboardModel.isEmpty() ) { + XkbConfig xkbConfig; + X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::MODEL_ONLY); + if( xkbConfig.keyboardModel != config.keyboardModel ) { + setxkbmapCommandArguments.append("-model"); + setxkbmapCommandArguments.append(config.keyboardModel); + } + } + if( config.configureLayouts ) { + QStringList layouts; + QStringList variants; + QList defaultLayouts = config.getDefaultLayouts(); + foreach (const LayoutUnit& layoutUnit, defaultLayouts) { + layouts.append(layoutUnit.layout); + variants.append(layoutUnit.variant); + } + + setxkbmapCommandArguments.append("-layout"); + setxkbmapCommandArguments.append(layouts.join(COMMAND_OPTIONS_SEPARATOR)); + if( ! variants.join("").isEmpty() ) { + setxkbmapCommandArguments.append("-variant"); + setxkbmapCommandArguments.append(variants.join(COMMAND_OPTIONS_SEPARATOR)); + } + } + if( config.resetOldXkbOptions ) { + setxkbmapCommandArguments.append("-option"); + } + if( ! config.xkbOptions.isEmpty() ) { + setxkbmapCommandArguments.append("-option"); + setxkbmapCommandArguments.append(config.xkbOptions.join(COMMAND_OPTIONS_SEPARATOR)); + } + + if( ! setxkbmapCommandArguments.isEmpty() ) { + return runConfigLayoutCommand(setxkbmapCommandArguments); + if( config.configureLayouts ) { + X11Helper::setDefaultLayout(); + } + } + return false; +} diff --git a/kcontrol/keyboard/xkb_helper.h b/kcontrol/keyboard/xkb_helper.h new file mode 100644 index 00000000..5e4f94d2 --- /dev/null +++ b/kcontrol/keyboard/xkb_helper.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef XKB_HELPER_H_ +#define XKB_HELPER_H_ + +template class QList; +class LayoutUnit; +class QStringList; +class KeyboardConfig; + +class XkbHelper { +public: + static bool initializeKeyboardLayouts(KeyboardConfig& config); + static bool initializeKeyboardLayouts(const QList& layouts); + static bool runConfigLayoutCommand(const QStringList& setxkbmapCommandArguments); +}; + +#endif /* XKB_HELPER_H_ */ diff --git a/kcontrol/keyboard/xkb_rules.cpp b/kcontrol/keyboard/xkb_rules.cpp new file mode 100644 index 00000000..616e7b84 --- /dev/null +++ b/kcontrol/keyboard/xkb_rules.cpp @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "xkb_rules.h" + +#include +#include +#include + +#include +#include +#include // for Qt::escape +#include +#include + +//#include +//#include + +#include "x11_helper.h" + +// for findXkbRuleFile +#include +#include +#include +#include +#include +#include +#include + + +class RulesHandler : public QXmlDefaultHandler +{ +public: + RulesHandler(Rules* rules_, bool fromExtras_): + rules(rules_), + fromExtras(fromExtras_){} + + bool startElement(const QString &namespaceURI, const QString &localName, + const QString &qName, const QXmlAttributes &attributes); + bool endElement(const QString &namespaceURI, const QString &localName, + const QString &qName); + bool characters(const QString &str); +// bool fatalError(const QXmlParseException &exception); +// QString errorString() const; + +private: +// QString getString(const QString& text); + + QStringList path; + Rules* rules; + const bool fromExtras; +}; + +static QString translate_xml_item(const QString& itemText) +{ + return i18n(Qt::escape(itemText).toUtf8()); + // return QString::fromUtf8(dgettext("xkeyboard-config", itemText.toAscii())); +} + +static QString translate_description(ConfigItem* item) +{ + return item->description.isEmpty() + ? item->name : translate_xml_item(item->description); +} + +static bool notEmpty(const ConfigItem* item) +{ + return ! item->name.isEmpty(); +} + +template +void removeEmptyItems(QList& list) +{ + QtConcurrent::blockingFilter(list, notEmpty); +} + +static +void postProcess(Rules* rules) +{ + //TODO remove elements with empty names to safeguard us + removeEmptyItems(rules->layoutInfos); + removeEmptyItems(rules->modelInfos); + removeEmptyItems(rules->optionGroupInfos); + + KGlobal::locale()->insertCatalog("xkeyboard-config"); +// setlocale(LC_ALL, ""); +// bindtextdomain("xkeyboard-config", LOCALE_DIR); + foreach(ModelInfo* modelInfo, rules->modelInfos) { + modelInfo->vendor = translate_xml_item(modelInfo->vendor); + modelInfo->description = translate_description(modelInfo); + } + + foreach(LayoutInfo* layoutInfo, rules->layoutInfos) { + layoutInfo->description = translate_description(layoutInfo); + + removeEmptyItems(layoutInfo->variantInfos); + foreach(VariantInfo* variantInfo, layoutInfo->variantInfos) { + variantInfo->description = translate_description(variantInfo); + } + } + foreach(OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { + optionGroupInfo->description = translate_description(optionGroupInfo); + + removeEmptyItems(optionGroupInfo->optionInfos); + foreach(OptionInfo* optionInfo, optionGroupInfo->optionInfos) { + optionInfo->description = translate_description(optionInfo); + } + } + KGlobal::locale()->removeCatalog("xkeyboard-config"); +} + + +Rules::Rules(): + version("1.0") +{ +} + +QString Rules::getRulesName() +{ + XkbRF_VarDefsRec vd; + char *tmp = NULL; + + if (XkbRF_GetNamesProp(QX11Info::display(), &tmp, &vd) && tmp != NULL ) { + // qDebug() << "namesprop" << tmp ; + const QString name(tmp); + XFree(tmp); + return name; + } + + return QString::null; +} + +static QString findXkbRulesFile() +{ + QString rulesFile; + QString rulesName = Rules::getRulesName(); + + if ( ! rulesName.isNull() ) { + QString xkbParentDir; + + QString base(XLIBDIR); + if( base.count('/') >= 3 ) { + // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb + QString delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11"; + QDir baseDir(base + delta); + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + else { + QDir baseDir(base + "/X11"); // .../usr/X11/lib/X11/xkb (old XFree) + if( baseDir.exists() ) { + xkbParentDir = baseDir.absolutePath(); + } + } + } + + if( xkbParentDir.isEmpty() ) { + xkbParentDir = "/usr/share/X11"; + } + + rulesFile = QString("%1/xkb/rules/%2.xml").arg(xkbParentDir, rulesName); + } + + return rulesFile; +} + +static +void mergeRules(Rules* rules, Rules* extraRules) +{ + rules->modelInfos.append( extraRules->modelInfos ); + rules->optionGroupInfos.append( extraRules->optionGroupInfos ); // need to iterate and merge? + + QList layoutsToAdd; + foreach(LayoutInfo* extraLayoutInfo, extraRules->layoutInfos) { + LayoutInfo* layoutInfo = findByName(rules->layoutInfos, extraLayoutInfo->name); + if( layoutInfo != NULL ) { + layoutInfo->variantInfos.append( extraLayoutInfo->variantInfos ); + layoutInfo->languages.append( extraLayoutInfo->languages ); + } + else { + layoutsToAdd.append(extraLayoutInfo); + } + } + rules->layoutInfos.append(layoutsToAdd); + kDebug() << "Merged from extra rules:" << extraRules->layoutInfos.size() << "layouts," << extraRules->modelInfos.size() << "models," << extraRules->optionGroupInfos.size() << "option groups"; + + // base rules now own the objects - remove them from extra rules so that it does not try to delete them + extraRules->layoutInfos.clear(); + extraRules->modelInfos.clear(); + extraRules->optionGroupInfos.clear(); +} + + +const char Rules::XKB_OPTION_GROUP_SEPARATOR = ':'; + +Rules* Rules::readRules(ExtrasFlag extrasFlag) +{ + Rules* rules = new Rules(); + QString rulesFile = findXkbRulesFile(); + if( ! readRules(rules, rulesFile, false) ) { + delete rules; + return NULL; + } + if( extrasFlag == Rules::READ_EXTRAS ) { + QRegExp regex("\\.xml$"); + Rules* rulesExtra = new Rules(); + QString extraRulesFile = rulesFile.replace(regex, ".extras.xml"); + if( readRules(rulesExtra, extraRulesFile, true) ) { // not fatal if it fails + mergeRules(rules, rulesExtra); + } + delete rulesExtra; + } + return rules; +} + + +Rules* Rules::readRules(Rules* rules, const QString& filename, bool fromExtras) +{ + QFile file(filename); + if( !file.open(QFile::ReadOnly | QFile::Text) ) { + kError() << "Cannot open the rules file" << file.fileName(); + return NULL; + } + + RulesHandler rulesHandler(rules, fromExtras); + + QXmlSimpleReader reader; + reader.setContentHandler(&rulesHandler); + reader.setErrorHandler(&rulesHandler); + + QXmlInputSource xmlInputSource(&file); + + kDebug() << "Parsing xkb rules from" << file.fileName(); + + if( ! reader.parse(xmlInputSource) ) { + kError() << "Failed to parse the rules file" << file.fileName(); + delete rules; + return NULL; + } + + postProcess(rules); + + return rules; +} + +bool RulesHandler::startElement(const QString &/*namespaceURI*/, const QString &/*localName*/, + const QString &qName, const QXmlAttributes &attributes) +{ + path << QString(qName); + + QString strPath = path.join("/"); + if( strPath.endsWith("layoutList/layout/configItem") ) { + rules->layoutInfos << new LayoutInfo(fromExtras); + } + else if( strPath.endsWith("layoutList/layout/variantList/variant") ) { + rules->layoutInfos.last()->variantInfos << new VariantInfo(fromExtras); + } + else if( strPath.endsWith("modelList/model") ) { + rules->modelInfos << new ModelInfo(); + } + else if( strPath.endsWith("optionList/group") ) { + rules->optionGroupInfos << new OptionGroupInfo(); + rules->optionGroupInfos.last()->exclusive = (attributes.value("allowMultipleSelection") != "true"); + } + else if( strPath.endsWith("optionList/group/option") ) { + rules->optionGroupInfos.last()->optionInfos << new OptionInfo(); + } + else if( strPath == ("xkbConfigRegistry") && ! attributes.value("version").isEmpty() ) { + rules->version = attributes.value("version"); + kDebug() << "xkbConfigRegistry version" << rules->version; + } + return true; +} + +bool RulesHandler::endElement(const QString &/*namespaceURI*/, const QString &/*localName*/, const QString &/*qName*/) +{ + path.removeLast(); + return true; +} + +bool RulesHandler::characters(const QString &str) +{ + if( !str.trimmed().isEmpty() ) { + QString strPath = path.join("/"); + if( strPath.endsWith("layoutList/layout/configItem/name") ) { + if( rules->layoutInfos.last() != NULL ) { + rules->layoutInfos.last()->name = str.trimmed(); +// qDebug() << "name:" << str; + } + // skipping invalid entry + } + else if( strPath.endsWith("layoutList/layout/configItem/description") ) { + rules->layoutInfos.last()->description = str.trimmed(); +// qDebug() << "descr:" << str; + } + else if( strPath.endsWith("layoutList/layout/configItem/languageList/iso639Id") ) { + rules->layoutInfos.last()->languages << str.trimmed(); +// qDebug() << "\tlang:" << str; + } + else if( strPath.endsWith("layoutList/layout/variantList/variant/configItem/name") ) { + rules->layoutInfos.last()->variantInfos.last()->name = str.trimmed(); +// qDebug() << "\tvariant name:" << str; + } + else if( strPath.endsWith("layoutList/layout/variantList/variant/configItem/description") ) { + rules->layoutInfos.last()->variantInfos.last()->description = str.trimmed(); +// qDebug() << "\tvariant descr:" << str; + } + else if( strPath.endsWith("layoutList/layout/variantList/variant/configItem/languageList/iso639Id") ) { + rules->layoutInfos.last()->variantInfos.last()->languages << str.trimmed(); +// qDebug() << "\tvlang:" << str; + } + else if( strPath.endsWith("modelList/model/configItem/name") ) { + rules->modelInfos.last()->name = str.trimmed(); +// qDebug() << "name:" << str; + } + else if( strPath.endsWith("modelList/model/configItem/description") ) { + rules->modelInfos.last()->description = str.trimmed(); +// qDebug() << "\tdescr:" << str; + } + else if( strPath.endsWith("modelList/model/configItem/vendor") ) { + rules->modelInfos.last()->vendor = str.trimmed(); +// qDebug() << "\tvendor:" << str; + } + else if( strPath.endsWith("optionList/group/configItem/name") ) { + rules->optionGroupInfos.last()->name = str.trimmed(); +// qDebug() << "name:" << str; + } + else if( strPath.endsWith("optionList/group/configItem/description") ) { + rules->optionGroupInfos.last()->description = str.trimmed(); +// qDebug() << "\tdescr:" << str; + } + else if( strPath.endsWith("optionList/group/option/configItem/name") ) { + rules->optionGroupInfos.last()->optionInfos.last()->name = str.trimmed(); +// qDebug() << "name:" << str; + } + else if( strPath.endsWith("optionList/group/option/configItem/description") ) { + rules->optionGroupInfos.last()->optionInfos.last()->description = str.trimmed(); +// qDebug() << "\tdescr:" << str; + } + } + return true; +} + +bool LayoutInfo::isLanguageSupportedByLayout(const QString& lang) const +{ + if( languages.contains(lang) || isLanguageSupportedByVariants(lang) ) + return true; + +// // return yes if no languages found in layout or its variants +// if( languages.empty() ) { +// foreach(const VariantInfo* info, variantInfos) { +// if( ! info->languages.empty() ) +// return false; +// } +// return true; +// } + + return false; +} + +bool LayoutInfo::isLanguageSupportedByVariants(const QString& lang) const +{ + foreach(const VariantInfo* info, variantInfos) { + if( info->languages.contains(lang) ) + return true; + } + return false; +} + +bool LayoutInfo::isLanguageSupportedByDefaultVariant(const QString& lang) const +{ + if( languages.contains(lang) ) + return true; + + if( languages.empty() && isLanguageSupportedByVariants(lang) ) + return true; + + return false; +} + +bool LayoutInfo::isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const +{ + if( variantInfo->languages.contains(lang) ) + return true; + + // if variant has no languages try to "inherit" them from layout + if( variantInfo->languages.empty() && languages.contains(lang) ) + return true; + + return false; +} diff --git a/kcontrol/keyboard/xkb_rules.h b/kcontrol/keyboard/xkb_rules.h new file mode 100644 index 00000000..2be85624 --- /dev/null +++ b/kcontrol/keyboard/xkb_rules.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef XKB_RULES_H_ +#define XKB_RULES_H_ + +#include +#include +#include + + +struct ConfigItem { + QString name; + QString description; +}; + +template +inline T* findByName(QList list, QString name) { + foreach(T* info, list) { + if( info->name == name ) + return info; + } + return NULL; +} + +struct VariantInfo: public ConfigItem { + QList languages; + const bool fromExtras; + + VariantInfo(bool fromExtras_): + fromExtras(fromExtras_) {} +}; + +struct LayoutInfo: public ConfigItem { + QList variantInfos; + QList languages; + const bool fromExtras; + +// LayoutInfo() {} + LayoutInfo(bool fromExtras_): + fromExtras(fromExtras_) {} + ~LayoutInfo() { foreach(VariantInfo* variantInfo, variantInfos) delete variantInfo; } + + VariantInfo* getVariantInfo(const QString& variantName) const { + return findByName(variantInfos, variantName); + } + + bool isLanguageSupportedByLayout(const QString& lang) const; + bool isLanguageSupportedByDefaultVariant(const QString& lang) const; + bool isLanguageSupportedByVariants(const QString& lang) const; + bool isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const; +}; + +struct ModelInfo: public ConfigItem { + QString vendor; +}; + +struct OptionInfo: public ConfigItem { +}; + +struct OptionGroupInfo: public ConfigItem { + QList optionInfos; + bool exclusive; + + ~OptionGroupInfo() { foreach(OptionInfo* opt, optionInfos) delete opt; } + + const OptionInfo* getOptionInfo(const QString& optionName) const { + return findByName(optionInfos, optionName); + } +}; + +struct Rules { + enum ExtrasFlag { NO_EXTRAS, READ_EXTRAS }; + + static const char XKB_OPTION_GROUP_SEPARATOR; + + QList layoutInfos; + QList modelInfos; + QList optionGroupInfos; + QString version; + + Rules(); + + ~Rules() { + foreach(LayoutInfo* layoutInfo, layoutInfos) delete layoutInfo; + foreach(ModelInfo* modelInfo, modelInfos) delete modelInfo; + foreach(OptionGroupInfo* optionGroupInfo, optionGroupInfos) delete optionGroupInfo; + } + + const LayoutInfo* getLayoutInfo(const QString& layoutName) const { + return findByName(layoutInfos, layoutName); + } + + const OptionGroupInfo* getOptionGroupInfo(const QString& optionGroupName) const { + return findByName(optionGroupInfos, optionGroupName); + } + + static Rules* readRules(ExtrasFlag extrasFlag); + static Rules* readRules(Rules* rules, const QString& filename, bool fromExtras); + static QString getRulesName(); +}; + +#endif /* XKB_RULES_H_ */ diff --git a/kcontrol/keys/CMakeLists.txt b/kcontrol/keys/CMakeLists.txt new file mode 100644 index 00000000..f0eb42c4 --- /dev/null +++ b/kcontrol/keys/CMakeLists.txt @@ -0,0 +1,46 @@ +kde4_no_enable_final(keys) + +########### next target ############### + +set(kcm_keys_PART_SRCS + kglobalshortcutseditor.cpp + globalshortcuts.cpp + select_scheme_dialog.cpp + kglobalaccel_interface.cpp + kglobalaccel_component_interface.cpp + export_scheme_dialog.cpp + ) + +kde4_add_ui_files( kcm_keys_PART_SRCS + export_scheme_dialog.ui + kglobalshortcutseditor.ui + select_scheme_dialog.ui ) + +set(kglobalaccel_xml ${KDE4_DBUS_INTERFACES_DIR}/org.kde.KGlobalAccel.xml) +set_source_files_properties(${kglobalaccel_xml} PROPERTIES INCLUDE "kglobalshortcutinfo_p.h") +qt4_add_dbus_interface(kdeui_LIB_SRCS ${kglobalaccel_xml} kglobalaccel_interface ) + +set(kglobalaccel_component_xml ${KDE4_DBUS_INTERFACES_DIR}/org.kde.kglobalaccel.Component.xml) +set_source_files_properties(${kglobalaccel_component_xml} PROPERTIES INCLUDE "kglobalshortcutinfo_p.h") +qt4_add_dbus_interface(kdeui_LIB_SRCS ${kglobalaccel_component_xml} kglobalaccel_component_interface ) + +kde4_add_plugin(kcm_keys ${kcm_keys_PART_SRCS}) +target_link_libraries(kcm_keys ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${X11_X11_LIB}) + +install(TARGETS kcm_keys DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install( FILES keys.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES + schemes/kde3.kksrc + schemes/kde4.kksrc + schemes/mac4.kksrc + schemes/unix3.kksrc + schemes/win3.kksrc + schemes/win4.kksrc + schemes/wm3.kksrc + DESTINATION ${DATA_INSTALL_DIR}/kcmkeys ) + + diff --git a/kcontrol/keys/ChangeLog b/kcontrol/keys/ChangeLog new file mode 100644 index 00000000..67c21160 --- /dev/null +++ b/kcontrol/keys/ChangeLog @@ -0,0 +1,29 @@ +2005-09-30 Benjamin Meyer + * Removed Command Shortcuts, it is already in kmenuedit + +1999-08-19 Duncan Haldane + * removed left-over commented out code from change + decribed below, and adjusted help doc names to + index-1.html + +1999-02-28 Duncan Haldane + * commented out those unnecessary debug calls. + in keyconfig.cpp + +1998-12-19 Duncan Haldane + * Converted global.cpp, global.h to keyconfig.cpp, + keyconfig.h, that can now be used to configure both + the standard keys and the global keys + in the same sophisticated manner as + global.cpp did for just the global keys. + * converted main.cpp to use keyconfig.cpp rather than + global.cpp and standard.cpp for standard and globall + key configuration. KGlobalConfig and KStdConfig disappear. + (KGlobalConfig is renamed to KKeyConfig) + * appropriate changes to Makefile.am. + * standard key binding are now #include'd from + stdbindings.cpp + * standard.cpp, standard.h are left here for now. + The entries that used to use them in main.cpp and + Makefile.am are just commented out for now. + diff --git a/kcontrol/keys/Messages.sh b/kcontrol/keys/Messages.sh new file mode 100644 index 00000000..78a9c48f --- /dev/null +++ b/kcontrol/keys/Messages.sh @@ -0,0 +1,7 @@ +#! /usr/bin/env bash +# customkeys=`grep "^.include .\.\." keyconfig.cpp | sed -e "s#.*\"\(.*\)\"#\1#"` +# $XGETTEXT *.cpp $customkeys -o $podir/kcmkeys.pot +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcmkeys.pot +rm -f rc.cpp + diff --git a/kcontrol/keys/README b/kcontrol/keys/README new file mode 100644 index 00000000..14e09f73 --- /dev/null +++ b/kcontrol/keys/README @@ -0,0 +1,7 @@ +CHANGES V0.2 +- Global keys stored by default in ~/.kde/share/config/kdeglobals + [Global Keys] group +- KKeyDialog checks new key choices against exising bindings for the widget +and against entries in .kderc [Global Keys] +- kcmkeys now has two standard kcontrol pages - one for standard desktop +accelerators and one for global keybindings. diff --git a/kcontrol/keys/export_scheme_dialog.cpp b/kcontrol/keys/export_scheme_dialog.cpp new file mode 100644 index 00000000..49ca7f3d --- /dev/null +++ b/kcontrol/keys/export_scheme_dialog.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2009 Michael Jansen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "export_scheme_dialog.h" + +#include + +#include + + +ExportSchemeDialog::ExportSchemeDialog(QStringList components, QWidget *parent) + : KDialog(parent), + ui(), + mComponents(components) + { + QWidget *w = new QWidget(this); + ui.setupUi(w); + setMainWidget(w); + + // We allow to check more than one button + mButtons.setExclusive(false); + + // A grid layout for the buttons + QGridLayout *vb = new QGridLayout(this); + + int item=0; + Q_FOREACH(QString component, mComponents) + { + QCheckBox *cb = new QCheckBox(component); + vb->addWidget(cb, item / 2, item % 2); + mButtons.addButton(cb, item); + ++item; + } + + ui.components->setLayout(vb); + } + + +ExportSchemeDialog::~ExportSchemeDialog() + {} + + +QStringList ExportSchemeDialog::selectedComponents() const + { + QStringList rc; + Q_FOREACH(QAbstractButton const *button, mButtons.buttons()) + { + if (button->isChecked()) + { + // Remove the '&' added by KAcceleratorManager magically + rc.append(KGlobal::locale()->removeAcceleratorMarker(button->text())); + } + } + return rc; + } + + +#include "moc_export_scheme_dialog.cpp" diff --git a/kcontrol/keys/export_scheme_dialog.h b/kcontrol/keys/export_scheme_dialog.h new file mode 100644 index 00000000..ab27fa19 --- /dev/null +++ b/kcontrol/keys/export_scheme_dialog.h @@ -0,0 +1,58 @@ +#ifndef EXPORT_SCHEME_DIALOG_H +#define EXPORT_SCHEME_DIALOG_H +/** + * Copyright (C) 2009 Michael Jansen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "ui_export_scheme_dialog.h" + +#include + +/** + * @author Michael Jansen + */ +class ExportSchemeDialog : public KDialog + { + Q_OBJECT + +public: + + ExportSchemeDialog (QStringList components, QWidget *parent=NULL); + + virtual ~ExportSchemeDialog(); + + // Get the list of currently selected components + QStringList selectedComponents() const; + +private: + + Ui::ExportSchemeDialog ui; + + // list of components to choose from + QStringList mComponents; + + // list of buttons for the components + QButtonGroup mButtons; + + }; // ExportSchemeDialog + + + + +#endif /* EXPORT_SCHEME_DIALOG_H */ + diff --git a/kcontrol/keys/export_scheme_dialog.ui b/kcontrol/keys/export_scheme_dialog.ui new file mode 100644 index 00000000..4e8651ee --- /dev/null +++ b/kcontrol/keys/export_scheme_dialog.ui @@ -0,0 +1,35 @@ + + + ExportSchemeDialog + + + + 0 + 0 + 400 + 300 + + + + + + + Select the Components to Export + + + Qt::AlignCenter + + + + + + + Components + + + + + + + + diff --git a/kcontrol/keys/globalshortcuts.cpp b/kcontrol/keys/globalshortcuts.cpp new file mode 100644 index 00000000..88220593 --- /dev/null +++ b/kcontrol/keys/globalshortcuts.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2007 Andreas Pakulat + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "globalshortcuts.h" + +#include "kglobalshortcutseditor.h" + +#include +#include +#include + + +#include + + +K_PLUGIN_FACTORY(GlobalShortcutsModuleFactory, registerPlugin();) +K_EXPORT_PLUGIN(GlobalShortcutsModuleFactory("kcmkeys")) + + +GlobalShortcutsModule::GlobalShortcutsModule(QWidget *parent, const QVariantList &args) + : KCModule(GlobalShortcutsModuleFactory::componentData(), parent, args), + editor(0) +{ + KCModule::setButtons(KCModule::Buttons(KCModule::Default | KCModule::Apply | KCModule::Help)); + + + // Create the kglobaleditor + editor = new KGlobalShortcutsEditor(this, KShortcutsEditor::GlobalAction); + connect(editor, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + + // Layout the hole bunch + QVBoxLayout *global = new QVBoxLayout; + global->addWidget(editor); + setLayout(global); +} + +GlobalShortcutsModule::~GlobalShortcutsModule() +{} + + +void GlobalShortcutsModule::load() +{ + editor->load(); +} + + +void GlobalShortcutsModule::defaults() +{ + switch (KMessageBox::questionYesNoCancel( + this, + i18n("You are about to reset all shortcuts to their default values."), + i18n("Reset to defaults"), + KGuiItem(i18n("Current Component")), + KGuiItem(i18n("All Components")))) + { + case KMessageBox::Yes: + editor->defaults(KGlobalShortcutsEditor::CurrentComponent); + break; + + case KMessageBox::No: + editor->defaults(KGlobalShortcutsEditor::AllComponents); + break; + + default: + return; + } +} + + +void GlobalShortcutsModule::save() +{ + editor->save(); +} + + +#include "globalshortcuts.moc" diff --git a/kcontrol/keys/globalshortcuts.h b/kcontrol/keys/globalshortcuts.h new file mode 100644 index 00000000..428c0335 --- /dev/null +++ b/kcontrol/keys/globalshortcuts.h @@ -0,0 +1,44 @@ +/* + * Copyright 2007 Andreas Pakulat + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SHORTCUTS_MODULE_H +#define SHORTCUTS_MODULE_H + +#include +#include + +class KGlobalShortcutsEditor; + +class GlobalShortcutsModule : public KCModule +{ + Q_OBJECT +public: + GlobalShortcutsModule(QWidget *parent, const QVariantList &args); + ~GlobalShortcutsModule(); + + virtual void save(); + virtual void load(); + virtual void defaults(); + +private: + KGlobalShortcutsEditor *editor; +}; + + +#endif diff --git a/kcontrol/keys/keys.desktop b/kcontrol/keys/keys.desktop new file mode 100644 index 00000000..0db464f6 --- /dev/null +++ b/kcontrol/keys/keys.desktop @@ -0,0 +1,227 @@ +[Desktop Entry] +Exec=kcmshell4 keys +Icon=preferences-desktop-keyboard-shortcut +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/keys/index.html + +X-KDE-Library=kcm_keys +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=shortcuts-and-gestures +X-KDE-Weight=160 + +Name=Global Keyboard Shortcuts +Name[ar]=اختصارات لوحة المفاتيح العمومية +Name[ast]=Accesos rápidos de tecláu globales +Name[be@latin]=Paŭsiudnyja klavijaturnyja skaroty +Name[bg]=Общи бързи клавиши +Name[bn]=গ্লোবাল কীবোর্ড শর্টকাট +Name[bn_IN]=কি-বোর্ডের সার্বজনীন শর্ট-কাট +Name[bs]=Globalne prečice sa tastature +Name[ca]=Dreceres de teclat globals +Name[ca@valencia]=Dreceres de teclat globals +Name[cs]=Globální klávesové zkratky +Name[csb]=Globalné klawiszowé skrodzënë +Name[da]=Globale tastaturgenveje +Name[de]=Globale Kurzbefehle +Name[el]=Καθολικές συντομεύσεις πληκτρολογίου +Name[en_GB]=Global Keyboard Shortcuts +Name[eo]=Ĝeneralaj Klavkombinoj +Name[es]=Accesos rápidos de teclado globales +Name[et]=Globaalsed kiirklahvid +Name[eu]=Laster-tekla orokorrak +Name[fa]=میان‌برهای صفحه‌ کلید سراسری +Name[fi]=Työpöydänlaajuiset pikanäppäimet +Name[fr]=Raccourcis globaux de clavier +Name[fy]=Globale fluchkeppelings +Name[ga]=Aicearraí Comhchoiteanna Méarchláir +Name[gl]=Atallos de teclado globais +Name[gu]=વૈશ્વીક કીબોર્ડ ટૂંકાણો +Name[he]=קיצורי מקשים גלובליים +Name[hi]=वैश्विक कुंजीपट शॉर्टकट +Name[hne]=वैस्विक कुंजीपट सार्टकट +Name[hr]=Globalni prečaci tipkovnice +Name[hsb]=Globalne tastaturowe skrótšenki +Name[hu]=Globális billentyűparancsok +Name[ia]=Vias breve global de claviero +Name[id]=Jalan Pintas Papan Ketik Global +Name[is]=Víðværir flýtilyklar +Name[it]=Scorciatoie globali della tastiera +Name[ja]=グローバルキーボードショートカット +Name[kk]=Жалпы жүйелік перне тіркесімдер +Name[km]=ផ្លូវកាត់​ក្ដារចុច​​សកល +Name[kn]=ಸಾರ್ವತ್ರಿಕ ಕೀಲಿಮಣೆ ಶೀಘ್ರಮಾರ್ಗಗಳು (ಶಾರ್ಟ್ ಕಟ್) +Name[ko]=전역 키보드 단축키 +Name[ku]=Kurteriyên Klavyeyê yên Giştî +Name[lt]=Globalieji spartieji klavišai +Name[lv]=Globālie tastatūras īsceļi +Name[mai]=वैश्विक कुंजीपटल शार्टकट +Name[mk]=Глобални кратенки на тастатурата +Name[ml]=ആഗോളമായ കീബോര്‍ഡിലെ കുറക്കുവഴികള്‍ +Name[mr]=जागतिक कळफलक शॉर्टकट +Name[nb]=Globale hurtigtaster +Name[nds]=Globaal Tastkombinatschonen +Name[nl]=Globale sneltoetsen +Name[nn]=Globale snøgg­tastar +Name[or]=ଜାଗତିକ କିବୋର୍ଡ଼ ସଂକ୍ଷିପ୍ତ ପଥ +Name[pa]=ਗਲੋਬਲ ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ +Name[pl]=Globalne skróty klawiszowe +Name[pt]=Atalhos Globais do Teclado +Name[pt_BR]=Atalhos de teclado globais +Name[ro]=Acceleratori de tastatură globali +Name[ru]=Глобальные комбинации клавиш +Name[si]=ගෝලීය යතුරුපුවරු කෙටිමං +Name[sk]=Globálne klávesové skratky +Name[sl]=Splošne tipkovne bližnjice +Name[sr]=Глобалне пречице са тастатуре +Name[sr@ijekavian]=Глобалне пречице са тастатуре +Name[sr@ijekavianlatin]=Globalne prečice sa tastature +Name[sr@latin]=Globalne prečice sa tastature +Name[sv]=Globala snabbtangenter +Name[ta]=பொது விசைப்பலகை குறுக்குவழிகள் +Name[te]=గ్లౌబల్ కీబోర్‍డ్ లఘువులు +Name[tg]=Глобальные комбинации клавиш +Name[th]=ปุ่มพิมพ์ลัดใช้งานส่วนรวม +Name[tr]=Genel Klavye Kısayolları +Name[ug]=ئومۇمىيەت ھەرپتاختا تېزلەتمىسى +Name[uk]=Загальні клавіатурні скорочення +Name[vi]=Phím tắt toàn hệ thống +Name[wa]=Rascourtis del taprece po ttavå +Name[x-test]=xxGlobal Keyboard Shortcutsxx +Name[zh_CN]=全局键盘快捷键 +Name[zh_TW]=全域鍵盤捷徑 + +Comment=Configuration of keybindings +Comment[af]=Opstelling van sleutel bindinge +Comment[ar]=إعداد ارتباطات المفاتيح +Comment[ast]=Configuración de les asociaciones de les tecles +Comment[be]=Настаўленні клавішных скаротаў +Comment[be@latin]=Nałady dla poviaziaŭ klavišaŭ z roznymi aperacyjami +Comment[bg]=Настройки на бързи клавиши +Comment[bn]=কী-বাইন্ডিং কনফিগারেশন +Comment[bn_IN]=কি-বাইন্ডিং কনফিগারেশন +Comment[br]=Kefluniañ ereoù stokell +Comment[bs]=Postava prečica sa tastature +Comment[ca]=Configuració dels lligams de tecles +Comment[ca@valencia]=Configuració dels lligams de tecles +Comment[cs]=Nastavení klávesových zkratek +Comment[csb]=Nastôw klawiszowëch skrodzënów +Comment[cy]=Furfweddiad o rwymiadau bysell +Comment[da]=Indstilling af tastebindinger +Comment[de]=Einrichtung von Tastenzuordnungen +Comment[el]=Διαμόρφωση συνδυασμών πλήκτρων +Comment[en_GB]=Configuration of keybindings +Comment[eo]=Agordo de klavkombinoj +Comment[es]=Configuración de las asociaciones de las teclas +Comment[et]=Kiirklahvide seadistamine +Comment[eu]=Laster-teklen konfigurazioa +Comment[fa]=پیکربندی مقیدسازیهای کلید +Comment[fi]=Näppäinsidosten asetukset +Comment[fy]=Ynstellings foar fluchtoetsen +Comment[ga]=Cumraíocht ceangal eochracha +Comment[gl]=Configuración dos atallos de teclado +Comment[gu]=કીજોડાણોનું રૂપરેખાંકન +Comment[he]=הגדרות מיפוי מקשים +Comment[hi]=की-बाइंडिंग का कॉन्फ़िगरेशन +Comment[hne]=की-बाइंडिंग के कान्फिगरेसन +Comment[hr]=Konfiguriranje prečaca tipkovnice +Comment[hsb]=Připrawjenje přirjadowanjow tastow +Comment[hu]=A billentyűparancsok beállításai +Comment[ia]=Configuration de keybindings (ligamines de claves) +Comment[id]=Konfigurasi pengikat tombol +Comment[is]=Stillingar altækra flýtihnappa +Comment[ka]=კლავიშთა წყვილების კონფიგურაცია +Comment[kk]=Перне тіркесімдерді баптау +Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ការ​ចង​គ្រាប់ចុច +Comment[kn]=ಕೀಲಿ ನಿಬಂಧಗಳ (ಬೈಂಡಿಂಗ್ಸ್) ಸಂರಚನೆ +Comment[ko]=키 바인딩 설정 +Comment[ku]=Veavakirina bicîkirina bişkojkan +Comment[lt]=Klavišų siečių derinimas +Comment[lv]=Taustiņsasaistes konfigurēšana +Comment[mai]=की-बाइंडिंग क' कान्फिगरेशन +Comment[mk]=Конфигурација на врски меѓу копчиња и акции +Comment[ml]=കീബൈന്‍ഡിങ്സിനുള്ള ക്രമീകരണം +Comment[mr]=कीबाइंडिंगची संयोजना +Comment[ms]=Konfigurasi untuk pengikatan kekunci +Comment[nb]=Oppsett av hurtigtaster +Comment[nds]=Instellen vun Tastkombinatschonen +Comment[ne]=कुञ्जी बाइन्डिङहरूको कन्फिगरेसन +Comment[nl]=Instellingen voor sneltoetsen +Comment[nn]=Oppsett av snøggtastar +Comment[or]=କିବନ୍ଧନଗୁଡ଼ିକର ସଂରଚନା +Comment[pa]=ਕੀ-ਬਾਇਡਿੰਗ ਦੀ ਸੰਰਚਨਾ +Comment[pl]=Ustawienia powiązań klawiszowych +Comment[pt]=Configuração das teclas +Comment[pt_BR]=Configuração dos atalhos de teclado +Comment[ro]=Configurează asocierile de taste +Comment[ru]=Настройка глобальных комбинаций клавиш +Comment[se]=Jođánisboaluid heiveheapmi +Comment[si]=යතුරු බැඳුම් වල සැකසුම +Comment[sk]=Nastavenie globálnych klávesových skratiek +Comment[sl]=Nastavitve tipkovnih bližnjic +Comment[sr]=Поставке пречица са тастатуре +Comment[sr@ijekavian]=Поставке пречица са тастатуре +Comment[sr@ijekavianlatin]=Postavke prečica sa tastature +Comment[sr@latin]=Postavke prečica sa tastature +Comment[sv]=Anpassa kortkommandon +Comment[ta]=விசைசேர்வுகளுக்கான வடிவமைப்பு +Comment[te]=కీ భందనముల యొక్క ఆకృతీకరణ +Comment[tg]=Танзимоти тугмаҳои якҷояшуда +Comment[th]=ปรับแต่งปุ่มพิมพ์ลัดต่าง ๆ +Comment[tr]=Tuş bağıntılarının yapılandırılması +Comment[ug]=كۇنۇپكا باغلاش سەپلىمە +Comment[uk]=Налаштування прив'язок клавіш +Comment[uz]=Tugmalar birikmasini moslash +Comment[uz@cyrillic]=Тугмалар бирикмасини мослаш +Comment[vi]=Cấu hình các tổ hợp phím +Comment[wa]=Apontiaedje des rascourtis di tapes +Comment[xh]=Uqwalaselo lwezibopheleo zesitshixo +Comment[x-test]=xxConfiguration of keybindingsxx +Comment[zh_CN]=键绑定配置 +Comment[zh_TW]=按鍵關聯設定 + +X-KDE-Keywords=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts +X-KDE-Keywords[bs]=Tipke, Globalni vezovi tipki, Šema tipki, Veze tipki, Prečice, Prečice za aplikacije, globalne Prečice +X-KDE-Keywords[ca]=Tecles,Assignació de tecles globals,Esquema de tecles,Assignació de tecles,dreceres,dreceres d'aplicació,dreceres globals +X-KDE-Keywords[ca@valencia]=Tecles,Assignació de tecles globals,Esquema de tecles,Assignació de tecles,dreceres,dreceres d'aplicació,dreceres globals +X-KDE-Keywords[da]=Taster,globale tastebindinger,tasteskema,tastebindinger,genveje,programgenveje,globale genveje +X-KDE-Keywords[de]=Tasten,Tastenzuordnung,Tastenkürzel,Kurzbefehle,Tastenschema,Tastaturlayout +X-KDE-Keywords[el]=Πλήκτρα,δεσμεύσεις καθολικών πλήκτρων, σχήμα πλήκτρων, δεσμεύσεις πλήκτρων,συντομεύσεις,συντομεύσεις εφαρμογών,καθολικές συντομεύσεις +X-KDE-Keywords[en_GB]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts +X-KDE-Keywords[es]=Teclas,Asociaciones globales de teclas,Esquema de teclas,Asociaciones de teclas,accesos rápidos,accesos rápidos de aplicaciones,accesos rápidos globales +X-KDE-Keywords[et]=klahvid,globaalsed kiirklahvid,klaviatuuriskeem,klahviseosed,kiirklahvid,rakenduse kiirklahvid,globaalsed kiirklahvid +X-KDE-Keywords[eu]=tekla,laster-tekla orokor,tekla-eskema,laster-tekla,lasterbide,aplikazioen laster-teklak +X-KDE-Keywords[fi]=näppäimet,globaalit näppäinsidokset,yleiset näppäinsidokset,työpöydänlaajuiset näppäinsidokset,globaalit pikanäppäimet,työpöydänlaajuiset pikanäppäimet,globaalit näppäinyhdistelmät,työpöydänlaajuiset näppäinyhdistelmät,näppäimistön yleispikavalinnat,näppäimistön globaalit pikavalinnat,näppäinsidokset,pikanäppäimet,näppäimistön pikavalinnat, näppäinyhdistelmät,näppäinoikotiet,sovellusten pikanäppäimet,sovellusten näppäinyhdistelmät,sovellusten näppäinoikotiet +X-KDE-Keywords[fr]=Touches, Association globale des touches, Schéma des touches, Association de touches, Raccourci des applications, Raccourcis globaux +X-KDE-Keywords[ga]=Eochracha,Ceangail chomhchoiteanna eochracha,Scéim eochracha,Ceangail eochracha,aicearraí,aicearraí feidhmchláir,aicearraí comhchoiteanna +X-KDE-Keywords[gl]=tecla, atallo, asociación, esquema de teclas, atallo de teclado, asociación de teclas, atallo a programa, atallos globais +X-KDE-Keywords[hu]=Billentyűk,Globális gyorsbillentyűk,Billentyűséma,Gyorsbillentyűk,alkalmazás gyorsbillentyűk,globális gyorsbillentyűk +X-KDE-Keywords[ia]=Claves,ligamines de clave global,schema de clave,ligamines de clave,vias breve,vias breve de application,vias breve global +X-KDE-Keywords[it]=tasti,scorciatoie globali di tastiera,schema di tasti,scorciatoie,scorciatoie delle applicazioni,scorciatoie globali +X-KDE-Keywords[kk]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts +X-KDE-Keywords[km]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts +X-KDE-Keywords[ko]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,키,전역 키 바인딩,키 바인딩,단축키,프로그램 단축키 +X-KDE-Keywords[mr]=कीज, ग्लोबल की बाईंडिंगज, की स्कीम, की बाईंडिंगज, शॉर्टकटस, अप्लिकेशन शॉर्टकटस, ग्लोबल शॉर्टकटस +X-KDE-Keywords[nb]=Taster,Globale tastebindinger,Tastaturutforming,Tastebindinger,snarveier,programsnarveier,globale snarveier +X-KDE-Keywords[nds]=Tasten,Globaal Tasttowiesen,Tasttowiesen,Tastkombinatschonen,Programm-Tastkombinatschonen,Globaal Tastkombinatschonen +X-KDE-Keywords[nl]=toetsen,globale toetsbindingen,toetsenschema,toetsbindingen,sneltoetsen,sneltoetsen van toepassing,globale sneltoetsen +X-KDE-Keywords[pl]=Klawisze,Globalne powiązania klawiszy,Motyw klawiszy,Powiązania klawiszy,skróty,skróty programów,globalne skróty +X-KDE-Keywords[pt]=Teclas,combinações de teclas,global,esquema de teclas,atalhos de teclado,atalhos,atalhos das aplicações +X-KDE-Keywords[pt_BR]=Teclas,combinações de teclas global,esquema de teclas,atalhos de teclado,atalhos,atalhos dos aplicativos, atalhos globais +X-KDE-Keywords[ru]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,клавиши,глобальные привязки клавиш,схема,привязки клавиш,комбинации клавиш,комбинации клавиш в приложениях,глобальные привязки клавиш +X-KDE-Keywords[sk]=Klávesy,Globálne klávesové skratky,Klávesová schéma,Klávesové skratky,skratky,skratky aplikácie,globálne skratky +X-KDE-Keywords[sl]=tipke,splošne tipkovne bližnjice,tipkovna shema,shema tipk,tipkovne bližnjice,vezave tipk,bližnjice,programske bližnjice,splošne bližnjice +X-KDE-Keywords[sr]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,тастери,глобалне свезе тастера,шема тастера,свезе тастера,пречице,пречице програма,глобалне пречице +X-KDE-Keywords[sr@ijekavian]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,тастери,глобалне свезе тастера,шема тастера,свезе тастера,пречице,пречице програма,глобалне пречице +X-KDE-Keywords[sr@ijekavianlatin]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,tasteri,globalne sveze tastera,šema tastera,sveze tastera,prečice,prečice programa,globalne prečice +X-KDE-Keywords[sr@latin]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,tasteri,globalne sveze tastera,šema tastera,sveze tastera,prečice,prečice programa,globalne prečice +X-KDE-Keywords[sv]=Tangenter,Globala tangentbindingar,Tangentschema,Tangentbindingar,genvägar,programgenvägar,globala genvägar +X-KDE-Keywords[tr]=Tuşlar,Genel kısayollar,Klavye şeması,Klavye Kısayolları,kısayollar,uygulama kısayolları,genel kısayollar, kısayol tuşları +X-KDE-Keywords[uk]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,клавіатура,скорочення,клавіатурні скорочення,схема,загальні клавіатурні скорочення,клавіатурні скорочення програми,загальні скорочення +X-KDE-Keywords[vi]=Phím,tổ hợp phím toàn cục,phối hợp phím,tổ hợp phím,gõ tắt,gõ tắt cho ứng dụng +X-KDE-Keywords[x-test]=xxKeys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcutsxx +X-KDE-Keywords[zh_CN]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts,按键,全局键绑定,按键方案,按键绑定,快捷键,应用程序,全局快捷键 +X-KDE-Keywords[zh_TW]=Keys,Global key bindings,Key scheme,Key bindings,shortcuts,application shortcuts,global shortcuts + +Categories=Qt;KDE;X-KDE-settings-accessibility; diff --git a/kcontrol/keys/kglobalshortcutseditor.cpp b/kcontrol/keys/kglobalshortcutseditor.cpp new file mode 100644 index 00000000..50f3796a --- /dev/null +++ b/kcontrol/keys/kglobalshortcutseditor.cpp @@ -0,0 +1,676 @@ +/* + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "kglobalshortcutseditor.h" + +#include "ui_kglobalshortcutseditor.h" +#include "export_scheme_dialog.h" +#include "select_scheme_dialog.h" +#include "globalshortcuts.h" +#include "kglobalaccel_interface.h" +#include "kglobalaccel_component_interface.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * README + * + * This class was created because the kshortcutseditor class has some shortcomings. That class uses + * QTreeWidget and therefore makes it impossible for an outsider to switch the models. But the + * global shortcuts editor did that. Each global component ( kded, krunner, kopete ... ) was + * destined to be separately edited. If you selected another component the kshortcutseditor was + * cleared and refilled. But the items take care of undoing. Therefore when switching the component + * you lost the undo history. + * + * To solve that problem this class keeps one kshortcuteditor for each component. That is easier + * than rewrite that dialog to a model/view framework. + * + * It perfectly covers a bug of KExtedableItemDelegate when clearing and refilling the associated + * model. + */ + +class ComponentData + { + +public: + + ComponentData( + const QString &uniqueName, + const QDBusObjectPath &path, + KShortcutsEditor *_editor); + + ~ComponentData(); + + QString uniqueName() const; + KShortcutsEditor *editor(); + QDBusObjectPath dbusPath(); + +private: + + QString _uniqueName; + QDBusObjectPath _path; + QPointer _editor; + }; + + +ComponentData::ComponentData( + const QString &uniqueName, + const QDBusObjectPath &path, + KShortcutsEditor *editor) + : _uniqueName(uniqueName), + _path(path), + _editor(editor) + {} + + +ComponentData::~ComponentData() + { + delete _editor; _editor = 0; + } + + +QString ComponentData::uniqueName() const + { + return _uniqueName; + } + + +QDBusObjectPath ComponentData::dbusPath() + { + return _path; + } + + +KShortcutsEditor *ComponentData::editor() + { + return _editor; + } + + +class KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate +{ +public: + + KGlobalShortcutsEditorPrivate(KGlobalShortcutsEditor *q) + : q(q), + stack(0), + bus(QDBusConnection::sessionBus()) + {} + + //! Setup the gui + void initGUI(); + + //! Delete the currently selected component + void removeComponent(); + + //! Load the component at @a componentPath + bool loadComponent(const QDBusObjectPath &componentPath); + + //! Return the componentPath for component + QDBusObjectPath componentPath(const QString &componentUnique); + + //! Remove the component + void removeComponent(const QString &componentUnique); + + KGlobalShortcutsEditor *q; + Ui::KGlobalShortcutsEditor ui; + QStackedWidget *stack; + KShortcutsEditor::ActionTypes actionTypes; + QHash components; + QDBusConnection bus; +}; + + +void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::initGUI() +{ + ui.setupUi(q); + // Create a stacked widget. + stack = new QStackedWidget(q); + q->layout()->addWidget(stack); + + // Connect our components + connect(ui.components, SIGNAL(activated(QString)), + q, SLOT(activateComponent(QString))); + + // Build the menu + QMenu *menu = new QMenu(q); + menu->addAction( KIcon("document-import"), i18n("Import Scheme..."), q, SLOT(importScheme())); + menu->addAction( KIcon("document-export"), i18n("Export Scheme..."), q, SLOT(exportScheme())); + menu->addAction( i18n("Set All Shortcuts to None"), q, SLOT(clearConfiguration())); + menu->addAction( KIcon("edit-delete"), i18n("Remove Component"), q, SLOT(removeComponent())); + + ui.menu_button->setMenu(menu); + + QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(q); + proxyModel->setSourceModel(new QStandardItemModel(0, 1, proxyModel)); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + ui.components->setModel(proxyModel); +} + + +KGlobalShortcutsEditor::KGlobalShortcutsEditor(QWidget *parent, KShortcutsEditor::ActionTypes actionTypes) + : QWidget(parent), + d(new KGlobalShortcutsEditorPrivate(this)) +{ + d->actionTypes = actionTypes; + // Setup the ui + d->initGUI(); +} + + +KGlobalShortcutsEditor::~KGlobalShortcutsEditor() +{ + // Before closing the door, undo all changes + undo(); + qDeleteAll(d->components); + delete d; +} + + +void KGlobalShortcutsEditor::activateComponent(const QString &component) +{ + QHash::Iterator iter = d->components.find(component); + if (iter == d->components.end()) { + Q_ASSERT(iter != d->components.end()); + return; + } else { + int index = d->ui.components->findText(component); + Q_ASSERT(index != -1); + if (index > -1) { + // Known component. Get it. + d->ui.components->setCurrentIndex(index); + d->stack->setCurrentWidget((*iter)->editor()); + } + } +} + + +void KGlobalShortcutsEditor::addCollection( + KActionCollection *collection, + const QDBusObjectPath &objectPath, + const QString &id, + const QString &friendlyName) +{ + KShortcutsEditor *editor; + // Check if this component is known + QHash::Iterator iter = d->components.find(friendlyName); + if (iter == d->components.end()) { + // Unknown component. Create an editor. + editor = new KShortcutsEditor(this, d->actionTypes); + d->stack->addWidget(editor); + + // try to find one appropriate icon ( allowing NULL pixmap to be returned) + QPixmap pixmap = KIconLoader::global()->loadIcon(id, KIconLoader::Small, 0, + KIconLoader::DefaultState, QStringList(), 0, true); + // if NULL pixmap is returned, use the F.D.O "system-run" icon + if (pixmap.isNull()) { + pixmap = KIconLoader::global()->loadIcon("system-run", KIconLoader::Small); + } + + // Add to the component combobox + d->ui.components->addItem(pixmap, friendlyName); + d->ui.components->model()->sort(0); + + // Add to our component registry + ComponentData *cd = new ComponentData(id, objectPath, editor); + d->components.insert(friendlyName, cd); + + connect(editor, SIGNAL(keyChange()), this, SLOT(_k_key_changed())); + } else { + // Known component. + editor = (*iter)->editor(); + } + + // Add the collection to the editor of the component + editor->addCollection(collection, friendlyName); + + if (d->ui.components->count() > -1) { + d->ui.components->setCurrentIndex(0); + activateComponent(d->ui.components->itemText(0)); + } +} + + +void KGlobalShortcutsEditor::clearConfiguration() +{ + QString name = d->ui.components->currentText(); + d->components[name]->editor()->clearConfiguration(); +} + + +void KGlobalShortcutsEditor::defaults(ComponentScope scope) +{ + switch (scope) + { + case AllComponents: + Q_FOREACH (ComponentData *cd, d->components) { + // The editors are responsible for the reset + cd->editor()->allDefault(); + } + break; + + case CurrentComponent: { + QString name = d->ui.components->currentText(); + // The editors are responsible for the reset + d->components[name]->editor()->allDefault(); + } + break; + + default: + Q_ASSERT(false); + }; +} + + +void KGlobalShortcutsEditor::clear() +{ + // Remove all components and their associated editors + qDeleteAll(d->components); + d->components.clear(); + d->ui.components->clear(); +} + + +static bool compare(const QString &a, const QString &b) + { + return a.toLower().localeAwareCompare(b.toLower()) < 0; + } + + +void KGlobalShortcutsEditor::exportScheme() +{ + QStringList keys = d->components.keys(); + qSort(keys.begin(), keys.end(), compare); + ExportSchemeDialog dia(keys); + + if (dia.exec() != KMessageBox::Ok) { + return; + } + + KUrl url = KFileDialog::getSaveFileName(KUrl(), "*.kksrc", this); + if (!url.isEmpty()) { + KConfig config(url.path(), KConfig::SimpleConfig); + // TODO: Bug ossi to provide a method for this + Q_FOREACH(const QString &group, config.groupList()) + { + // do not overwrite the Settings group. That makes it possible to + // update the standard scheme kksrc file with the editor. + if (group == "Settings") continue; + config.deleteGroup(group); + } + exportConfiguration(dia.selectedComponents(), &config); + } +} + + +void KGlobalShortcutsEditor::importScheme() +{ + // Check for unsaved modifications + if (isModified()) { + int choice = KMessageBox::warningContinueCancel( + this, + i18n("Your current changes will be lost if you load another scheme before saving this one"), + i18n("Load Shortcut Scheme"), + KGuiItem(i18n("Load"))); + if (choice != KMessageBox::Continue) { + return; + } + } + + SelectSchemeDialog dialog(this); + if (dialog.exec() != KDialog::Accepted) { + return; + } + + KUrl url = dialog.selectedScheme(); + if (!url.isLocalFile()) { + KMessageBox::sorry(this, i18n("This file (%1) does not exist. You can only select local files.", + url.url())); + return; + } + KConfig config(url.path(), KConfig::SimpleConfig); + importConfiguration(&config); +} + + +void KGlobalShortcutsEditor::load() +{ + // Connect to kglobalaccel. If that fails there is no need to continue. + qRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType(); + + org::kde::KGlobalAccel kglobalaccel( + "org.kde.kglobalaccel", + "/kglobalaccel", + d->bus); + + if (!kglobalaccel.isValid()) { + QString errorString; + QDBusError error = kglobalaccel.lastError(); + // The global shortcuts DBus service manages all global shortcuts and we + // can't do anything useful without it. + if (error.isValid()) { + errorString = i18n("Message: %1\nError: %2", error.message(), error.name()); + } + + KMessageBox::sorry( + this, + i18n("Failed to contact the KDE global shortcuts daemon\n") + + errorString ); + return; + } + + // Undo all changes not yet applied + undo(); + clear(); + + QDBusReply< QList > componentsRc = kglobalaccel.allComponents(); + if (!componentsRc.isValid()) + { + // Sometimes error pop up only after the first real call. + QString errorString; + QDBusError error = componentsRc.error(); + // The global shortcuts DBus service manages all global shortcuts and we + // can't do anything useful without it. + if (error.isValid()) { + errorString = i18n("Message: %1\nError: %2", error.message(), error.name()); + } + + KMessageBox::sorry( + this, + i18n("Failed to contact the KDE global shortcuts daemon\n") + + errorString ); + return; + } + QList components = componentsRc; + + Q_FOREACH(const QDBusObjectPath &componentPath, components) { + d->loadComponent(componentPath); + } // Q_FOREACH(component) +} + + +void KGlobalShortcutsEditor::save() +{ + // The editors are responsible for the saving + kDebug() << "Save the changes"; + Q_FOREACH (ComponentData *cd, d->components) { + cd->editor()->commit(); + } +} + + +void KGlobalShortcutsEditor::importConfiguration(KConfigBase *config) +{ + kDebug() << config->groupList(); + + // In a first step clean out the current configurations. We do this + // because we want to minimize the chance of conflicts. + Q_FOREACH (ComponentData *cd, d->components) { + KConfigGroup group(config, cd->uniqueName()); + kDebug() << cd->uniqueName() << group.name(); + if (group.exists()) { + kDebug() << "Removing" << cd->uniqueName(); + cd->editor()->clearConfiguration(); + } + } + + // Now import the new configurations. + Q_FOREACH (ComponentData *cd, d->components) { + KConfigGroup group(config, cd->uniqueName()); + if (group.exists()) { + kDebug() << "Importing" << cd->uniqueName(); + cd->editor()->importConfiguration(&group); + } + } +} + +void KGlobalShortcutsEditor::exportConfiguration(QStringList components, KConfig *config) const + { + Q_FOREACH (const QString &componentFriendly, components) + { + QHash::Iterator iter = d->components.find(componentFriendly); + if (iter == d->components.end()) + { + Q_ASSERT(iter != d->components.end()); + continue; + } + else + { + KConfigGroup group(config, (*iter)->uniqueName()); + (*iter)->editor()->exportConfiguration(&group); + } + } + } + + +void KGlobalShortcutsEditor::undo() +{ + // The editors are responsible for the undo + kDebug() << "Undo the changes"; + Q_FOREACH (ComponentData *cd, d->components) { + cd->editor()->undoChanges(); + } +} + + +bool KGlobalShortcutsEditor::isModified() const +{ + Q_FOREACH (ComponentData *cd, d->components) { + if (cd->editor()->isModified()) { + return true; + } + } + return false; +} + + +void KGlobalShortcutsEditor::_k_key_changed() +{ + emit changed(isModified()); +} + + +QDBusObjectPath KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::componentPath(const QString &componentUnique) +{ + return QDBusObjectPath(QLatin1String("/component/") + componentUnique); +} + + +void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::removeComponent() +{ + QString name = ui.components->currentText(); + QString componentUnique = components.value(name)->uniqueName(); + + // The confirmation text is different when the component is active + if (KGlobalAccel::isComponentActive(componentUnique)) { + if (KMessageBox::questionYesNo( + q, + i18n("Component '%1' is currently active. Only global shortcuts currently not active will be removed from the list.\n" + "All global shortcuts will reregister themselves with their defaults when they are next started.", componentUnique), + i18n("Remove component")) != KMessageBox::Yes) { + return; + } + } else { + if (KMessageBox::questionYesNo( + q, + i18n("Are you sure you want to remove the registered shortcuts for component '%1'? " + "The component and shortcuts will reregister themselves with their default settings" + " when they are next started.", + componentUnique), + i18n("Remove component")) != KMessageBox::Yes) { + return; + } + } + + // Initiate the removing of the component. + if (KGlobalAccel::cleanComponent(componentUnique)) { + + // Get the objectPath BEFORE we delete the source of it + QDBusObjectPath oPath = components.value(name)->dbusPath(); + // Remove the component from the gui + removeComponent(componentUnique); + + // Load it again + // ############# + if (loadComponent(oPath)) { + // Active it + q->activateComponent(name); + } + } +} + + +bool KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::loadComponent(const QDBusObjectPath &componentPath) +{ + // Get the component + org::kde::kglobalaccel::Component component( + "org.kde.kglobalaccel", + componentPath.path(), + bus); + if (!component.isValid()) { + kDebug() << "Component " << componentPath.path() << "not valid! Skipping!"; + return false; + } + + // Get the shortcut contexts. + QDBusReply shortcutContextsRc = component.getShortcutContexts(); + if (!shortcutContextsRc.isValid()) { + kDebug() << "Failed to get contexts for component " + << componentPath.path() <<"! Skipping!"; + kDebug() << shortcutContextsRc.error(); + return false; + } + QStringList shortcutContexts = shortcutContextsRc; + + // We add the shortcuts for all shortcut contexts to the editor. This + // way the user keeps full control of it's shortcuts. + Q_FOREACH (const QString &shortcutContext, shortcutContexts) { + + QDBusReply< QList > shortcutsRc = + component.allShortcutInfos(shortcutContext); + if (!shortcutsRc.isValid()) + { + kDebug() << "allShortcutInfos() failed for " << componentPath.path() << shortcutContext; + continue; + } + QList shortcuts = shortcutsRc; + // Shouldn't happen. But you never know + if (shortcuts.isEmpty()) { + kDebug() << "Got shortcut context" << shortcutContext << "without shortcuts for" + << componentPath.path(); + continue; + } + + // It's safe now + const QString componentUnique = shortcuts[0].componentUniqueName(); + QString componentContextId = componentUnique; + // kglobalaccel knows that '|' is our separator between + // component and context + if (shortcutContext != "default") { + componentContextId += QString("|") + shortcutContext; + } + + // Create a action collection for our current component:context + KActionCollection* col = new KActionCollection( + q, + KComponentData(componentContextId.toAscii())); + + // Now add the shortcuts. + Q_FOREACH (const KGlobalShortcutInfo &shortcut, shortcuts) { + + const QString &objectName = shortcut.uniqueName(); + KAction *action = col->addAction(objectName); + action->setProperty("isConfigurationAction", QVariant(true)); // see KAction::~KAction + action->setText(shortcut.friendlyName()); + + // Always call this to enable global shortcuts for the action. The editor widget + // checks it. + // Also actually loads the shortcut using the KAction::Autoloading mechanism. + // Avoid setting the default shortcut; it would just be written to the global + // configuration so we would not get the real one below. + action->setGlobalShortcut(KShortcut(), KAction::ActiveShortcut); + + // The default shortcut will never be loaded because it's pointless in a real + // application. There are no scarce resources [i.e. physical keys] to manage + // so applications can set them at will and there's no autoloading. + QList sc = shortcut.defaultKeys(); + if (sc.count()>0) { + action->setGlobalShortcut(KShortcut(sc[0]), KAction::DefaultShortcut); + } + } // Q_FOREACH(shortcut) + + QString componentFriendlyName = shortcuts[0].componentFriendlyName(); + + if (shortcuts[0].contextUniqueName() != "default") + { + componentFriendlyName += + QString('[') + shortcuts[0].contextFriendlyName() + QString(']'); + } + + q->addCollection(col, componentPath, componentContextId, componentFriendlyName ); + + } // Q_FOREACH(context) + + return true; +} + + +void KGlobalShortcutsEditor::KGlobalShortcutsEditorPrivate::removeComponent( + const QString &componentUnique ) + { + // TODO: Remove contexts too. + + Q_FOREACH (const QString &text, components.keys()) + { + if (components.value(text)->uniqueName() == componentUnique) + { + // Remove from QComboBox + int index = ui.components->findText(text); + Q_ASSERT(index != -1); + ui.components->removeItem(index); + + // Remove from QStackedWidget + stack->removeWidget(components[text]->editor()); + + // Remove the componentData + delete components.take(text); + } + } + } + + +#include "kglobalshortcutseditor.moc" diff --git a/kcontrol/keys/kglobalshortcutseditor.h b/kcontrol/keys/kglobalshortcutseditor.h new file mode 100644 index 00000000..26781862 --- /dev/null +++ b/kcontrol/keys/kglobalshortcutseditor.h @@ -0,0 +1,156 @@ +/* + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KGLOBALSHORTCUTSEDITOR_H +#define KGLOBALSHORTCUTSEDITOR_H + +#include + +#include "kshortcutseditor.h" + +class KActionCollection; +class KShortcut; +class KConfig; +class QDBusObjectPath; + +/** + * Combine a KShortcutsEditor with a KComboBox. + * + * @see KShortcutsEditor + * @author Michael Jansen + */ +class KGlobalShortcutsEditor : public QWidget +{ + Q_OBJECT + +public: + + /** + * Constructor + * + * @param parent parent widget + */ + KGlobalShortcutsEditor(QWidget *parent, + KShortcutsEditor::ActionTypes actionTypes = KShortcutsEditor::AllActions); + ~KGlobalShortcutsEditor(); + + /** + * Insert an action collection, i.e. add all it's actions to the ones already associated + * with the KShortcutsEditor object. + * + * @param collection the collection to add + * @param component title for the component + * @param title title for the subtree in the component + */ + void addCollection(KActionCollection *, const QDBusObjectPath &path, const QString &id, const QString &name); + + /** + * Clear all collections were currently hosting. Current changes are not + * undone? Do that before calling this method. + */ + void clear(); + + + /** + * Revert all changes made since the last save. + */ + void undo(); + + + /** + * Load the shortcuts from the configuration. + */ + void importConfiguration(KConfigBase *config); + + + /** + * Save the shortcuts to the configuration. + */ + void exportConfiguration(QStringList componentsFriendly, KConfig *config) const; + + + /** + * Are the unsaved changes? + */ + bool isModified() const; + + enum ComponentScope + { + AllComponents, + CurrentComponent + }; + +Q_SIGNALS: + + /** + * Indicate that state of the modules contents has changed. + * + * @param state changed or not + */ + void changed(bool); + + +public Q_SLOTS: + + /** + * Activate the component \a component. + * + * @param component the component + */ + void activateComponent(const QString &component); + + /** + * Set all shortcuts to none. + */ + void clearConfiguration(); + + /** + * Load/Reload the global shortcuts + */ + void load(); + + /** + * Make the changes persistent. + * + * That's function is not really saving. Global shortcuts are saved immediately. This + * prevent the undo on deleting the editor. + */ + void save(); + + /** + * Set shortcuts to their default value; + */ + void defaults(ComponentScope scope); + + virtual void importScheme(); + virtual void exportScheme(); + +private Q_SLOTS: + void _k_key_changed(); + +private: + + friend class KGlobalShortcutsEditorPrivate; + class KGlobalShortcutsEditorPrivate; + KGlobalShortcutsEditorPrivate *const d; + + Q_DISABLE_COPY(KGlobalShortcutsEditor) + + Q_PRIVATE_SLOT(d, void removeComponent()) +}; // class KGlobalShortcutsEditor + +#endif // KGLOBALSHORTCUTSEDITOR_H diff --git a/kcontrol/keys/kglobalshortcutseditor.ui b/kcontrol/keys/kglobalshortcutseditor.ui new file mode 100644 index 00000000..444103e2 --- /dev/null +++ b/kcontrol/keys/kglobalshortcutseditor.ui @@ -0,0 +1,57 @@ + + + KGlobalShortcutsEditor + + + + 0 + 0 + 612 + 516 + + + + + + + + + KDE component: + + + + + + + + 0 + 0 + + + + + + + + File + + + + + + + + + + KComboBox + QComboBox +
    kcombobox.h
    +
    +
    + + components + menu_button + + + +
    diff --git a/kcontrol/keys/schemes/kde3.kksrc b/kcontrol/keys/schemes/kde3.kksrc new file mode 100644 index 00000000..336757d3 --- /dev/null +++ b/kcontrol/keys/schemes/kde3.kksrc @@ -0,0 +1,166 @@ +[Settings] +Name=KDE Default for 3 Modifier Keys +Name[af]=Standaard KDE vir 3 verandering sleutels +Name[ar]=مبدئي كدي لـ3 مفاتيح مغيرة +Name[ast]=Predetermináu de KDE de 3 modificadores de tecláu +Name[be]=Стандартны для KDE з трыма клавішамі мадыфікацыі +Name[be@latin]=Zmoŭčanaja schiema „KDE” dla 3 klavišnych madyfikataraŭ +Name[bg]=KDE (с 3 модификационни клавиша) +Name[ca]=Omissió del KDE per a 3 tecles modificadores +Name[ca@valencia]=Omissió del KDE per a 3 tecles modificadores +Name[cs]=Výchozí pro KDE (3 modifikátory) +Name[csb]=Domëslny nastôw KDE dlô 3 klawiszów zjinaczi +Name[cy]=Rhagosodion KDE i 3 Bysell Addasu +Name[da]=KDE-standard med 3 modifikatortaster +Name[de]=KDE-Standard für 3 Sondertasten +Name[el]=Προκαθορισμένο του KDE για 3 τροποποιητές +Name[en_GB]=KDE Default for 3 Modifier Keys +Name[eo]=KDE-defaŭlto por 3 modifoklavoj +Name[es]=Predeterminado de KDE de 3 modificadores de teclado +Name[et]=KDE vaikeskeem 3 muuteklahviga +Name[eu]=KDE lehenetsia 3 tekla modifikatzailekin +Name[fa]=پیش‌فرض KDE برای ۳ کلید تغییردهنده +Name[fi]=KDE oletus 3:lle muokkausnäppäimelle +Name[fr]=KDE par défaut pour 3 touches de modifications +Name[fy]=KDE-standert foar 3 modifikaasjetoetsen +Name[ga]=Réamhshocrú KDE le haghaidh trí eochair mhionathraithe +Name[gl]=Predeterminado de KDE para 3 teclas modificadoras +Name[gu]=૩ બદલેલ કળો માટે KDE મૂળભૂત +Name[he]=ברירת המחדל של KDE עבור 3 כפתורים משני מצב +Name[hi]=3 मॉडीफ़ायर कुंजियों के लिए केडीई डिफ़ॉल्ट +Name[hne]=3 माडीफायर कुंजी मन बर केडीई डिफाल्ट +Name[hr]=KDE zadano za 3 modifikatorske tipke +Name[hsb]=KDE-standard za tři modifikowace tasty +Name[hu]=KDE-s alapértelmezés (3 módosító billentyűvel) +Name[ia]=KDE predefinite pro 3 claves modificator +Name[id]=Standar KDE untuk 3 Tombol Pengubah +Name[is]=Sjálfgefið KDE fyrir 3 breytilykla +Name[it]=Predefinito di KDE per 3 tasti modificatori +Name[ja]=KDE 標準 (修飾キー 3 個) +Name[kk]=3 түрлендіру пернелі KDE-нің әдетті баптауы +Name[km]=លំនាំដើម​របស់ KDE សម្រាប់​សោ​កែប្រែ ៣ +Name[kn]=೩ ಪರಿವರ್ತಕ ಕೀಲಿಗಳಿಗೆ ಕೆಡಿಇ ಪೂರ್ವನಿಯೋಜನೆ +Name[ko]=세 개의 수정자 키를 사용하는 KDE 기본값 +Name[ku]=KDE Standard ji bo 3 Bişkojkên Guherker +Name[lt]=KDE numatytoji 3 lygio klavišams – modifikatoriams +Name[lv]=KDE noklusējums ar 3 modifikācijas taustiņiem +Name[mai]=3 माडीफायर कुंजीसभ क' लेल केडीई पूर्वनिर्धारित +Name[mk]=KDE-стандардно за 3 копчиња-модификатори +Name[ml]=3 മോഡിഫയര്‍ കീകള്‍ക്കു് കെഡിഇയുടെ സഹജമായതു് +Name[mr]=3 संपादन की करीता KDE मुलभूत +Name[ms]=Piawai KDE untuk 3 Kekunci Pengubah Suai +Name[nb]=KDE-standard for tre valgtaster +Name[nds]=KDE-Standard för 3 Sünnertasten +Name[ne]=३ परिमार्जक कुञ्जीका लागि पूर्वनिर्धारित केडीई +Name[nl]=KDE-standaard voor 3 modificatietoetsen +Name[nn]=KDE-standard med tre valtastar +Name[or]=3ଟି ପରିବର୍ତ୍ତକ କି ପାଇଁ KDE ପୂର୍ବନିର୍ଦ୍ଧାରିତ +Name[pa]=3 ਮੋਡੀਫਾਇਰ ਸਵਿੱਚਾਂ ਲਈ KDE ਡਿਫਾਲਟ +Name[pl]=Ustawienia domyślne KDE dla 3 klawiszy modyfikatorów +Name[pt]=Predefinição do KDE para 3 Teclas Modificadoras +Name[pt_BR]=Padrão do KDE para 3 teclas modificadoras +Name[ro]=Implicit KDE pentru 3 modificatori +Name[ru]=KDE с тремя клавишами-модификаторами +Name[se]=KDE-standárda mas leat golbma válljeboalu +Name[si]=3 වෙනස් යතුරු සඳහා KDE පෙරනිමියන් +Name[sk]=KDE štandardné (3 modifikačné klávesy) +Name[sl]=Privzeto za 3 spremenilne tipke +Name[sr]=КДЕ‑ово подразумевано за три модификаторска тастера +Name[sr@ijekavian]=КДЕ‑ово подразумијевано за три модификаторска тастера +Name[sr@ijekavianlatin]=KDE‑ovo podrazumijevano za tri modifikatorska tastera +Name[sr@latin]=KDE‑ovo podrazumevano za tri modifikatorska tastera +Name[sv]=KDE-förinställt med 3 väljartangenter +Name[ta]=KDE Default for 3 Modifier Keys +Name[te]=3 సవరింపు కీలకొరకు KDE అప్రమేయం +Name[tg]=KDE с тремя клавишами-модификаторами +Name[th]=ค่าปริยายของ KDE สำหรับปุ่มเปลี่ยนหน้าที่ 3 ปุ่ม +Name[tr]=3 Değiştirici Anahtar için KDE Varsayılan +Name[uk]=Типова для KDE з 3 клавішами-модифікаторами +Name[vi]=Mặc định KDE cho 3 Phím Bổ trợ +Name[wa]=Prémetou KDE (3 tapes modifieueses) +Name[xh]=KDE Engagqibekanga ye 3 Izitsixo Mofifier +Name[x-test]=xxKDE Default for 3 Modifier Keysxx +Name[zh_CN]=三个修饰键的 KDE 默认值 +Name[zh_TW]=KDE 預設 3 個變更鍵 +Uses Win Modifier=false + +[klipper][Global Shortcuts] +clipboard_action=Ctrl+Alt+X +repeat_action=Ctrl+Alt+R +show_klipper_popup=Ctrl+Alt+V + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=Ctrl+Alt+L +Log Out Without Confirmation=none +Log Out=Ctrl+Alt+Del +Reboot Without Confirmation=none +Run Command=Alt+F2 +Show System Activity=Ctrl+Esc + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Ctrl+Print +Kill Window=Ctrl+Alt+Esc +Mouse Emulation=Alt+F12 +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Ctrl+F10 +Switch to Desktop 11=Ctrl+F11 +Switch to Desktop 12=Ctrl+F12 +Switch to Desktop 13=Ctrl+Shift+F1 +Switch to Desktop 14=Ctrl+Shift+F2 +Switch to Desktop 15=Ctrl+Shift+F3 +Switch to Desktop 16=Ctrl+Shift+F4 +Switch to Desktop 1=Ctrl+F1 +Switch to Desktop 2=Ctrl+F2 +Switch to Desktop 3=Ctrl+F3 +Switch to Desktop 4=Ctrl+F4 +Switch to Desktop 5=Ctrl+F5 +Switch to Desktop 6=Ctrl+F6 +Switch to Desktop 7=Ctrl+F7 +Switch to Desktop 8=Ctrl+F8 +Switch to Desktop 9=Ctrl+F9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab +Walk Through Desktop List=Ctrl+Tab +Walk Through Desktops (Reverse)=none +Walk Through Desktops=none +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+Tab +Window Close=Alt+F4 +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=none +Window Minimize=none +Window Move=none +Window Operations Menu=Alt+F3 +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Alt+Print +Window Shade=none +Window to Desktop 10=none +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=none +Window to Desktop 2=none +Window to Desktop 3=none +Window to Desktop 4=none +Window to Desktop 5=none +Window to Desktop 6=none +Window to Desktop 7=none +Window to Desktop 8=none +Window to Desktop 9=none +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/schemes/kde4.kksrc b/kcontrol/keys/schemes/kde4.kksrc new file mode 100644 index 00000000..2ea1432b --- /dev/null +++ b/kcontrol/keys/schemes/kde4.kksrc @@ -0,0 +1,166 @@ +[Settings] +Name=KDE Default for 4 Modifier Keys +Name[af]=Standaard KDE vir 4 verandering sleutels +Name[ar]=مبدئي كدي لـ4 مفاتيح مغيرة +Name[ast]=Predetermináu de KDE de 4 modificadores de tecláu +Name[be]=Стандартны для KDE з чатырма клавішамі мадыфікацыі +Name[be@latin]=Zmoŭčanaja schiema „KDE” dla 4 klavišnych madyfikataraŭ +Name[bg]=KDE (с 4 модификационни клавиша) +Name[ca]=Omissió del KDE per a 4 tecles modificadores +Name[ca@valencia]=Omissió del KDE per a 4 tecles modificadores +Name[cs]=Výchozí pro KDE (4 modifikátory) +Name[csb]=Domëslny nastôw KDE dlô 4 klawiszów zjinaczi +Name[cy]=Rhagosodion KDE i 4 Bysell Addasu +Name[da]=KDE-standard med 4 modifikatortaster +Name[de]=KDE-Standard für 4 Sondertasten +Name[el]=Προκαθορισμένο του KDE για 4 τροποποιητές +Name[en_GB]=KDE Default for 4 Modifier Keys +Name[eo]=KDE-defaŭlto por 4 modifoklavoj +Name[es]=Predeterminado de KDE de 4 modificadores de teclado +Name[et]=KDE vaikeskeem 4 muuteklahviga +Name[eu]=KDE lehenetsia 4 tekla modifikatzailekin +Name[fa]=پیش‌فرض KDE برای ۴ کلید تغییردهنده +Name[fi]=KDE oletus 4:lle muokkausnäppäimelle +Name[fr]=KDE par défaut pour 4 touches de modifications +Name[fy]=KDE-standert foar 4 modifikaasjetoetsen +Name[ga]=Réamhshocrú KDE le haghaidh ceithre eochair mhionathraithe +Name[gl]=Predeterminado de KDE para 4 teclas modificadoras +Name[gu]=૪ બદલેલ કળો માટે KDE મૂળભૂત +Name[he]=ברירת המחדל של KDE עבור 4 כפתורים משני מצב +Name[hi]=4 मॉडीफ़ायर कुंजियों के लिए केडीई डिफ़ॉल्ट +Name[hne]=4 माडीफायर कुंजी मन बर केडीई डिफाल्ट +Name[hr]=KDE zadano za 4 modifikatorske tipke +Name[hsb]=KDE-standard za štyri modifikowace tasty +Name[hu]=KDE-s alapértelmezés (4 módosító billentyűvel) +Name[ia]=KDE predefinite pro 4 claves modificator +Name[id]=Standar KDE untuk 4 Tombol Pengubah +Name[is]=Sjálfgefið KDE fyrir 4 breytilykla +Name[it]=Predefinito di KDE per 4 tasti modificatori +Name[ja]=KDE 標準 (修飾キー 4 個) +Name[kk]=4 түрлендіру пернелі KDE-нің әдетті баптауы +Name[km]=លំនាំដើម​របស់ KDE សម្រាប់​សោ​កែប្រែ ៤ +Name[kn]=೪ ಪರಿವರ್ತಕ ಕೀಲಿಗಳಿಗೆ ಕೆಡಿಇ ಪೂರ್ವನಿಯೋಜನೆ +Name[ko]=네 개의 수정자 키를 사용하는 KDE 기본값 +Name[ku]=KDE Standard ji bo 4 Bişkojkên Guherker +Name[lt]=KDE numatytoji 4 lygio klavišams – modifikatoriams +Name[lv]=KDE noklusējums ar 4 modifikācijas taustiņiem +Name[mai]=4 माडीफायर कुंजियों क' लेल केडीई पूर्वनिर्धारित +Name[mk]=KDE-стандардно за 4 копчиња-модификатори +Name[ml]=4 മോഡിഫയര്‍ കീകള്‍ക്കു് കെഡിഇയുടെ സഹജമായതു് +Name[mr]=4 संपादन की करीता KDE मुलभूत +Name[ms]=Piawai KDE untuk 4 Kekunci Pengubah Suai +Name[nb]=KDE-standard for fire valgtaster +Name[nds]=KDE-Standard för 4 Sünnertasten +Name[ne]=४ परिमार्जक कुञ्जीका लागि पूर्वनिर्धारित केडीई +Name[nl]=KDE-standaard voor 4 modificatietoetsen +Name[nn]=KDE-standard med fire valtastar +Name[or]=4ଟି ପରିବର୍ତ୍ତକ କି ପାଇଁ KDE ପୂର୍ବନିର୍ଦ୍ଧାରିତ +Name[pa]=4 ਮੋਡੀਫਾਇਰ ਸਵਿੱਚਾਂ ਲਈ KDE ਡਿਫਾਲਟ +Name[pl]=Ustawienia domyślne KDE dla 4 klawiszy modyfikatorów +Name[pt]=Predefinição do KDE para 4 Teclas Modificadoras +Name[pt_BR]=Padrão do KDE para 4 teclas modificadoras +Name[ro]=Implicit KDE pentru 4 modificatori +Name[ru]=KDE с четырьмя клавишами-модификаторами +Name[se]=KDE-standárda mas leat njeallje válljenboalu +Name[si]=4 වෙනස් යතුරු සඳහා KDE පෙරනිමියන් +Name[sk]=KDE štandardné (4 modifikačné klávesy) +Name[sl]=Privzeto za 4 spremenilne tipke +Name[sr]=КДЕ‑ово подразумевано за четири модификаторска тастера +Name[sr@ijekavian]=КДЕ‑ово подразумијевано за четири модификаторска тастера +Name[sr@ijekavianlatin]=KDE‑ovo podrazumijevano za četiri modifikatorska tastera +Name[sr@latin]=KDE‑ovo podrazumevano za četiri modifikatorska tastera +Name[sv]=KDE-förinställt med 4 väljartangenter +Name[ta]=KDE Default for 4 Modifier Keys +Name[te]=4 సవరింపు కీలకొరకు KDE అప్రమేయం +Name[tg]=KDE с четырьмя клавишами-модификаторами +Name[th]=ค่าปริยายของ KDE สำหรับปุ่มเปลี่ยนหน้าที่ 4 ปุ่ม +Name[tr]=4 Değiştirici Anahtar için KDE Varsayılan +Name[uk]=Типова для KDE з 4 клавішами-модифікаторами +Name[vi]=Mặc định KDE cho 4 Phím Bổ trợ +Name[wa]=Prémetou KDE (4 tapes modifieueses) +Name[xh]=KDE Engagqibekanga ye 4 Izitsixo Mofifier +Name[x-test]=xxKDE Default for 4 Modifier Keysxx +Name[zh_CN]=四个修饰键的 KDE 默认值 +Name[zh_TW]=KDE 預設 4 個變更鍵 +Uses Win Modifier=true + +[klipper][Global Shortcuts] +clipboard_action=Meta+Ctrl+X +repeat_action=Meta+Ctrl+R +show_klipper_popup=Meta+Ctrl+V + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=Meta+ScrollLock +Log Out Without Confirmation=none +Log Out=Meta+Esc +Reboot Without Confirmation=none +Run Command=Meta+Return; Alt+F2 +Show System Activity=Meta+Ctrl+Pause + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Meta+Print +Kill Window=Meta+Ctrl+Del +Mouse Emulation=none +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Meta+F10 +Switch to Desktop 11=none +Switch to Desktop 12=none +Switch to Desktop 13=none +Switch to Desktop 14=none +Switch to Desktop 15=none +Switch to Desktop 16=none +Switch to Desktop 1=Meta+F1 +Switch to Desktop 2=Meta+F2 +Switch to Desktop 3=Meta+F3 +Switch to Desktop 4=Meta+F4 +Switch to Desktop 5=Meta+F5 +Switch to Desktop 6=Meta+F6 +Switch to Desktop 7=Meta+F7 +Switch to Desktop 8=Meta+F8 +Switch to Desktop 9=Meta+F9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=none +Walk Through Desktop List=none +Walk Through Desktops (Reverse)=Meta+Shift+Tab +Walk Through Desktops=Meta+Tab +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+Tab +Window Close=Alt+Esc; Alt+F4 +Window Lower=none +Window Maximize Horizontal=Meta+= +Window Maximize Vertical=Meta+| +Window Maximize=Meta++ +Window Minimize=Meta+- +Window Move=none +Window Operations Menu=Alt+Menu +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Alt+Print +Window Shade=Meta+_ +Window to Desktop 10=Meta+Alt+F10 +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=Meta+Alt+F1 +Window to Desktop 2=Meta+Alt+F2 +Window to Desktop 3=Meta+Alt+F3 +Window to Desktop 4=Meta+Alt+F4 +Window to Desktop 5=Meta+Alt+F5 +Window to Desktop 6=Meta+Alt+F6 +Window to Desktop 7=Meta+Alt+F7 +Window to Desktop 8=Meta+Alt+F8 +Window to Desktop 9=Meta+Alt+F9 +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Meta+Ctrl+K diff --git a/kcontrol/keys/schemes/mac4.kksrc b/kcontrol/keys/schemes/mac4.kksrc new file mode 100644 index 00000000..0ecde007 --- /dev/null +++ b/kcontrol/keys/schemes/mac4.kksrc @@ -0,0 +1,171 @@ +[Settings] +Name=Mac Scheme +Name[af]=Mac Tema +Name[ar]=مخطط الماك +Name[ast]=Tema Mac +Name[be]=Схема Mac +Name[be@latin]=Schiema „Mac” +Name[bg]=Mac +Name[bn]=ম্যাক্ স্কীম +Name[bn_IN]=Mac স্কিম +Name[br]=Steuñv Mac +Name[ca]=Esquema Mac +Name[ca@valencia]=Esquema Mac +Name[cs]=Mac schéma +Name[csb]=Mòtiw Mac-a +Name[cy]=Cynllun Mac +Name[da]=Mac-system +Name[de]=Mac-Design +Name[el]=Σχήμα Mac +Name[en_GB]=Mac Scheme +Name[eo]=Makintoŝa aranĝo +Name[es]=Tema Mac +Name[et]=Maci skeem +Name[eu]=Mac eskema +Name[fa]=طرحواره مکینتاش +Name[fi]=Mac-skeema +Name[fr]=Agencement Mac +Name[fy]=Mac-skema +Name[ga]=Scéim Mac +Name[gl]=Esquema de Mac +Name[gu]=મેક પધ્ધતિ +Name[he]=ערכת Mac +Name[hi]=मॅक प्रसंग +Name[hne]=मॅक प्रसंग +Name[hr]=Mac shema +Name[hsb]=Mac-šema +Name[hu]=Mac +Name[ia]=Schema Mac +Name[id]=Skema Mac +Name[is]=Mac þema +Name[it]=Schema Mac +Name[ja]=Macintosh スキーマ +Name[ka]=Mac სქემა +Name[kk]=Mac сұлбасы +Name[km]=គ្រោងការណ៍ Mac +Name[kn]=ಮ್ಯಾಕ್ ಪದ್ಧತಿ (ಸ್ಕೀಮ್) +Name[ko]=Mac 배열 +Name[ku]=Dirbê Mac +Name[lt]=Mac schema +Name[lv]=Mac shēma +Name[mai]=मैक प्रसंग +Name[mk]=Mac-шема +Name[ml]=മാക് പദ്ധതി +Name[mr]=मॅक सुत्रयोजना +Name[nb]=Mac-oppsett +Name[nds]=Mac-Vörbild +Name[ne]=म्याक योजना +Name[nl]=Mac-schema +Name[nn]=Mac-oppsett +Name[or]=Mac ଯୋଜନା +Name[pa]=Mac ਸਕੀਮ +Name[pl]=Motyw Mac-a +Name[pt]=Esquema do Mac +Name[pt_BR]=Esquema do Mac +Name[ro]=Schemă Mac +Name[ru]=Mac +Name[se]=Mac-coakkáldat +Name[si]=Mac ක්‍රමය +Name[sk]=Mac schéma +Name[sl]=Shema Mac +Name[sr]=Мекинтошева шема +Name[sr@ijekavian]=Мекинтошева шема +Name[sr@ijekavianlatin]=Macintosheva šema +Name[sr@latin]=Macintosheva šema +Name[sv]=Mac schema +Name[ta]=Mac முறைமை +Name[te]=Mac స్కీమ్ +Name[tg]=Нақшаи Mac +Name[th]=ใช้แบบของ MAC +Name[tr]=Mac Şeması +Name[uk]=Схема Mac +Name[uz]=Mac mavzusi +Name[uz@cyrillic]=Mac мавзуси +Name[vi]=Phối hợp của Mac +Name[wa]=Djeu d' rascourtis Mac +Name[xh]=Udweliso lwe Mac +Name[x-test]=xxMac Schemexx +Name[zh_CN]=Mac 方案 +Name[zh_TW]=Mac 機制 +Uses Win Modifier=true + +[klipper][Global Shortcuts] +clipboard_action=Ctrl+Alt+X +repeat_action=Ctrl+Alt+R +show_klipper_popup=Ctrl+Alt+V + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=Ctrl+Alt+L +Log Out Without Confirmation=none +Log Out=Ctrl+Alt+Del +Reboot Without Confirmation=none +Run Command=Alt+F2 +Show System Activity=Ctrl+Esc + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Ctrl+Shift+3 +Kill Window=Ctrl+Alt+Esc +Mouse Emulation=none +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Ctrl+F10 +Switch to Desktop 11=Ctrl+F11 +Switch to Desktop 12=Ctrl+F12 +Switch to Desktop 13=Ctrl+Shift+F1 +Switch to Desktop 14=Ctrl+Shift+F2 +Switch to Desktop 15=Ctrl+Shift+F3 +Switch to Desktop 16=Ctrl+Shift+F4 +Switch to Desktop 1=Ctrl+F1 +Switch to Desktop 2=Ctrl+F2 +Switch to Desktop 3=Ctrl+F3 +Switch to Desktop 4=Ctrl+F4 +Switch to Desktop 5=Ctrl+F5 +Switch to Desktop 6=Ctrl+F6 +Switch to Desktop 7=Ctrl+F7 +Switch to Desktop 8=Ctrl+F8 +Switch to Desktop 9=Ctrl+F9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=Ctrl+E +Walk Through Desktop List (Reverse)=none +Walk Through Desktop List=none +Walk Through Desktops (Reverse)=Alt+Shift+Tab +Walk Through Desktops=Alt+Tab +Walk Through Windows (Reverse)=Ctrl+Shift+Tab +Walk Through Windows=Ctrl+Tab +Window Close=Alt+F4 +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=none +Window Minimize=none +Window Move=none +Window Operations Menu=Alt+F3 +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Ctrl+Shift+4 +Window Shade=none +Window to Desktop 10=none +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=none +Window to Desktop 2=none +Window to Desktop 3=none +Window to Desktop 4=none +Window to Desktop 5=none +Window to Desktop 6=none +Window to Desktop 7=none +Window to Desktop 8=none +Window to Desktop 9=none +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/schemes/old_kde3.kksrc b/kcontrol/keys/schemes/old_kde3.kksrc new file mode 100644 index 00000000..561ff99f --- /dev/null +++ b/kcontrol/keys/schemes/old_kde3.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Alt+F1 +Reboot Computer=none +Show Window List=Alt+F5 +Toggle Showing Desktop=Ctrl+Alt+D + +[Shortcuts] +AddBookmark=Ctrl+B +Back=Alt+Left +Close=Ctrl+W +Copy=Ctrl+C; Ctrl+Insert +Cut=Ctrl+X; Shift+Del +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V; Shift+Insert +PopupMenuContext=Menu +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit=Ctrl+Q +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_kde4.kksrc b/kcontrol/keys/schemes/old_kde4.kksrc new file mode 100644 index 00000000..64dfd8da --- /dev/null +++ b/kcontrol/keys/schemes/old_kde4.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Meta+Menu +Reboot Computer=none +Show Window List=Meta+0 +Toggle Showing Desktop=Meta+Ctrl+D + +[Shortcuts] +AddBookmark=Ctrl+B +Back=Alt+Left +Close=Ctrl+Esc; Ctrl+W +Copy=Ctrl+C; Ctrl+Insert +Cut=Ctrl+X; Shift+Del +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V; Shift+Insert +PopupMenuContext=Menu +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit=Ctrl+Q +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_mac4.kksrc b/kcontrol/keys/schemes/old_mac4.kksrc new file mode 100644 index 00000000..f0da90de --- /dev/null +++ b/kcontrol/keys/schemes/old_mac4.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Alt+F1 +Reboot Computer=none +Show Window List=Alt+F5 +Toggle Showing Desktop=Ctrl+Alt+D + +[Shortcuts] +AddBookmark=Ctrl+B +Back=Alt+Left +Close=Ctrl+W +Copy=Ctrl+C +Cut=Ctrl+X +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=Ctrl+G +FindPrev=Ctrl+Shift+G +Forward=Alt+Right +GotoLine=none +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V +PopupMenuContext=Menu +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit=Ctrl+Q +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_unix3.kksrc b/kcontrol/keys/schemes/old_unix3.kksrc new file mode 100644 index 00000000..6e724007 --- /dev/null +++ b/kcontrol/keys/schemes/old_unix3.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Alt+F1 +Reboot Computer=none +Show Window List=none +Toggle Showing Desktop=Ctrl+Alt+D + +[Shortcuts] +AddBookmark=Ctrl+B +Back=Alt+Left +Close=Ctrl+W +Copy=Ctrl+C +Cut=Ctrl+X +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+S +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V +PopupMenuContext=Menu +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit=Ctrl+Q +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll= +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_win3.kksrc b/kcontrol/keys/schemes/old_win3.kksrc new file mode 100644 index 00000000..410d6877 --- /dev/null +++ b/kcontrol/keys/schemes/old_win3.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Ctrl+Esc +Reboot Computer=none +Show Window List=none +Toggle Showing Desktop=Ctrl+Alt+D + +[Shortcuts] +AddBookmark=Ctrl+D +Back=Alt+Left +Close=Ctrl+F4; Ctrl+W +Copy=Ctrl+C; Ctrl+Insert +Cut=Ctrl+X; Shift+Del +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V; Shift+Insert +PopupMenuContext=F10 +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit= +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_win4.kksrc b/kcontrol/keys/schemes/old_win4.kksrc new file mode 100644 index 00000000..3859eb68 --- /dev/null +++ b/kcontrol/keys/schemes/old_win4.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Ctrl+Esc +Reboot Computer=none +Show Window List=none +Toggle Showing Desktop=Meta+D; Win+M + +[Shortcuts] +AddBookmark=Ctrl+D +Back=Alt+Left +Close=Ctrl+F4; Ctrl+W +Copy=Ctrl+C; Ctrl+Insert +Cut=Ctrl+X; Shift+Del +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V; Shift+Insert +PopupMenuContext=F10 +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit= +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/old_wm3.kksrc b/kcontrol/keys/schemes/old_wm3.kksrc new file mode 100644 index 00000000..561ff99f --- /dev/null +++ b/kcontrol/keys/schemes/old_wm3.kksrc @@ -0,0 +1,51 @@ + +[Global Shortcuts] +Halt Computer=none +Popup Launch Menu=Alt+F1 +Reboot Computer=none +Show Window List=Alt+F5 +Toggle Showing Desktop=Ctrl+Alt+D + +[Shortcuts] +AddBookmark=Ctrl+B +Back=Alt+Left +Close=Ctrl+W +Copy=Ctrl+C; Ctrl+Insert +Cut=Ctrl+X; Shift+Del +DeleteWordBack=Ctrl+Backspace +DeleteWordForward=Ctrl+Del +Deselect=Ctrl+Shift+A +End=Ctrl+End +Find=Ctrl+F +FindNext=F3 +FindPrev=Shift+F3 +Forward=Alt+Right +GotoLine=Ctrl+G +Help=F1 +Home=Ctrl+Home +Insert=Ctrl+Insert +New=Ctrl+N +Next=Next +NextCompletion=Ctrl+Down +Open=Ctrl+O +Paste=Ctrl+V; Shift+Insert +PopupMenuContext=Menu +PrevCompletion=Ctrl+Up +Print=Ctrl+P +Prior=Prior +Quit=Ctrl+Q +Redo=Ctrl+Shift+Z +Reload=F5 +Replace=Ctrl+R +RotateDown=Down +RotateUp=Up +Save=Ctrl+S +SelectAll=Ctrl+A +ShowMenubar=Ctrl+M +SubstringCompletion=Ctrl+T +TextCompletion=Ctrl+E +Undo=Ctrl+Z +Up=Alt+Up +WhatsThis=Shift+F1 +ZoomIn=Ctrl++ +ZoomOut=Ctrl+- diff --git a/kcontrol/keys/schemes/split_kksrc b/kcontrol/keys/schemes/split_kksrc new file mode 100755 index 00000000..9fab61e4 --- /dev/null +++ b/kcontrol/keys/schemes/split_kksrc @@ -0,0 +1,111 @@ +#!/usr/bin/perl + +use strict; +use warnings; + + +foreach my $file( @ARGV ) + { + print STDERR "Working on $file\n"; + + open(my $FILEHD, $file) or do + { + print STDERR "Failed to open $file : $!"; + next; + }; + + open(my $NEWHD, ">new_$file") or do + { + print STDERR "Failed to open new_$file : $!"; + next; + }; + + open(my $OLDHD, ">old_$file") or do + { + print STDERR "Failed to open old_$file : $!"; + next; + }; + + my $process = 0; + my @kwin; + my @krunner; + my @klipper; + my @kxkb; + for( <$FILEHD> ) + { + /\[Settings\]/ and do { print $NEWHD $_; next; }; + /Name(\[[a-zA-Z_@]*\])?/ and do { print $NEWHD $_; next; }; + /Name\[x-test\]/ and do { print $NEWHD $_; next; }; + /Uses Win Modifier/ and do { print $NEWHD $_; next; }; + + /\[Global Shortcuts\]/ and do { print $OLDHD $_; $process = 1; next; }; + /\[Shortcuts\]/ and do { print $OLDHD $_; $process = 0; next; }; + + s/Alt\+Ctrl/Ctrl+Alt/; + s/Delete/Del/; + s/Escape/Esc/; + s/Win/Meta/; + + if ($process) + { + /Desktop Screenshot=/ and do { s/Desktop Screenshot=/Desktop Screenshot to Clipboard=/; push @kwin, $_; next; }; + /Kill Window=/ and do { push @kwin, $_; next; }; + /Mouse Emulation/ and do { push @kwin, $_; next; }; + /Switch to Desktop [0-9]+/ and do { push @kwin, $_; next; }; + /Switch to (Next|Previous) Desktop=/ and do { push @kwin, $_; next; }; + /Switch One Desktop / and do { push @kwin, $_; next; }; + /Toggle Window Raise\/Lower=/ and do { push @kwin, $_; next; }; + /Walk Through Desktop/ and do { push @kwin, $_; next; }; + /Walk Through Windows/ and do { push @kwin, $_; next; }; + /Window to (Next |Previous )?Desktop/ and do { push @kwin, $_; next; }; + /Window (Close|Minimize|Lower|Move|Raise|Resize|Shade)/ and do { push @kwin, $_; next; }; + /Window Maximize/ and do { push @kwin, $_; next; }; + /Window Operations Menu=/ and do { s/Window Screenshot=/Window Screenshot to Clipboard=/; push @kwin, $_; next; }; + /Window Screenshot=/ and do { s/Window Screenshot=/Window Screenshot to Clipboard=/; push @kwin, $_; next; }; + + /Switch to Next Keyboard Layout/ and do { push @kxkb, $_; next; }; + + /clipboard_action/ and do { push @klipper, $_; next; }; + /repeat_action/ and do { push @klipper, $_; next; }; + /show_klipper_popup/ and do { push @klipper, $_; next; }; + + /Halt without Confirmation/ and do { s/Halt without Confirmation/Halt Without Confirmation/; push @krunner, $_; next; }; + /Lock Session/ and do { push @krunner, $_; next; }; + /Log Out/ and do { push @krunner, $_; next; }; + /Log Out Without Confirmation/ and do { push @krunner, $_; next; }; + /Lock Session/ and do { push @krunner, $_; next; }; + /Reboot without Confirmation/ and do { s/Reboot without Confirmation/Reboot Without Confirmation/; push @krunner, $_; next; }; + /Run Command/ and do { push @krunner, $_; next; }; + /Show Taskmanager/ and do { s/Show Taskmanager/Show System Activity/; push @krunner, $_; next; }; + } + + print $OLDHD $_; + } + + print $NEWHD "\n[klipper][Global Shortcuts]\n"; + print $NEWHD sort @klipper; + print $NEWHD "\n[krunner][Global Shortcuts]\n"; + print $NEWHD sort @krunner; + print $NEWHD "\n[kwin][Global Shortcuts]\n"; + print $NEWHD sort @kwin; + print $NEWHD "\n[kxkb][Global Shortcuts]\n"; + print $NEWHD sort @kxkb; + + close($FILEHD) or do + { + print STDERR "Failed to close $file : $!"; + next; + }; + + close($NEWHD) or do + { + print STDERR "Failed to close new_$file : $!"; + next; + }; + + close($OLDHD) or do + { + print STDERR "Failed to close old_$file : $!"; + next; + }; + } diff --git a/kcontrol/keys/schemes/unix3.kksrc b/kcontrol/keys/schemes/unix3.kksrc new file mode 100644 index 00000000..1845cde7 --- /dev/null +++ b/kcontrol/keys/schemes/unix3.kksrc @@ -0,0 +1,171 @@ +[Settings] +Name=UNIX Scheme +Name[af]=UNIX Tema +Name[ar]=مخطط يونِكس +Name[ast]=Esquema UNIX +Name[be]=Схема UNIX +Name[be@latin]=Schiema „UNIX” +Name[bg]=UNIX +Name[bn]=ইউনিক্স স্কীম +Name[bn_IN]=UNIX স্কিম +Name[br]=Steuñv UNIX +Name[ca]=Esquema UNIX +Name[ca@valencia]=Esquema UNIX +Name[cs]=Unixové schéma +Name[csb]=Mòtiw Uniksa +Name[cy]=Cynllun UNIX +Name[da]=UNIX-system +Name[de]=UNIX-Design +Name[el]=Σχήμα UNIX +Name[en_GB]=UNIX Scheme +Name[eo]=Uniksa aranĝo +Name[es]=Esquema UNIX +Name[et]=UNIX-i skeem +Name[eu]=UNIX eskema +Name[fa]=طرحواره یونیکس +Name[fi]=UNIX-skeema +Name[fr]=Agencement UNIX +Name[fy]=UNIX-skema +Name[ga]=Scéim UNIX +Name[gl]=Esquema de UNIX +Name[gu]=UNIX પધ્ધતિ +Name[he]=ערכת UNIX +Name[hi]=यूनिक्स प्रसंग +Name[hne]=यूनिक्स प्रसंग +Name[hr]=UNIX shema +Name[hsb]=UNIX-šema +Name[hu]=UNIX +Name[ia]=Schema UNIX +Name[id]=Skema UNIX +Name[is]=UNIX þema +Name[it]=Schema UNIX +Name[ja]=UNIX スキーマ +Name[ka]=UNIX სქემა +Name[kk]=UNIX сұлбасы +Name[km]=គ្រោងការណ៍​យូនីក +Name[kn]=ಯುನೀಕ್ಸ್ ಪದ್ಧತಿ (ಸ್ಕೀಮ್) +Name[ko]=UNIX 배열 +Name[ku]=Şemaya UNIX'ê +Name[lt]=UNIX schema +Name[lv]=UNIX shēma +Name[mai]=यूनिक्स प्रसंग +Name[mk]=UNIX-шема +Name[ml]=യൂണിക്സ് പദ്ധതി +Name[mr]=UNIX सुत्रयोजना +Name[nb]=UNIX-oppsett +Name[nds]=UNIX-Vörbild +Name[ne]=यूनिक्स योजना +Name[nl]=UNIX-schema +Name[nn]=UNIX-oppsett +Name[or]=UNIX ଯୋଜନା +Name[pa]=UNIX ਸਕੀਮ +Name[pl]=Motyw Uniksa +Name[pt]=Esquema do UNIX +Name[pt_BR]=Esquema do UNIX +Name[ro]=Schemă UNIX +Name[ru]=UNIX +Name[se]=UNIX-čoahkkáldat +Name[si]=UNIX ක්‍රමය +Name[sk]=UNIX schéma +Name[sl]=Shema UNIX +Name[sr]=Уникс шема +Name[sr@ijekavian]=Уникс шема +Name[sr@ijekavianlatin]=Unix šema +Name[sr@latin]=Unix šema +Name[sv]=Unix schema +Name[ta]=UNIX முறைமை +Name[te]=UNIX స్కీమ్ +Name[tg]=Нақшаи UNIX +Name[th]=ใช้แบบของ UNIX +Name[tr]=UNIX Şeması +Name[uk]=Схема UNIX +Name[uz]=UNIX mavzusi +Name[uz@cyrillic]=UNIX мавзуси +Name[vi]=Phối hợp của Unix +Name[wa]=Djeu d' rascourtis Unix +Name[xh]=Udweliso lwe UNIX +Name[x-test]=xxUNIX Schemexx +Name[zh_CN]=Unix 方案 +Name[zh_TW]=UNIX 機制 +Uses Win Modifier=false + +[klipper][Global Shortcuts] +clipboard_action=none +repeat_action=Ctrl+Alt+R +show_klipper_popup=none + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=Ctrl+Alt+L +Log Out Without Confirmation=none +Log Out=Ctrl+Alt+Del +Reboot Without Confirmation=none +Run Command=Alt+F2 +Show System Activity=Ctrl+Esc + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=none +Kill Window=Alt+F9 +Mouse Emulation=Alt+F12 +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Ctrl+F10 +Switch to Desktop 11=Ctrl+F11 +Switch to Desktop 12=Ctrl+F12 +Switch to Desktop 13=Ctrl+Shift+F1 +Switch to Desktop 14=Ctrl+Shift+F2 +Switch to Desktop 15=Ctrl+Shift+F3 +Switch to Desktop 16=Ctrl+Shift+F4 +Switch to Desktop 1=Ctrl+F1 +Switch to Desktop 2=Ctrl+F2 +Switch to Desktop 3=Ctrl+F3 +Switch to Desktop 4=Ctrl+F4 +Switch to Desktop 5=Ctrl+F5 +Switch to Desktop 6=Ctrl+F6 +Switch to Desktop 7=Ctrl+F7 +Switch to Desktop 8=Ctrl+F8 +Switch to Desktop 9=Ctrl+F9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab +Walk Through Desktop List=none +Walk Through Desktops (Reverse)=none +Walk Through Desktops=Ctrl+Tab +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+F11 +Window Close=none +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=Alt+Shift+F3 +Window Minimize=Alt+F4 +Window Move=Alt+F5 +Window Operations Menu=none +Window Raise=none +Window Resize=Alt+F6 +Window Screenshot to Clipboard=none +Window Shade=none +Window to Desktop 10=none +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=none +Window to Desktop 2=none +Window to Desktop 3=none +Window to Desktop 4=none +Window to Desktop 5=none +Window to Desktop 6=none +Window to Desktop 7=none +Window to Desktop 8=none +Window to Desktop 9=none +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/schemes/win3.kksrc b/kcontrol/keys/schemes/win3.kksrc new file mode 100644 index 00000000..e1929fb7 --- /dev/null +++ b/kcontrol/keys/schemes/win3.kksrc @@ -0,0 +1,170 @@ +[Settings] +Name=Windows Scheme (Without Win Key) +Name[af]=Venster Skema (Sonder Win Sleutel) +Name[ar]=مخطط ويندوز (بدون مفتاح Win) +Name[ast]=Esquema Windows (Ensin tecla Win) +Name[be]=Схема Windows (без клавішы "Win") +Name[be@latin]=Schiema „Windows” (biaz klavišy „Win”) +Name[bg]=Windows (без клавиша Win) +Name[bn]=উইণ্ডোস্ স্কীম (উইন্ কী ব্যতীত) +Name[br]=Steuñv Windows (hep stokell Win) +Name[ca]=Esquema Windows (sense la tecla Win) +Name[ca@valencia]=Esquema Windows (sense la tecla Win) +Name[cs]=Schéma Windows (bez klávesy Win) +Name[csb]=Mòtiw Windows (bez klawiszë Win) +Name[cy]=Cynllun Windows (Heb Allwedd Win) +Name[da]=Windows-system (uden Win-tast) +Name[de]=Windows-Design (ohne Windows-Taste) +Name[el]=Σχήμα Windows (Χωρίς πλήκτρο Win) +Name[en_GB]=Windows Scheme (Without Win Key) +Name[eo]=Vindoza aranĝo (sen Vindozoklavo) +Name[es]=Esquema Windows (Sin tecla Win) +Name[et]=Windowsi skeem (ilma Win-klahvita) +Name[eu]=Windows eskema (Win teklarik gabe) +Name[fa]=طرحواره ویندوز( بدون کلید پنجره) +Name[fi]=Windows-skeema (ilman Win-näppäintä) +Name[fr]=Agencement Windows (sans la touche « Win ») +Name[fy]=Windows-skema (sûnder Win-toets) +Name[ga]=Scéim Windows (Gan Eochair Win) +Name[gl]=Esquema de Windows (sen tecla de Windows) +Name[gu]=વિન્ડોઝ પધ્ધતિ (વિન કળ વગર) +Name[he]=ערכת חלונות (בלי מקש Win) +Name[hi]=विंडोज़ प्रसंग (विन कुंजी के बगैर) +Name[hne]=विंडोज प्रसंग (विन कुंजी के बिना) +Name[hr]=Windows shema (bez Windows tipki) +Name[hsb]=Windows-šema (bjez Win-tasty) +Name[hu]=Windows (Win billentyű nélkül) +Name[ia]=Schema Windows (Sin clave Win) +Name[id]=Skema Windows (Tanpa Tombol Win) +Name[is]=Windowsþema (án Win lykils) +Name[it]=Schema Windows (senza tasto Win) +Name[ja]=Windows スキーマ (Win キーなし) +Name[kk]=Windows сұлбасы (Win пернесіз) +Name[km]=គ្រោងការណ៍ វីនដូ (គ្មាន​គ្រាប់ចុច Win) +Name[kn]=ವಿಂಡೋಸ್ ಪದ್ಧತಿ (ವಿನ್ ಕೀಲಿ ರಹಿತ) +Name[ko]=윈도 배열 (윈도 키 사용 안함) +Name[ku]=Şemaya Windowsê (Bêyê Bişkojka Winê) +Name[lt]=Windows schema (be Win klavišo) +Name[lv]=Windows shēma (bez Win taustiņa) +Name[mai]=विंडोज प्रसंग (विन कुँजी केर बगैर) +Name[mk]=Windows-шема (без копчето Win) +Name[ml]=വിന്‍ഡോസ് പദ്ധതി (വിന്‍ കീ ഇല്ലാതെ) +Name[mr]=Windows सुत्रयोजना (विना Win किल्ली) +Name[ms]=Skim Tetingkap (Tanpa Kekunci Win) +Name[nb]=Windows-oppsett (uten Windows-tast) +Name[nds]=Windows-Schema (ahn Windows-Tast) +Name[ne]=विण्डोज योजना (विन कुञ्जी बाहेक) +Name[nl]=Windows-schema (zonder Win-toets) +Name[nn]=Windows-oppsett (utan Windows-tast) +Name[or]=ୱିଣ୍ଡୋ ଯୋଜନା (ୱିନ କି ବିନା) +Name[pa]=Windows ਸਕੀਮ (ਬਿਨਾਂ Win ਸਵਿੱਚ) +Name[pl]=Motyw Windows (bez klawisza Win) +Name[pt]=Esquema do Windows (Sem a Tecla Win) +Name[pt_BR]=Esquema do Windows (sem a tecla Win) +Name[ro]=Schemă Windows (fără tasta Win) +Name[ru]=Windows (без клавиши Win) +Name[se]=Windows-čoakkáldat (Windows-boalu haga) +Name[si]=Windows ක්‍රමය (Win යතුර නොමැතිව) +Name[sk]=Windows schéma (bez klávesu Win) +Name[sl]=Shema Windows (brez tipke Win) +Name[sr]=Виндоузова шема (без тастера Win) +Name[sr@ijekavian]=Виндоузова шема (без тастера Win) +Name[sr@ijekavianlatin]=Windowsova šema (bez tastera Win) +Name[sr@latin]=Windowsova šema (bez tastera Win) +Name[sv]=Windows schema (utan Win-tangent) +Name[ta]=சாளர முறைமை (விண் விசை இல்லாமல்) +Name[te]=Windows స్కీమ్ (విన్ కీ లేకుండా) +Name[tg]=Нақшаи Windows (Бе тугмаи Win) +Name[th]=ใช้แบบของวินโดวส์ (โดยไม่ใช้ปุ่ม Win) +Name[tr]=Windows Şeması (Win Key'siz) +Name[uk]=Схема Windows (без клавіші Win) +Name[uz]=Windows qolipi (Win tugmasi bilan) +Name[uz@cyrillic]=Windows қолипи (Win тугмаси билан) +Name[vi]=Phối hợp của Windows (không có phím Cửa sổ) +Name[wa]=Djeu Windows (sins tape Win) +Name[xh]=Window Yodweliso (Ngaphandle kwe Win key) +Name[x-test]=xxWindows Scheme (Without Win Key)xx +Name[zh_CN]=Windows 方案(无 Win 键) +Name[zh_TW]=Windows 機制(沒有 Win 鍵) +Uses Win Modifier=false + +[klipper][Global Shortcuts] +clipboard_action=none +repeat_action=none +show_klipper_popup=none + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=none +Log Out Without Confirmation=none +Log Out=none +Reboot Without Confirmation=none +Run Command=none +Show System Activity=Ctrl+Alt+Del + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Ctrl+Print +Kill Window=none +Mouse Emulation=none +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=none +Switch to Desktop 11=none +Switch to Desktop 12=none +Switch to Desktop 13=none +Switch to Desktop 14=none +Switch to Desktop 15=none +Switch to Desktop 16=none +Switch to Desktop 1=none +Switch to Desktop 2=none +Switch to Desktop 3=none +Switch to Desktop 4=none +Switch to Desktop 5=none +Switch to Desktop 6=none +Switch to Desktop 7=none +Switch to Desktop 8=none +Switch to Desktop 9=none +Switch to Next Desktop=Alt+Shift+Tab +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=none +Walk Through Desktop List=none +Walk Through Desktops (Reverse)=Ctrl+Alt+Shift+Tab +Walk Through Desktops=Ctrl+Alt+Tab +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+Tab +Window Close=Alt+F4 +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=none +Window Minimize=none +Window Move=none +Window Operations Menu=Alt+Space +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Alt+Print +Window Shade=none +Window to Desktop 10=none +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=none +Window to Desktop 2=none +Window to Desktop 3=none +Window to Desktop 4=none +Window to Desktop 5=none +Window to Desktop 6=none +Window to Desktop 7=none +Window to Desktop 8=none +Window to Desktop 9=none +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/schemes/win4.kksrc b/kcontrol/keys/schemes/win4.kksrc new file mode 100644 index 00000000..b28e8499 --- /dev/null +++ b/kcontrol/keys/schemes/win4.kksrc @@ -0,0 +1,170 @@ +[Settings] +Name=Windows Scheme (With Win Key) +Name[af]=Windows Skema (Met Win Sleutel) +Name[ar]=مخطط ويندوز (مع مفتاح Win) +Name[ast]=Esquema Windows (Con tecla Win) +Name[be]=Схема Windows (з клавішай "Win") +Name[be@latin]=Schiema „Windows” (z klavišaj „Win”) +Name[bg]=Windows (с клавиша Win) +Name[bn]=উইণ্ডোস্ স্কীম (উইন্ কী সমেত) +Name[br]=Steuñv Windows (gant stokell Win) +Name[ca]=Esquema Windows (amb la tecla Win) +Name[ca@valencia]=Esquema Windows (amb la tecla Win) +Name[cs]=Schéma Windows (s klávesou Win) +Name[csb]=Mòtiw Windows (z klawiszą Win) +Name[cy]=Cynllun Windows (Gyda'r Allwedd Win) +Name[da]=Windows-system (med Win-tast) +Name[de]=Windows-Design (mit Windows-Taste) +Name[el]=Σχήμα Windows (με πλήκτρο Win) +Name[en_GB]=Windows Scheme (With Win Key) +Name[eo]=Vindoza aranĝo (kun Vindozoklavo) +Name[es]=Esquema Windows (Con tecla Win) +Name[et]=Windowsi skeem (Win-klahviga) +Name[eu]=Windows eskema (Win teklarekin) +Name[fa]=طرحواره پنجره( با کلید پنجره) +Name[fi]=Windows-skeema (Win-näppäimellä) +Name[fr]=Agencement Windows (avec la touche « Win ») +Name[fy]=Windows-skema (mei Win-toets) +Name[ga]=Scéim Windows (Le hEochair Win) +Name[gl]=Esquema de Windows (con tecla de Windows) +Name[gu]=વિન્ડોઝ પધ્ધતિ (વિન કળ સાથે) +Name[he]=ערכת חלונות (עם מקש Win) +Name[hi]=विंडोज प्रसंग (विन कुंजी समेत) +Name[hne]=विंडोज प्रसंग (विन कुंजी समेत) +Name[hr]=Windows shema (s Windows tipkama) +Name[hsb]=Windows-šema (z Win-tastu) +Name[hu]=Windows (Win billentyűvel) +Name[ia]=Schema Windows (con clave Win) +Name[id]=Skema Windows (Dengan Tombol Win) +Name[is]=Windowsþema (með Win lykli) +Name[it]=Schema Windows (con tasto Win) +Name[ja]=Windows スキーマ (Win キーあり) +Name[ka]=Windows სქემა (Win კლავიშით) +Name[kk]=Windows сұлбасы (Win пернемен) +Name[km]=គ្រោងការណ៍ វីនដូ (មាន​គ្រាប់ចុច Win) +Name[kn]=ವಿಂಡೋಸ್ ಪದ್ಧತಿ (ವಿನ್ ಕೀಲಿ ಸಹಿತ) +Name[ko]=윈도 배열 (윈도 키 사용) +Name[ku]=Şemaya Windowsê (Digel Bişkojka Winê) +Name[lt]=Windows schema (su Win klavišu) +Name[lv]=Windows shēma (ar Win taustiņu) +Name[mai]=विंडोज प्रसंग (विन कुँजी समेत) +Name[mk]=Windows-шема (со копчето Win) +Name[ml]=വിന്‍ഡോസ് പദ്ധതി (വിന്‍ കീയോടൊപ്പം) +Name[mr]=Windows सुत्रयोजना (विन किल्ली सह) +Name[nb]=Windows-oppsett (med Windows-tast) +Name[nds]=Windows-Schema (mit Windows-Tast) +Name[ne]=विण्डोज योजना (विन कुञ्जीसँग) +Name[nl]=Windows-schema (met Win-toets) +Name[nn]=Windows-oppsett (med Windows-tast) +Name[or]=ୱିଣ୍ଡୋ ଯୋଜନା (ୱିନ କି ବିନା) +Name[pa]=Windows ਸਕੀਮ (Win ਸਵਿੱਚ ਨਾਲ) +Name[pl]=Motyw Windows (z klawiszem Win) +Name[pt]=Esquema do Windows (Com a Tecla Win) +Name[pt_BR]=Esquema do Windows (com a tecla Win) +Name[ro]=Schemă Windows (cu tasta Win) +Name[ru]=Windows (поддержка клавиши Win) +Name[se]=Windows-čoakkáldat (Windows-boaluin) +Name[si]=Windows ක්‍රමය (Win යතුර සමඟ) +Name[sk]=Windows schéma (s klávesom Win) +Name[sl]=Shema Windows (s tipko Win) +Name[sr]=Виндоузова шема (са тастером Win) +Name[sr@ijekavian]=Виндоузова шема (са тастером Win) +Name[sr@ijekavianlatin]=Windowsova šema (sa tasterom Win) +Name[sr@latin]=Windowsova šema (sa tasterom Win) +Name[sv]=Windows schema (med Win-tangent) +Name[ta]=சாளர முறைமை (விண் விசையுடன்) +Name[te]=విండోస్ పధకం (విన్ కీ తో) +Name[tg]=Нақшаи Windows (Бо тугмаи Win) +Name[th]=ใช้แบบของวินโดวส์ (ใช้ปุ่ม Win) +Name[tr]=Windows Şeması (Win Key İle) +Name[uk]=Схема Windows (з клавішею Win) +Name[uz]=Windows qolipi (Win tugmasiz) +Name[uz@cyrillic]=Windows қолипи (Win тугмасиз) +Name[vi]=Phối hợp của Windows (có phím Cửa sổ) +Name[wa]=Djeu Windows (avou tape Win) +Name[xh]=Windows Ezingagqibekanga (Nge Win-key) +Name[x-test]=xxWindows Scheme (With Win Key)xx +Name[zh_CN]=Windows 方案(有 Win 键) +Name[zh_TW]=Windows 機制(有 Win 鍵) +Uses Win Modifier=true + +[klipper][Global Shortcuts] +clipboard_action=none +repeat_action=none +show_klipper_popup=none + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=none +Log Out Without Confirmation=none +Log Out=none +Reboot Without Confirmation=none +Run Command=Meta+R +Show System Activity=Ctrl+Alt+Del + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Print +Kill Window=none +Mouse Emulation=none +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Meta+F10 +Switch to Desktop 11=none +Switch to Desktop 12=none +Switch to Desktop 13=none +Switch to Desktop 14=none +Switch to Desktop 15=none +Switch to Desktop 16=none +Switch to Desktop 1=Meta+F1 +Switch to Desktop 2=Meta+F2 +Switch to Desktop 3=Meta+F3 +Switch to Desktop 4=Meta+F4 +Switch to Desktop 5=Meta+F5 +Switch to Desktop 6=Meta+F6 +Switch to Desktop 7=Meta+F7 +Switch to Desktop 8=Meta+F8 +Switch to Desktop 9=Meta+F9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=none +Walk Through Desktop List=none +Walk Through Desktops (Reverse)=Meta+Shift+Tab +Walk Through Desktops=Meta+Tab +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+Tab +Window Close=Alt+F4 +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=none +Window Minimize=none +Window Move=none +Window Operations Menu=Alt+Space +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Alt+Print +Window Shade=none +Window to Desktop 10=none +Window to Desktop 11=none +Window to Desktop 12=none +Window to Desktop 13=none +Window to Desktop 14=none +Window to Desktop 15=none +Window to Desktop 16=none +Window to Desktop 1=none +Window to Desktop 2=none +Window to Desktop 3=none +Window to Desktop 4=none +Window to Desktop 5=none +Window to Desktop 6=none +Window to Desktop 7=none +Window to Desktop 8=none +Window to Desktop 9=none +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/schemes/wm3.kksrc b/kcontrol/keys/schemes/wm3.kksrc new file mode 100644 index 00000000..e57093fd --- /dev/null +++ b/kcontrol/keys/schemes/wm3.kksrc @@ -0,0 +1,165 @@ +[Settings] +Name=WindowMaker (3 Modifier Keys) +Name[af]=WindowMaker (3 verandering sleutels) +Name[ar]=صانع النوافذ (3 مفاتيح مغيرة) +Name[ast]=WindowMaker (3 tecles de modificación) +Name[be]=WindowMaker (тры клавішы мадыфікацыі) +Name[be@latin]=Schiema „WindowMaker” (z 3 madyfikacyjnymi klavišami) +Name[bg]=WindowMaker (с 3 модификационни клавиша) +Name[bn]=উইণ্ডো-মেকার (৩-টি মডিফায়ার কী) +Name[ca]=WindowMaker (3 tecles modificadores) +Name[ca@valencia]=WindowMaker (3 tecles modificadores) +Name[cs]=WindowMaker (3 modifikátory) +Name[csb]=WindowMaker (3 klawisze zjinaczi) +Name[cy]=WindowMaker (3 Bysell Addasu) +Name[da]=Windowmaker (3 modifikatortaster) +Name[de]=WindowMaker (3 Sondertasten) +Name[el]=WindowMaker (3 τροποποιητές) +Name[en_GB]=WindowMaker (3 Modifier Keys) +Name[eo]=WindowMaker (3 modifoklavoj) +Name[es]=WindowMaker (3 teclas de modificación) +Name[et]=WindowMaker (3 muuteklahviga) +Name[eu]=WindowMaker (3 tekla modifikatzailekin) +Name[fa]=WindowMaker (۳کلید تغییردهنده) +Name[fi]=WindowMaker (3 muokkausnäppäintä) +Name[fr]=WindowMaker (3 touches de modifications) +Name[fy]=WindowMaker (3 modifikaasjetoetsen) +Name[ga]=WindowMaker (3 Eochair Mhionathraithe) +Name[gl]=WindowMaker (3 teclas modificadoras) +Name[gu]=વિન્ડોમેકર (૩ બદલનાર કળો) +Name[he]=‏WindowMaker (עם 3 מקשים משני מצב) +Name[hi]=विंडोमेकर (3 मॉडीफ़ॉयर कुंजियाँ) +Name[hne]=विंडोमेकर (3 माडीफायर कुंजियाँ) +Name[hr]=WindowMaker (3 modifikatorske tipke) +Name[hsb]=WindowMaker (3 modifikowace tasty) +Name[hu]=WindowMaker (3 módosító billentyű) +Name[ia]=Windowmaker (3 Claves Modificator) +Name[id]=WindowMaker (3 Tombol Pengubah) +Name[is]=WindowMaker (3 breytilyklar) +Name[it]=WindowMaker (3 tasti modificatori) +Name[ja]=WindowMaker (修飾キー 3 個) +Name[ka]=WindowMaker (3 ცვლადი კლავიში) +Name[kk]=WindowMaker (3 түрлендіру перне) +Name[km]=WindowMaker (សោ​​កែប្រែ ៣) +Name[kn]=ವಿಂಡೋಮೇಕರ್ (೩ ಪರಿವರ್ತಕ ಕೀಲಿಗಳು) +Name[ko]=WindowMaker (수정자 키 세 개) +Name[ku]=WindowMaker(3 Bişkojkên Guherker) +Name[lt]=WindowMaker (3 lygio klavišai – modifikatoriai) +Name[lv]=WindowMaker (3 modifikācijas taustiņi) +Name[mai]=विंडोमेकर (3 माडीफायर कुंजीसभ) +Name[mk]=WindowMaker (3 копчиња-модификатори) +Name[ml]=വിന്‍ഡോമേക്കര്‍ (3 മോഡിഫയര്‍ കീകള്‍) +Name[mr]=चौकटमेकर (3 संपादन की) +Name[nb]=WindowMaker (tre valgtaster) +Name[nds]=WindowMaker (3 Sünnertasten) +Name[ne]=विण्डोज निर्माता (३ परिमार्जक कुञ्जी) +Name[nl]=WindowMaker (3 modificatietoetsen) +Name[nn]=WindowMaker (tre valtastar) +Name[or]=WindowMaker (3ଟି ପରିବର୍ତ୍ତକ କି) +Name[pa]=WindowMaker (3 ਸੋਧ ਸਵਿੱਚਾਂ) +Name[pl]=WindowMaker (3 klawisze modyfikatorów) +Name[pt]=WindowMaker (3 Teclas Modificadoras) +Name[pt_BR]=WindowMaker (3 teclas modificadoras) +Name[ro]=WindowMaker (3 modificatori) +Name[ru]=WindowMaker (3 клавиши-модификатора) +Name[se]=WindowMaker (golbma válljenboaluiguin) +Name[si]=කවුළු සැකසීම (3 වෙනස්කම් යතුරු) +Name[sk]=WindowMaker (3 modifikačné klávesy) +Name[sl]=WindowMaker (3 spremenilne tipke) +Name[sr]=Виндоумејкер (три модификаторска тастера) +Name[sr@ijekavian]=Виндоумејкер (три модификаторска тастера) +Name[sr@ijekavianlatin]=WindowMaker (tri modifikatorska tastera) +Name[sr@latin]=WindowMaker (tri modifikatorska tastera) +Name[sv]=Windowmaker (3 väljartangenter) +Name[ta]=WindowMaker (3 Modifier Keys) +Name[te]=విండోమేకర్ (3 సవరణి కీలు) +Name[tg]=WindowMaker (3 тугмаи якҷояшуда) +Name[th]=วินโดว์เมกเกอร์ (ใช้ปุ่มเปลี่ยนหน้าที่ 3ปุ่ม) +Name[tr]=WindowMaker (3 Değiştirici Anahtar) +Name[uk]=WindowMaker (3 клавіші-модифікатори) +Name[vi]=WindowMaker (3 Phím Bổ trợ) +Name[wa]=Djeu WindowMaker (3 tapes modifieuses) +Name[x-test]=xxWindowMaker (3 Modifier Keys)xx +Name[zh_CN]=WindowMaker (三个修饰键) +Name[zh_TW]=WindowMaker(3 個變更鍵) + +[klipper][Global Shortcuts] +clipboard_action=Ctrl+Alt+X +repeat_action=Ctrl+Alt+R +show_klipper_popup=Ctrl+Alt+V + +[krunner][Global Shortcuts] +Halt Without Confirmation=none +Lock Session=Ctrl+Alt+L +Log Out Without Confirmation=none +Log Out=Ctrl+Alt+Del +Reboot Without Confirmation=none +Run Command=Alt+F2 +Show System Activity=Ctrl+Esc + +[kwin][Global Shortcuts] +Desktop Screenshot to Clipboard=Ctrl+Print +Kill Window=Ctrl+Alt+Esc +Mouse Emulation=Alt+F12 +Switch One Desktop Down=none +Switch One Desktop Up=none +Switch One Desktop to the Left=none +Switch One Desktop to the Right=none +Switch to Desktop 10=Alt+Shift+1 +Switch to Desktop 11=Alt+Shift+2 +Switch to Desktop 12=Alt+Shift+3 +Switch to Desktop 13=Alt+Shift+4 +Switch to Desktop 14=Alt+Shift+5 +Switch to Desktop 15=Alt+Shift+6 +Switch to Desktop 16=Alt+Shift+7 +Switch to Desktop 1=Alt+1 +Switch to Desktop 2=Alt+2 +Switch to Desktop 3=Alt+3 +Switch to Desktop 4=Alt+4 +Switch to Desktop 5=Alt+5 +Switch to Desktop 6=Alt+6 +Switch to Desktop 7=Alt+7 +Switch to Desktop 8=Alt+8 +Switch to Desktop 9=Alt+9 +Switch to Next Desktop=none +Switch to Previous Desktop=none +Toggle Window Raise/Lower=none +Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab +Walk Through Desktop List=Ctrl+Tab +Walk Through Desktops (Reverse)=none +Walk Through Desktops=none +Walk Through Windows (Reverse)=Alt+Shift+Tab +Walk Through Windows=Alt+Tab +Window Close=Alt+Esc +Window Lower=none +Window Maximize Horizontal=none +Window Maximize Vertical=none +Window Maximize=none +Window Minimize=none +Window Move=none +Window Operations Menu=Alt+F3 +Window Raise=none +Window Resize=none +Window Screenshot to Clipboard=Alt+Print +Window Shade=none +Window to Desktop 10=Ctrl+Alt+Shift+1 +Window to Desktop 11=Ctrl+Alt+Shift+2 +Window to Desktop 12=Ctrl+Alt+Shift+3 +Window to Desktop 13=Ctrl+Alt+Shift+4 +Window to Desktop 14=Ctrl+Alt+Shift+5 +Window to Desktop 15=Ctrl+Alt+Shift+6 +Window to Desktop 16=Ctrl+Alt+Shift+7 +Window to Desktop 1=Ctrl+Alt+1 +Window to Desktop 2=Ctrl+Alt+2 +Window to Desktop 3=Ctrl+Alt+3 +Window to Desktop 4=Ctrl+Alt+4 +Window to Desktop 5=Ctrl+Alt+5 +Window to Desktop 6=Ctrl+Alt+6 +Window to Desktop 7=Ctrl+Alt+7 +Window to Desktop 8=Ctrl+Alt+8 +Window to Desktop 9=Ctrl+Alt+9 +Window to Next Desktop=none +Window to Previous Desktop=none + +[kxkb][Global Shortcuts] +Switch to Next Keyboard Layout=Ctrl+Alt+K diff --git a/kcontrol/keys/select_scheme_dialog.cpp b/kcontrol/keys/select_scheme_dialog.cpp new file mode 100644 index 00000000..e3720716 --- /dev/null +++ b/kcontrol/keys/select_scheme_dialog.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "select_scheme_dialog.h" +#include "ui_select_scheme_dialog.h" + + +#include "KDialog" +#include "KStandardDirs" +#include + +SelectSchemeDialog::SelectSchemeDialog(QWidget *parent) + : KDialog(parent), + ui(new Ui::SelectSchemeDialog) +{ + m_schemes = KGlobal::dirs()->findAllResources("data", "kcmkeys/*.kksrc"); + + ui->setupUi(this); + setMainWidget(ui->layoutWidget); + + foreach (const QString &res, m_schemes) { + KConfig config(res, KConfig::SimpleConfig); + KConfigGroup group(&config, "Settings"); + QString name = group.readEntry("Name"); + + if (name.isEmpty()) { + name = res; + } + ui->m_schemes->addItem(name); + } + + ui->m_schemes->setCurrentIndex(-1); + + ui->m_url->setMode(KFile::LocalOnly | KFile::ExistingOnly); + + connect(ui->m_schemes, SIGNAL(activated(int)), + this, SLOT(schemeActivated(int))); + connect(ui->m_url->lineEdit(), SIGNAL(textChanged(QString)), + this, SLOT(slotUrlChanged(QString))); + enableButtonOk(false); +} + + +SelectSchemeDialog::~SelectSchemeDialog() +{ + delete ui; +} + +void SelectSchemeDialog::schemeActivated(int index) +{ + ui->m_url->setUrl(m_schemes[index]); +} + + +KUrl SelectSchemeDialog::selectedScheme() const +{ + return ui->m_url->url(); +} + +void SelectSchemeDialog::slotUrlChanged(const QString &_text) +{ + enableButtonOk(!_text.isEmpty()); +} + +#include "moc_select_scheme_dialog.cpp" diff --git a/kcontrol/keys/select_scheme_dialog.h b/kcontrol/keys/select_scheme_dialog.h new file mode 100644 index 00000000..9d96a842 --- /dev/null +++ b/kcontrol/keys/select_scheme_dialog.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Michael Jansen + * + * 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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef SELECT_SCHEME_DIALOG_H +#define SELECT_SCHEME_DIALOG_H + +#include "KDialog" + +namespace Ui +{ +class SelectSchemeDialog; +} + +class SelectSchemeDialog : public KDialog +{ + Q_OBJECT +public: + SelectSchemeDialog(QWidget *parent = 0); + ~SelectSchemeDialog(); + + KUrl selectedScheme() const; + +private slots: + void schemeActivated(int index); + void slotUrlChanged(const QString &); + +private: + Ui::SelectSchemeDialog *ui; + QStringList m_schemes; +}; // SelectSchemeDialog + + + +#endif diff --git a/kcontrol/keys/select_scheme_dialog.ui b/kcontrol/keys/select_scheme_dialog.ui new file mode 100644 index 00000000..0803ad5d --- /dev/null +++ b/kcontrol/keys/select_scheme_dialog.ui @@ -0,0 +1,150 @@ + + + Michael Jansen + SelectSchemeDialog + + + + 0 + 0 + 717 + 224 + + + + Select Shortcut Scheme + + + true + + + + + 32 + 12 + 671 + 71 + + + + + + + + 0 + 50 + + + + Select one of the standard KDE shortcut schemes + + + &Standard scheme: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_schemes + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + true + + + + + + + + 150 + 0 + + + + + 1 + 0 + + + + + 0 + 50 + + + + Select a shortcut scheme file + + + &Path: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_url + + + + + + + + 3 + 0 + + + + + 0 + 50 + + + + *.kksrc + + + Select Shortcut Scheme + + + + + + + + + KComboBox + QComboBox +
    kcombobox.h
    +
    + + KDialog + QDialog +
    kdialog.h
    + 1 +
    + + KUrlRequester + QFrame +
    kurlrequester.h
    +
    +
    + + +
    diff --git a/kcontrol/kfontinst/AUTHORS b/kcontrol/kfontinst/AUTHORS new file mode 100644 index 00000000..afabc4a8 --- /dev/null +++ b/kcontrol/kfontinst/AUTHORS @@ -0,0 +1 @@ +Craig Drummond diff --git a/kcontrol/kfontinst/CMakeLists.txt b/kcontrol/kfontinst/CMakeLists.txt new file mode 100644 index 00000000..1ba461cf --- /dev/null +++ b/kcontrol/kfontinst/CMakeLists.txt @@ -0,0 +1,51 @@ +if (KFI_BUILD_STANDALONE) + cmake_minimum_required(VERSION 2.6.4) + find_package(KDE4 "4.6.0" REQUIRED) + find_package(Qt4 REQUIRED) + find_package(Freetype REQUIRED) + find_package(Fontconfig REQUIRED) + find_package(Strigi REQUIRED) + find_package(X11 REQUIRED) + macro_log_feature(X11_Xft_FOUND "libxft" "X FreeType interface library" "http://www.x.org" FALSE "" "Font installer and font previews") + include(KDE4Defaults) +endif (KFI_BUILD_STANDALONE) + +if (X11_Xft_FOUND) + check_include_files(locale.h HAVE_LOCALE_H) + configure_file(config-fontinst.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-fontinst.h) + include_directories( + ${KDE4_INCLUDES} + ${FREETYPE_INCLUDE_DIRS} + ${FONTCONFIG_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/lib + ${CMAKE_CURRENT_BINARY_DIR}/lib + ${CMAKE_CURRENT_SOURCE_DIR}/dbus + ${CMAKE_CURRENT_BINARY_DIR}/dbus + ${CMAKE_CURRENT_SOURCE_DIR}/viewpart + ${CMAKE_CURRENT_SOURCE_DIR}/kcmfontinst + ${CMAKE_CURRENT_BINARY_DIR}/kcmfontinst) + add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) + + set(libkfontinstdbusiface_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/dbus/FontinstIface.cpp) + set(libkfontinstview_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/viewpart/FontPreview.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/viewpart/PreviewSelectAction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/viewpart/CharTip.cpp ) + set(libkfontinstactionlabel_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/kcmfontinst/ActionLabel.cpp) + set(libkfontinstjobrunner_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/kcmfontinst/JobRunner.cpp + ${libkfontinstactionlabel_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/kcmfontinst/FontsPackage.cpp) + + add_subdirectory( lib ) + add_subdirectory( dbus ) + add_subdirectory( kcmfontinst ) + add_subdirectory( strigi-analyzer ) + add_subdirectory( apps ) + add_subdirectory( kio ) + add_subdirectory( thumbnail ) + add_subdirectory( viewpart ) + + kde4_install_icons( ${ICON_INSTALL_DIR} ) + +endif (X11_Xft_FOUND) diff --git a/kcontrol/kfontinst/ChangeLog b/kcontrol/kfontinst/ChangeLog new file mode 100644 index 00000000..fe87b58a --- /dev/null +++ b/kcontrol/kfontinst/ChangeLog @@ -0,0 +1,562 @@ +KDE4.4 +====== +1. Create a dbus daemon for handling font installtion, and have the kcm and ioslave + use this. +2. Use policykit to control installation of system-wide fonts. +3. Merged progress, skip, cancel, and error dialogs used when installing, etc., into + 1 dialog. +4. Simplify layout. +5. Remove simple mode - always use font management mode. +6. When multiple fonts are selected, use a list style preview of all selected fonts. +7. Because of the above, remove the in-line previews from the font list. + +KDE4.3 +====== +1. Dont cache previews to disk. + +KDE4.2 +====== +1. Added zoom controls to font preview. +2. Made viewer application a KUniqueApplication + +KDE3.5 -> KDE4.0 +================ + 1. Enabling/disabling of fonts. + 2. Creation of "Font Groups" + 3. Fonts are now grouped via family name, i.e. shown as: + + Courier [4] + - Times [2] + Regular + Italic + ...where the number in brackets indicates the number of styles. Clicking + on the expand icon (+) will then show the list of styles. + 4. Add ability in font view part to show unicode tables. + 5. Remove all references to Speedo fonts - haven't been supported since + KDE3.3! + 6. Only one view - list view. However, each item now has a small preview. + 7. Xft is now required. + 8. Remove Fontmap creation. + 9. Creation of fonts.dir & fonts.scale will be done via mkfontscale and + mkfontdir. +10. Legacy X is only configured for a folder if it already contains a fonts.dir + file. +11. Font installtion is *much* faster - as config files are now updated after + all fonts are installed, as opposed to every 50 fonts. +12. Folders are no longer added to X's config files - because of 10 above. + The only system config file that will be altered is either + /etc/fonts/local.conf or /etc/fonts/conf.d/00kde.conf (dependant upon + your fontconfig version) +13. When installing font files, install into a sub folder named after the 1st + character. e.g. + wibble.ttf -> ~/.fonts/w/wibble.ttf +14. Better unique names when creating font packages. +15. Use zip and not tar.gz for font packages. +16. Allow import of fonts/package. +17. Allow fonts/package to be installed via konqueror service menu. +18. Better TTC handling. +19. When installing to fonts:/, as non-root, automatically install to fonts:/Personal. + To install to fonts:/System need to explicity copy to fonts:/System. +20. Hide kfontview from KMenu - its only required by kcm, and when cliking on a font. +21. Renamed kcmfontinst to just fontinst. +22. When printing, use external kfontprint app - that way newly installed fonts can + also be printed. +23. When run as non-root, the kcontrol module will have a combo box allowing the user + to select Personal or System fonts. +24. Better bitmap font previews - list of sizes obtained via fontconfig. +25. Regular fonts listed as fonts:/, Regular - e.g. fonts:/Times, Regular +26. Use a kio_font_helper app when accesing fonts:/System - much faster, as kdesu is + not required to be called for each action. +27. Add a "Find Duplicates" tool, that looks for multiple installtions of the same font. + i.e. different locations, or the same location but different filename case + (e.g. times.ttf / times.TTF) + +KDE3.4 -> KDE3.5 +================ +1. When copying a file out of fonts sub-system, copy as filename, or .fonts.tar.gz + in the case of multiple font files mapped to the same font name. + + e.g. Times New Roman -> times.ttf + Helvetica, Bold Oblique-> Hevetica, Bold Oblique.fonts.tar.gz + Which contains: + 75dpi_helvBO10.pcf.gz + 75dpi_helvBO12.pcf.gz + 100dpi_helvBO10.pcf.gz + 100dpi_helvBO12.pcf.gz + ...etc + +2. New mimetype: fonts/package - to cater for the above. +3. Add settings to enable/disable configuring fonts for legacy X, and Ghostscript + (X defaults to true, and Ghostscript defaults to false) +4. Show mime-type in detailed view. +5. Simple font sample printing - but only of installed fonts! +6. Add toggle button to control display of bitmap fonts. + +KDE3.3 -> KDE3.4 +================ +1. Font listing comes from fontconfig. This means that fonts will be grouped, i.e. + previously each size of a bitmap font was shown seperately, now only 1 font + will be displayed which represents all sizes. +2. Only fonts, and not folders (except System and Personal), are now shown. +3. Creation of afms from pfa/pfb and a pfm file. +4. Previews are drawn via Xft - previously FreeType was called directly. +5. New font preview look. +6. No longer dependant upon file extension. +7. Check for FPE of "fontconfig" -> if set, then no need to configure X core fonts. + +KDE3.2 -> KDE3.3 +================ +1. List fonts as "Full Name" -> i.e. "Times New Roman". +2. Preview of bitmap fonts. +3. No fontname-title in thumbnails - as fonts:/ lists the fontnames! +4. When copying to fonts:/ (as non-root) only ask for destination if more than 5 seconds + since previously asked. +5. Add a konqueror service menu "Install" +6. Use FreeType2 for reading Type1 - instead of parsing the pfa/pfb header. +7. FamilyName is now the fonts *real* family name - no adding of style information. +8. Add extra style information (which was previously added to FamilyName) into the XLFD. +9. Consider regular weight to be medium (same as mkfontscale). +10. Default to width=normal, weight=medium if not set. +11. Allow change of preview string. +12. Allow zooming in/out of preview. +13. Waterfall font preview. +14. Use font preview part in the KControl module - less code duplication. +15. Include simple fontviwer app - basically just an application wrapper for the viewpart. + +KDE3.1 -> KDE3.2 +================ +1. Re-designed (yet again...) to be a kio slave. As a user, starting fonts:/ will display + + Personal Lists contents of $HOME/.fonts and $KDEHOME/share/fonts (where previous installer installed to) + Fonts are installed to $HOME/.fonts + + System Lists contents of /usr/local/share/fonts, /usr/share/fonts, and /usr/X11R6/lib/X11/fonts + Fonts are installed to /usr/local/share/fonts (as per FHS) + + To install fonts system wide, just drop onto "System" and root's password will be asked + for. + + As root, fonts:/ will show the same as fonts:/System (but without the System part...) + +2. New kcontrol module that uses fonts:/ +3. Removed: + AFM creation -- only really required (TTF wise) for SO <6.0 + StarOffice configuration (S0 6.0 / OO.o is *much* better anyway) +4. X font server (xfs) - if used - is refreshed by sending a SIGUSR1 instead of + relying on a /etc/init.d/xfs script. This is much more portable. +5. Simple FontView part for konqueror - this is basically a big re-sizable preview of the font. +6. Speed up creation of fonts.dir and fonts.scale - by reading in any existing files, and using the + entries from these instead of loading and testing the font (if listed). +7. Better font preview and thumbnails. +8. Only add a dir to fontpath if fonts.dir has greater than 0 entries! +9. Use /etc/fonts/local.conf as root fontconfig file. +10. Only add dirs to fontconfig if *not* a sub-dir of an existing dir. +11. Ensure that top-level fonts dir is always in fontpath. +12. A Fontmap file is created in each sub dir, which is then combined into 1 top level Fontmap file. + ~/.fonts/Fontmap for normal users, and /etc/fonts/Fontmap for root. +13. Modify /Fontmap to contain: + (/etc/fonts/Fontmap) .runlibfile + ...as this is the system-wide Fontmap file created. As for the per-user, one, hmmm... +14. When a folder is configured, ensure fonts.dir/fonts.scale/Fontmap/.fonts-config-timestamp (SuSE + specific) all have the same timestamp (if they exist). Helps to discover if a folder has been + modified - in which case it needs to be reconfigured (and should happen automatically). +15. Add support for TrueType Collections (.ttc), and OpenType (.otf) fonts. Currently TTC's are only + configured for X - need to also configure GS to see other faces. +16. CID fonts are *not* handled - therefore don't list the X11 CID directory, and don't let users + try to create this. +17. Don't list "encodings" in fonts:/System - and don't allow users to create this. +18. Use XFree86's libfontenc (if found) to read font-encodings. +19. Handle 1bpp glyphs in thumbnail code. +20. Ensure X fontpaths *never* end in "/" - i.e. when write XF86Config, xfs/config, + or fontpaths remove any trailing "/" +21. When adding/removing an unscaled dir from X font path, ensure ":unscaled" is + part of the path! +22. Call fc-cache on top-level dir, not on each dir. +23. Use "~" in Xft config and user X config files -> e.g. /home/user/.fonts -> ~/.fonts +24. Remove top-level dir spec from top-level fontmap, e.g. + + TimesNewRomanPSMT (/home/user/.fonts/wibble/times.ttf); + + ...becomes... + + TimesNewRomanPSMT (wibble/times.ttf); + +25. Add meta-data for AFM files to KFile plugin. + +0.11-> KDE3.1 +============= +1. Re-design of UI - removed "Install From" view. +2. Created a KIO/thumbnail font preview class. +3. Fonts are installed/uninstalled on "Apply". +4. Settings are saved on "Apply". +5. Settings tab simplified - some uneccesary settings removed. +6. Removal of Anti-Alias tab - relevant settings moved to kcmfonts. +7. Add kfile-plugin to display Meta data for fonts. +8. Remove settings wizard. +9. Drop use of internal version numbering - not tagging CVS anyway, so whats the point? +10. DCOP interface. +11. Remember size of main window when run via kcmshell. + +0.10->0.11 (KDE3.0) +=================== +1. Port to KDE3/Qt3. +2. Add support for CUPS's Fontmap. +3. Create backups of system files. +4. When install symbol encoding fonts, set encoding to "glyphs-fontspecific" in XftConfig. +5. When install monospaced fonts, set spacing to mono in XftConfig. +6. When first run (as root) - checks XFree86 config file to see if a font server is being used, if + so then fs/config is used as the config file, and "/etc/rc.d/init.d/xfs restart" is selected as + as the X refresh command. +7. Only install fonts that are useable. +8. Add checkbox to enable overwriting of existing AFMs. +9. Remember open directories in advanced mode. +10. Add support for .Z compressed Bitmap fonts. +11. Read Type1 encodings from .afm files if listed as "array" in pfa/pfb. + +0.10b11->0.10 +============= +1. Version added to KDE CVS. +2. Modified some keyboard shortcuts to remove conflicts. +3. Disable "Touch" and "Delete" folder if top-level X fonts dir is selected. + +0.10b10->0.10b11 (Test version...) +================ +1. Removed "root"/"Modify" and "Help" buttons - this gives more space to font lists, plus when using "root"/"Modify" root's + config files are not being saved. +2. "IsFixedPitch" flag in AFMs produced incorrectly - was outputing "false" for monospaced fonts! +3. Added rounding to AFM metric scaling. +4. When creating AFMs, check that each characters' BBox is within the main BBox - this is a quick fix for wingdings.afm, + which seems to be giving incorrect results. +5. StarOffice 6 / OpenOffice only need AFM files for Type1 fonts - plus no config files need to be altered. Therefore, added the ability to + select which font types AFMs should be created for. +6. Output *all* characters from a font into the AFM file. +7. Fixed a bug with Full/Family name in Speedo fonts. +8. For TrueType, Type1, and Speedo fonts - family name is obtained by using the fonts' FullName, remove FamilyName (read from file), remove + any weight, width, or italic designation, and re-add FamilyName. (This is because some fonts are named + , and was previously being lost). +9. When adding encodings to lists, check that they aren't alredy inserted. + +0.10b9->0.10b10 (Test version...) +=============== +1. Fixed a problem with non-enabled install button in basic mode - again, thanks to Hardy Griech for spotting this. + +0.10b8->0.10b9 (Test version...) +============== + +*** NOTE +*** Please remove any Kfontinst generated StarOffice psstd.fonts and Ghostscript Fontmap output before using this version + +1. StarOffice psstd.fonts generated output is no longer marked line-by line, instead it is marked as a section, e.g. + + # kfontinst /usr/X11R6/lib/X11/fonts/TrueType + + # kfontinst /usr/X11R6/lib/X11/fonts/TrueType + + ...Likewise for Ghostscript's Fontmap + +2. Limited generated StarOffice psstd.fonts lines to 126 characters, and lines longher than this will not be output. It appears + as if this is the max line len StarOffice will accept - thanks to Hardy Griech for discovering this. +3. Fixed a bug where a static pointer was not reset to NULL when module was unloaded. +4. When chekcing ps-fonts, I was looking for the string "%!PS-Adbobe", however the hershey fonts just has "%!FontType" - therefore + I've change the code to just look for "%!" +5. For pcf fonts, look for FAMILY as well as FAMILY_NAME +6. Construct name from xlfd for bitmap fonts where can't get seperate components + +0.10b7->0.10b8 (Test version...) +============== + +*** NOTE +*** Please remove any Kfontinst generated Ghostscript and/or StarOffice output before using this version + +1. Forgot to extract foundry from bitmap fonts - however, changed bitmap Xlfd creation, see below. +2. Extract Xlfd from Bitmap fonts directly - not all fonts have each seperate component available. Thanks to Claudio Bandaloukas + for helping me discover the various bugs with Bitmap output. +3. When displaying bitmap details, if individual entries (family, point size, etc) can't be read, then the + Xlfd will be displayed. +4. Ghostscript & StarOffice include guards changed from "kfontinst" to "kfi" -- this will *require" removing of any previous output! +5. Shortened generated TrueType foundry fields - to help with StarOffice + +0.10b6->0.10b7 (Test version...) +============== +1. Fixed a bug with string-to-width conversion for Type1 and bitmap fonts +2. Fixed some compile bugs if no Xft.h found +3. Remove any fonts.alias when deleting a dir +4. When try to open Type1 or Speedo fonts, check magic numbers - for Speedo check char[0]=='D' or 'd', char[1]==num, char[2]=='.', and char[3]==num + +0.10b5->0.10b6 (Test version...) +============== +1. Fonts with "Normal" weight now installed as "Medium" +2. Added support for "Oblique" in xlfd +3. Check is performed to see if destination is writeable before enabling "Install" button, likewise for the "Remove" button. + +0.10b4->0.10b5 (Test version...) +============== +1. Forgot to reset the made-changes state of XftConfig when saved! +2. Add a validator to math & edit line-edits to disallow usage of double-quotes & tabs +3. Select correct default entries for field-name combos when adding an XftRule. +4. Removed check for number of items in match list, as these are not always required (such as for the sub-pixel hinting + rule.) +5. When setting rgba - use symbolic name - previously always setting to 0! +6. Modified help a little +7. Reduced Advanced mode list-view treeStepSize to 10 pixels (from default of 20), this makes it easier for browsing + /usr/X11R6/lib/X11/fonts/etc... +8. Fixed bug where could not remove Xft exclude range! +9. Fixed a bug where uninstalled items could cause duplicates in "Install from" list. +10. Renamed the "Configure System" button to "Apply" - this should make the neccessity of the option more obvious. +11. Fixed display of uninstall folder. +12. Added "include" and "includeif" directives from XftConfig to editor. + +0.10b3->0.10b4 (Test version...) +============== + +*** NOTE +*** Please delete your existing ~/.kde/share/config/kfontinstrc -or- ~/.kde2/share/config/kfontinstrc file +*** before using this version + +1. Added support for X font server config files. +2. Show "unscaled" directories in italic. +3. Abilty to set directories as scaled/unscaled. +4. Modified GUI slightly so that it works beter with Liquid style. +5. Added chack to make sure XftConfig file exists before trying to parse. +6. Advanced editing of XftConfig. +7. Added help on XftConfig - from Danny Tholen (obiwan@mailmij.org) +8. Removed some memory leaks +10. Default folders changed for non-root users. KFontinst will now (upon initial start-up) select the following: + + X fonts dir: $KDEHOME/share/fonts + XConfig file: $KDEHOME/share/fonts/fontpaths + XftConfig file: $HOME/.xftconfig + Fontmap file: $KDEHOME/share/fonts/Fontmap + + ...This should make it possible for users to install fonts without being root. However, problems may arrise when + configuring StarOffice - as this requires some other files to be modified, which won't be possible if SO has been installed + by root. + + ...Also to accomplish this, some changes are needed to 'startkde' - see file README.startkde + +11. Because of the above, when started as non-root, KFontinst will create Type1 and TrueType sub-folders in + $KDEHOME/share/fonts - if they do not already exist. +12. Moved XftConfig stuff from a sub-page of settings tab into its own tab. +13. Added question dialog if module is unloaded before system has been configured. +14. Added ability to "touch" a X font folder - marking it as being modified, so that a re-configure of the that folder + can be done in order to create AFMs, modify encoding, etc. + +0.10b2->0.10b3 (Test version...) +============== +1. When locating Ghostscript's Fontmap file, sub-directories (up to a level of 4) are searched - this allows + for the possiblity of users using a different version of Ghostscript. +2. Create a fonts.scale as well as fonts.dir - just incase another program runs mkfontdir. +3. Fixed an error when creating AFMs for some symbol-encoded fonts. +4. Re-worded SettingsWizard "Folders/Files" tab. +5. Added a checkbox to Ghostscript configuration. +6. Added support for XftConfig. +7. Added/fixed support of Type1 fonts with no FullName or FamilyName fields - such as the hershey fonts. +8. Fixed some bugs when configuring with --enable-final. +9. Basic html help added. + +0.10b1->0.10b2 (Test version...) +============== +1. Minor compile error (struct declared as private, but used elsewhere!) + +0.9.2->0.10b1 (Test version...) +============= +1. Almost a complete re-write, +2. Handles Speedo, and Bitmap fonts +3. fonts.dir & encodings.dir are now created internally - no need for ttmkfdir +4. Re-design of GUI. +5. Advanced mode where X11 folder structure is displayed and all font types may be installed - and a Basic + mode where the X11 folder structure is hidden, and only TrueType and Type1 fonts may be installed. +6. Settings wizard. +7. Application is now a kcontrol module. +8. Complete X11 fonts directory structure is now managed - no need for seperate 'Managed' directory. +9. X11.PS is no longer created, instead the StarOffice printer file (*.PS) is now modified. +10. Ported to FreeType2. +11. Support more encodings - encodings combos now list standard encodings as well as those read from + .enc(.gz) files. +12. Internal AMF creator for Type1 and TrueType fonts - ttf2pt1 and pf2afm.ps are no longer used/supplied. +13. Removed the 'Process AFMs' & 'Delete AFMs' options - all AFMs are created be KFontinst, therefore they + should be OK for StarOffice and AbiWord. +14. If a writable XF86Config file is found - then complete folders may be installed, and folders in the X11 + directory may be uninstalled or disabled (i.e. the folder is not deleted, but it's entry is removed from + the XF86Config file). +15. No longer supply .enc files with KFontinst - they should be provided by the distro. + +0.9.1->0.9.2 +============ +1. Removed a bug where the "Configure System" menu entry was always disabled! +2. Spelling error in Settings dialog. +3. t1lib has problems with some of the fonts supplied with Adobe acrobat - therefore, if t1lib fails to load the + font, then KFontinst itself will try to read the header information (although no preview will be available, + everything else should still work). +4. Fixed multiple installing of programs in other/ directory. For instance KFontinst's version of ttmkfdir + was being installed into $(PREFIX) (usually /usr/bin) as well as $(KDE_DATADIR)/kfontinst - this was incorrect + as KFontinst will only use the version in $(KDE_DATADIR)/kfontinst, and it was possible that a previous version + of ttmkfdir (such as that supplied with XFree86) would have been overwritten. +5. Fixed bug where the user was allowed to select (and subsequently install) fonts which could not be loaded correctly. +6. Added the ability to enter a custom preview string. + +0.9->0.9.1 +========== +1. Fixed a few compile errors. +2. Fix to html formatting error. +3. Fixed a ./configure error if t1lib was not found (the string NO was being used as the + librarary name, instead of an empty string!) +4. Modified the reading of Type1 header information. + +0.8.3->0.9 +========== +1. Converted to KDE2. +2. Rearranged this file! +3. Removed command line interface - KDE2's command line stuff is way different! +4. Re-created dialogs with Qt designer. +5. Removed ProgressDialog, and replaced with a progress bar on a new statusbar. +6. Modified configure script to check for FreeType & t1lib. +7. If an encoding (not unicode) is selected, then the .enc file is copied to the X11 fonts directory. +8. As with the .enc files, the StarOffice .xpp files are also copied, and no longer just sym linked. +9. Removed enabling/disabing of Configure System button. +10. Fontmap.X11 is no longer created, instead the real Fontmap file itself is modified. + +0.8.2->0.8.3 +============ +1. Modified 'kfontinst.kdelnk' so that kdesu is now used - so that a user will automatically be prompted + for the root password. +2. Modified dialogs to use the KDE caption ("Font Installer") instead of the app name ("kfontinst") +3. Corrected size of Configure dialog. +4. Fixed a minor bug where if all fonts were uninstalled, the 'Configure System' button was disabled - therefore not + allowing you to activate the changes! +5. Added a command line interface. (type 'kfontinst --help' for details) +6. Added option to automatically fix TTF postscript names upon install. + +0.8.1->0.8.2 +============ +1. Fixed a bug which always had SO configuration disabled! +2. Fixed a bug when selecting Unicode encoding. +3. Changed "Fonts/Uninstalled" menu entry to "Fonts/Disk" +4. Added keyboard short-cuts to dialogs + +0.8->0.8.1 +========== +1. Fixed a bug where X configuration would fail if no TT fonts present. +2. If no fonts are installed, then the system configuration button/menu-entry is now disabled. +3. Changed menu structure to add 'Fonts' menu. + +0.7.4->0.8 +========== +1. Changed location of StarOffice stuf from
    /xp3 to just + -- As StarOffice 5.2 has 'xp3' within a 'share' sub-dir. +2. Changed structure of config file to be more modular. +3. Modified internal code structure to allow easier additon of extra apps to be configured. (NOTE: If any + apps need to be configured, then I'll also [later on] modify the Settings & Configure dialogs to + accomodate these.) +4. Because of 3, added a 'StarOffice' check to the settings dialog. If this is not seleted, then no check + is performed to make sure the SO dir is OK - and the option to config SO is diabled on the config dialog. +5. Added check when installing font to make sure that it's not already installed. + +0.7.3->0.7.4 +============ +1. Changed location of Fontmap.X11 -- from /lib/Fontmap.X11 to + /Fontmap.X11. As it seems some ghostscript installations don't + have the 'lib' sub directory. +2. Improved the documentation a little - added a FAQ section + +0.7.2->0.7.3 +============ +1. Very minor bug fix. + +0.7.1->0.7.2 +============ +1. Added more detailed error messages when system configuration fails. + +0.7->0.7.1 +========== +1. Removed lots of debug info from ttf2pt1, and afm.pl -- this should drastically speed up afm creation. +2. Modified ttf2pt1 to accept a parameter to just create .afm files +3. Added option to modify a .afm file when installing. +4. Added "Unicode" to list of encodings that can be used. +5. Removed kfontinst-cp1252.enc, kfontinst-cp1252.xpp -- these were hacks anyway, and seing as Qt2 is going to + support cp1252 by a hard-coded codec, there's no real point... +6. Rearranged the Configure System dialog - so that Force AFM regeneration is grouped next to the Generate AFMs option. +7. Encoding files now stored in /share/apps/kfontinst/Encodings + +0.6.1->0.7 +========== +1. Modified ttmkfdir & ttf2pt1 to allow usage of X11 style font re-encoding files. +2. Because .enc files are now used by kfontinst, removed the possibility of using gzipped encodings. +3. Added the ability to delete an installed font's .afm file. +4. Fixed a bug in the TtfPsNameFixer class - this would cause ttf2pt1 to creash when accessing a modified font! +5. Font encodings are now stored in /share/x11encodings +6. Removed the reencode shell script, as the encodng is all done by ttmkfdir. +7. Removed xfinst shell script - handled internally. +8. Supplied a kfontinst-cp1252 encoding - with the ugly single-quotes normaly found in .ttf files remapped to + the nice looking ones. +9. Added functionality, when configuring StarOffice, to select an appropriate xprinter.prolog for the selected + encoding (if one exists)... + +0.6->0.6.1 +========== +1. Fixed a display bug in the 'Un/Exclude from StarOffice" options. + +0.5->0.6 +======== +1. Added the ability to 'fix' the postscript names in a ttf file. +2. Fixed some missing changes to help files. + +0.4->0.5 +======== +1. Discovered a patch that modifies StarOffice's xprinter.prolog so that font's don't need to be modified + to use the microsoft cp1252 enocding scheme. (Previosuly the PS output from StarOffice would not print + OK with ghostscript - when using extra characters - unless the .ttf file was modified.) +2. Because of 1, removed the abilty to modify a TrueType font's internal charactermap - this was a hack anyway. +3. xfinst now uses mkfontdir to create encodings.dir - instead of kfontinst's install procedure copying a standard + one in (this didn't actually work...) +4. As kfontinst no longer reads the .enc files themselves, added the ability to use .enc.gz files as well + when selecting an encoding for X. +5. Re-wrote xfinst & reencode to be plain 'sh' scripts, as opposed to 'tcsh' scripts. + +0.3->0.4 +======== +1. All X fonts will now be placed with in a directory - "Managed" - this makes things easier for + AbiWord, and maybe others. +2. encodings.dir & Encodings/ will now be placed within this new "Managed" dir. +3. Only 1 StarOffice .PS file will be created - X11.PS +4. Only 1 Fontmap will be created - Fontmap.X11 - and this will be placed within + /lib +5. Because of 4, an option has been added to the Settings dialog to specify the location of + Ghostscript. +6. Because of 1, removed the font option from the Configure dialog. +7. Fixed an error with getting PS name from TT font - PS names are not allowed to have spaces, but in + fences.ttf it does. FontEngine.cpp will now check for, and fix, this - using the same 'algorithm' as that + of ttf2pt1 (which means the names will tie up with those in the .afm files). +8. Added some improvements to control of dialogs. + +0.2.1->0.3 +========== +1. Reverted back to naming .afm files .afm - and renaming any conflicting fonts. +2. Speeded up copying of files - by copying preview bitmap as opposed to regenerating it! +3. Removed need for FontMetrics directory - .afm files now placed within TrueType or Type1 dir, + and sym links are produced for StarOffice. + + 1. & 3. should now make things easier for AbiWord. + +4. Fixed output of Fontmap so that "URW Gothic" will be aliased as "UrwGothic-Roman" (etc.) as + this is what Qt will output. +5. Added more processing of .afm files - this makes them OK for AbiWord. + +0.2->0.2.1 +========== +1. Modified start-up progress dailog, and added progress dialogs to main window when scanning + fonts. These will only appear if numTTfonts>X || numT1fonts>Y + +0.1->0.2 +======== +1. Combined views of installed TrueType and Type1 fonts into 1 list. +2. When uninstalling a font, can now move the font to another directory - or delete. +3. Used t1lib so that Type1 fonts can also be previewed. +4. Changed Fontmap creator to dynamically allocate memory for each font-category. +5. .afm files are now named as ..afm - this removes the need + for renaming the .afm file if there exists Type1 and TrueType fonts with the same + fontname. +6. Removed the re-scanning of the install directories whenever a font is added. +7. Added support for extra Type1 font weights. +8. Added a start-up screen to inform the user that the installed/disk fonts are being scanned. +9. When exiting, confirmation is now only asked if the system has been changed and not + reconfigured. diff --git a/kcontrol/kfontinst/Messages.sh b/kcontrol/kfontinst/Messages.sh new file mode 100644 index 00000000..0634d49b --- /dev/null +++ b/kcontrol/kfontinst/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC `find . -name \*.rc` >> rc.cpp +$XGETTEXT rc.cpp */*.cpp */*.h -o $podir/kfontinst.pot +rm -f rc.cpp diff --git a/kcontrol/kfontinst/apps/CMakeLists.txt b/kcontrol/kfontinst/apps/CMakeLists.txt new file mode 100644 index 00000000..975a187f --- /dev/null +++ b/kcontrol/kfontinst/apps/CMakeLists.txt @@ -0,0 +1,33 @@ +include_directories( + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcontrol/kfontinst/kcmfontinst/ + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcontrol/kfontinst/viewpart/ + ${CMAKE_CURRENT_BINARY_DIR} + ) + +set(kfontinst_bin_SRCS ${libkfontinstjobrunner_SRCS} ${libkfontinstdbusiface_SRCS} Installer.cpp ) +# qt4_add_dbus_interface(kfontinst_bin_SRCS ../dbus/org.kde.fontinst.xml FontInstInterfaceBase) + +set(kfontprint_bin_SRCS ${libkfontinstactionlabel_SRCS} Printer.cpp ) +set(kfontview_bin_SRCS Viewer.cpp ) + +kde4_add_executable(kfontinst_bin ${kfontinst_bin_SRCS}) +kde4_add_executable(kfontprint_bin ${kfontprint_bin_SRCS}) +kde4_add_executable(kfontview_bin ${kfontview_bin_SRCS}) + +set_target_properties(kfontinst_bin PROPERTIES OUTPUT_NAME kfontinst) +set_target_properties(kfontprint_bin PROPERTIES OUTPUT_NAME kfontprint) +set_target_properties(kfontview_bin PROPERTIES OUTPUT_NAME kfontview) + +target_link_libraries(kfontinst_bin ${KDE4_KIO_LIBS} ${KDE4_KDESU_LIBS} ${X11_X11_LIB} kfontinst) +target_link_libraries(kfontprint_bin ${X11_X11_LIB} ${KDE4_KDEUI_LIBS} ${FREETYPE_LIBRARIES} kfontinstui kfontinst) +target_link_libraries(kfontview_bin ${KDE4_KPARTS_LIBS} kfontinstui kfontinst ) + +install(TARGETS kfontinst_bin ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(TARGETS kfontprint_bin DESTINATION ${LIBEXEC_INSTALL_DIR} ) +install(TARGETS kfontview_bin ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(FILES kfontviewui.rc DESTINATION ${DATA_INSTALL_DIR}/kfontview ) +install(PROGRAMS kfontview.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install(FILES installfont.desktop DESTINATION +${SERVICES_INSTALL_DIR}/ServiceMenus ) + +kde4_install_icons( ${ICON_INSTALL_DIR} ) diff --git a/kcontrol/kfontinst/apps/CreateParent.h b/kcontrol/kfontinst/apps/CreateParent.h new file mode 100644 index 00000000..5a3dc381 --- /dev/null +++ b/kcontrol/kfontinst/apps/CreateParent.h @@ -0,0 +1,73 @@ +#ifndef __CREATE_PARENT_H__ +#define __CREATE_PARENT_H__ + +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 +#include +#include +#include + +// +// *Very* hacky way to get some KDE dialogs to appear to be transient +// for 'xid' +// +// Create's a QWidget with size 0/0 and no border, makes this transient +// for xid, and all other widgets can use this as their parent... +static QWidget * createParent(int xid) +{ + if(!xid) + return NULL; + + QWidget *parent=new QWidget(NULL, Qt::FramelessWindowHint); + + parent->resize(1, 1); + parent->show(); + + XWindowAttributes attr; + int rx, ry; + Window junkwin; + + XSetTransientForHint(QX11Info::display(), parent->winId(), xid); + if(XGetWindowAttributes(QX11Info::display(), xid, &attr)) + { + XTranslateCoordinates(QX11Info::display(), xid, attr.root, + -attr.border_width, -16, + &rx, &ry, &junkwin); + + rx=(rx+(attr.width/2)); + if(rx<0) + rx=0; + ry=(ry+(attr.height/2)); + if(ry<0) + ry=0; + parent->move(rx, ry); + } + parent->setWindowOpacity(0); + parent->setWindowTitle(QLatin1String("KFI")); + + return parent; +} + +#endif diff --git a/kcontrol/kfontinst/apps/Installer.cpp b/kcontrol/kfontinst/apps/Installer.cpp new file mode 100644 index 00000000..9747fe3f --- /dev/null +++ b/kcontrol/kfontinst/apps/Installer.cpp @@ -0,0 +1,154 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 "Installer.h" +#include "Misc.h" +#include "FontsPackage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "JobRunner.h" +#include "CreateParent.h" + +namespace KFI +{ + +int CInstaller::install(const QSet &urls) +{ + QSet::ConstIterator it(urls.begin()), + end(urls.end()); + bool sysInstall(false); + CJobRunner *jobRunner=new CJobRunner(itsParent); + + CJobRunner::startDbusService(); + + if(!Misc::root()) + { + switch(KMessageBox::questionYesNoCancel(itsParent, + i18n("Do you wish to install the font(s) for personal use " + "(only available to you), or " + "system-wide (available to all users)?"), + i18n("Where to Install"), KGuiItem(i18n(KFI_KIO_FONTS_USER)), + KGuiItem(i18n(KFI_KIO_FONTS_SYS)))) + { + case KMessageBox::No: + sysInstall=true; + break; + case KMessageBox::Cancel: + return -1; + default: + break; + } + } + + QSet instUrls; + + for(; it!=end; ++it) + { + KUrl local(KIO::NetAccess::mostLocalUrl(*it, NULL)); + bool package(false); + + if(local.isLocalFile()) + { + QString localFile(local.toLocalFile()); + + if(Misc::isPackage(localFile)) + { + instUrls+=FontsPackage::extract(localFile, &itsTempDir); + package=true; + } + } + if(!package) + { + KUrl::List associatedUrls; + + CJobRunner::getAssociatedUrls(*it, associatedUrls, false, itsParent); + instUrls.insert(*it); + + KUrl::List::Iterator aIt(associatedUrls.begin()), + aEnd(associatedUrls.end()); + + for(; aIt!=aEnd; ++aIt) + instUrls.insert(*aIt); + } + } + + if(instUrls.count()) + { + CJobRunner::ItemList list; + QSet::ConstIterator it(instUrls.begin()), + end(instUrls.end()); + + for(; it!=end; ++it) + list.append(*it); + + return jobRunner->exec(CJobRunner::CMD_INSTALL, list, Misc::root() || sysInstall); + } + else + return -1; +} + +CInstaller::~CInstaller() +{ + delete itsTempDir; +} + +} + +static KAboutData aboutData("kfontinst", KFI_CATALOGUE, ki18n("Font Installer"), "1.0", ki18n("Simple font installer"), + KAboutData::License_GPL, ki18n("(C) Craig Drummond, 2007")); + +int main(int argc, char **argv) +{ + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("embed ", ki18n("Makes the dialog transient for an X app specified by winid")); + options.add("+[URL]", ki18n("URL to install")); + KCmdLineArgs::addCmdLineOptions(options); + + QSet urls; + KCmdLineArgs *args(KCmdLineArgs::parsedArgs()); + + for(int i=0; i < args->count(); i++) + urls.insert(args->url(i)); + + if(urls.count()) + { + KLocale::setMainCatalog(KFI_CATALOGUE); + + KApplication app; + QString opt(args->getOption("embed")); + KFI::CInstaller inst(createParent(opt.size() ? opt.toInt(0, 16) : 0)); + + return inst.install(urls); + } + + return -1; +} diff --git a/kcontrol/kfontinst/apps/Installer.h b/kcontrol/kfontinst/apps/Installer.h new file mode 100644 index 00000000..29237e58 --- /dev/null +++ b/kcontrol/kfontinst/apps/Installer.h @@ -0,0 +1,53 @@ +#ifndef __INSTALLER_H__ +#define __INSTALLER_H__ + +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 +#include + +class QWidget; +class KTempDir; + +namespace KFI +{ +class CInstaller +{ + public: + + CInstaller(QWidget *p) + : itsParent(p), itsTempDir(NULL) { } + ~CInstaller(); + + int install(const QSet &urls); + + private: + + QWidget *itsParent; + KTempDir *itsTempDir; +}; + +} + +#endif diff --git a/kcontrol/kfontinst/apps/Printer.cpp b/kcontrol/kfontinst/apps/Printer.cpp new file mode 100644 index 00000000..60393156 --- /dev/null +++ b/kcontrol/kfontinst/apps/Printer.cpp @@ -0,0 +1,496 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 "config-fontinst.h" +#include "Printer.h" +#include "FcEngine.h" +#include "ActionLabel.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_WS_X11) || defined(Q_WS_QWS) +#include +#include +#include FT_FREETYPE_H +#endif + +#ifdef HAVE_LOCALE_H +#include +#endif +#include "CreateParent.h" + +// Enable the following to allow printing of non-installed fonts. Does not seem to work :-( +//#define KFI_PRINT_APP_FONTS + +using namespace KFI; + +static const int constMarginLineBefore=1; +static const int constMarginLineAfter=2; +static const int constMarginFont=4; + +inline bool sufficientSpace(int y, int pageHeight, const QFontMetrics &fm) +{ + return (y+constMarginFont+fm.height())fontMetrics().height(), + required=titleFontHeight+constMarginLineBefore+constMarginLineAfter; + + for(unsigned int s=0; sizes[s]; ++s) + { + font.setPointSize(sizes[s]); + required+=QFontMetrics(font, painter->device()).height(); + if(sizes[s+1]) + required+=constMarginFont; + } + + if(0==size) + { + font.setPointSize(CFcEngine::constDefaultAlphaSize); + int fontHeight=QFontMetrics(font, painter->device()).height(); + + required+=(3*(constMarginFont+fontHeight))+ + constMarginLineBefore+constMarginLineAfter; + } + return (y+required)num_charmaps; ++cmap) + if(face->charmaps[cmap] && FT_ENCODING_ADOBE_CUSTOM==face->charmaps[cmap]->encoding) + { + FT_Select_Charmap(face, FT_ENCODING_ADOBE_CUSTOM); + break; + } + + for(unsigned int i=1; i<65535; ++i) + if(FT_Get_Char_Index(face, i)) + { + newStr+=QChar(i); + if(newStr.length()>255) + break; + } + + return newStr; +} + +static QString usableStr(FT_Face face, const QString &str) +{ + unsigned int slen=str.length(), + ch; + QString newStr; + + for(ch=0; ch &items, int size, QObject *parent) + : QThread(parent) + , itsPrinter(printer) + , itsItems(items) + , itsSize(size) + , itsCancelled(false) +{ +} + +CPrintThread::~CPrintThread() +{ +} + +void CPrintThread::cancel() +{ + itsCancelled=true; +} + +void CPrintThread::run() +{ + QPainter painter; + QFont sans("sans", 12, QFont::Bold); + bool changedFontEmbeddingSetting(false); + QString str(CFcEngine(false).getPreviewString()); + + if(!itsPrinter->fontEmbeddingEnabled()) + { + itsPrinter->setFontEmbeddingEnabled(true); + changedFontEmbeddingSetting=true; + } + + itsPrinter->setResolution(72); + painter.begin(itsPrinter); + + int pageWidth=painter.device()->width(), + pageHeight=painter.device()->height(), + y=0, + oneSize[2]={itsSize, 0}; + const int *sizes=oneSize; + bool firstFont(true); + + if(0==itsSize) + sizes=CFcEngine::constScalableSizes; + + painter.setClipping(true); + painter.setClipRect(0, 0, pageWidth, pageHeight); + + QList::ConstIterator it(itsItems.constBegin()), + end(itsItems.constEnd()); + + for(int i=0; it!=end && !itsCancelled; ++it, ++i) + { + QString name(FC::createName((*it).family, (*it).styleInfo)); + emit progress(i, name); + + unsigned int s=0; + QFont font; + +#ifdef KFI_PRINT_APP_FONTS + QString family; + + if(-1!=appFont[(*it).family]) + { + family=QFontDatabase::applicationFontFamilies(appFont[(*it).family]).first(); + font=QFont(family); + } +#else + font=CFcEngine::getQFont((*it).family, (*it).styleInfo, CFcEngine::constDefaultAlphaSize); +#endif + painter.setFont(sans); + + if(!firstFont && !sufficientSpace(y, &painter, font, sizes, pageHeight, itsSize)) + { + itsPrinter->newPage(); + y=0; + } + painter.setFont(sans); + y+=painter.fontMetrics().height(); + painter.drawText(0, y, name); + + y+=constMarginLineBefore; + painter.drawLine(0, y, pageWidth, y); + y+=constMarginLineAfter; + + bool onlyDrawChars=false; + Qt::TextElideMode em=Qt::LeftToRight==QApplication::layoutDirection() ? Qt::ElideRight : Qt::ElideLeft; + + if(0==itsSize) + { + font.setPointSize(CFcEngine::constDefaultAlphaSize); + painter.setFont(font); + + QFontMetrics fm(font, painter.device()); + bool lc=hasStr(font, CFcEngine::getLowercaseLetters()), + uc=hasStr(font, CFcEngine::getUppercaseLetters()); + + onlyDrawChars=!lc && !uc; + + if(lc || uc) + y+=CFcEngine::constDefaultAlphaSize; + + if(lc) + { + painter.drawText(0, y, fm.elidedText(CFcEngine::getLowercaseLetters(), em, pageWidth)); + y+=constMarginFont+CFcEngine::constDefaultAlphaSize; + } + + if(uc) + { + painter.drawText(0, y, fm.elidedText(CFcEngine::getUppercaseLetters(), em, pageWidth)); + y+=constMarginFont+CFcEngine::constDefaultAlphaSize; + } + + if(lc || uc) + { + QString validPunc(usableStr(font, CFcEngine::getPunctuation())); + if(validPunc.length()>=(CFcEngine::getPunctuation().length()/2)) + { + painter.drawText(0, y, fm.elidedText(CFcEngine::getPunctuation(), em, pageWidth)); + y+=constMarginFont+constMarginLineBefore; + } + painter.drawLine(0, y, pageWidth, y); + y+=constMarginLineAfter; + } + } + + for(; sizes[s]; ++s) + { + y+=sizes[s]; + font.setPointSize(sizes[s]); + painter.setFont(font); + + QFontMetrics fm(font, painter.device()); + + if(sufficientSpace(y, pageHeight, fm)) + { + painter.drawText(0, y, fm.elidedText(previewString(font, str, onlyDrawChars), em, pageWidth)); + if(sizes[s+1]) + y+=constMarginFont; + } + else + break; + } + y+=(s<1 || sizes[s-1]<25 ? 14 : 28); + firstFont=false; + } + emit progress(itsItems.count(), QString()); + painter.end(); + + // + // Did we change the users font settings? If so, reset to their previous values... + if(changedFontEmbeddingSetting) + itsPrinter->setFontEmbeddingEnabled(false); +} + +CPrinter::CPrinter(QWidget *parent) + : KDialog(parent) +{ + setCaption(i18n("Print")); + setButtons(Cancel); + + QFrame *page = new QFrame(this); + QGridLayout *layout=new QGridLayout(page); + layout->setMargin(KDialog::marginHint()); + layout->setSpacing(KDialog::spacingHint()); + itsStatusLabel=new QLabel(page); + itsProgress=new QProgressBar(page); + layout->addWidget(itsActionLabel = new CActionLabel(this), 0, 0, 2, 1); + layout->addWidget(itsStatusLabel, 0, 1); + layout->addWidget(itsProgress, 1, 1); + itsProgress->setRange(0, 100); + layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding), 2, 0); + setMainWidget(page); + setMinimumSize(420, 80); +} + +CPrinter::~CPrinter() +{ +} + +void CPrinter::print(const QList &items, int size) +{ + #ifdef HAVE_LOCALE_H + char *oldLocale=setlocale(LC_NUMERIC, "C"); + #endif + + QPrinter printer; + QPrintDialog *dialog = KdePrint::createPrintDialog(&printer, parentWidget()); + + if(dialog->exec()) + { + CPrintThread *thread = new CPrintThread(&printer, items, size, this); + + itsProgress->setRange(0, items.count()); + itsProgress->setValue(0); + progress(0, QString()); + connect(thread, SIGNAL(progress(int,QString)), SLOT(progress(int,QString))); + connect(thread, SIGNAL(finished()), SLOT(accept())); + connect(this, SIGNAL(cancelled()), thread, SLOT(cancel())); + itsActionLabel->startAnimation(); + thread->start(); + exec(); + delete thread; + } + + delete dialog; + + #ifdef HAVE_LOCALE_H + if(oldLocale) + setlocale(LC_NUMERIC, oldLocale); + #endif +} + +void CPrinter::progress(int p, const QString &label) +{ + if(!label.isEmpty()) + itsStatusLabel->setText(label); + itsProgress->setValue(p); +} + +void CPrinter::slotButtonClicked(int button) +{ + Q_UNUSED(button) + itsStatusLabel->setText(i18n("Canceling...")); + emit cancelled(); +} + +void CPrinter::closeEvent(QCloseEvent *e) +{ + Q_UNUSED(e) + e->ignore(); + slotButtonClicked(0); +} + +static KAboutData aboutData("kfontprint", KFI_CATALOGUE, ki18n("Font Printer"), "1.1", ki18n("Simple font printer"), + KAboutData::License_GPL, ki18n("(C) Craig Drummond, 2007")); + +int main(int argc, char **argv) +{ + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("embed ", ki18n("Makes the dialog transient for an X app specified by winid")); + options.add("size ", ki18n("Size index to print fonts")); + options.add("pfont ", ki18n("Font to print, specified as \"Family,Style\" where Style is a 24-bit decimal number composed as: ")); //krazy:exclude=i18ncheckarg + options.add("listfile ", ki18n("File containing list of fonts to print")); + options.add("deletefile", ki18n("Remove file containing list of fonts to print")); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + KCmdLineArgs *args(KCmdLineArgs::parsedArgs()); + QList fonts; + int size(args->getOption("size").toInt()); + + if(size>-1 && size<256) + { + QString listFile(args->getOption("listfile")); + + if(listFile.size()) + { + QFile f(listFile); + + if(f.open(QIODevice::ReadOnly)) + { + QTextStream str(&f); + + while (!str.atEnd()) + { + QString family(str.readLine()), + style(str.readLine()); + + if(!family.isEmpty() && !style.isEmpty()) + fonts.append(Misc::TFont(family, style.toUInt())); + else + break; + } + f.close(); + } + + if(args->isSet("deletefile")) + ::unlink(listFile.toLocal8Bit().constData()); + } + else + { + QStringList fl(args->getOptionList("pfont")); + QStringList::ConstIterator it(fl.begin()), + end(fl.end()); + + for(; it!=end; ++it) + { + QString f(*it); + + int commaPos=f.lastIndexOf(','); + + if(-1!=commaPos) + fonts.append(Misc::TFont(f.left(commaPos), f.mid(commaPos+1).toUInt())); + } + } + + if(fonts.count()) + { + KLocale::setMainCatalog(KFI_CATALOGUE); + CPrinter(createParent(args->getOption("embed").toInt(0, 16))).print(fonts, size); + + return 0; + } + } + + return -1; +} + +#include "Printer.moc" diff --git a/kcontrol/kfontinst/apps/Printer.h b/kcontrol/kfontinst/apps/Printer.h new file mode 100644 index 00000000..910e3285 --- /dev/null +++ b/kcontrol/kfontinst/apps/Printer.h @@ -0,0 +1,103 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2011 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 __PRINTER_H__ +#define __PRINTER_H__ + +#include +#include +#include +#include +#include "Misc.h" + +class QLabel; +class QProgressBar; +class QStackedWidget; +class QPrinter; + +namespace KFI +{ + +class CActionLabel; + +class CPrintThread : public QThread +{ + Q_OBJECT + + public: + + CPrintThread(QPrinter *printer, const QList &items, int size, QObject *parent); + ~CPrintThread(); + + void run(); + + Q_SIGNALS: + + void progress(int p, const QString &f); + + public Q_SLOTS: + + void cancel(); + + private: + + QPrinter *itsPrinter; + QList itsItems; + int itsSize; + bool itsCancelled; +}; + +class CPrinter : public KDialog +{ + Q_OBJECT + + public: + + explicit CPrinter(QWidget *parent); + ~CPrinter(); + + void print(const QList &items, int size); + + Q_SIGNALS: + + void cancelled(); + + public Q_SLOTS: + + void progress(int p, const QString &label); + void slotButtonClicked(int button); + + private: + + void closeEvent(QCloseEvent *e); + + private: + + QLabel *itsStatusLabel; + QProgressBar *itsProgress; + CActionLabel *itsActionLabel; +}; + +} + +#endif diff --git a/kcontrol/kfontinst/apps/Viewer.cpp b/kcontrol/kfontinst/apps/Viewer.cpp new file mode 100644 index 00000000..f8408c57 --- /dev/null +++ b/kcontrol/kfontinst/apps/Viewer.cpp @@ -0,0 +1,166 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 "Viewer.h" +#include "KfiConstants.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace KFI +{ + +CViewer::CViewer() +{ + KPluginFactory *factory=KPluginLoader("kfontviewpart").factory(); + + if(factory) + { + itsPreview=factory->create(this); + + actionCollection()->addAction(KStandardAction::Open, this, SLOT(fileOpen())); + actionCollection()->addAction(KStandardAction::Quit, this, SLOT(close())); + actionCollection()->addAction(KStandardAction::KeyBindings, this, SLOT(configureKeys())); + itsPrintAct=actionCollection()->addAction(KStandardAction::Print, itsPreview, SLOT(print())); + + itsPrintAct->setEnabled(false); + + if(itsPreview->browserExtension()) + connect(itsPreview->browserExtension(), SIGNAL(enableAction(const char*,bool)), + this, SLOT(enableAction(const char*,bool))); + + setCentralWidget(itsPreview->widget()); + createGUI(itsPreview); + + setAutoSaveSettings(); + applyMainWindowSettings(KGlobal::config()->group("MainWindow")); + } + else + exit(0); +} + +void CViewer::fileOpen() +{ + KUrl url(KFileDialog::getOpenUrl(KUrl(), "application/x-font-ttf application/x-font-otf " + "application/x-font-type1 " + "application/x-font-bdf application/x-font-pcf ", + this, i18n("Select Font to View"))); + showUrl(url); +} + +void CViewer::showUrl(const KUrl &url) +{ + if(url.isValid()) + itsPreview->openUrl(url); +} + +void CViewer::configureKeys() +{ + KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this); + + dlg.addCollection(actionCollection()); + dlg.configure(); +} + +void CViewer::enableAction(const char *name, bool enable) +{ + if(0==qstrcmp("print", name)) + itsPrintAct->setEnabled(enable); +} + + + + +class ViewerApplication : public KUniqueApplication +{ + public: + +#ifdef Q_WS_X11 + ViewerApplication(Display *display, Qt::HANDLE visual, Qt::HANDLE colormap) + : KUniqueApplication(display,visual,colormap) + { + } +#endif + + ViewerApplication() : KUniqueApplication() + { + } + + int newInstance() + { + KCmdLineArgs *args(KCmdLineArgs::parsedArgs()); + KFI::CViewer *viewer=new KFI::CViewer; + + viewer->show(); + if(args->count() > 0) + { + for (int i = 0; i < args->count(); ++i) + { + KUrl url(args->url(i)); + + if (i != 0) + { + viewer=new KFI::CViewer; + viewer->show(); + } + viewer->showUrl(url); + } + } + + return 0; + } +}; + +} + +static KAboutData aboutData("kfontview", KFI_CATALOGUE, ki18n("Font Viewer"), "1.1", ki18n("Simple font viewer"), + KAboutData::License_GPL, ki18n("(C) Craig Drummond, 2004-2007")); + +int main(int argc, char **argv) +{ + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addTempFileOption(); + + KCmdLineOptions options; + options.add("+[URL]", ki18n("URL to open")); + KCmdLineArgs::addCmdLineOptions(options); + + if (!KUniqueApplication::start()) + exit(0); + + KFI::ViewerApplication app; + + return app.exec(); +} + +#include "Viewer.moc" diff --git a/kcontrol/kfontinst/apps/Viewer.h b/kcontrol/kfontinst/apps/Viewer.h new file mode 100644 index 00000000..b0fafe52 --- /dev/null +++ b/kcontrol/kfontinst/apps/Viewer.h @@ -0,0 +1,59 @@ +#ifndef __VIEWER_H__ +#define __VIEWER_H__ + +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2007 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 +#include + +class QAction; + +namespace KFI +{ + +class CViewer : public KParts::MainWindow +{ + Q_OBJECT + + public: + + CViewer(); + virtual ~CViewer() { } + void showUrl(const KUrl &url); + + public Q_SLOTS: + + void fileOpen(); + void configureKeys(); + void enableAction(const char *name, bool enable); + + private: + + KParts::ReadOnlyPart *itsPreview; + QAction *itsPrintAct; +}; + +} + +#endif diff --git a/kcontrol/kfontinst/apps/installfont.desktop b/kcontrol/kfontinst/apps/installfont.desktop new file mode 100644 index 00000000..a83e4198 --- /dev/null +++ b/kcontrol/kfontinst/apps/installfont.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +X-KDE-ServiceTypes=KonqPopupMenu/Plugin,application/x-font-ttf,application/x-font-type1,application/x-font-bdf,application/x-font-pcf,application/x-font-otf,application/x-font-afm,fonts/package +Actions=installFont; +Type=Service + +[Desktop Action installFont] +Name=Install... +Name[af]=Installeer... +Name[ar]=ثبّت... +Name[as]=সংস্থাপন কৰক... +Name[ast]=Instalar... +Name[be]=Устанавіць... +Name[be@latin]=Zainstaluj... +Name[bg]=Инсталиране... +Name[bn]=ইনস্টল... +Name[bn_IN]=ইনস্টল করুন... +Name[bs]=Instaliraj... +Name[ca]=Instal·la... +Name[ca@valencia]=Instal·la... +Name[cs]=Instalovat... +Name[csb]=Instalëjë... +Name[da]=Installér... +Name[de]=Installieren ... +Name[el]=Εγκατάσταση... +Name[en_GB]=Install... +Name[eo]=Instali... +Name[es]=Instalar... +Name[et]=Paigalda... +Name[eu]=Instalatu... +Name[fa]=نصب... +Name[fi]=Asenna… +Name[fr]=Installer... +Name[fy]=Ynstallearje... +Name[ga]=Suiteáil... +Name[gl]=Instalar... +Name[gu]=સ્થાપન... +Name[he]=התקנה... +Name[hi]=संस्थापित करें... +Name[hne]=इंस्टाल करव... +Name[hr]=Instaliraj… +Name[hsb]=instalować... +Name[hu]=Telepítés... +Name[ia]=Installa ... +Name[id]=Instal... +Name[is]=Setja upp... +Name[it]=Installa... +Name[ja]=インストール... +Name[kk]=Орнату... +Name[km]=ដំឡើង... +Name[kn]=ಅನುಸ್ಢಾಪಿಸು... +Name[ko]=설치... +Name[ku]=Sazkirin... +Name[lt]=Įdiegti... +Name[lv]=Instalēt... +Name[mai]=संस्थापित करू... +Name[mk]=Инсталирање... +Name[ml]=ഇന്‍‌സ്റ്റോള്‍ ചെയ്യുക... +Name[mr]=प्रतिष्ठापन... +Name[nb]=Installer … +Name[nds]=Installeren... +Name[ne]=स्थापना गर्नुहोस् +Name[nl]=Installeren... +Name[nn]=Installer … +Name[oc]=Installar... +Name[or]=ସ୍ଥାପନ କରନ୍ତୁ... +Name[pa]=ਇੰਸਟਾਲ... +Name[pl]=Instaluj... +Name[pt]=Instalar... +Name[pt_BR]=Instalar... +Name[ro]=Instalare... +Name[ru]=Установить... +Name[se]=Sajáiduhte … +Name[si]=ස්ථාපනය... +Name[sk]=Inštalovať... +Name[sl]=Namesti ... +Name[sr]=Инсталирај... +Name[sr@ijekavian]=Инсталирај... +Name[sr@ijekavianlatin]=Instaliraj... +Name[sr@latin]=Instaliraj... +Name[sv]=Installera... +Name[ta]=நிறுவுக... +Name[te]=సంస్థాపించు... +Name[tg]=Коргузорӣ... +Name[th]=ติดตั้ง... +Name[tr]=Yükle... +Name[ug]=ئورنات… +Name[uk]=Встановити... +Name[uz]=Oʻrnatish... +Name[uz@cyrillic]=Ўрнатиш... +Name[vi]=Cài đặt... +Name[wa]=Astaler... +Name[x-test]=xxInstall...xx +Name[zh_CN]=安装... +Name[zh_TW]=安裝... +Icon=preferences-desktop-font-installer +Exec=kfontinst --icon preferences-desktop-font-installer %U diff --git a/kcontrol/kfontinst/apps/kfontview.desktop b/kcontrol/kfontinst/apps/kfontview.desktop new file mode 100755 index 00000000..20c0042e --- /dev/null +++ b/kcontrol/kfontinst/apps/kfontview.desktop @@ -0,0 +1,192 @@ +[Desktop Entry] +Name=KFontView +Name[af]=KFontView +Name[ar]=عارض خطوط كيدي +Name[ast]=KFontView +Name[be]=Прагляд шрыфтоў +Name[be@latin]=KFontView +Name[bg]=KFontView +Name[bn]=কে-ফন্ট-ভিউ +Name[bn_IN]=KFontView +Name[br]=KFontView +Name[bs]=K‑prikazivač-fontova +Name[ca]=KFontView +Name[ca@valencia]=KFontView +Name[cs]=Prohlížeč písem +Name[csb]=KFontView +Name[cy]=KFontView +Name[da]=KFontView +Name[de]=KFontView +Name[el]=KFontView +Name[en_GB]=KFontView +Name[eo]=KFontView +Name[es]=KFontView +Name[et]=KFontView +Name[eu]=KFontWiew +Name[fi]=KFontView +Name[fr]=KFontView +Name[fy]=KFontView +Name[ga]=KFontView +Name[gl]=KFontView +Name[gu]=KFontView +Name[he]=KFontView +Name[hi]=के-फ़ॉन्ट-व्यू +Name[hne]=के-फोंट-व्यू +Name[hr]=KFontView +Name[hsb]=KFontView +Name[hu]=KFontView +Name[ia]=KFontView +Name[id]=KFontView +Name[is]=KFontView +Name[it]=KFontView +Name[ja]=KFontView +Name[ka]=KFontView +Name[kk]=KFontView +Name[km]=KFontView +Name[kn]=ಕೆಫಾಂಟ್ ವ್ಯೂ +Name[ko]=KFontView +Name[ku]=KFontView +Name[lt]=KFontView +Name[lv]=KFontView +Name[mai]=के-फान्ट-व्यू +Name[mk]=КФонтПреглед +Name[ml]=കെഫോണ്ട്‌വ്യൂ +Name[mr]=केफॉन्टव्यू +Name[ms]=KFontView +Name[nb]=KFontView +Name[nds]=KFontView +Name[ne]=केडीई फन्ट दृश्य +Name[nl]=KFontView +Name[nn]=Skriftvisar +Name[oc]=KFontView +Name[or]=KFontView +Name[pa]=KFontView +Name[pl]=KFontView +Name[pt]=KFontView +Name[pt_BR]=KFontView +Name[ro]=KFontView +Name[ru]=KFontView +Name[se]=Fontačájeheaddji +Name[si]=KFontView +Name[sk]=KFontView +Name[sl]=KFontView +Name[sr]=К‑приказивач-фонтова +Name[sr@ijekavian]=К‑приказивач-фонтова +Name[sr@ijekavianlatin]=K‑prikazivač-fontova +Name[sr@latin]=K‑prikazivač-fontova +Name[sv]=Kfontview +Name[ta]=KFontView +Name[te]=KFontView +Name[tg]=Намоиши ҳарф +Name[th]=ดูแบบอักษร-K +Name[tr]=KFontView +Name[ug]=KFontView +Name[uk]=KFontView +Name[uz]=KFontView +Name[uz@cyrillic]=KFontView +Name[vi]=KFonView +Name[wa]=Håyneu d' fontes +Name[x-test]=xxKFontViewxx +Name[zh_CN]=KFontView +Name[zh_TW]=KFontView +Exec=kfontview %U +Icon=kfontview +X-KDE-StartupNotify=true +Type=Application +MimeType=application/x-font-ttf;application/x-font-type1;application/x-font-otf;application/x-font-pcf;application/x-font-bdf;application/vnd.kde.fontspackage; +GenericName=Font Viewer +GenericName[af]=Skriftipe Besigter +GenericName[ar]=عارض الخطوط +GenericName[ast]=Visor del triba de lletra +GenericName[be]=Прагляд шрыфта +GenericName[be@latin]=Prahladnik šryftoŭ +GenericName[bg]=Преглед на шрифтове +GenericName[bn]=ফন্ট প্রদর্শক +GenericName[bn_IN]=ফন্ট প্রদর্শক +GenericName[br]=Gweler Nodrezhoù +GenericName[bs]=Prikazivač fontova +GenericName[ca]=Visor de tipus de lletra +GenericName[ca@valencia]=Visor de tipus de lletra +GenericName[cs]=Prohlížeč písem +GenericName[csb]=Przezérnik fòntów +GenericName[cy]=Gwelydd Wynebfathau +GenericName[da]=Skrifttype-fremviser +GenericName[de]=Schriftartenbetrachter +GenericName[el]=Προβολέας γραμματοσειρών +GenericName[en_GB]=Font Viewer +GenericName[eo]=Tipara rigardilo +GenericName[es]=Visor del tipo de letra +GenericName[et]=Fontide näitaja +GenericName[eu]=Letra-tipoen ikustailea +GenericName[fa]=مشاهده‌گر قلم +GenericName[fi]=Fonttikatselin +GenericName[fr]=Afficheur de polices de caractères +GenericName[fy]=Lettertypewerjefte +GenericName[ga]=Amharcán Clónna +GenericName[gl]=Visor de tipos de letra +GenericName[gu]=ફોન્ટ દર્શક +GenericName[he]=מציג גופנים +GenericName[hi]=फ़ॉन्ट प्रदर्शक +GenericName[hne]=फोंट प्रदर्सक +GenericName[hr]=Preglednik fontova +GenericName[hsb]=Přehladowar za pisma +GenericName[hu]=Betűtípusböngésző +GenericName[ia]=Visor de fronte +GenericName[id]=Penampil Fonta +GenericName[is]=Leturskoðari +GenericName[it]=Visore di caratteri +GenericName[ja]=フォントビューア +GenericName[ka]=პროგრამა ფონტების სანახავად +GenericName[kk]=Қаріпті қарау құралы +GenericName[km]=កម្មវិធី​មើល​ពុម្ពអក្សរ +GenericName[kn]=ಅಕ್ಷರಶೈಲಿ ವೀಕ್ಷಕ +GenericName[ko]=글꼴 뷰어 +GenericName[ku]=Nîşandêra Curetîpan +GenericName[lt]=Šriftų žiūryklė +GenericName[lv]=Fontu skatītājs +GenericName[mai]=फान्ट प्रदर्शक +GenericName[mk]=Прегледувач на фонтови +GenericName[ml]=അക്ഷരസഞ്ചയദര്‍ശിനി +GenericName[mr]=फॉन्ट प्रदर्शक +GenericName[ms]=Pemapar Fon +GenericName[nb]=Skriftviser +GenericName[nds]=Schriftoortkieker +GenericName[ne]=फन्ट दर्शक +GenericName[nl]=Lettertypeweergave +GenericName[nn]=Skriftvisar +GenericName[or]=ଅକ୍ଷରରୂପ ପ୍ରଦର୍ଶକ +GenericName[pa]=ਫੋਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka czcionek +GenericName[pt]=Visualizador do Tipo de Letra +GenericName[pt_BR]=Visualizador de fontes +GenericName[ro]=Vizualizator de fonturi +GenericName[ru]=Просмотр шрифтов +GenericName[se]=Fontačájeheaddji +GenericName[si]=අකුරු දසුන +GenericName[sk]=Prehliadač písiem +GenericName[sl]=Pregledovalnik pisav +GenericName[sr]=Приказивач фонтова +GenericName[sr@ijekavian]=Приказивач фонтова +GenericName[sr@ijekavianlatin]=Prikazivač fontova +GenericName[sr@latin]=Prikazivač fontova +GenericName[sv]=Teckensnittsvisning +GenericName[ta]=Font Viewer +GenericName[te]=ఫాంట్ వీక్షణి +GenericName[tg]=Намоишгари ҳарфҳо +GenericName[th]=ดูตัวอย่างแบบอักษร +GenericName[tr]=Yazı Tipi Görüntüleyici +GenericName[ug]=خەت نۇسخا كۆرگۈچ +GenericName[uk]=Переглядач шрифтів +GenericName[uz]=Shrift koʻruvchi +GenericName[uz@cyrillic]=Шрифт кўрувчи +GenericName[vi]=Trình xem phông chữ +GenericName[wa]=Håyneu d' fontes +GenericName[x-test]=xxFont Viewerxx +GenericName[zh_CN]=字体查看器 +GenericName[zh_TW]=字型檢視器 +Terminal=false +InitialPreference=1 +NoDisplay=true +Categories=Qt;KDE;Utility; +X-DBUS-StartupType=Unique +X-KDE-HasTempFileOption=true diff --git a/kcontrol/kfontinst/apps/kfontviewui.rc b/kcontrol/kfontinst/apps/kfontviewui.rc new file mode 100644 index 00000000..f2e4a86f --- /dev/null +++ b/kcontrol/kfontinst/apps/kfontviewui.rc @@ -0,0 +1,4 @@ + + + + diff --git a/kcontrol/kfontinst/apps/ox16-app-kfontview.png b/kcontrol/kfontinst/apps/ox16-app-kfontview.png new file mode 100644 index 0000000000000000000000000000000000000000..3691f9068b5e297632061a9f1772e1d3ed17b8d9 GIT binary patch literal 719 zcmV;=0xk@#$4V#1-U z(mz~FtarYD^OAV}kjc~Qx^n!O^Ewf|V;DAwdSa&sAPUz#G!Fy6MQK=}MPE)a1 zB%|4+XI0g`!C=rp0MFmwZ7#vm4w~v3)0W7oGkKBX$uAU*M(NeuJPFwXN$NUT6s11e z2j$;gB&i_cjY}JOTAEv+`N?roYW0%N?n^c@qJZ;Sr*igA@FTl5V^C)V1uN4^JSk02 zKc`qMR?unLPipCVk>fN^D+UY>Uc4%9u6*cj6ovK{Lxup~bWk)aKdTfZY6L-W(LN|f zM@MNFdq;cV?dum>zK(0_>asVq+FF0|hWfrpB+}sZdT)n9AD-0;{lW&cnjKKiEHo)LY4_&9fi;5 zdyHw$*lf1dy#YNH{>&gke$fs%{4uPv^e5nd_zgIR1@P-;wx0k1002ovPDHLkV1hS!s8V~3H!vQ}|Ps!Q4!#h5pFqfM9OP2N3+1b!Bgu=PtmJn!?q@Oi_R z_kAe<>Kg#?!v9ZDQ5w%$3xixje29XqAaO)QDu@TUi~wc}xs6bW39%wWh#i6Een`wC z2gv()#~3uTva(_ihaY?)ih0OvW#F%Pd@r@RISE84O2y$=Mg|f7&^7$6;`{-n)6H|L zhYufpR|n>!%uZe#i$<(QgAv?aCoAX9p7{wt3H0~(i-df*Dfgq}5h+gK{IJ!}z4;#_ zg89U|7FUl=RmlTgEr6QmVK-j{TIV>ZN!u@8q&Lrxj*iv{`4b%D=y*U@5ok&0=I-9q znd}~u%VRO?Szt8=P}L|91OYg;23S+4ZX;QBSgob`X7{apj1++ggVJAHOSxPQ>fb(P zY~Zn6Z-6A0ppZ=f!!STGJalMJD7KC+ZAQ#oASLKXz-v*Fi&~>GNDYCmp)`LWL#}uL z@puAOS6AWL#@|X+R`%-(oo9KWHak0e7LEx+E-cH?d#@DWqzZ5h4f$LVVzEDfrfD$S zI%MxaW2aP>vkXJIDT-p-7MCPRbh>KhicE9mO0^MT}4zAQssuGS0!vuyy;DM`gY0n@hl z#`WvdyV>Vy6BKseaqyJGtbGNoC=J=d?04;DQ)f&@Lu6uN!hW2Xo}8QnG7IsDwhH z&c}~`zLgjA!JX}GNTpIw5{dZvp`jsTcXxN9udmPHcDrk9YipkcgTeW>#Kar*366Ws z^*4N8eSjGm896;LFc9H+-s$yvm1HtGJ~lS?_2G{HLzb79n}2)1ty!?qJ_n)9LiLfZ{g_zBre05*@$c{0r$k%@^W* R(LDeF002ovPDHLkV1h!A>9_y@ literal 0 HcmV?d00001 diff --git a/kcontrol/kfontinst/apps/ox32-app-kfontview.png b/kcontrol/kfontinst/apps/ox32-app-kfontview.png new file mode 100644 index 0000000000000000000000000000000000000000..c3063f15b993f67c7e93963ee5d386d482b78894 GIT binary patch literal 1545 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 literal 0 HcmV?d00001 diff --git a/kcontrol/kfontinst/apps/oxsc-app-kfontview.svgz b/kcontrol/kfontinst/apps/oxsc-app-kfontview.svgz new file mode 100644 index 0000000000000000000000000000000000000000..6a6a4f8d6b2d9b69a23443cd52105366efe87a78 GIT binary patch literal 9292 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 header file. */ +#cmakedefine HAVE_LOCALE_H 1 + +#endif diff --git a/kcontrol/kfontinst/dbus/CMakeLists.txt b/kcontrol/kfontinst/dbus/CMakeLists.txt new file mode 100644 index 00000000..e983796b --- /dev/null +++ b/kcontrol/kfontinst/dbus/CMakeLists.txt @@ -0,0 +1,32 @@ +include_directories(${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcontrol/fonts) +add_definitions(${QT_DEFINITIONS}) + +set(fontinst_bin_SRCS FcConfig.cpp FontInst.cpp Folder.cpp Main.cpp Utils.cpp ${libkfontinstdbusiface_SRCS} ) +set(fontinst_helper_SRCS FcConfig.cpp Helper.cpp Folder.cpp Utils.cpp ${libkfontinstdbusiface_SRCS} ) + +# qt4_generate_dbus_interface(FontInst.h org.kde.fontinst.xml) +qt4_add_dbus_adaptor(fontinst_bin_SRCS org.kde.fontinst.xml FontInst.h KFI::FontInst) +# qt4_add_dbus_interface(fontinst_bin_SRCS org.kde.fontinst.xml FontinstIface) + +kde4_add_executable(fontinst_bin ${fontinst_bin_SRCS}) +kde4_add_executable(fontinst_helper ${fontinst_helper_SRCS}) + +set_target_properties(fontinst_bin PROPERTIES OUTPUT_NAME fontinst) +target_link_libraries(fontinst_bin ${KDE4_KDECORE_LIBS} + ${QT_QTDBUS_LIBRARY} ${QT_QTXML_LIBRARY} ${FONTCONFIG_LIBRARIES} kfontinst) + +set_target_properties(fontinst_helper PROPERTIES OUTPUT_NAME fontinst_helper) +target_link_libraries(fontinst_helper ${KDE4_KDECORE_LIBS} + ${QT_QTDBUS_LIBRARY} ${QT_QTXML_LIBRARY} ${FONTCONFIG_LIBRARIES} kfontinst) + +install(TARGETS fontinst_bin DESTINATION ${LIBEXEC_INSTALL_DIR} ) +install(TARGETS fontinst_helper DESTINATION ${LIBEXEC_INSTALL_DIR} ) +install(PROGRAMS fontinst_x11 DESTINATION ${LIBEXEC_INSTALL_DIR}) + +configure_file(org.kde.fontinst.service.cmake ${CMAKE_CURRENT_BINARY_DIR}/session/org.kde.fontinst.service) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/session/org.kde.fontinst.service DESTINATION ${DBUS_SERVICES_INSTALL_DIR} ) + +kde4_install_auth_helper_files(fontinst_helper org.kde.fontinst root) +kde4_install_auth_actions(org.kde.fontinst fontinst.actions) diff --git a/kcontrol/kfontinst/dbus/FcConfig.cpp b/kcontrol/kfontinst/dbus/FcConfig.cpp new file mode 100644 index 00000000..2213a5ef --- /dev/null +++ b/kcontrol/kfontinst/dbus/FcConfig.cpp @@ -0,0 +1,194 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2009 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 "FcConfig.h" +#include "Misc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KFI_DBUG kDebug() << time(0L) + +namespace KFI +{ + +namespace FcConfig +{ + +inline QString xDirSyntax(const QString &d) { return Misc::fileSyntax(d); } + +// +// Obtain location of config file to use. +// +// For system, prefer the following: +// +// <...>/config.d/00kde.conf = preferred method from FCConfig >= 2.3 +// <...>/local.conf +// +// Non-system, prefer: +// +// $HOME/<...>/.fonts.conf +// $HOME/<...>/fonts.conf +// +QString getConfigFile(bool system) +{ +#if (FC_VERSION>=20300) + static const char constKdeRootFcFile[] = "00kde.conf"; +#endif + + FcStrList *list=FcConfigGetConfigFiles(FcConfigGetCurrent()); + QStringList files; + FcChar8 *file; + QString home(Misc::dirSyntax(QDir::homePath())); + + while((file=FcStrListNext(list))) + { + QString f((const char *)file); + + if(Misc::fExists(f)) + { + // For nonsystem, only consider file within $HOME + if(system || 0==Misc::fileSyntax(f).indexOf(home)) + files.append(f); + } +#if (FC_VERSION>=20300) + if(system && Misc::dExists(f) && (f.contains(QRegExp("/conf\\.d/?$")) || + f.contains(QRegExp("/conf\\.d?$"))) ) + return Misc::dirSyntax(f)+constKdeRootFcFile; // This ones good enough for me! +#endif + } + + // + // Go through list of files, looking for the preferred one... + if(files.count()) + { + QStringList::const_iterator it(files.begin()), + end(files.end()); + + for(; it!=end; ++it) + if(-1!=(*it).indexOf(QRegExp(system ? "/local\\.conf$" : "/\\.?fonts\\.conf$"))) + return *it; + return files.front(); // Just return the 1st one... + } + else // Hmmm... no known files? + return system ? "/etc/fonts/local.conf" : Misc::fileSyntax(home+"/.fonts.conf"); +} + +void addDir(const QString &dir, bool system) +{ + QDomDocument doc("fontconfig"); + QString fileName=getConfigFile(system); + QFile f(fileName); + bool hasDir(false); + + KFI_DBUG << "Using fontconfig file:" << fileName; + + // Load existing file - and check to see whether it has the dir... + if(f.open(QIODevice::ReadOnly)) + { + doc.clear(); + + if(doc.setContent(&f)) + { + QDomNode n = doc.documentElement().firstChild(); + + while(!n.isNull() && !hasDir) + { + QDomElement e = n.toElement(); + + if(!e.isNull() && "dir"==e.tagName()) + if(0==Misc::expandHome(Misc::dirSyntax(e.text())).indexOf(dir)) + hasDir=true; + n=n.nextSibling(); + } + } + f.close(); + } + + // Add dir, and save, if config does not already have this dir. + if(!hasDir) + { + if(doc.documentElement().isNull()) + doc.appendChild(doc.createElement("fontconfig")); + + QDomElement newNode = doc.createElement("dir"); + QDomText text = doc.createTextNode(Misc::contractHome(xDirSyntax(dir))); + + newNode.appendChild(text); + doc.documentElement().appendChild(newNode); + + FcAtomic *atomic=FcAtomicCreate((const unsigned char *)(QFile::encodeName(fileName).data())); + + if(atomic) + { + if(FcAtomicLock(atomic)) + { + FILE *f=fopen((char *)FcAtomicNewFile(atomic), "w"); + + if(f) + { + // + // Check document syntax... + static const char qtXmlHeader[] = ""; + static const char xmlHeader[] = ""; + static const char qtDocTypeLine[] = ""; + static const char docTypeLine[] = ""; + + QString str(doc.toString()); + int idx; + + if(0!=str.indexOf(" + * + * ---- + * + * 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. + */ + +class QString; + +namespace KFI +{ + +namespace FcConfig +{ + void addDir(const QString &dir, bool system); +} + +} + +#endif diff --git a/kcontrol/kfontinst/dbus/Folder.cpp b/kcontrol/kfontinst/dbus/Folder.cpp new file mode 100644 index 00000000..328dfad0 --- /dev/null +++ b/kcontrol/kfontinst/dbus/Folder.cpp @@ -0,0 +1,417 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2009 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Folder.h" +#include "FcConfig.h" +#include "Misc.h" +#include "KfiConstants.h" +#include "XmlStrings.h" +#include "Style.h" +#include "File.h" +#include "config-fontinst.h" + +#define DISABLED_FONTS "disabledfonts" +#define KFI_DBUG kDebug() << time(0L) + +namespace KFI +{ + +bool Folder::CfgFile::modified() +{ + return timestamp!=Misc::getTimeStamp(name); +} + +void Folder::CfgFile::updateTimeStamp() +{ + timestamp=Misc::getTimeStamp(name); +} + +Folder::~Folder() +{ + saveDisabled(); +} + +void Folder::init(bool system, bool systemBus) +{ + itsIsSystem=system; + if(!system) + { + FcStrList *list=FcConfigGetFontDirs(FcInitLoadConfigAndFonts()); + QStringList dirs; + FcChar8 *fcDir; + + while((fcDir=FcStrListNext(list))) + dirs.append(Misc::dirSyntax((const char *)fcDir)); + + itsLocation=Misc::getFolder(Misc::dirSyntax(QDir::homePath()+"/.fonts/"), Misc::dirSyntax(QDir::homePath()), dirs); + } + else + itsLocation=KFI_DEFAULT_SYS_FONTS_FOLDER; + + if((!system && !systemBus) || (system && systemBus)) + FcConfig::addDir(itsLocation, system); + + itsDisabledCfg.dirty=false; + if(itsDisabledCfg.name.isEmpty()) + { + QString fileName("/"DISABLED_FONTS".xml"); + + if(system) + itsDisabledCfg.name=QString::fromLatin1(KFI_ROOT_CFG_DIR)+fileName; + else + { + QString path=KGlobal::dirs()->localxdgconfdir(); + + if(!Misc::dExists(path)) + Misc::createDir(path); + itsDisabledCfg.name=path+fileName; + } + itsDisabledCfg.timestamp=0; + } +} + +bool Folder::allowToggling() const +{ + return Misc::fExists(itsDisabledCfg.name) + ? Misc::fWritable(itsDisabledCfg.name) + : Misc::dWritable(Misc::getDir(itsDisabledCfg.name)); +} + +void Folder::loadDisabled() +{ + if(itsDisabledCfg.dirty) + saveDisabled(); + + QFile f(itsDisabledCfg.name); + + KFI_DBUG << itsDisabledCfg.name; + itsDisabledCfg.dirty=false; + if(f.open(QIODevice::ReadOnly)) + { + QDomDocument doc; + + if(doc.setContent(&f)) + for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling()) + { + QDomElement e=n.toElement(); + + if(FONT_TAG==e.tagName()) + { + Family fam(e, false); + + if(!fam.name().isEmpty()) + { + Style style(e, false); + + if(KFI_NO_STYLE_INFO!=style.value()) + { + QList files; + + if(e.hasAttribute(PATH_ATTR)) + { + File file(e, true); + + if(!file.path().isEmpty()) + files.append(file); + else + itsDisabledCfg.dirty=true; + } + else + { + for(QDomNode n=e.firstChild(); !n.isNull(); n=n.nextSibling()) + { + QDomElement ent=n.toElement(); + + if(FILE_TAG==ent.tagName()) + { + File file(ent, true); + + if(!file.path().isEmpty()) + files.append(file); + else + { + KFI_DBUG << "Set dirty from load"; + itsDisabledCfg.dirty=true; + } + } + } + } + + if(files.count()>0) + { + QList::ConstIterator it(files.begin()), + end(files.end()); + + FamilyCont::ConstIterator f(itsFonts.insert(fam)); + StyleCont::ConstIterator s((*f).add(style)); + + for(; it!=end; ++it) + (*s).add(*it); + } + } + } + } + } + + f.close(); + itsDisabledCfg.updateTimeStamp(); + } + + saveDisabled(); +} + +void Folder::saveDisabled() +{ + if(itsDisabledCfg.dirty) + { + if(!itsIsSystem || Misc::root()) + { + KFI_DBUG << itsDisabledCfg.name; + + KSaveFile file; + + file.setFileName(itsDisabledCfg.name); + + if(!file.open()) + { + KFI_DBUG << "Exit - cant open save file"; + qApp->exit(0); + } + + QTextStream str(&file); + + str << "<"DISABLED_FONTS">" << endl; + + FamilyCont::ConstIterator it(itsFonts.begin()), + end(itsFonts.end()); + + for(; it!=end; ++it) + (*it).toXml(true, str); + str << "" << endl; + str.flush(); + + if(!file.finalize()) + { + KFI_DBUG << "Exit - cant finalize save file"; + qApp->exit(0); + } + } + itsDisabledCfg.updateTimeStamp(); + itsDisabledCfg.dirty=false; + } +} + +QStringList Folder::toXml(int max) +{ + QStringList rv; + FamilyCont::ConstIterator it(itsFonts.begin()), + end(itsFonts.end()); + QString string; + QTextStream str(&string); + + for(int i=0; it!=end; ++it, ++i) + { + if(0==(i%max)) + { + if(i) + { + str << "" << endl; + rv.append(string); + string=QString(); + } + str << "<"FONTLIST_TAG" " << SYSTEM_ATTR"=\"" << (itsIsSystem ? "true" : "false") << "\">" << endl; + } + + (*it).toXml(false, str); + } + + if(!string.isEmpty()) + { + str << "" << endl; + rv.append(string); + } + return rv; +} + +Families Folder::list() +{ + Families fam(itsIsSystem); + FamilyCont::ConstIterator it(itsFonts.begin()), + end(itsFonts.end()); + + for(int i=0; it!=end; ++it, ++i) + fam.items.insert(*it); + + return fam; +} + +bool Folder::contains(const QString &family, quint32 style) +{ + FamilyCont::ConstIterator fam=itsFonts.find(Family(family)); + + if(fam==itsFonts.end()) + return false; + + StyleCont::ConstIterator st=(*fam).styles().find(Style(style)); + + return st!=(*fam).styles().end(); +} + +void Folder::add(const Family &family) +{ + FamilyCont::ConstIterator existingFamily=itsFonts.find(family); + + if(existingFamily==itsFonts.end()) + itsFonts.insert(family); + else + { + StyleCont::ConstIterator it(family.styles().begin()), + end(family.styles().end()); + + for(; it!=end; ++it) + { + StyleCont::ConstIterator existingStyle=(*existingFamily).styles().find(*it); + + if(existingStyle==(*existingFamily).styles().end()) + (*existingFamily).add(*it); + else + { + FileCont::ConstIterator fit((*it).files().begin()), + fend((*it).files().end()); + + for(; fit!=fend; ++fit) + { + FileCont::ConstIterator f=(*existingStyle).files().find(*fit); + + if(f==(*existingStyle).files().end()) + (*existingStyle).add(*fit); + } + + (*existingStyle).setWritingSystems((*existingStyle).writingSystems()|(*it).writingSystems()); + if(!(*existingStyle).scalable() && (*it).scalable()) + (*existingStyle).setScalable(true); + } + } + } +} + +void Folder::configure(bool force) +{ +KFI_DBUG << "EMPTY MODIFIED " << itsModifiedDirs.isEmpty(); + + if(force || !itsModifiedDirs.isEmpty()) + { + saveDisabled(); + + QSet::ConstIterator it(itsModifiedDirs.constBegin()), + end(itsModifiedDirs.constEnd()); + QSet dirs; + + for(; it!=end; ++it) + if(Misc::fExists((*it)+"fonts.dir")) + dirs.insert(KShell::quoteArg(*it)); + + if(!dirs.isEmpty()) + QProcess::startDetached(QLatin1String(KFONTINST_LIB_EXEC_DIR"/fontinst_x11"), dirs.toList()); + + itsModifiedDirs.clear(); + +KFI_DBUG << "RUN FC"; + Misc::doCmd("fc-cache"); +KFI_DBUG << "DONE"; + } +} + +Folder::Flat Folder::flatten() const +{ + FamilyCont::ConstIterator fam=itsFonts.begin(), + famEnd=itsFonts.end(); + Flat rv; + + for(; fam!=famEnd; ++fam) + { + StyleCont::ConstIterator style((*fam).styles().begin()), + styleEnd((*fam).styles().end()); + + for(; style!=styleEnd; ++style) + { + FileCont::ConstIterator file((*style).files().begin()), + fileEnd((*style).files().end()); + + for(; file!=fileEnd; ++file) + rv.insert(FlatFont(*fam, *style, *file)); + } + } + + return rv; +} + +Families Folder::Flat::build(bool system) const +{ + ConstIterator it(begin()), + e(end()); + Families families(system); + + for(; it!=e; ++it) + { + Family f((*it).family); + Style s((*it).styleInfo, (*it).scalable, (*it).writingSystems); + FamilyCont::ConstIterator fam=families.items.constFind(f); + + if(families.items.constEnd()==fam) + { + s.add((*it).file); + f.add(s); + families.items.insert(f); + } + else + { + StyleCont::ConstIterator st=(*fam).styles().constFind(s); + + if((*fam).styles().constEnd()==st) + { + s.add((*it).file); + (*fam).add(s); + } + else + (*st).add((*it).file); + } + } + + return families; +} + +} diff --git a/kcontrol/kfontinst/dbus/Folder.h b/kcontrol/kfontinst/dbus/Folder.h new file mode 100644 index 00000000..63725d16 --- /dev/null +++ b/kcontrol/kfontinst/dbus/Folder.h @@ -0,0 +1,114 @@ +#ifndef FOLDER_H +#define FOLDER_H + +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2009 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 +#include +#include +#include "Family.h" +#include "Style.h" +#include "File.h" +#include "Misc.h" + +namespace KFI +{ + +class Folder +{ + struct CfgFile + { + bool modified(); + void updateTimeStamp(); + + bool dirty; + QString name; + time_t timestamp; + }; + + public: + + struct FlatFont : Misc::TFont + { + FlatFont(const Family &fam, const Style &style, const File &f) + : Misc::TFont(fam.name(), style.value()), + writingSystems(style.writingSystems()), + scalable(style.scalable()), + file(f) + { + } + bool operator==(const FlatFont &o) const { return file.path()==o.file.path(); } + + qulonglong writingSystems; + bool scalable; + File file; + }; + + struct Flat : public QSet + { + Families build(bool system) const; + }; + + Folder() { } + ~Folder(); + + void init(bool system, bool systemBus); + const QString & location() const { return itsLocation; } + bool allowToggling() const; + void loadDisabled(); + void saveDisabled(); + void setDisabledDirty() { itsDisabledCfg.dirty=true; } + bool disabledDirty() const { return itsDisabledCfg.dirty; } + QStringList toXml(int max=0); + Families list(); + bool contains(const QString &family, quint32 style); + void add(const Family &family); + void addModifiedDir(const QString &dir) { itsModifiedDirs.insert(dir); } + void addModifiedDirs(const QSet &dirs) { itsModifiedDirs+=dirs; } + bool isModified() const { return !itsModifiedDirs.isEmpty(); } + void clearModified() { itsModifiedDirs.clear(); } + void configure(bool force=false); + Flat flatten() const; + const FamilyCont & fonts() const { return itsFonts; } + FamilyCont::ConstIterator addFont(const Family &fam) { return itsFonts.insert(fam); } + void removeFont(const Family &fam) { itsFonts.remove(fam); } + void clearFonts() { itsFonts.clear(); } + + private: + + bool itsIsSystem; + FamilyCont itsFonts; + CfgFile itsDisabledCfg; + QString itsLocation; + QSet itsModifiedDirs; +}; + +inline KDE_EXPORT uint qHash(const Folder::FlatFont &key) +{ + return qHash(key.file); // +qHash(key.index()); +} + +} + +#endif diff --git a/kcontrol/kfontinst/dbus/FontInst.cpp b/kcontrol/kfontinst/dbus/FontInst.cpp new file mode 100644 index 00000000..ef6c5b8d --- /dev/null +++ b/kcontrol/kfontinst/dbus/FontInst.cpp @@ -0,0 +1,971 @@ +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2009 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FontInst.h" +#include "fontinstadaptor.h" +#include "Misc.h" +#include "Fc.h" +#include "WritingSystems.h" +#include "Utils.h" +#include "FontinstIface.h" + +#define KFI_DBUG kDebug() << time(0L) + +namespace KFI +{ + +static void decompose(const QString &name, QString &family, QString &style) +{ + int commaPos=name.lastIndexOf(','); + + family=-1==commaPos ? name : name.left(commaPos); + style=-1==commaPos ? KFI_WEIGHT_REGULAR : name.mid(commaPos+2); +} + +static bool isSystem=false; +static Folder theFolders[FontInst::FOLDER_COUNT]; +static const int constSystemReconfigured=-1; +static const int constConnectionsTimeout = 30 * 1000; +static const int constFontListTimeout = 10 * 1000; + +typedef void (*SignalHandler)(int); + +static void registerSignalHandler(SignalHandler handler) +{ + if (!handler) + handler = SIG_DFL; + + sigset_t mask; + sigemptyset(&mask); + +#ifdef SIGSEGV + signal(SIGSEGV, handler); + sigaddset(&mask, SIGSEGV); +#endif +#ifdef SIGFPE + signal(SIGFPE, handler); + sigaddset(&mask, SIGFPE); +#endif +#ifdef SIGILL + signal(SIGILL, handler); + sigaddset(&mask, SIGILL); +#endif +#ifdef SIGABRT + signal(SIGABRT, handler); + sigaddset(&mask, SIGABRT); +#endif + + sigprocmask(SIG_UNBLOCK, &mask, 0); +} + +void signalHander(int) +{ + static bool inHandler=false; + + if(!inHandler) + { + inHandler=true; + theFolders[isSystem ? FontInst::FOLDER_SYS : FontInst::FOLDER_USER].saveDisabled(); + inHandler=false; + } +} + +FontInst::FontInst() +{ + isSystem=Misc::root(); + registerTypes(); + + new FontinstAdaptor(this); + QDBusConnection bus=QDBusConnection::sessionBus(); + + KFI_DBUG << "Connecting to session bus"; + if(!bus.registerService(OrgKdeFontinstInterface::staticInterfaceName())) + { + KFI_DBUG << "Failed to register service!"; + ::exit(-1); + } + if(!bus.registerObject(FONTINST_PATH, this)) + { + KFI_DBUG << "Failed to register object!"; + ::exit(-1); + } + + registerSignalHandler(signalHander); + itsConnectionsTimer=new QTimer(this); + itsFontListTimer=new QTimer(this); + connect(itsConnectionsTimer, SIGNAL(timeout()), SLOT(connectionsTimeout())); + connect(itsFontListTimer, SIGNAL(timeout()), SLOT(fontListTimeout())); + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); + + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + theFolders[i].init(FOLDER_SYS==i, isSystem); + + updateFontList(false); +} + +FontInst::~FontInst() +{ + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + theFolders[i].saveDisabled(); +} + +void FontInst::list(int folders, int pid) +{ + KFI_DBUG << folders << pid; + + itsConnections.insert(pid); + updateFontList(false); + QList fonts; + + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + if(0==folders || folders&(1<start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); + emit fontList(pid, fonts); +} + +void FontInst::stat(const QString &name, int folders, int pid) +{ + KFI_DBUG << name << folders << pid; + + bool checkSystem=0==folders || folders&SYS_MASK || isSystem, + checkUser=0==folders || (folders&USR_MASK && !isSystem); + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + + itsConnections.insert(pid); + if( (checkSystem && findFont(name, FOLDER_SYS, fam, st)) || + (checkUser && findFont(name, FOLDER_USER, fam, st, !checkSystem)) ) + { + Family rv((*fam).name()); + rv.add(*st); + KFI_DBUG << "Found font, emit details..."; + emit fontStat(pid, rv); + } + else + { + KFI_DBUG << "Font not found, emit empty details..."; + emit fontStat(pid, Family(name)); + } +} + +void FontInst::install(const QString &file, bool createAfm, bool toSystem, int pid, bool checkConfig) +{ + KFI_DBUG << file << createAfm << toSystem << pid << checkConfig; + + itsConnections.insert(pid); + + if(checkConfig) + updateFontList(); + + EFolder folder=isSystem || toSystem ? FOLDER_SYS : FOLDER_USER; + Family font; + Utils::EFileType type=Utils::check(file, font); + + int result=Utils::FILE_BITMAP==type && !FC::bitmapsEnabled() + ? STATUS_BITMAPS_DISABLED + : Utils::FILE_INVALID==type + ? STATUS_NOT_FONT_FILE + : STATUS_OK; + + if(STATUS_OK==result) + { + if(Utils::FILE_AFM!=type && Utils::FILE_PFM!=type) + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT) && STATUS_OK==result; ++i) + if(theFolders[i].contains(font.name(), (*font.styles().begin()).value())) + result=STATUS_ALREADY_INSTALLED; + + if(STATUS_OK==result) + { + QString name(Misc::modifyName(Misc::getFile(file))), + destFolder(Misc::getDestFolder(theFolders[folder].location(), name)); + + result=Utils::FILE_AFM!=type && Utils::FILE_PFM!=type && Misc::fExists(destFolder+name) ? (int)KIO::ERR_FILE_ALREADY_EXIST : (int)STATUS_OK; + if(STATUS_OK==result) + { + if(toSystem && !isSystem) + { + KFI_DBUG << "Send request to system helper" << file << destFolder << name; + QVariantMap args; + args["method"] = "install"; + args["file"] = file; + args["name"] = name; + args["destFolder"] = destFolder; + args["createAfm"] = createAfm; + args["type"] = (int)type; + result=performAction(args); + } + else + { + if(!Misc::dExists(destFolder)) + result=Misc::createDir(destFolder) ? (int)STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED; + + if(STATUS_OK==result) + result=QFile::copy(file, destFolder+name) ? (int)STATUS_OK : (int)KIO::ERR_WRITE_ACCESS_DENIED; + + if(STATUS_OK==result) + { + Misc::setFilePerms(QFile::encodeName(destFolder+name)); + if((Utils::FILE_SCALABLE==type || Utils::FILE_PFM==type) && createAfm) + Utils::createAfm(destFolder+name, type); + } + } + + if(STATUS_OK==result && Utils::FILE_AFM!=type && Utils::FILE_PFM!=type) + { + StyleCont::ConstIterator st(font.styles().begin()); + FileCont::ConstIterator f((*st).files().begin()); + File df(destFolder+name, (*f).foundry(), (*f).index()); + + (*st).clearFiles(); + (*st).add(df); + theFolders[folder].add(font); + theFolders[folder].addModifiedDir(destFolder); + emit fontsAdded(Families(font, FOLDER_SYS==folder)); + } + } + } + } + + emit status(pid, result); + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); +} + +void FontInst::uninstall(const QString &family, quint32 style, bool fromSystem, int pid, bool checkConfig) +{ + KFI_DBUG << family << style << fromSystem << pid << checkConfig; + + itsConnections.insert(pid); + + if(checkConfig) + updateFontList(); + + EFolder folder=isSystem || fromSystem ? FOLDER_SYS : FOLDER_USER; + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + int result=findFont(family, style, folder, fam, st) ? (int)STATUS_OK : (int)KIO::ERR_DOES_NOT_EXIST; + + if(STATUS_OK==result) + { + Family del((*fam).name()); + Style s((*st).value(), (*st).scalable(), (*st).writingSystems()); + FileCont files((*st).files()); + FileCont::ConstIterator it(files.begin()), + end(files.end()); + + if(fromSystem && !isSystem) + { + QStringList fileList; + bool wasDisabled(false); + + for(; it!=end; ++it) + { + fileList.append((*it).path()); + theFolders[FOLDER_SYS].addModifiedDir(Misc::getDir((*it).path())); + if(!wasDisabled && Misc::isHidden(Misc::getFile((*it).path()))) + wasDisabled=true; + } + QVariantMap args; + args["method"] = "uninstall"; + args["files"] = fileList; + result=performAction(args); + + if(STATUS_OK==result) + { + FileCont empty; + s.setFiles(files); + (*st).setFiles(empty); + if(wasDisabled) + theFolders[FOLDER_SYS].setDisabledDirty(); + } + } + else + { + for(; it!=end; ++it) + if(!Misc::fExists((*it).path()) || QFile::remove((*it).path())) + { + // Also remove any AFM or PFM files... + QStringList other; + Misc::getAssociatedFiles((*it).path(), other); + QStringList::ConstIterator oit(other.constBegin()), + oend(other.constEnd()); + for(; oit!=oend; ++oit) + QFile::remove(*oit); + + theFolders[folder].addModifiedDir(Misc::getDir((*it).path())); + (*st).remove(*it); + s.add(*it); + if(!theFolders[folder].disabledDirty() && Misc::isHidden(Misc::getFile((*it).path()))) + theFolders[folder].setDisabledDirty(); + } + } + + if(STATUS_OK==result) + { + if((*st).files().isEmpty()) + { + (*fam).remove(*st); + if((*fam).styles().isEmpty()) + theFolders[folder].removeFont(*fam); + } + else + result=STATUS_PARTIAL_DELETE; + del.add(s); + } + emit fontsRemoved(Families(del, FOLDER_SYS==folder)); + + } + KFI_DBUG << "status" << result; + emit status(pid, result); + + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); +} + +void FontInst::uninstall(const QString &name, bool fromSystem, int pid, bool checkConfig) +{ + KFI_DBUG << name << fromSystem << pid << checkConfig; + + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + if(findFont(name, fromSystem || isSystem ? FOLDER_SYS : FOLDER_USER, fam, st)) + uninstall((*fam).name(), (*st).value(), fromSystem, pid, checkConfig); + else + emit status(pid, KIO::ERR_DOES_NOT_EXIST); +} + +void FontInst::move(const QString &family, quint32 style, bool toSystem, int pid, bool checkConfig) +{ + KFI_DBUG << family << style << toSystem << pid << checkConfig; + + itsConnections.insert(pid); + if(checkConfig) + updateFontList(); + + if(isSystem) + emit status(pid, KIO::ERR_UNSUPPORTED_ACTION); + else + { + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + EFolder from=toSystem ? FOLDER_USER : FOLDER_SYS, + to=toSystem ? FOLDER_SYS : FOLDER_USER; + + if(findFont(family, style, from, fam, st)) + { + FileCont::ConstIterator it((*st).files().begin()), + end((*st).files().end()); + QStringList files; + + for(; it!=end; ++it) + { + files.append((*it).path()); + theFolders[from].addModifiedDir(Misc::getDir((*it).path())); + // Actual 'to' folder does not really matter, as we only want to call fc-cache + // ...actual folders only matter for xreating fonts.dir, etc, and we wont be doing this... + theFolders[to].addModifiedDir(theFolders[to].location()); + } + + QVariantMap args; + args["method"] = "move"; + args["files"] = files; + args["toSystem"] = toSystem; + args["dest"] = theFolders[to].location(); + args["uid"] = getuid(); + args["gid"] = getgid(); + int result=performAction(args); + + if(STATUS_OK==result) + updateFontList(); + emit status(pid, result); + } + else + { + KFI_DBUG << "does not exist"; + emit status(pid, KIO::ERR_DOES_NOT_EXIST); + } + } + + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); +} + +static bool renameFontFile(const QString &from, const QString &to, int uid=-1, int gid=-1) +{ + QByteArray src(QFile::encodeName(from)), + dest(QFile::encodeName(to)); + + if(KDE_rename(src.data(), dest.data())) + return false; + + Misc::setFilePerms(dest); + if(-1!=uid && -1!=gid) + ::chown(dest.data(), uid, gid); + return true; +} + +void FontInst::enable(const QString &family, quint32 style, bool inSystem, int pid, bool checkConfig) +{ + KFI_DBUG << family << style << inSystem << pid << checkConfig; + toggle(true, family, style, inSystem, pid, checkConfig); +} + +void FontInst::disable(const QString &family, quint32 style, bool inSystem, int pid, bool checkConfig) +{ + KFI_DBUG << family << style << inSystem << pid << checkConfig; + toggle(false, family, style, inSystem, pid, checkConfig); +} + +void FontInst::removeFile(const QString &family, quint32 style, const QString &file, bool fromSystem, int pid, + bool checkConfig) +{ + KFI_DBUG << family << style << file << fromSystem << pid << checkConfig; + + itsConnections.insert(pid); + + if(checkConfig) + updateFontList(); + + // First find the family/style + EFolder folder=isSystem || fromSystem ? FOLDER_SYS : FOLDER_USER; + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + int result=findFont(family, style, folder, fam, st) ? (int)STATUS_OK : (int)KIO::ERR_DOES_NOT_EXIST; + + if(STATUS_OK==result) + { + // Family/style found - now check that the requested file is *within* the same folder as one + // of the files linked to this font... + FileCont files((*st).files()); + FileCont::ConstIterator it(files.begin()), + end(files.end()); + QString dir(Misc::getDir(file)); + + result=KIO::ERR_DOES_NOT_EXIST; + for(; it!=end && STATUS_OK!=result; ++it) + if(Misc::getDir((*it).path())==dir) + result=STATUS_OK; + + if(STATUS_OK==result) + { + // OK, found folder - so can now proceed to delete the file... + if(fromSystem && !isSystem) + { + QVariantMap args; + args["method"] = "removeFile"; + args["file"] = file; + result=performAction(args); + } + else + { + result=Misc::fExists(file) + ? QFile::remove(file) + ? (int)STATUS_OK + : (int)KIO::ERR_WRITE_ACCESS_DENIED + : (int)KIO::ERR_DOES_NOT_EXIST; + } + + if(STATUS_OK==result) + theFolders[folder].addModifiedDir(dir); + } + } + + emit status(pid, result); +} + +void FontInst::reconfigure(int pid, bool force) +{ + KFI_DBUG << pid << force; + bool sysModified(theFolders[FOLDER_SYS].isModified()); + + saveDisabled(); + + KFI_DBUG << theFolders[FOLDER_USER].isModified() << sysModified; + if(!isSystem && (force || theFolders[FOLDER_USER].isModified())) + theFolders[FOLDER_USER].configure(force); + + if(sysModified) + { + if(isSystem) + { + theFolders[FOLDER_SYS].configure(); + } + else + { + QVariantMap args; + args["method"] = "reconfigure"; + performAction(args); + theFolders[FOLDER_SYS].clearModified(); + } + } + + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); + + updateFontList(); + emit status(pid, isSystem ? constSystemReconfigured : STATUS_OK); +} + +QString FontInst::folderName(bool sys) +{ + return theFolders[sys || isSystem ? FOLDER_SYS : FOLDER_USER].location(); +} + +void FontInst::saveDisabled() +{ + if(isSystem) + theFolders[FOLDER_SYS].saveDisabled(); + else + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + if(FOLDER_SYS==i && !isSystem) + { + if(theFolders[i].disabledDirty()) + { + QVariantMap args; + args["method"] = "saveDisabled"; + performAction(args); + theFolders[i].saveDisabled(); + } + } + else + theFolders[i].saveDisabled(); +} + +void FontInst::connectionsTimeout() +{ + bool canExit(true); + + KFI_DBUG << "exiting"; + checkConnections(); + + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + { + if(theFolders[i].disabledDirty()) + canExit=false; + theFolders[i].saveDisabled(); + } + + if(0==itsConnections.count()) + { + if(canExit) + qApp->exit(0); + else // Try again later... + itsConnectionsTimer->start(constConnectionsTimeout); + } +} + +void FontInst::fontListTimeout() +{ + updateFontList(true); + itsFontListTimer->start(constFontListTimeout); +} + +void FontInst::updateFontList(bool emitChanges) +{ + // For some reason just the "!FcConfigUptoDate(0)" check does not always work :-( + FcBool fcModified=!FcConfigUptoDate(0); + + if(fcModified || + theFolders[FOLDER_SYS].fonts().isEmpty() || + (!isSystem && theFolders[FOLDER_USER].fonts().isEmpty()) || + theFolders[FOLDER_SYS].disabledDirty() || + (!isSystem && theFolders[FOLDER_USER].disabledDirty())) + { + KFI_DBUG << "Need to refresh font lists"; + if(fcModified) + { + KFI_DBUG << "Re-init FC"; + if(!FcInitReinitialize()) + KFI_DBUG << "Re-init failed????"; + } + + Folder::Flat old[FOLDER_COUNT]; + + if(emitChanges) + { + KFI_DBUG << "Flatten existing font lists"; + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + old[i]=theFolders[i].flatten(); + } + + saveDisabled(); + + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + theFolders[i].clearFonts(); + + KFI_DBUG << "update list of fonts"; + + FcPattern *pat = FcPatternCreate(); + FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_FAMILY, FC_FAMILYLANG, + FC_WEIGHT, FC_LANG, FC_CHARSET, FC_SCALABLE, +#ifndef KFI_FC_NO_WIDTHS + FC_WIDTH, +#endif + FC_SLANT, FC_INDEX, FC_FOUNDRY, (void*)0); + + FcFontSet *list=FcFontList(0, pat, os); + + FcPatternDestroy(pat); + FcObjectSetDestroy(os); + + theFolders[FOLDER_SYS].loadDisabled(); + if(!isSystem) + theFolders[FOLDER_USER].loadDisabled(); + + if(list) + { + QString home(Misc::dirSyntax(QDir::homePath())); + + for (int i = 0; i < list->nfont; i++) + { + QString fileName(Misc::fileSyntax(FC::getFcString(list->fonts[i], FC_FILE))); + + if(!fileName.isEmpty() && Misc::fExists(fileName)) // && 0!=fileName.indexOf(constDefomaLocation)) + { + QString family, + foundry; + quint32 styleVal; + int index; + qulonglong writingSystems(WritingSystems::instance()->get(list->fonts[i])); + FcBool scalable=FcFalse; + + if(FcResultMatch!=FcPatternGetBool(list->fonts[i], FC_SCALABLE, 0, &scalable)) + scalable=FcFalse; + + FC::getDetails(list->fonts[i], family, styleVal, index, foundry); + FamilyCont::ConstIterator fam=theFolders[isSystem || 0!=fileName.indexOf(home) + ? FOLDER_SYS : FOLDER_USER].addFont(Family(family)); + StyleCont::ConstIterator style=(*fam).add(Style(styleVal)); + FileCont::ConstIterator file=(*style).add(File(fileName, foundry, index)); + + (*style).setWritingSystems((*style).writingSystems()|writingSystems); + if(scalable) + (*style).setScalable(); + } + } + + FcFontSetDestroy(list); + } + + if(emitChanges) + { + KFI_DBUG << "Look for differences"; + for(int i=0; i<(isSystem ? 1 : FOLDER_COUNT); ++i) + { + KFI_DBUG << "Flatten, and take copies..."; + Folder::Flat newList=theFolders[i].flatten(), + onlyNew=newList; + + KFI_DBUG << "Determine differences..."; + onlyNew.subtract(old[i]); + old[i].subtract(newList); + + KFI_DBUG << "Emit changes..."; + Families families=onlyNew.build(isSystem || i==FOLDER_SYS); + + if(!families.items.isEmpty()) + emit fontsAdded(families); + + families=old[i].build(isSystem || i==FOLDER_SYS); + if(!families.items.isEmpty()) + emit fontsRemoved(families); + } + } + KFI_DBUG << "updated list of fonts"; + } +} + +void FontInst::toggle(bool enable, const QString &family, quint32 style, bool inSystem, int pid, bool checkConfig) +{ + KFI_DBUG; + itsConnections.insert(pid); + + if(checkConfig) + updateFontList(); + + EFolder folder=isSystem || inSystem ? FOLDER_SYS : FOLDER_USER; + FamilyCont::ConstIterator fam; + StyleCont::ConstIterator st; + int result=findFont(family, style, folder, fam, st) ? (int)STATUS_OK : (int)KIO::ERR_DOES_NOT_EXIST; + + if(STATUS_OK==result) + { + FileCont files((*st).files()), + toggledFiles; + FileCont::ConstIterator it(files.begin()), + end(files.end()); + QHash movedFonts; + QHash movedAssoc; + QSet modifiedDirs; + + for(; it!=end && STATUS_OK==result; ++it) + { + QString to=Misc::getDir((*it).path())+ + QString(enable ? Misc::unhide(Misc::getFile((*it).path())) + : Misc::hide(Misc::getFile((*it).path()))); + if(to!=(*it).path()) + { + KFI_DBUG << "MOVE:" << (*it).path() << " to " << to; + // If the font is a system font, and we're not root, then just go through the actions here - so + // that we can build the list of changes that would happen... + if((inSystem && !isSystem) || renameFontFile((*it).path(), to)) + { + modifiedDirs.insert(Misc::getDir(enable ? to : (*it).path())); + toggledFiles.insert(File(to, (*it).foundry(), (*it).index())); + // Now try to move an associated AFM or PFM files... + QStringList assoc; + + movedFonts[*it]=to; + Misc::getAssociatedFiles((*it).path(), assoc); + + QStringList::ConstIterator ait(assoc.constBegin()), + aend(assoc.constEnd()); + + for(; ait!=aend && STATUS_OK==result; ++ait) + { + to=Misc::getDir(*ait)+ + QString(enable ? Misc::unhide(Misc::getFile(*ait)) + : Misc::hide(Misc::getFile(*ait))); + + if(to!=*ait) + { + if((inSystem && !isSystem) || renameFontFile(*ait, to)) + { + movedAssoc[*ait]=to; + } + else + { + result=KIO::ERR_WRITE_ACCESS_DENIED; + } + } + } + } + else + { + result=KIO::ERR_WRITE_ACCESS_DENIED; + } + } + } + + if(inSystem && !isSystem) + { + Family toggleFam((*fam).name()); + + toggleFam.add(*st); + QVariantMap args; + args["method"] = "toggle"; + QString xml; + QTextStream str(&xml); + toggleFam.toXml(false, str); + args["xml"] = xml; + args["enable"] = enable; + result=performAction(args); + } + + if(STATUS_OK==result) + { + Family addFam((*fam).name()), + delFam((*fam).name()); + Style addStyle((*st).value(), (*st).scalable(), (*st).writingSystems()), + delStyle((*st).value(), (*st).scalable(), (*st).writingSystems()); + + addStyle.setFiles(toggledFiles); + addFam.add(addStyle); + delStyle.setFiles(files); + delFam.add(delStyle); + (*st).setFiles(toggledFiles); + + theFolders[folder].addModifiedDirs(modifiedDirs); + emit fontsAdded(Families(addFam, FOLDER_SYS==folder)); + emit fontsRemoved(Families(delFam, FOLDER_SYS==folder)); + + theFolders[folder].setDisabledDirty(); + } + else // un-move fonts! + { + QHash::ConstIterator fit(movedFonts.constBegin()), + fend(movedFonts.constEnd()); + QHash::ConstIterator ait(movedAssoc.constBegin()), + aend(movedAssoc.constEnd()); + + for(; fit!=fend; ++fit) + renameFontFile(fit.value(), fit.key().path()); + for(; ait!=aend; ++ait) + renameFontFile(ait.value(), ait.key()); + } + } + emit status(pid, result); + + itsConnectionsTimer->start(constConnectionsTimeout); + itsFontListTimer->start(constFontListTimeout); +} + +void FontInst::addModifedSysFolders(const Family &family) +{ + StyleCont::ConstIterator style(family.styles().begin()), + styleEnd(family.styles().end()); + + for(; style!=styleEnd; ++style) + { + FileCont::ConstIterator file((*style).files().begin()), + fileEnd((*style).files().end()); + + for(; file!=fileEnd; ++file) + theFolders[FOLDER_SYS].addModifiedDir(Misc::getDir((*file).path())); + } +} + +void FontInst::checkConnections() +{ + KFI_DBUG; + QSet::ConstIterator it(itsConnections.begin()), + end(itsConnections.end()); + QSet remove; + + for(; it!=end; ++it) + if(0!=kill(*it, 0)) + remove.insert(*it); + itsConnections.subtract(remove); +} + +bool FontInst::findFontReal(const QString &family, const QString &style, EFolder folder, + FamilyCont::ConstIterator &fam, StyleCont::ConstIterator &st) +{ + KFI_DBUG; + Family f(family); + fam=theFolders[folder].fonts().find(f); + if(theFolders[folder].fonts().end()==fam) + return false; + + StyleCont::ConstIterator end((*fam).styles().end()); + for(st=(*fam).styles().begin(); st!=end; ++st) + if(FC::createStyleName((*st).value())==style) + return true; + + return false; +} + +bool FontInst::findFont(const QString &font, EFolder folder, + FamilyCont::ConstIterator &fam, StyleCont::ConstIterator &st, + bool updateList) +{ + KFI_DBUG; + QString family, + style; + + decompose(font, family, style); + + if(!findFontReal(family, style, folder, fam, st)) + { + if(updateList) + { + // Not found, so refresh font list and try again... + updateFontList(); + return findFontReal(family, style, folder, fam, st); + } + else + { + return false; + } + } + + return true; +} + +bool FontInst::findFontReal(const QString &family, quint32 style, EFolder folder, + FamilyCont::ConstIterator &fam, StyleCont::ConstIterator &st) +{ + KFI_DBUG; + fam=theFolders[folder].fonts().find(Family(family)); + + if(theFolders[folder].fonts().end()==fam) + return false; + else + { + st=(*fam).styles().find(style); + + return (*fam).styles().end()!=st; + } +} + +bool FontInst::findFont(const QString &family, quint32 style, EFolder folder, + FamilyCont::ConstIterator &fam, StyleCont::ConstIterator &st, + bool updateList) +{ + KFI_DBUG; + if(!findFontReal(family, style, folder, fam, st)) + { + if(updateList) + { + // Not found, so refresh font list and try again... + updateFontList(); + return findFontReal(family, style, folder, fam, st); + } + else + { + return false; + } + } + return true; +} + +int FontInst::performAction(const QVariantMap &args) +{ + KAuth::Action action("org.kde.fontinst.manage"); + + action.setHelperID("org.kde.fontinst"); + action.setArguments(args); + KFI_DBUG << "Call " << args["method"].toString() << " on helper"; + itsFontListTimer->stop(); + itsConnectionsTimer->stop(); + KAuth::ActionReply reply = action.execute(); + + switch(reply.type()) + { + case KAuth::ActionReply::KAuthError: + KFI_DBUG << "KAuth failed - error code:" << reply.errorCode(); + return KIO::ERR_COULD_NOT_AUTHENTICATE; + case KAuth::ActionReply::HelperError: + KFI_DBUG << "Helper failed - error code:" << reply.errorCode(); + return (int)reply.errorCode(); + } + + KFI_DBUG << "Success!"; + return STATUS_OK; +} + +} diff --git a/kcontrol/kfontinst/dbus/FontInst.h b/kcontrol/kfontinst/dbus/FontInst.h new file mode 100644 index 00000000..e53ee6aa --- /dev/null +++ b/kcontrol/kfontinst/dbus/FontInst.h @@ -0,0 +1,162 @@ +#ifndef FONTINST_H +#define FONTINST_H + +/* + * KFontInst - KDE Font Installer + * + * Copyright 2003-2009 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 +#include +#include +#include +#include +#include "Family.h" +#include "Folder.h" +#include "FontinstIface.h" +#include "kfontinst_export.h" + +#define FONTINST_PATH "/FontInst" + +class QTimer; + +namespace KFI +{ + +class KFONTINST_EXPORT FontInst : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.fontinst") + + public: + + enum EStatus + { + STATUS_OK=0, + STATUS_SERVICE_DIED = KJob::UserDefinedError+500, + STATUS_BITMAPS_DISABLED, + STATUS_ALREADY_INSTALLED, + STATUS_NOT_FONT_FILE, + STATUS_PARTIAL_DELETE, + STATUS_NO_SYS_CONNECTION + }; + + enum EFolder + { + FOLDER_SYS, + FOLDER_USER, + + FOLDER_COUNT + }; + + enum + { + SYS_MASK=0x01, + USR_MASK=0x02 + }; + + static void registerTypes() + { + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType" +#define START_BASIC "" +#define START_TABLE "" +#define INFO_ROW "" +#define END_TABLE "
    %1:%2
    " +#define END "" + +HWInfo::HWInfo(QObject *parent, const QVariantList &args) + : SM::Applet(parent, args), m_info(0), m_icon(0) +{ + resize(234 + 20 + 23, 135 + 20 + 25); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateHtml())); +} + +HWInfo::~HWInfo() +{ +} + +void HWInfo::init() +{ + KGlobal::locale()->insertCatalog("plasma_applet_system-monitor"); + setTitle(i18n("Hardware Info")); + setEngine(dataEngine("soliddevice")); + setSources(); + connectToEngine(); +} + +bool HWInfo::addVisualization(const QString& source) +{ + if (mode() != SM::Applet::Panel) { + if (!m_info) { + m_info = new Plasma::TextBrowser(this); + m_info->nativeWidget()->setHtml(QString(START + i18n("Getting hardware information...") + END)); + appendVisualization(source, m_info); + //m_info->nativeWidget()->document()->setTextWidth(contentsRect().width()); + //setPreferredItemHeight(m_info->nativeWidget()->document()->size().height()); + setPreferredItemHeight(135); + } + } else { + if (!m_icon) { + m_icon = new Plasma::IconWidget(KIcon(icon()), "", this); + appendVisualization(source, m_icon); + } + } + return true; +} + +void HWInfo::deleteVisualizations() +{ + SM::Applet::deleteVisualizations(); + m_icon = 0; + m_info = 0; +} + +void HWInfo::setSources() +{ + m_cpus = engine()->query("IS Processor")["IS Processor"].toStringList(); + foreach (const QString& id, m_cpus) { + appendSource(id); + } + m_networks = engine()->query("IS NetworkInterface")["IS NetworkInterface"].toStringList(); + foreach (const QString& id, m_networks) { + appendSource(id); + } + m_audios = engine()->query("IS AudioInterface")["IS AudioInterface"].toStringList(); + foreach (const QString& id, m_audios) { + appendSource(id); + } + // TODO: get this from soliddevice + Plasma::DataEngine* engine = dataEngine("executable"); + QString path = QString::fromLocal8Bit(qgetenv("PATH")) + + QString::fromLatin1(":/usr/sbin:/sbin/"); + QString exe = KStandardDirs::findExe( "lspci", path ); + if (exe.isEmpty()) { + kError() << "lspci not found in " << path << endl; + } else { + QString tmp = exe + " | grep VGA | sed 's/.*: //g'"; + engine->connectSource(tmp, this); + } +} + +void HWInfo::dataUpdated(const QString& source, + const Plasma::DataEngine::Data &data) +{ + if (m_audios.contains(source) && !m_audioNames.contains(data["Name"].toString()) && + !data["Name"].toString().isEmpty()) { + m_audioNames.append(data["Name"].toString()); + } else if (m_networks.contains(source) && !m_networkNames.contains(data["Product"].toString()) && + !data["Product"].toString().isEmpty()) { + m_networkNames.append(data["Product"].toString()); + } else if (m_cpus.contains(source) && !m_cpuNames.contains(data["Product"].toString()) && + !data["Product"].toString().isEmpty()) { + m_cpuNames.append(data["Product"].toString().trimmed()); + } else if (source.indexOf("VGA") > -1) { + m_gpu = data["stdout"].toString().trimmed(); + } + updateHtml(); +} + +void HWInfo::updateHtml() +{ + QString html; + foreach(const QString& cpu, m_cpuNames) { + html += QString(INFO_ROW).arg(i18n("CPU")).arg(cpu); + } + html += QString(INFO_ROW).arg(i18n("GPU")).arg(m_gpu); + foreach(const QString& audio, m_audioNames) { + html += QString(INFO_ROW).arg(i18n("Audio")).arg(audio); + } + foreach(const QString& network, m_networkNames) { + html += QString(INFO_ROW).arg(i18n("Network")).arg(network); + } + html += END_TABLE END; + if (m_info) { + Plasma::Theme* theme = Plasma::Theme::defaultTheme(); + html = QString(START START_TABLE) + .arg(theme->color(Plasma::Theme::TextColor).name()) + html; + m_info->nativeWidget()->setHtml(html); + } else if (m_icon) { + html = START_BASIC START_TABLE + html; + Plasma::ToolTipContent data(i18n("Hardware Info"), html); + Plasma::ToolTipManager::self()->setContent(m_icon, data); + } +} + +#include "hwinfo.moc" diff --git a/plasma/generic/applets/system-monitor/hwinfo.h b/plasma/generic/applets/system-monitor/hwinfo.h new file mode 100644 index 00000000..e9fa4821 --- /dev/null +++ b/plasma/generic/applets/system-monitor/hwinfo.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef HWINFO_HEADER +#define HWINFO_HEADER + +#include +#include + +namespace Plasma { + class TextBrowser; + class IconWidget; +} + +class HWInfo : public SM::Applet +{ + Q_OBJECT + public: + HWInfo(QObject *parent, const QVariantList &args); + ~HWInfo(); + + virtual void init(); + virtual bool addVisualization(const QString&); + + public slots: + void dataUpdated(const QString &name, + const Plasma::DataEngine::Data &data); + + private slots: + void updateHtml(); + + protected: + virtual void deleteVisualizations(); + + private: + void setSources(); + + Plasma::TextBrowser *m_info; + Plasma::IconWidget *m_icon; + QString m_gpu; + QStringList m_cpus; + QStringList m_cpuNames; + QStringList m_networks; + QStringList m_networkNames; + QStringList m_audios; + QStringList m_audioNames; +}; + +K_EXPORT_PLASMA_APPLET(sm_hwinfo, HWInfo) + +#endif diff --git a/plasma/generic/applets/system-monitor/monitorbutton.cpp b/plasma/generic/applets/system-monitor/monitorbutton.cpp new file mode 100644 index 00000000..ee5e5d87 --- /dev/null +++ b/plasma/generic/applets/system-monitor/monitorbutton.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "monitorbutton.h" + +#include +#include +#include + +#include +#include +#include + +#include + +#define MARGIN 2 + +class MonitorButton::Private +{ +public: + Private() : imageSize(32, 32) + { + } + + QSize imageSize; + QString image; + KIcon icon; + QTimeLine highlighter; +}; + +MonitorButton::MonitorButton(QGraphicsWidget *parent) : + Plasma::PushButton(parent), + d(new Private) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setPreferredSize(d->imageSize.width() + 2 * MARGIN, d->imageSize.height() + 2 * MARGIN); + + d->highlighter.setDuration(100); + d->highlighter.setFrameRange(0, 10); + d->highlighter.setCurveShape(QTimeLine::EaseInCurve); + connect(&d->highlighter, SIGNAL(valueChanged(qreal)), this, SLOT(highlight())); +} + +MonitorButton::~MonitorButton() +{ + delete d; +} + +QString MonitorButton::image() const +{ + return d->image; +} + +void MonitorButton::setImage(const QString &image) +{ + d->image = image; + d->icon = KIcon(image); + update(); +} + +void MonitorButton::highlight() +{ + update(); +} + +void MonitorButton::hoverEnterEvent(QGraphicsSceneHoverEvent * event) +{ + Q_UNUSED(event) + + d->highlighter.setDirection(QTimeLine::Forward); + if (d->highlighter.currentValue() < 1 && + d->highlighter.state() == QTimeLine::NotRunning) { + d->highlighter.start(); + } +} + +void MonitorButton::hoverLeaveEvent(QGraphicsSceneHoverEvent * event) +{ + Q_UNUSED(event) + + d->highlighter.setDirection(QTimeLine::Backward); + + if (d->highlighter.currentValue() > 0 && + d->highlighter.state() == QTimeLine::NotRunning) { + d->highlighter.start(); + } +} + +void MonitorButton::paint(QPainter *p, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + QIcon::Mode mode = QIcon::Disabled; + if (isChecked()) { + mode = QIcon::Normal; + } + + QPixmap icon = Plasma::PaintUtils::transition(d->icon.pixmap(d->imageSize, QIcon::Disabled), + d->icon.pixmap(d->imageSize, QIcon::Normal), + isChecked() ? 1 : d->highlighter.currentValue()); + p->drawPixmap(QPointF((size().width() - d->imageSize.width()) / 2, + (size().height() - d->imageSize.height()) / 2), + icon); +} + +#include "monitorbutton.moc" diff --git a/plasma/generic/applets/system-monitor/monitorbutton.h b/plasma/generic/applets/system-monitor/monitorbutton.h new file mode 100644 index 00000000..fba0fb90 --- /dev/null +++ b/plasma/generic/applets/system-monitor/monitorbutton.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MONITORBUTTON_HEADER +#define MONITORBUTTON_HEADER + +#include +#include "sm_export.h" + +class SM_EXPORT MonitorButton : public Plasma::PushButton +{ + Q_OBJECT + Q_PROPERTY(QString image READ image WRITE setImage) + +public: + explicit MonitorButton(QGraphicsWidget *parent = 0); + virtual ~MonitorButton(); + + QString image() const; + void setImage(const QString &image); + +protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent * event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent * event); + virtual void paint(QPainter *p, + const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + +private slots: + void highlight(); + +private: + class Private; + Private * const d; +}; + +#endif diff --git a/plasma/generic/applets/system-monitor/monitoricon.cpp b/plasma/generic/applets/system-monitor/monitoricon.cpp new file mode 100644 index 00000000..2d604efa --- /dev/null +++ b/plasma/generic/applets/system-monitor/monitoricon.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "monitoricon.h" +#include +#include +#include +#include + +#define MARGIN 5 + +class MonitorIcon::Private +{ + public: + Private() : imageSize(22, 22) { } + + QSizeF imageSize; + QString image; + QStringList overlays; +}; + +MonitorIcon::MonitorIcon(QGraphicsItem *parent) : + QGraphicsWidget(parent), + d(new Private) +{ + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setPreferredSize(d->imageSize.width() + 2 * MARGIN, d->imageSize.height() + 2 * MARGIN); +} + +MonitorIcon::~MonitorIcon() +{ + delete d; +} + +QString MonitorIcon::image() const +{ + return d->image; +} + +void MonitorIcon::setImage(const QString &image) +{ + d->image = image; + update(); +} + +QStringList MonitorIcon::overlays() const +{ + return d->overlays; +} + +void MonitorIcon::setOverlays( const QStringList & overlays ) +{ + d->overlays = overlays; + update(); +} + +void MonitorIcon::paint(QPainter *p, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + p->drawPixmap(QPointF((size().width() - d->imageSize.width()) / 2, + (size().height() - d->imageSize.height()) / 2), + KIcon(d->image, KIconLoader::global(), + d->overlays).pixmap(d->imageSize.toSize())); +} + +#include "monitoricon.moc" diff --git a/plasma/generic/applets/system-monitor/monitoricon.h b/plasma/generic/applets/system-monitor/monitoricon.h new file mode 100644 index 00000000..e94f5462 --- /dev/null +++ b/plasma/generic/applets/system-monitor/monitoricon.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MONITORICON_HEADER +#define MONITORICON_HEADER + +#include +#include "sm_export.h" + +class SM_EXPORT MonitorIcon : public QGraphicsWidget +{ + Q_OBJECT + Q_PROPERTY(QString image READ image WRITE setImage) + +public: + explicit MonitorIcon(QGraphicsItem *parent = 0); + virtual ~MonitorIcon(); + + QString image() const; + void setImage(const QString &image); + + QStringList overlays() const; + void setOverlays( const QStringList & overlays ); +protected: + virtual void paint(QPainter *p, + const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); +private: + class Private; + Private * const d; +}; + +#endif diff --git a/plasma/generic/applets/system-monitor/net-config.ui b/plasma/generic/applets/system-monitor/net-config.ui new file mode 100644 index 00000000..f3011b8e --- /dev/null +++ b/plasma/generic/applets/system-monitor/net-config.ui @@ -0,0 +1,93 @@ + + + config + + + + 0 + 0 + 382 + 263 + + + + + + + + 0 + + + + + &Network interfaces: + + + treeView + + + + + + + false + + + true + + + true + + + + + + + + + Update &interval: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + intervalSpinBox + + + + + + + 1 + + + 0.100000000000000 + + + 525600.000000000000000 + + + 2.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/plasma/generic/applets/system-monitor/net.cpp b/plasma/generic/applets/system-monitor/net.cpp new file mode 100644 index 00000000..99955f32 --- /dev/null +++ b/plasma/generic/applets/system-monitor/net.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "net.h" +#include +#include +#include +#include +#include + +SM::Net::Net(QObject *parent, const QVariantList &args) + : SM::Applet(parent, args) + , m_rx("^network/interfaces/(\\w+)/transmitter/data$") +{ + setHasConfigurationInterface(true); + resize(234 + 20 + 23, 135 + 20 + 25); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_sourceTimer.setSingleShot(true); + connect(&m_sourceTimer, SIGNAL(timeout()), this, SLOT(sourcesAdded())); +} + +SM::Net::~Net() +{ +} + +void SM::Net::init() +{ + KGlobal::locale()->insertCatalog("plasma_applet_system-monitor"); + setEngine(dataEngine("systemmonitor")); + setTitle(i18n("Network")); + + connect(engine(), SIGNAL(sourceAdded(QString)), this, SLOT(sourceAdded(QString))); + connect(engine(), SIGNAL(sourceRemoved(QString)), + this, SLOT(sourceRemoved(QString))); + foreach (const QString& source, engine()->sources()) { + sourceAdded(source); + } +} + +void SM::Net::configChanged() +{ + KConfigGroup cg = config(); + setInterval(cg.readEntry("interval", 2.0) * 1000); + setSources(cg.readEntry("interfaces", m_interfaces)); + connectToEngine(); +} + +void SM::Net::sourceAdded(const QString& name) +{ + if (m_rx.indexIn(name) != -1) { + //kDebug() << m_rx.cap(1); + if (m_rx.cap(1) != "lo") { + m_interfaces << name; + if (!m_sourceTimer.isActive()) { + m_sourceTimer.start(0); + } + } + } +} + +void SM::Net::sourcesAdded() +{ + configChanged(); +} + +void SM::Net::sourceRemoved(const QString& name) +{ + m_interfaces.removeAll(name); +} + +bool SM::Net::addVisualization(const QString& source) +{ + QStringList l = source.split('/'); + if (l.count() < 3) { + return false; + } + QString interface = l[2]; + SM::Plotter *plotter = new SM::Plotter(this); + plotter->setTitle(interface); + plotter->setUnit("KiB/s"); + plotter->setCustomPlots(QList() << QColor("#0099ff") << QColor("#91ff00")); + //plotter->setStackPlots(false); + appendVisualization(interface, plotter); + connectSource("network/interfaces/" + interface + "/receiver/data"); + setPreferredItemHeight(80); + return true; +} + +void SM::Net::dataUpdated(const QString& source, + const Plasma::DataEngine::Data &data) +{ + QStringList splitted = source.split('/'); + + if (splitted.length() < 4) { + return; + } + + QString interface = splitted[2]; + int index = (splitted[3] == "receiver") ? 0 : 1; + + if (!m_data.contains(interface)) { + m_data[interface] = QList() << -1 << -1; + } + + m_data[interface][index] = qMax(0.0, data["value"].toDouble()); + + if (!m_data[interface].contains(-1)) { + + SM::Plotter *plotter = qobject_cast(visualization(interface)); + if (plotter) { + plotter->addSample(m_data[interface]); + + if (mode() == SM::Applet::Panel) { + const double downstream = m_data[interface][0]; + const double upstream = m_data[interface][1]; + + + QString tooltip = QString::fromUtf8("%1
    ⇧   %2
    ⇩   %3
    "); + + setToolTip(interface, tooltip.arg(plotter->title()) + .arg(KGlobal::locale()->formatByteSize(upstream*1024)) + .arg(KGlobal::locale()->formatByteSize(downstream*1024))); + } + } + m_data[interface] = QList() << -1 << -1; + } +} + +void SM::Net::createConfigurationInterface(KConfigDialog *parent) +{ + QWidget *widget = new QWidget(); + ui.setupUi(widget); + m_model.clear(); + m_model.setHorizontalHeaderLabels(QStringList() << i18n("Network Interface")); + QStandardItem *parentItem = m_model.invisibleRootItem(); + + foreach (const QString& interface, m_interfaces) { + QString ifname = interface.split('/')[2]; + QStandardItem *item1 = new QStandardItem(ifname); + item1->setEditable(false); + item1->setCheckable(true); + item1->setData(interface); + if (sources().contains(interface)) { + item1->setCheckState(Qt::Checked); + } + parentItem->appendRow(QList() << item1); + } + ui.treeView->setModel(&m_model); + ui.treeView->resizeColumnToContents(0); + ui.intervalSpinBox->setValue(interval() / 1000.0); + ui.intervalSpinBox->setSuffix(i18nc("second", " s")); + parent->addPage(widget, i18n("Interfaces"), "network-workgroup"); + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + connect(ui.treeView, SIGNAL(clicked(QModelIndex)), parent, SLOT(settingsModified())); + connect(ui.intervalSpinBox, SIGNAL(valueChanged(QString)), parent, SLOT(settingsModified())); +} + +void SM::Net::configAccepted() +{ + KConfigGroup cg = config(); + QStandardItem *parentItem = m_model.invisibleRootItem(); + + clear(); + + for (int i = 0; i < parentItem->rowCount(); ++i) { + QStandardItem *item = parentItem->child(i, 0); + if (item) { + if (item->checkState() == Qt::Checked) { + appendSource(item->data().toString()); + } + } + } + cg.writeEntry("interfaces", sources()); + + double interval = ui.intervalSpinBox->value(); + cg.writeEntry("interval", interval); + + emit configNeedsSaving(); +} + +#include "net.moc" diff --git a/plasma/generic/applets/system-monitor/net.h b/plasma/generic/applets/system-monitor/net.h new file mode 100644 index 00000000..c3707310 --- /dev/null +++ b/plasma/generic/applets/system-monitor/net.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NET_HEADER +#define NET_HEADER + +#include +#include "applet.h" +#include +#include +#include +#include + +class QStandardItemModel; + +namespace SM { + +class Net : public Applet +{ + Q_OBJECT + public: + Net(QObject *parent, const QVariantList &args); + ~Net(); + + virtual void init(); + virtual bool addVisualization(const QString&); + virtual void createConfigurationInterface(KConfigDialog *parent); + + public slots: + void configAccepted(); + void configChanged(); + void dataUpdated(const QString &name, + const Plasma::DataEngine::Data &data); + void sourceAdded(const QString &name); + void sourcesAdded(); + void sourceRemoved(const QString &name); + + private: + Ui::config ui; + QStandardItemModel m_model; + QStringList m_interfaces; + QMap > m_data; + QTimer m_sourceTimer; + QRegExp m_rx; +}; +} + +K_EXPORT_PLASMA_APPLET(sm_net, SM::Net) + +#endif diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_cpu.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_cpu.desktop new file mode 100644 index 00000000..86588d91 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_cpu.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=CPU Monitor +Name[ar]=مراقب استعمال المعالج +Name[ast]=Monitor de CPU +Name[bg]=Наблюдение на процесора +Name[bs]=nadzor procesora +Name[ca]=Controlador de la CPU +Name[ca@valencia]=Controlador de la CPU +Name[cs]=Monitor CPU +Name[da]=CPU-overvågning +Name[de]=Überwachungsmonitor für Prozessoren +Name[el]=Επόπτης ΚΜΕ +Name[en_GB]=CPU Monitor +Name[es]=Monitor de CPU +Name[et]=Protsessori jälgija +Name[eu]=PUZaren monitorea +Name[fi]=Suoritinkäyttö +Name[fr]=Surveillance du processeur +Name[ga]=Monatóir an LAP +Name[gl]=Vixilante da CPU +Name[gu]=CPU મોનિટર +Name[he]=מוניטור המעבד +Name[hi]=सीपीयू नीरीक्षक +Name[hr]=Nadzornik CPU-a +Name[hu]=Processzorfigyelő +Name[ia]=Monitor de CPU +Name[id]=Monitor CPU +Name[is]=Eftirlit með notkun örgjörva +Name[it]=Monitor del processore +Name[ja]=CPU モニタ +Name[kk]=Процссорды бақылау +Name[km]=ត្រួតពិនិត្យ​ស៊ីភីយូ +Name[kn]=CPU ಮೇಲ್ವಿಚಾರಕ +Name[ko]=CPU 모니터 +Name[lt]=CPU apkrovos stebėtojas +Name[lv]=Procesora novērotājs +Name[mr]=CPU नियंत्रक +Name[nb]=prosessor-overvåker +Name[nds]=CPU-Kieker +Name[nl]=Monitor voor CPU-gebruik +Name[pa]=CPU ਨਿਗਰਾਨ +Name[pl]=Monitor procesora +Name[pt]=Monitor do CPU +Name[pt_BR]=Monitor da CPU +Name[ro]=Monitor de procesor +Name[ru]=Использование процессора +Name[si]=CPU මොනිටරය +Name[sk]=Monitor CPU +Name[sl]=Nadzornik procesorja +Name[sr]=надзор процесора +Name[sr@ijekavian]=надзор процесора +Name[sr@ijekavianlatin]=nadzor procesora +Name[sr@latin]=nadzor procesora +Name[sv]=Övervakning av processoranvändning +Name[tg]=Монитори CPU +Name[th]=ติดตามการใช้งานตัวประมวลผลกลาง +Name[tr]=İşlemci İzleyici +Name[ug]=CPU كۆزەتكۈچ +Name[uk]=Використання процесора +Name[vi]=Trình quản lý CPU +Name[wa]=Corwaitoe CPU +Name[x-test]=xxCPU Monitorxx +Name[zh_CN]=CPU 监视器 +Name[zh_TW]=CPU 監視器 +Comment=A CPU usage monitor +Comment[ar]=مراقب استعمال المعالج +Comment[ast]=Monitor d'usu de la CPU +Comment[be@latin]=Nazirańnik zaniataści „CPU” +Comment[bg]=Наблюдение натоварването на процесора +Comment[bs]=Nadgledanje upotrebe procesora +Comment[ca]=Un controlador d'ús de la CPU +Comment[ca@valencia]=Un controlador d'ús de la CPU +Comment[cs]=Monitor vytížení CPU +Comment[csb]=Mònitór brëkùnkù CPU +Comment[da]=Overvågning af CPU-forbrug +Comment[de]=Ein Überwachungsmonitor für Prozessoren +Comment[el]=Ένας επόπτης χρήσης ΚΜΕ +Comment[en_GB]=A CPU usage monitor +Comment[eo]=Monitoro de procezila uzo +Comment[es]=Monitor de uso de la CPU +Comment[et]=Protsessori kasutuse jälgija +Comment[eu]=PUZaren erabilera-monitorea +Comment[fi]=Näyttää suoritinten käytön +Comment[fr]=Une surveillance de l'usage du processeur +Comment[fy]=In CPU brûkme monitor +Comment[ga]=Monatóir úsáid an LAP +Comment[gl]=Un vixilante da utilización da CPU +Comment[gu]=CPU વપરાશ દેખરેખ +Comment[he]=מנטר שימוש במעבד +Comment[hi]=सीपीयू उपयो मॉनीटर +Comment[hne]=सीपीयू उपयोग देखइया +Comment[hr]=Nadzor korištenja procesora +Comment[hsb]=Monitor, kiž pokazuje wućeženosć procesora +Comment[hu]=Kijelzi a CPU állapotát +Comment[ia]=Un monitor del usage de CPU +Comment[id]=Monitor penggunaan CPU +Comment[is]=Eftirlit með notkun örgjörva +Comment[it]=Indica l'uso della CPU +Comment[ja]=CPU 使用率を監視します +Comment[kk]=Процессордың жүктелісін бақылау +Comment[km]=កម្មវិធី​ត្រួតពិនិត្យ​ការ​ប្រើប្រាស់​ស៊ីភីយូ +Comment[kn]=ಒಂದು CPU ಬಳಕೆಯ ಮೇಲ್ವಿಚಾರಕ +Comment[ko]=CPU 사용량 모니터 +Comment[lt]=CPU apkrovos stebėtojas +Comment[lv]=Procesora noslogojuma novērotājs +Comment[mk]=Монитор на користењето на процесорот +Comment[ml]=സിപിയു ഉപയോഗ നിരീക്ഷകന്‍ +Comment[mr]=CPU वापरणी नियंत्रक +Comment[nb]=En overvåker for prosessorbruk +Comment[nds]=En Kieker för den CPU-Bruuk +Comment[nl]=Volgt het CPU-gebruik +Comment[nn]=Overvaking av prosessorbruk +Comment[or]=ଗୋଟିଏ CPU ବ୍ୟବହାର ବିଧି ନିରିକ୍ଷକ +Comment[pa]=ਇੱਕ CPU ਵਰਤੋਂ ਮਾਨੀਟਰ +Comment[pl]=Monitor użycia procesora +Comment[pt]=Um monitor da utilização do CPU +Comment[pt_BR]=Um monitor de utilização da CPU +Comment[ro]=Monitor de utilizare a procesorului +Comment[ru]=Монитор использования процессора +Comment[si]=CPU භාවිතය නිරික්‍ෂකය +Comment[sk]=Monitor využitia CPU +Comment[sl]=Nadzornik obremenjenosti procesorja +Comment[sr]=Надгледање употребе процесора +Comment[sr@ijekavian]=Надгледање употребе процесора +Comment[sr@ijekavianlatin]=Nadgledanje upotrebe procesora +Comment[sr@latin]=Nadgledanje upotrebe procesora +Comment[sv]=Övervakning av processoranvändning +Comment[ta]=A CPU usage monitor +Comment[tg]=Монитори истифодабарии манбаъи система +Comment[th]=ตัวติดตามการใช้งานตัวประมวลผลกลาง +Comment[tr]=Bir işlemci kullanımı izleyici +Comment[ug]=CPU ئىشلىتىشنى كۆزەتكۈچ +Comment[uk]=Монітор використання процесора +Comment[wa]=On corwaitoe di l' eployaedje del CPU +Comment[x-test]=xxA CPU usage monitorxx +Comment[zh_CN]=CPU 利用率监视器 +Comment[zh_TW]=CPU 使用量監視器 +Type=Service +Icon=cpu +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_cpu +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_cpu +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd.desktop new file mode 100644 index 00000000..37d0de45 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd.desktop @@ -0,0 +1,111 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hard Disk Space Usage +Name[bs]=Iskorisenost Hard diska +Name[ca]=Ús d'espai de disc dur +Name[ca@valencia]=Ús d'espai de disc dur +Name[cs]=Využití místa na pevném disku +Name[da]=Brug af harddiskplads +Name[de]=Festplattenbelegung +Name[el]=Χρήση χώρου σκληρού δίσκου +Name[en_GB]=Hard Disk Space Usage +Name[es]=Espacio usado en el disco duro +Name[et]=Kõvaketta ruumikasutus +Name[eu]=Disko gogorreko lekuaren erabilera +Name[fi]=Kiintolevyjen tilankäyttö +Name[fr]=Utilisation de l'espace des disques dur +Name[gl]=Uso do espazo do disco duro +Name[he]=השימוש בדיסק +Name[hu]=Lemezterület használat +Name[ia]=Usage de spatio del disco dur +Name[it]=Spazio del disco fisso +Name[kk]=Қатқыл дискідегі пайдаланған орын +Name[km]=ការ​ប្រើ​ប្រាស់​ទំហំ​ថាសរឹង +Name[ko]=하드디스크 공간 사용량 +Name[lt]=Kietojo disko panaudojimas +Name[mr]=हार्ड डिस्क वापर +Name[nb]=Plassbruk for harddisk +Name[nds]=Fastplaat-Bruuk +Name[nl]=Ruimtegebruik van de harde schijf +Name[pa]=ਹਾਰਡ ਡਿਸਕ ਥਾਂ ਵਰਤੋਂ +Name[pl]=Wykorzystanie przestrzeni dysku twardego +Name[pt]=Utilização do Disco Rígido +Name[pt_BR]=Uso do espaço do disco rígido +Name[ro]=Utilizarea spațiului pe discul dur +Name[ru]=Использование места на диске +Name[sk]=Využitie miesta na pevnom disku +Name[sl]=Uporaba prostora na trdem disku +Name[sr]=заузеће хард диска +Name[sr@ijekavian]=заузеће хард диска +Name[sr@ijekavianlatin]=zauzeće hard diska +Name[sr@latin]=zauzeće hard diska +Name[sv]=Utrymmesanvändning för hårddisk +Name[tr]=Sabit Disk Alanı Kullanımı +Name[uk]=Використання місця на диску +Name[vi]=Sử dụng không gian đĩa +Name[x-test]=xxHard Disk Space Usagexx +Name[zh_CN]=硬盘空间使用 +Name[zh_TW]=硬碟空間使用量 +Comment=An applet that monitors hard disk space usage and percentage +Comment[bs]=Aplet koji prati hard korištenje prostora na disku i postotak +Comment[ca]=Una miniaplicació que controla l'ús d'espai del disc dur i el tant per cent +Comment[ca@valencia]=Una miniaplicació que controla l'ús d'espai del disc dur i el tant per cent +Comment[cs]=Aplet, jenž monitoruje zaplnění místa na disku +Comment[da]=En applet som overvåger brug af harddiskplads og procent ledig plads +Comment[de]=Ein Miniprogramm, das die Festplattenbelegung absolut und in Prozent überwacht +Comment[el]=Μικροεφαρμογή που εποπτεύει την ποσοτική και ποσοστιαία χρήση χώρου του σκληρού δίσκου +Comment[en_GB]=An applet that monitors hard disk space usage and percentage +Comment[es]=Una miniaplicación que monitoriza el uso y porcentaje del espacio en disco duro +Comment[et]=Kõvaketta ruumikasutust ja protsenti jälgiv aplett +Comment[eu]=Disko gogorreko lekuaren erabilera eta ehunekoa kontrolatzen dituen miniaplikazio bat +Comment[fi]=Sovelma, joka näyttää kiintolevyjen tilankäytön ja sen prosenttiosuuden +Comment[fr]=Une applet surveillant l'utilisation de l'espace des disques durs et donnant des pourcentages +Comment[gl]=Unha applet que vixía o espazo usado do disco duro e a porcentaxe +Comment[hu]=Egy kisalkalmazás, amely figyeli a merevlemez használatot és százalékot +Comment[ia]=Un applet que monitora usage e percentage de spatio de disco dur +Comment[it]=Un'applet che controlla l'uso dello spazio su disco fisso +Comment[kk]=Қатқыл дискідегі пайдаланған орын және пайызын бақылау аплеті +Comment[km]=អាប់ភ្លេត​ដែល​ត្រួតពិនិត្យ​​ការ​ប្រើប្រាស់​ និង​ភាគរយ​ទំហំ​ថាសរឹង +Comment[ko]=하드디스크 공간 사용량 및 비율을 보여 주는 애플릿 +Comment[lt]=Programėlė, kuri stebi disko vietos panaudojimą ir procentinį santykį +Comment[mr]=हार्ड डिस्क वापर व टक्केवारी दर्शविणारे एप्लेट +Comment[nb]=Et miniprogram som overvåker bruk av plass på harddisk, og prosentvis +Comment[nds]=En Lüttprogramm, dat den Fastplaat-Bruuk afsluuts un in Perzent beluert +Comment[nl]=Een applet die het ruimtegebruik van de harde schijf volgt +Comment[pa]=ਐਪਲਿਟ, ਜੋ ਕਿ ਹਾਰਡ ਡਿਸਕ ਵਲੋਂ ਵਰਤੀ ਥਾਂ ਅਤੇ ਫੀਸਦੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ +Comment[pl]=Aplet, który monitoruje wykorzystaną przestrzeń i procent wykorzystania dysku twardego +Comment[pt]=Uma 'applet' que vigia a utilização e percentagem do disco +Comment[pt_BR]=Monitora o uso do espaço do disco rígido e a porcentagem +Comment[ro]=Miniaplicație ce monitorizează gradul de utilizare a discului dur +Comment[ru]=Мониторинг используемого дискового пространства +Comment[sk]=Applet, ktorý monitoruje použitie miesta na pevnom disku a percentá +Comment[sl]=Aplet, ki nadzoruje uporabo prostora na trdem disku +Comment[sr]=Аплет за надгледање заузећа хард диска +Comment[sr@ijekavian]=Аплет за надгледање заузећа хард диска +Comment[sr@ijekavianlatin]=Aplet za nadgledanje zauzeća hard diska +Comment[sr@latin]=Aplet za nadgledanje zauzeća hard diska +Comment[sv]=Ett miniprogram som övervakar hårddiskutrymme och procent +Comment[tr]=Sabit disk kullanımını izleyen ve yüzde olarak gösteren bir programcık +Comment[uk]=Аплет, який стежить за використанням місця на диску +Comment[vi]=Một ứng dụng nhỏ quản lý phần trăm sử dụng không gian đĩa +Comment[x-test]=xxAn applet that monitors hard disk space usage and percentagexx +Comment[zh_CN]=监视硬盘空间使用率的小程序 +Comment[zh_TW]=監視硬碟空間使用量百分比的小程式 +Type=Service +Icon=drive-harddisk +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_hdd +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_hdd +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd_activity.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd_activity.desktop new file mode 100644 index 00000000..78f6ca06 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_hdd_activity.desktop @@ -0,0 +1,114 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hard Disk I/O Monitor +Name[bs]=Hard Disk I/O Monitor +Name[ca]=Controlador d'E/S de disc dur +Name[ca@valencia]=Controlador d'E/S de disc dur +Name[cs]=Monitor I/O pevného disku +Name[da]=Overvågning af harddisk-I/O +Name[de]=Überwachungsmonitor für Festplattenein- und ausgabe +Name[el]=Επόπτης χρήσης του σκληρού δίσκου +Name[en_GB]=Hard Disk I/O Monitor +Name[es]=Monitor de E/S del disco duro +Name[et]=Kõvaketta sisendi/väljundi jälgija +Name[eu]=Disko gogorreko S/I monitorea +Name[fi]=Kiintolevyjen käyttöilmaisin +Name[fr]=Une surveillance des entrées / sorties des disques durs +Name[ga]=Monatóir I/A Diosca Crua +Name[gl]=Vixilante da E/S do disco duro +Name[he]=מנטר שימוש בכונן הקשיח +Name[hu]=Merevlemez I/O monitor +Name[ia]=Monitor de I/E del disco dur +Name[it]=Uso del disco fisso +Name[kk]=Қатқыл дискінің Е/Ш бақылауы +Name[km]=ត្រួតពិនិត្យ I/O ថាសរឹង +Name[ko]=하드디스크 I/O 모니터 +Name[lt]=Kietojo disko I/O stebėtojas +Name[mr]=हार्ड डिस्क I/O नियंत्रक +Name[nb]=En overvåker for disk-I/U +Name[nds]=Fastplaat-I/O-Beluern +Name[nl]=Volgt de activiteit van de harde schijf +Name[pa]=ਹਾਰਡ ਡਿਸਕ I/O ਮਾਨੀਟਰ +Name[pl]=Monitor WE/WY dysku twardego +Name[pt]=Monitor de E/S do Disco +Name[pt_BR]=Monitor de E/S do disco rígido +Name[ro]=Monitor pentru utilizarea discului dur +Name[ru]=Монитор ввода-вывода жестких дисков +Name[sk]=Monitor I/O pevného disku +Name[sl]=Nadzornik V/I trdega diska +Name[sr]=Надгледање У/И‑ја хард‑диска +Name[sr@ijekavian]=Надгледање У/И‑ја хард‑диска +Name[sr@ijekavianlatin]=Nadgledanje U/I‑ja hard‑diska +Name[sr@latin]=Nadgledanje U/I‑ja hard‑diska +Name[sv]=Övervakning av in- och utmatning för hårddisk +Name[tr]=Sabit Disk G/Ç İzleyici +Name[uk]=Монітор роботи жорсткого диска +Name[vi]=Trình quản lý I/O đĩa cứng +Name[x-test]=xxHard Disk I/O Monitorxx +Name[zh_CN]=硬盘 I/O 监视器 +Name[zh_TW]=硬碟使用量 I/O 監視器 + +Comment=An applet that monitors hard disk throughput and input/output +Comment[bs]=Aplet koji prati hard disk protok ulaz / izlaz +Comment[ca]=Una miniaplicació que controla la velocitat de transferència de dades del disc dur i l'entrada/sortida +Comment[ca@valencia]=Una miniaplicació que controla la velocitat de transferència de dades del disc dur i l'entrada/eixida +Comment[cs]=Aplet, jenž monitoruje propustnost disku a vstup/výstup +Comment[da]=En applet som overvåger gennemgang og input/output for harddisken +Comment[de]=Ein Miniprogramm, das den Festplattendurchsatz und die Festplattenein- und -ausgabe überwacht +Comment[el]=Μικροεφαρμογή που εποπτεύει τη ρυθμοαπόδοση και την είσοδο/έξοδο του σκληρού δίσκου +Comment[en_GB]=An applet that monitors hard disk throughput and input/output +Comment[es]=Una miniaplicación que monitoriza el rendimiento y la entrada/salida del disco duro +Comment[et]=Kõvaketta läbilaset ja sisendit/väljundit jälgiv aplett +Comment[eu]=Disko gogorraren errendimendua eta sarrera/irteera kontrolatzen dituen miniaplikazio bat +Comment[fi]=Sovelma joka tarkkailee kiintolevyjen suoritustehoa ja siirtomäärää +Comment[fr]=Une applet surveillant l'activité des disques durs et de leurs entrées / sorties +Comment[gl]=Unha applet que vixía o rendemento e a entrada/saída +Comment[hu]=Egy kisalkalmazás, amely figyeli a merevlemez átvitelét és a bemenetet/kimenetet +Comment[ia]=Un applet que que monitora le prestation (throughput) e ingresso/egresso de disco dur +Comment[it]=Un'applet che controlla le prestazioni e l'uso del disco fisso +Comment[kk]=Дискінің белсендігі және енгізу/шығаруды бақылау апплеті +Comment[km]=អាប់ភ្លេត​ដែល​ត្រួតពិនិត្យ​ថាសរឹង​ និង​ឧបករណ៍​ចេញ/ចូល +Comment[ko]=하드디스크 대역폭 및 I/O 상태를 보여 주는 애플릿 +Comment[lt]=Programėlė, kuri stebi disko apkrovimą ir įvestį/išvestį +Comment[mr]=हार्ड डिस्क इनपुट व आउटपुट दर्शविणारे एप्लेट +Comment[nb]=Et miniprogram som overvåker dataflyt til og fra harddisk +Comment[nds]=En Lüttprogramm, dat den Fastplaat-Dörsatz un de In- un Utgaven beluert +Comment[nl]=Een applet die de activiteit van de harde schijf volgt +Comment[pa]=ਹਾਰਡ ਡਿਸਕ ਥਰੂਪੁੱਟ ਅਤੇ ਇੰਪੁੱਟ/ਆਉਟਪੁੱਟ ਦੀ ਨਿਗਰਾਨੀ ਲਈ ਐਪਲਿਟ +Comment[pl]=Aplet, który monitoruje przepustowość wejścia/wyjścia dysku twardego +Comment[pt]=Uma 'applet' que vigia o rendimento e o fluxo de entrada-saída do disco +Comment[pt_BR]=Monitora a taxa de transferência e entrada/saída do disco rígido +Comment[ro]=Miniaplicație ce monitorizează traficul de intrare și cel de ieșire pentru discul dur +Comment[ru]=Мониторинг пропускной способности и процессов ввода/вывода жестких дисков +Comment[sk]=Applet, ktorý monitoruje priepustnosť pevného disku a vstup/výstup +Comment[sl]=Aplet, ki nadzoruje prepustnost in vhod/izhod trdega diska +Comment[sr]=Аплет за надгледање пропусности и улаза/излаза хард‑диска +Comment[sr@ijekavian]=Аплет за надгледање пропусности и улаза/излаза хард‑диска +Comment[sr@ijekavianlatin]=Aplet za nadgledanje propusnosti i ulaza/izlaza hard‑diska +Comment[sr@latin]=Aplet za nadgledanje propusnosti i ulaza/izlaza hard‑diska +Comment[sv]=Ett miniprogram som övervakar hårddiskprestanda samt in- och utmatning +Comment[tr]=Sabit diski girdi/çıktı olarak izleyen bir programcık +Comment[uk]=Аплет, який стежить за даними, які записуються на жорсткий диск та читаються з жорсткого диска +Comment[vi]=Một ứng dụng nhỏ quản lý dữ liệu vào/ra trên đĩa cứng +Comment[x-test]=xxAn applet that monitors hard disk throughput and input/outputxx +Comment[zh_CN]=监视硬盘输入输出的小程序 +Comment[zh_TW]=監視硬碟效能與 I/O 的小程式 + +Type=Service +Icon=drive-harddisk +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_hdd_activity +X-KDE-PluginInfo-Author=Shaun Reich +X-KDE-PluginInfo-Email=shaun.reich@kdemail.net +X-KDE-PluginInfo-Name=sm_hdd_activity +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_hwinfo.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_hwinfo.desktop new file mode 100644 index 00000000..2010f2a4 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_hwinfo.desktop @@ -0,0 +1,158 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hardware Info +Name[ar]=معلومات العتاد +Name[ast]=Información del hardware +Name[bg]=Хардуерни данни +Name[bs]=podaci o hardveru +Name[ca]=Informació del maquinari +Name[ca@valencia]=Informació del maquinari +Name[cs]=Informace o hardware +Name[da]=Hardwareinfo +Name[de]=Hardwareinformationen +Name[el]=Πληροφορίες υλικού +Name[en_GB]=Hardware Info +Name[es]=Información del hardware +Name[et]=Riistvara teave +Name[eu]=Hardwareari buruzko informazioa +Name[fi]=Laitteistotiedot +Name[fr]=Informations sur le matériel +Name[ga]=Faisnéis Crua-Earraí +Name[gl]=Información do hardware +Name[gu]=હાર્ડવેર જાણકારી +Name[he]=מידע אודות חומרה +Name[hi]=हार्डवेयर जानकारी +Name[hr]=Informacije o hardveru +Name[hu]=Hardverjellemzők +Name[ia]=Info de hardware +Name[id]=Info Peranti Keras +Name[is]=Vélbúnaðarupplýsingar +Name[it]=Informazioni sull'hardware +Name[ja]=ハードウェア情報 +Name[kk]=Жабдық мәліметі +Name[km]=ព័ត៌មាន​ផ្នែក​រឹង +Name[kn]=ಯಂತ್ರಾಂಶ ಮಾಹಿತಿ +Name[ko]=하드웨어 정보 +Name[lt]=Aparatinės įrangos informacija +Name[lv]=Aparatūras informācija +Name[mr]=हार्डवेअर माहिती +Name[nb]=Maskinvareinformasjon +Name[nds]=Reedschap-Informatschonen +Name[nl]=Hardware-informatie +Name[pa]=ਹਾਰਡਵੇਅਰ ਜਾਣਕਾਰੀ +Name[pl]=Informacje o sprzęcie +Name[pt]=Informação do 'Hardware' +Name[pt_BR]=Informações do hardware +Name[ro]=Informații echipament +Name[ru]=Оборудование компьютера +Name[si]=දෘඩාංග තොරතුරු +Name[sk]=Informácie o hardvéri +Name[sl]=Podatki o strojni opremi +Name[sr]=подаци о хардверу +Name[sr@ijekavian]=подаци о хардверу +Name[sr@ijekavianlatin]=podaci o hardveru +Name[sr@latin]=podaci o hardveru +Name[sv]=Hårdvaruinformation +Name[tg]=Иттилооти сахтафзор +Name[th]=ข้อมูลของฮาร์ดแวร์ +Name[tr]=Donanım Bilgileri +Name[ug]=قاتتىق دېتال ئۇچۇرى +Name[uk]=Відомості про обладнання +Name[vi]=Thông tin phần cứng +Name[wa]=Info so l' éndjolreye +Name[x-test]=xxHardware Infoxx +Name[zh_CN]=硬件信息 +Name[zh_TW]=硬體資訊 +Comment=Show hardware info +Comment[ar]=يظهر معلومات العتاد +Comment[ast]=Amosar información d'hardware +Comment[be@latin]=Pakazvaje źviestki pra aparaturu +Comment[bg]=Показване на данни за хардуера +Comment[bn]=হার্ডওয়্যার তথ্য দেখাও +Comment[bs]=Podaci o hardveru +Comment[ca]=Mostra la informació del maquinari +Comment[ca@valencia]=Mostra la informació del maquinari +Comment[cs]=Zobrazit informace o hardwaru +Comment[csb]=Wëskrzëniô wëdowiédzã ò hardwôrze +Comment[da]=Vis hardwareinformation +Comment[de]=Zeigt Informationen zu bestimmten Geräten an. +Comment[el]=Εμφάνιση πληροφοριών υλικού +Comment[en_GB]=Show hardware info +Comment[eo]=Montri aparatajn informojn +Comment[es]=Mostrar información de hardware +Comment[et]=Riistvarainfo näitamine +Comment[eu]=Erakutsi hardwareari buruzko informazioa +Comment[fi]=Näyttää laitteistotiedot +Comment[fr]=Affiche des informations sur le matériel +Comment[fy]=Hardware ynfo sjen litte +Comment[ga]=Taispeáin eolas faoi na crua-earraí +Comment[gl]=Mostra información acerca do hardware +Comment[gu]=હાર્ડવેર માહિતી બતાવો +Comment[he]=משמש להצגת מידע אודות חומרה +Comment[hi]=हार्डवेयर जानकारी दिखाएँ +Comment[hne]=हार्डवेयर जानकारी देखाव +Comment[hr]=Prikaz informacija o hardveru +Comment[hsb]=Pokazuje informaciju wo hardware +Comment[hu]=Hardverjellemzők +Comment[ia]=Monstra info del hardware +Comment[id]=Tampilkan info peranti keras +Comment[is]=Sýna upplýsingar um vélbúnað +Comment[it]=Mostra informazioni sull'hardware +Comment[ja]=ハードウェアの情報を表示します +Comment[kk]=Жабдықтар мәліметін қарау +Comment[km]=បង្ហាញ​ព័ត៌មាន​ផ្នែក​រឹង +Comment[kn]=ಯಂತ್ರಾಂಶ ಮಾಹಿತಿಯನ್ನು ತೋರಿಸು +Comment[ko]=하드웨어 정보를 표시합니다 +Comment[lt]=Rodyti aparatinės įrangos informaciją +Comment[lv]=Rāda aparatūras informāciju +Comment[mk]=Прикажува информации за хардверот +Comment[ml]=ഹാര്‍ഡ്വെവര്‍ വിവരം കാണിക്കുക +Comment[mr]=हार्डवेअर माहिती दर्शवा +Comment[nb]=Vis maskinvareinformasjon +Comment[nds]=Hardware-Infos wiesen +Comment[nl]=Geeft informatie over uw hardware +Comment[nn]=Vis maskinvareinfo +Comment[or]=ହାର୍ଡ଼ୱେର ସୂଚନା ଦର୍ଶାନ୍ତୁ +Comment[pa]=ਹਾਰਡਵੇਅਰ ਜਾਣਕਾਰੀ ਵੇਖੋ +Comment[pl]=Pokazywanie informacji o sprzęcie +Comment[pt]=Mostrar informações sobre o 'hardware' +Comment[pt_BR]=Mostra informações do hardware +Comment[ro]=Afișează informații despre echipamentul fizic +Comment[ru]=Показ сведений об оборудовании +Comment[si]=දෘඩාංග තොරතුරු පෙන්වන්න +Comment[sk]=Zobrazenie informácií o hardvéri +Comment[sl]=Prikaz podatkov o strojni opremi +Comment[sr]=Подаци о хардверу +Comment[sr@ijekavian]=Подаци о хардверу +Comment[sr@ijekavianlatin]=Podaci o hardveru +Comment[sr@latin]=Podaci o hardveru +Comment[sv]=Visa hårdvaruinformation +Comment[ta]=Show hardware info +Comment[te]=హార్డువేర్ సమాచారమును చూపుము +Comment[tg]=Намоиши иттилооти сахтафзор +Comment[th]=แสดงข้อมูลของฮาร์ดแวร์ +Comment[tr]=Donanım bilgilerini göster +Comment[ug]=قاتتىق دېتال ئۇچۇرىنى كۆرسەت +Comment[uk]=Показати інформацію про обладнання +Comment[wa]=Mostrer les pondants et les djondants di l' éndjolreye +Comment[x-test]=xxShow hardware infoxx +Comment[zh_CN]=显示硬件信息 +Comment[zh_TW]=顯示硬體資訊 +Type=Service +Icon=hwinfo +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_hwinfo +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_hwinfo +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_net.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_net.desktop new file mode 100644 index 00000000..782ab2ad --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_net.desktop @@ -0,0 +1,157 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Network Monitor +Name[ar]=مراقب الشبكة +Name[ast]=Monitor de rede +Name[bg]=Наблюдение на мрежата +Name[bs]=nadzor mreže +Name[ca]=Controlador de la xarxa +Name[ca@valencia]=Controlador de la xarxa +Name[cs]=Monitor sítě +Name[da]=Netværksovervågning +Name[de]=Netzwerküberwachung +Name[el]=Επίβλεψη δικτύου +Name[en_GB]=Network Monitor +Name[es]=Monitor de red +Name[et]=Võrgujälgija +Name[eu]=Sareko monitorea +Name[fi]=Verkon käyttö +Name[fr]=Surveillance du réseau +Name[ga]=Monatóir an Líonra +Name[gl]=Vixilante da rede +Name[gu]=નેટવર્ક મોનિટર +Name[he]=מוניטור רשת +Name[hi]=नेटवर्क नरीक्षण +Name[hr]=Nadzornik mreže +Name[hu]=Hálózatfigyelő +Name[ia]=Monitor de Rete +Name[id]=Monitor Jaringan +Name[is]=Netkerfisvaktari +Name[it]=Monitor di rete +Name[ja]=ネットワークモニタ +Name[kk]=Желіні бақылау +Name[km]=ត្រួតពិនិត្យ​បណ្ដាញ +Name[kn]=ಜಾಲಬಂಧ ಮೇಲ್ವಿಚಾರಕ +Name[ko]=네트워크 모니터 +Name[lt]=Tinklo stebėjimo priemonė +Name[lv]=Tīkla monitors +Name[mr]=संजाळ नियंत्रक +Name[nb]=Nettverksovervåker +Name[nds]=Nettwark-Kieker +Name[nl]=Netwerkmonitor +Name[nn]=Nettverksovervaking +Name[pa]=ਨੈੱਟਵਰਕ ਨਿਗਰਾਨ +Name[pl]=Monitor sieci +Name[pt]=Monitor da Rede +Name[pt_BR]=Monitor da rede +Name[ro]=Monitor de rețea +Name[ru]=Сетевой монитор +Name[se]=Fierbmi +Name[si]=ජාල මොනිටරය +Name[sk]=Monitor siete +Name[sl]=Nadzornik omrežja +Name[sr]=надзор мреже +Name[sr@ijekavian]=надзор мреже +Name[sr@ijekavianlatin]=nadzor mreže +Name[sr@latin]=nadzor mreže +Name[sv]=Nätverksövervakning +Name[tg]=Монитори шабака +Name[th]=ติดตามการใช้งานเครือข่าย +Name[tr]=Ağ İzleyici +Name[ug]=تور كۆزەتكۈچ +Name[uk]=Монітор мережі +Name[wa]=Corwaitoe del rantoele +Name[x-test]=xxNetwork Monitorxx +Name[zh_CN]=网络监视器 +Name[zh_TW]=網路監控 +Comment=A network usage monitor +Comment[ar]=يراقب استعمال الشبكة +Comment[ast]=Monitor d'usu de la rede +Comment[be@latin]=Nazirańnik zaniataści sietki +Comment[bg]=Наблюдение на изпозлването на мрежата +Comment[bs]=Nadgledanje upotrebe mreže +Comment[ca]=Un controlador d'ús de la xarxa +Comment[ca@valencia]=Un controlador d'ús de la xarxa +Comment[cs]=Monitor využití sítě +Comment[csb]=Mònitór brëkòwaniô sécë +Comment[da]=Overvågning af netværkstrafik +Comment[de]=Ein Überwachungsmonitor für Netzwerke +Comment[el]=Ένας επόπτης χρήσης του δικτύου +Comment[en_GB]=A network usage monitor +Comment[es]=Monitor de uso de la red +Comment[et]=Võrgukasutuse jälgija +Comment[eu]=Sarearen erabileraren monitorea +Comment[fi]=Näyttää verkon käytön +Comment[fr]=Surveillance de l'usage réseau +Comment[fy]=In netwurk brûkme monitor +Comment[ga]=Monatóir úsáide an líonra +Comment[gl]=Un vixilante do estado da rede +Comment[gu]=નેટવર્ક સ્થિતિ દેખરેખ +Comment[he]=משמש לניטור השימוש ברשת +Comment[hi]=नेटवर्क उपयोग मॉनीटर +Comment[hne]=नेटवर्क उपयोग देखइया +Comment[hr]=Nadzor korištenja mreže +Comment[hsb]=Monitor, kiž pokazuje wućeženosć syće +Comment[hu]=Kijelzi a hálózat állapotát +Comment[ia]=Un monitor de usage de rete +Comment[id]=Monitor penggunaan jaringan +Comment[is]=Eftirlit með notkun netsins +Comment[it]=Indica l'uso della rete +Comment[ja]=ネットワークの活動を監視します +Comment[kk]=Желі пайдалануын бақылау +Comment[km]=កម្មវិធី​ត្រួតពិនិត្យ​ការ​ប្រើ​បណ្ដាញ +Comment[kn]=ಜಾಲಬಂಧ ಬಳಕೆಯ ಮೇಲ್ವಿಚಾರಕ +Comment[ko]=네트워크 사용량 모니터 +Comment[ku]=Temaşekerê rewşa torê +Comment[lt]=Tinklo naudojimo stebėtojas +Comment[lv]=Tīkla noslogojuma novērotājs +Comment[mk]=Монитор на користењето на мрежата +Comment[ml]= ശ്രംഖല ഉപയോഗം നിരീക്ഷകന്‍ +Comment[mr]=संजाळ वापरणी नियंत्रक +Comment[nb]=En overvåker for nettverksbruk +Comment[nds]=En Kieker för den Nettwark-Bruuk +Comment[nl]=Toont het netwerkgebruik +Comment[nn]=Overvaking av nettverksbruk +Comment[or]=ଗୋଟିଏ ନେଟୱର୍କ ବ୍ୟବହାର ବିଧି ନିରିକ୍ଷକ +Comment[pa]=ਇੱਕ ਨੈੱਟਵਰਕ ਵਰਤੋਂ ਮਾਨੀਟਰ +Comment[pl]=Monitor wykorzystania sieci +Comment[pt]=Um monitor da utilização da rede +Comment[pt_BR]=Um monitor de utilização da rede +Comment[ro]=Monitor de utilizare a rețelei +Comment[ru]=Монитор сетевой активности +Comment[si]=ජාල භාවිතය නිරික්‍ෂකය +Comment[sk]=Monitor využitia siete +Comment[sl]=Nadzornik uporabe omrežja +Comment[sr]=Надгледање употребе мреже +Comment[sr@ijekavian]=Надгледање употребе мреже +Comment[sr@ijekavianlatin]=Nadgledanje upotrebe mreže +Comment[sr@latin]=Nadgledanje upotrebe mreže +Comment[sv]=Övervakning av nätverksanvändning +Comment[ta]=பிணைய பயன்பாடு நோட்டம் +Comment[tg]=Состояние сервера Samba +Comment[th]=ตัวติดตามดูการใช้งานเครือข่าย +Comment[tr]=Bir ağ kullanımı izleyici +Comment[ug]=تور ئىشلىتىشنى كۆزەتكۈچ +Comment[uk]=Монітор використання мережі +Comment[wa]=On corwaitoe di l' eployaedje del rantoele +Comment[x-test]=xxA network usage monitorxx +Comment[zh_CN]=网络利用率监视器 +Comment[zh_TW]=網路使用量監視器 +Type=Service +Icon=network-workgroup +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_net +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_net +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_ram.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_ram.desktop new file mode 100644 index 00000000..b433cba8 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_ram.desktop @@ -0,0 +1,151 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Memory Status +Name[ar]=حالة الذاكرة +Name[ast]=Estáu de la memoria +Name[bg]=Състояние на паметта +Name[bs]=stanje memorije +Name[ca]=Estat de la memòria +Name[ca@valencia]=Estat de la memòria +Name[cs]=Stav paměti +Name[da]=Hukommelsesstatus +Name[de]=Speicherstatus +Name[el]=Κατάσταση μνήμης +Name[en_GB]=Memory Status +Name[es]=Estado de la memoria +Name[et]=Mälu olek +Name[eu]=Memoria-egoera +Name[fi]=Muistin käyttö +Name[fr]=État de la mémoire +Name[ga]=Stádas Cuimhne +Name[gl]=Estado da memoria +Name[gu]=મેમરી પરિસ્થિતિ +Name[he]=מצב הזיכרון +Name[hi]=मेमोरी स्थिति +Name[hr]=Stanje memorije +Name[hu]=Memóriaállapot +Name[ia]=Stato de memoria +Name[id]=Memori Status +Name[is]=Staða minnis +Name[it]=Stato della memoria +Name[ja]=メモリの状態 +Name[kk]=Жад күй-жайы +Name[km]=ស្ថានភាព​សតិ +Name[kn]=ಸ್ಮೃತಿ (ಮೆಮೊರಿ) ಸ್ಥಿತಿ +Name[ko]=메모리 상태 +Name[lt]=Atminties būsena +Name[lv]=Atmiņas statuss +Name[mr]=स्मृति स्थिति +Name[nb]=Minnestatus +Name[nds]=Spieker-Status +Name[nl]=Geheugen-status +Name[pa]=ਮੈਮੋਰੀ ਹਾਲਤ +Name[pl]=Stan pamięci +Name[pt]=Estado da Memória +Name[pt_BR]=Status da memória +Name[ro]=Stare memorie +Name[ru]=Использование памяти +Name[si]=මතක තත්ත්වය +Name[sk]=Stav pamäte +Name[sl]=Stanje pomnilnika +Name[sr]=стање меморије +Name[sr@ijekavian]=стање меморије +Name[sr@ijekavianlatin]=stanje memorije +Name[sr@latin]=stanje memorije +Name[sv]=Minnesstatus +Name[tg]=Ҳолати хотира +Name[th]=สถานะหน่วยความจำ +Name[tr]=Bellek Durumu +Name[ug]=ئەسلەك ھالىتى +Name[uk]=Стан пам’яті +Name[wa]=Estat del memwere +Name[x-test]=xxMemory Statusxx +Name[zh_CN]=内存状态 +Name[zh_TW]=記憶體狀態 +Comment=A RAM usage monitor +Comment[ar]=مراقب استعمال الذاكرة العشوائية +Comment[ast]=Monitor d'usu de la RAM +Comment[bg]=Изпозлване на оперативната памет (RAM) +Comment[bs]=Nadgledanje upotrebe RAM‑a +Comment[ca]=Un controlador d'ús de la RAM +Comment[ca@valencia]=Un controlador d'ús de la RAM +Comment[cs]=Monitor využití RAM +Comment[csb]=Mònitór brëkòwaniô pamiãcë RAM +Comment[da]=Overvågning af ram-forbrug +Comment[de]=Ein Überwachungsmonitor für den Arbeitsspeicher +Comment[el]=Ένας επόπτης χρήσης μνήμης RAM +Comment[en_GB]=A RAM usage monitor +Comment[eo]=RAM uzada rigardilo +Comment[es]=Monitor de uso de la RAM +Comment[et]=RAM-i kasutuse jälgija +Comment[eu]=RAMaen erabileraren monitorea +Comment[fi]=Näyttää muistin käytön +Comment[fr]=Une surveillance de l'usage de la mémoire vive +Comment[fy]=In RAM brûkme monitor +Comment[ga]=Monatóir úsáid RAM +Comment[gl]=Un vixilante do utilización da memoria RAM +Comment[gu]=રેમ વપરાશ દેખરેખ +Comment[he]=משמש לניטור השימוש בזיכרון ה־RAM +Comment[hi]=रेम उपयोग मॉनीटर +Comment[hr]=Nadzor korištenja RAM memorije +Comment[hu]=Memóriahasználat-figyelő +Comment[ia]=Un monitor del usage de RAM +Comment[id]=Monitor penggunaan RAM +Comment[is]=Eftirlit með notkun vinnsluminnis +Comment[it]=Indica l'uso della RAM +Comment[ja]=RAM 使用率を監視します +Comment[kk]=Жадыны пайдалануын бақылау +Comment[km]=កម្មវិធី​ត្រួតពិនិត្យ​ការ​ប្រើ​សតិ +Comment[kn]=RAM ಬಳಕೆಯ ಮೇಲ್ವಿಚಾರಕ +Comment[ko]=RAM 사용량 모니터 +Comment[lt]=RAM naudojimo stebėtojas +Comment[lv]=Atmiņas izmantotāja novērotājs +Comment[mai]=रैम उपयोग मानीटर +Comment[mk]=Монитор на користењето на меморијата +Comment[ml]=റാം ഉപയോഗ നിരീക്ഷകന്‍ +Comment[mr]=RAM वापरणी नियंत्रक +Comment[nb]=En overvåker for RAM-bruk +Comment[nds]=En Kieker för den RAM-Bruuk +Comment[nl]=Volgt het RAM-gebruik +Comment[nn]=Overvaking av minnebruk +Comment[pa]=ਇੱਕ RAM ਵਰਤੋਂ ਮਾਨੀਟਰ +Comment[pl]=Monitor wykorzystania pamięci RAM +Comment[pt]=Um monitor da utilização da RAM +Comment[pt_BR]=Um monitor de utilização da RAM +Comment[ro]=Monitor pentru utilizarea memoriei +Comment[ru]=Монитор использования оперативной памяти +Comment[si]=RAM භාවිතය නිරික්‍ෂකය +Comment[sk]=Monitor využitia RAM +Comment[sl]=Nadzornik porabe pomnilnika +Comment[sr]=Надгледање употребе РАМ‑а +Comment[sr@ijekavian]=Надгледање употребе РАМ‑а +Comment[sr@ijekavianlatin]=Nadgledanje upotrebe RAM‑a +Comment[sr@latin]=Nadgledanje upotrebe RAM‑a +Comment[sv]=Övervakning av minnesanvändning +Comment[tg]=Монитори истифодабарии манбаъи система +Comment[th]=ตัวติดตามการใช้งานหน่วยความจำ +Comment[tr]=Bir bellek kullanımı izleyici +Comment[ug]=RAM ئىشلىتىشنى كۆزەتكۈچ +Comment[uk]=Монітор використання пам’яті +Comment[wa]=On corwaitoe di l' eployaedje del RAM +Comment[x-test]=xxA RAM usage monitorxx +Comment[zh_CN]=RAM 利用率监视器 +Comment[zh_TW]=記憶體使用量監視器 +Type=Service +Icon=media-flash +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_ram +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_ram +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-sm_temperature.desktop b/plasma/generic/applets/system-monitor/plasma-applet-sm_temperature.desktop new file mode 100644 index 00000000..2179384c --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-sm_temperature.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Hardware Temperature +Name[ar]=حرارة العتاد +Name[ast]=Temperatura del hardware +Name[bg]=Температура на хардуера +Name[bs]=temperatura hardvera +Name[ca]=Temperatura del maquinari +Name[ca@valencia]=Temperatura del maquinari +Name[cs]=Teplota hardwaru +Name[da]=Hardwaretemperatur +Name[de]=Hardwaretemperatur +Name[el]=Θερμοκρασία Υλικού +Name[en_GB]=Hardware Temperature +Name[es]=Temperatura del hardware +Name[et]=Riistvara temperatuur +Name[eu]=Hardwarearen tenperatura +Name[fi]=Laitteiston lämpötilat +Name[fr]=Température du matériel +Name[ga]=Teocht na gCrua-Earraí +Name[gl]=Temperatura do hardware +Name[he]=טמפרטורת חומרה +Name[hi]=हार्डवेयर तापमान +Name[hr]=Temperatura hardvera +Name[hu]=Hardverhőmérséklet +Name[ia]=Temperatura Hardware +Name[id]=Temperatur Peranti Keras +Name[is]=Hitastig vélbúnaðar +Name[it]=Temperatura dell'hardware +Name[ja]=ハードウェアの温度 +Name[kk]=Жабдықтың температурасы +Name[km]=សីតុណ្ហភាព​ផ្នែក​រឹង +Name[kn]=ಯಂತ್ರಾಂಶ ತಾಪಮಾನ +Name[ko]=하드웨어 온도 +Name[lt]=Techninės įrangos temperatūra +Name[lv]=Aparatūras temperatūra +Name[mr]=हार्डवेअर तापमान +Name[nb]=Maskintemperatur +Name[nds]=Reedschap-Temperatuur +Name[nl]=Hardware temperatuur +Name[pa]=ਹਾਰਡਵੇਅਰ ਤਾਪਮਾਨ +Name[pl]=Temperatura sprzętu +Name[pt]=Temperatura do 'Hardware' +Name[pt_BR]=Temperatura do hardware +Name[ro]=Temperatură echipament +Name[ru]=Температурные датчики +Name[si]=දෘඩාංග උෂ්ණත්වය +Name[sk]=Teplota hardvéru +Name[sl]=Temperatura strojne opreme +Name[sr]=температура хардвера +Name[sr@ijekavian]=температура хардвера +Name[sr@ijekavianlatin]=temperatura hardvera +Name[sr@latin]=temperatura hardvera +Name[sv]=Hårdvarutemperatur +Name[tg]=Ҳарорати сахтафзор +Name[th]=อุณหภูมิของฮาร์ดแวร์ +Name[tr]=Donanım Sıcaklığı +Name[ug]=قاتتىق دېتال تېمپېراتۇرىسى +Name[uk]=Температура обладнання +Name[vi]=Nhiệt độ phần cứng +Name[wa]=Tchåleur di l' éndjolreye +Name[x-test]=xxHardware Temperaturexx +Name[zh_CN]=硬件温度计 +Name[zh_TW]=硬體溫度 +Comment=A system temperature monitor +Comment[ar]=يراقب حرارة النظام +Comment[ast]=Monitor de la temperatura del sistema +Comment[be@latin]=Nazirańnik za temperaturaju systemy +Comment[bg]=Наблюдение на температурата на компютъра +Comment[bs]=Nadgledanje temperature sistema +Comment[ca]=Un controlador de la temperatura del sistema +Comment[ca@valencia]=Un controlador de la temperatura del sistema +Comment[cs]=Monitor teploty systému +Comment[csb]=Mònitór temperaturë systemë +Comment[da]=Overvågning af systemtemperatur +Comment[de]=Ein Überwachungsmonitor für Temperatursensoren +Comment[el]=Ένας επόπτης θερμοκρασίας του συστήματος +Comment[en_GB]=A system temperature monitor +Comment[eo]=Systema temperatura rigardilo +Comment[es]=Monitor de la temperatura del sistema +Comment[et]=Süsteemi temperatuuri jälgija +Comment[eu]=Sistemaren tenperaturaren monitorea +Comment[fi]=Näyttää järjestelmän lämpötilat +Comment[fr]=Une surveillance de la température du système +Comment[fy]=In systeemtempratuer monitor +Comment[ga]=Monatóir theocht an chórais +Comment[gl]=Un vixilante da temperatura do sistema +Comment[gu]=સિસ્ટમ તાપમાન દેખરેખ +Comment[he]=משמש לניטור טמפרטורת המערכת +Comment[hi]=तंत्र तापक्रम मॉनीटर +Comment[hne]=तंत्र तापमान देखइया +Comment[hr]=Nadzor temperature sustava +Comment[hsb]=Monitor za systemowu temparaturu +Comment[hu]=Kijelzi a rendszer jellemző hőmérsékleteit +Comment[ia]=Un monitor de temperatura de systema +Comment[id]=Monitor temperatur sistem +Comment[is]=Eftirlit með hitastigi í kerfinu +Comment[it]=Indica la temperatura del sistema +Comment[ja]=システムの温度を監視します +Comment[kk]=Жүйек температурасын бақылау +Comment[km]=កម្មវិធី​ត្រួតពិនិត្យ​សីតុណ្ហភាព​របស់​ប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥೆಯ ಉಷ್ಣತೆಯ ಮೇಲ್ವಿಚಾರಕ +Comment[ko]=시스템 온도 모니터 +Comment[lt]=Sistemos temperatūros stebėtojas +Comment[lv]=Sistēmas temperatūras novērotājs +Comment[mk]=Монитор на температурата на системот +Comment[ml]=സിസ്റ്റം താപനില നിരീക്ഷകന്‍ +Comment[mr]=प्रणाली तापमान नियंत्रक +Comment[nb]=En overvåker for systemtemperaturen +Comment[nds]=En Wachter för de Systeemtemperatuur +Comment[nl]=Volgt de systeemtemperatuur +Comment[nn]=Overvaking av systemtemperaturen +Comment[or]=ତନ୍ତ୍ର ଉତ୍ତାପ ନିରିକ୍ଷକ +Comment[pa]=ਇੱਕ ਸਿਸਟਮ ਤਾਪਮਾਨ ਮਾਨੀਟਰ +Comment[pl]=Monitor temperatury komputera +Comment[pt]=Um monitor da temperatura do sistema +Comment[pt_BR]=Um monitor da temperatura do sistema +Comment[ro]=Monitor de temperatură a sistemului +Comment[ru]=Монитор температуры разных узлов компьютера +Comment[si]=පද්ධති උෂ්ණත්ව නිරික්‍ෂකය +Comment[sk]=Monitor teploty systému +Comment[sl]=Nadzornik temperature v sistemu +Comment[sr]=Надгледање температуре система +Comment[sr@ijekavian]=Надгледање температуре система +Comment[sr@ijekavianlatin]=Nadgledanje temperature sistema +Comment[sr@latin]=Nadgledanje temperature sistema +Comment[sv]=Övervakning av systemtemperatur +Comment[ta]=A system temperature monitor +Comment[tg]=Системный монитор KDE +Comment[th]=ตัวติดตามสถานะของอุณหภูมิ +Comment[tr]=Bir sistem sıcaklığı izleyici +Comment[ug]=سىستېما تېمپېراتۇرىسىنى كۆزەتكۈچ +Comment[uk]=Монітор системної температури +Comment[vi]=Một trình quản lý nhiệt độ hệ thống +Comment[wa]=On corwaitoe del tchåleur do sistinme +Comment[x-test]=xxA system temperature monitorxx +Comment[zh_CN]=系统温度监视器 +Comment[zh_TW]=系統溫度監視器 +Type=Service +Icon=view-statistics +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_sm_temperature +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=sm_temperature +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plasma-applet-system-monitor.desktop b/plasma/generic/applets/system-monitor/plasma-applet-system-monitor.desktop new file mode 100644 index 00000000..81c394df --- /dev/null +++ b/plasma/generic/applets/system-monitor/plasma-applet-system-monitor.desktop @@ -0,0 +1,178 @@ +[Desktop Entry] +Name=System Monitor +Name[af]=Stelsel Monitor +Name[ar]=مراقب النظام +Name[ast]=Monitor del sistema +Name[be]=Сістэмны назіральнік +Name[be@latin]=Systemny nazirańnik +Name[bg]=Наблюдение на системата +Name[bn]=সিস্টেম মনিটর +Name[bn_IN]=সিস্টেম নিরীক্ষণ ব্যবস্থা +Name[bs]=Monitor sistema +Name[ca]=Monitor del sistema +Name[ca@valencia]=Monitor del sistema +Name[cs]=Monitor systému +Name[csb]=Mònitór systemë +Name[da]=Systemovervågning +Name[de]=Systemmonitor +Name[el]=Επόπτης συστήματος +Name[en_GB]=System Monitor +Name[eo]=Sistemstato-programo +Name[es]=Monitor del sistema +Name[et]=Süsteemi jälgija +Name[eu]=Sistema-monitorea +Name[fa]=نمایشگر سیستم +Name[fi]=Järjestelmän valvonta +Name[fr]=Surveillance du système +Name[fy]=Systeemmonitor +Name[ga]=Monatóir an Chórais +Name[gl]=Vixilante do sistema +Name[gu]=સિસ્ટમ દેખરેખ +Name[he]=מוניטור המערכת +Name[hi]=तंत्र मॉनीटर +Name[hne]=तंत्र मानीटर +Name[hr]=Nadzor sustava +Name[hsb]=Systemowy monitor +Name[hu]=Rendszermonitor +Name[ia]=Monitor de systema +Name[id]=Monitor Sistem +Name[is]=Kerfiseftirlit +Name[it]=Monitor di sistema +Name[ja]=システムモニタ +Name[kk]=Жүйе мониторы +Name[km]=កម្មវិធី​ត្រួត​​ពិនិត្យ​ប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥೆಯ ಪ್ರದರ್ಶಕ +Name[ko]=시스템 모니터 +Name[ku]=Temaşekerê Pergalê +Name[lt]=Sistemos stebėtojas +Name[lv]=Sistēmas monitors +Name[mai]=सिस्टम मानीटर +Name[mk]=Системски монитор +Name[ml]=സിസ്റ്റം നിരീക്ഷകന്‍ +Name[mr]=प्रणाली मॉनिटर +Name[nb]=Systemovervåker +Name[nds]=Systeemkieker +Name[ne]=प्रणाली मनिटर +Name[nl]=Systeemmonitor +Name[nn]=Systemovervaking +Name[oc]=Monitor sistèma +Name[pa]=ਸਿਸਟਮ ਮਾਨੀਟਰ +Name[pl]=Monitor systemu +Name[pt]=Monitor do Sistema +Name[pt_BR]=Monitor do sistema +Name[ro]=Monitor de sistem +Name[ru]=Системный монитор +Name[se]=Vuogádatgoziheaddji +Name[si]=පද්ධති නිරීක්‍ෂකය +Name[sk]=Monitor systému +Name[sl]=Sistemski nadzornik +Name[sr]=надзорник система +Name[sr@ijekavian]=надзорник система +Name[sr@ijekavianlatin]=nadzornik sistema +Name[sr@latin]=nadzornik sistema +Name[sv]=Systemövervakare +Name[ta]=கணினி நோட்டம் +Name[te]=సిస్టమ్ మానిటర్ +Name[tg]=Назорати система +Name[th]=ติดตามการทำงานของระบบ +Name[tr]=Sistem İzleyici +Name[ug]=سىستېما كۆزەتكۈچ +Name[uk]=Монітор системи +Name[vi]=Bộ theo dõi hệ thống +Name[wa]=Corwaitoe do sistinme +Name[x-test]=xxSystem Monitorxx +Name[zh_CN]=系统监视器 +Name[zh_TW]=系統監視器 +Comment=System monitoring applet +Comment[ar]=بريمج مراقب النظام +Comment[ast]=Miniaplicación de monitorización del sistema +Comment[be@latin]=Aplet nazirańnia za systemaju +Comment[bg]=Аплет за наблюдение на системата +Comment[bn]=সিস্টেম মনিটর অ্যাপলেট +Comment[bn_IN]=সিস্টেম নিরীক্ষণের অ্যাপ্লেট +Comment[bs]=Aplet za nadgledanje sistema +Comment[ca]=Miniaplicació controladora del sistema +Comment[ca@valencia]=Miniaplicació controladora del sistema +Comment[cs]=Applet pro monitorování systému +Comment[csb]=Aplet mònitorowaniô systemë +Comment[da]=Applet til systemovervågning +Comment[de]=Allgemeiner Systemmonitor +Comment[el]=Μικροεφαρμογή εποπτείας συστήματος +Comment[en_GB]=System monitoring applet +Comment[es]=Miniaplicación de monitorización del sistema +Comment[et]=Süsteemi jälgimise aplett +Comment[eu]=Sistema kontrolatzeko miniaplikazioa +Comment[fi]=Järjestelmänvalvontasovelma +Comment[fr]=Applet de surveillance du système +Comment[fy]=systeemtempratuer applet +Comment[ga]=Feidhmchláirín mhonatóireacht an chórais +Comment[gl]=Applet de vixilancia do sistema +Comment[gu]=સિસ્ટમ દેખરેખ એપ્લેટ +Comment[he]=יישומון לניטור המערכת +Comment[hi]=तंत्र मॉनिटरिंग एप्लेट +Comment[hne]=तंत्र मानीटर एपलेट +Comment[hr]=Nadzor sustava +Comment[hsb]=Applet za systemowy monitor +Comment[hu]=Rendszermonitor kisalkalmazás +Comment[ia]=Applet per monitorar le systema +Comment[id]=Applet monitor sistem +Comment[is]=Eftirlitsforritlingur í kerfisbakka +Comment[it]=Programma di monitoraggio del sistema +Comment[ja]=システムの状態を監視するアプレット +Comment[kk]=Жүйені бақылау апплеті +Comment[km]=អាប់ភ្លេត​​ត្រួតពិនិត្យ​ប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥೆಯ ಮೇಲ್ವಿಚಾರಕ ಆಪ್ಲೆಟ್ +Comment[ko]=시스템 모니터 애플릿 +Comment[ku]=Sepanoka temaşe kirina pergalê +Comment[lt]=Sistemos stebėjimo įskiepis +Comment[lv]=Sistēmas novērošanas sīkrīks +Comment[mk]=Аплет за следење на системот +Comment[ml]=സിസ്റ്റം നിരീക്ഷണി ലഘുപ്രയോഗം +Comment[mr]=प्रणाली नियंत्रण ऍपलेट +Comment[nb]=Systemovervåker miniprogram +Comment[nds]=Systeemwachter-Lüttprogramm +Comment[nl]=Systeemmonitorapplet +Comment[nn]=Overvaking av systemet +Comment[or]=ତନ୍ତ୍ର ନିରିକ୍ଷଣ ଆପଲେଟ +Comment[pa]=ਸਿਸਟਮ ਮਾਨੀਟਰ ਐਪਲਿਟ +Comment[pl]=Aplet monitora systemu +Comment[pt]='Applet' de monitorização do sistema +Comment[pt_BR]=Miniaplicativo de monitoramento do sistema +Comment[ro]=Miniaplicație de monitorizare a sistemului +Comment[ru]=Системный монитор +Comment[si]=පද්ධති නිරික්‍ෂණ යෙදුම්පත +Comment[sk]=Aplet pre monitorovanie systému +Comment[sl]=Sistemski nadzornik +Comment[sr]=Аплет за надгледање система +Comment[sr@ijekavian]=Аплет за надгледање система +Comment[sr@ijekavianlatin]=Aplet za nadgledanje sistema +Comment[sr@latin]=Aplet za nadgledanje sistema +Comment[sv]=Miniprogram för systemövervakning +Comment[ta]=கணினி நோட்ட சிறுபயன்பாடு +Comment[tg]=Барномаи мониторинги система +Comment[th]=แอพเพล็ตติดตามการทำงานของระบบ +Comment[tr]=Sistem izleme programcığı +Comment[ug]=سىستېما كۆزىتىش قوللانچىقى +Comment[uk]=Аплет моніторингу системи +Comment[wa]=Aplikete di corwaitaedje do sistinme +Comment[x-test]=xxSystem monitoring appletxx +Comment[zh_CN]=系统监视器小程序 +Comment[zh_TW]=系統監控小程式 +Type=Service +Icon=utilities-system-monitor +ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_system-monitor +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=system-monitor_applet +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System Information +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/generic/applets/system-monitor/plotter.cpp b/plasma/generic/applets/system-monitor/plotter.cpp new file mode 100644 index 00000000..231a4423 --- /dev/null +++ b/plasma/generic/applets/system-monitor/plotter.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2010 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "plotter.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace SM { + +Plotter::Plotter(QGraphicsItem* parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent, wFlags) + , m_layout(0) + , m_plotter(0) + , m_meter(0) + , m_plotCount(1) + , m_min(0.0) + , m_max(0.0) + , m_overlayFrame(0) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + createWidgets(); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeChanged())); +} + +Plotter::~Plotter() +{ +} + +void Plotter::setAnalog(bool analog) +{ + if (analog && m_layout->count() < 2) { + m_meter = new Plasma::Meter(this); + m_meter->setMeterType(Plasma::Meter::AnalogMeter); + m_meter->setLabelAlignment(1, Qt::AlignCenter); + m_layout->insertItem(0, m_meter); + m_meter->setMinimum(m_min); + m_meter->setMaximum(m_max); + m_meter->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + themeChanged(); + } else if (m_layout->count() > 1) { + m_layout->removeAt(0); + delete m_meter; + m_meter = 0; + } +} + +void Plotter::setMinMax(double min, double max) +{ + if (m_meter) { + m_meter->setMinimum(min); + m_meter->setMaximum(max); + } + m_plotter->setUseAutoRange(false); + m_plotter->setVerticalRange(min, max); + m_min = min; + m_max = max; +} + +const QString& Plotter::title() +{ + return m_title; +} + +void Plotter::setTitle(const QString& title) +{ + m_plotter->setTitle(title); + if (m_meter) { + m_meter->setLabel(0, title); + } + m_title = title; +} + +void Plotter::setUnit(const QString& unit) +{ + m_plotter->setUnit(unit); + m_unit = unit; +} + +void Plotter::setScale(qreal scale) +{ + m_plotter->scale(scale); +} + +void Plotter::setStackPlots(bool stack) +{ + m_plotter->setStackPlots(stack); +} + +void Plotter::setPlotCount(int count) +{ + for (int i = 0; i < m_plotCount; ++i) { + m_plotter->removePlot(0); + } + m_plotCount = count; + Plasma::Theme* theme = Plasma::Theme::defaultTheme(); + QColor text = theme->color(Plasma::Theme::TextColor); + QColor bg = theme->color(Plasma::Theme::BackgroundColor); + for (int i = 0; i < m_plotCount; ++i) { + QColor color = KColorUtils::tint(text, bg, 0.4 + ((double)i / 2.5)); + m_plotter->addPlot(color); + } +} + +void Plotter::setCustomPlots(const QList& colors) +{ + for (int i = 0; i < m_plotCount; ++i) { + m_plotter->removePlot(0); + } + m_plotCount = colors.count(); + foreach (const QColor& color, colors) { + m_plotter->addPlot(color); + } +} + +void Plotter::createWidgets() +{ + m_layout = new QGraphicsLinearLayout(Qt::Horizontal); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setSpacing(5); + setLayout(m_layout); + + m_plotter = new Plasma::SignalPlotter(this); + m_plotter->setThinFrame(false); + m_plotter->setShowLabels(false); + m_plotter->setShowTopBar(true); + m_plotter->setShowVerticalLines(false); + m_plotter->setShowHorizontalLines(false); + m_plotter->setUseAutoRange(true); + m_plotter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout->addItem(m_plotter); + themeChanged(); + setPlotCount(m_plotCount); +} + +void Plotter::themeChanged() +{ + Plasma::Theme* theme = Plasma::Theme::defaultTheme(); + if (m_meter) { + m_meter->setLabelColor(0, theme->color(Plasma::Theme::TextColor)); + m_meter->setLabelColor(0, theme->color(Plasma::Theme::TextColor)); + m_meter->setLabelColor(1, QColor("#000")); + } + m_plotter->setFontColor(theme->color(Plasma::Theme::TextColor)); + m_plotter->setSvgBackground("widgets/plot-background"); + QColor linesColor = theme->color(Plasma::Theme::TextColor); + linesColor.setAlphaF(0.4); + m_plotter->setHorizontalLinesColor(linesColor); + m_plotter->setVerticalLinesColor(linesColor); + resizeEvent(0); +} + +void Plotter::addSample(const QList& values) +{ + m_plotter->addSample(values); + QStringList list; + foreach (double value, values) { + double v = value / m_plotter->scaledBy(); + list << QString("%1 %2").arg(v, 0, 'f', (v > 1000.0) ? 0 : 1).arg(m_unit); + } + setOverlayText(list.join(" / ")); + if (m_meter) { + m_meter->setValue(values[0]); + } +} + +void Plotter::setOverlayText(const QString& text) +{ + if (!m_overlayFrame) { + QGraphicsLinearLayout* layout = new QGraphicsLinearLayout(Qt::Vertical, m_plotter); + m_plotter->setLayout(layout); + m_overlayFrame = new Plasma::Frame(m_plotter); + m_overlayFrame->setZValue(10); + m_overlayFrame->resize(m_overlayFrame->size().height() * 2.5, + m_overlayFrame->size().height()); + layout->addStretch(); + QGraphicsLinearLayout* layout2 = new QGraphicsLinearLayout(Qt::Horizontal, layout); + layout2->addStretch(); + layout2->addItem(m_overlayFrame); + layout2->addStretch(); + layout->addItem(layout2); + resizeEvent(0); + } + m_overlayFrame->setText(text); + if (m_meter) { + if (m_showAnalogValue) { + m_meter->setLabel(1, text); + } else { + m_meter->setLabel(1, QString()); + } + } +} + +void Plotter::resizeEvent(QGraphicsSceneResizeEvent* event) +{ + Q_UNUSED(event) + qreal h = size().height(); + qreal fontHeight = h / (7.0 * 1.5); // Seven rows + Plasma::Theme* theme = Plasma::Theme::defaultTheme(); + QFont font = theme->font(Plasma::Theme::DefaultFont); + QFont smallest = KGlobalSettings::smallestReadableFont(); + bool show = false; + QFontMetrics metrics(font); + QStringList list; + for (int i = 0; i < m_plotCount; ++i) { + list << QString("888.0 %2").arg(m_unit); + } + QString valueText = list.join(" / "); + + font.setPointSizeF(smallest.pointSizeF()); + forever { + metrics = QFontMetrics(font); + if (metrics.height() > fontHeight) { + break; + } + font.setPointSizeF(font.pointSizeF() + 0.5); + show = true; + } + m_plotter->setFont(font); + m_plotter->setShowTopBar(metrics.height() < h / 6); + m_plotter->setShowLabels(show); + m_plotter->setShowHorizontalLines(show); + if (m_overlayFrame) { + m_overlayFrame->setVisible(metrics.height() < h / 3 && + metrics.width(valueText) < size().width() * 0.8); + m_overlayFrame->setFont(font); + } + + if (m_meter) { + m_meter->setLabelFont(0, font); + m_meter->setLabelFont(1, font); + // Make analog meter square + m_meter->setMinimumSize(h, 8); + m_showAnalogValue = (m_meter->size().width() * 0.7 > metrics.width(valueText)); + if (m_meter->size().width() * 0.9 > metrics.width(m_title)) { + m_meter->setLabel(0, m_title); + } else { + m_meter->setLabel(0, QString()); + } + m_meter->setLabel(1, QString()); + } +} + +} // namespace + +#include "plotter.moc" diff --git a/plasma/generic/applets/system-monitor/plotter.h b/plasma/generic/applets/system-monitor/plotter.h new file mode 100644 index 00000000..b40a855b --- /dev/null +++ b/plasma/generic/applets/system-monitor/plotter.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SM_PLOTTER_HEADER +#define SM_PLOTTER_HEADER + +#include + +#include "sm_export.h" + +class QGraphicsLinearLayout; + +namespace Plasma { + class Meter; + class SignalPlotter; + class Frame; +} + +namespace SM { + +class SM_EXPORT Plotter : public QGraphicsWidget +{ + Q_OBJECT + public: + Plotter(QGraphicsItem* parent = 0, Qt::WindowFlags wFlags = 0); + ~Plotter(); + + void addSample(const QList& values); + void setAnalog(bool analog); + void setMinMax(double min, double max); + const QString& title(); + void setTitle(const QString& title); + void setUnit(const QString& unit); + void setPlotCount(int count); + void setCustomPlots(const QList& colors); + void setScale(qreal scale); + void setStackPlots(bool stack); + + protected slots: + void themeChanged(); + + protected: + void createWidgets(); + void setOverlayText(const QString& text); + virtual void resizeEvent(QGraphicsSceneResizeEvent* event); + + private: + QGraphicsLinearLayout *m_layout; + Plasma::SignalPlotter *m_plotter; + Plasma::Meter *m_meter; + int m_plotCount; + QString m_title; + QString m_unit; + double m_min; + double m_max; + Plasma::Frame* m_overlayFrame; + bool m_showAnalogValue; +}; + +} + +#endif diff --git a/plasma/generic/applets/system-monitor/ram-config.ui b/plasma/generic/applets/system-monitor/ram-config.ui new file mode 100644 index 00000000..0a0c2344 --- /dev/null +++ b/plasma/generic/applets/system-monitor/ram-config.ui @@ -0,0 +1,93 @@ + + + config + + + + 0 + 0 + 382 + 263 + + + + + + + + 0 + + + + + &Memory: + + + treeView + + + + + + + false + + + true + + + true + + + + + + + + + Update &interval: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + intervalSpinBox + + + + + + + 1 + + + 0.100000000000000 + + + 525600.000000000000000 + + + 2.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/plasma/generic/applets/system-monitor/ram.cpp b/plasma/generic/applets/system-monitor/ram.cpp new file mode 100644 index 00000000..ee88eb90 --- /dev/null +++ b/plasma/generic/applets/system-monitor/ram.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2008 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ram.h" +#include +#include +#include +#include +#include +#include "plotter.h" + +/* All sources we are interested in. */ +static const char phys_source[] = "mem/physical/application"; +static const char swap_source[] = "mem/swap/used"; + +SM::Ram::Ram(QObject *parent, const QVariantList &args) + : SM::Applet(parent, args) +{ + setHasConfigurationInterface(true); + resize(234 + 20 + 23, 135 + 20 + 25); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +SM::Ram::~Ram() +{ +} + +void SM::Ram::init() +{ + KGlobal::locale()->insertCatalog("plasma_applet_system-monitor"); + setEngine(dataEngine("systemmonitor")); + setTitle(i18n("RAM")); + + /* At the time this method is running, not all source may be connected. */ + connect(engine(), SIGNAL(sourceAdded(QString)), this, SLOT(sourceAdded(QString))); + foreach (const QString& source, engine()->sources()) { + sourceAdded(source); + } +} + +void SM::Ram::configChanged() +{ + KConfigGroup cg = config(); + setInterval(cg.readEntry("interval", 2.0) * 1000.0); + // sanity check + QStringList memories = cg.readEntry("memories", m_memories); + foreach (QString source, memories) { + if (source != phys_source && source != swap_source) + memories.removeAt(memories.indexOf(source)); + } + setSources(memories); + m_max.clear(); + connectToEngine(); +} + +void SM::Ram::sourceAdded(const QString& name) +{ + if ((name == phys_source || name == swap_source) && !m_memories.contains(name)) { + m_memories << name; + if (m_memories.count() == 2) { + // all sources are ready + QTimer::singleShot(0, this, SLOT(sourcesAdded())); + } + } +} + +void SM::Ram::sourcesAdded() +{ + configChanged(); +} + +bool SM::Ram::addVisualization(const QString& source) +{ + QStringList l = source.split('/'); + if (l.count() < 3) { + return false; + } + QString ram = l[1]; + + SM::Plotter *plotter = new SM::Plotter(this); + + // 'ram' should be "physical" or "swap". I'm not aware of other values + // for it, but who knows. + if (ram == "physical") { + ram = i18nc("noun, hardware, physical RAM/memory", "physical"); + } else if (ram == "swap") { + ram = i18nc("noun, hardware, swap file/partition", "swap"); + } + + plotter->setTitle(ram); + plotter->setUnit("B"); + + appendVisualization(source, plotter); + setPreferredItemHeight(80); + + return true; +} + +double SM::Ram::preferredBinaryUnit() +{ + KLocale::BinaryUnitDialect binaryUnit = KGlobal::locale()->binaryUnitDialect(); + + // this makes me feel all dirty inside. but it's the only way I could find + // which will let us know what we should be scaling our graph by, independent + // of how locale settings are configured. + switch (binaryUnit) { + case KLocale::IECBinaryDialect: + //fallthrough + case KLocale::JEDECBinaryDialect: + return 1024; + break; + case KLocale::MetricBinaryDialect: + return 1000; + break; + + default: + // being careful..I'm sure some genius will invent a new byte unit system ;-) + Q_ASSERT_X(0, "preferredBinaryUnit", "invalid binary preference enum returned"); + return 0; + } +} + +QStringList SM::Ram::preferredUnitsList() +{ + QStringList units; + KLocale::BinaryUnitDialect binaryUnit = KGlobal::locale()->binaryUnitDialect(); + switch (binaryUnit) { + case KLocale::IECBinaryDialect: + units << "B" << "KiB" << "MiB" << "GiB" << "TiB"; + break; + case KLocale::JEDECBinaryDialect: + units << "B" << "KB" << "MB" << "GB" << "TB"; + break; + case KLocale::MetricBinaryDialect: + units << "B" << "kB" << "MB" << "GB" << "TB"; + break; + default: + Q_ASSERT_X(0, "preferredBinaryUnit", "invalid binary preference enum returned"); + } + + return units; +} + +void SM::Ram::dataUpdated(const QString& source, const Plasma::DataEngine::Data &data) +{ + SM::Plotter *plotter = qobject_cast(visualization(source)); + if (plotter) { + /* A factor to convert from default units to bytes. + * If units is not "KB", assume it is bytes. + * NOTE: the dataengine refers to KB == 1024. so it's KiB as well. + * Though keep in mind, KB does not imply 1024 and can be KB == 1000 as well. + */ + const double preferredUnit = preferredBinaryUnit(); + const double factor = (data["units"].toString() == "KB") ? preferredUnit : 1.0; + const double value_b = data["value"].toDouble() * factor; + const double max_b = data["max"].toDouble() * factor; + const QStringList units = preferredUnitsList(); + + if (value_b > m_max[source]) { + m_max[source] = max_b; + plotter->setMinMax(0.0, max_b); + qreal scale = 1.0; + int i = 0; + while (max_b / scale > factor && i < units.size()) { + scale *= factor; + ++i; + } + + plotter->setUnit(units[i]); + plotter->setScale(scale); + } + + plotter->addSample(QList() << value_b); + QString temp = KGlobal::locale()->formatByteSize(value_b); + + if (mode() == SM::Applet::Panel) { + setToolTip(source, QString("%1%2of%3") + .arg(plotter->title()) + .arg(temp) + .arg(KGlobal::locale()->formatByteSize(m_max[source]))); + } + } +} + +void SM::Ram::createConfigurationInterface(KConfigDialog *parent) +{ + QWidget *widget = new QWidget(); + ui.setupUi(widget); + m_model.clear(); + m_model.setHorizontalHeaderLabels(QStringList() << i18n("RAM")); + QStandardItem *parentItem = m_model.invisibleRootItem(); + QRegExp rx("mem/(\\w+)/.*"); + QString ramName; + + foreach (const QString& ram, m_memories) { + if (rx.indexIn(ram) != -1) { + ramName = rx.cap(1); + + // 'ram' should be "physical" or "swap". I'm not aware of other values + // for it, but who knows. (see also addVisualization) + if (ramName == "physical") { + ramName = i18nc("noun, hardware, physical RAM/memory", "physical"); + } else if (ramName == "swap") { + ramName = i18nc("noun, hardware, swap file/partition", "swap"); + } + + QStandardItem *ramItem = new QStandardItem(ramName); + ramItem->setEditable(false); + ramItem->setCheckable(true); + ramItem->setData(ram); + + if (sources().contains(ram)) { + ramItem->setCheckState(Qt::Checked); + } + + parentItem->appendRow(ramItem); + } + } + + ui.treeView->setModel(&m_model); + ui.treeView->resizeColumnToContents(0); + ui.intervalSpinBox->setValue(interval() / 1000.0); + ui.intervalSpinBox->setSuffix(i18nc("second", " s")); + parent->addPage(widget, i18n("RAM"), "media-flash"); + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + connect(ui.treeView, SIGNAL(clicked(QModelIndex)), parent, SLOT(settingsModified())); + connect(ui.intervalSpinBox, SIGNAL(valueChanged(QString)), parent, SLOT(settingsModified())); +} + +void SM::Ram::configAccepted() +{ + KConfigGroup cg = config(); + QStandardItem *parentItem = m_model.invisibleRootItem(); + + clear(); + + for (int i = 0; i < parentItem->rowCount(); ++i) { + QStandardItem *item = parentItem->child(i, 0); + if (item) { + if (item->checkState() == Qt::Checked) { + // data() is the untranslated string + // for use with sources + appendSource(item->data().toString()); + } + } + } + + // note we write and read non-translated + // version to config file. + cg.writeEntry("memories", sources()); + + double interval = ui.intervalSpinBox->value(); + cg.writeEntry("interval", interval); + + emit configNeedsSaving(); +} + +#include "ram.moc" diff --git a/plasma/generic/applets/system-monitor/ram.h b/plasma/generic/applets/system-monitor/ram.h new file mode 100644 index 00000000..c9edde9b --- /dev/null +++ b/plasma/generic/applets/system-monitor/ram.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef RAM_HEADER +#define RAM_HEADER + +#include +#include "applet.h" +#include +#include + +class QStandardItemModel; + +namespace SM { + +class Ram : public Applet +{ + Q_OBJECT + public: + Ram(QObject *parent, const QVariantList &args); + ~Ram(); + + virtual void init(); + virtual bool addVisualization(const QString&); + virtual void createConfigurationInterface(KConfigDialog *parent); + + public slots: + void dataUpdated(const QString &name, + const Plasma::DataEngine::Data &data); + void sourceAdded(const QString &name); + void sourcesAdded(); + void configAccepted(); + void configChanged(); + + private: + // below methods exist because KLocale has no nice + // way of getting this info :( + // thought about adding it to the api, but perhaps this + // code is the only one that uses it? + /** + * The preferred binary unit byte value + * e.g. KiB, kiB, KIB, etc. + * @return double 1024 or 1000 + */ + double preferredBinaryUnit(); + + /** + * The preferred binary unit abbreviations. + * @return QStringList B, KiB, MiB, GiB, TiB.\ + * or whatever is best fit for current binary unit + * settings via klocale. + */ + QStringList preferredUnitsList(); + + Ui::config ui; + QStandardItemModel m_model; + QStringList m_memories; + QHash m_max; +}; +} + +K_EXPORT_PLASMA_APPLET(sm_ram, SM::Ram) + +#endif diff --git a/plasma/generic/applets/system-monitor/sm_export.h b/plasma/generic/applets/system-monitor/sm_export.h new file mode 100644 index 00000000..a802a7dd --- /dev/null +++ b/plasma/generic/applets/system-monitor/sm_export.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE project + Copyright (C) 2007 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SM_EXPORT_H +#define SM_EXPORT_H + +/* needed for KDE_EXPORT and KDE_IMPORT macros */ +#include + +#ifndef SM_EXPORT +# if defined(MAKE_PLASMA_APPLET_SYSTEM_MONITOR_LIB) + /* We are building this library */ +# define SM_EXPORT KDE_EXPORT +# else + /* We are using this library */ +# define SM_EXPORT KDE_IMPORT +# endif +#endif + +# ifndef SM_EXPORT_DEPRECATED +# define SM_EXPORT_DEPRECATED KDE_DEPRECATED SM_EXPORT +# endif + +#endif diff --git a/plasma/generic/applets/system-monitor/system-monitor.cpp b/plasma/generic/applets/system-monitor/system-monitor.cpp new file mode 100644 index 00000000..fc771b89 --- /dev/null +++ b/plasma/generic/applets/system-monitor/system-monitor.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "system-monitor.h" +#include "monitorbutton.h" +#include "applet.h" +#include +#include +#include +#include +#include +#include + +SystemMonitor::SystemMonitor(QObject *parent, const QVariantList &args) + : Plasma::PopupApplet(parent, args), m_layout(0), m_buttons(0), m_widget(0) +{ + setAspectRatioMode(Plasma::IgnoreAspectRatio); +} + +SystemMonitor::~SystemMonitor() +{ +} + +void SystemMonitor::saveState(KConfigGroup &group) const +{ + QStringList appletNames; + foreach (SM::Applet *applet, m_applets) { + applet->saveConfig(group); + appletNames << applet->objectName(); + } + + group.writeEntry("applets", appletNames); +} + +void SystemMonitor::createConfigurationInterface(KConfigDialog *parent) +{ + foreach (Plasma::Applet *applet, m_applets) { + applet->createConfigurationInterface(parent); + } +} + +void SystemMonitor::init() +{ + KConfigGroup cg = config(); + QStringList appletNames = cg.readEntry("applets", QStringList()); + + m_widget = new QGraphicsWidget(this); + m_layout = new QGraphicsLinearLayout(Qt::Vertical); + m_layout->setContentsMargins(0, 0, 0, 0); + m_buttons = new QGraphicsLinearLayout(Qt::Horizontal); + m_buttons->setContentsMargins(0, 0, 0, 0); + m_buttons->setSpacing(5); + + QMap appletsFound; + KPluginInfo::List appletList = listAppletInfo("System Information"); + foreach (const KPluginInfo &pluginInfo, appletList) { + if (pluginInfo.pluginName().startsWith("sm_") && !pluginInfo.isHidden()) { + appletsFound.insert(pluginInfo.pluginName(), pluginInfo); + } + } + + foreach (const KPluginInfo &pluginInfo, appletsFound) { + MonitorButton *button = new MonitorButton(m_widget); + button->setObjectName(pluginInfo.pluginName()); + Plasma::ToolTipContent data; + data.setMainText(pluginInfo.name()); + data.setImage(KIcon(pluginInfo.icon()).pixmap(IconSize(KIconLoader::Desktop))); + Plasma::ToolTipManager::self()->setContent(button, data); + button->setCheckable(true); + button->setImage(pluginInfo.icon()); + if (appletNames.contains(pluginInfo.pluginName())) { + button->setChecked(true); + } + connect(button, SIGNAL(toggled(bool)), this, SLOT(toggled(bool))); + m_buttons->addItem(button); + m_monitorButtons << button; + // this does not work + KGlobal::locale()->insertCatalog(pluginInfo.pluginName()); + } + + m_layout->addItem(m_buttons); + foreach (const QString& appletName, appletNames) { + if (appletsFound.contains(appletName)) { + Applet * applet = addApplet(appletName); + + if (applet) { + Plasma::Constraints constraints(Plasma::ImmutableConstraint | + Plasma::StartupCompletedConstraint); + applet->updateConstraints(constraints); + applet->flushPendingConstraintsEvents(); + } + } + } + + m_widget->setLayout(m_layout); + checkGeometry(); + + setPopupIcon("utilities-system-monitor"); +} + +void SystemMonitor::toggled(bool toggled) +{ + removeApplet(sender()->objectName()); + + if (toggled) { + SM::Applet * applet = addApplet(sender()->objectName()); + + if (applet) { + Plasma::Constraints constraints(Plasma::ImmutableConstraint | + Plasma::StartupCompletedConstraint); + applet->updateConstraints(constraints); + applet->flushPendingConstraintsEvents(); + } + } +} + +void SystemMonitor::configChanged() +{ + KConfigGroup cg = config(); + QStringList appletNames = cg.readEntry("applets", QStringList()); + + QStringList oldAppletNames; + foreach (SM::Applet *applet, m_applets) { + oldAppletNames << applet->objectName(); + } + + if (appletNames == oldAppletNames) { + foreach (SM::Applet *applet, m_applets) + applet->configChanged(); + } else { + QMap appletsFound; + KPluginInfo::List appletList = listAppletInfo("System Information"); + foreach (const KPluginInfo &pluginInfo, appletList) { + if (pluginInfo.pluginName().startsWith("sm_") && !pluginInfo.isHidden()) { + appletsFound.insert(pluginInfo.pluginName(), pluginInfo); + } + } + + foreach (MonitorButton *button, m_monitorButtons) { + button->setChecked(false); + } + + foreach (const QString& appletName, appletNames) { + if (appletsFound.contains(appletName)) { + foreach (MonitorButton* button, m_monitorButtons) { + if (button->objectName() == appletName) + button->setChecked(true); + } + } + } + checkGeometry(); + } +} + +SM::Applet *SystemMonitor::addApplet(const QString &name) +{ + if (name.isEmpty()) { + return 0; + } + + Plasma::Applet* plasmaApplet = Plasma::Applet::load(name, 0, QVariantList() << "SM"); + SM::Applet* applet = qobject_cast(plasmaApplet); + if (applet) { + applet->setParentItem(m_widget); + m_applets.append(applet); + connect(applet, SIGNAL(geometryChecked()), this, SLOT(checkGeometry())); + connect(applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletRemoved(QObject*))); + applet->setFlag(QGraphicsItem::ItemIsMovable, false); + applet->setBackgroundHints(Plasma::Applet::NoBackground); + applet->setObjectName(name); + connect(applet, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving())); + m_layout->addItem(applet); + applet->init(); + + KConfigGroup cg = config(); + saveState(cg); + emit configNeedsSaving(); + } else if (plasmaApplet) { + delete plasmaApplet; + } + + return applet; +} + +void SystemMonitor::removeApplet(const QString &name) +{ + foreach (SM::Applet *applet, m_applets) { + if (applet->objectName() == name) { + applet->destroy(); + } + } +} + +void SystemMonitor::appletRemoved(QObject *object) +{ + SM::Applet *applet = static_cast(object); + + foreach (SM::Applet *a, m_applets) { + if (a == applet) { + m_layout->removeItem(applet); + m_applets.removeAll(applet); + checkGeometry(); + + KConfigGroup cg = config(); + saveState(cg); + emit configNeedsSaving(); + } + } + + // sanity check the buttons + QSet running; + foreach (SM::Applet *a, m_applets) { + running << a->objectName(); + } + + foreach (MonitorButton* button, m_monitorButtons) { + if (!running.contains(button->objectName())) { + kDebug() << "unchecking" << button->objectName(); + button->setChecked(false); + } + } +} + +void SystemMonitor::checkGeometry() +{ + QSizeF margins = size() - contentsRect().size(); + qreal minHeight = m_buttons->minimumHeight(); + //kDebug() << minHeight; + + foreach (SM::Applet *applet, m_applets) { + //kDebug() << applet->minSize() << applet->minimumSize() + // << applet->metaObject()->className() << applet->size() - applet->contentsRect().size(); + minHeight += applet->preferredSize().height() + m_layout->spacing(); + } + + + update(); + /* + kDebug() << m_widget->size().height() << m_layout->geometry().height(); + foreach (SM::Applet *applet, m_applets) { + kDebug() << applet->metaObject()->className() << applet->size().height(); + } + for (int i = 0; i < m_layout->count(); ++i) { + kDebug() << m_layout->itemAt(i)->geometry().top() << m_layout->itemAt(i)->geometry().height(); + } + */ +} + +QGraphicsWidget *SystemMonitor::graphicsWidget() +{ + return m_widget; +} + +void SystemMonitor::constraintsEvent(Plasma::Constraints constraints) +{ + Plasma::Constraints passOn = Plasma::NoConstraint; + + if (constraints & Plasma::ImmutableConstraint) { + foreach (MonitorButton* button, m_monitorButtons) { + button->setEnabled(immutability() == Plasma::Mutable); + } + + passOn |= Plasma::ImmutableConstraint; + } + + if (constraints & Plasma::StartupCompletedConstraint) { + passOn |= Plasma::StartupCompletedConstraint; + } + + if (passOn != Plasma::NoConstraint) { + foreach (Plasma::Applet *applet, m_applets) { + applet->updateConstraints(passOn); + if (passOn & Plasma::StartupCompletedConstraint) { + applet->flushPendingConstraintsEvents(); + } + } + } + + PopupApplet::constraintsEvent(constraints); +} + +#include "system-monitor.moc" diff --git a/plasma/generic/applets/system-monitor/system-monitor.h b/plasma/generic/applets/system-monitor/system-monitor.h new file mode 100644 index 00000000..dc889021 --- /dev/null +++ b/plasma/generic/applets/system-monitor/system-monitor.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SYSTEM_MONITOR_HEADER +#define SYSTEM_MONITOR_HEADER + +#include +#include + +namespace SM { + class Applet; +} +class MonitorButton; + +class QGraphicsLinearLayout; + +class SystemMonitor : public Plasma::PopupApplet +{ + Q_OBJECT + public: + SystemMonitor(QObject *parent, const QVariantList &args); + virtual ~SystemMonitor(); + + void init(); + virtual QGraphicsWidget *graphicsWidget(); + virtual void constraintsEvent(Plasma::Constraints constraints); + + public slots: + void checkGeometry(); + + protected slots: + void toggled(bool toggled); + void appletRemoved(QObject *object); + void configChanged(); + + protected: + SM::Applet *addApplet(const QString &name); + void removeApplet(const QString &name); + void saveState(KConfigGroup &group) const; + void createConfigurationInterface(KConfigDialog *parent); + + private: + QGraphicsLinearLayout *m_layout; + QGraphicsLinearLayout *m_buttons; + QList m_applets; + QList m_monitorButtons; + QGraphicsWidget *m_widget; +}; + +K_EXPORT_PLASMA_APPLET(system-monitor_applet, SystemMonitor) + +#endif diff --git a/plasma/generic/applets/system-monitor/temperature-config.ui b/plasma/generic/applets/system-monitor/temperature-config.ui new file mode 100644 index 00000000..6bec6103 --- /dev/null +++ b/plasma/generic/applets/system-monitor/temperature-config.ui @@ -0,0 +1,90 @@ + + + config + + + + 0 + 0 + 383 + 323 + + + + + + + + + + &Available temperatures: + + + treeView + + + + + + + false + + + true + + + true + + + + + + + + + Update &interval: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + intervalSpinBox + + + + + + + 1 + + + 0.100000000000000 + + + 525600.000000000000000 + + + 2.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/plasma/generic/applets/system-monitor/temperature-offset-delegate.cpp b/plasma/generic/applets/system-monitor/temperature-offset-delegate.cpp new file mode 100644 index 00000000..2ed90d03 --- /dev/null +++ b/plasma/generic/applets/system-monitor/temperature-offset-delegate.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Elvis Stansvik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "temperature-offset-delegate.h" + +#include + +TemperatureOffsetDelegate::TemperatureOffsetDelegate(QObject *parent) : QItemDelegate(parent) +{ +} + +QWidget *TemperatureOffsetDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_UNUSED(option); + Q_UNUSED(index); + + KDoubleNumInput *input = new KDoubleNumInput(parent); + input->setMinimum(-1000); + input->setMaximum(1000); + input->setDecimals(1); + input->setSingleStep(0.1); + input->setSliderEnabled(false); + + return input; +} + +void TemperatureOffsetDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + KDoubleNumInput *input = static_cast(editor); + input->setValue(index.model()->data(index, Qt::EditRole).toDouble()); +} + +void TemperatureOffsetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + KDoubleNumInput *input = static_cast(editor); + model->setData(index, input->value(), Qt::EditRole); +} + +void TemperatureOffsetDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index); + editor->setGeometry(option.rect); +} diff --git a/plasma/generic/applets/system-monitor/temperature-offset-delegate.h b/plasma/generic/applets/system-monitor/temperature-offset-delegate.h new file mode 100644 index 00000000..8b7c1855 --- /dev/null +++ b/plasma/generic/applets/system-monitor/temperature-offset-delegate.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Elvis Stansvik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TEMPERATURE_OFFSET_DELEGATE_H +#define TEMPERATURE_OFFSET_DELEGATE_H + +#include + +/** + * Item delegate that uses a spinbox to edit real numbers. + */ +class TemperatureOffsetDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + TemperatureOffsetDelegate(QObject *parent = 0); + + /// reimplemented from QItemDelegate. + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + /// reimplemented from QItemDelegate. + void setEditorData(QWidget *editor, const QModelIndex &index) const; + /// reimplemented from QItemDelegate. + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + /// reimplemented from QItemDelegate. + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif // TEMPERATURE_OFFSET_DELEGATE_H diff --git a/plasma/generic/applets/system-monitor/temperature.cpp b/plasma/generic/applets/system-monitor/temperature.cpp new file mode 100644 index 00000000..a1ec715a --- /dev/null +++ b/plasma/generic/applets/system-monitor/temperature.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2008 Marco Martin + * Copyright (C) 2010 Michel Lafon-Puyo + * Copyright (C) 2011 Elvis Stansvik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "temperature.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "plotter.h" +#include "temperature-offset-delegate.h" + +using namespace KUnitConversion; + +Temperature::Temperature(QObject *parent, const QVariantList &args) + : SM::Applet(parent, args) + , m_tempModel(0) + , m_rx(".*temp.*", Qt::CaseInsensitive) +{ + setHasConfigurationInterface(true); + resize(215 + 20 + 23, 109 + 20 + 25); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + m_sourceTimer.setSingleShot(true); + connect(&m_sourceTimer, SIGNAL(timeout()), this, SLOT(sourcesAdded())); +} + +Temperature::~Temperature() +{ +} + +void Temperature::init() +{ + KGlobal::locale()->insertCatalog("plasma_applet_system-monitor"); + setEngine(dataEngine("systemmonitor")); + setTitle(i18n("Temperature")); + + /* At the time this method is running, not all source may be connected. */ + connect(engine(), SIGNAL(sourceAdded(QString)), this, SLOT(sourceAdded(QString))); + foreach (const QString& source, engine()->sources()) { + sourceAdded(source); + } +} + +void Temperature::configChanged() +{ + KConfigGroup cg = config(); + setInterval(cg.readEntry("interval", 2.0) * 1000.0); + setSources(cg.readEntry("temps", m_sources.mid(0, 5))); + connectToEngine(); +} + +void Temperature::sourceAdded(const QString& name) +{ + if (m_rx.indexIn(name) != -1) { + //kDebug() << m_rx.cap(1); + m_sources << name; + if (!m_sourceTimer.isActive()) { + m_sourceTimer.start(0); + } + } +} + +void Temperature::sourcesAdded() +{ + configChanged(); +} + +void Temperature::createConfigurationInterface(KConfigDialog *parent) +{ + QWidget *widget = new QWidget(); + ui.setupUi(widget); + m_tempModel.clear(); + m_tempModel.setHorizontalHeaderLabels(QStringList() << i18n("Sensor") + << i18n("Name") + << i18n("Offset")); + + QStandardItem *parentItem = m_tempModel.invisibleRootItem(); + foreach (const QString& temp, m_sources) { + QStandardItem *item1 = new QStandardItem(temp); + item1->setEditable(false); + item1->setCheckable(true); + if (sources().contains(temp)) { + item1->setCheckState(Qt::Checked); + } + QStandardItem *item2 = new QStandardItem(temperatureTitle(temp)); + item2->setEditable(true); + QStandardItem *item3 = new QStandardItem( + KGlobal::locale()->formatNumber(temperatureOffset(temp), 1)); + item3->setEditable(true); + parentItem->appendRow(QList() << item1 << item2 << item3); + } + ui.treeView->setModel(&m_tempModel); + ui.treeView->resizeColumnToContents(0); + ui.treeView->setItemDelegateForColumn(2, new TemperatureOffsetDelegate()); + + ui.intervalSpinBox->setValue(interval() / 1000.0); + ui.intervalSpinBox->setSuffix(i18nc("second", " s")); + parent->setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Apply); + parent->addPage(widget, i18n("Temperature"), "view-statistics"); + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + connect(ui.treeView, SIGNAL(clicked(QModelIndex)), parent, SLOT(settingsModified())); + connect(ui.intervalSpinBox, SIGNAL(valueChanged(QString)), parent, SLOT(settingsModified())); +} + +void Temperature::configAccepted() +{ + KConfigGroup cg = config(); + KConfigGroup cgGlobal = globalConfig(); + QStandardItem *parentItem = m_tempModel.invisibleRootItem(); + + clear(); + + for (int i = 0; i < parentItem->rowCount(); ++i) { + QStandardItem *item = parentItem->child(i, 0); + if (item) { + cgGlobal.writeEntry(item->text(), + parentItem->child(i, 1)->text()); + cgGlobal.writeEntry(item->text() + "_offset", QString::number( + parentItem->child(i, 2)->data(Qt::EditRole).toDouble(), 'f', 1)); + if (item->checkState() == Qt::Checked) { + appendSource(item->text()); + } + } + } + cg.writeEntry("temps", sources()); + uint interval = ui.intervalSpinBox->value(); + cg.writeEntry("interval", interval); + + emit configNeedsSaving(); +} + +QString Temperature::temperatureTitle(const QString& source) +{ + KConfigGroup cg = globalConfig(); + return cg.readEntry(source, source.mid(source.lastIndexOf('/') + 1).replace('_',' ')); +} + +double Temperature::temperatureOffset(const QString& source) +{ + KConfigGroup cg = globalConfig(); + return cg.readEntry(source + "_offset", 0.0); +} + +bool Temperature::addVisualization(const QString& source) +{ + Plasma::DataEngine *engine = dataEngine("systemmonitor"); + + if (!engine) { + return false; + } + + SM::Plotter *plotter = new SM::Plotter(this); + plotter->setTitle(temperatureTitle(source)); + plotter->setAnalog(mode() != SM::Applet::Panel); + + if (KGlobal::locale()->measureSystem() == KLocale::Metric) { + plotter->setMinMax(0, 110); + plotter->setUnit(QString::fromUtf8("°C")); + } else { + plotter->setMinMax(32, 230); + plotter->setUnit(QString::fromUtf8("°F")); + } + appendVisualization(source, plotter); + + Plasma::DataEngine::Data data = engine->query(source); + dataUpdated(source, data); + setPreferredItemHeight(80); + return true; +} + +void Temperature::dataUpdated(const QString& source, + const Plasma::DataEngine::Data &data) +{ + if (!sources().contains(source)) { + return; + } + SM::Plotter *plotter = qobject_cast(visualization(source)); + QString temp; + QString unit = data["units"].toString(); + double doubleValue = data["value"].toDouble() + temperatureOffset(source); + Value value = Value(doubleValue, unit); + + if (KGlobal::locale()->measureSystem() == KLocale::Metric) { + value = value.convertTo(Celsius); + } else { + value = value.convertTo(Fahrenheit); + } + + value.round(1); + if (plotter) { + plotter->addSample(QList() << value.number()); + } + + temp = value.toSymbolString(); + + if (mode() == SM::Applet::Panel) { + setToolTip(source, + QString("%1%2").arg(temperatureTitle(source)).arg(temp)); + } +} + +#include "temperature.moc" diff --git a/plasma/generic/applets/system-monitor/temperature.h b/plasma/generic/applets/system-monitor/temperature.h new file mode 100644 index 00000000..f340204f --- /dev/null +++ b/plasma/generic/applets/system-monitor/temperature.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2010 Michel Lafon-Puyo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TEMPERATURE_HEADER +#define TEMPERATURE_HEADER + +#include +#include "ui_temperature-config.h" +#include +#include +#include + +namespace Plasma { + class Meter; +} + +class Temperature : public SM::Applet +{ + Q_OBJECT + public: + Temperature(QObject *parent, const QVariantList &args); + ~Temperature(); + + virtual void init(); + + public slots: + void configChanged(); + void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data); + void createConfigurationInterface(KConfigDialog *parent); + + private slots: + void configAccepted(); + void sourceAdded(const QString& name); + void sourcesAdded(); + + private: + Ui::config ui; + QStandardItemModel m_tempModel; + QStringList m_sources; + QTimer m_sourceTimer; + QRegExp m_rx; + + QString temperatureTitle(const QString& source); + double temperatureOffset(const QString& source); + bool addVisualization(const QString& source); + bool isValidDevice(const QString& uuid, Plasma::DataEngine::Data* data); +}; + +K_EXPORT_PLASMA_APPLET(sm_temperature, Temperature) + +#endif diff --git a/plasma/generic/applets/systemtray/CMakeLists.txt b/plasma/generic/applets/systemtray/CMakeLists.txt new file mode 100644 index 00000000..caca7006 --- /dev/null +++ b/plasma/generic/applets/systemtray/CMakeLists.txt @@ -0,0 +1,66 @@ +project(plasma-systemtray) +#TODO: see if is still the case +# 'engineName' causes error +kde4_no_enable_final(plasma-systemtray) + +find_package(Qt4 4.8 COMPONENTS QtCore QtGui QtDeclarative REQUIRED) + +set(data_install_dir "plasma/packages/org.kde.systemtray") + +set(systemtray_SRCS + + core/manager.cpp + core/protocol.cpp + core/task.cpp + + protocols/fdo/fdoprotocol.cpp + protocols/fdo/fdotask.cpp + #FIXME: we should find another way to achieve that + #protocols/fdo/fdonotification.cpp + protocols/fdo/fdographicswidget.cpp + protocols/fdo/fdoselectionmanager.cpp + protocols/fdo/x11embedcontainer.cpp + protocols/fdo/x11embeddelegate.cpp + protocols/fdo/x11embedpainter.cpp + + protocols/plasmoid/plasmoidtaskprotocol.cpp + protocols/plasmoid/plasmoidtask.cpp + + protocols/dbussystemtray/dbussystemtraytask.cpp + protocols/dbussystemtray/dbussystemtrayprotocol.cpp + + ui/applet.cpp + ui/widgetitem.cpp + ui/mouseredirectarea.cpp + ) + +kde4_add_ui_files(systemtray_SRCS + ui/autohide.ui + ui/visibleitems.ui) + +include(${QT_USE_FILE}) +include (CheckLibraryExists) +check_library_exists (Xss XScreenSaverQueryInfo "" HAVE_LIBXSS) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +IF (HAVE_LIBXSS) + SET (IDLE_DETECTION_LIB "Xss") +ENDIF (HAVE_LIBXSS) + +kde4_add_plugin(plasma_applet_systemtray ${systemtray_SRCS}) +include_directories(${CMAKE_SOURCE_DIR}) +target_link_libraries(plasma_applet_systemtray + ${QT_LIBRARIES} + ${KDE4_KDEUI_LIBS} + ${KDE4_PLASMA_LIBS} + ${X11_LIBRARIES} + ${X11_Xrender_LIB} + ${X11_Xfixes_LIB} + ${X11_Xdamage_LIB} + ${X11_Xcomposite_LIB} + ${KDE4_SOLID_LIBS} + ${IDLE_DETECTION_LIB} +) + +install(TARGETS plasma_applet_systemtray DESTINATION ${PLUGIN_INSTALL_DIR}) +install(DIRECTORY "package/" DESTINATION "${DATA_INSTALL_DIR}/${data_install_dir}") +install(FILES plasma-applet-systemtray.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/applets/systemtray/Messages.sh b/plasma/generic/applets/systemtray/Messages.sh new file mode 100755 index 00000000..e761c32b --- /dev/null +++ b/plasma/generic/applets/systemtray/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp +$XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/plasma_applet_systemtray.pot +rm rc.cpp diff --git a/plasma/generic/applets/systemtray/TODO b/plasma/generic/applets/systemtray/TODO new file mode 100644 index 00000000..4a41987b --- /dev/null +++ b/plasma/generic/applets/systemtray/TODO @@ -0,0 +1,17 @@ +* Fix sizing on the desktop + +* Try overriding QPaintDevice to obtain the background pixmap + - Will get rid of the double painting + - Will possibly allow calling XSetBackgroundPixmap without having to call XClearWindow() + - Might allow paints that result in an identical background pixmap to be discarded + +* Remove X11EmbedContainer's dependency on SelectionManager + - X11EmbedContainer needs to be a self-contained QX11EmbedContainer implementation + +* Add checks for XRender presence and fail nicely if necessary +* Don't do all the extra QX11EmbedContainer hacks if the client window is of the same depth +* Handle taskId clashes better + +* Misbehavior of certain applets within the plasmoid protocol or vice-versa. (Still needs investigating) + +* Qt5: Remove WheelArea implementation, use Qt implementation instead \ No newline at end of file diff --git a/plasma/generic/applets/systemtray/config.h.in b/plasma/generic/applets/systemtray/config.h.in new file mode 100644 index 00000000..2b38ffb9 --- /dev/null +++ b/plasma/generic/applets/systemtray/config.h.in @@ -0,0 +1,4 @@ +#cmakedefine HAVE_LIBXSS + +// Path to directory containing qml stuff for systemtray +#define SYSTEMTRAY_DATA_INSTALL_DIR "${data_install_dir}" diff --git a/plasma/generic/applets/systemtray/core/manager.cpp b/plasma/generic/applets/systemtray/core/manager.cpp new file mode 100644 index 00000000..fc6f6a02 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/manager.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * manager.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2010 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "manager.h" + +#include +#include + +#include + +#include "protocol.h" +#include "task.h" + +#include "../protocols/fdo/fdoprotocol.h" +#include "../protocols/plasmoid/plasmoidtaskprotocol.h" +#include "../protocols/dbussystemtray/dbussystemtrayprotocol.h" + +#include + +namespace SystemTray +{ + +class Manager::Private +{ +public: + Private(Manager *manager) + : q(manager), + plasmoidProtocol(0) + { + } + + void setupProtocol(Protocol *protocol); + + Manager *q; + QList tasks; + PlasmoidProtocol *plasmoidProtocol; +}; + + +Manager::Manager() + : d(new Private(this)) +{ + d->plasmoidProtocol = new PlasmoidProtocol(this); + d->setupProtocol(d->plasmoidProtocol); + d->setupProtocol(new SystemTray::FdoProtocol(this)); + d->setupProtocol(new SystemTray::DBusSystemTrayProtocol(this)); +} + +Manager::~Manager() +{ + delete d; +} + + +QList Manager::tasks() const +{ + return d->tasks; +} + +void Manager::addTask(Task *task) +{ + connect(task, SIGNAL(destroyed(SystemTray::Task*)), this, SLOT(removeTask(SystemTray::Task*))); + connect(task, SIGNAL(changedStatus()), this, SIGNAL(taskStatusChanged())); + + kDebug() << task->name() << "(" << task->taskId() << ")"; + + d->tasks.append(task); + emit taskAdded(task); +} + +void Manager::removeTask(Task *task) +{ + d->tasks.removeAll(task); + disconnect(task, 0, this, 0); + emit taskRemoved(task); +} + +void Manager::forwardConstraintsEvent(Plasma::Constraints constraints, Plasma::Applet *host) +{ + d->plasmoidProtocol->forwardConstraintsEvent(constraints, host); +} + +void Manager::loadApplets(Plasma::Applet *parent) +{ + d->plasmoidProtocol->loadFromConfig(parent); +} + +void Manager::addApplet(const QString appletName, Plasma::Applet *parent) +{ + d->plasmoidProtocol->addApplet(appletName, 0, parent); +} + +void Manager::removeApplet(const QString appletName, Plasma::Applet *parent) +{ + d->plasmoidProtocol->removeApplet(appletName, parent); +} + +QStringList Manager::applets(Plasma::Applet *parent) const +{ + return d->plasmoidProtocol->applets(parent); +} + + +void Manager::Private::setupProtocol(Protocol *protocol) +{ + connect(protocol, SIGNAL(taskCreated(SystemTray::Task*)), q, SLOT(addTask(SystemTray::Task*))); + protocol->init(); +} + +} + + +#include "manager.moc" diff --git a/plasma/generic/applets/systemtray/core/manager.h b/plasma/generic/applets/systemtray/core/manager.h new file mode 100644 index 00000000..599a3fd9 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/manager.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * manager.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2010 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYMANAGER_H +#define SYSTEMTRAYMANAGER_H + +#include + +#include + +#include + +namespace Plasma +{ +class Applet; +} + +namespace SystemTray +{ + +class Applet; +class Notification; +class Task; +class Job; + +/** + * w + * @short Creator and amalgamator of the supported system tray specifications + **/ +class Manager : public QObject +{ + Q_OBJECT + +public: + Manager(); + ~Manager(); + + /** + * @return a list of all known Task instances + **/ + QList tasks() const; + + void forwardConstraintsEvent(Plasma::Constraints constraints, Plasma::Applet *host); + + void loadApplets(Plasma::Applet *parent); + + void addApplet(const QString appletName, Plasma::Applet *parent); + + void removeApplet(const QString appletName, Plasma::Applet *parent); + + QStringList applets(Plasma::Applet *parent) const; + +signals: + /** + * Emitted when a new task has been added + **/ + void taskAdded(SystemTray::Task *task); + + /** + * Emitted when status of task changes (such as it changing from + * Passive to NeedsAttention) + **/ + void taskStatusChanged(); + + /** + * Emitted when a task has been removed + **/ + void taskRemoved(SystemTray::Task *task); + +private slots: + void addTask(SystemTray::Task *task); + void removeTask(SystemTray::Task *task); + +private: + class Private; + Private* const d; + + friend class Applet; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/core/protocol.cpp b/plasma/generic/applets/systemtray/core/protocol.cpp new file mode 100644 index 00000000..a6af0c25 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/protocol.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + * taskprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "protocol.h" + + +namespace SystemTray +{ + +Protocol::Protocol(QObject *parent) + : QObject(parent) +{ +} + +} + +#include "protocol.moc" diff --git a/plasma/generic/applets/systemtray/core/protocol.h b/plasma/generic/applets/systemtray/core/protocol.h new file mode 100644 index 00000000..a6a56b53 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/protocol.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * taskprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYPROTOCOL_H +#define SYSTEMTRAYPROTOCOL_H + +#include + +namespace SystemTray +{ + class Job; + class Notification; + class Task; +} + + +namespace SystemTray +{ + +/** + * @short System tray protocol base class + * + * To support a new system tray protocol, this class and Task should be + * subclassed and the subclass of this class registered with the global + * Manager. The Protocol subclass should emit taskCreated() for each new + * task created. + **/ +class Protocol : public QObject +{ + Q_OBJECT +public: + explicit Protocol(QObject *parent); + + virtual void init() = 0; + +signals: + /** + * Signals that a new task has been created + **/ + void taskCreated(SystemTray::Task *task); + + /** + * Signals that a new notification has been created + **/ + void jobCreated(SystemTray::Job *job); + + /** + * Signals that a new notification has been created + **/ + void notificationCreated(SystemTray::Notification *notification); +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/core/task.cpp b/plasma/generic/applets/systemtray/core/task.cpp new file mode 100644 index 00000000..6e344ab7 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/task.cpp @@ -0,0 +1,198 @@ +/*************************************************************************** + * task.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "task.h" + +#include +#include + +#include "../ui/applet.h" + +namespace SystemTray +{ + + +class Task::Private +{ +public: + Private() + : status(Task::UnknownStatus), + category(Task::UnknownCategory) + { + } + + QHash widgetsByHost; + Task::Status status; + Task::Category category; + QString name; +}; + + +Task::Task(QObject *parent) + : QObject(parent), + d(new Private) +{ +} + +Task::~Task() +{ + emit destroyed(this); + foreach (QGraphicsWidget * widget, d->widgetsByHost) { + disconnect(widget, 0, this, 0); + // sometimes it appears that the widget will get scheduled for a repaint + // then it gets deleted here and QGraphicsScene doesn't get that straight + // in its bookkeeping and crashes occur; work around this by giving it a + // chance to schedule after the next paintfun + widget->deleteLater(); + } + delete d; +} + +QGraphicsWidget *Task::widget(Plasma::Applet *host, bool createIfNecessary) +{ + Q_ASSERT(host); + + QGraphicsWidget *widget = d->widgetsByHost.value(host); + + if (!widget && createIfNecessary) { + widget = createWidget(host); + + if (widget) { + d->widgetsByHost.insert(host, widget); + connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDeleted())); + } + } + + return widget; +} + +bool Task::isEmbeddable(SystemTray::Applet *host) +{ + if (!host) { + return false; + } + + return (d->widgetsByHost.value(host) || isEmbeddable()) && host->shownCategories().contains(category()); +} + +QHash Task::widgetsByHost() const +{ + return d->widgetsByHost; +} + +void Task::abandon(Plasma::Applet *host) +{ + QGraphicsWidget *widget = d->widgetsByHost.take(host); + if (widget) { + widget->deleteLater(); + } +} + +QGraphicsWidget *Task::forget(Plasma::Applet *host) +{ + return d->widgetsByHost.take(host); +} + +void Task::widgetDeleted() +{ + bool wasEmbeddable = isEmbeddable(); + + QGraphicsWidget *w = static_cast(sender()); + QMutableHashIterator it(d->widgetsByHost); + while (it.hasNext()) { + it.next(); + if (it.value() == w) { + it.remove(); + } + } + + if (!wasEmbeddable && isEmbeddable()) { + // we have to delay this call because some Task subclasses have a single widget that + // becomes embedabble at this point (e.g. FdoTaskWidget). if the signal is emitted + // immediately, another system tray will attempt to immediately embed it, and + // part of that process involves removing the item from any previous layouts. now, + // if that happens because a system tray is being deleted (removed, app exit, logout, etcS) + // then the previous parent layout will be a dangling pointer at this point and + // that will not get fixed up until everything is finished... so.. we delay the signal + QTimer::singleShot(0, this, SLOT(emitChanged())); + } +} + +void Task::emitChanged() +{ + emit changed(this); +} + +bool Task::isUsed() const +{ + return !d->widgetsByHost.isEmpty(); +} + +void Task::setCategory(Category category) +{ + if (d->category == category) { + return; + } + + d->category = category; + emit changedCategory(); + emit changed(this); +} + +Task::Category Task::category() const +{ + return d->category; +} + +void Task::setStatus(Status status) +{ + if (d->status == status) { + return; + } + + d->status = status; + emit changedStatus(); + emit changed(this); +} + +Task::Status Task::status() const +{ + return d->status; +} + +QString Task::name() const +{ + return d->name; +} + + +void Task::setName(QString name) +{ + if (d->name != name) { + d->name = name; + emit changedName(); + } +} + + +} + +#include "task.moc" diff --git a/plasma/generic/applets/systemtray/core/task.h b/plasma/generic/applets/systemtray/core/task.h new file mode 100644 index 00000000..6ae4ac99 --- /dev/null +++ b/plasma/generic/applets/systemtray/core/task.h @@ -0,0 +1,237 @@ +/*************************************************************************** + * task.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYTASK_H +#define SYSTEMTRAYTASK_H + +#include + +#include + +class QGraphicsWidget; + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +namespace SystemTray +{ + + class Applet; + +/** + * @short System tray task base class + * + * To support a new system tray protocol, Protocol and this class should + * be subclassed. + **/ +class Task : public QObject +{ + Q_OBJECT + + Q_PROPERTY(TaskType type READ type CONSTANT) + Q_PROPERTY(QString taskId READ taskId CONSTANT) + Q_PROPERTY(Status status READ status NOTIFY changedStatus) + Q_PROPERTY(QString name READ name NOTIFY changedName) + Q_PROPERTY(Category category READ category NOTIFY changedCategory) + +public: + enum Status { + UnknownStatus = 0, + Passive = 1, + Active = 2, + NeedsAttention = 3 + }; + Q_ENUMS(Status) + + enum Category { + UnknownCategory = 0, + ApplicationStatus = 1, + Communications = 2, + SystemServices = 3, + Hardware = 4 + }; + Q_ENUMS(Category) + + /** + * Derived classes should provide its type. We assume that number of different types of tasks is + * a limited value. So, it's easier to provide constants for each type of tasks than always + * try to cast classes. Moreover, these contants are used in QML code. + */ + enum TaskType { + TypePlasmoid, + TypeX11Task, + TypeStatusItem, + TypeUserDefined + }; + Q_ENUMS(TaskType) + + + virtual ~Task(); + + /** + * Creates a new graphics widget for this task + * + * isEmbeddable() should be checked before creating a new widget. + **/ + QGraphicsWidget* widget(Plasma::Applet *host, bool createIfNecessary = true); + + /** + * @return whether this task is embeddable; true if there is already a widget + * for this host. + */ + bool isEmbeddable(SystemTray::Applet *host); + + /** + * Returns whether this task can be embeddable + * + * Depending on the protocol, there may be circumstances under which + * a new widget can not be created. isEmbeddable() will return false + * under these circumstances. + **/ + virtual bool isEmbeddable() const = 0; + + /** + * Returns whether this task is represented as widget or it provides only information (icon, name, state, etc) + * @return true if task is represented as widget. + */ + virtual bool isWidget() const = 0; + + /** + * Returns the name of this task that should be presented to the user + **/ + QString name() const; + + void setName(QString name); + + /** + * Returns a unique identifier for this task + * + * The identifier is valid between restarts and so is safe to save + **/ + virtual QString taskId() const = 0; + + /** + * Returns an icon that can be associated with this task + * + * The icon returned is not necessarily the same icon that appears + * in the tray icon itself. + **/ + virtual QIcon icon() const = 0; + + /** + * @return true if this task is current being used, e.g. it has created + * widgets for one or more hosts + */ + bool isUsed() const; + + /** + * Sets the category of the task, UnknownCategory by default + * @arg category the category for this task + */ + void setCategory(Category category); + + /** + * @return the category of this task + */ + Category category() const; + + /** + * Sets the status of the task, UnknownStatus by default. + * @arg status the status for this task + */ + void setStatus(Status status); + + /** + * @return the status for this task + */ + Status status() const; + + /** + * This function must always return type of task (an integer value). This value must always be + * the same for each call of function. + * @return a type of task. + */ + virtual TaskType type() const = 0; + + + /** + * Can be used by the hostwhen they no longer wish to use the widget associated + * with the host. + */ + virtual void abandon(Plasma::Applet *host); + +Q_SIGNALS: + /** + * Emitted when something about the task has changed + **/ + //TODO: this should also state _what_ was changed so we can react more + // precisely (and therefore with greater efficiency) + void changed(SystemTray::Task *task); + + /** + * Special signal for changed status + */ + void changedStatus(); + + // if a category of task has been changed + void changedCategory(); + + // If a name of task has been changed + void changedName(); + + /// if visibility preference of task is changed + void changedVisibilityPreference(); + + /** + * Emitted when the task is about to be destroyed + **/ + void destroyed(SystemTray::Task *task); + +protected: + Task(QObject *parent = 0); + QHash widgetsByHost() const; + QGraphicsWidget *forget(Plasma::Applet *host); + + /** + * Called when a new widget is required + * + * Subclasses should implement this to return a graphics widget that + * handles all user interaction with the task. Ownership of the + * created widget is handled automatically so subclasses should not + * delete the created widget. + **/ + virtual QGraphicsWidget* createWidget(Plasma::Applet *host) = 0; + +private slots: + void widgetDeleted(); + void emitChanged(); + +private: + class Private; + Private* const d; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/package/contents/code/IconsList.js b/plasma/generic/applets/systemtray/package/contents/code/IconsList.js new file mode 100644 index 00000000..db77b46b --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/code/IconsList.js @@ -0,0 +1,34 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ +// This JS file is intended for IconsList.qml only as a stuff + +var tasks = {} + +function findMax() { + var max = 0 + for (var i in tasks) { + if (max < tasks[i]) + max = tasks[i] + } + return max +} diff --git a/plasma/generic/applets/systemtray/package/contents/code/TasksSet.js b/plasma/generic/applets/systemtray/package/contents/code/TasksSet.js new file mode 100644 index 00000000..12fd6513 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/code/TasksSet.js @@ -0,0 +1,130 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +// This is stateless library, it may be shared between several qml files +.pragma library + + +// Represents task +var Task = function(id, index, category, data) +{ + this.id = id + this.index = index + this.category = category + this.data = data +} + + +/** + * Creates new set of tasks + * @param categories_list a list of categories, this list gives order of categories + */ +var TasksSet = function(categories_list) +{ + var _categories = categories_list + var _tasks = {} // internal set of tasks + var _tasks_as_array = [] // array of tasks + + // number of tasks in each location with the same category + var _cat_sizes = {} + for (var i = 0, s = _categories.length; i < s; ++i) { + _cat_sizes[_categories[i]] = 0 + } + + // Finds correct model index for new task + function _findIndex(category) + { + var index = 0 // index is a sum of numbers of tasks groupped by category + for (var c = 0, l = _categories.length; c < l && _categories[c] !== category; ++c) + index += _cat_sizes[_categories[c]] + return index + } + + // Increments model indexes for tasks + function _incIndexes(index) + { + for (var i = 0, len = _tasks_as_array.length; i < len; ++i) { + var t = _tasks_as_array[i] + if (t.index >= index) + t.index++ + } + } + + // Decrement indexes of tasks + function _decIndexes(index) + { + for (var i = 0, len = _tasks_as_array.length; i < len; ++i) { + var t = _tasks_as_array[i] + if (t.index >= index) + t.index-- + } + } + + // Returns object representing properties of task + function _get(id) { + return _tasks[id] + } + this.get = _get + + /** + * Adds new task to set + * @param id unique id of task + * @param category a category of task + * @param data an additional data to accociate with task + * @return a new task object + */ + function _add(id, category, data) + { + var index = _findIndex(category) // first of all, find correct model index to insert task + _incIndexes(index) + var t = new Task(id, index, category, data) + _tasks[id] = t + _cat_sizes[category]++ + _tasks_as_array.push(t) + return t + } + this.add = _add + + /** + * Removes tasks from set + * @param id an unique ID of task + * @return an object containing properties of old task + */ + function _remove(id) + { + var t = _tasks[id] //find task using ID + // remove task from array, we remove last item and move it to new place + var arr_index = 0 + var len = _tasks_as_array.length + for (; _tasks_as_array[arr_index] !== t; ++arr_index); + if (arr_index < len-1) + _tasks_as_array[arr_index] = _tasks_as_array[len-1] // move item + _tasks_as_array.pop() + // remove task from internal set & decrement indexes + _cat_sizes[t.category]-- + delete _tasks[id] + _decIndexes(t.index) + return t + } + this.remove = _remove +} diff --git a/plasma/generic/applets/systemtray/package/contents/code/main.js b/plasma/generic/applets/systemtray/package/contents/code/main.js new file mode 100644 index 00000000..f5885e9c --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/code/main.js @@ -0,0 +1,74 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +// This isn't a stateless library, it is intended only as a stuff for main.qml + +// Constants +var ICONS_SIZE = 24 // Size of icons, icons are square i.e. width == height +var MINIMUM_SIZE = 8 // minimum size of widget +var ARROW_MARGINS = 5 // margins for an arrow +var BLINK_INTERVAL = 750 // time interval of blinking +var TASK_NOTIFICATIONS_TYPEID = "org.kde.notifications" +var USE_GRID_IN_POPUP = false // true if in popup icons should be placed like a grid without names + + +// [const] Location of item (model for icon) +var LOCATION_TRAY = 0 +var LOCATION_POPUP = LOCATION_TRAY + 1 +var LOCATION_NOTIFICATION = LOCATION_POPUP + 1 + + +// [const] List of possible locations +var LOCATIONS = [ + LOCATION_TRAY, + LOCATION_POPUP, + LOCATION_NOTIFICATION +] + +// [const] Number of locations +var LOCATIONS_NUMBER = LOCATIONS.length + +// This list determines order of categories of tasks +var CATEGORIES = [ + UnknownCategory, + ApplicationStatus, + Communications, + SystemServices, + Hardware +] + +// all available tasks by their id +var allTasks = {} + +// Set of tasks sets, each set for one location (area) +var tasks = new Array(LOCATIONS_NUMBER) + + +// Returns location of task by ID of task +function findLocation(id) +{ + for (var i = 0; i < LOCATIONS_NUMBER; ++i) { + if (tasks[i].get(id)) + return LOCATIONS[i] + } +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/ArrowArea.qml b/plasma/generic/applets/systemtray/package/contents/ui/ArrowArea.qml new file mode 100644 index 00000000..fd074694 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/ArrowArea.qml @@ -0,0 +1,135 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.extras 0.1 as PlasmaExtras + +Item { + id: arrow_area + + property variant content; ///< content of popup dialog + property int arrow_size: 12 // size of an icon + + MouseArea { + anchors.fill: parent + onClicked: togglePopup() + onPressed: PlasmaExtras.PressedAnimation { targetItem: arrow_widget } + onReleased: PlasmaExtras.ReleasedAnimation { targetItem: arrow_widget } + } + + PlasmaCore.SvgItem { + + id: arrow_widget + + anchors.centerIn: parent + width: arrow_size + height: width + + svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } + elementId: "left-arrow" + } + + // Tooltip for arrow ----------------------------------------------------------------------------------------------- + PlasmaCore.ToolTip { + id: arrow_tooltip + target: arrow_widget + subText: dialog.visible ? i18n("Hide icons") : i18n("Show hidden icons") + } + + // Popup dialog (window) ------------------------------------------------------------------------------------------- + PlasmaCore.Dialog { + id: dialog + visible: false + mainItem: content + location: plasmoid.location + windowFlags: Qt.WindowStaysOnTopHint + + onActiveWindowChanged: dialog.visible = activeWindow // hide window if it deactivates + + + // We have to move dialog if its size is changed + onHeightChanged: updatePosition() + onWidthChanged: updatePosition() + + onVisibleChanged: { + if (visible) { + if (dialog.windowId) + plasmoid.hideFromTaskbar(dialog.windowId) + updatePosition() + } + } + + function updatePosition() { + var pos = dialog.popupPosition(arrow_area, Qt.AlignCenter) + x = pos.x + y = pos.y + } + } + + + function togglePopup() { + if (dialog.visible) { + dialog.visible = false + return + } + dialog.visible = true + dialog.activateWindow() + } + + + states: [ + State { + name: "LEFT_EDGE" + PropertyChanges { + target: arrow_widget + elementId: dialog.visible ? "left-arrow" : "right-arrow" + } + }, + + State { + name: "RIGHT_EDGE" + PropertyChanges { + target: arrow_widget + elementId: dialog.visible ? "right-arrow" : "left-arrow" + } + }, + + State { + name: "TOP_EDGE" + PropertyChanges { + target: arrow_widget + elementId: dialog.visible ? "up-arrow" : "down-arrow" + } + }, + + State { + name: "BOTTOM_EDGE" + PropertyChanges { + target: arrow_widget + elementId: dialog.visible ? "down-arrow" : "up-arrow" + } + } + ] + +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/IconsGrid.qml b/plasma/generic/applets/systemtray/package/contents/ui/IconsGrid.qml new file mode 100644 index 00000000..8448f304 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/IconsGrid.qml @@ -0,0 +1,128 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +import QtQuick 1.1 + +Item { + id: root_item + + property int icons_size: 24 ///< Size of icons, icons are square i.e. width == height + property int icons_margins: 2 ///< Margins for icons + property alias icons_number: grid.count ///< [readonly] Number of icons + property alias model: grid.model; ///< Model for grid + property int cols_num: 0 ///< [readonly] Number of columns + property int rows_num: 0 ///< [readonly] Number of rows + property int min_width: cols_num*cell_size ///< [readonly] minimum width of component required to show whole grid + property int min_height: rows_num*cell_size ///< [readonly] minimum height of compontn required to show whole grid + property int cell_size: icons_size + 2*icons_margins ///< [readonly] size of grid cell + + property int _sqrt: 0 + property int _sqrt2: _sqrt*_sqrt + + GridView { + id: grid + anchors.centerIn: parent + width: min_width + height: min_height + + cellWidth: cell_size + cellHeight: cellWidth + interactive: false + delegate: TrayIcon { width: grid.cellWidth; height: grid.cellHeight } + } + + states: [ + /// Base state for square states (for internal use only) + State { + name: "__SQR" + + PropertyChanges { + target: root_item + _sqrt: Math.floor(Math.sqrt(grid.count)) + } + }, + + /// Vertical layout of grid + State { + name: "VERT" + + PropertyChanges { + target: root_item + _sqrt: 0 + cols_num: grid.count*cell_size <= width ? grid.count : Math.max(1, Math.floor(width / cell_size)) + rows_num: cols_num > 0 ? (Math.max(1, Math.floor(grid.count / cols_num)) + (grid.count % cols_num ? 1 : 0)) : 0 + } + PropertyChanges { + target: grid + flow: GridView.LeftToRight + } + }, + + /// Horizontal layout of grid + State { + name: "HORZ" + + PropertyChanges { + target: root_item + _sqrt: 0 + rows_num: grid.count*cell_size <= height ? grid.count : Math.max(1, Math.floor(height / cell_size)) + cols_num: rows_num > 0 ? (Math.max(1, Math.floor(grid.count / rows_num)) + (grid.count % rows_num ? 1 : 0)) : 0 + } + PropertyChanges { + target: grid + flow: GridView.TopToBottom + } + }, + + /// Square layout of grid with horizontal flow + State { + name: "SQR_H" + extend: "__SQR" + + PropertyChanges { + target: root_item + cols_num: ( grid.count > _sqrt2 ? _sqrt + 1 : _sqrt ) + rows_num: ( grid.count > _sqrt2 + _sqrt ? _sqrt + 1 : _sqrt ) + } + PropertyChanges { + target: grid + flow: GridView.LeftToRight + } + }, + + /// Square layout of grid with vertical flow + State { + name: "SQR_V" + extend: "__SQR" + PropertyChanges { + target: root_item + rows_num: ( grid.count > _sqrt2 ? _sqrt + 1 : _sqrt ) + cols_num: ( grid.count > _sqrt2 + _sqrt ? _sqrt + 1 : _sqrt ) + } + PropertyChanges { + target: grid + flow: GridView.TopToBottom + } + } + ] +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml b/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml new file mode 100644 index 00000000..d72733c1 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/IconsList.qml @@ -0,0 +1,149 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +import QtQuick 1.1 +import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets +import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.extras 0.1 as PlasmaExtras +import Private 0.1 + +import "../code/IconsList.js" as IconsListJS + +MouseArea { + id: root_item + + property int icons_size: 24 ///< Size of icons, icons are square i.e. width == height + property int icons_margins: icons_size/6 ///< Margins for icons + property alias icons_number: repeater.count ///< [readonly] Number of icons + property alias model: repeater.model; ///< Model for grid + property int cell_size: icons_size + 2*icons_margins ///< [readonly] size of grid cell + + //Those properties are used by PlasmaCore.Dialog for size hints + property int extraHorizMargins: delegate_highlight.marginHints.right + property int minimumWidth: extraHorizMargins + layoutColumn.childrenRect.width ///< [readonly] minimum width of component required to show whole grid + property int minimumHeight:layoutColumn.childrenRect.height ///< [readonly] minimum height of compontn required to show whole grid + property int maximumWidth: minimumWidth + property int maximumHeight: minimumHeight + + hoverEnabled: true + + Component { + id: delegate_task + + MouseRedirectArea { + id: delegate_root_item + width: Math.max(minimumWidth - extraHorizMargins, childrenRect.width) + height: childrenRect.height + + // we redirect some events to IconWidget or applet + target: task.type == TypeStatusItem ? ui_item.getMouseArea() : task + applet: plasmoid + + // Next events we process manually + onClickMiddle: ui_item.click(Qt.MiddleButton) + onClickRight: ui_item.click(Qt.RightButton) + onScrollVert: ui_item.scrollVert(delta) + onScrollHorz: ui_item.scrollHorz(delta) + onEntered: { + delegate_highlight.y = delegate_root_item.y + } + + Row { + Item { + id: tray_icon + + width: cell_size + height: width + + TrayIcon { + anchors.centerIn: parent + width: icons_size + height: width + } + } + + PlasmaComponents.Label { + id: name_item + anchors.verticalCenter: tray_icon.verticalCenter + wrapMode: Text.NoWrap + text: task.name + } + } + + + Component.onCompleted: { + var text_width = name_item.width + IconsListJS.tasks[delegate_root_item] = text_width + } + + Component.onDestruction: { + delete IconsListJS.tasks[delegate_root_item] + } + + Connections { + target: task + onChangedName: { + // if name is changed => we should recalculate width of popup + IconsListJS.tasks[delegate_root_item] = name_item.width + } + } + + } + + } + + PlasmaComponents.Highlight { + id: delegate_highlight + height: cell_size + width: minimumWidth + opacity: root_item.containsMouse + + Behavior on opacity { + NumberAnimation { + duration: 150 + easing: Easing.InOutQuad + } + } + Behavior on y { + NumberAnimation { + duration: 250 + easing: Easing.InOutQuad + } + } + } + + + Column { + id: layoutColumn + spacing: 0 + Repeater { + id: repeater + delegate: delegate_task + } + + } + + Component.onCompleted: { + console.log("========================> " + " " + minimumWidth + " " + layoutColumn.childrenRect.width); + } +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml b/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml new file mode 100644 index 00000000..8e06b5e8 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/StatusNotifierItem.qml @@ -0,0 +1,276 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +import QtQuick 1.1 +import Private 0.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.qtextracomponents 0.1 as QtExtraComponents + + +Item { + id: root_item + + property int blink_interval: 1000 // interval of blinking (if status of task is NeedsAttention) + property variant task: null // task that provides information for item + + property bool __has_task: task ? true : false + property string __icon_name: __has_task ? task.iconName : "" + property string __att_icon_name: __has_task ? task.attIconName : "" + property variant __icon: __has_task ? task.icon : QIcon("default") + property variant __att_icon: __has_task ? task.attIcon : __getDefaultIcon() + property string __overlay_icon_name: __has_task ? task.overlayIconName : "" + property string __movie_path: __has_task ? task.moviePath : "" + property int __status: __has_task ? task.status : UnknownStatus + //Hack for activating only items that has been clicked by ourselves + property variant __clickTime: 0; + + // Public functions ================================================================================================ + function click(buttons) { + __processClick(buttons, mouse_area) + } + + function scrollHorz(delta) { + task.activateHorzScroll(delta) + } + + function scrollVert(delta) { + task.activateVertScroll(delta) + } + + function getMouseArea() { + return mouse_area + } + + Connections { + target: task + + onChangedShortcut: { + // update shortcut for icon widget + if (!icon_widget.action) + return + plasmoid.updateShortcutAction(icon_widget.action, task.shortcut) + icon_widget.action.triggered.disconnect(__onActivatedShortcut) // disconnect old signals + icon_widget.action.triggered.connect(__onActivatedShortcut) + } + + onShowContextMenu: { + //refuse events for elapsed times < 1 second + var time = new Date().getTime(); + if (time - __clickTime < 1000) { + plasmoid.showMenu(menu, x, y, root_item) + } + } + } + + function __onActivatedShortcut() { + __processClick(Qt.LeftButton, icon_widget) + } + + + // Timer for blink effect ========================================================================================== + Timer { + id: timer_blink + running: false + repeat: true + interval: blink_interval + + property bool is_att_icon: false + + onTriggered: { + icon_widget.source = is_att_icon ? __getAttentionIcon() : __getDefaultIcon() + is_att_icon = !is_att_icon + } + } + + + // TODO: remove wheel area in QtQuick 2.0 + QtExtraComponents.MouseEventListener { + id: wheel_area + anchors.fill: parent + enabled: __has_task + visible: __has_task + z: -2 + + // Mouse events handlers =========================================================================================== + MouseArea { + id: mouse_area + anchors.fill: parent + hoverEnabled: true + // if no task passed we don't accept any buttons, if icon_widget is visible we pass left button to it + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + enabled: __has_task + visible: __has_task + + onClicked: __processClick(mouse.button, mouse_area) + + // Widget for icon if no animation is requested + PlasmaCore.IconItem { + id: icon_widget + + anchors.fill: parent + + property QtObject action: __has_task ? plasmoid.createShortcutAction(task.objectName + "-" + plasmoid.id) : null + + visible: false + active: mouse_area.containsMouse + + // Overlay icon + Image { + width: 10 // we fix size of an overlay icon + height: width + anchors { right: parent.right; bottom: parent.bottom } + + sourceSize.width: width + sourceSize.height: width + fillMode: Image.PreserveAspectFit + smooth: true + source: "image://icon/" + __overlay_icon_name + visible: __overlay_icon_name + } + + Component.onDestruction: { + var act = icon_widget.action + icon_widget.action = null + plasmoid.destroyShortcutAction(act) + } + } + + // Animation (Movie icon) + AnimatedImage { + id: animation + + anchors.fill: parent + + playing: false + visible: false + smooth: true + source: __movie_path + } + } + onWheelMoved: { + if (wheel.orientation === Qt.Horizontal) + task.activateHorzScroll(wheel.delta) + else + task.activateVertScroll(wheel.delta) + } + // Tooltip ========================================================================================================= + PlasmaCore.ToolTip { + id: tooltip + target: wheel_area + mainText: __has_task ? task.tooltipTitle : "" + subText: __has_task ? task.tooltipText : "" + image: __has_task ? task.tooltipIcon : "" + } + } + + // Functions ======================================================================================================= + function __getDefaultIcon() { + return task.customIcon(__icon_name != "" ? __icon_name : __icon) + } + + function __getAttentionIcon() { + return task.customIcon(__att_icon_name != "" ? __att_icon_name : __att_icon) + } + + function __processClick(buttons, item) { + __clickTime = (new Date()).getTime(); + var pos = plasmoid.popupPosition(item) + switch (buttons) { + case Qt.LeftButton: task.activate1(pos.x, pos.y); break + case Qt.RightButton: task.activateContextMenu(pos.x, pos.y); break + case Qt.MiddleButton: task.activate2(pos.x, pos.y); break + } + } + + // States ========================================================================================================== + states: [ + // Static icon + State { + name: "__STATIC" + when: __status !== NeedsAttention + PropertyChanges { + target: timer_blink + running: false + } + PropertyChanges { + target: icon_widget + source: __getDefaultIcon() + visible: true + } + PropertyChanges { + target: animation + visible: false + playing: false + } + StateChangeScript { + script: tooltip.target = icon_widget // binding to property doesn't work + } + }, + // Attention icon + State { + name: "__BLINK" + when: __status === NeedsAttention && !__movie_path + PropertyChanges { + target: icon_widget + source: __getAttentionIcon() + visible: true + } + PropertyChanges { + target: timer_blink + running: true + is_att_icon: false + } + PropertyChanges { + target: animation + visible: false + playing: false + } + StateChangeScript { + script: tooltip.target = icon_widget + } + }, + // Animation icon + State { + name: "__ANIM" + when: __status === NeedsAttention && __movie_path + PropertyChanges { + target: timer_blink + running: false + } + PropertyChanges { + target: icon_widget + source: __getDefaultIcon() + visible: false + } + PropertyChanges { + target: animation + visible: true + playing: true + } + StateChangeScript { + script: tooltip.target = animation + } + } + ] + +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/TrayIcon.qml b/plasma/generic/applets/systemtray/package/contents/ui/TrayIcon.qml new file mode 100644 index 00000000..7b69ebea --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/TrayIcon.qml @@ -0,0 +1,31 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ +import QtQuick 1.1 + +Item { + id: root_item + + Component.onCompleted: { + ui_item.parent = root_item + } +} diff --git a/plasma/generic/applets/systemtray/package/contents/ui/main.qml b/plasma/generic/applets/systemtray/package/contents/ui/main.qml new file mode 100644 index 00000000..209091b0 --- /dev/null +++ b/plasma/generic/applets/systemtray/package/contents/ui/main.qml @@ -0,0 +1,347 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: LGPLv2+ + * Authors: Dmitry Ashkadov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **********************************************************************************************************************/ + +import QtQuick 1.1 +import Private 0.1 + +import "../code/TasksSet.js" as TasksSet +import "../code/main.js" as JS // stuff & JS additions + +Item { + id: root_item // represents available space on screen + + // This 2 properties must be defined because we use states to set their values + property int minimumWidth: JS.MINIMUM_SIZE + property int minimumHeight: JS.MINIMUM_SIZE + + property int iconSize: Math.min(root_item.width, Math.min(root_item.height, theme.defaultFont.mSize.height < 20 ? 24 : theme.largeIconSize)) //Math.min(root_item.width, Math.min(root_item.height, JS.ICONS_SIZE)) + + // Data Models + property list models: [ + ListModel {id: model_tray}, + ListModel {id: model_popup}, + ListModel {id: model_notifications} + ] + + Connections { + target: plasmoid + + onNewTask: { + // create declarative item + var component = (task.type === TypeStatusItem ? component_status_item : component_widget) + var props = {"task": task} + var item = component.createObject(null, props) + if (item) { + var loc = getLocationForTask(task) + var task_id = plasmoid.getUniqueId(task) + JS.allTasks[task_id] = task + var t = JS.tasks[loc].add(task_id, task.category, item) + models[loc].insert(t.index, {"task": task, "ui_item": item}) + } + } + + onDeletedTask: { + var task_id = plasmoid.getUniqueId(task) + var loc = JS.findLocation(task_id) + var t = JS.tasks[loc].remove(task_id) + models[loc].remove(t.index) + t.data.destroy() // destroy item / we have to destroy it manually because we don't provide parent at initialization + delete JS.allTasks[task_id] + } + + onVisibilityPreferenceChanged: { + // move all tasks to their new location + for (var task_id in JS.allTasks) { + var task = JS.allTasks[task_id] + moveTaskToLocation(task, getLocationForTask(task)) + } + } + + onActivate: arrow_area.togglePopup() + } + + + Component.onCompleted: { + // create sets for tasks + for (var i = 0; i < JS.LOCATIONS_NUMBER; ++i) + JS.tasks[JS.LOCATIONS[i]] = new TasksSet.TasksSet(JS.CATEGORIES) + } + + Item { + id: content_item // represents rectangle containing all visual elements on panel + anchors.centerIn: parent + + // Notifications area in panel part of tray + IconsGrid { + id: notifications_area + icons_size: root_item.iconSize + model: model_notifications + } + + // Tray area that is in panel + IconsGrid { + id: tray_area + icons_size: root_item.iconSize + model: model_tray + } + + // An area that contains arrow + ArrowArea { + id: arrow_area + visible: model_popup.count > 0 + + content: IconsList { + id: popup_area + icons_size: root_item.iconSize + model: model_popup + } + } + } + + // Delegates for views ============================================================================================= + Component { + id: component_status_item + + StatusNotifierItem { + id: status_item + + blink_interval: JS.BLINK_INTERVAL + visible: task !== null + width: root_item.iconSize + height: width + anchors.centerIn: parent + + Connections { + target: task + onChangedStatus: moveTaskToLocation(task, getLocationForTask(task)) + onChangedVisibilityPreference: moveTaskToLocation(task, getLocationForTask(task)) + } + } + } + + Component { + id: component_widget + + WidgetItem { + id: widget_item + + applet: plasmoid + visible: task !== null + width: root_item.iconSize + height: width + anchors.centerIn: parent + + Connections { + target: task + onChangedStatus: moveTaskToLocation(task, getLocationForTask(task)) + onChangedVisibilityPreference: moveTaskToLocation(task, getLocationForTask(task)) + } + } + } + + // Funtions ======================================================================================================== + function getLocationForTask(task) { + var loc = getDefaultLocationForTask(task); + if (loc === JS.LOCATION_TRAY && task.taskId == JS.TASK_NOTIFICATIONS_TYPEID) { + // redefine location for notifications applet + return JS.LOCATION_NOTIFICATION; + } + return loc; + } + + /// Returns location depending on status and hide state of task + function getDefaultLocationForTask(task) { + var vis_pref = plasmoid.getVisibilityPreference(task); + + if (task.status === NeedsAttention || vis_pref === AlwaysShown) { + return JS.LOCATION_TRAY; + } + + if (vis_pref === AlwaysHidden || (task.status !== Active && task.status !== UnknownStatus)) { + return JS.LOCATION_POPUP; + } + + return JS.LOCATION_TRAY; + } + + /// Moves task to specified location + function moveTaskToLocation(task, loc) { + var task_id = plasmoid.getUniqueId(task); + var old_loc = JS.findLocation(task_id); + + if (old_loc === loc) { + return + } + + // remove from old location + var t = JS.tasks[old_loc].remove(task_id); + models[old_loc].remove(t.index); + + // add to new model + t = JS.tasks[loc].add(task_id, t.category, t.data); + models[loc].insert(t.index, {"task": task, "ui_item": t.data}); + } + + + // States ========================================================================================================== + states: [ + State { + name: "_HORZ" // it is shared state for HORZ and FLOAT + AnchorChanges { + target: arrow_area + anchors { left: tray_area.right; top: content_item.top; bottom: content_item.bottom } + } + PropertyChanges { + target: arrow_area + // it's strange but if width of arrow area is set to 0 then this may cause crashing of plasma during resising of panel (somewhere in QtDeclarative) + width: arrow_area.visible ? arrow_area.arrow_size + 2*JS.ARROW_MARGINS : 1 + state: plasmoid.location === TopEdge ? "TOP_EDGE" : "BOTTOM_EDGE" + } + PropertyChanges { + target: popup_area + state: JS.USE_GRID_IN_POPUP ? "SQR_H" : "" + } + }, + + State { + name: "HORZ" + extend: "_HORZ" + when: (plasmoid.formFactor === Horizontal) + + AnchorChanges { + target: notifications_area + anchors { top: content_item.top; bottom: content_item.bottom; left: content_item.left } + } + PropertyChanges { + target: notifications_area + state: "HORZ" + width: notifications_area.min_width + } + AnchorChanges { + target: tray_area + anchors { left: notifications_area.right; top: content_item.top; bottom: content_item.bottom } + } + PropertyChanges { + target: tray_area + state: "HORZ" + width: tray_area.min_width + } + PropertyChanges { + target: content_item + width: notifications_area.width + tray_area.width + arrow_area.width + height: root_item.height + } + PropertyChanges { + target: root_item + minimumWidth: content_item.width + minimumHeight: JS.MINIMUM_SIZE + } + }, + + State { + name: "VERT" + when: (plasmoid.formFactor === Vertical) + + AnchorChanges { + target: notifications_area + anchors { left: content_item.left; right: content_item.right; top: content_item.top } + } + PropertyChanges { + target: notifications_area + state: "VERT" + height: notifications_area.min_height + } + AnchorChanges { + target: tray_area + anchors { left: content_item.left; right: content_item.right; top: notifications_area.bottom } + } + PropertyChanges { + target: tray_area + state: "VERT" + height: tray_area.min_height + } + AnchorChanges { + target: arrow_area + anchors { left: content_item.left; right: content_item.right; top: tray_area.bottom } + } + PropertyChanges { + target: arrow_area + height: arrow_area.visible ? arrow_area.arrow_size + 2*JS.ARROW_MARGINS : 1 + state: plasmoid.location === LeftEdge ? "LEFT_EDGE" : "RIGHT_EDGE" + } + PropertyChanges { + target: popup_area + state: JS.USE_GRID_IN_POPUP ? "SQR_V" : "" + } + PropertyChanges { + target: content_item + width: root_item.width + height: notifications_area.height + tray_area.height + arrow_area.height + } + PropertyChanges { + target: root_item + minimumWidth: JS.MINIMUM_SIZE + minimumHeight: content_item.height + } + }, + + State { + name: "FLOAT" + extend: "_HORZ" + when: (plasmoid.formFactor === Floating) + + PropertyChanges { + target: notifications_area + state: "SQR_H" + width: notifications_area.min_width + height: notifications_area.min_height + } + AnchorChanges { + target: notifications_area + anchors { left: content_item.left; verticalCenter: content_item.verticalCenter } + } + AnchorChanges { + target: tray_area + anchors { left: notifications_area.right; verticalCenter: content_item.verticalCenter } + } + PropertyChanges { + target: tray_area + state: "SQR_V" + width: tray_area.min_width + height: tray_area.min_height + } + PropertyChanges { + target: content_item + width: notifications_area.width + tray_area.width + arrow_area.width + height: Math.max(notifications_area.min_height, tray_area.min_height, arrow_area.arrow_size) + } + PropertyChanges { + target: root_item + minimumWidth: content_item.width + minimumHeight: content_item.height + } + } + ] + + +} diff --git a/plasma/generic/applets/systemtray/plasma-applet-systemtray.desktop b/plasma/generic/applets/systemtray/plasma-applet-systemtray.desktop new file mode 100644 index 00000000..e7799142 --- /dev/null +++ b/plasma/generic/applets/systemtray/plasma-applet-systemtray.desktop @@ -0,0 +1,176 @@ +[Desktop Entry] +Name=System Tray +Name[af]=Stelsellaai +Name[ar]=صينية النظام +Name[ast]=Bandexa del sistema +Name[be]=Сістэмны трэй +Name[be@latin]=Systemny trej +Name[bg]=Системен панел +Name[bn]=সিস্টেম ট্রে +Name[bn_IN]=সিস্টেম ট্রে +Name[br]=Barlenn ar reizhiad +Name[bs]=sistemska kaseta +Name[ca]=Safata del sistema +Name[ca@valencia]=Safata del sistema +Name[cs]=Systémová část panelu +Name[csb]=Systemòwi zabiérnik +Name[cy]=Bar Tasgau +Name[da]=Statusområde +Name[de]=Systemabschnitt der Kontrollleiste +Name[el]=Πλαίσιο συστήματος +Name[en_GB]=System Tray +Name[eo]=Sistempleto +Name[es]=Bandeja del sistema +Name[et]=Süsteemne dokk +Name[eu]=Sistema-erretilua +Name[fa]=سینی سیستم +Name[fi]=Ilmoitusalue +Name[fr]=Boîte à miniatures +Name[fy]=Systeemfak +Name[ga]=Tráidire an Chórais +Name[gl]=Bandexa do sistema +Name[gu]=સિસ્ટમ ટ્રે +Name[he]=מגש המערכת +Name[hi]=तंत्र तश्तरी +Name[hne]=तंत्र तस्तरी +Name[hr]=Sistemski blok +Name[hsb]=Systemowa wotkładka +Name[hu]=Paneltálca +Name[ia]=Tabuliero de systema +Name[id]=Baki Sistem +Name[is]=Kerfisbakki +Name[it]=Vassoio di sistema +Name[ja]=システムトレイ +Name[ka]=სისტემური პანელი +Name[kk]=Жүйелік сөре +Name[km]=ថាស​ប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥಾ ಖಾನೆ (ಟ್ರೇ) +Name[ko]=시스템 트레이 +Name[lt]=Sistemos dėklas +Name[lv]=Sistēmas ikonu josla +Name[mai]=तंत्र तश्तरी +Name[mk]=Системска лента +Name[ml]=സിസ്റ്റം ട്രേ +Name[mr]=प्रणाली ट्रे +Name[ms]=Dulang Sistem +Name[nb]=Systemkurv +Name[nds]=Paneel-Systeemafsnitt +Name[ne]=प्रणाली ट्रे +Name[nl]=Systeemvak +Name[nn]=Systemtrau +Name[or]=ତନ୍ତ୍ର ଧାରକ +Name[pa]=ਸਿਸਟਮ ਟਰੇ +Name[pl]=Tacka systemowa +Name[pt]=Bandeja do Sistema +Name[pt_BR]=Área de notificação +Name[ro]=Tavă de sistem +Name[ru]=Системный лоток +Name[se]=Vuogádatgárcu +Name[si]=පද්ධතිය තැටිය +Name[sk]=Systémová lišta +Name[sl]=Sistemska vrstica +Name[sr]=системска касета +Name[sr@ijekavian]=системска касета +Name[sr@ijekavianlatin]=sistemska kaseta +Name[sr@latin]=sistemska kaseta +Name[sv]=Systembricka +Name[ta]=சாதன தட்டு +Name[te]=వ్యవస్థ ట్రె +Name[tg]=Системный лоток +Name[th]=ถาดระบบ +Name[tr]=Sistem Çekmecesi +Name[ug]=سىستېما قوندىقى +Name[uk]=Системний лоток +Name[vi]=Khay hệ thống +Name[wa]=Boesse ås imådjetes sistinme +Name[xh]=Itreyi Yendlela yokusebenza +Name[x-test]=xxSystem Trayxx +Name[zh_CN]=系统托盘 +Name[zh_TW]=系統匣 +Comment=Access hidden applications minimized in the system tray +Comment[ar]=انفذ إلى التطبيقات المخفية المصغرة في صينية النظام +Comment[ast]=Acceder a aplicaciones anubríes minimizaes na bandexa del sistema +Comment[be@latin]=Dostup da schavanych u systemnym trei aplikacyjaŭ +Comment[bg]=Достъп до минимизираните в системния панел програми +Comment[bs]=Pristup skrivenim programima minimizovanim u sistemsku kasetu +Comment[ca]=Accés a les aplicacions minimitzades ocultes en la safata del sistema +Comment[ca@valencia]=Accés a les aplicacions minimitzades ocultes en la safata del sistema +Comment[cs]=Přístup ke skrytým aplikacím, které jsou minimalizované v systémové oblasti +Comment[csb]=Dôwô mòżnotã taceniô ë minimalizowaniô aplikacëjów do systemòwégò zabiérnika +Comment[da]=Tilgå skjulte programmer der er minimeret i statusområdet +Comment[de]=Ermöglicht den Zugriff auf Programme, die im Systemabschnitt der Kontrollleiste laufen. +Comment[el]=Πρόσβαση κρυφών εφαρμογών ελαχιστοποιημένων στο πλαίσιο συστήματος +Comment[en_GB]=Access hidden applications minimised in the system tray +Comment[eo]=Atingi kaŝitan minimumigitajn aplikaĵojn en la taskopleto +Comment[es]=Acceder a aplicaciones ocultas minimizadas en la bandeja del sistema +Comment[et]=Süsteemsesse salve minimeeritud peidetud rakenduste kasutamine +Comment[eu]=Atzitu sistema-erretiluan ikonotuta dauden ezkutuko aplikazioak +Comment[fi]=Hae piilotettuja sovelluksia, jotka on pienennetty ilmoitusalueelle +Comment[fr]=Accède aux applications cachées et réduites dans la boîte à miniatures +Comment[fy]=Jou tagong ta programma's dy't yn it systeemfak rinne +Comment[ga]=Rochtain feidhmchláir atá íoslaghdaithe i dtráidire an chórais +Comment[gl]=Accede a programas ocultos minimizados na bandexa do sistema +Comment[gu]=સિસ્ટમ ટ્રેમાં નીચાં કરેલ છુપાયેલ કાર્યક્રમોને જુઓ +Comment[he]=גישה ליישומים נסתרים הממוזערים במגש המערכת +Comment[hi]=तंत्र तश्तरी में न्यूनतम किए गए छुपे अनुप्रयोगों पर पहुँच +Comment[hne]=सिस्टम ट्रे मं छोटा करे लुकाय गे अनुपरयोग मं पहुंच +Comment[hr]=Pristup skrivenim aplikacijama minimiziranim u sistemskom bloku +Comment[hu]=Minimalizált alkalmazások elérését teszi lehetővé a paneltálcáról +Comment[ia]=Accede a applicationes celate minimisate in le tabuliero de systema +Comment[id]=Akses aplikasi tersembunyi yang diminimalkan di baki sistem +Comment[is]=Aðgangur að földum forritum sem ganga í kerfisbakkanum +Comment[it]=Accedi alle applicazioni minimizzate nel vassoio di sistema +Comment[ja]=システムトレイに最小化されたアプリケーションにアクセスします +Comment[kk]=Жүйелік сөреге түйілген жасырын қолданбаларға қатынау +Comment[km]=ចូល​ដំណើរការ​កម្មវិធី​ដែល​លាក់​ដែល​បានបង្រួម​នៅ​ក្នុង​ថាស​ប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥಾ ಖಾನೆಯಲ್ಲಿ (ಟ್ರೇ) ಕನಿಷ್ಠೀಕರಿಸಲಾದ ಅಡಗಿಸಲಾದ ಅನ್ವಯಗಳನ್ನು ನಿಲುಕಿಸಿಕೋ +Comment[ko]=시스템 트레이에 숨어 있는 프로그램에 접근합니다 +Comment[lt]=Prieiti prie sistemos dėkle paslėptų programų +Comment[lv]=Piekļūst slēptām programmām, kas minimizētas sistēmas ikonu joslā +Comment[mk]=Пристап до скриените апликации што се наоѓаат во сис. лента +Comment[ml]=സിസ്റ്റം ട്രേയില്‍ മിനിമൈസ് ആയിരിക്കുന്ന ഒളിഞ്ഞിരിയ്ക്കുന്ന പ്രയോഗങ്ങളെ സമീപിയ്ക്കുക +Comment[mr]=system tray अंतर्गत प्रवेश करिता लपविलेले अनुप्रयोग लहान करा +Comment[nb]=Få tilgang til skjulte programmer som er minimert i systemkurven +Comment[nds]=Togriep op versteken Programmen binnen den Systeemafsnitt +Comment[nl]=Biedt toegang tot programma's die in het systeemvak draaien +Comment[nn]=Tilgang til program minimerte i systemtrauet +Comment[or]=ତନ୍ତ୍ର ଟ୍ରେରେ ଆକାର ଛୋଟହୋଇ ଲୁକ୍କାୟିତ ପ୍ରୟୋଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ +Comment[pa]=ਸਿਸਟਮ ਟਰੇ ਵਿੱਚ ਲੁਕਵੀਆਂ ਘੱਟੋ-ਘੱਟ ਕੀਤੀਆਂ ਆਈਟਮਾਂ ਲਈ ਅਸੈੱਸ +Comment[pl]=Dostęp do programów zminimalizowanych na tacce systemowej +Comment[pt]=Aceder às aplicações escondidas e minimizadas na bandeja do sistema +Comment[pt_BR]=Acessa aplicativos ocultos minimizados na área de notificação +Comment[ro]=Accesați aplicațiile ascunse minimizate în tava de sistem +Comment[ru]=Показ значков приложений, свёрнутых в системный лоток +Comment[si]=පද්ධති තැටියේ හකුළා සඟවා ඇති යෙදුම් වලට පිවිසෙන්න +Comment[sk]=Prístup k skrytým aplikáciam minimalizovaným do systémovej lišty +Comment[sl]=Dostopajte do skritih programov, pomanjšanih v sistemsko vrstico +Comment[sr]=Приступ скривеним програмима минимизованим у системску касету +Comment[sr@ijekavian]=Приступ скривеним програмима минимизованим у системску касету +Comment[sr@ijekavianlatin]=Pristup skrivenim programima minimizovanim u sistemsku kasetu +Comment[sr@latin]=Pristup skrivenim programima minimizovanim u sistemsku kasetu +Comment[sv]=Kom åt dolda program minimerade i systembrickan +Comment[ta]=Access hidden applications minimized in the system tray +Comment[te]=సిస్టమ్ ట్రేనందు మినిమైజ్ కాబడి దాగివున్న అనువవర్తనములను యాక్సిస్ చేయుము +Comment[th]=เข้าใช้งานโปรแกรมที่ซ่อนตัวอยู่ในถาดระบบ +Comment[tr]=Sistem çekmecesine küçültülen uygulamalara erişin +Comment[ug]=سىستېما قونداققا كىچىكلىتىپ يوشۇرۇلغان پروگراممىلارنى زىيارەت +Comment[uk]=Доступ до прихованих програм, мінімізованих до системного лотка +Comment[vi]=Truy cập các ứng dụng ẩn được thu nhỏ trong khay hệ thống +Comment[wa]=Åyoz accès ås programes catchîs metous ås pus ptit el boesse ås imådjetes do sistinme +Comment[x-test]=xxAccess hidden applications minimized in the system trayxx +Comment[zh_CN]=访问在系统托盘中最小化隐藏的应用程序 +Comment[zh_TW]=存取最小化在系統匣內的隱藏應用程式 +Icon=preferences-desktop-notification +Type=Service +X-KDE-ServiceTypes=Plasma/Applet + +X-KDE-Library=plasma_applet_systemtray +X-KDE-PluginInfo-Author=Alexander Rodin +X-KDE-PluginInfo-Email=rodin.alexander@gmail.com +X-KDE-PluginInfo-Name=systemtray +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Windows and Tasks +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL v2+ +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.cpp b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.cpp new file mode 100644 index 00000000..5fe0b7fa --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * dbussystemtrayprotocol.cpp * + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "dbussystemtraytask.h" +#include "dbussystemtrayprotocol.h" + +#include + + +namespace SystemTray +{ + +DBusSystemTrayProtocol::DBusSystemTrayProtocol(QObject *parent) + : Protocol(parent), + m_dataEngine(Plasma::DataEngineManager::self()->loadEngine("statusnotifieritem")), + m_tasks() +{ +} + +DBusSystemTrayProtocol::~DBusSystemTrayProtocol() +{ + Plasma::DataEngineManager::self()->unloadEngine("statusnotifieritem"); +} + +void DBusSystemTrayProtocol::init() +{ + if (m_dataEngine->isValid()) { + initRegisteredServices(); + connect(m_dataEngine, SIGNAL(sourceAdded(QString)), + this, SLOT(newTask(QString))); + connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), + this, SLOT(cleanupTask(QString))); + } +} + +void DBusSystemTrayProtocol::newTask(const QString &service) +{ + if (m_tasks.contains(service)) { + return; + } + + DBusSystemTrayTask *task = new DBusSystemTrayTask(service, m_dataEngine, this); + + m_tasks[service] = task; +} + +void DBusSystemTrayProtocol::cleanupTask(const QString &service) +{ + DBusSystemTrayTask *task = m_tasks.value(service); + + if (task) { + m_dataEngine->disconnectSource(service, task); + m_tasks.remove(service); + if (task->isValid()) { + emit task->destroyed(task); + } + task->deleteLater(); + } +} + +void DBusSystemTrayProtocol::initedTask(DBusSystemTrayTask *task) +{ + emit taskCreated(task); +} + +void DBusSystemTrayProtocol::initRegisteredServices() +{ + if (m_dataEngine->isValid()) { + QStringList registeredItems = m_dataEngine->sources(); + foreach (const QString &service, registeredItems) { + newTask(service); + } + } +} + +} + +#include "dbussystemtrayprotocol.moc" diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.h b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.h new file mode 100644 index 00000000..373f8716 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtrayprotocol.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef DBUSSYSTEMTRAYPROTOCOL_H +#define DBUSSYSTEMTRAYPROTOCOL_H + +#include "../../core/protocol.h" + +#include + +#include + +#include + + +namespace SystemTray +{ + +class DBusSystemTrayTask; + +class DBusSystemTrayProtocol : public Protocol +{ + Q_OBJECT + friend class DBusSystemTrayTask; +public: + DBusSystemTrayProtocol(QObject *parent); + ~DBusSystemTrayProtocol(); + void init(); + +protected: + void initRegisteredServices(); + +protected Q_SLOTS: + void newTask(const QString &service); + void cleanupTask(const QString &taskId); + +private: + void initedTask(DBusSystemTrayTask *task); + + Plasma::DataEngine *m_dataEngine; + QHash m_tasks; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp new file mode 100644 index 00000000..189ce7db --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp @@ -0,0 +1,409 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "dbussystemtraytask.h" + +#include "dbussystemtrayprotocol.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace SystemTray +{ + +DBusSystemTrayTask::DBusSystemTrayTask(const QString &serviceName, Plasma::DataEngine *dataEngine, QObject *parent) + : Task(parent), + m_serviceName(serviceName), + m_taskId(serviceName), + m_customIconLoader(0), + m_dataEngine(dataEngine), + m_service(dataEngine->serviceForSource(serviceName)), + m_isMenu(false), + m_valid(false) +{ + kDebug(); + m_service->setParent(this); + + m_dataEngine->connectSource(serviceName, this); +} + +DBusSystemTrayTask::~DBusSystemTrayTask() +{ +} + +QGraphicsWidget* DBusSystemTrayTask::createWidget(Plasma::Applet */*host*/) +{ + return 0; // d-bus tasks don't have widgets but provide info for GUI; +} + +bool DBusSystemTrayTask::isValid() const +{ + return m_valid; +} + +bool DBusSystemTrayTask::isEmbeddable() const +{ + return false; // this task cannot be embed because it only provides information to GUI part +} + +bool DBusSystemTrayTask::isWidget() const +{ + return false; // isn't a widget +} + +void DBusSystemTrayTask::setShortcut(QString text) { + if (m_shortcut != text) { + m_shortcut = text; + emit changedShortcut(); + } +} + + +QString DBusSystemTrayTask::taskId() const +{ + return m_taskId; +} + +QIcon DBusSystemTrayTask::icon() const +{ + return m_icon; +} + +void DBusSystemTrayTask::activate1(int x, int y) const +{ + KConfigGroup params; + if (m_isMenu) { + params = m_service->operationDescription("ContextMenu"); + } else { + params = m_service->operationDescription("Activate"); + } + params.writeEntry("x", x); + params.writeEntry("y", y); + KJob *job = m_service->startOperationCall(params); + connect(job, SIGNAL(result(KJob*)), this, SLOT(_onContextMenu(KJob*))); +} + +void DBusSystemTrayTask::activate2(int x, int y) const +{ + KConfigGroup params = m_service->operationDescription("SecondaryActivate"); + params.writeEntry("x", x); + params.writeEntry("y", y); + m_service->startOperationCall(params); +} + +void DBusSystemTrayTask::activateHorzScroll(int delta) const +{ + _activateScroll(delta, "Horizontal"); +} + +// Copied from kde-runtime/plasma/declarativeimports/core/iconitem.cpp +bool static hasm_svgIcon(QVariant source) +{ + // Set up compat envrionment, afterwards it is 100% copy'n'pastable. + const QString element = source.toString(); + const QString filename = element.split("-").first(); + Plasma::Svg svgIcon; + Plasma::Svg *m_svgIcon = &svgIcon; + + //try as a svg toolbar icon + m_svgIcon->setImagePath("toolbar-icons/" + filename); + + //try as a svg normal icon (like systray) + if (!m_svgIcon->isValid() || !m_svgIcon->hasElement(element)) { + m_svgIcon->setImagePath("icons/" + filename); + } + m_svgIcon->setContainsMultipleImages(true); + + //success? + if (m_svgIcon->isValid() && m_svgIcon->hasElement(element)) { + return true; + } + return false; +} + +QVariant DBusSystemTrayTask::customIcon(QVariant variant) const +{ + if (variant.canConvert()) { + // If we have no icon loader there is nothing to be done with strings. + if (!m_customIconLoader) + return variant; + + // If an SVG icon can be found (via Plasma theme) the name needs to be + // passed along for IconItem to be able to resolve to the theme name as + // well. + if (hasm_svgIcon(variant)) + return variant; + + // Otherwise return a QIcon from our custom icon loader. + return QVariant(KIcon(variant.toString(), m_customIconLoader)); + } else { + // Most importantly QIcons. Nothing to do for those. + return variant; + } +} + +void DBusSystemTrayTask::activateVertScroll(int delta) const +{ + _activateScroll(delta, "Vertical"); +} + +void DBusSystemTrayTask::_activateScroll(int delta, QString direction) const +{ + KConfigGroup params = m_service->operationDescription("Scroll"); + params.writeEntry("delta", delta); + params.writeEntry("direction", direction); + m_service->startOperationCall(params); +} + +void DBusSystemTrayTask::activateContextMenu(int x, int y) const +{ + KConfigGroup params = m_service->operationDescription("ContextMenu"); + params.writeEntry("x", x); + params.writeEntry("y", y); + KJob *job = m_service->startOperationCall(params); + connect(job, SIGNAL(result(KJob*)), this, SLOT(_onContextMenu(KJob*))); +} + +void DBusSystemTrayTask::_onContextMenu(KJob *job) +{ + if (QCoreApplication::closingDown()) { + // apparently an edge case can be triggered due to the async nature of all this + // see: https://bugs.kde.org/show_bug.cgi?id=251977 + return; + } + + Plasma::ServiceJob *sjob = qobject_cast(job); + if (!sjob) { + return; + } + + QMenu *menu = qobject_cast(sjob->result().value()); + if (menu) { + int x = sjob->parameters()["x"].toInt(); + int y = sjob->parameters()["y"].toInt(); + emit showContextMenu(x, y, QVariant::fromValue(menu)); + } +} + +void DBusSystemTrayTask::dataUpdated(const QString &taskName, const Plasma::DataEngine::Data &properties) +{ + Q_UNUSED(taskName); + + const QString id = properties["Id"].toString(); + bool becomeValid = false; + if (!id.isEmpty() && id != m_taskId) { + m_taskId = id; + m_valid = true; + becomeValid = true; + setObjectName(QString("SystemTray-%1").arg(m_taskId)); + } + + QString cat = properties["Category"].toString(); + if (!cat.isEmpty()) { + int index = metaObject()->indexOfEnumerator("Category"); + int key = metaObject()->enumerator(index).keyToValue(cat.toLatin1()); + + if (key != -1) { + setCategory((Task::Category)key); + } + } + + if (properties["TitleChanged"].toBool() || becomeValid) { + QString title = properties["Title"].toString(); + if (!title.isEmpty()) { + bool is_title_changed = (name() != title); + setName(title); + if (is_title_changed) { + emit changedTitle(); + emit changed(this); + } + } + } + + if (properties["IconsChanged"].toBool() || becomeValid) { + syncIcons(properties); + emit changedIcons(); + } + + if (properties["StatusChanged"].toBool() || becomeValid) { + syncStatus(properties["Status"].toString()); + } + + if (properties["ToolTipChanged"].toBool() || becomeValid) { + syncToolTip(properties["ToolTipTitle"].toString(), + properties["ToolTipSubTitle"].toString(), + properties["ToolTipIcon"].value()); + } + + bool is_menu = properties["ItemIsMenu"].toBool(); + if (is_menu != m_isMenu) { + m_isMenu = is_menu; + emit changedIsMenu(); + } + + if (becomeValid) { + DBusSystemTrayProtocol *protocol = qobject_cast(parent()); + if (protocol) { + protocol->initedTask(this); + } + } +} + +void DBusSystemTrayTask::syncIcons(const Plasma::DataEngine::Data &properties) +{ + m_icon = properties["Icon"].value(); + m_attentionIcon = properties["AttentionIcon"].value(); + + QString icon_name = properties["IconName"].toString(); + QString att_icon_name = properties["AttentionIconName"].toString(); + QString movie_path = properties["AttentionMovieName"].toString(); + QString overlay_icon_name = properties["OverlayIconName"].value(); + QString icon_theme_path = properties["IconThemePath"].value(); + bool is_icon_name_changed = false; + bool is_att_icon_name_changed = false; + bool is_movie_path_changed = false; + bool is_overlay_icon_name_changed = false; + + if (icon_name != m_iconName) { + m_iconName = icon_name; + is_icon_name_changed = true; + } + + if (att_icon_name != m_attentionIconName) { + m_attentionIconName = att_icon_name; + is_att_icon_name_changed = true; + } + + if (!movie_path.isEmpty() && !QDir::isAbsolutePath(movie_path)) { + movie_path = KIconLoader::global()->moviePath(movie_path, KIconLoader::Panel); + } + + if (movie_path != m_moviePath) { + m_moviePath = movie_path; + is_movie_path_changed = true; + } + + if (overlay_icon_name != m_overlayIconName) { + m_overlayIconName = overlay_icon_name; + is_overlay_icon_name_changed = true; + } + + if (icon_theme_path != m_iconThemePath) { + m_iconThemePath = icon_theme_path; + + if (m_customIconLoader) { + delete m_customIconLoader; + m_customIconLoader = 0; + } + const QString path = m_iconThemePath; + if (!path.isEmpty()) { + // FIXME: If last part of path is not "icons", this won't work! + QStringList tokens = path.split('/', QString::SkipEmptyParts); + if (tokens.length() >= 3 && tokens.takeLast() == QLatin1String("icons")) { + QString appName = tokens.takeLast(); + QString prefix = QChar('/') % tokens.join("/"); + // FIXME: Fix KIconLoader and KIconTheme so that we can use + // our own instance of KStandardDirs + KGlobal::dirs()->addResourceDir("data", prefix); + // We use a separate instance of KIconLoader to avoid + // adding all application dirs to KIconLoader::global(), to + // avoid potential icon name clashes between application + // icons + m_customIconLoader = new KIconLoader(appName, 0 /* dirs */, this); + } else { + kWarning() << "Wrong IconThemePath" << path << ": too short or does not end with 'icons'"; + } + } + + // Trigger updates + is_icon_name_changed = true; + is_att_icon_name_changed = true; + is_overlay_icon_name_changed = true; + emit changedIcons(); + } + + // emit signals + if (is_icon_name_changed) { + emit changedIconName(); + } + if (is_att_icon_name_changed) { + emit changedAttIconName(); + } + if (is_movie_path_changed) { + emit changedMoviePath(); + } + if (is_overlay_icon_name_changed) { + emit changedOverlayIconName(); + } +} + + +//toolTip + +void DBusSystemTrayTask::syncToolTip(const QString &title, const QString &subTitle, const QIcon &toolTipIcon) +{ + if (title != m_tooltipTitle) { + m_tooltipTitle = title; + emit changedTooltipTitle(); + } + + if (subTitle != m_tooltipText) { + m_tooltipText = subTitle; + emit changedTooltipText(); + } + + bool is_icon_name_changed = (m_tooltipIcon.name() != toolTipIcon.name()); + + m_tooltipIcon = toolTipIcon; + emit changedTooltip(); + + if (is_icon_name_changed) { + emit changedTooltipIconName(); + } +} + + +//Status + +void DBusSystemTrayTask::syncStatus(QString newStatus) +{ + Task::Status status = (Task::Status)metaObject()->enumerator(metaObject()->indexOfEnumerator("Status")).keyToValue(newStatus.toLatin1()); + + if (this->status() == status) { + return; + } + + setStatus(status); +} + +} + +#include "dbussystemtraytask.moc" diff --git a/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h new file mode 100644 index 00000000..e9f0b9ef --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.h @@ -0,0 +1,149 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef DBUSSYSTEMTRAYTASK_H +#define DBUSSYSTEMTRAYTASK_H + +#include "../../core/task.h" + +#include + +class KIconLoader; +class KJob; + +namespace Plasma +{ + +class Service; + +} + +namespace SystemTray +{ + +class DBusSystemTrayTaskPrivate; + +class DBusSystemTrayTask : public Task +{ + Q_OBJECT + + Q_PROPERTY(QIcon icon READ icon NOTIFY changedIcons) + Q_PROPERTY(QIcon attIcon READ attIcon NOTIFY changedIcons) + Q_PROPERTY(QString overlayIconName READ overlayIconName NOTIFY changedOverlayIconName) + Q_PROPERTY(QString iconName READ iconName NOTIFY changedIconName) + Q_PROPERTY(QString attIconName READ attIconName NOTIFY changedAttIconName) + Q_PROPERTY(QString moviePath READ moviePath NOTIFY changedMoviePath) + Q_PROPERTY(bool isMenu READ isMenu NOTIFY changedIsMenu) + Q_PROPERTY(QString title READ title NOTIFY changedTitle) + Q_PROPERTY(QString tooltipTitle READ tooltipTitle NOTIFY changedTooltipTitle) + Q_PROPERTY(QString tooltipText READ tooltipText NOTIFY changedTooltipText) + Q_PROPERTY(QIcon tooltipIcon READ tooltipIcon NOTIFY changedTooltip) + // property tooltipIconName was introduced to make available some icons in tooltip + // while PlasmaCore.ToolTip doesn't provide property for icon (not only name of an icon) + Q_PROPERTY(QString tooltipIconName READ tooltipIconName NOTIFY changedTooltipIconName) + Q_PROPERTY(QString shortcut READ shortcut NOTIFY changedShortcut) + + friend class DBusSystemTrayProtocol; + +public: + DBusSystemTrayTask(const QString &name, Plasma::DataEngine *service, QObject *parent); + ~DBusSystemTrayTask(); + + QGraphicsWidget* createWidget(Plasma::Applet *host); + bool isValid() const; + bool isEmbeddable() const; + virtual QString taskId() const; + virtual QIcon icon() const; + virtual bool isWidget() const; + virtual TaskType type() const { return TypeStatusItem; } + + QString iconName() const { return m_iconName; } + QIcon attIcon() const { return m_attentionIcon; } + QString attIconName() const { return m_attentionIconName; } + QString moviePath() const { return m_moviePath; } + QString overlayIconName() const { return m_overlayIconName; } + QString title() const { return name(); } + bool isMenu() const { return m_isMenu; } + QString tooltipTitle() const { return m_tooltipTitle; } + QString tooltipText() const { return m_tooltipText; } + QIcon tooltipIcon() const { return m_tooltipIcon; } + QString tooltipIconName() const { return m_tooltipIcon.name(); } + QString shortcut() const { return m_shortcut; } + void setShortcut(QString text); + + Q_INVOKABLE void activateContextMenu(int x, int y) const; + Q_INVOKABLE void activate1(int x, int y) const; + Q_INVOKABLE void activate2(int x, int y) const; + Q_INVOKABLE void activateVertScroll(int delta) const; + Q_INVOKABLE void activateHorzScroll(int delta) const; + Q_INVOKABLE QVariant customIcon(QVariant variant) const; + +signals: + void changedIcons(); // if icons, icon names, movie path are changed + void changedIconName(); // if icon name changed + void changedAttIconName(); // if attention icon name is changed + void changedMoviePath(); + void changedOverlayIconName(); + void changedIsMenu(); + void changedTitle(); + void changedTooltip(); + void changedTooltipTitle(); + void changedTooltipText(); + void changedTooltipIconName(); + void changedShortcut(); + void showContextMenu(int x, int y, QVariant menu); + +private: + void syncToolTip(const QString &title, const QString &subTitle, const QIcon &toolTipIcon); + void syncIcons(const Plasma::DataEngine::Data &properties); + void _activateScroll(int delta, QString direction) const; + +private Q_SLOTS: + void syncStatus(QString status); + void dataUpdated(const QString &taskName, const Plasma::DataEngine::Data &taskData); + void _onContextMenu(KJob*); + +private: + QString m_serviceName; + QString m_taskId; + QIcon m_icon; + QString m_iconName; + QIcon m_attentionIcon; + QString m_attentionIconName; + QString m_shortcut; + QString m_moviePath; + QString m_overlayIconName; + QString m_iconThemePath; + QString m_tooltipTitle; + QString m_tooltipText; + QIcon m_tooltipIcon; + + KIconLoader *m_customIconLoader; + + Plasma::DataEngine *m_dataEngine; + Plasma::Service *m_service; + bool m_isMenu; + bool m_valid; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp new file mode 100644 index 00000000..80fbed37 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.cpp @@ -0,0 +1,227 @@ +/*************************************************************************** + * fdographicswidget.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdographicswidget.h" +#include "x11embeddelegate.h" +#include "x11embedcontainer.h" + +#include +#include + +#include +#include + +#include + + +namespace SystemTray +{ + +class FdoGraphicsWidget::Private +{ +public: + Private() + : clientEmbedded(false) + { + } + + ~Private() + { + delete widget.data(); + } + + WId winId; + bool clientEmbedded; + QWeakPointer widget; +}; + +FdoGraphicsWidget::FdoGraphicsWidget(WId winId, QGraphicsWidget *parent) + : QGraphicsWidget(parent), + d(new Private()) +{ + d->winId = winId; + + setMinimumSize(22, 22); + setMaximumSize(48, 48); + resize(22, 22); + + setCacheMode(QGraphicsItem::NoCache); + + QGraphicsView *parentView = 0; + + foreach (QGraphicsView *view, scene()->views()) { + if (view->isVisible() && view->sceneRect().intersects(sceneBoundingRect())) { + parentView = view; + break; + } + } + + if (parentView) { + parentView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + } + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(updateWidgetBackground())); + QTimer::singleShot(0, this, SLOT(setupXEmbedDelegate())); +} + + +FdoGraphicsWidget::~FdoGraphicsWidget() +{ + delete d; +} + + +void FdoGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *parentWidget) +{ + QGraphicsWidget::paint(painter, option, parentWidget); + + QGraphicsView *parentView = 0; + foreach (QGraphicsView *view, scene()->views()) { + if (view->isVisible() && view->sceneRect().intersects(sceneBoundingRect())) { + parentView = view; + } + } + + if (!parentView) { + return; + } + + if (!d->widget) { + QTimer::singleShot(0, this, SLOT(setupXEmbedDelegate())); + return; + } else if (!d->clientEmbedded) { + return; + } + + QWidget *widget = d->widget.data(); + if (widget->parentWidget() != parentView) { + //kDebug() << "embedding into" << parentView->metaObject()->className() << "(" << d->winId << ")"; + widget->setParent(parentView); + } + + QPoint pos = parentView->mapFromScene(scenePos()); + pos += parentView->viewport()->pos(); + if (widget->pos() != pos) { + widget->move(pos); + } + + if (!widget->isVisible()) { + widget->show(); + } +} + +void FdoGraphicsWidget::hideEvent(QHideEvent *event) +{ + Q_UNUSED(event); + if (d->widget) { + d->widget.data()->hide(); + } +} + +void FdoGraphicsWidget::showEvent(QShowEvent *event) +{ + Q_UNUSED(event); + if (d->widget) { + d->widget.data()->show(); + } +} + +void FdoGraphicsWidget::setupXEmbedDelegate() +{ + if (d->widget) { + return; + } + +#if QT_VERSION < 0x040401 + const Qt::ApplicationAttribute attr = (Qt::ApplicationAttribute)4; +#else + const Qt::ApplicationAttribute attr = Qt::AA_DontCreateNativeWidgetSiblings; +#endif + if (!QApplication::testAttribute(attr)) { + QApplication::setAttribute(attr); + } + + X11EmbedDelegate *widget = new X11EmbedDelegate(); + widget->setMinimumSize(22, 22); + widget->setMaximumSize(48, 48); + widget->resize(size().toSize()); + widget->move(QPoint(size().width()/2, size().height()/2) - QPoint(11, 11)); + + connect(widget->container(), SIGNAL(clientIsEmbedded()), + this, SLOT(handleClientEmbedded())); + connect(widget->container(), SIGNAL(clientClosed()), + this, SLOT(handleClientClosed())); + connect(widget->container(), SIGNAL(error(QX11EmbedContainer::Error)), + this, SLOT(handleClientError(QX11EmbedContainer::Error))); + + widget->container()->embedSystemTrayClient(d->winId); + d->widget = widget; +} + +void FdoGraphicsWidget::updateWidgetBackground() +{ + X11EmbedDelegate *widget = d->widget.data(); + if (!widget) { + return; + } + + QPalette palette = widget->palette(); + palette.setBrush(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); + widget->setPalette(palette); + widget->setBackgroundRole(QPalette::Window); +} + + +void FdoGraphicsWidget::handleClientEmbedded() +{ + //kDebug() << "client embedded (" << d->winId << ")"; + d->clientEmbedded = true; + update(); +} + + +void FdoGraphicsWidget::handleClientClosed() +{ + emit clientClosed(); + //kDebug() << "client closed (" << d->winId << ")"; +} + + +void FdoGraphicsWidget::handleClientError(QX11EmbedContainer::Error error) +{ + Q_UNUSED(error); + + //kDebug() << "client error (" << d->winId << ")"; + emit clientClosed(); +} + +void FdoGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + if (d->widget) { + d->widget.data()->resize(size().toSize()); + } + +} + +} + +#include "fdographicswidget.moc" diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.h b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.h new file mode 100644 index 00000000..fbe95720 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdographicswidget.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * fdographicswidget.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOGRAPHICSWIDGET_H +#define FDOGRAPHICSWIDGET_H + +#include +#include + + +namespace SystemTray +{ + +class FdoGraphicsWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + FdoGraphicsWidget(WId winId, QGraphicsWidget *parent = 0); + ~FdoGraphicsWidget(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +signals: + void clientClosed(); + +protected: + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); + void resizeEvent(QGraphicsSceneResizeEvent *event); + +private slots: + void setupXEmbedDelegate(); + void handleClientEmbedded(); + void handleClientClosed(); + void handleClientError(QX11EmbedContainer::Error); + void updateWidgetBackground(); + +private: + class Private; + Private* const d; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.cpp new file mode 100644 index 00000000..08381cf0 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * fdonotification.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdonotification.h" + + +namespace SystemTray +{ + +FdoNotification::FdoNotification(WId winId, QObject *parent) + : Notification(parent), + m_winId(winId) +{ +} + + +FdoNotification::~FdoNotification() +{ + emit notificationDeleted(m_winId); +} + +} diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.h b/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.h new file mode 100644 index 00000000..c35bf692 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdonotification.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * fdonotification.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDONOTIFICATION_H +#define FDONOTIFICATION_H + +#include "../../core/notification.h" + + +namespace SystemTray +{ + +class FdoNotification : public Notification +{ + Q_OBJECT + + friend class FdoSelectionManager; + friend class FdoSelectionManagerPrivate; + +public: + FdoNotification(WId winId, QObject *parent = 0); + ~FdoNotification(); + +signals: + void notificationDeleted(WId winId); + +private: + WId m_winId; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.cpp new file mode 100644 index 00000000..c1bb8b13 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * fdoprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdoprotocol.h" + +#include "fdoselectionmanager.h" + + +namespace SystemTray +{ + +FdoProtocol::FdoProtocol(QObject *parent) + : Protocol(parent), + m_selectionManager(0) +{ +} + +FdoProtocol::~FdoProtocol() +{ + delete m_selectionManager; +} + +void FdoProtocol::init() +{ + m_selectionManager = new FdoSelectionManager; + connect(m_selectionManager, SIGNAL(taskCreated(SystemTray::Task*)), + this, SIGNAL(taskCreated(SystemTray::Task*))); + connect(m_selectionManager, SIGNAL(notificationCreated(SystemTray::Notification*)), + this, SIGNAL(notificationCreated(SystemTray::Notification*))); +} + +} + +#include "fdoprotocol.moc" + diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.h b/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.h new file mode 100644 index 00000000..b006967d --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdoprotocol.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * fdoprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOTASKPROTOCOL_H +#define FDOTASKPROTOCOL_H + +#include "../../core/protocol.h" + + +namespace SystemTray +{ + +class FdoSelectionManager; + +class FdoProtocol : public Protocol +{ + Q_OBJECT + +public: + FdoProtocol(QObject *parent); + ~FdoProtocol(); + void init(); + +private: + FdoSelectionManager *m_selectionManager; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.cpp new file mode 100644 index 00000000..4257202f --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.cpp @@ -0,0 +1,428 @@ +/*************************************************************************** + * fdoselectionmanager.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdoselectionmanager.h" +#include "fdotask.h" +#include "x11embedpainter.h" + +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#ifdef HAVE_XFIXES +# include +#endif + +#ifdef HAVE_XDAMAGE +# include +#endif + +#ifdef HAVE_XCOMPOSITE +# include +#endif + +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_BEGIN_MESSAGE 1 +#define SYSTEM_TRAY_CANCEL_MESSAGE 2 + + +namespace SystemTray +{ + +static FdoSelectionManager *s_manager = 0; +static X11EmbedPainter *s_painter = 0; + +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) +struct DamageWatch +{ + QWidget *container; + Damage damage; +}; + +static int damageEventBase = 0; +static QMap damageWatches; +static QCoreApplication::EventFilter oldEventFilter; + +// Global event filter for intercepting damage events +static bool x11EventFilter(void *message, long int *result) +{ + XEvent *event = reinterpret_cast(message); + if (event->type == damageEventBase + XDamageNotify) { + XDamageNotifyEvent *e = reinterpret_cast(event); + if (DamageWatch *damageWatch = damageWatches.value(e->drawable)) { + // Create a new region and empty the damage region into it. + // The window is small enough that we don't really care about the region; + // we'll just throw it away and schedule a full repaint of the container. + XserverRegion region = XFixesCreateRegion(e->display, 0, 0); + XDamageSubtract(e->display, e->damage, None, region); + XFixesDestroyRegion(e->display, region); + damageWatch->container->update(); + } + } + + if (oldEventFilter && oldEventFilter != x11EventFilter) { + return oldEventFilter(message, result); + } else { + return false; + } +} +#endif + + +struct MessageRequest +{ + long messageId; + long timeout; + long bytesRemaining; + QByteArray message; +}; + + +class FdoSelectionManagerPrivate +{ +public: + FdoSelectionManagerPrivate(FdoSelectionManager *q) + : q(q), + notificationsEngine(0), + haveComposite(false) + { + display = QX11Info::display(); + selectionAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_S" + QByteArray::number(QX11Info::appScreen()), false); + opcodeAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", false); + messageAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_MESSAGE_DATA", false); + visualAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_VISUAL", false); + +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + int eventBase, errorBase; + bool haveXfixes = XFixesQueryExtension(display, &eventBase, &errorBase); + bool haveXdamage = XDamageQueryExtension(display, &damageEventBase, &errorBase); + bool haveXComposite = XCompositeQueryExtension(display, &eventBase, &errorBase); + + if (haveXfixes && haveXdamage && haveXComposite) { + haveComposite = true; + oldEventFilter = QCoreApplication::instance()->setEventFilter(x11EventFilter); + } +#endif + } + + void createNotification(WId winId); + + void handleRequestDock(const XClientMessageEvent &event); + void handleBeginMessage(const XClientMessageEvent &event); + void handleMessageData(const XClientMessageEvent &event); + void handleCancelMessage(const XClientMessageEvent &event); + + Display *display; + Atom selectionAtom; + Atom opcodeAtom; + Atom messageAtom; + Atom visualAtom; + + QHash messageRequests; + QHash tasks; + + FdoSelectionManager *q; + Plasma::DataEngine *notificationsEngine; + + bool haveComposite; +}; + +FdoSelectionManager::FdoSelectionManager() + : d(new FdoSelectionManagerPrivate(this)) +{ + // Init the selection later just to ensure that no signals are sent + // until after construction is done and the creating object has a + // chance to connect. + QTimer::singleShot(0, this, SLOT(initSelection())); +} + + +FdoSelectionManager::~FdoSelectionManager() +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + if (d->haveComposite && QCoreApplication::instance()) { + QCoreApplication::instance()->setEventFilter(oldEventFilter); + } +#endif + + if (s_manager == this) { + s_manager = 0; + delete s_painter; + s_painter = 0; + } + + delete d; +} + +FdoSelectionManager *FdoSelectionManager::manager() +{ + return s_manager; +} + +X11EmbedPainter *FdoSelectionManager::painter() +{ + return s_painter; +} + +void FdoSelectionManager::addDamageWatch(QWidget *container, WId client) +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + DamageWatch *damage = new DamageWatch; + damage->container = container; + damage->damage = XDamageCreate(QX11Info::display(), client, XDamageReportNonEmpty); + damageWatches.insert(client, damage); +#endif +} + +void FdoSelectionManager::removeDamageWatch(QWidget *container) +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + for (QMap::Iterator it = damageWatches.begin(); it != damageWatches.end(); ++it) + { + DamageWatch *damage = *(it); + if (damage->container == container) { + XDamageDestroy(QX11Info::display(), damage->damage); + damageWatches.erase(it); + delete damage; + break; + } + } +#endif +} + + +bool FdoSelectionManager::haveComposite() const +{ + return d->haveComposite; +} + + +bool FdoSelectionManager::x11Event(XEvent *event) +{ + if (event->type == ClientMessage) { + if (event->xclient.message_type == d->opcodeAtom) { + switch (event->xclient.data.l[1]) { + case SYSTEM_TRAY_REQUEST_DOCK: + d->handleRequestDock(event->xclient); + return true; + case SYSTEM_TRAY_BEGIN_MESSAGE: + d->handleBeginMessage(event->xclient); + return true; + case SYSTEM_TRAY_CANCEL_MESSAGE: + d->handleCancelMessage(event->xclient); + return true; + } + } else if (event->xclient.message_type == d->messageAtom) { + d->handleMessageData(event->xclient); + return true; + } + } + + return QWidget::x11Event(event); +} + + +void FdoSelectionManager::initSelection() +{ + XSetSelectionOwner(d->display, d->selectionAtom, winId(), CurrentTime); + + WId selectionOwner = XGetSelectionOwner(d->display, d->selectionAtom); + if (selectionOwner != winId()) { + // FIXME: Hmmm... Reading the docs on XSetSelectionOwner, + // this should not be possible. + kDebug() << "Tried to set selection owner to" << winId() << "but it is set to" << selectionOwner; + return; + } + + // Prefer the ARGB32 visual if available + int nvi; + VisualID visual = XVisualIDFromVisual((Visual*)QX11Info::appVisual()); + XVisualInfo templ; + templ.visualid = visual; + XVisualInfo *xvi = XGetVisualInfo(d->display, VisualIDMask, &templ, &nvi); + if (xvi && xvi[0].depth > 16) { + templ.screen = xvi[0].screen; + templ.depth = 32; + templ.c_class = TrueColor; + XFree(xvi); + xvi = XGetVisualInfo(d->display, VisualScreenMask | VisualDepthMask | VisualClassMask, + &templ, &nvi); + for (int i = 0; i < nvi; i++) { + XRenderPictFormat *format = XRenderFindVisualFormat(d->display, xvi[i].visual); + if (format && format->type == PictTypeDirect && format->direct.alphaMask) { + visual = xvi[i].visualid; + break; + } + } + XFree(xvi); + } + XChangeProperty(d->display, winId(), d->visualAtom, XA_VISUALID, 32, + PropModeReplace, (const unsigned char*)&visual, 1); + + if (!s_painter) { + s_painter = new X11EmbedPainter; + } + s_manager = this; + + WId root = QX11Info::appRootWindow(); + XClientMessageEvent xev; + + xev.type = ClientMessage; + xev.window = root; + xev.message_type = XInternAtom(d->display, "MANAGER", false); + xev.format = 32; + xev.data.l[0] = CurrentTime; + xev.data.l[1] = d->selectionAtom; + xev.data.l[2] = winId(); + xev.data.l[3] = 0; + xev.data.l[4] = 0; + + XSendEvent(d->display, root, false, StructureNotifyMask, (XEvent*)&xev); +} + + +void FdoSelectionManagerPrivate::handleRequestDock(const XClientMessageEvent &event) +{ + const WId winId = (WId)event.data.l[2]; + + if (tasks.contains(winId)) { + kDebug() << "got a dock request from an already existing task"; + return; + } + + FdoTask *task = new FdoTask(winId, q); + + tasks[winId] = task; + q->connect(task, SIGNAL(taskDeleted(WId)), q, SLOT(cleanupTask(WId))); + + emit q->taskCreated(task); +} + + +void FdoSelectionManager::cleanupTask(WId winId) +{ + d->tasks.remove(winId); +} + + +void FdoSelectionManagerPrivate::handleBeginMessage(const XClientMessageEvent &event) +{ + const WId winId = event.window; + + MessageRequest request; + request.messageId = event.data.l[4]; + request.timeout = event.data.l[2]; + request.bytesRemaining = event.data.l[3]; + + if (request.bytesRemaining) { + messageRequests[winId] = request; + } +} + + +void FdoSelectionManagerPrivate::handleMessageData(const XClientMessageEvent &event) +{ + const WId winId = event.window; + const char *messageData = event.data.b; + + if (!messageRequests.contains(winId)) { + kDebug() << "Unexpected message data from" << winId; + return; + } + + MessageRequest &request = messageRequests[winId]; + const int messageSize = qMin(request.bytesRemaining, 20l); + request.bytesRemaining -= messageSize; + request.message += QByteArray(messageData, messageSize); + + if (request.bytesRemaining == 0) { + createNotification(winId); + messageRequests.remove(winId); + } +} + + +void FdoSelectionManagerPrivate::createNotification(WId winId) +{ + if (!tasks.contains(winId)) { + kDebug() << "message request from unknown task" << winId; + return; + } + + MessageRequest &request = messageRequests[winId]; + Task *task = tasks[winId]; + + QString message = QString::fromUtf8(request.message); + message = QTextDocument(message).toHtml(); + + if (!notificationsEngine) { + notificationsEngine = Plasma::DataEngineManager::self()->loadEngine("notifications"); + } + //FIXME: who is the source in this case? + Plasma::Service *service = notificationsEngine->serviceForSource("notification"); + KConfigGroup op = service->operationDescription("createNotification"); + + if (op.isValid()) { + op.writeEntry("appName", task->name()); + //FIXME: find a way to pass icons trough here + op.writeEntry("appIcon", task->name()); + + //op.writeEntry("summary", task->name()); + op.writeEntry("body", message); + op.writeEntry("timeout", (int)request.timeout); + KJob *job = service->startOperationCall(op); + QObject::connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater())); + } else { + delete service; + kDebug() << "invalid operation"; + } +} + + +void FdoSelectionManagerPrivate::handleCancelMessage(const XClientMessageEvent &event) +{ + const WId winId = event.window; + const long messageId = event.data.l[2]; + + if (messageRequests.contains(winId) && messageRequests[winId].messageId == messageId) { + messageRequests.remove(winId); + } +} + + +} diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.h b/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.h new file mode 100644 index 00000000..c86a2d54 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdoselectionmanager.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * fdoselectionmanager.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOSELECTIONMANAGER_H +#define FDOSELECTIONMANAGER_H + +#include + +namespace SystemTray +{ + +class Notification; +class Task; +class X11EmbedPainter; +class FdoSelectionManagerPrivate; + +class FdoSelectionManager : public QWidget +{ + Q_OBJECT + +public: + static FdoSelectionManager *manager(); + static X11EmbedPainter *painter(); + + FdoSelectionManager(); + ~FdoSelectionManager(); + + void addDamageWatch(QWidget *container, WId client); + void removeDamageWatch(QWidget *container); + bool haveComposite() const; + +signals: + void taskCreated(SystemTray::Task *task); + void notificationCreated(SystemTray::Notification *notification); + +protected: + bool x11Event(XEvent *event); + +private slots: + void initSelection(); + void cleanupTask(WId winId); + +private: + friend class FdoSelectionManagerPrivate; + FdoSelectionManagerPrivate* const d; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdotask.cpp b/plasma/generic/applets/systemtray/protocols/fdo/fdotask.cpp new file mode 100644 index 00000000..1d2d7f9a --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdotask.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * fdotask.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdographicswidget.h" +#include "fdotask.h" + +#include +#include + +namespace SystemTray +{ + +class FdoTask::Private +{ +public: + Private(WId winId) + : winId(winId), + widget(0) + { + KWindowInfo info = KWindowSystem::windowInfo(winId, NET::WMName, NET::WM2WindowClass); + + // FIXME: This isn't unique + taskId = info.windowClassName(); + + name = info.name(); + if (name.isEmpty()) { + name = taskId; + } + + icon = KWindowSystem::icon(winId); + } + + WId winId; + QString name; + QString taskId; + QIcon icon; + FdoGraphicsWidget *widget; +}; + + +FdoTask::FdoTask(WId winId, QObject *parent) + : Task(parent), + d(new Private(winId)) +{ + setCategory(ApplicationStatus); + setName(d->name); +} + +FdoTask::~FdoTask() +{ + emit taskDeleted(d->winId); + delete d; +} + +bool FdoTask::isEmbeddable() const +{ + return !isUsed(); +} + +bool FdoTask::isWidget() const { + return true; +} + +QString FdoTask::taskId() const +{ + return d->taskId; +} + +QIcon FdoTask::icon() const +{ + return d->icon; +} + +void FdoTask::abandon(Plasma::Applet *host) +{ + forget(host); + if (d->widget) { + d->widget->hide(); + } +} + +QGraphicsWidget* FdoTask::createWidget(Plasma::Applet *applet) +{ + if (!d->widget) { + d->widget = new FdoGraphicsWidget(d->winId, applet); + connect(d->widget, SIGNAL(clientClosed()), this, SLOT(deleteLater())); + } + + return d->widget; +} + +} + +#include "fdotask.moc" diff --git a/plasma/generic/applets/systemtray/protocols/fdo/fdotask.h b/plasma/generic/applets/systemtray/protocols/fdo/fdotask.h new file mode 100644 index 00000000..0a0a0ab9 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/fdotask.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * fdotask.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOTASK_H +#define FDOTASK_H + +#include "../../core/task.h" + + +namespace SystemTray +{ + +class FdoTask : public Task +{ + Q_OBJECT + +public: + FdoTask(WId winId, QObject *parent); + ~FdoTask(); + + bool isEmbeddable() const; + QString taskId() const; + QIcon icon() const; + void abandon(Plasma::Applet *host); + virtual bool isWidget() const; + virtual TaskType type() const { return TypeX11Task; } + +signals: + void taskDeleted(WId winId); + +protected: + virtual QGraphicsWidget* createWidget(Plasma::Applet *applet); + +private: + class Private; + Private* const d; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp new file mode 100644 index 00000000..a5bc8262 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp @@ -0,0 +1,252 @@ +/*************************************************************************** + * x11embedcontainer.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "x11embedcontainer.h" +#include "x11embedpainter.h" +#include "fdoselectionmanager.h" + +// KDE +#include + +// Qt +#include +#include +#include + +// Xlib +#include + +#include +#include + +#ifdef HAVE_XCOMPOSITE +# include +#endif + + +namespace SystemTray +{ + +class X11EmbedContainer::Private +{ +public: + Private(X11EmbedContainer *q) + : q(q), + picture(None), + updatesEnabled(true) + { + } + + ~Private() + { + if (picture) { + XRenderFreePicture(QX11Info::display(), picture); + } + } + + X11EmbedContainer *q; + + XWindowAttributes attr; + Picture picture; + bool updatesEnabled; + QImage oldBackgroundImage; +}; + + +X11EmbedContainer::X11EmbedContainer(QWidget *parent) + : QX11EmbedContainer(parent), + d(new Private(this)) +{ + connect(this, SIGNAL(clientIsEmbedded()), + this, SLOT(ensureValidSize())); +} + + +X11EmbedContainer::~X11EmbedContainer() +{ + FdoSelectionManager::manager()->removeDamageWatch(this); + delete d; +} + + +void X11EmbedContainer::embedSystemTrayClient(WId clientId) +{ + Display *display = QX11Info::display(); + + if (!XGetWindowAttributes(display, clientId, &d->attr)) { + emit error(QX11EmbedContainer::Unknown); + return; + } + + XSetWindowAttributes sAttr; + sAttr.background_pixel = BlackPixel(display, DefaultScreen(display)); + sAttr.border_pixel = BlackPixel(display, DefaultScreen(display)); + sAttr.colormap = d->attr.colormap; + + WId parentId = parentWidget() ? parentWidget()->winId() : DefaultRootWindow(display); + Window winId = XCreateWindow(display, parentId, 0, 0, d->attr.width, d->attr.height, + 0, d->attr.depth, InputOutput, d->attr.visual, + CWBackPixel | CWBorderPixel | CWColormap, &sAttr); + + XWindowAttributes attr; + if (!XGetWindowAttributes(display, winId, &attr)) { + emit error(QX11EmbedContainer::Unknown); + return; + } + + create(winId); + +#if defined(HAVE_XCOMPOSITE) && defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) + XRenderPictFormat *format = XRenderFindVisualFormat(display, d->attr.visual); + if (format && format->type == PictTypeDirect && format->direct.alphaMask && + FdoSelectionManager::manager()->haveComposite()) + { + // Redirect ARGB windows to offscreen storage so we can composite them ourselves + XRenderPictureAttributes attr; + attr.subwindow_mode = IncludeInferiors; + + d->picture = XRenderCreatePicture(display, clientId, format, CPSubwindowMode, &attr); + XCompositeRedirectSubwindows(display, winId, CompositeRedirectManual); + FdoSelectionManager::manager()->addDamageWatch(this, clientId); + + //kDebug() << "Embedded client uses an ARGB visual -> compositing."; + } else { + //kDebug() << "Embedded client is not using an ARGB visual."; + } +#endif + + // repeat everything from QX11EmbedContainer's ctor that might be relevant + setFocusPolicy(Qt::StrongFocus); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setAcceptDrops(true); + setEnabled(false); + + XSelectInput(display, winId, + KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | + KeymapStateMask | + PointerMotionMask | + EnterWindowMask | LeaveWindowMask | + FocusChangeMask | + ExposureMask | + StructureNotifyMask | + SubstructureNotifyMask); + + XFlush(display); + + embedClient(clientId); + + // FIXME: This checks that the client is still valid. Qt won't pick it up + // if the client closes before embedding completes. However, what happens + // if the close happens after this point? Should checks happen on a timer + // until embedding completes perhaps? + if (!XGetWindowAttributes(QX11Info::display(), clientId, &d->attr)) { + emit error(QX11EmbedContainer::Unknown); + return; + } +} + + +void X11EmbedContainer::ensureValidSize() +{ + QSize s = QSize(qBound(minimumSize().width(), width(), maximumSize().width()), + qBound(minimumSize().height(), height(), maximumSize().height())); + resize(s); +} + + +void X11EmbedContainer::setUpdatesEnabled(bool enabled) +{ + d->updatesEnabled = enabled; +} + + +void X11EmbedContainer::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + if (!d->updatesEnabled) { + return; + } + + if (!d->picture) { + FdoSelectionManager::painter()->updateContainer(this); + return; + } + + // Taking a detour via a QPixmap is unfortunately the only way we can get + // the window contents into Qt's backing store. + QPixmap pixmap = toX11Pixmap(QPixmap(size())); + pixmap.fill(Qt::transparent); + XRenderComposite(x11Info().display(), PictOpSrc, d->picture, None, pixmap.x11PictureHandle(), + 0, 0, 0, 0, 0, 0, width(), height()); + QPainter p(this); + p.drawPixmap(0, 0, pixmap); +} + +void X11EmbedContainer::setBackgroundPixmap(QPixmap background) +{ + if (!clientWinId()) { + return; + } + + //Prevent updating the background-image if possible. Updating can cause a very annoying flicker due to the XClearArea, and thus has to be kept to a minimum + QImage image; + if (background.paintEngine()->type() != QPaintEngine::X11) + image = background.toImage(); // With the raster graphics system this call just returns the backing image, so the image data isn't copied. + else + image = background.copy().toImage(); //With the X11 graphics engine, we have to create a copy first, else we get a crash + + if(d->oldBackgroundImage == image) { + return; + } + d->oldBackgroundImage = image; + + Display* display = QX11Info::display(); + XSetWindowBackgroundPixmap(display, clientWinId(), toX11Pixmap(background).handle()); + XClearArea(display, clientWinId(), 0, 0, 0, 0, True); +} + +// Qt has qt_toX11Pixmap(), but that's sadly not public API. So the only +// option seems to be to create X11-based QPixmap using QPixmap::fromX11Pixmap() +// and draw the non-native pixmap to it. +// NOTE: The alpha-channel is not preserved if it exists, but for X pixmaps it generally should not be needed anyway. +QPixmap X11EmbedContainer::toX11Pixmap(const QPixmap& pix) +{ + if (pix.handle() != 0) // X11 pixmap + return pix; + QPixmap ret; + Pixmap xpix = XCreatePixmap(pix.x11Info().display(), RootWindow(pix.x11Info().display(), pix.x11Info().screen()), + pix.width(), pix.height(), QX11Info::appDepth()); + { + QPixmap wrk = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared); + QPainter paint(&wrk); + paint.drawPixmap(0, 0, pix); + paint.end(); + ret = wrk.copy(); + } // free resources so that xpix can be freed (QPixmap does not own it) + XFreePixmap(pix.x11Info().display(), xpix); + return ret; +} + +} + +#include "x11embedcontainer.moc" diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.h b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.h new file mode 100644 index 00000000..a58fafa5 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * x11embedcontainer.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef X11EMBEDCONTAINER_H +#define X11EMBEDCONTAINER_H + +#include + + +namespace SystemTray +{ + +class X11EmbedContainer : public QX11EmbedContainer +{ + Q_OBJECT + +public: + X11EmbedContainer(QWidget *parent = 0); + ~X11EmbedContainer(); + + void embedSystemTrayClient(WId id); + void setUpdatesEnabled(bool enabled); + void setBackgroundPixmap(QPixmap background); + +protected: + void paintEvent(QPaintEvent *event); + +private slots: + void ensureValidSize(); + +private: + static QPixmap toX11Pixmap(const QPixmap& pix); + class Private; + Private* const d; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.cpp b/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.cpp new file mode 100644 index 00000000..7a3715b4 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * x11embeddelegate.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "x11embedcontainer.h" +#include "x11embeddelegate.h" + +#include + +namespace SystemTray +{ + +class X11EmbedDelegate::Private +{ +public: + X11EmbedContainer *container; +}; + + +X11EmbedDelegate::X11EmbedDelegate(QWidget *parent) + : QWidget(parent), + d(new Private()) +{ + d->container = new X11EmbedContainer(this); + d->container->move(0, 0); + d->container->show(); +} + + +X11EmbedDelegate::~X11EmbedDelegate() +{ + delete d; +} + + +void X11EmbedDelegate::setParent(QWidget *newParent) +{ + if (parent()) { + parent()->removeEventFilter(this); + } + QWidget::setParent(newParent); + if (newParent) { + newParent->installEventFilter(this); + } +} + + +void X11EmbedDelegate::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + d->container->resize(size()); +} + + +X11EmbedContainer* X11EmbedDelegate::container() +{ + return d->container; +} + + +bool X11EmbedDelegate::eventFilter(QObject *watched, QEvent *event) +{ + bool ret = QWidget::eventFilter(watched, event); + + if (event->type() == QEvent::Hide) { + setParent(0); + } + + return ret; +} + +} + +#include "x11embeddelegate.moc" diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.h b/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.h new file mode 100644 index 00000000..a4979899 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embeddelegate.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * x11embeddelegate.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef X11EMBEDDELEGATE_H +#define X11EMBEDDELEGATE_H + +#include + +namespace SystemTray +{ + +class X11EmbedContainer; + +class X11EmbedDelegate : public QWidget +{ + Q_OBJECT + +public: + X11EmbedDelegate(QWidget *parent = 0); + ~X11EmbedDelegate(); + + void setParent(QWidget *parent); + X11EmbedContainer* container(); + + bool eventFilter(QObject *watched, QEvent *event); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + class Private; + Private* const d; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.cpp b/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.cpp new file mode 100644 index 00000000..6076cf4f --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * x11embedpainter.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "x11embedpainter.h" + +#include +#include +#include + +#include + + +#define MAX_PAINTS_PER_SEC 20 +#define MIN_TIME_BETWEEN_PAINTS (1000 / MAX_PAINTS_PER_SEC) + + +namespace SystemTray +{ + +class X11EmbedPainter::Private +{ +public: + Private(X11EmbedPainter *parent) + : q(parent), + lastPaintTime(QTime::currentTime()), + fastPaints(0) + { + lastPaintTime.addMSecs(-MIN_TIME_BETWEEN_PAINTS); + + delayedPaintTimer.setSingleShot(true); + connect(&delayedPaintTimer, SIGNAL(timeout()), q, SLOT(performUpdates())); + } + + X11EmbedPainter *q; + QSet containers; + QTime lastPaintTime; + QTimer delayedPaintTimer; + int fastPaints; +}; + + +X11EmbedPainter::X11EmbedPainter() + : d(new Private(this)) +{ +} + + +X11EmbedPainter::~X11EmbedPainter() +{ + delete d; +} + + +void X11EmbedPainter::updateContainer(X11EmbedContainer *container) +{ + if (d->containers.contains(container)) { + return; + } + + d->containers.insert(container); + + connect(container, SIGNAL(destroyed(QObject*)), + this, SLOT(removeContainer(QObject*))); + + if (!d->delayedPaintTimer.isActive()) { + int msecsToNextPaint = MIN_TIME_BETWEEN_PAINTS - d->lastPaintTime.elapsed(); + if (msecsToNextPaint > 0 && msecsToNextPaint < MIN_TIME_BETWEEN_PAINTS) { + ++d->fastPaints; + if (d->fastPaints > 2) { + //kDebug() << "Delaying paint by" << msecsToNextPaint << "msecs"; + d->delayedPaintTimer.start(msecsToNextPaint); + } else { + d->delayedPaintTimer.start(0); + } + } else { + d->fastPaints = 0; + d->delayedPaintTimer.start(0); + } + } +} + + +void X11EmbedPainter::removeContainer(QObject *container) +{ + d->containers.remove(static_cast(container)); +} + + +void X11EmbedPainter::performUpdates() +{ + QMultiHash containersByParent; + + foreach (X11EmbedContainer *container, d->containers) { + QWidget *topWidget = container; + while (topWidget->parentWidget()) { + topWidget = topWidget->parentWidget(); + } + containersByParent.insert(topWidget, container); + container->setUpdatesEnabled(false); + } + + foreach (QWidget *parent, containersByParent.uniqueKeys()) { + QList containers = containersByParent.values(parent); + containersByParent.remove(parent); + + QRegion paintRegion; + QHash containerRects; + foreach (X11EmbedContainer *container, containers) { + QRect rect = QRect(container->mapTo(parent, QPoint(0, 0)), container->size()); + containerRects.insert(container, rect); + paintRegion = paintRegion.united(rect); + } + + QPixmap background = QPixmap(parent->size()); + parent->render(&background, paintRegion.boundingRect().topLeft(), paintRegion); + + foreach (X11EmbedContainer *container, containers) { + container->setBackgroundPixmap(background.copy(containerRects.value(container))); + } + } + + foreach (X11EmbedContainer *container, d->containers) { + container->setUpdatesEnabled(true); + disconnect(container, SIGNAL(destroyed(QObject*)), + this, SLOT(removeContainer(QObject*))); + } + + d->containers.clear(); + d->lastPaintTime.start(); +} + +} + +#include "x11embedpainter.moc" diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.h b/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.h new file mode 100644 index 00000000..d5cea64d --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embedpainter.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * x11embedpainter.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef X11EMBEDPAINTER_H +#define X11EMBEDPAINTER_H + +#include "x11embedcontainer.h" + +#include + + +namespace SystemTray +{ + +class X11EmbedPainter : public QObject +{ + Q_OBJECT + +public: + X11EmbedPainter(); + ~X11EmbedPainter(); + + void updateContainer(X11EmbedContainer *container); + +private slots: + void performUpdates(); + void removeContainer(QObject *container); + +private: + class Private; + Private* const d; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.cpp b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.cpp new file mode 100644 index 00000000..9531d3a7 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.cpp @@ -0,0 +1,205 @@ +/*************************************************************************** + * plasmoidtask.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2008 Sebastian Kügler * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasmoidtask.h" +#include + +#include +#include + +#include +#include +#include + + +namespace SystemTray +{ + +PlasmoidTask::PlasmoidTask(const QString &appletname, int id, QObject *parent, Plasma::Applet *host) + : Task(parent), + m_appletName(appletname), + m_taskId(appletname), + m_host(host), + m_takenByParent(false) +{ + setName(appletname); + setupApplet(appletname, id); +} + + +PlasmoidTask::~PlasmoidTask() +{ + emit taskDeleted(m_host, m_taskId); +} + + +bool PlasmoidTask::isEmbeddable() const +{ + return m_applet && !m_takenByParent; +} + +bool PlasmoidTask::isValid() const +{ + return !m_appletName.isEmpty() && m_applet; +} + + +QString PlasmoidTask::taskId() const +{ + return m_taskId; +} + + +QIcon PlasmoidTask::icon() const +{ + return m_icon; +} + +Plasma::Applet *PlasmoidTask::host() const +{ + return m_host; +} + +bool PlasmoidTask::isWidget() const { + return true; +} + +QGraphicsWidget* PlasmoidTask::createWidget(Plasma::Applet *host) +{ + if (host != m_host || !m_applet) { + return 0; + } + + Plasma::Applet *applet = m_applet.data(); + m_takenByParent = true; + applet->setParent(host); + applet->setParentItem(host); + KConfigGroup group = applet->config(); + group = group.parent(); + applet->restore(group); + applet->init(); + applet->updateConstraints(Plasma::StartupCompletedConstraint); + applet->flushPendingConstraintsEvents(); + applet->updateConstraints(Plasma::AllConstraints); + applet->flushPendingConstraintsEvents(); + + // make sure to record it in the configuration so that if we reload from the config, + // this applet is remembered + KConfigGroup dummy; + applet->save(dummy); + + connect(applet, SIGNAL(newStatus(Plasma::ItemStatus)), this, SLOT(newAppletStatus(Plasma::ItemStatus))); + + newAppletStatus(applet->status()); + + connect(applet, SIGNAL(configNeedsSaving()), host, SIGNAL(configNeedsSaving())); + connect(applet, SIGNAL(releaseVisualFocus()), host, SIGNAL(releaseVisualFocus())); + + return static_cast(applet); +} + +void PlasmoidTask::forwardConstraintsEvent(Plasma::Constraints constraints) +{ + Plasma::Applet *applet = m_applet.data(); + if (applet) { + applet->updateConstraints(constraints); + applet->flushPendingConstraintsEvents(); + } +} + +int PlasmoidTask::id() const +{ + if (m_applet) { + return m_applet.data()->id(); + } + + return 0; +} + +void PlasmoidTask::setupApplet(const QString &plugin, int id) +{ + Plasma::Applet *applet = Plasma::Applet::load(plugin, id); + m_applet = applet; + + if (!m_applet) { + kDebug() << "Could not load applet" << plugin; + return; + } + + //FIXME: System Information should be system services, but battery and devicenotifier are both there. we would need multiple categories + if (applet->category() == "System Information" || + applet->category() == "Network") { + setCategory(Hardware); + } else if (applet->category() == "Online Services") { + setCategory(Communications); + } + + setName(applet->name()); + + m_icon = KIcon(applet->icon()); + + applet->setFlag(QGraphicsItem::ItemIsMovable, false); + + connect(applet, SIGNAL(appletDestroyed(Plasma::Applet*)), this, SLOT(appletDestroyed(Plasma::Applet*))); + applet->setBackgroundHints(Plasma::Applet::NoBackground); +} + +void PlasmoidTask::appletDestroyed(Plasma::Applet *) +{ + emit destroyed(this); + forget(m_host); + deleteLater(); +} + +void PlasmoidTask::newAppletStatus(Plasma::ItemStatus status) +{ + Plasma::Applet *applet = m_applet.data(); + if (!applet) { + return; + } + + switch (status) { + case Plasma::PassiveStatus: + if (Plasma::PopupApplet *popupApplet = qobject_cast(applet)) { + popupApplet->hidePopup(); + } + setStatus(Task::Passive); + break; + + case Plasma::ActiveStatus: + setStatus(Task::Active); + break; + + case Plasma::NeedsAttentionStatus: + setStatus(Task::NeedsAttention); + break; + + default: + case Plasma::UnknownStatus: + setStatus(Task::UnknownStatus); + } +} + +} + +#include "plasmoidtask.moc" diff --git a/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.h b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.h new file mode 100644 index 00000000..1a1dec69 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtask.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * plasmoidtask.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2008 Sebastian Kügler * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef PLASMOIDTASK_H +#define PLASMOIDTASK_H + +#include "../../core/task.h" + +#include + +namespace SystemTray +{ + + +class PlasmoidTask : public Task +{ + Q_OBJECT + +public: + PlasmoidTask(const QString &appletName, int id, QObject *parent, Plasma::Applet *host); + virtual ~PlasmoidTask(); + + bool isValid() const; + virtual bool isEmbeddable() const; + virtual QString taskId() const; + virtual QIcon icon() const; + void forwardConstraintsEvent(Plasma::Constraints constraints); + int id() const; + Plasma::Applet *host() const; + virtual bool isWidget() const; + virtual TaskType type() const { return TypePlasmoid; } + +protected Q_SLOTS: + void appletDestroyed(Plasma::Applet *object); + void newAppletStatus(Plasma::ItemStatus status); + +Q_SIGNALS: + void taskDeleted(Plasma::Applet *host, const QString &taskId); + +protected: + virtual QGraphicsWidget* createWidget(Plasma::Applet *applet); + +private: + void setupApplet(const QString &plugin, int id); + + QString m_appletName; + QString m_taskId; + QIcon m_icon; + QWeakPointer m_applet; + Plasma::Applet *m_host; + bool m_takenByParent; +}; + +} + +#endif diff --git a/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp new file mode 100644 index 00000000..29e3d721 --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + * plasmoidprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2008 Sebastian Kügler * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasmoidtask.h" +#include "plasmoidtaskprotocol.h" + +#include + +#include + +namespace SystemTray +{ + +PlasmoidProtocol::PlasmoidProtocol(QObject *parent) + : Protocol(parent) +{ +} + + +PlasmoidProtocol::~PlasmoidProtocol() +{ +} + + +void PlasmoidProtocol::init() +{ +} + +void PlasmoidProtocol::forwardConstraintsEvent(Plasma::Constraints constraints, Plasma::Applet *host) +{ + if (m_tasks.contains(host)) { + QHash tasksForHost = m_tasks.value(host); + foreach (PlasmoidTask *task, tasksForHost) { + task->forwardConstraintsEvent(constraints); + } + } +} + +void PlasmoidProtocol::loadFromConfig(Plasma::Applet *parent) +{ + QHash existingTasks = m_tasks.value(parent); + QSet seenNames; + + KConfigGroup appletGroup = parent->config(); + appletGroup = KConfigGroup(&appletGroup, "Applets"); + + foreach (const QString &groupName, appletGroup.groupList()) { + const KConfigGroup childGroup(&appletGroup, groupName); + const QString appletName = childGroup.readEntry("plugin", QString()); + + existingTasks.remove(appletName); + addApplet(appletName, groupName.toInt(), parent); + } + + QHashIterator it(existingTasks); + while (it.hasNext()) { + it.next(); + Plasma::Applet *applet = qobject_cast(it.value()->widget(parent, true)); + if (applet) { + applet->destroy(); + } + } +} + +void PlasmoidProtocol::addApplet(const QString appletName, const int id, Plasma::Applet *parent) +{ + PlasmoidTask *task = m_tasks.value(parent).value(appletName); + if (task) { + // the host already has one of these applets ... but let's make sure that the id is the same + // if it isn't, we have a duplicate in the config file and it should be removed + if (task->id() != id) { + KConfigGroup appletGroup = parent->config(); + appletGroup = KConfigGroup(&appletGroup, "Applets"); + appletGroup = KConfigGroup(&appletGroup, QString::number(id)); + appletGroup.deleteGroup(); + } + + return; + } + + kDebug() << "Registering task with the manager" << appletName; + task = new PlasmoidTask(appletName, id, this, parent); + + if (!task->isValid()) { + // we failed to load our applet *sob* + delete task; + return; + } + + + m_tasks[parent].insert(appletName, task); + connect(task, SIGNAL(taskDeleted(Plasma::Applet*,QString)), this, SLOT(cleanupTask(Plasma::Applet*,QString))); + emit taskCreated(task); +} + +void PlasmoidProtocol::removeApplet(const QString appletName, Plasma::Applet *parent) +{ + if (!m_tasks.contains(parent) || !m_tasks.value(parent).contains(appletName)) { + return; + } + + Plasma::Applet *applet = qobject_cast(m_tasks.value(parent).value(appletName)->widget(parent, true)); + + if (applet) { + applet->destroy(); + } +} + +void PlasmoidProtocol::cleanupTask(Plasma::Applet *host, const QString &taskId) +{ + kDebug() << "task with taskId" << taskId << "removed"; + if (m_tasks.contains(host)) { + m_tasks[host].remove(taskId); + if (m_tasks.value(host).isEmpty()) { + m_tasks.remove(host); + } + } +} + +QStringList PlasmoidProtocol::applets(Plasma::Applet *host) const +{ + QStringList list; + if (!m_tasks.contains(host)) { + return list; + } + + QHashIterator i(m_tasks.value(host)); + + while (i.hasNext()) { + i.next(); + list << i.key(); + } + + return list; +} + +} + +#include "plasmoidtaskprotocol.moc" diff --git a/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h new file mode 100644 index 00000000..31aaca1c --- /dev/null +++ b/plasma/generic/applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * plasmoidprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2008 Sebastian Kügler * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef PLASMOIDTASKPROTOCOL_H +#define PLASMOIDTASKPROTOCOL_H + +#include "../../core/protocol.h" + +#include + +#include +#include + +namespace SystemTray +{ + +class PlasmoidTask; + +class PlasmoidProtocol : public Protocol +{ + Q_OBJECT + +public: + PlasmoidProtocol(QObject * parent); + ~PlasmoidProtocol(); + + void init(); + + void forwardConstraintsEvent(Plasma::Constraints constraints, Plasma::Applet *host); + void loadFromConfig(Plasma::Applet *parent); + void addApplet(const QString appletName, const int id, Plasma::Applet *parent); + void removeApplet(const QString appletName, Plasma::Applet *parent); + QStringList applets(Plasma::Applet *parent) const; + +private slots: + void cleanupTask(Plasma::Applet *host, const QString &taskId); + +private: + QHash > m_tasks; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/ui/applet.cpp b/plasma/generic/applets/systemtray/ui/applet.cpp new file mode 100644 index 00000000..bb951077 --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/applet.cpp @@ -0,0 +1,825 @@ +/*************************************************************************** + * applet.cpp * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2008 Sebastian Sauer * + * Copyright (C) 2010 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "applet.h" +#include "widgetitem.h" +#include "mouseredirectarea.h" + +#include "../protocols/dbussystemtray/dbussystemtraytask.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "config.h" + +#include "../core/manager.h" + +static const bool DEFAULT_SHOW_APPS = true; +static const bool DEFAULT_SHOW_COMMUNICATION = true; +static const bool DEFAULT_SHOW_SERVICES = true; +static const bool DEFAULT_SHOW_HARDWARE = true; +static const bool DEFAULT_SHOW_UNKNOWN = true; +static const char KlipperName[] = "Klipper"; + +namespace SystemTray +{ + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +namespace +{ + +static void _RegisterEnums(QDeclarativeContext *context, const QMetaObject &meta) +{ + for (int i = 0, s = meta.enumeratorCount(); i < s; ++i) { + QMetaEnum e = meta.enumerator(i); + for (int i = 0, s = e.keyCount(); i < s; ++i) { + context->setContextProperty(e.key(i), e.value(i)); + } + } +} + +} // namespace + + +K_EXPORT_PLASMA_APPLET(systemtray, Applet) + + +Manager *Applet::s_manager = 0; +int Applet::s_managerUsage = 0; + +Applet::Applet(QObject *parent, const QVariantList &arguments) + : Plasma::Applet(parent, arguments), + m_widget(0), + m_firstRun(true) +{ + if (!s_manager) { + s_manager = new SystemTray::Manager(); + } + + ++s_managerUsage; + + setAspectRatioMode(Plasma::IgnoreAspectRatio); + setHasConfigurationInterface(true); +} + +Applet::~Applet() +{ + // stop listening to the manager + disconnect(s_manager, 0, this, 0); + + foreach (Task *task, s_manager->tasks()) { + // we don't care about the task updates anymore + disconnect(task, 0, this, 0); + + // delete our widget (if any); some widgets (such as the extender info one) + // may rely on the applet being around, so we need to delete them here and now + // while we're still kicking + if (task->isWidget()) + delete task->widget(this, false); + } + + delete m_widget; + + --s_managerUsage; + if (s_managerUsage < 1) { + delete s_manager; + s_manager = 0; + s_managerUsage = 0; + } +} + +void Applet::init() +{ + // First of all, we have to register new QML types because they won't be registered later + qmlRegisterType("Private", 0, 1, "WidgetItem"); + qmlRegisterType("Private", 0, 1, "MouseRedirectArea"); + + // Find data directory + KStandardDirs std_dirs; + QStringList dirs = std_dirs.findDirs("data", SYSTEMTRAY_DATA_INSTALL_DIR); + QString data_path; + if (!dirs.isEmpty()) { + data_path = dirs.at(0); + } else { + setFailedToLaunch(true, "Data directory for applet isn't found"); + return; + } + + // Create declarative engine, etc + m_widget = new Plasma::DeclarativeWidget(this); + m_widget->setInitializationDelayed(true); + connect(m_widget, SIGNAL(finished()), this, SLOT(_onWidgetCreationFinished())); + m_widget->setQmlPath(data_path + QString::fromLatin1("contents/ui/main.qml")); + + if (!m_widget->engine() || !m_widget->engine()->rootContext() || !m_widget->engine()->rootContext()->isValid() + || m_widget->mainComponent()->isError()) { + QString reason; + foreach (QDeclarativeError error, m_widget->mainComponent()->errors()) { + reason += error.toString(); + } + setFailedToLaunch(true, reason); + return; + } + + // setup context add global object "plasmoid" + QDeclarativeContext *root_context = m_widget->engine()->rootContext(); + root_context->setContextProperty("plasmoid", this); + + // add enumerations manually to global context + _RegisterEnums(root_context, Task::staticMetaObject); + _RegisterEnums(root_context, SystemTray::Applet::staticMetaObject); + + // add declarative widget to our applet + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addItem(m_widget); +} + + +void Applet::_onAddedTask(Task *task) +{ + if (task->isWidget()) { + // If task is presented as a widget then we should check that widget + if (!task->isEmbeddable(this)) { + //was a widget created previously? kill it + QGraphicsWidget *widget = task->widget(this, false); + if (widget) { + task->abandon(this); + } + return; + } + + QGraphicsWidget *widget = task->widget(this); + if (!widget) { + return; + } + + //If the applet doesn't want to show FDO tasks, remove (not just hide) any of them + //if the dbus icon has a category that the applet doesn't want to show remove it + if (!m_shownCategories.contains(task->category()) && !qobject_cast(widget)) { + task->abandon(this); + return; + } + } else if (!m_shownCategories.contains(task->category())) { + return; + } + + // provide task to qml code + emit newTask(task); + + DBusSystemTrayTask *dbus_task = qobject_cast(task); + if (dbus_task && !dbus_task->objectName().isEmpty() && dbus_task->shortcut().isEmpty()) { + // try to set shortcut + bool is_klipper = false; + QString default_shortcut; + if (dbus_task->name() == KlipperName) { + // for klipper we have to read its default hotkey from its config + is_klipper = true; + QString file = KStandardDirs::locateLocal("config", "kglobalshortcutsrc"); + KConfig config(file); + KConfigGroup cg(&config, "klipper"); + QStringList shortcutTextList = cg.readEntry("show_klipper_popup", QStringList()); + + if (shortcutTextList.size() >= 2) { + default_shortcut = shortcutTextList.first(); + if (default_shortcut.isEmpty()) { + default_shortcut = shortcutTextList[1]; + } + } + if (default_shortcut.isEmpty()) { + default_shortcut = "Ctrl+Alt+V"; + } + } + + QString action_name = _getActionName(task); + KConfigGroup cg = config(); + KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); + QString shortcut = shortcutsConfig.readEntryUntranslated(action_name, default_shortcut); + dbus_task->setShortcut(shortcut); + + if (is_klipper && shortcut == default_shortcut) { + // we have to write klipper's hotkey to config + if (shortcut.isEmpty()) + shortcutsConfig.deleteEntry(action_name); + else + shortcutsConfig.writeEntry(action_name, shortcut); + } + } +} + + +void Applet::_onRemovedTask(Task *task) +{ + //remove task from QML code + emit deletedTask(task); +} + +void Applet::_onStatusChangedTask() +{ + foreach (Task *task, s_manager->tasks()) { + if (task->status() == Task::NeedsAttention) { + setStatus(Plasma::NeedsAttentionStatus); + return; + } + } + + setStatus(Plasma::PassiveStatus); +} + +void Applet::_onWidgetCreationFinished() +{ + // add already existing tasks + QList tasks = s_manager->tasks(); + foreach (Task *t, tasks) { + _onAddedTask(t); + } + + connect(s_manager, SIGNAL(taskAdded(SystemTray::Task*)), this, SLOT(_onAddedTask(SystemTray::Task*))); + connect(s_manager, SIGNAL(taskRemoved(SystemTray::Task*)), this, SLOT(_onRemovedTask(SystemTray::Task*))); + connect(s_manager, SIGNAL(taskStatusChanged()), this, SLOT(_onStatusChangedTask())); +} + + +bool Applet::isFirstRun() +{ + return m_firstRun; +} + + +void Applet::configChanged() +{ + KConfigGroup gcg = globalConfig(); + KConfigGroup cg = config(); + + m_hiddenTypes = QSet::fromList(cg.readEntry("hidden", QStringList())); + m_alwaysShownTypes = QSet::fromList(cg.readEntry("alwaysShown", QStringList())); + + m_shownCategories.clear(); + + if (cg.readEntry("ShowApplicationStatus", gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS))) { + m_shownCategories.insert(Task::ApplicationStatus); + } + + if (cg.readEntry("ShowCommunications", gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION))) { + m_shownCategories.insert(Task::Communications); + } + + if (cg.readEntry("ShowSystemServices", gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES))) { + m_shownCategories.insert(Task::SystemServices); + } + + if (cg.readEntry("ShowHardware", gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE))) { + m_shownCategories.insert(Task::Hardware); + } + + if (cg.readEntry("ShowUnknown", gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN))) { + m_shownCategories.insert(Task::UnknownCategory); + } + + s_manager->loadApplets(this); + + // notify QML code about new user's preferences + emit visibilityPreferenceChanged(); +} + + +QString Applet::_getActionName(Task *task) const { + if (task->objectName().isEmpty()) + return QString(""); + return task->objectName() + QString("-") + QString::number(this->id()); +} + +void Applet::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::FormFactorConstraint) { + emit formFactorChanged(); + } + + if (constraints & Plasma::LocationConstraint) { + emit locationChanged(); + } + + if (constraints & Plasma::ImmutableConstraint) { + if (m_visibleItemsInterface) { + bool visible = (immutability() == Plasma::UserImmutable); + m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable); + m_visibleItemsUi.unlockLabel->setVisible(visible); + m_visibleItemsUi.unlockButton->setVisible(visible); + } + } + + if (constraints & Plasma::StartupCompletedConstraint) { + QTimer::singleShot(0, this, SLOT(checkDefaultApplets())); + configChanged(); + } + + s_manager->forwardConstraintsEvent(constraints, this); +} + +SystemTray::Manager *Applet::manager() const +{ + return s_manager; +} + +QSet Applet::shownCategories() const +{ + return m_shownCategories; +} + + +void Applet::propogateSizeHintChange(Qt::SizeHint which) +{ + emit sizeHintChanged(which); +} + +void Applet::createConfigurationInterface(KConfigDialog *parent) +{ + if (!m_autoHideInterface) { + m_autoHideInterface = new QWidget(); + m_visibleItemsInterface = new QWidget(); + + m_autoHideUi.setupUi(m_autoHideInterface.data()); + m_autoHideUi.icons->header()->setResizeMode(QHeaderView::ResizeToContents); + + m_visibleItemsUi.setupUi(m_visibleItemsInterface.data()); + + QAction *unlockAction = 0; + if (containment() && containment()->corona()) { + unlockAction = containment()->corona()->action("lock widgets"); + } + + if (unlockAction) { + disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment())); + connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger()), Qt::UniqueConnection); + } else { + disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger())); + connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment()), Qt::UniqueConnection); + } + + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + + parent->addPage(m_visibleItemsInterface.data(), i18n("Display"), + "preferences-desktop-notification", + i18n("Choose which information to show")); + parent->addPage(m_autoHideInterface.data(), i18n("Entries"), "configure-toolbars"); + + bool visible = (immutability() == Plasma::UserImmutable); + //FIXME: always showing the scrollbar is due to a bug somewhere in QAbstractScrollArea, + //QListView and/or KCategorizedView; without it, under certain circumstances it will + //go into an infinite loop. too many people are running into this problem, so we are + //working around the problem rather than waiting for an upstream fix, which is against + //our usual policy. + //to determine if this line is no longer needed in the future, comment it out, lock + //widgets, then call up the configuration dialog for a system tray applet and click + //on the "unlock widgets" button. + m_visibleItemsUi.unlockLabel->setVisible(visible); + m_visibleItemsUi.unlockButton->setVisible(visible); + + m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable); + m_visibleItemsUi.visibleItemsView->setCategoryDrawer(new KCategoryDrawerV3(m_visibleItemsUi.visibleItemsView)); + m_visibleItemsUi.visibleItemsView->setMouseTracking(true); + m_visibleItemsUi.visibleItemsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + m_visibleItemsUi.visibleItemsView->setVerticalScrollMode(QListView::ScrollPerPixel); + + KCategorizedSortFilterProxyModel *visibleItemsModel = new KCategorizedSortFilterProxyModel(m_visibleItemsUi.visibleItemsView); + visibleItemsModel->setCategorizedModel(true); + + m_visibleItemsSourceModel = new QStandardItemModel(m_visibleItemsUi.visibleItemsView); + visibleItemsModel->setSourceModel(m_visibleItemsSourceModel.data()); + m_visibleItemsUi.visibleItemsView->setModel(visibleItemsModel); + } + + QStandardItemModel *visibleItemsSourceModel = m_visibleItemsSourceModel.data(); + // the lifespan of m_visibleItemsSourceModel is tied to the config UI, so it + // should always exist at this point + Q_ASSERT(visibleItemsSourceModel); + visibleItemsSourceModel->clear(); + m_autoHideUi.icons->clear(); + + QMultiMap sortedTasks; + foreach (Task *task, s_manager->tasks()) { + if (!m_shownCategories.contains(task->category())) { + continue; + } + + if (task->isWidget() && !task->widget(this, false)) { + // it is not being used by this widget + continue; + } + + sortedTasks.insert(task->name(), task); + } + + KConfigGroup gcg = globalConfig(); + KConfigGroup cg = config(); + KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); + + foreach (Task *task, sortedTasks) { + QTreeWidgetItem *listItem = new QTreeWidgetItem(m_autoHideUi.icons); + KComboBox *itemCombo = new KComboBox(m_autoHideUi.icons); + listItem->setText(0, task->name()); + listItem->setIcon(0, task->icon()); + listItem->setFlags(Qt::ItemIsEnabled); + listItem->setData(0, Qt::UserRole, task->taskId()); + + itemCombo->addItem(i18nc("Item will be automatically shown or hidden from the systray", "Auto")); + itemCombo->addItem(i18nc("Item is never visible in the systray", "Hidden")); + itemCombo->addItem(i18nc("Item is always visible in the systray", "Always Visible")); + + if (m_hiddenTypes.contains(task->taskId())) { + itemCombo->setCurrentIndex(1); + } else if (m_alwaysShownTypes.contains(task->taskId())) { + itemCombo->setCurrentIndex(2); + } else { + itemCombo->setCurrentIndex(0); + } + m_autoHideUi.icons->setItemWidget(listItem, 1, itemCombo); + + KKeySequenceWidget *button = new KKeySequenceWidget(m_autoHideUi.icons); + + DBusSystemTrayTask *dbus_task = qobject_cast(task); + Plasma::Applet *applet = qobject_cast(task->widget(this)); + + if (task && dbus_task && !dbus_task->objectName().isEmpty()) { + QString action_name = _getActionName(task); + QString shortcutText = shortcutsConfig.readEntryUntranslated(action_name, QString()); + button->setKeySequence(shortcutText); + } else if (task && applet) { + button->setKeySequence(applet->globalShortcut().primary()); + //no way to have a shortcut for the fdo protocol + } else { + button->setEnabled(false); + } + m_autoHideUi.icons->setItemWidget(listItem, 2, button); + m_autoHideUi.icons->addTopLevelItem(listItem); + + // try to make sure we have enough width! + int totalWidth = 0; + for (int i = 0; i < m_autoHideUi.icons->header()->count(); ++i) { + totalWidth += m_autoHideUi.icons->columnWidth(i); + } + m_autoHideUi.icons->setMinimumWidth(totalWidth + style()->pixelMetric(QStyle::PM_ScrollBarExtent)); + + connect(itemCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified())); + connect(button, SIGNAL(keySequenceChanged(QKeySequence)), parent, SLOT(settingsModified())); + } + + const QString itemCategories = i18nc("Categories of items in the systemtray that will be shown or hidden", "Shown Item Categories"); + + QStandardItem *applicationStatusItem = new QStandardItem(); + applicationStatusItem->setText(i18nc("Systemtray items that describe the status of a generic application", "Application status")); + applicationStatusItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + bool checked = cg.readEntry("ShowApplicationStatus", + gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS)); + applicationStatusItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + applicationStatusItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); + applicationStatusItem->setData("ShowApplicationStatus", Qt::UserRole+1); + visibleItemsSourceModel->appendRow(applicationStatusItem); + + QStandardItem *communicationsItem = new QStandardItem(); + communicationsItem->setText(i18nc("Items communication related, such as chat or email clients", "Communications")); + communicationsItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + checked = cg.readEntry("ShowCommunications", + gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION)); + communicationsItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + communicationsItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); + communicationsItem->setData("ShowCommunications", Qt::UserRole+1); + visibleItemsSourceModel->appendRow(communicationsItem); + + QStandardItem *systemServicesItem = new QStandardItem(); + systemServicesItem->setText(i18nc("Items about the status of the system, such as a filesystem indexer", "System services")); + systemServicesItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + checked = cg.readEntry("ShowSystemServices", + gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES)); + systemServicesItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + systemServicesItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); + systemServicesItem->setData("ShowSystemServices", Qt::UserRole+1); + visibleItemsSourceModel->appendRow(systemServicesItem); + + QStandardItem *hardwareControlItem = new QStandardItem(); + hardwareControlItem->setText(i18nc("Items about hardware, such as battery or volume control", "Hardware control")); + hardwareControlItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + checked = cg.readEntry("ShowHardware", + gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE)); + hardwareControlItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + hardwareControlItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); + hardwareControlItem->setData("ShowHardware", Qt::UserRole+1); + visibleItemsSourceModel->appendRow(hardwareControlItem); + + QStandardItem *unknownItem = new QStandardItem(); + unknownItem->setText(i18nc("Other uncategorized systemtray items", "Miscellaneous")); + unknownItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + checked = cg.readEntry("ShowUnknown", + gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN)); + unknownItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + unknownItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); + unknownItem->setData("ShowUnknown", Qt::UserRole+1); + visibleItemsSourceModel->appendRow(unknownItem); + + QStringList ownApplets = s_manager->applets(this); + + QMap sortedApplets; + foreach (const KPluginInfo &info, Plasma::Applet::listAppletInfo()) { + KService::Ptr service = info.service(); + if (service->property("X-Plasma-NotificationArea", QVariant::Bool).toBool()) { + // if we already have a plugin with this exact name in it, then check if it is the + // same plugin and skip it if it is indeed already listed + if (sortedApplets.contains(info.name())) { + + bool dupe = false; + // it is possible (though poor form) to have multiple applets + // with the same visible name but different plugins, so we hve to check all values + foreach (const KPluginInfo &existingInfo, sortedApplets.values(info.name())) { + if (existingInfo.pluginName() == info.pluginName()) { + dupe = true; + break; + } + } + + if (dupe) { + continue; + } + } + + // insertMulti becase it is possible (though poor form) to have multiple applets + // with the same visible name but different plugins + sortedApplets.insertMulti(info.name(), info); + } + } + + foreach (const KPluginInfo &info, sortedApplets) { + QStandardItem *item = new QStandardItem(); + item->setText(info.name()); + item->setIcon(KIcon(info.icon())); + item->setCheckable(true); + item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + item->setCheckState(ownApplets.contains(info.pluginName()) ? Qt::Checked : Qt::Unchecked); + item->setData(i18nc("Extra items to be manually added in the systray, such as little Plasma widgets", "Extra Items"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); + item->setData(info.pluginName(), Qt::UserRole+2); + visibleItemsSourceModel->appendRow(item); + } + + connect(visibleItemsSourceModel, SIGNAL(itemChanged(QStandardItem*)), parent, SLOT(settingsModified())); +} + +//not always the corona lock action is available: netbook locks per-containment +void Applet::unlockContainment() +{ + if (containment() && containment()->immutability() == Plasma::UserImmutable) { + containment()->setImmutability(Plasma::Mutable); + } +} + +void Applet::configAccepted() +{ + KConfigGroup cg = config(); + KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); + + QStringList hiddenTypes; + QStringList alwaysShownTypes; + QTreeWidget *hiddenList = m_autoHideUi.icons; + for (int i = 0; i < hiddenList->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = hiddenList->topLevelItem(i); + KComboBox *itemCombo = static_cast(hiddenList->itemWidget(item, 1)); + //kDebug() << (item->checkState() == Qt::Checked) << item->data(Qt::UserRole).toString(); + const QString taskTypeId = item->data(0, Qt::UserRole).toString(); + if (itemCombo->currentIndex() == 1) { + //Always hidden + hiddenTypes << taskTypeId; + } else if (itemCombo->currentIndex() == 2) { + //Always visible + alwaysShownTypes << taskTypeId; + } + + KKeySequenceWidget *keySeq = static_cast(hiddenList->itemWidget(item, 2)); + QKeySequence seq = keySeq->keySequence(); + Task *task = 0; + //FIXME: terribly inefficient + foreach (Task *candidateTask, s_manager->tasks()) { + if (candidateTask->taskId() == taskTypeId) { + task = candidateTask; + break; + } + } + + if (task) { + if (!task->isWidget()) { + DBusSystemTrayTask *dbus_task = qobject_cast(task); + if (dbus_task) { + QString shortcut = seq.toString(); + dbus_task->setShortcut(shortcut); + QString action_name = _getActionName(task); + if (seq.isEmpty()) + shortcutsConfig.deleteEntry(action_name); + else + shortcutsConfig.writeEntry(action_name, shortcut); + dbus_task->setShortcut(shortcut); + } + } else { + Plasma::Applet *applet = qobject_cast( task->widget(this) ); + if (applet) { + applet->setGlobalShortcut(KShortcut(seq)); + } + } + } + } + + cg.writeEntry("hidden", hiddenTypes); + cg.writeEntry("alwaysShown", alwaysShownTypes); + + QStringList applets = s_manager->applets(this); + + for (int i = 0; i <= m_visibleItemsSourceModel.data()->rowCount() - 1; i++) { + QModelIndex index = m_visibleItemsSourceModel.data()->index(i, 0); + QString itemCategory = index.data(Qt::UserRole+1).toString(); + QString appletName = index.data(Qt::UserRole+2).toString(); + if (!itemCategory.isEmpty()) { + QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index); + cg.writeEntry(itemCategory, (item->checkState() == Qt::Checked)); + } else if (!appletName.isEmpty()){ + QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index); + + if (item->checkState() != Qt::Unchecked && !applets.contains(appletName)) { + s_manager->addApplet(appletName, this); + } + + if (item->checkState() == Qt::Checked) { + applets.removeAll(appletName); + } + } + } + + foreach (const QString &appletName, applets) { + s_manager->removeApplet(appletName, this); + } + + emit configNeedsSaving(); +} + +void Applet::checkDefaultApplets() +{ + if (config().readEntry("DefaultAppletsAdded", false)) { + m_firstRun = false; + return; + } + + + QStringList applets = s_manager->applets(this); + if (!applets.contains("org.kde.networkmanagement")) { + s_manager->addApplet("org.kde.networkmanagement", this); + } + + if (!applets.contains("notifier")) { + s_manager->addApplet("notifier", this); + } + + if (!applets.contains("org.kde.notifications")) { + s_manager->addApplet("org.kde.notifications", this); + } + + if (!applets.contains("battery")) { + Plasma::DataEngineManager *engines = Plasma::DataEngineManager::self(); + Plasma::DataEngine *power = engines->loadEngine("powermanagement"); + if (power) { + const QStringList &batteries = power->query("Battery")["Sources"].toStringList(); + if (!batteries.isEmpty()) { + s_manager->addApplet("battery", this); + } + } + engines->unloadEngine("powermanagement"); + } + + config().writeEntry("DefaultAppletsAdded", true); +} + + +int Applet::getVisibilityPreference(QObject *task) const +{ + Task *t = qobject_cast(task); + if (!t) + return AutoVisibility; + if ( m_hiddenTypes.contains(t->taskId()) ) { + return AlwaysHidden; + } else if ( m_alwaysShownTypes.contains(t->taskId()) ) { + return AlwaysShown; + } + return AutoVisibility; +} + +QAction *Applet::createShortcutAction(QString action_id) const +{ + KAction *action = new KAction(parent()); + action->setObjectName(action_id); + return action; +} + +void Applet::updateShortcutAction(QAction *action, QString shortcut) const +{ + KAction *act = qobject_cast(action); + if (!act) { + return; + } + + act->forgetGlobalShortcut(); + if (!shortcut.isEmpty()) { + act->setGlobalShortcut(KShortcut(QKeySequence(shortcut)), + KAction::ShortcutTypes(KAction::ActiveShortcut | KAction::DefaultShortcut), + KAction::NoAutoloading); + } +} + +void Applet::destroyShortcutAction(QAction *action) const +{ + KAction *act = qobject_cast(action); + if (act) { + delete act; + } +} + +void Applet::showMenu(QObject *menu_var, int x, int y, QObject *item_var) const +{ + QGraphicsItem *item = qobject_cast(item_var); + QMenu *menu = qobject_cast(menu_var); + if (menu) { + QPoint pos(x, y); + menu->adjustSize(); + if (item && containment() && containment()->corona()) { + pos = containment()->corona()->popupPosition(item, menu->size()); + } else { + pos = Plasma::Applet::popupPosition(menu->size()); + } + menu->popup(pos); + } +} + +void Applet::hideFromTaskbar(qulonglong win_id) const +{ + if (win_id > 0) { + KWindowSystem::setState(win_id, NET::SkipTaskbar | NET::SkipPager); + } +} + +QString Applet::getUniqueId(QObject *obj) const +{ + return QString::number(reinterpret_cast(obj)); +} + +QPoint Applet::popupPosition(QObject *item_var, QSize size, int align) const +{ + QGraphicsItem *item = qobject_cast(item_var); + if ( item && containment() && containment()->corona() ) { + return containment()->corona()->popupPosition(item, size, (Qt::AlignmentFlag)align); + } + return Plasma::Applet::popupPosition(size, (Qt::AlignmentFlag)align); +} + + +} + +#include "applet.moc" diff --git a/plasma/generic/applets/systemtray/ui/applet.h b/plasma/generic/applets/systemtray/ui/applet.h new file mode 100644 index 00000000..0b4a8697 --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/applet.h @@ -0,0 +1,174 @@ +/*************************************************************************** + * applet.h * + * * + * Copyright (C) 2008 Jason Stubbs * + * Copyright (C) 2010 Marco Martin * + * Copyright (C) 2012 Dmitry Ashkadov * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef APPLET_H +#define APPLET_H + +#include + +#include "ui_autohide.h" +#include "ui_visibleitems.h" + +#include "../core/task.h" + +namespace Plasma +{ +class ExtenderItem; +class TabBar; +class Dialog; +class DeclarativeWidget; +} + +class QStandardItemModel; + +namespace SystemTray +{ + +class Manager; + +class Applet : public Plasma::Applet +{ + Q_OBJECT + + Q_ENUMS(FormFactor) + Q_ENUMS(Location) + Q_ENUMS(VisibilityPreference) + + Q_PROPERTY(bool firstRun READ isFirstRun) + + // TODO: remove these properties in the future (they will be supported in Plasma::Applet) + Q_PROPERTY(int formFactor READ formFactor NOTIFY formFactorChanged) + Q_PROPERTY(int location READ location NOTIFY locationChanged) + +public: + // Form factor + enum FormFactor + { + Planar = Plasma::Planar, + MediaCenter = Plasma::MediaCenter, + Horizontal = Plasma::Horizontal, + Vertical = Plasma::Vertical + }; + + // Location + enum Location + { + Floating = Plasma::Floating, + Desktop = Plasma::Desktop, + FullScreen = Plasma::FullScreen, + TopEdge = Plasma::TopEdge, + BottomEdge = Plasma::BottomEdge, + LeftEdge = Plasma::LeftEdge, + RightEdge = Plasma::RightEdge + }; + + /// User's preference of visibility of task + enum VisibilityPreference { + AutoVisibility = 0, + AlwaysHidden, + AlwaysShown + }; + + explicit Applet(QObject *parent, const QVariantList &arguments = QVariantList()); + ~Applet(); + + void init(); + void constraintsEvent(Plasma::Constraints constraints); + Manager *manager() const; + QSet shownCategories() const; + bool isFirstRun(); + + Q_INVOKABLE int getVisibilityPreference(QObject *task) const; + Q_INVOKABLE QAction* createShortcutAction(QString action_id) const; + Q_INVOKABLE void updateShortcutAction(QAction *action, QString shortcut) const; + Q_INVOKABLE void destroyShortcutAction(QAction *action) const; + Q_INVOKABLE void showMenu(QObject *menu, int x, int y, QObject *item) const; + Q_INVOKABLE void hideFromTaskbar(qulonglong win_id) const; + Q_INVOKABLE QString getUniqueId(QObject *obj) const; + Q_INVOKABLE QPoint popupPosition(QObject *item, QSize size = QSize(0, 0), int align = Qt::AlignLeft) const; + +protected: + void createConfigurationInterface(KConfigDialog *parent); + void configChanged(); + + void mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED(event); } + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED(event); } + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); } + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); } + +signals: + void formFactorChanged(); + void locationChanged(); + void visibilityPreferenceChanged(); ///< If user has changed his preference on visibility of tasks + + /** + * This signal is emmited for each new task + * @param task a new task + */ + void newTask(QObject *task); + + /** + * This signal is emmited before task is deleted + * @param task a task that is being deleted + */ + void deletedTask(QObject *task); + +private Q_SLOTS: + void configAccepted(); + void unlockContainment(); + void propogateSizeHintChange(Qt::SizeHint which); + void checkDefaultApplets(); + + void _onAddedTask(SystemTray::Task*); + void _onRemovedTask(SystemTray::Task*); + void _onStatusChangedTask(); + + void _onWidgetCreationFinished(); + +private: + QString _getActionName(Task *task) const; + +private: + static SystemTray::Manager *s_manager; + static int s_managerUsage; + + QWeakPointer m_autoHideInterface; + QWeakPointer m_visibleItemsInterface; + QSet m_shownCategories; + QSet m_hiddenTypes; + QSet m_alwaysShownTypes; + QDateTime m_lastActivity; + Plasma::DeclarativeWidget *m_widget; + + Ui::AutoHideConfig m_autoHideUi; + Ui::VisibleItemsConfig m_visibleItemsUi; + + QWeakPointer m_visibleItemsSourceModel; + + bool m_firstRun; +}; + +} + + +#endif diff --git a/plasma/generic/applets/systemtray/ui/autohide.ui b/plasma/generic/applets/systemtray/ui/autohide.ui new file mode 100644 index 00000000..3b6efffa --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/autohide.ui @@ -0,0 +1,58 @@ + + + AutoHideConfig + + + + 0 + 0 + 422 + 253 + + + + + 0 + + + + + false + + + 3 + + + true + + + 100 + + + 100 + + + true + + + + Item + + + + + Visibility + + + + + Keyboard Shortcut + + + + + + + + + diff --git a/plasma/generic/applets/systemtray/ui/mouseredirectarea.cpp b/plasma/generic/applets/systemtray/ui/mouseredirectarea.cpp new file mode 100644 index 00000000..753ece9a --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/mouseredirectarea.cpp @@ -0,0 +1,185 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: GPLv2+ + * Authors: Dmitry Ashkadov + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . + **********************************************************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Includes +#include "mouseredirectarea.h" + +#include "../core/task.h" + +#include +#include +#include +#include +#include + +#include + + +namespace SystemTray +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class MouseRedirectArea +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +template void MouseRedirectArea::forwardEvent(T *event, bool is_context_menu) +{ + if (!isEnabled() || !(m_task || m_widget) || !m_applet) + return; + QGraphicsObject *target = m_widget ? m_widget : (m_task ? m_task->widget(m_applet, false) : 0); + if (!target) + return; + + QPointF delta = target->sceneBoundingRect().center() - event->scenePos(); + event->setScenePos(target->sceneBoundingRect().center()); + event->setScreenPos((event->screenPos() + delta).toPoint()); + + if (m_isApplet) { + if (is_context_menu && m_applet->containment()) { + // redirect context menu event to containment because it is responsible for items of context menu of an applet + event->setPos(m_applet->containment()->mapFromScene(event->scenePos())); + scene()->sendEvent(m_applet->containment(), event); + } else { + event->setPos(scene()->itemAt(event->scenePos())->mapFromScene(event->scenePos())); + scene()->sendEvent(scene()->itemAt(event->scenePos()), event); + } + } else { + event->setPos(target->boundingRect().center()); + scene()->sendEvent(target, event); + } +} + + +MouseRedirectArea::MouseRedirectArea(QDeclarativeItem *parent) + : QDeclarativeItem(parent) + , m_widget(0) + , m_task(0) + , m_target(0) + , m_applet(0) + , m_isApplet(false) +{ + setAcceptHoverEvents(true); + setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton); +} + +void MouseRedirectArea::setTarget(QObject *t) +{ + if (m_target != t) { + m_target = t; + processTarget(); + } +} + +void MouseRedirectArea::setApplet(QObject *a) +{ + Plasma::Applet *applet = qobject_cast(a); + if (m_applet != applet) { + m_applet = applet; + processTarget(); // it may be that target already set so we should process it + } +} + + +void MouseRedirectArea::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + if (!m_isApplet && m_widget) { + switch (event->orientation()) { + case Qt::Vertical: + emit scrollVert(event->delta()); + break; + case Qt::Horizontal: + emit scrollHorz(event->delta()); + break; + default: + break; + } + return; + } + forwardEvent(event); +} + + +void MouseRedirectArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + forwardEvent(event, true); +} + + +void MouseRedirectArea::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (!m_isApplet && m_widget) { + switch (event->button()) { + case Qt::MiddleButton: emit clickMiddle(); return; + case Qt::RightButton: emit clickRight(); return; + default: break; + } + } + forwardEvent(event); +} + + +void MouseRedirectArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + forwardEvent(event); +} + +void MouseRedirectArea::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + forwardEvent(event); + emit entered(); +} + + +void MouseRedirectArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + forwardEvent(event); + emit exited(); +} + +void MouseRedirectArea::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + QPointF pos = event->pos(); + emit changedMousePos(pos.x(), pos.y()); + forwardEvent(event); +} + +void MouseRedirectArea::processTarget() +{ + // we have target as QObject but it may be Task or Widget + if (!m_applet || !m_target) + return; // applet and target must be already set + + m_isApplet = false; + m_widget = 0; + m_task = 0; + m_task = qobject_cast(m_target); + if (m_task) { + QGraphicsWidget *widget = m_task->widget(m_applet); + m_isApplet = (qobject_cast(widget) != 0); + } else { + m_widget = qobject_cast(m_target); + } +} + + +} // namespace SystemTray diff --git a/plasma/generic/applets/systemtray/ui/mouseredirectarea.h b/plasma/generic/applets/systemtray/ui/mouseredirectarea.h new file mode 100644 index 00000000..15d114af --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/mouseredirectarea.h @@ -0,0 +1,97 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: GPLv2+ + * Authors: Dmitry Ashkadov + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . + **********************************************************************************************************************/ + + +#ifndef __SYSTEMTRAY__MOUSEREDIRECTAREA_H +#define __SYSTEMTRAY__MOUSEREDIRECTAREA_H + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Includes +#include + +#include + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Forward declarations +class QGraphicsWidget; +class QGraphicsSceneWheelEvent; +class QGraphicsSceneContextMenuEvent; + + +namespace SystemTray +{ +class Task; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** @class MouseRedirectArea + * This helper class is intended to handle and redirect some mouse events + */ +class MouseRedirectArea: public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QObject* target READ target WRITE setTarget) + Q_PROPERTY(QObject* applet READ applet WRITE setApplet) +public: + explicit MouseRedirectArea(QDeclarativeItem *parent = 0); + + QObject* target() const { return m_target; } + void setTarget(QObject* t); + QObject *applet() const { return m_applet; } + void setApplet(QObject *applet); + +signals: + void clickMiddle(); + void clickRight(); + void scrollVert(int delta); + void scrollHorz(int delta); + void changedMousePos(qreal mouseX, qreal mouseY); + void entered(); + void exited(); + +private: //Events + virtual void wheelEvent(QGraphicsSceneWheelEvent *event); + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + + template void forwardEvent(T *event, bool is_context_menu = false); + +private: // Methods + void processTarget(); + +private: //Variables + QGraphicsObject *m_widget; + Task *m_task; + QObject *m_target; + Plasma::Applet *m_applet; + bool m_isApplet; // true if target is an applet +}; + +} // namespace SystemTray + +#endif // __SYSTEMTRAY__MOUSEREDIRECTAREA_H diff --git a/plasma/generic/applets/systemtray/ui/visibleitems.ui b/plasma/generic/applets/systemtray/ui/visibleitems.ui new file mode 100644 index 00000000..dc747680 --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/visibleitems.ui @@ -0,0 +1,87 @@ + + + VisibleItemsConfig + + + + 0 + 0 + 380 + 360 + + + + + 0 + 360 + + + + + 0 + + + + + Widgets are currently locked, disabling some options. + + + Qt::AlignCenter + + + true + + + + + + + + + Qt::Horizontal + + + + 34 + 24 + + + + + + + + Unlock Widgets + + + + + + + Qt::Horizontal + + + + 34 + 24 + + + + + + + + + + + + + + KCategorizedView + QListView +
    kcategorizedview.h
    +
    +
    + + +
    diff --git a/plasma/generic/applets/systemtray/ui/widgetitem.cpp b/plasma/generic/applets/systemtray/ui/widgetitem.cpp new file mode 100644 index 00000000..0756be96 --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/widgetitem.cpp @@ -0,0 +1,138 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: GPLv2+ + * Authors: Dmitry Ashkadov + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . + **********************************************************************************************************************/ + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Includes +#include "widgetitem.h" + +#include "../core/task.h" + +#include +#include + +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +namespace SystemTray +{ +// class WidgetItem +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +WidgetItem::WidgetItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_applet(0) +{ + setClip(false); + connect(this, SIGNAL(widthChanged()), this, SLOT(afterWidthChanged()), Qt::QueuedConnection); + connect(this, SIGNAL(heightChanged()), this, SLOT(afterHeightChanged()), Qt::QueuedConnection); +} + + +WidgetItem::~WidgetItem() +{ + unbind(); +} + +void WidgetItem::setTask(QObject *task) +{ + Task *t = qobject_cast(task); + if (m_task.data() == t) + return; + unbind(); + m_task = t; + bind(); + emit changedTask(); +} + +void WidgetItem::setApplet(QObject *a) +{ + Plasma::Applet *applet = qobject_cast(a); + if (m_applet == applet) + return; + unbind(); + m_applet = applet; + bind(); +} + +void WidgetItem::unbind() +{ + if (m_applet && m_task) { + QGraphicsWidget *widget = m_task.data()->widget(m_applet, false); + if (widget && widget->parentItem() == this) { + widget->hide(); + widget->setParentItem(0); + } + } +} + +void WidgetItem::bind() +{ + if (m_applet && m_task) { + QGraphicsWidget *widget = m_task.data()->widget(m_applet); + if (widget) { + widget->setParentItem(this); + widget->setPos(0, 0); + widget->setPreferredSize(width(), width()); + widget->setMinimumSize(width(), width()); + widget->setMaximumSize(width(), width()); + widget->show(); + } + } +} + + +void WidgetItem::afterWidthChanged() +{ + if (!m_applet || !m_task) { + return; + } + + QGraphicsWidget *widget = m_task.data()->widget(m_applet); + if (widget) { + widget->setPreferredSize(width(), width()); + widget->setMinimumSize(width(), width()); + widget->setMaximumSize(width(), width()); + widget->show(); + } +} + +void WidgetItem::afterHeightChanged() +{ + if (!m_applet || !m_task) { + return; + } + + QGraphicsWidget *widget = m_task.data()->widget(m_applet); + if (widget) { + widget->setPreferredSize(width(), width()); + widget->setMinimumSize(width(), width()); + widget->setMaximumSize(width(), width()); + widget->show(); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +} //namespace SystemTray + diff --git a/plasma/generic/applets/systemtray/ui/widgetitem.h b/plasma/generic/applets/systemtray/ui/widgetitem.h new file mode 100644 index 00000000..112b9b32 --- /dev/null +++ b/plasma/generic/applets/systemtray/ui/widgetitem.h @@ -0,0 +1,81 @@ +/*********************************************************************************************************************** + * KDE System Tray (Plasmoid) + * + * Copyright (C) 2012 ROSA + * License: GPLv2+ + * Authors: Dmitry Ashkadov + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . + **********************************************************************************************************************/ + + +#ifndef __SYSTEMTRAY__WIDGETITEM_H +#define __SYSTEMTRAY__WIDGETITEM_H + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Includess +#include "../core/task.h" + +#include + +#include + +namespace SystemTray +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class WidgetItem +/** @class WidgetItem + * Represents declarative item containing an specified graphics widget. + */ +class WidgetItem: public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QObject* applet READ applet WRITE setApplet) ///< host applet + Q_PROPERTY(QObject* task READ task WRITE setTask NOTIFY changedTask) ///< task +public: + explicit WidgetItem(QDeclarativeItem *parent = 0); + virtual ~WidgetItem(); + +public: + QObject *task() const { return m_task.data(); } + void setTask(QObject *task); + + /** + * @return applet as a host for widget + */ + QObject *applet() const { return m_applet; } + void setApplet(QObject *applet); + +signals: + void changedTask(); + +private Q_SLOTS: + void afterWidthChanged(); + void afterHeightChanged(); + +private: + void bind(); + void unbind(); + + Plasma::Applet *m_applet; + QWeakPointer m_task; +}; + +} //namespace SystemTray + +#endif // __SYSTEMTRAY__WIDGETITEM_H diff --git a/plasma/generic/applets/webbrowser/CMakeLists.txt b/plasma/generic/applets/webbrowser/CMakeLists.txt new file mode 100644 index 00000000..8861595e --- /dev/null +++ b/plasma/generic/applets/webbrowser/CMakeLists.txt @@ -0,0 +1,19 @@ +project(webbrowser) + +set(webbrowser_SRCS + bookmarksdelegate.cpp + bookmarkitem.cpp + webbrowser.cpp + webviewoverlay.cpp + browserhistorycombobox.cpp + browsermessagebox.cpp + errorpage.cpp + webbrowserpage.cpp + ) + +kde4_add_ui_files(webbrowser_SRCS webbrowserconfig.ui ) +kde4_add_plugin(plasma_applet_webbrowser ${webbrowser_SRCS}) +target_link_libraries(plasma_applet_webbrowser ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS} ${QT_QTWEBKIT_LIBRARY} ${KDE4_KDEWEBKIT_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KPARTS_LIBS}) + +install(TARGETS plasma_applet_webbrowser DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-applet-webbrowser.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/applets/webbrowser/Messages.sh b/plasma/generic/applets/webbrowser/Messages.sh new file mode 100755 index 00000000..f2af74d8 --- /dev/null +++ b/plasma/generic/applets/webbrowser/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_applet_webbrowser.pot +rm -f rc.cpp diff --git a/plasma/generic/applets/webbrowser/bookmarkitem.cpp b/plasma/generic/applets/webbrowser/bookmarkitem.cpp new file mode 100644 index 00000000..b6735ede --- /dev/null +++ b/plasma/generic/applets/webbrowser/bookmarkitem.cpp @@ -0,0 +1,70 @@ +/* Copyright (C) 2008 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "bookmarkitem.h" + + +#include +#include +#include + +BookmarkItem::BookmarkItem(KBookmark &bookmark) + : QStandardItem(), + m_bookmark(bookmark) +{ +} + +BookmarkItem::~BookmarkItem() +{ +} + + + +KBookmark BookmarkItem::bookmark() const +{ + return m_bookmark; +} + +void BookmarkItem::setBookmark(const KBookmark &bookmark) +{ + m_bookmark = bookmark; +} + +QVariant BookmarkItem::data(int role) const +{ + if (m_bookmark.isNull()) { + return QStandardItem::data(role); + } + + switch (role) + { + case Qt::DisplayRole: + return m_bookmark.text(); + case Qt::DecorationRole: + if (m_bookmark.isGroup() && m_bookmark.icon().isNull()) { + return KIcon("folder-bookmarks"); + } else { + return KIcon(m_bookmark.icon()); + } + case UrlRole: + return m_bookmark.url().prettyUrl(); + default: + return QStandardItem::data(role); + } +} + diff --git a/plasma/generic/applets/webbrowser/bookmarkitem.h b/plasma/generic/applets/webbrowser/bookmarkitem.h new file mode 100644 index 00000000..c0a950a0 --- /dev/null +++ b/plasma/generic/applets/webbrowser/bookmarkitem.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2008 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef BOOKMARKITEM_H +#define BOOKMARKITEM_H + + +#include +#include +#include + + +class BookmarkItem : public QStandardItem +{ + +public: + enum BookmarkRoles + { + UrlRole = Qt::UserRole+1 + }; + + BookmarkItem(KBookmark &bookmark); + ~BookmarkItem(); + + KBookmark bookmark() const; + void setBookmark(const KBookmark &bookmark); + QVariant data(int role) const; + + +private: + KBookmark m_bookmark; +}; + +#endif diff --git a/plasma/generic/applets/webbrowser/bookmarksdelegate.cpp b/plasma/generic/applets/webbrowser/bookmarksdelegate.cpp new file mode 100644 index 00000000..d5cab3a8 --- /dev/null +++ b/plasma/generic/applets/webbrowser/bookmarksdelegate.cpp @@ -0,0 +1,103 @@ +/* + Copyright 2008 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Own +#include "bookmarksdelegate.h" + +#include +#include + +// Qt +#include +#include +#include +#include + +// KDE +#include +#include +#include +#include + +// plasma +#include +#include + + +class BookmarksDelegatePrivate +{ +public: + BookmarksDelegatePrivate() { + } + + ~BookmarksDelegatePrivate() { + } +}; + + + + +BookmarksDelegate::BookmarksDelegate(QObject *parent) + : QStyledItemDelegate(parent), + d(/*new BookmarksDelegatePrivate*/0) +{ +} + +BookmarksDelegate::~BookmarksDelegate() +{ + delete d; +} + +void BookmarksDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QStyledItemDelegate::paint(painter, option, index); + + if (option.state & (QStyle::State_MouseOver | QStyle::State_Selected)) { + QRect destroyIconRect = QStyle::alignedRect(option.direction, + option.decorationPosition == QStyleOptionViewItem::Left ? + Qt::AlignRight : Qt::AlignLeft, + QSize(option.rect.height(), option.rect.height()), + option.rect); + painter->drawPixmap(destroyIconRect, KIcon("list-remove").pixmap(KIconLoader::SizeSmall, KIconLoader::SizeSmall)); + } +} + +bool BookmarksDelegate::editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + QRect destroyIconRect = QStyle::alignedRect(option.direction, + option.decorationPosition == QStyleOptionViewItem::Left ? + Qt::AlignRight : Qt::AlignLeft, + QSize(option.rect.height(), option.rect.height()), + option.rect); + + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + + if (destroyIconRect.contains(mouseEvent->pos())) { + emit destroyBookmark(index); + return true; + } + } + + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + diff --git a/plasma/generic/applets/webbrowser/bookmarksdelegate.h b/plasma/generic/applets/webbrowser/bookmarksdelegate.h new file mode 100644 index 00000000..1706aef8 --- /dev/null +++ b/plasma/generic/applets/webbrowser/bookmarksdelegate.h @@ -0,0 +1,55 @@ +/* + Copyright 2008 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef BOOKMARKSDELEGATE_H +#define BOOKMARKSDELEGATE_H + +// Qt +#include + + +class BookmarksDelegatePrivate; + +class BookmarksDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + + + BookmarksDelegate(QObject *parent = 0); + ~BookmarksDelegate(); + + //Reimplemented + virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + + + protected: + bool editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index); + +Q_SIGNALS: + void destroyBookmark(const QModelIndex &index); + +private: + BookmarksDelegatePrivate * const d; +}; + +#endif // BOOKMARKSDELEGATE_H diff --git a/plasma/generic/applets/webbrowser/browserhistorycombobox.cpp b/plasma/generic/applets/webbrowser/browserhistorycombobox.cpp new file mode 100644 index 00000000..73b199c0 --- /dev/null +++ b/plasma/generic/applets/webbrowser/browserhistorycombobox.cpp @@ -0,0 +1,446 @@ +/* + * Copyright 2008 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "browserhistorycombobox.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Plasma +{ + +class ComboBoxPrivate +{ +public: + ComboBoxPrivate(BrowserHistoryComboBox *comboBox) + : q(comboBox), + background(0), + customFont(false), + underMouse(false) + { + } + + ~ComboBoxPrivate() + { + } + + void syncActiveRect(); + void syncBorders(); + void animationUpdate(qreal progress); + + BrowserHistoryComboBox *q; + + FrameSvg *background; + FrameSvg *lineEditBackground; + int animId; + QPropertyAnimation *animation; + qreal opacity; + QRectF activeRect; + QStyle *style; + bool customFont; + bool underMouse; + Plasma::ComboBox *styleParent; + int progressValue; + bool displayProgress; +}; + +void ComboBoxPrivate::syncActiveRect() +{ + background->setElementPrefix("normal"); + + qreal left, top, right, bottom; + background->getMargins(left, top, right, bottom); + + background->setElementPrefix("active"); + qreal activeLeft, activeTop, activeRight, activeBottom; + background->getMargins(activeLeft, activeTop, activeRight, activeBottom); + + activeRect = QRectF(QPointF(0, 0), q->size()); + activeRect.adjust(left - activeLeft, top - activeTop, + -(right - activeRight), -(bottom - activeBottom)); + + background->setElementPrefix("normal"); +} + +void ComboBoxPrivate::syncBorders() +{ + //set margins from the normal element + qreal left, top, right, bottom; + + background->setElementPrefix("normal"); + background->getMargins(left, top, right, bottom); + q->setContentsMargins(left, top, right, bottom); + + //calc the rect for the over effect + syncActiveRect(); + + KComboBox *native = q->nativeWidget(); + if (customFont) { + native->setFont(q->font()); + } else { + native->setFont(Theme::defaultTheme()->font(Theme::DefaultFont)); + } +} + +void ComboBoxPrivate::animationUpdate(qreal progress) +{ + opacity = progress; + + // explicit update + q->update(); +} + +BrowserHistoryComboBox::BrowserHistoryComboBox(QGraphicsWidget *parent) + : QGraphicsProxyWidget(parent), + d(new ComboBoxPrivate(this)) +{ + d->background = new FrameSvg(this); + d->background->setImagePath("widgets/button"); + d->background->setCacheAllRenderedFrames(true); + d->background->setElementPrefix("normal"); + d->lineEditBackground = new FrameSvg(this); + d->lineEditBackground->setImagePath("widgets/lineedit"); + d->lineEditBackground->setCacheAllRenderedFrames(true); + setZValue(900); + + setAcceptHoverEvents(true); + + d->styleParent = new Plasma::ComboBox(); + d->style = d->styleParent->nativeWidget()->style(); + + setNativeWidget(new KComboBox); + + d->animation = new QPropertyAnimation(this, "animationUpdate", this); + d->animation->setStartValue(0); + d->animation->setEndValue(1); + + connect(Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(syncBorders())); + + d->displayProgress = false; + d->progressValue = 0; +} + +BrowserHistoryComboBox::~BrowserHistoryComboBox() +{ + delete d->styleParent; + delete d; +} + +QString BrowserHistoryComboBox::text() const +{ + return static_cast(widget())->currentText(); +} + +void BrowserHistoryComboBox::setStyleSheet(const QString &stylesheet) +{ + widget()->setStyleSheet(stylesheet); +} + +QString BrowserHistoryComboBox::styleSheet() +{ + return widget()->styleSheet(); +} + +void BrowserHistoryComboBox::setNativeWidget(KComboBox *nativeWidget) +{ + if (widget()) { + widget()->deleteLater(); + } + + connect(nativeWidget, SIGNAL(activated(QString)), this, SIGNAL(activated(QString))); + connect(nativeWidget, SIGNAL(currentIndexChanged(QString)), + this, SIGNAL(textChanged(QString))); + + setWidget(nativeWidget); + + nativeWidget->setAttribute(Qt::WA_NoSystemBackground); + nativeWidget->setStyle(d->style); + + d->syncBorders(); +} + +KComboBox *BrowserHistoryComboBox::nativeWidget() const +{ + return static_cast(widget()); +} + +void BrowserHistoryComboBox::addItem(const QString &text) +{ + static_cast(widget())->addItem(text); +} + +void BrowserHistoryComboBox::clear() +{ + static_cast(widget())->clear(); +} + +void BrowserHistoryComboBox::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + if (d->background) { + //resize needed panels + d->syncActiveRect(); + + d->background->setElementPrefix("focus"); + d->background->resizeFrame(size()); + + d->background->setElementPrefix("active"); + d->background->resizeFrame(d->activeRect.size()); + + d->background->setElementPrefix("normal"); + d->background->resizeFrame(size()); + } + + QGraphicsProxyWidget::resizeEvent(event); +} + +void BrowserHistoryComboBox::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + QAbstractAnimation::State animState = d->animation->state(); + + if (!styleSheet().isNull() || + Theme::defaultTheme()->useNativeWidgetStyle()) { + QGraphicsProxyWidget::paint(painter, option, widget); + return; + } + + if (nativeWidget()->isEditable()) { + if (d->displayProgress) { + painter->fillRect(QRectF(option->rect.x() + 2, option->rect.y() + 3, (int) (((qreal) (option->rect.width() - 4) / 100) * d->progressValue), option->rect.height() - 4), Theme::defaultTheme()->color(Theme::LinkColor)); + } + if (d->lineEditBackground->hasElement("hint-focus-over-base")) { + QGraphicsProxyWidget::paint(painter, option, widget); + } + if (animState != QAbstractAnimation::Stopped || hasFocus() || d->underMouse) { + if (hasFocus()) { + d->lineEditBackground->setElementPrefix("focus"); + } else { + d->lineEditBackground->setElementPrefix("hover"); + } + qreal left, top, right, bottom; + d->lineEditBackground->getMargins(left, top, right, bottom); + d->lineEditBackground->resizeFrame(size()+QSizeF(left+right, top+bottom)); + if (qFuzzyCompare(d->opacity, (qreal)1.0)) { + d->lineEditBackground->paintFrame(painter, QPoint(-left, -top)); + } else { + QPixmap bufferPixmap = d->lineEditBackground->framePixmap(); + QPainter buffPainter(&bufferPixmap); + buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + buffPainter.fillRect(bufferPixmap.rect(), QColor(0, 0, 0, 256*d->opacity)); + buffPainter.end(); + painter->drawPixmap(bufferPixmap.rect().translated(QPoint(-left, -top)), bufferPixmap, bufferPixmap.rect()); + } + } + if (!d->lineEditBackground->hasElement("hint-focus-over-base")) { + QGraphicsProxyWidget::paint(painter, option, widget); + } + return; + } + + QPixmap bufferPixmap; + + //normal button + if (isEnabled()) { + d->background->setElementPrefix("normal"); + + if (animState == QAbstractAnimation::Stopped) { + d->background->paintFrame(painter); + } + //disabled widget + } else { + bufferPixmap = QPixmap(rect().size().toSize()); + bufferPixmap.fill(Qt::transparent); + + QPainter buffPainter(&bufferPixmap); + d->background->paintFrame(&buffPainter); + buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + buffPainter.fillRect(bufferPixmap.rect(), QColor(0, 0, 0, 128)); + + painter->drawPixmap(0, 0, bufferPixmap); + } + + //if is under mouse draw the animated glow overlay + if (isEnabled() && acceptHoverEvents()) { + if (animState!= QAbstractAnimation::Stopped) { + d->background->setElementPrefix("normal"); + QPixmap normalPix = d->background->framePixmap(); + d->background->setElementPrefix("active"); + painter->drawPixmap( + d->activeRect.topLeft(), + PaintUtils::transition(d->background->framePixmap(), normalPix, 1 - d->opacity)); + } else if (isUnderMouse()) { + d->background->setElementPrefix("active"); + d->background->paintFrame(painter, d->activeRect.topLeft()); + } + } + + if (nativeWidget()->hasFocus()) { + d->background->setElementPrefix("focus"); + d->background->paintFrame(painter); + } + + painter->setPen(Theme::defaultTheme()->color(Theme::ButtonTextColor)); + + QStyleOptionComboBox comboOpt; + + comboOpt.initFrom(nativeWidget()); + + comboOpt.palette.setColor( + QPalette::ButtonText, Theme::defaultTheme()->color(Theme::ButtonTextColor)); + comboOpt.currentIcon = nativeWidget()->itemIcon( + nativeWidget()->currentIndex()); + comboOpt.currentText = nativeWidget()->itemText( + nativeWidget()->currentIndex()); + comboOpt.editable = false; + + nativeWidget()->style()->drawControl( + QStyle::CE_ComboBoxLabel, &comboOpt, painter, nativeWidget()); + comboOpt.rect = nativeWidget()->style()->subControlRect( + QStyle::CC_ComboBox, &comboOpt, QStyle::SC_ComboBoxArrow, nativeWidget()); + nativeWidget()->style()->drawPrimitive( + QStyle::PE_IndicatorArrowDown, &comboOpt, painter, nativeWidget()); +} + +void BrowserHistoryComboBox::setAnimationUpdate(qreal progress) +{ + d->animationUpdate(progress); +} + +qreal BrowserHistoryComboBox::animationUpdate() const +{ + return d->opacity; +} + +void BrowserHistoryComboBox::focusInEvent(QFocusEvent *event) +{ + if (nativeWidget()->isEditable() && !d->underMouse) { + const int FadeInDuration = 75; + + if (d->animation->state() != QAbstractAnimation::Stopped) { + d->animation->stop(); + } + d->animation->setDuration(FadeInDuration); + d->animation->setDirection(QAbstractAnimation::Forward); + d->animation->start(); + } + + QGraphicsProxyWidget::focusInEvent(event); +} + +void BrowserHistoryComboBox::focusOutEvent(QFocusEvent *event) +{ + if (nativeWidget()->isEditable() && !d->underMouse) { + const int FadeOutDuration = 150; + + if (d->animation->state() != QAbstractAnimation::Stopped) { + d->animation->stop(); + } + d->animation->setDuration(FadeOutDuration); + d->animation->setDirection(QAbstractAnimation::Backward); + d->animation->start(); + } + + + QGraphicsProxyWidget::focusInEvent(event); +} + +void BrowserHistoryComboBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + d->underMouse = true; + if (nativeWidget()->isEditable() && hasFocus()) { + return; + } + const int FadeInDuration = 75; + + if (d->animation->state() != QAbstractAnimation::Stopped) { + d->animation->stop(); + } + d->animation->setDuration(FadeInDuration); + d->animation->setDirection(QAbstractAnimation::Forward); + d->animation->start(); + + d->background->setElementPrefix("active"); + + QGraphicsProxyWidget::hoverEnterEvent(event); +} + +void BrowserHistoryComboBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + d->underMouse = false; + if (nativeWidget()->isEditable() && hasFocus()) { + return; + } + + const int FadeOutDuration = 150; + + if (d->animation->state() != QAbstractAnimation::Stopped) { + d->animation->stop(); + } + d->animation->setDuration(FadeOutDuration); + d->animation->setDirection(QAbstractAnimation::Backward); + d->animation->start(); + + d->background->setElementPrefix("active"); + + QGraphicsProxyWidget::hoverLeaveEvent(event); +} + +void BrowserHistoryComboBox::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::FontChange) { + d->customFont = true; + nativeWidget()->setFont(font()); + } + + QGraphicsProxyWidget::changeEvent(event); +} + +void BrowserHistoryComboBox::setProgressValue(int value) +{ + d->progressValue = value; + update(); +} + +void BrowserHistoryComboBox::setDisplayProgress(bool enable) +{ + d->displayProgress = enable; + update(); +} + +} // namespace Plasma + +#include "browserhistorycombobox.moc" + diff --git a/plasma/generic/applets/webbrowser/browserhistorycombobox.h b/plasma/generic/applets/webbrowser/browserhistorycombobox.h new file mode 100644 index 00000000..f35a6738 --- /dev/null +++ b/plasma/generic/applets/webbrowser/browserhistorycombobox.h @@ -0,0 +1,133 @@ +/* + * Copyright 2008 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BROWSERHISTORYCOMBOBOX_H +#define BROWSERHISTORYCOMBOBOX_H + +#include + +class KComboBox; + +namespace Plasma +{ + +class ComboBoxPrivate; + +/** + * @class ComboBox plasma/widgets/combobox.h + * + * @short Provides a Plasma-themed combo box. + */ +class BrowserHistoryComboBox : public QGraphicsProxyWidget +{ + Q_OBJECT + + Q_PROPERTY(QGraphicsWidget *parentWidget READ parentWidget) + Q_PROPERTY(QString text READ text NOTIFY textChanged) + Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet) + Q_PROPERTY(KComboBox *nativeWidget READ nativeWidget WRITE setNativeWidget) + + Q_PROPERTY(qreal animationUpdate READ animationUpdate WRITE setAnimationUpdate) + +public: + explicit BrowserHistoryComboBox(QGraphicsWidget *parent = 0); + ~BrowserHistoryComboBox(); + + /** + * @return the display text + */ + QString text() const; + + /** + * Sets the stylesheet used to control the visual display of this ComboBox + * + * @arg stylesheet a CSS string + */ + void setStyleSheet(const QString &stylesheet); + + /** + * @return the stylesheet currently used with this widget + */ + QString styleSheet(); + + /** + * Sets the combo box wrapped by this ComboBox (widget must inherit KComboBox), ownership is transferred to the ComboBox + * + * @arg combo box that will be wrapped by this ComboBox + * @since KDE4.4 + */ + void setNativeWidget(KComboBox *nativeWidget); + + /** + * @return the native widget wrapped by this ComboBox + */ + KComboBox *nativeWidget() const; + + /** + * Adds an item to the combo box with the given text. The + * item is appended to the list of existing items. + */ + void addItem(const QString &text); + + void setProgressValue(int value); + + void setDisplayProgress(bool enable); + +public Q_SLOTS: + void clear(); + +Q_SIGNALS: + /** + * This signal is sent when the user chooses an item in the combobox. + * The item's text is passed. + */ + void activated(const QString &text); + + /** + * This signal is sent whenever the currentIndex in the combobox changes + * either through user interaction or programmatically. + * The item's text is passed. + */ + void textChanged(const QString &text); + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event); + void paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget); + void focusInEvent(QFocusEvent *event); + void focusOutEvent(QFocusEvent *event); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void changeEvent(QEvent *event); + +private slots: + void setAnimationUpdate(qreal progress); + qreal animationUpdate() const; + +private: + ComboBoxPrivate * const d; + + friend class ComboBoxPrivate; + Q_PRIVATE_SLOT(d, void syncBorders()) +}; + +} // namespace Plasma + +#endif // multiple inclusion guard diff --git a/plasma/generic/applets/webbrowser/browsermessagebox.cpp b/plasma/generic/applets/webbrowser/browsermessagebox.cpp new file mode 100644 index 00000000..786102b2 --- /dev/null +++ b/plasma/generic/applets/webbrowser/browsermessagebox.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "browsermessagebox.h" + +#include + +#include +#include +#include + +BrowserMessageBox::BrowserMessageBox(QGraphicsWidget *parent, QString message) + : QGraphicsWidget(parent) +{ + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); + layout->setOrientation(Qt::Horizontal); + + Plasma::Label *messageLabel = new Plasma::Label(this); + messageLabel->setText(message); + layout->addItem(messageLabel); + + m_okButton = new Plasma::PushButton(this); + m_okButton->setText(i18n("OK")); + connect(m_okButton, SIGNAL(clicked()), this, SIGNAL(okClicked())); + layout->addItem(m_okButton); + + m_cancelButton = new Plasma::PushButton(this); + m_cancelButton->setText(i18n("Cancel")); + connect(m_cancelButton, SIGNAL(clicked()), this, SIGNAL(cancelClicked())); + layout->addItem(m_cancelButton); +} + +Plasma::PushButton *BrowserMessageBox::okButton() +{ + return m_okButton; +} + +Plasma::PushButton *BrowserMessageBox::cancelButton() +{ + return m_cancelButton; +} + +#include "browsermessagebox.moc" diff --git a/plasma/generic/applets/webbrowser/browsermessagebox.h b/plasma/generic/applets/webbrowser/browsermessagebox.h new file mode 100644 index 00000000..c167ffc3 --- /dev/null +++ b/plasma/generic/applets/webbrowser/browsermessagebox.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef BROWSERMESSAGEBOX_H +#define BROWSERMESSAGEBOX_H + +#include + +namespace Plasma +{ + class PushButton; +} + +class BrowserMessageBox : public QGraphicsWidget +{ + Q_OBJECT + + public: + BrowserMessageBox(QGraphicsWidget *parent, QString message); + + Plasma::PushButton *okButton(); + Plasma::PushButton *cancelButton(); + + private: + Plasma::PushButton *m_okButton; + Plasma::PushButton *m_cancelButton; + + Q_SIGNALS: + void okClicked(); + void cancelClicked(); +}; + +#endif diff --git a/plasma/generic/applets/webbrowser/errorpage.cpp b/plasma/generic/applets/webbrowser/errorpage.cpp new file mode 100644 index 00000000..6bd14ee5 --- /dev/null +++ b/plasma/generic/applets/webbrowser/errorpage.cpp @@ -0,0 +1,158 @@ +/* This file is part of the KDE project + * + * Copyright (C) Hamish Rodda, Urs Wolfer, Davide Bettio + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "errorpage.h" + +int webKitErrorToKIOError(int eValue) +{ + switch (eValue){ + case QNetworkReply::NoError: + return 0; + + case QNetworkReply::ConnectionRefusedError: + return KIO::ERR_COULD_NOT_CONNECT; + + case QNetworkReply::HostNotFoundError: + return KIO::ERR_UNKNOWN_HOST; + + case QNetworkReply::TimeoutError: + return KIO::ERR_SERVER_TIMEOUT; + + case QNetworkReply::OperationCanceledError: + return KIO::ERR_ABORTED; + + case QNetworkReply::ProxyNotFoundError: + return KIO::ERR_UNKNOWN_PROXY_HOST; + + case QNetworkReply::ContentAccessDenied: + return KIO::ERR_ACCESS_DENIED; + + case QNetworkReply::ContentOperationNotPermittedError: + return KIO::ERR_WRITE_ACCESS_DENIED; + + case QNetworkReply::ContentNotFoundError: + return KIO::ERR_NO_CONTENT; + + case QNetworkReply::AuthenticationRequiredError: + return KIO::ERR_COULD_NOT_AUTHENTICATE; + + case QNetworkReply::ProtocolUnknownError: + return KIO::ERR_UNSUPPORTED_PROTOCOL; + + case QNetworkReply::ProtocolInvalidOperationError: + return KIO::ERR_UNSUPPORTED_ACTION; + + default: + return KIO::ERR_UNKNOWN; + } +} + +/* + * from khtml_part code + */ +QString errorPageHtml( int errorCode, const QString& text, const KUrl& reqUrl ) +{ + QString errorName, techName, description; + QStringList causes, solutions; + + QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl ); + QDataStream stream(raw); + + stream >> errorName >> techName >> description >> causes >> solutions; + + QString url, protocol, datetime; + url = Qt::escape( reqUrl.prettyUrl() ); + protocol = reqUrl.protocol(); + datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(), + KLocale::LongDate ); + + QString filename( KStandardDirs::locate( "data", "khtml/error.html" ) ); + QFile file( filename ); + bool isOpened = file.open( QIODevice::ReadOnly ); + if ( !isOpened ) + kWarning(6050) << "Could not open error html template:" << filename; + + QString html = QString( QLatin1String( file.readAll() ) ); + + html.replace( QLatin1String( "TITLE" ), i18n( "Error: %1 - %2", errorName, url ) ); + html.replace( QLatin1String( "DIRECTION" ), QApplication::isRightToLeft() ? "rtl" : "ltr" ); + KUrl iconUrl(KIconLoader::global()->iconPath( "dialog-warning", -KIconLoader::SizeHuge )); + iconUrl.setProtocol("file://"); + html.replace( QLatin1String( "ICON_PATH" ), iconUrl.url()); + + QString doc = QLatin1String( "

    " ); + doc += i18n( "The requested operation could not be completed" ); + doc += QLatin1String( "

    " ); + doc += errorName; + doc += QLatin1String( "

    " ); + if ( !techName.isNull() ) { + doc += QLatin1String( "

    " ); + doc += i18n( "Technical Reason: " ); + doc += techName; + doc += QLatin1String( "

    " ); + } + doc += QLatin1String( "

    " ); + doc += i18n( "Details of the Request:" ); + doc += QLatin1String( "

    • " ); + doc += i18n( "URL: %1" , url ); + doc += QLatin1String( "
    • " ); + if ( !protocol.isNull() ) { + doc += i18n( "Protocol: %1", protocol ); + doc += QLatin1String( "
    • " ); + } + doc += i18n( "Date and Time: %1" , datetime ); + doc += QLatin1String( "
    • " ); + doc += i18n( "Additional Information: %1" , text ); + doc += QLatin1String( "

    " ); + doc += i18n( "Description:" ); + doc += QLatin1String( "

    " ); + doc += description; + doc += QLatin1String( "

    " ); + if ( causes.count() ) { + doc += QLatin1String( "

    " ); + doc += i18n( "Possible Causes:" ); + doc += QLatin1String( "

    • " ); + doc += causes.join( "
    • " ); + doc += QLatin1String( "
    " ); + } + if ( solutions.count() ) { + doc += QLatin1String( "

    " ); + doc += i18n( "Possible Solutions:" ); + doc += QLatin1String( "

    • " ); + doc += solutions.join( "
    • " ); + doc += QLatin1String( "
    " ); + } + + html.replace( QLatin1String("TEXT"), doc ); + + return html; +} diff --git a/plasma/generic/applets/webbrowser/errorpage.h b/plasma/generic/applets/webbrowser/errorpage.h new file mode 100644 index 00000000..a8239470 --- /dev/null +++ b/plasma/generic/applets/webbrowser/errorpage.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef ERRORPAGE_H +#define ERRORPAGE_H + +#include +#include + +int webKitErrorToKIOError(int eValue); +QString errorPageHtml( int errorCode, const QString& text, const KUrl& reqUrl ); + +#endif diff --git a/plasma/generic/applets/webbrowser/plasma-applet-webbrowser.desktop b/plasma/generic/applets/webbrowser/plasma-applet-webbrowser.desktop new file mode 100644 index 00000000..5d83d243 --- /dev/null +++ b/plasma/generic/applets/webbrowser/plasma-applet-webbrowser.desktop @@ -0,0 +1,185 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Web Browser +Name[af]=Web Blaaier +Name[ar]=متصفح الوِب +Name[ast]=Restolador Web +Name[be]=Вандроўнік па Сеціве +Name[be@latin]=Hartač sieciva +Name[bg]=Уеб браузър +Name[bn]=ওয়েব ব্রাউজার +Name[bn_IN]=ওয়েব ব্রাউজার +Name[br]=Furcher an Internet +Name[bs]=veb pregledač +Name[ca]=Navegació Web +Name[ca@valencia]=Navegació Web +Name[cs]=Prohlížeč Webu +Name[csb]=Przezérnik WWW +Name[cy]=Porydd Gwê +Name[da]=Browser +Name[de]=Webbrowser +Name[el]=Περιηγητής ιστού +Name[en_GB]=Web Browser +Name[eo]=Retumilo +Name[es]=Navegador Web +Name[et]=Veebibrauser +Name[eu]=Web-arakatzailea +Name[fa]=مرورگر وب‌‌ +Name[fi]=Verkkoselain +Name[fr]=Navigateur Web +Name[fy]=Webblêder +Name[ga]=Brabhsálaí Gréasáin +Name[gl]=Navegador web +Name[gu]=વેબ બ્રાઉઝર +Name[he]=דפדפן אינטרנט +Name[hi]=वेब ब्राउज़र +Name[hne]=वेब ब्राउजर +Name[hr]=Web preglednik +Name[hsb]=Web Browser +Name[hu]=Webböngésző +Name[ia]=Navigator Web +Name[id]=Peramban Web +Name[is]=Vafri +Name[it]=Browser Web +Name[ja]=ウェブブラウザ +Name[ka]=ვებ ბრაუზერი +Name[kk]=Веб шолғышы +Name[km]=កម្មវិធី​រុករក​បណ្ដាញ +Name[kn]=ಚಾಲ ವೀಕ್ಷಕ +Name[ko]=웹 브라우저 +Name[ku]=Geroka Torê +Name[lt]=Žiniatinklio naršyklė +Name[lv]=Tīmekļa pārlūks +Name[mai]=वेब ब्राउजर +Name[mk]=Веб-прелистувач +Name[ml]=വെബ് ബ്രൌസര്‍ +Name[mr]=वेब ब्राऊजर +Name[ms]=Pelayar Web +Name[nb]=Nettleser +Name[nds]=Nettkieker +Name[ne]=वेब ब्राउजर +Name[nl]=Webbrowser +Name[nn]=Nettlesar +Name[oc]=Navigador web +Name[or]=ୱେବ ବ୍ରାଉଜର +Name[pa]=ਵੈੱਬ ਬਰਾਊਜ਼ਰ +Name[pl]=Przeglądarka sieciowa +Name[pt]=Navegação Web +Name[pt_BR]=Navegador Web +Name[ro]=Navigator de web +Name[ru]=Браузер +Name[se]=Fierpmádatlogan +Name[si]=වෙබ් ගවේශකය +Name[sk]=Webový prehliadač +Name[sl]=Spletni brskalnik +Name[sr]=веб прегледач +Name[sr@ijekavian]=веб прегледач +Name[sr@ijekavianlatin]=veb pregledač +Name[sr@latin]=veb pregledač +Name[sv]=Webbläsning +Name[ta]=வலை உலாவி +Name[te]=వెబ్ బ్రౌజర్ +Name[tg]=Намоишгари Интернет +Name[th]=เว็บเบราว์เซอร์ +Name[tr]=Web Tarayıcı +Name[ug]=توركۆرگۈ +Name[uk]=Переглядач інтернету +Name[uz]=Veb-brauzer +Name[uz@cyrillic]=Веб-браузер +Name[vi]=Trình duyệt Mạng +Name[wa]=Betchteu waibe +Name[xh]=Umkhangeli zincwadi we Web +Name[x-test]=xxWeb Browserxx +Name[zh_CN]=网络浏览器 +Name[zh_TW]=網頁瀏覽器 +Comment=A simple web browser +Comment[ar]=متصفح وِب بسيط +Comment[ast]=Restolador cenciellu +Comment[be@latin]=Prosty hartač sieciva +Comment[bg]=Обикновен уеб браузър +Comment[bn]=একটি সরল ওয়েব ব্রাউজার +Comment[bn_IN]=একটি সাধারণ ওয়েব ব্রাউজার +Comment[bs]=Jednostavan veb pregledač +Comment[ca]=Un navegador web senzill +Comment[ca@valencia]=Un navegador web senzill +Comment[cs]=Jednoduchý webový prohlížeč +Comment[csb]=Prosti przezérnik WWW +Comment[da]=En simpel webbrowser +Comment[de]=Einfacher Webbrowser +Comment[el]=Ένας απλός περιηγητής ιστού +Comment[en_GB]=A simple web browser +Comment[eo]=Simpla foliumilo +Comment[es]=Navegador sencillo +Comment[et]=Lihtne veebibrauser +Comment[eu]=Web-arakatzaile soila +Comment[fi]=Yksinkertainen selain +Comment[fr]=Un navigateur Web simple +Comment[fy]=In ienfâldige webblêder +Comment[ga]=Brabhsálaí simplí +Comment[gl]=Un navegador web simples +Comment[gu]=સરળ વેબ બ્રાઉઝર +Comment[he]=דפדפן אינטרנט פשוט +Comment[hi]=एक सादा वेब ब्राउज़र +Comment[hne]=एक सादा ब्राउजर +Comment[hr]=Jednostavni web preglednik +Comment[hsb]=Jednory web browser +Comment[hu]=Egyszerű webböngésző +Comment[ia]=Un simple navigator web +Comment[id]=Peramban web sederhana +Comment[is]=Einfaldur vafri +Comment[it]=Un semplice browser Web +Comment[ja]=シンプルなウェブブラウザ +Comment[kk]=Қарапайым веб шолғышы +Comment[km]=កម្មវិធី​រុករក​បណ្ដាញ​ធម្មតា +Comment[kn]=ಒಂದು ಸರಳ ಜಾಲ ವೀಕ್ಷಕ +Comment[ko]=간단한 웹 브라우저 +Comment[ku]=Geroka torê yê hêsan +Comment[lt]=Paprasta žiniatinklio naršyklė +Comment[lv]=Vienkāršs tīmekļa pārlūks +Comment[mk]=Едноставен веб-прелистувач +Comment[ml]=ലളിതമായ വെബ് ബ്രൌസര്‍ +Comment[mr]=सोपा वेब ब्राऊजर +Comment[nb]=Enkel nettleser +Comment[nds]=En eenfach Nettkieker +Comment[nl]=Eenvoudige webbrowser +Comment[nn]=Enkel nettlesar +Comment[or]=ଗୋଟିଏ ସରଳ ୱେବ ବ୍ରାଉଜର +Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਵੈੱਬ ਬਰਾਊਜ਼ਰ +Comment[pl]=Prosta przeglądarka sieciowa +Comment[pt]=Um navegador Web simples +Comment[pt_BR]=Um navegador da Internet simples +Comment[ro]=Un navigator web simplu +Comment[ru]=Простой браузер +Comment[si]=සරල වෙබ් ගවේශකයක් +Comment[sk]=Jednoduchý webový prehliadač +Comment[sl]=Preprost spletni brskalnik +Comment[sr]=Једноставан веб прегледач +Comment[sr@ijekavian]=Једноставан веб прегледач +Comment[sr@ijekavianlatin]=Jednostavan veb pregledač +Comment[sr@latin]=Jednostavan veb pregledač +Comment[sv]=En enkel webbläsare +Comment[ta]=எளிய உலாவி +Comment[tg]=Веб-браузери Cisco +Comment[th]=เว็บเบราว์เซอร์พื้นฐาน +Comment[tr]=Basit bir ağ tarayıcı +Comment[ug]=ئاددىي توركۆرگۈ +Comment[uk]=Простий переглядач інтернету +Comment[wa]=On simpe betchteu waibe +Comment[x-test]=xxA simple web browserxx +Comment[zh_CN]=简单网络浏览器 +Comment[zh_TW]=簡易瀏覽器 +Type=Service +Icon=konqueror +ServiceTypes=Plasma/Applet +X-Plasma-DropMimeTypes=text/html + +X-KDE-Library=plasma_applet_webbrowser +X-KDE-PluginInfo-Author=Marco Martin +X-KDE-PluginInfo-Email=notmart@gmail.com +X-KDE-PluginInfo-Name=webbrowser +X-KDE-PluginInfo-Version=0.5 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Online Services +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPLv2+ +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/applets/webbrowser/webbrowser.cpp b/plasma/generic/applets/webbrowser/webbrowser.cpp new file mode 100644 index 00000000..43c93589 --- /dev/null +++ b/plasma/generic/applets/webbrowser/webbrowser.cpp @@ -0,0 +1,675 @@ +/*************************************************************************** + * Copyright (C) 2008 Marco Martin * + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "webbrowser.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "bookmarksdelegate.h" +#include "bookmarkitem.h" +#include "webviewoverlay.h" +#include "browserhistorycombobox.h" +#include "browsermessagebox.h" +#include "errorpage.h" +#include "webbrowserpage.h" + +using Plasma::MessageButton; + +WebBrowser::WebBrowser(QObject *parent, const QVariantList &args) + : Plasma::PopupApplet(parent, args), + m_browser(0), + m_verticalScrollValue(0), + m_horizontalScrollValue(0), + m_completion(0), + m_bookmarkManager(0), + m_bookmarkModel(0), + m_autoRefreshTimer(0) +{ + setHasConfigurationInterface(true); + setAspectRatioMode(Plasma::IgnoreAspectRatio); + + m_historyCombo = 0; + m_graphicsWidget = 0; + m_webOverlay = 0; + + m_layout = 0; + resize(500,500); + if (!args.isEmpty()) { + m_url = KUrl(args.value(0).toString()); + } + setPopupIcon("konqueror"); +} + +QGraphicsWidget *WebBrowser::graphicsWidget() +{ + if (m_graphicsWidget) { + return m_graphicsWidget; + } + + m_layout = new QGraphicsLinearLayout(Qt::Vertical); + m_toolbarLayout = new QGraphicsLinearLayout(Qt::Horizontal); + m_statusbarLayout = new QGraphicsLinearLayout(Qt::Horizontal); + + m_back = addTool("go-previous", m_toolbarLayout); + m_forward = addTool("go-next", m_toolbarLayout); + + m_nativeHistoryCombo = new KHistoryComboBox(); + m_historyCombo = new Plasma::BrowserHistoryComboBox(this); + m_historyCombo->setNativeWidget(m_nativeHistoryCombo); + m_historyCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_historyCombo->setZValue(999); + + m_nativeHistoryCombo->setDuplicatesEnabled(false); + m_pixmapProvider = new KUrlPixmapProvider; + m_nativeHistoryCombo->setPixmapProvider(m_pixmapProvider); + + m_toolbarLayout->addItem(m_historyCombo); + m_go = addTool("go-jump-locationbar", m_toolbarLayout); + m_goAction = m_go->action(); + m_reloadAction = new QAction(KIcon("view-refresh"), QString(), this); + + m_layout->addItem(m_toolbarLayout); + + m_browser = new Plasma::WebView(this); + m_browser->setPage(new WebBrowserPage(this)); + m_browser->setPreferredSize(400, 400); + m_browser->setMinimumSize(130, 130); + m_browser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + m_layout->addItem(m_browser); + + //bookmarks + m_bookmarkManager = KBookmarkManager::userBookmarksManager(); + connect(m_bookmarkManager, SIGNAL(changed(QString,QString)), this, SLOT(bookmarksModelInit())); + bookmarksModelInit(); + + m_bookmarksView = new Plasma::TreeView(this); + m_bookmarksView->setZValue(1); + m_bookmarksView->nativeWidget()->setAttribute(Qt::WA_NoSystemBackground, false); + m_bookmarksView->nativeWidget()->verticalScrollBar()->setStyle(QApplication::style()); + m_bookmarksView->nativeWidget()->horizontalScrollBar()->setStyle(QApplication::style()); + m_bookmarksView->setModel(m_bookmarkModel); + m_bookmarksView->nativeWidget()->setHeaderHidden(true); + m_bookmarksView->hide(); + + m_bookmarksDelegate = new BookmarksDelegate(this); + m_bookmarksView->nativeWidget()->setItemDelegate(m_bookmarksDelegate); + + connect(m_bookmarksDelegate, SIGNAL(destroyBookmark(QModelIndex)), this, SLOT(removeBookmark(QModelIndex))); + + m_layout->addItem(m_statusbarLayout); + + m_addBookmark = addTool("bookmark-new", m_statusbarLayout); + m_addBookmarkAction = m_addBookmark->action(); + m_removeBookmarkAction = new QAction(KIcon("list-remove"), QString(), this); + m_organizeBookmarks = addTool("bookmarks-organize", m_statusbarLayout); + + m_bookmarksViewAnimation = Plasma::Animator::create(Plasma::Animator::FadeAnimation, this); + m_bookmarksViewAnimation->setTargetWidget(m_bookmarksView); + connect(m_bookmarksViewAnimation, SIGNAL(finished()), this, SLOT(bookmarksAnimationFinished())); + + m_stop = addTool("process-stop", m_statusbarLayout); + + QGraphicsWidget *spacer = new QGraphicsWidget(this); + spacer->setMaximumWidth(INT_MAX); + spacer->setMaximumHeight(0); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_statusbarLayout->addItem(spacer); + + m_zoom = new Plasma::Slider(this); + m_zoom->setMaximum(100); + m_zoom->setMinimum(0); + m_zoom->setValue(50); + m_zoom->setOrientation(Qt::Horizontal); + m_zoom->hide(); + m_zoom->setMaximumWidth(200); + m_statusbarLayout->addItem(m_zoom); + + connect(m_zoom, SIGNAL(valueChanged(int)), this, SLOT(zoom(int))); + m_browser->setUrl(m_url); + m_browser->update(); + + connect(m_back->action(), SIGNAL(triggered()), this, SLOT(back())); + connect(m_forward->action(), SIGNAL(triggered()), this, SLOT(forward())); + connect(m_reloadAction, SIGNAL(triggered()), this, SLOT(reload())); + connect(m_goAction, SIGNAL(triggered()), this, SLOT(returnPressed())); + connect(m_stop->action(), SIGNAL(triggered()), m_browser->page()->action(QWebPage::Stop), SLOT(trigger())); + + connect(m_historyCombo->nativeWidget(), SIGNAL(returnPressed()), this, SLOT(returnPressed())); + connect(m_historyCombo->nativeWidget(), SIGNAL(activated(int)), this, SLOT(returnPressed())); + connect(m_historyCombo, SIGNAL(activated(QString)), this, SLOT(comboTextChanged(QString))); + connect(m_browser->page()->mainFrame(), SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl))); + connect(m_browser, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int))); + + connect(m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark())); + connect(m_removeBookmarkAction, SIGNAL(triggered()), this, SLOT(removeBookmark())); + connect(m_organizeBookmarks->action(), SIGNAL(triggered()), this, SLOT(bookmarksToggle())); + connect(m_bookmarksView->nativeWidget(), SIGNAL(clicked(QModelIndex)), this, SLOT(bookmarkClicked(QModelIndex))); + + //Autocompletion stuff + m_completion = new KCompletion(); + m_nativeHistoryCombo->setCompletionObject(m_completion); + + m_graphicsWidget = new QGraphicsWidget(this); + m_graphicsWidget->setLayout(m_layout); + + m_back->setEnabled(m_browser->page()->history()->canGoBack()); + m_forward->setEnabled(m_browser->page()->history()->canGoForward()); + + configChanged(); + + connect(this, SIGNAL(messageButtonPressed(MessageButton)), this, SLOT(removeBookmarkMessageButtonPressed(MessageButton))); + + return m_graphicsWidget; +} + +WebBrowser::~WebBrowser() +{ + KConfigGroup cg = config(); + saveState(cg); + delete m_completion; + delete m_bookmarkModel; +} + +Plasma::IconWidget *WebBrowser::addTool(const QString &iconString, QGraphicsLinearLayout *layout) +{ + Plasma::IconWidget *icon = new Plasma::IconWidget(this); + QAction *action = new QAction(KIcon(iconString), QString(), this); + icon->setAction(action); + icon->setPreferredSize(icon->sizeFromIconSize(IconSize(KIconLoader::Toolbar))); + layout->addItem(icon); + + return icon; +} + +void WebBrowser::bookmarksModelInit() +{ + if (m_bookmarkModel) { + m_bookmarkModel->clear(); + } else { + m_bookmarkModel = new QStandardItemModel; + } + + fillGroup(0, m_bookmarkManager->root()); +} + +void WebBrowser::configChanged() +{ + KConfigGroup cg = config(); + + m_browser->setDragToScroll(cg.readEntry("DragToScroll", false)); + + if (!m_url.isValid()) { + m_url = KUrl(cg.readEntry("Url", "http://www.kde.org")); + m_verticalScrollValue = cg.readEntry("VerticalScrollValue", 0); + m_horizontalScrollValue = cg.readEntry("HorizontalScrollValue", 0); + int value = cg.readEntry("Zoom", 50); + m_zoom->setValue(value); + qreal zoomFactor = qMax((qreal)0.2, ((qreal)value/(qreal)50)); + if ((zoomFactor > 0.95) && (zoomFactor < 1.05)){ + zoomFactor = 1; + } + m_browser->setZoomFactor(zoomFactor); + m_browser->setUrl(m_url); + } + + m_autoRefresh = cg.readEntry("autoRefresh", false); + m_autoRefreshInterval = qMax(2, cg.readEntry("autoRefreshInterval", 5)); + + if (m_autoRefresh) { + m_autoRefreshTimer = new QTimer(this); + m_autoRefreshTimer->start(m_autoRefreshInterval*60*1000); + connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(reload())); + } + + QStringList list = cg.readEntry("History list", QStringList()); + m_nativeHistoryCombo->setHistoryItems(list); +} + +void WebBrowser::fillGroup(BookmarkItem *parentItem, const KBookmarkGroup &group) +{ + KBookmark it = group.first(); + + while (!it.isNull()) { + BookmarkItem *bookmarkItem = new BookmarkItem(it); + bookmarkItem->setEditable(false); + + if (it.isGroup()) { + KBookmarkGroup grp = it.toGroup(); + fillGroup( bookmarkItem, grp ); + + } + + if (parentItem) { + parentItem->appendRow(bookmarkItem); + } else { + m_bookmarkModel->appendRow(bookmarkItem); + } + + it = m_bookmarkManager->root().next(it); + } +} + +void WebBrowser::saveState(KConfigGroup &cg) const +{ + cg.writeEntry("Url", m_url.prettyUrl()); + + if (m_historyCombo) { + const QStringList list = m_nativeHistoryCombo->historyItems(); + cg.writeEntry("History list", list); + } + + if (m_browser) { + cg.writeEntry("VerticalScrollValue", m_browser->page()->mainFrame()->scrollBarValue(Qt::Vertical)); + cg.writeEntry("HorizontalScrollValue", m_browser->page()->mainFrame()->scrollBarValue(Qt::Horizontal)); + } +} + +void WebBrowser::back() +{ + m_browser->page()->history()->back(); +} + +void WebBrowser::forward() +{ + m_browser->page()->history()->forward(); +} + +void WebBrowser::reload() +{ + m_browser->setUrl(m_url); +} + +void WebBrowser::returnPressed() +{ + KUrl url(m_nativeHistoryCombo->currentText()); + + + KUriFilter::self()->filterUri( url ); + + m_verticalScrollValue = 0; + m_horizontalScrollValue = 0; + m_browser->setUrl(url); +} + + +void WebBrowser::urlChanged(const QUrl &url) +{ + //ask for a favicon + Plasma::DataEngine *engine = dataEngine( "favicons" ); + if (engine) { + //engine->disconnectSource( url.toString(), this ); + engine->connectSource( url.toString(), this ); + + engine->query( url.toString() ); + } + + m_url = KUrl(url); + + if (m_bookmarkModel->match(m_bookmarkModel->index(0,0), BookmarkItem::UrlRole, m_url.prettyUrl()).isEmpty()) { + m_addBookmark->setAction(m_addBookmarkAction); + } else { + m_addBookmark->setAction(m_removeBookmarkAction); + } + + m_nativeHistoryCombo->addToHistory(m_url.prettyUrl()); + m_nativeHistoryCombo->setCurrentIndex(0); + + m_go->setAction(m_reloadAction); + + KConfigGroup cg = config(); + saveState(cg); + + m_back->setEnabled(m_browser->page()->history()->canGoBack()); + m_forward->setEnabled(m_browser->page()->history()->canGoForward()); + setAssociatedApplicationUrls(KUrl(url)); +} + +void WebBrowser::comboTextChanged(const QString &string) +{ + Q_UNUSED(string) + + m_go->setAction(m_goAction); +} + +void WebBrowser::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data ) +{ + //TODO: find a way to update bookmarks and history combobox here, at the moment the data engine + // is only used to save the icon files + if (source == m_nativeHistoryCombo->currentText()) { + QPixmap favicon(QPixmap::fromImage(data["Icon"].value())); + if (!favicon.isNull()) { + m_nativeHistoryCombo->setItemIcon( + m_nativeHistoryCombo->currentIndex(), QIcon(favicon)); + setPopupIcon(QIcon(favicon)); + } + } +} + +void WebBrowser::addBookmark() +{ + KBookmark bookmark = m_bookmarkManager->root().addBookmark(m_browser->page()->mainFrame()->title(), m_url); + m_bookmarkManager->save(); + + BookmarkItem *bookmarkItem = new BookmarkItem(bookmark); + m_bookmarkModel->appendRow(bookmarkItem); + + m_addBookmark->setAction(m_removeBookmarkAction); +} + +void WebBrowser::removeBookmark(const QModelIndex &index) +{ + BookmarkItem *item = dynamic_cast(m_bookmarkModel->itemFromIndex(index)); + + if (item) { + KBookmark bookmark = item->bookmark(); + + const QString text(i18nc("@info", "Do you really want to remove the bookmark to %1?", bookmark.url().host())); + showMessage(KIcon("dialog-warning"), text, Plasma::ButtonYes | Plasma::ButtonNo); + return; + } + + if (item && item->parent()) { + item->parent()->removeRow(index.row()); + } else { + m_bookmarkModel->removeRow(index.row()); + } + +} + +void WebBrowser::removeBookmarkMessageButtonPressed(const Plasma::MessageButton button) +{ + if (button == Plasma::ButtonNo){ + return; + } + + const QModelIndexList list = m_bookmarkModel->match(m_bookmarkModel->index(0,0), BookmarkItem::UrlRole, m_url.prettyUrl()); + + if (!list.isEmpty()) { + const QModelIndex &index = list.first(); + BookmarkItem *item = dynamic_cast(m_bookmarkModel->itemFromIndex(index)); + + if (item) { + KBookmark bookmark = item->bookmark(); + + bookmark.parentGroup().deleteBookmark(bookmark); + m_bookmarkManager->save(); + } + + if (item && item->parent()) { + item->parent()->removeRow(index.row()); + } else { + m_bookmarkModel->removeRow(index.row()); + } + } + + m_addBookmark->setAction(m_addBookmarkAction); +} +void WebBrowser::removeBookmark() +{ + const QModelIndexList list = m_bookmarkModel->match(m_bookmarkModel->index(0,0), BookmarkItem::UrlRole, m_url.prettyUrl()); + + if (!list.isEmpty()) { + removeBookmark(list.first()); + } +} + +void WebBrowser::bookmarksToggle() +{ + if (m_bookmarksView->isVisible()) { + m_bookmarksViewAnimation->setProperty("startOpacity", 1); + m_bookmarksViewAnimation->setProperty("targetOpacity", 0); + m_bookmarksViewAnimation->start(); + } else { + m_bookmarksView->show(); + m_bookmarksView->setOpacity(0); + updateOverlaysGeometry(); + m_bookmarksViewAnimation->setProperty("startOpacity", 0); + m_bookmarksViewAnimation->setProperty("targetOpacity", 1); + m_bookmarksViewAnimation->start(); + } +} + +void WebBrowser::bookmarksAnimationFinished() +{ + if (qFuzzyCompare(m_bookmarksView->opacity() + 1, 1)){ + m_bookmarksView->hide(); + } +} + +void WebBrowser::bookmarkClicked(const QModelIndex &index) +{ + QStandardItem *item = m_bookmarkModel->itemFromIndex(index); + + if (item) { + KUrl url(item->data(BookmarkItem::UrlRole).value()); + + if (url.isValid()) { + m_browser->setUrl(url); + bookmarksToggle(); + } + } +} + +void WebBrowser::zoom(int value) +{ + config().writeEntry("Zoom", value); + m_browser->setZoomFactor((qreal)0.2 + ((qreal)value/(qreal)50)); +} + +void WebBrowser::loadProgress(int progress) +{ + m_historyCombo->setProgressValue(progress); + + if (progress == 100) { + m_historyCombo->setDisplayProgress(false); + m_stop->hide(); + m_stop->setMaximumWidth(0); + m_zoom->show(); + m_statusbarLayout->invalidate(); + + m_browser->page()->mainFrame()->setScrollBarValue(Qt::Vertical, m_verticalScrollValue); + m_browser->page()->mainFrame()->setScrollBarValue(Qt::Horizontal, m_horizontalScrollValue); + + } else { + m_historyCombo->setDisplayProgress(true); + m_stop->show(); + m_stop->setMaximumWidth(INT_MAX); + m_zoom->hide(); + m_statusbarLayout->invalidate(); + } +} + +void WebBrowser::createConfigurationInterface(KConfigDialog *parent) +{ + QWidget *widget = new QWidget(); + ui.setupUi(widget); + parent->addPage(widget, i18n("General"), icon()); + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + + ui.autoRefresh->setChecked(m_autoRefresh); + ui.autoRefreshInterval->setValue(m_autoRefreshInterval); + ui.autoRefreshInterval->setSuffix(ki18np(" minute", " minutes")); + ui.dragToScroll->setChecked(m_browser->dragToScroll()); + connect(ui.autoRefresh, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); + connect(ui.dragToScroll, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); + connect(ui.autoRefreshInterval, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified())); +} + +void WebBrowser::configAccepted() +{ + KConfigGroup cg = config(); + + m_autoRefresh = ui.autoRefresh->isChecked(); + m_autoRefreshInterval = ui.autoRefreshInterval->value(); + + cg.writeEntry("autoRefresh", m_autoRefresh); + cg.writeEntry("autoRefreshInterval", m_autoRefreshInterval); + cg.writeEntry("DragToScroll", ui.dragToScroll->isChecked()); + m_browser->setDragToScroll(ui.dragToScroll->isChecked()); + + if (m_autoRefresh) { + if (!m_autoRefreshTimer) { + m_autoRefreshTimer = new QTimer(this); + connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(reload())); + } + + m_autoRefreshTimer->start(m_autoRefreshInterval*60*1000); + } else { + delete m_autoRefreshTimer; + m_autoRefreshTimer = 0; + } + + emit configNeedsSaving(); +} + +void WebBrowser::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::SizeConstraint){ + updateOverlaysGeometry(); + } +} + +void WebBrowser::updateOverlaysGeometry() +{ + QRect overlayGeometry(m_browser->pos().x() + contentsRect().x(), + m_browser->pos().y() + contentsRect().y(), + m_browser->geometry().width(), + m_browser->geometry().height()); + + if (m_bookmarksView->isVisible()) { + m_bookmarksView->setGeometry(overlayGeometry); + } + + if (m_webOverlay){ + m_webOverlay->setGeometry(overlayGeometry); + } +} + +void WebBrowser::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect) +{ + Q_UNUSED(option) + Q_UNUSED(contentsRect) + + if (!isIconified()){ + p->save(); + p->setBrush(QApplication::palette().window()); + p->setRenderHint(QPainter::Antialiasing); + p->setPen(Qt::NoPen); + p->drawRoundedRect(m_browser->pos().x() + contentsRect.x() - 2, + m_browser->pos().y() + contentsRect.y() - 2, + m_browser->geometry().width() + 4, + m_browser->geometry().height() + 4, + 2, 2); + p->restore(); + } +} + +void WebBrowser::closeWebViewOverlay() +{ + if (m_webOverlay){ + m_webOverlay->deleteLater(); + m_webOverlay = 0; + } +} + +QWebPage *WebBrowser::createWindow(QWebPage::WebWindowType type) +{ + Q_UNUSED(type) + + if (!m_webOverlay){ + m_webOverlay = new WebViewOverlay(this); + updateOverlaysGeometry(); + m_webOverlay->setZValue(999); + connect(m_webOverlay, SIGNAL(closeRequested()), this, SLOT(closeWebViewOverlay())); + } + + return m_webOverlay->page(); +} + +// +// Wallet managment +// + +void WebBrowser::saveFormDataRequested(const QString &uid, const QUrl &url) +{ + BrowserMessageBox *messageBox = new BrowserMessageBox(this, i18n("Do you want to store this password for %1?", url.host())); + messageBox->okButton()->setText(i18n("Store")); + messageBox->okButton()->setIcon(KIcon("document-save")); + messageBox->cancelButton()->setText(i18n("Do not store this time")); + messageBox->cancelButton()->setIcon(KIcon("dialog-cancel")); + m_layout->insertItem(1, messageBox); + walletRequests.insert(messageBox, uid); + connect(messageBox, SIGNAL(okClicked()), this, SLOT(acceptWalletRequest())); + connect(messageBox, SIGNAL(cancelClicked()), this, SLOT(rejectWalletRequest())); +} + +void WebBrowser::acceptWalletRequest() +{ + static_cast(m_browser->page())->wallet()->acceptSaveFormDataRequest( + walletRequests[static_cast(QObject::sender())]); + QObject::sender()->deleteLater(); +} + +void WebBrowser::rejectWalletRequest() +{ + static_cast(m_browser->page())->wallet()->rejectSaveFormDataRequest( + walletRequests[static_cast(QObject::sender())]); + QObject::sender()->deleteLater(); +} + +// +// End of wallet managment +// + +K_EXPORT_PLASMA_APPLET(webbrowser, WebBrowser) + +#include "webbrowser.moc" diff --git a/plasma/generic/applets/webbrowser/webbrowser.h b/plasma/generic/applets/webbrowser/webbrowser.h new file mode 100644 index 00000000..923f573d --- /dev/null +++ b/plasma/generic/applets/webbrowser/webbrowser.h @@ -0,0 +1,163 @@ +/*************************************************************************** + * Copyright (C) 2008 by Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef WEBBROWSER_H +#define WEBBROWSER_H + +#include +#include + +#include +#include + +#include "ui_webbrowserconfig.h" +#include "browsermessagebox.h" + +class WebViewOverlay; + +class QGraphicsLinearLayout; +class QStandardItemModel; +class QStandardItem; +class QTimer; +class KUrlPixmapProvider; +class KHistoryComboBox; +class KUrl; +class KCompletion; +class KBookmarkManager; +class KBookmarkGroup; +class QModelIndex; +class QAction; +class BookmarksDelegate; +class BookmarkItem; + +namespace Plasma +{ + class BrowserHistoryComboBox; + class IconWidget; + class ComboBox; + class WebView; + class TreeView; + class Slider; +} + + +using Plasma::MessageButton; + +class WebBrowser : public Plasma::PopupApplet +{ + Q_OBJECT +public: + WebBrowser(QObject *parent, const QVariantList &args); + ~WebBrowser(); + + QGraphicsWidget *graphicsWidget(); + void paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect); + QWebPage *createWindow(QWebPage::WebWindowType type); + + //TODO: put in a separate file + enum BookmarkRoles + { + UrlRole = Qt::UserRole+1, + BookmarkRole = Qt::UserRole+2 + }; + +public Q_SLOTS: + void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data); + void saveFormDataRequested(const QString &uid, const QUrl &url); + +protected: + void saveState(KConfigGroup &cg) const; + Plasma::IconWidget *addTool(const QString &iconString, QGraphicsLinearLayout *layout); + void createConfigurationInterface(KConfigDialog *parent); + void constraintsEvent(Plasma::Constraints constraints); + +protected Q_SLOTS: + void back(); + void forward(); + void reload(); + void returnPressed(); + void urlChanged(const QUrl &url); + void comboTextChanged(const QString &string); + void addBookmark(); + void removeBookmark(const QModelIndex &index); + void removeBookmark(); + void bookmarksToggle(); + void bookmarkClicked(const QModelIndex &index); + void zoom(int value); + void loadProgress(int progress); + void bookmarksModelInit(); + void configAccepted(); + void configChanged(); + void bookmarksAnimationFinished(); + void removeBookmarkMessageButtonPressed(const MessageButton button); + void closeWebViewOverlay(); + + void acceptWalletRequest(); + void rejectWalletRequest(); + +private: + void fillGroup(BookmarkItem *parentItem, const KBookmarkGroup &group); + void updateOverlaysGeometry(); + QHash walletRequests; + + + QGraphicsLinearLayout *m_layout; + QGraphicsLinearLayout *m_toolbarLayout; + QGraphicsLinearLayout *m_statusbarLayout; + Plasma::WebView *m_browser; + WebViewOverlay *m_webOverlay; + KUrl m_url; + int m_verticalScrollValue; + int m_horizontalScrollValue; + KUrlPixmapProvider *m_pixmapProvider; + KCompletion *m_completion; + KBookmarkManager *m_bookmarkManager; + QStandardItemModel *m_bookmarkModel; + Plasma::TreeView *m_bookmarksView; + Plasma::Animation *m_bookmarksViewAnimation; + + QTimer *m_autoRefreshTimer; + bool m_autoRefresh; + int m_autoRefreshInterval; + + QGraphicsWidget *m_graphicsWidget; + + Plasma::BrowserHistoryComboBox *m_historyCombo; + KHistoryComboBox *m_nativeHistoryCombo; + BookmarksDelegate *m_bookmarksDelegate; + + Plasma::IconWidget *m_back; + Plasma::IconWidget *m_forward; + + Plasma::IconWidget *m_go; + QAction *m_goAction; + QAction *m_reloadAction; + + Plasma::IconWidget *m_addBookmark; + QAction *m_addBookmarkAction; + QAction *m_removeBookmarkAction; + + Plasma::IconWidget *m_organizeBookmarks; + Plasma::IconWidget *m_stop; + Plasma::Slider *m_zoom; + + Ui::WebBrowserConfig ui; +}; + +#endif diff --git a/plasma/generic/applets/webbrowser/webbrowserconfig.ui b/plasma/generic/applets/webbrowser/webbrowserconfig.ui new file mode 100644 index 00000000..1b1278b1 --- /dev/null +++ b/plasma/generic/applets/webbrowser/webbrowserconfig.ui @@ -0,0 +1,120 @@ + + + WebBrowserConfig + + + + 0 + 0 + 298 + 140 + + + + Dialog + + + + + + Auto refresh: + + + autoRefresh + + + + + + + + + + + + + + Interval: + + + autoRefreshInterval + + + + + + + false + + + + 0 + + + 0 + + + + + + 130 + 0 + + + + 2 + + + 5 + + + + + + + + + + Drag to scroll the page: + + + dragToScroll + + + + + + + + + + + + + + + KIntSpinBox + QSpinBox +
    knuminput.h
    +
    +
    + + + + autoRefresh + toggled(bool) + intervalGroup + setEnabled(bool) + + + 238 + 11 + + + 238 + 39 + + + + +
    diff --git a/plasma/generic/applets/webbrowser/webbrowserpage.cpp b/plasma/generic/applets/webbrowser/webbrowserpage.cpp new file mode 100644 index 00000000..3b236144 --- /dev/null +++ b/plasma/generic/applets/webbrowser/webbrowserpage.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "webbrowserpage.h" +#include "webbrowser.h" +#include "errorpage.h" + +#include +#include + +#include + +WebBrowserPage::WebBrowserPage(WebBrowser *parent) + : KWebPage(parent) +{ + m_browser = parent; + //settings()->setAttribute(QWebSettings::JavaEnabled, true); + settings()->setAttribute(QWebSettings::PluginsEnabled, true); + + connect(networkAccessManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(networkAccessFinished(QNetworkReply*))); + connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoadFinished(bool))); + connect(wallet(), SIGNAL(saveFormDataRequested(QString,QUrl)), + m_browser, SLOT(saveFormDataRequested(QString,QUrl))); +} + +QWebPage *WebBrowserPage::createWindow(WebWindowType type) +{ + return m_browser->createWindow(type); +} + +void WebBrowserPage::pageLoadFinished(bool ok) +{ + if (ok){ + wallet()->fillFormData(mainFrame()); + } +} + +void WebBrowserPage::networkAccessFinished(QNetworkReply *nReply) +{ + switch (nReply->error()){ + case QNetworkReply::NoError: + case QNetworkReply::UnknownContentError: + case QNetworkReply::ContentNotFoundError: + return; + + default: + mainFrame()->setHtml(errorPageHtml(webKitErrorToKIOError(nReply->error()), nReply->url().toString(), nReply->url())); + } +} + +#include "webbrowserpage.moc" diff --git a/plasma/generic/applets/webbrowser/webbrowserpage.h b/plasma/generic/applets/webbrowser/webbrowserpage.h new file mode 100644 index 00000000..cd8e8c5b --- /dev/null +++ b/plasma/generic/applets/webbrowser/webbrowserpage.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef WEBBROWSERPAGE_H +#define WEBBROWSERPAGE_H + +#include + +class WebBrowser; + +class WebBrowserPage : public KWebPage +{ + Q_OBJECT + + public: + WebBrowserPage(WebBrowser *parent); + + protected: + QWebPage *createWindow(WebWindowType type); + + private Q_SLOTS: + void pageLoadFinished(bool ok); + void networkAccessFinished(QNetworkReply *nReply); + + private: + WebBrowser *m_browser; +}; + +#endif diff --git a/plasma/generic/applets/webbrowser/webviewoverlay.cpp b/plasma/generic/applets/webbrowser/webviewoverlay.cpp new file mode 100644 index 00000000..cfe00067 --- /dev/null +++ b/plasma/generic/applets/webbrowser/webviewoverlay.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "webviewoverlay.h" + +#include +#include +#include +#include + +#include +#include + +#include "webbrowser.h" +#include "webbrowserpage.h" + +WebViewOverlay::WebViewOverlay(WebBrowser *parent) + : QGraphicsWidget(parent) +{ + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); + layout->setOrientation(Qt::Vertical); + + m_webView = new Plasma::WebView(this); + m_webView->setPage(new WebBrowserPage(parent)); + m_webView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + layout->addItem(m_webView); + + m_closeButton = new Plasma::PushButton(this); + m_closeButton->setText(i18n("Close")); + connect(m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeRequested())); + layout->addItem(m_closeButton); + connect(m_webView->page(), SIGNAL(windowCloseRequested()), this, SIGNAL(closeRequested())); +} + +QWebPage *WebViewOverlay::page() +{ + return m_webView->page(); +} + +void WebViewOverlay::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + + painter->fillRect(option->rect, QApplication::palette().window()); +} + +#include "webviewoverlay.moc" diff --git a/plasma/generic/applets/webbrowser/webviewoverlay.h b/plasma/generic/applets/webbrowser/webviewoverlay.h new file mode 100644 index 00000000..052a00ac --- /dev/null +++ b/plasma/generic/applets/webbrowser/webviewoverlay.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2010 Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef WEBVIEWOVERLAY_H +#define WEBVIEWOVERLAY_H + +#include +#include + +class WebBrowser; + +namespace Plasma +{ + class PushButton; + class WebView; +} + +class WebViewOverlay : public QGraphicsWidget +{ + Q_OBJECT + + public: + WebViewOverlay(WebBrowser *parent); + QWebPage *page(); + + Q_SIGNALS: + void closeRequested(); + + protected: + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + private: + Plasma::WebView *m_webView; + Plasma::PushButton *m_closeButton; +}; + +#endif diff --git a/plasma/generic/containmentactions/CMakeLists.txt b/plasma/generic/containmentactions/CMakeLists.txt new file mode 100644 index 00000000..35c7b875 --- /dev/null +++ b/plasma/generic/containmentactions/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(contextmenu) +add_subdirectory(switchdesktop) +add_subdirectory(switchactivity) +add_subdirectory(paste) +add_subdirectory(switchwindow) +add_subdirectory(applauncher) +add_subdirectory(minimalcontextmenu) diff --git a/plasma/generic/containmentactions/applauncher/CMakeLists.txt b/plasma/generic/containmentactions/applauncher/CMakeLists.txt new file mode 100644 index 00000000..7025eaaf --- /dev/null +++ b/plasma/generic/containmentactions/applauncher/CMakeLists.txt @@ -0,0 +1,11 @@ +project(plasma-containmentactions-applauncher) + +set(applauncher_SRCS + launch.cpp +) + +kde4_add_plugin(plasma_containmentactions_applauncher ${applauncher_SRCS}) +target_link_libraries(plasma_containmentactions_applauncher ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containmentactions_applauncher DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-applauncher.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/applauncher/launch.cpp b/plasma/generic/containmentactions/applauncher/launch.cpp new file mode 100644 index 00000000..bef53e53 --- /dev/null +++ b/plasma/generic/containmentactions/applauncher/launch.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "launch.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +AppLauncher::AppLauncher(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), + m_action(new QAction(this)) +{ + m_menu = new KMenu(); + connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(switchTo(QAction*))); + + m_action->setMenu(m_menu); +} + +AppLauncher::~AppLauncher() +{ + delete m_menu; +} + +void AppLauncher::init(const KConfigGroup &) +{ +} + +void AppLauncher::contextEvent(QEvent *event) +{ + makeMenu(); + m_menu->adjustSize(); + m_menu->exec(popupPosition(m_menu->size(), event)); +} + +QList AppLauncher::contextualActions() +{ + makeMenu(); + + QList list; + list << m_action; + return list; +} + +void AppLauncher::makeMenu() +{ + Plasma::DataEngine *apps = dataEngine("apps"); + if (!apps->isValid()) { + return; + } + + m_menu->clear(); + + //add the whole kmenu + Plasma::DataEngine::Data app = dataEngine("apps")->query("/"); + const QStringList sources = app.value("entries").toStringList(); + foreach (const QString &source, sources) { + addApp(m_menu, source); + } +} + +bool AppLauncher::addApp(QMenu *menu, const QString &source) +{ + if (source == "---") { + menu->addSeparator(); + return false; + } + + Plasma::DataEngine::Data app = dataEngine("apps")->query(source); + + if (!app.value("display").toBool()) { + kDebug() << "hidden entry" << source; + return false; + } + QString name = app.value("name").toString(); + if (name.isEmpty()) { + kDebug() << "failed source" << source; + return false; + } + + name.replace("&", "&&"); //escaping + KIcon icon(app.value("iconName").toString()); + + if (app.value("isApp").toBool()) { + QAction *action = menu->addAction(icon, name); + action->setData(source); + } else { //ooh, it's actually a group! + QMenu *subMenu = menu->addMenu(icon, name); + bool hasEntries = false; + foreach (const QString &source, app.value("entries").toStringList()) { + hasEntries = addApp(subMenu, source) || hasEntries; + } + + if (!hasEntries) { + delete subMenu; + return false; + } + } + return true; +} + +void AppLauncher::switchTo(QAction *action) +{ + QString source = action->data().toString(); + kDebug() << source; + Plasma::Service *service = dataEngine("apps")->serviceForSource(source); + if (service) { + Plasma::ServiceJob *job = service->startOperationCall(service->operationDescription("launch")); + connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater())); + } +} + +#include "launch.moc" diff --git a/plasma/generic/containmentactions/applauncher/launch.h b/plasma/generic/containmentactions/applauncher/launch.h new file mode 100644 index 00000000..55a96230 --- /dev/null +++ b/plasma/generic/containmentactions/applauncher/launch.h @@ -0,0 +1,55 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SWITCHWINDOW_HEADER +#define SWITCHWINDOW_HEADER + +#include + +class QAction; +class KMenu; + +class AppLauncher : public Plasma::ContainmentActions +{ + Q_OBJECT + public: + AppLauncher(QObject* parent, const QVariantList& args); + ~AppLauncher(); + + void init(const KConfigGroup &config); + + void contextEvent(QEvent *event); + QList contextualActions(); + //returns true if something (other than a separator) was successfully added + bool addApp(QMenu *menu, const QString &source); + + public slots: + void switchTo(QAction *action); + + protected: + void makeMenu(); + + private: + KMenu *m_menu; + QAction *m_action; +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(applauncher, AppLauncher) + +#endif diff --git a/plasma/generic/containmentactions/applauncher/plasma-containmentactions-applauncher.desktop b/plasma/generic/containmentactions/applauncher/plasma-containmentactions-applauncher.desktop new file mode 100644 index 00000000..4d108240 --- /dev/null +++ b/plasma/generic/containmentactions/applauncher/plasma-containmentactions-applauncher.desktop @@ -0,0 +1,168 @@ +[Desktop Entry] +Name=Application Launcher +Name[af]=Programlanseerder +Name[ar]=مطلق التطبيقات +Name[ast]=Llanzador d'aplicaciones +Name[be]=Запуск праграмаў +Name[be@latin]=Uklučeńnie aplikacyi +Name[bg]=Стартиране на програми +Name[bn]=অ্যাপলিকেশন লঞ্চার +Name[bn_IN]=অ্যাপ্লিকেশন সঞ্চালনকারী +Name[bs]=pokretač programa +Name[ca]=Llançador d'aplicacions +Name[ca@valencia]=Llançador d'aplicacions +Name[cs]=Spouštěč aplikací +Name[csb]=Zrëszôcz programów +Name[da]=Startmenu +Name[de]=K-Menü +Name[el]=Εκτέλεση εφαρμογών +Name[en_GB]=Application Launcher +Name[eo]=Aplikaĵolanĉilo +Name[es]=Lanzador de aplicaciones +Name[et]=Rakenduste käivitaja +Name[eu]=Aplikazio-abiarazlea +Name[fa]=راه‌انداز برنامه +Name[fi]=Sovelluskäynnistin +Name[fr]=Lanceur d'application +Name[fy]=In applikaashe starter +Name[ga]=Tosaitheoir Feidhmchlár +Name[gl]=Iniciador de programas +Name[gu]=કાર્યક્રમ ચલાવનાર +Name[he]=משגר יישומים +Name[hi]=अनुप्रयोग चालक +Name[hne]=अनुपरयोग चालू करइया +Name[hr]=Pokretač aplikacija +Name[hsb]=Startowar za aplikacije +Name[hu]=Programindító +Name[ia]=Lanceator de application +Name[id]=Peluncur Aplikasi +Name[is]=Forrita-Ræsir +Name[it]=Avviatore di applicazioni +Name[ja]=Kickoff アプリケーションランチャー +Name[kk]=Қолданбаны жегу +Name[km]=កម្មវិធី​ចាប់ផ្ដើម​កម្មវិធី​ +Name[kn]=ಅನ್ವಯ ಪ್ರಕ್ಷೇಪಕ (ಲಾಚರ್) +Name[ko]=프로그램 실행기 +Name[ku]=Deskpêkerê Sepanan +Name[lt]=Programų paleidiklis +Name[lv]=Programmu palaidējs +Name[mai]=अनुप्रयोग चालक +Name[mk]=Стартувач на апликации +Name[ml]=പ്രയോഗവിക്ഷേപിണി +Name[mr]=अनुप्रयोग प्रक्षेपक +Name[nb]=Programstarter +Name[nds]=Programmoproper +Name[ne]=अनुप्रयोक सुरुआतकर्ता +Name[nl]=Programmastarter +Name[nn]=Programstartar +Name[or]=ପ୍ରୟୋଗ ଆରମ୍ଭକର୍ତ୍ତା +Name[pa]=ਐਪਲੀਕੇਸ਼ ਲਾਂਚਰ +Name[pl]=Aktywator programów +Name[pt]=Lançador de Aplicações +Name[pt_BR]=Lançador de aplicativos +Name[ro]=Lansator de aplicații +Name[ru]=Меню запуска приложений +Name[se]=Prográmmaálggaheaddji +Name[si]=යෙදුම් ඇරඹුම +Name[sk]=Spúšťač aplikácií +Name[sl]=Zaganjalnik programov +Name[sr]=покретач програма +Name[sr@ijekavian]=покретач програма +Name[sr@ijekavianlatin]=pokretač programa +Name[sr@latin]=pokretač programa +Name[sv]=Starta program +Name[ta]=பயன்பாடு ஏவி +Name[te]=అనువర్తనం దించునది +Name[tg]=Оғози барномаҳо +Name[th]=ตัวเรียกใช้งานโปรแกรม +Name[tr]=Uygulama Başlatıcısı +Name[ug]=پروگرامما ئىجرا قىلغۇچ +Name[uk]=Інструмент запуску програм +Name[uz]=Dasturlarni ishga tushiruvchi +Name[uz@cyrillic]=Дастурларни ишга туширувчи +Name[vi]=Trình chạy ứng dụng +Name[wa]=Enondeu di programe +Name[x-test]=xxApplication Launcherxx +Name[zh_CN]=程序启动器 +Name[zh_TW]=應用程式啟動器 +Type=Service +Icon=preferences-desktop-launch-feedback +Comment=Simple application launcher +Comment[ar]=مطلق التطبيقات البسيط +Comment[ast]=Llanzador d'aplicaciones simple +Comment[bg]=Стартиране на програми +Comment[bs]=Jednostavan pokretač programa +Comment[ca]=Llançador d'aplicacions senzill +Comment[ca@valencia]=Llançador d'aplicacions senzill +Comment[cs]=Jednoduchý spouštěč aplikací +Comment[csb]=Prosti zrëszôcz programów +Comment[da]=Simpel startmenu +Comment[de]=Einfacher Anwendungsstarter +Comment[el]=Απλή εκτέλεση εφαρμογών +Comment[en_GB]=Simple application launcher +Comment[es]=Lanzador de aplicaciones sencillo +Comment[et]=Lihtne rakenduste käivitaja +Comment[eu]=Aplikazio-abiarazle soila +Comment[fi]=Yksinkertainen sovelluskäynnistin +Comment[fr]=Lanceur simple d'application +Comment[fy]=Ienfâldige applikaasje útfierder +Comment[ga]=Tosaitheoir simplí feidhmchlár +Comment[gl]=Iniciador simple de programas +Comment[he]=משגר יישומים פשוט +Comment[hi]=सरल अनुप्रयोग चालक +Comment[hr]=Jednostavan pokretač aplikacija +Comment[hu]=Egyszerű alkalmazásindító +Comment[ia]=Simple lanceator de application +Comment[id]=Peluncur aplikasi sederhana +Comment[is]=Einfaldur forritaræsir +Comment[it]=Semplice avviatore di applicazioni +Comment[ja]=シンプルなアプリケーションランチャー +Comment[kk]=Қапапайым қолданба жеккіші +Comment[km]=កម្មវិធី​ចាប់ផ្ដើម​កម្មវិធី​សាមញ្ញ​ +Comment[kn]=ಸರಳ ಅನ್ವಯ ಪ್ರಕ್ಷೇಪಕ (ಲಾಂಚರ್) +Comment[ko]=간단한 프로그램 실행기 +Comment[lt]=Paprastas programų paleidiklis +Comment[lv]=Vienkāršs programmu palaidējs +Comment[mk]=Едноставен стартувач на апликации +Comment[ml]=ലളിതമായ പ്രയോഗവിക്ഷേപിണി +Comment[mr]=सोपा अनुप्रयोग प्रक्षेपक +Comment[nb]=Enkel programstarter +Comment[nds]=Eenfach Programmoproper +Comment[nl]=Eenvoudige programmastarter +Comment[nn]=Enkel programstartar +Comment[pa]=ਸਧਾਰਨ ਐਪਲੀਕੇਸ਼ ਲਾਂਚਰ +Comment[pl]=Proste uruchamianie programów +Comment[pt]=Lançador de aplicações simples +Comment[pt_BR]=Lançador de aplicativos simples +Comment[ro]=Lansator de aplicații simplu +Comment[ru]=Упрощённое меню запуска приложений +Comment[si]=සරල යෙදුම් අරඹනය +Comment[sk]=Jednoduchý spúšťač aplikácií +Comment[sl]=Preprost zaganjalnik programov +Comment[sr]=Једноставан покретач програма +Comment[sr@ijekavian]=Једноставан покретач програма +Comment[sr@ijekavianlatin]=Jednostavan pokretač programa +Comment[sr@latin]=Jednostavan pokretač programa +Comment[sv]=Enkel programstart +Comment[tg]=Иҷрогари барномаҳо +Comment[th]=ตัวเรียกใช้งานโปรแกรมพื้นฐาน +Comment[tr]=Basit uygulama başlatıcı +Comment[ug]=ئاددىي پروگرامما ئىجراچىسى +Comment[uk]=Простий інструмент запуску програм +Comment[wa]=Simpe enondeu di programe +Comment[x-test]=xxSimple application launcherxx +Comment[zh_CN]=简易程序启动器 +Comment[zh_TW]=簡單的應用程式啟動器 + +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_applauncher +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=applauncher +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/containmentactions/contextmenu/CMakeLists.txt b/plasma/generic/containmentactions/contextmenu/CMakeLists.txt new file mode 100644 index 00000000..91d1fada --- /dev/null +++ b/plasma/generic/containmentactions/contextmenu/CMakeLists.txt @@ -0,0 +1,18 @@ +project(plasma-containmentactions-contextmenu) + +set(contextmenu_SRCS + menu.cpp +) + +set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml) +QT4_ADD_DBUS_INTERFACE(contextmenu_SRCS ${krunner_xml} krunner_interface) + +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml) +QT4_ADD_DBUS_INTERFACE(contextmenu_SRCS ${screensaver_xml} screensaver_interface) + + +kde4_add_plugin(plasma_containmentactions_contextmenu ${contextmenu_SRCS}) +target_link_libraries(plasma_containmentactions_contextmenu ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} kworkspace) + +install(TARGETS plasma_containmentactions_contextmenu DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-contextmenu.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/contextmenu/Messages.sh b/plasma/generic/containmentactions/contextmenu/Messages.sh new file mode 100755 index 00000000..bc81a943 --- /dev/null +++ b/plasma/generic/containmentactions/contextmenu/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_containmentactions_contextmenu.pot diff --git a/plasma/generic/containmentactions/contextmenu/menu.cpp b/plasma/generic/containmentactions/contextmenu/menu.cpp new file mode 100644 index 00000000..bfd60a12 --- /dev/null +++ b/plasma/generic/containmentactions/contextmenu/menu.cpp @@ -0,0 +1,313 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "menu.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "kworkspace/kworkspace.h" +#include "krunner_interface.h" +#include "screensaver_interface.h" + +#ifdef Q_OS_WIN +#define _WIN32_WINNT 0x0500 // require NT 5.0 (win 2k pro) +#include +#endif // Q_OS_WIN + +ContextMenu::ContextMenu(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), + m_runCommandAction(0), + m_lockScreenAction(0), + m_logoutAction(0), + m_separator1(0), + m_separator2(0), + m_separator3(0), + m_buttons(0) +{ +} + +ContextMenu::~ContextMenu() +{ +} + +void ContextMenu::init(const KConfigGroup &config) +{ + Plasma::Containment *c = containment(); + Q_ASSERT(c); + + m_actions.clear(); + QHash actions; + QSet disabled; + + if (c->containmentType() == Plasma::Containment::PanelContainment || + c->containmentType() == Plasma::Containment::CustomPanelContainment) { + m_actionOrder << "add widgets" << "_add panel" << "lock widgets" << "_context" << "remove"; + } else { + actions.insert("configure shortcuts", false); + m_actionOrder << "_context" << "_run_command" << "add widgets" << "_add panel" + << "manage activities" << "remove" << "lock widgets" << "_sep1" + <<"_lock_screen" << "_logout" << "_sep2" << "configure" + << "configure shortcuts" << "_sep3" << "_wallpaper"; + disabled.insert("configure shortcuts"); + } + + foreach (const QString &name, m_actionOrder) { + actions.insert(name, !disabled.contains(name)); + } + + QHashIterator it(actions); + while (it.hasNext()) { + it.next(); + m_actions.insert(it.key(), config.readEntry(it.key(), it.value())); + } + + // everything below should only happen once, so check for it + if (c->containmentType() == Plasma::Containment::PanelContainment || + c->containmentType() == Plasma::Containment::CustomPanelContainment) { + //FIXME: panel does its own config action atm... + } else if (!m_runCommandAction) { + m_runCommandAction = new QAction(i18n("Run Command..."), this); + m_runCommandAction->setIcon(KIcon("system-run")); + connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand())); + + m_lockScreenAction = new QAction(i18n("Lock Screen"), this); + m_lockScreenAction->setIcon(KIcon("system-lock-screen")); + connect(m_lockScreenAction, SIGNAL(triggered(bool)), this, SLOT(lockScreen())); + + m_logoutAction = new QAction(i18n("Leave..."), this); + m_logoutAction->setIcon(KIcon("system-shutdown")); + connect(m_logoutAction, SIGNAL(triggered(bool)), this, SLOT(startLogout())); + + m_separator1 = new QAction(this); + m_separator1->setSeparator(true); + m_separator2 = new QAction(this); + m_separator2->setSeparator(true); + m_separator3 = new QAction(this); + m_separator3->setSeparator(true); + } +} + +void ContextMenu::contextEvent(QEvent *event) +{ + QList actions = contextualActions(); + if (actions.isEmpty()) { + return; + } + + KMenu desktopMenu; + desktopMenu.addActions(actions); + desktopMenu.adjustSize(); + desktopMenu.exec(popupPosition(desktopMenu.size(), event)); +} + +QList ContextMenu::contextualActions() +{ + Plasma::Containment *c = containment(); + Q_ASSERT(c); + QList actions; + foreach (const QString &name, m_actionOrder) { + if (!m_actions.value(name)) { + continue; + } + + if (name == "_context") { + actions << c->contextualActions(); + } if (name == "_wallpaper") { + if (c->wallpaper()) { + actions << c->wallpaper()->contextualActions(); + } + } else if (QAction *a = action(name)) { + actions << a; + } + } + + return actions; +} + +QAction *ContextMenu::action(const QString &name) +{ + Plasma::Containment *c = containment(); + Q_ASSERT(c); + if (name == "_sep1") { + return m_separator1; + } else if (name == "_sep2") { + return m_separator2; + } else if (name == "_sep3") { + return m_separator3; + } else if (name == "_add panel") { + if (c->corona() && c->corona()->immutability() == Plasma::Mutable) { + return c->corona()->action("add panel"); + } + } else if (name == "_run_command") { + if (KAuthorized::authorizeKAction("run_command")) { + return m_runCommandAction; + } + } else if (name == "_lock_screen") { + if (KAuthorized::authorizeKAction("lock_screen")) { + return m_lockScreenAction; + } + } else if (name == "_logout") { + if (KAuthorized::authorizeKAction("logout")) { + return m_logoutAction; + } + } else if (name == "manage activities") { + if (c->corona()) { + return c->corona()->action("manage activities"); + } + } else { + //FIXME: remove action: make removal of current activity possible + return c->action(name); + } + return 0; +} + +void ContextMenu::runCommand() +{ + if (!KAuthorized::authorizeKAction("run_command")) { + return; + } + + QString interface("org.kde.krunner"); + org::kde::krunner::App krunner(interface, "/App", QDBusConnection::sessionBus()); + krunner.display(); +} + +void ContextMenu::lockScreen() +{ + if (!KAuthorized::authorizeKAction("lock_screen")) { + return; + } + +#ifndef Q_OS_WIN + QString interface("org.freedesktop.ScreenSaver"); + org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver", + QDBusConnection::sessionBus()); + if (screensaver.isValid()) { + screensaver.Lock(); + } +#else + LockWorkStation(); +#endif // !Q_OS_WIN +} + +void ContextMenu::startLogout() +{ + // this short delay is due to two issues: + // a) KWorkSpace's DBus alls are all syncronous + // b) the destrution of the menu that this action is in is delayed + // + // (a) leads to the menu hanging out where everyone can see it because + // the even loop doesn't get returned to allowing it to close. + // + // (b) leads to a 0ms timer not working since a 0ms timer just appends to + // the event queue, and then the menu closing event gets appended to that. + // + // ergo a timer with small timeout + QTimer::singleShot(10, this, SLOT(logout())); +} + +void ContextMenu::logout() +{ + if (!KAuthorized::authorizeKAction("logout")) { + return; + } + + KWorkSpace::requestShutDown(); +} + +QWidget* ContextMenu::createConfigurationInterface(QWidget* parent) +{ + QWidget *widget = new QWidget(parent); + QVBoxLayout *lay = new QVBoxLayout(); + widget->setLayout(lay); + widget->setWindowTitle(i18n("Configure Contextual Menu Plugin")); + m_buttons = new QButtonGroup(widget); + m_buttons->setExclusive(false); + + foreach (const QString &name, m_actionOrder) { + QCheckBox *item = 0; + + if (name == "_context") { + item = new QCheckBox(widget); + //FIXME better text + item->setText(i18n("[Other Actions]")); + } else if (name == "_wallpaper") { + item = new QCheckBox(widget); + item->setText(i18n("Wallpaper Actions")); + item->setIcon(KIcon("user-desktop")); + } else if (name == "_sep1" || name =="_sep2" || name == "_sep3") { + item = new QCheckBox(widget); + item->setText(i18n("[Separator]")); + } else { + QAction *a = action(name); + if (a) { + item = new QCheckBox(widget); + item->setText(a->text()); + item->setIcon(a->icon()); + } + } + + if (item) { + item->setChecked(m_actions.value(name)); + item->setProperty("actionName", name); + lay->addWidget(item); + m_buttons->addButton(item); + } + } + + return widget; +} + +void ContextMenu::configurationAccepted() +{ + QList buttons = m_buttons->buttons(); + QListIterator it(buttons); + while (it.hasNext()) { + QAbstractButton *b = it.next(); + if (b) { + m_actions.insert(b->property("actionName").toString(), b->isChecked()); + } + } +} + +void ContextMenu::save(KConfigGroup &config) +{ + QHashIterator it(m_actions); + while (it.hasNext()) { + it.next(); + config.writeEntry(it.key(), it.value()); + } +} + + +#include "menu.moc" diff --git a/plasma/generic/containmentactions/contextmenu/menu.h b/plasma/generic/containmentactions/contextmenu/menu.h new file mode 100644 index 00000000..85cd9de6 --- /dev/null +++ b/plasma/generic/containmentactions/contextmenu/menu.h @@ -0,0 +1,65 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef CONTEXTMENU_HEADER +#define CONTEXTMENU_HEADER + +#include +#include + +class ContextMenu : public Plasma::ContainmentActions +{ + Q_OBJECT +public: + ContextMenu(QObject* parent, const QVariantList& args); + ~ContextMenu(); + + void init(const KConfigGroup&); + + void contextEvent(QEvent *event); + QList contextualActions(); + QAction* action(const QString &name); + + QWidget* createConfigurationInterface(QWidget* parent); + void configurationAccepted(); + void save(KConfigGroup &config); + +public slots: + void runCommand(); + void lockScreen(); + void startLogout(); + void logout(); + +private: + QAction *m_runCommandAction; + QAction *m_lockScreenAction; + QAction *m_logoutAction; + QAction *m_separator1; + QAction *m_separator2; + QAction *m_separator3; + + // action name and whether it is enabled or not + QHash m_actions; + QStringList m_actionOrder; + QButtonGroup *m_buttons; +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(contextmenu, ContextMenu) + +#endif diff --git a/plasma/generic/containmentactions/contextmenu/plasma-containmentactions-contextmenu.desktop b/plasma/generic/containmentactions/contextmenu/plasma-containmentactions-contextmenu.desktop new file mode 100644 index 00000000..9db0d321 --- /dev/null +++ b/plasma/generic/containmentactions/contextmenu/plasma-containmentactions-contextmenu.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +Name=Standard Menu +Name[ar]=القائمة المعيارية +Name[ast]=Menú standard +Name[bg]=Стандартно меню +Name[bs]=standardni meni +Name[ca]=Menú estàndard +Name[ca@valencia]=Menú estàndard +Name[cs]=Standardní nabídka +Name[csb]=Standardowé menu +Name[da]=Standardmenu +Name[de]=Standard-Menü +Name[el]=Τυπικό Μενού +Name[en_GB]=Standard Menu +Name[eo]=Defaŭlta Menuo +Name[es]=Menú estándar +Name[et]=Standardmenüü +Name[eu]=Menu estandarra +Name[fi]=Vakiovalikko +Name[fr]=Menu standard +Name[fy]=Standert menu +Name[ga]=Gnáthroghchlár +Name[gl]=Menú estándar +Name[he]=תפריט רגיל +Name[hi]=मानक मीनु +Name[hr]=Standardni izbornik +Name[hu]=Standard menü +Name[ia]=Menu standard +Name[id]=Menu Standar +Name[is]=Staðalvalmynd +Name[it]=Menu standard +Name[ja]=標準メニュー +Name[ka]=სტანდარტული მენიუ +Name[kk]=Стандартты мәзір +Name[km]=ម៉ឺនុយ​ស្តង់ដារ +Name[kn]=ಶಿಷ್ಟ ಪರಿವಿಡಿ +Name[ko]=표준 메뉴 +Name[lt]=Standartinis meniu +Name[lv]=Konteksta izvēlne +Name[mk]=Стандардно мени +Name[ml]=സ്റ്റാന്‍ഡര്‍ഡ് മെനു +Name[mr]=प्रमाणित मेन्यू +Name[nb]=Standardmeny +Name[nds]=Standardmenü +Name[nl]=Standaardmenu +Name[nn]=Standardmeny +Name[pa]=ਸਟੈਂਡਰਡ ਮੇਨੂ +Name[pl]=Menu standardowe +Name[pt]=Menu Normal +Name[pt_BR]=Menu padrão +Name[ro]=Meniu standard +Name[ru]=Стандартное контекстное меню +Name[si]=සම්මත මෙනුව +Name[sk]=Štandardné menu +Name[sl]=Običajni meni +Name[sr]=стандардни мени +Name[sr@ijekavian]=стандардни мени +Name[sr@ijekavianlatin]=standardni meni +Name[sr@latin]=standardni meni +Name[sv]=Standardmeny +Name[tg]=Менюи стандартӣ +Name[th]=เมนูมาตรฐาน +Name[tr]=Standart Menü +Name[ug]=ئۆلچەملىك تىزىملىك +Name[uk]=Стандартне меню +Name[wa]=Dressêye sitandård +Name[x-test]=xxStandard Menuxx +Name[zh_CN]=标准菜单 +Name[zh_TW]=標準選單 +Comment=The menu that normally shows on right-click +Comment[ar]=القائمة التي تظهر عادة عند الضغط بالزر الأيمن +Comment[ast]=El menú que se suel amosar al calcar col botón derechu +Comment[bg]=Менюто, което обикновено се появява при щракване с десен бутон на мишката +Comment[bs]=Meni koji se obično pokazuje na desni klik +Comment[ca]=Menú que es mostra normalment amb un clic del botó dret +Comment[ca@valencia]=Menú que es mostra normalment amb un clic del botó dret +Comment[cs]=Nabídka která se normálně zobrazuje po stisknutí pravého tlačítka +Comment[csb]=Menu wëskrzëniwóné zwëczajno pò klëkniãcô prawą knąpą +Comment[da]=Menuen der normalt vises ved højreklik +Comment[de]=Das Menü, welches für gewöhnlich durch einen Rechtsklick geöffnet wird +Comment[el]=Το μενού το οποίο εμφανίζεται με δεξί κλικ +Comment[en_GB]=The menu that normally shows on right-click +Comment[eo]=La menuo videblas per dekstra musklako +Comment[es]=El menú que se suele mostrar al hacer clic derecho +Comment[et]=Tavaliselt hiire parema nupu klõpsuga avanev menüü +Comment[eu]=Eskuineko botoiaz klik eginda agertu ohi den menua +Comment[fi]=Valikko, joka tavallisesti näkyy hiiren kakkospainikkeella +Comment[fr]=Le menu s'affichant normalement lors d'un clic droit +Comment[fy]=It menu dat normaal mei rjochts klik ferskynt +Comment[ga]=An roghchlár a thaispeántar tar éis deaschliceáil +Comment[gl]=O menú que se mostra xeralmente ao premer co botón dereito +Comment[he]=התפריט שמופיע בעת לחיצה על הכפתור הימני בעכבר +Comment[hr]=Izbornik koji se obično pojavljuje na desni klik +Comment[hu]=A jobb egérkattintásra megjelenő menü +Comment[ia]=Le menu que normalmente monstra se sur le pression dextere +Comment[id]=Menu yang normalnya muncul saat klik-kanan +Comment[is]=Valmyndin sem kemur venjulega upp við hægrismell +Comment[it]=Il menu che normalmente appare su clic destro +Comment[ja]=通常は右クリックで表示されるメニュー +Comment[kk]=Оң жақ түртімде шыға келетін кәдімгі мәзір +Comment[km]=ម៉ឺនុយ​ដែល​តាម​ធម្មតា​បង្ហាញ​នៅ​ពេល​ចុច​កណ្ដុរ​ស្ដាំ +Comment[kn]=ಸಾಮಾನ್ಯವಾಗಿ ಮೌಸ್‌ನ ಬಲ ಬದಿಯ ಕ್ಲಿಕ್‌ಗೆ ತೆರೆಯುವ ಪರಿವಿಡಿ +Comment[ko]=오른쪽 단추를 눌렀을 때 나타나는 메뉴 +Comment[lt]=Šis meniu paprastai rodomas po pelės dešinio klavišo paspaudimo +Comment[lv]=Izvēlne, kas parasti parādās pēc labā peles klikšķa +Comment[mk]=Менито што обично се појавува на десно кликнување +Comment[ml]=വലത്-ഞെക്കില്‍ സാധാരണ കാണിയ്ക്കുന്ന മെനു +Comment[mr]=उजवी क्लिक केल्यावर सामान्यतः दिसणारा मेन्यू +Comment[nb]=Menyen som vanligvis vises med høyre-klikk +Comment[nds]=Dat Menü, dat Een normalerwies mit de rechte Muustast opropen deit +Comment[nl]=Het menu dat normaal verschijnt bij rechtsklikken +Comment[nn]=Menyen som vanlegvis vert vist ved høgreklikking +Comment[pa]=ਮੇਨੂ, ਜੋ ਕਿ ਸੱਜੇ ਕਲਿੱਕ ਨਾਲ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ +Comment[pl]=Menu pokazujące się po kliknięciu prawym przyciskiem myszy +Comment[pt]=O menu que aparece normalmente com o botão direito +Comment[pt_BR]=O menu que normalmente aparece ao clicar com o botão direito +Comment[ro]=Meniul ce apare de obicei la clic-dreapta +Comment[ru]=Меню, которое обычно открывается правой кнопкой мыши +Comment[si]=දකුණු-ක්ලික් කිරීමට සාමාන්‍යයෙන් ලැබෙන මෙනුව +Comment[sk]=Menu, ktoré sa zvyčajne zobrazuje po kliknutí pravým tlačidlom myši +Comment[sl]=Meni, ki se običajno prikaže ob desnem kliku +Comment[sr]=Мени који се обично показује на десни клик +Comment[sr@ijekavian]=Мени који се обично показује на десни клик +Comment[sr@ijekavianlatin]=Meni koji se obično pokazuje na desni klik +Comment[sr@latin]=Meni koji se obično pokazuje na desni klik +Comment[sv]=Meny som normalt visas med högerklick +Comment[th]=เมนูปกติที่จะแสดงเมื่อมีการคลิกเมาส์ปุ่มขวา +Comment[tr]=Sağ tıklama ile doğal olarak gösterilen menü +Comment[ug]=چاشقىنەك ئوڭ توپچىسى چېكىلگەندە كۆرۈنىدىغان تىزىملىك +Comment[uk]=Меню, яке буде показано у відповідь на клацання правою кнопкою миші +Comment[wa]=Li dressêye k' on voet normålmint cwand on clitche droet +Comment[x-test]=xxThe menu that normally shows on right-clickxx +Comment[zh_CN]=通常在点击右键时显示的菜单 +Comment[zh_TW]=此選單通常由滑鼠右鍵叫出 +Type=Service +Icon=help-contextual +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_contextmenu +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=contextmenu +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-HasConfigurationInterface=true diff --git a/plasma/generic/containmentactions/minimalcontextmenu/CMakeLists.txt b/plasma/generic/containmentactions/minimalcontextmenu/CMakeLists.txt new file mode 100644 index 00000000..66310f93 --- /dev/null +++ b/plasma/generic/containmentactions/minimalcontextmenu/CMakeLists.txt @@ -0,0 +1,11 @@ +project(plasma-containmentactions-minimalcontextmenu) + +set(contextmenu_SRCS + menu.cpp +) + +kde4_add_plugin(plasma_containmentactions_minimalcontextmenu ${contextmenu_SRCS}) +target_link_libraries(plasma_containmentactions_minimalcontextmenu ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containmentactions_minimalcontextmenu DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-minimalcontextmenu.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/minimalcontextmenu/menu.cpp b/plasma/generic/containmentactions/minimalcontextmenu/menu.cpp new file mode 100644 index 00000000..7dfe668e --- /dev/null +++ b/plasma/generic/containmentactions/minimalcontextmenu/menu.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "menu.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + +ContextMenu::ContextMenu(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args) +{ + m_separator = new QAction(this); + m_separator->setSeparator(true); +} + +ContextMenu::~ContextMenu() +{ +} + +void ContextMenu::contextEvent(QEvent *event) +{ + QList actions = contextualActions(); + if (actions.isEmpty()) { + return; + } + + KMenu desktopMenu; + desktopMenu.addActions(actions); + desktopMenu.adjustSize(); + desktopMenu.exec(popupPosition(desktopMenu.size(), event)); +} + +QList ContextMenu::contextualActions() +{ + Plasma::Containment *c = containment(); + Q_ASSERT(c); + QList actions; + actions << c->contextualActions(); + if (c->wallpaper() && + !c->wallpaper()->contextualActions().isEmpty()) { + actions << m_separator; + actions << c->wallpaper()->contextualActions(); + } + return actions; +} + +#include "menu.moc" diff --git a/plasma/generic/containmentactions/minimalcontextmenu/menu.h b/plasma/generic/containmentactions/minimalcontextmenu/menu.h new file mode 100644 index 00000000..db413ea4 --- /dev/null +++ b/plasma/generic/containmentactions/minimalcontextmenu/menu.h @@ -0,0 +1,43 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef CONTEXTMENU_HEADER +#define CONTEXTMENU_HEADER + +#include +#include + +class ContextMenu : public Plasma::ContainmentActions +{ + Q_OBJECT +public: + ContextMenu(QObject* parent, const QVariantList& args); + ~ContextMenu(); + + void contextEvent(QEvent *event); + QList contextualActions(); + +private: + QAction *m_separator; + +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(minimalcontextmenu, ContextMenu) + +#endif diff --git a/plasma/generic/containmentactions/minimalcontextmenu/plasma-containmentactions-minimalcontextmenu.desktop b/plasma/generic/containmentactions/minimalcontextmenu/plasma-containmentactions-minimalcontextmenu.desktop new file mode 100644 index 00000000..a2a8b650 --- /dev/null +++ b/plasma/generic/containmentactions/minimalcontextmenu/plasma-containmentactions-minimalcontextmenu.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Name=Minimal Menu +Name[ar]=القائمة المصغرة +Name[ast]=Menú mínimu +Name[bg]=Малко меню +Name[bs]=najmanji meni +Name[ca]=Menú mínim +Name[ca@valencia]=Menú mínim +Name[cs]=Minimální nabídka +Name[da]=Minimal menu +Name[de]=Minimales Menü +Name[el]=Ελάχιστο μενού +Name[en_GB]=Minimal Menu +Name[es]=Menú mínimo +Name[et]=Minimaalne menüü +Name[eu]=Menu minimoa +Name[fi]=Minimaalinen valikko +Name[fr]=Menu minimum +Name[ga]=Roghchlár Íosta +Name[gl]=Menú mínimo +Name[he]=תפריט מינימלי +Name[hi]=न्युतम मीनु +Name[hr]=Minimalni izbornik +Name[hu]=Minimális menü +Name[ia]=Menu minime +Name[id]=Menu Minimal +Name[is]=Lágmarksvalmynd +Name[it]=Menu minimo +Name[ja]=最小メニュー +Name[ka]=მინიმალური მენიუ +Name[kk]=Minimal Menu +Name[km]=ម៉ឺនុយ​អប្បបរមា +Name[kn]=ಅತ್ಯಲ್ಪ ಪರಿವಿಡಿ +Name[ko]=최소 메뉴 +Name[lt]=Minimalistinis meniu +Name[lv]=Minimāla izvēlne +Name[mk]=Минимално мени +Name[mr]=किमान मेन्यू +Name[nb]=Minimal meny +Name[nds]=Minimaalmenü +Name[nl]=Minimaal menu +Name[nn]=Liten meny +Name[pa]=ਘੱਟੋ-ਘੱਟ ਮੈਨੂ +Name[pl]=Menu minimalistyczne +Name[pt]=Menu Mínimo +Name[pt_BR]=Menu Minimalista +Name[ro]=Meniu minim +Name[ru]=Минимальное меню +Name[si]=අවම මෙනුව +Name[sk]=Minimálne menu +Name[sl]=Minimalen meni +Name[sr]=најмањи мени +Name[sr@ijekavian]=најмањи мени +Name[sr@ijekavianlatin]=najmanji meni +Name[sr@latin]=najmanji meni +Name[sv]=Minimal meny +Name[tg]=Менюи хурдтарин +Name[th]=เมนูย่อ +Name[tr]=Basit Menü +Name[ug]=ئەڭ كىچىك تىزىملىك +Name[uk]=Мінімальне меню +Name[wa]=Dressêye å pus ptit +Name[x-test]=xxMinimal Menuxx +Name[zh_CN]=最小化菜单 +Name[zh_TW]=最小化選單 +Type=Service +Icon=help-contextual +ServiceTypes=Plasma/ContainmentActions +NoDisplay=true + +X-KDE-Library=plasma_containmentactions_minimalcontextmenu +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=minimalcontextmenu +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL + +X-Plasma-HasConfigurationInterface=false diff --git a/plasma/generic/containmentactions/paste/CMakeLists.txt b/plasma/generic/containmentactions/paste/CMakeLists.txt new file mode 100644 index 00000000..10ce544b --- /dev/null +++ b/plasma/generic/containmentactions/paste/CMakeLists.txt @@ -0,0 +1,11 @@ +project(plasma-containmentactions-paste) + +set(paste_SRCS + paste.cpp +) + +kde4_add_plugin(plasma_containmentactions_paste ${paste_SRCS}) +target_link_libraries(plasma_containmentactions_paste ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containmentactions_paste DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-paste.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/paste/paste.cpp b/plasma/generic/containmentactions/paste/paste.cpp new file mode 100644 index 00000000..c51a6920 --- /dev/null +++ b/plasma/generic/containmentactions/paste/paste.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "paste.h" + +#include +#include + +#include + +Paste::Paste(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args) +{ +} + +void Paste::contextEvent(QEvent *event) +{ + QPointF scenePos; + QPoint screenPos; + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + event->accept(); + return; + case QEvent::GraphicsSceneMouseRelease: { + QGraphicsSceneMouseEvent *e = static_cast(event); + scenePos = e->scenePos(); + screenPos = e->screenPos(); + break; } + case QEvent::GraphicsSceneWheel: { + QGraphicsSceneWheelEvent *e = static_cast(event); + scenePos = e->scenePos(); + screenPos = e->screenPos(); + break; } + default: //can't get the pos + return; + } + paste(scenePos, screenPos); +} + +#include "paste.moc" diff --git a/plasma/generic/containmentactions/paste/paste.h b/plasma/generic/containmentactions/paste/paste.h new file mode 100644 index 00000000..8a91da38 --- /dev/null +++ b/plasma/generic/containmentactions/paste/paste.h @@ -0,0 +1,36 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PASTE_HEADER +#define PASTE_HEADER + +#include + +class Paste : public Plasma::ContainmentActions +{ + Q_OBJECT + public: + Paste(QObject* parent, const QVariantList& args); + + void contextEvent(QEvent *event); +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(paste, Paste) + +#endif diff --git a/plasma/generic/containmentactions/paste/plasma-containmentactions-paste.desktop b/plasma/generic/containmentactions/paste/plasma-containmentactions-paste.desktop new file mode 100644 index 00000000..2c00688c --- /dev/null +++ b/plasma/generic/containmentactions/paste/plasma-containmentactions-paste.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +Name=Paste +Name[ar]=ألصِق +Name[ast]=Apegar +Name[bg]=Поставяне +Name[bn]=পেস্ট +Name[bs]=naljepljivanje +Name[ca]=Enganxa +Name[ca@valencia]=Apega +Name[cs]=Vložit +Name[csb]=Wlepi +Name[da]=Indsæt +Name[de]=Einfügen +Name[el]=Επικόλληση +Name[en_GB]=Paste +Name[eo]=Glui +Name[es]=Pegar +Name[et]=Asetamine +Name[eu]=Itsatsi +Name[fa]=چسباندن +Name[fi]=Liitä +Name[fr]=Coller +Name[fy]=Plakke +Name[ga]=Greamaigh +Name[gl]=Apegar +Name[gu]=ચોટાડો +Name[he]=הדבקה +Name[hi]=चिपकाएँ +Name[hr]=Umetni +Name[hu]=Beillesztés +Name[ia]=Colla +Name[id]=Tempel +Name[is]=Líma +Name[it]=Incolla +Name[ja]=貼り付け +Name[kk]=Орналастыру +Name[km]=បិទភ្ជាប់ +Name[kn]=ಅಂಟಿಸು +Name[ko]=붙여넣기 +Name[lt]=Įterpti +Name[lv]=Ielīmēt +Name[ml]=ഒട്ടിയ്ക്കുക +Name[mr]=चिटकवा +Name[nb]=Lim inn +Name[nds]=Infögen +Name[nl]=Plakken +Name[nn]=Tekstbitar +Name[pa]=ਚੇਪੋ +Name[pl]=Wklej +Name[pt]=Colar +Name[pt_BR]=Colar +Name[ro]=Lipește +Name[ru]=Вставка текста +Name[si]=අලවන්න +Name[sk]=Vložiť +Name[sl]=Lepljenje +Name[sr]=налепљивање +Name[sr@ijekavian]=наљепљивање +Name[sr@ijekavianlatin]=naljepljivanje +Name[sr@latin]=nalepljivanje +Name[sv]=Klistra in +Name[tg]=Часпондан +Name[th]=วาง +Name[tr]=Yapıştır +Name[ug]=چاپلا +Name[uk]=Вставка +Name[wa]=Aclaper +Name[x-test]=xxPastexx +Name[zh_CN]=粘贴 +Name[zh_TW]=貼上 +Type=Service +Icon=edit-paste +Comment=Creates a widget from the contents of the clipboard +Comment[ar]=أنشئ ودجة من محتويات الحافظة +Comment[ast]=Crea un elementu gráficu colos conteníos del cartafueyu +Comment[bg]=Създаване на джаджа със съдържанието на системния буфер +Comment[bs]=Stvara grafičku kontrolu na osnovu sadržaja klipborda +Comment[ca]=Crea un estri a partir del contingut del porta-retalls +Comment[ca@valencia]=Crea un estri a partir del contingut del porta-retalls +Comment[cs]=Vytvoří widget z obsahu schránky +Comment[da]=Opretter en widget ud fra indholdet af udklipsholderen +Comment[de]=Erzeugt ein Miniprogramm aus dem Inhalt der Zwischenablage +Comment[el]=Δημιουργία γραφικού συστατικού από τα περιεχόμενα του προχείρου. +Comment[en_GB]=Creates a widget from the contents of the clipboard +Comment[eo]=Krei fenestraĵon el la enhavo de la tondejo +Comment[es]=Crea un elemento gráfico con los contenidos del portapapeles +Comment[et]=Vidina loomine lõikepuhvri sisu põhjal +Comment[eu]=Trepeta bat sortzen du arbelaren edukiarekin +Comment[fi]=Luo käyttöliittymäelementin leikepöydän sisällöstä +Comment[fr]=Crée un composant graphique à partir du contenu du presse-papier +Comment[fy]=Makket in widget fan de ynhâld fan in klamboerd +Comment[ga]=Cruthaíonn sé giuirléid ó inneachar na gearrthaisce +Comment[gl]=Crea un widget a partir do contido do portarretallos +Comment[he]=משמש ליצירת ווידג׳ט מתוכן לוח העריכה +Comment[hr]=Stvara widget iz sadržaja međuspremnika +Comment[hu]=Készít egy widgetet a vágólap tartalmából +Comment[ia]=Il crea elemento graphic (Widget) ex le contentos del area de transferentia (clipboard) +Comment[id]=Membuat widget dari isi papan klip +Comment[is]=Búa til græju úr innihaldi klippispjaldsins +Comment[it]=Crea un oggetto dai contenuti degli appunti +Comment[ja]=クリップボードの内容からウィジェットを作成します +Comment[kk]=Алмасу буферіндегісінен виджетті құру +Comment[km]=បង្កើត​ធាតុក្រាហ្វិក​ពី​មាតិកា​របស់​ក្ដារតម្បៀតខ្ទាស់ +Comment[kn]=ನಕಲುಫಲಕದಲ್ಲಿರುವ (ಕ್ಲಿಪ್‌ಬೋರ್ಡ್) ವಿಷಯಗಳಿಂದ ಒಂದು ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟವನ್ನು(ವಿಡ್ಗೆಟ್) ನಿರ್ಮಿಸುತ್ತದೆ +Comment[ko]=클립보드 내용을 기반으로 위젯을 만듭니다 +Comment[lt]=Sukuria valdiklį iš laikinosios atmintinės turinio +Comment[lv]=Izveido sīkrīku no starpliktuves satura +Comment[ml]=ഓര്‍മ്മച്ചെപ്പിലെ ഉള്ളടക്കങ്ങള്‍ കൊണ്ട് ഒരു ഉരുപ്പടിയുണ്ടാക്കുന്നു +Comment[mr]=क्लिपबोर्ड मधील मजकूरावरुन विजेट बनवितो +Comment[nb]=Lager et skjermelement av innholdet fra utklippstavla +Comment[nds]=Stellt ut den Twischenaflaag-Inholt en Lüttprogramm op +Comment[nl]=Maakt een widget aan uit de inhoud van het klembord +Comment[nn]=Lag eit element frå innhaldet på utklippstavla +Comment[pa]=ਕਲਿੱਪਬੋਰਡ ਦੀ ਸਮੱਗਰੀ ਤੋਂ ਵਿਦਜੈੱਟ ਬਣਾਉ +Comment[pl]=Tworzy element interfejsu z zawartości schowka +Comment[pt]=Cria um elemento a partir do conteúdo da área de transferência +Comment[pt_BR]=Cria um widget a partir do conteúdo da área de transferência +Comment[ro]=Creează un control din conținutul clipboard-ului +Comment[ru]=Создание виджета с содержимым буфера обмена +Comment[si]=ක්ලිප් පුවරුවේ අන්තර්‍ගතය භාවිතයෙන් විජෙට්ටුවක් නිර්‍මාණය කරන්න +Comment[sk]=Vytvorí widget z obsahu schránky +Comment[sl]=Ustvari gradnik iz vsebine odložišča +Comment[sr]=Ствара виџет на основу садржаја клипборда +Comment[sr@ijekavian]=Ствара виџет на основу садржаја клипборда +Comment[sr@ijekavianlatin]=Stvara vidžet na osnovu sadržaja klipborda +Comment[sr@latin]=Stvara vidžet na osnovu sadržaja klipborda +Comment[sv]=Skapa komponent från klippbordets innehåll +Comment[th]=สร้างวิดเจ็ตจากเนื้อหาของคลิปบอร์ด +Comment[tr]=Pano içeriğininden bir gereç oluşturur +Comment[ug]=چاپلاش تاختىدىكى مەزمۇندىن widget قۇرىدۇ +Comment[uk]=Створює віджет з вмістом буфера обміну даними +Comment[vi]=Tạo một widget từ nội dung của bảng nhớ tạm +Comment[wa]=Ahive ene ahesse avou ç' k' i gn a e presse-papî +Comment[x-test]=xxCreates a widget from the contents of the clipboardxx +Comment[zh_CN]=从剪贴板内容中创建部件 +Comment[zh_TW]=從剪貼簿內容建立一元件 + +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_paste +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=paste +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/containmentactions/switchactivity/CMakeLists.txt b/plasma/generic/containmentactions/switchactivity/CMakeLists.txt new file mode 100644 index 00000000..dee043c7 --- /dev/null +++ b/plasma/generic/containmentactions/switchactivity/CMakeLists.txt @@ -0,0 +1,12 @@ +project(plasma-containmentactions-switchactivity) +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace) + +set(switchactivity_SRCS + switch.cpp +) + +kde4_add_plugin(plasma_containmentactions_switchactivity ${switchactivity_SRCS}) +target_link_libraries(plasma_containmentactions_switchactivity ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} kworkspace) + +install(TARGETS plasma_containmentactions_switchactivity DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-switchactivity.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/switchactivity/Messages.sh b/plasma/generic/containmentactions/switchactivity/Messages.sh new file mode 100755 index 00000000..3c54a526 --- /dev/null +++ b/plasma/generic/containmentactions/switchactivity/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_containmentactions_switchactivity.pot diff --git a/plasma/generic/containmentactions/switchactivity/plasma-containmentactions-switchactivity.desktop b/plasma/generic/containmentactions/switchactivity/plasma-containmentactions-switchactivity.desktop new file mode 100644 index 00000000..073516a8 --- /dev/null +++ b/plasma/generic/containmentactions/switchactivity/plasma-containmentactions-switchactivity.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Switch Activity +Name[ar]=بدّل النشاط +Name[ast]=Camudar xera +Name[bg]=Превключване на дейност +Name[bs]=prebacivanje aktivnosti +Name[ca]=Canvi d'activitat +Name[ca@valencia]=Canvi d'activitat +Name[cs]=Přepnout aktivitu +Name[da]=Skift aktivitet +Name[de]=Aktivität wechseln +Name[el]=Εναλλαγή δραστηριότητας +Name[en_GB]=Switch Activity +Name[eo]=Ŝalti Aktivecon +Name[es]=Cambiar actividad +Name[et]=Tegevuse vahetamine +Name[eu]=Jardueraz aldatu +Name[fi]=Vaihda aktiviteettia +Name[fr]=Changer d'activité +Name[fy]=Aktiviteit wikselje +Name[ga]=Athraigh Gníomhaíocht +Name[gl]=Trocar de actividade +Name[he]=מחליף פעילות +Name[hi]=क्रिया बदलें +Name[hr]=Prebaci aktivnost +Name[hu]=Aktivitásváltás +Name[ia]=Commuta activitate +Name[id]=Aktivitas Pindah +Name[is]=Skipta um virkni +Name[it]=Cambia attività +Name[ja]=アクティビティを切り替え +Name[kk]=Белсенділікті ауыстыру +Name[km]=ប្ដូរ​សកម្មភាព +Name[kn]=ಚಟುವಟಿಕೆಯನ್ನು ಬದಲಾಯಿಸು +Name[ko]=활동 전환 +Name[lt]=Pakeisti veiklą +Name[lv]=Pārslēgt aktivitāti +Name[mk]=Смени активност +Name[ml]=പ്രക്രിയ മാറ്റുക +Name[mr]=वेगळ्या कार्यपध्दती वर जा +Name[nb]=Bytt aktivitet +Name[nds]=Aktiviteet wesseln +Name[nl]=Activiteit omschakelen +Name[nn]=Byt aktivitet +Name[pa]=ਐਕਟਵਿਟੀ ਬਦਲੋ +Name[pl]=Przełącz działanie +Name[pt]=Mudar de Actividade +Name[pt_BR]=Alternar atividade +Name[ro]=Comutare activitate +Name[ru]=Переключение комнат +Name[si]=කාර්‍යය මාරුකරන්න +Name[sk]=Prepnúť aktivitu +Name[sl]=Preklapljanje med dejavnostmi +Name[sr]=пребацивање активности +Name[sr@ijekavian]=пребацивање активности +Name[sr@ijekavianlatin]=prebacivanje aktivnosti +Name[sr@latin]=prebacivanje aktivnosti +Name[sv]=Byt aktivitet +Name[tg]=Мубодилаи амалиёт +Name[th]=สลับกิจกรรม +Name[tr]=Etkinlik Değiştir +Name[ug]=پائالىيەت ئالماشتۇر +Name[uk]=Перемкнути простір дій +Name[wa]=Potchî a ene ôte activité +Name[x-test]=xxSwitch Activityxx +Name[zh_CN]=切换活动 +Name[zh_TW]=切換活動 +Type=Service +Icon=dashboard-show +Comment=Switch to another activity +Comment[ar]=بدّل إلى نشاط آخر +Comment[ast]=Camudar a otra xera +Comment[bg]=Превключване към друга дейност +Comment[bs]=Prebacuje na drugu aktivnost +Comment[ca]=Canvia a una altra activitat +Comment[ca@valencia]=Canvia a una altra activitat +Comment[cs]=Přepnout na jinou aktivitu +Comment[da]=Skift til en anden aktivitet +Comment[de]=Ermöglich Ihnen, zu einer anderen Aktivität zu wechseln +Comment[el]=Εναλλαγή σε μία άλλη δραστηριότητα +Comment[en_GB]=Switch to another activity +Comment[eo]=Ŝalti al alia aktiveco +Comment[es]=Cambiar a otra actividad +Comment[et]=Lülitumine teisele tegevusele +Comment[eu]=Aldatu beste jarduera batera +Comment[fi]=Vaihda toiseen aktiviteettiin +Comment[fr]=Passe à une autre activité +Comment[fy]=Nei in oare aktiviteit wikselje +Comment[ga]=Roghnaigh gníomhaíocht eile +Comment[gl]=Troca de actividade +Comment[he]=משמש למעבר בין פעילות +Comment[hr]=Prebaci na drugu aktivnost +Comment[hu]=Váltás másik aktivitásra +Comment[ia]=Commuta a altere activitate +Comment[id]=Pindah ke aktivitas lain +Comment[is]=Skipta í aðra virkni +Comment[it]=Passa ad un'altra attività +Comment[ja]=他のアクティビティに切り替えます +Comment[kk]=Басқа белсенділігіне ауысу +Comment[km]=ប្ដូរ​ទៅ​សកម្មភាព​ផ្សេង +Comment[kn]=ಬೇರೊಂದು ಚಟುವಟಿಕೆಗೆ ಬದಲಾಯಿಸು +Comment[ko]=다른 활동으로 전환합니다 +Comment[lt]=Persijungti į kitą veiklą +Comment[lv]=Pārslēgties uz citu aktivitāti +Comment[mk]=Се префрла на друга активност +Comment[ml]=മറ്റൊരു പ്രക്രിയിലേയ്ക്കുള്ള മാറ്റം +Comment[mr]=वेगळ्या कार्यपध्दती वर जा +Comment[nb]=Bytt til en annen aktivitet +Comment[nds]=Na en anner Aktiviteet wesseln +Comment[nl]=Schakel naar een andere activiteit +Comment[nn]=Byt til ein annan aktivitet +Comment[pa]=ਹੋਰ ਐਕਟਵਿਟੀ ਲਈ ਬਦਲੋ +Comment[pl]=Przełącz do innego działania +Comment[pt]=Mudar para outra actividade +Comment[pt_BR]=Alterna para outra atividade +Comment[ro]=Comută la altă activitate +Comment[ru]=Переключение на другую комнату +Comment[si]=වෙනත් කාර්‍යයකට මාරුවන්න +Comment[sk]=Prepne na inú aktivitu +Comment[sl]=Preklapljanje med razpoložljivimi dejavnostmi +Comment[sr]=Пребацује на другу активност +Comment[sr@ijekavian]=Пребацује на другу активност +Comment[sr@ijekavianlatin]=Prebacuje na drugu aktivnost +Comment[sr@latin]=Prebacuje na drugu aktivnost +Comment[sv]=Byt till en annan aktivitet +Comment[tg]=Мубодила ба дигар амалиёт +Comment[th]=สลับไปยังกิจกรรมอื่น ๆ +Comment[tr]=Başka bir etkinliğe geç +Comment[ug]=باشقا بىر پائالىيەتكە ئالماشتۇر +Comment[uk]=Перемкнутися на інший простір дій +Comment[wa]=Potchî a ene ôte activité +Comment[x-test]=xxSwitch to another activityxx +Comment[zh_CN]=切换到另一个活动 +Comment[zh_TW]=切換到其它活動 + +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_switchactivity +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=switchactivity +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/containmentactions/switchactivity/switch.cpp b/plasma/generic/containmentactions/switchactivity/switch.cpp new file mode 100644 index 00000000..a97c5262 --- /dev/null +++ b/plasma/generic/containmentactions/switchactivity/switch.cpp @@ -0,0 +1,223 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "switch.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +Q_DECLARE_METATYPE(QWeakPointer) + +SwitchActivity::SwitchActivity(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), + m_menu(new KMenu()), + m_action(new QAction(this)) +{ + //This is an awful hack, but I need to keep the old behaviour for plasma-netbook + //while using the new activity API for plasma-desktop. + //TODO 4.6 convert netbook to the activity API so we won't need this + m_useNepomuk = (qApp->applicationName() == "plasma-desktop"); + + connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(switchTo(QAction*))); + + m_action->setMenu(m_menu); + m_menu->setTitle(i18n("Activities")); +} + +SwitchActivity::~SwitchActivity() +{ + delete m_menu; +} + +void SwitchActivity::contextEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + contextEvent(static_cast(event)); + break; + case QEvent::GraphicsSceneWheel: + wheelEvent(static_cast(event)); + break; + default: + break; + } +} + +void SwitchActivity::makeMenu() +{ + m_menu->clear(); + m_menu->addTitle(i18n("Activities")); + + if (m_useNepomuk) { + Plasma::DataEngine *engine = dataEngine("org.kde.activities"); + if (!engine->isValid()) { + return; + } + + Plasma::DataEngine::Data data = engine->query("Status"); + QStringList activities = data["Running"].toStringList(); + foreach (const QString& id, activities) { + Plasma::DataEngine::Data data = engine->query(id); + QAction *action = m_menu->addAction(KIcon(data["Icon"].toString()), data["Name"].toString()); + action->setData(QVariant(id)); + if (data["Current"].toBool()) { + action->setEnabled(false); + } + } + } else { + Plasma::Containment *myCtmt = containment(); + if (!myCtmt) { + return; + } + + Plasma::Corona *c = myCtmt->corona(); + if (!c) { + return; + } + + QList containments = c->containments(); + foreach (Plasma::Containment *ctmt, containments) { + if (ctmt->containmentType() == Plasma::Containment::PanelContainment || + ctmt->containmentType() == Plasma::Containment::CustomPanelContainment || + c->offscreenWidgets().contains(ctmt)) { + continue; + } + + QString name = ctmt->activity(); + if (name.isEmpty()) { + name = ctmt->name(); + } + QAction *action = m_menu->addAction(name); + action->setData(QVariant::fromValue >(QWeakPointer(ctmt))); + + //WARNING this assumes the plugin will only ever be set on activities, not panels! + if (ctmt == myCtmt) { + action->setEnabled(false); + } + } + } + + m_menu->adjustSize(); +} + +void SwitchActivity::contextEvent(QGraphicsSceneMouseEvent *event) +{ + makeMenu(); + m_menu->exec(popupPosition(m_menu->size(), event)); +} + +QList SwitchActivity::contextualActions() +{ + makeMenu(); + + QList list; + list << m_action; + return list; +} + +void SwitchActivity::switchTo(QAction *action) +{ + if (m_useNepomuk) { + QString id = action->data().toString(); + Plasma::Service *service = dataEngine("org.kde.activities")->serviceForSource(id); + KConfigGroup op = service->operationDescription("setCurrent"); + Plasma::ServiceJob *job = service->startOperationCall(op); + connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater())); + } else { + QWeakPointer ctmt = action->data().value >(); + if (!ctmt) { + return; + } + Plasma::Containment *myCtmt = containment(); + if (!myCtmt) { + return; + } + + ctmt.data()->setScreen(myCtmt->screen(), myCtmt->desktop()); + } +} + +void SwitchActivity::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + int step = (event->delta() < 0) ? 1 : -1; + + if (m_useNepomuk) { + Plasma::DataEngine *engine = dataEngine("org.kde.activities"); + if (!engine->isValid()) { + return; + } + + Plasma::DataEngine::Data data = engine->query("Status"); + QStringList list = data["Running"].toStringList(); + QString current = data["Current"].toString(); + int start = list.indexOf(current); + int next = (start + step + list.size()) % list.size(); + + Plasma::Service *service = engine->serviceForSource(list.at(next)); + KConfigGroup op = service->operationDescription("setCurrent"); + Plasma::ServiceJob *job = service->startOperationCall(op); + connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater())); + return; + } + + Plasma::Containment *myCtmt = containment(); + if (!myCtmt) { + return; + } + + Plasma::Corona *c = myCtmt->corona(); + if (!c) { + return; + } + + QList containments = c->containments(); + int start = containments.indexOf(myCtmt); + int i = (start + step + containments.size()) % containments.size(); + + //FIXME we *really* need a proper way to cycle through activities + while (i != start) { + Plasma::Containment *ctmt = containments.at(i); + if (ctmt->containmentType() == Plasma::Containment::PanelContainment || + ctmt->containmentType() == Plasma::Containment::CustomPanelContainment || + c->offscreenWidgets().contains(ctmt)) { + //keep looking + i = (i + step + containments.size()) % containments.size(); + } else { + break; + } + } + + Plasma::Containment *ctmt = containments.at(i); + if (ctmt && ctmt != myCtmt) { + ctmt->setScreen(myCtmt->screen(), myCtmt->desktop()); + } +} + + +#include "switch.moc" diff --git a/plasma/generic/containmentactions/switchactivity/switch.h b/plasma/generic/containmentactions/switchactivity/switch.h new file mode 100644 index 00000000..e3807283 --- /dev/null +++ b/plasma/generic/containmentactions/switchactivity/switch.h @@ -0,0 +1,52 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SWITCHACTIVITY_HEADER +#define SWITCHACTIVITY_HEADER + +#include + +class QAction; +class KMenu; + +class SwitchActivity : public Plasma::ContainmentActions +{ + Q_OBJECT + public: + SwitchActivity(QObject* parent, const QVariantList& args); + ~SwitchActivity(); + + void contextEvent(QEvent *event); + void contextEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); + QList contextualActions(); + + private slots: + void switchTo(QAction *action); + void makeMenu(); + + private: + KMenu *m_menu; + QAction *m_action; + bool m_useNepomuk; +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(switchactivity, SwitchActivity) + +#endif diff --git a/plasma/generic/containmentactions/switchdesktop/CMakeLists.txt b/plasma/generic/containmentactions/switchdesktop/CMakeLists.txt new file mode 100644 index 00000000..c6f30da6 --- /dev/null +++ b/plasma/generic/containmentactions/switchdesktop/CMakeLists.txt @@ -0,0 +1,11 @@ +project(plasma-containmentactions-switchdesktop) + +set(switchdesktop_SRCS + desktop.cpp +) + +kde4_add_plugin(plasma_containmentactions_switchdesktop ${switchdesktop_SRCS}) +target_link_libraries(plasma_containmentactions_switchdesktop ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containmentactions_switchdesktop DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-switchdesktop.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/switchdesktop/Messages.sh b/plasma/generic/containmentactions/switchdesktop/Messages.sh new file mode 100755 index 00000000..de79ab5e --- /dev/null +++ b/plasma/generic/containmentactions/switchdesktop/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_containmentactions_switchdesktop.pot diff --git a/plasma/generic/containmentactions/switchdesktop/desktop.cpp b/plasma/generic/containmentactions/switchdesktop/desktop.cpp new file mode 100644 index 00000000..6844985b --- /dev/null +++ b/plasma/generic/containmentactions/switchdesktop/desktop.cpp @@ -0,0 +1,112 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "desktop.h" + +#include +#include + +#include +#include +#include + +SwitchDesktop::SwitchDesktop(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), + m_menu(new KMenu()), + m_action(new QAction(this)) +{ + m_menu->setTitle(i18n("Virtual Desktops")); + connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(switchTo(QAction*))); + + m_action->setMenu(m_menu); +} + +SwitchDesktop::~SwitchDesktop() +{ + delete m_menu; +} + +void SwitchDesktop::contextEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + contextEvent(static_cast(event)); + break; + case QEvent::GraphicsSceneWheel: + wheelEvent(static_cast(event)); + break; + default: + break; + } +} + +void SwitchDesktop::makeMenu() +{ + m_menu->clear(); + m_menu->addTitle(i18n("Virtual Desktops")); + const int numDesktops = KWindowSystem::numberOfDesktops(); + const int currentDesktop = KWindowSystem::currentDesktop(); + + for (int i = 1; i <= numDesktops; ++i) { + QString name = KWindowSystem::desktopName(i); + QAction *action = m_menu->addAction(QString("%1: %2").arg(i).arg(name)); + action->setData(i); + if (i == currentDesktop) { + action->setEnabled(false); + } + } + + m_menu->adjustSize(); +} + +void SwitchDesktop::contextEvent(QGraphicsSceneMouseEvent *event) +{ + makeMenu(); + m_menu->exec(popupPosition(m_menu->size(), event)); +} + +QList SwitchDesktop::contextualActions() +{ + makeMenu(); + QList list; + list << m_action; + return list; +} + +void SwitchDesktop::switchTo(QAction *action) +{ + const int desktop = action->data().toInt(); + KWindowSystem::setCurrentDesktop(desktop); +} + +void SwitchDesktop::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + kDebug() << event->orientation() << event->delta(); + const int numDesktops = KWindowSystem::numberOfDesktops(); + const int currentDesktop = KWindowSystem::currentDesktop(); + + if (event->delta() < 0) { + KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1); + } else { + KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1); + } +} + + +#include "desktop.moc" diff --git a/plasma/generic/containmentactions/switchdesktop/desktop.h b/plasma/generic/containmentactions/switchdesktop/desktop.h new file mode 100644 index 00000000..8834da8a --- /dev/null +++ b/plasma/generic/containmentactions/switchdesktop/desktop.h @@ -0,0 +1,53 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SWITCHDESKTOP_HEADER +#define SWITCHDESKTOP_HEADER + +#include + +class QAction; +class KMenu; + +class SwitchDesktop : public Plasma::ContainmentActions +{ + Q_OBJECT + public: + SwitchDesktop(QObject* parent, const QVariantList& args); + ~SwitchDesktop(); + + void contextEvent(QEvent *event); + void contextEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); + QList contextualActions(); + + private: + void makeMenu(); + + private slots: + void switchTo(QAction *action); + + private: + KMenu *m_menu; + QAction *m_action; +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(switchdesktop, SwitchDesktop) + +#endif diff --git a/plasma/generic/containmentactions/switchdesktop/plasma-containmentactions-switchdesktop.desktop b/plasma/generic/containmentactions/switchdesktop/plasma-containmentactions-switchdesktop.desktop new file mode 100644 index 00000000..13583c0c --- /dev/null +++ b/plasma/generic/containmentactions/switchdesktop/plasma-containmentactions-switchdesktop.desktop @@ -0,0 +1,150 @@ +[Desktop Entry] +Name=Switch Desktop +Name[ar]=بدّل سطح المكتب +Name[ast]=Camudar escritoriu +Name[bg]=Превключване на работен плот +Name[bn]=অন্য ডেস্কটপ +Name[bs]=prebacivanje površi +Name[ca]=Canvi d'escriptori +Name[ca@valencia]=Canvi d'escriptori +Name[cs]=Přepnout plochu +Name[da]=Skift skrivebord +Name[de]=Arbeitsfläche wechseln +Name[el]=Εναλλαγή Επιφάνειας εργασίας +Name[en_GB]=Switch Desktop +Name[eo]=Ŝalti Labortablon +Name[es]=Cambiar escritorio +Name[et]=Töölaua vahetamine +Name[eu]=Aldatu mahaigainez +Name[fi]=Vaihda työpöytää +Name[fr]=Changer de bureau +Name[fy]=Buroblêd wikselje +Name[ga]=Athraigh an Deasc +Name[gl]=Trocar de escritorio +Name[gu]=ડેસ્કટોપ બદલો +Name[he]=מחליף שולחנות עבודה +Name[hi]=डेस्कटॉप बदलें +Name[hr]=Prebaci radnu površinu +Name[hu]=Asztalváltás +Name[ia]=Commuta scriptorio +Name[id]=Pindah Desktop +Name[is]=Skipta um skjáborð +Name[it]=Cambia desktop +Name[ja]=デスクトップを切り替え +Name[kk]=Жұмыс үстелді ауыстыру +Name[km]=ប្ដូរ​ផ្ទៃតុ +Name[kn]=ಗಣಕತೆರೆಯನ್ನು ಬದಲಾಯಿಸು +Name[ko]=데스크톱 전환 +Name[lt]=Pakeisti darbastalį +Name[lv]=Pārslēgt darbvirsmu +Name[mk]=Смени раб. површина +Name[ml]=പണിയിടം മാറുക +Name[mr]=वेगळ्या डेस्कटॉप वर जा +Name[nb]=Bytt skrivebord +Name[nds]=Schriefdisch wesseln +Name[nl]=Bureaublad omschakelen +Name[nn]=Byt skrivebord +Name[pa]=ਡੈਸਕਟਾਪ ਬਦਲੋ +Name[pl]=Przełącz pulpit +Name[pt]=Mudar de Ecrã +Name[pt_BR]=Alternar área de trabalho +Name[ro]=Comutare birou +Name[ru]=Переключение рабочих столов +Name[si]=වැඩතලය මාරුකරන්න +Name[sk]=Prepnúť plochu +Name[sl]=Preklapljanje med namizji +Name[sr]=пребацивање површи +Name[sr@ijekavian]=пребацивање површи +Name[sr@ijekavianlatin]=prebacivanje površi +Name[sr@latin]=prebacivanje površi +Name[sv]=Byt skrivbord +Name[tg]=Мубодилаи мизи корӣ +Name[th]=สลับพื้นที่ทำงาน +Name[tr]=Masaüstünü Değiştir +Name[ug]=ئۈستەلئۈستى ئالماشتۇر +Name[uk]=Перемкнути стільницю +Name[wa]=Potchî a èn ôte sicribanne +Name[x-test]=xxSwitch Desktopxx +Name[zh_CN]=切换桌面 +Name[zh_TW]=切換桌面 +Type=Service +Icon=user-desktop +Comment=Switch to another virtual desktop +Comment[ar]=بدّل إلى سطح مكتب افتراضي آخر +Comment[ast]=Camudar a otru escritoriu virtual +Comment[bg]=Превключване към друг работен плот +Comment[bs]=Prebacuje na drugu virtuelnu površ +Comment[ca]=Canvia a un altre escriptori virtual +Comment[ca@valencia]=Canvia a un altre escriptori virtual +Comment[cs]=Přepnout na jinou virtuální plochu +Comment[da]=Skift til et andet virtuelt skrivebord +Comment[de]=Ermöglicht Ihnen, zu einer anderen virtuellen Arbeitsfläche zu wechseln. +Comment[el]=Εναλλαγή σε μία άλλη εικονική επιφάνειας εργασίας +Comment[en_GB]=Switch to another virtual desktop +Comment[eo]=Ŝalti al alia virtuala labortablo +Comment[es]=Cambiar a otro escritorio virtual +Comment[et]=Lülitumine teisele virtuaalsele töölauale +Comment[eu]=Aldatu beste alegiazko mahaigain batera +Comment[fi]=Vaihda toiseen virtuaalityöpöytään +Comment[fr]=Passe à un autre bureau virtuel +Comment[fy]=Nei in oare firuele buroblêd wikselje +Comment[ga]=Athraigh an deasc fhíorúil +Comment[gl]=Troca para outro escritorio virtual +Comment[he]=משמש למעבר לשולחן עבודה וירטואלי אחר +Comment[hi]=दूसरे आभासी डेस्कटॉप्स पर स्विच करें +Comment[hr]=Prebaci na drugu virtualnu radnu površinu +Comment[hu]=Váltás másik virtuális asztalra +Comment[ia]=Commuta a altere scriptorio virtual +Comment[id]=Berpindah ke desktop virtual lain +Comment[is]=Skiptir milli sýndarskjáborða +Comment[it]=Passa ad un altro desktop virtuale +Comment[ja]=他の仮想デスクトップに切り替えます +Comment[kk]=Басқа виртуалды үстелге ауысу +Comment[km]=ប្ដូរ​ទៅ​ផ្ទៃតុ​និម្មិត​ផ្សេង​ទៀត +Comment[kn]=ಮತ್ತೊಂದು ವಾಸ್ತವಪ್ರಾಯ ಗಣಕತೆರೆಗೆ ಬದಲಾಯಿಸು +Comment[ko]=다른 가상 데스크톱으로 전환합니다 +Comment[lt]=Pereiti į kitą virtualų darbastalį +Comment[lv]=Pārslēgties uz citu virtuālo darbvirsmu +Comment[mk]=Менување на друга виртуелна раб. површина +Comment[ml]=മറ്റൊരു മായാ പണിയിടത്തിലേയ്ക്കു് മാറുക +Comment[mr]=वेगळ्या आभासी डेस्कटॉप वर जा +Comment[nb]=Bytt til et annet virtuelt skrivebord +Comment[nds]=Na en anner Schriefdischen wesseln +Comment[nl]=Schakel naar een andere virtueel bureaublad +Comment[nn]=Byt til eit anna virtuelt skrivebord +Comment[pa]=ਵੁਰਚੁਅਲ ਡੈਸਕਟਾਪਾਂ ਵਿੱਚ ਸਵਿੱਚ ਕਰੋ +Comment[pl]=Przełączenie między wirtualnymi pulpitami +Comment[pt]=Mudar para outro ecrã virtual +Comment[pt_BR]=Alterna para outra área de trabalho +Comment[ro]=Comută la alt birou virtual +Comment[ru]=Переключение на другой рабочий стол +Comment[si]=වෙනත් අතත්‍ය වැඩතලයක් වෙත මාරුවන්න +Comment[sk]=Prepne na inú virtuálnu plochu +Comment[sl]=Preklapljanje med navideznimi namizji +Comment[sr]=Пребацује на другу виртуелну површ +Comment[sr@ijekavian]=Пребацује на другу виртуелну површ +Comment[sr@ijekavianlatin]=Prebacuje na drugu virtuelnu površ +Comment[sr@latin]=Prebacuje na drugu virtuelnu površ +Comment[sv]=Byt till ett annat virtuellt skrivbord +Comment[tg]=Мубодилаи мизи кориҳои виртуалӣ +Comment[th]=สลับไปยังพื้นที่ทำงานเสมือนตัวอื่น ๆ +Comment[tr]=Başka bir sanal masaüstüne geç +Comment[ug]=باشقا بىر مەۋھۇم ئۈستەلئۈستىگە ئالماشتۇر +Comment[uk]=Перемкнутися на іншу віртуальну стільницю +Comment[wa]=Potchî a èn ôte forveyou scribanne +Comment[x-test]=xxSwitch to another virtual desktopxx +Comment[zh_CN]=切换到另一个虚拟桌面 +Comment[zh_TW]=切換到其它虛擬桌面 + +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_switchdesktop +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=switchdesktop +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/containmentactions/switchwindow/CMakeLists.txt b/plasma/generic/containmentactions/switchwindow/CMakeLists.txt new file mode 100644 index 00000000..1e9f2bfe --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/CMakeLists.txt @@ -0,0 +1,12 @@ +project(plasma-containmentactions-switchwindow) + +set(switchwindow_SRCS + switch.cpp +) +kde4_add_ui_files(switchwindow_SRCS config.ui) + +kde4_add_plugin(plasma_containmentactions_switchwindow ${switchwindow_SRCS}) +target_link_libraries(plasma_containmentactions_switchwindow ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containmentactions_switchwindow DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containmentactions-switchwindow.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/containmentactions/switchwindow/Messages.sh b/plasma/generic/containmentactions/switchwindow/Messages.sh new file mode 100755 index 00000000..7f28e587 --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_containmentactions_switchwindow.pot diff --git a/plasma/generic/containmentactions/switchwindow/config.ui b/plasma/generic/containmentactions/switchwindow/config.ui new file mode 100644 index 00000000..a3b6b120 --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/config.ui @@ -0,0 +1,38 @@ + + Config + + + + 0 + 0 + 388 + 108 + + + + + + + Display all windows in one list + + + + + + + Display a submenu for each desktop + + + + + + + Display only the current desktop's windows + + + + + + + + diff --git a/plasma/generic/containmentactions/switchwindow/plasma-containmentactions-switchwindow.desktop b/plasma/generic/containmentactions/switchwindow/plasma-containmentactions-switchwindow.desktop new file mode 100644 index 00000000..52e913a8 --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/plasma-containmentactions-switchwindow.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Switch Window +Name[ar]=بدّل النافذة +Name[ast]=Camudar ventana +Name[bg]=Превключване на прозорци +Name[bs]=prebacivanje prozora +Name[ca]=Canvi de finestra +Name[ca@valencia]=Canvi de finestra +Name[cs]=Přepnout okna +Name[da]=Skift vindue +Name[de]=Fenster wechseln +Name[el]=Εναλλαγή παραθύρου +Name[en_GB]=Switch Window +Name[eo]=Ŝalti fenestron +Name[es]=Cambiar ventana +Name[et]=Akna vahetamine +Name[eu]=Aldatu leihoz +Name[fi]=Vaihda ikkunaa +Name[fr]=Changer de fenêtre +Name[fy]=Finster wikselje +Name[ga]=Athraigh an Fhuinneog +Name[gl]=Tocar de xanela +Name[he]=מחליף חלונות +Name[hi]=विंडो बदलें +Name[hr]=Prebaci prozor +Name[hu]=Ablakváltás +Name[ia]=Commuta fenestra +Name[id]=Pindah Jendela +Name[is]=Skipta um glugga +Name[it]=Cambia finestra +Name[ja]=ウィンドウを切り替え +Name[kk]=Терезені ауыстыру +Name[km]=ប្ដូរ​បង្អួច +Name[kn]=ಕಿಟಿಕಿಯನ್ನು ಬದಲಾಯಿಸು +Name[ko]=창 전환 +Name[lt]=Pakeisti langą +Name[lv]=Pārslēgt logu +Name[mk]=Смени прозорец +Name[ml]=ജാലകം മാറുക +Name[mr]=वेगळ्या चौकट वर जा +Name[nb]=Bytt vindu +Name[nds]=Finster wesseln +Name[nl]=Venster omschakelen +Name[nn]=Byt vindauge +Name[pa]=ਵਿੰਡੋ ਬਦਲੋ +Name[pl]=Przełącz okno +Name[pt]=Mudar de Janela +Name[pt_BR]=Alternar janela +Name[ro]=Comutare fereastră +Name[ru]=Переключение окон +Name[si]=කවුළුව මාරුකරන්න +Name[sk]=Prepnúť okno +Name[sl]=Preklapljanje med okni +Name[sr]=пребацивање прозора +Name[sr@ijekavian]=пребацивање прозора +Name[sr@ijekavianlatin]=prebacivanje prozora +Name[sr@latin]=prebacivanje prozora +Name[sv]=Byt fönster +Name[tg]=Мубодилаи тирезаҳо +Name[th]=สลับหน้าต่าง +Name[tr]=Pencereyi Değiştir +Name[ug]=كۆزنەك ئالماشتۇر +Name[uk]=Перемкнути вікно +Name[wa]=Passer a ene ôte finiesse +Name[x-test]=xxSwitch Windowxx +Name[zh_CN]=切换窗口 +Name[zh_TW]=切換視窗 +Type=Service +Icon=preferences-system-windows +Comment=Show a list of windows to switch to +Comment[ar]=أظهر لائحة بالنوافذ للانتقال لإحداها +Comment[ast]=Amosar una llista de ventanes a les que camudar +Comment[bg]=Списък с прозорци за превключване +Comment[bs]=Pokazuje spisak prozora za prebacivanje +Comment[ca]=Mostra una llista de les finestres per a canviar +Comment[ca@valencia]=Mostra una llista de les finestres per a canviar +Comment[cs]=Zobrazit seznam oken k přepnutí +Comment[da]=Vis en liste over åbne vinduer at skifte til +Comment[de]=Eine Liste aller Fenster anzeigen +Comment[el]=Εμφάνιση λίστας παραθύρων για εναλλαγή +Comment[en_GB]=Show a list of windows to switch to +Comment[eo]=Montri liston de festestro por komuti +Comment[es]=Mostrar una lista de ventanas a las que cambiar +Comment[et]=Võimalike akende loendi näitamine +Comment[eu]=Erakutsi hauta ditzakezun leihoen zerrenda bat +Comment[fi]=Näytä luettelo ikkunoista, joihin voi vaihtaa +Comment[fr]=Affiche une liste de fenêtres pouvant être activées +Comment[fy]=Lit in list sjen mei finsters om nei ta te wikseljen +Comment[gl]=Mostrar unha lista de xanelas ás que pode ir +Comment[he]=משמש להצגת רשימת חלונות שניתן לעבור אליהם +Comment[hr]=Prikaži listu prozora na koju se moguće prebaciti +Comment[hu]=Ablakok listájának megjelenítése váltáshoz +Comment[ia]=Monstra un lista de fenestras ubi commutar +Comment[id]=Tampilkan senarai jendela yang akan dipindahkan +Comment[is]=Sýna lista yfir glugga sem hægt er að skipta yfir í +Comment[it]=Mostra un elenco di finestre a cui passare +Comment[ja]=他のウィンドウに切り替えるためにウィンドウのリストを表示します +Comment[kk]=Ауысатын терезелер тізімін ұсыну +Comment[km]=បង្ហាញ​បញ្ជី​បង្អួច​ដើម្បី​ផ្លាស់ប្ដូរ +Comment[kn]=ವಿಂಡೊವನ್ನು ಬದಲಾಯಿಸಲು ವಿಂಡೊಗಳ ಒಂದು ಪಟ್ಟಿಯನ್ನು ತೋರಿಸು +Comment[ko]=전환할 수 있는 창 목록을 표시합니다 +Comment[lt]=Rodo langų, į kuriuos galima rodyti, sąrašą +Comment[lv]=Pārādīt logu sarakstu uz ko pārslēgties +Comment[mk]=Прикажува листа на прозорци во кои може да се префрлите +Comment[ml]=മാറാവുന്ന ജാലകങ്ങളടെ പട്ടിക കാണിയ്ക്കുക +Comment[mr]=वेगळ्या चौकट वर जाण्यासाठी यादी दर्शवा +Comment[nb]=Vis en liste over vinduer som kan byttes til +Comment[nds]=Finstern oplisten un dor henwesseln +Comment[nl]=Toon een lijst met vensters waarnaar om te schakelen +Comment[nn]=Vis ei oversikt over vindauge å byta til +Comment[pa]=ਬਦਲਣ ਲਈ ਵਿੰਡੋਜ਼ ਦੀ ਲਿਸਟ ਵੇਖੋ +Comment[pl]=Pokazanie listy okien, na które można się przełączyć +Comment[pt]=Mostrar uma lista com as janelas para onde mudar +Comment[pt_BR]=Exibe uma lista de janelas para alternar +Comment[ro]=Arată o listă de ferestre de comutat +Comment[ru]=Показать список окон +Comment[si]=මාරුවීම සඳහා කවුළු ලැයිස්තුව පෙන්වන්න +Comment[sk]=Zobrazenie zoznamu okien na prepnutie +Comment[sl]=Prikaže seznam oken na katere je mogoče preklopiti +Comment[sr]=Показује списак прозора за пребацивање +Comment[sr@ijekavian]=Показује списак прозора за пребацивање +Comment[sr@ijekavianlatin]=Pokazuje spisak prozora za prebacivanje +Comment[sr@latin]=Pokazuje spisak prozora za prebacivanje +Comment[sv]=Visa en lista med fönster att byta till +Comment[th]=แสดงรายการของหน้าต่างที่สามารถจะสลับไปใช้ได้ +Comment[tr]=Değiştirilecek pencereler listesini göster +Comment[ug]=كۆزنەك ئالماشتۇرۇشقا ئىشلىتىدىغان تىزىمنى كۆرسىتىدۇ +Comment[uk]=Показує список вікон для перемикання +Comment[wa]=Mostrer ene djivêye des fniesse k' on sait potchî dvins +Comment[x-test]=xxShow a list of windows to switch toxx +Comment[zh_CN]=显示可供切换的窗口列表 +Comment[zh_TW]=列出視窗並切換 + +ServiceTypes=Plasma/ContainmentActions + +X-KDE-Library=plasma_containmentactions_switchwindow +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=switchwindow +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-HasConfigurationInterface=true + diff --git a/plasma/generic/containmentactions/switchwindow/switch.cpp b/plasma/generic/containmentactions/switchwindow/switch.cpp new file mode 100644 index 00000000..593b91c6 --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/switch.cpp @@ -0,0 +1,264 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "switch.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include + +SwitchWindow::SwitchWindow(QObject *parent, const QVariantList &args) + : Plasma::ContainmentActions(parent, args), + m_menu(new KMenu()), + m_action(new QAction(this)), + m_mode(AllFlat), + m_clearOrderTimer(0) +{ + m_menu->setTitle(i18n("Windows")); + connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(switchTo(QAction*))); + + m_action->setMenu(m_menu); +} + +SwitchWindow::~SwitchWindow() +{ + delete m_menu; +} + +void SwitchWindow::init(const KConfigGroup &config) +{ + m_mode = (MenuMode)config.readEntry("mode", (int)AllFlat); +} + +QWidget* SwitchWindow::createConfigurationInterface(QWidget* parent) +{ + QWidget *widget = new QWidget(parent); + m_ui.setupUi(widget); + widget->setWindowTitle(i18n("Configure Switch Window Plugin")); + switch (m_mode) { + case AllFlat: + m_ui.flatButton->setChecked(true); + break; + case DesktopSubmenus: + m_ui.subButton->setChecked(true); + break; + case CurrentDesktop: + m_ui.curButton->setChecked(true); + break; + } + return widget; +} + +void SwitchWindow::configurationAccepted() +{ + if (m_ui.flatButton->isChecked()) { + m_mode = AllFlat; + } else if (m_ui.subButton->isChecked()) { + m_mode = DesktopSubmenus; + } else { + m_mode = CurrentDesktop; + } +} + +void SwitchWindow::save(KConfigGroup &config) +{ + config.writeEntry("mode", (int)m_mode); +} + +void SwitchWindow::contextEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + contextEvent(static_cast(event)); + break; + case QEvent::GraphicsSceneWheel: + wheelEvent(static_cast(event)); + break; + default: + break; + } +} + +void SwitchWindow::makeMenu() +{ + m_menu->clear(); + Plasma::DataEngine *tasks = dataEngine("tasks"); + if (!tasks->isValid()) { + return; + } + + QMultiHash desktops; + + //make all the window actions + foreach (const QString &source, tasks->sources()) { + Plasma::DataEngine::Data window = tasks->query(source); + if (window.value("startup").toBool()) { + //kDebug() << "skipped fake task" << source; + continue; + } + if (!window.value("onCurrentActivity").toBool()) { + continue; + } + + QString name = window.value("visibleNameWithState").toString(); + if (name.isEmpty()) { + kDebug() << "failed source" << source; + continue; + } + + QAction *action = new QAction(name, m_menu); + action->setIcon(window.value("icon").value()); + action->setData(source); + desktops.insert(window.value("desktop").toInt(), action); + } + + //sort into menu + if (m_mode == CurrentDesktop) { + int currentDesktop = KWindowSystem::currentDesktop(); + m_menu->addTitle(i18n("Windows")); + m_menu->addActions(desktops.values(currentDesktop)); + m_menu->addActions(desktops.values(-1)); + } else { + int numDesktops = KWindowSystem::numberOfDesktops(); + if (m_mode == AllFlat) { + for (int i = 1; i <= numDesktops; ++i) { + if (desktops.contains(i)) { + QString name = KWindowSystem::desktopName(i); + name = QString("%1: %2").arg(i).arg(name); + m_menu->addTitle(name); + m_menu->addActions(desktops.values(i)); + } + } + if (desktops.contains(-1)) { + m_menu->addTitle(i18n("All Desktops")); + m_menu->addActions(desktops.values(-1)); + } + } else { //submenus + for (int i = 1; i <= numDesktops; ++i) { + if (desktops.contains(i)) { + QString name = KWindowSystem::desktopName(i); + name = QString("%1: %2").arg(i).arg(name); + KMenu *subMenu = new KMenu(name, m_menu); + subMenu->addActions(desktops.values(i)); + m_menu->addMenu(subMenu); + } + } + if (desktops.contains(-1)) { + KMenu *subMenu = new KMenu(i18n("All Desktops"), m_menu); + subMenu->addActions(desktops.values(-1)); + m_menu->addMenu(subMenu); + } + } + } + + m_menu->adjustSize(); +} + +void SwitchWindow::contextEvent(QGraphicsSceneMouseEvent *event) +{ + makeMenu(); + if (!m_menu->isEmpty()) { + m_menu->exec(popupPosition(m_menu->size(), event)); + } +} + +QList SwitchWindow::contextualActions() +{ + makeMenu(); + QList list; + list << m_action; + return list; +} + +void SwitchWindow::switchTo(QAction *action) +{ + QString source = action->data().toString(); + kDebug() << source; + Plasma::Service *service = dataEngine("tasks")->serviceForSource(source); + if (service) { + service->startOperationCall(service->operationDescription("activateRaiseOrIconify")); + } +} + +void SwitchWindow::clearWindowsOrder() +{ + kDebug() << "CLEARING>......................."; + m_windowsOrder.clear(); +} + +void SwitchWindow::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + //TODO somehow find the "next" or "previous" window + //without changing hte window order (don't want to always go between two windows) + if (m_windowsOrder.isEmpty()) { + m_windowsOrder = KWindowSystem::stackingOrder(); + } else { + if (!m_clearOrderTimer) { + m_clearOrderTimer = new QTimer(this); + connect(m_clearOrderTimer, SIGNAL(timeout()), this, SLOT(clearWindowsOrder())); + m_clearOrderTimer->setSingleShot(true); + m_clearOrderTimer->setInterval(1000); + } + + m_clearOrderTimer->start(); + } + + const WId activeWindow = KWindowSystem::activeWindow(); + const bool up = event->delta() > 0; + bool next = false; + WId first = 0; + WId last = 0; + for (int i = 0; i < m_windowsOrder.count(); ++i) { + const WId id = m_windowsOrder.at(i); + const KWindowInfo info(id, NET::WMDesktop | NET::WMVisibleName | NET::WMWindowType); + if (info.windowType(NET::NormalMask | NET::DialogMask | NET::UtilityMask) != -1 && info.isOnCurrentDesktop()) { + if (next) { + KWindowSystem::forceActiveWindow(id); + return; + } + + if (first == 0) { + first = id; + } + + if (id == activeWindow) { + if (up) { + next = true; + } else if (last) { + KWindowSystem::forceActiveWindow(last); + return; + } + } + + last = id; + } + } + + KWindowSystem::forceActiveWindow(up ? first : last); +} + + +#include "switch.moc" diff --git a/plasma/generic/containmentactions/switchwindow/switch.h b/plasma/generic/containmentactions/switchwindow/switch.h new file mode 100644 index 00000000..fee0334f --- /dev/null +++ b/plasma/generic/containmentactions/switchwindow/switch.h @@ -0,0 +1,71 @@ +/* + * Copyright 2009 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SWITCHWINDOW_HEADER +#define SWITCHWINDOW_HEADER + +#include "ui_config.h" +#include + +class QAction; +class QTimer; +class KMenu; + +class SwitchWindow : public Plasma::ContainmentActions +{ + Q_OBJECT + public: + SwitchWindow(QObject* parent, const QVariantList& args); + ~SwitchWindow(); + + void init(const KConfigGroup &config); + QWidget* createConfigurationInterface(QWidget* parent); + void configurationAccepted(); + void save(KConfigGroup &config); + + void contextEvent(QEvent *event); + void contextEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); + QList contextualActions(); + + private: + void makeMenu(); + + private slots: + void clearWindowsOrder(); + void switchTo(QAction *action); + + private: + enum MenuMode { + AllFlat = 0, + DesktopSubmenus, + CurrentDesktop + }; + + KMenu *m_menu; + QAction *m_action; + Ui::Config m_ui; + MenuMode m_mode; + QTimer *m_clearOrderTimer; + QList m_windowsOrder; +}; + +K_EXPORT_PLASMA_CONTAINMENTACTIONS(switchwindow, SwitchWindow) + +#endif diff --git a/plasma/generic/dataengines/CMakeLists.txt b/plasma/generic/dataengines/CMakeLists.txt new file mode 100644 index 00000000..d240683d --- /dev/null +++ b/plasma/generic/dataengines/CMakeLists.txt @@ -0,0 +1,44 @@ +add_subdirectory(applicationjobs) +add_subdirectory(activities) +add_subdirectory(apps) +add_subdirectory(devicenotifications) +add_subdirectory(dict) +add_subdirectory(executable) +add_subdirectory(favicons) +add_subdirectory(filebrowser) +add_subdirectory(geolocation) +add_subdirectory(hotplug) +add_subdirectory(keystate) +add_subdirectory(mpris2) +#add_subdirectory(network) +add_subdirectory(notifications) +# KDE5: remove the nowplaying engine +add_subdirectory(nowplaying) +add_subdirectory(places) +add_subdirectory(powermanagement) +add_subdirectory(soliddevice) +add_subdirectory(time) +add_subdirectory(weather) +add_subdirectory(statusnotifieritem) +add_subdirectory(share) + +if (NepomukCore_FOUND AND Soprano_FOUND) + add_subdirectory(metadata) +endif () + +if(Boost_FOUND AND KdepimLibs_FOUND) + if(Akonadi_FOUND) + add_subdirectory(akonadi) + endif(Akonadi_FOUND) + add_subdirectory(calendar) + add_subdirectory(rss) +endif(Boost_FOUND AND KdepimLibs_FOUND) + +if(NOT WIN32) + add_subdirectory(mouse) + add_subdirectory(systemmonitor) + if(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") + add_subdirectory(tasks) + endif(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop") +endif(NOT WIN32) + diff --git a/plasma/generic/dataengines/Mainpage.dox b/plasma/generic/dataengines/Mainpage.dox new file mode 100644 index 00000000..52dcca06 --- /dev/null +++ b/plasma/generic/dataengines/Mainpage.dox @@ -0,0 +1,10 @@ +/** +* @mainpage Engines +* +* Plasma engines power widgets. +* +*/ + +// DOXYGEN_SET_PROJECT_NAME = Engines +// DOXYGEN_SET_RECURSIVE = YES +// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/plasma/generic/dataengines/activities/ActivityData.cpp b/plasma/generic/dataengines/activities/ActivityData.cpp new file mode 100644 index 00000000..d98e8c1e --- /dev/null +++ b/plasma/generic/dataengines/activities/ActivityData.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 Ivan Cukic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * or (at your option) any later version, as published by the Free + * Software Foundation + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ActivityData.h" + +#include +#include + +class ActivityDataStaticInit { +public: + ActivityDataStaticInit() + { + qDBusRegisterMetaType < ActivityData > (); + qDBusRegisterMetaType < QList < ActivityData > > (); + } + + static ActivityDataStaticInit _instance; + +}; + +ActivityDataStaticInit ActivityDataStaticInit::_instance; + +ActivityData::ActivityData() +{ +} + +ActivityData::ActivityData(const ActivityData & source) +{ + score = source.score; + id = source.id; +} + +ActivityData & ActivityData::operator = (const ActivityData & source) +{ + if (&source != this) { + score = source.score; + id = source.id; + } + + return *this; +} + +QDBusArgument & operator << (QDBusArgument & arg, const ActivityData r) +{ + arg.beginStructure(); + + arg << r.id; + arg << r.score; + + arg.endStructure(); + + return arg; +} + +const QDBusArgument & operator >> (const QDBusArgument & arg, ActivityData & r) +{ + arg.beginStructure(); + + arg >> r.id; + arg >> r.score; + + arg.endStructure(); + + return arg; +} + +QDebug operator << (QDebug dbg, const ActivityData & r) +{ + dbg << "ActivityData(" << r.score << r.id << ")"; + return dbg.space(); +} diff --git a/plasma/generic/dataengines/activities/ActivityData.h b/plasma/generic/dataengines/activities/ActivityData.h new file mode 100644 index 00000000..a36e85a2 --- /dev/null +++ b/plasma/generic/dataengines/activities/ActivityData.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 Ivan Cukic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * or (at your option) any later version, as published by the Free + * Software Foundation + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIVITY_DATA_H_ +#define ACTIVITY_DATA_H_ + +#include +#include +#include +#include + +class ActivityData { +public: + ActivityData(); + ActivityData(const ActivityData & source); + ActivityData & operator = (const ActivityData & source); + + double score; + QString id; + +}; + +typedef QList ActivityDataList; +Q_DECLARE_METATYPE(ActivityData) +Q_DECLARE_METATYPE(ActivityDataList) + +QDBusArgument & operator << (QDBusArgument & arg, const ActivityData); +const QDBusArgument & operator >> (const QDBusArgument & arg, ActivityData & rec); + +QDebug operator << (QDebug dbg, const ActivityData & r); + +#endif // ACTIVITY_DATA_H_ diff --git a/plasma/generic/dataengines/activities/CMakeLists.txt b/plasma/generic/dataengines/activities/CMakeLists.txt new file mode 100644 index 00000000..068d07a1 --- /dev/null +++ b/plasma/generic/dataengines/activities/CMakeLists.txt @@ -0,0 +1,28 @@ +project(activityengine) + +set(activity_engine_SRCS + ActivityData.cpp + activityengine.cpp + activityservice.cpp + activityjob.cpp) + +set_source_files_properties(org.kde.ActivityManager.ActivityRanking.xml PROPERTIES INCLUDE "ActivityData.h") +qt4_add_dbus_interface( + activity_engine_SRCS org.kde.ActivityManager.ActivityRanking.xml + ActivityRankingInterface + ) + +kde4_add_plugin(plasma_engine_activities ${activity_engine_SRCS}) +target_link_libraries(plasma_engine_activities + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + ${KACTIVITIES_LIBRARY}) + +install(TARGETS plasma_engine_activities + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-engine-activities.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES activities.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/plasma/generic/dataengines/activities/activities.operations b/plasma/generic/dataengines/activities/activities.operations new file mode 100644 index 00000000..c438c506 --- /dev/null +++ b/plasma/generic/dataengines/activities/activities.operations @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/activities/activityengine.cpp b/plasma/generic/dataengines/activities/activityengine.cpp new file mode 100644 index 00000000..2774a01c --- /dev/null +++ b/plasma/generic/dataengines/activities/activityengine.cpp @@ -0,0 +1,270 @@ +/* + * Copyright 2010 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "activityengine.h" +#include "activityservice.h" +#include "ActivityRankingInterface.h" + +#include +#include + +#include +#include + +#define ACTIVITYMANAGER_SERVICE "org.kde.kactivitymanagerd" +#define ACTIVITYRANKING_OBJECT "/ActivityRanking" + +ActivityEngine::ActivityEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args); +} + +void ActivityEngine::init() +{ + if (qApp->applicationName() == "plasma-netbook") { + //hack for the netbook + //FIXME can I read a setting or something instead? + } else { + m_activityController = new KActivities::Controller(this); + m_currentActivity = m_activityController->currentActivity(); + QStringList activities = m_activityController->listActivities(); + //setData("allActivities", activities); + foreach (const QString &id, activities) { + insertActivity(id); + } + + connect(m_activityController, SIGNAL(activityAdded(QString)), this, SLOT(activityAdded(QString))); + connect(m_activityController, SIGNAL(activityRemoved(QString)), this, SLOT(activityRemoved(QString))); + connect(m_activityController, SIGNAL(currentActivityChanged(QString)), this, SLOT(currentActivityChanged(QString))); + + //some convenience sources for times when checking every activity source would suck + //it starts with _ so that it can easily be filtered out of sources() + //maybe I should just make it not included in sources() instead? + m_runningActivities = m_activityController->listActivities(KActivities::Info::Running); + setData("Status", "Current", m_currentActivity); + setData("Status", "Running", m_runningActivities); + + m_watcher = new QDBusServiceWatcher( + ACTIVITYMANAGER_SERVICE, + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForRegistration + | QDBusServiceWatcher::WatchForUnregistration, + this); + + connect(m_watcher, SIGNAL(serviceRegistered(QString)), + this, SLOT(enableRanking())); + connect(m_watcher, SIGNAL(serviceUnregistered(QString)), + this, SLOT(disableRanking())); + + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(ACTIVITYMANAGER_SERVICE)) { + enableRanking(); + } + } +} + +void ActivityEngine::insertActivity(const QString &id) +{ + //id -> name, icon, state + KActivities::Info *activity = new KActivities::Info(id, this); + m_activities[id] = activity; + setData(id, "Name", activity->name()); + setData(id, "Icon", activity->icon()); + setData(id, "Current", m_currentActivity == id); + setData(id, "Encrypted", false); + + QString state; + switch (activity->state()) { + case KActivities::Info::Running: + state = "Running"; + break; + case KActivities::Info::Starting: + state = "Starting"; + break; + case KActivities::Info::Stopping: + state = "Stopping"; + break; + case KActivities::Info::Stopped: + state = "Stopped"; + break; + case KActivities::Info::Invalid: + default: + state = "Invalid"; + } + setData(id, "State", state); + setData(id, "Score", m_activityScores.value(id)); + + connect(activity, SIGNAL(infoChanged()), this, SLOT(activityDataChanged())); + connect(activity, SIGNAL(stateChanged(KActivities::Info::State)), this, SLOT(activityStateChanged())); + + m_runningActivities << id; +} + +void ActivityEngine::disableRanking() +{ + delete m_activityRankingClient; +} + +void ActivityEngine::enableRanking() +{ + m_activityRankingClient = new org::kde::ActivityManager::ActivityRanking( + ACTIVITYMANAGER_SERVICE, + ACTIVITYRANKING_OBJECT, + QDBusConnection::sessionBus() + ); + connect(m_activityRankingClient, SIGNAL(rankingChanged(QStringList,ActivityDataList)), + this, SLOT(rankingChanged(QStringList,ActivityDataList))); + + QDBusMessage msg = QDBusMessage::createMethodCall(ACTIVITYMANAGER_SERVICE, + ACTIVITYRANKING_OBJECT, + "org.kde.ActivityManager.ActivityRanking", + "activities"); + QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(msg); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(activityScoresReply(QDBusPendingCallWatcher*))); +} + +void ActivityEngine::activityScoresReply(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + kDebug() << "Error getting activity scores: " << reply.error().message(); + } else { + setActivityScores(reply.value()); + } + + watcher->deleteLater(); +} + +void ActivityEngine::rankingChanged(const QStringList &topActivities, const ActivityDataList &activities) +{ + Q_UNUSED(topActivities) + + setActivityScores(activities); +} + +void ActivityEngine::setActivityScores(const ActivityDataList &activities) +{ + QSet presentActivities; + m_activityScores.clear(); + + foreach (const ActivityData &activity, activities) { + if (m_activities.contains(activity.id)) { + setData(activity.id, "Score", activity.score); + } + presentActivities.insert(activity.id); + m_activityScores[activity.id] = activity.score; + } + + foreach (const QString &activityId, m_activityController->listActivities()) { + if (!presentActivities.contains(activityId) && m_activities.contains(activityId)) { + setData(activityId, "Score", 0); + } + } +} + +void ActivityEngine::activityAdded(const QString &id) +{ + insertActivity(id); + setData("Status", "Running", m_runningActivities); +} + +void ActivityEngine::activityRemoved(const QString &id) +{ + removeSource(id); + KActivities::Info *activity = m_activities.take(id); + if (activity) { + delete activity; + } + m_runningActivities.removeAll(id); + setData("Status", "Running", m_runningActivities); +} + +void ActivityEngine::currentActivityChanged(const QString &id) +{ + setData(m_currentActivity, "Current", false); + m_currentActivity = id; + setData(id, "Current", true); + setData("Status", "Current", id); +} + +void ActivityEngine::activityDataChanged() +{ + KActivities::Info *activity = qobject_cast(sender()); + if (!activity) { + return; + } + setData(activity->id(), "Name", activity->name()); + setData(activity->id(), "Icon", activity->icon()); + setData(activity->id(), "Encrypted", false); + setData(activity->id(), "Current", m_currentActivity == activity->id()); + setData(activity->id(), "Score", m_activityScores.value(activity->id())); +} + +void ActivityEngine::activityStateChanged() +{ + KActivities::Info *activity = qobject_cast(sender()); + const QString id = activity->id(); + if (!activity) { + return; + } + QString state; + switch (activity->state()) { + case KActivities::Info::Running: + state = "Running"; + break; + case KActivities::Info::Starting: + state = "Starting"; + break; + case KActivities::Info::Stopping: + state = "Stopping"; + break; + case KActivities::Info::Stopped: + state = "Stopped"; + break; + case KActivities::Info::Invalid: + default: + state = "Invalid"; + } + setData(id, "State", state); + + if (activity->state() == KActivities::Info::Running) { + if (!m_runningActivities.contains(id)) { + m_runningActivities << id; + } + } else { + m_runningActivities.removeAll(id); + } + + setData("Status", "Running", m_runningActivities); +} + + +Plasma::Service *ActivityEngine::serviceForSource(const QString &source) +{ + //FIXME validate the name + ActivityService *service = new ActivityService(m_activityController, source); + service->setParent(this); + return service; +} + +K_EXPORT_PLASMA_DATAENGINE(activities, ActivityEngine) + +#include "activityengine.moc" diff --git a/plasma/generic/dataengines/activities/activityengine.h b/plasma/generic/dataengines/activities/activityengine.h new file mode 100644 index 00000000..d6824a06 --- /dev/null +++ b/plasma/generic/dataengines/activities/activityengine.h @@ -0,0 +1,81 @@ +/* + * Copyright 2010 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIVITY_ENGINE_H +#define ACTIVITY_ENGINE_H + +#include + +#include +#include + +#include "ActivityData.h" +#include "ActivityRankingInterface.h" + + +class QDBusServiceWatcher; + +class ActivityService; + +namespace KActivities +{ + class Controller; + class Info; +} + + +class ActivityEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + ActivityEngine(QObject* parent, const QVariantList& args); + Plasma::Service *serviceForSource(const QString &source); + void init(); + +public slots: + void activityAdded(const QString &id); + void activityRemoved(const QString &id); + void currentActivityChanged(const QString &id); + + void activityDataChanged(); + void activityStateChanged(); + + void disableRanking(); + void enableRanking(); + void rankingChanged(const QStringList &topActivities, const ActivityDataList &activities); + void activityScoresReply(QDBusPendingCallWatcher *watcher); + +private: + void insertActivity(const QString &id); + void setActivityScores(const ActivityDataList &activities); + + KActivities::Controller *m_activityController; + QHash m_activities; + QStringList m_runningActivities; + QString m_currentActivity; + + org::kde::ActivityManager::ActivityRanking *m_activityRankingClient; + QDBusServiceWatcher *m_watcher; + QHash m_activityScores; + + friend class ActivityService; +}; + +#endif // SEARCHLAUNCH_ENGINE_H diff --git a/plasma/generic/dataengines/activities/activityjob.cpp b/plasma/generic/dataengines/activities/activityjob.cpp new file mode 100644 index 00000000..77ce52ad --- /dev/null +++ b/plasma/generic/dataengines/activities/activityjob.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "activityjob.h" + +#include +#include + +#include +#include + +ActivityJob::ActivityJob(KActivities::Controller *controller, const QString &id, const QString &operation, QMap ¶meters, QObject *parent) : + ServiceJob(parent->objectName(), operation, parameters, parent), + m_activityController(controller), + m_id(id) +{ +} + +ActivityJob::~ActivityJob() +{ +} + +void ActivityJob::start() +{ + const QString operation = operationName(); + if (operation == "add") { + //I wonder how well plasma will handle this... + QString name = parameters()["Name"].toString(); + if (name.isEmpty()) { + name = i18n("unnamed"); + } + const QString activityId = m_activityController->addActivity(name); + setResult(activityId); + return; + } + if (operation == "remove") { + QString id = parameters()["Id"].toString(); + m_activityController->removeActivity(id); + setResult(true); + return; + } + + //m_id is needed for the rest + if (m_id.isEmpty()) { + setResult(false); + return; + } + if (operation == "setCurrent") { + m_activityController->setCurrentActivity(m_id); + setResult(true); + return; + } + if (operation == "stop") { + m_activityController->stopActivity(m_id); + setResult(true); + return; + } + if (operation == "start") { + m_activityController->startActivity(m_id); + setResult(true); + return; + } + if (operation == "setName") { + m_activityController->setActivityName(m_id, parameters()["Name"].toString()); + setResult(true); + return; + } + if (operation == "setIcon") { + m_activityController->setActivityIcon(m_id, parameters()["Icon"].toString()); + setResult(true); + return; + } + if (operation == "setEncrypted") { + m_activityController->setActivityEncrypted(m_id, parameters()["Encrypted"].toBool()); + setResult(true); + return; + } + if (operation == "toggleActivityManager") { + QDBusMessage message = QDBusMessage::createMethodCall("org.kde.plasma-desktop", + "/App", + QString(), + "toggleActivityManager"); + QDBusConnection::sessionBus().call(message, QDBus::NoBlock); + setResult(true); + return; + } + setResult(false); +} + +#include "activityjob.moc" diff --git a/plasma/generic/dataengines/activities/activityjob.h b/plasma/generic/dataengines/activities/activityjob.h new file mode 100644 index 00000000..a8d59d39 --- /dev/null +++ b/plasma/generic/dataengines/activities/activityjob.h @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIVITYJOB_H +#define ACTIVITYJOB_H + +// plasma +#include + +namespace KActivities +{ + class Controller; +} // namespace KActivities + +class ActivityJob : public Plasma::ServiceJob +{ + + Q_OBJECT + + public: + ActivityJob(KActivities::Controller *controller, const QString &id, const QString &operation, QMap ¶meters, QObject *parent = 0); + ~ActivityJob(); + + protected: + void start(); + + private: + KActivities::Controller *m_activityController; + QString m_id; + +}; + +#endif // TASKJOB_H diff --git a/plasma/generic/dataengines/activities/activityservice.cpp b/plasma/generic/dataengines/activities/activityservice.cpp new file mode 100644 index 00000000..4760d108 --- /dev/null +++ b/plasma/generic/dataengines/activities/activityservice.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2010 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "activityservice.h" +#include "activityjob.h" + +ActivityService::ActivityService(KActivities::Controller *controller, const QString &source) + : m_activityController(controller), + m_id(source) +{ + setName("activities"); +} + +ServiceJob *ActivityService::createJob(const QString &operation, QMap ¶meters) +{ + return new ActivityJob(m_activityController, m_id, operation, parameters, this); +} + +#include "activityservice.moc" diff --git a/plasma/generic/dataengines/activities/activityservice.h b/plasma/generic/dataengines/activities/activityservice.h new file mode 100644 index 00000000..e964a81d --- /dev/null +++ b/plasma/generic/dataengines/activities/activityservice.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIVITY_SERVICE_H +#define ACTIVITY_SERVICE_H + +#include "activityengine.h" + +#include +#include + +using namespace Plasma; + +namespace KActivities +{ + class Controller; +} // namespace KActivities + + +class ActivityService : public Plasma::Service +{ + Q_OBJECT + +public: + ActivityService(KActivities::Controller *controller, const QString &source); + ServiceJob *createJob(const QString &operation, + QMap ¶meters); + +private: + KActivities::Controller *m_activityController; + QString m_id; +}; + +#endif // SEARCHLAUNCH_SERVICE_H diff --git a/plasma/generic/dataengines/activities/org.kde.ActivityManager.ActivityRanking.xml b/plasma/generic/dataengines/activities/org.kde.ActivityManager.ActivityRanking.xml new file mode 100644 index 00000000..11374014 --- /dev/null +++ b/plasma/generic/dataengines/activities/org.kde.ActivityManager.ActivityRanking.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/activities/plasma-engine-activities.desktop b/plasma/generic/dataengines/activities/plasma-engine-activities.desktop new file mode 100644 index 00000000..1409da77 --- /dev/null +++ b/plasma/generic/dataengines/activities/plasma-engine-activities.desktop @@ -0,0 +1,130 @@ +[Desktop Entry] +Name=Activities Engine +Name[ar]=محرك الأنشطة +Name[bg]=Ядро за дейности +Name[bs]=motor aktivnosti +Name[ca]=Motor d'activitats +Name[ca@valencia]=Motor d'activitats +Name[cs]=Stroj aktivit +Name[da]=Aktivitetsmotor +Name[de]=Aktivitätenverwaltung +Name[el]=Μηχανή δραστηριοτήτων +Name[en_GB]=Activities Engine +Name[es]=Motor de actividades +Name[et]=Tegevuste mootor +Name[eu]=Jarduera-motorra +Name[fi]=Aktiviteettimoottori +Name[fr]=Moteur d'activités +Name[ga]=Inneall Gníomhaíochta +Name[gl]=Motor de actividades +Name[he]=מנוע הפעילויות +Name[hr]=Mehanizam aktivnosti +Name[hu]=Aktivitások modul +Name[ia]=Motor de activitate +Name[is]=Virknivél +Name[it]=Motore delle attività +Name[ja]=アクティビティエンジン +Name[kk]=Белсенділік тетігі +Name[km]=ម៉ាស៊ីន​សកម្មភាព +Name[kn]=ಚಟುವಟಿಕೆ ಎಂಜಿನ್ +Name[ko]=활동 엔진 +Name[lt]=Veiklų modulis +Name[lv]=Aktivitāšu dzinējs +Name[mr]=कार्यपध्दती इंजिन +Name[nb]=Aktivitetsmotor +Name[nds]=Aktivitetenpleger +Name[nl]=Activiteiten-engine +Name[pa]=ਸਰਗਰਮੀ ਇੰਜਣ +Name[pl]=Silnik działań +Name[pt]=Motor de Actividades +Name[pt_BR]=Mecanismo de atividades +Name[ro]=Motor de activități +Name[ru]=Источник данных для комнат +Name[sk]=Nástroj aktivít +Name[sl]=Pogon za dejavnosti +Name[sr]=мотор активности +Name[sr@ijekavian]=мотор активности +Name[sr@ijekavianlatin]=motor aktivnosti +Name[sr@latin]=motor aktivnosti +Name[sv]=Aktivitetsgränssnitt +Name[th]=กลไกจัดการกิจกรรม +Name[tr]=Etkinlik Motoru +Name[ug]=پائالىيەت ماتورى +Name[uk]=Рушій просторів дій +Name[vi]=Cơ chế cho Hoạt động +Name[wa]=Moteur d' activités +Name[x-test]=xxActivities Enginexx +Name[zh_CN]=活动引擎 +Name[zh_TW]=活動引擎 +Comment=Information on Plasma Activities +Comment[ar]=معلومات عن أنشطة بلازما +Comment[bg]=Данни за дейности в Plasma +Comment[bs]=Podaci o plazma aktivnostima +Comment[ca]=Informació quant a activitats del Plasma +Comment[ca@valencia]=Informació quant a activitats del Plasma +Comment[cs]=Informace o Plasma aktivitách. +Comment[da]=Information om Plasma-aktiviteter +Comment[de]=Informationen über Plasma-Aktivitäten +Comment[el]=Πληροφορίες για τις δραστηριότητες Plasma +Comment[en_GB]=Information on Plasma Activities +Comment[es]=Información sobre las actividades de Plasma +Comment[et]=Teave Plasma tegevuste kohta. +Comment[eu]=Plasmaren jarduerei buruzko informazioa +Comment[fi]=Tietoja Plasma-aktiviteeteista +Comment[fr]=Informations sur les activités de Plasma +Comment[gl]=Información acerca das actividades de Plasma +Comment[he]=מידע אודות הפעילויות של Plasma +Comment[hr]=Informacije o Plasminim aktivnostima +Comment[hu]=Információk a Plasma aktivitásokról +Comment[ia]=Information re activitates de Plasma +Comment[is]=Upplýsingar um Plasma virkni +Comment[it]=Informazioni sulle attività di Plasma +Comment[ja]=Plasma アクティビティの情報 +Comment[kk]=Plasma белсенділігі туралы мәлімет +Comment[km]=ព័ត៌មាន​អំពី​សកម្មភាព​ប្លាស្មា +Comment[kn]=ಪ್ಲಾಸ್ಮಾ ಚಟುವಟಿಕೆಗಳ ಬಗೆಗೆ ಮಾಹಿತಿ. +Comment[ko]=Plasma 활동 정보 +Comment[lt]=Informacija apie Plasma veiklas +Comment[lv]=Informācija par Plasma aktivitātēm +Comment[mr]=प्लाज्मा कार्यपध्दती बद्दल माहिती +Comment[nb]=Informasjon om Plasma-aktiviteter +Comment[nds]=Informatschonen över Plasma-Aktiviteten +Comment[nl]=Informatie over Plasma activiteiten +Comment[nn]=Informasjon om Plasma-aktivitetar +Comment[pa]=ਪਲਾਜ਼ਮਾ ਸਰਗਰਮੀਆਂ ਲਈ ਜਾਣਕਾਰੀ +Comment[pl]=Informacje o działaniach Plazmy +Comment[pt]=Informação sobre as Actividades do Plasma +Comment[pt_BR]=Informações sobre as atividades do Plasma +Comment[ro]=Informații despre activitățile Plasma +Comment[ru]=Сведения о комнатах Plasma +Comment[sk]=Informácie o Plasma aktivitách +Comment[sl]=Podatki o dejavnostih za Plasmo +Comment[sr]=Подаци о плазма активностима +Comment[sr@ijekavian]=Подаци о плазма активностима +Comment[sr@ijekavianlatin]=Podaci o plasma aktivnostima +Comment[sr@latin]=Podaci o plasma aktivnostima +Comment[sv]=Information om aktiviteter i Plasma +Comment[th]=ข้อมูลเกี่ยวกับกิจกรรมต่างๆ ของพลาสมา +Comment[tr]=Plasma Etkinliklerindeki Bilgiler +Comment[ug]=پلازما پائالىيىتىدىكى ئۇچۇر +Comment[uk]=Інформація про простори дій Плазми +Comment[vi]=Thông tin về các Hoạt động Plasma +Comment[wa]=Pondants et djondants so les activités di Plasma +Comment[x-test]=xxInformation on Plasma Activitiesxx +Comment[zh_CN]=关于 Plasma 活动的信息 +Comment[zh_TW]=Plasma 活動的資訊 +Type=Service +Icon=preferences-activities + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_activities +X-Plasma-EngineName=activities +X-KDE-PluginInfo-Author=Chani Armitage +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=org.kde.activities +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/akonadi/CMakeLists.txt b/plasma/generic/dataengines/akonadi/CMakeLists.txt new file mode 100644 index 00000000..7f0dd346 --- /dev/null +++ b/plasma/generic/dataengines/akonadi/CMakeLists.txt @@ -0,0 +1,29 @@ +include_directories( + ${Boost_INCLUDE_DIR} + ${KDEPIMLIBS_INCLUDE_DIRS} +) + +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + +set(akonadi_engine_srcs + akonadiengine.cpp +) + +kde4_add_plugin(plasma_engine_akonadi ${akonadi_engine_srcs}) + +target_link_libraries( + plasma_engine_akonadi + ${KDE4_KPIMUTILS_LIBS} + ${KDE4_KDECORE_LIBS} + ${KDE4_AKONADI_LIBS} + ${KDE4_PLASMA_LIBS} + ${KDE4_KMIME_LIBS} + ${KDE4_AKONADI_KMIME_LIBS} + ${KDE4_KABC_LIBS} + ${QT_QTXML_LIBRARY} + microblog +) + +install(TARGETS plasma_engine_akonadi DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-engine-akonadi.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/akonadi/akonadiengine.cpp b/plasma/generic/dataengines/akonadi/akonadiengine.cpp new file mode 100644 index 00000000..b7c4372d --- /dev/null +++ b/plasma/generic/dataengines/akonadi/akonadiengine.cpp @@ -0,0 +1,486 @@ +/* + Copyright (c) 2007 Volker Krause + Copyright (c) 2009 Sebastian Kügler + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + +#include "akonadiengine.h" + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +using namespace Akonadi; + +AkonadiEngine::AkonadiEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent), + m_emailMonitor(0), + m_contactMonitor(0), + m_microBlogMonitor(0) +{ + Q_UNUSED(args); + setMaxSourceCount( 512 ); // Guard against loading thousands of emails + // TODO: monitoring for new microblog collections +} + +void AkonadiEngine::initEmailMonitor() +{ + m_emailMonitor = new Monitor( this ); + m_emailMonitor->setMimeTypeMonitored("message/rfc822"); + //m_emailMonitor->setCollectionMonitored(Collection::root(), false); + m_emailMonitor->itemFetchScope().fetchFullPayload( true ); + connect(m_emailMonitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), + SLOT(emailItemAdded(Akonadi::Item)) ); + connect(m_emailMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), + SLOT(emailItemAdded(Akonadi::Item)) ); + // remove the monitor on a source that's not used + connect(this, SIGNAL(sourceRemoved(QString)), SLOT(stopMonitor(QString))); +} + +void AkonadiEngine::initContactMonitor() +{ + m_contactMonitor = new Monitor( this ); + m_contactMonitor->setMimeTypeMonitored("text/directory"); + m_contactMonitor->setCollectionMonitored(Collection::root(), false); + m_contactMonitor->itemFetchScope().fetchFullPayload(); + connect(m_contactMonitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), + SLOT(contactItemAdded(Akonadi::Item)) ); + connect(m_contactMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), + SLOT(contactItemAdded(Akonadi::Item)) ); + // remove the monitor on a source that's not used + connect(this, SIGNAL(sourceRemoved(QString)), SLOT(stopMonitor(QString))); +} + +void AkonadiEngine::initMicroBlogMonitor() +{ + // TODO: set up monitoring for "application/x-vnd.kde.microblog" + m_microBlogMonitor = new Monitor( this ); + m_microBlogMonitor->setMimeTypeMonitored( "application/x-vnd.kde.microblog" ); + m_microBlogMonitor->setCollectionMonitored(Collection::root(), false); + m_microBlogMonitor->itemFetchScope().fetchFullPayload(); + connect(m_microBlogMonitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), + SLOT(microBlogItemAdded(Akonadi::Item)) ); + connect(m_microBlogMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), + SLOT(microBlogItemAdded(Akonadi::Item)) ); + // remove the monitor on a source that's not used + connect(this, SIGNAL(sourceRemoved(QString)), SLOT(stopMonitor(QString))); +} + +AkonadiEngine::~AkonadiEngine() +{ +} + +QStringList AkonadiEngine::sources() const +{ + return QStringList() << "EmailCollections" << "ContactCollections" << "MicroBlogs"; +} + +void AkonadiEngine::fetchEmailCollectionsDone(KJob* job) +{ + // called when the job fetching email collections from Akonadi emits result() + if ( job->error() ) { + kDebug() << "Job Error:" << job->errorString(); + } else { + CollectionFetchJob* cjob = static_cast( job ); + int i = 0; + foreach( const Collection &collection, cjob->collections() ) { + if (collection.contentMimeTypes().contains("message/rfc822")) { + //kDebug() << "EmailCollection setting data:" << collection.name() << collection.url() << collection.contentMimeTypes(); + i++; + setData("EmailCollections", QString("EmailCollection-%1").arg(collection.id()), collection.name()); + } + } + kDebug() << i << "Email collections are in now"; + scheduleSourcesUpdated(); + } +} + +void AkonadiEngine::fetchContactCollectionsDone(KJob* job) +{ + // called when the job fetching contact collections from Akonadi emits result() + if ( job->error() ) { + kDebug() << "Job Error:" << job->errorString(); + } else { + CollectionFetchJob* cjob = static_cast( job ); + int i = 0; + foreach( const Collection &collection, cjob->collections() ) { + if (collection.contentMimeTypes().contains("text/directory")) { + //kDebug() << "ContactCollection setting data:" << collection.name() << collection.url() << collection.contentMimeTypes(); + i++; + setData("ContactCollections", QString("ContactCollection-%1").arg(collection.id()), collection.name()); + } + } + kDebug() << i << "Contact collections are in now"; + scheduleSourcesUpdated(); + } +} + +void AkonadiEngine::fetchMicroBlogCollectionsDone(KJob* job) +{ + // called when the job fetching microblog collections from Akonadi emits result() + if ( job->error() ) { + kDebug() << "Job Error:" << job->errorString(); + } else { + CollectionFetchJob* cjob = static_cast( job ); + int i = 0; + foreach( const Collection &collection, cjob->collections() ) { + if (collection.contentMimeTypes().contains("application/x-vnd.kde.microblog")) { + kDebug() << "Microblog setting data:" << collection.name() << collection.url() << collection.contentMimeTypes(); + i++; + setData("MicroblogCollection", QString("MicroBlog-%1").arg(collection.id()), collection.name()); + } + } + kDebug() << i << "MicroBlog collections are in now"; + scheduleSourcesUpdated(); + } +} + +bool AkonadiEngine::sourceRequestEvent(const QString &name) +{ + kDebug() << "Source requested:" << name << sources(); + + if (name == "EmailCollections") { + Collection emailCollection(Collection::root()); + emailCollection.setContentMimeTypes(QStringList() << "message/rfc822"); + CollectionFetchJob *fetch = new CollectionFetchJob( emailCollection, CollectionFetchJob::Recursive); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchEmailCollectionsDone(KJob*)) ); + // For async data fetching, it's mandatory to set the data source to empty before returning true + setData(name, DataEngine::Data()); + return true; + + } else if (name.startsWith(QString("EmailCollection-"))) { + qlonglong id = name.split('-')[1].toLongLong(); + ItemFetchJob* fetch = new ItemFetchJob( Collection( id ), this ); + if (!m_emailMonitor) { + initEmailMonitor(); + } + m_emailMonitor->setCollectionMonitored(Collection( id ), true); + fetch->fetchScope().fetchPayloadPart( MessagePart::Envelope ); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchEmailCollectionDone(KJob*)) ); + connect( fetch, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(emailItemsReceived(Akonadi::Item::List)) ); + m_jobCollections[fetch] = name; + setData(name, DataEngine::Data()); + return true; + + } else if (name.startsWith(QString("Email-"))) { + qlonglong id = name.split('-')[1].toLongLong(); + ItemFetchJob* fetch = new ItemFetchJob( Item( id ), this ); + if (!m_emailMonitor) { + initEmailMonitor(); + } + m_emailMonitor->setItemMonitored(Item( id ), true); + fetch->fetchScope().fetchFullPayload( true ); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchEmailCollectionDone(KJob*)) ); + connect( fetch, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(emailItemsReceived(Akonadi::Item::List)) ); + m_jobCollections[fetch] = name; + setData(name, DataEngine::Data()); + return true; + + } else if (name == "ContactCollections") { + Collection contactCollection(Collection::root()); + contactCollection.setContentMimeTypes(QStringList() << "text/directory"); + + CollectionFetchJob* fetch = new CollectionFetchJob( contactCollection, CollectionFetchJob::Recursive); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchContactCollectionsDone(KJob*)) ); + setData(name, DataEngine::Data()); + return true; + + } else if (name.startsWith(QString("ContactCollection-"))) { + qlonglong id = name.split('-')[1].toLongLong(); + ItemFetchJob *fetch = new ItemFetchJob( Collection( id ), this ); + if (!m_contactMonitor) { + initContactMonitor(); + } + m_contactMonitor->setCollectionMonitored(Collection( id ), true); // FIXME: should be contacts monitor + fetch->fetchScope().fetchFullPayload(); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchContactCollectionDone(KJob*)) ); + setData(name, DataEngine::Data()); + return true; + + } else if (name.startsWith(QString("Contact-"))) { + kDebug() << "Fetching contact" << name; + qlonglong id = name.split('-')[1].toLongLong(); + ItemFetchJob *fetch = new ItemFetchJob( Item( id ), this ); + if (!m_contactMonitor) { + initContactMonitor(); + } + m_contactMonitor->setItemMonitored(Item( id ), true); // FIXME: should be contacts monitor + fetch->fetchScope().fetchFullPayload(); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchContactCollectionDone(KJob*)) ); + setData(name, DataEngine::Data()); + return true; + + } else if (name == "MicroBlogs") { + Collection microblogCollection(Collection::root()); + microblogCollection.setContentMimeTypes(QStringList() << "application/x-vnd.kde.microblog"); + CollectionFetchJob *fetch = new CollectionFetchJob( microblogCollection, CollectionFetchJob::Recursive); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchMicroBlogCollectionsDone(KJob*)) ); + setData(name, DataEngine::Data()); + return true; + + } else if (name.startsWith(QString("MicroBlog-"))) { + qlonglong id = name.split('-')[1].toLongLong(); + kDebug() << "MicroBlog ID" << id << " requested" << name; + ItemFetchJob *fetch = new ItemFetchJob( Akonadi::Collection( id )); + if (!m_microBlogMonitor) { + initMicroBlogMonitor(); + } + m_microBlogMonitor->setItemMonitored(Item( id ), true); + fetch->fetchScope().fetchFullPayload(); + connect( fetch, SIGNAL(result(KJob*)), SLOT(fetchMicroBlogDone(KJob*)) ); + setData(name, DataEngine::Data()); + return true; + } + // We don't understand the request. + kDebug() << "Don't know what to do with:" << name; + return false; +} + +void AkonadiEngine::stopMonitor(const QString &name) +{ + if (name.startsWith(QString("EmailCollection-"))) { + // Stop monitoring this one + qlonglong id = name.split('-')[1].toLongLong(); + m_emailMonitor->setCollectionMonitored( Collection( id ), false); + kDebug() << "Removed monitor from:" << name << id; + } +} + +void AkonadiEngine::emailItemsReceived(const Akonadi::Item::List &items) +{ + foreach (const Akonadi::Item &item, items) { + emailItemAdded(item); + } +} + +void AkonadiEngine::emailItemAdded(const Akonadi::Item &item, const QString &collection) +{ + if ( !item.hasPayload() ) { + return; + } + MessagePtr msg = item.payload(); + if (msg) { + QString source = QString::number( item.id() ); + source = "Email-" + source; + //kDebug() << "new source adding:" << source << item.url() << msg->subject()->asUnicodeString(); + + setData( source, "Id", item.id() ); + setData( source, "Collection", collection); + setData( source, "Url", item.url().url() ); + setData( source, "Subject", msg->subject()->asUnicodeString() ); + setData( source, "From", msg->from()->asUnicodeString() ); + setData( source, "DateTime", msg->date()->dateTime().date() ); + setData( source, "To", msg->to()->asUnicodeString() ); + setData( source, "Cc", msg->cc()->asUnicodeString() ); + setData( source, "Bcc", msg->bcc()->asUnicodeString() ); + setData( source, "Body", QString(msg->mainBodyPart()->body())); + // Flags + //kDebug() << item.flags(); + setData( source, "Flag-New", !item.hasFlag("\\Seen") ); + setData( source, "Flag-Task", item.hasFlag("\\Task") ); // not in Akonadi! + setData( source, "Flag-Important", item.hasFlag("important") ); + setData( source, "Flag-Attachment", item.hasFlag("has_attachment") ); + setData( source, "Flag-Spam", item.hasFlag("spam") ); + setData( source, "Flag-Draft", item.hasFlag("\\Draft") ); + setData( source, "Flag-Answered", item.hasFlag("\\Answered") ); + setData( source, "Flag-Deleted", item.hasFlag("\\Deleted") ); + setData( source, "Flag-Flagged", item.hasFlag("\\Flagged") ); + + if (!collection.isEmpty()) { + setData( collection, source, msg->subject()->asUnicodeString()); + } + printMessage(msg); + scheduleSourcesUpdated(); + } +} + +void AkonadiEngine::printMessage(const MessagePtr msg) +{ + return; + kDebug() << "sub" << msg->subject()->asUnicodeString(); + return; + kDebug() << "=============== New Item" << msg->from()->asUnicodeString() << msg->subject()->asUnicodeString(); + kDebug() << "sub" << msg->subject()->asUnicodeString(); + kDebug() << "from" << msg->from()->asUnicodeString(); + kDebug() << "date" << msg->date()->dateTime().date(); + kDebug() << "to" << msg->to()->asUnicodeString(); + kDebug() << "cc" << msg->cc()->asUnicodeString(); + kDebug() << "bcc" << msg->bcc()->asUnicodeString(); + kDebug() << "body" << msg->mainBodyPart()->body(); +} + +void AkonadiEngine::fetchEmailCollectionDone(KJob* job) +{ + if ( job->error() ) { + kDebug() << "Job Error:" << job->errorString(); + return; + } + const QString col = m_jobCollections[job]; + Item::List items = static_cast( job )->items(); + foreach ( const Item &item, items ) { + emailItemAdded(item, col); + } + m_jobCollections.remove(job); + scheduleSourcesUpdated(); +} + +void AkonadiEngine::fetchContactCollectionDone(KJob* job) +{ + if ( job->error() ) { + return; + } + Item::List items = static_cast( job )->items(); + foreach ( const Item &item, items ) { + contactItemAdded( item ); + } +} + +void AkonadiEngine::fetchMicroBlogDone(KJob* job) +{ + if (job->error()) { + kDebug() << "Microblog job failed:" << job->errorString(); + } else { + Item::List items = static_cast( job )->items(); + kDebug() << "Adding microblogs" << items.count(); + foreach (const Item &item, items) { + microBlogItemAdded(item); + } + } +} + + +void AkonadiEngine::microBlogItemAdded(const Akonadi::Item &item) +{ + // Get the Akonadi::Item's XML payload and parse that, then + // put it into the DataEngine's Data + kDebug() << "Checking one item"; + if (item.hasPayload()) { + Microblog::StatusItem s = item.payload(); + const QString source = QString("MicroBlog-%1").arg(s.id()); + kDebug() << "Adding" << source << s.keys(); + setData(source, "Date", s.date()); + setData(source, "Foo", "Bar"); + foreach (const QString &key, s.keys()) { + setData(source, key, s.value(key)); + } + scheduleSourcesUpdated(); + } else { + kDebug() << "Wrong payload (not a StatusItem)"; + } +} + +void AkonadiEngine::printContact(const QString &source, const KABC::Addressee &a) +{ + kDebug() << "-----------------------------------"; + kDebug() << source; + kDebug() << "name" << a.name(); + kDebug() << "formattedName" << a.formattedName(); + kDebug() << "nameLabel" << a.nameLabel(); + kDebug() << "given" << a.givenName(); + kDebug() << "familyName" << a.familyName(); + kDebug() << "realName" << a.realName(); + kDebug() << "organization" << a.organization(); + kDebug() << "department" << a.department(); + kDebug() << "role" << a.role(); + kDebug() << "emails" << a.emails(); + kDebug() << "fullEmail" << a.fullEmail(); + kDebug() << "photoUrl" << a.photo().url(); + kDebug() << "note" << a.note(); + + QStringList phoneNumbers; + foreach (const KABC::PhoneNumber &pn, a.phoneNumbers()) { + const QString key = QString("Phone-%1").arg(pn.typeLabel()); + kDebug() << key << a.phoneNumber(pn.type()).number(); + phoneNumbers << a.phoneNumber(pn.type()).number(); + } + kDebug() << "phoneNumbers" << phoneNumbers; + + kDebug() << "additionalName" << a.additionalName(); + +} + +void AkonadiEngine::contactItemAdded( const Akonadi::Item &item ) +{ + if (item.hasPayload()) { + //kDebug() << item.id() << "item has payload ..."; + KABC::Addressee a = item.payload(); + if (!a.isEmpty()) { + const QString source = QString("Contact-%1").arg(item.id()); + setData(source, "Id", item.id()); + setData(source, "Url", item.url().url()); + + // Name and related + setData(source, "Name", a.formattedName()); + setData(source, "GivenName", a.givenName()); + setData(source, "FamilyName", a.familyName()); + setData(source, "NickName", a.nickName()); + setData(source, "RealName", a.realName()); + setData(source, "AdditionalName", a.additionalName()); + + // Organization and related + setData(source, "Organization", a.organization()); + setData(source, "Department", a.department()); + setData(source, "Role", a.role()); + + // EMail and related + setData(source, "Emails", a.emails()); + setData(source, "FullEmail", a.fullEmail()); + + // Phone and related + QStringList phoneNumbers; + foreach (const KABC::PhoneNumber &pn, a.phoneNumbers()) { + const QString key = QString("Phone-%1").arg(pn.typeLabel()); + setData(source, key, a.phoneNumber(pn.type()).number()); + phoneNumbers << a.phoneNumber(pn.type()).number(); + } + setData(source, "PhoneNumbers", phoneNumbers); + + // Personal + setData(source, "Birthday", a.birthday()); + setData(source, "Photo", a.photo().data()); + setData(source, "PhotoUrl", a.photo().url()); + setData(source, "Latitude", a.geo().latitude()); + setData(source, "Longitude", a.geo().longitude()); + + // addresses + + // categories + + // note, + setData(source, "Note", a.note()); + // prefix + + // ... + //printContact(source, a); + + scheduleSourcesUpdated(); + } + } +} + +#include "akonadiengine.moc" diff --git a/plasma/generic/dataengines/akonadi/akonadiengine.h b/plasma/generic/dataengines/akonadi/akonadiengine.h new file mode 100644 index 00000000..c1457064 --- /dev/null +++ b/plasma/generic/dataengines/akonadi/akonadiengine.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2007 Volker Krause + Copyright (c) 2009 Sebastian Kügler + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + +#ifndef AKONADIENGINE_H +#define AKONADIENGINE_H + +#include + +#include +#include + +#include +#include + +#include +typedef boost::shared_ptr MessagePtr; + +class KJob; + +class AkonadiEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + AkonadiEngine( QObject* parent, const QVariantList& args ); + ~AkonadiEngine(); + QStringList sources() const; + + protected: + bool sourceRequestEvent(const QString &name); + + private slots: + + void stopMonitor(const QString &name); + + void fetchEmailCollectionDone(KJob* job); // done retrieving whole collection + void fetchContactCollectionDone(KJob* job); // done retrieving a whole contact collection + void fetchMicroBlogDone(KJob* job); + + void emailItemsReceived(const Akonadi::Item::List &items); + + void fetchEmailCollectionsDone(KJob* job); // got list of collections + void fetchContactCollectionsDone(KJob* job); + void fetchMicroBlogCollectionsDone(KJob* job); + + void emailItemAdded(const Akonadi::Item &item, const QString &collection = QString()); + void contactItemAdded(const Akonadi::Item & item); + void microBlogItemAdded(const Akonadi::Item &item); + + private: + void initEmailMonitor(); + void initContactMonitor(); + void initMicroBlogMonitor(); + // useful for debugging + void printMessage(MessagePtr msg); + void printContact(const QString &source, const KABC::Addressee &a); + + Akonadi::Monitor* m_emailMonitor; + Akonadi::Monitor* m_contactMonitor; + Akonadi::Monitor* m_microBlogMonitor; + + QHash m_jobCollections; +}; + +K_EXPORT_PLASMA_DATAENGINE(akonadi, AkonadiEngine) + +#endif diff --git a/plasma/generic/dataengines/akonadi/plasma-engine-akonadi.desktop b/plasma/generic/dataengines/akonadi/plasma-engine-akonadi.desktop new file mode 100644 index 00000000..66226a9b --- /dev/null +++ b/plasma/generic/dataengines/akonadi/plasma-engine-akonadi.desktop @@ -0,0 +1,152 @@ +[Desktop Entry] +Name=Akonadi +Name[ar]=أكونادي +Name[ast]=Akonadi +Name[bg]=Akonadi +Name[bs]=Akonadi +Name[ca]=Akonadi +Name[ca@valencia]=Akonadi +Name[cs]=Akonadi +Name[da]=Akonadi +Name[de]=Akonadi +Name[el]=Akonadi +Name[en_GB]=Akonadi +Name[eo]=Akonadi +Name[es]=Akonadi +Name[et]=Akonadi +Name[eu]=Akonadi +Name[fi]=Akonadi +Name[fr]=Akonadi +Name[fy]=Akonadi +Name[ga]=Akonadi +Name[gl]=Akonadi +Name[gu]=Akonadi +Name[he]=Akonadi +Name[hi]=अकोनादी +Name[hr]=Akonadi +Name[hu]=Akonadi +Name[ia]=Akonadi +Name[id]=Akonadi +Name[is]=Akonadi +Name[it]=Akonadi +Name[ja]=Akonadi +Name[ka]=Akonadi +Name[kk]=Akonadi +Name[km]=Akonadi +Name[kn]=Akonadi +Name[ko]=Akonadi +Name[lt]=Akonadi +Name[lv]=Akonadi +Name[mai]=Akonadi +Name[mk]=Akonadi +Name[ml]=അകോനാഡി +Name[mr]=आकोनाडी +Name[nb]=Akonadi +Name[nds]=Akonadi +Name[nl]=Akonadi +Name[nn]=Akonadi +Name[pa]=ਅਕੌਂਡੀ +Name[pl]=Akonadi +Name[pt]=Akonadi +Name[pt_BR]=Akonadi +Name[ro]=Akonadi +Name[ru]=Akonadi +Name[si]=Akonadi +Name[sk]=Akonadi +Name[sl]=Akonadi +Name[sr]=Аконади +Name[sr@ijekavian]=Аконади +Name[sr@ijekavianlatin]=Akonadi +Name[sr@latin]=Akonadi +Name[sv]=Akonadi +Name[tg]=Akonadi +Name[th]=Akonadi +Name[tr]=Akonadi +Name[ug]=Akonadi +Name[uk]=Akonadi +Name[vi]=Akonadi +Name[wa]=Akonadi +Name[x-test]=xxAkonadixx +Name[zh_CN]=Akonadi +Name[zh_TW]=Akonadi +Comment=Akonadi PIM data engine +Comment[ar]=محرك بيانات إدارة المعلومات الشخصية أكونادي +Comment[ast]=Motor de datos Akonadi PIM +Comment[bg]=Ядро за данни Akonadi PIM +Comment[bs]=PIM datomotor Akonadija +Comment[ca]=Motor de dades PIM de l'Akonadi +Comment[ca@valencia]=Motor de dades PIM de l'Akonadi +Comment[cs]=Datový nástroj Akonadi PIM +Comment[csb]=Czérownik pòdôwków Akonadi PIM +Comment[da]=Akonadi datamotor til PIM +Comment[de]=PIM-Datentreiber für Akonadi +Comment[el]=Μηχανή δεδομένων Akonadi PIM +Comment[en_GB]=Akonadi PIM data engine +Comment[eo]=Datuma Motoro de Akonadi PIM +Comment[es]=Motor de datos Akonadi PIM +Comment[et]=Akonadi PIM-i andmete mootor +Comment[eu]=Akonadi PIM datuen motorra +Comment[fi]=Akonadi PIM -tietomoottori +Comment[fr]=Moteur de données PIM d'Akonadi +Comment[fy]=Akonadi PIM gegevensmotor +Comment[ga]=Inneall sonraí PIM Akonadi +Comment[gl]=Motor de datos PIM de Akonadi +Comment[he]=מנוע תוכן של Akonadi PIM +Comment[hi]=अकोनाडी PIM डाटा इंजिन +Comment[hr]=Akonadi mehanizam za upravljanje osobnim informacijama +Comment[hu]=Akonadi adatkezelő modul +Comment[ia]=Motor de datos de Akonadi PIM +Comment[id]=Mesin data PIM Akonadi +Comment[is]=Akonadi gagnavél fyrir persónuupplýsingar (PIM) +Comment[it]=Motore dei dati PIM di Akonadi +Comment[ja]=Akonadi PIM データエンジン +Comment[kk]=Akonadi PIM деректер тетігі +Comment[km]=ម៉ាស៊ីន​ទិន្នន័យ Akonadi PIM +Comment[kn]=Akonadi PIM ದತ್ತ ಸಾಧನ +Comment[ko]=Akonadi PIM 데이터 엔진 +Comment[lt]=Akonadi PIM duomenų variklis +Comment[lv]=Akonadi PIM datu dzinējs +Comment[mk]=Податочна машина Akonadi PIM +Comment[ml]=അകോനാഡി പിം ഡേറ്റാ എഞ്ചിന്‍ +Comment[mr]=आकोनाडी PIM डेटा इन्जीन +Comment[nb]=Akonadi PIM datamotor +Comment[nds]=De PIM-Datenkarn Akonadi +Comment[nl]=Akonadi PIM gegevensengine +Comment[nn]=Akonadi PIM-datamotor +Comment[pa]=ਅਕੌਂਡੀ PIM ਡਾਟਾ ਇੰਜਣ +Comment[pl]=Silnik danych PIM Akonadi +Comment[pt]=Motor de dados PIM do Akonadi +Comment[pt_BR]=Mecanismo de dados PIM do Akonadi +Comment[ro]=Motor de date Akonadi PIM +Comment[ru]=Источник данных Plasma для работы с личными данными, хранящимися в Akonadi +Comment[si]=Akonadi PIM දත්ත එන්ජිම +Comment[sk]=Dátový nástroj Akonadi PIM +Comment[sl]=Podatkovni pogon za upravljanje z osebnimi podatki +Comment[sr]=ПИМ датомотор Аконадија +Comment[sr@ijekavian]=ПИМ датомотор Аконадија +Comment[sr@ijekavianlatin]=PIM datomotor Akonadija +Comment[sr@latin]=PIM datomotor Akonadija +Comment[sv]=Akonadi datagränssnitt för personlig information +Comment[tg]=Системаи санаи Python +Comment[th]=กลไกข้อมูล Akonadi PIM +Comment[tr]=Akonadi PIM veri motoru +Comment[ug]=Akonadi PIM سانلىق-مەلۇمات ماتورى +Comment[uk]=Рушій даних Akonadi PIM +Comment[vi]=Cơ chế dữ liệu Akonadi PIM +Comment[wa]=Éndjin d' dinêyes PIM Akonadi +Comment[x-test]=xxAkonadi PIM data enginexx +Comment[zh_CN]=Akonadi 个人信息管理数据引擎 +Comment[zh_TW]=Akonadi PIM 資料引擎 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=akonadi +X-KDE-Library=plasma_engine_akonadi + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=akonadi +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/applicationjobs/CMakeLists.txt b/plasma/generic/dataengines/applicationjobs/CMakeLists.txt new file mode 100644 index 00000000..5b7a1aab --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/CMakeLists.txt @@ -0,0 +1,21 @@ +project(kuiserver_engine) + +#include (KDE4Defaults) +#include (MacroLibrary) + +set(kuiserver_engine_SRCS + kuiserverengine.cpp + jobcontrol.cpp + jobaction.cpp +) + +qt4_add_dbus_adaptor(kuiserver_engine_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.JobViewV2.xml kuiserverengine.h JobView jobviewadaptor ) +qt4_add_dbus_adaptor(kuiserver_engine_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.JobViewServer.xml kuiserverengine.h KuiserverEngine jobviewserveradaptor ) + +kde4_add_plugin(plasma_engine_applicationjobs ${kuiserver_engine_SRCS}) +target_link_libraries(plasma_engine_applicationjobs ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_engine_applicationjobs DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-applicationjobs.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES applicationjobs.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/applicationjobs/Messages.sh b/plasma/generic/dataengines/applicationjobs/Messages.sh new file mode 100755 index 00000000..d37a3e02 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_kuiserver.pot diff --git a/plasma/generic/dataengines/applicationjobs/applicationjobs.operations b/plasma/generic/dataengines/applicationjobs/applicationjobs.operations new file mode 100644 index 00000000..5b8f5e61 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/applicationjobs.operations @@ -0,0 +1,8 @@ + + + + + + + diff --git a/plasma/generic/dataengines/applicationjobs/jobaction.cpp b/plasma/generic/dataengines/applicationjobs/jobaction.cpp new file mode 100644 index 00000000..1a76ce55 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/jobaction.cpp @@ -0,0 +1,51 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "jobaction.h" +#include "kuiserverengine.h" + +#include + +void JobAction::start() +{ + kDebug() << "Trying to perform the action" << operationName(); + + if (!m_jobView) { + setErrorText(i18nc("%1 is the subject (can be anything) upon which the job is performed", + "The JobView for %1 cannot be found", destination())); + setError(-1); + emitResult(); + return; + } + + //TODO: check with capabilities before performing actions. + if (operationName() == "resume") { + m_jobView->requestStateChange(JobView::Running); + } else if (operationName() == "suspend") { + m_jobView->requestStateChange(JobView::Suspended); + } else if (operationName() == "stop") { + m_jobView->requestStateChange(JobView::Stopped); + //in case the app crashed and won't call terminate on the jobview. + m_jobView->terminate(i18n("Job canceled by user.")); + } + + emitResult(); +} + +#include "jobaction.moc" + diff --git a/plasma/generic/dataengines/applicationjobs/jobaction.h b/plasma/generic/dataengines/applicationjobs/jobaction.h new file mode 100644 index 00000000..3b46040f --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/jobaction.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef JOBACTION_H +#define JOBACTION_H + +#include "kuiserverengine.h" + +#include + +class JobAction : public Plasma::ServiceJob +{ + Q_OBJECT + + public: + JobAction(JobView *jobView, + const QString& operation, + QMap& parameters, + QObject* parent = 0) + : ServiceJob(jobView->objectName(), operation, parameters, parent), + m_jobView(jobView) + { + } + + void start(); + + private: + JobView *m_jobView; +}; + +#endif //JOBVIEW_H diff --git a/plasma/generic/dataengines/applicationjobs/jobcontrol.cpp b/plasma/generic/dataengines/applicationjobs/jobcontrol.cpp new file mode 100644 index 00000000..57d26ff9 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/jobcontrol.cpp @@ -0,0 +1,38 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "jobcontrol.h" +#include "jobaction.h" +#include "kuiserverengine.h" + +JobControl::JobControl(QObject* parent, JobView *jobView) + : Plasma::Service(parent), + m_jobView(jobView) +{ + setName("applicationjobs"); + setDestination(jobView->objectName()); +} + +Plasma::ServiceJob* JobControl::createJob(const QString& operation, + QMap& parameters) +{ + return new JobAction(m_jobView, operation, parameters, this); +} + +#include "jobcontrol.moc" + diff --git a/plasma/generic/dataengines/applicationjobs/jobcontrol.h b/plasma/generic/dataengines/applicationjobs/jobcontrol.h new file mode 100644 index 00000000..68c79824 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/jobcontrol.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef JOBCONTROL_H +#define JOBCONTROL_H + +#include + +class JobView; + +class JobControl : public Plasma::Service +{ + Q_OBJECT + + public: + JobControl(QObject* parent, JobView *jobview); + + protected: + Plasma::ServiceJob* createJob(const QString& operation, + QMap& parameters); + + private: + JobView *m_jobView; + +}; + +#endif // JOBCONTROL_H diff --git a/plasma/generic/dataengines/applicationjobs/kuiserverengine.cpp b/plasma/generic/dataengines/applicationjobs/kuiserverengine.cpp new file mode 100644 index 00000000..59a4de7f --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/kuiserverengine.cpp @@ -0,0 +1,380 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "jobviewadaptor.h" +#include "jobviewserveradaptor.h" +#include "kuiserverengine.h" +#include "jobcontrol.h" + +#include + +#include + +#include + + +uint JobView::s_jobId = 0; + +static const int UPDATE_INTERVAL = 100; + +JobView::JobView(QObject* parent) + : Plasma::DataContainer(parent), + m_capabilities(-1), + m_percent(0), + m_speed(0), + m_totalBytes(0), + m_processedBytes(0), + m_state(UnknownState), + m_bytesUnitId(-1), + m_unitId(0) +{ + m_jobId = ++s_jobId; + setObjectName(QString("Job %1").arg(s_jobId)); + + new JobViewV2Adaptor(this); + + m_objectPath.setPath(QString("/DataEngine/applicationjobs/JobView_%1").arg(m_jobId)); + QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this); + + setSuspended(false); +} + +JobView::~JobView() +{ + QDBusConnection::sessionBus().unregisterObject(m_objectPath.path(), QDBusConnection::UnregisterTree); +} + +uint JobView::jobId() const +{ + return m_jobId; +} + +void JobView::scheduleUpdate() +{ + if (!m_updateTimer.isActive()) { + m_updateTimer.start(UPDATE_INTERVAL, this); + } +} + +void JobView::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_updateTimer.timerId()) { + m_updateTimer.stop(); + checkForUpdate(); + + if (m_state == Stopped) { + emit becameUnused(objectName()); + } + } else { + Plasma::DataContainer::timerEvent(event); + } +} + +void JobView::terminate(const QString &errorMessage) +{ + setData("error", errorMessage); + QTimer::singleShot(0, this, SLOT(finished())); +} + +void JobView::finished() +{ + if (m_state != Stopped) { + m_state = Stopped; + setData("state", "stopped"); + setData("speed", QVariant()); + setData("numericSpeed", QVariant()); + scheduleUpdate(); + } +} + +JobView::State JobView::state() +{ + return m_state; +} + +void JobView::setSuspended(bool suspended) +{ + if (suspended) { + if (m_state != Suspended) { + m_state = Suspended; + setData("state", "suspended"); + setData("speed", QVariant()); + setData("numericSpeed", QVariant()); + scheduleUpdate(); + } + } else if (m_state != Running) { + m_state = Running; + setData("state", "running"); + setData("speed", speedString()); + setData("numericSpeed", m_speed); + scheduleUpdate(); + } +} + +int JobView::unitId(const QString &unit) +{ + int id = 0; + if (m_unitMap.contains(unit)) { + id = m_unitMap.value(unit); + } else { + id = m_unitId; + setData(QString("totalUnit%1").arg(id), unit); + setData(QString("totalAmount%1").arg(id), 0); + setData(QString("processedUnit%1").arg(id), unit); + setData(QString("processedAmount%1").arg(id), 0); + m_unitMap.insert(unit, m_unitId); + + if (unit == "bytes") { + m_bytesUnitId = id; + } + + ++m_unitId; + scheduleUpdate(); + } + + return id; +} + +void JobView::updateEta() +{ + if (m_speed < 1) { + setData("eta", 0); + return; + } + + if (m_totalBytes < 1) { + setData("eta", 0); + return; + } + + const qlonglong remaining = 1000 * (m_totalBytes - m_processedBytes); + setData("eta", remaining / m_speed); +} + +void JobView::setTotalAmount(qlonglong amount, const QString &unit) +{ + const int id = unitId(unit); + const QString amountString = QString("totalAmount%1").arg(id); + const qlonglong prevTotal = data().value(amountString).toLongLong(); + if (prevTotal != amount) { + if (id == m_bytesUnitId) { + m_totalBytes = amount; + updateEta(); + } + + setData(amountString, amount); + scheduleUpdate(); + } +} + +void JobView::setProcessedAmount(qlonglong amount, const QString &unit) +{ + const int id = unitId(unit); + const QString processedString = QString("processedAmount%1").arg(id); + const qlonglong prevTotal = data().value(processedString).toLongLong(); + if (prevTotal != amount) { + if (id == m_bytesUnitId) { + m_processedBytes = amount; + updateEta(); + } + + setData(processedString, amount); + scheduleUpdate(); + } +} + +void JobView::setDestUrl(const QDBusVariant & destUrl) +{ + Q_UNUSED(destUrl); +} + +void JobView::setPercent(uint percent) +{ + if (m_percent != percent) { + m_percent = percent; + setData("percentage", m_percent); + scheduleUpdate(); + } +} + +void JobView::setSpeed(qlonglong bytesPerSecond) +{ + if (m_speed != bytesPerSecond) { + m_speed = bytesPerSecond; + setData("speed", speedString()); + setData("numericSpeed", m_speed); + + if (m_bytesUnitId > -1) { + updateEta(); + } + + scheduleUpdate(); + } +} + +QString JobView::speedString() const +{ + return i18nc("Byes per second", "%1/s", KGlobal::locale()->formatByteSize(m_speed)); +} + +void JobView::setInfoMessage(const QString &infoMessage) +{ + if (data().value("infoMessage") != infoMessage) { + setData("infoMessage", infoMessage); + scheduleUpdate(); + } +} + +bool JobView::setDescriptionField(uint number, const QString &name, const QString &value) +{ + const QString labelString = QString("label%1").arg(number); + const QString labelNameString = QString("labelName%1").arg(number); + + if (!data().contains(labelNameString) || data().value(labelString) != value) { + setData(labelNameString, name); + setData(labelString, value); + scheduleUpdate(); + } + return true; +} + +void JobView::clearDescriptionField(uint number) +{ + const QString labelString = QString("label%1").arg(number); + const QString labelNameString = QString("labelName%1").arg(number); + + setData(labelNameString, QVariant()); + setData(labelString, QVariant()); + scheduleUpdate(); +} + +void JobView::setAppName(const QString &appName) +{ + // don't need to update, this is only set once at creation + setData("appName", appName); +} + +void JobView::setAppIconName(const QString &appIconName) +{ + // don't need to update, this is only set once at creation + setData("appIconName", appIconName); +} + +void JobView::setCapabilities(int capabilities) +{ + if (m_capabilities != uint(capabilities)) { + m_capabilities = capabilities; + setData("suspendable", m_capabilities & KJob::Suspendable); + setData("killable", m_capabilities & KJob::Killable); + scheduleUpdate(); + } +} + +QDBusObjectPath JobView::objectPath() const +{ + return m_objectPath; +} + +void JobView::requestStateChange(State state) +{ + switch (state) { + case Running: + emit resumeRequested(); + break; + case Suspended: + emit suspendRequested(); + break; + case Stopped: + emit cancelRequested(); + break; + default: + break; + } +} + +KuiserverEngine::KuiserverEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ + new JobViewServerAdaptor(this); + + QDBusConnection bus = QDBusConnection::sessionBus(); + bus.registerObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), this); + + setMinimumPollingInterval(500); + + m_pendingJobsTimer.setSingleShot(true); + m_pendingJobsTimer.setInterval(500); + connect(&m_pendingJobsTimer, SIGNAL(timeout()), this, SLOT(processPendingJobs())); +} + +KuiserverEngine::~KuiserverEngine() +{ + QDBusConnection::sessionBus() + .unregisterObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), QDBusConnection::UnregisterTree); + qDeleteAll(m_pendingJobs); +} + +QDBusObjectPath KuiserverEngine::requestView(const QString &appName, + const QString &appIconName, int capabilities) +{ + JobView *jobView = new JobView(this); + jobView->setAppName(appName); + jobView->setAppIconName(appIconName); + jobView->setCapabilities(capabilities); + connect(jobView, SIGNAL(becameUnused(QString)), this, SLOT(removeSource(QString))); + + m_pendingJobs << jobView; + m_pendingJobsTimer.start(); + + return jobView->objectPath(); +} + +void KuiserverEngine::processPendingJobs() +{ + foreach (JobView *jobView, m_pendingJobs) { + if (jobView->state() == JobView::Stopped) { + delete jobView; + } else { + addSource(jobView); + } + } + + m_pendingJobs.clear(); +} + +Plasma::Service* KuiserverEngine::serviceForSource(const QString& source) +{ + JobView *jobView = qobject_cast(containerForSource(source)); + if (jobView) { + return new JobControl(this, jobView); + } else { + return DataEngine::serviceForSource(source); + } +} + +void KuiserverEngine::init() +{ + // register with the Job UI Serer to receive notifications of jobs becoming available + QDBusInterface interface("org.kde.kuiserver", "/JobViewServer"/* object to connect to */, + ""/* use the default interface */, QDBusConnection::sessionBus(), this); + interface.asyncCall(QLatin1String("registerService"), QDBusConnection::sessionBus().baseService(), "/DataEngine/applicationjobs/JobWatcher"); +} + +K_EXPORT_PLASMA_DATAENGINE(kuiserver, KuiserverEngine) + +#include "kuiserverengine.moc" diff --git a/plasma/generic/dataengines/applicationjobs/kuiserverengine.h b/plasma/generic/dataengines/applicationjobs/kuiserverengine.h new file mode 100644 index 00000000..c03b0700 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/kuiserverengine.h @@ -0,0 +1,145 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KUISERVERENGINE_H +#define KUISERVERENGINE_H + +#include +#include +#include + +#include +#include + +class JobView; + +namespace Plasma +{ + class Service; +} // namespace Plasma + +class KuiserverEngine : public Plasma::DataEngine +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.JobViewServer") + +public: + KuiserverEngine(QObject* parent, const QVariantList& args); + ~KuiserverEngine(); + + void init(); + + QDBusObjectPath requestView(const QString &appName, const QString &appIconName, + int capabilities); + Plasma::Service* serviceForSource(const QString& source); + +private Q_SLOTS: + void processPendingJobs(); + +private: + QTimer m_pendingJobsTimer; + QList m_pendingJobs; +}; + +class JobView : public Plasma::DataContainer +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.JobViewV2") + +public: + enum State { + UnknownState = -1, + Running = 0, + Suspended = 1, + Stopped = 2 + }; + + JobView(QObject *parent = 0); + ~JobView(); + + uint jobId() const; + JobView::State state(); + + void setTotalAmount(qlonglong amount, const QString &unit); + QString totalAmountSize() const; + QString totalAmountFiles() const; + + void setProcessedAmount(qlonglong amount, const QString &unit); + + void setSpeed(qlonglong bytesPerSecond); + QString speedString() const; + + void setInfoMessage(const QString &infoMessage); + QString infoMessage() const; + + bool setDescriptionField(uint number, const QString &name, const QString &value); + void clearDescriptionField(uint number); + + void setAppName(const QString &appName); + void setAppIconName(const QString &appIconName); + void setCapabilities(int capabilities); + void setPercent(uint percent); + void setSuspended(bool suspended); + + //vestigal, required to implement this dbus interface + void setDestUrl(const QDBusVariant &destUrl); + + void terminate(const QString &errorMessage); + + QDBusObjectPath objectPath() const; + + void requestStateChange(State state); + +public Q_SLOTS: + void finished(); + +Q_SIGNALS: + void suspendRequested(); + void resumeRequested(); + void cancelRequested(); + +protected: + void timerEvent(QTimerEvent *event); + +private: + void scheduleUpdate(); + void updateEta(); + int unitId(const QString &unit); + + QDBusObjectPath m_objectPath; + QBasicTimer m_updateTimer; + + uint m_capabilities; + uint m_percent; + uint m_jobId; + + // for ETA calculation we cache these values + qlonglong m_speed; + qlonglong m_totalBytes; + qlonglong m_processedBytes; + + State m_state; + + QMap m_unitMap; + int m_bytesUnitId; + int m_unitId; + + static uint s_jobId; +}; + +#endif diff --git a/plasma/generic/dataengines/applicationjobs/plasma-dataengine-applicationjobs.desktop b/plasma/generic/dataengines/applicationjobs/plasma-dataengine-applicationjobs.desktop new file mode 100644 index 00000000..53c1b3c9 --- /dev/null +++ b/plasma/generic/dataengines/applicationjobs/plasma-dataengine-applicationjobs.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Application Job Information +Name[ar]=معلومات مهام التطبيقات +Name[ast]=Información de xera d'aplicación +Name[be@latin]=Źviestki pra zadańnie aplikacyi +Name[bs]=podaci o poslovima programâ +Name[ca]=Informació de les tasques de les aplicacions +Name[ca@valencia]=Informació de les tasques de les aplicacions +Name[cs]=Informace o práci aplikace +Name[csb]=Wëdowiédzô ò robòce aplikacëjów +Name[da]=Information om programjob +Name[de]=Anwendungsaufgaben-Informationen +Name[el]=Πληροφορίες εργασιών εφαρμογών +Name[en_GB]=Application Job Information +Name[eo]=Aplikaĵaj Taskaj Informoj +Name[es]=Información de tarea de aplicación +Name[et]=Rakenduste tööde teave +Name[eu]=Aplikazioko lanei buruzko informazioa +Name[fi]=Sovellustyötiedot +Name[fr]=Informations sur les tâches d'applications en cours d'exécution +Name[fy]=Programma taak ynformaasje +Name[ga]=Eolas Faoi Jabanna Feidhmchláir +Name[gl]=Información de tarefas de programa +Name[gu]=કાર્યક્રમ કાર્ય માહિતી +Name[he]=מידע אודות עבודת יישום +Name[hi]=अनुप्रयोग कार्य जानकारी +Name[hne]=अनुपरयोग काम सूचना +Name[hr]=Informacije o poslovima aplikacija +Name[hu]=Az alkalmazások jellemzői +Name[ia]=Information de travalio de application +Name[id]=Informasi Tugas Aplikasi +Name[is]=Tilkynningar um verkefni forrita +Name[it]=Informazioni sui processi delle applicazioni +Name[ja]=アプリケーションのジョブ情報 +Name[kk]=Қолданба тапсырмасының ақпараты +Name[km]=ព័ត៌មាន​ការងារ​របស់​កម្មវិធី +Name[kn]=ಅನ್ವಯ ಕಾರ್ಯ ಮಾಹಿತಿ +Name[ko]=프로그램 작업 정보 +Name[ku]=Agahiyên Karê Sepanê +Name[lt]=Programos darbo informacija +Name[lv]=Programmas darba informācija +Name[ml]=പ്രയോഗ ജോലി അറിയിപ്പുകള്‍ +Name[mr]=अनुप्रयोग कार्यविषयी माहिती +Name[nb]=Informasjon om programjobb +Name[nds]=Programm-Opgaavinformatschoon +Name[nl]=Programmataakmeldingen +Name[nn]=Informasjon om programjobb +Name[or]=ପ୍ରୟୋଗ କାର୍ଯ୍ୟ ସୂଚନା +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਜਾਬ ਜਾਣਕਾਰੀ +Name[pl]=Informacja o zadaniu programu +Name[pt]=Informação da Tarefa da Aplicação +Name[pt_BR]=Informações da tarefa do aplicativo +Name[ro]=Informație despre sarcina aplicației +Name[ru]=Системные уведомления +Name[si]=යෙදුම් කාර්‍යය තොරතුරු +Name[sk]=Informácie o aplikácii +Name[sl]=Opravila programov +Name[sr]=подаци о пословима програма̂ +Name[sr@ijekavian]=подаци о пословима програма̂ +Name[sr@ijekavianlatin]=podaci o poslovima programâ̂ +Name[sr@latin]=podaci o poslovima programâ̂ +Name[sv]=Information om programjobb +Name[ta]=பயன்பாட்டு பணி விவரம் +Name[tg]=Иттилооти корҳои барнома +Name[th]=ข้อมูลงานของโปรแกรม +Name[tr]=Uygulama Görev Bilgileri +Name[ug]=پروگرامما خىزمەت ئۇچۇرى +Name[uk]=Відомості про завдання програми +Name[vi]=Thông tin công việc ứng dụng +Name[wa]=Pondants et djondants so les bouyes des programes +Name[x-test]=xxApplication Job Informationxx +Name[zh_CN]=程序任务信息 +Name[zh_TW]=應用程式工作資訊 +Comment=Application job updates (via kuiserver) +Comment[ar]=تحديثات مهام التطبيقات (عن طريق kuiserver) +Comment[ast]=Anovamientos de l'aplicación (vía kuiserver) +Comment[bs]=Ažuriranja programskih poslova (preko KUI‑servera) +Comment[ca]=Actualització de treballs d'aplicacions (via kuiserver) +Comment[ca@valencia]=Actualització de treballs d'aplicacions (via kuiserver) +Comment[cs]=Aktualizace úloh aplikací (pomocí kuiserver) +Comment[da]=Jobopdateringer for program (via kuiserver) +Comment[de]=Aktualisierung von Anwendungs-Aktionen (via kuiserver) +Comment[el]=Ενημέρωση εργασιών εφαρμογών (μέσω kuiserver) +Comment[en_GB]=Application job updates (via kuiserver) +Comment[eo]=Apikaĵaj taskoj ĝisdatigitaj (per kuiserver) +Comment[es]=Actualizaciones de la aplicación (vía kuiserver) +Comment[et]=Rakenduse töö uuendused (kuiserver'i kaudu) +Comment[eu]=Aplikazioko lanen eguneratzeak (kuiserver bidez) +Comment[fi]=Sovellustyöpäivitykset (kuiserver-palvelimen kautta) +Comment[fr]=Mise à jours des tâches d'application (via « kuiserver ») +Comment[fy]=Applikaasje taak fernijing (mei kuiserver) +Comment[gl]=Actualización de tarefa do programa (mediante kuiserver) +Comment[he]=עידכוני עבודת יישום (באמצעות kuiserver) +Comment[hr]=Ažuriranja poslova aplikacija (preko kuiservera) +Comment[hu]=Feladatfrissítő (a kuiserveren keresztül) +Comment[ia]=Actualisationes de travalio de application (via kuiserver) +Comment[id]=Tugas aplikasi dimutakhirkan (via kuiserver) +Comment[is]=Uppfærslutilkynningar um verkefni forrita (með kuiserver) +Comment[it]=Aggiornamenti sui processi delle applicazioni (via kuiserver) +Comment[ja]=アプリケーションジョブ更新 (kuiserver 経由) +Comment[kk]=Қолданба тапсырмасын жаңарту (kuiserver арқылы) +Comment[km]=បច្ចុប្បន្នភាព​​ការងារ​របស់​កម្មវិធី (តាមរយៈ kuiserver) +Comment[kn]=ಅನ್ವಯ ಕಾರ್ಯ ಅಪ್‌ಡೇಟ್‌ಗಳು (kuiserver ಮೂಲಕ) +Comment[ko]=프로그램 작업 업데이트 (kuiserver를 통하여) +Comment[lt]=Programų darbų atnaujinimai (per kuiserver) +Comment[lv]=Programmas darba atjauninājumu (izm. kuiserver) +Comment[mai]=अनुप्रयोग कार्य अद्यतन (kuiserver के द्वारा) +Comment[ml]=പ്രയോഗ ജോലിയിലെ മാറ്റങ്ങള്‍ (കൂയിസെര്‍വര്‍ വഴി) +Comment[mr]=अनुप्रयोग कार्य अद्ययावत माहिती (kuiserver द्वारे) +Comment[nb]=Programjobb-oppdateringer (via kuiserver) +Comment[nds]=Programmopgaav-Opfrischen (över »kuiserver«) +Comment[nl]=Applicatiejob bijwerken (via kuiserver) +Comment[nn]=Oppdateringar for programjobbar (gjennom kuiserver) +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ ਜਾਬ ਅੱਪਡੇਟ (kuiserver ਰਾਹੀਂ) +Comment[pl]=Uaktualnienia zadań programu (przez kuiserver) +Comment[pt]=Actualizações das tarefas da aplicação (através do 'kuiserver') +Comment[pt_BR]=Atualizações de tarefas de aplicativos (via kuiserver) +Comment[ro]=Actualizări pentru sarcina aplicației (via kuiserver) +Comment[ru]=Обновление заданий приложений (с помощью диспетчера заданий) +Comment[si]=යෙදුම් කාර්‍ය යාවත්කාලීන (kuiserver වෙතින්) +Comment[sk]=Aktualizácie úloh aplikácií (pomocou kuiserver) +Comment[sl]=Obveščanje o opravilih programov (prek KUIServer) +Comment[sr]=Ажурирања програмских послова (преко КУИ‑сервера) +Comment[sr@ijekavian]=Ажурирања програмских послова (преко КУИ‑сервера) +Comment[sr@ijekavianlatin]=Ažuriranja programskih poslova (preko KUIServera) +Comment[sr@latin]=Ažuriranja programskih poslova (preko KUIServera) +Comment[sv]=Uppdateringar av information om programjobb (via kuiserver) +Comment[tg]=Иттилооти амалҳои система (via kuiserver) +Comment[th]=ปรับปรุงงานของโปรแกรม (ผ่านทาง kuiserver) +Comment[tr]=Uygulama görevi güncellemeleri (kuiserver ile) +Comment[ug]=پروگرامما ۋەزىپىسى يېڭىلاندى(kuiserver ئارقىلىق) +Comment[uk]=Оновлення завдань програми (через kuiserver) +Comment[wa]=Metaedjes a djoû des bouyes des programes (via kuiserver) +Comment[x-test]=xxApplication job updates (via kuiserver)xx +Comment[zh_CN]=提供程序任务更新信息(通过 kuiserver) +Comment[zh_TW]=應用程式工作更新(透過 kuiserver) +Type=Service +X-KDE-ServiceTypes=Plasma/DataEngine +Icon=tool-animator +X-KDE-Library=plasma_engine_applicationjobs + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=applicationjobs +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= diff --git a/plasma/generic/dataengines/apps/CMakeLists.txt b/plasma/generic/dataengines/apps/CMakeLists.txt new file mode 100644 index 00000000..05d139cb --- /dev/null +++ b/plasma/generic/dataengines/apps/CMakeLists.txt @@ -0,0 +1,13 @@ +set(apps_engine_SRCS + appsengine.cpp + appsource.cpp + appservice.cpp + appjob.cpp +) + +kde4_add_plugin(plasma_engine_apps ${apps_engine_SRCS}) +target_link_libraries(plasma_engine_apps ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_engine_apps DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-apps.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES apps.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/plasma/generic/dataengines/apps/appjob.cpp b/plasma/generic/dataengines/apps/appjob.cpp new file mode 100644 index 00000000..3a91b1e4 --- /dev/null +++ b/plasma/generic/dataengines/apps/appjob.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "appjob.h" + +#include + +AppJob::AppJob(AppSource *source, const QString &operation, QMap ¶meters, QObject *parent) : + ServiceJob(source->objectName(), operation, parameters, parent), + m_source(source) +{ +} + +AppJob::~AppJob() +{ +} + +void AppJob::start() +{ + const QString operation = operationName(); + if (operation == "launch") { + QString path = m_source->getApp()->entryPath(); + new KRun(KUrl(path), 0); + setResult(true); + return; + } + setResult(false); +} + +#include "appjob.moc" diff --git a/plasma/generic/dataengines/apps/appjob.h b/plasma/generic/dataengines/apps/appjob.h new file mode 100644 index 00000000..2d59aec1 --- /dev/null +++ b/plasma/generic/dataengines/apps/appjob.h @@ -0,0 +1,45 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKJOB_H +#define TASKJOB_H + +// plasma +#include + +// own +#include "appsource.h" + +class AppJob : public Plasma::ServiceJob +{ + + Q_OBJECT + + public: + AppJob(AppSource *source, const QString &operation, QMap ¶meters, QObject *parent = 0); + ~AppJob(); + + protected: + void start(); + + private: + AppSource *m_source; + +}; + +#endif // TASKJOB_H diff --git a/plasma/generic/dataengines/apps/apps.operations b/plasma/generic/dataengines/apps/apps.operations new file mode 100644 index 00000000..837549f8 --- /dev/null +++ b/plasma/generic/dataengines/apps/apps.operations @@ -0,0 +1,5 @@ + + + + + diff --git a/plasma/generic/dataengines/apps/appsengine.cpp b/plasma/generic/dataengines/apps/appsengine.cpp new file mode 100644 index 00000000..340705c0 --- /dev/null +++ b/plasma/generic/dataengines/apps/appsengine.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "appsengine.h" +#include "appsource.h" + +#include + +AppsEngine::AppsEngine(QObject *parent, const QVariantList &args) : + Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args); +} + +AppsEngine::~AppsEngine() +{ +} + +void AppsEngine::init() +{ + addGroup(KServiceGroup::root()); + connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(QStringList))); +} + +void AppsEngine::sycocaChanged(const QStringList &changes) +{ + if (changes.contains("apps") || changes.contains("xdgdata-apps")) { + removeAllSources(); + addGroup(KServiceGroup::root()); + } +} + +Plasma::Service *AppsEngine::serviceForSource(const QString &name) +{ + AppSource *source = dynamic_cast(containerForSource(name)); + // if source does not exist, return null service + if (!source) { + return Plasma::DataEngine::serviceForSource(name); + } + + // if source represents a group or something, return null service + if (!source->isApp()) { + return Plasma::DataEngine::serviceForSource(name); + } + // if source represent a proper app, return real service + Plasma::Service *service = source->createService(); + service->setParent(this); + return service; +} + +void AppsEngine::addGroup(KServiceGroup::Ptr group) +{ + if (!(group && group->isValid())) { + return; + } + AppSource *appSource = new AppSource(group, this); + //TODO listen for changes + addSource(appSource); + //do children + foreach (const KServiceGroup::Ptr subGroup, group->groupEntries(KServiceGroup::NoOptions)) { + addGroup(subGroup); + } + foreach (const KService::Ptr app, group->serviceEntries(KServiceGroup::NoOptions)) { + addApp(app); + } +} + +void AppsEngine::addApp(KService::Ptr app) +{ + AppSource *appSource = new AppSource(app, this); + //TODO listen for changes + addSource(appSource); +} + +K_EXPORT_PLASMA_DATAENGINE(apps, AppsEngine) + +#include "appsengine.moc" diff --git a/plasma/generic/dataengines/apps/appsengine.h b/plasma/generic/dataengines/apps/appsengine.h new file mode 100644 index 00000000..d19b4a11 --- /dev/null +++ b/plasma/generic/dataengines/apps/appsengine.h @@ -0,0 +1,66 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSENGINE_H +#define TASKSENGINE_H + +// plasma +#include +#include + +#include +#include + +/** + * Apps Data Engine + * + * FIXME + * This engine provides information regarding tasks (windows that are currently open) + * as well as startup tasks (windows that are about to open). + * Each task and startup is represented by a unique source. Sources are added and removed + * as windows are opened and closed. You cannot request a customized source. + * + * A service is also provided for each task. It exposes some operations that can be + * performed on the windows (ex: maximize, minimize, activate). + * + * The data and operations are provided and handled by the taskmanager library. + * It should be noted that only a subset of data and operations are exposed. + */ +class AppsEngine : public Plasma::DataEngine +{ + + Q_OBJECT + + public: + AppsEngine(QObject *parent, const QVariantList &args); + ~AppsEngine(); + Plasma::Service *serviceForSource(const QString &name); + + protected: + virtual void init(); + + private slots: + void sycocaChanged(const QStringList &changes); + + private: + friend class AppSource; + void addGroup(KServiceGroup::Ptr group); + void addApp(KService::Ptr app); +}; + +#endif // TASKSENGINE_H diff --git a/plasma/generic/dataengines/apps/appservice.cpp b/plasma/generic/dataengines/apps/appservice.cpp new file mode 100644 index 00000000..adf1240b --- /dev/null +++ b/plasma/generic/dataengines/apps/appservice.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "appservice.h" + +// own +#include "appjob.h" + +AppService::AppService(AppSource *source) : + Plasma::Service(source), + m_source(source) +{ + setName("apps"); +} + +AppService::~AppService() +{ +} + +Plasma::ServiceJob *AppService::createJob(const QString &operation, QMap ¶meters) +{ + return new AppJob(m_source, operation, parameters, this); +} + +#include "appservice.moc" diff --git a/plasma/generic/dataengines/apps/appservice.h b/plasma/generic/dataengines/apps/appservice.h new file mode 100644 index 00000000..cd6e4f6c --- /dev/null +++ b/plasma/generic/dataengines/apps/appservice.h @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSERVICE_H +#define TASKSERVICE_H + +// plasma +#include +#include + +// own +#include "appsource.h" + +/** + * App Service + */ +class AppService : public Plasma::Service +{ + + Q_OBJECT + + public: + AppService(AppSource *source); + ~AppService(); + + protected: + Plasma::ServiceJob *createJob(const QString &operation, QMap ¶meters); + + private: + AppSource *m_source; +}; + +#endif // TASKSERVICE_H diff --git a/plasma/generic/dataengines/apps/appsource.cpp b/plasma/generic/dataengines/apps/appsource.cpp new file mode 100644 index 00000000..0596a452 --- /dev/null +++ b/plasma/generic/dataengines/apps/appsource.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "appsource.h" +#include "appsengine.h" +#include "appservice.h" + +#include + +AppSource::AppSource(KServiceGroup::Ptr group, QObject *parent) : + Plasma::DataContainer(parent), + m_group(group), + m_app(), + m_isApp(false) +{ + setObjectName(m_group->entryPath()); + setData("isApp", false); + updateGroup(); +} + +AppSource::AppSource(KService::Ptr app, QObject *parent) : + Plasma::DataContainer(parent), + m_group(), + m_app(app), + m_isApp(true) +{ + setObjectName(m_app->storageId()); + setData("isApp", true); + updateApp(); +} + +AppSource::~AppSource() +{ +} + +Plasma::Service *AppSource::createService() +{ + return new AppService(this); +} + +KService::Ptr AppSource::getApp() +{ + return m_app; +} + +bool AppSource::isApp() const +{ + return m_isApp; +} + +void AppSource::updateGroup() +{ + setData("iconName", m_group->icon()); + setData("name", m_group->caption()); + setData("comment", m_group->comment()); + setData("display", !m_group->noDisplay()); + + QStringList entries; + foreach (KSycocaEntry::Ptr p, m_group->entries(true, false, true)) { + if (p->isType(KST_KService)) { + const KService::Ptr service = KService::Ptr::staticCast(p); + entries << service->storageId(); + } else if (p->isType(KST_KServiceGroup)) { + const KServiceGroup::Ptr service = KServiceGroup::Ptr::staticCast(p); + entries << service->entryPath(); + } else if (p->isType(KST_KServiceSeparator)) { + entries << "---"; + } else { + kDebug() << "unexpected object in entry list"; + } + } + setData("entries", entries); + + checkForUpdate(); +} + +void AppSource::updateApp() +{ + setData("iconName", m_app->icon()); + setData("name", m_app->name()); + setData("genericName", m_app->genericName()); + setData("menuId", m_app->menuId()); + setData("entryPath", m_app->entryPath()); + setData("comment", m_app->comment()); + setData("keywords", m_app->keywords()); + setData("categories", m_app->categories()); + setData("display", !m_app->noDisplay()); + checkForUpdate(); +} + +#include "appsource.moc" diff --git a/plasma/generic/dataengines/apps/appsource.h b/plasma/generic/dataengines/apps/appsource.h new file mode 100644 index 00000000..92fc3c8e --- /dev/null +++ b/plasma/generic/dataengines/apps/appsource.h @@ -0,0 +1,59 @@ +/* + * Copyright 2009 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSOURCE_H +#define TASKSOURCE_H + +// plasma +#include + +#include +#include + +/** + * App Source + */ +class AppSource : public Plasma::DataContainer +{ + + Q_OBJECT + + public: + AppSource(KServiceGroup::Ptr startup, QObject *parent); + AppSource(KService::Ptr app, QObject *parent); + ~AppSource(); + + protected: + Plasma::Service *createService(); + KService::Ptr getApp(); + bool isApp() const; + + private slots: + void updateGroup(); + void updateApp(); + + private: + friend class AppsEngine; + friend class AppJob; + KServiceGroup::Ptr m_group; + KService::Ptr m_app; + bool m_isApp; + +}; + +#endif // TASKSOURCE_H diff --git a/plasma/generic/dataengines/apps/plasma-dataengine-apps.desktop b/plasma/generic/dataengines/apps/plasma-dataengine-apps.desktop new file mode 100644 index 00000000..0302e3a0 --- /dev/null +++ b/plasma/generic/dataengines/apps/plasma-dataengine-apps.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Application Information +Name[ar]=معلومات التطبيقات +Name[ast]=Información de l'aplicación +Name[bn]=অ্যাপলিকেশন তথ্য +Name[bs]=podaci o programima +Name[ca]=Informació de les aplicacions +Name[ca@valencia]=Informació de les aplicacions +Name[cs]=Informace o aplikaci +Name[csb]=Wëdowiédzô ò aplikacëji +Name[da]=Programinformation +Name[de]=Anwendungsinformationen +Name[el]=Πληροφορίες εφαρμογών +Name[en_GB]=Application Information +Name[eo]=Aplikaĵaj Informoj +Name[es]=Información de la aplicación +Name[et]=Rakenduse teave +Name[eu]=Aplikazioari buruzko informazioa +Name[fi]=Sovellustiedot +Name[fr]=Informations sur l'application +Name[fy]=Applikaasje ynformaasje +Name[ga]=Eolas faoi Fheidhmchláir +Name[gl]=Información do programa +Name[gu]=કાર્યક્રમ માહિતી +Name[he]=מידע אודות יישום +Name[hi]=अनुप्रयोग जानकारी +Name[hr]=Informacije o aplikacijama +Name[hu]=Az alkalmazások jellemzői +Name[ia]=Information de application +Name[id]=Informasi Aplikasi +Name[is]=Upplýsingar um forrit +Name[it]=Informazioni sulle applicazioni +Name[ja]=アプリケーションの情報 +Name[kk]=Қолданбаның ақпараты +Name[km]=ព័ត៌មាន​កម្មវិធី +Name[kn]=ಅನ್ವಯ ಮಾಹಿತಿ +Name[ko]=프로그램 정보 +Name[lt]=Programos informacija +Name[lv]=Programmas informācija +Name[mk]=Информации за апликации +Name[ml]=പ്രയോഗ വിവരം +Name[mr]=अनुप्रयोग माहिती +Name[nb]=Informasjon om program +Name[nds]=Programm-Informatschoon +Name[nl]=Programmainformatie +Name[nn]=Programinformasjon +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਜਾਣਕਾਰੀ +Name[pl]=Informacja o programie +Name[pt]=Informação da Aplicação +Name[pt_BR]=Informações do aplicativo +Name[ro]=Informații despre aplicații +Name[ru]=Информация о приложениях +Name[si]=යෙදුම් තොරතුරු +Name[sk]=Informácie o aplikácii +Name[sl]=Podatki o programih +Name[sr]=подаци о програмима +Name[sr@ijekavian]=подаци о програмима +Name[sr@ijekavianlatin]=podaci o programima +Name[sr@latin]=podaci o programima +Name[sv]=Information om program +Name[tg]=Иттилооти барнома +Name[th]=ข้อมูลของโปรแกรม +Name[tr]=Uygulama Bilgileri +Name[ug]=پروگرامما ئۇچۇرى +Name[uk]=Відомості щодо програм +Name[vi]=Thông tin ứng dụng +Name[wa]=Pondants et djondants do programe +Name[x-test]=xxApplication Informationxx +Name[zh_CN]=程序信息 +Name[zh_TW]=應用程式資訊 +Comment=Information and launching of all applications in the app menu. +Comment[ar]=معلومات وتشغيل جميع البرامج في قائمة البرامج +Comment[ast]=Información y execución de toles aplicaciones nel menú d'aplicaciones. +Comment[bs]=Podaci o programima iz programskog menija i njihovo pokretanje. +Comment[ca]=Informació i execució de totes les aplicacions en el menú d'aplicacions. +Comment[ca@valencia]=Informació i execució de totes les aplicacions en el menú d'aplicacions. +Comment[cs]=Informace a spouštění všech aplikací v nabídce aplikací. +Comment[da]=Information og opstart af alle programmer i programmenuen. +Comment[de]=Informationen und Starten aller Anwendungen im Programmmenü. +Comment[el]=Πληροφορίες και εκτέλεση όλων των εφαρμογών στο μενού εφαρμογών. +Comment[en_GB]=Information and launching of all applications in the app menu. +Comment[es]=Información y ejecución de todas las aplicaciones en el menú de aplicaciones. +Comment[et]=Kõigi rakenduste menüü rakenduste teave ja käivitamine. +Comment[eu]=Aplikazio-menuko aplikazio guztiei buruzko informazioa eta haien abiaraztea. +Comment[fi]=Tietoja ja kaikkien sovellusten käynnistäminen sovellusvalikossa. +Comment[fr]=Informations et démarrage de toutes les applications du menu des applications. +Comment[fy]=Ynformaasje en útfiere fan alle applikaasjes yn it app menu. +Comment[gl]=Información e inicio de todos os programas do menú. +Comment[he]=מידע והפעלה של כל היישומים בתפריט היישומים. +Comment[hr]=Informacije i pokretanja od svih aplikacija u izborniku aplikacija. +Comment[hu]=Az alkalmazásmenü alkalmazásainak indítása és jellemzőinek megjelenítése. +Comment[ia]=Information e lanceamento de omne applicationes in le menu de app +Comment[id]=Informasi dan meluncurkan semua aplikasi di menu aplikasi. +Comment[is]=Upplýsingar um og ræsing allra forrita í forritavalmyndinni. +Comment[it]=Informazioni e avvio di tutte le applicazioni nel loro menu. +Comment[ja]=アプリケーションメニューのすべてのアプリケーション用の情報・起動サービスです。 +Comment[kk]=Қолданбаның мәзірінен барлық қолданбаларды жегу және олардын ақпараттары. +Comment[km]=ព័ត៌មាន និង​ការ​ចាប់ផ្ដើម​កម្មវិធី​ទាំងអស់​នៅ​ក្នុង​ម៉ឺនុយ​កម្មវិធី ។ +Comment[kn]=App ಮೆನುವಿನಲ್ಲಿರುವ ಎಲ್ಲಾ ಅನ್ವಯಗಳ ಬಗೆಗಿನ ಮಾಹಿತಿ ಹಾಗು ಪ್ರಕ್ಷೇಪಣೆ(ಲಾಂಚಿಂಗ್). +Comment[ko]=프로그램 메뉴의 정보를 보고 실행할 수 있도록 합니다. +Comment[lt]=Programų leistukai ir informacija iš programų meniu. +Comment[lv]=Visu programmu informācija un palaišana programmu izvēlnē. +Comment[mk]=Информации и стартување на сите апликации од менито за апликации +Comment[ml]=ആപ്പ് മെനുവിലെ പ്രയോഗങ്ങളുടെ വിവരവും തുടക്കവും. +Comment[mr]=अनुप्रयोग मेन्यू मधील अनुप्रयोगांची माहिती व प्रक्षेपण +Comment[nb]=Informasjon og oppstart av alle programmer i programmenyen. +Comment[nds]=Infos över un opropen vun all Programmen binnen dat Programmmenü +Comment[nl]=Informatie en starten van alle programma's in het progmenu. +Comment[nn]=Informasjon og køyring av alle programma i programmenyen. +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ ਮੇਨ ਵਿੱਚ ਸਭ ਐਪਲੀਕੇਸ਼ਨਾਂ ਲਈ ਜਾਣਕਾਰੀ ਅਤੇ ਚਲਾਉਣਾ। +Comment[pl]=Uruchamianie dowolnych programów z menu i informacja o nich. +Comment[pt]=Informação e lançamento de todas as aplicações no menu de aplicações. +Comment[pt_BR]=Informação e inicialização de todos os aplicativos no menu de aplicativos. +Comment[ro]=Informații și lansare de aplicații în meniul aplicațiilor. +Comment[ru]=Информация и запуск всех приложений из меню приложений. +Comment[si]=යෙදුම් මෙනුවේ ඇති සියළු යෙදුම් ආරම්භ කිරීමේ තොරතුරු +Comment[sk]=Informácie a spúšťanie všetkých aplikácií v menu aplikácie. +Comment[sl]=Podatki o vseh programih v meniju in njihovo zaganjanje +Comment[sr]=Подаци о програмима из програмског менија и њихово покретање. +Comment[sr@ijekavian]=Подаци о програмима из програмског менија и њихово покретање. +Comment[sr@ijekavianlatin]=Podaci o programima iz programskog menija i njihovo pokretanje. +Comment[sr@latin]=Podaci o programima iz programskog menija i njihovo pokretanje. +Comment[sv]=Information om och start av alla program i programmenyn. +Comment[tg]=Иттилоот ва оғозии ҳамаи барномаҳо аз меню. +Comment[th]=ข้อมูลและการเรียกใช้โปรแกรมทั้งหมดที่อยู่ในเมนูโปรแกรม +Comment[tr]=Uygulama menüsündeki tüm uygulamalar hakkında bilgiler ve uygulamaları çalıştırma. +Comment[ug]=ئۇچۇر كۆرسىتىدۇ ياكى تىزىملىكتىكى ھەممە پروگراممىلارنى ئىجرا قىلىدۇ +Comment[uk]=Відомості і запуск всіх програма з меню програм. +Comment[vi]=Thông tin và khởi chạy tất cả các ứng dụng trong trình đơn ứng dụng. +Comment[wa]=Informåcions eyet enondaedje di tos les programes del dressêye des programes. +Comment[x-test]=xxInformation and launching of all applications in the app menu.xx +Comment[zh_CN]=显示信息或启动菜单中的所有应用程序。 +Comment[zh_TW]=列出資訊或啟動選單中所有應用程式 +Type=Service +Icon=user-desktop + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_apps + +X-KDE-PluginInfo-Author=Chani +X-KDE-PluginInfo-Email=chani@kde.org +X-KDE-PluginInfo-Name=apps +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/calendar/CMakeLists.txt b/plasma/generic/dataengines/calendar/CMakeLists.txt new file mode 100644 index 00000000..6ad3b610 --- /dev/null +++ b/plasma/generic/dataengines/calendar/CMakeLists.txt @@ -0,0 +1,44 @@ +project(calendar_engine) + +include_directories( + ${KDEPIMLIBS_INCLUDE_DIRS} + ${Boost_INCLUDE_DIR} +) + +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + +set(calendar_engine_srcs + calendarengine.cpp +) + +if(Akonadi_FOUND) + ADD_DEFINITIONS(-DAKONADI_FOUND) + set(calendar_engine_srcs ${calendar_engine_srcs} + eventdatacontainer.cpp + ) +endif(Akonadi_FOUND) + +kde4_add_plugin(plasma_engine_calendar ${calendar_engine_srcs}) + +target_link_libraries( + plasma_engine_calendar + ${KDEPIMLIBS_KHOLIDAYS_LIBRARY} + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + ${KDE4_KMIME_LIBS} + ${KDE4_KCALCORE_LIBS} + ${KDE4_KCALUTILS_LIBS} +) + +if(Akonadi_FOUND) + target_link_libraries( + plasma_engine_calendar + akonadi-calendar + ${KDE4_AKONADI_LIBS} + ${KDEPIMLIBS_AKONADI_KCAL_LIBS} + ) +endif(Akonadi_FOUND) + +install(TARGETS plasma_engine_calendar DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-calendar.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/calendar/Messages.sh b/plasma/generic/dataengines/calendar/Messages.sh new file mode 100755 index 00000000..9a5efa3c --- /dev/null +++ b/plasma/generic/dataengines/calendar/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp` -o $podir/plasma_engine_calendar.pot diff --git a/plasma/generic/dataengines/calendar/calendar.operations b/plasma/generic/dataengines/calendar/calendar.operations new file mode 100644 index 00000000..b429b8f2 --- /dev/null +++ b/plasma/generic/dataengines/calendar/calendar.operations @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/calendar/calendarengine.cpp b/plasma/generic/dataengines/calendar/calendarengine.cpp new file mode 100644 index 00000000..5b98d8a0 --- /dev/null +++ b/plasma/generic/dataengines/calendar/calendarengine.cpp @@ -0,0 +1,314 @@ +/* + Copyright (c) 2009 Davide Bettio + Copyright (c) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + +#include "calendarengine.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef AKONADI_FOUND +#include "eventdatacontainer.h" +#endif + +CalendarEngine::CalendarEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent) +{ + Q_UNUSED(args); +} + +CalendarEngine::~CalendarEngine() +{ + qDeleteAll(m_regions); +} + +bool CalendarEngine::sourceRequestEvent(const QString &request) +{ + kDebug() << "Request = " << request << '\n'; + + if (request.isEmpty()) { + return false; + } + + QStringList requestTokens = request.split(':'); + QString requestKey = requestTokens.takeFirst(); + + if (requestKey == "holidaysRegions" || + requestKey == "holidaysRegion" || + requestKey == "holidaysDefaultRegion" || + requestKey == "holidaysIsValidRegion" || + requestKey == "holidays" || + requestKey == "holidaysInMonth") { + return holidayCalendarSourceRequest(requestKey, requestTokens, request); + } + +#ifdef AKONADI_FOUND + if (requestKey == "events" || requestKey == "eventsInMonth") { + return akonadiCalendarSourceRequest(requestKey, requestTokens, request); + } +#endif + + return false; +} + +bool CalendarEngine::holidayCalendarSourceRequest(const QString& key, const QStringList& args, const QString& request) +{ + if (key == "holidaysRegions") { + QStringList regionList = KHolidays::HolidayRegion::regionCodes(); + Plasma::DataEngine::Data data; + foreach (const QString ®ionCode, regionList) { + Plasma::DataEngine::Data regionData; + KHolidays::HolidayRegion region(regionCode); + regionData.insert("Name", region.name()); + regionData.insert("Description", region.description()); + regionData.insert("CountryCode", region.countryCode()); + regionData.insert("Location", region.location()); + regionData.insert("LanguageCode", region.languageCode()); + data.insert(regionCode, regionData); + } + setData(request, data); + return true; + } + + if (key == "holidaysDefaultRegion") { + // If not set or the locale has changed since last set, then try determine a default region. + if(m_defaultHolidayRegion.isEmpty() || + m_defaultHolidayRegionCountry != KGlobal::locale()->country() || + m_defaultHolidayRegionLanguage != KGlobal::locale()->language()) { + + m_defaultHolidayRegion = QString(); + m_defaultHolidayRegionCountry = KGlobal::locale()->country(); + m_defaultHolidayRegionLanguage = KGlobal::locale()->language(); + + m_defaultHolidayRegion = KHolidays::HolidayRegion::defaultRegionCode( + m_defaultHolidayRegionCountry.toLower(), + m_defaultHolidayRegionLanguage.toLower() ); + if (m_defaultHolidayRegion.isEmpty()) { + m_defaultHolidayRegion = "NoDefault"; + } + } + + if (m_defaultHolidayRegion == "NoDefault") { + setData(request, QString()); + } else { + setData(request, m_defaultHolidayRegion); + } + return true; + } + + + int argsCount = args.count(); + if (argsCount < 1) { + return false; + } + + const QStringList regionCodeList = args.at(0).split(','); + if (regionCodeList.count() < 1) { + return false; + } + + foreach ( const QString ®ionCode, regionCodeList ) { + KHolidays::HolidayRegion *region = m_regions.value(regionCode); + if (!region || !region->isValid()) { + region = new KHolidays::HolidayRegion(regionCode); + if (region->isValid()) { + m_regions.insert(regionCode, region); + } else { + delete region; + return false; + } + } + } + + if (key == "holidaysIsValidRegion") { + if (regionCodeList.count() > 1) { + return false; + } + QString regionCode = regionCodeList.at(0); + if (m_regions.contains(regionCode)) { + setData(request, m_regions.value(regionCode)->isValid()); + } else { + setData(request, KHolidays::HolidayRegion::isValid(regionCode)); + } + return true; + } + + if (key == "holidaysRegion") { + Plasma::DataEngine::Data data; + foreach (const QString ®ionCode, regionCodeList) { + Plasma::DataEngine::Data regionData; + KHolidays::HolidayRegion *region = m_regions.value(regionCode); + regionData.insert("Name", region->name()); + regionData.insert("Description", region->description()); + regionData.insert("CountryCode", region->countryCode()); + regionData.insert("Location", region->location()); + regionData.insert("LanguageCode", region->languageCode()); + data.insert(regionCode, regionData); + } + setData(request, data); + return true; + } + + if (argsCount < 2) { + return false; + } + + QDate dateArg = QDate::fromString(args.at(1), Qt::ISODate); + if (!dateArg.isValid()) { + return false; + } + + if (key == "holidaysInMonth" || key == "holidays") { + QDate startDate, endDate; + if (key == "holidaysInMonth") { + int requestYear, requestMonth; + KGlobal::locale()->calendar()->getDate(dateArg, &requestYear, &requestMonth, 0); + int lastDay = KGlobal::locale()->calendar()->daysInMonth(dateArg); + KGlobal::locale()->calendar()->setDate(startDate, requestYear, requestMonth, 1); + KGlobal::locale()->calendar()->setDate(endDate, requestYear, requestMonth, lastDay); + } else if (argsCount == 2) { + startDate = dateArg; + endDate = dateArg; + } else if (argsCount < 3) { + return false; + } else { + startDate = dateArg; + endDate = QDate::fromString(args.at(2), Qt::ISODate); + } + + if (!startDate.isValid() || !endDate.isValid()) { + return false; + } + + QList holidayList; + foreach ( const QString ®ionCode, regionCodeList ) { + KHolidays::HolidayRegion *region = m_regions.value(regionCode); + KHolidays::Holiday::List holidays; + holidays = region->holidays(startDate, endDate, KHolidays::Holiday::MultidayHolidaysAsSingleEvents); + + foreach (const KHolidays::Holiday &holiday, holidays) { + if (!holiday.text().isEmpty()) { + Plasma::DataEngine::Data holidayData; + holidayData.insert("Name", holiday.text()); + holidayData.insert("RegionCode", regionCode); + holidayData.insert("ObservanceStartDate", holiday.observedStartDate().toString(Qt::ISODate)); + holidayData.insert("ObservanceEndDate", holiday.observedEndDate().toString(Qt::ISODate)); + holidayData.insert("ObservanceDuration", holiday.duration()); + // It's a blunt tool for now, we only know if it's a full public holiday or not + if ( holiday.dayType() == KHolidays::Holiday::NonWorkday ) { + holidayData.insert("ObservanceType", "PublicHoliday"); + } else { + holidayData.insert("ObservanceType", "Other"); + } + holidayList.append(QVariant(holidayData)); + } + } + } + + setData(request, QVariant(holidayList)); + return true; + } + + if (key == "isHoliday") { + bool isHoliday = false; + foreach ( const QString ®ionCode, regionCodeList ) { + KHolidays::HolidayRegion *region = m_regions.value(regionCode); + if (region->isHoliday(dateArg)) { + isHoliday = true; + } + } + setData(request, isHoliday); + return true; + } + + if (key == "description") { + QString summary; + foreach ( const QString ®ionCode, regionCodeList ) { + KHolidays::HolidayRegion *region = m_regions.value(regionCode); + KHolidays::Holiday::List holidays; + holidays = region->holidays(dateArg, KHolidays::Holiday::MultidayHolidaysAsSingleEvents); + foreach (const KHolidays::Holiday &holiday, holidays) { + if (!summary.isEmpty()) { + summary.append("\n"); + } + summary.append(holiday.text()); + } + } + + setData(request, summary); + return true; + } + + return false; +} + +#ifdef AKONADI_FOUND +bool CalendarEngine::akonadiCalendarSourceRequest(const QString& key, const QStringList& args, const QString& request) +{ + // figure out what time range was requested from the source string + QDate start; + QDate end; + if (key == "eventsInMonth") { + if (args.count() < 1) { + return false; + } + start = QDate::fromString(args.at(0), Qt::ISODate); + start.setDate(start.year(), start.month(), 1); + end = QDate(start.year(), start.month(), start.daysInMonth()); + } else if (key == "events") { + if (args.count() == 1) { + start = QDate::fromString(args.at(0), Qt::ISODate); + end = start.addDays(1); + } else { + if (args.count() < 2) { + return false; + } + start = QDate::fromString(args.at(0), Qt::ISODate); + end = QDate::fromString(args.at(1), Qt::ISODate); + } + } else { + return false; + } + + if (!start.isValid() || !end.isValid()) { + return false; + } + + if (!m_calendar) { + m_calendar = Akonadi::ETMCalendar::Ptr(new Akonadi::ETMCalendar()); + m_calendar->setCollectionFilteringEnabled(false); + } + + // create the corresponding EventDataContainer + addSource(new EventDataContainer(m_calendar, request, KDateTime(start, QTime(0, 0, 0)), KDateTime(end, QTime(23, 59, 59)))); + return true; +} + +#endif // AKONADI_FOUND + +#include "calendarengine.moc" diff --git a/plasma/generic/dataengines/calendar/calendarengine.h b/plasma/generic/dataengines/calendar/calendarengine.h new file mode 100644 index 00000000..21ad533e --- /dev/null +++ b/plasma/generic/dataengines/calendar/calendarengine.h @@ -0,0 +1,180 @@ +/* + Copyright (c) 2009 Davide Bettio + Copyright (c) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + +#ifndef CALENDARENGINE_H +#define CALENDARENGINE_H + +#include + +#ifdef AKONADI_FOUND +# include +#endif + +namespace KHolidays +{ + class HolidayRegion; +} // namespace KHolidays + +/** + The calendar data engine delivers calendar events. + It can be queried for holidays or the akonadi calendar. + + Supported Holiday requests are: + + holidaysRegions + * Returns a list of available Holiday Region Codes + holidaysDefaultRegion + * Returns a QString of a sensible default Holiday Region + holdaysIsValidRegion:[regionCode] + * Returns a bool if given Holiday Region is valid + holdaysRegion:[regionCode(s)] + * Returns the details of the Holiday Regions + holidays:[regionCode(s)]:[YYYY-MM-DD]:[YYYY-MM-DD] + * Returns a QList of all holidays in a Holiday Region(s) between two given dates. + holidays:[regionCode(s)]:[YYYY-MM-DD] + * Returns a QList of all holidays in a Holiday Region(s) on a given day + holidaysInMonth:[regionCode(s)]:[YYYY-MM-DD] + * Returns a QList of all holidays in a Holiday Region(s) in a given month + isHoliday:[regionCode(s)]:[YYYY-MM-DD] + * Returns a bool if a given date is a Holiday in the given Holiday Region(s) + description:[regionCode(s)]:[YYYY-MM-DD] + * Returns a QString of all holiday names in a given Holiday Region(s) on a given date + + Where valid, regionCode(s) are a comma separated list of one or more valid Holiday Regions + + Each Holiday Region is a pair of a QString containing the regionCode and a Data containing value + pairs for: + "Name" Name of the Holiday Region String + "Description" The description of the Region String + "CountryCode" The country code of the Region String, ISO 3166-2 format + "Location" The location of the Region String, ISO 3166-1 format + "LanguageCode" The language of the Region String, ISO 639-1 format + + Each Holiday is a Data containing QString value pairs for: + "Name" Name of holiday String + "RegionCode" The Holiday Region code String + "ObservanceStartDate" The start date of the holiday ISO format Gregorian date + "ObservanceEndDate" The end date of the holiday ISO format Gregorian date + "ObservanceDuration" How many days the holiday lasts Integer + "ObservanceType" If the holiday is a day off "PublicHoliday", "Other" + + Note that multiple holidays can be returned for each date. + + Supported Akonadi requests are: + + eventsInMonth:[YYYY-MM-DD] + events:[YYYY-MM-DD]:[YYYY-MM-DD] + events:[YYYY-MM-DD] + + The returned data contains (not all fields guaranteed to be populated): + + "UID" QString + "Type" QString "Event", "Todo", Journal" + "Summary" QString + "Comments" QStringList + "Location" QString + "OrganizerName" QString + "OrganizerEmail" QString + "Priority" int + "StartDate" KDateTime + "EndDate" KDateTime + "RecurrenceDates" QList(QVariant(KDateTime)) + "Recurs" bool + "AllDay" bool + "Categories" QStringList + "Resources" QStringList + "DurationDays" int + "DurationSeconds" int + "Status" QString "None", "Tentative", "Confirmed", "Draft", + "Final", "Completed", "InProcess", + "Cancelled", "NeedsAction", "NonStandard", + "Unknown" + "StatusName" QString translated Status + "Secrecy" QString "Public", "Private", "Confidential", "Unknown" + "SecrecyName" QString translated Secrecy + "Occurrences" QList(QVariant(Plasma::DataEngine::Data)) + where each Data contains details of an occurence of the event: + "OccurrenceUid" QString for convenience, same as UID + "OccurrenceStartDate" KDateTime + "OccurrenceEndDate" KDateTime + + Event type specific data keys: + "EventMultiDay" bool + "EventHasEndDate" bool + "EventTransparency" QString "Opaque", "Transparent", "Unknown" + + Todo type specific data keys: + "TodoHasStartDate" bool + "TodoIsOpenEnded" bool + "TodoHasDueDate" bool + "TodoDueDate" KDateTime + "TodoIsCompleted" bool + "TodoIsInProgress" bool + "TodoIsNotStarted" bool + "TodoPercentComplete" int + "TodoHasCompletedDate" bool + "TodoCompletedDate" bool + + Fields still to be done: + Attendees + Attachments + Relations + Alarms + Custom Properties + Lat/Lon + Collection/Source + +*/ +class CalendarEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + CalendarEngine( QObject* parent, const QVariantList& args ); + ~CalendarEngine(); + + protected: + /// general request for data from this data engine + bool sourceRequestEvent(const QString &name); + + private: + /// a request for holidays data + bool holidayCalendarSourceRequest(const QString& key, const QStringList& args, const QString& request); + + /// a request for data that comes from akonadi + /// creates EventDataContainers as needed + bool akonadiCalendarSourceRequest(const QString& key, const QStringList& args, const QString& request); + +#ifdef AKONADI_FOUND + /// this is the representation of the root calendar itself. it contains everything (calendars, incidences) + Akonadi::ETMCalendar::Ptr m_calendar; +#endif + + /// holiday calendar + QHash m_regions; + QString m_defaultHolidayRegion; // Cached value of default holiday region + QString m_defaultHolidayRegionCountry; // The locale country when the cached default calculated + QString m_defaultHolidayRegionLanguage; // The locale language when the cached default calculated +}; + +K_EXPORT_PLASMA_DATAENGINE(calendar, CalendarEngine) + +#endif diff --git a/plasma/generic/dataengines/calendar/eventdatacontainer.cpp b/plasma/generic/dataengines/calendar/eventdatacontainer.cpp new file mode 100644 index 00000000..27a1d580 --- /dev/null +++ b/plasma/generic/dataengines/calendar/eventdatacontainer.cpp @@ -0,0 +1,233 @@ +/* + Copyright (c) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "eventdatacontainer.h" + +#include + +#include +#include +#include +#include + +using namespace Akonadi; + +EventDataContainer::EventDataContainer(const Akonadi::ETMCalendar::Ptr &calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent) + : Plasma::DataContainer(parent), + m_calendar(calendar), + m_name(name), + m_startDate(start), + m_endDate(end) +{ + // name under which this dataEngine source appears + setObjectName(name); + + // Connect directly to the calendar for now + connect(calendar.data(), SIGNAL(calendarChanged()), this, SLOT(updateData())); + + // create the initial data + updateData(); +} + +void EventDataContainer::updateData() +{ + removeAllData(); + updateEventData(); + updateTodoData(); + updateJournalData(); + checkForUpdate(); +} + +void EventDataContainer::updateEventData() +{ + KCalCore::Event::List events = m_calendar->events(m_startDate.date(), m_endDate.date(), m_calendar->timeSpec()); + + foreach (const KCalCore::Event::Ptr &event, events) { + Plasma::DataEngine::Data eventData; + populateIncidenceData(event, eventData); + + // Event specific fields + eventData["EventMultiDay"] = event->allDay(); + eventData["EventHasEndDate"] = event->hasEndDate(); + if (event->transparency() == KCalCore::Event::Opaque) { + eventData["EventTransparency"] = "Opaque"; + } else if (event->transparency() == KCalCore::Event::Transparent) { + eventData["EventTransparency"] = "Transparent"; + } else { + eventData["EventTransparency"] = "Unknown"; + } + + setData(event->uid(), eventData); + } +} + +void EventDataContainer::updateTodoData() +{ + QDate todoDate = m_startDate.date(); + while(todoDate <= m_endDate.date()) { + KCalCore::Todo::List todos = m_calendar->todos(todoDate); + + foreach (const KCalCore::Todo::Ptr &todo, todos) { + Plasma::DataEngine::Data todoData; + populateIncidenceData(todo, todoData); + + QVariant var; + // Todo specific fields + todoData["TodoHasStartDate"] = todo->hasStartDate(); + todoData["TodoIsOpenEnded"] = todo->isOpenEnded(); + todoData["TodoHasDueDate"] = todo->hasDueDate(); + var.setValue(todo->dtDue().toTimeSpec(m_calendar->timeSpec())); + todoData["TodoDueDate"] = var; + todoData["TodoIsCompleted"] = todo->isCompleted(); + todoData["TodoIsInProgress"] = todo->isInProgress(false); // ??? + todoData["TodoIsNotStarted"] = todo->isNotStarted(false); // ??? + todoData["TodoPercentComplete"] = todo->percentComplete(); + todoData["TodoHasCompletedDate"] = todo->hasCompletedDate(); + var.setValue(todo->completed().toTimeSpec(m_calendar->timeSpec())); + todoData["TodoCompletedDate"] = var; + + setData(todo->uid(), todoData); + } + + todoDate = todoDate.addDays(1); + } +} + +void EventDataContainer::updateJournalData() +{ + QDate journalDate = m_startDate.date(); + while(journalDate <= m_endDate.date()) { + KCalCore::Journal::List journals = m_calendar->journals(journalDate); + + foreach (const KCalCore::Journal::Ptr &journal, journals) { + Plasma::DataEngine::Data journalData; + populateIncidenceData(journal, journalData); + + // No Journal specific fields + setData(journal->uid(), journalData); + } + + journalDate = journalDate.addDays(1); + } +} + +void EventDataContainer::populateIncidenceData(const KCalCore::Incidence::Ptr &incidence, Plasma::DataEngine::Data &incidenceData) +{ + QVariant var; + incidenceData["UID"] = incidence->uid(); + incidenceData["Type"] = incidence->typeStr(); + incidenceData["Summary"] = incidence->summary(); + incidenceData["Description"] = incidence->description(); + incidenceData["Comments"] = incidence->comments(); + incidenceData["Location"] = incidence->location(); + incidenceData["OrganizerName"] = incidence->organizer()->name(); + incidenceData["OrganizerEmail"] = incidence->organizer()->email(); + incidenceData["Priority"] = incidence->priority(); + var.setValue(incidence->dtStart().toTimeSpec(m_calendar->timeSpec())); + incidenceData["StartDate"] = var; + + KCalCore::Event* event = dynamic_cast(incidence.data()); + if (event) { + var.setValue(event->dtEnd().toTimeSpec(m_calendar->timeSpec())); + incidenceData["EndDate"] = var; + } + // Build the Occurance Index, this lists all occurences of the Incidence in the required range + // Single occurance events just repeat the standard start/end dates + // Recurring Events use each recurrence start/end date + // The OccurenceUid is redundant, but it makes it easy for clients to just take() the data structure intact as a separate index + QList occurences; + // Build the recurrence list of start dates for recurring incidences only + QList recurrences; + if (incidence->recurs()) { + KCalCore::DateTimeList recurList = incidence->recurrence()->timesInInterval(m_startDate.toTimeSpec(m_calendar->timeSpec()), m_endDate.toTimeSpec(m_calendar->timeSpec())); + foreach(const KDateTime &recurDateTime, recurList) { + var.setValue(recurDateTime.toTimeSpec(m_calendar->timeSpec())); + recurrences.append(var); + Plasma::DataEngine::Data occurence; + occurence.insert("OccurrenceUid", incidence->uid()); + occurence.insert("OccurrenceStartDate", var); + var.setValue(incidence->endDateForStart(recurDateTime).toTimeSpec(m_calendar->timeSpec())); + occurence.insert("OccurrenceEndDate", var); + occurences.append(QVariant(occurence)); + } + } else { + Plasma::DataEngine::Data occurence; + occurence.insert("OccurrenceUid", incidence->uid()); + var.setValue(incidence->dtStart().toTimeSpec(m_calendar->timeSpec())); + occurence.insert("OccurrenceStartDate", var); + if (event) { + var.setValue(event->dtEnd().toTimeSpec(m_calendar->timeSpec())); + occurence.insert("OccurrenceEndDate", var); + } + occurences.append(QVariant(occurence)); + } + incidenceData["RecurrenceDates"] = QVariant(recurrences); + incidenceData["Occurrences"] = QVariant(occurences); + if (incidence->status() == KCalCore::Incidence::StatusNone) { + incidenceData["Status"] = "None"; + } else if (incidence->status() == KCalCore::Incidence::StatusTentative) { + incidenceData["Status"] = "Tentative"; + } else if (incidence->status() == KCalCore::Incidence::StatusConfirmed) { + incidenceData["Status"] = "Confirmed"; + } else if (incidence->status() == KCalCore::Incidence::StatusDraft) { + incidenceData["Status"] = "Draft"; + } else if (incidence->status() == KCalCore::Incidence::StatusFinal) { + incidenceData["Status"] = "Final"; + } else if (incidence->status() == KCalCore::Incidence::StatusCompleted) { + incidenceData["Status"] = "Completed"; + } else if (incidence->status() == KCalCore::Incidence::StatusInProcess) { + incidenceData["Status"] = "InProcess"; + } else if (incidence->status() == KCalCore::Incidence::StatusCanceled) { + incidenceData["Status"] = "Cancelled"; + } else if (incidence->status() == KCalCore::Incidence::StatusNeedsAction) { + incidenceData["Status"] = "NeedsAction"; + } else if (incidence->status() == KCalCore::Incidence::StatusX) { + incidenceData["Status"] = "NonStandard"; + } else { + incidenceData["Status"] = "Unknown"; + } + incidenceData["StatusName"] = KCalUtils::Stringify::incidenceStatus( incidence->status() ); + + if (incidence->secrecy() == KCalCore::Incidence::SecrecyPublic) { + incidenceData["Secrecy"] = "Public"; + } else if (incidence->secrecy() == KCalCore::Incidence::SecrecyPrivate) { + incidenceData["Secrecy"] = "Private"; + } else if (incidence->secrecy() == KCalCore::Incidence::SecrecyConfidential) { + incidenceData["Secrecy"] = "Confidential"; + } else { + incidenceData["Secrecy"] = "Unknown"; + } + incidenceData["SecrecyName"] = KCalUtils::Stringify::secrecyName( incidence->secrecy() ); + incidenceData["Recurs"] = incidence->recurs(); + incidenceData["AllDay"] = incidence->allDay(); + incidenceData["Categories"] = incidence->categories(); + incidenceData["Resources"] = incidence->resources(); + incidenceData["DurationDays"] = incidence->duration().asDays(); + incidenceData["DurationSeconds"] = incidence->duration().asSeconds(); + + //TODO Attendees + //TODO Attachments + //TODO Relations + //TODO Alarms + //TODO Custom Properties + //TODO Lat/Lon + //TODO Collection/Source +} + +#include "eventdatacontainer.moc" diff --git a/plasma/generic/dataengines/calendar/eventdatacontainer.h b/plasma/generic/dataengines/calendar/eventdatacontainer.h new file mode 100644 index 00000000..fd3996f5 --- /dev/null +++ b/plasma/generic/dataengines/calendar/eventdatacontainer.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library 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 Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef EVENTDATACONTAINER_H +#define EVENTDATACONTAINER_H + +#include +#include +#include +#include + +class EventDataContainer : public Plasma::DataContainer +{ + Q_OBJECT +public: + EventDataContainer(const Akonadi::ETMCalendar::Ptr &calendar, const QString& name, const KDateTime& start, const KDateTime& end, QObject* parent = 0); + +public Q_SLOTS: + // update the list of incidents + void updateData(); + +private: + void updateEventData(); + void updateTodoData(); + void updateJournalData(); + void populateIncidenceData(const KCalCore::Incidence::Ptr &incidence, Plasma::DataEngine::Data &incidenceData); + + Akonadi::ETMCalendar::Ptr m_calendar; + QString m_name; + KDateTime m_startDate; + KDateTime m_endDate; +}; + +#endif diff --git a/plasma/generic/dataengines/calendar/plasma-dataengine-calendar.desktop b/plasma/generic/dataengines/calendar/plasma-dataengine-calendar.desktop new file mode 100644 index 00000000..bfc7e371 --- /dev/null +++ b/plasma/generic/dataengines/calendar/plasma-dataengine-calendar.desktop @@ -0,0 +1,161 @@ +[Desktop Entry] +Name=Calendar +Name[ar]=التقويم +Name[ast]=Calendariu +Name[be@latin]=Kalandar +Name[bg]=Календар +Name[bn]=ক্যালেণ্ডার +Name[bn_IN]=বর্ষপঞ্জি +Name[bs]=kalendar +Name[ca]=Calendari +Name[ca@valencia]=Calendari +Name[cs]=Kalendář +Name[csb]=Kalãdôrz +Name[da]=Kalender +Name[de]=Kalender +Name[el]=Ημερολόγιο +Name[en_GB]=Calendar +Name[eo]=Kalendaro +Name[es]=Calendario +Name[et]=Kalender +Name[eu]=Egutegia +Name[fa]=تقویم +Name[fi]=Kalenteri +Name[fr]=Calendrier +Name[fy]=Aginda +Name[ga]=Féilire +Name[gl]=Calendario +Name[gu]=કેલેન્ડર +Name[he]=לוח שנה +Name[hi]=कैलेन्डर +Name[hne]=कलेन्डर +Name[hr]=Kalendar +Name[hsb]=Protyka +Name[hu]=Naptár +Name[ia]=Calendario +Name[id]=Kalender +Name[is]=Dagatal +Name[it]=Calendario +Name[ja]=カレンダー +Name[kk]=Күнтізбе +Name[km]=ប្រតិទិន +Name[kn]=ದಿನಸೂಚಿ +Name[ko]=달력 +Name[ku]=Salname +Name[lt]=Kalendorius +Name[lv]=Kalendārs +Name[mai]=कैलेंडर +Name[mk]=Календар +Name[ml]=കലണ്ടര്‍ +Name[mr]=दिनदर्शिका +Name[nb]=Kalender +Name[nds]=Kalenner +Name[nl]=Kalender +Name[nn]=Kalender +Name[pa]=ਕੈਲੰਡਰ +Name[pl]=Kalendarz +Name[pt]=Calendário +Name[pt_BR]=Calendário +Name[ro]=Calendar +Name[ru]=Календарь +Name[si]=දිනදර්ශනය +Name[sk]=Kalendár +Name[sl]=Koledar +Name[sr]=календар +Name[sr@ijekavian]=календар +Name[sr@ijekavianlatin]=kalendar +Name[sr@latin]=kalendar +Name[sv]=Kalender +Name[ta]=நாட்காட்டி +Name[tg]=Тақвим +Name[th]=ปฏิทิน +Name[tr]=Takvim +Name[ug]=يىلنامە +Name[uk]=Календар +Name[vi]=Lịch +Name[wa]=Calindrî +Name[x-test]=xxCalendarxx +Name[zh_CN]=日历 +Name[zh_TW]=行事曆 +Comment=Calendar data engine +Comment[ar]=محرك بيانات التقويم +Comment[ast]=Motor de datos del calendariu +Comment[bg]=Ядро на календара +Comment[bs]=Kalendarski datomotor +Comment[ca]=Motor de dades de calendari +Comment[ca@valencia]=Motor de dades de calendari +Comment[cs]=Datový nástroj kalendáře +Comment[csb]=Kalãdôrz czérownika pòdôwków +Comment[da]=Datamtor til kalender +Comment[de]=Kalender-Datentreiber +Comment[el]=Μηχανή δεδομένων ημερολογίου +Comment[en_GB]=Calendar data engine +Comment[eo]=Kalendara datuma motoro +Comment[es]=Motor de datos del calendario +Comment[et]=Kalendri andmete mootor +Comment[eu]=Egutegiko datuen motorra +Comment[fi]=Kalenteritietomoottori +Comment[fr]=Moteur de données du calendrier +Comment[fy]=Kalinder gegevens motor +Comment[ga]=Inneall sonraí féilire +Comment[gl]=Motor de datos de calendario +Comment[gu]=કેલેન્ડર માહિતી એન્જિન +Comment[he]=מנוע תוכן לוחות שנה +Comment[hi]=कैलेन्डर डॉटा इंजन +Comment[hr]=Podatkovni mehanizam za kalendar +Comment[hu]=Naptárkezelő modul +Comment[ia]=Motor de datos de calendario +Comment[id]=Mesin data kalender +Comment[is]=Gagnavél fyrir dagatal +Comment[it]=Motore dei dati del calendario +Comment[ja]=カレンダー用データエンジン +Comment[kk]=Күнтізбе деректер тетігі +Comment[km]=ម៉ាស៊ីន​ទិន្នន័យ​ប្រតិទិន +Comment[kn]=ದಿನಸೂಚಿ ದತ್ತಾಂಶ ಸಾಧನ +Comment[ko]=달력 데이터 엔진 +Comment[lt]=Kalendoriaus duomenų variklis +Comment[lv]=Kalendāra datu dzinējs +Comment[mk]=Податочна машина за календари +Comment[ml]=കലണ്ടര്‍ ഡാറ്റ എഞ്ചിന്‍ +Comment[mr]=दिनदर्शिका डेटा इंजिन +Comment[nb]=Kalenderdata-motor +Comment[nds]=Kalenner-Datenkarn +Comment[nl]=Agendagegevensengine +Comment[nn]=Kalenderdatamotor +Comment[pa]=ਕੈਲੰਡਰ ਡਾਟਾ ਇੰਜਣ +Comment[pl]=Silnik danych kalendarza +Comment[pt]=Motor de dados do calendário +Comment[pt_BR]=Mecanismo de dados de calendário +Comment[ro]=Motor de date pentru calendar +Comment[ru]=Источник данных для календаря +Comment[si]=දිනදසුන් දත්ත එන්ජිම +Comment[sk]=Dátový nástroj kalendára +Comment[sl]=Podatkovni pogon s koledarskimi podatki +Comment[sr]=Календарски датомотор +Comment[sr@ijekavian]=Календарски датомотор +Comment[sr@ijekavianlatin]=Kalendarski datomotor +Comment[sr@latin]=Kalendarski datomotor +Comment[sv]=Datagränssnitt för kalendrar +Comment[tg]=Мудири тақвим +Comment[th]=ข้อมูลปฏิทินและกลไกจัดการ +Comment[tr]=Takvim veri motoru +Comment[ug]=يىلنامە سانلىق-مەلۇمات ماتورى +Comment[uk]=Рушій даних календаря +Comment[vi]=Cơ chế dữ liệu lịch biểu +Comment[wa]=Moteur di dnêyes do calindrî +Comment[x-test]=xxCalendar data enginexx +Comment[zh_CN]=日历数据引擎 +Comment[zh_TW]=行事曆資料引擎 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=office-calendar +X-KDE-Library=plasma_engine_calendar + +X-KDE-PluginInfo-Author=Davide Bettio +X-KDE-PluginInfo-Email=davide.bettio@kdemail.net +X-KDE-PluginInfo-Name=calendar +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/devicenotifications/CMakeLists.txt b/plasma/generic/dataengines/devicenotifications/CMakeLists.txt new file mode 100644 index 00000000..7eff4166 --- /dev/null +++ b/plasma/generic/dataengines/devicenotifications/CMakeLists.txt @@ -0,0 +1,12 @@ +set(device_notifications_engine_SRCS + devicenotificationsengine.cpp +) + +qt4_add_dbus_adaptor( device_notifications_engine_SRCS org.kde.DeviceNotifications.xml devicenotificationsengine.h DeviceNotificationsEngine ) + +kde4_add_plugin(plasma_engine_devicenotifications ${device_notifications_engine_SRCS}) + +target_link_libraries(plasma_engine_devicenotifications ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS}) + +install(TARGETS plasma_engine_devicenotifications DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-devicenotifications.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.cpp b/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.cpp new file mode 100644 index 00000000..fa92c0fb --- /dev/null +++ b/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Jacopo De Simoi + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "devicenotificationsengine.h" +#include "devicenotificationsadaptor.h" + +#include + +#include + +DeviceNotificationsEngine::DeviceNotificationsEngine( QObject* parent, const QVariantList& args ) + : Plasma::DataEngine( parent, args ), + m_id(0) +{ + new DeviceNotificationsAdaptor(this); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerService( "org.kde.DeviceNotifications" ); + dbus.registerObject( "/org/kde/DeviceNotifications", this ); +} + +DeviceNotificationsEngine::~DeviceNotificationsEngine() +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.unregisterService( "org.kde.DeviceNotifications" ); +} + +void DeviceNotificationsEngine::init() +{ +} + +void DeviceNotificationsEngine::notify(int solidError, const QString& error, const QString& errorDetails, const QString &udi) +{ + kDebug() << error << errorDetails << udi; + const QString source = QString("notification %1").arg(m_id++); + + Plasma::DataEngine::Data notificationData; + notificationData.insert("solidError", solidError); + notificationData.insert("error", error); + notificationData.insert("errorDetails", errorDetails); + notificationData.insert("udi", udi); + + setData(source, notificationData ); +} + +K_EXPORT_PLASMA_DATAENGINE(devicenotifications, DeviceNotificationsEngine) + +#include "devicenotificationsengine.moc" diff --git a/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.h b/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.h new file mode 100644 index 00000000..b5f5326a --- /dev/null +++ b/plasma/generic/dataengines/devicenotifications/devicenotificationsengine.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Jacopo De Simoi + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#ifndef DEVICENOTIFICATIONSENGINE_H +#define DEVICENOTIFICATIONSENGINE_H + +#include + +/** + * Engine which provides data sources for device notifications. + * Each notification is represented by one source. + */ +class DeviceNotificationsEngine : public Plasma::DataEngine +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.DeviceNotifications") + +public: + DeviceNotificationsEngine( QObject* parent, const QVariantList& args ); + ~DeviceNotificationsEngine(); + + virtual void init(); + + /** + * This function implements part of Notifications DBus interface. + * Once called, will add notification source to the engine + */ +public slots: + void notify(int solidError, const QString& error, const QString& errorDetails, const QString &udi); + +private: + uint m_id; +}; + +#endif diff --git a/plasma/generic/dataengines/devicenotifications/org.kde.DeviceNotifications.xml b/plasma/generic/dataengines/devicenotifications/org.kde.DeviceNotifications.xml new file mode 100644 index 00000000..efd08c39 --- /dev/null +++ b/plasma/generic/dataengines/devicenotifications/org.kde.DeviceNotifications.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/plasma/generic/dataengines/devicenotifications/plasma-dataengine-devicenotifications.desktop b/plasma/generic/dataengines/devicenotifications/plasma-dataengine-devicenotifications.desktop new file mode 100644 index 00000000..aa8f1e07 --- /dev/null +++ b/plasma/generic/dataengines/devicenotifications/plasma-dataengine-devicenotifications.desktop @@ -0,0 +1,133 @@ +[Desktop Entry] +Name=Device Notifications +Name[ar]=تنبيهات الأجهزة +Name[ast]=Notificaciones de preséu +Name[bg]=Уведомления от устройства +Name[bn]=ডিভাইস বিজ্ঞপ্তি +Name[bs]=Obavještenja o uređajima +Name[ca]=Notificacions dels dispositius +Name[ca@valencia]=Notificacions dels dispositius +Name[cs]=Oznamování zařízení +Name[da]=Enhedsbekendtgørelser +Name[de]=Geräte-Benachrichtigungen +Name[el]=Ειδοποιήσεις συσκευών +Name[en_GB]=Device Notifications +Name[es]=Notificaciones de dispositivo +Name[et]=Seadmete märguanded +Name[eu]=Gailu-jakinarazpenak +Name[fi]=Laiteilmoitukset +Name[fr]=Notifications des périphériques +Name[ga]=Fógraí Gléasanna +Name[gl]=Notificacións dos dispositivos +Name[he]=הודעות של התקנים +Name[hi]=औज़ार सूचनाएँ +Name[hr]=Obavijesti uređaja +Name[hu]=Eszközértesítések +Name[ia]=Notificationes de dispositivo +Name[id]=Notifikasi Divais +Name[is]=Tilkynningar um tæki +Name[it]=Notifiche dei dispositivi +Name[ja]=デバイスの通知 +Name[kk]=Құрылғы құлақтандырулары +Name[km]=ការ​​ជូន​ដំណឹង​​ឧបករណ៍ +Name[kn]=ಸಾಧನ ಸೂಚನೆಗಳು +Name[ko]=장치 알림 +Name[lt]=Pranešimai apie įrenginius +Name[lv]=Iekārtu paziņojumi +Name[mr]=साधन सूचना +Name[nb]=Enhetsvarslinger +Name[nds]=Reedschap-Bescheden +Name[nl]=Meldingen van apparaten +Name[pa]=ਜੰਤਰ ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienia urządzeń +Name[pt]=Notificações de Dispositivos +Name[pt_BR]=Notificações de dispositivos +Name[ro]=Notificări dispozitive +Name[ru]=Уведомления об устройствах +Name[si]=මෙවලම් දැනුම් දීම් +Name[sk]=Upozornenia zariadení +Name[sl]=Obvestila o napravah +Name[sr]=Обавештења о уређајима +Name[sr@ijekavian]=Обавјештења о уређајима +Name[sr@ijekavianlatin]=Obavještenja o uređajima +Name[sr@latin]=Obaveštenja o uređajima +Name[sv]=Enhetsunderrättelser +Name[tg]=Огоҳиҳои дастгоҳ +Name[th]=การแจ้งเกี่ยวกับอุปกรณ์ +Name[tr]=Aygıt Bildirimleri +Name[ug]=ئۈسكۈنە ئۇقتۇرۇشلىرى +Name[uk]=Сповіщення про пристрої +Name[vi]=Thông báo thiết bị +Name[wa]=Notifiaedjes des éndjins +Name[x-test]=xxDevice Notificationsxx +Name[zh_CN]=设备通知 +Name[zh_TW]=裝置通知 +Comment=Passive device notifications for the user. +Comment[ar]=إشعارات مرئية غير متفاعلة للمستخدم +Comment[ast]=Notificaciones pasives de preseos pal usuariu. +Comment[bg]=Пасивни уведомления от устройствата за потребителя. +Comment[bs]=Pasivna obavještenja o uređajima za korisnika. +Comment[ca]=Notificacions passives de dispositius per a l'usuari. +Comment[ca@valencia]=Notificacions passives de dispositius per a l'usuari. +Comment[cs]=Pasivní upozornění zařízení pro uživatele. +Comment[da]=Passive enhedsbekendtgørelser til brugeren. +Comment[de]=Passive Benachrichtigungen für den Anwender. +Comment[el]=Παθητική συσκευή ειδοποιήσεων για το χρήστη. +Comment[en_GB]=Passive device notifications for the user. +Comment[es]=Notificaciones pasivas de dispositivos para el usuario. +Comment[et]=Passiivsed seadmete märguanded kasutajale. +Comment[eu]=Erabiltzailearentzako gailu-jakinarazpen pasiboak. +Comment[fi]=Passiivisia laiteilmoituksia käyttäjälle. +Comment[fr]=Notifications passives de périphériques pour l'utilisateur. +Comment[gl]=Notificacións pasivas dos dispositivos para o usuario. +Comment[he]=הודעות פאסיביות של התקנים למשתמש. +Comment[hr]=Pasivne obavijesti uređaja za korisnika. +Comment[hu]=Passzív eszközértesítések a felhasználónak. +Comment[ia]=Notificationes de dispositivo passive pro le usator. +Comment[id]=Notifikasi divais pasif untuk pengguna. +Comment[is]=Hlutlausar sjónrænar tilkynningar til notandans. +Comment[it]=Notifiche dei dispositivi passive per l'utente. +Comment[ja]=ユーザ用の受動的デバイス通知です。 +Comment[kk]=Құрылғы пайдаланушысына құлақтандырулары +Comment[km]=ការ​ជូនដំណឹង​ឧបករណ៍​សកម្ម​សម្រាប់​អ្នក​ប្រើ ។ +Comment[kn]=ಬಳಕೆದಾರನಿಗಾಗಿ ನಿಷ್ಕ್ರಿಯವಾಗಿರುವ ಸಾಧನ ಸೂಚನೆಗಳು. +Comment[ko]=사용자에게 보이는 수동적인 장치 알림입니다. +Comment[lt]=Pasyvūs pranešimai naudotojui apie įrenginius. +Comment[lv]=Pasīvi iekārtu paziņojumi lietotājam. +Comment[mr]=वापरकर्त्यासाठी साधन सूचना. +Comment[nb]=Passive enhetsvarslinger for brukeren. +Comment[nds]=Passiev Reedschap-Bescheden för den Bruker +Comment[nl]=Passieve meldingen van apparaten voor de gebruiker. +Comment[pa]=ਯੂਜ਼ਰ ਲਈ ਪੈਸਿਵ ਜੰਤਰ ਨੋਟੀਫਿਕੇਸ਼ਨ। +Comment[pl]=Bierne powiadomienia urządzenia dla użytkownika. +Comment[pt]=Notificações passivas de dispositivos para o utilizador. +Comment[pt_BR]=Notificações passivas de dispositivos para o usuário. +Comment[ro]=Notificări de dispozitiv pasive pentru utilizator. +Comment[ru]=Пассивные уведомления для пользователя об оборудовании. +Comment[si]=පරිශීලකයන් සඳහා නිශ්ක්‍රීය මෙවලම් දැනුම්දීම්. +Comment[sk]=Pasívne upozornenia zariadení pre užívateľa. +Comment[sl]=Pasivna obvestila o napravah za uporabnika. +Comment[sr]=Пасивна обавештења о уређајима за корисника. +Comment[sr@ijekavian]=Пасивна обавјештења о уређајима за корисника. +Comment[sr@ijekavianlatin]=Pasivna obavještenja o uređajima za korisnika. +Comment[sr@latin]=Pasivna obaveštenja o uređajima za korisnika. +Comment[sv]=Passiva enhetsunderrättelser för användaren. +Comment[th]=การแจ้งอุปกรณ์ที่ไม่มีปฏิกิริยาแก่ผู้ใช้ +Comment[tr]=Kullanıcı için pasif aygıt bildirimleri. +Comment[ug]=ئىشلەتكۈچىگە پاسسىپ كۆرۈنىدىغان ئۈسكۈنىلەرنى ئۇقتۇرىدۇ. +Comment[uk]=Пасивні сповіщення користувача щодо пристроїв. +Comment[wa]=Notifiaedjes doirmants des éndjins po l' uzeu. +Comment[x-test]=xxPassive device notifications for the user.xx +Comment[zh_CN]=为用户提供被动出现的设备通知。 +Comment[zh_TW]=給使用者的被動裝置通知。 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=device-notifier +X-KDE-Library=plasma_engine_devicenotifications + +X-KDE-PluginInfo-Author=Jacopo De Simoi +X-KDE-PluginInfo-Email=wilderkde@gmail.com +X-KDE-PluginInfo-Name=devicenotifications +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= diff --git a/plasma/generic/dataengines/dict/CMakeLists.txt b/plasma/generic/dataengines/dict/CMakeLists.txt new file mode 100644 index 00000000..2cab7c25 --- /dev/null +++ b/plasma/generic/dataengines/dict/CMakeLists.txt @@ -0,0 +1,12 @@ +project(plasma-dictengine) + +set(dict_engine_SRCS + dictengine.cpp +) + +kde4_add_plugin(plasma_engine_dict ${dict_engine_SRCS}) +target_link_libraries(plasma_engine_dict ${KDE4_KDECORE_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTNETWORK_LIBRARY}) + +install(TARGETS plasma_engine_dict DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-dict.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/dict/Messages.sh b/plasma/generic/dataengines/dict/Messages.sh new file mode 100755 index 00000000..29218d33 --- /dev/null +++ b/plasma/generic/dataengines/dict/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_dict.pot diff --git a/plasma/generic/dataengines/dict/buggywords b/plasma/generic/dataengines/dict/buggywords new file mode 100644 index 00000000..711fb3c0 --- /dev/null +++ b/plasma/generic/dataengines/dict/buggywords @@ -0,0 +1 @@ +which diff --git a/plasma/generic/dataengines/dict/dictengine.cpp b/plasma/generic/dataengines/dict/dictengine.cpp new file mode 100644 index 00000000..425b307d --- /dev/null +++ b/plasma/generic/dataengines/dict/dictengine.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2007 Thomas Georgiou and Jeff Cooper + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "dictengine.h" +#include + +#include +#include +#include + +#include + +DictEngine::DictEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) + , m_tcpSocket(0) +{ + Q_UNUSED(args) + m_serverName = "dict.org"; //In case we need to switch it later + m_dictName = "wn"; //Default, good dictionary +} + +DictEngine::~DictEngine() +{ +} + +void DictEngine::setDict(const QString &dict) +{ + m_dictName = dict; +} + +void DictEngine::setServer(const QString &server) +{ + m_serverName = server; +} + +static QString wnToHtml(const QString &word, QByteArray &text) +{ + Q_UNUSED(word) + QList splitText = text.split('\n'); + QString def; + def += "
    "; + return def; +} + +void DictEngine::getDefinition() +{ + m_tcpSocket->readAll(); + QByteArray ret; + + m_tcpSocket->write(QByteArray("DEFINE ")); + m_tcpSocket->write(m_dictName.toAscii()); + m_tcpSocket->write(QByteArray(" \"")); + m_tcpSocket->write(m_currentWord.toUtf8()); + m_tcpSocket->write(QByteArray("\"\n")); + m_tcpSocket->flush(); + + while (!ret.contains("250") && !ret.contains("552") && !ret.contains("550")) { + m_tcpSocket->waitForReadyRead(); + ret += m_tcpSocket->readAll(); + } + + connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(socketClosed())); + m_tcpSocket->disconnectFromHost(); + // setData(m_currentWord, m_dictName, ret); + // qWarning()< theHash; + m_tcpSocket->readAll(); + QByteArray ret; + + m_tcpSocket->write(QByteArray("SHOW DB\n"));; + m_tcpSocket->flush(); + + m_tcpSocket->waitForReadyRead(); + while (!ret.contains("250")) { + m_tcpSocket->waitForReadyRead(); + ret += m_tcpSocket->readAll(); + } + + QList retLines = ret.split('\n'); + QString tmp1, tmp2; + + while (!retLines.empty()) { + QString curr(retLines.takeFirst()); + + if (curr.startsWith(QLatin1String("554"))) { + //TODO: What happens if no DB available? + //TODO: Eventually there will be functionality to change the server... + break; + } + + // ignore status code and empty lines + if (curr.startsWith(QLatin1String("250")) || curr.startsWith(QLatin1String("110")) + || curr.isEmpty()) { + continue; + } + + if (!curr.startsWith('-') && !curr.startsWith('.')) { + curr = curr.trimmed(); + tmp1 = curr.section(' ', 0, 0); + tmp2 = curr.section(' ', 1); + // theHash.insert(tmp1, tmp2); + //kDebug() << tmp1 + " " + tmp2; + setData("list-dictionaries", tmp1, tmp2); + } + } + + m_tcpSocket->disconnectFromHost(); +// setData("list-dictionaries", "dictionaries", QByteArray(theHash); +} + + + +void DictEngine::socketClosed() +{ + m_tcpSocket->deleteLater(); + m_tcpSocket = 0; +} + +bool DictEngine::sourceRequestEvent(const QString &query) +{ + // FIXME: this is COMPLETELY broken .. it can only look up one query at a time! + // a DataContainer subclass that does the look up should probably be made + if (m_currentQuery == query) { + return false; + } + + if (m_tcpSocket) { + m_tcpSocket->abort(); //stop if lookup is in progress and new query is requested + m_tcpSocket->deleteLater(); + m_tcpSocket = 0; + } + + QStringList queryParts = query.split(':', QString::SkipEmptyParts); + if (queryParts.isEmpty()) { + return false; + } + + m_currentWord = queryParts.last(); + m_currentQuery = query; + + //asked for a dictionary? + if (queryParts.count() > 1) { + setDict(queryParts[queryParts.count()-2]); + //default to wordnet + } else { + setDict("wn"); + } + + //asked for a server? + if (queryParts.count() > 2) { + setServer(queryParts[queryParts.count()-3]); + //default to wordnet + } else { + setServer("dict.org"); + } + + if (m_currentWord.simplified().isEmpty()) { + setData(m_currentWord, m_dictName, QString()); + } else { + setData(m_currentWord, m_dictName, QString()); + m_tcpSocket = new KTcpSocket(this); + m_tcpSocket->abort(); + connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(socketClosed())); + + if (m_currentWord == "list-dictionaries") { + connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(getDicts())); + } else { + connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(getDefinition())); + } + + m_tcpSocket->connectToHost(m_serverName, 2628); + } + + return true; +} + +#include "dictengine.moc" diff --git a/plasma/generic/dataengines/dict/dictengine.h b/plasma/generic/dataengines/dict/dictengine.h new file mode 100644 index 00000000..d91f246c --- /dev/null +++ b/plasma/generic/dataengines/dict/dictengine.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007 Thomas Georgiou and Jeff Cooper + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DICTENGINE_H +#define DICTENGINE_H +#include +#include +class KTcpSocket; + +/** + * This class evaluates the basic expressions given in the interface. + */ + + +class DictEngine: public Plasma::DataEngine +{ + Q_OBJECT + + public: + DictEngine( QObject* parent, const QVariantList& args ); + ~DictEngine(); + + protected: + bool sourceRequestEvent(const QString &word); + + private slots: + void getDefinition(); + void socketClosed(); + void getDicts(); + + private: + void setDict(const QString &dict); + void setServer(const QString &server); + + QHash m_dictNameToDictCode; + KTcpSocket *m_tcpSocket; + QString m_currentWord; + QString m_currentQuery; + QString m_dictName; + QString m_serverName; + +}; + +K_EXPORT_PLASMA_DATAENGINE(dict, DictEngine) + +#endif diff --git a/plasma/generic/dataengines/dict/plasma-dataengine-dict.desktop b/plasma/generic/dataengines/dict/plasma-dataengine-dict.desktop new file mode 100644 index 00000000..c8159510 --- /dev/null +++ b/plasma/generic/dataengines/dict/plasma-dataengine-dict.desktop @@ -0,0 +1,171 @@ +[Desktop Entry] +Name=Dictionary +Name[ar]=القاموس +Name[as]=অভিধান +Name[ast]=Diccionariu +Name[be@latin]=Słoŭnik +Name[bg]=Речник +Name[bn]=অভিধান +Name[bn_IN]=অভিধান +Name[bs]=rječnik +Name[ca]=Diccionari +Name[ca@valencia]=Diccionari +Name[cs]=Slovník +Name[csb]=Słowôrz +Name[da]=Ordbog +Name[de]=Wörterbuch +Name[el]=Λεξικό +Name[en_GB]=Dictionary +Name[eo]=Vortaro +Name[es]=Diccionario +Name[et]=Sõnaraamat +Name[eu]=Hiztegia +Name[fa]=واژه‌نامه +Name[fi]=Sanakirja +Name[fr]=Dictionnaire +Name[fy]=Wurdboek +Name[ga]=Foclóir +Name[gl]=Dicionario +Name[gu]=ડિક્શનરી +Name[he]=מילון +Name[hi]=शब्दकोश +Name[hne]=सब्दकोस +Name[hr]=Rječnik +Name[hu]=Szótár +Name[ia]=Dictionario +Name[id]=Kamus +Name[is]=Orðabók +Name[it]=Dizionario +Name[ja]=辞書 +Name[kk]=Сөздік +Name[km]=វចនានុក្រម +Name[kn]=ಶಬ್ದಕೋಶ +Name[ko]=사전 +Name[ku]=Ferheng +Name[lt]=Žodynas +Name[lv]=Vārdnīca +Name[mai]=शब्दकोश +Name[mk]=Речник +Name[ml]=നിഘണ്ടു +Name[mr]=माहितीकोष +Name[nb]=Ordbok +Name[nds]=Wöörbook +Name[nl]=Woordenboek +Name[nn]=Ordbok +Name[or]=ଅଭିଧାନ +Name[pa]=ਡਿਕਸ਼ਨਰੀ +Name[pl]=Słownik +Name[pt]=Dicionário +Name[pt_BR]=Dicionário +Name[ro]=Dicționar +Name[ru]=Словарь +Name[si]=ශබ්දකෝෂය +Name[sk]=Slovník +Name[sl]=Slovar +Name[sr]=речник +Name[sr@ijekavian]=рјечник +Name[sr@ijekavianlatin]=rječnik +Name[sr@latin]=rečnik +Name[sv]=Ordlista +Name[ta]=அகராதி +Name[tg]=Луғат +Name[th]=พจนานุกรม +Name[tr]=Sözlük +Name[ug]=لۇغەت +Name[uk]=Словник +Name[vi]=Từ điển +Name[wa]=Motî +Name[x-test]=xxDictionaryxx +Name[zh_CN]=词典 +Name[zh_TW]=字典 +Comment=Look up word meanings +Comment[af]=Slaan woordbetekenisse na +Comment[ar]=ابحث عن معنى الكلمة +Comment[ast]=Guetar significáu de les pallabres +Comment[be@latin]=Pošuk značeńniaŭ słovaŭ +Comment[bg]=Търсене значението на думи +Comment[bn_IN]=শব্দের অর্থ অনুসন্ধান করুন +Comment[bs]=Potražite značenja riječi +Comment[ca]=Cerca els significats de paraules +Comment[ca@valencia]=Cerca els significats de paraules +Comment[cs]=Vyhledávání významu slov +Comment[da]=Slå ords betydning op +Comment[de]=Nachschlagen von Wortbedeutungen +Comment[el]=Αναζήτηση σημασίας λέξεων +Comment[en_GB]=Look up word meanings +Comment[eo]=Serĉi difinojn de vortoj +Comment[es]=Buscar significado de las palabras +Comment[et]=Sõna tähenduse otsimine +Comment[eu]=Bilatu hitzen esanahiak +Comment[fi]=Tarkista sanojen merkityksiä +Comment[fr]=Connaître la signification des mots +Comment[fy]=Sykje de wurdbetekenissen op +Comment[ga]=Aimsigh sainmhíniú ar fhocal +Comment[gl]=Procura o significado de palabras +Comment[gu]=શબ્દનાં અર્થો શોધો +Comment[he]=בדיקת משמעויות של מילים +Comment[hi]=शब्द का अर्थ देखें +Comment[hne]=सब्द के मायने देखव +Comment[hr]=Pretražite riječi i njihova značenja +Comment[hu]=Értelmező szótár +Comment[ia]=Cerca significato de parola +Comment[id]=Cari arti kata +Comment[is]=Flettu upp merkingu orða +Comment[it]=Cerca i significati delle parole +Comment[ja]=単語の意味を調べる +Comment[kk]=Сөздің мәнін қарастыру +Comment[km]=រក​មើល​អត្ថន័យ​របស់​ពាក្យ +Comment[kn]=ಪದಗಳ ಅರ್ಥಗಳಿಗನ್ನು ಹುಡುಕು +Comment[ko]=단어의 뜻 찾기 +Comment[lt]=Žodžių prasmės paieška +Comment[lv]=Atrod vārdu nozīmes +Comment[mk]=Побарајте за значења на зборовите +Comment[ml]=വാക്കുകളുടെ അര്‍ത്ഥങ്ങള്‍ നിഘണ്ടുവില്‍ തെരയുക +Comment[mr]=शब्दांचे अर्थ शोधण्याकरिता लुकअप +Comment[nb]=Slå opp betydningen av ord +Comment[nds]=Woortbedüden naslaan +Comment[ne]=शब्दको अर्थ हेर्नुहोस् +Comment[nl]=Zoek de betekenis van woorden op +Comment[nn]=Slå opp tydinga til ord +Comment[pa]=ਸ਼ਬਦ ਅਰਥ ਖੋਜ +Comment[pl]=Wyszukiwanie znaczenia słów +Comment[pt]=Procurar os significados das palavras +Comment[pt_BR]=Procurar os significados das palavras +Comment[ro]=Caută înțelesul cuvintelor +Comment[ru]=Показ значений слов или перевода +Comment[se]=Oza maid sátni máksá +Comment[si]=වදන් තේරුම් සෙවීම +Comment[sk]=Vyhľadávanie významov slov +Comment[sl]=Poiščite pomene besed +Comment[sr]=Потражите значења речи +Comment[sr@ijekavian]=Потражите значења ријечи +Comment[sr@ijekavianlatin]=Potražite značenja riječi +Comment[sr@latin]=Potražite značenja reči +Comment[sv]=Slå upp ords betydelse +Comment[ta]=Look up word meanings +Comment[te]=పదము అర్ధాలను చూడుము +Comment[tg]=Выяснение значения слов +Comment[th]=ค้นหาความหมายของคำ +Comment[tr]=Sözcük anlamlarına bak +Comment[ug]=سۆز مەنىسىنى ئىزدە +Comment[uk]=Пошук значень слів +Comment[vi]=Tìm kiếm nghĩa của từ +Comment[wa]=Cweri çou k' on mot vout dire +Comment[x-test]=xxLook up word meaningsxx +Comment[zh_CN]=查阅单词含义 +Comment[zh_TW]=尋找單字的意義 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=accessories-dictionary +X-KDE-Library=plasma_engine_dict + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=dict +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License= + + diff --git a/plasma/generic/dataengines/executable/CMakeLists.txt b/plasma/generic/dataengines/executable/CMakeLists.txt new file mode 100644 index 00000000..2baf1fa9 --- /dev/null +++ b/plasma/generic/dataengines/executable/CMakeLists.txt @@ -0,0 +1,10 @@ +set(executable_engine_SRCS + executable.cpp +) + +kde4_add_plugin(plasma_engine_executable ${executable_engine_SRCS}) +target_link_libraries(plasma_engine_executable ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS}) + +install(TARGETS plasma_engine_executable DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-executable.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/executable/executable.cpp b/plasma/generic/dataengines/executable/executable.cpp new file mode 100644 index 00000000..1df8009e --- /dev/null +++ b/plasma/generic/dataengines/executable/executable.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007, 2008 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "executable.h" +#include +#include +ExecutableContainer::ExecutableContainer(const QString& command, QObject* parent) + : Plasma::DataContainer(parent), m_process(0) +{ + setObjectName(command); + connect(this, SIGNAL(updateRequested(DataContainer*)), this, SLOT(exec())); + exec(); +} + +ExecutableContainer::~ExecutableContainer() +{ + delete m_process; +} + +void ExecutableContainer::finished(int exitCode, QProcess::ExitStatus exitStatus) +{ + //kDebug() << objectName(); + setData("exit code", exitCode); + setData("exit status", exitStatus); + setData("stdout", QString::fromLocal8Bit(m_process->readAllStandardOutput())); + setData("stderr", QString::fromLocal8Bit(m_process->readAllStandardError())); + checkForUpdate(); +} + +void ExecutableContainer::exec() +{ + //kDebug() << objectName(); + if (!m_process) { + m_process = new KProcess(); + connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(finished(int,QProcess::ExitStatus))); + m_process->setOutputChannelMode(KProcess::SeparateChannels); + m_process->setShellCommand(objectName()); + } + + if (m_process->state() == QProcess::NotRunning) { + m_process->start(); + } else { + kDebug() << "Process" << objectName() << "already running. Pid:" << m_process->pid(); + } +} + + +ExecutableEngine::ExecutableEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ + setMinimumPollingInterval(1000); +} + +bool ExecutableEngine::sourceRequestEvent(const QString& source) +{ + //kDebug() << source; + addSource(new ExecutableContainer(source, this)); + return true; +} + +#include "executable.moc" diff --git a/plasma/generic/dataengines/executable/executable.h b/plasma/generic/dataengines/executable/executable.h new file mode 100644 index 00000000..229b04a8 --- /dev/null +++ b/plasma/generic/dataengines/executable/executable.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007, 2008 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef EXECUTABLE_DATAENGINE_H +#define EXECUTABLE_DATAENGINE_H + +#include +#include +#include + +class ExecutableContainer : public Plasma::DataContainer +{ + Q_OBJECT + public: + explicit ExecutableContainer(const QString& command, QObject *parent = 0); + virtual ~ExecutableContainer(); + + protected slots: + void finished(int exitCode, QProcess::ExitStatus exitStatus); + void exec(); + + private: + KProcess* m_process; +}; + +class ExecutableEngine : public Plasma::DataEngine +{ + Q_OBJECT + public: + ExecutableEngine(QObject *parent, const QVariantList &args); + + protected: + virtual bool sourceRequestEvent(const QString& source); +}; + +K_EXPORT_PLASMA_DATAENGINE(executable, ExecutableEngine) + +#endif diff --git a/plasma/generic/dataengines/executable/plasma-dataengine-executable.desktop b/plasma/generic/dataengines/executable/plasma-dataengine-executable.desktop new file mode 100644 index 00000000..d91615e0 --- /dev/null +++ b/plasma/generic/dataengines/executable/plasma-dataengine-executable.desktop @@ -0,0 +1,161 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Run Commands +Name[ar]=شغّل أوامراً +Name[ast]=Executar órdenes +Name[be@latin]=Vykonvaj zahady +Name[bg]=Изпълнение на команди +Name[bn]=কমান্ড চালাও +Name[bn_IN]=কমান্ড সঞ্চালনা +Name[bs]=izvršavanje naredbi +Name[ca]=Execució d'ordres +Name[ca@valencia]=Execució d'ordes +Name[cs]=Spustit příkazy +Name[csb]=Zrëszanié pòlétów +Name[da]=Kør kommandoer +Name[de]=Befehle ausführen +Name[el]=Εκτέλεση εντολών +Name[en_GB]=Run Commands +Name[eo]=Lanĉi komandon +Name[es]=Ejecutar órdenes +Name[et]=Käsu käivitamine +Name[eu]=Exekutatu komandoak +Name[fi]=Suorita komentoja +Name[fr]=Exécuter des commandes +Name[fy]=Rin kommando's +Name[ga]=Rith Orduithe +Name[gl]=Executar ordes +Name[gu]=આદેશ ચલાવો +Name[he]=הרצת פקודות +Name[hi]=कमांड चलाएँ +Name[hne]=कमांड चलाव +Name[hr]=Pokreni naredbe +Name[hu]=Parancsvégrehajtó +Name[ia]=Exeque commandos +Name[id]=Jalankan Perintah +Name[is]=Keyra skipanir +Name[it]=Esegui comandi +Name[ja]=コマンドを実行 +Name[kk]=Команданы орындау +Name[km]=រត់​ពាក្យ​បញ្ជា +Name[kn]=ಆದೇಶಗಳನ್ನು ಚಲಾಯಿಸು +Name[ko]=명령 실행 +Name[ku]=Fermanan Bixebitîne +Name[lt]=Vykdyti komandas +Name[lv]=Palaist komandas +Name[mk]=Изврши наредби +Name[ml]=ആജ്ഞകള്‍ പ്രവര്‍ത്തിപ്പിയ്ക്കുക +Name[mr]=आदेश चालवा +Name[nb]=Kjør kommandoer +Name[nds]=Befehlen utföhren +Name[nl]=Commando's uitvoeren +Name[nn]=Køyr kommandoar +Name[or]=ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକୁ ଚଲାନ୍ତୁ +Name[pa]=ਕਮਾਂਡਾਂ ਚਲਾਓ +Name[pl]=Uruchom polecenia +Name[pt]=Execução de Comandos +Name[pt_BR]=Executar comandos +Name[ro]=Execută comenzi +Name[ru]=Выполнить команду +Name[si]=විධාන ක්‍රියාත්මක කරන්න +Name[sk]=Spustiť príkazy +Name[sl]=Zaganjanje ukazov +Name[sr]=извршавање наредби +Name[sr@ijekavian]=извршавање наредби +Name[sr@ijekavianlatin]=izvršavanje naredbi +Name[sr@latin]=izvršavanje naredbi +Name[sv]=Kör kommandon +Name[ta]=இயக்க ஆணைகள் +Name[tg]=Иҷрои фармонҳо +Name[th]=ประมวลผลคำสั่ง +Name[tr]=Komut Çalıştır +Name[ug]=بۇيرۇقلارنى ئىجرا قىل +Name[uk]=Виконання команд +Name[wa]=Enonder des cmandes +Name[x-test]=xxRun Commandsxx +Name[zh_CN]=运行命令 +Name[zh_TW]=執行指令 +Comment=Run Executable Data Engine +Comment[ar]=شغل محرك البيانات التنفيذية +Comment[ast]=Executar motor de datos executables +Comment[be@latin]=Uklučaj systemu dostupu da źviestak +Comment[bg]=Изпълнение на програми +Comment[bs]=Datomotor pokretanja izvršnih +Comment[ca]=Motor de dades d'ordres executables +Comment[ca@valencia]=Motor de dades d'ordes executables +Comment[cs]=Spustit rozhraní pro spouštění programů +Comment[csb]=Zrëszanié wëkònëwólnëgò mòtóra pòdôwków +Comment[da]=Datamotor til at afvikle kørbare filer +Comment[de]=Datentreiber für ausführbare Objekte +Comment[el]=Μηχανή δεδομένων εκκίνησης εκτελέσιμων +Comment[en_GB]=Run Executable Data Engine +Comment[es]=Ejecutar motor de datos ejecutables +Comment[et]=Käsu käivitamise andmete mootor +Comment[eu]=Exekutatu exekutagarriaren datu-motorra +Comment[fi]=Suorita suoritettava datakone +Comment[fr]=Lancer le moteur de données d'exécutables +Comment[fy]=Utfierbere gegevensmotor starten +Comment[ga]=Rith Inneall Sonraí Executable +Comment[gl]=Executa o motor de dados de executábeis +Comment[gu]=ચલાવી શકાય તેવું માહિતી એન્જિન ચલાવો +Comment[he]=מנוע תוכן הרצת קובץ Executable +Comment[hi]=एक्जीक्यूटेबल डाटा इंजिन चलाएं +Comment[hne]=चलाय वाले डाटा इंजन चलाव +Comment[hr]=Pokreni izvršive podatkovne mehanizme +Comment[hu]=Adatkezelő futtatása +Comment[ia]=Motor per exequer datos executabile +Comment[id]=Jalankan Mesin Data Tereksekusi +Comment[is]=Gagnavél fyrir keyrslu forrita +Comment[it]=Motore di dati per esecuzione di comandi +Comment[ja]=コマンド実行のデータエンジン +Comment[kk]=Орындайтын деректер тетігін жегу +Comment[km]=រត់​ម៉ាស៊ីន​ទិន្នន័យ​ដែលអាច​ប្រតិបត្តិ​បាន +Comment[kn]=ಚಾಲನಾಯೋಗ್ಯವಾದ ದತ್ತ ಸಾಧನವನ್ನು ಚಲಾಯಿಸಿ +Comment[ko]=명령 실행 데이터 엔진 +Comment[ku]=Motora Dane yên Tên Xebitandin Bixebitîne +Comment[lt]=Leisti vykdomąjį duomenų variklį +Comment[lv]=Izpildfailu palaišanas datu dzinējs +Comment[ml]=പ്രവര്‍ത്തിക്കാന്‍ കഴിയുന്ന ഡേറ്റാ എഞ്ചിന്‍ പ്രവര്‍ത്തിപ്പിയ്ക്കുക +Comment[mr]=कार्यान्वितजोगी Data Engine चालवा +Comment[nb]=Datamotor for kjørbare filer/programmer +Comment[nds]=Programmoproop-Datenkarn +Comment[nl]=Uitvoerbare gegevensengine starten +Comment[nn]=Datamotor for kommandokøyrar +Comment[or]=ନିଷ୍ପାଦ୍ୟ ତଥ୍ୟ ଯନ୍ତ୍ର ଚଲାନ୍ତୁ +Comment[pa]=ਚੱਲਣਯੋਗ ਡਾਟਾ ਇੰਜਣ ਚਲਾਓ +Comment[pl]=Silnik uruchamiania wykonywalnych danych +Comment[pt]=Motor de Dados de Execução de Comandos +Comment[pt_BR]=Mecanismo de dados da execução de comandos +Comment[ro]=Motor de date pentru lansarea executabilelor +Comment[ru]=Источник данных исполняемых объектов +Comment[si]=ක්‍රියාකරවුම් දත්ත එන්ජිම +Comment[sk]=Dátový nástroj na spustenie programov +Comment[sl]=Podatkovni vir za zaganjanje ukazov +Comment[sr]=Датомотор покретања извршних +Comment[sr@ijekavian]=Датомотор покретања извршних +Comment[sr@ijekavianlatin]=Datomotor pokretanja izvršnih +Comment[sr@latin]=Datomotor pokretanja izvršnih +Comment[sv]=Datagränssnitt för att köra program +Comment[ta]=இயக்க வல்ல தேடு பொறி +Comment[tg]=Поставщик лент RSS +Comment[th]=กลไกข้อมูลการประมวลผลคำสั่ง +Comment[tr]=Çalıştırılabilir Veri Motorunu Başlat +Comment[ug]=ئىجراچان سانلىق-مەلۇمات ماتورىنى ئىجرا قىل +Comment[uk]=Виконати програму рушія даних +Comment[wa]=Enonder des éndjins des dnêyes enondåves +Comment[x-test]=xxRun Executable Data Enginexx +Comment[zh_CN]=运行程序数据引擎 +Comment[zh_TW]=執行可執行資料引擎 +ServiceTypes=Plasma/DataEngine +Type=Service +Icon=application-x-executable-script +X-KDE-Library=plasma_engine_executable + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=executable +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/favicons/CMakeLists.txt b/plasma/generic/dataengines/favicons/CMakeLists.txt new file mode 100644 index 00000000..9339ec5b --- /dev/null +++ b/plasma/generic/dataengines/favicons/CMakeLists.txt @@ -0,0 +1,12 @@ +set(favicons_engine_SRCS + favicons.cpp + faviconprovider.cpp +) + +kde4_add_plugin(plasma_engine_favicons ${favicons_engine_SRCS} ) +target_link_libraries(plasma_engine_favicons ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_engine_favicons DESTINATION ${PLUGIN_INSTALL_DIR} ) +install(FILES plasma-dataengine-favicons.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + diff --git a/plasma/generic/dataengines/favicons/faviconprovider.cpp b/plasma/generic/dataengines/favicons/faviconprovider.cpp new file mode 100644 index 00000000..acad2a30 --- /dev/null +++ b/plasma/generic/dataengines/favicons/faviconprovider.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 Tobias Koenig + * Copyright (C) 2008 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "faviconprovider.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +class FaviconProvider::Private +{ + public: + Private( FaviconProvider *parent ) + : q(parent) + { + } + + void imageRequestFinished( KJob *job ); + + FaviconProvider *q; + QImage image; + QString cachePath; +}; + +void FaviconProvider::Private::imageRequestFinished(KJob *job) +{ + if (job->error()) { + emit q->error(q); + return; + } + + KIO::StoredTransferJob *storedJob = qobject_cast(job); + image = QImage::fromData(storedJob->data()); + if (!image.isNull()) { + image.save(cachePath, "PNG"); + } + emit q->finished(q); +} + + +FaviconProvider::FaviconProvider(QObject *parent, const QString &url) + : QObject(parent), + m_url(url), + d(new Private(this)) +{ + KUrl faviconUrl(url); + if (faviconUrl.protocol().isEmpty()) { + faviconUrl = KUrl("http://" + url); + } + + const QString fileName = KMimeType::favIconForUrl(faviconUrl.url()); + + if (!fileName.isEmpty()) { + d->cachePath = KStandardDirs::locateLocal("cache", fileName + ".png"); + d->image.load(d->cachePath, "PNG"); + } else { + d->cachePath = KStandardDirs::locateLocal("cache", "favicons/" + faviconUrl.host() + ".png"); + faviconUrl.setPath("/favicon.ico"); + + if (faviconUrl.isValid()) { + KIO::StoredTransferJob *job = KIO::storedGet(faviconUrl, KIO::NoReload, KIO::HideProgressInfo); + //job->setProperty("uid", id); + connect(job, SIGNAL(result(KJob*)), this, SLOT(imageRequestFinished(KJob*))); + } + } +} + +FaviconProvider::~FaviconProvider() +{ + delete d; +} + +QImage FaviconProvider::image() const +{ + return d->image; +} + +QString FaviconProvider::identifier() const +{ + return m_url; +} + +#include "faviconprovider.moc" diff --git a/plasma/generic/dataengines/favicons/faviconprovider.h b/plasma/generic/dataengines/favicons/faviconprovider.h new file mode 100644 index 00000000..1f370f9d --- /dev/null +++ b/plasma/generic/dataengines/favicons/faviconprovider.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007 Tobias Koenig + * Copyright (C) 2008 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FAVICONPROVIDER_H +#define FAVICONPROVIDER_H + +#include + +class QImage; + +/** + * This class provides a favicon for a given url + */ +class FaviconProvider : public QObject +{ + Q_OBJECT + + public: + /** + * Creates a new favicon provider. + * + * @param parent The parent object. + */ + FaviconProvider( QObject *parent, const QString &url); + + /** + * Destroys the favicon provider. + */ + ~FaviconProvider(); + + /** + * Returns the requested image. + * + * Note: This method returns only a valid image after the + * finished() signal has been emitted. + */ + QImage image() const; + + /** + * Returns the identifier of the comic request (name + date). + */ + QString identifier() const; + + Q_SIGNALS: + /** + * This signal is emitted whenever a request has been finished + * successfully. + * + * @param provider The provider which emitted the signal. + */ + void finished( FaviconProvider *provider ); + + /** + * This signal is emitted whenever an error has occurred. + * + * @param provider The provider which emitted the signal. + */ + void error( FaviconProvider *provider ); + + private: + QString m_url; + + class Private; + Private* const d; + + Q_PRIVATE_SLOT( d, void imageRequestFinished(KJob *job) ) +}; + +#endif diff --git a/plasma/generic/dataengines/favicons/favicons.cpp b/plasma/generic/dataengines/favicons/favicons.cpp new file mode 100644 index 00000000..2eae6738 --- /dev/null +++ b/plasma/generic/dataengines/favicons/favicons.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "favicons.h" + +#include "faviconprovider.h" + +FaviconsEngine::FaviconsEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ +} + +FaviconsEngine::~FaviconsEngine() +{ +} + +bool FaviconsEngine::updateSourceEvent( const QString &identifier ) +{ + FaviconProvider *provider = new FaviconProvider(this, identifier); + + connect(provider, SIGNAL(finished(FaviconProvider*)), this, SLOT(finished(FaviconProvider*))); + connect(provider, SIGNAL(error(FaviconProvider*)), this, SLOT(error(FaviconProvider*))); + + if (provider->image() != QImage()) { + setData(provider->identifier(), "Icon", provider->image()); + } + + return true; +} + +bool FaviconsEngine::sourceRequestEvent(const QString &identifier) +{ + setData(identifier, QPixmap()); + return updateSourceEvent(identifier); +} + +void FaviconsEngine::finished(FaviconProvider *provider) +{ + setData(provider->identifier(), "Icon", provider->image()); + provider->deleteLater(); +} + +void FaviconsEngine::error(FaviconProvider *provider) +{ + setData(provider->identifier(), QImage()); + provider->deleteLater(); +} + +#include "favicons.moc" diff --git a/plasma/generic/dataengines/favicons/favicons.h b/plasma/generic/dataengines/favicons/favicons.h new file mode 100644 index 00000000..79565bf5 --- /dev/null +++ b/plasma/generic/dataengines/favicons/favicons.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Tobias Koenig + * Copyright (C) 2008 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FAVICONS_DATAENGINE_H +#define FAVICONS_DATAENGINE_H + +#include + +class FaviconProvider; + +/** + * This class provides favicons for websites + * + * the queries are just the url of websites we want to fetch an icon + */ +class FaviconsEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + FaviconsEngine( QObject* parent, const QVariantList& args ); + ~FaviconsEngine(); + + protected: + bool sourceRequestEvent( const QString &identifier ); + + protected Q_SLOTS: + bool updateSourceEvent( const QString &identifier ); + + private Q_SLOTS: + void finished( FaviconProvider* ); + void error( FaviconProvider* ); +}; + +K_EXPORT_PLASMA_DATAENGINE(favicons, FaviconsEngine) + +#endif diff --git a/plasma/generic/dataengines/favicons/plasma-dataengine-favicons.desktop b/plasma/generic/dataengines/favicons/plasma-dataengine-favicons.desktop new file mode 100644 index 00000000..bfc6704e --- /dev/null +++ b/plasma/generic/dataengines/favicons/plasma-dataengine-favicons.desktop @@ -0,0 +1,159 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Favicons +Name[ar]=أيقونات الويب +Name[ast]=Favicons +Name[be@latin]=Ikony sajtaŭ +Name[bg]=Уеб-икони +Name[bn]=ফ্যাভ-আইকন +Name[bn_IN]=Favicons +Name[bs]=favikone +Name[ca]=Icones de web +Name[ca@valencia]=Icones de web +Name[cs]=Oblíbené ikony +Name[csb]=Faviconë (ikònczi) +Name[da]=Favicons +Name[de]=Webseiten-Symbole +Name[el]=Αγαπημένα εικονίδια +Name[en_GB]=Favicons +Name[eo]=Favorikonoj +Name[es]=Favicons +Name[et]=Lemmikikoonid +Name[eu]=Gogoko-ikonoak +Name[fi]=Webbisivukuvakkeet +Name[fr]=Émoticônes +Name[fy]=Favicon-ôfbyldings +Name[ga]=Deilbhíní Ceanán +Name[gl]=Iconas de páxina web +Name[gu]=ફેવિકોન્સ +Name[he]=סמלי מועדפים +Name[hi]=फेविकॉन +Name[hne]=फेविकान +Name[hr]=Omiljene ikone +Name[hu]=Favikonok +Name[ia]=Favicons +Name[id]=Ikon Favorit +Name[is]=Veftáknmyndir (favicons) +Name[it]=Iconcine +Name[ja]=ファビコン +Name[kk]=Favicon таңбашалары +Name[km]=រូប​តំណាង​សំណព្វ +Name[kn]=ಫೆವಿಕಾನ್‌ಗಳು +Name[ko]=파비콘 +Name[ku]=Nîşanên Malperan +Name[lt]=Srities ženkliukai +Name[lv]=TīmekļaIkonas +Name[mai]=फेविकान +Name[mk]=Омилени икони +Name[ml]=ഇഷ്ടചിഹ്നങ്ങള്‍ +Name[mr]=Favicons +Name[nb]=Ikoner for favorittsteder +Name[nds]=Nettsieden-Lüttbiller +Name[nl]=Favicons +Name[nn]=Bokmerkeikon +Name[or]=Favicons +Name[pa]=ਫੇਵੀਕਾਨ +Name[pl]=Ikony witryn +Name[pt]='Favicons' +Name[pt_BR]=Favicons +Name[ro]=Pictograme favorite +Name[ru]=Значки сайтов +Name[si]=Favicons +Name[sk]=Favikony +Name[sl]=Ikone spletnih strani +Name[sr]=фавиконе +Name[sr@ijekavian]=фавиконе +Name[sr@ijekavianlatin]=favikone +Name[sr@latin]=favikone +Name[sv]=Favoritikoner +Name[ta]=சின்னங்கள் +Name[tg]=Нишонаҳои саҳифаи интернетӣ +Name[th]=ไอคอนเว็บ +Name[tr]=Site Simgeleri +Name[ug]=تور بېكەت سىنبەلگە +Name[uk]=Піктограми «Вибраного» +Name[wa]=Pititès imådjetes favicons +Name[x-test]=xxFaviconsxx +Name[zh_CN]=网站图标 +Name[zh_TW]=網站圖示 +Comment=Data Engine for getting favicons of web sites +Comment[ar]=محرك بيانات لجلب أيقونات مواقع الوِب +Comment[ast]=Motor de datos pa obtener favicons de los sitios web +Comment[be@latin]=Systema źviestak dla atrymańnia ikon sajtaŭ +Comment[bg]=Ядро за изтегляне на уеб-икони от сайтове +Comment[bs]=Datomotor za dobavljanje favikona veb sajtova +Comment[ca]=Motor de dades per obtenir icones de web dels llocs web +Comment[ca@valencia]=Motor de dades per obtindre icones de web dels llocs web +Comment[cs]=Mechanismus pro získávání ikon webových stránek +Comment[da]=Datamotor til at hente favicons fra hjemmesider +Comment[de]=Daten-Treiber zum Holen von Webseiten-Symbolen von Webseiten +Comment[el]=Μηχανή δεδομένων για ανάκτηση αγαπημένων εικονιδίων από ιστοσελίδες +Comment[en_GB]=Data Engine for getting favicons of web sites +Comment[es]=Motor de datos para obtener favicons de los sitios web +Comment[et]=Andmemootor lemmikikoonide hankimiseks veebilehekülgedelt +Comment[eu]=Webguneen gogoko-ikonoak eskuratzeko datu-motorra +Comment[fi]=Data-kone webbisivukuvakkeiden hakemiseksi +Comment[fr]=Moteur de données permettant d'obtenir les émoticônes des sites Web +Comment[fy]=Gegevens motor foar it krijen fan favicon-ôfbyldings fan websiden +Comment[ga]=Inneall Sonraí a fhaigheann deilbhíní ceanán ó shuímh Ghréasáin +Comment[gl]=Motor de datos para obter as iconas de páxina dos sitios web +Comment[gu]=વેબ સાઇટ્સનાં ફેવિકોન્સ મેળવવા માટે માહિતી એન્જિન +Comment[he]=מנוע תוכן להשגת סמלי מועדפים של אתרי אינטרנט +Comment[hi]=वेबसाइटों के फेविकॉन को प्राप्त करने के लिए डाटा इंजिन +Comment[hne]=वेब साइट के फेविकान लाय बर डाटा इंजिन +Comment[hr]=Podatkovni mehanizam za nabavljanje omiljenih ikona sa web stranica +Comment[hu]=Weboldalak favikonjainak letöltésére szolgáló adatmotor +Comment[ia]=Motor de datos per obtener favicons del sitos web +Comment[id]=Mesin Data untuk mendapatkan ikon favorit situs web +Comment[is]=Gagnavél til söfnunar á veftáknmyndum (favicons) +Comment[it]=Motore di dati per ottenere le iconcine dei siti Web +Comment[ja]=ウェブサイトのファビコンを取得するためのデータエンジン +Comment[kk]=Веб сайттарының таңбашаларын алу тетігі +Comment[km]=ម៉ាស៊ីន​ទិន្នន័យ​សម្រាប់​ទទួល​រូបតំណាង​សំណព្វ​របស់​តំបន់​បណ្ដាញ +Comment[kn]=ಜಾಲ ತಾಣಗಳ ಫೆವಿಕಾನ್‌ಗಳನ್ನು ಪಡೆಯಲು ನೆರವಾಗುವ ದತ್ತ ಎಂಜಿನ್ +Comment[ko]=웹 사이트의 파비콘을 가져오는 데이터 엔진 +Comment[lt]=Duomenų variklis srities ženkliukų atsisiuntimui iš interneto +Comment[lv]=Datu dzinējs tīmekļa vietņu ikonu ielādei +Comment[mk]=Податочна машина за добивање омилени икони од веб-локации +Comment[ml]=വെബ് സൈറ്റുകളുടെ ഇഷ്ടചിഹ്നങ്ങള്‍ ലഭിക്കാനുള്ള ഡേറ്റ എഞ്ചിന്‍ +Comment[mr]=संकेत स्थळाचे favicons प्राप्त करण्याकरिता Data Engine +Comment[nb]=Datamotor for å hente favorittikoner fra nettsider +Comment[nds]=Datenkarn för Nettsieden-Lüttbiller +Comment[nl]=Gegevensengine voor het ophalen van favicons van websites +Comment[nn]=Datamotor for henting av bokmerkeikon til nettsider +Comment[pa]=ਵੈੱਬ ਸਾਇਟਾਂ ਲਈ ਫੈਵੀਕਾਨ ਲੈਣ ਲਈ ਡਾਟਾ ਇੰਜਣ +Comment[pl]=Silnik danych do pobierania ikon witryn +Comment[pt]=Um motor de dados para obter os 'favicons' das páginas Web +Comment[pt_BR]=Mecanismo de dados para busca dos favicons de páginas Web +Comment[ro]=Motor de date pentru preluarea pictogramelor siturilor web +Comment[ru]=Источник данных значков сайтов +Comment[si]=වෙබ් අඩවි වල favicon ලබාගැනීමේ දත්ත එන්ජිම +Comment[sk]=Dátový nástroj na získavanie favikon z webových stránok +Comment[sl]=Podatkovni vir za pridobivanje ikon spletnih strani +Comment[sr]=Датомотор за добављање фавикона веб сајтова +Comment[sr@ijekavian]=Датомотор за добављање фавикона веб сајтова +Comment[sr@ijekavianlatin]=Datomotor za dobavljanje favikona veb sajtova +Comment[sr@latin]=Datomotor za dobavljanje favikona veb sajtova +Comment[sv]=Datagränssnitt för att hämta favoritikoner för webbplatser +Comment[ta]=Data Engine for getting favicons of web sites +Comment[te]=వెబ్ సైటులయొక్క ఫెవికాన్లను(ఫేవరేట్ఐకాన్‍స్) పొందుటకొరకు డాటా యింజన్ +Comment[th]=กลไกข้อมูลสำหรับรับค่าไอคอนหน้าเว็บของเว็บไซต์ +Comment[tr]=Ağ sitelerinden site simgelerini almak için bir Veri Motoru +Comment[ug]=تور بېكەت سىنبەلگىسىگە ئېرىشىدىغان سانلىق-مەلۇمات ماتورى +Comment[uk]=Рушій даних для отримання піктограм для вебсайтів +Comment[vi]=Cơ chế dữ liệu để lấy các favicon cho trang web +Comment[wa]=Moteur di dnêyes pos cweri des favicons des waibes +Comment[x-test]=xxData Engine for getting favicons of web sitesxx +Comment[zh_CN]=用于获取网站图标的数据引擎 +Comment[zh_TW]=取得網站的圖示的資料引擎 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=view-web-browser-dom-tree +X-KDE-Library=plasma_engine_favicons + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=favicons +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= diff --git a/plasma/generic/dataengines/filebrowser/CMakeLists.txt b/plasma/generic/dataengines/filebrowser/CMakeLists.txt new file mode 100644 index 00000000..528414f4 --- /dev/null +++ b/plasma/generic/dataengines/filebrowser/CMakeLists.txt @@ -0,0 +1,10 @@ +set(filebrowser_engine_SRCS + filebrowserengine.cpp +) + +kde4_add_plugin(plasma_engine_filebrowser ${filebrowser_engine_SRCS}) +target_link_libraries(plasma_engine_filebrowser ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_engine_filebrowser DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-filebrowser.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/filebrowser/filebrowserengine.cpp b/plasma/generic/dataengines/filebrowser/filebrowserengine.cpp new file mode 100644 index 00000000..4a0cc93a --- /dev/null +++ b/plasma/generic/dataengines/filebrowser/filebrowserengine.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2007 Ivan Cukic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License either version 2, or + * (at your option) any later version as published by the Free Software + * Foundation. + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "filebrowserengine.h" + +#include + +#include +#include +#include +#include + +#define InvalidIfEmpty(A) ((A.isEmpty())?(QVariant()):(QVariant(A))) +#define forMatchingSources for (DataEngine::SourceDict::iterator it = sources.begin(); it != sources.end(); ++it) \ + if (dir == QDir(it.key())) + +FileBrowserEngine::FileBrowserEngine(QObject* parent, const QVariantList& args) : + Plasma::DataEngine(parent, args), m_dirWatch(NULL) +{ + Q_UNUSED(args) + + m_dirWatch = new KDirWatch(this); + connect(m_dirWatch, SIGNAL(created( + const QString &)), this, SLOT(dirCreated(QString))); + connect(m_dirWatch, SIGNAL(deleted( + const QString &)), this, SLOT(dirDeleted(QString))); + connect(m_dirWatch, SIGNAL(dirty( + const QString &)), this, SLOT(dirDirty(QString))); +} + +FileBrowserEngine::~FileBrowserEngine() +{ + delete m_dirWatch; +} + +void FileBrowserEngine::init() +{ + kDebug() << "init() called"; +} + +bool FileBrowserEngine::sourceRequestEvent(const QString &path) +{ + kDebug() << "source requested() called: "<< path; + m_dirWatch->addDir(path); + setData(path, "type", QVariant("unknown")); + updateData (path, INIT); + return true; +} + +void FileBrowserEngine::dirDirty(const QString &path) +{ + updateData(path, DIRTY); +} + +void FileBrowserEngine::dirCreated(const QString &path) +{ + updateData(path, CREATED); +} + +void FileBrowserEngine::dirDeleted(const QString &path) +{ + updateData(path, DELETED); +} + +void FileBrowserEngine::updateData(const QString &path, EventType event) +{ + Q_UNUSED(event) + + ObjectType type = NOTHING; + if (QDir(path).exists()) { + type = DIRECTORY; + } else if (QFile::exists(path)) { + type = FILE; + } + + DataEngine::SourceDict sources = containerDict(); + + QDir dir(path); + clearData(path); + + if (type == DIRECTORY) { + kDebug() << "directory info processing: "<< path; + if (dir.isReadable()) { + const QStringList visibleFiles = dir.entryList(QDir::Files, QDir::Name); + const QStringList allFiles = dir.entryList(QDir::Files | QDir::Hidden, + QDir::Name); + + const QStringList visibleDirectories = dir.entryList(QDir::Dirs + | QDir::NoDotAndDotDot, QDir::Name); + const QStringList allDirectories = dir.entryList(QDir::Dirs + | QDir::NoDotAndDotDot | QDir::Hidden, QDir::Name); + + forMatchingSources { + kDebug() << "MATCH"; + it.value()->setData("item.type", QVariant("directory")); + + QVariant vdTmp; + if (!visibleDirectories.isEmpty()) vdTmp = QVariant(visibleDirectories); + it.value()->setData("directories.visible", vdTmp); + + QVariant adTmp; + if (!allDirectories.empty()) adTmp = QVariant(allDirectories); + it.value()->setData("directories.all", adTmp); + + QVariant vfTmp; + if (!visibleFiles.empty()) vfTmp = QVariant(visibleFiles); + it.value()->setData("files.visible", vfTmp); + + QVariant afTmp; + if (!allFiles.empty()) afTmp = QVariant(allFiles); + it.value()->setData("files.all", afTmp); + } + } + } else if (type == FILE) { + kDebug() << "file info processing: "<< path; + KFileMetaInfo kfmi(path, QString(), KFileMetaInfo::Everything); + if (kfmi.isValid()) { + kDebug() << "METAINFO: " << kfmi.keys(); + + forMatchingSources { + kDebug() << "MATCH"; + it.value()->setData("item.type", QVariant("file")); + + for (QHash< QString, KFileMetaInfoItem >::const_iterator i = kfmi.items().constBegin(); i != kfmi.items().constEnd(); ++i) { + it.value()->setData(i.key(), i.value().value()); + } + } + } + } else { + forMatchingSources { + it.value()->setData("item.type", QVariant("imaginary")); + } + }; + + scheduleSourcesUpdated(); + +} + +void FileBrowserEngine::clearData(const QString &path) +{ + QDir dir(path); + const DataEngine::SourceDict sources = containerDict(); + for (DataEngine::SourceDict::const_iterator it = sources.begin(); it + != sources.end(); ++it) { + if (dir == QDir(it.key())) { + kDebug() << "matched: "<< path << " "<< it.key(); + it.value()->removeAllData(); + + } else { + kDebug() << "didn't match: "<< path << " "<< it.key(); + } + } +} + +#include "filebrowserengine.moc" diff --git a/plasma/generic/dataengines/filebrowser/filebrowserengine.h b/plasma/generic/dataengines/filebrowser/filebrowserengine.h new file mode 100644 index 00000000..ad723d26 --- /dev/null +++ b/plasma/generic/dataengines/filebrowser/filebrowserengine.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007 Ivan Cukic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License either version 2, or + * (at your option) any later version as published by the Free Software + * Foundation. + * + * 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; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FILEBROWSERENGINE_H +#define FILEBROWSERENGINE_H + +#include + +class KDirWatch; + +/** + * This class evaluates the basic expressions given in the interface. + */ +class FileBrowserEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + FileBrowserEngine( QObject* parent, const QVariantList& args ); + ~FileBrowserEngine(); + +protected: + bool sourceRequestEvent(const QString &path); + void init(); + +protected slots: + void dirDirty (const QString &path); + void dirCreated(const QString &path); + void dirDeleted(const QString &path); + +private: + enum EventType {INIT, DIRTY, CREATED, DELETED}; + enum ObjectType {NOTHING, FILE, DIRECTORY}; + + KDirWatch * m_dirWatch; + void updateData(const QString &path, EventType event); + void clearData(const QString &path); + + //QMap < QString, QStringList > m_regiteredListeners; +}; + +K_EXPORT_PLASMA_DATAENGINE(filebrowser, FileBrowserEngine) + +#endif diff --git a/plasma/generic/dataengines/filebrowser/plasma-dataengine-filebrowser.desktop b/plasma/generic/dataengines/filebrowser/plasma-dataengine-filebrowser.desktop new file mode 100644 index 00000000..b8f252a0 --- /dev/null +++ b/plasma/generic/dataengines/filebrowser/plasma-dataengine-filebrowser.desktop @@ -0,0 +1,162 @@ +[Desktop Entry] +Name=Files and Directories +Name[ar]=الملفات والمجلدات +Name[ast]=Ficheros y direutorios +Name[be@latin]=Fajły j katalohi +Name[bg]=Файлове и папки +Name[bn]=ফাইল এবং ডিরেক্টরি +Name[bn_IN]=ফাইল ও ডিরেক্টরি +Name[bs]=datoteke i fascikle +Name[ca]=Fitxers i directoris +Name[ca@valencia]=Fitxers i directoris +Name[cs]=Soubory a složky +Name[csb]=Lopczi ë katalodżi +Name[da]=Filer og mapper +Name[de]=Dateien und Ordner +Name[el]=Αρχεία και κατάλογοι +Name[en_GB]=Files and Directories +Name[eo]=Dosieroj kaj Dosierujoj +Name[es]=Archivos y directorios +Name[et]=Failid ja kataloogid +Name[eu]=Fitxategiak eta direktorioak +Name[fi]=Tiedostot ja kansiot +Name[fr]=Fichiers et dossiers +Name[fy]=triemmen en triemtafels +Name[ga]=Comhaid agus Comhadlanna +Name[gl]=Ficheiros e cartafoles +Name[gu]=ફાઇલો અને ડિરેક્ટરીઓ +Name[he]=קבצים ותיקיות +Name[hi]=फ़ाइलें तथा डिरेक्ट्रियाँ +Name[hne]=फाइल अउ डिरेक्टरी +Name[hr]=Datoteke i direktoriji +Name[hu]=Fájlok és mappák +Name[ia]=Files e directorios +Name[id]=Berkas dan Direktori +Name[is]=Skrár og möppur +Name[it]=File e cartelle +Name[ja]=ファイルとディレクトリ +Name[kk]=Файлдар мен Қапшықтар +Name[km]=ឯកសារ​ និង​ថត +Name[kn]=ಕಡತ ಹಾಗೂ ಕಡಕಕೋಶಗಳು +Name[ko]=파일과 디렉터리 +Name[lt]=Failai ir aplankai +Name[lv]=Faili un Mapes +Name[mai]=फाइल आओर निर्देशिका +Name[mk]=Датотеки и папки +Name[ml]=ഫയല്‍, തട്ട് എന്നിവ +Name[mr]=फाईल व संचयीका +Name[nb]=Filer og mapper +Name[nds]=Dateien un Ornern +Name[nl]=Bestanden en mappen +Name[nn]=Filer og mapper +Name[or]=ଫାଇଲ ଏବଂ ଡ଼ିରେକ୍ଟୋରୀଗୁଡ଼ିକ +Name[pa]=ਫਾਇਲਾਂ ਅਤੇ ਡਾਇਰੈਕਟਰੀਆਂ +Name[pl]=Pliki i katalogi +Name[pt]=Ficheiros e Pastas +Name[pt_BR]=Arquivos e pastas +Name[ro]=Fișiere și directoare +Name[ru]=Файлы и папки +Name[si]=ගොනු සහ බහලුම් +Name[sk]=Súbory a adresáre +Name[sl]=Datoteke in mape +Name[sr]=фајлови и фасцикле +Name[sr@ijekavian]=фајлови и фасцикле +Name[sr@ijekavianlatin]=fajlovi i fascikle +Name[sr@latin]=fajlovi i fascikle +Name[sv]=Filer och kataloger +Name[ta]=கோப்புகளும் அடைவுகளும் +Name[tg]=Проводник +Name[th]=ดูแฟ้มและไดเรกทอรี +Name[tr]=Dosyalar ve Dizinler +Name[ug]=ھۆججەت ۋە مۇندەرىجەلەر +Name[uk]=Файли і каталоги +Name[vi]=Tập tin và thư mục +Name[wa]=Fitchîs eyet ridants +Name[x-test]=xxFiles and Directoriesxx +Name[zh_CN]=文件和目录 +Name[zh_TW]=檔案與目錄 +Comment=Information about files and directories. +Comment[ar]=معلومات عن الملفات والمجلدات. +Comment[ast]=Información sobre los ficheros y direutorios. +Comment[bg]=Данни за файлове и папки. +Comment[bn]=ফাইল এবং ডিরেক্টরি সংক্রান্ত তথ্য। +Comment[bs]=Podaci o datotekema i fasciklama. +Comment[ca]=Informació quant a fitxers i directoris. +Comment[ca@valencia]=Informació quant a fitxers i directoris. +Comment[cs]=Informace o souborech a adresářích. +Comment[csb]=Wëdowiédzô ò lopkach ë katalogach. +Comment[da]=Information om filer og mapper. +Comment[de]=Informationen über Dateien und Ordner. +Comment[el]=Πληροφορίες για αρχεία και καταλόγους. +Comment[en_GB]=Information about files and directories. +Comment[eo]=Informoj pri dosieroj kaj dosierujoj +Comment[es]=Información sobre los archivos y directorios. +Comment[et]=Teave failide ja kataloogide kohta. +Comment[eu]=Fitxategi eta direktorioei buruzko informazioa +Comment[fi]=Tietoa tiedostosta ja hakemistoista. +Comment[fr]=Informations sur les fichiers et les dossiers. +Comment[fy]=Ynformaasje oer triemmen en triemtafels. +Comment[ga]=Eolas faoi chomhaid agus faoi chomhadlanna. +Comment[gl]=Información acerca de ficheiros e cartafoles. +Comment[gu]=ફાઇલો અને ડિરેક્ટરીઓ માટે માહિતી +Comment[he]=מידע על קבצים ותיקיות +Comment[hi]=फ़ाइलों व डिरेक्ट्रियों के बारे में जानकारी +Comment[hr]=Informacije o datotekama i direktorijima. +Comment[hu]=Fájl- és mappajellemzők. +Comment[ia]=Information re files e directorios. +Comment[id]=Informasi tentang berkas dan direktori. +Comment[is]=Upplýsingar um skrár og möppur. +Comment[it]=Informazioni su file e cartelle. +Comment[ja]=ファイルとディレクトリに関する情報 +Comment[kk]=Файлдар мен қыпшықтар туралы мәлімет +Comment[km]=ព័ត៌មាន​អំពី​ឯកសារ និង​ថត ។ +Comment[kn]=ಕಡತಗಳು ಹಾಗೂ ಕಡತಕೋಶಗಳ ಬಗೆಗೆ ಮಾಹಿತಿ. +Comment[ko]=파일과 디렉터리 정보입니다. +Comment[lt]=Informacija apie failus ir aplankus. +Comment[lv]=Informācija par failiem un mapēm. +Comment[mk]=Информации за датотеки и папки. +Comment[ml]=ഫയലുകളുടേയും തട്ടുകളുടേയും വിവരങ്ങള്‍. +Comment[mr]=फाईल्स व संचयीका विषयी माहिती. +Comment[nb]=Informasjon om filer og mapper. +Comment[nds]=Informatschonen över Dateien un Ornern +Comment[nl]=Informatie over bestanden en mappen. +Comment[nn]=Informasjon om filer og mapper. +Comment[pa]=ਫਾਇਲਾਂ ਅਤੇ ਡਾਇਰੈਕਟਰੀਆਂ ਵਾਸਤੇ ਜਾਣਕਾਰੀ +Comment[pl]=Informacje o plikach i katalogach. +Comment[pt]=Informação sobre os ficheiros e pastas. +Comment[pt_BR]=Informações sobre pastas e arquivos. +Comment[ro]=Informații despre fișiere și dosare. +Comment[ru]=Сведения о файлах и папках для виджетов. +Comment[si]=ගොනු හා බහාළුම් පිළිබඳ තොරතුරු +Comment[sk]=Informácie o súboroch a adresároch. +Comment[sl]=Podatki o datotekah in mapah. +Comment[sr]=Подаци о фајловима и фасциклама. +Comment[sr@ijekavian]=Подаци о фајловима и фасциклама. +Comment[sr@ijekavianlatin]=Podaci o fajlovima i fasciklama. +Comment[sr@latin]=Podaci o fajlovima i fasciklama. +Comment[sv]=Information om filer och kataloger. +Comment[tg]=Информация о папках и файлах для плазмоидов +Comment[th]=ข้อมูลเกี่ยวกับแฟ้มและไดเรกทอรีต่าง ๆ +Comment[tr]=Dosyalar ve dizinler hakkında bilgiler. +Comment[ug]=ھۆججەت ۋە مۇندەرىجەلەر ھەققىدە ئۇچۇرلار +Comment[uk]=Інформація про файли і каталоги. +Comment[vi]=Thông tin về tất cả các tập tin và thư mục. +Comment[wa]=Pondants et djondants so les ridants eyet les fitchîs. +Comment[x-test]=xxInformation about files and directories.xx +Comment[zh_CN]=关于文件和目录的信息。 +Comment[zh_TW]=關於檔案與目錄的資訊。 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=system-file-manager +X-KDE-Library=plasma_engine_filebrowser + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=filebrowser +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License= + + diff --git a/plasma/generic/dataengines/geolocation/CMakeLists.txt b/plasma/generic/dataengines/geolocation/CMakeLists.txt new file mode 100644 index 00000000..e911d593 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/CMakeLists.txt @@ -0,0 +1,63 @@ +project(geolocation) + +# ------------------------------------------------------------------------------------------------- + +set(plasma_geolocation_interface_SRCS geolocationprovider.cpp) +kde4_add_library(plasma-geolocation-interface SHARED ${plasma_geolocation_interface_SRCS}) +target_link_libraries(plasma-geolocation-interface ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) +target_link_libraries(plasma-geolocation-interface + LINK_INTERFACE_LIBRARIES ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) +set_target_properties(plasma-geolocation-interface PROPERTIES + VERSION ${GENERIC_LIB_VERSION} + SOVERSION ${GENERIC_LIB_SOVERSION} +) +install(TARGETS plasma-geolocation-interface ${INSTALL_TARGETS_DEFAULT_ARGS}) + +install(FILES geolocationprovider.h geolocation_export.h + DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/geolocation + COMPONENT Devel) + +#install(FILES includes/Interface +# DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/Plasma/Geolocation +# COMPONENT Devel) +# ------------------------------------------------------------------------------------------------- + +set(plasma_dataengine_geolocation_SRCS geolocation.cpp) +kde4_add_plugin(plasma_engine_geolocation ${plasma_dataengine_geolocation_SRCS}) +target_link_libraries(plasma_engine_geolocation + plasma-geolocation-interface + ${KDE4_PLASMA_LIBS} + ${KDE4_KDECORE_LIBS} + ${KDE4_KIO_LIBS} + ${KDE4_SOLID_LIBS}) + +install(TARGETS plasma_engine_geolocation DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-geolocation.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-geolocationprovider.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) + +# ------------------------------------------------------------------------------------------------- + +set(plasma_geolocation_ip_SRCS location_ip.cpp) +kde4_add_plugin(plasma-geolocation-ip ${plasma_geolocation_ip_SRCS}) +target_link_libraries(plasma-geolocation-ip plasma-geolocation-interface) +install(FILES plasma-geolocation-ip.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(TARGETS plasma-geolocation-ip DESTINATION ${PLUGIN_INSTALL_DIR}) + +# ------------------------------------------------------------------------------------------------- + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) +macro_optional_find_package(libgps) +set_package_properties(libgps PROPERTIES DESCRIPTION "GPS support for geolocation" + URL "http://gpsd.berlios.de/" + TYPE OPTIONAL + ) +if(LIBGPS_FOUND) + include_directories(${LIBGPS_INCLUDES} ${LIBGPS_INCLUDE_DIR}) + set(plasma_geolocation_gps_SRCS location_gps.cpp) + kde4_add_plugin(plasma-geolocation-gps ${plasma_geolocation_gps_SRCS}) + target_link_libraries(plasma-geolocation-gps plasma-geolocation-interface ${LIBGPS_LIBRARIES}) + install(FILES plasma-geolocation-gps.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + install(TARGETS plasma-geolocation-gps DESTINATION ${PLUGIN_INSTALL_DIR}) +endif(LIBGPS_FOUND) + +# ------------------------------------------------------------------------------------------------- diff --git a/plasma/generic/dataengines/geolocation/cmake/modules/Findlibgps.cmake b/plasma/generic/dataengines/geolocation/cmake/modules/Findlibgps.cmake new file mode 100644 index 00000000..71a4a084 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/cmake/modules/Findlibgps.cmake @@ -0,0 +1,16 @@ +# LIBGPS_FOUND - system has the LIBGPS library +# LIBGPS_INCLUDE_DIR - the LIBGPS include directory +# LIBGPS_LIBRARIES - The libraries needed to use LIBGPS + +if(LIBGPS_INCLUDE_DIR AND LIBGPS_LIBRARIES) + set(LIBGPS_FOUND TRUE) +else(LIBGPS_INCLUDE_DIR AND LIBGPS_LIBRARIES) + + find_path(LIBGPS_INCLUDE_DIR NAMES gps.h) + find_library(LIBGPS_LIBRARIES NAMES gps) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(libgps DEFAULT_MSG LIBGPS_INCLUDE_DIR LIBGPS_LIBRARIES) + + mark_as_advanced(LIBGPS_INCLUDE_DIR LIBGPS_LIBRARIES) +endif(LIBGPS_INCLUDE_DIR AND LIBGPS_LIBRARIES) diff --git a/plasma/generic/dataengines/geolocation/geolocation.cpp b/plasma/generic/dataengines/geolocation/geolocation.cpp new file mode 100644 index 00000000..65c376ae --- /dev/null +++ b/plasma/generic/dataengines/geolocation/geolocation.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2009 Petri Damsten + * + * 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. If not, see . + */ + +#include "geolocation.h" + +#include + +#include +#include + +static const char SOURCE[] = "location"; + +Geolocation::Geolocation(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args) + setMinimumPollingInterval(500); + connect(Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)), + this, SLOT(networkStatusChanged())); + m_updateTimer.setInterval(100); + m_updateTimer.setSingleShot(true); + connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(actuallySetData())); +} + +void Geolocation::init() +{ + //TODO: should this be delayed even further, e.g. when the source is requested? + const KService::List offers = KServiceTypeTrader::self()->query("Plasma/GeolocationProvider"); + QVariantList args; + + foreach (const KService::Ptr service, offers) { + QString error; + GeolocationProvider *plugin = service->createInstance(0, args, &error); + if (plugin) { + m_plugins << plugin; + plugin->init(&m_data, &m_accuracy); + connect(plugin, SIGNAL(updated()), this, SLOT(pluginUpdated())); + connect(plugin, SIGNAL(availabilityChanged(GeolocationProvider*)), + this, SLOT(pluginAvailabilityChanged(GeolocationProvider*))); + } else { + kDebug() << "Failed to load GeolocationProvider:" << error; + } + } +} + +Geolocation::~Geolocation() +{ + qDeleteAll(m_plugins); +} + +QStringList Geolocation::sources() const +{ + return QStringList() << SOURCE; +} + +bool Geolocation::updateSourceEvent(const QString &name) +{ + //kDebug() << name; + if (name == SOURCE) { + return updatePlugins(GeolocationProvider::SourceEvent); + } + + return false; +} + +bool Geolocation::updatePlugins(GeolocationProvider::UpdateTriggers triggers) +{ + bool changed = false; + + foreach (GeolocationProvider *plugin, m_plugins) { + changed = plugin->requestUpdate(triggers) || changed; + } + + if (changed) { + m_updateTimer.start(); + } + + return changed; +} + +bool Geolocation::sourceRequestEvent(const QString &name) +{ + kDebug() << name; + if (name == SOURCE) { + updatePlugins(GeolocationProvider::ForcedUpdate); + setData(SOURCE, m_data); + return true; + } + + return false; +} + +void Geolocation::networkStatusChanged() +{ + kDebug() << "network status changed"; + const Solid::Networking::Status netStatus = Solid::Networking::status(); + if ((netStatus == Solid::Networking::Connected) || (netStatus == Solid::Networking::Unknown)) { + updatePlugins(GeolocationProvider::NetworkConnected); + } +} + +void Geolocation::pluginAvailabilityChanged(GeolocationProvider *provider) +{ + m_data.clear(); + m_accuracy.clear(); + + provider->requestUpdate(GeolocationProvider::ForcedUpdate); + + bool changed = false; + foreach (GeolocationProvider *plugin, m_plugins) { + changed = plugin->populateSharedData() || changed; + } + + if (changed) { + m_updateTimer.start(); + } +} + +void Geolocation::pluginUpdated() +{ + m_updateTimer.start(); +} + +void Geolocation::actuallySetData() +{ + setData(SOURCE, m_data); +} + +#include "geolocation.moc" diff --git a/plasma/generic/dataengines/geolocation/geolocation.h b/plasma/generic/dataengines/geolocation/geolocation.h new file mode 100644 index 00000000..88acc8b9 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/geolocation.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Petri Damstén + * + * 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. If not, see . + */ + +#ifndef GEOLOCATION_DATAENGINE_H +#define GEOLOCATION_DATAENGINE_H + +#include + +#include +#include + +#include "geolocationprovider.h" + +class GeolocationProvider; + +class Geolocation : public Plasma::DataEngine +{ + Q_OBJECT + + public: + Geolocation(QObject* parent, const QVariantList& args); + virtual ~Geolocation(); + virtual void init(); + virtual QStringList sources() const; + + protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString& name); + bool updatePlugins(GeolocationProvider::UpdateTriggers triggers); + + protected slots: + void networkStatusChanged(); + void pluginAvailabilityChanged(GeolocationProvider *provider); + void pluginUpdated(); + void actuallySetData(); + + private: + Data m_data; + EntryAccuracy m_accuracy; + QList m_plugins; + QTimer m_updateTimer; +}; + +K_EXPORT_PLASMA_DATAENGINE(geolocation, Geolocation) + +#endif + diff --git a/plasma/generic/dataengines/geolocation/geolocation_export.h b/plasma/generic/dataengines/geolocation/geolocation_export.h new file mode 100644 index 00000000..c8df298f --- /dev/null +++ b/plasma/generic/dataengines/geolocation/geolocation_export.h @@ -0,0 +1,41 @@ +/* This file is part of the KDE project + Copyright (C) 2007 David Faure + Copyright (C) 2009 Petri Damsten + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef GEOLOCATION_EXPORT_H +#define GEOLOCATION_EXPORT_H + +/* needed for KDE_EXPORT and KDE_IMPORT macros */ +#include + +#ifndef GEOLOCATION_EXPORT +# if defined(MAKE_PLASMA_GEOLOCATION_INTERFACE_LIB) +/* We are building this library */ +# define GEOLOCATION_EXPORT KDE_EXPORT +# else +/* We are using this library */ +# define GEOLOCATION_EXPORT KDE_IMPORT +# endif +#endif + +# ifndef GEOLOCATION_EXPORT_DEPRECATED +# define GEOLOCATION_EXPORT_DEPRECATED KDE_DEPRECATED GEOLOCATION_EXPORT +# endif + +#endif diff --git a/plasma/generic/dataengines/geolocation/geolocationprovider.cpp b/plasma/generic/dataengines/geolocation/geolocationprovider.cpp new file mode 100644 index 00000000..a8729e5a --- /dev/null +++ b/plasma/generic/dataengines/geolocation/geolocationprovider.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2009 Aaron Seigo + * + * 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. If not, see . + */ + +#include "geolocationprovider.h" + +GeolocationProvider::GeolocationProvider(QObject *parent, const QVariantList &args) + : QObject(parent), + m_sharedData(0), + m_sharedAccuracies(0), + m_accuracy(1000), + m_updateTriggers(SourceEvent), + m_available(true), + m_updating(false) +{ + Q_UNUSED(args) + m_updateTimer.setSingleShot(true); + m_updateTimer.setInterval(0); + qRegisterMetaType("Plasma::DataEngine::Data"); + connect(&m_updateTimer, SIGNAL(timeout()), this, SIGNAL(updated())); +} + +void GeolocationProvider::init(Plasma::DataEngine::Data *data, EntryAccuracy *accuracies) +{ + m_sharedData = data; + m_sharedAccuracies = accuracies; + init(); +} + +int GeolocationProvider::accuracy() const +{ + return m_accuracy; +} + +bool GeolocationProvider::isAvailable() const +{ + return m_available; +} + +bool GeolocationProvider::requestUpdate(GeolocationProvider::UpdateTriggers triggers) +{ + if (m_available && !m_updating && (triggers == ForcedUpdate || triggers & m_updateTriggers)) { + m_updating = true; + update(); + return true; + } + + return false; +} + +GeolocationProvider::UpdateTriggers GeolocationProvider::updateTriggers() const +{ + return m_updateTriggers; +} + +bool GeolocationProvider::populateSharedData() +{ + Plasma::DataEngine::Data::const_iterator it = m_data.constBegin(); + bool changed = false; + + while (it != m_data.constEnd()) { + if (!m_sharedData->contains(it.key()) || m_sharedAccuracies->value(it.key()) < m_accuracy) { + m_sharedData->insert(it.key(), it.value()); + m_sharedAccuracies->insert(it.key(), m_accuracy); + changed = true; + } + + ++it; + } + + return changed; +} + +void GeolocationProvider::setAccuracy(int accuracy) +{ + m_accuracy = accuracy; +} + +void GeolocationProvider::setIsAvailable(bool available) +{ + if (m_available == available) { + return; + } + + m_available = available; + emit availabilityChanged(this); +} + +void GeolocationProvider::setData(const Plasma::DataEngine::Data &data) +{ + m_updating = false; + m_data = data; + if (populateSharedData()) { + m_updateTimer.start(); + } +} + +void GeolocationProvider::setData(const QString &key, const QVariant &value) +{ + m_updating = false; + m_data.insert(key, value); + + if (!m_sharedData->contains(key) || m_sharedAccuracies->value("key") < m_accuracy) { + m_sharedData->insert(key, value); + m_sharedAccuracies->insert(key, accuracy()); + m_updateTimer.start(); + } +} + +void GeolocationProvider::setUpdateTriggers(UpdateTriggers triggers) +{ + m_updateTriggers = triggers; +} + +void GeolocationProvider::init() +{ +} + +void GeolocationProvider::update() +{ +} + +#include "geolocationprovider.moc" diff --git a/plasma/generic/dataengines/geolocation/geolocationprovider.h b/plasma/generic/dataengines/geolocation/geolocationprovider.h new file mode 100644 index 00000000..c8024d6c --- /dev/null +++ b/plasma/generic/dataengines/geolocation/geolocationprovider.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2009 Aaron Seigo + * + * 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. If not, see . + */ + +#ifndef GEOLOCATIONPROVIDER_H +#define GEOLOCATIONPROVIDER_H + +#include +#include +#include + +#include + +#include "geolocation_export.h" + +typedef QHash EntryAccuracy; + +class GEOLOCATION_EXPORT GeolocationProvider : public QObject +{ + Q_OBJECT + +public: + enum UpdateTrigger { ForcedUpdate = 0, SourceEvent = 1, NetworkConnected = 2 }; + Q_DECLARE_FLAGS(UpdateTriggers, UpdateTrigger) + + GeolocationProvider(QObject *parent = 0, const QVariantList &args = QVariantList()); + void init(Plasma::DataEngine::Data *data, EntryAccuracy *accuracies); + + UpdateTriggers updateTriggers() const; + int accuracy() const; + bool isAvailable() const; + bool requestUpdate(UpdateTriggers trigger); + bool populateSharedData(); + +Q_SIGNALS: + void updated(); + void availabilityChanged(GeolocationProvider *provider); + +protected: + void setAccuracy(int accuracy); + void setIsAvailable(bool available); + void setUpdateTriggers(UpdateTriggers triggers); + virtual void init(); + virtual void update(); + +protected Q_SLOTS: + void setData(const Plasma::DataEngine::Data &data); + void setData(const QString &key, const QVariant &value); + +private: + Plasma::DataEngine::Data *m_sharedData; + EntryAccuracy *m_sharedAccuracies; + Plasma::DataEngine::Data m_data; + QTimer m_updateTimer; + int m_accuracy; + UpdateTriggers m_updateTriggers; + bool m_available : 1; + bool m_updating : 1; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(GeolocationProvider::UpdateTriggers) + +#define K_EXPORT_PLASMA_GEOLOCATIONPROVIDER(libname, classname) \ +K_PLUGIN_FACTORY(factory, registerPlugin();) \ +K_EXPORT_PLUGIN(factory("plasma_GeolocationProvider_" #libname)) \ +K_EXPORT_PLUGIN_VERSION(1.0) + +#endif + diff --git a/plasma/generic/dataengines/geolocation/location_gps.cpp b/plasma/generic/dataengines/geolocation/location_gps.cpp new file mode 100644 index 00000000..225d1027 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/location_gps.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2009 Petri Damstén + * + * 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. If not, see . + */ + +#include "location_gps.h" +#include + +Gpsd::Gpsd(gps_data_t* gpsdata) + : m_gpsdata(gpsdata) + , m_abort(false) +{ +} + +Gpsd::~Gpsd() +{ + m_abort = true; + m_condition.wakeOne(); + wait(); +} + +void Gpsd::update() +{ + if (!isRunning()) { + start(); + } else { + m_condition.wakeOne(); + } +} + +void Gpsd::run() +{ +#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 ) && defined( WATCH_ENABLE ) + gps_stream(m_gpsdata, WATCH_ENABLE, NULL); +#else + gps_query(m_gpsdata, "w+x\n"); +#endif + + while (!m_abort) { + Plasma::DataEngine::Data d; + +#if GPSD_API_MAJOR_VERSION >= 5 + if (gps_read(m_gpsdata) != -1) { +#else + if (gps_poll(m_gpsdata) != -1) { +#endif + //kDebug() << "poll ok"; + if (m_gpsdata->online) { + //kDebug() << "online"; + if (m_gpsdata->status != STATUS_NO_FIX) { + //kDebug() << "fix"; + d["accuracy"] = 30; + d["latitude"] = QString::number(m_gpsdata->fix.latitude); + d["longitude"] = QString::number(m_gpsdata->fix.longitude); + } + } + } + + emit dataReady(d); + + m_condition.wait(&m_mutex); + } +} + +Gps::Gps(QObject* parent, const QVariantList& args) + : GeolocationProvider(parent, args), + m_gpsd(0) +#if GPSD_API_MAJOR_VERSION >= 5 + , m_gpsdata(0) +#endif +{ +#if GPSD_API_MAJOR_VERSION >= 5 + m_gpsdata = new gps_data_t; + if (gps_open("localhost", DEFAULT_GPSD_PORT, m_gpsdata) != -1) { +#else + gps_data_t* m_gpsdata = gps_open("localhost", DEFAULT_GPSD_PORT); + if (m_gpsdata) { +#endif + kDebug() << "gpsd found."; + m_gpsd = new Gpsd(m_gpsdata); + connect(m_gpsd, SIGNAL(dataReady(Plasma::DataEngine::Data)), + this, SLOT(setData(Plasma::DataEngine::Data))); + } else { + kDebug() << "gpsd not found"; + } + + setIsAvailable(m_gpsd); +} + +Gps::~Gps() +{ + delete m_gpsd; +#if GPSD_API_MAJOR_VERSION >= 5 + delete m_gpsdata; +#endif +} + +void Gps::update() +{ + if (m_gpsd) { + m_gpsd->update(); + } +} + +K_EXPORT_PLASMA_GEOLOCATIONPROVIDER(gps, Gps) + +#include "location_gps.moc" diff --git a/plasma/generic/dataengines/geolocation/location_gps.h b/plasma/generic/dataengines/geolocation/location_gps.h new file mode 100644 index 00000000..dba65a26 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/location_gps.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009 Petri Damstén + * + * 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. If not, see . + */ + +#ifndef GPS_H +#define GPS_H + +#include +#include +#include +#include + +#include "geolocationprovider.h" + +class Gpsd : public QThread +{ + Q_OBJECT +public: + Gpsd(gps_data_t* gpsdata); + virtual ~Gpsd(); + + void update(); + +signals: + void dataReady(const Plasma::DataEngine::Data& data); + +protected: + virtual void run(); + +private: + gps_data_t* m_gpsdata; + QMutex m_mutex; + QWaitCondition m_condition; + bool m_abort; +}; + +class Gps : public GeolocationProvider +{ + Q_OBJECT +public: + explicit Gps(QObject *parent = 0, const QVariantList &args = QVariantList()); + ~Gps(); + + void update(); + +private: + Gpsd* m_gpsd; +#if GPSD_API_MAJOR_VERSION >= 5 + gps_data_t* m_gpsdata; +#endif +}; + +#endif diff --git a/plasma/generic/dataengines/geolocation/location_ip.cpp b/plasma/generic/dataengines/geolocation/location_ip.cpp new file mode 100644 index 00000000..6ffe0b16 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/location_ip.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2009 Petri Damstén + * - Original Implementation. + * 2009 Andrew Coles + * - Extension to iplocationtools engine. + * + * 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. If not, see . + */ + +#include "location_ip.h" +#include +#include +#include +#include + +class Ip::Private : public QObject { + +public: + QByteArray payload; + + void populateDataEngineData(Plasma::DataEngine::Data & outd) + { + QString country, countryCode, city, latitude, longitude, ip; + const QList &bl = payload.split('\n'); + payload.clear(); + foreach (const QByteArray &b, bl) { + const QList &t = b.split(':'); + if (t.count() > 1) { + const QByteArray k = t[0]; + const QByteArray v = t[1]; + if (k == "Latitude") { + latitude = v; + } else if (k == "Longitude") { + longitude = v; + } else if (k == "Country") { + QStringList cc = QString(v).split('('); + if (cc.count() > 1) { + country = cc[0].trimmed(); + countryCode = cc[1].replace(')', ""); + } + } else if (k == "City") { + city = v; + } else if (k == "IP") { + ip = v; + } + } + } + // ordering of first three to preserve backwards compatibility + outd["accuracy"] = 40000; + outd["country"] = country; + outd["country code"] = countryCode; + outd["city"] = city; + outd["latitude"] = latitude; + outd["longitude"] = longitude; + outd["ip"] = ip; + } +}; + +Ip::Ip(QObject* parent, const QVariantList& args) + : GeolocationProvider(parent, args), d(new Private()) +{ + setUpdateTriggers(SourceEvent | NetworkConnected); +} + +Ip::~Ip() +{ + delete d; +} + +void Ip::update() +{ + d->payload.clear(); + KIO::TransferJob *datajob = KIO::get(KUrl("http://api.hostip.info/get_html.php?position=true"), + KIO::NoReload, KIO::HideProgressInfo); + + if (datajob) { + kDebug() << "Fetching http://api.hostip.info/get_html.php?position=true"; + connect(datajob, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(readData(KIO::Job*,QByteArray))); + connect(datajob, SIGNAL(result(KJob*)), this, SLOT(result(KJob*))); + } else { + kDebug() << "Could not create job"; + } +} + +void Ip::readData(KIO::Job* job, const QByteArray& data) +{ + Q_UNUSED(job) + + if (data.isEmpty()) { + return; + } + d->payload.append(data); +} + +void Ip::result(KJob* job) +{ + Plasma::DataEngine::Data outd; + + if(job && !job->error()) { + d->populateDataEngineData(outd); + } else { + kDebug() << "error" << job->errorString(); + } + + setData(outd); +} + +K_EXPORT_PLASMA_GEOLOCATIONPROVIDER(ip, Ip) + +#include "location_ip.moc" diff --git a/plasma/generic/dataengines/geolocation/location_ip.h b/plasma/generic/dataengines/geolocation/location_ip.h new file mode 100644 index 00000000..a8eccd66 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/location_ip.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 Petri Damstén + * + * 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. If not, see . + */ + +#ifndef IP_H +#define IP_H + +#include "geolocationprovider.h" + +class KJob; +namespace KIO { + class Job; +} + +class Ip : public GeolocationProvider +{ + Q_OBJECT +public: + explicit Ip(QObject *parent = 0, const QVariantList &args = QVariantList()); + ~Ip(); + + virtual void update(); + +protected slots: + void readData(KIO::Job *, const QByteArray& data); + void result(KJob* job); + +private: + class Private; + Private *const d; + +}; + +#endif diff --git a/plasma/generic/dataengines/geolocation/plasma-dataengine-geolocation.desktop b/plasma/generic/dataengines/geolocation/plasma-dataengine-geolocation.desktop new file mode 100644 index 00000000..9a7a6ffd --- /dev/null +++ b/plasma/generic/dataengines/geolocation/plasma-dataengine-geolocation.desktop @@ -0,0 +1,150 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Geolocation +Name[ar]=الموقع الجغرافي +Name[ast]=Xeollocalización +Name[bg]=Геолокация +Name[bs]=geolokacija +Name[ca]=Geolocalització +Name[ca@valencia]=Geolocalització +Name[cs]=Geolokace +Name[csb]=Geògrafnô lokalizacëjô +Name[da]=Geo-lokalisering +Name[de]=Geolokalisierung +Name[el]=Γεωτοποθέτηση +Name[en_GB]=Geolocation +Name[eo]=GeoLokado +Name[es]=Geolocalización +Name[et]=Geolokatsioon +Name[eu]=Geokokapena +Name[fi]=Paikkasijainti +Name[fr]=Géo-localisation +Name[fy]=Geolokaasje +Name[ga]=Geolocation +Name[gl]=Xeolocalización +Name[he]=מציאת מיקום גאוגרפי +Name[hr]=Geolociranje +Name[hu]=Földrajzi helyzet +Name[ia]=Geolocation +Name[id]=Geolokasi +Name[is]=Hnattstaðsetningar +Name[it]=Geolocalizzazione +Name[ja]=ジオロケーション +Name[kk]=Жердегі орны +Name[km]=ទីតាំង​ភូមិសាស្ដ្រ +Name[kn]=ಭೂಪ್ರದೇಶ +Name[ko]=위치 +Name[lt]=Geolokacija +Name[lv]=Ģeolokācija +Name[mk]=Геолоцирање +Name[ml]=ഭൂസ്ഥാനങ്ങള്‍ +Name[mr]=जिओलोकेशन +Name[nb]=Geografisk plassering +Name[nds]=Eersteden +Name[nl]=Geolocatie +Name[nn]=Geolocation +Name[pa]=ਭੂਗੋਲਿਕ ਟਿਕਾਣਾ +Name[pl]=Geolokalizacja +Name[pt]=Geo-Localização +Name[pt_BR]=Localização geográfica +Name[ro]=Geolocație +Name[ru]=Местоположение +Name[si]=පිහිටුම +Name[sk]=Geolokalizácia +Name[sl]=Geolokacija +Name[sr]=геолокација +Name[sr@ijekavian]=геолокација +Name[sr@ijekavianlatin]=geolokacija +Name[sr@latin]=geolokacija +Name[sv]=Geografisk lokalisering +Name[tg]=Ҷойгиршавӣ +Name[th]=การระบุพิกัดตำแหน่ง +Name[tr]=Geolocation +Name[ug]=جۇغراپىيىلىك ئورۇن +Name[uk]=Геопозиціювання +Name[vi]=Vị trí địa lý +Name[wa]=Djeyoplaeçmint +Name[x-test]=xxGeolocationxx +Name[zh_CN]=地理 +Name[zh_TW]=Geolocation +Comment=Geolocation Data Engine +Comment[ar]=محرك بيانات الموقع الجغرافي +Comment[ast]=Motor de datos de xeollocalización +Comment[bg]=Ядро с данни за геолокация +Comment[bs]=Datomotor geolokacije +Comment[ca]=Motor de dades de geolocalització +Comment[ca@valencia]=Motor de dades de geolocalització +Comment[cs]=Datový nástroj geolokace +Comment[csb]=Czérownik pòdôwków geògrafny lokalizacëji +Comment[da]=Datamotor til geo-lokalisering +Comment[de]=Geolokalisierungs-Datentreiber +Comment[el]=Μηχανή δεδομένων γεωτοποθέτησης +Comment[en_GB]=Geolocation Data Engine +Comment[eo]=Datuma motoro de GeoLokado +Comment[es]=Motor de datos de geolocalización +Comment[et]=Geolokatsiooni andmete mootor +Comment[eu]=Geokokapen datuen motorra +Comment[fi]=Paikkasijaintidatakone +Comment[fr]=Moteur de données de géo-localisation +Comment[fy]=Geolokaasje gegevens motor +Comment[ga]=Inneall Sonraí Geolocation +Comment[gl]=Motor de datos de xeolocalización +Comment[he]=מנוע תוכן מציאת מיקום גאוגרפי +Comment[hr]=Podatkovni mehanizam za geolociranje +Comment[hu]=Kezelőmodul a földrajzi helyzet kiírásához +Comment[ia]=Motor de datos de geolocation +Comment[id]=Mesin Data Geolokasi +Comment[is]=Gagnavél fyrir hnattstaðsetningu +Comment[it]=Motore di dati per la geolocalizzazione +Comment[ja]=ジオロケーション用データエンジン +Comment[kk]=Жердегі орын туралы деректер тетігі +Comment[km]=ម៉ាស៊ីន​ទិន្នន័យ​ Geolocation +Comment[kn]=ಭೂಪ್ರದೇಶ ದತ್ತ ಯಂತ್ರ +Comment[ko]=위치 데이터 엔진 +Comment[lt]=Geolokacijos duomenų variklis +Comment[lv]=Ģeolokācijas datu dzinējs +Comment[mai]=भूअवस्थिति डाटा इंजिन +Comment[mk]=Машина за податоци за геолоцирање +Comment[ml]=ഭൂസ്ഥാനങ്ങള്‍ക്കുള്ള ഡേറ്റാ എഞ്ചിന്‍ +Comment[mr]=जिओलोकेशन डेटा इंजिन +Comment[nb]=Datamotor for geografisk plassering +Comment[nds]=Eersteden-Datenkarn +Comment[nl]=Geolocatie gegevensengine +Comment[nn]=Geolocation-datamotor +Comment[pa]=ਭੂਗੋਲਿਕ-ਟਿਕਾਣਾ ਡਾਟਾ ਇੰਜਣ +Comment[pl]=Silnik danych geolokalizacji +Comment[pt]=Motor de Dados de Geo-Localização +Comment[pt_BR]=Mecanismo de dados de localização geográfica +Comment[ro]=Motor de date Geolocație +Comment[ru]=Источник данных о местоположении +Comment[si]=භූපිහිටුම් දත්ත එන්ජිම +Comment[sk]=Dátový nástroj geolokalizácie +Comment[sl]=Podatkovni pogon s podatki o geolokaciji +Comment[sr]=Датомотор геолокације +Comment[sr@ijekavian]=Датомотор геолокације +Comment[sr@ijekavianlatin]=Datomotor geolokacije +Comment[sr@latin]=Datomotor geolokacije +Comment[sv]=Datagränssnitt för geografisk lokalisering +Comment[tg]=Барномаҳои луғат +Comment[th]=กลไกข้อมูลการระบุพิกัดตำแหน่ง +Comment[tr]=Geolocation Veri Motoru +Comment[ug]=جۇغراپىيىلىك ئورۇن سانلىق-مەلۇمات ماتورى +Comment[uk]=Рушій даних геопозиціювання +Comment[vi]=Cơ chế dữ liệu vị trí địa lý +Comment[wa]=Éndjin di dnêyes di djeyoplaeçmint +Comment[x-test]=xxGeolocation Data Enginexx +Comment[zh_CN]=地理位置数据引擎 +Comment[zh_TW]=Geolocation 資料引擎 +ServiceTypes=Plasma/DataEngine +Type=Service +Icon=applications-internet +X-KDE-Library=plasma_engine_geolocation + +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=geolocation +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma@kde.org +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/geolocation/plasma-geolocation-gps.desktop b/plasma/generic/dataengines/geolocation/plasma-geolocation-gps.desktop new file mode 100644 index 00000000..460d0102 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/plasma-geolocation-gps.desktop @@ -0,0 +1,143 @@ +[Desktop Entry] +Name=Geolocation GPS +Name[ar]=الموقع الجغرافي جي بي اس +Name[ast]=Xeollocalización per aciu de GPS +Name[bg]=Геолокация (GPS) +Name[bs]=geolokacija GPS +Name[ca]=Geolocalització GPS +Name[ca@valencia]=Geolocalització GPS +Name[cs]=Geolokace GPS +Name[csb]=Geògrafnô lokalizacëjô GPS +Name[da]=GPS til geo-lokalisering +Name[de]=Geolokalisierung GPS +Name[el]=GPS Γεωτοποθέτηση +Name[en_GB]=Geolocation GPS +Name[eo]=GPS loktrovado +Name[es]=Geolocalización mediante GPS +Name[et]=Geolokatsioon GPS-ist +Name[eu]=GPS geokokapena +Name[fi]=Paikkasijainti GPS +Name[fr]=Géo-localisation par GPS +Name[fy]=Geolokaasje GPS +Name[ga]=Córas Suite Domhanda Geolocation +Name[gl]=Xeolocalización con GPS +Name[he]=מציאת מיקום גאוגרפי GPS +Name[hr]=GPS geolociranje +Name[hu]=GPS-alapú helyzetjelző +Name[ia]=Geolocation GPS +Name[id]=GPS Geolokasi +Name[is]=GPS hnattstaðsetning +Name[it]=Geolocalizzazione GPS +Name[ja]=ジオロケーション GPS +Name[kk]=GPS-тен орнын табу +Name[km]=ទីតាំង​ភូមិសាស្ត្រ GPS +Name[kn]=ಭೂಪ್ರದೇಶದ GPS +Name[ko]=GPS 위치 +Name[lt]=Geolokacinis GPS +Name[lv]=Ģeolokācija GPS +Name[mai]=भूअवस्थिति जीपीएस +Name[mk]=ГПС за геолоцирање +Name[ml]=ജിപിഎസ് ഭൂസ്ഥാനങ്ങള്‍ +Name[mr]=GPS जिओलोकेशन +Name[nb]=Geografisk plassering GPS +Name[nds]=GPS-Eersteed +Name[nl]=Geolocatie GPS +Name[nn]=Geolocation GPS +Name[pa]=ਭੂਗੋਲਿਕ-ਟਿਕਾਣਾ GPS +Name[pl]=Geolokalizacja: GPS +Name[pt]=Geo-Localização por GPS +Name[pt_BR]=Localização geográfica GPS +Name[ro]=GPS geolocație +Name[ru]=Геолокация по GPS +Name[si]=පිහිටුම් GPS +Name[sk]=Geolokalizácia GPS +Name[sl]=Geolokacija GPS +Name[sr]=геолокација ГПС +Name[sr@ijekavian]=геолокација ГПС +Name[sr@ijekavianlatin]=geolokacija GPS +Name[sr@latin]=geolokacija GPS +Name[sv]=Lokalisera geografiskt med GPS +Name[tg]=Ҷойгиршавии GPS +Name[th]=การระบุพิกัดตำแหน่งด้วย GPS +Name[tr]=Geolocation GPS +Name[ug]=جۇغراپىيىلىك ئورۇن GPS +Name[uk]=Геопозиціювання за GPS +Name[vi]=Vị trí địa lý GPS +Name[wa]=GPS di djeyoplaeçmint +Name[x-test]=xxGeolocation GPSxx +Name[zh_CN]=GPS 位置 +Name[zh_TW]=Geolocation GPS +Comment=Geolocation from GPS address. +Comment[ar]=الموقع الجغرافي من عنوان جي بي اس +Comment[ast]=Xeollocalización dende una direición GPS. +Comment[bg]=Геолокация от GPS адрес. +Comment[bs]=Geolociranje kroz GPS adresu. +Comment[ca]=Geolocalització des d'una adreça GPS. +Comment[ca@valencia]=Geolocalització des d'una adreça GPS. +Comment[cs]=Geolokace z GPS adresy. +Comment[csb]=Geògrafnô lokalizacëjô z adresë GPS. +Comment[da]=Geo-lokalisering ud fra GPS-adresse. +Comment[de]=Geolokalisierung mittels GPS-Koordinate. +Comment[el]=Γεωτοποθέτηση από GPS διεύθυνση. +Comment[en_GB]=Geolocation from GPS address. +Comment[eo]=Loktrovado el GPS adreso +Comment[es]=Geolocalización desde una dirección GPS. +Comment[et]=Geolokatsioon GPS-aadressi põhjal +Comment[eu]=Geokokapena GPS helbidetik. +Comment[fi]=Paikkasijainti GPS-osoitteesta. +Comment[fr]=Géo-localisation depuis une adresse GPS. +Comment[fy]=Geolokaasje fan GPS adres. +Comment[ga]=Suíomh geografach ó sheoladh GPS. +Comment[gl]=Xeolocaliza con datos de GPS. +Comment[he]=מציאת מיקום גאוגרפי ממיקום GPS. +Comment[hr]=Geolociranje s GPS adrese. +Comment[hu]=A földrajzi helyzet meghatározása GPS segítségével. +Comment[ia]=Geolocation ex adresse GPS. +Comment[id]=Geolokasi dari alamat GPS. +Comment[is]=Hnattstaðsetning eftir GPS vistfangi. +Comment[it]=Geolocalizzazione dalla posizione GPS. +Comment[ja]=GPS アドレスによるジオロケーション +Comment[kk]=GPS адресінен орнын табу +Comment[km]=ទីតាំង​ភូមិសាស្ត្រ​ពី​អាយដ្ឋាន GPS ។ +Comment[kn]=GPS ವಿಳಾಸದಿಂದ ಭೂಪ್ರದೇಶ. +Comment[ko]=GPS 위치에 따른 주소입니다. +Comment[lt]=Geolokacija pagal GPS adresą. +Comment[lv]=Ģeolokācija no GPS adreses. +Comment[mai]=GPS पता सँ भूअवस्थिति. +Comment[mk]=Геолокација преку ГПС-адреса. +Comment[ml]=ജിപിഎസ് വിലാസത്തില്‍ നിന്നും ഭൂസ്ഥാനങ്ങള്‍ +Comment[mr]=GPS पत्त्यावरुन जिओलोकेशन. +Comment[nb]=Geografisk plassering etter GPS-adresse. +Comment[nds]=Eersteed ut GPS-Adress +Comment[nl]=Geolocatie uit GPS-adres. +Comment[nn]=Geolocation med GPS-adresse. +Comment[pa]=GPS ਐਡਰੈੱਸ ਤੋਂ ਭੂਗੋਲਿਕ ਟਿਕਾਣਾ। +Comment[pl]=Geolokalizacja z adresu GPS. +Comment[pt]=Geo-localização a partir do endereço do GPS. +Comment[pt_BR]=Localização geográfica de endereços de GPS. +Comment[ro]=Geolocație din adresă GPS. +Comment[ru]=Геолокация по адресу GPS. +Comment[si]=GPS ලිපින මගින් පිහිටුම +Comment[sk]=Geolokalizácia z GPS adresy. +Comment[sl]=Geolokacija iz podatkov GPS. +Comment[sr]=Геолоцирање кроз ГПС адресу. +Comment[sr@ijekavian]=Геолоцирање кроз ГПС адресу. +Comment[sr@ijekavianlatin]=Geolociranje kroz GPS adresu. +Comment[sr@latin]=Geolociranje kroz GPS adresu. +Comment[sv]=Geografisk lokalisering från GPS-adress. +Comment[tg]=Ҷойгиршавии ҷуғрофӣ аз суроғаи GPS +Comment[th]=การระบุพิกัดตำแหน่งจากพิกัด GPS +Comment[tr]=GPS adresinden coğrafi konum. +Comment[ug]=GPS ئادرېسنىڭ جۇغراپىيىلىك ئورنى +Comment[uk]=Геопозиціювання за GPS-адресою +Comment[vi]=Vị trí địa lý từ địa chỉ GPS. +Comment[wa]=Djeyoplaeçmint a pårti d' ene adresse GPS. +Comment[x-test]=xxGeolocation from GPS address.xx +Comment[zh_CN]=GPS 地址产生的位置 +Comment[zh_TW]=從 GPS 位址取得 Geolocation。 +X-KDE-ServiceTypes=Plasma/GeolocationProvider +X-KDE-ParentApp=geolocation +Type=Service +Icon=applications-internet +X-KDE-Library=plasma-geolocation-gps +X-KDE-PluginInfo-Name=gps diff --git a/plasma/generic/dataengines/geolocation/plasma-geolocation-ip.desktop b/plasma/generic/dataengines/geolocation/plasma-geolocation-ip.desktop new file mode 100644 index 00000000..a1a84da1 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/plasma-geolocation-ip.desktop @@ -0,0 +1,143 @@ +[Desktop Entry] +Name=Geolocation IP +Name[ar]=المواقع الجغرافي عنوان الانترنت +Name[ast]=Xeollocalización per aciu d'IP +Name[bg]=Геолокация (IP) +Name[bs]=geolokacija IP +Name[ca]=Geolocalització IP +Name[ca@valencia]=Geolocalització IP +Name[cs]=Geolokace IP +Name[csb]=IP geògrafny lokalizacëji +Name[da]=IP-adresse til geo-lokalisering +Name[de]=Geolokalisierung IP +Name[el]=Γεωτοποθεσίες IP +Name[en_GB]=Geolocation IP +Name[eo]=GeoLokado IP +Name[es]=Geolocalización mediante IP +Name[et]=Geolokatsioon IP-st +Name[eu]=IP geokokapen +Name[fi]=Paikkasijainti-ip-osoite +Name[fr]=Géo-localisation par IP +Name[fy]=Geolokaasje IP +Name[ga]=Geolocation IP +Name[gl]=Xeolocalización pola IP +Name[he]=מציאת מיקום גיאוגרפי IP +Name[hr]=IP geolociranje +Name[hu]=Földrajzi helyzet IP címmel +Name[ia]=Geolocation IP +Name[id]=IP Geolokasi +Name[is]=IP vistfang hnattstaðsetningar +Name[it]=Geolocalizzazione IP +Name[ja]=ジオロケーション IP +Name[kk]=IP-ден орнын табу +Name[km]=IP ទីតាំង​ភូមិសាស្ត្រ +Name[kn]=ಭೂಪ್ರದೇಶದ IP +Name[ko]=IP 위치 +Name[lt]=Geolokacija pagal IP +Name[lv]=Ģeolokācija IP +Name[mai]=भूअवस्थिति IP +Name[mk]=ИП за геолоцирање +Name[ml]=ഭൂസ്ഥാന ഐപി +Name[mr]=जिओलोकेशन IP +Name[nb]=Geografisk plassering IP +Name[nds]=IP-Eersteed +Name[nl]=Geolocatie-IP +Name[nn]=Geolocation IP +Name[pa]=ਭੂਗੋਲਿਕ-ਟਿਕਾਣਾ IP +Name[pl]=Geolokalizacja: IP +Name[pt]=Geo-Localização por IP +Name[pt_BR]=Localização geográfica IP +Name[ro]=IP geolocație +Name[ru]=Геолокация по IP-адресу +Name[si]=පිහිටුම් IP +Name[sk]=Geolokalizácia IP +Name[sl]=Geolokacija IP +Name[sr]=геолокација ИП +Name[sr@ijekavian]=геолокација ИП +Name[sr@ijekavianlatin]=geolokacija IP +Name[sr@latin]=geolokacija IP +Name[sv]=Lokalisera geografiskt med IP-adress +Name[tg]=Ҷойгиршавии IP +Name[th]=การระบุพิกัดตำแหน่งจากไอพี +Name[tr]=Geolocation IP +Name[ug]=جۇغراپىيىلىك ئورۇن IP +Name[uk]=Геопозиціювання за IP +Name[vi]=Vị trí địa lý IP +Name[wa]=Gjeyoplaeçmint di l' IP +Name[x-test]=xxGeolocation IPxx +Name[zh_CN]=IP 位置 +Name[zh_TW]=Geolocation IP +Comment=Geolocation from IP address. +Comment[ar]=الموقع الجغرافي من عنوان الإنترنت +Comment[ast]=Xeollocalización dende una direición IP. +Comment[bg]=Геолокация по IP-адрес. +Comment[bs]=Geolociranje kroz IP adresu. +Comment[ca]=Geolocalització des d'una adreça IP. +Comment[ca@valencia]=Geolocalització des d'una adreça IP. +Comment[cs]=Geolokace z IP adresy. +Comment[csb]=Geògrafnô lokalizacëjô z adresë IP. +Comment[da]=Geo-lokalisering ud fra IP-adresse. +Comment[de]=Geolokalisierung mittels IP-Adresse. +Comment[el]=Γεωτοποθέτηση από IP διεύθυνση. +Comment[en_GB]=Geolocation from IP address. +Comment[eo]=Loktrovado el IP Adreso +Comment[es]=Geolocalización desde una dirección IP. +Comment[et]=Geolokatsioon IP-aadressi põhjal +Comment[eu]=Geokokapena IP helbidetik. +Comment[fi]=Paikkasijainti ip-osoitteesta. +Comment[fr]=Géo-localisation depuis une adresse IP. +Comment[fy]=Geolokaassje fan IP adres. +Comment[ga]=Suíomh geografach ó sheoladh IP. +Comment[gl]=Xeolocaliza mediante o enderezo IP. +Comment[he]=מציאת מיקום גאוגרפי באמצעות כתובת IP. +Comment[hr]=Geolociranje pomoću IP adrese. +Comment[hu]=Meghatározza a földrajzi helyzetet az IP cím alapján. +Comment[ia]=Geolocation ex adresse IP +Comment[id]=Geolokasi dari alamat IP. +Comment[is]=Hnattstaðsetning eftir IP vistfangi. +Comment[it]=Geolocalizzazione dall'indirizzo IP. +Comment[ja]=IP アドレスによるジオロケーション +Comment[kk]=IP адресінен орнын табу +Comment[km]=ទីតាំង​ភូមិសាស្ត្រ​ពី​​អាសយដ្ឋាន IP ។ +Comment[kn]=IP ವಿಳಾಸದಿಂದ ಭೂಪ್ರದೇಶ. +Comment[ko]=IP에서 얻어낸 주소입니다. +Comment[lt]=Geolokacija pagal IP adresą. +Comment[lv]=Ģeolokācija no IP adreses. +Comment[mai]=IP पता से भूअवस्थिति. +Comment[mk]=Геолокација преку ИП-адреса. +Comment[ml]=ഐപി വിലാസനതില്‍ നിന്നും ഭൂസ്ഥാനങ്ങള്‍ +Comment[mr]=IP पत्त्यावरुन जिओलोकेशन. +Comment[nb]=Geografisk plassering etter IP adresse. +Comment[nds]=Eersteed ut IP-Adress +Comment[nl]=Geolocatie uit IP-adres. +Comment[nn]=Geolocation med IP-adresse. +Comment[pa]=IP ਐਡਰੈੱਸ ਤੋਂ ਭੂਗੋਲਿਕ-ਟਿਕਾਣਾ +Comment[pl]=Geolokalizacja za pomocą adresu IP. +Comment[pt]=Geo-localização a partir do endereço IP. +Comment[pt_BR]=Localização geográfica de endereços IP. +Comment[ro]=Geolocație din adresă IP. +Comment[ru]=Геолокация по IP-адресу. +Comment[si]=IP ලිපින තුළින් පිහිටුම +Comment[sk]=Geolokalizácia z IP adresy. +Comment[sl]=Geolokacija iz naslova IP. +Comment[sr]=Геолоцирање кроз ИП адресу. +Comment[sr@ijekavian]=Геолоцирање кроз ИП адресу. +Comment[sr@ijekavianlatin]=Geolociranje kroz IP adresu. +Comment[sr@latin]=Geolociranje kroz IP adresu. +Comment[sv]=Geografisk lokalisering från IP-adress. +Comment[tg]=Ҷойгиршавии сурағаи интернетӣ. +Comment[th]=การระบุพิกัดตำแหน่งจากที่อยู่ไอพี +Comment[tr]=IP adresinden coğrafi konum. +Comment[ug]=IP ئادرېسنىڭ جۇغراپىيىلىك ئورنى. +Comment[uk]=Геопозиціювання за IP-адресою +Comment[vi]=Vị trí địa lý từ địa chỉ IP. +Comment[wa]=Djeyoplaeçmint a pårti d' ene adresse IP. +Comment[x-test]=xxGeolocation from IP address.xx +Comment[zh_CN]=IP 地址确定的位置 +Comment[zh_TW]=從 IP 位址取得 Geolocation。 +X-KDE-ServiceTypes=Plasma/GeolocationProvider +X-KDE-ParentApp=geolocation +Type=Service +Icon=applications-internet +X-KDE-Library=plasma-geolocation-ip +X-KDE-PluginInfo-Name=ip diff --git a/plasma/generic/dataengines/geolocation/plasma-geolocationprovider.desktop b/plasma/generic/dataengines/geolocation/plasma-geolocationprovider.desktop new file mode 100644 index 00000000..92682c43 --- /dev/null +++ b/plasma/generic/dataengines/geolocation/plasma-geolocationprovider.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=Plasma/GeolocationProvider +Comment=Plasma Geolocation Provider +Comment[ar]=مزود الموقع الجغرافي لبلازما +Comment[ast]=Fornidor de xeollocalización de Plasma +Comment[bg]=Доставчик на геолокация Plasma +Comment[bs]=Plazma dobavljač geolokacije +Comment[ca]=Proveïdor de geolocalització del Plasma +Comment[ca@valencia]=Proveïdor de geolocalització del Plasma +Comment[cs]=Poskytovatel geolokace Plasma +Comment[csb]=Plazma geògrafny lokalizacëji +Comment[da]=Plasma geo-lokalisering-udbyder +Comment[de]=Plasma-Geolokalisierungs-Anbieter +Comment[el]=Πάροχος γεωτοποθέτησης Plasma +Comment[en_GB]=Plasma Geolocation Provider +Comment[eo]=Plasma GeoLokada provizanto +Comment[es]=Proveedor de geolocalización de Plasma +Comment[et]=Plasma geolokatsiooni pakkuja +Comment[eu]=Plasma geokokapen hornitzailea +Comment[fi]=Plasma-paikkasijaintitarjoaja +Comment[fr]=Fournisseur de géo-localisation de Plasma +Comment[fy]=Plasma Geolokaasje ferskaffer +Comment[ga]=Soláthraí Geolocation Plasma +Comment[gl]=Subministrador de xeolocalización para Plasma +Comment[he]=ספק מציאת מיקום גאוגרפי ל־Plasma +Comment[hr]=Podrška za Plasma geolociranje +Comment[hu]=Plasma helymeghatározó modul +Comment[ia]=Fornitor de geolocation de Plasma +Comment[id]=Penyedia Geolokasi Plasma +Comment[is]=Útgefandi hnattstaðsetningar fyrir Plasma +Comment[it]=Motore di geolocalizzazione di Plasma +Comment[ja]=Plasma ジオロケーション・プロバイダ +Comment[kk]=Plasma орнын табу құралы +Comment[km]=ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​ភូមិសាស្ត្រ​ប្លាស្មា +Comment[kn]=ಪ್ಲಾಸ್ಮಾ ಭೂಪ್ರದೇಶ ಒದಗಿಸುವ ಸಾಧನ +Comment[ko]=Plasma 위치 공급자 +Comment[lt]=Plasma geolokacijos paslaugos teikiklis +Comment[lv]=Plasma ģeolokācijas piegādātājs +Comment[mai]=प्लाज्मा भूअवस्थिति प्रदाता +Comment[ml]=പ്ലാസ്മയുടെ ഭൂസ്ഥാന ധാതാവ് +Comment[mr]=प्लाज्मा जिओलोकेशन पुरवठाकर्ता +Comment[nb]=Plasma-leverandør av geografisk plassering +Comment[nds]=Plasma sien Eersteden-Anbeder +Comment[nl]=Plasma Geolocatieleverancier +Comment[nn]=Plasma Geolocation-leverandør +Comment[pa]=ਪਲਾਜ਼ਮਾ ਭੂਗੋਲਿਕ ਪਰੋਵਾਇਡਰ +Comment[pl]=Dostawca geolokalizacji Plazmy +Comment[pt]=Fornecedor de Geo-Localização do Plasma +Comment[pt_BR]=Fornecedor de localização geográfica do Plasma +Comment[ro]=Furnizor de geolocație Plasma +Comment[ru]=Источник данных о географическом местонахождении +Comment[si]=ප්ලාස්මා පිහිටුම සැපයුම්කරු +Comment[sk]=Poskytovateľ geolokalizácie Plasma +Comment[sl]=Ponudnik geolokacije za Plasmo +Comment[sr]=Плазма добављач геолокације +Comment[sr@ijekavian]=Плазма добављач геолокације +Comment[sr@ijekavianlatin]=Plasma dobavljač geolokacije +Comment[sr@latin]=Plasma dobavljač geolokacije +Comment[sv]=Plasma geografisk lokalisering +Comment[tg]=Барномаҳои луғат +Comment[th]=ผู้ให้บริการพิกัดตำแหน่งของพลาสมา +Comment[tr]=Plasma Geolocation Sağlayıcı +Comment[ug]=پلازما جۇغراپىيىلىك ئورۇن تەمىنلىگۈچى +Comment[uk]=Інструмент геопозиціювання Плазми +Comment[wa]=Ahesseu di djeyopleçmint di Plasma +Comment[x-test]=xxPlasma Geolocation Providerxx +Comment[zh_CN]=Plasma 地理定位提供方 +Comment[zh_TW]=Plasma Geolocation 提供者 + diff --git a/plasma/generic/dataengines/hotplug/CMakeLists.txt b/plasma/generic/dataengines/hotplug/CMakeLists.txt new file mode 100644 index 00000000..bc94e1be --- /dev/null +++ b/plasma/generic/dataengines/hotplug/CMakeLists.txt @@ -0,0 +1,12 @@ +set(hotplug_engine_SRCS + hotplugengine.cpp + hotplugservice.cpp + hotplugjob.cpp +) + +kde4_add_plugin(plasma_engine_hotplug ${hotplug_engine_SRCS}) +target_link_libraries(plasma_engine_hotplug ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_engine_hotplug DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-hotplug.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES hotplug.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services ) diff --git a/plasma/generic/dataengines/hotplug/hotplug.operations b/plasma/generic/dataengines/hotplug/hotplug.operations new file mode 100644 index 00000000..c58d0dc3 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplug.operations @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/plasma/generic/dataengines/hotplug/hotplugengine.cpp b/plasma/generic/dataengines/hotplug/hotplugengine.cpp new file mode 100644 index 00000000..38e16310 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugengine.cpp @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2007 Menard Alexis + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "hotplugengine.h" +#include "hotplugservice.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//solid specific includes +#include +#include +#include +#include +#include +#include + +//#define HOTPLUGENGINE_TIMING + +HotplugEngine::HotplugEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_dirWatch(new KDirWatch(this)) +{ + QStringList folders = KGlobal::dirs()->findDirs("data", "solid/actions/"); + foreach (const QString &folder, folders) { + m_dirWatch->addDir(folder, KDirWatch::WatchFiles); + } + connect(m_dirWatch, SIGNAL(dirty(QString)), this, SLOT(updatePredicates(QString))); +} + +HotplugEngine::~HotplugEngine() +{ + +} + +void HotplugEngine::init() +{ + findPredicates(); + + Solid::Predicate p(Solid::DeviceInterface::StorageAccess); + p |= Solid::Predicate(Solid::DeviceInterface::StorageDrive); + p |= Solid::Predicate(Solid::DeviceInterface::StorageVolume); + p |= Solid::Predicate(Solid::DeviceInterface::OpticalDrive); + p |= Solid::Predicate(Solid::DeviceInterface::PortableMediaPlayer); + p |= Solid::Predicate(Solid::DeviceInterface::SmartCardReader); + p |= Solid::Predicate(Solid::DeviceInterface::Camera); + QList devices = Solid::Device::listFromQuery(p); + foreach (const Solid::Device &dev, devices) { + m_startList.insert(dev.udi(), dev); + } + + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), + this, SLOT(onDeviceAdded(QString))); + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), + this, SLOT(onDeviceRemoved(QString))); + + m_encryptedPredicate = Solid::Predicate("StorageVolume", "usage", "Encrypted"); + + processNextStartupDevice(); +} + +Plasma::Service* HotplugEngine::serviceForSource(const QString& source) +{ + return new HotplugService (this, source); +} + +void HotplugEngine::processNextStartupDevice() +{ + if (!m_startList.isEmpty()) { + QHash::iterator it = m_startList.begin(); + //Solid::Device dev = const_cast(m_startList.takeFirst()); + onDeviceAdded(it.value(), false); + m_startList.erase(it); + } + + if (m_startList.isEmpty()) { + m_predicates.clear(); + } else { + QTimer::singleShot(0, this, SLOT(processNextStartupDevice())); + } +} + +void HotplugEngine::findPredicates() +{ + m_predicates.clear(); + + foreach (const QString &path, KGlobal::dirs()->findAllResources("data", "solid/actions/")) { + KDesktopFile cfg(path); + const QString string_predicate = cfg.desktopGroup().readEntry("X-KDE-Solid-Predicate"); + //kDebug() << path << string_predicate; + m_predicates.insert(KUrl(path).fileName(), Solid::Predicate::fromString(string_predicate)); + } + + if (m_predicates.isEmpty()) { + m_predicates.insert(QString(), Solid::Predicate::fromString(QString())); + } +} + +void HotplugEngine::updatePredicates(const QString &path) +{ + Q_UNUSED(path) + + findPredicates(); + + QHashIterator it(m_devices); + while (it.hasNext()) { + it.next(); + Solid::Device device(it.value()); + QString udi(it.key()); + + const QStringList predicates = predicatesForDevice(device); + if (!predicates.isEmpty()) { + if (sources().contains(udi)) { + Plasma::DataEngine::Data data; + data.insert("predicateFiles", predicates); + setData(udi, data); + } else { + onDeviceAdded(device, false); + } + } else if (!m_encryptedPredicate.matches(device) && sources().contains(udi)) { + removeSource(udi); + scheduleSourcesUpdated(); + } + } +} + +QStringList HotplugEngine::predicatesForDevice(Solid::Device &device) const +{ + QStringList interestingDesktopFiles; + //search in all desktop configuration file if the device inserted is a correct device + QHashIterator it(m_predicates); + //kDebug() << "=================" << udi; + while (it.hasNext()) { + it.next(); + if (it.value().matches(device)) { + //kDebug() << " hit" << it.key(); + interestingDesktopFiles << it.key(); + } + } + + return interestingDesktopFiles; +} + +void HotplugEngine::onDeviceAdded(const QString &udi) +{ + Solid::Device device(udi); + onDeviceAdded(device); +} + +void HotplugEngine::onDeviceAdded(Solid::Device &device, bool added) +{ + //kDebug() << "adding" << device.udi(); +#ifdef HOTPLUGENGINE_TIMING + QTime t; + t.start(); +#endif + // Skip things we know we don't care about + if (device.is()) { + Solid::StorageDrive *drive = device.as(); + if (!drive->isHotpluggable()) { +#ifdef HOTPLUGENGINE_TIMING + kDebug() << "storage, but not pluggable, returning" << t.restart(); +#endif + return; + } + } else if (device.is()) { + Solid::StorageVolume *volume = device.as(); + Solid::StorageVolume::UsageType type = volume->usage(); + if ((type == Solid::StorageVolume::Unused || + type == Solid::StorageVolume::PartitionTable) && !device.is()) { +#ifdef HOTPLUGENGINE_TIMING + kDebug() << "storage volume, but not of interest" << t.restart(); +#endif + return; + } + } + + m_devices.insert(device.udi(), device); + + if (m_predicates.isEmpty()) { + findPredicates(); + } + + const QStringList interestingDesktopFiles = predicatesForDevice(device); + const bool isEncryptedContainer = m_encryptedPredicate.matches(device); + + if (!interestingDesktopFiles.isEmpty() || isEncryptedContainer) { + //kDebug() << device.product(); + //kDebug() << device.vendor(); + //kDebug() << "number of interesting desktop file : " << interestingDesktopFiles.size(); + Plasma::DataEngine::Data data; + data.insert("added", added); + data.insert("udi", device.udi()); + + if (!device.description().isEmpty()) { + data.insert("text", device.description()); + } else { + data.insert("text", QString(device.vendor() + QLatin1Char(' ') + device.product())); + } + data.insert("icon", device.icon()); + data.insert("emblems", device.emblems()); + data.insert("predicateFiles", interestingDesktopFiles); + + QVariantList actions; + foreach(const QString& desktop, interestingDesktopFiles) { + QString actionUrl = KStandardDirs::locate("data", "solid/actions/" + desktop); + QList services = KDesktopFileActions::userDefinedServices(actionUrl, true); + if (!services.isEmpty()) { + Plasma::DataEngine::Data action; + action.insert("predicate", desktop); + action.insert("text", services[0].text()); + action.insert("icon", services[0].icon()); + actions << action; + } + } + data.insert("actions", actions); + + data.insert("isEncryptedContainer", isEncryptedContainer); + + setData(device.udi(), data); + //kDebug() << "add hardware solid : " << udi; + } + +#ifdef HOTPLUGENGINE_TIMING + kDebug() << "total time" << t.restart(); +#endif +} + +void HotplugEngine::onDeviceRemoved(const QString &udi) +{ + //kDebug() << "remove hardware:" << udi; + + if (m_startList.contains(udi)) { + m_startList.remove(udi); + return; + } + + m_devices.remove(udi); + removeSource(udi); + scheduleSourcesUpdated(); +} + +K_EXPORT_PLASMA_DATAENGINE(hotplug, HotplugEngine) + +#include "hotplugengine.moc" diff --git a/plasma/generic/dataengines/hotplug/hotplugengine.h b/plasma/generic/dataengines/hotplug/hotplugengine.h new file mode 100644 index 00000000..8a90c9c3 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugengine.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Menard Alexis + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#ifndef HOTPLUGENGINE_H +#define HOTPLUGENGINE_H + +#include + +#include +#include + +#include + +class KDirWatch; + +/** + * This class is connected with solid, filter devices and provide signal with source for applet in Plasma + */ +class HotplugEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + HotplugEngine( QObject* parent, const QVariantList& args); + ~HotplugEngine(); + void init(); + Plasma::Service* serviceForSource(const QString& source); + + protected Q_SLOTS: + void onDeviceAdded(const QString &udi); + void onDeviceRemoved(const QString &udi); + + private: + void onDeviceAdded(Solid::Device &dev, bool added = true); + void findPredicates(); + QStringList predicatesForDevice(Solid::Device &device) const; + + private Q_SLOTS: + void processNextStartupDevice(); + void updatePredicates(const QString &path); + + private: + QHash m_predicates; + QHash m_startList; + QHash m_devices; + Solid::Predicate m_encryptedPredicate; + KDirWatch *m_dirWatch; +}; + +#endif diff --git a/plasma/generic/dataengines/hotplug/hotplugjob.cpp b/plasma/generic/dataengines/hotplug/hotplugjob.cpp new file mode 100644 index 00000000..b92afb88 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugjob.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "hotplugjob.h" +#include "hotplugengine.h" + +#include +#include + +#include + +void HotplugJob::start() +{ + QString udi (m_dest); + QString operation = operationName(); + + if (operation == "invokeAction") { + QString action = parameters()["predicate"].toString(); + + QStringList desktopFiles; + desktopFiles << action; + QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer"); + QDBusReply reply = soliduiserver.call("showActionsDialog", udi, desktopFiles); + } + + emitResult(); +} + +#include "hotplugjob.moc" + diff --git a/plasma/generic/dataengines/hotplug/hotplugjob.h b/plasma/generic/dataengines/hotplug/hotplugjob.h new file mode 100644 index 00000000..64f10354 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugjob.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef HOTPLUG_JOB_H +#define HOTPLUG_JOB_H + +#include "hotplugengine.h" + +#include + +class HotplugJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + HotplugJob (HotplugEngine* engine, + const QString& destination, + const QString& operation, + QMap& parameters, + QObject* parent = 0) + : ServiceJob (destination, operation, parameters, parent), + m_engine (engine), + m_dest (destination) + { + } + + void start(); + +private: + HotplugEngine* m_engine; + QString m_dest; +}; + +#endif // HOTPLUG_JOB_H + diff --git a/plasma/generic/dataengines/hotplug/hotplugservice.cpp b/plasma/generic/dataengines/hotplug/hotplugservice.cpp new file mode 100644 index 00000000..df7d199a --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugservice.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "hotplugservice.h" +#include "hotplugjob.h" +#include "hotplugengine.h" + +HotplugService::HotplugService (HotplugEngine* parent, const QString& source) + : Plasma::Service (parent), + m_engine(parent) +{ + setName ("hotplug"); + setDestination (source); +} + +Plasma::ServiceJob* HotplugService::createJob (const QString& operation, + QMap & parameters) +{ + return new HotplugJob (m_engine, destination(), operation, parameters, this); +} + +#include "hotplugservice.moc" + diff --git a/plasma/generic/dataengines/hotplug/hotplugservice.h b/plasma/generic/dataengines/hotplug/hotplugservice.h new file mode 100644 index 00000000..e02a6539 --- /dev/null +++ b/plasma/generic/dataengines/hotplug/hotplugservice.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef HOTPLUG_SERVICE_H +#define HOTPLUG_SERVICE_H + +#include + +class HotplugEngine; + +class HotplugService : public Plasma::Service +{ + Q_OBJECT + +public: + HotplugService (HotplugEngine* parent, const QString& source); + +protected: + Plasma::ServiceJob* createJob (const QString& operation, + QMap& parameters); + +private: + HotplugEngine *m_engine; + QString m_dest; +}; + +#endif // HOTPLUG_SERVICE_H + diff --git a/plasma/generic/dataengines/hotplug/plasma-dataengine-hotplug.desktop b/plasma/generic/dataengines/hotplug/plasma-dataengine-hotplug.desktop new file mode 100644 index 00000000..0d0024ab --- /dev/null +++ b/plasma/generic/dataengines/hotplug/plasma-dataengine-hotplug.desktop @@ -0,0 +1,146 @@ +[Desktop Entry] +Name=Hotplug Events +Name[ar]=أحداث التوصيل +Name[ast]=Eventos en caliente +Name[be@latin]=Źjaŭleńnie novych pryładaŭ +Name[bn]=হট-প্লাগ ঘটনাবলী +Name[bs]=događaji vrućeg uključivanja +Name[ca]=Esdeveniments de connexió en calent +Name[ca@valencia]=Esdeveniments de connexió en calent +Name[cs]=Události hotplugu +Name[csb]=Hotplug Event +Name[da]=Hotplug-begivenheder +Name[de]=Hotplug-Ereignisse +Name[el]=Γεγονότα Hotplug +Name[en_GB]=Hotplug Events +Name[eo]=Dumkura permuteblaj eventoj +Name[es]=Eventos en caliente +Name[et]=Hotplug-sündmused +Name[eu]=Hotplug gertaerak +Name[fi]=Hotplug-tapahtumat +Name[fr]=Événements de branchement à chaud +Name[fy]=Hotplug barren +Name[ga]=Imeachtaí Hotplug +Name[gl]=Acontecementos de Hotplug +Name[gu]=હોટપ્લગ ઇવેન્ટ્સ +Name[he]=אירועי חיבור התקנים נשלפים +Name[hi]=हाटप्लग घटनाएँ +Name[hne]=हाटप्लग घटना +Name[hr]=Događaji brzog uštekavanja +Name[hu]=Eszközcsatolást kezelő plazmoid +Name[ia]=Eventos de hotplug +Name[id]=Acara Hotplug +Name[is]=Hraðtengingaatburðir +Name[it]=Eventi di collegamento in marcia +Name[ja]=Hotplug イベント +Name[kk]=Істеп турғанда қосу оқиғалар +Name[km]=ព្រឹត្តិការណ៍​ដោត​ដើរ +Name[kn]=Hotplug ಘಟನೆಗಳು (ಈವೆಂಟ್) +Name[ko]=핫플러그 이벤트 +Name[lt]=Hotplug įvykiai +Name[lv]=Hotplug notikumi +Name[ml]=ഹോട്ട്പ്ലഗ് സംഭവങ്ങള്‍ +Name[mr]=हॉटप्लग घटना +Name[nb]=Tilkoblingshendelser +Name[nds]=Tokoppel-Begeefnissen +Name[nl]=Hotplug-gebeurtenissen +Name[nn]=Hotplug-hendingar +Name[pa]=ਹਾਟਪਲੱਗ ਈਵੈਂਟ +Name[pl]=Zdarzenia podłączenia "na gorąco" +Name[pt]=Eventos do Hotplug +Name[pt_BR]=Eventos do hotplug +Name[ro]=Evenimente de atașare +Name[ru]=Уведомление о подключении устройств +Name[si]=හොට් ප්ලග් අවස්ථා +Name[sk]=Hotplug udalosti +Name[sl]=Priključitve +Name[sr]=догађаји врућег укључивања +Name[sr@ijekavian]=догађаји врућег укључивања +Name[sr@ijekavianlatin]=događaji vrućeg uključivanja +Name[sr@latin]=događaji vrućeg uključivanja +Name[sv]=Inkopplingshändelser +Name[ta]=Hotplug Events +Name[tg]=Дастгоҳҳои пайвастшаванда +Name[th]=เหตุการณ์อุปกรณ์ Hot Plug +Name[tr]=Tak Kullan Olayları +Name[ug]=قىزىق قىستۇرۇش ھادىسىسى +Name[uk]=Події гарячого підключення +Name[vi]=Các sự kiện tháo lắp nóng +Name[wa]=Evenmints tchôd-tchôkîs +Name[x-test]=xxHotplug Eventsxx +Name[zh_CN]=热插拔事件 +Name[zh_TW]=熱插拔事件 +Comment=Tracks hot-pluggable devices as they appear and disappear. +Comment[ar]=تتابع الأجهزة المركبة عندما تظهر أو تختفي +Comment[ast]=Rexistra los preseos estrayibles cuando apaecen y desapaecen. +Comment[bs]=Prati pojavljivanja i nestanke vruće uklonjivih uređaja. +Comment[ca]=Segueix els dispositius de connexió en calent quan apareixen i desapareixen. +Comment[ca@valencia]=Segueix els dispositius de connexió en calent quan apareixen i desapareixen. +Comment[cs]=Oznamovat připojení a odpojení za běhu připojitelných zařízení +Comment[da]=Holder styr på flytbare enheder efterhånden som de dukker op og forsvinder. +Comment[de]=Überwacht Hotplug-Geräte auf Aktivierung und Deaktivierung +Comment[el]=Ανίχνευση συσκευών hot-plug καθώς εμφανίζονται και εξαφανίζονται. +Comment[en_GB]=Tracks hot-pluggable devices as they appear and disappear. +Comment[es]=Registra los dispositivos extraíbles cuando aparecen y desaparecen. +Comment[et]=Töö ajal ühendatavate seadmete ilmumise ja kadumise jälgimine. +Comment[eu]=Martxan konekta daitezkeen gailuen jarraipena egiten du agertu eta desagertzen diren heinean. +Comment[fi]=Jäljittää lennosta kytkeytyviä laitteita kun ne ilmaantuvat ja katoavat. +Comment[fr]=Surveille l'apparition ou la disparition des périphériques pouvant être connectés à chaud. +Comment[fy]=Hâld hot-pluggeble aparaten yn de gaten as se ferskine of ferside gean. +Comment[gl]=Segue a pista dos dispositivos conectábeis en quente á medida que van aparecendo e desaparecendo. +Comment[he]=משמש למעקב אחר התקנים נשלפים בעת חיבורם וניתוקם. +Comment[hr]=Pratite uređaje za brzo uštekavanje kako se pojavljuju i nestaju +Comment[hu]=Követi a menet közben csatolható (hot-pluggable) eszközöket. +Comment[ia]=Il tracia dispositivos hot-pluggable (insertabile a calide) assi como illos appare e disappare +Comment[id]=Lacak divais hot-plug ketika mereka muncul atau menghilang. +Comment[is]=Fylgist með hraðtengdum tækjum um leið og þau birtast eða hverfa. +Comment[it]=Sorveglia il collegamento e lo scollegamento dei dispositivi collegabili mentre il sistema è in funzione. +Comment[ja]=ホットプラグ可能なデバイスが抜き差しされるのを捕捉します。 +Comment[kk]=Істеп турғанда қосылатын құрылғылардың қосылғанын/ажыратылғанын бақылау. +Comment[km]=តាមដាន​ឧបករណ៍​ដែល​អាច​ដោត​ដើរ​ដូច​ពួកវា​បង្ហាញ និង​មិន​បង្ហាញ ។ +Comment[kn]=ಹಾಟ್‌-ಪ್ಲಗ್‌ ಮಾಡಬಹುದಾದಂತಹ ಸಾಧನಗಳು ಕಾಣಿಸಿಕೊಂಡಾಗ ಹಾಗು ಅಡಗಿಸಿದಾಗ ಅವುಗಳ ಜಾಡನ್ನು ಇರಿಸುತ್ತದೆ. +Comment[ko]=장치가 연결되고 해제될 때 기록합니다. +Comment[lt]=Seka įrenginių prijungimą ir atjungimą. +Comment[lv]=Seko līdzi noņemamo ierīču pieslēgšanai un atvienošanai. +Comment[ml]=കമ്പ്യൂട്ടര്‍ പ്രവര്‍ത്തിച്ചു് കൊണ്ടിരിക്കുമ്പോള്‍ കുത്താവുന്ന ഉപകരണങ്ങള്‍ പ്രത്യക്ഷപ്പെടുന്നതും അപ്രത്യക്ഷമാകുന്നതും നിരീക്ഷിക്കുന്നു. +Comment[mr]=हॉटप्लग करता येणाऱ्या साधनांवर लक्ष ठेवतो. +Comment[nb]=Sporer enheter som kan kobles til og fra ettersom de dukker opp og forsvinner +Comment[nds]=Luert op Reedschappen, de sik hitt tokoppeln laat +Comment[nl]=Volgt inplugbare apparaten als deze verschijnen en verdwijnen. +Comment[nn]=Sporar hotplug-einingar når dei dukkar opp og forsvinn. +Comment[pa]=ਹਾਟ-ਪਲੱਗਯੋਗ ਜੰਤਰ ਜਾਣਕਾਰੀ, ਜਿਵੇਂ ਉਹ ਲਗਾਏ ਤੇ ਹਟਾਏ ਜਾਣਗੇ। +Comment[pl]=Śledzenie urządzeń podłączanych "na gorąco", przy ich pojawianiu i znikaniu. +Comment[pt]=Segue os dispositivos removíveis, à medida que aparecem e desaparecem. +Comment[pt_BR]=Segue os dispositivos removíveis, à medida que aparecem e desaparecem. +Comment[ro]=Urmărește dispozitivele detașabile după cum apar sau dispar. +Comment[ru]=Следит за появлением и исчезновением подключаемых на лету устройств. +Comment[si]=හොට්-ප්ලග් කල හැකි උපකරණ ඒවා පෙනෙන හා නොපෙනෙන විට හඳුනාගන්න +Comment[sk]=Sleduje hot-plug zariadenia pri ich zobrazení a zmiznutí. +Comment[sl]=Sledi odstranljivim napravam, ki se pojavljajo in izginjajo. +Comment[sr]=Прати појављивања и нестанке вруће уклоњивих уређаја. +Comment[sr@ijekavian]=Прати појављивања и нестанке вруће уклоњивих уређаја. +Comment[sr@ijekavianlatin]=Prati pojavljivanja i nestanke vruće uklonjivih uređaja. +Comment[sr@latin]=Prati pojavljivanja i nestanke vruće uklonjivih uređaja. +Comment[sv]=Följer enheter som kan kopplas in under spänning när de dyker upp och försvinner. +Comment[th]=ติดตามการตรวจพบ/ไม่พบ อุปกรณ์ประเภทถอด/เสียบได้ +Comment[tr]=Takıldıklarında ve çıkarıldıklarında tak kullan aygıtlarını izler. +Comment[ug]=قىزىق قىستۇرۇلىدىغان ئۈسكۈنىلەرنىڭ ھاسىل بولۇشى ۋە يوقىلىشىنى ئىزلايدۇ. +Comment[uk]=Стежить за з’єднанням і від’єднанням портативних пристроїв. +Comment[wa]=Shût les édjins tchôd-tchôcåves cwand il aparexhèt et disparexhèt. +Comment[x-test]=xxTracks hot-pluggable devices as they appear and disappear.xx +Comment[zh_CN]=跟踪热插拔设备的产生与消失。 +Comment[zh_TW]=追蹤熱插拔裝置的插入與拔除。 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=drive-removable-media-usb +X-KDE-Library=plasma_engine_hotplug + +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=wilderkde@gmail.com +X-KDE-PluginInfo-Name=hotplug +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License= + diff --git a/plasma/generic/dataengines/keystate/CMakeLists.txt b/plasma/generic/dataengines/keystate/CMakeLists.txt new file mode 100644 index 00000000..3f921737 --- /dev/null +++ b/plasma/generic/dataengines/keystate/CMakeLists.txt @@ -0,0 +1,12 @@ +set(keystate_engine_SRCS + keystate.cpp + keyservice.cpp +) + +kde4_add_plugin(plasma_engine_keystate ${keystate_engine_SRCS}) +target_link_libraries(plasma_engine_keystate ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_engine_keystate DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-keystate.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES modifierkeystate.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/keystate/Messages.sh b/plasma/generic/dataengines/keystate/Messages.sh new file mode 100755 index 00000000..0c9356c3 --- /dev/null +++ b/plasma/generic/dataengines/keystate/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp` -o $podir/plasma_engine_keystate.pot diff --git a/plasma/generic/dataengines/keystate/keyservice.cpp b/plasma/generic/dataengines/keystate/keyservice.cpp new file mode 100644 index 00000000..dec8d3a1 --- /dev/null +++ b/plasma/generic/dataengines/keystate/keyservice.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Aaron Seigo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * This library is free software; you can redistribute it and/or + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "keyservice.h" + +#include + +KeyService::KeyService(QObject* parent, KModifierKeyInfo *keyInfo, Qt::Key key) + : Plasma::Service(parent), + m_keyInfo(keyInfo), + m_key(key) +{ + setName("modifierkeystate"); + setDestination("keys"); +} + +Plasma::ServiceJob* KeyService::createJob(const QString& operation, QMap& parameters) +{ + if (operation == "Lock") { + return new LockKeyJob(this, parameters); + } else if (operation == "Latch") { + return new LatchKeyJob(this, parameters); + } + + return 0; +} + +void KeyService::lock(bool lock) +{ + m_keyInfo->setKeyLocked(m_key, lock); +} + +void KeyService::latch(bool lock) +{ + m_keyInfo->setKeyLatched(m_key, lock); +} + +LockKeyJob::LockKeyJob(KeyService *service, const QMap ¶meters) + : Plasma::ServiceJob(service->destination(), "Lock", parameters, service), + m_service(service) +{ +} + +void LockKeyJob::start() +{ + m_service->lock(parameters().value("Lock").toBool()); + setResult(true); +} + +LatchKeyJob::LatchKeyJob(KeyService *service, const QMap ¶meters) + : Plasma::ServiceJob(service->destination(), "Lock", parameters, service), + m_service(service) +{ +} + +void LatchKeyJob::start() +{ + m_service->latch(parameters().value("Lock").toBool()); + setResult(true); +} + +#include "keyservice.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/keystate/keyservice.h b/plasma/generic/dataengines/keystate/keyservice.h new file mode 100644 index 00000000..c6a0a1b1 --- /dev/null +++ b/plasma/generic/dataengines/keystate/keyservice.h @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Aaron Seigo aseigo@kde.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef KEYSERVICE_H +#define KEYSERVICE_H + +#include +#include + +class KModifierKeyInfo; + +class KeyService : public Plasma::Service +{ + Q_OBJECT + +public: + KeyService(QObject* parent, KModifierKeyInfo *keyInfo, Qt::Key key); + void lock(bool lock); + void latch(bool lock); + +protected: + Plasma::ServiceJob* createJob(const QString& operation, QMap& parameters); + +private: + KModifierKeyInfo *m_keyInfo; + Qt::Key m_key; +}; + +class LockKeyJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + LockKeyJob(KeyService *service, const QMap ¶meters); + void start(); + +private: + KeyService *m_service; +}; + +class LatchKeyJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + LatchKeyJob(KeyService *service, const QMap ¶meters); + void start(); + +private: + KeyService *m_service; +}; + +#endif // KEYSERVICE_H diff --git a/plasma/generic/dataengines/keystate/keystate.cpp b/plasma/generic/dataengines/keystate/keystate.cpp new file mode 100644 index 00000000..99bdd760 --- /dev/null +++ b/plasma/generic/dataengines/keystate/keystate.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2009 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keystate.h" + + +#include +#include "keyservice.h" + +KeyStatesEngine::KeyStatesEngine(QObject *parent, const QVariantList &args) + : Plasma::DataEngine(parent, args) +{ + m_mods.insert(Qt::Key_Shift, I18N_NOOP("Shift")); + m_mods.insert(Qt::Key_Control, I18N_NOOP("Ctrl")); + m_mods.insert(Qt::Key_Alt, I18N_NOOP("Alt")); + m_mods.insert(Qt::Key_Meta, I18N_NOOP("Meta")); + m_mods.insert(Qt::Key_Super_L, I18N_NOOP("Super")); + m_mods.insert(Qt::Key_Hyper_L, I18N_NOOP("Hyper")); + m_mods.insert(Qt::Key_AltGr, I18N_NOOP("AltGr")); + m_mods.insert(Qt::Key_NumLock, I18N_NOOP("Num Lock")); + m_mods.insert(Qt::Key_CapsLock, I18N_NOOP("Caps Lock")); + m_mods.insert(Qt::Key_ScrollLock, I18N_NOOP("Scroll Lock")); + + m_buttons.insert(Qt::LeftButton, I18N_NOOP("Left Button")); + m_buttons.insert(Qt::RightButton, I18N_NOOP("Right Button")); + m_buttons.insert(Qt::MidButton, I18N_NOOP("Middle Button")); + m_buttons.insert(Qt::XButton1, I18N_NOOP("First X Button")); + m_buttons.insert(Qt::XButton2, I18N_NOOP("Second X Button")); +} + +KeyStatesEngine::~KeyStatesEngine() +{ +} + +void KeyStatesEngine::init() +{ + QMap::const_iterator it; + QMap::const_iterator end = m_mods.constEnd(); + for (it = m_mods.constBegin(); it != end; ++it) { + if (m_keyInfo.knowsKey(it.key())) { + Data data; + data.insert(I18N_NOOP("Pressed"), m_keyInfo.isKeyPressed(it.key())); + data.insert(I18N_NOOP("Latched"), m_keyInfo.isKeyLatched(it.key())); + data.insert(I18N_NOOP("Locked"), m_keyInfo.isKeyLocked(it.key())); + setData(it.value(), data); + } + } + + QMap::const_iterator it2; + QMap::const_iterator end2 = m_buttons.constEnd(); + for (it2 = m_buttons.constBegin(); it2 != end2; ++it2) { + Data data; + data.insert(I18N_NOOP("Pressed"), m_keyInfo.isButtonPressed(it2.key())); + setData(it2.value(), data); + } + + connect(&m_keyInfo, SIGNAL(keyPressed(Qt::Key,bool)), this, SLOT(keyPressed(Qt::Key,bool))); + connect(&m_keyInfo, SIGNAL(keyLatched(Qt::Key,bool)), this, SLOT(keyLatched(Qt::Key,bool))); + connect(&m_keyInfo, SIGNAL(keyLocked(Qt::Key,bool)), this, SLOT(keyLocked(Qt::Key,bool))); + connect(&m_keyInfo, SIGNAL(buttonPressed(Qt::MouseButton,bool)), + this, SLOT(mouseButtonPressed(Qt::MouseButton,bool))); + connect(&m_keyInfo, SIGNAL(keyAdded(Qt::Key)), this, SLOT(keyAdded(Qt::Key))); + connect(&m_keyInfo, SIGNAL(keyRemoved(Qt::Key)), this, SLOT(keyRemoved(Qt::Key))); +} + +Plasma::Service *KeyStatesEngine::serviceForSource(const QString &source) +{ + QMap::const_iterator it; + QMap::const_iterator end = m_mods.constEnd(); + for (it = m_mods.constBegin(); it != end; ++it) { + if (it.value() == source) { + return new KeyService(this, &m_keyInfo, it.key()); + } + } + + return Plasma::DataEngine::serviceForSource(source); +} + +void KeyStatesEngine::keyPressed(Qt::Key key, bool state) +{ + if (m_mods.contains(key)) { + setData(m_mods.value(key), I18N_NOOP("Pressed"), state); + } +} + +void KeyStatesEngine::keyLatched(Qt::Key key, bool state) +{ + if (m_mods.contains(key)) { + setData(m_mods.value(key), I18N_NOOP("Latched"), state); + } +} + +void KeyStatesEngine::keyLocked(Qt::Key key, bool state) +{ + if (m_mods.contains(key)) { + setData(m_mods.value(key), I18N_NOOP("Locked"), state); + } +} + +void KeyStatesEngine::mouseButtonPressed(Qt::MouseButton button, bool state) +{ + if (m_buttons.contains(button)) { + setData(m_buttons.value(button), I18N_NOOP("Pressed"), state); + } +} + +void KeyStatesEngine::keyAdded(Qt::Key key) +{ + if (m_mods.contains(key)) { + Data data; + data.insert(I18N_NOOP("Pressed"), m_keyInfo.isKeyPressed(key)); + data.insert(I18N_NOOP("Latched"), m_keyInfo.isKeyLatched(key)); + data.insert(I18N_NOOP("Locked"), m_keyInfo.isKeyLocked(key)); + setData(m_mods.value(key), data); + } +} + +void KeyStatesEngine::keyRemoved(Qt::Key key) +{ + if (m_mods.contains(key)) { + removeSource(m_mods.value(key)); + } +} + +K_EXPORT_PLASMA_DATAENGINE(keystate, KeyStatesEngine) + +#include "keystate.moc" diff --git a/plasma/generic/dataengines/keystate/keystate.h b/plasma/generic/dataengines/keystate/keystate.h new file mode 100644 index 00000000..f1ab1433 --- /dev/null +++ b/plasma/generic/dataengines/keystate/keystate.h @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYSTATEENGINE_H +#define KEYSTATEENGINE_H + +#include + +#include + +/** + * This engine provides the current state of the keyboard modifiers + * and mouse buttons, primarily useful for accessibility feature support. + */ +class KeyStatesEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + KeyStatesEngine(QObject *parent, const QVariantList &args); + ~KeyStatesEngine(); + + void init(); + Plasma::Service *serviceForSource(const QString &source); + +protected: + //bool sourceRequestEvent(const QString &name); + //bool updateSourceEvent(const QString &source); + +protected Q_SLOTS: + void keyPressed(Qt::Key key, bool state); + void keyLatched(Qt::Key key, bool state); + void keyLocked(Qt::Key key, bool state); + void mouseButtonPressed(Qt::MouseButton button, bool state); + void keyAdded(Qt::Key key); + void keyRemoved(Qt::Key key); + +private: + KModifierKeyInfo m_keyInfo; + QMap m_mods; + QMap m_buttons; +}; + +#endif // KEYSTATEENGINE_H diff --git a/plasma/generic/dataengines/keystate/modifierkeystate.operations b/plasma/generic/dataengines/keystate/modifierkeystate.operations new file mode 100644 index 00000000..492ef4e0 --- /dev/null +++ b/plasma/generic/dataengines/keystate/modifierkeystate.operations @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/keystate/plasma-dataengine-keystate.desktop b/plasma/generic/dataengines/keystate/plasma-dataengine-keystate.desktop new file mode 100644 index 00000000..7a36af1f --- /dev/null +++ b/plasma/generic/dataengines/keystate/plasma-dataengine-keystate.desktop @@ -0,0 +1,148 @@ +[Desktop Entry] +Name=Keyboard and Mouse State +Name[ar]=حالة لوحة المفاتيح والفأرة +Name[ast]=Estáu del tecláu y del mur +Name[bg]=Състояние на клавиатура и мишка +Name[bn]=কীবোর্ড ও মাউস অবস্থা +Name[bs]=stanje tastature i miša +Name[ca]=Estat del teclat i ratolí +Name[ca@valencia]=Estat del teclat i ratolí +Name[cs]=Stav klávesnice a myši +Name[csb]=Stón klawiaturë ë mëszë +Name[da]=Tilstand for tastatur og mus +Name[de]=Status von Tastatur und Maus +Name[el]=Κατάσταση πληκτρολογίου και ποντικιού +Name[en_GB]=Keyboard and Mouse State +Name[eo]=Stato de klavaro kaj muso +Name[es]=Estado del teclado y del ratón +Name[et]=Klaviatuuri ja hiire olek +Name[eu]=Teklatuaren eta saguaren egoera +Name[fi]=Näppäimistön ja hiiren tila +Name[fr]=États du clavier et de la souris +Name[fy]=Toetseboerd en mûs tastân +Name[ga]=Staid an Mhéarchláir agus na Luiche +Name[gl]=Estado do teclado e do rato +Name[gu]=કીબોર્ડ અને માઉસ સ્થિતિ +Name[he]=מצב מקלדת ועכבר +Name[hi]=कुंजीपट व माउस स्थिति +Name[hr]=Stanje tipkovnice i miša +Name[hu]=Egér- és billentyűzetállapot-jelző +Name[ia]=Stato del mus e del claviero +Name[id]=Kondisi Papan Ketik dan Tetikus +Name[is]=Staða lyklaborðs og músar +Name[it]=Stato di tastiera e mouse +Name[ja]=キーボードとマウスの状態 +Name[kk]=Перенетақта мен тышқанның күй-жайы +Name[km]=ស្ថានភាព​ក្ដារចុច និង​កណ្ដុល +Name[kn]=ಕೀಲಿಮಣೆ ಮತ್ತು ಮೌಸ್‌ನ ಸ್ಥಿತಿ +Name[ko]=키보드와 마우스 상태 +Name[lt]=Klaviatūros ir pelės būklė +Name[lv]=Tastatūra un peles stāvoklis +Name[mk]=Состојба на тастатура и глушец +Name[ml]=കീബോര്‍ഡിന്റേയും മൌസിന്റേയും അവസ്ഥ +Name[mr]=कळफलक व माऊस स्थिती +Name[nb]=Tilstand for tastatur og mus +Name[nds]=Tastatuur- un Muus-Status +Name[nl]=Toetsenbord en muisstatus +Name[nn]=Status for tastatur og mus +Name[pa]=ਕੀ-ਬੋਰਡ ਅਤੇ ਮਾਊਂਸ ਹਾਲਤ +Name[pl]=Stan klawiatury i myszy +Name[pt]=Estado do Teclado e Rato +Name[pt_BR]=Estado do teclado e mouse +Name[ro]=Starea tastaturii și mausului +Name[ru]=Состояние клавиатуры и мыши +Name[si]=යතුරුපුවරුව සහ මවුස තත්වය +Name[sk]=Stav klávesnice a myši +Name[sl]=Stanje tipkovnice in miške +Name[sr]=стање тастатуре и миша +Name[sr@ijekavian]=стање тастатуре и миша +Name[sr@ijekavianlatin]=stanje tastature i miša +Name[sr@latin]=stanje tastature i miša +Name[sv]=Tillstånd för tangentbord och mus +Name[tg]=Клавиатура ва муш +Name[th]=สถานะของแป้นพิมพ์และเมาส์ +Name[tr]=Klavye ve Fare Durumu +Name[ug]=ھەرپتاختا ۋە چاشقىنەك ھالىتى +Name[uk]=Стан клавіатури і миші +Name[vi]=Bàn phím và trạng thái chuột +Name[wa]=Estat del taprece et del sori +Name[x-test]=xxKeyboard and Mouse Statexx +Name[zh_CN]=键盘和鼠标状态 +Name[zh_TW]=鍵盤與滑鼠狀態 +Comment=Keyboard modifier and mouse buttons states +Comment[ar]=حالة أزرار الفأرة و مغيرات لوحة المفاتيح +Comment[ast]=Estáu del modificador de tecláu y botones del mur +Comment[bg]=Състояние на клавиатурни модификатори и бутони на мишката +Comment[bs]=Stanja modifikatora na tastaturi i dugmadi miša +Comment[ca]=Modificador de l'estat del teclat i dels botons del ratolí +Comment[ca@valencia]=Modificador de l'estat del teclat i dels botons del ratolí +Comment[cs]=Stavy modifikátorů klávesnice a tlačítek myši +Comment[csb]=Mòdifikatora klawiaturë ë stónu klawiszów mëszë +Comment[da]=Tilstand for tastaturets ændringstaster og museknapper +Comment[de]=Status von Modifizierer- und Maustasten +Comment[el]=Τροποποιητής πληκτρολογίου και κατάστασης κουμπιών ποντικιού +Comment[en_GB]=Keyboard modifier and mouse buttons states +Comment[es]=Estado del modificador de teclado y botones del ratón +Comment[et]=Klaviatuuri muuteklahvide ja hiirenuppude olekud +Comment[eu]=Teklatuaren aldatzailearen eta saguaren botoien egoerak +Comment[fi]=Näppäimistömääre ja hiiren painikkeiden tilat +Comment[fr]=Modificateur du clavier et des états des boutons de souris +Comment[fy]=Toetseboerd bewurker en mûsknop tastân +Comment[gl]=Estados das modificadoras do teclado e dos botóns do rato +Comment[he]=המצב של לחצני מקלדת משני מצב ולחצני עכבר +Comment[hr]=Stanja tipaka ctrl, alt, shift i tipaka miša +Comment[hu]=Módosítóbillentyűk és egérgombok +Comment[ia]=Modificator de claviero e statos de buttones del mus +Comment[id]=Pengubah pepan ketik dan kondisi tombol tetikus +Comment[is]=Breytingar á lyklaborði og músarhnöppum +Comment[it]=Stati dei modificatori della tastiera e dei pulsanti del mouse +Comment[ja]=キーボードの修飾キーとマウスボタンの状態 +Comment[kk]=Перенетақта түрлендіргіш және тышқан батырмаларының күй-жайы +Comment[km]=កម្មវិធី​កែប្រែ​ក្ដារចុច និង​ស្ថានភាព​ប៊ូតុង​កណ្ដុរ +Comment[kn]=ಕೀಲಿಮಣೆ ಮಾರ್ಪಡಕ ಹಾಗು ಮೌಸ್ ಗುಂಡಿಗಳ ಸ್ಥಿತಿಗಳು +Comment[ko]=키보드 수정자 키 및 마우스 단추 상태 +Comment[lt]=Klaviatūros būsenos ir pelės mygtukų būsenos stebėklis +Comment[lv]=Tastatūras modifikatoru un peles pogu stāvoklis +Comment[ml]=കീബോര്‍ഡ് മോഡിഫയറിന്റേയും മൌസ് ബട്ടണിന്റെയും സ്ഥിതി +Comment[mr]=कळफलक परिवर्तक व माऊस बटन स्थिती +Comment[nb]=Tilstand for modifikatortaster og museknapper +Comment[nds]=Sünnertasten- un Muusknoop-Tostänn +Comment[nl]=Wijzigt toetsenbord en muisknoptoestanden +Comment[nn]=Status for valtastar og museknappar +Comment[pa]=ਕੀਬੋਰਡ ਸੋਧਕ ਅਤੇ ਮਾਊਂਸ ਬਟਨ ਹਾਲਤ +Comment[pl]=Stany modyfikatorów klawiatury i przycisków myszy +Comment[pt]=Estados das teclas modificadoras e dos botões do rato +Comment[pt_BR]=Estados do modificador de teclado e botões do mouse +Comment[ro]=Stările modificatorului de tastatură și a butoanelor mausului +Comment[ru]=Состояния клавиш-модификаторов на клавиатуре и кнопок мыши +Comment[si]=යතුරුපුවරු වෙනස්කිරීම් හා මවුස බොත්තම් තත්ව +Comment[sk]=Stavy modifikátorov klávesnice a tlačidiel myši +Comment[sl]=Stanje spremenilnih tipk tipkovnice in tipk miške +Comment[sr]=Стања модификатора на тастатури и дугмади миша +Comment[sr@ijekavian]=Стања модификатора на тастатури и дугмади миша +Comment[sr@ijekavianlatin]=Stanja modifikatora na tastaturi i dugmadi miša +Comment[sr@latin]=Stanja modifikatora na tastaturi i dugmadi miša +Comment[sv]=Tillstånd för väljartangenter och musknappar +Comment[th]=สถานะปุ่มเปลี่ยนหน้าที่ของแป้นพิมพ์และสถานะปุ่มของเมาส์ +Comment[tr]=Farenin ve klavyenin değiştirici tuşlarının durumları +Comment[ug]=ھەرپتاختا ئۆزگىرىشى ۋە چاشقىنەك توپچا ھالىتى +Comment[uk]=Стан модифікаторів клавіатури і кнопок миші +Comment[wa]=Candjaedje el taprece eyet estat des botons del sori +Comment[x-test]=xxKeyboard modifier and mouse buttons statesxx +Comment[zh_CN]=显示键盘修饰健及鼠标按键状态 +Comment[zh_TW]=鍵盤變更鍵與滑鼠按鍵狀態 +Type=Service +Icon=input-keyboard + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_keystate + +X-KDE-PluginInfo-Author=Aaron Seigo +X-KDE-PluginInfo-Email=aseigo@kde.org +X-KDE-PluginInfo-Name=keystate +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Accessibility +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/metadata/CMakeLists.txt b/plasma/generic/dataengines/metadata/CMakeLists.txt new file mode 100644 index 00000000..38f33238 --- /dev/null +++ b/plasma/generic/dataengines/metadata/CMakeLists.txt @@ -0,0 +1,20 @@ +project(metadata) + +set(metadata_engine_SRCS metadata_engine.cpp) + +kde4_add_plugin(plasma_engine_metadata ${metadata_engine_SRCS}) + +include_directories(${SOPRANO_INCLUDE_DIR} ${NEPOMUK_CORE_INCLUDE_DIR}) + +target_link_libraries(plasma_engine_metadata + ${KDE4_KIO_LIBS} + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + ${NEPOMUK_CORE_LIBRARY} + ${SOPRANO_LIBRARIES} ) + +install(TARGETS plasma_engine_metadata + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-engine-metadata.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/dataengines/metadata/Messages.sh b/plasma/generic/dataengines/metadata/Messages.sh new file mode 100644 index 00000000..ff842825 --- /dev/null +++ b/plasma/generic/dataengines/metadata/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_metadata.pot diff --git a/plasma/generic/dataengines/metadata/metadata_engine.cpp b/plasma/generic/dataengines/metadata/metadata_engine.cpp new file mode 100644 index 00000000..2fc341c1 --- /dev/null +++ b/plasma/generic/dataengines/metadata/metadata_engine.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2009 Anne-Marie Mahfouf + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "metadata_engine.h" + +#include +#include + +#include + +// Nepomuk +#include +#include +#include + +MetaDataEngine::MetaDataEngine(QObject* parent, const QVariantList& args) : + Plasma::DataEngine(parent, args) +{ +} + +MetaDataEngine::~MetaDataEngine() +{ +} + +void MetaDataEngine::init() +{ + Nepomuk2::ResourceManager::instance()->init(); +} + +bool MetaDataEngine::sourceRequestEvent(const QString &name) +{ + updateSourceEvent(name); + return true; +} + +bool MetaDataEngine::updateSourceEvent(const QString &name) +{ + // Get picture general properties through KFileMetaInfo + const KFileMetaInfo::WhatFlags flags = KFileMetaInfo::Fastest | + KFileMetaInfo::TechnicalInfo | + KFileMetaInfo::ContentInfo; + const KFileMetaInfo fileMetaInfo(name, QString(), flags); + if (fileMetaInfo.isValid()) { + const QHash& items = fileMetaInfo.items(); + QHash::const_iterator it = items.constBegin(); + const QHash::const_iterator end = items.constEnd(); + QString labelText; + while (it != end) { + const KFileMetaInfoItem& metaInfoItem = it.value(); + const QVariant& value = metaInfoItem.value(); + + if (value.isValid() && convertMetaInfo(metaInfoItem.name(), labelText)) { + if (labelText == i18nc("@label", "Size")) { + const QString s = QString::number(value.toDouble()/1024/1024, 'f', 2); + setData(name, labelText, QString::fromLatin1("%1 Mb").arg(s)); + } else if (labelText == i18nc("@label", "Source Modified")) { + QVariant newValue = QVariant(value.toDateTime()); + setData(name, labelText, newValue.toString()); + } else { + setData(name, labelText, value.toString()); + } + } + + ++it; + } + } + + // Get picture tags through Nepomuk + QUrl uri = QUrl(name); + QStringList tags; + Nepomuk2::Resource res( uri); + QList picTags = res.tags(); + Q_FOREACH(const Nepomuk2::Tag& tag, picTags) { + tags.append(tag.label() + ", "); + } + + setData(name, "tags", tags); + // Get picture comment through Nepomuk + setData(name, "comment", res.description()); + // Get picture rating through Nepomuk + setData(name, "rating", QString::number(res.rating())); + + return true; +} + +bool MetaDataEngine::convertMetaInfo(const QString& key, QString& text) const +{ + struct MetaKey { + const char* key; + QString text; + }; + + // keys list, more can be added + static const MetaKey keys[] = { + { "http://freedesktop.org/standards/xesam/1.0/core#cameraModel", i18nc("@label", "Model") }, + { "http://freedesktop.org/standards/xesam/1.0/core#focalLength", i18nc("@label", "Focal Length") }, + { "http://freedesktop.org/standards/xesam/1.0/core#mimeType", i18nc("@label", "Mime Type") }, + { "http://freedesktop.org/standards/xesam/1.0/core#cameraManufacturer", i18nc("@label", "Manufacturer") }, + { "http://freedesktop.org/standards/xesam/1.0/core#sourceModified", i18nc("@label", "Source Modified") }, + { "http://freedesktop.org/standards/xesam/1.0/core#orientation", i18nc("@label", "Orientation") }, + { "http://freedesktop.org/standards/xesam/1.0/core#flashUsed", i18nc("@label", "Flash Used") }, + { "http://freedesktop.org/standards/xesam/1.0/core#height", i18nc("@label", "Height") }, + { "http://freedesktop.org/standards/xesam/1.0/core#width", i18nc("@label", "Width") }, + { "http://freedesktop.org/standards/xesam/1.0/core#url", i18nc("@label", "Url") }, + { "http://freedesktop.org/standards/xesam/1.0/core#size", i18nc("@label", "Size") }, + { "http://freedesktop.org/standards/xesam/1.0/core#aperture", i18nc("@label", "Aperture") }, + { "http://freedesktop.org/standards/xesam/1.0/core#meteringMode", i18nc("@label", "Metering Mode") }, + { "http://freedesktop.org/standards/xesam/1.0/core#35mmEquivalent", i18nc("@label", "35mm Equivalent") }, + { "http://freedesktop.org/standards/xesam/1.0/core#fileExtension", i18nc("@label", "File Extension") }, + { "http://freedesktop.org/standards/xesam/1.0/core#name", i18nc("@label", "Name") }, + { "http://freedesktop.org/standards/xesam/1.0/core#exposureTime", i18nc("@label", "Exposure Time") } + }; + + // search if the key exists and get its value + int top = 0; + int bottom = sizeof(keys) / sizeof(MetaKey) - 1; + while (top <= bottom) { + const int result = key.compare(keys[top].key); + if (result == 0) { + text = keys[top].text; + return true; + } + top++; + } + + return false; +} + +K_EXPORT_PLASMA_DATAENGINE(metadata, MetaDataEngine) + +#include "metadata_engine.moc" diff --git a/plasma/generic/dataengines/metadata/metadata_engine.h b/plasma/generic/dataengines/metadata/metadata_engine.h new file mode 100644 index 00000000..f7f1d394 --- /dev/null +++ b/plasma/generic/dataengines/metadata/metadata_engine.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Anne-Marie Mahfouf + * + * 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef METADATA_ENGINE_H_ +#define METADATA_ENGINE_H_ + +#include + + +class MetaDataEngine: public Plasma::DataEngine +{ + Q_OBJECT + +public: + MetaDataEngine(QObject* parent, const QVariantList& args); + ~MetaDataEngine(); + +protected: + void init(); + bool sourceRequestEvent(const QString& name); + +protected slots: + bool updateSourceEvent(const QString& source); + +private: + /** + * Converts the meta key \a key to a readable format into \a text. + * Returns true, if the string \a key represents a meta information + * that should be shown. If false is returned, \a text is not modified. + */ + bool convertMetaInfo(const QString& key, QString& text) const; + +}; + +#endif /* METADATA_ENGINE_H_ */ diff --git a/plasma/generic/dataengines/metadata/plasma-engine-metadata.desktop b/plasma/generic/dataengines/metadata/plasma-engine-metadata.desktop new file mode 100644 index 00000000..625bdbe1 --- /dev/null +++ b/plasma/generic/dataengines/metadata/plasma-engine-metadata.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Name=Meta Data +Name[ar]=البيانات الوصفية +Name[ast]=Metadatos +Name[bg]=Мета данни +Name[bs]=metapodaci +Name[ca]=Metadades +Name[ca@valencia]=Metadades +Name[cs]=Metadata +Name[csb]=Pòdôwczi meta +Name[da]=Metadata +Name[de]=Metadaten +Name[el]=Μεταδεδομένα +Name[en_GB]=Meta Data +Name[eo]=Metaj Datumoj +Name[es]=Metadatos +Name[et]=Metaandmed +Name[eu]=Metadatuak +Name[fi]=Metatieto +Name[fr]=Méta données +Name[fy]=Meta gegevens +Name[ga]=Meiteashonraí +Name[gl]=Metadatos +Name[gu]=મેટા માહિતી +Name[he]=מידע על פריט המידע (Meta Data) +Name[hi]=मेटा डॉटा +Name[hr]=Metapodaci +Name[hu]=Metaadatok +Name[ia]=Meta datos +Name[id]=Meta Data +Name[is]=Metagögn +Name[ja]=メタデータ +Name[ka]=მეტამონაცემები +Name[kk]=Метадеректер +Name[km]=ទិន្នន័យ​មេតា +Name[kn]=ಮೆಟಾ ಡೇಟಾ +Name[ko]=메타 데이터 +Name[lt]=Meda duomenys +Name[lv]=Metadati +Name[mai]=मेटा डाटा +Name[mk]=Мета-податоци +Name[ml]=മെറ്റാ ഡാറ്റാ +Name[mr]=मेटा डेटा +Name[nb]=Metadata +Name[nds]=Metadaten +Name[nl]=Metadata +Name[nn]=Metadata +Name[pa]=ਮੇਟਾ ਡਾਟਾ +Name[pl]=Metadane +Name[pt]=Meta-Dados +Name[pt_BR]=Metadados +Name[ro]=Metadate +Name[ru]=Метаданные +Name[si]=මෙටා දත්ත +Name[sk]=Metadáta +Name[sl]=Metapodatki +Name[sr]=метаподаци +Name[sr@ijekavian]=метаподаци +Name[sr@ijekavianlatin]=metapodaci +Name[sr@latin]=metapodaci +Name[sv]=Metadata +Name[tg]=Маълумоти Meta +Name[th]=ข้อมูลกำกับ +Name[tr]=Meta Data +Name[ug]=مېتا سانلىق-مەلۇمات +Name[uk]=Метадані +Name[wa]=Meta-dnêyes +Name[x-test]=xxMeta Dataxx +Name[zh_CN]=元数据 +Name[zh_TW]=中繼資料 +Type=Service +Icon=nepomuk +X-KDE-ServiceTypes=Plasma/DataEngine + +X-Plasma-EngineName=metadata +X-KDE-Library=plasma_engine_metadata +X-KDE-PluginInfo-Author=Anne-Marie Mahfouf +X-KDE-PluginInfo-Email=annma@kde.org +X-KDE-PluginInfo-Name=metadata +X-KDE-PluginInfo-Version=0.0.1 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Utilities +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/mouse/CMakeLists.txt b/plasma/generic/dataengines/mouse/CMakeLists.txt new file mode 100644 index 00000000..86d7accb --- /dev/null +++ b/plasma/generic/dataengines/mouse/CMakeLists.txt @@ -0,0 +1,19 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/../../) + +set(mouse_engine_SRCS + mouseengine.cpp +) + +if (X11_Xfixes_FOUND) + set(mouse_engine_SRCS ${mouse_engine_SRCS} cursornotificationhandler.cpp) +endif (X11_Xfixes_FOUND) + +kde4_add_plugin(plasma_engine_mouse ${mouse_engine_SRCS}) +target_link_libraries(plasma_engine_mouse ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${X11_LIBRARIES}) +if (X11_Xfixes_FOUND) + target_link_libraries(plasma_engine_mouse ${X11_Xfixes_LIB}) +endif (X11_Xfixes_FOUND) + +install(TARGETS plasma_engine_mouse DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-mouse.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/mouse/cursornotificationhandler.cpp b/plasma/generic/dataengines/mouse/cursornotificationhandler.cpp new file mode 100644 index 00000000..3cb9add2 --- /dev/null +++ b/plasma/generic/dataengines/mouse/cursornotificationhandler.cpp @@ -0,0 +1,114 @@ +/* + * Copyright © 2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "cursornotificationhandler.h" + +#include + +#include +#include + + +/* + * This class is a QWidget because we need an X window to + * be able to receive XFixes events. We don't actually map + * the widget. + */ + +CursorNotificationHandler::CursorNotificationHandler() + : QWidget(), currentName(0) +{ + Display *dpy = QX11Info::display(); + int errorBase; + haveXfixes = false; + + // Request cursor change notification events + if (XFixesQueryExtension(dpy, &fixesEventBase, &errorBase)) + { + int major, minor; + XFixesQueryVersion(dpy, &major, &minor); + + if (major >= 2) + { + XFixesSelectCursorInput(dpy, winId(), XFixesDisplayCursorNotifyMask); + haveXfixes = true; + } + } +} + + +CursorNotificationHandler::~CursorNotificationHandler() +{ +} + + +QString CursorNotificationHandler::cursorName() +{ + if (!haveXfixes) + return QString(); + + if (!currentName) + { + // Xfixes doesn't have a request for getting the current cursor name, + // but it's included in the XFixesCursorImage struct. + XFixesCursorImage *image = XFixesGetCursorImage(QX11Info::display()); + currentName = image->atom; + XFree(image); + } + + return cursorName(currentName); +} + + +QString CursorNotificationHandler::cursorName(Atom cursor) +{ + QString name; + + // XGetAtomName() is a synchronous call, so we cache the name + // in an atom<->string map the first time we see a name + // to keep the X server round trips down. + if (names.contains(cursor)) + name = names[cursor]; + else + { + char *data = XGetAtomName(QX11Info::display(), cursor); + name = QString::fromUtf8(data); + XFree(data); + + names.insert(cursor, name); + } + + return name; +} + + +bool CursorNotificationHandler::x11Event(XEvent* event) +{ + if (event->type != fixesEventBase + XFixesCursorNotify) + return false; + + XFixesCursorNotifyEvent *xfe = reinterpret_cast(event); + currentName = xfe->cursor_name; + + emit cursorNameChanged(cursorName(currentName)); + + return false; +} + +#include "cursornotificationhandler.moc" + diff --git a/plasma/generic/dataengines/mouse/cursornotificationhandler.h b/plasma/generic/dataengines/mouse/cursornotificationhandler.h new file mode 100644 index 00000000..7b4d3eb7 --- /dev/null +++ b/plasma/generic/dataengines/mouse/cursornotificationhandler.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef CURSORNOTIFICATIONHANDLER_H +#define CURSORNOTIFICATIONHANDLER_H + +#include +#include + +#include + +class CursorNotificationHandler : public QWidget +{ + Q_OBJECT + +public: + CursorNotificationHandler(); + ~CursorNotificationHandler(); + + QString cursorName(); + +signals: + void cursorNameChanged(const QString &name); + +protected: + bool x11Event(XEvent *); + +private: + QString cursorName(Atom cursor); + +private: + bool haveXfixes; + int fixesEventBase; + Atom currentName; + QMap names; +}; + +#endif diff --git a/plasma/generic/dataengines/mouse/mouseengine.cpp b/plasma/generic/dataengines/mouse/mouseengine.cpp new file mode 100644 index 00000000..19a7fb74 --- /dev/null +++ b/plasma/generic/dataengines/mouse/mouseengine.cpp @@ -0,0 +1,103 @@ +/* + * Copyright © 2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mouseengine.h" + +#include + +#ifdef HAVE_XFIXES +# include "cursornotificationhandler.h" +#endif + + +MouseEngine::MouseEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), timerId(0) +#ifdef HAVE_XFIXES +, handler(0) +#endif +{ + Q_UNUSED(args) +} + + +MouseEngine::~MouseEngine() +{ + if (timerId) + killTimer(timerId); +#ifdef HAVE_XFIXES + delete handler; +#endif +} + + +QStringList MouseEngine::sources() const +{ + QStringList list; + + list << QLatin1String("Position"); +#ifdef HAVE_XFIXES + list << QLatin1String("Name"); +#endif + + return list; +} + + +void MouseEngine::init() +{ + if (!timerId) + timerId = startTimer(40); + + // Init cursor position + QPoint pos = QCursor::pos(); + setData(QLatin1String("Position"), QVariant(pos)); + lastPosition = pos; + +#ifdef HAVE_XFIXES + handler = new CursorNotificationHandler; + connect(handler, SIGNAL(cursorNameChanged(QString)), SLOT(updateCursorName(QString))); + + setData(QLatin1String("Name"), QVariant(handler->cursorName())); +#endif + + scheduleSourcesUpdated(); +} + + +void MouseEngine::timerEvent(QTimerEvent *) +{ + QPoint pos = QCursor::pos(); + + if (pos != lastPosition) + { + setData(QLatin1String("Position"), QVariant(pos)); + lastPosition = pos; + + scheduleSourcesUpdated(); + } +} + + +void MouseEngine::updateCursorName(const QString &name) +{ + setData(QLatin1String("Name"), QVariant(name)); + scheduleSourcesUpdated(); +} + +#include "mouseengine.moc" + diff --git a/plasma/generic/dataengines/mouse/mouseengine.h b/plasma/generic/dataengines/mouse/mouseengine.h new file mode 100644 index 00000000..095abe24 --- /dev/null +++ b/plasma/generic/dataengines/mouse/mouseengine.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2007 Fredrik Höglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MOUSEENGINE_H +#define MOUSEENGINE_H + +#include +#include + +#ifdef HAVE_XFIXES +class CursorNotificationHandler; +#endif + +class MouseEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + MouseEngine(QObject* parent, const QVariantList& args); + ~MouseEngine(); + + QStringList sources() const; + +protected: + void init(); + void timerEvent(QTimerEvent*); + +private slots: + void updateCursorName(const QString &name); + +private: + QPoint lastPosition; + int timerId; +#ifdef HAVE_XFIXES + CursorNotificationHandler *handler; +#endif +}; + +K_EXPORT_PLASMA_DATAENGINE(mouse, MouseEngine) + +#endif diff --git a/plasma/generic/dataengines/mouse/plasma-dataengine-mouse.desktop b/plasma/generic/dataengines/mouse/plasma-dataengine-mouse.desktop new file mode 100644 index 00000000..1ecafc68 --- /dev/null +++ b/plasma/generic/dataengines/mouse/plasma-dataengine-mouse.desktop @@ -0,0 +1,153 @@ +[Desktop Entry] +Name=Pointer Position +Name[ar]=موقع المؤشر +Name[ast]=Posición del punteru +Name[be@latin]=Miesca kursora +Name[bg]=Разположение на курсора +Name[bs]=položaj pokazivača +Name[ca]=Posició de l'apuntador +Name[ca@valencia]=Posició de l'apuntador +Name[cs]=Pozice ukazatele +Name[da]=Markørposition +Name[de]=Mausposition +Name[el]=Θέση δρομέα +Name[en_GB]=Pointer Position +Name[eo]=Pozicio de la Montrilo +Name[es]=Posición del puntero +Name[et]=Kursori asukoht +Name[eu]=Erakuslearen kokalekua +Name[fi]=Osoittimen sijainti +Name[fr]=Position du pointeur +Name[fy]=Mûsoanwizer posysje +Name[ga]=Ionad na Luiche +Name[gl]=Posición do rato +Name[gu]=દર્શક સ્થિતિ +Name[he]=מיקום סמן +Name[hi]=संकेतक स्थान +Name[hne]=पाइन्टर स्थिति +Name[hr]=Pozicija pokazivača miša +Name[hu]=Egérpozíció +Name[ia]=Position de punctator +Name[id]=Posisi Penunjuk +Name[is]=Staðsetning bendils +Name[it]=Posizione del puntatore +Name[ja]=マウスポインタの位置 +Name[kk]=Көрсеткіш орны +Name[km]=ទីតាំង​ទស្សន៍​ទ្រនិច +Name[kn]=ಸೂಚಿಯ ಸ್ಥಳ +Name[ko]=포인터 위치 +Name[lt]=Rodyklės pozicija +Name[lv]=Peles pozīcija +Name[mk]=Позиција на покажувач +Name[ml]=സൂചികയുടെ സ്ഥാനം +Name[mr]=पॉइन्टर स्थान +Name[nb]=Pekerposisjon +Name[nds]=Muuswieser-Steed +Name[nl]=Muisaanwijzerpositie +Name[nn]=Peikarplassering +Name[or]=ସୂଚକ ସ୍ଥାନ +Name[pa]=ਪੁਆਇੰਟਰ ਸਥਿਤੀ +Name[pl]=Pozycja kursora +Name[pt]=Posição do Cursor +Name[pt_BR]=Posição do ponteiro +Name[ro]=Poziție indicator +Name[ru]=Положение указателя мыши +Name[si]=ලක්‍ෂක ස්ථානය +Name[sk]=Pozícia kurzora +Name[sl]=Položaj kazalca +Name[sr]=положај показивача +Name[sr@ijekavian]=положај показивача +Name[sr@ijekavianlatin]=položaj pokazivača +Name[sr@latin]=položaj pokazivača +Name[sv]=Pekarposition +Name[ta]=Pointer Position +Name[te]=సూచకి స్థానము +Name[tg]=Положение указателя мыши +Name[th]=ตำแหน่งของตัวชี้ +Name[tr]=İşaretçi Konumu +Name[ug]=نۇربەلگە ئورنى +Name[uk]=Позиція вказівника +Name[wa]=Eplaeçmint do pwinteu +Name[x-test]=xxPointer Positionxx +Name[zh_CN]=指针位置 +Name[zh_TW]=指標位置 +Comment=Mouse position and cursor +Comment[ar]=موقع الفأرة و المؤشر +Comment[ast]=Posición del mur y cursor +Comment[bg]=Позиция на мишката и курсора +Comment[bs]=Položaj miša i pokazivača +Comment[ca]=Posició del ratolí i del cursor +Comment[ca@valencia]=Posició del ratolí i del cursor +Comment[cs]=Pozice myši a kurzoru +Comment[da]=Museposition og markør +Comment[de]=Mausposition und Mauszeiger +Comment[el]=Θέση ποντικιού και δρομέα +Comment[en_GB]=Mouse position and cursor +Comment[eo]=Pozicio de la muso kaj kursoro +Comment[es]=Posición del ratón y cursor +Comment[et]=Hiire asukoht ja kursor +Comment[eu]=Saguaren kokalekua eta kurtsorea +Comment[fi]=Hiiren sijainti ja kohdistin +Comment[fr]=Position et curseur de la souris +Comment[fy]=Mûsposysje en rinnerke +Comment[ga]=Suíomh na luiche agus an cúrsóir +Comment[gl]=Posición do rato e do cursor +Comment[gu]=માઉસ સ્થિતિ અને કર્સર +Comment[he]=מיקום עכבר וסמן +Comment[hr]=Pozicija miša i pokazivača miša +Comment[hu]=Egérmutató-pozíció +Comment[ia]=Position e cursor del mus +Comment[id]=Posisi tetikus dan kursor +Comment[is]=Staðsetning músar og bendils +Comment[it]=Posizione e cursore del mouse +Comment[ja]=マウスの位置とカーソル +Comment[kk]=Тышқанның орны және меңзері +Comment[km]=ទីតាំង និង​ទស្សន៍ទ្រនិច្ច​កណ្ដុរ +Comment[kn]=ಮೌಸ್‌ನ ಸ್ಥಾನ ಹಾಗು ತೆರೆಸೂಚಕ +Comment[ko]=마우스 위치와 커서 +Comment[lt]=Pelės pozicija ir kursorius +Comment[lv]=Peles pozīcija un kursors +Comment[mai]=माउसक स्थिति आओर कर्सर +Comment[mk]=Позиција и покажувач на глушецот +Comment[ml]=മൌസിന്റെ സ്ഥാനവും ചൂണ്ടിയും +Comment[mr]=माऊस स्थान व कर्सर +Comment[nb]=Museposisjon og markør +Comment[nds]=Muussteed un Blinker +Comment[nl]=Muispositie en cursor +Comment[nn]=Plassering av musa og peikaren +Comment[pa]=ਮਾਊਸ ਸਥਿਤੀ ਅਤੇ ਕਰਸਰ +Comment[pl]=Pozycja myszy i kursora +Comment[pt]=Posição e cursor do rato +Comment[pt_BR]=Posição do mouse e cursor +Comment[ro]=Poziția și cursorul mausului +Comment[ru]=Положение мыши и вид указателя +Comment[si]=මවුස ස්ථානය හා කර්සරය +Comment[sk]=Pozícia myši a kurzora +Comment[sl]=Položaj miškine kazalke +Comment[sr]=Положај миша и показивач +Comment[sr@ijekavian]=Положај миша и показивач +Comment[sr@ijekavianlatin]=Položaj miša i pokazivač +Comment[sr@latin]=Položaj miša i pokazivač +Comment[sv]=Musposition och pekare +Comment[tg]=Ҷойгиршавии муш ва курсор +Comment[th]=ตำแหน่งตัวชี้และเคอร์เซอร์ของเมาส์ +Comment[tr]=Fare konumu ve işaretçisi +Comment[ug]=چاشقىنەك ئورنى ۋە نۇربەلگە +Comment[uk]=Позиція вказівника миші і курсора +Comment[wa]=1Eplaeçmint del sori et do cursoe +Comment[x-test]=xxMouse position and cursorxx +Comment[zh_CN]=鼠标位置和光标 +Comment[zh_TW]=滑鼠位置與游標 +Type=Service +X-KDE-ServiceTypes=Plasma/DataEngine +Icon=input-mouse +X-KDE-Library=plasma_engine_mouse + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=mouse +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/mpris2/CMakeLists.txt b/plasma/generic/dataengines/mpris2/CMakeLists.txt new file mode 100644 index 00000000..310ce7dd --- /dev/null +++ b/plasma/generic/dataengines/mpris2/CMakeLists.txt @@ -0,0 +1,32 @@ +project(plasma-dataengine-mpris2) + +add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS) + +set(mpris2_engine_SRCS + mpris2engine.cpp + multiplexer.cpp + multiplexedservice.cpp + playercontrol.cpp + playeractionjob.cpp + playercontainer.cpp +) + +set_source_files_properties( + org.freedesktop.DBus.Properties.xml + org.mpris.MediaPlayer2.Player.xml + org.mpris.MediaPlayer2.xml + PROPERTIES + NO_NAMESPACE ON) +qt4_add_dbus_interface(mpris2_engine_SRCS org.freedesktop.DBus.Properties.xml dbusproperties) +qt4_add_dbus_interface(mpris2_engine_SRCS org.mpris.MediaPlayer2.Player.xml mprisplayer) +qt4_add_dbus_interface(mpris2_engine_SRCS org.mpris.MediaPlayer2.xml mprisroot) + +kde4_add_plugin(plasma_engine_mpris2 ${mpris2_engine_SRCS}) +target_link_libraries(plasma_engine_mpris2 + ${KDE4_PLASMA_LIBS} +) + +install(TARGETS plasma_engine_mpris2 DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-mpris2.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES mpris2.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/mpris2/Messages.sh b/plasma/generic/dataengines/mpris2/Messages.sh new file mode 100755 index 00000000..0e393ff3 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_mpris2.pot diff --git a/plasma/generic/dataengines/mpris2/TODO b/plasma/generic/dataengines/mpris2/TODO new file mode 100644 index 00000000..18057320 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/TODO @@ -0,0 +1,2 @@ +* add tracklist support (secondary source? eg: amarok:tracklist) +* add playlists support (secondary source? eg: amarok:playlists) diff --git a/plasma/generic/dataengines/mpris2/mpris2.operations b/plasma/generic/dataengines/mpris2/mpris2.operations new file mode 100644 index 00000000..5a49f0c3 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/mpris2.operations @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/mpris2/mpris2engine.cpp b/plasma/generic/dataengines/mpris2/mpris2engine.cpp new file mode 100644 index 00000000..16225a8a --- /dev/null +++ b/plasma/generic/dataengines/mpris2/mpris2engine.cpp @@ -0,0 +1,201 @@ +/* + * Copyright 2007-2012 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mpris2engine.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "playercontrol.h" +#include "playercontainer.h" +#include "multiplexer.h" +#include "multiplexedservice.h" + +Mpris2Engine::Mpris2Engine(QObject* parent, + const QVariantList& args) + : Plasma::DataEngine(parent) +{ + Q_UNUSED(args) + + setName("mpris2"); + + QDBusServiceWatcher *serviceWatcher = new QDBusServiceWatcher( + QString(), QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForOwnerChange, this); + connect(serviceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), + this, SLOT(serviceOwnerChanged(QString,QString,QString))); + + QDBusPendingCall async = QDBusConnection::sessionBus().interface()->asyncCall("ListNames"); + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(async, this); + connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(serviceNameFetchFinished(QDBusPendingCallWatcher*))); +} + +Plasma::Service* Mpris2Engine::serviceForSource(const QString& source) +{ + if (source == Multiplexer::sourceName) { + if (!m_multiplexer) { + createMultiplexer(); + } + return new MultiplexedService(m_multiplexer.data(), this); + } else { + PlayerContainer* container = qobject_cast(containerForSource(source)); + if (container) { + return new PlayerControl(container, this); + } else { + return DataEngine::serviceForSource(source); + } + } +} + +QStringList Mpris2Engine::sources() const +{ + if (m_multiplexer) + return DataEngine::sources(); + else + return DataEngine::sources() << Multiplexer::sourceName; +} + +void Mpris2Engine::serviceOwnerChanged( + const QString& serviceName, + const QString& oldOwner, + const QString& newOwner) +{ + if (!serviceName.startsWith(QLatin1String("org.mpris.MediaPlayer2."))) + return; + + QString sourceName = serviceName.mid(23); + + if (!oldOwner.isEmpty()) { + kDebug() << "MPRIS service" << serviceName << "just went offline"; + if (m_multiplexer) { + m_multiplexer.data()->removePlayer(sourceName); + } + removeSource(sourceName); + } + + if (!newOwner.isEmpty()) { + kDebug() << "MPRIS service" << serviceName << "just came online"; + addMediaPlayer(serviceName, sourceName); + } +} + +bool Mpris2Engine::updateSourceEvent(const QString& source) +{ + if (source == Multiplexer::sourceName) { + return false; + } else { + PlayerContainer *container = qobject_cast(containerForSource(source)); + if (container) { + container->refresh(); + return true; + } else { + return false; + } + } +} + +bool Mpris2Engine::sourceRequestEvent(const QString& source) +{ + if (source == Multiplexer::sourceName) { + createMultiplexer(); + return true; + } + return false; +} + +void Mpris2Engine::initialFetchFinished(PlayerContainer* container) +{ + kDebug() << "Props fetch for" << container->objectName() << "finished; adding"; + addSource(container); + if (m_multiplexer) { + m_multiplexer.data()->addPlayer(container); + } + // don't let future refreshes trigger this + disconnect(container, SIGNAL(initialFetchFinished(PlayerContainer*)), + this, SLOT(initialFetchFinished(PlayerContainer*))); + disconnect(container, SIGNAL(initialFetchFailed(PlayerContainer*)), + this, SLOT(initialFetchFailed(PlayerContainer*))); +} + +void Mpris2Engine::initialFetchFailed(PlayerContainer* container) +{ + kWarning() << "Failed to find working MPRIS2 interface for" << container->dbusAddress(); + container->deleteLater(); +} + +void Mpris2Engine::serviceNameFetchFinished(QDBusPendingCallWatcher* watcher) +{ + QDBusPendingReply propsReply = *watcher; + watcher->deleteLater(); + + if (propsReply.isError()) { + kWarning() << "Could not get list of available D-Bus services"; + } else { + foreach (const QString& serviceName, propsReply.value()) { + if (serviceName.startsWith("org.mpris.MediaPlayer2.")) { + kDebug() << "Found MPRIS2 service" << serviceName; + // watch out for race conditions; the media player could + // have appeared between starting the service watcher and + // this call being dealt with + // NB: _disappearing_ between sending this call and doing + // this processing is fine + QString sourceName = serviceName.mid(23); + PlayerContainer *container = qobject_cast(containerForSource(sourceName)); + if (!container) { + kDebug() << "Haven't already seen" << serviceName; + addMediaPlayer(serviceName, sourceName); + } + } + } + } +} + +void Mpris2Engine::addMediaPlayer(const QString& serviceName, const QString& sourceName) +{ + PlayerContainer *container = new PlayerContainer(serviceName, this); + container->setObjectName(sourceName); + connect(container, SIGNAL(initialFetchFinished(PlayerContainer*)), + this, SLOT(initialFetchFinished(PlayerContainer*))); + connect(container, SIGNAL(initialFetchFailed(PlayerContainer*)), + this, SLOT(initialFetchFailed(PlayerContainer*))); +} + +void Mpris2Engine::createMultiplexer() +{ + Q_ASSERT (!m_multiplexer); + m_multiplexer = new Multiplexer(this); + + SourceDict dict = containerDict(); + SourceDict::const_iterator i = dict.constBegin(); + while (i != dict.constEnd()) { + PlayerContainer *container = qobject_cast(i.value()); + m_multiplexer.data()->addPlayer(container); + ++i; + } + addSource(m_multiplexer.data()); +} + +#include "mpris2engine.moc" diff --git a/plasma/generic/dataengines/mpris2/mpris2engine.h b/plasma/generic/dataengines/mpris2/mpris2engine.h new file mode 100644 index 00000000..4d314f76 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/mpris2engine.h @@ -0,0 +1,65 @@ +/* + * Copyright 2007-2012 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MPRIS2ENGINE_H +#define MPRIS2ENGINE_H + +#include + +#include + +class QDBusPendingCallWatcher; +class PlayerContainer; +class Multiplexer; + +/** + * The MPRIS2 data engine. + */ +class Mpris2Engine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + Mpris2Engine(QObject* parent, const QVariantList& args); + + Plasma::Service* serviceForSource(const QString& source); + virtual QStringList sources() const; + +protected: + virtual bool sourceRequestEvent(const QString& source); + virtual bool updateSourceEvent(const QString& source); + +private slots: + void serviceOwnerChanged( + const QString& serviceName, + const QString& oldOwner, + const QString& newOwner); + void initialFetchFinished(PlayerContainer* container); + void initialFetchFailed(PlayerContainer* container); + void serviceNameFetchFinished(QDBusPendingCallWatcher* watcher); + +private: + void addMediaPlayer(const QString& serviceName, const QString& sourceName); + void createMultiplexer(); + + QWeakPointer m_multiplexer; +}; + +K_EXPORT_PLASMA_DATAENGINE(mpris2, Mpris2Engine) + +#endif // MPRIS2ENGINE_H diff --git a/plasma/generic/dataengines/mpris2/multiplexedservice.cpp b/plasma/generic/dataengines/mpris2/multiplexedservice.cpp new file mode 100644 index 00000000..a3b450d7 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/multiplexedservice.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "multiplexedservice.h" + +#include "multiplexer.h" +#include "playercontrol.h" + +MultiplexedService::MultiplexedService(Multiplexer *multiplexer, QObject *parent) + : Plasma::Service(parent) +{ + setObjectName(Multiplexer::sourceName + QLatin1String(" controller")); + setName("mpris2"); + setDestination(Multiplexer::sourceName); + + connect(multiplexer, SIGNAL(activePlayerChanged(PlayerContainer*)), + this, SLOT(activePlayerChanged(PlayerContainer*))); + + activePlayerChanged(multiplexer->activePlayer()); +} + +Plasma::ServiceJob* MultiplexedService::createJob(const QString& operation, + QMap& parameters) +{ + if (m_control) { + return m_control.data()->createJob(operation, parameters); + } + return 0; +} + +void MultiplexedService::updateEnabledOperations() +{ + if (m_control) { + foreach (const QString &op, operationNames()) { + setOperationEnabled(op, m_control.data()->isOperationEnabled(op)); + } + } else { + foreach (const QString &op, operationNames()) { + setOperationEnabled(op, false); + } + } +} + +void MultiplexedService::activePlayerChanged(PlayerContainer *container) +{ + delete m_control.data(); + + if (container) { + m_control = new PlayerControl(container, container->getDataEngine()); + connect(m_control.data(), SIGNAL(enabledOperationsChanged()), + this, SLOT(updateEnabledOperations())); + } + + updateEnabledOperations(); +} + diff --git a/plasma/generic/dataengines/mpris2/multiplexedservice.h b/plasma/generic/dataengines/mpris2/multiplexedservice.h new file mode 100644 index 00000000..c2c47400 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/multiplexedservice.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#ifndef MULTIPLEXEDSERVICE_H +#define MULTIPLEXEDSERVICE_H + +#include + +#include "playercontrol.h" +#include + +class Multiplexer; +class PlayerControl; + +class MultiplexedService : public Plasma::Service +{ + Q_OBJECT + +public: + MultiplexedService(Multiplexer *multiplexer, QObject *parent = 0); + +protected: + Plasma::ServiceJob *createJob(const QString &operation, + QMap ¶meters); + +private slots: + void updateEnabledOperations(); + void activePlayerChanged(PlayerContainer *container); + +private: + QWeakPointer m_control; +}; + +#endif // MULTIPLEXEDSERVICE_H diff --git a/plasma/generic/dataengines/mpris2/multiplexer.cpp b/plasma/generic/dataengines/mpris2/multiplexer.cpp new file mode 100644 index 00000000..d9e69897 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/multiplexer.cpp @@ -0,0 +1,198 @@ +/* + * Copyright 2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "multiplexer.h" + +#include + +// the '@' at the start is not valid for D-Bus names, so it will +// never interfere with an actual MPRIS2 player +const QLatin1String Multiplexer::sourceName = QLatin1String("@multiplex"); + +Multiplexer::Multiplexer(QObject* parent) + : DataContainer(parent) +{ + setObjectName(sourceName); +} + +void Multiplexer::addPlayer(PlayerContainer *container) +{ + bool makeActive = m_activeName.isEmpty(); + + if (container->data().value("PlaybackStatus") == QLatin1String("Playing")) { + m_playing.insert(container->objectName(), container); + if (!makeActive && + data().value("PlaybackStatus") != QLatin1String("Playing")) { + makeActive = true; + } + } else if (container->data().value("PlaybackStatus") == QLatin1String("Paused")) { + m_paused.insert(container->objectName(), container); + if (!makeActive && + data().value("PlaybackStatus") != QLatin1String("Playing") && + data().value("PlaybackStatus") != QLatin1String("Paused")) { + makeActive = true; + } + } else { + m_stopped.insert(container->objectName(), container); + } + + connect(container, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), + this, SLOT(playerUpdated(QString,Plasma::DataEngine::Data))); + + if (makeActive) { + m_activeName = container->objectName(); + replaceData(container->data()); + checkForUpdate(); + emit activePlayerChanged(container); + } +} + +void Multiplexer::removePlayer(const QString &name) +{ + PlayerContainer *container = m_playing.take(name); + if (!container) + container = m_paused.take(name); + if (!container) + container = m_stopped.take(name); + if (container) + container->disconnect(this); + + if (name == m_activeName) { + setBestActive(); + } +} + +PlayerContainer *Multiplexer::activePlayer() const +{ + if (m_activeName.isEmpty()) { + return 0; + } + + PlayerContainer *container = m_playing.value(m_activeName); + if (!container) + container = m_paused.value(m_activeName); + if (!container) + container = m_stopped.value(m_activeName); + Q_ASSERT(container); + return container; +} + +void Multiplexer::playerUpdated(const QString &name, const Plasma::DataEngine::Data &newData) +{ + if (newData.value("PlaybackStatus") == QLatin1String("Playing")) { + if (!m_playing.contains(name)) { + PlayerContainer *container = m_paused.take(name); + if (!container) { + container = m_stopped.take(name); + } + Q_ASSERT(container); + m_playing.insert(name, container); + } + if (m_activeName != name && + data().value("PlaybackStatus") != QLatin1String("Playing")) { + m_activeName = name; + replaceData(newData); + checkForUpdate(); + emit activePlayerChanged(activePlayer()); + return; + } + } else if (newData.value("PlaybackStatus") == QLatin1String("Paused")) { + if (!m_paused.contains(name)) { + PlayerContainer *container = m_playing.take(name); + if (!container) { + container = m_stopped.take(name); + } + Q_ASSERT(container); + m_paused.insert(name, container); + } + if (m_activeName != name && + data().value("PlaybackStatus") != QLatin1String("Playing") && + data().value("PlaybackStatus") != QLatin1String("Paused")) { + m_activeName = name; + replaceData(newData); + checkForUpdate(); + emit activePlayerChanged(activePlayer()); + return; + } + } else { + if (!m_stopped.contains(name)) { + PlayerContainer *container = m_playing.take(name); + if (!container) { + container = m_paused.take(name); + } + Q_ASSERT(container); + m_stopped.insert(name, container); + } + } + + if (m_activeName == name) { + bool isPaused = newData.value("PlaybackStatus") == QLatin1String("Paused"); + bool isStopped = !isPaused && newData.value("PlaybackStatus") != QLatin1String("Playing"); + if (isPaused && !m_playing.isEmpty()) { + setBestActive(); + } else if (isStopped && (!m_playing.isEmpty() || !m_paused.isEmpty())) { + setBestActive(); + } else { + replaceData(newData); + checkForUpdate(); + } + } +} + +void Multiplexer::setBestActive() +{ + QHash::const_iterator it = m_playing.constBegin(); + if (it != m_playing.constEnd()) { + m_activeName = it.key(); + replaceData(it.value()->data()); + emit activePlayerChanged(it.value()); + } else { + it = m_paused.constBegin(); + if (it != m_paused.constEnd()) { + m_activeName = it.key(); + replaceData(it.value()->data()); + emit activePlayerChanged(it.value()); + } else { + it = m_stopped.constBegin(); + if (it != m_stopped.constEnd()) { + m_activeName = it.key(); + replaceData(it.value()->data()); + emit activePlayerChanged(it.value()); + } else { + m_activeName = QString(); + removeAllData(); + emit activePlayerChanged(0); + } + } + } + checkForUpdate(); +} + +void Multiplexer::replaceData(const Plasma::DataEngine::Data &data) +{ + removeAllData(); + + Plasma::DataEngine::Data::const_iterator it = data.constBegin(); + while (it != data.constEnd()) { + setData(it.key(), it.value()); + ++it; + } + setData("Source Name", m_activeName); +} + diff --git a/plasma/generic/dataengines/mpris2/multiplexer.h b/plasma/generic/dataengines/mpris2/multiplexer.h new file mode 100644 index 00000000..083cdf1a --- /dev/null +++ b/plasma/generic/dataengines/mpris2/multiplexer.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef MULTIPLEXER_H +#define MULTIPLEXER_H + +#include + +#include "playercontainer.h" + +#include + +class Multiplexer : public Plasma::DataContainer +{ + Q_OBJECT + +public: + static const QLatin1String sourceName; + + explicit Multiplexer(QObject *parent = 0); + + void addPlayer(PlayerContainer *container); + void removePlayer(const QString &name); + PlayerContainer *activePlayer() const; + +signals: + void activePlayerChanged(PlayerContainer *container); + +private slots: + void playerUpdated(const QString &name, const Plasma::DataEngine::Data &data); + +private: + void setBestActive(); + void replaceData(const Plasma::DataEngine::Data &data); + + QString m_activeName; + QHash m_playing; + QHash m_paused; + QHash m_stopped; +}; + +#endif // MULTIPLEXER_H diff --git a/plasma/generic/dataengines/mpris2/org.freedesktop.DBus.Properties.xml b/plasma/generic/dataengines/mpris2/org.freedesktop.DBus.Properties.xml new file mode 100644 index 00000000..8fef9c38 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/org.freedesktop.DBus.Properties.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.Player.xml b/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.Player.xml new file mode 100644 index 00000000..96349980 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.Player.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.xml b/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.xml new file mode 100644 index 00000000..3bae600a --- /dev/null +++ b/plasma/generic/dataengines/mpris2/org.mpris.MediaPlayer2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/mpris2/plasma-dataengine-mpris2.desktop b/plasma/generic/dataengines/mpris2/plasma-dataengine-mpris2.desktop new file mode 100644 index 00000000..c5f88cbe --- /dev/null +++ b/plasma/generic/dataengines/mpris2/plasma-dataengine-mpris2.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +Name=MPRIS2 +Name[bs]=MPRIS2 +Name[ca]=MPRIS2 +Name[ca@valencia]=MPRIS2 +Name[cs]=MPRIS2 +Name[da]=MPRIS2 +Name[de]=MPRIS2 +Name[el]=MPRIS2 +Name[en_GB]=MPRIS2 +Name[es]=MPRIS2 +Name[et]=MPRIS2 +Name[eu]=MPRIS2 +Name[fi]=MPRIS2 +Name[fr]=MPRIS2 +Name[gl]=MPRIS2 +Name[he]=MPRIS2 +Name[hu]=MPRIS2 +Name[ia]=MPRIS2 +Name[it]=MPRIS2 +Name[kk]=MPRIS2 +Name[km]=MPRIS2 +Name[ko]=MPRIS2 +Name[lt]=MPRIS2 +Name[mr]=MPRIS2 +Name[nb]=MPRIS2 +Name[nds]=MPRIS2 +Name[nl]=MPRIS2 +Name[pa]=MPRIS2 +Name[pl]=MPRIS2 +Name[pt]=MPRIS2 +Name[pt_BR]=MPRIS2 +Name[ro]=MPRIS2 +Name[ru]=MPRIS2 +Name[sk]=MPRIS2 +Name[sl]=MPRIS2 +Name[sr]=МПРИС 2 +Name[sr@ijekavian]=МПРИС 2 +Name[sr@ijekavianlatin]=MPRIS 2 +Name[sr@latin]=MPRIS 2 +Name[sv]=MPRIS2 +Name[tr]=MPRIS2 +Name[uk]=MPRIS2 +Name[x-test]=xxMPRIS2xx +Name[zh_CN]=MPRIS2 +Name[zh_TW]=MPRIS2 +Comment=Provides information from and control over media players via MPRIS2 +Comment[bs]=Pruža informacije putem i kontrolom medija plejera pomoću MPRIS2 +Comment[ca]=Proporciona informació i controla els reproductors de suports via el MPRIS2 +Comment[ca@valencia]=Proporciona informació i controla els reproductors de suports via el MPRIS2 +Comment[cs]=Poskytuje informace a ovládání přehrávačů médií přes MPRIS2 +Comment[da]=Giver information fra og kontrol over medieafspillere via MPRIS2 +Comment[de]=Stellt Informationen über Medienspieler unter Verwendung von MPRIS2 bereit und ermöglicht deren Steuerung +Comment[el]=Παρέχει πληροφορίες και ελέγχει προγράμματα αναπαραγωγής πολυμέσων με το MPRIS2 +Comment[en_GB]=Provides information from and control over media players via MPRIS2 +Comment[es]=Proporciona información y control sobre reproductores multimedia vía MPRIS2 +Comment[et]=Teabe hankimine meediamängijatest ja nende juhtimine MPRIS2 kaudu +Comment[eu]=Multimedia-jotzaileei buruzko informazioa ematen du eta haiek kontrolatzen ditu MPRIS2 bidez +Comment[fi]=Mahdollistaa MPRIS2-yhteensopivien mediasoittimien hallinnan sekä tiedon välittämisen +Comment[fr]=Fournit des informations sur les lecteurs de média et les contrôle avec « MPRIS2 » +Comment[gl]=Fornece información e control de reprodutores multimedia mediante MPRIS2 +Comment[hu]=Információkat szolgáltat és vezérli a médialejátszókat az MPRIS2-n keresztül +Comment[ia]=Il provide information ex e control super media players via MPRIS2 +Comment[it]=Fornisce le informazioni da e controlla lettori multimediali via MPRIS2 +Comment[kk]=MPRIS2 арқылы медиаплейер мәліметін алып оны басқару мүмкіндігі +Comment[km]=ផ្ដល់​ព័ត៌មាន​ពី និង​ត្រួតពិនិត្យ​លើ​កម្មវិធី​ចាក់​មេឌៀ​តាមរយៈ MPRIS2 +Comment[ko]=MPRIS2를 통하여 미디어 재생기를 제어하고 정보 가져오기 +Comment[lt]=Pateikia informaciją iš MPRIS2 ir per jį valdo medijos grotuvus +Comment[mr]=MPRIS2 द्वारे मीडिया प्लेयर्स वर नियंत्रण व माहिती पुरवितो +Comment[nb]=Gir informasjon fra og kontroll over mediaspillere via MPRIS2-grensesnittet +Comment[nds]=Stellt Informatschonen ut un Kuntrull över Medienafspelers över MPRIS2 praat +Comment[nl]=Levert informatie uit en besturing aan mediaspelers via MPRIS2 +Comment[pl]=Dostarcza informacji z odtwarzaczy multimedialnych, a także steruje nimi przez MPRIS2 +Comment[pt]=Fornece informações e controla leitores multimédia através de MPRIS2 +Comment[pt_BR]=Fornece informações e controla leitores multimídia através de MPRIS2 +Comment[ro]=Furnizează informații de la și controlează lectorii multimedia prin MPRIS2 +Comment[ru]=Предоставление информации и управление медиапроигрывателем с помощью MPRIS2 +Comment[sk]=Poskytuje informácie z, a ovláda prehrávače médií cez MPRIS2 +Comment[sl]=Prikazuje podatke in omogoča nadzor predstavnostnih predvajalnikov +Comment[sr]=Подаци из медија плејера и управљање њима преко МПРИС‑а 2 +Comment[sr@ijekavian]=Подаци из медија плејера и управљање њима преко МПРИС‑а 2 +Comment[sr@ijekavianlatin]=Podaci iz medija plejera i upravljanje njima preko MPRIS‑a 2 +Comment[sr@latin]=Podaci iz medija plejera i upravljanje njima preko MPRIS‑a 2 +Comment[sv]=Tillhandahåller information från och styrning av mediaspelare via MPRIS2 +Comment[tr]=MPRIS2 kullanarak çokluortam oynatıcılara bilgi sağlar ve onları denetler +Comment[uk]=Надає дані з мультимедійних програвачів та керує ними за допомогою MPRIS2 +Comment[x-test]=xxProvides information from and control over media players via MPRIS2xx +Comment[zh_CN]=通过 MPRIS2 提供信息和控制播放器 +Comment[zh_TW]=透過 MPRIS2 取得媒體播放器的資訊並控制 + +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=applications-multimedia +X-KDE-Library=plasma_engine_mpris2 +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=mpris2 +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License= + diff --git a/plasma/generic/dataengines/mpris2/playeractionjob.cpp b/plasma/generic/dataengines/mpris2/playeractionjob.cpp new file mode 100644 index 00000000..fc656a00 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playeractionjob.cpp @@ -0,0 +1,180 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playeractionjob.h" + +#include "playercontrol.h" + +#include +#include +#include + +#include +#include +#include + +#include + +PlayerActionJob::PlayerActionJob(const QString& operation, + QMap& parameters, + PlayerControl* parent) + : ServiceJob(parent->name() + ": " + operation, operation, parameters, parent) + , m_controller(parent) +{ +} + +void PlayerActionJob::start() +{ + const QString operation(operationName()); + + kDebug() << "Trying to perform the action" << operationName(); + if (!m_controller->isOperationEnabled(operation)) { + setError(Denied); + emitResult(); + return; + } + + if (operation == QLatin1String("Quit") || operation == QLatin1String("Raise") + || operation == QLatin1String("SetFullscreen")) { + listenToCall(m_controller->rootInterface()->asyncCall(operation)); + } else if (operation == QLatin1String("Play") + || operation == QLatin1String("Pause") + || operation == QLatin1String("PlayPause") + || operation == QLatin1String("Stop") + || operation == QLatin1String("Next") + || operation == QLatin1String("Previous")) { + listenToCall(m_controller->playerInterface()->asyncCall(operation)); + } else if (operation == "Seek") { + if (parameters().value("microseconds").type() == QVariant::LongLong) { + listenToCall(m_controller->playerInterface()->Seek(parameters()["microseconds"].toLongLong())); + } else { + setErrorText("microseconds"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "SetPosition") { + if (parameters().value("microseconds").type() == QVariant::LongLong) { + listenToCall(m_controller->playerInterface()->SetPosition( + m_controller->trackId(), + parameters()["microseconds"].toLongLong())); + } else { + setErrorText("microseconds"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "OpenUri") { + if (parameters().value("uri").canConvert()) { + listenToCall(m_controller->playerInterface()->OpenUri( + QString::fromLatin1(parameters()["uri"].toUrl().toEncoded()))); + } else { + kDebug() << "uri was of type" << parameters().value("uri").userType(); + setErrorText("uri"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "SetLoopStatus") { + if (parameters().value("status").type() == QVariant::String) { + setDBusProperty(m_controller->playerInterface()->interface(), + "LoopStatus", QDBusVariant(parameters()["status"])); + } else { + setErrorText("status"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "SetShuffle") { + if (parameters().value("on").type() == QVariant::Bool) { + setDBusProperty(m_controller->playerInterface()->interface(), + "Shuffle", QDBusVariant(parameters()["on"])); + } else { + setErrorText("on"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "SetRate") { + if (parameters().value("rate").type() == QVariant::Double) { + setDBusProperty(m_controller->playerInterface()->interface(), + "Rate", QDBusVariant(parameters()["rate"])); + } else { + setErrorText("rate"); + setError(MissingArgument); + emitResult(); + } + } else if (operation == "SetVolume") { + if (parameters().value("level").type() == QVariant::Double) { + setDBusProperty(m_controller->playerInterface()->interface(), + "Volume", QDBusVariant(parameters()["level"])); + } else { + setErrorText("level"); + setError(MissingArgument); + emitResult(); + } + } else { + setError(UnknownOperation); + emitResult(); + } +} + +void PlayerActionJob::listenToCall(const QDBusPendingCall& call) +{ + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(callFinished(QDBusPendingCallWatcher*))); +} + +void PlayerActionJob::callFinished(QDBusPendingCallWatcher* watcher) +{ + QDBusPendingReply result = *watcher; + watcher->deleteLater(); + + if (result.isError()) { + // FIXME: try to be a bit cleverer with the error message? + setError(Failed); + setErrorText(result.error().message()); + } else { + setError(NoError); + } + + emitResult(); +} + +void PlayerActionJob::setDBusProperty(const QString& iface, const QString& propName, const QDBusVariant& value) +{ + listenToCall( + m_controller->propertiesInterface()->Set(iface, propName, value) + ); +} + +QString PlayerActionJob::errorString() const +{ + if (error() == Denied) { + return i18n("The media player '%1' cannot perform the action '%2'.", m_controller->name(), operationName()); + } else if (error() == Failed) { + return i18n("Attempting to perform the action '%1' failed with the message '%2'.", + operationName(), errorText()); + } else if (error() == MissingArgument) { + return i18n("The argument '%1' for the action '%2' is missing or of the wrong type.", operationName(), errorText()); + } else if (error() == UnknownOperation) { + return i18n("The operation '%1' is unknown.", operationName()); + } + return i18n("Unknown error."); +} + +#include "playeractionjob.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/mpris2/playeractionjob.h b/plasma/generic/dataengines/mpris2/playeractionjob.h new file mode 100644 index 00000000..6fd80367 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playeractionjob.h @@ -0,0 +1,74 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERACTIONJOB_H +#define PLAYERACTIONJOB_H + +#include + +class QDBusPendingCallWatcher; +class QDBusPendingCall; +class QDBusVariant; +class PlayerControl; + +class PlayerActionJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + PlayerActionJob(const QString& operation, + QMap& parameters, + PlayerControl* parent); + + enum { + /** + * The media player reports that the operation is not possible + */ + Denied = UserDefinedError, + /** + * Calling the media player resulted in an error + */ + Failed, + /** + * An argument is missing or of wrong type + * + * errorText is argument name + */ + MissingArgument, + /** + * The operation name is unknown + */ + UnknownOperation + }; + + void start(); + + virtual QString errorString() const; + +private slots: + void callFinished(QDBusPendingCallWatcher*); + void setDBusProperty(const QString& iface, const QString& propName, const QDBusVariant& value); + +private: + void listenToCall(const QDBusPendingCall& call); + + PlayerControl *m_controller; +}; + +#endif // PLAYERACTIONJOB_H diff --git a/plasma/generic/dataengines/mpris2/playercontainer.cpp b/plasma/generic/dataengines/mpris2/playercontainer.cpp new file mode 100644 index 00000000..23323f06 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playercontainer.cpp @@ -0,0 +1,397 @@ +/* + * Copyright 2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playercontainer.h" + +#include +#include +#include + +#define MPRIS2_PATH "/org/mpris/MediaPlayer2" +#define POS_UPD_STRING "Position last updated (UTC)" + +#include +#include +#include + +#include +#include + +static QVariant::Type expPropType(const QString& propName) +{ + if (propName == QLatin1String("Identity")) + return QVariant::String; + else if (propName == QLatin1String("DesktopEntry")) + return QVariant::String; + else if (propName == QLatin1String("SupportedUriSchemes")) + return QVariant::StringList; + else if (propName == QLatin1String("SupportedMimeTypes")) + return QVariant::StringList; + else if (propName == QLatin1String("Fullscreen")) + return QVariant::Bool; + else if (propName == QLatin1String("PlaybackStatus")) + return QVariant::String; + else if (propName == QLatin1String("LoopStatus")) + return QVariant::String; + else if (propName == QLatin1String("Shuffle")) + return QVariant::Bool; + else if (propName == QLatin1String("Rate")) + return QVariant::Double; + else if (propName == QLatin1String("MinimumRate")) + return QVariant::Double; + else if (propName == QLatin1String("MaximumRate")) + return QVariant::Double; + else if (propName == QLatin1String("Volume")) + return QVariant::Double; + else if (propName == QLatin1String("Position")) + return QVariant::LongLong; + else if (propName == QLatin1String("Metadata")) + return QVariant::Map; + // we give out CanControl, as this may completely + // change the UI of the widget + else if (propName == QLatin1String("CanControl")) + return QVariant::Bool; + return QVariant::Invalid; +} + +static PlayerContainer::Cap capFromName(const QString& capName) +{ + if (capName == QLatin1String("CanQuit")) + return PlayerContainer::CanQuit; + else if (capName == QLatin1String("CanRaise")) + return PlayerContainer::CanRaise; + else if (capName == QLatin1String("CanSetFullscreen")) + return PlayerContainer::CanSetFullscreen; + else if (capName == QLatin1String("CanControl")) + return PlayerContainer::CanControl; + else if (capName == QLatin1String("CanPlay")) + return PlayerContainer::CanPlay; + else if (capName == QLatin1String("CanPause")) + return PlayerContainer::CanPause; + else if (capName == QLatin1String("CanSeek")) + return PlayerContainer::CanSeek; + else if (capName == QLatin1String("CanGoNext")) + return PlayerContainer::CanGoNext; + else if (capName == QLatin1String("CanGoPrevious")) + return PlayerContainer::CanGoPrevious; + return PlayerContainer::NoCaps; +} + +PlayerContainer::PlayerContainer(const QString& busAddress, QObject* parent) + : DataContainer(parent) + , m_caps(NoCaps) + , m_fetchesPending(0) + , m_dbusAddress(busAddress) + , m_currentRate(0.0) +{ + Q_ASSERT(!busAddress.isEmpty()); + Q_ASSERT(busAddress.startsWith(QLatin1String("org.mpris.MediaPlayer2."))); + + m_propsIface = new OrgFreedesktopDBusPropertiesInterface( + busAddress, MPRIS2_PATH, + QDBusConnection::sessionBus(), this); + + m_playerIface = new OrgMprisMediaPlayer2PlayerInterface( + busAddress, MPRIS2_PATH, + QDBusConnection::sessionBus(), this); + + m_rootIface = new OrgMprisMediaPlayer2Interface( + busAddress, MPRIS2_PATH, + QDBusConnection::sessionBus(), this); + + connect(m_propsIface, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)), + this, SLOT(propertiesChanged(QString,QVariantMap,QStringList))); + + connect(m_playerIface, SIGNAL(Seeked(qlonglong)), + this, SLOT(seeked(qlonglong))); + + refresh(); +} + +void PlayerContainer::refresh() +{ + // despite these calls being async, we should never update values in the + // wrong order (eg: a stale GetAll response overwriting a more recent value + // from a PropertiesChanged signal) due to D-Bus message ordering guarantees. + + QDBusPendingCall async = m_propsIface->GetAll(OrgMprisMediaPlayer2Interface::staticInterfaceName()); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(getPropsFinished(QDBusPendingCallWatcher*))); + ++m_fetchesPending; + + async = m_propsIface->GetAll(OrgMprisMediaPlayer2PlayerInterface::staticInterfaceName()); + watcher = new QDBusPendingCallWatcher(async, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(getPropsFinished(QDBusPendingCallWatcher*))); + ++m_fetchesPending; +} + +static bool decodeUri(QVariantMap &map, const QString& entry) { + if (map.contains(entry)) { + QString urlString = map.value(entry).toString(); + QUrl url = QUrl::fromEncoded(urlString.toAscii()); + if (!url.isValid()) { + // try to be lenient + url = QUrl(urlString); + } + if (url.isValid()) { + map.insert(entry, QVariant(url)); + return true; + } else { + map.remove(entry); + return false; + } + } + // count it as a success if it doesn't exist + return true; +} + +void PlayerContainer::copyProperty(const QString& propName, const QVariant& _value, QVariant::Type expType, UpdateType updType) +{ + QVariant value = _value; + // we protect our users from bogus values + if (value.userType() == qMetaTypeId()) { + if (expType == QVariant::Map) { + QDBusArgument arg = value.value(); + if (arg.currentType() != QDBusArgument::MapType) { + kWarning() << m_dbusAddress << "exports" << propName + << "with the wrong type; it should be D-Bus type \"a{sv}\""; + return; + } + QVariantMap map; + arg >> map; + if (propName == QLatin1String("Metadata")) { + if (!decodeUri(map, QLatin1String("mpris:artUrl"))) { + kWarning() << m_dbusAddress << "has an invalid URL for the mpris:artUrl entry of the \"Metadata\" property"; + } + if (!decodeUri(map, QLatin1String("xesam:url"))) { + kWarning() << m_dbusAddress << "has an invalid URL for the xesam:url entry of the \"Metadata\" property"; + } + } + value = QVariant(map); + } + } + if (value.type() != expType) { + const char * gotTypeCh = QDBusMetaType::typeToSignature(value.userType()); + QString gotType = gotTypeCh ? QString::fromAscii(gotTypeCh) : ""; + const char * expTypeCh = QDBusMetaType::typeToSignature(expType); + QString expType = expTypeCh ? QString::fromAscii(expTypeCh) : ""; + + kWarning() << m_dbusAddress << "exports" << propName + << "as D-Bus type" << gotType + << "but it should be D-Bus type" << expType; + } + if (value.convert(expType)) { + if (propName == QLatin1String("Position")) { + + setData(POS_UPD_STRING, QDateTime::currentDateTimeUtc()); + + } else if (propName == QLatin1String("Metadata")) { + + if (updType == UpdatedSignal) { + QDBusObjectPath oldTrackId = data().value("Metadata").toMap().value("mpris:trackid").value(); + QDBusObjectPath newTrackId = value.toMap().value("mpris:trackid").value(); + if (oldTrackId != newTrackId) { + setData("Position", static_cast(0)); + setData(POS_UPD_STRING, QDateTime::currentDateTimeUtc()); + } + } + + } else if (propName == QLatin1String("Rate") && + data().value("PlaybackStatus").toString() == QLatin1String("Playing")) { + + if (data().contains("Position")) + recalculatePosition(); + m_currentRate = value.toDouble(); + + } else if (propName == QLatin1String("PlaybackStatus")) { + + if (data().contains("Position") && data().contains("PlaybackStatus")) { + recalculatePosition(); + + if (data().value("PlaybackStatus").toString() == QLatin1String("Playing") + && value.toString() == QLatin1String("Paused")) { + // Every time something that affects the predicted position changes + // (Rate or PlaybackStatus), we get a hundred milliseconds or so + // out, due to the time it takes for a D-Bus message to be delivered + // and processed. + // + // To try to prevent these errors from accumulating, we re-fetch + // the position when we enter paused mode; when paused, the position + // does not change, so we'll be about as accurate as we can be. + updatePosition(); + } + } + + // update the effective rate + if (data().contains("Rate")) { + if (value.toString() == QLatin1String("Playing")) + m_currentRate = data().value("Rate").toDouble(); + else + m_currentRate = 0.0; + } + if (value.toString() == QLatin1String("Stopped")) { + // assume the position has reset to 0, since this is really the + // only sensible value for a stopped track + setData("Position", static_cast(0)); + setData(POS_UPD_STRING, QDateTime::currentDateTimeUtc()); + } + } else if (propName == QLatin1String("DesktopEntry")) { + QString filename = value.toString() + QLatin1String(".desktop"); + KDesktopFile desktopFile("xdgdata-apps", filename); + QString iconName = desktopFile.readIcon(); + if (!iconName.isEmpty()) { + setData("Desktop Icon Name", iconName); + } + } + setData(propName, value); + } +} + +void PlayerContainer::updateFromMap(const QVariantMap& map, UpdateType updType) +{ + QMap::const_iterator i = map.constBegin(); + while (i != map.constEnd()) { + QVariant::Type type = expPropType(i.key()); + if (type != QVariant::Invalid) { + copyProperty(i.key(), i.value(), type, updType); + } + + Cap cap = capFromName(i.key()); + if (cap != NoCaps) { + if (i.value().type() == QVariant::Bool) { + if (i.value().toBool()) { + m_caps |= cap; + } else { + m_caps &= ~cap; + } + } else { + const char * gotTypeCh = QDBusMetaType::typeToSignature(i.value().userType()); + QString gotType = gotTypeCh ? QString::fromAscii(gotTypeCh) : ""; + + kWarning() << m_dbusAddress << "exports" << i.key() + << "as D-Bus type" << gotType + << "but it should be D-Bus type \"b\""; + } + } + // fake the CanStop capability + if (cap == CanControl || i.key() == QLatin1String("PlaybackStatus")) { + if ((m_caps & CanControl) && i.value().toString() != QLatin1String("Stopped")) { + kDebug() << "Enabling stop action"; + m_caps |= CanStop; + } else { + kDebug() << "Disabling stop action"; + m_caps &= ~CanStop; + } + } + ++i; + } +} + +void PlayerContainer::getPropsFinished(QDBusPendingCallWatcher* watcher) +{ + QDBusPendingReply propsReply = *watcher; + watcher->deleteLater(); + + if (m_fetchesPending < 1) { + // we already failed + return; + } + + if (propsReply.isError()) { + kWarning() << m_dbusAddress << "does not implement" + << OrgFreedesktopDBusPropertiesInterface::staticInterfaceName() + << "correctly"; + kDebug() << "Error message was" << propsReply.error().name() << propsReply.error().message(); + m_fetchesPending = 0; + emit initialFetchFailed(this); + return; + } + + updateFromMap(propsReply.value(), FetchAll); + checkForUpdate(); + + --m_fetchesPending; + if (m_fetchesPending == 0) { + emit initialFetchFinished(this); + } +} + +void PlayerContainer::updatePosition() +{ + QDBusPendingCall async = m_propsIface->Get(OrgMprisMediaPlayer2PlayerInterface::staticInterfaceName(), "Position"); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(getPositionFinished(QDBusPendingCallWatcher*))); +} + +void PlayerContainer::getPositionFinished(QDBusPendingCallWatcher* watcher) +{ + QDBusPendingReply propsReply = *watcher; + watcher->deleteLater(); + + if (propsReply.isError()) { + kWarning() << m_dbusAddress << "does not implement" + << OrgFreedesktopDBusPropertiesInterface::staticInterfaceName() + << "correctly"; + kDebug() << "Error message was" << propsReply.error().name() << propsReply.error().message(); + return; + } + + setData("Position", propsReply.value().toLongLong()); + setData(POS_UPD_STRING, QDateTime::currentDateTimeUtc()); + checkForUpdate(); +} + +void PlayerContainer::propertiesChanged( + const QString& interface, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties) +{ + Q_UNUSED(interface) + + updateFromMap(changedProperties, UpdatedSignal); + if (!invalidatedProperties.isEmpty()) { + refresh(); + } + checkForUpdate(); +} + +void PlayerContainer::seeked(qlonglong position) +{ + setData("Position", position); + setData(POS_UPD_STRING, QDateTime::currentDateTimeUtc()); + checkForUpdate(); +} + +void PlayerContainer::recalculatePosition() +{ + Q_ASSERT(data().contains("Position")); + + qint64 pos = data().value("Position").toLongLong(); + QDateTime lastUpdated = data().value(POS_UPD_STRING).toDateTime(); + QDateTime now = QDateTime::currentDateTimeUtc(); + qint64 diff = lastUpdated.msecsTo(now) * 1000; + qint64 newPos = pos + static_cast(diff * m_currentRate); + setData("Position", newPos); + setData(POS_UPD_STRING, now); +} + +#include "playercontainer.moc" diff --git a/plasma/generic/dataengines/mpris2/playercontainer.h b/plasma/generic/dataengines/mpris2/playercontainer.h new file mode 100644 index 00000000..34a2ad85 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playercontainer.h @@ -0,0 +1,99 @@ +/* + * Copyright 2008-2012 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERCONTAINER_H +#define PLAYERCONTAINER_H + +#include +#include + +class OrgFreedesktopDBusPropertiesInterface; +class OrgMprisMediaPlayer2Interface; +class OrgMprisMediaPlayer2PlayerInterface; +class PlayerControl; +class QDBusPendingCallWatcher; + +class PlayerContainer : public Plasma::DataContainer +{ + Q_OBJECT + +public: + explicit PlayerContainer(const QString& busAddress, QObject* parent = 0); + + QString dbusAddress() const { return m_dbusAddress; } + OrgFreedesktopDBusPropertiesInterface* propertiesInterface() const { return m_propsIface; } + OrgMprisMediaPlayer2Interface* rootInterface() const { return m_rootIface; } + OrgMprisMediaPlayer2PlayerInterface* playerInterface() const { return m_playerIface; } + + enum Cap { + NoCaps = 0, + CanQuit = 1 << 0, + CanRaise = 1 << 1, + CanSetFullscreen = 1 << 2, + CanControl = 1 << 3, + CanPlay = 1 << 4, + CanPause = 1 << 5, + CanSeek = 1 << 6, + CanGoNext = 1 << 7, + CanGoPrevious = 1 << 8, + // CanStop is not directly provided by the spec, + // but we infer it from PlaybackStatus and CanControl + CanStop = 1 << 9 + }; + Q_DECLARE_FLAGS(Caps, Cap) + Caps capabilities() const { return m_caps; } + + enum UpdateType { + FetchAll, + UpdatedSignal + }; + + void refresh(); + +signals: + void initialFetchFinished(PlayerContainer* self); + void initialFetchFailed(PlayerContainer* self); + void capsChanged(Caps newCaps); + +private slots: + void getPropsFinished(QDBusPendingCallWatcher* watcher); + void getPositionFinished(QDBusPendingCallWatcher* watcher); + void propertiesChanged(const QString& interface, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties); + void seeked(qlonglong position); + +private: + void copyProperty(const QString& propName, const QVariant& value, QVariant::Type expType, UpdateType updType); + void updateFromMap(const QVariantMap& map, UpdateType updType); + void updatePosition(); + void recalculatePosition(); + + Caps m_caps; + int m_fetchesPending; + QString m_dbusAddress; + OrgFreedesktopDBusPropertiesInterface *m_propsIface; + OrgMprisMediaPlayer2Interface *m_rootIface; + OrgMprisMediaPlayer2PlayerInterface *m_playerIface; + double m_currentRate; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(PlayerContainer::Caps) + +#endif // PLAYERCONTAINER_H diff --git a/plasma/generic/dataengines/mpris2/playercontrol.cpp b/plasma/generic/dataengines/mpris2/playercontrol.cpp new file mode 100644 index 00000000..e28fbc23 --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playercontrol.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playercontrol.h" + +#include "playeractionjob.h" +#include "playercontainer.h" + +#include +#include +#include + +#include +#include + +PlayerControl::PlayerControl(PlayerContainer* container, QObject* parent) + : Plasma::Service(parent) + , m_container(container) +{ + setObjectName(container->objectName() + QLatin1String(" controller")); + setName("mpris2"); + setDestination(container->objectName()); + + connect(container, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), + this, SLOT(updateEnabledOperations())); + connect(container, SIGNAL(destroyed(QObject*)), + this, SLOT(containerDestroyed())); + updateEnabledOperations(); +} + +void PlayerControl::updateEnabledOperations() +{ + PlayerContainer::Caps caps = PlayerContainer::NoCaps; + if (m_container) + caps = m_container->capabilities(); + + setOperationEnabled("Quit", caps & PlayerContainer::CanQuit); + setOperationEnabled("Raise", caps & PlayerContainer::CanRaise); + setOperationEnabled("SetFullscreen", caps & PlayerContainer::CanSetFullscreen); + + setOperationEnabled("Play", caps & PlayerContainer::CanPlay); + setOperationEnabled("Pause", caps & PlayerContainer::CanPause); + setOperationEnabled("PlayPause", caps & PlayerContainer::CanPause); + setOperationEnabled("Stop", caps & PlayerContainer::CanStop); + setOperationEnabled("Next", caps & PlayerContainer::CanGoNext); + setOperationEnabled("Previous", caps & PlayerContainer::CanGoPrevious); + setOperationEnabled("Seek", caps & PlayerContainer::CanSeek); + setOperationEnabled("SetPosition", caps & PlayerContainer::CanSeek); + setOperationEnabled("OpenUri", caps & PlayerContainer::CanControl); + setOperationEnabled("SetVolume", caps & PlayerContainer::CanControl); + setOperationEnabled("SetLoopStatus", caps & PlayerContainer::CanControl); + setOperationEnabled("SetRate", caps & PlayerContainer::CanControl); + setOperationEnabled("SetShuffle", caps & PlayerContainer::CanControl); + + emit enabledOperationsChanged(); +} + +QDBusObjectPath PlayerControl::trackId() const +{ + return m_container->data().value("Metadata").toMap().value("mpris:trackid").value(); +} + +void PlayerControl::containerDestroyed() +{ + m_container = 0; +} + +Plasma::ServiceJob* PlayerControl::createJob(const QString& operation, + QMap& parameters) +{ + if (!m_container) + return 0; + return new PlayerActionJob(operation, parameters, this); +} + +#include "playercontrol.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/mpris2/playercontrol.h b/plasma/generic/dataengines/mpris2/playercontrol.h new file mode 100644 index 00000000..100654bf --- /dev/null +++ b/plasma/generic/dataengines/mpris2/playercontrol.h @@ -0,0 +1,61 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERCONTROL_H +#define PLAYERCONTROL_H + +#include "playercontainer.h" + +#include +#include + +class OrgFreedesktopDBusPropertiesInterface; +class OrgMprisMediaPlayer2Interface; +class OrgMprisMediaPlayer2PlayerInterface; + +class PlayerControl : public Plasma::Service +{ + Q_OBJECT + +public: + PlayerControl(PlayerContainer* container, QObject* parent); + + OrgMprisMediaPlayer2Interface* rootInterface() const + { return m_container->rootInterface(); } + OrgMprisMediaPlayer2PlayerInterface* playerInterface() const + { return m_container->playerInterface(); } + OrgFreedesktopDBusPropertiesInterface* propertiesInterface() const + { return m_container->propertiesInterface(); } + QDBusObjectPath trackId() const; + + Plasma::ServiceJob* createJob(const QString& operation, + QMap& parameters); + +signals: + void enabledOperationsChanged(); + +private slots: + void updateEnabledOperations(); + void containerDestroyed(); + +private: + PlayerContainer *m_container; +}; + +#endif // PLAYERCONTROL_H diff --git a/plasma/generic/dataengines/network/CMakeLists.txt b/plasma/generic/dataengines/network/CMakeLists.txt new file mode 100644 index 00000000..9e3272fd --- /dev/null +++ b/plasma/generic/dataengines/network/CMakeLists.txt @@ -0,0 +1,10 @@ +set(network_engine_SRCS + networkengine.cpp +) + +kde4_add_plugin(plasma_engine_network ${network_engine_SRCS}) +target_link_libraries(plasma_engine_network ${KDE4_KDECORE_LIBS} ${KDE4_PLASMA_LIBS} solidcontrol) + +install(TARGETS plasma_engine_network DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-network.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/network/Messages.sh b/plasma/generic/dataengines/network/Messages.sh new file mode 100755 index 00000000..357360a4 --- /dev/null +++ b/plasma/generic/dataengines/network/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_network.pot diff --git a/plasma/generic/dataengines/network/networkengine.cpp b/plasma/generic/dataengines/network/networkengine.cpp new file mode 100644 index 00000000..63478d9f --- /dev/null +++ b/plasma/generic/dataengines/network/networkengine.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2007 Percy Leonhardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "networkengine.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//#define SYSPATH "/sys/class/net/" + +NetworkEngine::NetworkEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_secondsSinceLastUpdate(0) +{ + Q_UNUSED(args) + setMinimumPollingInterval(1000); +} + +NetworkEngine::~NetworkEngine() +{ +} + +QStringList NetworkEngine::sources() const +{ + Solid::Control::NetworkInterfaceList iflist = Solid::Control::NetworkManager::networkInterfaces(); + + QStringList availableInterfaces; + foreach (Solid::Control::NetworkInterface *iface, iflist) { + availableInterfaces.append(iface->uni().section('/', -1)); + } + return availableInterfaces; +} + +bool NetworkEngine::sourceRequestEvent(const QString &name) +{ + Solid::Control::NetworkInterfaceList iflist = Solid::Control::NetworkManager::networkInterfaces(); + + foreach(Solid::Control::NetworkInterface *iface, iflist) { + if (name == iface->uni().section('/', -1)) { + setData(name, DataEngine::Data()); + setData(name, I18N_NOOP("UNI"), iface->uni()); + updateSourceEvent(name); + return true; + } + } + return false; +} + +bool NetworkEngine::updateSourceEvent(const QString &source) +{ + const QString uni = query(source)[I18N_NOOP("UNI")].toString(); + Solid::Control::NetworkInterface *iface = Solid::Control::NetworkManager::findNetworkInterface(uni); + if (!iface) { + // remove the source as the interface is no longer available + removeSource(source); + return false; + } + + // Check if it is a wireless interface. + bool isWireless = iface->type() == Solid::Control::NetworkInterface::Ieee80211; + setData(source, I18N_NOOP("Wireless"), isWireless); + Solid::Control::WirelessNetworkInterface *wlan = 0; + + if (isWireless) { + wlan = static_cast(iface); + + QStringList availableNetworks; + Solid::Control::AccessPointList apList = wlan->accessPoints(); + foreach (const QString &apId, apList) { + Solid::Control::AccessPoint *ap = wlan->findAccessPoint(apId); + availableNetworks += ap->ssid(); + } + setData(source, I18N_NOOP("Available networks"), availableNetworks); + } + + Solid::Control::NetworkInterface::ConnectionState connectionState = iface->connectionState(); + if (connectionState == Solid::Control::NetworkInterface::Activated) { + // update the interface + updateInterfaceData(source, iface); + if (isWireless) { + updateWirelessData(source, wlan); + } + } else if (connectionState != Solid::Control::NetworkInterface::Activated && + query(source)[I18N_NOOP("ConnectionState")].toString() == I18N_NOOP("Activated")) { + // the interface was disconnected + removeAllData(source); + setData(source, I18N_NOOP("UNI"), uni); + } + + switch (connectionState) { + case Solid::Control::NetworkInterface::Preparing: + setData(source, I18N_NOOP("ConnectionState"), "Preparing"); + break; + case Solid::Control::NetworkInterface::Configuring: + setData(source, I18N_NOOP("ConnectionState"), "Configuring"); + break; + case Solid::Control::NetworkInterface::NeedAuth: + setData(source, I18N_NOOP("ConnectionState"), "NeedAuth"); + break; + case Solid::Control::NetworkInterface::IPConfig: + setData(source, I18N_NOOP("ConnectionState"), "IPConfig"); + break; + case Solid::Control::NetworkInterface::Activated: + setData(source, I18N_NOOP("ConnectionState"), "Activated"); + break; + case Solid::Control::NetworkInterface::Failed: + setData(source, I18N_NOOP("ConnectionState"), "Failed"); + break; + case Solid::Control::NetworkInterface::Unmanaged: + setData(source, I18N_NOOP("ConnectionState"), "Unmanaged"); + break; + case Solid::Control::NetworkInterface::Unavailable: + setData(source, I18N_NOOP("ConnectionState"), "Unavailable"); + break; + default: + setData(source, I18N_NOOP("ConnectionState"), "UnknownState"); + break; + } + return true; +} + +void NetworkEngine::updateInterfaceData(const QString &source, const Solid::Control::NetworkInterface *iface) +{ + Q_ASSERT(iface); + Solid::Control::IPv4Config network = iface->ipV4Config(); + +#if 0 + if (network.isValid()) { + setData(source, I18N_NOOP("Broadcast"), network.broadcast()); + } else { + removeData(source, I18N_NOOP("Broadcast")); + } +#endif + + QList addresses = network.addresses(); + if (addresses.isEmpty()) { + removeData(source, I18N_NOOP("Gateway")); + removeData(source, I18N_NOOP("IP")); + removeData(source, I18N_NOOP("Subnet mask")); + } else { + // FIXME: assumes there is only one network for ethernet + Solid::Control::IPv4Address address = addresses[0]; + setData(source, I18N_NOOP("Gateway"), address.gateway()); + setData(source, I18N_NOOP("IP"), address.address()); + setData(source, I18N_NOOP("Subnet mask"), address.netMask()); + } +} + +void NetworkEngine::updateWirelessData(const QString &source, const Solid::Control::WirelessNetworkInterface *iface) +{ + Q_ASSERT(iface); + const QString currentAP = iface->activeAccessPoint(); + + using namespace Solid::Control; + AccessPoint *ap = iface->findAccessPoint(currentAP); + WirelessNetworkInterface::OperationMode mode(WirelessNetworkInterface::Unassociated); + WirelessNetworkInterface::Capabilities capabilities(WirelessNetworkInterface::NoCapability); + + if (ap) { + setData(source, I18N_NOOP("Link quality"), ap->signalStrength()); + setData(source, I18N_NOOP("Frequency"), ap->frequency()); + setData(source, I18N_NOOP("ESSID"), ap->ssid()); + setData(source, I18N_NOOP("Bitrate"), ap->maxBitRate()); + setData(source, I18N_NOOP("Accesspoint"), ap->hardwareAddress()); + mode = ap->mode(); + } else { + setData(source, I18N_NOOP("Accesspoint"), i18n("None")); + removeData(source, I18N_NOOP("Link quality")); + removeData(source, I18N_NOOP("Frequency")); + removeData(source, I18N_NOOP("ESSID")); + removeData(source, I18N_NOOP("Bitrate")); + } + + switch (mode) { + case WirelessNetworkInterface::Unassociated: + setData(source, I18N_NOOP("Mode"), "Unassociated"); + break; + case WirelessNetworkInterface::Adhoc: + setData(source, I18N_NOOP("Mode"), "Adhoc"); + break; + case WirelessNetworkInterface::Managed: + setData(source, I18N_NOOP("Mode"), "Managed"); + break; + case WirelessNetworkInterface::Master: + setData(source, I18N_NOOP("Mode"), "Master"); + break; + case WirelessNetworkInterface::Repeater: + setData(source, I18N_NOOP("Mode"), "Repeater"); + break; + default: + setData(source, I18N_NOOP("Mode"), i18n("Unknown")); + break; + } + + setData(source, I18N_NOOP("Encryption"), + (capabilities & Solid::Control::AccessPoint::Privacy) != 0); +} + +#include "networkengine.moc" diff --git a/plasma/generic/dataengines/network/networkengine.h b/plasma/generic/dataengines/network/networkengine.h new file mode 100644 index 00000000..e6a63486 --- /dev/null +++ b/plasma/generic/dataengines/network/networkengine.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Percy Leonhardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETWORKENGINE_H +#define NETWORKENGINE_H + +#include + +namespace Solid +{ + namespace Control + { + class NetworkInterface; + class WirelessNetworkInterface; + } // namespace Control +} // namespace Solid + +class NetworkEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + NetworkEngine(QObject* parent, const QVariantList& args); + ~NetworkEngine(); + + QStringList sources() const; + +protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString& source); + +private: + void updateWirelessData(const QString &source, const Solid::Control::WirelessNetworkInterface *iface); + void updateInterfaceData(const QString &source, const Solid::Control::NetworkInterface *iface); + + int m_secondsSinceLastUpdate; +}; + +K_EXPORT_PLASMA_DATAENGINE(network, NetworkEngine) + +#endif diff --git a/plasma/generic/dataengines/network/plasma-dataengine-network.desktop b/plasma/generic/dataengines/network/plasma-dataengine-network.desktop new file mode 100644 index 00000000..fa8d2ad0 --- /dev/null +++ b/plasma/generic/dataengines/network/plasma-dataengine-network.desktop @@ -0,0 +1,183 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Networking +Name[ar]=ربط الشبكات +Name[ast]=Rede +Name[be@latin]=Sietka +Name[bg]=Мрежа +Name[bn]=নেটওয়ার্কিং +Name[bn_IN]=নেটওয়ার্ক ব্যবস্থা +Name[bs]=umrežavanje +Name[ca]=Treball en xarxa +Name[ca@valencia]=Treball en xarxa +Name[cs]=Síťové nástroje +Name[csb]=Séc +Name[da]=Netværk +Name[de]=Netzwerk +Name[el]=Δίκτυο +Name[en_GB]=Networking +Name[eo]=Reto +Name[es]=Red +Name[et]=Võrk +Name[eu]=Sarea +Name[fi]=Verkkotyöskentely +Name[fr]=Réseau +Name[fy]=netwurkjen +Name[ga]=Líonrú +Name[gl]=Rede +Name[gu]=નેટવર્કિંગ +Name[he]=רשת +Name[hi]=नेटवर्किंग +Name[hne]=नेटवर्किंग +Name[hr]=Mreža +Name[hu]=Hálózatkezelő +Name[ia]=Networking (A proposito del rete) +Name[id]=Jaringan +Name[is]=Netvinnsla +Name[it]=Rete +Name[ja]=ネットワーキング +Name[kk]=Желі +Name[km]=ការ​តបណ្ដាញ +Name[kn]=ಜಾಲಬಂಧ +Name[ko]=네트워킹 +Name[ku]=Têketina Torê +Name[lt]=Tinklas +Name[lv]=Tīkls +Name[mai]=नेटवर्किंग +Name[mk]=Мрежа +Name[ml]=ശൃംഖല +Name[mr]=नेटवर्कींग +Name[nb]=Nettverk +Name[nds]=Nettwark +Name[nl]=Netwerken +Name[nn]=Nettverk +Name[or]=ନେଟୱର୍କିଙ୍ଗ +Name[pa]=ਨੈੱਟਵਰਕਿੰਗ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=Rețea +Name[ru]=Сеть +Name[si]=ජාලය +Name[sk]=Sieť +Name[sl]=Povezovanje +Name[sr]=умрежавање +Name[sr@ijekavian]=умрежавање +Name[sr@ijekavianlatin]=umrežavanje +Name[sr@latin]=umrežavanje +Name[sv]=Nätverk +Name[ta]=பிணையம் +Name[tg]=Шабака +Name[th]=ระบบเครือข่าย +Name[tr]=Ağ +Name[ug]=تور +Name[uk]=Робота у мережі +Name[wa]=Rantoelaedje +Name[x-test]=xxNetworkingxx +Name[zh_CN]=网络 +Name[zh_TW]=網路 +Comment=Network interface information +Comment[af]=Netwerk koppelvlak informasie +Comment[ar]=معلومات عن واجهات الشبكة +Comment[as]=নে'টৱৰ্ক সংযোগমাধ্যমৰ তথ্য +Comment[ast]=Información sobre la interface de rede +Comment[be]=Звесткі пра сеткавы інтэрфейс +Comment[be@latin]=Źviestki pra sietkavyja interfejsy +Comment[bg]=Данни за мрежовите интерфейси +Comment[bn]=নেটওয়ার্ক ইন্টারফেস সংক্রান্ত তথ্য +Comment[bn_IN]=নেটওয়ার্ক ইন্টারফেস সংক্রান্ত তথ্য +Comment[br]=Titouroù diwar-benn an etrefasoù rouedad +Comment[bs]=podaci o mrežnom sučelju +Comment[ca]=Informació de la interfície de xarxa +Comment[ca@valencia]=Informació de la interfície de xarxa +Comment[cs]=Informace o síťových rozhraních +Comment[csb]=Wëdowiédzô ò sécowim interfejse +Comment[cy]=Gwybodaeth rhyngwynebau rhwydwaith +Comment[da]=Information om netværksgrænseflade +Comment[de]=Informationen zu Netzwerkschnittstellen +Comment[el]=Πληροφορίες διεπαφών δικτύου +Comment[en_GB]=Network interface information +Comment[eo]=Informoj pri retinterfaco +Comment[es]=Información sobre la interfaz de red +Comment[et]=Võrguliideste info +Comment[eu]=Sare-interfazeari buruzko informazioa +Comment[fa]=اطلاعات واسط شبکه +Comment[fi]=Verkkoliityntöjen tiedot +Comment[fr]=Informations sur les interfaces réseau +Comment[fy]=Netwurkynterface-ynformaasje +Comment[ga]=Eolas faoin gcomhéadan líonra +Comment[gl]=Información da interface de rede +Comment[gu]=નેટવર્ક ઇન્ટરફેસ માહિતી +Comment[he]=מידע על ממשקי רשת +Comment[hi]=नेटवर्क इंटरफेस जानकारी +Comment[hne]=नेटवर्क इंटरफेस जानकारी +Comment[hr]=Podaci o mrežnom sučelju +Comment[hsb]=Informacija wo syćowych interfejsach +Comment[hu]=A hálózati kártyák jellemzői +Comment[ia]=Information de interfacie de rete +Comment[id]=Informasi antarmuka jaringan +Comment[is]=Upplýsingar um netkort +Comment[it]=Informazioni sulle interfacce di rete +Comment[ja]=ネットワークインターフェースの情報 +Comment[ka]=ცნობები ქსელური ინტერფეისების შესახებ +Comment[kk]=Желі интерфейсінің мәліметі +Comment[km]=ព័ត៌មាន​ចំណុច​ប្រទាក់​បណ្ដាញ +Comment[kn]=ಜಾಲ ಸಂಪರ್ಕತಟಗಳ (ಇಂಟರ್ಫೇಸ್) ಮಾಹಿತಿ +Comment[ko]=네트워크 인터페이스 정보 +Comment[ku]=Agahiyên navrûyên torê +Comment[lt]=Tinklo sąsajos informacija +Comment[lv]=Tīkla ierīču informācija +Comment[mai]=नेटवर्क इंटरफेस सूचना +Comment[mk]=Информации за мрежните интерфејси +Comment[ml]=ശൃഖലാ വിനിമയതലങ്ങളെക്കുറിച്ചുള്ള വിവരം +Comment[mr]=संजाळ दुवा माहिती +Comment[ms]=Maklumat antara muka rangkaian +Comment[nb]=Informasjon om nettverksgrensesnitt +Comment[nds]=Informatschoon över de Nettwark-Koppelsteden +Comment[ne]=सञ्जाल इन्टरफेस सूचना +Comment[nl]=Netwerkinterface-informatie +Comment[nn]=Informasjon om nettverksgrensesnitt +Comment[or]=ନେଟୱର୍କ ଅନ୍ତାରାପୃଷ୍ଠ ସୂଚନା +Comment[pa]=ਨੈੱਟਵਰਕ ਇੰਟਰਫੇਸ ਜਾਣਕਾਰੀ +Comment[pl]=Informacje o interfejsach sieciowych +Comment[pt]=Informações sobre as interfaces de rede +Comment[pt_BR]=Informações da interface de rede +Comment[ro]=Afișează informații despre interfețele de rețea +Comment[ru]=Сведения о сетевых интерфейсах +Comment[se]=Fierbmalaktadiehtu +Comment[si]=ජාල මුහුණත් තොරතුරු +Comment[sk]=Informácie o sieťových rozhraniach +Comment[sl]=Podatki o omrežnih vmesnikih +Comment[sr]=Подаци о мрежним сучељима +Comment[sr@ijekavian]=Подаци о мрежним сучељима +Comment[sr@ijekavianlatin]=Podaci o mrežnim sučeljima +Comment[sr@latin]=Podaci o mrežnim sučeljima +Comment[sv]=Information om nätverksgränssnitt +Comment[ta]=பிணைய இடைமுகப்பு தகவல் +Comment[te]=నెట్వర్క్ ఇంటర్ ఫెస్ సమాచారం +Comment[tg]=Иттилооти воситаҳои шабака +Comment[th]=ข้อมูลแผงวงจรเครือข่าย +Comment[tr]=Ağ arayüz bilgisi +Comment[ug]=تور ئارايۈز ئۇچۇرلىرى +Comment[uk]=Інформація щодо інтерфейсів мережі +Comment[uz]=Tarmoq interfeyslari haqida maʼlumot +Comment[uz@cyrillic]=Тармоқ интерфейслари ҳақида маълумот +Comment[vi]=Thông tin giao diện mạng +Comment[wa]=Informåcion so l' eterface rantoele +Comment[xh]=Ulwazi lojongano lomsebenzi womnatha +Comment[x-test]=xxNetwork interface informationxx +Comment[zh_CN]=网络接口信息 +Comment[zh_TW]=網路界面資訊 +ServiceTypes=Plasma/DataEngine +Type=Service +Icon=network-workgroup +X-KDE-Library=plasma_engine_network + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=network +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/notifications/CMakeLists.txt b/plasma/generic/dataengines/notifications/CMakeLists.txt new file mode 100644 index 00000000..cf349715 --- /dev/null +++ b/plasma/generic/dataengines/notifications/CMakeLists.txt @@ -0,0 +1,15 @@ +set(notifications_engine_SRCS + notificationsengine.cpp + notificationservice.cpp + notificationaction.cpp +) + +qt4_add_dbus_adaptor( notifications_engine_SRCS org.freedesktop.Notifications.xml notificationsengine.h NotificationsEngine ) + +kde4_add_plugin(plasma_engine_notifications ${notifications_engine_SRCS}) + +target_link_libraries(plasma_engine_notifications ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS} ${KDE4_KNOTIFYCONFIG_LIBRARY}) + +install(TARGETS plasma_engine_notifications DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-notifications.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES notifications.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/plasma/generic/dataengines/notifications/Messages.sh b/plasma/generic/dataengines/notifications/Messages.sh new file mode 100755 index 00000000..5d52b61d --- /dev/null +++ b/plasma/generic/dataengines/notifications/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_notifications.pot diff --git a/plasma/generic/dataengines/notifications/notificationaction.cpp b/plasma/generic/dataengines/notifications/notificationaction.cpp new file mode 100644 index 00000000..f35bf19f --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationaction.cpp @@ -0,0 +1,73 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "notificationaction.h" +#include "notificationsengine.h" + +#include + +void NotificationAction::start() +{ + //kDebug() << "Trying to perform the action " << operationName() << " on " << destination(); + //kDebug() << "actionId: " << parameters()["actionId"].toString(); + //kDebug() << "params: " << parameters(); + + if (!m_engine) { + setErrorText(i18n("The notification dataEngine is not set.")); + setError(-1); + emitResult(); + return; + } + + const QStringList dest = destination().split(' '); + + uint id = 0; + if (dest.count() > 1 && !dest[1].toInt()) { + setErrorText(i18n("Invalid destination: %1", destination())); + setError(-2); + emitResult(); + return; + } else if (dest.count() > 1) { + id = dest[1].toUInt(); + } + + if (operationName() == "invokeAction") { + //kDebug() << "invoking action on " << id; + emit m_engine->ActionInvoked(id, parameters()["actionId"].toString()); + } else if (operationName() == "userClosed") { + //userClosedNotification deletes the job, so we have to invoke it queued, in this case emitResult() can be called + m_engine->metaObject()->invokeMethod(m_engine, "userClosedNotification", Qt::QueuedConnection, Q_ARG(uint, id)); + } else if (operationName() == "createNotification") { + int rv = m_engine->createNotification(parameters().value("appName").toString(), + parameters().value("appIcon").toString(), + parameters().value("summary").toString(), + parameters().value("body").toString(), + parameters().value("timeout").toInt(), + false, + QString() + ); + setResult(rv); + } else if (operationName() == "configureNotification") { + m_engine->configureNotification(parameters()["appRealName"].toString()); + } + + emitResult(); +} + +#include "notificationaction.moc" + diff --git a/plasma/generic/dataengines/notifications/notificationaction.h b/plasma/generic/dataengines/notifications/notificationaction.h new file mode 100644 index 00000000..cb084301 --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationaction.h @@ -0,0 +1,49 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NOTIFICATIONACTION_H +#define NOTIFICATIONACTION_H + +#include "notificationsengine.h" + +#include + +#include + +class NotificationAction : public Plasma::ServiceJob +{ + Q_OBJECT + + public: + NotificationAction(NotificationsEngine* engine, + const QString& destination, + const QString& operation, + QMap& parameters, + QObject* parent = 0) + : ServiceJob(destination, operation, parameters, parent), + m_engine(engine) + { + } + + void start(); + + private: + NotificationsEngine* m_engine; +}; + +#endif //NOTIFICATIONACTION_H diff --git a/plasma/generic/dataengines/notifications/notifications.operations b/plasma/generic/dataengines/notifications/notifications.operations new file mode 100644 index 00000000..93b7f0c5 --- /dev/null +++ b/plasma/generic/dataengines/notifications/notifications.operations @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/notifications/notificationsengine.cpp b/plasma/generic/dataengines/notifications/notificationsengine.cpp new file mode 100644 index 00000000..5294efac --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationsengine.cpp @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2008 Dmitry Suzdalev + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "notificationsengine.h" +#include "notificationservice.h" +#include "notificationsadaptor.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +NotificationsEngine::NotificationsEngine( QObject* parent, const QVariantList& args ) + : Plasma::DataEngine( parent, args ), m_nextId( 1 ) +{ + new NotificationsAdaptor(this); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerService( "org.freedesktop.Notifications" ); + dbus.registerObject( "/org/freedesktop/Notifications", this ); +} + +NotificationsEngine::~NotificationsEngine() +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.unregisterService( "org.freedesktop.Notifications" ); +} + +void NotificationsEngine::init() +{ +} + +inline void copyLineRGB32(QRgb* dst, const char* src, int width) +{ + const char* end = src + width * 3; + for (; src != end; ++dst, src+=3) { + *dst = qRgb(src[0], src[1], src[2]); + } +} + +inline void copyLineARGB32(QRgb* dst, const char* src, int width) +{ + const char* end = src + width * 4; + for (; src != end; ++dst, src+=4) { + *dst = qRgba(src[0], src[1], src[2], src[3]); + } +} + +static QImage decodeNotificationSpecImageHint(const QDBusArgument& arg) +{ + int width, height, rowStride, hasAlpha, bitsPerSample, channels; + QByteArray pixels; + char* ptr; + char* end; + + arg.beginStructure(); + arg >> width >> height >> rowStride >> hasAlpha >> bitsPerSample >> channels >> pixels; + arg.endStructure(); + //kDebug() << width << height << rowStride << hasAlpha << bitsPerSample << channels; + + #define SANITY_CHECK(condition) \ + if (!(condition)) { \ + kWarning() << "Sanity check failed on" << #condition; \ + return QImage(); \ + } + + SANITY_CHECK(width > 0); + SANITY_CHECK(width < 2048); + SANITY_CHECK(height > 0); + SANITY_CHECK(height < 2048); + SANITY_CHECK(rowStride > 0); + + #undef SANITY_CHECK + + QImage::Format format = QImage::Format_Invalid; + void (*fcn)(QRgb*, const char*, int) = 0; + if (bitsPerSample == 8) { + if (channels == 4) { + format = QImage::Format_ARGB32; + fcn = copyLineARGB32; + } else if (channels == 3) { + format = QImage::Format_RGB32; + fcn = copyLineRGB32; + } + } + if (format == QImage::Format_Invalid) { + kWarning() << "Unsupported image format (hasAlpha:" << hasAlpha << "bitsPerSample:" << bitsPerSample << "channels:" << channels << ")"; + return QImage(); + } + + QImage image(width, height, format); + ptr = pixels.data(); + end = ptr + pixels.length(); + for (int y=0; y end) { + kWarning() << "Image data is incomplete. y:" << y << "height:" << height; + break; + } + fcn((QRgb*)image.scanLine(y), ptr, width); + } + + return image; +} + +static QString findImageForSpecImagePath(const QString &_path) +{ + QString path = _path; + if (path.startsWith(QLatin1String("file:"))) { + KUrl url(path); + path = url.toLocalFile(); + } + return KIconLoader::global()->iconPath(path, -KIconLoader::SizeHuge, + true /* canReturnNull */); +} + +uint NotificationsEngine::Notify(const QString &app_name, uint replaces_id, + const QString &app_icon, const QString &summary, const QString &body, + const QStringList &actions, const QVariantMap &hints, int timeout) +{ + uint id = 0; + id = replaces_id ? replaces_id : m_nextId++; + + QString appname_str = app_name; + if (appname_str.isEmpty()) { + appname_str = i18n("Unknown Application"); + } + + if (timeout == -1) { + const int AVERAGE_WORD_LENGTH = 6; + const int WORD_PER_MINUTE = 250; + int count = summary.length() + body.length(); + timeout = 60000 * count / AVERAGE_WORD_LENGTH / WORD_PER_MINUTE; + + // Add two seconds for the user to notice the notification, and ensure + // it last at least five seconds, otherwise all the user see is a + // flash + timeout = 2000 + qMax(timeout, 3000); + } + + const QString source = QString("notification %1").arg(id); + if (replaces_id) { + Plasma::DataContainer *container = containerForSource(source); + if (container && container->data()["expireTimeout"].toInt() != timeout) { + int timerId = m_sourceTimers.value(source); + killTimer(timerId); + m_sourceTimers.remove(source); + m_timeouts.remove(timerId); + } + } + + Plasma::DataEngine::Data notificationData; + notificationData.insert("id", QString::number(id)); + notificationData.insert("appName", appname_str); + notificationData.insert("appIcon", app_icon); + notificationData.insert("summary", summary); + notificationData.insert("body", body); + notificationData.insert("actions", actions); + notificationData.insert("expireTimeout", timeout); + + QString appRealName; + bool configurable = false; + if (hints.contains("x-kde-appname")) { + appRealName = hints["x-kde-appname"].toString(); + configurable = true; + } + notificationData.insert("appRealName", appRealName); + notificationData.insert("configurable", configurable); + + QImage image; + if (hints.contains("image_data")) { + QDBusArgument arg = hints["image_data"].value(); + image = decodeNotificationSpecImageHint(arg); + } else if (hints.contains("image_path")) { + QString path = findImageForSpecImagePath(hints["image_path"].toString()); + if (!path.isEmpty()) { + image.load(path); + } + } else if (hints.contains("icon_data")) { + // This hint was in use in version 1.0 of the spec but has been + // replaced by "image_data" in version 1.1. We need to support it for + // users of the 1.0 version of the spec. + QDBusArgument arg = hints["icon_data"].value(); + image = decodeNotificationSpecImageHint(arg); + } + notificationData.insert("image", image); + + if (hints.contains("urgency")) { + notificationData.insert("urgency", hints["urgency"].toInt()); + } + + setData(source, notificationData); + + if (timeout) { + int timerId = startTimer(timeout); + m_sourceTimers.insert(source, timerId); + m_timeouts.insert(timerId, source); + } + + return id; +} + +void NotificationsEngine::timerEvent(QTimerEvent *event) +{ + const QString source = m_timeouts.value(event->timerId()); + if (!source.isEmpty()) { + killTimer(event->timerId()); + m_sourceTimers.remove(source); + m_timeouts.remove(event->timerId()); + removeSource(source); + emit NotificationClosed(source.split(" ").last().toInt(), 1); + return; + } + + Plasma::DataEngine::timerEvent(event); +} + +void NotificationsEngine::CloseNotification(uint id) +{ + removeSource(QString("notification %1").arg(id)); + emit NotificationClosed(id, 3); +} + +void NotificationsEngine::userClosedNotification(uint id) +{ + removeSource(QString("notification %1").arg(id)); + emit NotificationClosed(id, 2); +} + +Plasma::Service* NotificationsEngine::serviceForSource(const QString& source) +{ + return new NotificationService(this, source); +} + +QStringList NotificationsEngine::GetCapabilities() +{ + return QStringList() + << "body" + << "body-hyperlinks" + << "body-markup" + << "icon-static" + << "actions" + ; +} + +// FIXME: Signature is ugly +QString NotificationsEngine::GetServerInformation(QString& vendor, QString& version, QString& specVersion) +{ + vendor = "KDE"; + version = "1.0"; // FIXME + specVersion = "1.1"; + return "Plasma"; +} + +int NotificationsEngine::createNotification(const QString &appName, const QString &appIcon, const QString &summary, const QString &body, int timeout, bool configurable, const QString &appRealName) +{ + const QString source = QString("notification %1").arg(++m_nextId); + Plasma::DataEngine::Data notificationData; + notificationData.insert("id", QString::number(m_nextId)); + notificationData.insert("appName", appName); + notificationData.insert("appIcon", appIcon); + notificationData.insert("summary", summary); + notificationData.insert("body", body); + notificationData.insert("expireTimeout", timeout); + notificationData.insert("configurable", configurable); + notificationData.insert("appRealName", appRealName); + + setData(source, notificationData); + return m_nextId; +} + +void NotificationsEngine::configureNotification(const QString &appName) +{ + KNotifyConfigWidget::configure(0, appName); +} + +K_EXPORT_PLASMA_DATAENGINE(notifications, NotificationsEngine) + +#include "notificationsengine.moc" diff --git a/plasma/generic/dataengines/notifications/notificationsengine.h b/plasma/generic/dataengines/notifications/notificationsengine.h new file mode 100644 index 00000000..34d12add --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationsengine.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008 Dmitry Suzdalev + * + * This program is free software you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#ifndef NOTIFICATIONSENGINE_H +#define NOTIFICATIONSENGINE_H + +#include + +class QTimer; + +/** + * Engine which provides data sources for notifications. + * Each notification is represented by one source. + */ +class NotificationsEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + NotificationsEngine( QObject* parent, const QVariantList& args ); + ~NotificationsEngine(); + + virtual void init(); + + /** + * This function implements part of Notifications DBus interface. + * Once called, will add notification source to the engine + */ + uint Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantMap &hints, int timeout); + + void CloseNotification( uint id ); + + Plasma::Service* serviceForSource(const QString& source); + + QStringList GetCapabilities(); + + QString GetServerInformation(QString& vendor, QString& version, QString& specVersion); + + int createNotification(const QString &appName, const QString &appIcon, const QString &summary, const QString &body, int timeout, bool configurable, const QString &appRealName); + + void configureNotification(const QString &appName); + +public Q_SLOTS: + void userClosedNotification(uint id); + +signals: + void NotificationClosed( uint id, uint reason ); + void ActionInvoked( uint id, const QString& actionKey ); + +protected: + void timerEvent(QTimerEvent *event); + +private: + /** + * Holds the id that will be assigned to the next notification source + * that will be created + */ + uint m_nextId; + QHash m_timeouts; // timerIDs -> sources + QHash m_sourceTimers; // sources -> timerIDs + + friend class NotificationAction; +}; + +#endif diff --git a/plasma/generic/dataengines/notifications/notificationservice.cpp b/plasma/generic/dataengines/notifications/notificationservice.cpp new file mode 100644 index 00000000..b729da98 --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationservice.cpp @@ -0,0 +1,38 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "notificationservice.h" +#include "notificationaction.h" +#include "notificationsengine.h" + +NotificationService::NotificationService(NotificationsEngine* parent, const QString& source) + : Plasma::Service(parent), + m_notificationEngine(parent) +{ + setName("notifications"); + setDestination(source); +} + +Plasma::ServiceJob* NotificationService::createJob(const QString& operation, + QMap& parameters) +{ + return new NotificationAction(m_notificationEngine, destination(), operation, parameters, this); +} + +#include "notificationservice.moc" + diff --git a/plasma/generic/dataengines/notifications/notificationservice.h b/plasma/generic/dataengines/notifications/notificationservice.h new file mode 100644 index 00000000..d8f5b01f --- /dev/null +++ b/plasma/generic/dataengines/notifications/notificationservice.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NOTIFICATIONSERVICE_H +#define NOTIFICATIONSERVICE_H + +#include + +class NotificationsEngine; + +class NotificationService : public Plasma::Service +{ + Q_OBJECT + + public: + NotificationService(NotificationsEngine* parent, const QString& source); + + protected: + Plasma::ServiceJob* createJob(const QString& operation, + QMap& parameters); + + private: + NotificationsEngine* m_notificationEngine; + +}; + +#endif // NOTIFICATIONSERVICE_H diff --git a/plasma/generic/dataengines/notifications/org.freedesktop.Notifications.xml b/plasma/generic/dataengines/notifications/org.freedesktop.Notifications.xml new file mode 100644 index 00000000..8ddb421c --- /dev/null +++ b/plasma/generic/dataengines/notifications/org.freedesktop.Notifications.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/notifications/plasma-dataengine-notifications.desktop b/plasma/generic/dataengines/notifications/plasma-dataengine-notifications.desktop new file mode 100644 index 00000000..326db505 --- /dev/null +++ b/plasma/generic/dataengines/notifications/plasma-dataengine-notifications.desktop @@ -0,0 +1,150 @@ +[Desktop Entry] +Name=Application Notifications +Name[ar]=تنبيهات التطبيقات +Name[ast]=Notificaciones d'aplicaciones +Name[be@latin]=Infarmavańni aplikacyj +Name[bg]=Програмни съобщения +Name[bn]=অ্যাপলিকেশন বিজ্ঞপ্তি +Name[bn_IN]=অ্যাপ্লিকেশনের সূচনাবার্তা +Name[bs]=obavještenja programa +Name[ca]=Notificacions de les aplicacions +Name[ca@valencia]=Notificacions de les aplicacions +Name[cs]=Oznamování aplikací +Name[csb]=Dôwanié wiédzë ò aplikacëjach +Name[da]=Programbekendtgørelser +Name[de]=Anwendungs-Benachrichtigungen +Name[el]=Ειδοποιήσεις εφαρμογών +Name[en_GB]=Application Notifications +Name[eo]=Aplikaĵaj Atentigoj +Name[es]=Notificaciones de aplicaciones +Name[et]=Rakenduste märguanded +Name[eu]=Aplikazioen jakinarazpenak +Name[fi]=Sovellusilmoitukset +Name[fr]=Notifications des applications +Name[fy]=Applikaasje ntifikaasjes +Name[ga]=Fógairtí Feidhmchláir +Name[gl]=Notificacións dos programas +Name[gu]=કાર્યક્રમ નોંધણીઓ +Name[he]=הודעות יישומים +Name[hi]=अनुप्रयोग सूचनाएँ +Name[hne]=अनुपरयोग सूचना +Name[hr]=Obavijesti aplikacija +Name[hu]=Értesítő üzenetek +Name[ia]=Notificationes de application +Name[id]=Notifikasi Aplikasi +Name[is]=Tilkynningar forrita +Name[it]=Notifiche delle applicazioni +Name[ja]=アプリケーションの通知 +Name[kk]=Қолданба құлақтандырулары +Name[km]=ការ​ជូនដំណឹង​កម្មវិធី​ +Name[kn]=ಅನ್ವಯ ಸೂಚನೆಗಳು +Name[ko]=프로그램 알림 +Name[ku]=Hişyariyên Sepanê +Name[lt]=Programų pranešimai +Name[lv]=Programmu paziņojumi +Name[mk]=Известувања за апликации +Name[ml]=പ്രയോഗ അറിയിപ്പുകള്‍ +Name[mr]=अनुप्रयोग सूचना +Name[nb]=Programvarslinger +Name[nds]=Programm-Bescheden +Name[nl]=Programmameldingen +Name[nn]=Programvarsel +Name[or]=ପ୍ରୟୋଗ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienia programów +Name[pt]=Notificações das Aplicações +Name[pt_BR]=Notificações do aplicativo +Name[ro]=Notificări aplicații +Name[ru]=Уведомления приложений +Name[si]=යෙදුම් දැනුම් දීම් +Name[sk]=Upozornenia aplikácií +Name[sl]=Obvestila programov +Name[sr]=обавештења програма +Name[sr@ijekavian]=обавјештења програма +Name[sr@ijekavianlatin]=obavještenja programa +Name[sr@latin]=obaveštenja programa +Name[sv]=Programunderrättelser +Name[ta]=அமைப்பு குறிப்பகள் +Name[tg]=Огоҳномаҳои система +Name[th]=การแจ้งให้ทราบของโปรแกรม +Name[tr]=Uygulama Bildirimleri +Name[ug]=پروگرامما ئۇقتۇرۇشى +Name[uk]=Сповіщення програм +Name[vi]=Thông báo cho ứng dụng +Name[wa]=Notifiaedjes do programe +Name[x-test]=xxApplication Notificationsxx +Name[zh_CN]=应用程序通知 +Name[zh_TW]=應用程式通知 +Comment=Passive visual notifications for the user. +Comment[ar]=إشعارات مرئية غير متفاعلة للمستخدم +Comment[ast]=Notificaciones visuales pasives pal usuariu. +Comment[bg]=Пасивни визуални съобщения за потребителя. +Comment[bs]=Pasivna vizuelna obavještenja za korisnika. +Comment[ca]=Notificacions visuals passives per a l'usuari. +Comment[ca@valencia]=Notificacions visuals passives per a l'usuari. +Comment[cs]=Pasivní vizuální upozornění pro uživatele. +Comment[da]=Passive visuelle bekendtgørelser til brugeren. +Comment[de]=Passive sichtbare Benachrichtigungen für den Anwender. +Comment[el]=Παθητικές οπτικές ειδοποιήσεις για το χρήστη. +Comment[en_GB]=Passive visual notifications for the user. +Comment[es]=Notificaciones visuales pasivas para el usuario. +Comment[et]=Passiivsed visuaalsed märguanded kasutajale. +Comment[eu]=Erabiltzailearentzako ikusizko jakinarazpen pasiboak. +Comment[fi]=Passiivinen visuaali-ilmoitus käyttäjälle. +Comment[fr]=Notifications visuelles passives pour l'utilisateur +Comment[fy]=Pasive fisuele notifikaasje foar de brûker. +Comment[gl]=Notificacións visuais pasivas para o usuario. +Comment[he]=הודעות ויזאוליות פאסיביות עבור המשתמש. +Comment[hr]=Pasivne vizualne obavijesti korisniku. +Comment[hu]=Passzív értesítő üzeneteket tud küldeni a felhasználónak. +Comment[ia]=Notificationes visual passive pro le usator. +Comment[id]=Notifikasi visual pasif untuk pengguna. +Comment[is]=Hlutlausar sjónrænar tilkynningar til notandans. +Comment[it]=Notifiche visuali passive per l'utente. +Comment[ja]=ユーザ用の受動的ビジュアル通知 +Comment[kk]=Үнсіз көрсетілетін құлақтандыру. +Comment[km]=ការ​ជូនដំណឹង​ដែល​មើល​សម្រាប់​អ្នកប្រើ ។ +Comment[kn]=ಬಳಕೆದಾರನ ನಿಷ್ಕ್ರಿಯವಾಗಿರುವ ದೃಶ್ಯ ಸೂಚನೆಗಳು. +Comment[ko]=사용자에게 보이는 수동적인 알림입니다. +Comment[lt]=Pasyvūs vizualūs pranešimai naudotojui. +Comment[lv]=Pasīvi vizuālie paziņojumi lietotājam. +Comment[mk]=Пасивни визуелни известувања за корисникот. +Comment[ml]=ഉപയോക്താവിനുള്ള നടപടി വേണ്ടാത്ത ദൃശ്യ സൂചനകള്‍ +Comment[mr]=वापरकर्त्यासाठी दर्शनीय सूचना. +Comment[nb]=Passive visuelle varslinger for brukeren. +Comment[nds]=Passiev sichtbor Bescheden för den Bruker +Comment[nl]=Passieve visuele meldingen voor de gebruiker. +Comment[nn]=Passive visuelle varsel for brukaren. +Comment[pa]=ਯੂਜ਼ਰ ਲਈ ਪੈਸਿਵ ਦਿੱਖ ਨੋਟੀਫਿਕੇਸ਼ਨ। +Comment[pl]=Bierne, graficzne powiadomienia dla użytkownika. +Comment[pt]=Notificações passivas visuais para o utilizador. +Comment[pt_BR]=Notificações visuais passivas para o usuário. +Comment[ro]=Notificări vizuale pasive pentru utilizator. +Comment[ru]=Пассивные визуальные уведомления для пользователя. +Comment[si]=පරිශීලකයන් සඳහා නිශ්ක්‍රීය දෘශ්‍ය දැන්වීම්. +Comment[sk]=Pasívne vizuálne upozornenia pre užívateľa. +Comment[sl]=Pasivna vidna obvestila za uporabnika. +Comment[sr]=Пасивна визуелна обавештења за корисника. +Comment[sr@ijekavian]=Пасивна визуелна обавјештења за корисника. +Comment[sr@ijekavianlatin]=Pasivna vizuelna obavještenja za korisnika. +Comment[sr@latin]=Pasivna vizuelna obaveštenja za korisnika. +Comment[sv]=Passiva visuella underrättelser för användaren. +Comment[th]=ระบบการแจ้งให้ผู้ใช้งานทราบถึงเหตุการณ์ต่าง ๆ +Comment[tr]=Kullanıcı için pasif görsel bildirimler. +Comment[ug]=ئىشلەتكۈچىگە پاسسىپ كۆرۈنىدىغان كۆرۈش ئۈنۈم ئۇقتۇرۇشىنى تەمىنلەيدۇ +Comment[uk]=Пасивні візуальні сповіщення для користувача. +Comment[wa]=Notifiaedjes doirmants veyåves po l' uzeu. +Comment[x-test]=xxPassive visual notifications for the user.xx +Comment[zh_CN]=为用户提供被动出现的视觉通知。 +Comment[zh_TW]=給使用者的被動視覺通知。 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=preferences-desktop-notification +X-KDE-Library=plasma_engine_notifications + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=notifications +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= diff --git a/plasma/generic/dataengines/nowplaying/CMakeLists.txt b/plasma/generic/dataengines/nowplaying/CMakeLists.txt new file mode 100644 index 00000000..6e1b8c57 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/CMakeLists.txt @@ -0,0 +1,56 @@ +project(plasma-dataengine-nowplaying) + +set(nowplaying_engine_SRCS + nowplayingengine.cpp + playercontrol.cpp + playeractionjob.cpp + playercontainer.cpp + playerinterface/player.cpp + playerinterface/playerfactory.cpp + playerinterface/dbuswatcher.cpp + playerinterface/pollingwatcher.cpp + playerinterface/juk.cpp + playerinterface/mpris/mpris.cpp + playerinterface/mpris/mprisdbustypes.cpp + playerinterface/mpris2/mpris2.cpp +) + +qt4_add_dbus_interface(nowplaying_engine_SRCS playerinterface/org.kde.juk.player.xml juk_interface) + +set(mpris_player_desc playerinterface/mpris/org.freedesktop.MediaPlayer.player.xml) +set_source_files_properties(${mpris_player_desc} PROPERTIES + NO_NAMESPACE true + INCLUDE "playerinterface/mpris/mprisdbustypes.h" + CLASSNAME MprisPlayer +) +qt4_add_dbus_interface(nowplaying_engine_SRCS ${mpris_player_desc} mprisplayer) + +if(GLIB2_FOUND) + macro_optional_find_package(Xmms) + set_package_properties(Xmms PROPERTIES DESCRIPTION "X MultiMedia System development libraries" + URL "http://www.xmms.org" + TYPE OPTIONAL + PURPOSE "Support for XMMS in the Now Playing data engine" + ) + if(XMMS_FOUND) + include_directories(${XMMS_INCLUDE_DIRS}) + include_directories(${GLIB2_INCLUDE_DIR}) + set(nowplaying_engine_SRCS ${nowplaying_engine_SRCS} playerinterface/xmms.cpp) + message(STATUS "Found XMMS: the nowplaying dataengine will support XMMS 1.x") + else(XMMS_FOUND) + message(STATUS "Could NOT find XMMS: the nowplaying dataengine will NOT support XMMS 1.x") + endif(XMMS_FOUND) +endif(GLIB2_FOUND) + +configure_file(config-nowplaying.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-nowplaying.h) + +kde4_add_plugin(plasma_engine_nowplaying ${nowplaying_engine_SRCS}) +target_link_libraries(plasma_engine_nowplaying ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS} ${QT_QTGUI_LIBRARY}) +if(XMMS_FOUND) + target_link_libraries(plasma_engine_nowplaying ${XMMS_LDFLAGS}) +endif(XMMS_FOUND) + +install(TARGETS plasma_engine_nowplaying DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-nowplaying.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES nowplaying.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/nowplaying/Messages.sh b/plasma/generic/dataengines/nowplaying/Messages.sh new file mode 100755 index 00000000..eaac8ef0 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_nowplaying.pot diff --git a/plasma/generic/dataengines/nowplaying/TODO b/plasma/generic/dataengines/nowplaying/TODO new file mode 100644 index 00000000..557902f1 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/TODO @@ -0,0 +1,9 @@ +- add plugin support + - make juk, xmms support plugins +- MPD support +- support players in Kelly's spreadsheet (see panel-devel list) +- VLC pre-DBus support? See /usr/include/vlc/mediacontrol.h +- find a player that exports album artwork, and test +- separate the watchers and plugin bits into a library? +- unify the watchers? +- finish service support diff --git a/plasma/generic/dataengines/nowplaying/config-nowplaying.cmake b/plasma/generic/dataengines/nowplaying/config-nowplaying.cmake new file mode 100644 index 00000000..c5960660 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/config-nowplaying.cmake @@ -0,0 +1 @@ +#cmakedefine XMMS_FOUND diff --git a/plasma/generic/dataengines/nowplaying/nowplaying.operations b/plasma/generic/dataengines/nowplaying/nowplaying.operations new file mode 100644 index 00000000..4a5587d0 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/nowplaying.operations @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/nowplaying/nowplayingengine.cpp b/plasma/generic/dataengines/nowplaying/nowplayingengine.cpp new file mode 100644 index 00000000..620dcb0d --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/nowplayingengine.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "nowplayingengine.h" + +#include + +#include + +#include +#include + +#include "playerinterface/player.h" +#include "playerinterface/playerfactory.h" +#include "playerinterface/dbuswatcher.h" +#include "playerinterface/pollingwatcher.h" +#include "playerinterface/mpris/mpris.h" +#include "playerinterface/mpris2/mpris2.h" +#include "playerinterface/juk.h" +#ifdef XMMS_FOUND +#include "playerinterface/xmms.h" +#endif // XMMS_FOUND + +#include "playercontrol.h" +#include "playercontainer.h" + +NowPlayingEngine::NowPlayingEngine(QObject* parent, + const QVariantList& args) + : Plasma::DataEngine(parent), + dbusWatcher(new DBusWatcher(this)), + pollingWatcher(0) +{ + Q_UNUSED(args) + + setData("players", QStringList()); + + kWarning() << "The \"nowplaying\" engine is deprecated; use the \"mpris2\" engine instead"; + + connect(dbusWatcher, SIGNAL(newPlayer(Player::Ptr)), + this, SLOT(addPlayer(Player::Ptr))); + connect(dbusWatcher, SIGNAL(playerDisappeared(Player::Ptr)), + this, SLOT(removePlayer(Player::Ptr))); + + dbusWatcher->addFactory(new Mpris2Factory(dbusWatcher)); + dbusWatcher->addFactory(new MprisFactory(dbusWatcher)); + dbusWatcher->addFactory(new JukFactory(dbusWatcher)); + +#ifdef XMMS_FOUND + pollingWatcher = new PollingWatcher(this); + connect(pollingWatcher, SIGNAL(newPlayer(Player::Ptr)), + this, SLOT(addPlayer(Player::Ptr))); + connect(pollingWatcher, SIGNAL(playerDisappeared(Player::Ptr)), + this, SLOT(removePlayer(Player::Ptr))); + pollingWatcher->addFactory(new XmmsFactory(pollingWatcher)); +#endif +} + +Plasma::Service* NowPlayingEngine::serviceForSource(const QString& source) +{ + PlayerContainer* container = qobject_cast(containerForSource(source)); + if (container) { + return container->service(this); + } else { + return DataEngine::serviceForSource(source); + } +} + + +bool NowPlayingEngine::sourceRequestEvent(const QString& source) +{ + kDebug() << "Source" << source << "was requested"; + if (source == "help") { + setData(source, "Use 'players' to get a list of players.\n" + "Use 'properties' to get a list of all properties that may be returned." + ); + return true; + } else if (source == "properties") { + setData(source, "State", "QString - playing|paused|stopped"); + setData(source, "Artist", "QString - the artist metadata for the\n" + " current track, if available"); + setData(source, "Album", "QString - the album metadata for the\n" + " current track, if available"); + setData(source, "Title", "QString - the title metadata for the\n" + " current track, if available"); + setData(source, "Track number", "int - the album/collection track number\n" + " (eg: on a CD) if known, 0 otherwise"); + setData(source, "Comment", "QString - the comment metadata for the\n" + " current track, if available"); + setData(source, "Genre", "QString - the comment metadata for the\n" + " current track, if available"); + setData(source, "Length", "int - the length of the current track\n" + " in seconds, 0 if unknown"); + setData(source, "Position", "int - the position of the current track\n" + " in seconds, 0 if unknown"); + setData(source, "Volume", "float - the volume, given as a float\n" + " between 0 and 1, or -1 if unknown"); + setData(source, "Artwork", "QPixmap - the album artwork, if available"); + setData(source, "Lyrics", "QString - song lyrics, if available"); + return true; + } + + return false; +} + +void NowPlayingEngine::addPlayer(Player::Ptr player) +{ + kDebug() << "Adding player" << player->name(); + Plasma::DataContainer *container = containerForSource("players"); + QStringList players; + if (container) { + players = container->data()["players"].toStringList(); + } + + players << player->name(); + setData("players", players); + + addSource(new PlayerContainer(player, this)); +} + +void NowPlayingEngine::removePlayer(Player::Ptr player) +{ + kDebug() << "Player" << player->name() << "disappeared"; + Plasma::DataContainer *container = containerForSource("players"); + if (container) { + QStringList players = container->data()["players"].toStringList(); + players.removeAll(player->name()); + setData("players", players); + } + + removeSource(player->name()); +} + +#include "nowplayingengine.moc" diff --git a/plasma/generic/dataengines/nowplaying/nowplayingengine.h b/plasma/generic/dataengines/nowplaying/nowplayingengine.h new file mode 100644 index 00000000..e525b0ae --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/nowplayingengine.h @@ -0,0 +1,59 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NOWPLAYINGENGINE_H +#define NOWPLAYINGENGINE_H + +#include + +#include +#include + +#include "playerinterface/player.h" + +class DBusWatcher; +class PollingWatcher; + +/** + * The Now Playing data engine. + * + * Use plasmaengineexplorer and request the "help" source for more info. + */ +class NowPlayingEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + NowPlayingEngine(QObject* parent, const QVariantList& args); + Plasma::Service* serviceForSource(const QString& source); + +protected: + bool sourceRequestEvent(const QString &source); + +private slots: + void addPlayer(Player::Ptr player); + void removePlayer(Player::Ptr player); + +private: + DBusWatcher* dbusWatcher; + PollingWatcher* pollingWatcher; +}; + +K_EXPORT_PLASMA_DATAENGINE(nowplaying, NowPlayingEngine) + +#endif // NOWPLAYINGENGINE_H diff --git a/plasma/generic/dataengines/nowplaying/plasma-dataengine-nowplaying.desktop b/plasma/generic/dataengines/nowplaying/plasma-dataengine-nowplaying.desktop new file mode 100644 index 00000000..e654732f --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/plasma-dataengine-nowplaying.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +Name=Now Playing +Name[ar]=المشغلة حالياً +Name[ast]=Reproduciendo +Name[be@latin]=Ciapier hraje +Name[bg]=В момента се слуша +Name[bn]=এখন চলছে +Name[bn_IN]=বর্তমানে চলমান +Name[bs]=trenutna svirka +Name[ca]=Ara està en reproducció +Name[ca@valencia]=Ara està en reproducció +Name[cs]=Nyní přehrávám +Name[csb]=Terô grajë +Name[da]=Afspiller nu +Name[de]=Musiktitel-Anzeige +Name[el]=Αναπαράγεται τώρα +Name[en_GB]=Now Playing +Name[eo]=Nun legas +Name[es]=Reproduciendo +Name[et]=Praegu mängitakse +Name[eu]=Orain jotzen +Name[fa]=اکنون در حال پخش است +Name[fi]=Nyt soi +Name[fr]=En cours de lecture +Name[fy]=Spilet ôf +Name[ga]=Á Sheinm Anois +Name[gl]=Estase a reproducir +Name[gu]=અત્યારે વગાડે છે +Name[he]=מתנגן עכשיו +Name[hi]=अभी बजाया जा रहा है +Name[hne]=अभी बजावत हे +Name[hr]=Trenutno svira +Name[hu]=Most ezt hallgatom +Name[ia]=Ora il reproduce +Name[id]=Saat Ini Diputar +Name[is]=Nú í spilun +Name[ja]=今聴いているもの +Name[kk]=Қазір орындалуда +Name[km]=ឥឡូវ​កំពុង​ចាក់ +Name[kn]=ಪ್ರಸ್ತತ ನಿರೂಪಣೆ +Name[ko]=지금 재생 중 +Name[ku]=Niha lêdêde +Name[lt]=Dabar grojama +Name[lv]=Šobrīd atskaņo +Name[mai]=आब बाजि रहल अछि +Name[mk]=Сега е пуштено +Name[ml]=ഇപ്പോള്‍ പാടുന്നതു് +Name[mr]=आता चालवीत आहे +Name[nb]=Spiller nå +Name[nds]=Lopen Stück +Name[nl]=Speelt nu +Name[nn]=Spelar no +Name[or]=ବର୍ତ୍ତମାନ ଚାଲୁଅଛି +Name[pa]=ਹੁਣ ਚੱਲਦਾ +Name[pl]=Teraz odtwarzany +Name[pt]=Agora a Tocar +Name[pt_BR]=Reproduzindo agora +Name[ro]=În redare +Name[ru]=Сейчас проигрывается +Name[si]=දැන් වාදනය වන්නේ +Name[sk]=Teraz hrá +Name[sl]=Trenutno se predvaja +Name[sr]=тренутна свирка +Name[sr@ijekavian]=тренутна свирка +Name[sr@ijekavianlatin]=trenutna svirka +Name[sr@latin]=trenutna svirka +Name[sv]=Spelar nu +Name[ta]=Now Playing +Name[tg]=Музыка воспроизводимая в данный момент +Name[th]=กำลังเล่นอยู่ +Name[tr]=Şimdi Dinleniyor +Name[ug]=قويۇۋاتىدۇ +Name[uk]=Зараз відтворюється +Name[wa]=Djouwé asteure +Name[x-test]=xxNow Playingxx +Name[zh_CN]=正在收听 +Name[zh_TW]=現正播放 + +Comment=Lists currently playing music +Comment[ar]=تسرد الموسيقى المشغلة حالياً +Comment[ast]=Amuesa la música que ta sonando +Comment[be@latin]=Pakazvaje muzyku, jakuju ciapier hraje systema +Comment[bg]=Списък на текущо възпроизвежданата музика +Comment[bs]=Pokazuje koja muzika trenutno svira +Comment[ca]=Llista la música que s'està reproduint actualment +Comment[ca@valencia]=Llista la música que s'està reproduint actualment +Comment[cs]=Vypíše aktuálně přehrávanou hudbu +Comment[da]=Lister musik som aktuelt afspilles +Comment[de]=Listet die derzeit laufenden Titel auf +Comment[el]=Εμφάνιση της μουσικής που αναπαράγεται αυτήν τη στιγμή +Comment[en_GB]=Lists currently playing music +Comment[eo]=Listigas la nunan muzikon +Comment[es]=Muestra la música que está sonando +Comment[et]=Näitab parajasti esitatavat muusikat +Comment[eu]=Une honetan jotzen ari den musika zerrendatzen du +Comment[fi]=Luettelee parhaillaan soitettavan musiikin +Comment[fr]=Liste les musiques en cours d'écoute +Comment[fy]=Lit de track sjen dy no ôfspile wurdt +Comment[ga]=Taispeánann sé an ceol atá ag seinm faoi láthair +Comment[gl]=Lista a música que está a tocar +Comment[gu]=વાગતું સંગીત દર્શાવે છે +Comment[he]=משמש להצגת המוזיקה המתנגנת כעת +Comment[hi]=मौज़ूदा बज रहे संगीत की सूची +Comment[hne]=अभी जउन संगीत बजत हे वो सूची +Comment[hr]=Prikaz glazbe koja trenutno svira +Comment[hu]=Kiírja a lejátszott számok jellemzőit +Comment[ia]=Il lista le music currentemente reproducite +Comment[id]=Senarai musik yang dimainkan saat ini +Comment[is]=Telur upp hvaða tónlist er verið að spila +Comment[ja]=今聴いているものを表示します +Comment[kk]=Қазір орындалып жатқан әуендер тізімі +Comment[km]=រាយ​តន្ដ្រី​ដែល​កពុង​ចាក់ +Comment[kn]=ಪ್ರಸ್ತುತದಲ್ಲಿ ನಿರೂಪಣೆಯಾಗುತ್ತಿರುವ ಸಂಗೀತವನ್ನು ಪಟ್ಟಿಮಾಡುತ್ತದೆ +Comment[ko]=현재 재생 중인 음악 표시하기 +Comment[lt]=Pateikia dabar grojamos muzikos pavadinimą +Comment[lv]=Parāda pašlaik atskaņoto mūziku +Comment[mk]=Приказ на тековната музика +Comment[ml]=ഇപ്പോള്‍ പാടുന്ന പാട്ടു് കാണിക്കുന്നു. +Comment[mr]=वर्तमानात चालविले जाणाऱ्या संगीताची यादी करतो +Comment[nb]=Vis hvilken musikk som spilles nå +Comment[nds]=Wiest opstunns afspeelt Musik +Comment[nl]=Toont de track die momenteel wordt afgespeeld +Comment[nn]=Oversikt over musikken som vert spela +Comment[pa]=ਇਸ ਸਮੇਂ ਚੱਲਦਾ ਸੰਗੀਤ ਇੰਜਣ +Comment[pl]=Pokazuje obecnie odtwarzany utwór +Comment[pt]=Apresenta a música actualmente em reprodução +Comment[pt_BR]=Lista a música atualmente em reprodução +Comment[ro]=Afișează muzicaaa în curs de redare +Comment[ru]=Звучащее сейчас произведение +Comment[si]=දැන් වාදනය වන සංගීතය දක්වයි +Comment[sk]=Zobrazí aktuálne prehrávanú hudbu +Comment[sl]=Poda skladbo, ki se trenutno predvaja +Comment[sr]=Показује која музика тренутно свира +Comment[sr@ijekavian]=Показује која музика тренутно свира +Comment[sr@ijekavianlatin]=Pokazuje koja muzika trenutno svira +Comment[sr@latin]=Pokazuje koja muzika trenutno svira +Comment[sv]=Listar musik som för närvarande spelas +Comment[ta]=Lists currently playing music +Comment[te]=ప్రస్తుతం ప్లేచేస్తున్న మ్యూజిక్‌ను జాబితాచేస్తోంది +Comment[tg]=Сообщает о воспроизводимой музыке +Comment[th]=เรียกรายการดนตรีที่กำลังเล่นอยู่ในปัจจุบัน +Comment[tr]=O anda dinlenen müziği listeler +Comment[ug]=نۆۋەتتە قويۇلۇۋاتقان نەغمە تىزىمىنى كۆرسىتىدۇ +Comment[uk]=Показує список музики, що відтворюється +Comment[vi]=Liệt kê bài hát hiện đang phát +Comment[wa]=Fwait l' djivêye del muzike djouwêye pol moumint +Comment[x-test]=xxLists currently playing musicxx +Comment[zh_CN]=列出当前正在播放的音乐 +Comment[zh_TW]=列出目前播放的音樂 + +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=applications-multimedia +X-KDE-Library=plasma_engine_nowplaying +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=nowplaying +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License= + diff --git a/plasma/generic/dataengines/nowplaying/playeractionjob.cpp b/plasma/generic/dataengines/nowplaying/playeractionjob.cpp new file mode 100644 index 00000000..0aa1c25d --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playeractionjob.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playeractionjob.h" + +#include + +void PlayerActionJob::start() +{ + kDebug() << "Trying to perform the action" << operationName(); + if (!m_player) { + setErrorText(i18n("The player '%1' cannot be found.", destination())); + setError(-1); + emitResult(); + return; + } + + const QString operation(operationName()); + if (operation == "play") { + if (m_player->canPlay()) { + m_player->play(); + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'play'.", m_player->name())); + setError(-1); + } + } else if (operation == "pause") { + if (m_player->canPause()) { + m_player->pause(); + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'pause'.", m_player->name())); + setError(-1); + } + } else if (operation == "stop") { + if (m_player->canStop()) { + m_player->stop(); + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'stop'.", m_player->name())); + setError(-1); + } + } else if (operation == "previous") { + if (m_player->canGoPrevious()) { + m_player->previous(); + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'previous'.", m_player->name())); + setError(-1); + } + } else if (operation == "next") { + if (m_player->canGoNext()) { + m_player->next(); + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'next'.", m_player->name())); + setError(-1); + } + } else if (operation == "volume") { + if (m_player->canSetVolume()) { + if (parameters().contains("level")) { + qreal volume = parameters()["level"].toDouble(); + if (volume >= 0.0 && volume <= 1.0) { + m_player->setVolume(volume); + } else { + setErrorText(i18n("The 'level' argument to the 'volume' command must be between 0 and 1.")); + setError(-2); + } + } else { + setErrorText(i18n("The 'volume' command requires a 'level' argument.")); + setError(-2); + } + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'volume'.", m_player->name())); + setError(-1); + } + } else if (operation == "seek") { + if (m_player->canSeek()) { + if (parameters().contains("seconds")) { + qreal time = parameters()["seconds"].toInt(); + if (time >= 0 && time <= m_player->length()) { + m_player->seek(time); + } else { + setErrorText(i18n("The 'seconds' argument to the 'seek' command must be " + "between 0 and the length of the track.")); + setError(-2); + } + } else { + setErrorText(i18n("The 'seek' command requires a 'seconds' argument.")); + setError(-2); + } + } else { + setErrorText(i18n("The player '%1' cannot perform the action 'seek'.", m_player->name())); + setError(-1); + } + } + if (error()) { + kDebug() << "Failed with error" << errorText(); + } + emitResult(); +} + +#include "playeractionjob.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/nowplaying/playeractionjob.h b/plasma/generic/dataengines/nowplaying/playeractionjob.h new file mode 100644 index 00000000..2ff24e2b --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playeractionjob.h @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERACTIONJOB_H +#define PLAYERACTIONJOB_H + +#include +#include +#include "playerinterface/player.h" + +#include + +class PlayerActionJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + PlayerActionJob(Player::Ptr player, + const QString& operation, + QMap& parameters, + QObject* parent = 0) + : ServiceJob(player->name(), operation, parameters, parent), + m_player(player) + { + if (player) { + setObjectName("PlayerActionJob: " + player->name() + ": " + operation); + } else { + setObjectName("PlayerActionJob: null player: " + operation); + } + } + + void start(); + +private: + Player::Ptr m_player; +}; + +#endif // PLAYERACTIONJOB_H diff --git a/plasma/generic/dataengines/nowplaying/playercontainer.cpp b/plasma/generic/dataengines/nowplaying/playercontainer.cpp new file mode 100644 index 00000000..490a6d38 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playercontainer.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playercontainer.h" + +#include + +#include "playercontrol.h" + +PlayerContainer::PlayerContainer(Player::Ptr player, QObject* parent) + : DataContainer(parent) + , m_player(player) +{ + Q_ASSERT(m_player); + + setObjectName(m_player->name()); + + connect(this, SIGNAL(updateRequested(DataContainer*)), + this, SLOT(updateInfo())); +} + +Plasma::Service* PlayerContainer::service(QObject* parent) +{ + kDebug() << "Creating controller"; + Plasma::Service *controller = new PlayerControl(parent, m_player); + connect(this, SIGNAL(updateRequested(DataContainer*)), + controller, SLOT(updateEnabledOperations())); + return controller; +} + +void PlayerContainer::updateInfo() +{ + if (!m_player->isRunning()) { + kDebug() << objectName() << "isn't running"; + return; + } + + switch(m_player->state()) { + case Player::Playing: + setData("State", "playing"); + break; + case Player::Paused: + setData("State", "paused"); + break; + case Player::Stopped: + setData("State", "stopped"); + break; + } + + setData("Artist", m_player->artist()); + setData("Album", m_player->album()); + setData("Title", m_player->title()); + setData("Track number", m_player->trackNumber()); + setData("Comment", m_player->comment()); + setData("Genre", m_player->genre()); + setData("Lyrics", m_player->lyrics()); + setData("Length", m_player->length()); + setData("Position", m_player->position()); + setData("Volume", m_player->volume()); + setData("Artwork", m_player->artwork()); + + // propagate changes + checkForUpdate(); +} + +#include "playercontainer.moc" diff --git a/plasma/generic/dataengines/nowplaying/playercontainer.h b/plasma/generic/dataengines/nowplaying/playercontainer.h new file mode 100644 index 00000000..950c4448 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playercontainer.h @@ -0,0 +1,45 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERCONTAINER_H +#define PLAYERCONTAINER_H + +#include + +#include "playerinterface/player.h" + +class PlayerControl; + +class PlayerContainer : public Plasma::DataContainer +{ + Q_OBJECT + +public: + explicit PlayerContainer(Player::Ptr player, QObject* parent = 0); + + Plasma::Service* service(QObject* parent = 0); + +public slots: + void updateInfo(); + +private: + Player::Ptr m_player; +}; + +#endif // PLAYERCONTAINER_H diff --git a/plasma/generic/dataengines/nowplaying/playercontrol.cpp b/plasma/generic/dataengines/nowplaying/playercontrol.cpp new file mode 100644 index 00000000..6fca5e1c --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playercontrol.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "playercontrol.h" +#include "playeractionjob.h" + +#include + +PlayerControl::PlayerControl(QObject* parent, Player::Ptr player) + : Plasma::Service(parent), + m_player(player) +{ + setObjectName( QLatin1String("nowplaying controller" )); + setName("nowplaying"); + if (m_player) { + setDestination(m_player->name()); + setObjectName( QLatin1String("nowplaying controller for" ) + m_player->name()); + kDebug() << "Created a player control for" << m_player->name(); + } else { + kDebug() << "Created a dead player control"; + } + updateEnabledOperations(); +} + +void PlayerControl::updateEnabledOperations() +{ + if (m_player) { + /* + kDebug() << "Updating operations:" + << "\n Play:" << m_player->canPlay() + << "\n Pause:" << m_player->canPause() + << "\n Stop:" << m_player->canStop() + << "\n Next:" << m_player->canGoNext() + << "\n Previous:" << m_player->canGoPrevious() + << "\n Volume:" << m_player->canSetVolume() + << "\n Seek:" << m_player->canSeek(); + */ + setOperationEnabled("play", m_player->canPlay()); + setOperationEnabled("pause", m_player->canPause()); + setOperationEnabled("stop", m_player->canStop()); + setOperationEnabled("next", m_player->canGoNext()); + setOperationEnabled("previous", m_player->canGoPrevious()); + setOperationEnabled("volume", m_player->canSetVolume()); + setOperationEnabled("seek", m_player->canSeek()); + } else { + kDebug() << "No player"; + } +} + +Plasma::ServiceJob* PlayerControl::createJob(const QString& operation, + QMap& parameters) +{ + kDebug() << "Job" << operation << "with arguments" << parameters << "requested"; + return new PlayerActionJob(m_player, operation, parameters, this); +} + +#include "playercontrol.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/nowplaying/playercontrol.h b/plasma/generic/dataengines/nowplaying/playercontrol.h new file mode 100644 index 00000000..7344b11c --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playercontrol.h @@ -0,0 +1,45 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAYERCONTROL_H +#define PLAYERCONTROL_H + +#include + +#include "playerinterface/player.h" + +class PlayerControl : public Plasma::Service +{ + Q_OBJECT + +public: + PlayerControl(QObject* parent, Player::Ptr player); + +public slots: + void updateEnabledOperations(); + +protected: + Plasma::ServiceJob* createJob(const QString& operation, + QMap& parameters); + +private: + Player::Ptr m_player; +}; + +#endif // PLAYERCONTROL_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.cpp new file mode 100644 index 00000000..beab52f4 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#include "dbuswatcher.h" + +#include "player.h" +#include "playerfactory.h" + +#include +#include + +DBusWatcher::DBusWatcher(QObject* parent) + : QObject(parent), + m_bus(0) +{ + setObjectName( QLatin1String("DBusWatcher" )); + QDBusConnection sessionCon = QDBusConnection::sessionBus(); + if (sessionCon.isConnected()) { + m_bus = sessionCon.interface(); + connect(m_bus, SIGNAL(serviceOwnerChanged(QString,QString,QString)), + this, SLOT(serviceChange(QString,QString,QString))); + } else { + kWarning() << "Couldn't connect to session bus"; + } +} + +QList DBusWatcher::players() +{ + return m_players.values(); +} + +void DBusWatcher::addFactory(DBusPlayerFactory* factory) +{ + m_factories.append(factory); + + QDBusReply reply = m_bus->registeredServiceNames(); + if (reply.isValid()) { + QStringList services = reply.value(); + foreach (const QString &name, services) { + if (factory->matches(name)) { + QDBusReply ownerReply = m_bus->serviceOwner(name); + if (m_players.contains(name)) { + kWarning() << "Two factories tried to claim the same service:" << name; + } else if (ownerReply.isValid()) { + QString owner = ownerReply.value(); + kDebug() << "Service" << name << "has owner" << owner; + if (!m_owners.contains(owner)) { + QVariantList args; + args << QVariant(name); + Player::Ptr player = factory->create(args); + if (!player.isNull()) { + m_players[name] = player; + m_owners << owner; + emit(newPlayer(player)); + } else { + kDebug() << "Failed to get player" << name; + } + } + } + } + } + } else { + kWarning() << "Couldn't get service names:" << reply.error().message(); + } +} + +void DBusWatcher::serviceChange(const QString& name, + const QString& oldOwner, + const QString& newOwner) +{ + if (oldOwner.isEmpty() && !newOwner.isEmpty()) { + kDebug() << "Service" << name << "has owner" << newOwner; + if (m_owners.contains(newOwner)) { + kDebug() << "Owner" << newOwner << "is already being dealt with"; + // something is already dealing with this media player + return; + } + // got a new service + foreach (DBusPlayerFactory* factory, m_factories) { + if (factory->matches(name)) { + if (m_players.contains(name)) { + kWarning() << "Two factories tried to claim the same service:" << name; + } else { + QVariantList args; + args << QVariant(name); + Player::Ptr player = factory->create(args); + if (!player.isNull()) { + m_players[name] = player; + m_owners << newOwner; + emit(newPlayer(player)); + } else { + kDebug() << "Failed to get player" << name << "; trying other factories"; + } + } + } + } + } else if (!oldOwner.isEmpty() && newOwner.isEmpty()) { + m_owners.removeAll(oldOwner); + // an old service disappeared + if (m_players.contains(name)) { + Player::Ptr player = m_players[name]; + m_players.remove(name); + emit(playerDisappeared(player)); + } + } else if (!oldOwner.isEmpty() && !newOwner.isEmpty()) { + if (m_owners.removeAll(oldOwner) > 0) { + kDebug() << "Service" << name << "had owner" << oldOwner << "and is now owned by" << newOwner; + m_owners << newOwner; + } + } +} diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.h b/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.h new file mode 100644 index 00000000..38522ef6 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/dbuswatcher.h @@ -0,0 +1,70 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ + +#ifndef DBUSWATCHER_H +#define DBUSWATCHER_H + +#include +#include +#include + +#include "player.h" + +class QDBusConnectionInterface; +class DBusPlayerFactory; + +class DBusWatcher : public QObject +{ + Q_OBJECT + +public: + DBusWatcher(QObject* parent = 0); + + QList players(); + + /** + * Adds a service to watch for. + * + * @param factory the factory for the player + */ + void addFactory(DBusPlayerFactory* factory); + +Q_SIGNALS: + /** + * A new service appeared on D-Bus + */ + void newPlayer(Player::Ptr player); + /** + * A player disappeared from D-Bus + * + * @param player the now-invalid player + */ + void playerDisappeared(Player::Ptr player); + +private Q_SLOTS: + void serviceChange(const QString& name, + const QString& oldOwner, + const QString& newOwner); + +private: + QStringList m_owners; + QList m_factories; + QHash m_players; + QDBusConnectionInterface* m_bus; +}; + +#endif // DBUSWATCHER_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/juk.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/juk.cpp new file mode 100644 index 00000000..ad3deb69 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/juk.cpp @@ -0,0 +1,244 @@ +/* + * Copyright 2007 Alex Merry + * Copyright 2009 Michael Pyne + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "juk.h" +#include "juk_p.h" +#include + +#include + + +JukFactory::JukFactory(QObject* parent) + : DBusPlayerFactory(parent) +{ + setObjectName( QLatin1String("JukFactory" )); +} + +Player::Ptr JukFactory::create(const QVariantList& args) +{ + Q_UNUSED(args); + + Juk* player = new Juk(this); + if (!player->isRunning()) { + delete player; + player = 0; + } + return Player::Ptr(player); +} + +bool JukFactory::matches(const QString& serviceName) +{ + return serviceName == "org.kde.juk"; +} + + + + + +Juk::Juk(PlayerFactory* factory) + : Player(factory), + jukPlayer(new JukPlayer("org.kde.juk", "/Player", + QDBusConnection::sessionBus())) +{ + setName("JuK"); +} + +Juk::~Juk() +{ + delete jukPlayer; +} + +bool Juk::isRunning() +{ + if (!jukPlayer->isValid()) { + delete jukPlayer; + jukPlayer = new JukPlayer("org.kde.juk", "/Player", + QDBusConnection::sessionBus()); + } + return jukPlayer->isValid(); +} + +Player::State Juk::state() +{ + if (jukPlayer->isValid()) { + if (jukPlayer->playing()) { + return Playing; + } + if (jukPlayer->paused()) { + return Paused; + } + } + return Stopped; +} + +QString Juk::artist() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Artist"); + } + return QString(); +} + +QString Juk::album() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Album"); + } + return QString(); +} + +QString Juk::title() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Title"); + } + return QString(); +} + +int Juk::trackNumber() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Track").value().toInt(); + } + return 0; +} + +QString Juk::comment() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Comment"); + } + return QString(); +} + +QString Juk::genre() +{ + if (jukPlayer->isValid()) { + return jukPlayer->trackProperty("Genre"); + } + return QString(); +} + +int Juk::length() +{ + if (jukPlayer->isValid()) { + return jukPlayer->totalTime(); + } + return 0; +} + +int Juk::position() +{ + if (jukPlayer->isValid()) { + return jukPlayer->currentTime(); + } + return 0; +} + +float Juk::volume() +{ + if (jukPlayer->isValid()) { + return jukPlayer->volume(); + } + return 0; +} + +void Juk::play() +{ + if (jukPlayer->isValid()) { + jukPlayer->play(); + } +} + +void Juk::pause() +{ + if (jukPlayer->isValid()) { + jukPlayer->pause(); + } +} + +void Juk::stop() +{ + if (jukPlayer->isValid()) { + jukPlayer->stop(); + } +} + +void Juk::previous() +{ + if (jukPlayer->isValid()) { + jukPlayer->back(); + } +} + +void Juk::next() +{ + if (jukPlayer->isValid()) { + jukPlayer->forward(); + } +} + +void Juk::setVolume(qreal volume) { + if (jukPlayer->isValid()) { + jukPlayer->setVolume(volume); + } +} + +QPixmap Juk::artwork() +{ + if(!jukPlayer->isValid()) + return QPixmap(); + + QString playingPath = jukPlayer->trackProperty("Path"); + + // Caching is employed since some players have to make temp files for + // their cover art. If we were to grab a cover once per second that + // could be disastrous. + if(playingPath == m_lastPath) + return m_artwork; + + m_lastPath = playingPath; + if(playingPath.isEmpty()) { + m_artwork = QPixmap(); + return m_artwork; + } + + // JuK only supports this method starting from KDE 4.3 + QDBusInterface collectionIface("org.kde.juk", "/Collection", "org.kde.juk.collection"); + QDBusReply reply = collectionIface.call("trackCover", playingPath); + + if(reply.isValid() && !reply.value().isEmpty()) { + m_artwork = QPixmap(reply.value()); + return m_artwork; + } + + m_artwork = QPixmap(); + return m_artwork; +} + +void Juk::seek(int time) +{ + if (jukPlayer->isValid()) { + // jukPlayer->seek() wants milliseconds + jukPlayer->seek(time * 1000); + } +} + + +#include "juk.moc" diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/juk.h b/plasma/generic/dataengines/nowplaying/playerinterface/juk.h new file mode 100644 index 00000000..5f446189 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/juk.h @@ -0,0 +1,35 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef JUK_H +#define JUK_H + +#include "playerfactory.h" + +class JukFactory : public DBusPlayerFactory +{ + Q_OBJECT + +public: + explicit JukFactory(QObject* parent = 0); + Player::Ptr create(const QVariantList& args = QVariantList()); + bool matches(const QString& serviceName); +}; + + +#endif // JUK_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/juk_p.h b/plasma/generic/dataengines/nowplaying/playerinterface/juk_p.h new file mode 100644 index 00000000..d8f672c7 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/juk_p.h @@ -0,0 +1,75 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#ifndef JUK_P_H +#define JUK_P_H + +#include "juk.h" +#include "player.h" + +#include +#include +#include + +class OrgKdeJukPlayerInterface; + + + +class Juk : public Player +{ +public: + Juk(PlayerFactory* factory = 0); + ~Juk(); + + bool isRunning(); + State state(); + QString artist(); + QString album(); + QString title(); + int trackNumber(); + QString comment(); + QString genre(); + int length(); + int position(); + float volume(); + + bool canPlay() { return state() != Playing; } + void play(); + bool canPause() { return true; } + void pause(); + bool canStop() { return state() != Stopped; } + void stop(); + bool canGoPrevious() { return true; } + void previous(); + bool canGoNext() { return true; } + void next(); + + bool canSetVolume() { return true; } + void setVolume(qreal volume); + + QPixmap artwork(); + + bool canSeek() { return state() != Stopped; } + void seek(int time); + +private: + QPixmap m_artwork; + QString m_lastPath; + typedef OrgKdeJukPlayerInterface JukPlayer; + JukPlayer* jukPlayer; +}; + +#endif // JUK_P_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.cpp new file mode 100644 index 00000000..4bed1b12 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.cpp @@ -0,0 +1,396 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mpris.h" +#include "mpris_p.h" +#include + +#include +#include + +#include +#include + + + +MprisFactory::MprisFactory(QObject* parent) + : DBusPlayerFactory(parent) +{ + setObjectName( QLatin1String("MprisFactory" )); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); +} + +Player::Ptr MprisFactory::create(const QVariantList& args) +{ + if (args.isEmpty()) { + return Player::Ptr(0); + } + + QString dbusName(args.first().toString()); + if (dbusName.isEmpty()) { + return Player::Ptr(0); + } + + Mpris* player = new Mpris(dbusName, this); + if (!player->isRunning()) { + delete player; + player = 0; + } + + return Player::Ptr(player); +} + +bool MprisFactory::matches(const QString& serviceName) +{ + return serviceName.startsWith(QLatin1String("org.mpris")) && + !serviceName.startsWith(QLatin1String("org.mpris.MediaPlayer2")); +} + + + +Mpris::Mpris(const QString& name, PlayerFactory* factory) + : QObject(), + Player(factory), + m_player(0), + m_playerName(name), + m_artworkLoaded(false) +{ + if (!name.startsWith(QLatin1String("org.mpris"))) { + m_playerName = "org.mpris." + name; + } + setName(m_playerName); + setup(); +} + +Mpris::~Mpris() +{ + delete m_player; +} + +void Mpris::setup() +{ + delete m_player; + m_player = new MprisPlayer( + m_playerName, + "/Player", + QDBusConnection::sessionBus()); + + m_metadata.clear(); + m_state = Stopped; + m_caps = NO_CAPS; + + if (m_player->isValid()) { + connect(m_player, SIGNAL(CapsChange(int)), + this, SLOT(capsChanged(int))); + connect(m_player, SIGNAL(TrackChange(QVariantMap)), + this, SLOT(trackChanged(QVariantMap))); + connect(m_player, SIGNAL(StatusChange(MprisDBusStatus)), + this, SLOT(stateChanged(MprisDBusStatus))); + + QDBusReply caps = m_player->GetCaps(); + if (caps.isValid()) { + capsChanged(caps); + } + + QDBusReply metadata = m_player->GetMetadata(); + if (metadata.isValid()) { + trackChanged(metadata); + } + + QDBusReply status = m_player->GetStatus(); + if (status.isValid()) { + stateChanged(status); + } + } +} + +bool Mpris::isRunning() +{ + if (!m_player->isValid()) { + setup(); + } + + return m_player->isValid(); +} + +Player::State Mpris::state() +{ + return m_state; +} + +QString Mpris::artist() +{ + if (m_metadata.contains("artist")) { + return m_metadata["artist"].toString(); + } + return QString(); +} + +QString Mpris::album() +{ + if (m_metadata.contains("album")) { + return m_metadata["album"].toString(); + } + return QString(); +} + +QString Mpris::title() +{ + if (m_metadata.contains("title")) { + return m_metadata["title"].toString(); + } + return QString(); +} + +int Mpris::trackNumber() +{ + QVariant track; + if (m_metadata.contains("trackNumber")) { + track = m_metadata["trackNumber"]; + } else if (m_metadata.contains("tracknumber")) { + track = m_metadata["tracknumber"]; + } + if (track.isValid()) { + if (track.canConvert(QVariant::Int)) { + return track.toInt(); + } else { + QString text = track.toString(); + int pos = text.indexOf('/'); + if (pos >= 0) { + text.truncate(pos); + } + return text.toInt(); + } + } + return 0; +} + +QString Mpris::comment() +{ + if (m_metadata.contains("comment")) { + return m_metadata["comment"].toString(); + } + return QString(); +} + +QString Mpris::genre() +{ + if (m_metadata.contains("genre")) { + return m_metadata["genre"].toString(); + } + return QString(); +} + +QString Mpris::lyrics() +{ + if (m_metadata.contains("lyrics")) { + return m_metadata["lyrics"].toString(); + } + return QString(); +} + +int Mpris::length() +{ + if (m_metadata.contains("time")) { + return m_metadata["time"].toInt(); + } else if (m_metadata.contains("length")) { + // stupid audacious... + return m_metadata["length"].toInt()/1000; + } + return 0; +} + +int Mpris::position() +{ + if (m_player->isValid()) { + QDBusReply positionMs = m_player->PositionGet(); + if (positionMs.isValid()) { + return positionMs / 1000; + } + } + return 0; +} + +float Mpris::volume() +{ + if (m_player->isValid()) { + QDBusReply volumePercent = m_player->VolumeGet(); + if (volumePercent.isValid()) + return ((float)volumePercent) / 100; + } + return 0; +} + +QPixmap Mpris::artwork() +{ + if (m_artworkLoaded) { + return m_artwork; + } + + m_artwork = QPixmap(); + const QString arturl = m_metadata["arturl"].toString(); + if (!arturl.isEmpty()) { + if (!m_artfiles.contains(arturl) || + (!m_artfiles[arturl].isEmpty() && !QFile::exists(m_artfiles[arturl]))) { + QString artfile; + if (!KIO::NetAccess::download(arturl, artfile, 0)) { + kWarning() << KIO::NetAccess::lastErrorString(); + artfile.clear(); + } + + m_artfiles[arturl] = artfile; + } + + const QString url = m_artfiles[arturl]; + if (!url.isEmpty()) { + m_artwork = QPixmap(url); + } + } + + m_artworkLoaded = true; + return m_artwork; +} + +bool Mpris::canPlay() +{ + return m_caps & CAN_PLAY; +} + +void Mpris::play() +{ + if (m_player->isValid()) { + m_player->Play(); + } +} + +bool Mpris::canPause() +{ + return m_caps & CAN_PAUSE; +} + +void Mpris::pause() +{ + if (m_player->isValid()) { + m_player->Pause(); + } +} + +bool Mpris::canStop() +{ + return m_state != Stopped; +} + +void Mpris::stop() +{ + if (m_player->isValid()) { + m_player->Stop(); + } +} + +bool Mpris::canGoPrevious() +{ + return m_caps & CAN_GO_PREV; +} + +void Mpris::previous() +{ + if (m_player->isValid()) { + m_player->Prev(); + } +} + +bool Mpris::canGoNext() +{ + return m_caps & CAN_GO_NEXT; +} + +void Mpris::next() +{ + if (m_player->isValid()) { + m_player->Next(); + } +} + +bool Mpris::canSetVolume() +{ + return true; +} + +void Mpris::setVolume(qreal volume) +{ + if (m_player->isValid()) { + m_player->VolumeSet((int)(volume * 100)); + } +} + +bool Mpris::canSeek() +{ + return m_caps & CAN_SEEK; +} + +void Mpris::seek(int time) +{ + if (m_player->isValid()) { + // m_player->seek() wants milliseconds + m_player->PositionSet(time * 1000); + } +} + +// SLOTS + +void Mpris::trackChanged(const QVariantMap& metadata) +{ + //kDebug() << m_playerName << "metadata:" << metadata; + const QString oldArt = m_metadata.value("arturl").toString(); + m_metadata = metadata; + if (m_artworkLoaded) { + m_artworkLoaded = oldArt == m_metadata.value("arturl"); + } +} + +void Mpris::stateChanged(MprisDBusStatus state) +{ + kDebug() << m_playerName << "state:" << state.play; + switch (state.play) { + case MprisDBusStatus::Playing: + m_state = Playing; + break; + case MprisDBusStatus::Paused: + m_state = Paused; + break; + case MprisDBusStatus::Stopped: + m_state = Stopped; + break; + default: + kDebug() << m_playerName << "unexpected state" << state.play; + } +} + +void Mpris::capsChanged(int caps) +{ + kDebug() << m_playerName << "capabilities:" << caps; + m_caps = (DBusCaps)caps; + if (!(caps & CAN_PROVIDE_METADATA)) { + m_metadata.clear(); + } +} + + +#include "mpris.moc" +#include "mpris_p.moc" diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.h b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.h new file mode 100644 index 00000000..cb8cf83b --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris.h @@ -0,0 +1,34 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MPRIS_H +#define MPRIS_H + +#include "../playerfactory.h" + +class MprisFactory : public DBusPlayerFactory +{ + Q_OBJECT + +public: + explicit MprisFactory(QObject* parent = 0); + Player::Ptr create(const QVariantList& args = QVariantList()); + bool matches(const QString& serviceName); +}; + +#endif // MPRIS_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris_p.h b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris_p.h new file mode 100644 index 00000000..d8c3121c --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mpris_p.h @@ -0,0 +1,89 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#ifndef MPRIS_P_H +#define MPRIS_P_H + +#include "mpris.h" +#include "mprisdbustypes.h" +#include "../player.h" + +#include + +class MprisPlayer; + +class Mpris : public QObject, public Player +{ + Q_OBJECT + +public: + /** + * @param name the media player name. + */ + explicit Mpris(const QString& name, + PlayerFactory* factory = 0); + ~Mpris(); + + bool isRunning(); + State state(); + QString artist(); + QString album(); + QString title(); + int trackNumber(); + QString comment(); + QString genre(); + QString lyrics(); + int length(); + int position(); + float volume(); + QPixmap artwork(); + + bool canPlay(); + void play(); + bool canPause(); + void pause(); + bool canStop(); + void stop(); + bool canGoPrevious(); + void previous(); + bool canGoNext(); + void next(); + + bool canSetVolume(); + void setVolume(qreal volume); + + bool canSeek(); + void seek(int time); + +private Q_SLOTS: + void trackChanged(const QVariantMap& metadata); + void stateChanged(MprisDBusStatus state); + void capsChanged(int caps); + +private: + void setup(); + MprisPlayer* m_player; + + QString m_playerName; + QVariantMap m_metadata; + State m_state; + DBusCaps m_caps; + QMap m_artfiles; + bool m_artworkLoaded; + QPixmap m_artwork; +}; + +#endif // MPRIS_P_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.cpp new file mode 100644 index 00000000..2d42a50c --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2008 Alex Merry + * + * 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. If not, see . + */ +#include "mprisdbustypes.h" + +// Marshall the MprisDBusVersion data into a D-BUS argument +QDBusArgument &operator<<(QDBusArgument &argument, const MprisDBusVersion &version) +{ + argument.beginStructure(); + argument << version.major << version.minor; + argument.endStructure(); + return argument; +} + +// Retrieve the MprisDBusVersion data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, MprisDBusVersion &version) +{ + argument.beginStructure(); + argument >> version.major >> version.minor; + argument.endStructure(); + return argument; +} + +// Marshall the MprisDBusStatus data into a D-BUS argument +QDBusArgument &operator<<(QDBusArgument &argument, const MprisDBusStatus &status) +{ + argument.beginStructure(); + argument << (qint32)status.play; + argument << (qint32)status.random; + argument << (qint32)status.trackRepeat; + argument << (qint32)status.playlistRepeat; + argument.endStructure(); + return argument; +} + +// Retrieve the MprisDBusStatus data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, MprisDBusStatus &status) +{ + qint32 play, random, trackRepeat, playlistRepeat; + + argument.beginStructure(); + argument >> play; + argument >> random; + argument >> trackRepeat; + argument >> playlistRepeat; + argument.endStructure(); + + status.play = (MprisDBusStatus::PlayMode)play; + status.random = (MprisDBusStatus::RandomMode)random; + status.trackRepeat = (MprisDBusStatus::TrackRepeatMode)trackRepeat; + status.playlistRepeat = (MprisDBusStatus::PlaylistRepeatMode)playlistRepeat; + + return argument; +} + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.h b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.h new file mode 100644 index 00000000..325f3e49 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/mprisdbustypes.h @@ -0,0 +1,79 @@ +#ifndef MPRISDEFS_H +#define MPRISDEFS_H + +#include + +enum DBusCaps { + NO_CAPS = 0, + CAN_GO_NEXT = 1 << 0, + CAN_GO_PREV = 1 << 1, + CAN_PAUSE = 1 << 2, + CAN_PLAY = 1 << 3, + CAN_SEEK = 1 << 4, + CAN_PROVIDE_METADATA = 1 << 5, + CAN_HAS_TRACKLIST = 1 << 6, + UNKNOWN_CAP = 1 << 7 +}; + + +struct MprisDBusVersion +{ + quint16 major; + quint16 minor; +}; + +Q_DECLARE_METATYPE(MprisDBusVersion) + +// Marshall the MprisDBusVersion data into a D-BUS argument +QDBusArgument &operator<<(QDBusArgument &argument, const MprisDBusVersion &version); +// Retrieve the MprisDBusVersion data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, MprisDBusVersion &version); + + +struct MprisDBusStatus +{ + enum PlayMode { + Playing = 0, + Paused = 1, + Stopped = 2 + }; + + enum RandomMode { + Linear = 0, + Random = 1 + }; + + enum TrackRepeatMode { + GoToNext = 0, + RepeatCurrent = 1 + }; + + enum PlaylistRepeatMode { + StopWhenFinished = 0, + PlayForever = 1 + }; + + MprisDBusStatus(PlayMode _play = Stopped, + RandomMode _random = Linear, + TrackRepeatMode _trackRepeat = GoToNext, + PlaylistRepeatMode _playlistRepeat = StopWhenFinished) + : play(_play), + random(_random), + trackRepeat(_trackRepeat), + playlistRepeat(_playlistRepeat) + { + } + PlayMode play; + RandomMode random; + TrackRepeatMode trackRepeat; + PlaylistRepeatMode playlistRepeat; +}; + +Q_DECLARE_METATYPE(MprisDBusStatus) + +// Marshall the MprisDBusStatus data into a D-BUS argument +QDBusArgument &operator<<(QDBusArgument &argument, const MprisDBusStatus &status); +// Retrieve the MprisDBusStatus data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, MprisDBusStatus &status); + +#endif // MPRISDEFS_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.player.xml b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.player.xml new file mode 100644 index 00000000..302c3830 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.player.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.root.xml b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.root.xml new file mode 100644 index 00000000..aa93e4bd --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.root.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.tracklist.xml b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.tracklist.xml new file mode 100644 index 00000000..e8cb127b --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris/org.freedesktop.MediaPlayer.tracklist.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.cpp new file mode 100644 index 00000000..b28378da --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.cpp @@ -0,0 +1,500 @@ +/* + * Copyright 2011 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mpris2.h" +#include "mpris2_p.h" + +#include +#include +#include + +#include +#include + +#define MPRIS2_PATH "/org/mpris/MediaPlayer2" +#define MPRIS2_ROOT_IFACE "org.mpris.MediaPlayer2" +#define MPRIS2_PLAYER_IFACE "org.mpris.MediaPlayer2.Player" +#define DBUS_PROPS_IFACE "org.freedesktop.DBus.Properties" + +Mpris2Factory::Mpris2Factory(QObject* parent) + : DBusPlayerFactory(parent) +{ + setObjectName( QLatin1String("Mpris2Factory" )); +} + +Player::Ptr Mpris2Factory::create(const QVariantList& args) +{ + if (args.isEmpty()) { + return Player::Ptr(0); + } + + QString dbusName(args.first().toString()); + if (dbusName.isEmpty()) { + return Player::Ptr(0); + } + + Mpris2* player = new Mpris2(dbusName, this); + if (!player->isRunning()) { + delete player; + player = 0; + } + + return Player::Ptr(player); +} + +bool Mpris2Factory::matches(const QString& serviceName) +{ + return serviceName.startsWith(QLatin1String("org.mpris.MediaPlayer2.")); +} + + + +Mpris2::Mpris2(const QString& name, PlayerFactory* factory) + : QObject(), + Player(factory), + rootIface(0), + playerIface(0), + propsIface(0), + m_pos(0), + m_rate(0), + m_currentRate(0), + m_playerName(name), + m_volume(0.0f), + m_state(Stopped), + m_canControl(false), + m_canPlay(false), + m_canPause(false), + m_canGoPrevious(false), + m_canGoNext(false), + m_canSeek(false), + m_artworkLoaded(false) +{ + if (!name.startsWith(QLatin1String("org.mpris.MediaPlayer2."))) { + m_playerName = "org.mpris.MediaPlayer2." + name; + } + setName(m_playerName); + setup(); +} + +Mpris2::~Mpris2() +{ +} + +static Mpris2::State playbackStatusToState(const QString &status) +{ + if (status == "Playing") { + return Mpris2::Playing; + } else if (status == "Paused") { + return Mpris2::Paused; + } else { + return Mpris2::Stopped; + } +} + +static QVariantMap demarshallMetadata(const QVariant &value) +{ + if (!value.canConvert()) { + const char * gotTypeCh = QDBusMetaType::typeToSignature(value.userType()); + QString gotType = gotTypeCh ? QString::fromAscii(gotTypeCh) : ""; + kDebug() << "Expected variant containing a QDBusArgument, got ready-demarshalled item of type" << gotType; + return QVariantMap(); + } + QVariantMap metadata; + QDBusArgument arg = value.value(); + arg >> metadata; + return metadata; +} + +void Mpris2::updatePosition(qreal rate) +{ + QDBusReply reply = propsIface->call("Get", MPRIS2_PLAYER_IFACE, "Position"); + if (!reply.isValid()) { + kDebug() << DBUS_PROPS_IFACE ".Get(\"" MPRIS2_PLAYER_IFACE "\", \"Position\") failed at " + MPRIS2_PATH " on" << m_playerName << " with error " << + reply.error().name(); + m_pos = position(); + } else { + m_pos = reply.value().variant().toLongLong() / 1000L; + } + m_posLastUpdated = QDateTime::currentDateTime().toUTC(); + m_rate = rate; + m_currentRate = (m_state == Playing) ? m_rate : 0.0; +} + +bool Mpris2::getAllProps() +{ + QDBusReply identityReply = propsIface->call("Get", MPRIS2_ROOT_IFACE, "Identity"); + if (!identityReply.isValid()) { + kDebug() << DBUS_PROPS_IFACE ".Get(\"" MPRIS2_ROOT_IFACE "\", \"Identity\") failed at " + MPRIS2_PATH " on" << m_playerName << " with error " << + identityReply.error().name(); + return false; + } + m_identity = identityReply.value().variant().toString(); + if (m_identity.isEmpty()) { + kDebug() << "Empty player identity; giving up"; + return false; + } + + QDBusReply playerPropsReply = propsIface->call("GetAll", MPRIS2_PLAYER_IFACE); + if (!playerPropsReply.isValid()) { + kDebug() << DBUS_PROPS_IFACE ".GetAll(\"" MPRIS2_PLAYER_IFACE "\") failed at " + MPRIS2_PATH " on" << m_playerName << " with error " << + playerPropsReply.error().name(); + return false; + } + m_posLastUpdated = QDateTime::currentDateTime().toUTC(); + + QVariantMap props = playerPropsReply.value(); + m_state = playbackStatusToState(props.value("PlaybackStatus").toString()); + m_metadata = demarshallMetadata(props.value("Metadata")); + m_volume = props.value("Volume").toDouble(); + m_canControl = props.value("CanControl").toBool(); + m_canPlay = m_canControl && props.value("CanPlay").toBool(); + m_canPause = m_canControl && props.value("CanPause").toBool(); + m_canGoPrevious = m_canControl && props.value("CanGoPrevious").toBool(); + m_canGoNext = m_canControl && props.value("CanGoNext").toBool(); + m_canSeek = m_canControl && props.value("CanSeek").toBool(); + m_pos = props.value("Position").toLongLong() / 1000L; + m_rate = props.value("Rate").toDouble(); + m_currentRate = (m_state == Playing) ? m_rate : 0.0; + + return true; +} + +void Mpris2::setup() +{ + delete propsIface; + delete rootIface; + delete playerIface; + + propsIface = new QDBusInterface(m_playerName, MPRIS2_PATH, DBUS_PROPS_IFACE, QDBusConnection::sessionBus(), this); + rootIface = new QDBusInterface(m_playerName, MPRIS2_PATH, MPRIS2_ROOT_IFACE, QDBusConnection::sessionBus(), this); + playerIface = new QDBusInterface(m_playerName, MPRIS2_PATH, MPRIS2_PLAYER_IFACE, QDBusConnection::sessionBus(), this); + + if (getAllProps()) { + QDBusConnection::sessionBus().connect( + playerIface->service(), + playerIface->path(), + playerIface->interface(), + "Seeked", /* signature, */ + this, + SLOT(Seeked(qint64))); + QStringList matchArgs; + matchArgs << MPRIS2_PLAYER_IFACE; + QDBusConnection::sessionBus().connect( + propsIface->service(), + propsIface->path(), + propsIface->interface(), + "PropertiesChanged", + matchArgs, + QString(), // signature + this, + SLOT(PropertiesChanged(QString,QVariantMap,QStringList))); + } else { + m_identity.clear(); + } +} + +bool Mpris2::isRunning() +{ + if (m_identity.isEmpty()) { + setup(); + } + + return !m_identity.isEmpty(); +} + +Player::State Mpris2::state() +{ + return m_state; +} + +QString Mpris2::artist() +{ + if (m_metadata.contains("xesam:artist")) { + QStringList entries = m_metadata.value("xesam:artist").toStringList(); + if (!entries.isEmpty()) + return entries.first(); + } + return QString(); +} + +QString Mpris2::album() +{ + return m_metadata.value("xesam:album").toString(); +} + +QString Mpris2::title() +{ + return m_metadata.value("xesam:title").toString(); +} + +int Mpris2::trackNumber() +{ + QVariant track; + if (m_metadata.contains("xesam:trackNumber")) { + track = m_metadata.value("xesam:trackNumber"); + } + if (track.isValid() && track.canConvert(QVariant::Int)) { + return track.toInt(); + } + return 0; +} + +QString Mpris2::comment() +{ + if (m_metadata.contains("xesam:comment")) { + return m_metadata.value("xesam:comment").toStringList().join("\n"); + } + return QString(); +} + +QString Mpris2::genre() +{ + if (m_metadata.contains("xesam:genre")) { + QStringList entries = m_metadata.value("xesam:genre").toStringList(); + if (!entries.isEmpty()) + return entries.first(); + } + return QString(); +} + +QString Mpris2::lyrics() +{ + return m_metadata.value("xesam:asText").toString(); +} + +int Mpris2::length() +{ + qlonglong lengthMicros = m_metadata.value("mpris:length").toLongLong(); + return static_cast(lengthMicros / 1000000L); +} + +int Mpris2::position() +{ + return static_cast(positionMs() / 1000L); +} + +qint64 Mpris2::positionMs() +{ + qint64 elapsed = m_posLastUpdated.msecsTo(QDateTime::currentDateTime()); + return m_pos + (m_currentRate * elapsed); +} + +float Mpris2::volume() +{ + return m_volume; +} + +QPixmap Mpris2::artwork() +{ + if (m_artworkLoaded) { + return m_artwork; + } + + m_artwork = QPixmap(); + const QString arturl = m_metadata.value("mpris:artUrl").toString(); + if (!arturl.isEmpty()) { + if (!m_artfiles.contains(arturl) || + (!m_artfiles[arturl].isEmpty() && !QFile::exists(m_artfiles[arturl]))) { + QString artfile; + if (!KIO::NetAccess::download(arturl, artfile, 0)) { + kWarning() << "Could not download artwork from" << arturl << ":" << KIO::NetAccess::lastErrorString(); + artfile.clear(); + } + + m_artfiles[arturl] = artfile; + } + + const QString url = m_artfiles.value(arturl); + if (!url.isEmpty()) { + m_artwork = QPixmap(url); + } + } + + m_artworkLoaded = true; + return m_artwork; +} + +bool Mpris2::canPlay() +{ + return m_canPlay; +} + +void Mpris2::play() +{ + playerIface->asyncCall("Play"); +} + +bool Mpris2::canPause() +{ + return m_canPause; +} + +void Mpris2::pause() +{ + playerIface->asyncCall("Pause"); +} + +bool Mpris2::canStop() +{ + return m_canControl; +} + +void Mpris2::stop() +{ + playerIface->asyncCall("Stop"); +} + +bool Mpris2::canGoPrevious() +{ + return m_canGoPrevious; +} + +void Mpris2::previous() +{ + playerIface->asyncCall("Previous"); +} + +bool Mpris2::canGoNext() +{ + return m_canGoNext; +} + +void Mpris2::next() +{ + playerIface->asyncCall("Next"); +} + +bool Mpris2::canSetVolume() +{ + return m_canControl; +} + +void Mpris2::setVolume(qreal volume) +{ + QDBusVariant value = QDBusVariant(QVariant(static_cast(volume))); + propsIface->asyncCall("Set", MPRIS2_PLAYER_IFACE, "Volume", QVariant::fromValue(value)); +} + +bool Mpris2::canSeek() +{ + return m_canSeek; +} + +void Mpris2::seek(int time) +{ + if (!m_metadata.contains("mpris:trackid")) { + kDebug() << "No mpris:trackid; aborting seek"; + return; + } + QDBusObjectPath trackid = m_metadata.value("mpris:trackid").value(); + if (trackid.path().isEmpty()) { + kDebug() << "Empty path for mpris:trackid; aborting seek"; + return; + } + playerIface->asyncCall("SetPosition", + QVariant::fromValue(trackid), + QVariant::fromValue((qint64)time * 1000000L)); +} + +QVariant Mpris2::getPlayerProp(const QString& prop) +{ + QDBusReply reply = propsIface->call("Get", MPRIS2_PLAYER_IFACE, prop); + if (!reply.isValid()) { + kDebug() << DBUS_PROPS_IFACE ".Get( \"" MPRIS2_PLAYER_IFACE "\"," + << prop + << ") failed at " MPRIS2_PATH " on" + << m_playerName + << " with error " + << reply.error().name(); + return QVariant(); + } + return reply.value().variant(); +} + +bool Mpris2::updateBoolProp(const QString &name, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties, + bool currentVal) +{ + if (changedProperties.contains(name)) { + kDebug() << "Property" << name << "changed from" << currentVal << "to" << changedProperties.value(name).toBool(); + return changedProperties.value(name).toBool(); + } else if (invalidatedProperties.contains(name)) { + bool newVal = getPlayerProp(name).toBool(); + kDebug() << "Property" << name << "changed (inv) from" << currentVal << "to" << newVal; + return newVal; + } + return currentVal; +} + +// SLOTS + +void Mpris2::Seeked(qint64 position) +{ + m_pos = position / 1000L; + m_posLastUpdated = QDateTime::currentDateTime().toUTC(); +} + +void Mpris2::PropertiesChanged(const QString& interface, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties) +{ + if (interface != MPRIS2_PLAYER_IFACE) + return; + + State origState = m_state; + qreal rate = m_rate; + if (changedProperties.contains("PlaybackStatus")) { + m_state = playbackStatusToState(changedProperties.value("PlaybackStatus").toString()); + } else if (invalidatedProperties.contains("PlaybackStatus")) { + m_state = playbackStatusToState(getPlayerProp("PlaybackStatus").toString()); + } + if (changedProperties.contains("Rate")) { + rate = changedProperties.value("Rate").toDouble(); + } else if (invalidatedProperties.contains("Rate")) { + rate = getPlayerProp("Rate").toDouble(); + } + if (origState != m_state || !qFuzzyCompare(m_rate, rate)) { + updatePosition(rate); + } + + if (changedProperties.contains("Metadata")) { + m_metadata = demarshallMetadata(changedProperties.value("Metadata")); + } else if (invalidatedProperties.contains("Metadata")) { + m_metadata = demarshallMetadata(getPlayerProp("Metadata")); + } + + if (changedProperties.contains("Volume")) { + m_volume = changedProperties.value("Volume").toDouble(); + } else if (invalidatedProperties.contains("Volume")) { + m_volume = getPlayerProp("Volume").toDouble(); + } + + m_canPlay = m_canControl && updateBoolProp("CanPlay", changedProperties, invalidatedProperties, m_canPlay); + m_canPause = m_canControl && updateBoolProp("CanPause", changedProperties, invalidatedProperties, m_canPause); + m_canGoPrevious = m_canControl && updateBoolProp("CanGoPrevious", changedProperties, invalidatedProperties, m_canGoPrevious); + m_canGoNext = m_canControl && updateBoolProp("CanGoNext", changedProperties, invalidatedProperties, m_canGoNext); + m_canSeek = m_canControl && updateBoolProp("CanSeek", changedProperties, invalidatedProperties, m_canSeek); +} + +#include "mpris2.moc" +#include "mpris2_p.moc" +// vim:et:sts=4:sw=4 diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.h b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.h new file mode 100644 index 00000000..0ab36504 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MPRIS2_H +#define MPRIS2_H + +#include "../playerfactory.h" + +class Mpris2Factory : public DBusPlayerFactory +{ + Q_OBJECT + +public: + explicit Mpris2Factory(QObject* parent = 0); + Player::Ptr create(const QVariantList& args = QVariantList()); + bool matches(const QString& serviceName); +}; + +#endif // MPRIS2_H +// vim:et:sts=4:sw=4 diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2_p.h b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2_p.h new file mode 100644 index 00000000..04a3a762 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/mpris2/mpris2_p.h @@ -0,0 +1,113 @@ +/* + * Copyright 2011 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#ifndef MPRIS2_P_H +#define MPRIS2_P_H + +#include "mpris2.h" +#include "../player.h" + +#include +#include +class QDBusInterface; + +class Mpris2 : public QObject, public Player +{ + Q_OBJECT + +public: + /** + * @param name the media player name. + */ + explicit Mpris2(const QString& name, + PlayerFactory* factory = 0); + ~Mpris2(); + + bool isRunning(); + State state(); + QString artist(); + QString album(); + QString title(); + int trackNumber(); + QString comment(); + QString genre(); + QString lyrics(); + int length(); + int position(); + float volume(); + QPixmap artwork(); + + bool canPlay(); + void play(); + bool canPause(); + void pause(); + bool canStop(); + void stop(); + bool canGoPrevious(); + void previous(); + bool canGoNext(); + void next(); + + bool canSetVolume(); + void setVolume(qreal volume); + + bool canSeek(); + void seek(int time); + +private Q_SLOTS: + void Seeked(qint64 position); + void PropertiesChanged(const QString& interface, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties); + +private: + qint64 positionMs(); + void setup(); + bool getAllProps(); + void updatePosition(qreal rate); + QVariant getPlayerProp(const QString& prop); + bool updateBoolProp(const QString &name, + const QVariantMap& changedProperties, + const QStringList& invalidatedProperties, + bool currentVal); + + QDBusInterface* rootIface; + QDBusInterface* playerIface; + QDBusInterface* propsIface; + + qint64 m_pos; // milliseconds + qreal m_rate; + qreal m_currentRate; // 0.0 if not playing, Rate otherwise + QDateTime m_posLastUpdated; + + QString m_playerName; + QString m_identity; + QVariantMap m_metadata; + float m_volume; + State m_state; + bool m_canControl; + bool m_canPlay; + bool m_canPause; + bool m_canGoPrevious; + bool m_canGoNext; + bool m_canSeek; + QMap m_artfiles; + bool m_artworkLoaded; + QPixmap m_artwork; +}; + +#endif // MPRIS2_P_H +// vim:et:sts=4:sw=4 diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/org.kde.juk.player.xml b/plasma/generic/dataengines/nowplaying/playerinterface/org.kde.juk.player.xml new file mode 100644 index 00000000..bb6e18d4 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/org.kde.juk.player.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/player.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/player.cpp new file mode 100644 index 00000000..b0f2680b --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/player.cpp @@ -0,0 +1,164 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "player.h" + +Player::Player(PlayerFactory* factory) + : m_factory(factory) +{ +} + +Player::~Player() +{ +} + +PlayerFactory* Player::factory() const +{ + return m_factory; +} + +QString Player::name() const +{ + Q_ASSERT(!m_name.isEmpty()); + return m_name; +} + +QString Player::artist() +{ + return QString(); +} + +QString Player::album() +{ + return QString(); +} + +QString Player::title() +{ + return QString(); +} + +int Player::trackNumber() +{ + return 0; +} + +QString Player::comment() +{ + return QString(); +} + +QString Player::genre() +{ + return QString(); +} + +QString Player::lyrics() +{ + return QString(); +} + +int Player::length() +{ + return 0; +} + +int Player::position() +{ + return 0; +} + +float Player::volume() +{ + return -1; +} + +QPixmap Player::artwork() +{ + return QPixmap(); +} + +bool Player::canPlay() +{ + return false; +} + +void Player::play() +{ +} + +bool Player::canPause() +{ + return false; +} + +void Player::pause() +{ +} + +bool Player::canStop() +{ + return false; +} + +void Player::stop() +{ +} + +bool Player::canGoPrevious() +{ + return false; +} + +void Player::previous() +{ +} + +bool Player::canGoNext() +{ + return false; +} + +void Player::next() +{ +} + +bool Player::canSetVolume() +{ + return false; +} + +void Player::setVolume(qreal) +{ +} + +bool Player::canSeek() +{ + return false; +} + +void Player::seek(int) +{ +} + +void Player::setName(const QString& name) +{ + m_name = name; +} + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/player.h b/plasma/generic/dataengines/nowplaying/playerinterface/player.h new file mode 100644 index 00000000..9c2e0fcd --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/player.h @@ -0,0 +1,171 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLAYER_H +#define PLAYER_H + +#include +#include +#include +#include + +class PlayerFactory; + +/** + * Interface for getting information from and controlling a + * media player + */ +class Player : public QSharedData +{ +public: + typedef KSharedPtr Ptr; + + Player(PlayerFactory* factory = 0); + virtual ~Player(); + /** + * a pointer to the factory that created this player object + */ + PlayerFactory* factory() const; + /** + * The name of this player + */ + QString name() const; + /** + * Current state of the player + */ + enum State { + Playing, + Paused, + Stopped + }; + /** + * Whether the player is running and accessible + */ + virtual bool isRunning() = 0; + /** + * Current state of the player + * + * Undefined if !running() + * + * See State + */ + virtual State state() = 0; + /** Artist for current track. May be empty */ + virtual QString artist(); + /** Album for current track. May be empty */ + virtual QString album(); + /** Title of current track. May be empty */ + virtual QString title(); + /** + * Track number of current track. + * + * Note that this is the track on a CD or in an album, not + * the playlist position + * + * 0 if no track defined, or unknown. + */ + virtual int trackNumber(); + /** Comment for current track. May be empty */ + virtual QString comment(); + /** Genre of current track. May be empty */ + virtual QString genre(); + /** Lyrics of current track. May be empty */ + virtual QString lyrics(); + /** + * Length of current track in seconds. + * + * 0 if unknown. + */ + virtual int length(); + /** + * Position of current track in seconds. + * + * 0 if unknown, not defined if Stopped. + */ + virtual int position(); + /** + * Current volume + * + * Value should be between 0 and 1 + * + * -1 if unknown + */ + virtual float volume(); + /** + * Album artwork + * + * Null (pm.isNull()) if none available + */ + virtual QPixmap artwork(); + + // Commands + + /** + * Play a track + */ + virtual bool canPlay(); + virtual void play(); + /** + * Pause the currently playing track + */ + virtual bool canPause(); + virtual void pause(); + /** + * Stop the currently playing track + * + * canStop() should usually be state() != Stopped if + * stop() is implemented + */ + virtual bool canStop(); + virtual void stop(); + /** + * Move to the previous track + */ + virtual bool canGoPrevious(); + virtual void previous(); + /** + * Move to the next track + */ + virtual bool canGoNext(); + virtual void next(); + + /** + * Set the volume + * + * Must be between 0 and 1 + */ + virtual bool canSetVolume(); + virtual void setVolume(qreal volume); + + /** + * Set the position (in seconds) + * + * Should be <= length() + */ + virtual bool canSeek(); + virtual void seek(int time); + +protected: + void setName(const QString& name); + +private: + QString m_name; + PlayerFactory* m_factory; +}; + +#endif // PLAYER_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.cpp new file mode 100644 index 00000000..53c1724d --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.cpp @@ -0,0 +1,26 @@ +#include "playerfactory.h" + +PlayerFactory::PlayerFactory(QObject* parent) + : QObject(parent) +{ + setObjectName( QLatin1String("PlayerFactory" )); +} + +PollingPlayerFactory::PollingPlayerFactory(QObject* parent) + : PlayerFactory(parent) +{ + setObjectName( QLatin1String("PollingPlayerFactory" )); +} + +DBusPlayerFactory::DBusPlayerFactory(QObject* parent) + : PlayerFactory(parent) +{ + setObjectName( QLatin1String("DBusPlayerFactory" )); +} + +Player::Ptr DBusPlayerFactory::create(const QString& serviceName) +{ + return create(QVariantList() << QVariant(serviceName)); +} + +#include "playerfactory.moc" diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.h b/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.h new file mode 100644 index 00000000..27371f31 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/playerfactory.h @@ -0,0 +1,81 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ + +#ifndef PLAYERFACTORY_H +#define PLAYERFACTORY_H + +#include +#include + +#include "player.h" + +/** + * A player factory that creates players. + */ +class PlayerFactory : public QObject +{ + Q_OBJECT +public: + PlayerFactory(QObject* parent = 0); + /** + * Create a player. + * + * Returns 0 if a valid player could not be created. + */ + virtual Player::Ptr create(const QVariantList& args = QVariantList()) = 0; +}; + +/** + * A player factory that is polled. + */ +class PollingPlayerFactory : public PlayerFactory +{ + Q_OBJECT +public: + PollingPlayerFactory(QObject* parent = 0); + /** + * Whether create(args) will return a player + * + * Note that just because this returns true, it + * should not be assumed that create(args) will not + * return 0. However, if this returns false, + * it can be assumed that create(args) will always + * return 0. + */ + virtual bool exists(const QVariantList& args = QVariantList()) = 0; +}; + +/** + * A player factory that creates players based on a + * DBus service. + */ +class DBusPlayerFactory : public PlayerFactory +{ + Q_OBJECT +public: + DBusPlayerFactory(QObject* parent = 0); + /** + * Whether the given dbus service name is a service + * for this player + */ + virtual bool matches(const QString& serviceName) = 0; + // don't let the QString overload hide this + virtual Player::Ptr create(const QVariantList& args = QVariantList()) = 0; + Player::Ptr create(const QString& serviceName); +}; + +#endif // PLAYERFACTORY_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.cpp new file mode 100644 index 00000000..6aa65f1d --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.cpp @@ -0,0 +1,77 @@ +#include "pollingwatcher.h" + +#include + +#include + +#include "player.h" +#include "playerfactory.h" + +PollingWatcher::PollingWatcher(QObject* parent) + : QObject(parent), + m_timer(0) +{ + setObjectName( QLatin1String("PollingWatcher" )); +} + +QList PollingWatcher::players() +{ + return m_players.values(); +} + +void PollingWatcher::addFactory(PollingPlayerFactory* factory) +{ + if (factory->exists()) { + Player::Ptr player = factory->create(); + if (!player.isNull()) { + m_players.insert(player); + m_usedFactories.insert(factory); + emit newPlayer(player); + } else { + kWarning() << "Failed to create a player"; + m_polledFactories.insert(factory); + } + } else { + m_polledFactories.insert(factory); + } + + if (!m_timer) { + m_timer = new QTimer(this); + m_timer->setInterval(5000); + connect(m_timer, SIGNAL(timeout()), this, SLOT(checkPlayers())); + m_timer->start(); + } +} + +void PollingWatcher::checkPlayers() +{ + foreach (Player::Ptr player, m_players) { + if (!player->isRunning()) { + m_players.remove(player); + PollingPlayerFactory* factory = + qobject_cast(player->factory()); + if (factory) { + m_usedFactories.remove(factory); + m_polledFactories.insert(factory); + } else { + kWarning() << "Missing factory for player" << player->name(); + } + emit playerDisappeared(player); + } + } + foreach (PollingPlayerFactory* factory, m_polledFactories) { + if (factory->exists()) { + Player::Ptr player = factory->create(); + if (!player.isNull()) { + m_players.insert(player); + m_polledFactories.remove(factory); + m_usedFactories.insert(factory); + emit newPlayer(player); + } else { + kWarning() << "Failed to create a player"; + } + } + } + m_timer->start(); +} + diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.h b/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.h new file mode 100644 index 00000000..34446da9 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/pollingwatcher.h @@ -0,0 +1,71 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#ifndef POLLINGWATCHER_H +#define POLLINGWATCHER_H + + +#include +#include +#include + +#include "player.h" + +class QTimer; + +class PollingPlayerFactory; + +class PollingWatcher : public QObject +{ + Q_OBJECT + +public: + PollingWatcher(QObject* parent = 0); + + QList players(); + + /** + * Adds a service to watch for. + * + * @param factory the factory for the player + */ + void addFactory(PollingPlayerFactory* factory); + +Q_SIGNALS: + /** + * A new player is available + */ + void newPlayer(Player::Ptr player); + /** + * A previously existing player is no longer available + * + * @param player the now-invalid player + */ + void playerDisappeared(Player::Ptr player); + +private Q_SLOTS: + void checkPlayers(); + +private: + // the factories we are waiting for player to appear on + QSet m_polledFactories; + // the factories we have a player for + QSet m_usedFactories; + QSet m_players; + QTimer* m_timer; +}; + +#endif // POLLINGWATCHER_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/xmms.cpp b/plasma/generic/dataengines/nowplaying/playerinterface/xmms.cpp new file mode 100644 index 00000000..1c344621 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/xmms.cpp @@ -0,0 +1,181 @@ +/* + * Copyright 2007 Alex Merry + * + * Based on Xmms support in the Kopete Now Listening plugin + * Copyright 2002 by Will Stephenson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "xmms.h" +#include "xmms_p.h" + +#include + +#include + +XmmsFactory::XmmsFactory(QObject* parent) + : PollingPlayerFactory(parent) +{ + setObjectName( QLatin1String("XmmsFactory" )); +} + +Player::Ptr XmmsFactory::create(const QVariantList& args) +{ + int session = 0; + if (!args.isEmpty() && args.first().canConvert()) { + session = args.first().toInt(); + if (session < 0) { + return Player::Ptr(0); + } + } + if (xmms_remote_is_running(session)) { + Xmms* player = new Xmms(session, this); + kDebug() << "Creating a player for XMMS session" << session; + return Player::Ptr(player); + } + return Player::Ptr(0); +} + +bool XmmsFactory::exists(const QVariantList& args) +{ + int session = 0; + if (!args.isEmpty() && args.first().canConvert()) { + session = args.first().toInt(); + } + return (session >= 0) && xmms_remote_is_running(session); +} + + + + + +Xmms::Xmms(int session, PlayerFactory* factory) + : Player(factory), + m_session(session) +{ + if (m_session == 0) { + setName("XMMS"); + } else { + setName("XMMS" + QString::number(m_session)); + } +} + +Xmms::~Xmms() +{ +} + +bool Xmms::isRunning() +{ + return xmms_remote_is_running(m_session); +} + +Player::State Xmms::state() +{ + if (xmms_remote_is_paused(m_session)) { + return Paused; + } else if (xmms_remote_is_playing(m_session)) { + return Playing; + } + return Stopped; +} + +QString Xmms::artist() +{ + // let's hope no-one changes the default title string + QString track = xmms_remote_get_playlist_title(m_session, xmms_remote_get_playlist_pos(0)); + return track.section(" - ", 0, 0); +} + +QString Xmms::album() +{ + return QString(); +} + +QString Xmms::title() +{ + // let's hope no-one changes the default title string + QString track = xmms_remote_get_playlist_title(m_session, xmms_remote_get_playlist_pos(0)); + return track.section(" - ", -1, -1); +} + +int Xmms::trackNumber() +{ + // we can get the playlist pos, but that's not what we mean by "trackNumber" + return 0; +} + +QString Xmms::comment() +{ + return QString(); +} + +QString Xmms::genre() +{ + return QString(); +} + +int Xmms::length() +{ + return xmms_remote_get_playlist_time(m_session, xmms_remote_get_playlist_pos(0)); +} + +int Xmms::position() +{ + return xmms_remote_get_output_time(m_session); +} + +float Xmms::volume() +{ + return xmms_remote_get_main_volume(m_session); +} + +void Xmms::play() +{ + xmms_remote_play(m_session); +} + +void Xmms::pause() +{ + xmms_remote_pause(m_session); +} + +void Xmms::stop() +{ + xmms_remote_stop(m_session); +} + +void Xmms::previous() +{ + xmms_remote_playlist_prev(m_session); +} + +void Xmms::next() +{ + xmms_remote_playlist_next(m_session); +} + +void Xmms::setVolume(qreal volume) +{ + xmms_remote_set_main_volume(m_session, volume); +} + +void Xmms::seek(int time) +{ + xmms_remote_jump_to_time(m_session, time); +} + + +#include "xmms.moc" diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/xmms.h b/plasma/generic/dataengines/nowplaying/playerinterface/xmms.h new file mode 100644 index 00000000..8e58c736 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/xmms.h @@ -0,0 +1,34 @@ +/* + * Copyright 2007 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef XMMS_H +#define XMMS_H + +#include "playerfactory.h" + +class XmmsFactory : public PollingPlayerFactory +{ + Q_OBJECT + +public: + explicit XmmsFactory(QObject* parent = 0); + Player::Ptr create(const QVariantList& args = QVariantList()); + bool exists(const QVariantList& args = QVariantList()); +}; + +#endif // XMMS_H diff --git a/plasma/generic/dataengines/nowplaying/playerinterface/xmms_p.h b/plasma/generic/dataengines/nowplaying/playerinterface/xmms_p.h new file mode 100644 index 00000000..10a6e513 --- /dev/null +++ b/plasma/generic/dataengines/nowplaying/playerinterface/xmms_p.h @@ -0,0 +1,62 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see . + */ +#ifndef XMMS_P_H +#define XMMS_P_H + +#include "xmms.h" +#include "player.h" + +class Xmms : public Player +{ +public: + explicit Xmms(int session = 0, PlayerFactory* factory = 0); + ~Xmms(); + + bool isRunning(); + State state(); + QString artist(); + QString album(); + QString title(); + int trackNumber(); + QString comment(); + QString genre(); + int length(); + int position(); + float volume(); + + bool canPlay() { return state() != Playing; } + void play(); + bool canPause() { return true; } + void pause(); + bool canStop() { return state() != Stopped; } + void stop(); + bool canGoPrevious() { return true; } + void previous(); + bool canGoNext() { return true; } + void next(); + + bool canSetVolume() { return true; } + void setVolume(qreal volume); + + bool canSeek() { return state() != Stopped; } + void seek(int time); + +private: + int m_session; +}; + +#endif // XMMS_P_H diff --git a/plasma/generic/dataengines/places/CMakeLists.txt b/plasma/generic/dataengines/places/CMakeLists.txt new file mode 100644 index 00000000..016d6dc4 --- /dev/null +++ b/plasma/generic/dataengines/places/CMakeLists.txt @@ -0,0 +1,24 @@ +set(places_engine_SRCS + placesengine.cpp + placeservice.cpp + setupdevicejob.cpp +) + +AUTOMOC4_MOC_HEADERS(plasma_engine_places modeljob.h) + +kde4_add_plugin(plasma_engine_places ${places_engine_SRCS}) + +target_link_libraries(plasma_engine_places + plasma + ${KDE4_KIO_LIBS} + ${KDE4_KFILE_LIBS} + ${KDE4_SOLID_LIBS} +) + +install(TARGETS plasma_engine_places + DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-places.desktop + DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES org.kde.places.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services ) + diff --git a/plasma/generic/dataengines/places/TODO b/plasma/generic/dataengines/places/TODO new file mode 100644 index 00000000..5eeb9434 --- /dev/null +++ b/plasma/generic/dataengines/places/TODO @@ -0,0 +1,2 @@ +* periodic refresh? KFilePlacesModel doesn't broadcast + device setups etc. between programs diff --git a/plasma/generic/dataengines/places/jobs.h b/plasma/generic/dataengines/places/jobs.h new file mode 100644 index 00000000..e6867cd7 --- /dev/null +++ b/plasma/generic/dataengines/places/jobs.h @@ -0,0 +1,101 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#ifndef JOBS_H +#define JOBS_H + +#include "modeljob.h" + +class AddEditPlaceJob : public ModelJob +{ +public: + AddEditPlaceJob(KFilePlacesModel* model, + QModelIndex index, + const QVariantMap& parameters, + QObject* parent = 0) + : ModelJob(parent, model, index, (index.isValid() ? "Edit" : "Add"), parameters) + , m_text(parameters["Name"].toString()) + , m_url(parameters["Url"].toUrl()) + , m_icon(parameters["Icon"].toString()) + {} + + void start() + { + if (m_index.isValid()) { + m_model->editPlace(m_index, m_text, m_url, m_icon); + } else { + m_model->addPlace(m_text, m_url, m_icon); + } + } + +private: + QString m_text; + KUrl m_url; + QString m_icon; +}; + +class RemovePlaceJob : public ModelJob +{ +public: + RemovePlaceJob(KFilePlacesModel* model, const QModelIndex& index, + QObject* parent) + : ModelJob(parent, model, index, "Remove") + {} + + void start() + { + m_model->removePlace(m_index); + } +}; + +class ShowPlaceJob : public ModelJob +{ +public: + ShowPlaceJob(KFilePlacesModel* model, const QModelIndex& index, + bool show = true, QObject* parent = 0) + : ModelJob(parent, model, index, (show ? "Show" : "Hide")) + , m_show(show) + {} + + void start() + { + m_model->setPlaceHidden(m_index, m_show); + } + +private: + bool m_show; +}; + +class TeardownDeviceJob : public ModelJob +{ +public: + TeardownDeviceJob(KFilePlacesModel* model, const QModelIndex& index, + QObject* parent = 0) + : ModelJob(parent, model, index, "Teardown Device") + {} + + void start() + { + m_model->requestTeardown(m_index); + } +}; + +#include "setupdevicejob.h" + +#endif // JOBS_H + diff --git a/plasma/generic/dataengines/places/modeljob.h b/plasma/generic/dataengines/places/modeljob.h new file mode 100644 index 00000000..b505e371 --- /dev/null +++ b/plasma/generic/dataengines/places/modeljob.h @@ -0,0 +1,44 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#ifndef MODELJOB_H +#define MODELJOB_H + +#include +#include + +class ModelJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + ModelJob(QObject* parent, KFilePlacesModel* model, + const QModelIndex& index, const QString& operation, + const QVariantMap& parameters = QVariantMap()) + : ServiceJob(QString::number(index.row()), operation, parameters, parent) + , m_model(model) + , m_index(index) + {} + +protected: + KFilePlacesModel* m_model; + QModelIndex m_index; +}; + +#endif // MODELJOB_H + diff --git a/plasma/generic/dataengines/places/org.kde.places.operations b/plasma/generic/dataengines/places/org.kde.places.operations new file mode 100644 index 00000000..c33e8318 --- /dev/null +++ b/plasma/generic/dataengines/places/org.kde.places.operations @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/places/placesengine.cpp b/plasma/generic/dataengines/places/placesengine.cpp new file mode 100644 index 00000000..52139612 --- /dev/null +++ b/plasma/generic/dataengines/places/placesengine.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2008 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "placesengine.h" + +#include + +#include +#include + +#include "placeservice.h" + +PlacesEngine::PlacesEngine(QObject *parent, const QVariantList &args) + : Plasma::DataEngine(parent, args) +{ + connect(&m_placesModel, SIGNAL(modelReset()), + this, SLOT(modelReset())); + connect(&m_placesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT(dataChanged(QModelIndex,QModelIndex))); + connect(&m_placesModel, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(placesAdded(QModelIndex,int,int))); + connect(&m_placesModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(placesRemoved(QModelIndex,int,int))); + + sendAllData(); +} + +PlacesEngine::~PlacesEngine() +{ +} + +void PlacesEngine::modelReset() +{ + removeAllSources(); +} + +void PlacesEngine::placesAdded(const QModelIndex&, int start, int end) +{ + sendData(start, end); +} + +void PlacesEngine::placesRemoved(const QModelIndex&, int start, int end) +{ + kDebug() << "Places" << start << "through" << end << "removed"; + for (int index = start; index <= end; index++) { + removeSource(QString::number(index)); + } +} + +void PlacesEngine::dataChanged(const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + sendData(topLeft.row(), bottomRight.row()); +} + +void PlacesEngine::sendAllData() +{ + sendData(0, m_placesModel.rowCount() - 1); +} + +Plasma::Service *PlacesEngine::serviceForSource(const QString &source) +{ + const int row = source.toInt(); + const QModelIndex index = m_placesModel.index(row, 0); + if (index.isValid()) { + return new PlaceService(this, &m_placesModel, index); + } + + return DataEngine::serviceForSource(source); +} + +void PlacesEngine::sendData(int start, int end) +{ + for (int row = start; row <= end; ++row) { + const QModelIndex index = m_placesModel.index(row, 0); + + Data map; + + const QString source = QString::number(row); + + setData(source, "name", m_placesModel.text(index)); + setData(source, "url", m_placesModel.url(index).url()); + setData(source, "icon", m_placesModel.icon(index)); + setData(source, "hidden", + m_placesModel.data(index, KFilePlacesModel::HiddenRole)); + setData(source, "setupNeeded", + m_placesModel.data(index, KFilePlacesModel::SetupNeededRole)); + setData(source, "isDevice", + m_placesModel.deviceForIndex(index).isValid()); + + const QString path = m_placesModel.url(index).path(); + if (!path.isEmpty()) { + // We can't get free space for unmounted volumes :-( + KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(path); + setData(source, "kBSize", info.size()/1024); // deprecated + setData(source, "kBUsed", info.used()/1024); // deprecated + setData(source, "kBAvailable", info.available()/1024); // deprecated + setData(source, "size (bytes)", info.size()); + setData(source, "used (bytes)", info.used()); + setData(source, "available (bytes)", info.available()); + } + } +} + +K_EXPORT_PLASMA_DATAENGINE(places, PlacesEngine) + +#include "placesengine.moc" + diff --git a/plasma/generic/dataengines/places/placesengine.h b/plasma/generic/dataengines/places/placesengine.h new file mode 100644 index 00000000..e787dbd7 --- /dev/null +++ b/plasma/generic/dataengines/places/placesengine.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLACESENGINE_H +#define PLACESENGINE_H + +#include + +#include + +class PlacesEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + PlacesEngine(QObject* parent, const QVariantList& args); + ~PlacesEngine(); + + Plasma::Service *serviceForSource(const QString &source); + +private Q_SLOTS: + // KFilePlacesModel + void modelReset(); + void placesAdded(const QModelIndex& parent, int start, int end); + void placesRemoved(const QModelIndex& parent, int start, int end); + void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + +private: + void sendData(int start, int end); + void sendAllData(); + + KFilePlacesModel m_placesModel; +}; + + +#endif // PLACESENGINE_H diff --git a/plasma/generic/dataengines/places/placeservice.cpp b/plasma/generic/dataengines/places/placeservice.cpp new file mode 100644 index 00000000..1765c3fa --- /dev/null +++ b/plasma/generic/dataengines/places/placeservice.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "placeservice.h" +#include "jobs.h" + +#include + + +PlaceService::PlaceService(QObject* parent, + KFilePlacesModel* model, + QModelIndex index) + : Plasma::Service(parent), + m_model(model), + m_index(index) +{ + setName("org.kde.places"); + if (m_index.isValid()) { + Q_ASSERT(m_index.model() == model); + setDestination(QString::number(m_index.row())); + kDebug() << "Created a place service for" << destination(); + } else { + kDebug() << "Created a dead place service"; + } +} + +Plasma::ServiceJob* PlaceService::createJob(const QString& operation, + QMap& parameters) +{ + kDebug() << "Job" << operation << "with arguments" << parameters << "requested"; + if (operation == "Add") { + return new AddEditPlaceJob(m_model, m_index, parameters, this); + } else if (operation == "Edit") { + return new AddEditPlaceJob(m_model, QModelIndex(), parameters, this); + } else if (operation == "Remove") { + return new RemovePlaceJob(m_model, m_index, this); + } else if (operation == "Hide") { + return new ShowPlaceJob(m_model, m_index, false, this); + } else if (operation == "Show") { + return new ShowPlaceJob(m_model, m_index, true, this); + } else if (operation == "Setup Device") { + return new SetupDeviceJob(m_model, m_index, this); + } else if (operation == "Teardown Device") { + return new TeardownDeviceJob(m_model, m_index, this); + } else { + // FIXME: BAD! No! + return 0; + } +} + +#include "placeservice.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/places/placeservice.h b/plasma/generic/dataengines/places/placeservice.h new file mode 100644 index 00000000..7bea7624 --- /dev/null +++ b/plasma/generic/dataengines/places/placeservice.h @@ -0,0 +1,45 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLACESERVICE_H +#define PLACESERVICE_H + +#include + +#include "placesengine.h" + +class PlaceService : public Plasma::Service +{ + Q_OBJECT + +public: + PlaceService(QObject* parent, + KFilePlacesModel* model, + QModelIndex index = QModelIndex()); + +protected: + Plasma::ServiceJob* createJob(const QString& operation, + QMap& parameters); + +private: + KFilePlacesModel* m_model; + QModelIndex m_index; +}; + +#endif // PLACESERVICE_H diff --git a/plasma/generic/dataengines/places/plasma-dataengine-places.desktop b/plasma/generic/dataengines/places/plasma-dataengine-places.desktop new file mode 100644 index 00000000..4ed4e029 --- /dev/null +++ b/plasma/generic/dataengines/places/plasma-dataengine-places.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Name=Places +Name[ar]=الأماكن +Name[ast]=Llugares +Name[be@latin]=Miescy +Name[bg]=Места +Name[bn]=স্থান +Name[bs]=mjesta +Name[ca]=Llocs +Name[ca@valencia]=Llocs +Name[cs]=Místa +Name[csb]=Place +Name[da]=Steder +Name[de]=Orte +Name[el]=Τοποθεσίες +Name[en_GB]=Places +Name[eo]=Lokoj +Name[es]=Lugares +Name[et]=Asukohad +Name[eu]=Tokiak +Name[fi]=Sijainnit +Name[fr]=Emplacements +Name[fy]=Places +Name[ga]=Áiteanna +Name[gl]=Lugares +Name[gu]=જગ્યાઓ +Name[he]=מקומות +Name[hi]=स्थान +Name[hne]=प्लेसेस +Name[hr]=Mjesta +Name[hu]=Helyek +Name[ia]=Placias +Name[id]=Tempat +Name[is]=Staðir +Name[it]=Risorse +Name[ja]=場所 +Name[ka]=ადგილები +Name[kk]=Орындар +Name[km]=កន្លែង +Name[kn]=ಸ್ಥಳಗಳು +Name[ko]=위치 +Name[ku]=Cih +Name[lt]=Vietos +Name[lv]=Vietas +Name[mai]=स्थान +Name[mk]=Места +Name[ml]=സ്ഥലങ്ങള്‍ +Name[mr]=जागा +Name[nb]=Steder +Name[nds]=Steden +Name[nl]=Locaties +Name[nn]=Stader +Name[or]=ସ୍ଥାନଗୁଡ଼ିକ +Name[pa]=ਥਾਵਾਂ +Name[pl]=Miejsca +Name[pt]=Locais +Name[pt_BR]=Locais +Name[ro]=Locuri +Name[ru]=Точки входа +Name[si]=ස්ථාන +Name[sk]=Miesta +Name[sl]=Mesta +Name[sr]=места +Name[sr@ijekavian]=мјеста +Name[sr@ijekavianlatin]=mjesta +Name[sr@latin]=mesta +Name[sv]=Platser +Name[ta]=Places +Name[tg]=Ҷойҳо +Name[th]=ที่หลัก ๆ +Name[tr]=Konumlar +Name[ug]=ئورۇنلار +Name[uk]=Місця +Name[wa]=Plaeces +Name[x-test]=xxPlacesxx +Name[zh_CN]=位置 +Name[zh_TW]=地方 +Comment=Places, as seen in the file manager and in file dialogs. +Comment[ar]=الأماكن كما تُرى في مدير الملفات وحوارات الملف. +Comment[ast]=Llugares, como se ven nel xestor de ficheros y nos diálogos de ficheros. +Comment[bg]=Местата, както се виждат във файловия мениджър и прозорците. +Comment[bs]=Mjesta, kako se vide u menadžeru datoteka i datotečnim dijalozima. +Comment[ca]=Llocs, com es veuen en el gestor de fitxers i en els diàlegs de fitxer. +Comment[ca@valencia]=Llocs, com es veuen en el gestor de fitxers i en els diàlegs de fitxer. +Comment[cs]=Umístění, jak je vidíte ve správci souborů a souborových dialozích. +Comment[da]=Steder, som de ses i filhåndteringen og fildialoger. +Comment[de]=Orte, wie sie im Dateimanager und in Dateiauswahl-Dialogen zu sehen sind. +Comment[el]=Τοποθεσίες, όπως εμφανίζονται στη διαχείριση αρχείων και στους διαλόγους αρχείων. +Comment[en_GB]=Places, as seen in the file manager and in file dialogues. +Comment[es]=Lugares, como se ven en el gestor de archivos y en los diálogos de archivos. +Comment[et]=Asukohad, nagu neid näeb failihalduris ja -dialoogides. +Comment[eu]=Tokiak, fitxategi-kudeatzailean eta fitxategien elkarrizketa-koadroetan ikusi bezala. +Comment[fi]=Paikat, kuten nähdään tiedostohallinnassa ja tiedostovalintaikkunoissa. +Comment[fr]=Emplacements, tel que vus par le gestionnaire de fichiers et les boîtes de dialogue de fichiers. +Comment[fy]=Plakken, lykas yn de triembehearder en triem dialogen. +Comment[ga]=Áiteanna, mar a fheictear sa bhainisteoir comhad agus i ndialóga comhad. +Comment[gl]=Os lugares tal como se ven no xestor de ficheiros e nos diálogos de ficheiros. +Comment[he]=מיקומים, כפי שהם נראים במנהל הקבצים ובתיבות דו־שיח של קבצים. +Comment[hr]=Mjesta, kao što ih se vidi u pregledniku datoteka i dialozima za izbor datoteka +Comment[hu]=Helyek panel (ahogy a fájlkezelőben és a fájlmegnyitó ablakokban látható). +Comment[ia]=Placias, tal como vidite in le gerente de file e in le dialogos de file +Comment[id]=Tempat, seperti terlihat di manajer berkas dan di dialog berkas. +Comment[is]=Staðir, eins og sýnt er í skráastjóra og samskiptagluggum. +Comment[it]=Risorse, come nel gestore dei file e nelle finestre di selezione dei file. +Comment[ja]=ファイルマネージャやファイル選択ダイアログに表示される場所 +Comment[kk]=Файл менеджерде және диалогында көрсетілетін орындар. +Comment[km]=កន្លែង ដូច​ដែល​បានឃើញ​នៅ​ក្នុង​កម្មវិធី​គ្រប់គ្រង​ឯកសារ និង​ប្រអប់​ឯកសារ ។ +Comment[kn]=ಕಡತ ವ್ಯವಸ್ಥಾಪಕದಲ್ಲಿ ಹಾಗು ಕಡತ ಸಂವಾದಗಳಲ್ಲಿ ಕಾಣಿಸುವ ಸ್ಥಳಗಳು. +Comment[ko]=파일 관리자와 파일 대화 상자에 나타나는 위치입니다. +Comment[lt]=Vietos, kaip jos matomos failų tvarkyklėje ir failų dialoguose. +Comment[lv]=Vietas, kas redzamas failu pārvaldniekā un failu atvēršanas logos. +Comment[mk]=Места, како што се гледаат во менаџерот на датотеки и во дијалозите за датотеки +Comment[ml]=ഫയല്‍ കാര്യസ്ഥനിലും ഫയല്‍ സംഭാഷണങ്ങളിലും കാണുന്നപോലെയുള്ള ഇടങ്ങള്‍. +Comment[mr]=फाईल व्यवस्थापक व फाईल संवादामध्ये दिसणाऱ्या जागा. +Comment[nb]=Steder, som sett i filbehandleren og fildialogene. +Comment[nds]=Steden, as för den Dateipleger un binnen Dateidialogen +Comment[nl]=Plaatsen, zoals deze gezien worden in de bestandsbeheerder en in bestandsdialogen. +Comment[nn]=Stader, slik ein kan sjå dei i filhandsamaren og dialogvindauge for filer. +Comment[pa]=ਥਾਵਾਂ, ਜਿਵੇਂ ਕਿ ਫਾਇਲ ਮੈਨੇਜਰ ਅਤੇ ਹੋਰ ਫਾਇਲ ਡਾਇਲਾਗ ਵਿੱਚ ਦਿਸਦੀਆਂ ਹਨ। +Comment[pl]=Miejsca, widziane tak jak w przeglądarce plików i oknach dialogowych plików. +Comment[pt]=Os locais vistos nas janelas e gestores de ficheiros. +Comment[pt_BR]=Locais, como visto no gerenciador de arquivo e nos diálogos de arquivo. +Comment[ro]=Locuri, așa cum sînt văzute în gestionarul de fișiere și în dialogurile de fișier. +Comment[ru]=Точки входа, показываемые в диспетчере файлов и файловых диалогах. +Comment[si]=ස්ථාන, ගොනු පාලකයේ මෙන්ම ගොනු සංවාද වල පෙනෙන ආකාරයට +Comment[sk]=Miesta, ako sú vidieť v správcovi súborov a súborových dialógoch. +Comment[sl]=Mesta, kot jih je mogoče videti v upravljalniku datotek in pogovornih oknih za datoteke. +Comment[sr]=Места, како се виде у менаџеру фајлова и фајл дијалозима. +Comment[sr@ijekavian]=Места, како се виде у менаџеру фајлова и фајл дијалозима. +Comment[sr@ijekavianlatin]=Mesta, kako se vide u menadžeru fajlova i fajl dijalozima. +Comment[sr@latin]=Mesta, kako se vide u menadžeru fajlova i fajl dijalozima. +Comment[sv]=Platser som visas i filhanterare och fildialogrutor. +Comment[th]=ที่หลัก ๆ ที่จะถูกเห็นในเครื่องมือจัดการแฟ้มและในกล่องเลือกแฟ้ม +Comment[tr]=Konumlar, dosya yöneticisinde ve dosya açma pencerelerinde görünür. +Comment[ug]=ھۆججەت باشقۇرغۇچ ۋە ھۆججەت سۆزلەشكۈدە كۆرەلەيدىغان ئورۇننى تەمىنلەيدۇ. +Comment[uk]=Місця, так, як їх показано у менеджері файлів і діалогових вікнах. +Comment[wa]=Eplaeçmints, come i sont veyous e manaedjeu des fitchîs eyet ezès purneas di dvize des fitchîs. +Comment[x-test]=xxPlaces, as seen in the file manager and in file dialogs.xx +Comment[zh_CN]=提供文件管理器和文件对话框里能看到的位置。 +Comment[zh_TW]=在檔案管理員與檔案對話框中看到的「地方」項目。 +Type=Service +Icon=folder-favorites + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_places + +X-KDE-PluginInfo-Author=Alex Merry +X-KDE-PluginInfo-Email=alex.merry@kdemail.net +X-KDE-PluginInfo-Name=places +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=System +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/dataengines/places/setupdevicejob.cpp b/plasma/generic/dataengines/places/setupdevicejob.cpp new file mode 100644 index 00000000..1bd99f8d --- /dev/null +++ b/plasma/generic/dataengines/places/setupdevicejob.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "setupdevicejob.h" + +void SetupDeviceJob::setupDone(const QModelIndex& index, bool success) +{ + if (index == m_index) { + setError(!success); + emitResult(); + } +} + +void SetupDeviceJob::setupError(const QString& message) +{ + if (!error() || errorText().isEmpty()) { + setErrorText(message); + } +} + +#include "setupdevicejob.moc" + +// vim: sw=4 sts=4 et tw=100 diff --git a/plasma/generic/dataengines/places/setupdevicejob.h b/plasma/generic/dataengines/places/setupdevicejob.h new file mode 100644 index 00000000..facf9e39 --- /dev/null +++ b/plasma/generic/dataengines/places/setupdevicejob.h @@ -0,0 +1,49 @@ +/* + * Copyright 2008 Alex Merry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#ifndef SETUPDEVICEJOB_H +#define SETUPDEVICEJOB_H + +#include "modeljob.h" + +class SetupDeviceJob : public ModelJob +{ + Q_OBJECT + +public: + SetupDeviceJob(KFilePlacesModel* model, QModelIndex index, + QObject* parent = 0) + : ModelJob(parent, model, index, "Setup Device") + { + connect(model, SIGNAL(setupDone(QModelIndex,bool)), + SLOT(setupDone(QModelIndex,bool))); + connect(model, SIGNAL(errorMessage(QString)), + SLOT(setupError(QString))); + } + + void start() + { + m_model->requestSetup(m_index); + } + +private slots: + void setupDone(const QModelIndex& index, bool success); + void setupError(const QString& message); +}; + +#endif // SETUPDEVICEJOB_H diff --git a/plasma/generic/dataengines/powermanagement/CMakeLists.txt b/plasma/generic/dataengines/powermanagement/CMakeLists.txt new file mode 100644 index 00000000..acd73b7f --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/CMakeLists.txt @@ -0,0 +1,17 @@ + +set(powermanagement_engine_SRCS + powermanagementengine.cpp + powermanagementjob.cpp + powermanagementservice.cpp +) + +set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml) +QT4_ADD_DBUS_INTERFACE(powermanagement_engine_SRCS ${krunner_xml} krunner_interface) + +kde4_add_plugin(plasma_engine_powermanagement ${powermanagement_engine_SRCS}) +target_link_libraries(plasma_engine_powermanagement ${KDE4_KDECORE_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_KIDLETIME_LIBRARY} kworkspace) + +install(TARGETS plasma_engine_powermanagement DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-powermanagement.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES powermanagementservice.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/powermanagement/README.txt b/plasma/generic/dataengines/powermanagement/README.txt new file mode 100644 index 00000000..c657bc9f --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/README.txt @@ -0,0 +1,13 @@ +TODO: +====== +- Sleepstates don't match what solidshell reports +- ac plug state does not get updated +- this engine probably shares some functionality with + the solidengine, have a look at that and evaluate + +Notes +====== +There's a battery applet (also in kdebase) which uses this engine + +-- sebas + diff --git a/plasma/generic/dataengines/powermanagement/plasma-dataengine-powermanagement.desktop b/plasma/generic/dataengines/powermanagement/plasma-dataengine-powermanagement.desktop new file mode 100644 index 00000000..0e979a9a --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/plasma-dataengine-powermanagement.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +# ctxt: plasma data engine +Name=Power Management +Name[ar]=إدارة الطاقة +Name[ast]=Xestión d'enerxía +Name[bg]=Управление на захранването +Name[bn]=শক্তি ব্যবস্থাপনা +Name[bs]=upravljanje napajanjem +Name[ca]=Gestió d'energia +Name[ca@valencia]=Gestió d'energia +Name[cs]=Správa napájení +Name[csb]=Sprôwianié mòcą +Name[da]=Strømstyring +Name[de]=Energieverwaltung +Name[el]=Διαχείριση ενέργειας +Name[en_GB]=Power Management +Name[eo]=Energia administrado +Name[es]=Gestión de energía +Name[et]=Toitehaldus +Name[eu]=Energia-kudeaketa +Name[fi]=Virranhallinta +Name[fr]=Gestion de l'énergie +Name[fy]=Enerzjybehear +Name[ga]=Bainisteoireacht Cumhachta +Name[gl]=Xestión da enerxía +Name[gu]=પાવર વ્યવસ્થાપક +Name[he]=ניהול צריכת חשמל +Name[hi]=बिज़ली प्रबंधन +Name[hr]=Upravljanje potrošnjom energije +Name[hu]=Energiakezelő +Name[ia]=Gestion de energia +Name[id]=Manajemen Daya +Name[is]=Orkustýring +Name[it]=Gestione energetica +Name[ja]=電源管理 +Name[kk]=Қуаттандыруды басқару +Name[km]=ការ​គ្រប់គ្រង​ថាមពល​ +Name[kn]=ವಿದ್ಯುಚ್ಚಕ್ತಿಯ ನಿರ್ವಹಣೆ +Name[ko]=전원 관리 +Name[lt]=Energijos valdymas +Name[lv]=Energokontrole +Name[mk]=Менаџмент на енергија +Name[ml]=വൈദ്യുതി നടത്തിപ്പു് +Name[mr]=वीज व्यवस्थापन +Name[nb]=Strømstyring +Name[nds]=Stroomkuntrull +Name[nl]=Energiebeheer +Name[nn]=Straumstyring +Name[pa]=ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ +Name[pl]=Zarządzanie energią +Name[pt]=Gestão de Energia +Name[pt_BR]=Gerenciamento de energia +Name[ro]=Gestiunea alimentării +Name[ru]=Управление питанием +Name[si]=බල පරිපාලනය +Name[sk]=Správa napájania +Name[sl]=Upravljanje z energijo +Name[sr]=управљање напајањем +Name[sr@ijekavian]=управљање напајањем +Name[sr@ijekavianlatin]=upravljanje napajanjem +Name[sr@latin]=upravljanje napajanjem +Name[sv]=Strömsparhantering +Name[tg]=Идоракунии барқ +Name[th]=การจัดการพลังงาน +Name[tr]=Güç Yönetimi +Name[ug]=توك مەنبەسىنى باشقۇرۇش +Name[uk]=Керування живленням +Name[wa]=Manaedjmint di l' enerdjeye +Name[x-test]=xxPower Managementxx +Name[zh_CN]=电源管理 +Name[zh_TW]=電源管理 +Comment=Battery, AC, sleep and PowerDevil information. +Comment[ar]=معلومات البطارية والتيار المتناوب والنوم وعفريت الطاقة. +Comment[ast]=Información de batería, CA, hibernación y PowerDevil. +Comment[bg]=Данни за батерия, AC, приспиване и PowerDevil +Comment[bs]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju. +Comment[ca]=Informació de la bateria, AC, suspensió i del PowerDevil. +Comment[ca@valencia]=Informació de la bateria, AC, suspensió i del PowerDevil. +Comment[cs]=Informace o baterii, AC a uspání. +Comment[da]=Information om batteri, strømforsyning, dvale og PowerDevil. +Comment[de]=Informationen zu Akku, Netzanschluss, Ruhezustand und PowerDevil. +Comment[el]=Πληροφορίες μπαταρίας, AC, αδράνειας και PowerDevil +Comment[en_GB]=Battery, AC, sleep and PowerDevil information. +Comment[es]=Información de batería, CA, hibernación y PowerDevil. +Comment[et]=Aku, voolutoite, puhkeseisundi ja PowerDevili teave. +Comment[eu]=Bateria, korronte alternoa, loa eta PowerDevil-i buruzko informazioa. +Comment[fi]=Akku, vaihtovirta, nukkumis- ja PowerDevil-tiedot. +Comment[fr]=Batterie, chargeur, veille et informations sur PowerDevil +Comment[fy]=Batterij, AC, sliepe en PowerDevil ynformaasje +Comment[ga]=Faisnéis a bhaineann leis an gcadhnra, ceangal SA, codladh agus PowerDevil. +Comment[gl]=Información da batería, corrente, hibernación e PowerDevil. +Comment[he]=מידע אודות סוללה, צריכת חשמל, מצב שינה ו־PowerDevil. +Comment[hr]=Informacije o bateriji, adapteru, spavanju i PowerDevilu. +Comment[hu]=A telepek, a tápellátás és a PowerDevil energiakezelő jellemzői. +Comment[ia]=Batteria, AC, reposo e information de PowerDevil. +Comment[id]=Informasi Baterai, AC, tidur dan PowerDevil. +Comment[is]=Upplýsingar um raflöður, AC-straum, svæfingu og PowerDevil orkustýringarpúkann. +Comment[it]=Informazioni su batteria, alimentazione, sospensione e PowerDevil +Comment[ja]=バッテリ、商用電源、スリープ、PowerDevil の情報。 +Comment[kk]=Батарея, тоқ, ұйықтау күйі және PowerDevil мәліметі. +Comment[km]=ព័ត៌មាន ថ្ម AC ដេក និង​ PowerDevil ។ +Comment[kn]=ವಿದ್ಯುತ್ಕೋಶ, AC, ಜಡ ಹಾಗು PowerDevil ಮಾಹಿತಿ. +Comment[ko]=배터리, AC, 절전 모드 및 PowerDevil 정보입니다. +Comment[lt]=Akumuliatoriaus, AC, miego ir PowerDevil informacija. +Comment[lv]=Baterija, barošana, gulēšanas un PowerDevil informācija. +Comment[ml]=ബാറ്ററി, എസി, നിദ്ര പിന്നെ പവര്‍ഡെവിള്‍ എന്നീ വിവരങ്ങള്‍. +Comment[mr]=बॅटरी, AC, व पॉवरडेव्हिल माहिती. +Comment[nb]=Informasjon om batteri, nettstrøm, hvilemodus og PowerDevil. +Comment[nds]=Batterie-, Stroom-, Utsett- un Stroomdüvel-Infos +Comment[nl]=Accu-, stroomvoorziening-, slaapstand- en PowerDevil-informatie. +Comment[nn]=Informasjon om batteristatus, lading og liknande. +Comment[pa]=ਬੈਟਰੀ, ਏਸੀ, ਸਲੀਪ ਅਤੇ ਪਾਵਰਡਿਵੈਲ ਜਾਣਕਾਰੀ ਹੈ। +Comment[pl]=Bateria, zasilacz, usypianie i informacje PowerDevil. +Comment[pt]=Informação sobre a bateria, corrente eléctrica e o PowerDevil. +Comment[pt_BR]=Bateria, adaptador de energia, dormir e informação do PowerDevil. +Comment[ro]=Informații despre acumulator, priză, adormire și PowerDevil. +Comment[ru]=Информация о батарее, электрической сети и PowerDevil. +Comment[si]=බැටරි, AC, නිද්‍රා හා PowerDevil තොරතුරු +Comment[sk]=Informácie o batérii, AC a uspaní. +Comment[sl]=Podatki o baterijah, omrežnem napajanju, pripravljenosti in PowerDevilu. +Comment[sr]=Подаци из Струјног ђавола о батерији, АЦ‑у, и спавању. +Comment[sr@ijekavian]=Подаци из Струјног ђавола о батерији, АЦ‑у, и спавању. +Comment[sr@ijekavianlatin]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju. +Comment[sr@latin]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju. +Comment[sv]=Information om batteri, nätspänning, viloläge och Powerdevil. +Comment[tg]=Батарея, AC, захираи барқ ва иттилооти PowerDevil. +Comment[th]=แบตเตอรี่, การเสียบปลั๊กไฟ, การพักเครื่อง และข้อมูลของ PowerDevil +Comment[tr]=Pil, Adaptör, uyku kipi ve PowerDevil bilgileri. +Comment[ug]=توكدان، ئۆزگىرىشچان توك مەنبەسى، سىستېما ئۇخلات ۋە PowerDevil ئۇچۇرىنى تەمىنلەيدۇ. +Comment[uk]=Акумулятор, мережеве живлення, відомості щодо присипляння і PowerDevil. +Comment[vi]=Thông tin pin, AC, chế độ ngủ và PowerDevil +Comment[wa]=Pondants et djondants sol batreye, l' AC, l' edoirmaedje eyet l' Diâle d' Enerdjeye. +Comment[x-test]=xxBattery, AC, sleep and PowerDevil information.xx +Comment[zh_CN]=提供电池、交流适配器、系统睡眠及 PowerDevil 信息。 +Comment[zh_TW]=電池、市電電源、睡眠模式與 PowerDevil 資訊。 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=preferences-system-power-management +X-KDE-Library=plasma_engine_powermanagement + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=powermanagement +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= diff --git a/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp b/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp new file mode 100644 index 00000000..341a0077 --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementengine.cpp @@ -0,0 +1,486 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007-2008 Sebastian Kuegler + * CopyRight 2007 Maor Vanmak + * Copyright 2008 Dario Freddi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "powermanagementengine.h" + +//solid specific includes +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "powermanagementservice.h" + +typedef QMap< QString, QString > StringStringMap; +Q_DECLARE_METATYPE(StringStringMap) + +PowermanagementEngine::PowermanagementEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) + , m_sources(basicSourceNames()) +{ + Q_UNUSED(args) + qDBusRegisterMetaType< StringStringMap >(); +} + +PowermanagementEngine::~PowermanagementEngine() +{} + +void PowermanagementEngine::init() +{ + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), + this, SLOT(deviceAdded(QString))); + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), + this, SLOT(deviceRemoved(QString))); + + // FIXME This check doesn't work, connect seems to always return true, hence the hack below + if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/BrightnessControl", + "org.kde.Solid.PowerManagement.Actions.BrightnessControl", + "brightnessChanged", this, + SLOT(screenBrightnessChanged(int)))) { + kDebug() << "error connecting to Brightness changes via dbus"; + brightnessControlsAvailableChanged(false); + } else { + brightnessControlsAvailableChanged(true); + } + + if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl", + "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl", + "keyboardBrightnessChanged", this, + SLOT(keyboardBrightnessChanged(int)))) { + kDebug() << "error connecting to Keyboard Brightness changes via dbus"; + keyboardBrightnessControlsAvailableChanged(false); + } else { + keyboardBrightnessControlsAvailableChanged(true); + } + + sourceRequestEvent("PowerDevil"); + + if (!QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", + "batteryRemainingTimeChanged", this, + SLOT(batteryRemainingTimeChanged(qulonglong)))) { + kDebug() << "error connecting to remaining time changes"; + } + } +} + +QStringList PowermanagementEngine::basicSourceNames() const +{ + QStringList sources; + sources << "Battery" << "AC Adapter" << "Sleep States" << "PowerDevil"; + return sources; +} + +QStringList PowermanagementEngine::sources() const +{ + return m_sources; +} + +bool PowermanagementEngine::sourceRequestEvent(const QString &name) +{ + if (name == "Battery") { + const QList listBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery); + m_batterySources.clear(); + + if (listBattery.isEmpty()) { + setData("Battery", "Has Battery", false); + return true; + } + + uint index = 0; + QStringList batterySources; + + foreach (const Solid::Device &deviceBattery, listBattery) { + const Solid::Battery* battery = deviceBattery.as(); + + const QString source = QString("Battery%1").arg(index++); + + batterySources << source; + m_batterySources[deviceBattery.udi()] = source; + + connect(battery, SIGNAL(chargeStateChanged(int,QString)), this, + SLOT(updateBatteryChargeState(int,QString))); + connect(battery, SIGNAL(chargePercentChanged(int,QString)), this, + SLOT(updateBatteryChargePercent(int,QString))); + connect(battery, SIGNAL(plugStateChanged(bool,QString)), this, + SLOT(updateBatteryPlugState(bool,QString))); + + // Set initial values + updateBatteryChargeState(battery->chargeState(), deviceBattery.udi()); + updateBatteryChargePercent(battery->chargePercent(), deviceBattery.udi()); + updateBatteryPlugState(battery->isPlugged(), deviceBattery.udi()); + updateBatteryPowerSupplyState(battery->isPowerSupply(), deviceBattery.udi()); + + setData(source, "Vendor", deviceBattery.vendor()); + setData(source, "Product", deviceBattery.product()); + setData(source, "Capacity", battery->capacity()); + setData(source, "Type", batteryType(battery)); + } + + updateBatteryNames(); + + setData("Battery", "Has Battery", !batterySources.isEmpty()); + if (!batterySources.isEmpty()) { + setData("Battery", "Sources", batterySources); + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", + "batteryRemainingTime"); + QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(msg); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(batteryRemainingTimeReply(QDBusPendingCallWatcher*))); + } + + m_sources = basicSourceNames() + batterySources; + } else if (name == "AC Adapter") { + bool isPlugged = false; + + const QList list_ac = Solid::Device::listFromType(Solid::DeviceInterface::AcAdapter); + foreach (const Solid::Device & device_ac, list_ac) { + const Solid::AcAdapter* acadapter = device_ac.as(); + isPlugged |= acadapter->isPlugged(); + connect(acadapter, SIGNAL(plugStateChanged(bool,QString)), this, + SLOT(updateAcPlugState(bool)), Qt::UniqueConnection); + } + + updateAcPlugState(isPlugged); + } else if (name == "Sleep States") { + const QSet sleepstates = + Solid::PowerManagement::supportedSleepStates(); + // We first set all possible sleepstates to false, then enable the ones that are available + setData("Sleep States", "Standby", false); + setData("Sleep States", "Suspend", false); + setData("Sleep States", "Hibernate", false); + + foreach (const Solid::PowerManagement::SleepState &sleepstate, sleepstates) { + if (sleepstate == Solid::PowerManagement::StandbyState) { + setData("Sleep States", "Standby", true); + } else if (sleepstate == Solid::PowerManagement::SuspendState) { + setData("Sleep States", "Suspend", true); + } else if (sleepstate == Solid::PowerManagement::HibernateState) { + setData("Sleep States", "Hibernate", true); + } + //kDebug() << "Sleepstate \"" << sleepstate << "\" supported."; + } + } else if (name == "PowerDevil") { + if (m_brightnessControlsAvailable) { + QDBusMessage screenMsg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/BrightnessControl", + "org.kde.Solid.PowerManagement.Actions.BrightnessControl", + "brightness"); + QDBusPendingReply screenReply = QDBusConnection::sessionBus().asyncCall(screenMsg); + QDBusPendingCallWatcher *screenWatcher = new QDBusPendingCallWatcher(screenReply, this); + QObject::connect(screenWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(screenBrightnessReply(QDBusPendingCallWatcher*))); + } + + if (m_keyboardBrightnessControlsAvailable) { + QDBusMessage keyboardMsg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl", + "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl", + "keyboardBrightness"); + QDBusPendingReply keyboardReply = QDBusConnection::sessionBus().asyncCall(keyboardMsg); + QDBusPendingCallWatcher *keyboardWatcher = new QDBusPendingCallWatcher(keyboardReply, this); + QObject::connect(keyboardWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(keyboardBrightnessReply(QDBusPendingCallWatcher*))); + } + //any info concerning lock screen/screensaver goes here + } else if (name == "UserActivity") { + setData("UserActivity", "IdleTime", KIdleTime::instance()->idleTime()); + } else { + kDebug() << "Data for '" << name << "' not found"; + return false; + } + return true; +} + +QString PowermanagementEngine::batteryType(const Solid::Battery* battery) +{ + switch(battery->type()) { + case Solid::Battery::PrimaryBattery: + return QLatin1String("Battery"); + break; + case Solid::Battery::UpsBattery: + return QLatin1String("Ups"); + break; + case Solid::Battery::MonitorBattery: + return QLatin1String("Monitor"); + break; + case Solid::Battery::MouseBattery: + return QLatin1String("Mouse"); + break; + case Solid::Battery::KeyboardBattery: + return QLatin1String("Keyboad"); + break; + case Solid::Battery::PdaBattery: + return QLatin1String("Pda"); + break; + case Solid::Battery::PhoneBattery: + return QLatin1String("Phone"); + break; + default: + return QLatin1String("Unknown"); + } + + return QLatin1String("Unknown"); +} + +bool PowermanagementEngine::updateSourceEvent(const QString &source) +{ + if (source == "UserActivity") { + setData("UserActivity", "IdleTime", KIdleTime::instance()->idleTime()); + return true; + } + return Plasma::DataEngine::updateSourceEvent(source); +} + +Plasma::Service* PowermanagementEngine::serviceForSource(const QString &source) +{ + if (source == "PowerDevil") { + return new PowerManagementService(this); + } + + return 0; +} + +void PowermanagementEngine::updateBatteryChargeState(int newState, const QString& udi) +{ + QString state("Unknown"); + if (newState == Solid::Battery::NoCharge) { + state = "NoCharge"; + } else if (newState == Solid::Battery::Charging) { + state = "Charging"; + } else if (newState == Solid::Battery::Discharging) { + state = "Discharging"; + } + + const QString source = m_batterySources[udi]; + setData(source, "State", state); +} + +void PowermanagementEngine::updateBatteryPlugState(bool newState, const QString& udi) +{ + const QString source = m_batterySources[udi]; + setData(source, "Plugged in", newState); +} + +void PowermanagementEngine::updateBatteryChargePercent(int newValue, const QString& udi) +{ + const QString source = m_batterySources[udi]; + setData(source, "Percent", newValue); +} + +void PowermanagementEngine::updateBatteryPowerSupplyState(bool newState, const QString& udi) +{ + const QString source = m_batterySources[udi]; + setData(source, "Is Power Supply", newState); +} + +void PowermanagementEngine::updateBatteryNames() +{ + uint unnamedBatteries = 0; + foreach (QString source, m_batterySources) { + DataContainer *batteryDataContainer = containerForSource(source); + if (batteryDataContainer) { + const QString batteryVendor = batteryDataContainer->data()["Vendor"].toString(); + const QString batteryProduct = batteryDataContainer->data()["Product"].toString(); + + // Don't show battery name for primary power supply batteries. They usually have cryptic serial number names. + const bool showBatteryName = batteryDataContainer->data()["Type"].toString() != QLatin1String("Battery") || + !batteryDataContainer->data()["Is Power Supply"].toBool(); + + if (!batteryProduct.isEmpty() && batteryProduct != "Unknown Battery" && showBatteryName) { + if (!batteryVendor.isEmpty()) { + setData(source, "Pretty Name", QString(batteryVendor + ' ' + batteryProduct)); + } else { + setData(source, "Pretty Name", batteryProduct); + } + } else { + ++unnamedBatteries; + if (unnamedBatteries > 1) { + setData(source, "Pretty Name", i18nc("Placeholder is the battery number", "Battery %1", unnamedBatteries)); + } else { + setData(source, "Pretty Name", i18n("Battery")); + } + } + } + } +} + +void PowermanagementEngine::updateAcPlugState(bool newState) +{ + setData("AC Adapter", "Plugged in", newState); +} + +void PowermanagementEngine::deviceRemoved(const QString& udi) +{ + if (m_batterySources.contains(udi)) { + Solid::Device device(udi); + Solid::Battery* battery = device.as(); + if (battery) + battery->disconnect(); + + const QString source = m_batterySources[udi]; + m_batterySources.remove(udi); + removeSource(source); + + QStringList sourceNames(m_batterySources.values()); + sourceNames.removeAll(source); + setData("Battery", "Sources", sourceNames); + setData("Battery", "Has Battery", !sourceNames.isEmpty()); + } +} + +void PowermanagementEngine::deviceAdded(const QString& udi) +{ + Solid::Device device(udi); + if (device.isValid()) { + const Solid::Battery* battery = device.as(); + + if (battery) { + int index = 0; + QStringList sourceNames(m_batterySources.values()); + while (sourceNames.contains(QString("Battery%1").arg(index))) { + index++; + } + + const QString source = QString("Battery%1").arg(index); + sourceNames << source; + m_batterySources[device.udi()] = source; + + connect(battery, SIGNAL(chargeStateChanged(int,QString)), this, + SLOT(updateBatteryChargeState(int,QString))); + connect(battery, SIGNAL(chargePercentChanged(int,QString)), this, + SLOT(updateBatteryChargePercent(int,QString))); + connect(battery, SIGNAL(plugStateChanged(bool,QString)), this, + SLOT(updateBatteryPlugState(bool,QString))); + connect(battery, SIGNAL(powerSupplyStateChanged(bool,QString)), this, + SLOT(updateBatteryPowerSupplyState(bool,QString))); + + // Set initial values + updateBatteryChargeState(battery->chargeState(), device.udi()); + updateBatteryChargePercent(battery->chargePercent(), device.udi()); + updateBatteryPlugState(battery->isPlugged(), device.udi()); + updateBatteryPowerSupplyState(battery->isPowerSupply(), device.udi()); + + setData(source, "Vendor", device.vendor()); + setData(source, "Product", device.product()); + setData(source, "Capacity", battery->capacity()); + setData(source, "Type", batteryType(battery)); + + setData("Battery", "Sources", sourceNames); + setData("Battery", "Has Battery", !sourceNames.isEmpty()); + + updateBatteryNames(); + } + } +} + +void PowermanagementEngine::batteryRemainingTimeChanged(qulonglong time) +{ + //kDebug() << "Remaining time 2:" << time; + setData("Battery", "Remaining msec", time); +} + +void PowermanagementEngine::brightnessControlsAvailableChanged(bool available) +{ + setData("PowerDevil", "Screen Brightness Available", available); + m_brightnessControlsAvailable = available; +} + +void PowermanagementEngine::keyboardBrightnessControlsAvailableChanged(bool available) +{ + setData("PowerDevil", "Keyboard Brightness Available", available); + m_keyboardBrightnessControlsAvailable = available; +} + +void PowermanagementEngine::batteryRemainingTimeReply(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + kDebug() << "Error getting battery remaining time: " << reply.error().message(); + } else { + batteryRemainingTimeChanged(reply.value()); + } + + watcher->deleteLater(); +} + +void PowermanagementEngine::screenBrightnessChanged(int brightness) +{ + setData("PowerDevil", "Screen Brightness", brightness); +} + +void PowermanagementEngine::keyboardBrightnessChanged(int brightness) +{ + setData("PowerDevil", "Keyboard Brightness", brightness); +} + +void PowermanagementEngine::screenBrightnessReply(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + kDebug() << "Error getting screen brightness: " << reply.error().message(); + // FIXME Because the above check doesn't work, we unclaim backlight support as soon as it fails + brightnessControlsAvailableChanged(false); + } else { + screenBrightnessChanged(reply.value()); + } + + watcher->deleteLater(); +} + +void PowermanagementEngine::keyboardBrightnessReply(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + kDebug() << "Error getting keyboard brightness: " << reply.error().message(); + // FIXME Because the above check doesn't work, we unclaim backlight support as soon as it fails + keyboardBrightnessControlsAvailableChanged(false); + } else { + keyboardBrightnessChanged(reply.value()); + } + + watcher->deleteLater(); +} + +K_EXPORT_PLASMA_DATAENGINE(powermanagement, PowermanagementEngine) + +#include "powermanagementengine.moc" diff --git a/plasma/generic/dataengines/powermanagement/powermanagementengine.h b/plasma/generic/dataengines/powermanagement/powermanagementengine.h new file mode 100644 index 00000000..dafb6c28 --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementengine.h @@ -0,0 +1,86 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007-2008 Sebastian Kuegler + * Copyright 2008 Dario Freddi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POWERMANAGEMENTENGINE_H +#define POWERMANAGEMENTENGINE_H + +#include + +#include +#include + +#include +#include + +class QDBusPendingCallWatcher; + +/** + * This class provides runtime information about the battery and AC status + * for use in power management Plasma applets. + */ +class PowermanagementEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + PowermanagementEngine( QObject* parent, const QVariantList& args ); + ~PowermanagementEngine(); + QStringList sources() const; + Plasma::Service* serviceForSource(const QString &source); + +protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString &source); + void init(); + +private slots: + void updateBatteryChargeState(int newState, const QString& udi); + void updateBatteryPlugState(bool newState, const QString& udi); + void updateBatteryChargePercent(int newValue, const QString& udi); + void updateBatteryPowerSupplyState(bool newState, const QString& udi); + void updateAcPlugState(bool newState); + void updateBatteryNames(); + + void deviceRemoved(const QString& udi); + void deviceAdded(const QString& udi); + void batteryRemainingTimeChanged(qulonglong time); + void batteryRemainingTimeReply(QDBusPendingCallWatcher*); + void screenBrightnessChanged(int brightness); + void keyboardBrightnessChanged(int brightness); + void screenBrightnessReply(QDBusPendingCallWatcher *watcher); + void keyboardBrightnessReply(QDBusPendingCallWatcher *watcher); + void brightnessControlsAvailableChanged(bool available); + void keyboardBrightnessControlsAvailableChanged(bool available); + +private: + QString batteryType(const Solid::Battery *battery); + QStringList basicSourceNames() const; + + QStringList m_sources; + + QHash m_batterySources; // + + bool m_brightnessControlsAvailable; + bool m_keyboardBrightnessControlsAvailable; + +}; + + +#endif diff --git a/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp b/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp new file mode 100644 index 00000000..06156d98 --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementjob.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2011 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include + +// kde-workspace/libs +#include + +#include + +#include "powermanagementjob.h" + +#include + +#include + +PowerManagementJob::PowerManagementJob(const QString &operation, QMap ¶meters, QObject *parent) : + ServiceJob(parent->objectName(), operation, parameters, parent) +{ +} + +PowerManagementJob::~PowerManagementJob() +{ +} + +void PowerManagementJob::start() +{ + const QString operation = operationName(); + //kDebug() << "starting operation ... " << operation; + + if (operation == "lockScreen") { + if (KAuthorized::authorizeKAction("lock_screen")) { + const QString interface("org.freedesktop.ScreenSaver"); + QDBusInterface screensaver(interface, "/ScreenSaver"); + screensaver.asyncCall("Lock"); + setResult(true); + return; + } + kDebug() << "operation denied " << operation; + setResult(false); + return; + } else if (operation == "suspend" || operation == "suspendToRam") { + setResult(suspend(Ram)); + return; + } else if (operation == "suspendToDisk") { + setResult(suspend(Disk)); + return; + } else if (operation == "suspendHybrid") { + setResult(suspend(Hybrid)); + return; + } else if (operation == "requestShutDown") { + requestShutDown(); + setResult(true); + return; + } else if (operation == "switchUser") { + // Taken from kickoff/core/itemhandlers.cpp + org::kde::krunner::App krunner("org.kde.krunner", "/App", QDBusConnection::sessionBus()); + krunner.switchUser(); + setResult(true); + return; + } else if (operation == "beginSuppressingSleep") { + setResult(Solid::PowerManagement::beginSuppressingSleep(parameters().value("reason").toString())); + return; + } else if (operation == "stopSuppressingSleep") { + setResult(Solid::PowerManagement::stopSuppressingSleep(parameters().value("cookie").toInt())); + return; + } else if (operation == "beginSuppressingScreenPowerManagement") { + setResult(Solid::PowerManagement::beginSuppressingScreenPowerManagement(parameters().value("reason").toString())); + return; + } else if (operation == "stopSuppressingScreenPowerManagement") { + setResult(Solid::PowerManagement::stopSuppressingScreenPowerManagement(parameters().value("cookie").toInt())); + return; + } else if (operation == "setBrightness") { + setScreenBrightness(parameters().value("brightness").toInt()); + setResult(true); + return; + } else if (operation == "setKeyboardBrightness") { + setKeyboardBrightness(parameters().value("brightness").toInt()); + setResult(true); + return; + } + + kDebug() << "don't know what to do with " << operation; + setResult(false); +} + +bool PowerManagementJob::suspend(const SuspendType &type) +{ + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/SuspendSession", + "org.kde.Solid.PowerManagement.Actions.SuspendSession", + callForType(type)); + QDBusConnection::sessionBus().asyncCall(msg); + return true; +} + +QString PowerManagementJob::callForType(const SuspendType &type) +{ + switch (type) { + case Disk: + return "suspendToDisk"; + break; + + case Hybrid: + return "suspendHybrid"; + break; + + default: + return "suspendToRam"; + break; + } +} + +void PowerManagementJob::setScreenBrightness(int value) +{ + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/BrightnessControl", + "org.kde.Solid.PowerManagement.Actions.BrightnessControl", + "setBrightness"); + msg << value; + QDBusConnection::sessionBus().asyncCall(msg); +} + +void PowerManagementJob::setKeyboardBrightness(int value) +{ + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl", + "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl", + "setKeyboardBrightness"); + msg << value; + QDBusConnection::sessionBus().asyncCall(msg); +} + +void PowerManagementJob::requestShutDown() +{ + KWorkSpace::requestShutDown(); +} + +#include "powermanagementjob.moc" diff --git a/plasma/generic/dataengines/powermanagement/powermanagementjob.h b/plasma/generic/dataengines/powermanagement/powermanagementjob.h new file mode 100644 index 00000000..c1c7bf4a --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementjob.h @@ -0,0 +1,47 @@ +/* + * Copyright 2011 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POWERMANAGEMENTJOB_H +#define POWERMANAGEMENTJOB_H + +// plasma +#include + +class PowerManagementJob : public Plasma::ServiceJob +{ + + Q_OBJECT + + public: + PowerManagementJob(const QString &operation, QMap ¶meters, + QObject *parent = 0); + ~PowerManagementJob(); + + protected: + void start(); + + private: + enum SuspendType { Ram, Disk, Hybrid }; + bool suspend(const SuspendType &type); + void requestShutDown(); + QString callForType(const SuspendType &type); + void setScreenBrightness(int value); + void setKeyboardBrightness(int value); +}; + +#endif // POWERMANAGEMENTJOB_H diff --git a/plasma/generic/dataengines/powermanagement/powermanagementservice.cpp b/plasma/generic/dataengines/powermanagement/powermanagementservice.cpp new file mode 100644 index 00000000..e5f2f5d7 --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementservice.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2011 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "powermanagementservice.h" +#include "powermanagementjob.h" + +PowerManagementService::PowerManagementService(QObject *parent) + : Plasma::Service(parent) +{ + setName("powermanagementservice"); +} + +ServiceJob *PowerManagementService::createJob(const QString &operation, + QMap ¶meters) +{ + return new PowerManagementJob(operation, parameters, this); +} + +#include "powermanagementservice.moc" diff --git a/plasma/generic/dataengines/powermanagement/powermanagementservice.h b/plasma/generic/dataengines/powermanagement/powermanagementservice.h new file mode 100644 index 00000000..9976ecab --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementservice.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POWERMANAGEMENTSERVICE_H +#define POWERMANAGEMENTSERVICE_H + + +#include +#include + +using namespace Plasma; + + +class PowerManagementService : public Plasma::Service +{ + Q_OBJECT + +public: + PowerManagementService(QObject *parent = 0); + ServiceJob *createJob(const QString &operation, QMap ¶meters); +}; + +#endif // POWERMANAGEMENTSERVICE_H diff --git a/plasma/generic/dataengines/powermanagement/powermanagementservice.operations b/plasma/generic/dataengines/powermanagement/powermanagementservice.operations new file mode 100644 index 00000000..c9abbf9c --- /dev/null +++ b/plasma/generic/dataengines/powermanagement/powermanagementservice.operations @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/rss/CMakeLists.txt b/plasma/generic/dataengines/rss/CMakeLists.txt new file mode 100644 index 00000000..a1aec8c2 --- /dev/null +++ b/plasma/generic/dataengines/rss/CMakeLists.txt @@ -0,0 +1,13 @@ + +include_directories(${Boost_INCLUDE_DIR} ${KDEPIMLIBS_INCLUDE_DIR}) + +set(rss_engine_SRCS + rss.cpp +) + +kde4_add_plugin(plasma_engine_rss ${rss_engine_SRCS}) +target_link_libraries(plasma_engine_rss ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS} ${KDE4_SYNDICATION_LIBS} ${KDE4_SOLID_LIBS}) + +install(TARGETS plasma_engine_rss DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-rss.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/rss/Messages.sh b/plasma/generic/dataengines/rss/Messages.sh new file mode 100755 index 00000000..85329a4f --- /dev/null +++ b/plasma/generic/dataengines/rss/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_rss.pot diff --git a/plasma/generic/dataengines/rss/plasma-dataengine-rss.desktop b/plasma/generic/dataengines/rss/plasma-dataengine-rss.desktop new file mode 100644 index 00000000..e4c47b5f --- /dev/null +++ b/plasma/generic/dataengines/rss/plasma-dataengine-rss.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=RSS +Name[ar]=آر إس إس +Name[ast]=RSS +Name[be@latin]=RSS +Name[bg]=RSS +Name[bn]=RSS +Name[bn_IN]=RSS +Name[bs]=RSS +Name[ca]=RSS +Name[ca@valencia]=RSS +Name[cs]=RSS +Name[da]=RSS +Name[de]=RSS +Name[el]=RSS +Name[en_GB]=RSS +Name[eo]=RSS +Name[es]=RSS +Name[et]=RSS +Name[eu]=RSS +Name[fi]=RSS +Name[fr]=RSS +Name[fy]=RSS +Name[ga]=RSS +Name[gl]=RSS +Name[gu]=RSS +Name[he]=RSS +Name[hi]=आरएसएस +Name[hne]=आरएसएस +Name[hr]=RSS +Name[hu]=RSS-hírek +Name[ia]=RSS +Name[id]=RSS +Name[is]=RSS +Name[it]=RSS +Name[ja]=RSS +Name[ka]=RSS +Name[kk]=RSS +Name[km]=RSS +Name[kn]=RSS +Name[ko]=RSS +Name[ku]=RSS +Name[lt]=RSS +Name[lv]=RSS +Name[mai]=RSS +Name[mk]=RSS +Name[ml]=ആര്‍എസ്എസ് +Name[mr]=RSS +Name[nb]=RSS +Name[nds]=RSS +Name[nl]=RSS +Name[nn]=RSS +Name[or]=RSS +Name[pa]=RSS +Name[pl]=RSS +Name[pt]=RSS +Name[pt_BR]=RSS +Name[ro]=RSS +Name[ru]=Ленты новостей RSS +Name[si]=RSS +Name[sk]=RSS +Name[sl]=RSS +Name[sr]=РСС +Name[sr@ijekavian]=РСС +Name[sr@ijekavianlatin]=RSS +Name[sr@latin]=RSS +Name[sv]=RSS +Name[ta]=RSS +Name[te]=RSS +Name[tg]=Наворҳои RSS +Name[th]=หัวข้อข่าว (RSS) +Name[tr]=RSS +Name[ug]=RSS +Name[uk]=RSS +Name[wa]=RSS +Name[x-test]=xxRSSxx +Name[zh_CN]=RSS +Name[zh_TW]=RSS +Comment=RSS News Data Engine +Comment[ar]=محرك بيانات الخلاصات +Comment[ast]=Motor de RSS +Comment[be@latin]=Systema navinaŭ z žarołaŭ „RSS” +Comment[bg]=Зареждане на RSS емисии +Comment[bn_IN]=RSS খবরের ডাটা ইঞ্জিন +Comment[bs]=Datomotor RSS vesti +Comment[ca]=Motor de dades de notícies RSS +Comment[ca@valencia]=Motor de dades de notícies RSS +Comment[cs]=Služba RSS novinek +Comment[csb]=Mòtór pòdôwków dlô pòwrózków RSS +Comment[da]=Datamotor til RSS-nyheder +Comment[de]=Datentreiber für RSS-News +Comment[el]=Μηχανή δεδομένων ειδήσεων RSS +Comment[en_GB]=RSS News Data Engine +Comment[eo]=Datuma Motoro de RSS novaĵoj +Comment[es]=Motor de RSS +Comment[et]=RSS-voogude andmete mootor +Comment[eu]=RSS berrien datu-motorra +Comment[fi]=RSS-syötetietomoottori +Comment[fr]=Moteur de données des flux RSS +Comment[fy]=RSS nijs gegevens motor +Comment[ga]=Inneall Sonraí Nuachta RSS +Comment[gl]=Motor de datos de novas RSS +Comment[gu]=RSS સમાચાર માહિતી એન્જિન +Comment[he]=מנוע תוכן חדשות RSS +Comment[hi]=आरएसएस समाचार डाटा इंजिन +Comment[hne]=आरएसएस समाचार डाटा इंजन +Comment[hr]=Podatkovni mehanizam za vijesti preko RSS-a +Comment[hu]=RSS-hírkezelő +Comment[ia]=Motor de datos de novitates RSS +Comment[id]=Mesin Data Berita RSS +Comment[is]=RSS fréttagagnavél +Comment[it]=Motore di dati delle notizie RSS +Comment[ja]=RSS ニュースデータエンジン +Comment[kk]=RSS ақпарлар тетігі +Comment[km]=ម៉ាស៊ីន​ទិន្នន័យព័ត៌មាន RSS +Comment[kn]=RSS ಸುದ್ದಿ ದತ್ತಾಂಶ ಎಂಜಿನ್ +Comment[ko]=RSS 뉴스 데이터 엔진 +Comment[ku]=Motora Dane yên Nûçe yên RSS +Comment[lt]=RSS naujienų duomenų variklis +Comment[lv]=RSS ziņu datu dzinējs +Comment[ml]=ആര്‍എസ്എസ് ന്യൂസ് ഡേറ്റാ എഞ്ചിന്‍ +Comment[mr]=RSS समाचार डेटा इंजिन +Comment[nb]=RSS nyhets-datamotor +Comment[nds]=RSS-Stroom-Datenkarn +Comment[nl]=RSS-nieuws (gegevensengine) +Comment[nn]=Nyheitsmotor for RSS +Comment[or]=RSS ଖବର ତଥ୍ୟ ଯନ୍ତ୍ର +Comment[pa]=RSS ਖ਼ਬਰਾਂ ਡਾਟਾ ਇੰਜਣ +Comment[pl]=Silnik danych wiadomości RSS +Comment[pt]=Motor de Dados de Notícias RSS +Comment[pt_BR]=Mecanismo de dados de notícias RSS +Comment[ro]=Motor de date pentru știri RSS +Comment[ru]=Показ новостей из лент RSS +Comment[si]=RSS ප්‍රවෘත්ති දත්ත එන්ජිම +Comment[sk]=Dátový nástroj RSS noviniek +Comment[sl]=Podatkovni pogon za novice RSS +Comment[sr]=Датомотор РСС вести +Comment[sr@ijekavian]=Датомотор РСС вести +Comment[sr@ijekavianlatin]=Datomotor RSS vesti +Comment[sr@latin]=Datomotor RSS vesti +Comment[sv]=Datagränssnitt för RSS-nyheter +Comment[ta]=RSS News Data Engine +Comment[tg]=Поставщик лент RSS +Comment[th]=กลไกข้อมูล รับหัวข้อข่าว (RSS) +Comment[tr]=RSS Haber Veri Motoru +Comment[ug]=RSS خەۋەر سانلىق-مەلۇمات ماتورى +Comment[uk]=Рушій даних новин RSS +Comment[wa]=Moteur di dnêyes des noveles RSS +Comment[x-test]=xxRSS News Data Enginexx +Comment[zh_CN]=RSS 新闻数据引擎 +Comment[zh_TW]=RSS 新聞資料引擎 +ServiceTypes=Plasma/DataEngine +Type=Service +Icon=application-rss+xml +X-KDE-Library=plasma_engine_rss + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=rss +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/rss/rss.cpp b/plasma/generic/dataengines/rss/rss.cpp new file mode 100644 index 00000000..f3bab730 --- /dev/null +++ b/plasma/generic/dataengines/rss/rss.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +//Own +#include "rss.h" + +//KDE +#include +#include +#include +#include +#include +#include +#include +#include + +//Plasma +#include + +//Qt +#include +#include +#include +#include +#include + +#define TIMEOUT 15000 //timeout before updating the source if not all feeds + //are fetched. +#define CACHE_TIMEOUT 60 //time in seconds before the cached feeds are marked + //as out of date. +#define MINIMUM_INTERVAL 60000 +#define FAVICONINTERFACE "org.kde.FavIcon" + +RssEngine::RssEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_forceUpdate(false) +{ + Q_UNUSED(args) + setMinimumPollingInterval(MINIMUM_INTERVAL); + m_favIconsModule = new QDBusInterface("org.kde.kded", "/modules/favicons", + FAVICONINTERFACE); + m_signalMapper = new QSignalMapper(this); + connect(m_favIconsModule, SIGNAL(iconChanged(bool,QString,QString)), + this, SLOT(slotIconChanged(bool,QString,QString))); + connect(m_signalMapper, SIGNAL(mapped(QString)), + this, SLOT(timeout(QString))); + connect(Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)), + SLOT(networkStatusChanged(Solid::Networking::Status))); + +} + +RssEngine::~RssEngine() +{ + delete m_favIconsModule; +} + +void RssEngine::networkStatusChanged(Solid::Networking::Status status) +{ + if (status == Solid::Networking::Connected || status == Solid::Networking::Unknown) { + kDebug() << "network connected, force refreshing feeds in 3 seconds"; + // The forced update needs to happen after the new feeds are in, + // so remember to force the update in processRss() + m_forceUpdate = true; + // start updating the feeds + foreach(const QString &feedUrl, sources()) { + updateSourceEvent(feedUrl); + } + } +} + +bool RssEngine::updateSourceEvent(const QString &name) +{ + /* Plasmoids using this engine should be able to retrieve + * multiple feeds at the same time, so we allow a comma + * separated list of url's + */ + // NOTE: A comma separated list of feeds is not url compliant. Urls + // may and do contain commas see http://www.spiegel.de/schlagzeilen/rss/0,5291,,00.xml + // I have changed it to something more not url compliant " " three dots + // Otherwise take a list instead + const QStringList sources = name.split(' ', QString::SkipEmptyParts); + + foreach (const QString& source, sources) { + setStorageEnabled(source, true); + // Let's first see if we've got a recent cached version of + // the feed. This avoids 'large' amounts of unnecessary network + // traffic. + if (QDateTime::currentDateTime() > + m_feedTimes[source.toLower()].addSecs(CACHE_TIMEOUT)){ + kDebug() << "Cache from " << source << + " older than 60 seconds, refreshing..."; + + Syndication::Loader * loader = Syndication::Loader::create(); + connect(loader, SIGNAL(loadingComplete(Syndication::Loader*, + Syndication::FeedPtr, + Syndication::ErrorCode)), + this, SLOT(processRss(Syndication::Loader*, + Syndication::FeedPtr, + Syndication::ErrorCode))); + + m_feedMap.insert(loader, source); + m_sourceMap.insert(loader, name); + loader->loadFrom(source); + } else { + kDebug() << "Recent cached version of " << source << + " found. Skipping..."; + + // We might want to update the source: + if (cachesUpToDate(name)) { + updateFeeds(name, m_feedTitles[ source ] ); + } + } + } + + QTimer *timer = new QTimer(this); + m_timerMap[name] = timer; + timer->setSingleShot(true); + m_signalMapper->setMapping(timer, name); + + connect(timer, SIGNAL(timeout()), m_signalMapper, SLOT(map())); + + timer->start(TIMEOUT); + return true; +} + +void RssEngine::slotIconChanged(bool isHost, const QString& hostOrURL, + const QString& iconName) +{ + Q_UNUSED(isHost); + const QString iconFile = KGlobal::dirs()->findResource("cache", + iconName+".png"); + const QString url = hostOrURL.toLower(); + + m_feedIcons[url] = iconFile; + QMap map; + + for (int i = 0; i < m_feedItems[url].size(); i++) { + map = m_feedItems[url].at(i).toMap(); + map["icon"] = iconFile; + m_feedItems[url].replace(i, map); + } + + //Are there sources ready to get updated now? + foreach (const QString& source, m_sourceMap) { + if (source.contains(url, Qt::CaseInsensitive) && + cachesUpToDate(source)) { + kDebug() << "all caches from source " << source << + " up to date, updating..."; + updateFeeds(source, m_feedTitles[ source ] ); + } + } +} + +void RssEngine::timeout(const QString & source) +{ + kDebug() << "timout fired, updating source"; + updateFeeds(source, m_feedTitles[ source ] ); + m_signalMapper->removeMappings(m_timerMap[source]); +} + +bool RssEngine::sourceRequestEvent(const QString &name) +{ + setData(name, DataEngine::Data()); + updateSourceEvent(name); + return true; +} + +void RssEngine::processRss(Syndication::Loader* loader, + Syndication::FeedPtr feed, + Syndication::ErrorCode error) +{ + const QString url = m_feedMap.take(loader); + const QString source = m_sourceMap.take(loader); + QString title; + bool iconRequested = false; + KUrl u(url); + + if (error != Syndication::Success) { + kDebug() << "Syndication did not work out... url = " << url; + title = i18n("Syndication did not work out"); + setData(source, "title", i18n("Fetching feed failed.")); + setData(source, "link", url); + } else { + title = feed->title(); + QVariantList items; + QString location; + + foreach (const Syndication::ItemPtr& item, feed->items()) { + QMap dataItem; + + //some malformed rss feeds can have empty entries + if (item->title().isNull() && item->description().isNull() && dataItem["content"].isNull()) { + continue; + } + + dataItem["title"] = item->title(); + dataItem["feed_title"] = feed->title(); + dataItem["link"] = item->link(); + dataItem["feed_url"] = url; + dataItem["description"] = item->description(); + dataItem["content"] = item->content(); + dataItem["time"] = (uint)item->dateUpdated(); + if (!m_feedIcons.contains(url.toLower()) && !iconRequested) { + //lets request an icon, and only do this once per feed. + location = iconLocation(u); + if (location.isEmpty()) { + m_favIconsModule->call( "downloadHostIcon", u.url() ); + } else { + //the icon is already in cache, so call this slot manually. + slotIconChanged(false, u.url(), iconLocation(u)); + } + iconRequested = true; + } + dataItem["icon"] = m_feedIcons[url.toLower()]; + QStringList authors; + foreach (const boost::shared_ptr a, item->authors()) { + authors << a->name(); + } + dataItem["author"] = authors; + + items.append(dataItem); + + + if (!m_rssSourceNames.contains(url)) { + QMap sourceItem; + + sourceItem["feed_title"] = feed->title(); + sourceItem["feed_url"] = url; + sourceItem["icon"] = m_feedIcons[url.toLower()]; + + m_rssSources.append(sourceItem); + m_rssSourceNames.insert(url); + } + } + m_feedItems[url.toLower()] = items; + m_feedTimes[url.toLower()] = QDateTime::currentDateTime(); + m_feedTitles[url.toLower()] = title; + + // If we update the feeds every time a feed is fetched, + // only the first update will actually update a connected + // applet, which is actually sane, since plasma updates + // only one time each interval. This means, however, that + // we maybe want to delay updating the feeds untill either + // timeout, or all feeds are up to date. + if (cachesUpToDate(source)) { + kDebug() << "all caches from source " << source + << " up to date, updating..."; + updateFeeds(source, title); + if (m_forceUpdate) { + // Should be used with care ... + forceImmediateUpdateOfAllVisualizations(); + m_forceUpdate = false; + // and skip scheduleSourcesUpdated(), since we + // force a repaint anyway already + return; + } + } else { + kDebug() << "not all caches from source " << source + << ", delaying update."; + } + scheduleSourcesUpdated(); + } +} + +void RssEngine::updateFeeds(const QString & source, const QString & title) +{ + /** + * TODO: can this be improved? I'm calling mergeFeeds way too + * often here... + */ + const QVariantList list = mergeFeeds(source); + setData(source, "items", list); + + setData(source, "sources", m_rssSources); + const QStringList sourceNames = source.split(' ', QString::SkipEmptyParts); + if (sourceNames.size() > 1) { + setData(source, "title", i18np("1 RSS feed fetched", + "%1 RSS feeds fetched", sourceNames.size())); + } else { + setData(source, "title", title); + } +} + +bool RssEngine::cachesUpToDate(const QString & source) const +{ + const QStringList sources = source.split(' ', QString::SkipEmptyParts); + bool outOfDate = false; + foreach (const QString &url, sources) { + if (QDateTime::currentDateTime() > + m_feedTimes[url.toLower()].addSecs(CACHE_TIMEOUT)){ + outOfDate = true; + } + if (!m_feedIcons.contains(url.toLower())) { + outOfDate = true; + } + } + return (!outOfDate); +} + +bool compare(const QVariant &v1, const QVariant &v2) +{ + return v1.toMap()["time"].toUInt() > v2.toMap()["time"].toUInt(); +} + +QVariantList RssEngine::mergeFeeds(QString source) const +{ + QVariantList result; + const QStringList sources = source.split(' ', QString::SkipEmptyParts); + + foreach (const QString& feed, sources) { + result += m_feedItems[feed.toLower()]; + } + + qSort(result.begin(), result.end(), compare); + return result; +} + +QString RssEngine::iconLocation(const KUrl & url) const +{ + QDBusReply reply = m_favIconsModule->call( "iconForUrl", url.url() ); + if (reply.isValid()) { + QString result = reply; + return result; + } + return QString(); +} + +#include "rss.moc" + diff --git a/plasma/generic/dataengines/rss/rss.h b/plasma/generic/dataengines/rss/rss.h new file mode 100644 index 00000000..153a9c38 --- /dev/null +++ b/plasma/generic/dataengines/rss/rss.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2008 Rob Scheepmaker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef RSS_DATAENGINE_H +#define RSS_DATAENGINE_H + +#include +#include +#include +#include +#include +#include + +class QDBusInterface; +class QSignalMapper; + +/** + * This class can be used to fetch one or more rss feeds. By + * requesting a datasource with the url's of one or more rss + * feeds separated by " ", you will receive a merged list + * containing the items of all feeds requested. This list is + * sorted by timestamp. + * This class also fetches the favicons from all requested + * feeds. + */ +class RssEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + RssEngine(QObject* parent, const QVariantList& args); + virtual ~RssEngine(); + + protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString& name); + + protected slots: + void processRss(Syndication::Loader* loader, + Syndication::FeedPtr feed, + Syndication::ErrorCode error); + void slotIconChanged(bool isHost, const QString& hostOrURL, + const QString& iconName); + void timeout(const QString & source); + void networkStatusChanged(Solid::Networking::Status status); + + private: + QVariantList mergeFeeds(QString source) const; + void updateFeeds(const QString & source, + const QString & title); + bool cachesUpToDate(const QString & source) const; + QString iconLocation(const KUrl & url) const; + + QHash m_feedMap; + QHash m_sourceMap; + QHash m_timerMap; + QHash m_feedItems; + QHash m_feedIcons; + QHash m_feedTitles; + QHash m_feedTimes; + bool m_forceUpdate; + + QVariantList m_rssSources; + QSet m_rssSourceNames; + + QDBusInterface * m_favIconsModule; + QSignalMapper * m_signalMapper; +}; + +K_EXPORT_PLASMA_DATAENGINE(rss, RssEngine) + +#endif + diff --git a/plasma/generic/dataengines/share/CMakeLists.txt b/plasma/generic/dataengines/share/CMakeLists.txt new file mode 100644 index 00000000..e2e58a6b --- /dev/null +++ b/plasma/generic/dataengines/share/CMakeLists.txt @@ -0,0 +1,43 @@ +project(shareengine) + +set(share_engine_SRCS + shareprovider.cpp + shareengine.cpp + shareservice.cpp + share_package.cpp) + +kde4_add_plugin(plasma_engine_share ${share_engine_SRCS}) +target_link_libraries(plasma_engine_share + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + ${KDE4_KIO_LIBS} + ${KDE4_KROSSCORE_LIBS}) + +install(TARGETS plasma_engine_share + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES data/plasma-dataengine-share.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES data/plasma_shareprovider.desktop + DESTINATION ${SERVICETYPES_INSTALL_DIR}) + +install(FILES share.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + +set(sharepackage_SRCS + share_package.cpp + plugin_share_package.cpp +) + +add_subdirectory(backends) + +kde4_add_plugin(plasma_packagestructure_share + ${sharepackage_SRCS}) +target_link_libraries(plasma_packagestructure_share + ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_packagestructure_share + DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES data/plasma-packagestructure-share.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/dataengines/share/Messages.sh b/plasma/generic/dataengines/share/Messages.sh new file mode 100755 index 00000000..96beed36 --- /dev/null +++ b/plasma/generic/dataengines/share/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_share.pot diff --git a/plasma/generic/dataengines/share/backends/CMakeLists.txt b/plasma/generic/dataengines/share/backends/CMakeLists.txt new file mode 100644 index 00000000..9f1f7d08 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/CMakeLists.txt @@ -0,0 +1,11 @@ +add_subdirectory(kde) +add_subdirectory(imgur) +add_subdirectory(pastebincom) +add_subdirectory(pasteubuntucom) +add_subdirectory(simplestimagehosting) +add_subdirectory(wklej) +add_subdirectory(wstaw) +add_subdirectory(pasteopensuseorg) +add_subdirectory(imgsusepasteorg) +add_subdirectory(privatepaste) +add_subdirectory(im9) diff --git a/plasma/generic/dataengines/share/backends/im9/CMakeLists.txt b/plasma/generic/dataengines/share/backends/im9/CMakeLists.txt new file mode 100644 index 00000000..a4f4c574 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/im9/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-im9.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-im9.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/im9/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/im9) diff --git a/plasma/generic/dataengines/share/backends/im9/contents/code/main.js b/plasma/generic/dataengines/share/backends/im9/contents/code/main.js new file mode 100644 index 00000000..4ba04d47 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/im9/contents/code/main.js @@ -0,0 +1,47 @@ +/********************************************************************************** +* im9.eu backend for Plasma. +* Copyright (C) 2012 Michal Dutkiewicz +* +* 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; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +**********************************************************************************/ + +function url() +{ + return 'http://api.im9.eu/kde-pastebin/'; +} + +function contentKey() +{ + return 'image'; +} + +function setup() +{ +} + +function handleResultData(data) +{ + var result = data.match('800\n(http://.+)\n'); + + if (result == '') + { + provider.error(data); + + return; + } + + provider.success(data.replace('800', '').replace('\n', '')); +} diff --git a/plasma/generic/dataengines/share/backends/im9/metadata.desktop b/plasma/generic/dataengines/share/backends/im9/metadata.desktop new file mode 100644 index 00000000..c69fae7b --- /dev/null +++ b/plasma/generic/dataengines/share/backends/im9/metadata.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Name=im9.eu +Name[bs]=im9.eu +Name[ca]=im9.eu +Name[ca@valencia]=im9.eu +Name[cs]=im9.eu +Name[da]=im9.eu +Name[de]=im9.eu +Name[el]=im9.eu +Name[en_GB]=im9.eu +Name[es]=im9.eu +Name[et]=im9.eu +Name[eu]=im9.eu +Name[fi]=im9.eu +Name[fr]=im9.eu +Name[gl]=im9.eu +Name[hu]=im9.eu +Name[ia]=im9.eu +Name[it]=im9.eu +Name[kk]=im9.eu +Name[ko]=im9.eu +Name[lt]=im9.eu +Name[nb]=im9.eu +Name[nds]=im9.eu +Name[nl]=im9.eu +Name[pa]=im9.eu +Name[pl]=im9.eu +Name[pt]=im9.eu +Name[pt_BR]=im9.eu +Name[ro]=im9.eu +Name[ru]=im9.eu +Name[sk]=im9.eu +Name[sl]=im9.eu +Name[sr]=им9 +Name[sr@ijekavian]=им9 +Name[sr@ijekavianlatin]=im9 +Name[sr@latin]=im9 +Name[sv]=im9.eu +Name[tr]=im9.eu +Name[uk]=im9.eu +Name[x-test]=xxim9.euxx +Name[zh_CN]=im9.eu +Name[zh_TW]=im9.eu +Comment=Allows images to be shared using the im9.eu service +Comment[bs]=Dopušta dijeljenje slika preko servisa im9.eu +Comment[ca]=Permet la compartició d'imatges utilitzant el servei im9.eu +Comment[ca@valencia]=Permet la compartició d'imatges utilitzant el servei im9.eu +Comment[cs]=Povolí sdílení obrázků pomocí služby im9.eu +Comment[da]=Muliggør deling af billeder med tjenesten im9.eu +Comment[de]=Ermöglicht die Veröffentlichung von Bildern über den im9.eu-Dienst +Comment[el]=Επιτρέπει το μοίρασμα των εικόνων με την υπηρεσία im9.eu +Comment[en_GB]=Allows images to be shared using the im9.eu service +Comment[es]=Permite compartir imágenes a través del servicio im9.eu +Comment[et]=Piltide jagamine im9.eu teenuse kaudu +Comment[eu]=Irudiak im9.eu zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa kuvien jakamisen im9.eu-palvelussa +Comment[fr]=Permet le partage d'images à l'aide du service « im9.eu » +Comment[gl]=Permite compartir imaxes mediante o servizo im9.eu +Comment[hu]=Képek megosztása az im9.eu szolgáltatás használatával +Comment[ia]=Il permitte imagines de esser compartite per usage de servicio im9.eu +Comment[it]=Abilita la condivisione di immagini con il servizio img9.eu +Comment[kk]=im9.eu қызметі көмегімен кескіндерді ортақ қылуды рұқсат ету +Comment[ko]=im9.eu로 그림을 공유합니다 +Comment[lt]=Įjungia dalinimąsi nuotraukomis naudojant im9.eu tarnybą +Comment[nb]=Gjør det mulig å dele bilder via tjenesten im9.eu +Comment[nds]=Lett Di Biller över den Deenst "im9.eu" praatstellen +Comment[nl]=Staat het delen van afbeeldingen toe met gebruik van de service im9.eu +Comment[pa]=im9.eu ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚਿੱਤਰ ਸਾਂਝੇ ਕਰਨ ਲਈ ਸਹਾਇਕ +Comment[pl]=Pozwala na udostępnianie obrazów przy użyciu usługi im9.eu +Comment[pt]=Permite a partilha de imagens com o serviço do 'im9.eu' +Comment[pt_BR]=Permite o compartilhamento de imagens usando o serviço do im9.eu +Comment[ro]=Permite partajarea imaginilor cu serviciul im9.eu +Comment[ru]=Позволяет публиковать изображения на сервере im9.eu +Comment[sk]=Povolí zdieľanie obrázkov pomocou služby im9.eu +Comment[sl]=Omogoča deljenje slik prek storitve im9.eu +Comment[sr]=Дељење слика преко сервиса им9 +Comment[sr@ijekavian]=Дијељење слика преко сервиса им9 +Comment[sr@ijekavianlatin]=Dijeljenje slika preko servisa im9 +Comment[sr@latin]=Deljenje slika preko servisa im9 +Comment[sv]=Tillåter att bilder delas genom att använda tjänsten im9.eu +Comment[tr]=im9.eu hizmetini kullanarak resimleri paylaşmayı sağlar +Comment[uk]=Уможливлює оприлюднення зображень за допомогою служби im9.eu +Comment[x-test]=xxAllows images to be shared using the im9.eu servicexx +Comment[zh_CN]=用 im9.eu 服务共享图片 +Comment[zh_TW]=允許使用 im9.eu 服務分享影像 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=image/* + +X-KDE-PluginInfo-Name=im9 +X-KDE-PluginInfo-Author=Michał Dutkiewicz +X-KDE-PluginInfo-Email=emdeck@gmail.com +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/imgsusepasteorg/CMakeLists.txt b/plasma/generic/dataengines/share/backends/imgsusepasteorg/CMakeLists.txt new file mode 100644 index 00000000..a4cfe41b --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgsusepasteorg/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-imgsusepasteorg.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-imgsusepasteorg.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/imgsusepasteorg) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/imgsusepasteorg) diff --git a/plasma/generic/dataengines/share/backends/imgsusepasteorg/contents/code/main.js b/plasma/generic/dataengines/share/backends/imgsusepasteorg/contents/code/main.js new file mode 100644 index 00000000..35b4201b --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgsusepasteorg/contents/code/main.js @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2010 by Will Stephenson * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://susepaste.org"; +} + +function contentKey() { + return "file"; +} + +function setup() { + provider.addPostItem("name", "KDE", "text/plain"); + provider.addPostItem("title", "mypaste", "text/plain"); + provider.addPostItem("lang", "image", "text/plain"); + provider.addPostItem("submit", "submit", "text/plain"); + provider.addPostItem("expire","1440","text/plain"); +} + +function handleResultData(data) { + console.log("--> data: " + data); + var res = data.match("(Info.+)"); + if (res != "") { + return; + } + provider.error(data); +} + +function handleRedirection(url) { + provider.success(url); +} diff --git a/plasma/generic/dataengines/share/backends/imgsusepasteorg/metadata.desktop b/plasma/generic/dataengines/share/backends/imgsusepasteorg/metadata.desktop new file mode 100644 index 00000000..7aade0be --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgsusepasteorg/metadata.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Name=img.susepaste.org +Name[ar]=img.susepaste.org +Name[bg]=img.susepaste.org +Name[bs]=img.susepaste.org +Name[ca]=img.susepaste.org +Name[ca@valencia]=img.susepaste.org +Name[cs]=img.susepaste.org +Name[da]=img.susepaste.org +Name[de]=img.susepaste.org +Name[el]=img.susepaste.org +Name[en_GB]=img.susepaste.org +Name[es]=img.susepaste.org +Name[et]=img.susepaste.org +Name[eu]=img.susepaste.org +Name[fi]=img.susepaste.org +Name[fr]=img.susepaste.org +Name[gl]=img.susepaste.org +Name[he]=img.susepaste.org +Name[hr]=img.susepaste.org +Name[hu]=img.susepaste.org +Name[ia]=img.susepaste.org +Name[is]=img.susepaste.org +Name[it]=img.susepaste.org +Name[kk]=img.susepaste.org +Name[km]=img.susepaste.org +Name[ko]=img.susepaste.org +Name[lt]=img.susepaste.org +Name[lv]=img.susepaste.org +Name[mr]=img.susepaste.org +Name[nb]=img.susepaste.org +Name[nds]=img.susepaste.org +Name[nl]=img.susepaste.org +Name[pa]=img.susepaste.org +Name[pl]=img.susepaste.org +Name[pt]=img.susepaste.org +Name[pt_BR]=img.susepaste.org +Name[ro]=img.susepaste.org +Name[ru]=img.susepaste.org +Name[sk]=img.susepaste.org +Name[sl]=img.susepaste.org +Name[sr]=img.susepaste.org +Name[sr@ijekavian]=img.susepaste.org +Name[sr@ijekavianlatin]=img.susepaste.org +Name[sr@latin]=img.susepaste.org +Name[sv]=img.susepaste.org +Name[tr]=img.susepaste.org +Name[ug]=img.susepaste.org +Name[uk]=img.susepaste.org +Name[wa]=img.susepaste.org +Name[x-test]=xximg.susepaste.orgxx +Name[zh_CN]=img.susepaste.org +Name[zh_TW]=img.susepaste.org +Comment=Allows images to be shared using the susepaste.org service +Comment[ar]=يسمح للصور أن تُشارك بإستخدام خدمة susepaste.org +Comment[bg]=Позволява споделянето на картинки чрез susepaste.org +Comment[bs]=Dopušta dijeljenje slika preko servisa susepaste.org +Comment[ca]=Permet la compartició d'imatges utilitzant el servei susepaste.org +Comment[ca@valencia]=Permet la compartició d'imatges utilitzant el servei susepaste.org +Comment[cs]=Povolí sdílení obrázků pomocí služby susepaste.org +Comment[da]=Muliggør deling af billeder med tjenesten susepaste.org +Comment[de]=Ermöglicht die Veröffentlichung von Bildern über den susepaste.org-Dienst +Comment[el]=Επιτρέπει το μοίρασμα των εικόνων χρησιμοποιώντας την υπηρεσία susepaste.org +Comment[en_GB]=Allows images to be shared using the susepaste.org service +Comment[es]=Permite compartir imágenes a través del servicio de susepaste.org +Comment[et]=Piltide jagamine susepaste.org teenuse kaudu +Comment[eu]=Irudiak susepaste.org zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa kuvien jakamisen susepaste.org-palvelussa +Comment[fr]=Permet le partage d'images à l'aide du service « susepaste.org » +Comment[gl]=Permite compartir imaxes mediante o servizo susepaste.org +Comment[he]=מאפשר שיתוף תמונות באמצעות השירות susepaste.org +Comment[hr]=Omogućuje dijeljenje slika koristeći servis susepaste.org +Comment[hu]=Képek megosztása a susepaste.org szolgáltatás használatával +Comment[ia]=Il permitte images de esser compartite per usar le servicio susepaste.org +Comment[is]=Gerir kleift að deila myndum með susepaste.org þjónustunni +Comment[it]=Abilita la condivisione di immagini con il servizio susepaste.org +Comment[kk]=susepaste.org қызметі көмегімен кескіндерді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​រូបភាព​ ដោយ​ប្រើ​សេវា susepaste.org +Comment[ko]=susepaste.org로 그림을 공유합니다 +Comment[lt]=Įjungia dalinimąsį nuotraukomis naudojant susepaste.org tarnybą +Comment[lv]=Ļauj kopīgot attēlus, izmantojot susepaste.org servisu +Comment[mr]=susepaste.org सेवा वापरुन प्रतिमा शेअर करतो +Comment[nb]=Gjør det mulig å dele bilder via tjenesten susepaste.org +Comment[nds]=Biller op "img.susepaste.org" praatstellen +Comment[nl]=Staat het delen van afbeeldingen toe met gebruik van de service susepaste.org +Comment[pa]=susepaste.org ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚਿੱਤਰ ਸਾਂਝੇ ਕਰਨ ਲਈ ਸਹਾਇਕ +Comment[pl]=Pozwala na udostępnianie obrazów przy użyciu usługi susepaste.org +Comment[pt]=Permite a partilha de imagens com o serviço do 'susepaste.org' +Comment[pt_BR]=Permite o compartilhamento de imagens usando o serviço do susepaste.org +Comment[ro]=Permite partajarea imaginilor cu serviciul susepaste.org +Comment[ru]=Позволяет публиковать изображения на сервере susepaste.org +Comment[sk]=Povolí zdieľanie obrázkov pomocou služby susepaste.org +Comment[sl]=Omogoča deljenje slik prek storitve susepaste.org +Comment[sr]=Дељење слика преко сервиса susepaste.org +Comment[sr@ijekavian]=Дијељење слика преко сервиса susepaste.org +Comment[sr@ijekavianlatin]=Dijeljenje slika preko servisa susepaste.org +Comment[sr@latin]=Deljenje slika preko servisa susepaste.org +Comment[sv]=Tillåter att bilder delas genom att använda tjänsten susepaste.org +Comment[tr]=susepaste.org hizmeti kullanarak resim paylaşımı sağlar +Comment[ug]=رەسىملەرنى susepaste.org مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення зображень за допомогою служби susepaste.org +Comment[vi]=Cho phép chia sẻ ảnh qua dịch vụ susepaste.org +Comment[wa]=Permete li pårtaedje d' imådjes e s' siervant do siervice susepaste.org +Comment[x-test]=xxAllows images to be shared using the susepaste.org servicexx +Comment[zh_CN]=用 susepaste.org 服务共享图片 +Comment[zh_TW]=允許使用 susepaste.org 服務分享影像 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=image/* + +X-KDE-PluginInfo-Name=imgsusepasteorg +X-KDE-PluginInfo-Author=Javier Llorente +X-KDE-PluginInfo-Email=javier@opensuse.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-Priority=1 + diff --git a/plasma/generic/dataengines/share/backends/imgur/CMakeLists.txt b/plasma/generic/dataengines/share/backends/imgur/CMakeLists.txt new file mode 100644 index 00000000..e71a1b43 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgur/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-imgur.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-imgur.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/imgur/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/imgur) diff --git a/plasma/generic/dataengines/share/backends/imgur/contents/code/main.js b/plasma/generic/dataengines/share/backends/imgur/contents/code/main.js new file mode 100644 index 00000000..ab86abf5 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgur/contents/code/main.js @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://imgur.com/api/upload"; +} + +function contentKey() { + return "image"; +} + +function setup() { + // key associated with plasma-devel@kde.org + // thanks to Alan Schaaf of Imgur (alan@imgur.com) + provider.addPostItem("key", "d0757bc2e94a0d4652f28079a0be9379", "text/plain"); +} + +function handleResultData(data) { + var res = provider.parseXML("original_image", data); + if (res == "") { + provider.error(data); + return; + } + provider.success(res); +} diff --git a/plasma/generic/dataengines/share/backends/imgur/metadata.desktop b/plasma/generic/dataengines/share/backends/imgur/metadata.desktop new file mode 100644 index 00000000..5dcc2e67 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/imgur/metadata.desktop @@ -0,0 +1,125 @@ +[Desktop Entry] +Name=Imgur +Name[ast]=Imgur +Name[bg]=Imgur +Name[bs]=Imgur +Name[ca]=Imgur +Name[ca@valencia]=Imgur +Name[cs]=Imgur +Name[da]=Imgur +Name[de]=Imgur +Name[el]=Imgur +Name[en_GB]=Imgur +Name[es]=Imgur +Name[et]=Imgur +Name[eu]=Imgur +Name[fi]=Imgur +Name[fr]=Imgur +Name[ga]=Imgur +Name[gl]=Imgur +Name[he]=Imgur +Name[hi]=इंगुर +Name[hr]=Imgur +Name[hu]=Imgur +Name[ia]=Imgur +Name[is]=Imgur +Name[it]=Imgur +Name[ja]=Imgur +Name[kk]=Imgur +Name[km]=Imgur +Name[kn]=Imgur +Name[ko]=Imgur +Name[lt]=Imgur +Name[lv]=Imgur +Name[mr]=Imgur +Name[nb]=Imgur +Name[nds]=imgur +Name[nl]=Imgur +Name[pa]=Imgur +Name[pl]=Imgur +Name[pt]=Imgur +Name[pt_BR]=Imgur +Name[ro]=Imgur +Name[ru]=Imgur +Name[sk]=Imgur +Name[sl]=Imgur +Name[sr]=Имгур +Name[sr@ijekavian]=Имгур +Name[sr@ijekavianlatin]=Imgur +Name[sr@latin]=Imgur +Name[sv]=Imgur +Name[th]=Imgur +Name[tr]=Imgur +Name[ug]=Imgur +Name[uk]=Imgur +Name[vi]=Imgur +Name[wa]=Imgur +Name[x-test]=xxImgurxx +Name[zh_CN]=Imgur +Name[zh_TW]=Imgur +Comment=Allows images to be shared using the imgur service +Comment[ar]=يسمح للصور أن تُشارك بإستخدام خدمة imgur +Comment[bg]=Позволява споделянето на картинки чрез imgur +Comment[bs]=Dopušta dijeljenje slika preko servisa Imgur +Comment[ca]=Permet la compartició d'imatges utilitzant el servei imgur +Comment[ca@valencia]=Permet la compartició d'imatges utilitzant el servei imgur +Comment[cs]=Povolí sdílení obrázků pomocí služby imgur +Comment[da]=Muliggør deling af billeder med tjenesten imgur +Comment[de]=Ermöglicht die Veröffentlichung von Bildern über den Imgur-Dienst +Comment[el]=Επιτρέπει το μοίρασμα των εικόνων χρησιμοποιώντας την υπηρεσία imgur +Comment[en_GB]=Allows images to be shared using the imgur service +Comment[es]=Permite compartir imágenes a través del servicio de imgur +Comment[et]=Piltide jagamine imguri teenuse kaudu +Comment[eu]=Irudiak imgur zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa kuvien jakamisen imgur-palvelussa +Comment[fr]=Permet le partage d'images à l'aide du service « imgur » +Comment[gl]=Permite compartir imaxes mediante o servizo imgur +Comment[he]=מאפשר שיתוף תמונות באמצעות השירות imgur +Comment[hr]=Omogućuje dijeljenje slika koristeći servis imgur +Comment[hu]=Képek megosztása az imgur szolgáltatás használatával +Comment[ia]=Il permitte imagines de esser compartite per usage de servicio imgur +Comment[is]=Gerir kleift að deila myndum með imgur þjónustunni +Comment[it]=Abilita la condivisione di immagini con il servizio imgur +Comment[ja]=imgur のサービスを用いた画像の共有を有効にする +Comment[kk]=Imgur қызметі көмегімен кескіндерді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​រូបភាព ដោយ​ប្រើ​សេវា imgur​​ +Comment[ko]=imgur로 그림을 공유합니다 +Comment[lt]=Įjungia dalinimąsį nuotraukomis naudojant imgur tarnybą +Comment[lv]=Ļauj kopīgot attēlus, izmantojot imgur servisu +Comment[mr]=imgur सेवा वापरुन प्रतिमा शेअर करतो +Comment[nb]=Gjør det mulig å dele bilder via tjenesten imgur +Comment[nds]=Biller op "imgur" praatstellen +Comment[nl]=Staat het delen van afbeeldingen toe met gebruik van de service imgur +Comment[pa]=imgur ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚਿੱਤਰ ਸਾਂਝੇ ਕਰਨ ਲਈ ਸਹਾਇਕ +Comment[pl]=Pozwala na udostępnianie obrazów przy użyciu usługi imgur +Comment[pt]=Permite a partilha de imagens com o serviço do 'imgur' +Comment[pt_BR]=Permite o compartilhamento de imagens usando o serviço do imgur +Comment[ro]=Permite partajarea imaginilor cu serviciul imgur +Comment[ru]=Позволяет публиковать изображения на сервере imgur.com +Comment[sk]=Povolí zdieľanie obrázkov pomocou služby imgur +Comment[sl]=Omogoča deljenje slik prek storitve imgur +Comment[sr]=Дељење слика преко сервиса Имгур +Comment[sr@ijekavian]=Дијељење слика преко сервиса Имгур +Comment[sr@ijekavianlatin]=Dijeljenje slika preko servisa Imgur +Comment[sr@latin]=Deljenje slika preko servisa Imgur +Comment[sv]=Tillåter att bilder delas genom att använda tjänsten imgur +Comment[tr]=imgur servisini kullanarak resimleri paylaşmayı sağlar +Comment[ug]=رەسىملەرنى imgur مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення зображень за допомогою служби imgur +Comment[vi]=Cho phép chia sẻ ảnh qua dịch vụ imgur +Comment[wa]=Permete li pårtaedje d' imådjes e s' siervant do siervice imgur +Comment[x-test]=xxAllows images to be shared using the imgur servicexx +Comment[zh_CN]=用 imgur 服务共享图片 +Comment[zh_TW]=允許使用 imgur 服務分享影像 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=image/* + +X-KDE-PluginInfo-Name=imgur +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/kde/CMakeLists.txt b/plasma/generic/dataengines/share/backends/kde/CMakeLists.txt new file mode 100644 index 00000000..8f323451 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/kde/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-kde.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-kde.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/kde/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/kde) diff --git a/plasma/generic/dataengines/share/backends/kde/contents/code/main.js b/plasma/generic/dataengines/share/backends/kde/contents/code/main.js new file mode 100644 index 00000000..5746a4e0 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/kde/contents/code/main.js @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://paste.kde.org/api/xml/create"; +} + +function method() { + return "POST"; +} + +function contentKey() { + return "data"; +} + +function setup() { + provider.addQueryItem("language", "text"); +} + +function handleResultData(data) { + var res = provider.parseXML("id", data); + if (res == "") { + provider.error(data); + return; + } + provider.success("http://paste.kde.org/" + res); +} + diff --git a/plasma/generic/dataengines/share/backends/kde/metadata.desktop b/plasma/generic/dataengines/share/backends/kde/metadata.desktop new file mode 100644 index 00000000..32ab8792 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/kde/metadata.desktop @@ -0,0 +1,111 @@ +[Desktop Entry] +Name=paste.kde.org +Name[bs]=paste.kde.org +Name[ca]=paste.kde.org +Name[ca@valencia]=paste.kde.org +Name[cs]=paste.kde.org +Name[da]=paste.kde.org +Name[de]=paste.kde.org +Name[el]=paste.kde.org +Name[en_GB]=paste.kde.org +Name[es]=paste.kde.org +Name[et]=paste.kde.org +Name[eu]=paste.kde.org +Name[fi]=paste.kde.org +Name[fr]=paste.kde.org +Name[gl]=paste.kde.org +Name[hu]=paste.kde.org +Name[ia]=paste.kde.org +Name[it]=paste.kde.org +Name[kk]=paste.kde.org +Name[ko]=paste.kde.org +Name[lt]=paste.kde.org +Name[mr]=paste.kde.org +Name[nb]=paste.kde.org +Name[nds]=paste.kde.org +Name[nl]=paste.kde.org +Name[pa]=paste.kde.org +Name[pl]=paste.kde.org +Name[pt]=paste.kde.org +Name[pt_BR]=paste.kde.org +Name[ro]=paste.kde.org +Name[ru]=paste.kde.org +Name[sk]=paste.kde.org +Name[sl]=paste.kde.org +Name[sr]=paste.kde.org +Name[sr@ijekavian]=paste.kde.org +Name[sr@ijekavianlatin]=paste.kde.org +Name[sr@latin]=paste.kde.org +Name[sv]=paste.kde.org +Name[tr]=paste.kde.org +Name[uk]=paste.kde.org +Name[x-test]=xxpaste.kde.orgxx +Name[zh_CN]=paste.kde.org +Name[zh_TW]=paste.kde.org +Comment=Allows text to be shared using the kde.org service +Comment[ar]=يسمح للنصوص أن تُشارك بإستخدام خدمة kde.org +Comment[bg]=Позволява споделянето на текст чрез kde.org +Comment[bs]=Dopušta ijeljenje teksta preko servisa wklej.org +Comment[ca]=Permet la compartició de text utilitzant el servei kde.org +Comment[ca@valencia]=Permet la compartició de text utilitzant el servei kde.org +Comment[cs]=Povolí sdílení textů pomocí služby kde.org +Comment[da]=Muliggør deling af tekst med tjenesten kde.org +Comment[de]=Ermöglicht die Veröffentlichung von Text über den kde.org-Dienst +Comment[el]=Επιτρέπει στο κείμενο να γίνει κοινόχρηστο χρησιμοποιώντας την υπηρεσία kde.org +Comment[en_GB]=Allows text to be shared using the kde.org service +Comment[es]=Permite compartir texto a través del servicio de kde.org +Comment[et]=Teksti jagamine kde.org teenuse kaudu +Comment[eu]=Testua kde.org zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa tekstin jakamisen kde.org-palvelussa +Comment[fr]=Permet le partage de texte à l'aide du service « kde.org » +Comment[gl]=Permite compartir texto mediante o servizo kde.org +Comment[he]=מאפשר שיתוף טקסט באמצעות השירות kde.org +Comment[hr]=Omogućuje dijeljenje teksta koristeći servis kde.org +Comment[hu]=Szöveg megosztása a kde.org szolgáltatás használatával +Comment[ia]=Il permitte texto de esser compartite per usar le servicio kde.org +Comment[is]=Gerir kleift að deila texta með kde.org límklippusafninu +Comment[it]=Abilita la condivisione di immagini con il servizio kde.org +Comment[ja]=kde.org のサービスを用いたテキストの共有を有効にする +Comment[kk]=kde.org қызметі көмегімен мәтінді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​អត្ថបទ​ដោយ​ប្រើ​សេវា kde.org +Comment[ko]=kde.org로 텍스트를 공유합니다 +Comment[lt]=Įjungia dalinimąsį tekstu naudojant kde.org tarnybą +Comment[lv]=Ļauj kopīgot tekstu, izmantojot kde.org servisu +Comment[mr]=kde.org सेवा वापरुन पाठ्य शेअर करतो +Comment[nb]=Gjør det mulig å dele tekst via tjenesten kde.org +Comment[nds]=Text op "kde.org" praatstellen +Comment[nl]=Staat het delen van tekst toe met gebruik van de service kde.org +Comment[pa]=kde.org ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਟੈਕਸਟ ਸਾਂਝਾ ਕਰਨਾ ਯੋਗ +Comment[pl]=Pozwala na udostępnianie tekstu przy użyciu usługi kde.org +Comment[pt]=Permite a partilha de texto com o serviço do 'kde.org' +Comment[pt_BR]=Permite o compartilhamento de texto usando o serviço do kde.org +Comment[ro]=Permite partajarea textului cu serviciul kde.org +Comment[ru]=Позволяет публиковать текст на сервере kde.org +Comment[sk]=Povolí zdieľanie textu pomocou služby kde.org +Comment[sl]=Omogoča deljenje besedila prek storitve kde.org +Comment[sr]=Дељење текста преко сервиса kde.org +Comment[sr@ijekavian]=Дијељење текста преко сервиса kde.org +Comment[sr@ijekavianlatin]=Dijeljenje teksta preko servisa kde.org +Comment[sr@latin]=Deljenje teksta preko servisa kde.org +Comment[sv]=Tillåter att text delas genom att använda tjänsten kde.org +Comment[tr]=kde.org servisini kullanarak metinleri paylaşmayı sağlar +Comment[ug]=تېكىستلەرنى kde.org مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення фрагментів тексту за допомогою служби kde.org +Comment[vi]=Cho phép chia sẻ văn bản qua dịch vụ kde.org +Comment[wa]=Permete li pårtaedje di scrijhaedje e s' siervant do siervice kde.org +Comment[x-test]=xxAllows text to be shared using the kde.org servicexx +Comment[zh_CN]=用 kde.org 服务共享文字 +Comment[zh_TW]=允許使用 kde.org 服務分享文字 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=kde +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-Priority=100 + diff --git a/plasma/generic/dataengines/share/backends/pastebincom/CMakeLists.txt b/plasma/generic/dataengines/share/backends/pastebincom/CMakeLists.txt new file mode 100644 index 00000000..308f8030 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pastebincom/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pastebincom.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pastebincom.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pastebincom/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pastebincom) diff --git a/plasma/generic/dataengines/share/backends/pastebincom/contents/code/main.js b/plasma/generic/dataengines/share/backends/pastebincom/contents/code/main.js new file mode 100644 index 00000000..ef4b70d4 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pastebincom/contents/code/main.js @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://pastebin.com/api_public.php"; +} + +function contentKey() { + return "paste_code"; +} + +function setup() { + provider.addQueryItem("paste_name", "Test"); +} + +function handleResultData(data) { + if (data.search("ERROR") != -1) { + provider.error(data); + return; + } + provider.success(data); +} + diff --git a/plasma/generic/dataengines/share/backends/pastebincom/metadata.desktop b/plasma/generic/dataengines/share/backends/pastebincom/metadata.desktop new file mode 100644 index 00000000..529fbc82 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pastebincom/metadata.desktop @@ -0,0 +1,126 @@ +[Desktop Entry] +Name=pastebin.com +Name[ar]=pastebin.com +Name[ast]=pastebin.com +Name[bg]=pastebin.com +Name[bs]=pastebin.com +Name[ca]=pastebin.com +Name[ca@valencia]=pastebin.com +Name[cs]=pastebin.com +Name[da]=pastebin.com +Name[de]=pastebin.com +Name[el]=pastebin.com +Name[en_GB]=pastebin.com +Name[es]=pastebin.com +Name[et]=pastebin.com +Name[eu]=pastebin.com +Name[fi]=pastebin.com +Name[fr]=pastebin.com +Name[ga]=pastebin.com +Name[gl]=pastebin.com +Name[gu]=pastebin.com +Name[he]=pastebin.com +Name[hi]=pastebin.com +Name[hr]=pastebin.com +Name[hu]=pastebin.com +Name[ia]=pastebin.com +Name[is]=pastebin.com +Name[it]=pastebin.com +Name[ja]=pastebin.com +Name[kk]=pastebin.com +Name[km]=pastebin.com +Name[ko]=pastebin.com +Name[lt]=pastebin.com +Name[lv]=pastebin.com +Name[mr]=pastebin.com +Name[nb]=pastebin.com +Name[nds]=pastebin.com +Name[nl]=pastebin.com +Name[pa]=pastebin.com +Name[pl]=pastebin.com +Name[pt]=pastebin.com +Name[pt_BR]=pastebin.com +Name[ro]=pastebin.com +Name[ru]=pastebin.com +Name[sk]=pastebin.com +Name[sl]=pastebin.com +Name[sr]=pastebin.com +Name[sr@ijekavian]=pastebin.com +Name[sr@ijekavianlatin]=pastebin.com +Name[sr@latin]=pastebin.com +Name[sv]=pastebin.com +Name[tg]=pastebin.com +Name[th]=pastebin.com +Name[tr]=pastebin.com +Name[ug]=pastebin.com +Name[uk]=pastebin.com +Name[wa]=pastebin.com +Name[x-test]=xxpastebin.comxx +Name[zh_CN]=pastebin.com +Name[zh_TW]=pastebin.com +Comment=Allows text to be shared using the pastebin.com service +Comment[ar]=يسمح للنصوص أن تُشارك بإستخدام خدمة pastebin.com +Comment[bg]=Позволява споделянето на текст чрез pastebin.com +Comment[bs]=Omogućava dijeljenje teksta preko servisa pastebin.com +Comment[ca]=Permet la compartició de text utilitzant el servei pastebin.com +Comment[ca@valencia]=Permet la compartició de text utilitzant el servei pastebin.com +Comment[cs]=Povolí sdílení textů pomocí služby pastebin.com +Comment[da]=Muliggør deling af tekst med tjenesten pastebin.com +Comment[de]=Ermöglicht die Veröffentlichung von Text über den pastebin.com-Dienst +Comment[el]=Επιτρέπει στο κείμενο να γίνει κοινόχρηστο χρησιμοποιώντας την υπηρεσία pastebin.com +Comment[en_GB]=Allows text to be shared using the pastebin.com service +Comment[es]=Permite compartir texto a través del servicio de pastebin.com +Comment[et]=Teksti jagamine pastebin.com teenuse kaudu +Comment[eu]=Testua pastebin.com zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa tekstin jakamisen pastebin.com-palvelussa +Comment[fr]=Permet le partage de texte à l'aide du service « pastebin.com » +Comment[gl]=Permite compartir texto mediante o servizo pastebin.org +Comment[he]=מאפשר שיתוף טקסט באמצעות השירות pastebin.com +Comment[hr]=Omogućuje dijeljenje teksta koristeći servis pastebin.com +Comment[hu]=Szöveg megosztása a pastebin.com szolgáltatás használatával +Comment[ia]=Il permitte texto de esser compartite per usar le servicio pastebin.com +Comment[is]=Gerir kleift að deila texta með pastebin.com límklippusafninu +Comment[it]=Abilita la condivisione di testo con il servizio pastebin.com +Comment[ja]=pastebin.com のサービスを用いたテキストの共有を有効にする +Comment[kk]=pastebin.com қызметі көмегімен мәтінді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​អត្ថបទ ដោយ​ប្រើ​សេវា pastebin.com +Comment[ko]=pastebin.com으로 텍스트를 공유합니다 +Comment[lt]=Įjungia dalinimąsį tekstu naudojant pastebin.com tarnybą +Comment[lv]=Ļauj kopīgot tekstu, izmantojot pastebin.com servisu +Comment[mr]=pastebin.com सेवा वापरुन पाठ्य शेअर करतो +Comment[nb]=Gjør det mulig å dele tekst via tjenesten pastebin.com +Comment[nds]=Text op "pastebin.com" praatstellen +Comment[nl]=Staat het delen van tekst toe met gebruik van de service pastebin.com +Comment[pa]=pastebin.com ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਟੈਕਸਟ ਸਾਂਝਾ ਕਰੋ +Comment[pl]=Pozwala na udostępnianie tekstu przy użyciu usługi pastebin.com +Comment[pt]=Permite a partilha de texto com o serviço do 'pastebin.com' +Comment[pt_BR]=Permite o compartilhamento de texto usando o serviço do pastebin.com +Comment[ro]=Permite partajarea textului cu serviciul pastebin.com +Comment[ru]=Позволяет публиковать текст на сервере pastebin.com +Comment[sk]=Povolí zdieľanie textu pomocou služby pastebin.com +Comment[sl]=Omogoča deljenje besedila prek storitve pastebin.com +Comment[sr]=Дељење текста преко сервиса pastebin.com +Comment[sr@ijekavian]=Дијељење текста преко сервиса pastebin.com +Comment[sr@ijekavianlatin]=Dijeljenje teksta preko servisa pastebin.com +Comment[sr@latin]=Deljenje teksta preko servisa pastebin.com +Comment[sv]=Tillåter att text delas genom att använda tjänsten pastebin.com +Comment[tr]=pastebin.com servisini kullanarak metinleri paylaşmayı sağlar +Comment[ug]=تېكىستلەرنى pastebin.com مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення фрагментів тексту за допомогою служби pastebin.com +Comment[vi]=Cho phép chia sẻ văn bản qua dịch vụ pastebin.com +Comment[wa]=Permete li pårtaedje di scrijhaedje e s' siervant do siervice pastebin.com +Comment[x-test]=xxAllows text to be shared using the pastebin.com servicexx +Comment[zh_CN]=用 pastebin.com 服务共享文字 +Comment[zh_TW]=允許使用 pastebin.com 服務分享文字 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=pastebincom +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/pasteopensuseorg/CMakeLists.txt b/plasma/generic/dataengines/share/backends/pasteopensuseorg/CMakeLists.txt new file mode 100644 index 00000000..f2e6a93e --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteopensuseorg/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pasteopensuseorg.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pasteopensuseorg.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pasteopensuseorg) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pasteopensuseorg) diff --git a/plasma/generic/dataengines/share/backends/pasteopensuseorg/contents/code/main.js b/plasma/generic/dataengines/share/backends/pasteopensuseorg/contents/code/main.js new file mode 100644 index 00000000..6beaacb9 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteopensuseorg/contents/code/main.js @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2010 by Will Stephenson * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://paste.opensuse.org"; +} + +function contentKey() { + return "code"; +} + +function setup() { + provider.addQueryItem("name", "KDE"); + provider.addQueryItem("title", "mypaste"); + provider.addQueryItem("lang", "text"); + provider.addQueryItem("expire", "1440"); + provider.addQueryItem("submit", "submit"); +} + +function handleResultData(data) { + var res = data.match("(Info.+)"); + if (res != "") { + return; + } + provider.error(data); +} + +function handleRedirection(url) { + provider.success(url); +} diff --git a/plasma/generic/dataengines/share/backends/pasteopensuseorg/metadata.desktop b/plasma/generic/dataengines/share/backends/pasteopensuseorg/metadata.desktop new file mode 100644 index 00000000..67375527 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteopensuseorg/metadata.desktop @@ -0,0 +1,127 @@ +[Desktop Entry] +Name=paste.opensuse.org +Name[ar]=paste.opensuse.org +Name[ast]=paste.opensuse.org +Name[bg]=paste.opensuse.org +Name[bs]=paste.opensuse.org +Name[ca]=paste.opensuse.org +Name[ca@valencia]=paste.opensuse.org +Name[cs]=paste.opensuse.org +Name[da]=paste.opensuse.org +Name[de]=paste.opensuse.org +Name[el]=paste.opensuse.org +Name[en_GB]=paste.opensuse.org +Name[es]=paste.opensuse.org +Name[et]=paste.opensuse.org +Name[eu]=paste.opensuse.org +Name[fi]=paste.opensuse.org +Name[fr]=paste.opensuse.org +Name[ga]=paste.opensuse.org +Name[gl]=paste.opensuse.org +Name[gu]=paste.opensuse.org +Name[he]=paste.opensuse.org +Name[hi]=paste.opensuse.org +Name[hr]=paste.opensuse.org +Name[hu]=paste.opensuse.org +Name[ia]=paste.opensuse.org +Name[is]=paste.opensuse.org +Name[it]=paste.opensuse.org +Name[ja]=paste.opensuse.org +Name[kk]=paste.opensuse.org +Name[km]=paste.opensuse.org +Name[ko]=paste.opensuse.org +Name[lt]=paste.opensuse.org +Name[lv]=paste.opensuse.org +Name[mr]=paste.opensuse.org +Name[nb]=paste.opensuse.org +Name[nds]=paste.opensuse.org +Name[nl]=paste.opensuse.org +Name[pa]=paste.opensuse.org +Name[pl]=paste.opensuse.org +Name[pt]=paste.opensuse.org +Name[pt_BR]=paste.opensuse.org +Name[ro]=paste.opensuse.org +Name[ru]=paste.opensuse.org +Name[sk]=paste.opensuse.org +Name[sl]=paste.opensuse.org +Name[sr]=paste.opensuse.org +Name[sr@ijekavian]=paste.opensuse.org +Name[sr@ijekavianlatin]=paste.opensuse.org +Name[sr@latin]=paste.opensuse.org +Name[sv]=paste.opensuse.org +Name[tg]=paste.opensuse.org +Name[th]=paste.opensuse.org +Name[tr]=paste.opensuse.org +Name[ug]=paste.opensuse.org +Name[uk]=paste.opensuse.org +Name[wa]=paste.opensuse.org +Name[x-test]=xxpaste.opensuse.orgxx +Name[zh_CN]=paste.opensuse.org +Name[zh_TW]=paste.opensuse.org +Comment=Paste text with openSUSE +Comment[ast]=Apegar testu con openSUSE +Comment[bg]=Поставяне на текст през openSUSE +Comment[bs]=Opensuseov servis za naljepljivanje teksta +Comment[ca]=Enganxa text amb openSUSE +Comment[ca@valencia]=Apega text amb openSUSE +Comment[cs]=Vložit text s využitím openSUSE +Comment[da]=Indsæt tekst med openSUSE +Comment[de]=Text auf paste.opensuse.org veröffentlichen +Comment[el]=Επικόλληση κειμένου με το openSUSE +Comment[en_GB]=Paste text with openSUSE +Comment[es]=Pegar texto con openSUSE +Comment[et]=Teksti asetamine openSUSE abil +Comment[eu]=Itsatsi testua OpenSUSE-rekin +Comment[fi]=Liitä tekstiä openSUSEn avulla +Comment[fr]=Colle du texte avec Open-SUSE +Comment[gl]=Apega texto con openSUSE +Comment[he]=שיתוף קטעי טקסט באמצעות openSUSE +Comment[hr]=Zalijepi tekst pomoću openSUSE-a +Comment[hu]=Szöveg beillesztése openSUSE-val +Comment[ia]=Colla texto con openSUSE +Comment[is]=Líma texta með openSUSE +Comment[it]=Incolla testo con openSUSE +Comment[ja]=openSUSE でテキストを貼りつける +Comment[kk]=openSUSE-ден мәтіді алып орналастыру +Comment[km]=បិទភ្ជាប់​​នៅ​ក្នុង​អូផឹនស៊ូស៊ី +Comment[ko]=openSUSE 텍스트 공유 서비스 +Comment[lt]=Padėti tekstą naudojant openSUSE +Comment[lv]=Ielīmēt tekstu ar openSUSE +Comment[mr]=openSUSE वापरुन पाठ्य चिटकवा +Comment[nb]=Lim inn tekst med openSUSE +Comment[nds]=Text op "openSUSE" praatstellen +Comment[nl]=Plak tekst met openSUSE +Comment[pa]=openSUSE ਨਾਲ ਟੈਕਸਟ ਚੇਪੋopenSUSE ਨਾਲ ਟੈਕਸਟ ਚਪੇ +Comment[pl]=Wklejanie tekstu z openSUSE +Comment[pt]=Colar texto com o openSUSE +Comment[pt_BR]=Colar texto com o openSUSE +Comment[ro]=Lipește text cu openSUSE +Comment[ru]=Позволяет публиковать текст на сервере openSUSE +Comment[sk]=Vloží text pomocou služby openSUSE +Comment[sl]=Prilepite besedilo z openSUSE +Comment[sr]=Опенсусеов сервис за налепљивање текста +Comment[sr@ijekavian]=Опенсусеов сервис за наљепљивање текста +Comment[sr@ijekavianlatin]=OpenSuSE‑ov servis za naljepljivanje teksta +Comment[sr@latin]=OpenSuSE‑ov servis za nalepljivanje teksta +Comment[sv]=Klistra in text med openSUSE +Comment[tg]=Часпондани матн бо openSUSE +Comment[th]=แปะข้อความไปยังบริการของ openSUSE +Comment[tr]=Metinleri openSUSE servini kullanarak paylaş +Comment[ug]=openSUSE تىن تېكىست چاپلا +Comment[uk]=Вставити фрагмент тексту з openSUSE +Comment[wa]=Aclaper do tecse avou openSUSE +Comment[x-test]=xxPaste text with openSUSExx +Comment[zh_CN]=用 openSUSE 粘贴文字 +Comment[zh_TW]=用 openSUSE 貼上文字 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=pasteopensuseorg +X-KDE-PluginInfo-Author=Will Stephenson +X-KDE-PluginInfo-Email=wstephenson@suse.de +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/pasteubuntucom/CMakeLists.txt b/plasma/generic/dataengines/share/backends/pasteubuntucom/CMakeLists.txt new file mode 100644 index 00000000..294f20d9 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteubuntucom/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pasteubuntucom.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-pasteubuntucom.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pasteubuntucom) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/pasteubuntucom) diff --git a/plasma/generic/dataengines/share/backends/pasteubuntucom/contents/code/main.js b/plasma/generic/dataengines/share/backends/pasteubuntucom/contents/code/main.js new file mode 100644 index 00000000..e0d768b9 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteubuntucom/contents/code/main.js @@ -0,0 +1,41 @@ +/* + Copyright © 2010 Harald Sitter + + 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) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + 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. If not, see . +*/ + +function url() { + return "http://paste.ubuntu.com"; +} + +function contentKey() { + return "content"; +} + +function setup() { + provider.addQueryItem("poster", "KDE"); + provider.addQueryItem("syntax", "text"); +} + +function handleResultData(data) { + // Whenever no redirection was received, it is an error + provider.error(data); +} + +function handleRedirection(url) { + provider.success(url); +} diff --git a/plasma/generic/dataengines/share/backends/pasteubuntucom/metadata.desktop b/plasma/generic/dataengines/share/backends/pasteubuntucom/metadata.desktop new file mode 100644 index 00000000..00932a39 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/pasteubuntucom/metadata.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Name=paste.ubuntu.com +Name[ar]=paste.ubuntu.com +Name[ast]=paste.ubuntu.com +Name[bg]=paste.ubuntu.com +Name[bs]=paste.ubuntu.com +Name[ca]=paste.ubuntu.com +Name[ca@valencia]=paste.ubuntu.com +Name[cs]=paste.ubuntu.com +Name[da]=paste.ubuntu.com +Name[de]=paste.ubuntu.com +Name[el]=paste.ubuntu.com +Name[en_GB]=paste.ubuntu.com +Name[es]=paste.ubuntu.com +Name[et]=paste.ubuntu.com +Name[eu]=paste.ubuntu.com +Name[fi]=paste.ubuntu.com +Name[fr]=paste.ubuntu.com +Name[ga]=paste.ubuntu.com +Name[gl]=paste.ubuntu.com +Name[gu]=paste.ubuntu.com +Name[he]=paste.ubuntu.com +Name[hi]=paste.ubuntu.com +Name[hr]=paste.ubuntu.com +Name[hu]=paste.ubuntu.com +Name[ia]=paste.ubuntu.com +Name[is]=paste.ubuntu.com +Name[it]=paste.ubuntu.com +Name[ja]=paste.ubuntu.com +Name[kk]=paste.ubuntu.com +Name[km]=paste.ubuntu.com +Name[ko]=paste.ubuntu.com +Name[lt]=paste.ubuntu.com +Name[lv]=paste.ubuntu.com +Name[mr]=paste.ubuntu.com +Name[nb]=paste.ubuntu.com +Name[nds]=paste.ubuntu.com +Name[nl]=paste.ubuntu.com +Name[pa]=paste.ubuntu.com +Name[pl]=paste.ubuntu.com +Name[pt]=paste.ubuntu.com +Name[pt_BR]=paste.ubuntu.com +Name[ro]=paste.ubuntu.com +Name[ru]=paste.ubuntu.com +Name[sk]=paste.ubuntu.com +Name[sl]=paste.ubuntu.com +Name[sr]=paste.ubuntu.com +Name[sr@ijekavian]=paste.ubuntu.com +Name[sr@ijekavianlatin]=paste.ubuntu.com +Name[sr@latin]=paste.ubuntu.com +Name[sv]=paste.ubuntu.com +Name[th]=paste.ubuntu.com +Name[tr]=paste.ubuntu.com +Name[ug]=paste.ubuntu.com +Name[uk]=paste.ubuntu.com +Name[wa]=paste.ubuntu.com +Name[x-test]=xxpaste.ubuntu.comxx +Name[zh_CN]=paste.ubuntu.com +Name[zh_TW]=paste.ubuntu.com +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=pasteubuntucom +X-KDE-PluginInfo-Author=Harald Sitter +X-KDE-PluginInfo-Email=apachelogger@ubuntu.com +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://www.ubuntu.com diff --git a/plasma/generic/dataengines/share/backends/privatepaste/CMakeLists.txt b/plasma/generic/dataengines/share/backends/privatepaste/CMakeLists.txt new file mode 100644 index 00000000..4dbbb3e9 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/privatepaste/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-privatepastecom.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-privatepastecom.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/privatepastecom) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/privatepastecom) diff --git a/plasma/generic/dataengines/share/backends/privatepaste/contents/code/main.js b/plasma/generic/dataengines/share/backends/privatepaste/contents/code/main.js new file mode 100644 index 00000000..243037f9 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/privatepaste/contents/code/main.js @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://privatepaste.com/save"; +} + +function contentKey() { + return "paste_content"; +} + +function setup() { + provider.addQueryItem("_xsrf", "d38415c699a0408ebfce524c2dc0a4ba"); + provider.addQueryItem("formatting", "No Formatting"); + provider.addQueryItem("line_numbers", "on"); + provider.addQueryItem("expire", "31536000"); + provider.addQueryItem("secure_paste", "off"); +} + +function handleResultData(data) { + var res = data.match("(Error.+)"); + if (res != "") { + return; + } + provider.error(data); +} + +function handleRedirection(url) { + provider.success(url); +} diff --git a/plasma/generic/dataengines/share/backends/privatepaste/metadata.desktop b/plasma/generic/dataengines/share/backends/privatepaste/metadata.desktop new file mode 100644 index 00000000..63f5bab5 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/privatepaste/metadata.desktop @@ -0,0 +1,125 @@ +[Desktop Entry] +Name=privatepaste.com +Name[ar]=privatepaste.com +Name[ast]=privatepaste.com +Name[bg]=privatepaste.com +Name[bs]=privatepaste.com +Name[ca]=privatepaste.com +Name[ca@valencia]=privatepaste.com +Name[cs]=privatepaste.com +Name[da]=privatepaste.com +Name[de]=privatepaste.com +Name[el]=privatepaste.com +Name[en_GB]=privatepaste.com +Name[es]=privatepaste.com +Name[et]=privatepaste.com +Name[eu]=privatepaste.com +Name[fi]=privatepaste.com +Name[fr]=privatepaste.com +Name[ga]=privatepaste.com +Name[gl]=privatepaste.com +Name[gu]=privatepaste.com +Name[he]=privatepaste.com +Name[hi]=privatepaste.com +Name[hr]=privatepaste.com +Name[hu]=privatepaste.com +Name[ia]=privatepaste.com +Name[is]=privatepaste.com +Name[it]=privatepaste.com +Name[ja]=privatepaste.com +Name[kk]=privatepaste.com +Name[km]=privatepaste.com +Name[ko]=privatepaste.com +Name[lt]=privatepaste.com +Name[lv]=privatepaste.com +Name[mr]=privatepaste.com +Name[nb]=privatepaste.com +Name[nds]=privatepaste.com +Name[nl]=privatepaste.com +Name[pa]=privatepaste.com +Name[pl]=privatepaste.com +Name[pt]=privatepaste.com +Name[pt_BR]=privatepaste.com +Name[ro]=privatepaste.com +Name[ru]=privatepaste.com +Name[sk]=privatepaste.com +Name[sl]=privatepaste.com +Name[sr]=privatepaste.com +Name[sr@ijekavian]=privatepaste.com +Name[sr@ijekavianlatin]=privatepaste.com +Name[sr@latin]=privatepaste.com +Name[sv]=privatepaste.com +Name[th]=privatepaste.com +Name[tr]=privatepaste.com +Name[ug]=privatepaste.com +Name[uk]=privatepaste.com +Name[wa]=privatepaste.com +Name[x-test]=xxprivatepaste.comxx +Name[zh_CN]=privatepaste.com +Name[zh_TW]=privatepaste.com +Comment=Paste text with the PrivatePaste.com service +Comment[ast]=Apegar testu per aciu del serviciu PrivatePaste.com +Comment[bg]=Поставяне на текст през услугата PrivatePaste.com +Comment[bs]=Naljepljivanje teksta preko servisa privatepaste.com +Comment[ca]=Enganxa text amb el servei PrivatePaste.com +Comment[ca@valencia]=Apega text amb el servei PrivatePaste.com +Comment[cs]=Vložit text s využitím služby PrivatePaste.com +Comment[da]=Indsæt tekst med tjenesten PrivatePaste.com +Comment[de]=Text auf PrivatePaste.com veröffentlichen +Comment[el]=Επικόλληση κειμένου με την υπηρεσία PrivatePaste.com +Comment[en_GB]=Paste text with the PrivatePaste.com service +Comment[es]=Pegar texto mediante el servicio PrivatePaste.com +Comment[et]=Teksti asetamine PrivatePaste.com teenuse abil +Comment[eu]=Itsatsi testua PrivatePaste.com zerbitzuaren bidez +Comment[fi]=Liitä tekstiä PrivatePaste.com-palvelun avulla +Comment[fr]=Colle du texte à l'aide du service « PrivatePaste.com » +Comment[gl]=Apega texto co servizo PrivatePaste.com +Comment[he]=שיתוף קטעי טקסט באמצעות PrivatePaste.com +Comment[hr]=Zalijepi tekst pomoću servisa PrivatePaste.com +Comment[hu]=Szöveg beillesztése a PrivatePaste.com szolgáltatással +Comment[ia]=Colla texto con le servicio PrivatePaste.com +Comment[is]=Líma texta með PrivatePaste.com límklippusafninu +Comment[it]=Incolla testo con il servizio PrivatePaste.com +Comment[ja]=PrivatePaste.com のサービスを用いてテキストを貼り付ける +Comment[kk]=PrivatePaste.com қызметінен мәтінді алып орналастыру +Comment[km]=បិទភ្ជាប់​អត្ថបទ​ដោយ​ប្រើ​សេវា PrivatePaste.com +Comment[ko]=PrivatePaste.com으로 텍스트를 공유합니다 +Comment[lt]=Padėti tekstą naudojant PrivatePaste.com tarnybą +Comment[lv]=Ielīmēt tekstu ar PrivatePaste.com servisu +Comment[mr]=privatepaste.com सेवा वापरुन पाठ्य चिटकवा +Comment[nb]=Lim inn tekst med tjenesten PrivatePaste.com +Comment[nds]=Text op "PrivatePaste.com" praatstellen +Comment[nl]=Plak tekst met de service PrivatePaste.com +Comment[pa]=PrivatePaste.com ਸਰਵਿਸ ਨਾਲ ਟੈਕਸਟ ਚੇਪੋ +Comment[pl]=Wklejanie tekstu z usługą PrivatePaste.com +Comment[pt]=Colar texto com o serviço PrivatePaste.com +Comment[pt_BR]=Colar texto com o serviço PrivatePaste.com +Comment[ro]=Lipește text cu serviciul PrivatePaste.com +Comment[ru]=Позволяет публиковать текст на сервере PrivatePaste.com +Comment[sk]=Vloží text pomocou služby PrivatePaste.com +Comment[sl]=Prilepite besedilo s storitvijo PrivatePaste.com +Comment[sr]=Налепљивање текста преко сервиса privatepaste.com +Comment[sr@ijekavian]=Наљепљивање текста преко сервиса privatepaste.com +Comment[sr@ijekavianlatin]=Naljepljivanje teksta preko servisa privatepaste.com +Comment[sr@latin]=Nalepljivanje teksta preko servisa privatepaste.com +Comment[sv]=Klistra in text med tjänsten PrivatePaste.com +Comment[th]=แปะข้อความไปยังบริการของ PrivatePaste.com +Comment[tr]=Metinleri PrivatePaste.com servisini kullanarak paylaş +Comment[ug]=PrivatePaste.com مۇلازىمىتىدىن تېكىست چاپلا +Comment[uk]=Вставка фрагментів тексту за допомогою служби PrivatePaste.com +Comment[wa]=Aclaper do tecse avou l' siervice PrivatePaste.com +Comment[x-test]=xxPaste text with the PrivatePaste.com servicexx +Comment[zh_CN]=用 PrivatePaste.com 服务粘贴文字 +Comment[zh_TW]=用 PrivatePaste.com 服務貼上文字 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=privatepastecom +X-KDE-PluginInfo-Author=Artur Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/simplestimagehosting/CMakeLists.txt b/plasma/generic/dataengines/share/backends/simplestimagehosting/CMakeLists.txt new file mode 100644 index 00000000..a7961fb0 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/simplestimagehosting/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-simplestimagehosting.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-simplestimagehosting.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/simplestimagehosting/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/simplestimagehosting) diff --git a/plasma/generic/dataengines/share/backends/simplestimagehosting/contents/code/main.js b/plasma/generic/dataengines/share/backends/simplestimagehosting/contents/code/main.js new file mode 100644 index 00000000..bb68974d --- /dev/null +++ b/plasma/generic/dataengines/share/backends/simplestimagehosting/contents/code/main.js @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://api.simplest-image-hosting.net/upload:image,default"; +} + +function contentKey() { + return "fileName"; +} + +function setup() { +} + +function handleResultData(data) { + var res = data.match("800\n(http://.+)\n"); + if (res == "") { + provider.error(data); + return; + } + provider.success(data.replace("800", "").replace("\n", "")); +} diff --git a/plasma/generic/dataengines/share/backends/simplestimagehosting/metadata.desktop b/plasma/generic/dataengines/share/backends/simplestimagehosting/metadata.desktop new file mode 100644 index 00000000..acfed83c --- /dev/null +++ b/plasma/generic/dataengines/share/backends/simplestimagehosting/metadata.desktop @@ -0,0 +1,121 @@ +[Desktop Entry] +Name=Simplest Image Hosting +Name[ar]=أبسط إستضافة للصور +Name[ast]=Simplest Image Hosting +Name[bg]=Simplest Image Hosting +Name[bs]=Simplest Image Hosting +Name[ca]=Simplest Image Hosting +Name[ca@valencia]=Simplest Image Hosting +Name[cs]=Simplest Image Hosting +Name[da]=Simplest Image Hosting +Name[de]=Simplest Image Hosting +Name[el]=Πιο απλή φιλοξενία εικόνας +Name[en_GB]=Simplest Image Hosting +Name[es]=Simplest Image Hosting +Name[et]=Simplest Image Hosting +Name[eu]=Simplest Image Hosting +Name[fi]=Simplest Image Hosting +Name[fr]=Simplest Image Hosting +Name[gl]=Simplest Image Hosting +Name[he]=Simplest Image Hosting +Name[hr]=Simplest Image Hosting +Name[hu]=Simplest Image Hosting +Name[ia]=Simplest Image Hosting +Name[is]=Simplest Image Hosting +Name[it]=Simplest Image Hosting +Name[ja]=Simplest Image Hosting +Name[kk]=Simplest Image Hosting +Name[km]=ការ​បង្ហោះរូបភាព​សាមញ្ញ​បំផុត +Name[ko]=Simplest Image Hosting +Name[lt]=Paprasčiausias nuotraukų talpinimas +Name[lv]=Simplest Image Hosting +Name[mr]=सिंप्लेस्ट प्रतिमा होस्टींग +Name[nb]=Simplest Image Hosting +Name[nds]=Simplest-Image-Hosting +Name[nl]=Simplest Image Hosting +Name[pa]=ਸੈਂਪਲਸਟ ਈਮੇਜ਼ ਹੋਸਟਿੰਗ +Name[pl]=Simplest Image Hosting +Name[pt]=Simplest Image Hosting +Name[pt_BR]=Simplest Image Hosting +Name[ro]=Cea mai simplă găzduire de imagini +Name[ru]=Simplest-Image-Hosting.net +Name[sk]=Simplest Image Hosting +Name[sl]=Simplest Image Hosting +Name[sr]=Симплест имејџ хостинг +Name[sr@ijekavian]=Симплест имејџ хостинг +Name[sr@ijekavianlatin]=Simplest Image Hosting +Name[sr@latin]=Simplest Image Hosting +Name[sv]=Simplest Image Hosting +Name[th]=บริการ Simplest Image Hosting +Name[tr]=Simplest Image Hosting +Name[ug]=Simplest Image Hosting +Name[uk]=Simplest Image Hosting +Name[wa]=Simplest Image Hosting +Name[x-test]=xxSimplest Image Hostingxx +Name[zh_CN]=Simplest Image Hosting +Name[zh_TW]=Simplest Image Hosting +Comment=Allows images to be shared using the Simplest Image Hosting service +Comment[bg]=Позволява споделяне на изображения чрез услугата Simplest Image Hosting +Comment[bs]=Dijeljenje slika preko servisa Simplest image hosting +Comment[ca]=Permet la compartició d'imatges utilitzant el servei «Simplest Image Hosting» +Comment[ca@valencia]=Permet la compartició d'imatges utilitzant el servei «Simplest Image Hosting» +Comment[cs]=Povolí sdílení obrázků pomocí služby Simplest Image Hosting +Comment[da]=Muliggør deling af billeder med tjenesten Simplest Image Hosting +Comment[de]=Ermöglicht die Veröffentlichung von Bildern über den simplest-image-hosting.net-Dienst +Comment[el]=Επιτρέπει στις εικόνες να γίνουν κοινόχρηστες χρησιμοποιώντας την υπηρεσία imgur +Comment[en_GB]=Allows images to be shared using the Simplest Image Hosting service +Comment[es]=Permite compartir imágenes a través del servicio de Simplest Image Hosting +Comment[et]=Piltide jagamine Simplest Image Hosting teenuse kaudu +Comment[eu]=Irudiak Simplest Image Hosting zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa kuvien jakamisen Simplest Image Hosting -palvelussa +Comment[fr]=Permet le partage d'images à l'aide du service « Simplest Image Hosting » +Comment[gl]=Permite compartir imaxes mediante o servizo Simplest Image Hosting +Comment[he]=מאפשר שיתוף תמונות באמצעות השירות Simplest Image Hosting +Comment[hr]=Omogućuje dijeljenje slika koristeći servis Simplest Image Hosting +Comment[hu]=Képek megosztása a Simple Image Hosting szolgáltatás használatával +Comment[ia]=Il permitte imagines de esser compartite per usar le servicio Simplest Image Hosting +Comment[is]=Gerir kleift að deila myndum með Simplest Image Hosting þjónustunni +Comment[it]=Abilita la condivisione di immagini con il servizio Simplest Image Hosting +Comment[ja]=Simplest Image Hosting のサービスを用いたテキストの共有を有効にする +Comment[kk]=Simplest Image Hosting қызметі көмегімен кескіндерді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​រូបភាព​ ដោយ​ប្រើ​សេវា​បង្ហោះ​រូបភាព​សាមញ្ញ​បំផុត​ +Comment[ko]=Simplest Image Hosting으로 그림을 공유합니다 +Comment[lt]=Įjungia dalinimąsį nuotraukomis naudojant paprasčiausio nuotraukų talpinimo tarnybą +Comment[lv]=Ļauj kopīgot attēlus, izmantojot Simplest Image Hosting servisu +Comment[mr]=सिंप्लेस्ट प्रतिमा होस्टींग सेवा वापरुन प्रतिमा शेअर करतो +Comment[nb]=Gjør det mulig å dele bilder via tjenesten Simplest Image Hosting +Comment[nds]=Biller op "Simplest Image Hosting" praatstellen +Comment[nl]=Staat het delen van afbeeldingen toe met gebruik van de service Simplest Image Hosting +Comment[pa]=ਸੈਂਪਲਸਟ ਈਮੇਜ਼ ਹੋਸਟਿੰਗ ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚਿੱਤਰ ਸਾਂਝੇ ਕਰਨ ਲਈ ਸਹਾਇਕ +Comment[pl]=Pozwala na udostępnianie obrazów przy użyciu usługi Simplest Image Hosting +Comment[pt]=Permite a partilha de imagens com o serviço do Simplest Image Hosting +Comment[pt_BR]=Permite o compartilhamento de imagens usando o serviço do Simplest Image Hosting +Comment[ro]=Permite ca imaginile să fie partajate folosind serviciul Simplest Image Hosting +Comment[ru]=Позволяет публиковать изображения на сервере Simplest Image Hosting +Comment[sk]=Povolí zdieľanie obrázkov pomocou služby Simplest Image Hosting +Comment[sl]=Omogoča deljenje slik prek storitve Simplest Image Hosting +Comment[sr]=Дељење слика преко сервиса Симплест имејџ хостинг +Comment[sr@ijekavian]=Дијељење слика преко сервиса Симплест имејџ хостинг +Comment[sr@ijekavianlatin]=Dijeljenje slika preko servisa Simplest Image Hosting +Comment[sr@latin]=Deljenje slika preko servisa Simplest Image Hosting +Comment[sv]=Tillåter att bilder delas genom att använda Simplest Image Hosting +Comment[tr]=Simplest Image Hosting servisini kullanarak resimleri paylaşmayı sağlar +Comment[ug]=رەسىملەرنى Simplest Image Hosting مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення зображень за допомогою служби Simplest Image Hosting +Comment[vi]=Cho phép chia sẻ ảnh qua dịch vụ Simplet Image Hosting +Comment[wa]=Permete li pårtaedje d' imådjes e s' siervant do siervice Simplest Image Hosting +Comment[x-test]=xxAllows images to be shared using the Simplest Image Hosting servicexx +Comment[zh_CN]=用最简单的图片主机服务共享图片 +Comment[zh_TW]=允許使用 Simplest Image Hosting 服務分享影像 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=image/* + +X-KDE-PluginInfo-Name=simplestimagehosting +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/wklej/CMakeLists.txt b/plasma/generic/dataengines/share/backends/wklej/CMakeLists.txt new file mode 100644 index 00000000..06344690 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wklej/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-wklej.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-wklej.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/wklej/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/wklej) diff --git a/plasma/generic/dataengines/share/backends/wklej/contents/code/main.js b/plasma/generic/dataengines/share/backends/wklej/contents/code/main.js new file mode 100644 index 00000000..7060a89c --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wklej/contents/code/main.js @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://wklej.org"; +} + +function contentKey() { + return "body"; +} + +function setup() { + provider.addQueryItem("autor", "kde"); + provider.addQueryItem("syntax", "text"); +} + +function handleResultData(data) { + var res = provider.parseXML("title", data); + if (res == "") { + provider.error(data); + } + var id = res.split(" ")[1].replace("#", "http://wklej.org/id/"); + provider.success(id); +} + diff --git a/plasma/generic/dataengines/share/backends/wklej/metadata.desktop b/plasma/generic/dataengines/share/backends/wklej/metadata.desktop new file mode 100644 index 00000000..b478de53 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wklej/metadata.desktop @@ -0,0 +1,126 @@ +[Desktop Entry] +Name=wklej.org +Name[ar]=wklej.org +Name[ast]=wklej.org +Name[bg]=wklej.org +Name[bs]=wklej.org +Name[ca]=wklej.org +Name[ca@valencia]=wklej.org +Name[cs]=wklej.org +Name[da]=wklej.org +Name[de]=wklej.org +Name[el]=wklej.org +Name[en_GB]=wklej.org +Name[es]=wklej.org +Name[et]=wklej.org +Name[eu]=wklej.org +Name[fi]=wklej.org +Name[fr]=wklej.org +Name[ga]=wklej.org +Name[gl]=wklej.org +Name[gu]=wklej.org +Name[he]=wklej.org +Name[hi]=wklej.org +Name[hr]=wklej.org +Name[hu]=wklej.org +Name[ia]=wklej.org +Name[is]=wklej.org +Name[it]=wklej.org +Name[ja]=wklej.org +Name[kk]=wklej.org +Name[km]=wklej.org +Name[ko]=wklej.org +Name[lt]=wklej.org +Name[lv]=wklej.org +Name[mr]=wklej.org +Name[nb]=wklej.org +Name[nds]=wklej.org +Name[nl]=wklej.org +Name[pa]=wklej.org +Name[pl]=wklej.org +Name[pt]=wklej.org +Name[pt_BR]=wklej.org +Name[ro]=wklej.org +Name[ru]=wklej.org +Name[sk]=wklej.org +Name[sl]=wklej.org +Name[sr]=wklej.org +Name[sr@ijekavian]=wklej.org +Name[sr@ijekavianlatin]=wklej.org +Name[sr@latin]=wklej.org +Name[sv]=wklej.org +Name[tg]=wklej.org +Name[th]=wklej.org +Name[tr]=wklej.org +Name[ug]=wklej.org +Name[uk]=wklej.org +Name[wa]=wklej.org +Name[x-test]=xxwklej.orgxx +Name[zh_CN]=wklej.org +Name[zh_TW]=wklej.org +Comment=Allows text to be shared using the wklej.org service +Comment[ar]=يسمح للنصوص أن تُشارك بإستخدام خدمة wklej.org +Comment[bg]=Позволява споделянето на текст чрез wklej.org +Comment[bs]=Dopušta dijeljenje teksta preko servisa wklej.org +Comment[ca]=Permet la compartició de text utilitzant el servei wklej.org +Comment[ca@valencia]=Permet la compartició de text utilitzant el servei wklej.org +Comment[cs]=Povolí sdílení textů pomocí služby wklej.org +Comment[da]=Muliggør deling af tekst med tjenesten wklej.org +Comment[de]=Ermöglicht die Veröffentlichung von Text über den wklej.org-Dienst +Comment[el]=Επιτρέπει στο κείμενο να γίνει κοινόχρηστο χρησιμοποιώντας την υπηρεσία wklej.org +Comment[en_GB]=Allows text to be shared using the wklej.org service +Comment[es]=Permite compartir texto a través del servicio de wklej.org +Comment[et]=Teksti jagamine wklej.org teenuse kaudu +Comment[eu]=Testua wklej.org zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa tekstin jakamisen wklej.org-palvelussa +Comment[fr]=Permet le partage de texte à l'aide du service « wklej.org » +Comment[gl]=Permite compartir texto mediante o servizo wklej.org +Comment[he]=מאפשר שיתוף טקסט באמצעות השירות wklej.org +Comment[hr]=Omogućuje dijeljenje teksta koristeći servis wklej.org +Comment[hu]=Szöveg megosztása a wklej.org szolgáltatás használatával +Comment[ia]=Il permitte texto de esser compartite per usar le servicio wklej.org +Comment[is]=Gerir kleift að deila texta með wklej.org þjónustunni +Comment[it]=Abilita la condivisione di testo con il servizio wklej.org +Comment[ja]=wklej.org のサービスを用いたテキストの共有を有効にする +Comment[kk]=wklej.org қызметі көмегімен мәтінді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​អត្ថបទ​ដោយ​ប្រើ​សេវា wklej.org +Comment[ko]=wklej.org로 텍스트를 공유합니다 +Comment[lt]=Įjungia dalinimąsį tekstu naudojant wklej.org tarnybą +Comment[lv]=Ļauj kopīgot tekstu, izmantojot wklej.org servisu +Comment[mr]=wklej.org सेवा वापरुन पाठ्य शेअर करतो +Comment[nb]=Gjør det mulig å dele tekst via tjenesten wklej.org +Comment[nds]=Text op "wklej.org" praatstellen +Comment[nl]=Staat het delen van tekst toe met gebruik van de service wklej.org +Comment[pa]=wklej.org ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਟੈਕਸਟ ਸਾਂਝਾ ਕਰਨਾ ਯੋਗ +Comment[pl]=Pozwala na udostępnianie tekstu przy użyciu usługi wklej.org +Comment[pt]=Permite a partilha de texto com o serviço do 'wklej.org' +Comment[pt_BR]=Permite o compartilhamento de texto com o serviço do wklej.org +Comment[ro]=Permite partajarea textului cu serviciul wklej.org +Comment[ru]=Позволяет публиковать текст на сервере wklej.org +Comment[sk]=Povolí zdieľanie textu pomocou služby wklej.org +Comment[sl]=Omogoča deljenje besedila prek storitve wklej.org +Comment[sr]=Дељење текста преко сервиса wklej.org +Comment[sr@ijekavian]=Дијељење текста преко сервиса wklej.org +Comment[sr@ijekavianlatin]=Dijeljenje teksta preko servisa wklej.org +Comment[sr@latin]=Deljenje teksta preko servisa wklej.org +Comment[sv]=Tillåter att text delas genom att använda tjänsten wklej.org +Comment[tr]=wklej.org servisini kullanarak metinleri paylaşmayı sağlar +Comment[ug]=تېكىستلەرنى wklej.org مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення фрагментів тексту за допомогою служби wklej.org +Comment[vi]=Cho phép chia sẻ văn bản qua dịch vụ wklej.org +Comment[wa]=Permete li pårtaedje di scrijhaedje e s' siervant do siervice wklej.org +Comment[x-test]=xxAllows text to be shared using the wklej.org servicexx +Comment[zh_CN]=用 wklej.org服务共享文字 +Comment[zh_TW]=允許使用 wklej.org 服務分享文字 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=text/* + +X-KDE-PluginInfo-Name=wklej +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/backends/wstaw/CMakeLists.txt b/plasma/generic/dataengines/share/backends/wstaw/CMakeLists.txt new file mode 100644 index 00000000..3a31a16f --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wstaw/CMakeLists.txt @@ -0,0 +1,7 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-wstaw.desktop COPYONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-share-addon-wstaw.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/wstaw/) + +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/shareprovider/wstaw) diff --git a/plasma/generic/dataengines/share/backends/wstaw/contents/code/main.js b/plasma/generic/dataengines/share/backends/wstaw/contents/code/main.js new file mode 100644 index 00000000..607738c8 --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wstaw/contents/code/main.js @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2010 by Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +function url() { + return "http://wstaw.org"; +} + +function contentKey() { + return "pic"; +} + +function setup() { +} + +function handleResultData(data) { + var res = data.match("value=\"http://wstaw.org/m/.+\""); + if (res == null) { + provider.error(data); + return; + } + provider.success(res[0].replace("value=", "").replace("\"", "").replace("\"", "")); +} diff --git a/plasma/generic/dataengines/share/backends/wstaw/metadata.desktop b/plasma/generic/dataengines/share/backends/wstaw/metadata.desktop new file mode 100644 index 00000000..6fac7c8b --- /dev/null +++ b/plasma/generic/dataengines/share/backends/wstaw/metadata.desktop @@ -0,0 +1,126 @@ +[Desktop Entry] +Name=wstaw.org +Name[ar]=wstaw.org +Name[ast]=wstaw.org +Name[bg]=wstaw.org +Name[bs]=wstaw.org +Name[ca]=wstaw.org +Name[ca@valencia]=wstaw.org +Name[cs]=wstaw.org +Name[da]=wstaw.org +Name[de]=wstaw.org +Name[el]=wstaw.org +Name[en_GB]=wstaw.org +Name[es]=wstaw.org +Name[et]=wstaw.org +Name[eu]=wstaw.org +Name[fi]=wstaw.org +Name[fr]=wstaw.org +Name[ga]=wstaw.org +Name[gl]=wstaw.org +Name[gu]=wstaw.org +Name[he]=wstaw.org +Name[hi]=wstaw.org +Name[hr]=wstaw.org +Name[hu]=wstaw.org +Name[ia]=wstaw.org +Name[is]=wstaw.org +Name[it]=wstaw.org +Name[ja]=wstaw.org +Name[kk]=wstaw.org +Name[km]=wstaw.org +Name[ko]=wstaw.org +Name[lt]=wstaw.org +Name[lv]=wstaw.org +Name[mai]=wstaw.org +Name[mr]=wstaw.org +Name[nb]=wstaw.org +Name[nds]=wstaw.org +Name[nl]=wstaw.org +Name[pa]=wstaw.org +Name[pl]=wstaw.org +Name[pt]=wstaw.org +Name[pt_BR]=wstaw.org +Name[ro]=wstaw.org +Name[ru]=wstaw.org +Name[sk]=wstaw.org +Name[sl]=wstaw.org +Name[sr]=wstaw.org +Name[sr@ijekavian]=wstaw.org +Name[sr@ijekavianlatin]=wstaw.org +Name[sr@latin]=wstaw.org +Name[sv]=wstaw.org +Name[tg]=wstaw.org +Name[th]=wstaw.org +Name[tr]=wstaw.org +Name[ug]=wstaw.org +Name[uk]=wstaw.org +Name[wa]=wstaw.org +Name[x-test]=xxwstaw.orgxx +Name[zh_CN]=wstaw.org +Name[zh_TW]=wstaw.org +Comment=Allows images to be shared using the wstaw.org service +Comment[bg]=Позволява споделянето на изображения чрез wstaw.org +Comment[bs]=Dopušta dijeljenje slika preko servisa wstaw.org +Comment[ca]=Permet la compartició d'imatges utilitzant el servei wstaw.org +Comment[ca@valencia]=Permet la compartició d'imatges utilitzant el servei wstaw.org +Comment[cs]=Povolí sdílení obrázků pomocí služby wstaw.org +Comment[da]=Muliggør deling af billeder med tjenesten wstaw.org +Comment[de]=Ermöglicht die Veröffentlichung von Bildern über den wstaw.org-Dienst +Comment[el]=Επιτρέπει το μοίρασμα των εικόνων χρησιμοποιώντας την υπηρεσία wstaw.org +Comment[en_GB]=Allows images to be shared using the wstaw.org service +Comment[es]=Permite compartir imágenes a través del servicio de wstaw.org +Comment[et]=Piltide jagamine wstaw.org teenuse kaudu +Comment[eu]=Irudiak wstaw.org zerbitzuaren bidez partekatzeko aukera ematen du +Comment[fi]=Mahdollistaa kuvien jakamisen wstaw.org-palvelussa +Comment[fr]=Permet le partage d'images à l'aide du service « wstaw.org » +Comment[gl]=Permite compartir imaxes mediante o servizo wstaw.org +Comment[he]=מאפשר שיתוף תמונות באמצעות השירות wstaw.org +Comment[hr]=Omogućuje dijeljenje slika koristeći servis wstaw.org +Comment[hu]=Képek megosztása a wstaw.org szolgáltatás használatával +Comment[ia]=Il permitte images de esser compartite per usar le servicio wstaw.org +Comment[is]=Gerir kleift að deila myndum með wstaw.org þjónustunni +Comment[it]=Abilita la condivisione di immagini con il servizio wstaw.org +Comment[ja]=wstaw.org のサービスを用いた画像の共有を有効にする +Comment[kk]=wstaw.org қызметі көмегімен кескіндерді ортақ қылуды рұқсат ету +Comment[km]=បើក​ការ​ចែករំលែក​រូបភាព​ ដោយ​ប្រើ​សេវា wstaw.org +Comment[ko]=wstaw.org로 그림을 공유합니다 +Comment[lt]=Įjungia dalinimąsį nuotraukomis naudojant wstaw.org tarnybą +Comment[lv]=Ļauj kopīgot attēlus, izmantojot wstaw.org servisu +Comment[mr]=wstaw.org सेवा वापरुन प्रतिमा शेअर करतो +Comment[nb]=Gjør det mulig å dele bilder via tjenesten wstaw.org +Comment[nds]=Biller op "wstaw.org" praatstellen +Comment[nl]=Staat het delen van afbeeldingen toe met gebruik van de service wstaw.org +Comment[pa]=wstaw.org ਸਰਵਿਸ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਚਿੱਤਰ ਸਾਂਝੇ ਕਰਨ ਲਈ ਸਹਾਇਕ +Comment[pl]=Pozwala na udostępnianie obrazów przy użyciu usługi wstaw.org +Comment[pt]=Permite a partilha de imagens com o serviço do 'wstaw.org' +Comment[pt_BR]=Permite o compartilhamento de imagens usando o serviço do wstaw.org +Comment[ro]=Permite partajarea imaginilor cu serviciul wstaw.org +Comment[ru]=Позволяет публиковать изображения на сервере wstaw.org +Comment[sk]=Povolí zdieľanie obrázkov pomocou služby wstaw.org +Comment[sl]=Omogoča deljenje slik prek storitve wstaw.org +Comment[sr]=Дељење слика преко сервиса wstaw.org +Comment[sr@ijekavian]=Дијељење слика преко сервиса wstaw.org +Comment[sr@ijekavianlatin]=Dijeljenje slika preko servisa wstaw.org +Comment[sr@latin]=Deljenje slika preko servisa wstaw.org +Comment[sv]=Tillåter att bilder delas genom att använda tjänsten wstaw.org +Comment[tr]=wstaw.org servisi kullanarak resimleri paylaşmayı sağlar +Comment[ug]=رەسىملەرنى wstaw.org مۇلازىمىتىنى ئىشلىتىپ ھەمبەھىرلەشكە ئىجازەت +Comment[uk]=Уможливлює оприлюднення зображень за допомогою служби wstaw.org +Comment[vi]=Cho phép chia sẻ ảnh qua dịch vụ wstaw.org +Comment[wa]=Permete li pårtaedje d' imådjes e s' siervant do siervice wstaw.org +Comment[x-test]=xxAllows images to be shared using the wstaw.org servicexx +Comment[zh_CN]=用 wstaw.org 服务共享图片 +Comment[zh_TW]=允許使用 wstaw.org 服務分享影像 +Type=Service + +X-KDE-ServiceTypes=Plasma/ShareProvider +X-KDE-Library=plasma_engine_share +X-KDE-PlasmaShareProvider-MimeType=image/* + +X-KDE-PluginInfo-Name=wstaw +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/generic/dataengines/share/data/plasma-dataengine-share.desktop b/plasma/generic/dataengines/share/data/plasma-dataengine-share.desktop new file mode 100644 index 00000000..42236bfc --- /dev/null +++ b/plasma/generic/dataengines/share/data/plasma-dataengine-share.desktop @@ -0,0 +1,127 @@ +[Desktop Entry] +Name=Share Services +Name[ast]=Compartir Servicios +Name[bg]=Услуги за споделяне +Name[bs]=Servisi dijeljenja +Name[ca]=Serveis de compartició +Name[ca@valencia]=Serveis de compartició +Name[cs]=Sdílené služby +Name[da]=Delingstjenester +Name[de]=Veröffentlichungsdienste +Name[el]=Υπηρεσίες κοινής χρήσης +Name[en_GB]=Share Services +Name[es]=Compartir servicios +Name[et]=Jagamisteenused +Name[eu]=Partekatze-zerbitzuak +Name[fi]=Jakamispalvelut +Name[fr]=Services de partage +Name[ga]=Seirbhísí Comhroinnt +Name[gl]=Compartir servizos +Name[he]=שירותי שיתוף +Name[hi]=साझा सेवाएँ +Name[hr]=Servisi za dijeljenje +Name[hu]=Megosztási szolgáltatások +Name[ia]=Servicios compartite +Name[is]=Deila þjónustum +Name[it]=Servizi di condivisione +Name[ja]=サービスの共有 +Name[kk]=Ортақтастыру қызметтер +Name[km]=ចែក​រំលែក​សេវា +Name[kn]=ಹಂಚಿಕೆ ಸೇವೆಗಳು +Name[ko]=공유 서비스 +Name[lt]=Dalinimosi tarnybos +Name[lv]=Kopīgot servisus +Name[mr]=शेअर सेवा +Name[nb]=Dele-tjenester +Name[nds]=Praatstell-Deensten +Name[nl]=Services voor delen +Name[pa]=ਸਾਂਝੀਆਂ ਸਰਵਿਸਾਂ +Name[pl]=Usługi współdzielenia +Name[pt]=Serviços de Partilha +Name[pt_BR]=Serviços de compartilhamento +Name[ro]=Servicii de partajare +Name[ru]=Обмен информацией +Name[sk]=Služby zdieľania +Name[sl]=Storitve za deljenje +Name[sr]=Сервиси дељења +Name[sr@ijekavian]=Сервиси дељења +Name[sr@ijekavianlatin]=Servisi deljenja +Name[sr@latin]=Servisi deljenja +Name[sv]=Delningstjänster +Name[th]=บริการที่ใช้งานร่วมกัน +Name[tr]=Paylaşım Servisleri +Name[ug]=مۇلازىمەتلەرنى ھەمبەھىرلە +Name[uk]=Служби оприлюднення +Name[wa]=Pårtaedjî siervices +Name[x-test]=xxShare Servicesxx +Name[zh_CN]=共享服务 +Name[zh_TW]=分享服務 +Comment=Engine to share content using different services +Comment[ast]=Motor pa compartir conteníos a traviés d'estremaos servicios +Comment[bg]=Споделяне на данни чрез различни услуги +Comment[bs]=Motor za dijeljenje sadržaja preko različitih servisa +Comment[ca]=Motor per compartir contingut utilitzant diferents serveis +Comment[ca@valencia]=Motor per compartir contingut utilitzant diferents serveis +Comment[cs]=Povolí sdílení obsahu pomocí různých služeb +Comment[da]=Motor til at dele indhold ved brug af forskellige tjenester +Comment[de]=Treiber für die Veröffentlichung von Inhalten über verschiedene Dienste +Comment[el]=Μηχανισμός για το μοίρασμα περιεχομένου χρησιμοποιώντας διαφορετικές υπηρεσίες +Comment[en_GB]=Engine to share content using different services +Comment[es]=Motor para compartir contenidos a través de diferentes servicios +Comment[et]=Eri teenuste kaudu sisu jagamise mootor +Comment[eu]=Hainbat zerbitzuren bidez edukia partekatzeko motorra +Comment[fi]=Moottori sisällön jakamiseen useissa palveluissa +Comment[fr]=Système de partage de contenus utilisant différents services +Comment[gl]=Motor para compartir contido mediante diversos servizos +Comment[he]=מנוע לשיתוף תוכן באמצעות שירותים שונים +Comment[hr]=Mehanizam za dijeljenje sadržaja koristeći razne servise +Comment[hu]=Adatmodul tartalommegosztáshoz különböző szolgáltatások használatával +Comment[ia]=Motor pro compartir contento usante differente servicios +Comment[is]=Kerfi til að deila efni með ýmsum þjónustum +Comment[it]=Motore per condividere del contenuto usando diversi servizi +Comment[ja]=様々なサービスを用いたコンテンツ共有エンジン +Comment[kk]=Түрлі қызметтер көмегімен мазмұның ортақ қылу тетігі +Comment[km]=ម៉ាស៊ីន​ដើម្បី​ចែករំលែក​មាតិកា​ ដោយ​ប្រើ​សេវា​ផ្សេងៗ​គ្នា +Comment[ko]=컨텐츠 공유 서비스 +Comment[lt]=Turinio dalinimosi, naudojant įvairias tarnybas, modulis +Comment[lv]=Dzinējs satura kopīgošanai, izmantojot atšķirīgus servisus +Comment[mr]=विविध सेवा वापरुन मजकूर शेअर करण्याचे इंजिन +Comment[nb]=Motor for å dele innhold ved bruk av forskjellige tjenester +Comment[nds]=Programmkarn för Deensten för't Praatstellen vun Inholden +Comment[nl]=Engine om inhoud te delen met gebruik van verschillende services +Comment[pa]=ਵੱਖ ਵੱਖ ਸਰਵਿਸਾਂ ਵਿੱਚ ਸਮਗੱਰੀ ਸਾਂਝੀ ਕਰਨ ਲਈ ਇੰਜਣ +Comment[pl]=Silnik do udostępniania zawartości przy użyciu rożnych usług +Comment[pt]=Um motor para partilhar conteúdos através de vários serviços +Comment[pt_BR]=Um mecanismo para compartilhar conteúdos usando diferentes serviços +Comment[ro]=Motor pentru partajarea conținutului folosind diferite servicii +Comment[ru]=Источник данных для обмена содержимым между людьми, используя различные интернет-службы +Comment[sk]=Nástroj na zdieľanie obsahu pomocou rôznych služieb +Comment[sl]=Pogon za deljenje vsebin prek različnih storitev +Comment[sr]=Мотор за дељење садржаја преко различитих сервиса +Comment[sr@ijekavian]=Мотор за дијељење садржаја преко различитих сервиса +Comment[sr@ijekavianlatin]=Motor za dijeljenje sadržaja preko različitih servisa +Comment[sr@latin]=Motor za deljenje sadržaja preko različitih servisa +Comment[sv]=Gränssnitt för att dela innehåll genom att använda olika tjänster +Comment[th]=กลไกการแลกเปลี่ยนเนื้อหาบนบริการที่แตกต่างกัน +Comment[tr]=Farklı servisleri kullanarak içerik paylaşmayı sağlayan motor +Comment[ug]=ئوخشىمىغان مۇلازىمەتلەرنى ئىشلىتىپ مەزمۇنلارنى ھەمبەھىرلەيدىغان ماتور +Comment[uk]=Рушій спільного використання даних різними службами +Comment[vi]=Cơ chế chia sẻ nội dung thông qua các dịch vụ +Comment[wa]=Moteur po pårtaedjî l' ådvins tot s' siervant d' diferins siervices +Comment[x-test]=xxEngine to share content using different servicesxx +Comment[zh_CN]=用不同服务共享内容的引擎 +Comment[zh_TW]=用不同的服務來分享內容的引擎 +Type=Service +X-KDE-ServiceTypes=Plasma/DataEngine +Icon=document-share + +X-KDE-Library=plasma_engine_share +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Name=org.kde.plasma.dataengine.share +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Utilities +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/share/data/plasma-packagestructure-share.desktop b/plasma/generic/dataengines/share/data/plasma-packagestructure-share.desktop new file mode 100644 index 00000000..f51a4360 --- /dev/null +++ b/plasma/generic/dataengines/share/data/plasma-packagestructure-share.desktop @@ -0,0 +1,121 @@ +[Desktop Entry] +Name=ShareProvider +Name[ast]=Fornidor de Servicios +Name[bg]=Доставчик на услуги за споделяне +Name[bs]=Dobavljač dijeljenja +Name[ca]=ShareProvider +Name[ca@valencia]=ShareProvider +Name[cs]=ShareProvider +Name[da]=Delingsudbyder +Name[de]=Veröffentlichungsanbieter +Name[el]=Πάροχος κοινής χρήσης +Name[en_GB]=ShareProvider +Name[es]=Compartir proveedor +Name[et]=ShareProvider +Name[eu]=Partekatze-hornitzailea +Name[fi]=ShareProvider +Name[fr]=Fournisseur de partages +Name[gl]=ShareProvider +Name[he]=ShareProvider +Name[hr]=ShareProvider +Name[hu]=ShareProvider +Name[ia]=Fornitor compartite +Name[is]=ShareProvider +Name[it]=Fornitore di condivisione +Name[ja]=ShareProvider +Name[kk]=Ортақтастыру қызметтер +Name[km]=ShareProvider +Name[ko]=ShareProvider +Name[lt]=ShareProvider +Name[lv]=ShareProvider +Name[mr]=सेवा पुरवठाकर्ता +Name[nb]=Dele-tjenester +Name[nds]=Apenmaakdeenstanbeder +Name[nl]=ShareProvider +Name[pa]=ShareProvider +Name[pl]=Dostawca udostępniania +Name[pt]=Fornecedor de Partilha +Name[pt_BR]=Provedor de compartilhamento +Name[ro]=FurnizorPartajare +Name[ru]=Служба обмена информацией +Name[sk]=Poskytovateľ zdieľania +Name[sl]=ShareProvider +Name[sr]=Добављач дељења +Name[sr@ijekavian]=Добављач дијељења +Name[sr@ijekavianlatin]=Dobavljač dijeljenja +Name[sr@latin]=Dobavljač deljenja +Name[sv]=Delningstjänst +Name[th]=ผู้ให้ใช้งานร่วมกัน +Name[tr]=SağlayıcıyıPaylaş +Name[ug]=ھەمبەھىر تەمىنلىگۈچى +Name[uk]=Служба оприлюднення +Name[wa]=Ahesseu d' pårtaedje +Name[x-test]=xxShareProviderxx +Name[zh_CN]=共享提供 +Name[zh_TW]=分享服務提供者 +Comment=Share Package Structure +Comment[ast]=Estructura Paquete Compartir +Comment[bs]=Struktura paketa dijeljenja +Comment[ca]=Estructura de paquet de compartició +Comment[ca@valencia]=Estructura de paquet de compartició +Comment[cs]=Struktura sdíleného balíčku +Comment[da]=Pakkestruktur for deling +Comment[de]=Paketstruktur bereitstellen +Comment[el]=Δομή πακέτου κοινής χρήσης +Comment[en_GB]=Share Package Structure +Comment[es]=Estructura del paquete de compartición +Comment[et]=Paketistruktuuri jagamine +Comment[eu]=Partekatze-paketearen egitura +Comment[fi]=Jaa pakettirakenne +Comment[fr]=Structure du paquet de partage +Comment[gl]=Estrutura de paquete Share +Comment[he]=Share Package Structure +Comment[hr]=Podijeli strukturu paketa +Comment[hu]=Csomagstruktúra megosztása +Comment[ia]=Share Package Structure (Structura de uso commun de pacchetto) +Comment[is]=Deila pakkauppbyggingu +Comment[it]=Struttura del pacchetto di condivisione +Comment[ja]=パッケージの構造を共有 +Comment[kk]=Ортақ дестелер құрылымы +Comment[km]=ចែករំលែក​រចនាសម្ព័ន្ធ​កញ្ចប់ +Comment[ko]=공유 패키지 구조 +Comment[lt]=Dalinimosi paketo struktūra +Comment[lv]=Kopīgot pakotnes struktūru +Comment[mr]=शेर पॅकेज संरचना +Comment[nb]=Del pakkestruktur +Comment[nds]=Paketstruktuur praatstellen +Comment[nl]=Structuur van delen van pakketten +Comment[pa]=ਪੈਕੇਜ ਢਾਂਚਾ ਸਾਂਝਾ ਕਰੋਪੈਕੇਜ ਢਾਂਚਾ ਸਾਪੈਕੇਜ ਫਪੈਕੇਜ ਟਾ +Comment[pl]=Struktura pakietu udostępniania +Comment[pt]=Estrutura do Pacote da Partilha +Comment[pt_BR]=Estrutura do pacote de compartilhamento +Comment[ro]=Partajează structura pachetului +Comment[ru]=Структура пакета с параметрами службы обмена информацией +Comment[sk]=Štruktúra balíčka pre zdieľanie +Comment[sl]=Zgradba paketa Share +Comment[sr]=Структура пакета дељења +Comment[sr@ijekavian]=Структура пакета дијељења +Comment[sr@ijekavianlatin]=Struktura paketa dijeljenja +Comment[sr@latin]=Struktura paketa deljenja +Comment[sv]=Dela paketstruktur +Comment[th]=โครงสร้างแพกเกจที่ใช้ร่วมกัน +Comment[tr]=Paket Yapısını Paylaş +Comment[ug]=ھەمبەھىر بوغچا قۇرۇلمىسى +Comment[uk]=Структура спільних пакунків +Comment[wa]=Tcherpinte do pacaedje di pårtaedje +Comment[x-test]=xxShare Package Structurexx +Comment[zh_CN]=共享包结构 +Comment[zh_TW]=分享套件結構 +Type=Service +X-KDE-ServiceTypes=Plasma/PackageStructure + +X-KDE-Library=plasma_packagestructure_share +X-KDE-PluginInfo-Author=Artur de Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Name=Plasma/ShareProvider +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-License=GPLv2+ +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-PackageFileFilter=*.share +X-Plasma-PackageFileMimetypes=application/zip diff --git a/plasma/generic/dataengines/share/data/plasma_shareprovider.desktop b/plasma/generic/dataengines/share/data/plasma_shareprovider.desktop new file mode 100644 index 00000000..a5b6bc4c --- /dev/null +++ b/plasma/generic/dataengines/share/data/plasma_shareprovider.desktop @@ -0,0 +1,60 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=Plasma/ShareProvider +Comment=Plugin for Plasma Sharebin +Comment[ast]=Complementu pa Plasma Sharebin +Comment[bs]=Priključak za plazma korpu dijeljenja +Comment[ca]=Connector pel Sharebin del Plasma +Comment[ca@valencia]=Connector pel Sharebin del Plasma +Comment[cs]=Zásuvný modul pro Plasma Sharebin +Comment[da]=Plugin til Plasma Sharebin +Comment[de]=Modul für Plasma-Sharebin +Comment[el]=Πρόσθετο για το Plasma Sharebin +Comment[en_GB]=Plugin for Plasma Sharebin +Comment[es]=Complemento para Plasma Sharebin +Comment[et]=Plasma Sharebini plugin +Comment[eu]=Plasmaren Sharebin-erako plugina +Comment[fi]=Plasman Sharebin-liitännäinen +Comment[fr]=Module externe « Sharebin » pour Plasma +Comment[gl]=Extensión para o motor Sharebin de Plasma +Comment[he]=תוסף עבור Plasma Sharebin +Comment[hr]=Priključak za Plasma Sharebin +Comment[hu]=Bővítmény a Plasma Sharebinhez +Comment[ia]=Plugin pro Plasma Sharebin +Comment[is]=Íforrit fyrir Plasma Sharebin +Comment[it]=Estensione per Sharebin di Plasma +Comment[ja]=Plasma Sharebin プラグイン +Comment[kk]=Pasma ортақ дерегінің плагині +Comment[km]=កម្មវិធី​ជំនួយ​សម្រាប់​ Sharebin ប្លាស្មា +Comment[ko]=Plasma Sharebin 설정 +Comment[lt]=Plasma dalinimosi dėžės priedas +Comment[lv]=Spraudnis priekš Plasma Sharebin +Comment[mr]=प्लाज्मा शेअरबिन करिता प्लगइन +Comment[nb]=Programtillegg for Plasma Sharebin +Comment[nds]=Moduul för "Plasma-Sharebin" +Comment[nl]=Plugin voor Plasma Sharebin +Comment[pa]=ਪਲਾਜ਼ਮਾ ਸ਼ੇਅਰਬਿਨ ਲਈ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka dla Sharebin plazmy +Comment[pt]='Plugin' para o Sharebin do Plasma +Comment[pt_BR]=Plugin para o Sharebin do Plasma +Comment[ro]=Modul pentru Plasma Sharebin +Comment[ru]=Расширение для Plasma Sharebin +Comment[sk]=Modul pre Plasma Sharebin +Comment[sl]=Vstavek za Plasma Sharebin +Comment[sr]=Прикључак за плазма корпу дељења +Comment[sr@ijekavian]=Прикључак за плазма корпу дијељења +Comment[sr@ijekavianlatin]=Priključak za plasma korpu dijeljenja +Comment[sr@latin]=Priključak za plasma korpu deljenja +Comment[sv]=Insticksprogram för Plasma Sharebin +Comment[th]=ส่วนเสริมสำหรับถังขยะร่วมกันของพลาสมา +Comment[tr]=Plasma PaylaşımKutusu için Eklenti +Comment[ug]=پلازما Sharebin ئۈچۈن قىستۇرما +Comment[uk]=Додаток до спільного ресурсу Плазми +Comment[wa]=Tchôke-divins pol batch di pårtaedje di Plasma +Comment[x-test]=xxPlugin for Plasma Sharebinxx +Comment[zh_CN]=Plasma 共享插件 +Comment[zh_TW]=Plasma Sharebin 的外掛程式 + +[PropertyDef::X-KDE-PlasmaShareProvider-MimeType] +Type=QStringList + diff --git a/plasma/generic/dataengines/share/plugin_share_package.cpp b/plasma/generic/dataengines/share/plugin_share_package.cpp new file mode 100644 index 00000000..48e8745e --- /dev/null +++ b/plasma/generic/dataengines/share/plugin_share_package.cpp @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright 2009 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasma/package.h" +#include "share_package.h" + +K_EXPORT_PLASMA_PACKAGESTRUCTURE(share, SharePackage) diff --git a/plasma/generic/dataengines/share/share.operations b/plasma/generic/dataengines/share/share.operations new file mode 100644 index 00000000..ed828444 --- /dev/null +++ b/plasma/generic/dataengines/share/share.operations @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/plasma/generic/dataengines/share/share_package.cpp b/plasma/generic/dataengines/share/share_package.cpp new file mode 100644 index 00000000..8b9d2c1d --- /dev/null +++ b/plasma/generic/dataengines/share/share_package.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasma/applet.h" +#include "plasma/package.h" + +#include "share_package.h" + + +SharePackage::SharePackage(QObject *parent, QVariantList args) + : Plasma::PackageStructure(parent, "Plasma/ShareProvider") +{ + Q_UNUSED(args) + + addDirectoryDefinition("scripts", "code", i18n("Executable Scripts")); + QStringList mimetypes; + mimetypes << "text/*"; + setMimetypes( "scripts", mimetypes ); + + addFileDefinition("mainscript", "code/main.js", i18n("Main Script File")); + setDefaultPackageRoot("plasma/shareprovider/"); + setServicePrefix("plasma-share-"); +} + diff --git a/plasma/generic/dataengines/share/share_package.h b/plasma/generic/dataengines/share/share_package.h new file mode 100644 index 00000000..821db4e4 --- /dev/null +++ b/plasma/generic/dataengines/share/share_package.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SHARE_PACKAGE_H +#define SHARE_PACKAGE_H + +#include + +class SharePackage : public Plasma::PackageStructure +{ +public: + explicit SharePackage(QObject *parent = 0, QVariantList args = QVariantList()); +}; + +#endif diff --git a/plasma/generic/dataengines/share/shareengine.cpp b/plasma/generic/dataengines/share/shareengine.cpp new file mode 100644 index 00000000..c60db1da --- /dev/null +++ b/plasma/generic/dataengines/share/shareengine.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include +#include +#include + +#include + +#include "shareengine.h" +#include "shareservice.h" + + +ShareEngine::ShareEngine(QObject *parent, const QVariantList &args) + : Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args); +} + +void ShareEngine::init() +{ + connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), + this, SLOT(updatePlugins(QStringList))); + updatePlugins(QStringList() << "services"); +} + +void ShareEngine::updatePlugins(const QStringList &changes) +{ + if (!changes.contains("services")) { + return; + } + + removeAllSources(); + + KService::List services = KServiceTypeTrader::self()->query("Plasma/ShareProvider"); + QMultiMap sortedServices; + foreach (KService::Ptr service, services) { + sortedServices.insert(service->property("X-KDE-Priority").toInt(), service); + } + + QMapIterator it(sortedServices); + it.toBack(); + QHash mimetypes; + while (it.hasPrevious()) { + it.previous(); + KService::Ptr service = it.value(); + const QString pluginName = + service->property("X-KDE-PluginInfo-Name", QVariant::String).toString(); + + const QStringList pluginMimeTypes = + service->property("X-KDE-PlasmaShareProvider-MimeType", QVariant::StringList).toStringList(); + + const QString storageId = service->storageId(); + + if (pluginName.isEmpty() || pluginMimeTypes.isEmpty()) { + continue; + } + + // create the list of providers + Plasma::DataEngine::Data data; + data.insert("Name", service->name()); + data.insert("Service Id", service->storageId()); + data.insert("Mimetypes", pluginMimeTypes); + setData(pluginName, data); + + // create the list of providers by type + foreach (const QString &pluginMimeType, pluginMimeTypes) { + mimetypes[pluginMimeType].append(pluginName); + } + } + + + QHashIterator it2(mimetypes); + while (it2.hasNext()) { + it2.next(); + setData("Mimetypes", it2.key(), it2.value()); + } +} + +Plasma::Service *ShareEngine::serviceForSource(const QString &source) +{ + Plasma::DataContainer *data = containerForSource(source); + + if (!data) { + return Plasma::DataEngine::serviceForSource(source); + } + + if (source.compare("mimetype", Qt::CaseInsensitive) == 0) { + return Plasma::DataEngine::serviceForSource(source); + } + + const QString id = data->data().value("Service Id").toString(); + if (id.isEmpty()) { + return Plasma::DataEngine::serviceForSource(source); + } + + ShareService *service = new ShareService(this); + service->setDestination(id); + return service; +} + +#include "shareengine.moc" + +K_EXPORT_PLASMA_DATAENGINE(share, ShareEngine) diff --git a/plasma/generic/dataengines/share/shareengine.h b/plasma/generic/dataengines/share/shareengine.h new file mode 100644 index 00000000..4cedc862 --- /dev/null +++ b/plasma/generic/dataengines/share/shareengine.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SHARE_ENGINE_H +#define SHARE_ENGINE_H + +#include +#include + +class ShareService; + +class ShareEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + ShareEngine(QObject *parent, const QVariantList &args); + void init(); + Plasma::Service *serviceForSource(const QString &source); + +private Q_SLOTS: + void updatePlugins(const QStringList &changes); + +private: + friend class ShareService; +}; + +#endif // SHARE_ENGINE diff --git a/plasma/generic/dataengines/share/shareprovider.cpp b/plasma/generic/dataengines/share/shareprovider.cpp new file mode 100644 index 00000000..b5e8f4d7 --- /dev/null +++ b/plasma/generic/dataengines/share/shareprovider.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "shareprovider.h" +#include "share_package.h" + +Plasma::PackageStructure::Ptr ShareProvider::m_packageStructure(0); + + +ShareProvider::ShareProvider(QObject *parent) + : QObject(parent), m_isBlob(false), m_isPost(true) +{ + // Just make the boundary random part long enough to be sure + // it's not inside one of the arguments that we are sending + m_boundary = "----------"; + m_boundary += KRandom::randomString(55).toAscii(); +} + +QString ShareProvider::method() const +{ + if (!m_isPost) { + return QString("GET"); + } + return QString("POST"); +} + +void ShareProvider::setMethod(const QString &method) +{ + if (method == "GET") { + m_isPost = false; + } else { + m_isPost = true; + } +} + +KUrl ShareProvider::url() const +{ + // the url that is set in this provider + return m_url; +} + +void ShareProvider::setUrl(const QString &url) +{ + // set the provider's url + m_url = url; + m_service = url; +} + +QString ShareProvider::parseXML(const QString &key, const QString &data) +{ + // this method helps plugins to parse results from webpages + QXmlStreamReader xml(data); + if (xml.hasError()) { + return QString(); + } + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.name() == key) { + QString url = xml.readElementText(); + return url; + } + } + + return QString(); +} + +void ShareProvider::addPostItem(const QString &key, const QString &value, + const QString &contentType) +{ + if (!m_isPost) + return; + + // add a pair in a post form + QByteArray str; + QString length = QString("%1").arg(value.length()); + + str += "--"; + str += m_boundary; + str += "\r\n"; + + if (!key.isEmpty()) { + str += "Content-Disposition: form-data; name=\""; + str += key.toAscii(); + str += "\"\r\n"; + } + + if (!contentType.isEmpty()) { + str += "Content-Type: " + QByteArray(contentType.toAscii()); + str += "\r\n"; + str += "Mime-version: 1.0 "; + str += "\r\n"; + } + + str += "Content-Length: "; + str += length.toAscii(); + str += "\r\n\r\n"; + str += value.toUtf8(); + + m_buffer.append(str); + m_buffer.append("\r\n"); +} + +void ShareProvider::addPostFile(const QString &contentKey, const QString &content) +{ + // add a file in a post form (gets it using KIO) + m_contentKey = contentKey; + m_content = content; + + // we expect either text or an URL of a file. The file can be a text file + // that is an exception that we handle in this case. So we have basically + // three use cases: + // 1 - just text + // 2 - a file that is a text + // 3 - other kind of files (images, pdf, etc..) + // + // The applet using this engine must ensure that the provider selected + // supports the file format that is added here as a parameter, otherwise + // it will return as an error later in the process. + KUrl url(m_content); + + KIO::MimetypeJob *mjob = KIO::mimetype(url, KIO::HideProgressInfo); + connect(mjob, SIGNAL(finished(KJob*)), this, SLOT(mimetypeJobFinished(KJob*))); +} + +void ShareProvider::mimetypeJobFinished(KJob *job) +{ + KIO::MimetypeJob *mjob = qobject_cast(job); + if (!job) { + return; + } + + if (mjob->error()) { + // it's not a file - usually this happens when we are + // just sharing plain text, so add the content and publish it + addPostItem(m_contentKey, m_content, "text/plain"); + addQueryItem(m_contentKey, m_content); + emit readyToPublish(); + return; + } + + // It's a valid file because there were no errors + m_mimetype = mjob->mimetype(); + if (m_mimetype.isEmpty()) { + // if we ourselves can't determine the mime of the file, + // very unlikely the remote site will be able to identify it + error(i18n("Could not detect the file's mimetype")); + return; + } + + // If it's not text then we should handle it later + if (m_mimetype.indexOf("text/") != 0) + m_isBlob = true; + + // try to open the file + KIO::FileJob *fjob = KIO::open(KUrl(m_content), QIODevice::ReadOnly); + connect(fjob, SIGNAL(open(KIO::Job*)), this, SLOT(openFile(KIO::Job*))); +} + +void ShareProvider::openFile(KIO::Job *job) +{ + // finished opening the file, now try to read it's content + KIO::FileJob *fjob = static_cast(job); + fjob->read(fjob->size()); + connect(fjob, SIGNAL(data(KIO::Job*,QByteArray)), + this, SLOT(finishedContentData(KIO::Job*,QByteArray))); +} + +void ShareProvider::finishedContentData(KIO::Job *job, const QByteArray &data) +{ + // Close the job as we don't need it anymore. + // NOTE: this is essential to ensure the job gets de-scheduled and deleted! + job->disconnect(this); + static_cast(job)->close(); + + if (data.length() == 0) { + error(i18n("It was not possible to read the selected file")); + return; + } + + if (!m_isBlob) { + // it's just text and we can return here using data() + addPostItem(m_contentKey, QString::fromLocal8Bit(data), "text/plain"); + addQueryItem(m_contentKey, QString::fromLocal8Bit(data)); + emit readyToPublish(); + return; + } + + // Add the special http post stuff with the content of the file + QByteArray str; + const QString fileSize = QString("%1").arg(data.size()); + str += "--"; + str += m_boundary; + str += "\r\n"; + str += "Content-Disposition: form-data; name=\""; + str += m_contentKey.toAscii(); + str += "\"; "; + str += "filename=\""; + str += QFile::encodeName(KUrl(m_content).fileName()).replace(".tmp", ".jpg"); + str += "\"\r\n"; + str += "Content-Length: "; + str += fileSize.toAscii(); + str += "\r\n"; + str += "Content-Type: "; + str += m_mimetype.toAscii(); + str += "\r\n\r\n"; + + m_buffer.append(str); + m_buffer.append(data); + m_buffer.append("\r\n"); + + // tell the world that we are ready to publish + emit readyToPublish(); +} + +void ShareProvider::readPublishData(KIO::Job *job, const QByteArray &data) +{ + Q_UNUSED(job); + m_data.append(data); +} + +void ShareProvider::finishedPublish(KJob *job) +{ + Q_UNUSED(job); + if (m_data.length() == 0) { + error(i18n("Service was not available")); + return; + } + + // process data. should be interpreted by the plugin. + // plugin must call the right slots after processing the data. + emit handleResultData(QString(m_data)); +} + +void ShareProvider::finishHeader() +{ + QByteArray str; + str += "--"; + str += m_boundary; + str += "--"; + m_buffer.append(str); +} + +void ShareProvider::addQueryItem(const QString &key, const QString &value) +{ + // just add the item to the query's URL + m_url.addQueryItem(key, value); +} + +void ShareProvider::publish() +{ + if (m_url == "") { + emit finishedError(i18n("You must specify a URL for this service")); + } + + // clear the result data before publishing + m_data.clear(); + + // finish the http form + if (m_isBlob) { + finishHeader(); + } + + // Multipart is used to upload files + KIO::TransferJob *tf; + if (m_isBlob) { + tf = KIO::http_post(m_service, m_buffer, KIO::HideProgressInfo); + tf->addMetaData("content-type","Content-Type: multipart/form-data; boundary=" + m_boundary); + } else { + if (m_isPost) { + tf = KIO::http_post(m_service, + m_url.encodedQuery(), KIO::HideProgressInfo); + tf->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded"); + } else { + QString url = QString("%1?%2").arg(m_service.url(), QString(m_url.encodedQuery())); + tf = KIO::get(url); + } + } + + connect(tf, SIGNAL(data(KIO::Job*,QByteArray)), + this, SLOT(readPublishData(KIO::Job*,QByteArray))); + connect(tf, SIGNAL(result(KJob*)), this, SLOT(finishedPublish(KJob*))); + connect(tf, SIGNAL(redirection(KIO::Job*,KUrl)), + this, SLOT(redirected(KIO::Job*,KUrl))); +} + +void ShareProvider::redirected(KIO::Job *job, const KUrl &to) +{ + Q_UNUSED(job) + const QUrl toUrl(to); + const QUrl serviceUrl(m_service); + + const QString toString(toUrl.toString(QUrl::StripTrailingSlash)); + const QString serviceString(serviceUrl.toString(QUrl::StripTrailingSlash)); + + if (toString == serviceString) { + return; + } + + emit handleRedirection(toString); +} + +void ShareProvider::success(const QString &url) +{ + // notify the service that it worked and the result url + emit finished(url); +} + +void ShareProvider::error(const QString &msg) +{ + // notify the service that it didnt work and the error msg + emit finishedError(msg); +} + +Plasma::PackageStructure::Ptr ShareProvider::packageStructure() +{ + if (!m_packageStructure) { + m_packageStructure = new SharePackage(); + } + return m_packageStructure; +} + +#include "shareprovider.moc" diff --git a/plasma/generic/dataengines/share/shareprovider.h b/plasma/generic/dataengines/share/shareprovider.h new file mode 100644 index 00000000..319716c8 --- /dev/null +++ b/plasma/generic/dataengines/share/shareprovider.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SHAREPROVIDER_H +#define SHAREPROVIDER_H + +#include +#include +#include + +#include + + +class ShareProvider : public QObject +{ + Q_OBJECT + +public: + ShareProvider(QObject *parent =0); + static Plasma::PackageStructure::Ptr packageStructure(); + + QString method() const; + void setMethod(const QString &method); + + KUrl url() const; + void setUrl(const QString &url); + + void addPostFile(const QString &contentKey, const QString &content); + +Q_SIGNALS: + void handleResultData(QString data); + void handleRedirection(const QString &url); + void readyToPublish(); + void finished(const QString &url); + void finishedError(const QString &msg); + +public Q_SLOTS: + // ###: Function to return the content so the plugin can + // play with it before publishing? + + // helper methods + void publish(); + QString parseXML(const QString &key, const QString &data); + void addQueryItem(const QString &key, const QString &value); + void addPostItem(const QString &key, const QString &value, + const QString &contentType); + + // result methods + void success(const QString &url); + void error(const QString &msg); + void redirected(KIO::Job *job, const KUrl &from); + +protected Q_SLOTS: + // slots for kio + void mimetypeJobFinished(KJob *job); + void openFile(KIO::Job *job); + void finishedContentData(KIO::Job *job, const QByteArray &data); + void finishedPublish(KJob *job); + void readPublishData(KIO::Job *job, const QByteArray &data); + +protected: + void finishHeader(); + +private: + QString m_content; + QString m_contentKey; + QString m_mimetype; + + bool m_isBlob; + bool m_isPost; + + KUrl m_url; + KUrl m_service; + + QByteArray m_data; + QByteArray m_buffer; + QByteArray m_boundary; + + static Plasma::PackageStructure::Ptr m_packageStructure; +}; + +#endif // SHAREPROVIDER diff --git a/plasma/generic/dataengines/share/shareservice.cpp b/plasma/generic/dataengines/share/shareservice.cpp new file mode 100644 index 00000000..6aec7434 --- /dev/null +++ b/plasma/generic/dataengines/share/shareservice.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "shareservice.h" +#include "shareprovider.h" + + +ShareService::ShareService(ShareEngine *engine) + : Plasma::Service(engine) +{ + setName("share"); +} + +Plasma::ServiceJob *ShareService::createJob(const QString &operation, + QMap ¶meters) +{ + return new ShareJob(destination(), operation, parameters, this); +} + +ShareJob::ShareJob(const QString &destination, const QString &operation, + QMap ¶meters, QObject *parent) + : Plasma::ServiceJob(destination, operation, parameters, parent), + m_action(0), m_provider(0), m_package(0) +{ +} + +ShareJob::~ShareJob() +{ + delete m_action; + delete m_provider; + delete m_package; +} + +void ShareJob::start() +{ + //KService::Ptr service = KService::serviceByStorageId("plasma-share-pastebincom.desktop"); + KService::Ptr service = KService::serviceByStorageId(destination()); + if (!service) { + showError(i18n("Could not find the provider with the specified destination")); + return; + } + + QString pluginName = + service->property("X-KDE-PluginInfo-Name", QVariant::String).toString(); + + const QString path = + KStandardDirs::locate("data", "plasma/shareprovider/" + pluginName + '/' ); + + if (path.isEmpty()) { + showError(i18n("Invalid path for the requested provider")); + return; + } + + m_package = new Plasma::Package(path, ShareProvider::packageStructure()); + if (m_package->isValid()) { + const QString mainscript = + m_package->path() + m_package->structure()->contentsPrefixPaths().at(0) + + m_package->structure()->path("mainscript"); + + if (!QFile::exists(mainscript)) { + showError(i18n("Selected provider does not have a valid script file")); + return; + } + + const QString interpreter = + Kross::Manager::self().interpreternameForFile(mainscript); + + if (interpreter.isEmpty()) { + showError(i18n("Selected provider does not provide a supported script file")); + return; + } + + m_action = new Kross::Action(parent(), pluginName); + if (m_action) { + m_provider = new ShareProvider(this); + connect(m_provider, SIGNAL(readyToPublish()), this, SLOT(publish())); + connect(m_provider, SIGNAL(finished(QString)), + this, SLOT(showResult(QString))); + connect(m_provider, SIGNAL(finishedError(QString)), + this, SLOT(showError(QString))); + + // automatically connects signals and slots with the script + m_action->addObject(m_provider, "provider", + Kross::ChildrenInterface::AutoConnectSignals); + + // set the main script file and load it + m_action->setFile(mainscript); + m_action->trigger(); + + // check for any errors + if(m_action->hadError()) { + showError(i18n("Error trying to execute script")); + return; + } + + // do the work together with the loaded plugin + const QStringList functions = m_action->functionNames(); + if (!functions.contains("url") || !functions.contains("contentKey") || + !functions.contains("setup")) { + showError(i18n("Could not find all required functions")); + return; + } + + // call the methods from the plugin + const QString url = + m_action->callFunction("url", QVariantList()).toString(); + m_provider->setUrl(url); + + // setup the method (get/post) + QVariant vmethod; + if (functions.contains("method")) { + vmethod = + m_action->callFunction("method", QVariantList()).toString(); + } + + // default is POST (if the plugin does not specify one method) + const QString method = vmethod.isValid() ? vmethod.toString() : "POST"; + m_provider->setMethod(method); + + // setup the provider + QVariant setup = m_action->callFunction("setup", QVariantList()); + + // get the content from the parameters, set the url and add the file + // then we can wait the signal to publish the information + const QString contentKey = + m_action->callFunction("contentKey", QVariantList()).toString(); + + const QString content(parameters()["content"].toString()); + m_provider->addPostFile(contentKey, content); + } + } +} + +void ShareJob::publish() +{ + m_provider->publish(); +} + +void ShareJob::showResult(const QString &url) +{ + setResult(url); +} + +void ShareJob::showError(const QString &message) +{ + QString errorMsg = message; + if (errorMsg.isEmpty()) { + errorMsg = i18n("Unknown Error"); + } + + setError(1); + setErrorText(message); + emitResult(); +} + +#include "shareservice.moc" diff --git a/plasma/generic/dataengines/share/shareservice.h b/plasma/generic/dataengines/share/shareservice.h new file mode 100644 index 00000000..aa075911 --- /dev/null +++ b/plasma/generic/dataengines/share/shareservice.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright 2010 Artur Duque de Souza * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SHARE_SERVICE_H +#define SHARE_SERVICE_H + +#include "shareengine.h" + +#include +#include + +class ShareProvider; + +namespace Plasma { + class ServiceJob; + class Package; +} + +namespace Kross { + class Action; +} + +class ShareService : public Plasma::Service +{ + Q_OBJECT + +public: + ShareService(ShareEngine *engine); + Plasma::ServiceJob *createJob(const QString &operation, + QMap ¶meters); +}; + +class ShareJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + ShareJob(const QString &destination, const QString &operation, + QMap ¶meters, QObject *parent = 0); + ~ShareJob(); + void start(); + +public slots: + void publish(); + void showResult(const QString &url); + void showError(const QString &msg); + +private: + Kross::Action *m_action; + ShareProvider *m_provider; + Plasma::Package *m_package; +}; + +#endif // SHARE_SERVICE diff --git a/plasma/generic/dataengines/soliddevice/CMakeLists.txt b/plasma/generic/dataengines/soliddevice/CMakeLists.txt new file mode 100644 index 00000000..7e0ff39b --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/CMakeLists.txt @@ -0,0 +1,16 @@ +set(soliddevice_engine_SRCS + soliddeviceengine.cpp + devicesignalmapper.cpp + devicesignalmapmanager.cpp + hddtemp.cpp + soliddeviceservice.cpp + soliddevicejob.cpp +) + +kde4_add_plugin(plasma_engine_soliddevice ${soliddevice_engine_SRCS}) +target_link_libraries(plasma_engine_soliddevice ${KDE4_KDECORE_LIBS} ${KDE4_SOLID_LIBS} ${QT_QTNETWORK_LIBRARY} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBRARY}) + +install(TARGETS plasma_engine_soliddevice DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-soliddevice.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +install(FILES soliddevice.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services ) + diff --git a/plasma/generic/dataengines/soliddevice/Messages.sh b/plasma/generic/dataengines/soliddevice/Messages.sh new file mode 100755 index 00000000..ea6e6f04 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp` -o $podir/plasma_engine_soliddevice.pot diff --git a/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.cpp b/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.cpp new file mode 100644 index 00000000..102ce805 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "devicesignalmapmanager.h" + +DeviceSignalMapManager::DeviceSignalMapManager(QObject *parent) : QObject(parent) +{ + user = parent; +} + +DeviceSignalMapManager::~DeviceSignalMapManager() +{ +} + +void DeviceSignalMapManager::mapDevice(Solid::AcAdapter *ac, const QString &udi) +{ + AcAdapterSignalMapper *map=0; + if (!signalmap.contains(Solid::DeviceInterface::AcAdapter)) { + map = new AcAdapterSignalMapper(this); + signalmap[Solid::DeviceInterface::AcAdapter] = map; + connect(map, SIGNAL(deviceChanged(QString,QString,QVariant)), user, SLOT(deviceChanged(QString,QString,QVariant))); + } else { + map = (AcAdapterSignalMapper*)signalmap[Solid::DeviceInterface::AcAdapter]; + } + + connect(ac, SIGNAL(plugStateChanged(bool,QString)), map, SLOT(plugStateChanged(bool))); + map->setMapping(ac, udi); +} + +void DeviceSignalMapManager::mapDevice(Solid::Button *button, const QString &udi) +{ + ButtonSignalMapper *map=0; + if (!signalmap.contains(Solid::DeviceInterface::Button)) { + map = new ButtonSignalMapper(this); + signalmap[Solid::DeviceInterface::Button] = map; + connect(map, SIGNAL(deviceChanged(QString,QString,QVariant)), user, SLOT(deviceChanged(QString,QString,QVariant))); + } else { + map = (ButtonSignalMapper*)signalmap[Solid::DeviceInterface::Button]; + } + + connect(button, SIGNAL(pressed(Solid::Button::ButtonType,QString)), map, SLOT(pressed(Solid::Button::ButtonType))); + map->setMapping(button, udi); +} + +void DeviceSignalMapManager::mapDevice(Solid::Battery *battery, const QString &udi) +{ + BatterySignalMapper *map=0; + if (!signalmap.contains(Solid::DeviceInterface::Battery)) { + map = new BatterySignalMapper(this); + signalmap[Solid::DeviceInterface::Battery] = map; + connect(map, SIGNAL(deviceChanged(QString,QString,QVariant)), user, SLOT(deviceChanged(QString,QString,QVariant))); + } else { + map = (BatterySignalMapper*)signalmap[Solid::DeviceInterface::Battery]; + } + + connect(battery, SIGNAL(chargePercentChanged(int,QString)), map, SLOT(chargePercentChanged(int))); + connect(battery, SIGNAL(chargeStateChanged(int,QString)), map, SLOT(chargeStateChanged(int))); + connect(battery, SIGNAL(plugStateChanged(bool,QString)), map, SLOT(plugStateChanged(bool))); + map->setMapping(battery, udi); +} + +void DeviceSignalMapManager::mapDevice(Solid::StorageAccess *storageaccess, const QString &udi) +{ + StorageAccessSignalMapper *map=0; + if (!signalmap.contains(Solid::DeviceInterface::StorageAccess)) { + map = new StorageAccessSignalMapper(this); + signalmap[Solid::DeviceInterface::StorageAccess] = map; + connect(map, SIGNAL(deviceChanged(QString,QString,QVariant)), user, SLOT(deviceChanged(QString,QString,QVariant))); + } else { + map = (StorageAccessSignalMapper*)signalmap[Solid::DeviceInterface::StorageAccess]; + } + + connect(storageaccess, SIGNAL(accessibilityChanged(bool,QString)), map, SLOT(accessibilityChanged(bool))); + map->setMapping(storageaccess, udi); +} + +void DeviceSignalMapManager::unmapDevice(Solid::AcAdapter *ac) +{ + AcAdapterSignalMapper *map = (AcAdapterSignalMapper*)signalmap.value(Solid::DeviceInterface::AcAdapter); + if (!map) { + return; + } + + disconnect(ac, SIGNAL(plugStateChanged(bool,QString)), map, SLOT(plugStateChanged(bool))); + disconnect(map, SIGNAL(deviceChanged(QString,QString,QVariant)), user, SLOT(deviceChanged(QString,QString,QVariant))); +} + +void DeviceSignalMapManager::unmapDevice(Solid::Button *button) +{ + ButtonSignalMapper *map = (ButtonSignalMapper*)signalmap.value(Solid::DeviceInterface::Button); + if (!map) { + return; + } + + disconnect(button, SIGNAL(pressed(Solid::Button::ButtonType,QString)), map, SLOT(pressed(Solid::Button::ButtonType))); +} + +void DeviceSignalMapManager::unmapDevice(Solid::Battery *battery) +{ + BatterySignalMapper *map = (BatterySignalMapper*)signalmap.value(Solid::DeviceInterface::Battery); + if (!map) { + return; + } + + disconnect(battery, SIGNAL(chargePercentChanged(int,QString)), map, SLOT(chargePercentChanged(int))); + disconnect(battery, SIGNAL(chargeStateChanged(int,QString)), map, SLOT(chargeStateChanged(int))); + disconnect(battery, SIGNAL(plugStateChanged(bool,QString)), map, SLOT(plugStateChanged(bool))); +} + +void DeviceSignalMapManager::unmapDevice(Solid::StorageAccess *storageaccess) +{ + StorageAccessSignalMapper *map = (StorageAccessSignalMapper*)signalmap.value(Solid::DeviceInterface::StorageAccess); + if (!map) { + return; + } + + disconnect(storageaccess, SIGNAL(accessibilityChanged(bool,QString)), map, SLOT(accessibilityChanged(bool))); +} + +#include "devicesignalmapmanager.moc" diff --git a/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.h b/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.h new file mode 100644 index 00000000..5762a1fb --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/devicesignalmapmanager.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DEVICE_SIGNALMAP_MANAGER_H +#define DEVICE_SIGNALMAP_MANAGER_H + +#include + +#include "devicesignalmapper.h" + +class DeviceSignalMapManager : public QObject +{ + Q_OBJECT + + public: + DeviceSignalMapManager(QObject *parent=0); + ~DeviceSignalMapManager(); + + void mapDevice(Solid::AcAdapter *ac, const QString &udi); + void mapDevice(Solid::Button *button, const QString &udi); + void mapDevice(Solid::Battery *battery, const QString &udi); + void mapDevice(Solid::StorageAccess *storageaccess, const QString &udi); + + void unmapDevice(Solid::AcAdapter *ac); + void unmapDevice(Solid::Button *button); + void unmapDevice(Solid::Battery *battery); + void unmapDevice(Solid::StorageAccess *storageaccess); + + private: + QMap signalmap; + QObject *user; +}; + +#endif diff --git a/plasma/generic/dataengines/soliddevice/devicesignalmapper.cpp b/plasma/generic/dataengines/soliddevice/devicesignalmapper.cpp new file mode 100644 index 00000000..fde7cc35 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/devicesignalmapper.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "devicesignalmapper.h" + +DeviceSignalMapper::DeviceSignalMapper(QObject *parent) : QSignalMapper(parent) +{ +} + +DeviceSignalMapper::~DeviceSignalMapper() +{ +} + +void DeviceSignalMapper::setMapping(QObject* device, const QString &udi) +{ + signalmap[device] = udi; +} + +AcAdapterSignalMapper::AcAdapterSignalMapper(QObject *parent) : DeviceSignalMapper(parent) +{ +} + +AcAdapterSignalMapper::~AcAdapterSignalMapper() +{ +} + +void AcAdapterSignalMapper::plugStateChanged(bool newState) +{ + emit(deviceChanged(signalmap[sender()], "Plugged In", newState)); +} + + +ButtonSignalMapper::ButtonSignalMapper(QObject *parent) : DeviceSignalMapper(parent) +{ +} + +ButtonSignalMapper::~ButtonSignalMapper() +{ +} + +void ButtonSignalMapper::pressed(Solid::Button::ButtonType type) +{ + Q_UNUSED(type) + emit(deviceChanged(signalmap[sender()], "Pressed", true)); +} + +BatterySignalMapper::BatterySignalMapper(QObject *parent) : DeviceSignalMapper(parent) +{ +} + +BatterySignalMapper::~BatterySignalMapper() +{ +} + +void BatterySignalMapper::chargePercentChanged(int value) +{ + emit(deviceChanged(signalmap[sender()], "Charge Percent", value)); +} + +void BatterySignalMapper::chargeStateChanged(int newState) +{ + QStringList chargestate; + chargestate << "Fully Charged" << "Charging" << "Discharging"; + emit(deviceChanged(signalmap[sender()], "Charge State", chargestate.at(newState))); +} + +void BatterySignalMapper::plugStateChanged(bool newState) +{ + emit(deviceChanged(signalmap[sender()], "Plugged In", newState)); +} + +StorageAccessSignalMapper::StorageAccessSignalMapper(QObject *parent) : DeviceSignalMapper(parent) +{ +} + +StorageAccessSignalMapper::~StorageAccessSignalMapper() +{ +} + +void StorageAccessSignalMapper::accessibilityChanged(bool accessible) +{ + emit(deviceChanged(signalmap[sender()], "Accessible", accessible)); +} + +#include "devicesignalmapper.moc" diff --git a/plasma/generic/dataengines/soliddevice/devicesignalmapper.h b/plasma/generic/dataengines/soliddevice/devicesignalmapper.h new file mode 100644 index 00000000..e7467474 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/devicesignalmapper.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DEVICE_SIGNAL_MAPPER_H +#define DEVICE_SIGNAL_MAPPER_H + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DeviceSignalMapper : public QSignalMapper +{ + Q_OBJECT + + public: + DeviceSignalMapper(QObject *parent=0); + ~DeviceSignalMapper(); + + void setMapping(QObject* device, const QString &udi); + + Q_SIGNALS: + void deviceChanged(const QString& udi, const QString &property, QVariant value); + + protected: + QMap signalmap; +}; + +class AcAdapterSignalMapper : public DeviceSignalMapper +{ + Q_OBJECT + + public: + AcAdapterSignalMapper(QObject *parent=0); + ~AcAdapterSignalMapper(); + + public Q_SLOTS: + void plugStateChanged(bool newState); +}; + +class ButtonSignalMapper : public DeviceSignalMapper +{ + Q_OBJECT + + public: + ButtonSignalMapper(QObject *parent=0); + ~ButtonSignalMapper(); + + public Q_SLOTS: + void pressed(Solid::Button::ButtonType type); +}; + +class BatterySignalMapper : public DeviceSignalMapper +{ + Q_OBJECT + + public: + BatterySignalMapper(QObject *parent=0); + ~BatterySignalMapper(); + + public Q_SLOTS: + void chargePercentChanged(int value); + void chargeStateChanged(int newState); + void plugStateChanged(bool newState); +}; + +class StorageAccessSignalMapper : public DeviceSignalMapper +{ + Q_OBJECT + + public: + StorageAccessSignalMapper(QObject *parent=0); + ~StorageAccessSignalMapper(); + + public Q_SLOTS: + void accessibilityChanged(bool accessible); +}; + +#endif diff --git a/plasma/generic/dataengines/soliddevice/hddtemp.cpp b/plasma/generic/dataengines/soliddevice/hddtemp.cpp new file mode 100644 index 00000000..f2fee2f2 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/hddtemp.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "hddtemp.h" + +#include + +#include + +#include + +HddTemp::HddTemp(QObject* parent) + : QObject(parent), + m_failCount(0), + m_cacheValid(false) +{ + updateData(); +} + +HddTemp::~HddTemp() +{ +} + +QStringList HddTemp::sources() +{ + updateData(); + return m_data.keys(); +} + +void HddTemp::timerEvent(QTimerEvent *event) +{ + killTimer(event->timerId()); + m_cacheValid = false; +} + +bool HddTemp::updateData() +{ + if (m_cacheValid) { + return true; + } + + if (m_failCount > 4) { + return false; + } + + QTcpSocket socket; + QString data; + + socket.connectToHost("localhost", 7634); + if (socket.waitForConnected(500)) { + while (data.length() < 1024) { + if (!socket.waitForReadyRead(500)) { + if (data.length() > 0) { + break; + } else { + //kDebug() << socket.errorString(); + return false; + } + } + data += QString(socket.readAll()); + } + socket.disconnectFromHost(); + //on success retry fail count + m_failCount = 0; + } else { + m_failCount++; + //kDebug() << socket.errorString(); + return false; + } + const QStringList list = data.split('|'); + int i = 1; + m_data.clear(); + while (i + 4 < list.size()) { + m_data[list[i]].append(list[i + 2]); + m_data[list[i]].append(list[i + 3]); + i += 5; + } + m_cacheValid = true; + startTimer(0); + + return true; +} + +QVariant HddTemp::data(const QString source, const DataType type) const +{ + return m_data[source][type]; +} + +#include "hddtemp.moc" diff --git a/plasma/generic/dataengines/soliddevice/hddtemp.h b/plasma/generic/dataengines/soliddevice/hddtemp.h new file mode 100644 index 00000000..ea372ea1 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/hddtemp.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Petri Damsten + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef HDDTEMP_H +#define HDDTEMP_H + +#include +#include +#include +#include +#include +#include + + +class HddTemp : public QObject +{ + Q_OBJECT + + public: + enum DataType {Temperature=0, Unit}; + + HddTemp(QObject *parent=0); + ~HddTemp(); + QStringList sources(); + QVariant data(const QString source, const DataType type) const; + + protected: + void timerEvent(QTimerEvent *event); + + private: + int m_failCount; + bool m_cacheValid; + QMap > m_data; + bool updateData(); +}; + + +#endif diff --git a/plasma/generic/dataengines/soliddevice/plasma-dataengine-soliddevice.desktop b/plasma/generic/dataengines/soliddevice/plasma-dataengine-soliddevice.desktop new file mode 100644 index 00000000..bbed0e6e --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/plasma-dataengine-soliddevice.desktop @@ -0,0 +1,159 @@ +[Desktop Entry] +Name=Device Information +Name[ar]=معلومات الأجهزة +Name[ast]=Información del preséu +Name[be@latin]=Źviestki z pryłady +Name[bg]=Данни за устройства +Name[bn]=ডিভাইস তথ্য +Name[bn_IN]=ডিভাইস সংক্রান্ত তথ্য +Name[bs]=podaci o uređajima +Name[ca]=Informació dels dispositius +Name[ca@valencia]=Informació dels dispositius +Name[cs]=Informace o zařízení +Name[csb]=Wëdowiédzô ò ùrządzeniach +Name[da]=Enhedsinformation +Name[de]=Geräteinformationen +Name[el]=Πληροφορίες συσκευής +Name[en_GB]=Device Information +Name[eo]=Aparataj Informoj +Name[es]=Información del dispositivo +Name[et]=Seadmete teave +Name[eu]=Gailuari buruzko informazioa +Name[fi]=Laitetiedot +Name[fr]=Informations sur les périphériques +Name[fy]=Apparaatynformaasje +Name[ga]=Eolas faoi Ghléas +Name[gl]=Información do dispositivo +Name[gu]=ઉપકરણ માહિતી +Name[he]=מידע על התקנים +Name[hi]=उपकरण जानकारी +Name[hne]=उपकरन जानकारी +Name[hr]=Podaci o uređaju +Name[hu]=Eszközjellemzők +Name[ia]=Information de dispositivo +Name[id]=Informasi Divais +Name[is]=Upplýsingar tækis +Name[it]=Informazioni sui dispositivi +Name[ja]=デバイス情報 +Name[kk]=Құрылғы мәліметі +Name[km]=ព័ត៌មាន​ឧបករណ៍ +Name[kn]=ಸಾಧನದ ಮಾಹಿತಿ +Name[ko]=장치 정보 +Name[ku]=Agahiya Cîhazê +Name[lt]=Informacija apie įrenginius +Name[lv]=Ierīču informācija +Name[mai]=डिवायस सूचना +Name[mk]=Информации за уреди +Name[ml]=ഉപകരണ വിവരം +Name[mr]=साधन माहिती +Name[nb]=Enhetsinformasjon +Name[nds]=Reedschap-Informatschonen +Name[nl]=Apparaatinformatie +Name[nn]=Einingsinformasjon +Name[or]=ଯନ୍ତ୍ର ସୂଚନା +Name[pa]=ਜੰਤਰ ਜਾਣਕਾਰੀ +Name[pl]=Informacje o urządzeniach +Name[pt]=Informação dos Dispositivos +Name[pt_BR]=Informações do dispositivo +Name[ro]=Informații dispozitiv +Name[ru]=Сведения об устройствах +Name[si]=මෙවලම් තොරතුරු +Name[sk]=Informácie o zariadení +Name[sl]=Podatki o napravah +Name[sr]=подаци о уређајима +Name[sr@ijekavian]=подаци о уређајима +Name[sr@ijekavianlatin]=podaci o uređajima +Name[sr@latin]=podaci o uređajima +Name[sv]=Enhetsinformation +Name[ta]=Device Information +Name[tg]=Иттилооти дастгоҳ +Name[th]=รายละเอียดอุปกรณ์ +Name[tr]=Aygıt Bilgileri +Name[ug]=ئۈسكۈنە ئۇچۇرى +Name[uk]=Інформація про пристрої +Name[vi]=Thông tin thiết bị +Name[wa]=Informåcions so l' éndjin +Name[x-test]=xxDevice Informationxx +Name[zh_CN]=设备信息 +Name[zh_TW]=裝置資訊 +Comment=Device data via Solid +Comment[ar]=بيانات الأجهزة عن طريق سوليد +Comment[ast]=Datos de preséu vía Solid +Comment[bg]=Данни за устройствата (чрез Solid) +Comment[bs]=Podaci o uređajima preko Solida +Comment[ca]=Dades dels dispositius via Solid +Comment[ca@valencia]=Dades dels dispositius via Solid +Comment[cs]=Data zařízení pomocí Solid +Comment[csb]=Pòdôwczi ùrządzeniów z pòmòcą Solid +Comment[da]=Enhedsdata via Solid +Comment[de]=Gerätedaten mittels Solid +Comment[el]=Δεδομένα συσκευών μέσω Solid +Comment[en_GB]=Device data via Solid +Comment[es]=Datos de dispositivo vía Solid +Comment[et]=Seadmete andmed Solidi vahendusel +Comment[eu]=Gailuen datuak Solid bidez +Comment[fi]=Laitetietoja Solid-rajapinnalta +Comment[fr]=Données de périphériques utilisant Solid +Comment[fy]=Àpparaatgegevens fia Solid +Comment[ga]=Eolas faoi ghléas trí Solid +Comment[gl]=Datos do dispositivo mediante Solid +Comment[gu]=સોલિડ વડે ઉપકરણ માહિતી +Comment[he]=מידע אודות התקן באמצעות Solid +Comment[hr]=Podaci o uređajima preko Solida +Comment[hu]=Eszközjellemzők a Solid alrendszerből +Comment[ia]=Datos de dispositivos via Solid +Comment[id]=Data divais via Solid +Comment[is]=Vélbúnaðarupplýsingar með Solid +Comment[it]=Dati sui dispositivi con Solid +Comment[ja]=Solid によるデバイスデータ +Comment[kk]=Solid құрылғы деректері +Comment[km]=ទិន្នន័យ​ឧបករណ៍តាម​រយៈ Solid​ +Comment[kn]=ಸಾಲಿಡ್‌ನ ಮೂಲಕ ಸಾಧನ ದತ್ತಾಂಶ +Comment[ko]=Solid를 통한 장치 데이터 +Comment[lt]=Solid įrenginių duomenys +Comment[lv]=Ierīču dati no Solid +Comment[mai]=सालिड सँ युक्ति आंकड़ा +Comment[mk]=Податоци за уреди преку Солид +Comment[ml]=സോളിഡ് നല്‍കുന്ന ഉപകരണങ്ങളെക്കുറിച്ചുള്ള ഡാറ്റ +Comment[mr]=सॉलिड कडून साधन माहिती +Comment[nb]=Enhetsdata via Solid +Comment[nds]=Reedschapdaten över Solid +Comment[nl]=Apparaatgegevens via Solid +Comment[nn]=SolidDevice-data +Comment[pa]=ਜੰਤਰ ਡਾਟਾ ਸਾਲਡ ਵਜੋਂ +Comment[pl]=Dane urządzenia przez Solid +Comment[pt]=Dados dos dispositivos através do Solid +Comment[pt_BR]=Dados do dispositivo através do Solid +Comment[ro]=Date despre dispozitive via Solid +Comment[ru]=Сведения об устройствах от Solid +Comment[si]=Solid වෙතින් උපකරණ දත්ත +Comment[sk]=Dáta zariadenia pomocou Solid +Comment[sl]=Podatki o napravah s pomočjo Solid +Comment[sr]=Подаци о уређајима преко Солида +Comment[sr@ijekavian]=Подаци о уређајима преко Солида +Comment[sr@ijekavianlatin]=Podaci o uređajima preko Solida +Comment[sr@latin]=Podaci o uređajima preko Solida +Comment[sv]=Enhetsdata via Solid +Comment[tg]=Данные SolidDevice для плазмоидов +Comment[th]=ข้อมูลของอุปกรณ์ผ่านทาง Solid +Comment[tr]=Solid üzerinden aygıt verisi +Comment[ug]=Solid ئارقىلىق ئۈسكۈنە سانلىق-مەلۇماتىغا ئېرىشىدۇ +Comment[uk]=Дані щодо пристроїв з Solid +Comment[vi]=Thiết bị dữ liệu qua Solid +Comment[wa]=Dinêyes di l' éndjin avou Solid +Comment[x-test]=xxDevice data via Solidxx +Comment[zh_CN]=通过 Solid 获得设备数据 +Comment[zh_TW]=透過 Solid 的裝置資料 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=drive-harddisk +X-KDE-Library=plasma_engine_soliddevice + +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=wilderkde@gmail.com +X-KDE-PluginInfo-Name=soliddevice +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/soliddevice/soliddevice.operations b/plasma/generic/dataengines/soliddevice/soliddevice.operations new file mode 100644 index 00000000..49d8c471 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddevice.operations @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/soliddevice/soliddeviceengine.cpp b/plasma/generic/dataengines/soliddevice/soliddeviceengine.cpp new file mode 100644 index 00000000..b788fd66 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddeviceengine.cpp @@ -0,0 +1,806 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "soliddeviceengine.h" +#include "soliddeviceservice.h" + +#include +#include +#include + +#include +#include +#include + +#include + +//TODO: implement in libsolid2 +namespace +{ + template DevIface *getAncestorAs(const Solid::Device &device) + { + for (Solid::Device parent = device.parent(); + parent.isValid(); + parent = parent.parent()) { + if (parent.is()) { + return parent.as(); + } + } + return NULL; + } +} + +SolidDeviceEngine::SolidDeviceEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_temperature(0), + m_notifier(0) +{ + Q_UNUSED(args) + m_signalmanager = new DeviceSignalMapManager(this); + + listenForNewDevices(); + setMinimumPollingInterval(1000); + connect(this, SIGNAL(sourceRemoved(QString)), + this, SLOT(sourceWasRemoved(QString))); +} + +SolidDeviceEngine::~SolidDeviceEngine() +{ +} + +Plasma::Service* SolidDeviceEngine::serviceForSource(const QString& source) +{ + return new SolidDeviceService (this, source); +} + +void SolidDeviceEngine::listenForNewDevices() +{ + if (m_notifier) { + return; + } + + //detect when new devices are added + m_notifier = Solid::DeviceNotifier::instance(); + connect(m_notifier, SIGNAL(deviceAdded(QString)), + this, SLOT(deviceAdded(QString))); + connect(m_notifier, SIGNAL(deviceRemoved(QString)), + this, SLOT(deviceRemoved(QString))); +} + +bool SolidDeviceEngine::sourceRequestEvent(const QString &name) +{ + if (name.startsWith('/')) { + Solid::Device device = Solid::Device(name); + if (device.isValid()) { + if (m_devicemap.contains(name) ) { + return true; + } else { + m_devicemap[name] = device; + return populateDeviceData(name); + } + } + } else { + Solid::Predicate predicate = Solid::Predicate::fromString(name); + if (predicate.isValid() && !m_predicatemap.contains(name)) { + foreach (const Solid::Device &device, Solid::Device::listFromQuery(predicate)) { + m_predicatemap[name] << device.udi(); + } + + setData(name, m_predicatemap[name]); + return true; + } + } + + kDebug() << "Source is not a predicate or a device."; + return false; +} + +void SolidDeviceEngine::sourceWasRemoved(const QString &source) +{ + m_devicemap.remove(source); + m_predicatemap.remove(source); +} + +bool SolidDeviceEngine::populateDeviceData(const QString &name) +{ + Solid::Device device = m_devicemap.value(name); + if (!device.isValid()) { + return false; + } + + QStringList devicetypes; + setData(name, I18N_NOOP("Parent UDI"), device.parentUdi()); + setData(name, I18N_NOOP("Vendor"), device.vendor()); + setData(name, I18N_NOOP("Product"), device.product()); + setData(name, I18N_NOOP("Description"), device.description()); + setData(name, I18N_NOOP("Icon"), device.icon()); + setData(name, I18N_NOOP("Emblems"), device.emblems()); + setData(name, I18N_NOOP("State"), Idle); + setData(name, I18N_NOOP("Operation result"), Working); + setData(name, I18N_NOOP("Timestamp"), QDateTime::currentDateTime()); + + if (device.is()) { + Solid::Processor *processor = device.as(); + if (!processor) { + return false; + } + + devicetypes << I18N_NOOP("Processor"); + setData(name, I18N_NOOP("Number"), processor->number()); + setData(name, I18N_NOOP("Max Speed"), processor->maxSpeed()); + setData(name, I18N_NOOP("Can Change Frequency"), processor->canChangeFrequency()); + } + if (device.is()) { + Solid::Block *block = device.as(); + if (!block) { + return false; + } + + devicetypes << I18N_NOOP("Block"); + setData(name, I18N_NOOP("Major"), block->deviceMajor()); + setData(name, I18N_NOOP("Minor"), block->deviceMajor()); + setData(name, I18N_NOOP("Device"), block->device()); + } + if (device.is()) { + Solid::StorageAccess *storageaccess = device.as(); + if (!storageaccess) { + return false; + } + + devicetypes << I18N_NOOP("Storage Access"); + setData(name, I18N_NOOP("Accessible"), storageaccess->isAccessible()); + setData(name, I18N_NOOP("File Path"), storageaccess->filePath()); + + if (storageaccess->isAccessible()) { + QVariant freeDiskVar; + qulonglong freeDisk = freeDiskSpace(storageaccess->filePath()); + if ( freeDisk != (qulonglong)-1 ) { + freeDiskVar.setValue( freeDisk ); + } + if (!device.is()) { + setData(name, I18N_NOOP("Free Space"), freeDiskVar ); + setData(name, I18N_NOOP("Free Space Text"), KGlobal::locale()->formatByteSize(freeDisk)); + } + } + + m_signalmanager->mapDevice(storageaccess, device.udi()); + } + + if (device.is()) { + Solid::StorageDrive *storagedrive = device.as(); + if (!storagedrive) { + return false; + } + + devicetypes << I18N_NOOP("Storage Drive"); + + QStringList bus; + bus << I18N_NOOP("Ide") << I18N_NOOP("Usb") << I18N_NOOP("Ieee1394") << I18N_NOOP("Scsi") << I18N_NOOP("Sata") << I18N_NOOP("Platform"); + QStringList drivetype; + drivetype << I18N_NOOP("Hard Disk") << I18N_NOOP("Cdrom Drive") << I18N_NOOP("Floppy") << I18N_NOOP("Tape") << I18N_NOOP("Compact Flash") << I18N_NOOP("Memory Stick") << I18N_NOOP("Smart Media") << I18N_NOOP("SdMmc") << I18N_NOOP("Xd"); + + setData(name, I18N_NOOP("Bus"), bus.at((int)storagedrive->bus())); + setData(name, I18N_NOOP("Drive Type"), drivetype.at((int)storagedrive->driveType())); + setData(name, I18N_NOOP("Removable"), storagedrive->isRemovable()); + setData(name, I18N_NOOP("Hotpluggable"), storagedrive->isHotpluggable()); + + updateHardDiskTemperature(name); + } + else { + bool isRemovable = false; + bool isHotpluggable = false; + Solid::StorageDrive *drive = getAncestorAs(device); + if (drive) { + //remove check for isHotpluggable() when plasmoids are changed to check for both properties + isRemovable = (drive->isRemovable() || drive->isHotpluggable()); + isHotpluggable = drive->isHotpluggable(); + } + setData(name, I18N_NOOP("Removable"), isRemovable); + setData(name, I18N_NOOP("Hotpluggable"), isHotpluggable); + } + + + if (device.is()) { + Solid::OpticalDrive *opticaldrive = device.as(); + if (!opticaldrive) { + return false; + } + + devicetypes << I18N_NOOP("Optical Drive"); + + QStringList supportedtypes; + Solid::OpticalDrive::MediumTypes mediatypes = opticaldrive->supportedMedia(); + if (mediatypes & Solid::OpticalDrive::Cdr) { + supportedtypes << I18N_NOOP("CD-R"); + } + if (mediatypes & Solid::OpticalDrive::Cdrw) { + supportedtypes << I18N_NOOP("CD-RW"); + } + if (mediatypes & Solid::OpticalDrive::Dvd) { + supportedtypes << I18N_NOOP("DVD"); + } + if (mediatypes & Solid::OpticalDrive::Dvdr) { + supportedtypes << I18N_NOOP("DVD-R"); + } + if (mediatypes & Solid::OpticalDrive::Dvdrw) { + supportedtypes << I18N_NOOP("DVD-RW"); + } + if (mediatypes & Solid::OpticalDrive::Dvdram) { + supportedtypes << I18N_NOOP("DVD-RAM"); + } + if (mediatypes & Solid::OpticalDrive::Dvdplusr) { + supportedtypes << I18N_NOOP("DVD+R"); + } + if (mediatypes & Solid::OpticalDrive::Dvdplusrw) { + supportedtypes << I18N_NOOP("DVD+RW"); + } + if (mediatypes & Solid::OpticalDrive::Dvdplusdl) { + supportedtypes << I18N_NOOP("DVD+DL"); + } + if (mediatypes & Solid::OpticalDrive::Dvdplusdlrw) { + supportedtypes << I18N_NOOP("DVD+DLRW"); + } + if (mediatypes & Solid::OpticalDrive::Bd) { + supportedtypes << I18N_NOOP("BD"); + } + if (mediatypes & Solid::OpticalDrive::Bdr) { + supportedtypes << I18N_NOOP("BD-R"); + } + if (mediatypes & Solid::OpticalDrive::Bdre) { + supportedtypes << I18N_NOOP("BD-RE"); + } + if (mediatypes & Solid::OpticalDrive::HdDvd) { + supportedtypes << I18N_NOOP("HDDVD"); + } + if (mediatypes & Solid::OpticalDrive::HdDvdr) { + supportedtypes << I18N_NOOP("HDDVD-R"); + } + if (mediatypes & Solid::OpticalDrive::HdDvdrw) { + supportedtypes << I18N_NOOP("HDDVD-RW"); + } + setData(name, I18N_NOOP("Supported Media"), supportedtypes); + + setData(name, I18N_NOOP("Read Speed"), opticaldrive->readSpeed()); + setData(name, I18N_NOOP("Write Speed"), opticaldrive->writeSpeed()); + + //the following method return QList so we need to convert it to QList + QList writespeeds = opticaldrive->writeSpeeds(); + QList variantlist = QList(); + foreach(int num, writespeeds) { + variantlist << QVariant(num); + } + setData(name, I18N_NOOP("Write Speeds"), variantlist); + + } + if (device.is()) { + Solid::StorageVolume *storagevolume = device.as(); + if (!storagevolume) { + return false; + } + + devicetypes << I18N_NOOP("Storage Volume"); + + QStringList usagetypes; + usagetypes << i18n("Other") << i18n("Unused") << i18n("File System") + << i18n("Partition Table") << i18n("Raid") << i18n("Encrypted"); + + if (usagetypes.count() > storagevolume->usage()) { + setData(name, I18N_NOOP("Usage"), usagetypes.at((int)storagevolume->usage())); + } else { + setData(name, I18N_NOOP("Usage"), i18n("Unknown")); + } + + setData(name, I18N_NOOP("Ignored"), storagevolume->isIgnored()); + setData(name, I18N_NOOP("File System Type"), storagevolume->fsType()); + setData(name, I18N_NOOP("Label"), storagevolume->label()); + setData(name, I18N_NOOP("UUID"), storagevolume->uuid()); + setData(name, I18N_NOOP("Size"), storagevolume->size()); + updateInUse(name); + + //Check if the volume is part of an encrypted container + //This needs to trigger an update for the encrypted container volume since + //libsolid cannot notify us when the accessibility of the container changes + Solid::Device encryptedContainer = storagevolume->encryptedContainer(); + if (encryptedContainer.isValid()) { + QString containerUdi = encryptedContainer.udi(); + setData(name, I18N_NOOP("Encrypted Container"), containerUdi); + m_encryptedContainerMap[name] = containerUdi; + //TODO: compress the calls? + forceUpdateAccessibility(containerUdi); + } + } + if (device.is()) { + Solid::OpticalDisc *opticaldisc = device.as(); + if (!opticaldisc) { + return false; + } + + devicetypes << I18N_NOOP("OpticalDisc"); + + //get the content types + QStringList contenttypelist; + Solid::OpticalDisc::ContentTypes contenttypes = opticaldisc->availableContent(); + if (contenttypes & Solid::OpticalDisc::Audio) { + contenttypelist << I18N_NOOP("Audio"); + } + if (contenttypes & Solid::OpticalDisc::Audio) { + contenttypelist << I18N_NOOP("Data"); + } + if (contenttypes & Solid::OpticalDisc::Audio) { + contenttypelist << I18N_NOOP("Video CD"); + } + if (contenttypes & Solid::OpticalDisc::Audio) { + contenttypelist << I18N_NOOP("Super Video CD"); + } + if (contenttypes & Solid::OpticalDisc::Audio) { + contenttypelist << I18N_NOOP("Video DVD"); + } + setData(name, I18N_NOOP("Available Content"), contenttypelist); + + QStringList disctypes; + disctypes << I18N_NOOP("Unknown Disc Type") << I18N_NOOP("CD Rom") << I18N_NOOP("CD Recordable") + << I18N_NOOP("CD Rewritable") << I18N_NOOP("DVD Rom") << I18N_NOOP("DVD Ram") + << I18N_NOOP("DVD Recordable") << I18N_NOOP("DVD Rewritable") << I18N_NOOP("DVD Plus Recordable") + << I18N_NOOP("DVD Plus Rewritable") << I18N_NOOP("DVD Plus Recordable Duallayer") + << I18N_NOOP("DVD Plus Rewritable Duallayer") << I18N_NOOP("Blu Ray Rom") << I18N_NOOP("Blu Ray Recordable") + << I18N_NOOP("Blu Ray Rewritable") << I18N_NOOP("HD DVD Rom") << I18N_NOOP("HD DVD Recordable") + << I18N_NOOP("HD DVD Rewritable"); + //+1 because the enum starts at -1 + setData(name, I18N_NOOP("Disc Type"), disctypes.at((int)opticaldisc->discType() + 1)); + setData(name, I18N_NOOP("Appendable"), opticaldisc->isAppendable()); + setData(name, I18N_NOOP("Blank"), opticaldisc->isBlank()); + setData(name, I18N_NOOP("Rewritable"), opticaldisc->isRewritable()); + setData(name, I18N_NOOP("Capacity"), opticaldisc->capacity()); + } + if (device.is()) { + Solid::Camera *camera = device.as(); + if (!camera) { + return false; + } + + devicetypes << I18N_NOOP("Camera"); + + setData(name, I18N_NOOP("Supported Protocols"), camera->supportedProtocols()); + setData(name, I18N_NOOP("Supported Drivers"), camera->supportedDrivers()); + // Cameras are necessarily Removable and Hotpluggable + setData(name, I18N_NOOP("Removable"), true); + setData(name, I18N_NOOP("Hotpluggable"), true); + + } + if (device.is()) { + Solid::PortableMediaPlayer *mediaplayer = device.as(); + if (!mediaplayer) { + return false; + } + + devicetypes << I18N_NOOP("Portable Media Player"); + + setData(name, I18N_NOOP("Supported Protocols"), mediaplayer->supportedProtocols()); + setData(name, I18N_NOOP("Supported Drivers"), mediaplayer->supportedDrivers()); + // Portable Media Players are necessarily Removable and Hotpluggable + setData(name, I18N_NOOP("Removable"), true); + setData(name, I18N_NOOP("Hotpluggable"), true); + + } + if (device.is()) { + Solid::NetworkInterface *networkinterface = device.as(); + if (!networkinterface) { + return false; + } + + devicetypes << I18N_NOOP("Network Interface"); + + setData(name, I18N_NOOP("Interface Name"), networkinterface->ifaceName()); + setData(name, I18N_NOOP("Wireless"), networkinterface->isWireless()); + setData(name, I18N_NOOP("Hardware Address"), networkinterface->hwAddress()); + setData(name, I18N_NOOP("MAC Address"), networkinterface->macAddress()); + } + if (device.is()) { + Solid::AcAdapter *ac = device.as(); + if (!ac) { + return false; + } + + devicetypes << I18N_NOOP("AC Adapter"); + + setData(name, I18N_NOOP("Plugged In"), ac->isPlugged()); + m_signalmanager->mapDevice(ac, device.udi()); + } + if (device.is()) { + Solid::Battery *battery = device.as(); + if (!battery) { + return false; + } + + devicetypes << I18N_NOOP("Battery"); + + QStringList batterytype; + batterytype << I18N_NOOP("Unknown Battery") << I18N_NOOP("PDA Battery") << I18N_NOOP("UPS Battery") + << I18N_NOOP("Primary Battery") << I18N_NOOP("Mouse Battery") << I18N_NOOP("Keyboard Battery") + << I18N_NOOP("Keyboard Mouse Battery") << I18N_NOOP("Camera Battery"); + + QStringList chargestate; + chargestate << I18N_NOOP("Fully Charged") << I18N_NOOP("Charging") << I18N_NOOP("Discharging"); + + setData(name, I18N_NOOP("Plugged In"), battery->isPlugged()); + setData(name, I18N_NOOP("Type"), batterytype.at((int)battery->type())); + setData(name, I18N_NOOP("Charge Percent"), battery->chargePercent()); + setData(name, I18N_NOOP("Rechargeable"), battery->isRechargeable()); + setData(name, I18N_NOOP("Charge State"), chargestate.at((int)battery->chargeState())); + + m_signalmanager->mapDevice(battery, device.udi()); + } + if (device.is()) { + Solid::Button *button = device.as(); + if (!button) { + return false; + } + + devicetypes << I18N_NOOP("Button"); + + QStringList buttontype; + buttontype << I18N_NOOP("Lid Button") << I18N_NOOP("Power Button") << I18N_NOOP("Sleep Button") + << I18N_NOOP("Unknown Button Type"); + + setData(name, I18N_NOOP("Type"), buttontype.at((int)button->type())); + setData(name, I18N_NOOP("Has State"), button->hasState()); + setData(name, I18N_NOOP("State Value"), button->stateValue()); + setData(name, I18N_NOOP("Pressed"), false); //this is an extra value that is tracked by the button signals + + m_signalmanager->mapDevice(button, device.udi()); + } + if (device.is()) { + Solid::AudioInterface *audiointerface = device.as(); + if (!audiointerface) { + return false; + } + + devicetypes << I18N_NOOP("Audio Interface"); + + QStringList audiodriver; + audiodriver << I18N_NOOP("ALSA") << I18N_NOOP("Open Sound System") << I18N_NOOP("Unknown Audio Driver"); + + setData(name, I18N_NOOP("Driver"), audiodriver.at((int)audiointerface->driver())); + setData(name, I18N_NOOP("Driver Handle"), audiointerface->driverHandle()); + setData(name, I18N_NOOP("Name"), audiointerface->name()); + + //get AudioInterfaceTypes + QStringList audiointerfacetypes; + Solid::AudioInterface::AudioInterfaceTypes devicetypes = audiointerface->deviceType(); + if (devicetypes & Solid::AudioInterface::UnknownAudioInterfaceType) { + audiointerfacetypes << I18N_NOOP("Unknown Audio Interface Type"); + } + if (devicetypes & Solid::AudioInterface::AudioControl) { + audiointerfacetypes << I18N_NOOP("Audio Control"); + } + if (devicetypes & Solid::AudioInterface::AudioInput) { + audiointerfacetypes << I18N_NOOP("Audio Input"); + } + if (devicetypes & Solid::AudioInterface::AudioOutput) { + audiointerfacetypes << I18N_NOOP("Audio Output"); + } + setData(name, I18N_NOOP("Audio Device Type"), audiointerfacetypes); + + //get SoundCardTypes + QStringList soundcardtype; + soundcardtype << I18N_NOOP("Internal Soundcard") << I18N_NOOP("USB Soundcard") << I18N_NOOP("Firewire Soundcard") + << I18N_NOOP("Headset") << I18N_NOOP("Modem"); + setData(name, I18N_NOOP("Soundcard Type"), soundcardtype.at((int)audiointerface->soundcardType())); + } + if (device.is()) { + Solid::DvbInterface *dvbinterface = device.as(); + if (!dvbinterface) { + return false; + } + + devicetypes << I18N_NOOP("DVB Interface"); + + setData(name, I18N_NOOP("Device"), dvbinterface->device()); + setData(name, I18N_NOOP("Device Adapter"), dvbinterface->deviceAdapter()); + + //get devicetypes + QStringList dvbdevicetypes; + dvbdevicetypes << I18N_NOOP("DVB Unknown") << I18N_NOOP("DVB Audio") << I18N_NOOP("DVB Ca") + << I18N_NOOP("DVB Demux") << I18N_NOOP("DVB DVR") << I18N_NOOP("DVB Frontend") + << I18N_NOOP("DVB Net") << I18N_NOOP("DVB OSD") << I18N_NOOP("DVB Sec") << I18N_NOOP("DVB Video"); + + setData(name, I18N_NOOP("DVB Device Type"), dvbdevicetypes.at((int)dvbinterface->deviceType())); + setData(name, I18N_NOOP("Device Index"), dvbinterface->deviceIndex()); + } + if (device.is()) { + Solid::Video *video = device.as(); + if (!video) { + return false; + } + + devicetypes << I18N_NOOP("Video"); + + setData(name, I18N_NOOP("Supported Protocols"), video->supportedProtocols()); + setData(name, I18N_NOOP("Supported Drivers"), video->supportedDrivers()); + + QStringList handles; + foreach (const QString &driver, video->supportedDrivers()) { + handles << video->driverHandle(driver).toString(); + } + setData(name, I18N_NOOP("Driver Handles"), handles); + } + + int index = Solid::DeviceInterface::staticMetaObject.indexOfEnumerator("Type"); + QMetaEnum typeEnum = Solid::DeviceInterface::staticMetaObject.enumerator(index); + for (int i = typeEnum.keyCount() - 1 ; i > 0; i--) { + Solid::DeviceInterface::Type type = (Solid::DeviceInterface::Type)typeEnum.value(i); + const Solid::DeviceInterface *interface = device.asDeviceInterface(type); + if (interface) { + setData(name, I18N_NOOP("Type Description"), Solid::DeviceInterface::typeDescription(type)); + break; + } + } + + setData(name, I18N_NOOP("Device Types"), devicetypes); + return true; +} + +void SolidDeviceEngine::deviceAdded(const QString& udi) +{ + Solid::Device device(udi); + + foreach (const QString &query, m_predicatemap.keys()) { + Solid::Predicate predicate = Solid::Predicate::fromString(query); + if (predicate.matches(device)) { + m_predicatemap[query] << udi; + setData(query, m_predicatemap[query]); + } + } + + if (device.is()) { + Solid::OpticalDrive *drive = getAncestorAs(device); + if (drive) { + connect(drive, SIGNAL(ejectRequested(QString)), + this, SLOT(setUnmountingState(QString))); + connect(drive, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)), + this, SLOT(setIdleState(Solid::ErrorType,QVariant,QString))); + } + } + else if (device.is()) { + // update the volume in case of 2-stage devices + if (m_devicemap.contains(udi) && query(udi).value(I18N_NOOP("Size")).toULongLong() == 0) { + Solid::GenericInterface * iface = device.as(); + if (iface) { + iface->setProperty("udi", udi); + connect(iface, SIGNAL(propertyChanged(QMap)), + this, SLOT(deviceChanged(QMap))); + } + } + + Solid::StorageAccess *access = device.as(); + if (access) { + connect(access, SIGNAL(setupRequested(QString)), + this, SLOT(setMountingState(QString))); + connect(access, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)), + this, SLOT(setIdleState(Solid::ErrorType,QVariant,QString))); + connect(access, SIGNAL(teardownRequested(QString)), + this, SLOT(setUnmountingState(QString))); + connect(access, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)), + this, SLOT(setIdleState(Solid::ErrorType,QVariant,QString))); + } + } +} + +void SolidDeviceEngine::setMountingState(const QString &udi) +{ + setData(udi, I18N_NOOP("State"), Mounting); + setData(udi, I18N_NOOP("Operation result"), Working); +} + +void SolidDeviceEngine::setUnmountingState(const QString &udi) +{ + setData(udi, I18N_NOOP("State"), Unmounting); + setData(udi, I18N_NOOP("Operation result"), Working); +} + +void SolidDeviceEngine::setIdleState(Solid::ErrorType error, QVariant errorData, const QString &udi) +{ + Q_UNUSED(errorData) + + if (error == Solid::NoError) { + setData(udi, I18N_NOOP("Operation result"), Successful); + } else { + setData(udi, I18N_NOOP("Operation result"), Unsuccessful); + } + setData(udi, I18N_NOOP("State"), Idle); + + Solid::Device device = m_devicemap.value(udi); + if (!device.isValid()) { + return; + } + + Solid::StorageAccess *storageaccess = device.as(); + if (!storageaccess) { + return; + } + + setData(udi, I18N_NOOP("Accessible"), storageaccess->isAccessible()); + setData(udi, I18N_NOOP("File Path"), storageaccess->filePath()); +} + +void SolidDeviceEngine::deviceChanged(const QMap &props) +{ + Solid::GenericInterface * iface = qobject_cast(sender()); + if (iface && iface->isValid() && props.contains("Size") && iface->property("Size").toInt() > 0) { + const QString udi = qobject_cast(iface)->property("udi").toString(); + if (populateDeviceData(udi)) + forceImmediateUpdateOfAllVisualizations(); + } +} + +qulonglong SolidDeviceEngine::freeDiskSpace(const QString &mountPoint) +{ + KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint); + if (info.isValid()) { + return info.available(); + } + return (qulonglong)-1; +} + +bool SolidDeviceEngine::updateFreeSpace(const QString &udi) +{ + Solid::Device device = m_devicemap.value(udi); + if (!device.is() || device.is()) { + return false; + } else if (!device.as()->isAccessible()) { + removeData(udi, I18N_NOOP("Free Space")); + removeData(udi, I18N_NOOP("Free Space Text")); + } + + Solid::StorageAccess *storageaccess = device.as(); + if (!storageaccess) { + return false; + } + + QVariant freeSpaceVar; + qulonglong freeSpace = freeDiskSpace(storageaccess->filePath()); + if (freeSpace != (qulonglong)-1) { + freeSpaceVar.setValue( freeSpace ); + } + setData(udi, I18N_NOOP("Free Space"), freeSpaceVar ); + setData(udi, I18N_NOOP("Free Space Text"), KGlobal::locale()->formatByteSize(freeSpace)); + return true; +} + +bool SolidDeviceEngine::updateHardDiskTemperature(const QString &udi) +{ + Solid::Device device = m_devicemap.value(udi); + Solid::Block *block = device.as(); + if (!block) { + return false; + } + + if (!m_temperature) { + m_temperature = new HddTemp(this); + } + + if (m_temperature->sources().contains(block->device())) { + setData(udi, I18N_NOOP("Temperature"), m_temperature->data(block->device(), HddTemp::Temperature)); + setData(udi, I18N_NOOP("Temperature Unit"), m_temperature->data(block->device(), HddTemp::Unit)); + return true; + } + + return false; +} + +bool SolidDeviceEngine::updateEmblems(const QString &udi) +{ + Solid::Device device = m_devicemap.value(udi); + + setData(udi, I18N_NOOP("Emblems"), device.emblems() ); + return true; +} + +bool SolidDeviceEngine::forceUpdateAccessibility(const QString &udi) +{ + Solid::Device device = m_devicemap.value(udi); + if (!device.isValid()) { + return false; + } + + updateEmblems(udi); + Solid::StorageAccess *storageaccess = device.as(); + if (storageaccess) { + setData(udi, I18N_NOOP("Accessible"), storageaccess->isAccessible()); + } + + return true; +} + +bool SolidDeviceEngine::updateInUse(const QString &udi) +{ + Solid::Device device = m_devicemap.value(udi); + if (!device.isValid()) { + return false; + } + + Solid::StorageAccess *storageaccess = device.as(); + if (!storageaccess) { + return false; + } + + if (storageaccess->isAccessible()) { + setData(udi, I18N_NOOP("In Use"), true); + } else { + Solid::StorageDrive *drive = getAncestorAs(Solid::Device(udi)); + if (drive) { + setData(udi, I18N_NOOP("In Use"), drive->isInUse()); + } + } + + return true; +} + +bool SolidDeviceEngine::updateSourceEvent(const QString& source) +{ + bool update1 = updateFreeSpace(source); + bool update2 = updateHardDiskTemperature(source); + bool update3 = updateEmblems(source); + bool update4 = updateInUse(source); + + return (update1 || update2 || update3 || update4); +} + +void SolidDeviceEngine::deviceRemoved(const QString& udi) +{ + //libsolid cannot notify us when an encrypted container is closed, + //hence we trigger an update when a device contained in an encrypted container device dies + QString containerUdi = m_encryptedContainerMap.value(udi, QString()); + + if (!containerUdi.isEmpty()) { + forceUpdateAccessibility(containerUdi); + m_encryptedContainerMap.remove(udi); + } + + foreach (const QString &query, m_predicatemap.keys()) { + m_predicatemap[query].removeAll(udi); + setData(query, m_predicatemap[query]); + } + + Solid::Device device(udi); + if (device.is()) { + Solid::StorageAccess *access = device.as(); + if (access) { + disconnect(access, 0, this, 0); + } + } + else if (device.is()) { + Solid::OpticalDrive *drive = getAncestorAs(device); + if (drive) { + disconnect(drive, 0, this, 0); + } + } + + m_devicemap.remove(udi); + removeSource(udi); +} + +void SolidDeviceEngine::deviceChanged(const QString& udi, const QString &property, const QVariant &value) +{ + setData(udi, property, value); + updateSourceEvent(udi); +} + +K_EXPORT_PLASMA_DATAENGINE(soliddevice, SolidDeviceEngine) + +#include "soliddeviceengine.moc" diff --git a/plasma/generic/dataengines/soliddevice/soliddeviceengine.h b/plasma/generic/dataengines/soliddevice/soliddeviceengine.h new file mode 100644 index 00000000..85bdc68d --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddeviceengine.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007 Christopher Blauvelt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SOLIDDEVICEENGINE_H +#define SOLIDDEVICEENGINE_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include "devicesignalmapmanager.h" +#include "devicesignalmapper.h" +#include "hddtemp.h" + +enum State { + Idle = 0, + Mounting = 1, + Unmounting = 2 +}; + +enum OperationResult { + Working = 0, + Successful = 1, + Unsuccessful =2 +}; + +/** + * This class evaluates the basic expressions given in the interface. + */ +class SolidDeviceEngine : public Plasma::DataEngine +{ + Q_OBJECT + friend class SolidDeviceService; + +public: + SolidDeviceEngine( QObject* parent, const QVariantList& args); + ~SolidDeviceEngine(); + Plasma::Service *serviceForSource (const QString& source); + +protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString& source); + +private: + bool populateDeviceData(const QString &name); + qulonglong freeDiskSpace(const QString &mountPoint); + bool updateFreeSpace(const QString &udi); + bool updateHardDiskTemperature(const QString &udi); + bool updateEmblems(const QString &udi); + bool updateInUse(const QString &udi); + bool forceUpdateAccessibility(const QString &udi); + void listenForNewDevices(); + + //predicate in string form, list of devices by udi + QMap m_predicatemap; + //udi, corresponding device + QMap m_devicemap; + //udi, corresponding encrypted container udi; + QMap m_encryptedContainerMap; + DeviceSignalMapManager *m_signalmanager; + + HddTemp *m_temperature; + Solid::DeviceNotifier *m_notifier; + +private Q_SLOTS: + void deviceAdded(const QString &udi); + void deviceRemoved(const QString &udi); + void deviceChanged(const QString& udi, const QString &property, const QVariant &value); + void sourceWasRemoved(const QString &source); + void setMountingState(const QString &udi); + void setUnmountingState(const QString &udi); + void setIdleState(Solid::ErrorType error, QVariant errorData, const QString &udi); + void deviceChanged(const QMap & props); +}; + +#endif diff --git a/plasma/generic/dataengines/soliddevice/soliddevicejob.cpp b/plasma/generic/dataengines/soliddevice/soliddevicejob.cpp new file mode 100644 index 00000000..44817bb6 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddevicejob.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "soliddevicejob.h" +#include "soliddeviceengine.h" + +#include +#include +#include +#include + +#include + +void SolidDeviceJob::start() +{ + Solid::Device device (m_dest); + QString operation = operationName(); + + if (operation == "mount") { + if (device.is()) { + Solid::StorageAccess *access = device.as(); + if (access && !access->isAccessible()) { + access->setup(); + } + } + } + else if (operation == "unmount") { + if (device.is()) { + Solid::OpticalDrive *drive = device.as(); + if (!drive) { + drive = device.parent().as(); + } + if (drive) { + drive->eject(); + } + } + else if (device.is()) { + Solid::StorageAccess *access = device.as(); + if (access && access->isAccessible()) { + access->teardown(); + } + } + } + + emitResult(); +} + +#include "soliddevicejob.moc" + diff --git a/plasma/generic/dataengines/soliddevice/soliddevicejob.h b/plasma/generic/dataengines/soliddevice/soliddevicejob.h new file mode 100644 index 00000000..873f15ca --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddevicejob.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SOLIDDEVICE_JOB_H +#define SOLIDDEVICE_JOB_H + +#include "soliddeviceengine.h" + +#include + +class SolidDeviceJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + SolidDeviceJob (SolidDeviceEngine* engine, + const QString& destination, + const QString& operation, + QMap& parameters, + QObject* parent = 0) + : ServiceJob (destination, operation, parameters, parent), + m_engine (engine), + m_dest (destination) + { + } + + void start(); + +private: + SolidDeviceEngine* m_engine; + QString m_dest; +}; + +#endif // SOLIDDEVICE_JOB_H + diff --git a/plasma/generic/dataengines/soliddevice/soliddeviceservice.cpp b/plasma/generic/dataengines/soliddevice/soliddeviceservice.cpp new file mode 100644 index 00000000..714dd1a9 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddeviceservice.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "soliddeviceservice.h" +#include "soliddevicejob.h" +#include "soliddeviceengine.h" + +SolidDeviceService::SolidDeviceService (SolidDeviceEngine* parent, const QString& source) + : Plasma::Service (parent), + m_engine(parent) +{ + setName ("soliddevice"); + setDestination (source); +} + +Plasma::ServiceJob* SolidDeviceService::createJob (const QString& operation, + QMap & parameters) +{ + if (operation == "updateFreespace") { + m_engine->updateFreeSpace(destination()); + return 0; + } + + return new SolidDeviceJob (m_engine, destination(), operation, parameters, this); +} + +#include "soliddeviceservice.moc" + diff --git a/plasma/generic/dataengines/soliddevice/soliddeviceservice.h b/plasma/generic/dataengines/soliddevice/soliddeviceservice.h new file mode 100644 index 00000000..12126494 --- /dev/null +++ b/plasma/generic/dataengines/soliddevice/soliddeviceservice.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Viranch Mehta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SOLIDDEVICE_SERVICE_H +#define SOLIDDEVICE_SERVICE_H + +#include + +class SolidDeviceEngine; + +class SolidDeviceService : public Plasma::Service +{ + Q_OBJECT + +public: + SolidDeviceService (SolidDeviceEngine* parent, const QString& source); + +protected: + Plasma::ServiceJob* createJob (const QString& operation, + QMap& parameters); + +private: + SolidDeviceEngine* m_engine; + QString m_dest; +}; + +#endif // SOLIDDEVICE_SERVICE_H + diff --git a/plasma/generic/dataengines/statusnotifieritem/CMakeLists.txt b/plasma/generic/dataengines/statusnotifieritem/CMakeLists.txt new file mode 100644 index 00000000..16887e9e --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/CMakeLists.txt @@ -0,0 +1,33 @@ +project(plasma-statusnotifieritem_engine) + +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/statusnotifierwatcher) +include_directories(${DBUSMENUQT_INCLUDE_DIR}) + +# We add our source code here +set(statusnotifieritem_engine_SRCS + statusnotifieritem_engine.cpp + statusnotifieritemsource.cpp + statusnotifieritemservice.cpp + statusnotifieritemjob.cpp + systemtraytypes.cpp +) + +set(statusnotifierwatcher_xml ${KDE4_DBUS_INTERFACES_DIR}/org.kde.StatusNotifierWatcher.xml) +QT4_ADD_DBUS_INTERFACE(statusnotifieritem_engine_SRCS ${statusnotifierwatcher_xml} statusnotifierwatcher_interface) + +set(statusnotifieritem_xml ${KDE4_DBUS_INTERFACES_DIR}/org.kde.StatusNotifierItem.xml) + +set_source_files_properties(${statusnotifieritem_xml} PROPERTIES + NO_NAMESPACE false + INCLUDE "systemtraytypes.h" + CLASSNAME OrgKdeStatusNotifierItem +) +QT4_ADD_DBUS_INTERFACE(statusnotifieritem_engine_SRCS ${statusnotifieritem_xml} statusnotifieritem_interface) + +kde4_add_plugin(plasma_engine_statusnotifieritem ${statusnotifieritem_engine_SRCS}) +target_link_libraries(plasma_engine_statusnotifieritem ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${DBUSMENUQT_LIBRARIES}) + +install(TARGETS plasma_engine_statusnotifieritem DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma_engine_statusnotifieritem.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES statusnotifieritem.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) + diff --git a/plasma/generic/dataengines/statusnotifieritem/plasma_engine_statusnotifieritem.desktop b/plasma/generic/dataengines/statusnotifieritem/plasma_engine_statusnotifieritem.desktop new file mode 100644 index 00000000..49bbcd83 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/plasma_engine_statusnotifieritem.desktop @@ -0,0 +1,127 @@ +[Desktop Entry] +Name=Status Notifier Information +Name[ar]=معلومات حالة النظام +Name[ast]=Información de notificación d'estáu +Name[bs]=Podaci izveštavača o stanju +Name[ca]=Informació del notificador d'estats +Name[ca@valencia]=Informació del notificador d'estats +Name[cs]=Informace o oznamovači stavu +Name[da]=Information om statusbekendtgørelse +Name[de]=Status-Informationen +Name[el]=Πληροφορίες για τις ειδοποιήσεις κατάστασης +Name[en_GB]=Status Notifier Information +Name[es]=Información de notificación de estado +Name[et]=Oleku märguandja teave +Name[eu]=Egoera-jakinarazleari buruzko informazioa +Name[fi]=Järjestelmäilmoittimen tiedot +Name[fr]=Informations sur le notificateur d'état +Name[gl]=Información do notificador do estado +Name[he]=מידע מ־Status Notifier +Name[hi]=तंत्र सूचक जानकारी +Name[hr]=Informacije glasnika stanja +Name[hu]=Állaportértesítési információk +Name[ia]=Informationes de notificator de stato +Name[id]=Informasi Notifikasi Status +Name[is]=Stöðutilkynningaþjónn +Name[it]=Informazioni sul notificatore di stato +Name[ja]=ステータス通知情報 +Name[kk]=Күй-жайы туралы құлақтандыру мәліметі +Name[km]=ព័ត៌មាន​កម្មវិធី​ជំនួន​ដំណឹង​ស្ថានភាព +Name[kn]=ಸ್ಥಿತಿ ಸೂಚನಾ ಮಾಹಿತಿ +Name[ko]=장치 알림이 정보 +Name[lt]=Būsenos pranešėjo informacija +Name[lv]=Statusa ziņotāja informācija +Name[mr]=स्थिती निदर्शक माहिती +Name[nb]=StatusNotifier-opplysninger +Name[nds]=Statusbescheed-Informatschonen +Name[nl]=Melding van statusinformatie +Name[pa]=ਹਾਲਤ ਨੋਟੀਫਾਇਰ ਜਾਣਕਾਰੀ +Name[pl]=Informacja o powiadomieniach stanu +Name[pt]=Informações do Item de Notificação do Estado +Name[pt_BR]=Informações do Notificador de Status +Name[ro]=Informații notificator de stare +Name[ru]=Сведения уведомлений о состоянии +Name[si]=තත්ව දැනුම්දෙන්නාගේ තොරතුරු +Name[sk]=Informácie o oznámení stavu +Name[sl]=Podatki obvestilnika o stanju +Name[sr]=Подаци извештавача о стању +Name[sr@ijekavian]=Подаци извјештавача о стању +Name[sr@ijekavianlatin]=Podaci izvještavača o stanju +Name[sr@latin]=Podaci izveštavača o stanju +Name[sv]=Information från statusunderrättelser +Name[th]=ข้อมูลการแจ้งสถานะ +Name[tr]=Durum Bildirici Bilgileri +Name[ug]=ھالەت بىلدۈرگۈ ئۇچۇرى +Name[uk]=Відомості сповіщення про стан +Name[wa]=Informåcion do notifieu d' sitatut +Name[x-test]=xxStatus Notifier Informationxx +Name[zh_CN]=状态通知信息 +Name[zh_TW]=狀態通知器資訊 +Comment=Engine for applications' status information, based on the Status Notifier protocol. +Comment[ar]=محرك للمعلومات عن حالة البرامج, مبني على بروتوكول Status Notifier +Comment[ast]=Motor pa informar del estáu d'aplicaciones, basáu nel protocolu Status Notifier. +Comment[bs]=Motor za podatke o stanju programa, na osnovu protokola izveštavača o stanju. +Comment[ca]=Motor d'informació d'estat de les aplicacions, basat en el protocol notificador d'estat. +Comment[ca@valencia]=Motor d'informació d'estat de les aplicacions, basat en el protocol notificador d'estat. +Comment[cs]=Stroj pro informace o stavu aplikací, založen na protokolu Status Notifier +Comment[da]=Motor til programmers statusinformation, baseret på protokollen til statusbekendtgørelser. +Comment[de]=Treiber für Anwendungs-Status-Informationen, basierend auf dem Status-Informations-Protokoll. +Comment[el]=Μηχανή για τις πληροφορίες κατάστασης της εφαρμογής, βασισμένη στο πρωτόκολλο ειδοποιήσεων κατάστασης. +Comment[en_GB]=Engine for applications' status information, based on the Status Notifier protocol. +Comment[es]=Motor para informar del estado de aplicaciones, basado en el protocolo Status Notifier. +Comment[et]=Rakenduse olekuteabe mootor Status Notifieri protokolli alusel. +Comment[eu]=Aplikazioen egoerari buruzko informazioa emateko motorra, egoera-jakinarazlearen protokoloan oinarritua. +Comment[fi]=Kone sovelusten tilatiedoille, perustuu tilailmoitinyhteyskäytäntöön. +Comment[fr]=Moteur d'informations sur l'état des applications utilisant le protocole de notification d'état. +Comment[gl]=Motor para información do estado dos programas, baseado no protocolo Status Notifier. +Comment[he]=מנוע עבור מידע אודות מצב של יישומים, המתבסס על הפרוטוקול של Status Notifier. +Comment[hr]=Mehanizam za statusne informacije aplikacija baziran na protokolu glasnika stanja. +Comment[hu]=Az állaporértesítés protokollon alapuló modul az alkalmazások állapotértesítési információihoz. +Comment[ia]=Motor pro information de stato de applicationes basate sur le protocollo de Notificator de Stato +Comment[id]=Mesin untuk informasi status aplikasi, berbasis protokol Notifikasi Status. +Comment[is]=Kerfi fyrir stöðuupplýsingar forrita, byggt á samskiptamáta stöðutilkynninga (Status Notifier protocol). +Comment[it]=Motore per le informazioni di stato delle applicazioni, basato sul protocollo del notificatore di stato. +Comment[ja]=ステータス通知プロトコルに基づくアプリケーションステータス情報エンジン +Comment[kk]=Күй-жайы туралы құлақтандыру (Status Notifier) протоколын негіздеген қолданбаларға арналған тетік. +Comment[km]=ម៉ាស៊ីន​សម្រាប់​ព័ត៌មាន​ស្ថានភាព​របស់​​កម្មវិធី ដែលមាន​មូលដ្ឋាន​លើ​ពិធីការ​កម្មវិធី​ជូនដំណឹង​ស្ថានភាព ។ +Comment[ko]=상태 알림 프로토콜을 사용하는 프로그램 상태 정보 엔진입니다. +Comment[lt]=Programų būsenos informacijos varikliukas, pagrįstas būsenos pranešėjo protokolu. +Comment[lv]=Programmas statusa informācijas dzinējs, kas ir bāzēts uz sistēmas paziņojumu protokolu. +Comment[mr]=अनुप्रयोग स्थिती माहिती साठी स्थिती निदर्शक शिष्टाचारावर आधारित इंजिन +Comment[nb]=Motor for programstatus-informasjon basert på Status Notifier-protokollen. +Comment[nds]=Karn för Programmstatus-Informatschonen, de dat Statusbescheed-Protokoll bruukt. +Comment[nl]=Engine voor statusinformatie van toepassingen gebaseerde op het statusnotificatieprotocol. +Comment[pa]=ਹਾਲਤ ਨੋਟੀਫਾਇਰ ਪਰੋਟੋਕਾਲ ਉੱਤੇ ਅਧਾਰਿਤ ਐਪਲੀਕੇਸ਼ਨ ਹਾਲਤ ਜਾਣਕਾਰੀ ਲਈ ਇੰਜਣ। +Comment[pl]=Silnik do przekazywania informacji o stanie programów, oparty o protokół powiadomień o stanie. +Comment[pt]=Motor para a informação do estado das aplicações, baseado no protocolo do Item de Notificação do Estado. +Comment[pt_BR]=Mecanismo para informação de status de aplicativos baseado no protocolo do Notificador de Status. +Comment[ro]=Motor pentru informațiile de stare ale aplicațiilor, bazat pe protocolul Notificator de Stare. +Comment[ru]=Движок данных о состоянии программ, основанный на протоколе уведомлений о состоянии. +Comment[si]=තත්ව දැනුම්දීම් නියමාවලිය මත පදනම් වූ යෙදුම්වල තත්ව තොරතුරු සඳහා එන්ජිම. +Comment[sk]=Nástroj pre informácie o stave aplikácie, založený na protokole o oznámení stavu. +Comment[sl]=Pogon za podatke o stanju programov, ki temelji na protokolu obvestilnika o stanju. +Comment[sr]=Мотор за податке о стању програма, на основу протокола извештавача о стању. +Comment[sr@ijekavian]=Мотор за податке о стању програма, на основу протокола извјештавача о стању. +Comment[sr@ijekavianlatin]=Motor za podatke o stanju programa, na osnovu protokola izvještavača o stanju. +Comment[sr@latin]=Motor za podatke o stanju programa, na osnovu protokola izveštavača o stanju. +Comment[sv]=Gränssnitt för statusinformation om program baserat på protokollet för statusunderrättelser. +Comment[th]=กลไกสำหรับข้อมูลสถานะแอพลิเคชัน โดยใช้โพรโทคอลตัวแจ้งสถานะ +Comment[tr]=Uygulamaların durum bilgisi için motor +Comment[ug]=ھالەت ئۇقتۇرۇش كېلىشىمى ئاساسىدا، پروگرامما ھالەت ئۇچۇرىغا ئېرىشىشتە ئىشلىتىلىدىغان ماتور. +Comment[uk]=Рушій даних щодо стану програм, заснований на протоколі сповіщення про стан. +Comment[vi]=Cơ chế cho thông tin trạng thái ứng dụng, dựa trên giao thức Trình thông báo trạng thái +Comment[wa]=Moteur po l' informacion so l' estat do programe, båzé sol protocole Status Notifier. +Comment[x-test]=xxEngine for applications' status information, based on the Status Notifier protocol.xx +Comment[zh_CN]=用于提供应用程序状态信息的引擎,急于状态通知协议。 +Comment[zh_TW]=基於狀態通知器協定的應用程式狀態資訊引擎。 +Icon=preferences-desktop-notification + +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +X-KDE-Library=plasma_engine_statusnotifieritem +X-KDE-PluginInfo-Author=Matthieu Gallien +X-KDE-PluginInfo-Email=matthieu_gallien@yahoo.fr +X-KDE-PluginInfo-Name=statusnotifieritem +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem.operations b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem.operations new file mode 100644 index 00000000..4515850c --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem.operations @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem_engine.cpp b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem_engine.cpp new file mode 100644 index 00000000..660f8d62 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritem_engine.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * Copyright (C) 2009 Matthieu Gallien * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "statusnotifieritem_engine.h" +#include "statusnotifieritemsource.h" + +#include +#include +#include + +static const QString s_watcherServiceName("org.kde.StatusNotifierWatcher"); + +StatusNotifierItemEngine::StatusNotifierItemEngine(QObject *parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_statusNotifierWatcher(0) +{ + Q_UNUSED(args); +} + +StatusNotifierItemEngine::~StatusNotifierItemEngine() +{ + QDBusConnection::sessionBus().unregisterService(m_serviceName); +} + +Plasma::Service* StatusNotifierItemEngine::serviceForSource(const QString &name) +{ + StatusNotifierItemSource *source = dynamic_cast(containerForSource(name)); + // if source does not exist, return null service + if (!source) { + return Plasma::DataEngine::serviceForSource(name); + } + + Plasma::Service *service = source->createService(); + service->setParent(this); + return service; +} + +void StatusNotifierItemEngine::init() +{ + if (QDBusConnection::sessionBus().isConnected()) { + m_serviceName = "org.kde.StatusNotifierHost-" + QString::number(QCoreApplication::applicationPid()); + QDBusConnection::sessionBus().registerService(m_serviceName); + + QDBusServiceWatcher *watcher = new QDBusServiceWatcher(s_watcherServiceName, QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForOwnerChange, this); + connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), + this, SLOT(serviceChange(QString,QString,QString))); + + registerWatcher(s_watcherServiceName); + } +} + +void StatusNotifierItemEngine::serviceChange(const QString& name, const QString& oldOwner, const QString& newOwner) +{ + kDebug()<< "Service" << name << "status change, old owner:" << oldOwner << "new:" << newOwner; + + if (newOwner.isEmpty()) { + //unregistered + unregisterWatcher(name); + } else if (oldOwner.isEmpty()) { + //registered + registerWatcher(name); + } +} + +void StatusNotifierItemEngine::registerWatcher(const QString& service) +{ + kDebug()<<"service appeared"<isValid() && + m_statusNotifierWatcher->property("ProtocolVersion").toBool() == s_protocolVersion) { + connect(m_statusNotifierWatcher, SIGNAL(StatusNotifierItemRegistered(QString)), this, SLOT(serviceRegistered(QString))); + connect(m_statusNotifierWatcher, SIGNAL(StatusNotifierItemUnregistered(QString)), this, SLOT(serviceUnregistered(QString))); + + m_statusNotifierWatcher->call(QDBus::NoBlock, "RegisterStatusNotifierHost", m_serviceName); + + QStringList registeredItems = m_statusNotifierWatcher->property("RegisteredStatusNotifierItems").value(); + foreach (const QString &service, registeredItems) { + newItem(service); + } + } else { + delete m_statusNotifierWatcher; + m_statusNotifierWatcher = 0; + kDebug()<<"System tray daemon not reachable"; + } + } +} + +void StatusNotifierItemEngine::unregisterWatcher(const QString& service) +{ + if (service == s_watcherServiceName) { + kDebug()<< s_watcherServiceName << "disappeared"; + + disconnect(m_statusNotifierWatcher, SIGNAL(StatusNotifierItemRegistered(QString)), this, SLOT(serviceRegistered(QString))); + disconnect(m_statusNotifierWatcher, SIGNAL(StatusNotifierItemUnregistered(QString)), this, SLOT(serviceUnregistered(QString))); + + removeAllSources(); + + delete m_statusNotifierWatcher; + m_statusNotifierWatcher = 0; + } +} + +void StatusNotifierItemEngine::serviceRegistered(const QString &service) +{ + kDebug() << "Registering"< * + * Copyright (C) 2009 Matthieu Gallien * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef STATUSNOTIFIERITEM_ENGINE_H +#define STATUSNOTIFIERITEM_ENGINE_H + +#include "statusnotifierwatcher_interface.h" +#include +#include +#include + +// Define our plasma Runner +class StatusNotifierItemEngine : public Plasma::DataEngine { + Q_OBJECT + +public: + // Basic Create/Destroy + StatusNotifierItemEngine( QObject *parent, const QVariantList& args ); + ~StatusNotifierItemEngine(); + Plasma::Service *serviceForSource(const QString &name); +protected: + + virtual void init(); + void newItem(const QString &service); + +protected Q_SLOTS: + void serviceChange(const QString& name, + const QString& oldOwner, + const QString& newOwner); + void registerWatcher(const QString& service); + void unregisterWatcher(const QString& service); + void serviceRegistered(const QString &service); + void serviceUnregistered(const QString &service); + +private: + org::kde::StatusNotifierWatcher *m_statusNotifierWatcher; + QString m_serviceName; + static const int s_protocolVersion = 0; +}; + +#endif diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.cpp b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.cpp new file mode 100644 index 00000000..4b844355 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Alain Boyer + * Copyright (C) 2009 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "statusnotifieritemjob.h" +#include + +StatusNotifierItemJob::StatusNotifierItemJob(StatusNotifierItemSource *source, const QString &operation, QMap ¶meters, QObject *parent) : + ServiceJob(source->objectName(), operation, parameters, parent), + m_source(source) +{ + connect(source, SIGNAL(contextMenuReady(QMenu*)), this, SLOT(contextMenuReady(QMenu*))); +} + +StatusNotifierItemJob::~StatusNotifierItemJob() +{ +} + +void StatusNotifierItemJob::start() +{ + if (operationName() == QString::fromLatin1("Activate")) { + m_source->activate(parameters()["x"].toInt(), parameters()["y"].toInt()); + setResult(0); + } else if (operationName() == QString::fromLatin1("SecondaryActivate")) { + m_source->secondaryActivate(parameters()["x"].toInt(), parameters()["y"].toInt()); + setResult(0); + } else if (operationName() == QString::fromLatin1("ContextMenu")) { + m_source->contextMenu(parameters()["x"].toInt(), parameters()["y"].toInt()); + } else if (operationName() == QString::fromLatin1("Scroll")) { + m_source->scroll(parameters()["delta"].toInt(), parameters()["direction"].toString()); + setResult(0); + } +} + +void StatusNotifierItemJob::contextMenuReady(QMenu *menu) +{ + if (operationName() == QString::fromLatin1("ContextMenu")) { + setResult(qVariantFromValue((QObject*)menu)); + } +} + +#include "statusnotifieritemjob.moc" diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.h b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.h new file mode 100644 index 00000000..5bd6b610 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemjob.h @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Alain Boyer + * Copyright (C) 2009 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef STATUSNOTIFIERITEMJOB_H +#define STATUSNOTIFIERITEMJOB_H + +// own +#include "statusnotifieritemsource.h" + +// plasma +#include + +/** + * Task Job + */ +class StatusNotifierItemJob : public Plasma::ServiceJob +{ + Q_OBJECT + +public: + StatusNotifierItemJob(StatusNotifierItemSource *source, const QString &operation, QMap ¶meters, QObject *parent = NULL); + ~StatusNotifierItemJob(); + +protected: + void start(); + +private Q_SLOTS: + void contextMenuReady(QMenu *menu); + +private: + StatusNotifierItemSource *m_source; + +}; + +#endif // STATUSNOTIFIERITEMJOB_H diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.cpp b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.cpp new file mode 100644 index 00000000..1db9437d --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Alain Boyer + * Copyright (C) 2009 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "statusnotifieritemservice.h" + +// own +#include "statusnotifieritemjob.h" + +StatusNotifierItemService::StatusNotifierItemService(StatusNotifierItemSource *source) : + Plasma::Service(source), + m_source(source) +{ + setName("statusnotifieritem"); +} + +StatusNotifierItemService::~StatusNotifierItemService() +{ +} + +Plasma::ServiceJob* StatusNotifierItemService::createJob(const QString &operation, QMap ¶meters) +{ + return new StatusNotifierItemJob(m_source, operation, parameters, this); +} + +#include "statusnotifieritemservice.moc" diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.h b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.h new file mode 100644 index 00000000..c7dcd5a7 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemservice.h @@ -0,0 +1,49 @@ +/* + * Copyright 2008 Alain Boyer + * Copyright (C) 2009 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef STATUSNOTIFIERITEMSERVICE_H +#define STATUSNOTIFIERITEMSERVICE_H + +// own +#include "statusnotifieritemsource.h" + +// plasma +#include +#include + +/** + * StatusNotifierItem Service + */ +class StatusNotifierItemService : public Plasma::Service +{ + + Q_OBJECT + + public: + StatusNotifierItemService(StatusNotifierItemSource *source); + ~StatusNotifierItemService(); + + protected: + Plasma::ServiceJob *createJob(const QString &operation, QMap ¶meters); + + private: + StatusNotifierItemSource *m_source; +}; + +#endif // STATUSNOTIFIERITEMSERVICE_H diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp new file mode 100644 index 00000000..8baec40f --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.cpp @@ -0,0 +1,485 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * Copyright (C) 2009 Matthieu Gallien * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "statusnotifieritemsource.h" +#include "systemtraytypes.h" +#include "statusnotifieritemservice.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#ifndef DBUSMENUQT_VERSION +// DBUSMENUQT_VERSION was introduced in DBusMenuQt 0.4.0 +#define DBUSMENUQT_VERSION 0x000305 +#endif + +class PlasmaDBusMenuImporter : public DBusMenuImporter +{ +public: + PlasmaDBusMenuImporter(const QString &service, const QString &path, KIconLoader *iconLoader, QObject *parent) + : DBusMenuImporter(service, path, parent) + , m_iconLoader(iconLoader) + {} + +protected: + virtual QIcon iconForName(const QString &name) + { + return KIcon(name, m_iconLoader); + } + +private: + KIconLoader *m_iconLoader; +}; + +StatusNotifierItemSource::StatusNotifierItemSource(const QString ¬ifierItemId, QObject *parent) + : Plasma::DataContainer(parent), + m_customIconLoader(0), + m_menuImporter(0), + m_refreshing(false), + m_needsReRefreshing(false), + m_titleUpdate(true), + m_iconUpdate(true), + m_tooltipUpdate(true), + m_statusUpdate(true) +{ + setObjectName(notifierItemId); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + + m_typeId = notifierItemId; + m_name = notifierItemId; + + int slash = notifierItemId.indexOf('/'); + if (slash == -1) { + kError() << "Invalid notifierItemId:" << notifierItemId; + m_valid = false; + m_statusNotifierItemInterface = 0; + return; + } + QString service = notifierItemId.left(slash); + QString path = notifierItemId.mid(slash); + + m_statusNotifierItemInterface = new org::kde::StatusNotifierItem(service, path, + QDBusConnection::sessionBus(), this); + + m_refreshTimer.setSingleShot(true); + m_refreshTimer.setInterval(10); + connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(performRefresh())); + + m_valid = !service.isEmpty() && m_statusNotifierItemInterface->isValid(); + if (m_valid) { + connect(m_statusNotifierItemInterface, SIGNAL(NewTitle()), this, SLOT(refreshTitle())); + connect(m_statusNotifierItemInterface, SIGNAL(NewIcon()), this, SLOT(refreshIcons())); + connect(m_statusNotifierItemInterface, SIGNAL(NewAttentionIcon()), this, SLOT(refreshIcons())); + connect(m_statusNotifierItemInterface, SIGNAL(NewOverlayIcon()), this, SLOT(refreshIcons())); + connect(m_statusNotifierItemInterface, SIGNAL(NewToolTip()), this, SLOT(refreshToolTip())); + connect(m_statusNotifierItemInterface, SIGNAL(NewStatus(QString)), this, SLOT(syncStatus(QString))); + refresh(); + } +} + +StatusNotifierItemSource::~StatusNotifierItemSource() +{ + delete m_statusNotifierItemInterface; +} + +KIconLoader *StatusNotifierItemSource::iconLoader() const +{ + return m_customIconLoader ? m_customIconLoader : KIconLoader::global(); +} + +Plasma::Service *StatusNotifierItemSource::createService() +{ + return new StatusNotifierItemService(this); +} + +void StatusNotifierItemSource::syncStatus(QString status) +{ + setData("TitleChanged", false); + setData("IconsChanged", false); + setData("TooltipChanged", false); + setData("StatusChanged", true); + setData("Status", status); + checkForUpdate(); +} + +void StatusNotifierItemSource::refreshTitle() +{ + m_titleUpdate = true; + refresh(); +} + +void StatusNotifierItemSource::refreshIcons() +{ + m_iconUpdate = true; + refresh(); +} + +void StatusNotifierItemSource::refreshToolTip() +{ + m_tooltipUpdate = true; + refresh(); +} + +void StatusNotifierItemSource::refresh() +{ + if (!m_refreshTimer.isActive()) { + m_refreshTimer.start(); + } +} + +void StatusNotifierItemSource::performRefresh() +{ + if (m_refreshing) { + m_needsReRefreshing = true; + return; + } + + m_refreshing = true; + QDBusMessage message = QDBusMessage::createMethodCall(m_statusNotifierItemInterface->service(), + m_statusNotifierItemInterface->path(), "org.freedesktop.DBus.Properties", "GetAll"); + + message << m_statusNotifierItemInterface->interface(); + QDBusPendingCall call = m_statusNotifierItemInterface->connection().asyncCall(message); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(refreshCallback(QDBusPendingCallWatcher*))); +} + +/** + \todo add a smart pointer to guard call and to automatically delete it at the end of the function + */ +void StatusNotifierItemSource::refreshCallback(QDBusPendingCallWatcher *call) +{ + m_refreshing = false; + if (m_needsReRefreshing) { + m_needsReRefreshing = false; + performRefresh(); + call->deleteLater(); + return; + } + + QDBusPendingReply reply = *call; + if (reply.isError()) { + m_valid = false; + } else { + // record what has changed + setData("TitleChanged", m_titleUpdate); + m_titleUpdate = false; + setData("IconsChanged", m_iconUpdate); + m_iconUpdate = false; + setData("ToolTipChanged", m_tooltipUpdate); + m_tooltipUpdate = false; + setData("StatusChanged", m_statusUpdate); + m_statusUpdate = false; + + //IconThemePath (handle this one first, because it has an impact on + //others) + QVariantMap properties = reply.argumentAt<0>(); + if (!m_customIconLoader) { + QString path = properties["IconThemePath"].toString(); + if (!path.isEmpty()) { + // FIXME: If last part of path is not "icons", this won't work! + QStringList tokens = path.split('/', QString::SkipEmptyParts); + if (tokens.length() >= 3 && tokens.takeLast() == "icons") { + QString appName = tokens.takeLast(); + QString prefix = '/' + tokens.join("/"); + // FIXME: Fix KIconLoader and KIconTheme so that we can use + // our own instance of KStandardDirs + KGlobal::dirs()->addResourceDir("data", prefix); + // We use a separate instance of KIconLoader to avoid + // adding all application dirs to KIconLoader::global(), to + // avoid potential icon name clashes between application + // icons + m_customIconLoader = new KIconLoader(appName, 0 /* dirs */, this); + } else { + kWarning() << "Wrong IconThemePath" << path << ": too short or does not end with 'icons'"; + } + } + } + setData("IconThemePath", properties["IconThemePath"]); + + setData("Category", properties["Category"]); + setData("Status", properties["Status"]); + setData("Title", properties["Title"]); + setData("Id", properties["Id"]); + setData("WindowId", properties["WindowId"]); + setData("ItemIsMenu", properties["ItemIsMenu"]); + + //Attention Movie + setData("AttentionMovieName", properties["AttentionMovieName"]); + + QIcon overlay; + QStringList overlayNames; + + //Icon + { + KDbusImageVector image; + QIcon icon; + QString iconName; + + properties["OverlayIconPixmap"].value() >> image; + if (image.isEmpty()) { + QString iconName = properties["OverlayIconName"].toString(); + setData("OverlayIconName", iconName); + if (!iconName.isEmpty()) { + overlayNames << iconName; + overlay = KIcon(iconName, iconLoader()); + } + } else { + overlay = imageVectorToPixmap(image); + } + + properties["IconPixmap"].value() >> image; + if (image.isEmpty()) { + iconName = properties["IconName"].toString(); + if (!iconName.isEmpty()) { + icon = KIcon(iconName, iconLoader(), overlayNames); + + if (overlayNames.isEmpty() && !overlay.isNull()) { + overlayIcon(&icon, &overlay); + } + } + } else { + icon = imageVectorToPixmap(image); + if (!icon.isNull() && !overlay.isNull()) { + overlayIcon(&icon, &overlay); + } + } + setData("Icon", icon); + setData("IconName", iconName); + } + + //Attention icon + { + KDbusImageVector image; + QIcon attentionIcon; + + properties["AttentionIconPixmap"].value() >> image; + if (image.isEmpty()) { + QString iconName = properties["AttentionIconName"].toString(); + setData("AttentionIconName", iconName); + if (!iconName.isEmpty()) { + attentionIcon = KIcon(iconName, iconLoader(), overlayNames); + + if (overlayNames.isEmpty() && !overlay.isNull()) { + overlayIcon(&attentionIcon, &overlay); + } + } + } else { + attentionIcon = imageVectorToPixmap(image); + if (!attentionIcon.isNull() && !overlay.isNull()) { + overlayIcon(&attentionIcon, &overlay); + } + } + setData("AttentionIcon", attentionIcon); + } + + //ToolTip + { + KDbusToolTipStruct toolTip; + properties["ToolTip"].value() >> toolTip; + if (toolTip.title.isEmpty()) { + setData("ToolTipTitle", QVariant()); + setData("ToolTipSubTitle", QVariant()); + setData("ToolTipIcon", QVariant()); + } else { + QIcon toolTipIcon; + if (toolTip.image.size() == 0) { + toolTipIcon = KIcon(toolTip.icon, iconLoader()); + } else { + toolTipIcon = imageVectorToPixmap(toolTip.image); + } + setData("ToolTipTitle", toolTip.title); + setData("ToolTipSubTitle", toolTip.subTitle); + setData("ToolTipIcon", toolTipIcon); + } + } + + //Menu + if (!m_menuImporter) { + QString menuObjectPath = properties["Menu"].value().path(); + if (!menuObjectPath.isEmpty()) { + if (menuObjectPath == "/NO_DBUSMENU") { + // This is a hack to make it possible to disable DBusMenu in an + // application. The string "/NO_DBUSMENU" must be the same as in + // KStatusNotifierItem::setContextMenu(). + kWarning() << "DBusMenu disabled for this application"; + } else { + m_menuImporter = new PlasmaDBusMenuImporter(m_statusNotifierItemInterface->service(), menuObjectPath, iconLoader(), this); +#if DBUSMENUQT_VERSION >= 0x000400 + connect(m_menuImporter, SIGNAL(menuUpdated()), this, SLOT(contextMenuReady())); +#endif + } + } + } + } + + checkForUpdate(); + call->deleteLater(); +} + +void StatusNotifierItemSource::contextMenuReady() +{ +#if DBUSMENUQT_VERSION < 0x000400 + // Work around to avoid infinite recursion because menuReadyToBeShown() is emitted + // by DBusMenuImporter at the end of its slot connected to aboutToShow() + // (dbusmenu-qt 0.3.5) + disconnect(m_menuImporter, SIGNAL(menuReadyToBeShown()), this, SLOT(contextMenuReady())); +#endif + emit contextMenuReady(m_menuImporter->menu()); +} + +QPixmap StatusNotifierItemSource::KDbusImageStructToPixmap(const KDbusImageStruct &image) const +{ + //swap from network byte order if we are little endian + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + uint *uintBuf = (uint *) image.data.data(); + for (uint i = 0; i < image.data.size()/sizeof(uint); ++i) { + *uintBuf = ntohl(*uintBuf); + ++uintBuf; + } + } + QImage iconImage(image.width, image.height, QImage::Format_ARGB32 ); + memcpy(iconImage.bits(), (uchar*)image.data.data(), iconImage.numBytes()); + + return QPixmap::fromImage(iconImage); +} + +QIcon StatusNotifierItemSource::imageVectorToPixmap(const KDbusImageVector &vector) const +{ + QIcon icon; + + for (int i = 0; ipixmap(KIconLoader::SizeSmall, KIconLoader::SizeSmall); + + QPainter p(&m_iconPixmap); + + const int size = KIconLoader::SizeSmall/2; + p.drawPixmap(QRect(size, size, size, size), overlay->pixmap(size, size), QRect(0,0,size,size)); + p.end(); + tmp.addPixmap(m_iconPixmap); + + //if an m_icon exactly that size wasn't found don't add it to the vector + m_iconPixmap = icon->pixmap(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium); + if (m_iconPixmap.width() == KIconLoader::SizeSmallMedium) { + const int size = KIconLoader::SizeSmall/2; + QPainter p(&m_iconPixmap); + p.drawPixmap(QRect(m_iconPixmap.width()-size, m_iconPixmap.height()-size, size, size), overlay->pixmap(size, size), QRect(0,0,size,size)); + p.end(); + tmp.addPixmap(m_iconPixmap); + } + + m_iconPixmap = icon->pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium); + if (m_iconPixmap.width() == KIconLoader::SizeMedium) { + const int size = KIconLoader::SizeSmall/2; + QPainter p(&m_iconPixmap); + p.drawPixmap(QRect(m_iconPixmap.width()-size, m_iconPixmap.height()-size, size, size), overlay->pixmap(size, size), QRect(0,0,size,size)); + p.end(); + tmp.addPixmap(m_iconPixmap); + } + + m_iconPixmap = icon->pixmap(KIconLoader::SizeLarge, KIconLoader::SizeLarge); + if (m_iconPixmap.width() == KIconLoader::SizeLarge) { + const int size = KIconLoader::SizeSmall; + QPainter p(&m_iconPixmap); + p.drawPixmap(QRect(m_iconPixmap.width()-size, m_iconPixmap.height()-size, size, size), overlay->pixmap(size, size), QRect(0,0,size,size)); + p.end(); + tmp.addPixmap(m_iconPixmap); + } + + // We can't do 'm_icon->addPixmap()' because if 'm_icon' uses KIconEngine, + // it will ignore the added pixmaps. This is not a bug in KIconEngine, + // QIcon::addPixmap() doc says: "Custom m_icon engines are free to ignore + // additionally added pixmaps". + *icon = tmp; + //hopefully huge and enormous not necessary right now, since it's quite costly +} + +void StatusNotifierItemSource::activate(int x, int y) +{ + if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) { + m_statusNotifierItemInterface->call(QDBus::NoBlock, "Activate", x, y); + } +} + +void StatusNotifierItemSource::secondaryActivate(int x, int y) +{ + if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) { + m_statusNotifierItemInterface->call(QDBus::NoBlock, "SecondaryActivate", x, y); + } +} + +void StatusNotifierItemSource::scroll(int delta, const QString &direction) +{ + if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) { + m_statusNotifierItemInterface->call(QDBus::NoBlock, "Scroll", delta, direction); + } +} + +void StatusNotifierItemSource::contextMenu(int x, int y) +{ + if (m_menuImporter) { + #if DBUSMENUQT_VERSION >= 0x000400 + m_menuImporter->updateMenu(); + #else + QMenu *menu = m_menuImporter->menu(); + // Simulate an "aboutToShow" so that menu->sizeHint() is correct. Otherwise + // the menu may show up over the applet if new actions are added on the + // fly. + connect(m_menuImporter, SIGNAL(menuReadyToBeShown()), this, SLOT(contextMenuReady())); + QMetaObject::invokeMethod(menu, "aboutToShow"); + #endif + } else { + kWarning() << "Could not find DBusMenu interface, falling back to calling ContextMenu()"; + if (m_statusNotifierItemInterface && m_statusNotifierItemInterface->isValid()) { + m_statusNotifierItemInterface->call(QDBus::NoBlock, "ContextMenu", x, y); + } + } +} + +#include "statusnotifieritemsource.moc" diff --git a/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.h b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.h new file mode 100644 index 00000000..c60fb321 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/statusnotifieritemsource.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * Copyright (C) 2009 Matthieu Gallien * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef STATUSNOTIFIERITEMSOURCE_H +#define STATUSNOTIFIERITEMSOURCE_H + +#include +#include +#include + +#include "statusnotifieritem_interface.h" + +class KIconLoader; + +class DBusMenuImporter; + +class StatusNotifierItemSource : public Plasma::DataContainer +{ + + Q_OBJECT + +public: + StatusNotifierItemSource(const QString &service, QObject *parent); + ~StatusNotifierItemSource(); + Plasma::Service *createService(); + + void activate(int x, int y); + void secondaryActivate(int x, int y); + void scroll(int delta, const QString &direction); + void contextMenu(int x, int y); + +Q_SIGNALS: + void contextMenuReady(QMenu *menu); + +private slots: + void contextMenuReady(); + void refreshTitle(); + void refreshIcons(); + void refreshToolTip(); + void refresh(); + void performRefresh(); + void syncStatus(QString); + void refreshCallback(QDBusPendingCallWatcher *); + +private: + + QPixmap KDbusImageStructToPixmap(const KDbusImageStruct &image) const; + QIcon imageVectorToPixmap(const KDbusImageVector &vector) const; + void overlayIcon(QIcon *icon, QIcon *overlay); + KIconLoader *iconLoader() const; + + bool m_valid; + QString m_typeId; + QString m_name; + QTimer m_refreshTimer; + KIconLoader *m_customIconLoader; + DBusMenuImporter *m_menuImporter; + org::kde::StatusNotifierItem *m_statusNotifierItemInterface; + bool m_refreshing : 1; + bool m_needsReRefreshing : 1; + bool m_titleUpdate : 1; + bool m_iconUpdate : 1; + bool m_tooltipUpdate : 1; + bool m_statusUpdate : 1; +}; + +#endif // STATUSNOTIFIERITEMSOURCE_H diff --git a/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.cpp b/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.cpp new file mode 100644 index 00000000..dab7f949 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "systemtraytypes.h" + + +// Marshall the ImageStruct data into a D-BUS argument +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusImageStruct &icon) +{ + argument.beginStructure(); + argument << icon.width; + argument << icon.height; + argument << icon.data; + argument.endStructure(); + return argument; +} +#include + +// Retrieve the ImageStruct data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, KDbusImageStruct &icon) +{ + qint32 width = 0; + qint32 height = 0; + QByteArray data; + + if (argument.currentType() == QDBusArgument::StructureType) { + argument.beginStructure(); + //kDebug() << "begun structure"; + argument >> width; + //kDebug() << width; + argument >> height; + //kDebug() << height; + argument >> data; + //kDebug() << data.size(); + argument.endStructure(); + } + + icon.width = width; + icon.height = height; + icon.data = data; + + return argument; +} + +// Marshall the ImageVector data into a D-BUS argument +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusImageVector &iconVector) +{ + argument.beginArray(qMetaTypeId()); + for (int i=0; i>(const QDBusArgument &argument, KDbusImageVector &iconVector) +{ + iconVector.clear(); + + if (argument.currentType() == QDBusArgument::ArrayType) { + argument.beginArray(); + + while (!argument.atEnd()) { + KDbusImageStruct element; + argument >> element; + iconVector.append(element); + } + + argument.endArray(); + } + + return argument; +} + +// Marshall the ToolTipStruct data into a D-BUS argument +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusToolTipStruct &toolTip) +{ + argument.beginStructure(); + argument << toolTip.icon; + argument << toolTip.image; + argument << toolTip.title; + argument << toolTip.subTitle; + argument.endStructure(); + + return argument; +} + +// Retrieve the ToolTipStruct data from the D-BUS argument +const QDBusArgument &operator>>(const QDBusArgument &argument, KDbusToolTipStruct &toolTip) +{ + QString icon; + KDbusImageVector image; + QString title; + QString subTitle; + + if (argument.currentType() == QDBusArgument::StructureType) { + argument.beginStructure(); + argument >> icon; + argument >> image; + argument >> title; + argument >> subTitle; + argument.endStructure(); + } + + toolTip.icon = icon; + toolTip.image = image; + toolTip.title = title; + toolTip.subTitle = subTitle; + + return argument; +} diff --git a/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.h b/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.h new file mode 100644 index 00000000..95a77257 --- /dev/null +++ b/plasma/generic/dataengines/statusnotifieritem/systemtraytypes.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYTYPES_H +#define SYSTEMTRAYTYPES_H + +#include + +#include "systemtraytypedefs.h" + +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusImageStruct &icon); +const QDBusArgument &operator>>(const QDBusArgument &argument, KDbusImageStruct &icon); + + +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusImageVector &iconVector); +const QDBusArgument &operator>>(const QDBusArgument &argument, KDbusImageVector &iconVector); + +const QDBusArgument &operator<<(QDBusArgument &argument, const KDbusToolTipStruct &toolTip); +const QDBusArgument &operator>>(const QDBusArgument &argument, KDbusToolTipStruct &toolTip); + + +#endif diff --git a/plasma/generic/dataengines/systemmonitor/CMakeLists.txt b/plasma/generic/dataengines/systemmonitor/CMakeLists.txt new file mode 100644 index 00000000..b9bf5569 --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/CMakeLists.txt @@ -0,0 +1,14 @@ + +set(systemmonitor_engine_SRCS + systemmonitor.cpp +) + +kde4_add_plugin(plasma_engine_systemmonitor ${systemmonitor_engine_SRCS}) +target_link_libraries(plasma_engine_systemmonitor ${KDE4_PLASMA_LIBS} ${KDE4_KDECORE_LIBS} ${QT_QTNETWORK_LIBRARY} ksgrd) + +install(TARGETS plasma_engine_systemmonitor DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-systemmonitor.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + + + diff --git a/plasma/generic/dataengines/systemmonitor/Messages.sh b/plasma/generic/dataengines/systemmonitor/Messages.sh new file mode 100755 index 00000000..73d19d81 --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_engine_systemmonitor.pot diff --git a/plasma/generic/dataengines/systemmonitor/plasma-dataengine-systemmonitor.desktop b/plasma/generic/dataengines/systemmonitor/plasma-dataengine-systemmonitor.desktop new file mode 100644 index 00000000..89548707 --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/plasma-dataengine-systemmonitor.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=System Monitor +Name[af]=Stelsel Monitor +Name[ar]=مراقب النظام +Name[ast]=Monitor del sistema +Name[be]=Сістэмны назіральнік +Name[be@latin]=Systemny nazirańnik +Name[bg]=Наблюдение на системата +Name[bn]=সিস্টেম মনিটর +Name[bn_IN]=সিস্টেম নিরীক্ষণ ব্যবস্থা +Name[bs]=Monitor sistema +Name[ca]=Monitor del sistema +Name[ca@valencia]=Monitor del sistema +Name[cs]=Monitor systému +Name[csb]=Mònitór systemë +Name[da]=Systemovervågning +Name[de]=Systemmonitor +Name[el]=Επόπτης συστήματος +Name[en_GB]=System Monitor +Name[eo]=Sistemstato-programo +Name[es]=Monitor del sistema +Name[et]=Süsteemi jälgija +Name[eu]=Sistema-monitorea +Name[fa]=نمایشگر سیستم +Name[fi]=Järjestelmän valvonta +Name[fr]=Surveillance du système +Name[fy]=Systeemmonitor +Name[ga]=Monatóir an Chórais +Name[gl]=Vixilante do sistema +Name[gu]=સિસ્ટમ દેખરેખ +Name[he]=מוניטור המערכת +Name[hi]=तंत्र मॉनीटर +Name[hne]=तंत्र मानीटर +Name[hr]=Nadzor sustava +Name[hsb]=Systemowy monitor +Name[hu]=Rendszermonitor +Name[ia]=Monitor de systema +Name[id]=Monitor Sistem +Name[is]=Kerfiseftirlit +Name[it]=Monitor di sistema +Name[ja]=システムモニタ +Name[kk]=Жүйе мониторы +Name[km]=កម្មវិធី​ត្រួត​​ពិនិត្យ​ប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥೆಯ ಪ್ರದರ್ಶಕ +Name[ko]=시스템 모니터 +Name[ku]=Temaşekerê Pergalê +Name[lt]=Sistemos stebėtojas +Name[lv]=Sistēmas monitors +Name[mai]=सिस्टम मानीटर +Name[mk]=Системски монитор +Name[ml]=സിസ്റ്റം നിരീക്ഷകന്‍ +Name[mr]=प्रणाली मॉनिटर +Name[nb]=Systemovervåker +Name[nds]=Systeemkieker +Name[ne]=प्रणाली मनिटर +Name[nl]=Systeemmonitor +Name[nn]=Systemovervaking +Name[oc]=Monitor sistèma +Name[pa]=ਸਿਸਟਮ ਮਾਨੀਟਰ +Name[pl]=Monitor systemu +Name[pt]=Monitor do Sistema +Name[pt_BR]=Monitor do sistema +Name[ro]=Monitor de sistem +Name[ru]=Системный монитор +Name[se]=Vuogádatgoziheaddji +Name[si]=පද්ධති නිරීක්‍ෂකය +Name[sk]=Monitor systému +Name[sl]=Sistemski nadzornik +Name[sr]=надзорник система +Name[sr@ijekavian]=надзорник система +Name[sr@ijekavianlatin]=nadzornik sistema +Name[sr@latin]=nadzornik sistema +Name[sv]=Systemövervakare +Name[ta]=கணினி நோட்டம் +Name[te]=సిస్టమ్ మానిటర్ +Name[tg]=Назорати система +Name[th]=ติดตามการทำงานของระบบ +Name[tr]=Sistem İzleyici +Name[ug]=سىستېما كۆزەتكۈچ +Name[uk]=Монітор системи +Name[vi]=Bộ theo dõi hệ thống +Name[wa]=Corwaitoe do sistinme +Name[x-test]=xxSystem Monitorxx +Name[zh_CN]=系统监视器 +Name[zh_TW]=系統監視器 +Comment=System status information +Comment[ar]=معلومات حالة النظام +Comment[ast]=Información d'estáu del sistema +Comment[bg]=Данни за състоянието на системата +Comment[bn]=সিস্টেম স্ট্যাটাস তথ্য +Comment[bs]=Podaci o stanju sistema +Comment[ca]=Informació de l'estat del sistema +Comment[ca@valencia]=Informació de l'estat del sistema +Comment[cs]=Informace o stavu systému +Comment[csb]=Wëdowiédzô ò stónie systemë +Comment[da]=Information om systemstatus +Comment[de]=Systemstatus-Informationen +Comment[el]=Πληροφορίες κατάστασης συστήματος +Comment[en_GB]=System status information +Comment[eo]=Sistemstataj informoj +Comment[es]=Información de estado del sistema +Comment[et]=Süsteemi oleku teave +Comment[eu]=Sistemaren egoerari buruzko informazioa +Comment[fi]=Järjestelmätilatiedot +Comment[fr]=Informations sur l'état du système +Comment[fy]=Systeemtastân ynformaasje +Comment[ga]=Eolas faoi stádas an chórais +Comment[gl]=Información do estado do sistema +Comment[gu]=સિસ્ટમ સ્થિતિ માહિતી +Comment[he]=מידע אודות מצב המערכת +Comment[hi]=तंत्र स्थिति जानकारी +Comment[hr]=Podaci o stanju sustava +Comment[hu]=Rendszerjellemzők +Comment[ia]=Information de stato de systema +Comment[id]=Informasi status sistem +Comment[is]=Upplýsingar um kerfisforrit +Comment[it]=Informazioni sullo stato del sistema +Comment[ja]=システムのステータス情報 +Comment[kk]=Жүйе күй-жайы туралы мәлімет +Comment[km]=ព័ត៌មាន​ស្ថានភាព​របស់​ប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥೆಯ ಸ್ಥಿತಿಯ ಮಾಹಿತಿ +Comment[ko]=시스템 상태 정보 +Comment[lt]=Sistemos būklės informacija +Comment[lv]=Sistēmas statusa informācija +Comment[mk]=Информации за статусот на системот +Comment[ml]=സിസ്റ്റത്തിന്റെ അവസ്ഥാ വിവരം +Comment[mr]=प्रणाली स्थिती माहिती +Comment[nb]=Informasjon om systemstatus +Comment[nds]=Systeemstatus-Informatschonen +Comment[nl]=Informatie over systeemstatus +Comment[nn]=Informasjon om systemstatus +Comment[pa]=ਸਿਸਟਮ ਹਾਲਤ ਜਾਣਕਾਰੀ +Comment[pl]=Informacje o stanie systemu +Comment[pt]=Informações do estado do sistema +Comment[pt_BR]=Informação do status do sistema +Comment[ro]=Informații despre starea sistemului +Comment[ru]=Сведения о системе +Comment[si]=පද්ධති තත්ව තොරතුරු +Comment[sk]=Informácie o stave systému +Comment[sl]=Podatki o stanju sistema +Comment[sr]=Подаци о стању система +Comment[sr@ijekavian]=Подаци о стању система +Comment[sr@ijekavianlatin]=Podaci o stanju sistema +Comment[sr@latin]=Podaci o stanju sistema +Comment[sv]=Information om systemstatus +Comment[tg]=Барномаи маълумоти система +Comment[th]=ข้อมูลสถานะของระบบ +Comment[tr]=Sistem durumu bilgileri +Comment[ug]=سىستېما ھالەت ئۇچۇرى +Comment[uk]=Інформація про стан системи +Comment[wa]=Informåcion so l' estat do sistinme +Comment[x-test]=xxSystem status informationxx +Comment[zh_CN]=系统状态信息 +Comment[zh_TW]=系統狀態資訊 +ServiceTypes=Plasma/DataEngine +Icon=utilities-system-monitor +Type=Service +X-KDE-Library=plasma_engine_systemmonitor + +X-KDE-PluginInfo-Author= +X-KDE-PluginInfo-Email= +X-KDE-PluginInfo-Name=systemmonitor +X-KDE-PluginInfo-Version= +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category= diff --git a/plasma/generic/dataengines/systemmonitor/sensorclient.h b/plasma/generic/dataengines/systemmonitor/sensorclient.h new file mode 100644 index 00000000..074f59c2 --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/sensorclient.h @@ -0,0 +1,192 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000 Chris Schlaeger + Copyright (c) 2006 John Tapsell + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef KSG_SENSORCLIENT_H +#define KSG_SENSORCLIENT_H + +#include +#include +#include + +namespace KSGRD { + +/** + Every object that should act as a client to a sensor must inherit from + this class. A pointer to the client object is passed as SensorClient* + to the SensorAgent. When the requested information is available or a + problem occurred one of the member functions is called. + */ +class SensorClient +{ + public: + explicit SensorClient() { } + virtual ~SensorClient() { } + + /** + This function is called whenever the information from the sensor has + been received by the sensor agent. This function must be reimplemented + by the sensor client to receive and process this information. + */ + virtual void answerReceived( const QString &, const QList& ) { } + + /** + In case of an unexpected fatal problem with the sensor the sensor + agent will call this function to notify the client about it. + */ + virtual void sensorLost( const QString &) { } +}; + +/** + The following classes are utility classes that provide a + convenient way to retrieve pieces of information from the sensor + answers. For each type of answer there is a separate class. + */ +class SensorTokenizer +{ + public: + SensorTokenizer( const QByteArray &info, char separator ) + { + if ( separator == '/' ) { + //This is a special case where we assume that info is a '\' escaped string + + int i=0; + int lastTokenAt = -1; + + for( ; i < info.length(); ++i ) { + if( info[i] == '\\' ) { + ++i; + } + else if ( info[i] == separator ) { + m_tokens.append( unEscapeString( info.mid( lastTokenAt + 1, i - lastTokenAt - 1 ) ) ); + lastTokenAt = i; + } + } + + //Add everything after the last token + m_tokens.append( unEscapeString( info.mid( lastTokenAt + 1, i - lastTokenAt - 1 ) ) ); + } + else { + m_tokens = info.split( separator ); + } + } + + ~SensorTokenizer() { } + + const QByteArray& operator[]( unsigned idx ) + { + Q_ASSERT(idx < (unsigned)(m_tokens.count())); + return m_tokens[ idx ]; + } + + uint count() + { + return m_tokens.count(); + } + + private: + QList m_tokens; + + QByteArray unEscapeString( QByteArray string ) { + + int i=0; + for( ; i < string.length(); ++i ) { + if( string[i] == '\\' ) { + string.remove( i, 1 ); + ++i; + } + } + + return string; + } +}; + +/** + An integer info contains 4 fields separated by TABS, a description + (name), the minimum and the maximum values and the unit. + e.g. Swap Memory 0 133885952 KB + */ +class SensorIntegerInfo : public SensorTokenizer +{ + public: + explicit SensorIntegerInfo( const QByteArray &info ) + : SensorTokenizer( info, '\t' ) { } + + ~SensorIntegerInfo() { } + + QString name() + { + return QString::fromUtf8((*this)[ 0 ]); + } + + long min() + { + return (*this)[ 1 ].toLong(); + } + + long max() + { + return (*this)[ 2 ].toLong(); + } + + QString unit() + { + return QString::fromUtf8((*this)[ 3 ]); + } +}; + +/** + An float info contains 4 fields separated by TABS, a description + (name), the minimum and the maximum values and the unit. + e.g. CPU Voltage 0.0 5.0 V + */ +class SensorFloatInfo : public SensorTokenizer +{ + public: + explicit SensorFloatInfo( const QByteArray &info ) + : SensorTokenizer( info, '\t' ) { } + + ~SensorFloatInfo() { } + + QString name() + { + return QString::fromUtf8((*this)[ 0 ]); + } + + double min() + { + return (*this)[ 1 ].toDouble(); + } + + double max() + { + return (*this)[ 2 ].toDouble(); + } + + QString unit() + { + return QString::fromUtf8((*this)[ 3 ]); + } +}; + + +} + +#endif diff --git a/plasma/generic/dataengines/systemmonitor/systemmonitor.cpp b/plasma/generic/dataengines/systemmonitor/systemmonitor.cpp new file mode 100644 index 00000000..81a8e67d --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/systemmonitor.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2007 John Tapsell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "systemmonitor.h" + +#include +#include + +#include +#include + +#include + +#include "ksysguard/ksgrd/SensorManager.h" + +SystemMonitorEngine::SystemMonitorEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent) +{ + Q_UNUSED(args) + + KSGRD::SensorMgr = new KSGRD::SensorManager(this); + KSGRD::SensorMgr->engage("localhost", "", "ksysguardd"); + + m_waitingFor= 0; + connect(KSGRD::SensorMgr, SIGNAL(update()), this, SLOT(updateMonitorsList())); + updateMonitorsList(); +} + +SystemMonitorEngine::~SystemMonitorEngine() +{ +} + +void SystemMonitorEngine::updateMonitorsList() +{ + KSGRD::SensorMgr->sendRequest("localhost", "monitors", (KSGRD::SensorClient*)this, -1); +} + +QStringList SystemMonitorEngine::sources() const +{ + return m_sensors; +} + +bool SystemMonitorEngine::sourceRequestEvent(const QString &name) +{ + // NB: do not follow this example in your own data engines! + // This is kept for backwards compatilibility. + // Visualizations should instead listen to sourceAdded() + if (m_sensors.isEmpty()) { + // we don't have our first data yet, so let's trust the requester, at least fo rnow + // when we get our list of sensors later, then we'll know for sure and remove + // this source if they were wrong + setData(name, DataEngine::Data()); + return true; + } + + return false; +} + +bool SystemMonitorEngine::updateSourceEvent(const QString &sensorName) +{ + const int index = m_sensors.indexOf(sensorName); + + if (index != -1) { + KSGRD::SensorMgr->sendRequest("localhost", sensorName, (KSGRD::SensorClient*)this, index); + KSGRD::SensorMgr->sendRequest("localhost", QString("%1?").arg(sensorName), (KSGRD::SensorClient*)this, -(index + 2)); + } + + return false; +} + +void SystemMonitorEngine::updateSensors() +{ + DataEngine::SourceDict sources = containerDict(); + DataEngine::SourceDict::iterator it = sources.begin(); + if (m_waitingFor != 0) { + scheduleSourcesUpdated(); + } + + m_waitingFor = 0; + + while (it != sources.end()) { + m_waitingFor++; + QString sensorName = it.key(); + KSGRD::SensorMgr->sendRequest( "localhost", sensorName, (KSGRD::SensorClient*)this, -1); + ++it; + } +} + +void SystemMonitorEngine::answerReceived(int id, const QList &answer) +{ + if (id < -1) { + if (answer.isEmpty() || m_sensors.count() <= (-id - 2)) { + kDebug() << "sensor info answer was empty, (" << answer.isEmpty() << ") or sensors does not exist to us (" + << (m_sensors.count() < (-id - 2)) << ") for index" << (-id - 2); + return; + } + + DataEngine::SourceDict sources = containerDict(); + DataEngine::SourceDict::const_iterator it = sources.constFind(m_sensors.value(-id - 2)); + + const QStringList newSensorInfo = QString::fromUtf8(answer[0]).split('\t'); + + if (newSensorInfo.count() < 4) { + kDebug() << "bad sensor info, only" << newSensorInfo.count() + << "entries, and we were expecting 4. Answer was " << answer; + if(it != sources.constEnd()) + kDebug() << "value =" << it.value()->data()["value"] << "type=" << it.value()->data()["type"]; + return; + } + + const QString sensorName = newSensorInfo[0]; + const QString min = newSensorInfo[1]; + const QString max = newSensorInfo[2]; + const QString unit = newSensorInfo[3]; + + if (it != sources.constEnd()) { + it.value()->setData("name", sensorName); + it.value()->setData("min", min); + it.value()->setData("max", max); + it.value()->setData("units", unit); + scheduleSourcesUpdated(); + } + + return; + } + + if (id == -1) { + QSet sensors; + m_sensors.clear(); + int count = 0; + + foreach (const QByteArray &sens, answer) { + const QStringList newSensorInfo = QString::fromUtf8(sens).split('\t'); + if (newSensorInfo.count() < 2) { + continue; + } + if(newSensorInfo.at(1) == "logfile") + continue; // logfile data type not currently supported + + const QString newSensor = newSensorInfo[0]; + sensors.insert(newSensor); + m_sensors.append(newSensor); + { + // HACK: for backwards compability + // in case this source was created in sourceRequestEvent, stop it being + // automagically removed when disconnected from + Plasma::DataContainer *s = containerForSource( newSensor ); + if ( s ) { + disconnect( s, SIGNAL(becameUnused(QString)), this, SLOT(removeSource(QString)) ); + } + } + DataEngine::Data d; + d.insert("value", QVariant()); + d.insert("type", newSensorInfo[1]); + setData(newSensor, d); + KSGRD::SensorMgr->sendRequest( "localhost", QString("%1?").arg(newSensor), (KSGRD::SensorClient*)this, -(count + 2)); + ++count; + } + + QHash sourceDict = containerDict(); + QHashIterator it(sourceDict); + while (it.hasNext()) { + it.next(); + if (!sensors.contains(it.key())) { + removeSource(it.key()); + } + } + + return; + } + + m_waitingFor--; + QString reply; + if (!answer.isEmpty()) { + reply = QString::fromUtf8(answer[0]); + } + + DataEngine::SourceDict sources = containerDict(); + DataEngine::SourceDict::const_iterator it = sources.constFind(m_sensors.value(id)); + if (it != sources.constEnd()) { + it.value()->setData("value", reply); + } + + if (m_waitingFor == 0) { + scheduleSourcesUpdated(); + } +} + +void SystemMonitorEngine::sensorLost( int ) +{ + m_waitingFor--; +} + +#include "systemmonitor.moc" + diff --git a/plasma/generic/dataengines/systemmonitor/systemmonitor.h b/plasma/generic/dataengines/systemmonitor/systemmonitor.h new file mode 100644 index 00000000..ddb4ab44 --- /dev/null +++ b/plasma/generic/dataengines/systemmonitor/systemmonitor.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 John Tapsell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SYSTEMMONITORENGINE_H +#define SYSTEMMONITORENGINE_H + +#include + +#include "ksysguard/ksgrd/SensorClient.h" + +#include + +class QTimer; + +/** + * This class evaluates the basic expressions given in the interface. + */ +class SystemMonitorEngine : public Plasma::DataEngine, public KSGRD::SensorClient +{ + Q_OBJECT + + public: + /** Inherited from Plasma::DataEngine. Returns a list of all the sensors that ksysguardd knows about. */ + virtual QStringList sources() const; + SystemMonitorEngine( QObject* parent, const QVariantList& args ); + ~SystemMonitorEngine(); + + protected: + bool sourceRequestEvent(const QString &name); + /** inherited from SensorClient */ + virtual void answerReceived( int id, const QList&answer ); + virtual void sensorLost( int ); + virtual bool updateSourceEvent(const QString &sensorName); + + protected slots: + void updateSensors(); + void updateMonitorsList(); + + private: + QStringList m_sensors; + QTimer* m_timer; + int m_waitingFor; +}; + +K_EXPORT_PLASMA_DATAENGINE(systemmonitor, SystemMonitorEngine) + +#endif + diff --git a/plasma/generic/dataengines/tasks/CMakeLists.txt b/plasma/generic/dataengines/tasks/CMakeLists.txt new file mode 100644 index 00000000..ac9465c5 --- /dev/null +++ b/plasma/generic/dataengines/tasks/CMakeLists.txt @@ -0,0 +1,14 @@ +set(tasks_engine_SRCS + tasksengine.cpp + tasksource.cpp + taskservice.cpp + taskjob.cpp + virtualdesktopssource.cpp +) + +kde4_add_plugin(plasma_engine_tasks ${tasks_engine_SRCS}) +target_link_libraries(plasma_engine_tasks ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} taskmanager) + +install(TARGETS plasma_engine_tasks DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-tasks.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES tasks.operations DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/plasma/generic/dataengines/tasks/plasma-dataengine-tasks.desktop b/plasma/generic/dataengines/tasks/plasma-dataengine-tasks.desktop new file mode 100644 index 00000000..64239f1b --- /dev/null +++ b/plasma/generic/dataengines/tasks/plasma-dataengine-tasks.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Name=Window Information +Name[ar]=معلومات النافذة +Name[ast]=Información de ventana +Name[be@latin]=Źviestki z akna +Name[bg]=Данни за прозорци +Name[bn]=উইণ্ডো তথ্য +Name[bn_IN]=উইন্ডো সংক্রান্ড তথ্য +Name[bs]=podaci o prozorima +Name[ca]=Informació de les finestres +Name[ca@valencia]=Informació de les finestres +Name[cs]=Informace o okně +Name[csb]=Wëdowiédzô òknów +Name[da]=Vinduesinformation +Name[de]=Fensterinformationen +Name[el]=Πληροφορίες παραθύρου +Name[en_GB]=Window Information +Name[eo]=Fenestra Informo +Name[es]=Información de ventana +Name[et]=Akende teave +Name[eu]=Leihoari buruzko informazioa +Name[fi]=Ikkunatiedot +Name[fr]=Informations sur la fenêtre +Name[fy]=Finster ynformaasje +Name[ga]=Eolas Faoin Fhuinneog +Name[gl]=Información de xanelas +Name[gu]=વિન્ડો માહિતી +Name[he]=מידע על חלון +Name[hi]=विंडो जानकारी +Name[hne]=विंडो जानकारी +Name[hr]=Podaci o prozorima +Name[hu]=Ablakjellemzők +Name[ia]=Information de fenestra +Name[id]=Informasi Jendela +Name[is]=Gluggaupplýsingar +Name[it]=Informazioni sulle finestre +Name[ja]=ウィンドウの情報 +Name[kk]=Терезенің мәліметі +Name[km]=ព័ត៌មាន​បង្អួច +Name[kn]=ಕಿಟಕಿ ಮಾಹಿತಿ +Name[ko]=창 정보 +Name[ku]=Agahiya Paceyê +Name[lt]=Lango informacija +Name[lv]=Logu informācija +Name[mk]=Информации за прозорец +Name[ml]=വിന്‍ഡോ വിവരം +Name[mr]=चौकट माहिती +Name[nb]=Vindusinformasjon +Name[nds]=Finster-Informatschonen +Name[nl]=Vensterinformatie +Name[nn]=Vindaugsinformasjon +Name[or]=ୱିଣ୍ଡୋ ସୂଚନା +Name[pa]=ਵਿੰਡੋ ਜਾਣਕਾਰੀ +Name[pl]=Informacje o oknie +Name[pt]=Informação das Janelas +Name[pt_BR]=Informações da janela +Name[ro]=Informații fereastră +Name[ru]=Сведения об окне +Name[si]=කවුළු තොරතුරු +Name[sk]=Informácie o oknách +Name[sl]=Podatki o oknih +Name[sr]=подаци о прозорима +Name[sr@ijekavian]=подаци о прозорима +Name[sr@ijekavianlatin]=podaci o prozorima +Name[sr@latin]=podaci o prozorima +Name[sv]=Fönsterinformation +Name[ta]=Window Information +Name[tg]=Сведения об окне +Name[th]=ข้อมูลของหน้าต่าง +Name[tr]=Pencere Bilgileri +Name[ug]=كۆزنەك ئۇچۇرى +Name[uk]=Інформація про вікна +Name[wa]=Informåcions sol finiesse +Name[x-test]=xxWindow Informationxx +Name[zh_CN]=窗口信息 +Name[zh_TW]=視窗資訊 +Comment=Information and management services for all available windows. +Comment[ar]=معلومات و خدمات الإدارة لجميع النوافذ المتاحة. +Comment[ast]=Información y servicios de xestión pa toles ventanes disponibles. +Comment[bg]=Данни и услуги за управление на всички налични прозорци. +Comment[bs]=Servisi za podatke i upravljanje svim dostupnim prozorima. +Comment[ca]=Serveis d'informació i gestió de totes les finestres disponibles. +Comment[ca@valencia]=Serveis d'informació i gestió de totes les finestres disponibles. +Comment[cs]=Informace a správa služeb pro všechna dostupná okna. +Comment[da]=Information og håndteringstjenester for alle tilgængelige vinduer. +Comment[de]=Informationen und Verwaltungsdienste für alle verfügbaren Fenster. +Comment[el]=Πληροφορίες υπηρεσιών διαχείρισης για όλα τα διαθέσιμα παράθυρα. +Comment[en_GB]=Information and management services for all available windows. +Comment[eo]=Informado kaj servmastrumado por ĉiuj disponeblaj fenestroj. +Comment[es]=Información y servicios de gestión para todas las ventanas disponibles. +Comment[et]=Teave kõikide akende kohta ja vastavad haldamisteenused. +Comment[eu]=Informazioa eta kudeaketa-zerbitzuak leiho erabilgarri guztientzat. +Comment[fi]=Tieto- ja hallintapalveluja kaikkille käytettävissä oleville ikkunoille. +Comment[fr]=Services d'informations et de gestion pour toutes les fenêtres disponibles. +Comment[fy]=Ynformaasje en behear tsjinsten foar alle beskikbere finsters. +Comment[gl]=Servizos de información e xestión de todas as xanelas dispoñíbeis. +Comment[he]=שירותי מידע וניהול עבור כל החלונות הזמינים. +Comment[hr]=Usluge informiranja i upravljanja za sve dostupne prozore +Comment[hu]=Jellemzők és kezelő szolgáltatások az összes elérhető ablakhoz. +Comment[ia]=Servicios de gestion e information pro omne fenestras disponibile. +Comment[id]=Layanan informasi dan manajemen untuk semua jendela yang tersedia. +Comment[is]=Upplýsinga- og stýringaþjónusta fyrir alla tiltæka glugga. +Comment[it]=Servizi di informazioni e gestione per tutte le finestre disponibili. +Comment[ja]=すべての利用可能なウィンドウ用の情報・管理サービスです。 +Comment[kk]=Бүкіл бар терезелерінің мәліметі мен басқару қызметтері. +Comment[km]=ព័ត៌មាន​អំពី​សេវា និង​ការ​គ្រប់គ្រង​សម្រាប់​វីនដូ​ដែល​អាច​ប្រើ​បានទាំង​អស់ ។ +Comment[kn]=ಲಭ್ಯವಿರುವ ಎಲ್ಲಾ ವಿಂಡೋಗಳಿಗಾಗಿನ ಮಾಹಿತಿ ಹಾಗು ನಿರ್ವಹಣಾ ಸೇವೆಗಳು. +Comment[ko]=사용 가능한 창에 대한 정보 및 관리 서비스입니다. +Comment[lt]=Informacija ir tvarkymo tarnybos visiems prieinamiems langams. +Comment[lv]=Informācija un pārvaldības servisi visiem pieejamajiem logiem. +Comment[mk]=Информации и менаџирање сервиси за сите достапни прозорци. +Comment[ml]=ലഭ്യമായ ജാലകങ്ങള്‍ക്കുള്ള വിവരണങ്ങളും നേതൃത്വ സേവനങ്ങളും. +Comment[mr]=सर्व उपलब्ध चौकटींकरिता माहिती व व्यवस्थापन सेवा +Comment[nb]=Informasjon og styringstjenester for alle tilgjengelige vinduer. +Comment[nds]=Informatschonen un Pleegdeensten för all verföögbor Finstern +Comment[nl]=Informatie- en beheerservices voor alle beschikbare vensters. +Comment[nn]=Informasjon om og handteringstenester for alle tilgjengelege vindauge. +Comment[pa]=ਸਭ ਉਪਲੱਬਧ ਵਿੰਡੋਜ਼ ਲਈ ਜਾਣਕਾਰੀ ਅਤੇ ਪਰਬੰਧ ਸਰਵਿਸਾਂ +Comment[pl]=Informacje i usługi zarządzania dla wszystkich dostępnych okien. +Comment[pt]=Serviços de informação e gestão dos serviços para todas as janelas disponíveis. +Comment[pt_BR]=Informação e gerenciamento de serviços para todas as janelas disponíveis. +Comment[ro]=Servicii de informare și gestiune pentru toate ferestrele disponibile. +Comment[ru]=Информация и управление всеми доступными окнами. +Comment[si]=පවතින සියළු කවුළු සඳහා තොරතුරු හා පරිපාලන සේවා +Comment[sk]=Informačné a riadiace služby pre všetky dostupné okná. +Comment[sl]=Podatki o vseh razpoložljivih oknih in storitve za upravljanje oken. +Comment[sr]=Сервиси за податке и управљање свим доступним прозорима. +Comment[sr@ijekavian]=Сервиси за податке и управљање свим доступним прозорима. +Comment[sr@ijekavianlatin]=Servisi za podatke i upravljanje svim dostupnim prozorima. +Comment[sr@latin]=Servisi za podatke i upravljanje svim dostupnim prozorima. +Comment[sv]=Information om och hanteringstjänster för alla tillgängliga fönster. +Comment[tg]=Иттилоот ва идоракунии хизматҳо барои ҳамаи тирезаҳои дастрас. +Comment[th]=ข้อมูลรายละเอียดและบริการการจัดการต่าง ๆ สำหรับหน้าต่างที่มีใช้งานทั้งหมด +Comment[tr]=Kullanılabilir tüm pencereler için bilgi ve yönetim servisleri. +Comment[ug]=ئىشلەتكىلى بولىدىغان ھەممە كۆزنەكلەرنىڭ ئۇچۇرى ۋە باشقۇرۇش مۇلازىمەتلىرى +Comment[uk]=Відомості щодо служб і керування ними для всіх доступних вікон. +Comment[vi]=Thông tin và các dịch vụ quản lý cho tất cả các cửa sổ hiện hữu. +Comment[wa]=Informåcions eyet siervices di manaedjmint po tos les purneas k' i gn a. +Comment[x-test]=xxInformation and management services for all available windows.xx +Comment[zh_CN]=全部可用窗口的信息和管理服务 +Comment[zh_TW]=所有可用的視窗的資訊與管理服務。 +Type=Service +Icon=user-desktop + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_tasks + +X-KDE-PluginInfo-Author=Robert Knight +X-KDE-PluginInfo-Email=robertknight@gmail.com +X-KDE-PluginInfo-Name=tasks +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Windows and Tasks +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/tasks/taskjob.cpp b/plasma/generic/dataengines/tasks/taskjob.cpp new file mode 100644 index 00000000..9145cfd7 --- /dev/null +++ b/plasma/generic/dataengines/tasks/taskjob.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "taskjob.h" + +TaskJob::TaskJob(TaskSource *source, const QString &operation, QMap ¶meters, QObject *parent) : + ServiceJob(source->objectName(), operation, parameters, parent), + m_source(source) +{ +} + +TaskJob::~TaskJob() +{ +} + +void TaskJob::start() +{ + if (!m_source->task()) { + return; + } + + // only a subset of task operations are exported + const QString operation = operationName(); + if (operation == "setMaximized") { + m_source->task()->setMaximized(parameters().value("maximized").toBool()); + setResult(true); + return; + } else if (operation == "setMinimized") { + m_source->task()->setIconified(parameters().value("minimized").toBool()); + setResult(true); + return; + } else if (operation == "setShaded") { + m_source->task()->setShaded(parameters().value("shaded").toBool()); + setResult(true); + return; + } else if (operation == "setFullScreen") { + m_source->task()->setFullScreen(parameters().value("fullScreen").toBool()); + setResult(true); + return; + } else if (operation == "setAlwaysOnTop") { + m_source->task()->setAlwaysOnTop(parameters().value("alwaysOnTop").toBool()); + setResult(true); + return; + } else if (operation == "setKeptBelowOthers") { + m_source->task()->setKeptBelowOthers(parameters().value("keptBelowOthers").toBool()); + setResult(true); + return; + } else if (operation == "toggleMaximized") { + m_source->task()->toggleMaximized(); + setResult(true); + return; + } else if (operation == "toggleMinimized") { + m_source->task()->toggleIconified(); + setResult(true); + return; + } else if (operation == "toggleShaded") { + m_source->task()->toggleShaded(); + setResult(true); + return; + } else if (operation == "toggleFullScreen") { + m_source->task()->toggleFullScreen(); + setResult(true); + return; + } else if (operation == "toggleAlwaysOnTop") { + m_source->task()->toggleAlwaysOnTop(); + setResult(true); + return; + } else if (operation == "toggleKeptBelowOthers") { + m_source->task()->toggleKeptBelowOthers(); + setResult(true); + return; + } else if (operation == "restore") { + m_source->task()->restore(); + setResult(true); + return; + } else if (operation == "resize") { + m_source->task()->resize(); + setResult(true); + return; + } else if (operation == "move") { + m_source->task()->move(); + setResult(true); + return; + } else if (operation == "raise") { + m_source->task()->raise(); + setResult(true); + return; + } else if (operation == "lower") { + m_source->task()->lower(); + setResult(true); + return; + } else if (operation == "activate") { + m_source->task()->activate(); + setResult(true); + return; + } else if (operation == "activateRaiseOrIconify") { + m_source->task()->activateRaiseOrIconify(); + setResult(true); + return; + } else if (operation == "close") { + m_source->task()->close(); + setResult(true); + return; + } else if (operation == "toDesktop") { + m_source->task()->toDesktop(parameters().value("desktop").toInt()); + setResult(true); + return; + } else if (operation == "toCurrentDesktop") { + m_source->task()->toCurrentDesktop(); + setResult(true); + return; + } else if (operation == "publishIconGeometry") { + m_source->task()->publishIconGeometry(parameters().value("geometry").toRect()); + setResult(true); + return; + } + + setResult(false); +} + +#include "taskjob.moc" diff --git a/plasma/generic/dataengines/tasks/taskjob.h b/plasma/generic/dataengines/tasks/taskjob.h new file mode 100644 index 00000000..147c3580 --- /dev/null +++ b/plasma/generic/dataengines/tasks/taskjob.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKJOB_H +#define TASKJOB_H + +// plasma +#include + +// own +#include "tasksource.h" + +/** + * Task Job + */ +class TaskJob : public Plasma::ServiceJob +{ + + Q_OBJECT + + public: + TaskJob(TaskSource *source, const QString &operation, QMap ¶meters, QObject *parent = NULL); + ~TaskJob(); + + protected: + void start(); + + private: + TaskSource *m_source; + +}; + +#endif // TASKJOB_H diff --git a/plasma/generic/dataengines/tasks/tasks.operations b/plasma/generic/dataengines/tasks/tasks.operations new file mode 100644 index 00000000..21b3de1b --- /dev/null +++ b/plasma/generic/dataengines/tasks/tasks.operations @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plasma/generic/dataengines/tasks/tasksengine.cpp b/plasma/generic/dataengines/tasks/tasksengine.cpp new file mode 100644 index 00000000..059bccbf --- /dev/null +++ b/plasma/generic/dataengines/tasks/tasksengine.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2007 Robert Knight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tasksengine.h" +#include "virtualdesktopssource.h" + +// own +#include "tasksource.h" + +TasksEngine::TasksEngine(QObject *parent, const QVariantList &args) : + Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args); +} + +TasksEngine::~TasksEngine() +{ +} + +Plasma::Service *TasksEngine::serviceForSource(const QString &name) +{ + TaskSource *source = dynamic_cast(containerForSource(name)); + // if source does not exist or it represents a startup task, return a null service + if (!source || !source->task()) { + return Plasma::DataEngine::serviceForSource(name); + } + + // if source represent a proper task, return task service + Plasma::Service *service = source->createService(); + service->setParent(this); + return service; +} + +const QString TasksEngine::getStartupName(::TaskManager::Startup *startup) +{ + return startup->id().id(); +} + +const QString TasksEngine::getTaskName(::TaskManager::Task *task) +{ + return QString::number(task->window()); +} + +void TasksEngine::init() +{ + foreach (TaskManager::Task *task, TaskManager::TaskManager::self()->tasks()) { + Q_ASSERT(task); + taskAdded(task); + } + + TaskManager::TaskManager *manager = TaskManager::TaskManager::self(); + connect(manager, SIGNAL(startupAdded(::TaskManager::Startup*)), this, SLOT(startupAdded(::TaskManager::Startup*))); + connect(manager, SIGNAL(startupRemoved(::TaskManager::Startup*)), this, SLOT(startupRemoved(::TaskManager::Startup*))); + connect(manager, SIGNAL(taskAdded(::TaskManager::Task*)), this, SLOT(taskAdded(::TaskManager::Task*))); + connect(manager, SIGNAL(taskRemoved(::TaskManager::Task*)), this, SLOT(taskRemoved(::TaskManager::Task*))); +} + +void TasksEngine::startupRemoved(::TaskManager::Startup *startup) +{ + Q_ASSERT(startup); + // there is an event loop ref counting bug in Qt that prevents deleteLater() from working + // properly, so we need to remove the source our selves with a single shot + //removeSource(getStartupName(startup)); + if (Plasma::DataContainer *container = containerForSource(getStartupName(startup))) { + QTimer::singleShot(0, container, SLOT(deleteLater())); + } +} + +void TasksEngine::taskRemoved(::TaskManager::Task *task) +{ + Q_ASSERT(task); + // there is an event loop ref counting bug in Qt that prevents deleteLater() from working + // properly, so we need to remove the source our selves with a single shot + //removeSource(getTaskName(task)); + if (Plasma::DataContainer *container = containerForSource(getTaskName(task))) { + QTimer::singleShot(0, container, SLOT(deleteLater())); + } +} + +void TasksEngine::startupAdded(::TaskManager::Startup *startup) +{ + Q_ASSERT(startup); + if (!containerForSource(getStartupName(startup))) { + TaskSource *taskSource = new TaskSource(startup, this); + connect(startup, SIGNAL(changed(::TaskManager::TaskChanges)), taskSource, SLOT(updateStartup(::TaskManager::TaskChanges))); + addSource(taskSource); + } +} + +void TasksEngine::taskAdded(::TaskManager::Task *task) +{ + Q_ASSERT(task); + if (!containerForSource(getTaskName(task))) { + TaskSource *taskSource = new TaskSource(task, this); + connect(task, SIGNAL(changed(::TaskManager::TaskChanges)), taskSource, SLOT(updateTask(::TaskManager::TaskChanges))); + connect(TaskManager::TaskManager::self(), SIGNAL(desktopChanged(int)), taskSource, SLOT(updateDesktop())); + connect(TaskManager::TaskManager::self(), SIGNAL(activityChanged(QString)), taskSource, SLOT(updateActivity())); + addSource(taskSource); + } +} + +bool TasksEngine::sourceRequestEvent(const QString &source) +{ + if (source == "virtualDesktops") { + addSource(new VirtualDesktopsSource); + return true; + } + + return false; +} + +K_EXPORT_PLASMA_DATAENGINE(tasks, TasksEngine) + +#include "tasksengine.moc" diff --git a/plasma/generic/dataengines/tasks/tasksengine.h b/plasma/generic/dataengines/tasks/tasksengine.h new file mode 100644 index 00000000..982649f8 --- /dev/null +++ b/plasma/generic/dataengines/tasks/tasksengine.h @@ -0,0 +1,75 @@ +/* + * Copyright 2007 Robert Knight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSENGINE_H +#define TASKSENGINE_H + +// plasma +#include +#include + +// libtaskmanager +#include + +namespace TaskManager +{ + class Startup; + class Task; +} // namespace TaskManager + +/** + * Tasks Data Engine + * + * This engine provides information regarding tasks (windows that are currently open) + * as well as startup tasks (windows that are about to open). + * Each task and startup is represented by a unique source. Sources are added and removed + * as windows are opened and closed. You cannot request a customized source. + * + * A service is also provided for each task. It exposes some operations that can be + * performed on the windows (ex: maximize, minimize, activate). + * + * The data and operations are provided and handled by the taskmanager library. + * It should be noted that only a subset of data and operations are exposed. + */ +class TasksEngine : public Plasma::DataEngine +{ + + Q_OBJECT + + public: + TasksEngine(QObject *parent, const QVariantList &args); + ~TasksEngine(); + Plasma::Service *serviceForSource(const QString &name); + + protected: + static const QString getStartupName(::TaskManager::Startup *startup); + static const QString getTaskName(::TaskManager::Task *task); + virtual void init(); + bool sourceRequestEvent(const QString &source); + + private slots: + void startupAdded(::TaskManager::Startup *startup); + void startupRemoved(::TaskManager::Startup *startup); + void taskAdded(::TaskManager::Task *task); + void taskRemoved(::TaskManager::Task *task); + + private: + friend class TaskSource; +}; + +#endif // TASKSENGINE_H diff --git a/plasma/generic/dataengines/tasks/taskservice.cpp b/plasma/generic/dataengines/tasks/taskservice.cpp new file mode 100644 index 00000000..826c1ee0 --- /dev/null +++ b/plasma/generic/dataengines/tasks/taskservice.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "taskservice.h" + +// own +#include "taskjob.h" + +TaskService::TaskService(TaskSource *source) : + Plasma::Service(source), + m_source(source) +{ + setName("tasks"); +} + +TaskService::~TaskService() +{ +} + +Plasma::ServiceJob *TaskService::createJob(const QString &operation, QMap ¶meters) +{ + return new TaskJob(m_source, operation, parameters, this); +} + +#include "taskservice.moc" diff --git a/plasma/generic/dataengines/tasks/taskservice.h b/plasma/generic/dataengines/tasks/taskservice.h new file mode 100644 index 00000000..3ad92ab8 --- /dev/null +++ b/plasma/generic/dataengines/tasks/taskservice.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSERVICE_H +#define TASKSERVICE_H + +// plasma +#include +#include + +// own +#include "tasksource.h" + +/** + * Task Service + */ +class TaskService : public Plasma::Service +{ + + Q_OBJECT + + public: + TaskService(TaskSource *source); + ~TaskService(); + + protected: + Plasma::ServiceJob *createJob(const QString &operation, QMap ¶meters); + + private: + TaskSource *m_source; +}; + +#endif // TASKSERVICE_H diff --git a/plasma/generic/dataengines/tasks/tasksource.cpp b/plasma/generic/dataengines/tasks/tasksource.cpp new file mode 100644 index 00000000..ff377c84 --- /dev/null +++ b/plasma/generic/dataengines/tasks/tasksource.cpp @@ -0,0 +1,184 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tasksource.h" + +// own +#include "tasksengine.h" +#include "taskservice.h" + +TaskSource::TaskSource(::TaskManager::Startup *startup, QObject *parent) + : Plasma::DataContainer(parent), + m_startup(startup) +{ + setObjectName(TasksEngine::getStartupName(startup)); + setData("startup", true); + setData("task", false); + updateStartup(TaskManager::TaskUnchanged); +} + +TaskSource::TaskSource(::TaskManager::Task *task, QObject *parent) + : Plasma::DataContainer(parent), + m_task(task) +{ + setObjectName(TasksEngine::getTaskName(task)); + setData("startup", false); + setData("task", true); + setData("className", task->className()); + setData("classClass", task->classClass()); + updateTask(TaskManager::EverythingChanged); +} + +TaskSource::~TaskSource() +{ +} + +Plasma::Service *TaskSource::createService() +{ + return new TaskService(this); +} + +::TaskManager::Task *TaskSource::task() +{ + return m_task.data(); +} + +void TaskSource::updateStartup(::TaskManager::TaskChanges startupChanges) +{ + ::TaskManager::Startup *startup = m_startup.data(); + if (!startup) { + return; + } + + switch (startupChanges) { + case TaskManager::TaskUnchanged: + setData("text", startup->text()); + setData("bin", startup->bin()); + setData("icon", startup->icon()); + } + checkForUpdate(); +} + +void TaskSource::updateTask(::TaskManager::TaskChanges taskChanges) +{ + ::TaskManager::Task *taskPtr = m_task.data(); + if (!taskPtr) { + return; + } + + // only a subset of task information is exported + switch (taskChanges) { + case TaskManager::EverythingChanged: + setData("name", taskPtr->name()); + setData("visibleName", taskPtr->visibleName()); + setData("visibleNameWithState", taskPtr->visibleNameWithState()); + setData("maximized", taskPtr->isMaximized()); + setData("minimized", taskPtr->isMinimized()); + setData("shaded", taskPtr->isShaded()); + setData("fullScreen", taskPtr->isFullScreen()); + setData("alwaysOnTop", taskPtr->isAlwaysOnTop()); + setData("keptBelowOthers", taskPtr->isKeptBelowOthers()); + setData("active", taskPtr->isActive()); + setData("onTop", taskPtr->isOnTop()); + setData("onCurrentDesktop", taskPtr->isOnCurrentDesktop()); + setData("onAllDesktops", taskPtr->isOnAllDesktops()); + setData("desktop", taskPtr->desktop()); + setData("onCurrentActivity", taskPtr->isOnCurrentActivity()); + setData("onAllActivities", taskPtr->isOnAllActivities()); + setData("activities", taskPtr->activities()); + setData("icon", taskPtr->icon()); + setData("actionMinimize", taskPtr->info().actionSupported(NET::ActionMinimize)); + setData("actionMaximize", taskPtr->info().actionSupported(NET::ActionMax)); + setData("actionShade", taskPtr->info().actionSupported(NET::ActionShade)); + setData("actionResize", taskPtr->info().actionSupported(NET::ActionResize)); + setData("actionMove", taskPtr->info().actionSupported(NET::ActionMove)); + setData("actionClose", taskPtr->info().actionSupported(NET::ActionClose)); + setData("actionChangeDesktop", taskPtr->info().actionSupported(NET::ActionChangeDesktop)); + setData("actionFullScreen", taskPtr->info().actionSupported(NET::ActionFullScreen)); + break; + case TaskManager::IconChanged: + setData("icon", taskPtr->icon()); + break; + case TaskManager::NameChanged: + setData("name", taskPtr->name()); + setData("visibleName", taskPtr->visibleName()); + setData("visibleNameWithState", taskPtr->visibleNameWithState()); + break; + case TaskManager::StateChanged: + setData("maximized", taskPtr->isMaximized()); + setData("minimized", taskPtr->isMinimized()); + setData("shaded", taskPtr->isShaded()); + setData("fullScreen", taskPtr->isFullScreen()); + setData("alwaysOnTop", taskPtr->isAlwaysOnTop()); + setData("keptBelowOthers", taskPtr->isKeptBelowOthers()); + setData("active", taskPtr->isActive()); + setData("onTop", taskPtr->isOnTop()); + setData("visibleNameWithState", taskPtr->visibleNameWithState()); + break; + case TaskManager::DesktopChanged: + setData("onCurrentDesktop", taskPtr->isOnCurrentDesktop()); + setData("onAllDesktops", taskPtr->isOnAllDesktops()); + setData("desktop", taskPtr->desktop()); + break; + case TaskManager::ActivitiesChanged: + setData("onCurrentActivity", taskPtr->isOnCurrentActivity()); + setData("onAllActivities", taskPtr->isOnAllActivities()); + setData("activities", taskPtr->activities()); + case TaskManager::ActionsChanged: + setData("actionMinimize", taskPtr->info().actionSupported(NET::ActionMinimize)); + setData("actionMaximize", taskPtr->info().actionSupported(NET::ActionMax)); + setData("actionShade", taskPtr->info().actionSupported(NET::ActionShade)); + setData("actionResize", taskPtr->info().actionSupported(NET::ActionResize)); + setData("actionMove", taskPtr->info().actionSupported(NET::ActionMove)); + setData("actionClose", taskPtr->info().actionSupported(NET::ActionClose)); + setData("actionChangeDesktop", taskPtr->info().actionSupported(NET::ActionChangeDesktop)); + setData("actionFullScreen", taskPtr->info().actionSupported(NET::ActionFullScreen)); + break; + default: + break; + } + checkForUpdate(); +} + +void TaskSource::updateDesktop() +{ + if (!m_task) { + return; + } + + const bool onCurrentDesktop = m_task.data()->isOnCurrentDesktop(); + if (data()["onCurrentDesktop"].toBool() != onCurrentDesktop) { + setData("onCurrentDesktop", onCurrentDesktop); + checkForUpdate(); + } +} + +void TaskSource::updateActivity() +{ + if (!m_task) { + return; + } + + const bool onCurrentActivity = m_task.data()->isOnCurrentActivity(); + if (data()["onCurrentActivity"].toBool() != onCurrentActivity) { + setData("onCurrentActivity", onCurrentActivity); + checkForUpdate(); + } +} + +#include "tasksource.moc" diff --git a/plasma/generic/dataengines/tasks/tasksource.h b/plasma/generic/dataengines/tasks/tasksource.h new file mode 100644 index 00000000..6f4a0e80 --- /dev/null +++ b/plasma/generic/dataengines/tasks/tasksource.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Alain Boyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TASKSOURCE_H +#define TASKSOURCE_H + +// plasma +#include + +// libtaskmanager +#include + +/** + * Task Source + * + * This custom DataContainer represents a task or startup task as a unique source. + * It holds a shared pointer to the task or startup task and is responsible for setting + * and updating the data exposed by the source. + */ +class TaskSource : public Plasma::DataContainer +{ + + Q_OBJECT + + public: + TaskSource(::TaskManager::Startup *startup, QObject *parent); + TaskSource(::TaskManager::Task *task, QObject *parent); + ~TaskSource(); + + Plasma::Service *createService(); + ::TaskManager::Task *task(); + + private slots: + void updateStartup(::TaskManager::TaskChanges startupChanges); + void updateTask(::TaskManager::TaskChanges taskChanges); + void updateDesktop(); + void updateActivity(); + + private: + QWeakPointer< ::TaskManager::Startup > m_startup; + QWeakPointer< ::TaskManager::Task > m_task; +}; + +#endif // TASKSOURCE_H diff --git a/plasma/generic/dataengines/tasks/virtualdesktopssource.cpp b/plasma/generic/dataengines/tasks/virtualdesktopssource.cpp new file mode 100644 index 00000000..163718fe --- /dev/null +++ b/plasma/generic/dataengines/tasks/virtualdesktopssource.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2010 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License; 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "virtualdesktopssource.h" + +#include + +VirtualDesktopsSource::VirtualDesktopsSource() : Plasma::DataContainer() +{ + setObjectName( QLatin1String("virtualDesktops" )); + connect(KWindowSystem::self(), SIGNAL(numberOfDesktopsChanged(int)), this, SLOT(updateDesktopNumber(int))); + connect(KWindowSystem::self(), SIGNAL(desktopNamesChanged()), this, SLOT(updateDesktopNames())); + updateDesktopNumber(KWindowSystem::self()->numberOfDesktops()); + updateDesktopNames(); +} + +VirtualDesktopsSource::~VirtualDesktopsSource() +{ + disconnect(KWindowSystem::self(), SIGNAL(numberOfDesktopsChanged(int)), this, SLOT(updateDesktopNumber(int))); +} + +void VirtualDesktopsSource::updateDesktopNumber(int desktop) +{ + setData("number", desktop); + checkForUpdate(); +} + +void VirtualDesktopsSource::updateDesktopNames() +{ + QList desktopNames; + for (int i = 0; i < KWindowSystem::self()->numberOfDesktops(); i++) { + desktopNames.append(KWindowSystem::self()->desktopName(i + 1)); + } + setData("names", desktopNames); + checkForUpdate(); +} diff --git a/plasma/generic/dataengines/tasks/virtualdesktopssource.h b/plasma/generic/dataengines/tasks/virtualdesktopssource.h new file mode 100644 index 00000000..3712d4b4 --- /dev/null +++ b/plasma/generic/dataengines/tasks/virtualdesktopssource.h @@ -0,0 +1,43 @@ +/* + * Copyright 2010 Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License; 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef VIRTUALDESKTOPSSOURCE_H +#define VIRTUALDESKTOPSSOURCE_H + +// plasma +#include + +class VirtualDesktopsSource : public Plasma::DataContainer +{ + + Q_OBJECT + + public: + + VirtualDesktopsSource(); + + ~VirtualDesktopsSource(); + + private slots: + + void updateDesktopNumber(int desktop); + + void updateDesktopNames(); +}; + +#endif diff --git a/plasma/generic/dataengines/time/CMakeLists.txt b/plasma/generic/dataengines/time/CMakeLists.txt new file mode 100644 index 00000000..ebfc04c8 --- /dev/null +++ b/plasma/generic/dataengines/time/CMakeLists.txt @@ -0,0 +1,12 @@ +set(time_engine_SRCS + timeengine.cpp + timesource.cpp + solarsystem.cpp +) + +kde4_add_plugin(plasma_engine_time ${time_engine_SRCS}) +target_link_libraries(plasma_engine_time ${KDE4_KDECORE_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_SOLID_LIBS}) + +install(TARGETS plasma_engine_time DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-dataengine-time.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + diff --git a/plasma/generic/dataengines/time/plasma-dataengine-time.desktop b/plasma/generic/dataengines/time/plasma-dataengine-time.desktop new file mode 100644 index 00000000..d0dd521a --- /dev/null +++ b/plasma/generic/dataengines/time/plasma-dataengine-time.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=Date and Time +Name[ar]=التاريخ و الوقت +Name[as]=তাৰিখ আৰু সময় +Name[ast]=Data y hora +Name[be@latin]=Data j čas +Name[bg]=Дата и час +Name[bn]=তারিখ এবং সময় +Name[bn_IN]=তারিখ ও সময় +Name[bs]=datum i vrijeme +Name[ca]=Data i hora +Name[ca@valencia]=Data i hora +Name[cs]=Datum a čas +Name[csb]=Datum ë czas +Name[da]=Dato og tid +Name[de]=Datum und Zeit +Name[el]=Ημερομηνία και ώρα +Name[en_GB]=Date and Time +Name[eo]=Dato kaj Tempo +Name[es]=Fecha y hora +Name[et]=Kuupäev ja kellaaeg +Name[eu]=Data eta ordua +Name[fa]=تاریخ و زمان +Name[fi]=Aika ja päiväys +Name[fr]=Date et heure +Name[fy]=Datum en tiid +Name[ga]=Dáta agus Am +Name[gl]=Data e hora +Name[gu]=તારીખ અને સમય +Name[he]=תאריך ושעה +Name[hi]=तारीख़ और समय +Name[hne]=तारीक अउ समय +Name[hr]=Datum i vrijeme +Name[hu]=Dátum és idő +Name[ia]=Data e Tempore +Name[id]=Tanggal dan Waktu +Name[is]=Dagur og tími +Name[it]=Data e ora +Name[ja]=日付と時刻 +Name[kk]=Күні мен уақыты +Name[km]=កាល​បរិច្ឆេទ និង​ពេលវេលា +Name[kn]=ದಿನಾಂಕ ಮತ್ತು ಸಮಯ +Name[ko]=날짜와 시간 +Name[ku]=Dîrok û Dem +Name[lt]=Data ir laikas +Name[lv]=Datums un laiks +Name[mai]=दिनाँक आ समय +Name[mk]=Датум и време +Name[ml]=തീയതിയും സമയവും +Name[mr]=दिनांक व वेळ +Name[nb]=Dato og klokkeslett +Name[nds]=Datum un Tiet +Name[nl]=Datum en tijd +Name[nn]=Dato og klokkeslett +Name[or]=ତାରିଖ ଏବଂ ସମୟ +Name[pa]=ਮਿਤੀ ਅਤੇ ਟਾਈਮ +Name[pl]=Data i czas +Name[pt]=Data e Hora +Name[pt_BR]=Data e hora +Name[ro]=Data și ora +Name[ru]=Дата и время +Name[si]=දිනය සහ වේලාව +Name[sk]=Dátum a čas +Name[sl]=Datum in čas +Name[sr]=датум и време +Name[sr@ijekavian]=датум и време +Name[sr@ijekavianlatin]=datum i vreme +Name[sr@latin]=datum i vreme +Name[sv]=Datum och tid +Name[ta]=Date and Time +Name[tg]=Сана ва вақт +Name[th]=วันและเวลา +Name[tr]=Tarih ve Saat +Name[ug]=چېسلا ۋە ۋاقىت +Name[uk]=Дата і час +Name[vi]=Ngày giờ +Name[wa]=Date eyet eure +Name[x-test]=xxDate and Timexx +Name[zh_CN]=日期和时间 +Name[zh_TW]=日期與時間 +Comment=Date and time by timezone +Comment[ar]=التاريخ و الوقت بواسطة المنطقة الزمنية +Comment[ast]=Data y hora por estaya horaria +Comment[bg]=Настройки на датата и часа +Comment[bn]=টাইম-জোন অনুসারে তারিখ এবং সময় +Comment[bs]=Datum i vrijeme po vremenskoj zoni +Comment[ca]=Data i l'hora per zona horària +Comment[ca@valencia]=Data i l'hora per zona horària +Comment[cs]=Datum a čas podle časového pásma +Comment[csb]=Datum ë czas wedle czasowich conów +Comment[da]=Dato og tid efter tidszone +Comment[de]=Datum und Zeit nach Zeitzone +Comment[el]=Ημερομηνία και ώρα ανά ωρολογιακή ζώνη +Comment[en_GB]=Date and time by timezone +Comment[eo]=Dato kaj tempo laŭ horzonoj +Comment[es]=Fecha y hora por zona horaria +Comment[et]=Kuupäev ja kellaaeg ajavööndi põhjal +Comment[eu]=Data eta ordua ordu-eremuaren arabera +Comment[fi]=Aika ja päiväys aikavyöhykkeittäin +Comment[fr]=Date et heure par fuseau horaire +Comment[fy]=Datum en tiid mei help fan tiidsône +Comment[ga]=Dáta agus am de réir creasa ama +Comment[gl]=Data e hora segundo o fuso horario +Comment[gu]=સમયવિસ્તાર વડે તારીખ અને સમય +Comment[he]=תאריך ושעה לפי אזור זמן +Comment[hi]=तारीख़ तथा समय समयक्षेत्र हिसाब से +Comment[hr]=Datum i vrijeme po vremenskoj zoni +Comment[hu]=Dátum és idő (időzónánként) +Comment[ia]=Data e tempore per fuso horari +Comment[id]=Tanggal dan waktu menurut zona waktu +Comment[is]=Stillingar dagssetningar og klukku eftir tímabeltum +Comment[it]=Data e ora per fuso orario +Comment[ja]=タイムゾーンの日付と時刻 +Comment[kk]=Уақыт белдеуінің күн мен уақыты +Comment[km]=កាលបរិច្ឆេទ និង​ពេលវេលា​តាម​តំបន់​ពេលវេលា +Comment[kn]=ಕಾಲವಲಯದಿಂದ ದಿನಾಂಕ ಮತ್ತು ಸಮಯ +Comment[ko]=시간대에 따른 날짜와 시간 +Comment[lt]=Data ir laikas pagal laiko juostas +Comment[lv]=Datums un laiks pa laika joslām +Comment[mk]=Датум и време според временска зона +Comment[ml]=തീയതിയും സമയവും സമയമേഖലയനുസരിച്ചു് +Comment[mr]=वेळक्षेत्रा प्रमाणे दिनांक व वेळ +Comment[nb]=Dato og klokkeslett ved tidssone +Comment[nds]=Datum un Tiet na Tietrebeet +Comment[nl]=Datum en tijd per tijdzone +Comment[nn]=Dato og klokkeslett i ulike tidssoner +Comment[pa]=ਮਿਤੀ ਅਤੇ ਟਾਈਮ ਸਮਾਂ-ਖੇਤਰ ਰਾਹੀਂ +Comment[pl]=Ustawienia daty i czasu na podstawie strefy czasowej +Comment[pt]=Data e hora pelo fuso-horário +Comment[pt_BR]=Data e hora por fuso horário +Comment[ro]=Data și ora după fusul orar +Comment[ru]=Дата и время в различных часовых поясах +Comment[si]=වේලා කලාපය අනුව දිනය සහ වේලාව +Comment[sk]=Dátum a čas podľa časového pásma +Comment[sl]=Datum in čas po časovnih pasovih +Comment[sr]=Датум и време по временској зони +Comment[sr@ijekavian]=Датум и вријеме по временској зони +Comment[sr@ijekavianlatin]=Datum i vrijeme po vremenskoj zoni +Comment[sr@latin]=Datum i vreme po vremenskoj zoni +Comment[sv]=Datum och tid enligt tidszon +Comment[tg]=Танзимоти сана ва вақт +Comment[th]=วันและเวลาตามเขตเวลา +Comment[tr]=Zaman dilimine göre tarih ve saat +Comment[ug]=ۋاقىت رايونىغا ئاساسەن چېسلا ۋە ۋاقىت تەمىنلەيدۇ +Comment[uk]=Дата і час за часовими поясами +Comment[vi]=Ngày giờ theo múi giờ +Comment[wa]=Date et eure pa coisse ås eures +Comment[x-test]=xxDate and time by timezonexx +Comment[zh_CN]=根据时区提供日期和时间 +Comment[zh_TW]=時區的日期和時間 +Type=Service +Icon=preferences-system-time + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_time + +X-KDE-PluginInfo-Author=Aaron Seigo +X-KDE-PluginInfo-Email=aseigo@kde.org +X-KDE-PluginInfo-Name=time +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Date and Time +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/dataengines/time/solarsystem.cpp b/plasma/generic/dataengines/time/solarsystem.cpp new file mode 100644 index 00000000..82ca262e --- /dev/null +++ b/plasma/generic/dataengines/time/solarsystem.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2009 Petri Damsten + * + * 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. If not, see . + */ + +#include "solarsystem.h" +#include +#include + +/* + * Mathematics, ideas, public domain code used for these classes from: + * http://www.stjarnhimlen.se/comp/tutorial.html + * http://www.stjarnhimlen.se/comp/riset.html + * http://www.srrb.noaa.gov/highlights/solarrise/azel.html + * http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html + * http://bodmas.org/astronomy/riset.html + * moontool.c by John Walker + * Wikipedia + */ + +Sun::Sun() + : SolarSystemObject() +{ +} + +void Sun::calcForDateTime(const QDateTime& local, int offset) +{ + SolarSystemObject::calcForDateTime(local, offset); + + N = 0.0; + i = 0.0; + w = rev(282.9404 + 4.70935E-5 * m_day); + a = 1.0; + e = rev(0.016709 - 1.151E-9 * m_day); + M = rev(356.0470 + 0.9856002585 * m_day); + + calc(); +} + +void Sun::rotate(double* y, double* z) +{ + *y *= cosd(m_obliquity); + *z *= sind(m_obliquity); +} + +Moon::Moon(Sun *sun) + : m_sun(sun) +{ +} + +void Moon::calcForDateTime(const QDateTime& local, int offset) +{ + if (m_sun->dateTime() != local) { + m_sun->calcForDateTime(local, offset); + } + + SolarSystemObject::calcForDateTime(local, offset); + + N = rev(125.1228 - 0.0529538083 * m_day); + i = 5.1454; + w = rev(318.0634 + 0.1643573223 * m_day); + a = 60.2666; + e = 0.054900; + M = rev(115.3654 + 13.0649929509 * m_day); + + calc(); +} + +bool Moon::calcPerturbations(double *lo, double *la, double *r) +{ + double Ms = m_sun->meanAnomaly(); + double D = L - m_sun->meanLongitude(); + double F = L - N; + + *lo += -1.274 * sind(M - 2 * D) + +0.658 * sind(2 * D) + -0.186 * sind(Ms) + -0.059 * sind(2 * M - 2 * D) + -0.057 * sind(M - 2 * D + Ms) + +0.053 * sind(M + 2 * D) + +0.046 * sind(2 * D - Ms) + +0.041 * sind(M - Ms) + -0.035 * sind(D) + -0.031 * sind(M + Ms) + -0.015 * sind(2 * F - 2 * D) + +0.011 * sind(M - 4 * D); + *la += -0.173 * sind(F - 2 * D) + -0.055 * sind(M - F - 2 * D) + -0.046 * sind(M + F - 2 * D) + +0.033 * sind(F + 2 * D) + +0.017 * sind(2 * M + F); + *r += -0.58 * cosd(M - 2 * D) + -0.46 * cosd(2 * D); + return true; +} + +void Moon::topocentricCorrection(double* RA, double* dec) +{ + double HA = rev(siderealTime() - *RA); + double gclat = m_latitude - 0.1924 * sind(2 * m_latitude); + double rho = 0.99833 + 0.00167 * cosd(2 * m_latitude); + double mpar = asind(1 / rad); + double g = atand(tand(gclat) / cosd(HA)); + + *RA -= mpar * rho * cosd(gclat) * sind(HA) / cosd(*dec); + *dec -= mpar * rho * sind(gclat) * sind(g - *dec) / sind(g); +} + +double Moon::phase() +{ + return rev(m_eclipticLongitude - m_sun->lambda()); +} + +void Moon::rotate(double* y, double* z) +{ + double t = *y; + *y = t * cosd(m_obliquity) - *z * sind(m_obliquity); + *z = t * sind(m_obliquity) + *z * cosd(m_obliquity); +} + +void SolarSystemObject::calc() +{ + double x, y, z; + double la, r; + + L = rev(N + w + M); + double E0 = 720.0; + double E = M + (180.0 / M_PI) * e * sind(M) * (1.0 + e * cosd(M)); + for (int j = 0; fabs(E0 - E) > 0.005 && j < 10; ++j) { + E0 = E; + E = E0 - (E0 - (180.0 / M_PI) * e * sind(E0) - M) / (1 - e * cosd(E0)); + } + x = a * (cosd(E) - e); + y = a * sind(E) * sqrt(1.0 - e * e); + r = sqrt(x * x + y * y); + double v = rev(atan2d(y, x)); + m_lambda = rev(v + w); + x = r * (cosd(N) * cosd(m_lambda) - sind(N) * sind(m_lambda) * cosd(i)); + y = r * (sind(N) * cosd(m_lambda) + cosd(N) * sind(m_lambda) * cosd(i)); + z = r * sind(m_lambda); + if (!qFuzzyCompare(i, 0.0)) { + z *= sind(i); + } + toSpherical(x, y, z, &m_eclipticLongitude, &la, &r); + if (calcPerturbations(&m_eclipticLongitude, &la, &r)) { + toRectangular(m_eclipticLongitude, la, r, &x, &y, &z); + } + rotate(&y, &z); + toSpherical(x, y, z, &RA, &dec, &rad); + topocentricCorrection(&RA, &dec); + + HA = rev(siderealTime() - RA); + x = cosd(HA) * cosd(dec) * sind(m_latitude) - sind(dec) * cosd(m_latitude); + y = sind(HA) * cosd(dec); + z = cosd(HA) * cosd(dec) * cosd(m_latitude) + sind(dec) * sind(m_latitude); + m_azimuth = atan2d(y, x) + 180.0; + m_altitude = asind(z); +} + +double SolarSystemObject::siderealTime() +{ + double UT = m_utc.time().hour() + m_utc.time().minute() / 60.0 + + m_utc.time().second() / 3600.0; + double GMST0 = rev(282.9404 + 4.70935E-5 * m_day + 356.0470 + 0.9856002585 * m_day + 180.0); + return GMST0 + UT * 15.0 + m_longitude; +} + +void SolarSystemObject::calcForDateTime(const QDateTime& local, int offset) +{ + m_local = local; + m_utc = local.addSecs(-offset); + m_day = 367 * m_utc.date().year() - (7 * (m_utc.date().year() + + ((m_utc.date().month() + 9) / 12))) / 4 + + (275 * m_utc.date().month()) / 9 + m_utc.date().day() - 730530; + m_day += m_utc.time().hour() / 24.0 + m_utc.time().minute() / (24.0 * 60.0) + + m_utc.time().second() / (24.0 * 60.0 * 60.0); + m_obliquity = 23.4393 - 3.563E-7 * m_day; +} + +SolarSystemObject::SolarSystemObject() + : m_latitude(0.0) + , m_longitude(0.0) +{ +} + +SolarSystemObject::~SolarSystemObject() +{ +} + +void SolarSystemObject::setPosition(double latitude, double longitude) +{ + m_latitude = latitude; + m_longitude = longitude; +} + +double SolarSystemObject::rev(double x) +{ + return x - floor(x / 360.0) * 360.0; +} + +double SolarSystemObject::asind(double x) +{ + return asin(x) * 180.0 / M_PI; +} + +double SolarSystemObject::sind(double x) +{ + return sin(x * M_PI / 180.0); +} + +double SolarSystemObject::cosd(double x) +{ + return cos(x * M_PI / 180.0); +} + +double SolarSystemObject::tand(double x) +{ + return tan(x * M_PI / 180.0); +} + +double SolarSystemObject::atan2d(double y, double x) +{ + return atan2(y, x) * 180.0 / M_PI; +} + +double SolarSystemObject::atand(double x) +{ + return atan(x) * 180.0 / M_PI; +} + +void SolarSystemObject::toRectangular(double lo, double la, double r, double *x, double *y, double *z) +{ + *x = r * cosd(lo) * cosd(la); + *y = r * sind(lo) * cosd(la); + *z = r * sind(la); +} + +void SolarSystemObject::toSpherical(double x, double y, double z, double *lo, double *la, double *r) +{ + *r = sqrt(x * x + y * y + z * z); + *la = asind(z / *r); + *lo = rev(atan2d(y, x)); +} + +QPair SolarSystemObject::zeroPoints(QPointF p1, QPointF p2, QPointF p3) +{ + double a = ((p2.y() - p1.y()) * (p1.x() - p3.x()) + (p3.y() - p1.y()) * (p2.x() - p1.x())) / + ((p1.x() - p3.x()) * (p2.x() * p2.x() - p1.x() * p1.x()) + (p2.x() - p1.x()) * + (p3.x() * p3.x() - p1.x() * p1.x())); + double b = ((p2.y() - p1.y()) - a * (p2.x() * p2.x() - p1.x() * p1.x())) / (p2.x() - p1.x()); + double c = p1.y() - a * p1.x() * p1.x() - b * p1.x(); + double discriminant = b * b - 4.0 * a * c; + double z1 = -1.0, z2 = -1.0; + + if (discriminant >= 0.0) { + z1 = (-b + sqrt(discriminant)) / (2 * a); + z2 = (-b - sqrt(discriminant)) / (2 * a); + } + return QPair(z1, z2); +} + +QList< QPair > SolarSystemObject::timesForAngles(const QList& angles, + const QDateTime& dt, + int offset) +{ + QList altitudes; + QDate d = dt.date(); + QDateTime local(d, QTime(0, 0)); + for (int j = 0; j <= 25; ++j) { + calcForDateTime(local, offset); + altitudes.append(altitude()); + local = local.addSecs(60 * 60); + } + QList< QPair > result; + QTime rise, set; + foreach (double angle, angles) { + for (int j = 3; j <= 25; j += 2) { + QPointF p1((j - 2) * 60 * 60, altitudes[j - 2] - angle); + QPointF p2((j - 1) * 60 * 60, altitudes[j - 1] - angle); + QPointF p3(j * 60 * 60, altitudes[j] - angle); + QPair z = zeroPoints(p1, p2, p3); + if (z.first > p1.x() && z.first < p3.x()) { + if (p1.y() < 0.0) { + rise = QTime(0, 0).addSecs(z.first); + } else { + set = QTime(0, 0).addSecs(z.first); + } + } + if (z.second > p1.x() && z.second < p3.x()) { + if (p3.y() < 0.0) { + set = QTime(0, 0).addSecs(z.second); + } else { + rise = QTime(0, 0).addSecs(z.second); + } + } + } + result.append(QPair(QDateTime(d, rise), QDateTime(d, set))); + } + return result; +} + +double SolarSystemObject::calcElevation() +{ + double refractionCorrection; + + if (m_altitude > 85.0) { + refractionCorrection = 0.0; + } else { + double te = tand(m_altitude); + if (m_altitude > 5.0) { + refractionCorrection = 58.1 / te - 0.07 / (te * te * te) + + 0.000086 / (te * te * te * te * te); + } else if (m_altitude > -0.575) { + refractionCorrection = 1735.0 + m_altitude * + (-518.2 + m_altitude * (103.4 + m_altitude * + (-12.79 + m_altitude * 0.711) ) ); + } else { + refractionCorrection = -20.774 / te; + } + refractionCorrection = refractionCorrection / 3600.0; + } + return m_altitude + refractionCorrection; +} diff --git a/plasma/generic/dataengines/time/solarsystem.h b/plasma/generic/dataengines/time/solarsystem.h new file mode 100644 index 00000000..5ffdb5e1 --- /dev/null +++ b/plasma/generic/dataengines/time/solarsystem.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2009 Petri Damsten + * + * 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. If not, see . + */ + +#ifndef SOLARSYSTEM_H +#define SOLARSYSTEM_H + +#include +#include +#include + +/* + * Mathematics, ideas, public domain code used for these classes from: + * http://www.stjarnhimlen.se/comp/tutorial.html + * http://www.stjarnhimlen.se/comp/riset.html + * http://www.srrb.noaa.gov/highlights/solarrise/azel.html + * http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html + * http://bodmas.org/astronomy/riset.html + * moontool.c by John Walker + * Wikipedia + */ + +class SolarSystemObject +{ + public: + SolarSystemObject(); + virtual ~SolarSystemObject(); + + double meanLongitude() const { return L; }; + double meanAnomaly() const { return M; }; + double siderealTime(); + double altitude() const { return m_altitude; }; + double azimuth() const { return m_azimuth; }; + double calcElevation(); + QDateTime dateTime() const { return m_local; }; + double lambda() const { return m_lambda; }; + double eclipticLongitude() const { return m_eclipticLongitude; }; + void setPosition(double latitude, double longitude); + + virtual void calcForDateTime(const QDateTime& local, int offset); + QList< QPair > timesForAngles(const QList& angles, + const QDateTime& dt, + int offset); + + protected: + void calc(); + virtual bool calcPerturbations(double*, double*, double*) { return false; }; + virtual void rotate(double*, double*) { }; + virtual void topocentricCorrection(double*, double*) { }; + + inline double rev(double x); + inline double asind(double x); + inline double sind(double x); + inline double cosd(double x); + inline double atand(double x); + inline double tand(double x); + inline double atan2d(double y, double x); + void toRectangular(double lo, double la, double r, double *x, double *y, double *z); + void toSpherical(double x, double y, double z, double *lo, double *la, double *r); + QPair zeroPoints(QPointF p1, QPointF p2, QPointF p3); + + double N; + double i; + double w; + double a; + double e; + double M; + double m_obliquity; + + QDateTime m_utc; + QDateTime m_local; + double m_day; + double m_latitude; + double m_longitude; + + double L; + double rad; + double RA; + double dec; + double HA; + double m_altitude; + double m_azimuth; + double m_eclipticLongitude; + double m_lambda; +}; + +class Sun : public SolarSystemObject +{ + public: + Sun(); + virtual void calcForDateTime(const QDateTime& local, int offset); + + protected: + virtual void rotate(double*, double*); +}; + +class Moon : public SolarSystemObject +{ + public: + Moon(Sun *sun); + virtual ~Moon() {}; // to not delete the Sun + + virtual void calcForDateTime(const QDateTime& local, int offset); + double phase(); + + protected: + virtual bool calcPerturbations(double *RA, double *dec, double *r); + virtual void rotate(double*, double*); + virtual void topocentricCorrection(double*, double*); + + private: + Sun *m_sun; +}; + +#endif diff --git a/plasma/generic/dataengines/time/timeengine.cpp b/plasma/generic/dataengines/time/timeengine.cpp new file mode 100644 index 00000000..a59fc424 --- /dev/null +++ b/plasma/generic/dataengines/time/timeengine.cpp @@ -0,0 +1,111 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2008 Alex Merry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "timeengine.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "timesource.h" + +//timezone is defined in msvc +#ifdef timezone +#undef timezone +#endif + +TimeEngine::TimeEngine(QObject *parent, const QVariantList &args) + : Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args) + setMinimumPollingInterval(333); + + // To have translated timezone names + // (effectively a noop if the catalog is already present). + KGlobal::locale()->insertCatalog("timezones4"); +} + +TimeEngine::~TimeEngine() +{ +} + +void TimeEngine::init() +{ + //QDBusInterface *ktimezoned = new QDBusInterface("org.kde.kded", "/modules/ktimezoned", "org.kde.KTimeZoned"); + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.connect(QString(), QString(), "org.kde.KTimeZoned", "configChanged", this, SLOT(tzConfigChanged())); + dbus.connect(QString(), "/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated", this, SLOT(clockSkewed())); + + connect( Solid::PowerManagement::notifier(), SIGNAL(resumingFromSuspend()), this , SLOT(clockSkewed()) ); +} + +void TimeEngine::clockSkewed() +{ + kDebug() << "Time engine Clock skew signaled"; + updateAllSources(); + forceImmediateUpdateOfAllVisualizations(); +} + +void TimeEngine::tzConfigChanged() +{ + TimeSource *s = qobject_cast(containerForSource("Local")); + + if (s) { + s->setTimeZone("Local"); + } + + updateAllSources(); +} + +QStringList TimeEngine::sources() const +{ + QStringList timezones(KSystemTimeZones::zones().keys()); + timezones << "Local"; + return timezones; +} + +bool TimeEngine::sourceRequestEvent(const QString &name) +{ + addSource(new TimeSource(name, this)); + return true; +} + +bool TimeEngine::updateSourceEvent(const QString &tz) +{ + TimeSource *s = qobject_cast(containerForSource(tz)); + + if (s) { + s->updateTime(); + scheduleSourcesUpdated(); + return true; + } + + return false; +} + +K_EXPORT_PLASMA_DATAENGINE(time, TimeEngine) + +#include "timeengine.moc" diff --git a/plasma/generic/dataengines/time/timeengine.h b/plasma/generic/dataengines/time/timeengine.h new file mode 100644 index 00000000..f2e1e469 --- /dev/null +++ b/plasma/generic/dataengines/time/timeengine.h @@ -0,0 +1,52 @@ +/* + * Copyright 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TIMEENGINE_H +#define TIMEENGINE_H + +#include + +/** + * This engine provides the current date and time for a given + * timezone. Optionally it can also provide solar position info. + * + * "Local" is a special source that is an alias for the current + * timezone. + */ +class TimeEngine : public Plasma::DataEngine +{ + Q_OBJECT + + public: + TimeEngine(QObject *parent, const QVariantList &args); + ~TimeEngine(); + + void init(); + QStringList sources() const; + + protected: + bool sourceRequestEvent(const QString &name); + bool updateSourceEvent(const QString &source); + + protected Q_SLOTS: + void clockSkewed(); // call when system time changed and all clocks should be updated + void tzConfigChanged(); +}; + +#endif // TIMEENGINE_H diff --git a/plasma/generic/dataengines/time/timesource.cpp b/plasma/generic/dataengines/time/timesource.cpp new file mode 100644 index 00000000..fb3339ba --- /dev/null +++ b/plasma/generic/dataengines/time/timesource.cpp @@ -0,0 +1,259 @@ +/* + * Copyright 2009 Aaron Seigo + * + * Moon Phase: + * Copyright 1998,2000 Stephan Kulow + * Copyright 2009 by Davide Bettio + * + * Solar position: + * Copyright (C) 2009 Petri Damsten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "timesource.h" + +#include + +#include +#include + +#include "solarsystem.h" + +//timezone is defined in msvc +#ifdef timezone +#undef timezone +#endif + +TimeSource::TimeSource(const QString &name, QObject *parent) + : Plasma::DataContainer(parent), + m_offset(0), + m_latitude(0), + m_longitude(0), + m_sun(0), + m_moon(0), + m_moonPosition(false), + m_solarPosition(false), + m_local(false) +{ + setObjectName(name); + setTimeZone(parseName(name)); +} + +void TimeSource::setTimeZone(const QString &tz) +{ + m_tzName = tz; + m_local = m_tzName == I18N_NOOP("Local"); + if (m_local) { + m_tzName = KSystemTimeZones::local().name(); + } + + const QString trTimezone = i18n(m_tzName.toUtf8()); + setData(I18N_NOOP("Timezone"), trTimezone); + + const QStringList tzParts = trTimezone.split('/', QString::SkipEmptyParts); + if (tzParts.count() == 1) { + // no '/' so just set it as the city + setData(I18N_NOOP("Timezone City"), trTimezone); + } else { + setData(I18N_NOOP("Timezone Continent"), tzParts.value(0)); + setData(I18N_NOOP("Timezone City"), tzParts.value(1)); + } + + updateTime(); +} + +TimeSource::~TimeSource() +{ + // First delete the moon, that does not delete the Sun, and then the Sun + // If the Sun is deleted before the moon, the moon has a invalid pointer + // to where the Sun was pointing. + delete m_moon; + delete m_sun; +} + +void TimeSource::updateTime() +{ + KTimeZone tz; + if (m_local) { + tz = KSystemTimeZones::local(); + } else { + tz = KSystemTimeZones::zone(m_tzName); + if (!tz.isValid()) { + tz = KSystemTimeZones::local(); + } + } + + int offset = tz.currentOffset(); + if (m_offset != offset) { + m_offset = offset; + setData(I18N_NOOP("Offset"), m_offset); + } + + QDateTime dt = m_userDateTime ? data()["DateTime"].toDateTime() + : KDateTime::currentDateTime(tz).dateTime(); + + if (m_solarPosition || m_moonPosition) { + const QDate prev = data()["Date"].toDate(); + const bool updateDailies = prev != dt.date(); + + if (m_solarPosition) { + if (updateDailies) { + addDailySolarPositionData(dt); + } + + addSolarPositionData(dt); + } + + if (m_moonPosition) { + if (updateDailies) { + addDailyMoonPositionData(dt); + } + + addMoonPositionData(dt); + } + } + + if (!m_userDateTime) { + setData(I18N_NOOP("Time"), dt.time()); + setData(I18N_NOOP("Date"), dt.date()); + setData(I18N_NOOP("DateTime"), dt); + } +} + +QString TimeSource::parseName(const QString &name) +{ + m_userDateTime = false; + if (!name.contains('|')) { + // the simple case where it's just a timezone request + return name; + } + + // the various keys we recognize + static const QString latitude = I18N_NOOP("Latitude"); + static const QString longitude = I18N_NOOP("Longitude"); + static const QString solar = I18N_NOOP("Solar"); + static const QString moon = I18N_NOOP("Moon"); + static const QString datetime = I18N_NOOP("DateTime"); + + // now parse out what we got handed in + const QStringList list = name.split('|', QString::SkipEmptyParts); + + // set initial values for latitude and longitude, if available + const KTimeZone timezone = ((list.at(0) == I18N_NOOP("Local")) ? KSystemTimeZones::local() : KSystemTimeZones::zone(list.at(0))); + + if (timezone.isValid() && timezone.latitude() != KTimeZone::UNKNOWN) { + m_latitude = timezone.latitude(); + m_longitude = timezone.longitude(); + } + + const int listSize = list.size(); + for (int i = 1; i < listSize; ++i) { + const QString arg = list[i]; + const int n = arg.indexOf('='); + + if (n != -1) { + const QString key = arg.mid(0, n); + const QString value = arg.mid(n + 1); + + if (key == latitude) { + m_latitude = value.toDouble(); + } else if (key == longitude) { + m_longitude = value.toDouble(); + } else if (key == datetime) { + QDateTime dt = QDateTime::fromString(value, Qt::ISODate); + if (dt.isValid()) { + setData(I18N_NOOP("DateTime"), dt); + setData(I18N_NOOP("Date"), dt.date()); + setData(I18N_NOOP("Time"), dt.time()); + m_userDateTime = true; + } + } + } else if (arg == solar) { + m_solarPosition = true; + } else if (arg == moon) { + m_moonPosition = true; + } + } + + // timezone is first item ... + return list.at(0); +} + +Sun* TimeSource::sun() +{ + if (!m_sun) { + m_sun = new Sun(); + } + m_sun->setPosition(m_latitude, m_longitude); + return m_sun; +} + +Moon* TimeSource::moon() +{ + if (!m_moon) { + m_moon = new Moon(sun()); + } + m_moon->setPosition(m_latitude, m_longitude); + return m_moon; +} + +void TimeSource::addMoonPositionData(const QDateTime &dt) +{ + Moon* m = moon(); + m->calcForDateTime(dt, m_offset); + setData("Moon Azimuth", m->azimuth()); + setData("Moon Zenith", 90 - m->altitude()); + setData("Moon Corrected Elevation", m->calcElevation()); + setData("MoonPhaseAngle", m->phase()); +} + +void TimeSource::addDailyMoonPositionData(const QDateTime &dt) +{ + Moon* m = moon(); + QList< QPair > times = m->timesForAngles( + QList() << -0.833, dt, m_offset); + setData("Moonrise", times[0].first); + setData("Moonset", times[0].second); + m->calcForDateTime(QDateTime(dt.date(), QTime(12,0)), m_offset); + setData("MoonPhase", int(m->phase() / 360.0 * 29.0)); +} + +void TimeSource::addSolarPositionData(const QDateTime &dt) +{ + Sun* s = sun(); + s->calcForDateTime(dt, m_offset); + setData("Azimuth", s->azimuth()); + setData("Zenith", 90.0 - s->altitude()); + setData("Corrected Elevation", s->calcElevation()); +} + +void TimeSource::addDailySolarPositionData(const QDateTime &dt) +{ + Sun* s = sun(); + QList< QPair > times = s->timesForAngles( + QList() << -0.833 << -6.0 << -12.0 << -18.0, dt, m_offset); + + setData("Sunrise", times[0].first); + setData("Sunset", times[0].second); + setData("Civil Dawn", times[1].first); + setData("Civil Dusk", times[1].second); + setData("Nautical Dawn", times[2].first); + setData("Nautical Dusk", times[2].second); + setData("Astronomical Dawn", times[3].first); + setData("Astronomical Dusk", times[3].second); +} + diff --git a/plasma/generic/dataengines/time/timesource.h b/plasma/generic/dataengines/time/timesource.h new file mode 100644 index 00000000..e733e45a --- /dev/null +++ b/plasma/generic/dataengines/time/timesource.h @@ -0,0 +1,62 @@ +/* + * Copyright 2009 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TIMESOURCE_H +#define TIMESOURCE_H + +#include + +#include + +class Sun; +class Moon; + +class TimeSource : public Plasma::DataContainer +{ + Q_OBJECT + +public: + explicit TimeSource(const QString &name, QObject *parent = 0); + ~TimeSource(); + void setTimeZone(const QString &name); + void updateTime(); + +private: + QString parseName(const QString &name); + void addMoonPositionData(const QDateTime &dt); + void addDailyMoonPositionData(const QDateTime &dt); + void addSolarPositionData(const QDateTime &dt); + void addDailySolarPositionData(const QDateTime &dt); + Sun* sun(); + Moon* moon(); + + QString m_tzName; + int m_offset; + double m_latitude; + double m_longitude; + Sun *m_sun; + Moon *m_moon; + bool m_moonPosition : 1; + bool m_solarPosition : 1; + bool m_userDateTime : 1; + bool m_local : 1; +}; + +#endif + diff --git a/plasma/generic/dataengines/weather/CMakeLists.txt b/plasma/generic/dataengines/weather/CMakeLists.txt new file mode 100644 index 00000000..57038a51 --- /dev/null +++ b/plasma/generic/dataengines/weather/CMakeLists.txt @@ -0,0 +1,7 @@ +ADD_SUBDIRECTORY(ions) + +SET(weather_SRCS weatherengine.cpp) +kde4_add_plugin(plasma_engine_weather ${weather_SRCS}) +TARGET_LINK_LIBRARIES (plasma_engine_weather ${KDE4_KIO_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_PLASMA_LIBS} weather_ion) +INSTALL (TARGETS plasma_engine_weather DESTINATION ${PLUGIN_INSTALL_DIR}) +INSTALL (FILES plasma-dataengine-weather.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/dataengines/weather/Messages.sh b/plasma/generic/dataengines/weather/Messages.sh new file mode 100755 index 00000000..a0b026d9 --- /dev/null +++ b/plasma/generic/dataengines/weather/Messages.sh @@ -0,0 +1,10 @@ +#! /usr/bin/env bash +for file in ions/data/*.dat +do + awk -F'|' '$0 ~ /\|/ { + print "// i18n: file: '`basename $file`':"NR; + printf("i18nc(\"%s\", \"%s\");\n", $1, $2) + }' $file >> rc.cpp +done + +$XGETTEXT `find . -name \*.cpp` -o $podir/plasma_engine_weather.pot diff --git a/plasma/generic/dataengines/weather/ions/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/CMakeLists.txt new file mode 100644 index 00000000..5e2a4ff3 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/CMakeLists.txt @@ -0,0 +1,27 @@ +# the Ion shared library +set (ionlib_SRCS ion.cpp) +kde4_add_library (weather_ion SHARED ${ionlib_SRCS}) +target_link_libraries (weather_ion ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) +target_link_libraries (weather_ion LINK_INTERFACE_LIBRARIES ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +set_target_properties(weather_ion PROPERTIES + VERSION 6.0.0 + SOVERSION 6 +) + +install (TARGETS weather_ion EXPORT kdeworkspaceLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) + +INSTALL (FILES ion.h + ion_export.h + DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/weather COMPONENT Devel) + +INSTALL (FILES includes/Ion + DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/Plasma/Weather COMPONENT Devel) + +# the individual ion plugins +add_subdirectory(bbcukmet) +add_subdirectory(envcan) +add_subdirectory(noaa) +add_subdirectory(wetter.com) +add_subdirectory(debianweather) + diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/bbcukmet/CMakeLists.txt new file mode 100644 index 00000000..476260c0 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/bbcukmet/CMakeLists.txt @@ -0,0 +1,8 @@ +SET (ion_bbcukmet_SRCS ion_bbcukmet.cpp) +kde4_add_plugin(ion_bbcukmet ${ion_bbcukmet_SRCS}) +target_link_libraries (ion_bbcukmet ${KDE4_SOLID_LIBS} weather_ion) + +INSTALL (FILES ion-bbcukmet.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +INSTALL (TARGETS ion_bbcukmet DESTINATION ${PLUGIN_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/ion-bbcukmet.desktop b/plasma/generic/dataengines/weather/ions/bbcukmet/ion-bbcukmet.desktop new file mode 100644 index 00000000..05b234b6 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/bbcukmet/ion-bbcukmet.desktop @@ -0,0 +1,158 @@ +[Desktop Entry] +Name=BBC Weather from UK MET Office +Name[ar]=الطقس BBC من مكتب الأرصاد الجوية البريطاني +Name[ast]=Meteoroloxía de la BBC de la Oficina meteorolóxica del Reinu Xuníu +Name[be@latin]=Nadvorje „BBC” ad „UK MET Office” +Name[bg]=Време от BBC (офис UK MET) +Name[bs]=Meteouslovi po Bi‑bi‑siju +Name[ca]=Meteorologia de la BBC des d'UK MET Office +Name[ca@valencia]=Meteorologia de la BBC des d'UK MET Office +Name[cs]=Počasí BBC z britského meteorologického úřadu +Name[csb]=Wiodro BBC z bura UK-MET +Name[da]=BBC Weather fra UK MET-kontoret +Name[de]=BBC-Wetter aus dem UK-MET-Büro +Name[el]=Καιρός του BBC από το γραφείο UK MET +Name[en_GB]=BBC Weather from UK MET Office +Name[eo]=BBC-vetero el UK-MET-oficejo +Name[es]=Meteorología de la BBC de la Oficina meteorológica del Reino Unido +Name[et]=BBC ilmateade Briti ilmateenistusest +Name[eu]=BBCren eguraldia UK MET Office-tik +Name[fi]=BBC:n säätiedot UK MET -toimistolta +Name[fr]=Météo de la BBC venant du « UK MET Office » +Name[fy]=BBC Weather fan UK MET kantoor +Name[ga]=Aimsir BBC ó Oifig UK MET +Name[gl]=Tempo da BBC desde a Oficina meteorolóxica do UK +Name[gu]=UK MET ઓફિસ તરફથી BBC હવામાન +Name[he]=BBC Weather מ־UK MET Office +Name[hi]=यूके एमईटी ऑफ़िस से बीबीसी मौसम +Name[hne]=यूके एमईटी आफिस से बीबीसी मौसम +Name[hr]=BBC vremenska prognoza iz UK MET ureda +Name[hu]=BBC időjárási adatok (UK MET) +Name[ia]=BBC Weather ex Officio UK MET +Name[id]=BBC Weather dari UK MET Office +Name[is]=BBC veður frá UK MET stofnuninni +Name[it]=Meteo BBC dall'ufficio meteorologico UK MET +Name[ja]=英国 Met Office の BBC Weather +Name[kk]=UK MET Оффистің BBC ауа райы болжамы +Name[km]=អាកាសធាតុ BBC ពី​ការិយាល័យ UK MET +Name[kn]=ಬಿಬಿಸಿ ಹವಾಮಾನ ವರದಿ (ಯುಕೆ ಪವನಶಾಸ್ತ್ರ (MET) ಕಛೇರಿಯಿಂದ) +Name[ko]=영국 MET 사무소의 BBC 날씨 +Name[lt]=BBC orai iš UK MET Office +Name[lv]=BBC Weather no UK MET Office +Name[mk]=BBC-временска прогноза од канцеларијата на UK MET +Name[ml]=യു കെ മെറ്റ് ഓഫീസില്‍ നിന്നുമുള്ള ബിബിസി കാലാവസ്ഥ +Name[mr]=UK MET ऑफिस पासून BBC हवामान +Name[nb]=BBC vær fra det britiske meteorologi-kontoret +Name[nds]=BBC-Weder vun't engelsche Wederkunn-Kontoor +Name[ne]=यूके एमइटी कार्यालयबाट बीबीसी मौसम +Name[nl]=BBC Weather van UK MET Office +Name[nn]=BBC-vêr frå UK MET Office +Name[or]=UK MET କାର୍ଯ୍ୟାଳୟରୁ BBC ପାଣିପାଗ +Name[pa]=UK MET ਆਫਿਸ ਤੋਂ BBC ਮੌਸਮ +Name[pl]=Pogoda BBC z biura UK MET +Name[pt]=Meteorologia da BBC do Escritório MET na GB +Name[pt_BR]=BBC Weather do escritório MET no Reino Unido +Name[ro]=Vremea BBC de la Biroul meteorologic britanic +Name[ru]=BBC Weather от UK MET Office +Name[se]=BBC-dálki UK MET Offices +Name[si]=UK MET කාර්‍යාලය වෙතින් BBC කාලගුණය +Name[sk]=Počasie BBC - UK MET Office +Name[sl]=BBC Weather iz UK MET Office +Name[sr]=Метеоуслови по Би‑би‑сију +Name[sr@ijekavian]=Метеоуслови по Би‑би‑сију +Name[sr@ijekavianlatin]=Meteouslovi po BBC‑u +Name[sr@latin]=Meteouslovi po BBC‑u +Name[sv]=BBC-väder från brittiska meteorologiska departementet +Name[ta]=BBC Weather from UK MET Office +Name[te]=UK MET కార్యాలయం నుండి BBC వాతావరణం +Name[tg]=BBC Weather от UK MET Office +Name[th]=พยากรณ์อากาศของ BBC จากสำนักงาน UK MET +Name[tr]=İngiltere MET Ofisi'nden BBC Hava Durumu +Name[ug]=UK MET ئىشخانىسى تەمىنلىگەن BBC ھاۋارايى ئۇچۇرى +Name[uk]=Погода BBC з метеорологічного офісу UK +Name[vi]=Thời tiết BBC từ Cơ quan MET UK +Name[wa]=Tins ki fwait BBC do UK MET Office +Name[x-test]=xxBBC Weather from UK MET Officexx +Name[zh_CN]=英国 MET 办公室提供的 BBC 天气报告 +Name[zh_TW]=BBC 天氣報告,從 UK MET 辦公室來 +Comment=XML Data from the UK MET Office +Comment[ar]=معلومات XML من مكتب الأرصاد الجوية البريطاني +Comment[ast]=Datos XML de la Oficina Meteorolóxica del Reinu Xuníu +Comment[be@latin]=Źviestki ŭ farmacie „XML” ad „UK MET Office” +Comment[bg]=XML данни от UK MET +Comment[bs]=IksML podaci Britanskog meteorološkog ofisa +Comment[ca]=Dades XML des d'UK MET Office +Comment[ca@valencia]=Dades XML des d'UK MET Office +Comment[cs]=XML data z britského meteorologického úřadu +Comment[csb]=XML-pòdôwczi z bura UK-MET +Comment[da]=XML-data fra UK MET-kontoret +Comment[de]=XML-Daten aus dem UK-MET-Büro +Comment[el]=Δεδομένα XML από το γραφείο UK MET +Comment[en_GB]=XML Data from the UK MET Office +Comment[eo]=XML-datumoj el la UK-MET-oficejo +Comment[es]=Datos XML de la Oficina Meteorológica del Reino Unido +Comment[et]=Briti ilmateenistuse XML-andmed +Comment[eu]=XML datuak UK MET Office-tik +Comment[fi]=XML-tietoa UK MET -toimistolta +Comment[fr]=Données météo au format XML provenant du « UK MET Office » +Comment[fy]=XML Data fan de UK MET kantoor +Comment[ga]=Sonraí XML ó Oifig UK MET +Comment[gl]=Datos XML da oficina meteorolóxica do UK +Comment[gu]=UK MET ઓફિસ તરફથી XML માહિતી +Comment[he]=מידע ב־XML מ־UK MET Office +Comment[hi]=यूके एमईटी ऑफ़िस से एक्सएमएल डाटा +Comment[hne]=यूके एमईटी आफिस से एक्सएमएल डाटा +Comment[hr]=XML podaci iz UK MET ureda +Comment[hu]=XML adatok a UK MET intézettől +Comment[ia]=Datos XML ex le Officio UK MET +Comment[id]=Data XML dari UK MET Office +Comment[is]=XML veðurgögn frá UK MET stofnuninni +Comment[it]=Dati XML dall'ufficio meteorologico UK MET +Comment[ja]=英国 Met Office の XML データ +Comment[kk]=UK MET Оффистің XML дерегі +Comment[km]=ទិន្នន័យ XML ពី​ការិយាល័យ UK MET +Comment[kn]=ಯುಕೆ ಪವನಶಾಸ್ತ್ರ ಕಛೇರಿ (MET) ಇಂದ XML ದತ್ತ +Comment[ko]=영국 MET 사무소의 XML 데이터 +Comment[lt]=XML duomenys iš UK MET Office +Comment[lv]=XML dati no UK MET Office +Comment[mk]=XML-податоци од канцеларијата на UK MET +Comment[ml]=യുകെ മെറ്റ് ഓഫീസില്‍ നിന്നുമുള്ള എക്സ്എംഎല്‍ ഡേറ്റാ +Comment[mr]=UK MET ऑफिस पासून XML माहिती +Comment[nb]=XML-data fra det britiske meteorologi-kontoret +Comment[nds]=XML-Daten vun't engelsche Wederkunn-Kontoor +Comment[ne]=यूके एमईटी कार्यालयबाट एक्सएमएल डेटा +Comment[nl]=XML-gegevens van UK MET Office +Comment[nn]=XML-data frå UK MET Office +Comment[or]=UK MET କାର୍ଯ୍ୟାଳୟରୁ XML ତଥ୍ୟ +Comment[pa]=UK MET ਆਫਿਸ ਤੋਂ XML ਡਾਟਾ +Comment[pl]=Dane XML z biura UK MET +Comment[pt]=Dados em XML do Escritório MET na GB +Comment[pt_BR]=Dados em XML do escritório MET no Reino Unido +Comment[ro]=Date XML de la Biroul meteorologic britanic +Comment[ru]=Данные в формате XML от UK MET Office +Comment[se]=XML-dáhtat UK MET Offices +Comment[si]=UK MET කාර්‍යාලය වෙතින් XML දත්ත +Comment[sk]=XML dáta z UK MET Office +Comment[sl]=Podatki XML iz UK MET Office +Comment[sr]=ИксМЛ подаци Британског метеоролошког офиса +Comment[sr@ijekavian]=ИксМЛ подаци Британског метеоролошког офиса +Comment[sr@ijekavianlatin]=XML podaci Britanskog meteorološkog ofisa +Comment[sr@latin]=XML podaci Britanskog meteorološkog ofisa +Comment[sv]=XML-data från brittiska meteorologiska departementet +Comment[ta]=XML Data from the UK MET Office +Comment[te]=UK MET కార్యాలయం నుండి XML డాటా +Comment[tg]=Маълумоти XML аз UK MET Office +Comment[th]=ข้อมูล XML จากสำนักงาน UK MET +Comment[tr]=İngiltere MET Ofisi'nden XML Verisi +Comment[ug]=UK MET ئىشخانىسى تەمىنلىگەن XML سانلىق-مەلۇمات ئۇچۇرى +Comment[uk]=Дані XML з метеорологічного офісу UK +Comment[wa]=Dinêyes XML då UK MET Office +Comment[x-test]=xxXML Data from the UK MET Officexx +Comment[zh_CN]=英国 MET 办公室提供的 XML 数据 +Comment[zh_TW]=從 UK MET 辦公室來的 XML 資料 +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-ParentApp=weatherengine +Type=Service +Icon=noneyet +X-KDE-Library=ion_bbcukmet +X-KDE-PluginInfo-Name=bbcukmet diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp new file mode 100644 index 00000000..0db0e3a2 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp @@ -0,0 +1,964 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for BBC's Weather from the UK Met Office */ + +#include "ion_bbcukmet.h" + +#include +#include + +// ctor, dtor +UKMETIon::UKMETIon(QObject *parent, const QVariantList &args) + : IonInterface(parent, args) + +{ + Q_UNUSED(args) +} + +UKMETIon::~UKMETIon() +{ + deleteForecasts(); +} + +void UKMETIon::reset() +{ + deleteForecasts(); + m_sourcesToReset = sources(); + updateAllSources(); +} + +void UKMETIon::deleteForecasts() +{ + // Destroy each forecast stored in a QVector + QHash::iterator + it = m_weatherData.begin(), + end = m_weatherData.end(); + for (; it != end; ++it) { + qDeleteAll(it.value().forecasts); + it.value().forecasts.clear(); + } +} + + +// Get the master list of locations to be parsed +void UKMETIon::init() +{ + m_timeEngine = dataEngine("time"); + setInitialized(true); +} + +QMap UKMETIon::setupDayIconMappings(void) const +{ +// ClearDay, FewCloudsDay, PartlyCloudyDay, Overcast, +// Showers, ScatteredShowers, Thunderstorm, Snow, +// FewCloudsNight, PartlyCloudyNight, ClearNight, +// Mist, NotAvailable + + QMap dayList; + dayList["sunny"] = ClearDay; + //dayList["sunny night"] = ClearNight; + dayList["clear"] = ClearDay; + dayList["clar sky"] = ClearDay; + dayList["sunny intervals"] = PartlyCloudyDay; + //dayList["sunny intervals night"] = ClearNight; + dayList["partly cloudy"] = PartlyCloudyDay; + dayList["cloudy"] = Overcast; + dayList["white cloud"] = Overcast; + dayList["grey cloud"] = Overcast; + //dayList["low level cloud"] = NotAvailable; + //dayList["medium level cloud"] = NotAvailable; + //dayList["sandstorm"] = NotAvailable; + dayList["drizzle"] = LightRain; + dayList["misty"] = Mist; + dayList["mist"] = Mist; + dayList["fog"] = Mist; + dayList["foggy"] = Mist; + dayList["tropical storm"] = Thunderstorm; + dayList["hazy"] = NotAvailable; + dayList["light shower"] = Showers; + dayList["light rain shower"] = Showers; + dayList["light showers"] = Showers; + dayList["light rain"] = Showers; + dayList["heavy rain"] = Rain; + dayList["heavy showers"] = Rain; + dayList["heavy shower"] = Rain; + dayList["heavy rain shower"] = Rain; + dayList["thundery shower"] = Thunderstorm; + dayList["thunder storm"] = Thunderstorm; + dayList["cloudy with sleet"] = RainSnow; + dayList["sleet shower"] = RainSnow; + dayList["sleet showers"] = RainSnow; + dayList["sleet"] = RainSnow; + dayList["cloudy with hail"] = Hail; + dayList["hail shower"] = Hail; + dayList["hail showers"] = Hail; + dayList["hail"] = Hail; + dayList["light snow"] = LightSnow; + dayList["light snow shower"] = Flurries; + dayList["light snow showers"] = Flurries; + dayList["cloudy with light snow"] = LightSnow; + dayList["heavy snow"] = Snow; + dayList["heavy snow shower"] = Snow; + dayList["heavy snow showers"] = Snow; + dayList["cloudy with heavy snow"] = Snow; + dayList["na"] = NotAvailable; + return dayList; +} + +QMap UKMETIon::setupNightIconMappings(void) const +{ + QMap nightList; + nightList["clear"] = ClearNight; + nightList["clear sky"] = ClearNight; + nightList["clear intervals"] = PartlyCloudyNight; + nightList["sunny intervals"] = PartlyCloudyDay; // it's not really sunny + nightList["sunny"] = ClearDay; + nightList["cloudy"] = Overcast; + nightList["white cloud"] = Overcast; + nightList["grey cloud"] = Overcast; + nightList["partly cloudy"] = PartlyCloudyNight; + nightList["drizzle"] = LightRain; + nightList["misty"] = Mist; + nightList["mist"] = Mist; + nightList["fog"] = Mist; + nightList["foggy"] = Mist; + nightList["tropical storm"] = Thunderstorm; + nightList["hazy"] = NotAvailable; + nightList["light shower"] = Showers; + nightList["light rain shower"] = Showers; + nightList["light showers"] = Showers; + nightList["light rain"] = Showers; + nightList["heavy rain"] = Rain; + nightList["heavy showers"] = Rain; + nightList["heavy shower"] = Rain; + nightList["heavy rain shower"] = Rain; + nightList["thundery shower"] = Thunderstorm; + nightList["thunder storm"] = Thunderstorm; + nightList["cloudy with sleet"] = NotAvailable; + nightList["sleet shower"] = NotAvailable; + nightList["sleet showers"] = NotAvailable; + nightList["sleet"] = NotAvailable; + nightList["cloudy with hail"] = Hail; + nightList["hail shower"] = Hail; + nightList["hail showers"] = Hail; + nightList["hail"] = Hail; + nightList["light snow"] = LightSnow; + nightList["light snow shower"] = Flurries; + nightList["light snow showers"] = Flurries; + nightList["cloudy with light snow"] = LightSnow; + nightList["heavy snow"] = Snow; + nightList["heavy snow shower"] = Snow; + nightList["heavy snow showers"] = Snow; + nightList["cloudy with heavy snow"] = Snow; + nightList["na"] = NotAvailable; + + return nightList; +} + +QMap const& UKMETIon::dayIcons(void) const +{ + static QMap const dval = setupDayIconMappings(); + return dval; +} + +QMap const& UKMETIon::nightIcons(void) const +{ + static QMap const nval = setupNightIconMappings(); + return nval; +} + +// Get a specific Ion's data +bool UKMETIon::updateIonSource(const QString& source) +{ + // We expect the applet to send the source in the following tokenization: + // ionname|validate|place_name - Triggers validation of place + // ionname|weather|place_name - Triggers receiving weather of place + + QStringList sourceAction = source.split('|'); + + // Guard: if the size of array is not 3 then we have bad data, return an error + if (sourceAction.size() < 3) { + setData(source, "validate", "bbcukmet|malformed"); + return true; + } + + if (sourceAction[1] == "validate" && sourceAction.size() >= 3) { + // Look for places to match + findPlace(sourceAction[2], source); + return true; + } else if (sourceAction[1] == "weather" && sourceAction.size() >= 3) { + if (sourceAction.count() >= 3) { + if (sourceAction[2].isEmpty()) { + setData(source, "validate", "bbcukmet|malformed"); + return true; + } + m_place[QString("bbcukmet|%1").arg(sourceAction[2])].XMLurl = sourceAction[3]; + getXMLData(QString("%1|%2").arg(sourceAction[0]).arg(sourceAction[2])); + return true; + } else { + return false; + } + } else { + setData(source, "validate", "bbcukmet|malformed"); + return true; + } + + return false; +} + +// Gets specific city XML data +void UKMETIon::getXMLData(const QString& source) +{ + foreach (const QString &fetching, m_obsJobList) { + if (fetching == source) { + // already getting this source and awaiting the data + return; + } + } + + KUrl url; + url = m_place[source].XMLurl; + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); // Disable displaying cookies + m_obsJobXml.insert(m_job, new QXmlStreamReader); + m_obsJobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(observation_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, SLOT(observation_slotJobFinished(KJob*))); + } +} + +// Parses city list and gets the correct city based on ID number +void UKMETIon::findPlace(const QString& place, const QString& source) +{ + KUrl url; + url = "http://news.bbc.co.uk/weather/util/search/SearchResultsNode.xhtml?&search=" + place + "®ion=world&startIndex=0&count=500"; + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); // Disable displaying cookies + m_jobHtml.insert(m_job, new QByteArray()); + m_jobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(setup_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, SLOT(setup_slotJobFinished(KJob*))); + +/* + // Handle redirects for direct hit places. + connect(m_job, SIGNAL(redirection(KIO::Job*,KUrl)), this, + SLOT(setup_slotRedirected(KIO::Job*,KUrl))); +*/ + } +} + +void UKMETIon::getFiveDayForecast(const QString& source) +{ + + KUrl xmlMap(m_place[source].forecastHTMLUrl); + + QString xmlPath = xmlMap.path(); + + int splitIDPos = xmlPath.lastIndexOf('/'); + QString stationID = xmlPath.midRef(splitIDPos + 1).toString(); + m_place[source].XMLforecastURL = "http://newsrss.bbc.co.uk/weather/forecast/" + stationID + "/Next3DaysRSS.xml" + xmlMap.query(); + KUrl url(m_place[source].XMLforecastURL); + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); // Disable displaying cookies + m_forecastJobXml.insert(m_job, new QXmlStreamReader); + m_forecastJobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(forecast_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, SLOT(forecast_slotJobFinished(KJob*))); + } +} + +void UKMETIon::readSearchHTMLData(const QString& source, const QByteArray& html) +{ + QTextStream stream(html.data()); + QString line; + QStringList tokens; + QString url; + QString tmp; + int flag = 0; + int counter = 2; + + // "

    Vitoria, Brazil

    " + QRegExp grabURL("/[a-z]+/[a-z]+/([0-9]+)(\\?[^\"]+)?"); + QRegExp grabPlace(">([^<]*[a-z()])"); // FIXME: It would be better to strip away the extra '>' + + while (!stream.atEnd()) { + line = stream.readLine(); + if (line.contains("

    ") > 0) { + flag = 1; + } + + if (line.contains("There are no forecasts matching") > 0) { + break; + } + + if (flag) { + + if (grabURL.indexIn(line.trimmed()) > 0) { + url = "http://newsrss.bbc.co.uk/weather/forecast/" + grabURL.cap(1) + "/ObservationsRSS.xml"; + if (grabURL.captureCount() > 1) { + url += grabURL.cap(2); + } + grabPlace.indexIn(line.trimmed()); + tmp = QString("bbcukmet|").append(grabPlace.cap(1)); + + // Duplicate places can exist + if (m_locations.contains(tmp)) { + tmp = QString("bbcukmet|").append(QString("%1 (#%2)").arg(grabPlace.cap(1)).arg(counter)); + counter++; + } + + m_place[tmp].XMLurl = url; + m_place[tmp].place = grabPlace.cap(1); + m_locations.append(tmp); + } + } + + if (line.contains("

    ") > 0) { + flag = 0; + } + } + + // I stream ok? + //if (stream.status() == QTextStream::Ok) { + //return true; + //} + + validate(source); +} + +// handle when no XML tag is found +void UKMETIon::parseUnknownElement(QXmlStreamReader& xml) const +{ + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + parseUnknownElement(xml); + } + } +} + +void UKMETIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + if (data.isEmpty() || !m_jobHtml.contains(job)) { + return; + } + + m_jobHtml[job]->append(data); +} + +void UKMETIon::setup_slotJobFinished(KJob *job) +{ + if (job->error() == 149) { + setData(m_jobList[job], "validate", QString("bbcukmet|timeout")); + disconnectSource(m_jobList[job], this); + m_jobList.remove(job); + delete m_jobHtml[job]; + m_jobHtml.remove(job); + return; + } + + // If Redirected, don't go to this routine + if (!m_locations.contains(QString("bbcukmet|%1").arg(m_jobList[job]))) { + QByteArray *reader = m_jobHtml.value(job); + if (reader) { + readSearchHTMLData(m_jobList[job], *reader); + } + } + m_jobList.remove(job); + delete m_jobHtml[job]; + m_jobHtml.remove(job); +} + +void UKMETIon::observation_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + QByteArray local = data; + if (data.isEmpty() || !m_obsJobXml.contains(job)) { + return; + } + + // Send to xml. + m_obsJobXml[job]->addData(local); +} + +void UKMETIon::observation_slotJobFinished(KJob *job) +{ + const QString source = m_obsJobList.value(job); + setData(source, Data()); + + QXmlStreamReader *reader = m_obsJobXml.value(job); + if (reader) { + readObservationXMLData(m_obsJobList[job], *reader); + } + + m_obsJobList.remove(job); + delete m_obsJobXml[job]; + m_obsJobXml.remove(job); + + if (m_sourcesToReset.contains(source)) { + m_sourcesToReset.removeAll(source); + emit forceUpdate(this, source); + } +} + +void UKMETIon::forecast_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + QByteArray local = data; + if (data.isEmpty() || !m_forecastJobXml.contains(job)) { + return; + } + + // Send to xml. + m_forecastJobXml[job]->addData(local); +} + +void UKMETIon::forecast_slotJobFinished(KJob *job) +{ + setData(m_forecastJobList[job], Data()); + QXmlStreamReader *reader = m_forecastJobXml.value(job); + if (reader) { + readFiveDayForecastXMLData(m_forecastJobList[job], *reader); + } + + m_forecastJobList.remove(job); + delete m_forecastJobXml[job]; + m_forecastJobXml.remove(job); +} + +void UKMETIon::parsePlaceObservation(const QString &source, WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "rss"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "rss") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "channel") { + parseWeatherChannel(source, data, xml); + } + } + } +} + +void UKMETIon::parsePlaceForecast(const QString &source, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "rss"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement() && xml.name() == "channel") { + parseWeatherForecast(source, xml); + } + } +} + +void UKMETIon::parseWeatherChannel(const QString& source, WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "channel"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "channel") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "title") { + data.stationName = xml.readElementText().split("Observations for")[1].trimmed(); + data.stationName.replace("United Kingdom", i18n("UK")); + data.stationName.replace("United States of America", i18n("USA")); + + } else if (xml.name() == "item") { + parseWeatherObservation(source, data, xml); + } else { + parseUnknownElement(xml); + } + } + } +} + +void UKMETIon::parseWeatherForecast(const QString& source, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "channel"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "channel") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "item") { + parseFiveDayForecast(source, xml); + } else { + parseUnknownElement(xml); + } + } + } +} + +void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "item"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "item") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "title") { + QString conditionString = xml.readElementText(); + + // Get the observation time and condition + int splitIndex = conditionString.lastIndexOf(':'); + QStringRef conditionData = conditionString.midRef(splitIndex + 1); // Include ':' + data.obsTime = conditionString.midRef(0, splitIndex).toString(); + + // Friday at 0200 GMT + m_dateFormat = QDateTime::fromString(data.obsTime.split("at")[1].trimmed(), "hhmm 'GMT'"); + data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); + data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); + + data.condition = conditionData.toString().split('.')[0].trimmed(); + + } else if (xml.name() == "link") { + m_place[source].forecastHTMLUrl = xml.readElementText(); + + } else if (xml.name() == "description") { + QString observeString = xml.readElementText(); + QStringList observeData = observeString.split(':'); +#ifdef __GNUC__ +#warning FIXME: We should make this use a QRegExp but I need some help here :) -spstarr +#endif + + data.temperature_C = observeData[1].split(QChar(176))[0].trimmed(); + + // Temperature might be not available + if (data.temperature_C.contains("N/A")) { + data.temperature_C = i18n("N/A"); + } + + data.windDirection = observeData[2].split(',')[0].trimmed(); + data.windSpeed_miles = observeData[3].split(',')[0].split(' ')[1].remove("mph"); + + data.humidity = observeData[4].split(',')[0].split(' ')[1]; + if (data.humidity.endsWith('%')) { + data.humidity.chop(1); + } + + data.pressure = observeData[5].split(',')[0].split(' ')[1].split("mb")[0]; + data.pressureTendency = observeData[5].split(',')[1].trimmed(); + + data.visibilityStr = observeData[6].trimmed(); + + } else if (xml.name() == "lat") { + const QString ordinate = xml.readElementText(); + data.latitude = ordinate.toDouble(); + } else if (xml.name() == "long") { + const QString ordinate = xml.readElementText(); + data.longitude = ordinate.toDouble(); + } else { + parseUnknownElement(xml); + } + } + } +} + +bool UKMETIon::readObservationXMLData(const QString& source, QXmlStreamReader& xml) +{ + WeatherData data; + bool haveObservation = false; + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "rss") { + parsePlaceObservation(source, data, xml); + haveObservation = true; + } else { + parseUnknownElement(xml); + } + } + + } + + if (!haveObservation) { + return false; + } + m_weatherData[source] = data; + + // Get the 5 day forecast info next. + getFiveDayForecast(source); + + return !xml.error(); +} + +bool UKMETIon::readFiveDayForecastXMLData(const QString& source, QXmlStreamReader& xml) +{ + bool haveFiveDay = false; + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "rss") { + parsePlaceForecast(source, xml); + haveFiveDay = true; + } else { + parseUnknownElement(xml); + } + } + } + if (!haveFiveDay) return false; + updateWeather(source); + return !xml.error(); +} + +void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "item"); + + // Flush out the old forecasts when updating. + m_weatherData[source].forecasts.clear(); + + WeatherData::ForecastInfo *forecast = new WeatherData::ForecastInfo; + QString line; + QString period; + QString summary; + QRegExp high("-?\\d+"); + QRegExp low("-?\\d+"); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.name() == "title") { + line = xml.readElementText().trimmed(); +#ifdef __GNUC__ +#warning FIXME: We should make this all use QRegExps in UKMETIon::parseFiveDayForecast() for forecast -spstarr +#endif + + period = line.split(',')[0].split(':')[0]; + summary = line.split(',')[0].split(':')[1].trimmed(); + high.indexIn(line.split(',')[1]); + low.indexIn(line.split(',')[2]); + + forecast->period = period; + forecast->iconName = getWeatherIcon(dayIcons(), summary.toLower()); + forecast->summary = i18nc("weather forecast", summary.toUtf8()); + kDebug() << "i18n summary string: " << qPrintable(forecast->summary); + forecast->tempHigh = high.cap(0).toInt(); + forecast->tempLow = low.cap(0).toInt(); + m_weatherData[source].forecasts.append(forecast); + forecast = new WeatherData::ForecastInfo; + } + } + delete forecast; +} + +void UKMETIon::validate(const QString& source) +{ + bool beginflag = true; + + if (!m_locations.count()) { + QStringList invalidPlace = source.split('|'); + if (m_place[QString("bbcukmet|%1").arg(invalidPlace[2])].place.isEmpty()) { + setData(source, "validate", QString("bbcukmet|invalid|multiple|%1").arg(invalidPlace[2])); + } + m_locations.clear(); + return; + } else { + QString placeList; + foreach(const QString &place, m_locations) { + if (beginflag) { + placeList.append(QString("%1|extra|%2").arg(place.split('|')[1]).arg(m_place[place].XMLurl)); + beginflag = false; + } else { + placeList.append(QString("|place|%1|extra|%2").arg(place.split('|')[1]).arg(m_place[place].XMLurl)); + } + } + if (m_locations.count() > 1) { + setData(source, "validate", QString("bbcukmet|valid|multiple|place|%1").arg(placeList)); + } else { + placeList[0] = placeList[0].toUpper(); + setData(source, "validate", QString("bbcukmet|valid|single|place|%1").arg(placeList)); + } + } + m_locations.clear(); +} + +void UKMETIon::updateWeather(const QString& source) +{ + QString weatherSource = source; + weatherSource.replace("bbcukmet|", "bbcukmet|weather|"); + weatherSource.append(QString("|%1").arg(m_place[source].XMLurl)); + + QMap dataFields; + QStringList fieldList; + QVector forecastList; + int i = 0; + + Plasma::DataEngine::Data data; + + data.insert("Place", place(source)); + data.insert("Station", station(source)); + data.insert("Observation Period", observationTime(source)); + data.insert("Current Conditions", i18nc("weather condition", condition(source).toUtf8())); + kDebug() << "i18n condition string: " << qPrintable(i18nc("weather condition", condition(source).toUtf8())); + + const double lati = periodLatitude(source); + const double longi = periodLongitude(source); + const Plasma::DataEngine::Data timeData = m_timeEngine->query( + QString("Local|Solar|Latitude=%1|Longitude=%2|DateTime=%3") + .arg(lati).arg(longi).arg(m_dateFormat.toString(Qt::ISODate))); + + // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display + if (timeData["Corrected Elevation"].toDouble() >= 0.0) { + //kDebug() << "Using daytime icons\n"; + data.insert("Condition Icon", getWeatherIcon(dayIcons(), condition(source))); + } else { + data.insert("Condition Icon", getWeatherIcon(nightIcons(), condition(source))); + } + + data.insert("Latitude", lati); + data.insert("Longitude", longi); + + dataFields = humidity(source); + data.insert("Humidity", dataFields["humidity"]); + data.insert("Humidity Field", dataFields["humidityUnit"]); + + data.insert("Visibility", visibility(source)); + + dataFields = temperature(source); + data.insert("Temperature", dataFields["temperature"]); + data.insert("Temperature Unit", dataFields["temperatureUnit"]); + + dataFields = pressure(source); + data.insert("Pressure", dataFields["pressure"]); + data.insert("Pressure Unit", dataFields["pressureUnit"]); + data.insert("Pressure Tendency", dataFields["pressureTendency"]); + + dataFields = wind(source); + data.insert("Wind Speed", dataFields["windSpeed"]); + data.insert("Wind Speed Unit", dataFields["windUnit"]); + data.insert("Wind Direction", dataFields["windDirection"]); + + // 5 Day forecast info + forecastList = forecasts(source); + + // Set number of forecasts per day/night supported + data.insert("Total Weather Days", m_weatherData[source].forecasts.size()); + + foreach(const QString &forecastItem, forecastList) { + fieldList = forecastItem.split('|'); + + data.insert(QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6") \ + .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[2]).arg(fieldList[3]) \ + .arg(fieldList[4]).arg(fieldList[5])); + i++; + } + + data.insert("Credit", i18n("Supported by backstage.bbc.co.uk / Data from UK MET Office")); + data.insert("Credit Url", m_place[source].forecastHTMLUrl); + + setData(weatherSource, data); +} + +QString UKMETIon::place(const QString& source) const +{ + return m_weatherData[source].stationName; +} + +QString UKMETIon::station(const QString& source) const +{ + return m_weatherData[source].stationName; +} + +QString UKMETIon::observationTime(const QString& source) const +{ + return m_weatherData[source].obsTime; +} + +int UKMETIon::periodHour(const QString& source) const +{ + return m_weatherData[source].iconPeriodHour; +} + +int UKMETIon::periodMinute(const QString& source) const +{ + return m_weatherData[source].iconPeriodMinute; +} + +double UKMETIon::periodLatitude(const QString& source) const +{ + return m_weatherData[source].latitude; +} + +double UKMETIon::periodLongitude(const QString& source) const +{ + return m_weatherData[source].longitude; +} + +QString UKMETIon::condition(const QString& source) const +{ + return (m_weatherData[source].condition); +} + +QMap UKMETIon::temperature(const QString& source) const +{ + QMap temperatureInfo; + + temperatureInfo.insert("temperature", QString(m_weatherData[source].temperature_C)); + temperatureInfo.insert("temperatureUnit", QString::number(KUnitConversion::Celsius)); + return temperatureInfo; +} + +QMap UKMETIon::wind(const QString& source) const +{ + QMap windInfo; + if (m_weatherData[source].windSpeed_miles == "N/A") { + windInfo.insert("windSpeed", i18n("N/A")); + windInfo.insert("windUnit", QString::number(KUnitConversion::NoUnit)); + } else { + windInfo.insert("windSpeed", QString(m_weatherData[source].windSpeed_miles)); + windInfo.insert("windUnit", QString::number(KUnitConversion::MilePerHour)); + } + if (m_weatherData[source].windDirection.isEmpty()) { + windInfo.insert("windDirection", i18n("N/A")); + } else { + windInfo.insert("windDirection", i18nc("wind direction", m_weatherData[source].windDirection.toUtf8())); + } + return windInfo; +} + +QMap UKMETIon::humidity(const QString& source) const +{ + QMap humidityInfo; + if (m_weatherData[source].humidity != "N/A") { + humidityInfo.insert("humidity", m_weatherData[source].humidity); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::Percent)); + } else { + humidityInfo.insert("humidity", i18n("N/A")); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::NoUnit)); + } + + return humidityInfo; +} + +QString UKMETIon::visibility(const QString& source) const +{ + return i18nc("visibility", m_weatherData[source].visibilityStr.toUtf8()); +} + +QMap UKMETIon::pressure(const QString& source) const +{ + QMap pressureInfo; + if (m_weatherData[source].pressure == "N/A") { + pressureInfo.insert("pressure", i18n("N/A")); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::NoUnit)); + pressureInfo.insert("pressureTendency", i18n("N/A")); + return pressureInfo; + } + + pressureInfo.insert("pressure", QString(m_weatherData[source].pressure)); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::Millibar)); + + pressureInfo.insert("pressureTendency", i18nc("pressure tendency", m_weatherData[source].pressureTendency.toUtf8())); + return pressureInfo; +} + +QVector UKMETIon::forecasts(const QString& source) +{ + QVector forecastData; + + for (int i = 0; i < m_weatherData[source].forecasts.size(); ++i) { + + if (m_weatherData[source].forecasts[i]->period.contains("Saturday")) { + m_weatherData[source].forecasts[i]->period.replace("Saturday", i18nc("Short for Saturday", "Sat")); + } + + if (m_weatherData[source].forecasts[i]->period.contains("Sunday")) { + m_weatherData[source].forecasts[i]->period.replace("Sunday", i18nc("Short for Sunday", "Sun")); + } + + if (m_weatherData[source].forecasts[i]->period.contains("Monday")) { + m_weatherData[source].forecasts[i]->period.replace("Monday", i18nc("Short for Monday", "Mon")); + } + + if (m_weatherData[source].forecasts[i]->period.contains("Tuesday")) { + m_weatherData[source].forecasts[i]->period.replace("Tuesday", i18nc("Short for Tuesday", "Tue")); + } + + if (m_weatherData[source].forecasts[i]->period.contains("Wednesday")) { + m_weatherData[source].forecasts[i]->period.replace("Wednesday", i18nc("Short for Wednesday", "Wed")); + } + + if (m_weatherData[source].forecasts[i]->period.contains("Thursday")) { + m_weatherData[source].forecasts[i]->period.replace("Thursday", i18nc("Short for Thursday", "Thu")); + } + if (m_weatherData[source].forecasts[i]->period.contains("Friday")) { + m_weatherData[source].forecasts[i]->period.replace("Friday", i18nc("Short for Friday", "Fri")); + } + + forecastData.append(QString("%1|%2|%3|%4|%5|%6") \ + .arg(m_weatherData[source].forecasts[i]->period) \ + .arg(m_weatherData[source].forecasts[i]->iconName) \ + .arg(m_weatherData[source].forecasts[i]->summary) \ + .arg(m_weatherData[source].forecasts[i]->tempHigh) \ + .arg(m_weatherData[source].forecasts[i]->tempLow) \ + .arg("N/U")); + //.arg(m_weatherData[source].forecasts[i]->windSpeed) + //arg(m_weatherData[source].forecasts[i]->windDirection)); + } + + return forecastData; +} + +#include "ion_bbcukmet.moc" diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h new file mode 100644 index 00000000..11dce328 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.h @@ -0,0 +1,178 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for BBC Weather from UKMET Office */ + +#ifndef ION_BBCUKMET_H +#define ION_BBCUKMET_H + +#include +#include + +#include "../ion.h" +#include "../dataengineconsumer.h" + +class KJob; +namespace KIO +{ + class Job; + class TransferJob; +} + +class WeatherData +{ + +public: + QString place; + QString stationName; + // Current observation information. + QString obsTime; + int iconPeriodHour; + int iconPeriodMinute; + double longitude; + double latitude; + + QString condition; + QString conditionIcon; + QString temperature_C; + QString windDirection; + QString windSpeed_miles; + QString humidity; + QString pressure; + QString pressureTendency; + QString visibilityStr; + + // Five day forecast + struct ForecastInfo { + QString period; + QString iconName; + QString summary; + int tempHigh; + int tempLow; + int windSpeed; + QString windDirection; + }; + + // 5 day Forecast + QVector forecasts; +}; + +class KDE_EXPORT UKMETIon : public IonInterface, public Plasma::DataEngineConsumer +{ + Q_OBJECT + +public: + UKMETIon(QObject *parent, const QVariantList &args); + ~UKMETIon(); + void init(); // Setup the city location, fetching the correct URL name. + bool updateIonSource(const QString& source); + void updateWeather(const QString& source); + + QString place(const QString& source) const; + QString station(const QString& source) const; + QString observationTime(const QString& source) const; + //bool night(const QString& source) const; + int periodHour(const QString& source) const; + int periodMinute(const QString& source) const; + double periodLatitude(const QString& source) const; + double periodLongitude(const QString& source) const; + QString condition(const QString& source) const; + QMap temperature(const QString& source) const; + QMap wind(const QString& source) const; + QMap humidity(const QString& source) const; + QString visibility(const QString& source) const; + QMap pressure(const QString& source) const; + QVector forecasts(const QString& source); + +public Q_SLOTS: + virtual void reset(); + +protected Q_SLOTS: + void setup_slotDataArrived(KIO::Job *, const QByteArray &); + void setup_slotJobFinished(KJob *); + //void setup_slotRedirected(KIO::Job *, const KUrl &url); + void observation_slotDataArrived(KIO::Job *, const QByteArray &); + void observation_slotJobFinished(KJob *); + void forecast_slotDataArrived(KIO::Job *, const QByteArray &); + void forecast_slotJobFinished(KJob *); + +private: + /* UKMET Methods - Internal for Ion */ + + QMap setupDayIconMappings(void) const; + QMap setupNightIconMappings(void) const; + + QMap const& nightIcons(void) const; + QMap const& dayIcons(void) const; + + // Load and Parse the place search XML listings + void findPlace(const QString& place, const QString& source); + void validate(const QString& source); // Sync data source with Applet + void getFiveDayForecast(const QString& source); + void getXMLData(const QString& source); + void readSearchHTMLData(const QString& source, const QByteArray& html); + bool readFiveDayForecastXMLData(const QString& source, QXmlStreamReader& xml); + void parseSearchLocations(const QString& source, QXmlStreamReader& xml); + + // Observation parsing methods + bool readObservationXMLData(const QString& source, QXmlStreamReader& xml); + void parsePlaceObservation(const QString& source, WeatherData& data, QXmlStreamReader& xml); + void parseWeatherChannel(const QString& source, WeatherData& data, QXmlStreamReader& xml); + void parseWeatherObservation(const QString& source, WeatherData& data, QXmlStreamReader& xml); + void parseFiveDayForecast(const QString& source, QXmlStreamReader& xml); + void parsePlaceForecast(const QString& source, QXmlStreamReader& xml); + void parseWeatherForecast(const QString& source, QXmlStreamReader& xml); + void parseUnknownElement(QXmlStreamReader& xml) const; + + void deleteForecasts(); + + struct XMLMapInfo { + QString place; + QString XMLurl; + QString forecastHTMLUrl; + QString XMLforecastURL; + }; + + // Key dicts + QHash m_place; + QVector m_locations; + + // Weather information + QHash m_weatherData; + + // Store KIO jobs - Search list + QMap m_jobHtml; + QMap m_jobList; + + QMap m_obsJobXml; + QMap m_obsJobList; + + QMap m_forecastJobXml; + QMap m_forecastJobList; + + KIO::TransferJob *m_job; + Plasma::DataEngine *m_timeEngine; + + QDateTime m_dateFormat; + QStringList m_sourcesToReset; +}; + +K_EXPORT_PLASMA_DATAENGINE(bbcukmet, UKMETIon) + +#endif diff --git a/plasma/generic/dataengines/weather/ions/data/bbcukmet_i18n.dat b/plasma/generic/dataengines/weather/ions/data/bbcukmet_i18n.dat new file mode 100644 index 00000000..27a4103c --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/data/bbcukmet_i18n.dat @@ -0,0 +1,118 @@ +weather condition|clear sky +weather condition|clear +weather condition|clear intervals +weather condition|clear sky +weather condition|cloudy +weather condition|cloudy with hail +weather condition|cloudy with heavy snow +weather condition|cloudy with light snow +weather condition|cloudy with sleet +weather condition|drizzle +weather condition|fog +weather condition|foggy +weather condition|grey cloud +weather condition|hail +weather condition|hail shower +weather condition|hail showers +weather condition|hazy +weather condition|heavy rain +weather condition|heavy rain shower +weather condition|heavy shower +weather condition|heavy showers +weather condition|heavy snow +weather condition|heavy snow shower +weather condition|heavy snow showers +weather condition|light rain +weather condition|light rain shower +weather condition|light shower +weather condition|light showers +weather condition|light snow +weather condition|light snow shower +weather condition|light snow showers +weather condition|mist +weather condition|misty +weather condition|N/A +weather condition|na +weather condition|partly cloudy +weather condition|sandstorm +weather condition|weather condition|sleet +weather condition|sleet +weather condition|sleet shower +weather condition|sleet showers +weather condition|sunny +weather condition|sunny intervals +weather condition|thunder storm +weather condition|thundery shower +weather condition|tropical storm +weather condition|white cloud +weather forecast|clear sky +weather forecast|clear +weather forecast|clear intervals +weather forecast|clear sky +weather forecast|cloudy +weather forecast|cloudy with hail +weather forecast|cloudy with heavy snow +weather forecast|cloudy with light snow +weather forecast|cloudy with sleet +weather forecast|drizzle +weather forecast|fog +weather forecast|foggy +weather forecast|grey cloud +weather forecast|hail +weather forecast|hail shower +weather forecast|hail showers +weather forecast|hazy +weather forecast|heavy rain +weather forecast|heavy rain shower +weather forecast|heavy shower +weather forecast|heavy showers +weather forecast|heavy snow +weather forecast|heavy snow shower +weather forecast|heavy snow showers +weather forecast|light rain +weather forecast|light rain shower +weather forecast|light shower +weather forecast|light showers +weather forecast|light snow +weather forecast|light snow shower +weather forecast|light snow showers +weather forecast|mist +weather forecast|misty +weather forecast|na +weather forecast|partly cloudy +weather forecast|sandstorm +weather forecast|sleet +weather forecast|sleet +weather forecast|sleet shower +weather forecast|sleet showers +weather forecast|sunny +weather forecast|sunny intervals +weather forecast|thunder storm +weather forecast|thundery shower +weather forecast|tropical storm +weather forecast|white cloud +wind direction|N +wind direction|NNE +wind direction|NE +wind direction|ENE +wind direction|E +wind direction|SSE +wind direction|SE +wind direction|ESE +wind direction|S +wind direction|NNW +wind direction|NW +wind direction|WNW +wind direction|W +wind direction|SSW +wind direction|SW +wind direction|WSW +wind direction|VR +visibility|Very good +visibility|Good +visibility|Moderate +visibility|Poor +visibility|Very poor +pressure tendency|rising +pressure tendency|falling +pressure tendency|no change diff --git a/plasma/generic/dataengines/weather/ions/data/envcan_i18n.dat b/plasma/generic/dataengines/weather/ions/data/envcan_i18n.dat new file mode 100644 index 00000000..28d9f913 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/data/envcan_i18n.dat @@ -0,0 +1,361 @@ +weather condition|N/A +weather condition|Blowing Snow +weather condition|Clear +weather condition|Cloudy +weather condition|Decreasing Cloud +weather condition|Distant Precipitation +weather condition|Drifting Snow +weather condition|Drizzle +weather condition|Dust +weather condition|Dust Devils +weather condition|Fog +weather condition|Fog Bank Near Station +weather condition|Fog Depositing Ice +weather condition|Fog Patches +weather condition|Freezing drizzle +weather condition|Freezing rain +weather condition|Funnel Cloud +weather condition|Hail +weather condition|Haze +weather condition|Heavy Blowing Snow +weather condition|Heavy Drifting Snow +weather condition|Heavy Drizzle +weather condition|Heavy Hail +weather condition|Heavy Mixed Rain and Drizzle +weather condition|Heavy Mixed Rain and Snow Shower +weather condition|Heavy Rain +weather condition|Heavy Rain and Snow +weather condition|Heavy Rainshower +weather condition|Heavy Snow +weather condition|Heavy Snow Pellets +weather condition|Heavy Snowshower +weather condition|Heavy Thunderstorm with Hail +weather condition|Heavy Thunderstorm with Rain +weather condition|Ice Crystals +weather condition|Ice Pellets +weather condition|Increasing Cloud +weather condition|Light Drizzle +weather condition|Light Freezing Drizzle +weather condition|Light Freezing Rain +weather condition|Light Rain +weather condition|Light Rainshower +weather condition|Light Snow +weather condition|Light Snow Pellets +weather condition|Light Snowshower +weather condition|Lightning Visible +weather condition|Mainly Clear +weather condition|Mainly Sunny +weather condition|Mist +weather condition|Mixed Rain and Drizzle +weather condition|Mixed Rain and Snow Shower +weather condition|Mostly Cloudy +weather condition|Not Reported +weather condition|Partly Cloudy +weather condition|Rain +weather condition|Rain and Snow +weather condition|Rainshower +weather condition|Recent Drizzle +weather condition|Recent Dust or Sand Storm +weather condition|Recent Fog +weather condition|Recent Freezing Precipitation +weather condition|Recent Hail +weather condition|Recent Rain +weather condition|Recent Rain and Snow +weather condition|Recent Rainshower +weather condition|Recent Snow +weather condition|Recent Snowshower +weather condition|Recent Thunderstorm +weather condition|Recent Thunderstorm with Hail +weather condition|Recent Thunderstorm with Heavy Hail +weather condition|Recent Thunderstorm with Heavy Rain +weather condition|Recent Thunderstorm with Rain +weather condition|Sand or Dust Storm +weather condition|Severe Sand or Dust Storm +weather condition|Shallow Fog +weather condition|Smoke +weather condition|Snow +weather condition|Snow Crystals +weather condition|Snow Grains +weather condition|Squalls +weather condition|Sunny +weather condition|Mainly Sunny +weather condition|Partly Cloudy +weather condition|Thunderstorm with Hail +weather condition|Thunderstorm with Rain +weather condition|Thunderstorm with Sand or Dust Storm +weather condition|Thunderstorm without Precipitation +weather condition|Tornado +weather forecast|A few clouds +weather forecast|A few flurries +weather forecast|A few flurries mixed with ice pellets +weather forecast|A few flurries or rain showers +weather forecast|A few flurries or thundershowers +weather forecast|A few rain showers or flurries +weather forecast|A few rain showers or wet flurries +weather forecast|A few showers +weather forecast|A few showers or drizzle +weather forecast|A few showers or thundershowers +weather forecast|A few showers or thunderstorms +weather forecast|A few thundershowers +weather forecast|A few thunderstorms +weather forecast|A few wet flurries +weather forecast|A few wet flurries or rain showers +weather forecast|A mix of sun and cloud +weather forecast|Blizzard +weather forecast|Chance of drizzle +weather forecast|Chance of drizzle mixed with freezing drizzle +weather forecast|Chance of drizzle mixed with rain +weather forecast|Chance of drizzle or rain +weather forecast|Chance of flurries +weather forecast|Chance of flurries at times heavy +weather forecast|Chance of flurries mixed with ice pellets +weather forecast|Chance of flurries or ice pellets +weather forecast|Chance of flurries or rain showers +weather forecast|Chance of flurries or thundershowers +weather forecast|Chance of freezing drizzle +weather forecast|Chance of freezing rain +weather forecast|Chance of freezing rain mixed with snow +weather forecast|Chance of freezing rain or rain +weather forecast|Chance of freezing rain or snow +weather forecast|Chance of light snow +weather forecast|Chance of light snow and blowing snow +weather forecast|Chance of light snow mixed with freezing drizzle +weather forecast|Chance of light snow mixed with ice pellets +weather forecast|Chance of light snow mixed with rain +weather forecast|Chance of light snow or freezing rain +weather forecast|Chance of light snow or ice pellets +weather forecast|Chance of light snow or rain +weather forecast|Chance of light wet snow +weather forecast|Chance of rain +weather forecast|Chance of rain at times heavy +weather forecast|Chance of rain mixed with snow +weather forecast|Chance of rain or drizzle +weather forecast|Chance of rain or freezing rain +weather forecast|Chance of rain or snow +weather forecast|Chance of rain showers or flurries +weather forecast|Chance of rain showers or wet flurries +weather forecast|Chance of severe thunderstorms +weather forecast|Chance of showers +weather forecast|Chance of showers at times heavy +weather forecast|Chance of showers at times heavy or thundershowers +weather forecast|Chance of showers at times heavy or thunderstorms +weather forecast|Chance of showers or drizzle +weather forecast|Chance of showers or thundershowers +weather forecast|Chance of showers or thunderstorms +weather forecast|Chance of snow +weather forecast|Chance of snow and blizzard +weather forecast|Chance of snow mixed with freezing drizzle +weather forecast|Chance of snow mixed with freezing rain +weather forecast|Chance of snow mixed with rain +weather forecast|Chance of snow or rain +weather forecast|Chance of snow squalls +weather forecast|Chance of thundershowers +weather forecast|Chance of thunderstorms +weather forecast|Chance of thunderstorms and possible hail +weather forecast|Chance of wet flurries +weather forecast|Chance of wet flurries at times heavy +weather forecast|Chance of wet flurries or rain showers +weather forecast|Chance of wet snow +weather forecast|Chance of wet snow mixed with rain +weather forecast|Chance of wet snow or rain +weather forecast|Clear +weather forecast|Clearing +weather forecast|Cloudy +weather forecast|Cloudy periods +weather forecast|Cloudy with sunny periods +weather forecast|Drizzle +weather forecast|Drizzle mixed with freezing drizzle +weather forecast|Drizzle mixed with rain +weather forecast|Drizzle or freezing drizzle +weather forecast|Drizzle or rain +weather forecast|Flurries +weather forecast|Flurries at times heavy +weather forecast|Flurries at times heavy or rain showers +weather forecast|Flurries mixed with ice pellets +weather forecast|Flurries or ice pellets +weather forecast|Flurries or rain showers +weather forecast|Flurries or thundershowers +weather forecast|Fog +weather forecast|Fog developing +weather forecast|Fog dissipating +weather forecast|Fog patches +weather forecast|Freezing drizzle +weather forecast|Freezing rain +weather forecast|Freezing rain mixed with ice pellets +weather forecast|Freezing rain mixed with rain +weather forecast|Freezing rain mixed with snow +weather forecast|Freezing rain or ice pellets +weather forecast|Freezing rain or rain +weather forecast|Freezing rain or snow +weather forecast|Ice fog +weather forecast|Ice fog developing +weather forecast|Ice fog dissipating +weather forecast|Ice pellet +weather forecast|Ice pellet mixed with freezing rain +weather forecast|Ice pellet mixed with snow +weather forecast|Ice pellet or freezing rain +weather forecast|Ice pellet or snow +weather forecast|Increasing cloudiness +weather forecast|Increasing clouds +weather forecast|Light snow +weather forecast|Light snow and blizzard +weather forecast|Light snow and blizzard and blowing snow +weather forecast|Light snow and blowing snow +weather forecast|Light snow mixed with freezing drizzle +weather forecast|Light snow mixed with freezing rain +weather forecast|Light snow mixed with ice pellets +weather forecast|Light snow mixed with rain +weather forecast|Light snow or freezing drizzle +weather forecast|Light snow or freezing rain +weather forecast|Light snow or ice pellets +weather forecast|Light snow or rain +weather forecast|Light wet snow +weather forecast|Light wet snow or rain +weather forecast|Local snow squalls +weather forecast|Near blizzard +weather forecast|Overcast +weather forecast|Periods of drizzle +weather forecast|Periods of drizzle mixed with freezing drizzle +weather forecast|Periods of drizzle mixed with rain +weather forecast|Periods of drizzle or freezing drizzle +weather forecast|Periods of drizzle or rain +weather forecast|Periods of freezing drizzle +weather forecast|Periods of freezing drizzle or drizzle +weather forecast|Periods of freezing drizzle or rain +weather forecast|Periods of freezing rain +weather forecast|Periods of freezing rain mixed with ice pellets +weather forecast|Periods of freezing rain mixed with rain +weather forecast|Periods of freezing rain mixed with snow +weather forecast|Periods of freezing rain or ice pellets +weather forecast|Periods of freezing rain or rain +weather forecast|Periods of freezing rain or snow +weather forecast|Periods of ice pellet +weather forecast|Periods of ice pellet mixed with freezing rain +weather forecast|Periods of ice pellet mixed with snow +weather forecast|Periods of ice pellet or freezing rain +weather forecast|Periods of ice pellet or snow +weather forecast|Periods of light snow +weather forecast|Periods of light snow and blizzard +weather forecast|Periods of light snow and blizzard and blowing snow +weather forecast|Periods of light snow and blowing snow +weather forecast|Periods of light snow mixed with freezing drizzle +weather forecast|Periods of light snow mixed with freezing rain +weather forecast|Periods of light snow mixed with ice pellets +weather forecast|Periods of light snow mixed with rain +weather forecast|Periods of light snow or freezing drizzle +weather forecast|Periods of light snow or freezing rain +weather forecast|Periods of light snow or ice pellets +weather forecast|Periods of light snow or rain +weather forecast|Periods of light wet snow +weather forecast|Periods of light wet snow mixed with rain +weather forecast|Periods of light wet snow or rain +weather forecast|Periods of rain +weather forecast|Periods of rain mixed with freezing rain +weather forecast|Periods of rain mixed with snow +weather forecast|Periods of rain or drizzle +weather forecast|Periods of rain or freezing rain +weather forecast|Periods of rain or snow +weather forecast|Periods of rain or thundershowers +weather forecast|Periods of rain or thunderstorms +weather forecast|Periods of snow +weather forecast|Periods of snow and blizzard +weather forecast|Periods of snow and blizzard and blowing snow +weather forecast|Periods of snow and blowing snow +weather forecast|Periods of snow mixed with freezing drizzle +weather forecast|Periods of snow mixed with freezing rain +weather forecast|Periods of snow mixed with ice pellets +weather forecast|Periods of snow mixed with rain +weather forecast|Periods of snow or freezing drizzle +weather forecast|Periods of snow or freezing rain +weather forecast|Periods of snow or ice pellets +weather forecast|Periods of snow or rain +weather forecast|Periods of wet snow +weather forecast|Periods of wet snow mixed with rain +weather forecast|Periods of wet snow or rain +weather forecast|Rain +weather forecast|Rain at times heavy +weather forecast|Rain at times heavy mixed with freezing rain +weather forecast|Rain at times heavy mixed with snow +weather forecast|Rain at times heavy or drizzle +weather forecast|Rain at times heavy or freezing rain +weather forecast|Rain at times heavy or snow +weather forecast|Rain at times heavy or thundershowers +weather forecast|Rain at times heavy or thunderstorms +weather forecast|Rain mixed with freezing rain +weather forecast|Rain mixed with snow +weather forecast|Rain or drizzle +weather forecast|Rain or freezing rain +weather forecast|Rain or snow +weather forecast|Rain or thundershowers +weather forecast|Rain or thunderstorms +weather forecast|Rain showers or flurries +weather forecast|Rain showers or wet flurries +weather forecast|Showers +weather forecast|Showers at times heavy +weather forecast|Showers at times heavy or thundershowers +weather forecast|Showers at times heavy or thunderstorms +weather forecast|Showers or drizzle +weather forecast|Showers or thundershowers +weather forecast|Showers or thunderstorms +weather forecast|Smoke +weather forecast|Snow +weather forecast|Snow and blizzard +weather forecast|Snow and blizzard and blowing snow +weather forecast|Snow and blowing snow +weather forecast|Snow at times heavy +weather forecast|Snow at times heavy and blizzard +weather forecast|Snow at times heavy and blowing snow +weather forecast|Snow at times heavy mixed with freezing drizzle +weather forecast|Snow at times heavy mixed with freezing rain +weather forecast|Snow at times heavy mixed with ice pellets +weather forecast|Snow at times heavy mixed with rain +weather forecast|Snow at times heavy or freezing rain +weather forecast|Snow at times heavy or ice pellets +weather forecast|Snow at times heavy or rain +weather forecast|Snow mixed with freezing drizzle +weather forecast|Snow mixed with freezing rain +weather forecast|Snow mixed with ice pellets +weather forecast|Snow mixed with rain +weather forecast|Snow or freezing drizzle +weather forecast|Snow or freezing rain +weather forecast|Snow or ice pellets +weather forecast|Snow or rain +weather forecast|Snow squalls +weather forecast|Sunny +weather forecast|Mainly Sunny +weather forecast|Sunny with cloudy periods +weather forecast|Thunderstorms +weather forecast|Thunderstorms and possible hail +weather forecast|Wet flurries +weather forecast|Wet flurries at times heavy +weather forecast|Wet flurries at times heavy or rain showers +weather forecast|Wet flurries or rain showers +weather forecast|Wet snow +weather forecast|Wet snow at times heavy +weather forecast|Wet snow at times heavy mixed with rain +weather forecast|Wet snow mixed with rain +weather forecast|Wet snow or rain +weather forecast|Windy +wind direction|N +wind direction|NNE +wind direction|NE +wind direction|ENE +wind direction|E +wind direction|SSE +wind direction|SE +wind direction|ESE +wind direction|S +wind direction|NNW +wind direction|NW +wind direction|WNW +wind direction|W +wind direction|SSW +wind direction|SW +wind direction|WSW +wind direction|VR +wind speed|Calm +wind speed|N/A +pressure tendency|rising +pressure tendency|falling +pressure tendency|steady +Trace diff --git a/plasma/generic/dataengines/weather/ions/data/noaa_i18n.dat b/plasma/generic/dataengines/weather/ions/data/noaa_i18n.dat new file mode 100644 index 00000000..db64ed9a --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/data/noaa_i18n.dat @@ -0,0 +1,359 @@ +weather condition|A Few Clouds +weather condition|A Few Clouds and Breezy +weather condition|A Few Clouds and Windy +weather condition|A Few Clouds with Haze +weather condition|Blowing Dust +weather condition|Blowing Sand +weather condition|Blowing Snow +weather condition|Blowing Snow in Vicinity +weather condition|Breezy +weather condition|Clear +weather condition|Clear and Breezy +weather condition|Clear with Haze +weather condition|Drizzle +weather condition|Drizzle Fog +weather condition|Drizzle Fog/Mist +weather condition|Drizzle Ice Pellets +weather condition|Drizzle Snow +weather condition|Dust +weather condition|Dust/Sand Whirls +weather condition|Dust/Sand Whirls in Vicinity +weather condition|Dust Storm +weather condition|Dust Storm in Vicinity +weather condition|Fair +weather condition|Fair and Breezy +weather condition|Fair and Windy +weather condition|Fair with Haze +weather condition|Fog +weather condition|Fog in Vicinity +weather condition|Fog/Mist +weather condition|Freezing Drizzle +weather condition|Freezing Drizzle in Vicinity +weather condition|Freezing Drizzle Rain +weather condition|Freezing Drizzle Snow +weather condition|Freezing Fog +weather condition|Freezing Fog in Vicinity +weather condition|Freezing Rain +weather condition|Freezing Rain in Vicinity +weather condition|Freezing Rain Rain +weather condition|Freezing Rain Snow +weather condition|Funnel Cloud +weather condition|Funnel Cloud in Vicinity +weather condition|Hail +weather condition|Hail Showers +weather condition|Haze +weather condition|Heavy Blowing Snow +weather condition|Heavy Drizzle +weather condition|Heavy Drizzle Fog +weather condition|Heavy Drizzle Fog/Mist +weather condition|Heavy Drizzle Ice Pellets +weather condition|Heavy Drizzle Snow +weather condition|Heavy Drizzle Snow +weather condition|Heavy Dust Storm +weather condition|Heavy Freezing Drizzle +weather condition|Heavy Freezing Drizzle Rain +weather condition|Heavy Freezing Drizzle Snow +weather condition|Heavy Freezing Fog +weather condition|Heavy Freezing Rain +weather condition|Heavy Freezing Rain Rain +weather condition|Heavy Freezing Rain Snow +weather condition|Heavy Ice Pellets +weather condition|Heavy Ice Pellets Drizzle +weather condition|Heavy Ice Pellets Rain +weather condition|Heavy Rain +weather condition|Heavy Rain Fog +weather condition|Heavy Rain Fog/Mist +weather condition|Heavy Rain Freezing Drizzle +weather condition|Heavy Rain Freezing Rain +weather condition|Heavy Rain Ice Pellets +weather condition|Heavy Rain Showers +weather condition|Heavy Rain Showers Fog/Mist +weather condition|Heavy Rain Snow +weather condition|Heavy Sand Storm +weather condition|Heavy Showers Rain +weather condition|Heavy Showers Rain Fog/Mist +weather condition|Heavy Showers Snow +weather condition|Heavy Showers Snow Fog +weather condition|Heavy Showers Snow Fog/Mist +weather condition|Heavy small Hail/Snow Pellets +weather condition|Heavy Snow +weather condition|Heavy Snow Blowing Snow +weather condition|Heavy Snow Fog +weather condition|Heavy Snow Fog/Mist +weather condition|Heavy Snow Freezing Drizzle +weather condition|Heavy Snow Freezing Rain +weather condition|Heavy Snow Grains +weather condition|Heavy Snow Low Drifting Snow +weather condition|Heavy Snow Rain +weather condition|Heavy Snow Showers +weather condition|Heavy Snow Showers Fog +weather condition|Heavy Snow Showers Fog/Mist +weather condition|Heavy Thunderstorm Rain +weather condition|Heavy Thunderstorm Rain Fog +weather condition|Heavy Thunderstorm Rain Fog and Windy +weather condition|Heavy Thunderstorm Rain Fog/Mist +weather condition|Heavy Thunderstorm Rain Hail +weather condition|Heavy Thunderstorm Rain Hail Fog +weather condition|Heavy Thunderstorm Rain Hail Fog/Hail +weather condition|Heavy Thunderstorm Rain Hail Haze +weather condition|Heavy Thunderstorm Rain Haze +weather condition|Heavy Thunderstorm Rain Small Hail/Snow Pellets +weather condition|Heavy Thunderstorm Snow +weather condition|Ice Crystals +weather condition|Ice Pellets +weather condition|Ice Pellets Drizzle +weather condition|Ice Pellets in Vicinity +weather condition|Ice Pellets Rain +weather condition|Light Drizzle +weather condition|Light Drizzle Fog +weather condition|Light Drizzle Fog/Mist +weather condition|Light Drizzle Ice Pellets +weather condition|Light Drizzle Snow +weather condition|Light Freezing Drizzle +weather condition|Light Freezing Drizzle Rain +weather condition|Light Freezing Drizzle Snow +weather condition|Light Freezing Fog +weather condition|Light Freezing Rain +weather condition|Light Freezing Rain Rain +weather condition|Light Freezing Rain Snow +weather condition|Light Ice Pellets +weather condition|Light Ice Pellets Drizzle +weather condition|Light Ice Pellets Rain +weather condition|Light Rain +weather condition|Light Rain and Breezy +weather condition|Light Rain Fog +weather condition|Light Rain Fog/Mist +weather condition|Light Rain Freezing Drizzle +weather condition|Light Rain Freezing Rain +weather condition|Light Rain Ice Pellets +weather condition|Light Rain Showers +weather condition|Light Rain Showers Fog/Mist +weather condition|Light Rain Snow +weather condition|Light Showers Rain +weather condition|Light Showers Rain Fog/Mist +weather condition|Light Showers Snow +weather condition|Light Showers Snow Fog +weather condition|Light Showers Snow Fog/Mist +weather condition|Light Small Hail/Snow Pellets +weather condition|Light Snow +weather condition|Light Snow Blowing Snow +weather condition|Light Snow Blowing Snow Fog/Mist +weather condition|Light Snow Drizzle +weather condition|Light Snow Fog +weather condition|Light Snow Fog/Mist +weather condition|Light Snow Freezing Drizzle +weather condition|Light Snow Freezing Rain +weather condition|Light Snow Grains +weather condition|Light Snow Low Drifting Snow +weather condition|Light Snow Rain +weather condition|Light Snow Showers +weather condition|Light Snow Showers Fog +weather condition|Light Snow Showers Fog/Mist +weather condition|Light Thunderstorm Rain +weather condition|Light Thunderstorm Rain Fog +weather condition|Light Thunderstorm Rain Fog/Mist +weather condition|Light Thunderstorm Rain Hail +weather condition|Light Thunderstorm Rain Hail Fog +weather condition|Light Thunderstorm Rain Hail Fog/Mist +weather condition|Light Thunderstorm Rain Hail Haze +weather condition|Light Thunderstorm Rain Haze +weather condition|Light Thunderstorm Rain Small Hail/Snow Pellets +weather condition|Light Thunderstorm Snow +weather condition|Low Drifting Dust +weather condition|Low Drifting Sand +weather condition|Low Drifting Snow +weather condition|Mostly Cloudy +weather condition|Mostly Cloudy and Breezy +weather condition|Mostly Cloudy and Windy +weather condition|Mostly Cloudy with Haze +weather condition|Overcast +weather condition|Overcast and Breezy +weather condition|Overcast and Windy +weather condition|Overcast with Haze +weather condition|Partial Fog +weather condition|Partial Fog in Vicinity +weather condition|Partly Cloudy +weather condition|Partly Cloudy and Breezy +weather condition|Partly Cloudy and Windy +weather condition|Partly Cloudy with Haze +weather condition|Patches of Fog +weather condition|Patches of Fog in Vicinity +weather condition|Rain Fog +weather condition|Rain Fog/Mist +weather condition|Rain Freezing Drizzle +weather condition|Rain Freezing Rain +weather condition|Rain Ice Pellets +weather condition|Rain Showers +weather condition|Rain Showers Fog/Mist +weather condition|Rain Showers in Vicinity +weather condition|Rain Showers in Vicinity Fog/Mist +weather condition|Rain Snow +weather condition|Sand +weather condition|Sand Storm +weather condition|Sand Storm in Vicinity +weather condition|Shallow Fog +weather condition|Shallow Fog in Vicinity +weather condition|Showers Hail +weather condition|Showers Ice Pellets +weather condition|Showers in Vicinity Fog +weather condition|Showers in Vicinity Snow +weather condition|Showers Rain +weather condition|Showers Rain Fog/Mist +weather condition|Showers Rain in Vicinity +weather condition|Showers Rain in Vicinity Fog/Mist +weather condition|Showers Snow +weather condition|Showers Snow Fog +weather condition|Showers Snow Fog/Mist +weather condition|Small Hail/Snow Pellets +weather condition|Smoke +weather condition|Snow +weather condition|Snow Blowing Snow +weather condition|Snow Drizzle +weather condition|Snow Fog +weather condition|Snow Fog/Mist +weather condition|Snow Freezing Drizzle +weather condition|Snow Freezing Rain +weather condition|Snow Grains +weather condition|Snow Low Drifting Snow +weather condition|Snow Rain +weather condition|Snow Showers +weather condition|Snow Showers Fog +weather condition|Snow Showers Fog/Mist +weather condition|Snow Showers in Vicinity +weather condition|Snow Showers in Vicinity Fog +weather condition|Snow Showers in Vicinity Fog/Mist +weather condition|Thunderstorm +weather condition|Thunderstorm Fog +weather condition|Thunderstorm Hail +weather condition|Thunderstorm Hail Fog +weather condition|Thunderstorm Haze in Vicinity +weather condition|Thunderstorm Haze in Vicinity Hail +weather condition|Thunderstorm Heavy Rain +weather condition|Thunderstorm Heavy Rain Fog +weather condition|Thunderstorm Heavy Rain Fog/Mist +weather condition|Thunderstorm Heavy Rain Hail +weather condition|Thunderstorm Heavy Rain Hail Fog +weather condition|Thunderstorm Heavy Rain Hail Fog/Mist +weather condition|Thunderstorm Heavy Rain Hail Haze +weather condition|Thunderstorm Heavy Rain Haze +weather condition|Thunderstorm Ice Pellets +weather condition|Thunderstorm in Vicinity +weather condition|Thunderstorm in Vicinity Fog +weather condition|Thunderstorm in Vicinity Fog/Mist +weather condition|Thunderstorm in Vicinity Hail +weather condition|Thunderstorm in Vicinity Hail Haze +weather condition|Thunderstorm in Vicinity Haze +weather condition|Thunderstorm Light Rain +weather condition|Thunderstorm Light Rain Fog +weather condition|Thunderstorm Light Rain Fog/Mist +weather condition|Thunderstorm Light Rain Hail +weather condition|Thunderstorm Light Rain Hail Fog +weather condition|Thunderstorm Light Rain Hail Fog/Mist +weather condition|Thunderstorm Light Rain Hail Haze +weather condition|Thunderstorm Light Rain Haze +weather condition|Thunderstorm Rain +weather condition|Thunderstorm Rain Fog/Mist +weather condition|Thunderstorm Rain Hail Fog/Mist +weather condition|Thunderstorm Rain Small Hail/Snow Pellets +weather condition|Thunderstorm Showers in Vicinity +weather condition|Thunderstorm Showers in Vicinity Hail +weather condition|Thunderstorm Small Hail/Snow Pellets +weather condition|Thunderstorm Snow +weather condition|Tornado/Water Spout +weather condition|Windy +weather condition|N/A +weather forecast|Ice Crystals +weather forecast|Volcanic Ash +weather forecast|Water Spout +weather forecast|Freezing Spray +weather forecast|Frost +weather forecast|Chance Thunderstorms +weather forecast|Thunderstorms Likely +weather forecast|Thunderstorms +weather forecast|Severe Tstms +weather forecast|Chance Snow/Sleet +weather forecast|Snow/Sleet Likely +weather forecast|Snow/Sleet +weather forecast|Chance Rain/Sleet +weather forecast|Rain/Sleet Likely +weather forecast|Rain/Sleet +weather forecast|Chance Rain/Freezing Rain +weather forecast|Rain/Freezing Rain Likely +weather forecast|Rain/Freezing Rain +weather forecast|Wintry Mix +weather forecast|Chance Freezing Drizzle +weather forecast|Freezing Drizzle Likely +weather forecast|Freezing Drizzle +weather forecast|Chance Freezing Rain +weather forecast|Freezing Rain Likely +weather forecast|Freezing Rain +weather forecast|Chance Rain/Snow +weather forecast|Rain/Snow Likely +weather forecast|Rain/Snow +weather forecast|Chance Snow +weather forecast|Snow Likely +weather forecast|Snow +weather forecast|Heavy Snow +weather forecast|Chance Flurries +weather forecast|Flurries Likely +weather forecast|Flurries +weather forecast|Chance Snow Showers +weather forecast|Snow Showers Likely +weather forecast|Snow Showers +weather forecast|Chance Snow Showers +weather forecast|Snow Showers Likely +weather forecast|Snow Showers +weather forecast|Chance Drizzle +weather forecast|Drizzle Likely +weather forecast|Drizzle +weather forecast|Chance Rain +weather forecast|Rain Likely +weather forecast|Rain +weather forecast|Heavy Rain +weather forecast|Chance Rain Showers +weather forecast|Rain Showers Likely +weather forecast|Rain Showers +weather forecast|Chance Rain Showers +weather forecast|Rain Showers Likely +weather forecast|Rain Showers +weather forecast|Sleet +weather forecast|Smoke +weather forecast|Freezing Fog +weather forecast|Ice Fog +weather forecast|Haze +weather forecast|Blowing Sand +weather forecast|Blowing Dust +weather forecast|Blowing Snow +weather forecast|Dense Fog +weather forecast|Fog +weather forecast|Windy +weather forecast|Blustery +weather forecast|Breezy +weather forecast|Cold +weather forecast|Hot +weather forecast|Cloudy +weather forecast|Mostly Cloudy +weather forecast|Partly Cloudy +weather forecast|Mostly Sunny +weather forecast|Sunny +weather forecast|Increasing Clouds +weather forecast|Becoming Cloudy +weather forecast|Clearing +weather forecast|Gradual Clearing +weather forecast|Clearing Late +weather forecast|Decreasing Clouds +weather forecast|Becoming Sunny +weather forecast|Clear +weather forecast|Mostly Clear +weather forecast|Chance Thunderstorms +weather forecast|Slight Chance Thunderstorms +wind direction|N +wind direction|NE +wind direction|S +wind direction|SW +wind direction|E +wind direction|SE +wind direction|W +wind direction|N +wind direction|VR +wind speed|Calm diff --git a/plasma/generic/dataengines/weather/ions/dataengineconsumer.h b/plasma/generic/dataengines/weather/ions/dataengineconsumer.h new file mode 100644 index 00000000..97b5358a --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/dataengineconsumer.h @@ -0,0 +1,66 @@ +/* + * Copyright 2005 by Aaron Seigo + * Copyright 2007 by Riccardo Iaconelli + * Copyright 2008 by Ménard Alexis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_DATAENGINECONSUMER_H +#define PLASMA_DATAENGINECONSUMER_H + +#include + +#include + +#include "plasma/dataenginemanager.h" + +namespace Plasma +{ + +class DataEngineConsumer +{ +public: + ~DataEngineConsumer() + { + foreach (const QString &engine, m_loadedEngines) { + DataEngineManager::self()->unloadEngine(engine); + } + } + + DataEngine *dataEngine(const QString &name) + { + if (m_loadedEngines.contains(name)) { + return DataEngineManager::self()->engine(name); + } + + DataEngine *engine = DataEngineManager::self()->loadEngine(name); + if (engine->isValid()) { + m_loadedEngines.insert(name); + } + + return engine; + } + +private: + QSet m_loadedEngines; +}; + +} // namespace Plasma + +#endif + + diff --git a/plasma/generic/dataengines/weather/ions/debianweather/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/debianweather/CMakeLists.txt new file mode 100644 index 00000000..5a36888c --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/debianweather/CMakeLists.txt @@ -0,0 +1,16 @@ +# Project Needs a name ofcourse +project(iondebianweather) + +# We add our source code here +set(karaboudjan_SRCS iondebianweather.cpp) + +# Now make sure all files get to the right place +kde4_add_plugin(ion_debianweather ${karaboudjan_SRCS}) +target_link_libraries(ion_debianweather weather_ion + ${QT_QTCORE_LIBRARY}) + +install(TARGETS ion_debianweather + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES ion-debianweather.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/dataengines/weather/ions/debianweather/ion-debianweather.desktop b/plasma/generic/dataengines/weather/ions/debianweather/ion-debianweather.desktop new file mode 100644 index 00000000..e1ffa57a --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/debianweather/ion-debianweather.desktop @@ -0,0 +1,110 @@ +[Desktop Entry] +Name=Debian Weather Service +Name[bg]=Метеорологична услуга на Debian +Name[bs]=NOAA‑ova nacionalna meteorološka služba +Name[ca]=Servei meteorològic de Debian +Name[ca@valencia]=Servei meteorològic de Debian +Name[cs]=Informační služba Debianu o počasí +Name[da]=Debian vejrtjeneste +Name[de]=Debian-Wetterdienst +Name[el]=Υπηρεσία καιρού Debian +Name[en_GB]=Debian Weather Service +Name[es]=Servicio de meteorología de Debian +Name[et]=Debiani ilmateenistus +Name[eu]=Debian-en eguraldi-zerbitzua +Name[fi]=Debianin sääpalvelu +Name[fr]=Service météo de Debian +Name[ga]=Seirbhís na hAimsire de chuid Debian +Name[gl]=Servizo meteorolóxico da Debian +Name[he]=שירות מזג האוויר של דביאן +Name[hr]=Debian Weather Service +Name[hu]=Debian időjárásjelző szolgálat +Name[ia]=Servicio Meteorologic de Debian +Name[is]=Debian veðurþjónusta +Name[it]=Servizio meteorologico Debian +Name[kk]=Debian ауа райы қызметі +Name[km]=សេវា​អាកាសធាតុ​របស់​ដេបៀន +Name[ko]=Debian 날씨 서비스 +Name[lt]=Debian orų tarnyba +Name[lv]=Debian laikapstākļu serviss +Name[mr]=डेबिअन हवामान सेवा +Name[nb]=Debian værtjeneste +Name[nds]=Debian-Wederdeenst +Name[nl]=Weerdienst van Debian +Name[pa]=ਡੇਬੀਅਨ ਮੌਸਮ ਸਰਵਿਸ +Name[pl]=Usługa pogody z Debiana +Name[pt]=Serviço Meteorológico da Debian +Name[pt_BR]=Serviço Meteorológico do Debian +Name[ro]=Servici meteo Debian +Name[ru]=Служба погоды Debian +Name[sk]=Debian Weather Service +Name[sl]=Debian Weather Service +Name[sr]=Дебијанова метеоролошка служба +Name[sr@ijekavian]=Дебијанова метеоролошка служба +Name[sr@ijekavianlatin]=Debianova meteorološka služba +Name[sr@latin]=Debianova meteorološka služba +Name[sv]=Debian vädertjänst +Name[tr]=Debian Hava Durumu Servisi +Name[ug]=Debian ھاۋارايى مۇلازىمىتى +Name[uk]=Служба погоди Debian +Name[vi]=Dịch vụ thời tiết Debian +Name[wa]=Siervice meteyo di Debian +Name[x-test]=xxDebian Weather Servicexx +Name[zh_CN]=Debian 天气服务 +Name[zh_TW]=Debian 天氣服務 +Comment=XML Data from edos.debian.net +Comment[bg]=XML данни от edos.debian.net +Comment[bs]=XML podaci sa edos.debian.net +Comment[ca]=Dades XML d'edos.debian.net +Comment[ca@valencia]=Dades XML d'edos.debian.net +Comment[cs]=XML data z edos.debian.net +Comment[da]=XML-data fra edos.debian.net +Comment[de]=XML-Daten von edos.debian.net +Comment[el]=XML δεδομένα από edos.debian.net +Comment[en_GB]=XML Data from edos.debian.net +Comment[es]=Datos XML de edos.debian.net +Comment[et]=XML-andmed edos.debian.net-ist +Comment[eu]=XML datuak edos.debian.net-etik +Comment[fi]=XML-tietoa osoitteesta edos.denian.net +Comment[fr]=Données XML provenant de « edos.debian.net » +Comment[ga]=Sonraí XML ó edos.debian.net +Comment[gl]=Datos XML de edos.debian.net +Comment[hr]=XML-podaci s edos.debian.net +Comment[hu]=XML-adatok az edos.debian.net-ről +Comment[ia]=Datos XML ex edos.debian.net +Comment[is]=XML gögn frá edos.debian.net +Comment[it]=Dati XML da edos.debian.net +Comment[kk]=edos.debian.net XML дерегі +Comment[km]=ទិន្ននិយ XML ពី edos.debian.net +Comment[ko]=edos.debian.net의 XML 데이터 +Comment[lt]=XML duomenys iš edos.debian.net +Comment[lv]=XML dati no edos.debian.net +Comment[mr]=edos.debian.net पासून XML डेटा +Comment[nb]=XML-data fra edos.debian.net +Comment[nds]=XML-Daten vun edos.debian.net +Comment[nl]=XML-gegevens van edos.debian.net +Comment[pl]=Dane XML z edos.debian.net +Comment[pt]=Dados em XML do edos.debian.net +Comment[pt_BR]=Dados em XML do edos.debian.net +Comment[ro]=Date XML de la edos.debian.net +Comment[ru]=Данные в формате XML от edos.debian.net +Comment[sk]=XML dáta z edos.debian.net +Comment[sl]=Podatki XML iz edos.debian.net +Comment[sr]=ИксМЛ подаци са edos.debian.net +Comment[sr@ijekavian]=ИксМЛ подаци са edos.debian.net +Comment[sr@ijekavianlatin]=XML podaci sa edos.debian.net +Comment[sr@latin]=XML podaci sa edos.debian.net +Comment[sv]=XML-data från edos.debian.net +Comment[tr]=edos.debian.net adresinden gelen XML Verisi +Comment[ug]=edos.debian.net تەمىنلىگەن XML سانلىق-مەلۇماتى +Comment[uk]=Дані XML з edos.debian.net +Comment[wa]=Dinêyes XML da edos.debian.net +Comment[x-test]=xxXML Data from edos.debian.netxx +Comment[zh_CN]=edos.debian.net 的 XML 数据 +Comment[zh_TW]=從 edos.debian.net 來的 XML 資料 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=debian +X-KDE-Library=ion_debianweather +X-KDE-PluginInfo-Name=DebianWeather +X-KDE-ParentApp=weatherengine diff --git a/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.cpp b/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.cpp new file mode 100644 index 00000000..9589d1c4 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.cpp @@ -0,0 +1,293 @@ +/* + Copyright (c) 2011 Sune Vuorela + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +*/ +#define QT_NO_CAST_FROM_ASCII + +#include "iondebianweather.h" + +#include +#include + +#include + +#include + +IonDebianWeather::IonDebianWeather(QObject*, const QVariantList&) : IonInterface(), m_ionname(QLatin1String("DebianWeather")) { + +} + +void IonDebianWeather::init() { + setInitialized(true); +} + +IonDebianWeather::~IonDebianWeather() { + cleanup(); +} + +void IonDebianWeather::reset() { + cleanup(); +} + +void IonDebianWeather::cleanup() { + Q_FOREACH(KJob* job, m_jobs.keys()) { + delete job; + } + m_jobs.clear(); +} + +IonDebianWeather::jobtype IonDebianWeather::toJobType(const QString& data) { + if(data==QLatin1String("validate")) { + return validate; + } + if(data==QLatin1String("weather")) { + return weather; + } + return unknown; +} + +QString IonDebianWeather::toString(IonDebianWeather::jobtype type) { + switch(type) { + case validate: + return QLatin1String("validate"); + break; + ;; + case weather: + return QLatin1String("weather"); + break; + ;; + case unknown: + ;; + } + return QLatin1String("unknown"); +} + +bool IonDebianWeather::updateIonSource(const QString& source) { + // We expect the applet to send the source in the following tokenization: + // ionname|validate|place_name - Triggers validation of place + // ionname|weather|place_name - Triggers receiving weather of place + QStringList tokens = source.split(QLatin1Char('|')); + + if(tokens.count()==3 && toJobType(tokens.at(1)) == validate) { + //validate, whatever that is. + QSharedPointer p(new locationdata()); + if (tokens.at(2).simplified().startsWith(QLatin1String("Debian"), Qt::CaseInsensitive)){ + p->source = source; + p->type = validate; + p->valid = true; + QStringList searchparts = tokens.at(2).simplified().split(QLatin1Char(' ')); + if(searchparts.size() > 1) { + QStringList components(searchparts); + components.pop_front(); + p->searchstring = components.join(QLatin1String(" ")); + } + findAllPlaces(p); + return true; + }else { + setData(source, + toString(validate), + QString::fromLatin1("%1|invalid|single|%2").arg(m_ionname).arg(tokens.at(2).simplified())); + return true; + } + return true; + } else if(tokens.count()==3 && toJobType(tokens.at(1))==weather) { + QSharedPointer p(new locationdata()); + parseLocation(tokens.at(2).simplified(),p); + if(p->valid) { + p->source = source; + p->type = weather; + startFetchData(p); + return true; + } else { + setData(source, toString(validate),QString::fromLatin1("%1|invalid|single|%2").arg(m_ionname).arg(tokens.at(2).simplified())); + return true; + } + } else { + setData(source,toString(validate),QString::fromLatin1("%1|malformed").arg(m_ionname)); + return true; + } + return false; +} + +void IonDebianWeather::parseLocation(QString location,QSharedPointer data) { + QStringList parts = location.split(QLatin1Char(' ')); + if(parts.size()==3 && parts.at(0)==QLatin1String("Debian")) { + data->suite=parts.at(1); + data->arch=parts.at(2); + data->valid=true; + } +} + +void IonDebianWeather::findAllPlaces(QSharedPointer< IonDebianWeather::locationdata > data) { + Q_ASSERT(data->type==validate); + QUrl url (QLatin1String("http://edos.debian.net/edos-debcheck/results/available.xml")); + KIO::TransferJob* job = KIO::get(url,KIO::NoReload,KIO::HideProgressInfo); + if(job) { + m_jobs[job]=data; + connect(job,SIGNAL(result(KJob*)),this,SLOT(jobDone(KJob*))); + connect(job,SIGNAL(data(KIO::Job*,QByteArray)),this,SLOT(dataReceived(KIO::Job*,QByteArray))); + } +} + +void IonDebianWeather::startFetchData(QSharedPointer data) { + Q_ASSERT(data->valid); + Q_ASSERT(data->type==weather); + QUrl url(QString::fromLatin1("http://edos.debian.net/edos-debcheck/results/%1/latest/%2/weather.xml").arg(data->suite).arg(data->arch)); + KIO::TransferJob* job = KIO::get(url,KIO::NoReload,KIO::HideProgressInfo); + if(job) { + m_jobs[job]=data; + connect(job,SIGNAL(result(KJob*)),this,SLOT(jobDone(KJob*))); + connect(job,SIGNAL(data(KIO::Job*,QByteArray)),this,SLOT(dataReceived(KIO::Job*,QByteArray))); + } +} + +void IonDebianWeather::jobDone(KJob* job) { + if(KIO::TransferJob* kiojob = qobject_cast(job)) { + QSharedPointer locdata = m_jobs.value(job); + if(locdata->valid && locdata->type==weather) { + if(kiojob->error() != 0 || kiojob->isErrorPage()) { + setData(locdata->source, toString(validate), QString::fromLatin1("%1|timeout").arg(m_ionname)); + } else { + xmlresult result = parseWeatherXml(locdata); + ConditionIcons cond = toCondition(result); + Plasma::DataEngine::Data data; + data.insert( QLatin1String("Condition Icon"), getWeatherIcon(cond) ); + data.insert( QLatin1String("Place"), result.nicename ); + data.insert( QLatin1String("Temperature"), QString::number(result.broken) ); + data.insert( QLatin1String("Temperature Unit"), QString::number(KUnitConversion::Celsius) ); + data.insert( QLatin1String("Total Weather Days"), 0 ); + data.insert( QLatin1String("Current Conditions"), result.architecture ); + data.insert( QLatin1String("Credit"), QString::fromLatin1("Data from http://edos.debian.net")); + data.insert( QLatin1String("Credit Url"), QString::fromLatin1("http://edos.debian.net")); + setData( locdata->source,data); + } + } else if( locdata->type == validate ) { + if(kiojob->error()!=0 || kiojob->isErrorPage()) { + setData(locdata->source, toString(validate),QString::fromLatin1("%1|invalid|single|Debian %2").arg(m_ionname).arg(locdata->searchstring).simplified()); + } else { + QStringList archsuitelist = parseLocationXml(locdata); + QString places; + if(archsuitelist.size()==0) { + setData(locdata->source, toString(validate),QString::fromLatin1("%1|invalid|single|Debian %2").arg(m_ionname).arg(locdata->searchstring).simplified()); + } else if(archsuitelist.size()==1) { + setData(locdata->source, toString(validate), QString::fromLatin1("%1|valid|single|place|Debian %2").arg(m_ionname).arg(locdata->searchstring).simplified()); + } else { + Q_FOREACH(QString place, archsuitelist) { + places += QLatin1String("|place|"); + places += place; + } + setData(locdata->source, toString(validate), QString::fromLatin1("%1|valid|multiple%2").arg(m_ionname).arg(places)); + } + } + } else { + kError() << "something went horribly wrong with this locdata"; + } + m_jobs.remove(kiojob); + kiojob->deleteLater(); + } +} + +void IonDebianWeather::dataReceived(KIO::Job* job, QByteArray data) { + QSharedPointer locdata = m_jobs.value(job); + if(!locdata.isNull() && locdata->valid) { + locdata->data.append(data); + } else { + kError() << "wtf"; + } +} + +IonDebianWeather::xmlresult IonDebianWeather::parseWeatherXml(QSharedPointer< IonDebianWeather::locationdata > locdata) { + QXmlStreamReader reader(locdata->data); + xmlresult result; + while(!reader.atEnd()) { + reader.readNextStartElement(); + if( reader.name() == QLatin1String("total")) { + result.total = reader.readElementText().trimmed().toInt(); + } else if( reader.name() == QLatin1String("broken") ) { + result.broken = reader.readElementText().trimmed().toInt(); + } else if(reader.name() == QLatin1String("description") ) { + result.nicename = reader.readElementText(); + } else if(reader.name() == QLatin1String("architecture") ) { + result.architecture = reader.readElementText(); + } + } + return result; +} + +QStringList IonDebianWeather::parseLocationXml(QSharedPointer< IonDebianWeather::locationdata > locdata) { + QXmlStreamReader reader(locdata->data); + QStringList rv; + while (!reader.atEnd()) { + reader.readNext(); + while(!reader.atEnd() && !(reader.isEndElement() && reader.name() == QLatin1String("weathers"))) { + reader.readNext(); + QString suite; + while(!reader.atEnd() && !(reader.isEndElement() && reader.name()==QLatin1String("weather"))) { + reader.readNext(); + if(reader.isStartElement() && reader.name() == QLatin1String("name")) { + suite = reader.readElementText().trimmed(); + continue; + } + if(reader.isStartElement() && reader.name() == QLatin1String("title")) { + // qDebug() << reader.readElementText(); + continue; + } + if(reader.isStartElement() && reader.name() == QLatin1String("archs")) { + while (!reader.atEnd() && !(reader.isEndElement() && reader.name() == QLatin1String("archs"))) { + reader.readNext(); + if(reader.isStartElement() && reader.name()== QLatin1String("arch")) { + QString arch = reader.readElementText(); + QString locstring = QString::fromLatin1("Debian %1 %2").arg(suite).arg(arch); + if(locstring.contains(locdata->searchstring)) { + rv << locstring; + } + } + } + } + } + } + } + return rv; +} + +IonInterface::ConditionIcons IonDebianWeather::toCondition(IonDebianWeather::xmlresult result ) { + qreal percentage=101; //magicvalue ! + if(result.total!=0) { + percentage = result.broken*qreal(100.0)/result.total; + } + if(percentage <= 1) { + return ClearDay; + } else if(percentage <=2) { + return FewCloudsDay; + } else if(percentage <=3) { + return Overcast; + } else if(percentage <=4) { + return Showers; + } else if(percentage <=100) { + return Thunderstorm; + } + return NotAvailable; +} + +#include "iondebianweather.moc" diff --git a/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.h b/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.h new file mode 100644 index 00000000..a3ca1101 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/debianweather/iondebianweather.h @@ -0,0 +1,89 @@ +/* + Copyright (c) 2011 Sune Vuorela + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef IONDEBIANWEATHER_H +#define IONDEBIANWEATHER_H + +#include "../ion.h" +#include + +class KJob; +namespace KIO { + class Job; +} +class IonDebianWeather : public IonInterface { + Q_OBJECT + public: + IonDebianWeather(QObject*, const QVariantList&); + virtual ~IonDebianWeather(); + virtual bool updateIonSource(const QString& source); + virtual void init(); + public Q_SLOTS: + virtual void reset(); + private: + enum jobtype { + validate, + weather, + unknown + }; + struct xmlresult { + int total; + int broken; + QString nicename; + QString architecture; + xmlresult() : total(0), broken(0) {} + }; + struct locationdata { + QString suite; + QString arch; + bool valid; + QString source; + QByteArray data; + jobtype type; + QString searchstring; + locationdata() : valid(false),type(unknown) {} + }; + void tryFindPlace(QSharedPointer data); + void startFetchData(QSharedPointer data); + void findAllPlaces(QSharedPointer< IonDebianWeather::locationdata > data); + void parseLocation(QString sourcedata, QSharedPointer location); + QString m_ionname; + QHash > m_jobs; + xmlresult parseWeatherXml(QSharedPointer locdata); + QStringList parseLocationXml(QSharedPointer< IonDebianWeather::locationdata > locdata); + + jobtype toJobType(const QString& data); + QString toString(jobtype type); + ConditionIcons toCondition(xmlresult); + void cleanup(); + private Q_SLOTS: + void jobDone(KJob*); + void dataReceived(KIO::Job* job,QByteArray data); +}; + +K_EXPORT_PLASMA_DATAENGINE(debianweather, IonDebianWeather) + +#endif // IONDEBIANWEATHER_H diff --git a/plasma/generic/dataengines/weather/ions/envcan/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/envcan/CMakeLists.txt new file mode 100644 index 00000000..cb10a30d --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/envcan/CMakeLists.txt @@ -0,0 +1,8 @@ +SET (ion_envcan_SRCS ion_envcan.cpp) +kde4_add_plugin(ion_envcan ${ion_envcan_SRCS}) +target_link_libraries (ion_envcan ${KDE4_SOLID_LIBS} weather_ion) + +INSTALL (FILES ion-envcan.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +INSTALL (TARGETS ion_envcan DESTINATION ${PLUGIN_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/weather/ions/envcan/ion-envcan.desktop b/plasma/generic/dataengines/weather/ions/envcan/ion-envcan.desktop new file mode 100644 index 00000000..9c94bba0 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/envcan/ion-envcan.desktop @@ -0,0 +1,153 @@ +[Desktop Entry] +Name=Environment Canada +Name[ar]=وزارة البيئة الكندية +Name[ast]=Medioambiente de Canadá +Name[be@latin]=Environment Canada +Name[bg]=Environment Canada +Name[bs]=Prirodna sredina Kanada +Name[ca]=Medi ambient del Canadà +Name[ca@valencia]=Medi ambient del Canadà +Name[cs]=Meteorologický úřad Kanady (EC) +Name[da]=Environment Canada +Name[de]=Environment Canada +Name[el]=Περιβάλλον Καναδά +Name[en_GB]=Environment Canada +Name[eo]=Environment Canada +Name[es]=Medio ambiente de Canada +Name[et]=Environment Canada +Name[eu]=Kanadako Ingurumen Ministerioa +Name[fi]=Environment Canada -palvelu +Name[fr]=Météorologie du Canada +Name[fy]=Omjouwing Kanada +Name[ga]=Environment Canada +Name[gl]=Environment Canada +Name[gu]=એન્વાર્યમેન્ટ કેનેડા +Name[he]=Environment Canada +Name[hi]=एनवायरनमेंट कनाडा +Name[hne]=कनाडा मौसम +Name[hr]=Okoliš Kanade +Name[hu]=Environment Canada +Name[ia]=Environment Canada +Name[id]=Environment Canada +Name[is]=Environment Canada +Name[it]=Environment Canada +Name[ja]=Environment Canada +Name[kk]=Environment Canada +Name[km]=បរិស្ថាន​ប្រទេស​កាណាដា +Name[kn]=ಎನ್ವಯರನ್ಮೆಂಟ್ ಕೆನಡಾ +Name[ko]=캐나다 환경부 +Name[lt]=Environment Canada +Name[lv]=Environment Canada +Name[mk]=Environment Canada +Name[ml]=കാനഡയുടെ പരിസ്ഥിതി +Name[mr]=हवामान कॅनडा +Name[nb]=Environment Canada +Name[nds]=Ümwelt Kanada +Name[ne]=वातावरण क्यानाडा +Name[nl]=Environment Canada +Name[nn]=Environment Canada +Name[pa]=ਇੰਨਵਾਇਰਮੈਂਟ ਕੇਨੈਡਾ +Name[pl]=Environment Canada +Name[pt]=Environment Canada +Name[pt_BR]=Environment Canada +Name[ro]=Environment Canada +Name[ru]=Environment Canada +Name[se]=Environment Canada +Name[si]=කැනඩා පාරිසරිකය +Name[sk]=Počasie - Environment Canada +Name[sl]=Environment Canada +Name[sr]=Природна средина Канада +Name[sr@ijekavian]=Природна средина Канада +Name[sr@ijekavianlatin]=Prirodna sredina Kanada +Name[sr@latin]=Prirodna sredina Kanada +Name[sv]=Environment Canada +Name[ta]=Environment Canada +Name[te]=కెనడా వాతావరణం +Name[tg]=Environment Canada +Name[th]=Environment Canada +Name[tr]=Environment Canada +Name[ug]=كانادا مۇھىتى +Name[uk]=Погода в Канаді +Name[wa]=Evironmint Canada +Name[x-test]=xxEnvironment Canadaxx +Name[zh_CN]=加拿大环境 +Name[zh_TW]=Environment Canada +Comment=XML Data from Environment Canada +Comment[ar]=بيانات XML من وزارة البيئة الكندية +Comment[ast]=Datos XML de Medioambiente de Canadá +Comment[be@latin]=Źviestki ŭ farmacie „XML” ad „Environment Canada” +Comment[bg]=XML данни от Environment Canada +Comment[bs]=IksML podaci Prirodne sredine Kanada +Comment[ca]=Dades XML des de Medi ambient del Canadà +Comment[ca@valencia]=Dades XML des de Medi ambient del Canadà +Comment[cs]=XML data z meteorologického úřadu Kanady (EC) +Comment[da]=XML-data fra Environment Canada +Comment[de]=XML-Daten von Environment Canada +Comment[el]=Δεδομένα XML για το περιβάλλον του Καναδά +Comment[en_GB]=XML Data from Environment Canada +Comment[eo]=XML-datumoj el Environment Canada +Comment[es]=Datos XML de medio ambiente de Canada +Comment[et]=Environment Canada XML-andmed +Comment[eu]=XML datuak Kanadako Ingurumen Ministeriotik +Comment[fi]=XML-tietoa Environment Canada -palvelusta +Comment[fr]=Données au format XML de la météorologie du Canada +Comment[fy]=XML Data fan omjouwing Kanada +Comment[ga]=Sonraí XML ó Environment Canada +Comment[gl]=Datos XML de Environment Canada +Comment[gu]=એન્વાર્યમેન્ટ કેનેડા તરફથી XML માહિતી +Comment[he]=מידע ב־XML מ־Environment Canada +Comment[hi]=एनवायरनमेंट कनाडा से एक्सएमएल डाटा +Comment[hne]=कनाडा मौसम से एक्सएमएल डाटा +Comment[hr]=XML podaci iz Okoliša Kanade +Comment[hu]=XML-adatok az Environment Canada szervezettől +Comment[ia]=Datos XML ex Environment Canada +Comment[id]=Data XML dari Environment Canada +Comment[is]=XML gögn frá Umhverfisstofnun Kanada +Comment[it]=Dati XML da Environment Canada +Comment[ja]=Environment Canada の XML データ +Comment[kk]=Environment Canada-ның XML дерегі +Comment[km]=ទិន្នន័យ XML ពី​បរិស្ថាន​ប្រទេស​កាណាដា +Comment[kn]=ಎನ್ವಯರನ್ಮೆಂಟ್ ಕೆನಡಾ ದಿಂದ XML ದತ್ತ +Comment[ko]=캐나다 환경부의 XML 데이터 +Comment[lt]=XML duomenys iš Environment Canada +Comment[lv]=XML dati no Environment Canada +Comment[mk]=XML-податоци од „Environment Canada“ +Comment[ml]=കാനഡയുടെ പരിസ്ഥിതിയില്‍ നിന്നുമുള്ള എക്സ്എംഎല്‍ ഡേറ്റാ +Comment[mr]=हवामान कॅनडा पासून XML माहिती +Comment[nb]=XML-data fra Environment Canada +Comment[nds]=XML-Daten vun Ümwelt Kanada +Comment[ne]=वातावरण क्यानाडाबाट एक्सएमएल डेटा +Comment[nl]=XML-gegevens van Environment Canada +Comment[nn]=XML-data frå Environment Canada +Comment[pa]=ਇੰਨਵਾਇਰਨਮੈਂਟ ਕੇਨੈਡਾ ਤੋਂ XML ਡਾਟਾ +Comment[pl]=Dane XML z Environment Canada +Comment[pt]=Dados em XML do Environment Canada +Comment[pt_BR]=Dados em XML do Environment Canada +Comment[ro]=Date XML de la Environment Canada +Comment[ru]=Данные в формате XML от Environment Canada +Comment[se]=XML-dáhtat Environment Canadas +Comment[si]=කැනඩා පාරිසරිකය වෙතින් XML දත්ත +Comment[sk]=XML dáta z Environment Canada +Comment[sl]=Podatki XML od Environment Canada +Comment[sr]=ИксМЛ подаци Природне средине Канада +Comment[sr@ijekavian]=ИксМЛ подаци Природне средине Канада +Comment[sr@ijekavianlatin]=XML podaci Prirodne sredine Kanada +Comment[sr@latin]=XML podaci Prirodne sredine Kanada +Comment[sv]=XML-data från Environment Canada +Comment[ta]=XML Data from Environment Canada +Comment[te]=కెనడా వాతావరణం నుండి XML డాటా +Comment[tg]=Маълумоти XML аз Environment Canada +Comment[th]=ข้อมูล XML จาก Environment Canada +Comment[tr]=Environment Canada'dan XML Verisi +Comment[ug]=كانادا مۇھىتى تەمىنلىگەن XML سانلىق-مەلۇماتى +Comment[uk]=Дані XML з метеорологічного відділу Канади +Comment[wa]=Dinêyes XML da Evironmint Canada +Comment[x-test]=xxXML Data from Environment Canadaxx +Comment[zh_CN]=加拿大环境提供的 XML 数据 +Comment[zh_TW]=從 Environment Canada 來的 XML 資料 +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-ParentApp=weatherengine +Type=Service +Icon=noneyet +X-KDE-Library=ion_envcan +X-KDE-PluginInfo-Name=envcan diff --git a/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.cpp b/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.cpp new file mode 100644 index 00000000..51946fd9 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.cpp @@ -0,0 +1,1922 @@ +/*************************************************************************** + * Copyright (C) 2007-2011 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for Environment Canada XML data */ + +#include "ion_envcan.h" + +#include +#include +#include +#include + + +// ctor, dtor +EnvCanadaIon::EnvCanadaIon(QObject *parent, const QVariantList &args) + : IonInterface(parent, args) +{ +} + +void EnvCanadaIon::deleteForecasts() +{ + QMutableHashIterator it(m_weatherData); + while (it.hasNext()) { + it.next(); + WeatherData &item = it.value(); + qDeleteAll(item.warnings); + item.warnings.clear(); + + qDeleteAll(item.watches); + item.watches.clear(); + + qDeleteAll(item.forecasts); + item.forecasts.clear(); + } +} + +void EnvCanadaIon::reset() +{ + deleteForecasts(); + emitWhenSetup = true; + m_sourcesToReset = sources(); + getXMLSetup(); +} + +EnvCanadaIon::~EnvCanadaIon() +{ + // Destroy each watch/warning stored in a QVector + deleteForecasts(); +} + +// Get the master list of locations to be parsed +void EnvCanadaIon::init() +{ + // Get the real city XML URL so we can parse this + getXMLSetup(); + m_timeEngine = dataEngine("time"); +} + +QMap EnvCanadaIon::setupConditionIconMappings(void) const +{ + QMap conditionList; + + // Explicit periods + conditionList["mainly sunny"] = FewCloudsDay; + conditionList["mainly clear"] = FewCloudsNight; + conditionList["sunny"] = ClearDay; + conditionList["clear"] = ClearNight; + + // Available conditions + conditionList["blowing snow"] = Snow; + conditionList["cloudy"] = Overcast; + conditionList["distant precipitation"] = LightRain; + conditionList["drifting snow"] = Flurries; + conditionList["drizzle"] = LightRain; + conditionList["dust"] = NotAvailable; + conditionList["dust devils"] = NotAvailable; + conditionList["fog"] = Mist; + conditionList["fog bank near station"] = Mist; + conditionList["fog depositing ice"] = Mist; + conditionList["fog patches"] = Mist; + conditionList["freezing drizzle"] = FreezingDrizzle; + conditionList["freezing rain"] = FreezingRain; + conditionList["funnel cloud"] = NotAvailable; + conditionList["hail"] = Hail; + conditionList["haze"] = Haze; + conditionList["heavy blowing snow"] = Snow; + conditionList["heavy drifting snow"] = Snow; + conditionList["heavy drizzle"] = LightRain; + conditionList["heavy hail"] = Hail; + conditionList["heavy mixed rain and drizzle"] = LightRain; + conditionList["heavy mixed rain and snow shower"] = RainSnow; + conditionList["heavy rain"] = Rain; + conditionList["heavy rain and snow"] = RainSnow; + conditionList["heavy rainshower"] = Rain; + conditionList["heavy snow"] = Snow; + conditionList["heavy snow pellets"] = Snow; + conditionList["heavy snowshower"] = Snow; + conditionList["heavy thunderstorm with hail"] = Thunderstorm; + conditionList["heavy thunderstorm with rain"] = Thunderstorm; + conditionList["ice crystals"] = Flurries; + conditionList["ice pellets"] = Hail; + conditionList["increasing cloud"] = Overcast; + conditionList["light drizzle"] = LightRain; + conditionList["light freezing drizzle"] = FreezingRain; + conditionList["light freezing rain"] = FreezingRain; + conditionList["light rain"] = LightRain; + conditionList["light rainshower"] = LightRain; + conditionList["light snow"] = LightSnow; + conditionList["light snow pellets"] = LightSnow; + conditionList["light snowshower"] = Flurries; + conditionList["lightning visible"] = Thunderstorm; + conditionList["mist"] = Mist; + conditionList["mixed rain and drizzle"] = LightRain; + conditionList["mixed rain and snow shower"] = RainSnow; + conditionList["not reported"] = NotAvailable; + conditionList["rain"] = Rain; + conditionList["rain and snow"] = RainSnow; + conditionList["rainshower"] = LightRain; + conditionList["recent drizzle"] = LightRain; + conditionList["recent dust or sand storm"] = NotAvailable; + conditionList["recent fog"] = Mist; + conditionList["recent freezing precipitation"] = FreezingDrizzle; + conditionList["recent hail"] = Hail; + conditionList["recent rain"] = Rain; + conditionList["recent rain and snow"] = RainSnow; + conditionList["recent rainshower"] = Rain; + conditionList["recent snow"] = Snow; + conditionList["recent snowshower"] = Flurries; + conditionList["recent thunderstorm"] = Thunderstorm; + conditionList["recent thunderstorm with hail"] = Thunderstorm; + conditionList["recent thunderstorm with heavy hail"] = Thunderstorm; + conditionList["recent thunderstorm with heavy rain"] = Thunderstorm; + conditionList["recent thunderstorm with rain"] = Thunderstorm; + conditionList["sand or dust storm"] = NotAvailable; + conditionList["severe sand or dust storm"] = NotAvailable; + conditionList["shallow fog"] = Mist; + conditionList["smoke"] = NotAvailable; + conditionList["snow"] = Snow; + conditionList["snow crystals"] = Flurries; + conditionList["snow grains"] = Flurries; + conditionList["squalls"] = Snow; + conditionList["thunderstorm with hail"] = Thunderstorm; + conditionList["thunderstorm with rain"] = Thunderstorm; + conditionList["thunderstorm with sand or dust storm"] = Thunderstorm; + conditionList["thunderstorm without precipitation"] = Thunderstorm; + conditionList["tornado"] = NotAvailable; + return conditionList; +} + + +QMap EnvCanadaIon::setupForecastIconMappings(void) const +{ + QMap forecastList; + + // Abbreviated forecast descriptions + forecastList["a few flurries"] = Flurries; + forecastList["a few flurries mixed with ice pellets"] = RainSnow; + forecastList["a few flurries or rain showers"] = RainSnow; + forecastList["a few flurries or thundershowers"] = RainSnow; + forecastList["a few rain showers or flurries"] = RainSnow; + forecastList["a few rain showers or wet flurries"] = RainSnow; + forecastList["a few showers"] = LightRain; + forecastList["a few showers or drizzle"] = LightRain; + forecastList["a few showers or thundershowers"] = Thunderstorm; + forecastList["a few showers or thunderstorms"] = Thunderstorm; + forecastList["a few thundershowers"] = Thunderstorm; + forecastList["a few thunderstorms"] = Thunderstorm; + forecastList["a few wet flurries"] = RainSnow; + forecastList["a few wet flurries or rain showers"] = RainSnow; + forecastList["a mix of sun and cloud"] = PartlyCloudyDay; + forecastList["cloudy with sunny periods"] = PartlyCloudyDay; + forecastList["partly cloudy"] = PartlyCloudyDay; + forecastList["mainly sunny"] = FewCloudsDay; + forecastList["sunny"] = ClearDay; + forecastList["blizzard"] = Snow; + forecastList["clear"] = ClearNight; + forecastList["cloudy"] = Overcast; + forecastList["drizzle"] = LightRain; + forecastList["drizzle mixed with freezing drizzle"] = FreezingDrizzle; + forecastList["drizzle mixed with rain"] = LightRain; + forecastList["drizzle or freezing drizzle"] = LightRain; + forecastList["drizzle or rain"] = LightRain; + forecastList["flurries"] = Flurries; + forecastList["flurries at times heavy"] = Flurries; + forecastList["flurries at times heavy or rain snowers"] = RainSnow; + forecastList["flurries mixed with ice pellets"] = FreezingRain; + forecastList["flurries or ice pellets"] = FreezingRain; + forecastList["flurries or rain showers"] = RainSnow; + forecastList["flurries or thundershowers"] = Flurries; + forecastList["fog"] = Mist; + forecastList["fog developing"] = Mist; + forecastList["fog dissipating"] = Mist; + forecastList["fog patches"] = Mist; + forecastList["freezing drizzle"] = FreezingDrizzle; + forecastList["freezing rain"] = FreezingRain; + forecastList["freezing rain mixed with rain"] = FreezingRain; + forecastList["freezing rain mixed with snow"] = FreezingRain; + forecastList["freezing rain or ice pellets"] = FreezingRain; + forecastList["freezing rain or rain"] = FreezingRain; + forecastList["freezing rain or snow"] = FreezingRain; + forecastList["ice fog"] = Mist; + forecastList["ice fog developing"] = Mist; + forecastList["ice fog dissipating"] = Mist; + forecastList["ice pellet"] = Hail; + forecastList["ice pellet mixed with freezing rain"] = Hail; + forecastList["ice pellet mixed with snow"] = Hail; + forecastList["ice pellet or snow"] = RainSnow; + forecastList["light snow"] = LightSnow; + forecastList["light snow and blizzard"] = LightSnow; + forecastList["light snow and blizzard and blowing snow"] = Snow; + forecastList["light snow and blowing snow"] = LightSnow; + forecastList["light snow mixed with freezing drizzle"] = FreezingDrizzle; + forecastList["light snow mixed with freezing rain"] = FreezingRain; + forecastList["light snow or ice pellets"] = LightSnow; + forecastList["light snow or rain"] = RainSnow; + forecastList["light wet snow"] = RainSnow; + forecastList["light wet snow or rain"] = RainSnow; + forecastList["local snow squalls"] = Snow; + forecastList["near blizzard"] = Snow; + forecastList["overcast"] = Overcast; + forecastList["increasing cloudiness"] = Overcast; + forecastList["increasing clouds"] = Overcast; + forecastList["periods of drizzle"] = LightRain; + forecastList["periods of drizzle mixed with freezing drizzle"] = FreezingDrizzle; + forecastList["periods of drizzle mixed with rain"] = LightRain; + forecastList["periods of drizzle or freezing drizzle"] = FreezingDrizzle; + forecastList["periods of drizzle or rain"] = LightRain; + forecastList["periods of freezing drizzle"] = FreezingDrizzle; + forecastList["periods of freezing drizzle or drizzle"] = FreezingDrizzle; + forecastList["periods of freezing drizzle or rain"] = FreezingDrizzle; + forecastList["periods of freezing rain"] = FreezingRain; + forecastList["periods of freezing rain mixed with ice pellets"] = FreezingRain; + forecastList["periods of freezing rain mixed with rain"] = FreezingRain; + forecastList["periods of freezing rain mixed with snow"] = FreezingRain; + forecastList["periods of freezing rain mixed with freezing drizzle"] = FreezingRain; + forecastList["periods of freezing rain or ice pellets"] = FreezingRain; + forecastList["periods of freezing rain or rain"] = FreezingRain; + forecastList["periods of freezing rain or snow"] = FreezingRain; + forecastList["periods of ice pellet"] = Hail; + forecastList["periods of ice pellet mixed with freezing rain"] = Hail; + forecastList["periods of ice pellet mixed with snow"] = Hail; + forecastList["periods of ice pellet or freezing rain"] = Hail; + forecastList["periods of ice pellet or snow"] = Hail; + forecastList["periods of light snow"] = LightSnow; + forecastList["periods of light snow and blizzard"] = Snow; + forecastList["periods of light snow and blizzard and blowing snow"] = Snow; + forecastList["periods of light snow and blowing snow"] = LightSnow; + forecastList["periods of light snow mixed with freezing drizzle"] = RainSnow; + forecastList["periods of light snow mixed with freezing rain"] = RainSnow; + forecastList["periods of light snow mixed with ice pelletS"] = LightSnow; + forecastList["periods of light snow mixed with rain"] = RainSnow; + forecastList["periods of light snow or freezing drizzle"] = RainSnow; + forecastList["periods of light snow or freezing rain"] = RainSnow; + forecastList["periods of light snow or ice pellets"] = LightSnow; + forecastList["periods of light snow or rain"] = RainSnow; + forecastList["periods of light wet snow"] = LightSnow; + forecastList["periods of light wet snow mixed with rain"] = RainSnow; + forecastList["periods of light wet snow or rain"] = RainSnow; + forecastList["periods of rain"] = Rain; + forecastList["periods of rain mixed with freezing rain"] = Rain; + forecastList["periods of rain mixed with snow"] = RainSnow; + forecastList["periods of rain or drizzle"] = Rain; + forecastList["periods of rain or freezing rain"] = Rain; + forecastList["periods of rain or thundershowers"] = Showers; + forecastList["periods of rain or thunderstorms"] = Thunderstorm; + forecastList["periods of rain or snow"] = RainSnow; + forecastList["periods of snow"] = Snow; + forecastList["periods of snow and blizzard"] = Snow; + forecastList["periods of snow and blizzard and blowing snow"] = Snow; + forecastList["periods of snow and blowing snow"] = Snow; + forecastList["periods of snow mixed with freezing drizzle"] = RainSnow; + forecastList["periods of snow mixed with freezing rain"] = RainSnow; + forecastList["periods of snow mixed with ice pellets"] = Snow; + forecastList["periods of snow mixed with rain"] = RainSnow; + forecastList["periods of snow or freezing drizzle"] = RainSnow; + forecastList["periods of snow or freezing rain"] = RainSnow; + forecastList["periods of snow or ice pellets"] = Snow; + forecastList["periods of snow or rain"] = RainSnow; + forecastList["periods of rain or snow"] = RainSnow; + forecastList["periods of wet snow"] = Snow; + forecastList["periods of wet snow mixed with rain"] = RainSnow; + forecastList["periods of wet snow or rain"] = RainSnow; + forecastList["rain"] = Rain; + forecastList["rain at times heavy"] = Rain; + forecastList["rain at times heavy mixed with freezing rain"] = FreezingRain; + forecastList["rain at times heavy mixed with snow"] = RainSnow; + forecastList["rain at times heavy or drizzle"] = Rain; + forecastList["rain at times heavy or freezing rain"] = Rain; + forecastList["rain at times heavy or snow"] = RainSnow; + forecastList["rain at times heavy or thundershowers"] = Showers; + forecastList["rain at times heavy or thunderstorms"] = Thunderstorm; + forecastList["rain mixed with freezing rain"] = FreezingRain; + forecastList["rain mixed with snow"] = RainSnow; + forecastList["rain or drizzle"] = Rain; + forecastList["rain or freezing rain"] = Rain; + forecastList["rain or snow"] = RainSnow; + forecastList["rain or thundershowers"] = Showers; + forecastList["rain or thunderstorms"] = Thunderstorm; + forecastList["rain showers or flurries"] = RainSnow; + forecastList["rain showers or wet flurries"] = RainSnow; + forecastList["showers"] = Showers; + forecastList["showers at times heavy"] = Showers; + forecastList["showers at times heavy or thundershowers"] = Showers; + forecastList["showers at times heavy or thunderstorms"] = Thunderstorm; + forecastList["showers or drizzle"] = Showers; + forecastList["showers or thundershowers"] = Thunderstorm; + forecastList["showers or thunderstorms"] = Thunderstorm; + forecastList["smoke"] = NotAvailable; + forecastList["snow"] = Snow; + forecastList["snow and blizzard"] = Snow; + forecastList["snow and blizzard and blowing snow"] = Snow; + forecastList["snow and blowing snow"] = Snow; + forecastList["snow at times heavy"] = Snow; + forecastList["snow at times heavy and blizzard"] = Snow; + forecastList["snow at times heavy and blowing snow"] = Snow; + forecastList["snow at times heavy mixed with freezing drizzle"] = RainSnow; + forecastList["snow at times heavy mixed with freezing rain"] = RainSnow; + forecastList["snow at times heavy mixed with ice pellets"] = Snow; + forecastList["snow at times heavy mixed with rain"] = RainSnow; + forecastList["snow at times heavy or freezing rain"] = RainSnow; + forecastList["snow at times heavy or ice pellets"] = Snow; + forecastList["snow at times heavy or rain"] = RainSnow; + forecastList["snow mixed with freezing drizzle"] = RainSnow; + forecastList["snow mixed with freezing rain"] = RainSnow; + forecastList["snow mixed with ice pellets"] = Snow; + forecastList["snow mixed with rain"] = RainSnow; + forecastList["snow or freezing drizzle"] = RainSnow; + forecastList["snow or freezing rain"] = RainSnow; + forecastList["snow or ice pellets"] = Snow; + forecastList["snow or rain"] = RainSnow; + forecastList["snow squalls"] = Snow; + forecastList["sunny"] = ClearDay; + forecastList["sunny with cloudy periods"] = PartlyCloudyDay; + forecastList["thunderstorms"] = Thunderstorm; + forecastList["thunderstorms and possible hail"] = Thunderstorm; + forecastList["wet flurries"] = Flurries; + forecastList["wet flurries at times heavy"] = Flurries; + forecastList["wet flurries at times heavy or rain snowers"] = RainSnow; + forecastList["wet flurries or rain showers"] = RainSnow; + forecastList["wet snow"] = Snow; + forecastList["wet snow at times heavy"] = Snow; + forecastList["wet snow at times heavy mixed with rain"] = RainSnow; + forecastList["wet snow mixed with rain"] = RainSnow; + forecastList["wet snow or rain"] = RainSnow; + forecastList["windy"] = NotAvailable; + + forecastList["chance of drizzle mixed with freezing drizzle"] = LightRain; + forecastList["chance of flurries mixed with ice pellets"] = Flurries; + forecastList["chance of flurries or ice pellets"] = Flurries; + forecastList["chance of flurries or rain showers"] = RainSnow; + forecastList["chance of flurries or thundershowers"] = RainSnow; + forecastList["chance of freezing drizzle"] = FreezingDrizzle; + forecastList["chance of freezing rain"] = FreezingRain; + forecastList["chance of freezing rain mixed with snow"] = RainSnow; + forecastList["chance of freezing rain or rain"] = FreezingRain; + forecastList["chance of freezing rain or snow"] = RainSnow; + forecastList["chance of light snow and blowing snow"] = LightSnow; + forecastList["chance of light snow mixed with freezing drizzle"] = LightSnow; + forecastList["chance of light snow mixed with ice pellets"] = LightSnow; + forecastList["chance of light snow mixed with rain"] = RainSnow; + forecastList["chance of light snow or freezing rain"] = RainSnow; + forecastList["chance of light snow or ice pellets"] = LightSnow; + forecastList["chance of light snow or rain"] = RainSnow; + forecastList["chance of light wet snow"] = Snow; + forecastList["chance of rain"] = Rain; + forecastList["chance of rain at times heavy"] = Rain; + forecastList["chance of rain mixed with snow"] = RainSnow; + forecastList["chance of rain or drizzle"] = Rain; + forecastList["chance of rain or freezing rain"] = Rain; + forecastList["chance of rain or snow"] = RainSnow; + forecastList["chance of rain showers or flurries"] = RainSnow; + forecastList["chance of rain showers or wet flurries"] = RainSnow; + forecastList["chance of severe thunderstorms"] = Thunderstorm; + forecastList["chance of showers at times heavy"] = Rain; + forecastList["chance of showers at times heavy or thundershowers"] = Thunderstorm; + forecastList["chance of showers at times heavy or thunderstorms"] = Thunderstorm; + forecastList["chance of showers or thundershowers"] = Thunderstorm; + forecastList["chance of showers or thunderstorms"] = Thunderstorm; + forecastList["chance of snow"] = Snow; + forecastList["chance of snow and blizzard"] = Snow; + forecastList["chance of snow mixed with freezing drizzle"] = Snow; + forecastList["chance of snow mixed with freezing rain"] = RainSnow; + forecastList["chance of snow mixed with rain"] = RainSnow; + forecastList["chance of snow or rain"] = RainSnow; + forecastList["chance of snow squalls"] = Snow; + forecastList["chance of thundershowers"] = Showers; + forecastList["chance of thunderstorms"] = Thunderstorm; + forecastList["chance of thunderstorms and possible hail"] = Thunderstorm; + forecastList["chance of wet flurries"] = Flurries; + forecastList["chance of wet flurries at times heavy"] = Flurries; + forecastList["chance of wet flurries or rain showers"] = RainSnow; + forecastList["chance of wet snow"] = Snow; + forecastList["chance of wet snow mixed with rain"] = RainSnow; + forecastList["chance of wet snow or rain"] = RainSnow; + + return forecastList; +} + +QMap const& EnvCanadaIon::conditionIcons(void) const +{ + static QMap const condval = setupConditionIconMappings(); + return condval; +} + +QMap const& EnvCanadaIon::forecastIcons(void) const +{ + static QMap const foreval = setupForecastIconMappings(); + return foreval; +} + +QStringList EnvCanadaIon::validate(const QString& source) const +{ + QStringList placeList; + QString sourceNormalized = source.toUpper(); + QHash::const_iterator it = m_places.constBegin(); + while (it != m_places.constEnd()) { + if (it.key().toUpper().contains(sourceNormalized)) { + placeList.append(QString("place|").append(it.key())); + } + ++it; + } + + // Check if placeList is empty if so, return nothing. + if (placeList.isEmpty()) { + return QStringList(); + } + placeList.sort(); + return placeList; +} + +// Get a specific Ion's data +bool EnvCanadaIon::updateIonSource(const QString& source) +{ + //kDebug() << "updateIonSource()" << source; + + // We expect the applet to send the source in the following tokenization: + // ionname|validate|place_name - Triggers validation of place + // ionname|weather|place_name - Triggers receiving weather of place + + QStringList sourceAction = source.split('|'); + + // Guard: if the size of array is not 2 then we have bad data, return an error + if (sourceAction.size() < 2) { + setData(source, "validate", "envcan|malformed"); + return true; + } + + if (sourceAction[1] == "validate" && sourceAction.size() > 2) { + QStringList result = validate(sourceAction[2]); + + if (result.size() == 1) { + setData(source, "validate", QString("envcan|valid|single|").append(result.join("|"))); + return true; + } else if (result.size() > 1) { + setData(source, "validate", QString("envcan|valid|multiple|").append(result.join("|"))); + return true; + } else if (result.size() == 0) { + setData(source, "validate", QString("envcan|invalid|single|").append(sourceAction[2])); + return true; + } + + } else if (sourceAction[1] == "weather" && sourceAction.size() > 2) { + getXMLData(source); + return true; + } else { + setData(source, "validate", "envcan|malformed"); + return true; + } + return false; +} + +// Parses city list and gets the correct city based on ID number +void EnvCanadaIon::getXMLSetup() +{ + //kDebug() << "getXMLSetup()"; + + // If network is down, we need to spin and wait + + KIO::TransferJob *job = KIO::get(KUrl("http://dd.weatheroffice.ec.gc.ca/citypage_weather/xml/siteList.xml"), KIO::NoReload, KIO::HideProgressInfo); + + m_xmlSetup.clear(); + connect(job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(setup_slotDataArrived(KIO::Job*,QByteArray))); + connect(job, SIGNAL(result(KJob*)), this, SLOT(setup_slotJobFinished(KJob*))); +} + +// Gets specific city XML data +void EnvCanadaIon::getXMLData(const QString& source) +{ + foreach (const QString &fetching, m_jobList) { + if (fetching == source) { + // already getting this source and awaiting the data + return; + } + } + + //kDebug() << source; + + // Demunge source name for key only. + QString dataKey = source; + dataKey.remove("envcan|weather|"); + + KUrl url = QString("http://dd.weatheroffice.ec.gc.ca/citypage_weather/xml/" + m_places[dataKey].territoryName + "/" + m_places[dataKey].cityCode + "_e.xml"); + //url="file:///home/spstarr/Desktop/s0000649_e.xml"; + //kDebug() << "Will Try URL: " << url; + + if (m_places[dataKey].territoryName.isEmpty() && m_places[dataKey].cityCode.isEmpty()) { + setData(source, "validate", QString("envcan|malformed")); + return; + } + + KIO::TransferJob* const newJob = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + + m_jobXml.insert(newJob, new QXmlStreamReader); + m_jobList.insert(newJob, source); + + connect(newJob, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(slotDataArrived(KIO::Job*,QByteArray))); + connect(newJob, SIGNAL(result(KJob*)), this, SLOT(slotJobFinished(KJob*))); +} + +void EnvCanadaIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + Q_UNUSED(job) + + if (data.isEmpty()) { + //kDebug() << "done!"; + return; + } + + // Send to xml. + //kDebug() << data; + m_xmlSetup.addData(data); +} + +void EnvCanadaIon::slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + + if (data.isEmpty() || !m_jobXml.contains(job)) { + return; + } + + // Send to xml. + m_jobXml[job]->addData(data); +} + +void EnvCanadaIon::slotJobFinished(KJob *job) +{ + // Dual use method, if we're fetching location data to parse we need to do this first + const QString source = m_jobList.value(job); + //kDebug() << source << m_sourcesToReset.contains(source); + setData(source, Data()); + QXmlStreamReader *reader = m_jobXml.value(job); + if (reader) { + readXMLData(m_jobList[job], *reader); + } + + m_jobList.remove(job); + delete m_jobXml[job]; + m_jobXml.remove(job); + + if (m_sourcesToReset.contains(source)) { + m_sourcesToReset.removeAll(source); + + // so the weather engine updates it's data + forceImmediateUpdateOfAllVisualizations(); + + // update the clients of our engine + emit forceUpdate(this, source); + } +} + +void EnvCanadaIon::setup_slotJobFinished(KJob *job) +{ + Q_UNUSED(job) + const bool success = readXMLSetup(); + m_xmlSetup.clear(); + //kDebug() << success << m_sourcesToReset; + setInitialized(success); +} + +// Parse the city list and store into a QMap +bool EnvCanadaIon::readXMLSetup() +{ + bool success = false; + QString territory; + QString code; + QString cityName; + + //kDebug() << "readXMLSetup()"; + + while (!m_xmlSetup.atEnd()) { + m_xmlSetup.readNext(); + + if (m_xmlSetup.isStartElement()) { + + // XML ID code to match filename + if (m_xmlSetup.name() == "site") { + code = m_xmlSetup.attributes().value("code").toString(); + } + + if (m_xmlSetup.name() == "nameEn") { + cityName = m_xmlSetup.readElementText(); // Name of cities + } + + if (m_xmlSetup.name() == "provinceCode") { + territory = m_xmlSetup.readElementText(); // Provinces/Territory list + } + } + + if (m_xmlSetup.isEndElement() && m_xmlSetup.name() == "site") { + EnvCanadaIon::XMLMapInfo info; + QString tmp = cityName + ", " + territory; // Build the key name. + + // Set the mappings + info.cityCode = code; + info.territoryName = territory; + info.cityName = cityName; + + // Set the string list, we will use for the applet to display the available cities. + m_places[tmp] = info; + success = true; + } + + } + + return (success && !m_xmlSetup.error()); +} + +void EnvCanadaIon::parseWeatherSite(WeatherData& data, QXmlStreamReader& xml) +{ + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == "license") { + xml.readElementText(); + } else if (xml.name() == "location") { + parseLocations(data, xml); + } else if (xml.name() == "warnings") { + // Cleanup warning list on update + data.warnings.clear(); + data.watches.clear(); + parseWarnings(data, xml); + } else if (xml.name() == "currentConditions") { + parseConditions(data, xml); + } else if (xml.name() == "forecastGroup") { + // Clean up forecast list on update + data.forecasts.clear(); + parseWeatherForecast(data, xml); + } else if (xml.name() == "yesterdayConditions") { + parseYesterdayWeather(data, xml); + } else if (xml.name() == "riseSet") { + parseAstronomicals(data, xml); + } else if (xml.name() == "almanac") { + parseWeatherRecords(data, xml); + } else { + parseUnknownElement(xml); + } + } + } +} + +// Parse Weather data main loop, from here we have to decend into each tag pair +bool EnvCanadaIon::readXMLData(const QString& source, QXmlStreamReader& xml) +{ + WeatherData data; + data.comforttemp = i18n("N/A"); + data.recordHigh = 0.0; + data.recordLow = 0.0; + + //kDebug() << "readXMLData()"; + + QString dataKey = source; + dataKey.remove("envcan|weather|"); + data.shortTerritoryName = m_places[dataKey].territoryName; + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "siteData") { + parseWeatherSite(data, xml); + } else { + parseUnknownElement(xml); + } + } + } + + m_weatherData[source] = data; + updateWeather(source); + return !xml.error(); +} + +void EnvCanadaIon::parseDateTime(WeatherData& data, QXmlStreamReader& xml, WeatherData::WeatherEvent *event) +{ + + Q_ASSERT(xml.isStartElement() && xml.name() == "dateTime"); + + // What kind of date info is this? + QString dateType = xml.attributes().value("name").toString(); + QString dateZone = xml.attributes().value("zone").toString(); + + QString selectTimeStamp; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (dateType == "xmlCreation") { + return; + } + if (dateZone == "UTC") { + return; + } + if (xml.name() == "year") { + xml.readElementText(); + } else if (xml.name() == "month") { + xml.readElementText(); + } else if (xml.name() == "day") { + xml.readElementText(); + } else if (xml.name() == "hour") + xml.readElementText(); + else if (xml.name() == "minute") + xml.readElementText(); + else if (xml.name() == "timeStamp") + selectTimeStamp = xml.readElementText(); + else if (xml.name() == "textSummary") { + if (dateType == "eventIssue") { + if (event) { + event->timestamp = xml.readElementText(); + } + } else if (dateType == "observation") { + xml.readElementText(); + m_dateFormat = QDateTime::fromString(selectTimeStamp, "yyyyMMddHHmmss"); + data.obsTimestamp = m_dateFormat.toString("dd.MM.yyyy @ hh:mm"); + data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); + data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); + } else if (dateType == "forecastIssue") { + data.forecastTimestamp = xml.readElementText(); + } else if (dateType == "sunrise") { + data.sunriseTimestamp = xml.readElementText(); + } else if (dateType == "sunset") { + data.sunsetTimestamp = xml.readElementText(); + } else if (dateType == "moonrise") { + data.moonriseTimestamp = xml.readElementText(); + } else if (dateType == "moonset") { + data.moonsetTimestamp = xml.readElementText(); + } + } + } + } +} + +void EnvCanadaIon::parseLocations(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "location"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "country") { + data.countryName = xml.readElementText(); + } else if (xml.name() == "province" || xml.name() == "territory") { + data.longTerritoryName = xml.readElementText(); + } else if (xml.name() == "name") { + data.cityName = xml.readElementText(); + } else if (xml.name() == "region") { + data.regionName = xml.readElementText(); + } else { + parseUnknownElement(xml); + } + } + } +} + +void EnvCanadaIon::parseWindInfo(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "wind"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "speed") { + data.windSpeed = xml.readElementText(); + } else if (xml.name() == "gust") { + data.windGust = xml.readElementText(); + } else if (xml.name() == "direction") { + data.windDirection = xml.readElementText(); + } else if (xml.name() == "bearing") { + data.windDegrees = xml.attributes().value("degrees").toString(); + } else { + parseUnknownElement(xml); + } + } + } +} + +void EnvCanadaIon::parseConditions(WeatherData& data, QXmlStreamReader& xml) +{ + + Q_ASSERT(xml.isStartElement() && xml.name() == "currentConditions"); + data.temperature = i18n("N/A"); + data.dewpoint = i18n("N/A"); + data.condition = i18n("N/A"); + data.comforttemp = i18n("N/A"); + data.stationID = i18n("N/A"); + data.stationLat = i18n("N/A"); + data.stationLon = i18n("N/A"); + data.pressure = 0.0; + data.pressureTendency = i18n("N/A"); + data.visibility = 0; + data.humidity = i18n("N/A"); + data.windSpeed = i18n("N/A"); + data.windGust = i18n("N/A"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "currentConditions") + break; + + if (xml.isStartElement()) { + if (xml.name() == "station") { + data.stationID = xml.attributes().value("code").toString(); + data.stationLat = xml.attributes().value("lat").toString(); + data.stationLon = xml.attributes().value("lon").toString(); + } else if (xml.name() == "dateTime") { + parseDateTime(data, xml); + } else if (xml.name() == "condition") { + data.condition = xml.readElementText(); + } else if (xml.name() == "temperature") { + data.temperature = xml.readElementText(); + } else if (xml.name() == "dewpoint") { + data.dewpoint = xml.readElementText(); + } else if (xml.name() == "humidex" || xml.name() == "windChill") { + data.comforttemp = xml.readElementText(); + } else if (xml.name() == "pressure") { + data.pressureTendency = xml.attributes().value("tendency").toString(); + if (data.pressureTendency.isEmpty()) { + data.pressureTendency = "steady"; + } + data.pressure = xml.readElementText().toFloat(); + } else if (xml.name() == "visibility") { + data.visibility = xml.readElementText().toFloat(); + } else if (xml.name() == "relativeHumidity") { + data.humidity = xml.readElementText(); + } else if (xml.name() == "wind") { + parseWindInfo(data, xml); + } + //} else { + // parseUnknownElement(xml); + //} + } + } + if (data.temperature.isEmpty()) { + data.temperature = i18n("N/A"); + } +} + +void EnvCanadaIon::parseWarnings(WeatherData &data, QXmlStreamReader& xml) +{ + WeatherData::WeatherEvent *watch = new WeatherData::WeatherEvent; + WeatherData::WeatherEvent *warning = new WeatherData::WeatherEvent; + + Q_ASSERT(xml.isStartElement() && xml.name() == "warnings"); + QString eventURL = xml.attributes().value("url").toString(); + int flag = 0; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "warnings") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "dateTime") { + if (flag == 1) { + parseDateTime(data, xml, watch); + } + if (flag == 2) { + parseDateTime(data, xml, warning); + } + + if (!warning->timestamp.isEmpty() && !warning->url.isEmpty()) { + data.warnings.append(warning); + warning = new WeatherData::WeatherEvent; + } + if (!watch->timestamp.isEmpty() && !watch->url.isEmpty()) { + data.watches.append(watch); + watch = new WeatherData::WeatherEvent; + } + + } else if (xml.name() == "event") { + // Append new event to list. + QString eventType = xml.attributes().value("type").toString(); + if (eventType == "watch") { + watch->url = eventURL; + watch->type = eventType; + watch->priority = xml.attributes().value("priority").toString(); + watch->description = xml.attributes().value("description").toString(); + flag = 1; + } + + if (eventType == "warning") { + warning->url = eventURL; + warning->type = eventType; + warning->priority = xml.attributes().value("priority").toString(); + warning->description = xml.attributes().value("description").toString(); + flag = 2; + } + } else { + if (xml.name() != "dateTime") { + parseUnknownElement(xml); + } + } + } + } + delete watch; + delete warning; +} + + +void EnvCanadaIon::parseWeatherForecast(WeatherData& data, QXmlStreamReader& xml) +{ + WeatherData::ForecastInfo* forecast = new WeatherData::ForecastInfo; + Q_ASSERT(xml.isStartElement() && xml.name() == "forecastGroup"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "forecastGroup") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "dateTime") { + parseDateTime(data, xml); + } else if (xml.name() == "regionalNormals") { + parseRegionalNormals(data, xml); + } else if (xml.name() == "forecast") { + parseForecast(data, xml, forecast); + forecast = new WeatherData::ForecastInfo; + } else { + parseUnknownElement(xml); + } + } + } + delete forecast; +} + +void EnvCanadaIon::parseRegionalNormals(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "regionalNormals"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "textSummary") { + xml.readElementText(); + } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") { + data.normalHigh = xml.readElementText(); + } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") { + data.normalLow = xml.readElementText(); + } + } + } +} + +void EnvCanadaIon::parseForecast(WeatherData& data, QXmlStreamReader& xml, WeatherData::ForecastInfo *forecast) +{ + + Q_ASSERT(xml.isStartElement() && xml.name() == "forecast"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "forecast") { + data.forecasts.append(forecast); + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "period") { + forecast->forecastPeriod = xml.attributes().value("textForecastName").toString(); + } else if (xml.name() == "textSummary") { + forecast->forecastSummary = xml.readElementText(); + } else if (xml.name() == "abbreviatedForecast") { + parseShortForecast(forecast, xml); + } else if (xml.name() == "temperatures") { + parseForecastTemperatures(forecast, xml); + } else if (xml.name() == "winds") { + parseWindForecast(forecast, xml); + } else if (xml.name() == "precipitation") { + parsePrecipitationForecast(forecast, xml); + } else if (xml.name() == "uv") { + data.UVRating = xml.attributes().value("category").toString(); + parseUVIndex(data, xml); + // else if (xml.name() == "frost") { FIXME: Wait until winter to see what this looks like. + // parseFrost(xml, forecast); + } else { + if (xml.name() != "forecast") { + parseUnknownElement(xml); + } + } + } + } +} + +void EnvCanadaIon::parseShortForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "abbreviatedForecast"); + + QString shortText; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "abbreviatedForecast") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "pop") { + forecast->popPrecent = xml.readElementText(); + } + if (xml.name() == "textSummary") { + shortText = xml.readElementText(); + QMap forecastList; + forecastList = forecastIcons(); + if ((forecast->forecastPeriod == "tonight") || (forecast->forecastPeriod.contains("night"))) { + forecastList["a few clouds"] = FewCloudsNight; + forecastList["cloudy periods"] = PartlyCloudyNight; + forecastList["chance of drizzle mixed with rain"] = ChanceShowersNight; + forecastList["chance of drizzle"] = ChanceShowersNight; + forecastList["chance of drizzle or rain"] = ChanceShowersNight; + forecastList["chance of flurries"] = ChanceSnowNight; + forecastList["chance of light snow"] = ChanceSnowNight; + forecastList["chance of flurries at times heavy"] = ChanceSnowNight; + forecastList["chance of showers or drizzle"] = ChanceShowersNight; + forecastList["chance of showers"] = ChanceShowersNight; + forecastList["clearing"] = ClearNight; + } else { + forecastList["a few clouds"] = FewCloudsDay; + forecastList["cloudy periods"] = PartlyCloudyDay; + forecastList["chance of drizzle mixed with rain"] = ChanceShowersDay; + forecastList["chance of drizzle"] = ChanceShowersDay; + forecastList["chance of drizzle or rain"] = ChanceShowersDay; + forecastList["chance of flurries"] = ChanceSnowDay; + forecastList["chance of light snow"] = ChanceSnowDay; + forecastList["chance of flurries at times heavy"] = ChanceSnowDay; + forecastList["chance of showers or drizzle"] = ChanceShowersDay; + forecastList["chance of showers"] = ChanceShowersDay; + forecastList["clearing"] = ClearDay; + } + forecast->shortForecast = shortText; + forecast->iconName = getWeatherIcon(forecastList, shortText.toLower()); + } + } + } +} + +void EnvCanadaIon::parseUVIndex(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "uv"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "uv") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "index") { + data.UVIndex = xml.readElementText(); + } + if (xml.name() == "textSummary") { + xml.readElementText(); + } + } + } +} + +void EnvCanadaIon::parseForecastTemperatures(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "temperatures"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "temperatures") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "temperature" && xml.attributes().value("class") == "low") { + forecast->forecastTempLow = xml.readElementText(); + } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") { + forecast->forecastTempHigh = xml.readElementText(); + } else if (xml.name() == "textSummary") { + xml.readElementText(); + } + } + } +} + +void EnvCanadaIon::parsePrecipitationForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "precipitation"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "precipitation") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "textSummary") { + forecast->precipForecast = xml.readElementText(); + } else if (xml.name() == "precipType") { + forecast->precipType = xml.readElementText(); + } else if (xml.name() == "accumulation") { + parsePrecipTotals(forecast, xml); + } + } + } +} + +void EnvCanadaIon::parsePrecipTotals(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "accumulation"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "accumulation") { + break; + } + + if (xml.name() == "name") { + xml.readElementText(); + } else if (xml.name() == "amount") { + forecast->precipTotalExpected = xml.readElementText(); + } + } +} + +void EnvCanadaIon::parseWindForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "winds"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "winds") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "textSummary") { + forecast->windForecast = xml.readElementText(); + } else { + if (xml.name() != "winds") { + parseUnknownElement(xml); + } + } + } + } +} + +void EnvCanadaIon::parseYesterdayWeather(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "yesterdayConditions"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "temperature" && xml.attributes().value("class") == "high") { + data.prevHigh = xml.readElementText(); + } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") { + data.prevLow = xml.readElementText(); + } else if (xml.name() == "precip") { + data.prevPrecipType = xml.attributes().value("units").toString(); + if (data.prevPrecipType.isEmpty()) { + data.prevPrecipType = QString::number(KUnitConversion::NoUnit); + } + data.prevPrecipTotal = xml.readElementText(); + } + } + } +} + +void EnvCanadaIon::parseWeatherRecords(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "almanac"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "almanac") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMax") { + data.recordHigh = xml.readElementText().toFloat(); + } else if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMin") { + data.recordLow = xml.readElementText().toFloat(); + } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeRainfall") { + data.recordRain = xml.readElementText().toFloat(); + } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeSnowfall") { + data.recordSnow = xml.readElementText().toFloat(); + } + } + } +} + +void EnvCanadaIon::parseAstronomicals(WeatherData& data, QXmlStreamReader& xml) +{ + Q_ASSERT(xml.isStartElement() && xml.name() == "riseSet"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == "riseSet") { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "disclaimer") { + xml.readElementText(); + } else if (xml.name() == "dateTime") { + parseDateTime(data, xml); + } + } + } +} + +// handle when no XML tag is found +void EnvCanadaIon::parseUnknownElement(QXmlStreamReader& xml) const +{ + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + parseUnknownElement(xml); + } + } +} + +void EnvCanadaIon::updateWeather(const QString& source) +{ + //kDebug() << "updateWeather()"; + + QMap dataFields; + Plasma::DataEngine::Data data; + QStringList fieldList; + QVector forecastList; + int i = 0; + + data.insert("Country", country(source)); + data.insert("Place", QString("%1, %2").arg(city(source)).arg(territory(source))); + data.insert("Region", region(source)); + data.insert("Station", station(source)); + + data.insert("Latitude", latitude(source)); + data.insert("Longitude", longitude(source)); + + // Real weather - Current conditions + data.insert("Observation Period", observationTime(source)); + data.insert("Current Conditions", i18nc("weather condition", condition(source).toUtf8())); + //kDebug() << "i18n condition string: " << qPrintable(condition(source)); + + // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display + QMap conditionList; + conditionList = conditionIcons(); + + const double lati = latitude(source).replace(QRegExp("[^0-9.]"), NULL).toDouble(); + const double longi = longitude(source).replace(QRegExp("[^0-9.]"), NULL).toDouble(); + const Plasma::DataEngine::Data timeData = m_timeEngine->query( + QString("Local|Solar|Latitude=%1|Longitude=%2") + .arg(lati).arg(-1 * longi)); + + if (timeData["Corrected Elevation"].toDouble() < 0.0) { + conditionList["decreasing cloud"] = FewCloudsNight; + conditionList["mostly cloudy"] = PartlyCloudyNight; + conditionList["partly cloudy"] = PartlyCloudyNight; + conditionList["fair"] = FewCloudsNight; + //kDebug() << "Before sunrise/After sunset - using night icons\n"; + } else { + conditionList["decreasing cloud"] = FewCloudsDay; + conditionList["mostly cloudy"] = PartlyCloudyDay; + conditionList["partly cloudy"] = PartlyCloudyDay; + conditionList["fair"] = FewCloudsDay; + //kDebug() << "Using daytime icons\n"; + } + + data.insert("Condition Icon", getWeatherIcon(conditionList, condition(source))); + + dataFields = temperature(source); + data.insert("Temperature", dataFields["temperature"]); + + // Do we have a comfort temperature? if so display it + if (dataFields["comfortTemperature"] != "N/A" && !dataFields["comfortTemperature"].isEmpty()) { + if (dataFields["comfortTemperature"].toFloat() <= 0) { + data.insert("Windchill", QString("%1").arg(dataFields["comfortTemperature"])); + data.insert("Humidex", i18n("N/A")); + } else { + data.insert("Humidex", QString("%1").arg(dataFields["comfortTemperature"])); + data.insert("Windchill", i18n("N/A")); + } + } else { + data.insert("Windchill", i18n("N/A")); + data.insert("Humidex", i18n("N/A")); + } + + // Used for all temperatures + data.insert("Temperature Unit", dataFields["temperatureUnit"]); + + data.insert("Dewpoint", dewpoint(source)); + + dataFields = pressure(source); + data.insert("Pressure", dataFields["pressure"]); + data.insert("Pressure Unit", dataFields["pressureUnit"]); + data.insert("Pressure Tendency", dataFields["pressureTendency"]); + + dataFields = visibility(source); + data.insert("Visibility", dataFields["visibility"]); + data.insert("Visibility Unit", dataFields["visibilityUnit"]); + + dataFields = humidity(source); + data.insert("Humidity", dataFields["humidity"]); + data.insert("Humidity Unit", dataFields["humidityUnit"]); + + dataFields = wind(source); + data.insert("Wind Speed", dataFields["windSpeed"]); + data.insert("Wind Speed Unit", dataFields["windUnit"]); + + data.insert("Wind Gust", dataFields["windGust"]); + data.insert("Wind Direction", dataFields["windDirection"]); + data.insert("Wind Degrees", dataFields["windDegrees"]); + data.insert("Wind Gust Unit", dataFields["windGustUnit"]); + + dataFields = regionalTemperatures(source); + data.insert("Normal High", dataFields["normalHigh"]); + data.insert("Normal Low", dataFields["normalLow"]); + + // Check if UV index is available for the location + dataFields = uvIndex(source); + data.insert("UV Index", dataFields["uvIndex"]); + data.insert("UV Rating", dataFields["uvRating"]); + + dataFields = watches(source); + + // Set number of forecasts per day/night supported + data.insert("Total Watches Issued", m_weatherData[source].watches.size()); + + // Check if we have warnings or watches + for (int i = 0; i < m_weatherData[source].watches.size(); i++) { + fieldList = dataFields[QString("watch %1").arg(i)].split('|'); + data.insert(QString("Watch Priority %1").arg(i), fieldList[0]); + data.insert(QString("Watch Description %1").arg(i), fieldList[1]); + data.insert(QString("Watch Info %1").arg(i), fieldList[2]); + data.insert(QString("Watch Timestamp %1").arg(i), fieldList[3]); + } + + dataFields = warnings(source); + + data.insert("Total Warnings Issued", m_weatherData[source].warnings.size()); + + for (int k = 0; k < m_weatherData[source].warnings.size(); k++) { + fieldList = dataFields[QString("warning %1").arg(k)].split('|'); + data.insert(QString("Warning Priority %1").arg(k), fieldList[0]); + data.insert(QString("Warning Description %1").arg(k), fieldList[1]); + data.insert(QString("Warning Info %1").arg(k), fieldList[2]); + data.insert(QString("Warning Timestamp %1").arg(k), fieldList[3]); + } + + forecastList = forecasts(source); + + // Set number of forecasts per day/night supported + data.insert("Total Weather Days", m_weatherData[source].forecasts.size()); + + foreach(const QString &forecastItem, forecastList) { + fieldList = forecastItem.split('|'); + + data.insert(QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6") \ + .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[5])); + + /* + data.insert(QString("Long Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7|%8") \ + .arg(fieldList[0]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[6]) \ + .arg(fieldList[7]).arg(fieldList[8]).arg(fieldList[9])); + */ + i++; + } + + dataFields = yesterdayWeather(source); + data.insert("Yesterday High", dataFields["prevHigh"]); + data.insert("Yesterday Low", dataFields["prevLow"]); + + data.insert("Yesterday Precip Total", dataFields["prevPrecip"]); + data.insert("Yesterday Precip Unit", dataFields["prevPrecipUnit"]); + + dataFields = sunriseSet(source); + data.insert("Sunrise At", dataFields["sunrise"]); + data.insert("Sunset At", dataFields["sunset"]); + + dataFields = moonriseSet(source); + data.insert("Moonrise At", dataFields["moonrise"]); + data.insert("Moonset At", dataFields["moonset"]); + + dataFields = weatherRecords(source); + data.insert("Record High Temperature", dataFields["recordHigh"]); + data.insert("Record Low Temperature", dataFields["recordLow"]); + + data.insert("Record Rainfall", dataFields["recordRain"]); + data.insert("Record Rainfall Unit", dataFields["recordRainUnit"]); + data.insert("Record Snowfall", dataFields["recordSnow"]); + data.insert("Record Snowfall Unit", dataFields["recordSnowUnit"]); + + data.insert("Credit", i18n("Meteorological data is provided by Environment Canada")); + setData(source, data); +} + +QString const EnvCanadaIon::country(const QString& source) const +{ + // This will always return Canada + return m_weatherData[source].countryName; +} + +QString EnvCanadaIon::territory(const QString& source) const +{ + return m_weatherData[source].shortTerritoryName; +} + +QString EnvCanadaIon::city(const QString& source) const +{ + return m_weatherData[source].cityName; +} + +QString EnvCanadaIon::region(const QString& source) const +{ + return m_weatherData[source].regionName; +} + +QString EnvCanadaIon::station(const QString& source) const +{ + if (!m_weatherData[source].stationID.isEmpty()) { + return m_weatherData[source].stationID.toUpper(); + } + + return i18n("N/A"); +} + +QString EnvCanadaIon::latitude(const QString& source) const +{ + return m_weatherData[source].stationLat; +} + +QString EnvCanadaIon::longitude(const QString& source) const +{ + return m_weatherData[source].stationLon; +} + +QString EnvCanadaIon::observationTime(const QString& source) const +{ + return m_weatherData[source].obsTimestamp; +} + +int EnvCanadaIon::periodHour(const QString& source) const +{ + return m_weatherData[source].iconPeriodHour; +} + +int EnvCanadaIon::periodMinute(const QString& source) const +{ + return m_weatherData[source].iconPeriodMinute; +} + +QString EnvCanadaIon::condition(const QString& source) +{ + if (m_weatherData[source].condition.isEmpty()) { + m_weatherData[source].condition = i18n("N/A"); + } + return (m_weatherData[source].condition.toUtf8()); +} + +QString EnvCanadaIon::dewpoint(const QString& source) const +{ + if (!m_weatherData[source].dewpoint.isEmpty()) { + return (QString::number(m_weatherData[source].dewpoint.toFloat(), 'f', 1)); + } + return i18n("N/A"); +} + +QMap EnvCanadaIon::humidity(const QString& source) const +{ + QMap humidityInfo; + if (!m_weatherData[source].humidity.isEmpty()) { + humidityInfo.insert("humidity", m_weatherData[source].humidity); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::Percent)); + } else { + humidityInfo.insert("humidity", i18n("N/A")); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::NoUnit)); + } + return humidityInfo; +} + +QMap EnvCanadaIon::visibility(const QString& source) const +{ + QMap visibilityInfo; + + if (m_weatherData[source].visibility != 0) { + visibilityInfo.insert("visibility", QString::number(m_weatherData[source].visibility, 'f', 1)); + visibilityInfo.insert("visibilityUnit", QString::number(KUnitConversion::Kilometer)); + } else { + visibilityInfo.insert("visibility", i18n("N/A")); + visibilityInfo.insert("visibilityUnit", QString::number(KUnitConversion::NoUnit)); + } + return visibilityInfo; +} + +QMap EnvCanadaIon::temperature(const QString& source) const +{ + QMap temperatureInfo; + if (!m_weatherData[source].temperature.isEmpty()) { + temperatureInfo.insert("temperature", QString::number(m_weatherData[source].temperature.toFloat(), 'f', 1)); + } + + if (m_weatherData[source].temperature == i18n("N/A")) { + temperatureInfo.insert("temperature", i18n("N/A")); + } + + temperatureInfo.insert("comfortTemperature", i18n("N/A")); + + if (m_weatherData[source].comforttemp != i18n("N/A")) { + temperatureInfo.insert("comfortTemperature", m_weatherData[source].comforttemp); + } + + // This is used for not just current temperature but also 8 days. Cannot be NoUnit. + temperatureInfo.insert("temperatureUnit", QString::number(KUnitConversion::Celsius)); + return temperatureInfo; +} + +QMap EnvCanadaIon::watches(const QString& source) const +{ + QMap watchData; + QString watchType; + for (int i = 0; i < m_weatherData[source].watches.size(); ++i) { + watchType = QString("watch %1").arg(i); + watchData[watchType] = QString("%1|%2|%3|%4").arg(m_weatherData[source].watches[i]->priority) \ + .arg(m_weatherData[source].watches[i]->description) \ + .arg(m_weatherData[source].watches[i]->url) \ + .arg(m_weatherData[source].watches[i]->timestamp); + } + return watchData; +} + +QMap EnvCanadaIon::warnings(const QString& source) const +{ + QMap warningData; + QString warnType; + for (int i = 0; i < m_weatherData[source].warnings.size(); ++i) { + warnType = QString("warning %1").arg(i); + warningData[warnType] = QString("%1|%2|%3|%4").arg(m_weatherData[source].warnings[i]->priority) \ + .arg(m_weatherData[source].warnings[i]->description) \ + .arg(m_weatherData[source].warnings[i]->url) \ + .arg(m_weatherData[source].warnings[i]->timestamp); + } + return warningData; +} + +QVector EnvCanadaIon::forecasts(const QString& source) +{ + QVector forecastData; + + // Do some checks for empty data + for (int i = 0; i < m_weatherData[source].forecasts.size(); ++i) { + if (m_weatherData[source].forecasts[i]->forecastPeriod.isEmpty()) { + m_weatherData[source].forecasts[i]->forecastPeriod = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->shortForecast.isEmpty()) { + m_weatherData[source].forecasts[i]->shortForecast = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->iconName.isEmpty()) { + m_weatherData[source].forecasts[i]->iconName = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->forecastSummary.isEmpty()) { + m_weatherData[source].forecasts[i]->forecastSummary = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->forecastTempHigh.isEmpty()) { + m_weatherData[source].forecasts[i]->forecastTempHigh = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->forecastTempLow.isEmpty()) { + m_weatherData[source].forecasts[i]->forecastTempLow = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->popPrecent.isEmpty()) { + m_weatherData[source].forecasts[i]->popPrecent = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->windForecast.isEmpty()) { + m_weatherData[source].forecasts[i]->windForecast = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->precipForecast.isEmpty()) { + m_weatherData[source].forecasts[i]->precipForecast = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->precipType.isEmpty()) { + m_weatherData[source].forecasts[i]->precipType = i18n("N/A"); + } + if (m_weatherData[source].forecasts[i]->precipTotalExpected.isEmpty()) { + m_weatherData[source].forecasts[i]->precipTotalExpected = i18n("N/A"); + } + } + + for (int i = 0; i < m_weatherData[source].forecasts.size(); ++i) { + // We need to shortform the day/night strings. + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Today")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Today", i18n("day")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Tonight")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Tonight", i18nc("Short for tonight", "nite")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("night")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("night", i18nc("Short for night, appended to the end of the weekday", "nt")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Saturday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Saturday", i18nc("Short for Saturday", "Sat")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Sunday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Sunday", i18nc("Short for Sunday", "Sun")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Monday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Monday", i18nc("Short for Monday", "Mon")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Tuesday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Tuesday", i18nc("Short for Tuesday", "Tue")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Wednesday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Wednesday", i18nc("Short for Wednesday", "Wed")); + } + + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Thursday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Thursday", i18nc("Short for Thursday", "Thu")); + } + if (m_weatherData[source].forecasts[i]->forecastPeriod.contains("Friday")) { + m_weatherData[source].forecasts[i]->forecastPeriod.replace("Friday", i18nc("Short for Friday", "Fri")); + } + + forecastData.append(QString("%1|%2|%3|%4|%5|%6") \ + .arg(m_weatherData[source].forecasts[i]->forecastPeriod) \ + .arg(m_weatherData[source].forecasts[i]->iconName) \ + .arg(i18nc("weather forecast", m_weatherData[source].forecasts[i]->shortForecast.toUtf8())) \ + .arg(m_weatherData[source].forecasts[i]->forecastTempHigh) \ + .arg(m_weatherData[source].forecasts[i]->forecastTempLow) \ + .arg(m_weatherData[source].forecasts[i]->popPrecent)); + //kDebug() << "i18n summary string: " << qPrintable(i18n(m_weatherData[source].forecasts[i]->shortForecast.toUtf8())); + } + return forecastData; +} + +QMap EnvCanadaIon::pressure(const QString& source) const +{ + QMap pressureInfo; + + if (m_weatherData[source].pressure == 0) { + pressureInfo.insert("pressure", i18n("N/A")); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::NoUnit)); + pressureInfo.insert("pressureTendency", "N/A"); + } else { + pressureInfo.insert("pressure", QString::number(m_weatherData[source].pressure, 'f', 1)); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::Kilopascal)); + pressureInfo.insert("pressureTendency", i18nc("pressure tendency", m_weatherData[source].pressureTendency.toUtf8())); + } + return pressureInfo; +} + +QMap EnvCanadaIon::wind(const QString& source) const +{ + QMap windInfo; + + // May not have any winds + if (m_weatherData[source].windSpeed.isEmpty()) { + windInfo.insert("windSpeed", i18n("N/A")); + windInfo.insert("windUnit", QString::number(KUnitConversion::NoUnit)); + } else if (m_weatherData[source].windSpeed.toInt() == 0) { + windInfo.insert("windSpeed", i18nc("wind speed", "Calm")); + windInfo.insert("windUnit", QString::number(KUnitConversion::NoUnit)); + } else { + windInfo.insert("windSpeed", QString::number(m_weatherData[source].windSpeed.toInt())); + windInfo.insert("windUnit", QString::number(KUnitConversion::KilometerPerHour)); + } + + // May not always have gusty winds + if (m_weatherData[source].windGust.isEmpty() || m_weatherData[source].windGust == 0) { + windInfo.insert("windGust", i18n("N/A")); + windInfo.insert("windGustUnit", QString::number(KUnitConversion::NoUnit)); + } else { + windInfo.insert("windGust", QString::number(m_weatherData[source].windGust.toInt())); + windInfo.insert("windGustUnit", QString::number(KUnitConversion::KilometerPerHour)); + } + + if (m_weatherData[source].windDirection.isEmpty() && m_weatherData[source].windSpeed.isEmpty()) { + windInfo.insert("windDirection", i18n("N/A")); + windInfo.insert("windDegrees", i18n("N/A")); + } else if (m_weatherData[source].windSpeed.toInt() == 0) { + windInfo.insert("windDirection", i18nc("wind direction - wind speed is too low to measure", "VR")); // Variable/calm + } else { + windInfo.insert("windDirection", i18nc("wind direction", m_weatherData[source].windDirection.toUtf8())); + windInfo.insert("windDegrees", m_weatherData[source].windDegrees); + } + return windInfo; +} + +QMap EnvCanadaIon::uvIndex(const QString& source) const +{ + QMap uvInfo; + + if (m_weatherData[source].UVRating.isEmpty()) { + uvInfo.insert("uvRating", i18n("N/A")); + } else { + uvInfo.insert("uvRating", m_weatherData[source].UVRating); + } + + if (m_weatherData[source].UVIndex.isEmpty()) { + uvInfo.insert("uvIndex", i18n("N/A")); + } else { + uvInfo.insert("uvIndex", m_weatherData[source].UVIndex); + } + + return uvInfo; +} + +QMap EnvCanadaIon::regionalTemperatures(const QString& source) const +{ + QMap regionalTempInfo; + + if (m_weatherData[source].normalHigh.isEmpty()) { + regionalTempInfo.insert("normalHigh", i18n("N/A")); + } else { + regionalTempInfo.insert("normalHigh", m_weatherData[source].normalHigh); + } + + if (m_weatherData[source].normalLow.isEmpty()) { + regionalTempInfo.insert("normalLow", i18n("N/A")); + } else { + regionalTempInfo.insert("normalLow", m_weatherData[source].normalLow); + } + + return regionalTempInfo; +} + +QMap EnvCanadaIon::yesterdayWeather(const QString& source) const +{ + QMap yesterdayInfo; + + if (m_weatherData[source].prevHigh.isEmpty()) { + yesterdayInfo.insert("prevHigh", i18n("N/A")); + } else { + yesterdayInfo.insert("prevHigh", m_weatherData[source].prevHigh); + } + + if (m_weatherData[source].prevLow.isEmpty()) { + yesterdayInfo.insert("prevLow", i18n("N/A")); + } else { + yesterdayInfo.insert("prevLow", m_weatherData[source].prevLow); + } + + if (m_weatherData[source].prevPrecipTotal == "Trace") { + yesterdayInfo.insert("prevPrecip", i18nc("precipitation total, very little", "Trace")); + return yesterdayInfo; + } + + if (m_weatherData[source].prevPrecipTotal.isEmpty()) { + yesterdayInfo.insert("prevPrecip", i18n("N/A")); + yesterdayInfo.insert("prevPrecipUnit", QString::number(KUnitConversion::NoUnit)); + } else { + yesterdayInfo.insert("prevPrecipTotal", m_weatherData[source].prevPrecipTotal); + if (m_weatherData[source].prevPrecipType == "mm") { + yesterdayInfo.insert("prevPrecipUnit", QString::number(KUnitConversion::Millimeter)); + } else if (m_weatherData[source].prevPrecipType == "cm") { + yesterdayInfo.insert("prevPrecipUnit", QString::number(KUnitConversion::Centimeter)); + } else { + yesterdayInfo.insert("prevPrecipUnit", QString::number(KUnitConversion::NoUnit)); + } + } + + return yesterdayInfo; +} + +QMap EnvCanadaIon::sunriseSet(const QString& source) const +{ + QMap sunInfo; + + if (m_weatherData[source].sunriseTimestamp.isEmpty()) { + sunInfo.insert("sunrise", i18n("N/A")); + } else { + sunInfo.insert("sunrise", m_weatherData[source].sunriseTimestamp); + } + + if (m_weatherData[source].sunsetTimestamp.isEmpty()) { + sunInfo.insert("sunset", i18n("N/A")); + } else { + sunInfo.insert("sunset", m_weatherData[source].sunsetTimestamp); + } + + return sunInfo; +} + +QMap EnvCanadaIon::moonriseSet(const QString& source) const +{ + QMap moonInfo; + + if (m_weatherData[source].moonriseTimestamp.isEmpty()) { + moonInfo.insert("moonrise", i18n("N/A")); + } else { + moonInfo.insert("moonrise", m_weatherData[source].moonriseTimestamp); + } + + if (m_weatherData[source].moonsetTimestamp.isEmpty()) { + moonInfo.insert("moonset", i18n("N/A")); + } else { + moonInfo.insert("moonset", m_weatherData[source].moonsetTimestamp); + } + + return moonInfo; +} + +QMap EnvCanadaIon::weatherRecords(const QString& source) const +{ + QMap recordInfo; + + if (m_weatherData[source].recordHigh == 0) { + recordInfo.insert("recordHigh", i18n("N/A")); + } else { + recordInfo.insert("recordHigh", QString("%1").arg(m_weatherData[source].recordHigh)); + } + + if (m_weatherData[source].recordLow == 0) { + recordInfo.insert("recordLow", i18n("N/A")); + } else { + recordInfo.insert("recordLow", QString("%1").arg(m_weatherData[source].recordLow)); + } + + if (m_weatherData[source].recordRain == 0) { + recordInfo.insert("recordRain", i18n("N/A")); + recordInfo.insert("recordRainUnit", QString::number(KUnitConversion::NoUnit)); + } else { + recordInfo.insert("recordRain", QString("%1").arg(m_weatherData[source].recordRain)); + recordInfo.insert("recordRainUnit", QString::number(KUnitConversion::Millimeter)); + } + + if (m_weatherData[source].recordSnow == 0) { + recordInfo.insert("recordSnow", i18n("N/A")); + recordInfo.insert("recordSnowUnit", QString::number(KUnitConversion::NoUnit)); + } else { + recordInfo.insert("recordSnow", QString("%1").arg(m_weatherData[source].recordSnow)); + recordInfo.insert("recordSnowUnit", QString::number(KUnitConversion::Centimeter)); + } + + return recordInfo; +} + +#include "ion_envcan.moc" diff --git a/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.h b/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.h new file mode 100644 index 00000000..3e17d60c --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/envcan/ion_envcan.h @@ -0,0 +1,261 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for Environment Canada XML data */ + +#ifndef ION_ENVCAN_H +#define ION_ENVCAN_H + +#include +#include + +#include +#include + +#include "../ion.h" +#include "../dataengineconsumer.h" + +class KJob; +namespace KIO +{ + class Job; +} // namespace KIO + +class WeatherData +{ + +public: + // WeatherEvent can have more than one, especially in Canada, eh? :) + struct WeatherEvent { + QString url; + QString type; + QString priority; + QString description; + QString timestamp; + }; + + // Five day forecast + struct ForecastInfo { + QString forecastPeriod; + QString forecastSummary; + QString iconName; + QString shortForecast; + + QString forecastTempHigh; + QString forecastTempLow; + QString popPrecent; + QString windForecast; + + QString precipForecast; + QString precipType; + QString precipTotalExpected; + int forecastHumidity; + }; + + QString countryName; + QString longTerritoryName; + QString shortTerritoryName; + QString cityName; + QString regionName; + QString stationID; + QString stationLat; + QString stationLon; + + // Current observation information. + QString obsTimestamp; + + // Icon info to aproximate periods + int iconPeriodHour; + int iconPeriodMinute; + + QString condition; + QString temperature; + QString dewpoint; + + // In winter windchill, in summer, humidex + QString comforttemp; + + float pressure; + QString pressureTendency; + + float visibility; + QString humidity; + + QString windSpeed; + QString windGust; + QString windDirection; + QString windDegrees; + + QVector watches; + QVector warnings; + + QString normalHigh; + QString normalLow; + + QString forecastTimestamp; + + QString UVIndex; + QString UVRating; + + // 5 day Forecast + QVector forecasts; + + // Historical data from previous day. + QString prevHigh; + QString prevLow; + QString prevPrecipType; + QString prevPrecipTotal; + + // Almanac info + QString sunriseTimestamp; + QString sunsetTimestamp; + QString moonriseTimestamp; + QString moonsetTimestamp; + + // Historical Records + float recordHigh; + float recordLow; + float recordRain; + float recordSnow; +}; + +class KDE_EXPORT EnvCanadaIon : public IonInterface, public Plasma::DataEngineConsumer +{ + Q_OBJECT + +public: + EnvCanadaIon(QObject *parent, const QVariantList &args); + ~EnvCanadaIon(); + bool updateIonSource(const QString& source); // Sync data source with Applet + void updateWeather(const QString& source); + +public Q_SLOTS: + virtual void reset(); + +protected: + void init(); // Setup the city location, fetching the correct URL name. + +protected Q_SLOTS: + void setup_slotDataArrived(KIO::Job *, const QByteArray &); + void setup_slotJobFinished(KJob *); + + void slotDataArrived(KIO::Job *, const QByteArray &); + void slotJobFinished(KJob *); + +private: + /* Environment Canada Methods - Internal for Ion */ + void deleteForecasts(); + + QMap setupConditionIconMappings(void) const; + QMap setupForecastIconMappings(void) const; + + QMap const& conditionIcons(void) const; + QMap const& forecastIcons(void) const; + + // Place information + QString const country(const QString& source) const; + QString territory(const QString& source) const; + QString city(const QString& source) const; + QString region(const QString& source) const; + QString station(const QString& source) const; + QString latitude(const QString& source) const; + QString longitude(const QString& source) const; + + // Current Conditions Weather info + QString observationTime(const QString& source) const; + int periodHour(const QString& source) const; + int periodMinute(const QString& source) const; + QMap watches(const QString& source) const; + QMap warnings(const QString& source) const; + QString condition(const QString& source); + QMap temperature(const QString& source) const; + QString dewpoint(const QString& source) const; + QMap humidity(const QString& source) const; + QMap visibility(const QString& source) const; + QMap pressure(const QString& source) const; + QMap wind(const QString& source) const; + QMap regionalTemperatures(const QString& source) const; + QMap uvIndex(const QString& source) const; + QVector forecasts(const QString& source); + QMap yesterdayWeather(const QString& source) const; + QMap sunriseSet(const QString& source) const; + QMap moonriseSet(const QString& source) const; + QMap weatherRecords(const QString& source) const; + + // Load and Parse the place XML listing + void getXMLSetup(void); + bool readXMLSetup(void); + + // Load and parse the specific place(s) + void getXMLData(const QString& source); + bool readXMLData(const QString& source, QXmlStreamReader& xml); + + // Check if place specified is valid or not + QStringList validate(const QString& source) const; + + // Catchall for unknown XML tags + void parseUnknownElement(QXmlStreamReader& xml) const; + + // Parse weather XML data + void parseWeatherSite(WeatherData& data, QXmlStreamReader& xml); + void parseDateTime(WeatherData& data, QXmlStreamReader& xml, WeatherData::WeatherEvent* event = NULL); + void parseLocations(WeatherData& data, QXmlStreamReader& xml); + void parseConditions(WeatherData& data, QXmlStreamReader& xml); + void parseWarnings(WeatherData& data, QXmlStreamReader& xml); + void parseWindInfo(WeatherData& data, QXmlStreamReader& xml); + void parseWeatherForecast(WeatherData& data, QXmlStreamReader& xml); + void parseRegionalNormals(WeatherData& data, QXmlStreamReader& xml); + void parseForecast(WeatherData& data, QXmlStreamReader& xml, WeatherData::ForecastInfo* forecast); + void parseShortForecast(WeatherData::ForecastInfo* forecast, QXmlStreamReader& xml); + void parseForecastTemperatures(WeatherData::ForecastInfo* forecast, QXmlStreamReader& xml); + void parseWindForecast(WeatherData::ForecastInfo* forecast, QXmlStreamReader& xml); + void parsePrecipitationForecast(WeatherData::ForecastInfo* forecast, QXmlStreamReader& xml); + void parsePrecipTotals(WeatherData::ForecastInfo* forecast, QXmlStreamReader& xml); + void parseUVIndex(WeatherData& data, QXmlStreamReader& xml); + void parseYesterdayWeather(WeatherData& data, QXmlStreamReader& xml); + void parseAstronomicals(WeatherData& data, QXmlStreamReader& xml); + void parseWeatherRecords(WeatherData& data, QXmlStreamReader& xml); + + struct XMLMapInfo { + QString cityName; + QString territoryName; + QString cityCode; + }; + + // Key dicts + QHash m_places; + + // Weather information + QHash m_weatherData; + + // Store KIO jobs + QHash m_jobXml; + QHash m_jobList; + QStringList m_sourcesToReset; + QXmlStreamReader m_xmlSetup; + Plasma::DataEngine *m_timeEngine; + + QDateTime m_dateFormat; + bool emitWhenSetup; + +}; + +K_EXPORT_PLASMA_DATAENGINE(envcan, EnvCanadaIon) + +#endif diff --git a/plasma/generic/dataengines/weather/ions/includes/Ion b/plasma/generic/dataengines/weather/ions/includes/Ion new file mode 100644 index 00000000..4ebf1cf7 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/includes/Ion @@ -0,0 +1 @@ +#include "../../../plasma/weather/ion.h" diff --git a/plasma/generic/dataengines/weather/ions/ion.cpp b/plasma/generic/dataengines/weather/ions/ion.cpp new file mode 100644 index 00000000..4715bc1d --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/ion.cpp @@ -0,0 +1,210 @@ +/***************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public License * + * along with this library; see the file COPYING.LIB. If not, write to * + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * + *****************************************************************************/ + +#include "ion.h" +#include "ion.moc" + +#include + +class IonInterface::Private +{ +public: + Private(IonInterface *i) + : ion(i), + initialized(false) {} + + IonInterface *ion; + bool initialized; +}; + +IonInterface::IonInterface(QObject *parent, const QVariantList &args) + : Plasma::DataEngine(parent, args), + d(new Private(this)) +{ +} + +IonInterface::~IonInterface() +{ + delete d; +} + +/** + * If the ion is not initialized just set the initial data source up even if it's empty, we'll retry once the initialization is done + */ +bool IonInterface::sourceRequestEvent(const QString &source) +{ + kDebug() << "sourceRequested(): " << source; + + // init anyway the data as it's going to be used + // sooner or later (doesnt depend upon initialization + // this will avoid problems if updateIonSource() fails for any reason + // but later it's able to retrieve the data + setData(source, Plasma::DataEngine::Data()); + + // if initialized, then we can try to grab the data + if (d->initialized) { + return updateIonSource(source); + } + + return true; +} + +/** + * Update the ion's datasource. Triggered when a Plasma::DataEngine::connectSource() timeout occurs. + */ +bool IonInterface::updateSourceEvent(const QString& source) +{ + kDebug() << "updateSource(" << source << ")"; + if (d->initialized) { + kDebug() << "Calling updateIonSource(" << source << ")"; + return updateIonSource(source); + } + + return false; +} + +/** + * Set the ion to make sure it is ready to get real data. + */ +void IonInterface::setInitialized(bool initialized) +{ + d->initialized = initialized; + + if (d->initialized) { + updateAllSources(); + } +} + +/** + * Return wind direction svg element to display in applet when given a wind direction. + */ +QString IonInterface::getWindDirectionIcon(const QMap &windDirList, const QString& windDirection) const +{ + switch (windDirList[windDirection.toLower()]) { + case N: + return i18n("N"); + case NNE: + return i18n("NNE"); + case NE: + return i18n("NE"); + case ENE: + return i18n("ENE"); + case E: + return i18n("E"); + case SSE: + return i18n("SSE"); + case SE: + return i18n("SE"); + case ESE: + return i18n("ESE"); + case S: + return i18n("S"); + case NNW: + return i18n("NNW"); + case NW: + return i18n("NW"); + case WNW: + return i18n("WNW"); + case W: + return i18n("W"); + case SSW: + return i18n("SSW"); + case SW: + return i18n("SW"); + case WSW: + return i18n("WSW"); + case VR: + return i18n("N/A"); // For now, we'll make a variable wind icon later on + } + + // No icon available, use 'X' + return i18n("N/A"); +} + +/** + * Return weather icon to display in an applet when given a condition. + */ +QString IonInterface::getWeatherIcon(ConditionIcons condition) const +{ + switch (condition) { + case ClearDay: + return "weather-clear"; + case FewCloudsDay: + return "weather-few-clouds"; + case PartlyCloudyDay: + return "weather-clouds"; + case Overcast: + return "weather-many-clouds"; + case Rain: + return "weather-showers"; + case LightRain: + return "weather-showers-scattered"; + case Showers: + return "weather-showers-scattered"; + case ChanceShowersDay: + return "weather-showers-scattered-day"; + case ChanceShowersNight: + return "weather-showers-scattered-night"; + case ChanceSnowDay: + return "weather-snow-scattered-day"; + case ChanceSnowNight: + return "weather-snow-scattered-night"; + case Thunderstorm: + return "weather-storm"; + case Hail: + return "weather-hail"; + case Snow: + return "weather-snow"; + case LightSnow: + return "weather-snow-scattered"; + case Flurries: + return "weather-snow-scattered"; + case RainSnow: + return "weather-snow-rain"; + case FewCloudsNight: + return "weather-few-clouds-night"; + case PartlyCloudyNight: + return "weather-clouds-night"; + case ClearNight: + return "weather-clear-night"; + case Mist: + return "weather-mist"; + case Haze: + return "weather-mist"; + case FreezingRain: + return "weather-freezing-rain"; + case FreezingDrizzle: + return "weather-freezing-rain"; + case ChanceThunderstormDay: + return "weather-storm-day"; + case ChanceThunderstormNight: + return "weather-storm-night"; + case NotAvailable: + return "weather-none-available"; + } + return "weather-none-available"; +} + +/** + * Return weather icon to display in an applet when given a condition. + */ +QString IonInterface::getWeatherIcon(const QMap &conditionList, const QString& condition) const +{ + return getWeatherIcon(conditionList[condition.toLower()]); +} diff --git a/plasma/generic/dataengines/weather/ions/ion.h b/plasma/generic/dataengines/weather/ions/ion.h new file mode 100644 index 00000000..d7316235 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/ion.h @@ -0,0 +1,132 @@ +/***************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public License * + * along with this library; see the file COPYING.LIB. If not, write to * + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * + *****************************************************************************/ + +#ifndef ION_H +#define ION_H + +#include +#include + +#include "ion_export.h" + +/** +* @author Shawn Starr +* This is the base class to be used to implement new ions for the WeatherEngine. +* The idea is that you can have multiple ions which provide weather information from different services to the engine from which an applet will request the data from. +* +* Basically an ion is a Plasma::DataEngine, which is queried by the WeatherEngine instead of some applet. +*/ +class ION_EXPORT IonInterface : public Plasma::DataEngine +{ + Q_OBJECT + +public: + + enum ConditionIcons { ClearDay = 1, FewCloudsDay, PartlyCloudyDay, Overcast, + Rain, LightRain, Showers, ChanceShowersDay, Thunderstorm, Hail, + Snow, LightSnow, Flurries, FewCloudsNight, ChanceShowersNight, + PartlyCloudyNight, ClearNight, Mist, Haze, FreezingRain, + RainSnow, FreezingDrizzle, ChanceThunderstormDay, ChanceThunderstormNight, + ChanceSnowDay, ChanceSnowNight, NotAvailable + }; + + enum WindDirections { N, NNE, NE, ENE, E, SSE, SE, ESE, S, NNW, NW, WNW, W, SSW, SW, WSW, VR }; + + /** + * Constructor for the ion + * @param parent The parent object. + * @Param args The argument list. + */ + explicit IonInterface(QObject *parent = 0, const QVariantList &args = QVariantList()); + /** + * Destructor for the ion + */ + virtual ~IonInterface(); + + /** + * Returns weather icon filename to display in applet. + * @param condition the current condition being reported. + * @return icon name + */ + QString getWeatherIcon(ConditionIcons condition) const; + + /** + * Returns weather icon filename to display in applet. + * @param conditionList a QList map pair of icons mapped to a enumeration of conditions. + * @param condition the current condition being reported. + * @return icon name + */ + QString getWeatherIcon(const QMap &conditionList, const QString& condition) const; + + /** + * Returns wind icon element to display in applet. + * @param windDirList a QList map pair of wind directions mapped to a enumeration of directions. + * @param windDirection the current wind direction. + * @return svg element for wind direction + */ + QString getWindDirectionIcon(const QMap &windDirList, const QString& windDirection) const; + +public Q_SLOTS: + + /** + * Reimplemented from Plasma::DataEngine + * @param source the name of the datasource to be updated + */ + bool updateSourceEvent(const QString& source); + + /** + * Reimplement for ion to reload data if network status comes back up + */ + virtual void reset() = 0; + +Q_SIGNALS: + void forceUpdate(IonInterface *ion, const QString &source); + +protected: + + /** + * Call this method to flush waiting source requests that may be pending + * initialization + * + * @arg initialized whether or not the ion is currently ready to fetch data + */ + void setInitialized(bool initialized); + + /** + * Reimplemented from Plasma::DataEngine + * @param source The datasource being requested + */ + bool sourceRequestEvent(const QString &source); + + /** + * Reimplement to fetch the data from the ion. + * @arg source the name of the datasource. + * @return true if update was successful, false if failed + */ + virtual bool updateIonSource(const QString &source) = 0; + + friend class WeatherEngine; + +private: + class Private; + Private* const d; +}; + +#endif + diff --git a/plasma/generic/dataengines/weather/ions/ion_export.h b/plasma/generic/dataengines/weather/ions/ion_export.h new file mode 100644 index 00000000..d7f201af --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/ion_export.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE project + Copyright (C) 2007 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ION_EXPORT_H +#define ION_EXPORT_H + +/* needed for KDE_EXPORT and KDE_IMPORT macros */ +#include + +#ifndef ION_EXPORT +# if defined(MAKE_WEATHER_ION_LIB) +/* We are building this library */ +# define ION_EXPORT KDE_EXPORT +# else +/* We are using this library */ +# define ION_EXPORT KDE_IMPORT +# endif +#endif + +# ifndef ION_EXPORT_DEPRECATED +# define ION_EXPORT_DEPRECATED KDE_DEPRECATED ION_EXPORT +# endif + +#endif diff --git a/plasma/generic/dataengines/weather/ions/noaa/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/noaa/CMakeLists.txt new file mode 100644 index 00000000..72dd2cf0 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/noaa/CMakeLists.txt @@ -0,0 +1,8 @@ +SET (ion_noaa_SRCS ion_noaa.cpp) +kde4_add_plugin(ion_noaa ${ion_noaa_SRCS}) +target_link_libraries (ion_noaa ${KDE4_SOLID_LIBS} weather_ion) + +INSTALL (FILES ion-noaa.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +INSTALL (TARGETS ion_noaa DESTINATION ${PLUGIN_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/weather/ions/noaa/ion-noaa.desktop b/plasma/generic/dataengines/weather/ions/noaa/ion-noaa.desktop new file mode 100644 index 00000000..d364f2e1 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/noaa/ion-noaa.desktop @@ -0,0 +1,153 @@ +[Desktop Entry] +Name=NOAA's National Weather Service +Name[ar]=خدمة الطقس الوطني الأمريكي من NOAA +Name[ast]=Serviciu nacional norteamericanu NOAA +Name[be@latin]=Nacyjanalnaja słužba nadvorja „NOAA” +Name[bg]=Метеорологична станция NOAA +Name[bs]=NOAA‑ova nacionalna meteorološka služba +Name[ca]=Servei meteorològic nacional de NOAA +Name[ca@valencia]=Servei meteorològic nacional de NOAA +Name[cs]=Informační služba o počasí agentury NOAA +Name[da]=NOAAs nationale vejrtjeneste +Name[de]=NOAA's nationaler Wetterdienst +Name[el]=Υπηρεσία καιρού NOAA +Name[en_GB]=NOAA's National Weather Service +Name[eo]=Nacia veterservo de NOAA +Name[es]=Servicio nacional norteamericano NOAA +Name[et]=NOAA riiklik ilmateenistus +Name[eu]=NOAA Eguraldi Zerbitzu Nazionala +Name[fi]=NOAA:n kansallinen sääpalvelu +Name[fr]=Service météo national du NOAA +Name[fy]=NOAA's nasjonale waar tsjinst +Name[ga]=Seirbhís Náisiúnta na hAimsire de chuid NOAA +Name[gl]=Servizo meteorolóxico nacional da NOAA +Name[gu]=NOAA ની નેશનલ વેધર સર્વિસ +Name[he]=NOAA's National Weather Service +Name[hi]=एनओएए के राष्ट्रीय मौसम सेवा +Name[hne]=एनओएए के रास्ट्रीय मौसम सेवा +Name[hr]=NOAA-ova usluga nacionalne vremenske proznoze +Name[hu]=NOAA időjárásjelző szolgálat +Name[ia]=Servicio Meteorologic National NOAA +Name[id]=NOAA's National Weather Service +Name[is]=NOAA veðurþjónustan +Name[it]=Servizio meteorologico nazionale del NOAA +Name[ja]=NOAA (アメリカ海洋大気圏局) National Weather Service +Name[kk]=NOAA Ұлттық ауа райы қызметі +Name[km]=សេវា​អាកាសធាតុ​ជាតិ​របស់ NOAA +Name[kn]=NOAA ದ ರಾಷ್ಟ್ರೀಯ ಹವಾಮಾನ ಸೇವೆ +Name[ko]=NOAA 미국 기상 서비스 +Name[lt]=NOAA's National Weather Service +Name[lv]=NOAA's Nacionālais Laikapstākļu Serviss +Name[mk]=Национален сервис за време на NOAA +Name[ml]=നോആ-യുടെ ദേശീയ കാലവസ്ഥാ സേവനം +Name[mr]=NOAA ची राष्ट्रीय हवामान सेवा +Name[nb]=NOAAs nasjonale værtjeneste +Name[nds]=Wederdeenst vun't US-Ozeaankunn- un Wederamt +Name[ne]=NOAA को राष्ट्रिय मौसम सेवा +Name[nl]=NOAA's nationale weerdienst +Name[nn]=NOAAs amerikanske vêrteneste +Name[pa]=NOAA ਦੀ ਕੌਮੀ ਮੌਸਮ ਸਰਵਿਸ +Name[pl]=Narodowa Usługa Pogodowa NOAA +Name[pt]=Serviço Meteorológico Nacional da NOAA +Name[pt_BR]=Serviço Meteorológico Nacional da NOAA +Name[ro]=NOAA's National Weather Service +Name[ru]=Национальная служба погоды США +Name[se]=NOAA amerihkálaš dálkebálvalus +Name[si]=NOAA's ජාතික කාලගුණ සේවාව +Name[sk]=Počasie - NOAA National Weather Service +Name[sl]=NOAA's National Weather Service +Name[sr]=НОАА‑ова национална метеоролошка служба +Name[sr@ijekavian]=НОАА‑ова национална метеоролошка служба +Name[sr@ijekavianlatin]=NOAA‑ova nacionalna meteorološka služba +Name[sr@latin]=NOAA‑ova nacionalna meteorološka služba +Name[sv]=NOAA:s nationella vädertjänst +Name[ta]=NOAA's National Weather Service +Name[te]=NOAA యొక్క జాతీయ వాతావరణ సేవ +Name[tg]=Национальная служба погоды NOAA +Name[th]=บริการพยากรณ์อากาศสากล NOAA +Name[tr]=NOAA Ulusal Hava Durumu Servisi +Name[ug]=NOAA تەمىنلىگەن دۆلەت ھاۋارايى مۇلازىمىتى +Name[uk]=Національна служба погоди NOAA +Name[wa]=NOAA's National Weather Service +Name[x-test]=xxNOAA's National Weather Servicexx +Name[zh_CN]=NOAA 提供的国家天气服务 +Name[zh_TW]=NOAA 的國家天氣服務 +Comment=XML Data from NOAA's National Weather Service +Comment[ar]=معلومات XML من خدمة الطقس الوطني الأمريكي من NOAA +Comment[ast]=Datos XML del serviciu nacional meteorolóxicu norteamericanu NOAA +Comment[be@latin]=Źviestki ŭ farmacie „XML” ad Nacyjanalnaj słužby nadvorja „NOAA” +Comment[bg]=XML данни от метеорологична станция NOAA +Comment[bs]=IksML podaci NOAA‑ove nacionalne meteorološke službe +Comment[ca]=Dades XML del servei meteorològic nacional de NOAA +Comment[ca@valencia]=Dades XML del servei meteorològic nacional de NOAA +Comment[cs]=XML data služby o počasí agentury NOAA +Comment[da]=XML-data fra NOAAs nationale vejrtjeneste +Comment[de]=XML-Daten von NOAA's nationalem Wetterdienst +Comment[el]=Δεδομένα XML από την υπηρεσία καιρού NOAA +Comment[en_GB]=XML Data from NOAA's National Weather Service +Comment[eo]=XML-datumoj el la NOAA nacia vetera servo +Comment[es]=Datos XML del servicio nacional meteorológico norteamericano NOAA +Comment[et]=NOAA riikliku ilmateenistuse XML-andmed +Comment[eu]=XML datuak NOAA Eguraldi Zerbitzu Nazionaletik +Comment[fi]=XML-tietoa NOAA:n kansallisesti sääpalvelusta +Comment[fr]=Données XML du service météo national du NOAA +Comment[fy]=XML Data fan NOAA's nasjonale waar tsjinst +Comment[ga]=Sonraí XML ó Sheirbhís Náisiúnta na hAimsire de chuid NOAA +Comment[gl]=Datos XML do Servizo meteorolóxico nacional da NOAA +Comment[gu]=NOAA ની નેશનલ વેધર સર્વિસ તરફથી XML માહિતી +Comment[he]=מידע ב־XML מ־NOAA's National Weather Service +Comment[hi]=एनओएए के राष्ट्रीय मौसम सेवा से एक्सएमएल डाटा +Comment[hne]=एनओएए के रास्ट्रीय मौसम सेवा से एक्सएमएल डाटा +Comment[hr]=XML podaci iz NOAA-ove usluge nacionalne vremenske prognoze +Comment[hu]=XML adatok a NOAA időjárásjelző szolgálattól +Comment[ia]=Datos XML ex Servicio National Meteorologic NOAA +Comment[id]=Data XML dari NOAA's National Weather Service +Comment[is]=XML gögn frá NOAA veðurþjónustunni +Comment[it]=Dati XML dal servizio meteorologico nazionale del NOAA +Comment[ja]=NOAA (アメリカ海洋大気圏局) National Weather Service の XML データ +Comment[kk]=NOAA Ұлттық ауа райы қызметінің XML дерегі +Comment[km]=ទិន្នន័យ XML ពី​សេវា​អាកាសធាតុ​ជាតិ​របស់ NOAA +Comment[kn]=NOAA ದ ರಾಷ್ಟ್ರೀಯ ಹವಾಮಾನ ಸೇವೆಯಿಂದ XML ದತ್ತ +Comment[ko]=NOAA 미국 기상 서비스의 XML 데이터 +Comment[lt]=XML duomenys iš NOAA's National Weather Service +Comment[lv]=XML dati no NOAA Nacionālā Laikapstākļu Servisa (ASV) +Comment[mk]=XML-податоци од Националниот сервис за време на NOAA +Comment[ml]=നോആ-യുടെ ദേശീയി കാലവസ്ഥാ സേവനത്തില്‍ നിന്നുമുള്ള എക്സ്എംഎല്‍ ഡേറ്റാ +Comment[mr]=NOAA च्या राष्ट्रीय हवामान सेवा पासून XML माहिती +Comment[nb]=XML-data fra NOAAs nasjonale værtjeneste +Comment[nds]=XML-Daten vun't US-Ozeaankunn- un Wederamt +Comment[ne]=NOAA को राष्ट्रिय मौसम सेवाबाट एक्षएमएल डेटा +Comment[nl]=XML-gegevens van NOAA's nationale weerdienst +Comment[nn]=XML-data frå NOAAs amerikanske vêrteneste +Comment[pa]=NOAA ਦੀ ਕੌਮੀ ਮੌਸਮ ਸਰਵਿਸ ਤੋਂ XML ਡਾਟਾ +Comment[pl]=Dane XML z Narodowej Usługi Pogodowej NOAA +Comment[pt]=Dados em XML do Serviço Meteorológico Nacional da NOAA +Comment[pt_BR]=Dados em XML do Serviço Meteorológico Nacional da NOAA +Comment[ro]=Date XML de la „NOAA's National Weather Service” +Comment[ru]=Данные в формате XML от NOAA +Comment[se]=XML-dáhtat NOAA amerihkálaš dálkebálvalusas +Comment[si]=NOAA හී ජාතික කාලගුණ සේවාව වෙතින් XML දත්ත +Comment[sk]=XML dáta z NOAA National Weather Service +Comment[sl]=Podatki XML od NOAA's National Weather Service +Comment[sr]=ИксМЛ подаци НОАА‑ове националне метеоролошке службе +Comment[sr@ijekavian]=ИксМЛ подаци НОАА‑ове националне метеоролошке службе +Comment[sr@ijekavianlatin]=XML podaci NOAA‑ove nacionalne meteorološke službe +Comment[sr@latin]=XML podaci NOAA‑ove nacionalne meteorološke službe +Comment[sv]=XML-data från NOAA:s nationella vädertjänst +Comment[ta]=XML Data from NOAA's National Weather Service +Comment[te]=NOAA యొక్క జాతీయ వాతావరణ సేవనుండి XML డాటా +Comment[tg]=Маълумоти XML аз NOAA's National Weather Service +Comment[th]=ข้อมูล XML จากบริการพยากรณ์อากาศสากล NOAA +Comment[tr]=NOAA Ulusal Hava Durumu Servisi'nden XML Verisi +Comment[ug]=NOAA دۆلەت ھاۋارايى مۇلازىمىتى تەمىنلىگەن XML سانلىق-مەلۇماتى +Comment[uk]=Дані XML з національної служби погоди NOAA +Comment[wa]=Dinêyes XML då NOAA's National Weather Service +Comment[x-test]=xxXML Data from NOAA's National Weather Servicexx +Comment[zh_CN]=NOAA 国家天气服务提供的 XML 数据 +Comment[zh_TW]=從 NOAA 的國家天氣服務來的 XML 資料 +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-ParentApp=weatherengine +Type=Service +Icon=noneyet +X-KDE-Library=ion_noaa +X-KDE-PluginInfo-Name=noaa diff --git a/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.cpp b/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.cpp new file mode 100644 index 00000000..c5b899cb --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.cpp @@ -0,0 +1,967 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for NOAA's National Weather Service XML data */ + +#include "ion_noaa.h" + +#include +#include + +#include + +QMap NOAAIon::setupWindIconMappings(void) const +{ + QMap windDir; + windDir["north"] = N; + windDir["northeast"] = NE; + windDir["south"] = S; + windDir["southwest"] = SW; + windDir["east"] = E; + windDir["southeast"] = SE; + windDir["west"] = W; + windDir["northwest"] = NW; + windDir["calm"] = VR; + return windDir; +} + +QMap NOAAIon::setupConditionIconMappings(void) const +{ + + QMap conditionList; + return conditionList; +} + +QMap const& NOAAIon::conditionIcons(void) const +{ + static QMap const condval = setupConditionIconMappings(); + return condval; +} + +QMap const& NOAAIon::windIcons(void) const +{ + static QMap const wval = setupWindIconMappings(); + return wval; +} + +// ctor, dtor +NOAAIon::NOAAIon(QObject *parent, const QVariantList &args) + : IonInterface(parent, args) +{ + Q_UNUSED(args) +} + +void NOAAIon::reset() +{ + m_sourcesToReset = sources(); + getXMLSetup(); +} + +NOAAIon::~NOAAIon() +{ +} + +// Get the master list of locations to be parsed +void NOAAIon::init() +{ + // Get the real city XML URL so we can parse this + getXMLSetup(); + + m_timeEngine = dataEngine("time"); +} + +QStringList NOAAIon::validate(const QString& source) const +{ + QStringList placeList; + QString station; + QString sourceNormalized = source.toUpper(); + + QHash::const_iterator it = m_places.constBegin(); + // If the source name might look like a station ID, check these too and return the name + bool checkState = source.count() == 2; + + while (it != m_places.constEnd()) { + if (checkState) { + if (it.value().stateName == source) { + placeList.append(QString("place|").append(it.key())); + } + } else if (it.key().toUpper().contains(sourceNormalized)) { + placeList.append(QString("place|").append(it.key())); + } else if (it.value().stationID == sourceNormalized) { + station = QString("place|").append(it.key()); + } + + ++it; + } + + placeList.sort(); + if (!station.isEmpty()) { + placeList.prepend(station); + } + + return placeList; +} + +bool NOAAIon::updateIonSource(const QString& source) +{ + // We expect the applet to send the source in the following tokenization: + // ionname:validate:place_name - Triggers validation of place + // ionname:weather:place_name - Triggers receiving weather of place + + QStringList sourceAction = source.split('|'); + + // Guard: if the size of array is not 2 then we have bad data, return an error + if (sourceAction.size() < 2) { + setData(source, "validate", "noaa|malformed"); + return true; + } + + if (sourceAction[1] == "validate" && sourceAction.size() > 2) { + QStringList result = validate(sourceAction[2]); + + if (result.size() == 1) { + setData(source, "validate", QString("noaa|valid|single|").append(result.join("|"))); + return true; + } else if (result.size() > 1) { + setData(source, "validate", QString("noaa|valid|multiple|").append(result.join("|"))); + return true; + } else if (result.size() == 0) { + setData(source, "validate", QString("noaa|invalid|single|").append(sourceAction[2])); + return true; + } + } else if (sourceAction[1] == "weather" && sourceAction.size() > 2) { + getXMLData(source); + return true; + } else { + setData(source, "validate", "noaa|malformed"); + return true; + } + + return false; +} + +// Parses city list and gets the correct city based on ID number +void NOAAIon::getXMLSetup() const +{ + KIO::TransferJob *job = KIO::get(KUrl("http://www.weather.gov/data/current_obs/index.xml"), KIO::NoReload, KIO::HideProgressInfo); + + if (job) { + connect(job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(setup_slotDataArrived(KIO::Job*,QByteArray))); + connect(job, SIGNAL(result(KJob*)), this, SLOT(setup_slotJobFinished(KJob*))); + } else { + kDebug() << "Could not create place name list transfer job"; + } +} + +// Gets specific city XML data +void NOAAIon::getXMLData(const QString& source) +{ + foreach (const QString &fetching, m_jobList) { + if (fetching == source) { + // already getting this source and awaiting the data + return; + } + } + + QString dataKey = source; + dataKey.remove("noaa|weather|"); + KUrl url = m_places[dataKey].XMLurl; + + // If this is empty we have no valid data, send out an error and abort. + if (url.url().isEmpty()) { + setData(source, "validate", QString("noaa|malformed")); + return; + } + + KIO::TransferJob * const m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_jobXml.insert(m_job, new QXmlStreamReader); + m_jobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, SLOT(slotJobFinished(KJob*))); + } +} + +void NOAAIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + Q_UNUSED(job) + + if (data.isEmpty()) { + return; + } + + // Send to xml. + m_xmlSetup.addData(data); +} + +void NOAAIon::slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + if (data.isEmpty() || !m_jobXml.contains(job)) { + return; + } + + // Send to xml. + m_jobXml[job]->addData(data); +} + +void NOAAIon::slotJobFinished(KJob *job) +{ + // Dual use method, if we're fetching location data to parse we need to do this first + const QString source(m_jobList.value(job)); + removeAllData(source); + QXmlStreamReader *reader = m_jobXml.value(job); + if (reader) { + readXMLData(m_jobList[job], *reader); + } + + // Now that we have the longitude and latitude, fetch the seven day forecast. + getForecast(m_jobList[job]); + + m_jobList.remove(job); + m_jobXml.remove(job); + delete reader; +} + +void NOAAIon::setup_slotJobFinished(KJob *job) +{ + Q_UNUSED(job) + const bool success = readXMLSetup(); + setInitialized(success); + + foreach (const QString &source, m_sourcesToReset) { + updateSourceEvent(source); + } +} + +void NOAAIon::parseStationID() +{ + QString state; + QString stationName; + QString stationID; + QString xmlurl; + + while (!m_xmlSetup.atEnd()) { + m_xmlSetup.readNext(); + + if (m_xmlSetup.isEndElement() && m_xmlSetup.name() == "station") { + if (!xmlurl.isEmpty()) { + NOAAIon::XMLMapInfo info; + info.stateName = state; + info.stationName = stationName; + info.stationID = stationID; + info.XMLurl = xmlurl; + + QString tmp = stationName + ", " + state; // Build the key name. + m_places[tmp] = info; + } + break; + } + + if (m_xmlSetup.isStartElement()) { + if (m_xmlSetup.name() == "station_id") { + stationID = m_xmlSetup.readElementText(); + } else if (m_xmlSetup.name() == "state") { + state = m_xmlSetup.readElementText(); + } else if (m_xmlSetup.name() == "station_name") { + stationName = m_xmlSetup.readElementText(); + } else if (m_xmlSetup.name() == "xml_url") { + xmlurl = m_xmlSetup.readElementText().replace("http://", "http://www."); + } else { + parseUnknownElement(m_xmlSetup); + } + } + } +} + +void NOAAIon::parseStationList() +{ + while (!m_xmlSetup.atEnd()) { + m_xmlSetup.readNext(); + + if (m_xmlSetup.isEndElement()) { + break; + } + + if (m_xmlSetup.isStartElement()) { + if (m_xmlSetup.name() == "station") { + parseStationID(); + } else { + parseUnknownElement(m_xmlSetup); + } + } + } +} + +// Parse the city list and store into a QMap +bool NOAAIon::readXMLSetup() +{ + bool success = false; + while (!m_xmlSetup.atEnd()) { + m_xmlSetup.readNext(); + + if (m_xmlSetup.isStartElement()) { + if (m_xmlSetup.name() == "wx_station_index") { + parseStationList(); + success = true; + } + } + } + return (!m_xmlSetup.error() && success); +} + +void NOAAIon::parseWeatherSite(WeatherData& data, QXmlStreamReader& xml) +{ + data.temperature_C = i18n("N/A"); + data.temperature_F = i18n("N/A"); + data.dewpoint_C = i18n("N/A"); + data.dewpoint_F = i18n("N/A"); + data.weather = i18n("N/A"); + data.stationID = i18n("N/A"); + data.pressure = i18n("N/A"); + data.visibility = i18n("N/A"); + data.humidity = i18n("N/A"); + data.windSpeed = i18n("N/A"); + data.windGust = i18n("N/A"); + data.windchill_F = i18n("N/A"); + data.windchill_C = i18n("N/A"); + data.heatindex_F = i18n("N/A"); + data.heatindex_C = i18n("N/A"); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == "location") { + data.locationName = xml.readElementText(); + } else if (xml.name() == "station_id") { + data.stationID = xml.readElementText(); + } else if (xml.name() == "latitude") { + data.stationLat = xml.readElementText(); + } else if (xml.name() == "longitude") { + data.stationLon = xml.readElementText(); + } else if (xml.name() == "observation_time") { + data.observationTime = xml.readElementText(); + QStringList tmpDateStr = data.observationTime.split(' '); + data.observationTime = QString("%1 %2").arg(tmpDateStr[6]).arg(tmpDateStr[7]); + m_dateFormat = QDateTime::fromString(data.observationTime, "h:mm ap"); + data.iconPeriodHour = m_dateFormat.toString("HH"); + data.iconPeriodAP = m_dateFormat.toString("ap"); + + } else if (xml.name() == "weather") { + data.weather = xml.readElementText(); + // Pick which icon set depending on period of day + } else if (xml.name() == "temp_f") { + data.temperature_F = xml.readElementText(); + } else if (xml.name() == "temp_c") { + data.temperature_C = xml.readElementText(); + } else if (xml.name() == "relative_humidity") { + data.humidity = xml.readElementText(); + } else if (xml.name() == "wind_dir") { + data.windDirection = xml.readElementText(); + } else if (xml.name() == "wind_mph") { + data.windSpeed = xml.readElementText(); + } else if (xml.name() == "wind_gust_mph") { + data.windGust = xml.readElementText(); + } else if (xml.name() == "pressure_in") { + data.pressure = xml.readElementText(); + } else if (xml.name() == "dewpoint_f") { + data.dewpoint_F = xml.readElementText(); + } else if (xml.name() == "dewpoint_c") { + data.dewpoint_C = xml.readElementText(); + } else if (xml.name() == "heat_index_f") { + data.heatindex_F = xml.readElementText(); + } else if (xml.name() == "heat_index_c") { + data.heatindex_C = xml.readElementText(); + } else if (xml.name() == "windchill_f") { + data.windchill_F = xml.readElementText(); + } else if (xml.name() == "windchill_c") { + data.windchill_C = xml.readElementText(); + } else if (xml.name() == "visibility_mi") { + data.visibility = xml.readElementText(); + } else { + parseUnknownElement(xml); + } + } + } +} + +// Parse Weather data main loop, from here we have to decend into each tag pair +bool NOAAIon::readXMLData(const QString& source, QXmlStreamReader& xml) +{ + WeatherData data; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + if (xml.name() == "current_observation") { + parseWeatherSite(data, xml); + } else { + parseUnknownElement(xml); + } + } + } + + m_weatherData[source] = data; + return !xml.error(); +} + +// handle when no XML tag is found +void NOAAIon::parseUnknownElement(QXmlStreamReader& xml) const +{ + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + break; + } + + if (xml.isStartElement()) { + parseUnknownElement(xml); + } + } +} + +void NOAAIon::updateWeather(const QString& source) +{ + QMap dataFields; + Plasma::DataEngine::Data data; + + data.insert("Country", country(source)); + data.insert("Place", place(source)); + data.insert("Station", station(source)); + + data.insert("Latitude", latitude(source)); + data.insert("Longitude", longitude(source)); + + // Real weather - Current conditions + data.insert("Observation Period", observationTime(source)); + data.insert("Current Conditions", conditionI18n(source)); + kDebug() << "i18n condition string: " << qPrintable(conditionI18n(source)); + + // Determine the weather icon based on the current time and computed sunrise/sunset time. + const Plasma::DataEngine::Data timeData = m_timeEngine->query( + QString("Local|Solar|Latitude=%1|Longitude=%2") + .arg(latitude(source)).arg(longitude(source))); + + QTime sunriseTime = timeData["Sunrise"].toDateTime().time(); + QTime sunsetTime = timeData["Sunset"].toDateTime().time(); + QTime currentTime = QDateTime::currentDateTime().time(); + + // Provide mapping for the condition-type to the icons to display + if (currentTime > sunriseTime && currentTime < sunsetTime) { + // Day + QString weather = condition(source).toLower(); + ConditionIcons condition = getConditionIcon(weather, true); + data.insert("Condition Icon", getWeatherIcon(condition)); + kDebug() << "Using daytime icons\n"; + } else { + // Night + QString weather = condition(source).toLower(); + ConditionIcons condition = getConditionIcon(weather, false); + data.insert("Condition Icon", getWeatherIcon(condition)); + kDebug() << "Using nighttime icons\n"; + } + + dataFields = temperature(source); + data.insert("Temperature", dataFields["temperature"]); + data.insert("Temperature Unit", dataFields["temperatureUnit"]); + + // Do we have a comfort temperature? if so display it + if (dataFields["comfortTemperature"] != "N/A") { + if (m_weatherData[source].windchill_F != "NA") { + data.insert("Windchill", QString("%1").arg(dataFields["comfortTemperature"])); + data.insert("Humidex", i18n("N/A")); + } + if (m_weatherData[source].heatindex_F != "NA" && m_weatherData[source].temperature_F.toInt() != m_weatherData[source].heatindex_F.toInt()) { + data.insert("Humidex", QString("%1").arg(dataFields["comfortTemperature"])); + data.insert("Windchill", i18n("N/A")); + } + } else { + data.insert("Windchill", i18n("N/A")); + data.insert("Humidex", i18n("N/A")); + } + + data.insert("Dewpoint", dewpoint(source)); + dataFields = pressure(source); + data.insert("Pressure", dataFields["pressure"]); + data.insert("Pressure Unit", dataFields["pressureUnit"]); + + dataFields = visibility(source); + data.insert("Visibility", dataFields["visibility"]); + data.insert("Visibility Unit", dataFields["visibilityUnit"]); + + dataFields = humidity(source); + data.insert("Humidity", dataFields["humidity"]); + data.insert("Humidity Unit", dataFields["humidityUnit"]); + + // Set number of forecasts per day/night supported, none for this ion right now + data.insert(QString("Total Weather Days"), 0); + + dataFields = wind(source); + data.insert("Wind Speed", dataFields["windSpeed"]); + data.insert("Wind Speed Unit", dataFields["windUnit"]); + + data.insert("Wind Gust", dataFields["windGust"]); + data.insert("Wind Gust Unit", dataFields["windGustUnit"]); + data.insert("Wind Direction", getWindDirectionIcon(windIcons(), dataFields["windDirection"].toLower())); + data.insert("Credit", i18n("Data provided by NOAA National Weather Service")); + + int dayIndex = 0; + foreach(const WeatherData::Forecast &forecast, m_weatherData[source].forecasts) { + + ConditionIcons icon = getConditionIcon(forecast.summary.toLower(), true); + QString iconName = getWeatherIcon(icon); + + /* Sometimes the forecast for the later days is unavailable, if so skip remianing days + * since their forecast data is probably unavailable. + */ + if (forecast.low.isEmpty() || forecast.high.isEmpty()) { + break; + } + + // Get the short day name for the forecast + data.insert(QString("Short Forecast Day %1").arg(dayIndex), QString("%1|%2|%3|%4|%5|%6") + .arg(forecast.day).arg(iconName) + .arg(i18nc("weather forecast", forecast.summary.toUtf8())) + .arg(forecast.high).arg(forecast.low).arg("N/U")); + dayIndex++; + } + + // Set number of forecasts per day/night supported + data.insert("Total Weather Days", dayIndex); + + + + setData(source, data); +} + +QString const NOAAIon::country(const QString& source) const +{ + Q_UNUSED(source); + return QString("USA"); +} + +QString NOAAIon::place(const QString& source) const +{ + return m_weatherData[source].locationName; +} + +QString NOAAIon::station(const QString& source) const +{ + return m_weatherData[source].stationID; +} + +QString NOAAIon::latitude(const QString& source) const +{ + return m_weatherData[source].stationLat; +} + +QString NOAAIon::longitude(const QString& source) const +{ + return m_weatherData[source].stationLon; +} + +QString NOAAIon::observationTime(const QString& source) const +{ + return m_weatherData[source].observationTime; +} + +int NOAAIon::periodHour(const QString& source) const +{ + return m_weatherData[source].iconPeriodHour.toInt(); +} + +QString NOAAIon::condition(const QString& source) +{ + if (m_weatherData[source].weather.isEmpty() || m_weatherData[source].weather == "NA") { + m_weatherData[source].weather = "N/A"; + } + return m_weatherData[source].weather; +} + +QString NOAAIon::conditionI18n(const QString& source) +{ + if (condition(source) == "N/A") { + return i18n("N/A"); + } else { + return i18nc("weather condition", condition(source).toUtf8()); + } +} + +QString NOAAIon::dewpoint(const QString& source) const +{ + return m_weatherData[source].dewpoint_F; +} + +QMap NOAAIon::humidity(const QString& source) const +{ + QMap humidityInfo; + if (m_weatherData[source].humidity == "NA") { + humidityInfo.insert("humidity", QString(i18n("N/A"))); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::NoUnit)); + return humidityInfo; + } else { + humidityInfo.insert("humidity", m_weatherData[source].humidity); + humidityInfo.insert("humidityUnit", QString::number(KUnitConversion::Percent)); + } + + return humidityInfo; +} + +QMap NOAAIon::visibility(const QString& source) const +{ + QMap visibilityInfo; + if (m_weatherData[source].visibility.isEmpty()) { + visibilityInfo.insert("visibility", QString(i18n("N/A"))); + visibilityInfo.insert("visibilityUnit", QString::number(KUnitConversion::NoUnit)); + return visibilityInfo; + } + if (m_weatherData[source].visibility == "NA") { + visibilityInfo.insert("visibility", QString(i18n("N/A"))); + visibilityInfo.insert("visibilityUnit", QString::number(KUnitConversion::NoUnit)); + } else { + visibilityInfo.insert("visibility", m_weatherData[source].visibility); + visibilityInfo.insert("visibilityUnit", QString::number(KUnitConversion::Mile)); + } + return visibilityInfo; +} + +QMap NOAAIon::temperature(const QString& source) const +{ + QMap temperatureInfo; + temperatureInfo.insert("temperature", m_weatherData[source].temperature_F); + temperatureInfo.insert("temperatureUnit", QString::number(KUnitConversion::Fahrenheit)); + temperatureInfo.insert("comfortTemperature", i18n("N/A")); + + if (m_weatherData[source].heatindex_F != "NA" && m_weatherData[source].windchill_F == "NA") { + temperatureInfo.insert("comfortTemperature", m_weatherData[source].heatindex_F); + } + + if (m_weatherData[source].windchill_F != "NA" && m_weatherData[source].heatindex_F == "NA") { + temperatureInfo.insert("comfortTemperature", m_weatherData[source].windchill_F); + } + + return temperatureInfo; +} + +QMap NOAAIon::pressure(const QString& source) const +{ + QMap pressureInfo; + if (m_weatherData[source].pressure.isEmpty()) { + pressureInfo.insert("pressure", i18n("N/A")); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::NoUnit)); + return pressureInfo; + } + + if (m_weatherData[source].pressure == "NA") { + pressureInfo.insert("pressure", i18n("N/A")); + pressureInfo.insert("visibilityUnit", QString::number(KUnitConversion::NoUnit)); + } else { + pressureInfo.insert("pressure", m_weatherData[source].pressure); + pressureInfo.insert("pressureUnit", QString::number(KUnitConversion::InchesOfMercury)); + } + return pressureInfo; +} + +QMap NOAAIon::wind(const QString& source) const +{ + QMap windInfo; + + // May not have any winds + if (m_weatherData[source].windSpeed == "NA") { + windInfo.insert("windSpeed", i18nc("wind speed", "Calm")); + windInfo.insert("windUnit", QString::number(KUnitConversion::NoUnit)); + } else { + windInfo.insert("windSpeed", QString::number(m_weatherData[source].windSpeed.toFloat(), 'f', 1)); + windInfo.insert("windUnit", QString::number(KUnitConversion::MilePerHour)); + } + + // May not always have gusty winds + if (m_weatherData[source].windGust == "NA" || m_weatherData[source].windGust == "N/A") { + windInfo.insert("windGust", i18n("N/A")); + windInfo.insert("windGustUnit", QString::number(KUnitConversion::NoUnit)); + } else { + windInfo.insert("windGust", QString::number(m_weatherData[source].windGust.toFloat(), 'f', 1)); + windInfo.insert("windGustUnit", QString::number(KUnitConversion::MilePerHour)); + } + + if (m_weatherData[source].windDirection.isEmpty()) { + windInfo.insert("windDirection", i18n("N/A")); + } else { + windInfo.insert("windDirection", i18nc("wind direction", m_weatherData[source].windDirection.toUtf8())); + } + return windInfo; +} + +/** + * Determine the condition icon based on the list of possible NOAA weather conditions as defined at + * and + * Since the number of NOAA weather conditions need to be fitted into the narowly defined groups in IonInterface::ConditionIcons, we + * try to group the NOAA conditions as best as we can based on their priorities/severity. + */ +IonInterface::ConditionIcons NOAAIon::getConditionIcon(const QString& weather, bool isDayTime) const +{ + // Consider any type of storm, tornado or funnel to be a thunderstorm. + if (weather.contains("thunderstorm") || weather.contains("funnel") || + weather.contains("tornado") || weather.contains("storm") || weather.contains("tstms")) { + + if (weather.contains("vicinity") || weather.contains("chance")) { + if (isDayTime) { + return IonInterface::ChanceThunderstormDay; + } else { + return IonInterface::ChanceThunderstormNight; + } + } + return IonInterface::Thunderstorm; + + } else if (weather.contains("pellets") || weather.contains("crystals") || + weather.contains("hail")) { + return IonInterface::Hail; + + } else if (((weather.contains("rain") || weather.contains("drizzle") || + weather.contains("showers")) && weather.contains("snow")) || weather.contains("wintry mix")) { + return IonInterface::RainSnow; + + } else if (weather.contains("snow") && weather.contains("light")) { + return IonInterface::LightSnow; + + } else if (weather.contains("snow")) { + + if (weather.contains("vicinity") || weather.contains("chance")) { + if (isDayTime) { + return IonInterface::ChanceSnowDay; + } else { + return IonInterface::ChanceSnowNight; + } + } + return IonInterface::Snow; + + } else if (weather.contains("freezing rain")) { + return IonInterface::FreezingRain; + + } else if (weather.contains("freezing drizzle")) { + return IonInterface::FreezingDrizzle; + + } else if (weather.contains("showers")) { + + if (weather.contains("vicinity") || weather.contains("chance")) { + if (isDayTime) { + return IonInterface::ChanceShowersDay; + } else { + return IonInterface::ChanceShowersNight; + } + } + return IonInterface::Showers; + + } else if (weather.contains("light rain") || weather.contains("drizzle")) { + return IonInterface::LightRain; + + } else if (weather.contains("rain")) { + return IonInterface::Rain; + + } else if (weather.contains("few clouds") || weather.contains("mostly sunny") || + weather.contains("mostly clear") || weather.contains("increasing clouds") || + weather.contains("becoming cloudy") || weather.contains("clearing") || + weather.contains("decreasing clouds") || weather.contains("becoming sunny")) { + if(isDayTime) { + return IonInterface::FewCloudsDay; + } else { + return IonInterface::FewCloudsNight; + } + } else if (weather.contains("partly cloudy") || weather.contains("partly sunny") || + weather.contains("partly clear")) { + if(isDayTime) { + return IonInterface::PartlyCloudyDay; + } else { + return IonInterface::PartlyCloudyNight; + } + } else if (weather.contains("overcast") || weather.contains("cloudy")) { + return IonInterface::Overcast; + + } else if (weather.contains("haze") || weather.contains("smoke") || + weather.contains("dust") || weather.contains("sand")) { + return IonInterface::Haze; + + } else if (weather.contains("fair") || weather.contains("clear") || weather.contains("sunny")) { + if (isDayTime) { + return IonInterface::ClearDay; + } else { + return IonInterface::ClearNight; + } + } else if (weather.contains("fog")) { + return IonInterface::Mist; + + } else { + return IonInterface::NotAvailable; + + } +} + +void NOAAIon::getForecast(const QString& source) +{ + /* Assuming that we have the latitude and longitude data at this point, get the 7-day + * forecast. + */ + KUrl url = QString("http://www.weather.gov/forecasts/xml/sample_products/browser_interface/" + "ndfdBrowserClientByDay.php?lat=%1&lon=%2&format=24+hourly&numDays=7") + .arg(latitude(source)).arg(longitude(source)); + + KIO::TransferJob * const m_job = KIO::get(url, KIO::Reload, KIO::HideProgressInfo); + m_jobXml.insert(m_job, new QXmlStreamReader); + m_jobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(forecast_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, SLOT(forecast_slotJobFinished(KJob*))); + } +} + +void NOAAIon::forecast_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + if (data.isEmpty() || !m_jobXml.contains(job)) { + return; + } + + // Send to xml. + m_jobXml[job]->addData(data); +} + +void NOAAIon::forecast_slotJobFinished(KJob *job) +{ + QXmlStreamReader *reader = m_jobXml.value(job); + const QString source = m_jobList.value(job); + + if (reader) { + readForecast(source, *reader); + updateWeather(source); + } + + m_jobList.remove(job); + delete m_jobXml[job]; + m_jobXml.remove(job); + + if (m_sourcesToReset.contains(source)) { + m_sourcesToReset.removeAll(source); + + // so the weather engine updates it's data + forceImmediateUpdateOfAllVisualizations(); + + // update the clients of our engine + emit forceUpdate(this, source); + } +} + +void NOAAIon::readForecast(const QString& source, QXmlStreamReader& xml) +{ + QList& forecasts = m_weatherData[source].forecasts; + + // Clear the current forecasts + forecasts.clear(); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + + /* Read all reported days from . We check for existence of a specific + * which indicates the separate day listings. The schema defines it to be + * the first item before the day listings. + */ + if (xml.name() == "layout-key" && xml.readElementText() == "k-p24h-n7-1") { + + // Read days until we get to end of parent ()tag + while (! (xml.isEndElement() && xml.name() == "time-layout")) { + + xml.readNext(); + + if (xml.name() == "start-valid-time") { + QString data = xml.readElementText(); + QDateTime date = QDateTime::fromString(data, Qt::ISODate); + + WeatherData::Forecast forecast; + forecast.day = KLocalizedDate(date.date()).formatDate(KLocale::DayName, KLocale::ShortName); + forecasts.append(forecast); + //kDebug() << forecast.day; + } + } + + } else if (xml.name() == "temperature" && xml.attributes().value("type") == "maximum") { + + // Read max temps until we get to end tag + int i = 0; + while (! (xml.isEndElement() && xml.name() == "temperature") && + i < forecasts.count()) { + + xml.readNext(); + + if (xml.name() == "value") { + forecasts[i].high = xml.readElementText(); + //kDebug() << forecasts[i].high; + i++; + } + } + } else if (xml.name() == "temperature" && xml.attributes().value("type") == "minimum") { + + // Read min temps until we get to end tag + int i = 0; + while (! (xml.isEndElement() && xml.name() == "temperature") && + i < forecasts.count()) { + + xml.readNext(); + + if (xml.name() == "value") { + forecasts[i].low = xml.readElementText(); + //kDebug() << forecasts[i].low; + i++; + } + } + } else if (xml.name() == "weather") { + + // Read weather conditions until we get to end tag + int i = 0; + while (! (xml.isEndElement() && xml.name() == "weather") && + i < forecasts.count()) { + + xml.readNext(); + + if (xml.name() == "weather-conditions" && xml.isStartElement()) { + QString summary = xml.attributes().value("weather-summary").toString(); + forecasts[i].summary = summary; + //kDebug() << forecasts[i].summary; + kDebug() << "i18n summary string: " + << qPrintable(i18nc("weather forecast", forecasts[i].summary.toUtf8())); + i++; + } + } + } + } + } +} + +#include "ion_noaa.moc" diff --git a/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.h b/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.h new file mode 100644 index 00000000..660a79d9 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/noaa/ion_noaa.h @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for NOAA's National Weather Service XML data */ + +#ifndef ION_NOAA_H +#define ION_NOAA_H + +#include +#include +#include + +class KJob; +namespace KIO +{ + class Job; +} // namespace KIO +#include + +#include + +#include "../dataengineconsumer.h" +#include "../ion.h" + +class WeatherData +{ + +public: + //QString countryName; // USA + QString locationName; + QString stationID; + QString stationLat; + QString stationLon; + QString stateName; + + // Current observation information. + QString observationTime; + QString iconPeriodHour; + QString iconPeriodAP; + QString weather; + + QString temperature_F; + QString temperature_C; + QString humidity; + QString windString; + QString windDirection; + QString windSpeed; // Float value + QString windGust; // Float value + QString pressure; + QString dewpoint_F; + QString dewpoint_C; + QString heatindex_F; + QString heatindex_C; + QString windchill_F; + QString windchill_C; + QString visibility; + + struct Forecast + { + QString day; + QString summary; + QString low; + QString high; + }; + QList forecasts; +}; + +class KDE_EXPORT NOAAIon : public IonInterface, public Plasma::DataEngineConsumer +{ + Q_OBJECT + +public: + NOAAIon(QObject *parent, const QVariantList &args); + ~NOAAIon(); + void init(void); // Setup the city location, fetching the correct URL name. + bool updateIonSource(const QString& source); // Sync data source with Applet + void updateWeather(const QString& source); + +public Q_SLOTS: + virtual void reset(); + +protected Q_SLOTS: + void setup_slotDataArrived(KIO::Job *, const QByteArray &); + void setup_slotJobFinished(KJob *); + + void slotDataArrived(KIO::Job *, const QByteArray &); + void slotJobFinished(KJob *); + + void forecast_slotDataArrived(KIO::Job *, const QByteArray &); + void forecast_slotJobFinished(KJob *); + +private: + /* NOAA Methods - Internal for Ion */ + QMap setupConditionIconMappings(void) const; + QMap const & conditionIcons(void) const; + QMap setupWindIconMappings(void) const; + QMap const& windIcons(void) const; + + // Place information + QString const country(const QString& source) const; + QString place(const QString& source) const; + QString station(const QString& source) const; + QString latitude(const QString& source) const; + QString longitude(const QString& source) const; + + // Current Conditions Weather info + QString observationTime(const QString& source) const; + //bool night(const QString& source); + int periodHour(const QString& source) const; + QString condition(const QString& source); + QString conditionI18n(const QString& source); + QMap temperature(const QString& source) const; + QString dewpoint(const QString& source) const; + QMap humidity(const QString& source) const; + QMap visibility(const QString& source) const; + QMap pressure(const QString& source) const; + QMap wind(const QString& source) const; + IonInterface::ConditionIcons getConditionIcon(const QString& weather, bool isDayTime) const; + + // Load and Parse the place XML listing + void getXMLSetup(void) const; + bool readXMLSetup(void); + + // Load and parse the specific place(s) + void getXMLData(const QString& source); + bool readXMLData(const QString& source, QXmlStreamReader& xml); + + // Load and parse upcoming forecast for the next N days + void getForecast(const QString& source); + void readForecast(const QString& source, QXmlStreamReader& xml); + + // Check if place specified is valid or not + QStringList validate(const QString& source) const; + + // Catchall for unknown XML tags + void parseUnknownElement(QXmlStreamReader& xml) const; + + // Parse weather XML data + void parseWeatherSite(WeatherData& data, QXmlStreamReader& xml); + void parseStationID(void); + void parseStationList(void); + + struct XMLMapInfo { + QString stateName; + QString stationName; + QString stationID; + QString XMLurl; + }; + + // Key dicts + QHash m_places; + + // Weather information + QHash m_weatherData; + + // Store KIO jobs + QMap m_jobXml; + QMap m_jobList; + QXmlStreamReader m_xmlSetup; + + Plasma::DataEngine *m_timeEngine; + QDateTime m_dateFormat; + bool emitWhenSetup; + QStringList m_sourcesToReset; +}; + +K_EXPORT_PLASMA_DATAENGINE(noaa, NOAAIon) + +#endif diff --git a/plasma/generic/dataengines/weather/ions/wetter.com/CMakeLists.txt b/plasma/generic/dataengines/weather/ions/wetter.com/CMakeLists.txt new file mode 100644 index 00000000..87383810 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/wetter.com/CMakeLists.txt @@ -0,0 +1,7 @@ +set(ion_wettercom_SRCS ion_wettercom.cpp) +kde4_add_plugin(ion_wettercom ${ion_wettercom_SRCS}) +target_link_libraries(ion_wettercom weather_ion ${KDE4_KDECORE_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KUNITCONVERSION_LIBS}) + +install(FILES ion-wettercom.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(TARGETS ion_wettercom DESTINATION ${PLUGIN_INSTALL_DIR}) + diff --git a/plasma/generic/dataengines/weather/ions/wetter.com/ion-wettercom.desktop b/plasma/generic/dataengines/weather/ions/wetter.com/ion-wettercom.desktop new file mode 100644 index 00000000..fbbc99a1 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/wetter.com/ion-wettercom.desktop @@ -0,0 +1,141 @@ +[Desktop Entry] +Name=wetter.com +Name[ar]=wetter.com +Name[ast]=wetter.com +Name[bg]=wetter.com +Name[bn]=wetter.com +Name[bs]=wetter.com +Name[ca]=wetter.com +Name[ca@valencia]=wetter.com +Name[cs]=wetter.com +Name[da]=wetter.com +Name[de]=wetter.com +Name[el]=wetter.com +Name[en_GB]=wetter.com +Name[eo]=wetter.com +Name[es]=wetter.com +Name[et]=wetter.com +Name[eu]=wetter.com +Name[fi]=wetter.com +Name[fr]=wetter.com +Name[fy]=wetter.com +Name[ga]=wetter.com +Name[gl]=wetter.com +Name[gu]=wetter.com +Name[he]=wetter.com +Name[hi]=wetter.com +Name[hr]=wetter.com +Name[hu]=wetter.com +Name[ia]=wetter.com +Name[id]=wetter.com +Name[is]=wetter.com +Name[it]=wetter.com +Name[ja]=wetter.com +Name[ka]=wetter.com +Name[kk]=wetter.com +Name[km]=wetter.com +Name[kn]=wetter.com +Name[ko]=wetter.com +Name[lt]=wetter.com +Name[lv]=wetter.com +Name[mk]=wetter.com +Name[ml]=വെറ്റര്‍.കൊം +Name[mr]=wetter.com +Name[nb]=wetter.com +Name[nds]=wetter.com +Name[nl]=wetter.com +Name[nn]=wetter.com +Name[pa]=wetter.com +Name[pl]=wetter.com +Name[pt]=wetter.com +Name[pt_BR]=wetter.com +Name[ro]=wetter.com +Name[ru]=wetter.com +Name[si]=wetter.com +Name[sk]=wetter.com +Name[sl]=wetter.com +Name[sr]=wetter.com +Name[sr@ijekavian]=wetter.com +Name[sr@ijekavianlatin]=wetter.com +Name[sr@latin]=wetter.com +Name[sv]=wetter.com +Name[tg]=wetter.com +Name[th]=wetter.com +Name[tr]=wetter.com +Name[ug]=wetter.com +Name[uk]=wetter.com +Name[wa]=wetter.com +Name[x-test]=xxwetter.comxx +Name[zh_CN]=wetter.com +Name[zh_TW]=wetter.com +Comment=Weather forecast by wetter.com +Comment[ar]=نشرة الأحوال الجوية من wetter.com +Comment[ast]=Previsión meteorolóxica de wetter.com +Comment[bg]=Прогноза за времето от wetter.com +Comment[bs]=Prognoza vremena sa wetter.com +Comment[ca]=Previsió meteorològica per wetter.com +Comment[ca@valencia]=Previsió meteorològica per wetter.com +Comment[cs]=Předpověď počasí od wetter.com +Comment[da]=Vejrudsigt fra wetter.com +Comment[de]=Wettervorhersage von wetter.com +Comment[el]=Πρόγνωση καιρού από το wetter.com +Comment[en_GB]=Weather forecast by wetter.com +Comment[es]=Previsión meteorológica de wetter.com +Comment[et]=Wetter.com-i ilmateade +Comment[eu]=wetter.com-en eguraldi-iragarpena +Comment[fi]=Sääennustus osoitteesta wetter.com +Comment[fr]=Prévisions météorologiques par « wetter.com » +Comment[fy]=Waarberjocht fan wetter.com +Comment[ga]=Réamhaisnéis aimsire ó wetterm.com +Comment[gl]=Prognóstico meteorolóxico de wetter.com +Comment[he]=תחזית מזג אוויר על־ידי wetter.com +Comment[hi]=wetter.com द्वारा मोसम पूर्वानुमान +Comment[hr]=Prognoza vremena s wetter.com +Comment[hu]=Időjárás-előrejelzés a wetter.com-ról +Comment[ia]=Prevision Meteorologic per wetter.com +Comment[id]=Ramalan cuaca oleh wetter.com +Comment[is]=Veðurspá frá wetter.com +Comment[it]=Previsioni del tempo di wetter.com +Comment[ja]=wetter.com による天気予報 +Comment[kk]=wetter.com дегеннің ауа райы болжамы. +Comment[km]=ព្យាករណ៍​អាកាស​ធាតុ​ដោយ wetter.com +Comment[kn]=wetter.com ನಿಂದ ಹವಾಮಾನ ಮುನ್ಸೂಚನೆ +Comment[ko]=wetter.com 일기예보 +Comment[lt]=Orų prognozės iš wetter.com +Comment[lv]=wetter.com laikapstākļu prognoze +Comment[mk]=Временска прогноза од wetter.com +Comment[ml]=വെറ്റര്‍.കോമിന്റെ കാലാവസ്ഥാ പ്രവചനം +Comment[mr]=wetter.com वरील हवामान पूर्वानुमान +Comment[nb]=Værmelding fra wetter.com +Comment[nds]=Wederutsichten vun "wetter.com" +Comment[nl]=Weersvoorspelling door wetter.com +Comment[nn]=Vêrmelding +Comment[pa]=wetter.com ਤੋਂ ਮੌਸਮ ਭਵਿੱਖਬਾਣੀ +Comment[pl]=Prognoza pogody z wetter.com +Comment[pt]=Previsão meteorológica da wetter.com +Comment[pt_BR]=Previsão do tempo por wetter.com +Comment[ro]=Prognoza vremii de la wetter.com +Comment[ru]=Прогноз погоды с wetter.com +Comment[si]=wetter.com මඟින් කාළගුණ අනාවැකිය +Comment[sk]=Predpoveď počasia z wetter.com +Comment[sl]=Vremenska napoved iz wetter.com +Comment[sr]=Прогноза времена са wetter.com +Comment[sr@ijekavian]=Прогноза времена са wetter.com +Comment[sr@ijekavianlatin]=Prognoza vremena sa wetter.com +Comment[sr@latin]=Prognoza vremena sa wetter.com +Comment[sv]=Väderprognos av wetter.com +Comment[tg]=Обу ҳаво аз wetter.com +Comment[th]=พยากรณ์อากาศ โดย wetter.com +Comment[tr]=wetter.com'dan hava tahmini +Comment[ug]=wetter.com تەمىنلىگەن ھاۋارايىدىن ئالدىن مەلۇمات +Comment[uk]=Прогноз погоди з wetter.com +Comment[wa]=Prédijhaedjes del meteyo pa wetter.com +Comment[x-test]=xxWeather forecast by wetter.comxx +Comment[zh_CN]=wetter.com 网站提供的天气预报 +Comment[zh_TW]=氣象預報,由 wetter.com 提供 +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-ParentApp=weatherengine +Type=Service +Icon=noneyet +X-KDE-Library=ion_wettercom +X-KDE-PluginInfo-Name=wettercom diff --git a/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.cpp b/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.cpp new file mode 100644 index 00000000..9c304a76 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.cpp @@ -0,0 +1,823 @@ +/*************************************************************************** + * Copyright (C) 2009 by Thilo-Alexander Ginkel * + * * + * Based upon BBC Weather Ion by Shawn Starr * + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for weather data from wetter.com */ + +// Sample URLs: +// http://api.wetter.com/location/index/search/Heidelberg/project/weatherion/cs/9090dec6e783b96bd6a6ca9d451f3fee +// http://api.wetter.com/forecast/weather/city/DE0004329/project/weatherion/cs/89f1264869cce5c6fd5a2db80051f3d8 + +#include "ion_wettercom.h" +#include +#include +#include + +/* + * Initialization + */ + +WetterComIon::WetterComIon(QObject *parent, const QVariantList &args) + : IonInterface(parent, args) + +{ + Q_UNUSED(args) + +#if defined(MIN_POLL_INTERVAL) + setMinimumPollingInterval(MIN_POLL_INTERVAL); +#endif +} + +WetterComIon::~WetterComIon() +{ + cleanup(); +} + +void WetterComIon::cleanup() +{ + // Clean up dynamically allocated forecasts + QMutableHashIterator it(m_weatherData); + while (it.hasNext()) { + it.next(); + WeatherData &item = it.value(); + qDeleteAll(item.forecasts); + item.forecasts.clear(); + } +} + +void WetterComIon::reset() +{ + cleanup(); + m_sourcesToReset = sources(); + updateAllSources(); +} + +void WetterComIon::init() +{ + setInitialized(true); +} + +QMap WetterComIon::setupCommonIconMappings(void) const +{ + QMap conditionList; + + conditionList["3"] = Overcast; + conditionList["30"] = Overcast; + conditionList["4"] = Haze; + conditionList["40"] = Haze; + conditionList["45"] = Haze; + conditionList["48"] = Haze; + conditionList["49"] = Haze; + conditionList["5"] = Mist; + conditionList["50"] = Mist; + conditionList["51"] = Mist; + conditionList["53"] = Mist; + conditionList["55"] = Mist; + conditionList["56"] = FreezingDrizzle; + conditionList["57"] = FreezingDrizzle; + conditionList["6"] = Rain; + conditionList["60"] = LightRain; + conditionList["61"] = LightRain; + conditionList["63"] = Rain; + conditionList["65"] = Rain; + conditionList["66"] = FreezingRain; + conditionList["67"] = FreezingRain; + conditionList["68"] = RainSnow; + conditionList["69"] = RainSnow; + conditionList["7"] = Snow; + conditionList["70"] = LightSnow; + conditionList["71"] = LightSnow; + conditionList["73"] = Snow; + conditionList["75"] = Flurries; + conditionList["8"] = Showers; + conditionList["81"] = Showers; + conditionList["82"] = Showers; + conditionList["83"] = RainSnow; + conditionList["84"] = RainSnow; + conditionList["85"] = Snow; + conditionList["86"] = Snow; + conditionList["9"] = Thunderstorm; + conditionList["90"] = Thunderstorm; + conditionList["96"] = Thunderstorm; + conditionList["999"] = NotAvailable; + + return conditionList; +} + +QMap WetterComIon::setupDayIconMappings(void) const +{ + QMap conditionList = setupCommonIconMappings(); + + conditionList["0"] = ClearDay; + conditionList["1"] = FewCloudsDay; + conditionList["10"] = FewCloudsDay; + conditionList["2"] = PartlyCloudyDay; + conditionList["20"] = PartlyCloudyDay; + conditionList["80"] = ChanceShowersDay; + conditionList["95"] = ChanceThunderstormDay; + + return conditionList; +} + +QMap const& WetterComIon::dayIcons(void) const +{ + static QMap const val = setupDayIconMappings(); + return val; +} + +QMap WetterComIon::setupNightIconMappings(void) const +{ + QMap conditionList = setupCommonIconMappings(); + + conditionList["0"] = ClearNight; + conditionList["1"] = FewCloudsNight; + conditionList["10"] = FewCloudsNight; + conditionList["2"] = PartlyCloudyNight; + conditionList["20"] = PartlyCloudyNight; + conditionList["80"] = ChanceShowersNight; + conditionList["95"] = ChanceThunderstormNight; + + return conditionList; +} + +QMap const& WetterComIon::nightIcons(void) const +{ + static QMap const val = setupNightIconMappings(); + return val; +} + +QMap WetterComIon::setupCommonConditionMappings(void) const +{ + QMap conditionList; + conditionList["1"] = i18nc("weather condition", "few clouds"); + conditionList["10"] = i18nc("weather condition", "few clouds"); + conditionList["2"] = i18nc("weather condition", "cloudy"); + conditionList["20"] = i18nc("weather condition", "cloudy"); + conditionList["3"] = i18nc("weather condition", "overcast"); + conditionList["30"] = i18nc("weather condition", "overcast"); + conditionList["4"] = i18nc("weather condition", "haze"); + conditionList["40"] = i18nc("weather condition", "haze"); + conditionList["45"] = i18nc("weather condition", "haze"); + conditionList["48"] = i18nc("weather condition", "fog with icing"); + conditionList["49"] = i18nc("weather condition", "fog with icing"); + conditionList["5"] = i18nc("weather condition", "drizzle"); + conditionList["50"] = i18nc("weather condition", "drizzle"); + conditionList["51"] = i18nc("weather condition", "light drizzle"); + conditionList["53"] = i18nc("weather condition", "drizzle"); + conditionList["55"] = i18nc("weather condition", "heavy drizzle"); + conditionList["56"] = i18nc("weather condition", "freezing drizzle"); + conditionList["57"] = i18nc("weather condition", "heavy freezing drizzle"); + conditionList["6"] = i18nc("weather condition", "rain"); + conditionList["60"] = i18nc("weather condition", "light rain"); + conditionList["61"] = i18nc("weather condition", "light rain"); + conditionList["63"] = i18nc("weather condition", "moderate rain"); + conditionList["65"] = i18nc("weather condition", "heavy rain"); + conditionList["66"] = i18nc("weather condition", "light freezing rain"); + conditionList["67"] = i18nc("weather condition", "freezing rain"); + conditionList["68"] = i18nc("weather condition", "light rain snow"); + conditionList["69"] = i18nc("weather condition", "heavy rain snow"); + conditionList["7"] = i18nc("weather condition", "snow"); + conditionList["70"] = i18nc("weather condition", "light snow"); + conditionList["71"] = i18nc("weather condition", "light snow"); + conditionList["73"] = i18nc("weather condition", "moderate snow"); + conditionList["75"] = i18nc("weather condition", "heavy snow"); + conditionList["8"] = i18nc("weather condition", "showers"); + conditionList["80"] = i18nc("weather condition", "light showers"); + conditionList["81"] = i18nc("weather condition", "showers"); + conditionList["82"] = i18nc("weather condition", "heavy showers"); + conditionList["83"] = i18nc("weather condition", "light snow rain showers"); + conditionList["84"] = i18nc("weather condition", "heavy snow rain showers"); + conditionList["85"] = i18nc("weather condition", "light snow showers"); + conditionList["86"] = i18nc("weather condition", "snow showers"); + conditionList["9"] = i18nc("weather condition", "thunderstorm"); + conditionList["90"] = i18nc("weather condition", "thunderstorm"); + conditionList["95"] = i18nc("weather condition", "light thunderstorm"); + conditionList["96"] = i18nc("weather condition", "heavy thunderstorm"); + conditionList["999"] = i18nc("weather condition", "n/a"); + + return conditionList; +} + +QMap WetterComIon::setupDayConditionMappings(void) const +{ + QMap conditionList = setupCommonConditionMappings(); + conditionList["0"] = i18nc("weather condition", "sunny"); + return conditionList; +} + +QMap const& WetterComIon::dayConditions(void) const +{ + static QMap const val = setupDayConditionMappings(); + return val; +} + +QMap WetterComIon::setupNightConditionMappings(void) const +{ + QMap conditionList = setupCommonConditionMappings(); + conditionList["0"] = i18nc("weather condition", "clear sky"); + return conditionList; +} + +QMap const& WetterComIon::nightConditions(void) const +{ + static QMap const val = setupNightConditionMappings(); + return val; +} + +QString WetterComIon::getWeatherCondition(const QMap &conditionList, const QString& condition) const +{ + return conditionList[condition]; +} + +bool WetterComIon::updateIonSource(const QString& source) +{ + // We expect the applet to send the source in the following tokenization: + // ionname|validate|place_name|extra - Triggers validation of place + // ionname|weather|place_name|extra - Triggers receiving weather of place + + QStringList sourceAction = source.split('|'); + + if (sourceAction.size() < 3) { + setData(source, "validate", "wettercom|malformed"); + return true; + } + + if (sourceAction[1] == "validate" && sourceAction.size() >= 3) { + // Look for places to match + findPlace(sourceAction[2], source); + return true; + } else if (sourceAction[1] == "weather" && sourceAction.size() >= 3) { + if (sourceAction.count() >= 4) { + if (sourceAction[2].isEmpty()) { + setData(source, "validate", "wettercom|malformed"); + return true; + } + + // Extra data format: placeCode;displayName + QStringList extraData = sourceAction[3].split(';'); + + if (extraData.count() != 2) { + setData(source, "validate", "wettercom|malformed"); + return true; + } + + m_place[sourceAction[2]].placeCode = extraData[0]; + + m_place[sourceAction[2]].displayName = extraData[1]; + + kDebug() << "About to retrieve forecast for source: " << sourceAction[2]; + + fetchForecast(sourceAction[2]); + + return true; + } else { + return false; + } + } else { + setData(source, "validate", "wettercom|malformed"); + return true; + } + + return false; +} + + +/* + * Handling of place searches + */ + +void WetterComIon::findPlace(const QString& place, const QString& source) +{ + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QString::fromLatin1(PROJECTNAME).toUtf8()); + md5.addData(QString::fromLatin1(APIKEY).toUtf8()); + md5.addData(place.toUtf8()); + + KUrl url = QString::fromLatin1(SEARCH_URL).arg(place).arg(md5.result().toHex().data()); + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); // Disable displaying cookies + m_searchJobXml.insert(m_job, new QXmlStreamReader); + m_searchJobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(setup_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, + SLOT(setup_slotJobFinished(KJob*))); + } +} + +void WetterComIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + QByteArray local = data; + + if (data.isEmpty() || !m_searchJobXml.contains(job)) { + return; + } + + m_searchJobXml[job]->addData(local); +} + +void WetterComIon::setup_slotJobFinished(KJob *job) +{ + if (job->error() == 149) { + setData(m_searchJobList[job], "validate", + QString::fromLatin1("wettercom|timeout")); + disconnectSource(m_searchJobList[job], this); + m_searchJobList.remove(job); + delete m_searchJobXml[job]; + m_searchJobXml.remove(job); + return; + } + + QXmlStreamReader *reader = m_searchJobXml.value(job); + + if (reader) { + parseSearchResults(m_searchJobList[job], *reader); + } + + m_searchJobList.remove(job); + + delete m_searchJobXml[job]; + m_searchJobXml.remove(job); +} + +void WetterComIon::parseSearchResults(const QString& source, QXmlStreamReader& xml) +{ + QString name, code, quarter, state, country; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement()) { + if (xml.name() == "search") { + break; + } else if (xml.name() == "item") { + // we parsed a place from the search result + QString placeName; + + if (quarter.isEmpty()) { + placeName = i18nc("Geographical location: city, state, ISO-country-code", "%1, %2, %3", + name, state, country); + } else { + placeName = i18nc("Geographical location: quarter (city), state, ISO-country-code", + "%1 (%2), %3, %4", quarter, name, state, country); + } + + kDebug() << "Storing place data for place:" << placeName; + + m_place[placeName].name = placeName; + m_place[placeName].displayName = name; + m_place[placeName].placeCode = code; + m_locations.append(placeName); + + name = ""; + code = ""; + quarter = ""; + country = ""; + state = ""; + } + } + + if (xml.isStartElement()) { + if (xml.name() == "name") { + name = xml.readElementText(); + } else if (xml.name() == "city_code") { + code = xml.readElementText(); + } else if (xml.name() == "quarter") { + quarter = xml.readElementText(); + } else if (xml.name() == "adm_1_code") { + country = xml.readElementText(); + } else if (xml.name() == "adm_2_name") { + state = xml.readElementText(); + } + } + } + + validate(source, xml.error() != QXmlStreamReader::NoError); +} + +void WetterComIon::validate(const QString& source, bool parseError) +{ + bool beginflag = true; + + if (!m_locations.count() || parseError) { + QStringList invalidPlace = source.split('|'); + + if (m_place[invalidPlace[2]].name.isEmpty()) { + setData(source, "validate", + QString::fromLatin1("wettercom|invalid|multiple|%1") + .arg(invalidPlace[2])); + } + + m_locations.clear(); + + return; + } else { + QString placeList; + foreach(const QString &place, m_locations) { + // Extra data format: placeCode;displayName + if (beginflag) { + placeList.append(QString::fromLatin1("%1|extra|%2;%3") + .arg(place).arg(m_place[place].placeCode) + .arg(m_place[place].displayName)); + beginflag = false; + } else { + placeList.append(QString::fromLatin1("|place|%1|extra|%2;%3") + .arg(place).arg(m_place[place].placeCode) + .arg(m_place[place].displayName)); + } + } + + kDebug() << "Returning place list:" << placeList; + + if (m_locations.count() > 1) { + setData(source, "validate", + QString::fromLatin1("wettercom|valid|multiple|place|%1") + .arg(placeList)); + } else { + placeList[0] = placeList[0].toUpper(); + setData(source, "validate", + QString::fromLatin1("wettercom|valid|single|place|%1") + .arg(placeList)); + } + } + + m_locations.clear(); +} + + +/* + * Handling of forecasts + */ + +void WetterComIon::fetchForecast(const QString& source) +{ + foreach (const QString &fetching, m_forecastJobList) { + if (fetching == source) { + // already fetching! + return; + } + } + + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QString::fromLatin1(PROJECTNAME).toUtf8()); + md5.addData(QString::fromLatin1(APIKEY).toUtf8()); + md5.addData(m_place[source].placeCode.toUtf8()); + + KUrl url = QString::fromLatin1(FORECAST_URL) + .arg(m_place[source].placeCode).arg(md5.result().toHex().data()); + + m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); + m_job->addMetaData("cookies", "none"); + m_forecastJobXml.insert(m_job, new QXmlStreamReader); + m_forecastJobList.insert(m_job, source); + + if (m_job) { + connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, + SLOT(forecast_slotDataArrived(KIO::Job*,QByteArray))); + connect(m_job, SIGNAL(result(KJob*)), this, + SLOT(forecast_slotJobFinished(KJob*))); + } +} + +void WetterComIon::forecast_slotDataArrived(KIO::Job *job, const QByteArray &data) +{ + QByteArray local = data; + + if (data.isEmpty() || !m_forecastJobXml.contains(job)) { + return; + } + + m_forecastJobXml[job]->addData(local); +} + +void WetterComIon::forecast_slotJobFinished(KJob *job) +{ + const QString source(m_forecastJobList.value(job)); + setData(source, Data()); + QXmlStreamReader *reader = m_forecastJobXml.value(job); + + if (reader) { + parseWeatherForecast(source, *reader); + } + + m_forecastJobList.remove(job); + + delete m_forecastJobXml[job]; + m_forecastJobXml.remove(job); + + if (m_sourcesToReset.contains(source)) { + m_sourcesToReset.removeAll(source); + const QString weatherSource = QString::fromLatin1("wettercom|weather|%1|%2;%3") + .arg(source).arg(m_place[source].placeCode) + .arg(m_place[source].displayName); + + // so the weather engine updates it's data + forceImmediateUpdateOfAllVisualizations(); + + // update the clients of our engine + emit forceUpdate(this, weatherSource); + } +} + +void WetterComIon::parseWeatherForecast(const QString& source, QXmlStreamReader& xml) +{ + kDebug() << "About to parse forecast for source:" << source; + + // Clear old forecasts when updating + m_weatherData[source].forecasts.clear(); + + WeatherData::ForecastPeriod *forecastPeriod = new WeatherData::ForecastPeriod; + WeatherData::ForecastInfo *forecast = new WeatherData::ForecastInfo; + int summaryWeather = -1, summaryProbability = 0; + int tempMax = -273, tempMin = 100, weather = -1, probability = 0; + uint summaryUtcTime = 0, utcTime = 0, localTime = 0; + QString date, time; + + m_weatherData[source].place = source; + + while (!xml.atEnd()) { + xml.readNext(); + + kDebug() << "parsing xml elem: " << xml.name(); + + if (xml.isEndElement()) { + if (xml.name() == "city") { + break; + } else if (xml.name() == "date") { + // we have parsed a complete day + + forecastPeriod->period = QDateTime::fromTime_t(summaryUtcTime); + QString weatherString = QString::number(summaryWeather); + forecastPeriod->iconName = getWeatherIcon(dayIcons(), + weatherString); + forecastPeriod->summary = getWeatherCondition(dayConditions(), + weatherString); + forecastPeriod->probability = summaryProbability; + + m_weatherData[source].forecasts.append(forecastPeriod); + forecastPeriod = new WeatherData::ForecastPeriod; + + date = ""; + summaryWeather = -1; + summaryProbability = 0; + summaryUtcTime = 0; + } else if (xml.name() == "time") { + // we have parsed one forecast + + kDebug() << "Parsed a forecast interval:" << date << time; + + // yep, that field is written to more often than needed... + m_weatherData[source].timeDifference = localTime - utcTime; + + forecast->period = QDateTime::fromTime_t(utcTime); + QString weatherString = QString::number(weather); + forecast->tempHigh = tempMax; + forecast->tempLow = tempMin; + forecast->probability = probability; + + QTime localWeatherTime = QDateTime::fromTime_t(utcTime).time(); + localWeatherTime.addSecs(m_weatherData[source].timeDifference); + + kDebug() << "localWeatherTime =" << localWeatherTime; + + // TODO use local sunset/sunrise time + + if (localWeatherTime.hour() < 20 && localWeatherTime.hour() > 6) { + forecast->iconName = getWeatherIcon(dayIcons(), + weatherString); + forecast->summary = getWeatherCondition(dayConditions(), + weatherString); + forecastPeriod->dayForecasts.append(forecast); + } else { + forecast->iconName = getWeatherIcon(nightIcons(), + weatherString); + forecast->summary = getWeatherCondition(nightConditions(), + weatherString); + forecastPeriod->nightForecasts.append(forecast); + } + + forecast = new WeatherData::ForecastInfo; + + tempMax = -273; + tempMin = 100; + weather = -1; + probability = 0; + utcTime = localTime = 0; + time = ""; + } + } + + if (xml.isStartElement()) { + if (xml.name() == "date") { + date = xml.attributes().value("value").toString(); + } else if (xml.name() == "time") { + time = xml.attributes().value("value").toString(); + } else if (xml.name() == "tx") { + tempMax = qRound(xml.readElementText().toDouble()); + kDebug() << "parsed t_max:" << tempMax; + } else if (xml.name() == "tn") { + tempMin = qRound(xml.readElementText().toDouble()); + kDebug() << "parsed t_min:" << tempMin; + } else if (xml.name() == "w") { + int tmp = xml.readElementText().toInt(); + + if (!time.isEmpty()) + weather = tmp; + else + summaryWeather = tmp; + + kDebug() << "parsed weather condition:" << tmp; + } else if (xml.name() == "name") { + m_weatherData[source].stationName = xml.readElementText(); + kDebug() << "parsed station name:" << m_weatherData[source].stationName; + } else if (xml.name() == "pc") { + int tmp = xml.readElementText().toInt(); + + if (!time.isEmpty()) + probability = tmp; + else + summaryProbability = tmp; + + kDebug() << "parsed probability:" << probability; + } else if (xml.name() == "text") { + m_weatherData[source].credits = xml.readElementText(); + kDebug() << "parsed credits:" << m_weatherData[source].credits; + } else if (xml.name() == "link") { + m_weatherData[source].creditsUrl = xml.readElementText(); + kDebug() << "parsed credits url:" << m_weatherData[source].creditsUrl; + } else if (xml.name() == "d") { + localTime = xml.readElementText().toInt(); + kDebug() << "parsed local time:" << localTime; + } else if (xml.name() == "du") { + int tmp = xml.readElementText().toInt(); + + if (!time.isEmpty()) + utcTime = tmp; + else + summaryUtcTime = tmp; + + kDebug() << "parsed UTC time:" << tmp; + } + } + } + + delete forecast; + delete forecastPeriod; + + updateWeather(source, xml.error() != QXmlStreamReader::NoError); +} + +void WetterComIon::updateWeather(const QString& source, bool parseError) +{ + kDebug() << "Source:" << source; + + QString weatherSource = QString::fromLatin1("wettercom|weather|%1|%2;%3") + .arg(source).arg(m_place[source].placeCode) + .arg(m_place[source].displayName); + + Plasma::DataEngine::Data data; + data.insert("Place", m_place[source].displayName); + + if (!parseError && !m_weatherData[source].forecasts.isEmpty()) { + data.insert("Station", m_place[source].displayName); + //data.insert("Condition Icon", "N/A"); + //data.insert("Temperature", "N/A"); + data.insert("Temperature Unit", QString::number(KUnitConversion::Celsius)); + + int i = 0; + foreach(WeatherData::ForecastPeriod * forecastPeriod, m_weatherData[source].forecasts) { + if (i > 0) { + WeatherData::ForecastInfo weather = forecastPeriod->getWeather(); + + data.insert(QString::fromLatin1("Short Forecast Day %1").arg(i), + QString::fromLatin1("%1|%2|%3|%4|%5|%6") + .arg(KLocalizedDate(weather.period.date()).formatDate(KLocale::DayName, KLocale::ShortName)) + .arg(weather.iconName).arg(weather.summary) + .arg(weather.tempHigh).arg(weather.tempLow) + .arg(weather.probability)); + i++; + } else { + WeatherData::ForecastInfo dayWeather = forecastPeriod->getDayWeather(); + + data.insert(QString::fromLatin1("Short Forecast Day %1").arg(i), + QString::fromLatin1("%1|%2|%3|%4|%5|%6") + .arg(i18n("Day")).arg(dayWeather.iconName) + .arg(dayWeather.summary).arg(dayWeather.tempHigh) + .arg(dayWeather.tempLow).arg(dayWeather.probability)); + i++; + + if (forecastPeriod->hasNightWeather()) { + WeatherData::ForecastInfo nightWeather = forecastPeriod->getNightWeather(); + data.insert(QString::fromLatin1("Short Forecast Day %1").arg(i), + QString::fromLatin1("%1 nt|%2|%3|%4|%5|%6") + .arg(i18n("Night")).arg(nightWeather.iconName) + .arg(nightWeather.summary) + .arg(nightWeather.tempHigh) + .arg(nightWeather.tempLow) + .arg(nightWeather.probability)); + i++; + } + } + } + + // Set number of forecasts per day/night supported + data.insert("Total Weather Days", i); + + data.insert("Credit", m_weatherData[source].credits); // FIXME i18n? + data.insert("Credit Url", m_weatherData[source].creditsUrl); + + kDebug() << "updated weather data:" << data; + } else { + kDebug() << "Something went wrong when parsing weather data for source:" << source; + } + + setData(weatherSource, data); +} + + +/* + * WeatherData::ForecastPeriod convenience methods + */ + +WeatherData::ForecastPeriod::~ForecastPeriod() +{ + qDeleteAll(dayForecasts); + qDeleteAll(nightForecasts); +} + +WeatherData::ForecastInfo WeatherData::ForecastPeriod::getDayWeather() const +{ + WeatherData::ForecastInfo result; + result.period = period; + result.iconName = iconName; + result.summary = summary; + result.tempHigh = getMaxTemp(dayForecasts); + result.tempLow = getMinTemp(dayForecasts); + result.probability = probability; + return result; +} + +WeatherData::ForecastInfo WeatherData::ForecastPeriod::getNightWeather() const +{ + kDebug() << "nightForecasts.size() =" << nightForecasts.size(); + + // TODO do not just pick the first night forecast + return *(nightForecasts.at(0)); +} + +bool WeatherData::ForecastPeriod::hasNightWeather() const +{ + return !nightForecasts.isEmpty(); +} + +WeatherData::ForecastInfo WeatherData::ForecastPeriod::getWeather() const +{ + WeatherData::ForecastInfo result = getDayWeather(); + result.tempHigh = std::max(result.tempHigh, getMaxTemp(nightForecasts)); + result.tempLow = std::min(result.tempLow, getMinTemp(nightForecasts)); + return result; +} + +int WeatherData::ForecastPeriod::getMaxTemp(QVector forecastInfos) const +{ + int result = -273; + foreach(const WeatherData::ForecastInfo * forecast, forecastInfos) { + result = std::max(result, forecast->tempHigh); + } + + return result; +} + +int WeatherData::ForecastPeriod::getMinTemp(QVector forecastInfos) const +{ + int result = 100; + foreach(const WeatherData::ForecastInfo * forecast, forecastInfos) { + result = std::min(result, forecast->tempLow); + } + + return result; +} + +#include "ion_wettercom.moc" +// kate: indent-mode cstyle; space-indent on; indent-width 4; diff --git a/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.h b/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.h new file mode 100644 index 00000000..11205298 --- /dev/null +++ b/plasma/generic/dataengines/weather/ions/wetter.com/ion_wettercom.h @@ -0,0 +1,173 @@ +/*************************************************************************** + * Copyright (C) 2009 by Thilo-Alexander Ginkel * + * * + * Based upon BBC Weather Ion by Shawn Starr * + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +/* Ion for weather data from wetter.com */ + +#ifndef ION_WETTERCOM_H +#define ION_WETTERCOM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../ion.h" + +// wetter.com API project data +#define PROJECTNAME "weatherion" +#define SEARCH_URL "http://api.wetter.com/location/index/search/%1/project/" PROJECTNAME "/cs/%2" +#define FORECAST_URL "http://api.wetter.com/forecast/weather/city/%1/project/" PROJECTNAME "/cs/%2" +#define APIKEY "07025b9a22b4febcf8e8ec3e6f1140e8" +#define MIN_POLL_INTERVAL 3600000L // 1 h + +class WeatherData +{ +public: + QString place; + QString stationName; + + // time difference to UTC + int timeDifference; + + // credits as returned from API request + QString credits; + QString creditsUrl; + + class ForecastBase + { + public: + QDateTime period; + QString iconName; + QString summary; + int probability; + }; + + class ForecastInfo : public ForecastBase + { + public: + int tempHigh; + int tempLow; + }; + + class ForecastPeriod : public ForecastInfo + { + public: + ~ForecastPeriod(); + + WeatherData::ForecastInfo getDayWeather() const; + WeatherData::ForecastInfo getNightWeather() const; + WeatherData::ForecastInfo getWeather() const; + + bool hasNightWeather() const; + + QVector dayForecasts; + QVector nightForecasts; + private: + int getMaxTemp(QVector forecastInfos) const; + int getMinTemp(QVector forecastInfos) const; + }; + + QVector forecasts; +}; + +class KDE_EXPORT WetterComIon : public IonInterface +{ + Q_OBJECT + +public: + WetterComIon(QObject *parent, const QVariantList &args); + ~WetterComIon(); + + bool updateIonSource(const QString& source); + +public Q_SLOTS: + virtual void reset(); + +protected Q_SLOTS: + void setup_slotDataArrived(KIO::Job *, const QByteArray &); + void setup_slotJobFinished(KJob *); + void forecast_slotDataArrived(KIO::Job *, const QByteArray &); + void forecast_slotJobFinished(KJob *); + +private: + void init(); + void cleanup(); + + // Set up the mapping from the wetter.com condition code to the respective icon / condition name + QMap setupCommonIconMappings(void) const; + QMap setupDayIconMappings(void) const; + QMap setupNightIconMappings(void) const; + QMap setupCommonConditionMappings(void) const; + QMap setupDayConditionMappings(void) const; + QMap setupNightConditionMappings(void) const; + + // Retrieve the mapping from the wetter.com condition code to the respective icon / condition name + QMap const& nightIcons(void) const; + QMap const& dayIcons(void) const; + QMap const& dayConditions(void) const; + QMap const& nightConditions(void) const; + + QString getWeatherCondition(const QMap &conditionList, const QString& condition) const; + + // Find place + void findPlace(const QString& place, const QString& source); + void parseSearchResults(const QString& source, QXmlStreamReader& xml); + void validate(const QString& source, bool parseError); + + // Retrieve and parse forecast + void fetchForecast(const QString& source); + void parseWeatherForecast(const QString& source, QXmlStreamReader& xml); + void updateWeather(const QString& source, bool parseError); + + struct PlaceInfo { + QString name; + QString displayName; + QString placeCode; + }; + + // Key dicts + QHash m_place; + QVector m_locations; + + // Weather information + QHash m_weatherData; + + // Store KIO jobs - Search list + QMap m_searchJobXml; + QMap m_searchJobList; + + // Store KIO jobs - Forecast retrieval + QMap m_forecastJobXml; + QMap m_forecastJobList; + + KIO::TransferJob *m_job; + QStringList m_sourcesToReset; +}; + +K_EXPORT_PLASMA_DATAENGINE(wettercom, WetterComIon) + +#endif +// kate: indent-mode cstyle; space-indent on; indent-width 4; diff --git a/plasma/generic/dataengines/weather/plasma-dataengine-weather.desktop b/plasma/generic/dataengines/weather/plasma-dataengine-weather.desktop new file mode 100644 index 00000000..4d2897d1 --- /dev/null +++ b/plasma/generic/dataengines/weather/plasma-dataengine-weather.desktop @@ -0,0 +1,157 @@ +[Desktop Entry] +Name=Weather +Name[ar]=الطقس +Name[ast]=Tiempu meteorolóxicu +Name[be@latin]=Nadvorje +Name[bg]=Метеорологично време +Name[bn]=আবহাওয়া +Name[bn_IN]=আবহাওয়া +Name[bs]=vrijeme +Name[ca]=Meteorologia +Name[ca@valencia]=Meteorologia +Name[cs]=Počasí +Name[da]=Vejr +Name[de]=Wetter +Name[el]=Καιρός +Name[en_GB]=Weather +Name[eo]=Vetero +Name[es]=Tiempo meteorológico +Name[et]=Ilmateade +Name[eu]=Eguraldia +Name[fi]=Sää +Name[fr]=Météo +Name[fy]=It Waar +Name[ga]=Aimsir +Name[gl]=O tempo +Name[gu]=હવામાન +Name[he]=מזג אוויר +Name[hi]=मौसम +Name[hne]=मौसम +Name[hr]=Vrijeme +Name[hu]=Időjárás +Name[ia]=Tempore meteorologic +Name[id]=Cuaca +Name[is]=Veður +Name[it]=Tempo +Name[ja]=気象 +Name[kk]=Ауа райы +Name[km]=អាកាសធាតុ +Name[kn]=ಹವಾಮಾನ +Name[ko]=날씨 +Name[ku]=Hewa +Name[lt]=Orai +Name[lv]=Laikapstākļi +Name[mai]=मौसम +Name[mk]=Време +Name[ml]=കാലാവസ്ഥ +Name[mr]=हवामान +Name[nb]=Været +Name[nds]=Weder +Name[nl]=Het weer +Name[nn]=Vêr +Name[or]=ପାଣିପାଗ +Name[pa]=ਮੌਸਮ +Name[pl]=Pogoda +Name[pt]=Meteorologia +Name[pt_BR]=Meteorologia +Name[ro]=Vremea +Name[ru]=Погода +Name[si]=කාලගුණය +Name[sk]=Počasie +Name[sl]=Vreme +Name[sr]=време +Name[sr@ijekavian]=време +Name[sr@ijekavianlatin]=vreme +Name[sr@latin]=vreme +Name[sv]=Väder +Name[ta]= +Name[te]=వాతావరణము +Name[tg]=Обу Ҳаво +Name[th]=พยากรณ์อากาศ +Name[tr]=Hava Durumu +Name[ug]=ھاۋا رايى +Name[uk]=Погода +Name[wa]=Meteyo +Name[x-test]=xxWeatherxx +Name[zh_CN]=天气 +Name[zh_TW]=天氣 +Comment=Weather data from multiple online sources +Comment[ar]=معلومات الطقس من مصادر انترنت مختلفة +Comment[ast]=Datos meteorolóxicos dende múltiples fontes. +Comment[bg]=Данни за метеорологичното време +Comment[bs]=Meteorološki podaci iz više izvora na vezi +Comment[ca]=Dades meteorològiques de múltiples fonts en línia +Comment[ca@valencia]=Dades meteorològiques de múltiples fonts en línia +Comment[cs]=Data o počasí z různých online zdrojů +Comment[da]=Vejrdata fra flere online-kilder +Comment[de]=Wetterdaten aus verschiedenen Online-Quellen +Comment[el]=Δεδομένα καιρού από πολλαπλές δικτυακές πηγές +Comment[en_GB]=Weather data from multiple online sources +Comment[eo]=Veteraj datumoj el diversaj interretaj fontoj +Comment[es]=Datos meteorológicos desde múltiples fuentes. +Comment[et]=Ilmaandmed mitmest internetiallikast +Comment[eu]=Eguraldiari buruzko informazioa hainbat iturritatik +Comment[fi]=Säätietoja useasta lähteestä +Comment[fr]=Données météorologiques depuis des sources multiples en ligne +Comment[fy]=Waar gegevens fan ferskate ynternetboarnen +Comment[ga]=Sonraí aimsire ó fhoinsí éagsúla ar líne +Comment[gl]=Información meteorolóxica de varias fontes de internet +Comment[he]=מידע על מזג האוויר ממגוון מקורות מקוונים +Comment[hi]=मोसम जानकारी अनेक ऑनलाईन स्रोतों से +Comment[hr]=Podaci o vremenu iz raznih online izvora +Comment[hu]=Időjárás-jelentés több forrásból +Comment[ia]=Datos meteorologic ex multiple fontes in linea +Comment[id]=Data cuaca dari berbagai sumber daring +Comment[is]=Veðurgögn frá ýmsum gagnabönkum á netinu +Comment[it]=Dati meteorologici da varie fonti in rete +Comment[ja]=複数のオンライン情報源からの気象データ +Comment[kk]=Түрлі онлайн көздерден алынған ауа-райы +Comment[km]=ទិន្នន័យ​អាកាសធាតុ​ពី​ប្រភព​លើបណ្ដាញ​ជា​ច្រើន +Comment[kn]=ಅನೇಕ ಆನ್‌ಲೈನ್ ಮೂಲಗಳಿಂದ ಹವಾಮಾನ ಮಾಹಿತಿ +Comment[ko]=온라인에서 온 다양한 날씨 데이터 +Comment[lt]=Orų informacija iš įvairių žiniatinklio šaltinių +Comment[lv]=Laikapstākļu dati no vairākiem tiešsaistes avotiem +Comment[mk]=Метеоролошки податоци од разни интернет-извори +Comment[ml]=പല സ്രോതസ്സുകളില്‍നിന്നുമുള്ള കാലാവസ്ഥാ സ്ഥിതിവിവരങ്ങള്‍ +Comment[mr]=अनेक ऑनलाइन स्रोतांकडून हवामान माहिती +Comment[nb]=Værdata fra mange nettverkskilder +Comment[nds]=Wederdaten vun verscheden Tokoppelborns +Comment[nl]=Weergegevens voor meervoudige online bronnen +Comment[nn]=Vêrdata frå ulike nettkjelder +Comment[pa]=ਕਈ ਆਨਲਾਈਨ ਸਰੋਤਾਂ ਤੋਂ ਮੌਸਮ ਡਾਟਾ +Comment[pl]=Dane pogodowe z wielu internetowych źródeł +Comment[pt]=Dados meteorológicos de várias fontes 'online' +Comment[pt_BR]=Dados meteorológicos de múltiplas fontes on-line +Comment[ro]=Date meteorologice din diferite surse online +Comment[ru]=Информация о погоде из разных источников в Интернете +Comment[si]=විවිධ මාර්‍ගගත මූල වලින් කාලගුණ දත්ත +Comment[sk]=Dáta o počasí z rôznych online zdrojov +Comment[sl]=Podatki o vremenu iz več spletnih virov +Comment[sr]=Метеоролошки подаци из више извора на вези +Comment[sr@ijekavian]=Метеоролошки подаци из више извора на вези +Comment[sr@ijekavianlatin]=Meteorološki podaci iz više izvora na vezi +Comment[sr@latin]=Meteorološki podaci iz više izvora na vezi +Comment[sv]=Väderdata från flera olika nättjänster +Comment[tg]=Иттилооти обу ҳаво аз манбаъҳои гуногун +Comment[th]=ข้อมูลพยากรณ์อากาศจากแหล่งข้อมูลออนไลน์ต่าง ๆ +Comment[tr]=Birden fazla çevrim içi kaynaktan hava durumu verisi +Comment[ug]=توردىكى كۆپ مەنبەدىن كەلگەن ھاۋارايى سانلىق-مەلۇماتى +Comment[uk]=Дані щодо погоди з декількох мережевих джерел +Comment[wa]=Li meteyo a pårti di sacwants sourdants so fyis +Comment[x-test]=xxWeather data from multiple online sourcesxx +Comment[zh_CN]=来自多个在线信息源的天气数据 +Comment[zh_TW]=不同線上來源的天氣資料 +X-KDE-ServiceTypes=Plasma/DataEngine +Type=Service +Icon=weather-clear +X-KDE-Library=plasma_engine_weather + +X-KDE-PluginInfo-Author=Shawn Starr +X-KDE-PluginInfo-Email=shawn.starr@rogers.com +X-KDE-PluginInfo-Name=weather +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://www.kde.org +X-KDE-PluginInfo-License=GPLv2+ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= + diff --git a/plasma/generic/dataengines/weather/weatherengine.cpp b/plasma/generic/dataengines/weather/weatherengine.cpp new file mode 100644 index 00000000..4ac23b70 --- /dev/null +++ b/plasma/generic/dataengines/weather/weatherengine.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * Copyright (C) 2009 by Aaron Seigo * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "weatherengine.h" + +#include +#include + +#include +#include +#include + +#include +#include + +#include "ions/ion.h" + +// Constructor +WeatherEngine::WeatherEngine(QObject *parent, const QVariantList& args) + : Plasma::DataEngine(parent, args), + m_networkAvailable(false) +{ + Q_UNUSED(args) + + m_reconnectTimer.setSingleShot(true); + connect(&m_reconnectTimer, SIGNAL(timeout()), this, SLOT(startReconnect())); + + // Globally notify all plugins to remove their sources (and unload plugin) + connect(this, SIGNAL(sourceRemoved(QString)), this, SLOT(removeIonSource(QString))); + connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(unloadIons())); +} + +// Destructor +WeatherEngine::~WeatherEngine() +{ + // Cleanup all private data. + unloadIons(); +} + +/** + * Loads an ion plugin given a plugin name found via KService. + */ +Plasma::DataEngine *WeatherEngine::loadIon(const QString& plugName) +{ + KPluginInfo foundPlugin; + + foreach(const KPluginInfo &info, Plasma::DataEngineManager::listEngineInfo("weatherengine")) { + if (info.pluginName() == plugName) { + foundPlugin = info; + break; + } + } + + if (!foundPlugin.isValid()) { + return NULL; + } + + // Load the Ion plugin, store it into a QMap to handle multiple ions. + Plasma::DataEngine *ion = Plasma::DataEngineManager::self()->loadEngine(foundPlugin.pluginName()); + ion->setObjectName(plugName); + connect(ion, SIGNAL(sourceAdded(QString)), this, SLOT(newIonSource(QString))); + connect(ion, SIGNAL(forceUpdate(IonInterface*,QString)), this, SLOT(forceUpdate(IonInterface*,QString))); + + m_ions << plugName; + + return ion; +} + +/* FIXME: Q_PROPERTY functions to update the list of available plugins */ + +/** + * Unload an Ion plugin given a Ion plugin name. + */ +void WeatherEngine::unloadIon(const QString &name) +{ + Plasma::DataEngineManager::self()->unloadEngine(name); + m_ions.removeOne(name); +} + +void WeatherEngine::init() +{ + // Get the list of available plugins but don't load them + Solid::Networking::Status status = Solid::Networking::status(); + m_networkAvailable = (status == Solid::Networking::Connected || + status == Solid::Networking::Unknown); + connect(Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)), + this, SLOT(networkStatusChanged(Solid::Networking::Status))); + connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(updateIonList())); + + updateIonList(); + kDebug() << "init()"; +} + +void WeatherEngine::updateIonList(const QStringList &changedResources) +{ + if (changedResources.isEmpty() || changedResources.contains("services")) { + removeAllData("ions"); + foreach (const KPluginInfo &info, Plasma::DataEngineManager::listEngineInfo("weatherengine")) { + setData("ions", info.pluginName(), + QString("%1|%2").arg(info.property("Name").toString()).arg(info.pluginName())); + } + } +} + +/** + * SLOT: Get data from a new source + */ +void WeatherEngine::newIonSource(const QString& source) +{ + IonInterface *ion = qobject_cast(sender()); + + if (!ion) { + return; + } + + kDebug() << "newIonSource()"; + ion->connectSource(source, this); +} + +/** + * SLOT: Remove the datasource from the ion and unload plugin if needed + */ +void WeatherEngine::removeIonSource(const QString& source) +{ + IonInterface *ion = ionForSource(source); + if (ion) { + ion->removeSource(source); + // If plugin has no more sources let's unload the plugin + if (ion->isEmpty()) { + unloadIon(ionNameForSource(source)); + } + } + kDebug() << "removeIonSource()"; +} + +/** + * SLOT: Push out new data to applet + */ +void WeatherEngine::dataUpdated(const QString& source, Plasma::DataEngine::Data data) +{ + kDebug() << "dataUpdated()"; + setData(source, data); +} + +void WeatherEngine::unloadIons() +{ + foreach (const QString &ion, m_ions) { + Plasma::DataEngineManager::self()->unloadEngine(ion); + } + + m_ions.clear(); +} + +/** + * SLOT: Set up each Ion for the first time and get any data + */ +bool WeatherEngine::sourceRequestEvent(const QString &source) +{ + Plasma::DataEngine *ion = ionForSource(source); + + if (!ion) { + ion = loadIon(ionNameForSource(source)); + if (!ion) { + return false; + } + } + + // we should connect to the ion anyway, even if the network + // is down. when it comes up again, then it will be refreshed + ion->connectSource(source, this); + + kDebug() << "sourceRequestEvent(): Network is: " << m_networkAvailable; + if (!m_networkAvailable) { + setData(source, Data()); + return true; + } + + if (!containerForSource(source)) { + // it is an async reply, we need to set up the data anyways + setData(source, Data()); + } + return true; +} + +/** + * SLOT: update the Applet with new data from all ions loaded. + */ +bool WeatherEngine::updateSourceEvent(const QString& source) +{ + IonInterface *ion = ionForSource(source); + if (!ion) { + return false; + } + + kDebug() << "updateSourceEvent(): Network is: " << m_networkAvailable; + if (!m_networkAvailable) { + return false; + } + + return ion->updateSourceEvent(source); +} + +void WeatherEngine::networkStatusChanged(Solid::Networking::Status status) +{ + kDebug(); + m_networkAvailable = status == Solid::Networking::Connected || status == Solid::Networking::Unknown; + if (m_networkAvailable) { + // allow the network to settle down and actually come up + m_reconnectTimer.start(5000); + } +} + +void WeatherEngine::startReconnect() +{ + foreach (const QString &i, m_ions) { + IonInterface * ion = qobject_cast(Plasma::DataEngineManager::self()->engine(i)); + kDebug() << "resetting" << ion; + if (ion) { + ion->reset(); + } + } +} + +void WeatherEngine::forceUpdate(IonInterface *i, const QString &source) +{ + const QString actualSource(i->pluginName() + '|' + source); + Plasma::DataContainer *container = containerForSource(source); + if (container) { + kDebug() << "immediate update of" << source; + container->forceImmediateUpdate(); + } else { + kDebug() << "innexplicable failure of" << source; + } +} + +IonInterface* WeatherEngine::ionForSource(const QString& name) const +{ + int offset = name.indexOf('|'); + + if (offset < 1) { + return NULL; + } + + QString ionName = name.left(offset); + return qobject_cast(Plasma::DataEngineManager::self()->engine(ionName)); +} + +QString WeatherEngine::ionNameForSource(const QString& source) const +{ + int offset = source.indexOf('|'); + if (offset < 1) { + return QString(); + } + + return QString(source.left(offset)); +} + +#include "weatherengine.moc" diff --git a/plasma/generic/dataengines/weather/weatherengine.h b/plasma/generic/dataengines/weather/weatherengine.h new file mode 100644 index 00000000..5ef9f7a8 --- /dev/null +++ b/plasma/generic/dataengines/weather/weatherengine.h @@ -0,0 +1,137 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 by Shawn Starr * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef WEATHERENGINE_H +#define WEATHERENGINE_H + +#include + +#include + +#include + +#include "ions/ion.h" + + +/** + * @author Shawn Starr + * This class is DataEngine. It handles loading, unloading, updating any data the ions wish to send. It is a gateway for datasources (ions) to + * communicate with the WeatherEngine. + */ + +class WeatherEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + /** Constructor + * @param parent The parent object. + * @param args Argument list, unused. + */ + WeatherEngine(QObject *parent, const QVariantList &args); + + // Destructor + ~WeatherEngine(); + + // initialization + void init(); + + /** + * Load a plugin + * @arg pluginName Name of the plugin + * @return IonInterface returns an instance of the loaded plugin + */ + DataEngine* loadIon(const QString& pluginName); + + /** + * Unload a plugin. + * @arg name Name of the plugin. + */ + void unloadIon(const QString& name); + +protected: + /** + * Reimplemented from Plasma::DataEngine. We use it to communicate to the Ion plugins to set the data sources. + * @param source The datasource name. + */ + bool sourceRequestEvent(const QString &source); + +protected Q_SLOTS: + /** + * Reimplemented from Plasma::DataEngine. + * @param source The datasource to be updated. + * @param data The new data updated. + */ + void dataUpdated(const QString& source, Plasma::DataEngine::Data data); + + void forceUpdate(IonInterface *ion, const QString &source); + + /** + * Notify WeatherEngine a new ion has data sources. + * @arg source datasource name. + */ + void newIonSource(const QString& source); + /** + * Notify WeatherEngine a datasource is being removed. + * @arg source datasource name. + */ + void removeIonSource(const QString& source); + /** + * Reimplemented from Plasma::DataEngine. + * @param source The datasource to update. + */ + bool updateSourceEvent(const QString& source); + + /** + * Whenever networking changes, take action + */ + void networkStatusChanged(Solid::Networking::Status); + void startReconnect(); + + /** + * Cleans up the ions that are currently loaded + */ + void unloadIons(void); + + /** + * updates the list of ions whenever KSycoca changes (as well as on init + */ + void updateIonList(const QStringList &changedResources = QStringList()); + +private: + /** + * Get instance of a loaded ion. + * @returns a IonInterface instance of a loaded plugin. + */ + IonInterface* ionForSource(const QString& name) const; + + /** + * Get plugin name from datasource. + * @returns The plugin name given a datasource. + */ + QString ionNameForSource(const QString& source) const; + + QStringList m_ions; + bool m_networkAvailable; + QTimer m_reconnectTimer; +}; + +K_EXPORT_PLASMA_DATAENGINE(weather, WeatherEngine) + +#endif diff --git a/plasma/generic/runners/CMakeLists.txt b/plasma/generic/runners/CMakeLists.txt new file mode 100644 index 00000000..6831ac0b --- /dev/null +++ b/plasma/generic/runners/CMakeLists.txt @@ -0,0 +1,23 @@ +add_subdirectory(activities) +add_subdirectory(bookmarks) +add_subdirectory(calculator) +add_subdirectory(locations) +add_subdirectory(places) +add_subdirectory(services) +add_subdirectory(recentdocuments) +add_subdirectory(shell) +add_subdirectory(solid) +add_subdirectory(webshortcuts) +add_subdirectory(windowedwidgets) + +if(NepomukCore_FOUND) + add_subdirectory(nepomuksearch) +endif(NepomukCore_FOUND) + +if(NOT WIN32) +add_subdirectory(powerdevil) +add_subdirectory(sessions) +add_subdirectory(windows) +add_subdirectory(kill) +endif(NOT WIN32) + diff --git a/plasma/generic/runners/activities/CMakeLists.txt b/plasma/generic/runners/activities/CMakeLists.txt new file mode 100644 index 00000000..e630c36c --- /dev/null +++ b/plasma/generic/runners/activities/CMakeLists.txt @@ -0,0 +1,12 @@ +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs) + +set(krunner_activities_SRCS + activityrunner.cpp +) + +kde4_add_plugin(krunner_activities ${krunner_activities_SRCS}) +target_link_libraries(krunner_activities ${KDE4_PLASMA_LIBS} ${KACTIVITIES_LIBRARY}) + +install(TARGETS krunner_activities DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-runner-activityrunner.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/activities/Messages.sh b/plasma/generic/runners/activities/Messages.sh new file mode 100755 index 00000000..7d7bb1ca --- /dev/null +++ b/plasma/generic/runners/activities/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_runner_activities.pot +rm -f rc.cpp diff --git a/plasma/generic/runners/activities/activityrunner.cpp b/plasma/generic/runners/activities/activityrunner.cpp new file mode 100644 index 00000000..728e155a --- /dev/null +++ b/plasma/generic/runners/activities/activityrunner.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2011 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "activityrunner.h" + +#include +#include +#include + +ActivityRunner::ActivityRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args), + m_activities(0), + m_keywordi18n(i18nc("KRunner keyword", "activity")), + m_keyword("activity"), + m_enabled(false) +{ + setObjectName(QLatin1String("Activities")); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | + Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Help); + + connect(this, SIGNAL(prepare()), this, SLOT(prep())); + connect(this, SIGNAL(teardown()), this, SLOT(down())); + + serviceStatusChanged(KActivities::Consumer::FullFunctionality); +} + +void ActivityRunner::prep() +{ + if (!m_activities) { + m_activities = new KActivities::Controller(this); + connect(m_activities, SIGNAL(serviceStatusChanged(KActivities::Consumer::ServiceStatus)), + this, SLOT(serviceStatusChanged(KActivities::Consumer::ServiceStatus))); + serviceStatusChanged(m_activities->serviceStatus()); + } +} + +void ActivityRunner::down() +{ + delete m_activities; + m_activities = 0; +} + +void ActivityRunner::serviceStatusChanged(KActivities::Consumer::ServiceStatus status) +{ + const bool active = status != KActivities::Consumer::NotRunning; + if (m_enabled == active) { + return; + } + + m_enabled = active; + QList syntaxes; + if (m_enabled) { + setDefaultSyntax(Plasma::RunnerSyntax(m_keywordi18n, i18n("Lists all activities currently available to be run."))); + addSyntax(Plasma::RunnerSyntax(i18nc("KRunner keyword", "activity :q:"), i18n("Switches to activity :q:."))); + } +} + +ActivityRunner::~ActivityRunner() +{ +} + +void ActivityRunner::match(Plasma::RunnerContext &context) +{ + if (!m_enabled) { + return; + } + + const QString term = context.query().trimmed(); + bool list = false; + QString name; + + if (term.startsWith(m_keywordi18n, Qt::CaseInsensitive)) { + if (term.size() == m_keywordi18n.size()) { + list = true; + } else { + name = term.right(term.size() - m_keywordi18n.size()).trimmed(); + list = name.isEmpty(); + } + } else if (term.startsWith(m_keyword, Qt::CaseInsensitive)) { + if (term.size() == m_keyword.size()) { + list = true; + } else { + name = term.right(term.size() - m_keyword.size()).trimmed(); + list = name.isEmpty(); + } + } else if (context.singleRunnerQueryMode()) { + name = term; + } else { + return; + } + + QList matches; + QStringList activities = m_activities->listActivities(); + qSort(activities); + + const QString current = m_activities->currentActivity(); + + if (!context.isValid()) { + return; + } + + if (list) { + foreach (const QString &activity, activities) { + if (current == activity) { + continue; + } + + KActivities::Info info(activity); + addMatch(info, matches); + + if (!context.isValid()) { + return; + } + } + } else { + foreach (const QString &activity, activities) { + if (current == activity) { + continue; + } + + KActivities::Info info(activity); + if (info.name().startsWith(name, Qt::CaseInsensitive)) { + addMatch(info, matches); + } + + if (!context.isValid()) { + return; + } + } + } + + context.addMatches(context.query(), matches); +} + +void ActivityRunner::addMatch(const KActivities::Info &activity, QList &matches) +{ + Plasma::QueryMatch match(this); + match.setData(activity.id()); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setIcon(activity.icon().isEmpty() ? KIcon("preferences-activities") : KIcon(activity.icon())); + match.setText(i18n("Switch to \"%1\"", activity.name())); + match.setRelevance(0.7 + ((activity.state() == KActivities::Info::Running || + activity.state() == KActivities::Info::Starting) ? 0.1 : 0)); + matches << match; +} + +void ActivityRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context) + + if (!m_enabled || !m_activities) { + return; + } + + m_activities->setCurrentActivity(match.data().toString()); +} + +#include "activityrunner.moc" diff --git a/plasma/generic/runners/activities/activityrunner.h b/plasma/generic/runners/activities/activityrunner.h new file mode 100644 index 00000000..7fef7492 --- /dev/null +++ b/plasma/generic/runners/activities/activityrunner.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ACTIVITYRUNNER_H +#define ACTIVITYRUNNER_H + +#include + +#include + +class ActivityRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + ActivityRunner(QObject *parent, const QVariantList &args); + ~ActivityRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + + private Q_SLOTS: + void prep(); + void down(); + void serviceStatusChanged(KActivities::Consumer::ServiceStatus status); + + private: + void addMatch(const KActivities::Info &activity, QList &matches); + + KActivities::Controller *m_activities; + const QString m_keywordi18n; + const QString m_keyword; + bool m_enabled; +}; + +K_EXPORT_PLASMA_RUNNER(activities, ActivityRunner) + +#endif diff --git a/plasma/generic/runners/activities/plasma-runner-activityrunner.desktop b/plasma/generic/runners/activities/plasma-runner-activityrunner.desktop new file mode 100644 index 00000000..f1ecde23 --- /dev/null +++ b/plasma/generic/runners/activities/plasma-runner-activityrunner.desktop @@ -0,0 +1,121 @@ +[Desktop Entry] +Name=Activities +Name[ar]=الأنشطة +Name[bg]=Дейности +Name[bs]=motor aktivnosti +Name[ca]=Activitats +Name[ca@valencia]=Activitats +Name[cs]=Aktivity +Name[da]=Aktiviteter +Name[de]=Aktivitäten +Name[el]=Δραστηριότητες +Name[en_GB]=Activities +Name[es]=Actividades +Name[et]=Tegevused +Name[eu]=Jarduerak +Name[fa]=فعالیتها +Name[fi]=Aktiviteetit +Name[fr]=Activités +Name[ga]=Gníomhaíochtaí +Name[gl]=Actividades +Name[he]=עילויות +Name[hr]=Aktivnosti +Name[hu]=Aktivitások +Name[ia]=Activitates +Name[is]=Virknistjóri +Name[it]=Attività +Name[ja]=アクティビティ +Name[kk]=Белсенділіктер +Name[km]=សកម្មភាព +Name[ko]=활동 +Name[lt]=Veiklos +Name[lv]=Aktivitātes +Name[mr]=कार्यपध्दती +Name[nb]=Aktiviteter +Name[nds]=Aktiviteten +Name[nl]=Activiteiten +Name[pa]=ਸਰਗਰਮੀਆਂ +Name[pl]=Działania +Name[pt]=Actividades +Name[pt_BR]=Atividades +Name[ro]=Activități +Name[ru]=Комнаты +Name[sk]=Aktivity +Name[sl]=Dejavnosti +Name[sr]=активности +Name[sr@ijekavian]=активности +Name[sr@ijekavianlatin]=aktivnosti +Name[sr@latin]=aktivnosti +Name[sv]=Aktiviteter +Name[tr]=Etkinlikler +Name[ug]=پائالىيەتلەر +Name[uk]=Простори дій +Name[vi]=Hoạt động +Name[wa]=Activités +Name[x-test]=xxActivitiesxx +Name[zh_CN]=活动 +Name[zh_TW]=活動 +Comment=List and switch between desktop activities +Comment[bg]=Списък и превключване между дейностите +Comment[bs]=Prikaz i prebacivanje između aktivnosti radne površine +Comment[ca]=Llista i commuta entre activitats d'escriptori +Comment[ca@valencia]=Llista i commuta entre activitats d'escriptori +Comment[cs]=Zobrazení a přepínač aktivit pracovní plochy +Comment[da]=Vis og skift mellem skrivebordsaktiviteter +Comment[de]=Aktivitäten anzeigen und zwischen ihnen umschalten +Comment[el]=Εμφάνιση και εναλλαγή μεταξύ των δραστηριοτήτων της επιφάνειας εργασίας +Comment[en_GB]=List and switch between desktop activities +Comment[es]=Ver y cambiar entre las actividades de escritorio +Comment[et]=Töölauategevuste näitamine ja nende vahel lülitamine +Comment[eu]=Zerrendatu mahaigaineko jarduerak eta batetik bestera aldatu +Comment[fi]=Luettele aktiviteetit ja vaihda niiden välillä +Comment[fr]=Affiche les activités du bureau et permet d'en changer +Comment[gl]=Lista e troca entre actividades o escritorio +Comment[he]=הצגה והחלפה בין פעילויות שולחן עבודה +Comment[hr]=Izlistaj i prebacuj između aktivnosti radne površine +Comment[hu]=Asztali aktivitások listázása és váltás közöttük +Comment[ia]=Lista e commuta inter activitates de scriptorio +Comment[is]=Telur upp og skiptir milli skjáborðsvirkni +Comment[it]=Visualizza e cambia le attività del desktop +Comment[ja]=デスクトップアクティビティを一覧表示して切り替える +Comment[kk]=Белсенділіктерді тізімдеу және ауыстыру +Comment[km]=មើល ហើយ​ប្ដូរ​ប្លង់​ផ្ទៃតុ​សកម្ម​ +Comment[ko]=데스크톱 활동을 보거나 바꾸기 +Comment[lt]=Peržiūrėti ir persijungti tarp darbastalio veiklų +Comment[lv]=Parādīt un pārslēgties starp virtuālajām darbvirsmām +Comment[mr]=वेगळ्या डेस्कटॉप कार्यपध्दतीवर जाण्यासाठी यादी दर्शवा व बदला +Comment[nb]=Vis og bytt mellom skrivebordsaktiviteter +Comment[nds]=Aktiv Schriefdischakschonen ankieken un wesseln +Comment[nl]=Bureaubladactiviteiten laten zien en er tussen schakelen +Comment[pa]=ਡੈਸਕਟਾਪ ਸਰਗਰਮੀਆਂ ਵੇਖੋ ਅਤੇ ਉਹਨਾਂ ਵਿੱਚ ਜਾਉ +Comment[pl]=Tworzenie listy i przełączanie się pomiędzy działaniami pulpitu +Comment[pt]=Ver e mudar de actividades no ambiente de trabalho +Comment[pt_BR]=Lista e alterna entre as atividades da área de trabalho +Comment[ro]=Vizualizează și schimbă între activitățile biroului +Comment[ru]=Просмотр и переключение между комнатами +Comment[sk]=Vypísať a prepínať medzi aktivitami pracovnej plochy +Comment[sl]=Oglejte si namizne dejavnosti in preklopite med njimi +Comment[sr]=Приказ и пребацивање између активности површи +Comment[sr@ijekavian]=Приказ и пребацивање између активности површи +Comment[sr@ijekavianlatin]=Prikaz i prebacivanje između aktivnosti površi +Comment[sr@latin]=Prikaz i prebacivanje između aktivnosti površi +Comment[sv]=Visa och byt mellan skrivbordsaktiviteter +Comment[tr]=Listele ve masaüstü eylemleri arasında değiştir +Comment[ug]=ئۈستەلئۈستى پائالىيەتلىرى ئارىسىدىكى تىزىم ۋە ئالماشتۇرۇش +Comment[uk]=Перегляд і перемикання між просторами дій стільниці +Comment[vi]=Liệt kê và chuyển đổi giữa các Hoạt động màn hình làm việc +Comment[wa]=Fé l' djivêye eyet passer d' ene activité do scribanne a ene ôte +Comment[x-test]=xxList and switch between desktop activitiesxx +Comment[zh_CN]=显示和切换桌面活动 +Comment[zh_TW]=列出並在桌面活動間切換 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=preferences-activities +X-KDE-Library=krunner_activities +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=org.kde.activities +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/bookmarks/.gitignore b/plasma/generic/runners/bookmarks/.gitignore new file mode 100644 index 00000000..b25c15b8 --- /dev/null +++ b/plasma/generic/runners/bookmarks/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/plasma/generic/runners/bookmarks/CMakeLists.txt b/plasma/generic/runners/bookmarks/CMakeLists.txt new file mode 100644 index 00000000..173866bf --- /dev/null +++ b/plasma/generic/runners/bookmarks/CMakeLists.txt @@ -0,0 +1,45 @@ +########### next target ############### +set(EXTERNAL_LIBS ${KDE4_KIO_LIBS} ${QT_QTSCRIPT_LIBRARY} ${KDE4_PLASMA_LIBS} ${QT_QTSQL_LIBRARY}) +if(QJSON_FOUND) + add_definitions(-DHAVE_QJSON=1) + # Some distributions (e.g. Debian or Ubuntu 12.10) seem to install a QJSONConfig.cmake with lower-case variables, + # which is preferred to our FindQJSON.cmake. Make sure this does not break the build. + set(EXTERNAL_LIBS ${EXTERNAL_LIBS} ${QJSON_LIBRARIES} ${qjson_LIBRARIES} ) + include_directories(${QJSON_INCLUDE_DIR} ${qjson_INCLUDE_DIR}) +endif(QJSON_FOUND) + +set(krunner_bookmarksrunner_SRCS + browserfactory.cpp + bookmarkmatch.cpp + faviconfromblob.cpp + favicon.cpp + fetchsqlite.cpp + browsers/opera.cpp + bookmarksrunner.cpp + browsers/kdebrowser.cpp + browsers/firefox.cpp +) + +if(QJSON_FOUND) +set(krunner_bookmarksrunner_SRCS + ${krunner_bookmarksrunner_SRCS} + browsers/chromefindprofile.cpp + browsers/chrome.cpp +) +endif(QJSON_FOUND) + + +kde4_add_plugin(krunner_bookmarksrunner ${krunner_bookmarksrunner_SRCS}) +target_link_libraries(krunner_bookmarksrunner ${EXTERNAL_LIBS}) + +install(TARGETS krunner_bookmarksrunner DESTINATION ${PLUGIN_INSTALL_DIR} ) + + +########### install files ############### + +install(FILES plasma-runner-bookmarks.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +# Currently tests include only chrome, so no need to get include them if json is not found +if(QJSON_FOUND) + add_subdirectory(tests) +endif(QJSON_FOUND) diff --git a/plasma/generic/runners/bookmarks/Messages.sh b/plasma/generic/runners/bookmarks/Messages.sh new file mode 100755 index 00000000..25d9792d --- /dev/null +++ b/plasma/generic/runners/bookmarks/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_bookmarksrunner.pot diff --git a/plasma/generic/runners/bookmarks/bookmarkmatch.cpp b/plasma/generic/runners/bookmarks/bookmarkmatch.cpp new file mode 100644 index 00000000..31eb0637 --- /dev/null +++ b/plasma/generic/runners/bookmarks/bookmarkmatch.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "bookmarkmatch.h" +#include +#include "favicon.h" + +// TODO: test + +BookmarkMatch::BookmarkMatch(Favicon *favicon, const QString& searchTerm, const QString& bookmarkTitle, const QString& bookmarkURL, const QString& description ) + : m_favicon(favicon), m_searchTerm(searchTerm), m_bookmarkTitle(bookmarkTitle), m_bookmarkURL(bookmarkURL), m_description(description) +{ +} + +Plasma::QueryMatch BookmarkMatch::asQueryMatch( Plasma::AbstractRunner* runner ) +{ + Plasma::QueryMatch::Type type = Plasma::QueryMatch::NoMatch; + qreal relevance = 0; + + if (m_bookmarkTitle.compare(m_searchTerm, Qt::CaseInsensitive) == 0 || + (!m_description.isEmpty() && m_description.compare(m_searchTerm, Qt::CaseInsensitive) == 0) + ) { + type = Plasma::QueryMatch::ExactMatch; + relevance = 1.0; + } else if (m_bookmarkTitle.contains(m_searchTerm, Qt::CaseInsensitive)) { + type = Plasma::QueryMatch::PossibleMatch; + relevance = 0.45; + } else if (!m_description.isEmpty() && m_description.contains(m_searchTerm, Qt::CaseInsensitive)) { + type = Plasma::QueryMatch::PossibleMatch; + relevance = 0.3; + } else if (m_bookmarkURL.contains(m_searchTerm, Qt::CaseInsensitive)) { + type = Plasma::QueryMatch::PossibleMatch; + relevance = 0.2; + } else { + type = Plasma::QueryMatch::PossibleMatch; + relevance = 0.18; + } + + bool isNameEmpty = m_bookmarkTitle.isEmpty(); + bool isDescriptionEmpty = m_description.isEmpty(); + + Plasma::QueryMatch match(runner); + match.setType(type); + match.setRelevance(relevance); + match.setIcon(m_favicon->iconFor(m_bookmarkURL)); + match.setSubtext(m_bookmarkURL); + + // Try to set the following as text in this order: name, description, url + match.setText( isNameEmpty + ? + (!isDescriptionEmpty ? m_description : m_bookmarkURL) + : + m_bookmarkTitle ); + + match.setData(m_bookmarkURL); + return match; +} + +void BookmarkMatch::addTo(QList< BookmarkMatch >& listOfResults, bool addEvenOnNoMatch) +{ + if(!addEvenOnNoMatch && ! ( + matches(m_searchTerm, m_bookmarkTitle) || + matches(m_searchTerm, m_description) || + matches(m_searchTerm, m_bookmarkURL) + )) { + return; + } + listOfResults << *this; +} + +bool BookmarkMatch::matches(const QString &search, const QString &matchingField) +{ + return !matchingField.simplified().isEmpty() && matchingField.contains(search, Qt::CaseInsensitive); +} + + diff --git a/plasma/generic/runners/bookmarks/bookmarkmatch.h b/plasma/generic/runners/bookmarks/bookmarkmatch.h new file mode 100644 index 00000000..54ac19d7 --- /dev/null +++ b/plasma/generic/runners/bookmarks/bookmarkmatch.h @@ -0,0 +1,47 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef BOOKMARKMATCH_H +#define BOOKMARKMATCH_H + +#include +#include +#include +#include + +class Favicon; +class BookmarkMatch +{ +public: + BookmarkMatch(Favicon *favicon, const QString &searchTerm, const QString &bookmarkTitle, const QString &bookmarkURL, const QString &description = QString()); + void addTo(QList< BookmarkMatch >& listOfResults, bool addEvenOnNoMatch); + Plasma::QueryMatch asQueryMatch(Plasma::AbstractRunner *runner); +private: + bool matches(const QString &search, const QString &matchingField); +private: + Favicon * m_favicon; + QString m_searchTerm; + QString m_bookmarkTitle; + QString m_bookmarkURL; + QString m_description; +}; + +#endif // BOOKMARKMATCH_H diff --git a/plasma/generic/runners/bookmarks/bookmarksrunner.cpp b/plasma/generic/runners/bookmarks/bookmarksrunner.cpp new file mode 100644 index 00000000..45093af1 --- /dev/null +++ b/plasma/generic/runners/bookmarks/bookmarksrunner.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "bookmarksrunner.h" +#include "browser.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "bookmarkmatch.h" +#include "browserfactory.h" +#include "bookmarksrunner_defs.h" + +BookmarksRunner::BookmarksRunner( QObject* parent, const QVariantList &args ) + : Plasma::AbstractRunner(parent, args), m_browser(0), m_browserFactory(new BrowserFactory(this)) +{ + Q_UNUSED(args) + kDebug(kdbg_code) << "Creating BookmarksRunner"; + setObjectName( QLatin1String("Bookmarks" )); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds web browser bookmarks matching :q:."))); + setDefaultSyntax(Plasma::RunnerSyntax(i18nc("list of all web browser bookmarks", "bookmarks"), + i18n("List all web browser bookmarks"))); + + connect(this, SIGNAL(prepare()), this, SLOT(prep())); +} + +BookmarksRunner::~BookmarksRunner() +{ +} + + +void BookmarksRunner::prep() +{ + m_browser = m_browserFactory->find(findBrowserName(), this); + connect(this, SIGNAL(teardown()), dynamic_cast(m_browser), SLOT(teardown())); + m_browser->prepare(); +} + + + +void BookmarksRunner::match(Plasma::RunnerContext &context) +{ + if(! m_browser) return; + const QString term = context.query(); + if ((term.length() < 3) && (!context.singleRunnerQueryMode())) { + return; + } + + bool allBookmarks = term.compare(i18nc("list of all konqueror bookmarks", "bookmarks"), + Qt::CaseInsensitive) == 0; + + QList matches = m_browser->match(term, allBookmarks); + foreach(BookmarkMatch match, matches) { + if(!context.isValid()) + return; + context.addMatch(term, match.asQueryMatch(this)); + } +} + +QString BookmarksRunner::findBrowserName() +{ + //HACK find the default browser + KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), QLatin1String("General") ); + QString exec = config.readPathEntry(QLatin1String("BrowserApplication"), QString()); + kDebug(kdbg_code) << "Found exec string: " << exec; + if (exec.isEmpty()) { + KService::Ptr service = KMimeTypeTrader::self()->preferredService("text/html"); + if (service) { + exec = service->exec(); + } + } + + kDebug(kdbg_code) << "KRunner::Bookmarks: found executable " << exec << " as default browser"; + return exec; + +} + +void BookmarksRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action) +{ + Q_UNUSED(context); + const QString term = action.data().toString(); + KUrl url = KUrl(term); + + //support urls like "kde.org" by transforming them to http://kde.org + if (url.protocol().isEmpty()) { + const int idx = term.indexOf('/'); + + url.clear(); + url.setHost(term.left(idx)); + if (idx != -1) { + //allow queries + const int queryStart = term.indexOf('?', idx); + int pathLength = -1; + if ((queryStart > -1) && (idx < queryStart)) { + pathLength = queryStart - idx; + url.setQuery(term.mid(queryStart)); + } + + url.setPath(term.mid(idx, pathLength)); + } + url.setProtocol("http"); + } + + KToolInvocation::invokeBrowser(url.url()); +} + +QMimeData * BookmarksRunner::mimeDataForMatch(const Plasma::QueryMatch * match) +{ + QMimeData * result = new QMimeData(); + QList urls; + urls << QUrl(match->data().toString()); + result->setUrls(urls); + + result->setText(match->data().toString()); + + return result; +} + +#include "bookmarksrunner.moc" diff --git a/plasma/generic/runners/bookmarks/bookmarksrunner.h b/plasma/generic/runners/bookmarks/bookmarksrunner.h new file mode 100644 index 00000000..ef0b1ea0 --- /dev/null +++ b/plasma/generic/runners/bookmarks/bookmarksrunner.h @@ -0,0 +1,64 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef BOOKMARKSRUNNER_H +#define BOOKMARKSRUNNER_H + +#include +#include + + +class KBookmark; +class Browser; +class BrowserFactory; +class KJob; + +/** This runner searchs for bookmarks in browsers like Konqueror, Firefox and Opera */ +class BookmarksRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + BookmarksRunner(QObject* parent, const QVariantList &args); + ~BookmarksRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + + private: + + /** @returns the browser to get the bookmarks from + * @see Browser + */ + QString findBrowserName(); + + private: + Browser *m_browser; + BrowserFactory * const m_browserFactory; + protected Q_SLOTS: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); + + private Q_SLOTS: + void prep(); +}; + +K_EXPORT_PLASMA_RUNNER(bookmarksrunner, BookmarksRunner) + +#endif diff --git a/plasma/generic/runners/bookmarks/bookmarksrunner_defs.h b/plasma/generic/runners/bookmarks/bookmarksrunner_defs.h new file mode 100644 index 00000000..211925af --- /dev/null +++ b/plasma/generic/runners/bookmarks/bookmarksrunner_defs.h @@ -0,0 +1,26 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BOOKMARKS_RUNNER_DEFS +#define BOOKMARKS_RUNNER_DEFS + +#define kdbg_code 1207 + +#endif \ No newline at end of file diff --git a/plasma/generic/runners/bookmarks/browser.h b/plasma/generic/runners/bookmarks/browser.h new file mode 100644 index 00000000..300e646d --- /dev/null +++ b/plasma/generic/runners/bookmarks/browser.h @@ -0,0 +1,39 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BROWSER_H +#define BROWSER_H +#include +#include +#include "bookmarkmatch.h" + +class Browser +{ +public: + virtual ~Browser() {} + virtual QList match(const QString& term, bool addEveryThing) = 0; + virtual void prepare() {} + +public Q_SLOTS: + virtual void teardown() {} +}; + + +#endif // BROWSER_H diff --git a/plasma/generic/runners/bookmarks/browserfactory.cpp b/plasma/generic/runners/bookmarks/browserfactory.cpp new file mode 100644 index 00000000..8abeb6fd --- /dev/null +++ b/plasma/generic/runners/bookmarks/browserfactory.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "browserfactory.h" +#include "browser.h" +#include "browsers/kdebrowser.h" +#include "browsers/firefox.h" +#include "browsers/opera.h" +#include "browsers/chromefindprofile.h" +#include "browsers/chrome.h" + +Browser *BrowserFactory::find(const QString& browserName, QObject* parent) +{ + if(m_previousBrowserName == browserName) { + return m_previousBrowser; + } + delete m_previousBrowser; + m_previousBrowserName = browserName; + if (browserName.contains("firefox", Qt::CaseInsensitive) || browserName.contains("iceweasel", Qt::CaseInsensitive)) { + m_previousBrowser = new Firefox(parent); + } else if (browserName.contains("opera", Qt::CaseInsensitive)) { + m_previousBrowser = new Opera(parent); +#ifdef HAVE_QJSON + } else if (browserName.contains("chrome", Qt::CaseInsensitive)) { + m_previousBrowser = new Chrome(new FindChromeProfile("google-chrome", QDir::homePath(), parent), parent); + } else if (browserName.contains("chromium", Qt::CaseInsensitive)) { + m_previousBrowser = new Chrome(new FindChromeProfile("chromium", QDir::homePath(), parent), parent); +#endif // HAVE_QJSON + } else { + m_previousBrowser = new KDEBrowser(parent); + } + + return m_previousBrowser; +} + + +BrowserFactory::BrowserFactory(QObject *parent) + : QObject(parent), m_previousBrowser(0), m_previousBrowserName("invalid") +{ +} + diff --git a/plasma/generic/runners/bookmarks/browserfactory.h b/plasma/generic/runners/bookmarks/browserfactory.h new file mode 100644 index 00000000..1f15f223 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browserfactory.h @@ -0,0 +1,38 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BROWSERFACTORY_H +#define BROWSERFACTORY_H +#include +#include + +class Browser; +class BrowserFactory : public QObject +{ + Q_OBJECT +public: + BrowserFactory(QObject *parent =0); + Browser *find(const QString &browserName, QObject *parent = 0); +private: + Browser *m_previousBrowser; + QString m_previousBrowserName; +}; + +#endif // BROWSERFACTORY_H diff --git a/plasma/generic/runners/bookmarks/browsers/chrome.cpp b/plasma/generic/runners/bookmarks/browsers/chrome.cpp new file mode 100644 index 00000000..f1f004ea --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/chrome.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "chrome.h" +#include "faviconfromblob.h" +#include "browsers/findprofile.h" +#include +#include +#include +#include "bookmarksrunner_defs.h" +#include +#include + +class ProfileBookmarks { +public: + ProfileBookmarks(Profile &profile) : m_profile(profile) {} + inline QList bookmarks() { return m_bookmarks; } + inline Profile profile() { return m_profile; } + void tearDown() { m_profile.favicon()->teardown(); m_bookmarks.clear(); } + void add(QVariantMap &bookmarkEntry) { m_bookmarks << bookmarkEntry; } +private: + Profile m_profile; + QList m_bookmarks; +}; + +Chrome::Chrome( FindProfile* findProfile, QObject* parent ) + : QObject(parent) +{ + foreach(Profile profile, findProfile->find()) { + m_profileBookmarks << new ProfileBookmarks(profile); + } +} + +Chrome::~Chrome() +{ + foreach(ProfileBookmarks *profileBookmark, m_profileBookmarks) { + delete profileBookmark; + } +} + +QList Chrome::match(const QString &term, bool addEveryThing) +{ + QList results; + foreach(ProfileBookmarks *profileBookmarks, m_profileBookmarks) { + results << match(term, addEveryThing, profileBookmarks); + } + return results; +} + +QList Chrome::match(const QString &term, bool addEveryThing, ProfileBookmarks *profileBookmarks) +{ + QList results; + foreach(QVariantMap bookmark, profileBookmarks->bookmarks()) { + QString url = bookmark.value("url").toString(); + + BookmarkMatch bookmarkMatch(profileBookmarks->profile().favicon(), term, bookmark.value("name").toString(), url); + bookmarkMatch.addTo(results, addEveryThing); + } + return results; +} + +void Chrome::prepare() +{ + QJson::Parser parser; + bool ok; + foreach(ProfileBookmarks *profileBookmarks, m_profileBookmarks) { + Profile profile = profileBookmarks->profile(); + QFile bookmarksFile(profile.path()); + QVariant result = parser.parse(&bookmarksFile, &ok); + if(!ok || !result.toMap().contains("roots")) { + return; + } + QVariantMap entries = result.toMap().value("roots").toMap(); + foreach(QVariant folder, entries.values()) { + parseFolder(folder.toMap(), profileBookmarks); + } + profile.favicon()->prepare(); + } +} + +void Chrome::teardown() +{ + foreach(ProfileBookmarks *profileBookmarks, m_profileBookmarks) { + profileBookmarks->tearDown(); + } +} + +void Chrome::parseFolder(const QVariantMap &entry, ProfileBookmarks *profile) +{ + QVariantList children = entry.value("children").toList(); + foreach(QVariant child, children) { + QVariantMap entry = child.toMap(); + if(entry.value("type").toString() == "folder") + parseFolder(entry, profile); + else { + profile->add(entry); + } + } +} diff --git a/plasma/generic/runners/bookmarks/browsers/chrome.h b/plasma/generic/runners/bookmarks/browsers/chrome.h new file mode 100644 index 00000000..44bde2e9 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/chrome.h @@ -0,0 +1,49 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef CHROME_H +#define CHROME_H + +#include "browser.h" +#include "findprofile.h" +#include +#include +#include + +class FaviconFromBlob; +class ProfileBookmarks; +class Chrome : public QObject, public Browser +{ + Q_OBJECT +public: + Chrome(FindProfile *findProfile, QObject* parent = 0); + ~Chrome(); + virtual QList match(const QString &term, bool addEveryThing); +public slots: + virtual void prepare(); + virtual void teardown(); +private: + void parseFolder(const QVariantMap &entry, ProfileBookmarks *profile); + virtual QList match(const QString &term, bool addEveryThing, ProfileBookmarks *profileBookmarks); + QList m_profileBookmarks; +}; + +#endif // CHROME_H diff --git a/plasma/generic/runners/bookmarks/browsers/chromefindprofile.cpp b/plasma/generic/runners/bookmarks/browsers/chromefindprofile.cpp new file mode 100644 index 00000000..5983697f --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/chromefindprofile.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "chromefindprofile.h" +#include +#include +#include +#include +#include "bookmarksrunner_defs.h" +#include "faviconfromblob.h" +#include + +FindChromeProfile::FindChromeProfile (const QString &applicationName, const QString &homeDirectory, QObject* parent ) + : QObject(parent), m_applicationName(applicationName), m_homeDirectory(homeDirectory) +{ +} + +QList FindChromeProfile::find() +{ + QString configDirectory = QString("%1/.config/%2") + .arg(m_homeDirectory).arg(m_applicationName); + QString localStateFileName = QString("%1/Local State") + .arg(configDirectory); + + QList profiles; + QJson::Parser parser; + bool ok; + QFile localStateFile(localStateFileName); + + QVariantMap localState = parser.parse(&localStateFile, &ok).toMap(); + if(!ok) { + kDebug(kdbg_code) << "error opening " << QFileInfo(localStateFile).absoluteFilePath(); + return profiles; + } + + QVariantMap profilesConfig = localState.value("profile").toMap().value("info_cache").toMap(); + + foreach(QString profile, profilesConfig.keys()) { + QString profilePath = QString("%1/%2").arg(configDirectory).arg(profile); + QString profileBookmarksPath = QString("%1/%2").arg(profilePath).arg("Bookmarks"); + profiles << Profile(profileBookmarksPath, FaviconFromBlob::chrome(profilePath, this)); + } + + return profiles; +} diff --git a/plasma/generic/runners/bookmarks/browsers/chromefindprofile.h b/plasma/generic/runners/bookmarks/browsers/chromefindprofile.h new file mode 100644 index 00000000..890c6e31 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/chromefindprofile.h @@ -0,0 +1,40 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef CHROMEFINDPROFILE_H +#define CHROMEFINDPROFILE_H + +#include +#include +#include "browsers/findprofile.h" + +class FindChromeProfile : public QObject, public FindProfile +{ + +public: + explicit FindChromeProfile (const QString& applicationName, const QString &homeDirectory = QDir::homePath(), QObject* parent = 0 ); + virtual QList find(); +private: + QString const m_applicationName; + QString const m_homeDirectory; +}; + +#endif // CHROMEFINDPROFILE_H diff --git a/plasma/generic/runners/bookmarks/browsers/findprofile.h b/plasma/generic/runners/bookmarks/browsers/findprofile.h new file mode 100644 index 00000000..8d3b23ac --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/findprofile.h @@ -0,0 +1,42 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef FIND_PROFILE_H +#define FIND_PROFILE_H +#include +#include + +class Favicon; +class Profile { +public: + Profile(const QString &path, Favicon *favicon) : m_path(path), m_favicon(favicon) {} + inline QString path() const { return m_path; } + inline Favicon *favicon() const { return m_favicon; } +private: + QString m_path; + Favicon *m_favicon; +}; + +class FindProfile { +public: + virtual QList find() = 0; + virtual ~FindProfile() {} +}; + +#endif diff --git a/plasma/generic/runners/bookmarks/browsers/firefox.cpp b/plasma/generic/runners/bookmarks/browsers/firefox.cpp new file mode 100644 index 00000000..4cbe6d02 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/firefox.cpp @@ -0,0 +1,166 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "firefox.h" +#include +#include +#include +#include "bookmarksrunner_defs.h" +#include +#include +#include +#include +#include "bookmarkmatch.h" +#include "favicon.h" +#include "fetchsqlite.h" +#include "faviconfromblob.h" + +Firefox::Firefox(QObject *parent) : + QObject(parent), + m_favicon(new FallbackFavicon(this)), + m_fetchsqlite(0) +{ + reloadConfiguration(); + kDebug(kdbg_code) << "Loading Firefox Bookmarks Browser"; +} + + +Firefox::~Firefox() +{ + if (!m_dbCacheFile.isEmpty()) { + QFile db_CacheFile(m_dbCacheFile); + if (db_CacheFile.exists()) { + kDebug(kdbg_code) << "Cache file was removed: " << db_CacheFile.remove(); + } + } + kDebug(kdbg_code) << "Deleted Firefox Bookmarks Browser"; +} + +void Firefox::prepare() +{ + if (m_dbCacheFile.isEmpty()) { + m_dbCacheFile = KStandardDirs::locateLocal("cache", "") + "bookmarkrunnerfirefoxdbfile.sqlite"; + } + if (!m_dbFile.isEmpty()) { + m_fetchsqlite = new FetchSqlite(m_dbFile, m_dbCacheFile); + m_fetchsqlite->prepare(); + + delete m_favicon; + m_favicon = 0; + + m_favicon = FaviconFromBlob::firefox(m_fetchsqlite, this); + } +} + +QList< BookmarkMatch > Firefox::match(const QString& term, bool addEverything) +{ + QList< BookmarkMatch > matches; + if (!m_fetchsqlite) { + return matches; + } + kDebug(kdbg_code) << "Firefox bookmark: match " << term; + + QString tmpTerm = term; + QString query; + if (addEverything) { + query = QString("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url," \ + "moz_places.favicon_id FROM moz_bookmarks, moz_places WHERE " \ + "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id"); + } else { + const QString escapedTerm = tmpTerm.replace('\'', "\\'"); + query = QString("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url," \ + "moz_places.favicon_id FROM moz_bookmarks, moz_places WHERE " \ + "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id AND " \ + "(moz_bookmarks.title LIKE '%" + escapedTerm + "%' or moz_places.url LIKE '%" + + escapedTerm + "%')"); + } + QList results = m_fetchsqlite->query(query, QMap()); + foreach(QVariantMap result, results) { + const QString title = result.value("title").toString(); + const QUrl url = result.value("url").toUrl(); + if (url.scheme().contains("place")) { + //Don't use bookmarks with empty title, url or Firefox intern url + kDebug(kdbg_code) << "element " << url << " was not added"; + continue; + } + + BookmarkMatch bookmarkMatch( m_favicon, term, title, url.toString()); + bookmarkMatch.addTo(matches, addEverything); + } + + return matches; +} + + +void Firefox::teardown() +{ + if(m_fetchsqlite) { + m_fetchsqlite->teardown(); + delete m_favicon; + m_favicon = 0; + } +} + + + +void Firefox::reloadConfiguration() +{ + KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), QLatin1String("General") ); + if (QSqlDatabase::isDriverAvailable("QSQLITE")) { + KConfigGroup grp = config; + /* This allows the user to specify a profile database */ + m_dbFile = grp.readEntry("dbfile", ""); + if (m_dbFile.isEmpty() || QFile::exists(m_dbFile)) { + //Try to get the right database file, the default profile is used + KConfig firefoxProfile(QDir::homePath() + "/.mozilla/firefox/profiles.ini", + KConfig::SimpleConfig); + QStringList profilesList = firefoxProfile.groupList(); + profilesList = profilesList.filter(QRegExp("^Profile\\d+$")); + int size = profilesList.size(); + + QString profilePath; + if (size == 1) { + // There is only 1 profile so we select it + KConfigGroup fGrp = firefoxProfile.group(profilesList.first()); + profilePath = fGrp.readEntry("Path", ""); + } else { + // There are multiple profiles, find the default one + foreach(const QString & profileName, profilesList) { + KConfigGroup fGrp = firefoxProfile.group(profileName); + if (fGrp.readEntry("Default", 0)) { + profilePath = fGrp.readEntry("Path", ""); + break; + } + } + } + + if (profilePath.isEmpty()) { + kDebug(kdbg_code) << "No default firefox profile found"; + return; + } + kDebug(kdbg_code) << "Profile " << profilePath << " found"; + profilePath.prepend(QString("%1/.mozilla/firefox/").arg(QDir::homePath())); + m_dbFile = profilePath + "/places.sqlite"; + grp.writeEntry("dbfile", m_dbFile); + } + } else { + kDebug(kdbg_code) << "SQLITE driver isn't available"; + } +} diff --git a/plasma/generic/runners/bookmarks/browsers/firefox.h b/plasma/generic/runners/bookmarks/browsers/firefox.h new file mode 100644 index 00000000..551954a1 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/firefox.h @@ -0,0 +1,48 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FIREFOX_H +#define FIREFOX_H + +#include +#include "browser.h" + +class KJob; +class Favicon; +class FetchSqlite; +class Firefox : public QObject, public Browser +{ + Q_OBJECT +public: + explicit Firefox(QObject *parent = 0); + virtual ~Firefox(); + virtual QList match(const QString& term, bool addEverything); +public slots: + virtual void teardown(); + virtual void prepare(); +private: + virtual void reloadConfiguration(); + QString m_dbFile; + QString m_dbCacheFile; + Favicon * m_favicon; + FetchSqlite *m_fetchsqlite; +}; + +#endif // FIREFOX_H diff --git a/plasma/generic/runners/bookmarks/browsers/kdebrowser.cpp b/plasma/generic/runners/bookmarks/browsers/kdebrowser.cpp new file mode 100644 index 00000000..ff329096 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/kdebrowser.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdebrowser.h" +#include +#include +#include +#include "bookmarkmatch.h" +#include +#include +#include "favicon.h" + + +QIcon KDEFavicon::iconFor(const QString &url) { + const QString iconFile = KMimeType::favIconForUrl(KUrl(url)); + if (iconFile.isEmpty()) { + return defaultIcon(); + } + return KIcon(iconFile); +} + + +KDEFavicon::KDEFavicon(QObject *parent) : Favicon(parent) {} + + +KDEBrowser::KDEBrowser(QObject *parent) : + QObject(parent), m_bookmarkManager(KBookmarkManager::userBookmarksManager()), m_favicon(new KDEFavicon(this)) +{ +} + + +QList< BookmarkMatch > KDEBrowser::match(const QString& term, bool addEverything) +{ + KBookmarkGroup bookmarkGroup = m_bookmarkManager->root(); + + QList< BookmarkMatch > matches; + QStack groups; + + KBookmark bookmark = bookmarkGroup.first(); + while (!bookmark.isNull()) { +// if (!context.isValid()) { +// return; +// } TODO: restore? + + if (bookmark.isSeparator()) { + bookmark = bookmarkGroup.next(bookmark); + continue; + } + + if (bookmark.isGroup()) { // descend + //kDebug (kdbg_code) << "descending into" << bookmark.text(); + groups.push(bookmarkGroup); + bookmarkGroup = bookmark.toGroup(); + bookmark = bookmarkGroup.first(); + + while (bookmark.isNull() && !groups.isEmpty()) { +// if (!context.isValid()) { +// return; +// } TODO: restore? + + bookmark = bookmarkGroup; + bookmarkGroup = groups.pop(); + bookmark = bookmarkGroup.next(bookmark); + } + + continue; + } + + BookmarkMatch bookmarkMatch(m_favicon, term, bookmark.text(), bookmark.url().url() ); + bookmarkMatch.addTo(matches, addEverything); + + bookmark = bookmarkGroup.next(bookmark); + while (bookmark.isNull() && !groups.isEmpty()) { +// if (!context.isValid()) { +// return; +// } // TODO: restore? + + bookmark = bookmarkGroup; + bookmarkGroup = groups.pop(); + //kDebug(kdbg_code) << "ascending from" << bookmark.text() << "to" << bookmarkGroup.text(); + bookmark = bookmarkGroup.next(bookmark); + } + } + return matches; +} + diff --git a/plasma/generic/runners/bookmarks/browsers/kdebrowser.h b/plasma/generic/runners/bookmarks/browsers/kdebrowser.h new file mode 100644 index 00000000..c23f3610 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/kdebrowser.h @@ -0,0 +1,52 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDEBROWSER_H +#define KDEBROWSER_H + +#include "browser.h" +#include "favicon.h" +class KBookmarkManager; +class Favicon; + +class KDEFavicon : public Favicon { + Q_OBJECT +public: + KDEFavicon(QObject *parent = 0); + virtual QIcon iconFor(const QString &url); + +}; + +class KDEBrowser : public QObject, public Browser +{ + Q_OBJECT +public: + explicit KDEBrowser(QObject *parent = 0); + virtual QList match(const QString& term, bool addEverything); + +public Q_SLOTS: + virtual void teardown() {} + +private: + KBookmarkManager * const m_bookmarkManager; + Favicon * const m_favicon; +}; + +#endif // KDEBROWSER_H diff --git a/plasma/generic/runners/bookmarks/browsers/opera.cpp b/plasma/generic/runners/bookmarks/browsers/opera.cpp new file mode 100644 index 00000000..965b051a --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/opera.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "opera.h" +#include +#include "bookmarksrunner_defs.h" +#include +#include +#include "favicon.h" + + +Opera::Opera(QObject* parent): QObject(parent), m_favicon(new FallbackFavicon(this)) +{ +} + +QList Opera::match( const QString& term, bool addEverything ) +{ + QList matches; + + QLatin1String nameStart("\tNAME="); + QLatin1String urlStart("\tURL="); + QLatin1String descriptionStart("\tDESCRIPTION="); + + // search + foreach (const QString & entry, m_operaBookmarkEntries) { + QStringList entryLines = entry.split("\n"); + if (!entryLines.first().startsWith(QString("#URL"))) { + continue; // skip folder entries + } + entryLines.pop_front(); + + QString name; + QString url; + QString description; + + foreach (const QString & line, entryLines) { + if (line.startsWith(nameStart)) { + name = line.mid( QString(nameStart).length() ).simplified(); + } else if (line.startsWith(urlStart)) { + url = line.mid( QString(urlStart).length() ).simplified(); + } else if (line.startsWith(descriptionStart)) { + description = line.mid(QString(descriptionStart).length()) + .simplified(); + } + } + + BookmarkMatch bookmarkMatch(m_favicon, term, name, url, description); + bookmarkMatch.addTo(matches, addEverything); + } + return matches; +} + + +void Opera::prepare() +{ + // open bookmarks file + QString operaBookmarksFilePath = QDir::homePath() + "/.opera/bookmarks.adr"; + QFile operaBookmarksFile(operaBookmarksFilePath); + if (!operaBookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + kDebug(kdbg_code) << "Could not open Operas Bookmark File " + operaBookmarksFilePath; + return; + } + + // check format + QString firstLine = operaBookmarksFile.readLine(); + if (firstLine.compare("Opera Hotlist version 2.0\n")) { + kDebug(kdbg_code) << "Format of Opera Bookmarks File might have changed."; + } + operaBookmarksFile.readLine(); // skip options line ("Options: encoding = utf8, version=3") + operaBookmarksFile.readLine(); // skip empty line + + // load contents + QString contents = operaBookmarksFile.readAll(); + m_operaBookmarkEntries = contents.split("\n\n", QString::SkipEmptyParts); + + // close file + operaBookmarksFile.close(); +} + +void Opera::teardown() +{ + m_operaBookmarkEntries.clear(); +} + diff --git a/plasma/generic/runners/bookmarks/browsers/opera.h b/plasma/generic/runners/bookmarks/browsers/opera.h new file mode 100644 index 00000000..f5fa4074 --- /dev/null +++ b/plasma/generic/runners/bookmarks/browsers/opera.h @@ -0,0 +1,45 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + + +#ifndef OPERA_H +#define OPERA_H + +#include "browser.h" +#include + +class Favicon; + +class Opera : public QObject, public Browser +{ +Q_OBJECT +public: + Opera(QObject* parent = 0); + virtual QList match(const QString& term, bool addEverything); +public slots: + virtual void prepare(); + virtual void teardown(); +private: + QStringList m_operaBookmarkEntries; + Favicon * const m_favicon; +}; + +#endif // OPERA_H diff --git a/plasma/generic/runners/bookmarks/favicon.cpp b/plasma/generic/runners/bookmarks/favicon.cpp new file mode 100644 index 00000000..0fee8bc0 --- /dev/null +++ b/plasma/generic/runners/bookmarks/favicon.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "favicon.h" + +Favicon::Favicon(QObject *parent) : + QObject(parent), m_default_icon(KIcon("bookmarks")) +{ +} diff --git a/plasma/generic/runners/bookmarks/favicon.h b/plasma/generic/runners/bookmarks/favicon.h new file mode 100644 index 00000000..3cc42620 --- /dev/null +++ b/plasma/generic/runners/bookmarks/favicon.h @@ -0,0 +1,55 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef FAVICON_H +#define FAVICON_H + +#include +#include + +class Favicon : public QObject +{ + Q_OBJECT +public: + explicit Favicon(QObject *parent = 0); + virtual QIcon iconFor(const QString &url) = 0; + +protected: + inline KIcon defaultIcon() const { return m_default_icon; } +private: + KIcon const m_default_icon; + +public slots: + virtual void prepare() {} + virtual void teardown() {} + +}; + + +class FallbackFavicon : public Favicon { + Q_OBJECT +public: + FallbackFavicon(QObject *parent = 0) : Favicon(parent) {} + virtual QIcon iconFor(const QString &) { return defaultIcon(); } +}; + + +#endif // FAVICON_H diff --git a/plasma/generic/runners/bookmarks/faviconfromblob.cpp b/plasma/generic/runners/bookmarks/faviconfromblob.cpp new file mode 100644 index 00000000..dc0010eb --- /dev/null +++ b/plasma/generic/runners/bookmarks/faviconfromblob.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "faviconfromblob.h" + +#include +#include +#include +#include +#include +#include +#include +#include "bookmarksrunner_defs.h" +#include "fetchsqlite.h" + +#include +#include +#include +#include + +#define dbFileName m_profileCacheDirectory + QDir::separator() + "Favicons.sqlite" + + +class StaticQuery : public BuildQuery { +public: + StaticQuery(const QString &query) : m_query(query) {} + virtual QString query(QSqlDatabase *database) const { + Q_UNUSED(database); + return m_query; + } +private: + const QString m_query; +}; + +class ChromeQuery : public BuildQuery { +public: + ChromeQuery() {} + virtual QString query(QSqlDatabase *database) const { + kDebug(kdbg_code) << "tables: " << database->tables(); + if(database->tables().contains("favicon_bitmaps")) + return "SELECT * FROM favicons " \ + "inner join icon_mapping on icon_mapping.icon_id = favicons.id " \ + "inner join favicon_bitmaps on icon_mapping.icon_id = favicon_bitmaps.icon_id " \ + "WHERE page_url = :url ORDER BY height desc LIMIT 1;"; + return "SELECT * FROM favicons inner join icon_mapping " \ + "on icon_mapping.icon_id = favicons.id " \ + "WHERE page_url = :url LIMIT 1;"; + } +}; + +FaviconFromBlob *FaviconFromBlob::chrome(const QString &profileDirectory, QObject *parent) +{ + QString profileName = QFileInfo(profileDirectory).fileName(); + QString faviconCache = QString("%1/KRunner-Chrome-Favicons-%2.sqlite") + .arg(KStandardDirs::locateLocal("cache", "")) + .arg(profileName); + FetchSqlite *fetchSqlite = new FetchSqlite(profileDirectory + "/Favicons", faviconCache, parent); + return new FaviconFromBlob(profileName, new ChromeQuery(), "image_data", fetchSqlite, parent); +} + +FaviconFromBlob *FaviconFromBlob::firefox(FetchSqlite *fetchSqlite, QObject *parent) +{ + + QString faviconQuery = QString("SELECT moz_favicons.data FROM moz_favicons" \ + " inner join moz_places ON moz_places.favicon_id = moz_favicons.id" \ + " WHERE moz_places.url = :url LIMIT 1;"); + return new FaviconFromBlob("firefox-default", new StaticQuery(faviconQuery), "data", fetchSqlite, parent); +} + + +FaviconFromBlob::FaviconFromBlob(const QString &profileName, BuildQuery *buildQuery, const QString &blobColumn, FetchSqlite *fetchSqlite, QObject *parent) + : Favicon(parent), m_buildQuery(buildQuery), m_blobcolumn(blobColumn), m_fetchsqlite(fetchSqlite) +{ + m_profileCacheDirectory = QString("%1/KRunner-Favicons-%2") + .arg(KStandardDirs::locateLocal("cache", "")) + .arg(profileName); + kDebug(kdbg_code) << "got cache directory: " << m_profileCacheDirectory; + cleanCacheDirectory(); + QDir().mkpath(m_profileCacheDirectory); +} + +FaviconFromBlob::~FaviconFromBlob() +{ + cleanCacheDirectory(); + delete m_buildQuery; +} + +void FaviconFromBlob::prepare() +{ + m_fetchsqlite->prepare(); +} + +void FaviconFromBlob::teardown() +{ + m_fetchsqlite->teardown(); +} + +void FaviconFromBlob::cleanCacheDirectory() +{ + foreach(QFileInfo file, QDir(m_profileCacheDirectory).entryInfoList(QDir::NoDotAndDotDot)) { + kDebug(kdbg_code) << "Removing file " << file.absoluteFilePath() << ": " << + QFile(file.absoluteFilePath()).remove(); + } + QDir().rmdir(m_profileCacheDirectory); +} + +QIcon FaviconFromBlob::iconFor(const QString &url) +{ + kDebug(kdbg_code) << "got url: " << url; + QString fileChecksum = QString("%1").arg(qChecksum(url.toAscii(), url.toAscii().size())); + QFile iconFile( m_profileCacheDirectory + QDir::separator() + fileChecksum + "_favicon" ); + if(iconFile.size() == 0) + iconFile.remove(); + if(!iconFile.exists()) { + QMap bindVariables; + bindVariables.insert("url", url); + QList faviconFound = m_fetchsqlite->query(m_buildQuery, bindVariables); + if(faviconFound.isEmpty()) return defaultIcon(); + + QByteArray iconData = faviconFound.first().value(m_blobcolumn).toByteArray(); + kDebug(kdbg_code) << "Favicon found: " << iconData.size() << " bytes"; + if(iconData.size() <=0) + return defaultIcon(); + + iconFile.open(QFile::WriteOnly); + iconFile.write(iconData); + iconFile.close(); + } + return QIcon(iconFile.fileName()); +} + diff --git a/plasma/generic/runners/bookmarks/faviconfromblob.h b/plasma/generic/runners/bookmarks/faviconfromblob.h new file mode 100644 index 00000000..df520933 --- /dev/null +++ b/plasma/generic/runners/bookmarks/faviconfromblob.h @@ -0,0 +1,50 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef CHROMEFAVICON_H +#define CHROMEFAVICON_H + +#include +#include "favicon.h" +#include "fetchsqlite.h" + +class FaviconFromBlob : public Favicon +{ + Q_OBJECT +public: + static FaviconFromBlob *chrome(const QString &profileDirectory, QObject *parent = 0); + static FaviconFromBlob *firefox(FetchSqlite *fetchSqlite, QObject *parent = 0); + ~FaviconFromBlob(); + virtual QIcon iconFor(const QString &url); + +public slots: + virtual void prepare(); + virtual void teardown(); + +private: + FaviconFromBlob(const QString &profileName, BuildQuery *buildQuery, const QString &blobColumn, FetchSqlite *fetchSqlite, QObject *parent = 0); + QString m_profileCacheDirectory; + BuildQuery *m_buildQuery; + QString const m_blobcolumn; + FetchSqlite *m_fetchsqlite; + void cleanCacheDirectory(); +}; + +#endif // CHROMEFAVICON_H diff --git a/plasma/generic/runners/bookmarks/fetchsqlite.cpp b/plasma/generic/runners/bookmarks/fetchsqlite.cpp new file mode 100644 index 00000000..c732d873 --- /dev/null +++ b/plasma/generic/runners/bookmarks/fetchsqlite.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "fetchsqlite.h" +#include +#include +#include "bookmarksrunner_defs.h" +#include +#include +#include + +FetchSqlite::FetchSqlite(const QString &originalFilePath, const QString ©To, QObject *parent) : + QObject(parent), m_databaseFile(copyTo) +{ + m_db = QSqlDatabase::addDatabase("QSQLITE", originalFilePath); + m_db.setHostName("localhost"); + + QFile originalFile(originalFilePath); + QFile(copyTo).remove(); + bool couldCopy = originalFile.copy(copyTo); + if(!couldCopy) { + kDebug(kdbg_code) << "error copying favicon database from " << originalFile.fileName() << " to " << copyTo; + kDebug(kdbg_code) << originalFile.errorString(); + } +} + +FetchSqlite::~FetchSqlite() +{ + if(m_db.isOpen()) m_db.close(); + QFile(m_databaseFile).remove(); +} + +void FetchSqlite::prepare() +{ + m_db.setDatabaseName(m_databaseFile); + bool ok = m_db.open(); + kDebug(kdbg_code) << "Sqlite Database " << m_databaseFile << " was opened: " << ok; + if(!ok) { + kDebug(kdbg_code) << "Error: " << m_db.lastError().text(); + } +} + +void FetchSqlite::teardown() +{ + m_db.close(); +} + +QList FetchSqlite::query(BuildQuery *buildQuery, QMap bindObjects) +{ + return query(buildQuery->query(&m_db), bindObjects); +} + +QList FetchSqlite::query(const QString &sql, QMap bindObjects) +{ + kDebug(kdbg_code) << "query: " << sql; + QSqlQuery query(m_db); + query.prepare(sql); + foreach(const QString &variableName, bindObjects.keys()) { + query.bindValue(variableName, bindObjects.value(variableName)); + kDebug(kdbg_code) << "* Bound " << variableName << " to " << query.boundValue(variableName); + } + + if(!query.exec()) { + QSqlError error = m_db.lastError(); + kDebug(kdbg_code) << "query failed: " << error.text() << " (" << error.type() << ", " << error.number() << ")"; + kDebug(kdbg_code) << query.lastQuery(); + } + + QList result; + while(query.next()) { + QVariantMap recordValues; + QSqlRecord record = query.record(); + for(int field=0; field + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FETCHSQLITE_H +#define FETCHSQLITE_H +#include +#include +#include + +#include +#include + +#include + + +class BuildQuery { +public: + virtual QString query(QSqlDatabase *database) const = 0; + virtual ~BuildQuery() {} +}; + +class FetchSqlite : public QObject +{ + Q_OBJECT +public: + explicit FetchSqlite(const QString &originalFile, const QString ©To, QObject *parent = 0); + ~FetchSqlite(); + void prepare(); + void teardown(); + QList query(const QString &sql, QMap bindObjects); + QList query(BuildQuery *buildQuery, QMap bindObjects); + QList query(const QString &sql); + +private: + QString const m_databaseFile; + QSqlDatabase m_db; +}; + +#endif // FETCHSQLITE_H diff --git a/plasma/generic/runners/bookmarks/plasma-runner-bookmarks.desktop b/plasma/generic/runners/bookmarks/plasma-runner-bookmarks.desktop new file mode 100644 index 00000000..f3c0231c --- /dev/null +++ b/plasma/generic/runners/bookmarks/plasma-runner-bookmarks.desktop @@ -0,0 +1,160 @@ +[Desktop Entry] +# ctxt: plasma runner +Name=Bookmarks +Name[ar]=العلامات +Name[ast]=Marcadores +Name[bg]=Отметки +Name[bn]=বুকমার্ক +Name[bs]=Zabilješke +Name[ca]=Adreces d'interès +Name[ca@valencia]=Adreces d'interés +Name[cs]=Záložky +Name[csb]=Załóżczi +Name[da]=Bogmærker +Name[de]=Lesezeichen +Name[el]=Σελιδοδείκτες +Name[en_GB]=Bookmarks +Name[eo]=Legosignoj +Name[es]=Marcadores +Name[et]=Järjehoidjad +Name[eu]=Laster-markak +Name[fi]=Kirjanmerkit +Name[fr]=Signets +Name[fy]=Blêdwizers +Name[ga]=Leabharmharcanna +Name[gl]=Marcadores +Name[gu]=બુકમાર્કો +Name[he]=סימניות +Name[hi]=पसंदीदा +Name[hr]=Oznake +Name[hu]=Könyvjelzők +Name[ia]=Marcatores de libro +Name[id]=Penanda +Name[is]=Bókamerki +Name[it]=Segnalibri +Name[ja]=ブックマーク +Name[kk]=Бетбелгілер +Name[km]=ចំណាំ​ +Name[kn]=ಅಂಕನಗಳು (ಬುಕ್ ಮಾರ್ಕ್) +Name[ko]=책갈피 +Name[lt]=Žymelės +Name[lv]=Grāmatzīmes +Name[mk]=Обележувачи +Name[ml]=അടയാളക്കുറിപ്പുകള്‍ +Name[mr]=ओळखचिन्ह +Name[nb]=Bokmerker +Name[nds]=Leestekens +Name[nl]=Bladwijzers +Name[nn]=Bokmerke +Name[pa]=ਬੁੱਕਮਾਰਕ +Name[pl]=Zakładki +Name[pt]=Favoritos +Name[pt_BR]=Favoritos +Name[ro]=Semne de carte +Name[ru]=Закладки +Name[si]=පොත්සලකුණු +Name[sk]=Záložky +Name[sl]=Zaznamki +Name[sr]=обележивачи +Name[sr@ijekavian]=обележивачи +Name[sr@ijekavianlatin]=obeleživači +Name[sr@latin]=obeleživači +Name[sv]=Bokmärken +Name[tg]=Хатчӯбмонӣ +Name[th]=ที่คั่นหน้า +Name[tr]=Yer İmleri +Name[ug]=خەتكۈشلەر +Name[uk]=Закладки +Name[vi]=Dấu trang +Name[wa]=Rimarkes +Name[x-test]=xxBookmarksxx +Name[zh_CN]=书签 +Name[zh_TW]=書籤 +Comment=Find and open bookmarks +Comment[ar]=اعثر على وافتح علامات +Comment[ast]=Guetar y abrir marcadores +Comment[be@latin]=Pošuk i adčynieńnie zakładak. +Comment[bg]=Търсене и зареждане на отметки +Comment[bn]=বুকমার্ক খোঁজো এবং খোলো +Comment[bn_IN]=বুকমার্ক অনুসন্ধান করুন ও খুলুন +Comment[bs]=Nađite i otvorite zabilješku +Comment[ca]=Cerca i obre adreces d'interès +Comment[ca@valencia]=Cerca i obri adreces d'interés +Comment[cs]=Najít a otevřít záložku +Comment[csb]=Malézë ë òtemkni załóżczi +Comment[da]=Find og åbn bogmærker +Comment[de]=Lesezeichen finden und aufrufen +Comment[el]=Αναζήτηση και άνοιγμα σελιδοδεικτών +Comment[en_GB]=Find and open bookmarks +Comment[eo]=Trovi kaj malfermi legosignon +Comment[es]=Buscar y abrir marcadores +Comment[et]=Järjehoidjate otsimine ja avamine +Comment[eu]=Bilatu eta ireki laster-markak +Comment[fi]=Etsi ja avaa kirjanmerkkejä +Comment[fr]=Trouver et ouvrir les signets +Comment[fy]=Sykje en iepenje blêdwizers +Comment[ga]=Aimsigh agus oscail leabharmharcanna +Comment[gl]=Busca e abre marcadores +Comment[gu]=બુકમાર્ક્સ શોધો અને ખોલો +Comment[he]=חיפוש ופתיחת סימניות +Comment[hi]=पसंदीदा ढूंढें व खोलें +Comment[hne]=निसानी खोजो अउ खोलो +Comment[hr]=Pronađi i otvori oznake +Comment[hu]=Könyvjelzőmegnyitó +Comment[ia]=Trova e aperi marcatores de libro +Comment[id]=Cari dan buka penanda +Comment[is]=Finna og opna bókamerki +Comment[it]=Trova e apri segnalibri +Comment[ja]=ブックマークを探して開きます +Comment[kk]=Бетбелгілерді тауып ашу +Comment[km]=រក​ និង​បើក​ចំណាំ +Comment[kn]=ಅಂಕನಗಳನ್ನು (ಬುಕ್ ಮಾರ್ಕ್) ಹುಡುಕಿ ತೆರೆ +Comment[ko]=책갈피를 탐색하고 열기 +Comment[ku]=Bijareyan bibîne û veke +Comment[lt]=Rasti ir atverti žymelę +Comment[lv]=Meklēt un atvērt grāmatzīmes +Comment[mk]=Пронајдете и отворете обележувачи +Comment[ml]=അടയാളക്കുറിപ്പുകള്‍ കണ്ടെത്തി തുറക്കുക +Comment[mr]=ओळखचिन्ह शोधा व उघडा +Comment[nb]=Søk etter og åpne bokmerker +Comment[nds]=Leestekens söken un opmaken +Comment[nl]=Bladwijzers vinden en openen +Comment[nn]=Finn og opna bokmerke +Comment[or]=ଚିହ୍ନିତ ସ୍ଥାନଗୁଡ଼ିକୁ ଖୋଜନ୍ତୁ ଏବଂ ଖୋଲନ୍ତୁ +Comment[pa]=ਬੁੱਕਮਾਰਕ ਖੋਜੋ ਅਤੇ ਖੋਲ੍ਹੋ +Comment[pl]=Znajdowanie i otwieranie zakładek +Comment[pt]=Descobrir e abrir os favoritos +Comment[pt_BR]=Localiza e abre favoritos +Comment[ro]=Caută și deschide semne de carte +Comment[ru]=Закладки +Comment[si]=පොත්සලකුණු සොයා විවෘත කරන්න +Comment[sk]=Nájsť a otvoriť záložky +Comment[sl]=Najdi in odpri zaznamke +Comment[sr]=Нађите и отворите обележивач +Comment[sr@ijekavian]=Нађите и отворите обиљеживач +Comment[sr@ijekavianlatin]=Nađite i otvorite obilježivač +Comment[sr@latin]=Nađite i otvorite obeleživač +Comment[sv]=Sök efter och öppna bokmärken +Comment[ta]=Find and open bookmarks +Comment[te]=పేజిగుర్తులను కనుగొనుము మరియు తెరువుము +Comment[tg]=Ҷустуҷӯи замимаҳо +Comment[th]=ค้นหาและเปิดคั่นหน้า +Comment[tr]=Yer imlerini bul ve aç +Comment[ug]=خەتكۈشلەرنى ئىزدە ۋە ئاچ +Comment[uk]=Знайти і відкрити закладки +Comment[vi]=Tìm và mở đánh dấu trang +Comment[wa]=Trover eyet drovi des rmarkes +Comment[x-test]=xxFind and open bookmarksxx +Comment[zh_CN]=查找并打开书签 +Comment[zh_TW]=尋找並開啟書籤 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=bookmarks +X-KDE-Library=krunner_bookmarksrunner +X-KDE-PluginInfo-Author=Glenn Ergeerts, Marco Gulino +X-KDE-PluginInfo-Email=glenn.ergeerts@telenet.be, marco.gulino@gmail.com +X-KDE-PluginInfo-Name=bookmarks +X-KDE-PluginInfo-Version=1.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/bookmarks/tests/CMakeLists.txt b/plasma/generic/runners/bookmarks/tests/CMakeLists.txt new file mode 100644 index 00000000..1325ffdf --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/CMakeLists.txt @@ -0,0 +1,14 @@ +set( testChromeBookmarks_SRCS testchromebookmarks.cpp + ../browsers/chrome.cpp + ../faviconfromblob.cpp + ../browsers/chromefindprofile.cpp + ../bookmarkmatch.cpp + ../favicon.cpp + ../fetchsqlite.cpp +) +include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/.. ) +kde4_add_unit_test( testChromeBookmarks TESTNAME plasma-runner-bookmarks-TestChromeBookmarks ${testChromeBookmarks_SRCS} ) + +target_link_libraries( testChromeBookmarks ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY} ${QT_QTSQL_LIBRARY} ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} qjson) + +file(COPY chrome-config-home DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/plasma/generic/runners/bookmarks/tests/chrome-config-home/.config/chromium/Local State b/plasma/generic/runners/bookmarks/tests/chrome-config-home/.config/chromium/Local State new file mode 100644 index 00000000..711eaa90 --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/chrome-config-home/.config/chromium/Local State @@ -0,0 +1,65 @@ +{ + "browser": { + "last_redirect_origin": "" + }, + "local_state": { + "multiple_profile_prefs_version": 7 + }, + "ntp": { + "intro_display_count": 11, + "promo_locale": "en-US", + "promo_version": 7 + }, + "profile": { + "info_cache": { + "Default": { + "avatar_icon": "chrome://theme/IDR_PROFILE_AVATAR_0", + "background_apps": false, + "name": "First user", + "user_name": "" + }, + "Profile 1": { + "avatar_icon": "chrome://theme/IDR_PROFILE_AVATAR_14", + "background_apps": false, + "name": "Awesome", + "user_name": "" + } + }, + "last_used": "Default", + "profiles_created": 2 + }, + "show-first-run-bubble": false, + "shutdown": { + "num_processes": 3, + "num_processes_slow": 1, + "type": 1 + }, + "uninstall_metrics": { + "installation_date2": "1342779510", + "launch_count": "1" + }, + "user_experience_metrics": { + "session_id": 0, + "stability": { + "breakpad_registration_fail": 1, + "breakpad_registration_ok": 0, + "crash_count": 0, + "debugger_not_present": 1, + "debugger_present": 0, + "exited_cleanly": true, + "incomplete_session_end_count": 0, + "last_timestamp_sec": "1342779635", + "launch_count": 1, + "launch_time_sec": "1342779510", + "page_load_count": 0, + "renderer_crash_count": 0, + "renderer_hang_count": 0, + "session_end_completed": true, + "stats_buildtime": "1342149434", + "stats_version": "20.0.1132.47-64-devel" + } + }, + "was": { + "restarted": false + } +} diff --git a/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-Sample.json b/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-Sample.json new file mode 100644 index 00000000..092ac37d --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-Sample.json @@ -0,0 +1,55 @@ +{ + "checksum": "191d94e91bec51787ab07c82e94c396f", + "roots": { + "bookmark_bar": { + "children": [ { + "date_added": "12987182320843562", + "id": "4", + "name": "some bookmark in bookmark bar", + "type": "url", + "url": "http://somehost.com/" + } ], + "date_added": "12987182274941985", + "date_modified": "12987182320843562", + "id": "1", + "name": "Bookmarks Bar", + "type": "folder" + }, + "other": { + "children": [ { + "date_added": "12987182348211072", + "id": "5", + "name": "bookmark in other bookmarks", + "type": "url", + "url": "http://otherbookmarks.com/" + }, { + "children": [ { + "date_added": "12987182366305763", + "id": "7", + "name": "bookmark in somefolder", + "type": "url", + "url": "http://somefolder.com/" + } ], + "date_added": "12987182352136671", + "date_modified": "12987182366305763", + "id": "6", + "name": "somefolder", + "type": "folder" + } ], + "date_added": "12987182274941996", + "date_modified": "12987182348211072", + "id": "2", + "name": "Other Bookmarks", + "type": "folder" + }, + "synced": { + "children": [ ], + "date_added": "12987182274941997", + "date_modified": "0", + "id": "3", + "name": "Mobile Bookmarks", + "type": "folder" + } + }, + "version": 1 +} diff --git a/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-SecondProfile.json b/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-SecondProfile.json new file mode 100644 index 00000000..6087568f --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/chrome-config-home/Chrome-Bookmarks-SecondProfile.json @@ -0,0 +1,20 @@ +{ + "checksum": "191d94e91bec51787ab07c82e94c396f", + "roots": { + "bookmark_bar": { + "children": [ ], + "date_added": "12987182274941985", + "date_modified": "12987182320843562", + "id": "1", + "name": "Bookmarks Bar", + "type": "folder" + }, + "other": { + "children": [{ + "date_added": "12987182366305763", + "id": "7", + "name": "bookmark in secondProfile", + "type": "url", + "url": "http://secondprofile.com/" + } ] } } +} diff --git a/plasma/generic/runners/bookmarks/tests/testchromebookmarks.cpp b/plasma/generic/runners/bookmarks/tests/testchromebookmarks.cpp new file mode 100644 index 00000000..5c42eed9 --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/testchromebookmarks.cpp @@ -0,0 +1,125 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "testchromebookmarks.h" +#include +#include +#include "browsers/chrome.h" +#include "browsers/chromefindprofile.h" +#include "favicon.h" + +using namespace Plasma; + +FakeFindProfile findBookmarksInCurrentDirectory(QList() + << Profile("chrome-config-home/Chrome-Bookmarks-Sample.json", new FallbackFavicon())); + + +void TestChromeBookmarks::bookmarkFinderShouldFindEachProfileDirectory() +{ + FindChromeProfile findChrome("chromium", "./chrome-config-home"); + QString profileTemplate = QString("./chrome-config-home/.config/%1/%2/Bookmarks"); + + QList profiles = findChrome.find(); + QCOMPARE(profiles.size(), 2); + QCOMPARE(profiles[0].path(), profileTemplate.arg("chromium").arg("Default")); + QCOMPARE(profiles[1].path(), profileTemplate.arg("chromium").arg("Profile 1")); +} + +void TestChromeBookmarks::bookmarkFinderShouldReportNoProfilesOnErrors() +{ + FindChromeProfile findChrome("chromium", "./no-config-directory"); + + QList profiles = findChrome.find(); + QCOMPARE(profiles.size(), 0); +} + + +void TestChromeBookmarks::itShouldFindNothingWhenPrepareIsNotCalled() +{ + Chrome *chrome = new Chrome(&findBookmarksInCurrentDirectory, this); + QCOMPARE(chrome->match("any", true).size(), 0); +} + +void TestChromeBookmarks::itShouldGracefullyExitWhenFileIsNotFound() +{ + FakeFindProfile finder(QList() << Profile("FileNotExisting.json", NULL)); + Chrome *chrome = new Chrome(&finder, this); + chrome->prepare(); + QCOMPARE(chrome->match("any", true).size(), 0); +} + + +void verifyMatch(BookmarkMatch &match, const QString &title, const QString &url, qreal relevance, QueryMatch::Type type) { + QueryMatch queryMatch = match.asQueryMatch(NULL); + QCOMPARE(queryMatch.text(), title); + QCOMPARE(queryMatch.data().toString(), url); + QCOMPARE(queryMatch.relevance(), relevance); + QVERIFY2(queryMatch.type() == type, + QString("Wrong query match type: expecting %1 but was %2").arg(type).arg(queryMatch.type() ).toAscii()); +} + +void TestChromeBookmarks::itShouldFindAllBookmarks() +{ + Chrome *chrome = new Chrome(&findBookmarksInCurrentDirectory, this); + chrome->prepare(); + QList matches = chrome->match("any", true); + QCOMPARE(matches.size(), 3); + verifyMatch(matches[0], "some bookmark in bookmark bar", "http://somehost.com/", 0.18, QueryMatch::PossibleMatch); + verifyMatch(matches[1], "bookmark in other bookmarks", "http://otherbookmarks.com/", 0.18, QueryMatch::PossibleMatch); + verifyMatch(matches[2], "bookmark in somefolder", "http://somefolder.com/", 0.18, QueryMatch::PossibleMatch); +} + +void TestChromeBookmarks::itShouldFindOnlyMatches() +{ + Chrome *chrome = new Chrome(&findBookmarksInCurrentDirectory, this); + chrome->prepare(); + QList matches = chrome->match("other", false); + QCOMPARE(matches.size(), 1); + verifyMatch(matches[0], "bookmark in other bookmarks", "http://otherbookmarks.com/", 0.45, QueryMatch::PossibleMatch); +} + +void TestChromeBookmarks::itShouldClearResultAfterCallingTeardown() +{ + Chrome *chrome = new Chrome(&findBookmarksInCurrentDirectory, this); + chrome->prepare(); + QCOMPARE(chrome->match("any", true).size(), 3); + chrome->teardown(); + QCOMPARE(chrome->match("any", true).size(), 0); + +} + +void TestChromeBookmarks::itShouldFindBookmarksFromAllProfiles() +{ + FakeFindProfile findBookmarksFromAllProfiles(QList() + << Profile("chrome-config-home/Chrome-Bookmarks-Sample.json", new FallbackFavicon(this)) + << Profile("chrome-config-home/Chrome-Bookmarks-SecondProfile.json", new FallbackFavicon(this)) ); + Chrome *chrome = new Chrome(&findBookmarksFromAllProfiles, this); + chrome->prepare(); + QList matches = chrome->match("any", true); + QCOMPARE(matches.size(), 4); + verifyMatch(matches[0], "some bookmark in bookmark bar", "http://somehost.com/", 0.18, QueryMatch::PossibleMatch); + verifyMatch(matches[1], "bookmark in other bookmarks", "http://otherbookmarks.com/", 0.18, QueryMatch::PossibleMatch); + verifyMatch(matches[2], "bookmark in somefolder", "http://somefolder.com/", 0.18, QueryMatch::PossibleMatch); + verifyMatch(matches[3], "bookmark in secondProfile", "http://secondprofile.com/", 0.18, QueryMatch::PossibleMatch); +} + +#include "testchromebookmarks.moc" + +QTEST_MAIN(TestChromeBookmarks); diff --git a/plasma/generic/runners/bookmarks/tests/testchromebookmarks.h b/plasma/generic/runners/bookmarks/tests/testchromebookmarks.h new file mode 100644 index 00000000..12a77067 --- /dev/null +++ b/plasma/generic/runners/bookmarks/tests/testchromebookmarks.h @@ -0,0 +1,53 @@ +/* + * Copyright 2007 Glenn Ergeerts + * Copyright 2012 Glenn Ergeerts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef TESTCHROMEBOOKMARKS_H +#define TESTCHROMEBOOKMARKS_H + +#include +#include "browsers/findprofile.h" + +class FakeFindProfile : public FindProfile { +public: + FakeFindProfile(const QList &profiles) : m_profiles(profiles) {} + virtual QList find() { return m_profiles; } +private: + QList m_profiles; +}; + +class TestChromeBookmarks : public QObject +{ +Q_OBJECT +public: + explicit TestChromeBookmarks(QObject* parent = 0) : QObject(parent) {} +private slots: + void bookmarkFinderShouldFindEachProfileDirectory(); + void bookmarkFinderShouldReportNoProfilesOnErrors(); + void itShouldFindNothingWhenPrepareIsNotCalled(); + void itShouldGracefullyExitWhenFileIsNotFound(); + void itShouldFindAllBookmarks(); + void itShouldFindOnlyMatches(); + void itShouldClearResultAfterCallingTeardown(); + void itShouldFindBookmarksFromAllProfiles(); + +}; + +#endif // TESTCHROMEBOOKMARKS_H diff --git a/plasma/generic/runners/calculator/CMakeLists.txt b/plasma/generic/runners/calculator/CMakeLists.txt new file mode 100644 index 00000000..79e13705 --- /dev/null +++ b/plasma/generic/runners/calculator/CMakeLists.txt @@ -0,0 +1,35 @@ + +########### next target ############### + +macro_optional_find_package(Qalculate) +set_package_properties(Qalculate PROPERTIES DESCRIPTION "Qalculate Library" + URL "http://qalculate.sourceforge.net" + TYPE OPTIONAL + PURPOSE "Needed to enable advanced features of the calculator runner" + ) +if ( QALCULATE_FOUND ) + add_definitions(-DENABLE_QALCULATE) + + set(qalculate_engine_SRCS + qalculate_engine.cpp + ) + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -Wno-deprecated") +endif( QALCULATE_FOUND ) + +set(krunner_calculatorrunner_SRCS + calculatorrunner.cpp +) + +if ( QALCULATE_FOUND ) + kde4_add_plugin(krunner_calculatorrunner ${qalculate_engine_SRCS} ${krunner_calculatorrunner_SRCS}) + target_link_libraries(krunner_calculatorrunner ${QALCULATE_LIBRARIES} ${CLN_LIBRARIES} ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ) +else ( QALCULATE_FOUND ) + kde4_add_plugin(krunner_calculatorrunner ${krunner_calculatorrunner_SRCS}) + target_link_libraries(krunner_calculatorrunner ${KDE4_KDEUI_LIBS} ${QT_QTSCRIPT_LIBRARY} ${KDE4_PLASMA_LIBS}) +endif ( QALCULATE_FOUND ) + +install(TARGETS krunner_calculatorrunner DESTINATION ${PLUGIN_INSTALL_DIR} ) + +########### install files ############### +install(FILES plasma-runner-calculator.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/runners/calculator/Messages.sh b/plasma/generic/runners/calculator/Messages.sh new file mode 100755 index 00000000..fa74f055 --- /dev/null +++ b/plasma/generic/runners/calculator/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_calculatorrunner.pot diff --git a/plasma/generic/runners/calculator/calculatorrunner.cpp b/plasma/generic/runners/calculator/calculatorrunner.cpp new file mode 100644 index 00000000..cb911a83 --- /dev/null +++ b/plasma/generic/runners/calculator/calculatorrunner.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2007 Barış Metin + * Copyright (C) 2006 David Faure + * Copyright (C) 2007 Richard Moore + * Copyright (C) 2010 Matteo Agostinelli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "calculatorrunner.h" + +#ifdef ENABLE_QALCULATE +#include "qalculate_engine.h" +#else +#include +#endif + +#include +#include + +#include + +CalculatorRunner::CalculatorRunner( QObject* parent, const QVariantList &args ) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args) + + #ifdef ENABLE_QALCULATE + m_engine = new QalculateEngine; + setSpeed(SlowSpeed); + #endif + + setObjectName( QLatin1String("Calculator" )); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | + Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Executable | + Plasma::RunnerContext::ShellCommand); + + QString description = i18n("Calculates the value of :q: when :q: is made up of numbers and " + "mathematical symbols such as +, -, /, * and ^."); + addSyntax(Plasma::RunnerSyntax(":q:", description)); + addSyntax(Plasma::RunnerSyntax("=:q:", description)); + addSyntax(Plasma::RunnerSyntax(":q:=", description)); +} + +CalculatorRunner::~CalculatorRunner() +{ + #ifdef ENABLE_QALCULATE + delete m_engine; + #endif +} + +void CalculatorRunner::powSubstitutions(QString& cmd) +{ + if (cmd.contains("e+", Qt::CaseInsensitive)) { + cmd = cmd.replace("e+", "*10^", Qt::CaseInsensitive); + } + + if (cmd.contains("e-", Qt::CaseInsensitive)) { + cmd = cmd.replace("e-", "*10^-", Qt::CaseInsensitive); + } + + // the below code is scary mainly because we have to honor priority + // honor decimal numbers and parenthesis. + while (cmd.contains('^')) { + int where = cmd.indexOf('^'); + cmd = cmd.replace(where, 1, ','); + int preIndex = where - 1; + int postIndex = where + 1; + int count = 0; + + QChar decimalSymbol = KGlobal::locale()->decimalSymbol().at(0); + //avoid out of range on weird commands + preIndex = qMax(0, preIndex); + postIndex = qMin(postIndex, cmd.length()-1); + + //go backwards looking for the beginning of the number or expression + while (preIndex != 0) { + QChar current = cmd.at(preIndex); + QChar next = cmd.at(preIndex-1); + //kDebug() << "index " << preIndex << " char " << current; + if (current == ')') { + count++; + } else if (current == '(') { + count--; + } else { + if (((next <= '9' ) && (next >= '0')) || next == decimalSymbol) { + preIndex--; + continue; + } + } + if (count == 0) { + //check for functions + if (!((next <= 'z' ) && (next >= 'a'))) { + break; + } + } + preIndex--; + } + + //go forwards looking for the end of the number or expression + count = 0; + while (postIndex != cmd.size() - 1) { + QChar current=cmd.at(postIndex); + QChar next=cmd.at(postIndex + 1); + + //check for functions + if ((count == 0) && (current <= 'z') && (current >= 'a')) { + postIndex++; + continue; + } + + if (current == '(') { + count++; + } else if (current == ')') { + count--; + } else { + if (((next <= '9' ) && (next >= '0')) || next == decimalSymbol) { + postIndex++; + continue; + } + } + if (count == 0) { + break; + } + postIndex++; + } + + preIndex = qMax(0, preIndex); + postIndex = qMin(postIndex, cmd.length()); + + cmd.insert(preIndex,"pow("); + // +1 +4 == next position to the last number after we add 4 new characters pow( + cmd.insert(postIndex + 1 + 4, ')'); + //kDebug() << "from" << preIndex << " to " << postIndex << " got: " << cmd; + } +} + +void CalculatorRunner::hexSubstitutions(QString& cmd) +{ + if (cmd.contains("0x")) { + //Append +0 so that the calculator can serve also as a hex converter + cmd.append("+0"); + bool ok; + int pos = 0; + QString hex; + + while (cmd.contains("0x")) { + hex.clear(); + pos = cmd.indexOf("0x", pos); + + for (int q = 0; q < cmd.size(); q++) {//find end of hex number + QChar current = cmd[pos+q+2]; + if (((current <= '9' ) && (current >= '0')) || ((current <= 'F' ) && (current >= 'A')) || ((current <= 'f' ) && (current >= 'a'))) { //Check if valid hex sign + hex[q] = current; + } else { + break; + } + } + cmd = cmd.replace(pos, 2+hex.length(), QString::number(hex.toInt(&ok,16))); //replace hex with decimal + } + } +} + +void CalculatorRunner::userFriendlySubstitutions(QString& cmd) +{ + if (cmd.contains(KGlobal::locale()->decimalSymbol(), Qt::CaseInsensitive)) { + cmd=cmd.replace(KGlobal::locale()->decimalSymbol(), QChar('.'), Qt::CaseInsensitive); + } + + // the following substitutions are not needed with libqalculate + #ifndef ENABLE_QALCULATE + hexSubstitutions(cmd); + powSubstitutions(cmd); + + if (cmd.contains(QRegExp("\\d+and\\d+"))) { + cmd = cmd.replace(QRegExp("(\\d+)and(\\d+)"), "\\1&\\2"); + } + if (cmd.contains(QRegExp("\\d+or\\d+"))) { + cmd = cmd.replace(QRegExp("(\\d+)or(\\d+)"), "\\1|\\2"); + } + if (cmd.contains(QRegExp("\\d+xor\\d+"))) { + cmd = cmd.replace(QRegExp("(\\d+)xor(\\d+)"), "\\1^\\2"); + } + #endif +} + + +void CalculatorRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + QString cmd = term; + + //no meanless space between friendly guys: helps simplify code + cmd = cmd.trimmed().remove(' '); + + if (cmd.length() < 3) { + return; + } + + if (cmd.toLower() == "universe" || cmd.toLower() == "life") { + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::InformationalMatch); + match.setIcon(KIcon("accessories-calculator")); + match.setText("42"); + match.setData("42"); + match.setId(term); + context.addMatch(term, match); + return; + } + + bool toHex = cmd.startsWith(QLatin1String("hex=")); + bool startsWithEquals = !toHex && cmd[0] == '='; + + if (toHex || startsWithEquals) { + cmd.remove(0, cmd.indexOf('=') + 1); + } else if (cmd.endsWith('=')) { + cmd.chop(1); + } else { + bool foundDigit = false; + for (int i = 0; i < cmd.length(); ++i) { + QChar c = cmd.at(i); + if (c.isLetter()) { + // not just numbers and symbols, so we return + return; + } + if (c.isDigit()) { + foundDigit = true; + } + } + if (!foundDigit) { + return; + } + } + + if (cmd.isEmpty()) { + return; + } + + userFriendlySubstitutions(cmd); + #ifndef ENABLE_QALCULATE + cmd.replace(QRegExp("([a-zA-Z]+)"), "Math.\\1"); //needed for accessing math funktions like sin(),.... + #endif + + QString result = calculate(cmd); + if (!result.isEmpty() && result != cmd) { + if (toHex) { + result = "0x" + QString::number(result.toInt(), 16).toUpper(); + } + + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::InformationalMatch); + match.setIcon(KIcon("accessories-calculator")); + match.setText(result); + match.setData(result); + match.setId(term); + context.addMatch(term, match); + } +} + +QString CalculatorRunner::calculate(const QString& term) +{ + #ifdef ENABLE_QALCULATE + QString result; + + try { + result = m_engine->evaluate(term); + } catch(std::exception& e) { + kDebug() << "qalculate error: " << e.what(); + } + + return result.replace('.', KGlobal::locale()->decimalSymbol(), Qt::CaseInsensitive); + #else + //kDebug() << "calculating" << term; + QScriptEngine eng; + QScriptValue result = eng.evaluate(" var result ="+term+"; result"); + + if (result.isError()) { + return QString(); + } + + const QString resultString = result.toString(); + if (resultString.isEmpty()) { + return QString(); + } + + if (!resultString.contains('.')) { + return resultString; + } + + //ECMAScript has issues with the last digit in simple rational computations + //This script rounds off the last digit; see bug 167986 + QString roundedResultString = eng.evaluate("var exponent = 14-(1+Math.floor(Math.log(Math.abs(result))/Math.log(10)));\ + var order=Math.pow(10,exponent);\ + (order > 0? Math.round(result*order)/order : 0)").toString(); + + roundedResultString.replace('.', KGlobal::locale()->decimalSymbol(), Qt::CaseInsensitive); + + return roundedResultString; + #endif +} + +QMimeData * CalculatorRunner::mimeDataForMatch(const Plasma::QueryMatch *match) +{ + //kDebug(); + QMimeData *result = new QMimeData(); + result->setText(match->text()); + return result; +} + +#include "calculatorrunner.moc" diff --git a/plasma/generic/runners/calculator/calculatorrunner.h b/plasma/generic/runners/calculator/calculatorrunner.h new file mode 100644 index 00000000..f01e5288 --- /dev/null +++ b/plasma/generic/runners/calculator/calculatorrunner.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007 Barış Metin + * Copyright (C) 2010 Matteo Agostinelli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef CALCULATORRUNNER_H +#define CALCULATORRUNNER_H + +#include + +#ifdef ENABLE_QALCULATE +class QalculateEngine; +#endif + +#include + +/** + * This class evaluates the basic expressions given in the interface. + */ +class CalculatorRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + CalculatorRunner(QObject* parent, const QVariantList &args); + ~CalculatorRunner(); + + void match(Plasma::RunnerContext &context); + + protected slots: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); + + private: + QString calculate(const QString& term); + void userFriendlySubstitutions(QString& cmd); + void powSubstitutions(QString& cmd); + void hexSubstitutions(QString& cmd); + + #ifdef ENABLE_QALCULATE + QalculateEngine* m_engine; + #endif +}; + +K_EXPORT_PLASMA_RUNNER(calculatorrunner, CalculatorRunner) + +#endif diff --git a/plasma/generic/runners/calculator/plasma-runner-calculator.desktop b/plasma/generic/runners/calculator/plasma-runner-calculator.desktop new file mode 100644 index 00000000..84956108 --- /dev/null +++ b/plasma/generic/runners/calculator/plasma-runner-calculator.desktop @@ -0,0 +1,171 @@ +[Desktop Entry] +Name=Calculator +Name[ar]=آلة حاسبة +Name[ast]=Calculadora +Name[be@latin]=Kalkulatar +Name[bg]=Калкулатор +Name[bn]=ক্যালকুলেটর +Name[bn_IN]=ক্যালকুলেটর +Name[bs]=kalkulator +Name[ca]=Calculadora +Name[ca@valencia]=Calculadora +Name[cs]=Kalkulátor +Name[csb]=Kalkùlator +Name[da]=Regnemaskine +Name[de]=Rechner +Name[el]=Αριθμομηχανή +Name[en_GB]=Calculator +Name[eo]=Kalkulilo +Name[es]=Calculadora +Name[et]=Kalkulaator +Name[eu]=Kalkulagailua +Name[fi]=Laskin +Name[fr]=Calculatrice +Name[fy]=Rekkenmasine +Name[ga]=Áireamhán +Name[gl]=Calculadora +Name[gu]=કેલ્ક્યુલેટર +Name[he]=מחשבון +Name[hi]=गणक +Name[hne]=केलकुलेटर +Name[hr]=Kalkulator +Name[hu]=Számológép +Name[ia]=Calculator +Name[id]=Kalkulator +Name[is]=Reiknivél +Name[it]=Calcolatrice +Name[ja]=計算機 +Name[kk]=Калькулятор +Name[km]=ម៉ាស៊ីន​គិត​លេខ +Name[kn]=ಲೆಕ್ಕಿಗ (ಕಾಲ್ಕುಲೇಟರ್) +Name[ko]=계산기 +Name[ku]=Makîneya Hesaban +Name[lt]=Skaičiuotuvas +Name[lv]=Kalkulators +Name[mai]=कैलकुलेटर +Name[mk]=Калкулатор +Name[ml]=കാല്‍ക്കുലേറ്റര്‍ +Name[mr]=गणनायंत्र +Name[nb]=Kalkulator +Name[nds]=Taschenreekner +Name[nl]=Rekenmachine +Name[nn]=Kalkulator +Name[or]=କାଲକୁଲେଟର +Name[pa]=ਕੈਲਕੂਲੇਟਰ +Name[pl]=Kalkulator +Name[pt]=Calculadora +Name[pt_BR]=Calculadora +Name[ro]=Calculator +Name[ru]=Калькулятор +Name[se]=Kalkuláhtor +Name[si]=ගණනය +Name[sk]=Kalkulačka +Name[sl]=Računalo +Name[sr]=калкулатор +Name[sr@ijekavian]=калкулатор +Name[sr@ijekavianlatin]=kalkulator +Name[sr@latin]=kalkulator +Name[sv]=Miniräknare +Name[ta]=Calculator +Name[te]=గణనపరికరం +Name[tg]=Калкулятор +Name[th]=เครื่องคิดเลข +Name[tr]=Hesap Makinesi +Name[ug]=ھېسابلىغۇچ +Name[uk]=Калькулятор +Name[uz]=Kalkulyator +Name[uz@cyrillic]=Калкулятор +Name[vi]=Máy tính +Name[wa]=Carculete +Name[x-test]=xxCalculatorxx +Name[zh_CN]=计算器 +Name[zh_TW]=計算機 +Comment=Calculate expressions +Comment[ar]=احسب تعبيرات +Comment[ast]=Calcular espresiones +Comment[be@latin]=Padlik vyrazaŭ. +Comment[bg]=Изчисления +Comment[bs]=Računajte izraze +Comment[ca]=Calcula expressions +Comment[ca@valencia]=Calcula expressions +Comment[cs]=Výpočet vzorců +Comment[csb]=Przeprowôdzanié rechòwaniô +Comment[da]=Beregn udtryk +Comment[de]=Berechnungen durchführen +Comment[el]=Υπολογισμός εκφράσεων +Comment[en_GB]=Calculate expressions +Comment[eo]=Kalkuli esprimojn +Comment[es]=Calcular expresiones +Comment[et]=Avaldiste arvutamine +Comment[eu]=Kalkulatu adierazpenak +Comment[fa]=محاسبه عبارات +Comment[fi]=Suorittaa laskutoimituksia +Comment[fr]=Calcule des expressions +Comment[fy]=Utdrukkings berekkenje +Comment[ga]=Áirigh sloinn +Comment[gl]=Calcula expresións +Comment[gu]=સૂત્રોની ગણતરી કરો +Comment[he]=חישוב ביטויים +Comment[hi]=एक्सप्रेशन्स गणना करें +Comment[hne]=एक्सप्रेसन्स गनना करव +Comment[hr]=Izračunaj izraze +Comment[hu]=Kifejezéseket kezelni tudó számológép +Comment[ia]=Calcula expressiones +Comment[id]=Kalkukasi ekspresi +Comment[is]=Reikna segðir +Comment[it]=Calcola espressioni +Comment[ja]=数式を計算します +Comment[kk]=Өрнектерді есептеу +Comment[km]=គណនា​កន្សោម​​ +Comment[kn]=ಕ್ರಮೋಕ್ತಿಗಳನ್ನು (ಎಕ್ಸ್ಪ್ರೆಶನ್) ಬಿಡಿಸು +Comment[ko]=수식 계산기 +Comment[ku]=ravekirinên Hesabkirinê +Comment[lt]=Skaičiuoti išraiškas +Comment[lv]=Rēķina izteiksmes +Comment[mai]=एक्सप्रेशन्स गणना करू +Comment[mk]=Пресметувајте изрази +Comment[ml]=എക്സ്പ്രെഷനുകള്‍ കണക്കുകൂട്ടുക +Comment[mr]=एक्सप्रेशन्स गणना करा +Comment[nb]=Beregn uttrykk +Comment[nds]=Utdrück utreken +Comment[ne]=अभिव्यक्ति गणना गर्नुहोस् +Comment[nl]=Expressies berekenen +Comment[nn]=Grafisk kalkulator +Comment[or]=ଅଭିବ୍ୟକ୍ତିଗୁଡ଼ିକୁ ଗଣନା କରନ୍ତୁ +Comment[pa]=ਸਮੀਕਰਨ ਕੱਢੋ +Comment[pl]=Obliczanie wyrażeń +Comment[pt]=Calcular expressões +Comment[pt_BR]=Calcula expressões +Comment[ro]=Calculează expresii +Comment[ru]=Вычисление выражений +Comment[se]=Rehkenastte mattebihtáid +Comment[si]=ප්‍රකාශන ගණනය කරන්න +Comment[sk]=Výpočty na kalkulačke +Comment[sl]=Izračunaj izraze +Comment[sr]=Рачунајте изразе +Comment[sr@ijekavian]=Рачунајте изразе +Comment[sr@ijekavianlatin]=Računajte izraze +Comment[sr@latin]=Računajte izraze +Comment[sv]=Beräkna uttryck +Comment[ta]=Calculate expressions +Comment[te]=సమాసాలను గణించుము +Comment[tg]=Вычисление выражений +Comment[th]=คำนวณนิพจน์ +Comment[tr]=İfadeleri hesapla +Comment[ug]=ئىپادىنى ھېسابلا +Comment[uk]=Обчислення виразів +Comment[vi]=Tính biểu thức +Comment[wa]=Carcule des ratourneures +Comment[x-test]=xxCalculate expressionsxx +Comment[zh_CN]=计算表达式 +Comment[zh_TW]=計算機表示式 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=accessories-calculator +X-KDE-Library=krunner_calculatorrunner +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=calculator +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/calculator/qalculate_engine.cpp b/plasma/generic/runners/calculator/qalculate_engine.cpp new file mode 100644 index 00000000..74975267 --- /dev/null +++ b/plasma/generic/runners/calculator/qalculate_engine.cpp @@ -0,0 +1,127 @@ +/* +* Copyright 2010 Matteo Agostinelli +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "qalculate_engine.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +QAtomicInt QalculateEngine::s_counter; + +QalculateEngine::QalculateEngine(QObject* parent): + QObject(parent) +{ + m_lastResult = ""; + s_counter.ref(); + if (!CALCULATOR) { + new Calculator(); + CALCULATOR->terminateThreads(); + CALCULATOR->loadGlobalDefinitions(); + CALCULATOR->loadLocalDefinitions(); + CALCULATOR->loadGlobalCurrencies(); + CALCULATOR->loadExchangeRates(); + } +} + +QalculateEngine::~QalculateEngine() +{ + if (s_counter.deref()) { + delete CALCULATOR; + CALCULATOR = NULL; + } +} + +void QalculateEngine::updateExchangeRates() +{ + KUrl source = KUrl("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml"); + KUrl dest = KUrl(CALCULATOR->getExchangeRatesFileName().c_str()); + + KIO::Job* getJob = KIO::file_copy(source, dest, -1, KIO::Overwrite | KIO::HideProgressInfo); + connect( getJob, SIGNAL(result(KJob*)), this, SLOT(updateResult(KJob*)) ); +} + +void QalculateEngine::updateResult(KJob* job) +{ + if (job->error()) { + kDebug() << i18n("The exchange rates could not be updated. The following error has been reported: %1",job->errorString()); + } else { + // the exchange rates have been successfully updated, now load them + CALCULATOR->loadExchangeRates(); + } +} + +QString QalculateEngine::evaluate(const QString& expression) +{ + if (expression.isEmpty()) { + return ""; + } + + QString input = expression; + QByteArray ba = input.replace(QChar(0xA3), "GBP").replace(QChar(0xA5), "JPY").replace('$', "USD").replace(QChar(0x20AC), "EUR").toLatin1(); + const char *ctext = ba.data(); + + CALCULATOR->terminateThreads(); + EvaluationOptions eo; + + eo.auto_post_conversion = POST_CONVERSION_BEST; + eo.keep_zero_units = false; + + eo.parse_options.angle_unit = ANGLE_UNIT_RADIANS; + eo.structuring = STRUCTURING_SIMPLIFY; + + MathStructure result = CALCULATOR->calculate(ctext, eo); + + PrintOptions po; + po.number_fraction_format = FRACTION_DECIMAL; + po.indicate_infinite_series = false; + po.use_all_prefixes = false; + po.use_denominator_prefix = true; + po.negative_exponents = false; + po.lower_case_e = true; + po.base_display = BASE_DISPLAY_NORMAL; + + result.format(po); + + m_lastResult = result.print(po).c_str(); + + return m_lastResult; +} + +void QalculateEngine::copyToClipboard(bool flag) +{ + Q_UNUSED(flag); + + QApplication::clipboard()->setText(m_lastResult); +} + diff --git a/plasma/generic/runners/calculator/qalculate_engine.h b/plasma/generic/runners/calculator/qalculate_engine.h new file mode 100644 index 00000000..a2264738 --- /dev/null +++ b/plasma/generic/runners/calculator/qalculate_engine.h @@ -0,0 +1,55 @@ +/* +* Copyright 2010 Matteo Agostinelli +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef QALCULATEENGINE_H +#define QALCULATEENGINE_H + +#include +#include + +class KJob; + +class QalculateEngine : public QObject +{ + Q_OBJECT +public: + QalculateEngine(QObject* parent = 0); + ~QalculateEngine(); + + QString lastResult() const { return m_lastResult; } + +public slots: + QString evaluate(const QString& expression); + void updateExchangeRates(); + + void copyToClipboard(bool flag = true); + +protected slots: + void updateResult(KJob*); + +signals: + void resultReady(const QString&); + void formattedResultReady(const QString&); + +private: + QString m_lastResult; + static QAtomicInt s_counter; +}; + +#endif // QALCULATEENGINE_H diff --git a/plasma/generic/runners/kill/CMakeLists.txt b/plasma/generic/runners/kill/CMakeLists.txt new file mode 100644 index 00000000..20d300cb --- /dev/null +++ b/plasma/generic/runners/kill/CMakeLists.txt @@ -0,0 +1,28 @@ +project(plasma-runner-kill) + +set(krunner_kill_SRCS killrunner.cpp) + +set(kcm_krunner_kill_SRCS + killrunner_config.cpp +) + +kde4_add_ui_files(kcm_krunner_kill_SRCS killrunner_config.ui) +kde4_add_plugin(kcm_krunner_kill ${kcm_krunner_kill_SRCS}) +target_link_libraries(kcm_krunner_kill + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} + ${KDE4_KCMUTILS_LIBS} + ${QT_QTCORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ) + +kde4_add_plugin(krunner_kill ${krunner_kill_SRCS}) +target_link_libraries(krunner_kill + ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} processcore) +add_dependencies(krunner_kill kcm_krunner_kill) + +install(TARGETS krunner_kill kcm_krunner_kill + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-runner-kill.desktop plasma-runner-kill_config.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/runners/kill/Messages.sh b/plasma/generic/runners/kill/Messages.sh new file mode 100644 index 00000000..e405d4f6 --- /dev/null +++ b/plasma/generic/runners/kill/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_runner_kill.pot diff --git a/plasma/generic/runners/kill/TODO b/plasma/generic/runners/kill/TODO new file mode 100644 index 00000000..e69de29b diff --git a/plasma/generic/runners/kill/killrunner.cpp b/plasma/generic/runners/kill/killrunner.cpp new file mode 100644 index 00000000..f9d9badb --- /dev/null +++ b/plasma/generic/runners/kill/killrunner.cpp @@ -0,0 +1,223 @@ +/* Copyright 2009 Jan Gerrit Marker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "killrunner.h" + +#include + +#include +#include +#include +#include +#include + +#include "ksysguard/processcore/processes.h" +#include "ksysguard/processcore/process.h" + +#include "killrunner_config.h" + +KillRunner::KillRunner(QObject *parent, const QVariantList& args) + : Plasma::AbstractRunner(parent, args), + m_processes(0) +{ + Q_UNUSED(args); + setObjectName( QLatin1String("Kill Runner") ); + reloadConfiguration(); + + connect(this, SIGNAL(prepare()), this, SLOT(prep())); + connect(this, SIGNAL(teardown()), this, SLOT(cleanup())); + + m_delayedCleanupTimer.setInterval(50); + m_delayedCleanupTimer.setSingleShot(true); + connect(&m_delayedCleanupTimer, SIGNAL(timeout()), this, SLOT(cleanup())); +} + +KillRunner::~KillRunner() +{ +} + + +void KillRunner::reloadConfiguration() +{ + KConfigGroup grp = config(); + m_triggerWord.clear(); + if (grp.readEntry(CONFIG_USE_TRIGGERWORD, true)) { + m_triggerWord = grp.readEntry(CONFIG_TRIGGERWORD, i18n("kill")) + ' '; + } + + m_sorting = (KillRunnerConfig::Sort) grp.readEntry(CONFIG_SORTING, 0); + QList syntaxes; + syntaxes << Plasma::RunnerSyntax(m_triggerWord + ":q:", + i18n("Terminate running applications whose names match the query.")); + setSyntaxes(syntaxes); +} + +void KillRunner::prep() +{ + m_delayedCleanupTimer.stop(); +} + +void KillRunner::cleanup() +{ + if (!m_processes) { + return; + } + + if (m_prepLock.tryLockForWrite()) { + delete m_processes; + m_processes = 0; + + m_prepLock.unlock(); + } else { + m_delayedCleanupTimer.stop(); + } +} + +void KillRunner::match(Plasma::RunnerContext &context) +{ + QString term = context.query(); + const bool hasTrigger = !m_triggerWord.isEmpty(); + if (hasTrigger && !term.startsWith(m_triggerWord, Qt::CaseInsensitive)) { + return; + } + + m_prepLock.lockForRead(); + if (!m_processes) { + m_prepLock.unlock(); + m_prepLock.lockForWrite(); + if (!m_processes) { + suspendMatching(true); + m_processes = new KSysGuard::Processes(); + m_processes->updateAllProcesses(); + suspendMatching(false); + } + } + m_prepLock.unlock(); + + term = term.right(term.length() - m_triggerWord.length()); + + if (term.length() < 2) { + return; + } + + QList matches; + const QList processlist = m_processes->getAllProcesses(); + foreach (const KSysGuard::Process *process, processlist) { + if (!context.isValid()) { + return; + } + + const QString name = process->name; + if (!name.contains(term, Qt::CaseInsensitive)) { + //Process doesn't match the search term + continue; + } + + const quint64 pid = process->pid; + const qlonglong uid = process->uid; + const QString user = getUserName(uid); + + QVariantList data; + data << pid << user; + + Plasma::QueryMatch match(this); + match.setText(i18n("Terminate %1", name)); + match.setSubtext(i18n("Process ID: %1\nRunning as user: %2", QString::number(pid), user)); + match.setIcon(KIcon("application-exit")); + match.setData(data); + match.setId(name); + + // Set the relevance + switch (m_sorting) { + case KillRunnerConfig::CPU: + match.setRelevance((process->userUsage + process->sysUsage) / 100); + break; + case KillRunnerConfig::CPUI: + match.setRelevance(1 - (process->userUsage + process->sysUsage) / 100); + break; + case KillRunnerConfig::NONE: + match.setRelevance(name.compare(term, Qt::CaseInsensitive) == 0 ? 1 : 9); + break; + } + + matches << match; + } + + kDebug() << "match count is" << matches.count(); + context.addMatches(term, matches); +} + +void KillRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context) + + QVariantList data = match.data().value(); + quint64 pid = data[0].toUInt(); + QString user = data[1].toString(); + + int signal; + if (match.selectedAction() != NULL) { + signal = match.selectedAction()->data().toInt(); + } else { + signal = 9; //default: SIGKILL + } + + QStringList args; + args << QString("-%1").arg(signal) << QString("%1").arg(pid); + KProcess *process = new KProcess(this); + int returnCode = process->execute("kill", args); + + if (returnCode == 0) + { + return; + } + + KAuth::Action killAction = QString("org.kde.ksysguard.processlisthelper.sendsignal"); + killAction.setHelperID("org.kde.ksysguard.processlisthelper"); + killAction.addArgument("pid0", pid); + killAction.addArgument("pidcount", 1); + killAction.addArgument("signal", signal); + killAction.execute(); +} + +QList KillRunner::actionsForMatch(const Plasma::QueryMatch &match) +{ + Q_UNUSED(match) + + QList ret; + + if (!action("SIGTERM")) { + (addAction("SIGTERM", KIcon("application-exit"), i18n("Send SIGTERM")))->setData(15); + (addAction("SIGKILL", KIcon("process-stop"), i18n("Send SIGKILL")))->setData(9); + } + ret << action("SIGTERM") << action("SIGKILL"); + return ret; +} + +QString KillRunner::getUserName(qlonglong uid) +{ + KUser user(uid); + if (user.isValid()) { + return user.loginName(); + } + kDebug() << QString("No user with UID %1 was found").arg(uid); + return "root";//No user with UID uid was found, so root is used +} + +#include "killrunner.moc" diff --git a/plasma/generic/runners/kill/killrunner.h b/plasma/generic/runners/kill/killrunner.h new file mode 100644 index 00000000..e843be05 --- /dev/null +++ b/plasma/generic/runners/kill/killrunner.h @@ -0,0 +1,77 @@ +/* Copyright 2009 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef KILLRUNNER_H +#define KILLRUNNER_H + +#include +#include + +#include + +#include "killrunner_config.h" +class QAction; + +namespace KSysGuard +{ + class Processes; + class Process; +} + +class KillRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + +public: + KillRunner(QObject *parent, const QVariantList& args); + ~KillRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match); + QList actionsForMatch(const Plasma::QueryMatch &match); + void reloadConfiguration(); + +private Q_SLOTS: + void prep(); + void cleanup(); + +private: + /** @param uid the uid of the user + * @return the username of the user with the UID uid + */ + QString getUserName(qlonglong uid); + + /** The trigger word */ + QString m_triggerWord; + + /** How to sort */ + KillRunnerConfig::Sort m_sorting; + + /** process lister */ + KSysGuard::Processes *m_processes; + + /** lock for initializing m_processes */ + QReadWriteLock m_prepLock; + + /** timer for retrying the cleanup due to lock contention */ + QTimer m_delayedCleanupTimer; +}; +K_EXPORT_PLASMA_RUNNER(kill, KillRunner) + +#endif diff --git a/plasma/generic/runners/kill/killrunner_config.cpp b/plasma/generic/runners/kill/killrunner_config.cpp new file mode 100644 index 00000000..94fe7a74 --- /dev/null +++ b/plasma/generic/runners/kill/killrunner_config.cpp @@ -0,0 +1,90 @@ +/* Copyright 2009 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +//Project-Includes +#include "killrunner_config.h" +//KDE-Includes +#include + +K_EXPORT_RUNNER_CONFIG(kill, KillRunnerConfig) + +KillRunnerConfigForm::KillRunnerConfigForm(QWidget* parent) : QWidget(parent) +{ + setupUi(this); +} + +KillRunnerConfig::KillRunnerConfig(QWidget* parent, const QVariantList& args) : + KCModule(ConfigFactory::componentData(), parent, args) +{ + m_ui = new KillRunnerConfigForm(this); + + QGridLayout* layout = new QGridLayout(this); + layout->addWidget(m_ui, 0, 0); + + m_ui->sorting->addItem(i18n("CPU usage"), CPU); + m_ui->sorting->addItem(i18n("inverted CPU usage"), CPUI); + m_ui->sorting->addItem(i18n("nothing"), NONE); + + connect(m_ui->useTriggerWord,SIGNAL(stateChanged(int)),this,SLOT(changed())); + connect(m_ui->triggerWord,SIGNAL(textChanged(QString)),this,SLOT(changed())); + connect(m_ui->sorting,SIGNAL(currentIndexChanged(int)),this,SLOT(changed())); + + load(); +} + +void KillRunnerConfig::load() +{ + KCModule::load(); + + KSharedConfig::Ptr cfg = KSharedConfig::openConfig("krunnerrc"); + KConfigGroup grp = cfg->group("Runners"); + grp = KConfigGroup(&grp, "Kill Runner"); + + m_ui->useTriggerWord->setChecked(grp.readEntry(CONFIG_USE_TRIGGERWORD,true)); + m_ui->triggerWord->setText(grp.readEntry(CONFIG_TRIGGERWORD,i18n("kill"))); + m_ui->sorting->setCurrentIndex(m_ui->sorting->findData(grp.readEntry(CONFIG_SORTING, (int) NONE))); + + emit changed(false); +} + +void KillRunnerConfig::save() +{ + KCModule::save(); + + KSharedConfig::Ptr cfg = KSharedConfig::openConfig("krunnerrc"); + KConfigGroup grp = cfg->group("Runners"); + grp = KConfigGroup(&grp, "Kill Runner"); + + grp.writeEntry(CONFIG_USE_TRIGGERWORD,m_ui->useTriggerWord->isChecked()); + grp.writeEntry(CONFIG_TRIGGERWORD,m_ui->triggerWord->text()); + grp.writeEntry(CONFIG_SORTING,m_ui->sorting->itemData(m_ui->sorting->currentIndex())); + + emit changed(false); +} + +void KillRunnerConfig::defaults() +{ + KCModule::defaults(); + + m_ui->useTriggerWord->setChecked(true); + m_ui->triggerWord->setText(i18n("kill")); + m_ui->sorting->setCurrentIndex(m_ui->sorting->findData((int) NONE)); + + emit changed(true); +} diff --git a/plasma/generic/runners/kill/killrunner_config.h b/plasma/generic/runners/kill/killrunner_config.h new file mode 100644 index 00000000..3e015c2f --- /dev/null +++ b/plasma/generic/runners/kill/killrunner_config.h @@ -0,0 +1,59 @@ +/* Copyright 2009 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef KILLRUNNERCONFIG_H +#define KILLRUNNERCONFIG_H + +//Project-Includes +#include "ui_killrunner_config.h" +//KDE-Includes +#include +//Qt + +static const char CONFIG_USE_TRIGGERWORD[] = "useTriggerWord"; +static const char CONFIG_TRIGGERWORD[] = "triggerWord"; +static const char CONFIG_SORTING[] = "sorting"; + +class KillRunnerConfigForm : public QWidget, public Ui::KillRunnerConfigUi +{ + Q_OBJECT + +public: + explicit KillRunnerConfigForm(QWidget* parent); +}; + +class KillRunnerConfig : public KCModule +{ + Q_OBJECT + +public: + explicit KillRunnerConfig(QWidget* parent = 0, const QVariantList& args = QVariantList()); + + /** Possibilities to sort */ + enum Sort {NONE = 0, CPU, CPUI}; + +public slots: + void save(); + void load(); + void defaults(); + +private: + KillRunnerConfigForm* m_ui; +}; +#endif diff --git a/plasma/generic/runners/kill/killrunner_config.ui b/plasma/generic/runners/kill/killrunner_config.ui new file mode 100644 index 00000000..2eda8bac --- /dev/null +++ b/plasma/generic/runners/kill/killrunner_config.ui @@ -0,0 +1,129 @@ + + + Jan Gerrit Marker + KillRunnerConfigUi + + + + 0 + 0 + 308 + 252 + + + + + + + Kill Applications Config + + + + + + true + + + &Use trigger word + + + true + + + + + + + + + &Trigger word: + + + triggerWord + + + + + + + true + + + + + + + + + + + &Sort by + + + sorting + + + + + + + It is not sure, that this will take effect + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + KLineEdit + QLineEdit +
    klineedit.h
    +
    + + KComboBox + QComboBox +
    kcombobox.h
    +
    +
    + + useTriggerWord + triggerWord + + + + + useTriggerWord + toggled(bool) + triggerWord + setEnabled(bool) + + + 97 + 49 + + + 122 + 79 + + + + +
    diff --git a/plasma/generic/runners/kill/plasma-runner-kill.desktop b/plasma/generic/runners/kill/plasma-runner-kill.desktop new file mode 100644 index 00000000..1f6f9ffb --- /dev/null +++ b/plasma/generic/runners/kill/plasma-runner-kill.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Terminate Applications +Name[ar]=أنهِ تطبيقات +Name[ast]=Zarrar aplicaciones +Name[bg]=Прекъсване на програми +Name[bn]=অ্যাপলিকেশন থামাও +Name[bs]=obustavljanje programa +Name[ca]=Finalitza aplicacions +Name[ca@valencia]=Finalitza aplicacions +Name[cs]=Ukončit aplikace +Name[csb]=Zamëkô apliakcëje +Name[da]=Afslut programmer +Name[de]=Programme beenden +Name[el]=Τερματισμός εφαρμογών +Name[en_GB]=Terminate Applications +Name[eo]=Terminalaj Aplikaĵoj +Name[es]=Cerrar aplicaciones +Name[et]=Rakenduste töö lõpetamine +Name[eu]=Amaitu aplikazioak +Name[fa]=پایان دادن به برنامه‌ها +Name[fi]=Lopeta sovellukset +Name[fr]=Terminer des applications +Name[fy]=Programma's ôfbrekke +Name[ga]=Scoir ó Fheidhmchláir +Name[gl]=Terminar programas +Name[gu]=કાર્યક્રમો બંધ કરો +Name[he]=סיום פעולת יישומים +Name[hi]=अनुप्रयोग खतम करो +Name[hr]=Prekini aplikacije +Name[hu]=Program félbeszakítása +Name[ia]=Termina applicationes +Name[id]=Hentikan Aplikasi +Name[is]=Loka forritum +Name[it]=Termina applicazioni +Name[ja]=アプリケーションを終了 +Name[kk]=Қолданбалары аяқтау +Name[km]=កម្មវិធី​ស្ថានីយ +Name[kn]=ಅನ್ವಯಗಳನ್ನು ಅಂತ್ಯಗೊಳಿಸು +Name[ko]=프로그램 끝내기 +Name[lt]=Nutraukti programas +Name[lv]=Pārtraukt programmas +Name[mk]=Запирање на апликации +Name[ml]=പ്രയോഗങ്ങളെ ഇല്ലാതാക്കുക +Name[mr]=अनुप्रयोग बंद करा +Name[nb]=Avslutt programmer +Name[nds]=Programmen utmaken +Name[nl]=Toepassingen afsluiten +Name[nn]=Avslutt program +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਖਤਮ ਕਰੋ +Name[pl]=Zakańczanie programów +Name[pt]=Terminar as Aplicações +Name[pt_BR]=Terminar aplicativos +Name[ro]=Termină aplicații +Name[ru]=Завершение приложений +Name[si]=යෙදුම් මර්‍ධනය +Name[sk]=Ukončenie aplikácií +Name[sl]=Uničenje programov +Name[sr]=обустављање програма +Name[sr@ijekavian]=обустављање програма +Name[sr@ijekavianlatin]=obustavljanje programa +Name[sr@latin]=obustavljanje programa +Name[sv]=Avsluta program +Name[tg]=Барномаҳои терминал +Name[th]=ยุติการทำงานของโปรแกรม +Name[tr]=Uygulamaları Bitir +Name[ug]=پروگراممىلارنى توختات +Name[uk]=Переривання програм +Name[wa]=Fé fini des programes +Name[x-test]=xxTerminate Applicationsxx +Name[zh_CN]=终止程序 +Name[zh_TW]=終端機應用程式 +Comment=Stop applications that are currently running +Comment[ar]=أوقف برامجاً قيد الشغيل حالياً +Comment[ast]=Parar aplicaciones que tan executándose +Comment[bg]=Спиране на работещи в момента програми +Comment[bs]=Zaustavlja programe trenutno u pogonu +Comment[ca]=Atura aplicacions que estan actualment en execució +Comment[ca@valencia]=Para aplicacions que estan actualment en execució +Comment[cs]=Ukončit aktuálně spuštěné aplikace +Comment[csb]=Zamëkô prawie robiącé aplikacëje +Comment[da]=Stop programmer der kører i øjeblikket +Comment[de]=Gerade laufende Anwendungen beenden +Comment[el]=Σταμάτημα των εκτελούμενων εργασιών +Comment[en_GB]=Stop applications that are currently running +Comment[es]=Parar aplicaciones que se están ejecutando +Comment[et]=Töötavate rakenduste töö lõpetamine +Comment[eu]=Gelditu une honetan exekutatzen ari diren aplikazioak +Comment[fi]=Pysäytä sovellukset, joita parhaillaan suoritetaan +Comment[fr]=Arrête des applications en cours d'exécution +Comment[fy]=Lit applikaasje dy't no rinne ophâlde +Comment[ga]=Scoir ó fheidhmchláir atá ag rith faoi láthair +Comment[gl]=Detén programas que están a executarse +Comment[he]=עצירת יישומים הפועלים כעת +Comment[hr]=Zaustavi aplikacije koje su trenutno pokrenute +Comment[hu]=Jelenleg futó alkalmazások leállítása +Comment[ia]=Stoppa applicationes que il es currentemente executante +Comment[id]=Stop aplikasi yang saat ini tengah berjalan +Comment[is]=Stöðva forrit sem eru keyrandi +Comment[it]=Ferma le applicazioni attualmente in esecuzione +Comment[ja]=実行中のアプリケーションを停止します +Comment[kk]=Орындалып жатқан қолданбаларды тоқтату +Comment[km]=បញ្ឈប់​កម្មវិធី​ដែលបច្ចុប្បន្ន​កំពុង​តែ​រត់ +Comment[kn]=ಪ್ರಸ್ತುತ ಚಾಲನೆಯಲ್ಲಿರುವ ಅನ್ವಯಗಳನ್ನು ನಿಲ್ಲಿಸು +Comment[ko]=현재 실행 중인 프로그램을 끝냅니다 +Comment[lt]=Sustabdo programas, kurios šiuo metu veikia +Comment[lv]=Apturēt šobrīd darbojošās programmas +Comment[mk]=Ги запира апликациите што моментално се активни +Comment[ml]=ഇപ്പോള്‍ പ്രവര്‍ത്തിയ്ക്കുന്ന പ്രയോഗങ്ങള്‍ നിര്‍ത്തുക +Comment[mr]=चालू असणारे अनुप्रयोग बंद करा +Comment[nb]=Stopp programmer som kjører nå +Comment[nds]=Opstunns lopen Programmen utmaken +Comment[nl]=Beëindig toepassingen die momenteel draaien +Comment[nn]=Stop program som køyrer +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੋਕੋ, ਜੋ ਇਸ ਸਮੇਂ ਚੱਲ ਰਹੀਆਂ ਹਨ +Comment[pl]=Zatrzymanie programów, które są obecnie uruchomione +Comment[pt]=Parar as aplicações actualmente em execução +Comment[pt_BR]=Interrompe aplicativos em execução +Comment[ro]=Oprește aplicații ce rulează momentan +Comment[ru]=Завершение работы запущенных в данный момент приложений +Comment[si]=දැනට ක්‍රියාකරන යෙදුම් නැවතීම +Comment[sk]=Zastavenie práve bežiacich aplikácií +Comment[sl]=Zaustavite trenutno zagnane programe +Comment[sr]=Зауставља програме тренутно у погону +Comment[sr@ijekavian]=Зауставља програме тренутно у погону +Comment[sr@ijekavianlatin]=Zaustavlja programe trenutno u pogonu +Comment[sr@latin]=Zaustavlja programe trenutno u pogonu +Comment[sv]=Stoppa program som för närvarande kör +Comment[tg]=Қатъ кардани барномаҳои ҷорӣ +Comment[th]=หยุดการทำงานของโปรแกรมที่กำลังทำงานอยู่ในปัจจุบัน +Comment[tr]=Şu anda çalışan uygulamaları durdur +Comment[ug]=نۆۋەتتە ئىجرا بولۇۋاتقان پروگراممىلارنى توختىتىدۇ +Comment[uk]=Завершує роботу запущених програм +Comment[wa]=Arester des programes k' ovrèt pol moumint +Comment[x-test]=xxStop applications that are currently runningxx +Comment[zh_CN]=停止正在运行的应用程序 +Comment[zh_TW]=停止目前執行中的應用程式 +Icon=application-exit + +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +X-KDE-Library=krunner_kill +X-KDE-PluginInfo-Author=Jan Gerrit Marker +X-KDE-PluginInfo-Email=jangerrit@weiler-marker.com +X-KDE-PluginInfo-Name=Kill Runner +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/kill/plasma-runner-kill_config.desktop b/plasma/generic/runners/kill/plasma-runner-kill_config.desktop new file mode 100644 index 00000000..b78523a3 --- /dev/null +++ b/plasma/generic/runners/kill/plasma-runner-kill_config.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kcm_krunner_kill +X-KDE-ParentComponents=Kill Runner +X-KDE-PluginKeyword=kcm_krunner_kill + +Name=Kill Applications +Name[ar]=اقتل تطبيقات +Name[ast]=Matar aplicaciones +Name[bg]=Убиване на програми +Name[bn]=অ্যাপলিকেশন বন্ধ করো +Name[bs]=Obustavljanje programa +Name[ca]=Mata aplicacions +Name[ca@valencia]=Mata aplicacions +Name[cs]=Zabít aplikace +Name[csb]=Zamkni apliakcëjã +Name[da]=Dræb programmer +Name[de]=Programme abschießen +Name[el]=Τερματισμός εφαρμογών +Name[en_GB]=Kill Applications +Name[eo]=Mortigi aplikaĵon +Name[es]=Matar aplicaciones +Name[et]=Rakenduste tapmine +Name[eu]=Hil aplikazioak +Name[fi]=Tuhoa sovellukset +Name[fr]=Tuer des applications +Name[fy]=Programma's ôfbrekke +Name[ga]=Maraigh Feidhmchláir +Name[gl]=Matar programas +Name[gu]=કાર્યક્રમો બંધ કરો +Name[he]=הריגת יישומים +Name[hi]=अनुप्रयोग खतम करो +Name[hr]=Uništi aplikacije +Name[hu]=Alkalmazás kilövése +Name[ia]=Occide applicationes +Name[id]=Matikan Aplikasi +Name[is]=Drepa forrit +Name[it]=Termina applicazioni +Name[ja]=アプリケーションを強制終了 +Name[kk]=Қолданбалары құрту +Name[km]=បញ្ឈប់​កម្មវិធី +Name[kn]=ಅನ್ವಯಗಳನ್ನು ಅಂತ್ಯಗೊಳಿಸು +Name[ko]=프로그램 죽이기 +Name[lt]=Užverti programas +Name[lv]=Nokaut programmas +Name[mk]=Запирање на апликации +Name[ml]=പ്രയോഗങ്ങളെ കൊല്ലുക +Name[mr]=केडीई अनुप्रयोग +Name[nb]=Drep programmer +Name[nds]=Programmen afscheten +Name[nl]=Programma's afbreken +Name[nn]=Drep program +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਖਤਮ ਕਰੋ +Name[pl]=Niszczenie programów +Name[pt]=Matar as Aplicações +Name[pt_BR]=Matar aplicativos +Name[ro]=Omoară aplicații +Name[ru]=Завершение приложений +Name[si]=KDE යෙදුම් +Name[sk]=Zabiť aplikácie +Name[sl]=Uniči programe +Name[sr]=Обустављање програма +Name[sr@ijekavian]=Обустављање програма +Name[sr@ijekavianlatin]=Obustavljanje programa +Name[sr@latin]=Obustavljanje programa +Name[sv]=Döda program +Name[tg]=Барномаҳои KDE +Name[th]=ฆ่าโพรเซสของโปรแกรม +Name[tr]=Uygulamaları Sonlandır +Name[ug]=پروگراممىنى ئاخىرلاشتۇر +Name[uk]=Припинення роботи програм +Name[vi]=Tắt ứng dụng +Name[wa]=Touwer des programes +Name[x-test]=xxKill Applicationsxx +Name[zh_CN]=杀死程序 +Name[zh_TW]=砍掉應用程式 diff --git a/plasma/generic/runners/locations/CMakeLists.txt b/plasma/generic/runners/locations/CMakeLists.txt new file mode 100644 index 00000000..4cb3d2a5 --- /dev/null +++ b/plasma/generic/runners/locations/CMakeLists.txt @@ -0,0 +1,11 @@ +set(krunner_locations_SRCS + locationrunner.cpp +) + +kde4_add_plugin(krunner_locations ${krunner_locations_SRCS}) +target_link_libraries(krunner_locations ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS krunner_locations DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-locations.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/locations/Messages.sh b/plasma/generic/runners/locations/Messages.sh new file mode 100755 index 00000000..68cd7205 --- /dev/null +++ b/plasma/generic/runners/locations/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_locations.pot diff --git a/plasma/generic/runners/locations/locationrunner.cpp b/plasma/generic/runners/locations/locationrunner.cpp new file mode 100644 index 00000000..c13dfc18 --- /dev/null +++ b/plasma/generic/runners/locations/locationrunner.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2007 Teemu Rytilahti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "locationrunner.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +LocationsRunner::LocationsRunner(QObject *parent, const QVariantList& args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args); + // set the name shown after the result in krunner window + setObjectName(QLatin1String("Locations")); + setIgnoredTypes(Plasma::RunnerContext::Executable | Plasma::RunnerContext::ShellCommand); + addSyntax(Plasma::RunnerSyntax(":q:", + i18n("Finds local directories and files, network locations and Internet sites with paths matching :q:."))); +} + +LocationsRunner::~LocationsRunner() +{ +} + +void LocationsRunner::match(Plasma::RunnerContext &context) +{ + QString term = context.query(); + Plasma::RunnerContext::Type type = context.type(); + + if (type == Plasma::RunnerContext::Directory || type == Plasma::RunnerContext::File) { + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setText(i18n("Open %1", term)); + + if (type == Plasma::RunnerContext::File) { + match.setIcon(KIcon(KMimeType::iconNameForUrl(KUrl(term)))); + } else { + match.setIcon(KIcon("system-file-manager")); + } + + match.setRelevance(1); + match.setData(term); + match.setType(Plasma::QueryMatch::ExactMatch); + + if (type == Plasma::RunnerContext::Directory) { + match.setId("opendir"); + } else { + match.setId("openfile"); + } + context.addMatch(term, match); + } else if (type == Plasma::RunnerContext::Help) { + //kDebug() << "Locations matching because of" << type; + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setText(i18n("Open %1", term)); + match.setIcon(KIcon("system-help")); + match.setRelevance(1); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setId("help"); + context.addMatch(term, match); + } else if (type == Plasma::RunnerContext::NetworkLocation || type == Plasma::RunnerContext::UnknownType) { + const bool filtered = KUriFilter::self()->filterUri(term, QStringList() << QLatin1String("kshorturifilter")); + + if (!filtered) { + return; + } + + KUrl url(term); + + if (!KProtocolInfo::isKnownProtocol(url.protocol())) { + return; + } + + Plasma::QueryMatch match(this); + match.setText(i18n("Go to %1", url.prettyUrl())); + match.setIcon(KIcon(KProtocolInfo::icon(url.protocol()))); + match.setData(url.url()); + + if (KProtocolInfo::isHelperProtocol(url.protocol())) { + //kDebug() << "helper protocol" << url.protocol() <<"call external application" ; + if (url.protocol() == "mailto") { + match.setText(i18n("Send email to %1",url.path())); + } else { + match.setText(i18n("Launch with %1", KProtocolInfo::exec(url.protocol()))); + } + } else { + //kDebug() << "protocol managed by browser" << url.protocol(); + match.setText(i18n("Go to %1", url.prettyUrl())); + } + + if (type == Plasma::RunnerContext::UnknownType) { + match.setId("openunknown"); + match.setRelevance(0.5); + match.setType(Plasma::QueryMatch::PossibleMatch); + } else { + match.setId("opennetwork"); + match.setRelevance(0.7); + match.setType(Plasma::QueryMatch::ExactMatch); + } + + context.addMatch(term, match); + } +} + +void LocationsRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(match) + + QString location = context.query(); + + if (location.isEmpty()) { + return; + } + + //kDebug() << "command: " << context.query(); + //kDebug() << "url: " << location << data; + + KUrl urlToRun(KUriFilter::self()->filteredUri(location, QStringList() << QLatin1String("kshorturifilter"))); + + new KRun(urlToRun, 0); +} + +QMimeData * LocationsRunner::mimeDataForMatch(const Plasma::QueryMatch *match) +{ + const QString data = match->data().toString(); + if (!data.isEmpty()) { + KUrl url(data); + QList list; + list << url; + QMimeData *result = new QMimeData(); + result->setUrls(list); + result->setText(data); + return result; + } + + return 0; +} + + +#include "locationrunner.moc" diff --git a/plasma/generic/runners/locations/locationrunner.h b/plasma/generic/runners/locations/locationrunner.h new file mode 100644 index 00000000..8ab35954 --- /dev/null +++ b/plasma/generic/runners/locations/locationrunner.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef LOCATIONRUNNER_H +#define LOCATIONRUNNER_H + +#include + +class LocationsRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + LocationsRunner(QObject *parent, const QVariantList& args); + ~LocationsRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + + protected Q_SLOTS: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); +}; + +K_EXPORT_PLASMA_RUNNER(locations, LocationsRunner) + +#endif diff --git a/plasma/generic/runners/locations/plasma-runner-locations.desktop b/plasma/generic/runners/locations/plasma-runner-locations.desktop new file mode 100644 index 00000000..88afd224 --- /dev/null +++ b/plasma/generic/runners/locations/plasma-runner-locations.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=Locations +Name[ar]=مواقع +Name[ast]=Llugares +Name[be@latin]=Miescy +Name[bg]=Местоположения +Name[bn]=অবস্থান +Name[bn_IN]=অবস্থান +Name[bs]=lokacije +Name[ca]=Ubicacions +Name[ca@valencia]=Ubicacions +Name[cs]=Umístění +Name[csb]=Dzejania +Name[da]=Placeringer +Name[de]=Orte +Name[el]=Τοποθεσίες +Name[en_GB]=Locations +Name[eo]=Lokoj +Name[es]=Ubicaciones +Name[et]=Asukohad +Name[eu]=Kokalekuak +Name[fi]=Sijainnit +Name[fr]=Emplacements +Name[fy]=Lokaasjes +Name[ga]=Áiteanna +Name[gl]=Lugares +Name[gu]=સ્થળો +Name[he]=מיקומים +Name[hi]=स्थान +Name[hne]=जगह +Name[hr]=Lokacije +Name[hu]=Helyek +Name[ia]=Locationes +Name[id]=Lokasi +Name[is]=Staðsetningar +Name[it]=Posizioni +Name[ja]=場所 +Name[kk]=Адрестер +Name[km]=ទីតាំង +Name[kn]=ಸ್ಥಳಗಳು +Name[ko]=위치 +Name[ku]=Cih +Name[lt]=Vietos +Name[lv]=Vietas +Name[mk]=Локации +Name[ml]=സ്ഥാനങ്ങള്‍ +Name[mr]=स्थान +Name[nb]=Steder +Name[nds]=Steden +Name[nl]=Locaties +Name[nn]=Adresser +Name[or]=ସ୍ଥାନଗୁଡ଼ିକ +Name[pa]=ਟਿਕਾਣੇ +Name[pl]=Położenia +Name[pt]=Locais +Name[pt_BR]=Localizações +Name[ro]=Locații +Name[ru]=Расположения +Name[si]=පිහිටුම +Name[sk]=Miesta +Name[sl]=Mesta +Name[sr]=локације +Name[sr@ijekavian]=локације +Name[sr@ijekavianlatin]=lokacije +Name[sr@latin]=lokacije +Name[sv]=Platser +Name[ta]=Locations +Name[te]=స్థానములు +Name[tg]=Ҷойгиршавӣ +Name[th]=ตำแหน่งที่อยู่ +Name[tr]=Konumlar +Name[ug]=ئورنى +Name[uk]=Адреси +Name[vi]=Vị trí +Name[wa]=Eplaeçmints +Name[x-test]=xxLocationsxx +Name[zh_CN]=位置 +Name[zh_TW]=位置 +Comment=File and URL opener +Comment[ar]=فاتح الملفات و العناوين +Comment[ast]=Visor de ficheros y URL +Comment[be@latin]=Adčynieńnie fajłaŭ i adrasoŭ +Comment[bg]=Отваряне на файлове и адреси +Comment[bn_IN]=ফাইল ও URL প্রদর্শক +Comment[bs]=Otvarač datoteka i URL‑ova +Comment[ca]=Obre fitxers i URL +Comment[ca@valencia]=Obri fitxers i URL +Comment[cs]=Otvírač souborů a URL +Comment[csb]=Òtmëkôcz lopków ë adresół URL +Comment[da]=Fil- og URL-åbner +Comment[de]=Öffnet Dateien und Adressen +Comment[el]=Άνοιγμα αρχείων και URL +Comment[en_GB]=File and URL opener +Comment[eo]=Malfermas dosierojn kaj adresojn +Comment[es]=Visor de archivos y URL +Comment[et]=Faili ja URL-i avaja +Comment[eu]=Fitxategiak eta URLak irekitzea +Comment[fi]=Tiedostojen ja osoitteiden avaaja +Comment[fr]=Ouverture de fichiers et d'URL +Comment[fy]=Triem en URL-adres iepener +Comment[ga]=Osclóir Comhad agus URLanna +Comment[gl]=Abre ficheiros e URL +Comment[gu]=ફાઇલ અને URL ખોલનાર +Comment[he]=פותח קבצים וכתובות +Comment[hi]=फ़ाइल व यूआरएल खोलने वाला +Comment[hne]=फाइल अउ यूआरएल खोलइया +Comment[hr]=Otvarač datoteka i URL-ova +Comment[hu]=Fájlmegnyitó +Comment[ia]=Aperitor de file e de URL +Comment[id]=Pembuka Berkas dan URL +Comment[is]=Skráa og slóða opnun +Comment[it]=Apertura di file e URL +Comment[ja]=ファイルと URL を開きます +Comment[kk]=Файл мен URL ашқышы +Comment[km]=កម្មវិធី​បើក ឯកសារ និង URL +Comment[kn]=ಕಡತ ಮತ್ತು URL ತೆರೆಯುಗ +Comment[ko]=파일과 URL을 여는 도구 +Comment[ku]=Vekera pel û URL'an +Comment[lt]=Failų ir URL atvėriklis +Comment[lv]=Failu un URL atvērējs +Comment[mk]=Отворач на датотеки и адреси +Comment[ml]=ഫയല്‍, യുആര്‍എല്‍ തുറക്കുന്നതിനുള്ള സംവിധാനം +Comment[mr]=फाईल व URL ओपनर +Comment[nb]=Fil- og URL-åpner +Comment[nds]=Opmaker för Dateien un URLs +Comment[nl]=Openen van bestanden en URL-adressen +Comment[nn]=Opna filer og nettadresser +Comment[or]=ଫାଇଲ ଏବଂ URL ଖୋଲା +Comment[pa]=ਫਾਇਲ ਅਤੇ URL ਖੋਲ੍ਹਣ ਵਾਲਾ +Comment[pl]=Otwieranie plików i adresów URL +Comment[pt]=Abertura de ficheiros e URL's +Comment[pt_BR]=Abertura de arquivos e URLs +Comment[ro]=Deschizător de fișiere și URL-uri +Comment[ru]=Открытие файлов и ссылок +Comment[si]=ගොනු සහ URL විවෘතකරණය +Comment[sk]=Otváranie súborov a URL +Comment[sl]=Odpri datoteke in naslove URL +Comment[sr]=Отварач фајлова и УРЛ‑ова +Comment[sr@ijekavian]=Отварач фајлова и УРЛ‑ова +Comment[sr@ijekavianlatin]=Otvarač fajlova i URL‑ova +Comment[sr@latin]=Otvarač fajlova i URL‑ova +Comment[sv]=Öppna filer och webbadresser +Comment[ta]=File and URL opener +Comment[te]=ఫైల్ మరియు URL తెరువునది +Comment[tg]=Кушодани файлҳо ва URL +Comment[th]=ตัวเปิดแฟ้มและที่อยู่ URL +Comment[tr]=Dosya ve Adres açıcı +Comment[ug]=ھۆججەت ۋە URL ئاچقۇچ +Comment[uk]=Відкривання файлів і адрес URL +Comment[vi]=Trình mở tập tin và URL +Comment[wa]=Droveu d' fitchî eyet d' adresses +Comment[x-test]=xxFile and URL openerxx +Comment[zh_CN]=文件和 URL 打开器 +Comment[zh_TW]=檔案與網址開啟器 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=system-file-manager +X-KDE-Library=krunner_locations +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=locations +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/nepomuksearch/CMakeLists.txt b/plasma/generic/runners/nepomuksearch/CMakeLists.txt new file mode 100644 index 00000000..051741b0 --- /dev/null +++ b/plasma/generic/runners/nepomuksearch/CMakeLists.txt @@ -0,0 +1,34 @@ +project(nepomuksearchrunner) + +include_directories( + ${QT_INCLUDES} + ${KDE4_INCLUDES} + ${SOPRANO_INCLUDE_DIR} + ${NEPOMUK_CORE_INCLUDE_DIR} +) + +SET(nepomuksearchrunner_SRCS + nepomuksearchrunner.cpp +) + +kde4_add_plugin(krunner_nepomuksearchrunner ${nepomuksearchrunner_SRCS}) + +target_link_libraries(krunner_nepomuksearchrunner + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} + ${KDE4_KIO_LIBS} + ${NEPOMUK_CORE_LIBRARY} + ${QT_QTGUI_LIBRARY} + ${SOPRANO_LIBRARIES} + ${KDE4_PLASMA_LIBS} +) + +install( + TARGETS krunner_nepomuksearchrunner + DESTINATION ${PLUGIN_INSTALL_DIR} + ) + +install( + FILES plasma-runner-nepomuksearch.desktop + DESTINATION ${SERVICES_INSTALL_DIR} +) diff --git a/plasma/generic/runners/nepomuksearch/Messages.sh b/plasma/generic/runners/nepomuksearch/Messages.sh new file mode 100755 index 00000000..5e7cef84 --- /dev/null +++ b/plasma/generic/runners/nepomuksearch/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_nepomuksearchrunner.pot diff --git a/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.cpp b/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.cpp new file mode 100644 index 00000000..fd532847 --- /dev/null +++ b/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.cpp @@ -0,0 +1,386 @@ +/* This file is part of the Nepomuk Project + Copyright (c) 2008 Sebastian Trueg + Copyright (c) 2012-13 Vishesh Handa + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "nepomuksearchrunner.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace Nepomuk2::Vocabulary; +using namespace Soprano::Vocabulary; + +namespace { + /** + * Milliseconds to wait before issuing the next query. + * This timeout is intended to prevent us from starting + * a query after each key press by the user. So it should + * roughly equal the time between key presses of an average user. + */ + const int s_userActionTimeout = 400; + const int s_maxResults = 10; +} + + +Nepomuk2::SearchRunner::SearchRunner( QObject* parent, const QVariantList& args ) + : Plasma::AbstractRunner( parent, args ) +{ +} + + +Nepomuk2::SearchRunner::SearchRunner( QObject* parent, const QString& serviceId ) + : Plasma::AbstractRunner( parent, serviceId ) +{ +} + + +void Nepomuk2::SearchRunner::init() +{ + // Just constructing the instance initializes the ResourceManager + Nepomuk2::ResourceManager::instance(); + + // we are pretty slow at times and use DBus calls + setSpeed(SlowSpeed); + + // we are way less important than others, mostly because we are slow + setPriority(LowPriority); + + m_actions = new KFileItemActions(this); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds files, documents and other content that matches :q: using the desktop search system."))); +} + + +Nepomuk2::SearchRunner::~SearchRunner() +{ + qDeleteAll(m_konqActions); +} + + +void Nepomuk2::SearchRunner::match( Plasma::RunnerContext& context ) +{ + //kDebug() << &context << context.query(); + + if( ResourceManager::instance()->initialized() ) { + // This method needs to be thread-safe since KRunner does simply start new threads whenever + // the query term changes. + m_mutex.lock(); + + // we do not want to restart a query on each key-press. That would result + // in way too many queries for the rather sluggy Nepomuk query service + // Thus, we use a little timeout to make sure we do not query too often + + m_waiter.wait(&m_mutex, s_userActionTimeout); + m_mutex.unlock(); + + if (!context.isValid()) { + //kDebug() << "deprecated search:" << context.query(); + // we are no longer the latest call + return; + } + + // no queries on very short strings + // We use a default length of 4 characters cause virtuoso has a min length requirement of 4 + // leading characters. This way we avoid using the expensive regex search + if( context.query().length() >= 4 ) { + //kDebug() << "got through" << context.query(); + Query::Query query = Query::QueryParser::parseQuery(context.query()); + query.setLimit(s_maxResults); + + Query::ResultIterator it(query); + while (context.isValid() && it.next()) { + Plasma::QueryMatch match = convertToQueryMatch(it.result()); + if (match.isValid()) { + context.addMatch(context.query(), match); + } + } + } + } +} + +namespace { + // Copied from kde-runtime/nepomuk/kioslaves/kio_nepomuk.cpp + /** + * This function constructs the url the nepomuk kioslave would redirect to. + * We use this instead of just supplying the nepomuk kioslave with the url because + * applications like Dolphin display the url on the title bar even though the + * 'display name' would be set cause that would involve stating the file. + * + * Therefore, in order to avoid showing an ugly 'nepomuk:/res/uuid' to the user we + * redirect the url ourselves so we have a pretty representation. + */ + KUrl redirectionUrl(const Nepomuk2::Resource& res) { + using namespace Nepomuk2; + + // list tags by listing everything tagged with that tag + if (res.hasType(NAO::Tag())) { + Query::ComparisonTerm term(NAO::hasTag(), Query::ResourceTerm( res ), Query::ComparisonTerm::Equal); + KUrl url = Query::Query(term).toSearchUrl(i18n( "Things tagged '%1'", res.genericLabel())); + url.addQueryItem(QLatin1String("resource"), KUrl(res.uri()).url()); + return url; + } + + // list everything else besides files by querying things related to the resource in some way + // this works for music albums or artists but it would also work for tags + else if (!res.hasType(NFO::FileDataObject())) { + Query::ComparisonTerm term(QUrl(), Query::ResourceTerm(res), Query::ComparisonTerm::Equal); + KUrl url = Query::Query(term).toSearchUrl(res.genericLabel()); + url.addQueryItem(QLatin1String("resource"), KUrl(res.uri()).url()); + return url; + } + + // no forwarding done + return KUrl(); + } +} + +void Nepomuk2::SearchRunner::run( const Plasma::RunnerContext&, const Plasma::QueryMatch& match ) +{ + // If no action was selected, the interface doesn't support multiple + // actions so we simply open the file + if (QAction *a = match.selectedAction()) { + if (a != action("open")) { + match.selectedAction()->trigger(); + return; + } + } + + Nepomuk2::Resource res = match.data().value(); + KUrl url = res.uri(); + KUrl nieUrl = res.property( NIE::url() ).toUrl(); + if( !nieUrl.isEmpty() ) + url = nieUrl; + + // Redirect it in order to avoid showing the user an ugly URL + if(url.scheme() == QLatin1String("nepomuk")) { + KUrl newUrl = redirectionUrl(res); + if(newUrl.isValid()) + url = newUrl; + } + + KService::Ptr preferredServicePtr; + if (res.hasProperty(Nepomuk2::Vocabulary::NIE::mimeType()) && + KUrl(res.property(Nepomuk2::Vocabulary::NIE::url()).toUrl()).isLocalFile()) { + preferredServicePtr = KMimeTypeTrader::self()->preferredService(res.property(Nepomuk2::Vocabulary::NIE::mimeType()).toString()); + } + + if (preferredServicePtr.isNull() || !KRun::run(*preferredServicePtr.constData(), KUrl::List(url), 0)) { + (void)new KRun(url, 0); + } +} + +QList Nepomuk2::SearchRunner::actionsFromMenu(QMenu *menu, const QString &prefix, QObject *parent) +{ + Q_ASSERT(menu); + + QList ret; + foreach (QAction *action, menu->actions()) { + if (QMenu *submenu = action->menu()) { + //Flatten hierarchy and prefix submenu text to all actions in submenu + ret << actionsFromMenu(submenu, action->text(), parent); + } else if (!action->isSeparator() && action->isEnabled()) { + QString text = action->text(); + if (action->isCheckable()) { + if (action->isChecked()) { + text = QString("(%1) %2").arg(QChar(0x2613)).arg(text); + } else { + text = QString("( ) %1").arg(text); + } + } + + if (!prefix.isEmpty()) { + text = QString("%1: %2").arg(prefix).arg(text); + } + text = text.replace(QRegExp("&([\\S])"), "\\1"); + + QAction *a = new QAction(action->icon(), text, parent); + + QObject::connect(a, SIGNAL(triggered(bool)), action, SIGNAL(triggered(bool))); + ret << a; + } + } + return ret; +} + + +QList Nepomuk2::SearchRunner::actionsForMatch(const Plasma::QueryMatch &match) +{ + //Unlike other runners, the actions generated here are likely to see + //little reuse. Hence, we will clear the actions then generate new + //ones per iteration to avoid excessive memory consumption. + qDeleteAll(m_konqActions); + m_konqActions.clear(); + + QList ret; + if (!action("open")) { + addAction("open", KIcon("document-open"), i18n("Open")); + } + ret << action("open"); + + Nepomuk2::Resource res = match.data().value(); + + KUrl url(res.uri()); + KIO::UDSEntry entry; + if (!KIO::NetAccess::stat(url.path(), entry, 0)) { + return QList(); + } + + KFileItemList list; + list << KFileItem(entry, url); + + KFileItemListProperties prop; + prop.setItems(list); + + QMenu dummy; + m_actions->setItemListProperties(prop); + m_actions->addOpenWithActionsTo(&dummy, QString()); + //Add user defined actions + m_actions->addServiceActionsTo(&dummy); + + m_konqActions = actionsFromMenu(&dummy); + + ret << m_konqActions; + + return ret; +} + +QMimeData * Nepomuk2::SearchRunner::mimeDataForMatch(const Plasma::QueryMatch *match) +{ + Nepomuk2::Resource res = match->data().value(); + + QUrl url = res.property(NIE::url()).toUrl(); + + if (!url.isValid()) { + return 0; + } + + QMimeData *result = new QMimeData(); + QList urls; + urls << url; + kDebug() << urls; + result->setUrls(urls); + return result; +} + +namespace { + qreal normalizeScore(double score) { + // no search result is ever a perfect match, NEVER. And mostly, when typing a URL + // the users wants to open that url instead of using the search result. Thus, all + // search results need to have a lower score than URLs which can drop to 0.5 + // And in the end, for 10 results, the score is not that important at the moment. + // This can be improved in the future. + // We go the easy way here and simply cut the score at 0.4 + return qMin(0.4, score); + } +} + +// FIXME: Avoid using the Resource class. Request the extra properties from the query +Plasma::QueryMatch Nepomuk2::SearchRunner::convertToQueryMatch(const Nepomuk2::Query::Result& result) +{ + Plasma::QueryMatch match( this ); + match.setType(Plasma::QueryMatch::PossibleMatch); + match.setRelevance(normalizeScore(result.score())); + + Nepomuk2::Resource res = result.resource(); + + QString type; + QString iconName; + + KMimeType::Ptr mimetype; + if (res.hasProperty(NIE::mimeType())) { + mimetype = KMimeType::mimeType(res.property(NIE::mimeType()).toString()); + } + + const QUrl fileUrl = res.toFile().url(); + if (!mimetype && res.isFile() && fileUrl.isLocalFile() ) { + mimetype = KMimeType::findByUrl(fileUrl); + } + + if (mimetype) { + type = mimetype->comment(); + iconName = mimetype->iconName(); + } + + if(type.isEmpty()) { + type = Nepomuk2::Types::Class(res.type()).label(); + + // The Query engine should typically never return properties, classes or graphs. + // But this doesn't seem to be the case cause of certain bugs in virtuoso + // Earlier versions of Nepomuk avoided this by complex queries which resulted in many + // "Virtuoso is crazy" reports. + // For 4.10, we just try to cover it up and not show the results. + // See nepomuk-core/libnepomukcore/query/query.cpp for more details + // + if(type.contains(QLatin1String("property"), Qt::CaseInsensitive) || + type.contains(QLatin1String("class"), Qt::CaseInsensitive) || + type.contains(QLatin1String("graph"), Qt::CaseInsensitive)) { + return Plasma::QueryMatch( 0 ); + } + iconName = res.genericIcon(); + } + + // HACK: Do not show non-existing files + if( fileUrl.isLocalFile() && !QFile::exists( fileUrl.toLocalFile() ) ) + return Plasma::QueryMatch( 0 ); + + // HACK: Do not show resources which do not have a label + QString label = res.genericLabel(); + if( label.startsWith(QLatin1String("nepomuk:/res")) ) + return Plasma::QueryMatch( 0 ); + + match.setText(res.genericLabel()); + match.setSubtext(type); + match.setIcon(KIcon(iconName.isEmpty() ? QString::fromLatin1("nepomuk") : iconName)); + + match.setData(qVariantFromValue(res)); + match.setId(KUrl(res.uri()).url()); + + return match; +} + + +K_EXPORT_PLASMA_RUNNER(nepomuksearchrunner, Nepomuk2::SearchRunner) + +#include "nepomuksearchrunner.moc" diff --git a/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.h b/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.h new file mode 100644 index 00000000..5a430b27 --- /dev/null +++ b/plasma/generic/runners/nepomuksearch/nepomuksearchrunner.h @@ -0,0 +1,82 @@ +/* This file is part of the Nepomuk Project + Copyright (c) 2008 Sebastian Trueg + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _NEPOMUK_SEARCH_RUNNER_H_ +#define _NEPOMUK_SEARCH_RUNNER_H_ + +#include + +#include +#include +#include + +#include + +class KFileItemActions; + +class QAction; + +namespace Nepomuk2 { + + class SearchRunner : public Plasma::AbstractRunner + { + Q_OBJECT + + public: + SearchRunner( QObject* parent, const QVariantList& args ); + SearchRunner( QObject* parent, const QString& serviceId = QString() ); + ~SearchRunner(); + + void match( Plasma::RunnerContext& context ); + void run( const Plasma::RunnerContext& context, const Plasma::QueryMatch& action ); + + QList actionsForMatch(const Plasma::QueryMatch &match); + + protected Q_SLOTS: + void init(); + QMimeData *mimeDataForMatch(const Plasma::QueryMatch *match); + + private: + /** + * Returns a list of all actions in the given QMenu + * This method flattens the hierarchy of the menu by prefixing the + * text of all actions in a submenu with the submenu title. + * + * @param menu the QMenu storing the actions + * @param prefix text to display before the text of all actions in the menu + * @param parent QObject to be passed as parent of all the actions in the list + * + * @since 4.4 + */ + QList actionsFromMenu(QMenu *menu, const QString &prefix = QString(), QObject *parent = 0); + + /** + * Converts a Nepomuk Query Result to a Plasma::QueryMatch, which can be used + * in the runner context + */ + Plasma::QueryMatch convertToQueryMatch( const Query::Result& result ); + + QMutex m_mutex; + QWaitCondition m_waiter; + + KFileItemActions *m_actions; + QList m_konqActions; + }; +} + +#endif diff --git a/plasma/generic/runners/nepomuksearch/plasma-runner-nepomuksearch.desktop b/plasma/generic/runners/nepomuksearch/plasma-runner-nepomuksearch.desktop new file mode 100644 index 00000000..2261719c --- /dev/null +++ b/plasma/generic/runners/nepomuksearch/plasma-runner-nepomuksearch.desktop @@ -0,0 +1,125 @@ +[Desktop Entry] +Name=Nepomuk Desktop Search +Name[bs]=Nepomuk pretraga desktopa +Name[ca]=Cerca d'escriptori del Nepomuk +Name[ca@valencia]=Cerca d'escriptori del Nepomuk +Name[cs]=Vyhledávání v počítači pomocí Nepomuku +Name[da]=Nepomuk skrivebordssøgning +Name[de]=Nepomuk-Desktop-Suche +Name[el]=Αναζήτηση επιφάνειας εργασίας Nepomuk +Name[en_GB]=Nepomuk Desktop Search +Name[es]=Buscador para escritorio Nepomuk +Name[et]=Nepomuki töölauaotsing +Name[eu]=Nepomuk mahaigainaren bilatzailea +Name[fi]=Nepomuk-työpöytähaku +Name[fr]=Rechercher sur le bureau avec Nepomuk +Name[ga]=Cuardach Deisce Nepomuk +Name[gl]=Buscas no escritorio con Nepomuk +Name[he]=חיפוש בשולחן עבודה באמצעות Nepomuk +Name[hu]=Nepomuk asztali keresés +Name[ia]=Cerca de scriptorio de Nepomuk +Name[kk]=Nepomuk іздеуі +Name[km]=ស្វែងរក​ផ្ទៃតុ Nepomuk +Name[ko]=Nepomuk 데스크톱 검색 +Name[lt]=Nepomuk darbastalio paieška +Name[mr]=निपोमुक डेस्कटॉप शोध +Name[nb]=Nepomuk skrivebordssøk +Name[nds]=Nepomuk-Schriefdischsöök +Name[nl]=Nepomuk Bureaublad-zoekopdracht +Name[pa]=ਨਿਮੁਪੂਕ ਡੈਸਕਟਾਪ ਖੋਜ +Name[pl]=Wyszukiwanie na pulpicie Nepomuk +Name[pt]=Pesquisa no Ambiente de Trabalho Nepomuk +Name[pt_BR]=Pesquisa no desktop do Nepomuk +Name[ro]=Căutare de birou Nepomuk +Name[ru]=Служба поиска Nepomuk +Name[sk]=Hľadanie na ploche Nepomuk +Name[sl]=Namizno iskanje Nepomuk +Name[sr]=Непомукова претрага површи +Name[sr@ijekavian]=Непомукова претрага површи +Name[sr@ijekavianlatin]=Nepomukova pretraga površi +Name[sr@latin]=Nepomukova pretraga površi +Name[sv]=Nepomuk skrivbordssökning +Name[tr]=Nepomuk Masaüstü Araması +Name[uk]=Стільничний пошук Nepomuk +Name[x-test]=xxNepomuk Desktop Searchxx +Name[zh_CN]=Nepomuk 桌面搜索 +Name[zh_TW]=Nepomuk 桌面搜尋 +Comment=KRunner which performs desktop searches via Nepomuk +Comment[ar]=مشغل لـKRunner ينفذ البحث لسطح المكتب بواسطة نبومك +Comment[ast]=Krunner executa guetes nel escritoriu vía Nepomuk +Comment[be@latin]=Modul „KRunner”, jaki šukaje ŭ kamputary praz systemu „Nepomuk” +Comment[bg]=KRunner търси с помощта на Nepomuk +Comment[bs]=Izvođač za pretraživanje radne površi putem Nepomuka +Comment[ca]=El KRunner executa cerques d'escriptori via el Nepomuk +Comment[ca@valencia]=El KRunner executa cerques d'escriptori via el Nepomuk +Comment[cs]=KRunner vyhledává v počítači prostřednictvím Nepomuku +Comment[da]=KRunner som udfører skrivebordssøgning via Nepomuk +Comment[de]=Starter, der eine Desktop-Suche mit Nepomuk ausführt. +Comment[el]=KRunner που εκτελεί αναζητήσεις επιφάνειας εργασίας μέσω του Nepomuk +Comment[en_GB]=KRunner which performs desktop searches via Nepomuk +Comment[es]=Krunner que ejecuta búsquedas en el escritorio vía Nepomuk +Comment[et]=KRunner, mis sooritab töölauaotsinguid Nepomuki vahendusel +Comment[eu]=KRunner, Nepomuk bidez mahaigain-bilaketak egiten dituena +Comment[fi]=KRunner, joka suorittaa työpöytähakuja Nepomuk-ohjelman kautta +Comment[fr]=Krunner qui réalise des recherches sur le bureau grâce à Nepomuk +Comment[fy]=KRunner dy sykopdrachten fia Nepomuk útfiert +Comment[ga]=KRunner a chuardaíonn an deasc le Nepomuk +Comment[gl]=Un KRunner que fai buscas no escritorio mediante Nepomuk +Comment[gu]=KRunner જે નેપોમુક વડે ડેસ્કટોપ શોધ કરે છે +Comment[he]=‏KRunner אשר מבצע חיפוש בשולחן העבודה באמצעות Nepomuk +Comment[hi]=के-रनर जो नेपोमक के जरिए डेस्कटॉप खोज करता है +Comment[hne]=के-रनर जउन हर नेपोमक के साथ डेस्कटाप सर्च करथे +Comment[hr]=KRunner koji izvodi pretragu računala preko Nepomuka +Comment[hu]=Kezelőelem kereséshez a Nepomukon keresztül +Comment[ia]=KRunner que il exeque cercas de scriptorio via Nepomuk +Comment[id]=KRunner yang melakukan pencarian desktop via Nepomuk +Comment[is]=KRunner keyrsluforrit fyrir skjáborðsleit með Nemopuk +Comment[ja]=Nepomuk を介してデスクトップ検索を行う KRunner +Comment[kk]=Nepomuk арқылы іздеуді орындайтын KRunner бағдарламасы +Comment[km]=KRunner ដែល​​អនុវត្ត​ការ​ស្វែងរក​ផ្ទៃតុ​តាមរយៈ Nepomuk +Comment[kn]=ನೆಪೋಮುಕ್ ಮೂಲಕ KRunner ಗಣಕತೆರೆಯಲ್ಲಿ ಹುಡುಕುವ ಕೆಲಸವನ್ನು ಮಾಡುತ್ತದೆ +Comment[ko]=Nepomuk을 통해 데스크톱을 검색하는 KRunner +Comment[lt]=KRunner atliekantis darbastalio paiešką per Nepomuk +Comment[lv]=KRunner, kas veic meklēšanu ar Nepomuk +Comment[ml]=നെപ്പോമുക്ക് വഴി പണിയിടത്തില്‍ തെരച്ചില്‍ നടത്തുന്ന കെറണ്ണര്‍ +Comment[mr]=नेपोमुक द्वारे डेस्कटॉप शोध कार्यान्वित करणारे के-रनर +Comment[nb]=KRunner som utfører skrivebordssøk via Nepomuk +Comment[nds]=KRunner-Moduul, mit dat sik Schriefdischsöken över Nepomuk utföhren laat +Comment[nl]=KRunner die zoekopdrachten via Nepomuk uitvoert +Comment[nn]=KRunner-program som utfører skrivebordssøk gjennom Nepomuk +Comment[pa]=ਕੇ-ਰਨਰ, ਜੋ ਕਿ ਨਿਪੁਮੂਕ ਰਾਹੀਂ ਡੈਸਕਟਾਪ ਖੋਜ ਕਰਦਾ ਹੈ +Comment[pl]=KRunner, który dokonuje wyszukiwania za pomocą Nepomuka +Comment[pt]=Um KRunner que efectua pesquisas no ambiente de trabalho com o Nepomuk +Comment[pt_BR]=KRunner que faz pesquisas no desktop com o Nepomuk +Comment[ro]=Un KRunner ce execută căutări de birou prin Nepomuk +Comment[ru]=Поиск данных с помощью Nepomuk +Comment[si]=Nepomuk යොදාගෙන වැඩතල සෙවුම් ඉටුකරන KRunner +Comment[sk]=KRunner, ktorý prehľadáva plochu pomocou Nepomuku +Comment[sl]=Zaganjalnik, ki prek Nepomuka opravi iskanje po namizju +Comment[sr]=Извођач за претраживање радне површи путем Непомука +Comment[sr@ijekavian]=Извођач за претраживање радне површи путем Непомука +Comment[sr@ijekavianlatin]=Izvođač za pretraživanje radne površi putem Nepomuka +Comment[sr@latin]=Izvođač za pretraživanje radne površi putem Nepomuka +Comment[sv]=Programkörning som utför skrivbordssökningar via Nepomuk +Comment[ta]=KRunner which performs desktop searches via Nepomuk +Comment[te]=నెపోమక్ ద్వారా రంగస్థల శోధనలను జరిపే KRunner +Comment[th]=KRunner สามารถค้นหาบนพื้นที่ทำงานผ่าน Nepomuk +Comment[tr]=Nepomuk üzerinden masaüstü araması yapan KRunner +Comment[ug]=KRunner ئارقىلىق KRunner ئۈستەلئۈستى ئىزدەش ئىجراچىسى +Comment[uk]=KRunner, який виконуватиме стільничний пошук за допомогою Nepomuk +Comment[vi]=KRunner thực hiện tìm kiếm máy tính qua Nepomuk +Comment[wa]=KRunner ki fwait des cweraedjes sol sicribanne avou Nepomuk +Comment[x-test]=xxKRunner which performs desktop searches via Nepomukxx +Comment[zh_CN]=通过 Nepomuk 执行桌面搜索的运行器 +Comment[zh_TW]=透過 Nepomuk 執行桌面搜尋的 KRunner 程式。 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=nepomuk +X-KDE-Library=krunner_nepomuksearchrunner +X-KDE-PluginInfo-Author=Sebastian Trueg +X-KDE-PluginInfo-Email=trueg@kde.org +X-KDE-PluginInfo-Name=nepomuksearch +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/places/CMakeLists.txt b/plasma/generic/runners/places/CMakeLists.txt new file mode 100644 index 00000000..8b0960e0 --- /dev/null +++ b/plasma/generic/runners/places/CMakeLists.txt @@ -0,0 +1,18 @@ + +set(krunner_placesrunner_SRCS + placesrunner.cpp +) + +kde4_add_plugin(krunner_placesrunner ${krunner_placesrunner_SRCS}) +target_link_libraries( + krunner_placesrunner + ${KDE4_KFILE_LIBS} + ${KDE4_SOLID_LIBS} + ${KDE4_KIO_LIBS} + ${KDE4_PLASMA_LIBS} + ) + +install(TARGETS krunner_placesrunner DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-places.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/places/Messages.sh b/plasma/generic/runners/places/Messages.sh new file mode 100755 index 00000000..1ef74d99 --- /dev/null +++ b/plasma/generic/runners/places/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_placesrunner.pot diff --git a/plasma/generic/runners/places/placesrunner.cpp b/plasma/generic/runners/places/placesrunner.cpp new file mode 100644 index 00000000..7fca5cd3 --- /dev/null +++ b/plasma/generic/runners/places/placesrunner.cpp @@ -0,0 +1,170 @@ +/* + * Copyright 2008 David Edmundson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "placesrunner.h" + +#include +#include +#include + +#include +#include +#include +#include + +//Q_DECLARE_METATYPE(Plasma::RunnerContext) +PlacesRunner::PlacesRunner(QObject* parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args) +{ +// qRegisterMetaType + Q_UNUSED(args) + setObjectName( QLatin1String("Places" )); + Plasma::RunnerSyntax defaultSyntax(i18n("places"), i18n("Lists all file manager locations")); + setDefaultSyntax(defaultSyntax); + addSyntax(defaultSyntax); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds file manager locations that match :q:"))); + + // ensure the bookmarkmanager, etc. in the places model gets creates created in the main thread + // otherwise crashes ensue + m_helper = new PlacesRunnerHelper(this); +} + +PlacesRunner::~PlacesRunner() +{ +} + +void PlacesRunner::match(Plasma::RunnerContext &context) +{ + if (QThread::currentThread() == QCoreApplication::instance()->thread()) { + // from the main thread + //kDebug() << "calling"; + m_helper->match(&context); + } else { + // from the non-gui thread + //kDebug() << "emitting"; + emit doMatch(&context); + } + //m_helper->match(c); +} + +PlacesRunnerHelper::PlacesRunnerHelper(PlacesRunner *runner) + : QObject(runner) +{ + Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread()); + connect(runner, SIGNAL(doMatch(Plasma::RunnerContext*)), + this, SLOT(match(Plasma::RunnerContext*)), + Qt::BlockingQueuedConnection); +} + +void PlacesRunnerHelper::match(Plasma::RunnerContext *c) +{ + Plasma::RunnerContext &context = *c; + if (!context.isValid()) { + return; + } + + const QString term = context.query(); + + if (term.length() < 3) { + return; + } + + QList matches; + const bool all = term.compare(i18n("places"), Qt::CaseInsensitive) == 0; + for (int i = 0; i <= m_places.rowCount(); i++) { + QModelIndex current_index = m_places.index(i, 0); + Plasma::QueryMatch::Type type = Plasma::QueryMatch::NoMatch; + qreal relevance = 0; + + const QString text = m_places.text(current_index); + if ((all && !text.isEmpty()) || text.compare(term, Qt::CaseInsensitive) == 0) { + type = Plasma::QueryMatch::ExactMatch; + relevance = all ? 0.9 : 1.0; + } else if (text.contains(term, Qt::CaseInsensitive)) { + type = Plasma::QueryMatch::PossibleMatch; + relevance = 0.7; + } + + if (type != Plasma::QueryMatch::NoMatch) { + Plasma::QueryMatch match(static_cast(parent())); + match.setType(type); + match.setRelevance(relevance); + match.setIcon(KIcon(m_places.icon(current_index))); + match.setText(text); + + //if we have to mount it set the device udi instead of the URL, as we can't open it directly + KUrl url; + if (m_places.isDevice(current_index) && m_places.setupNeeded(current_index)) { + url = m_places.deviceForIndex(current_index).udi(); + } else { + url = m_places.url(current_index); + } + + match.setData(url); + match.setId(url.prettyUrl()); + matches << match; + } + } + + context.addMatches(term, matches); +} + + +void PlacesRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action) +{ + Q_UNUSED(context); + //I don't just pass the model index because the list could change before the user clicks on it, which would make everything go wrong. Ideally we don't want things to go wrong. + if (action.data().canConvert()) { + new KRun(action.data().value().url(), 0); + } else if (action.data().canConvert()) { + //search our list for the device with the same udi, then set it up (mount it). + QString deviceUdi = action.data().toString(); + + // gets deleted in setupComplete + KFilePlacesModel *places = new KFilePlacesModel(this); + connect(places, SIGNAL(setupDone(QModelIndex,bool)), SLOT(setupComplete(QModelIndex,bool))); + bool found = false; + + for (int i = 0; i <= places->rowCount();i++) { + QModelIndex current_index = places->index(i, 0); + if (places->isDevice(current_index) && places->deviceForIndex(current_index).udi() == deviceUdi) { + places->requestSetup(current_index); + found = true; + break; + } + } + + if (!found) { + delete places; + } + } +} + +//if a device needed mounting, this slot gets called when it's finished. +void PlacesRunner::setupComplete(QModelIndex index, bool success) +{ + KFilePlacesModel *places = qobject_cast(sender()); + //kDebug() << "setup complete" << places << sender(); + if (success && places) { + new KRun(places->url(index), 0); + places->deleteLater(); + } +} + +#include "placesrunner.moc" diff --git a/plasma/generic/runners/places/placesrunner.h b/plasma/generic/runners/places/placesrunner.h new file mode 100644 index 00000000..94efd3ec --- /dev/null +++ b/plasma/generic/runners/places/placesrunner.h @@ -0,0 +1,66 @@ +/* + * Copyright 2008 David Edmundson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLACESRUNNER_H +#define PLACESRUNNER_H + + +#include +#include + +class PlacesRunner; + +class PlacesRunnerHelper : public QObject +{ + Q_OBJECT + +public: + PlacesRunnerHelper(PlacesRunner *runner); + +public Q_SLOTS: + void match(Plasma::RunnerContext *context); + +private: + KFilePlacesModel m_places; +}; + +class PlacesRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + +public: + PlacesRunner(QObject* parent, const QVariantList &args); + ~PlacesRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + +Q_SIGNALS: + void doMatch(Plasma::RunnerContext *context); + +private slots: + void setupComplete(QModelIndex, bool); + +private: + PlacesRunnerHelper *m_helper; +}; + +K_EXPORT_PLASMA_RUNNER(placesrunner, PlacesRunner) + +#endif diff --git a/plasma/generic/runners/places/plasma-runner-places.desktop b/plasma/generic/runners/places/plasma-runner-places.desktop new file mode 100644 index 00000000..ddec1629 --- /dev/null +++ b/plasma/generic/runners/places/plasma-runner-places.desktop @@ -0,0 +1,133 @@ +[Desktop Entry] +Name=Places +Name[ar]=الأماكن +Name[ast]=Llugares +Name[be@latin]=Miescy +Name[bg]=Места +Name[bn]=স্থান +Name[bs]=mjesta +Name[ca]=Llocs +Name[ca@valencia]=Llocs +Name[cs]=Místa +Name[csb]=Place +Name[da]=Steder +Name[de]=Orte +Name[el]=Τοποθεσίες +Name[en_GB]=Places +Name[eo]=Lokoj +Name[es]=Lugares +Name[et]=Asukohad +Name[eu]=Tokiak +Name[fi]=Sijainnit +Name[fr]=Emplacements +Name[fy]=Places +Name[ga]=Áiteanna +Name[gl]=Lugares +Name[gu]=જગ્યાઓ +Name[he]=מקומות +Name[hi]=स्थान +Name[hne]=प्लेसेस +Name[hr]=Mjesta +Name[hu]=Helyek +Name[ia]=Placias +Name[id]=Tempat +Name[is]=Staðir +Name[it]=Risorse +Name[ja]=場所 +Name[ka]=ადგილები +Name[kk]=Орындар +Name[km]=កន្លែង +Name[kn]=ಸ್ಥಳಗಳು +Name[ko]=위치 +Name[ku]=Cih +Name[lt]=Vietos +Name[lv]=Vietas +Name[mai]=स्थान +Name[mk]=Места +Name[ml]=സ്ഥലങ്ങള്‍ +Name[mr]=जागा +Name[nb]=Steder +Name[nds]=Steden +Name[nl]=Locaties +Name[nn]=Stader +Name[or]=ସ୍ଥାନଗୁଡ଼ିକ +Name[pa]=ਥਾਵਾਂ +Name[pl]=Miejsca +Name[pt]=Locais +Name[pt_BR]=Locais +Name[ro]=Locuri +Name[ru]=Точки входа +Name[si]=ස්ථාන +Name[sk]=Miesta +Name[sl]=Mesta +Name[sr]=места +Name[sr@ijekavian]=мјеста +Name[sr@ijekavianlatin]=mjesta +Name[sr@latin]=mesta +Name[sv]=Platser +Name[ta]=Places +Name[tg]=Ҷойҳо +Name[th]=ที่หลัก ๆ +Name[tr]=Konumlar +Name[ug]=ئورۇنلار +Name[uk]=Місця +Name[wa]=Plaeces +Name[x-test]=xxPlacesxx +Name[zh_CN]=位置 +Name[zh_TW]=地方 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=user-home +Comment=Open devices and folder bookmarks +Comment[bs]=Otvoreni uređaji i mape favorita +Comment[ca]=Obre els punts dels dispositius i dels preferits +Comment[ca@valencia]=Obri els punts dels dispositius i dels preferits +Comment[cs]=Otevřít záložky zařízení a složek +Comment[da]=Åbn enheder og mappebogmærker +Comment[de]=Geräte und Lesezeichen für Ordner öffnen +Comment[el]=Άνοιγμα σελιδοδεικτών συσκευών και φακέλων +Comment[en_GB]=Open devices and folder bookmarks +Comment[es]=Abrir dispositivos y marcadores de carpetas +Comment[et]=Seadmete ja kataloogide järjehoidjate avamine +Comment[eu]=Ireki gailuen eta karpeten laster-markak +Comment[fi]=Avaa laitteita ja kansiokirjanmerkkejä +Comment[fr]=Ouvrir les signets de périphériques et de dossiers +Comment[ga]=Oscail gléasanna agus leabharmharcanna fillteáin +Comment[gl]=Abre dispositivos e cartafoles de marcadores +Comment[he]=פותח סימניות התקנים ותיקיות +Comment[hu]=Eszközökre és mappákra mutató könyvjelzők megnyitása +Comment[ia]=Aperi dispositivos e marcatores de libros de dossieres +Comment[it]=Apre segnalibri di dispositivi e cartelle +Comment[kk]=Құрылғы мен қапшықтардың бетбелгілерін ашу +Comment[km]=បើក​ឧបករណ៍ និង​ចំណាំ​ថត +Comment[ko]=장치와 폴더 책갈피 열기 +Comment[lt]=Atverti įrenginių ir aplankų žymeles +Comment[mr]=साधने व संचयीका ओळखचिन्ह उघडा +Comment[nb]=Åpne bokmerker for enheter og mapper +Comment[nds]=Reedschappen un Orner-Leestekens opmaken +Comment[nl]=Apparaten- en mappenbladwijzers openen +Comment[pa]=ਜੰਤਰ ਅਤੇ ਫੋਲਡਰ ਬੁੱਕਮਾਰਕ ਖੋਲ੍ਹੋ +Comment[pl]=Otwieranie urządzeń i zakładek katalogów +Comment[pt]=Abrir os favoritos dos dispositivos e pastas +Comment[pt_BR]=Abre os favoritos dos dispositivos e pastas +Comment[ro]=Deschide semne de carte pentru dispozitive și dosare +Comment[ru]=Переход по закладкам для устройств и папок +Comment[sk]=Otváranie záložiek priečinkov a zariadení +Comment[sl]=Odpiranje naprav in map, ki so med zaznamki +Comment[sr]=Отварајте обележиваче уређаја и фасцикли +Comment[sr@ijekavian]=Отварајте обиљеживаче уређаја и фасцикли +Comment[sr@ijekavianlatin]=Otvarajte obilježivače uređaja i fascikli +Comment[sr@latin]=Otvarajte obeleživače uređaja i fascikli +Comment[sv]=Öppna enhets- och katalogbokmärken +Comment[tr]=Aygıt ve dizin yer imlerini aç +Comment[uk]=Відкриття пристроїв та закладок на теки +Comment[x-test]=xxOpen devices and folder bookmarksxx +Comment[zh_CN]=打开设备和文件夹书签 +Comment[zh_TW]=開啟裝置與資料夾書籤 +X-KDE-Library=krunner_placesrunner +X-KDE-PluginInfo-Author=David Edmundson +X-KDE-PluginInfo-Email=kde@davidedmundson.co.uk +X-KDE-PluginInfo-Name=places +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/powerdevil/CMakeLists.txt b/plasma/generic/runners/powerdevil/CMakeLists.txt new file mode 100644 index 00000000..d1901be5 --- /dev/null +++ b/plasma/generic/runners/powerdevil/CMakeLists.txt @@ -0,0 +1,15 @@ +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR} +) + +set(krunner_powerdevil_SRCS + PowerDevilRunner.cpp +) + +kde4_add_plugin(krunner_powerdevil ${krunner_powerdevil_SRCS}) +target_link_libraries(krunner_powerdevil ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_SOLID_LIBS}) + +install(TARGETS krunner_powerdevil DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-runner-powerdevil.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/powerdevil/Messages.sh b/plasma/generic/runners/powerdevil/Messages.sh new file mode 100755 index 00000000..99ae5dce --- /dev/null +++ b/plasma/generic/runners/powerdevil/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_powerdevil.pot + diff --git a/plasma/generic/runners/powerdevil/PowerDevilRunner.cpp b/plasma/generic/runners/powerdevil/PowerDevilRunner.cpp new file mode 100644 index 00000000..4085a0fd --- /dev/null +++ b/plasma/generic/runners/powerdevil/PowerDevilRunner.cpp @@ -0,0 +1,329 @@ +/*************************************************************************** + * Copyright 2008 by Dario Freddi * + * Copyright 2008 by Sebastian Kügler * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "PowerDevilRunner.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +PowerDevilRunner::PowerDevilRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args), + m_shortestCommand(1000) +{ + Q_UNUSED(args) + qDBusRegisterMetaType< StringStringMap >(); + + setObjectName( QLatin1String("PowerDevil" )); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | + Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Help); + updateStatus(); + initUpdateTriggers(); + + /* Let's define all the words here. m_words contains all the words that + * will eventually trigger a match in the runner. + */ + + QStringList commands; + commands << i18nc("Note this is a KRunner keyword", "power profile") + << i18nc("Note this is a KRunner keyword", "suspend") + << i18nc("Note this is a KRunner keyword", "sleep") + << i18nc("Note this is a KRunner keyword", "hibernate") + << i18nc("Note this is a KRunner keyword", "to disk") + << i18nc("Note this is a KRunner keyword", "to ram") + << i18nc("Note this is a KRunner keyword", "screen brightness") + << i18nc("Note this is a KRunner keyword", "dim screen"); + + foreach (const QString &command, commands) { + if (command.length() < m_shortestCommand) { + m_shortestCommand = command.length(); + } + } +} + +void PowerDevilRunner::updateSyntaxes() +{ + QList syntaxes; + syntaxes.append(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "power profile"), + i18n("Lists all power profiles and allows them to be activated"))); + syntaxes.append(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "suspend"), + i18n("Lists system suspend (e.g. sleep, hibernate) options " + "and allows them to be activated"))); + + QSet< Solid::PowerManagement::SleepState > states = Solid::PowerManagement::supportedSleepStates(); + + if (states.contains(Solid::PowerManagement::SuspendState)) { + Plasma::RunnerSyntax sleepSyntax(i18nc("Note this is a KRunner keyword", "sleep"), + i18n("Suspends the system to RAM")); + sleepSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "to ram")); + syntaxes.append(sleepSyntax); + } + + if (states.contains(Solid::PowerManagement::HibernateState)) { + Plasma::RunnerSyntax hibernateSyntax(i18nc("Note this is a KRunner keyword", "hibernate"), + i18n("Suspends the system to disk")); + hibernateSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "to disk")); + syntaxes.append(hibernateSyntax); + } + + Plasma::RunnerSyntax brightnessSyntax(i18nc("Note this is a KRunner keyword", "screen brightness"), + // xgettext:no-c-format + i18n("Lists screen brightness options or sets it to the brightness defined by :q:; " + "e.g. screen brightness 50 would dim the screen to 50% maximum brightness")); + brightnessSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "dim screen")); + syntaxes.append(brightnessSyntax); + setSyntaxes(syntaxes); +} + +PowerDevilRunner::~PowerDevilRunner() +{ +} + +void PowerDevilRunner::initUpdateTriggers() +{ + // Also receive updates triggered through the DBus + QDBusConnection dbus = QDBusConnection::sessionBus(); + if (dbus.interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + if (!dbus.connect("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", + "profileChanged", this, SLOT(updateStatus()))) { + kDebug() << "error!"; + } + if (!dbus.connect("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", + "configurationReloaded", this, SLOT(updateStatus()))) { + kDebug() << "error!"; + } + } +} + +void PowerDevilRunner::updateStatus() +{ + // Profiles and their icons + { + KSharedConfigPtr profilesConfig = KSharedConfig::openConfig("powerdevil2profilesrc", KConfig::SimpleConfig); + // Request profiles to the daemon + QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "availableProfiles"); + QDBusPendingReply< StringStringMap > reply = QDBusConnection::sessionBus().asyncCall(call); + reply.waitForFinished(); + + if (!reply.isValid()) { + kDebug() << "Error contacting the daemon!"; + return; + } + + m_availableProfiles = reply.value(); + + if (m_availableProfiles.isEmpty()) { + kDebug() << "No available profiles!"; + return; + } + + for (StringStringMap::const_iterator i = m_availableProfiles.constBegin(); i != m_availableProfiles.constEnd(); ++i) { + KConfigGroup settings(profilesConfig, i.key()); + if (settings.readEntry< QString >("icon", QString()).isEmpty()) { + m_profileIcon[i.key()] = "preferences-system-power-management"; + } else { + m_profileIcon[i.key()] = settings.readEntry< QString >("icon", QString()); + } + } + } + + updateSyntaxes(); +} + + +bool PowerDevilRunner::parseQuery(const QString& query, const QList& rxList, QString& parameter) const +{ + foreach (const QRegExp& rx, rxList) { + if (rx.exactMatch(query)) { + parameter = rx.cap(1).trimmed(); + return true; + } + } + return false; +} + +void PowerDevilRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + if (term.length() < m_shortestCommand) { + return; + } + + QList matches; + + QString parameter; + + if (parseQuery(term, + QList() << QRegExp(i18nc("Note this is a KRunner keyword; %1 is a parameter", "power profile %1", "(.*)"), Qt::CaseInsensitive) + << QRegExp(i18nc("Note this is a KRunner keyword", "power profile"), Qt::CaseInsensitive), + parameter)) { + for (StringStringMap::const_iterator i = m_availableProfiles.constBegin(); i != m_availableProfiles.constEnd(); ++i) { + if (!parameter.isEmpty()) { + if (!i.value().startsWith(parameter, Qt::CaseInsensitive)) { + continue; + } + } + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setIcon(KIcon(m_profileIcon[i.key()])); + match.setText(i18n("Set Profile to '%1'", i.value())); + match.setData(i.key()); + match.setRelevance(1); + match.setId("ProfileChange "+ i.key()); + matches.append(match); + } + } else if (parseQuery(term, + QList() << QRegExp(i18nc("Note this is a KRunner keyword; %1 is a parameter", "screen brightness %1", "(.*)"), Qt::CaseInsensitive) + << QRegExp(i18nc("Note this is a KRunner keyword", "screen brightness"), Qt::CaseInsensitive) + << QRegExp(i18nc("Note this is a KRunner keyword; %1 is a parameter", "dim screen %1", "(.*)"), Qt::CaseInsensitive) + << QRegExp(i18nc("Note this is a KRunner keyword", "dim screen"), Qt::CaseInsensitive), + parameter)) { + if (!parameter.isEmpty()) { + bool test; + int b = parameter.toInt(&test); + if (test) { + int brightness = qBound(0, b, 100); + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setIcon(KIcon("preferences-system-power-management")); + match.setText(i18n("Set Brightness to %1", brightness)); + match.setData(brightness); + match.setRelevance(1); + match.setId("BrightnessChange"); + matches.append(match); + } + } else { + Plasma::QueryMatch match1(this); + match1.setType(Plasma::QueryMatch::ExactMatch); + match1.setIcon(KIcon("preferences-system-power-management")); + match1.setText(i18n("Dim screen totally")); + match1.setRelevance(1); + match1.setId("DimTotal"); + matches.append(match1); + + Plasma::QueryMatch match2(this); + match2.setType(Plasma::QueryMatch::ExactMatch); + match2.setIcon(KIcon("preferences-system-power-management")); + match2.setText(i18n("Dim screen by half")); + match2.setRelevance(1); + match2.setId("DimHalf"); + matches.append(match2); + + Plasma::QueryMatch match3(this); + match3.setType(Plasma::QueryMatch::ExactMatch); + match3.setIcon(KIcon("video-display")); + match3.setText(i18n("Turn off screen")); + match3.setRelevance(1); + match3.setId("TurnOffScreen"); + matches.append(match3); + } + } else if (term.compare(i18nc("Note this is a KRunner keyword", "suspend"), Qt::CaseInsensitive) == 0) { + QSet< Solid::PowerManagement::SleepState > states = Solid::PowerManagement::supportedSleepStates(); + + if (states.contains(Solid::PowerManagement::SuspendState)) { + addSuspendMatch(Solid::PowerManagement::SuspendState, matches); + } + + if (states.contains(Solid::PowerManagement::HibernateState)) { + addSuspendMatch(Solid::PowerManagement::HibernateState, matches); + } + } else if (term.compare(i18nc("Note this is a KRunner keyword", "sleep"), Qt::CaseInsensitive) == 0 || + term.compare(i18nc("Note this is a KRunner keyword", "to ram"), Qt::CaseInsensitive) == 0) { + addSuspendMatch(Solid::PowerManagement::SuspendState, matches); + } else if (term.compare(i18nc("Note this is a KRunner keyword", "hibernate"), Qt::CaseInsensitive) == 0 || + term.compare(i18nc("Note this is a KRunner keyword", "to disk"), Qt::CaseInsensitive) == 0) { + addSuspendMatch(Solid::PowerManagement::HibernateState, matches); + } + + if (!matches.isEmpty()) { + context.addMatches(term, matches); + } +} + +void PowerDevilRunner::addSuspendMatch(int value, QList &matches) +{ + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + + switch ((Solid::PowerManagement::SleepState)value) { + case Solid::PowerManagement::SuspendState: + case Solid::PowerManagement::StandbyState: + match.setIcon(KIcon("system-suspend")); + match.setText(i18n("Suspend to RAM")); + match.setRelevance(1); + break; + case Solid::PowerManagement::HibernateState: + match.setIcon(KIcon("system-suspend-hibernate")); + match.setText(i18n("Suspend to Disk")); + match.setRelevance(0.99); + break; + } + + match.setData(value); + match.setId("Suspend"); + matches.append(match); +} + +void PowerDevilRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context) + + QDBusInterface iface("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement"); + if (match.id().startsWith("PowerDevil_ProfileChange")) { + iface.asyncCall("loadProfile", match.data().toString()); + } else if (match.id() == "PowerDevil_BrightnessChange") { + iface.asyncCall("setBrightness", match.data().toInt()); + } else if (match.id() == "PowerDevil_DimTotal") { + iface.asyncCall("setBrightness", 0); + } else if (match.id() == "PowerDevil_DimHalf") { + iface.asyncCall("setBrightness", -2); + } else if (match.id() == "PowerDevil_TurnOffScreen") { + // FIXME: Maybe this should be even removed + // iface.asyncCall("turnOffScreen"); + } else if (match.id().startsWith("PowerDevil_Suspend")) { + switch ((Solid::PowerManagement::SleepState)match.data().toInt()) { + case Solid::PowerManagement::SuspendState: + case Solid::PowerManagement::StandbyState: + Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, 0, 0); + break; + case Solid::PowerManagement::HibernateState: + Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, 0, 0); + break; + } + } +} + +#include "PowerDevilRunner.moc" diff --git a/plasma/generic/runners/powerdevil/PowerDevilRunner.h b/plasma/generic/runners/powerdevil/PowerDevilRunner.h new file mode 100644 index 00000000..90cce613 --- /dev/null +++ b/plasma/generic/runners/powerdevil/PowerDevilRunner.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef POWERDEVILRUNNER_H +#define POWERDEVILRUNNER_H + +#include +#include + +typedef QMap< QString, QString > StringStringMap; + +class PowerDevilRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + PowerDevilRunner( QObject *parent, const QVariantList &args ); + ~PowerDevilRunner(); + + void match( Plasma::RunnerContext &context ); + void run( const Plasma::RunnerContext &context, const Plasma::QueryMatch &action ); + + private slots: + void updateStatus(); + + private: + void initUpdateTriggers(); + void updateSyntaxes(); + void addSuspendMatch(int value, QList &matches); + bool parseQuery(const QString& query, const QList& rxList, QString& parameter) const; + + StringStringMap m_availableProfiles; + QHash m_profileIcon; + QHash m_suspendMethods; + QHash m_synonyms; + + int m_shortestCommand; +}; + +Q_DECLARE_METATYPE(StringStringMap) +K_EXPORT_PLASMA_RUNNER( powerdevil, PowerDevilRunner ) + +#endif diff --git a/plasma/generic/runners/powerdevil/plasma-runner-powerdevil.desktop b/plasma/generic/runners/powerdevil/plasma-runner-powerdevil.desktop new file mode 100644 index 00000000..e0269f9a --- /dev/null +++ b/plasma/generic/runners/powerdevil/plasma-runner-powerdevil.desktop @@ -0,0 +1,159 @@ +[Desktop Entry] +Comment=Basic Power Management Operations +Comment[ar]=عمليات إدارة الطاقة الأساسية +Comment[ast]=Operaciones básiques de xestión de la batería +Comment[be@latin]=Prostyja aperacyi dla kiravańnia enerhijaj +Comment[bg]=Основни операции по захранването +Comment[bs]=Osnovni postupci upravljanja napajanjem +Comment[ca]=Operacions bàsiques de gestió d'energia +Comment[ca@valencia]=Operacions bàsiques de gestió d'energia +Comment[cs]=Základní úkony týkající se správy napájení +Comment[csb]=Spòdlowé òperacejë sprôwiania mòcą +Comment[da]=Grundlæggende strømstyringsoperationer +Comment[de]=Grundlegende Operationen zur Energieverwaltung +Comment[el]=Βασικές λειτουργίες διαχείρισης ενέργειας +Comment[en_GB]=Basic Power Management Operations +Comment[es]=Operaciones básicas de gestión de la batería +Comment[et]=Peamised toitehalduse toimingud +Comment[eu]=Energia-kudeaketako oinarrizko eragiketak +Comment[fi]=Yksinkertaiset virranhallintaoperaatiot +Comment[fr]=Opérations basiques de gestion de l'énergie +Comment[fy]=Basis enerzjybehear aksjes +Comment[ga]=Bunoibríochtaí Bainisteoireachta Cumhachta +Comment[gl]=Operacións básicas de xestión da enerxía +Comment[gu]=સામાન્ય પાવર વ્યવસ્થાપક પ્રક્રિયાઓ +Comment[he]=פעולות בסיסיות לניהול צריכת חשמל +Comment[hi]=आधारभूत बिज़ली प्रबंधन ऑपरेशन +Comment[hne]=मूल पावर प्रबंधन आपरेसन +Comment[hr]=Osnovne operacije upravljanja potrošnjom energije +Comment[hu]=Energiakezelési funkciók +Comment[ia]=Operationes basic de gestion de energia +Comment[id]=Operasi Manajemen Daya Dasar +Comment[is]=Grunnaðgerðir orkustýringarkerfis +Comment[it]=Operazioni di base per la gestione energetica +Comment[ja]=基本的な電源管理操作 +Comment[kk]=Негізгі қуаттандыруды басқару амалдары +Comment[km]=ប្រតិបត្តិការ​គ្រប់គ្រង​ថាមពល​ជា​មូលដ្ឋាន +Comment[kn]=ಮೂಲಭೂತ ವಿದ್ಯುಚ್ಛಕ್ತಿ ವ್ಯವಸ್ಥಾಪನಾ ಕಾರ್ಯಾಚರಣೆಗಳು +Comment[ko]=기본 전원 관리 작업 +Comment[ku]=Çalakiyên Rêveberiya Hêzê yê Bingehîn +Comment[lt]=Elementarios maitinimo valdymo operacijos +Comment[lv]=Pamata energokontroles darbības +Comment[mk]=Основни операции за менаџмент на енергија +Comment[ml]=അടിസ്ഥാനപരമായ പവര്‍ മാനേജ്മെന്റ് ബാക്കെന്‍ഡ് നടപടികള്‍ +Comment[mr]=मूळ पावर व्यवस्थापन कार्ये +Comment[nb]=Enkle strømstyringshandlinger +Comment[nds]=Eenfache Stroomkuntrull-Funkschonen +Comment[nl]=Basis energiebeheeroperaties +Comment[nn]=Grunnleggjande straumstyringsfunksjonar +Comment[or]=ମୌଳିକ ଶକ୍ତି ପରିଚାଳନା ପ୍ରୟୋଗଗୁଡ଼ିକ +Comment[pa]=ਬੇਸਿਕ ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ ਓਪਰੇਸ਼ਨ +Comment[pl]=Podstawowe operacje zarządzania energią +Comment[pt]=Operações Básicas de Gestão da Energia +Comment[pt_BR]=Operações básicas de gerenciamento de energia +Comment[ro]=Operații de bază pentru gestiunea energiei +Comment[ru]=Управление питанием +Comment[si]=මූලික බල පරිපාලන ක්‍රියාකාරකම් +Comment[sk]=Základné operácie správy napájania +Comment[sl]=Osnovna dejanja upravljanja z energijo +Comment[sr]=Основни поступци управљања напајањем +Comment[sr@ijekavian]=Основни поступци управљања напајањем +Comment[sr@ijekavianlatin]=Osnovni postupci upravljanja napajanjem +Comment[sr@latin]=Osnovni postupci upravljanja napajanjem +Comment[sv]=Grundläggande strömsparfunktioner +Comment[ta]=Basic Power Management Operations +Comment[tg]=Служба управления питанием ноутбука +Comment[th]=ปฏิบัติการจัดการพลังงานขั้นพื้นฐาน +Comment[tr]=Temel Güç Yönetimi İşlemleri +Comment[ug]=ئاساسىي توك مەنبە باشقۇرۇش مەشغۇلاتى +Comment[uk]=Керування базовими операціями з керування живленням +Comment[vi]=Thao tác quản lý năng lượng cơ bản +Comment[wa]=Operåcions di båze do manaedjmint di l' enerdjeye +Comment[x-test]=xxBasic Power Management Operationsxx +Comment[zh_CN]=基本电源管理操作 +Comment[zh_TW]=基本的電源管理操作 +Icon=preferences-system-power-management +Name=PowerDevil +Name[ar]=عفريت الطاقة +Name[ast]=PowerDevil +Name[be@latin]=PowerDevil +Name[bg]=PowerDevil +Name[bn]=পাওয়ার-ডেভিল +Name[bn_IN]=PowerDevil +Name[bs]=PowerDevil +Name[ca]=PowerDevil +Name[ca@valencia]=PowerDevil +Name[cs]=PowerDevil +Name[da]=PowerDevil +Name[de]=PowerDevil +Name[el]=PowerDevil +Name[en_GB]=PowerDevil +Name[eo]=PowerDevil +Name[es]=PowerDevil +Name[et]=PowerDevil +Name[eu]=PowerDevil +Name[fi]=PowerDevil +Name[fr]=PowerDevil +Name[fy]=PowerDevil +Name[ga]=PowerDevil +Name[gl]=PowerDevil +Name[gu]=પાવરડેવિલ +Name[he]=PowerDevil +Name[hi]=पावर-डेविल +Name[hne]=पावर-डेविल +Name[hr]=PowerDevil +Name[hu]=Power Devil +Name[ia]=PowerDevil +Name[id]=PowerDevil +Name[is]=OrkuPúki +Name[it]=PowerDevil +Name[ja]=PowerDevil +Name[kk]=PowerDevil +Name[km]=PowerDevil +Name[kn]=ಪವರ್ ಡೆವಿಲ್ +Name[ko]=PowerDevil +Name[lt]=PowerDevil +Name[lv]=PowerDevil +Name[mai]=पावर-डेविल +Name[ml]=പവര്‍ഡെവിള്‍ +Name[mr]=पॉवरडेव्हिल +Name[nb]=PowerDevil +Name[nds]=Stroomdüvel +Name[nl]=PowerDevil +Name[nn]=PowerDevil +Name[or]=PowerDevil +Name[pa]=ਪਾਵਰ-ਡੀਵਿਲ +Name[pl]=PowerDevil +Name[pt]=PowerDevil +Name[pt_BR]=PowerDevil +Name[ro]=PowerDevil +Name[ru]=PowerDevil +Name[si]=PowerDevil +Name[sk]=PowerDevil +Name[sl]=PowerDevil +Name[sr]=Струјни ђаво +Name[sr@ijekavian]=Струјни ђаво +Name[sr@ijekavianlatin]=Strujni đavo +Name[sr@latin]=Strujni đavo +Name[sv]=Powerdevil +Name[ta]=PowerDevil +Name[te]=PowerDevil +Name[tg]=PowerDevil +Name[th]=PowerDevil +Name[tr]=PowerDevil +Name[ug]=PowerDevil +Name[uk]=PowerDevil +Name[wa]=Li Diâle d' Enerdjeye +Name[x-test]=xxPowerDevilxx +Name[zh_CN]=PowerDevil +Name[zh_TW]=PowerDevil +Type=Service +X-KDE-Library=krunner_powerdevil +X-KDE-PluginInfo-Author=Dario Freddi +X-KDE-PluginInfo-Email=drf@kdemod.ath.cx +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-Name=PowerDevil +X-KDE-PluginInfo-Version=1.0 +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-ServiceTypes=Plasma/Runner diff --git a/plasma/generic/runners/recentdocuments/CMakeLists.txt b/plasma/generic/runners/recentdocuments/CMakeLists.txt new file mode 100644 index 00000000..df24f655 --- /dev/null +++ b/plasma/generic/runners/recentdocuments/CMakeLists.txt @@ -0,0 +1,11 @@ +set(krunner_recentdocuments_SRCS + recentdocuments.cpp +) + +kde4_add_plugin(krunner_recentdocuments ${krunner_recentdocuments_SRCS}) +target_link_libraries(krunner_recentdocuments ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS krunner_recentdocuments DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES recentdocuments.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/recentdocuments/Messages.sh b/plasma/generic/runners/recentdocuments/Messages.sh new file mode 100755 index 00000000..9bed7616 --- /dev/null +++ b/plasma/generic/runners/recentdocuments/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_recentdocuments.pot diff --git a/plasma/generic/runners/recentdocuments/README b/plasma/generic/runners/recentdocuments/README new file mode 100644 index 00000000..2a809d1e --- /dev/null +++ b/plasma/generic/runners/recentdocuments/README @@ -0,0 +1,7 @@ +Kate Session Runner +======================== +This Runner loads a list of recent documents and matches +KRunner's queries against it. + +-- +sebas@kde.org diff --git a/plasma/generic/runners/recentdocuments/recentdocuments.cpp b/plasma/generic/runners/recentdocuments/recentdocuments.cpp new file mode 100644 index 00000000..57185f89 --- /dev/null +++ b/plasma/generic/runners/recentdocuments/recentdocuments.cpp @@ -0,0 +1,111 @@ +/* + * Copyright 2008 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "recentdocuments.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + + +RecentDocuments::RecentDocuments(QObject *parent, const QVariantList& args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args); + setObjectName( QLatin1String("Recent Documents" )); + m_icon = KIcon("document-open-recent"); + loadRecentDocuments(); + // listen for changes to the list of recent documents + KDirWatch *recentDocWatch = new KDirWatch(this); + recentDocWatch->addDir(KRecentDocument::recentDocumentDirectory(), KDirWatch::WatchFiles); + connect(recentDocWatch,SIGNAL(created(QString)),this,SLOT(loadRecentDocuments())); + connect(recentDocWatch,SIGNAL(deleted(QString)),this,SLOT(loadRecentDocuments())); + connect(recentDocWatch,SIGNAL(dirty(QString)),this,SLOT(loadRecentDocuments())); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Looks for documents recently used with names matching :q:."))); +} + +RecentDocuments::~RecentDocuments() +{ +} + +void RecentDocuments::loadRecentDocuments() +{ + //kDebug() << "Refreshing recent documents."; + m_recentdocuments = KRecentDocument::recentDocuments(); +} + + +void RecentDocuments::match(Plasma::RunnerContext &context) +{ + if (m_recentdocuments.isEmpty()) { + return; + } + + const QString term = context.query(); + if (term.length() < 3) { + return; + } + + foreach (const QString &document, m_recentdocuments) { + if (!context.isValid()) { + return; + } + + if (document.contains(term, Qt::CaseInsensitive)) { + KConfig _config( document, KConfig::SimpleConfig ); + KConfigGroup config(&_config, "Desktop Entry" ); + QString niceName = config.readEntry( "Name" ); + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::PossibleMatch); + match.setRelevance(1.0); + match.setIcon(KIcon(config.readEntry("Icon"))); + match.setData(document); // TODO: Read URL[$e], or can we just pass the path to the .desktop file? + match.setText(niceName); + match.setSubtext(i18n("Recent Document")); + context.addMatch(term, match); + } + } +} + +void RecentDocuments::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context) + QString url = match.data().toString(); + kDebug() << "Opening Recent Document" << url; + new KRun(url, 0); +} + +QMimeData * RecentDocuments::mimeDataForMatch(const Plasma::QueryMatch * match) +{ + QMimeData * result = new QMimeData(); + QList urls; + urls << QUrl(match->data().toString()); + result->setUrls(urls); + + result->setText(match->data().toString()); + return result; +} + +#include "recentdocuments.moc" diff --git a/plasma/generic/runners/recentdocuments/recentdocuments.desktop b/plasma/generic/runners/recentdocuments/recentdocuments.desktop new file mode 100644 index 00000000..0e240340 --- /dev/null +++ b/plasma/generic/runners/recentdocuments/recentdocuments.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Name=Recent Documents +Name[ar]=المسندات الحديثة +Name[ast]=Documentos recientes +Name[be]=Нядаўнія дакументы +Name[be@latin]=Niadaŭnyja dakumenty +Name[bg]=Последно използвани +Name[bn]=সম্প্রতি ব্যবহৃত নথী +Name[br]=Teulioù nevez +Name[bs]=nedavnii dokumenti +Name[ca]=Documents recents +Name[ca@valencia]=Documents recents +Name[cs]=Nedávné dokumenty +Name[cy]=Dogfenni Diweddar +Name[da]=Nylige dokumenter +Name[de]=Zuletzt geöffnete Dokumente +Name[el]=Πρόσφατα έγγραφα +Name[en_GB]=Recent Documents +Name[eo]=Lastlaboritaj dokumentoj +Name[es]=Documentos recientes +Name[et]=Viimati kasutatud dokumendid +Name[eu]=Azken dokumentuak +Name[fa]=سندهای اخیر +Name[fi]=Viimeksi käytetyt tiedostot +Name[fr]=Documents récents +Name[fy]=Koatlyn brûkte dokuminten +Name[ga]=Cáipéisí is Déanaí +Name[gl]=Documentos recentes +Name[gu]=હાલનાં દસ્તાવેજો +Name[he]=מסמכים שהיו בשימוש לאחרונה +Name[hi]=हाल ही में प्रयुक्त दस्तावेज़ +Name[hne]=हाल ही मं प्रयुक्त कागद +Name[hr]=Nedavno pristupljeni dokumenti +Name[hu]=Nemrég használt dokumentumok +Name[ia]=Documentos recente +Name[id]=Dokumen Terkini +Name[is]=Nýleg skjöl +Name[it]=Documenti recenti +Name[ja]=最近の文書 +Name[ka]=ბოლო დოკუმენტები +Name[kk]=Жуырда ашылғандар +Name[km]=ឯកសារ​បច្ចុប្បន្ន +Name[kn]=ಇತ್ತೀಚಿನ ದಸ್ತಾವೇಜುಗಳು +Name[ko]=최근 문서 +Name[ku]=Pelgeyên Hatine Bikaranîn +Name[lt]=Neseni dokumentai +Name[lv]=Nesenie dokumenti +Name[mai]=हालक दस्ताबेज +Name[mk]=Скорешни документи +Name[ml]=ഈയിടെ തുറന്ന രേഖകള്‍ +Name[mr]=अलिकडील दस्तऐवज +Name[nb]=Nylig brukte dokumenter +Name[nds]=Tolest bruukt Dokmenten +Name[nl]=Recente documenten +Name[nn]=Nyleg brukte dokument +Name[or]=ପ୍ରଚଳିତ ଦଲିଲଗୁଡ଼ିକ +Name[pa]=ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ +Name[pl]=Ostatnie dokumenty +Name[pt]=Documentos Recentes +Name[pt_BR]=Documentos recentes +Name[ro]=Documente recente +Name[ru]=Последние документы +Name[si]=මෑතකදි භාවිත කළ ලේඛන +Name[sk]=Nedávne dokumenty +Name[sl]=Nedavni dokumenti +Name[sr]=недавни документи +Name[sr@ijekavian]=недавни документи +Name[sr@ijekavianlatin]=nedavni dokumenti +Name[sr@latin]=nedavni dokumenti +Name[sv]=Senaste dokument +Name[ta]=Recent Documents +Name[te]=ఇటీవలి పత్రములు +Name[tg]=Ҳуҷҷатҳои кушодашуда +Name[th]=เอกสารที่เรียกใช้ไม่นานนี้ +Name[tr]=Son Kullanılan Belgeler +Name[ug]=يېقىنقى پۈتۈكلەر +Name[uk]=Недавні документи +Name[uz]=Yaqinda ochilgan hujjatlar +Name[uz@cyrillic]=Яқинда очилган ҳужжатлар +Name[vi]=Tài liệu gần đây +Name[wa]=Documints d' enawaire +Name[xh]=Uxwebhu Olusandukusebenziswa +Name[x-test]=xxRecent Documentsxx +Name[zh_CN]=最近的文档 +Name[zh_TW]=最近的文件 +Icon=document-open-recent + +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +X-KDE-Library=krunner_recentdocuments +X-KDE-PluginInfo-Author=Sebastian Kügler +X-KDE-PluginInfo-Email=sebas@kde.org +X-KDE-PluginInfo-Name=recentdocuments +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/recentdocuments/recentdocuments.h b/plasma/generic/runners/recentdocuments/recentdocuments.h new file mode 100644 index 00000000..e16949da --- /dev/null +++ b/plasma/generic/runners/recentdocuments/recentdocuments.h @@ -0,0 +1,50 @@ +/* + * Copyright 2008 Sebastian Kügler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef RECENTDOCUMENTS_H +#define RECENTDOCUMENTS_H + +#include + +#include + +class RecentDocuments : public Plasma::AbstractRunner { + Q_OBJECT + + public: + RecentDocuments( QObject *parent, const QVariantList& args ); + ~RecentDocuments(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match); + + private Q_SLOTS: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); + + private Q_SLOTS: + void loadRecentDocuments(); + + private: + KIcon m_icon; + QStringList m_recentdocuments; +}; + +K_EXPORT_PLASMA_RUNNER(recentdocuments, RecentDocuments) + +#endif diff --git a/plasma/generic/runners/services/CMakeLists.txt b/plasma/generic/runners/services/CMakeLists.txt new file mode 100644 index 00000000..052cc2c0 --- /dev/null +++ b/plasma/generic/runners/services/CMakeLists.txt @@ -0,0 +1,11 @@ +set(krunner_services_SRCS + servicerunner.cpp +) + +kde4_add_plugin(krunner_services ${krunner_services_SRCS}) +target_link_libraries(krunner_services ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS krunner_services DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-services.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/services/Messages.sh b/plasma/generic/runners/services/Messages.sh new file mode 100755 index 00000000..e81fc20f --- /dev/null +++ b/plasma/generic/runners/services/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_services.pot diff --git a/plasma/generic/runners/services/plasma-runner-services.desktop b/plasma/generic/runners/services/plasma-runner-services.desktop new file mode 100644 index 00000000..4bdd62d2 --- /dev/null +++ b/plasma/generic/runners/services/plasma-runner-services.desktop @@ -0,0 +1,179 @@ +[Desktop Entry] +Name=Applications +Name[af]=Programme +Name[ar]=تطبيقات +Name[as]=অনুপ্ৰয়োগ +Name[ast]=Aplicaciones +Name[be]=Праграмы +Name[be@latin]=Aplikacyi +Name[bg]=Програми +Name[bn]=অ্যাপলিকেশন +Name[bn_IN]=অ্যাপ্লিকেশন তালিকা +Name[br]=Arloadoù +Name[bs]=programi +Name[ca]=Aplicacions +Name[ca@valencia]=Aplicacions +Name[cs]=Aplikace +Name[csb]=Programë +Name[cy]=Cymhwysiadau +Name[da]=Programmer +Name[de]=Programme +Name[el]=Εφαρμογές +Name[en_GB]=Applications +Name[eo]=Aplikaĵoj +Name[es]=Aplicaciones +Name[et]=Rakendused +Name[eu]=Aplikazioak +Name[fa]=برنامه‌ها +Name[fi]=Sovellukset +Name[fr]=Applications +Name[fy]=Programma's +Name[ga]=Feidhmchláir +Name[gl]=Programas +Name[gu]=કાર્યક્રમો +Name[he]=תוכניות +Name[hi]=अनुप्रयोग +Name[hne]=अनुपरयोग +Name[hr]=Aplikacije +Name[hsb]=Aplikacija +Name[hu]=Alkalmazások +Name[ia]=Applicationes +Name[id]=Aplikasi +Name[is]=Forrit +Name[it]=Applicazioni +Name[ja]=アプリケーション +Name[ka]=პროგრამები +Name[kk]=Қолданбалар +Name[km]=កម្មវិធី +Name[kn]=ಅನ್ವಯಗಳು +Name[ko]=응용 프로그램 +Name[ku]=Sepan +Name[lt]=Programos +Name[lv]=Programmas +Name[mai]=अनुप्रयोग +Name[mk]=Апликации +Name[ml]=പ്രയോഗങ്ങള്‍ +Name[mr]=अनुप्रयोग +Name[ms]=Aplikasi +Name[nb]=Programmer +Name[nds]=Programmen +Name[ne]=अनुप्रयोग +Name[nl]=Programma's +Name[nn]=Program +Name[oc]=Aplicacions +Name[or]=ପ୍ରୟୋଗଗୁଡ଼ିକ +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ +Name[pl]=Programy +Name[pt]=Aplicações +Name[pt_BR]=Aplicativos +Name[ro]=Aplicații +Name[ru]=Приложения +Name[se]=Prográmmat +Name[si]=යෙදුම් +Name[sk]=Aplikácie +Name[sl]=Programi +Name[sr]=програми +Name[sr@ijekavian]=програми +Name[sr@ijekavianlatin]=programi +Name[sr@latin]=programi +Name[sv]=Program +Name[ta]=பயன்பாடுகள் +Name[te]=కార్యక్రమాలు +Name[tg]=Барномаҳо +Name[th]=โปรแกรมต่าง ๆ +Name[tr]=Uygulamalar +Name[ug]=پروگراممىلار +Name[uk]=Програми +Name[uz]=Dasturlar +Name[uz@cyrillic]=Дастурлар +Name[vi]=Ứng dụng +Name[wa]=Programes +Name[x-test]=xxApplicationsxx +Name[zh_CN]=应用程序 +Name[zh_TW]=應用程式 +Comment=Find applications, control panels and services +Comment[ar]=ابحث عن التطبيقات ولوحات التحكم والخدمات +Comment[ast]=Aplicaciones, paneles de control y servicios +Comment[be@latin]=Pošuk aplikacyjaŭ, panelaŭ kiravańnia j słužbaŭ +Comment[bg]=Търсене на програми, панели и услуги +Comment[bs]=Tražite programe, kontrolne panele i servise +Comment[ca]=Cerca aplicacions, plafons de control i serveis +Comment[ca@valencia]=Cerca aplicacions, plafons de control i serveis +Comment[cs]=Najít aplikace, ovládací panely a služby +Comment[da]=Find programmer, kontrolpaneler og tjenester +Comment[de]=Auffinden von Anwendungen, Einrichtungsprogrammen und Diensten +Comment[el]=Αναζήτηση εφαρμογών, πινάκων ελέγχου και υπηρεσιών +Comment[en_GB]=Find applications, control panels and services +Comment[eo]=Trovi aplikaĵojn, stirpanelojn kaj servojn +Comment[es]=Aplicaciones, paneles de control y servicios +Comment[et]=Rakenduste, juhtpaneelide ja teenuste otsimine +Comment[eu]=Bilatu aplikazioak, aginte-panelak eta zerbitzuak +Comment[fi]=Etsi ohjelmat, asetukset ja palvelut +Comment[fr]=Trouver des applications, des tableaux de bords et des services +Comment[fy]=Sykje om applikaasjes, konfiguraasjemodules en tsjinsten +Comment[ga]=Aimsigh feidhmchláir, painéil rialaithe agus seirbhísí +Comment[gl]=Busca programas, paneis de control e servizos +Comment[gu]=કાર્યક્રમો, નિયંત્રણ પેનલો અને સેવાઓ શોધો +Comment[he]=משמש למציאת יישומים, לוחות בקרה ושירותים +Comment[hi]=अनुप्रयोग, नियंत्रण पटल तथा सेवाएँ ढूंढें +Comment[hne]=अनुपरयोग ढूंढव, नियंत्रन केंद्र अउ सेवा +Comment[hr]=Pronađi aplikacije, kontrolne okvire i usluge +Comment[hu]=Alkalmazások, vezérlőpanelek és szolgáltatások keresése +Comment[ia]=Trova applicationes, pannellos de controlo e servicios +Comment[id]=Cari aplikasi, panel kontrol dan layanan +Comment[is]=Finna forrit, stjórneiningar og þjónustur +Comment[it]=Trova applicazioni, pannelli di controllo e servizi +Comment[ja]=アプリケーション、コントロールパネル、サービスを探します +Comment[kk]=Қолданбаларды табу, панельдер мен қызметтерді басқару +Comment[km]=រក​កម្មវិធី បន្ទះ​ត្រួតពិនិត្យ និង​សេវា +Comment[kn]=ಅನ್ವಯಗಳು, ನಿಯಂತ್ರಣಾ ಪುಟೀಪುಗಳು (ಕಂಟ್ರೋಲ್ ಪಾನಲ್ಸ್) ಹಾಗೂ ಸೇವೆಗಳನ್ನು ಹುಡುಕು +Comment[ko]=프로그램, 제어판, 서비스 찾기 +Comment[ku]=Sepanan, panelên kontrolê û servîsan bibîne +Comment[lt]=Rasti programas, valdymo pultus ir tarnybas +Comment[lv]=Meklēt lietotnes, kontroles paneļus un servisus +Comment[mk]=Пронајдете апликации, контролни панели и сервиси +Comment[ml]=പ്രയോഗങ്ങള്‍, നിയന്ത്രണപാനലുകള്‍, സേവനങ്ങള്‍ എന്നിവ കണ്ടുപിടിയ്ക്കുക +Comment[mr]=अनुप्रयोग, नियंत्रण पटल व सेवा शोधा +Comment[nb]=Finn programmer, kontrollpanel og tjenester +Comment[nds]=Programmen, Kuntrullpaneels un Deensten söken +Comment[nl]=Zoek naar programma's, configuratiemodules en diensten +Comment[nn]=Finn program, kontrollpanel og tenester +Comment[or]=ପ୍ରୟୋଗ, ନିୟନ୍ତ୍ରଣ ପଟି ଏବଂ ସର୍ଭିସଗୁଡ଼ିକୁ ଖୋଜନ୍ତୁ +Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ, ਕੰਟਰੋਲ ਪੈਨਲ ਅਤੇ ਸਰਵਿਸਾਂ ਲੱਭੋ +Comment[pl]=Znajdowanie programów, paneli sterowania i usług +Comment[pt]=Procura aplicações, painéis de controlo e serviços +Comment[pt_BR]=Localiza aplicativos, painéis de controle e serviços +Comment[ro]=Găsește aplicații, panouri de control și servicii +Comment[ru]=Поиск приложений и служб +Comment[si]=යෙදුම්, පාළන පුවරු සහ සේවා සොයන්න +Comment[sk]=Hľadanie aplikácií, ovládacích panelov a služieb +Comment[sl]=Najdite programe, nadzorne plošče in storitve +Comment[sr]=Тражите програме, контролне панеле и сервисе +Comment[sr@ijekavian]=Тражите програме, контролне панеле и сервисе +Comment[sr@ijekavianlatin]=Tražite programe, kontrolne panele i servise +Comment[sr@latin]=Tražite programe, kontrolne panele i servise +Comment[sv]=Sök efter program, kontrollpaneler och tjänster +Comment[ta]=Find applications, control panels and services +Comment[te]=అనువర్తనములను, కంట్రోల్ ప్యానల్‍స్ ను మరియు సేవలను కనుగొనుము +Comment[tg]=Ҷустуҷӯи барномаҳо ва хизматҳо +Comment[th]=ค้นหาโปรแกรม, ถาดควบคุม และบริการ +Comment[tr]=Uygulamaları, kontrol panellerini ve servisleri bul +Comment[ug]=پروگرامما، تىزگىن تاختا ۋە مۇلازىمەت ئىزدە +Comment[uk]=Знайти програми, панелі керування та служби +Comment[vi]=Tìm kiếm ứng dụng, bảng thiết lập và dịch vụ +Comment[wa]=Trover des programes, des paneas d' controle et des siervices +Comment[x-test]=xxFind applications, control panels and servicesxx +Comment[zh_CN]=查找应用程序、控制面板和服务 +Comment[zh_TW]=尋找應用程式、控制面板與服務 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=applications-other +X-KDE-Library=krunner_services +X-Plasma-RunnerPhase=first +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=services +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/services/servicerunner.cpp b/plasma/generic/runners/services/servicerunner.cpp new file mode 100644 index 00000000..985a09c0 --- /dev/null +++ b/plasma/generic/runners/services/servicerunner.cpp @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "servicerunner.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +ServiceRunner::ServiceRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args) + + setObjectName( QLatin1String("Application" )); + setPriority(AbstractRunner::HighestPriority); + + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds applications whose name or description match :q:"))); +} + +ServiceRunner::~ServiceRunner() +{ +} + +void ServiceRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + + QList matches; + QSet seen; + QString query; + + if (term.length() > 1) { + // Search for applications which are executable and case-insensitively match the search term + // See http://techbase.kde.org/Development/Tutorials/Services/Traders#The_KTrader_Query_Language + // if the following is unclear to you. + query = QString("exist Exec and ('%1' =~ Name)").arg(term); + KService::List services = KServiceTypeTrader::self()->query("Application", query); + + if (!services.isEmpty()) { + //kDebug() << service->name() << "is an exact match!" << service->storageId() << service->exec(); + foreach (const KService::Ptr &service, services) { + if (!service->noDisplay() && service->property("NotShowIn", QVariant::String) != "KDE") { + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + setupMatch(service, match); + match.setRelevance(1); + matches << match; + seen.insert(service->storageId()); + seen.insert(service->exec()); + } + } + } + } + + if (!context.isValid()) { + return; + } + + // If the term length is < 3, no real point searching the Keywords and GenericName + if (term.length() < 3) { + query = QString("exist Exec and ( (exist Name and '%1' ~~ Name) or ('%1' ~~ Exec) )").arg(term); + } else { + // Search for applications which are executable and the term case-insensitive matches any of + // * a substring of one of the keywords + // * a substring of the GenericName field + // * a substring of the Name field + // Note that before asking for the content of e.g. Keywords and GenericName we need to ask if + // they exist to prevent a tree evaluation error if they are not defined. + query = QString("exist Exec and ( (exist Keywords and '%1' ~subin Keywords) or (exist GenericName and '%1' ~~ GenericName) or (exist Name and '%1' ~~ Name) or ('%1' ~~ Exec) )").arg(term); + } + + KService::List services = KServiceTypeTrader::self()->query("Application", query); + services += KServiceTypeTrader::self()->query("KCModule", query); + + //kDebug() << "got " << services.count() << " services from " << query; + foreach (const KService::Ptr &service, services) { + if (!context.isValid()) { + return; + } + + if (service->noDisplay()) { + continue; + } + + const QString id = service->storageId(); + const QString name = service->desktopEntryName(); + const QString exec = service->exec(); + + if (seen.contains(id) || seen.contains(exec)) { + //kDebug() << "already seen" << id << exec; + continue; + } + + //kDebug() << "haven't seen" << id << "so processing now"; + seen.insert(id); + seen.insert(exec); + + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::PossibleMatch); + setupMatch(service, match); + qreal relevance(0.6); + + // If the term was < 3 chars and NOT at the beginning of the App's name or Exec, then + // chances are the user doesn't want that app. + if (term.length() < 3) { + if (name.startsWith(term) || exec.startsWith(term)) { + relevance = 0.9; + } else { + continue; + } + } else if (service->name().contains(term, Qt::CaseInsensitive)) { + relevance = 0.8; + + if (service->name().startsWith(term, Qt::CaseInsensitive)) { + relevance += 0.1; + } + } else if (service->genericName().contains(term, Qt::CaseInsensitive)) { + relevance = 0.7; + + if (service->genericName().startsWith(term, Qt::CaseInsensitive)) { + relevance += 0.1; + } + } + + if (service->categories().contains("KDE") || service->serviceTypes().contains("KCModule")) { + //kDebug() << "found a kde thing" << id << match.subtext() << relevance; + if (id.startsWith("kde-")) { + //kDebug() << "old" << service->type(); + if (!service->isApplication()) { + // avoid showing old kcms and what not + continue; + } + + // This is an older version, let's disambiguate it + QString subtext("KDE3"); + + if (!match.subtext().isEmpty()) { + subtext.append(", " + match.subtext()); + } + + match.setSubtext(subtext); + } else { + relevance += .1; + } + } + + //kDebug() << service->name() << "is this relevant:" << relevance; + match.setRelevance(relevance); + matches << match; + } + + //search for applications whose categories contains the query + query = QString("exist Exec and (exist Categories and '%1' ~subin Categories)").arg(term); + services = KServiceTypeTrader::self()->query("Application", query); + + //kDebug() << service->name() << "is an exact match!" << service->storageId() << service->exec(); + foreach (const KService::Ptr &service, services) { + if (!context.isValid()) { + return; + } + + if (!service->noDisplay()) { + QString id = service->storageId(); + QString exec = service->exec(); + if (seen.contains(id) || seen.contains(exec)) { + //kDebug() << "already seen" << id << exec; + continue; + } + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::PossibleMatch); + setupMatch(service, match); + + qreal relevance = 0.6; + if (service->categories().contains("X-KDE-More") || + !service->showInKDE()) { + relevance = 0.5; + } + + if (service->isApplication()) { + relevance += .4; + } + + match.setRelevance(relevance); + matches << match; + } + } + + context.addMatches(term, matches); +} + +void ServiceRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context); + KService::Ptr service = KService::serviceByStorageId(match.data().toString()); + if (service) { + KRun::run(*service, KUrl::List(), 0); + } +} + +void ServiceRunner::setupMatch(const KService::Ptr &service, Plasma::QueryMatch &match) +{ + const QString name = service->name(); + + match.setText(name); + match.setData(service->storageId()); + + if (!service->genericName().isEmpty() && service->genericName() != name) { + match.setSubtext(service->genericName()); + } else if (!service->comment().isEmpty()) { + match.setSubtext(service->comment()); + } + + if (!service->icon().isEmpty()) { + match.setIcon(KIcon(service->icon())); + } +} + +QMimeData * ServiceRunner::mimeDataForMatch(const Plasma::QueryMatch *match) +{ + KService::Ptr service = KService::serviceByStorageId(match->data().toString()); + if (service) { + QMimeData * result = new QMimeData(); + QList urls; + urls << KUrl(service->entryPath()); + kDebug() << urls; + result->setUrls(urls); + return result; + } + + return 0; +} + +#include "servicerunner.moc" + diff --git a/plasma/generic/runners/services/servicerunner.h b/plasma/generic/runners/services/servicerunner.h new file mode 100644 index 00000000..f7d998d5 --- /dev/null +++ b/plasma/generic/runners/services/servicerunner.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SERVICERUNNER_H +#define SERVICERUNNER_H + + +#include + +#include + + +/** + * This class looks for matches in the set of .desktop files installed by + * applications. This way the user can type exactly what they see in the + * appications menu and have it start the appropriate app. Essentially anything + * that KService knows about, this runner can launch + */ + +class ServiceRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + ServiceRunner(QObject *parent, const QVariantList &args); + ~ServiceRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + + protected slots: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); + + protected: + void setupMatch(const KService::Ptr &service, Plasma::QueryMatch &action); +}; + +K_EXPORT_PLASMA_RUNNER(services, ServiceRunner) + +#endif + diff --git a/plasma/generic/runners/sessions/CMakeLists.txt b/plasma/generic/runners/sessions/CMakeLists.txt new file mode 100644 index 00000000..816b71db --- /dev/null +++ b/plasma/generic/runners/sessions/CMakeLists.txt @@ -0,0 +1,14 @@ +set(krunner_sessions_SRCS + sessionrunner.cpp +) + +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml) +QT4_ADD_DBUS_INTERFACE(krunner_sessions_SRCS ${screensaver_xml} screensaver_interface) + +kde4_add_plugin(krunner_sessions ${krunner_sessions_SRCS}) +target_link_libraries(krunner_sessions ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS} kworkspace) + +install(TARGETS krunner_sessions DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-sessions.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/sessions/Messages.sh b/plasma/generic/runners/sessions/Messages.sh new file mode 100755 index 00000000..7fe6ea81 --- /dev/null +++ b/plasma/generic/runners/sessions/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_sessions.pot diff --git a/plasma/generic/runners/sessions/plasma-runner-sessions.desktop b/plasma/generic/runners/sessions/plasma-runner-sessions.desktop new file mode 100644 index 00000000..911be961 --- /dev/null +++ b/plasma/generic/runners/sessions/plasma-runner-sessions.desktop @@ -0,0 +1,164 @@ +[Desktop Entry] +Name=Desktop Sessions +Name[ar]=جلسات سطح المكتب +Name[ast]=Sesiones d'escritoriu +Name[be@latin]=Sesii rabočaha stała +Name[bg]=Сесии +Name[bn]=ডেস্কটপ সেশন +Name[bn_IN]=ডেস্কটপের সেশান +Name[bs]=sesije radne površi +Name[ca]=Sessions d'escriptori +Name[ca@valencia]=Sessions d'escriptori +Name[cs]=Sezení plochy +Name[csb]=Sesëje pùltu +Name[da]=Skrivebordssessioner +Name[de]=Desktop-Sitzungen +Name[el]=Συνεδρίες επιφάνειας εργασίας +Name[en_GB]=Desktop Sessions +Name[eo]=Labortablaj seancoj +Name[es]=Sesiones de escritorio +Name[et]=Töölauaseansid +Name[eu]=Mahaigaineko saioak +Name[fi]=Työpöytäistunnot +Name[fr]=Sessions de bureau +Name[fy]=Buroblêdsesjes +Name[ga]=Seisiúin Deisce +Name[gl]=Sesións do escritorio +Name[gu]=ડેસ્કટોપ સત્રો +Name[he]=הפעלות של שולחן העבודה +Name[hi]=डेस्कटॉप सत्र +Name[hne]=डेस्कटाप सेसन +Name[hr]=Sesije radne površine +Name[hu]=Asztali munkamenetek +Name[ia]=Sessiones de scriptorio +Name[id]=Sesi Desktop +Name[is]=Skjáborðssetur +Name[it]=Sessioni di desktop +Name[ja]=デスクトップセッション +Name[kk]=Үстел сеансы +Name[km]=សម័យ​ផ្ទៃតុ +Name[kn]=ಗಣಕತೆರೆ ಅಧಿವೇಶನಗಳು (ಸೆಶನ್) +Name[ko]=데스크톱 세션 +Name[ku]=Danişînên Sermaseyê +Name[lt]=Darbastalio sesijos +Name[lv]=Darbvirsmas sesijas +Name[mk]=Работни сесии +Name[ml]=പണിയിടത്തിന്റെ പ്രവര്‍ത്തനവേളകള്‍ +Name[mr]=डेस्कटॉप सत्र +Name[nb]=Skrivebordsøkter +Name[nds]=Schriefdischtörns +Name[nl]=Desktopsessies +Name[nn]=Skrivebordsøkter +Name[or]=ଡ଼େସ୍କଟପ ଅଧିବେଶନଗୁଡ଼ିକ +Name[pa]=ਡੈਸਕਟਾਪ ਸ਼ੈਸ਼ਨ +Name[pl]=Sesje pulpitu +Name[pt]=Sessões do Ecrã +Name[pt_BR]=Sessões da área de trabalho +Name[ro]=Sesiuni de birou +Name[ru]=Сеансы +Name[si]=වැඩතල සැසිය +Name[sk]=Sedenia plochy +Name[sl]=Namizne seje +Name[sr]=сесије радне површи +Name[sr@ijekavian]=сесије радне површи +Name[sr@ijekavianlatin]=sesije radne površi +Name[sr@latin]=sesije radne površi +Name[sv]=Skrivbordssessioner +Name[ta]=Desktop Sessions +Name[te]=డెస్‍క్ టాప్ భాగములు +Name[tg]=Амалҳои мизи корӣ +Name[th]=วาระงานของพื้นที่ทำงาน +Name[tr]=Masaüstü Oturumları +Name[ug]=ئۈستەلئۈستى ئەڭگىمە +Name[uk]=Стільничні сеанси +Name[vi]=Phiên làm việc +Name[wa]=Sessions do scribanne +Name[x-test]=xxDesktop Sessionsxx +Name[zh_CN]=桌面会话 +Name[zh_TW]=桌面工作階段 +Comment=Fast user switching +Comment[ar]=تبديل سريع للمستخدم +Comment[ast]=Cambéu rápidu d'usuariu +Comment[be@latin]=Chutkaje pieraklučeńnie karystańnikaŭ +Comment[bg]=Превключване на потребители +Comment[bs]=Brzo prebacivanje korisnika +Comment[ca]=Commutador ràpid d'usuari +Comment[ca@valencia]=Commutador ràpid d'usuari +Comment[cs]=Rychlé přepínání uživatelů +Comment[da]=Hurtig brugerskift +Comment[de]=Schneller Benutzerwechsel +Comment[el]=Γρήγορη αλλαγή χρήστη +Comment[en_GB]=Fast user switching +Comment[eo]=Rapida ŝanĝado de uzantoj +Comment[es]=Cambio rápido de usuario +Comment[et]=Kiire kasutaja vahetamine +Comment[eu]=Erabiltzaile-aldaketa bizkorra +Comment[fi]=Nopea käyttäjänvaihto +Comment[fr]=Commutation rapide d'utilisateurs +Comment[fy]=Flugge brûker wikseljen +Comment[ga]=Athraigh úsáideoirí go tapa +Comment[gl]=Troco rápido de usuario +Comment[gu]=ઝડપી વપરાશકર્તા બદલનાર +Comment[he]=החלפת משתמשים מהירה +Comment[hi]=उपयोक्ता त्वरित बदलें +Comment[hne]=उपयोग करइया के जल्दी अदल-बदल +Comment[hr]=Brza promjena korisnika +Comment[hu]=Felhasználóváltó +Comment[ia]=Commutation rapide de usator +Comment[id]=Penggantian pengguna cepat +Comment[is]=Hröð skipting milli notenda +Comment[it]=Cambio rapido dell'utente +Comment[ja]=ユーザを素早く切り替えます +Comment[kk]=Пайдаланушыны тез ауыстыру +Comment[km]=ការប្ដូរ​អ្នក​ប្រើ​យ៉ាង​លឿន +Comment[kn]=ಶೀಘ್ರ ಬಳಕೆದಾರ ಪರಿವರ್ತನೆ +Comment[ko]=빠른 사용자 전환 +Comment[ku]=Derbasbûna lezgîn a bikarhêner +Comment[lt]=Greitas naudotojų perjungimas +Comment[lv]=Ātra lietotāju pārslēgšana +Comment[mk]=Брзо менување корисници +Comment[ml]=മറ്റൊരു ഉപയോക്താവാകുന്നത് അനുവദിയ്ക്കുന്നതിനുള്ള സംവിധാനം +Comment[mr]=जलद वापरकर्ता बदल +Comment[nb]=Raskt brukerbytte +Comment[nds]=Gau den Bruker wesseln +Comment[nl]=Snel van gebruiker wisselen +Comment[nn]=Kjapt brukarbyte +Comment[or]=ପ୍ରଥମ ଚାଳକ ପରିବର୍ତ୍ତନ ହେଉଅଛି +Comment[pa]=ਤੇਜ਼ ਯੂਜ਼ਰ ਸਵਿੱਚਰ +Comment[pl]=Szybkie przełączanie użytkowników +Comment[pt]=Mudança rápida de utilizador +Comment[pt_BR]=Mudança rápida de usuário +Comment[ro]=Comutare rapidă între utilizatori +Comment[ru]=Быстрое переключение пользователей +Comment[si]=ක්‍ෂණික පරිශීලක මාරුව +Comment[sk]=Rýchle prepínanie užívateľov +Comment[sl]=Hitro preklapljanje uporabnikov +Comment[sr]=Брзо пребацивање корисника +Comment[sr@ijekavian]=Брзо пребацивање корисника +Comment[sr@ijekavianlatin]=Brzo prebacivanje korisnika +Comment[sr@latin]=Brzo prebacivanje korisnika +Comment[sv]=Snabbt användarbyte +Comment[ta]=Fast user switching +Comment[te]=వేగవంతమైన వినియోగదారి మార్పు +Comment[tg]=Мубодилаи фаврии корбар +Comment[th]=สลับผู้ใช้งานด่วน +Comment[tr]=Hızlı kullanıcı değiştirme +Comment[ug]=ئىشلەتكۈچىنى تېز ئالماشتۇرۇش +Comment[uk]=Швидке перемикання користувачів +Comment[vi]=Chuyển đổi người dùng nhanh +Comment[wa]=Candjî rade d' uzeu +Comment[x-test]=xxFast user switchingxx +Comment[zh_CN]=快速用户切换 +Comment[zh_TW]=快速切換使用者 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=system-shutdown +X-KDE-Library=krunner_sessions +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=desktopsessions +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true + diff --git a/plasma/generic/runners/sessions/sessionrunner.cpp b/plasma/generic/runners/sessions/sessionrunner.cpp new file mode 100644 index 00000000..dde4f390 --- /dev/null +++ b/plasma/generic/runners/sessions/sessionrunner.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sessionrunner.h" + + +#include +#include +#include +#include + +#include "kworkspace/kworkspace.h" + +#include "screensaver_interface.h" + +SessionRunner::SessionRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args) + + setObjectName( QLatin1String("Sessions" )); + setPriority(LowPriority); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | + Plasma::RunnerContext::NetworkLocation); + + m_canLogout = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout"); + if (m_canLogout) { + addSyntax(Plasma::RunnerSyntax(i18nc("log out command", "logout"), + i18n("Logs out, exiting the current desktop session"))); + addSyntax(Plasma::RunnerSyntax(i18nc("shutdown computer command", "shutdown"), + i18n("Turns off the computer"))); + } + + if (KAuthorized::authorizeKAction("lock_screen") && m_canLogout) { + addSyntax(Plasma::RunnerSyntax(i18nc("lock screen command", "lock"), + i18n("Locks the current sessions and starts the screen saver"))); + } + + Plasma::RunnerSyntax rebootSyntax(i18nc("restart computer command", "restart"), i18n("Reboots the computer")); + rebootSyntax.addExampleQuery(i18nc("restart computer command", "reboot")); + addSyntax(rebootSyntax); + + m_triggerWord = i18nc("switch user command", "switch"); + addSyntax(Plasma::RunnerSyntax(i18nc("switch user command", "switch :q:"), + i18n("Switches to the active session for the user :q:, " + "or lists all active sessions if :q: is not provided"))); + + Plasma::RunnerSyntax fastUserSwitchSyntax(i18n("switch user"), + i18n("Starts a new session as a different user")); + fastUserSwitchSyntax.addExampleQuery(i18n("new session")); + addSyntax(fastUserSwitchSyntax); + + //"SESSIONS" should not be translated; it's used programmaticaly + setDefaultSyntax(Plasma::RunnerSyntax("SESSIONS", i18n("Lists all sessions"))); + +} + +SessionRunner::~SessionRunner() +{ +} + +void SessionRunner::matchCommands(QList &matches, const QString& term) +{ + if (!m_canLogout) { + return; + } + + if (term.compare(i18nc("log out command","logout"), Qt::CaseInsensitive) == 0 || + term.compare(i18n("log out"), Qt::CaseInsensitive) == 0) { + Plasma::QueryMatch match(this); + match.setText(i18nc("log out command","Logout")); + match.setIcon(KIcon("system-log-out")); + match.setData(LogoutAction); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setRelevance(0.9); + matches << match; + } else if (term.compare(i18nc("restart computer command", "restart"), Qt::CaseInsensitive) == 0 || + term.compare(i18nc("restart computer command", "reboot"), Qt::CaseInsensitive) == 0) { + Plasma::QueryMatch match(this); + match.setText(i18n("Restart the computer")); + match.setIcon(KIcon("system-reboot")); + match.setData(RestartAction); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setRelevance(0.9); + matches << match; + } else if (term.compare(i18nc("shutdown computer command","shutdown"), Qt::CaseInsensitive) == 0) { + Plasma::QueryMatch match(this); + match.setText(i18n("Shutdown the computer")); + match.setIcon(KIcon("system-shutdown")); + match.setData(ShutdownAction); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setRelevance(0.9); + matches << match; + } else if (term.compare(i18nc("lock screen command","lock"), Qt::CaseInsensitive) == 0) { + if (KAuthorized::authorizeKAction("lock_screen")) { + Plasma::QueryMatch match(this); + match.setText(i18n("Lock the screen")); + match.setIcon(KIcon("system-lock-screen")); + match.setData(LockAction); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setRelevance(0.9); + matches << match; + } + } +} + +void SessionRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + QString user; + bool matchUser = false; + + QList matches; + + if (term.size() < 3) { + return; + } + + // first compare with SESSIONS. this must *NOT* be translated (i18n) + // as it is used as an internal command trigger (e.g. via d-bus), + // not as a user supplied query. and yes, "Ugh, magic strings" + bool listAll = term.compare("SESSIONS", Qt::CaseInsensitive) == 0 || + term.compare(i18nc("User sessions", "sessions"), Qt::CaseInsensitive) == 0; + + if (!listAll) { + //no luck, try the "switch" user command + if (term.startsWith(m_triggerWord, Qt::CaseInsensitive)) { + user = term.right(term.size() - m_triggerWord.length()).trimmed(); + listAll = user.isEmpty(); + matchUser = !listAll; + } else { + // we know it's not SESSION or "switch ", so let's + // try some other possibilities + matchCommands(matches, term); + } + } + + //kDebug() << "session switching to" << (listAll ? "all sessions" : term); + bool switchUser = listAll || + term.compare(i18n("switch user"), Qt::CaseInsensitive) == 0 || + term.compare(i18n("new session"), Qt::CaseInsensitive) == 0; + + if (switchUser && + KAuthorized::authorizeKAction("start_new_session") && + dm.isSwitchable() && + dm.numReserve() >= 0) { + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setIcon(KIcon("system-switch-user")); + match.setText(i18n("New Session")); + matches << match; + } + + // now add the active sessions + if (listAll || matchUser) { + SessList sessions; + dm.localSessions(sessions); + + foreach (const SessEnt& session, sessions) { + if (!session.vt || session.self) { + continue; + } + + QString name = KDisplayManager::sess2Str(session); + Plasma::QueryMatch::Type type = Plasma::QueryMatch::NoMatch; + qreal relevance = 0.7; + + if (listAll) { + type = Plasma::QueryMatch::ExactMatch; + relevance = 1; + } else if (matchUser) { + if (name.compare(user, Qt::CaseInsensitive) == 0) { + // we need an elif branch here because we don't + // want the last conditional to be checked if !listAll + type = Plasma::QueryMatch::ExactMatch; + relevance = 1; + } else if (name.contains(user, Qt::CaseInsensitive)) { + type = Plasma::QueryMatch::PossibleMatch; + } + } + + if (type != Plasma::QueryMatch::NoMatch) { + Plasma::QueryMatch match(this); + match.setType(type); + match.setRelevance(relevance); + match.setIcon(KIcon("user-identity")); + match.setText(name); + match.setData(QString::number(session.vt)); + matches << match; + } + } + } + + context.addMatches(term, matches); +} + +void SessionRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context); + if (match.data().type() == QVariant::Int) { + KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeDefault; + + switch (match.data().toInt()) { + case LogoutAction: + type = KWorkSpace::ShutdownTypeNone; + break; + case RestartAction: + type = KWorkSpace::ShutdownTypeReboot; + break; + case ShutdownAction: + type = KWorkSpace::ShutdownTypeHalt; + break; + case LockAction: + lock(); + return; + break; + } + + if (type != KWorkSpace::ShutdownTypeDefault) { + KWorkSpace::ShutdownConfirm confirm = KWorkSpace::ShutdownConfirmDefault; + KWorkSpace::requestShutDown(confirm, type); + return; + } + } + + if (!match.data().toString().isEmpty()) { + dm.lockSwitchVT(match.data().toString().toInt()); + return; + } + + //TODO: this message is too verbose and too technical. + int result = KMessageBox::warningContinueCancel( + 0, + i18n("

    You have chosen to open another desktop session.
    " + "The current session will be hidden " + "and a new login screen will be displayed.
    " + "An F-key is assigned to each session; " + "F%1 is usually assigned to the first session, " + "F%2 to the second session and so on. " + "You can switch between sessions by pressing " + "Ctrl, Alt and the appropriate F-key at the same time. " + "Additionally, the KDE Panel and Desktop menus have " + "actions for switching between sessions.

    ", + 7, 8), + i18n("Warning - New Session"), + KGuiItem(i18n("&Start New Session"), "fork"), + KStandardGuiItem::cancel(), + ":confirmNewSession", + KMessageBox::PlainCaption | KMessageBox::Notify); + + if (result == KMessageBox::Cancel) { + return; + } + + lock(); + dm.startReserve(); +} + +void SessionRunner::lock() +{ + QString interface("org.freedesktop.ScreenSaver"); + org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver", + QDBusConnection::sessionBus()); + if (screensaver.isValid()) { + screensaver.Lock(); + } +} + +#include "sessionrunner.moc" diff --git a/plasma/generic/runners/sessions/sessionrunner.h b/plasma/generic/runners/sessions/sessionrunner.h new file mode 100644 index 00000000..04196aa3 --- /dev/null +++ b/plasma/generic/runners/sessions/sessionrunner.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SESSIONRUNNER_H +#define SESSIONRUNNER_H + +#include +#include + + +/** + * This class provides matches for running sessions as well as + * an action to start a new session, etc. + */ +class SessionRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + SessionRunner(QObject *parent, const QVariantList &args); + ~SessionRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + + enum { LogoutAction = 1, ShutdownAction, RestartAction, LockAction }; + + private: + void lock(); + void matchCommands(QList &matches, const QString& term); + + QString m_triggerWord; + KDisplayManager dm; + bool m_canLogout; +}; + +K_EXPORT_PLASMA_RUNNER(sessions, SessionRunner) + +#endif + diff --git a/plasma/generic/runners/shell/CMakeLists.txt b/plasma/generic/runners/shell/CMakeLists.txt new file mode 100644 index 00000000..9c23d297 --- /dev/null +++ b/plasma/generic/runners/shell/CMakeLists.txt @@ -0,0 +1,12 @@ +set(krunner_shell_SRCS + shellrunner.cpp + shell_config.cpp +) + +kde4_add_ui_files(krunner_shell_SRCS shellOptions.ui) +kde4_add_plugin(krunner_shell ${krunner_shell_SRCS}) +target_link_libraries(krunner_shell ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_KDESU_LIBS}) + +install(TARGETS krunner_shell DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-runner-shell.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/shell/Messages.sh b/plasma/generic/runners/shell/Messages.sh new file mode 100755 index 00000000..5c826f4b --- /dev/null +++ b/plasma/generic/runners/shell/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_runner_shell.pot +rm -f rc.cpp diff --git a/plasma/generic/runners/shell/plasma-runner-shell.desktop b/plasma/generic/runners/shell/plasma-runner-shell.desktop new file mode 100644 index 00000000..344677a2 --- /dev/null +++ b/plasma/generic/runners/shell/plasma-runner-shell.desktop @@ -0,0 +1,168 @@ +[Desktop Entry] +Name=Command Line +Name[ar]=سطر الأوامر +Name[ast]=Execución d'órdenes +Name[be@latin]=Zahadny radok +Name[bg]=Команден ред +Name[bn]=কমান্ড লাইন +Name[bn_IN]=কমান্ড-লাইন +Name[bs]=komandna linija +Name[ca]=Línia d'ordres +Name[ca@valencia]=Línia d'ordes +Name[cs]=Příkazový řádek +Name[csb]=Réga pòlétu +Name[da]=Kommandolinje +Name[de]=Befehlszeile +Name[el]=Γραμμή εντολών +Name[en_GB]=Command Line +Name[eo]=Komandlinio +Name[es]=Ejecución de órdenes +Name[et]=Käsurida +Name[eu]=Komando-lerroa +Name[fi]=Komentorivi +Name[fr]=Ligne de commandes +Name[fy]=Kommandorigel +Name[ga]=Líne na nOrduithe +Name[gl]=Execución de ordes +Name[gu]=આદેશ જગ્યા +Name[he]=שורת הפקודה +Name[hi]=कमांड लाइन +Name[hne]=कमांड लाइन +Name[hr]=Naredbena linija +Name[hu]=Parancssor +Name[ia]=Linea de commando +Name[id]=Baris Perintah +Name[is]=Skipanalína +Name[it]=Riga di comando +Name[ja]=コマンドライン +Name[kk]=Команда жолы +Name[km]=បន្ទាត់​ពាក្យ​បញ្ជា +Name[kn]=ಆದೇಶ ತೆರೆ +Name[ko]=명령줄 +Name[ku]=Rêzika Fermanê +Name[lt]=Komandinė eilutė +Name[lv]=Komandrinda +Name[mai]=कमांड लाइन +Name[mk]=Командна линија +Name[ml]=ആജ്ഞാസ്ഥാനം +Name[mr]=आदेश ओळ +Name[nb]=Kommandolinje +Name[nds]=Konsool +Name[nl]=Commandoregel +Name[nn]=Kommandolinje +Name[oc]=Linha de comanda +Name[or]=ନିର୍ଦ୍ଦେଶନାମା +Name[pa]=ਕਮਾਂਡ ਲਾਈਨ +Name[pl]=Wiersz poleceń +Name[pt]=Linha de Comandos +Name[pt_BR]=Linha de comando +Name[ro]=Linie de comandă +Name[ru]=Запуск программ +Name[si]=විධාන රේඛාව +Name[sk]=Príkazový riadok +Name[sl]=Ukazna vrstica +Name[sr]=командна линија +Name[sr@ijekavian]=командна линија +Name[sr@ijekavianlatin]=komandna linija +Name[sr@latin]=komandna linija +Name[sv]=Kommandorad +Name[ta]=Command Line +Name[te]=ఆదేశ వరుస +Name[tg]=Иҷрои фармон +Name[th]=บรรทัดคำสั่ง +Name[tr]=Komut Satırı +Name[ug]=بۇيرۇق قۇرى +Name[uk]=Командний рядок +Name[vi]=Dòng lệnh +Name[wa]=Roye di cmande +Name[x-test]=xxCommand Linexx +Name[zh_CN]=命令行 +Name[zh_TW]=命令列 +Comment=Executes shell commands +Comment[ar]=ينفذ أوامر الصدفة +Comment[ast]=Executa órdenes de la consola +Comment[be@latin]=Vykanańnie zahadaŭ abałonki. +Comment[bg]=Изпълнение на команди на обвивката +Comment[bn]=শেল কমাণ্ড চালায় +Comment[bn_IN]=শেল কমান্ড সঞ্চালনের জন্য প্রয়োগ হবে +Comment[bs]=Izvršavanje naredbi školjke +Comment[ca]=Executa ordres de l'intèrpret d'ordres +Comment[ca@valencia]=Executa ordes de l'intèrpret d'ordes +Comment[cs]=Spouští shellové příkazy +Comment[da]=Kører skal-kommandoer +Comment[de]=Führt Shell-Befehle aus +Comment[el]=Εκτελεί εντολές του κελύφους +Comment[en_GB]=Executes shell commands +Comment[eo]=Plenumas ŝel-komandojn +Comment[es]=Ejecuta órdenes de la consola +Comment[et]=Shellikäskude käivitamine +Comment[eu]=Shell komandoak exekutatzen ditu +Comment[fi]=Suorittaa komentorivikomentoja +Comment[fr]=Exécute des commandes shell +Comment[fy]=Flueskommando's útfiere +Comment[ga]=Rith orduithe blaoisce +Comment[gl]=Executa ordes da shell +Comment[gu]=શૅલ આદેશ ચલાવો +Comment[he]=משמש להרצת פקודות Shell +Comment[hi]=शेल कमांड्स चलाता है +Comment[hne]=सेल कमांड चलाथे +Comment[hr]=Izvodi naredbe ljuske +Comment[hu]=Parancsokat hajt végre terminálban +Comment[ia]=Il exeque commandos de shell +Comment[id]=Eksekusi perintah shell +Comment[is]=Framkvæmir skeljarskipanir +Comment[it]=Esegue comandi della shell +Comment[ja]=シェルコマンドを実行します +Comment[kk]=Қоршау-орта командаларын орындау +Comment[km]=ប្រតិបត្តិ​ពាក្យ​បញ្ជា​សែល +Comment[kn]=ಆದೇಶಗ್ರಾಹಿ (ಶೆಲ್) ಆದೇಶಗಳನ್ನು ಚಾಲಯಿಸುತ್ತದೆ +Comment[ko]=셸 명령 실행 +Comment[ku]=Fermanên Shelê yên xebatî +Comment[lt]=Vykdyti apvalkalo komandas +Comment[lv]=Darbina čaulas komandas +Comment[mk]=Извршува наредби за школка +Comment[ml]=ഷെല്‍ ആജ്ഞകള്‍ നടപ്പിലാക്കുക +Comment[mr]=शेल आदेश चालवितो +Comment[nb]=Kjører skallkommando +Comment[nds]=Föhrt Konsoolbefehlen ut +Comment[nl]=Voert shellcommando's uit +Comment[nn]=Køyr skalkommandoar +Comment[or]=ସେଲ ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକୁ ନିଷ୍ପାଦନ କରନ୍ତୁ +Comment[pa]=ਸ਼ੈੱਲ ਕਮਾਂਡਾਂ ਚਲਾਓ +Comment[pl]=Wykonuje polecenia powłoki +Comment[pt]=Executa comandos da consola +Comment[pt_BR]=Executa comandos do shell +Comment[ro]=Execută comenzi de consolă +Comment[ru]=Запуск исполняемых программ +Comment[si]=ශෙල් විධාන ක්‍රියාකරවන්න +Comment[sk]=Vykonanie príkazov shellu +Comment[sl]=Izvede lupinske ukaze +Comment[sr]=Извршавање наредби шкољке +Comment[sr@ijekavian]=Извршавање наредби шкољке +Comment[sr@ijekavianlatin]=Izvršavanje naredbi školjke +Comment[sr@latin]=Izvršavanje naredbi školjke +Comment[sv]=Kör skalkommandon +Comment[ta]=Executes shell commands +Comment[te]=షెల్ ఆదేశాలను నిర్వర్తిస్తుంది +Comment[tg]=Выполняет команды оболочки +Comment[th]=ประมวลผลคำสั่งของเชลล์ +Comment[tr]=Kabuk komutlarını çalıştırır +Comment[ug]=shell بۇيرۇقنى ئىجرا قىلىدۇ +Comment[uk]=Виконує команди оболонки +Comment[vi]=Thực hiện các lệnh vỏ +Comment[wa]=Enonde des comandes shell +Comment[x-test]=xxExecutes shell commandsxx +Comment[zh_CN]=执行 shell 命令 +Comment[zh_TW]=執行 shell 指令 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=system-run +X-KDE-Library=krunner_shell +X-Plasma-RunnerPhase=first +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=shell +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/shell/shellOptions.ui b/plasma/generic/runners/shell/shellOptions.ui new file mode 100644 index 00000000..83d890b7 --- /dev/null +++ b/plasma/generic/runners/shell/shellOptions.ui @@ -0,0 +1,264 @@ + + + shellOptions + + + + 0 + 0 + 325 + 112 + + + + + 0 + 0 + + + + + 0 + + + 3 + + + + + 3 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 3 + + + + + false + + + + 0 + 0 + + + + Enter the user you want to run the application as here. + + + User&name: + + + leUsername + + + + + + + false + + + + 5 + 0 + + + + Enter the password here for the user you specified above. + + + QLineEdit::Password + + + + + + + false + + + + 0 + 0 + + + + Enter the password here for the user you specified above. + + + Pass&word: + + + lePassword + + + + + + + Check this option if the application you want to run is a text mode application. The application will then be run in a terminal emulator window. + + + Run in &terminal window + + + + + + + false + + + + 5 + 0 + + + + Enter the user you want to run the application as here. + + + + + + + Check this option if you want to run the application with a different user id. Every process has a user id associated with it. This id code determines file access and other permissions. The password of the user is required to do this. + + + Run as a different &user + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + KLineEdit + QLineEdit +
    klineedit.h
    +
    +
    + + cbRunInTerminal + cbRunAsOther + leUsername + lePassword + + + + + cbRunAsOther + toggled(bool) + lbUsername + setEnabled(bool) + + + 153 + 59 + + + 96 + 62 + + + + + cbRunAsOther + toggled(bool) + leUsername + setEnabled(bool) + + + 127 + 59 + + + 188 + 62 + + + + + cbRunAsOther + toggled(bool) + lbPassword + setEnabled(bool) + + + 81 + 45 + + + 146 + 101 + + + + + cbRunAsOther + toggled(bool) + lePassword + setEnabled(bool) + + + 114 + 41 + + + 323 + 101 + + + + +
    diff --git a/plasma/generic/runners/shell/shell_config.cpp b/plasma/generic/runners/shell/shell_config.cpp new file mode 100644 index 00000000..03efebbd --- /dev/null +++ b/plasma/generic/runners/shell/shell_config.cpp @@ -0,0 +1,61 @@ + +/*************************************************************************** + * Copyright 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "shell_config.h" + + +#include +#include +#include +#include + +#include + +ShellConfig::ShellConfig(const KConfigGroup &config, QWidget* parent) + : QWidget(parent), + m_config(config) +{ + QHBoxLayout *hboxLayout = new QHBoxLayout(parent); + hboxLayout->addWidget(this); + m_ui.setupUi(this); + +#ifdef Q_OS_UNIX + connect(m_ui.cbRunAsOther, SIGNAL(clicked(bool)), this, SLOT(slotUpdateUser(bool))); +#else + m_ui.cbRunAsOther->hide(); + m_ui.lbUsername->hide(); + m_ui.leUsername->hide(); + m_ui.lbPassword->hide(); + m_ui.lePassword->hide(); +#endif +} + +ShellConfig::~ShellConfig() +{ +} + +void ShellConfig::slotUpdateUser(bool b) +{ + if (b) { + m_ui.leUsername->setFocus(); + } +} + +#include "shell_config.moc" diff --git a/plasma/generic/runners/shell/shell_config.h b/plasma/generic/runners/shell/shell_config.h new file mode 100644 index 00000000..97ae7829 --- /dev/null +++ b/plasma/generic/runners/shell/shell_config.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright 2008 by Montel Laurent * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SHELLCONFIG_H +#define SHELLCONFIG_H + +#include + +#include + +#include "ui_shellOptions.h" + +class ShellConfig : public QWidget +{ + Q_OBJECT + public: + explicit ShellConfig(const KConfigGroup &config, QWidget* parent = 0); + ~ShellConfig(); + + Ui::shellOptions m_ui; + + protected slots: + void slotUpdateUser(bool); + + private: + KConfigGroup m_config; +}; + +#endif diff --git a/plasma/generic/runners/shell/shellrunner.cpp b/plasma/generic/runners/shell/shellrunner.cpp new file mode 100644 index 00000000..dd24e8fd --- /dev/null +++ b/plasma/generic/runners/shell/shellrunner.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "shellrunner.h" + +#include +#include + +#include +#include +#ifdef Q_OS_UNIX +#include +#endif +#include +#include +#include +#include +#include +#include + +#include + +#include "shell_config.h" + +ShellRunner::ShellRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args), + m_inTerminal(false), + m_asOtherUser(false) +{ + setObjectName( QLatin1String("Command" )); + setPriority(AbstractRunner::HighestPriority); + setHasRunOptions(true); + m_enabled = KAuthorized::authorizeKAction("run_command") && KAuthorized::authorizeKAction("shell_access"); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | + Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::UnknownType | + Plasma::RunnerContext::Help); + + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds commands that match :q:, using common shell syntax"))); +} + +ShellRunner::~ShellRunner() +{ +} + +void ShellRunner::match(Plasma::RunnerContext &context) +{ + if (!m_enabled) { + return; + } + + if (context.type() == Plasma::RunnerContext::Executable || + context.type() == Plasma::RunnerContext::ShellCommand) { + const QString term = context.query(); + Plasma::QueryMatch match(this); + match.setId(term); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setIcon(KIcon("system-run")); + match.setText(i18n("Run %1", term)); + match.setRelevance(0.7); + context.addMatch(term, match); + } +} + +void ShellRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(match); + + // filter match's id to remove runner's name + // as this is the command we want to run + + if (m_enabled) { +#ifdef Q_OS_UNIX + //kDebug() << m_asOtherUser << m_username << m_password; + if (m_asOtherUser && !m_username.isEmpty()) { + //TODO: provide some user feedback on failure + QString exec; + QString args; + if (m_inTerminal) { + // we have to reimplement this from KToolInvocation because we need to use KDESu + KConfigGroup confGroup( KGlobal::config(), "General" ); + exec = confGroup.readPathEntry("TerminalApplication", "konsole"); + if (!exec.isEmpty()) { + if (exec == "konsole") { + args += " --noclose"; + } else if (exec == "xterm") { + args += " -hold"; + } + + args += " -e " + context.query(); + } + } else { + const QStringList commandLine = KShell::splitArgs(context.query(), KShell::TildeExpand); + if (!commandLine.isEmpty()) { + exec = commandLine.at(0); + } + + args = context.query().right(context.query().size() - commandLine.at(0).length()); + } + + if (!exec.isEmpty()) { + exec = KStandardDirs::findExe(exec); + exec.append(args); + if (!exec.isEmpty()) { + KDESu::SuProcess client(m_username.toLocal8Bit(), exec.toLocal8Bit()); + const QByteArray password = m_password.toLocal8Bit(); + //TODO handle errors like wrong password via KNotifications in 4.7 + client.exec(password.constData()); + } + } + } else +#endif + if (m_inTerminal) { + KToolInvocation::invokeTerminal(context.query()); + } else { + KRun::runCommand(context.query(), NULL); + } + } + + // reset for the next run! + m_inTerminal = false; + m_asOtherUser = false; + m_username.clear(); + m_password.clear(); +} + +void ShellRunner::createRunOptions(QWidget *parent) +{ + //TODO: for multiple runners? + //TODO: sync palette on theme changes + ShellConfig *configWidget = new ShellConfig(config(), parent); + + QPalette pal = configWidget->palette(); + Plasma::Theme *theme = Plasma::Theme::defaultTheme(); + pal.setColor(QPalette::Normal, QPalette::Window, theme->color(Plasma::Theme::BackgroundColor)); + pal.setColor(QPalette::Normal, QPalette::WindowText, theme->color(Plasma::Theme::TextColor)); + configWidget->setPalette(pal); + + connect(configWidget->m_ui.cbRunAsOther, SIGNAL(clicked(bool)), this, SLOT(setRunAsOtherUser(bool))); + connect(configWidget->m_ui.cbRunInTerminal, SIGNAL(clicked(bool)), this, SLOT(setRunInTerminal(bool))); + connect(configWidget->m_ui.leUsername, SIGNAL(textChanged(QString)), this, SLOT(setUsername(QString))); + connect(configWidget->m_ui.lePassword, SIGNAL(textChanged(QString)), this, SLOT(setPassword(QString))); +} + +void ShellRunner::setRunAsOtherUser(bool asOtherUser) +{ + m_asOtherUser = asOtherUser; +} + +void ShellRunner::setRunInTerminal(bool runInTerminal) +{ + m_inTerminal = runInTerminal; +} + +void ShellRunner::setUsername(const QString &username) +{ + m_username = username; +} + +void ShellRunner::setPassword(const QString &password) +{ + m_password = password; +} + +#include "shellrunner.moc" diff --git a/plasma/generic/runners/shell/shellrunner.h b/plasma/generic/runners/shell/shellrunner.h new file mode 100644 index 00000000..208f8dc5 --- /dev/null +++ b/plasma/generic/runners/shell/shellrunner.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SHELLRUNNER_H +#define SHELLRUNNER_H + +#include + +class QWidget; + + +/** + * This class runs programs using the literal name of the binary, much as one + * would use at a shell prompt. + */ +class ShellRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + ShellRunner(QObject *parent, const QVariantList &args); + ~ShellRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + void createRunOptions(QWidget *parent); + + private Q_SLOTS: + void setRunAsOtherUser(bool asOtherUser); + void setRunInTerminal(bool runInTerminal); + void setUsername(const QString &username); + void setPassword(const QString &password); + + private: + QString m_username; + QString m_password; + bool m_enabled; + bool m_inTerminal; + bool m_asOtherUser; +}; + +K_EXPORT_PLASMA_RUNNER(shell, ShellRunner) + +#endif diff --git a/plasma/generic/runners/solid/CMakeLists.txt b/plasma/generic/runners/solid/CMakeLists.txt new file mode 100644 index 00000000..4b17c3d9 --- /dev/null +++ b/plasma/generic/runners/solid/CMakeLists.txt @@ -0,0 +1,11 @@ +set(krunner_solid_SRCS + solidrunner.cpp + devicewrapper.cpp +) + +kde4_add_plugin(krunner_solid ${krunner_solid_SRCS}) +target_link_libraries(krunner_solid ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS krunner_solid DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-solid.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/runners/solid/Messages.sh b/plasma/generic/runners/solid/Messages.sh new file mode 100644 index 00000000..101576f5 --- /dev/null +++ b/plasma/generic/runners/solid/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_solid.pot + diff --git a/plasma/generic/runners/solid/devicewrapper.cpp b/plasma/generic/runners/solid/devicewrapper.cpp new file mode 100644 index 00000000..176065cc --- /dev/null +++ b/plasma/generic/runners/solid/devicewrapper.cpp @@ -0,0 +1,210 @@ +/************************************************************************** + * Copyright 2009 by Jacopo De Simoi * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +//own +#include "devicewrapper.h" + +//Qt +#include +#include +#include +#include + +//Solid +#include +#include +#include +#include +#include + +//KDE +#include +#include +#include +#include + +//Plasma +#include + +DeviceWrapper::DeviceWrapper(const QString& udi) + : m_device(udi), + m_isStorageAccess(false), + m_isAccessible(false), + m_isEncryptedContainer(false) +{ + m_udi = m_device.udi(); +} + +DeviceWrapper::~DeviceWrapper() +{ +} + +void DeviceWrapper::dataUpdated(const QString &source, Plasma::DataEngine::Data data) +{ + Q_UNUSED(source) + + if (data.isEmpty()) { + return; + } + if (data["text"].isValid()) { + m_actionIds.clear(); + foreach (const QString &desktop, data["predicateFiles"].toStringList()) { + QString filePath = KStandardDirs::locate("data", "solid/actions/" + desktop); + QList services = KDesktopFileActions::userDefinedServices(filePath, true); + + foreach (KServiceAction serviceAction, services) { + QString actionId = id()+'_'+desktop+'_'+serviceAction.name(); + m_actionIds << actionId; + emit registerAction(actionId, serviceAction.icon(), serviceAction.text(), desktop); + } + } + m_isEncryptedContainer = data["isEncryptedContainer"].toBool(); + } else { + if (data["Device Types"].toStringList().contains("Storage Access")) { + m_isStorageAccess = true; + if (data["Accessible"].toBool() == true) { + m_isAccessible = true; + } else { + m_isAccessible = false; + } + } else { + m_isStorageAccess = false; + } + if (data["Device Types"].toStringList().contains("OpticalDisc")) { + m_isOpticalDisc = true; + } else { + m_isOpticalDisc = false; + } + } + + m_emblems = m_device.emblems(); + m_description = m_device.description(); + m_iconName = m_device.icon(); + + emit refreshMatch(m_udi); +} + +QString DeviceWrapper::id() const { + return m_udi; +} + +Solid::Device DeviceWrapper::device() const { + return m_device; +} + +KIcon DeviceWrapper::icon() const { + return KIcon(m_iconName, NULL, m_emblems); +} + +bool DeviceWrapper::isStorageAccess() const { + return m_isStorageAccess; +} + +bool DeviceWrapper::isAccessible() const { + return m_isAccessible; +} + +bool DeviceWrapper::isEncryptedContainer() const { + return m_isEncryptedContainer; +} + +bool DeviceWrapper::isOpticalDisc() const { + return m_isOpticalDisc; +} + +QString DeviceWrapper::description() const { + return m_description; +} + +void DeviceWrapper::setForceEject(bool force) +{ + m_forceEject = force; +} + +QString DeviceWrapper::defaultAction() const { + + QString actionString; + + if (m_isOpticalDisc && m_forceEject) { + actionString = i18n("Eject medium"); + } else if (m_isStorageAccess) { + if (!m_isEncryptedContainer) { + if (!m_isAccessible) { + actionString = i18n("Mount the device"); + } else { + actionString = i18n("Unmount the device"); + } + } else { + if (!m_isAccessible) { + actionString = i18nc("Unlock the encrypted container; will ask for a password; partitions inside will appear as they had been plugged in","Unlock the container"); + } else { + actionString = i18nc("Close the encrypted container; partitions inside will disappear as they had been unplugged", "Lock the container"); + } + } + } else { + actionString = i18n("Eject medium"); + } + return actionString; +} + +void DeviceWrapper::runAction(QAction * action) +{ + if (action) { + QString desktopAction = action->data().toString(); + if (!desktopAction.isEmpty()) { + QStringList desktopFiles; + desktopFiles.append(desktopAction); + QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer"); + soliduiserver.asyncCall("showActionsDialog", id(), desktopFiles); + } + } else { + if (isOpticalDisc() && m_forceEject) { + Solid::OpticalDrive *drive = m_device.parent().as(); + if (drive) { + drive->eject(); + } + return; + } + + if (m_device.is()) { + Solid::StorageAccess *access = m_device.as(); + if (access) { + if (access->isAccessible()) { + access->teardown(); + } else { + access->setup(); + } + return; + } + } + + if (isOpticalDisc()) { + Solid::OpticalDrive *drive = m_device.parent().as(); + if (drive) { + drive->eject(); + } + } + } +} + +QStringList DeviceWrapper::actionIds() const +{ + return m_actionIds; +} + +#include "devicewrapper.moc" diff --git a/plasma/generic/runners/solid/devicewrapper.h b/plasma/generic/runners/solid/devicewrapper.h new file mode 100644 index 00000000..c42eded5 --- /dev/null +++ b/plasma/generic/runners/solid/devicewrapper.h @@ -0,0 +1,89 @@ +/************************************************************************** + * Copyright 2009 by Jacopo De Simoi * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef DEVICEWRAPPER_H +#define DEVICEWRAPPER_H + +#include + +#include + +#include + +#include + + +#include + +class DeviceWrapper : public QObject +{ + Q_OBJECT + + public: + DeviceWrapper(const QString& udi); + ~DeviceWrapper(); + + QString id() const; + Solid::Device device() const; + KIcon icon() const; + bool isStorageAccess() const; + bool isAccessible() const; + bool isOpticalDisc() const; + bool isEncryptedContainer() const; + QString description() const; + QString defaultAction() const; + void runAction(QAction *) ; + QStringList actionIds() const; + void setForceEject(bool force); + + signals: + void registerAction(QString &id, QString icon, QString text, QString desktop); + void refreshMatch(QString &id); + + protected slots: + + /** + * slot called when a source of the hotplug engine is updated + * @param source the name of the source + * @param data the data of the source + * + * @internal + **/ + void dataUpdated(const QString &source, Plasma::DataEngine::Data data); + + private: + + Solid::Device m_device; + QString m_iconName; + bool m_isStorageAccess; + bool m_isAccessible; + bool m_isEncryptedContainer; + bool m_isOpticalDisc; + bool m_forceEject; + QString m_description; + QStringList m_actionIds; + // Solid doesn't like multithreading that much + // We cache the informations we need locally so that + // 1) nothing possibly goes wrong when processing a query + // 2) performance++ + + QString m_udi; + QStringList m_emblems; +}; + +#endif //DEVICEWRAPPER_H diff --git a/plasma/generic/runners/solid/plasma-runner-solid.desktop b/plasma/generic/runners/solid/plasma-runner-solid.desktop new file mode 100644 index 00000000..372817b5 --- /dev/null +++ b/plasma/generic/runners/solid/plasma-runner-solid.desktop @@ -0,0 +1,150 @@ +[Desktop Entry] +# ctxt: plasma runner +Name=Devices +Name[ar]=الأجهزة +Name[ast]=Preseos +Name[bg]=Устройства +Name[bn]=ডিভাইস +Name[bs]=uređaji +Name[ca]=Dispositius +Name[ca@valencia]=Dispositius +Name[cs]=Zařízení +Name[csb]=Ùrządzenia +Name[da]=Enheder +Name[de]=Geräte +Name[el]=Συσκευές +Name[en_GB]=Devices +Name[eo]=Aparatoj +Name[es]=Dispositivos +Name[et]=Seadmed +Name[eu]=Gailuak +Name[fa]=دستگاهها +Name[fi]=Laitteet +Name[fr]=Périphériques +Name[fy]=Apparaten +Name[ga]=Gléasanna +Name[gl]=Dispositivos +Name[gu]=ઉપકરણો +Name[he]=התקנים +Name[hi]=औज़ार +Name[hr]=Uređaji +Name[hu]=Eszközök +Name[ia]=Dispositivos +Name[id]=Divais +Name[is]=Tæki +Name[it]=Dispositivi +Name[ja]=デバイス +Name[kk]=Құрылғылар +Name[km]=ឧបករណ៍ +Name[kn]=ಸಾಧನಗಳು +Name[ko]=장치 +Name[lt]=Įrenginiai +Name[lv]=Ierīces +Name[mk]=Уреди +Name[ml]=ഉപകരണങ്ങള്‍ +Name[mr]=साधने +Name[nb]=Enhet +Name[nds]=Reedschappen +Name[nl]=Apparaten +Name[nn]=Einingar +Name[pa]=ਜੰਤਰ +Name[pl]=Urządzenia +Name[pt]=Dispositivos +Name[pt_BR]=Dispositivos +Name[ro]=Dispozitive +Name[ru]=Устройства +Name[si]=මෙවලම් +Name[sk]=Zariadenia +Name[sl]=Naprave +Name[sr]=уређаји +Name[sr@ijekavian]=уређаји +Name[sr@ijekavianlatin]=uređaji +Name[sr@latin]=uređaji +Name[sv]=Enheter +Name[tg]=Дастгоҳҳо +Name[th]=อุปกรณ์ต่าง ๆ +Name[tr]=Aygıtlar +Name[ug]=ئۈسكۈنىلەر +Name[uk]=Пристрої +Name[vi]=Thiết bị +Name[wa]=Éndjins +Name[x-test]=xxDevicesxx +Name[zh_CN]=设备 +Name[zh_TW]=裝置 +Comment=Manage removable devices +Comment[ar]=أدر الأجهزة القابلة للإزالة +Comment[ast]=Xestionar preseos estrayibles +Comment[bn]=অপসারণযোগ্য ডিভাইস ব্যবস্থাপনা +Comment[bs]=Upravljanje uklonjivim uređajima +Comment[ca]=Gestiona dispositius extraïbles +Comment[ca@valencia]=Gestiona dispositius extraïbles +Comment[cs]=Spravovat odpojitelná zařízení +Comment[csb]=Sprôwiôj przenosnyma ùrządzeniama +Comment[da]=Håndtér flytbare enheder +Comment[de]=Wechselmedien verwalten +Comment[el]=Διαχείριση αφαιρούμενων συσκευών +Comment[en_GB]=Manage removable devices +Comment[es]=Gestionar dispositivos extraíbles +Comment[et]=Eemaldatavate seadmete haldamine +Comment[eu]=Kudeatu gailu eramangarriak +Comment[fi]=Hallitse irrotettavia laitteita +Comment[fr]=Gère les périphériques amovibles +Comment[fy]=Utnimbere apparaten beheare +Comment[ga]=Bainistigh gléasanna inbhainte +Comment[gl]=Xestiona os dispositivos extraíbeis +Comment[he]=משמש לניהול התקנים נשלפים +Comment[hr]=Upravlja uklonjivim uređajima +Comment[hu]=Cserélhető eszközök kezelése +Comment[ia]=Gere dispositivos removibile +Comment[id]=Kelola divais dapat dilepas +Comment[is]=Sýsla með fjarlægjanleg tæki +Comment[it]=Gestisci i dispositivi rimovibili +Comment[ja]=リムーバブルデバイスを管理します +Comment[kk]=Ауыстырмалы құрылғыларды басқару +Comment[km]=គ្រប់គ្រង​ឧបករណ៍​ដែល​ចល័ត​បាន +Comment[kn]=ತೆಗೆದು ಹಾಕಬಹುದಾದ ಸಾಧನಗಳನ್ನು ವ್ಯವಸ್ಥಾಪಿಸಿ +Comment[ko]=이동식 장치를 관리합니다 +Comment[lt]=Tvarkyti keičiamuosius įrenginius +Comment[lv]=Pārvaldīt noņemamās iekārtas +Comment[mk]=Ракувајте со подвижните уреди +Comment[ml]=നീക്കം ചെയ്യാവുന്ന ഉപകരണങ്ങള്‍ നോക്കി നടത്തല്‍ +Comment[mr]=काढता येणाऱ्या साधनांचे व्यवस्थापन करा +Comment[nb]=Flyttbar +Comment[nds]=Tuuschbor Reedschappen plegen +Comment[nl]=Verwijderbare apparaten beheren +Comment[nn]=Handter flyttbare einingar +Comment[pa]=ਹਟਾਉਣਯੋਗ ਜੰਤਰ ਪਰਬੰਧ +Comment[pl]=Zarządzanie urządzeniami wymiennymi +Comment[pt]=Gerir os dispositivos removíveis +Comment[pt_BR]=Gerencia dispositivos removíveis +Comment[ro]=Gestionează dispozitive amovibile +Comment[ru]=Управление подключаемыми устройствами +Comment[si]=ඉවත් කල හැකි මෙවලම් කළමනාකරනය කරන්න +Comment[sk]=Správa vymeniteľných zariadení +Comment[sl]=Upravljanje odstranljivih naprav +Comment[sr]=Управљање уклоњивим уређајима +Comment[sr@ijekavian]=Управљање уклоњивим уређајима +Comment[sr@ijekavianlatin]=Upravljanje uklonjivim uređajima +Comment[sr@latin]=Upravljanje uklonjivim uređajima +Comment[sv]=Hantera flyttbara enheter +Comment[tg]=Идоракунии дастгоҳҳои ҷудошаванда +Comment[th]=จัดการอุปกรณ์ที่สามารถถอด/เสียบได้ +Comment[tr]=Çıkarılabilir aygıtları yönet +Comment[ug]=كۆچمە ئۈسكۈنىلەرنى باشقۇرۇش +Comment[uk]=Керування портативними пристроями +Comment[vi]=Quản lý thiết bị gắn ngoài +Comment[wa]=Manaedjî oiståves éndjins +Comment[x-test]=xxManage removable devicesxx +Comment[zh_CN]=管理移动设备 +Comment[zh_TW]=管理可移除裝置 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=device-notifier +X-KDE-Library=krunner_solid +X-KDE-PluginInfo-Author=Jacopo De Simoi +X-KDE-PluginInfo-Email=wilderkde@gmail.com +X-KDE-PluginInfo-Name=solid +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/solid/solidrunner.cpp b/plasma/generic/runners/solid/solidrunner.cpp new file mode 100644 index 00000000..c6266523 --- /dev/null +++ b/plasma/generic/runners/solid/solidrunner.cpp @@ -0,0 +1,286 @@ +/*************************************************************************** + * Copyright 2009 by Jacopo De Simoi * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +//own +#include "solidrunner.h" +#include "devicewrapper.h" + +//Qt +#include + +//KDE +#include + +//Plasma +#include +#include + +//Solid +#include + +using namespace Plasma; + +SolidRunner::SolidRunner(QObject* parent, const QVariantList& args) + : AbstractRunner(parent, args), + m_deviceList() +{ + Q_UNUSED(args) + setObjectName( QLatin1String("Solid" )); + + m_engineManager = Plasma::DataEngineManager::self(); + + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds devices whose name match :q:"))); + + setDefaultSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "device"), + i18n("Lists all devices and allows them to be mounted, unmounted or ejected."))); + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "mount"), + i18n("Lists all devices which can be mounted, and allows them to be mounted."))); + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "unlock"), + i18n("Lists all encrypted devices which can be unlocked, and allows them to be unlocked."))); + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "unmount"), + i18n("Lists all devices which can be unmounted, and allows them to be unmounted."))); + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "lock"), + i18n("Lists all encrypted devices which can be locked, and allows them to be locked."))); + + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "eject"), + i18n("Lists all devices which can be ejected, and allows them to be ejected."))); + +} + +SolidRunner::~SolidRunner() +{ +} + +void SolidRunner::init() +{ + + m_hotplugEngine = dataEngine("hotplug"); + m_solidDeviceEngine = dataEngine("soliddevice"); + + //connect to engine when a device is plugged + connect(m_hotplugEngine, SIGNAL(sourceAdded(QString)), + this, SLOT(onSourceAdded(QString))); + connect(m_hotplugEngine, SIGNAL(sourceRemoved(QString)), + this, SLOT(onSourceRemoved(QString))); + fillPreviousDevices(); +} + +void SolidRunner::cleanActionsForDevice(DeviceWrapper * dev) +{ + const QStringList actionIds = dev->actionIds(); + if (!actionIds.isEmpty()) { + foreach (const QString& id, actionIds) { + removeAction(id); + } + } +} + +QList SolidRunner::actionsForMatch(const Plasma::QueryMatch &match) +{ + QList actions; + + DeviceWrapper* dev = m_deviceList.value(match.data().toString()); + if (dev) { + QStringList actionIds = dev->actionIds(); + if (!actionIds.isEmpty()) { + foreach (const QString& id, actionIds) { + actions << action(id); + } + } + } + return actions; +} + +void SolidRunner::match(Plasma::RunnerContext& context) +{ + m_currentContext = context; + createOrUpdateMatches(m_deviceList.keys()); +} + +void SolidRunner::createOrUpdateMatches(const QStringList &udiList) +{ + const QString term = m_currentContext.query(); + + if (!m_currentContext.isValid()) { + return; + } + + if (!m_currentContext.singleRunnerQueryMode() && (term.length() < 3)) { + return; + } + QList matches; + + // keyword match: when term starts with "device" we list all devices + QStringList keywords = term.split(" "); + QString deviceDescription; + bool onlyMounted = false; + bool onlyMountable = false; + bool onlyEncrypted = false; + bool onlyOptical = false; + bool forceEject = false; + bool showDevices = false; + if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "device") , Qt::CaseInsensitive)) { + showDevices = true; + keywords.removeFirst(); + } + + if (!keywords.isEmpty()) { + if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "mount") , Qt::CaseInsensitive)) { + showDevices = true; + onlyMountable = true; + keywords.removeFirst(); + } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unmount") , Qt::CaseInsensitive)) { + showDevices = true; + onlyMounted = true; + keywords.removeFirst(); + } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "eject") , Qt::CaseInsensitive)) { + showDevices = true; + onlyOptical = true; + forceEject = true; + keywords.removeFirst(); + } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "unlock") , Qt::CaseInsensitive)) { + showDevices = true; + onlyMountable = true; + onlyEncrypted = true; + keywords.removeFirst(); + } else if (keywords[0].startsWith(i18nc("Note this is a KRunner keyword", "lock") , Qt::CaseInsensitive)) { + showDevices = true; + onlyMounted = true; + onlyEncrypted = true; + keywords.removeFirst(); + } + } + + if (!keywords.isEmpty()) { + deviceDescription = keywords[0]; + } + + foreach (const QString& udi, udiList) { + DeviceWrapper * dev = m_deviceList.value(udi); + if ((deviceDescription.isEmpty() && showDevices) || dev->description().contains(deviceDescription, Qt::CaseInsensitive)) { + // This is getting quite messy indeed + if (((!onlyEncrypted) || (onlyEncrypted && dev->isEncryptedContainer())) && + ((!onlyOptical) || (onlyOptical && dev->isOpticalDisc())) && + ((onlyMounted && dev->isAccessible()) || + (onlyMountable && dev->isStorageAccess() && !dev->isAccessible()) || + (!onlyMounted && !onlyMountable))) { + dev->setForceEject(forceEject); + Plasma::QueryMatch match = deviceMatch(dev); + if (dev->description().compare(deviceDescription, Qt::CaseInsensitive)) { + match.setType(Plasma::QueryMatch::ExactMatch); + } else if (deviceDescription.isEmpty()) { + match.setType(Plasma::QueryMatch::PossibleMatch); + } else { + match.setType(Plasma::QueryMatch::CompletionMatch); + } + matches << match; + } + } + } + + if (!matches.isEmpty()) { + m_currentContext.addMatches(term, matches); + } +} + +Plasma::QueryMatch SolidRunner::deviceMatch(DeviceWrapper * device) +{ + Plasma::QueryMatch match(this); + match.setId(device->id()); + match.setData(device->id()); + match.setIcon(device->icon()); + match.setText(device->description()); + + match.setSubtext(device->defaultAction()); + + //Put them in order such that the last added device is on top. + match.setRelevance(0.5+0.1*qreal(m_udiOrderedList.indexOf(device->id()))/qreal(m_udiOrderedList.count())); + + return match; +} + +void SolidRunner::run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match) +{ + Q_UNUSED(context) + + DeviceWrapper *device = m_deviceList.value(match.data().toString()); + if (device) { + device->runAction(match.selectedAction()); + } +} + +void SolidRunner::registerAction(QString &id, QString icon, QString text, QString desktop) +{ + QAction* action = addAction(id, KIcon(icon), text); + action->setData(desktop); +} + +void SolidRunner::refreshMatch(QString &id) +{ + if (!m_currentContext.isValid()) { + return; + } + + QueryMatch match(this); + match.setId(id); + m_currentContext.removeMatch(match.id()); + QStringList deviceList; + deviceList << id; + createOrUpdateMatches(deviceList); +} + +void SolidRunner::onSourceAdded(const QString &name) +{ + DeviceWrapper * device = new DeviceWrapper(name); + connect(device, SIGNAL(registerAction(QString&,QString,QString,QString)), + this, SLOT(registerAction(QString&,QString,QString,QString))); + connect(device, SIGNAL(refreshMatch(QString&)), this, SLOT(refreshMatch(QString&))); + + m_deviceList.insert(name, device); + m_udiOrderedList << name; + m_hotplugEngine->connectSource(name, device); + m_solidDeviceEngine->connectSource(name, device); +} + +void SolidRunner::onSourceRemoved(const QString &name) +{ + DeviceWrapper * device = m_deviceList.value(name); + if (device) { + m_hotplugEngine->disconnectSource(name, device); + m_solidDeviceEngine->disconnectSource(name, device); + disconnect(device, 0, this, 0); + cleanActionsForDevice(device); + m_deviceList.remove(name); + m_udiOrderedList.removeAll(name); + if (m_currentContext.isValid()) { + QueryMatch match(this); + match.setId(device->id()); + m_currentContext.removeMatch(match.id()); + } + delete device; + } +} + +void SolidRunner::fillPreviousDevices() +{ + foreach (const QString &source, m_hotplugEngine->sources()) { + onSourceAdded(source); + } +} + +#include "solidrunner.moc" diff --git a/plasma/generic/runners/solid/solidrunner.h b/plasma/generic/runners/solid/solidrunner.h new file mode 100644 index 00000000..beac2a85 --- /dev/null +++ b/plasma/generic/runners/solid/solidrunner.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright 2009 by Jacopo De Simoi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ +#ifndef SOLIDRUNNER_H +#define SOLIDRUNNER_H + +#include + +namespace Plasma { + class DataEngine; + class DataEngineManager; + class RunnerContext; +} + +class DeviceWrapper; + +class SolidRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + SolidRunner(QObject* parent, const QVariantList &args); + ~SolidRunner(); + + virtual void match(Plasma::RunnerContext& context); + virtual void run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match); + + + protected: + QList actionsForMatch(const Plasma::QueryMatch &match); + + protected slots: + + void init(); + void onSourceAdded(const QString &name); + void onSourceRemoved(const QString &name); + + private slots: + void registerAction(QString &id, QString icon, QString text, QString desktop); + void refreshMatch(QString &id); + + private: + + void fillPreviousDevices(); + void cleanActionsForDevice(DeviceWrapper *); + void createOrUpdateMatches(const QStringList &udiList); + + Plasma::QueryMatch deviceMatch(DeviceWrapper * device); + + Plasma::DataEngine *m_hotplugEngine; + Plasma::DataEngine *m_solidDeviceEngine; + + QHash m_deviceList; + QStringList m_udiOrderedList; + Plasma::DataEngineManager* m_engineManager; + Plasma::RunnerContext m_currentContext; +}; + +K_EXPORT_PLASMA_RUNNER(solid, SolidRunner) + +#endif // SOLIDRUNNER_H diff --git a/plasma/generic/runners/webshortcuts/CMakeLists.txt b/plasma/generic/runners/webshortcuts/CMakeLists.txt new file mode 100644 index 00000000..a6da726d --- /dev/null +++ b/plasma/generic/runners/webshortcuts/CMakeLists.txt @@ -0,0 +1,11 @@ +set(krunner_webshortcuts_SRCS + webshortcutrunner.cpp +) + +kde4_add_plugin(krunner_webshortcuts ${krunner_webshortcuts_SRCS}) +target_link_libraries(krunner_webshortcuts ${KDE4_KIO_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS krunner_webshortcuts DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-webshortcuts.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/runners/webshortcuts/Messages.sh b/plasma/generic/runners/webshortcuts/Messages.sh new file mode 100755 index 00000000..52acdd12 --- /dev/null +++ b/plasma/generic/runners/webshortcuts/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_webshortcuts.pot diff --git a/plasma/generic/runners/webshortcuts/plasma-runner-webshortcuts.desktop b/plasma/generic/runners/webshortcuts/plasma-runner-webshortcuts.desktop new file mode 100644 index 00000000..89db96cb --- /dev/null +++ b/plasma/generic/runners/webshortcuts/plasma-runner-webshortcuts.desktop @@ -0,0 +1,129 @@ +[Desktop Entry] +# ctxt: plasma runner +Name=Web Shortcuts +Name[ar]=اختصارات الوِب +Name[ast]=Accesos rápidos pa web +Name[bg]=Уеб отметки +Name[bn]=ওয়েব শর্টকাট +Name[bs]=veb prečice +Name[ca]=Dreceres web +Name[ca@valencia]=Dreceres web +Name[cs]=Webové zkratky +Name[csb]=Sécowé skrodzënë +Name[da]=Webgenveje +Name[de]=Web-Kürzel +Name[el]=Συντομεύσεις ιστού +Name[en_GB]=Web Shortcuts +Name[eo]=Web Shortcuts +Name[es]=Accesos rápidos para web +Name[et]=Veebi kiirkorraldused +Name[eu]=Web-eko lasterbideak +Name[fa]=میان‌برهای وب +Name[fi]=WWW-pikavalinnat +Name[fr]=Raccourcis Web +Name[fy]=Webskeakels +Name[ga]=Aicearraí Gréasáin +Name[gl]=Atallos web +Name[gu]=વેબ ટૂંકાણો +Name[he]=קיצורי דרך אינטרנטיים +Name[hi]=वेब शॉर्टकट +Name[hr]=Internetski prečaci +Name[hu]=Keresési azonosítók +Name[ia]=Vias breve de Web +Name[id]=Jalan Pintas Web +Name[is]=Vefskammstafanir +Name[it]=Scorciatoie del Web +Name[ja]=ウェブショートカット +Name[kk]=Веб қысқартулары +Name[km]=ផ្លូវកាត់​បណ្ដាញ​ +Name[kn]=ಜಾಲ ಶೀಘ್ರಮಾರ್ಗಗಳು (ಶಾರ್ಟ್ ಕಟ್) +Name[ko]=웹 바로 가기 +Name[lt]=Žiniatinklio trumpės +Name[lv]=Ātrās meklēšanas īsceļi +Name[mk]=Интернет-кратенки +Name[ml]=വെബിലെ കുറക്കുവഴികള്‍ +Name[mr]=वेब शॉर्टकट +Name[nb]=Nettsnarveier +Name[nds]=Söökafkörten +Name[nl]=Websnelkoppelingen +Name[nn]=Vevsnarvegar +Name[pa]=ਵੈਬ ਸ਼ਾਰਟਕੱਟ +Name[pl]=Skróty sieciowe +Name[pt]=Atalhos Web +Name[pt_BR]=Atalhos da Web +Name[ro]=Acceleratori web +Name[ru]=Сокращения +Name[si]=ජාල කෙටිමං +Name[sk]=Webové skratky +Name[sl]=Spletne bližnjice +Name[sr]=веб пречице +Name[sr@ijekavian]=веб пречице +Name[sr@ijekavianlatin]=veb prečice +Name[sr@latin]=veb prečice +Name[sv]=Webbgenvägar +Name[tg]=Тугмаҳои тез +Name[th]=ทางลัดถึงเว็บ +Name[tr]=Web Kısayolları +Name[ug]=تور تېزلەتمىسى +Name[uk]=Вебскорочення +Name[wa]=Rascourtis waibe +Name[x-test]=xxWeb Shortcutsxx +Name[zh_CN]=网页快捷方式 +Name[zh_TW]=網頁捷徑 +Comment=Allows user to use Konqueror's web shortcuts +Comment[bs]=Dozvoli koristenje Koquerorovih web prečica +Comment[ca]=Permet que l'usuari utilitzi les dreceres web del Konqueror +Comment[ca@valencia]=Permet que l'usuari utilitze les dreceres web del Konqueror +Comment[cs]=Umožňuje používat webové zkratky Konqueroru +Comment[da]=Lader brugeren anvende Konquerors webgenveje +Comment[de]=Ermöglicht die Verwendung von Web-Kürzeln in Konqueror +Comment[el]=Επιτρέπει τη χρήση συντομεύσεων ιστού του Konqueror +Comment[en_GB]=Allows user to use Konqueror's web shortcuts +Comment[es]=Permite al usuario usar accesos rápidos web de Konqueror +Comment[et]=Võimaldab kasutajal kasutada Konquerori veebikiirkorraldusi +Comment[eu]=Konqueror-en web-eko lasterbideak erabiltzeko aukera ematen dio erabiltzaileari +Comment[fi]=Mahdollistaa Konquerorin WWW-pikavalintojen käytön +Comment[fr]=Permet d'utiliser les raccourcis Web de Konqueror +Comment[ga]=Ceadaigh don úsáideoir aicearraí Gréasáin de chuid Konqueror a úsáid +Comment[gl]=Permítelle ao usuario empregar os atallos web de Konqueror +Comment[he]=מאפשר למשתמש להשתמש בקיצורי דרך אינטרנטיים של Konqueror +Comment[hu]=Lehetővé teszi a felhasználónak a Konqueror kereső azonosítóinak használatát +Comment[ia]=Il permitte al usator de usar vias breve de Web de Konqueror +Comment[it]=Permette all'utente di usare le scorciatoie del Web di Konqueror +Comment[kk]=Konqueror-дың Веб қысқармаларын пайдалануға мүмкіндік беру +Comment[km]=អនុញ្ញាត​ឲ្យ​អ្នកប្រើ​ ប្រើ​ផ្លូវកាត់​បណ្ដាញ​របស់ Konqueror +Comment[ko]=Konqueror 웹 바로 가기 사용 허용 +Comment[lt]=Leidžia naudotojui naudoti Konqueror žiniatinklio nuorodas +Comment[mr]=कॉन्कररचे वेब शार्टकट वापरण्यास वापरकर्त्यास परवानगी देतो +Comment[nb]=Lar brukeren benytte nettsnarveier i Konqueror +Comment[nds]=Lett den Bruker Konqueror sien Söökafkörten bruken +Comment[nl]=Maakt het mogelijk om webkoppelingen van Konqueror te gebruiken +Comment[pa]=ਯੂਜ਼ਰਾਂ ਨੂੰ ਕੋਨਕਿਉਰੋਰ ਦੇ ਵੈੱਬ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣੇ ਮਨਜ਼ੂਰ +Comment[pl]=Pozwala użytkownikowi na użycie skrótów sieciowych Konquerora +Comment[pt]=Permite ao utilizador usar os atalhos Web do Konqueror +Comment[pt_BR]=Permite ao usuário usar os atalhos da Web do Konqueror +Comment[ro]=Permite utilizatorului să folosească scurtăturile web ale Konqueror +Comment[ru]=Использование веб-сокращений Konqueror +Comment[sk]=Umožňuje používateľovi použiť webové skratky Konquerora +Comment[sl]=Omogoča uporabo spletnih bližnjic iz Konquerorja +Comment[sr]=Употребите К‑освајачеве веб пречице +Comment[sr@ijekavian]=Употријебите К‑освајачеве веб пречице +Comment[sr@ijekavianlatin]=Upotrijebite K‑osvajačeve veb prečice +Comment[sr@latin]=Upotrebite K‑osvajačeve veb prečice +Comment[sv]=Låter användaren utnyttja webbgenvägar i Konqueror +Comment[tr]=Kullanıcının Konqueror Web kısayollarını kullanabilmesini sağlar +Comment[uk]=Надає змогу використовувати вебскорочення Konqueror +Comment[x-test]=xxAllows user to use Konqueror's web shortcutsxx +Comment[zh_CN]=允许用户使用 Konqueror 的网页快捷键 +Comment[zh_TW]=允許使用者使用 Konqueror 的網頁捷徑 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=internet-web-browser +X-KDE-Library=krunner_webshortcuts +X-KDE-PluginInfo-Author=Teemu Rytilahti +X-KDE-PluginInfo-Email=tpr@iki.fi +X-KDE-PluginInfo-Name=webshortcuts +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-Plasma-AdvertiseSingleRunnerQueryMode=true +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/generic/runners/webshortcuts/webshortcutrunner.cpp b/plasma/generic/runners/webshortcuts/webshortcutrunner.cpp new file mode 100644 index 00000000..2777c705 --- /dev/null +++ b/plasma/generic/runners/webshortcuts/webshortcutrunner.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007 Teemu Rytilahti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "webshortcutrunner.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +WebshortcutRunner::WebshortcutRunner(QObject *parent, const QVariantList& args) + : Plasma::AbstractRunner(parent, args), + m_match(this), m_filterBeforeRun(false) +{ + Q_UNUSED(args); + setObjectName( QLatin1String("Web Shortcut" )); + setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | Plasma::RunnerContext::Executable); + + m_icon = KIcon("internet-web-browser"); + + m_match.setType(Plasma::QueryMatch::ExactMatch); + m_match.setRelevance(0.9); + + // Listen for KUriFilter plugin config changes and update state... + QDBusConnection sessionDbus = QDBusConnection::sessionBus(); + sessionDbus.connect(QString(), "/", "org.kde.KUriFilterPlugin", + "configure", this, SLOT(readFiltersConfig())); + + connect(this, SIGNAL(teardown()), this, SLOT(resetState())); + readFiltersConfig(); +} + +WebshortcutRunner::~WebshortcutRunner() +{ +} + +void WebshortcutRunner::readFiltersConfig() +{ + // Make sure that the searchEngines cache, etc. is refreshed when the config file is changed. + loadSyntaxes(); +} + +void WebshortcutRunner::loadSyntaxes() +{ + KUriFilterData filterData (QLatin1String(":q")); + filterData.setSearchFilteringOptions(KUriFilterData::RetrieveAvailableSearchProvidersOnly); + if (KUriFilter::self()->filterSearchUri(filterData, KUriFilter::NormalTextFilter)) { + m_delimiter = filterData.searchTermSeparator(); + } + + //kDebug() << "keyword delimiter:" << m_delimiter; + //kDebug() << "search providers:" << filterData.preferredSearchProviders(); + + QList syns; + Q_FOREACH (const QString &provider, filterData.preferredSearchProviders()) { + //kDebug() << "checking out" << provider; + Plasma::RunnerSyntax s(filterData.queryForPreferredSearchProvider(provider), /*":q:",*/ + i18n("Opens \"%1\" in a web browser with the query :q:.", provider)); + syns << s; + } + + setSyntaxes(syns); +} + +void WebshortcutRunner::resetState() +{ + kDebug(); + m_lastFailedKey.clear(); + m_lastProvider.clear(); + m_lastKey.clear(); +} + +void WebshortcutRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + + if (term.length() < 3 || !term.contains(m_delimiter)) + return; + + // kDebug() << "checking term" << term; + + const int delimIndex = term.indexOf(m_delimiter); + if (delimIndex == term.length() - 1) + return; + + const QString key = term.left(delimIndex); + + if (key == m_lastFailedKey) { + return; // we already know it's going to suck ;) + } + + if (!context.isValid()) { + kDebug() << "invalid context"; + return; + } + + // Do a fake user feedback text update if the keyword has not changed. + // There is no point filtering the request on every key stroke. + // filtering + if (m_lastKey == key) { + m_filterBeforeRun = true; + m_match.setText(i18n("Search %1 for %2", m_lastProvider, term.mid(delimIndex + 1))); + context.addMatch(term, m_match); + return; + } + + KUriFilterData filterData(term); + if (!KUriFilter::self()->filterSearchUri(filterData, KUriFilter::WebShortcutFilter)) { + m_lastFailedKey = key; + return; + } + + m_lastFailedKey.clear(); + m_lastKey = key; + m_lastProvider = filterData.searchProvider(); + + m_match.setData(filterData.uri().url()); + m_match.setId("WebShortcut:" + key); + + m_match.setIcon(KIcon(filterData.iconName())); + m_match.setText(i18n("Search %1 for %2", m_lastProvider, filterData.searchTerm())); + context.addMatch(term, m_match); +} + +void WebshortcutRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + QString location; + + //kDebug() << "filter before run?" << m_filterBeforeRun; + if (m_filterBeforeRun) { + m_filterBeforeRun = false; + //kDebug() << "look up webshortcut:" << context.query(); + KUriFilterData filterData (context.query()); + if (KUriFilter::self()->filterSearchUri(filterData, KUriFilter::WebShortcutFilter)) + location = filterData.uri().url(); + } else { + location = match.data().toString(); + } + + //kDebug() << location; + if (!location.isEmpty()) { + KToolInvocation::invokeBrowser(location); + } +} + +#include "webshortcutrunner.moc" diff --git a/plasma/generic/runners/webshortcuts/webshortcutrunner.h b/plasma/generic/runners/webshortcuts/webshortcutrunner.h new file mode 100644 index 00000000..73339c47 --- /dev/null +++ b/plasma/generic/runners/webshortcuts/webshortcutrunner.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Teemu Rytilahti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef WEBSHORTCUTRUNNER_H +#define WEBSHORTCUTRUNNER_H + +#include + +#include + +class WebshortcutRunner : public Plasma::AbstractRunner { + Q_OBJECT + + public: + WebshortcutRunner( QObject *parent, const QVariantList& args ); + ~WebshortcutRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match); + + private: + void loadSyntaxes(); + + private Q_SLOTS: + void readFiltersConfig(); + void resetState(); + + private: + KIcon m_icon; + Plasma::QueryMatch m_match; + bool m_filterBeforeRun; + + QChar m_delimiter; + QString m_lastFailedKey; + QString m_lastKey; + QString m_lastProvider; +}; + +K_EXPORT_PLASMA_RUNNER(webshortcuts, WebshortcutRunner) + +#endif diff --git a/plasma/generic/runners/windowedwidgets/CMakeLists.txt b/plasma/generic/runners/windowedwidgets/CMakeLists.txt new file mode 100644 index 00000000..f17376c7 --- /dev/null +++ b/plasma/generic/runners/windowedwidgets/CMakeLists.txt @@ -0,0 +1,13 @@ +project(windowedwidgetsrunner) + +include_directories( ${QT_INCLUDES} ${KDE4_INCLUDES} ) + +set(krunner_windowedwidgets_SRCS + windowedwidgetsrunner.cpp +) + +kde4_add_plugin(krunner_windowedwidgets ${krunner_windowedwidgets_SRCS}) +target_link_libraries(krunner_windowedwidgets ${KDE4_PLASMA_LIBS}) + +install(TARGETS krunner_windowedwidgets DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-runner-windowedwidgets.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/runners/windowedwidgets/Messages.sh b/plasma/generic/runners/windowedwidgets/Messages.sh new file mode 100644 index 00000000..2ecdc58b --- /dev/null +++ b/plasma/generic/runners/windowedwidgets/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_windowedwidgets.pot diff --git a/plasma/generic/runners/windowedwidgets/plasma-runner-windowedwidgets.desktop b/plasma/generic/runners/windowedwidgets/plasma-runner-windowedwidgets.desktop new file mode 100644 index 00000000..167adcb3 --- /dev/null +++ b/plasma/generic/runners/windowedwidgets/plasma-runner-windowedwidgets.desktop @@ -0,0 +1,136 @@ +[Desktop Entry] +Name=Windowed widgets +Name[ar]=ودجات مُنوفذة +Name[ast]=Componentes en ventana +Name[bg]=Джаджи като прозорци +Name[bs]=Grafičke kontrole s prozorom +Name[ca]=Estris en finestres +Name[ca@valencia]=Estris en finestres +Name[cs]=Widgety v okně +Name[da]=Widgets som vinduer +Name[de]=Eigenständige Miniprogramme +Name[el]=Συστατικά σε παράθυρο +Name[en_GB]=Windowed widgets +Name[es]=Componentes en ventana +Name[et]=Akendesse paigutatavad vidinad +Name[eu]=Trepeta leihodunak +Name[fi]=Ikkunoidut sovelmat +Name[fr]=Composants graphiques fenêtrés +Name[ga]=Giuirléidí i bhfuinneoga +Name[gl]=Widgets en xanelas +Name[he]=ווידג׳טים בחלון +Name[hi]=विंडोज़ विडजेट +Name[hr]=Widgeti u prozorima +Name[hu]=Önálló widgetek +Name[ia]=Widgets (elemento graphic) in le fenestra +Name[id]=Widget jendela +Name[is]=Græjur í gluggum +Name[it]=Oggetti fenestrabili +Name[ja]=ウィンドウ化されたウィジェット +Name[kk]=Терезелерлі виджеттер +Name[km]=ធាតុក្រាហ្វិក​​វីនដូ +Name[kn]=ವಿಂಡೋವ್ಡ್ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟಗಳು (ವಿಡ್ಗೆಟ್) +Name[ko]=창에 들어있는 위젯 +Name[lt]=Langų valdikliai +Name[lv]=Logoti sīkrīki +Name[mr]=चौकटीतील विजेट्स +Name[nb]=Skjermelementer i vinduer +Name[nds]=Lüttprogrammen as Enkelfinstern +Name[nl]=Widgets weergegeven in vensters +Name[pa]=ਵਿੰਡੋ ਵਿਦਜੈੱਟ +Name[pl]=Elementy interfejsu w oknach +Name[pt]=Elementos em janelas +Name[pt_BR]=Widgets em janelas +Name[ro]=Controale în fereastră +Name[ru]=Мобильные виджеты +Name[si]=කවුළුකල විජට්ටු +Name[sk]=Widgety v oknách +Name[sl]=Gradniki v oknih +Name[sr]=виџети с прозором +Name[sr@ijekavian]=виџети с прозором +Name[sr@ijekavianlatin]=vidžeti s prozorom +Name[sr@latin]=vidžeti s prozorom +Name[sv]=Fönsterbaserade grafiska komponenter +Name[th]=วิดเจ็ตที่เป็นหน้าต่าง +Name[tr]=Pencerelendirilmiş gereçler +Name[ug]=كۆزنەكلىك ۋىجېتلار +Name[uk]=Віджети-вікна +Name[wa]=Ahesses metous dins des fniesses +Name[x-test]=xxWindowed widgetsxx +Name[zh_CN]=窗口化部件 +Name[zh_TW]=視窗元件 + + +Comment=Find Plasma widgets that can be run as standalone windows +Comment[ar]=ابحث عن ودجات بلازما التي يمكن تشغيلها كنوافذ مستقلة +Comment[ast]=Gueta componentes Plasma que puen executase como ventanes independientes +Comment[bg]=Търсене на джаджи, които могат да се използват като самостоятелни прозорци +Comment[bs]=Nađite plazma grafičke kontrole koje mogu da rade kao samostalni prozori +Comment[ca]=Cerca estris del Plasma que es poden executar en finestres autònomes +Comment[ca@valencia]=Cerca estris del Plasma que es poden executar en finestres autònomes +Comment[cs]=Najít Plasma widgety, které mohou být spuštěny ve vlastních oknech +Comment[da]=Find Plasma-widgets der kan køres som selvstændige vinduer +Comment[de]=Findet Plasma-Miniprogramme, die als eigenständige Anwendungen gestartet werden können +Comment[el]=Βρείτε γραφικά συστατικά Plasma που να μπορούν να εκτελεστούν ως ανεξάρτητα παράθυρα +Comment[en_GB]=Find Plasma widgets that can be run as standalone windows +Comment[es]=Busca componentes Plasma que se pueden ejecutar como ventanas independientes +Comment[et]=Plasma vidinate otsimine, mida saab panna tööle autonoomsetes akendes +Comment[eu]=Bilatu leiho autonomo gisa exekuta daitezkeen Plasmaren trepetak +Comment[fi]=Etsi Plasma-sovelmia, joita voidaan ajaa omina ikkunoinaan +Comment[fr]=Trouve des composants graphiques de Plasma pouvant êtres démarrés comme des fenêtres individuelles +Comment[ga]=Aimsigh giuirléidí Plasma is féidir rith i bhfuinneog shaorsheasaimh +Comment[gl]=Busca os widgets de Plasma que se poden executar en xanelas independentes +Comment[he]=משמש למציאת ווידג׳טים של Plasma אשר ניתן להריץ אותם בחלון עצמאי +Comment[hr]=Pronađi Plasma widgete koji se mogu pokrenuti kao zasebni prozori +Comment[hu]=Megkeresi az önálló alkalmazásként futtatható Plasma-elemeket +Comment[ia]=Trova widgets (elementos graphic) de plasma que on pote executar como fenestras sole +Comment[id]=Cari widget Plasma yang dapat dijalankan sebagai jendela mandiri +Comment[is]=Finnur Plasmagræjur sem hægt er að keyra sem sjálfstæð forrit +Comment[it]=Trova i plasmoidi che possono essere eseguiti come finestre a sé +Comment[ja]=スタンドアローンのウィンドウとして起動できる Plasma ウィジェットを検索します +Comment[kk]=Бөлек терезелі Plasma виджеттерін табу +Comment[km]=រក​ធាតុក្រាហ្វិក​ប្លាស្មា​ ដែល​អាច​ត្រូវ​បាន​​រត់​ជា​វីនដូ​តែ​ឯង +Comment[ko]=창으로 실행될 수 있는 위젯을 찾습니다 +Comment[lt]=Rasti plasmos elementus, kurie gali veikti kaip atskiri langai +Comment[lv]=Meklē Plasma sīkrīkus, ko var darbināt kā patstāvīgus logus +Comment[mr]=चौकटीत चालण्याजोगी प्लाज्मा विजेट्स शोधा +Comment[nb]=Finn Plasmaelementer som kan kjøres som frittstående programmer +Comment[nds]=Plasma-Lüttprogrammen söken, de ok as alleenstahn Finstern löppt. +Comment[nl]=Zoek Plasma widgets die als zelfstandige vensters kunnen draaien +Comment[pa]=ਪਲਾਜ਼ਾਮ ਵਿਦਜੈੱਟ ਲੱਭੋ, ਜੋ ਕਿ ਇੱਕਲੇ ਵਿੰਡੋਜ਼ ਵਜੋਂ ਚੱਲ ਸਕਦੇ ਹਨ +Comment[pl]=Znajdź elementy interfejsu, które mogą działać jako oddzielne okna +Comment[pt]=Procurar elementos do Plasma que possam ser executados como janelas autónomas +Comment[pt_BR]=Localiza widgets do Plasma que possam ser executados como janelas independentes +Comment[ro]=Găsește controale Plasma ce pot rula în ferestre independente +Comment[ru]=Поиск виджетов, способных работать как самостоятельные приложения +Comment[si]=තනි කවුළු ලෙස ධාවනය කල හැකි ප්ලැස්මා විජට්ටු සොයන්න +Comment[sk]=Nájde Plasma widgety, ktoré môžu bežať ako samostatné okná +Comment[sl]=Najdite gradnike za Plasmo, ki jih je mogoče zagnati v samostojnem oknu +Comment[sr]=Нађите плазма виџете који могу да раде као самостални прозори +Comment[sr@ijekavian]=Нађите плазма виџете који могу да раде као самостални прозори +Comment[sr@ijekavianlatin]=Nađite plasma vidžete koji mogu da rade kao samostalni prozori +Comment[sr@latin]=Nađite plasma vidžete koji mogu da rade kao samostalni prozori +Comment[sv]=Hitta grafiska Plasma-komponenter som kan köras som fristående fönster +Comment[th]=ค้นหาวิดเจ็ตพลาสมาที่สามารถทำงานได้บนหน้าต่างอิสระ +Comment[tr]=Tek başına pencere olarak da çalışabilen Plasma araçlarını bul +Comment[ug]=مۇستەقىل كۆزنەك شەكلىدە ئىجرا قىلغىلى بولىدىغان پلازما widget نى ئىزدەيدۇ +Comment[uk]=Пошук віджетів Плазми, які можна запускати у окремих вікнах +Comment[vi]=Tìm các widget có thể được chạy trong cửa sổ riêng +Comment[wa]=Trover des ahesses Plasma k' on sait enonder dins des fniesses mierseules +Comment[x-test]=xxFind Plasma widgets that can be run as standalone windowsxx +Comment[zh_CN]=查找可以独立窗口形式运行的 Plasma 部件 +Comment[zh_TW]=尋找可以以獨立視窗執行的 Plasma 元件 + + +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=plasma +X-KDE-Library=krunner_windowedwidgets +X-Plasma-RunnerPhase=first +X-KDE-PluginInfo-Author=Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=org.kde.windowedwidgets +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.cpp b/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.cpp new file mode 100644 index 00000000..17e9710c --- /dev/null +++ b/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * Copyright (C) 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "windowedwidgetsrunner.h" + +#include + +#include + +#include +#include +#include + +#include + +WindowedWidgetsRunner::WindowedWidgetsRunner(QObject *parent, const QVariantList &args) + : Plasma::AbstractRunner(parent, args) +{ + Q_UNUSED(args) + + setObjectName( QLatin1String("WindowedWidgets" )); + setPriority(AbstractRunner::HighestPriority); + + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds Plasma widgets whose name or description match :q:"))); + setDefaultSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "mobile applications"), i18n("list all Plasma widgets that can run as standalone applications"))); +} + +WindowedWidgetsRunner::~WindowedWidgetsRunner() +{ +} + +void WindowedWidgetsRunner::match(Plasma::RunnerContext &context) +{ + const QString term = context.query(); + + if (!context.singleRunnerQueryMode() && term.length() < 3) { + return; + } + + + QList matches; + + foreach (const KPluginInfo &info, Plasma::Applet::listAppletInfo()) { + KService::Ptr service = info.service(); + + if ((service->name().contains(term, Qt::CaseInsensitive) || + service->genericName().contains(term, Qt::CaseInsensitive) || + service->comment().contains(term, Qt::CaseInsensitive)) || + service->categories().contains(term, Qt::CaseInsensitive) || + term.startsWith(i18nc("Note this is a KRunner keyword", "mobile applications"))) { + + Plasma::QueryMatch match(this); + setupMatch(service, match); + if (service->name().compare(term, Qt::CaseInsensitive) == 0) { + match.setType(Plasma::QueryMatch::ExactMatch); + match.setRelevance(1); + } else { + match.setType(Plasma::QueryMatch::PossibleMatch); + match.setRelevance(0.7); + } + matches << match; + + kDebug() << service; + } + } + + if (!context.isValid()) { + return; + } + + context.addMatches(term, matches); +} + +void WindowedWidgetsRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) +{ + Q_UNUSED(context); + KService::Ptr service = KService::serviceByStorageId(match.data().toString()); + if (service) { + QProcess::startDetached("plasma-windowed", QStringList() << service->property("X-KDE-PluginInfo-Name", QVariant::String).toString()); + } +} + +void WindowedWidgetsRunner::setupMatch(const KService::Ptr &service, Plasma::QueryMatch &match) +{ + const QString name = service->name(); + + match.setText(name); + match.setData(service->storageId()); + + if (!service->genericName().isEmpty() && service->genericName() != name) { + match.setSubtext(service->genericName()); + } else if (!service->comment().isEmpty()) { + match.setSubtext(service->comment()); + } + + if (!service->icon().isEmpty()) { + match.setIcon(KIcon(service->icon())); + } +} + +QMimeData * WindowedWidgetsRunner::mimeDataForMatch(const Plasma::QueryMatch *match) +{ + KService::Ptr service = KService::serviceByStorageId(match->data().toString()); + if (service) { + + QMimeData *data = new QMimeData(); + data->setData("text/x-plasmoidservicename", + service->property("X-KDE-PluginInfo-Name", QVariant::String).toString().toUtf8()); + return data; + + } + + return 0; +} + + +#include "windowedwidgetsrunner.moc" + diff --git a/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.h b/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.h new file mode 100644 index 00000000..7509e166 --- /dev/null +++ b/plasma/generic/runners/windowedwidgets/windowedwidgetsrunner.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2006 Aaron Seigo + * Copyright (C) 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef WINDOWEDWIDGETSRUNNER_H +#define WINDOWEDWIDGETSRUNNER_H + + +#include + +#include + + +/** + * This class looks for matches in the set of .desktop files installed by + * applications. This way the user can type exactly what they see in the + * appications menu and have it start the appropriate app. Essentially anything + * that KService knows about, this runner can launch + */ + +class WindowedWidgetsRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + +public: + WindowedWidgetsRunner(QObject *parent, const QVariantList &args); + ~WindowedWidgetsRunner(); + + void match(Plasma::RunnerContext &context); + void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action); + +protected slots: + QMimeData * mimeDataForMatch(const Plasma::QueryMatch *match); + + +protected: + void setupMatch(const KService::Ptr &service, Plasma::QueryMatch &action); +}; + +K_EXPORT_PLASMA_RUNNER(windowedwidgets, WindowedWidgetsRunner) + +#endif + diff --git a/plasma/generic/runners/windows/CMakeLists.txt b/plasma/generic/runners/windows/CMakeLists.txt new file mode 100644 index 00000000..8bf9258e --- /dev/null +++ b/plasma/generic/runners/windows/CMakeLists.txt @@ -0,0 +1,10 @@ +set(krunner_windows_SRCS + windowsrunner.cpp +) + +kde4_add_plugin(krunner_windows ${krunner_windows_SRCS}) +target_link_libraries(krunner_windows ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS krunner_windows DESTINATION ${PLUGIN_INSTALL_DIR} ) + +install(FILES plasma-runner-windows.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/runners/windows/Messages.sh b/plasma/generic/runners/windows/Messages.sh new file mode 100755 index 00000000..412322ba --- /dev/null +++ b/plasma/generic/runners/windows/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_runner_windows.pot diff --git a/plasma/generic/runners/windows/plasma-runner-windows.desktop b/plasma/generic/runners/windows/plasma-runner-windows.desktop new file mode 100644 index 00000000..9764d102 --- /dev/null +++ b/plasma/generic/runners/windows/plasma-runner-windows.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +# ctxt: plasma runner +Name=Windows +Name[ar]=النوافذ +Name[ast]=Ventanes +Name[bg]=Прозорци +Name[bn]=উইণ্ডো +Name[bs]=prozori +Name[ca]=Finestres +Name[ca@valencia]=Finestres +Name[cs]=Okna +Name[csb]=Òkna +Name[da]=Vinduer +Name[de]=Fenster +Name[el]=Παράθυρα +Name[en_GB]=Windows +Name[eo]=Fenestroj +Name[es]=Ventanas +Name[et]=Aknad +Name[eu]=Leihoak +Name[fa]=پنجره‌ها +Name[fi]=Ikkunat +Name[fr]=Fenêtres +Name[fy]=Finsters +Name[ga]=Fuinneoga +Name[gl]=Xanelas +Name[gu]=વિન્ડોઝ +Name[he]=חלונות +Name[hi]=विंडोज़ +Name[hr]=Prozori +Name[hu]=Ablakok +Name[ia]=Fenestras +Name[id]=Jendela +Name[is]=Gluggar +Name[it]=Finestre +Name[ja]=ウィンドウ +Name[kk]=Терезелер +Name[km]=បង្អួច +Name[kn]=ಕಿಟಕಿಗಳು +Name[ko]=창 +Name[lt]=Langai +Name[lv]=Logi +Name[mk]=Прозорци +Name[ml]=ജാലകങ്ങള്‍ +Name[mr]=चौकटी +Name[nb]=Vinduer +Name[nds]=Finstern +Name[nl]=Vensters +Name[nn]=Vindauge +Name[pa]=ਵਿੰਡੋਜ਼ +Name[pl]=Okna +Name[pt]=Janelas +Name[pt_BR]=Janelas +Name[ro]=Ferestre +Name[ru]=Окна +Name[si]=කවුළු +Name[sk]=Okná +Name[sl]=Okna +Name[sr]=прозори +Name[sr@ijekavian]=прозори +Name[sr@ijekavianlatin]=prozori +Name[sr@latin]=prozori +Name[sv]=Fönster +Name[tg]=Windows +Name[th]=หน้าต่างต่าง ๆ +Name[tr]=Pencereler +Name[ug]=كۆزنەكلەر +Name[uk]=Вікна +Name[wa]=Finiesses +Name[x-test]=xxWindowsxx +Name[zh_CN]=窗口 +Name[zh_TW]=視窗 +Comment=List windows and desktops and switch them +Comment[ar]=اسرد النوافذ وسطوح المكتب وبدّلها +Comment[ast]=Llista ventanes y escritorios y camuda ente ellos +Comment[bg]=Показване и превключване на прозорци и работни плотове +Comment[bs]=Nabrajanje i prebacivanje između prozora i površî +Comment[ca]=Llista finestres i escriptoris i canvia entre ells +Comment[ca@valencia]=Llista finestres i escriptoris i canvia entre ells +Comment[cs]=Seznam oken a ploch k přepínání +Comment[da]=Oplist vinduer og skriveborde og skift mellem dem +Comment[de]=Listet Fenster und Arbeitsflächen auf und wechselt zwischen ihnen. +Comment[el]=Εμφάνιση λίστας παραθύρων και επιφανειών εργασίας για εναλλαγή +Comment[en_GB]=List windows and desktops and switch them +Comment[eo]=Listi fenestrojn kaj labortablojn kaj ŝanĝi ilin +Comment[es]=Lista ventanas y escritorios y cambia entre ellos +Comment[et]=Akende ja töölauade näitamine võimalusega neile lülituda +Comment[eu]=Zerrendatu leihoak eta mahaigainak, eta batetik bestera aldatu +Comment[fi]=Luettele ikkunat ja työpöydät ja vaihda niitä +Comment[fr]=Liste les fenêtres / bureaux et passe de l'un à l'autre +Comment[fy]=Sommet finsters en buroblêden en wikselt har +Comment[ga]=Taispeáin fuinneoga agus deasca agus athraigh eatarthu +Comment[gl]=Lista as xanelas e escritorio e salta entre eles +Comment[he]=משמש להצגת חלונות ושולחנות עבודה ולהחלפה ביניהם +Comment[hr]=Popis prozora i radnih površina za laku promjenu među njima +Comment[hu]=Kilistázza az ablakokat és asztalokat, és vált rájuk +Comment[ia]=Lista fenestras e scriptorios e commuta los +Comment[id]=Urutkan jendela dan desktop lalu kemudian tukar mereka +Comment[is]=Telur upp glugga og skjáborð og skiptir á milli þeirra +Comment[it]=Elenca e scegli finestre e desktop +Comment[ja]=ウィンドウとデスクトップの一覧表示と切り替えを行います +Comment[kk]=Бар терезе мен үстелдерді ұсынып оларға ауысу +Comment[km]=រាយ​​បង្អួច និង​ផ្ទៃតុ​ ហើយ​ប្ដូរ​ពួកវា +Comment[kn]=ವಿಂಡೊ ಹಾಗು ಗಣಕತೆರೆಗಳನ್ನು ಪಟ್ಟಿಮಾಡು ಹಾಗು ಅವುಗಳನ್ನು ಬದಲಾಯಿಸು +Comment[ko]=창 및 데스크톱 목록을 보여 주고 전환합니다 +Comment[lt]=Išvardija langus ir darbastalius su galimybe į juos pereiti +Comment[lv]=Parāda logus un darbvirsmas un pārslēdz tos +Comment[mk]=Приказ на прозорци и раб. површини и преминување меѓу нив +Comment[ml]=ജാലകങ്ങളും പണിയിടങ്ങളും പട്ടികയായി കണ്ടു് പരസ്പരം മാറുക +Comment[mr]=वेगळ्या चौकट व डेस्कटॉप वर जाण्यासाठी यादी दर्शवा व बदला +Comment[nb]=List vinduer og skrivebord og bytt mellom dem +Comment[nds]=Finstern un Schriefdischen oplisten un wesseln +Comment[nl]=Toon vensters en bureaubladen en schakel ze om +Comment[nn]=Vis vindauge og skrivebord, og byt mellom dei +Comment[pa]=ਵਿੰਡੋਜ਼ ਅਤੇ ਡੈਸਕਟਾਪ ਦੀ ਲਿਸਟ ਅਤੇ ਉਹਨਾਂ ਵਿੱਚ ਬਦਲੋ +Comment[pl]=Lista okien i pulpitów oraz przełączenia ich +Comment[pt]=Listar as janelas e ecrãs e mudar entre eles +Comment[pt_BR]=Lista as janelas e áreas de trabalho e alterna entre elas +Comment[ro]=Enumeră ferestre și birouri și le comută +Comment[ru]=Список окон и рабочих столов с возможностью переключения между ними +Comment[si]=කවුළු හා වැඩතල ලැයිස්තුගත කර ඒවා මාරුකරන්න +Comment[sk]=Zoznam okien a plôch a ich prepínanie +Comment[sl]=Seznam oken in namizij ter preklapljanje med njimi +Comment[sr]=Набрајање и пребацивање између прозора и површи̂ +Comment[sr@ijekavian]=Набрајање и пребацивање између прозора и површи̂ +Comment[sr@ijekavianlatin]=Nabrajanje i prebacivanje između prozora i površî +Comment[sr@latin]=Nabrajanje i prebacivanje između prozora i površî +Comment[sv]=Lista fönster och skrivbord, och byt mellan dem +Comment[tg]=Намоиши рӯйхати тирезаҳо, мизҳои корӣ ва панелҳо +Comment[th]=รายการหน้าต่างและพื้นที่ทำงานต่าง ๆ ที่สามารถสลับไปใช้งานได้ +Comment[tr]=Pencereleri ve masaüstlerini listele ve seç +Comment[ug]=ھەممە كۆزنەكلەر ۋە ئۈستەلئۈستى تىزىمىنى كۆرسىتىپ، ئۇلارنى ئالماشتۇرىدۇ +Comment[uk]=Показує список вікон і стільниць і перемикає їх +Comment[vi]=Liệt kê các cửa sổ, màn hình làm việc và chuyển đổi chúng +Comment[wa]=Fé l' djivêye des fniesses eyet des scribannes eyet passer d' n' onk a l' ôte +Comment[x-test]=xxList windows and desktops and switch themxx +Comment[zh_CN]=列出所有窗口和桌面,并可供切换 +Comment[zh_TW]=列出視窗與桌面並切換 +X-KDE-ServiceTypes=Plasma/Runner +Type=Service +Icon=preferences-system-windows +X-KDE-Library=krunner_windows +X-KDE-PluginInfo-Author=Martin Gräßlin +X-KDE-PluginInfo-Email=kde@martin-graesslin.com +X-KDE-PluginInfo-Name=windows +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-AdvertiseSingleRunnerQueryMode=true diff --git a/plasma/generic/runners/windows/windowsrunner.cpp b/plasma/generic/runners/windows/windowsrunner.cpp new file mode 100644 index 00000000..f9712fae --- /dev/null +++ b/plasma/generic/runners/windows/windowsrunner.cpp @@ -0,0 +1,467 @@ +/*************************************************************************** + * Copyright 2009 by Martin Gräßlin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ +#include "windowsrunner.h" + +#include + +#include +#include +#include + +#ifdef Q_WS_X11 +#include +#include +#endif + +WindowsRunner::WindowsRunner(QObject* parent, const QVariantList& args) + : AbstractRunner(parent, args), + m_inSession(false), + m_ready(false) +{ + Q_UNUSED(args) + setObjectName( QLatin1String("Windows" )); + + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds windows whose name, window class or window role match :q:. " + "It is possible to interact with the windows by using one of the following keywords: " + "activate, close, min(imize), max(imize), fullscreen, shade, keep above and keep below."))); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds windows which are on desktop named :q: " + "It is possible to interact with the windows by using one of the following keywords: " + "activate, close, min(imize), max(imize), fullscreen, shade, keep above and keep below."))); + addSyntax(Plasma::RunnerSyntax(":q:", i18n("Switch to desktop named :q:"))); + setDefaultSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "window"), + i18n("Lists all windows and allows to activate them. " + "With name=, class=, role= and desktop= the list can be reduced to " + "windows matching these restrictions. " + "It is possible to interact with the windows by using one of the following keywords: " + "activate, close, min(imize), max(imize), fullscreen, shade, keep above and keep below."))); + addSyntax(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "desktop"), + i18n("Lists all other desktops and allows to switch to them."))); + + connect(this, SIGNAL(prepare()), this, SLOT(prepareForMatchSession())); + connect(this, SIGNAL(teardown()), this, SLOT(matchSessionComplete())); +} + +WindowsRunner::~WindowsRunner() +{ +} + +void WindowsRunner::gatherInfo() +{ + if (!m_inSession) { + return; + } + + foreach (const WId w, KWindowSystem::windows()) { + KWindowInfo info = KWindowSystem::windowInfo(w, NET::WMWindowType | NET::WMDesktop | + NET::WMState | NET::XAWMState | + NET::WMName, + NET::WM2WindowClass | NET::WM2WindowRole | NET::WM2AllowedActions); + if (info.valid()) { + // ignore NET::Tool and other special window types + NET::WindowType wType = info.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask | + NET::ToolbarMask | NET::MenuMask | NET::DialogMask | + NET::OverrideMask | NET::TopMenuMask | + NET::UtilityMask | NET::SplashMask); + + if (wType != NET::Normal && wType != NET::Override && wType != NET::Unknown && + wType != NET::Dialog && wType != NET::Utility) { + continue; + } + m_windows.insert(w, info); + m_icons.insert(w, QIcon(KWindowSystem::icon(w))); + } + } + + for (int i=1; i<=KWindowSystem::numberOfDesktops(); i++) { + m_desktopNames << KWindowSystem::desktopName(i); + } + + m_ready = true; +} + +void WindowsRunner::prepareForMatchSession() +{ + m_inSession = true; + m_ready = false; + QTimer::singleShot(0, this, SLOT(gatherInfo())); +} + +void WindowsRunner::matchSessionComplete() +{ + m_inSession = false; + m_ready = false; + m_desktopNames.clear(); + m_icons.clear(); + m_windows.clear(); +} + +void WindowsRunner::match(Plasma::RunnerContext& context) +{ + if (!m_ready) { + return; + } + + QString term = context.query(); + + if (!context.singleRunnerQueryMode() && (term.length() < 3)) { + return; + } + QList matches; + + // check if the search term ends with an action keyword + WindowAction action = ActivateAction; + if (term.endsWith(i18nc("Note this is a KRunner keyword", "activate") , Qt::CaseInsensitive)) { + action = ActivateAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "activate")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "close") , Qt::CaseInsensitive)) { + action = CloseAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "close")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "min") , Qt::CaseInsensitive)) { + action = MinimizeAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "min")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "minimize") , Qt::CaseInsensitive)) { + action = MinimizeAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "minimize")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "max") , Qt::CaseInsensitive)) { + action = MaximizeAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "max")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "maximize") , Qt::CaseInsensitive)) { + action = MaximizeAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "maximize")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "fullscreen") , Qt::CaseInsensitive)) { + action = FullscreenAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "fullscreen")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "shade") , Qt::CaseInsensitive)) { + action = ShadeAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "shade")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "keep above") , Qt::CaseInsensitive)) { + action = KeepAboveAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "keep above")) - 1); + } else if (term.endsWith(i18nc("Note this is a KRunner keyword", "keep below") , Qt::CaseInsensitive)) { + action = KeepBelowAction; + term = term.left(term.lastIndexOf(i18nc("Note this is a KRunner keyword", "keep below")) - 1); + } + + // keyword match: when term starts with "window" we list all windows + // the list can be restricted to windows matching a given name, class, role or desktop + if (term.startsWith(i18nc("Note this is a KRunner keyword", "window") , Qt::CaseInsensitive)) { + const QStringList keywords = term.split(" "); + QString windowName; + QString windowClass; + QString windowRole; + int desktop = -1; + foreach (const QString& keyword, keywords) { + if (keyword.endsWith('=')) { + continue; + } + if (keyword.startsWith(i18nc("Note this is a KRunner keyword", "name") + "=" , Qt::CaseInsensitive)) { + windowName = keyword.split("=")[1]; + } else if (keyword.startsWith(i18nc("Note this is a KRunner keyword", "class") + "=" , Qt::CaseInsensitive)) { + windowClass = keyword.split("=")[1]; + } else if (keyword.startsWith(i18nc("Note this is a KRunner keyword", "role") + "=" , Qt::CaseInsensitive)) { + windowRole = keyword.split("=")[1]; + } else if (keyword.startsWith(i18nc("Note this is a KRunner keyword", "desktop") + "=" , Qt::CaseInsensitive)) { + bool ok; + desktop = keyword.split("=")[1].toInt(&ok); + if (!ok || desktop > KWindowSystem::numberOfDesktops()) { + desktop = -1; // sanity check + } + } else { + // not a keyword - use as name if name is unused, but another option is set + if (windowName.isEmpty() && !keyword.contains('=') && + (!windowRole.isEmpty() || !windowClass.isEmpty() || desktop != -1)) { + windowName = keyword; + } + } + } + QHashIterator it(m_windows); + while(it.hasNext()) { + it.next(); + WId w = it.key(); + KWindowInfo info = it.value(); + QString windowClassCompare = QString::fromUtf8(info.windowClassName()) + " " + + QString::fromUtf8(info.windowClassClass()); + // exclude not matching windows + if (!KWindowSystem::hasWId(w)) { + continue; + } + if (!windowName.isEmpty() && !info.name().contains(windowName, Qt::CaseInsensitive)) { + continue; + } + if (!windowClass.isEmpty() && !windowClassCompare.contains(windowClass, Qt::CaseInsensitive)) { + continue; + } + if (!windowRole.isEmpty() && !QString::fromUtf8(info.windowRole()).contains(windowRole, Qt::CaseInsensitive)) { + continue; + } + if (desktop != -1 && !info.isOnDesktop(desktop)) { + continue; + } + // check for windows when no keywords were used + // check the name, class and role for containing the query without the keyword + if (windowName.isEmpty() && windowClass.isEmpty() && windowRole.isEmpty() && desktop == -1) { + const QString& test = term.mid(keywords[0].length() + 1); + if (!info.name().contains(test, Qt::CaseInsensitive) && + !windowClassCompare.contains(test, Qt::CaseInsensitive) && + !QString::fromUtf8(info.windowRole()).contains(test, Qt::CaseInsensitive)) { + continue; + } + } + // blacklisted everything else: we have a match + if (actionSupported(info, action)){ + matches << windowMatch(info, action); + } + } + + if (!matches.isEmpty()) { + // the window keyword found matches - do not process other syntax possibilities + context.addMatches(context.query(), matches); + return; + } + } + + bool desktopAdded = false; + // check for desktop keyword + if (term.startsWith(i18nc("Note this is a KRunner keyword", "desktop") , Qt::CaseInsensitive)) { + const QStringList parts = term.split(" "); + if (parts.size() == 1) { + // only keyword - list all desktops + for (int i=1; i<=KWindowSystem::numberOfDesktops(); i++) { + if (i == KWindowSystem::currentDesktop()) { + continue; + } + matches << desktopMatch(i); + desktopAdded = true; + } + } else { + // keyword + desktop - restrict matches + bool isInt; + int desktop = term.mid(parts[0].length() + 1).toInt(&isInt); + if (isInt && desktop != KWindowSystem::currentDesktop()) { + matches << desktopMatch(desktop); + desktopAdded = true; + } + } + } + + // check for matches without keywords + QHashIterator it(m_windows); + while (it.hasNext()) { + it.next(); + WId w = it.key(); + if (!KWindowSystem::hasWId(w)) { + continue; + } + // check if window name, class or role contains the query + KWindowInfo info = it.value(); + QString className = QString::fromUtf8(info.windowClassName()); + if (info.name().startsWith(term, Qt::CaseInsensitive) || + className.startsWith(term, Qt::CaseInsensitive)) { + matches << windowMatch(info, action, 0.8, Plasma::QueryMatch::ExactMatch); + } else if ((info.name().contains(term, Qt::CaseInsensitive) || + className.contains(term, Qt::CaseInsensitive)) && + actionSupported(info, action)) { + matches << windowMatch(info, action, 0.7, Plasma::QueryMatch::PossibleMatch); + } + } + + // check for matching desktops by name + foreach (const QString& desktopName, m_desktopNames) { + int desktop = m_desktopNames.indexOf(desktopName) +1; + if (desktopName.contains(term, Qt::CaseInsensitive)) { + // desktop name matches - offer switch to + // only add desktops if it hasn't been added by the keyword which is quite likely + if (!desktopAdded && desktop != KWindowSystem::currentDesktop()) { + matches << desktopMatch(desktop, 0.8); + } + + // search for windows on desktop and list them with less relevance + QHashIterator it(m_windows); + while (it.hasNext()) { + it.next(); + KWindowInfo info = it.value(); + if (info.isOnDesktop(desktop) && actionSupported(info, action)) { + matches << windowMatch(info, action, 0.5, Plasma::QueryMatch::PossibleMatch); + } + } + } + } + + if (!matches.isEmpty()) { + context.addMatches(context.query(), matches); + } +} + +void WindowsRunner::run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match) +{ + Q_UNUSED(context) + // check if it's a desktop + if (match.id().startsWith("windows_desktop")) { + KWindowSystem::setCurrentDesktop(match.data().toInt()); + return; + } + + const QStringList parts = match.data().toString().split("_"); + WindowAction action = WindowAction(parts[0].toInt()); + WId w = WId(parts[1].toULong()); + KWindowInfo info = m_windows[w]; + switch (action) { + case ActivateAction: + KWindowSystem::forceActiveWindow(w); + break; + case CloseAction: + { + NETRootInfo ri(QX11Info::display(), NET::CloseWindow); + ri.closeWindowRequest(w); + break; + } + case MinimizeAction: + if (info.isMinimized()) { + KWindowSystem::unminimizeWindow(w); + } else { + KWindowSystem::minimizeWindow(w); + } + break; + case MaximizeAction: + if (info.hasState(NET::Max)) { + KWindowSystem::clearState(w, NET::Max); + } else { + KWindowSystem::setState(w, NET::Max); + } + break; + case FullscreenAction: + if (info.hasState(NET::FullScreen)) { + KWindowSystem::clearState(w, NET::FullScreen); + } else { + KWindowSystem::setState(w, NET::FullScreen); + } + break; + case ShadeAction: + if (info.hasState(NET::Shaded)) { + KWindowSystem::clearState(w, NET::Shaded); + } else { + KWindowSystem::setState(w, NET::Shaded); + } + break; + case KeepAboveAction: + if (info.hasState(NET::KeepAbove)) { + KWindowSystem::clearState(w, NET::KeepAbove); + } else { + KWindowSystem::setState(w, NET::KeepAbove); + } + break; + case KeepBelowAction: + if (info.hasState(NET::KeepBelow)) { + KWindowSystem::clearState(w, NET::KeepBelow); + } else { + KWindowSystem::setState(w, NET::KeepBelow); + } + break; + } +} + +Plasma::QueryMatch WindowsRunner::desktopMatch(int desktop, qreal relevance) +{ + Plasma::QueryMatch match(this); + match.setType(Plasma::QueryMatch::ExactMatch); + match.setData(desktop); + match.setId("desktop-" + QString::number(desktop)); + match.setIcon(KIcon("user-desktop")); + QString desktopName; + if (desktop <= m_desktopNames.size()) { + desktopName = m_desktopNames[desktop - 1]; + } else { + desktopName = KWindowSystem::desktopName(desktop); + } + match.setText(desktopName); + match.setSubtext(i18n("Switch to desktop %1", desktop)); + match.setRelevance(relevance); + return match; +} + +Plasma::QueryMatch WindowsRunner::windowMatch(const KWindowInfo& info, WindowAction action, qreal relevance, Plasma::QueryMatch::Type type) +{ + Plasma::QueryMatch match(this); + match.setType(type); + match.setData(QString(QString::number((int)action) + "_" + QString::number(info.win()))); + match.setIcon(m_icons[info.win()]); + match.setText(info.name()); + QString desktopName; + int desktop = info.desktop(); + if (desktop == NET::OnAllDesktops) { + desktop = KWindowSystem::currentDesktop(); + } + if (desktop <= m_desktopNames.size()) { + desktopName = m_desktopNames[desktop - 1]; + } else { + desktopName = KWindowSystem::desktopName(desktop); + } + switch (action) { + case CloseAction: + match.setSubtext(i18n("Close running window on %1", desktopName)); + break; + case MinimizeAction: + match.setSubtext(i18n("(Un)minimize running window on %1", desktopName)); + break; + case MaximizeAction: + match.setSubtext(i18n("Maximize/restore running window on %1", desktopName)); + break; + case FullscreenAction: + match.setSubtext(i18n("Toggle fullscreen for running window on %1", desktopName)); + break; + case ShadeAction: + match.setSubtext(i18n("(Un)shade running window on %1", desktopName)); + break; + case KeepAboveAction: + match.setSubtext(i18n("Toggle keep above for running window on %1", desktopName)); + break; + case KeepBelowAction: + match.setSubtext(i18n("Toggle keep below running window on %1", desktopName)); + break; + case ActivateAction: + default: + match.setSubtext(i18n("Activate running window on %1", desktopName)); + break; + } + match.setRelevance(relevance); + return match; +} + +bool WindowsRunner::actionSupported(const KWindowInfo& info, WindowAction action) +{ + switch (action) { + case CloseAction: + return info.actionSupported(NET::ActionClose); + case MinimizeAction: + return info.actionSupported(NET::ActionMinimize); + case MaximizeAction: + return info.actionSupported(NET::ActionMax); + case ShadeAction: + return info.actionSupported(NET::ActionShade); + case FullscreenAction: + return info.actionSupported(NET::ActionFullScreen); + case KeepAboveAction: + case KeepBelowAction: + case ActivateAction: + default: + return true; + } +} + +#include "windowsrunner.moc" diff --git a/plasma/generic/runners/windows/windowsrunner.h b/plasma/generic/runners/windows/windowsrunner.h new file mode 100644 index 00000000..a51041a4 --- /dev/null +++ b/plasma/generic/runners/windows/windowsrunner.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright 2009 by Martin Gräßlin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ +#ifndef WINDOWSRUNNER_H +#define WINDOWSRUNNER_H + +#include + +class KWindowInfo; + +class WindowsRunner : public Plasma::AbstractRunner +{ + Q_OBJECT + + public: + WindowsRunner(QObject* parent, const QVariantList &args); + ~WindowsRunner(); + + virtual void match(Plasma::RunnerContext& context); + virtual void run(const Plasma::RunnerContext& context, const Plasma::QueryMatch& match); + + private Q_SLOTS: + void prepareForMatchSession(); + void matchSessionComplete(); + void gatherInfo(); + + private: + enum WindowAction { + ActivateAction, + CloseAction, + MinimizeAction, + MaximizeAction, + FullscreenAction, + ShadeAction, + KeepAboveAction, + KeepBelowAction + }; + Plasma::QueryMatch desktopMatch(int desktop, qreal relevance = 1.0); + Plasma::QueryMatch windowMatch(const KWindowInfo& info, WindowAction action, qreal relevance = 1.0, + Plasma::QueryMatch::Type type = Plasma::QueryMatch::ExactMatch); + bool actionSupported(const KWindowInfo& info, WindowAction action); + + QHash m_windows; + QHash m_icons; + QStringList m_desktopNames; + + bool m_inSession : 1; + bool m_ready : 1; +}; + +K_EXPORT_PLASMA_RUNNER(windows, WindowsRunner) + +#endif // WINDOWSRUNNER_H diff --git a/plasma/generic/scriptengines/CMakeLists.txt b/plasma/generic/scriptengines/CMakeLists.txt new file mode 100644 index 00000000..0c50409e --- /dev/null +++ b/plasma/generic/scriptengines/CMakeLists.txt @@ -0,0 +1,9 @@ +macro_optional_add_subdirectory(ruby) + +if(QT_QTWEBKIT_FOUND) + macro_optional_add_subdirectory(webkit) +endif(QT_QTWEBKIT_FOUND) + +if (PYTHONLIBRARY_FOUND AND NOT WIN32) + macro_optional_add_subdirectory(python) +endif (PYTHONLIBRARY_FOUND AND NOT WIN32) diff --git a/plasma/generic/scriptengines/python/CMakeLists.txt b/plasma/generic/scriptengines/python/CMakeLists.txt new file mode 100644 index 00000000..d4e5b133 --- /dev/null +++ b/plasma/generic/scriptengines/python/CMakeLists.txt @@ -0,0 +1,41 @@ +project(plasma-python) + +include(PythonMacros) + +# install the library, .desktop, and plasma.py +python_install(pyappletscript.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python) +python_install(plasma_importer.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python) +python_install(pydataengine.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python) +python_install(pyrunner.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python) +python_install(pywallpaper.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python) + +# remove the following three lines once we branch 4.5, they are only necessary as long +# as people update kdebase but not yet kdelibs (PYTHON_SITE_PACKAGES_INSTALL_DIR has just +# recently been added to FindPYthonLib.cmake and should be used as install destination). Alex +if(NOT PYTHON_SITE_PACKAGES_INSTALL_DIR) + set(PYTHON_SITE_PACKAGES_INSTALL_DIR ${PYTHON_SITE_PACKAGES_DIR} ) +endif(NOT PYTHON_SITE_PACKAGES_INSTALL_DIR) + +python_install(plasmascript.py ${PYTHON_SITE_PACKAGES_INSTALL_DIR}/PyKDE4) + +install(FILES plasma-scriptengine-applet-python.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-scriptengine-dataengine-python.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-scriptengine-runner-python.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-scriptengine-wallpaper-python.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +########################################################################### +# Test plasmoids +option(INSTALL_PYTHON_TEST_PLASMA "Install test python applet" OFF) + +if(INSTALL_PYTHON_TEST_PLASMA ) + + install(DIRECTORY test/plasma-applet-pyclock DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids) + + #TODO where install it ? + #install(DIRECTORY test/plasma-dataengine-pytime DESTINATION ${DATA_INSTALL_DIR}/plasma/engines) + +endif(INSTALL_PYTHON_TEST_PLASMA) diff --git a/plasma/generic/scriptengines/python/plasma-scriptengine-applet-python.desktop b/plasma/generic/scriptengines/python/plasma-scriptengine-applet-python.desktop new file mode 100644 index 00000000..f07ec350 --- /dev/null +++ b/plasma/generic/scriptengines/python/plasma-scriptengine-applet-python.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +Name=Python Widget +Name[ar]=ودجة بايثون +Name[ast]=Widget de Python +Name[be@latin]=Widžet „Python” +Name[bg]=Джаджа на Python +Name[bn]=পাইথন উইজেট +Name[bn_IN]=Python উইজেট +Name[bs]=Python grafičkih kontrola +Name[ca]=Estri en Python +Name[ca@valencia]=Estri en Python +Name[cs]=Python widget +Name[csb]=Interfejs Phythona +Name[da]=Python-widget +Name[de]=Python-Miniprogramm +Name[el]=Συστατικό Python +Name[en_GB]=Python Widget +Name[eo]=Pitona fenestraĵo +Name[es]=Widget de Python +Name[et]=Pythoni vidin +Name[eu]=Python trepeta +Name[fi]=Python-sovelma +Name[fr]=Composant graphique Python +Name[fy]=Python Widget +Name[ga]=Giuirléid Python +Name[gl]=Widget de Python +Name[gu]=પાયથોન વિજેટ +Name[he]=ווידג׳ט של Python +Name[hi]=पायथन विज़ेट +Name[hne]=पायथन विजेट +Name[hr]=Python widget +Name[hu]=Python-elem +Name[ia]=Elemento graphic (Widget) de Python +Name[id]=Widget Python +Name[is]=Python græja +Name[ja]=Python ウィジェット +Name[kk]=Python бөлшегі +Name[km]=ធាតុ​ក្រាហ្វិក Python +Name[kn]=ಪೈಥಾನ್ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Name[ko]=파이썬 위젯 +Name[ku]=Alava Python +Name[lt]=Python valdiklis +Name[lv]=Python sīkrīks +Name[ml]=പൈത്തണ്‍ ഉരുപ്പടി +Name[mr]=Python Widget +Name[nb]=Pythonelement +Name[nds]=Python-Lüttprogramm +Name[nl]=Python-widget +Name[nn]=Python-element +Name[or]=ପାଇଥନ ୱିଜେଟ +Name[pa]=ਪਾਈਥਨ ਵਿਦਜੈੱਟ +Name[pl]=Element interfejsu w Pythonie +Name[pt]=Elemento em Python +Name[pt_BR]=Widget em Python +Name[ro]=Control Python +Name[ru]=Виджет на языке Python +Name[si]=QEdje +Name[sk]=Python widget +Name[sl]=Gradnik v Pythonu +Name[sr]=питонски виџет +Name[sr@ijekavian]=питонски виџет +Name[sr@ijekavianlatin]=Python vidžet +Name[sr@latin]=Python vidžet +Name[sv]=Grafisk Python-komponent +Name[ta]=Python Widget +Name[tg]=Илова ба Python +Name[th]=วิดเจ็ตภาษาไพธอน +Name[tr]=Python Programcığı +Name[ug]=Python Widget +Name[uk]=Віджет Python +Name[wa]=Ahesse Python +Name[x-test]=xxPython Widgetxx +Name[zh_CN]=Python 部件 +Name[zh_TW]=Python 元件 +Comment=Plasma widget support written in Python +Comment[ar]=دعم ودجات البلازما المكتوبة بالبايثون +Comment[ast]=Elementu gráficu nativu de Plasma escritu en Python +Comment[be@latin]=Widžet systemy „Plasma”, napisany ŭ movie „Python” +Comment[bg]=Оригинална джаджа за Plasma, написана на Python +Comment[bs]=Podrška plazma grafičkim kontrolama pisanih u Pythonu +Comment[ca]=Estri nadiu del Plasma escrit en Python +Comment[ca@valencia]=Estri nadiu del Plasma escrit en Python +Comment[cs]=Podpora pro plasmoidy napsaná v Pythonu +Comment[da]=Understøttelse af plasma-widgets skrevet i Python +Comment[de]=Plasma-Miniprogramm-Unterstützung, geschrieben in Python +Comment[el]=Υποστήριξη συστατικού Plasma γραμμένο σε Python +Comment[en_GB]=Plasma widget support written in Python +Comment[es]=Elemento gráfico nativo de Plasma escrito en Python +Comment[et]=Pythonis kirjutatud Plasma vidina toetus +Comment[eu]=Python-en idatzitako Plasmaren trepeta-euskarria +Comment[fi]=Tuki Pythonilla kirjoitetuille Plasma-sovelmille +Comment[fr]=Prise en charge des composants graphiques de Plasma écrits en Python +Comment[fy]=Plasma widget stipe skreaun yn Python +Comment[ga]=Tacaíocht giuirléidí Plasma scríofa i Python +Comment[gl]=Widget nativo de Plasma escrito en Python +Comment[gu]=પાયથોનમાં લખાયેલ પ્લાઝમા વિજેટ આધાર +Comment[he]=תמיכה בווידג׳טים של Plasma עבור Python +Comment[hi]=पायथन में लिखा गया प्लाज्मा विजेट समर्थन +Comment[hne]=पायथन मं लिखे प्लाज्मा विजेट सपोर्ट +Comment[hr]=Podrška za Plasma widgete napisana u Pythonu +Comment[hu]=Plazmoid-támogatás Python nyelven +Comment[ia]=Supporto de elemento graphic (Widget) de Plasma scribite in Python +Comment[id]=Dukungan widget Plasma didukung oleh Python +Comment[is]=Stuðningur við plasmadót skrifaður í Python +Comment[ja]=Python で書かれた Plasma のウィジェット +Comment[kk]=Python-да жазылған Plasma интерфейс бөлшегі +Comment[km]=ការ​គាំទ្រ​ធាតុក្រាហ្វិក​ប្លាស្មា​ត្រូវបាន​សរសេរ​នៅ​ក្នុង​ភាសា Python +Comment[kn]=ಪೈಥಾನಿನಲ್ಲಿ ಬರೆಯಲಾದ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ(ವಿಡ್ಗೆಟ್) ಬೆಂಬಲ +Comment[ko]=파이썬으로 작성된 Plasma 위젯 +Comment[lt]=Plasma valdiklių palaikymas, parašytas su Python +Comment[lv]=Plasma sīkrīks, kas rakstīts Python +Comment[ml]=പൈത്തണില്‍ തയ്യാറാക്കിയിരിക്കുന്ന പ്ലാസ്മയില്‍ ഉരുപ്പടികള്‍ക്കുള്ള പിന്തുണ +Comment[mr]=Python अंतर्गत लिहीले गेलेले स्थानिक Plasma विजेट +Comment[nb]=Plasma skjermelement skrevet i Python +Comment[nds]=Plasma-Lüttprogrammünnerstütten, schreven in Python +Comment[nl]=Plasma-widget-ondersteuning geschreven in Python +Comment[nn]=Plasmoidestøtte skriven i Python +Comment[or]=ପାଇଥନରେ ଲିଖିତ ପ୍ଲାଜମା ୱିଜେଟ ସମର୍ଥନ +Comment[pa]=ਪਾਈਥਨ ਵਿੱਚ ਲਿਖੇ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ ਸਹਿਯੋਗ +Comment[pl]=Obsługa elementu interfejsu Plazmy w Pythonie +Comment[pt]=Elemento nativo do Plasma feito em Python +Comment[pt_BR]=Widget nativo do Plasma escrito em Python +Comment[ro]=Suport controale Plasma scris în Python +Comment[ru]=Виджет Plasma, написанный на языке Python +Comment[si]=Plasma widget support written in Python +Comment[sk]=Podpora widgetov plasmy napísaných v Pythone +Comment[sl]=Podpora za gradnike napisane v Pythonu +Comment[sr]=Подршка плазма виџета писаних у питону +Comment[sr@ijekavian]=Подршка плазма виџета писаних у питону +Comment[sr@ijekavianlatin]=Podrška plasma vidžeta pisanih u Pythonu +Comment[sr@latin]=Podrška plasma vidžeta pisanih u Pythonu +Comment[sv]=Stöd för grafisk Plasma-komponent skriven i Python +Comment[ta]=Plasma widget support written in Python +Comment[tg]=Модуль Plasma, написанный на языке JavaScript +Comment[th]=วิดเจ็ตพลาสมาที่ถูกเขียนด้วยภาษาไพธอน +Comment[tr]=Python ile yazılmış Plasma gereci desteği +Comment[ug]=Python بىلەن يېزىلغان Plasma widget نى قوللايدۇ +Comment[uk]=Віджет Плазми, написаний на Python +Comment[wa]=Sopoirt des ahesses sicrîtes e Python po Plasma +Comment[x-test]=xxPlasma widget support written in Pythonxx +Comment[zh_CN]=Plasma 部件支持用 Python 来编写 +Comment[zh_TW]=用 Python 寫的 Plasma 元件支援 +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-Plasma-API=python +X-Plasma-ComponentTypes=Applet +X-KDE-Library=kpythonpluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_python/pyappletscript.py diff --git a/plasma/generic/scriptengines/python/plasma-scriptengine-dataengine-python.desktop b/plasma/generic/scriptengines/python/plasma-scriptengine-dataengine-python.desktop new file mode 100644 index 00000000..bf1917b4 --- /dev/null +++ b/plasma/generic/scriptengines/python/plasma-scriptengine-dataengine-python.desktop @@ -0,0 +1,151 @@ +[Desktop Entry] +Name=Python data engine +Name[ar]=محرك بيانات بايثون +Name[ast]=Motor de datos de Python +Name[be@latin]=Systema źviestak u movie „Python” +Name[bg]=Ядро за данни с Python +Name[bn_IN]=Python ডাটা ইঞ্জিন +Name[bs]=Python pogon podataka +Name[ca]=Motor de dades en Python +Name[ca@valencia]=Motor de dades en Python +Name[cs]=Rozhraní v Pythonu +Name[csb]=Czérownik Phythona +Name[da]=Datamotor til Python +Name[de]=Python-Datentreiber +Name[el]=Μηχανή δεδομένων Python +Name[en_GB]=Python data engine +Name[eo]=Pitona datuma motoro +Name[es]=Motor de datos de Python +Name[et]=Pythoni andmete mootor +Name[eu]=Python-en datu-motorra +Name[fi]=Python-tietomoottori +Name[fr]=Moteur de données Python +Name[fy]=Python gegevens motor +Name[ga]=Inneall sonraí Python +Name[gl]=Motor de datos de Python +Name[gu]=પાયથોન માહિતી એન્જિન +Name[he]=מנוע תוכן של Python +Name[hi]=पायथन डाटा इंजिन +Name[hne]=पायथन डाटा इंजिन +Name[hr]=Pythonov podatkovni mehanizam +Name[hu]=Adatkezelő modul Python nyelven +Name[ia]=Motor de datos de Python +Name[id]=Mesin data Python +Name[is]=Python gagnavél +Name[ja]=Python データエンジン +Name[kk]=Python деректер тетігі +Name[km]=ម៉ាស៊ីន​ទិន្នន័យ Python +Name[kn]=ಪೈಥಾನ್ ದತ್ತಾಂಶ ಎಂಜಿನ್ +Name[ko]=파이썬 데이터 엔진 +Name[lt]=Python duomenų variklis +Name[lv]=Python datu dzinējs +Name[ml]=പൈത്തണ്‍ ഡേറ്റാ എഞ്ചിന്‍ +Name[mr]=Python माहिती इन्जीन +Name[nb]=Python datamotor +Name[nds]=Python-Datenkarn +Name[nl]=Python (gegevensengine) +Name[nn]=Python-datamotor +Name[or]=ପାଇଥନ ତଥ୍ୟ ମେସିନ +Name[pa]=ਪਾਈਥਨ ਡਾਟਾ ਇੰਜਣ +Name[pl]=Silnik danych w Pythonie +Name[pt]=Motor de dados em Python +Name[pt_BR]=Mecanismo de dados Python +Name[ro]=Motor de date Python +Name[ru]=Источник данных на языке Python +Name[si]=Python data engine +Name[sk]=Python dátový nástroj +Name[sl]=Podatkovni vir v Pythonu +Name[sr]=питонски датомотор +Name[sr@ijekavian]=питонски датомотор +Name[sr@ijekavianlatin]=Python datomotor +Name[sr@latin]=Python datomotor +Name[sv]=Python datagränssnitt +Name[ta]=Python data engine +Name[tg]=Системаи санаи Python +Name[th]=กลไกข้อมูลภาษาไพธอน +Name[tr]=Python veri motoru +Name[ug]=Python سانلىق-مەلۇمات ماتورى +Name[uk]=Рушій даних Python +Name[wa]=Moteur di dnêyes Python +Name[x-test]=xxPython data enginexx +Name[zh_CN]=Python 数据引擎 +Name[zh_TW]=Python 資料引擎 +Comment=Plasma data engine support for Python +Comment[ar]=دعم محرك بيانات بلازما للبايثون +Comment[ast]=Sofitu del motor de datos de plasma pa Python +Comment[be@latin]=Absłuhoŭvańnie systemy źviestak „Plasma” u movie „Python” +Comment[bg]=Поддръжка за създаване на ядра за данни на Plasma с Python +Comment[bs]=Podrška plazma pogona podataka za Python +Comment[ca]=Implementació de motor de dades del Plasma per al Python +Comment[ca@valencia]=Implementació de motor de dades del Plasma per al Python +Comment[cs]=Podpora datového rozhraní Plasmy v Pythonu +Comment[da]=Plasma datamotor-understøttelse af Python +Comment[de]=Unterstützung für Plasma-Datentreiber in Python +Comment[el]=Υποστήριξη μηχανής δεδομένων Plasma για την Python +Comment[en_GB]=Plasma data engine support for Python +Comment[eo]=Plasma datummotora apogo por Pitono +Comment[es]=Soporte del motor de datos de plasma para Python +Comment[et]=Plasma andmemootori toetus Pythonile +Comment[eu]=Python-erako Plasmaren datu-motorraren euskarria +Comment[fi]=Plasma-tietomoottorituki Python-kielelle +Comment[fr]=Prise en charge du moteur de données Python pour Plasma +Comment[fy]=Plasma-gegevensmotor-stipe foar Python +Comment[ga]=Tacaíocht innill sonraí Plasma le haghaidh Python +Comment[gl]=Motor de datos de Plasma para dar soporte a Python +Comment[gu]=પાયથોન માટે પ્લાઝમા માહિતી એન્જિન આધાર +Comment[he]=תמיכה במנועי תוכן של Plasma עבור Python +Comment[hi]=पायथन के लिए प्लाज्मा डाटा इंजिन समर्थन +Comment[hne]=पायथन बर प्लाज्मा डाटा इंजिन सपोर्ट +Comment[hr]=Plasmin podatkovni mehanizam koji podržava Python +Comment[hu]=Plazma adatkezelő modul Pythonhoz +Comment[ia]=Supporto de motor de datos de Plasma pro Python +Comment[id]=Mesin data Plasma didukung oleh Python +Comment[is]=Plasma gagnavélarstuðningur fyrir Python +Comment[ja]=Python のための Plasma データエンジンのサポート +Comment[kk]=Python деректер тетігінің Plasma қолдауы +Comment[km]=កា​រគាំទ្រ​ម៉ាស៊ីន​ទិន្នន័យ​ប្លាស្មា​សម្រាប់ Python +Comment[kn]=ಪೈಥಾನ್‌ಗಾಗಿ ಪ್ಲಾಸ್ಮಾ ದತ್ತ ಸಾಧನದ ಬೆಂಬಲ +Comment[ko]=파이썬을 위한 Plasma 데이터 엔진 지원 +Comment[lt]=Plasma duomenų variklio palaikymas Python kalbai +Comment[lv]=Plasma datu dzinēju atbalsts Python +Comment[ml]=പൈത്തിണിനുള്ള പ്ലാസ്മ ഡാറ്റാഎഞ്ചിന്‍ പിന്തുണ +Comment[mr]=Python करिता Plasma माहिती इन्जीन समर्थन +Comment[nb]=Plasma datamotor-støtte for Python +Comment[nds]=Plasma-Datenkarnünnerstütten för Python +Comment[nl]=Plasma-gegevensengine-ondersteuning voor Python +Comment[nn]=Plasma-datamotorstøtte for Python +Comment[or]=ପାଇଥନ ପାଇଁ ପ୍ଲାଜମା ତଥ୍ୟ ମେସିନ ସମର୍ଥନ +Comment[pa]=ਪਾਈਥਨ ਲਈ ਪਲਾਜ਼ਮਾ ਡਾਟਾ ਇੰਜਣ ਸਹਿਯੋਗ +Comment[pl]=Obsługa silnika danych Plazmy w Pythonie +Comment[pt]=Suporte para os motores de dados do Plasma em Python +Comment[pt_BR]=Suporte aos mecanismos de dados em Python +Comment[ro]=Suport motor de date Plasma pentru Python +Comment[ru]=Поддержка источников данных для Python +Comment[si]=Plasma data engine support for Python +Comment[sk]=Podpora dátového nástroja plasmy pre Python +Comment[sl]=Podpora za podatkovne vire napisane v Pythonu +Comment[sr]=Подршка плазма датомотора за питон +Comment[sr@ijekavian]=Подршка плазма датомотора за питон +Comment[sr@ijekavianlatin]=Podrška plasma datomotora za Python +Comment[sr@latin]=Podrška plasma datomotora za Python +Comment[sv]=Plasma datagränssnittstöd för Python +Comment[ta]=Plasma data engine support for Python +Comment[te]=ఫైథాన్ మద్దతుకొరకు ప్లాస్మా డాటా యింజన్ +Comment[tg]=Пуштибонии Python дар асоси маълумоти Plasma +Comment[th]=กลไกข้อมูลของพลาสมาที่เป็นภาษาไพธอน +Comment[tr]=Python için Plasma veri motoru desteği +Comment[ug]=Python نىڭ Plasma سانلىق-مەلۇمات ماتورىنى قوللىشى +Comment[uk]=Підтримка у рушіях даних для Python +Comment[wa]=Sopoirt po Python do moteur di dnêyes di Plasma +Comment[x-test]=xxPlasma data engine support for Pythonxx +Comment[zh_CN]=Python 的 Plasma 数据引擎支持 +Comment[zh_TW]=支援 Python 的 Plasma 資料引擎 + +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-KDE-Library=kpythonpluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_python/pydataengine.py +X-EngineName=pythondataengine +X-Plasma-API=python +X-Plasma-ComponentTypes=DataEngine diff --git a/plasma/generic/scriptengines/python/plasma-scriptengine-runner-python.desktop b/plasma/generic/scriptengines/python/plasma-scriptengine-runner-python.desktop new file mode 100644 index 00000000..c21118c4 --- /dev/null +++ b/plasma/generic/scriptengines/python/plasma-scriptengine-runner-python.desktop @@ -0,0 +1,133 @@ +[Desktop Entry] +Name=Python Runner +Name[ar]=مشغل بايثون +Name[ast]=Llanzador Python +Name[bg]=Стартер с Python +Name[bs]=Python izvođač +Name[ca]=Executor en Python +Name[ca@valencia]=Executor en Python +Name[cs]=Python spouštěč +Name[da]=Python Runner +Name[de]=Python-Starter +Name[el]=Εκτελεστής Python +Name[en_GB]=Python Runner +Name[eo]=Pitona motoro +Name[es]=Lanzador Python +Name[et]=Pythoni käivitaja +Name[eu]=Python abiarazlea +Name[fi]=Python-suoritusohjelma +Name[fr]=Lanceur Python +Name[ga]=Feidhmitheoir Python +Name[gl]=Executor en Python +Name[gu]=Python રનર +Name[he]=Python Runner +Name[hi]=पायथन रनर +Name[hr]=Python Runner +Name[hu]=Python-indító +Name[ia]=Executor de Python +Name[id]=Pelari Python +Name[is]=Python keyrari +Name[ja]=Python ラナー +Name[kk]=Python-ды жегу +Name[km]=កម្មវិធី​រត់ Python +Name[kn]=ಪೈಥಾನ್ ರನ್ನರ್ +Name[ko]=파이썬 실행기 +Name[lt]=Python leistukas +Name[lv]=Python darbinātājs +Name[mr]=पायथोन रनर +Name[nb]=Python-kjører +Name[nds]=Python-Dreger +Name[nl]=Python-starter +Name[nn]=Python-køyrar +Name[pa]=ਪਾਈਥਨ ਰਨਰ +Name[pl]=Uruchamianie w Pythonie +Name[pt]=Módulo de Execução em Python +Name[pt_BR]=Execução em Python +Name[ro]=Executor Python +Name[ru]=Модули запуска команд на языке Python +Name[si]=Python ධාවකය +Name[sk]=Python spúšťač +Name[sl]=Zaganjalnik v Pythonu +Name[sr]=питонски извођач +Name[sr@ijekavian]=питонски извођач +Name[sr@ijekavianlatin]=Python izvođač +Name[sr@latin]=Python izvođač +Name[sv]=Python körningsprogram +Name[tg]=Системаи санаи Python +Name[th]=ตัวเรียกใช้โปรแกรมภาษาไพธอน +Name[tr]=Python Çalıştırıcı +Name[ug]=Python ئىجراچىسى +Name[uk]=Запуск для Python +Name[wa]=Enondeu Python +Name[x-test]=xxPython Runnerxx +Name[zh_CN]=Python 运行器 +Name[zh_TW]=Python 執行器 +Comment=Plasma Runner support for Python +Comment[ar]=دعم مشغل بلازما لبايثون +Comment[ast]=Implementación de llanzador Plasma pa Python +Comment[bg]=Поддръжка за създаване на стартери на Plasma с Python +Comment[bs]=Podrška plazma izvođača za Python +Comment[ca]=Implementació de l'executor del Plasma per al Python +Comment[ca@valencia]=Implementació de l'executor del Plasma per al Python +Comment[cs]=Podpora Plasma spouštěče pro Python +Comment[da]=Understøttelse af Plasma Runner til Python +Comment[de]=Plasma-Starter-Unterstützung für Python +Comment[el]=Υποστήριξη εκτελεστή Plasma για την Python +Comment[en_GB]=Plasma Runner support for Python +Comment[es]=Implementación de lanzador Plasma para Python +Comment[et]=Plasma käivitaja toetus Pythonile +Comment[eu]=Python-erako Plasmaren abiarazlearen euskarria +Comment[fi]=Plasma-suoritusohjelmatuki Python-kielelle +Comment[fr]=Prise en charge du lanceur Plasma pour Python +Comment[gl]=Executor de Plasma que permite usar Python +Comment[he]=תמיכה ב־Runner של Plasma עבור Python +Comment[hi]=पायथन के लिए प्लाज्मा रनर समर्थन +Comment[hr]=Plasma Runner podrška za Python +Comment[hu]=Plazma-indító támogatás Pythonhoz +Comment[ia]=Supporto de executor de Plasma pro Python +Comment[id]=Dukungan Pelari Plasma terhadap Python +Comment[is]=Plasma gagnavélarstuðningur fyrir Python +Comment[ja]=Python のための Plasma ラナーサポート +Comment[kk]=Plasma-дағы Python-ды жегуін қолдауы +Comment[km]=ការ​គាំទ្រ​កម្មវិធី​រត់​ប្លាស្មា​សម្រាប់ Python +Comment[kn]=ಪೈಥಾನ್‌ಗಾಗಿ ಪ್ಲಾಸ್ಮಾ ರನ್ನರ್ ಬೆಂಬಲ +Comment[ko]=Plasma 파이썬 실행기 +Comment[lt]=Plasma paleidiklio palaikymas Python kalbai +Comment[lv]=Plasma darbinātāja atbalsts Python +Comment[mr]=पायथोन करिता प्लाज्मा रनर समर्थन +Comment[nb]=Plasma kjørerstøtte for Python +Comment[nds]=Plasma-Dregerünnerstütten för Python +Comment[nl]=Plasma-starter-ondersteuning voor Python +Comment[nn]=Plasma-køyrarstøtte for Python +Comment[pa]=ਪਾਈਥਨ ਲਈ ਪਲਾਜ਼ਮਾ ਰਨਰ ਸਹਿਯੋਗ +Comment[pl]=Obsługa programów uruchamiających dla Pythona +Comment[pt]=Suporte de módulos de execução do Plasma em Python +Comment[pt_BR]=Suporte aos mecanismos de execução do Plasma para Python +Comment[ro]=Suport executori Plasma pentru Python +Comment[ru]=Поддержка модулей запуска KRunner на языке Python +Comment[si]=Python සඳහා ප්ලාස්මා ධාවක සහාය +Comment[sk]=Podpora spúšťača plasmy pre Python +Comment[sl]=Podpora za zaganjalnike napisane v Pythonu +Comment[sr]=Подршка плазма извођача за питон +Comment[sr@ijekavian]=Подршка плазма извођача за питон +Comment[sr@ijekavianlatin]=Podrška plasma izvođača za Python +Comment[sr@latin]=Podrška plasma izvođača za Python +Comment[sv]=Plasma körningsstöd för Python +Comment[tg]=Пуштибонии Python дар асоси маълумоти Plasma +Comment[th]=ตัวเรียกใช้งานของพลาสมาที่รองรับสำหรับโปรแกรมภาษาไพธอน +Comment[tr]=Python için Plasma Çalıştırıcı desteği +Comment[ug]=Python نى قوللايدىغان Plasma ئىجراچىسى +Comment[uk]=Підтримка Python у інструментах запуску +Comment[wa]=Sopoirt po Python di l' enondeu di Plasma +Comment[x-test]=xxPlasma Runner support for Pythonxx +Comment[zh_CN]=支持 Python 的 Plasma 运行器 +Comment[zh_TW]=支援 Python 的執行器 + +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-KDE-Library=kpythonpluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_python/pyrunner.py +X-EngineName=pythonrunner +X-Plasma-API=python +X-Plasma-ComponentTypes=Runner diff --git a/plasma/generic/scriptengines/python/plasma-scriptengine-wallpaper-python.desktop b/plasma/generic/scriptengines/python/plasma-scriptengine-wallpaper-python.desktop new file mode 100644 index 00000000..17491cdf --- /dev/null +++ b/plasma/generic/scriptengines/python/plasma-scriptengine-wallpaper-python.desktop @@ -0,0 +1,137 @@ +[Desktop Entry] +Name=Python wallpaper +Name[ar]=خلفية شاشة مكتوبة باستخدام بايثون +Name[ast]=Fondu d'escritoriu en Python +Name[bg]=Тапети с Python +Name[bn]=পাইথন ওয়ালপেপার +Name[bs]=Python pozadinska slika +Name[ca]=Fons d'escriptori en Python +Name[ca@valencia]=Fons d'escriptori en Python +Name[cs]=Python pozadí plochy +Name[da]=Python-baggrundsbillede +Name[de]=Python-Hintergrundbild +Name[el]=Ταπετσαρία Python +Name[en_GB]=Python wallpaper +Name[eo]=Pitona ekranfono +Name[es]=Fondo de escritorio en Python +Name[et]=Pythoni taustapilt +Name[eu]=Python-en horma-papera +Name[fi]=Python-taustakuva +Name[fr]=Papier peint Python +Name[fy]=Python eftergrûnôfbylding +Name[ga]=Cúlbhrat Python +Name[gl]=Fondo de escritorio en Python +Name[gu]=પાયથોન વોલપેપર +Name[he]=רקע לשולחן עבודה של Python +Name[hr]=Python podloga +Name[hu]=Python háttérkép +Name[ia]=Tapete de papiro de Python +Name[id]=Wallpaper Python +Name[is]=Python veggfóður +Name[ja]=Python 壁紙 +Name[kk]=Python тұсқағазы +Name[km]=ផ្ទាំង​រូបភាព​របស់ Python +Name[kn]=ಪೈಥಾನ್ ಹಿನ್ನೆಲೆ ತೆರೆಚಿತ್ರ (ವಾಲ್ ಪೇಪರ್) +Name[ko]=파이썬 배경 그림 +Name[lt]=Python darbastalio fonas +Name[lv]=Python ekrāntapete +Name[ml]=പൈത്തണ്‍ ചുവര്‍ചിത്രം +Name[mr]=पायथोन वॉलपेपर +Name[nb]=Python bakgrunnsbilde +Name[nds]=Python-Achtergrundbild +Name[nl]=Python-achtergrondafbeelding +Name[nn]=Python-bakgrunnsbilete +Name[pa]=ਪਾਈਥਨ ਵਾਲਪੇਪਰ +Name[pl]=Tapeta w Pythonie +Name[pt]=Papel de parede em Python +Name[pt_BR]=Papel de parede em Python +Name[ro]=Fundal Python +Name[ru]=Обои рабочего стола на языке Python +Name[si]=Python වෝල්පේපර +Name[sk]=Python tapeta +Name[sl]=Ozadje v Pythonu +Name[sr]=питонски тапет +Name[sr@ijekavian]=питонски тапет +Name[sr@ijekavianlatin]=Python tapet +Name[sr@latin]=Python tapet +Name[sv]=Python skrivbordsunderlägg +Name[tg]=Барномаи Plasma +Name[th]=ภาพพื้นหลังของโปรแกรมไพธอน +Name[tr]=Python duvar kağıdı +Name[ug]=Python تام قەغىزى +Name[uk]=Шпалери для Python +Name[wa]=Tapisreye Python +Name[x-test]=xxPython wallpaperxx +Name[zh_CN]=Python 壁纸 +Name[zh_TW]=Python 桌布 +Comment=Plasma wallpaper support for Python +Comment[ar]=دعم خلفية شاشة بلازما لبايثون +Comment[ast]=Fondos de pantalla de Plasma pa Python +Comment[bg]=Поддръжка за работа с тапети на Plasma с Python +Comment[bs]=Podrška plazma pozadinskih slika za Python +Comment[ca]=Implementació de fons d'escriptori del Plasma per al Python +Comment[ca@valencia]=Implementació de fons d'escriptori del Plasma per al Python +Comment[cs]=Podpora Plasma pozadí plochy pro Python +Comment[da]=Understøttelse af Plasma wallpaper til Python +Comment[de]=Unterstützung in Plasma für Python-Hintergrundbilder +Comment[el]=Υποστήριξη ταπετσαρίας Plasma για την Python +Comment[en_GB]=Plasma wallpaper support for Python +Comment[es]=Fondos de pantalla de Plasma para Python +Comment[et]=Plasma taustapildi toetus Pythonile +Comment[eu]=Python-erako Plasma horma-paperaren euskarria +Comment[fi]=Plasma-taustakuvatuki Python-kielelle +Comment[fr]=Prise en charge du papier peint de Plasma pour Python +Comment[fy]=Plasma eftergrûnôfbylding stipe foar Python +Comment[gl]=Compatibilidade de Python co fondo de escritorio de Plasma +Comment[he]=תמיכה ברקעי שולחן עבודה של Plasma עבור Python +Comment[hi]=पायथन के लिए प्लाज्मा वालपेपर समर्थन +Comment[hr]=Plasmina podloga koja podržava Python +Comment[hu]=Plasma-háttérkép támogatás Pythonhoz +Comment[ia]=Supporto de tapete de papiro pro Python +Comment[id]=Wallpeper Plasma yang mendukung Python +Comment[is]=Plasma veggfóðurstuðningur fyrir Python +Comment[ja]=Python のための Plasma の壁紙 +Comment[kk]=Plasma-дағы Python тұсқағазының қолдауы +Comment[km]=ការ​គាំទ្រ​​ផ្ទាំង​​រូបភាព​ប្លាស្មា​សម្រាប់ Python +Comment[kn]=ಪೈಥಾನ್‌ಗಾಗಿ ಪ್ಲಾಸ್ಮಾ ಗಣಕತೆರೆ ಹಿನ್ನೆಲೆ ಚಿತ್ರ ಬೆಂಬಲ +Comment[ko]=파이썬을 위한 Plasma 배경 그림 지원 +Comment[lt]=Plasma apmušalo palaikymas Python kalbai +Comment[lv]=Plasma ekrāntapetes atbalsts Python +Comment[ml]=പൈത്തിണിനുള്ള പ്ലാസ്മ ചുമര്‍ച്ചിത്ര പിന്തുണ +Comment[mr]=पायथोन करिता प्लाज्मा वॉलपेपर समर्थन +Comment[nb]=Plasma bakgrunnsbilde-støtte for Python +Comment[nds]=Plasma-Achtergrundünnerstütten för Python +Comment[nl]=Plasma-achtergrondafbeelding-ondersteuning voor Python +Comment[nn]=Plasma-bakgrunnsbiletstøtte for Python +Comment[pa]=ਪਾਈਥਨ ਲਈ ਪਲਾਜ਼ਮਾ ਵਾਲਪੇਪਰ ਸਹਿਯੋਗ +Comment[pl]=Obsługa tapet Plazmy w Pythonie +Comment[pt]=Suporte para os papéis de parede do Plasma em Python +Comment[pt_BR]=Suporte aos mecanismos a papéis de parede do Plasma em Python +Comment[ro]=Suport fundaluri Plasma pentru Python +Comment[ru]=Поддержка обоев рабочего стола на языке Python +Comment[si]=Python සඳහා ප්ලාස්මා වෝල්පේපර් සහය +Comment[sk]=Podpora tapiet plasmy pre Python +Comment[sl]=Podpora za ozadja napisana v Pythonu +Comment[sr]=Подршка плазма тапета за питон +Comment[sr@ijekavian]=Подршка плазма тапета за питон +Comment[sr@ijekavianlatin]=Podrška plasma tapeta za Python +Comment[sr@latin]=Podrška plasma tapeta za Python +Comment[sv]=Plasma skrivbordsunderläggsstöd för Python +Comment[tg]=Пуштибонии Python дар асоси маълумоти Plasma +Comment[th]=ภาพพื้นหลังของพลาสมาที่รองรับสำหรับโปรแกรมภาษาไพธอน +Comment[tr]=Python için Plasma duvar kağıdı desteği +Comment[ug]=Python نى قوللايدىغان Plasma تام قەغەز +Comment[uk]=Підтримка Python у шпалерах Плазми +Comment[wa]=Sopoirt po Python del tapisreye di Plasma +Comment[x-test]=xxPlasma wallpaper support for Pythonxx +Comment[zh_CN]=支持 Python 的 Plasma 壁纸 +Comment[zh_TW]=支援 Python 的 Plasma 桌布 + +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-KDE-Library=kpythonpluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_python/pywallpaper.py +X-EngineName=pythonwallpaper +X-Plasma-API=python +X-Plasma-ComponentTypes=Wallpaper diff --git a/plasma/generic/scriptengines/python/plasma_importer.py b/plasma/generic/scriptengines/python/plasma_importer.py new file mode 100644 index 00000000..dae245ae --- /dev/null +++ b/plasma/generic/scriptengines/python/plasma_importer.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +import sys +import os +import imp + +PY3 = sys.version_info[0] == 3 + + +class PlasmaImporter(object): + def __init__(self): + self.toplevel = {} + self.toplevelcount = {} + self.marker = '' + str(id(self)) + sys.path.append(self.marker) + sys.path_hooks.append(self.hook) + + def hook(self,path): + if path==self.marker: + return self + else: + raise ImportError() + + def register_top_level(self,name,path): + if name not in self.toplevel: + self.toplevelcount[name] = 1 + self.toplevel[name] = path + else: + self.toplevelcount[name] += 1 + + def unregister_top_level(self,name): + value = self.toplevelcount[name]-1 + self.toplevelcount[name] = value + if value==0: + del self.toplevelcount[name] + del self.toplevel[name] + for key in list(sys.modules.keys()): + if key==name or key.startswith(name+"."): + del sys.modules[key] + + def find_module(self,fullname, path=None): + location = self.find_pymod(fullname) + if location is not None: + return self + else: + return None + + # Find the given module in the plasma directory. + # Result a tuple on success otherwise None. The tuple contains the location + # of the module/package in disk and a boolean indicating if it is a package + # or module + def find_pymod(self,modulename): + parts = modulename.split('.') + toppackage = parts[0] + rest = parts[1:] + + if toppackage in self.toplevel: + path = self.toplevel[toppackage] + if len(rest)==0: + # Simple top level Plasma package + return (path,True) + else: + restpath = apply(os.path.join,rest) + fullpath = os.path.join(path,'contents','code',restpath) + if os.path.isdir(fullpath): + return (fullpath,True) + elif os.path.exists(fullpath+'.py'): + return (fullpath+'.py',False) + else: + return None + + def _get_code(self,location): + return open(location).read() + + def load_module(self, fullname): + location,ispkg = self.find_pymod(fullname) + if ispkg: # Package dir. + initlocation = os.path.join(location,'__init__.py') + code = None + if os.path.isfile(initlocation): + code = open(initlocation) + else: + code = open(location) + + mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) + mod.__file__ = location #"<%s>" % self.__class__.__name__ + mod.__loader__ = self + if ispkg: + mod.__path__ = [self.marker] + if code is not None: + try: + if PY3: + exec(code in mod.__dict__) + else: + exec code in mod.__dict__ + finally: + code.close() + return mod + +#plasma_importer = PlasmaImporter() +#plasma_importer.register_top_level('plasma_pyclock','/home/sbe/devel/python_plasma_2/test/plasma-pyclock') +#from plasma_pyclock import main diff --git a/plasma/generic/scriptengines/python/plasmascript.py b/plasma/generic/scriptengines/python/plasmascript.py new file mode 100644 index 00000000..ba149cf5 --- /dev/null +++ b/plasma/generic/scriptengines/python/plasmascript.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +# Plasma applet API for Python + +from PyQt4.QtCore import QObject +from PyQt4.QtGui import QGraphicsWidget +from PyKDE4.plasma import Plasma # Plasma C++ namespace + +#import sip +#import gc + +class Applet(QObject): + ''' Subclass Applet in your module and return an instance of it in a global function named + applet(). Implement the following functions to breathe life into your applet: + * paint - Draw the applet given a QPainter and some options + It provides the same API as Plasma.Applet; it just has slightly less irritating event names. ''' + def __init__(self, parent=None): + # this should be set when the applet is created + QObject.__init__(self, parent) + #sip.settracemask(0x3f) + self.applet = None + self.applet_script = None + self._forward_to_applet = True + + def __getattr__(self, key): + # provide transparent access to the real applet instance + if self._forward_to_applet: + try: + return getattr(self.applet_script, key) + except: + return getattr(self.applet, key) + else: + raise AttributeError(key) + + def _enableForwardToApplet(self): + self._forward_to_applet = True + def _disableForwardToApplet(self): + self._forward_to_applet = False + + # Events + def setApplet(self,applet): + self.applet = applet + + def setAppletScript(self,appletScript): + self.applet_script = appletScript + + def init(self): + pass + + def configChanged(self): + pass + + def paintInterface(self, painter, options, rect): + pass + + def constraintsEvent(self, flags): + pass + + def showConfigurationInterface(self): + self.dlg = self.standardConfigurationDialog() + self.createConfigurationInterface(self.dlg) + self.addStandardConfigurationPages(self.dlg) + self.dlg.show() + + def createConfigurationInterface(self, dlg): + pass + + def contextualActions(self): + return [] + + def shape(self): + return QGraphicsWidget.shape(self.applet) + + def initExtenderItem(self, item): + print ("Missing implementation of initExtenderItem in the applet " + \ + item.config().readEntry('SourceAppletPluginName', '').toString() + \ + "!\nAny applet that uses extenders should implement initExtenderItem to " + \ + "instantiate a widget.") + + def saveState(self, config): + pass + +########################################################################### +class DataEngine(QObject): + def __init__(self, parent=None): + QObject.__init__(self, parent) + self.dataengine = None + self.dataengine_script = None + + def setDataEngine(self,dataEngine): + self.dataEngine = dataEngine + + def setDataEngineScript(self,dataEngineScript): + self.data_engine_script = dataEngineScript + + def __getattr__(self, key): + # provide transparent access to the real dataengine script instance + try: + return getattr(self.data_engine_script, key) + except: + return getattr(self.dataEngine, key) + + def init(self): + pass + + def sources(self): + return [] + + def sourceRequestEvent(self,name): + return False + + def updateSourceEvent(self,source): + return False + + def serviceForSource(self,source): + return Plasma.DataEngineScript.serviceForSource(self.data_engine_script,source) + +########################################################################### +class Wallpaper(QObject): + def __init__(self, parent=None): + QObject.__init__(self, parent) + self.wallpaper = None + self.wallpaper_script = None + + def setWallpaper(self,wallpaper): + self.wallpaper = wallpaper + + def setWallpaperScript(self,wallpaperScript): + self.wallpaper_script = wallpaperScript + + def __getattr__(self, key): + # provide transparent access to the real wallpaper script instance + try: + return getattr(self.wallpaper_script, key) + except: + return getattr(self.wallpaper, key) + + def init(self, config): + pass + + def paint(self,painter, exposedRect): + pass + + def save(self,config): + pass + + def createConfigurationInterface(self,parent): + return None + + def mouseMoveEvent(self,event): + pass + + def mousePressEvent(self,event): + pass + + def mouseReleaseEvent(self,event): + pass + + def wheelEvent(self,event): + pass + + def renderCompleted(self, image): + pass + + def urlDropped(self, url): + pass + +########################################################################### +class Runner(QObject): + def __init__(self, parent=None): + QObject.__init__(self, parent) + self.runner = None + self.runner_script = None + + def setRunner(self,runner): + self.runner = runner + + def setRunnerScript(self,runnerScript): + self.runner_script = runnerScript + + def __getattr__(self, key): + # provide transparent access to the real runner script instance + try: + return getattr(self.runner_script, key) + except: + return getattr(self.runner, key) + + def init(self): + pass + + def match(self, search): + pass + + def run(self, search, action): + pass + + def prepare(self): + pass + + def teardown(self): + pass + + def createRunOptions(self, widget): + pass + + def reloadConfiguration(self): + pass diff --git a/plasma/generic/scriptengines/python/pyappletscript.py b/plasma/generic/scriptengines/python/pyappletscript.py new file mode 100644 index 00000000..907d10ad --- /dev/null +++ b/plasma/generic/scriptengines/python/pyappletscript.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyKDE4.plasma import Plasma +import plasma_importer +import os.path + +class PythonAppletScript(Plasma.AppletScript): + importer = None + + def __init__(self, parent): + Plasma.AppletScript.__init__(self,parent) + #print("PythonAppletScript()") + if PythonAppletScript.importer is None: + PythonAppletScript.importer = plasma_importer.PlasmaImporter() + self.initialized = False + + def init(self): + #print("Script Name: " + str(self.applet().name())) + #print("Script Category: " + str(self.applet().category())) + + # applet() cannot be relied on to give the right details in the destructor, + # so the plugin name is stored aside. (n.b module.__name__ cannot be relied + # on either; it might have been changed in the module itself) + self.moduleName = str(self.applet().pluginName()) + #print("pluginname: " + str(self.applet().pluginName())) + self.pluginName = 'applet_' + self.moduleName.replace('-','_') + + PythonAppletScript.importer.register_top_level(self.pluginName, str(self.applet().package().path())) + + #print("mainScript: " + str(self.mainScript())) + #print("package path: " + str(self.applet().package().path())) + + # import the code at the file name reported by mainScript() + relpath = os.path.relpath(str(self.mainScript()),str(self.applet().package().path())) + if relpath.startswith("contents/code/"): + relpath = relpath[14:] + if relpath.endswith(".py"): + relpath = relpath[:-3] + relpath = relpath.replace("/",".") + self.module = __import__(self.pluginName+'.'+relpath) + + # Plasma main scripts not necessarily are named "main" + # So we use __dict__ to get the right main script name + basename = os.path.basename(str(self.mainScript())) + basename = os.path.splitext(basename)[0] + self.pyapplet = self.module.__dict__[basename].CreateApplet(None) + self.pyapplet.setApplet(self.applet()) + self.pyapplet.setAppletScript(self) + self.connect(self.applet(), SIGNAL('extenderItemRestored(Plasma::ExtenderItem*)'), + self, SLOT('initExtenderItem(Plasma::ExtenderItem*)')) + self.connect(self, SIGNAL('saveState(KConfigGroup&)'), + self, SLOT('saveStateSlot(KConfigGroup&)')) + self._setUpEventHandlers() + self.initialized = True + + self.pyapplet.init() + return True + + def __dtor__(self): + #print("~PythonAppletScript()") + if not self.initialized: + return + + PythonAppletScript.importer.unregister_top_level(self.pluginName) + self.pyapplet = None + + @pyqtSignature("initExtenderItem(Plasma::ExtenderItem*)") + def initExtenderItem(self, item): + if not self.initialized: + return + self.pyapplet.initExtenderItem(item) + + @pyqtSignature("saveStateSlot(KConfigGroup&)") + def saveStateSlot(self, config): + if not self.initialized: + return + self.pyapplet.saveState(config) + + def constraintsEvent(self, constraints): + if not self.initialized: + return + self.pyapplet.constraintsEvent(constraints) + + def showConfigurationInterface(self): + if not self.initialized: + return + #print("Script: showConfigurationInterface") + self.pyapplet.showConfigurationInterface() + + def configChanged(self): + if not self.initialized: + return + self.pyapplet.configChanged() + + def paintInterface(self, painter, option, contentsRect): + if not self.initialized: + return + self.pyapplet.paintInterface(painter, option, contentsRect) + + def contextualActions(self): + if not self.initialized: + return + + #print("pythonapplet contextualActions()") + return self.pyapplet.contextualActions() + + def shape(self): + if not self.initialized: + return QPainterPath() + return self.pyapplet.shape() + + def eventFilter(self, obj, event): + handler = self.event_handlers.get(event.type(),None) + if handler is not None: + apply(getattr(self.pyapplet,handler), (event,) ) + return True + else: + return False + + def _setUpEventHandlers(self): + self.event_handlers = {} + + self.pyapplet._disableForwardToApplet() + for event_type,handler in { + QEvent.GraphicsSceneMousePress: "mousePressEvent", + QEvent.GraphicsSceneContextMenu: "contextMenuEvent", + QEvent.GraphicsSceneDragEnter: "dragEnterEvent", + QEvent.GraphicsSceneDragLeave: "dragLeaveEvent", + QEvent.GraphicsSceneDragMove: "dragMoveEvent", + QEvent.GraphicsSceneDrop: "dropEvent", + QEvent.FocusIn: "focusInEvent", + QEvent.FocusOut: "focusOutEvent", + QEvent.GraphicsSceneHoverEnter: "hoverEnterEvent", + QEvent.GraphicsSceneHoverLeave: "hoverLeaveEvent", + QEvent.GraphicsSceneHoverMove: "hoverMoveEvent", + QEvent.InputMethod: "inputMethodEvent", + QEvent.KeyPress: "keyPressEvent", + QEvent.KeyRelease: "keyReleaseEvent", + QEvent.GraphicsSceneMouseDoubleClick: "mouseDoubleClickEvent", + QEvent.GraphicsSceneMouseMove: "mouseMoveEvent", + QEvent.GraphicsSceneMousePress: "mousePressEvent", + QEvent.GraphicsSceneMouseRelease: "mouseReleaseEvent", + QEvent.GraphicsSceneWheel: "wheelEvent" + }.iteritems(): + if hasattr(self.pyapplet,handler): + self.event_handlers[event_type] = handler + self.pyapplet._enableForwardToApplet() + + if self.event_handlers: + self.applet().installEventFilter(self) + +def CreatePlugin(widget_parent, parent, component_data): + return PythonAppletScript(parent) diff --git a/plasma/generic/scriptengines/python/pydataengine.py b/plasma/generic/scriptengines/python/pydataengine.py new file mode 100644 index 00000000..edb93c9c --- /dev/null +++ b/plasma/generic/scriptengines/python/pydataengine.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyKDE4.plasma import Plasma +import plasma_importer +import os.path + +class PythonDataEngineScript(Plasma.DataEngineScript): + importer = None + + def __init__(self, parent): + Plasma.DataEngineScript.__init__(self,parent) + if PythonDataEngineScript.importer is None: + PythonDataEngineScript.importer = plasma_importer.PlasmaImporter() + self.initialized = False + + def init(self): + self.moduleName = str(self.dataEngine().pluginName()) + self.pluginName = 'dataengine_' + self.moduleName.replace('-','_') + + PythonDataEngineScript.importer.register_top_level(self.pluginName, str(self.dataEngine().package().path())) + + # import the code at the file name reported by mainScript() + relpath = os.path.relpath(str(self.mainScript()),str(self.dataEngine().package().path())) + if relpath.startswith("contents/code/"): + relpath = relpath[14:] + if relpath.endswith(".py"): + relpath = relpath[:-3] + relpath = relpath.replace("/",".") + self.module = __import__(self.pluginName+'.'+relpath) + # The script may not necessarily be called "main" + # So we use __dict__ to look up the right name + basename = os.path.basename(str(self.mainScript())) + basename = os.path.splitext(basename)[0] + + self.pydataengine = self.module.__dict__[basename].CreateDataEngine(None) + self.pydataengine.setDataEngine(self.dataEngine()) + self.pydataengine.setDataEngineScript(self) + self.pydataengine.init() + + self.initialized = True + return True + + def __dtor__(self): + PythonDataEngineScript.importer.unregister_top_level(self.pluginName) + self.pydataengine = None + + def sources(self): + return self.pydataengine.sources() + + def serviceForSource(self,source): + return self.pydataengine.serviceForSource(source) + + def sourceRequestEvent(self,name): + return self.pydataengine.sourceRequestEvent(name) + + def updateSourceEvent(self,source): + return self.pydataengine.updateSourceEvent(source) + +def CreatePlugin(widget_parent, parent, component_data): + return PythonDataEngineScript(parent) diff --git a/plasma/generic/scriptengines/python/pyrunner.py b/plasma/generic/scriptengines/python/pyrunner.py new file mode 100644 index 00000000..e520e307 --- /dev/null +++ b/plasma/generic/scriptengines/python/pyrunner.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# Copyright 2009 Petri Damstén +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyKDE4.plasma import Plasma +import plasma_importer +import os.path + +class PythonRunnerScript(Plasma.RunnerScript): + importer = None + + def __init__(self, parent): + Plasma.RunnerScript.__init__(self,parent) + if PythonRunnerScript.importer is None: + PythonRunnerScript.importer = plasma_importer.PlasmaImporter() + self.initialized = False + + def init(self): + self.moduleName = str(self.runner().package().metadata().pluginName()) + self.pluginName = 'runner_' + self.moduleName.replace('-','_') + + PythonRunnerScript.importer.register_top_level(self.pluginName, str(self.runner().package().path())) + + # import the code at the file name reported by mainScript() + relpath = os.path.relpath(str(self.mainScript()),str(self.runner().package().path())) + if relpath.startswith("contents/code/"): + relpath = relpath[14:] + if relpath.endswith(".py"): + relpath = relpath[:-3] + relpath = relpath.replace("/",".") + self.module = __import__(self.pluginName+'.'+relpath) + basename = os.path.basename(str(self.mainScript())) + basename = os.path.splitext(basename)[0] + self.pyrunner = self.module.__dict__[basename].CreateRunner(None) + self.pyrunner.setRunner(self.runner()) + self.pyrunner.setRunnerScript(self) + self.connect(self, SIGNAL('prepare()'), self, SLOT('prepare()')) + self.connect(self, SIGNAL('teardown()'), self, SLOT('teardown()')) + self.connect(self, SIGNAL('createRunOptions(QWidget*)'), + self, SLOT('createRunOptions(QWidget*)')) + self.connect(self, SIGNAL('reloadConfiguration()'), + self, SLOT('reloadConfiguration()')) + self.pyrunner.init() + + self.initialized = True + return True + + def __dtor__(self): + PythonRunnerScript.importer.unregister_top_level(self.pluginName) + self.pyrunner = None + + def match(self, search): + self.pyrunner.match(search) + + def run(self, search, action): + self.pyrunner.run(search, action) + + @pyqtSignature("prepare()") + def prepare(self): + self.pyrunner.prepare() + + @pyqtSignature("teardown()") + def teardown(self): + self.pyrunner.teardown() + + @pyqtSignature("createRunOptions(QWidget*)") + def createRunOptions(self, widget): + self.pyrunner.createRunOptions(widget) + + @pyqtSignature("reloadConfiguration()") + def reloadConfiguration(self): + self.pyrunner.reloadConfiguration() + +def CreatePlugin(widget_parent, parent, component_data): + return PythonRunnerScript(parent) diff --git a/plasma/generic/scriptengines/python/pywallpaper.py b/plasma/generic/scriptengines/python/pywallpaper.py new file mode 100644 index 00000000..e0e7e8cd --- /dev/null +++ b/plasma/generic/scriptengines/python/pywallpaper.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2008 Simon Edwards +# Copyright 2009 Petri Damstén +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2, 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 Library General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyKDE4.plasma import Plasma +import plasma_importer +import os.path + +class PythonWallpaperScript(Plasma.WallpaperScript): + importer = None + + def __init__(self, parent): + Plasma.WallpaperScript.__init__(self,parent) + if PythonWallpaperScript.importer is None: + PythonWallpaperScript.importer = plasma_importer.PlasmaImporter() + self.initialized = False + + def init(self): + self.moduleName = str(self.wallpaper().pluginName()) + self.pluginName = 'wallpaper_' + self.moduleName.replace('-','_') + + PythonWallpaperScript.importer.register_top_level(self.pluginName, str(self.wallpaper().package().path())) + + # import the code at the file name reported by mainScript() + relpath = os.path.relpath(str(self.mainScript()),str(self.wallpaper().package().path())) + if relpath.startswith("contents/code/"): + relpath = relpath[14:] + if relpath.endswith(".py"): + relpath = relpath[:-3] + relpath = relpath.replace("/",".") + self.module = __import__(self.pluginName+'.'+relpath) + self.pywallpaper = self.module.main.CreateWallpaper(None) + self.pywallpaper.setWallpaper(self.wallpaper()) + self.pywallpaper.setWallpaperScript(self) + self.initialized = True + return True + + def __dtor__(self): + PythonWallpaperScript.importer.unregister_top_level(self.pluginName) + self.pywallpaper = None + + def paint(self, painter, exposedRect): + self.pywallpaper.paint(painter, exposedRect) + + def initWallpaper(self, config): + self.pywallpaper.init(config) + + def save(self, config): + self.pywallpaper.save(config) + + def createConfigurationInterface(self, parent): + self.connect(self, SIGNAL('settingsChanged(bool)'), parent, SLOT('settingsChanged(bool)')) + return self.pywallpaper.createConfigurationInterface(parent) + + def settingsChanged(self, changed): + self.emit(SIGNAL('settingsChanged(bool)'), changed) + + def mouseMoveEvent(self, event): + self.pywallpaper.mouseMoveEvent(event) + + def mousePressEvent(self, event): + self.pywallpaper.mousePressEvent(event) + + def mouseReleaseEvent(self, event): + self.pywallpaper.mouseReleaseEvent(event) + + def wheelEvent(self, event): + self.pywallpaper.wheelEvent(event) + + @pyqtSignature("renderCompleted(const QImage&)") + def renderCompleted(self, image): + self.pywallpaper.renderCompleted(image) + + @pyqtSignature("urlDropped(const KUrl&)") + def urlDropped(self, url): + self.pywallpaper.urlDropped(url) + +def CreatePlugin(widget_parent, parent, component_data): + return PythonWallpaperScript(parent) diff --git a/plasma/generic/scriptengines/ruby/CMakeLists.txt b/plasma/generic/scriptengines/ruby/CMakeLists.txt new file mode 100644 index 00000000..b6d744c0 --- /dev/null +++ b/plasma/generic/scriptengines/ruby/CMakeLists.txt @@ -0,0 +1,6 @@ +install(FILES applet.rb DESTINATION ${DATA_INSTALL_DIR}/plasma_scriptengine_ruby) +install(FILES data_engine.rb DESTINATION ${DATA_INSTALL_DIR}/plasma_scriptengine_ruby) + +install(FILES plasma-scriptengine-ruby-applet.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-scriptengine-ruby-dataengine.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/generic/scriptengines/ruby/ChangeLog b/plasma/generic/scriptengines/ruby/ChangeLog new file mode 100644 index 00000000..24df1d18 --- /dev/null +++ b/plasma/generic/scriptengines/ruby/ChangeLog @@ -0,0 +1,140 @@ +2010-02-14 Richard Dale + +* Special case the constructors of the new Plasma widgets so that they can be +passed a PlasmaScripting::Applet as parent +* Fixed the dialog handling so that it uses the standardConfigurationDialog() +and addStandardConfigurationPages() methods + +2009-08-07 Richard Dale +* Fixed typo in the type signature of the initExtenderItem() slot. Thanks to +David Palacio for reporting the bug + +2009-07-19 Richard Dale +* Use the new name 'extenderItemRestored()' for the signal to connect to +initExtenderItem() + +2009-07-18 Richard Dale +* Add a Ruby version of the C++ extender tutorial example on Techbase + +2009-07-17 Richard Dale +* If an applet has implemented an initExtenderItem() method, then connect the +new initScriptingExtenderItem() signal to it. + +2009-06-16 Richard Dale +* The resize() method doesn't work with scripting plasmoids, so if it is used +output a warning message, and suggest adding a X-Plasma-DefautSize entry in +the metadata.desktop file. + +2009-05-26 Richard Dale +* Add a callback for the configChanged() method in scripting applets + +2009-04-27 Richard Dale +* Added some special casing for the new KDE 4.3 widgets, so they work with +PLasmaScripting::Applet arguments + +2009-04-22 Richard Dale +* Added PlasmaScripting::Containment and PlasmaScripting::PopupApplet classes, + now that scripting containments and popups can be created + +2009-02-10 Richard Dale +* For the methods that need to be special cased to work with + PlasmaScripting::Applet type arguments, add lower case/underscore versions + of the methods + +2009-02-05 Richard Dale +* Added various special casing to the Plasma::ToolTipManager class so you can + pass a PlasmaScripting::Applet to the methods. Thanks to Mathieu Jobin for + reporting the bug. + +2008-12-22 Richard Dale +* Changed the tiger applet example to find its tiger.svg resource from within + the plasmoid package. Thanks to Rany Keddo for helping to get it working. + +2008-12-01 Richard Dale +* Added updateAllSources() and removeSource() slots to the + PlasmScripting::DataEngine +* Add DBus notification to the time data engine example for when the config + changes + +2008-11-18 Richard Dale +* Fix problem with the ruby 'type()' method clashing with the one in + Qt::GraphicsItem subclasses reported by David Palacio +* Added a 'dbpedia-queries' data engine for making SPARQL queries to DBpedia + about music albums +* The sources() and init() methods needn't be implemented by a scripting + data engine + +2008-11-17 Richard Dale +* Fixed missing constructor bug in Qt::GraphicsProxyWidget reported by David + Palacio. Thanks to David for reporting the bug. +* Improved the names of the Ruby applet and dataengine examples +* Allow a PlasmaScripting::Applet to be a parent of all the Qt::GraphicsItem + sub classes in their constructors + +2008-11-05 Richard Dale +* Fixed some bugs in the DataEngineScript class. The expected path was + 'plasma/engines' whereas the plasmapkg tool installs them in + 'plasma/dataengines'. The mainScript() and package() methods hadn't been + implemented and were added. +* Added a 'ruby_time' example scripting data engine + +2008-10-30 Richard Dale +* Separated the script engine plugins from the plasma ruby extension and moved + the script engine code to kdebase with the other script engines + +2008-10-23 Richard Dale +* Converted the webapplet to use the script engine api, and renamed it + plasma_applet_ruby_webapplet + +2008-08-15 Richard Dale +* Re-added the ruby version of the plasmoidviewer app + +2008-08-12 Arno Rehn +* Fix restoring of applet sizes. + +2008-08-07 Richard Dale +* The marshaller for Plasma::DataEngine::Data was creating Qt::Variants with + the wrong smoke pointer in the smokeruby_object struct, and this was causing + a crash in the GC marking function. +* In PlasmaScripting::Applet, if a constant such as NoBackground is referenced + and found to be missing, then look for it in Plasma::Applet. +* Fix bugs in the PlasmaScripting::Applet#showConfigurationInterface method +* Special case Plasma::Applet#id so it doesn't get a Ruby warning. +* In PlasmaScriptengineRuby::Applet the module name wasn't being derived + correctly from the Package path +* Add two versions of the clock applet + * plasma_applet_ruby_clock uses the ScriptEngine api and is packaged as a + plasmoid. It can be installed by typing the following command in the + examples/applets directory: + + $ plasmapkg --install plasma_applet_ruby_clock --type plasmoid + + * analog-clock uses the C++ plugin api. Normally Ruby applets should be + written using the script engine api, and this example is only included + to show how the two apis differ. The clocks are functionally identical. + +2008-08-06 Richard Dale +* Add some fixes for the new Plasma::Frame and Plasma::Slider widgets + +2008-07-03 Richard Dale +* Add slots and signals for scripting applets and data engines corresponding + to the ones in Plasma::Applet and Plasma::DataEngine +* Change the install destination to plasma_scriptengine_ruby and the modules + of the plugin classes to match + +2008-06-30 Richard Dale +* For script engine based applets, add the directory where the mainScript was + found to the ruby load path. + +2008-06-29 Richard Dale +* If a method call is invoked on a PlasmaScripting::Applet, then relay it to + the underlying Plasma::Applet in the script engine. +* Add an event filter to the RubyAppletScript::Applet class so that scripting + applets can implement event method handling overrides. +* Change various methods in the QGraphicsView and Plasma api so that they can + accept instances of PlasmaScripting::Applet, and the instance is substituted + for the underlying Plasma::Applet in the ScriptEngine. + +2008-06-28 Richard Dale +* Make the Ruby ScriptEngine based plugins work +* Add a Ruby version of the Javascript Tiger applet diff --git a/plasma/generic/scriptengines/ruby/applet.rb b/plasma/generic/scriptengines/ruby/applet.rb new file mode 100644 index 00000000..7b2a7bec --- /dev/null +++ b/plasma/generic/scriptengines/ruby/applet.rb @@ -0,0 +1,1215 @@ +=begin + * Copyright 2008-2010 by Richard Dale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=end + +require 'plasma_applet' + +module PlasmaScripting + class Applet < Qt::Object + slots "setImmutability(Plasma::ImmutabilityType)", + :destroy, + :showConfigurationInterface, + :raise, + :lower, + :flushPendingConstraintsEvents, + :init, + 'initExtenderItem(Plasma::ExtenderItem*)' + + signals :releaseVisualFocus, + :geometryChanged, + :configNeedsSaving, + :activate + + attr_accessor :applet_script + + def initialize(parent, args = nil) + super(parent) + @applet_script = parent + connect(@applet_script.applet, SIGNAL(:releaseVisualFocus), self, SIGNAL(:releaseVisualFocus)) + connect(@applet_script.applet, SIGNAL(:geometryChanged), self, SIGNAL(:geometryChanged)) + connect(@applet_script.applet, SIGNAL(:configNeedsSaving), self, SIGNAL(:configNeedsSaving)) + connect(@applet_script.applet, SIGNAL(:activate), self, SIGNAL(:activate)) + connect(@applet_script.applet, SIGNAL('extenderItemRestored(Plasma::ExtenderItem*)'), self, SLOT('initExtenderItem(Plasma::ExtenderItem*)')) + end + + # If a method is called on a PlasmaScripting::Applet instance is found to be missing + # then try calling the method on the underlying Plasma::Applet in the ScriptEngine. + def method_missing(method, *args) + begin + super(method, *args) + rescue + applet_script.applet.method_missing(method, *args) + end + end + + def self.const_missing(name) + begin + super(name) + rescue + Plasma::Applet.const_missing(name) + end + end + + def configChanged + end + + def paintInterface(painter, option, contentsRect) + end + + def initExtenderItem(item) + puts "Missing implementation of initExtenderItem in the applet " \ + "#{item.config.readEntry('SourceAppletPluginName', '')}" \ + "!\n Any applet that uses extenders should implement initExtenderItem to " \ + "instantiate a widget." + end + + def size + @applet_script.size + end + + def shape + @applet_script.shape + end + + def resize(*args) + if args.length == 1 && args[0].kindof?(Qt::Size) + puts "Warning: invalid resize() call. Add this to your metadata.desktop file:" + puts "X-Plasma-DefautSize=%d,%d" % [args[0].width, args[0].height] + elsif args.length == 2 + puts "Warning: invalid resize() call. Add this to your metadata.desktop file:" + puts "X-Plasma-DefautSize=%d,%d" % [args[0].to_i, args[1].to_i] + else + super(*args) + end + end + + def constraintsEvent(constraints) + end + + def contextualActions + return [] + end + + def createConfigurationInterface(dialog) + end + + def showConfigurationInterface + end + + def dataEngine(engine) + @applet_script.dataEngine(engine) + end + + def package + @applet_script.package + end + + def setImmutability(immutabilityType) + @applet_script.applet.setImmutability(immutabilityType) + end + + def immutability=(immutabilityType) + setImmutability(immutabilityType) + end + + def destroy + @applet_script.applet.destroy + end + + def raise + @applet_script.applet.raise + end + + def lower + @applet_script.applet.lower + end + + def flushPendingConstraintsEvents + @applet_script.applet.flushPendingConstraintsEvents + end + end + + class Containment < Applet + def initialize(parent, args = nil) + super(parent, args) + end + end + + class PopupApplet < Applet + def initialize(parent, args = nil) + super(parent, args) + end + end +end + +module PlasmaScriptengineRuby + class Applet < Plasma::AppletScript + def initialize(parent, args) + super(parent) + end + + def camelize(str) + str.gsub(/(^|[._-])(.)/) { $2.upcase } + end + + def init + oldSize = applet.size + + puts "RubyAppletScript::Applet#init mainScript: #{mainScript}" + program = Qt::FileInfo.new(mainScript) + $: << program.path + load Qt::File.encodeName(program.filePath).to_s + moduleName = camelize(Qt::Dir.new(package.path).dirName) + className = camelize(program.baseName) + puts "RubyAppletScript::Applet#init instantiating: #{moduleName}::#{className}" + klass = Object.const_get(moduleName.to_sym).const_get(className.to_sym) + @applet_script = klass.new(self) + @applet_script.init + if oldSize.height > 10 && oldSize.width > 10 + applet.resize(oldSize) + end + + set_up_event_handlers + return true + end + + def configChanged + @applet_script.configChanged + end + + def paintInterface(painter, option, contentsRect) + @applet_script.paintInterface(painter, option, contentsRect) + end + + def constraintsEvent(constraints) + @applet_script.constraintsEvent(constraints) + end + + def contextualActions + @applet_script.contextualActions + end + + def showConfigurationInterface + dialog = standardConfigurationDialog() + @applet_script.createConfigurationInterface(dialog) + addStandardConfigurationPages(dialog) + dialog.show + end + + protected + + def eventFilter(obj, event) + handler = @event_handlers[event.type.to_i] + if handler + @applet_script.send(handler, event) + return true + else + return false + end + end + + private + + def set_up_event_handlers + @event_handlers = {} + + if @applet_script.respond_to?(:mousePressEvent) + @event_handlers[Qt::Event::GraphicsSceneMousePress.to_i] = :mousePressEvent + end + + if @applet_script.respond_to?(:contextMenuEvent) + @event_handlers[Qt::Event::GraphicsSceneContextMenu.to_i] = :contextMenuEvent + end + + if @applet_script.respond_to?(:dragEnterEvent) + @event_handlers[Qt::Event::GraphicsSceneDragEnter.to_i] = :dragEnterEvent + end + + if @applet_script.respond_to?(:dragLeaveEvent) + @event_handlers[Qt::Event::GraphicsSceneDragLeave.to_i] = :dragLeaveEvent + end + + if @applet_script.respond_to?(:dragMoveEvent) + @event_handlers[Qt::Event::GraphicsSceneDragMove.to_i] = :dragMoveEvent + end + + if @applet_script.respond_to?(:dropEvent) + @event_handlers[Qt::Event::GraphicsSceneDrop.to_i] = :dropEvent + end + + if @applet_script.respond_to?(:focusInEvent) + @event_handlers[Qt::Event::FocusIn.to_i] = :focusInEvent + end + + if @applet_script.respond_to?(:focusOutEvent) + @event_handlers[Qt::Event::FocusOut.to_i] = :focusOutEvent + end + + if @applet_script.respond_to?(:hoverEnterEvent) + @event_handlers[Qt::Event::GraphicsSceneHoverEnter.to_i] = :hoverEnterEvent + end + + if @applet_script.respond_to?(:hoverLeaveEvent) + @event_handlers[Qt::Event::GraphicsSceneHoverLeave.to_i] = :hoverLeaveEvent + end + + if @applet_script.respond_to?(:hoverMoveEvent) + @event_handlers[Qt::Event::GraphicsSceneHoverMove.to_i] = :hoverMoveEvent + end + + if @applet_script.respond_to?(:inputMethodEvent) + @event_handlers[Qt::Event::InputMethod.to_i] = :inputMethodEvent + end + + if @applet_script.respond_to?(:keyPressEvent) + @event_handlers[Qt::Event::KeyPress.to_i] = :keyPressEvent + end + + if @applet_script.respond_to?(:keyReleaseEvent) + @event_handlers[Qt::Event::KeyRelease.to_i] = :keyReleaseEvent + end + + if @applet_script.respond_to?(:mouseDoubleClickEvent) + @event_handlers[Qt::Event::GraphicsSceneMouseDoubleClick.to_i] = :mouseDoubleClickEvent + end + + if @applet_script.respond_to?(:mouseMoveEvent) + @event_handlers[Qt::Event::GraphicsSceneMouseMove.to_i] = :mouseMoveEvent + end + + if @applet_script.respond_to?(:mousePressEvent) + @event_handlers[Qt::Event::GraphicsSceneMousePress.to_i] = :mousePressEvent + end + + if @applet_script.respond_to?(:mouseReleaseEvent) + @event_handlers[Qt::Event::GraphicsSceneMouseRelease.to_i] = :mouseReleaseEvent + end + + if @applet_script.respond_to?(:wheelEvent) + @event_handlers[Qt::Event::GraphicsSceneWheel.to_i] = :wheelEvent + end + + if !@event_handlers.empty? + applet.installEventFilter(self) + end + end + + end +end + +module Plasma + # + # Because a PlasmaScript::Applet is not actually a Plasma::Applet we + # need to 'cheat' in the api, to pretend that it is. So the constructors + # in the Plasma widget classes will substitute any PlasmaScript::Applet + # argument passed for the real Plasma::Applet in the ScriptEngine + # + + class BusyWidget < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class CheckBox < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class ComboBox < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Extender < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class FlashingLabel < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Frame < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class GroupBox < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class IconWidget < Qt::Base + def initialize(*args) + sargs = [] + for i in 0...args.length do + if args[i].kind_of?(PlasmaScripting::Applet) + sargs << args[i].applet_script.applet + else + sargs << args[i] + end + end + super(*sargs) + end + end + + class ItemBackground < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Label < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class LineEdit < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Meter < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class PushButton < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class RadioButton < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class ScrollBar < Qt::Base + def initialize(orientation, parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(orientation, parent.applet_script.applet) + else + super + end + end + end + + class ScrollWidget < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Separator < Qt::Base + def initialize(parent = nil, wFlags = 0) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + end + + class SignalPlotter < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class Slider < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class SpinBox < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + + def range=(arg) + if arg.kind_of? Range + return super(arg.begin, arg.exclude_end? ? arg.end - 1 : arg.end) + else + return super(arg) + end + end + end + + class SvgWidget < Qt::Base + def initialize(*args) + if args.length > 0 && args[0].kind_of?(PlasmaScripting::Applet) + args[0] = args[0].applet_script.applet + super(*args) + elsif args.length > 2 && args[2].kind_of?(PlasmaScripting::Applet) + args[2] = args[2].applet_script.applet + super(*args) + else + super + end + end + end + + class TabBar < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class TextBrowser < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class TextEdit < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class ToolButton < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class ToolTipManager < Qt::Base + def setContent(widget, data) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet, data) + else + super + end + end + + def set_content(widget, data) + setContent(widget, data) + end + + def clearContent(widget) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet) + else + super + end + end + + def clear_content(widget) + clearContent(widget) + end + + def show(widget) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet) + else + super + end + end + + def visible?(widget) + return isVisible(widget) + end + + def isVisible(widget) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet) + else + super + end + end + + def registerWidget(widget) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet) + else + super + end + end + + def register_widget(widget) + registerWidget(widget) + end + + def unregisterWidget(widget) + if widget.kind_of?(PlasmaScripting::Applet) + super(widget.applet_script.applet) + else + super + end + end + + def unregister_widget(widget) + unregisterWidget(widget) + end + end + + class TreeView < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class VideoWidget < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + + class WebView < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + end + +end + +module Qt + class GraphicsProxyWidget < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class QAbstractGraphicsShapeItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsEllipseItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsItemGroup < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsLineItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsPathItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsPixmapItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsPolygonItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsRectItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsSimpleTextItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsSvgItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsTextItem < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsWidget < Qt::Base + def initialize(parent = nil, wFlags = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet, wFlags) + else + super + end + end + + def parent_item=(item) + setParentItem(item) + end + + def parentItem=(item) + setParentItem(item) + end + + def setParentItem(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def type(*args) + method_missing(:type, *args) + end + end + + class GraphicsGridLayout < Qt::Base + def initialize(parent = nil) + if parent.kind_of?(PlasmaScripting::Applet) + super(parent.applet_script.applet) + else + super + end + end + + def add_item(*args) + addItem(*args) + end + + def addItem(*args) + sargs = [] + for i in 0...args.length do + if args[i].kind_of?(PlasmaScripting::Applet) + sargs << args[i].applet_script.applet + else + sargs << args[i] + end + end + super(*sargs) + end + + def alignment(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def set_alignment(item, alignment) + setAlignment(item, alignment) + end + + def setAlignment(item, alignment) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet, alignment) + else + super + end + end + end + + class GraphicsLinearLayout < Qt::Base + def initialize(*args) + sargs = [] + for i in 0...args.length do + if args[i].kind_of?(PlasmaScripting::Applet) + sargs << args[i].applet_script.applet + else + sargs << args[i] + end + end + super(*sargs) + end + + def add_item(*args) + addItem(*args) + end + + def addItem(*args) + sargs = [] + for i in 0...args.length do + if args[i].kind_of?(PlasmaScripting::Applet) + sargs << args[i].applet_script.applet + else + sargs << args[i] + end + end + super(*sargs) + end + + def alignment(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + + def insert_item(index, item) + insertItem(index, item) + end + + def insertItem(index, item) + if item.kind_of?(PlasmaScripting::Applet) + super(index, item.applet_script.applet) + else + super + end + end + + def set_alignment(item, alignment) + setAlignment(item, alignment) + end + + def setAlignment(item, alignment) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet, alignment) + else + super + end + end + + def set_stretch_factor(item, stretch) + setStretchFactor(item, stretch) + end + + def setStretchFactor(item, stretch) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet, stretch) + else + super + end + end + + def stretch_factor(item) + stretchFactor(item) + end + + def stretchFactor(item) + if item.kind_of?(PlasmaScripting::Applet) + super(item.applet_script.applet) + else + super + end + end + end +end + +# kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off; diff --git a/plasma/generic/scriptengines/ruby/data_engine.rb b/plasma/generic/scriptengines/ruby/data_engine.rb new file mode 100644 index 00000000..459c9cc9 --- /dev/null +++ b/plasma/generic/scriptengines/ruby/data_engine.rb @@ -0,0 +1,147 @@ +=begin + * Copyright 2008 by Richard Dale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=end + +require 'plasma_applet' + +module PlasmaScripting + class DataEngine < Qt::Object + slots :updateAllSources, "removeSource(QString)" + signals "sourceAdded(QString)", "sourceRemoved(QString)" + + attr_accessor :data_engine_script + + def initialize(parent, args = nil) + super(parent) + @data_engine_script = parent + connect(@data_engine_script.dataEngine, SIGNAL("sourceAdded(QString)"), self, SIGNAL("sourceAdded(QString)")) + connect(@data_engine_script.dataEngine, SIGNAL("sourceRemoved(QString)"), self, SIGNAL("sourceRemoved(QString)")) + end + + def init + end + + def sourceRequestEvent(name) + end + + def updateSourceEvent(source) + end + + def setData(*args) + if args.length == 2 && !args[1].kind_of?(Qt::Variant) + args[1] = Qt::Variant.fromValue(args[1]) + elsif args.length == 3 && !args[2].kind_of?(Qt::Variant) + args[2] = Qt::Variant.fromValue(args[2]) + end + @data_engine_script.setData(*args) + end + + def removeAllData(source) + @data_engine_script.removeAllData(source) + end + + def removeData(source, key) + @data_engine_script.removeData(source, key) + end + + def setMaxSourceCount(limit) + @data_engine_script.setMaxSourceCount(limit) + end + + def maxSourceCount=(limit) + setMaxSourceCount(limit) + end + + def setMinimumPollingInterval(minimumMs) + @data_engine_script.setMinimumPollingInterval(minimumMs) + end + + def minimumPollingInterval=(minimumMs) + setMinimumPollingInterval(minimumMs) + end + + def minimumPollingInterval + @data_engine_script.minimumPollingInterval + end + + def setPollingInterval(frequency) + @data_engine_script.setPollingInterval(frequency) + end + + def pollingInterval=(frequency) + setPollingInterval(frequency) + end + + def removeAllSources + @data_engine_script.removeAllSources + end + + def sources + return [] + end + + def removeSource(source) + @data_engine_script.dataEngine.removeSource(source) + end + + def updateAllSources + @data_engine_script.dataEngine.updateAllSources + end + end +end + +module PlasmaScriptengineRuby + class DataEngine < Plasma::DataEngineScript + def initialize(parent, args) + super(parent) + end + + def camelize(str) + str.gsub(/(^|[._-])(.)/) { $2.upcase } + end + + def init + puts "RubyAppletScript::DataEngine#init mainScript: #{mainScript}" + program = Qt::FileInfo.new(mainScript) + $: << program.path + load Qt::File.encodeName(program.filePath).to_s + moduleName = camelize(Qt::Dir.new(package.path).dirName) + className = camelize(program.baseName) + puts "RubyAppletScript::DataEngine#init instantiating: #{moduleName}::#{className}" + klass = Object.const_get(moduleName.to_sym).const_get(className.to_sym) + @data_engine_script = klass.new(self) + @data_engine_script.init + return true + end + + def sources + @data_engine_script.sources + end + + def sourceRequestEvent(name) + @data_engine_script.sourceRequestEvent(name) + end + + def updateSourceEvent(source) + @data_engine_script.updateSourceEvent(source) + end + end +end + +# kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off; + diff --git a/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-applet.desktop b/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-applet.desktop new file mode 100644 index 00000000..e3cd95a0 --- /dev/null +++ b/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-applet.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +Name=Ruby Widget +Name[ar]=ودجة روبي +Name[ast]=Elementu gráficu en Ruby +Name[be@latin]=Widžet u movie „Ruby” +Name[bg]=Джаджа на Ruby +Name[bn]=রুবি উইজেট +Name[bn_IN]=Ruby উইজেট +Name[bs]=Ruby grafička kontrola +Name[ca]=Estri Ruby +Name[ca@valencia]=Estri Ruby +Name[cs]=Ruby widget +Name[csb]=Interfejs Ruby +Name[da]=Ruby-widget +Name[de]=Ruby-Miniprogramm +Name[el]=Συστατικό Ruby +Name[en_GB]=Ruby Widget +Name[eo]=Ruby-fenestraĵo +Name[es]=Elemento gráfico en Ruby +Name[et]=Ruby vidin +Name[eu]=Ruby trepeta +Name[fi]=Ruby-sovelma +Name[fr]=Composant graphique Ruby +Name[fy]=Ruby widget +Name[ga]=Giuirléid Ruby +Name[gl]=Widget escrito en Ruby +Name[gu]=રૂબી વિજેટ +Name[he]=ווידג׳ט של Ruby +Name[hi]=रूबी विज़ेट +Name[hne]=रूबी विजेट +Name[hr]=Ruby widget +Name[hu]=Ruby-elem +Name[ia]=Elemento graphic (Widget) de Ruby +Name[id]=Widget Ruby +Name[is]=Ruby græja +Name[ja]=Ruby ウィジェット +Name[kk]=Ruby бөлшегі +Name[km]=ធាតុក្រាហ្វិក​ +Name[kn]=ರೂಬಿ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Name[ko]=루비 위젯 +Name[ku]=Alava Ruby +Name[lt]=Ruby valdiklis +Name[lv]=Ruby sīkrīks +Name[ml]=റൂബി ഉരുപ്പടി +Name[mr]=Ruby विजेट +Name[nb]=Ruby-element +Name[nds]=Ruby-Lüttprogramm +Name[nl]=Ruby-widget +Name[nn]=Ruby-element +Name[or]=ରୁବି ୱିଜେଟ +Name[pa]=ਰੂਬੀ ਵਿਦਜੈੱਟ +Name[pl]=Element interfejsu w języku Ruby +Name[pt]=Elemento em Ruby +Name[pt_BR]=Widget Ruby +Name[ro]=Control Ruby +Name[ru]=Виджет на языке Ruby +Name[si]=Ruby මෙවලම් +Name[sk]=Ruby widget +Name[sl]=Gradnik v Ruby +Name[sr]=рубијевски виџет +Name[sr@ijekavian]=рубијевски виџет +Name[sr@ijekavianlatin]=ruby vidžet +Name[sr@latin]=ruby vidžet +Name[sv]=Grafisk Ruby-komponent +Name[ta]=Ruby Widget +Name[tg]=Илова ба Ruby +Name[th]=วิดเจ็ตภาษารูบี้ +Name[tr]=Ruby Gereci +Name[ug]=Ruby ۋىجېتى +Name[uk]=Віджет Ruby +Name[wa]=Ahesse Ruby +Name[x-test]=xxRuby Widgetxx +Name[zh_CN]=Ruby 部件 +Name[zh_TW]=Ruby 元件 +Comment=Native Plasma widget written in Ruby +Comment[ar]=وجة بلازما أصلية مكتوبة بروبي +Comment[ast]=Elementu gráficu nativu de Plasma escrito en Ruby +Comment[be@latin]=Rodny widžet systemy „Plasma”, napisany ŭ movie „Ruby” +Comment[bg]=Оригинална джаджа за Plasma, написана на Ruby +Comment[bs]=Samosvojni plazma grafička kontrola napisana u Ruby-ju +Comment[ca]=Estri nadiu del Plasma escrit en Ruby +Comment[ca@valencia]=Estri nadiu del Plasma escrit en Ruby +Comment[cs]=Nativní plasmoid napsaný v Ruby +Comment[da]=Ægte Plasma-widget skrevet i Ruby +Comment[de]=Echtes Plasma-Programm, geschrieben in Ruby +Comment[el]=Εγγενές συστατικό Plasma γραμμένο σε Ruby +Comment[en_GB]=Native Plasma widget written in Ruby +Comment[es]=Elemento gráfico nativo de Plasma escrito en Ruby +Comment[et]=Rubys kirjutatud Plasma vidin +Comment[eu]=Jatorrizko Plasma trepeta, Ruby lengoaian idatzia +Comment[fi]=Natiivi, Ruby-pohjainen Plasma-sovelma +Comment[fr]=Composant graphique natif de Plasma écrit en Ruby +Comment[fy]=Plasma widget skreaun yn Ruby +Comment[ga]=Giuirléid dhúchasach Plasma scríofa i Ruby +Comment[gl]=Widget nativo de Plasma escrito en Ruby +Comment[gu]=રૂબીમાં લખાયેલ મૂળભૂત પ્લાઝમા વિજેટ +Comment[he]=ווידג׳ט Plasma הנכתב ב־Ruby +Comment[hi]=रूबी में लिखा गया नेटिव प्लाज्मा विजेट +Comment[hne]=रुबी मं लिखे नेटिव प्लाज्मा विजेट +Comment[hr]=Izvorna Plasma widget napisana u Rubyu +Comment[hu]=Plasma-elem Ruby nyelven +Comment[ia]=Elemento graphic (widget) native de Plasma scribite in Ruby +Comment[id]=Widget Plasma asli yang ditulis dalam Ruby +Comment[is]=Upprunabundin Plasma græja skrifuð í Ruby +Comment[ja]=Ruby で書かれた Plasma のネイティブウィジェット +Comment[kk]=Ruby-дег жазылған Plasma интерфейс бөлшегі +Comment[km]=ធាតុក្រាហ្វិក​ប្លាស្មា​ដើម​បាន​សរសេរ​នៅ​ក្នុង Ruby +Comment[kn]=ರೂಬಿಯಲ್ಲಿ ಬರೆಯಲಾದ ಸ್ಥಳೀಯ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=루비로 작성된 Plasma 위젯 +Comment[lt]=Nuosavas Plasma valdiklis parašytas Ruby kalba +Comment[lv]=Plasma sīkrīks, rakstīts Ruby +Comment[ml]=റൂബിയില്‍ തയ്യാറാക്കിയിരിക്കുന്ന നേറ്റീവ് പ്ലാസ്മാ ഉരുപ്പടി +Comment[mr]=Ruby अंतर्गत लिहीले गेलेले मूळ Plasma विजेट +Comment[nb]=Plasmaelement for dette systemet, skrevet i Ruby +Comment[nds]=En orginaal Plasma-Lüttprogramm, schreven in Ruby +Comment[nl]=Plasma-widget geschreven in Ruby +Comment[nn]=Lokalt Plasma-element skrive i Ruby +Comment[or]=Ruby ରେ ଲେଖା ହୋଇଥିବା ସ୍ଥାନୀୟ ପ୍ଲାଜମା ୱିଜେଟ +Comment[pa]=ਰੂਬੀ ਵਿੱਚ ਲਿਖੇ ਨੇਟਿਵ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu Plazmy napisany w języku Ruby +Comment[pt]=Elemento nativo do Plasma feito em Ruby +Comment[pt_BR]=Widget nativo do Plasma, escrito em Ruby +Comment[ro]=Miniaplicație Plasma scrisă în Ruby +Comment[ru]=Виджет Plasma, написанный на языке Ruby +Comment[si]=Native Plasma widget written in Ruby +Comment[sk]=Natívny plasma widget napísaný v Ruby +Comment[sl]=Lastni gradnik za Plasmo, ki je napisan v Rubyu +Comment[sr]=Самосвојни плазма виџет написан у рубију +Comment[sr@ijekavian]=Самосвојни плазма виџет написан у рубију +Comment[sr@ijekavianlatin]=Samosvojni plasma vidžet napisan u Rubyju +Comment[sr@latin]=Samosvojni plasma vidžet napisan u Rubyju +Comment[sv]=Inbyggd grafisk Plasma-komponent skriven i Ruby +Comment[ta]=Native Plasma widget written in Ruby +Comment[tg]=Модуль Plasma, написанный на языке JavaScript +Comment[th]=วิดเจ็ตพลาสมาแท้ที่ถูกเขียนด้วยภาษารูบี้ +Comment[tr]=Ruby ile yazılmış gerçek Plasma gereci +Comment[ug]=Ruby بىلەن يېزىلغان ئەسلى Plasma widget +Comment[uk]=Віджет Плазми, написаний на Ruby +Comment[wa]=Ahesse askepieye po Plasma eyet scrîte e Ruby +Comment[x-test]=xxNative Plasma widget written in Rubyxx +Comment[zh_CN]=使用 Ruby 编写的原生 Plasma 部件 +Comment[zh_TW]=用 Ruby 寫的原始 Plasma 元件 +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-KDE-Library=krubypluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_ruby/applet.rb +X-Plasma-API=ruby-script +X-Plasma-ComponentTypes=Applet diff --git a/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-dataengine.desktop b/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-dataengine.desktop new file mode 100644 index 00000000..881ab4d8 --- /dev/null +++ b/plasma/generic/scriptengines/ruby/plasma-scriptengine-ruby-dataengine.desktop @@ -0,0 +1,150 @@ +[Desktop Entry] +Name=Ruby Widget +Name[ar]=ودجة روبي +Name[ast]=Elementu gráficu en Ruby +Name[be@latin]=Widžet u movie „Ruby” +Name[bg]=Джаджа на Ruby +Name[bn]=রুবি উইজেট +Name[bn_IN]=Ruby উইজেট +Name[bs]=Ruby grafička kontrola +Name[ca]=Estri Ruby +Name[ca@valencia]=Estri Ruby +Name[cs]=Ruby widget +Name[csb]=Interfejs Ruby +Name[da]=Ruby-widget +Name[de]=Ruby-Miniprogramm +Name[el]=Συστατικό Ruby +Name[en_GB]=Ruby Widget +Name[eo]=Ruby-fenestraĵo +Name[es]=Elemento gráfico en Ruby +Name[et]=Ruby vidin +Name[eu]=Ruby trepeta +Name[fi]=Ruby-sovelma +Name[fr]=Composant graphique Ruby +Name[fy]=Ruby widget +Name[ga]=Giuirléid Ruby +Name[gl]=Widget escrito en Ruby +Name[gu]=રૂબી વિજેટ +Name[he]=ווידג׳ט של Ruby +Name[hi]=रूबी विज़ेट +Name[hne]=रूबी विजेट +Name[hr]=Ruby widget +Name[hu]=Ruby-elem +Name[ia]=Elemento graphic (Widget) de Ruby +Name[id]=Widget Ruby +Name[is]=Ruby græja +Name[ja]=Ruby ウィジェット +Name[kk]=Ruby бөлшегі +Name[km]=ធាតុក្រាហ្វិក​ +Name[kn]=ರೂಬಿ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Name[ko]=루비 위젯 +Name[ku]=Alava Ruby +Name[lt]=Ruby valdiklis +Name[lv]=Ruby sīkrīks +Name[ml]=റൂബി ഉരുപ്പടി +Name[mr]=Ruby विजेट +Name[nb]=Ruby-element +Name[nds]=Ruby-Lüttprogramm +Name[nl]=Ruby-widget +Name[nn]=Ruby-element +Name[or]=ରୁବି ୱିଜେଟ +Name[pa]=ਰੂਬੀ ਵਿਦਜੈੱਟ +Name[pl]=Element interfejsu w języku Ruby +Name[pt]=Elemento em Ruby +Name[pt_BR]=Widget Ruby +Name[ro]=Control Ruby +Name[ru]=Виджет на языке Ruby +Name[si]=Ruby මෙවලම් +Name[sk]=Ruby widget +Name[sl]=Gradnik v Ruby +Name[sr]=рубијевски виџет +Name[sr@ijekavian]=рубијевски виџет +Name[sr@ijekavianlatin]=ruby vidžet +Name[sr@latin]=ruby vidžet +Name[sv]=Grafisk Ruby-komponent +Name[ta]=Ruby Widget +Name[tg]=Илова ба Ruby +Name[th]=วิดเจ็ตภาษารูบี้ +Name[tr]=Ruby Gereci +Name[ug]=Ruby ۋىجېتى +Name[uk]=Віджет Ruby +Name[wa]=Ahesse Ruby +Name[x-test]=xxRuby Widgetxx +Name[zh_CN]=Ruby 部件 +Name[zh_TW]=Ruby 元件 +Comment=Native Plasma widget written in Ruby +Comment[ar]=وجة بلازما أصلية مكتوبة بروبي +Comment[ast]=Elementu gráficu nativu de Plasma escrito en Ruby +Comment[be@latin]=Rodny widžet systemy „Plasma”, napisany ŭ movie „Ruby” +Comment[bg]=Оригинална джаджа за Plasma, написана на Ruby +Comment[bs]=Samosvojni plazma grafička kontrola napisana u Ruby-ju +Comment[ca]=Estri nadiu del Plasma escrit en Ruby +Comment[ca@valencia]=Estri nadiu del Plasma escrit en Ruby +Comment[cs]=Nativní plasmoid napsaný v Ruby +Comment[da]=Ægte Plasma-widget skrevet i Ruby +Comment[de]=Echtes Plasma-Programm, geschrieben in Ruby +Comment[el]=Εγγενές συστατικό Plasma γραμμένο σε Ruby +Comment[en_GB]=Native Plasma widget written in Ruby +Comment[es]=Elemento gráfico nativo de Plasma escrito en Ruby +Comment[et]=Rubys kirjutatud Plasma vidin +Comment[eu]=Jatorrizko Plasma trepeta, Ruby lengoaian idatzia +Comment[fi]=Natiivi, Ruby-pohjainen Plasma-sovelma +Comment[fr]=Composant graphique natif de Plasma écrit en Ruby +Comment[fy]=Plasma widget skreaun yn Ruby +Comment[ga]=Giuirléid dhúchasach Plasma scríofa i Ruby +Comment[gl]=Widget nativo de Plasma escrito en Ruby +Comment[gu]=રૂબીમાં લખાયેલ મૂળભૂત પ્લાઝમા વિજેટ +Comment[he]=ווידג׳ט Plasma הנכתב ב־Ruby +Comment[hi]=रूबी में लिखा गया नेटिव प्लाज्मा विजेट +Comment[hne]=रुबी मं लिखे नेटिव प्लाज्मा विजेट +Comment[hr]=Izvorna Plasma widget napisana u Rubyu +Comment[hu]=Plasma-elem Ruby nyelven +Comment[ia]=Elemento graphic (widget) native de Plasma scribite in Ruby +Comment[id]=Widget Plasma asli yang ditulis dalam Ruby +Comment[is]=Upprunabundin Plasma græja skrifuð í Ruby +Comment[ja]=Ruby で書かれた Plasma のネイティブウィジェット +Comment[kk]=Ruby-дег жазылған Plasma интерфейс бөлшегі +Comment[km]=ធាតុក្រាហ្វិក​ប្លាស្មា​ដើម​បាន​សរសេរ​នៅ​ក្នុង Ruby +Comment[kn]=ರೂಬಿಯಲ್ಲಿ ಬರೆಯಲಾದ ಸ್ಥಳೀಯ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=루비로 작성된 Plasma 위젯 +Comment[lt]=Nuosavas Plasma valdiklis parašytas Ruby kalba +Comment[lv]=Plasma sīkrīks, rakstīts Ruby +Comment[ml]=റൂബിയില്‍ തയ്യാറാക്കിയിരിക്കുന്ന നേറ്റീവ് പ്ലാസ്മാ ഉരുപ്പടി +Comment[mr]=Ruby अंतर्गत लिहीले गेलेले मूळ Plasma विजेट +Comment[nb]=Plasmaelement for dette systemet, skrevet i Ruby +Comment[nds]=En orginaal Plasma-Lüttprogramm, schreven in Ruby +Comment[nl]=Plasma-widget geschreven in Ruby +Comment[nn]=Lokalt Plasma-element skrive i Ruby +Comment[or]=Ruby ରେ ଲେଖା ହୋଇଥିବା ସ୍ଥାନୀୟ ପ୍ଲାଜମା ୱିଜେଟ +Comment[pa]=ਰੂਬੀ ਵਿੱਚ ਲਿਖੇ ਨੇਟਿਵ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu Plazmy napisany w języku Ruby +Comment[pt]=Elemento nativo do Plasma feito em Ruby +Comment[pt_BR]=Widget nativo do Plasma, escrito em Ruby +Comment[ro]=Miniaplicație Plasma scrisă în Ruby +Comment[ru]=Виджет Plasma, написанный на языке Ruby +Comment[si]=Native Plasma widget written in Ruby +Comment[sk]=Natívny plasma widget napísaný v Ruby +Comment[sl]=Lastni gradnik za Plasmo, ki je napisan v Rubyu +Comment[sr]=Самосвојни плазма виџет написан у рубију +Comment[sr@ijekavian]=Самосвојни плазма виџет написан у рубију +Comment[sr@ijekavianlatin]=Samosvojni plasma vidžet napisan u Rubyju +Comment[sr@latin]=Samosvojni plasma vidžet napisan u Rubyju +Comment[sv]=Inbyggd grafisk Plasma-komponent skriven i Ruby +Comment[ta]=Native Plasma widget written in Ruby +Comment[tg]=Модуль Plasma, написанный на языке JavaScript +Comment[th]=วิดเจ็ตพลาสมาแท้ที่ถูกเขียนด้วยภาษารูบี้ +Comment[tr]=Ruby ile yazılmış gerçek Plasma gereci +Comment[ug]=Ruby بىلەن يېزىلغان ئەسلى Plasma widget +Comment[uk]=Віджет Плазми, написаний на Ruby +Comment[wa]=Ahesse askepieye po Plasma eyet scrîte e Ruby +Comment[x-test]=xxNative Plasma widget written in Rubyxx +Comment[zh_CN]=使用 Ruby 编写的原生 Plasma 部件 +Comment[zh_TW]=用 Ruby 寫的原始 Plasma 元件 +X-KDE-ServiceTypes=Plasma/ScriptEngine +Type=Service +Icon=text-x-script +X-KDE-Library=krubypluginfactory +X-KDE-PluginKeyword=plasma_scriptengine_ruby/data_engine.rb +X-EngineName=ruby-dataengine-script +X-Plasma-API=ruby-script +X-Plasma-ComponentTypes=DataEngine diff --git a/plasma/generic/scriptengines/webkit/CMakeLists.txt b/plasma/generic/scriptengines/webkit/CMakeLists.txt new file mode 100644 index 00000000..12a4a79a --- /dev/null +++ b/plasma/generic/scriptengines/webkit/CMakeLists.txt @@ -0,0 +1,33 @@ +add_subdirectory(dashboard) + +project(plasma-webapplet) + +set(webapplet_SRCS + webpage.cpp webapplet.cpp plasmawebapplet.cpp plasmajs.cpp webapplet_plugin.cpp) +kde4_add_plugin(plasma_appletscriptengine_webapplet ${webapplet_SRCS}) +target_link_libraries(plasma_appletscriptengine_webapplet ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${QT_QTWEBKIT_LIBRARY} ) +install(TARGETS plasma_appletscriptengine_webapplet DESTINATION ${PLUGIN_INSTALL_DIR}) + +set(webappletpackage_SRCS + webapplet_package.cpp) +kde4_add_plugin(plasma_packagestructure_web ${webappletpackage_SRCS}) +target_link_libraries(plasma_packagestructure_web ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${QT_QTWEBKIT_LIBRARY} ) +install(TARGETS plasma_packagestructure_web DESTINATION ${PLUGIN_INSTALL_DIR}) + +set(dashboardapplet_SRCS + webpage.cpp webapplet.cpp dashboardapplet.cpp bundle.cpp dashboardjs.cpp) +kde4_add_plugin(plasma_appletscriptengine_dashboard ${dashboardapplet_SRCS}) +target_link_libraries(plasma_appletscriptengine_dashboard ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${QT_QTWEBKIT_LIBRARY} ) +install(TARGETS plasma_appletscriptengine_dashboard DESTINATION ${PLUGIN_INSTALL_DIR}) + +set(bundlepackage_SRCS + bundle.cpp dashboard_plugin.cpp) +kde4_add_plugin(plasma_packagestructure_dashboard ${bundlepackage_SRCS}) +target_link_libraries(plasma_packagestructure_dashboard ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${QT_QTWEBKIT_LIBRARY} ) +install(TARGETS plasma_packagestructure_dashboard DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-scriptengine-applet-web.desktop + plasma-scriptengine-applet-dashboard.desktop + plasma-packagestructure-dashboard.desktop + plasma-packagestructure-web.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/scriptengines/webkit/Messages.sh b/plasma/generic/scriptengines/webkit/Messages.sh new file mode 100755 index 00000000..f6730e1f --- /dev/null +++ b/plasma/generic/scriptengines/webkit/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_appletscriptengine_dashboard.pot diff --git a/plasma/generic/scriptengines/webkit/README b/plasma/generic/scriptengines/webkit/README new file mode 100644 index 00000000..ff8717bc --- /dev/null +++ b/plasma/generic/scriptengines/webkit/README @@ -0,0 +1,2 @@ +Document about dashboard stuff +http://developer.apple.com/documentation/AppleApplications/Conceptual/Dashboard_ProgTopics/Dashboard_ProgTopics.pdf diff --git a/plasma/generic/scriptengines/webkit/bundle.cpp b/plasma/generic/scriptengines/webkit/bundle.cpp new file mode 100644 index 00000000..8d9c73fe --- /dev/null +++ b/plasma/generic/scriptengines/webkit/bundle.cpp @@ -0,0 +1,430 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#include "bundle.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +void recursive_print(const KArchiveDirectory *dir, const QString &path) +{ + const QStringList l = dir->entries(); + QStringList::const_iterator it = l.constBegin(); + for (; it != l.end(); ++it) + { + const KArchiveEntry* entry = dir->entry((*it)); + printf("mode=%07o %s %s size: %lld pos: %lld %s%s isdir=%d%s", + entry->permissions(), + entry->user().toLatin1().constData(), + entry->group().toLatin1().constData(), + entry->isDirectory() ? 0 : ((KArchiveFile*)entry)->size(), + entry->isDirectory() ? 0 : ((KArchiveFile*)entry)->position(), + path.toLatin1().constData(), + (*it).toLatin1().constData(), entry->isDirectory(), + entry->symLinkTarget().isEmpty() ? "" : + QString(" symlink: %1").arg( + entry->symLinkTarget()).toLatin1().constData()); + + //if (!entry->isDirectory()) printf("%d", + // ((KArchiveFile*)entry)->size()); + printf("\n"); + if (entry->isDirectory()) + recursive_print((KArchiveDirectory *)entry, path+(*it)+'/'); + } +} + + +static const KArchiveDirectory *recursiveFind(const KArchiveDirectory *dir) +{ + const QStringList l = dir->entries(); + QStringList::const_iterator it; + for (it = l.constBegin(); it != l.constEnd(); ++it) { + const KArchiveEntry* entry = dir->entry((*it)); + if (entry->isDirectory()) { + QString name = *it; + if (name.startsWith(QLatin1String("__MACOSX"))) { + //skip this + continue; + } else if (name.endsWith(QLatin1String(".wdgt"))) { + //got our bad boy + return static_cast(entry); + } else { + const KArchiveDirectory *fd = + recursiveFind(static_cast(entry)); + if (fd) + return fd; + } + } + } + return 0; +} + +Bundle::Bundle(const QString &path) + : PackageStructure(0, "MacDashboard"), + m_isValid(false), + m_width(0), m_height(0) +{ + setContentsPrefix(QString()); + QFile f(path); + f.open(QIODevice::ReadOnly); + m_data = f.readAll(); + f.close(); + initTempDir(); + open(); +} + +Bundle::Bundle(const QByteArray &data) + : PackageStructure(0, "MacDashboard"), + m_isValid(false), + m_width(0), + m_height(0) +{ + setContentsPrefix(QString()); + m_data = data; + initTempDir(); + open(); +} + +Bundle::Bundle(QObject *parent, QVariantList args) + : PackageStructure(parent, "MacDashboard"), + m_isValid(false), + m_tempDir(0), + m_width(0), + m_height(0) +{ + Q_UNUSED(args) + setContentsPrefix(QString()); +} + +Bundle::~Bundle() +{ + close(); +} + +void Bundle::setData(const QByteArray &data) +{ + m_data = data; + close(); + open(); +} + +QByteArray Bundle::data() const +{ + return m_data; +} + +bool Bundle::open() +{ + if (!m_tempDir) { + initTempDir(); + } + + if (m_data.isEmpty()) { + return false; + } + + QBuffer buffer(&m_data); + KZip zip(&buffer); + if (!zip.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open the bundle!"); + return false; + } + + const KArchiveDirectory *dir = zip.directory(); + + const KArchiveDirectory *foundDir = recursiveFind(dir); + if (!foundDir) { + qWarning("not a bundle"); + m_isValid = false; + zip.close(); + return 0; + } + + m_isValid = extractArchive(foundDir, QLatin1String("")); + qDebug()<<"Dir = "<name() << m_isValid; + + if (m_isValid) { + setPath(m_tempDir->name()); + } + + zip.close(); + + return m_isValid; +} + +bool Bundle::close() +{ + bool ret = m_tempDir; + delete m_tempDir; + m_tempDir = 0; + return ret; +} + +bool Bundle::extractArchive(const KArchiveDirectory *dir, const QString &path) +{ + const QStringList l = dir->entries(); + + QStringList::const_iterator it; + for (it = l.constBegin(); it != l.constEnd(); ++it) { + const KArchiveEntry* entry = dir->entry((*it)); + QString fullPath = QString("%1/%2").arg(path).arg(*it); + if (entry->isDirectory()) { + QString outDir = QString("%1%2").arg(m_tempDir->name()).arg(path); + QDir qdir(outDir); + qdir.mkdir(*it); + extractArchive(static_cast(entry), fullPath); + } else if (entry->isFile()) { + QString outName = QString("%1%2").arg(m_tempDir->name()).arg(fullPath.remove(0, 1)); + //qDebug()<<"-------- "<(entry); + f.write(archiveFile->data()); + f.close(); + } else { + qWarning("Unidentified entry at %s", qPrintable(fullPath)); + } + } + return true; +} + +void Bundle::pathChanged() +{ + //qDebug() << "path changed"; + m_isValid = extractInfo(); +} + +bool Bundle::extractInfo() +{ + QString plistLocation = QString("%1Info.plist").arg(path()); + QString configXml = QString("%1config.xml").arg(path()); + if (QFile::exists(plistLocation)) { + //qDebug() << "doing plist"; + return parsePlist(plistLocation); + } else if (QFile::exists(configXml)) { + return parseConfigXml(configXml); + } + + return false; +} + +bool Bundle::parsePlist(const QString &loc) +{ + QFile f(loc); + if (!f.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open info file: '%s'", qPrintable(loc)); + return false; + } + + QMap infoMap; + QString str = f.readAll(); + QXmlStreamReader reader(str); + while (!reader.atEnd()) { + reader.readNext(); + // do processing + if (reader.isStartElement()) { + //qDebug() << reader.name().toString(); + if (reader.name() == "key") { + QString key, value; + reader.readNext(); + if (reader.isCharacters()) { + QString str = reader.text().toString(); + str = str.trimmed(); + if (!str.isEmpty()) + key = str; + } + if (key.isEmpty()) + continue; + while (!reader.isStartElement()) + reader.readNext(); + if (reader.name() != "string" && + reader.name() != "integer") { + qDebug()<<"Unrecognized val "<setAutoRemove(false); + QString pluginName = "dashboard_" + m_bundleId; + //kDebug() << "valid, so going to move it in to" << pluginName; + KIO::CopyJob* job = KIO::move(m_tempDir->name(), QString(packageRoot + pluginName), KIO::HideProgressInfo); + m_isValid = job->exec(); + + if (m_isValid) { + //kDebug() << "still so good ... registering"; + Plasma::PackageMetadata data; + data.setName(m_name); + data.setDescription(m_description); + data.setPluginName(pluginName); + data.setImplementationApi("dashboard"); + Plasma::Package::registerPackage(data, m_iconLocation); + } + } + + if (!m_isValid) { + // make sure we clean up after ourselves afterwards on failure + m_tempDir->setAutoRemove(true); + } + + return m_isValid; +} + +bool Bundle::parseConfigXml(const QString &loc) +{ + QFile f(loc); + if (!f.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open info file: '%s'", qPrintable(loc)); + return false; + } + + qWarning("FIXME: Widgets 1.0 not implemented"); + + return false; +} + +void Bundle::initTempDir() +{ + m_tempDir = new KTempDir(); + //make it explicit + m_tempDir->setAutoRemove(true); +} + +QString Bundle::bundleId() const +{ + return m_bundleId; +} + +QString Bundle::name() const +{ + return m_name; +} + +QString Bundle::version() const +{ + return m_version; +} + +QString Bundle::description() const +{ + return m_description; +} + +int Bundle::width() const +{ + return m_width; +} + +int Bundle::height() const +{ + return m_height; +} + +QString Bundle::htmlLocation() const +{ + return m_htmlLocation; +} + +QString Bundle::iconLocation() const +{ + return m_iconLocation; +} + +bool Bundle::isValid() const +{ + return m_isValid; +} + + diff --git a/plasma/generic/scriptengines/webkit/bundle.h b/plasma/generic/scriptengines/webkit/bundle.h new file mode 100644 index 00000000..e312dace --- /dev/null +++ b/plasma/generic/scriptengines/webkit/bundle.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#ifndef BUNDLE_H +#define BUNDLE_H + +#include +#include + +#include + +class KArchiveDirectory; + +class Bundle : public Plasma::PackageStructure +{ + Q_OBJECT +public: + Bundle(const QString &path); + Bundle(const QByteArray &data); + Bundle(QObject *parent, QVariantList args); + ~Bundle(); + + bool isValid() const; + + void setData(const QByteArray &fn); + QByteArray data() const; + + QString bundleId() const; + QString name() const; + QString version() const; + QString description() const; + int width() const; + int height() const; + QString htmlLocation() const; + QString iconLocation() const; + +protected: + void pathChanged(); + +private: + bool extractArchive(const KArchiveDirectory *dir, const QString &path); + bool extractInfo(); + + bool parsePlist(const QString &loc); + bool parseConfigXml(const QString &loc); + + void initTempDir(); + + bool open(); + bool close(); + bool installPackage(const QString &archivePath, const QString &packageRoot); + +private: + QByteArray m_data; + bool m_isValid; + KTempDir *m_tempDir; + + QString m_bundleId; + QString m_name; + QString m_version; + QString m_description; + int m_width; + int m_height; + QString m_htmlLocation; + QString m_iconLocation; +}; + +#endif diff --git a/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleAnimator.js b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleAnimator.js new file mode 100644 index 00000000..93b51297 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleAnimator.js @@ -0,0 +1,142 @@ +/* + * Copyright 2008 Stefan Buller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +function AppleAnimator(duration, interval, start, finish, handler) +{ + //properties specified by Apple + this.duration = duration; + this.interval = interval; + this.animations = []; + this.timer = 0; + this.oncomplete; //no documentation exists for this. + + //internal members: + this.intervalPointer = undefined; + + var that = this; + + if (arguments.length === 5) { + var animation = new AppleAnimation(start, finish, handler); + that.addAnimation(animation); //I hope I can use this already + } +}; + +AppleAnimator.prototype.addAnimation = function (animation) { + //I'm unsure what the behaviour of this function should be if + //AppleAnimator.start() has already been called. + animation.initialize(this.duration, this.interval); + this.animations.push(animation); +}; + +AppleAnimator.prototype.start = function () +{ + if (this.intervalPointer == undefined) { + + var that = this; //for the closure (may not be necessary?) + function intervalHandler() { + //setInterval doesn't pass 'this', so we need a closure instead. + that.timer += that.interval; + if (that.timer > that.duration) { + that.stop(); + } else { + for (var i=0; i + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +function AppleScrollArea(content) { + for (var i = 0; i < arguments.length; i++) { + this.addScrollbar(arguments[i]); + } + var that=this; + var handler=function(e) { + switch(e.which) { + case 37: //left + that.horizontalScrollTo(that.content.scrollLeft - + that.singlepressScrollPixels); + break; + case 38: //up + that.verticalScrollTo(that.content.scrollTop - + that.singlepressScrollPixels); + break; + case 39: //right + that.horizontalScrollTo(that.content.scrollLeft + + that.singlepressScrollPixels); + break; + case 40: //down + that.verticalScrollTo(that.content.scrollTop + + that.singlepressScrollPixels); + break; + default: + //the event may contiue to propagate + return true; + } + //arrest propagation + return false; + } + content.addEventListener('keydown',handler,false); + + //Apple mandated properties that must be reacted to. + this.scrollsVertically = false; + this.scrollsHorizontally = false; + this.singlepressScrollPixels = 10; //Somebody change this. Please. + + //Apple mandated properties that are `read only'. + this.viewHeight = content.clientHeight; + this.viewToContentHeightRatio = content.clientHeight / content.scrollHeight; + this.viewWidth = content.clientWidth; + this.viewToContentWidthRatio = content.clientWidth / content.scrollWidth; + //I'm worried that the scrollHeight/Width could change on me. If that turns + //out to be a problem, then getters would be the way to go. + + //extras + this.scrollbars = []; + this.content = content; +} + +AppleScrollArea.prototype.addScrollbar = function(scrollbar) { + this.scrollbars.push(scrollbar); + scrollbar.setScrollArea(this); +} + +AppleScrollArea.prototype.removeScrollbar = function(scrollbar) { + this.scrollbars.filter(function(element){return (element === scrollbar);}); + scrollbar.setScrollArea(null); //Just a guess. This might not be right. +} + +AppleScrollArea.prototype.remove = function() { + //Remove the div, or remove the effects of AppleScrollArea? + //Perhaps this can all be replaced with a simple removeChild() + content.scrollTop = 0; + content.scrollLeft = 0; + for (var i = 0; i < this.scrollbars.length; i++) { + this.scrollbars[i].remove(); + delete this.scrollbars[i]; + } + delete this; +} + +AppleScrollArea.prototype.reveal = function(element) { + //First we find it + var distX = 0; + var distY = 0; + var el = element; + while (el !== this.content) { + distX += (+el.offsetTop); + distY += (+el.offsetLeft); + el = el.parentNode; + if (el == null) { + throw "Target element not in ScrollArea."; + } + } + + this.verticalScrollTo(distY); + this.horizontalScrollTo(distX); +} + +AppleScrollArea.prototype.focus = function() { + this.content.focus(); +} + +AppleScrollArea.prototype.blur = function() { + this.content.blur(); +} + +AppleScrollArea.prototype.verticalScrollTo = function(position) { + this.scrollTop = position; +} + +AppleScrollArea.prototype.horizontalScrollTo = function(position) { + this.scrollLeft = position; +} + + diff --git a/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleScrollbar.js b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleScrollbar.js new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleScrollbar.js @@ -0,0 +1 @@ + diff --git a/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleSlider.js b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleSlider.js new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/AppleSlider.js @@ -0,0 +1 @@ + diff --git a/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/CMakeLists.txt b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/CMakeLists.txt new file mode 100644 index 00000000..b9a2b4c7 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/AppleClasses/CMakeLists.txt @@ -0,0 +1,7 @@ +install(FILES AppleButton.js + AppleInfoButton.js + AppleAnimator.js + AppleScrollArea.js + AppleScrollbar.js + AppleSlider.js + DESTINATION ${DATA_INSTALL_DIR}/plasma/dashboard/AppleClasses/) diff --git a/plasma/generic/scriptengines/webkit/dashboard/CMakeLists.txt b/plasma/generic/scriptengines/webkit/dashboard/CMakeLists.txt new file mode 100644 index 00000000..9477cb9d --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(button) +add_subdirectory(AppleClasses) \ No newline at end of file diff --git a/plasma/generic/scriptengines/webkit/dashboard/button/CMakeLists.txt b/plasma/generic/scriptengines/webkit/dashboard/button/CMakeLists.txt new file mode 100644 index 00000000..afa0eb40 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/button/CMakeLists.txt @@ -0,0 +1,2 @@ +install(FILES genericButton.js + DESTINATION ${DATA_INSTALL_DIR}/plasma/dashboard/button) diff --git a/plasma/generic/scriptengines/webkit/dashboard/button/genericButton.js b/plasma/generic/scriptengines/webkit/dashboard/button/genericButton.js new file mode 100644 index 00000000..464eda40 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard/button/genericButton.js @@ -0,0 +1,8 @@ + + +function createGenericButton(placeElement,buttonText,clickHandler) { + var b = document.createElement("button"); + b.appendChild(document.createTextNode(buttonText)); + b.onclick = clickHandler; + placeElement.appendChild(b); +} \ No newline at end of file diff --git a/plasma/generic/scriptengines/webkit/dashboard_plugin.cpp b/plasma/generic/scriptengines/webkit/dashboard_plugin.cpp new file mode 100644 index 00000000..f7a421f7 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboard_plugin.cpp @@ -0,0 +1,25 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "bundle.h" + +K_EXPORT_PLASMA_PACKAGESTRUCTURE(dashboard, Bundle) + diff --git a/plasma/generic/scriptengines/webkit/dashboardapplet.cpp b/plasma/generic/scriptengines/webkit/dashboardapplet.cpp new file mode 100644 index 00000000..0da78188 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboardapplet.cpp @@ -0,0 +1,94 @@ +/* +Copyright (c) 2007 Zack Rusin +Copyright (c) 2008 Beat Wolf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "dashboardapplet.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "dashboardjs.h" + +DashboardApplet::DashboardApplet(QObject *parent, const QVariantList &args) + : WebApplet(parent, args) +{ +} + +DashboardApplet::~DashboardApplet() +{ +} + +bool DashboardApplet::init() +{ + applet()->setAspectRatioMode(Plasma::FixedSize); + return WebApplet::init(); +} + +void DashboardApplet::loadFinished(bool success) +{ + WebApplet::loadFinished(success); + if (success) { + view()->resize(view()->mainFrame()->contentsSize()); + applet()->resize(view()->mainFrame()->contentsSize()); + } +} + +void DashboardApplet::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::FormFactorConstraint) { + applet()->setBackgroundHints(Plasma::Applet::NoBackground); + } +} + +void DashboardApplet::initJsObjects() +{ + QWebFrame *frame = qobject_cast(sender()); + Q_ASSERT(frame); + frame->addToJavaScriptWindowObject(QLatin1String("applet"), this); + frame->addToJavaScriptWindowObject(QLatin1String("widget"), new DashboardJs(frame, this, applet())); +} + +QByteArray DashboardApplet::dataFor(const QString &str) +{ + QFile f(str); + f.open(QIODevice::ReadOnly); + QByteArray data = f.readAll(); + f.close(); + + //replace the apple javascript imports with the kde ones + QString jsBaseDir = KGlobal::dirs()->findResourceDir("data","plasma/dashboard/button/genericButton.js") + + "plasma/dashboard"; + + data.replace("file:///System/Library/WidgetResources", jsBaseDir.toUtf8()); + data.replace("/System/Library/WidgetResources", jsBaseDir.toUtf8()); + + return data; +} + +#include "dashboardapplet.moc" diff --git a/plasma/generic/scriptengines/webkit/dashboardapplet.h b/plasma/generic/scriptengines/webkit/dashboardapplet.h new file mode 100644 index 00000000..193be084 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboardapplet.h @@ -0,0 +1,54 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#ifndef SAMPLEITEM_H +#define SAMPLEITEM_H + +#include "webapplet.h" +#include "bundle.h" + +#include "dashboardjs.h" + +#include + +#include + +class DashboardApplet : public WebApplet +{ + Q_OBJECT +public: + DashboardApplet(QObject *parent, const QVariantList &args); + ~DashboardApplet(); + + bool init(); + +protected: + virtual QByteArray dataFor(const QString &str); + +protected slots: + virtual void loadFinished(bool success); + virtual void initJsObjects(); + virtual void constraintsEvent(Plasma::Constraints constraints); +}; + +K_EXPORT_PLASMA_APPLETSCRIPTENGINE(dashboard, DashboardApplet) + +#endif diff --git a/plasma/generic/scriptengines/webkit/dashboardjs.cpp b/plasma/generic/scriptengines/webkit/dashboardjs.cpp new file mode 100644 index 00000000..d41252e8 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboardjs.cpp @@ -0,0 +1,179 @@ +/* +Copyright (c) 2008 Beat Wolf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "dashboardjs.h" +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +DashboardJs::DashboardJs(QWebFrame *frame, QObject *parent, Plasma::Applet *applet) + : QObject(parent) +{ + m_applet = applet; + m_frame = frame; +} + +DashboardJs::~DashboardJs() +{ + if(m_frame){ + kDebug() << "deconstructor calles javascript: " << m_onremove; + m_frame->evaluateJavaScript(m_onremove); + } +} + +void DashboardJs::openApplication(QString name) +{ + //STUB + kDebug() << "not implemented: open application" << name; + + //WARNING: this might be dangerous and exploited (or not) + /* create list of applications: + * com.apple.ical + * com.RealNetworks.RealPlayer + */ +} + +void DashboardJs::openURL(QString name) +{ + //TODO: this could be dangerous(really?). filter valid urls + new KRun(name, 0); +} + +QVariant DashboardJs::preferenceForKey(QString key) +{ + KConfigGroup conf = m_applet->config(); + + if (!conf.hasKey(key)) { + return QVariant(); + } + + return conf.readEntry(key,""); +} + +void DashboardJs::prepareForTransition(QString transition) +{ + //STUB + kDebug() << "not implemented: transition with name" << transition; + //TODO:freeze widget drawing. possible? + //not really needed for things to work, but would be prettier +} + +void DashboardJs::performTransition() +{ + //STUB + //TODO: enable widget drawing again, perform nice animation. + kDebug() << "not implemented: perform transition"; + //not really needed for things to work, but would be prettier +} + +void DashboardJs::setCloseBoxOffset(int x, int y) +{ + //STUB, not needed, plasma has its own close box + kDebug() << "not implemented: close box offset" << x << y; +} + +void DashboardJs::setPreferenceForKey(QString value, QString key) +{ + kDebug() << "save key" << key << value; + KConfigGroup conf = m_applet->config(); + conf.writeEntry(key, value); +} + +void DashboardJs::system(QString command, QString handler) +{ + //WARNING: this might be dangerous and exploited. + //STUB + kDebug() << "not implemented: system command:" << command << handler; +} + +//Property sets and gets +QString DashboardJs::identifier() const +{ + return QString::number(m_applet->id()); +} + +QString DashboardJs::onshow() const +{ + return m_onshow; +} + +void DashboardJs::setOnshow(const QString &value) +{ + m_onshow = value; +} + +QString DashboardJs::onhide() const +{ + return m_onhide; +} + +void DashboardJs::setOnhide(const QString &value) +{ + m_onhide = value; +} + +QString DashboardJs::onremove() const +{ + return m_onremove; +} + +void DashboardJs::setOnremove(const QString &value) +{ + m_onremove = value; +} + + +QString DashboardJs::ondragstart() const +{ + return m_ondragstart; +} + +void DashboardJs::setOndragstart(const QString &value) +{ + m_ondragstart = value; +} + +QString DashboardJs::ondragstop() const +{ + return m_ondragstop; +} + +void DashboardJs::setOndragstop(const QString &value) +{ + m_ondragstop = value; +} +//only for testing purpose +//TODO: remove when not needed anymore +void DashboardJs::hello(int test) +{ + kDebug() << "hello world" << test; +} + diff --git a/plasma/generic/scriptengines/webkit/dashboardjs.h b/plasma/generic/scriptengines/webkit/dashboardjs.h new file mode 100644 index 00000000..2376571d --- /dev/null +++ b/plasma/generic/scriptengines/webkit/dashboardjs.h @@ -0,0 +1,116 @@ +/* +Copyright (c) 2008 Beat Wolf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +#ifndef DASHBOARDJS_H +#define DASHBOARDJS_H + +#include +#include +#include + +#include + +#include + +/** + * Implements the Mac OS X Dashboard widget javascript functions. + * This document was used to create this class: + * http://developer.apple.com/documentation/AppleApplications/Reference/Dashboard_Ref/Dashboard_Ref.pdf + */ +class DashboardJs : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString identifier READ identifier) + + Q_PROPERTY(QString onshow READ onshow WRITE setOnshow) + Q_PROPERTY(QString onhide READ onhide WRITE setOnhide) + Q_PROPERTY(QString onremove READ onremove WRITE setOnremove) + Q_PROPERTY(QString ondragstart READ ondragstart WRITE setOndragstart) + Q_PROPERTY(QString ondragstop READ ondragstop WRITE setOndragstop) + +public: + DashboardJs(QWebFrame *frame, QObject *parent= 0, Plasma::Applet *applet = 0); + ~DashboardJs(); + + QString identifier() const; + + QString onshow() const; + void setOnshow(const QString &onshow); + + QString onhide() const; + void setOnhide(const QString &onhide); + + QString onremove() const; + void setOnremove(const QString &onremove); + + QString ondragstart() const; + void setOndragstart(const QString &ondragstart); + + QString ondragstop() const; + void setOndragstop(const QString &ondragstop); + +public slots: + void hello(int test); + + /** + * opens a certain application + */ + void openApplication(QString name); + + /** + * opens a URL. Does not open file urls by default. + * TODO: find out what protocols dashboard widgets support. filter out the others + */ + void openURL(QString name); //ok + + /** + * Returns the value associated with a certain key + */ + QVariant preferenceForKey(QString key); //ok + + void prepareForTransition(QString transition); + + void performTransition(); + + void setCloseBoxOffset(int x, int y); //not needed + + /** + * Saves a value to a key + */ + void setPreferenceForKey(QString value, QString key); //ok + + void system(QString command, QString handler); //cannot really be implemented +private: + //TODO: execute when needed + QString m_onshow; //has no equivalent in plasma, because always shown + QString m_onhide; //has no equivalent in plasma, because always shown + QString m_onremove; //ok + + QString m_ondragstart; + QString m_ondragstop; + + //my private stuff + Plasma::Applet *m_applet; + QWebFrame *m_frame; +}; + +#endif diff --git a/plasma/generic/scriptengines/webkit/plasma-packagestructure-dashboard.desktop b/plasma/generic/scriptengines/webkit/plasma-packagestructure-dashboard.desktop new file mode 100644 index 00000000..1a2485b6 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasma-packagestructure-dashboard.desktop @@ -0,0 +1,159 @@ +[Desktop Entry] +Name=MacOS Dashboard Widgets +Name[ar]=ودجات لوحة MacOS +Name[ast]=Elementos gráficos del tableru de mandos de MacOS +Name[be@latin]=Widžety „Dashboard” dla systemy „MacOS” +Name[bg]=Джаджи за табло на MacOS +Name[bs]=Grafičke kontrole instrument-table MacOS‑a +Name[ca]=Estri del tauler del MacOS +Name[ca@valencia]=Estri del tauler del MacOS +Name[cs]=Widgety palubní desky MacOS +Name[da]=MacOS dashboard-widgets +Name[de]=MacOS-Dashboard-Miniprogramme +Name[el]=Συστατικά του MacOS dashboard +Name[en_GB]=MacOS Dashboard Widgets +Name[eo]=MacOS stirtabla fenestraĵo +Name[es]=Elementos gráficos del tablero de mandos de MacOS +Name[et]=MacOS-i vidinavaate vidinad +Name[eu]=MacOS-ren aginte-mahaiko trepetak +Name[fi]=MacOS-kojelautasovelmat +Name[fr]=Composants graphiques du panneau de contrôle de MacOS +Name[fy]=MacOS Dashboard Widgets +Name[ga]=Giuirléidí Dashboard MacOS +Name[gl]=Widget do Dashboard de MacOS +Name[gu]=MacOS ડેશબોર્ડ વિજેટ +Name[he]=ווידג׳טים של MacOS Dashboard +Name[hi]=मैकओएस डैशबोर्ड विजेट +Name[hne]=मेकओएस डेसबोर्ड विजेट +Name[hr]=MacOS widgeti nadzorne ploče +Name[hu]=MacOS Dashboard-elem +Name[ia]=MacOS Dashboard Widgets +Name[id]=Widget Dasbor MacOS +Name[is]=MacOS dashboard græjur +Name[ja]=MacOS ダッシュボードウィジェット +Name[kk]=MacOS аспаптар панелі +Name[km]=ធាតុក្រាហ្វិក​ផ្ទាំង​គ្រប់គ្រង MacOS +Name[kn]=MacOS ಯಂತ್ರೋಪಕರಣ ಪಟ್ಟಿ (ಡ್ಯಾಶ್‌ಬೋರ್ಡ್) ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟಗಳು (ವಿಡ್ಗೆಟ್) +Name[ko]=MacOS 대시보드 위젯 +Name[ku]=Alavên Panela Kontrolê yên MacOS +Name[lt]=MacOS prietaisų skydelio valdikliai +Name[lv]=MacOS dashboard sīkrīki +Name[ml]=മാക് ഓഎസ് ഡാഷ്ബോര്‍ഡ് ഉരുപ്പടികള്‍ +Name[mr]=MacOS डॅशबोर्ड विजेट +Name[nb]=Kontrollpult-elementer for MacOS +Name[nds]=MacOs-Klockpaneel-Lüttprogrammen +Name[nl]=MacOS Dashboard Widgets +Name[nn]=MacOS-kontrollpultelement +Name[or]=MacOS ଡ୍ୟାସବୋର୍ଡ ୱିଜେଟଗୁଡ଼ିକ +Name[pa]=MacOS ਡੈਸ਼ਬੋਰਡ ਵਿਦਜੈੱਟ +Name[pl]=Element interfejsu na tablicy z MacOS +Name[pt]=Elementos do Painel do MacOS +Name[pt_BR]=Widgets do painel do MacOS +Name[ro]=Controale ale tabloului de bord MacOS +Name[ru]=Виджеты Mac OS +Name[si]=MacOS Dashboard Widgets +Name[sk]=MacOS Dashboard widgety +Name[sl]=Gradniki za Mac OS Dashboard +Name[sr]=виџети инструмент-табле МекОС‑а +Name[sr@ijekavian]=виџети инструмент-табле МекОС‑а +Name[sr@ijekavianlatin]=vidžeti instrument-table MacOS‑a +Name[sr@latin]=vidžeti instrument-table MacOS‑a +Name[sv]=Grafiska komponenter för MacOS instrumentpanel +Name[ta]=MacOS Dashboard Widgets +Name[tg]=Илова ба панели MacOS +Name[th]=วิดเจ็ตของแดชบอร์ด MacOS +Name[tr]=MacOS Kontrol Paneli Gereçleri +Name[ug]=MacOS تىزگىن تاختا ۋىجېتلىرى +Name[uk]=Віджети панелі приладів MacOS +Name[vi]=Widget bảng thông tin MacOS +Name[wa]=Ahesses Dashboard MacOS +Name[x-test]=xxMacOS Dashboard Widgetsxx +Name[zh_CN]=MacOS 部件板部件 +Name[zh_TW]=MacOS 資訊看板元件 +Comment=MacOS dashboard widget +Comment[ar]=ودجة لوحة MacOS +Comment[ast]=Elementu gráficu del tableru de mandos de MacOS +Comment[be@latin]=Widžet „Dashboard” dla systemy „MacOS” +Comment[bg]=Джаджа за табло на MacOS +Comment[bs]=Grafičke kontrola instrument-table kao u MacOS‑u +Comment[ca]=Estri del tauler del MacOS +Comment[ca@valencia]=Estri del tauler del MacOS +Comment[cs]=Widget palubní desky MacOS +Comment[da]=MacOS dashboard-widget +Comment[de]=MacOS-Dashboard-Miniprogramm +Comment[el]=Συστατικό του MacOS dashboard +Comment[en_GB]=MacOS dashboard widget +Comment[eo]=MacOS stirtabla fenestraĵo +Comment[es]=Elemento gráfico del tablero de mandos de MacOS +Comment[et]=MacOS-i vidinavaate vidin +Comment[eu]=MacOS-ren aginte-mahaiko trepeta +Comment[fi]=MacOS-kojelautasovelma +Comment[fr]=Composant graphique du panneau de contrôle de MacOS +Comment[fy]=MacOS dashboard widget +Comment[ga]=Giuirléid Dashboard MacOS +Comment[gl]=Widget do dashboard de MacOS +Comment[gu]=MacOS ડેશબોર્ડ વિજેટ +Comment[he]=ווידג׳ט של MacOS dashboard +Comment[hi]=मैकओएस डैशबोर्ड विजेट +Comment[hne]=मेकओएस डेसबोर्ड विजेट +Comment[hr]=MacOS widget nadzorne ploče +Comment[hu]=MacOS Dashboard-elem +Comment[ia]=Widget de pannello de instrumentos de MacOS +Comment[id]=Widget dasbor MacOS +Comment[is]=MacOS dashboard græja +Comment[ja]=MacOS ダッシュボードウィジェット +Comment[kk]=MacOS аспаптар панелі +Comment[km]=ធាតុ​ក្រាហ្វិក​ផ្ទាំង​គ្រប់គ្រង​របស់ MacOS +Comment[kn]=MacOS ಯಂತ್ರೋಪಕರಣ ಪಟ್ಟಿ (ಡಾಶ್ ಬೋರ್ಡ್) ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=MacOS 대시보드 위젯 +Comment[ku]=Amûrê MacOS dashboardê +Comment[lt]=MacOS prietaisų skydelio valdiklis +Comment[lv]=MacOS dashboard skrīks +Comment[ml]=മാക് ഓഎസ് ഡാഷ്ബോര്‍ഡ് ഉരുപ്പടി +Comment[mr]=MacOS डॅशबोर्ड विजेट +Comment[nb]=Kontrollpult-element for MacOS +Comment[nds]=MacOs-Klockpaneel +Comment[nl]=MacOS-dashboard-widget +Comment[nn]=MacOS-kontrollpultelement +Comment[or]=MacOS ଡ୍ୟାସବୋର୍ଡ ୱିଜେଟ +Comment[pa]=MacOS ਡੈਸ਼ਬੋਰਡ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu przypominający tablicę z MacOS +Comment[pt]=Elemento do Painel do MacOS +Comment[pt_BR]=Widget do painel do MacOS +Comment[ro]=Control al tabloului de bord MacOS +Comment[ru]=Виджет Mac OS +Comment[si]=MacOS dashboard widget +Comment[sk]=MacOS dashboard widget +Comment[sl]=Gradnik za Mac OS Dashboard +Comment[sr]=Виџет инструмент-табле као у МекОС‑у +Comment[sr@ijekavian]=Виџет инструмент-табле као у МекОС‑у +Comment[sr@ijekavianlatin]=Vidžet instrument-table kao u MacOS‑u +Comment[sr@latin]=Vidžet instrument-table kao u MacOS‑u +Comment[sv]=Grafisk komponent för MacOS instrumentpanel +Comment[ta]=MacOS dashboard widget +Comment[te]=MacOS డాష్‌బోర్‍డ్ విడ్జట్ +Comment[tg]=Илова ба панели MacOS +Comment[th]=วิดเจ็ตของแดชบอร์ด MacOS +Comment[tr]=MacOS kontrol paneli gereci +Comment[ug]=MacOS تىزگىن تاختا ۋىجېتى +Comment[uk]=Віджет панелі приладів MacOS +Comment[vi]=Widget bảng thông tin MacOS +Comment[wa]=Ahesse do tåvlea d' boird dashboard di MacOS +Comment[x-test]=xxMacOS dashboard widgetxx +Comment[zh_CN]=MacOS 部件板 +Comment[zh_TW]=MacOS 資訊看板元件 +Type=Service +ServiceTypes=Plasma/PackageStructure + +X-KDE-Library=plasma_packagestructure_dashboard +X-KDE-PluginInfo-Author=Zack Rusin +X-KDE-PluginInfo-Email=zackr@kde.org +X-KDE-PluginInfo-Name=dashboard +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Applet +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=BSD +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-PackageFileFilter=* +X-Plasma-PackageFileMimetypes=application/zip diff --git a/plasma/generic/scriptengines/webkit/plasma-packagestructure-web.desktop b/plasma/generic/scriptengines/webkit/plasma-packagestructure-web.desktop new file mode 100644 index 00000000..1cb95afe --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasma-packagestructure-web.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +Name=Web Widgets +Name[ar]=ودجات الوِب +Name[ast]=Elementos gráficos Web +Name[be@latin]=Sieciŭnyja widžety +Name[bg]=Уеб джаджи +Name[bn]=ওয়েব উইজেট +Name[bn_IN]=ওয়েব উইজেট +Name[bs]=Web grafičke kontrola +Name[ca]=Estris web +Name[ca@valencia]=Estris web +Name[cs]=Webové widgety +Name[csb]=Interfejs sécë Web +Name[da]=Web-widgets +Name[de]=Web-Miniprogramme +Name[el]=Συστατικά ιστού +Name[en_GB]=Web Widgets +Name[eo]=Reta fenestraĵo +Name[es]=Elementos gráficos Web +Name[et]=Veebividinad +Name[eu]=Web-trepetak +Name[fi]=Web-sovelmat +Name[fr]=Composants graphiques Web +Name[fy]=Web Widgets +Name[ga]=Giuirléidí Gréasáin +Name[gl]=Widgets web +Name[gu]=વેબ વિજેટ્સ +Name[he]=ווידג׳טים אינטרנטיים +Name[hi]=वेब विजेट +Name[hne]=वेब विजेट +Name[hr]=Web widgeti +Name[hu]=Webes elem +Name[ia]=Web Widgets +Name[id]=Widget Web +Name[is]=Vefgræjur +Name[ja]=ウェブウィジェット +Name[kk]=Веб интерфейс бөлшегі +Name[km]=ធាតុក្រាហ្វិក​បណ្ដាញ +Name[kn]=ಜಾಲ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟಗಳು (ವಿಡ್ಗೆಟ್) +Name[ko]=웹 위젯 +Name[ku]=Alavên Torê +Name[lt]=Žiniatinklio valdikliai +Name[lv]=Tīmekļa sīkrīki +Name[ml]=വെബ് ഉരുപ്പടികള്‍ +Name[mr]=वेब विजेट +Name[nb]=Nett-elementer +Name[nds]=Nett-Lüttprogrammen +Name[nl]=Web Widgets +Name[nn]=Vevelement +Name[or]=ୱେବ ୱିଜେଟଗୁଡ଼ିକ +Name[pa]=ਵੈੱਬ ਵਿਦਜੈੱਟ +Name[pl]=Strona sieci Web (element interfejsu) +Name[pt]=Elementos Web +Name[pt_BR]=Widgets da Internet +Name[ro]=Controale WEB +Name[ru]=Веб-виджеты +Name[si]=වෙබ් මෙවලම් +Name[sk]=Webové widgety +Name[sl]=Spletni gradniki +Name[sr]=веб виџети +Name[sr@ijekavian]=веб виџети +Name[sr@ijekavianlatin]=veb vidžeti +Name[sr@latin]=veb vidžeti +Name[sv]=Grafiska webbkomponenter +Name[ta]=Web Widgets +Name[tg]=Иловагиҳо ба Интернет +Name[th]=วิดเจ็ตแบบเว็บ +Name[tr]=Web Gereçleri +Name[ug]=تور بەت Widget +Name[uk]=Віджети Тенет +Name[wa]=Ahesses waibe +Name[x-test]=xxWeb Widgetsxx +Name[zh_CN]=网页部件 +Name[zh_TW]=網頁元件 +Comment=HTML widget +Comment[ar]=ودجة HTML +Comment[ast]=Elementu gráficu HTML +Comment[be@latin]=Widžet HTML +Comment[bg]=HTML джаджи +Comment[bn]=HTML উইজেট +Comment[bn_IN]=HTML উইজেট +Comment[bs]=HTML grafička kontrola +Comment[ca]=Estri HTML +Comment[ca@valencia]=Estri HTML +Comment[cs]=HTML widget +Comment[csb]=Interfejs HTML +Comment[da]=HTML-widget +Comment[de]=HTML-Miniprogramme +Comment[el]=Συστατικό HTML +Comment[en_GB]=HTML widget +Comment[eo]=HTML-fenestraĵo +Comment[es]=Elemento gráfico HTML +Comment[et]=HTML-vidin +Comment[eu]=HTML trepeta +Comment[fi]=HTML-sovelma +Comment[fr]=Composant graphique HTML +Comment[fy]=HTML widget +Comment[ga]=Giuirléid HTML +Comment[gl]=Widget HTML +Comment[gu]=HTML વિજેટ +Comment[he]=ווידג׳ט HTML +Comment[hi]=एचटीएमएल विज़ेट +Comment[hne]=एचटीएमएल विजेट +Comment[hr]=HTML widget +Comment[hu]=HTML-elem +Comment[ia]=widget HTML +Comment[id]=Widget HTML +Comment[is]=HTML græja +Comment[ja]=HTML ウィジェット +Comment[kk]=HTML интерфейс бөлшегі +Comment[km]=ធាតុ​ក្រាហ្វិក HTML +Comment[kn]=HTML ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=HTML 위젯 +Comment[ku]=Alava HTML +Comment[lt]=HTML valdiklis +Comment[lv]=HTML sīkrīks +Comment[ml]=എച്ച്ടിഎംഎല്‍ ഉരുപ്പടി +Comment[mr]=HTML विजेट +Comment[nb]=HTML-element +Comment[nds]=HTML-Lüttprogramm +Comment[nl]=HTML-widget +Comment[nn]=HTML-element +Comment[or]=HTML ୱିଜେଟ +Comment[pa]=HTML ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu będący stroną w HTML-u +Comment[pt]=Elemento HTML +Comment[pt_BR]=Widget HTML +Comment[ro]=Control HTML +Comment[ru]=Виджет на HTML +Comment[si]=HTML මෙවලම් +Comment[sk]=HTML widget +Comment[sl]=Gradnik HTML +Comment[sr]=ХТМЛ виџет +Comment[sr@ijekavian]=ХТМЛ виџет +Comment[sr@ijekavianlatin]=HTML vidžet +Comment[sr@latin]=HTML vidžet +Comment[sv]=Grafisk HTML-komponent +Comment[ta]=HTML widget +Comment[tg]=Илова ба HTML +Comment[th]=วิดเจ็ตแบบ HTML +Comment[tr]=HTML parçacığı +Comment[ug]=HTML widget +Comment[uk]=Віджет HTML +Comment[vi]=Widget HTML +Comment[wa]=Ahesse HTML +Comment[x-test]=xxHTML widgetxx +Comment[zh_CN]=HTML 部件 +Comment[zh_TW]=HTML 元件 +Type=Service +ServiceTypes=Plasma/PackageStructure + +X-KDE-Library=plasma_packagestructure_web +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=webkit +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Applet +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=BSD +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-PackageFileFilter=* +X-Plasma-PackageFileMimetypes=application/zip diff --git a/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-dashboard.desktop b/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-dashboard.desktop new file mode 100644 index 00000000..a74dabd1 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-dashboard.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Name=Dashboard +Name[ar]=لوحة الودجات +Name[ast]=Tableru de mandos +Name[be@latin]=Dashboard +Name[bg]=Табло +Name[bn]=ড্যাশবোর্ড +Name[bn_IN]=Dashboard +Name[bs]=instrument-tabla +Name[ca]=Tauler +Name[ca@valencia]=Tauler +Name[cs]=Dashboard +Name[csb]=Panel +Name[da]=Instrumentbræt +Name[de]=Dashboard +Name[el]=Πίνακας συστατικών +Name[en_GB]=Dashboard +Name[eo]=Stirtablo +Name[es]=Tablero de mandos +Name[et]=Vidinavaade +Name[eu]=Agente-mahaia +Name[fi]=Kojelauta +Name[fr]=Panneau de contrôle +Name[fy]=Dashboard +Name[ga]=Dashboard +Name[gl]=Cadro de control +Name[gu]=ડેશબોર્ડ +Name[he]=מכתבה +Name[hi]=डैशबोर्ड +Name[hne]=डेशबोर्ड +Name[hr]=Nadzorna ploča +Name[hu]=Dashboard +Name[ia]=Pannello de instrumentos +Name[id]=Dasbor +Name[is]=Dashboard +Name[it]=Dashboard +Name[ja]=ダッシュボード +Name[kk]=Аспаптар панелі +Name[km]=ផ្ទាំង​គ្រប់គ្រង +Name[kn]=ಯಂತ್ರೋಪಕರಣ ಪಟ್ಟಿ (ಡಾಶ್ ಬೋರ್ಡ್) +Name[ko]=대시보드 +Name[ku]=Panela Kontrolê +Name[lt]=Prietaisų skydelis +Name[lv]=Dashboard +Name[ml]=ഡാഷ്ബോര്‍ഡ് +Name[mr]=डॅशबोर्ड +Name[nb]=Kontrollpult +Name[nds]=Klockpaneel +Name[nl]=Dashboard +Name[nn]=Kontrollpult +Name[or]=ଡ୍ୟାସବୋର୍ଡ +Name[pa]=ਡੈਸ਼ਬੋਰਡ +Name[pl]=Tablica +Name[pt]=Dashboard +Name[pt_BR]=Painel +Name[ro]=Tablou de bord +Name[ru]=Приборная доска +Name[si]=පාලක පුරුව +Name[sk]=Nástenka +Name[sl]=Nadzorna plošča +Name[sr]=инструмент-табла +Name[sr@ijekavian]=инструмент-табла +Name[sr@ijekavianlatin]=instrument-tabla +Name[sr@latin]=instrument-tabla +Name[sv]=Instrumentpanel +Name[ta]= எக்ஸ்போர்டு +Name[te]=డాష్‌బోర్‍డ్ +Name[tg]=Панели иловагиҳо +Name[th]=แดชบอร์ด +Name[tr]=Kontrol Paneli +Name[ug]=باشقۇرۇش بېتى +Name[uk]=Панель приладів +Name[vi]=Bảng thông tin +Name[wa]=Tåvlea d' boird +Name[x-test]=xxDashboardxx +Name[zh_CN]=部件板 +Name[zh_TW]=資訊看板 +Comment=MacOS X dashboard widget +Comment[ar]=ودجة لوحة MacOS +Comment[ast]=Elementu gráficu del tableru de mandos de MacOS X +Comment[be@latin]=Widžet „Dashboard” systemy „MacOS X”. +Comment[bg]=Джаджа за табло на MacOS X +Comment[bs]=Grafička kontrola instrument-table MacOS‑a X +Comment[ca]=Estri del tauler del MacOS X +Comment[ca@valencia]=Estri del tauler del MacOS X +Comment[cs]=Widget palubní desky MacOS +Comment[da]=MacOS X dashboard-widget +Comment[de]=MacOS-X-Dashboard-Miniprogramm +Comment[el]=Συστατικό MacOS X dashboard +Comment[en_GB]=MacOS X dashboard widget +Comment[eo]=MacOS X stirtabla fenestraĵo +Comment[es]=Elemento gráfico del tablero de mandos de MacOS X +Comment[et]=MacOS X vidinavaate vidin +Comment[eu]=MacOS X-ren aginte-mahaiko trepeta +Comment[fi]=MacOS X -kojelautasovelma +Comment[fr]=Composant graphique du panneau de contrôle de MacOS X +Comment[fy]=MacOS X dashboard widget +Comment[ga]=Giuirléid Dashboard MacOS X +Comment[gl]=Widget do dashboard de MacOS X +Comment[gu]=MacOS X ડેશબોર્ડ વિજેટ +Comment[he]=ווידג׳טים של MacOS X dashboard +Comment[hi]=मैकओएस X डैशबोर्ड विजेट +Comment[hne]=मेकओएस X डेसबोर्ड विजेट +Comment[hr]=MacOS X nadzorna ploča za widgete +Comment[hu]=MacOS X Dashboard-elem +Comment[ia]=Widget de pannello de instrumentos de MacOS X +Comment[id]=Widget dasbor MacOS X +Comment[is]=MacOS X dashboard græja +Comment[ja]=MacOS X ダッシュボードウィジェット +Comment[kk]=MacOS X аспаптар панелі +Comment[km]=ធាតុ​ក្រាហ្វិក​ផ្ទាំងគ្រប់គ្រង​របស់ MacOS +Comment[kn]=MacOS X ಯಂತ್ರೋಪಕರಣ ಪಟ್ಟಿ (ಡಾಶ್ ಬೋರ್ಡ್) ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=Mac OS X 대시보드 위젯 +Comment[ku]=Amûrê MacOS X dashboardê +Comment[lt]=MacOS X prietaisų skydelio valdiklis +Comment[lv]=MacOS X dashboard sīkrīks +Comment[ml]=മാക് ഓഎസ് എക്സ് ഡാഷ്ബോര്‍ഡ് ഉരുപ്പടി +Comment[mr]=MacOS X डॅशबोर्ड विजेट +Comment[nb]=MacOS X kontrollpult-element +Comment[nds]=MacOs-X-Klockpaneel +Comment[nl]=MacOS X-dashboard-widget +Comment[nn]=MacOS X-kontrollpultelement +Comment[or]=MacOS X ଡ୍ୟାସବୋର୍ଡ ୱିଜେଟ +Comment[pa]=MacOS X ਡੈਸ਼ਬੋਰਡ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu przypominający tablicę z MacOS X +Comment[pt]=Elemento gráfico do painel do MacOS X +Comment[pt_BR]=Widget do painel do MacOS X +Comment[ro]=Control al tabloului de bord MacOS X +Comment[ru]=Виджет Mac OS X +Comment[si]=MacOS X dashboard widget +Comment[sk]=MacOS X dashboard widget +Comment[sl]=Gradnik za Mac OS X Dashboard +Comment[sr]=Виџет инструмент-табле МекОС‑а X +Comment[sr@ijekavian]=Виџет инструмент-табле МекОС‑а X +Comment[sr@ijekavianlatin]=Vidžet instrument-table MacOS‑a X +Comment[sr@latin]=Vidžet instrument-table MacOS‑a X +Comment[sv]=Grafisk komponent för MacOS X instrumentpanel +Comment[ta]=MacOS X dashboard widget +Comment[te]=MacOS X డాష్‌బోర్‍డ్ విడ్జట్ +Comment[tg]=Илова ба панели MacOS X +Comment[th]=วิดเจ็ตของแดชบอร์ด MacOS X +Comment[tr]=MacOS X kontrol paneli programcığı +Comment[ug]=MacOS X تىزگىن تاختا ۋىجېتى +Comment[uk]=Віджет панелі приладів MacOS X +Comment[vi]=Widget bảng thông tin MacOS X +Comment[wa]=Ahesse do tåvlea d' boird dashboard di MacOS X +Comment[x-test]=xxMacOS X dashboard widgetxx +Comment[zh_CN]=MacOS X 部件板 +Comment[zh_TW]=MacOS X 資訊看板元件 +Type=Service +ServiceTypes=Plasma/ScriptEngine +Icon=internet-web-browser + +X-KDE-Library=plasma_appletscriptengine_dashboard +X-KDE-PluginInfo-Author=Zack Rusin +X-KDE-PluginInfo-Email=zackr@kde.org +X-KDE-PluginInfo-Name=dashboard +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Applet +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=BSD +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-ComponentTypes=Applet +X-Plasma-API=dashboard +X-Plasma-PackageFormat=dashboard diff --git a/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-web.desktop b/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-web.desktop new file mode 100644 index 00000000..dac3dd10 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasma-scriptengine-applet-web.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +Name=Web Widget +Name[ar]=ودجة وِب +Name[ast]=Elementu gráficu Web +Name[be@latin]=Sieciŭny widžet +Name[bg]=Уеб джаджа +Name[bn]=ওয়েব উইজেট +Name[bn_IN]=ওয়েব উইজেট +Name[bs]=Web grafička kontrola +Name[ca]=Estri web +Name[ca@valencia]=Estri web +Name[cs]=Webový widget +Name[csb]=Sztél zblëżający bedënk do sécë Web +Name[da]=Webwidget +Name[de]=Web-Miniprogramm +Name[el]=Συστατικό ιστού +Name[en_GB]=Web Widget +Name[eo]=Reta fenestraĵo +Name[es]=Elemento gráfico Web +Name[et]=Veebividin +Name[eu]=Web-trepeta +Name[fi]=Web-sovelma +Name[fr]=Composant graphique Web +Name[fy]=Web Widget +Name[ga]=Giuirléid Ghréasáin +Name[gl]=Widget web +Name[gu]=વેબ વિજેટ +Name[he]=ווידג׳ט אינטרנט +Name[hi]=वेब विज़ेट +Name[hne]=वेब विजेट +Name[hr]=Web widget +Name[hu]=Webes elem +Name[ia]=Web Widget +Name[id]=Widget Web +Name[is]=Vefgræja +Name[ja]=ウェブウィジェット +Name[kk]=Веб интерфейс бөлшегі +Name[km]=ធាតុក្រាហ្វិក​បណ្ដាញ +Name[kn]=ಜಾಲ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Name[ko]=웹 위젯 +Name[ku]=Alava Torê +Name[lt]=Žiniatinklio valdiklis +Name[lv]=Tīmekļa sīkrīks +Name[ml]=വെബ് ഉരുപ്പടി +Name[mr]=वेब विजेट +Name[nb]=Nett-element +Name[nds]=Nett-Lüttprogramm +Name[nl]=Web-widget +Name[nn]=Vevelement +Name[or]=ୱେବ ୱିଜେଟ +Name[pa]=ਵੈੱਬ ਵਿਦਜੈੱਟ +Name[pl]=Strona sieci Web (element interfejsu) +Name[pt]=Elemento Web +Name[pt_BR]=Widget da Internet +Name[ro]=Control WEB +Name[ru]=Веб-виджет +Name[si]=වෙබ් මෙවලම් +Name[sk]=Webový widget +Name[sl]=Spletni gradnik +Name[sr]=веб виџет +Name[sr@ijekavian]=веб виџет +Name[sr@ijekavianlatin]=veb vidžet +Name[sr@latin]=veb vidžet +Name[sv]=Webbkomponent +Name[ta]=Web Widget +Name[te]=వెబ్ విడ్జట్ +Name[tg]=Илова ба Интернет +Name[th]=วิดเจ็ตแบบเว็บ +Name[tr]=Web Programcığı +Name[ug]=تور بەت Widget +Name[uk]=Віджет тенет +Name[wa]=Ahesse waibe +Name[x-test]=xxWeb Widgetxx +Name[zh_CN]=网页部件 +Name[zh_TW]=網頁元件 +Comment=Webpage widget using HTML and JavaScript +Comment[ar]=صفحة وِب باستخدام HTML وجافا سكربت +Comment[ast]=Elementu gráficu de páxina web qu'usa HTML y JavaScript +Comment[be@latin]=Widžet z staronkaj u farmacie „HTML” i z skryptami „JavaScript”. +Comment[bg]=Джаджа за уеб страници (HTML и JavaScript) +Comment[bs]=Grafička kontrola web stranice sa HTML‑om i JavaScriptom +Comment[ca]=Estri per a pàgines web que usa HTML i JavaScript +Comment[ca@valencia]=Estri per a pàgines web que usa HTML i JavaScript +Comment[cs]=Widget webové stránky s HTML a JS +Comment[da]=Hjemmeside-widget som bruger HTML og JavaScript +Comment[de]=Webseiten-Miniprogramm (verwendet HTML und JavaScript) +Comment[el]=Συστατικό ιστοσελίδας με χρήση HTML και JavaScript +Comment[en_GB]=Webpage widget using HTML and JavaScript +Comment[eo]=Reta fenestraĵo kiu uzas HTML-on kaj Ĝavoskripton +Comment[es]=Elemento gráfico de página web que usa HTML y JavaScript +Comment[et]=HTML-i ja JavaScripti kasutav veebilehekülje vidin +Comment[eu]=HTML eta JavaScript erabiltzen dituen web-orriko trepeta +Comment[fi]=HTML:ää ja JavaScriptiä käyttävä verkkosivusovelma +Comment[fr]=Composant graphique de page Web utilisant HTML et JavaScript +Comment[fy]=Webside widget brûkend HTML en JavaSkript +Comment[ga]=Giuirléid Ghréasáin a úsáideann HTML agus JavaScript +Comment[gl]=Widget de páxina web que emprega HTML e JavaScript +Comment[gu]=HTML અને જાવાસ્ક્રિપ્ટ ઉપયોગ કરીને વેબપાનું વિજેટ +Comment[he]=ווידג׳ט עמוד אינטרנט העושה שימוש ב־HTML וב־JavaScript +Comment[hi]=एचटीएमएल एवं जावा-स्क्रिप्ट के प्रयोग से जालपृष्ठ विजेट +Comment[hne]=एचटीएमएल अउ जावास्क्रिप्ट के उपयोग से वेबपेज विजेट +Comment[hr]=Widgeti web stranice koja koristi HTML i JavaScript +Comment[hu]=Webes elem HTML/Javascript használatával +Comment[ia]=Elemento graphic (Widget) de pagina web usante HTML e JavaScript +Comment[id]=Widget halaman web menggunakan HTML dan JavaScript +Comment[is]=Vefsíðugræja sem notar HTML og JavaScript +Comment[ja]=HTML と JavaScript を使ったウェブページウィジェット +Comment[kk]=HTML мен JavaScript негіздеген Веб-парақ бөлшегі +Comment[km]=ធាតុក្រាហ្វិក​ទំព័រ​បណ្ដាញ​ដោយប្រើ HTML និង JavaScript +Comment[kn]=HTML ಮತ್ತು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಬಳಸುವ ಜಾಲಪುಟ ನಿಯಂತ್ರಣಾಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=HTML과 자바스크립트를 사용하는 웹 페이지 위젯 +Comment[ku]=Amûrê Rûpela Webê HTML û JavaScript bi kar tîne +Comment[lt]=Žiniatinklio puslapio valdiklis naudojantis HTML ir JavaScript +Comment[lv]=Tīmekļa lapas sīkrīks, kas izmanto HTML un JavaScript +Comment[ml]=എച്ച്ടിഎംഎലും ജാവാസ്ക്രിപ്റ്റും ഉപയോഗിക്കുന്ന വെബ്താള്‍ ഉരുപ്പടി +Comment[mr]=HTML व जावास्क्रिप्टचा वापर करणारे वेबपान विजेट +Comment[nb]=Nettside-element som bruker HTML og JavaScript +Comment[nds]=Nettsieden-Finster, bruukt HTML un JavaScript +Comment[nl]=Webpagina-widget, gebruikmakend van HTML en JavaScript +Comment[nn]=Nettsideelement som brukar HTML og JavaScript +Comment[or]=HTML ଏବଂ JavaScript ବ୍ୟବହାର କରି ୱେବ ପୃଷ୍ଠା ୱିଜେଟ +Comment[pa]=HTML ਅਤੇ ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਨਾਲ ਵੈੱਬ-ਪੇਜ਼ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu wykorzystujący HTML oraz JavaScript +Comment[pt]=Elemento de página Web que usa HTML e JavaScript +Comment[pt_BR]=Widget de página da Internet usando HTML e JavaScript +Comment[ro]=Control web scris în HTML și JavaScript +Comment[ru]=Показ веб-страницы +Comment[si]=Webpage widget using HTML and JavaScript +Comment[sk]=Widget webovej stránky, ktorý používa HTML a JavaScript +Comment[sl]=Spletni gradnik, ki uporablja HTML in JavaScript +Comment[sr]=Виџет веб странице са ХТМЛ‑ом и јаваскриптом +Comment[sr@ijekavian]=Виџет веб странице са ХТМЛ‑ом и јаваскриптом +Comment[sr@ijekavianlatin]=Vidžet veb stranice sa HTML‑om i JavaScriptom +Comment[sr@latin]=Vidžet veb stranice sa HTML‑om i JavaScriptom +Comment[sv]=Grafisk webbkomponent som använder HTML och Javascript +Comment[ta]=Webpage widget using HTML and JavaScript +Comment[te]=HTML మరియు జావాస్క్రిప్‍ట్ ఉపయోగించు వెబ్‌పేజ్ విడ్జట్ +Comment[tg]=Модуль, использующий HTML и JavaScript +Comment[th]=วิดเจ็ตหน้าเว็บที่ถูกเขียนด้วย HTML และจาวาสคริปต์ +Comment[tr]=HTML ve JavaScript kullanan Web sayfası programcığı +Comment[ug]=HTML ۋە JavaScript ئىشلەتكەن تور بەت widget +Comment[uk]=Віджет сторінки тенет, що використовує HTML і JavaScript +Comment[wa]=Ahesse di pådje waibe eployant l' HTML eyet JavaScript +Comment[x-test]=xxWebpage widget using HTML and JavaScriptxx +Comment[zh_CN]=使用 HTML 和JavaScript 的网页部件 +Comment[zh_TW]=使用 HTML 與 JavaScript 的網頁元件 +Type=Service +ServiceTypes=Plasma/ScriptEngine +Icon=internet-web-browser + +X-KDE-Library=plasma_appletscriptengine_webapplet +X-KDE-PluginInfo-Author=Zack Rusin +X-KDE-PluginInfo-Email=zack@kde.org +X-KDE-PluginInfo-Name=webkit +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Applet +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=BSD +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-API=webkit +X-Plasma-ComponentTypes=Applet +X-Plasma-PackageFormat=webkit diff --git a/plasma/generic/scriptengines/webkit/plasmajs.cpp b/plasma/generic/scriptengines/webkit/plasmajs.cpp new file mode 100644 index 00000000..3bfe4132 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasmajs.cpp @@ -0,0 +1,141 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "plasmajs.h" +#include "plasmawebapplet.h" + +#include + +using namespace Plasma; + +ConfigGroupWrapper::ConfigGroupWrapper(const KConfigGroup &config) +: m_config(config) +{ +} + +void ConfigGroupWrapper::setConfig(const KConfigGroup &config) +{ + //kDebug() << config.config()->name() << config.name(); + m_config = config; +} + +QVariant ConfigGroupWrapper::readEntry(const QString &key, const QVariant &aDefault) const +{ + // Should KConfig do this? + // There is readEntry(key, QVariant) but it does not seem to work + // (if writeEntry was not QVariant??) + // kDebug() << aDefault.typeName(); + if (aDefault.type() == QVariant::Int) { + return m_config.readEntry(key, aDefault.toInt()); + } else if (aDefault.type() == QVariant::Double) { + return m_config.readEntry(key, aDefault.toDouble()); + } else if (aDefault.type() == QVariant::Bool) { + return m_config.readEntry(key, aDefault.toBool()); + } else { + return m_config.readEntry(key, aDefault.toString()); + } +} + +void ConfigGroupWrapper::writeEntry(const QString &key, const QVariant& value) +{ + m_config.writeEntry(key, value); +} + +DataEngineDataWrapper::DataEngineDataWrapper(const DataEngine::Data &data) + : m_data(data) +{ +} + +int DataEngineDataWrapper::length() const +{ + return m_data.count(); +} + +void DataEngineDataWrapper::setData(const Plasma::DataEngine::Data &data) +{ + m_data = data; +} + +QVariant DataEngineDataWrapper::value(const QString &key) const +{ + return m_data[key]; +} + +bool DataEngineDataWrapper::contains(const QString &key) const +{ + return m_data.keys().contains(key); +} + +QStringList DataEngineDataWrapper::keys() const +{ + return m_data.keys(); +} + +QString DataEngineDataWrapper::key(int i) const +{ + return m_data.keys().at(i); +} + +DataEngineWrapper::DataEngineWrapper(Plasma::DataEngine *engine, QObject *applet) + : QObject(engine), m_engine(engine), m_applet(applet) +{ +} + +QStringList DataEngineWrapper::sources() const +{ + return m_engine->sources(); +} + +QString DataEngineWrapper::engineName() const +{ + return m_engine->name(); +} + +bool DataEngineWrapper::isValid() const +{ + return m_engine->isValid(); +} + +QString DataEngineWrapper::icon() const +{ + return m_engine->icon(); +} + +QObject * DataEngineWrapper::query(const QString &str) const +{ + DataEngine::Data data = m_engine->query(str); + return new DataEngineDataWrapper(data); +} + +DataEngineWrapper::~DataEngineWrapper() +{ +} + +void DataEngineWrapper::connectSource(const QString& source, + uint pollingInterval, uint intervalAlignment) +{ + if (m_applet) { + m_engine->connectSource(source, m_applet, pollingInterval, + (Plasma::IntervalAlignment)intervalAlignment); + } +} + +#include "plasmajs.moc" diff --git a/plasma/generic/scriptengines/webkit/plasmajs.h b/plasma/generic/scriptengines/webkit/plasmajs.h new file mode 100644 index 00000000..af5b4319 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasmajs.h @@ -0,0 +1,93 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#ifndef PLASMAJS_H +#define PLASMAJS_H + +#include +#include +#include + +class PlasmaWebApplet; + +class DataEngineDataWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(int length READ length) +public: + DataEngineDataWrapper(const Plasma::DataEngine::Data &data = Plasma::DataEngine::Data()); + + int length() const; + void setData(const Plasma::DataEngine::Data &data); + +public Q_SLOTS: + bool contains(const QString &key) const; + QVariant value(const QString &key) const; + QStringList keys() const; + QString key(int i) const; + +private: + Plasma::DataEngine::Data m_data; +}; + +class DataEngineWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList sources READ sources) + Q_PROPERTY(bool valid READ isValid) + Q_PROPERTY(QString icon READ icon) + Q_PROPERTY(QString engineName READ engineName) +public: + DataEngineWrapper(Plasma::DataEngine *engine, QObject *applet = 0); + ~DataEngineWrapper(); + + QStringList sources() const; + QString engineName() const; + bool isValid() const; + QString icon() const; + +public Q_SLOTS: + QObject *query(const QString &str) const; + void connectSource(const QString& source, + uint pollingInterval = 0, uint intervalAlignment = 0); + +private: + Plasma::DataEngine *m_engine; + QObject *m_applet; +}; + +class ConfigGroupWrapper : public QObject +{ + Q_OBJECT +public: + ConfigGroupWrapper(const KConfigGroup &config = KConfigGroup()); + + void setConfig(const KConfigGroup &config); + +public Q_SLOTS: + QVariant readEntry(const QString &key, const QVariant &aDefault) const; + void writeEntry(const QString &key, const QVariant& value); + +private: + KConfigGroup m_config; +}; + +#endif diff --git a/plasma/generic/scriptengines/webkit/plasmawebapplet.cpp b/plasma/generic/scriptengines/webkit/plasmawebapplet.cpp new file mode 100644 index 00000000..c5bf20cb --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasmawebapplet.cpp @@ -0,0 +1,483 @@ +/* +Copyright (c) 2007 Zack Rusin +Copyright (c) 2008 Petri Damstén + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "plasmawebapplet.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define JS_CONSTANTS_CONSTRAINT \ +"var NoConstraint = %1;\n"\ +"var FormFactorConstraint = %2;\n"\ +"var LocationConstraint = %3;\n"\ +"var ScreenConstraint = %4;\n"\ +"var SizeConstraint = %5;\n"\ +"var ImmutableConstraint = %6;\n"\ +"var StartupCompletedConstraint = %7;\n"\ +"var ContextConstraint = %8;\n"\ +"var AllConstraints = %9;\n" + +#define JS_CONSTANTS_BACKGROUND \ +"var NoBackground = %1;\n"\ +"var StandardBackground = %2;\n"\ +"var TranslucentBackground = %3;\n"\ +"var DefaultBackground = %5;\n" + +#define JS_CONSTANTS_SCROLLBAR \ +"var QtHorizontal = %1;\n"\ +"var QtVertical = %2;\n"\ +"var ScrollBarAsNeeded = %3;\n"\ +"var ScrollBarAlwaysOff = %4;\n"\ +"var ScrollBarAlwaysOn = %5;\n"\ + +#define JS_CONSTANTS_ASPECTRATIO \ +"var InvalidAspectRatioMode = %1;\n"\ +"var IgnoreAspectRatio = %2;\n"\ +"var KeepAspectRatio = %3;\n"\ +"var Square = %4;\n"\ +"var ConstrainedSquare = %5;\n"\ +"var FixedSize = %6;\n" + +#define JS_CONSTANTS_FORMFACTOR \ +"var Planar = %1;\n"\ +"var MediaCenter = %2;\n"\ +"var Horizontal = %3;\n"\ +"var Vertical = %4;\n"\ + +#define JS_CONSTANTS_LOCATION \ +"var Floating = %1;\n"\ +"var Desktop = %2;\n"\ +"var FullScreen = %3;\n"\ +"var TopEdge = %4;\n"\ +"var BottomEdge = %5;\n"\ +"var LeftEdge = %6;\n"\ +"var RightEdge = %7;\n" + +#define JS_CONSTANTS_OTHER \ +"var size_width = 0;\n"\ +"var size_height = 1;\n"\ +"var point_x = 0;\n"\ +"var point_y = 1;\n"\ +"var rect_x = 0;\n"\ +"var rect_y = 1;\n"\ +"var rect_width = 2;\n"\ +"var rect_height = 3;\n"\ +"var margin_left = 0;\n"\ +"var margin_top = 1;\n"\ +"var margin_right = 2;\n"\ +"var margin_bottom = 3;\n"\ + +#define CSS "body { font-family: %3; font-size: %4pt; color:%1; background-color:%2 }\n" + +QString PlasmaWebApplet::s_jsConstants; + +PlasmaWebApplet::PlasmaWebApplet(QObject *parent, const QVariantList &args) +: WebApplet(parent, args) +{ + if (s_jsConstants.isEmpty()) { + s_jsConstants = JS_CONSTANTS_OTHER; + s_jsConstants += QString(JS_CONSTANTS_CONSTRAINT) + .arg(Plasma::NoConstraint) + .arg(Plasma::FormFactorConstraint) + .arg(Plasma::LocationConstraint) + .arg(Plasma::ScreenConstraint) + .arg(Plasma::SizeConstraint) + .arg(Plasma::ImmutableConstraint) + .arg(Plasma::StartupCompletedConstraint) + .arg(Plasma::ContextConstraint) + .arg(Plasma::AllConstraints); + s_jsConstants += QString(JS_CONSTANTS_BACKGROUND) + .arg(Plasma::Applet::NoBackground) + .arg(Plasma::Applet::StandardBackground) + .arg(Plasma::Applet::TranslucentBackground) + .arg(Plasma::Applet::DefaultBackground); + s_jsConstants += QString(JS_CONSTANTS_SCROLLBAR) + .arg(Qt::Horizontal) + .arg(Qt::Vertical) + .arg(Qt::ScrollBarAsNeeded) + .arg(Qt::ScrollBarAlwaysOff) + .arg(Qt::ScrollBarAlwaysOn); + s_jsConstants += QString(JS_CONSTANTS_ASPECTRATIO) + .arg(Plasma::InvalidAspectRatioMode) + .arg(Plasma::IgnoreAspectRatio) + .arg(Plasma::KeepAspectRatio) + .arg(Plasma::Square) + .arg(Plasma::ConstrainedSquare) + .arg(Plasma::FixedSize); + s_jsConstants += QString(JS_CONSTANTS_FORMFACTOR) + .arg(Plasma::Planar) + .arg(Plasma::MediaCenter) + .arg(Plasma::Horizontal) + .arg(Plasma::Vertical); + s_jsConstants += QString(JS_CONSTANTS_LOCATION) + .arg(Plasma::Floating) + .arg(Plasma::Desktop) + .arg(Plasma::FullScreen) + .arg(Plasma::TopEdge) + .arg(Plasma::BottomEdge) + .arg(Plasma::LeftEdge) + .arg(Plasma::RightEdge); + } +} + +PlasmaWebApplet::~PlasmaWebApplet() +{ +} + +bool PlasmaWebApplet::init() +{ + if (WebApplet::init()) { + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(themeChanged())); + makeStylesheet(); + page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QAction *inspectAction = page()->action(QWebPage::InspectElement); + inspectAction->setText(i18n("Inspect this widget")); + return true; + } + + return false; +} + +void PlasmaWebApplet::makeStylesheet() +{ + if (!page()) { + return; + } + + // this temporary file contains the style sheet to be used when loading/reloading the + // web content. we keep it around for the lifetime of the widget since it needs to be there + // when reloaded + + //TODO perhaps share this file between all instances? perhaps even keep it persistent on disk + // to limit disk write/deletes. that would be simple enough, the only trick would be to + // ensure it updates (and only updates once) on Plasma theme changes so that it doesn't get + // written to in a flury by every PlasmaWebApplet when the theme updates + // probably a reference counted singleton would be the way to go here. + if (!m_styleSheetFile.open()) { + return; + } + + KColorScheme plasmaColorTheme = KColorScheme(QPalette::Active, KColorScheme::View, + Plasma::Theme::defaultTheme()->colorScheme()); + QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); + QColor backgroundColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor); + QFont font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont); + + QString css = QString(CSS).arg(textColor.name()) + .arg(backgroundColor.name()) + .arg(font.family()) + .arg(font.pointSize()); + m_styleSheetFile.write(css.toUtf8()); + page()->settings()->setUserStyleSheetUrl(QUrl(m_styleSheetFile.fileName())); + m_styleSheetFile.close(); +} + +void PlasmaWebApplet::themeChanged() +{ + makeStylesheet(); + callJsFunction("themeChanged"); +} + +void PlasmaWebApplet::loadFinished(bool success) +{ + WebApplet::loadFinished(success); + if (success) { + page()->mainFrame()->evaluateJavaScript(s_jsConstants); + callJsFunction("init"); + } +} + +void PlasmaWebApplet::constraintsEvent(Plasma::Constraints constraints) +{ + if (page() && constraints & Plasma::SizeConstraint) { + qreal left; + qreal top; + qreal right; + qreal bottom; + applet()->getContentsMargins(&left, &top, &right, &bottom); + view()->setPos(QPointF(left, top)); + view()->resize(WebApplet::size() - QSizeF(left + right, top + bottom)); + //kDebug() << WebApplet::size() << left << right << top << bottom << page()->size(); + } + callJsFunction("constraintsEvent", QVariantList() << (int)constraints); +} + +QVariant PlasmaWebApplet::arg(int index) const +{ + return m_args[index]; +} + +QObject* PlasmaWebApplet::objArg(int index) const +{ + return m_args[index].value(); +} + +QString PlasmaWebApplet::name() const +{ + return applet()->name(); +} + +uint PlasmaWebApplet::id() const +{ + return applet()->id(); +} + +int PlasmaWebApplet::formFactor() const +{ + return (int)applet()->formFactor(); +} + +int PlasmaWebApplet::location() const +{ + return (int)applet()->location(); +} + +QString PlasmaWebApplet::pluginName() const +{ + return applet()->pluginName(); +} + +QString PlasmaWebApplet::icon() const +{ + return applet()->icon(); +} + +QString PlasmaWebApplet::category() const +{ + return applet()->category(); +} + +bool PlasmaWebApplet::shouldConserveResources() const +{ + return applet()->shouldConserveResources(); +} + +QStringList PlasmaWebApplet::listAllDataEngines() +{ + return Plasma::DataEngineManager::listAllEngines(); +} + +QObject* PlasmaWebApplet::dataEngine(const QString& name) +{ + QString id = QString("%1").arg(applet()->id()); + Plasma::DataEngine *de = applet()->dataEngine(name); + DataEngineWrapper *wrapper = de->findChild(id); + if (!wrapper) { + wrapper = new DataEngineWrapper(de, this); + wrapper->setObjectName(id); + } + return wrapper; +} + +QObject* PlasmaWebApplet::config() +{ + m_config.setConfig(applet()->config()); + return &m_config; +} + +QObject* PlasmaWebApplet::globalConfig() +{ + m_globalConfig.setConfig(applet()->globalConfig()); + return &m_globalConfig; +} + +void PlasmaWebApplet::resize(qreal w, qreal h) +{ + applet()->resize(w, h); +} + +void PlasmaWebApplet::setBackgroundHints(int hints) +{ + applet()->setBackgroundHints((Plasma::Applet::BackgroundHints)hints); +} + +void PlasmaWebApplet::setScrollBarPolicy(int orientation, int policy) +{ + page()->mainFrame()->setScrollBarPolicy((Qt::Orientation)orientation, + (Qt::ScrollBarPolicy)policy); +} + +void PlasmaWebApplet::setAspectRatioMode(int mode) +{ + applet()->setAspectRatioMode((Plasma::AspectRatioMode)mode); +} + +QVariant PlasmaWebApplet::callJsFunction(const QString& func, const QVariantList& args) +{ + if (loaded()) { + m_args = args; + QString cmd = "if (window." + func + ") { " + func + '('; + for(int i = 0; i < args.count(); ++i) { + if (i > 0) { + cmd += ','; + } + if (args[i].canConvert()) { + cmd += QString("window.plasmoid.objArg(%1)").arg(i); + } else { + cmd += QString("window.plasmoid.arg(%1)").arg(i); + } + } + cmd += ") }"; + //kDebug() << cmd; + return page()->mainFrame()->evaluateJavaScript(cmd); + } + return QVariant(); +} + +void PlasmaWebApplet::dataUpdated(const QString& source, const Plasma::DataEngine::Data &data) +{ + m_dataEngineData.setData(data); + callJsFunction("dataUpdated", + QVariantList() << source << QVariant::fromValue((QObject*)&m_dataEngineData)); +} + +void PlasmaWebApplet::configChanged() +{ + callJsFunction("configChanged"); +} + +void PlasmaWebApplet::initJsObjects() +{ + QWebFrame *frame = qobject_cast(sender()); + Q_ASSERT(frame); + frame->addToJavaScriptWindowObject(QLatin1String("plasmoid"), this); +} + +QVariantList PlasmaWebApplet::geometry() +{ + return QVariantList() << applet()->geometry().left() << applet()->geometry().top() + << applet()->geometry().width() << applet()->geometry().height(); +} + +QVariantList PlasmaWebApplet::screenRect() +{ + return QVariantList() << applet()->screenRect().left() << applet()->screenRect().top() + << applet()->screenRect().width() << applet()->screenRect().height(); +} + +int PlasmaWebApplet::backgroundHints() +{ + return applet()->backgroundHints(); +} + +int PlasmaWebApplet::aspectRatioMode() +{ + return applet()->aspectRatioMode(); +} + +void PlasmaWebApplet::setConfigurationRequired(bool needsConfiguring, const QString &reason) +{ + WebApplet::setConfigurationRequired(needsConfiguring, reason); +} + +void PlasmaWebApplet::setMaximumSize(qreal w, qreal h) +{ + applet()->setMaximumSize(w, h); +} + +void PlasmaWebApplet::setMinimumSize(qreal w, qreal h) +{ + applet()->setMinimumSize(w, h); +} + +void PlasmaWebApplet::setPreferredSize(qreal w, qreal h) +{ + applet()->setPreferredSize(w, h); +} + +QVariantList PlasmaWebApplet::maximumSize() +{ + return QVariantList() << applet()->maximumSize().width() << applet()->maximumSize().height(); +} + +QVariantList PlasmaWebApplet::minimumSize() +{ + return QVariantList() << applet()->minimumSize().width() << applet()->minimumSize().height(); +} + +QVariantList PlasmaWebApplet::preferredSize() +{ + return QVariantList() << applet()->preferredSize().width() + << applet()->preferredSize().height(); +} + +QVariantList PlasmaWebApplet::getContentsMargins() +{ + qreal left; + qreal top; + qreal right; + qreal bottom; + applet()->getContentsMargins(&left, &top, &right, &bottom); + return QVariantList() << left << top << right << bottom; +} + +void PlasmaWebApplet::setGeometry(qreal x, qreal y, qreal w, qreal h) +{ + applet()->setGeometry(x, y, w, h); +} + +void PlasmaWebApplet::setPos(qreal x, qreal y) +{ + applet()->setPos(x, y); +} + +QVariantList PlasmaWebApplet::pos() +{ + return QVariantList() << applet()->pos().x() << applet()->pos().y(); +} + +QVariantList PlasmaWebApplet::size() +{ + return QVariantList() << applet()->size().width() << applet()->size().height(); +} + +void PlasmaWebApplet::setFailedToLaunch(bool failed, const QString &reason) +{ + WebApplet::setFailedToLaunch(failed, reason); +} + +void PlasmaWebApplet::update() +{ + applet()->update(); +} + +bool PlasmaWebApplet::isBusy() const +{ + return applet()->isBusy(); +} + +void PlasmaWebApplet::setBusy(bool busy) +{ + applet()->setBusy(busy); +} + +#include "plasmawebapplet.moc" diff --git a/plasma/generic/scriptengines/webkit/plasmawebapplet.h b/plasma/generic/scriptengines/webkit/plasmawebapplet.h new file mode 100644 index 00000000..90b7a326 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/plasmawebapplet.h @@ -0,0 +1,112 @@ +/* +Copyright (c) 2007 Zack Rusin +Copyright (c) 2008 Petri Damstén + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef PLASMAWEBAPPLET_H +#define PLASMAWEBAPPLET_H + +#include "webapplet.h" +#include "plasmajs.h" + +#include + +class PlasmaWebApplet : public WebApplet +{ + Q_OBJECT + Q_PROPERTY(QString name READ name) + Q_PROPERTY(uint id READ id) + Q_PROPERTY(QString pluginName READ pluginName) + Q_PROPERTY(QString icon READ icon) + Q_PROPERTY(QString category READ category) + Q_PROPERTY(int formFactor READ formFactor) + Q_PROPERTY(int location READ location) + +public: + PlasmaWebApplet(QObject *parent, const QVariantList &args); + virtual ~PlasmaWebApplet(); + + virtual bool init(); + + QString name() const; + uint id() const; + QString pluginName() const; + QString icon() const; + QString category() const; + bool shouldConserveResources() const; + int formFactor() const; + int location() const; + +public slots: + QStringList listAllDataEngines(); + QObject* dataEngine(const QString& name); + QObject* config(); + QObject* globalConfig(); + void setScrollBarPolicy(int orientation, int policy); + QVariantList screenRect(); + void setConfigurationRequired(bool needsConfiguring, const QString &reason = QString()); + QVariantList getContentsMargins(); + void resize(qreal w, qreal h); + QVariantList size(); + void setBackgroundHints(int hints); + int backgroundHints(); + void setAspectRatioMode(int mode); + int aspectRatioMode(); + void setMaximumSize(qreal w, qreal h); + QVariantList maximumSize(); + void setMinimumSize(qreal w, qreal h); + QVariantList minimumSize(); + void setPreferredSize(qreal w, qreal h); + QVariantList preferredSize(); + void setGeometry(qreal x, qreal y, qreal w, qreal h); + QVariantList geometry(); + void setPos(qreal x, qreal y); + QVariantList pos(); + void setFailedToLaunch(bool failed, const QString &reason = QString()); + void update(); + bool isBusy() const; + void setBusy(bool busy); + + QVariant arg(int index) const; + QObject* objArg(int index) const; + void dataUpdated(const QString& source, const Plasma::DataEngine::Data &data); + void configChanged(); + void themeChanged(); + void makeStylesheet(); + +protected: + QVariant callJsFunction(const QString &func, const QVariantList &args = QVariantList()); + void constraintsEvent(Plasma::Constraints constraints); + +protected slots: + virtual void loadFinished(bool success); + virtual void initJsObjects(); + +private: + QVariantList m_args; + DataEngineDataWrapper m_dataEngineData; + ConfigGroupWrapper m_config; + ConfigGroupWrapper m_globalConfig; + KTemporaryFile m_styleSheetFile; + static QString s_jsConstants; +}; + +#endif diff --git a/plasma/generic/scriptengines/webkit/tests/AppletAnimatorTest.html b/plasma/generic/scriptengines/webkit/tests/AppletAnimatorTest.html new file mode 100644 index 00000000..d450c8da --- /dev/null +++ b/plasma/generic/scriptengines/webkit/tests/AppletAnimatorTest.html @@ -0,0 +1,39 @@ + + + + + + +
    + + diff --git a/plasma/generic/scriptengines/webkit/tests/HelloWorld.zip b/plasma/generic/scriptengines/webkit/tests/HelloWorld.zip new file mode 100644 index 0000000000000000000000000000000000000000..bdada5d39c6977baa560c163e19d05104eae7c4e GIT binary patch literal 24205 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 literal 0 HcmV?d00001 diff --git a/plasma/generic/scriptengines/webkit/webapplet.cpp b/plasma/generic/scriptengines/webkit/webapplet.cpp new file mode 100644 index 00000000..0a35e4ae --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webapplet.cpp @@ -0,0 +1,154 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "webapplet.h" + +#include "webpage.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +using namespace Plasma; + +class WebApplet::Private +{ +public: + Private() + : view(0) + { + } + + void init(WebApplet *q) + { + loaded = false; + + Plasma::Applet *applet = q->applet(); + applet->setAcceptsHoverEvents(true); + + view = new Plasma::WebView(applet); + QObject::connect(view, SIGNAL(loadFinished(bool)), + q, SLOT(loadFinished(bool))); + QObject::connect(view->page(), SIGNAL(frameCreated(QWebFrame*)), + q, SLOT(connectFrame(QWebFrame*))); + q->connectFrame(view->mainFrame()); + + view->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); + view->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); + + QPalette palette = view->palette(); + palette.setColor(QPalette::Base, Qt::transparent); + view->page()->setPalette(palette); + } + + Plasma::WebView *view; + bool loaded; +}; + +WebApplet::WebApplet(QObject *parent, const QVariantList &args) + : AppletScript(parent), + d(new Private) +{ + Q_UNUSED(args) +} + +WebApplet::~WebApplet() +{ + delete d; +} + +bool WebApplet::init() +{ + d->init(this); + + QString webpage; + webpage = package()->filePath("mainscript"); + + if (webpage.isEmpty()) { + kDebug() << "fail! no page"; + delete d->view; + d->view = 0; + return false; + } + + KUrl url(package()->filePath("html")); + kDebug() << webpage << package()->path() << url; + d->view->mainFrame()->setHtml(dataFor(webpage), url); + return true; +} + +void WebApplet::paintInterface(QPainter *painter, + const QStyleOptionGraphicsItem *option, + const QRect &contentsRect) +{ + Q_UNUSED(painter) + Q_UNUSED(option) + Q_UNUSED(contentsRect) +} + +Plasma::WebView* WebApplet::view() const +{ + return d->view; +} + +void WebApplet::loadFinished(bool success) +{ + d->loaded = success; +} + +void WebApplet::connectFrame(QWebFrame *frame) +{ + connect(frame, SIGNAL(javaScriptWindowObjectCleared()), + this, SLOT(initJsObjects())); +} + +void WebApplet::initJsObjects() +{ +} + +QByteArray WebApplet::dataFor(const QString &str) +{ + QFile f(str); + f.open(QIODevice::ReadOnly); + QByteArray data = f.readAll(); + f.close(); + return data; +} + +QWebPage *WebApplet::page() +{ + return d->view ? d->view->page() : 0; +} + +bool WebApplet::loaded() +{ + return d->loaded; +} + +#include "webapplet.moc" diff --git a/plasma/generic/scriptengines/webkit/webapplet.h b/plasma/generic/scriptengines/webkit/webapplet.h new file mode 100644 index 00000000..d08620fc --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webapplet.h @@ -0,0 +1,66 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#ifndef WEBAPPLET_H +#define WEBAPPLET_H + +#include + +#include +#include + +class QWebFrame; +class QWebPage; + +namespace Plasma +{ + class WebView; +} // namespace Plasma + +class WebApplet : public Plasma::AppletScript +{ + Q_OBJECT +public: + WebApplet(QObject *parent, const QVariantList &args); + ~WebApplet(); + + bool init(); + +protected: + Plasma::WebView *view() const; + void paintInterface(QPainter *painter, + const QStyleOptionGraphicsItem *option, + const QRect &contentsRect); + virtual QByteArray dataFor(const QString &str); + QWebPage *page(); + bool loaded(); + +protected slots: + void connectFrame(QWebFrame *); + virtual void loadFinished(bool); + virtual void initJsObjects(); + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/plasma/generic/scriptengines/webkit/webapplet_package.cpp b/plasma/generic/scriptengines/webkit/webapplet_package.cpp new file mode 100644 index 00000000..11b4b5f0 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webapplet_package.cpp @@ -0,0 +1,50 @@ +/* +Copyright (c) 2008 Petri Damstén + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "webapplet_package.h" + +#include + +WebAppletPackage::WebAppletPackage(QObject *parent, QVariantList args) +: Plasma::PackageStructure(parent, "Web") +{ + Q_UNUSED(args) + // copy the main applet structure + Plasma::PackageStructure::operator=(*Plasma::Applet::packageStructure()); + addFileDefinition("mainscript", "code/main.html", i18n("Main Script File")); + setRequired("mainscript", true); + + // For Webapplet::init() + addDirectoryDefinition("html", "code/", i18n("Root HTML directory")); +} + +void WebAppletPackage::pathChanged() +{ + KDesktopFile config(path() + "/metadata.desktop"); + KConfigGroup cg = config.desktopGroup(); + QString mainScript = cg.readEntry("X-Plasma-MainScript", QString()); + if (!mainScript.isEmpty()) { + addFileDefinition("mainscript", mainScript, i18n("Main Script File")); + setRequired("mainscript", true); + } +} + diff --git a/plasma/generic/scriptengines/webkit/webapplet_package.h b/plasma/generic/scriptengines/webkit/webapplet_package.h new file mode 100644 index 00000000..671e1c5d --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webapplet_package.h @@ -0,0 +1,41 @@ +/* +Copyright (c) 2008 Petri Damstén + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef WEBAPPLET_PACKAGE_H +#define WEBAPPLET_PACKAGE_H + +#include + +#include + +class WebAppletPackage : public Plasma::PackageStructure +{ +public: + WebAppletPackage(QObject *parent, QVariantList args); + +protected: + void pathChanged(); +}; + +K_EXPORT_PLASMA_PACKAGESTRUCTURE(webkit, WebAppletPackage) + +#endif diff --git a/plasma/generic/scriptengines/webkit/webapplet_plugin.cpp b/plasma/generic/scriptengines/webkit/webapplet_plugin.cpp new file mode 100644 index 00000000..8e720e58 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webapplet_plugin.cpp @@ -0,0 +1,25 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "plasmawebapplet.h" + +K_EXPORT_PLASMA_APPLETSCRIPTENGINE(webkit, PlasmaWebApplet) + diff --git a/plasma/generic/scriptengines/webkit/webpage.cpp b/plasma/generic/scriptengines/webkit/webpage.cpp new file mode 100644 index 00000000..ea547118 --- /dev/null +++ b/plasma/generic/scriptengines/webkit/webpage.cpp @@ -0,0 +1,75 @@ +/* +Copyright (c) 2007 Zack Rusin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#include "webpage.h" + +#include +#include + +namespace Plasma +{ + +WebPage::WebPage(QObject *parent) + : QWebPage(parent) +{ + settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, false); + settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true); + settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, true); +} + +QWebPage * WebPage::createWindow(QWebPage::WebWindowType) +{ + Q_ASSERT(0); + return 0; +} + +void WebPage::javaScriptAlert(QWebFrame *frame, const QString& message) +{ + Q_UNUSED(frame) + qDebug()<< "JS ALERT: "<< message; +} + +void WebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, + const QString& sourceID) +{ + Q_UNUSED(sourceID) + qDebug()<< "JS CONSOLE MESSAGE: line "<< lineNumber<<": " << message; +} + +bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) +{ + Q_UNUSED(frame) + qDebug()<< "JS CONFIRM: "<< msg; + return true; +} + +bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, + const QString& defaultValue, QString* result) +{ + Q_UNUSED(frame) + qDebug()<<"JS PROMPT: "<< msg <<", default text: "< + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ +#ifndef WEBPAGE_H +#define WEBPAGE_H + +#include +#include + +namespace Plasma +{ + +class WebPage : public QWebPage +{ + Q_OBJECT +public: + WebPage(QObject *parent=0); + + QWebPage *createWindow(QWebPage::WebWindowType); + + void javaScriptAlert(QWebFrame *frame, const QString& message); + void javaScriptConsoleMessage(const QString& message, int lineNumber, + const QString& sourceID); + bool javaScriptConfirm(QWebFrame *frame, const QString& msg); + bool javaScriptPrompt(QWebFrame *frame, const QString& msg, + const QString& defaultValue, QString* result); +}; + +} // namespace Plasma + +#endif diff --git a/plasma/generic/shells/CMakeLists.txt b/plasma/generic/shells/CMakeLists.txt new file mode 100644 index 00000000..cbec9580 --- /dev/null +++ b/plasma/generic/shells/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(plasma-windowed) diff --git a/plasma/generic/shells/plasma-windowed/CMakeLists.txt b/plasma/generic/shells/plasma-windowed/CMakeLists.txt new file mode 100644 index 00000000..86b7770b --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/CMakeLists.txt @@ -0,0 +1,19 @@ +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace) + + +set(plasma-windowed_SRCS + singleview.cpp + main.cpp + plasmaapp.cpp + ${appletbrowserdialog_SRCS} +) + + +kde4_add_kdeinit_executable(plasma-windowed ${plasma-windowed_SRCS}) + +target_link_libraries(kdeinit_plasma-windowed ${KDE4_PLASMA_LIBS} kworkspace ${KDE4_KIO_LIBS} ${X11_LIBRARIES} ${KDE4_KFILE_LIBS} ) + + +install(TARGETS kdeinit_plasma-windowed DESTINATION ${LIB_INSTALL_DIR}) +install(TARGETS plasma-windowed ${INSTALL_TARGETS_DEFAULT_ARGS}) + diff --git a/plasma/generic/shells/plasma-windowed/Messages.sh b/plasma/generic/shells/plasma-windowed/Messages.sh new file mode 100755 index 00000000..61de9a35 --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma-windowed.pot diff --git a/plasma/generic/shells/plasma-windowed/main.cpp b/plasma/generic/shells/plasma-windowed/main.cpp new file mode 100644 index 00000000..7cdf2e3c --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/main.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include "plasmaapp.h" + +static const char description[] = I18N_NOOP( "Shell used to load Plasma widgets as stand-alone applications." ); +static const char version[] = "0.1"; + +extern "C" +KDE_EXPORT int kdemain(int argc, char **argv) +{ + KAboutData aboutData("plasma-windowed", 0, ki18n("Plasma Widgets shell"), + version, ki18n(description), KAboutData::License_GPL, + ki18n("Copyright 2006-2009, The KDE Team")); + aboutData.addAuthor(ki18n("Marco Martin"), + ki18n("Author and maintainer"), + "notmart@gmail.com"); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("b", ki18n("Show window decorations around the widget")); + options.add("noborder", ki18n("Do not show window decorations around the widget")); + options.add("f"); + options.add("fullscreen", ki18n("Display the widget fullscreen")); + options.add("+applet", ki18n("Name of applet to view; may refer to the plugin name or be a path " + "(absolute or relative) to a package. If not provided, then an " + "attempt is made to load a package from the current directory.")); + options.add("+[args]", ki18n("Optional arguments for the applet to add")); + KCmdLineArgs::addCmdLineOptions(options); + + PlasmaApp *app = PlasmaApp::self(); + QApplication::setWindowIcon(KIcon("plasma")); + int rc = app->exec(); + delete app; + return rc; +} + diff --git a/plasma/generic/shells/plasma-windowed/plasmaapp.cpp b/plasma/generic/shells/plasma-windowed/plasmaapp.cpp new file mode 100644 index 00000000..dbdff472 --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/plasmaapp.cpp @@ -0,0 +1,255 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "plasmaapp.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "singleview.h" + + +PlasmaApp* PlasmaApp::self() +{ + if (!kapp) { + return new PlasmaApp(); + } + + return qobject_cast(kapp); +} + +PlasmaApp::PlasmaApp() + : KUniqueApplication(), + m_corona(0), + m_maxId(0) +{ + KGlobal::locale()->insertCatalog("plasma-standaloneplasmoids"); + KCrash::setFlags(KCrash::AutoRestart); + + KConfigGroup cg(KGlobal::config(), "General"); + Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font())); + + corona(); + + KConfigGroup applets = storedConfig(0); + foreach (const QString &group, applets.groupList()) { + KConfigGroup appletGroup(&applets, group); + + int id = appletGroup.name().toInt(); + QString pluginName = appletGroup.readEntry("plugin", QString()); + if (id != 0 && !pluginName.isEmpty()) { + m_storedApplets.insert(pluginName, id); + m_maxId = qMax(id, m_maxId); + } + } + + //newInstance(); + connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup())); + setQuitOnLastWindowClosed(true); +} + +PlasmaApp::~PlasmaApp() +{ +} + +KConfigGroup PlasmaApp::storedConfig(int appletId) +{ + KConfigGroup cg(m_corona->config(), "StoredApplets"); + + if (appletId > 0) { + cg = KConfigGroup(&cg, QString::number(appletId)); + } + + return cg; +} + +int PlasmaApp::newInstance() +{ + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); + + if (args->count() == 0) { + KCmdLineArgs::usage(); + return 0; + } + + QString pluginName; + if (args->count() > 0) { + pluginName = args->arg(0); + } + + //is the applet already running? + if (m_viewForPlugin.contains(pluginName)) { + m_viewForPlugin.value(pluginName)->activateWindow(); + m_viewForPlugin.value(pluginName)->raise(); + return 0; + } + + QVariantList appletArgs; + for (int i = 1; i < args->count(); ++i) { + appletArgs << args->arg(i); + } + + int appletId; + Plasma::Containment *containment = m_corona->addContainment("null"); + containment->setFormFactor(Plasma::Application); + containment->setLocation(Plasma::Floating); + appletId = ++m_maxId; + + if (m_storedApplets.contains(pluginName)) { + int storedAppletId = m_storedApplets.values(pluginName).first(); + KConfigGroup config = storedConfig(storedAppletId); + + KConfigGroup actualConfig(containment->config()); + actualConfig = KConfigGroup(&actualConfig, "Applets"); + actualConfig = KConfigGroup(&actualConfig, QString::number(appletId)); + + config.copyTo(&actualConfig); + config.deleteGroup(); + m_storedApplets.remove(pluginName, storedAppletId); + } + + SingleView *view = new SingleView(m_corona, containment, pluginName, appletId, appletArgs); + + if (!view->applet()) { + delete view; + return 0; + } + + connect(view, SIGNAL(storeApplet(Plasma::Applet*)), this, SLOT(storeApplet(Plasma::Applet*))); + connect(view, SIGNAL(destroyed(QObject*)), this, SLOT(viewDestroyed(QObject*))); + + if (args->isSet("border")) { + view->setBackgroundBrush(KColorUtils::mix(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor), Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 0.15)); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged())); + view->applet()->setBackgroundHints(Plasma::Applet::NoBackground); + } else { + view->setWindowFlags(Qt::FramelessWindowHint); + view->setAttribute(Qt::WA_TranslucentBackground); + view->setAutoFillBackground(false); + view->viewport()->setAutoFillBackground(false); + view->setAttribute(Qt::WA_NoSystemBackground); + view->viewport()->setAttribute(Qt::WA_NoSystemBackground); + Plasma::WindowEffects::overrideShadow(view->winId(), true); + } + + if (args->isSet("fullscreen")) { + view->setWindowState(Qt::WindowFullScreen); + } + + args->clear(); + + m_viewForPlugin[pluginName] = view; + m_pluginForView[view] = pluginName; + KWindowSystem::setOnDesktop(view->winId(), KWindowSystem::currentDesktop()); + view->show(); + view->raise(); + + return 0; +} + + +void PlasmaApp::cleanup() +{ + if (m_corona) { + m_corona->saveLayout(); + } + + qDeleteAll(m_viewForPlugin); + + delete m_corona; + m_corona = 0; + + //TODO: This manual sync() should not be necessary? + syncConfig(); +} + +void PlasmaApp::syncConfig() +{ + KGlobal::config()->sync(); +} + +void PlasmaApp::themeChanged() +{ + foreach (SingleView *view, m_viewForPlugin) { + if (view->autoFillBackground()) { + view->setBackgroundBrush(KColorUtils::mix(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor), Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 0.15)); + } + } +} + +Plasma::Corona* PlasmaApp::corona() +{ + if (!m_corona) { + m_corona = new Plasma::Corona(this); + connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig())); + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + //m_corona->initializeLayout(); + } + + return m_corona; +} + +bool PlasmaApp::hasComposite() +{ + return KWindowSystem::compositingActive(); +} + + +void PlasmaApp::storeApplet(Plasma::Applet *applet) +{ + m_storedApplets.insert(applet->name(), applet->id()); + KConfigGroup storage = storedConfig(0); + KConfigGroup cg(applet->containment()->config()); + cg = KConfigGroup(&cg, "Applets"); + cg = KConfigGroup(&cg, QString::number(applet->id())); + delete applet; +// kDebug() << "storing" << applet->name() << applet->id() << "to" << storage.name() << ", applet config is" << cg.name(); + cg.reparent(&storage); +} + +void PlasmaApp::viewDestroyed(QObject *view) +{ + SingleView *sView = static_cast(view); + + m_viewForPlugin.remove(m_pluginForView.value(sView)); + m_pluginForView.remove(sView); + if (m_viewForPlugin.isEmpty()) { + quit(); + } +} + +#include "plasmaapp.moc" diff --git a/plasma/generic/shells/plasma-windowed/plasmaapp.h b/plasma/generic/shells/plasma-windowed/plasmaapp.h new file mode 100644 index 00000000..057d303e --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/plasmaapp.h @@ -0,0 +1,83 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_APP_H +#define PLASMA_APP_H + +#include +#include + +#include +#include + +#include + +#ifdef Q_WS_X11 +#include +#include +#endif + +namespace Plasma +{ + class Corona; + class View; + class Applet; +} // namespace Plasma + +class SingleView; + +class PlasmaApp : public KUniqueApplication +{ + Q_OBJECT +public: + ~PlasmaApp(); + + int newInstance(); + + static PlasmaApp* self(); + static bool hasComposite(); + + Plasma::Corona* corona(); + + +private: + PlasmaApp(); + +private Q_SLOTS: + void cleanup(); + void syncConfig(); + void themeChanged(); + void storeApplet(Plasma::Applet *view); + void viewDestroyed(QObject *view); + +private: + KConfigGroup storedConfig(int appletId); + + Plasma::Corona *m_corona; + QMultiHash m_storedApplets; + + int m_maxId; + + QHash m_viewForPlugin; + QHash m_pluginForView; +}; + +#endif // multiple inclusion guard + diff --git a/plasma/generic/shells/plasma-windowed/singleview.cpp b/plasma/generic/shells/plasma-windowed/singleview.cpp new file mode 100644 index 00000000..d56e6f44 --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/singleview.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "singleview.h" + +#include +#include +#include + +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +SingleView::SingleView(Plasma::Corona *corona, Plasma::Containment *containment, const QString &pluginName, int appletId, const QVariantList &appletArgs, QWidget *parent) + : QGraphicsView(parent), + m_applet(0), + m_containment(containment), + m_corona(corona) +{ + setScene(m_corona); + QFileInfo info(pluginName); + if (!info.isAbsolute()) { + info = QFileInfo(QDir::currentPath() + '/' + pluginName); + } + + if (info.exists()) { + m_applet = Plasma::Applet::loadPlasmoid(info.absoluteFilePath(), appletId, appletArgs); + } + + if (!m_applet) { + m_applet = Plasma::Applet::load(pluginName, appletId, appletArgs); + } + + if (!m_applet) { + kDebug() << "failed to load" << pluginName; + return; + } + + m_containment->addApplet(m_applet, QPointF(-1, -1), false); + m_containment->resize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + m_applet->setPos(0, 0); + m_applet->setFlag(QGraphicsItem::ItemIsMovable, false); + setSceneRect(m_applet->sceneBoundingRect()); + setWindowTitle(m_applet->name()); + setWindowIcon(SmallIcon(m_applet->icon())); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setFrameStyle(QFrame::NoFrame); + + QAction *action = m_applet->action("remove"); + delete action; + + QAction *quitAction = KStandardAction::quit(this, SLOT(close()), this); + m_applet->addAction(QString("remove"), quitAction); + addAction(quitAction); + // enforce the applet being our size + connect(m_applet, SIGNAL(geometryChanged()), this, SLOT(updateGeometry())); +} + +SingleView::~SingleView() +{ + m_containment->destroy(false); +} + + +void SingleView::setContainment(Plasma::Containment *c) +{ + if (m_containment) { + disconnect(m_containment, 0, this, 0); + } + + m_containment = c; + updateGeometry(); +} + + +void SingleView::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + updateGeometry(); + emit geometryChanged(); +} + +void SingleView::closeEvent(QCloseEvent *event) +{ + if (m_applet) { + KConfigGroup dummy; + m_containment->save(dummy); + emit storeApplet(m_applet); + m_applet = 0; + } + + QGraphicsView::closeEvent(event); + deleteLater(); +} + +Plasma::Applet *SingleView::applet() +{ + return m_applet; +} + +Plasma::Location SingleView::location() const +{ + return m_containment->location(); +} + +Plasma::FormFactor SingleView::formFactor() const +{ + return m_containment->formFactor(); +} + +void SingleView::updateGeometry() +{ + if (!m_containment) { + return; + } + + //kDebug() << "New applet geometry is" << m_applet->geometry(); + + if (m_applet) { + if (m_applet->size().toSize() != size()) { + m_applet->resize(size()); + } + + setSceneRect(m_applet->sceneBoundingRect()); + } + + if ((windowFlags() & Qt::FramelessWindowHint) && + applet()->backgroundHints() != Plasma::Applet::NoBackground) { + + // TODO: Use the background's mask for blur + QRegion mask; + mask += QRect(QPoint(), size()); + + Plasma::WindowEffects::enableBlurBehind(winId(), true, mask); + } +} + +#include "singleview.moc" + diff --git a/plasma/generic/shells/plasma-windowed/singleview.h b/plasma/generic/shells/plasma-windowed/singleview.h new file mode 100644 index 00000000..47d4d019 --- /dev/null +++ b/plasma/generic/shells/plasma-windowed/singleview.h @@ -0,0 +1,70 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SINGLEVIEW_H +#define SINGLEVIEW_H + +#include + +#include + +namespace Plasma +{ + class Containment; + class Applet; + class Corona; +} // namespace Plasma + +class SingleView; + +class SingleView : public QGraphicsView +{ + Q_OBJECT + +public: + SingleView(Plasma::Corona *corona, Plasma::Containment *containment, const QString &pluginName, int appletId, const QVariantList &appletArgs, QWidget *parent=0); + ~SingleView(); + + + Plasma::Applet *applet(); + Plasma::Location location() const; + Plasma::FormFactor formFactor() const; + +public Q_SLOTS: + void setContainment(Plasma::Containment *containment); + void updateGeometry(); + +Q_SIGNALS: + void locationChanged(const SingleView *view); + void geometryChanged(); + void containmentActivated(); + void storeApplet(Plasma::Applet *applet); + +protected: + void resizeEvent(QResizeEvent *event); + void closeEvent(QCloseEvent *event); + +private: + Plasma::Applet *m_applet; + Plasma::Containment *m_containment; + Plasma::Corona *m_corona; +}; + +#endif // multiple inclusion guard diff --git a/plasma/generic/wallpapers/CMakeLists.txt b/plasma/generic/wallpapers/CMakeLists.txt new file mode 100644 index 00000000..7a1777bb --- /dev/null +++ b/plasma/generic/wallpapers/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(color) +add_subdirectory(image) diff --git a/plasma/generic/wallpapers/color/CMakeLists.txt b/plasma/generic/wallpapers/color/CMakeLists.txt new file mode 100644 index 00000000..5ad829d8 --- /dev/null +++ b/plasma/generic/wallpapers/color/CMakeLists.txt @@ -0,0 +1,15 @@ +project(plasma-wallpaper-color) + +set(color_SRCS + color.cpp + backgrounddelegate.cpp + backgroundlistmodel.cpp + itemsview.cpp +) +kde4_add_ui_files(color_SRCS config.ui) + +kde4_add_plugin(plasma_wallpaper_color ${color_SRCS}) +target_link_libraries(plasma_wallpaper_color ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_wallpaper_color DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-wallpaper-color.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/generic/wallpapers/color/Messages.sh b/plasma/generic/wallpapers/color/Messages.sh new file mode 100755 index 00000000..ce80d610 --- /dev/null +++ b/plasma/generic/wallpapers/color/Messages.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_wallpaper_color.pot +rm -f rc.cpp + diff --git a/plasma/generic/wallpapers/color/backgrounddelegate.cpp b/plasma/generic/wallpapers/color/backgrounddelegate.cpp new file mode 100644 index 00000000..3a9e2e0a --- /dev/null +++ b/plasma/generic/wallpapers/color/backgrounddelegate.cpp @@ -0,0 +1,131 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2010 Dario Andres Rodriguez + Copyright 2012 Reza Fatahilah Shah + + 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. +*/ + +#include "backgrounddelegate.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +static const int BLUR_PAD = 6; + +BackgroundDelegate::BackgroundDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ + m_maxHeight = SCREENSHOT_SIZE/1.6 + BLUR_INCREMENT; + m_maxWidth = SCREENSHOT_SIZE + BLUR_INCREMENT; +} + +void BackgroundDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + const QString title = index.model()->data(index, Qt::DisplayRole).toString(); + const QPixmap pix = index.model()->data(index, ScreenshotRole).value(); + + // Highlight selected item + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &option, painter); + + // Draw wallpaper thumbnail + if (pix.isNull()) { + painter->fillRect(option.rect, option.palette.brush(QPalette::Base)); + } else { + // blur calculation + QImage blur(pix.size() + QSize(BLUR_INCREMENT + BLUR_PAD, BLUR_INCREMENT + BLUR_PAD), QImage::Format_ARGB32); + QRect blurRect = QRect(QPoint((blur.width() - pix.width()) / 2, (blur.height() - pix.height()) / 2), pix.size()); + blur.fill(Qt::transparent); + QPainter p(&blur); + + QColor color = option.palette.color(QPalette::Base); + bool darkBaseColor = qGray(color.rgb()) < 192; + p.fillRect(blurRect, darkBaseColor ? Qt::white : Qt::black); + p.end(); + + // apply blur with a radius of 2 as thumbnail shadow + Plasma::PaintUtils::shadowBlur(blur, 2, darkBaseColor ? Qt::white : Qt::black); + + // calculate point + const int bx = (option.rect.width() - blur.width()) / 2; + const int by = MARGIN + qMax(0, m_maxHeight - blur.height()); + QRect shadowRect = QRect(option.rect.topLeft(), blur.size()).translated(bx, by); + // draw the blur + painter->drawImage(shadowRect.topLeft(), blur); + // draw the actual thumbnail + painter->drawPixmap(QRect(shadowRect.topLeft() + QPoint((shadowRect.width() - pix.width()) / 2, (shadowRect.height() - pix.height()) / 2), + pix.size()), pix); + } + + //Use a QTextDocument to layout the text + QTextDocument document; + QString html = QString("%1").arg(title); + + //Set the text color according to the item state + QPalette::ColorGroup cg = QPalette::Active; + if (!(option.state & QStyle::State_Enabled)) { + cg = QPalette::Disabled; + } else if (!(option.state & QStyle::State_Active)) { + cg = QPalette::Inactive; + } + + QColor color; + if (option.state & QStyle::State_Selected) { + color = QApplication::palette().brush(cg, QPalette::HighlightedText).color(); + } else { + color = QApplication::palette().brush(cg, QPalette::Text).color(); + } + + html = QString("
    %2
    ").arg(color.name()).arg(html); + + document.setHtml(html); + + //Calculate positioning + int x = option.rect.left() + MARGIN; + + //Enable word-wrap + document.setTextWidth(m_maxWidth); + + //Center text on the row + int y = option.rect.top() + m_maxHeight + MARGIN * 2; //qMax(0 ,(int)((option.rect.height() - document.size().height()) / 2)); + + //Draw text + painter->save(); + painter->translate(x, y); + document.drawContents(painter, QRect(QPoint(0, 0), option.rect.size() - QSize(0, m_maxHeight + MARGIN * 2))); + painter->restore(); +} + +QSize BackgroundDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_UNUSED(option) + const QString title = index.model()->data(index, Qt::DisplayRole).toString(); + const int fontSize = KGlobalSettings::smallestReadableFont().pointSize(); + + //Generate a sample complete entry (with the real title) to calculate sizes + QTextDocument document; + QString html = QString("%1
    ").arg(title); + html += QString("1600x1200").arg(fontSize); + + document.setHtml(html); + document.setTextWidth(m_maxWidth); + + QSize s(m_maxWidth + MARGIN * 2, + m_maxHeight + MARGIN * 3 + (int)(document.size().height())); + return s; +} + diff --git a/plasma/generic/wallpapers/color/backgrounddelegate.h b/plasma/generic/wallpapers/color/backgrounddelegate.h new file mode 100644 index 00000000..3c9cd2e7 --- /dev/null +++ b/plasma/generic/wallpapers/color/backgrounddelegate.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright 2012 Reza Fatahilah Shah + + 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. +*/ + +#ifndef BACKGROUNDDELEGATE_H +#define BACKGROUNDDELEGATE_H + +#include + +class BackgroundDelegate : public QAbstractItemDelegate +{ +public: + enum { + ScreenshotRole = Qt::UserRole + }; + + BackgroundDelegate(QObject *parent = 0); + + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + static const int SCREENSHOT_SIZE = 128; + static const int BLUR_INCREMENT = 9; + static const int MARGIN = 6; + + void resetMaxHeight() { m_maxHeight = 0; } + int m_maxHeight; +private: + int m_maxWidth; +}; + +#endif // BACKGROUNDDELEGATEL_H diff --git a/plasma/generic/wallpapers/color/backgroundlistmodel.cpp b/plasma/generic/wallpapers/color/backgroundlistmodel.cpp new file mode 100644 index 00000000..4819a161 --- /dev/null +++ b/plasma/generic/wallpapers/color/backgroundlistmodel.cpp @@ -0,0 +1,131 @@ +#ifndef BACKGROUNDLISTMODEL_CPP +#define BACKGROUNDLISTMODEL_CPP +/* + Copyright (c) 2007 Paolo Capriotti + Copyright 2012 Reza Fatahilah Shah + + 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. +*/ + +#include "backgroundlistmodel.h" + +#include + +#include "backgrounddelegate.h" +#include "color.h" + +BackgroundListModel::BackgroundListModel(Color *listener, QObject *parent) + : QAbstractListModel(parent), + m_structureParent(listener) +{ + m_previewUnavailablePix.fill(Qt::transparent); +} + +BackgroundListModel::~BackgroundListModel() +{ +} + +void BackgroundListModel::reload() +{ + for (int i = 0; i < m_backgroundModes.size(); i++) { + m_previews.insert(m_backgroundModes[i], createPixmap(m_backgroundModes[i])); + } +} + +void BackgroundListModel::addColor(int mode, const QString &title) +{ + m_titles.insert(mode, title); + m_backgroundModes.append(mode); + m_previews.insert(mode, createPixmap(mode)); +} + +QModelIndex BackgroundListModel::indexOf(const int &path) const +{ + for (int i = 0; i < m_backgroundModes.size(); i++) { + if (path == m_backgroundModes[i]) { + return index(i, 0); + } + } + return QModelIndex(); +} + +int BackgroundListModel::rowCount(const QModelIndex &) const +{ + return m_backgroundModes.size(); +} + +QVariant BackgroundListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= m_backgroundModes.size()) { + return QVariant(); + } + + int mode = backgroundMode(index.row()); + + switch (role) { + case Qt::DisplayRole: { + if (m_titles.contains(mode)) { + return m_titles.value(mode); + } + + return QVariant(); + } + break; + + case BackgroundDelegate::ScreenshotRole: { + if (m_previews.contains(mode)) { + return m_previews.value(mode); + } + + const_cast(this)->m_previews.insert(mode, m_previewUnavailablePix); + return m_previewUnavailablePix; + } + break; + + default: + return QVariant(); + break; + } + return QVariant(); +} + +int BackgroundListModel::backgroundMode(int index) const +{ + return m_backgroundModes.at(index); +} + +void BackgroundListModel::setWallpaperSize(const QSize& size) +{ + float newHeight = ((float)size.height() / (float)size.width()) * BackgroundDelegate::SCREENSHOT_SIZE; + + m_size = QSize(BackgroundDelegate::SCREENSHOT_SIZE, newHeight); + + m_size.scale(BackgroundDelegate::SCREENSHOT_SIZE, BackgroundDelegate::SCREENSHOT_SIZE/1.6, Qt::KeepAspectRatio); +} + +QPixmap BackgroundListModel::createPixmap(int mode) const +{ + if (m_structureParent.isNull()) { + return QPixmap(); + } + + QPixmap scaledPixmap(m_size); + QPainter p(&scaledPixmap); + + m_structureParent.data()->generatePainting(mode, &p, scaledPixmap.rect(), scaledPixmap.rect()); + + p.end(); + + return scaledPixmap; +} +#include "backgroundlistmodel.moc" + + +#endif // BACKGROUNDLISTMODEL_CPP diff --git a/plasma/generic/wallpapers/color/backgroundlistmodel.h b/plasma/generic/wallpapers/color/backgroundlistmodel.h new file mode 100644 index 00000000..491216e7 --- /dev/null +++ b/plasma/generic/wallpapers/color/backgroundlistmodel.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright 2012 Reza Fatahilah Shah + + 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. +*/ + +#ifndef BACKGROUNDLISTMODEL_H +#define BACKGROUNDLISTMODEL_H + +#include +#include + +#include + +class Color; + +class BackgroundListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + BackgroundListModel(Color *listener, QObject *parent); + virtual ~BackgroundListModel(); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int backgroundMode(int index) const; + + void reload(); + QModelIndex indexOf(const int &path) const; + + void setWallpaperSize(const QSize& size); + void setResizeMethod(Plasma::Wallpaper::ResizeMethod resizeMethod); + + void addColor(int mode, const QString &title); + +private: + QPixmap createPixmap(int mode) const; + +private: + QWeakPointer m_structureParent; + QList m_backgroundModes; + QHash m_previews; + QHash m_titles; + QPixmap m_previewUnavailablePix; + QSize m_size; +}; + +#endif // BACKGROUNDLISTMODEL_H diff --git a/plasma/generic/wallpapers/color/color.cpp b/plasma/generic/wallpapers/color/color.cpp new file mode 100644 index 00000000..411fbd41 --- /dev/null +++ b/plasma/generic/wallpapers/color/color.cpp @@ -0,0 +1,236 @@ +/* + * Copyright 2008 by Petri Damsten + * Copyright 2012 by Reza Fatahilah Shah + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "color.h" + +#include +#include +#include + +#include "backgroundlistmodel.h" +#include "backgrounddelegate.h" + +K_EXPORT_PLASMA_WALLPAPER(color, Color) + +enum BackgroundMode { + SOLID, + HORIZONTAL, + VERTICAL, + RECTANGULAR, + RADIAL, + TOP_LEFT_DIAGONAL, + TOP_RIGHT_DIAGONAL +}; + +Color::Color(QObject *parent, const QVariantList &args) + : Plasma::Wallpaper(parent, args), + m_model(0) +{ +} + +void Color::init(const KConfigGroup &config) +{ + m_color1 = config.readEntry("color1", QColor(Qt::white)); + m_color2 = config.readEntry("color2", QColor(Qt::black)); + m_backgroundMode = config.readEntry("backgroundMode", (int)SOLID); + emit update(boundingRect()); +} + +void Color::paint(QPainter *painter, const QRectF& exposedRect) +{ + generatePainting(m_backgroundMode, painter, exposedRect, boundingRect()); +} + +QWidget* Color::createConfigurationInterface(QWidget* parent) +{ + QWidget *widget = new QWidget(parent); + + m_ui.setupUi(widget); + + m_ui.m_color1->setColor(m_color1); + m_ui.m_color2->setColor(m_color2); + + m_model = new BackgroundListModel(this, widget); + m_model->setWallpaperSize(targetSizeHint().toSize()); + m_model->addColor(0,i18n("Solid")); + m_model->addColor(1,i18n("Horizontal")); + m_model->addColor(2,i18n("Vertical")); + m_model->addColor(3,i18n("Rectangular")); + m_model->addColor(4,i18n("Radial")); + m_model->addColor(5,i18n("Top Left Diagonal")); + m_model->addColor(6,i18n("Top Right Diagonal")); + + m_ui.m_view->setItemDelegate(new BackgroundDelegate(m_ui.m_view)); + m_ui.m_view->setMinimumWidth((BackgroundDelegate::SCREENSHOT_SIZE + BackgroundDelegate::MARGIN * 2 + + BackgroundDelegate::BLUR_INCREMENT) * 3 + + m_ui.m_view->spacing() * 4 + + QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent) + + QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2 + 7); + m_ui.m_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_ui.m_view->setModel(m_model); + connect(m_ui.m_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(backgroundModeChanged(QModelIndex))); + + QModelIndex index = m_model->indexOf(m_backgroundMode); + if (index.isValid()) { + m_ui.m_view->setCurrentIndex(index); + } + + connect(m_ui.m_color1, SIGNAL(changed(QColor)), SLOT(widgetChanged())); + connect(m_ui.m_color2, SIGNAL(changed(QColor)), SLOT(widgetChanged())); + + connect(this, SIGNAL(settingsChanged(bool)), parent, SLOT(settingsChanged(bool))); + + return widget; +} + +void Color::save(KConfigGroup &config) +{ + config.writeEntry("color1", m_color1); + config.writeEntry("color2", m_color2); + config.writeEntry("backgroundMode", m_backgroundMode); +} + +void Color::backgroundModeChanged(const QModelIndex &index) +{ + if (index.row() == -1 || !m_model) { + return; + } + + m_backgroundMode = m_model->backgroundMode(index.row()); + + emit settingsChanged(true); + emit update(boundingRect()); +} + +void Color::widgetChanged() +{ + const QColor newColor1 = m_ui.m_color1->color(); + const QColor newColor2 = m_ui.m_color2->color(); + const bool updateThumbs = (m_color1 != newColor1) || (m_color2 != newColor2); + + m_color1 = newColor1; + m_color2 = newColor2; + + if (updateThumbs) { + m_model->reload(); + } + + emit settingsChanged(true); + emit update(boundingRect()); +} + +void Color::generatePainting(int mode, QPainter* painter, const QRectF& exposedRect, const QRectF& boundingRect) const +{ + switch (mode) { + case SOLID: { + painter->fillRect(exposedRect, m_color1); + break; + } + + case HORIZONTAL: { + QLinearGradient gradient = QLinearGradient(boundingRect.topLeft(), + boundingRect.topRight()); + gradient.setColorAt(0, m_color1); + gradient.setColorAt(1, m_color2); + painter->fillRect(exposedRect, gradient); + break; + } + + case VERTICAL: { + QLinearGradient gradient = QLinearGradient(boundingRect.topLeft(), + boundingRect.bottomLeft()); + gradient.setColorAt(0, m_color1); + gradient.setColorAt(1, m_color2); + painter->fillRect(exposedRect, gradient); + break; + } + + case RECTANGULAR: { + // First draw a horizontal gradient covering the whole view/screen + QLinearGradient horizontalGradient = QLinearGradient(boundingRect.topLeft(), + boundingRect.topRight()); + horizontalGradient.setColorAt(0, m_color2); + horizontalGradient.setColorAt(0.5, m_color1); + horizontalGradient.setColorAt(1, m_color2); + + painter->fillRect(exposedRect, horizontalGradient); + + // Then draw two triangles with vertical gradient + QLinearGradient verticalGradient = QLinearGradient(boundingRect.topLeft(), + boundingRect.bottomLeft()); + verticalGradient.setColorAt(0, m_color2); + verticalGradient.setColorAt(0.5, m_color1); + verticalGradient.setColorAt(1, m_color2); + painter->setBrush(verticalGradient); + painter->setPen(Qt::NoPen); + + QPolygon triangle = QPolygon(3); + + // Draw a triangle which starts from the top edge to the center + triangle.append(boundingRect.topLeft().toPoint()); + triangle.append(boundingRect.topRight().toPoint()); + triangle.append(boundingRect.center().toPoint()); + painter->drawPolygon(triangle); + + triangle.clear(); + + // Draw a triangle which starts from the bottom edge to the center + triangle.append(boundingRect.bottomLeft().toPoint()); + triangle.append(boundingRect.bottomRight().toPoint()); + triangle.append(boundingRect.center().toPoint()); + painter->drawPolygon(triangle); + + break; + } + + case RADIAL: { + // The diameter of the gradient will be the max screen dimension + int maxDimension = qMax(boundingRect.height(), boundingRect.width()); + + QRadialGradient gradient = QRadialGradient(boundingRect.center(), + maxDimension / 2, + boundingRect.center()); + gradient.setColorAt(0, m_color1); + gradient.setColorAt(1, m_color2); + painter->fillRect(exposedRect, gradient); + break; + } + + case TOP_LEFT_DIAGONAL: { + QLinearGradient gradient = QLinearGradient(boundingRect.topLeft(), + boundingRect.bottomRight()); + gradient.setColorAt(0, m_color1); + gradient.setColorAt(1, m_color2); + painter->fillRect(exposedRect, gradient); + break; + } + + case TOP_RIGHT_DIAGONAL: { + QLinearGradient gradient = QLinearGradient(boundingRect.topRight(), + boundingRect.bottomLeft()); + gradient.setColorAt(0, m_color1); + gradient.setColorAt(1, m_color2); + painter->fillRect(exposedRect, gradient); + break; + } + + } +} +#include "color.moc" diff --git a/plasma/generic/wallpapers/color/color.h b/plasma/generic/wallpapers/color/color.h new file mode 100644 index 00000000..1519cd9b --- /dev/null +++ b/plasma/generic/wallpapers/color/color.h @@ -0,0 +1,62 @@ +/* + * Copyright 2008 by Petri Damsten + * Copyright 2012 by Reza Fatahilah Shah + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef COLOR_HEADER +#define COLOR_HEADER + +#include +#include +#include "ui_config.h" + +class BackgroundListModel; + +class Color : public Plasma::Wallpaper +{ + Q_OBJECT + public: + Color(QObject* parent, const QVariantList& args); + + virtual void save(KConfigGroup &config); + virtual void paint(QPainter* painter, const QRectF& exposedRect); + virtual QWidget* createConfigurationInterface(QWidget* parent); + void generatePainting(int mode, QPainter* painter, const QRectF& exposedRect, const QRectF &boundingRect) const; + + Q_SIGNALS: + void settingsChanged(bool modified); + + protected: + virtual void init(const KConfigGroup &config); + + protected slots: + void backgroundModeChanged(const QModelIndex &index); + + private slots: + void widgetChanged(); + + private: + Ui::Config m_ui; + BackgroundListModel *m_model; + QColor m_color1; + QColor m_color2; + + int m_backgroundMode; +}; + +#endif diff --git a/plasma/generic/wallpapers/color/config.ui b/plasma/generic/wallpapers/color/config.ui new file mode 100644 index 00000000..da66736d --- /dev/null +++ b/plasma/generic/wallpapers/color/config.ui @@ -0,0 +1,176 @@ + + + Config + + + + 0 + 0 + 437 + 313 + + + + Color + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 300 + 220 + + + + QListView::Static + + + QListView::Adjust + + + QListView::Batched + + + 2 + + + QListView::IconMode + + + false + + + + + + + + 0 + 0 + + + + &Second Color: + + + + 70 + 90 + 130 + + + + + 70 + 90 + 130 + + + + + + + + Qt::Horizontal + + + + 187 + 20 + + + + + + + + + 0 + 0 + + + + + 70 + 90 + 130 + + + + + 70 + 90 + 130 + + + + + + + + + 125 + 0 + + + + &Second color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_color1 + + + + + + + + 125 + 0 + + + + &First color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_color1 + + + + + + + + KColorButton + QPushButton +
    kcolorbutton.h
    +
    + + ItemsView + QListView +
    itemsview.h
    +
    +
    + + +
    diff --git a/plasma/generic/wallpapers/color/itemsview.cpp b/plasma/generic/wallpapers/color/itemsview.cpp new file mode 100644 index 00000000..281b19ab --- /dev/null +++ b/plasma/generic/wallpapers/color/itemsview.cpp @@ -0,0 +1,32 @@ +/* + Copyright (C) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "itemsview.h" + +#include + +ItemsView::ItemsView(QWidget* parent) + : QListView(parent) +{ +} + +void ItemsView::wheelEvent(QWheelEvent* event) +{ + // this is a workaround because scrolling by mouse wheel is broken in Qt list views for big items + verticalScrollBar()->setSingleStep(10); + QListView::wheelEvent(event); +} diff --git a/plasma/generic/wallpapers/color/itemsview.h b/plasma/generic/wallpapers/color/itemsview.h new file mode 100644 index 00000000..b9bdef3b --- /dev/null +++ b/plasma/generic/wallpapers/color/itemsview.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef ITEMSVIEW_H +#define ITEMSVIEW_H + +#include + +class ItemsView: public QListView +{ +public: + ItemsView(QWidget* parent = 0); + +protected: + void wheelEvent(QWheelEvent* event); +}; + +#endif diff --git a/plasma/generic/wallpapers/color/plasma-wallpaper-color.desktop b/plasma/generic/wallpapers/color/plasma-wallpaper-color.desktop new file mode 100644 index 00000000..435c923d --- /dev/null +++ b/plasma/generic/wallpapers/color/plasma-wallpaper-color.desktop @@ -0,0 +1,135 @@ +[Desktop Entry] +Name=Color +Name[ar]=لون +Name[as]=ৰং +Name[ast]=Color +Name[be@latin]=Koler +Name[bg]=Цвят +Name[bn]=রং +Name[bn_IN]=রং +Name[bs]=boja +Name[ca]=Color +Name[ca@valencia]=Color +Name[cs]=Barva +Name[csb]=Farwa +Name[da]=Farve +Name[de]=Farbe +Name[el]=Χρώμα +Name[en_GB]=Colour +Name[eo]=Koloro +Name[es]=Color +Name[et]=Värv +Name[eu]=Kolorea +Name[fi]=Väri +Name[fr]=Couleur +Name[fy]=Kleur +Name[ga]=Dath +Name[gl]=Cor +Name[gu]=રંગ +Name[he]=צבע +Name[hi]=रंग +Name[hne]=रंग +Name[hr]=Boja +Name[hu]=Szín +Name[ia]=Color +Name[id]=Warna +Name[is]=Litur +Name[ja]=色 +Name[ka]=ფერი +Name[kk]=Түсі +Name[km]=ពណ៌ +Name[kn]=ಬಣ್ಣ +Name[ko]=색 +Name[ku]=Reng +Name[lt]=Spalvos +Name[lv]=Krāsa +Name[mai]=रंग +Name[mk]=Боја +Name[ml]=നിറം +Name[mr]=रंग +Name[nb]=Farge +Name[nds]=Klöör +Name[nl]=Kleur +Name[nn]=Farge +Name[or]=ରଙ୍ଗ +Name[pa]=ਰੰਗ +Name[pl]=Kolor +Name[pt]=Cor +Name[pt_BR]=Cor +Name[ro]=Culoare +Name[ru]=Цвет +Name[si]=වර්‍ණය +Name[sk]=Farba +Name[sl]=Barva +Name[sr]=боја +Name[sr@ijekavian]=боја +Name[sr@ijekavianlatin]=boja +Name[sr@latin]=boja +Name[sv]=Färg +Name[ta]=Color +Name[te]=రంగు +Name[tg]=Ранг +Name[th]=สี +Name[tr]=Renk +Name[ug]=رەڭ +Name[uk]=Колір +Name[vi]=Màu sắc +Name[wa]=Coleur +Name[x-test]=xxColorxx +Name[zh_CN]=颜色 +Name[zh_TW]=顏色 +Comment=A plain color or gradient +Comment[bs]=Prosta boja ili gradijent +Comment[ca]=Un color normal o degradat +Comment[ca@valencia]=Un color normal o degradat +Comment[cs]=Barva nebo barevný přechod +Comment[da]=En enkelt farve eller gradient +Comment[de]=Einfache Farbe oder Verlauf +Comment[el]=Ένα απλό χρώμα ή μια διαβάθμιση +Comment[en_GB]=A plain colour or gradient +Comment[es]=Un color liso o gradiente +Comment[et]=Puhas värv või üleminek +Comment[eu]=Kolore bakarra edo gradientea +Comment[fi]=Tasainen väri tai liukuväri +Comment[fr]=Une couleur pleine ou un dégradé +Comment[gl]=Unha cor ou gradación. +Comment[hu]=Egy homogén szín vagy színátmenet +Comment[ia]=Unn color plan o gradiente +Comment[it]=Un colore semplice o sfumatura +Comment[kk]=Жәй түс пе, градиент пе +Comment[ko]=단색이나 그라디언트 +Comment[nb]=En enkel farge eller gradient +Comment[nds]=En eenfach Klöörövergang +Comment[nl]=Een vlakke kleur of verloop +Comment[pa]=ਇਕਸਾਰ ਰੰਗ ਜਾਂ ਗਰੇਡੀਐਂਟ +Comment[pl]=Jednolity kolor lub gradient +Comment[pt]=Uma cor simples ou gradiente +Comment[pt_BR]=Cor simples ou gradiente +Comment[ro]=Culoare simplă sau gradient +Comment[ru]=Простой цвет или градиент +Comment[sk]=Jednoduchá farba alebo prechod +Comment[sl]=Preprosta barva ali preliv +Comment[sr]=Обична боја или прелив +Comment[sr@ijekavian]=Обична боја или прелив +Comment[sr@ijekavianlatin]=Obična boja ili preliv +Comment[sr@latin]=Obična boja ili preliv +Comment[sv]=En enkel färg eller toning +Comment[tr]=Düz veya gradyan bir renk +Comment[uk]=Простий колір або градієнт +Comment[x-test]=xxA plain color or gradientxx +Comment[zh_CN]=纯色或渐变色 +Comment[zh_TW]=簡單的顏色或漸層 +Type=Service +Icon=preferences-desktop-color +ServiceTypes=Plasma/Wallpaper + +X-KDE-Library=plasma_wallpaper_color +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=color +X-KDE-PluginInfo-Version=0.2 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/generic/wallpapers/image/CMakeLists.txt b/plasma/generic/wallpapers/image/CMakeLists.txt new file mode 100644 index 00000000..47183413 --- /dev/null +++ b/plasma/generic/wallpapers/image/CMakeLists.txt @@ -0,0 +1,22 @@ +project(plasma-wallpaper-image) + +set(image_SRCS + image.cpp + backgrounddelegate.cpp + backgroundlistmodel.cpp + removebuttonmanager.cpp + removebutton.cpp + itemsview.cpp +) +kde4_add_ui_files(image_SRCS imageconfig.ui slideshowconfig.ui) + +set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) +qt4_add_dbus_interface(image_SRCS ${ksmserver_xml} ksmserver_interface) + +kde4_add_plugin(plasma_wallpaper_image ${image_SRCS}) +target_link_libraries(plasma_wallpaper_image ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KNEWSTUFF3_LIBS} ${KDE4_THREADWEAVER_LIBRARY}) + +install(TARGETS plasma_wallpaper_image DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-wallpaper-image.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES wallpaper.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/plasma/generic/wallpapers/image/Messages.sh b/plasma/generic/wallpapers/image/Messages.sh new file mode 100755 index 00000000..01788de2 --- /dev/null +++ b/plasma/generic/wallpapers/image/Messages.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_wallpaper_image.pot +rm -f rc.cpp + diff --git a/plasma/generic/wallpapers/image/backgrounddelegate.cpp b/plasma/generic/wallpapers/image/backgrounddelegate.cpp new file mode 100644 index 00000000..dab0bc9e --- /dev/null +++ b/plasma/generic/wallpapers/image/backgrounddelegate.cpp @@ -0,0 +1,162 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2010 Dario Andres Rodriguez + + 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. +*/ + +#include "backgrounddelegate.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +static const int BLUR_PAD = 6; + +BackgroundDelegate::BackgroundDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ + m_maxHeight = SCREENSHOT_SIZE/1.6 + BLUR_INCREMENT; + m_maxWidth = SCREENSHOT_SIZE + BLUR_INCREMENT; +} + +void BackgroundDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + const QString title = index.model()->data(index, Qt::DisplayRole).toString(); + const QString author = index.model()->data(index, AuthorRole).toString(); + const QString resolution = index.model()->data(index, ResolutionRole).toString(); + const QPixmap pix = index.model()->data(index, ScreenshotRole).value(); + + // Highlight selected item + QStyleOptionViewItemV4 opt(option); + opt.showDecorationSelected = true; + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + + // Draw wallpaper thumbnail + if (pix.isNull()) { + painter->fillRect(option.rect, option.palette.brush(QPalette::Base)); + } else { + // blur calculation + QImage blur(pix.size() + QSize(BLUR_INCREMENT + BLUR_PAD, BLUR_INCREMENT + BLUR_PAD), QImage::Format_ARGB32); + QRect blurRect = QRect(QPoint((blur.width() - pix.width()) / 2, (blur.height() - pix.height()) / 2), pix.size()); + blur.fill(Qt::transparent); + QPainter p(&blur); + + QColor color = option.palette.color(QPalette::Base); + bool darkBaseColor = qGray(color.rgb()) < 192; + p.fillRect(blurRect, darkBaseColor ? Qt::white : Qt::black); + p.end(); + + // apply blur with a radius of 2 as thumbnail shadow + Plasma::PaintUtils::shadowBlur(blur, 2, darkBaseColor ? Qt::white : Qt::black); + + // calculate point + const int bx = (option.rect.width() - blur.width()) / 2; + const int by = MARGIN + qMax(0, m_maxHeight - blur.height()); + QRect shadowRect = QRect(option.rect.topLeft(), blur.size()).translated(bx, by); + // draw the blur + painter->drawImage(shadowRect.topLeft(), blur); + // draw the actual thumbnail + painter->drawPixmap(QRect(shadowRect.topLeft() + QPoint((shadowRect.width() - pix.width()) / 2, (shadowRect.height() - pix.height()) / 2), + pix.size()), pix); + } + + //Use a QTextDocument to layout the text + + // Borrowed from Dolphin for consistency and beauty. + // For the color of the additional info the inactive text color + // is not used as this might lead to unreadable text for some color schemes. Instead + // the text color is slightly mixed with the background color. + const QColor textColor = option.palette.text().color(); + const QColor baseColor = option.palette.base().color(); + const int p1 = 70; + const int p2 = 100 - p1; + const QColor detailsColor = QColor((textColor.red() * p1 + baseColor.red() * p2) / 100, + (textColor.green() * p1 + baseColor.green() * p2) / 100, + (textColor.blue() * p1 + baseColor.blue() * p2) / 100); + QTextDocument document; + QString html = title; + + if (!resolution.isEmpty()) { + html += QString("
    %2") + .arg(detailsColor.name()) + .arg(resolution); + } + + if (!author.isEmpty()) { + html += QString("
    %2") + .arg(detailsColor.name()) + .arg(author); + } + + //Set the text color according to the item state + QPalette::ColorGroup cg = QPalette::Active; + if (!(option.state & QStyle::State_Enabled)) { + cg = QPalette::Disabled; + } else if (!(option.state & QStyle::State_Active)) { + cg = QPalette::Inactive; + } + + QColor color; + if (option.state & QStyle::State_Selected) { + color = QApplication::palette().brush(cg, QPalette::HighlightedText).color(); + } else { + color = QApplication::palette().brush(cg, QPalette::Text).color(); + } + + html = QString("
    %2
    ").arg(color.name()).arg(html); + + document.setHtml(html); + + //Calculate positioning + int x = option.rect.left() + MARGIN; + + //Enable word-wrap + document.setTextWidth(m_maxWidth); + + //Center text on the row + int y = option.rect.top() + m_maxHeight + MARGIN * 2; //qMax(0 ,(int)((option.rect.height() - document.size().height()) / 2)); + + //Draw text + painter->save(); + painter->translate(x, y); + document.drawContents(painter, QRect(QPoint(0, 0), option.rect.size() - QSize(0, m_maxHeight + MARGIN * 2))); + painter->restore(); +} + +QSize BackgroundDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_UNUSED(option) + const QString title = index.model()->data(index, Qt::DisplayRole).toString(); + const QString author = index.model()->data(index, AuthorRole).toString(); + + //Generate a sample complete entry (with the real title) to calculate sizes + QTextDocument document; + QString html = title + "
    "; + if (!author.isEmpty()) { + html += author + "
    "; + } + html += QString("1600x1200"); + + document.setHtml(html); + document.setTextWidth(m_maxWidth); + + QSize s(m_maxWidth + MARGIN * 2, + m_maxHeight + MARGIN * 3 + (int)(document.size().height())); + return s; +} + diff --git a/plasma/generic/wallpapers/image/backgrounddelegate.h b/plasma/generic/wallpapers/image/backgrounddelegate.h new file mode 100644 index 00000000..9e38b501 --- /dev/null +++ b/plasma/generic/wallpapers/image/backgrounddelegate.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2007 Paolo Capriotti + + 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. +*/ + +#ifndef BACKGROUNDDELEGATE_H +#define BACKGROUNDDELEGATE_H + +#include + +class BackgroundDelegate : public QAbstractItemDelegate +{ +public: + enum { + AuthorRole = Qt::UserRole, + ScreenshotRole, + ResolutionRole + }; + + BackgroundDelegate(QObject *parent = 0); + + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + static const int SCREENSHOT_SIZE = 128; + static const int BLUR_INCREMENT = 9; + static const int MARGIN = 6; + + void resetMaxHeight() { m_maxHeight = 0; } + int m_maxHeight; +private: + int m_maxWidth; +}; + +#endif // BACKGROUNDDELEGATEL_H diff --git a/plasma/generic/wallpapers/image/backgroundlistmodel.cpp b/plasma/generic/wallpapers/image/backgroundlistmodel.cpp new file mode 100644 index 00000000..d79cdbb5 --- /dev/null +++ b/plasma/generic/wallpapers/image/backgroundlistmodel.cpp @@ -0,0 +1,428 @@ +#ifndef BACKGROUNDLISTMODEL_CPP +#define BACKGROUNDLISTMODEL_CPP +/* + Copyright (c) 2007 Paolo Capriotti + + 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. +*/ + +#include "backgroundlistmodel.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "backgrounddelegate.h" +#include "image.h" + +QSet BackgroundFinder::m_suffixes; + +ImageSizeFinder::ImageSizeFinder(const QString &path, QObject *parent) + : QObject(parent), + m_path(path) +{ +} + +void ImageSizeFinder::run() +{ + QImage image(m_path); + emit sizeFound(m_path, image.size()); +} + + +BackgroundListModel::BackgroundListModel(Image *listener, QObject *parent) + : QAbstractListModel(parent), + m_structureParent(listener), + m_size(0,0), + m_resizeMethod(Plasma::Wallpaper::ScaledResize) +{ + connect(&m_dirwatch, SIGNAL(deleted(QString)), this, SLOT(removeBackground(QString))); + m_previewUnavailablePix.fill(Qt::transparent); + //m_previewUnavailablePix = KIcon("unknown").pixmap(m_previewUnavailablePix.size()); +} + +BackgroundListModel::~BackgroundListModel() +{ + qDeleteAll(m_packages); +} + +void BackgroundListModel::removeBackground(const QString &path) +{ + QModelIndex index; + while ((index = indexOf(path)).isValid()) { + beginRemoveRows(QModelIndex(), index.row(), index.row()); + Plasma::Package *package = m_packages.at(index.row()); + m_packages.removeAt(index.row()); + m_sizeCache.remove(package); + m_previews.remove(package); + delete package; + endRemoveRows(); + } +} + +void BackgroundListModel::reload() +{ + reload(QStringList()); +} + +void BackgroundListModel::reload(const QStringList &selected) +{ + if (!m_packages.isEmpty()) { + beginRemoveRows(QModelIndex(), 0, m_packages.count() - 1); + qDeleteAll(m_packages); + m_packages.clear(); + m_sizeCache.clear(); + m_previews.clear(); + endRemoveRows(); + } + + if (!m_structureParent) { + return; + } + + if (!selected.isEmpty()) { + processPaths(selected); + } + + const QStringList dirs = KGlobal::dirs()->findDirs("wallpaper", ""); + kDebug() << "going looking in" << dirs; + BackgroundFinder *finder = new BackgroundFinder(m_structureParent.data(), dirs); + connect(finder, SIGNAL(backgroundsFound(QStringList,QString)), this, SLOT(backgroundsFound(QStringList,QString))); + m_findToken = finder->token(); + finder->start(); +} + +void BackgroundListModel::backgroundsFound(const QStringList &paths, const QString &token) +{ + if (token == m_findToken) { + processPaths(paths); + } +} + +void BackgroundListModel::processPaths(const QStringList &paths) +{ + if (!m_structureParent) { + return; + } + + QList newPackages; + foreach (const QString &file, paths) { + if (!contains(file) && QFile::exists(file)) { + Plasma::PackageStructure::Ptr structure = Plasma::Wallpaper::packageStructure(m_structureParent.data()); + Plasma::Package *package = new Plasma::Package(file, structure); + if (package->isValid()) { + newPackages << package; + } else { + delete package; + } + } + } + + // add new files to dirwatch + foreach (Plasma::Package *b, newPackages) { + if (!m_dirwatch.contains(b->path())) { + m_dirwatch.addFile(b->path()); + } + } + + if (!newPackages.isEmpty()) { + const int start = rowCount(); + beginInsertRows(QModelIndex(), start, start + newPackages.size()); + m_packages.append(newPackages); + endInsertRows(); + } + //kDebug() << t.elapsed(); +} + +void BackgroundListModel::addBackground(const QString& path) +{ + if (!m_structureParent || !contains(path)) { + if (!m_dirwatch.contains(path)) { + m_dirwatch.addFile(path); + } + beginInsertRows(QModelIndex(), 0, 0); + Plasma::PackageStructure::Ptr structure = Plasma::Wallpaper::packageStructure(m_structureParent.data()); + Plasma::Package *pkg = new Plasma::Package(path, structure); + m_packages.prepend(pkg); + endInsertRows(); + } +} + +QModelIndex BackgroundListModel::indexOf(const QString &path) const +{ + for (int i = 0; i < m_packages.size(); i++) { + // packages will end with a '/', but the path passed in may not + QString package = m_packages[i]->path(); + if (package.at(package.length() - 1) == '/') { + package.truncate(package.length() - 1); + } + + if (path.startsWith(package)) { + // FIXME: ugly hack to make a difference between local files in the same dir + // package->path does not contain the actual file name + if ((!m_packages[i]->structure()->contentsPrefixPaths().isEmpty()) || + (path == m_packages[i]->filePath("preferred"))) { + return index(i, 0); + } + } + } + return QModelIndex(); +} + +bool BackgroundListModel::contains(const QString &path) const +{ + return indexOf(path).isValid(); +} + +int BackgroundListModel::rowCount(const QModelIndex &) const +{ + return m_packages.size(); +} + +QSize BackgroundListModel::bestSize(Plasma::Package *package) const +{ + if (m_sizeCache.contains(package)) { + return m_sizeCache.value(package); + } + + const QString image = package->filePath("preferred"); + if (image.isEmpty()) { + return QSize(); + } + + ImageSizeFinder *finder = new ImageSizeFinder(image); + connect(finder, SIGNAL(sizeFound(QString,QSize)), this, + SLOT(sizeFound(QString,QSize))); + QThreadPool::globalInstance()->start(finder); + + QSize size(-1, -1); + const_cast(this)->m_sizeCache.insert(package, size); + return size; +} + +void BackgroundListModel::sizeFound(const QString &path, const QSize &s) +{ + if (!m_structureParent) { + return; + } + + QModelIndex index = indexOf(path); + if (index.isValid()) { + Plasma::Package *package = m_packages.at(index.row()); + m_sizeCache.insert(package, s); + m_structureParent.data()->updateScreenshot(index); + } +} + +QVariant BackgroundListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= m_packages.size()) { + return QVariant(); + } + + Plasma::Package *b = package(index.row()); + if (!b) { + return QVariant(); + } + + switch (role) { + case Qt::DisplayRole: { + QString title = b->metadata().name(); + + if (title.isEmpty()) { + return QFileInfo(b->filePath("preferred")).completeBaseName(); + } + + return title; + } + break; + + case BackgroundDelegate::ScreenshotRole: { + if (m_previews.contains(b)) { + return m_previews.value(b); + } + + KUrl file(b->filePath("preferred")); + if (!m_previewJobs.contains(file) && file.isValid()) { + KFileItemList list; + list.append(KFileItem(file, QString(), 0)); + KIO::PreviewJob* job = KIO::filePreview(list, + QSize(BackgroundDelegate::SCREENSHOT_SIZE, + BackgroundDelegate::SCREENSHOT_SIZE/1.6)); + job->setIgnoreMaximumSize(true); + connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)), + this, SLOT(showPreview(KFileItem,QPixmap))); + connect(job, SIGNAL(failed(KFileItem)), + this, SLOT(previewFailed(KFileItem))); + const_cast(this)->m_previewJobs.insert(file, QPersistentModelIndex(index)); + } + + const_cast(this)->m_previews.insert(b, m_previewUnavailablePix); + return m_previewUnavailablePix; + } + break; + + case BackgroundDelegate::AuthorRole: + return b->metadata().author(); + break; + + case BackgroundDelegate::ResolutionRole:{ + QSize size = bestSize(b); + + if (size.isValid()) { + return QString("%1x%2").arg(size.width()).arg(size.height()); + } + + return QString(); + } + break; + + default: + return QVariant(); + break; + } +} + +void BackgroundListModel::showPreview(const KFileItem &item, const QPixmap &preview) +{ + if (!m_structureParent) { + return; + } + + QPersistentModelIndex index = m_previewJobs.value(item.url()); + m_previewJobs.remove(item.url()); + + if (!index.isValid()) { + return; + } + + Plasma::Package *b = package(index.row()); + if (!b) { + return; + } + + m_previews.insert(b, preview); + //kDebug() << "preview size:" << preview.size(); + m_structureParent.data()->updateScreenshot(index); +} + +void BackgroundListModel::previewFailed(const KFileItem &item) +{ + m_previewJobs.remove(item.url()); +} + +Plasma::Package* BackgroundListModel::package(int index) const +{ + return m_packages.at(index); +} + +void BackgroundListModel::setWallpaperSize(const QSize& size) +{ + m_size = size; +} + +void BackgroundListModel::setResizeMethod(Plasma::Wallpaper::ResizeMethod resizeMethod) +{ + m_resizeMethod = resizeMethod; +} + +BackgroundFinder::BackgroundFinder(Plasma::Wallpaper *structureParent, const QStringList &paths) + : QThread(structureParent), + m_structure(Plasma::Wallpaper::packageStructure(structureParent)), + m_paths(paths), + m_token(QUuid().toString()) +{ +} + +BackgroundFinder::~BackgroundFinder() +{ + wait(); +} + +QString BackgroundFinder::token() const +{ + return m_token; +} + +const QSet &BackgroundFinder::suffixes() +{ + if(m_suffixes.isEmpty()) { + m_suffixes << "png" << "jpeg" << "jpg" << "svg" << "svgz"; + } + + return m_suffixes; +} + +void BackgroundFinder::run() +{ + //QTime t; + //t.start(); + const QSet &fileSuffixes = suffixes(); + + QStringList papersFound; + //kDebug() << "starting with" << m_paths; + + QDir dir; + dir.setFilter(QDir::AllDirs | QDir::Files | QDir::Hidden | QDir::Readable); + Plasma::Package pkg(QString(), m_structure); + + int i; + for (i = 0; i < m_paths.count(); ++i) { + const QString path = m_paths.at(i); + //kDebug() << "doing" << path; + dir.setPath(path); + const QFileInfoList files = dir.entryInfoList(); + foreach (const QFileInfo &wp, files) { + if (wp.isDir()) { + //kDebug() << "directory" << wp.fileName() << validPackages.contains(wp.fileName()); + const QString name = wp.fileName(); + if (name == "." || name == "..") { + // do nothing + continue; + } + + const QString filePath = wp.filePath(); + if (QFile::exists(filePath + "/metadata.desktop")) { + pkg.setPath(filePath); + if (pkg.isValid()) { + papersFound << pkg.path(); + continue; + //kDebug() << "gots a" << wp.filePath(); + } + } + + // add this to the directories we should be looking at + m_paths.append(filePath); + } else if (fileSuffixes.contains(wp.suffix().toLower())) { + //kDebug() << " adding image file" << wp.filePath(); + papersFound << wp.filePath(); + } + } + } + + //kDebug() << "background found!" << papersFound.size() << "in" << i << "dirs, taking" << t.elapsed() << "ms"; + emit backgroundsFound(papersFound, m_token); + deleteLater(); +} + +#include "backgroundlistmodel.moc" + + +#endif // BACKGROUNDLISTMODEL_CPP diff --git a/plasma/generic/wallpapers/image/backgroundlistmodel.h b/plasma/generic/wallpapers/image/backgroundlistmodel.h new file mode 100644 index 00000000..8ec913b3 --- /dev/null +++ b/plasma/generic/wallpapers/image/backgroundlistmodel.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 2007 Paolo Capriotti + + 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. +*/ + +#ifndef BACKGROUNDLISTMODEL_H +#define BACKGROUNDLISTMODEL_H + +#include +#include +#include +#include + +#include +#include + +#include + +class QEventLoop; +class KProgressDialog; + +namespace Plasma +{ + class Package; +} // namespace Plasma + +class Image; + +class ImageSizeFinder : public QObject, public QRunnable +{ + Q_OBJECT + public: + ImageSizeFinder(const QString &path, QObject *parent = 0); + void run(); + + Q_SIGNALS: + void sizeFound(const QString &path, const QSize &size); + + private: + QString m_path; +}; + +class BackgroundListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + BackgroundListModel(Image *listener, QObject *parent); + virtual ~BackgroundListModel(); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + Plasma::Package *package(int index) const; + + void reload(); + void reload(const QStringList &selected); + void addBackground(const QString &path); + QModelIndex indexOf(const QString &path) const; + virtual bool contains(const QString &bg) const; + + void setWallpaperSize(const QSize& size); + void setResizeMethod(Plasma::Wallpaper::ResizeMethod resizeMethod); + +protected Q_SLOTS: + void removeBackground(const QString &path); + void showPreview(const KFileItem &item, const QPixmap &preview); + void previewFailed(const KFileItem &item); + void sizeFound(const QString &path, const QSize &s); + void backgroundsFound(const QStringList &paths, const QString &token); + void processPaths(const QStringList &paths); + +private: + QSize bestSize(Plasma::Package *package) const; + + QWeakPointer m_structureParent; + QList m_packages; + QHash m_sizeCache; + QHash m_previews; + QHash m_previewJobs; + KDirWatch m_dirwatch; + + QSize m_size; + Plasma::Wallpaper::ResizeMethod m_resizeMethod; + QString m_findToken; + QPixmap m_previewUnavailablePix; +}; + +class BackgroundFinder : public QThread +{ + Q_OBJECT + +public: + BackgroundFinder(Plasma::Wallpaper *structureParent, const QStringList &p); + ~BackgroundFinder(); + + QString token() const; + + static const QSet &suffixes(); + +signals: + void backgroundsFound(const QStringList &paths, const QString &token); + +protected: + void run(); + +private: + Plasma::PackageStructure::Ptr m_structure; + QStringList m_paths; + QString m_token; + + static QSet m_suffixes; +}; + +#endif // BACKGROUNDLISTMODEL_H diff --git a/plasma/generic/wallpapers/image/image.cpp b/plasma/generic/wallpapers/image/image.cpp new file mode 100644 index 00000000..02b4e6b8 --- /dev/null +++ b/plasma/generic/wallpapers/image/image.cpp @@ -0,0 +1,935 @@ +/* + Copyright (c) 2007 by Paolo Capriotti + Copyright (c) 2007 by Aaron Seigo + Copyright (c) 2008 by Alexis Ménard + Copyright (c) 2008 by Petri Damsten + + 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. +*/ + +#include "image.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "backgroundlistmodel.h" +#include "backgrounddelegate.h" +#include "removebuttonmanager.h" +#include "ksmserver_interface.h" + +K_EXPORT_PLASMA_WALLPAPER(image, Image) + +Image::Image(QObject *parent, const QVariantList &args) + : Plasma::Wallpaper(parent, args), + m_delay(10), + m_dirWatch(0), + m_scanDirty(false), + m_configWidget(0), + m_wallpaperPackage(0), + m_currentSlide(-1), + m_fadeValue(0), + m_animation(0), + m_model(0), + m_dialog(0), + m_nextWallpaperAction(0), + m_openImageAction(0) +{ + connect(this, SIGNAL(renderCompleted(QImage)), this, SLOT(wallpaperRenderComplete(QImage))); + connect(this, SIGNAL(renderHintsChanged()), this, SLOT(checkSize())); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(nextSlide())); + connect(&m_delayedRenderTimer, SIGNAL(timeout()), this, SLOT(actuallyRenderWallpaper())); + m_delayedRenderTimer.setSingleShot(true); +} + +Image::~Image() +{ + delete m_animation; +} + +void Image::init(const KConfigGroup &config) +{ + m_timer.stop(); + + if (renderingMode().name().isEmpty()) { + m_mode = "SingleImage"; + } else { + m_mode = renderingMode().name(); + } + + calculateGeometry(); + + m_delay = config.readEntry("slideTimer", 10); + setResizeMethodHint((ResizeMethod)config.readEntry("wallpaperposition", (int)ScaledResize)); + m_wallpaper = config.readEntry("wallpaper", QString()); + if (m_wallpaper.isEmpty()) { + useSingleImageDefaults(); + } + + m_color = config.readEntry("wallpapercolor", QColor(Qt::black)); + m_usersWallpapers = config.readEntry("userswallpapers", QStringList()); + QStringList dirs = config.readEntry("slidepaths", QStringList()); + + if (dirs.isEmpty()) { + dirs << KStandardDirs::installPath("wallpaper"); + } + + setUsingRenderingCache(m_mode == "SingleImage"); + + if (m_mode == "SingleImage") { + setSingleImage(); + setContextualActions(QList()); + } else { + m_nextWallpaperAction = new QAction(KIcon("user-desktop"), i18n("Next Wallpaper Image"), this); + connect(m_nextWallpaperAction, SIGNAL(triggered(bool)), this, SLOT(nextSlide())); + m_openImageAction = new QAction(KIcon("document-open"), i18n("Open Wallpaper Image"), this); + connect(m_openImageAction, SIGNAL(triggered(bool)), this, SLOT(openSlide())); + QTimer::singleShot(200, this, SLOT(startSlideshow())); + updateDirWatch(dirs); + QList actions; + actions.push_back(m_nextWallpaperAction); + actions.push_back(m_openImageAction); + setContextualActions(actions); + updateWallpaperActions(); + } +} + +void Image::useSingleImageDefaults() +{ + m_wallpaper = Plasma::Theme::defaultTheme()->wallpaperPath(); + int index = m_wallpaper.indexOf("/contents/images/"); + if (index > -1) { // We have file from package -> get path to package + m_wallpaper = m_wallpaper.left(index); + } +} + +void Image::save(KConfigGroup &config) +{ + config.writeEntry("slideTimer", m_delay); + config.writeEntry("wallpaperposition", (int)resizeMethodHint()); + config.writeEntry("slidepaths", m_dirs); + config.writeEntry("wallpaper", m_wallpaper); + config.writeEntry("wallpapercolor", m_color); + config.writeEntry("userswallpapers", m_usersWallpapers); +} + +void Image::configWidgetDestroyed() +{ + m_configWidget = 0; + m_model = 0; +} + +QWidget* Image::createConfigurationInterface(QWidget* parent) +{ + m_configWidget = new QWidget(parent); + connect(m_configWidget, SIGNAL(destroyed(QObject*)), this, SLOT(configWidgetDestroyed())); + + if (m_mode == "SingleImage") { + m_uiImage.setupUi(m_configWidget); + + m_model = new BackgroundListModel(this, m_configWidget); + m_model->setResizeMethod(resizeMethodHint()); + m_model->setWallpaperSize(m_size); + m_model->reload(m_usersWallpapers); + QTimer::singleShot(0, this, SLOT(setConfigurationInterfaceModel())); + m_uiImage.m_view->setItemDelegate(new BackgroundDelegate(m_uiImage.m_view)); + //FIXME: setting the minimum width is rather ugly, but this gets us 3 columns of papers + //which looks quite good as a default. the magic number 7 at the end of the calculation is + //evidently making up for some other PM involved in the QListView that isn't being caught. + //if a cleaner way can be found to achieve all this, that would be great + m_uiImage.m_view->setMinimumWidth((BackgroundDelegate::SCREENSHOT_SIZE + BackgroundDelegate::MARGIN * 2 + + BackgroundDelegate::BLUR_INCREMENT) * 3 + + m_uiImage.m_view->spacing() * 4 + + QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent) + + QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2 + 7); + m_uiImage.m_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + RemoveButtonManager *rmManager = new RemoveButtonManager(m_uiImage.m_view, &m_usersWallpapers); + connect(rmManager, SIGNAL(removeClicked(QString)), this, SLOT(removeWallpaper(QString))); + + m_uiImage.m_pictureUrlButton->setIcon(KIcon("document-open")); + connect(m_uiImage.m_pictureUrlButton, SIGNAL(clicked()), this, SLOT(showFileDialog())); + + m_uiImage.m_resizeMethod->addItem(i18n("Scaled & Cropped"), ScaledAndCroppedResize); + m_uiImage.m_resizeMethod->addItem(i18n("Scaled"), ScaledResize); + m_uiImage.m_resizeMethod->addItem(i18n("Scaled, keep proportions"), MaxpectResize); + m_uiImage.m_resizeMethod->addItem(i18n("Centered"), CenteredResize); + m_uiImage.m_resizeMethod->addItem(i18n("Tiled"), TiledResize); + m_uiImage.m_resizeMethod->addItem(i18n("Center Tiled"), CenterTiledResize); + for (int i = 0; i < m_uiImage.m_resizeMethod->count(); ++i) { + if (resizeMethodHint() == m_uiImage.m_resizeMethod->itemData(i).value()) { + m_uiImage.m_resizeMethod->setCurrentIndex(i); + break; + } + } + connect(m_uiImage.m_resizeMethod, SIGNAL(currentIndexChanged(int)), + this, SLOT(positioningChanged(int))); + + m_uiImage.m_color->setColor(m_color); + //Color button is useless with some resize methods + m_uiImage.m_color->setEnabled(resizeMethodHint() == MaxpectResize || resizeMethodHint() == CenteredResize); + connect(m_uiImage.m_color, SIGNAL(changed(QColor)), this, SLOT(colorChanged(QColor))); + + m_uiImage.m_newStuff->setIcon(KIcon("get-hot-new-stuff")); + connect(m_uiImage.m_newStuff, SIGNAL(clicked()), this, SLOT(getNewWallpaper())); + + connect(m_uiImage.m_color, SIGNAL(changed(QColor)), this, SLOT(modified())); + connect(m_uiImage.m_resizeMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(modified())); + connect(m_uiImage.m_view, SIGNAL(clicked(QModelIndex)), this, SLOT(modified())); + + } else { + m_uiSlideshow.setupUi(m_configWidget); + m_uiSlideshow.m_newStuff->setIcon(KIcon("get-hot-new-stuff")); + m_uiSlideshow.m_dirlist->clear(); + m_uiSlideshow.m_systemCheckBox->setChecked(false); + m_uiSlideshow.m_downloadedCheckBox->setChecked(false); + + QString systemPath = KStandardDirs::installPath("wallpaper"); + QString localPath = KGlobal::dirs()->saveLocation("wallpaper"); + + foreach (const QString &dir, m_dirs) { + if (dir == KStandardDirs::installPath("wallpaper")) { + m_uiSlideshow.m_systemCheckBox->setChecked(true); + } else if (dir == localPath) { + m_uiSlideshow.m_downloadedCheckBox->setChecked(true); + } else { + m_uiSlideshow.m_dirlist->addItem(dir); + } + } + m_uiSlideshow.m_dirlist->setCurrentRow(0); + updateDirs(); + m_uiSlideshow.m_addDir->setIcon(KIcon("list-add")); + connect(m_uiSlideshow.m_addDir, SIGNAL(clicked()), this, SLOT(addDir())); + m_uiSlideshow.m_removeDir->setIcon(KIcon("list-remove")); + connect(m_uiSlideshow.m_removeDir, SIGNAL(clicked()), this, SLOT(removeDir())); + + QTime time(0, 0, 0); + time = time.addSecs(m_delay); + m_uiSlideshow.m_slideshowDelay->setTime(time); + m_uiSlideshow.m_slideshowDelay->setMinimumTime(QTime(0, 0, 10)); + connect(m_uiSlideshow.m_slideshowDelay, SIGNAL(timeChanged(QTime)), + this, SLOT(timeChanged(QTime))); + + m_uiSlideshow.m_resizeMethod->addItem(i18n("Scaled & Cropped"), ScaledAndCroppedResize); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Scaled"), ScaledResize); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Scaled, keep proportions"), MaxpectResize); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Centered"), CenteredResize); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Tiled"), TiledResize); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Center Tiled"), CenterTiledResize); + for (int i = 0; i < m_uiSlideshow.m_resizeMethod->count(); ++i) { + if (resizeMethodHint() == m_uiSlideshow.m_resizeMethod->itemData(i).value()) { + m_uiSlideshow.m_resizeMethod->setCurrentIndex(i); + break; + } + } + connect(m_uiSlideshow.m_resizeMethod, SIGNAL(currentIndexChanged(int)), + this, SLOT(positioningChanged(int))); + + m_uiSlideshow.m_color->setColor(m_color); + //Color button is useless with some resize methods + m_uiSlideshow.m_color->setEnabled(resizeMethodHint() == MaxpectResize || resizeMethodHint() == CenteredResize); + connect(m_uiSlideshow.m_color, SIGNAL(changed(QColor)), this, SLOT(colorChanged(QColor))); + connect(m_uiSlideshow.m_newStuff, SIGNAL(clicked()), this, SLOT(getNewWallpaper())); + + connect(m_uiSlideshow.m_systemCheckBox, SIGNAL(toggled(bool)), + this, SLOT(systemCheckBoxToggled(bool))); + connect(m_uiSlideshow.m_downloadedCheckBox, SIGNAL(toggled(bool)), + this, SLOT(downloadedCheckBoxToggled(bool))); + connect(m_uiSlideshow.m_color, SIGNAL(changed(QColor)), this, SLOT(modified())); + connect(m_uiSlideshow.m_resizeMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(modified())); + connect(m_uiSlideshow.m_addDir, SIGNAL(clicked()), this, SLOT(modified())); + connect(m_uiSlideshow.m_removeDir, SIGNAL(clicked()), this, SLOT(modified())); + connect(m_uiSlideshow.m_slideshowDelay, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(modified())); + connect(m_uiSlideshow.m_dirlist, SIGNAL(currentRowChanged(int)), SLOT(updateDirs())); + } + + connect(this, SIGNAL(settingsChanged(bool)), parent, SLOT(settingsChanged(bool))); + return m_configWidget; +} + +void Image::systemCheckBoxToggled(bool checked) +{ + if (checked) { + m_dirs << KStandardDirs::installPath("wallpaper"); + } else { + m_dirs.removeAll(KStandardDirs::installPath("wallpaper")); + } + modified(); +} + +void Image::downloadedCheckBoxToggled(bool checked) +{ + if (checked) { + m_dirs << KGlobal::dirs()->saveLocation("wallpaper"); + } else { + m_dirs.removeAll(KGlobal::dirs()->saveLocation("wallpaper")); + } + modified(); +} + +void Image::setConfigurationInterfaceModel() +{ + m_uiImage.m_view->setModel(m_model); + connect(m_uiImage.m_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(pictureChanged(QModelIndex))); + + QModelIndex index = m_model->indexOf(m_wallpaper); + if (index.isValid()) { + m_uiImage.m_view->setCurrentIndex(index); + } +} + +void Image::modified() +{ + emit settingsChanged(true); +} + +void Image::calculateGeometry() +{ + m_size = boundingRect().size().toSize(); + + if (m_model) { + m_model->setWallpaperSize(m_size); + } +} + +void Image::paint(QPainter *painter, const QRectF& exposedRect) +{ + // Check if geometry changed + //kDebug() << m_size << boundingRect().size().toSize(); + if (m_pixmap.isNull()) { + painter->fillRect(exposedRect, QBrush(m_color)); + //kDebug() << "pixmap null"; + return; + } + + if (painter->worldMatrix() == QMatrix()) { + // draw the background untransformed when possible;(saves lots of per-pixel-math) + painter->resetTransform(); + } + + // blit the background (saves all the per-pixel-products that blending does) + painter->setCompositionMode(QPainter::CompositionMode_Source); + + // for pixmaps we draw only the exposed part (untransformed since the + // bitmapBackground already has the size of the viewport) + painter->drawPixmap(exposedRect, m_pixmap, exposedRect.translated(-boundingRect().topLeft())); + + if (!m_oldFadedPixmap.isNull()) { + // Put old faded image on top. + painter->setCompositionMode(QPainter::CompositionMode_SourceAtop); + painter->drawPixmap(exposedRect, m_oldFadedPixmap, + exposedRect.translated(-boundingRect().topLeft())); + } +} + +void Image::timeChanged(const QTime& time) +{ + m_delay = QTime(0, 0, 0).secsTo(time); + if (!m_slideshowBackgrounds.isEmpty()) { + m_timer.start(m_delay * 1000); + } +} + +void Image::addDir() +{ + KUrl empty; + KDirSelectDialog *dialog = new KDirSelectDialog(empty, true, m_configWidget); + connect(dialog, SIGNAL(accepted()), this, SLOT(addDirFromSelectionDialog())); + dialog->show(); +} + +void Image::addDirFromSelectionDialog() +{ + KDirSelectDialog *dialog = qobject_cast(sender()); + if (dialog) { + QString urlDir = dialog->url().path(); + if (!urlDir.isEmpty() && m_uiSlideshow.m_dirlist->findItems(urlDir, Qt::MatchExactly).isEmpty()) { + m_uiSlideshow.m_dirlist->addItem(urlDir); + updateDirs(); + startSlideshow(); + } + } +} + +void Image::removeDir() +{ + int row = m_uiSlideshow.m_dirlist->currentRow(); + if (row != -1) { + m_uiSlideshow.m_dirlist->takeItem(row); + updateDirs(); + startSlideshow(); + } +} + +void Image::updateDirs() +{ + m_dirs.clear(); + + if (m_uiSlideshow.m_systemCheckBox->isChecked()) { + m_dirs << KStandardDirs::installPath("wallpaper"); + } + if (m_uiSlideshow.m_downloadedCheckBox->isChecked()) { + m_dirs << KGlobal::dirs()->saveLocation("wallpaper"); + } + + const int dirCount = m_uiSlideshow.m_dirlist->count(); + for (int i = 0; i < dirCount; ++i) { + m_dirs.append(m_uiSlideshow.m_dirlist->item(i)->text()); + } + + m_uiSlideshow.m_removeDir->setEnabled(m_uiSlideshow.m_dirlist->currentRow() != -1); +} + +void Image::updateDirWatch(const QStringList &newDirs) +{ + if (isPreviewing()) { + return; + } + + if (!m_dirWatch) { + m_dirWatch = new KDirWatch(this); + connect(m_dirWatch, SIGNAL(created(QString)), SLOT(pathCreated(QString))); + connect(m_dirWatch, SIGNAL(dirty(QString)), SLOT(pathDirty(QString))); + connect(m_dirWatch, SIGNAL(deleted(QString)), SLOT(pathDeleted(QString))); + } + + foreach (const QString &oldDir, m_dirs) { + if (!newDirs.contains(oldDir)) { + m_dirWatch->removeDir(oldDir); + } + } + + foreach (const QString &newDir, newDirs) { + if (!m_dirWatch->contains(newDir)) { + m_dirWatch->addDir(newDir, KDirWatch::WatchSubDirs | KDirWatch::WatchFiles); + } + } + + m_dirWatch->startScan(); + m_dirs = newDirs; +} + +void Image::setSingleImage() +{ + if (isPreviewing()) { + return; + } + + if (m_wallpaper.isEmpty()) { + useSingleImageDefaults(); + } + + QString img; + + if (QDir::isAbsolutePath(m_wallpaper)) { + Plasma::Package b(m_wallpaper, packageStructure(this)); + img = b.filePath("preferred"); + //kDebug() << img << m_wallpaper; + + if (img.isEmpty() && QFile::exists(m_wallpaper)) { + img = m_wallpaper; + } + } else { + //if it's not an absolute path, check if it's just a wallpaper name + const QString path = KStandardDirs::locate("wallpaper", m_wallpaper + "/metadata.desktop"); + + if (!path.isEmpty()) { + QDir dir(path); + dir.cdUp(); + + Plasma::Package b(dir.path(), packageStructure(this)); + img = b.filePath("preferred"); + } + } + + if (img.isEmpty()) { + // ok, so the package we have failed to work out; let's try the default + // if we have already + const QString wallpaper = m_wallpaper; + useSingleImageDefaults(); + if (wallpaper != m_wallpaper) { + setSingleImage(); + } + } + + if (!m_size.isEmpty()) { + renderWallpaper(img); + } +} + +void Image::addUrls(const KUrl::List &urls) +{ + bool first = true; + foreach (const KUrl &url, urls) { + // set the first drop as the current paper, just add the rest to the roll + addUrl(url, first); + first = false; + } +} + +void Image::addUrl(const KUrl &url, bool setAsCurrent) +{ + ///kDebug() << "droppage!" << url << url.isLocalFile(); + if (url.isLocalFile()) { + const QString path = url.toLocalFile(); + if (setAsCurrent) { + setWallpaper(path); + } else { + if (m_mode != "SingleImage") { + // it's a slide show, add it to the slide show + m_slideshowBackgrounds.append(path); + m_unseenSlideshowBackgrounds.append(path); + } + + // always add it to the user papers, though + if (!m_usersWallpapers.contains(path)) { + m_usersWallpapers.append(path); + } + } + } else { + QString wallpaperPath = KGlobal::dirs()->locateLocal("wallpaper", url.fileName()); + + if (!wallpaperPath.isEmpty()) { + KIO::FileCopyJob *job = KIO::file_copy(url, KUrl(wallpaperPath)); + if (setAsCurrent) { + connect(job, SIGNAL(result(KJob*)), this, SLOT(setWallpaperRetrieved(KJob*))); + } else { + connect(job, SIGNAL(result(KJob*)), this, SLOT(addWallpaperRetrieved(KJob*))); + } + } + } +} + +void Image::setWallpaperRetrieved(KJob *job) +{ + KIO::FileCopyJob *copyJob = qobject_cast(job); + if (copyJob && !copyJob->error()) { + setWallpaper(copyJob->destUrl().toLocalFile()); + } +} + +void Image::addWallpaperRetrieved(KJob *job) +{ + KIO::FileCopyJob *copyJob = qobject_cast(job); + if (copyJob && !copyJob->error()) { + addUrl(copyJob->destUrl(), false); + } +} + +void Image::setWallpaper(const QString &path) +{ + if (m_mode == "SingleImage") { + m_wallpaper = path; + setSingleImage(); + } else { + m_slideshowBackgrounds.append(path); + m_unseenSlideshowBackgrounds.clear(); + m_currentSlide = -1; + nextSlide(); + updateWallpaperActions(); + } + + if (!m_usersWallpapers.contains(path)) { + m_usersWallpapers.append(path); + } +} + +void Image::startSlideshow() +{ + if (isPreviewing()) { + return; + } + + if (m_findToken.isEmpty()) { + // populate background list + m_timer.stop(); + m_slideshowBackgrounds.clear(); + m_unseenSlideshowBackgrounds.clear(); + BackgroundFinder *finder = new BackgroundFinder(this, m_dirs); + m_findToken = finder->token(); + connect(finder, SIGNAL(backgroundsFound(QStringList,QString)), this, SLOT(backgroundsFound(QStringList,QString))); + finder->start(); + //TODO: what would be cool: paint on the wallpaper itself a busy widget and perhaps some text + //about loading wallpaper slideshow while the thread runs + } else { + m_scanDirty = true; + } +} + +void Image::backgroundsFound(const QStringList &paths, const QString &token) +{ + if (token != m_findToken) { + return; + } + + m_findToken.clear(); + + if(m_scanDirty) { + m_scanDirty = false; + startSlideshow(); + return; + } + + m_slideshowBackgrounds = paths; + m_unseenSlideshowBackgrounds.clear(); + updateWallpaperActions(); + // start slideshow + if (m_slideshowBackgrounds.isEmpty()) { + // no image has been found, which is quite weird... try again later (this is useful for events which + // are not detected by KDirWatch, like a NFS directory being mounted) + QTimer::singleShot(1000, this, SLOT(startSlideshow())); + m_pixmap = QPixmap(); + emit update(boundingRect()); + } else { + m_currentSlide = -1; + nextSlide(); + m_timer.start(m_delay * 1000); + } +} + +void Image::updateWallpaperActions() +{ + if (m_nextWallpaperAction) { + m_nextWallpaperAction->setEnabled(!m_slideshowBackgrounds.isEmpty()); + } + + if (m_openImageAction) { + m_openImageAction->setEnabled(!m_slideshowBackgrounds.isEmpty()); + } +} + +void Image::getNewWallpaper() +{ + if (!m_newStuffDialog) { + m_newStuffDialog = new KNS3::DownloadDialog( "wallpaper.knsrc", m_configWidget ); + connect(m_newStuffDialog.data(), SIGNAL(accepted()), SLOT(newStuffFinished())); + } + m_newStuffDialog.data()->show(); +} + +void Image::newStuffFinished() +{ + if (m_model && (!m_newStuffDialog || m_newStuffDialog.data()->changedEntries().size() > 0)) { + m_model->reload(); + } +} + +void Image::colorChanged(const QColor& color) +{ + m_color = color; + setSingleImage(); +} + +void Image::pictureChanged(const QModelIndex &index) +{ + if (index.row() == -1 || !m_model) { + return; + } + + Plasma::Package *b = m_model->package(index.row()); + if (!b) { + return; + } + + if (b->structure()->contentsPrefixPaths().isEmpty()) { + // it's not a full package, but a single paper + m_wallpaper = b->filePath("preferred"); + } else { + m_wallpaper = b->path(); + } +} + +void Image::positioningChanged(int index) +{ + if (m_mode == "SingleImage") { + setResizeMethodHint((ResizeMethod)m_uiImage.m_resizeMethod->itemData(index).value()); + setSingleImage(); + } else { + setResizeMethodHint((ResizeMethod)m_uiSlideshow.m_resizeMethod->itemData(index).value()); + startSlideshow(); + } + + //Color button is useless with some resize methods + const bool colorizable = resizeMethodHint() == MaxpectResize || resizeMethodHint() == CenteredResize; + if (m_mode == "SingleImage") { + m_uiImage.m_color->setEnabled(colorizable); + } else { + m_uiSlideshow.m_color->setEnabled(colorizable); + } + + if (m_model) { + m_model->setResizeMethod(resizeMethodHint()); + } +} + +void Image::showFileDialog() +{ + if (!m_dialog) { + KUrl baseUrl; + if(m_wallpaper.indexOf(QDir::homePath()) > -1){ + baseUrl = KUrl(m_wallpaper); + } + + m_dialog = new KFileDialog(baseUrl, "*.png *.jpeg *.jpg *.xcf *.svg *.svgz *.bmp", m_configWidget); + m_dialog->setOperationMode(KFileDialog::Opening); + m_dialog->setInlinePreviewShown(true); + m_dialog->setCaption(i18n("Select Wallpaper Image File")); + m_dialog->setModal(false); + + connect(m_dialog, SIGNAL(okClicked()), this, SLOT(wallpaperBrowseCompleted())); + connect(m_dialog, SIGNAL(destroyed(QObject*)), this, SLOT(fileDialogFinished())); + } + + m_dialog->show(); + m_dialog->raise(); + m_dialog->activateWindow(); +} + +void Image::fileDialogFinished() +{ + m_dialog = 0; +} + +void Image::wallpaperBrowseCompleted() +{ + Q_ASSERT(m_model); + + const QFileInfo info(m_dialog->selectedFile()); + + //the full file path, so it isn't broken when dealing with symlinks + const QString wallpaper = info.canonicalFilePath(); + + if (wallpaper.isEmpty()) { + return; + } + + if (m_model->contains(wallpaper)) { + m_uiImage.m_view->setCurrentIndex(m_model->indexOf(wallpaper)); + return; + } + + // add background to the model + m_model->addBackground(wallpaper); + + // select it + QModelIndex index = m_model->indexOf(wallpaper); + if (index.isValid()) { + m_uiImage.m_view->setCurrentIndex(index); + pictureChanged(index); + modified(); + } + + // save it + m_usersWallpapers << wallpaper; +} + +void Image::nextSlide() +{ + if (m_slideshowBackgrounds.isEmpty()) { + return; + } + + QString previousPath; + if (m_currentSlide > -1 && m_currentSlide < m_unseenSlideshowBackgrounds.size()) { + previousPath = m_unseenSlideshowBackgrounds.takeAt(m_currentSlide); + } + + if (m_unseenSlideshowBackgrounds.isEmpty()) { + m_unseenSlideshowBackgrounds = m_slideshowBackgrounds; + + // We're filling the queue again, make sure we can't pick up again + // the last one picked from the previous set + if (!previousPath.isEmpty()) { + m_unseenSlideshowBackgrounds.removeAll(previousPath); + + // prevent empty list + if (m_unseenSlideshowBackgrounds.isEmpty()) { + m_unseenSlideshowBackgrounds = m_slideshowBackgrounds; + } + } + } + + m_currentSlide = KRandom::random() % m_unseenSlideshowBackgrounds.size(); + const QString currentPath = m_unseenSlideshowBackgrounds.at(m_currentSlide); + + if (!m_wallpaperPackage) { + m_wallpaperPackage = new Plasma::Package(currentPath, packageStructure(this)); + } else { + m_wallpaperPackage->setPath(currentPath); + } + + m_timer.stop(); + renderWallpaper(m_wallpaperPackage->filePath("preferred")); + m_timer.start(m_delay * 1000); +} + +void Image::openSlide() +{ + if (!m_wallpaperPackage) { + return; + } + + // open in image viewer + KUrl filepath(m_wallpaperPackage->filePath("preferred")); + //kDebug() << "opening file " << filepath.path(); + new KRun(filepath, NULL); +} + +void Image::renderWallpaper(const QString& image) +{ + if (!image.isEmpty()) { + m_img = image; + } + + if (m_img.isEmpty()) { + return; + } + + m_delayedRenderTimer.start(100); +} + +void Image::actuallyRenderWallpaper() +{ + render(m_img, m_size, resizeMethodHint(), m_color); +} + +void Image::pathCreated(const QString &path) +{ + if (!m_slideshowBackgrounds.contains(path)) { + QFileInfo fileInfo(path); + if (fileInfo.isFile() && BackgroundFinder::suffixes().contains(fileInfo.suffix().toLower())) { + m_slideshowBackgrounds.append(path); + m_unseenSlideshowBackgrounds.append(path); + if (m_slideshowBackgrounds.count() == 1) { + nextSlide(); + } + } + } +} + +void Image::pathDirty(const QString &path) +{ + if (path == m_img) { + renderWallpaper(path); + } +} + +void Image::pathDeleted(const QString &path) +{ + if (m_slideshowBackgrounds.removeAll(path)) { + m_unseenSlideshowBackgrounds.removeAll(path); + if (path == m_img) { + nextSlide(); + } + } +} + +void Image::wallpaperRenderComplete(const QImage &img) +{ + m_oldPixmap = m_pixmap; + m_oldFadedPixmap = m_oldPixmap; + m_pixmap = QPixmap::fromImage(img); + + if (!m_oldPixmap.isNull()) { + if (!m_animation) { + m_animation = new QPropertyAnimation(this, "fadeValue"); + m_animation->setProperty("easingCurve", QEasingCurve::OutQuad); + m_animation->setProperty("duration", 300); + m_animation->setProperty("startValue", 0.2); + m_animation->setProperty("endValue", 1.0); + } + + m_animation->start(); + setFadeValue(0.1); + } else { + emit update(boundingRect()); + } +} + +void Image::updateScreenshot(QPersistentModelIndex index) +{ + m_uiImage.m_view->update(index); +} + +qreal Image::fadeValue() const +{ + return m_fadeValue; +} + +void Image::setFadeValue(qreal value) +{ + m_fadeValue = value; + + //If we are done, delete the pixmaps and don't draw. + if (qFuzzyCompare(m_fadeValue, qreal(1.0))) { + m_oldFadedPixmap = QPixmap(); + m_oldPixmap = QPixmap(); + emit update(boundingRect()); + return; + } + + //Create the faded image. + m_oldFadedPixmap.fill(Qt::transparent); + + QPainter p; + p.begin(&m_oldFadedPixmap); + p.drawPixmap(0, 0, m_oldPixmap); + + p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + p.fillRect(m_oldFadedPixmap.rect(), QColor(0, 0, 0, 254 * (1-m_fadeValue)));//255*((150 - m_fadeValue)/150))); + + p.end(); + + emit update(boundingRect()); +} + +//FIXME: we have to save the configuration also when the dialog cancel button is clicked. +void Image::removeWallpaper(QString name) +{ + int wallpaperIndex = m_usersWallpapers.indexOf(name); + if (wallpaperIndex >= 0){ + m_usersWallpapers.removeAt(wallpaperIndex); + m_model->reload(m_usersWallpapers); + //TODO: save the configuration in the right way + emit settingsChanged(true); + } +} + +bool Image::checkSize() +{ + if (m_size != boundingRect().size().toSize()) { + calculateGeometry(); + if (!m_size.isEmpty()) { // We have a size set + if (m_mode == "SingleImage") { + // make sure we pick the best size wallpaper for the new size + setSingleImage(); + } else { + renderWallpaper(); + } + //kDebug() << "re-rendering"; + } + + return false; + } + + return true; +} + +#include "image.moc" diff --git a/plasma/generic/wallpapers/image/image.h b/plasma/generic/wallpapers/image/image.h new file mode 100644 index 00000000..49271e8f --- /dev/null +++ b/plasma/generic/wallpapers/image/image.h @@ -0,0 +1,142 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2008 by Petri Damsten + + 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. +*/ + +#ifndef IMAGE_HEADER +#define IMAGE_HEADER + +#include +#include +#include + +#include +#include + +#include "ui_imageconfig.h" +#include "ui_slideshowconfig.h" + +class QPropertyAnimation; + +class KDirWatch; +class KFileDialog; +class KJob; + +namespace KNS3 { + class DownloadDialog; +} + +class BackgroundListModel; + +class Image : public Plasma::Wallpaper +{ + Q_OBJECT + Q_PROPERTY(qreal fadeValue READ fadeValue WRITE setFadeValue) + + public: + Image(QObject* parent, const QVariantList& args); + ~Image(); + + virtual void save(KConfigGroup &config); + virtual void paint(QPainter* painter, const QRectF& exposedRect); + virtual QWidget* createConfigurationInterface(QWidget* parent); + void updateScreenshot(QPersistentModelIndex index); + qreal fadeValue() const; + + signals: + void settingsChanged(bool); + + protected slots: + void removeWallpaper(QString name); + void timeChanged(const QTime& time); + void positioningChanged(int index); + void addDir(); + void removeDir(); + void getNewWallpaper(); + void colorChanged(const QColor& color); + void pictureChanged(const QModelIndex &); + void wallpaperBrowseCompleted(); + void nextSlide(); + /** + * Open the current slide in the default image application + */ + void openSlide(); + void wallpaperRenderComplete(const QImage &img); + void showFileDialog(); + void setFadeValue(qreal value); + void configWidgetDestroyed(); + void startSlideshow(); + void modified(); + void fileDialogFinished(); + void addUrl(const KUrl &url, bool setAsCurrent); + void addUrls(const KUrl::List &urls); + void setWallpaper(const QString &path); + void setWallpaperRetrieved(KJob *job); + void addWallpaperRetrieved(KJob *job); + void newStuffFinished(); + void setConfigurationInterfaceModel(); + void updateDirs(); + void updateDirWatch(const QStringList &newDirs); + void addDirFromSelectionDialog(); + void systemCheckBoxToggled(bool); + void downloadedCheckBoxToggled(bool); + void pathCreated(const QString &path); + void pathDirty(const QString &path); + void pathDeleted(const QString &path); + void backgroundsFound(const QStringList &paths, const QString &token); + bool checkSize(); + void actuallyRenderWallpaper(); + + protected: + void init(const KConfigGroup &config); + void renderWallpaper(const QString& image = QString()); + void suspendStartup(bool suspend); // for ksmserver + void calculateGeometry(); + void setSingleImage(); + void updateWallpaperActions(); + void useSingleImageDefaults(); + + private: + static bool s_startupResumed; + static bool s_startupSuspended; + + int m_delay; + QStringList m_dirs; + QString m_wallpaper; + QColor m_color; + QStringList m_usersWallpapers; + KDirWatch *m_dirWatch; + bool m_scanDirty; + + QWidget* m_configWidget; + Ui::ImageConfig m_uiImage; + Ui::SlideshowConfig m_uiSlideshow; + QString m_mode; + Plasma::Package *m_wallpaperPackage; + QStringList m_slideshowBackgrounds; + QStringList m_unseenSlideshowBackgrounds; + QTimer m_timer; + QTimer m_delayedRenderTimer; + QPixmap m_pixmap; + QPixmap m_oldPixmap; + QPixmap m_oldFadedPixmap; + int m_currentSlide; + qreal m_fadeValue; + QPropertyAnimation *m_animation; + BackgroundListModel *m_model; + KFileDialog *m_dialog; + QSize m_size; + QString m_img; + QWeakPointer m_newStuffDialog; + QString m_findToken; + + QAction* m_nextWallpaperAction; + QAction* m_openImageAction; +}; + +#endif diff --git a/plasma/generic/wallpapers/image/imageconfig.ui b/plasma/generic/wallpapers/image/imageconfig.ui new file mode 100644 index 00000000..7c0dc2f6 --- /dev/null +++ b/plasma/generic/wallpapers/image/imageconfig.ui @@ -0,0 +1,194 @@ + + + ImageConfig + + + + 0 + 0 + 568 + 379 + + + + + + + + 300 + 220 + + + + QListView::Static + + + QListView::Adjust + + + QListView::Batched + + + 2 + + + QListView::IconMode + + + false + + + + + + + P&ositioning: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_resizeMethod + + + + + + + &Color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_color + + + + + + + + + + 0 + 0 + + + + Change wallpaper frame color + + + Change the color of the frame that it may be visible when the wallpaper is centered or scaled with the same proportions. + + + + 70 + 90 + 130 + + + + + 70 + 90 + 130 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 187 + 17 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Open... + + + + + + + + + Get New Wallpapers... + + + + + + + + ItemsView + QListView +
    itemsview.h
    +
    + + KPushButton + QPushButton +
    kpushbutton.h
    +
    + + KColorButton + QPushButton +
    kcolorbutton.h
    +
    +
    + + +
    diff --git a/plasma/generic/wallpapers/image/itemsview.cpp b/plasma/generic/wallpapers/image/itemsview.cpp new file mode 100644 index 00000000..281b19ab --- /dev/null +++ b/plasma/generic/wallpapers/image/itemsview.cpp @@ -0,0 +1,32 @@ +/* + Copyright (C) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "itemsview.h" + +#include + +ItemsView::ItemsView(QWidget* parent) + : QListView(parent) +{ +} + +void ItemsView::wheelEvent(QWheelEvent* event) +{ + // this is a workaround because scrolling by mouse wheel is broken in Qt list views for big items + verticalScrollBar()->setSingleStep(10); + QListView::wheelEvent(event); +} diff --git a/plasma/generic/wallpapers/image/itemsview.h b/plasma/generic/wallpapers/image/itemsview.h new file mode 100644 index 00000000..1a497357 --- /dev/null +++ b/plasma/generic/wallpapers/image/itemsview.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2010 Frederik Gladhorn + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef ITEMSVIEW_H +#define ITEMSVIEW_H + +#include + +class ItemsView: public QListView +{ +public: + ItemsView(QWidget* parent = 0); + +protected: + void wheelEvent(QWheelEvent* event); +}; + +#endif diff --git a/plasma/generic/wallpapers/image/plasma-wallpaper-image.desktop b/plasma/generic/wallpapers/image/plasma-wallpaper-image.desktop new file mode 100644 index 00000000..c4a633f0 --- /dev/null +++ b/plasma/generic/wallpapers/image/plasma-wallpaper-image.desktop @@ -0,0 +1,341 @@ +[Desktop Entry] +Type=Service +Name=Image +Name[ar]=صورة +Name[ast]=Imaxe +Name[be@latin]=Vyjava +Name[bg]=Изображение +Name[bn]=ছবি +Name[bn_IN]=ছবি +Name[bs]=slika +Name[ca]=Imatge +Name[ca@valencia]=Imatge +Name[cs]=Obrázek +Name[csb]=Òbrôzk +Name[da]=Billede +Name[de]=Bild +Name[el]=Εικόνα +Name[en_GB]=Image +Name[eo]=Bildo +Name[es]=Imagen +Name[et]=Pilt +Name[eu]=Irudia +Name[fa]=تصویر +Name[fi]=Kuva +Name[fr]=Image +Name[fy]=Ofbylding +Name[ga]=Íomhá +Name[gl]=Imaxe +Name[gu]=ચિત્ર +Name[he]=תמונה +Name[hi]=छवि +Name[hne]=फोटो +Name[hr]=Slika +Name[hu]=Kép +Name[ia]=Image +Name[id]=Gambar +Name[is]=Mynd +Name[it]=Immagine +Name[ja]=画像 +Name[ka]=გამოსახულება +Name[kk]=Кескіні +Name[km]=រូបភាព +Name[kn]=ಬಿಂಬ (ಇಮೇಜ್) +Name[ko]=그림 +Name[ku]=Wêne +Name[lt]=Paveikslėlis +Name[lv]=Attēls +Name[mai]=चित्र +Name[mk]=Слика +Name[ml]=ചിത്രം +Name[mr]=प्रतिमा +Name[nb]=Bilde +Name[nds]=Bild +Name[nl]=Afbeelding +Name[nn]=Bilete +Name[or]=ପ୍ରତିଛବି +Name[pa]=ਚਿੱਤਰ +Name[pl]=Obraz +Name[pt]=Imagem +Name[pt_BR]=Imagem +Name[ro]=Imagine +Name[ru]=Изображение +Name[si]=පිංතූරය +Name[sk]=Obrázok +Name[sl]=Slika +Name[sr]=слика +Name[sr@ijekavian]=слика +Name[sr@ijekavianlatin]=slika +Name[sr@latin]=slika +Name[sv]=Bild +Name[ta]=Image +Name[tg]=Тасвир +Name[th]=ภาพ +Name[tr]=Resim +Name[ug]=سۈرەت +Name[uk]=Зображення +Name[vi]=Ảnh +Name[wa]=Imådje +Name[x-test]=xxImagexx +Name[zh_CN]=图像 +Name[zh_TW]=影像 +Icon=image-jpeg +ServiceTypes=Plasma/Wallpaper +Actions=SingleImage;Slideshow; + +X-KDE-Library=plasma_wallpaper_image +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=image +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +MimeType=image/jpeg;image/png;image/svg+xml;image/svg+xml-compressed;image/bmp; +X-Plasma-DropMimeTypes=image/jpeg,image/png,image/svg+xml,image/svg+xml-compressed,image/bmp + +[Desktop Action SingleImage] +Name=Image +Name[ar]=صورة +Name[ast]=Imaxe +Name[be@latin]=Vyjava +Name[bg]=Изображение +Name[bn]=ছবি +Name[bn_IN]=ছবি +Name[bs]=slika +Name[ca]=Imatge +Name[ca@valencia]=Imatge +Name[cs]=Obrázek +Name[csb]=Òbrôzk +Name[da]=Billede +Name[de]=Bild +Name[el]=Εικόνα +Name[en_GB]=Image +Name[eo]=Bildo +Name[es]=Imagen +Name[et]=Pilt +Name[eu]=Irudia +Name[fa]=تصویر +Name[fi]=Kuva +Name[fr]=Image +Name[fy]=Ofbylding +Name[ga]=Íomhá +Name[gl]=Imaxe +Name[gu]=ચિત્ર +Name[he]=תמונה +Name[hi]=छवि +Name[hne]=फोटो +Name[hr]=Slika +Name[hu]=Kép +Name[ia]=Image +Name[id]=Gambar +Name[is]=Mynd +Name[it]=Immagine +Name[ja]=画像 +Name[ka]=გამოსახულება +Name[kk]=Кескіні +Name[km]=រូបភាព +Name[kn]=ಬಿಂಬ (ಇಮೇಜ್) +Name[ko]=그림 +Name[ku]=Wêne +Name[lt]=Paveikslėlis +Name[lv]=Attēls +Name[mai]=चित्र +Name[mk]=Слика +Name[ml]=ചിത്രം +Name[mr]=प्रतिमा +Name[nb]=Bilde +Name[nds]=Bild +Name[nl]=Afbeelding +Name[nn]=Bilete +Name[or]=ପ୍ରତିଛବି +Name[pa]=ਚਿੱਤਰ +Name[pl]=Obraz +Name[pt]=Imagem +Name[pt_BR]=Imagem +Name[ro]=Imagine +Name[ru]=Изображение +Name[si]=පිංතූරය +Name[sk]=Obrázok +Name[sl]=Slika +Name[sr]=слика +Name[sr@ijekavian]=слика +Name[sr@ijekavianlatin]=slika +Name[sr@latin]=slika +Name[sv]=Bild +Name[ta]=Image +Name[tg]=Тасвир +Name[th]=ภาพ +Name[tr]=Resim +Name[ug]=سۈرەت +Name[uk]=Зображення +Name[vi]=Ảnh +Name[wa]=Imådje +Name[x-test]=xxImagexx +Name[zh_CN]=图像 +Name[zh_TW]=影像 +Icon=image-jpeg +Comment=A single image +Comment[bs]=Prosta slika +Comment[ca]=Una única imatge +Comment[ca@valencia]=Una única imatge +Comment[cs]=Jeden obrázek +Comment[da]=Et enkelt billede +Comment[de]=Ein einzelnes Bild +Comment[el]=Μια εικόνα μόνο +Comment[en_GB]=A single image +Comment[es]=Una única imagen +Comment[et]=Üks pilt +Comment[eu]=Irudi bakuna +Comment[fi]=Yksi kuva +Comment[fr]=Une image simple +Comment[gl]=Unha imaxe. +Comment[hu]=Egy egyszerű kép +Comment[ia]=Un imagine singule +Comment[kk]=Жалғыз кескін +Comment[ko]=단일 그림 +Comment[nb]=Ett enkelt bilde +Comment[nds]=En eenfach Bild +Comment[nl]=Een enkele afbeelding +Comment[pa]=ਇੱਕਲਾ ਚਿੱਤਰ +Comment[pl]=Pojedynczy obraz +Comment[pt]=Uma imagem simples +Comment[pt_BR]=Imagem simples +Comment[ru]=Одно изображение +Comment[sk]=Jednoduchý obrázok +Comment[sl]=Ena slika +Comment[sr]=Једна слика +Comment[sr@ijekavian]=Једна слика +Comment[sr@ijekavianlatin]=Jedna slika +Comment[sr@latin]=Jedna slika +Comment[sv]=En enda bild +Comment[tr]=Tek bir resim +Comment[uk]=Окреме зображення +Comment[x-test]=xxA single imagexx +Comment[zh_CN]=单个图像 +Comment[zh_TW]=單一影像 +# Dummy +Exec=plasma + +[Desktop Action Slideshow] +Name=Slideshow +Name[ar]=عرض شرائح +Name[ast]=Presentación +Name[be@latin]=Słajdy +Name[bg]=Прожекция +Name[bn]=স্লাইড-শো +Name[bn_IN]=স্লাইড-শো +Name[bs]=slajd‑šou +Name[ca]=Passi de diapositives +Name[ca@valencia]=Passe de diapositives +Name[cs]=Promítání +Name[csb]=Pòkôz slajdów +Name[da]=Diasshow +Name[de]=Diaschau +Name[el]=Προβολή σλάιντ +Name[en_GB]=Slideshow +Name[eo]=Bildoserio +Name[es]=Presentación +Name[et]=Slaidiseanss +Name[eu]=Diaporama +Name[fi]=Diaesitys +Name[fr]=Diaporama +Name[fy]=Diafoarstelling +Name[ga]=Taispeántas Sleamhnán +Name[gl]=Presentación +Name[gu]=સ્લાઇડશો +Name[he]=מצגת +Name[hi]=स्लाइड-शो +Name[hne]=स्लाइडसो +Name[hr]=Prezentacija +Name[hu]=Diabemutató +Name[ia]=Slideshow (Sequentia de diapositivas) +Name[id]=Salindia +Name[is]=Skyggnusýning +Name[it]=Presentazione +Name[ja]=スライドショー +Name[kk]=Слайд көрсетілімі +Name[km]=បញ្ចាំង​ស្លាយ +Name[kn]=ಚಿತ್ರಫಲಕ ಪ್ರದರ್ಶನ (ಸ್ಲೈಡ್ ಶೋ) +Name[ko]=슬라이드 쇼 +Name[ku]=NîşandanaSlaydê +Name[lt]=Skaidrių peržiūra +Name[lv]=Slīdrāde +Name[mai]=स्लाइडशो +Name[mk]=Слајдшоу +Name[ml]=മാറുന്ന ചിത്രങ്ങള്‍ +Name[mr]=स्लाइडशो +Name[nb]=Lysbildevisning +Name[nds]=Diaschau +Name[nl]=Diavoorstelling +Name[nn]=Lysbiletvising +Name[or]=ସ୍ଲାଇଡ଼ ଦୃଶ୍ୟ +Name[pa]=ਸਲਾਈਡ-ਸ਼ੋ +Name[pl]=Pokaz slajdów +Name[pt]=Apresentação +Name[pt_BR]=Apresentação de slides +Name[ro]=Diapozitiv +Name[ru]=Слайд-шоу +Name[si]=ස්ලයිඩ් දසුන +Name[sk]=Prezentácia +Name[sl]=Predstavitev +Name[sr]=слајд‑шоу +Name[sr@ijekavian]=слајд‑шоу +Name[sr@ijekavianlatin]=slajd‑šou +Name[sr@latin]=slajd‑šou +Name[sv]=Bildspel +Name[ta]=Slideshow +Name[tg]=Намоиши слайдҳо +Name[th]=นำเสนอภาพนิ่ง +Name[tr]=Slayt Gösterisi +Name[ug]=تام تەسۋىرى +Name[uk]=Показ слайдів +Name[wa]=Diaporama +Name[x-test]=xxSlideshowxx +Name[zh_CN]=幻灯显示 +Name[zh_TW]=投影播放 +Comment=Cycles through a set of images +Comment[bs]=Ciklus kroz skup slika +Comment[ca]=Passa a través d'un conjunt d'imatges +Comment[ca@valencia]=Passa a través d'un conjunt d'imatges +Comment[cs]=Prochází sadu obrázků +Comment[da]=Gennemgår et sæt af billeder +Comment[de]=Durchläuft einen Satz Bilder +Comment[el]=Επανάληψη μιας σειράς εικόνων +Comment[en_GB]=Cycles through a set of images +Comment[es]=Repetir un conjunto de imágenes +Comment[et]=Pildivaliku läbikerimine +Comment[eu]=Irudi multzo batekin zikloa osatzen du +Comment[fi]=Käy läpi kuvasarjaa +Comment[fr]=Un cycle d'une série d'images +Comment[gl]=Mostra unha serie de imaxes unha detrás da outra. +Comment[hu]=Ciklikusan változtatja a képek halmazát +Comment[ia]=Il cycla trans un unsimul de imagines +Comment[kk]=Кескін жиынын қайталай беру +Comment[ko]=여러 그림 사이를 순환하기 +Comment[nb]=Roterer gjennom et sett bilder +Comment[nds]=Geiht en Sett vun Biller dör +Comment[nl]=Circuleert door een set afbeeldingen +Comment[pa]=ਚਿੱਤਰਾਂ ਦੇ ਸਮੂਹ ਵਿੱਚੋਂ +Comment[pl]=Krąży po zestawie obrazów +Comment[pt]=Percorre um conjunto de imagens +Comment[pt_BR]=Percorre um conjunto de imagens +Comment[ru]=Циклическая смена изображений +Comment[sk]=Cyklus cez sadu obrázkov +Comment[sl]=Kroži po naboru slik +Comment[sr]=Кружење кроз скуп слика +Comment[sr@ijekavian]=Кружење кроз скуп слика +Comment[sr@ijekavianlatin]=Kruženje kroz skup slika +Comment[sr@latin]=Kruženje kroz skup slika +Comment[sv]=Går igenom en uppsättning bilder +Comment[tr]=Birden fazla resim arasında gezinir +Comment[uk]=Циклічне відтворення набору зображень +Comment[x-test]=xxCycles through a set of imagesxx +Comment[zh_CN]=在一系列图像间循环 +Comment[zh_TW]=許多影像循環播放 +Icon=folder-image +# Dummy +Exec=plasma + diff --git a/plasma/generic/wallpapers/image/removebutton.cpp b/plasma/generic/wallpapers/image/removebutton.cpp new file mode 100644 index 00000000..dbe7e7e2 --- /dev/null +++ b/plasma/generic/wallpapers/image/removebutton.cpp @@ -0,0 +1,230 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz * + * Copyright (C) 2010 by Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "removebutton.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +RemoveButton::RemoveButton(QWidget* parent) : + QAbstractButton(parent), + m_isHovered(false), + m_leftMouseButtonPressed(false), + m_fadingValue(0), + m_icon(), + m_fadingTimeLine(0) +{ + setFocusPolicy(Qt::NoFocus); + parent->installEventFilter(this); + resize(sizeHint()); + connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), + this, SLOT(refreshIcon())); + + m_icon = KIconLoader::global()->loadIcon("edit-delete", + KIconLoader::NoGroup, + qMin(width(), height())); + setToolTip(i18n("Remove from list")); +} + +RemoveButton::~RemoveButton() +{ +} + +QSize RemoveButton::sizeHint() const +{ + return QSize(32, 32); +} + +void RemoveButton::reset() +{ + m_itemName = ""; + hide(); +} + +void RemoveButton::setVisible(bool visible) +{ + QAbstractButton::setVisible(visible); + + stopFading(); + if (visible) { + startFading(); + } + +} + +bool RemoveButton::eventFilter(QObject* obj, QEvent* event) +{ + if (obj == parent()) { + switch (event->type()) { + case QEvent::Leave: + hide(); + break; + + case QEvent::MouseMove: + if (m_leftMouseButtonPressed) { + // Don't forward mouse move events to the viewport, + // otherwise a rubberband selection will be shown when + // clicking on the selection removeButton and moving the mouse + // above the viewport. + return true; + } + break; + + default: + break; + } + } + + return QAbstractButton::eventFilter(obj, event); +} + +void RemoveButton::enterEvent(QEvent* event) +{ + QAbstractButton::enterEvent(event); + + // if the mouse cursor is above the selection removeButton, display + // it immediately without fading timer + m_isHovered = true; + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + } + m_fadingValue = 255; + + update(); +} + +void RemoveButton::leaveEvent(QEvent* event) +{ + QAbstractButton::leaveEvent(event); + m_isHovered = false; + update(); +} + +void RemoveButton::mousePressEvent(QMouseEvent* event) +{ + QAbstractButton::mousePressEvent(event); + m_leftMouseButtonPressed = (event->buttons() & Qt::LeftButton); +} + +void RemoveButton::mouseReleaseEvent(QMouseEvent* event) +{ + QAbstractButton::mouseReleaseEvent(event); + m_leftMouseButtonPressed = (event->buttons() & Qt::LeftButton); +} + +void RemoveButton::resizeEvent(QResizeEvent* event) +{ + QAbstractButton::resizeEvent(event); + + m_icon = KIconLoader::global()->loadIcon("edit-delete", + KIconLoader::NoGroup, + qMin(width(), height())); + update(); +} + +void RemoveButton::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + painter.setClipRect(event->rect()); + + // draw the icon overlay + if (m_isHovered) { + KIconEffect iconEffect; + QPixmap activeIcon = iconEffect.apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState); + painter.drawPixmap(0, 0, activeIcon); + } else { + if (m_fadingValue < 255) { + // apply an alpha mask respecting the fading value to the icon + QPixmap icon = m_icon; + QPixmap alphaMask(icon.width(), icon.height()); + const QColor color(m_fadingValue, m_fadingValue, m_fadingValue); + alphaMask.fill(color); + icon.setAlphaChannel(alphaMask); + painter.drawPixmap(0, 0, icon); + } else { + // no fading is required + painter.drawPixmap(0, 0, m_icon); + } + } +} + +void RemoveButton::setFadingValue(int value) +{ + m_fadingValue = value; + if (m_fadingValue >= 255) { + Q_ASSERT(m_fadingTimeLine != 0); + m_fadingTimeLine->stop(); + } + update(); +} + +void RemoveButton::refreshIcon() +{ + m_icon = KIconLoader::global()->loadIcon("edit-delete", + KIconLoader::NoGroup, + qMin(width(), height())); + update(); +} + +void RemoveButton::startFading() +{ + Q_ASSERT(m_fadingTimeLine == 0); + + const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects; + const int duration = animate ? 600 : 1; + + m_fadingTimeLine = new QTimeLine(duration, this); + connect(m_fadingTimeLine, SIGNAL(frameChanged(int)), + this, SLOT(setFadingValue(int))); + m_fadingTimeLine->setFrameRange(0, 255); + m_fadingTimeLine->start(); + m_fadingValue = 0; +} + +void RemoveButton::stopFading() +{ + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + delete m_fadingTimeLine; + m_fadingTimeLine = 0; + } + m_fadingValue = 0; +} + +void RemoveButton::setItemName(const QString& name) +{ + m_itemName = name; +} + +QString RemoveButton::itemName() const +{ + return m_itemName; +} + +#include "removebutton.moc" diff --git a/plasma/generic/wallpapers/image/removebutton.h b/plasma/generic/wallpapers/image/removebutton.h new file mode 100644 index 00000000..536ebc9d --- /dev/null +++ b/plasma/generic/wallpapers/image/removebutton.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz * + * Copyright (C) 2010 by Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef SELECTIONTOGGLE_H +#define SELECTIONTOGGLE_H + +#include + +#include +#include + +class QTimeLine; + +/** + * @brief Toggle button for changing the selection of an hovered item. + * + * The removeButton button is visually invisible until it is displayed at least + * for one second. + * + * @see RemoveButtonManager + */ +class RemoveButton : public QAbstractButton +{ + Q_OBJECT + +public: + explicit RemoveButton(QWidget* parent); + virtual ~RemoveButton(); + virtual QSize sizeHint() const; + + /** + * Resets the selection removeButton so that it is hidden and stays + * visually invisible for at least one second after it is shown again. + */ + void reset(); + void setItemName(const QString& name); + QString itemName() const; + +public slots: + virtual void setVisible(bool visible); + +protected: + virtual bool eventFilter(QObject* obj, QEvent* event); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void resizeEvent(QResizeEvent* event); + virtual void paintEvent(QPaintEvent* event); + +private slots: + /** + * Sets the alpha value for the fading animation and is + * connected with m_fadingTimeLine. + */ + void setFadingValue(int value); + + void refreshIcon(); + +private: + void startFading(); + void stopFading(); + +private: + bool m_isHovered; + bool m_leftMouseButtonPressed; + int m_fadingValue; + QPixmap m_icon; + QTimeLine* m_fadingTimeLine; + QString m_itemName; +}; + +#endif diff --git a/plasma/generic/wallpapers/image/removebuttonmanager.cpp b/plasma/generic/wallpapers/image/removebuttonmanager.cpp new file mode 100644 index 00000000..def212a9 --- /dev/null +++ b/plasma/generic/wallpapers/image/removebuttonmanager.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz * + * Copyright (C) 2010 by Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "removebuttonmanager.h" + +#include "removebutton.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "backgroundlistmodel.h" +#include + +RemoveButtonManager::RemoveButtonManager(QAbstractItemView* parent, QStringList *list) : + QObject(parent), + m_view(parent), + m_removeButton(0), + m_connected(false) +{ + m_removableWallpapers = list; + + parent->setMouseTracking(true); + + connect(parent, SIGNAL(entered(QModelIndex)), + this, SLOT(slotEntered(QModelIndex))); + connect(parent, SIGNAL(viewportEntered()), + this, SLOT(slotViewportEntered())); + m_removeButton = new RemoveButton(m_view->viewport()); + m_removeButton->hide(); + connect(m_removeButton, SIGNAL(clicked(bool)), + this, SLOT(removeButtonClicked())); +} + +RemoveButtonManager::~RemoveButtonManager() +{ +} + +void RemoveButtonManager::slotEntered(const QModelIndex& index) +{ + m_removeButton->hide(); + + BackgroundListModel *model = static_cast(m_view->model()); + m_removeButton->setItemName(model->package(index.row())->filePath("preferred")); + + if (m_removableWallpapers->indexOf(m_removeButton->itemName()) < 0){ + return; + } + + if (!m_connected) { + connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(slotRowsRemoved(QModelIndex,int,int))); + connect(m_view->selectionModel(), + SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection))); + m_connected = true; + } + + // increase the size of the removeButton for large items + const int height = m_view->iconSize().height(); + if (height >= KIconLoader::SizeEnormous) { + m_removeButton->resize(KIconLoader::SizeMedium, KIconLoader::SizeMedium); + } else if (height >= KIconLoader::SizeLarge) { + m_removeButton->resize(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium); + } else { + m_removeButton->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall); + } + + const QRect rect = m_view->visualRect(index); + int x = rect.left(); + int y = rect.top(); + + m_removeButton->move(QPoint(x, y)); + m_removeButton->show(); +} + +void RemoveButtonManager::slotViewportEntered() +{ + m_removeButton->hide(); +} + +void RemoveButtonManager::slotRowsRemoved(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + m_removeButton->hide(); +} + +void RemoveButtonManager::removeButtonClicked() +{ + RemoveButton *removeButton = static_cast(sender()); + emit removeClicked(removeButton->itemName()); +} + +#include "removebuttonmanager.moc" diff --git a/plasma/generic/wallpapers/image/removebuttonmanager.h b/plasma/generic/wallpapers/image/removebuttonmanager.h new file mode 100644 index 00000000..691352fe --- /dev/null +++ b/plasma/generic/wallpapers/image/removebuttonmanager.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2008 by Peter Penz * + * Copyright (C) 2010 by Davide Bettio * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef SELECTIONMANAGER_H +#define SELECTIONMANAGER_H + +#include + +#include + +class QAbstractItemView; +class QModelIndex; +class QItemSelection; +class RemoveButton; + +/** + * @brief Allows to select and deselect items for item views. + * + * Whenever an item is hovered by the mouse, a removeButton button is shown + * which allows to select/deselect the current item. + */ +class RemoveButtonManager : public QObject +{ + Q_OBJECT + +public: + RemoveButtonManager(QAbstractItemView* parent, QStringList *list); + virtual ~RemoveButtonManager(); + +signals: + /** Is emitted if the selection has been changed by the removeButton button. */ + void selectionChanged(); + void removeClicked(QString item); + +private slots: + void slotEntered(const QModelIndex& index); + void slotViewportEntered(); + void slotRowsRemoved(const QModelIndex& parent, int start, int end); + void removeButtonClicked(); + +private: + const QModelIndex indexForUrl(const KUrl& url) const; + +private: + QAbstractItemView* m_view; + RemoveButton* m_removeButton; + bool m_connected; + QStringList *m_removableWallpapers; +}; + +#endif diff --git a/plasma/generic/wallpapers/image/slideshowconfig.ui b/plasma/generic/wallpapers/image/slideshowconfig.ui new file mode 100644 index 00000000..8990f3d1 --- /dev/null +++ b/plasma/generic/wallpapers/image/slideshowconfig.ui @@ -0,0 +1,330 @@ + + + SlideshowConfig + + + + 0 + 0 + 634 + 470 + + + + + + + &Positioning: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_resizeMethod + + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + &Color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_color + + + + + + + + + Change wallpaper frame color + + + Change the color of the frame that it may be visible when the wallpaper is centered or scaled with the same proportions. + + + + 70 + 90 + 130 + + + + + 70 + 90 + 130 + + + + + + + + Qt::Horizontal + + + + 325 + 20 + + + + + + + + + + + 0 + 0 + + + + C&hange images every: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_slideshowDelay + + + + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + + + QDateTimeEdit::HourSection + + + hh 'Hours' mm 'Mins' ss 'Secs' + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + + + + <b>Images</b> + + + + + + + &System wallpapers: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_systemCheckBox + + + + + + + Use system-installed wallpapers in slideshow + + + + + + false + + + + + + + &My downloaded wallpapers: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_downloadedCheckBox + + + + + + + Use wallpapers I have downloaded with "Get New Wallpapers..." in slideshow + + + + + + false + + + + + + + Custom folders: + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + m_downloadedCheckBox + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + &Add Folder... + + + + + + + + 0 + 0 + + + + &Remove Folder + + + + + + + Download new wallpapers + + + Get New Wallpapers... + + + + + + + + + + KColorButton + QPushButton +
    kcolorbutton.h
    +
    + + KPushButton + QPushButton +
    kpushbutton.h
    +
    + + KListWidget + QListWidget +
    klistwidget.h
    +
    +
    + + m_resizeMethod + m_color + m_slideshowDelay + m_systemCheckBox + m_downloadedCheckBox + m_dirlist + m_addDir + m_removeDir + m_newStuff + + + +
    diff --git a/plasma/generic/wallpapers/image/wallpaper.knsrc b/plasma/generic/wallpapers/image/wallpaper.knsrc new file mode 100644 index 00000000..6d55e3d6 --- /dev/null +++ b/plasma/generic/wallpapers/image/wallpaper.knsrc @@ -0,0 +1,6 @@ +[KNewStuff3] +ProvidersUrl=http://download.kde.org/ocs/providers.xml +Categories=KDE Wallpaper 800x600,KDE Wallpaper 1024x768,KDE Wallpaper 1280x1024,KDE Wallpaper 1440x900,KDE Wallpaper 1600x1200,KDE Wallpaper 1680x1050,KDE Wallpaper 1920x1200,KDE Wallpaper 2560x1600,KDE Wallpaper (other),KDE Wallpaper (SVG) +StandardResource=wallpaper +Uncompress=archive + diff --git a/plasma/netbook/CMakeLists.txt b/plasma/netbook/CMakeLists.txt new file mode 100644 index 00000000..1eff685c --- /dev/null +++ b/plasma/netbook/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(applets) +add_subdirectory(containments) +add_subdirectory(dataengines) +add_subdirectory(desktoptheme) +if(NOT WIN32) +add_subdirectory(shell) +endif(NOT WIN32) diff --git a/plasma/netbook/applets/CMakeLists.txt b/plasma/netbook/applets/CMakeLists.txt new file mode 100644 index 00000000..04db5fff --- /dev/null +++ b/plasma/netbook/applets/CMakeLists.txt @@ -0,0 +1,5 @@ +if(X11_XTest_FOUND) + add_subdirectory(currentappcontrol) +endif(X11_XTest_FOUND) + +add_subdirectory(searchbox) diff --git a/plasma/netbook/applets/currentappcontrol/CMakeLists.txt b/plasma/netbook/applets/currentappcontrol/CMakeLists.txt new file mode 100644 index 00000000..46178ce3 --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/CMakeLists.txt @@ -0,0 +1,16 @@ +project(plasma-currentappcontrol) + + +set(currentappcontrol_SRCS currentappcontrol.cpp) + +kde4_add_ui_files(currentappcontrol_SRCS general.ui ) + +kde4_add_plugin(plasma_applet_currentappcontrol ${currentappcontrol_SRCS}) +target_link_libraries(plasma_applet_currentappcontrol + ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS} ${X11_XTest_LIB} ${X11_X11_LIB} ${X11_LIBS}) + +install(TARGETS plasma_applet_currentappcontrol + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-applet-currentappcontrol.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/netbook/applets/currentappcontrol/Messages.sh b/plasma/netbook/applets/currentappcontrol/Messages.sh new file mode 100644 index 00000000..45d44681 --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma_applet_currentappcontrol.pot diff --git a/plasma/netbook/applets/currentappcontrol/currentappcontrol.cpp b/plasma/netbook/applets/currentappcontrol/currentappcontrol.cpp new file mode 100644 index 00000000..de8dc9ce --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/currentappcontrol.cpp @@ -0,0 +1,451 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "currentappcontrol.h" + +//Qt +#include +#include +#include +#include +#include + +//KDE +#include +#include +#include +#include +#include + +//Plasma +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//X +#ifdef Q_WS_X11 +#include +#include +#endif + +CurrentAppControl::CurrentAppControl(QObject *parent, const QVariantList &args) + : Plasma::Applet(parent, args), + m_syncDelay(false), + m_activeWindow(0), + m_lastActiveWindow(0), + m_pendingActiveWindow(0), + m_listDialog(0), + m_listWidget(0), + m_showMaximize(false), + m_alwaysUseDialog(false) +{ + m_currentTask = new Plasma::IconWidget(this); + m_currentTask->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_currentTask->setTextBackgroundColor(QColor()); + m_currentTask->setTextBackgroundColor(QColor(Qt::transparent)); + m_closeTask = new Plasma::IconWidget(this); + m_closeTask->setSvg("widgets/configuration-icons", "close"); + m_closeTask->setMaximumWidth(KIconLoader::SizeSmallMedium); + + m_maximizeTask = new Plasma::IconWidget(this); + m_maximizeTask->setSvg("widgets/configuration-icons", "maximize"); + m_maximizeTask->setMaximumWidth(KIconLoader::SizeSmallMedium); + m_maximizeTask->setZValue(999); + + connect(m_closeTask, SIGNAL(clicked()), this, SLOT(closeWindow())); + connect(m_closeTask, SIGNAL(pressed(bool)), this, SLOT(setSyncDelay(bool))); + connect(m_maximizeTask, SIGNAL(clicked()), this, SLOT(toggleMaximizedWindow())); + connect(m_maximizeTask, SIGNAL(pressed(bool)), this, SLOT(setSyncDelay(bool))); + connect(m_currentTask, SIGNAL(clicked()), this, SLOT(listWindows())); +} + + +CurrentAppControl::~CurrentAppControl() +{ +} + +void CurrentAppControl::init() +{ + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), + this, SLOT(activeWindowChanged(WId))); + connect(KWindowSystem::self(), SIGNAL(windowChanged(WId)), + this, SLOT(windowChanged(WId))); + connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), + this, SLOT(windowRemoved(WId))); + QGraphicsLinearLayout *lay = new QGraphicsLinearLayout(Qt::Horizontal, this); + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(0); + lay->addItem(m_currentTask); + lay->addItem(m_closeTask); + activeWindowChanged(KWindowSystem::activeWindow()); + configChanged(); +} + +void CurrentAppControl::configChanged() +{ + QGraphicsLinearLayout *lay = static_cast(layout()); + m_showMaximize = config().readEntry("ShowMaximize", true); + m_alwaysUseDialog = config().readEntry("AlwaysUseDialog", false); + if (m_showMaximize) { + m_maximizeTask->show(); + lay->insertItem(lay->count()-1, m_maximizeTask); + m_closeTask->setMaximumWidth(KIconLoader::SizeSmallMedium); + } else { + lay->removeItem(m_maximizeTask); + m_closeTask->setMaximumWidth(KIconLoader::SizeSmallMedium*2); + m_maximizeTask->hide(); + } +} + +void CurrentAppControl::constraintsEvent(Plasma::Constraints constraints) +{ + + if ((constraints & Plasma::FormFactorConstraint) || + (constraints & Plasma::SizeConstraint) ) { + QFontMetrics fm(Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont)); + if (formFactor() == Plasma::Vertical) { + m_currentTask->setOrientation(Qt::Vertical); + //FIXME: all this minimum/maximum sizes shouldn't be necessary + m_currentTask->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + m_currentTask->setMinimumSize(0, 0); + } else { + m_currentTask->setOrientation(Qt::Horizontal); + const int width = qMin((qreal)(KIconLoader::SizeSmallMedium*2 + fm.width('M')*30), containment()->size().width()/4); + m_currentTask->setMaximumSize(width, QWIDGETSIZE_MAX); + m_currentTask->setMinimumSize(width, 0); + } + } +} + +void CurrentAppControl::windowChanged(WId id) +{ + bool applicationActive = false; + + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (widget->winId() == id) { + applicationActive = true; + break; + } + } + if (!applicationActive && id == m_activeWindow) { + m_pendingActiveWindow = m_activeWindow; + syncActiveWindow(); + } +} + +void CurrentAppControl::activeWindowChanged(WId id) +{ + m_pendingActiveWindow = id; + //delay the switch to permit to pass the close action to the proper window if our view accepts focus + if (!m_syncDelay) { + syncActiveWindow(); + } +} + +void CurrentAppControl::windowRemoved(WId id) +{ + Q_UNUSED(id) + + QTimer::singleShot(300, this, SLOT(syncActiveWindow())); +} + +void CurrentAppControl::syncActiveWindow() +{ + m_syncDelay = false; + bool applicationActive = false; + + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (widget->winId() == m_pendingActiveWindow || + widget->winId() == KWindowSystem::activeWindow()) { + applicationActive = true; + break; + } + } + + Plasma::ToolTipContent toolTipData = Plasma::ToolTipContent(); + toolTipData.setAutohide(true); + toolTipData.setSubText(i18n("Click here to have an overview of all the running applications")); + + if (applicationActive && m_pendingActiveWindow > 0) { + m_activeWindow = 0; + m_currentTask->setIcon("preferences-system-windows"); + const int activeWindows = qMax(0, windowsCount()-1); + if (activeWindows) { + m_currentTask->setText(i18np("%1 running app", "%1 running apps", activeWindows)); + } else { + m_currentTask->setText(i18n("No running apps")); + } + m_closeTask->hide(); + m_maximizeTask->hide(); + + toolTipData.setMainText(m_currentTask->text()); + toolTipData.setImage(KIcon("preferences-system-windows")); + + } else if (m_pendingActiveWindow <= 0) { + toolTipData.setMainText(m_currentTask->text()); + toolTipData.setImage(KWindowSystem::icon(m_activeWindow, KIconLoader::SizeHuge, KIconLoader::SizeHuge)); + } else { + m_activeWindow = m_pendingActiveWindow; + m_lastActiveWindow = m_pendingActiveWindow; + KWindowInfo info = KWindowSystem::windowInfo(m_activeWindow, NET::WMName|NET::WMState); + m_currentTask->setIcon(KWindowSystem::icon(m_activeWindow, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium)); + m_currentTask->setText(info.name()); + //FIXME: this is utterly bad: the layout seems to -not- resize it? + m_currentTask->resize(size().width() - m_closeTask->size().width(), m_currentTask->size().height()); + m_closeTask->show(); + if (m_showMaximize) { + m_maximizeTask->show(); + } + + toolTipData.setMainText(info.name()); + toolTipData.setImage(KWindowSystem::icon(m_activeWindow, KIconLoader::SizeHuge, KIconLoader::SizeHuge)); + + if (info.state() & (NET::MaxVert|NET::MaxHoriz)) { + m_maximizeTask->setSvg("widgets/configuration-icons", "unmaximize"); + } else { + m_maximizeTask->setSvg("widgets/configuration-icons", "maximize"); + } + } + + Plasma::ToolTipManager::self()->registerWidget(this); + Plasma::ToolTipManager::self()->setContent(m_currentTask, toolTipData); + m_pendingActiveWindow = 0; +} + +void CurrentAppControl::setSyncDelay(bool delay) +{ + m_syncDelay = delay; +} + +void CurrentAppControl::closeWindow() +{ + m_syncDelay = false; + + if (m_activeWindow) { +#ifdef Q_WS_X11 + NETRootInfo ri( QX11Info::display(), NET::CloseWindow ); + ri.closeWindowRequest(m_activeWindow); +#endif + } + + syncActiveWindow(); +} + +void CurrentAppControl::toggleMaximizedWindow() +{ + //TODO: change the icon +#ifdef Q_WS_X11 + KWindowInfo info = KWindowSystem::windowInfo(m_activeWindow, NET::WMState | NET::XAWMState | NET::WMDesktop); + bool on_current = info.isOnCurrentDesktop(); + + if (!on_current) { + KWindowSystem::setCurrentDesktop(info.desktop()); + } + + if (info.isMinimized()) { + KWindowSystem::unminimizeWindow(m_activeWindow); + } + + NETWinInfo ni(QX11Info::display(), m_activeWindow, QX11Info::appRootWindow(), NET::WMState); + + if (!(ni.state() & NET::Max)) { + ni.setState(NET::Max, NET::Max); + m_maximizeTask->setSvg("widgets/configuration-icons", "unmaximize"); + } else { + ni.setState(0, NET::Max); + m_maximizeTask->setSvg("widgets/configuration-icons", "maximize"); + } + + if (!on_current) { + KWindowSystem::forceActiveWindow(m_activeWindow); + } +#endif +} + +void CurrentAppControl::listWindows() +{ + QGraphicsView *v = view(); + if (v) { + KWindowSystem::forceActiveWindow(v->winId()); + } + + if (!m_alwaysUseDialog && Plasma::WindowEffects::isEffectAvailable(Plasma::WindowEffects::PresentWindows)) { + Plasma::WindowEffects::presentWindows(view()->winId() , KWindowSystem::currentDesktop()); + } else if (!m_listDialog || !m_listDialog->isVisible()) { + if (!m_listDialog) { + m_listDialog = new Plasma::Dialog(); + m_listWidget = new QGraphicsWidget(this); + m_listWidget->installEventFilter(this); + m_listWidget->setAcceptHoverEvents(true); + m_listDialog->setGraphicsWidget(m_listWidget); + Plasma::Corona *corona = 0; + if (containment() && containment()->corona()) { + corona = containment()->corona(); + corona->addOffscreenWidget(m_listWidget); + } + + m_listDialog->setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog); + KWindowSystem::setType(m_listDialog->winId(), NET::PopupMenu); + KWindowSystem::setState(m_listDialog->winId(), NET::SkipTaskbar); + m_listDialog->installEventFilter(this); + + connect(m_listDialog, SIGNAL(destroyed()), this, SLOT(closePopup())); + + m_layout = new QGraphicsLinearLayout(m_listWidget); + m_layout->setOrientation(Qt::Vertical); + m_itemBackground = new Plasma::ItemBackground(m_listWidget); + } else { + QHash::const_iterator i = m_windowIcons.constBegin(); + while (i != m_windowIcons.constEnd()) { + i.key()->hide(); + m_oldIcons << i.key(); + ++i; + } + m_windowIcons.clear(); + } + + m_itemBackground->hide(); + + Plasma::WindowEffects::slideWindow(m_listDialog, location()); + + foreach(WId window, KWindowSystem::stackingOrder()) { + KWindowInfo info = KWindowSystem::windowInfo(window, NET::WMName|NET::WMState|NET::WMWindowType); + NET::WindowType type = info.windowType(NET::AllTypesMask); + if (!(info.state() & NET::SkipTaskbar) && + ((type == NET::Normal) || (type == NET::Unknown))) { + Plasma::IconWidget *icon; + if (m_oldIcons.isEmpty()) { + icon = new Plasma::IconWidget(m_listWidget); + icon->setTextBackgroundColor(QColor()); + icon->setTextBackgroundColor(QColor(Qt::transparent)); + icon->setDrawBackground(false); + icon->setPreferredIconSize(QSizeF(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium)); + + qreal left, top, right, bottom; + m_itemBackground->getContentsMargins(&left, &top, &right, &bottom); + icon->setContentsMargins(left, top, right, bottom); + icon->installEventFilter(this); + } else { + icon = m_oldIcons.first(); + m_oldIcons.pop_front(); + } + + icon->setOrientation(Qt::Horizontal); + if (containment()) { + const qreal maxWidth = containment()->corona()->screenGeometry(containment()->screen()).width() * 0.8; + QFontMetrics fm(icon->font()); + icon->setText(fm.elidedText(info.name(), Qt::ElideRight, maxWidth)); + } else { + icon->setText(info.name()); + } + icon->setIcon(KWindowSystem::icon(window, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium)); + icon->setMinimumSize(icon->effectiveSizeHint(Qt::PreferredSize)); + connect(icon, SIGNAL(clicked()), this, SLOT(windowItemClicked())); + m_windowIcons[icon] = window; + m_layout->addItem(icon); + icon->show(); + } + } + + if (containment() && containment()->corona()) { + m_listDialog->move(containment()->corona()->popupPosition(this, m_listDialog->size())); + } + + m_listDialog->show(); + } else { + closePopup(); + KWindowSystem::forceActiveWindow(m_lastActiveWindow); + } +} + +void CurrentAppControl::createConfigurationInterface(KConfigDialog *parent) +{ + QWidget *widget = new QWidget(); + m_generalUi.setupUi(widget); + parent->addPage(widget, i18nc("General configuration page", "General"), icon()); + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + + m_generalUi.alwaysUseDialog->setChecked(m_alwaysUseDialog); + connect(m_generalUi.alwaysUseDialog, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); +} + +void CurrentAppControl::configAccepted() +{ + m_alwaysUseDialog = m_generalUi.alwaysUseDialog->checkState() == Qt::Checked; + config().writeEntry("AlwaysUseDialog", m_alwaysUseDialog); +} + +int CurrentAppControl::windowsCount() const +{ + int count = 0; + foreach(WId window, KWindowSystem::stackingOrder()) { + KWindowInfo info = KWindowSystem::windowInfo(window, NET::WMWindowType | NET::WMPid | NET::WMState); + if (!(info.state() & NET::SkipTaskbar) && + info.windowType(NET::NormalMask | NET::DialogMask | + NET::OverrideMask | NET::UtilityMask) != NET::Utility && + info.windowType(NET::NormalMask | NET::DialogMask | + NET::OverrideMask | NET::UtilityMask | NET::DockMask) != NET::Dock) { + ++count; + } + } + return count; +} + +void CurrentAppControl::windowItemClicked() +{ + if (sender() && m_windowIcons.contains(static_cast(sender()))) { + KWindowSystem::forceActiveWindow(m_windowIcons.value(static_cast(sender()))); + } +} + +void CurrentAppControl::closePopup() +{ + m_listDialog->deleteLater(); + m_listWidget->deleteLater(); + m_listDialog = 0; + m_listWidget = 0; +} + +bool CurrentAppControl::eventFilter(QObject *watched, QEvent *event) +{ + Plasma::IconWidget *icon = qobject_cast(watched); + + if (watched == m_listDialog && event->type() == QEvent::WindowDeactivate) { + closePopup(); + } else if (icon && event->type() == QEvent::GraphicsSceneHoverEnter) { + m_itemBackground->show(); + m_itemBackground->setTargetItem(icon); + } else if (watched == m_listWidget && event->type() == QEvent::GraphicsSceneHoverLeave) { + m_itemBackground->hide(); + } + + return false; +} + +#include "currentappcontrol.moc" diff --git a/plasma/netbook/applets/currentappcontrol/currentappcontrol.h b/plasma/netbook/applets/currentappcontrol/currentappcontrol.h new file mode 100644 index 00000000..29c04cb9 --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/currentappcontrol.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef CURRENTAPPCONTROL_HEADER +#define CURRENTAPPCONTROL_HEADER + +#include + +#include "ui_general.h" + +class QGraphicsLinearLayout; + +namespace Plasma +{ + class IconWidget; + class ItemBackground; + class Dialog; +} + +class CurrentAppControl : public Plasma::Applet +{ + Q_OBJECT +public: + + CurrentAppControl(QObject *parent, const QVariantList &args); + ~CurrentAppControl(); + + void init(); + void configChanged(); + void constraintsEvent(Plasma::Constraints constraints); + + void createConfigurationInterface(KConfigDialog *parent); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + int windowsCount() const; + +protected Q_SLOTS: + void activeWindowChanged(WId id); + void windowChanged(WId id); + void windowRemoved(WId id); + void setSyncDelay(bool delay); + void syncActiveWindow(); + void closeWindow(); + void toggleMaximizedWindow(); + void listWindows(); + void windowItemClicked(); + void closePopup(); + void configAccepted(); + +private: + Plasma::IconWidget *m_currentTask; + Plasma::IconWidget *m_closeTask; + Plasma::IconWidget *m_maximizeTask; + bool m_syncDelay; + WId m_activeWindow; + WId m_lastActiveWindow; + WId m_pendingActiveWindow; + + Plasma::Dialog *m_listDialog; + QGraphicsWidget *m_listWidget; + QGraphicsLinearLayout *m_layout; + Plasma::ItemBackground *m_itemBackground; + bool m_showMaximize; + bool m_alwaysUseDialog; + QList m_oldIcons; + QHash m_windowIcons; + + Ui::GeneralConfig m_generalUi; +}; + +K_EXPORT_PLASMA_APPLET(currentappcontrol, CurrentAppControl) +#endif diff --git a/plasma/netbook/applets/currentappcontrol/general.ui b/plasma/netbook/applets/currentappcontrol/general.ui new file mode 100644 index 00000000..0b799957 --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/general.ui @@ -0,0 +1,32 @@ + + + GeneralConfig + + + + 0 + 0 + 329 + 79 + + + + + + + Always list the applications in a menu + + + + + + + + + + + + + + + diff --git a/plasma/netbook/applets/currentappcontrol/plasma-applet-currentappcontrol.desktop b/plasma/netbook/applets/currentappcontrol/plasma-applet-currentappcontrol.desktop new file mode 100644 index 00000000..37aa9e95 --- /dev/null +++ b/plasma/netbook/applets/currentappcontrol/plasma-applet-currentappcontrol.desktop @@ -0,0 +1,146 @@ +[Desktop Entry] +Name=Current Application Control +Name[ar]=التحكم بالتطبيق الحالي +Name[ast]=Control de l'aplicación actual +Name[bn]=সক্রিয় অ্যাপলিকেশন নিয়ন্ত্রণ +Name[bs]=upravljanje tekućim programom +Name[ca]=Control d'aplicació actual +Name[ca@valencia]=Control d'aplicació actual +Name[cs]=Ovládání aktuální aplikace +Name[da]=Styring af aktuelt program +Name[de]=Steuerung für aktuelles Fenster +Name[el]=Έλεγχος τρέχουσας εφαρμογής +Name[en_GB]=Current Application Control +Name[es]=Control de la aplicación actual +Name[et]=Aktiivne rakenduse juhtimine +Name[eu]=Uneko aplikazioaren kontrola +Name[fi]=Nykyinen sovellusohjain +Name[fr]=Contrôle de l'application courante +Name[fy]=Aktive programma kontrôle +Name[gl]=Control do programa actual +Name[gu]=હાલનાં કાર્યક્રમનું નિયંત્રણ +Name[he]=שליטה ביישום הנוכחי +Name[hi]=मोजूदा अनुप्रयोग नियंत्रण +Name[hr]=Kontrola trenutne aplikacije +Name[hu]=Alkalmazásvezérlő +Name[ia]=Controlo de application currente ... +Name[id]=Kontrol Aplikasi Saat Ini +Name[is]=Stýringar fyrir forrit í keyrslu +Name[ja]=現在のアプリケーションコントロール +Name[kk]=Орындалып жатқан қолданбаны басқару +Name[km]=ការ​ត្រួតពិនិត្យ​កម្មវិធី​បច្ចុប្បន្ន +Name[kn]=ಪ್ರಸ್ತುತ ಅನ್ವಯಗಳ ನಿಯಂತ್ರಣ +Name[ko]=현재 프로그램의 컨트롤 +Name[lt]=Dabartinės programos valdymas +Name[lv]=Aktīvās programmas kontrole +Name[mk]=Контрола за активната апликација +Name[ml]=നിലവിലെ പ്രയോഗനിയന്ത്രണം +Name[mr]=चालू अनुप्रयोग नियंत्रण +Name[nb]=Styring for gjeldende program +Name[nds]=Programmstüern +Name[nl]=De huidige besturing van programma's +Name[nn]=Kontroll for gjeldande program +Name[pa]=ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਕੰਟਰੋਲ +Name[pl]=Sterowanie bieżącym programem +Name[pt]=Controlo da Aplicação Actual +Name[pt_BR]=Controle do aplicativo atual +Name[ro]=Control aplicații curente +Name[ru]=Текущее приложение +Name[si]=වත්මන් යෙදුම් පාලකය +Name[sk]=Ovládanie aktuálnej aplikácie +Name[sl]=Nadzor trenutnega programa +Name[sr]=управљање текућим програмом +Name[sr@ijekavian]=управљање текућим програмом +Name[sr@ijekavianlatin]=upravljanje tekućim programom +Name[sr@latin]=upravljanje tekućim programom +Name[sv]=Styrning av nuvarande program +Name[tg]=Барномаҳои иловагӣ +Name[th]=ควบคุมโปรแกรมปัจจุบัน +Name[tr]=Geçerli Uygulama Denetimi +Name[ug]=نۆۋەتتىكى پروگرامما تىزگىنى +Name[uk]=Керування поточною програмою +Name[vi]=Điều khiển ứng dụng hiện tại +Name[wa]=Controle do programe do moumint +Name[x-test]=xxCurrent Application Controlxx +Name[zh_CN]=当前程序控制 +Name[zh_TW]=目前應用程式控制 +Comment=Controls for the active window +Comment[ar]=تتحكم بالنافذة المُفعلة +Comment[ast]=Controles de la ventana activa +Comment[bn]=সক্রিয় উইণ্ডোর জন্য নিয়ন্ত্রণসমূহ +Comment[bs]=Upravljanje aktivnim prozorom +Comment[ca]=Controls per a la finestra activa +Comment[ca@valencia]=Controls per a la finestra activa +Comment[cs]=Ovládání aktivního okna +Comment[da]=Styring af det aktive vindue +Comment[de]=Das aktuelle Fenster steuern +Comment[el]=Χειριστήρια για το ενεργό παράθυρο +Comment[en_GB]=Controls for the active window +Comment[es]=Controles de la ventana activa +Comment[et]=Aktiivse akna juhtimine +Comment[eu]=Leiho aktiborako kontrolak +Comment[fi]=Ohjaimet ikkunan aktivoimiseksi +Comment[fr]=Contrôles pour la fenêtre active +Comment[fy]=Bestjoering foar it aktive finster +Comment[ga]=Rialtáin le haghaidh na fuinneoige reatha +Comment[gl]=Controla a xanela actual +Comment[he]=בקרים לחלון הפעיל +Comment[hi]=सक्रिय विंडो के लिए नियंत्रण +Comment[hr]=Kontrole aktivnog prozora +Comment[hu]=Vezérlők az aktív ablakhoz +Comment[ia]=Controlos pro le fenestra de activitate +Comment[id]=Kontrol untuk jendela aktif +Comment[is]=Stillingar virka gluggans +Comment[ja]=アクティブウィンドウのコントロール +Comment[kk]=Белсенді терезені басқару +Comment[km]=ការត្រួតពិនិត្យ​សម្រាប់​បង្អួច​សកម្ម +Comment[kn]=ಸಕ್ರಿಯ ಕಿಟಕಿಯನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ +Comment[ko]=현재 프로그램에 있는 컨트롤 +Comment[lt]=Aktyvaus lango valdymo priemonės +Comment[lv]=Kontroles aktīvajam logam +Comment[mk]=Контроли за активниот прозорец +Comment[ml]=സജീവ ജാലകത്തിനുള്ള നിയന്ത്രണങ്ങള്‍ +Comment[mr]=चालू चौकटीकरिता नियंत्रणे +Comment[nb]=Styring for det aktive vinduet +Comment[nds]=Kuntrull för't aktive Finster +Comment[nl]=Besturing van het actieve venster +Comment[nn]=Kontroll for det aktive vindauget +Comment[pa]=ਐਕਟਿਵ ਵਿੰਡੋ ਲਈ ਕੰਟਰੋਲ +Comment[pl]=Sterowanie aktywnym oknem +Comment[pt]=Controlos para a janela activa +Comment[pt_BR]=Controles para a janela ativa +Comment[ro]=Controale pentru fereastra activă +Comment[ru]=Элементы управления для активного окна +Comment[si]=සක්‍රිය කවුළුව සඳහා පාලක +Comment[sk]=Ovládanie pre aktívne okno +Comment[sl]=Nadzorniki za dejavno okno +Comment[sr]=Управљање активним прозором +Comment[sr@ijekavian]=Управљање активним прозором +Comment[sr@ijekavianlatin]=Upravljanje aktivnim prozorom +Comment[sr@latin]=Upravljanje aktivnim prozorom +Comment[sv]=Styrning av det aktiva fönstret +Comment[tg]=Барномаи идоракунии Jack +Comment[th]=ควบคุมหน้าต่างที่กำลังทำงานอยู่ +Comment[tr]=Etkin pencere için denetimler +Comment[ug]=ئاكتىپ كۆزنەكنى تىزگىنلەيدۇ +Comment[uk]=Інструменти керування активним вікном +Comment[vi]=Các nút điều khiển cho cửa sổ đang hoạt động +Comment[wa]=Controle po l' finiesse ovrante +Comment[x-test]=xxControls for the active windowxx +Comment[zh_CN]=控制活动窗口 +Comment[zh_TW]=作用中視窗控制 +Icon=preferences-system-windows +Type=Service + +X-KDE-ServiceTypes=Plasma/Applet +X-KDE-Library=plasma_applet_currentappcontrol +X-KDE-PluginInfo-Author=Marco Martin +X-KDE-PluginInfo-Email=notmart@gmail.com +X-KDE-PluginInfo-Name=currentappcontrol +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + diff --git a/plasma/netbook/applets/searchbox/CMakeLists.txt b/plasma/netbook/applets/searchbox/CMakeLists.txt new file mode 100644 index 00000000..bc07d652 --- /dev/null +++ b/plasma/netbook/applets/searchbox/CMakeLists.txt @@ -0,0 +1,15 @@ +project(plasma-searchbox) + + +set(searchbox_SRCS searchbox.cpp) + + +kde4_add_plugin(plasma_applet_searchbox ${searchbox_SRCS}) +target_link_libraries(plasma_applet_searchbox + ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS}) + +install(TARGETS plasma_applet_searchbox + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-applet-searchbox.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/netbook/applets/searchbox/Messages.sh b/plasma/netbook/applets/searchbox/Messages.sh new file mode 100644 index 00000000..d22cbe18 --- /dev/null +++ b/plasma/netbook/applets/searchbox/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_applet_searchbox.pot diff --git a/plasma/netbook/applets/searchbox/plasma-applet-searchbox.desktop b/plasma/netbook/applets/searchbox/plasma-applet-searchbox.desktop new file mode 100644 index 00000000..a8390060 --- /dev/null +++ b/plasma/netbook/applets/searchbox/plasma-applet-searchbox.desktop @@ -0,0 +1,142 @@ +[Desktop Entry] +Name=Search Box +Name[ar]=صندوق البحث +Name[ast]=Caxa de gueta +Name[bg]=Поле за търсене +Name[bn]=অনুসন্ধান বাক্স +Name[bs]=polje pretrage +Name[ca]=Quadre de cerca +Name[ca@valencia]=Quadre de cerca +Name[cs]=Vyhledávací pole +Name[csb]=Kastka szëkbë +Name[da]=Søgfelt +Name[de]=Suchfeld +Name[el]=Πλαίσιο Αναζήτησης +Name[en_GB]=Search Box +Name[eo]=Skatol-serĉo +Name[es]=Caja de búsqueda +Name[et]=Otsingukast +Name[eu]=Bilaketa-koadroa +Name[fi]=Hakuikkuna +Name[fr]=Boîte de recherche +Name[fy]=Sykfak +Name[ga]=Bosca Cuardaigh +Name[gl]=Caixa de busca +Name[gu]=શોધ ખાનું +Name[he]=תיבת חיפוש +Name[hi]=खोज़ डिब्बा +Name[hr]=Polje za pretragu +Name[hu]=Keresődoboz +Name[ia]=Quadrato de cerca +Name[id]=Kotak Pencarian +Name[is]=Leitarreitur +Name[ja]=検索ボックス +Name[kk]=Іздеу панелі +Name[km]=ប្រអប់​ស្វែងរក +Name[kn]=ಹುಡುಕು ಪೆಟ್ಟಿಗೆ +Name[ko]=검색 상자 +Name[lt]=Paieškos laukas +Name[lv]=Meklēšanas lodziņš +Name[ml]=തെരച്ചിലിനുള്ള പെട്ടി +Name[mr]=शोध पट्टी +Name[nb]=Søkeboks +Name[nds]=Söökreeg +Name[nl]=Zoekvak +Name[nn]=Søkjefelt +Name[pa]=ਖੋਜ ਬਕਸਾ +Name[pl]=Pole wyszukiwania +Name[pt]=Campo de Pesquisa +Name[pt_BR]=Campo de pesquisa +Name[ro]=Casetă de căutare +Name[ru]=Строка поиска +Name[si]=සෙවුම් කොටුව +Name[sk]=Vyhľadávacie pole +Name[sl]=Iskalno polje +Name[sr]=поље претраге +Name[sr@ijekavian]=поље претраге +Name[sr@ijekavianlatin]=polje pretrage +Name[sr@latin]=polje pretrage +Name[sv]=Sökruta +Name[tg]=Ҷои ҷустуҷӯӣ +Name[th]=กล่องค้นหา +Name[tr]=Arama Kutusu +Name[ug]=ئىزدەش رامكىسى +Name[uk]=Панель пошуку +Name[wa]=Boesse di cweraedje +Name[x-test]=xxSearch Boxxx +Name[zh_CN]=搜索框 +Name[zh_TW]=搜尋盒 +Comment=Search Box for a given RunnerManager +Comment[ar]=صندوق بحث لـ RunnerManager معين +Comment[ast]=Caxa de gueta pa un determináu xestor de llanzamientu +Comment[bs]=Okvir pretrage za dati menadžer izvođača +Comment[ca]=Quadre de cerca per a un gestor d'execució indicat +Comment[ca@valencia]=Quadre de cerca per a un gestor d'execució indicat +Comment[cs]=Vyhledávací pole pro daný RunnerManager +Comment[da]=Søgfelt til en given RunnerManager +Comment[de]=Suchfeld für einen Starter-Manager +Comment[el]=Πλαίσιο αναζήτησης για ένα δοσμένο διαχειριστή εκτελέσεων +Comment[en_GB]=Search Box for a given RunnerManager +Comment[eo]=Serĉu dialogujon por la proponita RunnerManager +Comment[es]=Caja de búsqueda para un determinado gestor de lanzamiento +Comment[et]=Käivitamishalduri otsingukast +Comment[eu]=Abiarazle-kudeatzaile jakin baterako bilaketa-koadroa +Comment[fi]=Etsintäikkuna tietylle RunnerManagerille +Comment[fr]=Boîte de recherche pour un gestionnaire de lancement donné +Comment[fy]=Sykfak foar de oantsjutte RunnerManager +Comment[gl]=Caixa de busca para un RunnerManager dado +Comment[he]=תיבת חיפוש עבור RunnerManager נתון +Comment[hr]=Polje za pretragu za dani Upravitelj Pokretanja +Comment[hu]=Keresődoboz egy adott RunnerManagerhez +Comment[ia]=Quadrato de cerca pro un date RunnerManager (Gerente de Execution) +Comment[id]=Kotak pencarian untuk manajer pelari yang diberikan +Comment[is]=Leitarreitur fyrir tiltekinn KeyrsluStjóra (RunnerManager) +Comment[ja]=RunnerManager の検索ボックス +Comment[kk]=Таңдаған ЖегуМенеджері үшін Іздеу панелі +Comment[km]=ប្រអប់​ស្វែងរក​សម្រាប់​កម្មវិធី​គ្រប់គ្រង​របស់​កម្មវិធី​ដែលបាន​ផ្ដល់ +Comment[kn]=ಒದಗಿಸಲಾದ RunnerManager ಗಾಗಿನ ಹುಡುಕು ಚೌಕ +Comment[ko]=주어진 실행기 관리자를 위한 검색 상자 +Comment[lt]=Paieškos laukas nurodytam paleidiklio tvarkikliui +Comment[lv]=Meklēšanas lodziņš dotam RunnerManager +Comment[ml]=റണ്ണര്‍മാനേജറിനു് വേണ്ടിയുള്ള തെരച്ചില്‍ പെട്ടി +Comment[mr]=दिलेल्या RunnerManager साठी शोध पट्टी +Comment[nb]=Søkeboks for en gitt RunnerManager +Comment[nds]=Söökreeg för en angeven Dreegpleger +Comment[nl]=Zoekvak voor een gegeven startbeheerder +Comment[nn]=Søkjefelt for ein gjeven RunnerManager +Comment[pa]=ਦਿੱਤੇ ਰਨਰਮੈਨੇਜਰ ਲਈ ਖੋਜ ਬਾਕਸ +Comment[pl]=Pole wyszukiwania w podanym programie uruchamiającym +Comment[pt]=Campo de Pesquisa para um dado Gestor de Execuções +Comment[pt_BR]=Campo de pesquisa para um gerenciador de execuções indicado +Comment[ro]=Casetă de căutare pentru un anumit RunnerManager +Comment[ru]=Строка поиска для заданного диспетчера запуска +Comment[si]=දෙනලද ක්‍රියාකරවුම් පාලකය සඳහා සෙවුම් කොටුව +Comment[sk]=Vyhľadávacie pole pre zadaný spúšťač +Comment[sl]=Iskalno polje za določen upravljalnik zaganjalnikov +Comment[sr]=Оквир претраге за дати менаџер извођача +Comment[sr@ijekavian]=Оквир претраге за дати менаџер извођача +Comment[sr@ijekavianlatin]=Okvir pretrage za dati menadžer izvođača +Comment[sr@latin]=Okvir pretrage za dati menadžer izvođača +Comment[sv]=Sökruta för en given hanterare av programkörning +Comment[th]=กล่องค้นหาสำหรับตัวจัดการเรียกใช้งานที่ให้มา +Comment[tr]=Verilen bir Çalıştırıcı Yöneticisi için Arama Kutusu +Comment[ug]=باشقۇرغۇچنى ئىجرا قىلىدىغان ئىزدەش قۇتىسى +Comment[uk]=Панель пошуку для вказаного Керування запуском +Comment[wa]=Boesse di cweraedje pos on Manaedjeu d' enondaedje di dné +Comment[x-test]=xxSearch Box for a given RunnerManagerxx +Comment[zh_CN]=运行管理器的搜索框 +Comment[zh_TW]=RunnerManager 的搜尋盒 +Icon=edit-find +Type=Service + +X-KDE-ServiceTypes=Plasma/Applet +X-KDE-Library=plasma_applet_searchbox +X-KDE-PluginInfo-Author=Artur Souza +X-KDE-PluginInfo-Email=asouza@kde.org +X-KDE-PluginInfo-Name=searchbox +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/netbook/applets/searchbox/searchbox.cpp b/plasma/netbook/applets/searchbox/searchbox.cpp new file mode 100644 index 00000000..e1b582ce --- /dev/null +++ b/plasma/netbook/applets/searchbox/searchbox.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2009 by Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "searchbox.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +SearchBox::SearchBox(QObject *parent, const QVariantList &args) + : Plasma::PopupApplet(parent, args), m_widget(0), m_search(0), + m_closeIcon(0) +{ + setPopupIcon("edit-find"); + setPassivePopup(true); + setAspectRatioMode(Plasma::IgnoreAspectRatio); +} + +void SearchBox::init() +{ + // tooltip stuff + Plasma::ToolTipContent toolTipData = Plasma::ToolTipContent(); + toolTipData.setAutohide(true); + toolTipData.setMainText(name()); + toolTipData.setImage(KIcon("edit-find")); + + Plasma::ToolTipManager::self()->registerWidget(this); + Plasma::ToolTipManager::self()->setContent(this, toolTipData); +} + +SearchBox::~SearchBox() +{ +} + +QGraphicsWidget *SearchBox::graphicsWidget() +{ + if (m_widget) { + return m_widget; + } + + m_search = new Plasma::LineEdit(); + m_search->nativeWidget()->setClearButtonShown(true); + m_search->nativeWidget()->setClickMessage(i18n("Enter your query here")); + connect(m_search, SIGNAL(returnPressed()), this, SLOT(query())); + connect(m_search->nativeWidget(), SIGNAL(textChanged(QString)), this, SLOT(delayedQuery())); + + m_searchTimer = new QTimer(this); + m_searchTimer->setSingleShot(true); + connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(query())); + + + m_closeIcon = new Plasma::IconWidget(); + m_closeIcon->setIcon("dialog-close"); + m_closeIcon->setPreferredSize(KIconLoader::SizeSmallMedium, + KIconLoader::SizeSmallMedium); + connect(m_closeIcon, SIGNAL(clicked()), this, SLOT(hidePopup())); + + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(); + layout->addItem(m_search); + layout->addItem(m_closeIcon); + layout->setStretchFactor(m_search, 4); + + m_widget = new QGraphicsWidget(this); + m_widget->setLayout(layout); + m_widget->setPreferredWidth(300); + m_widget->installEventFilter(this); + + return m_widget; +} + +void SearchBox::popupEvent(bool shown) +{ + if (!m_search) { + return; + } + + if (shown) { + focusEditor(); + } else { + m_search->setText(QString()); + } +} + +void SearchBox::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event); + + focusEditor(); +} + +bool SearchBox::eventFilter(QObject* watched, QEvent *event) +{ + Q_UNUSED(watched); + + //FIXME: is there a way to do it in PopupApplet? + if (event->type() == QEvent::FocusIn) { + focusEditor(); + } + return false; +} + +void SearchBox::focusEditor() +{ + m_search->clearFocus(); + m_search->setFocus(); + m_search->nativeWidget()->clearFocus(); + m_search->nativeWidget()->setFocus(); +} + +void SearchBox::delayedQuery() +{ + m_searchTimer->start(500); +} + +void SearchBox::query() +{ + Plasma::Service *service = dataEngine("searchlaunch")->serviceForSource("query"); + KConfigGroup ops = service->operationDescription("query"); + ops.writeEntry("query", m_search->text()); + KJob *job = service->startOperationCall(ops); + connect(job, SIGNAL(finished(KJob*)), service, SLOT(deleteLater())); +} + +#include "searchbox.moc" diff --git a/plasma/netbook/applets/searchbox/searchbox.h b/plasma/netbook/applets/searchbox/searchbox.h new file mode 100644 index 00000000..e8662332 --- /dev/null +++ b/plasma/netbook/applets/searchbox/searchbox.h @@ -0,0 +1,63 @@ +/* + * Copyright 2009 by Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SEARCHBOX_APPLET_H +#define SEARCHBOX_APPLET_H + +#include + + +namespace Plasma +{ + class IconWidget; + class LineEdit; +} + +class QTimer; + +class SearchBox: public Plasma::PopupApplet +{ + Q_OBJECT + +public: + SearchBox(QObject *parent, const QVariantList &args); + ~SearchBox(); + void init(); + + QGraphicsWidget *graphicsWidget(); + +public slots: + void delayedQuery(); + void query(); + +protected: + void popupEvent(bool shown); + void focusInEvent(QFocusEvent *event); + bool eventFilter(QObject* watched, QEvent *event); + void focusEditor(); + +private: + QGraphicsWidget *m_widget; + Plasma::LineEdit *m_search; + Plasma::IconWidget *m_closeIcon; + QTimer *m_searchTimer; +}; + +K_EXPORT_PLASMA_APPLET(searchbox, SearchBox) + +#endif diff --git a/plasma/netbook/containments/CMakeLists.txt b/plasma/netbook/containments/CMakeLists.txt new file mode 100644 index 00000000..c96a688c --- /dev/null +++ b/plasma/netbook/containments/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(netpanel) +if(NOT WIN32) +add_subdirectory(sal) +endif(NOT WIN32) diff --git a/plasma/netbook/containments/common/appletmovespacer.cpp b/plasma/netbook/containments/common/appletmovespacer.cpp new file mode 100644 index 00000000..7a4a259a --- /dev/null +++ b/plasma/netbook/containments/common/appletmovespacer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "appletmovespacer.h" + +#include + +#include + +AppletMoveSpacer::AppletMoveSpacer(QGraphicsWidget *parent) + : QGraphicsWidget(parent) +{ + m_background = new Plasma::FrameSvg(this); + m_background->setImagePath("widgets/frame"); + m_background->setElementPrefix("sunken"); +} + +AppletMoveSpacer::~AppletMoveSpacer() +{ +} + +void AppletMoveSpacer::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + event->setPos(mapToParent(event->pos())); + emit dropRequested(event); +} + +void AppletMoveSpacer::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + m_background->resizeFrame(event->newSize()); +} + +void AppletMoveSpacer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + m_background->paintFrame(painter); +} + +#include "appletmovespacer.moc" diff --git a/plasma/netbook/containments/common/appletmovespacer.h b/plasma/netbook/containments/common/appletmovespacer.h new file mode 100644 index 00000000..ff2d1be7 --- /dev/null +++ b/plasma/netbook/containments/common/appletmovespacer.h @@ -0,0 +1,50 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef APPLETMOVESPACER_H +#define APPLETMOVESPACER_H + +#include + +namespace Plasma { + class FrameSvg; +} + +class AppletMoveSpacer : public QGraphicsWidget +{ + Q_OBJECT + +public: + AppletMoveSpacer(QGraphicsWidget *parent); + ~AppletMoveSpacer(); + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +Q_SIGNALS: + void dropRequested(QGraphicsSceneDragDropEvent *event); + +private: + Plasma::FrameSvg *m_background; +}; + +#endif diff --git a/plasma/netbook/containments/common/linearappletoverlay.cpp b/plasma/netbook/containments/common/linearappletoverlay.cpp new file mode 100644 index 00000000..ac352c42 --- /dev/null +++ b/plasma/netbook/containments/common/linearappletoverlay.cpp @@ -0,0 +1,298 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linearappletoverlay.h" + +#include "../common/appletmovespacer.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +LinearAppletOverlay::LinearAppletOverlay(Plasma::Containment *parent, QGraphicsLinearLayout *layout) + : QGraphicsWidget(parent), + m_applet(0), + m_containment(parent), + m_layout(layout), + m_spacer(0), + m_spacerIndex(0), + m_clickDrag(false) +{ + setAcceptHoverEvents(true); + setAcceptDrops(true); + setZValue(900); +} + +LinearAppletOverlay::~LinearAppletOverlay() +{ +} + +void LinearAppletOverlay::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + + QColor c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); + c.setAlphaF(0.15); + + painter->fillRect(option->exposedRect, c); + + if (m_applet) { + QRectF geom = m_applet->geometry(); + geom.moveTopLeft(geom.topLeft()); + c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor); + c.setAlphaF(0.30); + QPainterPath p = Plasma::PaintUtils::roundedRectangle(geom, 4); + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->fillPath(p, c); + painter->restore(); + } +} + +void LinearAppletOverlay::appletDestroyed() +{ + m_applet = 0; +} + +void LinearAppletOverlay::spacerRequestedDrop(QGraphicsSceneDragDropEvent *event) +{ + dropEvent(event); +} + +void LinearAppletOverlay::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() != Qt::LeftButton) { + //Hack to make scene::itemAt() work + int z = zValue(); + setZValue(-100); + //FIXME:here we don't have a screen pos in the event + m_containment->showContextMenu(event->pos(), event->pos().toPoint()); + setZValue(z); + return; + } + + if (m_clickDrag) { + m_clickDrag = false; + m_origin = QPoint(); + return; + } + + if (m_applet) { + m_origin = event->pos(); + showSpacer(event->pos()); + if (m_layout) { + m_layout->removeItem(m_applet); + m_applet->raise(); + } + if (m_spacer) { + m_spacer->setMinimumHeight(m_applet->size().height()); + } + } +} + +void LinearAppletOverlay::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + if (m_clickDrag) { + //Cheat and pretend a mousemoveevent is arrived + QGraphicsSceneMouseEvent me; + me.setPos(event->pos()); + me.setLastPos(event->lastPos()); + mouseMoveEvent(&me); + return; + } + + if (m_applet) { + disconnect(m_applet, SIGNAL(destroyed()), this, SLOT(appletDestroyed())); + } + m_applet = 0; + + Plasma::Applet *oldApplet = 0; + + //FIXME: is there a way more efficient than this linear one? scene()itemAt() won't work because it would always be == this + foreach (Plasma::Applet *applet, m_containment->applets()) { + if (applet->geometry().contains(event->pos())) { + m_applet = applet; + connect(applet, SIGNAL(destroyed()), this, SLOT(appletDestroyed())); + break; + } + } + if (m_applet != oldApplet) { + update(); + } +} + +void LinearAppletOverlay::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_spacer) { + QPointF delta = event->pos()-event->lastPos(); + if (m_applet) { + if (m_containment->formFactor() == Plasma::Vertical) { + m_applet->moveBy(0, delta.y()); + } else { + m_applet->moveBy(delta.x(), 0); + } + } + showSpacer(event->pos()); + } + + update(); +} + +void LinearAppletOverlay::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) + + QPoint delta = event->pos().toPoint() - m_origin.toPoint(); + if (m_origin != QPointF() && delta.manhattanLength() < KGlobalSettings::dndEventDelay()) { + m_clickDrag = true; + m_origin = QPointF(); + return; + } + + if (m_spacer && m_layout) { + m_layout->removeItem(m_spacer); + if (m_applet) { + m_layout->insertItem(m_spacerIndex, m_applet); + } + } + + delete m_spacer; + m_spacer = 0; + m_spacerIndex = 0; +} + +void LinearAppletOverlay::dragEnterEvent(QGraphicsSceneDragDropEvent *event) +{ + showSpacer(event->pos()); + event->accept(); +} + +void LinearAppletOverlay::dragMoveEvent(QGraphicsSceneDragDropEvent *event) +{ + showSpacer(event->pos()); +} + +void LinearAppletOverlay::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + event->setPos(mapToParent(event->pos())); + emit dropRequested(event); + + if (m_layout) { + m_layout->removeItem(m_spacer); + } + + if (m_spacer) { + m_spacer->deleteLater(); + } + + m_spacer = 0; + m_spacerIndex = 0; +} + +void LinearAppletOverlay::showSpacer(const QPointF &pos) +{ + if (!scene()) { + return; + } + + if (pos == QPoint()) { + if (m_spacer) { + m_layout->removeItem(m_spacer); + m_spacer->hide(); + } + return; + } + + //lucky case: the spacer is already in the right position + if (m_spacer && m_spacer->geometry().contains(pos)) { + return; + } + + int insertIndex = -1; + + for (int i = 0; i < m_layout->count(); ++i) { + if (!dynamic_cast(m_layout->itemAt(i)) && + !dynamic_cast(m_layout->itemAt(i))) { + continue; + } + QRectF siblingGeometry = m_layout->itemAt(i)->geometry(); + + if (m_containment->formFactor() != Plasma::Vertical) { + qreal middle = siblingGeometry.center().x(); + if (pos.x() < middle) { + insertIndex = i; + break; + } else if (pos.x() <= siblingGeometry.right()) { + insertIndex = i + 1; + break; + } + } else { // Vertical + qreal middle = siblingGeometry.center().y(); + + if (pos.y() < middle) { + insertIndex = i; + break; + } else if (pos.y() <= siblingGeometry.bottom()) { + insertIndex = i + 1; + break; + } + } + } + + if (m_spacerIndex < insertIndex) { + --insertIndex; + } + + //if is -1 let's see if there are spacers, zero, one or two + if (insertIndex < 0) { + bool firstSpacer = (!dynamic_cast(m_layout->itemAt(0)) && + !dynamic_cast(m_layout->itemAt(0))); + bool lastSpacer = (!dynamic_cast(m_layout->itemAt(m_layout->count() - 1)) && + !dynamic_cast(m_layout->itemAt(m_layout->count() - 1))); + + if (firstSpacer && lastSpacer && m_layout->count() > 1) { + insertIndex = m_layout->count() - 2; + } else if (lastSpacer) { + insertIndex = 0; + } + } + + m_spacerIndex = insertIndex; + if (insertIndex != -1) { + if (!m_spacer) { + m_spacer = new AppletMoveSpacer(this); + connect (m_spacer, SIGNAL(dropRequested(QGraphicsSceneDragDropEvent*)), + this, SLOT(spacerRequestedDrop(QGraphicsSceneDragDropEvent*))); + } + + m_layout->removeItem(m_spacer); + m_spacer->show(); + m_layout->insertItem(insertIndex, m_spacer); + } +} + +#include + diff --git a/plasma/netbook/containments/common/linearappletoverlay.h b/plasma/netbook/containments/common/linearappletoverlay.h new file mode 100644 index 00000000..d33addc7 --- /dev/null +++ b/plasma/netbook/containments/common/linearappletoverlay.h @@ -0,0 +1,77 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef LINEARAPPLETOVERLAY_H +#define LINEARAPPLETOVERLAY_H + + +#include + +namespace Plasma +{ + class Applet; + class Containment; +} + +class Panel; +class AppletMoveSpacer; +class QGraphicsLinearLayout; +class QTimer; + +class LinearAppletOverlay : public QGraphicsWidget +{ + Q_OBJECT + + friend class AppletMoveSpacer; + +public: + explicit LinearAppletOverlay(Plasma::Containment *parent = 0, QGraphicsLinearLayout *layout = 0); + ~LinearAppletOverlay(); + + void showSpacer(const QPointF &pos); + +protected Q_SLOTS: + void appletDestroyed(); + void spacerRequestedDrop(QGraphicsSceneDragDropEvent *event); + +protected: + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + void dragMoveEvent(QGraphicsSceneDragDropEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + +Q_SIGNALS: + void dropRequested(QGraphicsSceneDragDropEvent *event); + +private: + Plasma::Applet *m_applet; + Plasma::Containment *m_containment; + QGraphicsLinearLayout *m_layout; + Panel *m_panel; + AppletMoveSpacer *m_spacer; + int m_spacerIndex; + bool m_clickDrag; + QPointF m_origin; +}; + +#endif diff --git a/plasma/netbook/containments/netpanel/CMakeLists.txt b/plasma/netbook/containments/netpanel/CMakeLists.txt new file mode 100644 index 00000000..f6f768a4 --- /dev/null +++ b/plasma/netbook/containments/netpanel/CMakeLists.txt @@ -0,0 +1,13 @@ + +set(panel_SRCS + panel.cpp + dummytoolbox.cpp + ../common/linearappletoverlay.cpp + ../common/appletmovespacer.cpp + ) + +kde4_add_plugin(plasma_containment_netpanel ${panel_SRCS}) +target_link_libraries(plasma_containment_netpanel ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_containment_netpanel DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containment-netpanel.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/netbook/containments/netpanel/Messages.sh b/plasma/netbook/containments/netpanel/Messages.sh new file mode 100644 index 00000000..4aa94ac2 --- /dev/null +++ b/plasma/netbook/containments/netpanel/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_applet_netpanel.pot diff --git a/plasma/netbook/containments/netpanel/dummytoolbox.cpp b/plasma/netbook/containments/netpanel/dummytoolbox.cpp new file mode 100644 index 00000000..7363af2d --- /dev/null +++ b/plasma/netbook/containments/netpanel/dummytoolbox.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "dummytoolbox.h" + + + +DummyToolBox::DummyToolBox(Plasma::Containment *parent) + : Plasma::AbstractToolBox(parent), + m_showing(false) +{ +} + +DummyToolBox::~DummyToolBox() +{ +} + +bool DummyToolBox::isShowing() const +{ + return m_showing; +} + +void DummyToolBox::setShowing(const bool show) +{ + if (show != m_showing) { + emit toggled(); + emit visibilityChanged(show); + } + + m_showing = show; +} + + +void DummyToolBox::addTool(QAction *) +{ + //not supported +} + +void DummyToolBox::removeTool(QAction *) +{ + //not supported +} + +#include "dummytoolbox.moc" diff --git a/plasma/netbook/containments/netpanel/dummytoolbox.h b/plasma/netbook/containments/netpanel/dummytoolbox.h new file mode 100644 index 00000000..492da18c --- /dev/null +++ b/plasma/netbook/containments/netpanel/dummytoolbox.h @@ -0,0 +1,45 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DUMMYTOOLBOX_H +#define DUMMYTOOLBOX_H + + +#include + + +class DummyToolBox : public Plasma::AbstractToolBox +{ + Q_OBJECT + Q_PROPERTY(bool showing READ isShowing WRITE setShowing ) +public: + DummyToolBox(Plasma::Containment *parent = 0); + ~DummyToolBox(); + + bool isShowing() const; + void setShowing(const bool show); + + void addTool(QAction *action); + void removeTool(QAction *action); + +private: + bool m_showing; +}; + +#endif diff --git a/plasma/netbook/containments/netpanel/panel.cpp b/plasma/netbook/containments/netpanel/panel.cpp new file mode 100644 index 00000000..488946ba --- /dev/null +++ b/plasma/netbook/containments/netpanel/panel.cpp @@ -0,0 +1,535 @@ +/* +* Copyright 2007 by Alex Merry +* Copyright 2008 by Alexis Ménard +* Copyright 2008 by Aaron Seigo +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "panel.h" +#include "dummytoolbox.h" +#include "../common/linearappletoverlay.h" + +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include +#include +#include +#include + +using namespace Plasma; + +Panel::Panel(QObject *parent, const QVariantList &args) + : Containment(parent, args), + m_layout(0), + m_appletOverlay(0) +{ + m_background = new Plasma::FrameSvg(this); + m_background->setImagePath("widgets/panel-background"); + m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders); + connect(m_background, SIGNAL(repaintNeeded()), this, SLOT(backgroundChanged())); + setZValue(150); + setContainmentType(Containment::PanelContainment); + + QSize size = QSize(args.count() ? args[0].toInt() : 1024, 22); + kDebug() << "**********" << size; + resize(size); + setMinimumSize(size); + setMaximumSize(size); + setDrawWallpaper(false); + + DummyToolBox *toolBox = new DummyToolBox(this); + setToolBox(toolBox); + + connect(this, SIGNAL(appletRemoved(Plasma::Applet*)), + this, SLOT(appletRemoved(Plasma::Applet*))); + connect(this, SIGNAL(toolBoxVisibilityChanged(bool)), + this, SLOT(updateConfigurationMode(bool))); +} + +Panel::~Panel() +{ +} + +void Panel::init() +{ + Containment::init(); + + Plasma::Corona *c = corona(); + connect(c, SIGNAL(containmentAdded(Plasma::Containment*)), + this, SLOT(containmentAdded(Plasma::Containment*))); + + KAction *lockAction = new KAction(this); + addAction("lock panel", lockAction); + lockAction->setText(i18n("Lock Panel")); + lockAction->setIcon(KIcon("object-locked")); + QObject::connect(lockAction, SIGNAL(triggered(bool)), this, SLOT(toggleImmutability())); + lockAction->setShortcut(KShortcut("alt+d, l")); + lockAction->setShortcutContext(Qt::ApplicationShortcut); + + QAction *configureAction = new QAction(KIcon("configure"), i18n("Settings"), this); + addAction("configure panel", configureAction); + connect(configureAction, SIGNAL(triggered(bool)), this, SLOT(showToolBox())); +} + +void Panel::toggleImmutability() +{ + if (immutability() == Plasma::UserImmutable) { + setImmutability(Plasma::Mutable); + } else if (immutability() == Plasma::Mutable) { + setImmutability(Plasma::UserImmutable); + } +} + +void Panel::containmentAdded(Plasma::Containment *containment) +{ + connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), + this, SLOT(updateConfigurationMode(bool))); +} + +void Panel::showToolBox() +{ + setToolBoxOpen(true); +} + +void Panel::backgroundChanged() +{ + constraintsEvent(Plasma::LocationConstraint); +} + +void Panel::layoutApplet(Plasma::Applet* applet, const QPointF &pos) +{ + // this gets called whenever an applet is added, and we add it to our m_layoutout + + if (!m_layout) { + return; + } + + Plasma::FormFactor f = formFactor(); + int insertIndex = -1; + + //if pos is (-1,-1) insert at the end of the panel + if (pos != QPoint(-1, -1)) { + for (int i = 0; i < m_layout->count(); ++i) { + QRectF siblingGeometry = m_layout->itemAt(i)->geometry(); + if (f == Plasma::Horizontal) { + qreal middle = (siblingGeometry.left() + siblingGeometry.right()) / 2.0; + if (pos.x() < middle) { + insertIndex = i; + break; + } else if (pos.x() <= siblingGeometry.right()) { + insertIndex = i + 1; + break; + } + } else { // Plasma::Vertical + qreal middle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0; + if (pos.y() < middle) { + insertIndex = i; + break; + } else if (pos.y() <= siblingGeometry.bottom()) { + insertIndex = i + 1; + break; + } + } + } + } + + if (insertIndex == -1) { + m_layout->addItem(applet); + } else { + m_layout->insertItem(insertIndex, applet); + } + + connect(applet, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updateSize())); +} + +void Panel::appletRemoved(Plasma::Applet* applet) +{ + //shrink the panel if possible + if (formFactor() == Plasma::Horizontal) { + resize(size().width() - applet->size().width(), size().height()); + } else { + resize(size().width(), size().height() - applet->size().height()); + } + layout()->setMaximumSize(size()); +} + +void Panel::updateSize() +{ + Plasma::Applet *applet = qobject_cast(sender()); + + if (applet) { + if (formFactor() == Plasma::Horizontal) { + const int delta = applet->preferredWidth() - applet->size().width(); + //setting the preferred width when delta = 0 and preferredWidth() < minimumWidth() + // leads to the same thing as setPreferredWidth(minimumWidth()) + if (delta != 0) { + setPreferredWidth(preferredWidth() + delta); + } + } else if (formFactor() == Plasma::Vertical) { + const int delta = applet->preferredHeight() - applet->size().height(); + if (delta != 0) { + setPreferredHeight(preferredHeight() + delta); + } + } + + resize(preferredSize()); + } +} + +void Panel::updateBorders() +{ + FrameSvg::EnabledBorders enabledBorders = FrameSvg::AllBorders; + + kDebug() << "!!!!!!!!!!!!!!!! location be:" << location(); + switch (location()) { + case BottomEdge: + enabledBorders = FrameSvg::TopBorder; + break; + case TopEdge: + enabledBorders = FrameSvg::BottomBorder; + break; + case LeftEdge: + enabledBorders = FrameSvg::RightBorder; + break; + case RightEdge: + enabledBorders = FrameSvg::LeftBorder; + break; + default: + break; + } + + qreal topHeight = 0; + qreal bottomHeight = 0; + qreal leftWidth = 0; + qreal rightWidth = 0; + + //activate borders and fetch sizes again + m_background->setEnabledBorders(enabledBorders); + m_background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight); + + //FIXME: this will be probably just killed not kept in this zombie state :) +#if 0 + //calculation of extra margins has to be done after getMargins + if (formFactor() == Vertical) { + //hardcoded extra margin for the toolbox right now + if (immutability() == Mutable) { + bottomHeight += 20; + } + //Default to horizontal for now + } else { + //hardcoded extra margin for the toolbox for now + if (immutability() == Mutable) { + if (QApplication::layoutDirection() == Qt::RightToLeft) { + leftWidth += 20; + } else { + rightWidth += 20; + } + } + } +#endif + + switch (location()) { + case LeftEdge: + rightWidth = qMin(rightWidth, qMax(qreal(1), size().width() - KIconLoader::SizeMedium)); + break; + case RightEdge: + leftWidth = qMin(leftWidth, qMax(qreal(1), size().width() - KIconLoader::SizeMedium)); + break; + case TopEdge: + bottomHeight = qMin(bottomHeight, qMax(qreal(1), size().height() - KIconLoader::SizeMedium)); + break; + case BottomEdge: + topHeight = qMin(topHeight, qMax(qreal(1), size().height() - KIconLoader::SizeMedium)); + break; + default: + break; + } + + //invalidate the layout and set again + if (layout()) { + layout()->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight); + layout()->invalidate(); + } + + update(); +} + +void Panel::constraintsEvent(Plasma::Constraints constraints) +{ + kDebug() << "constraints updated with" << constraints << "!!!!!!"; + + if (constraints & Plasma::FormFactorConstraint) { + Plasma::FormFactor form = formFactor(); + Qt::Orientation layoutDirection = form == Plasma::Vertical ? Qt::Vertical : Qt::Horizontal; + + // create our layout! + if (layout()) { + QGraphicsLayout *lay = layout(); + QGraphicsLinearLayout * linearLay = dynamic_cast(lay); + if (linearLay) { + linearLay->setOrientation(layoutDirection); + } + } else { + m_layout = new QGraphicsLinearLayout(this); + m_layout->setOrientation(layoutDirection); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setSpacing(4); + m_layout->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding)); + setLayout(m_layout); + updateBorders(); + + foreach (Applet *applet, applets()) { + m_layout->addItem(applet); + } + } + } + + //we need to know if the width or height is 100% + if (constraints & Plasma::LocationConstraint || constraints & Plasma::SizeConstraint) { + QSize size = geometry().size().toSize(); + QRectF screenRect = screen() >= 0 ? QApplication::desktop()->screenGeometry(screen()) : geometry(); + + if (formFactor() == Horizontal || + formFactor() == Vertical) { + m_background->setElementPrefix(location()); + } else { + m_background->setElementPrefix(QString()); + } + + m_background->resizeFrame(size); + updateBorders(); + } + + if (constraints & Plasma::SizeConstraint && m_appletOverlay) { + m_appletOverlay->resize(size()); + } + + //FIXME: this seems the only way to correctly resize the layout the first time when the + // saved panel size is less than the default is to setting a maximum size. + // this shouldn't happen. maybe even a qgraphicslayout bug? + if (layout() && (constraints & Plasma::SizeConstraint)) { + layout()->setMaximumSize(size()); + } + + if (constraints & Plasma::LocationConstraint) { + setFormFactorFromLocation(location()); + } + + if (constraints & Plasma::ImmutableConstraint) { + updateBorders(); + + QAction *a = action("lock panel"); + if (a) { + switch (immutability()) { + case Plasma::SystemImmutable: + a->setEnabled(false); + a->setVisible(false); + break; + case Plasma::UserImmutable: + a->setText(i18n("Unlock Panel")); + a->setIcon(KIcon("object-unlocked")); + a->setEnabled(true); + a->setVisible(true); + break; + case Plasma::Mutable: + a->setText(i18n("Lock Panel")); + a->setIcon(KIcon("object-locked")); + a->setEnabled(true); + a->setVisible(true); + break; + } + } + a = action("configure panel"); + if (a) { + switch (immutability()) { + case Plasma::Mutable: + a->setEnabled(true); + a->setVisible(true); + break; + default: + a->setEnabled(false); + a->setVisible(false); + } + } + } + + if (constraints & Plasma::StartupCompletedConstraint) { + connect(this, SIGNAL(appletAdded(Plasma::Applet*,QPointF)), + this, SLOT(layoutApplet(Plasma::Applet*,QPointF))); + delete action("remove"); + } +} + +QList Panel::contextualActions() +{ + QList actions; + + QAction *a = action("lock panel"); + if (a) { + actions << a; + } + a = action("configure panel"); + if (a) { + actions << a; + } + + return actions; +} + +void Panel::updateConfigurationMode(bool config) +{ + if (config && !m_appletOverlay && immutability() == Plasma::Mutable) { + m_appletOverlay = new LinearAppletOverlay(this, m_layout); + m_appletOverlay->resize(size()); + connect (m_appletOverlay, SIGNAL(dropRequested(QGraphicsSceneDragDropEvent*)), + this, SLOT(overlayRequestedDrop(QGraphicsSceneDragDropEvent*))); + } else if (!config) { + delete m_appletOverlay; + m_appletOverlay = 0; + } +} + +void Panel::overlayRequestedDrop(QGraphicsSceneDragDropEvent *event) +{ + dropEvent(event); +} + +//TODO: fold it into saveContents even if it's not strictly contents related? +void Panel::saveState(KConfigGroup &config) const +{ + config.writeEntry("minimumSize", minimumSize()); + config.writeEntry("maximumSize", maximumSize()); +} + +void Panel::paintInterface(QPainter *painter, + const QStyleOptionGraphicsItem *option, + const QRect& contentsRect) +{ + Q_UNUSED(contentsRect) + + //FIXME: this background drawing is bad and ugly =) + // draw the background untransformed (saves lots of per-pixel-math) + painter->save(); + painter->resetTransform(); + + const Containment::StyleOption *containmentOpt = qstyleoption_cast(option); + + QRect viewGeom; + if (containmentOpt) { + viewGeom = containmentOpt->view->geometry(); + } + + painter->fillRect(option->exposedRect, Qt::transparent); + m_background->paintFrame(painter, option->exposedRect, option->exposedRect); + + + // restore transformation and composition mode + painter->restore(); +} + +void Panel::setFormFactorFromLocation(Plasma::Location loc) { + switch (loc) { + case BottomEdge: + case TopEdge: + //kDebug() << "setting horizontal form factor"; + setFormFactor(Plasma::Horizontal); + break; + case RightEdge: + case LeftEdge: + //kDebug() << "setting vertical form factor"; + setFormFactor(Plasma::Vertical); + break; + case Floating: + //TODO: implement a form factor for floating panels + kDebug() << "Floating is unimplemented."; + break; + default: + kDebug() << "invalid location!!"; + } +} + +void Panel::restore(KConfigGroup &group) +{ + Containment::restore(group); + + KConfigGroup appletsConfig(&group, "Applets"); + + QMap oderedApplets; + QList unoderedApplets; + + foreach (Applet *applet, applets()) { + KConfigGroup appletConfig(&appletsConfig, QString::number(applet->id())); + KConfigGroup layoutConfig(&appletConfig, "LayoutInformation"); + + int order = layoutConfig.readEntry("Order", -1); + + if (order > -1) { + oderedApplets[order] = applet; + //if LayoutInformation is not available use the usual way, as a bonus makes it retrocompatible with oler configs + } else { + unoderedApplets.append(applet); + } + + connect(applet, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updateSize())); + } + + foreach (Applet *applet, oderedApplets) { + m_layout->addItem(applet); + } + + foreach (Applet *applet, unoderedApplets) { + layoutApplet(applet, applet->pos()); + } + + updateSize(); +} + +void Panel::saveContents(KConfigGroup &group) const +{ + Containment::saveContents(group); + + if (!m_layout) { + return; + } + + KConfigGroup appletsConfig(&group, "Applets"); + for (int order = 0; order < m_layout->count(); ++order) { + const Applet *applet = dynamic_cast(m_layout->itemAt(order)); + if (applet) { + KConfigGroup appletConfig(&appletsConfig, QString::number(applet->id())); + KConfigGroup layoutConfig(&appletConfig, "LayoutInformation"); + + layoutConfig.writeEntry("Order", order); + } + } +} + +K_EXPORT_PLASMA_APPLET(netpanel, Panel) + +#include "panel.moc" + diff --git a/plasma/netbook/containments/netpanel/panel.h b/plasma/netbook/containments/netpanel/panel.h new file mode 100644 index 00000000..6871ba07 --- /dev/null +++ b/plasma/netbook/containments/netpanel/panel.h @@ -0,0 +1,89 @@ +/* +* Copyright 2007 by Alex Merry +* Copyright 2008 by Alexis Ménard +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef PLASMA_PANEL_H +#define PLASMA_PANEL_H + +#include + +class QAction; +class QGraphicsLinearLayout; +class LinearAppletOverlay; + +namespace Plasma +{ + class FrameSvg; +} + +class Panel : public Plasma::Containment +{ + Q_OBJECT + Q_PROPERTY(QString shadowPath READ shadowPath) + +public: + Panel(QObject *parent, const QVariantList &args); + ~Panel(); + void init(); + + void constraintsEvent(Plasma::Constraints constraints); + + void paintInterface(QPainter *painter, + const QStyleOptionGraphicsItem *option, + const QRect &contentsRect); + void paintBackground(QPainter *painter, const QRect &contentsRect); + QList contextualActions(); + + QString shadowPath() {return "widgets/panel-background";} + +protected: + void saveState(KConfigGroup &config) const; + + void saveContents(KConfigGroup &group) const; + void restore(KConfigGroup &group); + +private Q_SLOTS: + void toggleImmutability(); + void backgroundChanged(); + void layoutApplet(Plasma::Applet* applet, const QPointF &pos); + void appletRemoved(Plasma::Applet* applet); + void updateSize(); + void updateConfigurationMode(bool config); + void overlayRequestedDrop(QGraphicsSceneDragDropEvent *event); + void containmentAdded(Plasma::Containment *containment); + void showToolBox(); + +private: + /** + * update the formfactor based on the location + */ + void setFormFactorFromLocation(Plasma::Location loc); + + /** + * recalculate which borders to show + */ + void updateBorders(); + + Plasma::FrameSvg *m_background; + QGraphicsLinearLayout *m_layout; + LinearAppletOverlay *m_appletOverlay; +}; + + +#endif // PLASMA_PANEL_H diff --git a/plasma/netbook/containments/netpanel/plasma-containment-netpanel.desktop b/plasma/netbook/containments/netpanel/plasma-containment-netpanel.desktop new file mode 100644 index 00000000..bbe343ef --- /dev/null +++ b/plasma/netbook/containments/netpanel/plasma-containment-netpanel.desktop @@ -0,0 +1,155 @@ +[Desktop Entry] +Name=Panel for Netbooks +Name[ar]=لوحة للحاسب المحمول الشبكي +Name[ast]=Panel pa netbooks +Name[bg]=Панел за нетбук +Name[bn]=নেটবুক-এর জন্য প্যানেল +Name[bs]=panel za netbuke +Name[ca]=Plafó per a ordinadors ultraportàtils +Name[ca@valencia]=Plafó per a ordinadors ultraportàtils +Name[cs]=Panel pro Netbooky +Name[csb]=Panel dlô Netbooków +Name[da]=Panel til netbooks +Name[de]=Kontrollleiste für Netbooks +Name[el]=Πίνακας για Netbooks +Name[en_GB]=Panel for Netbooks +Name[eo]=Panelo por malgrandaj komputiloj +Name[es]=Panel para netbooks +Name[et]=Väikesülearvuti paneel +Name[eu]=Netbooketarako panela +Name[fi]=Paneeli miniläppäreille +Name[fr]=Tableau de bord pour les ultra portables +Name[fy]=Paniel foar Netbooks +Name[gl]=Panel para ultraportátiles +Name[he]=לוח עבור נטבוקים +Name[hi]=नेटबुक के लिए पटल +Name[hr]=Ploča za Netbooke +Name[hu]=Netbook panel +Name[ia]=Pannello pro Netbooks +Name[id]=Panel untuk Komputer Mini +Name[is]=Spjald fyrir smáfartölvur +Name[ja]=ネットブックのパネル +Name[kk]=Нетбуктерге арналған панель +Name[km]=បន្ទះ​សម្រាប់ Netbooks +Name[kn]=ನೆಟ್‌ಬುಕ್‌ಗಳಿಗಾಗಿನ ಫಲಕ +Name[ko]=넷북을 위한 패널 +Name[lt]=Pultas Netbukams +Name[lv]=Panelis mazdatoriem +Name[ml]=നെറ്റ്ബുക്കുകള്‍ക്കു വേണ്ടിയുള്ള പാളി +Name[mr]=नेटबूक करिता पटल +Name[nb]=Panel for nettbok +Name[nds]=Paneel för Nettböker +Name[nl]=Paneel voor netbooks +Name[nn]=Panel for mini-PC-ar +Name[pa]=ਨੈੱਟਬੁੱਕ ਲਈ ਪੈਨਲ +Name[pl]=Panel dla netbooków +Name[pt]=Painel para Netbooks +Name[pt_BR]=Painel para Netbooks +Name[ro]=Panou pentru netbook-uri +Name[ru]=Панель для нетбуков +Name[si]=නෙට්බුක් සඳහා පැනලය +Name[sk]=Panel pre Netbooky +Name[sl]=Pult za male prenosnike +Name[sr]=панел за нетбуке +Name[sr@ijekavian]=панел за нетбуке +Name[sr@ijekavianlatin]=panel za netbuke +Name[sr@latin]=panel za netbuke +Name[sv]=Panel för bärbara nätdatorer +Name[tg]=Панел баро Нетбук +Name[th]=แถบพาเนลสำหรับเน็ตบุ้ค +Name[tr]=Netbooklar için Panel +Name[ug]=تور كومپيۇتېرنىڭ تاختىسى +Name[uk]=Панель для субноутбука +Name[wa]=Scriftôr po les poirtåvès éndjoletes +Name[x-test]=xxPanel for Netbooksxx +Name[zh_CN]=笔记本面板 +Name[zh_TW]=Netbooks 的面板 +Comment=A containment for a panel +Comment[af]='n Plekhouer vir 'n paneel +Comment[ar]=حاوية للوحة +Comment[ast]=Un contenedor pa un panel +Comment[be@latin]=Jomišča dla paneli +Comment[bg]=Контейнер за панел +Comment[bs]=Sadržalac za panel +Comment[ca]=Un contenidor per un plafó +Comment[ca@valencia]=Un contenidor per un plafó +Comment[cs]=Kontejner pro panel +Comment[da]=En beholder til et panel +Comment[de]=Ein Behältnis für eine Kontrollleiste +Comment[el]=Ένας υποδοχέας για έναν πίνακα +Comment[en_GB]=A containment for a panel +Comment[eo]=Panelujo +Comment[es]=Un contenedor para un panel +Comment[et]=Paneeli konteiner +Comment[eu]=Panel baterako edukiontzi bat +Comment[fi]=Sovelmasäiliö paneelille +Comment[fr]=Un conteneur pour un tableau de bord +Comment[fy]=In ynslúter foar in paniel +Comment[ga]=Coimeádán le haghaidh painéil +Comment[gl]=Un contido para un panel +Comment[gu]=પેનલ માટે ધરાવનાર +Comment[he]=תיבה ללוח +Comment[hi]=फलक के लिए कंटेनमेंट +Comment[hne]=पेनल बर कंटेनमेंट +Comment[hr]=Okruženje za panel +Comment[hu]=Tartóobjektum a panelhez +Comment[ia]=Un contento pro un pannello +Comment[id]=Pembatasan untuk panel +Comment[is]=Afmörkun fyrir spjald +Comment[ja]=プラズモイド (Plasma パネル) の入れ物 +Comment[kk]=Панельдің ішіндегісі +Comment[km]=ការ​ផ្ទុក​សម្រាប់​បន្ទះ +Comment[kn]=ಪುಟೀಪಿಗೆ (ಪಾನಲ್) ಒಂದು ಧಾರಕ +Comment[ko]=모든 것을 포함하는 패널 +Comment[lt]=Pulto laikiklis +Comment[lv]=Ietvērums panelim +Comment[ml]=പാളി വെയ്ക്കാനുള്ള കണ്ടൈന്‍മെന്റ് +Comment[mr]=पटल करिता एक कंटेनर +Comment[nb]=En beholder for et panel +Comment[nds]=En Gelaats för en Paneel +Comment[ne]=प्यानलका लागि एउटा रोकथाम +Comment[nl]=Een insluiting voor een paneel +Comment[nn]=Ein behaldar for panel +Comment[or]=ଫଳକ ପାଇଁ ଗୋଟିଏ ପ୍ୟାନେଲ +Comment[pa]=ਇੱਕ ਪੈਨਲ ਲਈ ਕੰਨਟੇਨਮੈਂਟ +Comment[pl]=Kontener dla panelu +Comment[pt]=Um contentor para um painel +Comment[pt_BR]=Um contêiner para um painel +Comment[ro]=Container pentru un panou +Comment[ru]=Контейнер панели +Comment[se]=Lihtti mii sisttisdoallá panela +Comment[si]=පැනලය සඳහා ධාරකය +Comment[sk]=Kontajner pre panel +Comment[sl]=Vsebnik za pult +Comment[sr]=Садржалац за панел +Comment[sr@ijekavian]=Садржалац за панел +Comment[sr@ijekavianlatin]=Sadržalac za panel +Comment[sr@latin]=Sadržalac za panel +Comment[sv]=En omgivning för en panel +Comment[ta]=A containment for a panel +Comment[te]=ప్యానల్ కొరకు ఒక కంటైన్‌మెంట్ +Comment[tg]=Контейнер для панели +Comment[th]=ส่วนบรรจุสำหรับพาเนล +Comment[tr]=Panel için bir tutucu +Comment[ug]=تاختا قاچىسى +Comment[uk]=Вмістилище для панелі +Comment[wa]=On contneu pos on scriftôr +Comment[x-test]=xxA containment for a panelxx +Comment[zh_CN]=面板容器 +Comment[zh_TW]=面板容器 +Icon= +Type=Service +X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +X-Plasma-ContainmentCategories=netbook,panel +NoDisplay=true + +X-KDE-Library=plasma_containment_netpanel +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=netpanel +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Containments +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/netbook/containments/sal/CMakeLists.txt b/plasma/netbook/containments/sal/CMakeLists.txt new file mode 100644 index 00000000..7d6c4215 --- /dev/null +++ b/plasma/netbook/containments/sal/CMakeLists.txt @@ -0,0 +1,26 @@ + +set(sal_SRCS + sal.cpp + itemcontainer.cpp + itemview.cpp + ../common/linearappletoverlay.cpp + ../common/appletmovespacer.cpp + stripwidget.cpp + resultwidget.cpp + runnersconfig.cpp + iconactioncollection.cpp + models/krunnermodel.cpp + models/standarditemfactory.cpp + models/favouritesmodel.cpp + models/kservicemodel.cpp + ) + +kde4_add_plugin(plasma_containment_sal ${sal_SRCS}) +target_link_libraries(plasma_containment_sal ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KCMUTILS_LIBS} ) + +install(TARGETS plasma_containment_sal DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containment-sal.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +install(FILES plasma-sal-menu.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) + +file(GLOB services services/*.desktop) +install(FILES ${services} DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/netbook/containments/sal/Messages.sh b/plasma/netbook/containments/sal/Messages.sh new file mode 100644 index 00000000..2692643c --- /dev/null +++ b/plasma/netbook/containments/sal/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_applet_sal.pot diff --git a/plasma/netbook/containments/sal/iconactioncollection.cpp b/plasma/netbook/containments/sal/iconactioncollection.cpp new file mode 100644 index 00000000..c1ed8f66 --- /dev/null +++ b/plasma/netbook/containments/sal/iconactioncollection.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "iconactioncollection.h" + + +IconActionCollection::IconActionCollection(Plasma::Applet *applet, QObject *parent) + : QObject(parent), + m_immutability(Plasma::Mutable) +{ + if (applet) { + connect (applet, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), this, SLOT(immutabilityChanged(Plasma::ImmutabilityType))); + m_immutability = Plasma::Mutable; + } +} + +IconActionCollection::~IconActionCollection() +{ +} + +void IconActionCollection::addAction(QAction *action) +{ + if (action) { + m_actions.insert(action); + connect (action, SIGNAL(destroyed(QObject*)), this, SLOT(actionDestroyed(QObject*))); + action->setVisible(m_immutability == Plasma::Mutable); + action->setEnabled(m_immutability == Plasma::Mutable); + } +} + +void IconActionCollection::removeAction(QAction *action) +{ + m_actions.remove(action); +} + + + +QList IconActionCollection::actions() const +{ + return m_actions.toList(); +} + + + +void IconActionCollection::actionDestroyed(QObject *object) +{ + m_actions.remove(static_cast(object)); +} + +void IconActionCollection::immutabilityChanged(Plasma::ImmutabilityType immutability) +{ + m_immutability = immutability; + + foreach (QAction *action, m_actions) { + action->setVisible(immutability == Plasma::Mutable); + action->setEnabled(immutability == Plasma::Mutable); + } +} + + +#include "iconactioncollection.moc" diff --git a/plasma/netbook/containments/sal/iconactioncollection.h b/plasma/netbook/containments/sal/iconactioncollection.h new file mode 100644 index 00000000..dff4a78a --- /dev/null +++ b/plasma/netbook/containments/sal/iconactioncollection.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_ICONACTIONCOLLECTION_H +#define PLASMA_ICONACTIONCOLLECTION_H + +#include + +#include +#include + +class IconActionCollection : public QObject +{ + Q_OBJECT + +public: + IconActionCollection(Plasma::Applet *applet, QObject *parent = 0); + ~IconActionCollection(); + + void addAction(QAction *action); + void removeAction(QAction *action); + + QList actions() const; + +protected Q_SLOTS: + void actionDestroyed(QObject *object); + void immutabilityChanged(Plasma::ImmutabilityType immutability); + +private: + QSet m_actions; + Plasma::ImmutabilityType m_immutability; +}; + +#endif diff --git a/plasma/netbook/containments/sal/itemcontainer.cpp b/plasma/netbook/containments/sal/itemcontainer.cpp new file mode 100644 index 00000000..459ed609 --- /dev/null +++ b/plasma/netbook/containments/sal/itemcontainer.cpp @@ -0,0 +1,721 @@ +/* + * Copyright 2009 by Marco Martin + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "itemcontainer.h" +#include "itemview.h" +#include "resultwidget.h" +#include "models/commonmodel.h" +#include "iconactioncollection.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +ItemContainer::ItemContainer(ItemView *parent) + : QGraphicsWidget(parent), + m_orientation(Qt::Vertical), + m_currentIconIndexX(-1), + m_currentIconIndexY(-1), + m_iconSize(-1), + m_spacerIndex(-1), + m_firstRelayout(true), + m_dragAndDropMode(ItemContainer::NoDragAndDrop), + m_dragging(false), + m_model(0), + m_itemView(parent) +{ + m_positionAnimation = new QPropertyAnimation(this, "pos", this); + m_positionAnimation->setEasingCurve(QEasingCurve::InOutQuad); + m_positionAnimation->setDuration(250); + + setIconSize(KIconLoader::SizeHuge); + + QGraphicsItem *pi = parent->parentItem(); + Plasma::Applet *applet = 0; + //FIXME: this way to find the Applet is quite horrible + while (pi) { + applet = dynamic_cast(pi); + if (applet) { + break; + } else { + pi = pi->parentItem(); + } + } + m_iconActionCollection = new IconActionCollection(applet, this); + + setFocusPolicy(Qt::StrongFocus); + setAcceptHoverEvents(true); + m_hoverIndicator = new Plasma::ItemBackground(this); + m_hoverIndicator->setZValue(-100); + m_hoverIndicator->hide(); + + m_relayoutTimer = new QTimer(this); + m_relayoutTimer->setSingleShot(true); + connect(m_relayoutTimer, SIGNAL(timeout()), this, SLOT(relayout())); + + m_setCurrentTimer = new QTimer(this); + m_setCurrentTimer->setSingleShot(true); + connect(m_setCurrentTimer, SIGNAL(timeout()), this, SLOT(syncCurrentItem())); + + m_hideUsedItemsTimer = new QTimer(this); + m_hideUsedItemsTimer->setSingleShot(true); + connect(m_hideUsedItemsTimer, SIGNAL(timeout()), this, SLOT(hideUsedItems())); +} + +ItemContainer::~ItemContainer() +{} + +void ItemContainer::setCurrentItem(ResultWidget *currentIcon) +{ + if (m_relayoutTimer->isActive()) { + m_setCurrentTimer->start(400); + m_currentIcon = currentIcon; + return; + } + + QWeakPointer currentWeakIcon = currentIcon; + //m_currentIcon.clear(); + + if (m_currentIcon.data() != currentIcon) { + const int nColumns = qMax(1, (int)ceil(size().width() / m_cellSize.width())); + + for (int i = 0; i < m_model->rowCount(); ++i) { + QModelIndex index = m_model->index(i, 0, m_rootIndex); + ResultWidget *item = m_items.value(index); + + if (item == currentIcon) { + m_currentIconIndexX = i % nColumns; + m_currentIconIndexY = i / nColumns; + break; + } + } + } + + m_hoverIndicator->setTargetItem(currentIcon); +} + +void ItemContainer::syncCurrentItem() +{ + setCurrentItem(m_currentIcon.data()); +} + +ResultWidget *ItemContainer::currentItem() const +{ + return m_currentIcon.data(); +} + +//FIXME: remove +QList ItemContainer::items() const +{ + return m_items.values(); +} + +ResultWidget *ItemContainer::createItem(QModelIndex index) +{ + ResultWidget *item; + if (!m_usedItems.isEmpty()) { + int key = m_usedItems.keys().first(); + item = m_usedItems.values(key).first(); + m_usedItems.remove(key, item); + } else { + item = new ResultWidget(this); + item->setCacheMode(QGraphicsItem::ItemCoordinateCache); + item->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + item->hide(); + item->setPos(boundingRect().center().x(), size().height()); + } + + item->installEventFilter(m_itemView); + + if (index.isValid()) { + item->setPreferredIconSize(QSizeF(m_iconSize, m_iconSize)); + item->setMaximumIconSize(QSizeF(m_iconSize, m_iconSize)); + item->setMinimumIconSize(QSizeF(m_iconSize, m_iconSize)); + item->setIcon(index.data(Qt::DecorationRole).value()); + item->setText(index.data(Qt::DisplayRole).value()); + + Plasma::ToolTipContent toolTipData = Plasma::ToolTipContent(); + toolTipData.setAutohide(true); + toolTipData.setMainText(index.data(Qt::DisplayRole).value()); + toolTipData.setSubText(index.data(CommonModel::Description).value()); + toolTipData.setImage(index.data(Qt::DecorationRole).value()); + + Plasma::ToolTipManager::self()->registerWidget(this); + Plasma::ToolTipManager::self()->setContent(item, toolTipData); + + CommonModel::ActionType actionType = (CommonModel::ActionType)index.data(CommonModel::ActionTypeRole).value(); + if (actionType != CommonModel::NoAction) { + QAction *action = new QAction(item); + if (actionType == CommonModel::AddAction) { + action->setIcon(KIcon("favorites")); + } else { + action->setIcon(KIcon("list-remove")); + } + item->addIconAction(action); + m_iconActionCollection->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(actionTriggered())); + } + + qreal left, top, right, bottom; + m_hoverIndicator->getContentsMargins(&left, &top, &right, &bottom); + item->setContentsMargins(left, top, right, bottom); + + item->setMinimumSize(m_cellSize); + item->setMaximumSize(m_cellSize); + item->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(item, SIGNAL(clicked()), this, SLOT(itemClicked())); + connect(item, SIGNAL(dragStartRequested(ResultWidget*)), this, SLOT(itemRequestedDrag(ResultWidget*))); + } + + return item; +} + +void ItemContainer::disposeItem(ResultWidget *icon) +{ + if (m_usedItems.count() < 40) { + icon->removeIconAction(0); + disconnect(icon, 0, 0, 0); + + int row = m_itemToIndex.value(icon).row(); + row = icon->pos().x() + icon->pos().y()/10 * size().width(); + + m_usedItems.insert(row, icon); + icon->removeEventFilter(m_itemView); + + //if they will be immediately recycled they won't be hidden at all + m_hideUsedItemsTimer->start(500); + } else { + icon->deleteLater(); + } +} + +void ItemContainer::setOrientation(Qt::Orientation orientation) +{ + m_orientation = orientation; + if (orientation == Qt::Horizontal) { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + } else { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + } + askRelayout(); +} + +Qt::Orientation ItemContainer::orientation() const +{ + return m_orientation; +} + +void ItemContainer::setIconSize(int size) +{ + if (size == m_iconSize) { + return; + } + + m_iconSize = size; + + QFontMetrics fm(Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont)); + int cellSize = m_iconSize + fm.height()*2 + 40; + m_cellSize = QSize(cellSize, cellSize); + + foreach (ResultWidget *icon, m_items) { + icon->setPreferredIconSize(QSizeF(size, size)); + icon->setMaximumIconSize(QSizeF(size, size)); + icon->setMinimumIconSize(QSizeF(size, size)); + } +} + +int ItemContainer::iconSize() const +{ + return m_iconSize; +} + +void ItemContainer::setDragAndDropMode(DragAndDropMode mode) +{ + m_dragAndDropMode = mode; +} + +ItemContainer::DragAndDropMode ItemContainer::dragAndDropMode() const +{ + return m_dragAndDropMode; +} + +void ItemContainer::askRelayout() +{ + if (!m_relayoutTimer->isActive()) { + m_relayoutTimer->start(200); + } +} + +void ItemContainer::relayout() +{ + if (!m_model) { + return; + } + + + //FIXME: reserve a random fixed size for the scrollbars, regardless they're present or not + QSizeF availableSize(m_itemView->size() - QSizeF(30, 30)); + + + int nColumns = qMax(1, (int)availableSize.width() / m_cellSize.width()); + int nRows = qMax(1, (int)availableSize.height() / m_cellSize.height()); + + nColumns = qMin(m_model->rowCount(), nColumns); + nRows = qMin(m_model->rowCount(), nRows); + + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + if (m_orientation == Qt::Vertical) { + nRows = qMax(1, (int)ceil((qreal)m_model->rowCount() / nColumns)); + for (int i = 0; i <= m_model->rowCount() - 1; i++) { + + int actualIndex = i; + if (m_spacerIndex > -1) { + if (i >= m_spacerIndex) { + actualIndex = i+1; + } + if (i >= m_draggingIndex.row()) { + --actualIndex; + } + } + + const int row = actualIndex / nColumns; + const int column = actualIndex % nColumns; + + QModelIndex index = m_model->index(i, 0, m_rootIndex); + if (index == m_draggingIndex) { + continue; + } + + ResultWidget *icon = m_items.value(index); + if (icon) { + icon->animatePos(QPoint(column*m_cellSize.width(), row*m_cellSize.height())); + icon->show(); + } + } + } else { + nColumns = qMax(1, (int)ceil((qreal)m_model->rowCount() / nRows)); + for (int i = 0; i <= m_model->rowCount() - 1; i++) { + + int actualIndex = i; + if (m_spacerIndex > -1) { + if (i >= m_spacerIndex) { + actualIndex = i+1; + } + if (i >= m_draggingIndex.row()) { + --actualIndex; + } + } + + const int row = actualIndex % nRows; + const int column = actualIndex / nRows; + + QModelIndex index = m_model->index(i, 0, m_rootIndex); + if (index == m_draggingIndex) { + continue; + } + ResultWidget *icon = m_items.value(index); + if (icon) { + icon->animatePos(QPoint(column*m_cellSize.width(), row*m_cellSize.height())); + icon->show(); + } + } + } + + + m_itemView->setSnapSize(QSizeF(m_cellSize.width(), m_cellSize.height()) + QSizeF(0,0)); //TODO: items spacing? + + QSizeF newSize = sizeHint(Qt::MinimumSize, QSizeF()); + newSize = QSizeF(nColumns*m_cellSize.width(), nRows*m_cellSize.height()); + + setMaximumSize(newSize); + setPreferredSize(newSize); + resize(newSize); + m_relayoutTimer->stop(); + m_firstRelayout = false; +} + +void ItemContainer::itemRequestedDrag(ResultWidget *icon) +{ + if (m_dragging || dragAndDropMode() == NoDragAndDrop) { + return; + } + + if (dragAndDropMode() == MoveDragAndDrop) { + m_dragging = true; + icon->setZValue(900); + icon->installEventFilter(this); + m_draggingIndex = m_itemToIndex.value(icon); + //ugly but necessary to don't make it clipped + icon->setParentItem(0); + } + + QModelIndex index = m_itemToIndex.value(icon); + if (index.isValid()) { + emit dragStartRequested(index); + } +} + +void ItemContainer::keyPressEvent(QKeyEvent *event) +{ + const int nColumns = qMax(1, (int)ceil(size().width() / m_cellSize.width())); + const int nRows = qMax(1, (int)ceil(size().height() / m_cellSize.height())); + + switch (event->key()) { + case Qt::Key_Left: { + m_currentIcon.clear(); + while (!m_currentIcon.data()) { + m_currentIconIndexX = (nColumns + m_currentIconIndexX - 1) % nColumns; + m_currentIcon = m_items.value(m_model->index(nColumns*(m_currentIconIndexY)+m_currentIconIndexX, 0, m_rootIndex)); + } + m_hoverIndicator->setTargetItem(m_currentIcon.data()); + emit itemSelected(m_currentIcon.data()); + break; + } + case Qt::Key_Right: { + m_currentIcon.clear(); + while (!m_currentIcon.data()) { + m_currentIconIndexX = (m_currentIconIndexX + 1) % nColumns; + m_currentIcon = m_items.value(m_model->index(nColumns*(m_currentIconIndexY)+m_currentIconIndexX, 0, m_rootIndex)); + } + m_hoverIndicator->setTargetItem(m_currentIcon.data()); + emit itemSelected(m_currentIcon.data()); + break; + } + case Qt::Key_Up: { + m_currentIcon.clear(); + while (!m_currentIcon) { + m_currentIconIndexY = (nRows + m_currentIconIndexY - 1) % nRows; + m_currentIcon = m_items.value(m_model->index(nColumns*(m_currentIconIndexY)+m_currentIconIndexX, 0, m_rootIndex)); + } + m_hoverIndicator->setTargetItem(m_currentIcon.data()); + emit itemSelected(m_currentIcon.data()); + break; + } + case Qt::Key_Down: { + m_currentIcon.clear(); + while (!m_currentIcon.data()) { + m_currentIconIndexY = (m_currentIconIndexY + 1) % nRows; + m_currentIcon = m_items.value(m_model->index(nColumns*(m_currentIconIndexY)+m_currentIconIndexX, 0, m_rootIndex)); + } + m_hoverIndicator->setTargetItem(m_currentIcon.data()); + emit itemSelected(m_currentIcon.data()); + break; + } + case Qt::Key_Enter: + case Qt::Key_Return: + if (m_currentIcon) { + QModelIndex index = m_itemToIndex.value(m_currentIcon.data()); + if (index.isValid()) { + emit itemActivated(m_model->index(index.row(), 0, m_rootIndex)); + } + } + break; + case Qt::Key_Backspace: + case Qt::Key_Home: + emit resetRequested(); + break; + default: + break; + } +} + +QVariant ItemContainer::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionChange) { + QPointF newPos = value.toPointF(); + if (m_dragging) { + return pos(); + } + } + + return QGraphicsWidget::itemChange(change, value); +} + +void ItemContainer::showSpacer(const QPointF &pos) +{ + if (pos == QPointF()) { + m_spacerIndex = -1; + } else { + m_spacerIndex = rowForPosition(pos); + //FIXME: this is not pretty, but rowForPosition should never return a number bigger than the model rows + if ((m_orientation == Qt::Horizontal && pos.x() > size().width()-m_cellSize.width()/2) || + (m_orientation == Qt::Vertical && pos.y() > size().height()-m_cellSize.height()/2)) { + m_spacerIndex++; + } + } + askRelayout(); +} + +bool ItemContainer::eventFilter(QObject *watched, QEvent *event) +{ + ResultWidget *icon = qobject_cast(watched); + + if (event->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *me = static_cast(event); + + icon->setPos(icon->mapToParent(me->pos()) - icon->boundingRect().center()); + m_dragging = false; + + m_itemView->setScrollPositionFromDragPosition(icon->mapToParent(me->pos())); + m_dragging = true; + + showSpacer(mapFromScene(me->scenePos())); + + askRelayout(); + } else if (event->type() == QEvent::GraphicsSceneMouseRelease) { + QGraphicsSceneMouseEvent *me = static_cast(event); + m_dragging = false; + icon->setZValue(10); + icon->removeEventFilter(this); + icon->setPos(icon->mapToItem(this, QPoint(0,0))); + icon->setParentItem(this); + + QModelIndex index = m_itemToIndex.value(icon); + if (index.isValid()) { + emit itemAskedReorder(index, mapFromScene(me->scenePos())); + } + + m_spacerIndex = -1; + m_draggingIndex = QModelIndex(); + askRelayout(); + } + + return false; +} + + +int ItemContainer::rowForPosition(const QPointF &point) +{ + const int nColumns = qMax(1, (int)ceil(size().width() / m_cellSize.width())); + const int nRows = qMax(1, (int)ceil(size().height() / m_cellSize.height())); + + int row = qMin(nRows-1, (int)round(point.y()/m_cellSize.height())); + int column = qMin(nColumns-1, (int)round(point.x()/m_cellSize.width())); + + kDebug() << "The item will be put at" << row; + + int modelRow = qMin(m_model->rowCount(), row*nColumns + qBound(0, column, nColumns)); + + kDebug() << "Corresponding to the model row" << modelRow; + + return modelRow; +} + +void ItemContainer::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event) + + if (m_model->rowCount() > 0 && m_currentIconIndexX == -1) { + m_currentIconIndexX = 0; + m_currentIconIndexY = 0; + QModelIndex index = m_model->index(0, 0, m_rootIndex); + ResultWidget *item = m_items.value(index); + emit itemSelected(item); + setCurrentItem(item); + } else { + setCurrentItem(m_currentIcon.data()); + } +} + +void ItemContainer::focusOutEvent(QFocusEvent *event) +{ + Q_UNUSED(event) + + m_hoverIndicator->hide(); +} + +void ItemContainer::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) + + if (!hasFocus()) { + m_hoverIndicator->hide(); + } +} + +void ItemContainer::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QGraphicsWidget *pw = parentWidget(); + if (pw) { + QRectF parentRect = pw->boundingRect(); + QPointF newPos(pos()); + if (size().width() < parentRect.size().width()) { + newPos.setX(parentRect.center().x() - size().width()/2); + } else { + newPos.setX(qMin(pos().x(), (qreal)0.0)); + } + if (size().height() < parentRect.size().height()) { + newPos.setY(parentRect.center().y() - size().height()/2); + } else { + newPos.setY(qMin(pos().y(), (qreal)0.0)); + } + if (m_positionAnimation->state() == QAbstractAnimation::Running) { + m_positionAnimation->stop(); + } + if (m_firstRelayout) { + setPos(newPos.toPoint()); + } else { + m_positionAnimation->setEndValue(newPos.toPoint()); + m_positionAnimation->start(); + } + } + + if ((m_orientation == Qt::Vertical && !qFuzzyCompare(event->newSize().width(), event->oldSize().width())) || + (m_orientation == Qt::Horizontal && !qFuzzyCompare(event->newSize().height(), event->oldSize().height()))) { + m_relayoutTimer->start(300); + } +} + +void ItemContainer::setModel(QAbstractItemModel *model) +{ + if (m_model) { + disconnect(m_model, 0, this, 0); + reset(); + } + + m_model = model; + connect (m_model, SIGNAL(modelAboutToBeReset()), this, SLOT(reset())); + connect (m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(generateItems(QModelIndex,int,int))); + connect (m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(removeItems(QModelIndex,int,int))); + + generateItems(m_rootIndex, 0, m_model->rowCount()); +} + +QAbstractItemModel *ItemContainer::model() const +{ + return m_model; +} + +void ItemContainer::reset() +{ + m_hoverIndicator->setTargetItem(0); + + + foreach (ResultWidget *icon, m_items) { + disposeItem(icon); + } + m_items.clear(); + m_itemToIndex.clear(); + askRelayout(); +} + +void ItemContainer::generateItems(const QModelIndex &parent, int start, int end) +{ + if (parent != m_rootIndex) { + return; + } + + for (int i = start; i <= end; i++) { + QModelIndex index = m_model->index(i, 0, m_rootIndex); + + if (index.isValid()) { + ResultWidget *icon = createItem(index); + + m_items.insert(QPersistentModelIndex(index), icon); + m_itemToIndex.insert(icon, QPersistentModelIndex(index)); + } + } + m_relayoutTimer->start(500); +} + +void ItemContainer::actionTriggered() +{ + ResultWidget *icon = static_cast(sender()->parent()); + QModelIndex index = m_itemToIndex.value(icon); + + CommonModel::ActionType actionType = (CommonModel::ActionType)index.data(CommonModel::ActionTypeRole).value(); + + if (actionType == CommonModel::RemoveAction) { + m_model->removeRow(index.row()); + } else if (actionType == CommonModel::AddAction) { + emit addActionTriggered(index); + } +} + +void ItemContainer::removeItems(const QModelIndex &parent, int start, int end) +{ + if (m_rootIndex != parent) { + return; + } + + for (int i = start; i <= end; i++) { + QModelIndex index = m_model->index(i, 0, m_rootIndex); + ResultWidget *icon = m_items.value(index); + disposeItem(icon); + m_items.remove(index); + m_itemToIndex.remove(icon); + } + m_relayoutTimer->start(500); +} + +void ItemContainer::itemClicked() +{ + ResultWidget *icon = qobject_cast(sender()); + + if (icon) { + QModelIndex i = m_itemToIndex.value(icon); + if (i.isValid()) { + QModelIndex index = m_model->index(i.row(), 0, m_rootIndex); + emit itemActivated(index); + } + } +} + +void ItemContainer::setRootIndex(QModelIndex index) +{ + m_rootIndex = index; + reset(); +} + +QModelIndex ItemContainer::rootIndex() const +{ + return m_rootIndex; +} + +void ItemContainer::hideUsedItems() +{ + QMapIterator i(m_usedItems); + while (i.hasNext()) { + i.next(); + foreach (ResultWidget *icon, m_usedItems.values(i.key())) { + icon->animateHide(); + } + } +} + +#include diff --git a/plasma/netbook/containments/sal/itemcontainer.h b/plasma/netbook/containments/sal/itemcontainer.h new file mode 100644 index 00000000..d44d24d5 --- /dev/null +++ b/plasma/netbook/containments/sal/itemcontainer.h @@ -0,0 +1,140 @@ +/* + * Copyright 2009 by Marco Martin + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ITEMCONTAINER_H +#define ITEMCONTAINER_H + +#include +#include + +#include + +#include +#include + +class QGraphicsGridLayout; +class QPropertyAnimation; +class QAbstractItemModel; + +namespace Plasma +{ + class ItemBackground; +} + +class ItemView; +class IconActionCollection; +class ResultWidget; + +class ItemContainer : public QGraphicsWidget +{ + Q_OBJECT + +public: + enum DragAndDropMode{ + NoDragAndDrop = 0, + CopyDragAndDrop = 1, + MoveDragAndDrop = 2 + }; + + ItemContainer(ItemView *parent); + ~ItemContainer(); + + void setCurrentItem(ResultWidget *currentItem); + ResultWidget *currentItem() const; + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + void setIconSize(int size); + int iconSize() const; + + void showSpacer(const QPointF &pos); + + void setDragAndDropMode(DragAndDropMode mode); + DragAndDropMode dragAndDropMode() const; + + QListitems() const; + + void askRelayout(); + + void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; + void setRootIndex(QModelIndex index); + QModelIndex rootIndex() const; + int rowForPosition(const QPointF &point); + +protected: + void focusInEvent(QFocusEvent *event); + void focusOutEvent(QFocusEvent *event); + void keyPressEvent(QKeyEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void resizeEvent(QGraphicsSceneResizeEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + ResultWidget *createItem(QModelIndex index); + void disposeItem(ResultWidget *icon); + +private Q_SLOTS: + void relayout(); + void syncCurrentItem(); + void itemRequestedDrag(ResultWidget *); + void reset(); + void generateItems(const QModelIndex &parent, int start, int end); + void removeItems(const QModelIndex &parent, int start, int end); + void itemClicked(); + void actionTriggered(); + void hideUsedItems(); + +Q_SIGNALS: + void itemSelected(ResultWidget *); + void itemActivated(const QModelIndex &); + void resetRequested(); + void itemAskedReorder(const QModelIndex &index, const QPointF &point); + void dragStartRequested(const QModelIndex &index); + void addActionTriggered(const QModelIndex &index); + +private: + QWeakPointer m_currentIcon; + ResultWidget *m_ghostIcon; + Plasma::ItemBackground *m_hoverIndicator; + QTimer *m_relayoutTimer; + QTimer *m_setCurrentTimer; + QTimer *m_hideUsedItemsTimer; + QHash m_items; + QHash m_itemToIndex; + //we store the old row to sort them, necessary to do a good animation + QMultiMap m_usedItems; + Qt::Orientation m_orientation; + QPropertyAnimation *m_positionAnimation; + int m_currentIconIndexX; + int m_currentIconIndexY; + int m_iconSize; + int m_spacerIndex; + QSize m_cellSize; + bool m_firstRelayout; + DragAndDropMode m_dragAndDropMode; + bool m_dragging; + QAbstractItemModel *m_model; + QModelIndex m_rootIndex; + QModelIndex m_draggingIndex; + ItemView *m_itemView; + IconActionCollection *m_iconActionCollection; +}; + +#endif diff --git a/plasma/netbook/containments/sal/itemview.cpp b/plasma/netbook/containments/sal/itemview.cpp new file mode 100644 index 00000000..ecd23906 --- /dev/null +++ b/plasma/netbook/containments/sal/itemview.cpp @@ -0,0 +1,213 @@ +/* + * Copyright 2009 by Marco Martin + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "itemview.h" +#include "itemcontainer.h" +#include "resultwidget.h" + +#include +#include +#include + + +ItemView::ItemView(QGraphicsWidget *parent) + : Plasma::ScrollWidget(parent) +{ + setFocusPolicy(Qt::StrongFocus); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_itemContainer = new ItemContainer(this); + setAlignment(Qt::AlignCenter); + setWidget(m_itemContainer); + m_noActivateTimer = new QTimer(this); + m_noActivateTimer->setSingleShot(true); + m_itemContainer->installEventFilter(this); + + connect(m_itemContainer, SIGNAL(itemSelected(ResultWidget*)), this, SIGNAL(itemSelected(ResultWidget*))); + connect(m_itemContainer, SIGNAL(itemActivated(QModelIndex)), this, SIGNAL(itemActivated(QModelIndex))); + connect(m_itemContainer, SIGNAL(resetRequested()), this, SIGNAL(resetRequested())); + connect(m_itemContainer, SIGNAL(itemSelected(ResultWidget*)), this, SLOT(selectItem(ResultWidget*))); + connect(m_itemContainer, SIGNAL(itemAskedReorder(QModelIndex,QPointF)), this, SIGNAL(itemAskedReorder(QModelIndex,QPointF))); + connect(m_itemContainer, SIGNAL(dragStartRequested(QModelIndex)), this, SIGNAL(dragStartRequested(QModelIndex))); + + connect(m_itemContainer, SIGNAL(addActionTriggered(QModelIndex)), this, SIGNAL(addActionTriggered(QModelIndex))); +} + +ItemView::~ItemView() +{} + +void ItemView::selectItem(ResultWidget *icon) +{ + if (!m_noActivateTimer->isActive()) { + ensureItemVisible(icon); + } +} + +void ItemView::setCurrentItem(ResultWidget *currentIcon) +{ + m_itemContainer->setCurrentItem(currentIcon); +} + +ResultWidget *ItemView::currentItem() const +{ + return m_itemContainer->currentItem(); +} + +void ItemView::focusInEvent(QFocusEvent *event) +{ + m_itemContainer->setFocus(); + Plasma::ScrollWidget::focusInEvent(event); +} + + +void ItemView::setOrientation(Qt::Orientation orientation) +{ + m_itemContainer->setOrientation(orientation); +} + +Qt::Orientation ItemView::orientation() const +{ + return m_itemContainer->orientation(); +} + +void ItemView::setIconSize(int size) +{ + m_itemContainer->setIconSize(size); +} + +QList ItemView::items() const +{ + return m_itemContainer->items(); +} + +int ItemView::iconSize() const +{ + return m_itemContainer->iconSize(); +} + +void ItemView::setDragAndDropMode(ItemContainer::DragAndDropMode mode) +{ + m_itemContainer->setDragAndDropMode(mode); +} + +ItemContainer::DragAndDropMode ItemView::dragAndDropMode() const +{ + return m_itemContainer->dragAndDropMode(); +} + +void ItemView::setScrollPositionFromDragPosition(const QPointF &point) +{ + const qreal xRatio = point.x() / size().width(); + const qreal yRatio = point.y() / size().height(); + + QPointF newPos(scrollPosition()); + + if (size().width() < contentsSize().width()) { + qreal newXPos = xRatio * (size().width() - contentsSize().width()); + newPos.setX(qBound(qreal(0.0), -newXPos, contentsSize().width() - viewportGeometry().width())); + } + if (size().height() < contentsSize().height()) { + newPos.setY(-(yRatio * (size().height() - contentsSize().height()))); + } + + setScrollPosition(newPos); +} + +void ItemView::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QRectF rect = boundingRect(); + QPointF newPos(m_itemContainer->pos()); + if (m_itemContainer->size().width() < rect.size().width()) { + newPos.setX(rect.center().x() - m_itemContainer->size().width()/2); + } else { + newPos.setX(qMin(m_itemContainer->pos().x(), (qreal)0.0)); + } + if (m_itemContainer->size().height() < rect.size().height()) { + newPos.setY(rect.center().y() - m_itemContainer->size().height()/2); + } else { + newPos.setY(qMin(m_itemContainer->pos().y(), (qreal)0.0)); + } + m_itemContainer->setPos(newPos.toPoint()); + m_itemContainer->askRelayout(); + + Plasma::ScrollWidget::resizeEvent(event); +} + +bool ItemView::eventFilter(QObject *watched, QEvent *event) +{ + ResultWidget *icon = qobject_cast(watched); + if (icon && event->type() == QEvent::GraphicsSceneHoverEnter) { + if (icon) { + m_itemContainer->setCurrentItem(icon); + } + } else if (watched == m_itemContainer && event->type() == QEvent::GraphicsSceneResize) { + + ScrollBarFlags scrollBars = NoScrollBar; + if (m_itemContainer->pos().x() < 0 || m_itemContainer->geometry().right() > size().width()) { + scrollBars |= HorizontalScrollBar; + } + if (m_itemContainer->pos().y() < 0 || m_itemContainer->geometry().bottom() > size().height()) { + scrollBars |= VerticalScrollBar; + } + emit scrollBarsNeededChanged(scrollBars); + } else if (watched == m_itemContainer && event->type() == QEvent::GraphicsSceneMove) { + m_noActivateTimer->start(300); + ScrollBarFlags scrollBars = NoScrollBar; + if (m_itemContainer->pos().x() < 0 || m_itemContainer->geometry().right() > size().width()) { + scrollBars |= HorizontalScrollBar; + } + if (m_itemContainer->pos().y() < 0 || m_itemContainer->geometry().bottom() > size().height()) { + scrollBars |= VerticalScrollBar; + } + emit scrollBarsNeededChanged(scrollBars); + } + + return Plasma::ScrollWidget::eventFilter(watched, event); +} + +void ItemView::showSpacer(const QPointF &pos) +{ + m_itemContainer->showSpacer(pos); +} + +void ItemView::setModel(QAbstractItemModel *model) +{ + m_itemContainer->setModel(model); +} + +QAbstractItemModel *ItemView::model() const +{ + return m_itemContainer->model(); +} + +void ItemView::setRootIndex(QModelIndex index) +{ + m_itemContainer->setRootIndex(index); +} + +QModelIndex ItemView::rootIndex() const +{ + return m_itemContainer->rootIndex(); +} + +int ItemView::rowForPosition(const QPointF &point) +{ + return m_itemContainer->rowForPosition(point); +} + +#include diff --git a/plasma/netbook/containments/sal/itemview.h b/plasma/netbook/containments/sal/itemview.h new file mode 100644 index 00000000..f93ed39e --- /dev/null +++ b/plasma/netbook/containments/sal/itemview.h @@ -0,0 +1,102 @@ +/* + * Copyright 2009 by Marco Martin + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ITEMVIEW_H +#define ITEMVIEW_H + +#include +#include + +#include + +#include "itemcontainer.h" + + +namespace Plasma +{ + class IconWidget; +} + +class QTimer; + +class ItemView : public Plasma::ScrollWidget +{ + Q_OBJECT + +public: + enum ScrollBarNeeded { + NoScrollBar = 0, + HorizontalScrollBar = 1, + VerticalScrollBar = 2, + AllScrollBars = HorizontalScrollBar|VerticalScrollBar + }; + Q_DECLARE_FLAGS(ScrollBarFlags, ScrollBarNeeded) + + ItemView(QGraphicsWidget *parent); + ~ItemView(); + + void setCurrentItem(ResultWidget *currentItem); + ResultWidget *currentItem() const; + + void setOrientation(Qt::Orientation orientation); + Qt::Orientation orientation() const; + + void showSpacer(const QPointF &pos); + + void setIconSize(int size); + int iconSize() const; + + QListitems() const; + + void setDragAndDropMode(ItemContainer::DragAndDropMode mode); + ItemContainer::DragAndDropMode dragAndDropMode() const; + + qreal positionToWeight(const QPointF &point); + void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; + void setRootIndex(QModelIndex index); + QModelIndex rootIndex() const; + int rowForPosition(const QPointF &point); + +public Q_SLOTS: + void setScrollPositionFromDragPosition(const QPointF &point); + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + void focusInEvent(QFocusEvent *event); + +protected Q_SLOTS: + void selectItem(ResultWidget *icon); + +Q_SIGNALS: + void itemSelected(ResultWidget *); + void itemActivated(const QModelIndex &index); + void resetRequested(); + void scrollBarsNeededChanged(ItemView::ScrollBarFlags); + void itemAskedReorder(const QModelIndex &index, const QPointF &point); + void dragStartRequested(const QModelIndex &index); + void addActionTriggered(const QModelIndex &index); + +private: + ItemContainer *m_itemContainer; + QTimer *m_noActivateTimer; +}; + +#endif diff --git a/plasma/netbook/containments/sal/models/commonmodel.h b/plasma/netbook/containments/sal/models/commonmodel.h new file mode 100644 index 00000000..588458bc --- /dev/null +++ b/plasma/netbook/containments/sal/models/commonmodel.h @@ -0,0 +1,41 @@ +/* + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef COMMONMODEL_H +#define COMMONMODEL_H + +#include + +namespace CommonModel +{ + enum ActionType { + NoAction = 0, + AddAction = 1, + RemoveAction = 2 + }; + + enum Roles { + Description = Qt::UserRole+1, + Url = Qt::UserRole+2, + Weight = Qt::UserRole+3, + ActionTypeRole = Qt::UserRole+4 + }; +} + +#endif diff --git a/plasma/netbook/containments/sal/models/favouritesmodel.cpp b/plasma/netbook/containments/sal/models/favouritesmodel.cpp new file mode 100644 index 00000000..fd23c2a0 --- /dev/null +++ b/plasma/netbook/containments/sal/models/favouritesmodel.cpp @@ -0,0 +1,209 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Own +#include "favouritesmodel.h" +#include "krunnermodel.h" +#include "kservicemodel.h" +#include "commonmodel.h" + +// Qt + +// KDE +#include +#include +#include +#include + +//Plasma +#include +#include + + +FavouritesModel::FavouritesModel(QObject *parent) + : QStandardItemModel(parent) +{ + QHash newRoleNames = roleNames(); + newRoleNames[CommonModel::Description] = "description"; + newRoleNames[CommonModel::Url] = "url"; + newRoleNames[CommonModel::Weight] = "weight"; + newRoleNames[CommonModel::ActionTypeRole] = "action"; + + setRoleNames(newRoleNames); +} + +FavouritesModel::~FavouritesModel() +{ +} + +Plasma::RunnerManager *FavouritesModel::runnerManager() +{ + return KRunnerModel::runnerManager(); +} + +void FavouritesModel::restore(KConfigGroup &cg) +{ + kDebug() << "----------------> Restoring Stuff..."; + + KConfigGroup stripGroup(&cg, "stripwidget"); + + clear(); + // get all the favourites + QStringList groupNames(stripGroup.groupList()); + qSort(groupNames); + QMap favouritesConfigs; + foreach (const QString &favouriteGroup, stripGroup.groupList()) { + if (favouriteGroup.startsWith("favourite-")) { + KConfigGroup favouriteConfig(&stripGroup, favouriteGroup); + favouritesConfigs.insert(favouriteGroup.split("-").last().toUInt(), favouriteConfig); + } + } + + QVector urls; + int numIcons; + + if (favouritesConfigs.isEmpty()) { + numIcons = 4; + urls << "konqueror" << "kmail" << "systemsettings" << "dolphin"; + } else { + urls.resize(favouritesConfigs.size()); + QMap::const_iterator it = favouritesConfigs.constBegin(); + int i = 0; + while (it != favouritesConfigs.constEnd()) { + KConfigGroup favouriteConfig = it.value(); + + urls[i] = favouriteConfig.readEntry("url"); + ++i; + ++it; + } + numIcons = stripGroup.groupList().size(); + } + + for (int i = 0; i < numIcons; ++i ) { + if (!urls[i].isNull()) { + add(urls[i]); + } + } +} + + +void FavouritesModel::add(const QUrl &url, const QModelIndex &before) +{ + + KService::Ptr service = KService::serviceByDesktopPath(url.path()); + + if (!service) { + service = KService::serviceByDesktopName(url.path()); + } + + if (!service) { + if (!url.isValid()) { + return; + } + + QString query = url.path(); + QString runnerId = url.host(); + QString matchId = url.fragment(); + if (matchId.startsWith(QLatin1Char('/'))) { + matchId = matchId.remove(0, 1); + } + + //FIXME: another inefficient async query + runnerManager()->blockSignals(true); + runnerManager()->execQuery(query, runnerId); + runnerManager()->blockSignals(false); + + Plasma::QueryMatch match(runnerManager()->searchContext()->match(matchId)); + + if (match.isValid()) { + if (before.isValid()) { + insertRow( + before.row(), + StandardItemFactory::createItem( + match.icon(), + match.text(), + match.subtext(), + url.path(), + 1, //don't need weigt here + CommonModel::RemoveAction + ) + ); + } else { + appendRow( + StandardItemFactory::createItem( + match.icon(), + match.text(), + match.subtext(), + url.path(), + 1, //don't need weigt here + CommonModel::RemoveAction + ) + ); + } + } + } else { + if (before.isValid()) { + insertRow( + before.row(), + StandardItemFactory::createItem( + KIcon(service->icon()), + service->name(), + service->genericName(), + service->entryPath(), + 1, //don't need weigt here + CommonModel::RemoveAction + ) + ); + } else { + appendRow( + StandardItemFactory::createItem( + KIcon(service->icon()), + service->name(), + service->genericName(), + service->entryPath(), + 1, //don't need weigt here + CommonModel::RemoveAction + ) + ); + } + } +} + +void FavouritesModel::save(KConfigGroup &cg) +{ + kDebug() << "----------------> Saving Stuff..."; + + // erase the old stuff before saving the new one + KConfigGroup oldGroup(&cg, "stripwidget"); + oldGroup.deleteGroup(); + + KConfigGroup stripGroup(&cg, "stripwidget"); + + for (int i = 0; i <= rowCount(); i++) { + QModelIndex currentIndex = index(i, 0); + KConfigGroup config(&stripGroup, QString("favourite-%1").arg(i)); + QString url = currentIndex.data(CommonModel::Url).value(); + if (!url.isNull()) { + config.writeEntry("url", url); + } + } +} + +#include "favouritesmodel.moc" diff --git a/plasma/netbook/containments/sal/models/favouritesmodel.h b/plasma/netbook/containments/sal/models/favouritesmodel.h new file mode 100644 index 00000000..eab47592 --- /dev/null +++ b/plasma/netbook/containments/sal/models/favouritesmodel.h @@ -0,0 +1,54 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef FAVOURITESMODEL_H +#define FAVOURITESMODEL_H + +#include + +#include + +#include + +#include "standarditemfactory.h" + +namespace Plasma { + class RunnerManager; +} + + +class FavouritesModel : public QStandardItemModel +{ + Q_OBJECT + +public: + FavouritesModel(QObject *parent); + virtual ~FavouritesModel(); + + void save(KConfigGroup &cg); + void add(const QUrl &url, const QModelIndex &before = QModelIndex()); + void restore(KConfigGroup &cg); + + static Plasma::RunnerManager *runnerManager(); + +}; + +#endif // FAVOURITESMODEL_H + diff --git a/plasma/netbook/containments/sal/models/krunnermodel.cpp b/plasma/netbook/containments/sal/models/krunnermodel.cpp new file mode 100644 index 00000000..f191e927 --- /dev/null +++ b/plasma/netbook/containments/sal/models/krunnermodel.cpp @@ -0,0 +1,228 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Own +#include "krunnermodel.h" +#include "models/commonmodel.h" + +// Qt +#include +#include +#include +#include +#include + +// KDE +#include +#include +#include +#include + +#define DELAY_TIME 50 + + +Plasma::RunnerManager * s_runnerManager = NULL; +Plasma::RunnerManager * runnerManager() { + if (s_runnerManager == NULL) { + s_runnerManager = new Plasma::RunnerManager(); + } + return s_runnerManager; +} + +KService::Ptr serviceForUrl(const KUrl & url) +{ + QString runner = url.host(); + QString id = url.fragment(); + + if (id.startsWith(QLatin1Char('/'))) { + id = id.remove(0, 1); + } + + if (runner != QLatin1String("services")) { + return KService::Ptr(NULL); + } + + // URL path example: services_kde4-kate.desktop + // or: services_firefox.desktop + id.remove("services_"); + + return KService::serviceByStorageId(id); +} + + +bool KRunnerItemHandler::openUrl(const KUrl& url) +{ + QString runner = url.host(); + QString id = url.fragment(); + if (id.startsWith(QLatin1Char('/'))) { + id = id.remove(0, 1); + } + + runnerManager()->run(id); + return true; +} + +class KRunnerModel::Private { +public: + Private() + { + } + + ~Private() + { + } + + QBasicTimer searchDelay; + QString searchQuery; + QString currentRunner; +}; + +KRunnerModel::KRunnerModel(QObject *parent) + : QStandardItemModel(parent) + , d(new Private()) +{ + connect(runnerManager(), + SIGNAL(matchesChanged(QList)), + this, + SLOT(matchesChanged(QList))); + + QHash newRoleNames = roleNames(); + newRoleNames[CommonModel::Description] = "description"; + newRoleNames[CommonModel::Url] = "url"; + newRoleNames[CommonModel::Weight] = "weight"; + newRoleNames[CommonModel::ActionTypeRole] = "action"; + + setRoleNames(newRoleNames); + + setSortRole(CommonModel::Weight); +} + +KRunnerModel::~KRunnerModel() +{ + delete d; +} + +void KRunnerModel::setQuery(const QString& query, const QString& runner) +{ + runnerManager()->reset(); + clear(); + + d->searchQuery = query.trimmed(); + d->currentRunner = runner; + + if (d->searchQuery.isEmpty()) { + return; + } + + d->searchDelay.start(DELAY_TIME, this); +} + +void KRunnerModel::timerEvent(QTimerEvent * event) +{ + QStandardItemModel::timerEvent(event); + + if (event->timerId() == d->searchDelay.timerId()) { + d->searchDelay.stop(); + runnerManager()->launchQuery(d->searchQuery, d->currentRunner); + }; +} + + +void KRunnerModel::matchesChanged(const QList< Plasma::QueryMatch > & m) +{ + QList< Plasma::QueryMatch > matches = m; + + qSort(matches.begin(), matches.end()); + + clear(); + + while (matches.size()) { + Plasma::QueryMatch match = matches.takeLast(); + + appendRow( + StandardItemFactory::createItem( + match.icon(), + match.text(), + match.subtext(), + QString("krunner://") + match.runner()->id() + "/" + ::runnerManager()->query() + "#" + match.id(), + match.relevance(), + CommonModel::AddAction + ) + ); + } + + sort(0, Qt::DescendingOrder); +} + +Qt::ItemFlags KRunnerModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QStandardItemModel::flags(index); + + if (index.isValid()) { + KUrl url = data(index, CommonModel::Url).toString(); + QString host = url.host(); + if (host != "services") { + flags &= ~ ( Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled ); + } + } else { + flags = 0; + } + + return flags; +} + +QMimeData * KRunnerModel::mimeData(const QModelIndexList &indexes) const +{ + KUrl::List urls; + + foreach (const QModelIndex & index, indexes) { + KUrl url = data(index, CommonModel::Url).toString(); + + KService::Ptr service = serviceForUrl(url); + + if (service) { + urls << KUrl(service->entryPath()); + } + } + + QMimeData *mimeData = new QMimeData(); + + if (!urls.isEmpty()) { + urls.populateMimeData(mimeData); + } else { + QList urls; + foreach (const QModelIndex & index, indexes) { + urls << QUrl(data(index, CommonModel::Url).toString()); + } + + mimeData = new QMimeData; + mimeData->setUrls(urls); + } + + return mimeData; + +} + +Plasma::RunnerManager *KRunnerModel::runnerManager() +{ + return ::runnerManager(); +} + +#include "krunnermodel.moc" diff --git a/plasma/netbook/containments/sal/models/krunnermodel.h b/plasma/netbook/containments/sal/models/krunnermodel.h new file mode 100644 index 00000000..416551cb --- /dev/null +++ b/plasma/netbook/containments/sal/models/krunnermodel.h @@ -0,0 +1,72 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KRUNNERMODEL_H +#define KRUNNERMODEL_H + +#include + +#include + +#include + +#include "standarditemfactory.h" + +namespace Plasma +{ + class RunnerManager; +} + +namespace KRunnerItemHandler { + bool openUrl(const KUrl& url); +} + +class KRunnerModel : public QStandardItemModel +{ + Q_OBJECT + +public: + KRunnerModel(QObject *parent); + virtual ~KRunnerModel(); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QMimeData *mimeData(const QModelIndexList &indexes) const; + + static Plasma::RunnerManager *runnerManager(); + +private: + void timerEvent(QTimerEvent * event); + +public Q_SLOTS: + void setQuery(const QString& query, const QString& runner = QString()); + +private Q_SLOTS: + void matchesChanged(const QList< Plasma::QueryMatch > & matches); + +Q_SIGNALS: + void resultsAvailable(); + +private: + class Private; + Private * const d; +}; + +#endif // KRUNNERMODEL_H + diff --git a/plasma/netbook/containments/sal/models/kservicemodel.cpp b/plasma/netbook/containments/sal/models/kservicemodel.cpp new file mode 100644 index 00000000..e19632d8 --- /dev/null +++ b/plasma/netbook/containments/sal/models/kservicemodel.cpp @@ -0,0 +1,299 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Own +#include "kservicemodel.h" +#include "commonmodel.h" + +// Qt +#include + +// KDE +#include +#include +#include +#include +#include +#include + +//Plasma +#include +#include + + +bool KServiceItemHandler::openUrl(const KUrl& url) +{ + QString urlString = url.path(); + KService::Ptr service = KService::serviceByDesktopPath(urlString); + + if (!service) { + service = KService::serviceByDesktopName(urlString); + } + + if (!service) { + return false; + } + + return KRun::run(*service, KUrl::List(), 0); +} + + +KServiceModel::KServiceModel(const KConfigGroup &group, QObject *parent) + : QStandardItemModel(parent), + m_config(group), + m_path("/"), + m_allRootEntriesModel(0) +{ + QHash newRoleNames = roleNames(); + newRoleNames[CommonModel::Description] = "description"; + newRoleNames[CommonModel::Url] = "url"; + newRoleNames[CommonModel::Weight] = "weight"; + newRoleNames[CommonModel::ActionTypeRole] = "action"; + + setRoleNames(newRoleNames); + + loadRootEntries(this); +} + +KServiceModel::~KServiceModel() +{ +} + +QMimeData * KServiceModel::mimeData(const QModelIndexList &indexes) const +{ + KUrl::List urls; + + foreach (const QModelIndex & index, indexes) { + QString urlString = data(index, CommonModel::Url).toString(); + + KService::Ptr service = KService::serviceByDesktopPath(urlString); + + if (!service) { + service = KService::serviceByDesktopName(urlString); + } + + if (service) { + urls << KUrl(service->entryPath()); + } + } + + QMimeData *mimeData = new QMimeData(); + + if (!urls.isEmpty()) { + urls.populateMimeData(mimeData); + } + + return mimeData; + +} + +void KServiceModel::setPath(const QString &path) +{ + clear(); + + if (path == "/") { + loadRootEntries(this); + } else { + loadServiceGroup(KServiceGroup::group(path)); + setSortRole(Qt::DisplayRole); + sort(0, Qt::AscendingOrder); + } + m_path = path; +} + +QString KServiceModel::path() const +{ + return m_path; +} + +void KServiceModel::saveConfig() +{ + if (!m_allRootEntriesModel) { + return; + } + + QStringList enabledEntries; + + for (int i = 0; i <= m_allRootEntriesModel->rowCount() - 1; i++) { + QModelIndex index = m_allRootEntriesModel->index(i, 0, QModelIndex()); + QStandardItem *item = m_allRootEntriesModel->itemFromIndex(index); + if (item && item->checkState() == Qt::Checked) { + enabledEntries << index.data(CommonModel::Url).value(); + } + } + + m_config.writeEntry("EnabledEntries", enabledEntries); + + //sync should be kinda safe here this function is very rarely called + m_config.sync(); + + setPath("/"); +} + +QStandardItemModel *KServiceModel::allRootEntriesModel() +{ + if (!m_allRootEntriesModel) { + m_allRootEntriesModel = new QStandardItemModel(this); + loadRootEntries(m_allRootEntriesModel); + } + + return m_allRootEntriesModel; +} + +void KServiceModel::loadRootEntries(QStandardItemModel *model) +{ + QStringList defaultEnabledEntries; + defaultEnabledEntries << "plasma-sal-contacts.desktop" << "plasma-sal-bookmarks.desktop" + << "plasma-sal-multimedia.desktop" << "plasma-sal-internet.desktop" + << "plasma-sal-graphics.desktop" << "plasma-sal-education.desktop" + << "plasma-sal-games.desktop" << "plasma-sal-office.desktop"; + QSet enabledEntries = m_config.readEntry("EnabledEntries", defaultEnabledEntries).toSet(); + + QHash groupSet; + KServiceGroup::Ptr group = KServiceGroup::root(); + KServiceGroup::List list = group->entries(); + + for( KServiceGroup::List::ConstIterator it = list.constBegin(); + it != list.constEnd(); it++) { + const KSycocaEntry::Ptr p = (*it); + + if (p->isType(KST_KServiceGroup)) { + KServiceGroup::Ptr subGroup = KServiceGroup::Ptr::staticCast(p); + + if (!subGroup->noDisplay() && subGroup->childCount() > 0) { + groupSet.insert(subGroup->relPath(), subGroup); + } + } + + } + + KService::List services = KServiceTypeTrader::self()->query("Plasma/Sal/Menu"); + if (!services.isEmpty()) { + foreach (const KService::Ptr &service, services) { + const QUrl url = QUrl(service->property("X-Plasma-Sal-Url", QVariant::String).toString()); + const int relevance = service->property("X-Plasma-Sal-Relevance", QVariant::Int).toInt(); + const QString groupName = url.path().remove(0, 1); + + if ((model != m_allRootEntriesModel) && enabledEntries.contains(service->storageId()) && + (url.scheme() != "kservicegroup" || groupSet.contains(groupName))) { + model->appendRow( + StandardItemFactory::createItem( + KIcon(service->icon()), + service->name(), + service->comment(), + url.toString(), + relevance, + CommonModel::NoAction + ) + ); + } else if (model == m_allRootEntriesModel && (url.scheme() != "kservicegroup" || groupSet.contains(groupName))) { + QStandardItem * item = StandardItemFactory::createItem( + KIcon(service->icon()), + service->name(), + service->comment(), + service->storageId(), + relevance, + CommonModel::NoAction + ); + item->setCheckable(true); + item->setCheckState(enabledEntries.contains(service->storageId())?Qt::Checked:Qt::Unchecked); + model->appendRow(item); + } + + if (groupSet.contains(groupName)) { + groupSet.remove(groupName); + } + } + } + + foreach (const KServiceGroup::Ptr group, groupSet) { + if ((model != m_allRootEntriesModel) && enabledEntries.contains(group->relPath())) { + model->appendRow( + StandardItemFactory::createItem( + KIcon(group->icon()), + group->caption(), + group->comment(), + QString("kserviceGroup://root/") + group->relPath(), + 0.1, + CommonModel::NoAction + ) + ); + } else if (model == m_allRootEntriesModel) { + QStandardItem *item = StandardItemFactory::createItem( + KIcon(group->icon()), + group->caption(), + group->comment(), + group->storageId(), + 0.1, + CommonModel::NoAction + ); + item->setCheckable(true); + item->setCheckState(enabledEntries.contains(group->storageId())?Qt::Checked:Qt::Unchecked); + model->appendRow(item); + } + } + + model->setSortRole(CommonModel::Weight); + model->sort(0, Qt::DescendingOrder); +} + +void KServiceModel::loadServiceGroup(KServiceGroup::Ptr group) +{ + if (group && group->isValid()) { + KServiceGroup::List list = group->entries(); + + for( KServiceGroup::List::ConstIterator it = list.constBegin(); + it != list.constEnd(); it++) { + const KSycocaEntry::Ptr p = (*it); + + if (p->isType(KST_KService)) { + const KService::Ptr service = KService::Ptr::staticCast(p); + + if (!service->noDisplay()) { + QString genericName = service->genericName(); + if (genericName.isNull()) { + genericName = service->comment(); + } + appendRow( + StandardItemFactory::createItem( + KIcon(service->icon()), + service->name(), + genericName, + service->entryPath(), + 0.5, + CommonModel::AddAction + ) + ); + } + + } else if (p->isType(KST_KServiceGroup)) { + const KServiceGroup::Ptr subGroup = KServiceGroup::Ptr::staticCast(p); + + if (!subGroup->noDisplay() && subGroup->childCount() > 0) { + loadServiceGroup(subGroup); + } + } + + } + + } +} + +#include "kservicemodel.moc" diff --git a/plasma/netbook/containments/sal/models/kservicemodel.h b/plasma/netbook/containments/sal/models/kservicemodel.h new file mode 100644 index 00000000..64379bef --- /dev/null +++ b/plasma/netbook/containments/sal/models/kservicemodel.h @@ -0,0 +1,67 @@ +/* + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSERVICEMODEL_H +#define KSERVICEMODEL_H + +#include + +#include +#include +#include + +#include "standarditemfactory.h" + +namespace Plasma { +} + +namespace KServiceItemHandler { + bool openUrl(const KUrl& url); +} + +class KServiceModel : public QStandardItemModel +{ + Q_OBJECT + +public: + KServiceModel(const KConfigGroup &group, QObject *parent); + virtual ~KServiceModel(); + + virtual QMimeData *mimeData(const QModelIndexList &indexes) const; + + void setPath(const QString &path); + QString path() const; + + QStandardItemModel *allRootEntriesModel(); + +public Q_SLOTS: + void saveConfig(); + +protected: + void loadRootEntries(QStandardItemModel *model); + void loadServiceGroup(KServiceGroup::Ptr group); + +private: + KConfigGroup m_config; + QString m_path; + QStandardItemModel *m_allRootEntriesModel; +}; + +#endif // KSERVICEMODEL_H + diff --git a/plasma/netbook/containments/sal/models/standarditemfactory.cpp b/plasma/netbook/containments/sal/models/standarditemfactory.cpp new file mode 100644 index 00000000..e8d85568 --- /dev/null +++ b/plasma/netbook/containments/sal/models/standarditemfactory.cpp @@ -0,0 +1,37 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "standarditemfactory.h" +#include "commonmodel.h" + +QStandardItem *StandardItemFactory::createItem(const QIcon & icon, const QString & title, + const QString & description, const QString & url, qreal weight, int actionType) +{ + QStandardItem *appItem = new QStandardItem; + + appItem->setText(title); + appItem->setIcon(icon); + appItem->setData(description, CommonModel::Description); + appItem->setData(url, CommonModel::Url); + appItem->setData(weight, CommonModel::Weight); + appItem->setData(actionType, CommonModel::ActionTypeRole); + + return appItem; +} diff --git a/plasma/netbook/containments/sal/models/standarditemfactory.h b/plasma/netbook/containments/sal/models/standarditemfactory.h new file mode 100644 index 00000000..93c426f0 --- /dev/null +++ b/plasma/netbook/containments/sal/models/standarditemfactory.h @@ -0,0 +1,41 @@ +/* + Copyright 2009 Ivan Cukic + Copyright 2010 Marco Martin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef STANDARDITEMFACTORY_H +#define STANDARDITEMFACTORY_H + + +#include +#include +/** + * Factory for creating QStandardItems with appropriate text, icons, URL + * and other information for a given URL or Service. + */ +class StandardItemFactory +{ +public: + static QStandardItem *createItem(const QIcon & icon, const QString & title, + const QString & description, const QString & url, qreal weight, int actionType); + +private: + static void setSpecialUrlProperties(const KUrl& url, QStandardItem *item); +}; + +#endif diff --git a/plasma/netbook/containments/sal/plasma-containment-sal.desktop b/plasma/netbook/containments/sal/plasma-containment-sal.desktop new file mode 100644 index 00000000..6c3a742f --- /dev/null +++ b/plasma/netbook/containments/sal/plasma-containment-sal.desktop @@ -0,0 +1,128 @@ +[Desktop Entry] +Name=Search and Launch +Name[ar]=ابحث و شغل +Name[ast]=Guetar y executar +Name[bg]=Търсене и стартиране +Name[bs]=Traženje i pokretanje +Name[ca]=Cerca i llançament +Name[ca@valencia]=Cerca i llançament +Name[cs]=Vyhledat a spustit +Name[da]=Søg og start +Name[de]=Suchen und ausführen +Name[el]=Αναζήτηση και εκτέλεση +Name[en_GB]=Search and Launch +Name[es]=Buscar y ejecutar +Name[et]=Otsimine ja käivitamine +Name[eu]=Bilatu eta abiarazi +Name[fi]=Etsi ja käynnistä +Name[fr]=Rechercher et lancer +Name[ga]=Cuardaigh agus Tosaigh +Name[gl]=Buscar e executar +Name[he]=חיפוש והפעלה +Name[hi]=खोज कर लाँच करें +Name[hr]=Pretraži i pokreni +Name[hu]=Keresés és indítás +Name[ia]=Cerca e lancea +Name[is]=Leit að forritum og ræsing +Name[ja]=検索と起動 +Name[kk]=Іздеу және жегу +Name[km]=ស្វែងរក​ ហើយ​​ចាប់ផ្ដើម +Name[kn]=ಹುಡುಕು ಹಾಗು ಪ್ರಕ್ಷೇಪನ +Name[ko]=찾아서 실행하기 +Name[lt]=Rasti ir paleisti +Name[lv]=Meklēt un palaist +Name[mr]=शोधा व प्रक्षेपण करा +Name[nb]=Søk og start +Name[nds]=Söken un opropen +Name[nl]=Zoeken en starten +Name[nn]=Søk og køyr +Name[pa]=ਖੋਜ ਅਤੇ ਚਲਾਓ +Name[pl]=Znajdź i uruchom +Name[pt]=Pesquisa e Lançamento +Name[pt_BR]=Pesquisa e execução +Name[ro]=Căutare și lansare +Name[ru]=Поиск и запуск +Name[sk]=Hľadať a spustiť +Name[sl]=Iskanje in zaganjanje +Name[sr]=Тражење и покретање +Name[sr@ijekavian]=Тражење и покретање +Name[sr@ijekavianlatin]=Traženje i pokretanje +Name[sr@latin]=Traženje i pokretanje +Name[sv]=Sök och starta +Name[th]=ค้นหาและเรียกใช้งาน +Name[tr]=Ara ve Çalıştır +Name[ug]=ئىزدەش ۋە ئىجرا قىلىش +Name[uk]=Пошук і запуск +Name[wa]=Trover ey enonder +Name[x-test]=xxSearch and Launchxx +Name[zh_CN]=搜索与启动 +Name[zh_TW]=搜尋並啟動 +Comment=Full screen application launcher with search interface +Comment[ast]=Llanzador d'aplicaciones a pantalla completa con una interface de gueta +Comment[bs]=Pokretač programa preko cijelog ekrana sa sučeljem za pretragu +Comment[ca]=Llançador d'aplicacions de pantalla completa amb interfície de cerca +Comment[ca@valencia]=Llançador d'aplicacions de pantalla completa amb interfície de cerca +Comment[cs]=Celoobrazovkový spouštěč aplikací s rozhraním pro vyhledávání +Comment[da]=Startmenu i fuldskærm med søgefunktion +Comment[de]=Anwendungsstarter im Vollbildmodus mit Suchfeld +Comment[el]=Ένας πλήρης οθόνης εκτελεστής εφαρμογών, με λειτουργία αναζήτησης +Comment[en_GB]=Full screen application launcher with search interface +Comment[es]=Lanzador de aplicaciones a pantalla completa con una interfaz de búsqueda +Comment[et]=Täisekraanis rakenduste käivitaja otsinguliidesega +Comment[eu]=Bilaketa-interfazea duen pantaila osoko aplikazio-abiarazlea +Comment[fi]=Koko näytön sovelluskäynnistin haulla +Comment[fr]=Lanceur d'applications en plein écran avec interface de recherche +Comment[gl]=Iniciador de programas a pantalla completa con interface de buscas +Comment[he]=משגר יישומים במסך מלא עם ממשק חיפוש +Comment[hr]=Pokretač aplikacija sa sučeljem za pretraživanje preko cijelog ekrana +Comment[hu]=Teljes képernyős alkalmazásindító- és keresőfelület +Comment[ia]=Lanceator de application a schermo plen con interfacie de cerca +Comment[is]=Forritaræsir í heilsjásham með leitarviðmóti +Comment[kk]=Іздеу интерфейсі бар, толық экранды бағдарлама жеккіші +Comment[km]=កម្មវិធី​ចាប់ផ្ដើម​​​នៃ​កម្មវិធី​ពេញអេក្រង់​ដែលមាន​ចំណុច​ប្រទាក់​ស្វែងរក +Comment[ko]=검색 인터페이스가 있는 전체 화면 프로그램 실행기 +Comment[lt]=Pilno ekrano programų paleidiklis su paieškos sąsaja +Comment[lv]=Pilnekrāna programmu palaidējs ar meklēšanas saskarni +Comment[mr]=शोध संवादासहीत पूर्ण स्क्रीन अनुप्रयोग प्रक्षेपक +Comment[nb]=Fullskjerms programstarter med grensesnitt for søk +Comment[nds]=Heelschirm-Programmoproper mit Söök-Koppelsteed +Comment[nl]=Programmastarter op volledig scherm met zoekinterface +Comment[pa]=ਖੋਜ ਇੰਟਰਫੇਸ ਨਾਲ ਪੂਰੀ ਸਕਰੀਨ ਉੱਤੇ ਐਪਲੀਕੇਸਨ ਲਾਂਚਰਖੋਜ ਇੰਟਰਫੇਸ ਨਾਲ ਪੂਰੀ ਸਕਰੀਨ ਉੱਤੇ ਐਪਲੀਕੇਸਨ ਕਖੋਜ ਇੰਟਰਫੇਸ ਨਾਲ ਪੂਰੀ ਸਕਰੀਨ ਉੱਤੇ ਐਪਲੀਕੇਸ਼ਣ ਖੋਜ ਇੰਟਰਫੇਸ ਨਾਲ ਪੂਰੀ ਖੋਜ ਇੰਟਰ +Comment[pl]=Pełnoekranowy aktywator programów z interfejsem wyszukiwania +Comment[pt]=Um lançador de aplicações de ecrã completo, com interface de pesquisa +Comment[pt_BR]=Executa aplicativos em tela cheia com interface de pesquisa +Comment[ro]=Lansator de aplicații pe tot ecranul, cu interfață de căutare +Comment[ru]=Полноэкранное меню запуска приложений с возможностью поиска +Comment[sk]=Celoobrazovkový spúšťač aplikácií s rozhraním pre vyhľadávanie +Comment[sl]=Celozaslonski zaganjalnik programov z vmesnikom za iskanje +Comment[sr]=Покретач програма преко целог екрана са сучељем за претрагу +Comment[sr@ijekavian]=Покретач програма преко цијелог екрана са сучељем за претрагу +Comment[sr@ijekavianlatin]=Pokretač programa preko cijelog ekrana sa sučeljem za pretragu +Comment[sr@latin]=Pokretač programa preko celog ekrana sa sučeljem za pretragu +Comment[sv]=Startprogram med fullskärm och sökgränssnitt +Comment[th]=ตัวเรียกใช้งานแอพลิเคชันเต็มจอด้วยอินเทอร์เฟซการค้นหา +Comment[tr]=Arama arayüzüyle birlikte tam ekran uygulama başlatıcı +Comment[ug]=ئىزدەش ئارا يۈزى بار تولۇق ئېكران پروگرامما ئىجراچىسى +Comment[uk]=Повноекранний інструмент запуску програм з інтерфейсом пошуку +Comment[vi]=Trình chạy ứng dụng toàn màn hình với giao diện tìm kiếm +Comment[wa]=Enondeu di programe so tote li waitroûle avou èn eterface di cweraedje +Comment[x-test]=xxFull screen application launcher with search interfacexx +Comment[zh_CN]=带搜索界面的全屏应用程序启动器 +Comment[zh_TW]=全畫面應用程式啟動器,有搜尋介面 + +Icon=edit-find +Type=Service +X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +X-Plasma-ContainmentCategories=netbook,desktop +NoDisplay=false + +X-KDE-Library=plasma_containment_sal +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=sal +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Containments +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/netbook/containments/sal/plasma-sal-menu.desktop b/plasma/netbook/containments/sal/plasma-sal-menu.desktop new file mode 100644 index 00000000..d193201e --- /dev/null +++ b/plasma/netbook/containments/sal/plasma-sal-menu.desktop @@ -0,0 +1,139 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=Plasma/Sal/Menu + +Name=Plasma Search and Launch menu +Name[ar]=قائمة بلازما للبحث والإطلاق +Name[ast]=Menú Plasma de gueta y llanzamientu +Name[bg]=Меню за търсене и стартиране в Plasma +Name[bs]=meni pretrage i pokretanja +Name[ca]=Menú de cerca i llançament del Plasma +Name[ca@valencia]=Menú de cerca i llançament del Plasma +Name[cs]=Vyhledávací a spouštěcí nabídka plasmy +Name[csb]=Menu szëkbë ë zrëszaniô plazmë +Name[da]=Plasma menu til søgning og opstart +Name[de]=Menü „Suchen und Starten“ für Plasma +Name[el]=Μενού Plasma αναζήτησης και εκτέλεσης +Name[en_GB]=Plasma Search and Launch menu +Name[es]=Menú Plasma de búsqueda y lanzamiento +Name[et]=Plasma otsimise ja käivitamise menüü +Name[eu]=Bilaketa eta abiorako Plasmaren menua +Name[fi]=Plasma-etsintä- ja -käynnistysvalikko +Name[fr]=Menu Plasma de recherche et de lancement +Name[fy]=Plasma syk en útfier menu +Name[ga]=Roghchlár Cuardaigh/Tosaithe Plasma +Name[gl]=Menú de busca e inicio de Plasma +Name[he]=תפריט חיפוש והפעלה של Plasma +Name[hi]=प्लासमा खोज व लाँच मीनु +Name[hr]=Plasmin izbornik "Traži i pokreni" +Name[hu]=Plasma keresés és indítás menü +Name[ia]=Menu de Plasma per cercar e lancear +Name[id]=Menu Pencarian dan Peluncuran Plasma +Name[is]=Plasma leitar- og ræsingavalmynd +Name[ja]=Plasma 検索と起動メニュー +Name[kk]=Plasma іздеу және жегу мәзірі +Name[km]=ស្វែងរក​ប្លាស្មា ហើយ​ចាប់ផ្ដើម​ម៉ឺនុយ +Name[kn]=ಪ್ಲಾಸ್ಮಾ ಹುಡುಕು ಹಾಗು ಪ್ರಕ್ಷೇಪನ ಪರಿವಿಡಿ +Name[ko]=Plasma 찾아서 실행 메뉴 +Name[lt]=Plasma paieškos ir paleidimo meniu +Name[lv]=Plasma meklēšanas un palaišanas izvēlne +Name[mk]=Мени за Пребарување и стартување преку Плазма +Name[ml]=പ്ലാസ്മയിലെ തെരയാനും തുടങ്ങാനുമുള്ള മെനു +Name[mr]=प्लाज्मा शोधा व प्रक्षेपण करा मेन्यू +Name[nb]=Plasma søk og start-meny +Name[nds]=Plasma-Söök- un Oproopmenü +Name[nl]=Menu voor Plasma zoeken en starten +Name[nn]=Søk- og køyr i Plasma +Name[pa]=ਪਲਾਜ਼ਮਾ ਖੋਜ ਅਤੇ ਲਾਂਚ ਮੇਨੂ +Name[pl]=Menu Plazmy "znajdź i uruchom" +Name[pt]=Menu de Pesquisa e Lançamento do Plasma +Name[pt_BR]=Menu de pesquisa e execução do Plasma +Name[ro]=Meniu de căutare și lansare Plasma +Name[ru]=Меню «Поиск и запуск» +Name[si]=ප්ලාස්මා සොයා ක්‍රියාකරවන එන්ජිම +Name[sk]=Menu "Hľadať a spustiť" pre plasmu +Name[sl]=Meni za iskanje in zaganjanje +Name[sr]=мени претраге и покретања +Name[sr@ijekavian]=мени претраге и покретања +Name[sr@ijekavianlatin]=meni pretrage i pokretanja +Name[sr@latin]=meni pretrage i pokretanja +Name[sv]=Plasma sök- och startmeny +Name[tg]=Барномаи ҷустуҷӯ +Name[th]=พลาสมารูปแบบค้นหาและเมนูเรียกใช้งาน +Name[tr]=Plasma Ara ve Çalıştır Menüsü +Name[ug]=پلازما ئىزدە ۋە ئىجرا تىزىملىكى +Name[uk]=Меню пошуку і запуску Плазми +Name[wa]=Dressêye Plasma po trover eyet enonder +Name[x-test]=xxPlasma Search and Launch menuxx +Name[zh_CN]=Plasma 搜索与启动菜单 +Name[zh_TW]=Plasma 搜尋與啟動選單 +Comment=Menu entry for The Plasma search and launch activity +Comment[ar]=مدخلة قائمة لنشاط بلازما للبحث والإطلاق +Comment[ast]=Entrada de menú pa la xera de gueta y llanzamientu de Plasma +Comment[bg]=Запис в менюто за търсене и стартиране в Plasma +Comment[bs]=Stavka menija za aktivnost plazma pretrage i pokretanja +Comment[ca]=Entrada de menú per a l'activitat de cerca i llançament del Plasma +Comment[ca@valencia]=Entrada de menú per a l'activitat de cerca i llançament del Plasma +Comment[cs]=Položka nabídky pro pro Vyhledávací a spouštěcí aktivitu plasmy +Comment[da]=Menupunkt til Plasma søg og opstart-aktivitet +Comment[de]=Menüeintrag für die Aktivität „Suchen und Starten“ von Plasma +Comment[el]=Καταχώρηση μενού για τις ενέργειες αναζήτησης και εκτέλεσης Plasma +Comment[en_GB]=Menu entry for The Plasma search and launch activity +Comment[es]=Entrada de menú para la actividad de búsqueda y lanzamiento de Plasma +Comment[et]=Plasma otsimis- ja käivitamistegevuse menüükirje +Comment[eu]=Plasmaren bilaketa- eta abiarazte-jarduerako menu-sarrera +Comment[fi]=Valikkorivi Plasma-etsintä- ja -käynnistysaktiviteettiin +Comment[fr]=Entrée de menu pour l'activité de Plasma pour la recherche et le lancement +Comment[fy]=Menu ynfier foar de Plasma syk en útfier aktiviteit +Comment[gl]=Unha entrada no menú para a actividade de busca e inicio de Plasma +Comment[he]=רשומה בתפריט לפעילות החיפוש וההפעלה של Plasma +Comment[hr]=Stavka izbornika za Plasminu "traži i pokreni" aktivnost +Comment[hu]=Menübejegyzés a Plasma keresés és indítás aktivitáshoz +Comment[ia]=Entrata de menu pro activitate de Plasma per cercar e lancear +Comment[id]=Lema menu untuk aktivitas pencarian dan peluncuran Plasma +Comment[is]=Valmyndarfærsla fyrir aðgerð í Plasma leit- og ræsingu +Comment[ja]=Plasma 検索と起動メニュー用のメニューエントリ +Comment[kk]=Plasma-да іздеу және жегуді орындайтын мәзір бабы +Comment[km]=ធាតុ​ម៉ឺនុយ​សម្រាប់​កា​រស្វែងរក​ប្លាស្មា និង​​ចាប់ផ្ដើម​សកម្មភាព +Comment[ko]=Plasma 찾아서 실행 활동을 위한 메뉴 항목 +Comment[lt]=Plazmos meniu įrašas, skirtas paieškai ir programų paleidimui +Comment[lv]=Izvēlnes ieraksts Plasma meklēšanas un palaišanas nodarbei +Comment[mk]=Ставка од мени за активноста „Пребарување и стартување преку Плазма“ +Comment[ml]=പ്ലാസ്മാ തെരച്ചില്‍ വിക്ഷേപണ പ്രവര്‍ത്തനങ്ങള്‍ക്കുള്ള മെനുവിലെ വരി +Comment[mr]=शोधा व प्रक्षेपण करा या प्लाज्मा कार्यपध्दतीची मेन्यू नोंद +Comment[nb]=Menyinnslag for Plasmas søk-og-start-aktivitet +Comment[nds]=Menüindrag för de Plasma-Aktiviteet »Söken un Opropen« +Comment[nl]=Menu-item voor de Plasma zoeken en starten activiteit +Comment[nn]=Menyoppføring av søk- og køyr i Plasma +Comment[pa]=ਪਲਾਜ਼ਮਾ ਖੋਜ ਤੇ ਲਾਂਚ ਸਰਗਰਮੀ ਲਈ ਮੇਨੂ ਐਂਟਰੀ +Comment[pl]=Wpis menu dla działania Plazmy "znajdź i uruchom" +Comment[pt]=Item do menu para a actividade de pesquisa e lançamento do Plasma +Comment[pt_BR]=Entrada do menu para a atividade de pesquisa e execução do Plasma +Comment[ro]=Înregistrare de meniu pentru activitatea de căutare și lansare Plasma +Comment[ru]=Пункт меню для поиска и запуска комнат Plasma +Comment[si]=ප්ලාස්මා සොයා ක්‍රියාකරවන ක්‍රියාවලියට මෙනු ඇතුළත් කිරීමක් +Comment[sk]=Položka menu pre aktivitu plasmy Hľadať a spustiť +Comment[sl]=Menijski vnos za dejavnost iskanja in zaganjanja +Comment[sr]=Ставка менија за активност плазма претраге и покретања +Comment[sr@ijekavian]=Ставка менија за активност плазма претраге и покретања +Comment[sr@ijekavianlatin]=Stavka menija za aktivnost plasma pretrage i pokretanja +Comment[sr@latin]=Stavka menija za aktivnost plasma pretrage i pokretanja +Comment[sv]=Menyalternativ för sök- och startåtgärder i Plasma +Comment[tg]=Менюи воридот барои ҷустуҷӯ ва оғози фаъолияти Plasma +Comment[th]=รายการเมนูของกิจกรรมพลาสมารูปแบบค้นหาและเมนูเรียกใช้งาน +Comment[tr]=Plasma ara ve çalıştır etkinliği için menü girdisi +Comment[ug]=پلازمىنىڭ تىزىملىك تۈرىنى ئىزدەپ ئىجرا قىلىدۇ +Comment[uk]=Пункт меню для простору дій пошуку і запису Плазми +Comment[wa]=Intrêye del dressêye pol cweraedje di Plasma eyet l' activité d' enondeu +Comment[x-test]=xxMenu entry for The Plasma search and launch activityxx +Comment[zh_CN]=搜索与启动 Plasma 的菜单项 +Comment[zh_TW]=Plasma 搜尋與啟動的選單項目 + +[PropertyDef::X-Plasma-Sal-Url] +Type=QString + +[PropertyDef::X-Plasma-Sal-Relevance] +Type=int + + + diff --git a/plasma/netbook/containments/sal/resultwidget.cpp b/plasma/netbook/containments/sal/resultwidget.cpp new file mode 100644 index 00000000..4fd23d06 --- /dev/null +++ b/plasma/netbook/containments/sal/resultwidget.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "resultwidget.h" + +#include +#include + +ResultWidget::ResultWidget(QGraphicsItem *parent) + : Plasma::IconWidget(parent), + m_shouldBeVisible(true) +{ + m_animation = new QPropertyAnimation(this, "pos", this); + m_animation->setEasingCurve(QEasingCurve::InOutQuad); + m_animation->setDuration(250); + connect(m_animation, SIGNAL(finished()), this, SLOT(animationFinished())); +} + +ResultWidget::~ResultWidget() +{ +} + +void ResultWidget::animateHide() +{ + m_shouldBeVisible = false; + QGraphicsItem *parent = parentItem(); + if (parent) { + animatePos(QPoint(parent->boundingRect().center().x(), parent->boundingRect().bottom())); + } +} + +void ResultWidget::animatePos(const QPointF &point) +{ + m_animation->stop(); + m_animation->setStartValue(pos()); + m_animation->setEndValue(point); + m_animation->start(); +} + +void ResultWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Plasma::IconWidget::mousePressEvent(event); +} + +void ResultWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + const int distance = QPointF(boundingRect().center() - event->pos()).manhattanLength(); + + //arbitrary drag distance: this has to be way more than the usual: + //double of the average of width and height + if (distance > ((size().width() + size().height())/2)*2) { + emit dragStartRequested(this); + } + + Plasma::IconWidget::mouseMoveEvent(event); +} + +void ResultWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Plasma::IconWidget::mouseReleaseEvent(event); +} + +void ResultWidget::animationFinished() +{ + setVisible(m_shouldBeVisible); +} + +QVariant ResultWidget::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == QGraphicsItem::ItemVisibleChange) { + m_shouldBeVisible = value.toBool(); + } + + return QGraphicsWidget::itemChange(change, value); +} + + +#include "resultwidget.moc" diff --git a/plasma/netbook/containments/sal/resultwidget.h b/plasma/netbook/containments/sal/resultwidget.h new file mode 100644 index 00000000..9fc5ae3b --- /dev/null +++ b/plasma/netbook/containments/sal/resultwidget.h @@ -0,0 +1,56 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_RESULTWIDGET_H +#define PLASMA_RESULTWIDGET_H + + +#include + +class QPropertyAnimation; + +class ResultWidget : public Plasma::IconWidget +{ + Q_OBJECT +public: + ResultWidget(QGraphicsItem *parent); + ~ResultWidget(); + + void animateHide(); + void animatePos(const QPointF &point); + + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + +protected Q_SLOTS: + void animationFinished(); + +Q_SIGNALS: + void dragStartRequested(ResultWidget *); + +private: + QPropertyAnimation *m_animation; + bool m_shouldBeVisible; +}; + +#endif diff --git a/plasma/netbook/containments/sal/runnersconfig.cpp b/plasma/netbook/containments/sal/runnersconfig.cpp new file mode 100644 index 00000000..40765002 --- /dev/null +++ b/plasma/netbook/containments/sal/runnersconfig.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2008 Ryan P. Bitanga + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "runnersconfig.h" + +#include + +#include +#include +#include +#include + +#include + + +RunnersConfig::RunnersConfig(Plasma::RunnerManager *manager, QWidget *parent) + : KPluginSelector(parent), + m_manager(manager) +{ + connect(this, SIGNAL(configCommitted(QByteArray)), this, SLOT(updateRunner(QByteArray))); + + KService::List offers = KServiceTypeTrader::self()->query("Plasma/Runner"); + QList runnerInfo = KPluginInfo::fromServices(offers); + addPlugins(runnerInfo, KPluginSelector::ReadConfigFile, i18n("Available Features"), QString(), KGlobal::config()); +} + +void RunnersConfig::updateRunner(const QByteArray &name) +{ + Plasma::AbstractRunner *runner = m_manager->runner(name); + //Update runner if runner is loaded + if (runner) { + runner->reloadConfiguration(); + } +} + +RunnersConfig::~RunnersConfig() +{ +} + +void RunnersConfig::accept() +{ + save(); + m_manager->reloadConfiguration(); + close(); +} + +#include "runnersconfig.moc" + diff --git a/plasma/netbook/containments/sal/runnersconfig.h b/plasma/netbook/containments/sal/runnersconfig.h new file mode 100644 index 00000000..608bcb65 --- /dev/null +++ b/plasma/netbook/containments/sal/runnersconfig.h @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Ryan P. Bitanga + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KRUNNERCONFIG_H +#define KRUNNERCONFIG_H + +#include + + + +class KPluginSelector; + +namespace Plasma { + class RunnerManager; +} + +class RunnersConfig : public KPluginSelector +{ +Q_OBJECT + public: + RunnersConfig(Plasma::RunnerManager *manager, QWidget *parent = 0); + ~RunnersConfig(); + + public slots: + void accept(); + + private slots: + void updateRunner(const QByteArray& runnerName); + + private: + void init(); + + KPluginSelector *m_sel; + Plasma::RunnerManager *m_manager; +}; + +#endif + diff --git a/plasma/netbook/containments/sal/sal.cpp b/plasma/netbook/containments/sal/sal.cpp new file mode 100644 index 00000000..c4759746 --- /dev/null +++ b/plasma/netbook/containments/sal/sal.cpp @@ -0,0 +1,753 @@ +/* + * Copyright 2009 by Aaron Seigo + * Copyright 2009 by Artur Duque de Souza + * Copyright 2009 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sal.h" +#include "stripwidget.h" +#include "itemview.h" +#include "runnersconfig.h" +#include "../common/linearappletoverlay.h" +#include "../common/appletmovespacer.h" +#include "iconactioncollection.h" +#include "models/commonmodel.h" +#include "models/kservicemodel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +SearchLaunch::SearchLaunch(QObject *parent, const QVariantList &args) + : Containment(parent, args), + m_runnerModel(0), + m_serviceModel(0), + m_backButton(0), + m_queryCounter(0), + m_maxColumnWidth(0), + m_searchField(0), + m_resultsView(0), + m_orientation(Qt::Vertical), + m_firstItem(0), + m_appletsLayout(0), + m_appletOverlay(0), + m_iconActionCollection(0), + m_stripUninitialized(true) +{ + setContainmentType(Containment::CustomContainment); + m_iconActionCollection = new IconActionCollection(this, this); + setHasConfigurationInterface(true); + setFocusPolicy(Qt::StrongFocus); + setFlag(QGraphicsItem::ItemIsFocusable, true); + m_background = new Plasma::FrameSvg(this); + m_background->setImagePath("widgets/frame"); + m_background->setElementPrefix("raised"); + m_background->setEnabledBorders(Plasma::FrameSvg::BottomBorder); +} + +SearchLaunch::~SearchLaunch() +{ + KConfigGroup cg = config(); + m_stripWidget->save(cg); + config().writeEntry("orientation", (int)m_orientation); +} + +void SearchLaunch::init() +{ + Containment::init(); + connect(this, SIGNAL(appletAdded(Plasma::Applet*,QPointF)), + this, SLOT(layoutApplet(Plasma::Applet*,QPointF))); + connect(this, SIGNAL(appletRemoved(Plasma::Applet*)), + this, SLOT(appletRemoved(Plasma::Applet*))); + + connect(this, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(updateConfigurationMode(bool))); + + + setToolBox(Plasma::AbstractToolBox::load(corona()->preferredToolBoxPlugin(Plasma::Containment::DesktopContainment), QVariantList(), this)); + + QAction *a = action("add widgets"); + if (a) { + addToolBoxAction(a); + } + + + if (toolBox()) { + connect(toolBox(), SIGNAL(toggled()), this, SIGNAL(toolBoxToggled())); + connect(toolBox(), SIGNAL(visibilityChanged(bool)), this, SIGNAL(toolBoxVisibilityChanged(bool))); + toolBox()->show(); + } + + a = action("configure"); + if (a) { + addToolBoxAction(a); + a->setText(i18n("Configure Search and Launch")); + } + + + QAction *lockAction = 0; + if (corona()) { + lockAction = corona()->action("lock widgets"); + } + + if (!lockAction || !lockAction->isEnabled()) { + lockAction = new QAction(this); + addAction("lock page", lockAction); + lockAction->setText(i18n("Lock Page")); + lockAction->setIcon(KIcon("object-locked")); + QObject::connect(lockAction, SIGNAL(triggered(bool)), this, SLOT(toggleImmutability())); + } + + addToolBoxAction(lockAction); + + //FIXME: two different use cases for the desktop and the newspaper, another reason to move the toolbox management out of here + QAction *activityAction = 0; + if (corona()) { + activityAction = corona()->action("manage activities"); + } + if (activityAction) { + addToolBoxAction(activityAction); + } + + a = new QAction(i18n("Next activity"), this); + addAction("next containment", a); + a = new QAction(i18n("Previous activity"), this); + addAction("previous containment", a); + + if (corona()) { + connect(corona(), SIGNAL(availableScreenRegionChanged()), this, SLOT(availableScreenRegionChanged())); + availableScreenRegionChanged(); + } + + Plasma::FormFactor form = formFactor(); + Qt::Orientation layoutOtherDirection = form == Plasma::Vertical ? \ + Qt::Horizontal : Qt::Vertical; + + // create main layout + m_mainLayout = new QGraphicsLinearLayout(); + m_mainLayout->setOrientation(layoutOtherDirection); + m_mainLayout->setContentsMargins(0, 0, 0, 0); + m_mainLayout->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Expanding)); + setLayout(m_mainLayout); + + // create launch grid and make it centered + m_resultsLayout = new QGraphicsLinearLayout; + + + m_resultsView = new ItemView(this); + + m_resultsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_resultsView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_resultsLayout->addItem(m_resultsView); + + connect(m_resultsView, SIGNAL(dragStartRequested(QModelIndex)), this, SLOT(resultsViewRequestedDrag(QModelIndex))); + connect(m_resultsView, SIGNAL(itemActivated(QModelIndex)), this, SLOT(launch(QModelIndex))); + connect(m_resultsView, SIGNAL(addActionTriggered(QModelIndex)), this, SLOT(addFavourite(QModelIndex))); + + + //TODO how to do the strip widget? + m_stripWidget = new StripWidget(this); + m_stripWidget->setImmutability(immutability()); + connect(m_stripWidget, SIGNAL(saveNeeded()), this, SLOT(saveFavourites())); + + //load all config, only at this point we are sure it won't crash + configChanged(); + + m_appletsLayout = new QGraphicsLinearLayout(Qt::Horizontal); + m_appletsLayout->setPreferredHeight(KIconLoader::SizeMedium); + m_appletsLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + QGraphicsWidget *leftSpacer = new QGraphicsWidget(this); + QGraphicsWidget *rightSpacer = new QGraphicsWidget(this); + m_appletsLayout->addItem(leftSpacer); + m_appletsLayout->addItem(rightSpacer); + + m_backButton = new Plasma::IconWidget(this); + m_backButton->setIcon(KIcon("go-previous")); + m_backButton->setText(i18n("Back")); + m_backButton->setOrientation(Qt::Horizontal); + m_backButton->setPreferredSize(m_backButton->sizeFromIconSize(KIconLoader::SizeSmallMedium)); + connect(m_backButton, SIGNAL(clicked()), this, SLOT(reset())); + connect(m_resultsView, SIGNAL(resetRequested()), this, SLOT(reset())); + + QGraphicsAnchorLayout *searchLayout = new QGraphicsAnchorLayout(); + searchLayout->setSpacing(10); + + m_searchField = new Plasma::LineEdit(this); + m_searchField->setPreferredWidth(200); + m_searchField->nativeWidget()->setClearButtonShown(true); + m_searchField->nativeWidget()->setClickMessage(i18n("Search...")); + connect(m_searchField, SIGNAL(returnPressed()), this, SLOT(searchReturnPressed())); + connect(m_searchField->nativeWidget(), SIGNAL(textEdited(QString)), this, SLOT(delayedQuery())); + m_searchTimer = new QTimer(this); + m_searchTimer->setSingleShot(true); + connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(query())); + searchLayout->addAnchor(m_searchField, Qt::AnchorHorizontalCenter, searchLayout, Qt::AnchorHorizontalCenter); + searchLayout->addAnchors(m_searchField, searchLayout, Qt::Vertical); + searchLayout->addAnchors(m_backButton, searchLayout, Qt::Vertical); + searchLayout->addAnchor(m_backButton, Qt::AnchorRight, m_searchField, Qt::AnchorLeft); + + + // add our layouts to main vertical layout + m_mainLayout->addItem(m_stripWidget); + m_mainLayout->addItem(searchLayout); + m_mainLayout->addItem(m_resultsLayout); + + + // correctly set margins + m_mainLayout->activate(); + m_mainLayout->updateGeometry(); + + setTabOrder(m_stripWidget, m_searchField); + setTabOrder(m_searchField, m_resultsView); + setFormFactorFromLocation(location()); + + if (action("remove")) { + addToolBoxAction(action("remove")); + } +} + +void SearchLaunch::launchPackageManager() +{ + if (toolBox()) { + toolBox()->setShowing(false); + } + KRun::run(*m_packageManagerService.data(), KUrl::List(), 0); +} + +void SearchLaunch::configChanged() +{ + setOrientation((Qt::Orientation)config().readEntry("Orientation", (int)Qt::Vertical)); + + m_stripWidget->setIconSize(config().readEntry("FavouritesIconSize", (int)KIconLoader::SizeLarge)); + + m_resultsView->setIconSize(config().readEntry("ResultsIconSize", (int)KIconLoader::SizeHuge)); + + const QString packageManagerName = config().readEntry("PackageManager", "kpackagekit"); + if (!packageManagerName.isEmpty()) { + m_packageManagerService = KService::serviceByDesktopName(packageManagerName); + + if (!action("add applications") && m_packageManagerService && !m_packageManagerService->exec().isEmpty()) { + KAction *addApplicationsAction = new KAction(this); + addAction("add applications", addApplicationsAction); + addApplicationsAction->setText(i18n("Add applications")); + addApplicationsAction->setIcon(KIcon("applications-other")); + addToolBoxAction(addApplicationsAction); + + connect(addApplicationsAction, SIGNAL(triggered()), this, SLOT(launchPackageManager())); + } + } + + if (m_serviceModel) { + m_serviceModel->setPath("/"); + } + restoreStrip(); + m_stripUninitialized = false; +} + +void SearchLaunch::availableScreenRegionChanged() +{ + if (!corona()) { + return; + } + + QRect maxRect; + int maxArea = 0; + //we don't want the bounding rect (that could include panels too), but the maximumone representing the desktop + foreach (const QRect &rect, corona()->availableScreenRegion(screen()).rects()) { + int area = rect.width() * rect.height(); + if (area > maxArea) { + maxRect = rect; + maxArea = area; + } + } + + QGraphicsView *ownView = view(); + + //FIXME: the second check is a workaround to a qt bug: when a qwidget has just been created, maptoglobal and mapfromglobal aren't symmetryc. remove as soon as the bug is fixed + if (ownView && (ownView->mapFromGlobal(QPoint(0,0)) == -ownView->mapToGlobal(QPoint(0,0)))) { + maxRect.moveTopLeft(ownView->mapFromGlobal(maxRect.topLeft())); + } + + maxRect.moveTopLeft(QPoint(qMax(0, maxRect.left()), qMax(0, maxRect.top()))); + + setContentsMargins(maxRect.left(), maxRect.top(), qMax((qreal)0.0, size().width() - maxRect.right()), qMax((qreal)0.0, size().height() - maxRect.bottom())); +} + +void SearchLaunch::toggleImmutability() +{ + if (immutability() == Plasma::UserImmutable) { + setImmutability(Plasma::Mutable); + } else if (immutability() == Plasma::Mutable) { + setImmutability(Plasma::UserImmutable); + } +} + +void SearchLaunch::doSearch(const QString &query, const QString &runner) +{ + if (!query.isEmpty()) { + m_resultsView->setModel(m_runnerModel); + } else { + m_resultsView->setModel(m_serviceModel); + m_serviceModel->setPath("/"); + } + + m_runnerModel->setQuery(query, runner); + m_lastQuery = query; + //enable or disable drag and drop + if (immutability() == Plasma::Mutable && (m_resultsView->model() != m_serviceModel || m_serviceModel->path() != "/")) { + m_resultsView->setDragAndDropMode(ItemContainer::CopyDragAndDrop); + } else { + m_resultsView->setDragAndDropMode(ItemContainer::NoDragAndDrop); + } +} + +void SearchLaunch::reset() +{ + if (m_resultsView->model() != m_serviceModel || m_serviceModel->path() != "/") { + m_searchField->setText(QString()); + doSearch(QString()); + m_serviceModel->setPath("/"); + m_resultsView->setModel(m_serviceModel); + } +} + +void SearchLaunch::launch(QModelIndex index) +{ + KUrl url(index.data(CommonModel::Url).value()); + + if (m_resultsView->model() == m_runnerModel) { + KRunnerItemHandler::openUrl(url); + emit releaseVisualFocus(); + } else { + QString id = url.path(); + if (id.startsWith(QLatin1Char('/'))) { + id = id.remove(0, 1); + } + if (url.protocol() == "kservicegroup") { + m_serviceModel->setPath(id); + } else if (url.protocol() == "krunner") { + m_resultsView->setModel(m_runnerModel); + m_runnerModel->setQuery(id, url.host()); + } else { + KServiceItemHandler::openUrl(url); + reset(); + emit releaseVisualFocus(); + } + } + + //enable or disable drag and drop + if (immutability() == Plasma::Mutable && (m_resultsView->model() != m_serviceModel || m_serviceModel->path() != "/")) { + m_resultsView->setDragAndDropMode(ItemContainer::CopyDragAndDrop); + } else { + m_resultsView->setDragAndDropMode(ItemContainer::NoDragAndDrop); + } +} + +void SearchLaunch::addFavourite(const QModelIndex &index) +{ + QMimeData *mimeData = m_resultsView->model()->mimeData(QModelIndexList()<urls().isEmpty()) { + m_stripWidget->add(mimeData->urls().first()); + } +} + +void SearchLaunch::layoutApplet(Plasma::Applet* applet, const QPointF &pos) +{ + Q_UNUSED(pos); + + if (!m_appletsLayout) { + return; + } + + if (m_appletsLayout->count() == 2) { + m_mainLayout->removeItem(m_appletsLayout); + m_mainLayout->addItem(m_appletsLayout); + } + + Plasma::FormFactor f = formFactor(); + int insertIndex = -1; + + //if pos is (-1,-1) insert at the end of the panel + if (pos != QPoint(-1, -1)) { + for (int i = 1; i < m_appletsLayout->count()-1; ++i) { + if (!dynamic_cast(m_appletsLayout->itemAt(i)) && + !dynamic_cast(m_appletsLayout->itemAt(i))) { + continue; + } + + QRectF siblingGeometry = m_appletsLayout->itemAt(i)->geometry(); + if (f == Plasma::Horizontal) { + qreal middle = (siblingGeometry.left() + siblingGeometry.right()) / 2.0; + if (pos.x() < middle) { + insertIndex = i; + break; + } else if (pos.x() <= siblingGeometry.right()) { + insertIndex = i + 1; + break; + } + } else { // Plasma::Vertical + qreal middle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0; + if (pos.y() < middle) { + insertIndex = i; + break; + } else if (pos.y() <= siblingGeometry.bottom()) { + insertIndex = i + 1; + break; + } + } + } + } + + if (insertIndex != -1) { + m_appletsLayout->insertItem(insertIndex, applet); + } else { + m_appletsLayout->insertItem(m_appletsLayout->count()-1, applet); + } + + applet->setBackgroundHints(NoBackground); +} + +void SearchLaunch::appletRemoved(Plasma::Applet* applet) +{ + Q_UNUSED(applet) + + if (!m_appletOverlay && m_appletsLayout->count() == 3) { + m_mainLayout->removeItem(m_appletsLayout); + } +} + +void SearchLaunch::constraintsEvent(Plasma::Constraints constraints) +{ + //kDebug() << "constraints updated with" << constraints << "!!!!!!"; + + if (constraints & Plasma::FormFactorConstraint || + constraints & Plasma::StartupCompletedConstraint) { + + // create the models + if (!m_runnerModel) { + m_runnerModel = new KRunnerModel(this); + m_serviceModel = new KServiceModel(config(), this); + m_resultsView->setModel(m_serviceModel); + } + + resize(corona()->screenGeometry(screen()).size()); + } + + if (constraints & Plasma::LocationConstraint) { + setFormFactorFromLocation(location()); + } + + if (constraints & Plasma::SizeConstraint) { + availableScreenRegionChanged(); + if (m_appletsLayout) { + m_appletsLayout->setMaximumHeight(size().height()/4); + } + if (m_appletOverlay) { + m_appletOverlay->resize(size()); + } + } + + if (constraints & Plasma::StartupCompletedConstraint) { + Plasma::DataEngine *engine = dataEngine("searchlaunch"); + engine->connectSource("query", this); + } + + if (constraints & Plasma::ScreenConstraint) { + if (screen() != -1 && m_searchField) { + m_searchField->setFocus(); + } + } + + if (constraints & Plasma::ImmutableConstraint) { + //update lock button + QAction *a = action("lock page"); + if (a) { + switch (immutability()) { + case Plasma::SystemImmutable: + a->setEnabled(false); + a->setVisible(false); + break; + + case Plasma::UserImmutable: + a->setText(i18n("Unlock Page")); + a->setIcon(KIcon("object-unlocked")); + a->setEnabled(true); + a->setVisible(true); + break; + + case Plasma::Mutable: + a->setText(i18n("Lock Page")); + a->setIcon(KIcon("object-locked")); + a->setEnabled(true); + a->setVisible(true); + break; + } + } + + //kill or create the config overlay if needed + if (immutability() == Plasma::Mutable && !m_appletOverlay && toolBox() && toolBox()->isShowing()) { + m_appletOverlay = new LinearAppletOverlay(this, m_appletsLayout); + m_appletOverlay->resize(size()); + } else if (immutability() != Plasma::Mutable && m_appletOverlay && toolBox() && toolBox()->isShowing()) { + m_appletOverlay->deleteLater(); + m_appletOverlay = 0; + } + + //enable or disable drag and drop + if (immutability() == Plasma::Mutable && (m_resultsView->model() != m_serviceModel || m_serviceModel->path() != "/")) { + m_resultsView->setDragAndDropMode(ItemContainer::CopyDragAndDrop); + } else { + m_resultsView->setDragAndDropMode(ItemContainer::NoDragAndDrop); + } + m_stripWidget->setImmutability(immutability()); + } +} + +void SearchLaunch::setOrientation(Qt::Orientation orientation) +{ + if (m_orientation == orientation) { + return; + } + + m_orientation = orientation; + m_resultsView->setOrientation(orientation); +} + +void SearchLaunch::setFormFactorFromLocation(Plasma::Location loc) +{ + switch (loc) { + case Plasma::BottomEdge: + case Plasma::TopEdge: + //kDebug() << "setting horizontal form factor"; + setFormFactor(Plasma::Horizontal); + break; + case Plasma::RightEdge: + case Plasma::LeftEdge: + //kDebug() << "setting vertical form factor"; + setFormFactor(Plasma::Vertical); + break; + default: + setFormFactor(Plasma::Horizontal); + } +} + +void SearchLaunch::restoreStrip() +{ + KConfigGroup cg = config(); + m_stripWidget->restore(cg); + //reset(); +} + +void SearchLaunch::updateConfigurationMode(bool config) +{ + + if (config && !m_appletOverlay && immutability() == Plasma::Mutable) { + if (m_appletsLayout->count() == 2) { + m_mainLayout->addItem(m_appletsLayout); + } + m_appletOverlay = new LinearAppletOverlay(this, m_appletsLayout); + m_appletOverlay->resize(size()); + connect (m_appletOverlay, SIGNAL(dropRequested(QGraphicsSceneDragDropEvent*)), + this, SLOT(overlayRequestedDrop(QGraphicsSceneDragDropEvent*))); + } else if (!config) { + delete m_appletOverlay; + m_appletOverlay = 0; + if (m_appletsLayout->count() == 2) { + m_mainLayout->removeItem(m_appletsLayout); + } + } +} + +void SearchLaunch::overlayRequestedDrop(QGraphicsSceneDragDropEvent *event) +{ + dropEvent(event); +} + + +void SearchLaunch::resultsViewRequestedDrag(QModelIndex index) +{ + if (!m_resultsView->model()) { + return; + } + + + QModelIndexList list; + list.append(index); + QMimeData *mimeData = m_resultsView->model()->mimeData(list); + + QDrag *drag = new QDrag(view()); + drag->setMimeData(mimeData); + drag->setPixmap(index.data(Qt::DecorationRole).value().pixmap(KIconLoader::SizeHuge, KIconLoader::SizeHuge)); + + drag->exec(Qt::CopyAction); +} + +void SearchLaunch::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *, const QRect &) +{ + if (m_stripUninitialized) { + m_stripUninitialized = false; + QTimer::singleShot(100, this, SLOT(restoreStrip())); + } else { + m_background->resizeFrame(QSizeF(size().width(), m_stripWidget->geometry().bottom())); + m_background->paintFrame(painter); + } +} + +void SearchLaunch::delayedQuery() +{ + m_searchTimer->start(500); +} + +void SearchLaunch::query() +{ + QString query = m_searchField->text(); + doSearch(query); + m_lastQuery = query; +} + +void SearchLaunch::searchReturnPressed() +{ + QString query = m_searchField->text(); + //by pressing enter do a query or + if (query == m_lastQuery && !query.isEmpty()) { + launch(m_resultsView->model()->index(0, 0, QModelIndex())); + reset(); + } else { + doSearch(query); + m_lastQuery = query; + } +} + +void SearchLaunch::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) +{ + Q_UNUSED(sourceName); + + const QString query(data["query"].toString()); + //Take ownership of the screen if we don't have one + //FIXME: hardcoding 0 is bad: maybe pass the screen from the dataengine? + if (!query.isEmpty()) { + if (screen() < 0) { + setScreen(0); + } + emit activate(); + } + + doSearch(query); + if (m_searchField) { + m_searchField->setText(query); + } +} + +void SearchLaunch::focusInEvent(QFocusEvent *event) +{ + if (m_searchField) { + m_searchField->setFocus(); + } + if (screen() < 0) { + setScreen(0); + } + Containment::focusInEvent(event); +} + +void SearchLaunch::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::ContentsRectChange) { + + if (toolBox() && toolBox()->isShowing()) { + updateConfigurationMode(true); + } + } + Plasma::Containment::changeEvent(event); +} + +void SearchLaunch::createConfigurationInterface(KConfigDialog *parent) +{ + RunnersConfig *runnersConfig = new RunnersConfig(m_runnerModel->runnerManager(), parent); + parent->addPage(runnersConfig, i18nc("Title of the page that lets the user choose the loaded krunner plugins", "Search plugins"), "edit-find"); + + connect(parent, SIGNAL(applyClicked()), runnersConfig, SLOT(accept())); + connect(parent, SIGNAL(okClicked()), runnersConfig, SLOT(accept())); + + QListView *enabledEntries = new QListView(parent); + enabledEntries->setModel(m_serviceModel->allRootEntriesModel()); + enabledEntries->setModelColumn(0); + parent->addPage(enabledEntries, i18nc("Title of the page that lets the user choose what entries will be allowed in the main menu", "Main menu"), "view-list-icons"); + + QWidget *page = new QWidget; + QVBoxLayout *layout = new QVBoxLayout(page); + + if (!m_shortcutEditor) { + m_shortcutEditor = new KKeySequenceWidget(page); + connect(parent, SIGNAL(applyClicked()), this, SLOT(configDialogFinished())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configDialogFinished())); + } + + m_shortcutEditor.data()->setKeySequence(globalShortcut().primary()); + layout->addWidget(m_shortcutEditor.data()); + layout->addStretch(); + parent->addPage(page, i18n("Keyboard Shortcut"), "preferences-desktop-keyboard"); + + connect(parent, SIGNAL(applyClicked()), m_serviceModel, SLOT(saveConfig())); + connect(parent, SIGNAL(okClicked()), m_serviceModel, SLOT(saveConfig())); +} + +void SearchLaunch::configDialogFinished() +{ + if (m_shortcutEditor) { + QKeySequence sequence = m_shortcutEditor.data()->keySequence(); + if (sequence != globalShortcut().primary()) { + setGlobalShortcut(KShortcut(sequence)); + emit configNeedsSaving(); + } + } +} + +void SearchLaunch::saveFavourites() +{ + KConfigGroup cg = config(); + m_stripWidget->save(cg); +} + +K_EXPORT_PLASMA_APPLET(sal, SearchLaunch) + +#include "sal.moc" + diff --git a/plasma/netbook/containments/sal/sal.h b/plasma/netbook/containments/sal/sal.h new file mode 100644 index 00000000..367934f7 --- /dev/null +++ b/plasma/netbook/containments/sal/sal.h @@ -0,0 +1,135 @@ +/* + * Copyright 2007 by Alex Merry + * Copyright 2008 by Alexis Ménard + * Copyright 2009 by Marco Martin + * Copyright 2009 by Artur Duque de Souza + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SEARCHLAUNCH_CONTAINMENT_H +#define SEARCHLAUNCH_CONTAINMENT_H + +#include "models/krunnermodel.h" + +#include +#include + +#include + +class QTimer; +class StripWidget; +class ItemView; +class LinearAppletOverlay; +class IconActionCollection; +class KRunnerModel; +class KServiceModel; +class KKeySequenceWidget; + +namespace Plasma +{ + class IconWidget; + class LineEdit; + class Frame; + class FrameSvg; +} + +class SearchLaunch : public Plasma::Containment +{ + Q_OBJECT +public: + SearchLaunch(QObject *parent, const QVariantList &args); + ~SearchLaunch(); + void init(); + + void setOrientation(Qt::Orientation orientation); + + void constraintsEvent(Plasma::Constraints constraints); + + void createConfigurationInterface(KConfigDialog *parent); + +protected: + void focusInEvent(QFocusEvent *event); + void paintInterface(QPainter *, const QStyleOptionGraphicsItem *, const QRect &); + void changeEvent(QEvent *event); + void doSearch(const QString &query, const QString &runner = QString()); + +public Q_SLOTS: + void configChanged(); + void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data); + +private Q_SLOTS: + void toggleImmutability(); + void layoutApplet(Plasma::Applet* applet, const QPointF &pos); + void appletRemoved(Plasma::Applet* applet); + void restoreStrip(); + void updateConfigurationMode(bool config); + void overlayRequestedDrop(QGraphicsSceneDragDropEvent *event); + void resultsViewRequestedDrag(QModelIndex index); + void availableScreenRegionChanged(); + void launchPackageManager(); + void configDialogFinished(); + + void delayedQuery(); + void query(); + void searchReturnPressed(); + void launch(QModelIndex index); + void addFavourite(const QModelIndex &index); + void reset(); + + void saveFavourites(); + +private: + /** + * update the formfactor based on the location + */ + void setFormFactorFromLocation(Plasma::Location loc); + + Plasma::FrameSvg *m_background; + KRunnerModel *m_runnerModel; + KServiceModel *m_serviceModel; + Plasma::IconWidget *m_backButton; + + int m_queryCounter; + int m_maxColumnWidth; + + QTimer *m_searchTimer; + + Plasma::LineEdit *m_searchField; + + ItemView *m_resultsView; + StripWidget *m_stripWidget; + + Qt::Orientation m_orientation; + QString m_lastQuery; + Plasma::IconWidget *m_firstItem; + + KSharedPtr m_packageManagerService; + + QGraphicsLinearLayout *m_mainLayout; + QGraphicsLinearLayout *m_resultsLayout; + QGraphicsLinearLayout *m_appletsLayout; + QPointF m_buttonDownMousePos; + LinearAppletOverlay *m_appletOverlay; + + IconActionCollection *m_iconActionCollection; + QWeakPointer m_shortcutEditor; + + bool m_stripUninitialized; +}; + + +#endif // PLASMA_SEARCHLAUNCH_H diff --git a/plasma/netbook/containments/sal/services/plasma-sal-bookmarks.desktop b/plasma/netbook/containments/sal/services/plasma-sal-bookmarks.desktop new file mode 100644 index 00000000..ebba0f54 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-bookmarks.desktop @@ -0,0 +1,169 @@ +[Desktop Entry] +Name=Bookmarks +Name[af]=Boekmerke +Name[ar]=العلامات +Name[as]=পত্ৰচিহ্ন +Name[ast]=Marcadores +Name[be]=Закладкі +Name[be@latin]=Zakładki +Name[bg]=Отметки +Name[bn]=বুকমার্ক +Name[bn_IN]=বুকমার্ক +Name[br]=Sinedoù +Name[bs]=Zabilješke +Name[ca]=Adreces d'interès +Name[ca@valencia]=Adreces d'interés +Name[cs]=Záložky +Name[csb]=Załóżczi +Name[cy]=Nodau Tudalen +Name[da]=Bogmærker +Name[de]=Lesezeichen +Name[el]=Σελιδοδείκτες +Name[en_GB]=Bookmarks +Name[eo]=Legosignoj +Name[es]=Marcadores +Name[et]=Järjehoidjad +Name[eu]=Laster-markak +Name[fa]=چوب الفها +Name[fi]=Kirjanmerkit +Name[fr]=Signets +Name[fy]=Blêdwizers +Name[ga]=Leabharmharcanna +Name[gl]=Marcadores +Name[gu]=બુકમાર્ક્સ +Name[he]=סימניות +Name[hi]= पसंदीदा +Name[hne]=निसानी +Name[hr]=Oznake +Name[hsb]=Lubuški +Name[hu]=Könyvjelzők +Name[ia]=Marcatores de libro +Name[id]=Penanda +Name[is]=Bókamerki +Name[ja]=ブックマーク +Name[ka]=სანიშნეები +Name[kk]=Бетбелгі +Name[km]=ចំណាំ +Name[kn]=ಅಂಕನಗಳು (ಬುಕ್ ಮಾರ್ಕ್) +Name[ko]=책갈피 +Name[ku]=Bijare +Name[lt]=Žymelės +Name[lv]=Grāmatzīmes +Name[mai]=पुस्तकचिह्न +Name[mk]=Обележувачи +Name[ml]=ഓര്‍മ്മക്കുറിപ്പുകള്‍ +Name[mr]=ओळखचिन्ह +Name[ms]=Tanda Buku +Name[nb]=Bokmerker +Name[nds]=Leestekens +Name[ne]=पुस्तकचिनो +Name[nl]=Bladwijzers +Name[nn]=Bokmerke +Name[oc]=Marca-paginas +Name[or]=ଚିହ୍ନିତ ସ୍ଥାନ +Name[pa]=ਬੁੱਕਮਾਰਕ +Name[pl]=Zakładki +Name[pt]=Favoritos +Name[pt_BR]=Favoritos +Name[ro]=Semne de carte +Name[ru]=Закладки +Name[se]=Girjemearkkat +Name[si]=පිටු සලකුණු +Name[sk]=Záložky +Name[sl]=Zaznamki +Name[sr]=Обележивачи +Name[sr@ijekavian]=Обиљеживачи +Name[sr@ijekavianlatin]=Obilježivači +Name[sr@latin]=Obeleživači +Name[sv]=Bokmärken +Name[ta]=நினைவுக்குறிகள் +Name[te]=పేజి గుర్తులు +Name[tg]=Хатчӯбмонӣ +Name[th]=ที่คั่นหน้า +Name[tr]=Yer İmleri +Name[ug]=خەتكۈشلەر +Name[uk]=Закладки +Name[uz]=Xatchoʻplar +Name[uz@cyrillic]=Хатчўплар +Name[vi]=Dấu trang +Name[wa]=Rimarkes +Name[xh]=Amanqaku eencwadi +Name[x-test]=xxBookmarksxx +Name[zh_CN]=书签 +Name[zh_TW]=書籤 +Comment=List all your bookmarks +Comment[ar]=اسرد كل علاماتك +Comment[ast]=Llistar tolos tos marcadores +Comment[bg]=Списък с отметките ви +Comment[bs]=Nabraja sve vaše zabilješke +Comment[ca]=Llista totes les adreces d'interès +Comment[ca@valencia]=Llista totes les adreces d'interés +Comment[cs]=Seznam všech vašich záložek +Comment[csb]=Wëskrzëni wszëtczé twòjé załóżczi +Comment[da]=Oplist alle dine bogmærker +Comment[de]=Alle Lesezeichen auflisten +Comment[el]=Λίστα με όλους τους σελιδοδείκτες +Comment[en_GB]=List all your bookmarks +Comment[eo]=Listi ĉiujn viajn legosignojn +Comment[es]=Listar todos sus marcadores +Comment[et]=Kõigi järjehoidjate loend +Comment[eu]=Zerrendatu laster-marka guztiak +Comment[fi]=Luettelo kaikista kirjanmerkeistäsi +Comment[fr]=Liste tous vos signets +Comment[fy]=All jo blêdwizers opsomme +Comment[ga]=Taispeáin do chuid leabharmharcanna +Comment[gl]=Enumera todos os marcadores +Comment[gu]=તમારા બધાં બુકમાર્ક્સની યાદી બતાવો +Comment[he]=משמש להצגת כל הסימניות שלך +Comment[hi]=सभी पसंदीदा दिखाएँ +Comment[hr]=Izlistaj sve moje oznake +Comment[hu]=Kilistázza az összes könyvjelzőt +Comment[ia]=Il lista tote tu marcatores de libro +Comment[id]=Tampilkan semua penanda anda +Comment[is]=Listar öll bókamerkin þín +Comment[ja]=すべてのブックマークを一覧表示します +Comment[kk]=Барлық бетбелгілер тізімі +Comment[km]=រាយ​ចំណាំ​របស់​អ្នក​ទាំងអស់ +Comment[kn]=ಇರಬಹುದಾದ ಎಲ್ಲಾ ಅಂಕನಗಳನ್ನು(ಬುಕ್ ಮಾರ್ಕ್) ಪಟ್ಟಿ ಮಾಡು +Comment[ko]=모든 책갈피를 표시합니다 +Comment[lt]=Rodyti visas jūsų žymeles +Comment[lv]=Parāda visas jūsu grāmatzīmes +Comment[mk]=Прикажете ги сите ваши обележувачи +Comment[ml]=എല്ലാ അടയാളക്കുറിപ്പുകളും കാണിയ്ക്കുക +Comment[mr]=तुमच्या सर्व ओळखचिन्हांची यादी करा +Comment[nb]=List alle dine bokmerker +Comment[nds]=All Dien Leestekens oplisten +Comment[nl]=Alle bladwijzers tonen +Comment[nn]=Vis alle bokmerka +Comment[pa]=ਤੁਹਾਡੇ ਸਭ ਬੁੱਕਮਾਰਕ ਦੀ ਲਿਸਟ +Comment[pl]=Wykaz wszystkich twoich zakładek +Comment[pt]=Apresentar todos os seus favoritos +Comment[pt_BR]=Lista todos os seus favoritos +Comment[ro]=Enumeră toate semnele de carte +Comment[ru]=Список всех ваших закладок +Comment[si]=ඔබේ පොත්සලකුණු සියල්ල ලැයිස්තුගත කරන්න +Comment[sk]=Zoznam všetkých záložiek +Comment[sl]=Izpiše seznam vseh zaznamkov +Comment[sr]=Набраја све ваше обележиваче +Comment[sr@ijekavian]=Набраја све ваше обиљеживаче +Comment[sr@ijekavianlatin]=Nabraja sve vaše obilježivače +Comment[sr@latin]=Nabraja sve vaše obeleživače +Comment[sv]=Lista alla bokmärken +Comment[tg]=Ҷустуҷӯи замимаҳо +Comment[th]=เรียกดูที่คั่นหน้าทั้งหมดของคุณ +Comment[tr]=Tüm yer imlerini listele +Comment[ug]=ھەممە خەتكۈچلەر تىزىمى +Comment[uk]=Список всіх ваших закладок +Comment[vi]=Liệt kê tất cả đánh dấu trang của bạn +Comment[wa]=Fé l' djivêye di totes vos rimarkes +Comment[x-test]=xxList all your bookmarksxx +Comment[zh_CN]=列出所有书签 +Comment[zh_TW]=列出所有的書籤 +Icon=bookmarks + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-bookmarks + +X-Plasma-Sal-Url=krunner://bookmarks/bookmarks +X-Plasma-Sal-Relevance=9 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-contacts.desktop b/plasma/netbook/containments/sal/services/plasma-sal-contacts.desktop new file mode 100644 index 00000000..7f517544 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-contacts.desktop @@ -0,0 +1,146 @@ +[Desktop Entry] +Name=Contacts +Name[ar]=المراسلون +Name[ast]=Contautos +Name[bg]=Контакти +Name[bs]=kontakti +Name[ca]=Contactes +Name[ca@valencia]=Contactes +Name[cs]=Kontakty +Name[csb]=Łączbë +Name[da]=Kontakter +Name[de]=Kontakte +Name[el]=Επαφές +Name[en_GB]=Contacts +Name[eo]=Kontaktoj +Name[es]=Contactos +Name[et]=Kontaktid +Name[eu]=Kontaktuak +Name[fa]=تماسها +Name[fi]=Yhteystiedot +Name[fr]=Contacts +Name[fy]=Kontakten +Name[ga]=Teagmhálacha +Name[gl]=Contactos +Name[gu]=સંબંધો +Name[he]=אנשי קשר +Name[hi]=संपर्क +Name[hr]=Kontakti +Name[hu]=Névjegyek +Name[ia]=Contactos +Name[id]=Kontak +Name[is]=Tengiliðir +Name[ja]=連絡先 +Name[kk]=Контакттар +Name[km]=ទំនាក់ទំនង +Name[kn]=ಸಂಪರ್ಕ ವಿಳಾಸಗಳು +Name[ko]=연락처 +Name[lt]=Kontaktai +Name[lv]=Kontakti +Name[mk]=Контакти +Name[ml]=വിലാസങ്ങള്‍ +Name[mr]=संपर्क +Name[nb]=Kontakter +Name[nds]=Kontakten +Name[nl]=Contacts +Name[nn]=Kontaktar +Name[pa]=ਸੰਪਰਕ +Name[pl]=Kontakty +Name[pt]=Contactos +Name[pt_BR]=Contatos +Name[ro]=Contacte +Name[ru]=Контакты +Name[si]=සබඳතා +Name[sk]=Kontakty +Name[sl]=Stiki +Name[sr]=контакти +Name[sr@ijekavian]=контакти +Name[sr@ijekavianlatin]=kontakti +Name[sr@latin]=kontakti +Name[sv]=Kontakter +Name[tg]=Тамосҳо +Name[th]=ที่อยู่ติดต่อต่าง ๆ +Name[tr]=Kişiler +Name[ug]=ئالاقەداشلار +Name[uk]=Контакти +Name[vi]=Liên lạc +Name[wa]=Contaks +Name[x-test]=xxContactsxx +Name[zh_CN]=联系人 +Name[zh_TW]=聯絡人 +Comment=List all your contacts +Comment[ar]=اسرد جميع مراسليك +Comment[ast]=Llistar tolos contautos +Comment[bg]=Списък с контактите ви +Comment[bs]=Nabraja sve vaše kontakte +Comment[ca]=Llista tots els contactes +Comment[ca@valencia]=Llista tots els contactes +Comment[cs]=Seznam všech vašich kontaktů +Comment[csb]=Wëskrzëni wszëtczé twòjé łączbë +Comment[da]=Oplist alle dine kontakter +Comment[de]=Alle Kontakte auflisten +Comment[el]=Λίστα με όλες οι επαφές +Comment[en_GB]=List all your contacts +Comment[eo]=Listo de ĉiuj viaj kontaktoj +Comment[es]=Listar todos sus contactos +Comment[et]=Kõigi kontaktide loend +Comment[eu]=Zerrendatu kontaktu guztiak +Comment[fi]=Luettelo kaikista yhteystiedoistasi +Comment[fr]=Liste tous vos contacts +Comment[fy]=Al jo kontakten opsomme +Comment[ga]=Taispeáin do theagmhálacha go léir +Comment[gl]=Enumera todos os contactos +Comment[gu]=તમારા બધાં સંપર્કો બતાવે છે +Comment[he]=משמש להצגת כל אנשי הקשר שלך +Comment[hi]=अपने सभी संपर्क दिखाएँ +Comment[hr]=Izlistaj sve moje kontakte +Comment[hu]=Kilistázza az összes névjegyet +Comment[ia]=Il lista tote tu contactos +Comment[id]=Tampilkan semua kontak anda +Comment[is]=Listar alla tengiliðina þína +Comment[ja]=すべての連絡先を一覧表示します +Comment[kk]=Контакттарыңыздың тізімі +Comment[km]=រាយ​ទំនាក់ទំនង​របស់​អ្នក​ទាំងអស់​ +Comment[kn]=ನಿಮ್ಮ ಎಲ್ಲಾ ಸಂಪರ್ಕಗಳನ್ನು ಪಟ್ಟಿ ಮಾಡು +Comment[ko]=모든 연락처를 표시합니다 +Comment[lt]=Visų kontaktų sąrašas +Comment[lv]=Parāda visus jūsu kontaktus +Comment[mk]=Прикажете ги сите Ваши контакти +Comment[ml]=നിങ്ങളുടെ എല്ലാ വിലാസങ്ങളും കാണിയ്ക്കുക +Comment[mr]=तुमच्या सर्व संपर्कातील व्यक्तिंची यादी करा +Comment[nb]=List alle dine kontakter +Comment[nds]=All Dien Kontakten oplisten +Comment[nl]=Toon al uw contacten +Comment[nn]=Vis alle kontaktane +Comment[pa]=ਆਪਣੇ ਸਭ ਸੰਪਰਕ ਵੇਖੋ +Comment[pl]=Wykaz wszystkich twoich kontaktów +Comment[pt]=Apresentar todos os seus contactos +Comment[pt_BR]=Lista todos os seus contatos +Comment[ro]=Enumeră toate contactele +Comment[ru]=Список всех ваших контактов +Comment[si]=ඔබේ සබඳතා සියල්ල ලැයිස්තුගත කරන්න +Comment[sk]=Zoznam všetkých kontaktov +Comment[sl]=Izpiše seznam vseh stikov +Comment[sr]=Набраја све ваше контакте +Comment[sr@ijekavian]=Набраја све ваше контакте +Comment[sr@ijekavianlatin]=Nabraja sve vaše kontakte +Comment[sr@latin]=Nabraja sve vaše kontakte +Comment[sv]=Lista alla kontakter +Comment[tg]=Рӯйхати алоқаҳо +Comment[th]=เรียกดูรายการที่อยู่ติดต่อต่าง ๆ ของคุณ +Comment[tr]=Tüm kişileri listele +Comment[ug]=ھەممە ئالاقەداشلار تىزىمىڭىز +Comment[uk]=Список всіх ваших записів контактів +Comment[vi]=Liệt kê các liên lạc của bạn +Comment[wa]=Fé l' djivêye di tos vos contaks +Comment[x-test]=xxList all your contactsxx +Comment[zh_CN]=列出所有联系人 +Comment[zh_TW]=列出所有聯絡人 +Icon=view-pim-contacts + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-contacts + +X-Plasma-Sal-Url=krunner://kabccontacts/contacts +X-Plasma-Sal-Relevance=8 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-development.desktop b/plasma/netbook/containments/sal/services/plasma-sal-development.desktop new file mode 100644 index 00000000..6e2cf5c5 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-development.desktop @@ -0,0 +1,162 @@ +[Desktop Entry] +Name=Development +Name[af]=Ontwikkeling +Name[ar]=تطوير +Name[as]=বিকাশ +Name[ast]=Desendolcu +Name[be]=Распрацоўка +Name[be@latin]=Raspracoŭvańnie +Name[bg]=Разработка +Name[bn]=ডেভেলপমেন্ট +Name[bn_IN]=ডিভেলপমেন্ট +Name[br]=Diorren +Name[bs]=Razvoj +Name[ca]=Desenvolupament +Name[ca@valencia]=Desenvolupament +Name[cs]=Vývoj +Name[csb]=Nôrzãdza programistów +Name[cy]=Datblygu +Name[da]=Udvikling +Name[de]=Entwicklung +Name[el]=Ανάπτυξη +Name[en_GB]=Development +Name[eo]=Programado +Name[es]=Desarrollo +Name[et]=Arendus +Name[eu]=Garapena +Name[fa]=توسعه +Name[fi]=Kehitystyökalut +Name[fr]=Développement +Name[fy]=Untwikkelje +Name[ga]=Forbairt +Name[gl]=Desenvolvemento +Name[gu]=ડેવલોપમેન્ટ +Name[he]=פיתוח +Name[hi]=विकास +Name[hne]=विकास +Name[hr]=Razvoj +Name[hsb]=Wuwiwanje +Name[hu]=Fejlesztőeszközök +Name[ia]=Developpamento +Name[id]=Pengembangan +Name[is]=Forritaþróun +Name[it]=Sviluppo +Name[ka]=განვითარება +Name[kk]=Жетілдіру +Name[km]=ការ​​អភិវឌ្ឍន៍ +Name[kn]=ವಿಕಸನ +Name[ko]=개발 +Name[ku]=Pêşvebirin +Name[lt]=Programavimas +Name[lv]=Izstrāde +Name[mai]=विकास +Name[mk]=Развој +Name[ml]=വികസനം‌ +Name[mr]=विकास +Name[ms]=Pemaju +Name[nb]=Utvikling +Name[nds]=Utwickeln +Name[ne]=विकास +Name[nl]=Ontwikkeling +Name[nn]=Utvikling +Name[oc]=Desvolopament +Name[or]=ବିକାଶ +Name[pa]=ਡਿਵੈਲਪਮੈਂਟ +Name[pl]=Narzędzia programistów +Name[pt]=Desenvolvimento +Name[pt_BR]=Desenvolvimento +Name[ro]=Dezvoltare +Name[ru]=Разработка +Name[se]=Ovdánahttin +Name[si]=සංවර්‍ධණය +Name[sk]=Vývoj +Name[sl]=Razvoj +Name[sr]=Развој +Name[sr@ijekavian]=Развој +Name[sr@ijekavianlatin]=Razvoj +Name[sr@latin]=Razvoj +Name[sv]=Utveckling +Name[ta]=உருவாக்கம் +Name[te]=డెవలప్ మెంట్ +Name[tg]=Пешрафт +Name[th]=พัฒนาโปรแกรม +Name[tr]=Geliştirme +Name[ug]=ئىجادىيەت +Name[uk]=Розробка +Name[uz]=Tuzish +Name[uz@cyrillic]=Тузиш +Name[vi]=Phát triển +Name[wa]=Programaedje +Name[xh]=Ubhekiso phambili +Name[x-test]=xxDevelopmentxx +Name[zh_CN]=开发 +Name[zh_TW]=程式開發 +Comment=Applications targeted to software development +Comment[ar]=تطبيقات لتطوير البرامج +Comment[ast]=Aplicaciones orientaes al desendolcu de software +Comment[bg]=Програми за разработка на софтуер +Comment[bn]=সফটওয়্যার ডেভেলপমেন্ট সংক্রান্ত অ্যাপলিকেশন +Comment[bs]=Programi namijenjeni razvoju softvera +Comment[ca]=Aplicacions enfocades al desenvolupament de programari +Comment[ca@valencia]=Aplicacions enfocades al desenvolupament de programari +Comment[cs]=Aplikace změřené na vývoj softwaru +Comment[da]=Programmer til softwareudvikling +Comment[de]=Anwendungen für die Software-Entwicklung +Comment[el]=Εφαρμογές στοχευμένες στην ανάπτυξη λογισμικού +Comment[en_GB]=Applications targeted to software development +Comment[es]=Aplicaciones orientadas al desarrollo de software +Comment[et]=Tarkvara arendamiseks mõeldud rakendused +Comment[eu]=Softwarea garatzeko aplikazioak +Comment[fi]=Ohjelmistokehitykseen suunnatut sovellukset +Comment[fr]=Applications destinées au développement de logiciels +Comment[ga]=Feidhmchlár dírithe ar fhorbairt bhogearraí +Comment[gl]=Programas para o desenvolvemento de software +Comment[he]=יישומים המיועדים לפיתוח תוכנות +Comment[hr]=Aplikacije namijenjene za razvoj softvera +Comment[hu]=Szoftverfejlesztő alkalmazások +Comment[ia]=Applicationes adressate al disveloppamento de software +Comment[id]=Aplikasi yang ditargetkan untuk pengembangan peranti lunak +Comment[is]=Forrit sem nýtast til hugbúnaðarþróunar +Comment[ja]=ソフトウェア開発に向けたアプリケーション +Comment[kk]=Бағдарлама құрастыруға арналған қолданбалар +Comment[km]=កម្មវិធីមានគោលដៅ​​ទៅនឹង​ការអភិវឌ្ឍន៍​កម្មវិធី +Comment[kn]=ತಂತ್ರಾಂಶ ವಿನ್ಯಾಸಕ್ಕೆ ಗುರಿಯಾಗಿರಿಸಲ್ಪಟ್ಟ ಅನ್ವಯಗಳು +Comment[ko]=소프트웨어 개발을 위한 프로그램 +Comment[lt]=Programos, skirtos programų kūrimui +Comment[lv]=Uz programmatūras izstrādi mērķētas aplikācijas +Comment[mr]=सॉफ्टवेअर विकासाकरिता अनुप्रयोग +Comment[nb]=Programmer beregnet på programvareutvikling +Comment[nds]=Programmen för Programmschrievers +Comment[nl]=Applicaties bedoelt voor software ontwikkelen +Comment[pa]=ਸਾਫਟਵੇਅਰ ਡਿਵੈਲਪਮੈਂਟ ਲਈ ਐਪਲੀਕੇਸ਼ਨ ਟਾਰਗੇਟ +Comment[pl]=Programy przeznaczone dla programistów +Comment[pt]=Aplicações destinadas ao desenvolvimento de 'software' +Comment[pt_BR]=Aplicativos destinados ao desenvolvimento de software +Comment[ro]=Aplicații orientate spre dezvoltarea de programe +Comment[ru]=Приложения, предназначенные для разработки программных продуктов +Comment[si]=මෘදුකාංග සංවර්ධනයට ඉලක්ක වූ යෙදුම් +Comment[sk]=Aplikácie zamerané na vývoj softvéru +Comment[sl]=Programi za razvoj programske opreme +Comment[sr]=Програми намењени развоју софтвера +Comment[sr@ijekavian]=Програми намијењени развоју софтвера +Comment[sr@ijekavianlatin]=Programi namijenjeni razvoju softvera +Comment[sr@latin]=Programi namenjeni razvoju softvera +Comment[sv]=Program med programvaruutveckling som målsättning +Comment[th]=แอพลิเคชันที่ตั้งเป้าเพื่อการพัฒนาซอฟต์แวร์ +Comment[tr]=Yazılım geliştirmeye yönelik uygulamalar +Comment[ug]=يۇمشاق دېتال ئىجادىيىتىگە يۈزلەنگەن پروگرامما +Comment[uk]=Програми, призначені для розробки програмного забезпечення +Comment[vi]=Các ứng dụng hỗ trợ phát triển phần mềm +Comment[wa]=Programes kel såme est d' siervi å diswalpaedje di programes +Comment[x-test]=xxApplications targeted to software developmentxx +Comment[zh_CN]=面向软件开发的应用程序 +Comment[zh_TW]=為了軟體開發而設計的應用程式 + +Icon=applications-development + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-utility + +X-Plasma-Sal-Url=kservicegroup://root/Development/ +X-Plasma-Sal-Relevance=0.8 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-education.desktop b/plasma/netbook/containments/sal/services/plasma-sal-education.desktop new file mode 100644 index 00000000..85b08992 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-education.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Name=Education +Name[af]=Opvoeding +Name[ar]=التعليم +Name[as]=শিক্ষা +Name[ast]=Educación +Name[be]=Адукацыя +Name[be@latin]=Adukacyja +Name[bg]=Обучение +Name[bn]=‌শিক্ষা +Name[bn_IN]=শিক্ষা +Name[bs]=Obrazovanje +Name[ca]=Educació +Name[ca@valencia]=Educació +Name[cs]=Výuka +Name[csb]=Edukacëjô +Name[da]=Uddannelse +Name[de]=Lernprogramme +Name[el]=Εκπαίδευση +Name[en_GB]=Education +Name[eo]=Edukado +Name[es]=Educación +Name[et]=Õppimine +Name[eu]=Hezkuntza +Name[fa]=آموزش +Name[fi]=Opetus +Name[fr]=Éducation +Name[fy]=Edukaasje +Name[ga]=Oideachas +Name[gl]=Educación +Name[gu]=શિક્ષણ +Name[he]=חינוך +Name[hi]=शिक्षा +Name[hne]=सिक्छा +Name[hr]=Obrazovanje +Name[hsb]=Wuknjenje a hrajkanje +Name[hu]=Oktatás +Name[ia]=Education +Name[id]=Pendidikan +Name[is]=Kennsla +Name[it]=Didattica +Name[kk]=Оқу-ағарту +Name[km]=ការ​អប់រំ +Name[kn]=ಶಿಕ್ಷಣ +Name[ko]=교육 +Name[ku]=Perwerdehî +Name[lt]=Švietimas +Name[lv]=Izglītība +Name[mai]=शिक्षा +Name[mk]=Едукација +Name[ml]=വിദ്യാഭ്യാസം +Name[mr]=शिक्षण +Name[nb]=Utdanning +Name[nds]=Lehren +Name[ne]=शिक्षा +Name[nl]=Onderwijs +Name[nn]=Utdanning +Name[oc]=Educacion +Name[or]=ଶିକ୍ଷା +Name[pa]=ਸਿੱਖਿਆ +Name[pl]=Edukacja +Name[pt]=Educação +Name[pt_BR]=Educação +Name[ro]=Educație +Name[ru]=Образование +Name[se]=Oahpahus +Name[si]=අධ්‍යාපනික +Name[sk]=Vzdelávanie +Name[sl]=Izobraževanje +Name[sr]=Образовање +Name[sr@ijekavian]=Образовање +Name[sr@ijekavianlatin]=Obrazovanje +Name[sr@latin]=Obrazovanje +Name[sv]=Utbildning +Name[ta]=கல்வி +Name[te]=విధ్య +Name[tg]=Омӯзиш ва парвариш +Name[th]=การศึกษา +Name[tr]=Eğitim +Name[ug]=مائارىپ +Name[uk]=Освіта +Name[uz]=Taʼlim +Name[uz@cyrillic]=Таълим +Name[vi]=Giáo dục +Name[wa]=Sicolaedje +Name[x-test]=xxEducationxx +Name[zh_CN]=教育 +Name[zh_TW]=教育 +Comment=Educational applications +Comment[ar]=برامج تعليمية +Comment[ast]=Aplicaciones educatives +Comment[bg]=Образователни програми +Comment[bn]=শিক্ষামূলক অ্যাপলিকেশন +Comment[bs]=Obrazovni programi +Comment[ca]=Aplicacions educatives +Comment[ca@valencia]=Aplicacions educatives +Comment[cs]=Výukové aplikace +Comment[csb]=Edukacjowé aplikacëje +Comment[da]=Læringsprogrammer +Comment[de]=Lernprogramme +Comment[el]=Εκπαιδευτικές εφαρμογές +Comment[en_GB]=Educational applications +Comment[eo]=Edukadaj Aplikaĵoj +Comment[es]=Aplicaciones educativas +Comment[et]=Õpirakendused +Comment[eu]=Hezkuntzarako aplikazioak +Comment[fa]=برنامه‌های آموزشی +Comment[fi]=Koulutussovellukset +Comment[fr]=Applications pour l'éducation +Comment[fy]=Leer programma's +Comment[ga]=Feidhmchláir oideachasúla +Comment[gl]=Programas educativos +Comment[gu]=શૈક્ષણિક કાર્યક્રમો +Comment[he]=יישומים חינוכיים +Comment[hi]=शेक्षणिक अनुप्रयोग +Comment[hr]=Edukacijske aplikacije +Comment[hu]=Oktatóprogramok +Comment[ia]=Applicationes de Instruction +Comment[id]=Aplikasi edukasi +Comment[is]=Kennslu- og fræðsluforrit +Comment[ja]=教育アプリケーション +Comment[kk]=Білім-беру қолданбалары +Comment[km]=កម្មវិធីអប់រំ +Comment[kn]=ಕಲಿಕೆಯ ಆನ್ವಯಗಳು +Comment[ko]=교육 프로그램 +Comment[lt]=Mokomosios programos +Comment[lv]=Izglītības programmas +Comment[mk]=Едукативни апликации +Comment[ml]=വിദ്യഭ്യാസ പ്രയോഗങ്ങള്‍ +Comment[mr]=शिक्षणोपयोगी अनुप्रयोग +Comment[nb]=Opplæringsprogrammer +Comment[nds]=Lehrprogrammen +Comment[nl]=Onderwijstoepassingen +Comment[nn]=Lærerike program +Comment[pa]=ਸਿੱਖਿਅਕ ਐਪਲੀਕੇਸ਼ਨ +Comment[pl]=Programy edukacyjne +Comment[pt]=Aplicações educativas +Comment[pt_BR]=Aplicativos educacionais +Comment[ro]=Aplicații educaționale +Comment[ru]=Обучающие приложения +Comment[si]=අධ්‍යාපන යෙදුම් +Comment[sk]=Vzdelávacie aplikácie +Comment[sl]=Izobraževalni programi +Comment[sr]=Образовни програми +Comment[sr@ijekavian]=Образовни програми +Comment[sr@ijekavianlatin]=Obrazovni programi +Comment[sr@latin]=Obrazovni programi +Comment[sv]=Utbildningsprogram +Comment[tg]=Барномаҳои терминал +Comment[th]=โปรแกรมต่าง ๆ ด้านการศึกษา +Comment[tr]=Eğitim uygulamaları +Comment[ug]=ئوقۇتۇش پروگراممىلىرى +Comment[uk]=Навчальні програми +Comment[vi]=Ứng dụng giáo dục +Comment[wa]=Programes di scolaedje +Comment[x-test]=xxEducational applicationsxx +Comment[zh_CN]=教学程序 +Comment[zh_TW]=教育類應用程式 +Icon=applications-education + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-education + +X-Plasma-Sal-Url=kservicegroup://root/Education/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-games.desktop b/plasma/netbook/containments/sal/services/plasma-sal-games.desktop new file mode 100644 index 00000000..8f1a9768 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-games.desktop @@ -0,0 +1,169 @@ +[Desktop Entry] +Name=Games +Name[af]=Speletjies +Name[ar]=ألعاب +Name[as]=খেলা +Name[ast]=Xuegos +Name[be]=Гульні +Name[be@latin]=Hulni +Name[bg]=Игри +Name[bn]=খেলা +Name[bn_IN]=খেলা +Name[br]=C'hoarioù +Name[bs]=Igre +Name[ca]=Jocs +Name[ca@valencia]=Jocs +Name[cs]=Hry +Name[csb]=Grë +Name[cy]=Gemau +Name[da]=Spil +Name[de]=Spiele +Name[el]=Παιχνίδια +Name[en_GB]=Games +Name[eo]=Ludoj +Name[es]=Juegos +Name[et]=Mängud +Name[eu]=Jokoak +Name[fa]=بازیها +Name[fi]=Pelit +Name[fr]=Jeux +Name[fy]=Amusemint +Name[ga]=Cluichí +Name[gl]=Xogos +Name[gu]=રમતો +Name[he]=משחקים +Name[hi]=खेल +Name[hne]=खेल +Name[hr]=Igre +Name[hsb]=Hry +Name[hu]=Játékok +Name[ia]=Jocos +Name[id]=Permainan +Name[is]=Leikir +Name[it]=Giochi +Name[ka]=თამაშები +Name[kk]=Ойындар +Name[km]=ល្បែង +Name[kn]=ಆಟಗಳು +Name[ko]=게임 +Name[ku]=Listîk +Name[lt]=Žaidimai +Name[lv]=Spēles +Name[mai]=खेल +Name[mk]=Игри +Name[ml]=കളികള്‍ +Name[mr]=खेळ +Name[ms]=Permainan +Name[nb]=Spill +Name[nds]=Spelen +Name[ne]=खेल +Name[nl]=Amusement +Name[nn]=Spel +Name[oc]=Jòcs +Name[or]=ଖେଳ +Name[pa]=ਖੇਡਾਂ +Name[pl]=Gry +Name[pt]=Jogos +Name[pt_BR]=Jogos +Name[ro]=Jocuri +Name[ru]=Игры +Name[se]=Spealut +Name[si]=ක්‍රීඩා +Name[sk]=Hry +Name[sl]=Igre +Name[sr]=Игре +Name[sr@ijekavian]=Игре +Name[sr@ijekavianlatin]=Igre +Name[sr@latin]=Igre +Name[sv]=Spel +Name[ta]=விளையாட்டுகள் +Name[te]=ఆటలు +Name[tg]=Бозиҳо +Name[th]=เกมต่าง ๆ +Name[tr]=Oyunlar +Name[ug]=ئويۇنلار +Name[uk]=Ігри +Name[uz]=Oʻyinlar +Name[uz@cyrillic]=Ўйинлар +Name[vi]=Trò chơi +Name[wa]=Djeus +Name[xh]=Imidlalo +Name[x-test]=xxGamesxx +Name[zh_CN]=游戏 +Name[zh_TW]=遊戲 +Comment=A collection of fun games +Comment[ar]=مجموعة من الألعاب المسلية +Comment[ast]=Un garrapiellu de xuegos prestosos +Comment[bg]=Набор от забавни игри +Comment[bn]=মজাদার খেলার একটি সংগ্রহ +Comment[bs]=Zbirka igara za razonodu +Comment[ca]=Una col·lecció de jocs divertits +Comment[ca@valencia]=Una col·lecció de jocs divertits +Comment[cs]=Sbírka zábavných her +Comment[csb]=Zbiérk grów dlô szpôsu +Comment[da]=En samling af sjove spil +Comment[de]=Eine Sammlung Spielspaß +Comment[el]=Μια συλλογή παιχνιδιών για διασκέδαση +Comment[en_GB]=A collection of fun games +Comment[eo]=Amuza ludaro +Comment[es]=Una colección de juegos +Comment[et]=Lahedate mängude kogu +Comment[eu]=Joko dibertigarrien bilduma bat +Comment[fi]=Hauskojen pelien kokoelma +Comment[fr]=Une collection de jeux amusants +Comment[fy]=In samling grappige spultsjes +Comment[ga]=Bailiúchán de chluichí taitneamhacha +Comment[gl]=Unha colección de xogos +Comment[gu]=આનંદમય રમતોનો સંગ્રહ +Comment[he]=אוסף משחקי כיף +Comment[hi]=मस्ती भरे खेल +Comment[hr]=Zbirka zabavnih igara +Comment[hu]=Szórakoztató játékok gyűjteménye +Comment[ia]=Un collection de jocos divertente +Comment[id]=Koleksi permainan seru +Comment[is]=Safn sniðugra leikja +Comment[ja]=楽しいゲームのコレクション +Comment[kk]=Ойындар жинағы +Comment[km]=បណ្ដុំ​ល្បែង​កំសាន្ត​ជា​ច្រើន +Comment[kn]=ಮನೋರಂಜನಾ ಆಟಗಳ ಸಂಗ್ರಹ +Comment[ko]=재미있는 게임 모음 +Comment[lt]=Linksmų žaidimų rinkinys +Comment[lv]=Jautru spēļu krājums +Comment[mk]=Колекција од забавни игри +Comment[ml]=തമാശയുള്ള കളികളുടെ ശേഖരം +Comment[mr]=मनोरंजक खेळांचा संग्रह +Comment[nb]=En samling underholdende spill +Comment[nds]=En Sammeln vun Spaaßspelen +Comment[nl]=Een verzameling van grappige spellen +Comment[nn]=Ei samling morosame spel +Comment[pa]=ਖੇਡ ਤਮਾਸ਼ਿਆਂ ਦਾ ਭੰਡਾਰ +Comment[pl]=Kolekcja zabawnych gier +Comment[pt]=Uma colecção de jogos engraçados +Comment[pt_BR]=Uma coleção de jogos divertidos +Comment[ro]=Colecție de jocuri distractive +Comment[ru]=Коллекция весёлых игр +Comment[si]=විනෝද ක්‍රීඩා එකතුවක් +Comment[sk]=Kolekcia zábavných hier +Comment[sl]=Zbirka zabavnih iger +Comment[sr]=Збирка игара за разоноду +Comment[sr@ijekavian]=Збирка игара за разоноду +Comment[sr@ijekavianlatin]=Zbirka igara za razonodu +Comment[sr@latin]=Zbirka igara za razonodu +Comment[sv]=En samling roliga spel +Comment[tg]=Маҷмӯъи бозиҳои хушӣ +Comment[th]=ชุดเกมสนุก ๆ ต่าง ๆ +Comment[tr]=Neşeli oyunlar koleksiyonu +Comment[ug]=بىر توپلام قىزىقارلىق ئويۇنلار +Comment[uk]=Збірка веселих ігор +Comment[wa]=Ene ramexhnêye di zûnants djeus +Comment[x-test]=xxA collection of fun gamesxx +Comment[zh_CN]=一组趣味游戏 +Comment[zh_TW]=好玩遊戲的集合 +Icon=applications-games + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-games + +X-Plasma-Sal-Url=kservicegroup://root/Games/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-graphics.desktop b/plasma/netbook/containments/sal/services/plasma-sal-graphics.desktop new file mode 100644 index 00000000..340cd156 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-graphics.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Name=Graphics +Name[af]=Grafieka +Name[ar]=برامج رسم +Name[as]=চিত্ৰাঙ্কন +Name[ast]=Gráficos +Name[be]=Графіка +Name[be@latin]=Hrafika +Name[bg]=Графика +Name[bn]=গ্রাফিক্স +Name[bn_IN]=গ্রাফিক্স +Name[br]=Grafikoù +Name[bs]=Grafika +Name[ca]=Gràfics +Name[ca@valencia]=Gràfics +Name[cs]=Grafika +Name[csb]=Grafika +Name[cy]=Graffeg +Name[da]=Grafik +Name[de]=Grafik +Name[el]=Γραφικά +Name[en_GB]=Graphics +Name[eo]=Grafiko +Name[es]=Gráficos +Name[et]=Graafika +Name[eu]=Grafikoak +Name[fa]=نگاره‌ها +Name[fi]=Grafiikka +Name[fr]=Graphisme +Name[fy]=Grafysk +Name[ga]=Grafaic +Name[gl]=Gráficos +Name[gu]=ચિત્રો +Name[he]=גרפיקה +Name[hi]=ग्राफिक्स +Name[hne]=ग्राफिक्स +Name[hr]=Grafika +Name[hsb]=Grafika +Name[hu]=Grafikai programok +Name[ia]=Graphiches +Name[id]=Grafik +Name[is]=Myndvinnsla +Name[it]=Grafica +Name[ka]=გრაფიკა +Name[kk]=Графика +Name[km]=ក្រាហ្វិក +Name[kn]=ಸಚಿತ್ರತೆ (ಗ್ರಾಫಿಕ್ಸ್) +Name[ko]=그래픽 +Name[ku]=Grafîk +Name[lt]=Grafika +Name[lv]=Grafika +Name[mai]=आलेखी +Name[mk]=Графика +Name[ml]=ഗ്രാഫിക്സ് +Name[mr]=आलेखीय +Name[ms]=Grafik +Name[nb]=Grafikk +Name[nds]=Grafik +Name[ne]=ग्राफिक्स +Name[nl]=Grafisch +Name[nn]=Bilete +Name[oc]=Grafisme +Name[or]=ଆଲେଖି +Name[pa]=ਗਰਾਫਿਕਸ +Name[pl]=Grafika +Name[pt]=Gráficos +Name[pt_BR]=Gráficos +Name[ro]=Grafică +Name[ru]=Графика +Name[se]=Grafihkka +Name[si]=චිත්‍රක +Name[sk]=Grafika +Name[sl]=Grafika +Name[sr]=Графика +Name[sr@ijekavian]=Графика +Name[sr@ijekavianlatin]=Grafika +Name[sr@latin]=Grafika +Name[sv]=Grafik +Name[ta]=சித்திரங்கள் +Name[te]=గ్రాఫిక్స్ +Name[tg]=Графика +Name[th]=กราฟิก +Name[tr]=Grafik +Name[ug]=گرافىك +Name[uk]=Графіка +Name[uz]=Grafika +Name[uz@cyrillic]=Графика +Name[vi]=Đồ hoạ +Name[wa]=Imådjes +Name[xh]=Imizobo +Name[x-test]=xxGraphicsxx +Name[zh_CN]=图像 +Name[zh_TW]=圖形 +Comment=Graphics applications, such as paint programs and image viewers +Comment[ar]=برامج رسومية مثل برامج التلوين وعارضات الصور +Comment[ast]=Aplicaciones de gráficos, como programes de dibuxu y visores d'imáxenes +Comment[bg]=Графични програми – за рисуване и преглед +Comment[bn]=গ্রাফিক্স অ্যাপলিকেশন, যেমন আঁকার প্রোগ্রাম এবং ছবি প্রদর্শক +Comment[bs]=Grafički programi, poput onih za crtanje i prikazivača slika +Comment[ca]=Aplicacions gràfiques, com programes de pintura i visors d'imatges +Comment[ca@valencia]=Aplicacions gràfiques, com programes de pintura i visors d'imatges +Comment[cs]=Grafické aplikace, jako kreslící programy a prohlížeče obrázků +Comment[csb]=Graficzné aplikacëje jakno do malënków ë przezéraniô òbrôzków +Comment[da]=Grafikprogrammer, såsom tegneprogrammer og billedfremvisere +Comment[de]=Grafikanwendungen wie Malprogramme und Bildbetrachter +Comment[el]=Εφαρμογές γραφικών, όπως προγράμματα ζωγραφικής και προβολής εικόνων +Comment[en_GB]=Graphics applications, such as paint programs and image viewers +Comment[es]=Aplicaciones de gráficos, como programas de dibujo y visores de imágenes +Comment[et]=Graafikarakendused, näiteks joonistamisrakendused ja pildinäitajad +Comment[eu]=Aplikazio grafikoak; adibidez, margotzeko programak eta irudi-ikustaileak +Comment[fi]=Grafiikkasovellukset, kuten piirto-ohjelmat ja kuvankatselimet +Comment[fr]=Applications graphiques tel que les programmes de dessin et les afficheurs d'images +Comment[fy]=Grafyske applikaasjes, lykas tekenprogramma's en ôfbylding werjouwers +Comment[ga]=Feidhmchláir ghrafaice, mar shampla ríomhchláir phéinteála agus amharcáin íomhánna +Comment[gl]=Programas gráficos, por ex. programas de debuxo e visores de imaxes +Comment[he]=יישומים גרפיים, כמו תוכנות ציור ומציגי תמונות +Comment[hr]=Grafičke aplikacije, poput programa za crtanje i pregledavanje slika +Comment[hu]=Grafikus alkalmazások, például rajzprogramok és képmegjelenítők +Comment[ia]=Applicationes graphic, tal como programmas de picturar e visores de imagines +Comment[id]=Aplikasi grafis, seperti program menggambar dan penampil gambar +Comment[is]=Myndmeðhöndlunarforrit eins og myndvinnsluforrit, teikniforrit og myndskoðarar +Comment[ja]=お絵描きアプリケーションやイメージビューアなどのグラフィックアプリケーション +Comment[kk]=Сурет салу және кескінді қарау құралы секілді графикалық қолданбалар +Comment[km]=កម្មវិធី​ក្រាហ្វិក ដូ​ចជា​ កម្មវិធី​គូរ និង​កម្មវិធីមើល​រូបភាព +Comment[ko]=그림 편집기, 뷰어와 같은 그래픽 프로그램 +Comment[lt]=Vaizdų programos, pavyzdžiui piešimo ir nuotraukų peržiūros +Comment[lv]=Grafikas lietotnes, zīmēšanas programmas un attēlu skatītāji +Comment[mk]=Графички апликации, како што се програми за цртање и прегледувачи на слики +Comment[ml]=വരയ്ക്കാനും ചിത്രങ്ങള്‍ കാണുന്നതിനും പോലുമുള്ള ഗ്രാഫിക്സ് പ്രയോഗങ്ങള്‍ +Comment[mr]=आलेखीय अनुप्रयोग. उदा. पेंट कार्यक्रम व प्रतिमा प्रदर्शक +Comment[nb]=Grafiske programmer, slik som maleprogrammer og bildevisere +Comment[nds]=Grafikprogrammen, so as Maalprogrammen un Bildkiekers +Comment[nl]=Grafische programma's, zoals teken- en afbeeldingsweergave-programma's +Comment[nn]=Biletprogram, som teikneprogram og fotovisarar +Comment[pa]=ਗਰਾਫਿਕਸ ਐਪਲੀਕੇਸ਼ਨ, ਜਿਵੇਂ ਕਿ ਪੇਂਟ ਪਰੋਗਰਾਮ ਅਤੇ ਚਿੱਤਰ ਦਰਸ਼ਕ +Comment[pl]=Programy graficzne, takie jak programy do rysowania i przeglądarki obrazów +Comment[pt]=Aplicações gráficas, como os programas de pintura e os visualizadores de imagens +Comment[pt_BR]=Aplicativos gráficos, tais como programas de desenho e visualizadores de imagens +Comment[ro]=Aplicații de grafică, cum ar fi programe de desen și vizualizare de imagini +Comment[ru]=Графические приложения, такие как программы рисования и просмотра изображений +Comment[si]=චිත්‍රණ යෙදුම්, චිත්‍ර ඇඳීම් හා පින්තූර දසුන් වැඩසටහන් වැනි +Comment[sk]=Grafické aplikácie, ako kresliace programy a prehliadače obrázkov +Comment[sl]=Grafični programi, npr. slikarski programi in pregledovalniki slik +Comment[sr]=Графички програми, попут оних за цртање и приказивача слика +Comment[sr@ijekavian]=Графички програми, попут оних за цртање и приказивача слика +Comment[sr@ijekavianlatin]=Grafički programi, poput onih za crtanje i prikazivača slika +Comment[sr@latin]=Grafički programi, poput onih za crtanje i prikazivača slika +Comment[sv]=Grafikprogram, som ritprogram och bildvisning +Comment[tg]=Поиск приложений и служб +Comment[th]=โปรแกรมต่าง ๆ ด้านกราฟิก เช่นโปรแกรมวาดภาพ และโปรแกรมดูรูปภาพ +Comment[tr]=Grafik uygulamaları, boyama ve resim gösterme uygulamaları gibi +Comment[ug]=گرافىك پروگراممىلىرى، رەسىم سىزىش ۋە سۈرەت كۆرگۈچ پروگراممىلىرى +Comment[uk]=Програми для роботи з графікою, зокрема програми для малювання та перегляду зображень +Comment[vi]=Các ứng dụng đồ hoạ như các chương trình vẽ hay trình xem ảnh +Comment[wa]=Programes po les imådjes come des programes di pondeure eyet des håyneus d' imådjes +Comment[x-test]=xxGraphics applications, such as paint programs and image viewersxx +Comment[zh_CN]=图形图像应用程序,如绘画工具和图像查看器 +Comment[zh_TW]=美工應用程式,如繪圖程式與影像檢視器等 +Icon=applications-graphics + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-graphics + +X-Plasma-Sal-Url=kservicegroup://root/Graphics/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-internet.desktop b/plasma/netbook/containments/sal/services/plasma-sal-internet.desktop new file mode 100644 index 00000000..0fa8f42c --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-internet.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=Internet +Name[af]=Internet +Name[ar]=الإنترنت +Name[as]=ইন্টাৰ্নে'ট +Name[ast]=Internet +Name[be]=Інтэрнэт +Name[be@latin]=Internet +Name[bg]=Интернет +Name[bn]=ইন্টারনেট +Name[bn_IN]=ইন্টারনেট +Name[br]=Kenrouedad +Name[bs]=Internet +Name[ca]=Internet +Name[ca@valencia]=Internet +Name[cs]=Internet +Name[csb]=Internet +Name[cy]=Rhyngrwyd +Name[da]=Internet +Name[de]=Internet +Name[el]=Διαδίκτυο +Name[en_GB]=Internet +Name[eo]=Interreto +Name[es]=Internet +Name[et]=Internet +Name[eu]=Internet +Name[fa]=اینترنت +Name[fi]=Internet +Name[fr]=Internet +Name[fy]=Ynternet +Name[ga]=Idirlíon +Name[gl]=Internet +Name[gu]=ઇન્ટરનેટ +Name[he]=אינטרנט +Name[hi]=इन्टरनेट +Name[hne]=इन्टरनेट +Name[hr]=Internet +Name[hsb]=Internet +Name[hu]=Internet +Name[ia]=Internet +Name[id]=Internet +Name[is]=Internetið +Name[it]=Internet +Name[ka]=ინტერნეტი +Name[kk]=Интернет +Name[km]=អ៊ីនធឺណិត +Name[kn]=ಅಂತರ್ಜಾಲ +Name[ko]=인터넷 +Name[ku]=Înternet +Name[lt]=Internetas +Name[lv]=Internets +Name[mai]=इंटरनेट +Name[mk]=Интернет +Name[ml]=ഇന്റര്‍നെറ്റ് +Name[mr]=महाजाळ +Name[ms]=Internet +Name[nb]=Internett +Name[nds]=Internet +Name[ne]=इन्टरनेट +Name[nl]=Internet +Name[nn]=Internett +Name[oc]=Internet +Name[or]=ଇଣ୍ଟରନେଟ +Name[pa]=ਇੰਟਰਨੈੱਟ +Name[pl]=Internet +Name[pt]=Internet +Name[pt_BR]=Internet +Name[ro]=Internet +Name[ru]=Интернет +Name[se]=Interneahtta +Name[si]=අන්තර්ජාලය +Name[sk]=Internet +Name[sl]=Internet +Name[sr]=Интернет +Name[sr@ijekavian]=Интернет +Name[sr@ijekavianlatin]=Internet +Name[sr@latin]=Internet +Name[sv]=Internet +Name[ta]=இணையம் +Name[te]=ఇంటర్నెట్ +Name[tg]=Интернет +Name[th]=อินเทอร์เน็ต +Name[tr]=İnternet +Name[ug]=ئىنتېرنېت +Name[uk]=Інтернет +Name[uz]=Internet +Name[uz@cyrillic]=Интернет +Name[vi]=Internet +Name[wa]=Daegntoele +Name[x-test]=xxInternetxx +Name[zh_CN]=互联网 +Name[zh_TW]=網際網路 +Comment=Internet related applications, such as Web browser, Email and chat +Comment[ar]=برامج متعلقة بالإنترنت كمتصفح الوِب والبريد والدردشة +Comment[ast]=Aplicaciones rellacionaes con Internet, como restoladores web, corréu electrónicu y chat +Comment[bg]=Интернет приложения, като уеб браузър, електронна поща и чат +Comment[bn]=ইন্টারনেট সংক্রান্ত অ্যাপলিকেশন, যেমন ওয়েব-ব্রাউসার, ই-মেইল এবং চ্যাট +Comment[bs]=Programi u vezi s Internetom, poput veb pregledača, e‑pošte i ćaskanja +Comment[ca]=Aplicacions relacionades amb Internet, com navegador Web, correu electrònic i xat +Comment[ca@valencia]=Aplicacions relacionades amb Internet, com navegador Web, correu electrònic i xat +Comment[cs]=Aplikace související s internetem jako je internetový prohlížeč, e-mail a rozhovor +Comment[csb]=Aplikacëje sparłãczoné z internetã, jakno przezérniczi, programë e-mailowé ë czatowé +Comment[da]=Internetrelaterede programmer, såsom webbrowser, e-mail og chat +Comment[de]=Internet-Anwendungen wie Webbrowser, E-Mail-Programm oder Chat +Comment[el]=Εφαρμογές σχετικές με το διαδίκτυο, όπως περιηγητές διαδικτύου, ηλεκτρονικής αλληλογραφίας και συνομιλίας +Comment[en_GB]=Internet related applications, such as Web browser, Email and chat +Comment[es]=Aplicaciones relacionadas con Internet, como navegadores web, correo electrónico y chat +Comment[et]=Internetiga seotud rakendused, näiteks veebibrauser, e-posti klient ja kiirsuhtlusrakendus +Comment[eu]=Internetekin erlazionatutako aplikazioak; adibidez, web-arakatzaileak, posta elektronikoa eta berriketa +Comment[fi]=Internetiin liittyvät sovellukset, kuten verkkoselain, sähköposti ja verkkokeskustelu +Comment[fr]=Applications en relation avec Internet tel que les navigateurs, les clients de courrier électronique et les logiciels de messagerie instantanée +Comment[fy]=Mei ynternet relatearre applikaasje, lykas webblêd, e-post en tsjet +Comment[ga]=Feidhmchlár a bhaineann leis an Idirlíon, mar shampla brabhsálaithe, cliaint ríomhphoist agus cláir chomhrá +Comment[gl]=Programas relacionados con internet, como un navegador web, correo e chat +Comment[he]=יישומי אינטרנט, כגון דפדפן רשת, דואר אלקטרוני ומסרים מידיים +Comment[hr]=Aplikacije vezane za Internet, poput web preglednika, te programa za e-poštu i čavrljanje +Comment[hu]=Internetes alkalmazások, például webböngésző, e-mail kliens és csevegőprogram +Comment[ia]=Applicationes referite a Internet, tal como Navigator Web, E-Posta e confabulation +Comment[id]=Aplikasi terkait Internet, seperti peramban Web, Email dan obrolan +Comment[is]=Internetforrit á borð við vafra, tölvupóst- og spjallforrit +Comment[ja]=ウェブブラウザ、電子メール、チャットなどのインターネット関連のアプリケーション +Comment[kk]=Веб шолғыш, эл.пошта, чат секілді Интернетке қатысты қолданбалар +Comment[km]=កម្មវិធី​ដែលទាក់ទង​នឹង​អ៊ីនធឺណិត ដូចជា​ កម្មវិធី​រុករក​បណ្ដាញ អ៊ីមែល ជជែក +Comment[kn]=ಜಾಲ ವೀಕ್ಷಕ, ವಿಅಂಚೆ ಹಾಗು ಚಾಟ್‌ನಂತಹ ಅಂತರ್ಜಾಲ ಸಂಬಂಧಿತವಾದ ಅನ್ವಯಗಳು +Comment[ko]=웹 브라우저, 이메일, 채팅과 같은 인터넷 프로그램 +Comment[lt]=Su internetu susijusios programos, tokios kaip naršyklės, el. pašto ar pokalbių +Comment[lv]=Ar Internetu saistītas lietotnes, tīmekļa pārlūks, e-pasts un tērzēšana +Comment[mk]=Апликации поврзани со Интернет, како што е веб-прелистување, е-пошта и разговор +Comment[ml]=ഇന്റര്‍നെറ്റിനോടനുബന്ധിച്ചിട്ടുള്ള പ്രയോഗങ്ങളായ വെബ് ബ്രൌസര്‍, ഈമെയില്‍, സല്ലാപം മുതലായവ +Comment[mr]=महाजाळ संबंधित अनुप्रयोग. उदा. वेब ब्राऊजर, इमेल व चेैट +Comment[nb]=Internett-relaterte programmer, slik som nettleser, e-post og prateprogrammer +Comment[nds]=Programmen rund dat Internet, so as Nettkiekers, Nettpost- un Klöönprogrammen +Comment[nl]=Internet gerelateerde programma's, zoals Webbrowser, E-mail en chat +Comment[nn]=Internett-relaterte program, som nettlesarar og e-post- og prateprogram +Comment[pa]=ਇੰਟਰਨੈੱਟ ਨਾਲ ਸਬੰਧਿਤ ਐਪਲੀਕੇਸ਼ਨ, ਜਿਵੇਂ ਕਿ ਵੈੱਬ ਬਰਾਊਜ਼ਰ, ਈਮੇਲ ਅਤੇ ਚੈਟ +Comment[pl]=Programy internetowe, takie jak przeglądarka WWW, poczta i czat +Comment[pt]=Aplicações relacionadas com a Internet, como o navegador Web, o E-mail e as conversações +Comment[pt_BR]=Aplicativos relacionados à Internet, tais como o navegador da Web, e-mail e bate-papo +Comment[ro]=Aplicații legate de Internet, cum ar fi navigator web, poștă și discuții +Comment[ru]=Приложения, связанные с Интернетом, такие как браузер, почтовый клиент и клиент мгновенных сообщений +Comment[si]=අන්තර්ජාලය සම්බන්ධ භාවිත යෙදවුම්, වෙබ් ගවේශකය, තැපැල් හා සංවාද වැනි +Comment[sk]=Internetové aplikácie, ako webový prehliadač, poštový klient a chat +Comment[sl]=Internetni programi, npr. spletni brskalniki, e-pošta in klepet +Comment[sr]=Програми у вези с Интернетом, попут веб прегледача, е‑поште и ћаскања +Comment[sr@ijekavian]=Програми у вези с Интернетом, попут веб прегледача, е‑поште и ћаскања +Comment[sr@ijekavianlatin]=Programi u vezi s Internetom, poput veb pregledača, e‑pošte i ćaskanja +Comment[sr@latin]=Programi u vezi s Internetom, poput veb pregledača, e‑pošte i ćaskanja +Comment[sv]=Internet-relaterade program, som webbläsare, e-post och chatt +Comment[th]=โปรแกรมต่าง ๆ ด้านอินเทอร์เน็ต เช่นเว็บเบราว์เซอร์, การรับส่งจดหมาย และโปรแกรมพูดคุย +Comment[tr]=İnternet ile ilgili uygulamalar, Web tarayıcı, e-posta ve sohbet istemcileri gibi +Comment[ug]=ئىنتېرنېتقا مۇناسىۋەتلىك پروگراممىلار، توركۆرگۈ، ئېلخەت ۋە مۇڭداشقۇلار +Comment[uk]=Програми, пов’язані з інтернетом, зокрема переглядач інтернету, поштовий клієнт та клієнти служб обміну повідомленнями +Comment[vi]=Các ứng dụng mạng như trình duyệt web, thư điện tử và chat +Comment[wa]=Programes pol Daegntoele come li betchteu waibe, l' emilaedje eyet l' berdelaedje sol moumint +Comment[x-test]=xxInternet related applications, such as Web browser, Email and chatxx +Comment[zh_CN]=互联网应用程序,如网络浏览器、邮件客户端和聊天工具 +Comment[zh_TW]=網際網路相關應用程式,如瀏覽器、電子郵件收發程式與聊天室 +Icon=applications-internet + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-internet + +X-Plasma-Sal-Url=kservicegroup://root/Internet/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-multimedia.desktop b/plasma/netbook/containments/sal/services/plasma-sal-multimedia.desktop new file mode 100644 index 00000000..e1cc9a1b --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-multimedia.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Name=Multimedia +Name[af]=Multimedia +Name[ar]=الوسائط المتعددة +Name[as]=মাল্টিমিডিয়া +Name[ast]=Multimedia +Name[be]=Мультымедыя +Name[be@latin]=Multymedyja +Name[bg]=Мултимедия +Name[bn]=মাল্টিমিডিয়া +Name[bn_IN]=মাল্টি-মিডিয়া +Name[br]=Liesvedia +Name[bs]=Multimedija +Name[ca]=Multimèdia +Name[ca@valencia]=Multimèdia +Name[cs]=Multimédia +Name[csb]=Mùltimedia +Name[cy]=Amlgyfryngau +Name[da]=Multimedie +Name[de]=Multimedia +Name[el]=Πολυμέσα +Name[en_GB]=Multimedia +Name[eo]=Aŭdvido +Name[es]=Multimedia +Name[et]=Multimeedia +Name[eu]=Multimedia +Name[fa]=چند رسانه‌ای +Name[fi]=Multimedia +Name[fr]=Multimédia +Name[fy]=Multimedia +Name[ga]=Ilmheáin +Name[gl]=Multimedia +Name[gu]=મલ્ટિમીડિઆ +Name[he]=מולטימדיה +Name[hi]=मल्टीमीडिया +Name[hne]=मल्टीमीडिया +Name[hr]=Multimedija +Name[hsb]=Multimedija +Name[hu]=Multimédia +Name[ia]=Multimedia +Name[id]=Multimedia +Name[is]=Margmiðlun +Name[it]=Multimedia +Name[ka]=მულტიმედია +Name[kk]=Мультимедиа +Name[km]=ពហុព័ត៌មាន +Name[kn]=ಬಹುಮಾಧ್ಯಮ +Name[ko]=멀티미디어 +Name[ku]=Multîmedya +Name[lt]=Multimedia +Name[lv]=Multivide +Name[mai]=मल्टीमीडिया +Name[mk]=Мултимедија +Name[ml]=മള്‍ട്ടീമീഡിയ +Name[mr]=मल्टीमीडिया +Name[ms]=Multimedia +Name[nb]=Multimedia +Name[nds]=Multimedia +Name[ne]=मल्टिमिडिया +Name[nl]=Multimedia +Name[nn]=Multimedia +Name[oc]=Multimedià +Name[or]=ବହୁମାଧ୍ଯମ +Name[pa]=ਮਲਟੀਮੀਡਿਆ +Name[pl]=Multimedia +Name[pt]=Multimédia +Name[pt_BR]=Multimídia +Name[ro]=Multimedia +Name[ru]=Мультимедиа +Name[se]=Multimedia +Name[si]=බහුමාධ්‍යය +Name[sk]=Multimédiá +Name[sl]=Predstavnost +Name[sr]=Мултимедија +Name[sr@ijekavian]=Мултимедија +Name[sr@ijekavianlatin]=Multimedija +Name[sr@latin]=Multimedija +Name[sv]=Multimedia +Name[ta]=பல்லூடகம் +Name[te]=బహుళ మాద్యమం +Name[tg]=Мултимедиа +Name[th]=มัลติมีเดีย +Name[tr]=Çoklu Ortam +Name[ug]=كۆپ ۋاسىتە +Name[uk]=Мультимедіа +Name[uz]=Multimedia +Name[uz@cyrillic]=Мултимедиа +Name[vi]=Nhạc/Ảnh +Name[wa]=Multimedia +Name[xh]=Iindlela ezininzi zokwenza +Name[x-test]=xxMultimediaxx +Name[zh_CN]=多媒体 +Name[zh_TW]=多媒體 +Comment=Multimedia applications, such as audio and video players +Comment[ar]=برامج الوسائط المتعدّدة كمشغلات الصوت والفيديو +Comment[ast]=Aplicaciones multimedia, como reproductores d'audio y videu +Comment[bg]=Мултимедийни приложения, като аудио и видео плеъри +Comment[bn]=মাল্টিমিডিয়া অ্যাপলিকেশন, যেমন অডিও ও ভিডিও প্লেয়ার +Comment[bs]=Multimedijski programi, poput audio i video plejera +Comment[ca]=Aplicacions multimèdia, com reproductors d'àudio i vídeo +Comment[ca@valencia]=Aplicacions multimèdia, com reproductors d'àudio i vídeo +Comment[cs]=Multimediální aplikace jako jsou audio a video přehrávače +Comment[csb]=Mùltimedialné aplikacëje jakno grôcze aùdio ë wideò +Comment[da]=Multimedieprogrammer, såsom lyd- og videoafspillere +Comment[de]=Multimedia-Anwendungen wie Abspielprogramme für Audio und Video +Comment[el]=Εφαρμογές πολυμέσων, όπως αναπαραγωγείς ήχου και εικόνας +Comment[en_GB]=Multimedia applications, such as audio and video players +Comment[eo]=Plurmediaj aplikaĵoj kiel son- kaj film- legiloj +Comment[es]=Aplicaciones multimedia, como reproductores de audio y vídeo +Comment[et]=Multimeediarakendused, näiteks muusika- ja videomängija +Comment[eu]=Multimedia-aplikazioak; adibidez, audio- eta bideo-jotzaileak +Comment[fi]=Multimediasovellukset, kuten ääni- ja videosoittimet +Comment[fr]=Applications multimédia tel que les lecteurs audio et vidéo +Comment[fy]=Multymedia applikaasjes, lykas audio en fideo spilers +Comment[ga]=Feidhmchláir ilmheán, mar shampla seinnteoirí fuaime agus físe +Comment[gl]=Programas multimedia, do estilo de reprodutores de son e vídeo +Comment[he]=יישומי מולטימדיה, כגון נגני מוזיקה וסרטים +Comment[hr]=Multimedijalne aplikacije, poput audio i video svirača +Comment[hu]=Multimédiás alkalmazások, például hang- és videolejátszók +Comment[ia]=Applicationes multimedial, tal como reproductores audio e video +Comment[id]=Aplikasi multimedia, seperti pemutar audio dan video +Comment[is]=Margmiðlunarforrit eins og vídeó- og hljóðspilarar +Comment[ja]=オーディオやビデオプレーヤーなどのマルチメディアアプリケーション +Comment[kk]=Аудио және видео плейер секілді мультимедиа қолданбалар +Comment[km]=កម្មវិធី​​ពហុ​មេឌៀ ដូច​ជា កម្មវិធី​ចាក់​អូឌីយ៉ូ និង​វីដេអូ +Comment[ko]=오디오 및 비디오 재생기와 같은 멀티미디어 프로그램 +Comment[lt]=Daugialypės terpės programos, tokios kaip audio ir video leistuvai +Comment[lv]=Multivides lietotnes, audio un video atskaņotāji +Comment[mk]=Мултимедијални апликации, како што се аудио и видео плеери +Comment[ml]=മള്‍ട്ടീമീഡിയാ പ്രയോഗങ്ങളായ: ഓഡിയോ, വീഡിയോ പ്ലയറുകള്‍ മുതലായവ +Comment[mr]=मल्टीमीडिया अनुप्रयोग. उदा. ऑडिओ व व्हिडीओ प्लेयर्स +Comment[nb]=Multimediaprogrammer, slik som lyd- og videospillere +Comment[nds]=Multimedia-Programmen, so as Klang- un Video-Afspelers +Comment[nl]=Multimedia programma's, zoals audio- en videospelers +Comment[nn]=Multimedia-program, som musikk- og filmspelarar +Comment[pa]=ਮਲਟੀਮੀਡਿਆ ਐਪਲੀਕੇਸ਼ਨ, ਜਿਵੇਂ ਆਡੀਓ ਅਤੇ ਵਿਡੀਓ ਪਲੇਅਰ +Comment[pl]=Programy multimedialne, takie jak odtwarzacze audio i wideo +Comment[pt]=Aplicações multimédia, como os leitores de áudio e vídeo +Comment[pt_BR]=Aplicativos multimídia, tais como reprodutores de áudio e vídeo +Comment[ro]=Aplicații multimedia, pentru redare de sunet și imagine +Comment[ru]=Мультимедийные приложения, в том числе проигрыватели аудио и видео +Comment[si]=බහුමාධ්‍ය භාවිත යෙදවුම්, ශ්‍රව්‍ය දෘශ්‍ය ධාවක වැනි +Comment[sk]=Multimediálne aplikácie, ako prehrávače videa a zvuku +Comment[sl]=Predstavnostni programi, npr. predvajalniki zvoka in videa +Comment[sr]=Мултимедијски програми, попут аудио и видео плејера +Comment[sr@ijekavian]=Мултимедијски програми, попут аудио и видео плејера +Comment[sr@ijekavianlatin]=Multimedijski programi, poput audio i video plejera +Comment[sr@latin]=Multimedijski programi, poput audio i video plejera +Comment[sv]=Multimediaprogram, som ljud- och videospelare +Comment[tg]=Барномаҳои мултимедиа монанди плеерҳои аудио ва видео +Comment[th]=โปรแกรมต่าง ๆ ด้านสื่อประสม เช่น เครื่องเล่นวีดิทัศน์และเครื่องเล่นเสียง +Comment[tr]=Ses ve video oynatıcılar gibi çoklu ortam uygulamaları +Comment[ug]=كۆپ ۋاسىتە پروگراممىلار، ئۈن ۋە سىن چالغۇلار +Comment[uk]=Мультимедійні програми, зокрема програвачі звукових та відеоданих +Comment[wa]=Programes multimedia come des djouweus odio ou d' videyo +Comment[x-test]=xxMultimedia applications, such as audio and video playersxx +Comment[zh_CN]=多媒体应用程序,如视频/音频播放器 +Comment[zh_TW]=多媒體應用程式,如音效與影像播放器 +Icon=applications-multimedia + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-multimedia + +X-Plasma-Sal-Url=kservicegroup://root/Multimedia/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-office.desktop b/plasma/netbook/containments/sal/services/plasma-sal-office.desktop new file mode 100644 index 00000000..d710a3bd --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-office.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=Office +Name[af]=Kantoor +Name[ar]=المكتب +Name[as]=কাৰ্যালয় +Name[ast]=Oficina +Name[be]=Офіс +Name[be@latin]=Ofis +Name[bg]=Офис +Name[bn]=অফিস +Name[bn_IN]=অফিস +Name[br]=Burev +Name[bs]=Kancelarija +Name[ca]=Oficina +Name[ca@valencia]=Oficina +Name[cs]=Kancelář +Name[csb]=Biuro +Name[cy]=Swyddfa +Name[da]=Kontor +Name[de]=Büroprogramme +Name[el]=Γραφείο +Name[en_GB]=Office +Name[eo]=Laborejo +Name[es]=Oficina +Name[et]=Kontoritöö +Name[eu]=Bulegoa +Name[fa]=اداره +Name[fi]=Toimisto-ohjelmat +Name[fr]=Bureautique +Name[fy]=Kantoartapassingen +Name[ga]=Oifig +Name[gl]=Ofimática +Name[gu]=ઓફિસ +Name[he]=משרד +Name[hi]=कार्यालय +Name[hne]=आफिस +Name[hr]=Ured +Name[hsb]=Běrowowe programy +Name[hu]=Irodai alkalmazások +Name[ia]=Officio +Name[id]=Perkantoran +Name[is]=Skrifstofuforrit +Name[it]=Ufficio +Name[ka]=ოფისი +Name[kk]=Офис +Name[km]=ការិយាល័យ +Name[kn]=ಕಛೇರಿ +Name[ko]=사무용 도구 +Name[ku]=Nivîsgeh +Name[lt]=Biuro programos +Name[lv]=Birojs +Name[mai]=कार्यालय +Name[mk]=Канцеларија +Name[ml]=ഓഫീസ് +Name[mr]=ऑफीस +Name[ms]=Pejabat +Name[nb]=Kontor +Name[nds]=Kontoor +Name[ne]=कार्यालय +Name[nl]=Kantoortoepassingen +Name[nn]=Kontor +Name[oc]=Burèu +Name[or]=ଅଫିସ +Name[pa]=ਦਫ਼ਤਰ +Name[pl]=Biuro +Name[pt]=Escritório +Name[pt_BR]=Escritório +Name[ro]=Aplicații birotică +Name[ru]=Офис +Name[se]=Kántuvra +Name[si]=කාර්‍යයාලීය +Name[sk]=Kancelária +Name[sl]=Pisarna +Name[sr]=Канцеларија +Name[sr@ijekavian]=Канцеларија +Name[sr@ijekavianlatin]=Kancelarija +Name[sr@latin]=Kancelarija +Name[sv]=Kontor +Name[ta]=அலுவலகம் +Name[te]=కార్యాలయము +Name[tg]=Офис +Name[th]=สำนักงาน +Name[tr]=Ofis +Name[ug]=ئىشخانا +Name[uk]=Офіс +Name[uz]=Idora uchun dasturlar +Name[uz@cyrillic]=Идора учун дастурлар +Name[vi]=Văn phòng +Name[wa]=Buro +Name[xh]=Ofisi +Name[x-test]=xxOfficexx +Name[zh_CN]=办公 +Name[zh_TW]=辦公軟體 +Comment=Office related applications, such as wordprocessing and spreadsheets +Comment[ar]=برامج متعلقة بالمكتب كمعالجة النصوص والجداول الممتدة +Comment[ast]=Aplicaciones d'oficina, como procesadores de testu y fueyes de cálculu +Comment[bg]=Офисни приложения, като текстообработка и таблици +Comment[bn]=অফিস সংক্রান্ত অ্যাপলিকেশন, যেমন ওয়ার্ড-প্রসেসর এবং স্প্রেডশীট +Comment[bs]=Kancelarijski programi, poput obrade riječi i računskih tablica +Comment[ca]=Aplicacions relacionades amb una oficina, com processament de textos i fulls de càlcul +Comment[ca@valencia]=Aplicacions relacionades amb una oficina, com processament de textos i fulls de càlcul +Comment[cs]=Kancelářské aplikace jako jsou textové a tabulkové procesory +Comment[csb]=Biurowé aplikacëje, jakno procesorë tekstu ë sprôwdzanié pisënkù +Comment[da]=Kontorrelaterede programmer, såsom tekstbehandling og regneark +Comment[de]=Büroanwendungen wie Textverarbeitung oder Tabellenkalkulation +Comment[el]=Εφαρμογές γραφείου, όπως επεξεργαστές κειμένου και λογιστικά φύλλα +Comment[en_GB]=Office related applications, such as wordprocessing and spreadsheets +Comment[es]=Aplicaciones de oficina, como procesadores de texto y hojas de cálculo +Comment[et]=Kontoritöö rakendused, näiteks teksti- ja tabelitöötluseks +Comment[eu]=Bulegoko aplikazioak; adibidez, testu-prozesatzailea eta kalkulu-orriak +Comment[fi]=Toimistoon liittyvät sovellukset, kuten tekstinkäsittely ja taulukonlaskenta +Comment[fr]=Applications en rapport avec la bureautique tel que les traitements de texte et les tableurs +Comment[fy]=Mei kantoor relatearre applikaasjes, lyk tekstferwurker en rekkenboerden +Comment[ga]=Feidhmchláir oifige, mar shampla próiseálaithe focal agus scarbhileoga +Comment[gl]=Programas ofimáticos, como procesadores de texto e follas de cálculo +Comment[he]=יישומים משרדיים, כגון מעבדי תמלילים וגיליונות אלקטרונים +Comment[hr]=Uredske aplikacije, poput procesora teksta i proračunskih tablica +Comment[hu]=Irodai alkalmazások, például szövegszerkesztők és táblázatkezelők +Comment[ia]=Applicationes referite al officio, tal como processator de parolas e folios de calculo +Comment[id]=Aplikasi terkait perkantoran, seperti pengolah kata dan lembar gaya +Comment[is]=Skrifstofutengd forrit, svo sem ritvinnsla og töflureiknar +Comment[ja]=ワープロやスプレッドシートなどのオフィス関連アプリケーション +Comment[kk]=Мәтін өңдегіші мен электрондық кесте секілді Офисіне қатысты қолданбалар +Comment[km]=ការ​រិយាល័យ​ដែល​ទាក់ទង​នឹង​កម្មវិធី ដូច​ជាកម្មវិធី​វាយ​អត្ថបទ និង​សៀវភៅ​បញ្ជី +Comment[ko]=워드프로세서, 스프레드시트와 같은 사무용 프로그램 +Comment[lt]=Biuro programos, tokios, kaip tekstų rinkimo ir elektroninių lentelių +Comment[lv]=Biroja lietotnes, tekstapstrādes un izklājlapu programmas +Comment[mk]=Канцелариски апликации, како што е обработка на текст и табеларни пресметки +Comment[ml]=ആപ്പീസുമായി ബന്ധപ്പെട്ട പ്രയോഗങ്ങളായ വേര്‍ഡ് പ്രൊസസ്സര്‍, സ്പ്രെഡ് ഷീറ്റ് മുതലായവ +Comment[mr]=ऑफीस संबंधित अनुप्रयोग. उदा. वर्डप्रोसेसिंग व स्प्रेडशीट +Comment[nb]=Kontorprogrammer, slik som tekstbehandling og regneark +Comment[nds]=Programmen rund dat Kontoor, so as Textverarbeiden un Tabellrekenprogrammen +Comment[nl]=Kantoor gerelateerde programma's, zoals woordprocessing en rekenbladen +Comment[nn]=Kontorprogramvare, som teksthandsaming og rekneark +Comment[pa]=ਦਫ਼ਤਰ ਨਾਲ ਸਬੰਧਿਤ ਐਪਲੀਕੇਸ਼ਨ, ਜਿਵੇਂ ਕਿ ਵਰਲਡ-ਪਰੋਸੈਸਿੰਗ ਅਤੇ ਸਪਰੈੱਡਸ਼ੀਟ +Comment[pl]=Programy biurowe, takie jak edytory tekstu i arkusze kalkulacyjne +Comment[pt]=Aplicações relacionadas com o escritório, como os processadores de texto e folhas de cálculo +Comment[pt_BR]=Aplicativos de escritório, tais como processadores de texto e planilhas +Comment[ro]=Aplicații legate de birou, cum ar fi procesare de texte și tabele +Comment[ru]=Офисные приложения, такие как текстовые процессоры и электронные таблицы +Comment[si]=වදන් සැකසුම් හා පැතුරුම්ත් වැනි කාර්‍යාල සම්බන්ධ යෙදුම්. +Comment[sk]=Kancelárske aplikácie, ako textový a tabuľkový procesor +Comment[sl]=Pisarniški programi, npr. urejevalniki besedil in preglednice +Comment[sr]=Канцеларијски програми, попут обраде речи и рачунских таблица +Comment[sr@ijekavian]=Канцеларијски програми, попут обраде ријечи и рачунских таблица +Comment[sr@ijekavianlatin]=Kancelarijski programi, poput obrade riječi i računskih tablica +Comment[sr@latin]=Kancelarijski programi, poput obrade reči i računskih tablica +Comment[sv]=Kontorsrelaterade program, som ordbehandling och kalkylblad +Comment[tg]=Барномаҳо барои корҳои идоравӣ, монанди барномаҳои таҳрири матн ва ҷадвалҳои электронӣ +Comment[th]=โปรแกรมต่าง ๆ ด้านสำนักงาน เช่น โปรแกรมประมวลผลคำ และกระดาษคำนวณ +Comment[tr]=Ofis ile ilgili uygulamalar, kelime işlemciler ve hesap tabloları gibi +Comment[ug]=ئىشخانا يۈرۈشلۈك پروگراممىلار، يېزىق بىر تەرەپ قىلىش ۋە ئېلېكترونلۇق جەدۋەل +Comment[uk]=Програми, пов’язані з офісними завданнями, зокрема текстові процесори та електронні таблиці +Comment[wa]=Programes di burotike, come li scrijhaedje di tecses eyet les tåvleus +Comment[x-test]=xxOffice related applications, such as wordprocessing and spreadsheetsxx +Comment[zh_CN]=办公应用程序,如文字处理工具和电子表格 +Comment[zh_TW]=辦公相關應用程式,如文書處理與試算表等 +Icon=applications-office + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-office + +X-Plasma-Sal-Url=kservicegroup://root/Office/ +X-Plasma-Sal-Relevance=1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-system.desktop b/plasma/netbook/containments/sal/services/plasma-sal-system.desktop new file mode 100644 index 00000000..3f437858 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-system.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=System +Name[af]=Stelsel +Name[ar]=النظام +Name[as]=ব্যৱস্থাপ্ৰণালী +Name[ast]=Sistema +Name[be]=Сістэма +Name[be@latin]=Systema +Name[bg]=Система +Name[bn]=সিস্টেম +Name[bn_IN]=সিস্টেম +Name[br]=Reizhiad +Name[bs]=Sistem +Name[ca]=Sistema +Name[ca@valencia]=Sistema +Name[cs]=Systém +Name[csb]=Systema +Name[cy]=Cysawd +Name[da]=System +Name[de]=System +Name[el]=Σύστημα +Name[en_GB]=System +Name[eo]=Sistemo +Name[es]=Sistema +Name[et]=Süsteem +Name[eu]=Sistema +Name[fa]=سیستم +Name[fi]=Järjestelmä +Name[fr]=Système +Name[fy]=Systeem +Name[ga]=Córas +Name[gl]=Sistema +Name[gu]=સિસ્ટમ +Name[he]=מערכת +Name[hi]=तंत्र +Name[hne]=तंत्र +Name[hr]=Sustav +Name[hsb]=System +Name[hu]=Rendszer +Name[ia]=Systema +Name[id]=Sistem +Name[is]=Kerfi +Name[it]=Sistema +Name[ka]=სისტემა +Name[kk]=Жүйе +Name[km]=ប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥೆ +Name[ko]=시스템 +Name[ku]=Pergal +Name[lt]=Sistema +Name[lv]=Sistēma +Name[mai]=सिस्टम +Name[mk]=Систем +Name[ml]=സിസ്റ്റം +Name[mr]=प्रणाली +Name[ms]=Sistem +Name[nb]=System +Name[nds]=Systeem +Name[ne]=प्रणाली +Name[nl]=Systeem +Name[nn]=System +Name[oc]=Sistèma +Name[or]=ତନ୍ତ୍ର +Name[pa]=ਸਿਸਟਮ +Name[pl]=System +Name[pt]=Sistema +Name[pt_BR]=Sistema +Name[ro]=Sistem +Name[ru]=Система +Name[se]=Vuogádat +Name[si]=පද්ධතිය +Name[sk]=Systém +Name[sl]=Sistem +Name[sr]=Систем +Name[sr@ijekavian]=Систем +Name[sr@ijekavianlatin]=Sistem +Name[sr@latin]=Sistem +Name[sv]=System +Name[ta]=அமைப்பு +Name[te]=వ్యవస్థ +Name[tg]=Система +Name[th]=ระบบ +Name[tr]=Sistem +Name[ug]=سىستېما +Name[uk]=Система +Name[uz]=Tizim +Name[uz@cyrillic]=Тизим +Name[vi]=Hệ thống +Name[wa]=Sistinme +Name[xh]=Indlela esestyenziswayo +Name[x-test]=xxSystemxx +Name[zh_CN]=系统 +Name[zh_TW]=系統 +Comment=System preferences and setup programs +Comment[ar]=تفضيلات النظام وإعدادت البرامج +Comment[ast]=Preferencies del sistemes y configuración de programes +Comment[bg]=Програми за системни настройки +Comment[bs]=Programi za podešavanje sistema +Comment[ca]=Preferències del sistema i programes de configuració +Comment[ca@valencia]=Preferències del sistema i programes de configuració +Comment[cs]=Systémové předvolby a nastavení programů +Comment[csb]=Nastôwë systemë ë ùstôwë programów +Comment[da]=Systemindstillinger og opsætningsprogrammer +Comment[de]=Systemeinstellungen und Einrichtungsprogramme +Comment[el]=Προτιμήσεις συστήματος και προγράμματα ρυθμίσεων +Comment[en_GB]=System preferences and setup programs +Comment[eo]=Sistem-preferencoj kaj agordaj programoj +Comment[es]=Preferencias del sistema y configuración de programas +Comment[et]=Süsteemi eelistused ja häälestamisprogrammid +Comment[eu]=Sistemaren hobespenak eta konfigurazio-programak +Comment[fi]=Järjestelmäoikeudet ja asetusohjelmat +Comment[fr]=Programmes de préférences et de configuration du système +Comment[fy]=Systeem foarkar en opset programma's +Comment[ga]=Sainroghanna an chórais agus cláir chumraíochta +Comment[gl]=Preferencias do sistema e programas de configuración +Comment[he]=העדפות מערכת והגדרות יישומים +Comment[hr]=Podešavanje sustava i programi za postavljanje +Comment[hu]=Rendszerbeállítások és beállítóprogramok +Comment[ia]=Preferentias de systema e programmas de disposition +Comment[id]=Pengaturan sistem dan pengaturan program +Comment[is]=Kerfisvalkostir og uppsetningaforrit +Comment[ja]=システム設定やセットアッププログラム +Comment[kk]=Жүйе параметрлер мен оларды баптау қолданбалар +Comment[km]=ចំណូល​ចិត្ត​​ប្រព័ន្ធ និង​រៀបចំ​កម្មវិធី +Comment[kn]=ವ್ಯವಸ್ಥೆಯ ಆದ್ಯತೆಗಳು ಹಾಗು ಸಿದ್ಧತಾ ಕ್ರಮವಿಧಿಗಳು +Comment[ko]=시스템 설정 및 관리 프로그램 +Comment[lt]=Sistemos nustatymų ir derinimo programos +Comment[lv]=Sistēmas iestaījumi un konfigurēšanas programmas +Comment[ml]=സിസ്റ്റത്തിലെ മുന്‍ഗണനകളും സജ്ജീകരണ പ്രോഗ്രാമുകളും +Comment[mr]=प्रणाली प्राधान्य व संयोजना कार्यक्रम +Comment[nb]=Systeminnstillinger og oppsettsprogrammer +Comment[nds]=Systeeminstell- un Inrichtprogrammen +Comment[nl]=Systeemvoorkeuren en instellingsprogramma's +Comment[nn]=Systeminnstillingar og oppsettprogram +Comment[pa]=ਸਿਸਟਮ ਪਸੰਦ ਅਤੇ ਸੈਟਅੱਪ ਪਰੋਗਰਾਮ +Comment[pl]=Ustawienia systemowe i programy konfigurujące +Comment[pt]=Preferências do sistema e programas de configuração +Comment[pt_BR]=Preferências do sistema e programas de configuração +Comment[ro]=Preferințe de sistem și programe de configurare +Comment[ru]=Системные параметры и установка программ +Comment[si]=පද්ධති අභිප්‍රේත හා ස්ථාපක වැඩසටහන් +Comment[sk]=Nastavenie systému a programov +Comment[sl]=Sistemske možnosti in nastavitveni programi +Comment[sr]=Програми за подешавање система +Comment[sr@ijekavian]=Програми за подешавање система +Comment[sr@ijekavianlatin]=Programi za podešavanje sistema +Comment[sr@latin]=Programi za podešavanje sistema +Comment[sv]=Systemanpassning och inställningsprogram +Comment[tg]=Хусусиятҳои система ва танзимоти барномаҳо +Comment[th]=การตั้งค่าต่าง ๆ ของระบบ และโปรแกรมตั้งค่าต่าง ๆ +Comment[tr]=Sistem tercihleri ve ayarlama uygulamaları +Comment[ug]=سىستېما مايىللىقى ۋە بەلگىلەش پروگراممىسى +Comment[uk]=Налаштування системи та програми для налаштування +Comment[wa]=Preferinces do sistinme eyet programes d' apontiaedje +Comment[x-test]=xxSystem preferences and setup programsxx +Comment[zh_CN]=系统首选项和系统设置程序 +Comment[zh_TW]=系統喜好與設定程式 +Icon=preferences-system + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-system + +X-Plasma-Sal-Url=kservicegroup://root/System/ +X-Plasma-Sal-Relevance=0.1 diff --git a/plasma/netbook/containments/sal/services/plasma-sal-utility.desktop b/plasma/netbook/containments/sal/services/plasma-sal-utility.desktop new file mode 100644 index 00000000..65125c44 --- /dev/null +++ b/plasma/netbook/containments/sal/services/plasma-sal-utility.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Name=Utilities +Name[af]=Nutsprogramme +Name[ar]=خدمات +Name[as]=সৰঞ্জাম +Name[ast]=Utilidaes +Name[be]=Службовыя праграмы +Name[be@latin]=Pryładździe +Name[bg]=Инструменти +Name[bn]=আনুষঙ্গিক +Name[bn_IN]=বিবিধ সামগ্রী +Name[br]=Mavegoù +Name[bs]=Alatke +Name[ca]=Utilitats +Name[ca@valencia]=Utilitats +Name[cs]=Nástroje +Name[csb]=Nôrzãdza +Name[cy]=Defnyddioldebau +Name[da]=Værktøjer +Name[de]=Dienstprogramme +Name[el]=Εργαλεία +Name[en_GB]=Utilities +Name[eo]=Utilaĵoj +Name[es]=Utilidades +Name[et]=Tööriistad +Name[eu]=Utilitateak +Name[fa]=برنامه‌های سودمند +Name[fi]=Apuohjelmat +Name[fr]=Utilitaires +Name[fy]=Helpmiddelen +Name[ga]=Uirlisí +Name[gl]=Utensilios +Name[gu]=ઉપયોગી વસ્તુઓ +Name[he]=כלים +Name[hi]=यूटिलिटीज़ +Name[hne]=यूटिलिटीज +Name[hr]=Alati +Name[hsb]=Pomocniki +Name[hu]=Segédprogramok +Name[ia]=Utilitates +Name[id]=Utilitas +Name[is]=Nytjatól +Name[it]=Accessori +Name[ka]=ხელსაწყოები +Name[kk]=Утилиталары +Name[km]=ឧបករណ៍​ប្រើ​ប្រាស់ +Name[kn]=ಸೌಲಭ್ಯಗಳು +Name[ko]=유틸리티 +Name[ku]=Bernameyên Alîkar +Name[lt]=Pagalbininkai +Name[lv]=Utilītas +Name[mai]=उपयोगिता +Name[mk]=Алатки +Name[ml]=ഉപകരണങ്ങള്‍ +Name[mr]=उपकार्यक्रम +Name[ms]=Utiliti +Name[nb]=Verktøy +Name[nds]=Warktüüch +Name[ne]=युटिलिटी +Name[nl]=Hulpmiddelen +Name[nn]=Verktøy +Name[oc]=Utilitaris +Name[or]=ଉପଯୋଗିତା +Name[pa]=ਸਹੂਲਤ +Name[pl]=Narzędzia +Name[pt]=Utilitários +Name[pt_BR]=Utilitários +Name[ro]=Utilitare +Name[ru]=Служебные +Name[se]=Reaiddut +Name[si]=උපයෝග +Name[sk]=Nástroje +Name[sl]=Potrebščine +Name[sr]=Алатке +Name[sr@ijekavian]=Алатке +Name[sr@ijekavianlatin]=Alatke +Name[sr@latin]=Alatke +Name[sv]=Verktyg +Name[ta]=கருவிகள் +Name[te]=సౌలభ్యాలు +Name[tg]=Барномаҳои системавӣ +Name[th]=อรรถประโยชน์ +Name[tr]=Yardımcı Araçlar +Name[ug]=قوراللار +Name[uk]=Утиліти +Name[uz]=Vositalar +Name[uz@cyrillic]=Воситалар +Name[vi]=Tiện ích +Name[wa]=Usteyes +Name[xh]=Izinto eziluncedo +Name[x-test]=xxUtilitiesxx +Name[zh_CN]=工具 +Name[zh_TW]=實用工具 +Comment=Small utilities and accessories +Comment[ar]=أدوات خدمية وملحقات +Comment[ast]=Pequeñes utilidaes y accesorios +Comment[bg]=Разни инструменти +Comment[bs]=Manje priručne alatke +Comment[ca]=Petites utilitats i accessoris +Comment[ca@valencia]=Petites utilitats i accessoris +Comment[cs]=Malé nástroje a příslušenství +Comment[csb]=Môłé nôrzãdza ë pòmòcné aplikacëje +Comment[da]=Små værktøjer og tilbehør +Comment[de]=Kleine Werkzeuge und Zubehörprogramme +Comment[el]=Μικρές εφαρμογές και εξαρτήματα +Comment[en_GB]=Small utilities and accessories +Comment[es]=Pequeñas utilidades y accesorios +Comment[et]=Väikesed tööriistad ja abivahendid +Comment[eu]=Utilitate txikiak eta gehigarriak +Comment[fi]=Pienet apuohjelmat ja oheislaitteet +Comment[fr]=Petits utilitaires et accessoires +Comment[fy]=Stikmannich lyts ark +Comment[ga]=Uirlisí beaga agus oiriúintí +Comment[gl]=Pequenas utilidades e accesorios +Comment[he]=כלים ועזרים קטנים +Comment[hr]=Mali uslužni programi i pomagala +Comment[hu]=Kis segédprogramok és kellékek +Comment[ia]=Parve utilitates e accessorios +Comment[id]=Utilitas dan aksesoris kecil +Comment[is]=Lítil nytjatól og aukahlutir +Comment[ja]=小さなユーティリティとアクセサリ +Comment[kk]=Шағын утилиталар мен әбзелдері +Comment[km]=ឧបករណ៍​ប្រើប្រាស់​តូច និង​គ្រឿង​របស់​វា +Comment[kn]=ಸಣ್ಣ ಸವಲತ್ತುಗಳು ಮತ್ತು ಸಲಕರಣೆಗಳು +Comment[ko]=작은 유틸리티와 액세서리 +Comment[lt]=Nedideli pagalbininkai +Comment[lv]=Mazas utilītas un aksesuāri +Comment[mk]=Мали алатки и додатоци +Comment[ml]=ചെറിയ ഉപകരണങ്ങള്‍ +Comment[mr]=लहान उपकार्यक्रम व साधने +Comment[nb]=Små verktøy- og tilbehørsprogrammer +Comment[nds]=Lütte Warktüüch un Hülpprogrammen +Comment[nl]=Kleine programma's en accessoires +Comment[nn]=Små verktøy og nytteprogram +Comment[pa]=ਛੋਟੀਆਂ ਸਹੂਲਤਾਂ ਅਤੇ ਸਹਾਇਕ +Comment[pl]=Niewielkie narzędzia i akcesoria +Comment[pt]=Pequenos utilitários e acessórios +Comment[pt_BR]=Pequenos utilitários e acessórios +Comment[ro]=Mici accesorii și utilitare +Comment[ru]=Небольшие программы и инструменты +Comment[si]=කුඩා උපයෝග සහ උපාංග +Comment[sk]=Nástroje a príslušenstvo +Comment[sl]=Majhna orodja in pripomočki +Comment[sr]=Мање приручне алатке +Comment[sr@ijekavian]=Мање приручне алатке +Comment[sr@ijekavianlatin]=Manje priručne alatke +Comment[sr@latin]=Manje priručne alatke +Comment[sv]=Mindre verktyg och tillbehör +Comment[tg]=Барномаҳо ва афзорҳои хурд +Comment[th]=เครื่องมืออรรถประโยชน์และโปรแกรมเพิ่มเติมต่าง ๆ ที่มีขนาดเล็ก +Comment[tr]=Küçük ve faydalı uygulamalar +Comment[ug]=كىچىك قوراللار ۋە قوشۇمچە قوراللار +Comment[uk]=Малі програми та інструменти +Comment[wa]=Pititès usteyes +Comment[x-test]=xxSmall utilities and accessoriesxx +Comment[zh_CN]=小型附件和辅助工具 +Comment[zh_TW]=小型實用工具與輔助程式 +Icon=applications-utilities + +Type=Service +X-KDE-ServiceTypes=Plasma/Sal/Menu +X-KDE-PluginInfo-Name=plasma-sal-utility + +X-Plasma-Sal-Url=kservicegroup://root/Utilities/ +X-Plasma-Sal-Relevance=0.2 diff --git a/plasma/netbook/containments/sal/stripwidget.cpp b/plasma/netbook/containments/sal/stripwidget.cpp new file mode 100644 index 00000000..cded4bcf --- /dev/null +++ b/plasma/netbook/containments/sal/stripwidget.cpp @@ -0,0 +1,292 @@ +/* + * Copyright 2009 by Artur Duque de Souza + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stripwidget.h" +#include "models/favouritesmodel.h" +#include "models/krunnermodel.h" +#include "models/kservicemodel.h" +#include "models/commonmodel.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "itemview.h" +#include "iconactioncollection.h" + +StripWidget::StripWidget(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_itemView(0), + m_deleteTarget(0), + m_iconActionCollection(0), + m_offset(0), + m_startupCompleted(false) +{ + m_favouritesModel = new FavouritesModel(this); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + setAcceptDrops(true); + + Plasma::Applet *applet = qobject_cast(parent); + if (applet) { + m_iconActionCollection = new IconActionCollection(applet, this); + } + + m_arrowsLayout = new QGraphicsLinearLayout(this); + m_arrowsLayout->setContentsMargins(0, 0, 0, 0); + setFocusPolicy(Qt::StrongFocus); + + m_leftArrow = new Plasma::ToolButton(this); + m_leftArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + m_leftArrow->setPreferredWidth(KIconLoader::SizeMedium); + m_leftArrow->setImage("widgets/arrows", "left-arrow"); + connect(m_leftArrow, SIGNAL(clicked()), this, SLOT(goLeft())); + connect(m_leftArrow, SIGNAL(pressed()), this, SLOT(scrollTimeout())); + + m_rightArrow = new Plasma::ToolButton(this); + m_rightArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + m_rightArrow->setPreferredWidth(KIconLoader::SizeMedium); + m_rightArrow->setImage("widgets/arrows", "right-arrow"); + connect(m_rightArrow, SIGNAL(clicked()), this, SLOT(goRight())); + connect(m_rightArrow, SIGNAL(pressed()), this, SLOT(scrollTimeout())); + + m_leftArrow->setEnabled(false); + m_rightArrow->setEnabled(false); + m_leftArrow->hide(); + m_rightArrow->hide(); + + m_itemView = new ItemView(this); + m_itemView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_itemView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_itemView->installEventFilter(this); + m_itemView->setOrientation(Qt::Horizontal); + m_itemView->setIconSize(KIconLoader::SizeLarge); + m_itemView->setDragAndDropMode(ItemContainer::MoveDragAndDrop); + m_itemView->setModel(m_favouritesModel); + + connect(m_itemView, SIGNAL(itemActivated(QModelIndex)), this, SLOT(launchFavourite(QModelIndex))); + connect(m_itemView, SIGNAL(scrollBarsNeededChanged(ItemView::ScrollBarFlags)), this, SLOT(arrowsNeededChanged(ItemView::ScrollBarFlags))); + connect(m_itemView, SIGNAL(itemAskedReorder(QModelIndex,QPointF)), this, SLOT(reorderItem(QModelIndex,QPointF))); + connect(m_itemView, SIGNAL(dragStartRequested(QModelIndex)), this, SLOT(showDeleteTarget())); + + m_arrowsLayout->addItem(m_leftArrow); + m_arrowsLayout->addItem(m_itemView); + m_arrowsLayout->addItem(m_rightArrow); + + m_scrollTimer = new QTimer(this); + m_scrollTimer->setSingleShot(false); + connect(m_scrollTimer, SIGNAL(timeout()), this, SLOT(scrollTimeout())); +} + +StripWidget::~StripWidget() +{ +} + +void StripWidget::showDeleteTarget() +{ + if (!m_deleteTarget) { + m_deleteTarget = new Plasma::IconWidget(); + scene()->addItem(m_deleteTarget); + m_deleteTarget->setIcon("user-trash"); + m_deleteTarget->resize(KIconLoader::SizeHuge, KIconLoader::SizeHuge); + m_deleteTarget->setZValue(99); + } + m_deleteTarget->setPos(mapToScene(boundingRect().bottomLeft())); + m_deleteTarget->show(); + Plasma::Animation *zoomAnim = Plasma::Animator::create(Plasma::Animator::ZoomAnimation); + zoomAnim->setTargetWidget(m_deleteTarget); + zoomAnim->setProperty("zoom", 1.0); + zoomAnim->start(QAbstractAnimation::DeleteWhenStopped); +} + +void StripWidget::setImmutability(Plasma::ImmutabilityType immutability) +{ + if (immutability == Plasma::Mutable) { + m_itemView->setDragAndDropMode(ItemContainer::MoveDragAndDrop); + } else { + m_itemView->setDragAndDropMode(ItemContainer::NoDragAndDrop); + } +} + + +void StripWidget::reorderItem(const QModelIndex &index, const QPointF &pos) +{ + if (m_deleteTarget && m_deleteTarget->geometry().contains(m_itemView->widget()->mapToItem(this, pos))) { + m_favouritesModel->removeRow(index.row()); + } else { + QListitems = m_favouritesModel->takeRow(index.row()); + int row = m_itemView->rowForPosition(pos); + + m_favouritesModel->insertRow(row, items); + } + + Plasma::Animation *zoomAnim = Plasma::Animator::create(Plasma::Animator::ZoomAnimation); + zoomAnim->setTargetWidget(m_deleteTarget); + zoomAnim->start(QAbstractAnimation::DeleteWhenStopped); +} + +void StripWidget::save(KConfigGroup &cg) +{ + m_favouritesModel->save(cg); +} + +void StripWidget::restore(KConfigGroup &cg) +{ + m_favouritesModel->restore(cg); +} + +void StripWidget::launchFavourite(const QModelIndex &index) +{ + KUrl url(index.data(CommonModel::Url).value()); + if (!KServiceItemHandler::openUrl(url)) { + KRunnerItemHandler::openUrl(url); + } +} + +void StripWidget::add(const QUrl &url) +{ + m_favouritesModel->add(url); + emit saveNeeded(); +} + +void StripWidget::goRight() +{ + QRectF rect(m_itemView->boundingRect()); + rect.moveLeft(rect.right() - m_itemView->widget()->pos().x()); + rect.setWidth(rect.width()/4); + + m_itemView->ensureRectVisible(rect); +} + +void StripWidget::goLeft() +{ + QRectF rect(m_itemView->boundingRect()); + rect.setWidth(rect.width()/4); + rect.moveRight(- m_itemView->widget()->pos().x()); + + m_itemView->ensureRectVisible(rect); +} + +void StripWidget::scrollTimeout() +{ + if (!m_scrollTimer->isActive()) { + m_scrollTimer->start(250); + } else if (m_leftArrow->isDown()) { + goLeft(); + } else if (m_rightArrow->isDown()) { + goRight(); + } else { + m_scrollTimer->stop(); + } +} + +void StripWidget::setIconSize(int iconSize) +{ + m_itemView->setIconSize(iconSize); +} + +int StripWidget::iconSize() const +{ + return m_itemView->iconSize(); +} + +void StripWidget::arrowsNeededChanged(ItemView::ScrollBarFlags flags) +{ + bool leftNeeded = false; + bool rightNeeded = false; + + if (flags & ItemView::HorizontalScrollBar) { + leftNeeded = m_itemView->scrollPosition().x() > 0; + rightNeeded = m_itemView->contentsSize().width() - m_itemView->scrollPosition().x() > m_itemView->size().width(); + } + + m_leftArrow->setEnabled(leftNeeded); + m_rightArrow->setEnabled(rightNeeded); + m_leftArrow->setVisible(leftNeeded|rightNeeded); + m_rightArrow->setVisible(leftNeeded|rightNeeded); + m_arrowsLayout->invalidate(); +} + + + +void StripWidget::focusInEvent(QFocusEvent *event) +{ + Q_UNUSED(event) + + m_itemView->setFocus(); +} + +void StripWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event) +{ + event->setAccepted(event->mimeData()->hasFormat("application/x-plasma-salquerymatch") || event->mimeData()->hasFormat("text/uri-list")); +} + +void StripWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event) +{ + m_itemView->setScrollPositionFromDragPosition(event->pos()); + m_itemView->showSpacer(m_itemView->widget()->mapFromScene(event->scenePos())); +} + +void StripWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) +{ + Q_UNUSED(event) + + m_itemView->showSpacer(QPointF()); +} + +void StripWidget::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + m_itemView->showSpacer(QPointF()); + if (event->mimeData()->hasFormat("application/x-plasma-salquerymatch")) { + QByteArray itemData = event->mimeData()->data("application/x-plasma-salquerymatch"); + QDataStream dataStream(&itemData, QIODevice::ReadOnly); + + QUrl url; + + dataStream >>url; + + int row = m_itemView->rowForPosition(m_itemView->widget()->mapFromScene(event->scenePos())); + QModelIndex index = m_favouritesModel->index(row, 0, QModelIndex()); + //TODO: proper index + m_favouritesModel->add(url.toString(), index); + emit saveNeeded(); + + } else if (event->mimeData()->urls().size() > 0) { + int row = m_itemView->rowForPosition(m_itemView->widget()->mapFromScene(event->scenePos())); + QModelIndex index = m_favouritesModel->index(row, 0, QModelIndex()); + m_favouritesModel->add(event->mimeData()->urls().first().path(), index); + emit saveNeeded(); + } else { + event->ignore(); + } +} diff --git a/plasma/netbook/containments/sal/stripwidget.h b/plasma/netbook/containments/sal/stripwidget.h new file mode 100644 index 00000000..208e74d4 --- /dev/null +++ b/plasma/netbook/containments/sal/stripwidget.h @@ -0,0 +1,102 @@ +/* + * Copyright 2009 by Artur Duque de Souza + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef STRIPWIDGET_H +#define STRIPWIDGET_H + + +#include +#include + +#include +#include +#include + + +#include + +#include "itemview.h" + +namespace Plasma +{ + class IconWidget; + class ToolButton; +} + +class QTimer; +class IconActionCollection; + +class FavouritesModel; + +class StripWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + StripWidget(QGraphicsWidget *parent = 0); + ~StripWidget(); + + void save(KConfigGroup &cg); + void restore(KConfigGroup &cg); + + void setIconSize(int iconSize); + int iconSize() const; + + //TODO: geter and setter? + void setImmutability(Plasma::ImmutabilityType immutability); + void add(const QUrl &url); + +protected: + Plasma::IconWidget *createIcon(const QPointF &point); + void focusInEvent(QFocusEvent *event); + void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + void dragMoveEvent(QGraphicsSceneDragDropEvent *event); + void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + +private Q_SLOTS: + void launchFavourite(const QModelIndex &index); + void arrowsNeededChanged(ItemView::ScrollBarFlags flags); + void goLeft(); + void goRight(); + void scrollTimeout(); + void reorderItem(const QModelIndex &index, const QPointF &point); + void showDeleteTarget(); + +Q_SIGNALS: + void saveNeeded(); + +private: + Plasma::ToolButton *m_leftArrow; + Plasma::ToolButton *m_rightArrow; + QGraphicsLinearLayout *m_arrowsLayout; + + QHash m_services; + ItemView *m_itemView; + Plasma::RunnerContext *m_context; + QTimer *m_scrollTimer; + Plasma::IconWidget *m_deleteTarget; + IconActionCollection *m_iconActionCollection; + int m_shownIcons; + int m_offset; + bool m_startupCompleted; + FavouritesModel *m_favouritesModel; +}; + +#endif diff --git a/plasma/netbook/dataengines/CMakeLists.txt b/plasma/netbook/dataengines/CMakeLists.txt new file mode 100644 index 00000000..e6a67825 --- /dev/null +++ b/plasma/netbook/dataengines/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(searchlaunch) diff --git a/plasma/netbook/dataengines/searchlaunch/CMakeLists.txt b/plasma/netbook/dataengines/searchlaunch/CMakeLists.txt new file mode 100644 index 00000000..a4ecc661 --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/CMakeLists.txt @@ -0,0 +1,19 @@ +project(searchlaunchengine) + +set(searchlaunch_engine_SRCS + salengine.cpp + salservice.cpp) + +kde4_add_plugin(plasma_engine_searchlaunch ${searchlaunch_engine_SRCS}) +target_link_libraries(plasma_engine_searchlaunch + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_engine_searchlaunch + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-engine-searchlaunch.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES searchlaunch.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/plasma/netbook/dataengines/searchlaunch/plasma-engine-searchlaunch.desktop b/plasma/netbook/dataengines/searchlaunch/plasma-engine-searchlaunch.desktop new file mode 100644 index 00000000..d952ce6e --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/plasma-engine-searchlaunch.desktop @@ -0,0 +1,140 @@ +[Desktop Entry] +Name=Search and Launch Engine +Name[ar]=محرك البحث والإطلاق +Name[ast]=Motor de gueta y llanzamientu +Name[bs]=motor pretrage i pokretanja +Name[ca]=Motor de cerca i llançament +Name[ca@valencia]=Motor de cerca i llançament +Name[cs]=Vyhledávací a spouštěcí stroj +Name[csb]=Mòtórë szëkbë ë zrëszaniô +Name[da]=Motor til søg og opstart +Name[de]=Treiber für „Suchen und ausführen“ +Name[el]=Μηχανή αναζήτησης και εκτέλεσης +Name[en_GB]=Search and Launch Engine +Name[eo]=Serĉi kaj lanĉi motoron +Name[es]=Motor de búsqueda y lanzamiento +Name[et]=Otsimise ja käivitamise mootor +Name[eu]=Bilaketetarako eta abioetarako motorra +Name[fi]=Haku- ja käynnistyskone +Name[fr]=Moteur de recherche et de lancement +Name[fy]=Syk en útfier motor +Name[ga]=Inneall Cuardaigh/Tosaithe +Name[gl]=Motor de busca e inicio +Name[gu]=શોધ અને શરુકરનાર એન્જિન +Name[he]=מנוע חיפוש והפעלה +Name[hi]=खोज और लाँच इंजन +Name[hr]=Mehanizam za pretragu i pokretanje +Name[hu]=Keresés és indítás modul +Name[ia]=Motor per cercar e lancear +Name[id]=Mesin Pencari dan Peluncur +Name[is]=Leitar- og ræsingarvél +Name[ja]=検索起動エンジン +Name[kk]=Іздеу және жегу тетіктер +Name[km]=ស្វែងរក ហើយ​ចាប់ផ្ដើម​ម៉ាស៊ីន +Name[kn]=ಹುಡುಕು ಹಾಗು ಪ್ರಕ್ಷೇಪನ ಯಂತ್ರ +Name[ko]=찾아서 실행하기 엔진 +Name[lt]=Paieškos ir paleidimo variklis +Name[lv]=Meklēšanas un plaišanas dzinējs +Name[mk]=Машина за пребарување и стартување +Name[ml]=തെരയാനും തുടങ്ങാനുമുള്ള എഞ്ചിന്‍ +Name[mr]=शोधा व प्रक्षेपण करा इंजिन +Name[nb]=Søk og start-motor +Name[nds]=Söök- un Oproopkarn +Name[nl]=Zoek- en start-engine +Name[nn]=Motor for søk og køyr +Name[pa]=ਖੋਜ ਅਤੇ ਚਲਾਉਣ ਇੰਜਣ +Name[pl]=Silnik wyszukiwania i uruchamiania +Name[pt]=Motor de Busca e Lançamento +Name[pt_BR]=Mecanismo de pesquisa e execução +Name[ro]=Motor de căutare și lansare +Name[ru]=Источник данных для страницы «Поиск и запуск» +Name[si]=සොයා ක්‍රියාකරවන එන්ජිම +Name[sk]=Nástroj pre Hľadať a spustiť +Name[sl]=Pogon za iskanje in zaganjanje +Name[sr]=мотор претраге и покретања +Name[sr@ijekavian]=мотор претраге и покретања +Name[sr@ijekavianlatin]=motor pretrage i pokretanja +Name[sr@latin]=motor pretrage i pokretanja +Name[sv]=Sök- och startprogram +Name[tg]=Барномаи ҷустуҷӯ +Name[th]=กลไลการค้นหาและเรียกใช้งาน +Name[tr]=Ara ve Çalıştır Motoru +Name[ug]=ئىزدە ۋە ئىجرا قىلىش ماتورى +Name[uk]=Рушій пошуку і запуску +Name[wa]=Moteur di cweraedje et d' enondaedje +Name[x-test]=xxSearch and Launch Enginexx +Name[zh_CN]=搜索与启动引擎 +Name[zh_TW]=搜索與啟動引擎 +Comment=Engine to handle queries to SAL containment +Comment[ar]=محرك لمعاملة الاستعلامات إلى حاوية البحث والإطلاق +Comment[ast]=Motor pa remanar consultes a un contenedor SAL +Comment[bs]=Datomotor za obradu upita za sadržalac pretrage i pokretanja +Comment[ca]=Motor per gestionar consultes al contenidor SAL +Comment[ca@valencia]=Motor per gestionar consultes al contenidor SAL +Comment[cs]=Stroj pro řízení dotazů SAL kontejneru +Comment[da]=Motor til at håndtere forespørgsler til SAL-beholderen +Comment[de]=Treiber zur Behandlung von Anfragen an den Container „Suchen und Ausführen“ +Comment[el]=Μηχανή ελέγχου ερωτημάτων για τον υποδοχέα SAL +Comment[en_GB]=Engine to handle queries to SAL containment +Comment[es]=Motor para manejar consultas a un contenedor SAL +Comment[et]=SAL konteineri päringuid käitlev mootor +Comment[eu]=Kontsultak SAL edukiontzira kudeatzeko motorra +Comment[fi]=Kone käsittelemään SAL-sovelmasäiliön kyselyjä +Comment[fr]=Moteur manipulant les requêtes vers le conteneur SAL +Comment[fy]=Motor om defragen nei SAL kontainer ôf te hanneljen +Comment[gl]=Un motor para manipular consultas ao contedor SAL +Comment[he]=מנוע לניהול שאילתות לתיבת החיפוש וההפעלה +Comment[hr]=Mehanizam za rad s upitima SAL okruženju +Comment[hu]=Modul lekérdezések kezelésére a SAL tartóelemtől +Comment[ia]=Motor pro manear interrogationes al contento SAL +Comment[id]=Mesin untuk menangani lema ke pembatasan SAL +Comment[is]=Kerfi sem meðhöndlar fyrirspurnir til SAL geymslugrunns +Comment[ja]=SAL コンテンツのクエリを処理するエンジン +Comment[kk]=SAL контейнеріне қойылған сұраныстарына жауап беретін тетік +Comment[km]=ម៉ាស៊ីន​ត្រូវ​គ្រប់គ្រង​សំណួរ​ការ​ផ្ទុក SAL +Comment[ko]=SAL 포함 플러그인의 쿼리 처리를 위한 엔진 +Comment[lt]=Variklis, skirtas tvarkyti užklausas į SAL konteinerį +Comment[lv]=Dzinējs, kas apstrādā pieprasījumus uz SAL ietvērumu +Comment[ml]=എസ്എഎല്‍ കണ്ടൈന്‍മെന്റിനുള്ള ക്വറികള്‍ കൈകാര്യം ചെയ്യുന്നതിനുള്ള എഞ്ചിന്‍ +Comment[mr]=SAL कंटेनमेंटचे प्रश्न हाताळणारे इंजिन +Comment[nb]=Motor som håndterer forespørsler til SoS-beholder +Comment[nds]=Karn för Anfragen na't SuO-Gelaats +Comment[nl]=Engine voor het afhandelen van zoekopdrachten naar de SAL-houder +Comment[nn]=Motor for å handtera spørjinga til SAL-behaldaren +Comment[pa]=SAL ਕਨਟੇਨਮੈਂਟ ਲਈ ਕਿਊਰੀ ਹੈਂਡਲ ਕਰਨ ਵਾਸਤੇ ਇੰਜਣ +Comment[pl]=Silnik do obsługi zapytań do kontenera SAL +Comment[pt]=Motor para lidar com as pesquisas ao contentor ASL +Comment[pt_BR]=Mecanismo para lidar com pesquisas ao contêiner ASL +Comment[ro]=Motor pentru tratarea cererilor către un container SAL +Comment[ru]=Обработка запросов к контейнеру «Поиск и запуск» +Comment[si]=SAL ධාරක විමසීම් හැසිරවිම සඳහා එන්ජිම +Comment[sk]=Nástroj na spracovanie dotazov pre Hľadať a spustiť +Comment[sl]=Pogon za ravnanje s poizvedbami za vsebnik SAL +Comment[sr]=Датомотор за обраду упита за садржалац претраге и покретања +Comment[sr@ijekavian]=Датомотор за обраду упита за садржалац претраге и покретања +Comment[sr@ijekavianlatin]=Datomotor za obradu upita za sadržalac pretrage i pokretanja +Comment[sr@latin]=Datomotor za obradu upita za sadržalac pretrage i pokretanja +Comment[sv]=Program för att hantera förfrågningar till SAL-omgivning +Comment[th]=กลไกที่จะจัดการการสืบค้นไปยังส่วนบรรจุ SAL +Comment[tr]=SAL içericisine gelen sorgular için bir motor +Comment[ug]=SAL قاچا سۈرۈشتۈرىدىغان ماتورنى بىر تەرەپ قىلىدۇ +Comment[uk]=Рушій для обробки запитів до контейнера SAL +Comment[vi]=Cơ chế xử lý truy vấn tới SAL +Comment[wa]=Moteur pos apougnî les rcweraedje e contenmint SAL +Comment[x-test]=xxEngine to handle queries to SAL containmentxx +Comment[zh_CN]=处理 SAL 容器查询的引擎 +Comment[zh_TW]=處理 SAL 容器查詢的引擎 +Type=Service + +X-KDE-ServiceTypes=Plasma/DataEngine +X-KDE-Library=plasma_engine_searchlaunch +X-Plasma-EngineName=searchlaunch +X-KDE-PluginInfo-Author=Artur Souza +X-KDE-PluginInfo-Email=morpheuz@gmail.com +X-KDE-PluginInfo-Name=searchlaunch +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plasma/netbook/dataengines/searchlaunch/salengine.cpp b/plasma/netbook/dataengines/searchlaunch/salengine.cpp new file mode 100644 index 00000000..a8df7c60 --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/salengine.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "salengine.h" +#include "salservice.h" + + +SearchLaunchEngine::SearchLaunchEngine(QObject* parent, const QVariantList& args) + : Plasma::DataEngine(parent, args) +{ + Q_UNUSED(args); +} + +void SearchLaunchEngine::init() +{ + setData("query", QString()); +} + +Plasma::Service *SearchLaunchEngine::serviceForSource(const QString &source) +{ + if (source != "query") { + return 0; + } + + SearchLaunchService *service = new SearchLaunchService(this); + service->setParent(this); + return service; +} + +K_EXPORT_PLASMA_DATAENGINE(searchlaunch, SearchLaunchEngine) + +#include "salengine.moc" diff --git a/plasma/netbook/dataengines/searchlaunch/salengine.h b/plasma/netbook/dataengines/searchlaunch/salengine.h new file mode 100644 index 00000000..ee4c6695 --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/salengine.h @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SEARCHLAUNCH_ENGINE_H +#define SEARCHLAUNCH_ENGINE_H + +#include +#include + +class SearchLaunchService; + +class SearchLaunchEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + SearchLaunchEngine(QObject* parent, const QVariantList& args); + Plasma::Service *serviceForSource(const QString &source); + void init(); + + friend class SearchLaunchService; +}; + +#endif // SEARCHLAUNCH_ENGINE_H diff --git a/plasma/netbook/dataengines/searchlaunch/salservice.cpp b/plasma/netbook/dataengines/searchlaunch/salservice.cpp new file mode 100644 index 00000000..ffeb4b35 --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/salservice.cpp @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "salservice.h" + + +SearchLaunchService::SearchLaunchService(SearchLaunchEngine *engine) +{ + m_engine = engine; + setName("searchlaunch"); +} + +ServiceJob *SearchLaunchService::createJob(const QString &operation, + QMap ¶meters) +{ + if (!m_engine) { + return 0; + } + + m_engine->setData(operation, parameters["query"]); + return 0; +} + +#include "salservice.moc" diff --git a/plasma/netbook/dataengines/searchlaunch/salservice.h b/plasma/netbook/dataengines/searchlaunch/salservice.h new file mode 100644 index 00000000..bbce8e78 --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/salservice.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SEARCHLAUNCH_SERVICE_H +#define SEARCHLAUNCH_SERVICE_H + +#include "salengine.h" + +#include +#include + +using namespace Plasma; + + +class SearchLaunchService : public Plasma::Service +{ + Q_OBJECT + +public: + SearchLaunchService(SearchLaunchEngine *engine); + ServiceJob *createJob(const QString &operation, + QMap ¶meters); + +private: + SearchLaunchEngine *m_engine; +}; + +#endif // SEARCHLAUNCH_SERVICE_H diff --git a/plasma/netbook/dataengines/searchlaunch/searchlaunch.operations b/plasma/netbook/dataengines/searchlaunch/searchlaunch.operations new file mode 100644 index 00000000..d71d182f --- /dev/null +++ b/plasma/netbook/dataengines/searchlaunch/searchlaunch.operations @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/plasma/netbook/desktoptheme/CMakeLists.txt b/plasma/netbook/desktoptheme/CMakeLists.txt new file mode 100644 index 00000000..1b5ccec0 --- /dev/null +++ b/plasma/netbook/desktoptheme/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(air-netbook) diff --git a/plasma/netbook/desktoptheme/air-netbook/CMakeLists.txt b/plasma/netbook/desktoptheme/air-netbook/CMakeLists.txt new file mode 100644 index 00000000..a4216bbe --- /dev/null +++ b/plasma/netbook/desktoptheme/air-netbook/CMakeLists.txt @@ -0,0 +1,6 @@ + +install(FILES colors metadata.desktop DESTINATION ${DATA_INSTALL_DIR}/desktoptheme/air-netbook/) + +FILE(GLOB widgets widgets/*.svgz) +install( FILES ${widgets} DESTINATION ${DATA_INSTALL_DIR}/desktoptheme/air-netbook/widgets/ ) + diff --git a/plasma/netbook/desktoptheme/air-netbook/colors b/plasma/netbook/desktoptheme/air-netbook/colors new file mode 100644 index 00000000..faba1450 --- /dev/null +++ b/plasma/netbook/desktoptheme/air-netbook/colors @@ -0,0 +1,82 @@ +[Colors:Button] +BackgroundAlternate=218,221,215 +BackgroundNormal=218,221,215 +DecorationFocus=239,132,65 +DecorationHover=72,177,60 +ForegroundActive=255,0,0 +ForegroundInactive=152,154,149 +ForegroundLink=0,0,255 +ForegroundNegative=107,0,0 +ForegroundNeutral=0,90,95 +ForegroundNormal=0,0,0 +ForegroundPositive=0,95,0 +ForegroundVisited=88,55,150 + +[Colors:Selection] +BackgroundAlternate=62,138,204 +BackgroundNormal=65,139,212 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=165,193,228 +ForegroundLink=0,49,110 +ForegroundNegative=156,14,14 +ForegroundNeutral=255,221,0 +ForegroundNormal=255,255,255 +ForegroundPositive=128,255,128 +ForegroundVisited=69,40,134 + + +[Colors:Tooltip] +BackgroundAlternate=255,248,209 +BackgroundNormal=255,255,255 +DecorationFocus=239,132,65 +DecorationHover=72,177,60 +ForegroundActive=255,0,0 +ForegroundInactive=232,185,149 +ForegroundLink=0,0,255 +ForegroundNegative=107,0,0 +ForegroundNeutral=0,90,95 +ForegroundNormal=0,0,0 +ForegroundPositive=0,95,0 +ForegroundVisited=88,55,150 + +[Colors:View] +BackgroundAlternate=248,247,246 +BackgroundNormal=255,255,255 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=255,128,224 +ForegroundInactive=36,35,34 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=100,74,155 + +[Colors:Window] +BackgroundAlternate=218,217,216 +BackgroundNormal=255,255,255 +DecorationFocus=43,116,199 +DecorationHover=119,183,255 +ForegroundActive=10,128,224 +ForegroundInactive=36,35,34 +ForegroundLink=0,87,174 +ForegroundNegative=191,3,3 +ForegroundNeutral=176,128,0 +ForegroundNormal=20,19,18 +ForegroundPositive=0,110,40 +ForegroundVisited=100,74,155 + +[General] +shadeSortColumn=true + +[KDE] +contrast=7 + +[WM] +activeBackground=65,142,220 +activeForeground=255,255,255 +inactiveBackground=157,170,186 +inactiveForeground=65,142,220 diff --git a/plasma/netbook/desktoptheme/air-netbook/metadata.desktop b/plasma/netbook/desktoptheme/air-netbook/metadata.desktop new file mode 100644 index 00000000..03cfc192 --- /dev/null +++ b/plasma/netbook/desktoptheme/air-netbook/metadata.desktop @@ -0,0 +1,148 @@ +[Desktop Entry] +Name=Air for netbooks +Name[ar]=الهواء للحاسبات المحمولة الشبكيّة +Name[ast]=Air pa netbooks +Name[bg]=Тема "Въздух" за нетбук +Name[bn]=নেটবুক-এর জন্য এয়ার +Name[bs]=Vazduh za netbuke +Name[ca]=Air per a ordinadors ultraportàtils +Name[ca@valencia]=Air per a ordinadors ultraportàtils +Name[cs]=Air pro netbooky +Name[da]=Air til netbooks +Name[de]=Air für Netbooks +Name[el]=Αέρας για τα netbooks +Name[en_GB]=Air for netbooks +Name[eo]=Air por netbook-oj +Name[es]=Air para netbooks +Name[et]=Air väikesülearvutitele +Name[eu]=Netbooketarako "Air" +Name[fi]=Air miniläppäreille +Name[fr]=« Air » pour les ultra portables +Name[fy]=Air foar netbooks +Name[gl]=Air para ultraportátiles +Name[he]=‏Air לנטבוקים +Name[hr]=Zrak za netbooke +Name[hu]=Air téma netbookokra +Name[ia]=Air pro netbooks +Name[id]=Air untuk komputer mini +Name[is]=Air fyrir smáfartölvur +Name[ja]=ネットブック用の Air +Name[kk]=Нетбукке арналған Air +Name[km]=ខ្យល់​សម្រាប់ netbooks +Name[kn]=ನೆಟ್‌ಬುಕ್‌ಗಳಿಗಾಗಿನ ಏರ್ +Name[ko]=넷북을 위한 Air +Name[lt]=Oras netbukams +Name[lv]=Air mazdatoriem +Name[ml]=നെറ്റ്ബൂക്കിനുവേണ്ടിയുള്ള എയര്‍ +Name[mr]=नेटबूक करिता एअर +Name[nb]=Air for netbook-maskiner +Name[nds]=Luft för Nettböker +Name[nl]=Air voor netbooks +Name[nn]=Luft for mini-PC-ar +Name[pa]=ਨੈੱਟਬੁੱਕ ਲਈ ਏਅਰ +Name[pl]=Air dla netbooków +Name[pt]=Air para Netbooks +Name[pt_BR]=Ar para Netbooks +Name[ro]=Aer pentru netbook +Name[ru]=Air для нетбуков +Name[si]=නෙට්බුක් සඳහා Air +Name[sk]=Vzduch pre netbooky +Name[sl]=Zrak za male prenosnike +Name[sr]=Ваздух за нетбуке +Name[sr@ijekavian]=Ваздух за нетбуке +Name[sr@ijekavianlatin]=Vazduh za netbuke +Name[sr@latin]=Vazduh za netbuke +Name[sv]=Luft för bärbara nätdatorer +Name[tg]=Ҳаво барои нетбукҳо +Name[th]=รูปแบบ Air สำหรับเครื่องเน็ตบุ๊ก +Name[tr]=Netbooklar için Air +Name[ug]=تور كومپيۇتېر ھاۋا ئۆرنىكى +Name[uk]=«Air» для субноутбука +Name[vi]=Air cho netbook +Name[wa]=Air po les poirtåvès éndjoletes +Name[x-test]=xxAir for netbooksxx +Name[zh_CN]=上网本大气主题 +Name[zh_TW]=Netbooks 上的 Air +Comment=A breath of fresh air +Comment[ar]=نسمة من الهواء النقي +Comment[ast]=Un soplu d'aire frescu +Comment[bg]=Глътка свеж въздух +Comment[bs]=Dašak svježeg vazduha +Comment[ca]=Una alenada d'aire fresc +Comment[ca@valencia]=Una alenada d'aire fresc +Comment[cs]=Závan čerstvého vzduchu +Comment[csb]=Wiéw swiérzegò lëftu +Comment[da]=En mundfuld frisk luft +Comment[de]=Ein Atemzug frische Luft +Comment[el]=Μια ανάσα φρέσκου αέρα +Comment[en_GB]=A breath of fresh air +Comment[eo]=Spiro de freŝa aero +Comment[es]=Un soplo de aire fresco +Comment[et]=Värskendav tuulepuhang +Comment[eu]=Haize-bolada freskoa +Comment[fa]=نفسی از هوای تازه +Comment[fi]=Raikkaan ilman leyhähdys +Comment[fr]=Un souffle d'air frais +Comment[fy]=it sykheljen yn de frisse lucht +Comment[ga]=Béalán den aer cumhra +Comment[gl]=Un folgo de ar fresco +Comment[gu]=તાજી હવાનો અનુભવ +Comment[he]=נשימה של אוויר רענן +Comment[hi]=ताजी हवा का झोंका +Comment[hr]=Dašak svježeg zraka +Comment[hu]=Friss fuvallat +Comment[ia]=Un respiration de aere fresc +Comment[id]=Tarikan nafas udara segar +Comment[is]=Ferskir vindar +Comment[ja]=新鮮な空気 +Comment[kk]=Самал желдей жеңіл +Comment[km]=ខ្យល់ដង្ហើម​បរិសុទ្ធ +Comment[kn]=ಸ್ವಚ್ಛ ಗಾಳಿಯ ಶ್ವಾಸ +Comment[ko]=신선한 바람 +Comment[lt]=Gryno oro gurkšnis +Comment[lv]=Svaiga gaisa elpa +Comment[mai]=ताजा हवाक झौंका +Comment[mk]=Здив од свеж воздух +Comment[ml]=ശുദ്ധവായുവിന്റെ ഒരിളംകാറ്റ് +Comment[mr]=शुद्ध हवेचा श्वास +Comment[nb]=Et pust av frisk luft +Comment[nds]=Wat frische Luft +Comment[nl]=Een hap frisse lucht +Comment[nn]=Eit friskt pust +Comment[pa]=ਤਾਜ਼ਾ ਹਵਾ ਵਿੱਚ ਸਾਹ ਲਵੋ +Comment[pl]=Powiew świeżego powietrza +Comment[pt]=Uma brisa de ar fresco +Comment[pt_BR]=Uma brisa de ar fresco +Comment[ro]=O gură de aer proaspăt +Comment[ru]=Волшебные пузырьки +Comment[si]=නැවුමෙ වාතය සමඟ ආශ්වාසයක් +Comment[sk]=Závan čerstvého vzduchu +Comment[sl]=Svež vetrič +Comment[sr]=Дашак свежег ваздуха +Comment[sr@ijekavian]=Дашак свјежег ваздуха +Comment[sr@ijekavianlatin]=Dašak svježeg vazduha +Comment[sr@latin]=Dašak svežeg vazduha +Comment[sv]=Ett friskt andetag +Comment[tg]=Нафаскашии ҳавои тоза +Comment[th]=ลมหายใจของอากาศบริสุทธิ์ +Comment[tr]=Temiz havadan bir nefes +Comment[ug]=ساپ ھاۋادىن نەپەسلىنىش +Comment[uk]=Ковток свіжого повітря +Comment[wa]=On shofla d' frisse air +Comment[x-test]=xxA breath of fresh airxx +Comment[zh_CN]=呼吸清新空气 +Comment[zh_TW]=吸一口新鮮空氣 + + +X-KDE-PluginInfo-Author=The Oxygen Project +X-KDE-PluginInfo-Email=kde-artists@kde.org +X-KDE-PluginInfo-Name=air-netbook +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +[Settings] +FallbackTheme=default diff --git a/plasma/netbook/desktoptheme/air-netbook/widgets/background.svgz b/plasma/netbook/desktoptheme/air-netbook/widgets/background.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3bb14aed7af7f248c34871fcd6828834c2d37f7a GIT binary patch literal 5988 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 literal 0 HcmV?d00001 diff --git a/plasma/netbook/desktoptheme/air-netbook/widgets/panel-background.svgz b/plasma/netbook/desktoptheme/air-netbook/widgets/panel-background.svgz new file mode 100644 index 0000000000000000000000000000000000000000..209e5253b317153c6954b797f04dd44cd6b5a9dd GIT binary patch literal 9421 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 + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include "plasmaapp.h" + +static const char description[] = I18N_NOOP( "The KDE workspace application optimized for Netbook devices." ); +static const char version[] = "0.2"; + +extern "C" +KDE_EXPORT int kdemain(int argc, char **argv) +{ + KAboutData aboutData("plasma-netbook", 0, ki18n("Plasma Netbook Shell"), + version, ki18n(description), KAboutData::License_GPL, + ki18n("Copyright 2006-2009, The KDE Team")); + aboutData.addAuthor(ki18n("Aaron J. Seigo"), + ki18n("Author and maintainer"), + "aseigo@kde.org"); + + + bool customGraphicsSystem = false; + for (int i = 0; i < argc; ++i) { + if (QString(argv[i]) == "-graphicssystem") { + customGraphicsSystem = true; + break; + } + } + + if (!customGraphicsSystem) { + KConfigGroup cg(KSharedConfig::openConfig("plasma-netbookrc"), "General"); + QApplication::setGraphicsSystem(cg.readEntry("GraphicsSystem", "native")); + } + + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("nodesktop", ki18n("Starts as a normal application instead of as the primary user interface")); + options.add("opengl", ki18n("Use OpenGL to draw the main screen")); + options.add("screen ", ki18n("The geometry of the screen"), "800x480"); + KCmdLineArgs::addCmdLineOptions(options); + + PlasmaApp *app = PlasmaApp::self(); + QApplication::setWindowIcon(KIcon("plasma")); + app->disableSessionManagement(); // autostarted + int rc = app->exec(); + delete app; + return rc; +} + diff --git a/plasma/netbook/shell/netcorona.cpp b/plasma/netbook/shell/netcorona.cpp new file mode 100644 index 00000000..47a2f1fd --- /dev/null +++ b/plasma/netbook/shell/netcorona.cpp @@ -0,0 +1,234 @@ +/* + * Copyright 2008 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netcorona.h" +#include "netdialogmanager.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "plasmaapp.h" +#include "netview.h" +#include +#include + +NetCorona::NetCorona(QObject *parent) + : Plasma::Corona(parent) +{ + init(); +} + +void NetCorona::init() +{ + setPreferredToolBoxPlugin(Plasma::Containment::DesktopContainment, "org.kde.nettoolbox"); + QDesktopWidget *desktop = QApplication::desktop(); + QObject::connect(desktop, SIGNAL(resized(int)), this, SLOT(screenResized(int))); + connect(PlasmaApp::self(), SIGNAL(controlBarChanged()), this, SIGNAL(availableScreenRegionChanged())); + + connect(this, SIGNAL(containmentAdded(Plasma::Containment*)), this, SLOT(containmentAdded(Plasma::Containment*))); + + Plasma::ContainmentActionsPluginsConfig desktopPlugins; + desktopPlugins.addPlugin(Qt::NoModifier, Qt::MidButton, "paste"); + desktopPlugins.addPlugin(Qt::NoModifier, Qt::RightButton, "contextmenu"); + Plasma::ContainmentActionsPluginsConfig panelPlugins; + panelPlugins.addPlugin(Qt::NoModifier, Qt::RightButton, "contextmenu"); + + setContainmentActionsDefaults(Plasma::Containment::DesktopContainment, desktopPlugins); + setContainmentActionsDefaults(Plasma::Containment::CustomContainment, desktopPlugins); + setContainmentActionsDefaults(Plasma::Containment::PanelContainment, panelPlugins); + setContainmentActionsDefaults(Plasma::Containment::CustomPanelContainment, panelPlugins); + + setDialogManager(new NetDialogManager(this)); + + QAction *a = new QAction(KIcon("view-pim-news"), i18n("Add page"), this); + addAction("add page", a); + connect(a, SIGNAL(triggered()), this, SLOT(addPage())); + + //we have a page-level lock action + a = action("lock widgets"); + delete a; + setImmutability(Plasma::Mutable); + setDefaultContainmentPlugin("newspaper"); +} + +void NetCorona::loadDefaultLayout() +{ + evaluateScripts(WorkspaceScripting::NetbookScriptEngine::defaultLayoutScripts()); + if (!containments().isEmpty()) { + return; + } + + QString defaultConfig = KStandardDirs::locate("appdata", "plasma-default-layoutrc"); + if (!defaultConfig.isEmpty()) { + kDebug() << "attempting to load the default layout from:" << defaultConfig; + + // gcc bug 36490: KConfig's copy constructor is private, so passing it as a + // temporary to importLayout, ie importLayout(KConfig(defaultConfig)) fails + // on gcc < 4.3.0 + KConfig c(defaultConfig); + importLayout(c.group(QByteArray())); + + return; + } +} + +Plasma::Applet *NetCorona::loadDefaultApplet(const QString &pluginName, Plasma::Containment *c) +{ + QVariantList args; + Plasma::Applet *applet = Plasma::Applet::load(pluginName, 0, args); + + if (applet) { + c->addApplet(applet); + } + + return applet; +} + +void NetCorona::addPage() +{ + //count the pages + int numPages = 0; + foreach (Plasma::Containment *containment, containments()) { + if (containment->location() == Plasma::Floating) { + ++numPages; + } + } + + Plasma::Containment *cont = addContainment(QString()); + if (!cont) { + //it may fail, for instance when widgets are locked + return; + } + + cont->setActivity(i18nc("Page number", "Page %1", numPages)); + cont->setScreen(0); + cont->setToolBoxOpen(true); +} + +void NetCorona::containmentAdded(Plasma::Containment *cont) +{ + if (cont->pluginName() == "sal") { + QAction *a = cont->action("remove"); + cont->removeAction(a); + delete a; + } + + foreach (QAction *action, actions()) { + cont->addToolBoxAction(action); + } +} + +Plasma::Containment *NetCorona::findFreeContainment() const +{ + foreach (Plasma::Containment *cont, containments()) { + if ((cont->containmentType() == Plasma::Containment::DesktopContainment || + cont->containmentType() == Plasma::Containment::CustomContainment) && + cont->screen() == -1 && !offscreenWidgets().contains(cont)) { + return cont; + } + } + + return 0; +} + +void NetCorona::screenResized(int screen) +{ + int numScreens = QApplication::desktop()->numScreens(); + if (screen < numScreens) { + foreach (Plasma::Containment *c, containments()) { + if (c->screen() == screen) { + // trigger a relayout + c->setScreen(screen); + } + } + } +} + +int NetCorona::numScreens() const +{ + return Kephal::ScreenUtils::numScreens(); +} + +QRect NetCorona::screenGeometry(int id) const +{ + return PlasmaApp::self()->mainView()->geometry(); +} + +QRegion NetCorona::availableScreenRegion(int id) const +{ + QRegion r(screenGeometry(id)); + NetView *view = PlasmaApp::self()->controlBar(); + if (view) { + r = r.subtracted(view->geometry()); + } + QWidget *explorer = PlasmaApp::self()->widgetExplorer(); + if (explorer) { + r = r.subtracted(explorer->geometry()); + } + + return r; +} + +void NetCorona::processUpdateScripts() +{ + evaluateScripts(WorkspaceScripting::NetbookScriptEngine::pendingUpdateScripts()); +} + +void NetCorona::evaluateScripts(const QStringList &scripts) +{ + foreach (const QString &script, scripts) { + WorkspaceScripting::NetbookScriptEngine scriptEngine(this); + connect(&scriptEngine, SIGNAL(printError(QString)), this, SLOT(printScriptError(QString))); + connect(&scriptEngine, SIGNAL(print(QString)), this, SLOT(printScriptMessage(QString))); + connect(&scriptEngine, SIGNAL(createPendingPanelViews()), PlasmaApp::self(), SLOT(createWaitingPanels())); + + QFile file(script); + if (file.open(QIODevice::ReadOnly | QIODevice::Text) ) { + QString code = file.readAll(); + kDebug() << "evaluating startup script:" << script; + scriptEngine.evaluateScript(code); + } + } +} + +void NetCorona::printScriptError(const QString &error) +{ + kWarning() << "Startup script errror:" << error; +} + +void NetCorona::printScriptMessage(const QString &error) +{ + kDebug() << "Startup script: " << error; +} + + +#include "netcorona.moc" + diff --git a/plasma/netbook/shell/netcorona.h b/plasma/netbook/shell/netcorona.h new file mode 100644 index 00000000..dc90b389 --- /dev/null +++ b/plasma/netbook/shell/netcorona.h @@ -0,0 +1,73 @@ +/* + * Copyright 2008 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETVCORONA_H +#define NETVCORONA_H + +#include + +#include + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +/** + * @short A Corona with desktop-y considerations + */ +class NetCorona : public Plasma::Corona +{ + Q_OBJECT + +public: + NetCorona(QObject * parent); + + /** + * Loads the default (system wide) layout for this user + **/ + void loadDefaultLayout(); + + Plasma::Containment *findFreeContainment() const; + + bool loadDefaultLayoutScripts(); + void processUpdateScripts(); + + virtual int numScreens() const; + virtual QRect screenGeometry(int id) const; + virtual QRegion availableScreenRegion(int id) const; + +protected Q_SLOTS: + void screenResized(int); + void evaluateScripts(const QStringList &scripts); + void printScriptError(const QString &error); + void printScriptMessage(const QString &error); + void containmentAdded(Plasma::Containment *cont); + void addPage(); + +private: + void init(); + Plasma::Applet *loadDefaultApplet(const QString &pluginName, Plasma::Containment *c); + + int m_numScreens; +}; + +#endif + + diff --git a/plasma/netbook/shell/netdialogmanager.cpp b/plasma/netbook/shell/netdialogmanager.cpp new file mode 100644 index 00000000..b3ba99d0 --- /dev/null +++ b/plasma/netbook/shell/netdialogmanager.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netdialogmanager.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +NetDialogManager::NetDialogManager(Plasma::Corona *parent) + : Plasma::AbstractDialogManager(parent), + m_corona(parent) +{ +} + +NetDialogManager::~NetDialogManager() +{ +} + +void NetDialogManager::showDialog(QWidget *widget, Plasma::Applet *applet) +{ + Q_UNUSED(applet) + if (KWindowSystem::compositingActive()) { + widget->setAttribute(Qt::WA_WindowPropagation, false); + widget->setAttribute(Qt::WA_TranslucentBackground); + widget->setAttribute(Qt::WA_NoSystemBackground, false); + widget->setWindowFlags(Qt::FramelessWindowHint); + KWindowSystem::setState(widget->effectiveWinId(), NET::MaxVert|NET::MaxHoriz); + Plasma::WindowEffects::enableBlurBehind(widget->effectiveWinId(), true); + + QPalette palette = widget->palette(); + palette.setColor(QPalette::Window, QColor(0,0,0,100)); + widget->setAttribute(Qt::WA_WindowPropagation); + palette.setColor(QPalette::WindowText, Qt::white); + palette.setColor(QPalette::ToolTipText, Qt::white); + widget->setPalette(palette); + } + + Plasma::Containment *containment = applet->containment(); + if (containment) { + Plasma::Corona *corona = containment->corona(); + if (corona) { + QRect r = corona->availableScreenRegion(containment->screen()).boundingRect(); + //assumption: the panel is 100% wide + QRect screenRect = corona->screenGeometry(containment->screen()); + + widget->setContentsMargins(r.left() - screenRect.left(), + r.top() - screenRect.top(), + screenRect.right() - r.right(), + screenRect.bottom() - r.bottom()); + } + } + + widget->show(); +} + + +#include "netdialogmanager.moc" diff --git a/plasma/netbook/shell/netdialogmanager.h b/plasma/netbook/shell/netdialogmanager.h new file mode 100644 index 00000000..d117f880 --- /dev/null +++ b/plasma/netbook/shell/netdialogmanager.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NET_DIALOGMANAGER_H +#define NET_DIALOGMANAGER_H + +#include + +#include + + +namespace Plasma +{ + class Corona; +} + +class NetDialogManager : public Plasma::AbstractDialogManager +{ + Q_OBJECT + +public: + explicit NetDialogManager(Plasma::Corona *parent=0); + ~NetDialogManager(); + +public Q_SLOTS: + void showDialog(QWidget *widget, Plasma::Applet *applet); + +private: + Plasma::Corona *m_corona; +}; + +#endif diff --git a/plasma/netbook/shell/netpanelcontroller.cpp b/plasma/netbook/shell/netpanelcontroller.cpp new file mode 100644 index 00000000..c647d7b6 --- /dev/null +++ b/plasma/netbook/shell/netpanelcontroller.cpp @@ -0,0 +1,255 @@ +/* + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netpanelcontroller.h" +#include "netview.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +NetPanelController::NetPanelController(QWidget *parent, NetView *view, Plasma::Containment *containment) + : Plasma::Dialog(parent), + m_containment(containment), + m_view(view), + m_watched(0) +{ + hide(); + + m_mainWidget = new QGraphicsWidget(containment); + if (containment && containment->corona()) { + containment->corona()->addOffscreenWidget(m_mainWidget); + } + + m_layout = new QGraphicsLinearLayout(Qt::Horizontal, m_mainWidget); + + m_iconSvg = new Plasma::Svg(this); + m_iconSvg->setImagePath("widgets/configuration-icons"); + m_iconSvg->setContainsMultipleImages(true); + m_iconSvg->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall); + + m_moveButton = new Plasma::ToolButton(m_mainWidget); + m_moveButton->nativeWidget()->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_moveButton->setIcon(m_iconSvg->pixmap("move")); + m_moveButton->setText(i18n("Screen edge")); + m_moveButton->setCursor(Qt::SizeAllCursor); + m_layout->addItem(m_moveButton); + + m_resizeButton = new Plasma::ToolButton(m_mainWidget); + m_resizeButton->nativeWidget()->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_resizeButton->setIcon(m_iconSvg->pixmap("size-vertical")); + m_resizeButton->setText(i18n("Height")); + m_layout->addItem(m_resizeButton); + + m_autoHideButton = new Plasma::ToolButton(m_mainWidget); + m_autoHideButton->nativeWidget()->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_autoHideButton->nativeWidget()->setCheckable(true); + m_autoHideButton->setIcon(m_iconSvg->pixmap("collapse")); + m_autoHideButton->setText(i18n("Auto Hide")); + m_layout->addItem(m_autoHideButton); + m_autoHideButton->nativeWidget()->setChecked(view->autoHide()); + connect(m_autoHideButton->nativeWidget(), SIGNAL(toggled(bool)), view, SLOT(setAutoHide(bool))); + connect(containment, SIGNAL(geometryChanged()), this, SLOT(updatePosition())); + + m_moveButton->installEventFilter(this); + m_resizeButton->installEventFilter(this); + setGraphicsWidget(m_mainWidget); + layout()->activate(); + m_layout->activate(); + m_mainWidget->resize(m_mainWidget->effectiveSizeHint(Qt::PreferredSize)); + updatePosition(); + show(); + Plasma::WindowEffects::slideWindow(this, containment->location()); + KWindowSystem::setState(winId(), NET::KeepAbove|NET::StaysOnTop); +} + +NetPanelController::~NetPanelController() +{ + Plasma::WindowEffects::slideWindow(this, m_containment->location()); +} + +void NetPanelController::updatePosition() +{ + QRect viewGeometry(m_view->geometry()); + switch (m_containment->location()) { + case Plasma::LeftEdge: + move(viewGeometry.right(), viewGeometry.center().y() - size().height()/2); + break; + case Plasma::RightEdge: + move(viewGeometry.left() - size().width(), viewGeometry.center().y() - size().height()/2); + break; + case Plasma::TopEdge: + move(viewGeometry.center().x() - size().width()/2, viewGeometry.bottom()); + break; + case Plasma::BottomEdge: + move(viewGeometry.center().x() - size().width()/2, viewGeometry.top() - size().height()); + break; + default: + break; + } + + updateFormFactor(); +} + +void NetPanelController::updateFormFactor() +{ + QRect viewGeometry(m_view->geometry()); + switch (m_containment->location()) { + case Plasma::LeftEdge: + case Plasma::RightEdge: + m_layout->setOrientation(Qt::Vertical); + m_resizeButton->setIcon(m_iconSvg->pixmap("size-horizontal")); + m_resizeButton->setText(i18n("Width")); + m_resizeButton->setCursor(Qt::SizeHorCursor); + break; + case Plasma::TopEdge: + case Plasma::BottomEdge: + m_layout->setOrientation(Qt::Horizontal); + m_resizeButton->setIcon(m_iconSvg->pixmap("size-vertical")); + m_resizeButton->setText(i18n("Height")); + m_resizeButton->setCursor(Qt::SizeVerCursor); + break; + default: + break; + } +} + +void NetPanelController::resizeEvent(QResizeEvent *e) +{ + updatePosition(); + Plasma::Dialog::resizeEvent(e); +} + +bool NetPanelController::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::GraphicsSceneMousePress) { + m_watched = qobject_cast(watched); + } else if (event->type() == QEvent::GraphicsSceneMouseRelease) { + m_watched = 0; + } else if (watched == m_moveButton && event->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *me = static_cast(event); + QRect screenGeom = Kephal::ScreenUtils::screenGeometry(m_containment->screen()); + + //only move when the mouse cursor is out of the controller to avoid an endless reposition cycle + if (geometry().contains(me->screenPos())) { + return false; + } + + if (!screenGeom.contains(me->screenPos())) { + //move panel to new screen if dragged there + int targetScreen = Kephal::ScreenUtils::screenId(me->screenPos()); + //kDebug() << "Moving panel from screen" << containment()->screen() << "to screen" << targetScreen; + m_containment->setScreen(targetScreen); + return false; + } + + //create a dead zone so you can go across the middle without having it hop to one side + float dzFactor = 0.35; + QPoint offset = QPoint(screenGeom.width()*dzFactor,screenGeom.height()*dzFactor); + QRect deadzone = QRect(screenGeom.topLeft()+offset, screenGeom.bottomRight()-offset); + if (deadzone.contains(me->screenPos())) { + //kDebug() << "In the deadzone:" << deadzone; + return false; + } + + const Plasma::Location oldLocation = m_containment->location(); + Plasma::Location newLocation = oldLocation; + float screenAspect = float(screenGeom.height())/screenGeom.width(); + + /* Use diagonal lines so we get predictable behavior when moving the panel + * y=topleft.y+(x-topleft.x)*aspectratio topright < bottomleft + * y=bottomleft.y-(x-topleft.x)*aspectratio topleft < bottomright + */ + if (me->screenPos().y() < screenGeom.y()+(me->screenPos().x()-screenGeom.x())*screenAspect) { + if (me->screenPos().y() < screenGeom.bottomLeft().y()-(me->screenPos().x()-screenGeom.x())*screenAspect) { + if (m_containment->location() == Plasma::TopEdge) { + return false; + } else { + newLocation = Plasma::TopEdge; + } + } else if (m_containment->location() == Plasma::RightEdge) { + return false; + } else { + newLocation = Plasma::RightEdge; + } + } else { + if (me->screenPos().y() < screenGeom.bottomLeft().y()-(me->screenPos().x()-screenGeom.x())*screenAspect) { + if (m_containment->location() == Plasma::LeftEdge) { + return false; + } else { + newLocation = Plasma::LeftEdge; + } + } else if(m_containment->location() == Plasma::BottomEdge) { + return false; + } else { + newLocation = Plasma::BottomEdge; + } + } + + m_containment->setLocation(newLocation); + + } else if (watched == m_resizeButton && event->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *me = static_cast(event); + QPointF deltaPos(me->screenPos() - me->lastScreenPos()); + + m_containment->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + + switch (m_containment->location()) { + case Plasma::LeftEdge: + + m_containment->setMinimumWidth(qBound((qreal)KIconLoader::SizeSmall, m_containment->size().width() + deltaPos.x(), (qreal)(KIconLoader::SizeEnormous*2))); + m_containment->setMaximumWidth(m_containment->minimumWidth()); + + break; + case Plasma::RightEdge: + + m_containment->setMinimumWidth(qBound((qreal)KIconLoader::SizeSmall, m_containment->size().width() - deltaPos.x(), (qreal)(KIconLoader::SizeEnormous*2))); + m_containment->setMaximumWidth(m_containment->minimumWidth()); + break; + case Plasma::TopEdge: + + m_containment->setMinimumHeight(qBound((qreal)KIconLoader::SizeSmall, m_containment->size().height() + deltaPos.y(), (qreal)(KIconLoader::SizeEnormous*2))); + m_containment->setMaximumHeight(m_containment->minimumHeight()); + break; + case Plasma::BottomEdge: + + m_containment->setMinimumHeight(qBound((qreal)KIconLoader::SizeSmall, m_containment->size().height() - deltaPos.y(), (qreal)(KIconLoader::SizeEnormous*2))); + m_containment->setMaximumHeight(m_containment->minimumHeight()); + break; + default: + break; + } + } + return Plasma::Dialog::eventFilter(watched, event); +} + +#include "netpanelcontroller.moc" diff --git a/plasma/netbook/shell/netpanelcontroller.h b/plasma/netbook/shell/netpanelcontroller.h new file mode 100644 index 00000000..7fcfec6f --- /dev/null +++ b/plasma/netbook/shell/netpanelcontroller.h @@ -0,0 +1,65 @@ +/* + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETPANELCONTROLLER_H +#define NETPANELCONTROLLER_H + +#include + +namespace Plasma +{ + class Containment; + class ToolButton; + class Svg; + class View; +} + +class QGraphicsWidget; +class QGraphicsLinearLayout; + +class NetView; + +class NetPanelController : public Plasma::Dialog +{ + Q_OBJECT +public: + NetPanelController(QWidget *parent = 0, NetView *view = 0, Plasma::Containment *containment = 0); + ~NetPanelController(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + void updateFormFactor(); + void resizeEvent(QResizeEvent *e); + +private Q_SLOTS: + void updatePosition(); + +private: + Plasma::Containment *m_containment; + Plasma::View *m_view; + QGraphicsWidget *m_mainWidget; + QGraphicsLinearLayout *m_layout; + Plasma::ToolButton *m_moveButton; + Plasma::ToolButton *m_resizeButton; + Plasma::ToolButton *m_autoHideButton; + Plasma::ToolButton *m_watched; + Plasma::Svg *m_iconSvg; +}; + +#endif diff --git a/plasma/netbook/shell/nettoolbox/CMakeLists.txt b/plasma/netbook/shell/nettoolbox/CMakeLists.txt new file mode 100644 index 00000000..74c3c30a --- /dev/null +++ b/plasma/netbook/shell/nettoolbox/CMakeLists.txt @@ -0,0 +1,15 @@ +project(plasma-nettoolbox) + + +set(nettoolbox_SRCS nettoolbox.cpp) + + +kde4_add_plugin(plasma_toolbox_nettoolbox ${nettoolbox_SRCS}) +target_link_libraries(plasma_toolbox_nettoolbox + ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS}) + +install(TARGETS plasma_toolbox_nettoolbox + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-toolbox-nettoolbox.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/plasma/netbook/shell/nettoolbox/Messages.sh b/plasma/netbook/shell/nettoolbox/Messages.sh new file mode 100644 index 00000000..f3a944ea --- /dev/null +++ b/plasma/netbook/shell/nettoolbox/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_toolbox_nettoolbox.pot diff --git a/plasma/netbook/shell/nettoolbox/nettoolbox.cpp b/plasma/netbook/shell/nettoolbox/nettoolbox.cpp new file mode 100644 index 00000000..0f096808 --- /dev/null +++ b/plasma/netbook/shell/nettoolbox/nettoolbox.cpp @@ -0,0 +1,566 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "nettoolbox.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + + +class ToolContainer : public QGraphicsWidget +{ +public: + ToolContainer(QGraphicsWidget *parent) + : QGraphicsWidget(parent) + { + m_itemBackground = new Plasma::ItemBackground(this); + m_itemBackground->hide(); + + m_background = new Plasma::FrameSvg(this); + m_background->setImagePath("widgets/frame"); + m_background->setElementPrefix("raised"); + setLocation(Plasma::BottomEdge); + setAcceptHoverEvents(true); + } + + ~ToolContainer() + { + } + + void setLocation(Plasma::Location location) + { + m_location = location; + switch (location) { + case Plasma::TopEdge: + m_background->setEnabledBorders(Plasma::FrameSvg::BottomBorder); + break; + case Plasma::BottomEdge: + m_background->setEnabledBorders(Plasma::FrameSvg::TopBorder); + break; + case Plasma::LeftEdge: + m_background->setEnabledBorders(Plasma::FrameSvg::RightBorder); + break; + case Plasma::RightEdge: + m_background->setEnabledBorders(Plasma::FrameSvg::LeftBorder); + break; + default: + m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders); + break; + } + qreal left, top, right, bottom; + m_background->getMargins(left, top, right, bottom); + setContentsMargins(left, top, right, bottom); + } + + Plasma::ItemBackground *itemBackground() const + { + return m_itemBackground; + } + + Plasma::Location location() const + { + return m_location; + } + + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) + { + event->accept(); + } + + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) + { + Q_UNUSED(event); + m_itemBackground->hide(); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option) + Q_UNUSED(widget) + + m_background->paintFrame(painter); + } + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event) + { + m_background->resizeFrame(event->newSize()); + } + + void mousePressEvent(QGraphicsSceneMouseEvent *event) + { + event->accept(); + } + + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const + { + QSizeF hint = QGraphicsWidget::sizeHint(which, constraint); + + if (which == Qt::PreferredSize) { + qreal left, top, right, bottom; + m_itemBackground->getContentsMargins(&left, &top, &right, &bottom); + + if (m_location == Plasma::TopEdge) { + hint.setHeight(KIconLoader::SizeSmallMedium + m_background->marginSize(Plasma::BottomMargin) + top + bottom); + } else if (m_location == Plasma::BottomEdge) { + hint.setHeight(KIconLoader::SizeSmallMedium + m_background->marginSize(Plasma::TopMargin) + top + bottom); + } + } + + return hint; + } + + bool eventFilter(QObject *watched, QEvent *event) + { + Plasma::IconWidget *icon = qobject_cast(watched); + if (icon) { + if (event->type() == QEvent::GraphicsSceneHoverEnter) { + m_itemBackground->setTargetItem(icon); + } else if (event->type() == QEvent::Show) { + //force the newly shown icon to have a sensible size + icon->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + layout()->invalidate(); + } else if (event->type() == QEvent::Hide) { + if (m_location == Plasma::TopEdge || m_location == Plasma::BottomEdge) { + icon->setMaximumWidth(0); + } else { + icon->setMaximumHeight(0); + } + layout()->invalidate(); + } + } + return false; + } + + +private: + Plasma::FrameSvg *m_background; + Plasma::ItemBackground *m_itemBackground; + Plasma::Location m_location; +}; + +NetToolBox::NetToolBox(Plasma::Containment *parent) + : Plasma::AbstractToolBox(parent) +{ + init(); +} + +NetToolBox::NetToolBox(QObject *parent, const QVariantList &args) + : AbstractToolBox(parent, args) +{ + init(); +} + +NetToolBox::~NetToolBox() +{ +} + +void NetToolBox::init() +{ + m_containment = containment(); + Q_ASSERT(m_containment); + + m_icon = KIcon("plasma"); + m_closeIcon = KIcon("dialog-close"); + m_iconSize = QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall); + m_animHighlightFrame = 0; + m_hovering = false; + m_showing = false; + m_location = Plasma::BottomEdge; + m_newToolsPosition = 0; + + setZValue(9000); + resize(KIconLoader::SizeMedium, KIconLoader::SizeMedium); + setAcceptHoverEvents(true); + + m_toolContainer = new ToolContainer(this); + m_toolContainer->hide(); + m_toolContainer->setFlag(QGraphicsWidget::ItemStacksBehindParent); + m_toolContainerLayout = new QGraphicsLinearLayout(m_toolContainer); + m_toolContainerLayout->addStretch(); + + m_background = new Plasma::Svg(this); + m_background->setImagePath("widgets/toolbox"); + m_background->setContainsMultipleImages(true); + setLocation(Plasma::BottomEdge); + + m_containment->installEventFilter(this); + connect(m_containment, SIGNAL(geometryChanged()), this, SLOT(containmentGeometryChanged())); + containmentGeometryChanged(); + + slideAnim = Plasma::Animator::create(Plasma::Animator::SlideAnimation, this); + slideAnim->setProperty("movementDirection", Plasma::Animation::MoveAny); + connect(slideAnim, SIGNAL(stateChanged(QAbstractAnimation::State, + QAbstractAnimation::State)), + this, SLOT(onMovement(QAbstractAnimation::State,QAbstractAnimation::State))); + connect(slideAnim, SIGNAL(finished()), this, SLOT(movementFinished())); + + anim = new QPropertyAnimation(this, "highlight", this); + anim->setDuration(250); + anim->setStartValue(0); + anim->setEndValue(1); +} + +bool NetToolBox::isShowing() const +{ + return m_showing; +} + +void NetToolBox::setShowing(const bool show) +{ + m_showing = show; + if (show != m_toolContainer->isVisible()) { + emit toggled(); + emit visibilityChanged(show); + } + + if (show) { + qreal left, top, right, bottom = 0; + + switch (m_location) { + case Plasma::TopEdge: + m_toolContainer->setPos(boundingRect().topLeft() - QPoint(0, m_toolContainer->size().height())); + slideAnim->setProperty("distancePointF", QPointF(0, m_toolContainer->size().height())); + top = m_toolContainer->size().height(); + break; + case Plasma::LeftEdge: + m_toolContainer->setPos(boundingRect().topLeft() - QPoint(m_toolContainer->size().width(), 0)); + slideAnim->setProperty("distancePointF", QPointF(m_toolContainer->size().width(), 0)); + left = m_toolContainer->size().width(); + break; + case Plasma::RightEdge: + m_toolContainer->setPos(boundingRect().topRight()); + slideAnim->setProperty("distancePointF", QPointF(-m_toolContainer->size().width(), 0)); + right = m_toolContainer->size().width(); + break; + case Plasma::BottomEdge: + default: + m_toolContainer->setPos(boundingRect().bottomLeft()); + slideAnim->setProperty("distancePointF", QPointF(0, -m_toolContainer->size().height())); + bottom = m_toolContainer->size().height(); + break; + } + + slideAnim->setTargetWidget(m_toolContainer); + slideAnim->setDirection(QAbstractAnimation::Forward); + slideAnim->start(); + + if (m_containment->layout()) { + m_containment->layout()->setContentsMargins(left, top, right, bottom); + } + + } else { + slideAnim->setDirection(QAbstractAnimation::Backward); + slideAnim->start(); + + if (m_containment->layout()) { + m_containment->layout()->setContentsMargins(0, 0, 0, 0); + } + } +} + + +void NetToolBox::addTool(QAction *action) +{ + Plasma::IconWidget *button = new Plasma::IconWidget(this); + button->setOrientation(Qt::Horizontal); + button->setTextBackgroundColor(QColor()); + button->installEventFilter(m_toolContainer); + button->setAction(action); + + qreal left, top, right, bottom; + m_toolContainer->itemBackground()->getContentsMargins(&left, &top, &right, &bottom); + button->setContentsMargins(left, top, right, bottom); + + if (m_location == Plasma::LeftEdge || m_location == Plasma::RightEdge) { + button->setOrientation(Qt::Vertical); + } else { + button->setOrientation(Qt::Horizontal); + } + + m_actionButtons[action] = button; + + if (action == m_containment->action("remove")) { + m_toolContainerLayout->addItem(button); + --m_newToolsPosition; + } else if (action == m_containment->action("add page")) { + m_toolContainerLayout->insertItem(m_newToolsPosition+1, button); + --m_newToolsPosition; + } else if (action == m_containment->action("add applications")) { + m_toolContainerLayout->insertItem(1, button); + --m_newToolsPosition; + } else { + m_toolContainerLayout->insertItem(m_newToolsPosition, button); + } + ++m_newToolsPosition; + + if (m_toolContainerLayout->count() == 1) { + m_toolContainer->itemBackground()->setTargetItem(button); + } +} + +void NetToolBox::removeTool(QAction *action) +{ + if (m_actionButtons.contains(action)) { + Plasma::IconWidget *button = m_actionButtons.value(action); + m_toolContainerLayout->removeItem(button); + m_actionButtons.remove(action); + button->deleteLater(); + if (action != m_containment->action("remove") || + action != m_containment->action("add page")) { + --m_newToolsPosition; + } + } +} + +QRectF NetToolBox::expandedGeometry() const +{ + QRectF containerGeometry = m_toolContainer->boundingRect(); + containerGeometry.moveBottomLeft(geometry().bottomLeft()); + return containerGeometry; +} + +void NetToolBox::setLocation(Plasma::Location location) +{ + m_location = location; + m_toolContainer->setLocation(location); + if (location == Plasma::LeftEdge || location == Plasma::RightEdge) { + m_toolContainerLayout->setOrientation(Qt::Vertical); + m_toolContainerLayout->setContentsMargins(0, size().height(), 0, 0); + foreach (Plasma::IconWidget *icon, m_actionButtons) { + icon->setOrientation(Qt::Vertical); + } + } else { + m_toolContainerLayout->setOrientation(Qt::Horizontal); + m_toolContainerLayout->setContentsMargins(size().width(), 0, 0, 0); + foreach (Plasma::IconWidget *icon, m_actionButtons) { + icon->setOrientation(Qt::Horizontal); + } + } + containmentGeometryChanged(); +} + +Plasma::Location NetToolBox::location() const +{ + return m_location; +} + +void NetToolBox::containmentGeometryChanged() +{ + m_toolContainerLayout->invalidate(); + m_toolContainerLayout->activate(); + + switch (m_location) { + case Plasma::TopEdge: + m_toolContainer->resize(m_containment->size().width(), m_toolContainer->effectiveSizeHint(Qt::PreferredSize).height()); + m_toolContainer->setPos(0, 0); + setPos(m_containment->contentsRect().topLeft()); + break; + case Plasma::BottomEdge: + m_toolContainer->resize(m_containment->size().width(), m_toolContainer->effectiveSizeHint(Qt::PreferredSize).height()); + m_toolContainer->setPos(0, size().height()-m_toolContainer->size().height()); + setPos(m_containment->contentsRect().left(), m_containment->contentsRect().bottom()-size().height()+1); + break; + case Plasma::LeftEdge: + m_toolContainer->resize(m_toolContainer->effectiveSizeHint(Qt::PreferredSize).width(), m_containment->size().height()); + m_toolContainer->setPos(0, 0); + setPos(m_containment->contentsRect().topLeft()); + break; + case Plasma::RightEdge: + m_toolContainer->resize(m_toolContainer->effectiveSizeHint(Qt::PreferredSize).width(), m_containment->size().height()); + m_toolContainer->setPos(size().width()-m_toolContainer->size().width(), 0); + setPos(m_containment->contentsRect().right()-size().width()+1, m_containment->contentsRect().top()); + break; + default: + m_toolContainer->resize(m_toolContainer->effectiveSizeHint(Qt::PreferredSize)); + m_toolContainer->setPos(m_containment->contentsRect().left(), size().height()-m_toolContainer->size().height()); + break; + } +} + +void NetToolBox::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->accept(); +} + +void NetToolBox::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) + setShowing(!isShowing()); +} + +void NetToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + QPoint iconPos; + QString svgElement; + + switch (m_location) { + case Plasma::TopEdge: + case Plasma::LeftEdge: + iconPos = QPoint(2, 2); + svgElement = "desktop-northwest"; + break; + case Plasma::RightEdge: + iconPos = QPoint(size().width() - m_iconSize.width() - 2, 2); + svgElement = "desktop-northeast"; + break; + case Plasma::BottomEdge: + default: + iconPos = QPoint(2, size().height() - m_iconSize.height() - 2); + svgElement = "desktop-southwest"; + break; + } + + m_background->paint(painter, boundingRect(), svgElement); + + KIcon icon; + if (isShowing()) { + icon = m_closeIcon; + } else { + icon = m_icon; + } + + if (qFuzzyCompare(qreal(1.0), m_animHighlightFrame)) { + icon.paint(painter, QRect(iconPos, m_iconSize)); + } else if (qFuzzyCompare(qreal(1.0), 1 + m_animHighlightFrame)) { + icon.paint(painter, QRect(iconPos, m_iconSize), + Qt::AlignCenter, QIcon::Disabled, QIcon::Off); + } else { + QPixmap disabled = icon.pixmap(m_iconSize, QIcon::Disabled, QIcon::Off); + QPixmap enabled = icon.pixmap(m_iconSize); + QPixmap result = Plasma::PaintUtils::transition( + icon.pixmap(m_iconSize, QIcon::Disabled, QIcon::Off), + icon.pixmap(m_iconSize), m_animHighlightFrame); + painter->drawPixmap(QRect(iconPos, m_iconSize), result); + } +} + +bool NetToolBox::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == m_containment && event->type() == QEvent::ContentsRectChange) { + qreal left, top, right, bottom; + m_containment->getContentsMargins(&left, &top, &right, &bottom); + + //left preferred over right + if (left > top && left > right && left > bottom) { + setLocation(Plasma::RightEdge); + } else if (right > top && right >= left && right > bottom) { + setLocation(Plasma::LeftEdge); + } else if (bottom > top && bottom > left && bottom > right) { + setLocation(Plasma::TopEdge); + //bottom is the default + } else { + setLocation(Plasma::BottomEdge); + } + } + + return AbstractToolBox::eventFilter(watched, event); +} + +void NetToolBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + if (isShowing() || m_hovering) { + QGraphicsWidget::hoverEnterEvent(event); + return; + } + + highlight(true); + + QGraphicsWidget::hoverEnterEvent(event); +} + +void NetToolBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + //kDebug() << event->pos() << event->scenePos() + // << d->toolBacker->rect().contains(event->scenePos().toPoint()); + if (!m_hovering || isShowing()) { + QGraphicsWidget::hoverLeaveEvent(event); + return; + } + + highlight(false); + + QGraphicsWidget::hoverLeaveEvent(event); +} + +void NetToolBox::highlight(bool highlighting) +{ + if (m_hovering == highlighting) { + return; + } + + m_hovering = highlighting; + + if (anim->state() != QAbstractAnimation::Stopped) { + anim->stop(); + } + + anim->start(); +} + +void NetToolBox::setHighlight(qreal progress) +{ + if (m_hovering) { + m_animHighlightFrame = progress; + } else { + m_animHighlightFrame = 1.0 - progress; + } + + update(); +} + +qreal NetToolBox::highlight() +{ + return m_animHighlightFrame; +} + +void NetToolBox::movementFinished() +{ + if (slideAnim) { + if (slideAnim->property("direction") == QAbstractAnimation::Forward) { + slideAnim->setProperty("direction", QAbstractAnimation::Backward); + } else { + slideAnim->setProperty("direction", QAbstractAnimation::Forward); + } + } + m_toolContainer->setVisible(m_showing); +} + +void NetToolBox::onMovement(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + Q_UNUSED(newState); + Q_UNUSED(oldState); + m_toolContainer->show(); +} + +#include "nettoolbox.moc" diff --git a/plasma/netbook/shell/nettoolbox/nettoolbox.h b/plasma/netbook/shell/nettoolbox/nettoolbox.h new file mode 100644 index 00000000..b17f5798 --- /dev/null +++ b/plasma/netbook/shell/nettoolbox/nettoolbox.h @@ -0,0 +1,109 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETTOOLBOX_H +#define NETTOOLBOX_H + +#include +#include +#include + +#include +#include + + +class QGraphicsLinearLayout; + +namespace Plasma +{ + class Containment; + class IconWidget; + class Svg; +} + +class ToolContainer; + +class NetToolBox : public Plasma::AbstractToolBox +{ + Q_OBJECT + Q_PROPERTY(bool showing READ isShowing WRITE setShowing ) + Q_PROPERTY(qreal highlight READ highlight WRITE setHighlight) +public: + explicit NetToolBox(Plasma::Containment *parent = 0); + explicit NetToolBox(QObject *parent, const QVariantList &args); + ~NetToolBox(); + + bool isShowing() const; + void setShowing(const bool show); + + /** + * create a toolbox tool from the given action + * @p action the action to associate the tool with + */ + void addTool(QAction *action); + /** + * remove the tool associated with this action + */ + void removeTool(QAction *action); + + QRectF expandedGeometry() const; + + void setLocation(Plasma::Location location); + Plasma::Location location() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +protected: + void init(); + + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + +private Q_SLOTS: + void containmentGeometryChanged(); + void setHighlight(qreal progress); + qreal highlight(); + void movementFinished(); + void onMovement(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + +private: + void highlight(bool highlighting); + ToolContainer *m_toolContainer; + QGraphicsLinearLayout *m_toolContainerLayout; + QHash m_actionButtons; + Plasma::Containment *m_containment; + Plasma::Svg *m_background; + KIcon m_icon; + KIcon m_closeIcon; + QSize m_iconSize; + Plasma::Animation *slideAnim; + QPropertyAnimation *anim; + qreal m_animHighlightFrame; + bool m_hovering; + bool m_showing; + Plasma::Location m_location; + int m_newToolsPosition; +}; + +K_EXPORT_PLASMA_TOOLBOX(nettoolbox, NetToolBox) + +#endif diff --git a/plasma/netbook/shell/nettoolbox/plasma-toolbox-nettoolbox.desktop b/plasma/netbook/shell/nettoolbox/plasma-toolbox-nettoolbox.desktop new file mode 100644 index 00000000..3df2e8cf --- /dev/null +++ b/plasma/netbook/shell/nettoolbox/plasma-toolbox-nettoolbox.desktop @@ -0,0 +1,124 @@ +[Desktop Entry] +Comment=Default toolbox for the netbook shell +Comment[ast]=Caxa de ferramientes predeterminada de la shell pa netbooks +Comment[bg]=Стандартни инструменти за обвивка на нетбук +Comment[bs]=Podrazumijevana alatnica za netbuk školjku +Comment[ca]=Quadre d'eines per defecte per a l'àrea de treball dels ordinadors ultraportàtils +Comment[ca@valencia]=Quadre d'eines per defecte per a l'àrea de treball dels ordinadors ultraportàtils +Comment[cs]=Výchozí nástroje pro netbook shell +Comment[da]=Standard værktøjskasse til netbook-skallen +Comment[de]=Standard-Werkzeugkasten für die Plasma-Netbook-Oberfläche +Comment[el]=Προκαθορισμένη εργαλειοθήκη για το κέλυφος netbook +Comment[en_GB]=Default toolbox for the netbook shell +Comment[es]=Caja de herramientas predeterminada de la shell para netbooks +Comment[et]=Väikesülearvutikooriku vaikimisi tööriistakast +Comment[eu]=Netbooken shell-erako tresna-kutxa lehenetsia +Comment[fi]=Netbook-kuoren oletustyökalupakki +Comment[fr]=Boîte à outils par défaut pour le shell des ultra portables +Comment[gl]=A caixa de ferramentas predeterminada da shell netbook +Comment[he]=ארגז־כלים ברירת המחדל עבור מעטפת הנטבוק +Comment[hr]=Zadana alatna kutija za netbook ljusku +Comment[hu]=Alapértelmezett eszközkészlet a netbook héjhoz +Comment[ia]=Instrumentario predefinite pro le shell del netbook +Comment[is]=Sjálfgefið verkfærasafn fyrir smáfartölvuskelina +Comment[ja]=ネットブックシェル用の標準ツールボックス +Comment[kk]=Нетбук ортасының әдетті құралдар панелі +Comment[km]=ប្រអប់​ឧបករណ៍​លំនាំដើម សម្រាប់​សែល netbook +Comment[ko]=넷북 셸을 위한 기본 도구 상자 +Comment[lt]=Numatytoji netbook apvalkalo įrankinė +Comment[lv]=Noklusētā rīkkaste mazdatoru čaulai +Comment[mr]=नेटबूक शेलसाठी मूलभूत साधने +Comment[nb]=Standard verktøykasse for netbook-skallet +Comment[nds]=Standardwarktüüchkist för de Nettbook-Konsool +Comment[nl]=Standaard hulpmiddelen voor de netbook-shell +Comment[pa]=ਨੈੱਟਬੁੱਕ ਸ਼ੈੱਲ ਲਈ ਡਿਫਾਲਟ ਟੂਲਬਾਕਸ +Comment[pl]=Domyślny przybornik dla powłoki netbook +Comment[pt]=A barra predefinida para a consola do Netbook +Comment[pt_BR]=A barra padrão para o shell do netbook +Comment[ro]=Trusă de unelte implicită pentru învelișul de netbook +Comment[ru]=Стандартные инструменты настройки оболочки для нетбуков +Comment[sk]=Štandardné nástroje pre netbook shell +Comment[sl]=Privzeti nabor orodij za Namizno lupino Plasma za male prenosnike +Comment[sr]=Подразумевана алатница за нетбук шкољку +Comment[sr@ijekavian]=Подразумијевана алатница за нетбук шкољку +Comment[sr@ijekavianlatin]=Podrazumijevana alatnica za netbuk školjku +Comment[sr@latin]=Podrazumevana alatnica za netbuk školjku +Comment[sv]=Standardverktyg för nätdatorskalet +Comment[th]=กล่องเครื่องมือปริยายสำหรับเชลล์ของเน็ตบุ้ค +Comment[tr]=Netbook kabuğu için öntanımlı araçkutusu +Comment[ug]=تور كومپيۇتېر shell ئۈچۈن كۆڭۈلدىكى قورال قۇتىسى +Comment[uk]=Типовий набір інструментів для оболонки субноутбуків +Comment[vi]=Hộp công cụ mặc định cho vỏ netbook +Comment[wa]=Usteye prémetowe pol shell di poirtåve éndjolete +Comment[x-test]=xxDefault toolbox for the netbook shellxx +Comment[zh_CN]=上网本外壳的默认工具 +Comment[zh_TW]=netbook shell 的預設工具盒 +Icon=plasma +Name=Net toolbox +Name[ast]=Caxa de ferramientes netbook +Name[bs]=Netbuk alatnica +Name[ca]=Quadre d'eines de la xarxa +Name[ca@valencia]=Quadre d'eines de la xarxa +Name[cs]=Nástroje sítě +Name[da]=Netværktøjskasse +Name[de]=Werkzeugkasten für Netbooks +Name[el]=Εργαλειοθήκη δικτύου +Name[en_GB]=Net toolbox +Name[es]=Caja de herramientas netbook +Name[et]=Väikesülearvuti tööriistakast +Name[eu]=Netbooketarako tresna-kutxa +Name[fi]=Verkkotyökalupakki +Name[fr]=Boîte à outils réseau +Name[ga]=Bosca uirlisí líonra +Name[gl]=Caixa de ferramentas de rede +Name[he]=ארגז־כלי רשת +Name[hr]=Mrežna alatna kutija +Name[hu]=Hálózati eszközkészlet +Name[ia]=Instrumentario de rete +Name[is]=Net-verkfærasafn +Name[ja]=ネットワークツールボックス +Name[kk]=Желі құралдары +Name[km]=ប្រអប់​ឧបករណ៍​បណ្ដាញ +Name[kn]=ಜಾಲ ಉಪಕರಣಪಟ್ಟಿ +Name[ko]=넷북 도구 상자 +Name[lt]=Tinklo įrankinė +Name[lv]=Tīkla rīkkaste +Name[mr]=नेटबूक साधने +Name[nb]=Nettverksverktøykasse +Name[nds]=Nettbook-Warktüüchkist +Name[nl]=Netwerk-hulpmiddelen +Name[pa]=ਨੈੱਟ ਟੂਲਬਾਕਸ +Name[pl]=Przybornik Net +Name[pt]=Barra da rede +Name[pt_BR]=Barra da rede +Name[ro]=Trusă unelte de rețea +Name[ru]=Настройка оболочки для нетбуков +Name[sk]=Nástroje pre netbook +Name[sl]=Orodja za delovno okolje +Name[sr]=Нетбук алатница +Name[sr@ijekavian]=Нетбук алатница +Name[sr@ijekavianlatin]=Netbuk alatnica +Name[sr@latin]=Netbuk alatnica +Name[sv]=Nätverksverktyg +Name[th]=เครื่องมือระบบเครือข่าย +Name[tr]=Ağ araçkutusu +Name[ug]=تور قورال قۇتىسى +Name[uk]=Набір інструментів для субноутбуків +Name[wa]=Boesse ås usteye del rantoele +Name[x-test]=xxNet toolboxxx +Name[zh_CN]=网络工具箱 +Name[zh_TW]=網路工具盒 +Type=Service + +X-KDE-ServiceTypes=Plasma/ToolBox +X-KDE-Library=plasma_toolbox_nettoolbox +X-KDE-PluginInfo-Author=Marco Martin +X-KDE-PluginInfo-Category= +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-Email=mart@kde.org +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-Name=org.kde.nettoolbox +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ + diff --git a/plasma/netbook/shell/netview.cpp b/plasma/netbook/shell/netview.cpp new file mode 100644 index 00000000..a7825f36 --- /dev/null +++ b/plasma/netbook/shell/netview.cpp @@ -0,0 +1,338 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netview.h" +#include "netcorona.h" +#include "netpanelcontroller.h" + +#include +#include + +#ifndef QT_NO_OPENGL +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + +NetView::NetView(Plasma::Containment *containment, int uid, QWidget *parent) + : Plasma::View(containment, uid, parent), + m_panelController(0), + m_configurationMode(false), + m_useGL(false) +{ + setFocusPolicy(Qt::NoFocus); + connectContainment(containment); + + connect(this, SIGNAL(lostContainment()), SLOT(grabContainment())); + //setOptimizationFlags(QGraphicsView::DontSavePainterState); + + setAttribute(Qt::WA_TranslucentBackground, uid == controlBarId()); + + m_containmentSwitchAnimation = new QPropertyAnimation(this, "sceneRect", this); +} + +NetView::~NetView() +{ +} + +void NetView::setUseGL(const bool on) +{ +#ifndef QT_NO_OPENGL + if (on) { + QGLWidget *glWidget = new QGLWidget; + glWidget->setAutoFillBackground(false); + setViewport(glWidget); + } else { + QWidget *widget = new QWidget; + widget->setAutoFillBackground(false); + setViewport(widget); + } +#endif + m_useGL = on; +} + +bool NetView::useGL() const +{ + return m_useGL; +} + +void NetView::connectContainment(Plasma::Containment *containment) +{ + if (!containment) { + return; + } + + connect(containment, SIGNAL(activate()), this, SIGNAL(containmentActivated())); + connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updateGeometry())); + connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(updateConfigurationMode(bool))); + connect(containment, SIGNAL(immutabilityChanged(ImmutabilityType)), this, SLOT(immutabilityChanged(ImmutabilityType))); + + QAction *a = containment->action("next containment"); + if (a) { + connect(a, SIGNAL(triggered()), this, SLOT(nextContainment())); + } + a = containment->action("previous containment"); + if (a) { + connect(a, SIGNAL(triggered()), this, SLOT(previousContainment())); + } +} + +void NetView::setContainment(Plasma::Containment *c) +{ + if (containment()) { + disconnect(containment(), 0, this, 0); + + QAction *a = containment()->action("next containment"); + if (a) { + disconnect(a, SIGNAL(triggered()), this, SLOT(nextContainment())); + } + a = containment()->action("previous containment"); + if (a) { + disconnect(a, SIGNAL(triggered()), this, SLOT(previousContainment())); + } + } + + if (containment() && id() == mainViewId()) { + setTrackContainmentChanges(false); + Plasma::WindowEffects::enableBlurBehind(effectiveWinId(), false); + } else if (containment() && id() == controlBarId()) { + Plasma::WindowEffects::enableBlurBehind(effectiveWinId(), true); + } + + Plasma::View::setContainment(c); + connectContainment(c); + updateGeometry(); + + if (containment() && id() == mainViewId()) { + if (c) { + m_containmentSwitchAnimation->setDuration(250); + m_containmentSwitchAnimation->setStartValue(sceneRect()); + m_containmentSwitchAnimation->setEndValue(c->geometry()); + m_containmentSwitchAnimation->start(); + } + setTrackContainmentChanges(true); + } +} + +bool NetView::autoHide() const +{ + return config().readEntry("panelAutoHide", true); +} + +void NetView::setAutoHide(bool hide) +{ + if (hide != autoHide()) { + emit autoHideChanged(hide); + } + config().writeEntry("panelAutoHide", hide); +} + +void NetView::immutabilityChanged(Plasma::ImmutabilityType immutability) +{ + if (m_configurationMode && immutability == Plasma::Mutable) { + updateConfigurationMode(true); + } else if (m_configurationMode) { + updateConfigurationMode(false); + } +} + +// This function is reimplemented from QGraphicsView to work around the problem +// that QPainter::fillRect(QRectF/QRect, QBrush), which QGraphicsView uses, is +// potentially slow when the anti-aliasing hint is set and as implemented won't +// hit accelerated code at all when it isn't set. This implementation avoids +// the problem by using integer coordinates and by using drawTiledPixmap() in +// the case of a texture brush, and fillRect(QRect, QColor) in the case of a +// solid pattern. As an additional optimization it draws the background with +// CompositionMode_Source. +void NetView::drawBackground(QPainter *painter, const QRectF &rect) +{ + if (!testAttribute(Qt::WA_TranslucentBackground)) { + painter->fillRect(rect.toAlignedRect(), Qt::black); + } else { + if (KWindowSystem::compositingActive()) { + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->fillRect(rect.toAlignedRect(), Qt::transparent); + } else { + Plasma::View::drawBackground(painter, rect); + } + } +} + + +void NetView::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + updateGeometry(); + emit geometryChanged(); +} + +bool NetView::event(QEvent *e) +{ + if (e->type() == QEvent::Close) { + //prevent ALT+F4 from killing the shell + e->ignore(); + return true; + } else { + return Plasma::View::event(e); + } +} + +void NetView::screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* containment) +{ + kDebug() << "was, is, containment:" << wasScreen << isScreen << (QObject*)containment; + if (containment->containmentType() == Plasma::Containment::PanelContainment) { + // we don't care about panel containments changing screens on us + return; + } + + if (wasScreen == screen() && this->containment() == containment) { + setContainment(0); + } + + if ((isScreen == screen() || screen() == -1) && this->containment( )!= containment) { + setContainment(containment); + } +} + +Plasma::Location NetView::location() const +{ + return containment()->location(); +} + +Plasma::FormFactor NetView::formFactor() const +{ + return containment()->formFactor(); +} + +void NetView::updateGeometry() +{ + Plasma::Containment *c = containment(); + if (!c) { + return; + } + + kDebug() << "New containment geometry is" << c->geometry(); + + switch (c->location()) { + case Plasma::TopEdge: + case Plasma::BottomEdge: + setMinimumWidth(0); + setMaximumWidth(QWIDGETSIZE_MAX); + setFixedHeight(c->size().height()); + emit locationChanged(this); + break; + case Plasma::LeftEdge: + case Plasma::RightEdge: + setMinimumHeight(0); + setMaximumHeight(QWIDGETSIZE_MAX); + setFixedWidth(c->size().width()); + emit locationChanged(this); + break; + //ignore changes in the main view + default: + break; + } + + if (c->size().toSize() != size()) { + c->setMaximumSize(size()); + c->setMinimumSize(size()); + c->resize(size()); + } +} + +void NetView::grabContainment() +{ + + NetCorona *corona = qobject_cast(scene()); + if (!corona) { + kDebug() << "no corona :("; + return; + } + + Plasma::Containment *cont = corona->findFreeContainment(); + if (cont) { + cont->setScreen(screen(), desktop()); + } +} + +void NetView::updateConfigurationMode(bool config) +{ + m_configurationMode = config; + + Plasma::Containment *cont = containment(); + if (config && cont && cont->immutability() == Plasma::Mutable && + (cont->location() != Plasma::Desktop && cont->location() != Plasma::Floating)) { + m_panelController = new NetPanelController(0, this, cont); + } else { + delete m_panelController; + m_panelController = 0; + } +} + +void NetView::nextContainment() +{ + QList containments = containment()->corona()->containments(); + int start = containments.indexOf(containment()); + int i = (start + containments.size() - 1) % containments.size(); + Plasma::Containment *cont = containments.at(i); + + //FIXME this is a *horrible* way of choosing a "previous" containment. + while (i != start) { + if ((cont->location() == Plasma::Desktop || cont->location() == Plasma::Floating) && + cont->screen() == -1) { + break; + } + + if (--i < 0) { + i += containments.size(); + } + cont = containments.at(i); + } + + cont->setScreen(screen(), desktop()); +} + +void NetView::previousContainment() +{ + QList containments = containment()->corona()->containments(); + int start = containments.indexOf(containment()); + int i = (start + 1) % containments.size(); + Plasma::Containment *cont = containments.at(i); + //FIXME this is a *horrible* way of choosing a "next" containment. + while (i != start) { + if ((cont->location() == Plasma::Desktop || cont->location() == Plasma::Floating) && + cont->screen() == -1) { + break; + } + + i = (i + 1) % containments.size(); + cont = containments.at(i); + } + + cont->setScreen(screen(), desktop()); +} + +#include "netview.moc" + diff --git a/plasma/netbook/shell/netview.h b/plasma/netbook/shell/netview.h new file mode 100644 index 00000000..ef691aae --- /dev/null +++ b/plasma/netbook/shell/netview.h @@ -0,0 +1,89 @@ +/* + * Copyright 2007-2008 Aaron Seigo + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETVIEW_H +#define NETVIEW_H + +#include +#include + +class NetPanelController; +class QPropertyAnimation; + +namespace Plasma +{ + class Containment; +} // namespace Plasma + +class NetView : public Plasma::View +{ + Q_OBJECT + +public: + typedef Plasma::ImmutabilityType ImmutabilityType; + NetView(Plasma::Containment *containment, int uid, QWidget *parent = 0); + ~NetView(); + + /** + * hook up all needed signals to a containment + */ + void connectContainment(Plasma::Containment *containment); + + Plasma::Location location() const; + Plasma::FormFactor formFactor() const; + KConfigGroup config() const {return Plasma::View::config();} + bool autoHide() const; + + static int mainViewId() { return 1; } + static int controlBarId() { return 2; } + + void setUseGL(const bool on); + bool useGL() const; + + +public Q_SLOTS: + void setContainment(Plasma::Containment *containment); + void screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* containment); + void updateGeometry(); + void grabContainment(); + void updateConfigurationMode(bool config); + void setAutoHide(bool autoHide); + void immutabilityChanged(ImmutabilityType immutability); + void nextContainment(); + void previousContainment(); + +Q_SIGNALS: + void locationChanged(const NetView *view); + void geometryChanged(); + void containmentActivated(); + void autoHideChanged(bool autoHide); + +protected: + void drawBackground(QPainter *painter, const QRectF &rect); + void resizeEvent(QResizeEvent *event); + bool event(QEvent *e); + +private: + NetPanelController *m_panelController; + bool m_configurationMode; + bool m_useGL; + QPropertyAnimation *m_containmentSwitchAnimation; +}; + +#endif // multiple inclusion guard diff --git a/plasma/netbook/shell/plasmaapp.cpp b/plasma/netbook/shell/plasmaapp.cpp new file mode 100644 index 00000000..c364238b --- /dev/null +++ b/plasma/netbook/shell/plasmaapp.cpp @@ -0,0 +1,1306 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "plasmaapp.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "netcorona.h" +#include "netview.h" + +#include "widgetsexplorer/widgetexplorer.h" +#include "plasmagenericshell/backgrounddialog.h" + +#ifdef Q_WS_X11 +#include +#include +#include +#endif + +PlasmaApp* PlasmaApp::self() +{ + if (!kapp) { + return new PlasmaApp(); + } + + return qobject_cast(kapp); +} + + +class GlowBar : public QWidget +{ +public: + GlowBar(Plasma::Direction direction, const QRect &triggerZone) + : QWidget(0), + m_strength(0.3), + m_svg(new Plasma::Svg(this)), + m_direction(direction) + { + setAttribute(Qt::WA_TranslucentBackground); + KWindowSystem::setOnAllDesktops(winId(), true); + unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove; + KWindowSystem::setState(winId(), state); + KWindowSystem::setType(winId(), NET::Dock); + m_svg->setImagePath("widgets/glowbar"); + +#ifdef Q_WS_X11 + QRegion region(QRect(0,0,1,1)); + XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0, + region.handle(), ShapeSet); +#endif + + QPalette pal = palette(); + pal.setColor(backgroundRole(), Qt::transparent); + setPalette(pal); + + QRect glowGeom = triggerZone; + QSize s = sizeHint(); + switch (m_direction) { + case Plasma::Up: + glowGeom.setY(glowGeom.y() - s.height() + 1); + // fallthrough + case Plasma::Down: + glowGeom.setHeight(s.height()); + break; + case Plasma::Left: + glowGeom.setX(glowGeom.x() - s.width() + 1); + // fallthrough + case Plasma::Right: + glowGeom.setWidth(s.width()); + break; + } + + //kDebug() << "glow geom is" << glowGeom << "from" << triggerZone; + setGeometry(glowGeom); + m_buffer = QPixmap(size()); + } + + void paintEvent(QPaintEvent* e) + { + Q_UNUSED(e) + QPixmap pixmap; + const QSize glowRadius = m_svg->elementSize("hint-glow-radius"); + QPoint pixmapPosition(0, 0); + + m_buffer.fill(QColor(0, 0, 0, int(qreal(255)*m_strength))); + QPainter p(&m_buffer); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + + switch (m_direction) { + case Plasma::Down: + pixmap = m_svg->pixmap("bottom"); + pixmapPosition = QPoint(0, -glowRadius.height()); + break; + case Plasma::Up: + pixmap = m_svg->pixmap("top"); + break; + case Plasma::Right: + pixmap = m_svg->pixmap("right"); + pixmapPosition = QPoint(-glowRadius.width(), 0); + break; + case Plasma::Left: + pixmap = m_svg->pixmap("left"); + break; + } + + if (m_direction == Plasma::Left || m_direction == Plasma::Right) { + p.drawTiledPixmap(QRect(0, pixmapPosition.x(), pixmap.width(), height()), pixmap); + } else { + p.drawTiledPixmap(QRect(0, pixmapPosition.y(), width(), pixmap.height()), pixmap); + } + + p.end(); + p.begin(this); + p.drawPixmap(QPoint(0, 0), m_buffer); + } + + QSize sizeHint() const + { + return m_svg->elementSize("bottomright") - m_svg->elementSize("hint-glow-radius"); + } + + bool event(QEvent *event) + { + if (event->type() == QEvent::Paint) { + QPainter p(this); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(rect(), Qt::transparent); + } + return QWidget::event(event); + } + + void updateStrength(QPoint point) + { + QPoint localPoint = mapFromGlobal(point); + + qreal newStrength; + switch (m_direction) { + case Plasma::Up: // when the panel is at the bottom. + newStrength = 1 - qreal(-localPoint.y())/m_triggerDistance; + break; + case Plasma::Right: + newStrength = 1 - qreal(localPoint.x())/m_triggerDistance; + break; + case Plasma::Left: // when the panel is right-aligned + newStrength = 1 - qreal(-localPoint.x())/m_triggerDistance; + break; + case Plasma::Down: + default: + newStrength = 1- qreal(localPoint.y())/m_triggerDistance; + break; + } + if (qAbs(newStrength - m_strength) > 0.01 && newStrength >= 0 && newStrength <= 1) { + m_strength = newStrength; + update(); + } + } + + +private: + static const int m_triggerDistance = 30; + qreal m_strength; + Plasma::Svg *m_svg; + Plasma::Direction m_direction; + QPixmap m_buffer; +}; + + +class ShadowWindow : public QWidget +{ +public: + ShadowWindow(NetView *panel) + : QWidget(0), + m_panel(panel), + m_valid(false) + { + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_NoSystemBackground, false); + setAutoFillBackground(false); +#ifdef Q_WS_X11 + QRegion region(QRect(0,0,1,1)); + XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0, + region.handle(), ShapeSet); +#endif + + m_shadow = new Plasma::FrameSvg(this); + } + + void setSvg(const QString &path) + { + m_shadow->setImagePath(path); + + if (!m_shadow->hasElementPrefix("shadow")) { + hide(); + m_valid = false; + } else { + m_valid = true; + } + + m_shadow->setElementPrefix("shadow"); + + adjustMargins(geometry()); + } + + bool isValid() const + { + return m_valid; + } + + void adjustMargins(const QRect &geo) + { + QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_panel->screen()); + + Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders; + + if (geo.left() <= screenRect.left()) { + enabledBorders ^= Plasma::FrameSvg::LeftBorder; + } + if (geo.top() <= screenRect.top()) { + enabledBorders ^= Plasma::FrameSvg::TopBorder; + } + if (geo.bottom() >= screenRect.bottom()) { + enabledBorders ^= Plasma::FrameSvg::BottomBorder; + } + if (geo.right() >= screenRect.right()) { + enabledBorders ^= Plasma::FrameSvg::RightBorder; + } + + m_shadow->setEnabledBorders(enabledBorders); + + qreal left, top, right, bottom; + + m_shadow->getMargins(left, top, right, bottom); + setContentsMargins(left, top, right, bottom); + } + +protected: + bool event(QEvent *event) + { + Q_UNUSED(event) + + if (event->type() == QEvent::Paint) { + QPainter p(this); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(rect(), Qt::transparent); + } + return QWidget::event(event); + } + + void resizeEvent(QResizeEvent *event) + { + m_shadow->resizeFrame(event->size()); + + adjustMargins(geometry()); + } + + void paintEvent(QPaintEvent* e) + { + Q_UNUSED(e) + + QPainter p(this); + //p.setCompositionMode(QPainter::CompositionMode_Source); + m_shadow->paintFrame(&p); + } + +private: + Plasma::FrameSvg *m_shadow; + NetView *m_panel; + bool m_valid; +}; + +PlasmaApp::PlasmaApp() + : KUniqueApplication(), + m_corona(0), + m_widgetExplorerView(0), + m_widgetExplorer(0), + m_glowBar(0), + m_mousePollTimer(0), + m_controlBar(0), + m_mainView(0), + m_isDesktop(false), + m_autoHideControlBar(true), + m_unHideTimer(0), + m_shadowWindow(0), + m_startupSuspendWaitCount(0) +{ + PlasmaApp::suspendStartup(true); + KGlobal::locale()->insertCatalog("libplasma"); + KGlobal::locale()->insertCatalog("plasmagenericshell"); + + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + bool isDesktop = args->isSet("desktop"); + if (isDesktop) { + KCrash::setFlags(KCrash::AutoRestart); + } + + //TODO: decide how to handle the cache size; possibilities: + // * % of ram, as in desktop + // * fixed size, hardcoded (uck) + // * optional size, specified on command line + // * optional size, in a config file + // * don't do anything special at all + //QPixmapCache::setCacheLimit(cacheSize); + + KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-netbook"); + const QString themeName = cg.readEntry("name", "air-netbook"); + Plasma::Theme::defaultTheme()->setUseGlobalSettings(false); + Plasma::Theme::defaultTheme()->setThemeName(themeName); + + cg = KConfigGroup(KGlobal::config(), "General"); + + Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font())); + + m_mainView = new NetView(0, NetView::mainViewId(), 0); + m_mainView->hide(); + + connect(m_mainView, SIGNAL(containmentActivated()), this, SLOT(mainContainmentActivated())); + connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(positionPanel())); + + bool useGL = args->isSet("opengl"); + m_mainView->setUseGL(useGL); + + connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(controlBarVisibilityUpdate())); + + int width = 400; + int height = 200; + if (isDesktop) { + QRect rect = Kephal::ScreenUtils::screenGeometry(m_mainView->screen()); + width = rect.width(); + height = rect.height(); + } else { + QAction *action = KStandardAction::quit(qApp, SLOT(quit()), m_mainView); + m_mainView->addAction(action); + + QString geom = args->getOption("screen"); + int x = geom.indexOf('x'); + + if (x > 0) { + width = qMax(width, geom.left(x).toInt()); + height = qMax(height, geom.right(geom.length() - x - 1).toInt()); + } + } + + m_mainView->setFixedSize(width, height); + m_mainView->move(0,0); + setIsDesktop(isDesktop); + + // this line initializes the corona. + corona(); + //setIsDesktop(isDesktop); + reserveStruts(); + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(checkShadow())); + connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup())); +} + +PlasmaApp::~PlasmaApp() +{ +} + +void PlasmaApp::cleanup() +{ + if (m_corona) { + m_corona->saveLayout(); + } + + if (!m_mainView->containment()) { + return; + } + + // save the mapping of Views to Containments at the moment + // of application exit so we can restore that when we start again. + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + viewIds.deleteGroup(); + viewIds.writeEntry(QString::number(m_mainView->containment()->id()), NetView::mainViewId()); + + if (m_controlBar) { + viewIds.writeEntry(QString::number(m_controlBar->containment()->id()), NetView::controlBarId()); + } + + delete m_mainView; + m_mainView = 0; + + delete m_corona; + m_corona = 0; + + //TODO: This manual sync() should not be necessary? + syncConfig(); +} + +void PlasmaApp::syncConfig() +{ + KGlobal::config()->sync(); +} + +void PlasmaApp::positionPanel() +{ + if (!m_controlBar) { + return; + } + + QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen()); + if (!m_isDesktop) { + screenRect = m_mainView->geometry(); + } + + //move + controlBarMoved(m_controlBar); + + if (m_controlBar->formFactor() == Plasma::Horizontal) { + m_controlBar->setFixedSize(screenRect.width(), m_controlBar->size().height()); + } else if (m_controlBar->formFactor() == Plasma::Vertical) { + m_controlBar->setFixedSize(m_controlBar->size().width(), screenRect.height()); + } + + + m_controlBar->containment()->setMaximumSize(m_controlBar->size()); + m_controlBar->containment()->setMinimumSize(m_controlBar->size()); + + if (m_autoHideControlBar && m_controlBar->isVisible()) { + destroyUnHideTrigger(); + createUnhideTrigger(); + } + + checkShadow(); + + emit controlBarChanged(); +} + +void PlasmaApp::checkShadow() +{ + if (!m_controlBar) { + return; + } + + if (KWindowSystem::compositingActive() && m_controlBar->containment()->property("shadowPath").isValid()) { + if (!m_shadowWindow) { + m_shadowWindow = new ShadowWindow(m_controlBar); + KWindowSystem::setOnAllDesktops(m_controlBar->winId(), true); + } + KWindowSystem::setType(m_shadowWindow->winId(), NET::Dock); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow); + KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true); + m_shadowWindow->setSvg(m_controlBar->containment()->property("shadowPath").toString()); + int left, right, top, bottom; + m_shadowWindow->adjustMargins(m_controlBar->geometry()); + m_shadowWindow->getContentsMargins(&left, &top, &right, &bottom); + m_shadowWindow->setMinimumSize(-1, -1); + m_shadowWindow->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + m_shadowWindow->setGeometry(m_controlBar->geometry().adjusted(-left, -top, right, bottom)); + m_shadowWindow->setFixedSize(m_shadowWindow->size()); + if (m_shadowWindow->isValid()) { + m_shadowWindow->show(); + } + } else { + m_shadowWindow->deleteLater(); + m_shadowWindow = 0; + } +} + +void PlasmaApp::mainContainmentActivated() +{ + if (m_mainView->containment()) { + m_mainView->setWindowTitle(m_mainView->containment()->activity()); + } + + + const WId id = m_mainView->effectiveWinId(); + + QWidget * activeWindow = QApplication::activeWindow(); + KWindowSystem::raiseWindow(id); + + if (activeWindow) { + KWindowSystem::raiseWindow(activeWindow->effectiveWinId()); + m_mainView->activateWindow(); + activeWindow->setFocus(); + if (m_shadowWindow) { + KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove); + } + } else { + m_mainView->activateWindow(); + } +} + +void PlasmaApp::setIsDesktop(bool isDesktop) +{ + m_isDesktop = isDesktop; + + if (isDesktop) { + KWindowSystem::setType(m_mainView->winId(), NET::Normal); + m_mainView->setWindowFlags(m_mainView->windowFlags() | Qt::FramelessWindowHint); + KWindowSystem::setOnAllDesktops(m_mainView->winId(), true); + if (m_controlBar) { + KWindowSystem::setOnAllDesktops(m_controlBar->winId(), true); + } + m_mainView->show(); + } else { + m_mainView->setWindowFlags(m_mainView->windowFlags() & ~Qt::FramelessWindowHint); + KWindowSystem::setOnAllDesktops(m_mainView->winId(), false); + if (m_controlBar) { + KWindowSystem::setOnAllDesktops(m_controlBar->winId(), false); + } + KWindowSystem::setType(m_mainView->winId(), NET::Normal); + } +} + +bool PlasmaApp::isDesktop() const +{ + return m_isDesktop; +} + +void PlasmaApp::adjustSize(Kephal::Screen *screen) +{ + Q_UNUSED(screen) + + QRect rect = Kephal::ScreenUtils::screenGeometry(m_mainView->screen()); + + int width = rect.width(); + int height = rect.height(); + //FIXME: ugly hack there too + m_mainView->setFixedSize(width, height); + positionPanel(); + reserveStruts(); +} + +void PlasmaApp::reserveStruts() +{ + if (!m_controlBar) { + return; + } + + if (m_autoHideControlBar || !isDesktop()) { + KWindowSystem::setExtendedStrut(m_controlBar->winId(), + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0); + return; + } + + NETExtendedStrut strut; + + if (!m_autoHideControlBar || hasForegroundWindows()) { + switch (m_controlBar->location()) { + case Plasma::LeftEdge: + strut.left_width = m_controlBar->width(); + strut.left_start = m_controlBar->y(); + strut.left_end = m_controlBar->y() + m_controlBar->height() - 1; + break; + case Plasma::RightEdge: + strut.right_width = m_controlBar->width(); + strut.right_start = m_controlBar->y(); + strut.right_end = m_controlBar->y() + m_controlBar->height() - 1; + break; + case Plasma::TopEdge: + strut.top_width = m_controlBar->height(); + strut.top_start = m_controlBar->x(); + strut.top_end = m_controlBar->x() + m_controlBar->width() - 1; + break; + case Plasma::BottomEdge: + default: + strut.bottom_width = m_controlBar->height(); + strut.bottom_start = m_controlBar->x(); + strut.bottom_end = m_controlBar->x() + m_controlBar->width() - 1; + } + } + + KWindowSystem::setExtendedStrut(m_controlBar->winId(), + strut.left_width, strut.left_start, strut.left_end, + strut.right_width, strut.right_start, strut.right_end, + strut.top_width, strut.top_start, strut.top_end, + strut.bottom_width, strut.bottom_start, strut.bottom_end); + + //ensure the main view is at the proper position too + QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen()); + m_mainView->move(screenRect.topLeft()); +} + +NetView *PlasmaApp::controlBar() const +{ + return m_controlBar; +} + +NetView *PlasmaApp::mainView() const +{ + return m_mainView; +} + +QWidget *PlasmaApp::widgetExplorer() const +{ + return m_widgetExplorerView; +} + +Plasma::Corona* PlasmaApp::corona() +{ + if (!m_corona) { + m_corona = new NetCorona(this); + connect(m_corona, SIGNAL(containmentAdded(Plasma::Containment*)), + this, SLOT(createView(Plasma::Containment*))); + connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig())); + + connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)), + m_mainView, SLOT(screenOwnerChanged(int,int,Plasma::Containment*))); + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + m_corona->initializeLayout(); + m_corona->processUpdateScripts(); + + m_mainView->show(); + } + + foreach (Plasma::Containment *containment, m_corona->containments()) { + if (containment->screen() != -1 && containment->wallpaper()) { + ++m_startupSuspendWaitCount; + connect(containment->wallpaper(), SIGNAL(update(QRectF)), this, SLOT(wallpaperCheckedIn())); + } + } + + QTimer::singleShot(5000, this, SLOT(wallpaperCheckInTimeout())); + + return m_corona; +} + +void PlasmaApp::wallpaperCheckInTimeout() +{ + if (m_startupSuspendWaitCount > 0) { + m_startupSuspendWaitCount = 0; + suspendStartup(false); + } +} + +void PlasmaApp::wallpaperCheckedIn() +{ + if (m_startupSuspendWaitCount < 1) { + return; + } + + --m_startupSuspendWaitCount; + if (m_startupSuspendWaitCount < 1) { + m_startupSuspendWaitCount = 0; + suspendStartup(false); + } +} + +bool PlasmaApp::hasComposite() +{ + return KWindowSystem::compositingActive(); +} + +void PlasmaApp::suspendStartup(bool suspend) +{ + org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus()); + + const QString startupID("netbook desktop"); + if (suspend) { + ksmserver.suspendStartup(startupID); + } else { + ksmserver.resumeStartup(startupID); + } +} + +void PlasmaApp::createView(Plasma::Containment *containment) +{ + connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer())); + connect(containment, SIGNAL(configureRequested(Plasma::Containment*)), + this, SLOT(configureContainment(Plasma::Containment*))); + connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), + this, SLOT(updateToolBoxVisibility(bool))); + + + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + int defaultId = 0; + if (containment->containmentType() == Plasma::Containment::PanelContainment && + (!m_controlBar || m_controlBar->containment() == 0) ) { + defaultId = NetView::controlBarId(); + } else if (containment->containmentType() == Plasma::Containment::PanelContainment && + m_mainView->containment() == 0 ) { + defaultId = NetView::mainViewId(); + } + + int id = viewIds.readEntry(QString::number(containment->id()), defaultId); + + + kDebug() << "new containment" << (QObject*)containment << containment->id() << "view id" << id; + + //is it a desktop -and- is it active? + if ((m_mainView && id == NetView::mainViewId()) || + (containment->containmentType() != Plasma::Containment::PanelContainment && + containment->containmentType() != Plasma::Containment::CustomPanelContainment && + !viewIds.exists() && containment->screen() == 0)) { + m_mainView->setContainment(containment); + containment->setScreen(0); + //is it a panel? + } else if (id == NetView::controlBarId()) { + if (!m_controlBar) { + m_controlBar = new NetView(0, NetView::controlBarId(), 0); + + Kephal::Screens *screens = Kephal::Screens::self(); + connect(screens, SIGNAL(screenResized(Kephal::Screen*,QSize,QSize)), + this, SLOT(adjustSize(Kephal::Screen*))); + + m_controlBar->setAutoFillBackground(false); + m_controlBar->viewport()->setAutoFillBackground(false); + m_controlBar->setAttribute(Qt::WA_TranslucentBackground); + + connect(m_controlBar, SIGNAL(locationChanged(const NetView*)), this, SLOT(positionPanel())); + connect(m_controlBar, SIGNAL(geometryChanged()), this, SLOT(positionPanel())); + connect(m_controlBar, SIGNAL(containmentActivated()), this, SLOT(showControlBar())); + connect(m_controlBar, SIGNAL(autoHideChanged(bool)), this, SLOT(setAutoHideControlBar(bool))); + } + + m_controlBar->setContainment(containment); + positionPanel(); + setControlBarVisible(true); + containment->setMaximumSize(m_controlBar->size()); + containment->setMinimumSize(m_controlBar->size()); + containment->setImmutability(Plasma::UserImmutable); + + m_autoHideControlBar = m_controlBar->config().readEntry("panelAutoHide", true); + + setAutoHideControlBar(m_autoHideControlBar); + emit controlBarChanged(); + setControlBarVisible(true); + } else { + containment->setScreen(-1); + } +} + +void PlasmaApp::closeWidgetExplorer() +{ + if (m_widgetExplorer) { + Plasma::WindowEffects::slideWindow(m_widgetExplorerView, m_controlBar->location()); + m_widgetExplorer->deleteLater(); + m_widgetExplorerView->deleteLater(); + } +} + +void PlasmaApp::updateToolBoxVisibility(bool visible) +{ + bool hadToolBoxOpen = false; + + foreach (Plasma::Containment *cont, m_corona->containments()) { + if (cont->isToolBoxOpen()) { + hadToolBoxOpen = true; + } + cont->setToolBoxOpen(visible); + } + + if (!visible && hadToolBoxOpen) { + closeWidgetExplorer(); + } +} + +void PlasmaApp::controlBarMoved(const NetView *controlBar) +{ + if (!m_controlBar || controlBar != m_controlBar) { + return; + } + + QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen()); + + Plasma::Containment *cont = m_controlBar->containment(); + + switch (controlBar->location()) { + case Plasma::LeftEdge: + m_controlBar->move(screenRect.topLeft()); + break; + case Plasma::RightEdge: + m_controlBar->move(screenRect.topRight()-QPoint(m_controlBar->size().width(), 0)); + break; + case Plasma::TopEdge: + m_controlBar->move(screenRect.topLeft()); + break; + case Plasma::BottomEdge: + m_controlBar->move(screenRect.bottomLeft()-QPoint(0,m_controlBar->size().height())); + default: + break; + } + + //flip height and width + if (controlBar->formFactor() == Plasma::Vertical) { + if (cont && m_controlBar->size().width() > m_controlBar->size().height()) { + cont->setMinimumSize(cont->size().height(), cont->size().width()); + cont->setMaximumSize(cont->minimumSize()); + } + } else if (controlBar->formFactor() == Plasma::Horizontal) { + if (cont && m_controlBar->size().width() < m_controlBar->size().height()) { + cont->setMinimumSize(cont->size().height(), cont->size().width()); + cont->setMaximumSize(cont->minimumSize()); + } + } + + reserveStruts(); +} + +void PlasmaApp::setAutoHideControlBar(bool autoHide) +{ + if (!m_controlBar) { + return; + } + + if (autoHide) { + if (!m_unHideTimer) { + m_unHideTimer = new QTimer(this); + m_unHideTimer->setSingleShot(true); + connect(m_unHideTimer, SIGNAL(timeout()), this, SLOT(controlBarVisibilityUpdate())); + } + + m_controlBar->installEventFilter(this); + controlBarVisibilityUpdate(); + } else { + m_controlBar->removeEventFilter(this); + destroyUnHideTrigger(); + delete m_unHideTimer; + m_unHideTimer = 0; + setControlBarVisible(true); + } + + m_autoHideControlBar = autoHide; + reserveStruts(); + m_controlBar->config().writeEntry("panelAutoHide", autoHide); +} + +void PlasmaApp::showWidgetExplorer() +{ + Plasma::Containment *containment = dynamic_cast(sender()); + + if (!containment) { + return; + } + + showWidgetExplorer(containment); +} + +void PlasmaApp::showWidgetExplorer(Plasma::Containment *containment) +{ + if (!containment) { + return; + } + + containment->setToolBoxOpen(true); + + if (!m_widgetExplorerView) { + + m_widgetExplorerView = new Plasma::Dialog(); + + KWindowSystem::setOnAllDesktops(m_widgetExplorerView->winId(), true); + m_widgetExplorerView->show(); + KWindowSystem::activateWindow(m_widgetExplorerView->winId()); + m_widgetExplorerView->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + m_widgetExplorerView->setAttribute(Qt::WA_TranslucentBackground); + m_widgetExplorerView->setAttribute(Qt::WA_DeleteOnClose); + KWindowSystem::setState(m_widgetExplorerView->winId(), NET::StaysOnTop|NET::KeepAbove); + connect(m_widgetExplorerView, SIGNAL(destroyed()), this, SLOT(widgetExplorerDestroyed())); + + if (m_controlBar) { + switch (m_controlBar->location()) { + case Plasma::TopEdge: + m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous); + m_widgetExplorerView->move(m_controlBar->geometry().bottomLeft()); + break; + case Plasma::LeftEdge: + m_widgetExplorerView->resize(KIconLoader::SizeEnormous, m_mainView->size().height()); + m_widgetExplorerView->move(m_controlBar->geometry().topRight()); + break; + case Plasma::RightEdge: + m_widgetExplorerView->resize(KIconLoader::SizeEnormous, m_mainView->size().height()); + m_widgetExplorerView->move(m_controlBar->geometry().topLeft() - QPoint(m_widgetExplorerView->size().width(), 0)); + break; + case Plasma::BottomEdge: + default: + m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous); + m_widgetExplorerView->move(m_controlBar->geometry().topLeft() - QPoint(0, m_widgetExplorerView->size().height())); + break; + } + } else { + m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous); + m_widgetExplorerView->move(0,0); + } + + } + + if (!m_widgetExplorer) { + m_widgetExplorer = new Plasma::WidgetExplorer(m_controlBar->containment()); + connect(m_widgetExplorer, SIGNAL(closeClicked()), this, SLOT(closeWidgetExplorer())); + m_widgetExplorer->setContainment(m_mainView->containment()); + m_widgetExplorer->populateWidgetList(); + + m_corona->addOffscreenWidget(m_widgetExplorer); + + QSize viewSize = m_widgetExplorerView->size(); + m_widgetExplorerView->setGraphicsWidget(m_widgetExplorer); + + m_widgetExplorerView->installEventFilter(this); + } + + m_widgetExplorer->setLocation(m_controlBar->location()); + + if (m_widgetExplorer->location() == Plasma::LeftEdge || m_widgetExplorer->location() == Plasma::RightEdge) { + m_widgetExplorer->setMinimumWidth(-1); + m_widgetExplorer->setMinimumHeight(m_mainView->size().height()); + } else { + m_widgetExplorer->setMinimumWidth(m_mainView->size().width()); + m_widgetExplorer->setMinimumHeight(-1); + } + + positionPanel(); + + m_widgetExplorer->show(); + Plasma::WindowEffects::slideWindow(m_widgetExplorerView, m_controlBar->location()); + m_widgetExplorerView->show(); + emit controlBarChanged(); +} + +void PlasmaApp::widgetExplorerDestroyed() +{ + m_widgetExplorer = 0; + m_widgetExplorerView = 0; + positionPanel(); + if (m_mainView->containment()) { + m_mainView->containment()->setToolBoxOpen(false); + } +} + + +void PlasmaApp::configureContainment(Plasma::Containment *containment) +{ + const QString id = QString::number(containment->id()) + "settings" + containment->name(); + BackgroundDialog *configDialog = qobject_cast(KConfigDialog::exists(id)); + kDebug() << configDialog; + + if (configDialog) { + configDialog->reloadConfig(); + } else { + const QSize resolution = Kephal::ScreenUtils::screenGeometry(m_mainView->screen()).size(); + + + KConfigSkeleton *nullManager = new KConfigSkeleton(0); + configDialog = new BackgroundDialog(resolution, containment, m_mainView, 0, id, nullManager); + configDialog->setAttribute(Qt::WA_DeleteOnClose); + + connect(configDialog, SIGNAL(destroyed(QObject*)), nullManager, SLOT(deleteLater())); + } + + configDialog->show(); + KWindowSystem::setOnDesktop(configDialog->winId(), KWindowSystem::currentDesktop()); + KWindowSystem::activateWindow(configDialog->winId()); +} + +bool PlasmaApp::mainViewOnTop() const +{ + bool onTop = false; + + QSet ownWindows; + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + ownWindows.insert(widget->winId()); + } + + //search if the main view is actually one of the widgets on top, show the panel only in this case + QList windows = KWindowSystem::stackingOrder(); + for (int i = windows.size() - 1; i >= 0; --i) { + WId window = windows.at(i); + + if (window == m_mainView->winId()) { + onTop = true; + break; + } else if (!ownWindows.contains(window)) { + break; + } + } + + return onTop; +} + +bool PlasmaApp::eventFilter(QObject * watched, QEvent *event) +{ + if (watched == m_widgetExplorerView && event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Escape) { + closeWidgetExplorer(); + } + } else if (watched == m_widgetExplorerView && event->type() == QEvent::Resize) { + m_widgetExplorer->resize(m_widgetExplorerView->contentsRect().size()); + } else if (!m_isDesktop && watched == m_mainView && event->type() == QEvent::Close) { + exit(); + } + return false; +} + +bool PlasmaApp::x11EventFilter(XEvent *event) +{ + + if (m_controlBar && m_autoHideControlBar && !m_controlBar->isVisible() && event->xcrossing.window == m_unhideTrigger && + (event->xany.send_event != True && event->type == EnterNotify)) { + //delayed show + if (!m_glowBar && KWindowSystem::compositingActive() && !m_triggerZone.contains(QCursor::pos())) { + Plasma::Direction direction = Plasma::locationToDirection(m_controlBar->location()); + m_glowBar = new GlowBar(direction, m_triggerZone); + m_glowBar->show(); + XMoveResizeWindow(QX11Info::display(), m_unhideTrigger, m_triggerZone.x(), m_triggerZone.y(), m_triggerZone.width(), m_triggerZone.height()); + + //FIXME: This is ugly as hell but well, yeah + if (!m_mousePollTimer) { + m_mousePollTimer = new QTimer(this); + } + + disconnect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll())); + connect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll())); + m_mousePollTimer->start(200); + } else { + m_unHideTimer->start(400); + } + } else if ((event->xany.send_event != True && event->type == FocusOut)) { + QTimer::singleShot(100, this, SLOT(lowerMainView())); + } else if (m_controlBar && m_autoHideControlBar && m_controlBar->isVisible() && + (event->xany.send_event != True && event->type == LeaveNotify)) { + if (m_unHideTimer) { + m_unHideTimer->start(200); + } + } + + return KUniqueApplication::x11EventFilter(event); +} + +bool PlasmaApp::hasForegroundWindows() const +{ + return QApplication::activeWindow(); +} + +void PlasmaApp::lowerMainView() +{ + if (m_isDesktop && !hasForegroundWindows()) { + KWindowSystem::lowerWindow(m_mainView->winId()); + } + if (m_shadowWindow) { + KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepAbove); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow); + } +} + +void PlasmaApp::controlBarVisibilityUpdate() +{ + if (!m_controlBar) { + return; + } + + if (!m_autoHideControlBar) { + setControlBarVisible(true); + + if (m_shadowWindow && m_shadowWindow->isValid()) { + Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location()); + m_shadowWindow->show(); + if (hasForegroundWindows()) { + KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove); + } else { + KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepAbove); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow); + } + KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true); + } + + return; + } else if (m_autoHideControlBar && hasForegroundWindows() && m_controlBar->isVisible()) { + return; + } + + if (sender() != m_unHideTimer) { + m_unHideTimer->start(200); + return; + } + + //would be nice to avoid this + QPoint cursorPos = QCursor::pos(); + + if (m_triggerZone.adjusted(-1, -1, 1, 1).contains(cursorPos) || hasForegroundWindows()) { + if (!m_controlBar->isVisible()) { + destroyUnHideTrigger(); + Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location()); + setControlBarVisible(true); + } + + if (m_shadowWindow && m_shadowWindow->isValid()) { + Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location()); + if (hasForegroundWindows()) { + KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow); + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove); + } + m_shadowWindow->show(); + KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true); + } + } else if (!m_controlBar->geometry().contains(cursorPos) && !mainViewOnTop() && !hasForegroundWindows()) { + Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location()); + m_controlBar->hide(); + + if (m_shadowWindow) { + Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location()); + m_shadowWindow->hide(); + } + + createUnhideTrigger(); + } +} + +void PlasmaApp::showControlBar() +{ + setControlBarVisible(true); +} + +void PlasmaApp::hideControlBar() +{ + setControlBarVisible(false); +} + +void PlasmaApp::setControlBarVisible(bool visible) +{ + if (!m_controlBar || m_controlBar->isVisible() == visible) { + return; + } + + if (visible) { + destroyUnHideTrigger(); + Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location()); + m_controlBar->setWindowFlags(m_mainView->windowFlags() | Qt::FramelessWindowHint); + m_controlBar->setFrameShape(QFrame::NoFrame); + m_controlBar->show(); + KWindowSystem::setOnAllDesktops(m_controlBar->winId(), m_isDesktop); + unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove; + KWindowSystem::setState(m_controlBar->effectiveWinId(), state); + KWindowSystem::setType(m_controlBar->effectiveWinId(), NET::Dock); + + if (m_shadowWindow && m_shadowWindow->isValid()) { + Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location()); + m_shadowWindow->show(); + if (!m_autoHideControlBar) { + KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow); + } + KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true); + } + } else if (!m_autoHideControlBar) { + Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location()); + m_controlBar->hide(); + createUnhideTrigger(); + + if (m_shadowWindow) { + Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location()); + m_shadowWindow->hide(); + } + } +} + +void PlasmaApp::toggleControlBarVisibility() +{ + setControlBarVisible(!m_controlBar->isVisible()); +} + +void PlasmaApp::unhideHintMousePoll() +{ +#ifdef Q_WS_X11 + QPoint mousePos = QCursor::pos(); + m_glowBar->updateStrength(mousePos); + + if (!m_unhideTriggerGeom.contains(mousePos)) { + //kDebug() << "hide the glow"; + if (m_mousePollTimer) { + m_mousePollTimer->stop(); + disconnect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll())); + } + + delete m_glowBar; + m_glowBar = 0; + XMoveResizeWindow(QX11Info::display(), m_unhideTrigger, m_unhideTriggerGeom.x(), m_unhideTriggerGeom.y(), m_unhideTriggerGeom.width(), m_unhideTriggerGeom.height()); + } else { + m_unHideTimer->start(0); + } +#endif +} + +void PlasmaApp::createUnhideTrigger() +{ +#ifdef Q_WS_X11 + //kDebug() << m_unhideTrigger << None; + if (!m_autoHideControlBar || m_unhideTrigger != None || !m_controlBar || m_controlBar->isVisible()) { + return; + } + + int actualWidth = 1; + int actualHeight = 1; + int triggerWidth = 1; + int triggerHeight = 1; + + if (KWindowSystem::compositingActive()) { + triggerWidth = 30; + triggerHeight = 30; + } + + QPoint actualTriggerPoint; + QPoint triggerPoint = actualTriggerPoint = QPoint(qMax(0, m_controlBar->pos().x()), qMax(0, m_controlBar->pos().y())); + + switch (m_controlBar->location()) { + case Plasma::TopEdge: + actualWidth = triggerWidth = m_controlBar->width() - 1; + actualHeight = 1; + triggerPoint += QPoint(1, 0); + + break; + case Plasma::BottomEdge: + actualWidth = triggerWidth = m_controlBar->width() - 1; + actualTriggerPoint = triggerPoint = m_controlBar->geometry().bottomLeft() + QPoint(1, 0); + + break; + case Plasma::RightEdge: + actualHeight = triggerHeight = m_controlBar->height() - 1; + actualTriggerPoint = triggerPoint = m_controlBar->geometry().topRight() + QPoint(0, 1); + + break; + case Plasma::LeftEdge: + actualHeight = triggerHeight = m_controlBar->height() - 1; + triggerPoint += QPoint(0, -1); + + break; + default: + // no hiding unless we're on an edge. + return; + break; + } + + + XSetWindowAttributes attributes; + attributes.override_redirect = True; + attributes.event_mask = EnterWindowMask; + + + attributes.event_mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask | + KeyPressMask | ButtonPressMask | + ButtonReleaseMask | ButtonMotionMask | + KeymapStateMask | VisibilityChangeMask | + StructureNotifyMask | ResizeRedirectMask | + SubstructureNotifyMask | + SubstructureRedirectMask | FocusChangeMask | + PropertyChangeMask | ColormapChangeMask | OwnerGrabButtonMask; + + unsigned long valuemask = CWOverrideRedirect | CWEventMask; + m_unhideTrigger = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), + triggerPoint.x(), triggerPoint.y(), triggerWidth, triggerHeight, + 0, CopyFromParent, InputOnly, CopyFromParent, + valuemask, &attributes); + + XMapWindow(QX11Info::display(), m_unhideTrigger); + m_unhideTriggerGeom = QRect(triggerPoint, QSize(triggerWidth, triggerHeight)); + m_triggerZone = QRect(actualTriggerPoint, QSize(actualWidth, actualHeight)); +#endif +} + +void PlasmaApp::destroyUnHideTrigger() +{ +#ifdef Q_WS_X11 + if (m_unhideTrigger != None) { + XDestroyWindow(QX11Info::display(), m_unhideTrigger); + m_unhideTrigger = None; + m_triggerZone = m_unhideTriggerGeom = QRect(); + } +#endif +} + +#include "plasmaapp.moc" diff --git a/plasma/netbook/shell/plasmaapp.h b/plasma/netbook/shell/plasmaapp.h new file mode 100644 index 00000000..8374e535 --- /dev/null +++ b/plasma/netbook/shell/plasmaapp.h @@ -0,0 +1,158 @@ +/* + * Copyright 2006-2008 Aaron Seigo + * Copyright 2009 Marco Martin + * + * 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, + * 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_APP_H +#define PLASMA_APP_H + + +#include + +#include + +#ifdef Q_WS_X11 +#include +#include +#endif + +namespace Plasma +{ + class Containment; + class Corona; + class Dialog; + class View; + class WidgetExplorer; +} // namespace Plasma + +class NetView; +class NetCorona; +class QTimer; +class GlowBar; +class ShadowWindow; + +namespace Kephal +{ + class Screen; +} + +class PlasmaApp : public KUniqueApplication +{ + Q_OBJECT +public: + ~PlasmaApp(); + + static PlasmaApp* self(); + static bool hasComposite(); + + void suspendStartup(bool suspend); + Plasma::Corona* corona(); + + /** + * Sets the view to be a desktop window if @p isDesktop is true + * or an ordinary window otherwise. + * + * Desktop windows are displayed beneath all other windows, have + * no window decoration and occupy the full size of the screen. + * + * The default behaviour is not to register the view as the desktop + * window. + */ + void setIsDesktop(bool isDesktop); + + NetView *controlBar() const; + + NetView *mainView() const; + + QWidget *widgetExplorer() const; + + /** + * Returns true if this widget is currently a desktop window. + * See setIsDesktop() + */ + bool isDesktop() const; + + void showWidgetExplorer(Plasma::Containment *containment); + +public Q_SLOTS: + void setAutoHideControlBar(bool autoHide); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + bool x11EventFilter(XEvent *event); + //true if the application has an active window + bool hasForegroundWindows() const; + //more strict than hasForegroundWindows, the mainview has to be not only active, but also on top of other windows + bool mainViewOnTop() const; + +private: + PlasmaApp(); + void reserveStruts(); + void createUnhideTrigger(); + void destroyUnHideTrigger(); + +private Q_SLOTS: + void cleanup(); + void syncConfig(); + void positionPanel(); + void createView(Plasma::Containment *containment); + void adjustSize(Kephal::Screen *); + void controlBarMoved(const NetView *controlBar); + void showWidgetExplorer(); + void widgetExplorerDestroyed(); + void closeWidgetExplorer(); + void mainContainmentActivated(); + //TODO: probably those functions can go in netview + void controlBarVisibilityUpdate(); + void showControlBar(); + void hideControlBar(); + void setControlBarVisible(bool visible); + void toggleControlBarVisibility(); + void lowerMainView(); + void configureContainment(Plasma::Containment *containment); + void updateToolBoxVisibility(bool visible); + void unhideHintMousePoll(); + void wallpaperCheckedIn(); + void wallpaperCheckInTimeout(); + void checkShadow(); + +Q_SIGNALS: + void controlBarChanged(); + +private: + NetCorona *m_corona; + Plasma::Dialog *m_widgetExplorerView; + Plasma::WidgetExplorer *m_widgetExplorer; +#ifdef Q_WS_X11 + Window m_unhideTrigger; + QRect m_triggerZone; + QRect m_unhideTriggerGeom; +#endif + GlowBar *m_glowBar; + QTimer *m_mousePollTimer; + NetView *m_controlBar; + NetView *m_mainView; + bool m_isDesktop; + bool m_autoHideControlBar; + QTimer *m_unHideTimer; + ShadowWindow *m_shadowWindow; + int m_startupSuspendWaitCount; +}; + +#endif // multiple inclusion guard + diff --git a/plasma/netbook/shell/scripting/netbookscriptengine.cpp b/plasma/netbook/shell/scripting/netbookscriptengine.cpp new file mode 100644 index 00000000..7c538fe2 --- /dev/null +++ b/plasma/netbook/shell/scripting/netbookscriptengine.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2010 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netbookscriptengine.h" + +#include + +#include +#include + +#include "panel.h" +#include "newspaper.h" + +namespace WorkspaceScripting +{ + +NetbookScriptEngine::NetbookScriptEngine(Plasma::Corona *corona, QObject *parent) + : ScriptEngine(corona, parent) +{ +} + +QScriptValue NetbookScriptEngine::wrap(Plasma::Containment *c) +{ + Containment *wrapper; + + if (c->name() == "newspaper") { + wrapper = new Newspaper(c); + } else if (isPanel(c)) { + wrapper = new NetPanel(c); + } else { + wrapper = new Containment(c); + } + + QScriptValue v = wrap(wrapper); + v.setProperty("addWidgetAt", newFunction(Newspaper::addWidgetAt)); + return v; +} + +QScriptValue NetbookScriptEngine::wrap(Containment *c) +{ + return ScriptEngine::wrap(c); +} + +} + +#include "netbookscriptengine.moc" + diff --git a/plasma/netbook/shell/scripting/netbookscriptengine.h b/plasma/netbook/shell/scripting/netbookscriptengine.h new file mode 100644 index 00000000..d5d268ac --- /dev/null +++ b/plasma/netbook/shell/scripting/netbookscriptengine.h @@ -0,0 +1,42 @@ +/* + * Copyright 2010 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETBOOKSCRIPTENGINE_H +#define NETBOOKSCRIPTENGINE_H + +#include + +namespace WorkspaceScripting +{ + +class NetbookScriptEngine : public ScriptEngine +{ + Q_OBJECT + +public: + NetbookScriptEngine(Plasma::Corona *corona, QObject *parent = 0); + QScriptValue wrap(Plasma::Containment *c); + QScriptValue wrap(Containment *c); +}; + +} + +#endif + diff --git a/plasma/netbook/shell/scripting/newspaper.cpp b/plasma/netbook/shell/scripting/newspaper.cpp new file mode 100644 index 00000000..0f02b8a9 --- /dev/null +++ b/plasma/netbook/shell/scripting/newspaper.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2009 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "newspaper.h" + +#include + +#include +#include + +#include "netview.h" +#include "plasmaapp.h" +#include +#include + +namespace WorkspaceScripting +{ + +Newspaper::Newspaper(Plasma::Containment *containment, QObject *parent) + : Containment(containment, parent) +{ +} + +Newspaper::~Newspaper() +{ +} + +QScriptValue Newspaper::addWidgetAt(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() < 3) { + return context->throwError(i18n("widgetById requires a name of a widget or a widget object, with the row and column coordinates")); + } + + Containment *c = qobject_cast(context->thisObject().toQObject()); + + if (!c || !c->containment()) { + return engine->undefinedValue(); + } + + QScriptValue v = context->argument(0); + int row = context->argument(1).toInt32(); + int column = context->argument(2).toInt32(); + Plasma::Applet *applet = 0; + if (v.isString()) { + kWarning()<containment(), "addApplet", Qt::DirectConnection, + Q_RETURN_ARG(Plasma::Applet *, applet), + Q_ARG(QString, v.toString()), + Q_ARG(int, row), + Q_ARG(int, column)); + if (applet) { + ScriptEngine *env = ScriptEngine::envFor(engine); + return env->wrap(applet); + } + } else if (Widget *widget = qobject_cast(v.toQObject())) { + applet = widget->applet(); + QMetaObject::invokeMethod(c->containment(), "addApplet", Qt::DirectConnection, + Q_ARG(Plasma::Applet *, applet), + Q_ARG(int, row), + Q_ARG(int, column)); + c->containment()->addApplet(applet); + return v; + } + + return engine->undefinedValue(); +} + +} + +#include "newspaper.moc" + + diff --git a/plasma/netbook/shell/scripting/newspaper.h b/plasma/netbook/shell/scripting/newspaper.h new file mode 100644 index 00000000..6b434ccc --- /dev/null +++ b/plasma/netbook/shell/scripting/newspaper.h @@ -0,0 +1,67 @@ +/* + * Copyright 2009 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NEWSPAPER_H +#define NEWSPAPER_H + +#include +#include + +#include + +namespace WorkspaceScripting +{ + +class Newspaper : public Containment +{ + Q_OBJECT + Q_PROPERTY(QStringList configKeys READ configKeys) + Q_PROPERTY(QStringList configGroups READ configGroups) + Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup) + + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString type READ type) + Q_PROPERTY(QString formFactor READ formFactor) + Q_PROPERTY(QList widgetIds READ widgetIds) + Q_PROPERTY(int screen READ screen WRITE setScreen) + Q_PROPERTY(int desktop READ desktop WRITE setDesktop) + Q_PROPERTY(int id READ id) + + +public: + Newspaper(Plasma::Containment *containment, QObject *parent = 0); + ~Newspaper(); + + static QScriptValue addWidgetAt(QScriptContext *context, QScriptEngine *engine); + +public Q_SLOTS: + void remove() { Containment::remove(); } + void showConfigurationInterface() { Containment::showConfigurationInterface(); } + + // from the applet interface + QVariant readConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readConfig(key, def); } + void writeConfig(const QString &key, const QVariant &value) { Applet::writeConfig(key, value); } + void reloadConfig() { Applet::reloadConfig(); } +}; + +} + +#endif + diff --git a/plasma/netbook/shell/scripting/panel.cpp b/plasma/netbook/shell/scripting/panel.cpp new file mode 100644 index 00000000..9d45a35e --- /dev/null +++ b/plasma/netbook/shell/scripting/panel.cpp @@ -0,0 +1,172 @@ +/* + * Copyright 2009 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "panel.h" + + +#include +#include + +#include "netview.h" +#include "plasmaapp.h" +#include +#include + +namespace WorkspaceScripting +{ + +NetPanel::NetPanel(Plasma::Containment *containment, QObject *parent) + : Containment(containment, parent) +{ +} + +NetPanel::~NetPanel() +{ +} + +QString NetPanel::location() const +{ + Plasma::Containment *c = containment(); + if (!c) { + return "floating"; + } + + switch (c->location()) { + case Plasma::Floating: + return "floating"; + break; + case Plasma::Desktop: + return "desktop"; + break; + case Plasma::FullScreen: + return "fullscreen"; + break; + case Plasma::TopEdge: + return "top"; + break; + case Plasma::BottomEdge: + return "bottom"; + break; + case Plasma::LeftEdge: + return "left"; + break; + case Plasma::RightEdge: + return "right"; + break; + } + + return "floating"; +} + +void NetPanel::setLocation(const QString &locationString) +{ + Plasma::Containment *c = containment(); + if (!c) { + return; + } + + const QString lower = locationString.toLower(); + Plasma::Location loc = Plasma::Floating; + if (lower == "desktop") { + loc = Plasma::Desktop; + } else if (lower == "fullscreen") { + loc = Plasma::FullScreen; + } else if (lower == "top") { + loc = Plasma::TopEdge; + } else if (lower == "bottom") { + loc = Plasma::BottomEdge; + } else if (lower == "left") { + loc = Plasma::LeftEdge; + } else if (lower == "right") { + loc = Plasma::RightEdge; + } + + c->setLocation(loc); +} + +NetView *NetPanel::panel() const +{ + Plasma::Containment *c = containment(); + if (!c) { + return 0; + } + + return PlasmaApp::self()->controlBar(); +} + +int NetPanel::height() const +{ + Plasma::Containment *c = containment(); + if (!c) { + return 0; + } + + return c->formFactor() == Plasma::Vertical ? c->size().width() + : c->size().height(); +} + +void NetPanel::setHeight(int height) +{ + Plasma::Containment *c = containment(); + if (height < 16 || !c) { + return; + } + + NetView *v = panel(); + if (v) { + QRect screen = c->corona()->screenGeometry(v->screen()); + QSizeF size = c->size(); + const int max = (c->formFactor() == Plasma::Vertical ? screen.width() : screen.height()) / 3; + height = qBound(16, height, max); + + if (c->formFactor() == Plasma::Vertical) { + size.setWidth(height); + } else { + size.setHeight(height); + } + + c->resize(size); + c->setMinimumSize(size); + c->setMaximumSize(size); + } +} + +bool NetPanel::autoHide() const +{ + NetView *v = panel(); + if (v) { + return v->autoHide(); + } + + return false; +} + +void NetPanel::setAutoHide(const bool autoHide) +{ + NetView *v = panel(); + if (v && autoHide != v->autoHide()) { + v->setAutoHide(autoHide); + } +} + +} + +#include "panel.moc" + diff --git a/plasma/netbook/shell/scripting/panel.h b/plasma/netbook/shell/scripting/panel.h new file mode 100644 index 00000000..d0a56840 --- /dev/null +++ b/plasma/netbook/shell/scripting/panel.h @@ -0,0 +1,82 @@ +/* + * Copyright 2009 Aaron Seigo + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PANEL_NETBOOK +#define PANEL_NETBOOK + + +#include + +class NetView; + +namespace WorkspaceScripting +{ + +class NetPanel : public Containment +{ + Q_OBJECT + Q_PROPERTY(QStringList configKeys READ configKeys) + Q_PROPERTY(QStringList configGroups READ configGroups) + Q_PROPERTY(QStringList currentConfigGroup WRITE setCurrentConfigGroup READ currentConfigGroup) + + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString type READ type) + Q_PROPERTY(QString formFactor READ formFactor) + Q_PROPERTY(QList widgetIds READ widgetIds) + Q_PROPERTY(int screen READ screen WRITE setScreen) + Q_PROPERTY(int desktop READ desktop WRITE setDesktop) + Q_PROPERTY(QString location READ location WRITE setLocation) + Q_PROPERTY(int id READ id) + Q_PROPERTY(bool locked READ locked WRITE setLocked) + + // panel properties + Q_PROPERTY(int height READ height WRITE setHeight) + Q_PROPERTY(bool autoHide READ autoHide WRITE setAutoHide) + +public: + NetPanel(Plasma::Containment *containment, QObject *parent = 0); + ~NetPanel(); + + QString location() const; + void setLocation(const QString &location); + + int height() const; + void setHeight(int height); + + bool autoHide() const; + void setAutoHide(const bool autoHide); + +public Q_SLOTS: + void remove() { Containment::remove(); } + void showConfigurationInterface() { Containment::showConfigurationInterface(); } + + // from the applet interface + QVariant readConfig(const QString &key, const QVariant &def = QString()) const { return Applet::readConfig(key, def); } + void writeConfig(const QString &key, const QVariant &value) { Applet::writeConfig(key, value); } + void reloadConfig() { Applet::reloadConfig(); } + +private: + NetView *panel() const; +}; + +} + +#endif + diff --git a/plasma/screensaver/CMakeLists.txt b/plasma/screensaver/CMakeLists.txt new file mode 100644 index 00000000..514c8565 --- /dev/null +++ b/plasma/screensaver/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(containments) +if(NOT WIN32) +add_subdirectory(shell) +endif(NOT WIN32) + + diff --git a/plasma/screensaver/containments/CMakeLists.txt b/plasma/screensaver/containments/CMakeLists.txt new file mode 100644 index 00000000..48879e90 --- /dev/null +++ b/plasma/screensaver/containments/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(screensaver) + diff --git a/plasma/screensaver/containments/screensaver/CMakeLists.txt b/plasma/screensaver/containments/screensaver/CMakeLists.txt new file mode 100644 index 00000000..b18c2dbf --- /dev/null +++ b/plasma/screensaver/containments/screensaver/CMakeLists.txt @@ -0,0 +1,10 @@ +set(desktop_SRCS + desktop.cpp + ../../../desktop/toolboxes/internaltoolbox.cpp) + +kde4_add_plugin(plasma_containment_saverdesktop ${desktop_SRCS}) +target_link_libraries(plasma_containment_saverdesktop ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS}) + +install(TARGETS plasma_containment_saverdesktop DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containment-saverdesktop.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + diff --git a/plasma/screensaver/containments/screensaver/Messages.sh b/plasma/screensaver/containments/screensaver/Messages.sh new file mode 100755 index 00000000..5bd4d899 --- /dev/null +++ b/plasma/screensaver/containments/screensaver/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_applet_saverdesktop.pot diff --git a/plasma/screensaver/containments/screensaver/desktop.cpp b/plasma/screensaver/containments/screensaver/desktop.cpp new file mode 100644 index 00000000..fff0e98e --- /dev/null +++ b/plasma/screensaver/containments/screensaver/desktop.cpp @@ -0,0 +1,116 @@ +/* +* Copyright 2007 by Aaron Seigo +* Copyright 2008 by Chani Armitage +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "desktop.h" + +#include + +#include + +#include +#include + +//#define DEBUG_CONSOLE +#ifdef DEBUG_CONSOLE +#include +#include +#include +#endif + +#include <../../../desktop/toolboxes/internaltoolbox.h> + +using namespace Plasma; + +SaverDesktop::SaverDesktop(QObject *parent, const QVariantList &args) + : Containment(parent, args), + m_lockDesktopAction(0), + m_appletBrowserAction(0) +{ + setContainmentType(CustomContainment); + connect(this, SIGNAL(appletAdded(Plasma::Applet*,QPointF)), SLOT(newApplet(Plasma::Applet*,QPointF))); + setHasConfigurationInterface(true); +} + +SaverDesktop::~SaverDesktop() +{ +} + +void SaverDesktop::init() +{ + Containment::init(); + + // trigger the creation of the toolbox. ugly! :) but nicer than having our own toolbox plugin + // just for the screensaver? + QAction *dummy = new QAction(this); + addToolBoxAction(dummy); + removeToolBoxAction(dummy); + delete dummy; + + Plasma::AbstractToolBox *tools = toolBox(); + InternalToolBox *internal = dynamic_cast(tools); + +#ifdef DEBUG_CONSOLE + Plasma::Frame *f = new Plasma::Frame(this); + f->setGeometry(QRectF(100, 100, 500, 500)); + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(f); + l->addItem(msgs); + Plasma::TextBrowser *msgs new Plasma::TextBrowser(this); + msgs->setText(QString("got %1 with %2 actions").arg((int)internal).arg(tools ? + tools->metaObject()->className() : "NADA")); +#endif + + if (internal) { + // remove all the actions pre-made for us here + foreach (QAction *action, internal->actions()) { + internal->removeTool(action); + } + } + + // add our own actions. huzzah. + QAction *leave = corona()->action("unlock desktop"); + if (leave) { + addToolBoxAction(leave); + } + + QAction *lock = corona()->action("unlock widgets"); + if (lock) { + addToolBoxAction(lock); + } + + QAction *a = action("configure"); + if (a) { + a->setText(i18n("Settings")); + addToolBoxAction(a); + } + + a = action("add widgets"); + if (a) { + addToolBoxAction(a); + } +} + +void SaverDesktop::newApplet(Plasma::Applet *applet, const QPointF &pos) +{ + Q_UNUSED(pos); + applet->installSceneEventFilter(this); +} + +K_EXPORT_PLASMA_APPLET(saverdesktop, SaverDesktop) + +#include "desktop.moc" diff --git a/plasma/screensaver/containments/screensaver/desktop.h b/plasma/screensaver/containments/screensaver/desktop.h new file mode 100644 index 00000000..45d68680 --- /dev/null +++ b/plasma/screensaver/containments/screensaver/desktop.h @@ -0,0 +1,53 @@ +/* +* Copyright 2007 by Aaron Seigo +* Copyright 2008 by Chani Armitage +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* 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 Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef PLASMA_SAVERDESKTOP_H +#define PLASMA_SAVERDESKTOP_H + +#include +#include + +#include + +class QAction; + +/** + * SaverDesktop + * + * This is a minimal containment for plasma-overlay. + */ + +class SaverDesktop : public Plasma::Containment +{ + Q_OBJECT + +public: + SaverDesktop(QObject *parent, const QVariantList &args); + ~SaverDesktop(); + void init(); + +private slots: + void newApplet(Plasma::Applet *applet, const QPointF &pos); + +private: + QAction *m_lockDesktopAction; + QAction *m_appletBrowserAction; +}; + +#endif diff --git a/plasma/screensaver/containments/screensaver/plasma-containment-saverdesktop.desktop b/plasma/screensaver/containments/screensaver/plasma-containment-saverdesktop.desktop new file mode 100644 index 00000000..eb49a71f --- /dev/null +++ b/plasma/screensaver/containments/screensaver/plasma-containment-saverdesktop.desktop @@ -0,0 +1,95 @@ +[Desktop Entry] +Name=SaverDesktop +Name[ar]=حافظ سطح المكتب +Name[ast]=Curiapantalles +Name[be@latin]=SaverDesktop +Name[bn]=SaverDesktop +Name[bn_IN]=SaverDesktop +Name[bs]=čuvar na površi +Name[ca]=SaverDesktop +Name[ca@valencia]=SaverDesktop +Name[cs]=Spořič plochy +Name[csb]=SaverDesktop +Name[da]=SaverDesktop +Name[de]=SaverDesktop +Name[el]=Προφύλαξη επιφάνειας εργασίας +Name[en_GB]=SaverDesktop +Name[eo]=SaverDesktop +Name[es]=Salvapantallas +Name[et]=Ekraanisäästja-töölaud +Name[eu]=SaverDesktop +Name[fi]=Säästäjätyöpöytä +Name[fr]=Économiseur d'écran +Name[fy]=SaverDesktop +Name[ga]=SaverDesktop +Name[gl]=SaverDesktop +Name[gu]=સર્વરડેસ્કટોપ +Name[he]=SaverDesktop +Name[hi]=सेवरडेस्कटॉप +Name[hne]=सेवर-डेस्कटाप +Name[hr]=Spremač radne površine +Name[hu]=Tárolóasztal +Name[ia]=SaverDesktop +Name[id]=Penyimpan Desktop +Name[is]=Skjáborð +Name[ja]=セーバーデスクトップ +Name[kk]=Үстел сақтағышы +Name[km]=SaverDesktop +Name[kn]=ಉಳಿಕೆಗಾರ ಗಣಕತೆರೆ +Name[ko]=SaverDesktop +Name[ku]=SermasêDîmenderParêzê +Name[lt]=SaverDesktop +Name[lv]=SaudzētājaDarbvirsma +Name[mai]=SaverDesktop +Name[ml]=സേവര്‍പണിയിടം +Name[mr]=SaverDesktop +Name[nb]=SparerSkrivebord +Name[nds]=SekerSchriefdisch +Name[nl]=SaverDesktop +Name[nn]=SaverDesktop +Name[or]=ସର୍ଭର ଡ଼େସ୍କଟପ +Name[pa]=ਸੇਵਰਡੈਸਕਟਾਪ +Name[pl]=Wygaszacz na pulpicie +Name[pt]=Ecrã de Protecção +Name[pt_BR]=Proteção da área de trabalho +Name[ro]=SaverDesktop +Name[ru]=Рабочий стол в качестве хранителя экрана +Name[si]=SaverDesktop +Name[sk]=Šetrič plochy +Name[sl]=OhranjevalnikNamizje +Name[sr]=чувар на површи +Name[sr@ijekavian]=чувар на површи +Name[sr@ijekavianlatin]=čuvar na površi +Name[sr@latin]=čuvar na površi +Name[sv]=Skrivbordsunderlägg +Name[ta]=பணிமேசை காப்பு +Name[te]=సేవిక‍డెస్‍క్ టాప్ +Name[tg]=Мизи корӣ, монанди пардаи экран +Name[th]=รักษาจอภาพ +Name[tr]=Ekran Koruyucu Masaüstü +Name[ug]=ئېكران قوغداش ئۈستەلئۈستى +Name[uk]=Зберігач стільниці +Name[wa]=SaverDesktop +Name[x-test]=xxSaverDesktopxx +Name[zh_CN]=屏幕保护桌面 +Name[zh_TW]=保護程式桌面 +Icon=Plasma +Type=Service +X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +X-Plasma-ContainmentCategories=screensaver +NoDisplay=true + +X-KDE-Library=plasma_containment_saverdesktop +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=plasma-devel@kde.org +X-KDE-PluginInfo-Name=saverdesktop +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Containments +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-Plasma-Requires-FileDialog=Unused +X-Plasma-Requires-LaunchApp=Unused + diff --git a/plasma/screensaver/shell/BackgroundDialog.ui b/plasma/screensaver/shell/BackgroundDialog.ui new file mode 100644 index 00000000..c6b0aa7a --- /dev/null +++ b/plasma/screensaver/shell/BackgroundDialog.ui @@ -0,0 +1,108 @@ + + + BackgroundDialog + + + + 0 + 0 + 572 + 600 + + + + + 0 + 600 + + + + + 200 + 700 + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 17 + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Wallpaper + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_wallpaperMode + + + + + + + + 1 + 0 + + + + + 150 + 0 + + + + + + + + + + + 0 + 0 + + + + + + + + + diff --git a/plasma/screensaver/shell/CMakeLists.txt b/plasma/screensaver/shell/CMakeLists.txt new file mode 100644 index 00000000..5c52da69 --- /dev/null +++ b/plasma/screensaver/shell/CMakeLists.txt @@ -0,0 +1,39 @@ +include_directories( + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kdm + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/plasmagenericshell + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/ + ${CMAKE_BINARY_DIR}/ksmserver/screenlocker/greeter/ + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcheckpass +) + +set(plasma-overlay_SRCS + backgrounddialog.cpp + main.cpp + plasmaapp.cpp + savercorona.cpp + saverview.cpp + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/greeter.cpp + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/sessions.cpp +) + +kde4_add_ui_files(plasma-overlay_SRCS BackgroundDialog.ui) + +kde4_add_kcfg_files(plasma-overlay_SRCS ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc) + +set(plasmaapp_dbusXML org.kde.plasma-overlay.App.xml) +#qt4_generate_dbus_interface(plasmaapp.h ${plasmaapp_dbusXML} OPTIONS -S -M) +qt4_add_dbus_adaptor(plasma-overlay_SRCS ${plasmaapp_dbusXML} plasmaapp.h PlasmaApp) + +kde4_add_executable(plasma-overlay ${plasma-overlay_SRCS}) + +target_link_libraries(plasma-overlay ${KDE4_PLASMA_LIBS} kworkspace ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} + ${X11_X11_LIB} plasmagenericshell ${QT_QTDECLARATIVE_LIBRARY} kdeclarative) +if(X11_Xrender_FOUND) + target_link_libraries(plasma-overlay ${X11_Xrender_LIB}) +endif(X11_Xrender_FOUND) +set_target_properties(plasma-overlay PROPERTIES OUTPUT_NAME plasma-overlay) + +install(TARGETS plasma-overlay ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES plasma-overlayrc DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/plasma/screensaver/shell/Messages.sh b/plasma/screensaver/shell/Messages.sh new file mode 100755 index 00000000..b79d051d --- /dev/null +++ b/plasma/screensaver/shell/Messages.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma-overlay.pot +rm -f rc.cpp + diff --git a/plasma/screensaver/shell/backgrounddialog.cpp b/plasma/screensaver/shell/backgrounddialog.cpp new file mode 100644 index 00000000..dc6ee8b0 --- /dev/null +++ b/plasma/screensaver/shell/backgrounddialog.cpp @@ -0,0 +1,211 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (C) 2007 Ivan Cukic + Copyright (c) 2008 by Petri Damsten + + 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. +*/ + +#include "backgrounddialog.h" + +//#include +//#include +//#include + +#include +//#include +//#include +//#include + +#include +#include +#include +#include +//#include + +#include "plasmaapp.h" +#include "plasmagenericshell/wallpaperpreview.h" + +#include "../../../libs/kworkspace/screenpreviewwidget.h" + +typedef QPair WallpaperInfo; +Q_DECLARE_METATYPE(WallpaperInfo) + + +BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::Containment *c, /*Plasma::View* view,*/ QWidget* parent) + : KDialog(parent), + m_wallpaper(0), + //m_view(view), + m_containment(c) +{ + //setWindowIcon(KIcon("preferences-desktop-wallpaper")); + setCaption(i18n("Background Settings")); + setButtons(Ok | Cancel | Apply); + + QWidget * main = new QWidget(this); + setupUi(main); + + // Size of monitor image: 200x186 + // Geometry of "display" part of monitor image: (23,14)-[151x115] + qreal previewRatio = (qreal)res.width() / (qreal)res.height(); + QSize monitorSize(200, int(200 * previewRatio)); + + connect(this, SIGNAL(finished(int)), this, SLOT(cleanup())); + connect(this, SIGNAL(okClicked()), this, SLOT(saveConfig())); + connect(this, SIGNAL(applyClicked()), this, SLOT(saveConfig())); + + setMainWidget(main); + reloadConfig(); + adjustSize(); + + if (c->view()) { + setParent(c->view()); + setBackgroundRole(QPalette::Window); + setAutoFillBackground(true); + move(c->view()->width()/2 - width()/2, y()); + } +} + +BackgroundDialog::~BackgroundDialog() +{ + cleanup(); +} + +void BackgroundDialog::cleanup() +{ + //FIXME could be bad if we get hidden and reshown + delete m_wallpaper; + m_wallpaper = 0; +} + +void BackgroundDialog::reloadConfig() +{ + // Wallpaper + disconnect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changeBackgroundMode(int))); + int wallpaperIndex = 0; + + bool doWallpaper = m_containment->drawWallpaper(); + m_wallpaperLabel->setVisible(doWallpaper); + m_wallpaperTypeLabel->setVisible(doWallpaper); + m_wallpaperMode->setVisible(doWallpaper); + m_wallpaperConfig->setVisible(doWallpaper); + + if (doWallpaper) { + // Load wallpaper plugins + QString currentPlugin; + QString currentMode; + + Plasma::Wallpaper *currentWallpaper = m_containment->wallpaper(); + if (currentWallpaper) { + currentPlugin = currentWallpaper->pluginName(); + currentMode = currentWallpaper->renderingMode().name(); + } + + const KPluginInfo::List plugins = Plasma::Wallpaper::listWallpaperInfo(); + m_wallpaperMode->clear(); + int i = 0; + QString placeholder = i18n("No Wallpaper"); + //m_wallpaperMode->addItem(KIcon(), i18n("No Wallpaper"), + // QVariant::fromValue(WallpaperInfo(QString(), QString()))); + foreach (const KPluginInfo& info, plugins) { + bool matches = info.pluginName() == currentPlugin; + const QList& modes = info.service()->actions(); + if (modes.count() > 0) { + foreach (const KServiceAction& mode, modes) { + m_wallpaperMode->addItem(KIcon(mode.icon()), mode.text(), + QVariant::fromValue(WallpaperInfo(info.pluginName(), mode.name()))); + if (matches && mode.name() == currentMode) { + wallpaperIndex = i; + } + ++i; + } + } else { + m_wallpaperMode->addItem(KIcon(info.icon()), info.name(), + QVariant::fromValue(WallpaperInfo(info.pluginName(), QString()))); + if (matches) { + wallpaperIndex = i; + } + ++i; + } + } + m_wallpaperMode->setCurrentIndex(wallpaperIndex); + changeBackgroundMode(wallpaperIndex); + } + + connect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changeBackgroundMode(int))); +} + +void BackgroundDialog::changeBackgroundMode(int mode) +{ + kDebug(); + QWidget* w = 0; + WallpaperInfo wallpaperInfo = m_wallpaperMode->itemData(mode).value(); + + if (!m_wallpaperConfig->layout()) { + new QVBoxLayout(m_wallpaperConfig); + } + + if (m_wallpaperConfig->layout()->count() > 0) { + delete dynamic_cast(m_wallpaperConfig->layout()->takeAt(0))->widget(); + } + + if (m_wallpaper && m_wallpaper->pluginName() != wallpaperInfo.first) { + delete m_wallpaper; + m_wallpaper = 0; + } + + if (wallpaperInfo.first.isEmpty()) { + return; + } + + if (!m_wallpaper) { + m_wallpaper = Plasma::Wallpaper::load(wallpaperInfo.first); + } + + if (m_wallpaper) { + m_wallpaper->setRenderingMode(wallpaperInfo.second); + KConfigGroup cfg = wallpaperConfig(wallpaperInfo.first); + kDebug() << "making a" << wallpaperInfo.first << "in mode" << wallpaperInfo.second; + m_wallpaper->restore(cfg); + w = m_wallpaper->createConfigurationInterface(m_wallpaperConfig); + } + + if (!w) { + w = new QWidget(m_wallpaperConfig); + } + + m_wallpaperConfig->layout()->addWidget(w); +} + +KConfigGroup BackgroundDialog::wallpaperConfig(const QString &plugin) +{ + Q_ASSERT(m_containment); + + //FIXME: we have details about the structure of the containment config duplicated here! + KConfigGroup cfg = m_containment->config(); + cfg = KConfigGroup(&cfg, "Wallpaper"); + return KConfigGroup(&cfg, plugin); +} + +void BackgroundDialog::saveConfig() +{ + // Wallpaper + QString wallpaperPlugin = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value().first; + QString wallpaperMode = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value().second; + + Plasma::Wallpaper *currentWallpaper = m_containment->wallpaper(); + if (currentWallpaper) { + KConfigGroup cfg = wallpaperConfig(currentWallpaper->pluginName()); + currentWallpaper->save(cfg); + } + + if (m_wallpaper) { + KConfigGroup cfg = wallpaperConfig(m_wallpaper->pluginName()); + m_wallpaper->save(cfg); + } + + m_containment->setWallpaper(wallpaperPlugin, wallpaperMode); +} diff --git a/plasma/screensaver/shell/backgrounddialog.h b/plasma/screensaver/shell/backgrounddialog.h new file mode 100644 index 00000000..04b507ae --- /dev/null +++ b/plasma/screensaver/shell/backgrounddialog.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2008 by Petri Damsten + + 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. +*/ + +#ifndef BACKGROUNDDIALOG_H +#define BACKGROUNDDIALOG_H + +#include +#include "ui_BackgroundDialog.h" + +namespace Plasma { + class Wallpaper; + class Containment; + class View; +} + +class ScreenPreviewWidget; + +class BackgroundDialog : public KDialog, public Ui::BackgroundDialog +{ + Q_OBJECT +public: + BackgroundDialog(const QSize &res, Plasma::Containment *containment, + /*Plasma::View *view,*/ QWidget *parent = 0); + ~BackgroundDialog(); + + void reloadConfig(); + +public slots: + void saveConfig(); + +private: + KConfigGroup wallpaperConfig(const QString &plugin); + +private slots: + void changeBackgroundMode(int mode); + void cleanup(); + +private: + Plasma::Wallpaper* m_wallpaper; + //Plasma::View* m_view; + Plasma::Containment* m_containment; + ScreenPreviewWidget* m_preview; +}; + +#endif // BACKGROUNDDIALOG_H diff --git a/plasma/screensaver/shell/main.cpp b/plasma/screensaver/shell/main.cpp new file mode 100644 index 00000000..a70bcdfc --- /dev/null +++ b/plasma/screensaver/shell/main.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2006-2007 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * 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, + * 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. If not, see . + */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include "plasmaapp.h" + +static const char description[] = I18N_NOOP( "Plasma widgets over the screensaver" ); +static const char version[] = "0.0"; + +//extern "C" +int main(int argc, char **argv) +{ + KAboutData aboutData("plasma-overlay",0 , ki18n("Plasma for the Screensaver"), + version, ki18n(description), KAboutData::License_GPL, + ki18n("Copyright 2006-2008, The KDE Team")); + aboutData.addAuthor(ki18n("Chani Armitage"), + ki18n("Author and maintainer"), + "chanika@gmail.com"); + aboutData.addAuthor(ki18n("Aaron J. Seigo"), + ki18n("Plasma Author and maintainer"), + "aseigo@kde.org"); + aboutData.addCredit(ki18n("John Lions"), + ki18n("In memory of his contributions, 1937-1998."), + 0, "http://en.wikipedia.org/wiki/John_Lions"); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("cheats",ki18n("Enables some cheats that are useful for debugging.")); + options.add("setup",ki18n("Start unlocked for configuration.")); + KCmdLineArgs::addCmdLineOptions(options); + + PlasmaApp *app = PlasmaApp::self(); + QApplication::setWindowIcon(KIcon("plasma")); + KGlobal::locale()->insertCatalog(QLatin1String( "libkworkspace" )); + KGlobal::locale()->insertCatalog(QLatin1String( "kscreenlocker_greet" )); + app->disableSessionManagement(); // I assume we'd never want a screensaver thing reppearing on login? + // This allow ksmserver to know when the applicaion has actually finished setting itself up. + // Crucial for blocking until it is ready, ensuring locking happens before sleep, e.g. + std::cout << "Locked at " << QDateTime::currentDateTime().toTime_t() << std::endl; + int rc = app->exec(); + delete app; + return rc; +} diff --git a/plasma/screensaver/shell/org.kde.plasma-overlay.App.xml b/plasma/screensaver/shell/org.kde.plasma-overlay.App.xml new file mode 100644 index 00000000..54724a89 --- /dev/null +++ b/plasma/screensaver/shell/org.kde.plasma-overlay.App.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/plasma/screensaver/shell/plasma-overlayrc b/plasma/screensaver/shell/plasma-overlayrc new file mode 100644 index 00000000..393e2c95 --- /dev/null +++ b/plasma/screensaver/shell/plasma-overlayrc @@ -0,0 +1,10 @@ +[KDE Action Restrictions][$i] +plasma/allow_configure_when_locked=false + +[Constraints] +FileDialog=false +LaunchApp=false + +[General] +ExcludeCategories=Windows and Tasks,Application Launchers + diff --git a/plasma/screensaver/shell/plasmaapp.cpp b/plasma/screensaver/shell/plasmaapp.cpp new file mode 100644 index 00000000..ad061602 --- /dev/null +++ b/plasma/screensaver/shell/plasmaapp.cpp @@ -0,0 +1,514 @@ +/* + * Copyright 2006 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * + * 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, + * 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. If not, see . + */ + +// plasma.loadEngine("hardware") +// LineGraph graph +// plasma.connect(graph, "hardware", "cpu"); + +#include "plasmaapp.h" + +#include "greeter.h" +#include "sessions.h" + +#include + +#ifndef _SC_PHYS_PAGES + #ifdef Q_OS_FREEBSD + #include + #include + #endif + + #ifdef Q_OS_NETBSD + #include + #include + #endif +#endif + +#include +#include +#include +#include +#include + +//#include +#include +#include +#include + +//#include + +#include +#include +#include + +#include "appadaptor.h" +#include "savercorona.h" +#include "saverview.h" +#include "backgrounddialog.h" + + +#include +#include +#include + +Atom tag; //FIXME should this be a member var or what? +Atom tag2; + +const unsigned char DIALOG = 1; //FIXME this is really bad code +const unsigned char VIEW = 2; + +Display* dpy = 0; +Colormap colormap = 0; +Visual *visual = 0; +bool composite = false; + +void checkComposite() +{ + dpy = XOpenDisplay(0); // open default display + if (!dpy) { + kError() << "Cannot connect to the X server" << endl; + return; + } + if( qgetenv( "KDE_SKIP_ARGB_VISUALS" ) == "1" ) + return; + + int screen = DefaultScreen(dpy); + int eventBase, errorBase; + + if (XRenderQueryExtension(dpy, &eventBase, &errorBase)) { + int nvi; + XVisualInfo templ; + templ.screen = screen; + templ.depth = 32; + templ.c_class = TrueColor; + XVisualInfo *xvi = XGetVisualInfo(dpy, + VisualScreenMask | VisualDepthMask | VisualClassMask, + &templ, &nvi); + for (int i = 0; i < nvi; ++i) { + XRenderPictFormat *format = XRenderFindVisualFormat(dpy, xvi[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) { + visual = xvi[i].visual; + colormap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone); + break; + } + } + XFree(xvi); + } + + composite = KWindowSystem::compositingActive() && colormap; + + kDebug() << (colormap ? "Plasma has an argb visual" : "Plasma lacks an argb visual") << visual << colormap; + kDebug() << ((KWindowSystem::compositingActive() && colormap) ? "Plasma can use COMPOSITE for effects" + : "Plasma is COMPOSITE-less") << "on" << dpy; +} + +PlasmaApp* PlasmaApp::self() +{ + if (!kapp) { + checkComposite(); + return new PlasmaApp(dpy, visual ? Qt::HANDLE(visual) : 0, colormap ? Qt::HANDLE(colormap) : 0); + } + + return qobject_cast(kapp); +} + +PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap) + : KUniqueApplication(display, visual, colormap), + m_corona(0), + m_configDialog(0) +{ + const char *uri = "org.kde.kscreenlocker"; + qmlRegisterType(uri, 1, 0, "GreeterItem"); + qmlRegisterType(uri, 1, 0, "KeyboardItem"); + qmlRegisterType(uri, 1, 0, "Sessions"); + qmlRegisterType(); + //load translations for libplasma + KGlobal::locale()->insertCatalog("libplasma"); + KGlobal::locale()->insertCatalog("plasmagenericshell"); + + new AppAdaptor(this); + QDBusConnection::sessionBus().registerObject("/App", this); + + //FIXME this is probably totally invalid + // Enlarge application pixmap cache + // Calculate the size required to hold background pixmaps for all screens. + // Add 10% so that other (smaller) pixmaps can also be cached. + int cacheSize = 0; + QDesktopWidget *desktop = QApplication::desktop(); + int numScreens = desktop->numScreens(); + for (int i = 0; i < numScreens; i++) { + QRect geometry = desktop->screenGeometry(i); + cacheSize += 4 * geometry.width() * geometry.height() / 1024; + } + cacheSize += cacheSize / 10; + + // Calculate the size of physical system memory; _SC_PHYS_PAGES * + // _SC_PAGESIZE is documented to be able to overflow 32-bit integers, + // so apply a 10-bit shift. FreeBSD 6-STABLE doesn't have _SC_PHYS_PAGES + // (it is documented in FreeBSD 7-STABLE as "Solaris and Linux extension") + // so use sysctl in those cases. +#if defined(_SC_PHYS_PAGES) + int memorySize = sysconf(_SC_PHYS_PAGES); + memorySize *= sysconf(_SC_PAGESIZE) / 1024; +#else +#ifdef Q_OS_FREEBSD + int sysctlbuf[2]; + size_t size = sizeof(sysctlbuf); + int memorySize; + // This could actually use hw.physmem instead, but I can't find + // reliable documentation on how to read the value (which may + // not fit in a 32 bit integer). + if (!sysctlbyname("vm.stats.vm.v_page_size", sysctlbuf, &size, NULL, 0)) { + memorySize = sysctlbuf[0] / 1024; + size = sizeof(sysctlbuf); + if (!sysctlbyname("vm.stats.vm.v_page_count", sysctlbuf, &size, NULL, 0)) { + memorySize *= sysctlbuf[0]; + } + } +#endif +#ifdef Q_OS_NETBSD + size_t memorySize; + size_t len; + static int mib[] = { CTL_HW, HW_PHYSMEM }; + + len = sizeof(memorySize); + sysctl(mib, 2, &memorySize, &len, NULL, 0); + memorySize /= 1024; +#endif + // If you have no suitable sysconf() interface and are not FreeBSD, + // then you are out of luck and get a compile error. +#endif + + // Increase the pixmap cache size to 1% of system memory if it isn't already + // larger so as to maximize cache usage. 1% of 1GB ~= 10MB. + if (cacheSize < memorySize / 100) { + cacheSize = memorySize / 100; + } + + kDebug() << "Setting the pixmap cache size to" << cacheSize << "kilobytes"; + QPixmapCache::setCacheLimit(cacheSize); + + KConfigGroup cg(KGlobal::config(), "General"); + Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font())); + + if (cg.readEntry("forceNoComposite", false)) { + composite = false; + } + + //we have to keep an eye on created windows + tag = XInternAtom(QX11Info::display(), "_KDE_SCREENSAVER_OVERRIDE", False); + tag2 = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); + qApp->installEventFilter(this); + + // this line initializes the corona. + corona(); + + connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup())); + + setup(KCmdLineArgs::parsedArgs()->isSet("setup")); + + m_viewCreationTimer.setSingleShot(true); + m_viewCreationTimer.setInterval(0); + connect(&m_viewCreationTimer, SIGNAL(timeout()), this, SLOT(createWaitingViews())); +} + +PlasmaApp::~PlasmaApp() +{ +} + +void PlasmaApp::cleanup() +{ + if (m_corona) { + m_corona->saveLayout(); + } + + qDeleteAll(m_views); + delete m_corona; + m_corona = 0; + + KGlobal::config()->sync(); +} + +void PlasmaApp::createWaitingViews() +{ + const QList > containments = m_viewsWaiting; + m_viewsWaiting.clear(); + foreach(QWeakPointer weakContainment, containments) { + if (weakContainment) { + Plasma::Containment *containment = weakContainment.data(); + + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + + // we have a new screen. neat. + SaverView *view = viewForScreen(containment->screen()); + if (view) { + return; + } + + view = new SaverView(containment, 0); + if (m_corona) { + connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)), + view, SLOT(screenOwnerChanged(int,int,Plasma::Containment*))); + connect(m_corona, SIGNAL(shortcutsChanged()), view, SLOT(updateShortcuts())); + } + view->setGeometry(QApplication::desktop()->screenGeometry(containment->screen())); + + //FIXME why do I get BadWindow? + //unsigned char data = VIEW; + //XChangeProperty(QX11Info::display(), view->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1); + + connect(containment, SIGNAL(configureRequested(Plasma::Containment*)), + this, SLOT(configureContainment(Plasma::Containment*))); + + //a hack to make sure the keyboard shortcut works + view->addAction(corona()->action("unlock desktop")); + view->addAction(corona()->action("unlock widgets")); + m_views.append(view); + connect(view, SIGNAL(hidden()), SLOT(lock())); + connect(view, SIGNAL(hidden()), SIGNAL(hidden())); + connect(this, SIGNAL(showViews()), view, SLOT(show())); + connect(this, SIGNAL(hideViews()), view, SLOT(hide())); + connect(this, SIGNAL(enableSetupMode()), view, SLOT(disableSetupMode())); + connect(this, SIGNAL(disableSetupMode()), view, SLOT(disableSetupMode())); + connect(this, SIGNAL(openToolBox()), view, SLOT(openToolBox())); + connect(this, SIGNAL(closeToolBox()), view, SLOT(closeToolBox())); + connect(QApplication::desktop(), SIGNAL(resized(int)), view, SLOT(adjustSize(int))); + emit(openToolBox()); + kDebug() << "view created"; + } + } + //activate the new views (yes, this is a lazy way to do it) + setActive(m_active); +} + + +void PlasmaApp::setActive(bool activate) +{ + m_active = activate; + //note: allow this to run even if the value isn't changed, + //because some views may need updating. + if (activate) { + emit showViews(); + emit openToolBox(); + } else { + emit hideViews(); + } +} + +void PlasmaApp::syncConfig() +{ + KGlobal::config()->sync(); +} + +Plasma::Corona* PlasmaApp::corona() +{ + if (!m_corona) { + m_corona = new SaverCorona(this); + connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)), + this, SLOT(containmentScreenOwnerChanged(int,int,Plasma::Containment*))); + connect(m_corona, SIGNAL(configSynced()), SLOT(syncConfig())); + //kDebug() << "connected to containmentAdded"; + /* + foreach (DesktopView *view, m_desktops) { + connect(c, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)), + view, SLOT(screenOwnerChanged(int,int,Plasma::Containment*))); + }*/ + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + m_corona->initializeLayout(); + + //we want this *after* init so that we ignore any lock/unlock spasms that might happen then + connect(m_corona, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), this, SLOT(immutabilityChanged(Plasma::ImmutabilityType))); + + //kDebug() << "layout should exist"; + //c->checkScreens(); + } + + return m_corona; +} + +bool PlasmaApp::hasComposite() +{ + return composite; +} + +void PlasmaApp::containmentScreenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment *containment) +{ + Q_UNUSED(wasScreen); + if (isScreen < 0) + return; + m_viewsWaiting.append(containment); + m_viewCreationTimer.start(); +} + +void PlasmaApp::setup(bool setupMode) +{ + kDebug() << "setup mode:" << setupMode; + + if (setupMode) { + emit enableSetupMode(); + if (m_corona->immutability() == Plasma::UserImmutable) { + m_corona->setImmutability(Plasma::Mutable); + } + setActive(true); + } else { + kDebug() << "checking lockprocess is still around"; + QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", + "org.kde.screenlocker.LockProcess", QDBusConnection::sessionBus(), this); + if (lockprocess.isValid()) { + kDebug() << "success!"; + setActive(false); + } else { + kDebug() << "bailing out"; + qApp->quit(); //this failed once. why? + } + } +} + +bool PlasmaApp::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::Show) { + //apparently this means we created a new window + //so, add a tag to prove it's our window + //FIXME using the show event means we tag on every show, not just the first. + //harmless but kinda wasteful. + QWidget *widget = qobject_cast(obj); + if (widget && widget->isWindow() && !(qobject_cast(widget) || + widget->testAttribute(Qt::WA_DontShowOnScreen))) { + unsigned char data = 0; + if (qobject_cast(widget)) { + data = VIEW; + } else if (m_dialogs.contains(widget)) { + data = DIALOG; + } else { + Qt::WindowFlags oldFlags = widget->windowFlags(); + Qt::WindowFlags newFlags = oldFlags |Qt::X11BypassWindowManagerHint; + if (oldFlags != newFlags) { + //now we're *really* fucking with things + //we force-disable window management and frames to cut off access to wm-y stuff + //and to make it easy to check the tag (frames are a pain) + kDebug() << "!!!!!!!setting flags on!!!!!" << widget; + QDesktopWidget *desktop = QApplication::desktop(); + if (qobject_cast(widget)) { + //this is a terrible horrible hack that breaks extenders but it mostly works + //weird thing is, it sometimes makes the calendar popup too small. + newFlags = Qt::Popup; + } else { + //plasmadialogs can't handle direct input + //but configdialogs need it + m_dialogs.append(widget); + connect(widget, SIGNAL(destroyed(QObject*)), SLOT(dialogDestroyed(QObject*))); + connect(this, SIGNAL(showDialogs()), widget, SLOT(show())); + connect(this, SIGNAL(hideDialogs()), widget, SLOT(hide())); + } + widget->setWindowFlags(newFlags); + //we do not know the screen this widget should appear on + QRect availableGeometry = desktop->availableGeometry(); + //if has weird position, move to the default screen + if (!availableGeometry.contains(widget->pos())) { + widget->move(availableGeometry.x(), availableGeometry.y()); + } + widget->show(); //setting the flags hid it :( + //qApp->setActiveWindow(widget); //gives kbd but not mouse events + //kDebug() << "parent" << widget->parentWidget(); + //FIXME why can I only activate these dialogs from this exact line? + widget->activateWindow(); //gives keyboard focus + return false; //we'll be back when we get the new show event + } else { + widget->activateWindow(); //gives keyboard focus + } + } + + XChangeProperty(QX11Info::display(), widget->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1); + XChangeProperty(QX11Info::display(), widget->effectiveWinId(), tag2, tag2, 32, PropModeReplace, 0, 0); + kDebug() << "tagged" << widget << widget->effectiveWinId() << "as" << data; + } + } + return false; +} + +void PlasmaApp::dialogDestroyed(QObject *obj) +{ + m_dialogs.removeAll(qobject_cast(obj)); + //if (m_dialogs.isEmpty()) { + //FIXME multiview + //if (m_view) { + //this makes qactions work again + //m_view->activateWindow(); + //} + /*} else { failed attempt to fix kbd input after a subdialog closes + QWidget *top = m_dialogs.last(); + top->activateWindow(); + kDebug() << top;*/ + //} +} + +void PlasmaApp::configureContainment(Plasma::Containment *containment) +{ +// SaverView *view = viewForScreen(containment->screen()); +// if (!view) { +// return; +// } + + if (m_configDialog) { + m_configDialog->reloadConfig(); + } else { + const QSize resolution = QApplication::desktop()->screenGeometry(containment->screen()).size(); + + m_configDialog = new BackgroundDialog(resolution, containment); + m_configDialog->setAttribute(Qt::WA_DeleteOnClose); + } + + m_configDialog->show(); +} + +void PlasmaApp::lock() +{ + kDebug() << "lock"; + if (corona() && corona()->immutability() == Plasma::Mutable) { + corona()->setImmutability(Plasma::UserImmutable); + } +} + +void PlasmaApp::quit() +{ + qApp->quit(); +} + +void PlasmaApp::immutabilityChanged(Plasma::ImmutabilityType immutability) +{ + if (immutability == Plasma::Mutable) { + emit showDialogs(); + } else { + emit hideDialogs(); + emit hideWidgetExplorer(); + emit disableSetupMode(); + } +} + +SaverView *PlasmaApp::viewForScreen(int screen) +{ + foreach(SaverView *view, m_views) { + if (view->screen() == screen) + return view; + } + return 0; +} + +#include "plasmaapp.moc" diff --git a/plasma/screensaver/shell/plasmaapp.h b/plasma/screensaver/shell/plasmaapp.h new file mode 100644 index 00000000..fb795024 --- /dev/null +++ b/plasma/screensaver/shell/plasmaapp.h @@ -0,0 +1,129 @@ +/* + * Copyright 2006, 2007 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * 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, + * 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. If not, see . + */ + +#ifndef PLASMA_APP_H +#define PLASMA_APP_H + +#include +#include +#include + +#include + +#include + +namespace Plasma +{ + class Containment; + class Corona; +} // namespace Plasma + +class SaverView; +class BackgroundDialog; + +class PlasmaApp : public KUniqueApplication +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.plasmaoverlay.App") +public: + ~PlasmaApp(); + + static PlasmaApp* self(); + static bool hasComposite(); + + Plasma::Corona* corona(); + +Q_SIGNALS: + // DBUS interface. + //if you change stuff, remember to regenerate with: + //qdbuscpp2xml -S -M plasmaapp.h > org.kde.plasma-overlay.App.xml + + //XXX can this be deleted? probably. if lockprocess really cares it can use the unmapnotify + void hidden(); + +public Q_SLOTS: + // DBUS interface. + //if you change stuff, remember to regenerate ^^^ + /** + * tell plasma to go into active mode, ready for interaction + */ + void setActive(bool activate); + + /** + * lock widgets + */ + void lock(); + + //not really slots, but we want them in dbus: + + /** + * get plasma all set up and ready + * this makes sure things like visibility and locked-ness are set right + * normally this is called only by plasmaapp itself when it finishes initialization, but it's + * possible that it might need to be run again by lockprocess + * + * @param setupMode whether we're starting in setup mode + */ + void setup(bool setupMode); + + /** + * quit the application + * this is a duplicate so we can have everything we need in one dbus interface + */ + void quit(); + +private Q_SLOTS: + void cleanup(); + //void adjustSize(int screen); + void dialogDestroyed(QObject *obj); + void configureContainment(Plasma::Containment*); + void syncConfig(); + void immutabilityChanged(Plasma::ImmutabilityType immutability); + void createWaitingViews(); + void containmentScreenOwnerChanged(int, int, Plasma::Containment*); + +Q_SIGNALS: + void showViews(); + void hideViews(); + void showDialogs(); + void hideDialogs(); + void hideWidgetExplorer(); + void enableSetupMode(); + void disableSetupMode(); + void openToolBox(); + void closeToolBox(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap); + SaverView *viewForScreen(int screen); + + Plasma::Corona *m_corona; + QList m_views; + QList m_dialogs; + QPointer m_configDialog; + + QList > m_viewsWaiting; + QTimer m_viewCreationTimer; + + bool m_active; +}; + +#endif // multiple inclusion guard diff --git a/plasma/screensaver/shell/savercorona.cpp b/plasma/screensaver/shell/savercorona.cpp new file mode 100644 index 00000000..36a7f5d2 --- /dev/null +++ b/plasma/screensaver/shell/savercorona.cpp @@ -0,0 +1,269 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2008 by Chani Armitage + * Copyright 2011 Martin Gräßlin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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. If not, see .. + */ + +#include "savercorona.h" +#include "kscreensaversettings.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +static const char *DEFAULT_MAIN_PACKAGE = "org.kde.passworddialog"; + +SaverCorona::SaverCorona(QObject *parent) + : Plasma::Corona(parent) + , m_engine(NULL) + , m_greeterItem(NULL) + , m_mode(ScreenLock) + , m_capsLocked(false) +{ + init(); +} + +void SaverCorona::init() +{ + setPreferredToolBoxPlugin(Plasma::Containment::DesktopContainment, "org.kde.desktoptoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::CustomContainment, "org.kde.desktoptoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::PanelContainment, "org.kde.paneltoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::CustomPanelContainment, "org.kde.paneltoolbox"); + + QDesktopWidget *desktop = QApplication::desktop(); + connect(desktop,SIGNAL(screenCountChanged(int)), SLOT(numScreensUpdated(int))); + m_numScreens = desktop->numScreens(); + + Plasma::ContainmentActionsPluginsConfig plugins; + plugins.addPlugin(Qt::NoModifier, Qt::RightButton, "minimalcontextmenu"); + //should I add paste too? + setContainmentActionsDefaults(Plasma::Containment::CustomContainment, plugins); + + bool unlocked = immutability() == Plasma::Mutable; + + QAction *lock = action("lock widgets"); + if (lock) { + kDebug() << "unlock action"; + //rename the lock action so that corona doesn't mess with it + addAction("unlock widgets", lock); + //rewire the action so we can check for a password + lock->disconnect(SIGNAL(triggered(bool))); + connect(lock, SIGNAL(triggered()), this, SLOT(toggleLock())); + lock->setIcon(KIcon(unlocked ? "object-locked" : "configure")); + lock->setText(unlocked ? i18n("Lock Screen") : i18n("Configure Widgets")); + } + + //the most important action ;) + QAction *leave = new QAction(unlocked ? i18n("Leave Screensaver") : i18n("Unlock"), this); + leave->setIcon(KIcon("system-lock-screen")); + leave->setShortcut(QKeySequence("esc")); + connect(leave, SIGNAL(triggered()), this, SLOT(unlockDesktop())); + addAction("unlock desktop", leave); + + //updateShortcuts(); //just in case we ever get a config dialog + + // create the QML Component + m_engine = new QDeclarativeEngine(this); + KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(m_engine); + kdeclarative.initialize(); + kdeclarative.setupBindings(); + + connect(this, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), SLOT(updateActions(Plasma::ImmutabilityType))); + + installEventFilter(this); +} + +void SaverCorona::loadDefaultLayout() +{ + //kDebug(); + QDesktopWidget *desktop = QApplication::desktop(); + + // create a containment for the screens + Plasma::Containment *c; + for(int screen = 0; screen < m_numScreens; ++screen) + { + QRect g = desktop->screenGeometry(screen); + kDebug() << " screen" << screen << "geometry is" << g; + c = addContainment("saverdesktop"); + if (c) { + c->setScreen(screen); + c->setFormFactor(Plasma::Planar); + c->flushPendingConstraintsEvents(); + } + } + + // a default clock + c = containmentForScreen(desktop->primaryScreen()); + if (c) { + Plasma::Applet *clock = Plasma::Applet::load("clock"/*, c->id() + 1*/); + c->addApplet(clock, QPointF(KDialog::spacingHint(), KDialog::spacingHint()), true); + clock->init(); + clock->flushPendingConstraintsEvents(); + } + //emit containmentAdded(c); +} + +int SaverCorona::numScreens() const +{ + return m_numScreens; +} + +QRect SaverCorona::screenGeometry(int id) const +{ + return QApplication::desktop()->screenGeometry(id); +} + +void SaverCorona::updateActions(Plasma::ImmutabilityType immutability) +{ + bool unlocked = immutability == Plasma::Mutable; + QAction *a = action("unlock widgets"); + if (a) { + a->setIcon(KIcon(unlocked ? "object-locked" : "configure")); + a->setText(unlocked ? i18n("Lock Screen") : i18n("Configure Widgets")); + } + a = action("unlock desktop"); + if (a) { + a->setText(unlocked ? i18n("Leave Screensaver") : i18n("Unlock")); + } +} + +void SaverCorona::toggleLock() +{ + //require a password to unlock + if (immutability() == Plasma::Mutable) { + setImmutability(Plasma::UserImmutable); + kDebug() << "locking up!"; + } else if (immutability() == Plasma::UserImmutable) { + // show a greeter + if (!m_greeterItem) { + createGreeter(); + } + m_mode = AppletLock; + // TODO: disable session switching + m_greeterItem->setProperty("notification", i18n("Unlock widgets to configure them")); + m_greeterItem->setVisible(true); + } +} + +void SaverCorona::unlockDesktop() +{ + if (!m_greeterItem) { + createGreeter(); + } + m_mode = ScreenLock; + m_greeterItem->setProperty("notification", ""); + // TODO: enable session switching + m_greeterItem->setVisible(true); +} + +void SaverCorona::numScreensUpdated(int newCount) +{ + m_numScreens = newCount; + //do something? +} + +void SaverCorona::createGreeter() +{ + Plasma::PackageStructure::Ptr structure = Plasma::PackageStructure::load("Plasma/Generic"); + Plasma::Package *package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), KScreenSaverSettings::greeterQML(), structure); + + QString mainQmlPath = package->filePath("mainscript"); + if (mainQmlPath.isEmpty()) { + delete package; + package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, structure); + mainQmlPath = package->filePath("mainscript"); + } + + QDeclarativeComponent component(m_engine, QUrl::fromLocalFile(mainQmlPath)); + + m_greeterItem = qobject_cast(component.create()); + QDeclarativeProperty lockProperty(m_greeterItem, "locked"); + lockProperty.write(true); + + addItem(m_greeterItem); + m_greeterItem->setFocus(); + connect(m_greeterItem, SIGNAL(unlockRequested()), SLOT(greeterAccepted())); + connect(m_greeterItem, SIGNAL(canceled()), SLOT(greeterCanceled())); + const QRect screenRect = screenGeometry(QApplication::desktop()->primaryScreen()); + // TODO: center on screen + m_greeterItem->setPos(screenRect.x() + screenRect.width()/2, + screenRect.y() + screenRect.height()/2); +} + +void SaverCorona::greeterAccepted() +{ + if (m_mode == ScreenLock) { + qApp->quit(); + } else if (m_mode == AppletLock) { + setImmutability(Plasma::Mutable); + // greeter has problems with reusing after success + delete m_greeterItem; + m_greeterItem = NULL; + } +} + +void SaverCorona::greeterCanceled() +{ + m_greeterItem->setVisible(false); +} + +bool SaverCorona::eventFilter(QObject* watched, QEvent* event) +{ + Q_UNUSED(watched) + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + capsLocked(); + } + return false; +} + +void SaverCorona::capsLocked() +{ + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer(QX11Info::display(), DefaultRootWindow( QX11Info::display() ), &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &lmask); + const bool before = m_capsLocked; + m_capsLocked = lmask & LockMask; + if (before != m_capsLocked) { + if (m_greeterItem) { + m_greeterItem->setProperty("capsLockOn", m_capsLocked); + } + } +} + +#include "savercorona.moc" + diff --git a/plasma/screensaver/shell/savercorona.h b/plasma/screensaver/shell/savercorona.h new file mode 100644 index 00000000..4f814769 --- /dev/null +++ b/plasma/screensaver/shell/savercorona.h @@ -0,0 +1,75 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2008 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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. If not, see . + */ + +#ifndef SAVERCORONA_H +#define SAVERCORONA_H + +#include + +#include + +class QDeclarativeEngine; + +/** + * @short A Corona for the screensaver + */ +class SaverCorona : public Plasma::Corona +{ + Q_OBJECT + +public: + explicit SaverCorona(QObject * parent = 0); + + /** + * Loads the default (system wide) layout for this user + **/ + void loadDefaultLayout(); + + virtual int numScreens() const; + virtual QRect screenGeometry(int id) const; + +protected: + virtual bool eventFilter(QObject *watched, QEvent *event); + +private Q_SLOTS: + void updateActions(Plasma::ImmutabilityType immutability); + void toggleLock(); + void unlockDesktop(); + void numScreensUpdated(int newCount); + void greeterAccepted(); + void greeterCanceled(); + +private: + enum UnlockMode { + AppletLock, + ScreenLock + }; + void init(); + void createGreeter(); + void capsLocked(); + + int m_numScreens; + QDeclarativeEngine *m_engine; + QGraphicsObject *m_greeterItem; + UnlockMode m_mode; + bool m_capsLocked; +}; + +#endif + + diff --git a/plasma/screensaver/shell/saverview.cpp b/plasma/screensaver/shell/saverview.cpp new file mode 100644 index 00000000..8937df7d --- /dev/null +++ b/plasma/screensaver/shell/saverview.cpp @@ -0,0 +1,294 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007 Matt Broadstone + * Copyright 2007 André Duffeck + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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. If not, see . + */ + +#include "saverview.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#include "plasmaapp.h" + +static const int SUPPRESS_SHOW_TIMEOUT = 500; // Number of millis to prevent reshow of dashboard + + +class ScreenSaverWidgetExplorer : public Plasma::WidgetExplorer +{ +public: + ScreenSaverWidgetExplorer(QGraphicsWidget *parent) + : Plasma::WidgetExplorer(parent) + { + connect(this, SIGNAL(closeClicked()), this, SLOT(deleteLater())); + m_svg = new Plasma::FrameSvg(this); + m_svg->setImagePath("widgets/frame"); + m_svg->setElementPrefix("raised"); + m_svg->setEnabledBorders(Plasma::FrameSvg::TopBorder); + } + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event) + { + m_svg->resizeFrame(event->newSize()); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option) + Q_UNUSED(widget) + m_svg->paintFrame(painter); + } + +private: + Plasma::FrameSvg *m_svg; +}; + +SaverView::SaverView(Plasma::Containment *containment, QWidget *parent) + : Plasma::View(containment, parent), + m_suppressShow(false), + m_setupMode(false), + m_init(false) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | + Qt::X11BypassWindowManagerHint); + + //app is doing this for us - if needed + //QDesktopWidget *desktop = QApplication::desktop(); + //setGeometry(desktop->screenGeometry(containment->screen())); + + setWallpaperEnabled(true); + + containment->corona()->installEventFilter(this); +} + +SaverView::~SaverView() +{ + delete m_widgetExplorer.data(); +} + +void SaverView::enableSetupMode() +{ + if (!m_setupMode) { + m_setupMode = true; + update(); + } +} + +void SaverView::disableSetupMode() +{ + if (m_setupMode) { + m_setupMode = false; + update(); + } +} + +void SaverView::drawBackground(QPainter *painter, const QRectF & rect) +{ + if (PlasmaApp::hasComposite()) { + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->fillRect(rect, Qt::transparent); + } else { + Plasma::View::drawBackground(painter, rect); + } +} + +void SaverView::showWidgetExplorer() +{ + Plasma::Containment *c = containment(); + if (!c) { + return; + } + + if (m_widgetExplorer) { + delete m_widgetExplorer.data(); + } else { + ScreenSaverWidgetExplorer *widgetExplorer = new ScreenSaverWidgetExplorer(c); + widgetExplorer->installEventFilter(this); + widgetExplorer->setContainment(c); + widgetExplorer->setLocation(Plasma::BottomEdge); + widgetExplorer->populateWidgetList(); + widgetExplorer->setMaximumWidth(width()); + widgetExplorer->adjustSize(); + widgetExplorer->setZValue(1000000); + widgetExplorer->resize(width(), widgetExplorer->size().height()); + widgetExplorer->setPos(0, containment()->geometry().height() - widgetExplorer->geometry().height()); + m_widgetExplorer = widgetExplorer; + } +} + +void SaverView::hideWidgetExplorer() +{ + delete m_widgetExplorer.data(); +} + +void SaverView::paintEvent(QPaintEvent *event) +{ + Plasma::View::paintEvent(event); + if (!m_setupMode) { + return; + } + + // now draw a little label reminding the user their screen's not quite locked + const QRect r = rect(); + const QString text = i18n("Setup Mode - Screen is NOT locked"); + QFont f = font(); + f.bold(); + const QFontMetrics fm(f); + const int margin = 6; + const int textWidth = fm.width(text); + const QPoint centered(r.width() / 2 - textWidth / 2 - margin, r.y()); + const QRect boundingBox(centered, QSize(margin * 2 + textWidth, fm.height() + margin * 2)); + + if (!viewport() || !event->rect().intersects(boundingBox)) { + return; + } + + QPainterPath box; + box.moveTo(boundingBox.topLeft()); + box.lineTo(boundingBox.bottomLeft() + QPoint(0, -margin * 2)); + box.quadTo(boundingBox.bottomLeft(), boundingBox.bottomLeft() + QPoint(margin * 2, 0)); + box.lineTo(boundingBox.bottomRight() + QPoint(-margin * 2, 0)); + box.quadTo(boundingBox.bottomRight(), boundingBox.bottomRight() + QPoint(0, -margin * 2)); + box.lineTo(boundingBox.topRight()); + box.closeSubpath(); + + QPainter painter(viewport()); + painter.setRenderHint(QPainter::Antialiasing); + painter.setFont(f); + //kDebug() << "******************** painting from" << centered << boundingBox << rect() << event->rect(); + QColor highlight = palette().highlight().color(); + highlight.setAlphaF(0.7); + painter.setPen(highlight.darker()); + painter.setBrush(highlight); + painter.drawPath(box); + painter.setPen(palette().highlightedText().color()); + painter.drawText(boundingBox, Qt::AlignCenter | Qt::AlignVCenter, text); +} + +bool SaverView::eventFilter(QObject *watched, QEvent *event) +{ + if (containment() && (watched == (QObject*)m_widgetExplorer.data()) && + (event->type() == QEvent::GraphicsSceneResize || event->type() == QEvent::GraphicsSceneMove)) { + Plasma::WidgetExplorer *widgetExplorer = m_widgetExplorer.data(); + widgetExplorer->setPos(0, containment()->geometry().height() - widgetExplorer->geometry().height()); + } else if (watched == containment()->corona() && event->type() == QEvent::GraphicsSceneMousePress) { + activateWindow(); + grabKeyboard(); + } + + return false; +} + +void SaverView::showView() +{ + if (isHidden()) { + if (m_suppressShow) { + kDebug() << "show was suppressed"; + return; + } + + setWindowState(Qt::WindowFullScreen); + //KWindowSystem::setOnAllDesktops(winId(), true); + //KWindowSystem::setState(winId(), NET::KeepAbove|NET::SkipTaskbar); + + show(); + raise(); + + m_suppressShow = true; + QTimer::singleShot(SUPPRESS_SHOW_TIMEOUT, this, SLOT(suppressShowTimeout())); + activateWindow(); + grabKeyboard(); + } +} + +void SaverView::setContainment(Plasma::Containment *newContainment) +{ + if (m_init && newContainment == containment()) { + return; + } + + m_init = true; + + if (containment()) { + disconnect(containment(), SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer())); + } + + if (newContainment) { + connect(newContainment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer())); + } + + if (m_widgetExplorer) { + m_widgetExplorer.data()->setContainment(newContainment); + } + + View::setContainment(newContainment); +} + +void SaverView::hideView() +{ + if (isHidden()) { + return; + } + + hideWidgetExplorer(); + + if (containment()) { + containment()->closeToolBox(); + } + + hide(); + //let the lockprocess know + emit hidden(); +} + +void SaverView::suppressShowTimeout() +{ + kDebug() << "SaverView::suppressShowTimeout"; + m_suppressShow = false; +} + +void SaverView::openToolBox() +{ + kDebug() << "close toolbox"; + containment()->openToolBox(); +} + +void SaverView::closeToolBox() +{ + kDebug() << "close toolbox"; + containment()->closeToolBox(); +} + +void SaverView::adjustSize(int screen) +{ + QDesktopWidget *desktop = QApplication::desktop(); + int thisScreen = desktop->screenNumber(this); + if(screen == thisScreen) + { + setGeometry(desktop->screenGeometry(screen)); + } +} + +#include "saverview.moc" diff --git a/plasma/screensaver/shell/saverview.h b/plasma/screensaver/shell/saverview.h new file mode 100644 index 00000000..dbf00cde --- /dev/null +++ b/plasma/screensaver/shell/saverview.h @@ -0,0 +1,82 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007 André Duffeck + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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. If not, see . + */ + +#ifndef SAVERVIEW_H +#define SAVERVIEW_H + +#include + +#include +#include + +namespace Plasma +{ + class Containment; + class WidgetExplorer; +} + +class SaverView : public Plasma::View +{ + Q_OBJECT + +public: + SaverView(Plasma::Containment* containment, QWidget *parent); + ~SaverView(); + + bool eventFilter(QObject *watched, QEvent *event); + +signals: + void hidden(); + +protected: + void drawBackground(QPainter *painter, const QRectF & rect); + void paintEvent(QPaintEvent *event); + +public slots: + void showView(); + void hideView(); + void adjustSize(int screen); + + /** + * Sets the containment for this view, which will also cause the view + * to track the geometry of the containment. + * + * @arg containment the containment to center the view on + */ + void setContainment(Plasma::Containment *newContainment); + void hideWidgetExplorer(); + + void enableSetupMode(); + void disableSetupMode(); + +protected slots: + void showWidgetExplorer(); //FIXME actually this is toggle + void suppressShowTimeout(); + void openToolBox(); + void closeToolBox(); + +private: + QWeakPointer m_widgetExplorer; + QPoint m_appletBrowserDragStart; + bool m_suppressShow : 1; + bool m_setupMode : 1; + bool m_init : 1; +}; + +#endif // multiple inclusion guard diff --git a/powerdevil/.krazy b/powerdevil/.krazy new file mode 100644 index 00000000..74563658 --- /dev/null +++ b/powerdevil/.krazy @@ -0,0 +1,3 @@ +EXTRA null +EXTRA kdebug +EXTRA defines diff --git a/powerdevil/CMakeLists.txt b/powerdevil/CMakeLists.txt new file mode 100644 index 00000000..0bede398 --- /dev/null +++ b/powerdevil/CMakeLists.txt @@ -0,0 +1,11 @@ + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/daemon +) + +add_subdirectory(daemon) +add_subdirectory(kcmodule) + +install( FILES powerdevil.notifyrc DESTINATION ${DATA_INSTALL_DIR}/powerdevil ) diff --git a/powerdevil/COPYING b/powerdevil/COPYING new file mode 100644 index 00000000..5185fd3f --- /dev/null +++ b/powerdevil/COPYING @@ -0,0 +1,346 @@ +NOTE! The GPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (the kde programs) are copyrighted +by the authors who actually wrote it. + +--------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/powerdevil/PowerDevilSettings.kcfg b/powerdevil/PowerDevilSettings.kcfg new file mode 100644 index 00000000..cd103c6d --- /dev/null +++ b/powerdevil/PowerDevilSettings.kcfg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + + + + 20 + + + 5 + + + 2 + + + diff --git a/powerdevil/PowerDevilSettings.kcfgc b/powerdevil/PowerDevilSettings.kcfgc new file mode 100644 index 00000000..4d4f6361 --- /dev/null +++ b/powerdevil/PowerDevilSettings.kcfgc @@ -0,0 +1,5 @@ +ClassName=PowerDevilSettings +File=PowerDevilSettings.kcfg +Mutators=true +Singleton=true +Visibility=KDE_EXPORT diff --git a/powerdevil/daemon/BackendConfig.cmake b/powerdevil/daemon/BackendConfig.cmake new file mode 100644 index 00000000..41c8812a --- /dev/null +++ b/powerdevil/daemon/BackendConfig.cmake @@ -0,0 +1,66 @@ +# This files sets the needed sources for powerdevil's backend +# TODO 4.7: Compile only one backend instead of doing runtime checks + + +########################## UPower Backend ##################################### +if (UDEV_FOUND) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backends/upower + ${X11_INCLUDE_DIR} + ${X11_Xrandr_INCLUDE_PATH}) + + set(powerdevilupowerbackend_SRCS + backends/upower/upowersuspendjob.cpp + backends/upower/login1suspendjob.cpp + backends/upower/powerdevilupowerbackend.cpp + backends/upower/xrandrbrightness.cpp + backends/upower/xrandrx11helper.cpp + backends/upower/udevqtclient.cpp + backends/upower/udevqtdevice.cpp + ) + + set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.xml + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.Device.xml + PROPERTIES NO_NAMESPACE TRUE) + + qt4_add_dbus_interface(powerdevilupowerbackend_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.xml + upower_interface) + + qt4_add_dbus_interface(powerdevilupowerbackend_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.Device.xml + upower_device_interface) + + qt4_add_dbus_interface(powerdevilupowerbackend_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml + upower_kbdbacklight_interface) + + qt4_add_dbus_interface(powerdevilupowerbackend_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/com.ubuntu.Upstart.xml + upstart_interface) + + set(powerdevilupowerbackend_LIBS ${X11_LIBRARIES} ${QT_QTGUI_LIBRARY} ${X11_Xrandr_LIB} ${KDE4_KDEUI_LIBRARY} ${UDEV_LIBS}) + + ## backlight helper executable + kde4_add_executable(backlighthelper backends/upower/backlighthelper.cpp ${backlighthelper_mocs}) + target_link_libraries(backlighthelper ${KDE4_KDECORE_LIBS}) + install(TARGETS backlighthelper DESTINATION ${LIBEXEC_INSTALL_DIR}) + kde4_install_auth_helper_files(backlighthelper org.kde.powerdevil.backlighthelper root) + kde4_install_auth_actions(org.kde.powerdevil.backlighthelper ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/backlight_helper_actions.actions) +endif (UDEV_FOUND) + +########################## HAL Backend ##################################### + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backends/hal) + +set(powerdevilhalbackend_SRCS + backends/hal/halsuspendjob.cpp + backends/hal/powerdevilhalbackend.cpp +) + +set(powerdevilhalbackend_LIBS ${KDE4_SOLID_LIBS}) + +########################## Daemon variables ################################ + +set(POWERDEVIL_BACKEND_SRCS ${powerdevilupowerbackend_SRCS} ${powerdevilhalbackend_SRCS}) +set(POWERDEVIL_BACKEND_LIBS ${powerdevilupowerbackend_LIBS} ${powerdevilhalbackend_LIBS}) diff --git a/powerdevil/daemon/CMakeLists.txt b/powerdevil/daemon/CMakeLists.txt new file mode 100644 index 00000000..0a965ff6 --- /dev/null +++ b/powerdevil/daemon/CMakeLists.txt @@ -0,0 +1,112 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +add_subdirectory(actions) + +set(POWERDEVIL_CORE_VERSION_MAJOR 0) +set(POWERDEVIL_CORE_VERSION_MINOR 1) +set(POWERDEVIL_CORE_VERSION_MICRO 0) +set(POWERDEVIL_CORE_VERSION_STRING ${POWERDEVIL_CORE_VERSION_MAJOR}.${POWERDEVIL_CORE_VERSION_MINOR}.${POWERDEVIL_CORE_VERSION_MICRO}) + +# Add bundled actions +set(powerdevil_bundled_actions_SRCS + actions/bundled/suspendsession.cpp + actions/bundled/brightnesscontrol.cpp + actions/bundled/keyboardbrightnesscontrol.cpp + actions/bundled/dimdisplay.cpp + actions/bundled/runscript.cpp + actions/bundled/handlebuttonevents.cpp +) + +# target no.1 - powerdevil core library +set(powerdevilcore_SRCS + powerdevilaction.cpp + powerdevilactionpool.cpp + powerdevilbackendinterface.cpp + powerdevilcore.cpp + powerdevilpolicyagent.cpp + powerdevilprofilegenerator.cpp + + brightnessosdwidget.cpp +) + +kde4_add_kcfg_files(powerdevilcore_SRCS ../PowerDevilSettings.kcfgc) + +set(screensaver_xml "${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml") +qt4_add_dbus_interface(powerdevilcore_SRCS ${screensaver_xml} screensaver_interface ) + +# Action DBus Adaptors +qt4_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml + actions/bundled/brightnesscontrol.h PowerDevil::BundledActions::BrightnessControl) +qt4_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml + actions/bundled/keyboardbrightnesscontrol.h PowerDevil::BundledActions::KeyboardBrightnessControl) +qt4_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml + actions/bundled/handlebuttonevents.h PowerDevil::BundledActions::HandleButtonEvents) +qt4_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml + actions/bundled/suspendsession.h PowerDevil::BundledActions::SuspendSession) + +kde4_add_library(powerdevilcore SHARED ${powerdevilcore_SRCS} ${powerdevil_bundled_actions_SRCS}) +set_target_properties(powerdevilcore PROPERTIES VERSION ${POWERDEVIL_CORE_VERSION_STRING} SOVERSION ${POWERDEVIL_CORE_VERSION_MAJOR}) + +target_link_libraries(powerdevilcore + ${KDE4_KDECORE_LIBS} + ${KDE4_SOLID_LIBS} + ${KDE4_KIDLETIME_LIBS} + ${KDE4_PLASMA_LIBS} + ${KACTIVITIES_LIBRARY} + kworkspace +) + +# target no.2 - powerdevil kded module +set(kded_powerdevil_SRCS + kdedpowerdevil.cpp + powerdevilbackendloader.cpp + powerdevilfdoconnector.cpp +) + +# DBus Adaptors +qt4_add_dbus_adaptor(kded_powerdevil_SRCS org.kde.Solid.PowerManagement.xml powerdevilcore.h PowerDevil::Core) +qt4_add_dbus_adaptor(kded_powerdevil_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.Solid.PowerManagement.PolicyAgent.xml + powerdevilpolicyagent.h PowerDevil::PolicyAgent + powermanagementpolicyagentadaptor PowerManagementPolicyAgentAdaptor) + +qt4_add_dbus_adaptor(kded_powerdevil_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.freedesktop.PowerManagement.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementfdoadaptor PowerManagementFdoAdaptor) +qt4_add_dbus_adaptor(kded_powerdevil_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.freedesktop.PowerManagement.Inhibit.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementinhibitadaptor PowerManagementInhibitAdaptor) + + +# Backends +include(BackendConfig.cmake) + +kde4_add_plugin(kded_powerdevil ${kded_powerdevil_SRCS} ${POWERDEVIL_BACKEND_SRCS}) + +target_link_libraries(kded_powerdevil + ${KDE4_KDECORE_LIBS} + ${POWERDEVIL_BACKEND_LIBS} + powerdevilcore +) + +if (UDEV_FOUND) + target_link_libraries(kded_powerdevil ${UDEV_LIBS}) +endif (UDEV_FOUND) + +install(TARGETS kded_powerdevil DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS powerdevilcore ${INSTALL_TARGETS_DEFAULT_ARGS}) + +# target no.3 - powerdevil ui library +set(powerdevilui_SRCS + powerdevilactionconfig.cpp +) + +kde4_add_library(powerdevilui SHARED ${powerdevilui_SRCS}) +set_target_properties(powerdevilui PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) + +target_link_libraries(powerdevilui + ${KDE4_KDECORE_LIBS} + ${QT_QTGUI_LIBRARY} +) + +macro_bool_to_01(UDEV_FOUND HAVE_UDEV) +configure_file(config-powerdevil.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-powerdevil.h ) + +install(TARGETS powerdevilui ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES powerdevil.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded) diff --git a/powerdevil/daemon/Messages.sh b/powerdevil/daemon/Messages.sh new file mode 100755 index 00000000..ded50a52 --- /dev/null +++ b/powerdevil/daemon/Messages.sh @@ -0,0 +1,5 @@ +#! /bin/sh +$EXTRACTRC `find -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp || exit 11 +$XGETTEXT `find -name \*.cpp -o -name \*.h` -o $podir/powerdevil.pot +rm -f rc.cpp + diff --git a/powerdevil/daemon/actions/CMakeLists.txt b/powerdevil/daemon/actions/CMakeLists.txt new file mode 100644 index 00000000..db9ca479 --- /dev/null +++ b/powerdevil/daemon/actions/CMakeLists.txt @@ -0,0 +1,6 @@ +install(FILES powerdevilaction.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) + +add_subdirectory(bundled) +if(HAVE_DPMS) + add_subdirectory(dpms) +endif(HAVE_DPMS) \ No newline at end of file diff --git a/powerdevil/daemon/actions/bundled/CMakeLists.txt b/powerdevil/daemon/actions/bundled/CMakeLists.txt new file mode 100644 index 00000000..d3470016 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/CMakeLists.txt @@ -0,0 +1,19 @@ +function(add_powerdevil_bundled_action _name) + set(actionconfig_SRCS ${_name}config.cpp) + kde4_add_plugin(powerdevil${_name}action_config + ${actionconfig_SRCS}) + target_link_libraries(powerdevil${_name}action_config + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} + powerdevilui + ${ARGN}) + install(TARGETS powerdevil${_name}action_config DESTINATION ${PLUGIN_INSTALL_DIR}) + install(FILES powerdevil${_name}action.desktop DESTINATION ${SERVICES_INSTALL_DIR}) +endfunction(add_powerdevil_bundled_action _name) + +add_powerdevil_bundled_action(brightnesscontrol) +add_powerdevil_bundled_action(keyboardbrightnesscontrol) +add_powerdevil_bundled_action(dimdisplay) +add_powerdevil_bundled_action(runscript ${KDE4_KIO_LIBS}) +add_powerdevil_bundled_action(suspendsession ${KDE4_KIO_LIBS} ${KDE4_SOLID_LIBS}) +add_powerdevil_bundled_action(handlebuttonevents ${KDE4_SOLID_LIBS}) diff --git a/powerdevil/daemon/actions/bundled/brightnesscontrol.cpp b/powerdevil/daemon/actions/bundled/brightnesscontrol.cpp new file mode 100644 index 00000000..49026ab8 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/brightnesscontrol.cpp @@ -0,0 +1,191 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "brightnesscontrol.h" + +#include "brightnessosdwidget.h" + +#include "brightnesscontroladaptor.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace PowerDevil { +namespace BundledActions { + +BrightnessControl::BrightnessControl(QObject* parent) + : Action(parent) +{ + // DBus + new BrightnessControlAdaptor(this); + + setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings); + + connect(core()->backend(), SIGNAL(brightnessChanged(float,PowerDevil::BackendInterface::BrightnessControlType)), + this, SLOT(onBrightnessChangedFromBackend(float,PowerDevil::BackendInterface::BrightnessControlType))); + + KActionCollection* actionCollection = new KActionCollection( this ); + + KAction* globalAction = actionCollection->addAction("Increase Screen Brightness"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Increase Screen Brightness")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_MonBrightnessUp)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(increaseBrightness())); + + globalAction = actionCollection->addAction("Decrease Screen Brightness"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Decrease Screen Brightness")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_MonBrightnessDown)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(decreaseBrightness())); +} + +BrightnessControl::~BrightnessControl() +{ + if (!m_brightnessOSD.isNull()) { + m_brightnessOSD.data()->deleteLater(); + } +} + +void BrightnessControl::onProfileUnload() +{ + // +} + +void BrightnessControl::onWakeupFromIdle() +{ + // +} + +void BrightnessControl::onIdleTimeout(int msec) +{ + Q_UNUSED(msec); +} + +void BrightnessControl::onProfileLoad() +{ + // This unparsable conditional block means: if the current profile is more + // conservative than the previous one and the current brightness is lower + // than the new profile + if (((m_currentProfile == "Battery" && m_lastProfile == "AC") || + (m_currentProfile == "LowBattery" && (m_lastProfile == "AC" || m_lastProfile == "Battery"))) && + m_defaultValue > brightness()) { + // We don't want to change anything here + kDebug() << "Not changing brightness, the current one is lower and the profile is more conservative"; + } else if (m_defaultValue >= 0) { + QVariantMap args; + args["Value"] = QVariant::fromValue((float)m_defaultValue); + trigger(args); + } +} + +void BrightnessControl::triggerImpl(const QVariantMap& args) +{ + backend()->setBrightness(args["Value"].toFloat()); + if (args["Explicit"].toBool()) { + showBrightnessOSD(backend()->brightness()); + } +} + +bool BrightnessControl::isSupported() +{ + BackendInterface::BrightnessControlsList controls = backend()->brightnessControlsAvailable(); + if (controls.key(BackendInterface::Screen).isEmpty()) { + return false; + } + + return true; +} + +bool BrightnessControl::loadAction(const KConfigGroup& config) +{ + // Handle profile changes + m_lastProfile = m_currentProfile; + m_currentProfile = config.parent().name(); + + kDebug() << "Profiles: " << m_currentProfile << m_lastProfile; + + if (config.hasKey("value")) { + m_defaultValue = config.readEntry("value", 50); + } else { + m_defaultValue = -1; + } + + return true; +} + +void BrightnessControl::showBrightnessOSD(int brightness) +{ + // code adapted from KMix + if (m_brightnessOSD.isNull()) { + m_brightnessOSD = new BrightnessOSDWidget(BackendInterface::Screen); + } + + m_brightnessOSD.data()->setCurrentBrightness(brightness); + m_brightnessOSD.data()->show(); + m_brightnessOSD.data()->activateOSD(); //Enable the hide timer + + //Center the OSD + QDesktopWidget * desktop = qApp->desktop(); + QRect rect = desktop->screenGeometry(desktop->primaryScreen()); + QSize size = m_brightnessOSD.data()->sizeHint(); + int posX = rect.x() + (rect.width() - size.width()) / 2; + int posY = rect.y() + 4 * rect.height() / 5; + m_brightnessOSD.data()->setGeometry(posX, posY, size.width(), size.height()); +} + +void BrightnessControl::onBrightnessChangedFromBackend(float brightness, PowerDevil::BackendInterface::BrightnessControlType type) +{ + if (type == BackendInterface::Screen) { + showBrightnessOSD(brightness); + Q_EMIT brightnessChanged(brightness); + } +} + +int BrightnessControl::brightness() const +{ + return backend()->brightness(); +} + +void BrightnessControl::setBrightness(int percent) +{ + QVariantMap args; + args["Value"] = QVariant::fromValue((float)percent); + args["Explicit"] = true; + trigger(args); +} + +void BrightnessControl::increaseBrightness() +{ + backend()->brightnessKeyPressed(BackendInterface::Increase); +} + +void BrightnessControl::decreaseBrightness() +{ + backend()->brightnessKeyPressed(BackendInterface::Decrease); +} + +} +} diff --git a/powerdevil/daemon/actions/bundled/brightnesscontrol.h b/powerdevil/daemon/actions/bundled/brightnesscontrol.h new file mode 100644 index 00000000..c4844f07 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/brightnesscontrol.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROL_H +#define POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROL_H + +#include +#include + +class BrightnessOSDWidget; + +namespace PowerDevil { +namespace BundledActions { + +class BrightnessControl : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(BrightnessControl) + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.Actions.BrightnessControl") + +public: + explicit BrightnessControl(QObject* parent); + virtual ~BrightnessControl(); + +protected: + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + virtual bool isSupported(); + +public: + virtual bool loadAction(const KConfigGroup& config); + +public Q_SLOTS: + void showBrightnessOSD(int brightness); + + // DBus export + void increaseBrightness(); + void decreaseBrightness(); + int brightness() const; + void setBrightness(int percent); + +private Q_SLOTS: + void onBrightnessChangedFromBackend(float brightness, PowerDevil::BackendInterface::BrightnessControlType type); + +Q_SIGNALS: + void brightnessChanged(int percent); + +private: + int m_defaultValue; + QWeakPointer< BrightnessOSDWidget > m_brightnessOSD; + QString m_lastProfile; + QString m_currentProfile; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROL_H diff --git a/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.cpp b/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.cpp new file mode 100644 index 00000000..1ce410f6 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "brightnesscontrolconfig.h" + +#include +#include +#include + +#include +#include + +K_PLUGIN_FACTORY(PowerDevilBrightnessControlConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilBrightnessControlConfigFactory("powerdevilbrightnesscontrolaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +BrightnessControlConfig::BrightnessControlConfig(QObject *parent, const QVariantList& ) + : ActionConfig(parent) +{ + +} + +BrightnessControlConfig::~BrightnessControlConfig() +{ + +} + +void BrightnessControlConfig::save() +{ + configGroup().writeEntry("value", m_slider->value()); + configGroup().sync(); +} + +void BrightnessControlConfig::load() +{ + configGroup().config()->reparseConfiguration(); + m_slider->setValue(configGroup().readEntry("value", 50)); +} + +QList< QPair< QString, QWidget* > > BrightnessControlConfig::buildUi() +{ + QList< QPair< QString, QWidget* > > retlist; + m_slider = new QSlider(Qt::Horizontal); + m_slider->setMaximumWidth(300); + m_slider->setRange(0, 100); + retlist.append(qMakePair< QString, QWidget* >(i18nc("Brightness level, label for the slider", "Level"), m_slider)); + + connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + + +} +} + +#include "brightnesscontrolconfig.moc" diff --git a/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.h b/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.h new file mode 100644 index 00000000..2419bc88 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/brightnesscontrolconfig.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROLCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROLCONFIG_H + +#include + +#include + +class QSlider; + +namespace PowerDevil { +namespace BundledActions { + +class KDE_EXPORT BrightnessControlConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(BrightnessControlConfig) +public: + BrightnessControlConfig(QObject*, const QVariantList&); + virtual ~BrightnessControlConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + QSlider *m_slider; +}; + +} +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_BRIGHTNESSCONTROLCONFIG_H diff --git a/powerdevil/daemon/actions/bundled/dimdisplay.cpp b/powerdevil/daemon/actions/bundled/dimdisplay.cpp new file mode 100644 index 00000000..fc265855 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/dimdisplay.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "dimdisplay.h" + +#include + +#include +#include +#include + +namespace PowerDevil { +namespace BundledActions { + +DimDisplay::DimDisplay(QObject* parent) + : Action(parent), m_dimmed(false) +{ + setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings); +} + +DimDisplay::~DimDisplay() +{ + +} + +void DimDisplay::onProfileUnload() +{ +} + +void DimDisplay::onWakeupFromIdle() +{ + if (!m_dimmed) { + return; + } + setBrightnessHelper(m_oldBrightness); + m_dimmed = false; +} + +void DimDisplay::onIdleTimeout(int msec) +{ + if (qFuzzyIsNull(backend()->brightness())) { + //Some drivers report brightness == 0 when display is off because of DPMS + //(especially Intel driver). Don't change brightness in this case, or + //backlight won't switch on later. + //Furthermore, we can't dim if brightness is 0 already. + return; + } + + if (msec == m_dimOnIdleTime) { + setBrightnessHelper(0); + } else if (msec == (m_dimOnIdleTime * 3 / 4)) { + float newBrightness = backend()->brightness() / 4; + setBrightnessHelper(newBrightness); + } else if (msec == (m_dimOnIdleTime * 1 / 2)) { + m_oldBrightness = backend()->brightness(); + float newBrightness = backend()->brightness() / 2; + setBrightnessHelper(newBrightness); + } + + m_dimmed = true; +} + +void DimDisplay::onProfileLoad() +{ + // +} + +void DimDisplay::setBrightnessHelper(float brightness) +{ + QVariantMap args; + args["_BrightnessValue"] = QVariant::fromValue(brightness); + trigger(args); +} + +void DimDisplay::triggerImpl(const QVariantMap& args) +{ + backend()->setBrightness(args["_BrightnessValue"].toFloat()); +} + +bool DimDisplay::isSupported() +{ + BackendInterface::BrightnessControlsList controls = backend()->brightnessControlsAvailable(); + if (controls.key(BackendInterface::Screen).isEmpty()) { + return false; + } + + return true; +} + +bool DimDisplay::loadAction(const KConfigGroup& config) +{ + kDebug(); + if (config.hasKey("idleTime")) { + m_dimOnIdleTime = config.readEntry("idleTime", 10000000); + kDebug() << "Loading timeouts with " << m_dimOnIdleTime; + registerIdleTimeout(m_dimOnIdleTime * 3 / 4); + registerIdleTimeout(m_dimOnIdleTime / 2); + registerIdleTimeout(m_dimOnIdleTime); + } + + return true; +} + +} +} diff --git a/powerdevil/daemon/actions/bundled/dimdisplay.h b/powerdevil/daemon/actions/bundled/dimdisplay.h new file mode 100644 index 00000000..1564df12 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/dimdisplay.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAY_H +#define POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAY_H + +#include + + +namespace PowerDevil { +namespace BundledActions { + +class DimDisplay : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(DimDisplay) + +public: + explicit DimDisplay(QObject *parent); + virtual ~DimDisplay(); + +protected: + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + virtual bool isSupported(); + +public: + virtual bool loadAction(const KConfigGroup& config); + +private: + void setBrightnessHelper(float brightness); + + int m_dimOnIdleTime; + float m_oldBrightness; + bool m_dimmed; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAY_H diff --git a/powerdevil/daemon/actions/bundled/dimdisplayconfig.cpp b/powerdevil/daemon/actions/bundled/dimdisplayconfig.cpp new file mode 100644 index 00000000..ac26e05c --- /dev/null +++ b/powerdevil/daemon/actions/bundled/dimdisplayconfig.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "dimdisplayconfig.h" + +#include +#include + +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilDimDisplayConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilDimDisplayConfigFactory("powerdevildimdisplayaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +DimDisplayConfig::DimDisplayConfig(QObject *parent, const QVariantList& ) + : ActionConfig(parent) +{ + +} + +DimDisplayConfig::~DimDisplayConfig() +{ + +} + +void DimDisplayConfig::save() +{ + configGroup().writeEntry("idleTime", m_spinBox->value() * 60 * 1000); +} + +void DimDisplayConfig::load() +{ + configGroup().config()->reparseConfiguration(); + m_spinBox->setValue((configGroup().readEntry("idleTime", 600000) / 60) / 1000); +} + +QList< QPair< QString, QWidget* > > DimDisplayConfig::buildUi() +{ + QList< QPair< QString, QWidget* > > retlist; + m_spinBox = new KIntSpinBox(0, 180, 1, 0, 0); + m_spinBox->setMaximumWidth(150); + m_spinBox->setMinimum(1); + m_spinBox->setMaximum(360); + m_spinBox->setSuffix(i18n(" min")); + retlist.append(qMakePair< QString, QWidget* >(i18n("After"), m_spinBox)); + + connect(m_spinBox, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + +} +} + +#include "dimdisplayconfig.moc" diff --git a/powerdevil/daemon/actions/bundled/dimdisplayconfig.h b/powerdevil/daemon/actions/bundled/dimdisplayconfig.h new file mode 100644 index 00000000..14b78793 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/dimdisplayconfig.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAYCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAYCONFIG_H + +#include + +class KIntSpinBox; + +namespace PowerDevil { +namespace BundledActions { + +class DimDisplayConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(DimDisplayConfig) +public: + DimDisplayConfig(QObject *, const QVariantList&); + virtual ~DimDisplayConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + KIntSpinBox *m_spinBox; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_DIMDISPLAYCONFIG_H diff --git a/powerdevil/daemon/actions/bundled/handlebuttonevents.cpp b/powerdevil/daemon/actions/bundled/handlebuttonevents.cpp new file mode 100644 index 00000000..571e8f69 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/handlebuttonevents.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "handlebuttonevents.h" +#include "handlebuttoneventsadaptor.h" + +#include "suspendsession.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "PowerDevilSettings.h" +#include "screensaver_interface.h" + +namespace PowerDevil { +namespace BundledActions { + +HandleButtonEvents::HandleButtonEvents(QObject* parent) + : Action(parent) + , m_lidAction(0) + , m_powerButtonAction(0) + , m_sleepButtonAction(1) + , m_hibernateButtonAction(2) +{ + new HandleButtonEventsAdaptor(this); + // We enforce no policies here - after all, we just call other actions - which have their policies. + setRequiredPolicies(PowerDevil::PolicyAgent::None); + connect(backend(), SIGNAL(buttonPressed(PowerDevil::BackendInterface::ButtonType)), + this, SLOT(onButtonPressed(PowerDevil::BackendInterface::ButtonType))); + + KActionCollection* actionCollection = new KActionCollection( this ); + + KAction *globalAction = actionCollection->addAction("Sleep"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Sleep")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_Sleep)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(suspendToRam())); + + globalAction = actionCollection->addAction("Hibernate"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Hibernate")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_Hibernate)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(suspendToDisk())); + + globalAction = actionCollection->addAction("PowerOff"); + //globalAction->setText(i18nc("Global shortcut", "Power Off button")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_PowerOff)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(powerOffButtonTriggered())); +} + +HandleButtonEvents::~HandleButtonEvents() +{ + +} + +bool HandleButtonEvents::isSupported() +{ + // get a list of all devices that are Buttons + foreach (Solid::Device device, Solid::Device::listFromType(Solid::DeviceInterface::Button, QString())) { + Solid::Button *button = device.as(); + if (button->type() == Solid::Button::LidButton || button->type() == Solid::Button::PowerButton) { + return true; + } + } + + return false; +} + +void HandleButtonEvents::onProfileUnload() +{ + m_lidAction = 0; + m_powerButtonAction = 0; +} + +void HandleButtonEvents::onWakeupFromIdle() +{ + // +} + +void HandleButtonEvents::onIdleTimeout(int msec) +{ + Q_UNUSED(msec) +} + +void HandleButtonEvents::onProfileLoad() +{ + // +} + +void HandleButtonEvents::onButtonPressed(BackendInterface::ButtonType type) +{ + switch (type) { + case BackendInterface::LidClose: + // Check if the configuration makes it explicit or not + processAction(m_lidAction, PowerDevilSettings::doNotInhibitOnLidClose()); + break; + case BackendInterface::LidOpen: + // In this case, let's send a wakeup event + KIdleTime::instance()->simulateUserActivity(); + break; + case BackendInterface::PowerButton: + // This one is always explicit + processAction(m_powerButtonAction, true); + break; + case BackendInterface::SleepButton: + // This one is always explicit + processAction(m_sleepButtonAction, true); + break; + case BackendInterface::HibernateButton: + // This one is always explicit + processAction(m_hibernateButtonAction, true); + break; + default: + break; + } +} + +void HandleButtonEvents::processAction(uint action, bool isExplicit) +{ + // Basically, we simply trigger other actions :) + switch ((SuspendSession::Mode)action) { + case SuspendSession::TurnOffScreenMode: + // Turn off screen + triggerAction("DPMSControl", qVariantFromValue< QString >("TurnOff"), isExplicit); + break; + default: + triggerAction("SuspendSession", qVariantFromValue< uint >(action), isExplicit); + break; + } +} + +void HandleButtonEvents::triggerAction(const QString& action, const QVariant &type, bool isExplicit) +{ + PowerDevil::Action *helperAction = ActionPool::instance()->loadAction(action, KConfigGroup(), core()); + if (helperAction) { + QVariantMap args; + args["Type"] = type; + args["Explicit"] = QVariant::fromValue(isExplicit); + helperAction->trigger(args); + } +} + +void HandleButtonEvents::triggerImpl(const QVariantMap& args) +{ + // For now, let's just accept the phantomatic "32" button. It is also always explicit + if (args["Button"].toInt() == 32) { + if (args.contains("Type")) { + triggerAction("SuspendSession", args["Type"], true); + } + } +} + +bool HandleButtonEvents::loadAction(const KConfigGroup& config) +{ + // Read configs + m_lidAction = config.readEntry("lidAction", 0); + m_powerButtonAction = config.readEntry("powerButtonAction", 0); + + return true; +} + +int HandleButtonEvents::lidAction() const +{ + return m_lidAction; +} + +void HandleButtonEvents::powerOffButtonTriggered() +{ + onButtonPressed(BackendInterface::PowerButton); +} + +void HandleButtonEvents::suspendToDisk() +{ + onButtonPressed(BackendInterface::HibernateButton); +} + +void HandleButtonEvents::suspendToRam() +{ + onButtonPressed(BackendInterface::SleepButton); +} + +} +} + +#include "handlebuttonevents.moc" diff --git a/powerdevil/daemon/actions/bundled/handlebuttonevents.h b/powerdevil/daemon/actions/bundled/handlebuttonevents.h new file mode 100644 index 00000000..8ea23f6e --- /dev/null +++ b/powerdevil/daemon/actions/bundled/handlebuttonevents.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTS_H +#define POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTS_H + +#include +#include + +namespace PowerDevil { +namespace BundledActions { + +class HandleButtonEvents : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(HandleButtonEvents) + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.Actions.HandleButtonEvents") + +public: + explicit HandleButtonEvents(QObject* parent); + virtual ~HandleButtonEvents(); + + virtual bool loadAction(const KConfigGroup& config); + virtual bool isSupported(); + +protected: + virtual void triggerImpl(const QVariantMap& args); + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + +public Q_SLOTS: + int lidAction() const; + +private Q_SLOTS: + void onButtonPressed(PowerDevil::BackendInterface::ButtonType type); + void powerOffButtonTriggered(); + void suspendToRam(); + void suspendToDisk(); + +private: + void processAction(uint action, bool isExplicit); + void triggerAction(const QString &action, const QVariant &type, bool isExplicit); + + uint m_lidAction; + uint m_powerButtonAction; + uint m_sleepButtonAction; + uint m_hibernateButtonAction; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTS_H diff --git a/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.cpp b/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.cpp new file mode 100644 index 00000000..0ab276af --- /dev/null +++ b/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "handlebuttoneventsconfig.h" + +#include "suspendsession.h" + +#include +#include +#include + +#include +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilSuspendSessionConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilSuspendSessionConfigFactory("powerdevilhandlebuttoneventsaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +HandleButtonEventsConfig::HandleButtonEventsConfig(QObject* parent, const QVariantList& ) + : ActionConfig(parent) +{ + +} + +HandleButtonEventsConfig::~HandleButtonEventsConfig() +{ + +} + + +void HandleButtonEventsConfig::save() +{ + if (m_lidCloseCombo) { + configGroup().writeEntry< uint >("lidAction", m_lidCloseCombo->itemData(m_lidCloseCombo->currentIndex()).toUInt()); + } + if (m_powerButtonCombo) { + configGroup().writeEntry< uint >("powerButtonAction", m_powerButtonCombo->itemData(m_powerButtonCombo->currentIndex()).toUInt()); + } + + configGroup().sync(); +} + +void HandleButtonEventsConfig::load() +{ + configGroup().config()->reparseConfiguration(); + + if (m_lidCloseCombo) { + m_lidCloseCombo->setCurrentIndex(m_lidCloseCombo->findData(QVariant::fromValue(configGroup().readEntry< uint >("lidAction", 0)))); + } + if (m_powerButtonCombo) { + m_powerButtonCombo->setCurrentIndex(m_powerButtonCombo->findData(QVariant::fromValue(configGroup().readEntry< uint >("powerButtonAction", 0)))); + } +} + +QList< QPair< QString, QWidget* > > HandleButtonEventsConfig::buildUi() +{ + // Create the boxes + m_lidCloseCombo = new KComboBox; + m_powerButtonCombo = new KComboBox; + + // Fill the boxes with options! + { + QList< KComboBox* > boxes; + boxes << m_lidCloseCombo << m_powerButtonCombo; + + QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); + + foreach (KComboBox *box, boxes) { + box->addItem(KIcon("dialog-cancel"), i18n("Do nothing"), (uint)SuspendSession::None); + if (methods.contains(Solid::PowerManagement::SuspendState)) { + box->addItem(KIcon("system-suspend"), i18n("Sleep"), (uint)SuspendSession::ToRamMode); + } + if (methods.contains(Solid::PowerManagement::HibernateState)) { + box->addItem(KIcon("system-suspend-hibernate"), i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); + } + box->addItem(KIcon("system-shutdown"), i18n("Shutdown"), (uint)SuspendSession::ShutdownMode); + box->addItem(KIcon("system-lock-screen"), i18n("Lock screen"), (uint)SuspendSession::LockScreenMode); + if (box != m_lidCloseCombo) { + box->addItem(KIcon("system-log-out"), i18n("Prompt log out dialog"), (uint)SuspendSession::LogoutDialogMode); + } + box->addItem(KIcon("preferences-desktop-screensaver"), i18n("Turn off screen"), (uint)SuspendSession::TurnOffScreenMode); + } + } + + connect(m_lidCloseCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + connect(m_powerButtonCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + + m_lidCloseCombo->setMaximumWidth(300); + m_powerButtonCombo->setMaximumWidth(300); + + bool lidFound = false; + bool powerFound = false; + // get a list of all devices that are Buttons + foreach (Solid::Device device, Solid::Device::listFromType(Solid::DeviceInterface::Button, QString())) { + Solid::Button *button = device.as(); + if (button->type() == Solid::Button::LidButton) { + lidFound = true; + } else if (button->type() == Solid::Button::PowerButton) { + powerFound = true; + } + } + + QList< QPair< QString, QWidget* > > retlist; + + if (lidFound) { + retlist.append(qMakePair< QString, QWidget* >(i18n("When laptop lid closed"), m_lidCloseCombo)); + } else { + m_lidCloseCombo->deleteLater(); + m_lidCloseCombo = 0; + } + + if (powerFound) { + retlist.append(qMakePair< QString, QWidget* >(i18n("When power button pressed"), m_powerButtonCombo)); + } else { + m_powerButtonCombo->deleteLater(); + m_powerButtonCombo = 0; + } + + return retlist; +} + +} +} + +#include "handlebuttoneventsconfig.moc" diff --git a/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.h b/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.h new file mode 100644 index 00000000..a55bca7d --- /dev/null +++ b/powerdevil/daemon/actions/bundled/handlebuttoneventsconfig.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTSCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTSCONFIG_H + +#include + +class KComboBox; +namespace PowerDevil { +namespace BundledActions { + +class HandleButtonEventsConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(HandleButtonEventsConfig) + +public: + HandleButtonEventsConfig(QObject* parent, const QVariantList&); + virtual ~HandleButtonEventsConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + KComboBox *m_lidCloseCombo; + KComboBox *m_powerButtonCombo; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_HANDLEBUTTONEVENTSCONFIG_H diff --git a/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.cpp b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.cpp new file mode 100644 index 00000000..d712b4c2 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright (C) 2012 by Michael Zanetti * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "keyboardbrightnesscontrol.h" + +#include "brightnessosdwidget.h" +#include "keyboardbrightnesscontroladaptor.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace PowerDevil { +namespace BundledActions { + +KeyboardBrightnessControl::KeyboardBrightnessControl(QObject* parent) + : Action(parent) +{ + // DBus + new KeyboardBrightnessControlAdaptor(this); + + setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings); + + connect(core()->backend(), SIGNAL(brightnessChanged(float,PowerDevil::BackendInterface::BrightnessControlType)), + this, SLOT(onBrightnessChangedFromBackend(float,PowerDevil::BackendInterface::BrightnessControlType))); + + KActionCollection* actionCollection = new KActionCollection( this ); + + KAction *globalAction = actionCollection->addAction("Increase Keyboard Brightness"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Increase Keyboard Brightness")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_KeyboardBrightnessUp)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(increaseKeyboardBrightness())); + + globalAction = actionCollection->addAction("Decrease Keyboard Brightness"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Decrease Keyboard Brightness")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_KeyboardBrightnessDown)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(decreaseKeyboardBrightness())); + + globalAction = actionCollection->addAction("Toggle Keyboard Backlight"); + globalAction->setText(i18nc("@action:inmenu Global shortcut", "Toggle Keyboard Backlight")); + globalAction->setGlobalShortcut(KShortcut(Qt::Key_KeyboardLightOnOff)); + connect(globalAction, SIGNAL(triggered(bool)), SLOT(toggleKeyboardBacklight())); +} + +KeyboardBrightnessControl::~KeyboardBrightnessControl() +{ + if (!m_brightnessOSD.isNull()) { + m_brightnessOSD.data()->deleteLater(); + } +} + +void KeyboardBrightnessControl::onProfileUnload() +{ + // +} + +void KeyboardBrightnessControl::onWakeupFromIdle() +{ + // +} + +void KeyboardBrightnessControl::onIdleTimeout(int msec) +{ + Q_UNUSED(msec); +} + +void KeyboardBrightnessControl::onProfileLoad() +{ + // This unparsable conditional block means: if the current profile is more + // conservative than the previous one and the current brightness is lower + // than the new profile + if (((m_currentProfile == "Battery" && m_lastProfile == "AC") || + (m_currentProfile == "LowBattery" && (m_lastProfile == "AC" || m_lastProfile == "Battery"))) && + m_defaultValue > keyboardBrightness()) { + // We don't want to change anything here + kDebug() << "Not changing keyboard brightness, the current one is lower and the profile is more conservative"; + } else if (m_defaultValue > 0) { + QVariantMap args; + args["Value"] = QVariant::fromValue((float)m_defaultValue); + trigger(args); + } +} + +void KeyboardBrightnessControl::triggerImpl(const QVariantMap& args) +{ + backend()->setBrightness(args["Value"].toFloat(), BackendInterface::Keyboard); + if (args["Explicit"].toBool()) { + showBrightnessOSD(backend()->brightness(BackendInterface::Keyboard)); + } +} + +bool KeyboardBrightnessControl::isSupported() +{ + BackendInterface::BrightnessControlsList controls = backend()->brightnessControlsAvailable(); + if (controls.key(BackendInterface::Keyboard).isEmpty()) { + return false; + } + + return true; +} + +bool KeyboardBrightnessControl::loadAction(const KConfigGroup& config) +{ + // Handle profile changes + m_lastProfile = m_currentProfile; + m_currentProfile = config.parent().name(); + + kDebug() << "Profiles: " << m_currentProfile << m_lastProfile; + + if (config.hasKey("value")) { + m_defaultValue = config.readEntry("value", 50); + } else { + m_defaultValue = -1; + } + + return true; +} + +void KeyboardBrightnessControl::showBrightnessOSD(int brightness) +{ + // code adapted from KMix + if (m_brightnessOSD.isNull()) { + m_brightnessOSD = new BrightnessOSDWidget(BackendInterface::Keyboard); + } + + m_brightnessOSD.data()->setCurrentBrightness(brightness); + m_brightnessOSD.data()->show(); + m_brightnessOSD.data()->activateOSD(); //Enable the hide timer + + //Center the OSD + QRect rect = KApplication::kApplication()->desktop()->screenGeometry(QCursor::pos()); + QSize size = m_brightnessOSD.data()->sizeHint(); + int posX = rect.x() + (rect.width() - size.width()) / 2; + int posY = rect.y() + 4 * rect.height() / 5; + m_brightnessOSD.data()->setGeometry(posX, posY, size.width(), size.height()); +} + +void KeyboardBrightnessControl::onBrightnessChangedFromBackend(float brightness, PowerDevil::BackendInterface::BrightnessControlType type) +{ + if (type == BackendInterface::Keyboard) { + showBrightnessOSD(brightness); + Q_EMIT keyboardBrightnessChanged(brightness); + } +} + +void KeyboardBrightnessControl::increaseKeyboardBrightness() +{ + backend()->brightnessKeyPressed(BackendInterface::Increase, BackendInterface::Keyboard); +} + +void KeyboardBrightnessControl::decreaseKeyboardBrightness() +{ + backend()->brightnessKeyPressed(BackendInterface::Decrease, BackendInterface::Keyboard); +} + +void KeyboardBrightnessControl::toggleKeyboardBacklight() +{ + backend()->brightnessKeyPressed(BackendInterface::Toggle, BackendInterface::Keyboard); +} + +int KeyboardBrightnessControl::keyboardBrightness() const +{ + return backend()->brightness(BackendInterface::Keyboard); +} + +void KeyboardBrightnessControl::setKeyboardBrightness(int percent) +{ + QVariantMap args; + args["Value"] = QVariant::fromValue((float)percent); + args["Explicit"] = true; + trigger(args); +} + +} +} diff --git a/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.h b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.h new file mode 100644 index 00000000..59affda3 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrol.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2012 by Michael Zanetti * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROL_H +#define POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROL_H + +#include +#include + +class BrightnessOSDWidget; + +namespace PowerDevil { +namespace BundledActions { + +class KeyboardBrightnessControl : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(KeyboardBrightnessControl) + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl") + +public: + explicit KeyboardBrightnessControl(QObject* parent); + virtual ~KeyboardBrightnessControl(); + +protected: + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + virtual bool isSupported(); + +public: + virtual bool loadAction(const KConfigGroup& config); + +public Q_SLOTS: + void showBrightnessOSD(int brightness); + void onBrightnessChangedFromBackend(float brightness, PowerDevil::BackendInterface::BrightnessControlType type); + + // DBus export + void increaseKeyboardBrightness(); + void decreaseKeyboardBrightness(); + void toggleKeyboardBacklight(); + + int keyboardBrightness() const; + void setKeyboardBrightness(int percent); + +Q_SIGNALS: + void keyboardBrightnessChanged(int percent); + +private: + int m_defaultValue; + QWeakPointer< BrightnessOSDWidget > m_brightnessOSD; + QString m_lastProfile; + QString m_currentProfile; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROL_H diff --git a/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.cpp b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.cpp new file mode 100644 index 00000000..9887b3ba --- /dev/null +++ b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "keyboardbrightnesscontrolconfig.h" + +#include +#include +#include + +#include +#include + +K_PLUGIN_FACTORY(PowerDevilKeyboardBrightnessControlConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilKeyboardBrightnessControlConfigFactory("powerdevilkeyboardbrightnesscontrolaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +KeyboardBrightnessControlConfig::KeyboardBrightnessControlConfig(QObject *parent, const QVariantList& ) + : ActionConfig(parent) +{ + +} + +KeyboardBrightnessControlConfig::~KeyboardBrightnessControlConfig() +{ + +} + +void KeyboardBrightnessControlConfig::save() +{ + configGroup().writeEntry("value", m_slider->value()); + configGroup().sync(); +} + +void KeyboardBrightnessControlConfig::load() +{ + configGroup().config()->reparseConfiguration(); + m_slider->setValue(configGroup().readEntry("value", 50)); +} + +QList< QPair< QString, QWidget* > > KeyboardBrightnessControlConfig::buildUi() +{ + QList< QPair< QString, QWidget* > > retlist; + m_slider = new QSlider(Qt::Horizontal); + m_slider->setMaximumWidth(300); + m_slider->setRange(0, 100); + retlist.append(qMakePair< QString, QWidget* >(i18nc("@label:slider Brightness level", "Level"), m_slider)); + + connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + + +} +} + +#include "keyboardbrightnesscontrolconfig.moc" diff --git a/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.h b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.h new file mode 100644 index 00000000..08126d1b --- /dev/null +++ b/powerdevil/daemon/actions/bundled/keyboardbrightnesscontrolconfig.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROLCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROLCONFIG_H + +#include + +#include + +class QSlider; + +namespace PowerDevil { +namespace BundledActions { + +class KDE_EXPORT KeyboardBrightnessControlConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(KeyboardBrightnessControlConfig) +public: + KeyboardBrightnessControlConfig(QObject*, const QVariantList&); + virtual ~KeyboardBrightnessControlConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + QSlider *m_slider; +}; + +} +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_KEYBOARDBRIGHTNESSCONTROLCONFIG_H diff --git a/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml new file mode 100644 index 00000000..9c4d3df5 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml new file mode 100644 index 00000000..68b21653 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml new file mode 100644 index 00000000..08b54077 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml new file mode 100644 index 00000000..7e4cab44 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/powerdevil/daemon/actions/bundled/powerdevilbrightnesscontrolaction.desktop b/powerdevil/daemon/actions/bundled/powerdevilbrightnesscontrolaction.desktop new file mode 100644 index 00000000..45d059a2 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevilbrightnesscontrolaction.desktop @@ -0,0 +1,106 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +X-KDE-Library=powerdevilbrightnesscontrolaction_config +Icon=preferences-system-power-management +Name=Screen Brightness +Name[bs]=Osvetljaj ekrana +Name[ca]=Lluminositat de la pantalla +Name[ca@valencia]=Lluminositat de la pantalla +Name[cs]=Jas obrazovky +Name[da]=Skærmens lysstyrke +Name[de]=Bildschirmhelligkeit +Name[el]=Φωτεινότητα οθόνης +Name[en_GB]=Screen Brightness +Name[es]=Brillo de la pantalla +Name[et]=Ekraani heledus +Name[eu]=Pantailaren distira +Name[fi]=Näytön kirkkaus +Name[fr]=Luminosité de l'écran +Name[gl]=Brillo da pantalla +Name[hu]=Képernyő fényessége +Name[ia]=Brillantia de Schermo +Name[kk]=Экран жарықтығы +Name[ko]=화면 밝기 +Name[lt]=Ekrano šviesumas +Name[nb]=Skjermlysstyrke +Name[nds]=Schirm-Helligkeit +Name[nl]=Schermhelderheid +Name[pa]=ਸਕਰੀਨ ਚਮਕ +Name[pl]=Jasność ekranu +Name[pt]=Brilho do Ecrã +Name[pt_BR]=Brilho da tela +Name[ro]=Luminozitate ecran +Name[ru]=Яркость экрана +Name[sk]=Jas obrazovky +Name[sl]=Svetlost zaslona +Name[sr]=Осветљај екрана +Name[sr@ijekavian]=Освјетљај екрана +Name[sr@ijekavianlatin]=Osvjetljaj ekrana +Name[sr@latin]=Osvetljaj ekrana +Name[sv]=Skärmljusstyrka +Name[tr]=Ekran Parlaklığı +Name[uk]=Яскравість екрана +Name[x-test]=xxScreen Brightnessxx +Name[zh_CN]=屏幕亮度 +Name[zh_TW]=螢幕亮度 +Comment=Basic Controls for brightness +Comment[ast]=Control básicu del brillu +Comment[bg]=Основни настройки на яркостта +Comment[bs]=Osnovne kontrole osvetljaja +Comment[ca]=Controls bàsics per la lluminositat +Comment[ca@valencia]=Controls bàsics per la lluminositat +Comment[cs]=Základní ovládání jasu +Comment[da]=Basal kontrol af lysstyrke +Comment[de]=Grundeinstellungen zur Bildschirmhelligkeit +Comment[el]=Βασικά στοιχεία ελέγχου λαμπρότητας +Comment[en_GB]=Basic Controls for brightness +Comment[es]=Control básico del brillo +Comment[et]=Heleduse lihtne juhtimine +Comment[eu]=Distiraren oinarrizko kontrolak +Comment[fi]=Kirkkauden perussäätimet +Comment[fr]=Contrôles simples de la luminosité +Comment[gl]=Controis básicos do brillo +Comment[he]=בקרים בסיסיים לשליטה בבהירות +Comment[hr]=Osnovne kontrole za osvjetljenje +Comment[hu]=Alap fényerő-beállítások +Comment[ia]=Controlos basic pro brillantia +Comment[is]=Grunnstýringar fyrir birtustig +Comment[kk]=Жарықтығының негізгі тұтқалары +Comment[km]=ការ​ត្រួតពិនិត្យ​ពន្លឺ​ជា​មូលដ្ឋាន +Comment[ko]=기본 밝기 제어 +Comment[lt]=Pagrindiniai šviesumo valdikliai +Comment[lv]=Pamata gaišuma vadīklas +Comment[mr]=प्रखरतेसाठी मूलभूत नियंत्रण +Comment[nb]=Grunnleggende lysstyrkestyring +Comment[nds]=Eenfach Helligkeit-Instellen +Comment[nl]=Basisbesturing voor helderheid +Comment[pa]=ਚਮਕ ਲਈ ਮੁੱਢਲੇ ਕੰਟਰੋਲ +Comment[pl]=Podstawowe sterowanie jasnością +Comment[pt]=Controlos básicos do brilho +Comment[pt_BR]=Controles básicos do brilho +Comment[ro]=Controale de bază pentru luminozitate +Comment[ru]=Базовые функции управления яркостью +Comment[sk]=Základné ovládanie jasu +Comment[sl]=Osnovni nadzor svetlosti +Comment[sr]=Основне контроле осветљаја +Comment[sr@ijekavian]=Основне контроле освјетљаја +Comment[sr@ijekavianlatin]=Osnovne kontrole osvjetljaja +Comment[sr@latin]=Osnovne kontrole osvetljaja +Comment[sv]=Grundkontroller för ljusstyrka +Comment[th]=การควบคุมพื้นฐานสำหรับความสว่าง +Comment[tr]=Parlaklık için temel kontroller +Comment[ug]=يورۇقلۇقنىڭ ئاساسىي تىزگىنى +Comment[uk]=Базове керування яскравістю +Comment[vi]=Điều khiển độ sáng cơ bản +Comment[wa]=Controles di båze pol rilujhance +Comment[x-test]=xxBasic Controls for brightnessxx +Comment[zh_CN]=亮度基本控制 +Comment[zh_TW]=基本亮度控制 + +X-KDE-PowerDevil-Action-ID=BrightnessControl +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevilbrightnesscontrolaction_config +X-KDE-PowerDevil-Action-ConfigPriority=100 +X-KDE-PowerDevil-Action-HasRuntimeRequirement=true +X-KDE-PowerDevil-Action-RegistersDBusInterface=true diff --git a/powerdevil/daemon/actions/bundled/powerdevildimdisplayaction.desktop b/powerdevil/daemon/actions/bundled/powerdevildimdisplayaction.desktop new file mode 100644 index 00000000..1aad371a --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevildimdisplayaction.desktop @@ -0,0 +1,106 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +# X-KDE-Library=powerdevildimdisplayaction +Icon=preferences-desktop-display +Name=Dim Screen +Name[bs]=Dim ekran +Name[ca]=Enfosquiment de pantalla +Name[ca@valencia]=Enfosquiment de pantalla +Name[cs]=Ztmavit obrazovku +Name[da]=Dæmp skærmen +Name[de]=Bildschirm abdunkeln +Name[el]=Σκίαση οθόνης +Name[en_GB]=Dim Screen +Name[es]=Oscurecer pantalla +Name[et]=Ekraani tumendamine +Name[eu]=Ilundu leihoa +Name[fi]=Näytön himmennys +Name[fr]=Régler la luminosité de l'écran +Name[gl]=Atenuar a pantalla +Name[hu]=Képernyő homályosítása +Name[ia]=Obscura Schermo +Name[kk]=Экранды қараңғы қылу +Name[ko]=화면 어둡게 하기 +Name[lt]=Užtemdyti ekraną +Name[nb]=Mørklegg skjerm +Name[nds]=Schirmafdüüstern +Name[nl]=Scherm dimmen +Name[pa]=ਸਕਰੀਨ ਡਿਮ +Name[pl]=Przyciemnij ekran +Name[pt]=Escurecer o Ecrã +Name[pt_BR]=Escurecer a tela +Name[ro]=Întunecă ecranul +Name[ru]=Потухание экрана +Name[sk]=Stmaviť obrazovku +Name[sl]=Potemni zaslon +Name[sr]=Пригуши екран +Name[sr@ijekavian]=Пригуши екран +Name[sr@ijekavianlatin]=Priguši ekran +Name[sr@latin]=Priguši ekran +Name[sv]=Dämpa skärmen +Name[tr]=Ekranı kapat +Name[uk]=Зменшення яскравості екрана +Name[x-test]=xxDim Screenxx +Name[zh_CN]=暗淡屏幕 +Name[zh_TW]=將螢幕變暗 +Comment=Dims gradually the display on a time basis +Comment[ast]=Atenúa la pantalla gradualmente según pasa'l tiempu +Comment[bg]=Постепенно затъмняване на екрана след определено време +Comment[bs]=Postepeno prigušuje ekran na zadato vrijeme +Comment[ca]=Atenua gradualment la pantalla en funció del temps +Comment[ca@valencia]=Atenua gradualment la pantalla en funció del temps +Comment[cs]=Postupné ztmavení obrazovky +Comment[da]=Dæmper skærmen gradvist baseret på tid +Comment[de]=Dunkelt den Bildschirm zeitgesteuert ab +Comment[el]=Μειώνει σταδιακά στο χρόνο την φωτεινότητα της οθόνης +Comment[en_GB]=Dims gradually the display on a time basis +Comment[es]=Oscurece la pantalla gradualmente según pasa el tiempo +Comment[et]=Kuva järkjärguline tumendamine aega arvestades +Comment[eu]=Bistaratzea pixkanaka iluntzen du +Comment[fi]=Himmentää näyttöä vaiheittain ajan perusteella +Comment[fr]=Assombrit graduellement l'affichage sur une base de temps +Comment[gl]=Escurece progresivamente a pantalla segundo o tempo +Comment[he]=משמש לעמעום הדרגתי של הצג על בסיס זמן +Comment[hr]=Postepeno prigušuje zaslon na vremenskoj osnovi +Comment[hu]=Fokozatos elhalványítja a kijelzőt egy adott idő után +Comment[ia]=Obscura gradualmente le monstrator usante como base le tempore +Comment[is]=Dimmir skjáborðið smátt og smátt +Comment[ja]=ディスプレイを時間とともに徐々に暗くする +Comment[kk]=Дисплей жарықтығын біртіндеп азайту +Comment[km]=ធ្វើ​ឲ្យ​​ការ​បង្ហាញ​ព្រិល​ៗ​ទៅ​តាម​​ពេលវេលា​ +Comment[kn]=ಸಮಯಕ್ಕೆ ಅನುಗುಣವಾಗಿ ಪ್ರದರ್ಶಕವನ್ನು ನಿಧಾನವಾಗಿ ಮಬ್ಬುಗೊಳಿಸುತ್ತದೆ +Comment[ko]=밝기를 단계적으로 어둡게 합니다 +Comment[lt]=Laikui bėgant, dalinai pritamsina ekraną +Comment[lv]=Pakāpeniski patumšina ekrānu atkarībā no laika +Comment[mr]=वेळे नुसार क्रमाक्रमाने डिस्प्ले फीका करतो +Comment[nb]=Mørklegger skjermen gradvis etter som tiden går +Comment[nds]=Maakt de Schirm na en vörinstellt Tiet düüsterer +Comment[nl]=Dimt geleidelijk het beeldscherm op basis van tijd +Comment[pa]=ਸਮੇਂ ਨਾਲ ਡਿਸਪਲੇਅ ਨੂੰ ਲਗਾਤਾਰ ਡਿਮ ਕਰੋ +Comment[pl]=Po podanym czasie, stopniowo przyciemnia wyświetlacz +Comment[pt]=Escurece gradualmente o ecrã durante um dado período +Comment[pt_BR]=Escurece gradualmente a tela durante um período +Comment[ro]=Întunecă gradual ecranul în dependență de timp +Comment[ru]=Экран медленно затухает со временем +Comment[sk]=Postupne stmavie obrazovku v závislosti na čase +Comment[sl]=Postopoma potemni zaslon +Comment[sr]=Постепено пригушује екран на задато време +Comment[sr@ijekavian]=Постепено пригушује екран на задато вријеме +Comment[sr@ijekavianlatin]=Postepeno prigušuje ekran na zadato vrijeme +Comment[sr@latin]=Postepeno prigušuje ekran na zadato vreme +Comment[sv]=Dämpa bildskärmen gradvis baserat på tid +Comment[th]=ลดความสว่างจอภาพลงเมื่อถึงช่วงเวลาตามที่กำหนด +Comment[tr]=Zamana bağlı olarak ekranı karart +Comment[uk]=Поступове зменшення яскравості дисплея з часом +Comment[vi]=Làm tối dần màn hình theo thời gian +Comment[wa]=Baxhe pitchote a midjote li håynaedje so ene båze di tins +Comment[x-test]=xxDims gradually the display on a time basisxx +Comment[zh_CN]=在一定时间逐步变暗屏幕 +Comment[zh_TW]=依時間逐漸讓顯示變暗 + +X-KDE-PowerDevil-Action-ID=DimDisplay +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevildimdisplayaction_config +X-KDE-PowerDevil-Action-ConfigPriority=99 +X-KDE-PowerDevil-Action-HasRuntimeRequirement=true diff --git a/powerdevil/daemon/actions/bundled/powerdevilhandlebuttoneventsaction.desktop b/powerdevil/daemon/actions/bundled/powerdevilhandlebuttoneventsaction.desktop new file mode 100644 index 00000000..081d5861 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevilhandlebuttoneventsaction.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +# X-KDE-Library=powerdevilhandlebuttoneventsaction +Icon=system-suspend + +Name=Button events handling +Name[ast]=Remanar eventos botón +Name[bg]=Събития при натискане бутони +Name[bs]=Rukovanje događajima dugmadi +Name[ca]=Gestió d'esdeveniments de botons +Name[ca@valencia]=Gestió d'esdeveniments de botons +Name[cs]=Řízení událostí tlačítek +Name[da]=Håndtering af knaphændelser +Name[de]=Knopf-Ereignisbehandlung +Name[el]=Διαχείριση συμβάντων +Name[en_GB]=Button events handling +Name[es]=Gestión de eventos de botón +Name[et]=Nupusündmuste kohtlemine +Name[eu]=Botoi-gertaeren kudeaketa +Name[fi]=Näppäintapahtumien käsittely +Name[fr]=Prise en charge des évènements de boutons +Name[gl]=Xestión dos acontecementos nos botóns +Name[he]=טיפול באירועי לחצנים +Name[hr]=Rukovanje događajima gumbiju +Name[hu]=Gombesemények kezelése +Name[ia]=Button maneante de eventos +Name[is]=Meðhöndlun hnappaatburða +Name[kk]=Батырма басуға көңіл болу +Name[km]=ការ​គ្រប់គ្រង​ប៊ូតុង​​ព្រឹត្តិការណ៍​​ +Name[ko]=단추 이벤트 처리 +Name[lt]=Mygtukų įvykių valdymas +Name[lv]=Taustiņu darbību apstrāde +Name[mr]=बटन घटना हाताळणी +Name[nb]=Håndtering av knappehendelser +Name[nds]=Knoop för't Ümgahn mit Begeefnissen +Name[nl]=Knop voor afhandelen van evenementen +Name[pa]=ਬਟਨ ਈਵੈਂਟ ਹੈਡਲਿੰਗ +Name[pl]=Obsługuj następujące zdarzenia +Name[pt]=Tratamento dos eventos dos botões +Name[pt_BR]=Tratamento de eventos dos botões +Name[ro]=Manipularea evenimentelor de la butoane +Name[ru]=Обработка событий от кнопок +Name[sk]=Spracovanie udalostí tlačidiel +Name[sl]=Rokovanje z dogodki gumbov +Name[sr]=Руковање догађајима дугмади +Name[sr@ijekavian]=Руковање догађајима дугмади +Name[sr@ijekavianlatin]=Rukovanje događajima dugmadi +Name[sr@latin]=Rukovanje događajima dugmadi +Name[sv]=Händelsehantering för knappar +Name[th]=การจัดการกับเหตุการณ์ของปุ่ม +Name[tr]=Düğme işlevlerini ata +Name[ug]=توپچا ھادىسىنى باشقۇرۇش +Name[uk]=Обробка натискань кнопок +Name[vi]=Xử lý sự kiện nhấn nút +Name[wa]=Apougnaedje des evenmints des botons +Name[x-test]=xxButton events handlingxx +Name[zh_CN]=按键事件处理 +Name[zh_TW]=按鍵事件處理 + +Comment=Performs an action whenever a button is pressed +Comment[ast]=Facer aiciones cuando se calque un botón +Comment[bg]=Изпълнява действие при натискане на бутони +Comment[bs]=Izvršava radnju na svaki pritisak dugmeta +Comment[ca]=Porta a terme una acció quan es prem un botó +Comment[ca@valencia]=Porta a terme una acció quan es prem un botó +Comment[cs]=Vykoná akci kdykoli je tlačítko stisknuto +Comment[da]=Udfører en handling når der trykkes på en knap +Comment[de]=Führt eine Aktion aus, sobald ein Knopf gedrückt wird +Comment[el]=Εκτελεί μία λειτουργία όποτε ένα κουμπί πιέζεται +Comment[en_GB]=Performs an action whenever a button is pressed +Comment[es]=Realiza una acción cuando se presiona un botón +Comment[et]=Toimingu sooritamine, kui vajutatakse nuppu +Comment[eu]=Ekintza bat gauzatzen du botoi bat sakatzen den bakoitzean +Comment[fi]=Suorittaa toiminnon painiketta painettaessa +Comment[fr]=Effectue une action à chaque fois qu'un bouton est pressé +Comment[gl]=Realiza unha acción cando se prema un botón +Comment[he]=משמש לביצוע פעולה בלחיצה על לחצן +Comment[hr]=Izvršava radnju kad god se pritisne gumb +Comment[hu]=Végrehajt egy műveletet, valahányszor egy gomb megnyomásra kerül +Comment[ia]=Il executa un action quando un button es pressate +Comment[is]=Framkvæmir aðgerð í hvert skipti sem ýtt er á hnapp +Comment[kk]=Әрқашанда батырмасы басылғанда әрекетін орындау +Comment[km]=អនុវត្ត​សកម្មភាព​នៅពេល​ដែល​ចុច​ប៊ូតុង +Comment[ko]=단추가 눌렸을 때 동작을 실행합니다 +Comment[lt]=Įvykdo veiksmą kiekvieną kartą paspaudus mygtuką +Comment[lv]=Izpilda darbību, kad tiek nospiests taustiņš +Comment[mr]=कधीही बटन दाबल्यावर एक क्रिया कार्यान्वित करतो +Comment[nb]=Utfører en handling hver gang en knapp trykkes +Comment[nds]=Föhrt en Akschoon ut, wenn en Knoop drückt warrt +Comment[nl]=Voer een actie uit als er een knop wordt ingedrukt +Comment[pa]=ਜਦੋਂ ਬਟਨ ਦੱਬਿਆ ਜਾਵੇ ਤਾਂ ਕਾਰਵਾਈ ਕਰੋ +Comment[pl]=Wykonuje działanie przy każdorazowym naciśnięciu przycisku +Comment[pt]=Efectua uma acção quando carregar num botão +Comment[pt_BR]=Executa uma ação sempre que um botão é pressionado +Comment[ro]=Îndeplinește o acțiune la apăsarea unui buton +Comment[ru]=Выполняет действие при нажатии кнопки +Comment[sk]=Vykoná akcie kedykoľvek je stlačené tlačidlo +Comment[sl]=Ob pritisku na gumb izvede dejanje +Comment[sr]=Извршава радњу на сваки притисак дугмета +Comment[sr@ijekavian]=Извршава радњу на сваки притисак дугмета +Comment[sr@ijekavianlatin]=Izvršava radnju na svaki pritisak dugmeta +Comment[sr@latin]=Izvršava radnju na svaki pritisak dugmeta +Comment[sv]=Utför en åtgärd så fort en knapp trycks ner +Comment[th]=ดำเนินการการกระทำเมื่อกดปุ่ม +Comment[tr]=Bir düğmeye basıldığında bir eylem gerçekleştirir +Comment[ug]=بىر توپچا بېسىلغاندا بىر مەشغۇلاتنى جەزملەيدۇ +Comment[uk]=Виконання дій у відповідь на натискання кнопки +Comment[wa]=Fwait on faitindje cwand on boton est tchôkî +Comment[x-test]=xxPerforms an action whenever a button is pressedxx +Comment[zh_CN]=按键时执行一个动作 +Comment[zh_TW]=按鍵被按下時執行動作 + +X-KDE-PowerDevil-Action-ID=HandleButtonEvents +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevilhandlebuttoneventsaction_config +X-KDE-PowerDevil-Action-ConfigPriority=80 +X-KDE-PowerDevil-Action-HasRuntimeRequirement=true +X-KDE-PowerDevil-Action-RegistersDBusInterface=true diff --git a/powerdevil/daemon/actions/bundled/powerdevilkeyboardbrightnesscontrolaction.desktop b/powerdevil/daemon/actions/bundled/powerdevilkeyboardbrightnesscontrolaction.desktop new file mode 100644 index 00000000..069f6e46 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevilkeyboardbrightnesscontrolaction.desktop @@ -0,0 +1,98 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +X-KDE-Library=powerdevilkeyboardbrightnesscontrolaction_config +Icon=input-keyboard +Name=Keyboard Backlight +Name[bs]=Pozadinsko osvjetljenje tastature +Name[ca]=Retroil·luminació del teclat +Name[ca@valencia]=Retroil·luminació del teclat +Name[cs]=Podsvícení klávesnice +Name[da]=Tastaturets baglys +Name[de]=Tastatur-Hintergrundhelligkeit +Name[el]=Φωτισμός πληκτρολογίου +Name[en_GB]=Keyboard Backlight +Name[es]=Luz trasera del teclado +Name[et]=Klaviatuuri tagavalgustus +Name[eu]=Teklatuaren atzeko argia +Name[fi]=Näppäimistön taustavalo +Name[fr]=Rétroéclairage du clavier +Name[gl]=Luz do teclado +Name[he]=תאורה אחורית של מקלדת +Name[hu]=Billentyűzet háttérvilágítás +Name[ia]=Luce de retro (Backlight) de claviero +Name[kk]=Перенетақта жарықтығы +Name[ko]=키보드 백라이트 +Name[lt]=Klaviatūros apšvietimas +Name[mr]=कळफलक मागील प्रकाश +Name[nb]=Tastaturbaklys +Name[nds]=Tastatuur-Achterlicht +Name[nl]=Toetsenbordverlichting +Name[pa]=ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ +Name[pl]=Podświetlenie klawiatury +Name[pt]=Luz Traseira do Teclado +Name[pt_BR]=Iluminação do teclado +Name[ro]=Iluminarea tastaturii +Name[ru]=Подсветка клавиатуры +Name[sk]=Spätné svetlo klávesnice +Name[sl]=Osvetlitev tipkovnice +Name[sr]=Осветљење тастатуре +Name[sr@ijekavian]=Осветљење тастатуре +Name[sr@ijekavianlatin]=Osvetljenje tastature +Name[sr@latin]=Osvetljenje tastature +Name[sv]=Bakgrundsbelysning på tangentbord +Name[tr]=Klavye Arkaışığı +Name[uk]=Підсвічування клавіатури +Name[x-test]=xxKeyboard Backlightxx +Name[zh_CN]=键盘背光 +Name[zh_TW]=鍵盤背光 +Comment=Basic Controls for the keyboard backlight brightness +Comment[bs]=Osnovne kontrole osvetljaja pozadine tastature +Comment[ca]=Controls bàsics per la brillantor de la retroil·luminació del teclat +Comment[ca@valencia]=Controls bàsics per la brillantor de la retroil·luminació del teclat +Comment[cs]=Základní ovládání jasu podsvícení klávesnice +Comment[da]=Basal kontrol af lysstyrke på tastaturets baglys +Comment[de]=Grundeinstellungen zur Hintergrundhelligkeit der Tastatur +Comment[el]=Βασικά στοιχεία ελέγχου λαμπρότητας στο φωτισμό του πληκτρολογίου +Comment[en_GB]=Basic Controls for the keyboard backlight brightness +Comment[es]=Control básico del brillo de la luz trasera del teclado +Comment[et]=Klaviatuuri tagavalgustuse lihtne juhtimine +Comment[eu]=Teklatuaren atzeko-argi distiraren oinarrizko aginteak +Comment[fi]=Näppäimistön taustavalon kirkkauden perussäätimet +Comment[fr]=Contrôles simples de la luminosité pour le rétro-éclairage du clavier +Comment[gl]=Controis básicos do brillo da luz do teclado +Comment[hu]=Alap vezérlők a billentyűzet háttérvilágításának fényerejéhez +Comment[ia]=Controlos basic pro intensitatede illumination de luce de retro de claviero +Comment[is]=Grunnstýringar fyrir baklýsingarbirtustig lyklaborðs +Comment[kk]=Пернетақта жарықтық күшінің негізгі тұтқалары +Comment[ko]=키보드 백라이트 기본 밝기 제어 +Comment[lt]=Pagrindiniai klaviatūros apšvietimo valdikliai +Comment[mr]=कळफलक मागील प्रकाशाच्या प्रखरतेसाठी मूलभूत नियंत्रण +Comment[nb]=Enkel styring av lysstyrke for tastaturbaklys +Comment[nds]=Helligkeit-Instellen för't Tastatuur-Achterlicht +Comment[nl]=Basisbesturing voor helderheid van de toetsenbordverlichting +Comment[pa]=ਕੀਬੋਰਡ ਬੈਕਲਿਟ ਚਮਕ ਲਈ ਮੁੱਢਲੇ ਕੰਟਰੋਲ +Comment[pl]=Podstawowe sterowanie dla jasności podświetlenia klawiatury +Comment[pt]=Controlos básicos do brilho da luz traseira do teclado +Comment[pt_BR]=Controles básicos da iluminação do teclado +Comment[ro]=Controale de bază pentru luminozitatea iluminării tastaturii +Comment[ru]=Базовое управление подсветкой клавиатуры +Comment[sk]=Základné ovládacie prvky pre jas spätného svetla klávesnice +Comment[sl]=Osnovni nadzor osvetlitve tipkovnice +Comment[sr]=Основне контроле осветљења тастатуре +Comment[sr@ijekavian]=Основне контроле осветљења тастатуре +Comment[sr@ijekavianlatin]=Osnovne kontrole osvetljenja tastature +Comment[sr@latin]=Osnovne kontrole osvetljenja tastature +Comment[sv]=Grundkontroller för ljusstyrka av tangentbordets bakgrundsbelysning +Comment[tr]=Klavyenin arkaışık parlaklığı için Temel Kontroller +Comment[uk]=Базове керування яскравістю підсвічування клавіатури +Comment[x-test]=xxBasic Controls for the keyboard backlight brightnessxx +Comment[zh_CN]=键盘背光亮度基本控制 +Comment[zh_TW]=鍵盤背光亮度的基本控制 + +X-KDE-PowerDevil-Action-ID=KeyboardBrightnessControl +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevilkeyboardbrightnesscontrolaction_config +X-KDE-PowerDevil-Action-ConfigPriority=100 +X-KDE-PowerDevil-Action-HasRuntimeRequirement=true +X-KDE-PowerDevil-Action-RegistersDBusInterface=true diff --git a/powerdevil/daemon/actions/bundled/powerdevilrunscriptaction.desktop b/powerdevil/daemon/actions/bundled/powerdevilrunscriptaction.desktop new file mode 100644 index 00000000..3b157228 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevilrunscriptaction.desktop @@ -0,0 +1,120 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +# X-KDE-Library=powerdevilrunscriptaction +Icon=system-run +Name=Run Script +Name[ar]=تشغيل سكربت +Name[ast]=Executar guión +Name[bg]=Изпълнение на скрипт +Name[bs]=Izvrši skriptu +Name[ca]=Executa un script +Name[ca@valencia]=Executa un script +Name[cs]=Spustit skript +Name[da]=Kør script +Name[de]=Skript ausführen +Name[el]=Εκτέλεση σεναρίου +Name[en_GB]=Run Script +Name[es]=Ejecutar guion +Name[et]=Skripti käivitamine +Name[eu]=Exekutatu scripta +Name[fi]=Suorita skripti +Name[fr]=Démarrer un script +Name[ga]=Rith Script +Name[gl]=Executar un script +Name[he]=הרצת תסריט +Name[hi]=स्क्रिप्ट चलाएँ +Name[hr]=Pokreni skriptu +Name[hu]=Parancsfájl futtatása +Name[ia]=Exeque script +Name[is]=Keyra skriftu +Name[ja]=スクリプトを実行 +Name[kk]=Скриптті орындау +Name[km]=ដំណើរការ​ស្គ្រីប +Name[ko]=스크립트 실행 +Name[lt]=Paleisti scenarijų +Name[lv]=Palaist skriptu +Name[mr]=स्क्रिप्ट चालवा +Name[nb]=Kjør skript +Name[nds]=Skript utföhren +Name[nl]=Script uitvoeren +Name[pa]=ਸਕ੍ਰਿਪਟ ਚਲਾਓ +Name[pl]=Uruchom skrypt +Name[pt]=Executar um Programa +Name[pt_BR]=Executar script +Name[ro]=Rulează script +Name[ru]=Запустить сценарий +Name[sk]=Spustiť skript +Name[sl]=Zaženi skript +Name[sr]=Изврши скрипту +Name[sr@ijekavian]=Изврши скрипту +Name[sr@ijekavianlatin]=Izvrši skriptu +Name[sr@latin]=Izvrši skriptu +Name[sv]=Kör skript +Name[th]=ให้สคริปต์ทำงาน +Name[tr]=Betik Çalıştır +Name[ug]=قوليازما ئىجرا قىل +Name[uk]=Виконати скрипт +Name[wa]=Enonder scripe +Name[x-test]=xxRun Scriptxx +Name[zh_CN]=运行脚本 +Name[zh_TW]=執行文稿 +Comment=Runs a custom script +Comment[ast]=Executa un guión personalizáu +Comment[bg]=Изпълнение на потребителски скрипт +Comment[bs]=Izvršava posebnu skriptu +Comment[ca]=Executa un script personalitzat +Comment[ca@valencia]=Executa un script personalitzat +Comment[cs]=Spustit vlastní skript +Comment[da]=Kører et brugerdefineret script +Comment[de]=Führt ein benutzerdefiniertes Skript aus +Comment[el]=Εκτελεί ένα προσαρμοσμένο σενάριο +Comment[en_GB]=Runs a custom script +Comment[es]=Ejecuta un guion personalizado +Comment[et]=Kohandatud skripti käivitamine +Comment[eu]=Script pertsonalizatu bat exekutatzen du +Comment[fi]=Suorittaa mukautetun skriptin +Comment[fr]=Démarre un script personnalisé +Comment[ga]=Rith script shaincheaptha +Comment[gl]=Executa un script +Comment[he]=משמש להרצת תסריט מותאם אישית +Comment[hr]=Pokreće prilagođene skripte +Comment[hu]=Egyéni parancsfájl futtatása +Comment[ia]=Il exeque un script personalisate +Comment[is]=Keyra sérsniðna skriftu +Comment[ja]=カスタムスクリプトを実行 +Comment[kk]=Пайдаланушының скриптін орындау +Comment[km]=ដំណើរការ​ស្គ្រីប​ផ្ទាល់ខ្លួន +Comment[ko]=사용자 정의 스크립트를 실행합니다 +Comment[lt]=Paleisti savo scenarijų +Comment[lv]=Palaiž pielāgotu skriptu +Comment[mr]=ऐच्छिक स्क्रिप्ट चालवा +Comment[nb]=Kjører et egendefinert skript +Comment[nds]=Föhrt en egen Skript ut +Comment[nl]=Een eigen script uitvoeren +Comment[pa]=ਪਸੰਦੀਦਾ ਸਕ੍ਰਿਪਟ ਚਲਾਓ +Comment[pl]=Uruchomia własny skrypt +Comment[pt]=Executa um programa personalizado +Comment[pt_BR]=Executa um script personalizado +Comment[ro]=Rulează un script personalizat +Comment[ru]=Запускает пользовательский сценарий +Comment[sk]=Spustí vlastný skript +Comment[sl]=Zažene skript po meri +Comment[sr]=Извршава посебну скрипту +Comment[sr@ijekavian]=Извршава посебну скрипту +Comment[sr@ijekavianlatin]=Izvršava posebnu skriptu +Comment[sr@latin]=Izvršava posebnu skriptu +Comment[sv]=Kör ett eget skript +Comment[th]=ให้สคริปตท์ที่กำหนดเองทำงาน +Comment[tr]=Özel bir betik çalıştır +Comment[ug]=ئۆزلەشتۈرگەن قوليازمىدىن بىرنى ئىجرا قىلىدۇ +Comment[uk]=Запускає вказаний користувачем скрипт +Comment[wa]=Enonde on scripe da vosse +Comment[x-test]=xxRuns a custom scriptxx +Comment[zh_CN]=运行自定义脚本 +Comment[zh_TW]=執行自訂文稿 + +X-KDE-PowerDevil-Action-ID=RunScript +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevilrunscriptaction_config +X-KDE-PowerDevil-Action-ConfigPriority=70 diff --git a/powerdevil/daemon/actions/bundled/powerdevilsuspendsessionaction.desktop b/powerdevil/daemon/actions/bundled/powerdevilsuspendsessionaction.desktop new file mode 100644 index 00000000..4cebd703 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/powerdevilsuspendsessionaction.desktop @@ -0,0 +1,118 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +# X-KDE-Library=powerdevilsuspendsessionaction +Icon=system-shutdown +Name=Suspend Session +Name[ast]=Suspender la sesión +Name[bg]=Прекратяване на сесията +Name[bs]=Suspenduj sesiju +Name[ca]=Suspèn la sessió +Name[ca@valencia]=Suspèn la sessió +Name[cs]=Pozastavit sezení +Name[da]=Suspendér session +Name[de]=Sitzung in den Ruhezustand versetzen +Name[el]=Αναστολή συνεδρίας +Name[en_GB]=Suspend Session +Name[es]=Suspender la sesión +Name[et]=Seansi peatamine +Name[eu]=Egonean utzi saioa +Name[fi]=Keskeytä istunto +Name[fr]=Suspendre la session +Name[gl]=Suspender a sesión +Name[he]=השהיית ההפעלה +Name[hi]=सत्र स्थगिक +Name[hr]=Obustavljanje sesije +Name[hu]=Munkamenet felfüggesztése +Name[ia]=Suspende session +Name[is]=Setja skjáborðssetu í bið +Name[ja]=セッションをサスペンド +Name[kk]=Сеансын аялдату +Name[km]=ផ្អាក​សម័យ +Name[ko]=세션 일시 중지 +Name[lt]=Užlaikyti sesiją +Name[lv]=Iemidzināt sesiju +Name[mr]=सत्र अकार्यक्षम करा +Name[nb]=Suspender økt +Name[nds]=Törn utsetten +Name[nl]=Sessie onderbreken +Name[pa]=ਸ਼ੈਸ਼ਨ ਸਸਪੈਂਡ +Name[pl]=Wstrzymaj sesję +Name[pt]=Suspender a Sessão +Name[pt_BR]=Suspender sessão +Name[ro]=Suspendă sesiunea +Name[ru]=Приостановить сеанс +Name[sk]=Pozastaviť sedenie +Name[sl]=Prestavi sejo v pripravljenost +Name[sr]=Суспендуј сесију +Name[sr@ijekavian]=Суспендуј сесију +Name[sr@ijekavianlatin]=Suspenduj sesiju +Name[sr@latin]=Suspenduj sesiju +Name[sv]=Stoppa tillfälligt session +Name[th]=หยุดวาระ +Name[tr]=Oturumu Askıya Al +Name[ug]=ئەڭگىمە توڭلىتىش +Name[uk]=Призупинити сеанс +Name[wa]=Mete doirmi l' session +Name[x-test]=xxSuspend Sessionxx +Name[zh_CN]=挂起会话 +Name[zh_TW]=暫停工作階段 +Comment=Suspends the session +Comment[ast]=Suspende la sesión +Comment[bg]=Прекратява сесията +Comment[bs]=Suspenduje sesiju +Comment[ca]=Suspèn la sessió +Comment[ca@valencia]=Suspèn la sessió +Comment[cs]=Pozastaví sezení +Comment[da]=Suspenderer sessionen +Comment[de]=Versetzt die Sitzung in den Ruhezustand +Comment[el]=Αναστέλλει την συνεδρία +Comment[en_GB]=Suspends the session +Comment[es]=Suspende la sesión +Comment[et]=Seansi peatamine +Comment[eu]=Saioa egonean uzten du +Comment[fi]=Keskeyttää istunnon +Comment[fr]=Suspend la session +Comment[gl]=Suspende a sesión +Comment[he]=משמש להשהיית ההפעלה +Comment[hr]=Obustavljanje ove sesije +Comment[hu]=A munkamenet felfüggesztése +Comment[ia]=Il suspende le session +Comment[is]=Setur setuna í bið +Comment[ja]=セッションをサスペンドします +Comment[kk]=Сеансын тоқтата тұру +Comment[km]=ផ្អាក​សម័យ +Comment[ko]=세션을 일시 중단합니다 +Comment[lt]=Užlaiko sesiją +Comment[lv]=Iemidzina sesiju +Comment[mr]=सत्र अकार्यक्षम करतो +Comment[nb]=Suspenderer økta +Comment[nds]=Sett den Törn ut +Comment[nl]=De sessie onderbreken +Comment[pa]=ਸ਼ੈਸ਼ਨ ਸਸਪੈਂਡ ਕਰੋ +Comment[pl]=Wstrzymuje sesję +Comment[pt]=Suspende a sessão +Comment[pt_BR]=Suspende a sessão +Comment[ro]=Suspendă sesiunea +Comment[ru]=Приостанавливает текущий сеанс KDE +Comment[sk]=Pozastaví sedenie +Comment[sl]=Prestavi sejo v pripravljenost +Comment[sr]=Суспендује сесију +Comment[sr@ijekavian]=Суспендује сесију +Comment[sr@ijekavianlatin]=Suspenduje sesiju +Comment[sr@latin]=Suspenduje sesiju +Comment[sv]=Stoppar sessionen tillfälligt +Comment[th]=หยุดวาระ +Comment[tr]=Oturumu askıya alır +Comment[ug]=ئەڭگىمەنى توڭلىتىدۇ +Comment[uk]=Призупиняє сеанс +Comment[wa]=Met doirmi l' session +Comment[x-test]=xxSuspends the sessionxx +Comment[zh_CN]=挂起会话 +Comment[zh_TW]=暫停工作階段 + +X-KDE-PowerDevil-Action-ID=SuspendSession +X-KDE-PowerDevil-Action-IsBundled=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevilsuspendsessionaction_config +X-KDE-PowerDevil-Action-ConfigPriority=90 +X-KDE-PowerDevil-Action-RegistersDBusInterface=true diff --git a/powerdevil/daemon/actions/bundled/runscript.cpp b/powerdevil/daemon/actions/bundled/runscript.cpp new file mode 100644 index 00000000..863f2a5b --- /dev/null +++ b/powerdevil/daemon/actions/bundled/runscript.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "runscript.h" + +#include + +#include + +namespace PowerDevil { +namespace BundledActions { + +RunScript::RunScript(QObject* parent) + : Action(parent) +{ + // TODO: Which policy should we enforce here? Let's go for the less restrictive one + setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings); +} + +RunScript::~RunScript() +{ + +} + +void RunScript::onProfileUnload() +{ + if (m_scriptPhase == 1) { + QProcess::startDetached(m_scriptCommand); + } +} + +void RunScript::onWakeupFromIdle() +{ + // +} + +void RunScript::onIdleTimeout(int msec) +{ + Q_UNUSED(msec); + QProcess::startDetached(m_scriptCommand); +} + +void RunScript::onProfileLoad() +{ + if (m_scriptPhase == 0) { + QProcess::startDetached(m_scriptCommand); + } +} + +void RunScript::triggerImpl(const QVariantMap& args) +{ + Q_UNUSED(args); +} + +bool RunScript::loadAction(const KConfigGroup& config) +{ + if (config.hasKey("scriptCommand") && config.hasKey("scriptPhase")) { + m_scriptCommand = config.readEntry("scriptCommand", QString()); + m_scriptPhase = config.readEntry("scriptPhase", 0); + if (m_scriptPhase == 2) { + if (!config.hasKey("idleTime")) { + return false; + } + registerIdleTimeout(config.readEntry("idleTime", 10000000)); + } + } + + return true; +} + +} +} diff --git a/powerdevil/daemon/actions/bundled/runscript.h b/powerdevil/daemon/actions/bundled/runscript.h new file mode 100644 index 00000000..41498ac2 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/runscript.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPT_H +#define POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPT_H + +#include + + +namespace PowerDevil { +namespace BundledActions { + +class RunScript : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(RunScript) + +public: + explicit RunScript(QObject* parent); + virtual ~RunScript(); + +protected: + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + +public: + virtual bool loadAction(const KConfigGroup& config); + +private: + int m_scriptPhase; + QString m_scriptCommand; +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPT_H diff --git a/powerdevil/daemon/actions/bundled/runscriptconfig.cpp b/powerdevil/daemon/actions/bundled/runscriptconfig.cpp new file mode 100644 index 00000000..63850d65 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/runscriptconfig.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "runscriptconfig.h" + +#include + +#include +#include +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilRunScriptConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilRunScriptConfigFactory("powerdevilrunscriptaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +RunScriptConfig::RunScriptConfig(QObject* parent, const QVariantList&) + : ActionConfig(parent) +{ + +} + +RunScriptConfig::~RunScriptConfig() +{ + +} + +void RunScriptConfig::save() +{ + configGroup().writeEntry("scriptCommand", m_urlRequester->text()); + configGroup().writeEntry("scriptPhase", m_comboBox->currentIndex()); + configGroup().writeEntry("idleTime", m_idleTime->value() * 60 * 1000); + + configGroup().sync(); +} + +void RunScriptConfig::load() +{ + configGroup().config()->reparseConfiguration(); + m_urlRequester->setText(configGroup().readEntry("scriptCommand", QString())); + m_comboBox->setCurrentIndex(configGroup().readEntry("scriptPhase", 0)); + m_idleTime->setValue((configGroup().readEntry("idleTime", 600000) / 60) / 1000); +} + +QList< QPair< QString, QWidget* > > RunScriptConfig::buildUi() +{ + QList< QPair< QString, QWidget* > > retlist; + m_urlRequester = new KUrlRequester(); + m_urlRequester->setMode(KFile::File | KFile::LocalOnly | KFile::ExistingOnly); + m_urlRequester->setMaximumWidth(300); + retlist.append(qMakePair< QString, QWidget* >(i18n("Script"), m_urlRequester)); + + QWidget *tempWidget = new QWidget; + QHBoxLayout *hlay = new QHBoxLayout; + m_comboBox = new KComboBox; + m_idleTime = new KIntSpinBox(0, 180, 1, 0, 0); + m_idleTime->setMaximumWidth(150); + m_idleTime->setMinimum(1); + m_idleTime->setMaximum(360); + m_idleTime->setDisabled(true); + m_idleTime->setSuffix(i18n(" min")); + m_comboBox->addItem(i18n("On Profile Load")); + m_comboBox->addItem(i18n("On Profile Unload")); + m_comboBox->addItem(i18n("After")); + connect(m_comboBox, SIGNAL(currentIndexChanged(QString)), + this, SLOT(onIndexChanged(QString))); + + hlay->addWidget(m_comboBox); + hlay->addWidget(m_idleTime); + hlay->addStretch(); + + tempWidget->setLayout(hlay); + + retlist.append(qMakePair< QString, QWidget* >(i18n("Run script"), tempWidget)); + + connect(m_urlRequester, SIGNAL(textChanged(QString)), this, SLOT(setChanged())); + connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + connect(m_idleTime, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + +void RunScriptConfig::onIndexChanged(const QString &text) +{ + m_idleTime->setEnabled(text == i18n("After")); +} + +} +} + +#include "runscriptconfig.moc" diff --git a/powerdevil/daemon/actions/bundled/runscriptconfig.h b/powerdevil/daemon/actions/bundled/runscriptconfig.h new file mode 100644 index 00000000..7ad61cfb --- /dev/null +++ b/powerdevil/daemon/actions/bundled/runscriptconfig.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPTCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPTCONFIG_H + +#include + +class KIntSpinBox; +class KComboBox; +class KUrlRequester; + +namespace PowerDevil { +namespace BundledActions { + +class RunScriptConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(RunScriptConfig) + +public: + RunScriptConfig(QObject* parent, const QVariantList&); + virtual ~RunScriptConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + KUrlRequester *m_urlRequester; + KComboBox *m_comboBox; + KIntSpinBox *m_idleTime; + +private Q_SLOTS: + void onIndexChanged(const QString&); +}; + +} +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_RUNSCRIPTCONFIG_H diff --git a/powerdevil/daemon/actions/bundled/suspendsession.cpp b/powerdevil/daemon/actions/bundled/suspendsession.cpp new file mode 100644 index 00000000..c6d2456d --- /dev/null +++ b/powerdevil/daemon/actions/bundled/suspendsession.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "suspendsession.h" + +#include "powerdevilbackendinterface.h" +#include "powerdevilcore.h" + +#include "suspendsessionadaptor.h" + +#include +#include +#include +#include + +#include + +#include "screensaver_interface.h" +#include + +namespace PowerDevil +{ +namespace BundledActions +{ + +SuspendSession::SuspendSession(QObject* parent) + : Action(parent), + m_dbusWatcher(0) +{ + // DBus + new SuspendSessionAdaptor(this); + + setRequiredPolicies(PowerDevil::PolicyAgent::InterruptSession); + + connect(backend(), SIGNAL(resumeFromSuspend()), + this, SLOT(onResumeFromSuspend())); +} + +SuspendSession::~SuspendSession() +{ + +} + +void SuspendSession::onProfileUnload() +{ + // Nothing to do +} + +void SuspendSession::onWakeupFromIdle() +{ + // Nothing to do +} + +void SuspendSession::onIdleTimeout(int msec) +{ + Q_UNUSED(msec); + QVariantMap args; + args.insert("Type", m_autoType); + trigger(args); +} + +void SuspendSession::onProfileLoad() +{ + // Nothing to do +} + +void SuspendSession::triggerImpl(const QVariantMap& args) +{ + kDebug() << "Triggered with " << args["Type"].toString() << args["SkipLocking"].toBool(); + + // Switch for screen lock + QVariantMap recallArgs; + switch ((Mode) (args["Type"].toUInt())) { + case ToRamMode: + case ToDiskMode: + case SuspendHybridMode: + // Do we want to lock the screen? + if (PowerDevilSettings::configLockScreen() && !args["SkipLocking"].toBool()) { + // Yeah, we do. + m_savedArgs = args; + recallArgs["Type"] = (uint)LockScreenMode; + triggerImpl(recallArgs); + return; + } + break; + default: + break; + } + + // Switch for real action + KJob *suspendJob = 0; + switch ((Mode) (args["Type"].toUInt())) { + case ToRamMode: + suspendJob = backend()->suspend(PowerDevil::BackendInterface::ToRam); + break; + case ToDiskMode: + suspendJob = backend()->suspend(PowerDevil::BackendInterface::ToDisk); + break; + case SuspendHybridMode: + suspendJob = backend()->suspend(PowerDevil::BackendInterface::HybridSuspend); + break; + case ShutdownMode: + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmNo, KWorkSpace::ShutdownTypeHalt); + break; + case LogoutDialogMode: + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmYes); + break; + case LockScreenMode: + lockScreenAndWait(); + break; + default: + break; + } + + if (suspendJob) { + suspendJob->start(); + } +} + +void SuspendSession::lockScreenAndWait() +{ + OrgFreedesktopScreenSaverInterface iface("org.freedesktop.ScreenSaver", + "/ScreenSaver", + QDBusConnection::sessionBus()); + QDBusPendingReply< void > reply = iface.Lock(); + m_dbusWatcher = new QDBusPendingCallWatcher(reply, this); + connect(m_dbusWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(lockCompleted())); +} + +void SuspendSession::lockCompleted() +{ + QVariantMap args = m_savedArgs; + + m_dbusWatcher->deleteLater(); + m_dbusWatcher = 0; + m_savedArgs.clear(); + + args["SkipLocking"] = true; + triggerImpl(args); +} + +bool SuspendSession::loadAction(const KConfigGroup& config) +{ + if (config.isValid() && config.hasKey("idleTime") && config.hasKey("suspendType")) { + // Add the idle timeout + registerIdleTimeout(config.readEntry("idleTime", 0)); + m_autoType = config.readEntry("suspendType", 0); + } + + return true; +} + +void SuspendSession::suspendHybrid() +{ + triggerSuspendSession(SuspendHybridMode); +} + +void SuspendSession::suspendToDisk() +{ + triggerSuspendSession(ToDiskMode); +} + +void SuspendSession::suspendToRam() +{ + triggerSuspendSession(ToRamMode); +} + +void SuspendSession::triggerSuspendSession(uint action) +{ + QVariantMap args; + args["Type"] = action; + args["Explicit"] = true; + trigger(args); +} + +void SuspendSession::onResumeFromSuspend() +{ + // Notify the screensaver + OrgFreedesktopScreenSaverInterface iface("org.freedesktop.ScreenSaver", + "/ScreenSaver", + QDBusConnection::sessionBus()); + iface.SimulateUserActivity(); + PowerDevil::PolicyAgent::instance()->setupSystemdInhibition(); + + Q_EMIT resumingFromSuspend(); +} + +} +} + +#include "suspendsession.moc" diff --git a/powerdevil/daemon/actions/bundled/suspendsession.h b/powerdevil/daemon/actions/bundled/suspendsession.h new file mode 100644 index 00000000..0c319f26 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/suspendsession.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSION_H +#define POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSION_H + +#include + +class QDBusPendingCallWatcher; + +namespace PowerDevil +{ +namespace BundledActions +{ + +class SuspendSession : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(SuspendSession) + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.Actions.SuspendSession") + +public: + enum Mode { + None = 0, + ToRamMode = 1, + ToDiskMode = 2, + SuspendHybridMode = 4, + ShutdownMode = 8, + LogoutDialogMode = 16, + LockScreenMode = 32, + TurnOffScreenMode = 64 + }; + + explicit SuspendSession(QObject *parent); + virtual ~SuspendSession(); + + virtual bool loadAction(const KConfigGroup& config); + +protected: + virtual void onProfileUnload(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + +public Q_SLOTS: + void suspendToRam(); + void suspendToDisk(); + void suspendHybrid(); + + void onResumeFromSuspend(); + +Q_SIGNALS: + void resumingFromSuspend(); + +private slots: + void lockCompleted(); + void triggerSuspendSession(uint action); + +private: + uint m_autoType; + QVariantMap m_savedArgs; + QDBusPendingCallWatcher *m_dbusWatcher; + + void lockScreenAndWait(); +}; + +} + +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSION_H diff --git a/powerdevil/daemon/actions/bundled/suspendsessionconfig.cpp b/powerdevil/daemon/actions/bundled/suspendsessionconfig.cpp new file mode 100644 index 00000000..7443e00c --- /dev/null +++ b/powerdevil/daemon/actions/bundled/suspendsessionconfig.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "suspendsessionconfig.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include "suspendsession.h" + +K_PLUGIN_FACTORY(PowerDevilSuspendSessionConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilSuspendSessionConfigFactory("powerdevilsuspendsessionaction_config")) + +namespace PowerDevil { +namespace BundledActions { + +SuspendSessionConfig::SuspendSessionConfig(QObject* parent, const QVariantList&) + : ActionConfig(parent) +{ + +} + +SuspendSessionConfig::~SuspendSessionConfig() +{ + +} + +void SuspendSessionConfig::save() +{ + configGroup().writeEntry< uint >("suspendType", m_comboBox->itemData(m_comboBox->currentIndex()).toUInt()); + configGroup().writeEntry("idleTime", m_idleTime->value() * 60 * 1000); + + configGroup().sync(); +} + +void SuspendSessionConfig::load() +{ + configGroup().config()->reparseConfiguration(); + + uint suspendType = configGroup().readEntry< uint >("suspendType", 0); + m_comboBox->setCurrentIndex(m_comboBox->findData(suspendType)); + m_idleTime->setValue((configGroup().readEntry("idleTime", 600000) / 60) / 1000); +} + +QList< QPair< QString, QWidget* > > SuspendSessionConfig::buildUi() +{ + QWidget *tempWidget = new QWidget; + QHBoxLayout *hlay = new QHBoxLayout; + m_comboBox = new KComboBox; + m_idleTime = new KIntSpinBox(0, 180, 1, 0, 0); + m_idleTime->setMaximumWidth(150); + m_idleTime->setMinimum(1); + m_idleTime->setMaximum(360); + m_idleTime->setSuffix(i18n(" min")); + + QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); + + if (methods.contains(Solid::PowerManagement::SuspendState)) { + m_comboBox->addItem(KIcon("system-suspend"), i18n("Sleep"), (uint)SuspendSession::ToRamMode); + } + if (methods.contains(Solid::PowerManagement::HibernateState)) { + m_comboBox->addItem(KIcon("system-suspend-hibernate"), i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); + } + m_comboBox->addItem(KIcon("system-shutdown"), i18n("Shutdown"), (uint)SuspendSession::ShutdownMode); + m_comboBox->addItem(KIcon("system-lock-screen"), i18n("Lock screen"), (uint)SuspendSession::LockScreenMode); + + hlay->addWidget(m_idleTime); + hlay->addWidget(m_comboBox); + hlay->addStretch(); + + tempWidget->setLayout(hlay); + + QList< QPair< QString, QWidget* > > retlist; + retlist.append(qMakePair< QString, QWidget* >(i18n("After"), tempWidget)); + + connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + connect(m_idleTime, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + +} +} diff --git a/powerdevil/daemon/actions/bundled/suspendsessionconfig.h b/powerdevil/daemon/actions/bundled/suspendsessionconfig.h new file mode 100644 index 00000000..cf94b871 --- /dev/null +++ b/powerdevil/daemon/actions/bundled/suspendsessionconfig.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSIONCONFIG_H +#define POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSIONCONFIG_H + +#include + +class KComboBox; +class KIntSpinBox; + +namespace PowerDevil { +namespace BundledActions { + +class SuspendSessionConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(SuspendSessionConfig) +public: + SuspendSessionConfig(QObject* parent, const QVariantList&); + virtual ~SuspendSessionConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + KIntSpinBox *m_idleTime; + KComboBox *m_comboBox; +}; + +} +} + +#endif // POWERDEVIL_BUNDLEDACTIONS_SUSPENDSESSIONCONFIG_H diff --git a/powerdevil/daemon/actions/dpms/CMakeLists.txt b/powerdevil/daemon/actions/dpms/CMakeLists.txt new file mode 100644 index 00000000..5a0b0e73 --- /dev/null +++ b/powerdevil/daemon/actions/dpms/CMakeLists.txt @@ -0,0 +1,24 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${X11_dpms_INCLUDE_PATH}) + +set(powerdevildpmsaction_SRCS powerdevildpmsaction.cpp) + +kde4_add_plugin(powerdevildpmsaction ${powerdevildpmsaction_SRCS}) +target_link_libraries(powerdevildpmsaction + ${X11_LIBRARIES} + ${KDE4_KDECORE_LIBS} + ${QT_QTGUI_LIBRARY} + powerdevilcore) +install(TARGETS powerdevildpmsaction DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES powerdevildpmsaction.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +# Action config +set(dpmsconfig_SRCS powerdevildpmsactionconfig.cpp) +kde4_add_plugin(powerdevildpmsaction_config + ${dpmsconfig_SRCS}) +target_link_libraries(powerdevildpmsaction_config + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBS} + powerdevilui) +install(TARGETS powerdevildpmsaction_config DESTINATION ${PLUGIN_INSTALL_DIR}) \ No newline at end of file diff --git a/powerdevil/daemon/actions/dpms/powerdevildpmsaction.cpp b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.cpp new file mode 100644 index 00000000..29c0e5f9 --- /dev/null +++ b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "powerdevildpmsaction.h" + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +extern "C" { +#include + int __kde_do_not_unload = 1; + +#ifndef HAVE_DPMSCAPABLE_PROTO + Bool DPMSCapable(Display *); +#endif + +#ifndef HAVE_DPMSINFO_PROTO + Status DPMSInfo(Display *, CARD16 *, BOOL *); +#endif + +int dropError(Display *, XErrorEvent *); +typedef int (*XErrFunc)(Display *, XErrorEvent *); +} + +int dropError(Display *, XErrorEvent *) +{ + return 0; +} + +class PowerDevilDPMSAction::Private +{ +public: + XErrorHandler defaultHandler; +}; + +K_PLUGIN_FACTORY(PowerDevilDPMSActionFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilDPMSActionFactory("powerdevildpmsaction")) + +PowerDevilDPMSAction::PowerDevilDPMSAction(QObject* parent, const QVariantList &args) + : Action(parent) + , m_idleTime(0) + , m_inhibitScreen(0) // can't use PowerDevil::PolicyAgent enum because X11/X.h defines None as 0L + , d(new Private) +{ + setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings); + + // We want to query for DPMS in the constructor, before anything else happens + d->defaultHandler = XSetErrorHandler(dropError); + + // Since we are in the constructor, we should check for support manually + if (!isSupported()) { + XSetErrorHandler(d->defaultHandler); + return; + } + + // Is the action being loaded outside the core? + if (args.size() > 0) { + if (args.first().toBool()) { + kDebug() << "Action loaded from outside the core, skipping early init"; + return; + } + } + + // Pretend we're unloading profiles here, as if the action is not enabled, DPMS should be switched off. + onProfileUnload(); + + // Listen to the policy agent + connect(PowerDevil::PolicyAgent::instance(), + SIGNAL(unavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies)), + this, + SLOT(onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies))); + // inhibitions persist over kded module unload/load + m_inhibitScreen = PowerDevil::PolicyAgent::instance()->unavailablePolicies() & PowerDevil::PolicyAgent::ChangeScreenSettings; +} + +PowerDevilDPMSAction::~PowerDevilDPMSAction() +{ + delete d; +} + +bool PowerDevilDPMSAction::isSupported() +{ + Display *dpy = QX11Info::display(); + int dummy; + + return DPMSQueryExtension(dpy, &dummy, &dummy) && DPMSCapable(dpy); +} + +void PowerDevilDPMSAction::onProfileUnload() +{ + using namespace PowerDevil; + Display *dpy = QX11Info::display(); + if (!(PolicyAgent::instance()->unavailablePolicies() & PolicyAgent::ChangeScreenSettings)) { + DPMSDisable(dpy); + } else { + kDebug() << "Not performing DPMS action due to inhibition"; + } + DPMSSetTimeouts(dpy, 0, 0, 0); +} + +void PowerDevilDPMSAction::onWakeupFromIdle() +{ + // +} + +void PowerDevilDPMSAction::onIdleTimeout(int msec) +{ + Q_UNUSED(msec); +} + +void PowerDevilDPMSAction::onProfileLoad() +{ + using namespace PowerDevil; + Display *dpy = QX11Info::display(); + if (!(PolicyAgent::instance()->unavailablePolicies() & PolicyAgent::ChangeScreenSettings)) { + DPMSEnable(dpy); + } else { + kDebug() << "Not performing DPMS action due to inhibition"; + return; + } + + XFlush(dpy); + XSetErrorHandler(d->defaultHandler); + + // An unloaded action will have m_idleTime = 0: + // DPMS enabled with zeroed timeouts is effectively disabled. + // So onProfileLoad is always safe + DPMSSetTimeouts(dpy, (CARD16)m_idleTime, (CARD16)(m_idleTime * 1.5), (CARD16)(m_idleTime * 2)); + + XFlush(dpy); + XSetErrorHandler(d->defaultHandler); +} + +void PowerDevilDPMSAction::triggerImpl(const QVariantMap& args) +{ + CARD16 dummy; + BOOL enabled; + Display *dpy = QX11Info::display(); + DPMSInfo(dpy, &dummy, &enabled); + + if (args["Type"].toString() == "TurnOff") { + if (enabled) { + DPMSForceLevel(dpy, DPMSModeOff); + } else { + DPMSEnable(dpy); + DPMSForceLevel(dpy, DPMSModeOff); + } + } else if (args["Type"].toString() == "Standby") { + if (enabled) { + DPMSForceLevel(dpy, DPMSModeStandby); + } else { + DPMSEnable(dpy); + DPMSForceLevel(dpy, DPMSModeStandby); + } + } else if (args["Type"].toString() == "Suspend") { + if (enabled) { + DPMSForceLevel(dpy, DPMSModeSuspend); + } else { + DPMSEnable(dpy); + DPMSForceLevel(dpy, DPMSModeSuspend); + } + } + + // this leaves DPMS enabled but if it's meant to be disabled + // then the timeouts will be zero and so effectively disabled +} + +bool PowerDevilDPMSAction::loadAction(const KConfigGroup& config) +{ + m_idleTime = config.readEntry("idleTime", -1); + + return true; +} + +bool PowerDevilDPMSAction::onUnloadAction() +{ + m_idleTime = 0; + return Action::onUnloadAction(); +} + +void PowerDevilDPMSAction::onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies policies) +{ + // only take action if screen inhibit changed + PowerDevil::PolicyAgent::RequiredPolicies oldPolicy = m_inhibitScreen; + m_inhibitScreen = policies & PowerDevil::PolicyAgent::ChangeScreenSettings; + if (oldPolicy == m_inhibitScreen) { + return; + } + + if (m_inhibitScreen) { + // Inhibition triggered: disable DPMS + kDebug() << "Disabling DPMS due to inhibition"; + Display *dpy = QX11Info::display(); + DPMSSetTimeouts(dpy, 0, 0, 0); + DPMSDisable(dpy); // wakes the screen - do we want this? + } else { + // Inhibition removed: let's start again + onProfileLoad(); + kDebug() << "Restoring DPMS features after inhibition release"; + } +} + +#include "powerdevildpmsaction.moc" diff --git a/powerdevil/daemon/actions/dpms/powerdevildpmsaction.desktop b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.desktop new file mode 100644 index 00000000..adbcece7 --- /dev/null +++ b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevil/Action +X-KDE-Library=powerdevildpmsaction +Icon=preferences-desktop-screensaver +Name=Screen Energy Saving +Name[ast]=Aforru d'enerxía de la pantalla +Name[bg]=Пестене на енергия за екрана +Name[bs]=Štednja energije ekrana +Name[ca]=Estalvi d'energia de pantalla +Name[ca@valencia]=Estalvi d'energia de pantalla +Name[cs]=Úsporný režim obrazovky +Name[da]=Strømbesparelse for skærm +Name[de]=Bildschirm-Energiesparmodus +Name[el]=Εξοικονόμηση ενέργειας οθόνης +Name[en_GB]=Screen Energy Saving +Name[es]=Ahorro de energía de la pantalla +Name[et]=Ekraanisäästja +Name[eu]=Pantaila-energia aurreztea +Name[fi]=Näytön virransäästö +Name[fr]=Économie d'énergie pour l'écran +Name[gl]=Aforro enerxético da pantalla +Name[he]=חיסכון באנרגיית המסך +Name[hr]=Zaslonska štednja energije +Name[hu]=Kijelző kikapcsolása +Name[ia]=Sparnio de energia de schermo +Name[is]=Orkusparnaðarstillingar fyrir skjá +Name[kk]=Экран қуатын үнемдеу +Name[km]=សន្សំ​ថាមពល​អេក្រង់ +Name[ko]=화면 에너지 절약 +Name[lt]=Ekrano energijos taupymas +Name[lv]=Ekrāna enerģijas taupīšana +Name[mr]=स्क्रीन ऊर्जा बचत +Name[nb]=Energisparing for skjerm +Name[nds]=Monitor-Stroomspoorbedrief +Name[nl]=Energiebesparing bij het beeldscherm +Name[pa]=ਸਕਰੀਨ ਊਰਜਾ ਬਚਾਉਣੀ +Name[pl]=Oszczędzaj energię ekranu +Name[pt]=Configuração da Energia do Ecrã +Name[pt_BR]=Configurações da energia da tela +Name[ro]=Economisire energie ecran +Name[ru]=Энергосбережение монитора +Name[sk]=Šetrenie energie obrazovky +Name[sl]=Varčevanje z energijo zaslona +Name[sr]=Штедња енергије екрана +Name[sr@ijekavian]=Штедња енергије екрана +Name[sr@ijekavianlatin]=Štednja energije ekrana +Name[sr@latin]=Štednja energije ekrana +Name[sv]=Strömsparhantering av bildskärmen +Name[th]=การรักษาพลังงานของหน้าจอ +Name[tr]=Ekran Enerji Tasarrufu +Name[ug]=ئېكران ئېنېرگىيە تېجەش +Name[uk]=Заощадження енергії екраном +Name[wa]=Spårgnaedje di l' enerdjeye del waitroûle +Name[x-test]=xxScreen Energy Savingxx +Name[zh_CN]=屏幕节能 +Name[zh_TW]=螢幕節能 +Comment=Controls DPMS settings +Comment[ast]=Configuraciones control DPMS +Comment[bg]=Управление настройките на DPMS +Comment[bs]=Upravlja DPMS postavkama +Comment[ca]=Controla l'arranjament del DPMS +Comment[ca@valencia]=Controla l'arranjament del DPMS +Comment[cs]=Ovládání nastavení DPMS +Comment[da]=Styrer DPMS-indstillinger +Comment[de]=DPMS-Einstellungen +Comment[el]=Ελέγχει τις ρυθμίσεις DPMS +Comment[en_GB]=Controls DPMS settings +Comment[es]=Controla preferencias de DPMS +Comment[et]=Monitori toiteseadistused +Comment[eu]=DPMS ezarpenak kontrolatzen ditu +Comment[fi]=Hallitsee DPMS-asetuksia +Comment[fr]=Contrôle les paramètres DPMS +Comment[gl]=Controla a configuración do DPMS +Comment[he]=משמש לשליטה בהגדרות DPMS +Comment[hr]=Kontrola DPMS postavki +Comment[hu]=DPMS-beállítások irányítása +Comment[ia]=Preferentias de controlos DPMS +Comment[is]=Stillingar DPMS +Comment[ja]=DPMS の設定 +Comment[kk]=DPMS параметрлерін басқару +Comment[km]=ការ​កំណត់​វត្ថុ​បញ្ជា DPMS +Comment[kn]=DPMA ಸಂಯೋಜನೆಗಳನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ +Comment[ko]=DPMS 설정 +Comment[lt]=Valdo DPMS nustatymus +Comment[lv]=Kontrolē DPMS iestatījumus +Comment[mr]=DPMS संयोजना नियंत्रीत करतो +Comment[nb]=Styrer DPMS-innstillinger +Comment[nds]=Monitor-Stroomspoorbedrief instellen +Comment[nl]=DPMS-instellingen besturen +Comment[pa]=DPMS ਕੰਟਰੋਲ ਕਰੋ +Comment[pl]=Steruje ustawieniami DPMS +Comment[pt]=Controla a configuração do DPMS +Comment[pt_BR]=Controla as configurações do DPMS +Comment[ro]=Controlează configurările DPMS +Comment[ru]=Управление настройками энергопотребления монитора +Comment[sk]=Ovláda nastavenie DPMS +Comment[sl]=Nadzira nastavitve upravljanja z energijo zaslona +Comment[sr]=Управља ДПМС поставкама +Comment[sr@ijekavian]=Управља ДПМС поставкама +Comment[sr@ijekavianlatin]=Upravlja DPMS postavkama +Comment[sr@latin]=Upravlja DPMS postavkama +Comment[sv]=Styr DPMS-inställningar +Comment[th]=ควบคุมการตั้งค่า DPMS +Comment[tr]=DPMS ayarlarını kontrol eder +Comment[ug]=DPMS تەڭشەكلىرىنى تىزگىنلەيدۇ +Comment[uk]=Керування параметрами DPMS +Comment[vi]=Điều khiển các thiết lập DPMS +Comment[wa]=Controle les tchuzes DPMS +Comment[x-test]=xxControls DPMS settingsxx +Comment[zh_CN]=控制屏幕电源设置 +Comment[zh_TW]=控制 DPMS 設定 + +X-KDE-PowerDevil-Action-ID=DPMSControl +X-KDE-PowerDevil-Action-IsBundled=false +X-KDE-PowerDevil-Action-ForceInstantLoad=true +X-KDE-PowerDevil-Action-UIComponentLibrary=powerdevildpmsaction_config +X-KDE-PowerDevil-Action-ConfigPriority=98 +X-KDE-PowerDevil-Action-HasRuntimeRequirement=true diff --git a/powerdevil/daemon/actions/dpms/powerdevildpmsaction.h b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.h new file mode 100644 index 00000000..71f9ccee --- /dev/null +++ b/powerdevil/daemon/actions/dpms/powerdevildpmsaction.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVILDPMSACTION_H +#define POWERDEVILDPMSACTION_H + +#include + +class PowerDevilDPMSAction : public PowerDevil::Action +{ + Q_OBJECT + Q_DISABLE_COPY(PowerDevilDPMSAction) + +public: + explicit PowerDevilDPMSAction(QObject* parent, const QVariantList&); + virtual ~PowerDevilDPMSAction(); + +protected: + virtual void onProfileUnload(); + virtual bool onUnloadAction(); + virtual void onWakeupFromIdle(); + virtual void onIdleTimeout(int msec); + virtual void onProfileLoad(); + virtual void triggerImpl(const QVariantMap& args); + bool isSupported(); + +public: + virtual bool loadAction(const KConfigGroup& config); + +private Q_SLOTS: + void onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies policies); + +private: + int m_idleTime; + PowerDevil::PolicyAgent::RequiredPolicies m_inhibitScreen; + + class Private; + Private * const d; +}; + +#endif // POWERDEVILDPMSACTION_H diff --git a/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.cpp b/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.cpp new file mode 100644 index 00000000..968b521f --- /dev/null +++ b/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevildpmsactionconfig.h" + +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilDPMSConfigFactory, registerPlugin(); ) +K_EXPORT_PLUGIN(PowerDevilDPMSConfigFactory("powerdevildpmsaction_config")) + +PowerDevilDPMSActionConfig::PowerDevilDPMSActionConfig(QObject* parent, const QVariantList& ) + : ActionConfig(parent) +{ + +} +PowerDevilDPMSActionConfig::~PowerDevilDPMSActionConfig() +{ + +} + +void PowerDevilDPMSActionConfig::save() +{ + configGroup().writeEntry("idleTime", m_spinBox->value() * 60); + + configGroup().sync(); +} + +void PowerDevilDPMSActionConfig::load() +{ + configGroup().config()->reparseConfiguration(); + m_spinBox->setValue(configGroup().readEntry("idleTime", 600) / 60); +} + +QList< QPair< QString, QWidget* > > PowerDevilDPMSActionConfig::buildUi() +{ + QList< QPair< QString, QWidget* > > retlist; + + m_spinBox = new KIntSpinBox(0, 180, 1, 0, 0); + m_spinBox->setMaximumWidth(150); + m_spinBox->setMinimum(1); + m_spinBox->setMaximum(360); + m_spinBox->setSuffix(i18n(" min")); + retlist.append(qMakePair< QString, QWidget* >(i18n("Switch off after"), m_spinBox)); + + connect(m_spinBox, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + return retlist; +} + diff --git a/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.h b/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.h new file mode 100644 index 00000000..b6271ff2 --- /dev/null +++ b/powerdevil/daemon/actions/dpms/powerdevildpmsactionconfig.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVILDPMSACTIONCONFIG_H +#define POWERDEVILDPMSACTIONCONFIG_H + +#include + +class KIntSpinBox; +class PowerDevilDPMSActionConfig : public PowerDevil::ActionConfig +{ + Q_OBJECT + Q_DISABLE_COPY(PowerDevilDPMSActionConfig) +public: + PowerDevilDPMSActionConfig(QObject* parent, const QVariantList&); + virtual ~PowerDevilDPMSActionConfig(); + + virtual void save(); + virtual void load(); + virtual QList< QPair< QString, QWidget* > > buildUi(); + +private: + KIntSpinBox *m_spinBox; +}; + +#endif // POWERDEVILDPMSACTIONCONFIG_H diff --git a/powerdevil/daemon/actions/powerdevilaction.desktop b/powerdevil/daemon/actions/powerdevilaction.desktop new file mode 100644 index 00000000..d3a44409 --- /dev/null +++ b/powerdevil/daemon/actions/powerdevilaction.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=PowerDevil/Action + +Comment=Power Management Action Extension +Comment[ast]=Estensión aiciones xestión d'enerxía +Comment[bg]=Разширение за действия по управление на захранването +Comment[bs]=Proširenje radnji za upravljanje napajanjem +Comment[ca]=Extensió d'accions de gestió d'energia +Comment[ca@valencia]=Extensió d'accions de gestió d'energia +Comment[cs]=Rozšiřující akce správy napájení +Comment[da]=Udvidelse af strømstyringshandling +Comment[de]=Erweiterung für Energieverwaltungs-Aktionen +Comment[el]=Επέκταση ενεργών διαχείρισης ενέργειας +Comment[en_GB]=Power Management Action Extension +Comment[es]=Extensión de acción de gestión de energía +Comment[et]=Toitehalduse laiendus +Comment[eu]=Energia kudeatzeko ekintzen hedapena +Comment[fi]=Virranhallinnan toimintolaajennus +Comment[fr]=Extension des actions de gestion de l'énergie +Comment[gl]=Extensión de accións de xestión da enerxía +Comment[he]=Power Management Action Extension +Comment[hr]=Proširenje radnje za upravljanje potrošnjom energije +Comment[hu]=Energiakezelő-műveletek kiterjesztés +Comment[ia]=Extension de action de gestion de energia +Comment[is]=Orkustýringarbakendi +Comment[kk]=Қуаттандыруды басқару әрекетін кеңейтуі +Comment[km]=ផ្នែក​បន្ថែម​សកម្មភាព​គ្រប់គ្រង​ថាមពល +Comment[ko]=전원 관리 동작 확장 +Comment[lt]=Energijos valdymo veiksmų plėtinys +Comment[lv]=Energokontroles darbības papildinājums +Comment[mr]=वीज व्यवस्थापन क्रिया एक्सटेंशन +Comment[nb]=Handlingsutvidelse for strømstyring +Comment[nds]=Verwiedern för Stroomkuntrullakschonen +Comment[nl]=Uitbreiding voor energiebeheeractie +Comment[pa]=ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ ਐਕਸ਼ਣ ਇਕਸਟੈਸ਼ਨ +Comment[pl]=Rozszerzenie do działań związanych z zarządzaniem energią +Comment[pt]=Extensão da Acção de Gestão da Energia +Comment[pt_BR]=Extensão da ação do gerenciamento de energia +Comment[ro]=Extensie pentru acțiunea de gestiune a alimentării +Comment[ru]=Расширение для комнаты управления питанием +Comment[sk]=Rozširujúce akcie správy napájania +Comment[sl]=Razširitev za dejanja za upravljanje z energijo +Comment[sr]=Проширење радњи за управљање напајањем +Comment[sr@ijekavian]=Проширење радњи за управљање напајањем +Comment[sr@ijekavianlatin]=Proširenje radnji za upravljanje napajanjem +Comment[sr@latin]=Proširenje radnji za upravljanje napajanjem +Comment[sv]=Åtgärdsutökning för strömsparhantering +Comment[th]=ส่วนขยายการกระทำเกี่ยวกับการจัดการพลังงาน +Comment[tr]=Güç Yönetimi Eylem Eklentisi +Comment[ug]=توك مەنبە باشقۇرۇش مەشغۇلات كېڭەيتىلمىسى +Comment[uk]=Розширення дій керування живленням +Comment[wa]=Sitindaedje des faitindjes do Manaedjmint di l' enerdjeye +Comment[x-test]=xxPower Management Action Extensionxx +Comment[zh_CN]=电源管理动作扩展 +Comment[zh_TW]=電源管理動作延伸 + +[PropertyDef::X-KDE-PowerDevil-Action-ID] +Type=QString +[PropertyDef::X-KDE-PowerDevil-Action-IsBundled] +Type=bool +[PropertyDef::X-KDE-PowerDevil-Action-RegistersDBusInterface] +Type=bool +[PropertyDef::X-KDE-PowerDevil-Action-ForceInstantLoad] +Type=bool +[PropertyDef::X-KDE-PowerDevil-Action-UIComponentLibrary] +Type=QString +[PropertyDef::X-KDE-PowerDevil-Action-ConfigPriority] +Type=int +[PropertyDef::X-KDE-PowerDevil-Action-HasRuntimeRequirement] +Type=bool diff --git a/powerdevil/daemon/backends/hal/halsuspendjob.cpp b/powerdevil/daemon/backends/hal/halsuspendjob.cpp new file mode 100644 index 00000000..d0b07ee2 --- /dev/null +++ b/powerdevil/daemon/backends/hal/halsuspendjob.cpp @@ -0,0 +1,136 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "halsuspendjob.h" + +#include +#include +#include +#include +#include + +HalSuspendJob::HalSuspendJob(QDBusInterface &powermanagement, QDBusInterface &computer, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported) + : KJob(), m_halPowerManagement(powermanagement), m_halComputer(computer) +{ + if (supported & method) + { + QDBusReply reply; + + switch(method) + { + case PowerDevil::BackendInterface::ToRam: + reply = m_halComputer.call("GetPropertyBoolean", "power_management.can_suspend_hybrid"); + + if (reply.isValid()) + { + bool can_hybrid = reply; + if (can_hybrid) + { + // Temporary: let's check if system is configured to use Hybrid suspend. Default is no. + KConfig sconf("suspendpreferencesrc"); + KConfigGroup group(&sconf, "Preferences"); + if (group.readEntry("use_hybrid", false)) { + m_dbusMethod = "SuspendHybrid"; + } else { + m_dbusMethod = "Suspend"; + } + } + else + { + m_dbusMethod = "Suspend"; + } + } + else + { + m_dbusMethod = "Suspend"; + } + m_dbusParam = 0; + break; + case PowerDevil::BackendInterface::ToDisk: + m_dbusMethod = "Hibernate"; + m_dbusParam = -1; + break; + default: + break; + } + } +} + +HalSuspendJob::~HalSuspendJob() +{ + +} + +void HalSuspendJob::start() +{ + QTimer::singleShot(0, this, SLOT(doStart())); +} + +void HalSuspendJob::kill(bool /*quietly */) +{ + +} + +void HalSuspendJob::doStart() +{ + if (m_dbusMethod.isEmpty()) + { + setError(1); + setErrorText("Unsupported suspend method"); + emitResult(); + return; + } + + QList args; + + if (m_dbusParam>=0) + { + args << m_dbusParam; + } + + if (!m_halPowerManagement.callWithCallback(m_dbusMethod, args, + this, SLOT(resumeDone(QDBusMessage)))) + { + setError(1); + setErrorText(m_halPowerManagement.lastError().name()+": " + +m_halPowerManagement.lastError().message()); + emitResult(); + } +} + + +void HalSuspendJob::resumeDone(const QDBusMessage &reply) +{ + if (reply.type() == QDBusMessage::ErrorMessage) + { + // We ignore the NoReply error, since we can timeout anyway + // if the computer is suspended for too long. + if (reply.errorName() != "org.freedesktop.DBus.Error.NoReply") + { + setError(1); + setErrorText(reply.errorName()+": "+reply.arguments().at(0).toString()); + } + } + + emitResult(); +} + +#include "halsuspendjob.moc" diff --git a/powerdevil/daemon/backends/hal/halsuspendjob.h b/powerdevil/daemon/backends/hal/halsuspendjob.h new file mode 100644 index 00000000..ba0bd7ff --- /dev/null +++ b/powerdevil/daemon/backends/hal/halsuspendjob.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef HALSUSPENDJOB_H +#define HALSUSPENDJOB_H + +#include +#include +#include + +#include "powerdevilhalbackend.h" + +class HalSuspendJob : public KJob +{ + Q_OBJECT +public: + HalSuspendJob(QDBusInterface &powermanagement, QDBusInterface &computer, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported); + virtual ~HalSuspendJob(); + + void start(); + void kill(bool quietly); + +private Q_SLOTS: + void doStart(); + void resumeDone(const QDBusMessage &reply); + +private: + QDBusInterface &m_halPowerManagement; + QDBusInterface &m_halComputer; + QString m_dbusMethod; + int m_dbusParam; +}; + +#endif diff --git a/powerdevil/daemon/backends/hal/powerdevilhalbackend.cpp b/powerdevil/daemon/backends/hal/powerdevilhalbackend.cpp new file mode 100644 index 00000000..726261d5 --- /dev/null +++ b/powerdevil/daemon/backends/hal/powerdevilhalbackend.cpp @@ -0,0 +1,519 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2008-2010 Dario Freddi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + + +#include "powerdevilhalbackend.h" +#include +#include +#include +#include +#include "halsuspendjob.h" +#include +#include +#include +#include +#include +#include +#include + +PowerDevilHALBackend::PowerDevilHALBackend(QObject* parent) + : BackendInterface(parent), + m_screenBrightnessInHardware(false), + m_halComputer("org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device", + QDBusConnection::systemBus()), + m_halPowerManagement("org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + QDBusConnection::systemBus()), + m_halCpuFreq("org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.CPUFreq", + QDBusConnection::systemBus()), + m_halManager("org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + QDBusConnection::systemBus()) +{ +} + +PowerDevilHALBackend::~PowerDevilHALBackend() +{ + qDeleteAll(m_acAdapters); + qDeleteAll(m_batteries); + qDeleteAll(m_buttons); +} + +bool PowerDevilHALBackend::isAvailable() +{ + return QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.Hal"); +} + +void PowerDevilHALBackend::init() +{ + setCapabilities(NoCapabilities); + + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), + this, SLOT(slotDeviceRemoved(QString))); + connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), + this, SLOT(slotDeviceAdded(QString))); + + m_pluggedAdapterCount = 0; + computeAcAdapters(); + + computeBatteries(); + updateBatteryStats(); + + computeButtons(); + + // Brightness Control available + BrightnessControlsList controls; + { + QDBusPendingReply reply = m_halManager.asyncCall("FindDeviceByCapability", "laptop_panel"); + reply.waitForFinished(); + if (reply.isValid()) { + foreach(const QString &name, reply.value()) { + controls.insert(name, Screen); + } + } + reply = m_halManager.call("FindDeviceByCapability", "keyboard_backlight"); + if (reply.isValid()) { + foreach(const QString &name, reply.value()) { + controls.insert(name, Keyboard); + } + } + } + + QList screenControls = controls.keys(Screen); + + if (!screenControls.isEmpty()) { + m_cachedScreenBrightness = brightness(Screen); + + QDBusInterface deviceInterface("org.freedesktop.Hal", + screenControls.at(0), + "org.freedesktop.Hal.Device", + QDBusConnection::systemBus()); + QDBusReply replyInHardware = deviceInterface.call("GetPropertyBoolean", + "laptop_panel.brightness_in_hardware"); + if (replyInHardware.isValid()) { + m_screenBrightnessInHardware = replyInHardware; + } + } + + // Supported suspend methods + SuspendMethods supported = UnknownSuspendMethod; + { + QDBusPendingReply reply = m_halComputer.asyncCall("GetPropertyBoolean", "power_management.can_suspend"); + reply.waitForFinished(); + + if (reply.isValid()) { + bool can_suspend = reply; + if (can_suspend) { + supported |= ToRam; + } + } else { + kDebug() << reply.error().name() << ": " << reply.error().message(); + } + + reply = m_halComputer.asyncCall("GetPropertyBoolean", "power_management.can_hibernate"); + reply.waitForFinished(); + + if (reply.isValid()) { + bool can_hibernate = reply; + if (can_hibernate) { + supported |= ToDisk; + } + } else { + kDebug() << reply.error().name() << ": " << reply.error().message(); + } + } + + // Battery capacity + { + foreach (Solid::Device *d, m_batteries) { + Solid::GenericInterface *interface = d->as(); + + if (interface == 0) continue; + + if (interface->property("battery.reporting.design").toInt() > 0) { + uint capacity = ((float)(interface->property("battery.reporting.last_full").toInt()) / + (float)(interface->property("battery.reporting.design").toInt())) * 100; + + if (capacity > 0) { + setCapacityForBattery(d->udi(), capacity); + } else { + // Not supported, set capacity to 100% + setCapacityForBattery(d->udi(), 100); + } + } else { + // Not supported, set capacity to 100% + setCapacityForBattery(d->udi(), 100); + } + } + } + + setBackendIsReady(controls, supported); +} + +void PowerDevilHALBackend::brightnessKeyPressed(PowerDevil::BackendInterface::BrightnessKeyType type, BrightnessControlType controlType) +{ + BrightnessControlsList allControls = brightnessControlsAvailable(); + QList controls = allControls.keys(controlType); + + if (controls.isEmpty()) { + return; // ignore as we are not able to determine the brightness level + } + + if (type == Toggle && controlType == Screen) { + return; // ignore as we wont toggle the display off + } + + float currentBrightness = brightness(controlType); + + float cachedBrightness; + + if (controlType == Screen) { + cachedBrightness = m_cachedScreenBrightness; + } else { + cachedBrightness = m_cachedKeyboardBrightness; + } + + if (qFuzzyCompare(currentBrightness, cachedBrightness) && (!m_screenBrightnessInHardware || controlType == Screen)) { + float newBrightness; + if (type == Increase) { + newBrightness = qMin(100.0f, currentBrightness + 10); + } else if (type == Decrease) { + newBrightness = qMax(0.0f, currentBrightness - 10); + } else { // Toggle + newBrightness = currentBrightness > 0 ? 0 : 100; + } + + if (setBrightness(newBrightness, controlType)) { + newBrightness = brightness(controlType); + if (!qFuzzyCompare(newBrightness, cachedBrightness)) { + cachedBrightness = newBrightness; + onBrightnessChanged(controlType, cachedBrightness); + } + } + } else { + cachedBrightness = currentBrightness; + } + + if (controlType == Screen) { + m_cachedScreenBrightness = cachedBrightness; + } else { + m_cachedKeyboardBrightness = cachedBrightness; + } +} + +float PowerDevilHALBackend::brightness(PowerDevil::BackendInterface::BrightnessControlType type) const +{ + float brightness; + if (type == Screen) { + QDBusPendingReply reply = m_halManager.asyncCall("FindDeviceByCapability", "laptop_panel"); + reply.waitForFinished(); + if(reply.isValid()) { + foreach (const QString &device, reply.value()) { + QDBusInterface deviceInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device.LaptopPanel", QDBusConnection::systemBus()); + QDBusReply brightnessReply = deviceInterface.call("GetBrightness"); + if(!brightnessReply.isValid()) { + return 0.0; + } + brightness = brightnessReply; + + QDBusInterface propertyInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device", QDBusConnection::systemBus()); + QDBusReply levelsReply = propertyInterface.call("GetProperty", "laptop_panel.num_levels"); + if (levelsReply.isValid()) { + int levels = levelsReply; + return (float)(100*(brightness/(levels-1))); + } + } + } + } else { + QDBusPendingReply reply = m_halManager.asyncCall("FindDeviceByCapability", "keyboard_backlight"); + reply.waitForFinished(); + if(reply.isValid()) { + foreach (const QString &device, reply.value()) { + //TODO - I do not have a backlight enabled keyboard, so I'm guessing a bit here. Could someone please check this. + QDBusInterface deviceInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device.KeyboardBacklight", QDBusConnection::systemBus()); + + QDBusReply brightnessReply = deviceInterface.call("GetBrightness"); + if (!brightnessReply.isValid()) { + return 0.0; + } + brightness = brightnessReply; + + QDBusInterface propertyInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device", QDBusConnection::systemBus()); + QDBusReply levelsReply = propertyInterface.call("GetProperty", "keyboard_backlight.num_levels"); + if (levelsReply.isValid()) { + int levels = levelsReply; + return (float)(100*(brightness/(levels-1))); + } + } + } + } + return 0.0; +} + +bool PowerDevilHALBackend::setBrightness(float brightnessValue, PowerDevil::BackendInterface::BrightnessControlType type) +{ + if (type == Screen) { + QDBusPendingReply reply = m_halManager.asyncCall("FindDeviceByCapability", "laptop_panel"); + reply.waitForFinished(); + if(reply.isValid()) { + foreach (const QString &device, reply.value()) { + QDBusInterface propertyInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device", QDBusConnection::systemBus()); + int levels = propertyInterface.call("GetProperty", "laptop_panel.num_levels").arguments().at(0).toInt(); + QDBusInterface deviceInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device.LaptopPanel", QDBusConnection::systemBus()); + deviceInterface.call("SetBrightness", qRound((levels-1)*(brightnessValue/100.0))); // .0? The right way? Feels hackish. + if (!deviceInterface.lastError().isValid()) { + return true; + } + } + } + } else { + QDBusPendingReply reply = m_halManager.asyncCall("FindDeviceByCapability", "keyboard_backlight"); + reply.waitForFinished(); + if(reply.isValid()) { + foreach (const QString &device, reply.value()) { + QDBusInterface propertyInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device", QDBusConnection::systemBus()); + int levels = propertyInterface.call("GetProperty", "keyboard_backlight.num_levels").arguments().at(0).toInt(); + //TODO - I do not have a backlight enabled keyboard, so I'm guessing a bit here. Could someone please check this. + QDBusInterface deviceInterface("org.freedesktop.Hal", device, + "org.freedesktop.Hal.Device.KeyboardBacklight", QDBusConnection::systemBus()); + + deviceInterface.call("SetBrightness", qRound((levels-1)*(brightnessValue/100.0))); + if(!deviceInterface.lastError().isValid()) { + return true; + } + } + } + } + return false; +} + +KJob* PowerDevilHALBackend::suspend(PowerDevil::BackendInterface::SuspendMethod method) +{ + // Ok, that's not cool, but it's all HAL really gives us, so. + QTimer::singleShot(0, this, SLOT(setResumeFromSuspend())); + return new HalSuspendJob(m_halPowerManagement, m_halComputer, + method, supportedSuspendMethods()); +} + +void PowerDevilHALBackend::computeAcAdapters() +{ + QList adapters + = Solid::Device::listFromType(Solid::DeviceInterface::AcAdapter); + + foreach (const Solid::Device &adapter, adapters) { + m_acAdapters[adapter.udi()] = new Solid::Device(adapter); + connect(m_acAdapters[adapter.udi()]->as(), SIGNAL(plugStateChanged(bool,QString)), + this, SLOT(slotPlugStateChanged(bool))); + + if (m_acAdapters[adapter.udi()]->as()!=0 + && m_acAdapters[adapter.udi()]->as()->isPlugged()) { + m_pluggedAdapterCount++; + } + } + + if (m_pluggedAdapterCount > 0) { + setAcAdapterState(Plugged); + } else { + setAcAdapterState(Unplugged); + } +} + +void PowerDevilHALBackend::computeBatteries() +{ + QList batteries + = Solid::Device::listFromQuery("Battery.type == 'PrimaryBattery'"); + + foreach (const Solid::Device &battery, batteries) { + m_batteries[battery.udi()] = new Solid::Device(battery); + connect(m_batteries[battery.udi()]->as(), SIGNAL(chargePercentChanged(int,QString)), + this, SLOT(updateBatteryStats())); + connect(m_batteries[battery.udi()]->as(), SIGNAL(propertyChanged(QMap)), + this, SLOT(slotBatteryPropertyChanged(QMap))); + } + + updateBatteryStats(); +} + +void PowerDevilHALBackend::computeButtons() +{ + QList buttons + = Solid::Device::listFromType(Solid::DeviceInterface::Button); + + foreach (const Solid::Device &button, buttons) { + m_buttons[button.udi()] = new Solid::Device(button); + connect(m_buttons[button.udi()]->as(), SIGNAL(pressed(Solid::Button::ButtonType,QString)), + this, SLOT(slotButtonPressed(Solid::Button::ButtonType))); + } +} + +void PowerDevilHALBackend::slotPlugStateChanged(bool newState) +{ + if (newState) { + if(m_pluggedAdapterCount == 0) { + setAcAdapterState(Plugged); + } + m_pluggedAdapterCount++; + } else { + if(m_pluggedAdapterCount == 1) { + setAcAdapterState(Unplugged); + } + m_pluggedAdapterCount--; + } +} + +void PowerDevilHALBackend::slotButtonPressed(Solid::Button::ButtonType type) +{ + Solid::Button *button = qobject_cast(sender()); + + if (button == 0) return; + + switch(type) { + case Solid::Button::PowerButton: + setButtonPressed(PowerButton); + break; + case Solid::Button::SleepButton: + setButtonPressed(SleepButton); + break; + case Solid::Button::LidButton: + if (button->stateValue()) { + setButtonPressed(LidClose); + } else { + setButtonPressed(LidOpen); + } + break; + default: + //kWarning() << "Unknown button type"; + break; + } +} + +void PowerDevilHALBackend::slotDeviceAdded(const QString &udi) +{ + Solid::Device *device = new Solid::Device(udi); + if (device->is()) { + m_acAdapters[udi] = device; + connect(m_acAdapters[udi]->as(), SIGNAL(plugStateChanged(bool,QString)), + this, SLOT(slotPlugStateChanged(bool))); + + if (m_acAdapters[udi]->as()!=0 + && m_acAdapters[udi]->as()->isPlugged()) { + m_pluggedAdapterCount++; + } + } else if (device->is()) { + m_batteries[udi] = device; + connect(m_batteries[udi]->as(), SIGNAL(chargePercentChanged(int,QString)), + this, SLOT(updateBatteryStats())); + connect(m_batteries[udi]->as(), SIGNAL(propertyChanged(QMap)), + this, SLOT(slotBatteryPropertyChanged(QMap))); + } else if (device->is()) { + m_buttons[udi] = device; + connect(m_buttons[udi]->as(), SIGNAL(pressed(int,QString)), + this, SLOT(slotButtonPressed(int))); + } else { + delete device; + } +} + +void PowerDevilHALBackend::slotDeviceRemoved(const QString &udi) +{ + Solid::Device *device = 0; + + device = m_acAdapters.take(udi); + + if (device != 0) { + delete device; + + m_pluggedAdapterCount = 0; + + foreach (Solid::Device *d, m_acAdapters) { + if (d->as()!=0 + && d->as()->isPlugged()) { + m_pluggedAdapterCount++; + } + } + + return; + } + + device = m_batteries.take(udi); + + if (device!=0) { + delete device; + updateBatteryStats(); + return; + } + + device = m_buttons.take(udi); + + if (device!=0) { + delete device; + return; + } +} + +void PowerDevilHALBackend::slotBatteryPropertyChanged(const QMap &changes) +{ + /* This slot catches property changes on battery devices. At + * the moment it is used to find out remaining time on batteries. + */ + + if (changes.contains("battery.remaining_time")) { + updateBatteryStats(); + + setBatteryRemainingTime(m_estimatedBatteryTime); + } +} + +void PowerDevilHALBackend::updateBatteryStats() +{ + m_currentBatteryCharge = 0; + m_maxBatteryCharge = 0; + m_lowBatteryCharge = 0; + m_criticalBatteryCharge = 0; + m_estimatedBatteryTime = 0; + + foreach (Solid::Device *d, m_batteries) { + Solid::GenericInterface *interface = d->as(); + + if (interface == 0) continue; + + m_currentBatteryCharge += interface->property("battery.charge_level.current").toInt(); + m_maxBatteryCharge += interface->property("battery.charge_level.last_full").toInt(); + m_lowBatteryCharge += interface->property("battery.charge_level.low").toInt(); + m_estimatedBatteryTime += interface->property("battery.remaining_time").toInt() * 1000; + } + + m_criticalBatteryCharge = m_lowBatteryCharge/2; +} + +#include "powerdevilhalbackend.moc" diff --git a/powerdevil/daemon/backends/hal/powerdevilhalbackend.desktop b/powerdevil/daemon/backends/hal/powerdevilhalbackend.desktop new file mode 100644 index 00000000..f249dc66 --- /dev/null +++ b/powerdevil/daemon/backends/hal/powerdevilhalbackend.desktop @@ -0,0 +1,115 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevilBackend +X-KDE-Library=powerdevilhalbackend +InitialPreference=100 +Icon=preferences-system-power-management +Name=HAL PowerDevil Backend +Name[ast]=HAL PowerDevil Backend +Name[bg]=Ядро HAL PowerDevil +Name[bs]=HAL kao pozadina Strujnog đavola +Name[ca]=Dorsal de HAL per al PowerDevil +Name[ca@valencia]=Dorsal de HAL per al PowerDevil +Name[cs]=Podpůrná vrstva HAL PowerDevil +Name[da]=HAL-motor til PowerDevil +Name[de]=HAL-PowerDevil-Backend +Name[el]=Σύστημα υποστήριξης HAL για το PowerDevil +Name[en_GB]=HAL PowerDevil Backend +Name[es]=Motor HAL para PowerDevil +Name[et]=HAL-i PowerDevili taustaprogramm +Name[eu]=PowerDevil-erako HAL bizkarraldekoa +Name[fi]=HAL PowerDevil-taustaosa +Name[fr]=Module HAL de PowerDevil +Name[ga]=Inneall HAL PowerDevil +Name[gl]=Infraestrutura de HAL do PowerDevil +Name[he]=מנגנון HAL PowerDevil +Name[hr]=HAL pozadinski servis za PowerDevil +Name[hu]=HAL Powerdevil-modul +Name[ia]=HAL PowerDevil Backend (retro-administration de PowerDevil de HAL) +Name[is]=HAL OrkuPúki +Name[ja]=HAL PowerDevil バックエンド +Name[kk]=HAL PowerDevil тетігі +Name[km]=កម្មវិធី​ខាងក្រោយ HAL PowerDevil +Name[kn]=HAL PowerDevil ಬ್ಯಾಕೆಂಡ್ +Name[ko]=HAL PowerDevil 백엔드 +Name[lt]=HAL PowerDevil programinė sąsaja +Name[lv]=HAL PowerDevil aizmugure +Name[mr]=HAL पॉवरडेव्हिल बॅकएन्ड +Name[nb]=HAL PowerDevil-motor +Name[nds]=Hülpprogramm för den HAL-Stroomdüvel +Name[nl]=Backend voor HAL PowerDevil +Name[pa]=HAL ਪਾਵਰ-ਡੀਵਿਲ ਬੈਕਐਂਡ +Name[pl]=Moduł HAL dla PowerDevil +Name[pt]=Infra-Estrutura de HAL para o PowerDevil +Name[pt_BR]=Infraestrutura de HAL para o PowerDevil +Name[ro]=Suport PowerDevil HAL +Name[ru]=Модуль поддержки HAL для PowerDevil +Name[sk]=Backend HAL PowerDevil +Name[sl]=Zaledje HAL za PowerDevil +Name[sr]=ХАЛ као позадина Струјног ђавола +Name[sr@ijekavian]=ХАЛ као позадина Струјног ђавола +Name[sr@ijekavianlatin]=HAL kao pozadina Strujnog đavola +Name[sr@latin]=HAL kao pozadina Strujnog đavola +Name[sv]=HAL Powerdevil-gränssnitt +Name[th]=โปรแกรมเบื้องหลัง HAL PowerDevil +Name[tr]=HAL PowerDevil Arkaucu +Name[ug]=HAL PowerDevil ئارقا ئۇچى +Name[uk]=Сервер PowerDevil HAL +Name[wa]=Bouye di fond HAL do Diâle d' Enerdjeye +Name[x-test]=xxHAL PowerDevil Backendxx +Name[zh_CN]=HAL PowerDevil 后端 +Name[zh_TW]=HAL PowerDevil 後端介面 +Comment=Use KDE Power Management system through freedesktop.org HAL daemon +Comment[ast]=Usar la xestión de enerxía del sistema KDE a traviés del degorriu HAL de freedesktop.org +Comment[bg]=Управление на захранването на KDE чрез демона HAL на freedesktop.org +Comment[bs]=KDE‑ov sistem za upravljanje napajanjem preko demona HAL‑a +Comment[ca]=Usa el sistema de gestió d'energia del KDE mitjançant el dimoni HAL del freedesktop.org +Comment[ca@valencia]=Usa el sistema de gestió d'energia del KDE mitjançant el dimoni HAL del freedesktop.org +Comment[cs]=Využít démon freedesktop.org HAL pro systém správy napájení KDE +Comment[da]=Brug KDE strømstyring via HAL-dæmonen fra freedesktop.org +Comment[de]=Das KDE-Energieverwaltungssystem mit Hilfe des HAL-Dienstes von freedesktop.org verwenden +Comment[el]=Διαχείριση ενέργειας ΚDE με χρήση του δαίμονα HAL του freedesktop.org +Comment[en_GB]=Use KDE Power Management system through freedesktop.org HAL dæmon +Comment[es]=Usar el sistema de gestión de energía de KDE mediante el demonio HAL de freedesktop.org +Comment[et]=KDE toitehalduse süsteemi kasutamine freedesktop.org-i HAL-deemoni abil +Comment[eu]=Erabili KDEren energia kudeatzeko sistema freedesktop.org-eko HAL daimonaren bidez +Comment[fi]=KDE:n virranhallintajärjestelmän käyttö freedesktop.org HAL-taustaprosessilla +Comment[fr]=Utiliser le système de gestion de l'énergie du matériel via le démon HAL de « freedesktop.org » +Comment[gl]=Usa o sistema de xestión enerxética de KDE mediante o daemon HAL de freedesktop.org +Comment[he]=שימוש במנהל צריכת החשמל של KDE דרך תהליך הרקע של freedesktop.org HAL +Comment[hr]=Koristi KDE-ovo upravljanje potrošnjom energije kroz servis freedesktop.org HAL +Comment[hu]=A KDE energiakezelő rendszerének használata a freedesktop.org HAL-démonán keresztül +Comment[ia]=Usa systema de gestion de energia de KDE usante demone HAL de freedesktop.org +Comment[is]=KDE-orkustilling vélbúnaðar með HAL púkanum frá freedesktop.org +Comment[ja]=freedesktop.org の HAL デーモンを介して KDE 電源管理を使用 +Comment[kk]=freedesktop.org HAL қызметі көмегімен KDE қуаттандыру жүйесін басқару +Comment[km]=ប្រើ​ប្រព័ន្ធ​គ្រប់គ្រង​ថាមពល​របស់ KDE តាមរយៈ​ដេមិន freedesktop.org HAL +Comment[kn]=freedesktop.org ನ HAL ನೇಪಥಿಕ (ಡೀಮನ್) ಬಳಸಿ KDE ವಿದ್ಯುಚ್ಛಕ್ತಿ ನಿರ್ವಹಣಾ ವ್ಯವಸ್ಥೆಯನ್ನು ಬಳಸಿ +Comment[ko]=freedesktop.org HAL 데몬을 사용하는 KDE 전원 관리 시스템 +Comment[lt]=Naudoti KDE energijos valdymo sistemą, naudojant freedesktop.org HAL tarnybą +Comment[lv]=Lietot KDE energokontroles sistēmu, izmantojot freedesktop.org HAL dēmonu +Comment[mr]=freedesktop.org HAL डीमनने केडीई वीज व्यवस्थापन वापरा +Comment[nb]=Bruk KDE strømstyringssystem med HAL-nissen fra freedesktop.org +Comment[nds]=Den HAL-Dämoon vun freedesktop.org för de KDE-Stroomkuntrull bruken +Comment[nl]=KDE energiebeheer gebruiken via de HAL-daemon van freedesktop.org +Comment[pa]=freedesktop.org HAL ਡੈਮਨ ਦੀ ਵਰਤੋਂ ਨਾਲ KDE ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ ਸਿਸਟਮ +Comment[pl]=Zarządzanie zasilaniem za pomocą usługi HAL z freedesktop.org +Comment[pt]=Usar o sistema de gestão de energia do KDE através do servidor de HAL do freedesktop.org +Comment[pt_BR]=Usar o sistema de gerenciamento de energia do KDE através do daemon HAL do freedesktop.org +Comment[ro]=Folosește sistemul KDE de gestiune a alimentării prin intermediul demonului HAL de la freedesktop.org +Comment[ru]=Управление питанием с использованием службы HAL от freedesktop.org +Comment[sk]=Správa napájania KDE pomocou démona HAL z freedesktop.org +Comment[sl]=Uporaba KDE-jevega sistema za upravljanje z energijo prek ozadnjega programa HAL +Comment[sr]=КДЕ‑ов систем за управљање напајањем преко демона ХАЛ‑а +Comment[sr@ijekavian]=КДЕ‑ов систем за управљање напајањем преко демона ХАЛ‑а +Comment[sr@ijekavianlatin]=KDE‑ov sistem za upravljanje napajanjem preko demona HAL‑a +Comment[sr@latin]=KDE‑ov sistem za upravljanje napajanjem preko demona HAL‑a +Comment[sv]=Använd KDE:s strömsparhantering via HAL-demon från freedesktop.org +Comment[th]=ใช้ระบบจัดการพลังงานของ KDE โดยใช้ดีมอน HAL จาก freedesktop.org +Comment[tr]=KDE Güç Yönetim sisteminde freedesktop.org HAL servisini kullan +Comment[ug]=KDE توك مەنبە باشقۇرغۇچ سىستېمىسىدا freedesktop.org HAL نازارەتچىنى ئىشلەت +Comment[uk]=Використання системи керування живленням KDE за допомогою фонової служби HAL freedesktop.org +Comment[wa]=Eployî l' sistinme di manaedjmint di l' enerdjeye di KDE åd triviè do démon HAL di freedesktop.org +Comment[x-test]=xxUse KDE Power Management system through freedesktop.org HAL daemonxx +Comment[zh_CN]=用 freedesktop.org HAL 守护程序进行 KDE 电源管理 +Comment[zh_TW]=透過 freedesktop.org 的 HAL 伺服程式使用 KDE 電源管理系統 diff --git a/powerdevil/daemon/backends/hal/powerdevilhalbackend.h b/powerdevil/daemon/backends/hal/powerdevilhalbackend.h new file mode 100644 index 00000000..8f9769af --- /dev/null +++ b/powerdevil/daemon/backends/hal/powerdevilhalbackend.h @@ -0,0 +1,93 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2008-2010 Dario Freddi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef POWERDEVILHALBACKEND_H +#define POWERDEVILHALBACKEND_H + +#include + +#include +#include + +#include + +#include +#include +#include + +namespace Solid { +class Device; +} + + +class KDE_EXPORT PowerDevilHALBackend : public PowerDevil::BackendInterface +{ + Q_OBJECT + Q_DISABLE_COPY(PowerDevilHALBackend) +public: + explicit PowerDevilHALBackend(QObject* parent); + virtual ~PowerDevilHALBackend(); + + virtual void init(); + static bool isAvailable(); + + virtual float brightness(BrightnessControlType type = Screen) const; + + virtual void brightnessKeyPressed(PowerDevil::BackendInterface::BrightnessKeyType type, PowerDevil::BackendInterface::BrightnessControlType controlType = Screen); + virtual bool setBrightness(float brightness, PowerDevil::BackendInterface::BrightnessControlType type = Screen); + virtual KJob* suspend(PowerDevil::BackendInterface::SuspendMethod method); + +private: + void computeAcAdapters(); + void computeBatteries(); + void computeButtons(); + +private slots: + void updateBatteryStats(); + void slotPlugStateChanged(bool newState); + void slotButtonPressed(Solid::Button::ButtonType type); + void slotDeviceAdded(const QString &udi); + void slotDeviceRemoved(const QString &udi); + void slotBatteryPropertyChanged(const QMap &changes); + +private: + QMap m_acAdapters; + QMap m_batteries; + QMap m_buttons; + + int m_pluggedAdapterCount; + + int m_currentBatteryCharge; + int m_maxBatteryCharge; + int m_lowBatteryCharge; + int m_criticalBatteryCharge; + int m_estimatedBatteryTime; + + bool m_screenBrightnessInHardware; + float m_cachedScreenBrightness; + float m_cachedKeyboardBrightness; + + mutable QDBusInterface m_halComputer; + mutable QDBusInterface m_halPowerManagement; + mutable QDBusInterface m_halCpuFreq; + mutable QDBusInterface m_halManager; +}; + +#endif // POWERDEVILHALBACKEND_H diff --git a/powerdevil/daemon/backends/upower/backlight_helper_actions.actions b/powerdevil/daemon/backends/upower/backlight_helper_actions.actions new file mode 100644 index 00000000..e3586d07 --- /dev/null +++ b/powerdevil/daemon/backends/upower/backlight_helper_actions.actions @@ -0,0 +1,369 @@ +[Domain] +Name=KDE +Name[ar]=كدي +Name[bg]=KDE +Name[bs]=KDE +Name[ca]=KDE +Name[ca@valencia]=KDE +Name[cs]=KDE +Name[da]=KDE +Name[de]=KDE +Name[el]=KDE +Name[en_GB]=KDE +Name[es]=KDE +Name[et]=KDE +Name[eu]=KDE +Name[fa]=KDE +Name[fi]=KDE +Name[fr]=KDE +Name[ga]=KDE +Name[gl]=KDE +Name[gu]=KDE +Name[he]=KDE +Name[hi]=केडीई +Name[hr]=KDE +Name[hu]=KDE +Name[ia]=KDE +Name[is]=KDE +Name[ja]=KDE +Name[kk]=KDE +Name[km]=KDE +Name[kn]=KDE +Name[ko]=KDE +Name[lt]=KDE +Name[lv]=KDE +Name[mr]=केडीई +Name[nb]=KDE +Name[nds]=KDE +Name[nl]=KDE +Name[pa]=KDE +Name[pl]=KDE +Name[pt]=KDE +Name[pt_BR]=KDE +Name[ro]=KDE +Name[ru]=KDE +Name[sk]=KDE +Name[sl]=KDE +Name[sr]=КДЕ +Name[sr@ijekavian]=КДЕ +Name[sr@ijekavianlatin]=KDE +Name[sr@latin]=KDE +Name[sv]=KDE +Name[th]=KDE +Name[tr]=KDE +Name[ug]=ك د ئې(KDE) +Name[uk]=KDE +Name[vi]=KDE +Name[wa]=KDE +Name[x-test]=xxKDExx +Name[zh_CN]=KDE +Name[zh_TW]=KDE +Icon=kde + +[org.kde.powerdevil.backlighthelper.brightness] +Name=Get brightness +Name[bg]=Ниво на яркост +Name[bs]=Dobavi osvetljaj +Name[ca]=Lluminositat de la pantalla +Name[ca@valencia]=Lluminositat de la pantalla +Name[cs]=Získat jas +Name[da]=Hent lysstyrke +Name[de]=Bildschirmhelligkeit abrufen +Name[el]=Ανάκτηση λαμπρότητας +Name[en_GB]=Get brightness +Name[es]=Obtener brillo +Name[et]=Heleduse hankimine +Name[eu]=Eskuratu distira +Name[fi]=Lue kirkkaus +Name[fr]=Obtenir la luminosité +Name[ga]=Faigh an ghile +Name[gl]=Obter o brillo +Name[he]=קבלת ערך הבהירות +Name[hi]=चमक लाएँ +Name[hr]=Dohvati osvjetljenje +Name[hu]=Fényesség lekérdezése +Name[ia]=Obtene brillantia +Name[is]=Ná í upplýsingar um birtu skjás +Name[kk]=Жарықтығын білу +Name[km]=យក​ពន្លឺ +Name[kn]=ಪ್ರದರ್ಶಕದ ಹೊಳಪನ್ನು ತಿಳಿದುಕೊಳ್ಳಿ +Name[ko]=밝기 가져오기 +Name[lt]=Gauti šviesumą +Name[lv]=Iegūt gaišumu +Name[mr]=प्रखरता घ्या +Name[nb]=Hent lysstyrke +Name[nds]=Helligkeit afropen +Name[nl]=Helderheid verkrijgen +Name[pa]=ਚਮਕ ਲਵੋ +Name[pl]=Pobierz jasność +Name[pt]=Obter o brilho +Name[pt_BR]=Obter brilho +Name[ro]=Obține luminozitatea +Name[ru]=Настройка яркости +Name[sk]=Získať jas +Name[sl]=Dobi svetlost +Name[sr]=Добави осветљај +Name[sr@ijekavian]=Добави освјетљај +Name[sr@ijekavianlatin]=Dobavi osvjetljaj +Name[sr@latin]=Dobavi osvetljaj +Name[sv]=Hämta ljusstyrka +Name[th]=แสดงความสว่างของการแสดงผล +Name[tr]=Parlaklık bilgisi al +Name[ug]=يورۇقلۇققا ئېرىش +Name[uk]=Отримання рівня яскравості +Name[vi]=Lấy độ sáng +Name[wa]=Awè l' rilujhance +Name[x-test]=xxGet brightnessxx +Name[zh_CN]=获取亮度 +Name[zh_TW]=取得亮度 +Description=System policies prevent you from getting the brightness level. +Description[bg]=Системни правила забраняват показването на нивото на яркостта +Description[bs]=Sistemske smjernice sprečavaju dobavljanje postavki nivoa osvetljaja. +Description[ca]=Les polítiques del sistema impedeixen que conegueu el nivell de brillantor de la pantalla. +Description[ca@valencia]=Les polítiques del sistema impedeixen que conegueu el nivell de brillantor de la pantalla. +Description[cs]=Nastavení systému vám znemožňuje získat úroveň podsvícení. +Description[da]=Systempolitikker forhindrer dig i at hente lysstyrkeniveauet. +Description[de]=Die Stufe der Bildschirmhelligkeit kann aufgrund einer Systemrichtlinie nicht abgerufen werden. +Description[el]=Οι πολιτικές του συστήματος αποτρέπουν τη λήψη του επίπεδου λαμπρότητας. +Description[en_GB]=System policies prevent you from getting the brightness level. +Description[es]=Las políticas del sistema le impiden guardar el nivel de brillo. +Description[et]=Süsteemi reeglid takistavad heledustaseme hankimist. +Description[eu]=Sistemako gidalerroek distira-maila eskuratzea galarazten dizute. +Description[fi]=Järjestelmämenettelytavat estävät sinua saamasta kirkkauden tasoa selville. +Description[fr]=La stratégie système vous empêche d'obtenir le niveau de luminosité. +Description[ga]=Mar gheall ar pholasaí an chórais, níl cead agat an ghile a fháil. +Description[gl]=As políticas do sistema evitan que coñeza o nivel de brillo. +Description[he]=מדינויות מערכת מונעות קבלת ערך הבהירות. +Description[hr]=Pravila sustava vam onemogućuju dohvaćanje razine osvjetljenja. +Description[hu]=A rendszer házirendjei nem engedik meg Önnek a fényesség lekérdezését. +Description[ia]=Le politicas de systema preveni te ex obtener le nivello de brillantia. +Description[is]=Öryggisstillingar kerfisins koma í veg fyrir að þú getir náð í upplýsingar um birtustig. +Description[kk]=Жарықтық деңгейін білуді болдырмайтын жүйелік ережелері. +Description[km]=គោលនយោបាយ​ប្រព័ន្ធ​ ការពារ​អ្នក​​មិន​ឲ្យ​យក​កម្រិត​ពន្លឺ ។ +Description[kn]=ವ್ಯವಸ್ಥೆಯ ಕಾರ್ಯನೀತಿಯು ನಿಮ್ಮನ್ನು ಪ್ರದರ್ಶಕದ ಹೊಳಪನ್ನು ತಿಳಿದುಕೊಳ್ಳದಂತೆ ತಡೆಯುತ್ತಿದೆ. +Description[ko]=시스템 정책 때문에 밝기를 가져올 수 없습니다. +Description[lt]=Sistemos taisyklės neleidžia jums gauti šviesumo lygio. +Description[lv]=Sistēmas politikas jums neļauj iegūt gaišuma līmeni. +Description[mr]=प्रणाली धोरण प्रखरता पातळी घेण्यास प्रतिबंध करत आहे. +Description[nb]=Systembestemmelser gjør at du ikke kan hente lysstyrkenivået. +Description[nds]=De Systeemregeln verlöövt nich, dat Du de Instellen för de Helligkeit afröppst. +Description[nl]=Systeembeleid voorkwam dat u het helderheidsniveau kon verkrijgen. +Description[pa]=ਸਿਸਟਮ ਪਾਲਸੀ ਤੁਹਾਨੂੰ ਚਮਕ (brightness) ਲੈਵਲ ਲੈਣ ਤੋਂ ਰੋਕਦੀ ਹੈ। +Description[pl]=Polityka systemu nie pozwala Ci na pobranie poziomu jasności. +Description[pt]=As políticas do sistema proíbem a leitura do nível do brilho. +Description[pt_BR]=As políticas do sistema não permitem a modificação do nível de brilho. +Description[ro]=Politicile sistemului vă interzic obținerea nivelului de luminozitate. +Description[ru]=Правила безопасности запрещают вам узнавать уровень яркости. +Description[sk]=Systémové politiky vám zabránili získať úroveň jasu. +Description[sl]=Sistemski pravilniki vam onemogočajo, da bi prebrali svetlost. +Description[sr]=Системске смернице спречавају добављање поставки нивоа осветљаја. +Description[sr@ijekavian]=Системске смјернице спречавају добављање поставки нивоа освјетљаја. +Description[sr@ijekavianlatin]=Sistemske smjernice sprečavaju dobavljanje postavki nivoa osvjetljaja. +Description[sr@latin]=Sistemske smernice sprečavaju dobavljanje postavki nivoa osvetljaja. +Description[sv]=Systemets policy förhindrar att du hämtar ljusstyrkans nivå. +Description[th]=นโยบายของระบบเพื่อป้องกันการแสดงระดับความสว่าง +Description[tr]=Sistem politikaları parlaklık seviye bilgisini almanızı engelliyor +Description[ug]=سىستېما بىخەتەرلىك تەدبىرىڭىز يورۇقلۇق دەرىجىسىگە ئېرىشىشكە يول قويمايدۇ. +Description[uk]=Відповідно до загальносистемних правил, ви не можете отримувати даних щодо рівня яскравості. +Description[wa]=Les politikes do sistinme vos espaitchèt d' awè l' livea del rilujhance. +Description[x-test]=xxSystem policies prevent you from getting the brightness level.xx +Description[zh_CN]=系统安全策略不允许获取亮度级别。 +Description[zh_TW]=系統政策不允許您取得亮度設定。 +Policy=yes +PolicyInactive=yes + +[org.kde.powerdevil.backlighthelper.setbrightness] +Name=Set brightness +Name[bg]=Задаване на яркост +Name[bs]=Postavi osvetljaj +Name[ca]=Ajusta la lluminositat +Name[ca@valencia]=Ajusta la lluminositat +Name[cs]=Nastavit jas +Name[da]=Sæt lysstyrke +Name[de]=Bildschirmhelligkeit einstellen +Name[el]=Ρύθμιση λαμπρότητας +Name[en_GB]=Set brightness +Name[es]=Establecer brillo +Name[et]=Heleduse määramine +Name[eu]=Ezarri distira +Name[fi]=Aseta kirkkaus +Name[fr]=Fixer la luminosité +Name[ga]=Socraigh an ghile +Name[gl]=Axustar o brillo +Name[he]=קביעת הבהירות +Name[hi]=चमक लगाएँ +Name[hr]=Postavi osvjetljenje +Name[hu]=Fényesség beállítása +Name[ia]=Fixa brillantia +Name[is]=Setja birtustig +Name[ja]=明るさを設定 +Name[kk]=Жарықтығын орнату +Name[km]=កំណត់​ពន្លឺ +Name[kn]=ಪ್ರದರ್ಶಕದ ಹೊಳಪನ್ನು ಬದಲಾಯಿಸಿ +Name[ko]=밝기 설정하기 +Name[lt]=Nustatyti šviesumą +Name[lv]=Iestatīt gaišumu +Name[mr]=प्रखरता संयोजना +Name[nb]=Sett lysstyrke +Name[nds]=Helligkeit instellen +Name[nl]=Helderheid instellen +Name[pa]=ਚਮਕ ਸੈੱਟ ਕਰੋ +Name[pl]=Ustaw jasność +Name[pt]=Mudar o brilho +Name[pt_BR]=Definir o brilho +Name[ro]=Stabilește luminozitatea +Name[ru]=Настройка яркости +Name[sk]=Nastaviť jas +Name[sl]=Nastavi svetlost +Name[sr]=Постави осветљај +Name[sr@ijekavian]=Постави освјетљај +Name[sr@ijekavianlatin]=Postavi osvjetljaj +Name[sr@latin]=Postavi osvetljaj +Name[sv]=Ställ in ljusstyrka +Name[th]=ปรับความสว่างของการแสดงผล +Name[tr]=Parlaklığı ayarla +Name[ug]=يورۇقلۇق تەڭشىكى +Name[uk]=Встановлення рівня яскравості +Name[wa]=Defini l' rilujhance +Name[x-test]=xxSet brightnessxx +Name[zh_CN]=设置亮度 +Name[zh_TW]=設定亮度 +Description=System policies prevent you from setting the brightness level. +Description[bg]=Системни правила забраняват настройването на нивото на яркостта +Description[bs]=Sistemske smjernice sprečavaju postavljanje nivoa osvetljaja. +Description[ca]=Les polítiques del sistema impedeixen que ajusteu la lluminositat de la pantalla. +Description[ca@valencia]=Les polítiques del sistema impedeixen que ajusteu la lluminositat de la pantalla. +Description[cs]=Systémové omezení vám neumožňuje nastavit úroveň podsvícení. +Description[da]=Systempolitikker forhindrer dig i at sætte lysstyrkeniveauet. +Description[de]=Die Bildschirmhelligkeit kann aufgrund einer Systemrichtlinie nicht geändert werden. +Description[el]=Οι πολιτικές του συστήματος αποτρέπουν τον ορισμό του επίπεδου λαμπρότητας. +Description[en_GB]=System policies prevent you from setting the brightness level. +Description[es]=Las políticas del sistema le impiden establecer el nivel de brillo. +Description[et]=Süsteemi reeglid takistavad heleduse määramist. +Description[eu]=Sistemako gidalerroek distira-maila ezartzea galarazten dizute. +Description[fi]=Järjestelmämenettelytavat estävät sinua asettamasta kirkkauden tasoa. +Description[fr]=La stratégie système vous empêche de fixer le niveau de luminosité. +Description[ga]=Mar gheall ar pholasaí an chórais, níl cead agat an ghile a shocrú. +Description[gl]=As políticas do sistema evitan que modifique o nivel de brillo. +Description[he]=מדינויות מערכת מונעות קביעת ערך הבהירות. +Description[hr]=Pravila sustava vam onemogućuju postavljanje razine osvjetljenja. +Description[hu]=A rendszer házirendjei nem engedik meg Önnek a fényesség beállítását. +Description[ia]=Le politicas de systema preveni te ex fixar le nivello de brillantia. +Description[is]=Öryggisstillingar kerfisins koma í veg fyrir að þú getir breytt birtustigi. +Description[ja]=システムポリシーにより、明るさを設定することができません。 +Description[kk]=Жарықтық деңгейін орнатуды болдырмайтын жүйелік ережелері. +Description[km]=គោលនយោបាយ​ប្រព័ន្ធ​ការពារ​អ្នក​មិន​​ឲ្យ​កំណត់​កម្រិត​ពន្លឺ ។ +Description[kn]=ವ್ಯವಸ್ಥೆಯ ಕಾರ್ಯನೀತಿಯು ನಿಮ್ಮನ್ನು ಪ್ರದರ್ಶಕದ ಹೊಳಪನ್ನು ಬದಲಾಯಿಸದಂತೆ ತಡೆಯುತ್ತಿದೆ. +Description[ko]=시스템 정책 때문에 밝기를 지정할 수 없습니다. +Description[lt]=Sistemos taisyklės neleidžia jums nustatyti šviesumo lygio. +Description[lv]=Sistēmas politikas jums neļauj iestatīt gaišuma līmeni. +Description[mr]=प्रणाली धोरण प्रखरता पातळी संयोजीत करण्यास प्रतिबंध करत आहे. +Description[nb]=Systembestemmelser gjør at du ikke kan sette lysstyrkenivået. +Description[nds]=De Systeemregeln verlöövt nich, dat Du de Instellen för de Helligkeit instellst. +Description[nl]=Systeembeleid voorkwam dat u het helderheidsniveau kon instellen. +Description[pa]=ਸਿਸਟਮ ਪਾਲਸੀ, ਜੋ ਤੁਹਾਨੂੰ ਚਮਕ ਲੈਵਲ ਸੈੱਟ ਕਰਨ ਤੋਂ ਰੋਕਦੀ ਹੈ। +Description[pl]=Polityka systemu nie pozwala Ci na ustawienie jasności. +Description[pt]=As políticas do sistema proíbem a mudança do nível do brilho. +Description[pt_BR]=As políticas do sistema não permitem a modificação das configurações do nível de brilho. +Description[ro]=Politicile sistemului vă interzic stabilirea nivelului de luminozitate. +Description[ru]=Правила безопасности запрещают вам устанавливать уровень яркости. +Description[sk]=Systémové politiky vám zabránili nastaviť úroveň jasu. +Description[sl]=Sistemski pravilniki vam onemogočajo, da bi nastavili svetlost. +Description[sr]=Системске смернице спречавају постављање нивоа осветљаја. +Description[sr@ijekavian]=Системске смјернице спречавају постављање нивоа освјетљаја. +Description[sr@ijekavianlatin]=Sistemske smjernice sprečavaju postavljanje nivoa osvjetljaja. +Description[sr@latin]=Sistemske smernice sprečavaju postavljanje nivoa osvetljaja. +Description[sv]=Systemets policy förhindrar att du ställer in ljusstyrkans nivå. +Description[th]=นโยบายของระบบเพื่อป้องกันการตั้งระดับความสว่าง +Description[tr]=Sistem politikaları parlaklık seviyesini ayarlamanızı engelliyor +Description[ug]=سىستېما بىخەتەرلىك تەدبىرىڭىز يورۇقلۇق دەرىجىسىنى تەڭشىشىڭىزگە يول قويمايدۇ. +Description[uk]=Відповідно до загальносистемних правил, ви не можете встановлювати рівень яскравості. +Description[wa]=Les politikes do sistinme vos espaitchèt d' defini l' livea del rilujhance. +Description[x-test]=xxSystem policies prevent you from setting the brightness level.xx +Description[zh_CN]=系统安全策略不允许设置亮度级别。 +Description[zh_TW]=系統政策不允許您設定亮度。 +Policy=yes + +[org.kde.powerdevil.backlighthelper.syspath] +Name=Get syspath +Name[bs]=Dobavi sistemsku stazu +Name[ca]=Obtén el «syspath» +Name[ca@valencia]=Obtén el «syspath» +Name[cs]=Získat syspath +Name[da]=Hent syspath +Name[de]=„syspath“ holen +Name[el]=Λήψη syspath +Name[en_GB]=Get syspath +Name[es]=Obtener ruta del sistema +Name[et]=Süsteemse asukoha hankimine +Name[eu]="Syspath", Sistemaren bide-izenak, eskuratu +Name[fi]=Lue järjestelmäpolku +Name[fr]=Obtenir « syspath » +Name[gl]=Obter syspath +Name[hu]=Rendszerútvonal lekérése +Name[ia]=Obtene syspath +Name[kk]=Жүйелік жолды табу +Name[ko]=syspath 가져오기 +Name[lt]=Gauti syspath +Name[nb]=Hent syspath +Name[nds]=Syspadd halen +Name[nl]=Systeempad ophalen +Name[pa]=syspath ਲਵੋ +Name[pl]=Pobierz ścieżkę systemową +Name[pt]=Obter o 'syspath' +Name[pt_BR]=Obter o syspath +Name[ru]=Получение системного пути +Name[sk]=Získať systémovú cestu +Name[sl]=Dobi syspath +Name[sr]=Добави сис‑путању +Name[sr@ijekavian]=Добави сис‑путању +Name[sr@ijekavianlatin]=Dobavi sis‑putanju +Name[sr@latin]=Dobavi sis‑putanju +Name[sv]=Hämta systemsökväg +Name[tr]=Syspath'i al +Name[uk]=Отримання шляху у системі +Name[x-test]=xxGet syspathxx +Name[zh_CN]=获取 syspath +Name[zh_TW]=取得系統路徑 +Description=System policies prevent you from getting the syspath +Description[bs]=Sistemske smjernice sprečavaju dobavljanje sistemske staze. +Description[ca]=Les polítiques del sistema impedeixen que conegueu el camí del sistema «syspath» +Description[ca@valencia]=Les polítiques del sistema impedeixen que conegueu el camí del sistema «syspath» +Description[cs]=Nastavení systému vám znemožňuje získat syspath +Description[da]=Systempolitikker forhindrer dig i at hente syspath +Description[de]=Systemrichtlinien verhindern das Holen von „syspath“ +Description[el]=Οι πολιτικές του συστήματος αποτρέπουν τη λήψη του syspath +Description[en_GB]=System policies prevent you from getting the syspath +Description[es]=Las políticas del sistema le impiden obtener la ruta del sistema. +Description[et]=Süsteemi reeglid takistavad süsteemse asukoha hankimist +Description[eu]=Sistemaren gidalerroek syspath, sistemaren bide-izenak eskuratzea galarazten dizu. +Description[fi]=Järjestelmämenettelytavat estävät sinua saamasta järjestelmäpolkua selville. +Description[fr]=La stratégie système vous empêche d'obtenir « syspath ». +Description[gl]=As políticas do sistema evitan que coñeza syspath +Description[hu]=A rendszer házirendjei nem engedik meg Önnek a rendszerútvonal lekérdezését. +Description[ia]=Le politicas de systema preveni te ex obtener le syspath +Description[kk]=Жүйелік жолын білуді болдырмайтын жүйелік ережелері. +Description[ko]=시스템 정책 때문에 syspath를 가져올 수 없습니다. +Description[lt]=Sistemos taisyklės neleidžia jums gauti syspath +Description[nb]=Systembestemmelser gjør at du ikke kan hente syspath-en +Description[nds]=De Systeemregeln verlöövt nich, dat Du den Syspadd afröppst. +Description[nl]=Systeembeleid voorkwam dat u het systeempad kon ophalen +Description[pa]=ਸਿਸਟਮ ਪਾਲਸੀ ਤੁਹਾਨੂੰ syspath ਲੈਣ ਤੋਂ ਰੋਕਦੀ ਹੈ। +Description[pl]=Polityka systemu nie pozwala Ci na pobranie ścieżki systemowej +Description[pt]=As políticas de sistema impedem-no de obter o 'syspath' +Description[pt_BR]=As políticas do sistema não permitem a modificação do syspath +Description[ru]=Правила безопасности не позволяют вам получить системный путь. +Description[sk]=Systémové politiky vám zabránili získať systémovú cestu +Description[sl]=Sistemski pravilniki vam onemogočajo, da bi prebrali syspath. +Description[sr]=Системске смернице спречавају добављање сис‑путање. +Description[sr@ijekavian]=Системске смјернице спречавају добављање сис‑путање. +Description[sr@ijekavianlatin]=Sistemske smjernice sprečavaju dobavljanje sis‑putanje. +Description[sr@latin]=Sistemske smernice sprečavaju dobavljanje sis‑putanje. +Description[sv]=Systemets policy förhindrar att du hämtar systemsökvägen. +Description[tr]=Sistem politikaları syspath almanızı engelliyor +Description[uk]=Відповідно до загальносистемних правил, ви не можете отримувати даних щодо шляхів у системі +Description[x-test]=xxSystem policies prevent you from getting the syspathxx +Description[zh_CN]=系统安全策略不允许获取系统路径 +Description[zh_TW]=系統政策不允許您取得系統路徑 +Policy=yes +PolicyInactive=yes diff --git a/powerdevil/daemon/backends/upower/backlighthelper.cpp b/powerdevil/daemon/backends/upower/backlighthelper.cpp new file mode 100644 index 00000000..a94217ae --- /dev/null +++ b/powerdevil/daemon/backends/upower/backlighthelper.cpp @@ -0,0 +1,373 @@ +/* This file is part of the KDE project + * Copyright (C) 2010-2011 Lukas Tinkl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "backlighthelper.h" + +#include +#include + +#include + +#ifdef Q_OS_FREEBSD +#define USE_SYSCTL +#endif + +#ifdef USE_SYSCTL +#include +#include + +#define HAS_SYSCTL(n) (sysctlbyname(n, NULL, NULL, NULL, 0) == 0) +#endif + +#define PREFIX "/sys/class/backlight/" + +BacklightHelper::BacklightHelper(QObject * parent) + : QObject(parent), m_isSupported(false) +{ + init(); +} + +void BacklightHelper::init() +{ + + if (useWhitelistInit()) { + initUsingWhitelist(); + } else { + initUsingBacklightType(); + } + + if (m_dirname.isEmpty()) { + initUsingSysctl(); + + if (m_sysctlDevice.isEmpty() || m_sysctlBrightnessLevels.isEmpty()) { + qWarning() << "no kernel backlight interface found"; + return; + } + } + + m_isSupported = true; +} + +void BacklightHelper::initUsingBacklightType() +{ + QDir dir(PREFIX); + dir.setFilter(QDir::AllDirs | QDir::NoDot | QDir::NoDotDot | QDir::NoDotAndDotDot | QDir::Readable); + dir.setSorting(QDir::Name | QDir::Reversed);// Reverse is needed to priorize acpi_video1 over 0 + + QStringList interfaces = dir.entryList(); + + if (interfaces.isEmpty()) { + return; + } + + QFile file; + QByteArray buffer; + QStringList firmware, platform, raw; + + foreach(const QString & interface, interfaces) { + file.setFileName(PREFIX + interface + "/type"); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + continue; + } + + buffer = file.readLine().trimmed(); + if (buffer == "firmware") { + firmware.append(interface); + } else if(buffer == "platform") { + platform.append(interface); + } else if (buffer == "raw") { + raw.append(interface); + } else { + qWarning() << "Interface type not handled" << buffer; + } + + file.close(); + } + + if (!firmware.isEmpty()) { + m_dirname = PREFIX + firmware.first(); + return; + } + + if (!platform.isEmpty()) { + m_dirname = PREFIX + platform.first(); + return; + } + + if (!raw.isEmpty()) { + m_dirname = PREFIX + raw.first(); + return; + } +} + + +void BacklightHelper::initUsingWhitelist() +{ + QStringList interfaces; + interfaces << "nv_backlight" << "radeon_bl" << "mbp_backlight" << "asus_laptop" + << "toshiba" << "eeepc" << "thinkpad_screen" << "acpi_video1" << "acpi_video0" + << "intel_backlight" << "apple_backlight" << "fujitsu-laptop" << "samsung" + << "nvidia_backlight" << "dell_backlight" << "sony" << "pwm-backlight" + ; + + QDir dir; + foreach (const QString & interface, interfaces) { + dir.setPath(PREFIX + interface); + //qDebug() << "searching dir:" << dir; + if (dir.exists()) { + m_dirname = dir.path(); + //qDebug() << "kernel backlight support found in" << m_dirname; + break; + } + } + + //If none of our whitelisted interface is available, get the first one (if any) + if (m_dirname.isEmpty()) { + dir.setPath(PREFIX); + dir.setFilter(QDir::AllDirs | QDir::NoDot | QDir::NoDotDot | QDir::NoDotAndDotDot | QDir::Readable); + QStringList dirList = dir.entryList(); + if (!dirList.isEmpty()) { + m_dirname = dirList.first(); + } + } +} + +bool BacklightHelper::useWhitelistInit() +{ + struct utsname uts; + uname(&uts); + + int major, minor, patch, result; + result = sscanf(uts.release, "%d.%d", &major, &minor); + + if (result != 2) { + return true; // Malformed version + } + + if (major == 3) { + return false; //Kernel 3, we want type based init + } + + result = sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch); + + if (result != 3) { + return true; // Malformed version + } + + if (patch < 37) { + return true; //Minor than 2.6.37, use whiteList based + } + + return false;//Use Type based interafce +} + +void BacklightHelper::initUsingSysctl() +{ +#ifdef USE_SYSCTL + /* + * lcd0 is, in theory, the correct device, but some vendors have custom ACPI implementations + * which cannot be interpreted. In that case, devices should be reported as "out", but + * FreeBSD doesn't care (yet), so they can appear as any other type. Let's search for the first + * device with brightness management, then. + */ + QStringList types; + types << "lcd" << "out" << "crt" << "tv" << "ext"; + foreach (const QString &type, types) { + for (int i = 0; m_sysctlDevice.isEmpty(); i++) { + QString device = QString("%1%2").arg(type, QString::number(i)); + // We don't care about the value, we only want the sysctl to be there. + if (!HAS_SYSCTL(qPrintable(QString("hw.acpi.video.%1.active").arg(device)))) { + break; + } + if (HAS_SYSCTL(qPrintable(QString("hw.acpi.video.%1.brightness").arg(device))) && + HAS_SYSCTL(qPrintable(QString("hw.acpi.video.%1.levels").arg(device)))) { + m_sysctlDevice = device; + break; + } + } + } + + if (m_sysctlDevice.isEmpty()) { + return; + } + + size_t len; + if (sysctlbyname(qPrintable(QString("hw.acpi.video.%1.levels").arg(m_sysctlDevice)), NULL, &len, NULL, 0) != 0 || + len == 0) { + return; + } + int *levels = (int *)malloc(len); + if (!levels) { + return; + } + if (sysctlbyname(qPrintable(QString("hw.acpi.video.%1.levels").arg(m_sysctlDevice)), levels, &len, NULL, 0) != 0) { + free(levels); + return; + } + // acpi_video(4) supports only some predefined brightness levels. + int nlevels = len / sizeof(int); + for (int i = 0; i < nlevels; i++) { + m_sysctlBrightnessLevels << levels[i]; + } + free(levels); + // Sorting helps when finding max value and when scanning for the nearest level in setbrightness(). + qSort(m_sysctlBrightnessLevels.begin(), m_sysctlBrightnessLevels.end()); +#endif +} + +ActionReply BacklightHelper::brightness(const QVariantMap & args) +{ + Q_UNUSED(args); + + ActionReply reply; + + if (!m_isSupported) { + reply = ActionReply::HelperErrorReply; + return reply; + } + + // current brightness + int brightness; + +#ifdef USE_SYSCTL + size_t len = sizeof(int); + if (sysctlbyname(qPrintable(QString("hw.acpi.video.%1.brightness").arg(m_sysctlDevice)), &brightness, &len, NULL, 0) != 0) { + reply = ActionReply::HelperErrorReply; + return reply; + } +#else + QFile file(m_dirname + "/brightness"); + if (!file.open(QIODevice::ReadOnly)) { + reply = ActionReply::HelperErrorReply; + reply.setErrorCode(file.error()); + qWarning() << "reading brightness failed with error code " << file.error() << file.errorString(); + return reply; + } + + QTextStream stream(&file); + stream >> brightness; + file.close(); +#endif + + //qDebug() << "brightness:" << brightness; + reply.addData("brightness", brightness * 100 / maxBrightness()); + //qDebug() << "data contains:" << reply.data()["brightness"]; + + return reply; +} + +ActionReply BacklightHelper::setbrightness(const QVariantMap & args) +{ + ActionReply reply; + + if (!m_isSupported) { + reply = ActionReply::HelperErrorReply; + return reply; + } + + int actual_brightness = qRound(args["brightness"].toFloat() * maxBrightness() / 100); + //qDebug() << "setting brightness:" << actual_brightness; + +#ifdef USE_SYSCTL + int actual_level = -1; + int d1 = 101; + // Search for the nearest level. + foreach (int level, m_sysctlBrightnessLevels) { + int d2 = qAbs(level - actual_brightness); + /* + * The list is sorted, so we break when it starts diverging. There may be repeated values, + * so we keep going on equal gap (e.g., value = 7.5, levels = 0 0 10 ...: we don't break at + * the second '0' so we can get to the '10'). This also means that the value will always + * round off to the bigger level when in the middle (e.g., value = 5, levels = 0 10 ...: + * value rounds off to 10). + */ + if (d2 > d1) { + break; + } + actual_level = level; + d1 = d2; + } + size_t len = sizeof(int); + if (sysctlbyname(qPrintable(QString("hw.acpi.video.%1.brightness").arg(m_sysctlDevice)), NULL, NULL, &actual_level, len) != 0) { + reply = ActionReply::HelperErrorReply; + return reply; + } +#else + QFile file(m_dirname + "/brightness"); + if (!file.open(QIODevice::WriteOnly)) { + reply = ActionReply::HelperErrorReply; + reply.setErrorCode(file.error()); + qWarning() << "writing brightness failed with error code " << file.error() << file.errorString(); + return reply; + } + + int result = file.write(QByteArray::number(actual_brightness)); + file.close(); + + if (result == -1) { + reply = ActionReply::HelperErrorReply; + reply.setErrorCode(file.error()); + qWarning() << "writing brightness failed with error code " << file.error() << file.errorString(); + } +#endif + + return reply; +} + +ActionReply BacklightHelper::syspath(const QVariantMap& args) +{ + Q_UNUSED(args); + + ActionReply reply; + + if (!m_isSupported || m_dirname.isEmpty()) { + reply = ActionReply::HelperErrorReply; + return reply; + } + + reply.addData("syspath", m_dirname); + + return reply; +} + +int BacklightHelper::maxBrightness() const +{ + // maximum brightness + int max_brightness; + +#ifdef USE_SYSCTL + max_brightness = m_sysctlBrightnessLevels.last(); +#else + QFile file(m_dirname + "/max_brightness"); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "reading max brightness failed with error code " << file.error() << file.errorString(); + return -1; // some non-zero value + } + + QTextStream stream(&file); + stream >> max_brightness; + file.close(); +#endif + + //qDebug() << "max brightness:" << max_brightness; + + return max_brightness ? max_brightness : -1; +} + +KDE4_AUTH_HELPER_MAIN("org.kde.powerdevil.backlighthelper", BacklightHelper) diff --git a/powerdevil/daemon/backends/upower/backlighthelper.h b/powerdevil/daemon/backends/upower/backlighthelper.h new file mode 100644 index 00000000..5ab9298d --- /dev/null +++ b/powerdevil/daemon/backends/upower/backlighthelper.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + * Copyright (C) 2010 Lukas Tinkl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKLIGHTHELPER_H +#define BACKLIGHTHELPER_H + +#include +#include + +using namespace KAuth; + +class BacklightHelper: public QObject +{ + Q_OBJECT +public: + BacklightHelper(QObject * parent = 0); + +public slots: + ActionReply brightness(const QVariantMap & args); + ActionReply setbrightness(const QVariantMap & args); + ActionReply syspath(const QVariantMap & args); + +private: + void init(); + /** + * For older kernels that doesn't indicate which type the interface use we have + * a whitelsit based on the feedback given by our users, if the interface is not + * within our whitelist we will look for a random one within the backlight folder + */ + void initUsingWhitelist(); + + /** + * The kernel offer from version 2.6.37 the type of the interface, and based on that + * we can decide which interface is better for us, being the order + * firmware-platform-raw + */ + void initUsingBacklightType(); + + /** + * FreeBSD (and other BSDs) can control backlight via acpi_video(4) + */ + void initUsingSysctl(); + + /** + * If Kernel older than 2.6.37 use whitelsit, otherwise use backlight/type + * @see https://bugs.kde.org/show_bug.cgi?id=288180 + */ + bool useWhitelistInit(); + int maxBrightness() const; + bool m_isSupported; + QString m_dirname; + QString m_sysctlDevice; + QList m_sysctlBrightnessLevels; +}; + +#endif // BACKLIGHTHELPER_H diff --git a/powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml b/powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml new file mode 100644 index 00000000..dc7ae42d --- /dev/null +++ b/powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.Device.xml b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.Device.xml new file mode 100644 index 00000000..3c408ee0 --- /dev/null +++ b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.Device.xml @@ -0,0 +1,613 @@ + +]> + + + + + + Objects implementing this interface are usually discovered through + the org.freedesktop.UPower interface on + the /org/freedesktop/UPower object on + the D-Bus system bus service with the well-known + name org.freedesktop.UPower using + the + EnumerateDevices + method. + + + + +$ dbus-send --print-reply \ + --system \ + --dest=org.freedesktop.UPower \ + /org/freedesktop/UPower/devices/battery_BAT0 \ + org.freedesktop.DBus.Properties.GetAll \ + string:org.freedesktop.UPower.Device + +method return sender=:1.386 -> dest=:1.477 reply_serial=2 + array [ + dict entry( + string "native-path" + variant string "/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:01/PNP0C09:00/PNP0C0A:00/power_supply/BAT0" + ) + dict entry( + string "vendor" + variant string "SONY" + ) + dict entry( + string "model" + variant string "42T4568" + ) + dict entry( + string "serial" + variant string "4179" + ) + dict entry( + string "update-time" + variant uint64 1226417875 + ) + dict entry( + string "type" + variant uint 2 + ) + dict entry( + string "power-supply" + variant boolean true + ) + dict entry( + string "has-history" + variant boolean true + ) + dict entry( + string "has-statistics" + variant boolean true + ) + dict entry( + string "online" + variant boolean false + ) + dict entry( + string "energy" + variant double 72.85 + ) + dict entry( + string "energy-empty" + variant double 0 + ) + dict entry( + string "energy-full" + variant double 74.55 + ) + dict entry( + string "energy-full-design" + variant double 74.88 + ) + dict entry( + string "energy-rate" + variant double 0 + ) + dict entry( + string "voltage" + variant double 16.415 + ) + dict entry( + string "time-to-empty" + variant int64 0 + ) + dict entry( + string "time-to-full" + variant int64 0 + ) + dict entry( + string "percentage" + variant double 97.7197 + ) + dict entry( + string "is-present" + variant boolean true + ) + dict entry( + string "state" + variant uint 3 + ) + dict entry( + string "is-rechargeable" + variant boolean true + ) + dict entry( + string "capacity" + variant double 100 + ) + dict entry( + string "technology" + variant uint 1 + ) + ] + + + + + Unless otherwise noted, an empty string or the value 0 in a + property on this interface means not set. + + + + + + + + + + + + Refreshes the data collected from the power source. + + + Callers need the org.freedesktop.upower.refresh-power-source authorization + + if an error occured while refreshing + + + + + + + + + + Some value on the power source changed. + + + + + + + + + + + OS specific native path of the power source. On Linux this + is the sysfs path, for + example /sys/devices/LNXSYSTM:00/device:00/PNP0C0A:00/power_supply/BAT0. Is + blank if the device is being driven by a user space + driver. + + + + + + + + + + Name of the vendor of the battery. + + + + + + + + + + Name of the model of this battery. + + + + + + + + + + Unique serial number of the battery. + + + + + + + + + + The point in time (seconds since the Epoch Jan 1, 1970 + 0:00 UTC) that data was read from the power source. + + + + + + + + + + Type of power source. + + + + 0Unknown + + + 1Line Power + + + 2Battery + + + 3Ups + + + 4Monitor + + + 5Mouse + + + 6Keyboard + + + 7Pda + + + 8Phone + + + + + + + + + + + If the power device is used to supply the system. + This would be set TRUE for laptop batteries and UPS devices, + but set FALSE for wireless mice or PDAs. + + + + + + + + + + If the power device has history. + + + + + + + + + + If the power device has statistics. + + + + + + + + + + Whether power is currently being provided through line power. + This property is only valid if the property + type + has the value "line-power". + + + + + + + + + + Amount of energy (measured in Wh) currently available in + the power source. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Amount of energy (measured in Wh) in the power source when + it's considered to be empty. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Amount of energy (measured in Wh) in the power source when + it's considered full. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Amount of energy (measured in Wh) the power source is + designed to hold when it's considered full. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Amount of energy being drained from the source, measured + in W. If positive, the source is being discharged, if + negative it's being charged. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Voltage in the Cell or being recorded by the meter. + + + + + + + + + + Number of seconds until the power source is considered empty. + Is set to 0 if unknown. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Number of seconds until the power source is considered full. + Is set to 0 if unknown. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + The amount of energy left in the power source expressed as + a percentage between 0 and 100. Typically this is the same as + (energy - + energy-empty) / + (energy-full - + energy-empty). + However, some primitive power sources are capable of only + reporting percentages and in this case the energy-* + properties will be unset while this property is set. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + If the power source is present in the bay. + This field is required as some batteries are hot-removable, for example + expensive UPS and most laptop batteries. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + The battery power state. + + + + 0Unknown + + + 1Charging + + + 2Discharging + + + 3Empty + + + 4Fully charged + + + 5Pending charge + + + 6Pending discharge + + + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + If the power source is rechargeable. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + The capacity of the power source expressed as a percentage between 0 and 100. + The capacity of the battery will reduce with age. + A capacity value less than 75% is usually a sign that you should renew your battery. + Typically this value is the same as + (full-design / + full) * 100. + However, some primitive power sources are not capable reporting capacity + and in this case the capacity property will be unset. + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + Technology used in the battery: + + + + 0Unknown + + + 1Lithium ion + + + 2Lithium polymer + + + 3Lithium iron phosphate + + + 4Lead acid + + + 5Nickel cadmium + + + 6Nickel metal hydride + + + + This property is only valid if the property + type + has the value "battery". + + + + + + + + + + If the device may have been recalled by the vendor due to a suspected + fault. + This key does not imply the device is faulty, only that it approximatly + matches the description from the vendor of units that were recalled. + + + + + + + + + + The vendor that is handling the hardware recall. + + + This property is only valid if the property recall-notice is true. + + + + + + + + + + The URL to visit about the hardware recall. + + + This property is only valid if the property recall-notice is true. + + + + + + + + diff --git a/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml new file mode 100644 index 00000000..3ccc2113 --- /dev/null +++ b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml @@ -0,0 +1,101 @@ + +]> + + + + + + org.freedesktop.UPower.KbdBacklight is a DBus interface implimented + by UPower. + It allows the keyboard backlight (if present) to be controlled. + + + + + + + + + + The maximum value of the keyboard backlight brightness. + + + + + + + Get the maximum brightness level for the keyboard backlight. + + + + if an error occured while getting the maximum brightness + + + + + + + + + + The current value of the keyboard backlight brightness. + + + + + + + Get the brightness level of the keyboard backlight. + + + + if an error occured while getting the brightness + + + + + + + + + + The value to set the KbdBacklight brightness. + + + + + + + Set the brightness level of the keyboard backlight. + + + + if an error occured while setting the brightness + + + + + + + + + + The new brightness value of the keyboard backlight. + + + + + + + The keyboard backlight brightness level has changed. + + + + + + + + diff --git a/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.xml b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.xml new file mode 100644 index 00000000..807f4e6a --- /dev/null +++ b/powerdevil/daemon/backends/upower/dbus/org.freedesktop.UPower.xml @@ -0,0 +1,395 @@ + + + + + + + + The UPower service is available via the system message + bus. To access the service, use + the org.freedesktop.UPower interface on + the /org/freedesktop/UPower object on + the D-Bus system bus service with the well-known + name org.freedesktop.UPower. + + + + +$ dbus-send --print-reply \ + --system \ + --dest=org.freedesktop.UPower \ + /org/freedesktop/UPower \ + org.freedesktop.UPower.EnumerateDevices + +method return sender=:1.386 -> dest=:1.451 reply_serial=2 + array [ + object path "/org/freedesktop/UPower/devices/line_power_AC" + object path "/org/freedesktop/UPower/devices/battery_BAT0" + ] + + + + + + + + + + + + An array of object paths for devices. + + + + + + Enumerate all power objects on the system. + + + + + + + + + + Object path of device that was added. + + + + + + Emitted when a device is added. + + + + + + + + + + Object path of device that was removed. + + + + + + Emitted when a device is removed. + + + + + + + + + + Object path of device that was changed. + + + + + + Emitted when a device changed. + + + + + + + + + + + + Emitted when one or more properties on the object changes. + + + + + + + + + + + + This signal is sent when the session is about to be suspended or + hibernated. + + + This signal is DEPRECATED. Use NotifySleep() instead. + + + + + + + + + + + + This signal is sent when the session is about to be suspended or + hibernated. + Session and system programs have one second to do anything required + before the sleep action is taken (such as sending out Avahi or + Jabber messages). + + + + + + + The sleep action type, e.g. suspend, + hibernate or hybrid. + + + + + + + + + + + + This signal is sent when the session has just returned from + Suspend() or Hibernate(). + + + This signal is DEPRECATED. Use NotifyResume() instead. + + + + + + + + + + + + This signal is sent when the session has just returned from + Suspend() or Hibernate(). + Session and system programs can then do anything required (such as + sending out Avahi or Jabber messages). + + + + + + + The sleep action type, e.g. suspend, + hibernate or hybrid. + + + + + + + + + + + + + This method tells UPower that the Suspend() or Hibernate() method + is about to be called. + This allows UPower to emit the Suspending signal whilst + session activities are happening that have to be done before the + suspend process is started. + + + This method would typically be called by the session power + management daemon, before it locks the screen and waits for the + screen to fade to black. + The session power management component would then call Suspend() or + Hibernate() when these syncronous tasks have completed. + + + If this method is not called than nothing bad will happen and + Suspend() or Hibernate() will block for the required second. + + + + + + + The sleep action type, e.g. suspend or + hibernate. + + + + + + + + + + + + + Suspends the computer into a low power state. + System state is not preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Suspend. + + + + + + + + + + + + + Hibernates the computer into a low power state. + System state is preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Hibernate. + + + + + + + + + + Version of the running daemon, e.g. 002. + + + + + + Whether the system is able to suspend. + + + + + + Whether the system is able to hibernate. + + + + + + Indicates whether the system is running on battery power. + This property is provided for convenience. + + + + + + Indicates whether the system is running on battery power and if the battery is critically low. + This property is provided for convenience. + + + + + + + + Indicates if the laptop lid is closed where the display cannot be seen. + + + + + + + + + + If the system has a lid device. + + + + + + + + + + If the system really has to sleep when the lid is closed. + Some laptops actually melt (!) if the lid is closed and the + computer keeps running. We blacklist those, and do something + sane for the other machines. + + + This allows us to set the default session policy to not + suspend on lid close if the laptop is docked, and be sure + the machine is not going to melt. + + + + + + + + + + If the system is currently docked. + Note: the "is-docked" value is the result of a heuristic, + which may involve testing the display output. + + + + + + + + diff --git a/powerdevil/daemon/backends/upower/login1suspendjob.cpp b/powerdevil/daemon/backends/upower/login1suspendjob.cpp new file mode 100644 index 00000000..54371c8c --- /dev/null +++ b/powerdevil/daemon/backends/upower/login1suspendjob.cpp @@ -0,0 +1,107 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2010 Alejandro Fiestas + Copyright (C) 2013 Lukáš Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "login1suspendjob.h" + +#include +#include +#include +#include +#include + +Login1SuspendJob::Login1SuspendJob(QDBusInterface *login1Interface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported) + : KJob(), m_login1Interface(login1Interface) +{ + kDebug() << "Starting Login1 suspend job"; + m_method = method; + m_supported = supported; + + connect(m_login1Interface, SIGNAL(PrepareForSleep(bool)), this, SLOT(slotLogin1Resuming(bool))); +} + +Login1SuspendJob::~Login1SuspendJob() +{ + +} + +void Login1SuspendJob::start() +{ + QTimer::singleShot(0, this, SLOT(doStart())); +} + +void Login1SuspendJob::kill(bool /*quietly */) +{ + +} + +void Login1SuspendJob::doStart() +{ + if (m_supported & m_method) + { + QVariantList args; + args << true; // interactive, ie. with polkit dialogs + + QDBusPendingReply reply; + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(sendResult(QDBusPendingCallWatcher*))); + + switch(m_method) + { + case PowerDevil::BackendInterface::ToRam: + reply = m_login1Interface->asyncCallWithArgumentList("Suspend", args); + break; + case PowerDevil::BackendInterface::ToDisk: + reply = m_login1Interface->asyncCallWithArgumentList("Hibernate", args); + break; + case PowerDevil::BackendInterface::HybridSuspend: + reply = m_login1Interface->asyncCallWithArgumentList("HybridSleep", args); + break; + default: + kDebug() << "Unsupported suspend method"; + setError(1); + setErrorText(i18n("Unsupported suspend method")); + break; + } + } +} + +void Login1SuspendJob::sendResult(QDBusPendingCallWatcher *watcher) +{ + const QDBusPendingReply reply = *watcher; + if (!reply.isError()) { + emitResult(); + } else { + kWarning() << "Failed to start suspend job" << reply.error().name() << reply.error().message(); + } + + watcher->deleteLater(); +} + +void Login1SuspendJob::slotLogin1Resuming(bool active) +{ + if (!active) + emitResult(); +} + + +#include "login1suspendjob.moc" diff --git a/powerdevil/daemon/backends/upower/login1suspendjob.h b/powerdevil/daemon/backends/upower/login1suspendjob.h new file mode 100644 index 00000000..e1c2ff42 --- /dev/null +++ b/powerdevil/daemon/backends/upower/login1suspendjob.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2010 Alejandro Fiestas + Copyright (C) 2013 Lukáš Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef LOGIN1SUSPENDJOB_H +#define LOGIN1SUSPENDJOB_H + +#include +#include +#include +#include + +#include "powerdevilbackendinterface.h" + +class Login1SuspendJob : public KJob +{ + Q_OBJECT +public: + Login1SuspendJob(QDBusInterface *login1Interface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported); + virtual ~Login1SuspendJob(); + + void start(); + void kill(bool quietly); + +private Q_SLOTS: + void doStart(); + void sendResult(QDBusPendingCallWatcher* watcher); + void slotLogin1Resuming(bool active); + +private: + QDBusInterface *m_login1Interface; + PowerDevil::BackendInterface::SuspendMethod m_method; + PowerDevil::BackendInterface::SuspendMethods m_supported; +}; + +#endif //LOGIN1SUSPENDJOB_H diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp new file mode 100644 index 00000000..cc20dc73 --- /dev/null +++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp @@ -0,0 +1,570 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2008-2010 Dario Freddi + Copyright (C) 2010 Alejandro Fiestas + Copyright (C) 2010-2013 Lukáš Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "powerdevilupowerbackend.h" + +#include +#include + +#include +#include +#include + +#include "xrandrx11helper.h" +#include "xrandrbrightness.h" +#include "upowersuspendjob.h" +#include "login1suspendjob.h" +#include "upstart_interface.h" +#include "udevqt.h" + +#define HELPER_ID "org.kde.powerdevil.backlighthelper" + +bool checkSystemdVersion(uint requiredVersion) +{ + + QDBusInterface systemdIface("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", + QDBusConnection::systemBus(), 0); + + const QString reply = systemdIface.property("Version").toString(); + + QRegExp expsd("(systemd )?([0-9]+)"); + + if (expsd.exactMatch(reply)) { + const uint version = expsd.cap(2).toUInt(); + return (version >= requiredVersion); + } + + // Since version 1.11 Upstart user sessions implement the exact same API as logind + // and are going to the maintain the API in future releases. + // Hence, powerdevil can support this init system as well + // This has no effect on systemd integration since the check is done after systemd + ComUbuntuUpstart0_6Interface upstartInterface(QLatin1String("com.ubuntu.Upstart"), + QLatin1String("/com/ubuntu/Upstart"), + QDBusConnection::sessionBus()); + + QRegExp exp("(?:init \\()?upstart ([0-9.]+)(?:\\))?"); + if(exp.exactMatch(upstartInterface.version())) { + // Only keep the X.Y part of a X.Y.Z version + QStringList items = exp.cap(1).split('.').mid(0, 2); + const float upstartVersion = items.join(QString('.')).toFloat(); + return upstartVersion >= 1.1; + } + + kDebug() << "No appropriate systemd version or upstart version found"; + return false; +} + +PowerDevilUPowerBackend::PowerDevilUPowerBackend(QObject* parent) + : BackendInterface(parent), + m_brightnessControl(0), m_kbdMaxBrightness(0), + m_lidIsPresent(false), m_lidIsClosed(false), m_onBattery(false) +{ + +} + +PowerDevilUPowerBackend::~PowerDevilUPowerBackend() +{ + delete m_brightnessControl; +} + +bool PowerDevilUPowerBackend::isAvailable() +{ + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { + // Is it pending activation? + kDebug() << "UPower service, " << UPOWER_SERVICE << ", is not registered on the bus. Trying to find out if it is activated."; + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListActivatableNames"); + + QDBusPendingReply< QStringList > reply = QDBusConnection::systemBus().asyncCall(message); + reply.waitForFinished(); + + if (reply.isValid()) { + if (reply.value().contains(UPOWER_SERVICE)) { + kDebug() << "UPower was found, activating service..."; + QDBusConnection::systemBus().interface()->startService(UPOWER_SERVICE); + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { + // Wait for it + QEventLoop e; + QTimer *timer = new QTimer; + timer->setInterval(10000); + timer->setSingleShot(true); + + connect(QDBusConnection::systemBus().interface(), SIGNAL(serviceRegistered(QString)), + &e, SLOT(quit())); + connect(timer, SIGNAL(timeout()), &e, SLOT(quit())); + + timer->start(); + + while (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { + e.exec(); + + if (!timer->isActive()) { + kDebug() << "Activation of UPower timed out. There is likely a problem with your configuration."; + timer->deleteLater(); + return false; + } + } + + timer->deleteLater(); + } + return true; + } else { + kDebug() << "UPower cannot be found on this system."; + return false; + } + } else { + kWarning() << "Could not request activatable names to DBus!"; + return false; + } + } else { + return true; + } +} + +void PowerDevilUPowerBackend::init() +{ + // interfaces + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) { + // Activate it. + QDBusConnection::systemBus().interface()->startService(LOGIN1_SERVICE); + } + + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { + // Activate it. + QDBusConnection::systemBus().interface()->startService(UPOWER_SERVICE); + } + + if (QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) { + m_login1Interface = new QDBusInterface(LOGIN1_SERVICE, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus(), this); + } + + bool screenBrightnessAvailable = false; + m_upowerInterface = new OrgFreedesktopUPowerInterface(UPOWER_SERVICE, "/org/freedesktop/UPower", QDBusConnection::systemBus(), this); + m_brightnessControl = new XRandrBrightness(); + if (!m_brightnessControl->isSupported()) { + kDebug() << "Using helper"; + KAuth::Action action("org.kde.powerdevil.backlighthelper.syspath"); + action.setHelperID(HELPER_ID); + KAuth::ActionReply reply = action.execute(); + if (reply.succeeded()) { + m_syspath = reply.data()["syspath"].toString(); + m_syspath = QFileInfo(m_syspath).readLink(); + + UdevQt::Client *client = new UdevQt::Client(QStringList("backlight"), this); + connect(client, SIGNAL(deviceChanged(UdevQt::Device)), SLOT(onDeviceChanged(UdevQt::Device))); + screenBrightnessAvailable = true; + } + } else { + kDebug() << "Using XRandR"; + m_randrHelper = new XRandRX11Helper(); + connect(m_randrHelper, SIGNAL(brightnessChanged()), this, SLOT(slotScreenBrightnessChanged())); + screenBrightnessAvailable = true; + } + + // Capabilities + setCapabilities(SignalResumeFromSuspend); + + // devices + enumerateDevices(); + + connect(m_upowerInterface, SIGNAL(Changed()), this, SLOT(slotPropertyChanged())); + // for UPower >= 0.99.0, missing Changed() signal + QDBusConnection::systemBus().connect(UPOWER_SERVICE, UPOWER_PATH, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, + SLOT(onPropertiesChanged(QString,QVariantMap,QStringList))); + + connect(m_upowerInterface, SIGNAL(DeviceAdded(QString)), this, SLOT(slotDeviceAdded(QString))); + connect(m_upowerInterface, SIGNAL(DeviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString))); + // for UPower >= 0.99.0, changed signature :o/ + QDBusConnection::systemBus().connect(UPOWER_SERVICE, UPOWER_PATH, UPOWER_IFACE, "DeviceAdded", + this, SLOT(slotDeviceAdded(QDBusObjectPath))); + QDBusConnection::systemBus().connect(UPOWER_SERVICE, UPOWER_PATH, UPOWER_IFACE, "DeviceRemoved", + this, SLOT(slotDeviceRemoved(QDBusObjectPath))); + + connect(m_upowerInterface, SIGNAL(DeviceChanged(QString)), this, SLOT(slotDeviceChanged(QString))); + // for UPower >= 0.99.0, see slotDeviceAdded(const QString & device) + + // Brightness Controls available + BrightnessControlsList controls; + if (screenBrightnessAvailable) { + controls.insert(QLatin1String("LVDS1"), Screen); + m_cachedBrightnessMap.insert(Screen, brightness(Screen)); + kDebug() << "current screen brightness: " << m_cachedBrightnessMap.value(Screen); + } + + m_kbdBacklight = new OrgFreedesktopUPowerKbdBacklightInterface(UPOWER_SERVICE, "/org/freedesktop/UPower/KbdBacklight", QDBusConnection::systemBus(), this); + if (m_kbdBacklight->isValid()) { + // Cache max value + QDBusPendingReply rep = m_kbdBacklight->GetMaxBrightness(); + rep.waitForFinished(); + if (rep.isValid()) { + m_kbdMaxBrightness = rep.value(); + } + // TODO Do a proper check if the kbd backlight dbus object exists. But that should work for now .. + if (m_kbdMaxBrightness) { + controls.insert(QLatin1String("KBD"), Keyboard); + m_cachedBrightnessMap.insert(Keyboard, brightness(Keyboard)); + kDebug() << "current keyboard backlight brightness: " << m_cachedBrightnessMap.value(Keyboard); + connect(m_kbdBacklight, SIGNAL(BrightnessChanged(int)), this, SLOT(onKeyboardBrightnessChanged(int))); + } + } + + // Supported suspend methods + SuspendMethods supported = UnknownSuspendMethod; + if (m_login1Interface && checkSystemdVersion(195)) { + QDBusPendingReply canSuspend = m_login1Interface.data()->asyncCall("CanSuspend"); + canSuspend.waitForFinished(); + if (canSuspend.isValid() && (canSuspend.value() == "yes" || canSuspend.value() == "challenge")) + supported |= ToRam; + + QDBusPendingReply canHibernate = m_login1Interface.data()->asyncCall("CanHibernate"); + canHibernate.waitForFinished(); + if (canHibernate.isValid() && (canHibernate.value() == "yes" || canHibernate.value() == "challenge")) + supported |= ToDisk; + + QDBusPendingReply canHybridSleep = m_login1Interface.data()->asyncCall("CanHybridSleep"); + canHybridSleep.waitForFinished(); + if (canHybridSleep.isValid() && (canHybridSleep.value() == "yes" || canHybridSleep.value() == "challenge")) + supported |= HybridSuspend; + } else { + if (m_upowerInterface->canSuspend() && m_upowerInterface->SuspendAllowed()) { + kDebug() << "Can suspend"; + supported |= ToRam; + } + + if (m_upowerInterface->canHibernate() && m_upowerInterface->HibernateAllowed()) { + kDebug() << "Can hibernate"; + supported |= ToDisk; + } + } + + // "resuming" signal + if (m_login1Interface && checkSystemdVersion(198)) { + connect(m_login1Interface.data(), SIGNAL(PrepareForSleep(bool)), this, SLOT(slotLogin1Resuming(bool))); + } else { + connect(m_upowerInterface, SIGNAL(Resuming()), this, SIGNAL(resumeFromSuspend())); + } + + // battery + QList recallList; + foreach(OrgFreedesktopUPowerDeviceInterface * upowerDevice, m_devices) { + if (upowerDevice->type() == 2 && upowerDevice->powerSupply()) { + QString udi = upowerDevice->path(); + setCapacityForBattery(udi, qRound(upowerDevice->capacity())); // acknowledge capacity + + if (upowerDevice->recallNotice()) { // check for recall notices + RecallNotice notice; + notice.batteryId = udi; + notice.url = upowerDevice->recallUrl(); + notice.vendor = upowerDevice->recallVendor(); + + recallList.append(notice); + } + } + } + if (!recallList.isEmpty()) + setRecallNotices(recallList); + + // backend ready + setBackendIsReady(controls, supported); +} + +void PowerDevilUPowerBackend::onDeviceChanged(const UdevQt::Device &device) +{ + kDebug() << "Udev device changed" << m_syspath << device.sysfsPath(); + if (device.sysfsPath() != m_syspath) { + return; + } + + int maxBrightness = device.sysfsProperty("max_brightness").toInt(); + if (maxBrightness <= 0) { + return; + } + float newBrightness = device.sysfsProperty("brightness").toInt() * 100 / maxBrightness; + + if (!qFuzzyCompare(newBrightness, m_cachedBrightnessMap[Screen])) { + m_cachedBrightnessMap[Screen] = newBrightness; + onBrightnessChanged(Screen, m_cachedBrightnessMap[Screen]); + } +} + +void PowerDevilUPowerBackend::brightnessKeyPressed(PowerDevil::BackendInterface::BrightnessKeyType type, BrightnessControlType controlType) +{ + BrightnessControlsList allControls = brightnessControlsAvailable(); + QList controls = allControls.keys(controlType); + + if (controls.isEmpty()) { + return; // ignore as we are not able to determine the brightness level + } + + if (type == Toggle && controlType == Screen) { + return; // ignore as we wont toggle the screen off + } + + float currentBrightness = brightness(controlType); + + int step = 10; + if (controlType == Keyboard) { + // In case the keyboard backlight has only 5 or less possible values, + // 10% are not enough to hit the next value. Lets use 30% because + // that jumps exactly one value for 2, 3, 4 and 5 possible steps + // when rounded. + if (m_kbdMaxBrightness < 6) { + step = 30; + } + } + + if (qFuzzyCompare(currentBrightness, m_cachedBrightnessMap.value(controlType))) { + float newBrightness; + if (type == Increase) { + newBrightness = qMin(100.0f, currentBrightness + step); + } else if (type == Decrease) { + newBrightness = qMax(0.0f, currentBrightness - step); + } else { // Toggle On/off + newBrightness = currentBrightness > 0 ? 0 : 100; + } + + setBrightness(newBrightness, controlType); + } else { + m_cachedBrightnessMap[controlType] = currentBrightness; + } +} + +float PowerDevilUPowerBackend::brightness(PowerDevil::BackendInterface::BrightnessControlType type) const +{ + float result = 0.0; + + if (type == Screen) { + if (m_brightnessControl->isSupported()) { + //kDebug() << "Calling xrandr brightness"; + result = m_brightnessControl->brightness(); + } else { + //kDebug() << "Falling back to helper to get brightness"; + KAuth::Action action("org.kde.powerdevil.backlighthelper.brightness"); + action.setHelperID(HELPER_ID); + KAuth::ActionReply reply = action.execute(); + if (reply.succeeded()) { + result = reply.data()["brightness"].toFloat(); + //kDebug() << "org.kde.powerdevil.backlighthelper.brightness succeeded: " << reply.data()["brightness"]; + } + else + kWarning() << "org.kde.powerdevil.backlighthelper.brightness failed"; + + } + kDebug() << "Screen brightness: " << result; + } else if (type == Keyboard) { + kDebug() << "Kbd backlight brightness: " << m_kbdBacklight->GetBrightness(); + result = 1.0 * m_kbdBacklight->GetBrightness() / m_kbdMaxBrightness * 100; + } + + return result; +} + +bool PowerDevilUPowerBackend::setBrightness(float brightnessValue, PowerDevil::BackendInterface::BrightnessControlType type) +{ + bool success = false; + if (type == Screen) { + kDebug() << "set screen brightness: " << brightnessValue; + if (m_brightnessControl->isSupported()) { + m_brightnessControl->setBrightness(brightnessValue); + } else { + //kDebug() << "Falling back to helper to set brightness"; + KAuth::Action action("org.kde.powerdevil.backlighthelper.setbrightness"); + action.setHelperID(HELPER_ID); + action.addArgument("brightness", brightnessValue); + KAuth::ActionReply reply = action.execute(); + if (reply.failed()) { + kWarning() << "org.kde.powerdevil.backlighthelper.setbrightness failed"; + return false; + } + } + + success = true; + } else if (type == Keyboard) { + kDebug() << "set kbd backlight: " << brightnessValue; + m_kbdBacklight->SetBrightness(qRound(brightnessValue / 100 * m_kbdMaxBrightness)); + success = true; + } + + return success; +} + +void PowerDevilUPowerBackend::slotScreenBrightnessChanged() +{ + float newBrightness = brightness(Screen); + kDebug() << "Brightness changed!!"; + if (!qFuzzyCompare(newBrightness, m_cachedBrightnessMap[Screen])) { + m_cachedBrightnessMap[Screen] = newBrightness; + onBrightnessChanged(Screen, m_cachedBrightnessMap[Screen]); + } +} + +void PowerDevilUPowerBackend::onKeyboardBrightnessChanged(int value) +{ + kDebug() << "Keyboard brightness changed!!"; + float realValue = 1.0 * value / m_kbdMaxBrightness * 100; + if (!qFuzzyCompare(realValue, m_cachedBrightnessMap[Keyboard])) { + m_cachedBrightnessMap[Keyboard] = realValue; + onBrightnessChanged(Keyboard, m_cachedBrightnessMap[Keyboard]); + } +} + +KJob* PowerDevilUPowerBackend::suspend(PowerDevil::BackendInterface::SuspendMethod method) +{ + if (m_login1Interface && checkSystemdVersion(195)) { + return new Login1SuspendJob(m_login1Interface.data(), method, supportedSuspendMethods()); + } else { + return new UPowerSuspendJob(m_upowerInterface, method, supportedSuspendMethods()); + } +} + +void PowerDevilUPowerBackend::enumerateDevices() +{ + m_lidIsPresent = m_upowerInterface->lidIsPresent(); + m_lidIsClosed = m_upowerInterface->lidIsClosed(); + m_onBattery = m_upowerInterface->onBattery(); + + QList deviceList = m_upowerInterface->EnumerateDevices(); + foreach (const QDBusObjectPath & device, deviceList) { + OrgFreedesktopUPowerDeviceInterface * upowerDevice = + new OrgFreedesktopUPowerDeviceInterface(UPOWER_SERVICE, device.path(), QDBusConnection::systemBus(), this); + m_devices.insert(device.path(), upowerDevice); + } + + updateDeviceProps(); + + if (m_onBattery) + setAcAdapterState(Unplugged); + else + setAcAdapterState(Plugged); +} + +void PowerDevilUPowerBackend::slotDeviceAdded(const QString & device) +{ + OrgFreedesktopUPowerDeviceInterface * upowerDevice = + new OrgFreedesktopUPowerDeviceInterface(UPOWER_SERVICE, device, QDBusConnection::systemBus(), this); + m_devices.insert(device, upowerDevice); + + // for UPower >= 0.99.0 which doesn't emit the DeviceChanged(QString) signal + QDBusConnection::systemBus().connect(UPOWER_SERVICE, device, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, + SLOT(onDevicePropertiesChanged(QString,QVariantMap,QStringList))); + + updateDeviceProps(); +} + +void PowerDevilUPowerBackend::slotDeviceRemoved(const QString & device) +{ + OrgFreedesktopUPowerDeviceInterface * upowerDevice = m_devices.take(device); + + delete upowerDevice; + + updateDeviceProps(); +} + +void PowerDevilUPowerBackend::slotDeviceAdded(const QDBusObjectPath &path) +{ + slotDeviceAdded(path.path()); +} + +void PowerDevilUPowerBackend::slotDeviceRemoved(const QDBusObjectPath &path) +{ + slotDeviceRemoved(path.path()); +} + +void PowerDevilUPowerBackend::slotDeviceChanged(const QString & /*device*/) +{ + updateDeviceProps(); +} + +void PowerDevilUPowerBackend::updateDeviceProps() +{ + qlonglong remainingTime = 0; + + foreach(OrgFreedesktopUPowerDeviceInterface * upowerDevice, m_devices) { + const uint type = upowerDevice->type(); + if (( type == 2 || type == 3) && upowerDevice->powerSupply()) { + const uint state = upowerDevice->state(); + if (state == 1) // charging + remainingTime += upowerDevice->timeToFull(); + else if (state == 2) //discharging + remainingTime += upowerDevice->timeToEmpty(); + } + } + + setBatteryRemainingTime(remainingTime * 1000); +} + +void PowerDevilUPowerBackend::slotPropertyChanged() +{ + // check for lid button changes + if (m_lidIsPresent) { + const bool lidIsClosed = m_upowerInterface->lidIsClosed(); + if (lidIsClosed != m_lidIsClosed) { + if (lidIsClosed) + setButtonPressed(LidClose); + else + setButtonPressed(LidOpen); + } + m_lidIsClosed = lidIsClosed; + } + + // check for AC adapter changes + const bool onBattery = m_upowerInterface->onBattery(); + if (m_onBattery != onBattery) { + if (onBattery) + setAcAdapterState(Unplugged); + else + setAcAdapterState(Plugged); + } + + m_onBattery = onBattery; +} + +void PowerDevilUPowerBackend::onPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps) +{ + Q_UNUSED(changedProps); + Q_UNUSED(invalidatedProps); + + if (ifaceName == UPOWER_IFACE) { + slotPropertyChanged(); // TODO maybe process the 2 properties separately? + } +} + +void PowerDevilUPowerBackend::onDevicePropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps) +{ + Q_UNUSED(changedProps); + Q_UNUSED(invalidatedProps); + + if (ifaceName == UPOWER_IFACE_DEVICE) { + updateDeviceProps(); // TODO maybe process the properties separately? + } +} + +void PowerDevilUPowerBackend::slotLogin1Resuming(bool active) +{ + if (!active) { + emit resumeFromSuspend(); + } +} + +#include "powerdevilupowerbackend.moc" diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.desktop b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.desktop new file mode 100644 index 00000000..1ae15ee0 --- /dev/null +++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.desktop @@ -0,0 +1,115 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=PowerDevilBackend +X-KDE-Library=powerdevilupowerbackend +InitialPreference=200 +Icon=preferences-system-power-management +Name=UPower PowerDevil Backend +Name[ast]=UPower PowerDevil Backend +Name[bg]=PowerDevil поддръжка на UPower +Name[bs]=U‑pauer kao pozadina Strujnog đavola +Name[ca]=Dorsal d'UPower per al PowerDevil +Name[ca@valencia]=Dorsal d'UPower per al PowerDevil +Name[cs]=Podpůrná vrstva UPower PowerDevil +Name[da]=UPower-motor til PowerDevil +Name[de]=UPower-PowerDevil-Modul +Name[el]=Σύστημα υποστήριξης UPower για το PowerDevil +Name[en_GB]=UPower PowerDevil Backend +Name[es]=Motor UPower para PowerDevil +Name[et]=UPoweri PowerDevili taustaprogramm +Name[eu]=UPower, PowerDevil-erako bizkarraldeakoa +Name[fi]=UPower PowerDevil-taustaosa +Name[fr]=Module « UPower » de PowerDevil +Name[ga]=Inneall UPower PowerDevil +Name[gl]=Infraestrutura UPower de PowerDevil +Name[he]=מנגנון UPower PowerDevil +Name[hr]=UPower pozadinski servis za PowerDevil +Name[hu]=UPower Powerdevil-modul +Name[ia]=UPower PowerDevil Backend (RetroAdministration de Powerdevil de UPower) +Name[is]=UPower OrkuPúki +Name[ja]=UPower PowerDevil バックエンド +Name[kk]=UPower PowerDevil тетігі +Name[km]=កម្មវិធី​ខាងក្រោយ UPower PowerDevil +Name[kn]=UPower PowerDevil ಬ್ಯಾಕೆಂಡ್ +Name[ko]=UPower PowerDevil 백엔드 +Name[lt]=UPower PowerDevil programinė sąsaja +Name[lv]=UPower PowerDevil aizmugure +Name[mr]=UPower पॉवरडेव्हिल बॅकएन्ड +Name[nb]=UPower PowerDevil-motor +Name[nds]=Hülpprogramm för den UPower-Stroomdüvel +Name[nl]=Backend voor UPower PowerDevil +Name[pa]=UPower ਪਾਵਰ-ਡੀਵਿਲ ਬੈਕਐਂਡ +Name[pl]=Moduł UPower dla PowerDevil +Name[pt]=Infra-Estrutura de UPower para o PowerDevil +Name[pt_BR]=Infraestrutura de UPower para o PowerDevil +Name[ro]=Platformă PowerDevil UPower +Name[ru]=Модуль поддержки UPower для PowerDevil +Name[sk]=Backend UPower PowerDevil +Name[sl]=Zaledje UPower za PowerDevil +Name[sr]=У‑пауер као позадина Струјног ђавола +Name[sr@ijekavian]=У‑пауер као позадина Струјног ђавола +Name[sr@ijekavianlatin]=UPower kao pozadina Strujnog đavola +Name[sr@latin]=UPower kao pozadina Strujnog đavola +Name[sv]=Upower Powerdevil-gränssnitt +Name[th]=โปรแกรมเบื้องหลัง PowerDevil ของ UPower +Name[tr]=UPower PowerDevil Arkaucu +Name[ug]=UPower PowerDevil ئارقا ئۇچى +Name[uk]=Сервер PowerDevil UPower +Name[wa]=Bouye di fond UPower do Diâle d' enerdjeye +Name[x-test]=xxUPower PowerDevil Backendxx +Name[zh_CN]=UPower PowerDevil 后端 +Name[zh_TW]=UPower PowerDevil 後端介面 +Comment=Use KDE Power Management system through freedesktop.org upower daemon +Comment[ast]=Usar la xestión d'enerxía del sistema KDE a traviés del degorriu HAL de freedesktop.org sobre'l degorriu +Comment[bg]=Управление на захранването на KDE чрез демона upower на freedesktop.org +Comment[bs]=KDE‑ov sistem za upravljanje napajanjem preko demona U‑pauera +Comment[ca]=Usa el sistema de gestió d'energia del KDE mitjançant el dimoni upower del freedesktop.org +Comment[ca@valencia]=Usa el sistema de gestió d'energia del KDE mitjançant el dimoni upower del freedesktop.org +Comment[cs]=Využít démon freedesktop.org upower pro systém správy napájení KDE +Comment[da]=Brug KDE strømstyring via upower-dæmonen fra freedesktop.org +Comment[de]=Das KDE-Energieverwaltungssystem mit Hilfe des upower-Dienstes von freedesktop.org verwenden +Comment[el]=Διαχείριση ενέργειας ΚDE με χρήση του δαίμονα upower του freedesktop.org +Comment[en_GB]=Use KDE Power Management system through freedesktop.org upower dæmon +Comment[es]=Usar el sistema de gestión de energía de KDE mediante el demonio UPower de freedesktop.org +Comment[et]=KDE toitehalduse süsteemi kasutamine freedesktop.org-i upoweri deemoni abil +Comment[eu]=Erabili KDE-ren energia kudeatzeko sistema freedesktop.org upower deabruaren bitartez +Comment[fi]=KDE:n virranhallintajärjestelmän käyttö freedesktop.org upower-taustaprosessilla +Comment[fr]=Utiliser la gestion de l'énergie du matériel de KDE via le démon « UPower » de « freedesktop.org » +Comment[gl]=Usa o sistema de xestión enerxética de KDE mediante o daemon upower de freedesktop.org +Comment[he]=שימוש במנהל צריכת החשמל של KDE דרך תהליך הרקע freedesktop.org upower +Comment[hr]=Koristi KDE-ovo upravljanje potrošnjom energije kroz servis freedesktop.org upower +Comment[hu]=A KDE energiakezelő rendszerének használata a freedesktop.org upower démonán keresztül +Comment[ia]=Usa systema de gestion de energia de KDE usante demone upower de freedesktop.org +Comment[is]=KDE-orkustilling vélbúnaðar með upower púkanum frá freedesktop.org +Comment[ja]=freedesktop.org の upower デーモンを介して KDE 電源管理を使用 +Comment[kk]=freedesktop.org upower қызметі көмегімен KDE қуаттандыру жүйесін басқару +Comment[km]=ប្រើ​ប្រព័ន្ធ​គ្រប់គ្រង​ថាមពល​របស់ KDE តាមរយៈ​ដេមិន freedesktop.org upower +Comment[kn]=freedesktop.org ನ upower ನೇಪಥಿಕ (ಡೀಮನ್) ಬಳಸಿ KDE ವಿದ್ಯುಚ್ಛಕ್ತಿ ನಿರ್ವಹಣಾ ವ್ಯವಸ್ಥೆಯನ್ನು ಬಳಸಿ +Comment[ko]=freedesktop.org UPower 데몬을 사용하는 KDE 전원 관리 시스템 +Comment[lt]=Naudoti KDE energijos valdymo sistemą, naudojant freedesktop.org HAL tarnybą +Comment[lv]=Lietot KDE energokontroles sistēmu, izmantojot freedesktop.org upower dēmonu +Comment[mr]=freedesktop.org upower डीमनने केडीई वीज व्यवस्थापन प्रणाली वापरा +Comment[nb]=Bruk KDE strømstyringssystem med upower-nissen fra freedesktop.org +Comment[nds]=Den UPower-Dämoon vun freedesktop.org för de KDE-Stroomkuntrull bruken +Comment[nl]=KDE energiebeheer gebruiken via de upower-daemon van freedesktop.org +Comment[pa]=freedesktop.org upower ਡੈਮਨ ਰਾਹੀਂ KDE ਪਾਵਰ ਪਰਬੰਧ ਵਰਤੋਂ +Comment[pl]=Zarządzanie zasilaniem za pomocą usługi upower z freedesktop.org +Comment[pt]=Usar o sistema de gestão de energia do KDE através do servidor 'upower' do freedesktop.org +Comment[pt_BR]=Usar o sistema de gerenciamento de energia do KDE através do daemon upower do freedesktop.org +Comment[ro]=Folosește sistemul KDE de gestiune a alimentării prin intermediul demonului upower de la freedesktop.org +Comment[ru]=Управление питанием с использованием службы upower от freedesktop.org +Comment[sk]=Správa napájania KDE pomocou démona upower z freedesktop.org +Comment[sl]=Uporaba KDE-jevega sistema za upravljanje z energijo prek ozadnjega programa freedesktop.org upower +Comment[sr]=КДЕ‑ов систем за управљање напајањем преко демона У‑пауера +Comment[sr@ijekavian]=КДЕ‑ов систем за управљање напајањем преко демона У‑пауера +Comment[sr@ijekavianlatin]=KDE‑ov sistem za upravljanje napajanjem preko demona UPowera +Comment[sr@latin]=KDE‑ov sistem za upravljanje napajanjem preko demona UPowera +Comment[sv]=Använd KDE:s strömsparhantering via Upower-demon från freedesktop.org +Comment[th]=ใช้ระบบจัดการพลังงานของ KDE โดยใช้ดีมอน upower จาก freedesktop.org +Comment[tr]=KDE Güç Yönetim sisteminde freedesktop.org upower servisini kullan +Comment[ug]=KDE توك مەنبە باشقۇرغۇچ سىستېمىسىدا freedesktop.org upower نازارەتچىنى ئىشلەت +Comment[uk]=Використання системи керування живленням KDE за допомогою фонової служби upower freedesktop.org +Comment[wa]=Eployî l' sistinme di manaedjmint di l' enerdjeye di KDE åd triviè do démon upower di freedesktop.org +Comment[x-test]=xxUse KDE Power Management system through freedesktop.org upower daemonxx +Comment[zh_CN]=用 freedesktop.org upower 守护程序进行 KDE 电源管理 +Comment[zh_TW]=透過 freedesktop.org 的 upower 伺服程式使用 KDE 電源管理系統 diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h new file mode 100644 index 00000000..c6563b0d --- /dev/null +++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h @@ -0,0 +1,109 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2008-2010 Dario Freddi + Copyright (C) 2010 Alejandro Fiestas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef POWERDEVILUPOWERBACKEND_H +#define POWERDEVILUPOWERBACKEND_H + +#include + +#include +#include + +#include + +#include "upower_device_interface.h" +#include "upower_interface.h" +#include "upower_kbdbacklight_interface.h" +#include "udevqt.h" + +#define UPOWER_SERVICE "org.freedesktop.UPower" +#define UPOWER_PATH "/org/freedesktop/UPower" +#define UPOWER_IFACE "org.freedesktop.UPower" +#define UPOWER_IFACE_DEVICE "org.freedesktop.UPower.Device" + +#define LOGIN1_SERVICE "org.freedesktop.login1" + +class UdevHelper; +class XRandRX11Helper; +class XRandrBrightness; + +class KDE_EXPORT PowerDevilUPowerBackend : public PowerDevil::BackendInterface +{ + Q_OBJECT + Q_DISABLE_COPY(PowerDevilUPowerBackend) +public: + explicit PowerDevilUPowerBackend(QObject* parent); + virtual ~PowerDevilUPowerBackend(); + + virtual void init(); + static bool isAvailable(); + + virtual float brightness(BrightnessControlType type = Screen) const; + + virtual void brightnessKeyPressed(PowerDevil::BackendInterface::BrightnessKeyType type, PowerDevil::BackendInterface::BrightnessControlType controlType); + virtual bool setBrightness(float brightness, PowerDevil::BackendInterface::BrightnessControlType type = Screen); + virtual KJob* suspend(PowerDevil::BackendInterface::SuspendMethod method); + +private: + void enumerateDevices(); + +private slots: + void updateDeviceProps(); + void slotDeviceAdded(const QString &); + void slotDeviceRemoved(const QString &); + void slotDeviceAdded(const QDBusObjectPath & path); + void slotDeviceRemoved(const QDBusObjectPath & path); + void slotDeviceChanged(const QString &); + void slotPropertyChanged(); + void slotLogin1Resuming(bool active); + void slotScreenBrightnessChanged(); + void onDeviceChanged(const UdevQt::Device &device); + void onKeyboardBrightnessChanged(int); + + void onPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps); + void onDevicePropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps); + +private: + // upower devices + QMap m_devices; + + // brightness + QMap m_cachedBrightnessMap; + XRandrBrightness *m_brightnessControl; + XRandRX11Helper *m_randrHelper; + + OrgFreedesktopUPowerInterface *m_upowerInterface; + OrgFreedesktopUPowerKbdBacklightInterface *m_kbdBacklight; + int m_kbdMaxBrightness; + + // login1 interface + QWeakPointer m_login1Interface; + + // buttons + bool m_lidIsPresent; + bool m_lidIsClosed; + bool m_onBattery; + + //helper path + QString m_syspath; +}; + +#endif // POWERDEVILUPOWERBACKEND_H diff --git a/powerdevil/daemon/backends/upower/udevqt.h b/powerdevil/daemon/backends/upower/udevqt.h new file mode 100644 index 00000000..228687e4 --- /dev/null +++ b/powerdevil/daemon/backends/upower/udevqt.h @@ -0,0 +1,109 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVQT_H +#define UDEVQT_H + +#include +#include +#include +#include +#include + +namespace UdevQt +{ + +class DevicePrivate; +class Device +{ + public: + Device(); + Device(const Device &other); + ~Device(); + Device &operator= (const Device &other); + + bool isValid() const; + QString subsystem() const; + QString devType() const; + QString name() const; + QString sysfsPath() const; + int sysfsNumber() const; + QString driver() const; + QString primaryDeviceFile() const; + QStringList alternateDeviceSymlinks() const; + QStringList deviceProperties() const; + QStringList sysfsProperties() const; + Device parent() const; + + // ### should this really be a QVariant? as far as udev knows, everything is a string... + // see also Client::devicesByProperty + QVariant deviceProperty(const QString &name) const; + QString decodedDeviceProperty(const QString &name) const; + QVariant sysfsProperty(const QString &name) const; + Device ancestorOfType(const QString &subsys, const QString &devtype) const; + + private: + Device(DevicePrivate *devPrivate); + friend class Client; + friend class ClientPrivate; + + DevicePrivate *d; +}; + +typedef QList DeviceList; + +class ClientPrivate; +class Client : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QStringList watchedSubsystems READ watchedSubsystems WRITE setWatchedSubsystems) + + public: + Client(QObject *parent = 0); + Client(const QStringList &subsystemList, QObject *parent = 0); + ~Client(); + + QStringList watchedSubsystems() const; + void setWatchedSubsystems(const QStringList &subsystemList); + + DeviceList allDevices(); + DeviceList devicesByProperty(const QString &property, const QVariant &value); + DeviceList devicesBySubsystem(const QString &subsystem); + Device deviceByDeviceFile(const QString &deviceFile); + Device deviceBySysfsPath(const QString &sysfsPath); + Device deviceBySubsystemAndName(const QString &subsystem, const QString &name); + + signals: + void deviceAdded(const UdevQt::Device &dev); + void deviceRemoved(const UdevQt::Device &dev); + void deviceChanged(const UdevQt::Device &dev); + void deviceOnlined(const UdevQt::Device &dev); + void deviceOfflined(const UdevQt::Device &dev); + + private: + friend class ClientPrivate; + Q_PRIVATE_SLOT(d, void _uq_monitorReadyRead(int fd)) + ClientPrivate *d; +}; + +} + +#endif diff --git a/powerdevil/daemon/backends/upower/udevqt_p.h b/powerdevil/daemon/backends/upower/udevqt_p.h new file mode 100644 index 00000000..189a5ff8 --- /dev/null +++ b/powerdevil/daemon/backends/upower/udevqt_p.h @@ -0,0 +1,82 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVQT_P_H +#define UDEVQT_P_H + +extern "C" +{ +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE +#include +} + +class QByteArray; +class QSocketNotifier; + +namespace UdevQt +{ + +class DevicePrivate +{ + public: + DevicePrivate(struct udev_device *udev_, bool ref = true); + ~DevicePrivate(); + DevicePrivate &operator=(const DevicePrivate& other); + + QString decodePropertyValue(const QByteArray &encoded) const; + + struct udev_device *udev; +}; + + +class ClientPrivate +{ + public: + enum ListenToWhat { ListenToList, ListenToNone }; + + ClientPrivate(Client *q_); + ~ClientPrivate(); + + void init(const QStringList &subsystemList, ListenToWhat what); + void setWatchedSubsystems(const QStringList &subsystemList); + void _uq_monitorReadyRead(int fd); + DeviceList deviceListFromEnumerate(struct udev_enumerate *en); + + struct udev *udev; + struct udev_monitor *monitor; + Client *q; + QSocketNotifier *monitorNotifier; + QStringList watchedSubsystems; +}; + +inline QStringList listFromListEntry(struct udev_list_entry *list) +{ + QStringList ret; + struct udev_list_entry *entry; + + udev_list_entry_foreach(entry, list) { + ret << QString::fromLatin1(udev_list_entry_get_name(entry)); + } + return ret; +} + +} + +#endif diff --git a/powerdevil/daemon/backends/upower/udevqtclient.cpp b/powerdevil/daemon/backends/upower/udevqtclient.cpp new file mode 100644 index 00000000..c1157c3e --- /dev/null +++ b/powerdevil/daemon/backends/upower/udevqtclient.cpp @@ -0,0 +1,256 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevqt.h" +#include "udevqt_p.h" + +#include +#include + +namespace UdevQt { + +ClientPrivate::ClientPrivate(Client *q_) + : udev(0), monitor(0), q(q_), monitorNotifier(0) +{ +} + +ClientPrivate::~ClientPrivate() +{ + udev_unref(udev); + delete monitorNotifier; + + if (monitor) + udev_monitor_unref(monitor); +} + +void ClientPrivate::init(const QStringList &subsystemList, ListenToWhat what) +{ + udev = udev_new(); + + if (what != ListenToNone) { + setWatchedSubsystems(subsystemList); + } +} + +void ClientPrivate::setWatchedSubsystems(const QStringList &subsystemList) +{ + // create a listener + struct udev_monitor *newM = udev_monitor_new_from_netlink(udev, "udev"); + + if (!newM) { + qWarning("UdevQt: unable to create udev monitor connection"); + return; + } + + // apply our filters; an empty list means listen to everything + foreach (const QString& subsysDevtype, subsystemList) { + int ix = subsysDevtype.indexOf("/"); + + if (ix > 0) { + QByteArray subsystem = subsysDevtype.left(ix).toLatin1(); + QByteArray devType = subsysDevtype.mid(ix + 1).toLatin1(); + udev_monitor_filter_add_match_subsystem_devtype(newM, subsystem.constData(), devType.constData()); + } else { + udev_monitor_filter_add_match_subsystem_devtype(newM, subsysDevtype.toLatin1().constData(), NULL); + } + } + + // start the new monitor receiving + udev_monitor_enable_receiving(newM); + QSocketNotifier *sn = new QSocketNotifier(udev_monitor_get_fd(newM), QSocketNotifier::Read); + QObject::connect(sn, SIGNAL(activated(int)), q, SLOT(_uq_monitorReadyRead(int))); + + // kill any previous monitor + delete monitorNotifier; + if (monitor) + udev_monitor_unref(monitor); + + // and save our new one + monitor = newM; + monitorNotifier = sn; + watchedSubsystems = subsystemList; +} + +void ClientPrivate::_uq_monitorReadyRead(int fd) +{ + Q_UNUSED(fd); + monitorNotifier->setEnabled(false); + struct udev_device *dev = udev_monitor_receive_device(monitor); + monitorNotifier->setEnabled(true); + + if (!dev) + return; + + Device device(new DevicePrivate(dev, false)); + + QByteArray action(udev_device_get_action(dev)); + if (action == "add") { + emit q->deviceAdded(device); + } else if (action == "remove") { + emit q->deviceRemoved(device); + } else if (action == "change") { + emit q->deviceChanged(device); + } else if (action == "online") { + emit q->deviceOnlined(device); + } else if (action == "offline") { + emit q->deviceOfflined(device); + } else { + qWarning("UdevQt: unhandled device action \"%s\"", action.constData()); + } +} + +DeviceList ClientPrivate::deviceListFromEnumerate(struct udev_enumerate *en) +{ + DeviceList ret; + struct udev_list_entry *list, *entry; + + udev_enumerate_scan_devices(en); + list = udev_enumerate_get_list_entry(en); + udev_list_entry_foreach(entry, list) { + struct udev_device *ud = udev_device_new_from_syspath(udev_enumerate_get_udev(en), + udev_list_entry_get_name(entry)); + + if (!ud) + continue; + + ret << Device(new DevicePrivate(ud, false)); + } + + udev_enumerate_unref(en); + + return ret; +} + + +Client::Client(QObject *parent) + : QObject(parent) + , d(new ClientPrivate(this)) +{ + d->init(QStringList(), ClientPrivate::ListenToNone); +} + +Client::Client(const QStringList& subsystemList, QObject *parent) + : QObject(parent) + , d(new ClientPrivate(this)) +{ + d->init(subsystemList, ClientPrivate::ListenToList); +} + +Client::~Client() +{ + delete d; +} + +QStringList Client::watchedSubsystems() const +{ + // we're watching a specific list + if (!d->watchedSubsystems.isEmpty()) + return d->watchedSubsystems; + + // we're not watching anything + if (!d->monitor) + return QStringList(); + + // we're watching everything: figure out what "everything" currently is + // we don't cache it, since it may be subject to change, depending on hotplug + struct udev_enumerate *en = udev_enumerate_new(d->udev); + udev_enumerate_scan_subsystems(en); + QStringList s = listFromListEntry(udev_enumerate_get_list_entry(en)); + udev_enumerate_unref(en); + return s; +} + +void Client::setWatchedSubsystems(const QStringList &subsystemList) +{ + d->setWatchedSubsystems(subsystemList); +} + +DeviceList Client::devicesByProperty(const QString &property, const QVariant &value) +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + + if (value.isValid()) { + udev_enumerate_add_match_property(en, property.toLatin1().constData(), value.toString().toLatin1().constData()); + } else { + udev_enumerate_add_match_property(en, property.toLatin1().constData(), NULL); + } + + return d->deviceListFromEnumerate(en); +} + +DeviceList Client::allDevices() +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + return d->deviceListFromEnumerate(en); +} + +DeviceList Client::devicesBySubsystem(const QString &subsystem) +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + + udev_enumerate_add_match_subsystem(en, subsystem.toLatin1().constData()); + return d->deviceListFromEnumerate(en); +} + +Device Client::deviceByDeviceFile(const QString &deviceFile) +{ + struct stat sb; + + if (stat(deviceFile.toLatin1().constData(), &sb) != 0) + return Device(); + + struct udev_device *ud = 0; + + if (S_ISBLK(sb.st_mode)) + ud = udev_device_new_from_devnum(d->udev, 'b', sb.st_rdev); + else if (S_ISCHR(sb.st_mode)) + ud = udev_device_new_from_devnum(d->udev, 'c', sb.st_rdev); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +Device Client::deviceBySysfsPath(const QString &sysfsPath) +{ + struct udev_device *ud = udev_device_new_from_syspath(d->udev, sysfsPath.toLatin1().constData()); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +Device Client::deviceBySubsystemAndName(const QString &subsystem, const QString &name) +{ + struct udev_device *ud = udev_device_new_from_subsystem_sysname(d->udev, + subsystem.toLatin1().constData(), + name.toLatin1().constData()); + + if (!ud) + return Device(); + + return Device(new DevicePrivate(ud, false)); +} + +} + +#include "udevqt.moc" diff --git a/powerdevil/daemon/backends/upower/udevqtdevice.cpp b/powerdevil/daemon/backends/upower/udevqtdevice.cpp new file mode 100644 index 00000000..f1926664 --- /dev/null +++ b/powerdevil/daemon/backends/upower/udevqtdevice.cpp @@ -0,0 +1,270 @@ +/* + Copyright 2009 Benjamin K. Stuhl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevqt.h" +#include "udevqt_p.h" + +#include + +namespace UdevQt { + +DevicePrivate::DevicePrivate(struct udev_device *udev_, bool ref) + : udev(udev_) +{ + if (ref) + udev_device_ref(udev); +} + +DevicePrivate::~DevicePrivate() +{ + udev_device_unref(udev); +} + +DevicePrivate &DevicePrivate::operator=(const DevicePrivate &other) +{ + udev_device_unref(udev); + udev = udev_device_ref(other.udev); + return *this; +} + +QString DevicePrivate::decodePropertyValue(const QByteArray &encoded) const +{ + QByteArray decoded; + const int len = encoded.length(); + + for (int i = 0; i < len; i++) { + quint8 ch = encoded.at(i); + + if (ch == '\\') { + if (i + 1 < len && encoded.at(i + 1) == '\\') { + decoded.append('\\'); + i++; + continue; + } else if (i + 3 < len && encoded.at(i + 1) == 'x') { + QByteArray hex = encoded.mid(i + 2, 2); + bool ok; + int code = hex.toInt(&ok, 16); + if (ok) + decoded.append(char(code)); + i += 3; + continue; + } + } else { + decoded.append(ch); + } + } + return QString::fromUtf8(decoded); +} + +Device::Device() + : d(0) +{ +} + +Device::Device(const Device &other) +{ + if (other.d) { + d = new DevicePrivate(other.d->udev); + } else { + d = 0; + } +} + +Device::Device(DevicePrivate *devPrivate) + : d(devPrivate) +{ +} + +Device::~Device() +{ + delete d; +} + +Device &Device::operator=(const Device &other) +{ + if (this == &other) + return *this; + if (!other.d) { + delete d; + d = 0; + return *this; + } + if (!d) { + d = new DevicePrivate(other.d->udev); + } else { + *d = *other.d; + } + + return *this; +} + +bool Device::isValid() const +{ + return (d != 0); +} + +QString Device::subsystem() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_subsystem(d->udev)); +} + +QString Device::devType() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_devtype(d->udev)); +} + +QString Device::name() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_sysname(d->udev)); +} + +QString Device::sysfsPath() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_syspath(d->udev)); +} + +int Device::sysfsNumber() const +{ + if (!d) + return -1; + + QString value = QString::fromLatin1(udev_device_get_sysnum(d->udev)); + bool success = false; + int number = value.toInt(&success); + if (success) + return number; + return -1; +} + +QString Device::driver() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_driver(d->udev)); +} + +QString Device::primaryDeviceFile() const +{ + if (!d) + return QString(); + + return QString::fromLatin1(udev_device_get_devnode(d->udev)); +} + +QStringList Device::alternateDeviceSymlinks() const +{ + if (!d) + return QStringList(); + + return listFromListEntry(udev_device_get_devlinks_list_entry(d->udev)); +} + +QStringList Device::deviceProperties() const +{ + if (!d) + return QStringList(); + + return listFromListEntry(udev_device_get_properties_list_entry(d->udev)); +} + +QStringList Device::sysfsProperties() const +{ + if (!d) + return QStringList(); + + return listFromListEntry(udev_device_get_properties_list_entry(d->udev)); +} + +Device Device::parent() const +{ + if (!d) + return Device(); + + struct udev_device *p = udev_device_get_parent(d->udev); + + if (!p) + return Device(); + + return Device(new DevicePrivate(p)); +} + +QVariant Device::deviceProperty(const QString &name) const +{ + if (!d) + return QVariant(); + + QByteArray propName = name.toLatin1(); + QString propValue = QString::fromLatin1(udev_device_get_property_value(d->udev, propName.constData())); + if (!propValue.isEmpty()) { + return QVariant::fromValue(propValue); + } + return QVariant(); +} + +QString Device::decodedDeviceProperty(const QString &name) const +{ + if (!d) + return QString(); + + QByteArray propName = name.toLatin1(); + return d->decodePropertyValue(udev_device_get_property_value(d->udev, propName.constData())); +} + +QVariant Device::sysfsProperty(const QString &name) const +{ + if (!d) + return QVariant(); + + QByteArray propName = name.toLatin1(); + QString propValue = QString::fromLatin1(udev_device_get_sysattr_value(d->udev, propName.constData())); + if (!propValue.isEmpty()) { + return QVariant::fromValue(propValue); + } + return QVariant(); +} + +Device Device::ancestorOfType(const QString &subsys, const QString &devtype) const +{ + if (!d) + return Device(); + + struct udev_device *p = udev_device_get_parent_with_subsystem_devtype(d->udev, + subsys.toLatin1().constData(), devtype.toLatin1().constData()); + + if (!p) + return Device(); + + return Device(new DevicePrivate(p)); +} + +} diff --git a/powerdevil/daemon/backends/upower/upowersuspendjob.cpp b/powerdevil/daemon/backends/upower/upowersuspendjob.cpp new file mode 100644 index 00000000..08a850a4 --- /dev/null +++ b/powerdevil/daemon/backends/upower/upowersuspendjob.cpp @@ -0,0 +1,88 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2010 Alejandro Fiestas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "upowersuspendjob.h" + +#include "upower_interface.h" + +#include +#include +#include +#include +#include + +UPowerSuspendJob::UPowerSuspendJob(OrgFreedesktopUPowerInterface *upowerInterface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported) + : KJob(), m_upowerInterface(upowerInterface) +{ + kDebug() << "Starting UPower suspend job"; + m_method = method; + m_supported = supported; + + connect(m_upowerInterface, SIGNAL(Resuming()), this, SLOT(resumeDone())); +} + +UPowerSuspendJob::~UPowerSuspendJob() +{ + +} + +void UPowerSuspendJob::start() +{ + QTimer::singleShot(0, this, SLOT(doStart())); +} + +void UPowerSuspendJob::kill(bool /*quietly */) +{ + +} + +void UPowerSuspendJob::doStart() +{ + if (m_supported & m_method) + { + switch(m_method) + { + case PowerDevil::BackendInterface::ToRam: + m_upowerInterface->AboutToSleep("suspend"); + m_upowerInterface->Suspend(); + break; + case PowerDevil::BackendInterface::ToDisk: + m_upowerInterface->AboutToSleep("hibernate"); + m_upowerInterface->Hibernate(); + break; + default: + kDebug() << "This backend doesn't support hybrid mode"; + setError(1); + setErrorText(i18n("Unsupported suspend method")); + break; + } + emitResult(); + } +} + + +void UPowerSuspendJob::resumeDone() +{ + emitResult(); +} + +#include "upowersuspendjob.moc" diff --git a/powerdevil/daemon/backends/upower/upowersuspendjob.h b/powerdevil/daemon/backends/upower/upowersuspendjob.h new file mode 100644 index 00000000..aac4b12b --- /dev/null +++ b/powerdevil/daemon/backends/upower/upowersuspendjob.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens + Copyright (C) 2010 Alejandro Fiestas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef UPOWERSUSPENDJOB_H +#define UPOWERSUSPENDJOB_H + +#include +#include +#include + +#include "powerdevilbackendinterface.h" + +class OrgFreedesktopUPowerInterface; + +class UPowerSuspendJob : public KJob +{ + Q_OBJECT +public: + UPowerSuspendJob(OrgFreedesktopUPowerInterface *upowerInterface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported); + virtual ~UPowerSuspendJob(); + + void start(); + void kill(bool quietly); + +private Q_SLOTS: + void doStart(); + void resumeDone(); + +private: + OrgFreedesktopUPowerInterface *m_upowerInterface; + PowerDevil::BackendInterface::SuspendMethod m_method; + PowerDevil::BackendInterface::SuspendMethods m_supported; +}; + +#endif //UPOWERSUSPENDJOB_H diff --git a/powerdevil/daemon/backends/upower/xlibandxrandr.h b/powerdevil/daemon/backends/upower/xlibandxrandr.h new file mode 100644 index 00000000..0dab3672 --- /dev/null +++ b/powerdevil/daemon/backends/upower/xlibandxrandr.h @@ -0,0 +1,36 @@ +/************************************************************************************* + * Copyright (C) 2012 by Alejandro Fiestas Olivares * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#ifndef XLIBANDXRANDR_H +#define XLIBANDXRANDR_H + +extern "C" +{ +#include +#include +#define INT8 _X11INT8 +#define INT32 _X11INT32 +#include +#undef INT8 +#undef INT32 +#include +} + +#include + +#endif // XLIBANDXRANDR diff --git a/powerdevil/daemon/backends/upower/xrandrbrightness.cpp b/powerdevil/daemon/backends/upower/xrandrbrightness.cpp new file mode 100644 index 00000000..f18092e7 --- /dev/null +++ b/powerdevil/daemon/backends/upower/xrandrbrightness.cpp @@ -0,0 +1,182 @@ +/* This file is part of the KDE project + * Copyright (C) 2010 Lukas Tinkl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "xrandrbrightness.h" + +#include + +#include +#include + +#include +#include +#include + +XRandrBrightness::XRandrBrightness() + : m_backlight(None), m_resources(0) +{ + // init + int major, minor; + if (!XRRQueryVersion (QX11Info::display(), &major, &minor)) + { + qWarning("RandR extension missing"); + return; + } + + if (major < 1 || (major == 1 && minor < 2)) + { + qWarning("RandR version %d.%d too old", major, minor); + return; + } + + m_backlight = XInternAtom(QX11Info::display(), "Backlight", True); + if (m_backlight == None) + m_backlight = XInternAtom(QX11Info::display(), "BACKLIGHT", True); // try with legacy atom + + if (m_backlight == None) + { + qWarning("No outputs have backlight property"); + return; + } + + m_resources = XRRGetScreenResources(QX11Info::display(), QX11Info::appRootWindow()); + + if (!m_resources) + { + qWarning("No available Randr resources"); + return; + } +} + +XRandrBrightness::~XRandrBrightness() +{ + if (m_resources) { + XRRFreeScreenResources(m_resources); + } +} + +bool XRandrBrightness::isSupported() const +{ + if (!m_resources) + return false; + + // Verify that there are outputs that actually support backlight control... + for (int o = 0; o < m_resources->noutput; o++) + { + if (backlight_get(m_resources->outputs[o]) != -1) { + return true; + } + } + + return false; +} + +float XRandrBrightness::brightness() const +{ + float result = 0; + + if (!m_resources) + return result; + + for (int o = 0; o < m_resources->noutput; o++) + { + RROutput output = m_resources->outputs[o]; + double cur = backlight_get(output); + if (cur != -1) + { + XRRPropertyInfo * info = XRRQueryOutputProperty(QX11Info::display(), output, m_backlight); + if (info) + { + if (info->range && info->num_values == 2) + { + double min = info->values[0]; + double max = info->values[1]; + XFree(info); + + // FIXME for now just return the first output's value + result = (cur - min) * 100 / (max - min); + break; + } + XFree(info); + } + } + } + + return result; +} + +void XRandrBrightness::setBrightness(float brightness) +{ + if (!m_resources) + return; + + for (int o = 0; o < m_resources->noutput; o++) + { + RROutput output = m_resources->outputs[o]; + double cur = backlight_get(output); + if (cur != -1) + { + XRRPropertyInfo * info = XRRQueryOutputProperty(QX11Info::display(), output, m_backlight); + if (info) + { + if (info->range && info->num_values == 2) + { + double min = info->values[0]; + double max = info->values[1]; + + // FIXME for now just set the first output's value + double value = min + (brightness * (max - min) / 100); + backlight_set(output, (long) (value + 0.5)); + } + XFree(info); + } + } + } + + XSync(QX11Info::display(), False); +} + +long XRandrBrightness::backlight_get(RROutput output) const +{ + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop; + Atom actual_type; + int actual_format; + long value; + + if (!m_backlight || XRRGetOutputProperty (QX11Info::display(), output, m_backlight, + 0, 4, False, False, None, + &actual_type, &actual_format, + &nitems, &bytes_after, &prop) != Success) + return -1; + + if (actual_type != XA_INTEGER || nitems != 1 || actual_format != 32) + value = -1; + else + value = *((long *) prop); + XFree (prop); + return value; +} + +void XRandrBrightness::backlight_set(RROutput output, long value) +{ + XRRChangeOutputProperty (QX11Info::display(), output, m_backlight, XA_INTEGER, 32, + PropModeReplace, (unsigned char *) &value, 1); +} diff --git a/powerdevil/daemon/backends/upower/xrandrbrightness.h b/powerdevil/daemon/backends/upower/xrandrbrightness.h new file mode 100644 index 00000000..875c6672 --- /dev/null +++ b/powerdevil/daemon/backends/upower/xrandrbrightness.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + * Copyright (C) 2010 Lukas Tinkl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef XRANDRBRIGHTNESS_H +#define XRANDRBRIGHTNESS_H + +#include + +#include +#include +#include + +class XRandrBrightness +{ +public: + XRandrBrightness(); + ~XRandrBrightness(); + bool isSupported() const; + float brightness() const; + void setBrightness(float brightness); + +private: + long backlight_get(RROutput output) const; + void backlight_set(RROutput output, long value); + + Atom m_backlight; + XRRScreenResources *m_resources; +}; + +#endif // XRANDRBRIGHTNESS_H diff --git a/powerdevil/daemon/backends/upower/xrandrx11helper.cpp b/powerdevil/daemon/backends/upower/xrandrx11helper.cpp new file mode 100644 index 00000000..28bad37f --- /dev/null +++ b/powerdevil/daemon/backends/upower/xrandrx11helper.cpp @@ -0,0 +1,70 @@ +/************************************************************************************* + * Copyright (C) 2013 by Dan Vrátil * + * Copyright (C) 2013 by Dario Freddi * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#include "xrandrx11helper.h" + +#include + +#include +#include + +XRandRX11Helper::XRandRX11Helper(): + QWidget() +{ + XRRQueryVersion (QX11Info::display(), &m_versionMajor, &m_versionMinor); + + XRRQueryExtension(QX11Info::display(), &m_randrBase, &m_randrError); + + m_window = XCreateSimpleWindow(QX11Info::display(), + XRootWindow(QX11Info::display(), DefaultScreen(QX11Info::display())) + , 0, 0, 1, 1, 0, 0, 0 ); + + XRRSelectInput(QX11Info::display(), m_window, RROutputPropertyNotifyMask); + + KSystemEventFilter::installEventFilter(this); +} + +XRandRX11Helper::~XRandRX11Helper() +{ + KSystemEventFilter::removeEventFilter(this); + XDestroyWindow(QX11Info::display(), m_window); +} + +bool XRandRX11Helper::x11Event(XEvent *event) +{ + XRRNotifyEvent* e2 = reinterpret_cast< XRRNotifyEvent* >(event); + + if (event->xany.type != m_randrBase + RRNotify) { + return false; + } + + if (e2->subtype == RRNotify_OutputProperty) { + XRROutputPropertyNotifyEvent* e2 = reinterpret_cast< XRROutputPropertyNotifyEvent* >(event); + char *atomName = XGetAtomName(QX11Info::display(), e2->property); + if (QString(atomName) == RR_PROPERTY_BACKLIGHT) { + Q_EMIT brightnessChanged(); + } + + XFree(atomName); + } + + return false; +} + +#include "xrandrx11helper.moc" diff --git a/powerdevil/daemon/backends/upower/xrandrx11helper.h b/powerdevil/daemon/backends/upower/xrandrx11helper.h new file mode 100644 index 00000000..184f582a --- /dev/null +++ b/powerdevil/daemon/backends/upower/xrandrx11helper.h @@ -0,0 +1,49 @@ +/************************************************************************************* + * Copyright (C) 2013 by Dan Vrátil * + * Copyright (C) 2013 by Dario Freddi * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#ifndef XRANDRX11HELPER_H +#define XRANDRX11HELPER_H + +#include +#include "xlibandxrandr.h" + +class XRandRX11Helper : public QWidget +{ + Q_OBJECT + + public: + XRandRX11Helper(); + virtual ~XRandRX11Helper(); + + Q_SIGNALS: + void brightnessChanged(); + + protected: + virtual bool x11Event(XEvent *); + + int m_randrBase; + int m_randrError; + int m_versionMajor; + int m_versionMinor; + + bool m_debugMode; + Window m_window; +}; + +#endif // XRANDRX11HELPER_H diff --git a/powerdevil/daemon/brightnessosdwidget.cpp b/powerdevil/daemon/brightnessosdwidget.cpp new file mode 100644 index 00000000..1474018d --- /dev/null +++ b/powerdevil/daemon/brightnessosdwidget.cpp @@ -0,0 +1,135 @@ +/******************************************************************* +* brightnessosdwidget.cpp +* adapted from kdemultimedia/kmix/osdwidget.cpp +* Copyright 2009 Aurélien Gâteau +* Copyright 2009 Dario Andres Rodriguez +* Copyright 2009 Christian Esken +* Copyright 2010 Felix Geyer +* +* 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. If not, see . +* +******************************************************************/ + +#include "brightnessosdwidget.h" + +// Qt +#include +#include +#include +#include + +// KDE +#include +#include +#include +#include +#include +#include + +BrightnessOSDWidget::BrightnessOSDWidget(PowerDevil::BackendInterface::BrightnessControlType type, QWidget * parent) + : Plasma::Dialog(parent, Qt::ToolTip), + m_type(type), + m_scene(new QGraphicsScene(this)), + m_container(new QGraphicsWidget), + m_iconLabel(new Plasma::Label), + m_volumeLabel(new Plasma::Label), + m_meter(new Plasma::Meter), + m_hideTimer(new QTimer(this)) +{ + KWindowSystem::setState(winId(), NET::KeepAbove); + KWindowSystem::setType(winId(), NET::Tooltip); + setAttribute(Qt::WA_X11NetWmWindowTypeToolTip, true); + m_meter->setMeterType(Plasma::Meter::BarMeterHorizontal); + m_meter->setMaximum(100); + + m_volumeLabel->setAlignment(Qt::AlignCenter); + + //Setup the auto-hide timer + m_hideTimer->setInterval(2000); + m_hideTimer->setSingleShot(true); + connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hide())); + + //Setup the OSD layout + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(m_container); + layout->setContentsMargins(0, 0, 0, 0); + layout->addItem(m_iconLabel); + layout->addItem(m_meter); + layout->addItem(m_volumeLabel); + + m_scene->addItem(m_container); + setGraphicsWidget(m_container); + + themeUpdated(); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeUpdated())); // e.g. for updating font +} + +void BrightnessOSDWidget::activateOSD() +{ + m_hideTimer->start(); +} + +void BrightnessOSDWidget::setCurrentBrightness(int brightnessLevel) +{ + m_meter->setValue(brightnessLevel); + m_volumeLabel->setText(QString::number(brightnessLevel) + " %"); +} + +void BrightnessOSDWidget::themeUpdated() +{ + //Set a font which makes the text appear as big (height-wise) as the meter. + //QFont font = QFont(m_volumeLabel->nativeWidget()->font()); + Plasma::Theme* theme = Plasma::Theme::defaultTheme(); + + + QPalette palette = m_volumeLabel->palette(); + palette.setColor(QPalette::WindowText, theme->color(Plasma::Theme::TextColor)); + m_volumeLabel->setPalette(palette); + + QFont font = theme->font(Plasma::Theme::DefaultFont); + font.setPointSize(15); + m_volumeLabel->setFont(font); + QFontMetrics qfm(font); + QRect textSize = qfm.boundingRect("100 % "); + + int widthHint = textSize.width(); + int heightHint = textSize.height(); + //setCurrentVolume(100,false); + m_volumeLabel->setMaximumHeight(heightHint); + m_volumeLabel->setMinimumWidth(widthHint); + m_volumeLabel->nativeWidget()->setFixedWidth(widthHint); + + //Cache the icon pixmaps + QFontMetrics fm(m_volumeLabel->font()); + QSize iconSize = QSize(fm.height(), fm.height()); + + if (m_type == PowerDevil::BackendInterface::Screen) { + m_brightnessPixmap = KIcon("video-display").pixmap(iconSize); + } else { + m_brightnessPixmap = KIcon("input-keyboard").pixmap(iconSize); + } + + m_iconLabel->nativeWidget()->setPixmap(m_brightnessPixmap); + m_iconLabel->nativeWidget()->setFixedSize(iconSize); + m_iconLabel->setMinimumSize(iconSize); + m_iconLabel->setMaximumSize(iconSize); + + m_meter->setMaximumHeight(iconSize.height()); + m_container->setMinimumSize(iconSize.width() * 13 + m_volumeLabel->nativeWidget()->width(), iconSize.height()); + m_container->setMaximumSize(iconSize.width() * 13 + m_volumeLabel->nativeWidget()->width(), iconSize.height()); + + syncToGraphicsWidget(); +} + + +#include "brightnessosdwidget.moc" diff --git a/powerdevil/daemon/brightnessosdwidget.h b/powerdevil/daemon/brightnessosdwidget.h new file mode 100644 index 00000000..40166d4a --- /dev/null +++ b/powerdevil/daemon/brightnessosdwidget.h @@ -0,0 +1,65 @@ +/******************************************************************* +* brightnessosdwidget.h +* adapted from kdemultimedia/kmix/osdwidget.h +* Copyright 2009 Aurélien Gâteau +* Copyright 2009 Dario Andres Rodriguez +* Copyright 2009 Christian Esken +* Copyright 2010 Felix Geyer +* +* 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. If not, see . +* +******************************************************************/ + +#ifndef BRIGHTNESSOSDWIDGET__H +#define BRIGHTNESSOSDWIDGET__H + +#include "powerdevilbackendinterface.h" + +#include + +#include + +class QTimer; + +namespace Plasma +{ +class Label; +class Meter; +} + +class BrightnessOSDWidget : public Plasma::Dialog +{ +Q_OBJECT +public: + BrightnessOSDWidget(PowerDevil::BackendInterface::BrightnessControlType type, QWidget * parent = 0); + + void setCurrentBrightness(int brightnessLevel); + void activateOSD(); + +protected slots: + void themeUpdated(); + +private: + PowerDevil::BackendInterface::BrightnessControlType m_type; + QGraphicsScene *m_scene; + QGraphicsWidget *m_container; + Plasma::Label *m_iconLabel; + Plasma::Label *m_volumeLabel; + Plasma::Meter *m_meter; + QTimer *m_hideTimer; + + QPixmap m_brightnessPixmap; +}; + +#endif diff --git a/powerdevil/daemon/config-powerdevil.h.cmake b/powerdevil/daemon/config-powerdevil.h.cmake new file mode 100644 index 00000000..b730cd9f --- /dev/null +++ b/powerdevil/daemon/config-powerdevil.h.cmake @@ -0,0 +1,2 @@ +/* Defines if you have UDev */ +#cmakedefine HAVE_UDEV 1 diff --git a/powerdevil/daemon/kdedpowerdevil.cpp b/powerdevil/daemon/kdedpowerdevil.cpp new file mode 100644 index 00000000..4b363a78 --- /dev/null +++ b/powerdevil/daemon/kdedpowerdevil.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "kdedpowerdevil.h" + +#include "powerdevilfdoconnector.h" +#include "powermanagementadaptor.h" +#include "powermanagementpolicyagentadaptor.h" + +#include "powerdevilbackendloader.h" +#include "powerdevilcore.h" + +#include + +#include +#include + +#include +#include +#include + +K_PLUGIN_FACTORY( PowerDevilFactory, + registerPlugin(); ) +K_EXPORT_PLUGIN( PowerDevilFactory( "powerdevildaemon" ) ) + +#define POWERDEVIL_VERSION "1.99" + +KDEDPowerDevil::KDEDPowerDevil(QObject* parent, const QVariantList &) + : KDEDModule(parent) +{ + QTimer::singleShot(0, this, SLOT(init())); +} + +KDEDPowerDevil::~KDEDPowerDevil() +{ +} + +void KDEDPowerDevil::init() +{ + KGlobal::insertCatalog("powerdevil"); + + KAboutData aboutData("powerdevil", "powerdevil", ki18n("KDE Power Management System"), + POWERDEVIL_VERSION, ki18n("KDE Power Management System is PowerDevil, an " + "advanced, modular and lightweight Power Management " + "daemon"), + KAboutData::License_GPL, ki18n("(c) 2010 MetalWorkers Co."), + KLocalizedString(), "http://www.kde.org"); + + aboutData.addAuthor(ki18n( "Dario Freddi" ), ki18n("Maintainer"), "drf@kde.org", + "http://drfav.wordpress.com"); + + if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.PowerManagement") || + QDBusConnection::systemBus().interface()->isServiceRegistered("com.novell.powersave") || + QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.Policy.Power")) { + kError() << "KDE Power Management system not initialized, another power manager has been detected"; + return; + } + + m_core = new PowerDevil::Core(this, KComponentData(aboutData)); + + connect(m_core, SIGNAL(coreReady()), this, SLOT(onCoreReady())); + + // Before doing anything, let's set up our backend + PowerDevil::BackendInterface *interface = PowerDevil::BackendLoader::loadBackend(m_core); + + if (!interface) { + // Ouch + kError() << "KDE Power Management System init failed!"; + m_core->loadCore(0); + } else { + // Let's go! + kDebug() << "Backend loaded, loading core"; + m_core->loadCore(interface); + } +} + +void KDEDPowerDevil::onCoreReady() +{ + kDebug() << "Core is ready, registering various services on the bus..."; + //DBus logic for the core + new PowerManagementAdaptor(m_core); + new PowerDevil::FdoConnector(m_core); + + QDBusConnection::sessionBus().registerService("org.kde.Solid.PowerManagement"); + QDBusConnection::sessionBus().registerObject("/org/kde/Solid/PowerManagement", m_core); + + QDBusConnection::systemBus().interface()->registerService("org.freedesktop.Policy.Power"); + + // Start the Policy Agent service + new PowerManagementPolicyAgentAdaptor(PowerDevil::PolicyAgent::instance()); + + QDBusConnection::sessionBus().registerService("org.kde.Solid.PowerManagement.PolicyAgent"); + QDBusConnection::sessionBus().registerObject("/org/kde/Solid/PowerManagement/PolicyAgent", PowerDevil::PolicyAgent::instance()); +} + +#include "kdedpowerdevil.moc" diff --git a/powerdevil/daemon/kdedpowerdevil.h b/powerdevil/daemon/kdedpowerdevil.h new file mode 100644 index 00000000..137e6ca5 --- /dev/null +++ b/powerdevil/daemon/kdedpowerdevil.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef KDEDPOWERDEVIL_H +#define KDEDPOWERDEVIL_H + +#include +#include + +namespace PowerDevil { + class Core; +} + +class KDEDPowerDevil : public KDEDModule +{ + Q_OBJECT + Q_DISABLE_COPY(KDEDPowerDevil) + +public: + explicit KDEDPowerDevil(QObject* parent, const QVariantList &); + virtual ~KDEDPowerDevil(); + +private Q_SLOTS: + void init(); + void onCoreReady(); + +private: + PowerDevil::Core *m_core; +}; + +#endif // KDEDPOWERDEVIL_H diff --git a/powerdevil/daemon/org.kde.Solid.PowerManagement.xml b/powerdevil/daemon/org.kde.Solid.PowerManagement.xml new file mode 100644 index 00000000..e097dfce --- /dev/null +++ b/powerdevil/daemon/org.kde.Solid.PowerManagement.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/powerdevil/daemon/powerdevil.desktop b/powerdevil/daemon/powerdevil.desktop new file mode 100644 index 00000000..e1fa3e0b --- /dev/null +++ b/powerdevil/daemon/powerdevil.desktop @@ -0,0 +1,145 @@ +[Desktop Entry] +Type=Service +Icon=preferences-system-power-management +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=powerdevil +X-KDE-DBus-ModuleName=powerdevil +X-KDE-Kded-autoload=true +X-KDE-Kded-load-on-demand=false +X-KDE-Kded-phase=1 + +Name=Power Management +Name[ar]=إدارة الطاقة +Name[ast]=Xestión d'enerxía +Name[be@latin]=Kiravańnie enerhijaj +Name[bg]=Управление на захранването +Name[bn]=পাওয়ার ব্যবস্থাপনা +Name[bn_IN]=বিদ্যুৎ সরবরাহ পরিচালনা +Name[bs]=Upravljanje napajanjem +Name[ca]=Gestió d'energia +Name[ca@valencia]=Gestió d'energia +Name[cs]=Správa napájení +Name[csb]=Sprôwianié mòcą +Name[da]=Strømstyring +Name[de]=Energieverwaltung +Name[el]=Διαχείριση ενέργειας +Name[en_GB]=Power Management +Name[eo]=Energiadministrado +Name[es]=Gestión de energía +Name[et]=Toitehaldus +Name[eu]=Energia-kudeaketa +Name[fi]=Virranhallinta +Name[fr]=Gestion de l'énergie +Name[fy]=Enerzjybehear +Name[ga]=Bainisteoireacht Cumhachta +Name[gl]=Xestión da enerxía +Name[gu]=પાવર વ્યવસ્થાપક +Name[he]=ניהול צריכת חשמל +Name[hi]=बिज़ली प्रबंधन +Name[hne]=पावर प्रबंधन +Name[hr]=Upravljanje potrošnjom energije +Name[hu]=Energiakezelő +Name[ia]=Gestion de energia +Name[id]=Manajemen Daya +Name[is]=Orkustjórnun +Name[it]=Gestione energetica +Name[ja]=電源管理 +Name[kk]=Қуаттандыруды басқару +Name[km]=ការ​គ្រប់គ្រង​ថាមពល +Name[kn]=ವಿದ್ಯುಚ್ಛಕ್ತಿ ವ್ಯವಸ್ಥಾಪನೆ +Name[ko]=전원 관리 +Name[ku]=Gerînendeyê hêzê +Name[lt]=Energijos valdymas +Name[lv]=Energokontrole +Name[mai]=पावर मैनेजमेंट +Name[mk]=Менаџмент на енергија +Name[ml]=വൈദ്യുതി നടത്തിപ്പു് +Name[mr]=वीज व्यवस्थापन +Name[nb]=Strømstyring +Name[nds]=Stroomkuntrull +Name[nl]=Energiebeheer +Name[nn]=Straumstyring +Name[or]=ଶକ୍ତି ପରିଚାଳନା +Name[pa]=ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ +Name[pl]=Zarządzanie energią +Name[pt]=Gestão de Energia +Name[pt_BR]=Gerenciamento de energia +Name[ro]=Gestiune energie +Name[ru]=Управление питанием +Name[si]=බල පරිපාලනය +Name[sk]=Správa napájania +Name[sl]=Upravljanje z energijo +Name[sr]=Управљање напајањем +Name[sr@ijekavian]=Управљање напајањем +Name[sr@ijekavianlatin]=Upravljanje napajanjem +Name[sr@latin]=Upravljanje napajanjem +Name[sv]=Strömsparhantering +Name[ta]=Power Management +Name[tg]=Идоракунии барқ +Name[th]=การจัดการพลังงาน +Name[tr]=Güç Yönetimi +Name[ug]=توك مەنبەسىنى باشقۇرۇش +Name[uk]=Керування живленням +Name[wa]=Manaedjmint di l' enerdjeye +Name[x-test]=xxPower Managementxx +Name[zh_CN]=电源管理 +Name[zh_TW]=電源管理 + +Comment=Battery, Display and CPU power management and notification +Comment[ar]=إدارة طاقة وإشعارات البطارية والشاشة والمعالج +Comment[ast]=Xestión y notificaciones d'enerxía de la batería, pantalla y CPU +Comment[bg]=Управление и уведомяване относно захранването на батерията, екрана и процесора +Comment[bs]=Obavještavanje i upravljanje baterijom i napajanjem ekrana i procesora +Comment[ca]=Gestió d'energia i notificació de la bateria, pantalla i CPU +Comment[ca@valencia]=Gestió d'energia i notificació de la bateria, pantalla i CPU +Comment[cs]=Správa a oznamování baterie, zobrazení a výkonu CPU +Comment[da]=Bekendtgørelser om strømstyring for batteri, skærm og CPU +Comment[de]=Akku-, Anzeige- und Prozessorleistungsverwaltung und -benachrichtigung +Comment[el]=Μπαταρία, Εμφάνιση και διαχείριση ενέργειας και ειδοποιήσεων ΚΜΕ +Comment[en_GB]=Battery, Display and CPU power management and notification +Comment[es]=Gestión y notificaciones de energía de la batería, pantalla y CPU +Comment[et]=Aku, monitori ja protsessori toitehaldus ja märguanded +Comment[eu]=Bateriaren, bistaratzearen eta PUZaren ahalmenaren kudeaketa eta jakinarazpenak +Comment[fi]=Akun, näytön ja suorittimen virranhallinta sekä ilmoitukset +Comment[fr]=Gestion et notifications de l'énergie pour les batteries, l'affichage et la consommation du processeur +Comment[gl]=Xestión e notificacións da xestión enerxética da batería, da pantalla e da CPU +Comment[he]=ניהול והודעות של צריכת החשמל של הסוללה, התצוגה והמעבד +Comment[hr]=Upravljanje potrošnjom energije baterije, ekrana i CPU-a i pripadajućim obavijestima. +Comment[hu]=Akkumulátor-, kijelző- és processzorkezelés és értesítés +Comment[ia]=Batteria, monstrator, gestion de energia de CPU e notification +Comment[id]=Baterai, Tampilan dan manajemen daya CPU dan notifikasi +Comment[is]=Stjórnun og tilkynningar vegna rafhlaðna, skjáa og örgjörva +Comment[ja]=バッテリ、ディスプレイ、CPU の電源管理と通知 +Comment[kk]=Батарея, дисплей, процесорын қуаттаныруын басқару және олs туралы құлақтандыру +Comment[km]=ថ្ម បង្ហាញ​ការ​ជូនដំណឹង និង​គ្រប់គ្រង​ថាមពល​ស៊ីភីយូ +Comment[ko]=배터리, 디스플레이, CPU 전원 관리 및 알림 +Comment[lt]=Baterijos, Monitoriaus ir CPU energijos valdymas ir pranešimai +Comment[lv]=Baterijas, ekrāna un procesora enerģijas pārvaldība un paziņojumi +Comment[mr]=बॅटरी, डिस्प्ले व CPU वीज व्यवस्थापन व सूचना +Comment[nb]=Håndtering og varsling for strømstyring av batteri, skjerm og prosessor +Comment[nds]=Batterie-, Schirm- un Perzesser-Stroomkuntrull un -Bescheden +Comment[nl]=Energiebeheer voor accu, scherm en CPU en meldingen +Comment[pa]=ਬੈਟਰੀ, ਡਿਸਪਲੇਅ ਤੇ CPU ਪਾਵਰ ਪਰਬੰਧ ਤੇ ਨੋਟੀਫਿਕੇਸ਼ਨ +Comment[pl]=Zarządzanie i powiadomienia o stanie baterii, wyświetlacza i zasilania procesora +Comment[pt]=Gestão e notificação da energia, do ecrã e do CPU +Comment[pt_BR]=Gerenciamento e notificação de energia, da tela e do CPU +Comment[ro]=Gestiune și notificări pentru acumulator, afișaj și putere procesor +Comment[ru]=Настройка яркости экрана, режима ожидания и питания +Comment[si]=බැටරි, ප්‍රදර්ශන සහ CPU බලශක්ති කළමනාකරනය සහ දැනුම්දීම +Comment[sk]=Správa napájania a upozornenia batérie, obrazovky a CPU +Comment[sl]=Upravljanje in obveščanje o porabi energije baterije, zaslona in procesorja +Comment[sr]=Обавештавање и управљање батеријом и напајањем екрана и процесора +Comment[sr@ijekavian]=Обавјештавање и управљање батеријом и напајањем екрана и процесора +Comment[sr@ijekavianlatin]=Obavještavanje i upravljanje baterijom i napajanjem ekrana i procesora +Comment[sr@latin]=Obaveštavanje i upravljanje baterijom i napajanjem ekrana i procesora +Comment[sv]=Hantering och underrättelser om batteri, skärm och processorkraft +Comment[tg]=Батарея, Экран ва идоракунии манбаъи CPU ва огоҳӣ +Comment[th]=การจัดการพลังงานของ แบตเตอรี่, ส่วนแสดงผล และซีพียู รวมถึงการแจ้งให้ทราบ +Comment[tr]=Pil, Ekran ve CPU güç yönetimi ve bildirimler +Comment[ug]=توكدان، ئېكران ۋە CPU توك مەنبە باشقۇرۇش ۋە ئۇقتۇرۇش +Comment[uk]=Керування та сповіщення про стан акумуляторів та живлення дисплея і процесора +Comment[vi]=Quản lý năng lượng và thông báo cho pin, màn hình và CPU +Comment[wa]=Manaedjmint eyet notifiaedje di l' enerdjeye del batreye, do håynaedje et do CPU +Comment[x-test]=xxBattery, Display and CPU power management and notificationxx +Comment[zh_CN]=电池、显示器和 CPU 电源管理及通知 +Comment[zh_TW]=電池、顯示與 CPU 電力管理與通知 diff --git a/powerdevil/daemon/powerdevilaction.cpp b/powerdevil/daemon/powerdevilaction.cpp new file mode 100644 index 00000000..f16394cc --- /dev/null +++ b/powerdevil/daemon/powerdevilaction.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevilaction.h" + +#include "powerdevilcore.h" + +#include + +namespace PowerDevil +{ + +class Action::Private +{ +public: + Private() {} + ~Private() {} + + PowerDevil::Core *core; + + QList< int > registeredIdleTimeouts; + PowerDevil::PolicyAgent::RequiredPolicies requiredPolicies; +}; + +Action::Action(QObject* parent) + : QObject(parent) + , d(new Private) +{ + d->core = qobject_cast(parent); +} + +Action::~Action() +{ + delete d; +} + +void Action::registerIdleTimeout(int msec) +{ + d->registeredIdleTimeouts.append(msec); + d->core->registerActionTimeout(this, msec); +} + +bool Action::unloadAction() +{ + // Remove all registered idle timeouts, if any + d->core->unregisterActionTimeouts(this); + d->registeredIdleTimeouts.clear(); + + // Ok, let's see if the action has to do something for being unloaded + return onUnloadAction(); +} + +bool Action::onUnloadAction() +{ + // Usually nothing has to be done, so let's just happily return true + return true; +} + +bool Action::isSupported() +{ + return true; +} + +BackendInterface* Action::backend() const +{ + return d->core->backend(); +} + +Core* Action::core() +{ + return d->core; +} + +void Action::trigger(const QVariantMap& args) +{ + if (args.contains("Explicit") && args["Explicit"].toBool()) { + // The action was explicitly triggered by the user, hence any policy check is bypassed. + triggerImpl(args); + } else { + // The action was taken automatically: let's check if we have the rights to do that + PolicyAgent::RequiredPolicies unsatisfiablePolicies = PolicyAgent::instance()->requirePolicyCheck(d->requiredPolicies); + if (unsatisfiablePolicies == PolicyAgent::None) { + // Ok, let's trigger the action + triggerImpl(args); + } else { + // TODO: Notify somehow? + kWarning() << "Unsatisfied policies, the action has been aborted"; + } + } +} + +void Action::setRequiredPolicies(PolicyAgent::RequiredPolicies requiredPolicies) +{ + d->requiredPolicies = requiredPolicies; +} + +} + +#include "powerdevilaction.moc" diff --git a/powerdevil/daemon/powerdevilaction.h b/powerdevil/daemon/powerdevilaction.h new file mode 100644 index 00000000..81249d47 --- /dev/null +++ b/powerdevil/daemon/powerdevilaction.h @@ -0,0 +1,234 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_POWERDEVILACTION_H +#define POWERDEVIL_POWERDEVILACTION_H + +#include "powerdevilpolicyagent.h" + +#include +#include + +#include + +class KConfigGroup; + +namespace PowerDevil +{ +class BackendInterface; +class Core; + +/** + * @brief The base class for Power Management Actions + * + * The Action class is the very base class for writing a new Power Management action. + * Developers wishing to implement their own action are supposed to subclass Action. + * + * @par Creating a brand new Action + * + * If you are already familiar with KDE's plugin system, you have to know that actions are + * nothing but a KService plugin which will be loaded on demand. Each action has an ID associated to it + * which represents it in the config file and uniquely identifies it in the loading phase. + * + * In addition to standard parameters, the .desktop file representing your action should contain the following + * entries: + * + * @code + * X-KDE-ServiceTypes=PowerDevil/Action + * X-KDE-PowerDevil-Action-ID=YourActionID + * X-KDE-PowerDevil-Action-IsBundled=false + * X-KDE-PowerDevil-Action-UIComponentLibrary=myactionplugin_config + * X-KDE-PowerDevil-Action-ConfigPriority=98 + * @endcode + * + * The @c UIComponentLibrary field refers to the library which contains the configuration UI + * for your action. Please see ActionConfig documentation for more details. + * + * The @c ConfigPriority is relevant to the configuration UI as well, and determines where your config UI will appear. + * The higher the number, the higher your config UI will be in the list of actions. Choose this value wisely: usually + * only very basic power management functions should have a value > 50. + * + * The most important functions you need to reimplement are loadAction and triggerImpl. The first is called + * whenever an action is loaded, carrying the action's configuration. The other is called whenever + * the action is triggered. You usually want to process the action here as triggerImpl is guaranteed + * to be called just when policies are satisfied. + * + * @par Runtime requirements + * + * Some actions might be available only when the system satisfies certain hardware or software runtime requirements. + * In this case, powerdevil provides a way for the action to advertise to the outside whether it is supported or + * not. This can be done by reimplementing @c isSupported and adding to the .desktop file the field + * + * @code + * X-KDE-PowerDevil-Action-HasRuntimeRequirement=true + * @endcode + * + * Done that, powerdevil will take care of exposing your action only if support for it is advertised. In addition, + * the UI will expose the configuration of your action only if its support is advertised. Of course, this means the + * action will be temporarily loaded by the config UI to verify its support. If your action is performing some tasks in + * the constructor besides setting policies, first of all revise your design since you probably don't need or want to + * do that. If you really cannot avoid that, you MUST check for an OPTIONAL parameter in the QVariantList coming + * from the plugin's constructor. If it exists, it's a boolean and it is true, the action is being loaded just for + * a support check, and you should refrain from doing any actions which would affect the system. This parameter is also + * used in tests. + * + * @par Handling policies from within the action + * + * As you might know, the KDE Power Management system features a very efficient policy handler, which + * prevents Power Management actions when certain condition occurs. The integration with Actions is very easy: + * in your Action's constructor, you want to call setRequiredPolicies, stating which policies have to be + * satisfied to perform the action. For example, if your action should not be performed whenever the session + * cannot be interrupted, you would pass @c InterruptSession. + * + * Done that, your action is already obeying to the policy. trigger, in fact, calls triggerImpl just when + * the policies are allowing your action to be performed. + * + * @since 4.6 + */ +class KDE_EXPORT Action : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Action) + +public: + /** + * Default constructor + */ + explicit Action(QObject *parent); + /** + * Default destructor + */ + virtual ~Action(); + + /** + * Reimplement this function when creating a new Action. This function is called whenever the action is loaded or + * its configuration changes. It carries the KConfigGroup associated with your action and generated from your + * config interface. + * + * @param config The action's configuration which should be loaded. + * @returns Whether the action has been successfully loaded. + * + * @see ActionConfig + */ + virtual bool loadAction(const KConfigGroup &config) = 0; + /** + * Unloads the action. You usually shouldn't reimplement this function: reimplement onUnloadAction instead. + * + * @returns Whether the action has been successfully unloaded + */ + virtual bool unloadAction(); + + /** + * This function is meant to find out if this action is available on this system. Actions + * CAN reimplement this function if they are dependent on specific hardware/software requirements. + * By default, this function will always return true. + * + * Should this function return false, the core will delete and ignore the action right after creation. + * + * @returns Whether this action is supported or not by the current system + */ + virtual bool isSupported(); + + /** + * Triggers the action with the given argument. This function is meant to be used by the caller only - + * if you are implementing your own action, reimplement triggerImpl instead. + * + * @param args The arguments for triggering the action + */ + void trigger(const QVariantMap &args); + +protected: + /** + * Registers an idle timeout for this action. Call this function and not KIdleTime directly to take advantage + * of Action's automated handling of idle timeouts. Also, please reimplement onIdleTimeout instead of listening + * to KIdleTime's signals to catch idle timeout events. + * + * @param msec The idle timeout to be registered in milliseconds. + */ + void registerIdleTimeout(int msec); + /** + * Sets the required policies needed for this Action to run. Usually, you want to call this function in your + * Action's constructor. + * + * @param requiredPolicies A set of policies which are required to run this action. It can be empty if your + * Action does not rely on policies. + */ + void setRequiredPolicies(PowerDevil::PolicyAgent::RequiredPolicies requiredPolicies); + + /** + * This function's body should undertake the Action's execution. It has to be reimplemented in a new Action. + * + * @param args The arguments for triggering the action + */ + virtual void triggerImpl(const QVariantMap &args) = 0; + + /** + * @returns The BackendInterface + */ + PowerDevil::BackendInterface *backend() const; + /** + * @returns The PowerDevil Core + */ + PowerDevil::Core *core(); + +protected Q_SLOTS: + /** + * This function is called whenever a profile is loaded. Please note that this is slightly different from + * loadAction: in fact a profile can be reloaded without having the action change its configuration. + * If your action should do something as soon as a profile switches, it should be done inside this function. + */ + virtual void onProfileLoad() = 0; + /** + * This slot is triggered whenever an idle timeout registered with registerIdleTimeout is reached. + * + * @param msec The idle timeout reached in milliseconds + */ + virtual void onIdleTimeout(int msec) = 0; + /** + * This slot is triggered whenever the PC wakes up from an Idle state. It is @b always called after a registered + * idle timeout has been reached. + */ + virtual void onWakeupFromIdle() = 0; + /** + * This function is called when the profile is unloaded. + */ + virtual void onProfileUnload() = 0; + /** + * This function is called when the action is unloaded. You usually want to put what would have gone in your + * destructor here. + * + * @returns Whether the action was unloaded successfully. + */ + virtual bool onUnloadAction(); + +Q_SIGNALS: + void actionTriggered(bool result, const QString &error = QString()); + +private: + class Private; + Private * const d; + + friend class Core; + friend class ActionPool; +}; + +} + +#endif // POWERDEVIL_POWERDEVILACTION_H diff --git a/powerdevil/daemon/powerdevilactionconfig.cpp b/powerdevil/daemon/powerdevilactionconfig.cpp new file mode 100644 index 00000000..51b1d946 --- /dev/null +++ b/powerdevil/daemon/powerdevilactionconfig.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevilactionconfig.h" + +namespace PowerDevil +{ + +class ActionConfig::Private +{ +public: + KConfigGroup config; +}; + +ActionConfig::ActionConfig(QObject *parent) + : QObject(parent) + , d(new Private) +{ + +} + +ActionConfig::~ActionConfig() +{ + delete d; +} + +KConfigGroup ActionConfig::configGroup() const +{ + return d->config; +} + +void ActionConfig::setConfigGroup(const KConfigGroup& group) +{ + d->config = group; +} + +void ActionConfig::setChanged() +{ + emit changed(); +} + +} + +#include "powerdevilactionconfig.moc" diff --git a/powerdevil/daemon/powerdevilactionconfig.h b/powerdevil/daemon/powerdevilactionconfig.h new file mode 100644 index 00000000..a114b65a --- /dev/null +++ b/powerdevil/daemon/powerdevilactionconfig.h @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_POWERDEVILACTIONCONFIG_H +#define POWERDEVIL_POWERDEVILACTIONCONFIG_H + +#include + +#include + +#include + +namespace PowerDevil { + +/** + * @brief The base class for Action's config interfaces + * + * This class should be reimplemented when creating a new Action. It is used to generate + * a configuration UI for your action and integrate it into KDE Power Management System's + * config module seamlessly. + * + * @par Creating an ActionConfig + * + * If you already have been through creating an Action, you have seen that Action's desktop + * file contains already all the needed information for loading its respective ActionConfig. For this + * reason, despite ActionConfig being a plugin, you do not need to create a desktop file for it - + * you just have to write the correct info into the Action's one. + * + * @par The key/value pair rationale + * + * The config UI works in a key/value fashion, where value is a generic QWidget. This is done + * to keep the UI consistent without hurting the flexibility of the implementation. + * Please remember to keep the configuration as easy and essential as possible: if you have gone + * beyond 2 rows, you might be doing something wrong. + * + * @par Loading and saving configuration + * + * Of course, you should also be providing the logic for saving and loading your action's configuration. + * This is done through KConfigGroup: your action has a KConfigGroup assigned by KDE Power Management System + * which can be accessed through configGroup or overwritten through setConfigGroup. The very same group + * you are loading/saving here will be the one passed to Action::loadAction. + * + * @see Action + * + * @since 4.6 + */ +class KDE_EXPORT ActionConfig : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(ActionConfig) + +public: + /** + * Default constructor + */ + ActionConfig(QObject *parent); + /** + * Default destructor + */ + virtual ~ActionConfig(); + + /** + * @returns The KConfigGroup associated to this action, where data should be saved (and loaded) + * + * @note You should not track this KConfigGroup, as it might change from profile to profile. + * Always use this function to access it. + */ + KConfigGroup configGroup() const; + /** + * Overwrites the config group associated with this Action with @c group. + * + * @param group A KConfigGroup carrying the settings for this Action. + */ + void setConfigGroup(const KConfigGroup &group); + + /** + * This function should return the key/value pairs containing your Action's configuration UI. + * + * @returns A list of QString, QWidget pairs representing your Action's configuration UI + */ + virtual QList< QPair< QString, QWidget* > > buildUi() = 0; + + /** + * This function gets called whenever the parent module requires to load a specific configuration. This + * usually occurs when @c configGroup is updated, for example due to the fact that the user wants to modify + * a different profile. In this function, you should update the info contained in the widgets generated + * by @c buildUi accordingly. + */ + virtual void load() = 0; + /** + * This function gets called whenever the parent module requires to save the configuration. Usually, you + * want to read values from the widgets generated with @c buildUi and call @c setConfigGroup to update the + * Action's configuration. + */ + virtual void save() = 0; + +protected Q_SLOTS: + /** + * Call this slot whenever the user makes some changes to the widgets. + */ + void setChanged(); + +Q_SIGNALS: + /** + * This signal gets emitted every time the user changes the (unsaved) configuration. Do not emit this signal + * directly: call setChanged instead. + * + * @see setChanged + */ + void changed(); + +private: + class Private; + Private * const d; +}; + +} + +#endif // POWERDEVIL_POWERDEVILACTIONCONFIG_H diff --git a/powerdevil/daemon/powerdevilactionpool.cpp b/powerdevil/daemon/powerdevilactionpool.cpp new file mode 100644 index 00000000..970aa18a --- /dev/null +++ b/powerdevil/daemon/powerdevilactionpool.cpp @@ -0,0 +1,186 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "powerdevilactionpool.h" + +#include "powerdevilaction.h" +#include "powerdevilcore.h" + +#include +#include +#include +#include +#include + +#include + +// Bundled actions: +#include "actions/bundled/suspendsession.h" +#include "actions/bundled/brightnesscontrol.h" +#include "actions/bundled/keyboardbrightnesscontrol.h" +#include "actions/bundled/dimdisplay.h" +#include "actions/bundled/runscript.h" +#include "actions/bundled/handlebuttonevents.h" + +namespace PowerDevil +{ + +class ActionPoolHelper +{ +public: + ActionPoolHelper() : q(0) {} + ~ActionPoolHelper() { + delete q; + } + ActionPool *q; +}; + +K_GLOBAL_STATIC(ActionPoolHelper, s_globalActionPool) + +ActionPool *ActionPool::instance() +{ + if (!s_globalActionPool->q) { + new ActionPool; + } + + return s_globalActionPool->q; +} + +ActionPool::ActionPool() +{ + Q_ASSERT(!s_globalActionPool->q); + s_globalActionPool->q = this; +} + +ActionPool::~ActionPool() +{ + clearCache(); +} + +void ActionPool::clearCache() +{ + QHash< QString, Action* >::iterator i = m_actionPool.begin(); + while (i != m_actionPool.end()) { + // Delete the associated action and erase + i.value()->deleteLater(); + i = m_actionPool.erase(i); + } +} + +void ActionPool::init(PowerDevil::Core *parent) +{ + // Load all the actions + KService::List offers = KServiceTypeTrader::self()->query("PowerDevil/Action", + "[X-KDE-PowerDevil-Action-IsBundled] == FALSE"); + foreach (KService::Ptr offer, offers) { + QString actionId = offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String).toString(); + + kDebug() << "Got a valid offer for " << actionId; + //try to load the specified library + PowerDevil::Action *retaction = offer->createInstance< PowerDevil::Action >(parent); + + if (!retaction) { + // Troubles... + kWarning() << "failed to load" << offer->desktopEntryName(); + continue; + } + + // Is the action available and supported? + if (!retaction->isSupported()) { + // Skip that + retaction->deleteLater(); + continue; + } + + // Insert + m_actionPool.insert(actionId, retaction); + } + + // Load bundled actions now + m_actionPool.insert("SuspendSession", new BundledActions::SuspendSession(parent)); + m_actionPool.insert("BrightnessControl", new BundledActions::BrightnessControl(parent)); + m_actionPool.insert("KeyboardBrightnessControl", new BundledActions::KeyboardBrightnessControl(parent)); + m_actionPool.insert("DimDisplay", new BundledActions::DimDisplay(parent)); + m_actionPool.insert("RunScript", new BundledActions::RunScript(parent)); + m_actionPool.insert("HandleButtonEvents", new BundledActions::HandleButtonEvents(parent)); + + // Verify support + QHash::iterator i = m_actionPool.begin(); + while (i != m_actionPool.end()) { + Action *action = i.value(); + if (!action->isSupported()) { + i = m_actionPool.erase(i); + action->deleteLater(); + } else { + ++i; + } + } + + // Register DBus objects + { + KService::List offers = KServiceTypeTrader::self()->query("PowerDevil/Action", + "[X-KDE-PowerDevil-Action-RegistersDBusInterface] == TRUE"); + foreach (KService::Ptr offer, offers) { + QString actionId = offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String).toString(); + + if (m_actionPool.contains(actionId)) { + QDBusConnection::sessionBus().registerObject("/org/kde/Solid/PowerManagement/Actions/" + actionId, m_actionPool[actionId]); + } + } + } +} + +Action* ActionPool::loadAction(const QString& actionId, const KConfigGroup& group, PowerDevil::Core *parent) +{ + Q_UNUSED(parent); + // Let's retrieve the action + if (m_actionPool.contains(actionId)) { + Action *retaction = m_actionPool[actionId]; + + if (group.isValid()) { + + if (m_activeActions.contains(actionId)) { + // We are reloading the action: let's unload it first then. + retaction->onProfileUnload(); + retaction->unloadAction(); + m_activeActions.removeOne(actionId); + } + + retaction->loadAction(group); + m_activeActions.append(actionId); + } + + return retaction; + } else { + // Hmm... troubles in configuration. Np, let's just return 0 and let the core handle this + return 0; + } +} + +void ActionPool::unloadAllActiveActions() +{ + foreach (const QString &action, m_activeActions) { + m_actionPool[action]->onProfileUnload(); + m_actionPool[action]->unloadAction(); + } + m_activeActions.clear(); +} + +} diff --git a/powerdevil/daemon/powerdevilactionpool.h b/powerdevil/daemon/powerdevilactionpool.h new file mode 100644 index 00000000..ca436ffc --- /dev/null +++ b/powerdevil/daemon/powerdevilactionpool.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_POWERDEVILACTIONPOOL_H +#define POWERDEVIL_POWERDEVILACTIONPOOL_H + +#include +#include + +#include + +class KConfigGroup; +namespace PowerDevil +{ + +class Core; +class Action; + +class KDE_EXPORT ActionPool +{ +public: + static ActionPool *instance(); + + virtual ~ActionPool(); + + void init(PowerDevil::Core *parent); + + Action *loadAction(const QString &actionId, const KConfigGroup &group, PowerDevil::Core *parent); + + void unloadAllActiveActions(); + + void clearCache(); + +private: + ActionPool(); + + QHash< QString, Action* > m_actionPool; + QStringList m_activeActions; +}; + +} + +#endif // POWERDEVIL_POWERDEVILACTIONPOOL_H diff --git a/powerdevil/daemon/powerdevilbackendinterface.cpp b/powerdevil/daemon/powerdevilbackendinterface.cpp new file mode 100644 index 00000000..0634499e --- /dev/null +++ b/powerdevil/daemon/powerdevilbackendinterface.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevilbackendinterface.h" + +namespace PowerDevil +{ + +class BackendInterface::Private +{ +public: + Private() : batteryRemainingTime(0), isReady(false), isError(false), isLidClosed(false) {} + ~Private() {} + + AcAdapterState acAdapterState; + qulonglong batteryRemainingTime; + BatteryState batteryState; + QHash< BrightnessControlType, float > brightness; + BrightnessControlsList brightnessControlsAvailable; + Capabilities capabilities; + SuspendMethods suspendMethods; + QString errorString; + bool isReady; + bool isError; + bool isLidClosed; + QHash< QString, uint > capacities; + QList< RecallNotice > recallNotices; +}; + +BackendInterface::BackendInterface(QObject* parent) + : QObject(parent) + , d(new Private) +{ +} + +BackendInterface::~BackendInterface() +{ + delete d; +} + +BackendInterface::AcAdapterState BackendInterface::acAdapterState() const +{ + return d->acAdapterState; +} + +qulonglong BackendInterface::batteryRemainingTime() const +{ + return d->batteryRemainingTime; +} + +BackendInterface::BatteryState BackendInterface::batteryState() const +{ + return d->batteryState; +} + +float BackendInterface::brightness(BackendInterface::BrightnessControlType type) const +{ + return d->brightness[type]; +} + +BackendInterface::BrightnessControlsList BackendInterface::brightnessControlsAvailable() const +{ + return d->brightnessControlsAvailable; +} + +QHash< QString, uint > BackendInterface::capacities() const +{ + return d->capacities; +} + +QList< BackendInterface::RecallNotice > BackendInterface::recallNotices() const +{ + return d->recallNotices; +} + +BackendInterface::SuspendMethods BackendInterface::supportedSuspendMethods() const +{ + return d->suspendMethods; +} + +bool BackendInterface::isLidClosed() const +{ + return d->isLidClosed; +} + +void BackendInterface::setAcAdapterState(PowerDevil::BackendInterface::AcAdapterState state) +{ + d->acAdapterState = state; + emit acAdapterStateChanged(state); +} + +void BackendInterface::setBackendHasError(const QString& errorDetails) +{ + Q_UNUSED(errorDetails) +} + +void BackendInterface::setBackendIsReady(BrightnessControlsList availableBrightnessControls, + BackendInterface::SuspendMethods supportedSuspendMethods) +{ + d->brightnessControlsAvailable = availableBrightnessControls; + d->suspendMethods = supportedSuspendMethods; + d->isReady = true; + + emit backendReady(); +} + +void BackendInterface::setBatteryRemainingTime(qulonglong time) +{ + if (d->batteryRemainingTime != time) { + d->batteryRemainingTime = time; + emit batteryRemainingTimeChanged(time); + } +} + +void BackendInterface::setBatteryState(PowerDevil::BackendInterface::BatteryState state) +{ + d->batteryState = state; + emit batteryStateChanged(state); +} + +void BackendInterface::setButtonPressed(PowerDevil::BackendInterface::ButtonType type) +{ + if (type == LidClose) { + d->isLidClosed = true; + } else if (type == LidOpen) { + d->isLidClosed = false; + } + emit buttonPressed(type); +} + +void BackendInterface::setCapacityForBattery(const QString& batteryId, uint percent) +{ + d->capacities.insert(batteryId, percent); +} + +void BackendInterface::setRecallNotices(const QList< BackendInterface::RecallNotice >& notices) +{ + d->recallNotices = notices; +} + +void BackendInterface::onBrightnessChanged(BackendInterface::BrightnessControlType device, float brightness) +{ + d->brightness[device] = brightness; + emit brightnessChanged(brightness, device); +} + +void BackendInterface::setResumeFromSuspend() +{ + emit resumeFromSuspend(); +} + +BackendInterface::Capabilities BackendInterface::capabilities() const +{ + return d->capabilities; +} + +void BackendInterface::setCapabilities(BackendInterface::Capabilities capabilities) +{ + d->capabilities = capabilities; +} + +} + +#include "powerdevilbackendinterface.moc" diff --git a/powerdevil/daemon/powerdevilbackendinterface.h b/powerdevil/daemon/powerdevilbackendinterface.h new file mode 100644 index 00000000..911c25a4 --- /dev/null +++ b/powerdevil/daemon/powerdevilbackendinterface.h @@ -0,0 +1,327 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_BACKENDINTERFACE_H +#define POWERDEVIL_BACKENDINTERFACE_H + +#include +#include + +#include + +class KJob; + +namespace PowerDevil { + +class KDE_EXPORT BackendInterface : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(BackendInterface) + +public: + explicit BackendInterface(QObject* parent = 0); + virtual ~BackendInterface(); + + /** + * This enum type defines the different states of the system battery. + * + * - NoBatteryState: No battery available + * - Normal: The battery is at its normal charge level + * - Warning: The battery is at its warning charge level + * - Low: The battery is at its low charge level + * - Critical: The battery is at its critical charge level + */ + enum BatteryState{ NoBatteryState, Normal, Warning, Low, Critical }; + + /** + * This enum type defines the different states of the AC adapter. + * + * - UnknownAcAdapterState: The AC adapter has an unknown state + * - Plugged: The AC adapter is plugged + * - Unplugged: The AC adapter is unplugged + */ + enum AcAdapterState{ UnknownAcAdapterState, Plugged, Unplugged }; + + /** + * This enum type defines the types of system button events. + * + * - UnknownButtonType: An unknown button + * - PowerButton: A power button pressed event, generally used to turn on or off the system + * - SleepButton: A sleep button pressed event, generally used to make the system asleep + * - LidOpen: A laptop lid open event + * - LidClose: A laptop lid close event + */ + enum ButtonType{ UnknownButtonType, PowerButton, SleepButton, LidOpen, LidClose, HibernateButton }; + + /** + * This enum type defines the different suspend methods. + * + * - UnknownSuspendMethod: The name says it all + * - Standby: Processes are stopped, some hardware is deactivated (ACPI S1) + * - ToRam: Most devices are deactivated, only RAM is powered (ACPI S3) + * - ToDisk: State of the machine is saved to disk, and it's powered down (ACPI S4) + */ + enum SuspendMethod{ UnknownSuspendMethod = 0, Standby = 1, ToRam = 2, ToDisk = 4, HybridSuspend = 8 }; + + /** + * This type stores an OR combination of SuspendMethod values. + */ + Q_DECLARE_FLAGS(SuspendMethods, SuspendMethod) + + /** + * This enum defines the different types of brightness controls. + * + * - UnknownBrightnessControl: Unknown + * - Screen: Brightness control for a monitor or laptop panel + * - Keyboard: Brightness control for a keyboard backlight + */ + enum BrightnessControlType{ UnknownBrightnessControl = 0, Screen = 1, Keyboard = 2 }; + + typedef QHash BrightnessControlsList; + + /** + * This enum defines the different types brightness keys. + * + * - Increase: Key to increase brightness (Qt::Key_MonBrightnessUp or Qt::Key_KeyboardBrightnessUp) + * - Decrease: Key to decrease brightness (Qt::Key_MonBrightnessDown or Qt::Key_KeyboardBrightnessDown) + * - Toggle: Key to toggle backlight (Qt::Key_KeyboardBacklightOnOff) + */ + enum BrightnessKeyType{ Increase, Decrease, Toggle }; + + /** + * This enum defines capabilities of the backend + * + * - SignalResumeFromSuspend: The backend is able to stream the @c resumeFromSuspend signal accurately + */ + enum Capability { NoCapabilities = 0, SignalResumeFromSuspend = 1 }; + + Q_DECLARE_FLAGS(Capabilities, Capability) + + /** + * This struct contains information for a recall notice from the vendor + */ + struct RecallNotice { + /** The battery uuid */ + QString batteryId; + /** The vendor's name */ + QString vendor; + /** The vendor's website */ + QString url; + }; + + /** + * Initializes the backend. This function @b MUST be called before the backend is usable. Using + * any method in BackendInterface without initializing it might lead to undefined behavior. The signal + * @c backendReady or @c backendError will be streamed upon completion. + * + * @note Backend implementations @b MUST reimplement this function + */ + virtual void init() = 0; + + /** + * @returns the capabilities of the backend + * @see PowerDevil::BackendInterface::Capability + */ + Capabilities capabilities() const; + + /** + * Retrieves the current state of the system battery. + * + * @return the current battery state + * @see PowerDevil::BackendInterface::BatteryState + */ + BatteryState batteryState() const; + + /** + * Retrieves the current estimated remaining time of the system batteries + * + * @return the current global estimated remaining time in milliseconds + */ + qulonglong batteryRemainingTime() const; + + /** + * Retrieves the current state of the system AC adapter. + * + * @return the current AC adapter state + * @see PowerDevil::BackendInterface::AcAdapterState + */ + AcAdapterState acAdapterState() const; + + + /** + * Retrieves the set of suspend methods supported by the system. + * + * @return the suspend methods supported by this system + * @see PowerDevil::BackendInterface::SuspendMethod + * @see PowerDevil::BackendInterface::SuspendMethods + */ + SuspendMethods supportedSuspendMethods() const; + + /** + * Requests a suspend of the system. + * + * @param method the suspend method to use + * @return the job handling the operation + */ + virtual KJob *suspend(SuspendMethod method) = 0; + + /** + * Checks if brightness controls are enabled on this system. + * + * @return a list of the devices available to control + */ + BrightnessControlsList brightnessControlsAvailable() const; + + /** + * Gets the screen brightness. + * + * @param device the name of the device that you would like to control + * @return the brightness of the device, as a percentage + */ + virtual float brightness(BrightnessControlType type = Screen) const; + + /** + * @returns whether the lid is closed or not. + */ + bool isLidClosed() const; + + /** + * Sets the screen brightness. + * + * @param brightness the desired screen brightness, as a percentage + * @param device the name of the device that you would like to control + * @return true if the brightness change succeeded, false otherwise + */ + virtual bool setBrightness(float brightness, BrightnessControlType type = Screen) = 0; + + /** + * Should be called when the user presses a brightness key. + * + * @param type the type of the brightness key press + * @see PowerDevil::BackendInterface::BrightnessKeyType + */ + virtual void brightnessKeyPressed(BrightnessKeyType type, BrightnessControlType controlType = Screen) = 0; + + /** + * Retrieves the capacities of the installed batteries in percentage. + * + * @returns A dictionary with the battery's capacity percentage mapped to the battery uuid. + */ + QHash< QString, uint > capacities() const; + + /** + * Returns a list of recall notices, if available + * + * @return a list of recall notices + * @see PowerDevil::BackendInterface::RecallNotice + */ + QList< RecallNotice > recallNotices() const; + +Q_SIGNALS: + /** + * This signal is emitted when the AC adapter is plugged or unplugged. + * + * @param newState the new state of the AC adapter, it's one of the + * type @see PowerDevil::BackendInterface::AcAdapterState + */ + void acAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState newState); + + /** + * This signal is emitted when the system battery state changed. + * + * @param newState the new state of the system battery, it's one of the + * type @see PowerDevil::BackendInterface::BatteryState + */ + void batteryStateChanged(PowerDevil::BackendInterface::BatteryState newState); + + /** + * This signal is emitted when a button has been pressed. + * + * @param buttonType the pressed button type, it's one of the + * type @see PowerDevil::BackendInterface::ButtonType + */ + void buttonPressed(PowerDevil::BackendInterface::ButtonType buttonType); + + /** + * This signal is emitted when the brightness changes. + * + * @param brightness the new brightness level + */ + void brightnessChanged(float brightness, PowerDevil::BackendInterface::BrightnessControlType type); + + /** + * This signal is emitted when the estimated battery remaining time changes. + * + * @param time the new remaining time + */ + void batteryRemainingTimeChanged(qulonglong time); + + /** + * This signal is emitted when the backend is ready to be used + * + * @see init + */ + void backendReady(); + + /** + * This signal is emitted if the backend could not be initialized + * + * @param error Details about the error occurred + * @see init + */ + void backendError(const QString &error); + + /** + * This signal is emitted when the PC is resuming from suspension + */ + void resumeFromSuspend(); + +protected: + void setCapabilities(Capabilities capabilities); + + void onBrightnessChanged(BrightnessControlType device, float brightness); + void setBatteryRemainingTime(qulonglong time); + void setButtonPressed(PowerDevil::BackendInterface::ButtonType type); + void setBatteryState(PowerDevil::BackendInterface::BatteryState state); + void setAcAdapterState(PowerDevil::BackendInterface::AcAdapterState state); + + void setCapacityForBattery(const QString &batteryId, uint percent); + void setRecallNotices(const QList< RecallNotice > ¬ices); + + void setBackendIsReady(BrightnessControlsList availableBrightnessControls, SuspendMethods supportedSuspendMethods); + void setBackendHasError(const QString &errorDetails); + +protected slots: + // This function is actually here due to HAL + void setResumeFromSuspend(); + +private: + class Private; + Private * const d; + + friend class Core; +}; + +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(PowerDevil::BackendInterface::Capabilities) +Q_DECLARE_OPERATORS_FOR_FLAGS(PowerDevil::BackendInterface::SuspendMethods) + +#endif // POWERDEVIL_BACKENDINTERFACE_H diff --git a/powerdevil/daemon/powerdevilbackendloader.cpp b/powerdevil/daemon/powerdevilbackendloader.cpp new file mode 100644 index 00000000..8259a136 --- /dev/null +++ b/powerdevil/daemon/powerdevilbackendloader.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include +#include "powerdevilbackendloader.h" + +#ifdef HAVE_UDEV +#include "backends/upower/powerdevilupowerbackend.h" +#endif +#include "backends/hal/powerdevilhalbackend.h" + +#include + +namespace PowerDevil { +namespace BackendLoader { + +BackendInterface* loadBackend(QObject *parent) +{ +#ifdef HAVE_UDEV + // Check UPower first + kDebug() << "Loading UPower backend..."; + if (PowerDevilUPowerBackend::isAvailable()) { + kDebug() << "Success!"; + return new PowerDevilUPowerBackend(parent); + } + + kDebug() << "Failed!"; +#endif + + // If we are here, try HAL + kDebug() << "Loading HAL backend..."; + if (PowerDevilHALBackend::isAvailable()) { + kDebug() << "Success!"; + return new PowerDevilHALBackend(parent); + } + + // Fail... + kDebug() << "Failed!"; + return 0; +} + +} +} + diff --git a/powerdevil/daemon/powerdevilbackendloader.h b/powerdevil/daemon/powerdevilbackendloader.h new file mode 100644 index 00000000..5cd60be5 --- /dev/null +++ b/powerdevil/daemon/powerdevilbackendloader.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef POWERDEVIL_BACKENDLOADER_H +#define POWERDEVIL_BACKENDLOADER_H + +class QObject; +namespace PowerDevil { + +class BackendInterface; + + +namespace BackendLoader +{ + BackendInterface *loadBackend(QObject *parent); +} + +} + +#endif // POWERDEVIL_POWERDEVILBACKENDLOADER_H diff --git a/powerdevil/daemon/powerdevilcore.cpp b/powerdevil/daemon/powerdevilcore.cpp new file mode 100644 index 00000000..d096d748 --- /dev/null +++ b/powerdevil/daemon/powerdevilcore.cpp @@ -0,0 +1,730 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevilcore.h" + +#include "PowerDevilSettings.h" +#include "screensaver_interface.h" + +#include "powerdevilaction.h" +#include "powerdevilactionpool.h" +#include "powerdevilbackendinterface.h" +#include "powerdevilpolicyagent.h" +#include "powerdevilprofilegenerator.h" + +#include "daemon/actions/bundled/suspendsession.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace PowerDevil +{ + +Core::Core(QObject* parent, const KComponentData &componentData) + : QObject(parent) + , m_backend(0) + , m_applicationData(componentData) + , m_criticalBatteryTimer(new QTimer(this)) + , m_activityConsumer(new KActivities::Consumer(this)) + , m_pendingWakeupEvent(true) +{ +} + +Core::~Core() +{ + // Unload all actions before exiting, and clear the cache + ActionPool::instance()->unloadAllActiveActions(); + ActionPool::instance()->clearCache(); +} + +void Core::loadCore(BackendInterface* backend) +{ + if (!backend) { + onBackendError(i18n("No valid Power Management backend plugins are available. " + "A new installation might solve this problem.")); + return; + } + + m_backend = backend; + + // Async backend init - so that KDED gets a bit of a speed up + kDebug() << "Core loaded, initializing backend"; + connect(m_backend, SIGNAL(backendReady()), this, SLOT(onBackendReady())); + connect(m_backend, SIGNAL(backendError(QString)), this, SLOT(onBackendError(QString))); + m_backend->init(); + + // Register DBus Metatypes + qDBusRegisterMetaType< StringStringMap >(); +} + +void Core::onBackendReady() +{ + kDebug() << "Backend is ready, KDE Power Management system initialized"; + + m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::CascadeConfig); + + // Is it brand new? + if (m_profilesConfig->groupList().isEmpty()) { + // Generate defaults + bool toRam = m_backend->supportedSuspendMethods() & PowerDevil::BackendInterface::ToRam; + bool toDisk = m_backend->supportedSuspendMethods() & PowerDevil::BackendInterface::ToDisk; + if (ProfileGenerator::generateProfiles(toRam, toDisk, true) == ProfileGenerator::ResultUpgraded) { + // Notify the user + emitNotification("warningnot", i18n("Your Power Profiles have been updated to be used with the new KDE Power " + "Management System. You can tweak them or generate a new set of defaults from " + "System Settings."), "system-software-update"); + } + m_profilesConfig->reparseConfiguration(); + } + + // Get the battery devices ready + { + using namespace Solid; + connect(DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), + this, SLOT(onDeviceAdded(QString))); + connect(DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), + this, SLOT(onDeviceRemoved(QString))); + + // Force the addition of already existent batteries + foreach (const Device &device, Device::listFromType(DeviceInterface::Battery, QString())) { + onDeviceAdded(device.udi()); + } + } + + connect(m_backend, SIGNAL(acAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState)), + this, SLOT(onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState))); + connect(m_backend, SIGNAL(batteryRemainingTimeChanged(qulonglong)), + this, SLOT(onBatteryRemainingTimeChanged(qulonglong))); + connect(KIdleTime::instance(), SIGNAL(timeoutReached(int,int)), + this, SLOT(onKIdleTimeoutReached(int,int))); + connect(KIdleTime::instance(), SIGNAL(resumingFromIdle()), + this, SLOT(onResumingFromIdle())); + connect(m_activityConsumer, SIGNAL(currentActivityChanged(QString)), + this, SLOT(loadProfile())); + + // Set up the policy agent + PowerDevil::PolicyAgent::instance()->init(); + + // Initialize the action pool, which will also load the needed startup actions. + PowerDevil::ActionPool::instance()->init(this); + + // Set up the critical battery timer + m_criticalBatteryTimer->setSingleShot(true); + m_criticalBatteryTimer->setInterval(30000); + connect(m_criticalBatteryTimer, SIGNAL(timeout()), this, SLOT(onCriticalBatteryTimerExpired())); + + // In 30 seconds (so we are sure the user sees eventual notifications), check the battery state + QTimer::singleShot(30000, this, SLOT(checkBatteryStatus())); + + // All systems up Houston, let's go! + emit coreReady(); + refreshStatus(); +} + +bool Core::isActionSupported(const QString& actionName) +{ + Action *action = ActionPool::instance()->loadAction(actionName, KConfigGroup(), this); + if (!action) { + return false; + } else { + return action->isSupported(); + } +} + +QString Core::checkBatteryStatus(bool notify) +{ + QString lastMessage; + // Any batteries below 50% of capacity? + for (QHash< QString, uint >::const_iterator i = m_backend->capacities().constBegin(); + i != m_backend->capacities().constEnd(); ++i) { + if (i.value() < 50) { + // Notify, we have a broken battery. + if (m_loadedBatteriesUdi.size() == 1) { + lastMessage = i18n("Your battery capacity is %1%. This means your battery is broken and " + "needs a replacement. Please contact your hardware vendor for more details.", + i.value()); + } else { + lastMessage = i18n("One of your batteries (ID %2) has a capacity of %1%. This means it is broken " + "and needs a replacement. Please contact your hardware vendor for more details.", + i.value(), i.key()); + } + if (notify) { + emitRichNotification("brokenbattery", i18n("Broken Battery"), lastMessage); + } + } + } + + // Any recalled batteries? + foreach (const BackendInterface::RecallNotice ¬ice, m_backend->recallNotices()) { + // Notify, a battery has been recalled + if (m_loadedBatteriesUdi.size() == 1) { + lastMessage = i18n("Your battery might have been recalled by %1. Usually, when vendors recall the " + "hardware, it is because of factory defects which are usually eligible for a " + "free repair or substitution. Please check %1's website to " + "verify if your battery is faulted.", notice.vendor, notice.url); + } else { + lastMessage = i18n("One of your batteries (ID %3) might have been recalled by %1. " + "Usually, when vendors recall the hardware, it is because of factory defects " + "which are usually eligible for a free repair or substitution. " + "Please check %1's website to " + "verify if your battery is faulted.", notice.vendor, notice.url, notice.batteryId); + } + if (notify) { + emitRichNotification("brokenbattery", i18n("Check Your Battery"), lastMessage); + } + } + + return lastMessage; +} + +void Core::refreshStatus() +{ + /* The configuration could have changed if this function was called, so + * let's resync it. + */ + reparseConfiguration(); + + loadProfile(true); +} + +void Core::reparseConfiguration() +{ + PowerDevilSettings::self()->readConfig(); + m_profilesConfig->reparseConfiguration(); + + // Config reloaded + emit configurationReloaded(); +} + +void Core::loadProfile(bool force) +{ + QString profileId; + + // Policy check + if (PolicyAgent::instance()->requirePolicyCheck(PolicyAgent::ChangeProfile) != PolicyAgent::None) { + kDebug() << "Policy Agent prevention: on"; + return; + } + + KConfigGroup config; + + // Check the activity in which we are in + QString activity = m_activityConsumer->currentActivity(); + if (activity.isEmpty()) { + activity = "default"; + } + kDebug() << "We are now into activity " << activity; + KConfigGroup activitiesConfig(m_profilesConfig, "Activities"); + kDebug() << activitiesConfig.groupList() << activitiesConfig.keyList(); + + // Are we mirroring an activity? + if (activitiesConfig.group(activity).readEntry("mode", "None") == "ActLike" && + activitiesConfig.group(activity).readEntry("actLike", QString()) != "AC" && + activitiesConfig.group(activity).readEntry("actLike", QString()) != "Battery" && + activitiesConfig.group(activity).readEntry("actLike", QString()) != "LowBattery") { + // Yes, let's use that then + activity = activitiesConfig.group(activity).readEntry("actLike", QString()); + kDebug() << "Activity is a mirror"; + } + + KConfigGroup activityConfig = activitiesConfig.group(activity); + kDebug() << activityConfig.groupList() << activityConfig.keyList(); + + // See if this activity has priority + if (activityConfig.readEntry("mode", "None") == "SeparateSettings") { + // Prioritize this profile over anything + config = activityConfig.group("SeparateSettings"); + kDebug() << "Activity is enforcing a different profile"; + profileId = activity; + } else if (activityConfig.readEntry("mode", "None") == "ActLike") { + if (activityConfig.readEntry("actLike", QString()) == "AC" || + activityConfig.readEntry("actLike", QString()) == "Battery" || + activityConfig.readEntry("actLike", QString()) == "LowBattery") { + // Same as above, but with an existing profile + config = m_profilesConfig.data()->group(activityConfig.readEntry("actLike", QString())); + profileId = activityConfig.readEntry("actLike", QString()); + kDebug() << "Activity is mirroring a different profile"; + } + } else { + // It doesn't, let's load the current state's profile + if (m_loadedBatteriesUdi.isEmpty()) { + kDebug() << "No batteries found, loading AC"; + profileId = "AC"; + } else { + // Compute the previous and current global percentage + int percent = 0; + for (QHash::const_iterator i = m_batteriesPercent.constBegin(); + i != m_batteriesPercent.constEnd(); ++i) { + percent += i.value(); + } + + if (backend()->acAdapterState() == BackendInterface::Plugged) { + profileId = "AC"; + kDebug() << "Loading profile for plugged AC"; + } else if (percent <= PowerDevilSettings::batteryLowLevel()) { + profileId = "LowBattery"; + kDebug() << "Loading profile for low battery"; + } else { + profileId = "Battery"; + kDebug() << "Loading profile for unplugged AC"; + } + } + + config = m_profilesConfig.data()->group(profileId); + kDebug() << "Activity is not forcing a profile"; + } + + // Release any special inhibitions + { + QHash::iterator i = m_sessionActivityInhibit.begin(); + while (i != m_sessionActivityInhibit.end()) { + PolicyAgent::instance()->ReleaseInhibition(i.value()); + i = m_sessionActivityInhibit.erase(i); + } + + i = m_screenActivityInhibit.begin(); + while (i != m_screenActivityInhibit.end()) { + PolicyAgent::instance()->ReleaseInhibition(i.value()); + i = m_screenActivityInhibit.erase(i); + } + } + + if (!config.isValid()) { + emitNotification("powerdevilerror", i18n("The profile \"%1\" has been selected, " + "but it does not exist.\nPlease check your PowerDevil configuration.", + profileId)); + return; + } + + // Check: do we need to change profile at all? + if (m_currentProfile == profileId && !force) { + // No, let's leave things as they are + kDebug() << "Skipping action reload routine as profile has not changed"; + + // Do we need to force a wakeup? + if (m_pendingWakeupEvent) { + // Fake activity at this stage, when no timeouts are registered + onResumingFromIdle(); + KIdleTime::instance()->simulateUserActivity(); + m_pendingWakeupEvent = false; + } + } else { + // First of all, let's clean the old actions. This will also call the onProfileUnload callback + ActionPool::instance()->unloadAllActiveActions(); + + // Do we need to force a wakeup? + if (m_pendingWakeupEvent) { + // Fake activity at this stage, when no timeouts are registered + onResumingFromIdle(); + KIdleTime::instance()->simulateUserActivity(); + m_pendingWakeupEvent = false; + } + + // Cool, now let's load the needed actions + foreach (const QString &actionName, config.groupList()) { + Action *action = ActionPool::instance()->loadAction(actionName, config.group(actionName), this); + if (action) { + action->onProfileLoad(); + } else { + // Ouch, error. But let's just warn and move on anyway + //TODO Maybe Remove from the configuration if unsupported + kWarning() << "The profile " << profileId << "tried to activate" + << actionName << "a non existent action. This is usually due to an installation problem" + " or to a configuration problem. or simlpy the action is not supported"; + } + } + + // We are now on a different profile + m_currentProfile = profileId; + emit profileChanged(m_currentProfile); + } + + // Now... any special behaviors we'd like to consider? + if (activityConfig.readEntry("mode", "None") == "SpecialBehavior") { + kDebug() << "Activity has special behaviors"; + KConfigGroup behaviorGroup = activityConfig.group("SpecialBehavior"); + if (behaviorGroup.readEntry("performAction", false)) { + // Let's override the configuration for this action at all times + ActionPool::instance()->loadAction("SuspendSession", behaviorGroup.group("ActionConfig"), this); + kDebug() << "Activity overrides suspend session action"; + } + + if (behaviorGroup.readEntry("noSuspend", false)) { + kDebug() << "Activity triggers a suspend inhibition"; + // Trigger a special inhibition - if we don't have one yet + if (!m_sessionActivityInhibit.contains(activity)) { + int cookie = + PolicyAgent::instance()->AddInhibition(PolicyAgent::InterruptSession, i18n("Activity Manager"), + i18n("This activity's policies prevent the system from suspending")); + + m_sessionActivityInhibit.insert(activity, cookie); + } + } + + if (behaviorGroup.readEntry("noScreenManagement", false)) { + kDebug() << "Activity triggers a screen management inhibition"; + // Trigger a special inhibition - if we don't have one yet + if (!m_screenActivityInhibit.contains(activity)) { + int cookie = + PolicyAgent::instance()->AddInhibition(PolicyAgent::ChangeScreenSettings, i18n("Activity Manager"), + i18n("This activity's policies prevent screen power management")); + + m_screenActivityInhibit.insert(activity, cookie); + } + } + } + + // If the lid is closed, retrigger the lid close signal + if (m_backend->isLidClosed()) { + emit m_backend->buttonPressed(PowerDevil::BackendInterface::LidClose); + } +} + +void Core::onDeviceAdded(const QString& udi) +{ + if (m_loadedBatteriesUdi.contains(udi)) { + // We already know about this device + return; + } + + using namespace Solid; + Device device(udi); + Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); + + if (!b) { + // Not interesting to us + return; + } + + if (b->type() != Solid::Battery::PrimaryBattery && b->type() != Solid::Battery::UpsBattery) { + // Not interesting to us + return; + } + + if (!b->isPowerSupply()) { + // TODO: At some later point it would be really nice to handle those batteries too + // eg, show "your mouse is running low", but in the mean time, we don't care about those + return; + } + + if (!connect(b, SIGNAL(chargePercentChanged(int,QString)), + this, SLOT(onBatteryChargePercentChanged(int,QString))) || + !connect(b, SIGNAL(chargeStateChanged(int,QString)), + this, SLOT(onBatteryChargeStateChanged(int,QString)))) { + emitNotification("powerdevilerror", i18n("Could not connect to battery interface.\n" + "Please check your system configuration")); + } + + kDebug() << "A new battery was detected"; + + m_batteriesPercent[udi] = b->chargePercent(); + if (b->chargeState() == Solid::Battery::NoCharge) { + m_batteriesCharged[udi] = true; + } else { + m_batteriesCharged[udi] = false; + } + m_loadedBatteriesUdi.append(udi); + + // Compute the current global percentage + int globalChargePercent = 0; + for (QHash::const_iterator i = m_batteriesPercent.constBegin(); i != m_batteriesPercent.constEnd(); ++i) { + globalChargePercent += i.value(); + } + + // If a new battery has been added, let's clear some pending suspend actions if the new global batteries percentage is + // higher than the battery low level. (See bug 329537) + if (m_criticalBatteryTimer->isActive() && globalChargePercent > PowerDevilSettings::batteryCriticalLevel()) { + m_criticalBatteryTimer->stop(); + } + + // So we get a "Battery is low" notification directly on system startup if applicable + emitBatteryChargePercentNotification(globalChargePercent, 100); +} + +void Core::onDeviceRemoved(const QString& udi) +{ + if (!m_loadedBatteriesUdi.contains(udi)) { + // We don't know about this device + return; + } + + using namespace Solid; + Device device(udi); + Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); + + disconnect(b, SIGNAL(chargePercentChanged(int,QString)), + this, SLOT(onBatteryChargePercentChanged(int,QString))); + disconnect(b, SIGNAL(chargeStateChanged(int,QString)), + this, SLOT(onBatteryChargeStateChanged(int,QString))); + + kDebug() << "An existing battery has been removed"; + + m_batteriesPercent.remove(udi); + m_batteriesCharged.remove(udi); + m_loadedBatteriesUdi.removeOne(udi); +} + +void Core::emitNotification(const QString &evid, const QString &message, const QString &iconname) +{ + if (!iconname.isEmpty()) { + KNotification::event(evid, message, KIcon(iconname).pixmap(48,48), + 0, KNotification::CloseOnTimeout, m_applicationData); + } else { + KNotification::event(evid, message, QPixmap(), + 0, KNotification::CloseOnTimeout, m_applicationData); + } +} + +void Core::emitRichNotification(const QString &evid, const QString &title, const QString &message) +{ + KNotification::event(evid, title, message, QPixmap(), + 0, KNotification::CloseOnTimeout, m_applicationData); +} + +bool Core::emitBatteryChargePercentNotification(int currentPercent, int previousPercent) +{ + if (m_backend->acAdapterState() == BackendInterface::Plugged) { + return false; + } + + if (currentPercent <= PowerDevilSettings::batteryCriticalLevel() && + previousPercent > PowerDevilSettings::batteryCriticalLevel()) { + switch (PowerDevilSettings::batteryCriticalAction()) { + case PowerDevil::BundledActions::SuspendSession::ShutdownMode: + emitRichNotification("criticalbattery", i18n("Battery Critical (%1% Remaining)", currentPercent), + i18n("Your battery level is critical, the computer will be halted in 30 seconds.")); + m_criticalBatteryTimer->start(); + break; + case PowerDevil::BundledActions::SuspendSession::ToDiskMode: + emitRichNotification("criticalbattery", i18n("Battery Critical (%1% Remaining)", currentPercent), + i18n("Your battery level is critical, the computer will be hibernated in 30 seconds.")); + m_criticalBatteryTimer->start(); + break; + case PowerDevil::BundledActions::SuspendSession::ToRamMode: + emitRichNotification("criticalbattery", i18n("Battery Critical (%1% Remaining)", currentPercent), + i18n("Your battery level is critical, the computer will be suspended in 30 seconds.")); + m_criticalBatteryTimer->start(); + break; + default: + emitRichNotification("criticalbattery", i18n("Battery Critical (%1% Remaining)", currentPercent), + i18n("Your battery level is critical, save your work as soon as possible.")); + break; + } + return true; + } else if (currentPercent <= PowerDevilSettings::batteryLowLevel() && + previousPercent > PowerDevilSettings::batteryLowLevel()) { + emitRichNotification("lowbattery", i18n("Battery Low (%1% Remaining)", currentPercent), + i18n("Your battery is low. If you need to continue using your computer, either plug in your computer, or shut it down and then change the battery.")); + return true; + } + return false; +} + + +void Core::onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState state) +{ + kDebug(); + // Post request for faking an activity event - usually adapters don't plug themselves out :) + m_pendingWakeupEvent = true; + loadProfile(); + + if (state == BackendInterface::Plugged) { + // If the AC Adaptor has been plugged in, let's clear some pending suspend actions + if (m_criticalBatteryTimer->isActive()) { + m_criticalBatteryTimer->stop(); + emitRichNotification("criticalbattery", + i18n("AC Adapter Plugged In"), + i18n("All pending suspend actions have been canceled.")); + } else { + emitRichNotification("pluggedin", i18n("Running on AC power"), i18n("The power adaptor has been plugged in.")); + } + } else if (state == BackendInterface::Unplugged) { + emitRichNotification("unplugged", i18n("Running on Battery Power"), i18n("The power adaptor has been unplugged.")); + } +} + +void Core::onBackendError(const QString& error) +{ + emitNotification("powerdevilerror", i18n("KDE Power Management System could not be initialized. " + "The backend reported the following error: %1\n" + "Please check your system configuration", error)); +} + +void Core::onBatteryChargePercentChanged(int percent, const QString &udi) +{ + // Compute the previous and current global percentage + int previousPercent = 0; + for (QHash::const_iterator i = m_batteriesPercent.constBegin(); i != m_batteriesPercent.constEnd(); ++i) { + previousPercent += i.value(); + } + int currentPercent = previousPercent - (m_batteriesPercent[udi] - percent); + + // Update the battery percentage + m_batteriesPercent[udi] = percent; + + if (currentPercent < previousPercent) { + if (emitBatteryChargePercentNotification(currentPercent, previousPercent)) { + // Only refresh status if a notification has actually been emitted + refreshStatus(); + } + } +} + +void Core::onBatteryChargeStateChanged(int state, const QString &udi) +{ + bool previousCharged = true; + for (QHash::const_iterator i = m_batteriesCharged.constBegin(); i != m_batteriesCharged.constEnd(); ++i) { + if (!i.value()) { + previousCharged = false; + break; + } + } + + m_batteriesCharged[udi] = (state == Solid::Battery::NoCharge); + + if (m_backend->acAdapterState() != BackendInterface::Plugged) { + return; + } + + bool currentCharged = true; + for (QHash::const_iterator i = m_batteriesCharged.constBegin(); i != m_batteriesCharged.constEnd(); ++i) { + if (!i.value()) { + currentCharged = false; + break; + } + } + + if (!previousCharged && currentCharged) { + emitRichNotification("fullbattery", i18n("Charge Complete"), i18n("Your battery is now fully charged.")); + refreshStatus(); + } +} + +void Core::onCriticalBatteryTimerExpired() +{ + // Do that only if we're not on AC + if (m_backend->acAdapterState() == BackendInterface::Unplugged) { + // We consider this as a very special button + PowerDevil::Action *helperAction = ActionPool::instance()->loadAction("HandleButtonEvents", KConfigGroup(), this); + if (helperAction) { + QVariantMap args; + args["Button"] = 32; + args["Type"] = QVariant::fromValue(PowerDevilSettings::batteryCriticalAction()); + helperAction->trigger(args); + } + } +} + +void Core::onBatteryRemainingTimeChanged(qulonglong time) +{ + emit batteryRemainingTimeChanged(time); +} + +void Core::onKIdleTimeoutReached(int identifier, int msec) +{ + // Find which action(s) requested this idle timeout + for (QHash< Action*, QList< int > >::const_iterator i = m_registeredActionTimeouts.constBegin(); + i != m_registeredActionTimeouts.constEnd(); ++i) { + if (i.value().contains(identifier)) { + i.key()->onIdleTimeout(msec); + // And it will need to be awaken + if (!m_pendingResumeFromIdleActions.contains(i.key())) { + m_pendingResumeFromIdleActions.append(i.key()); + } + break; + } + } + + // Catch the next resume event if some actions require it + if (!m_pendingResumeFromIdleActions.isEmpty()) { + KIdleTime::instance()->catchNextResumeEvent(); + } +} + +void Core::registerActionTimeout(Action* action, int timeout) +{ + // Register the timeout with KIdleTime + int identifier = KIdleTime::instance()->addIdleTimeout(timeout); + + // Add the identifier to the action hash + QList< int > timeouts = m_registeredActionTimeouts[action]; + timeouts.append(identifier); + m_registeredActionTimeouts[action] = timeouts; +} + +void Core::unregisterActionTimeouts(Action* action) +{ + // Clear all timeouts from the action + QList< int > timeoutsToClean = m_registeredActionTimeouts[action]; + + foreach (int id, timeoutsToClean) { + KIdleTime::instance()->removeIdleTimeout(id); + } + + m_registeredActionTimeouts.remove(action); +} + +void Core::onResumingFromIdle() +{ + // Wake up the actions in which an idle action was triggered + QList< Action* >::iterator i = m_pendingResumeFromIdleActions.begin(); + while (i != m_pendingResumeFromIdleActions.end()) { + (*i)->onWakeupFromIdle(); + i = m_pendingResumeFromIdleActions.erase(i); + } +} + +BackendInterface* Core::backend() +{ + return m_backend; +} + +bool Core::isLidClosed() +{ + return m_backend->isLidClosed(); +} + +qulonglong Core::batteryRemainingTime() const +{ + return m_backend->batteryRemainingTime(); +} + +uint Core::backendCapabilities() +{ + return m_backend->capabilities(); +} + +} + +#include "powerdevilcore.moc" diff --git a/powerdevil/daemon/powerdevilcore.h b/powerdevil/daemon/powerdevilcore.h new file mode 100644 index 00000000..7312053e --- /dev/null +++ b/powerdevil/daemon/powerdevilcore.h @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVILCORE_H +#define POWERDEVILCORE_H + +#include "powerdevilbackendinterface.h" + +#include +#include + +#include + +namespace KActivities +{ + class Consumer; +} // namespace KActivities +typedef QMap< QString, QString > StringStringMap; + +class KDirWatch; +class QTimer; +class KNotification; +namespace Solid { +class Battery; +} + +namespace PowerDevil +{ + +class BackendInterface; +class Action; + +class KDE_EXPORT Core : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Core) + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement") + +public: + explicit Core(QObject* parent, const KComponentData &componentData); + virtual ~Core(); + + void reloadProfile(int state); + + void emitNotification(const QString &evid, const QString &message = QString(), + const QString &iconname = QString()); + void emitRichNotification(const QString &evid, const QString &title, const QString &message = QString()); + bool emitBatteryChargePercentNotification(int currentPercent, int previousPercent); + + BackendInterface *backend(); + + // More... + +public Q_SLOTS: + void loadCore(PowerDevil::BackendInterface *backend); + // Set of common action - useful for the DBus interface + uint backendCapabilities(); + void refreshStatus(); + void reparseConfiguration(); + + QString checkBatteryStatus(bool notify = true); + + void loadProfile(bool force = false); + + qulonglong batteryRemainingTime() const; + + bool isLidClosed(); + bool isActionSupported(const QString &actionName); + +Q_SIGNALS: + void coreReady(); + void profileChanged(const QString &newProfile); + void configurationReloaded(); + void batteryRemainingTimeChanged(qulonglong time); + +private: + void registerActionTimeout(Action *action, int timeout); + void unregisterActionTimeouts(Action *action); + + friend class Action; + + BackendInterface *m_backend; + QStringList m_loadedBatteriesUdi; + + QWeakPointer< KNotification > notification; + KComponentData m_applicationData; + KSharedConfigPtr m_profilesConfig; + + QString m_currentProfile; + + QHash< QString, int > m_batteriesPercent; + QHash< QString, bool > m_batteriesCharged; + + QTimer *m_criticalBatteryTimer; + + KActivities::Consumer *m_activityConsumer; + + // Idle time management + QHash< Action*, QList< int > > m_registeredActionTimeouts; + QList< Action* > m_pendingResumeFromIdleActions; + bool m_pendingWakeupEvent; + + // Activity inhibition management + QHash< QString, int > m_sessionActivityInhibit; + QHash< QString, int > m_screenActivityInhibit; + +private Q_SLOTS: + void onBackendReady(); + void onBackendError(const QString &error); + void onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState); + void onBatteryChargePercentChanged(int,const QString&); + void onBatteryChargeStateChanged(int,const QString&); + void onBatteryRemainingTimeChanged(qulonglong); + void onKIdleTimeoutReached(int,int); + void onResumingFromIdle(); + void onDeviceAdded(const QString &udi); + void onDeviceRemoved(const QString &udi); + void onCriticalBatteryTimerExpired(); +}; + +} + +Q_DECLARE_METATYPE(StringStringMap) + +#endif // POWERDEVILCORE_H diff --git a/powerdevil/daemon/powerdevilfdoconnector.cpp b/powerdevil/daemon/powerdevilfdoconnector.cpp new file mode 100644 index 00000000..3e5b3eec --- /dev/null +++ b/powerdevil/daemon/powerdevilfdoconnector.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright (C) 2008 by Kevin Ottens * + * Copyright (C) 2008-2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + **************************************************************************/ + +#include "powerdevilfdoconnector.h" + +#include "powerdevilaction.h" +#include "powerdevilactionpool.h" +#include "powerdevilcore.h" + +#include "powermanagementfdoadaptor.h" +#include "powermanagementinhibitadaptor.h" + +#include "daemon/actions/bundled/suspendsession.h" + +#include + +namespace PowerDevil { + +FdoConnector::FdoConnector(PowerDevil::Core *parent) + : QObject(parent), m_core(parent) +{ + new PowerManagementFdoAdaptor(this); + new PowerManagementInhibitAdaptor(this); + + QDBusConnection c = QDBusConnection::sessionBus(); + + c.registerService("org.freedesktop.PowerManagement"); + c.registerObject("/org/freedesktop/PowerManagement", this); + + c.registerService("org.freedesktop.PowerManagement.Inhibit"); + c.registerObject("/org/freedesktop/PowerManagement/Inhibit", this); + + connect(m_core->backend(), SIGNAL(acAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState)), + this, SLOT(onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState))); + connect(PolicyAgent::instance(), SIGNAL(unavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies)), + this, SLOT(onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies))); +} + +bool FdoConnector::CanHibernate() +{ + return m_core->backend()->supportedSuspendMethods() & PowerDevil::BackendInterface::ToDisk; +} + +bool FdoConnector::CanSuspend() +{ + return m_core->backend()->supportedSuspendMethods() & PowerDevil::BackendInterface::ToRam; +} + +bool FdoConnector::CanHybridSuspend() +{ + return m_core->backend()->supportedSuspendMethods() & PowerDevil::BackendInterface::HybridSuspend; +} + +bool FdoConnector::GetPowerSaveStatus() +{ + return m_core->backend()->acAdapterState() == PowerDevil::BackendInterface::Unplugged; +} + +void FdoConnector::Suspend() +{ + triggerSuspendSession(BundledActions::SuspendSession::ToRamMode); +} + +void FdoConnector::Hibernate() +{ + triggerSuspendSession(BundledActions::SuspendSession::ToDiskMode); +} + +void FdoConnector::HybridSuspend() +{ + triggerSuspendSession(BundledActions::SuspendSession::SuspendHybridMode); +} + +bool FdoConnector::HasInhibit() +{ + return PolicyAgent::instance()->requirePolicyCheck(PolicyAgent::InterruptSession) != PolicyAgent::None; +} + +int FdoConnector::Inhibit(const QString &application, const QString &reason) +{ + // Inhibit here means we cannot interrupt the session. + // If we've been called from DBus, use PolicyAgent's service watching system + if (calledFromDBus()) { + return PolicyAgent::instance()->addInhibitionWithExplicitDBusService((uint)PolicyAgent::InterruptSession, + application, reason, message().service()); + } else { + return PolicyAgent::instance()->AddInhibition((uint)PolicyAgent::InterruptSession, application, reason); + } +} + +void FdoConnector::UnInhibit(int cookie) +{ + PolicyAgent::instance()->ReleaseInhibition(cookie); +} + +void FdoConnector::ForceUnInhibitAll() +{ + PolicyAgent::instance()->releaseAllInhibitions(); +} + +void FdoConnector::onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState newstate) +{ + emit PowerSaveStatusChanged(newstate == PowerDevil::BackendInterface::Unplugged); +} + +void FdoConnector::onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies newpolicies) +{ + emit HasInhibitChanged(newpolicies & PowerDevil::PolicyAgent::InterruptSession); +} + +void FdoConnector::triggerSuspendSession(uint action) +{ + PowerDevil::Action *helperAction = ActionPool::instance()->loadAction("SuspendSession", KConfigGroup(), m_core); + if (helperAction) { + QVariantMap args; + args["Type"] = action; + args["Explicit"] = true; + helperAction->trigger(args); + } +} + +} + +#include "powerdevilfdoconnector.moc" diff --git a/powerdevil/daemon/powerdevilfdoconnector.h b/powerdevil/daemon/powerdevilfdoconnector.h new file mode 100644 index 00000000..5d981f14 --- /dev/null +++ b/powerdevil/daemon/powerdevilfdoconnector.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2008 by Kevin Ottens * + * Copyright (C) 2008-2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef POWERDEVILFDOCONNECTOR_H +#define POWERDEVILFDOCONNECTOR_H + +#include + +#include "powerdevilbackendinterface.h" +#include "powerdevilpolicyagent.h" + +namespace PowerDevil { +class Core; + +class FdoConnector : public QObject, protected QDBusContext +{ + Q_OBJECT + Q_DISABLE_COPY(FdoConnector) + + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.PowerManagement") + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.PowerManagement.Inhibit") + +public: + FdoConnector(PowerDevil::Core *parent); + + bool CanHibernate(); + bool CanSuspend(); + bool CanHybridSuspend(); + + bool GetPowerSaveStatus(); + + void Suspend(); + void Hibernate(); + void HybridSuspend(); + + bool HasInhibit(); + + int Inhibit(const QString &application, const QString &reason); + void UnInhibit(int cookie); + void ForceUnInhibitAll(); + +Q_SIGNALS: + void CanSuspendChanged(bool canSuspend); + void CanHibernateChanged(bool canHibernate); + void CanHybridSuspendChanged(bool canHybridSuspend); + void PowerSaveStatusChanged(bool savePower); + + void HasInhibitChanged(bool hasInhibit); + +private Q_SLOTS: + void onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState); + void onUnavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies); + void triggerSuspendSession(uint action); + +private: + PowerDevil::Core *m_core; +}; + +} + +#endif /*POWERDEVILFDOCONNECTOR_H*/ diff --git a/powerdevil/daemon/powerdevilpolicyagent.cpp b/powerdevil/daemon/powerdevilpolicyagent.cpp new file mode 100644 index 00000000..d217e924 --- /dev/null +++ b/powerdevil/daemon/powerdevilpolicyagent.cpp @@ -0,0 +1,579 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * Copyright (C) 2012 Lukáš Tinkl * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "powerdevilpolicyagent.h" +#include "screensaver_interface.h" + +struct NamedDBusObjectPath +{ + QString name; + QDBusObjectPath path; +}; + +// Marshall the NamedDBusObjectPath data into a D-Bus argument +QDBusArgument &operator<<(QDBusArgument &argument, const NamedDBusObjectPath &namedPath) +{ + argument.beginStructure(); + argument << namedPath.name << namedPath.path; + argument.endStructure(); + return argument; +} + +// Retrieve the NamedDBusObjectPath data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, NamedDBusObjectPath &namedPath) +{ + argument.beginStructure(); + argument >> namedPath.name >> namedPath.path; + argument.endStructure(); + return argument; +} + +Q_DECLARE_METATYPE(NamedDBusObjectPath) + +namespace PowerDevil +{ + +class PolicyAgentHelper +{ +public: + PolicyAgentHelper() : q(0) { } + ~PolicyAgentHelper() { + delete q; + } + PolicyAgent *q; +}; + +K_GLOBAL_STATIC(PolicyAgentHelper, s_globalPolicyAgent) + +PolicyAgent *PolicyAgent::instance() +{ + if (!s_globalPolicyAgent->q) { + new PolicyAgent; + } + + return s_globalPolicyAgent->q; +} + +PolicyAgent::PolicyAgent(QObject* parent) + : QObject(parent) + , m_sdAvailable(false) + , m_systemdInhibitFd(-1) + , m_ckAvailable(false) + , m_sessionIsBeingInterrupted(false) + , m_lastCookie(0) + , m_busWatcher(new QDBusServiceWatcher(this)) + , m_sdWatcher(new QDBusServiceWatcher(this)) + , m_ckWatcher(new QDBusServiceWatcher(this)) +{ + Q_ASSERT(!s_globalPolicyAgent->q); + s_globalPolicyAgent->q = this; +} + +PolicyAgent::~PolicyAgent() +{ +} + +void PolicyAgent::init() +{ + // Watch over the systemd service + m_sdWatcher.data()->setConnection(QDBusConnection::systemBus()); + m_sdWatcher.data()->setWatchMode(QDBusServiceWatcher::WatchForUnregistration | + QDBusServiceWatcher::WatchForRegistration); + m_sdWatcher.data()->addWatchedService(SYSTEMD_LOGIN1_SERVICE); + + connect(m_sdWatcher.data(), SIGNAL(serviceRegistered(QString)), + this, SLOT(onSessionHandlerRegistered(QString))); + connect(m_sdWatcher.data(), SIGNAL(serviceUnregistered(QString)), + this, SLOT(onSessionHandlerUnregistered(QString))); + // If it's up and running already, let's cache it + if (QDBusConnection::systemBus().interface()->isServiceRegistered(SYSTEMD_LOGIN1_SERVICE)) { + onSessionHandlerRegistered(SYSTEMD_LOGIN1_SERVICE); + } + + // Watch over the ConsoleKit service + m_ckWatcher.data()->setConnection(QDBusConnection::sessionBus()); + m_ckWatcher.data()->setWatchMode(QDBusServiceWatcher::WatchForUnregistration | + QDBusServiceWatcher::WatchForRegistration); + m_ckWatcher.data()->addWatchedService(CONSOLEKIT_SERVICE); + + connect(m_ckWatcher.data(), SIGNAL(serviceRegistered(QString)), + this, SLOT(onSessionHandlerRegistered(QString))); + connect(m_ckWatcher.data(), SIGNAL(serviceUnregistered(QString)), + this, SLOT(onSessionHandlerUnregistered(QString))); + // If it's up and running already, let's cache it + if (QDBusConnection::systemBus().interface()->isServiceRegistered(CONSOLEKIT_SERVICE)) { + onSessionHandlerRegistered(CONSOLEKIT_SERVICE); + } + + // Now set up our service watcher + m_busWatcher.data()->setConnection(QDBusConnection::sessionBus()); + m_busWatcher.data()->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + + connect(m_busWatcher.data(), SIGNAL(serviceUnregistered(QString)), + this, SLOT(onServiceUnregistered(QString))); +} + +QString PolicyAgent::getNamedPathProperty(const QString &path, const QString &iface, const QString &prop) const +{ + QDBusMessage message = QDBusMessage::createMethodCall(SYSTEMD_LOGIN1_SERVICE, path, + QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); + message << iface << prop; + QDBusMessage reply = QDBusConnection::systemBus().call(message); + + QVariantList args = reply.arguments(); + if (!args.isEmpty()) { + NamedDBusObjectPath namedPath; + args.at(0).value().variant().value() >> namedPath; + return namedPath.path.path(); + } + + return QString(); +} + +void PolicyAgent::forceLockAndWait() +{ + OrgFreedesktopScreenSaverInterface screenSaveriface("org.freedesktop.ScreenSaver", + "/ScreenSaver", + QDBusConnection::sessionBus()); + QDBusPendingReply< void > reply = screenSaveriface.Lock(); + reply.waitForFinished(); +} + +void PolicyAgent::onSessionHandlerRegistered(const QString & serviceName) +{ + if (serviceName == SYSTEMD_LOGIN1_SERVICE) { + m_sdAvailable = true; + + qRegisterMetaType(); + qDBusRegisterMetaType(); + + // get the current session + QDBusInterface managerIface(SYSTEMD_LOGIN1_SERVICE, SYSTEMD_LOGIN1_PATH, SYSTEMD_LOGIN1_MANAGER_IFACE, QDBusConnection::systemBus()); + QDBusPendingReply session = managerIface.asyncCall(QLatin1String("GetSessionByPID"), (quint32) QCoreApplication::applicationPid()); + session.waitForFinished(); + + if (!session.isValid()) { + kDebug() << "The session is not registered with systemd"; + m_sdAvailable = false; + return; + } + + QString sessionPath = session.value().path(); + kDebug() << "Session path:" << sessionPath; + + m_sdSessionInterface = new QDBusInterface(SYSTEMD_LOGIN1_SERVICE, sessionPath, + SYSTEMD_LOGIN1_SESSION_IFACE, QDBusConnection::systemBus(), this); + if (!m_sdSessionInterface.data()->isValid()) { + // As above + kDebug() << "Can't contact session iface"; + m_sdAvailable = false; + delete m_sdSessionInterface.data(); + return; + } + + // listen to the systemd-login1 session's Lock signal + connect(m_sdSessionInterface.data(), SIGNAL(Lock()), this, SLOT(forceLockAndWait())); + + // now let's obtain the seat + QString seatPath = getNamedPathProperty(sessionPath, SYSTEMD_LOGIN1_SESSION_IFACE, "Seat"); + + if (seatPath.isEmpty() || seatPath == "/") { + kDebug() << "Unable to associate systemd session with a seat" << seatPath; + m_sdAvailable = false; + return; + } + + // get the current seat + m_sdSeatInterface = new QDBusInterface(SYSTEMD_LOGIN1_SERVICE, seatPath, + SYSTEMD_LOGIN1_SEAT_IFACE, QDBusConnection::systemBus(), this); + + if (!m_sdSeatInterface.data()->isValid()) { + // As above + kDebug() << "Can't contact seat iface"; + m_sdAvailable = false; + delete m_sdSeatInterface.data(); + return; + } + + // finally get the active session path and watch for its changes + m_activeSessionPath = getNamedPathProperty(seatPath, SYSTEMD_LOGIN1_SEAT_IFACE, "ActiveSession"); + + kDebug() << "ACTIVE SESSION PATH:" << m_activeSessionPath; + QDBusConnection::systemBus().connect(SYSTEMD_LOGIN1_SERVICE, seatPath, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, + SLOT(onActiveSessionChanged(QString,QVariantMap,QStringList))); + + onActiveSessionChanged(m_activeSessionPath); + + setupSystemdInhibition(); + + kDebug() << "systemd support initialized"; + } else if (serviceName == CONSOLEKIT_SERVICE) { + m_ckAvailable = true; + + // Otherwise, let's ask ConsoleKit + QDBusInterface ckiface(CONSOLEKIT_SERVICE, "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); + + QDBusPendingReply sessionPath = ckiface.asyncCall("GetCurrentSession"); + + sessionPath.waitForFinished(); + + if (!sessionPath.isValid() || sessionPath.value().path().isEmpty()) { + kDebug() << "The session is not registered with ck"; + m_ckAvailable = false; + return; + } + + m_ckSessionInterface = new QDBusInterface(CONSOLEKIT_SERVICE, sessionPath.value().path(), + "org.freedesktop.ConsoleKit.Session", QDBusConnection::systemBus()); + + if (!m_ckSessionInterface.data()->isValid()) { + // As above + kDebug() << "Can't contact iface"; + m_ckAvailable = false; + return; + } + + // Now let's obtain the seat + QDBusPendingReply< QDBusObjectPath > seatPath = m_ckSessionInterface.data()->asyncCall("GetSeatId"); + seatPath.waitForFinished(); + + if (!seatPath.isValid() || seatPath.value().path().isEmpty()) { + kDebug() << "Unable to associate ck session with a seat"; + m_ckAvailable = false; + return; + } + + if (!QDBusConnection::systemBus().connect(CONSOLEKIT_SERVICE, seatPath.value().path(), + "org.freedesktop.ConsoleKit.Seat", "ActiveSessionChanged", + this, SLOT(onActiveSessionChanged(QString)))) { + kDebug() << "Unable to connect to ActiveSessionChanged"; + m_ckAvailable = false; + return; + } + + // Force triggering of active session changed + QDBusMessage call = QDBusMessage::createMethodCall(CONSOLEKIT_SERVICE, seatPath.value().path(), + "org.freedesktop.ConsoleKit.Seat", "GetActiveSession"); + QDBusPendingReply< QDBusObjectPath > activeSession = QDBusConnection::systemBus().asyncCall(call); + activeSession.waitForFinished(); + + onActiveSessionChanged(activeSession.value().path()); + + kDebug() << "ConsoleKit support initialized"; + } + else + kWarning() << "Unhandled service registered:" << serviceName; +} + +void PolicyAgent::onSessionHandlerUnregistered(const QString & serviceName) +{ + if (serviceName == SYSTEMD_LOGIN1_SERVICE) { + m_sdAvailable = false; + delete m_sdSessionInterface.data(); + } + else if (serviceName == CONSOLEKIT_SERVICE) { + m_ckAvailable = false; + delete m_ckSessionInterface.data(); + } +} + +void PolicyAgent::onActiveSessionChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps) +{ + const QString key = QLatin1String("ActiveSession"); + + if (ifaceName == SYSTEMD_LOGIN1_SEAT_IFACE && (changedProps.keys().contains(key) || invalidatedProps.contains(key))) { + m_activeSessionPath = getNamedPathProperty(m_sdSeatInterface.data()->path(), SYSTEMD_LOGIN1_SEAT_IFACE, key); + kDebug() << "ACTIVE SESSION PATH CHANGED:" << m_activeSessionPath; + onActiveSessionChanged(m_activeSessionPath); + } +} + +void PolicyAgent::onActiveSessionChanged(const QString& activeSession) +{ + if (activeSession.isEmpty() || activeSession == "/") { + kDebug() << "Switched to inactive session - leaving unchanged"; + return; + } else if ((!m_sdSessionInterface.isNull() && activeSession == m_sdSessionInterface.data()->path()) || + (!m_ckSessionInterface.isNull() && activeSession == m_ckSessionInterface.data()->path())) { + kDebug() << "Current session is now active"; + m_wasLastActiveSession = true; + } else { + kDebug() << "Current session is now inactive"; + m_wasLastActiveSession = false; + } +} + +void PolicyAgent::onServiceUnregistered(const QString& serviceName) +{ + if (m_cookieToBusService.values().contains(serviceName)) { + // Ouch - the application quit or crashed without releasing its inhibitions. Let's fix that. + foreach (uint key, m_cookieToBusService.keys(serviceName)) { + ReleaseInhibition(key); + } + } +} + +PolicyAgent::RequiredPolicies PolicyAgent::unavailablePolicies() +{ + RequiredPolicies retpolicies = None; + + if (!m_typesToCookie[ChangeProfile].isEmpty()) { + retpolicies |= ChangeProfile; + } + if (!m_typesToCookie[ChangeScreenSettings].isEmpty()) { + retpolicies |= ChangeScreenSettings; + } + if (!m_typesToCookie[InterruptSession].isEmpty()) { + retpolicies |= InterruptSession; + } + + return retpolicies; +} + +PolicyAgent::RequiredPolicies PolicyAgent::requirePolicyCheck(PolicyAgent::RequiredPolicies policies) +{ + if (!m_sdAvailable) { + // No way to determine if we are on the current session, simply suppose we are + kDebug() << "Can't contact systemd"; + } else if (!m_sdSessionInterface.isNull()) { + bool isActive = m_sdSessionInterface.data()->property("Active").toBool(); + + if (!isActive && !m_wasLastActiveSession) { + return policies; + } + } + + if (!m_ckAvailable) { + // No way to determine if we are on the current session, simply suppose we are + kDebug() << "Can't contact ck"; + } else if (!m_ckSessionInterface.isNull()) { + QDBusPendingReply< bool > rp = m_ckSessionInterface.data()->asyncCall("IsActive"); + rp.waitForFinished(); + + if (!(rp.isValid() && rp.value()) && !m_wasLastActiveSession) { + return policies; + } + } + + // Ok, let's go then + RequiredPolicies retpolicies = None; + + if (policies & ChangeProfile) { + if (!m_typesToCookie[ChangeProfile].isEmpty()) { + retpolicies |= ChangeProfile; + } + } + if (policies & ChangeScreenSettings) { + if (!m_typesToCookie[ChangeScreenSettings].isEmpty()) { + retpolicies |= ChangeScreenSettings; + } + } + if (policies & InterruptSession) { + if (m_sessionIsBeingInterrupted || !m_typesToCookie[InterruptSession].isEmpty()) { + retpolicies |= InterruptSession; + } + } + + return retpolicies; +} + +void PolicyAgent::startSessionInterruption() +{ + m_sessionIsBeingInterrupted = true; +} + +void PolicyAgent::finishSessionInterruption() +{ + m_sessionIsBeingInterrupted = false; +} + +uint PolicyAgent::addInhibitionWithExplicitDBusService(uint types, const QString& appName, + const QString& reason, const QString& service) +{ + ++m_lastCookie; + + m_cookieToAppName.insert(m_lastCookie, qMakePair(appName, reason)); + + if (!m_busWatcher.isNull() && !service.isEmpty()) { + m_cookieToBusService.insert(m_lastCookie, service); + m_busWatcher.data()->addWatchedService(service); + } + + kDebug() << "Added inhibition from an explicit DBus service, " << service << ", with cookie " << + m_lastCookie << " from " << appName << " with " << reason; + + addInhibitionTypeHelper(m_lastCookie, static_cast< PolicyAgent::RequiredPolicies >(types)); + + return m_lastCookie; +} + +uint PolicyAgent::AddInhibition(uint types, + const QString& appName, + const QString& reason) +{ + ++m_lastCookie; + + m_cookieToAppName.insert(m_lastCookie, qMakePair(appName, reason)); + + // Retrieve the service, if we've been called from DBus + if (calledFromDBus() && !m_busWatcher.isNull()) { + if (!message().service().isEmpty()) { + kDebug() << "DBus service " << message().service() << " is requesting inhibition"; + m_cookieToBusService.insert(m_lastCookie, message().service()); + m_busWatcher.data()->addWatchedService(message().service()); + } + } + + kDebug() << "Added inhibition with cookie " << m_lastCookie << " from " << + appName << " with " << reason; + + addInhibitionTypeHelper(m_lastCookie, static_cast< PolicyAgent::RequiredPolicies >(types)); + + return m_lastCookie; +} + +void PolicyAgent::addInhibitionTypeHelper(uint cookie, PolicyAgent::RequiredPolicies types) +{ + // Look through all of the inhibition types + bool notify = false; + if (types & ChangeProfile) { + // Check if we have to notify + if (m_typesToCookie[ChangeProfile].isEmpty()) { + kDebug() << "Added change profile"; + notify = true; + } + m_typesToCookie[ChangeProfile].append(cookie); + } + if (types & ChangeScreenSettings) { + // Check if we have to notify + kDebug() << "Added change screen settings"; + if (m_typesToCookie[ChangeScreenSettings].isEmpty()) { + notify = true; + } + m_typesToCookie[ChangeScreenSettings].append(cookie); + types |= InterruptSession; // implied by ChangeScreenSettings + } + if (types & InterruptSession) { + // Check if we have to notify + kDebug() << "Added interrupt session"; + if (m_typesToCookie[InterruptSession].isEmpty()) { + notify = true; + } + m_typesToCookie[InterruptSession].append(cookie); + } + + if (notify) { + // Emit the signal - inhibition has changed + emit unavailablePoliciesChanged(unavailablePolicies()); + } +} + +void PolicyAgent::ReleaseInhibition(uint cookie) +{ + kDebug() << "Released inhibition with cookie " << cookie; + m_cookieToAppName.remove(cookie); + QString service = m_cookieToBusService.take(cookie); + if (!m_busWatcher.isNull() && !service.isEmpty() && !m_cookieToBusService.key(service)) { + // no cookies from service left + m_busWatcher.data()->removeWatchedService(service); + } + + // Look through all of the inhibition types + bool notify = false; + if (m_typesToCookie[ChangeProfile].contains(cookie)) { + m_typesToCookie[ChangeProfile].removeOne(cookie); + // Check if we have to notify + if (m_typesToCookie[ChangeProfile].isEmpty()) { + notify = true; + } + } + if (m_typesToCookie[ChangeScreenSettings].contains(cookie)) { + m_typesToCookie[ChangeScreenSettings].removeOne(cookie); + // Check if we have to notify + if (m_typesToCookie[ChangeScreenSettings].isEmpty()) { + notify = true; + } + } + if (m_typesToCookie[InterruptSession].contains(cookie)) { + m_typesToCookie[InterruptSession].removeOne(cookie); + // Check if we have to notify + if (m_typesToCookie[InterruptSession].isEmpty()) { + notify = true; + } + } + + if (notify) { + // Emit the signal - inhibition has changed + emit unavailablePoliciesChanged(unavailablePolicies()); + } +} + +void PolicyAgent::releaseAllInhibitions() +{ + QList< uint > allCookies = m_cookieToAppName.keys(); + foreach (uint cookie, allCookies) { + ReleaseInhibition(cookie); + } +} + +void PolicyAgent::setupSystemdInhibition() +{ + if (m_systemdInhibitFd.fileDescriptor() != -1) + return; + + // inhibit systemd handling of power/sleep/lid buttons + // http://www.freedesktop.org/wiki/Software/systemd/inhibit + QDBusInterface managerIface(SYSTEMD_LOGIN1_SERVICE, SYSTEMD_LOGIN1_PATH, SYSTEMD_LOGIN1_MANAGER_IFACE, QDBusConnection::systemBus()); + kDebug() << "fd passing available:" << bool(managerIface.connection().connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing); + + QVariantList args; + args << "handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch"; // what + args << "PowerDevil"; // who + args << "KDE handles power events"; // why + args << "block"; // mode + QDBusPendingReply desc = managerIface.asyncCallWithArgumentList("Inhibit", args); + desc.waitForFinished(); + if (desc.isValid()) { + m_systemdInhibitFd = desc.value(); + kDebug() << "systemd powersave events handling inhibited, descriptor:" << m_systemdInhibitFd.fileDescriptor(); + } + else + kWarning() << "failed to inhibit systemd powersave handling"; +} + +} + +#include "powerdevilpolicyagent.moc" diff --git a/powerdevil/daemon/powerdevilpolicyagent.h b/powerdevil/daemon/powerdevilpolicyagent.h new file mode 100644 index 00000000..aa3d0cd4 --- /dev/null +++ b/powerdevil/daemon/powerdevilpolicyagent.h @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * Copyright (C) 2012 Lukáš Tinkl * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef POWERDEVIL_POWERDEVILPOLICYAGENT_H +#define POWERDEVIL_POWERDEVILPOLICYAGENT_H + +#include +#include +#include + +#include +#include + +#include + +class QDBusServiceWatcher; +class QDBusInterface; + +#define SYSTEMD_LOGIN1_SERVICE "org.freedesktop.login1" +#define SYSTEMD_LOGIN1_PATH "/org/freedesktop/login1" +#define SYSTEMD_LOGIN1_MANAGER_IFACE "org.freedesktop.login1.Manager" +#define SYSTEMD_LOGIN1_SESSION_IFACE "org.freedesktop.login1.Session" +#define SYSTEMD_LOGIN1_SEAT_IFACE "org.freedesktop.login1.Seat" + +#define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit" + + +namespace PowerDevil +{ + +class KDE_EXPORT PolicyAgent : public QObject, protected QDBusContext +{ + Q_OBJECT + Q_DISABLE_COPY(PolicyAgent) + + Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.PolicyAgent") + +public: + enum RequiredPolicy { + None = 0, + InterruptSession = 1, + ChangeProfile = 2, + ChangeScreenSettings = 4 + }; + Q_DECLARE_FLAGS(RequiredPolicies, RequiredPolicy) + + static PolicyAgent *instance(); + + virtual ~PolicyAgent(); + + /** + * This function performs a policy check on given policies, and returns a set of unsatisfiable policies, + * or \c None if all the policies are satisfiable and the action can be carried on. + */ + RequiredPolicies requirePolicyCheck(RequiredPolicies policies); + + RequiredPolicies unavailablePolicies(); + + void setupSystemdInhibition(); + +public Q_SLOTS: + // Exported slots + uint AddInhibition(uint types, const QString &appName, const QString &reason); + void ReleaseInhibition(uint cookie); + + void releaseAllInhibitions(); +Q_SIGNALS: + void unavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies newpolicies); + +private Q_SLOTS: + void onServiceUnregistered(const QString & serviceName); + void onSessionHandlerRegistered(const QString & serviceName); + void onSessionHandlerUnregistered(const QString & serviceName); + void onActiveSessionChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps); + void onActiveSessionChanged(const QString &activeSession); + void forceLockAndWait(); + +private: + explicit PolicyAgent(QObject* parent = 0); + + void init(); + void startSessionInterruption(); + void finishSessionInterruption(); + + void addInhibitionTypeHelper(uint cookie, RequiredPolicies types); + + // This function serves solely for fd.o connector + uint addInhibitionWithExplicitDBusService(uint types, const QString &appName, + const QString &reason, const QString &service); + + // systemd support + QString getNamedPathProperty(const QString & path, const QString & iface, const QString & prop) const; + bool m_sdAvailable; + QString m_activeSessionPath; + QWeakPointer< QDBusInterface > m_sdSessionInterface; + QWeakPointer< QDBusInterface > m_sdSeatInterface; + QDBusUnixFileDescriptor m_systemdInhibitFd; + + // ConsoleKit support + bool m_ckAvailable; + QWeakPointer< QDBusInterface > m_ckSessionInterface; + QWeakPointer< QDBusInterface > m_ckSeatInterface; + bool m_sessionIsBeingInterrupted; + + QHash< uint, QPair< QString, QString > > m_cookieToAppName; + QHash< uint, QString > m_cookieToBusService; + QHash< RequiredPolicy, QList< uint > > m_typesToCookie; + + uint m_lastCookie; + + QWeakPointer< QDBusServiceWatcher > m_busWatcher; + QWeakPointer< QDBusServiceWatcher > m_sdWatcher; + QWeakPointer< QDBusServiceWatcher > m_ckWatcher; + + bool m_wasLastActiveSession; + + friend class Core; + friend class FdoConnector; +}; + +} + +#endif // POWERDEVIL_POWERDEVILPOLICYAGENT_H diff --git a/powerdevil/daemon/powerdevilprofilegenerator.cpp b/powerdevil/daemon/powerdevilprofilegenerator.cpp new file mode 100644 index 00000000..32d1ede8 --- /dev/null +++ b/powerdevil/daemon/powerdevilprofilegenerator.cpp @@ -0,0 +1,359 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "powerdevilprofilegenerator.h" + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace PowerDevil { + +ProfileGenerator::GeneratorResult ProfileGenerator::generateProfiles(bool toRam, bool toDisk, bool tryUpgrade) +{ + if (tryUpgrade) { + bool isUpgraded = false; + KSharedConfigPtr oldProfilesConfigv1 = KSharedConfig::openConfig("powerdevilprofilesrc", KConfig::SimpleConfig); + if (!oldProfilesConfigv1->groupList().isEmpty()) { + // We can upgrade from v1, let's do that. + upgradeProfilesv1(toRam, toDisk); + isUpgraded = true; + } + KSharedConfigPtr oldProfilesConfigv2 = KSharedConfig::openConfig("powerdevil2profilesrc", KConfig::SimpleConfig); + if (!oldProfilesConfigv2->groupList().isEmpty()) { + // We can upgrade from v2, let's do that. + upgradeProfilesv2(); + isUpgraded = true; + } + + if (isUpgraded) { + return ResultUpgraded; + } + } + + // Let's change some defaults + if (!toRam) { + if (!toDisk) { + PowerDevilSettings::setBatteryCriticalAction(0); + } else { + PowerDevilSettings::setBatteryCriticalAction(2); + } + } + + // Ok, let's get our config file. + KSharedConfigPtr profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig); + + // And clear it + foreach (const QString &group, profilesConfig->groupList()) { + // Don't delete activity-specific settings + if (group != "Activities") { + profilesConfig->deleteGroup(group); + } + } + + // Let's start: AC profile before anything else + KConfigGroup acProfile(profilesConfig, "AC"); + acProfile.writeEntry("icon", "battery-charging"); + + // We want to dim the screen after a while, definitely + { + KConfigGroup dimDisplay(&acProfile, "DimDisplay"); + dimDisplay.writeEntry< int >("idleTime", 300000); + } + // Show the dialog when power button is pressed and suspend on suspend button pressed and lid closed (if supported) + { + KConfigGroup handleButtonEvents(&acProfile, "HandleButtonEvents"); + handleButtonEvents.writeEntry< uint >("powerButtonAction", LogoutDialogMode); + if (toRam) { + handleButtonEvents.writeEntry< uint >("lidAction", ToRamMode); + } else { + handleButtonEvents.writeEntry< uint >("lidAction", TurnOffScreenMode); + } + } + + // And we also want to turn off the screen after another while + { + KConfigGroup dpmsControl(&acProfile, "DPMSControl"); + dpmsControl.writeEntry< uint >("idleTime", 600); + } + + // Easy part done. Now, any batteries? + bool hasBattery = false; + + foreach(const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { + const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); + if (b->isPowerSupply() && (b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery)) { + hasBattery = true; + break; + } + } + + if (hasBattery) { + // Then we want to handle brightness in performance. + { + KConfigGroup brightnessControl(&acProfile, "BrightnessControl"); + brightnessControl.writeEntry< int >("value", 100); + } + } + + // Powersave + KConfigGroup batteryProfile(profilesConfig, "Battery"); + batteryProfile.writeEntry("icon", "battery-060"); + // Less brightness. + { + KConfigGroup brightnessControl(&batteryProfile, "BrightnessControl"); + brightnessControl.writeEntry< int >("value", 60); + } + // We want to dim the screen after a while, definitely + { + KConfigGroup dimDisplay(&batteryProfile, "DimDisplay"); + dimDisplay.writeEntry< int >("idleTime", 120000); + } + // Show the dialog when power button is pressed and suspend on suspend button pressed and lid closed (if supported) + { + KConfigGroup handleButtonEvents(&batteryProfile, "HandleButtonEvents"); + handleButtonEvents.writeEntry< uint >("powerButtonAction", LogoutDialogMode); + if (toRam) { + handleButtonEvents.writeEntry< uint >("lidAction", ToRamMode); + } else { + handleButtonEvents.writeEntry< uint >("lidAction", TurnOffScreenMode); + } + } + // We want to turn off the screen after another while + { + KConfigGroup dpmsControl(&batteryProfile, "DPMSControl"); + dpmsControl.writeEntry< uint >("idleTime", 300); + } + // Last but not least, we want to suspend after a rather long period of inactivity + if (toRam) { + KConfigGroup suspendSession(&batteryProfile, "SuspendSession"); + suspendSession.writeEntry< uint >("idleTime", 600000); + suspendSession.writeEntry< uint >("suspendType", ToRamMode); + } + + + // Ok, now for aggressive powersave + KConfigGroup lowBatteryProfile(profilesConfig, "LowBattery"); + lowBatteryProfile.writeEntry("icon", "battery-low"); + // Less brightness. + { + KConfigGroup brightnessControl(&lowBatteryProfile, "BrightnessControl"); + brightnessControl.writeEntry< int >("value", 30); + } + // We want to dim the screen after a while, definitely + { + KConfigGroup dimDisplay(&lowBatteryProfile, "DimDisplay"); + dimDisplay.writeEntry< int >("idleTime", 60000); + } + // Show the dialog when power button is pressed and suspend on suspend button pressed and lid closed (if supported) + { + KConfigGroup handleButtonEvents(&lowBatteryProfile, "HandleButtonEvents"); + handleButtonEvents.writeEntry< uint >("powerButtonAction", LogoutDialogMode); + if (toRam) { + handleButtonEvents.writeEntry< uint >("lidAction", ToRamMode); + } else { + handleButtonEvents.writeEntry< uint >("lidAction", TurnOffScreenMode); + } + } + // We want to turn off the screen after another while + { + KConfigGroup dpmsControl(&lowBatteryProfile, "DPMSControl"); + dpmsControl.writeEntry< uint >("idleTime", 120); + } + // Last but not least, we want to suspend after a rather long period of inactivity + if (toRam) { + KConfigGroup suspendSession(&lowBatteryProfile, "SuspendSession"); + suspendSession.writeEntry< uint >("idleTime", 300000); + suspendSession.writeEntry< uint >("suspendType", ToRamMode); + } + + // Save and be happy + profilesConfig->sync(); + + return ResultGenerated; +} + +void ProfileGenerator::upgradeProfilesv1(bool toRam, bool toDisk) +{ + // Let's change some defaults + if (!toRam) { + if (!toDisk) { + PowerDevilSettings::setBatteryCriticalAction(None); + } else { + PowerDevilSettings::setBatteryCriticalAction(ToDiskMode); + } + } else { + PowerDevilSettings::setBatteryCriticalAction(ToRamMode); + } + + // Ok, let's get our config file. + KSharedConfigPtr profilesConfig = KSharedConfig::openConfig("powerdevil2profilesrc", KConfig::SimpleConfig); + KSharedConfigPtr oldProfilesConfig = KSharedConfig::openConfig("powerdevilprofilesrc", KConfig::SimpleConfig); + + // And clear it + foreach (const QString &group, profilesConfig->groupList()) { + profilesConfig->deleteGroup(group); + } + + foreach (const QString &group, oldProfilesConfig->groupList()) { + KConfigGroup oldGroup = oldProfilesConfig->group(group); + KConfigGroup newGroup(profilesConfig, oldGroup.readEntry< QString >("name", QString())); + + // Read stuff + // Brightness. + { + KConfigGroup brightnessControl(&newGroup, "BrightnessControl"); + brightnessControl.writeEntry< int >("value", oldGroup.readEntry< int >("brightness", 100)); + } + // Dim screen + if (oldGroup.readEntry< bool >("dimOnIdle", false)) { + KConfigGroup dimDisplay(&newGroup, "DimDisplay"); + dimDisplay.writeEntry< int >("idleTime", oldGroup.readEntry< int >("dimOnIdleTime", 30) * 60 * 1000); + } + // DPMS + if (oldGroup.readEntry< bool >("DPMSEnabled", false) && oldGroup.readEntry< int >("DPMSPowerOff", 0) > 0) { + KConfigGroup dpmsControl(&newGroup, "DPMSControl"); + dpmsControl.writeEntry< uint >("idleTime", oldGroup.readEntry< int >("DPMSPowerOff", 30) * 60); + } + // Script + if (!oldGroup.readEntry< QString >("scriptpath", QString()).isEmpty()) { + KConfigGroup runScript(&newGroup, "RunScript"); + runScript.writeEntry< QString >("scriptCommand", oldGroup.readEntry< QString >("scriptpath", QString())); + runScript.writeEntry< uint >("scriptPhase", 0); + } + // SuspendSession + if (oldGroup.readEntry< uint >("idleAction", 0) > 0) { + KConfigGroup suspendSession(&newGroup, "SuspendSession"); + suspendSession.writeEntry< uint >("idleTime", oldGroup.readEntry< int >("idleTime", 30) * 60 * 1000); + suspendSession.writeEntry< uint >("suspendType", upgradeOldAction(oldGroup.readEntry< uint >("idleAction", 0))); + } + // Buttons + if (oldGroup.readEntry< uint >("powerButtonAction", 0) > 0 || oldGroup.readEntry< uint >("lidAction", 0) > 0) { + KConfigGroup handleButtons(&newGroup, "HandleButtonEvents"); + handleButtons.writeEntry< uint >("powerButtonAction", upgradeOldAction(oldGroup.readEntry< uint >("powerButtonAction", 0))); + handleButtons.writeEntry< uint >("lidAction", upgradeOldAction(oldGroup.readEntry< uint >("lidAction", 0))); + } + } + + // Save and be happy + profilesConfig->sync(); + + // We also want to backup and erase the old profiles. + QString oldProfilesFile = KGlobal::dirs()->findResource("config", "powerdevilprofilesrc"); + if (!oldProfilesFile.isEmpty()) { + // Backup + QString bkProfilesFile = oldProfilesFile; + bkProfilesFile.append(".old"); + KConfig *bkConfig = oldProfilesConfig->copyTo(bkProfilesFile); + if (bkConfig != 0) { + bkConfig->sync(); + delete bkConfig; + + // Delete the old profiles now. + QFile::remove(oldProfilesFile); + } + } +} + +void ProfileGenerator::upgradeProfilesv2() +{ + // Ok, let's get our config file. + KSharedConfigPtr profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig); + KSharedConfigPtr oldProfilesConfig = KSharedConfig::openConfig("powerdevil2profilesrc", KConfig::SimpleConfig); + + // And clear it + foreach (const QString &group, profilesConfig->groupList()) { + // Don't delete activity-specific settings + if (group != "Activities") { + profilesConfig->deleteGroup(group); + } + } + + // Ok: back in the days, which profile we used for which task? + { + KConfigGroup oldAC = oldProfilesConfig.data()->group(PowerDevilSettings::aCProfile()); + KConfigGroup newGroup(profilesConfig, "AC"); + + oldAC.copyTo(&newGroup); + } + { + KConfigGroup oldBattery = oldProfilesConfig.data()->group(PowerDevilSettings::batteryProfile()); + KConfigGroup newGroup(profilesConfig, "Battery"); + + oldBattery.copyTo(&newGroup); + } + { + KConfigGroup oldLowBattery = oldProfilesConfig.data()->group(PowerDevilSettings::lowProfile()); + KConfigGroup newGroup(profilesConfig, "LowBattery"); + + oldLowBattery.copyTo(&newGroup); + } + + // Save and be happy + profilesConfig->sync(); + + // We also want to backup and erase the old profiles. + QString oldProfilesFile = KGlobal::dirs()->findResource("config", "powerdevil2profilesrc"); + if (!oldProfilesFile.isEmpty()) { + // Backup + QString bkProfilesFile = oldProfilesFile; + bkProfilesFile.append(".old"); + KConfig *bkConfig = oldProfilesConfig->copyTo(bkProfilesFile); + if (bkConfig != 0) { + bkConfig->sync(); + delete bkConfig; + + // Delete the old profiles now. + QFile::remove(oldProfilesFile); + } + } +} + +uint ProfileGenerator::upgradeOldAction(uint oldAction) +{ + switch ((OldIdleAction)oldAction) { + case Standby: + case S2Ram: + return ToRamMode; + case S2Disk: + return ToDiskMode; + case Shutdown: + return ShutdownMode; + case Lock: + return LockScreenMode; + case ShutdownDialog: + return LogoutDialogMode; + case TurnOffScreen: + return TurnOffScreenMode; + default: + return 0; + } +} + +} diff --git a/powerdevil/daemon/powerdevilprofilegenerator.h b/powerdevil/daemon/powerdevilprofilegenerator.h new file mode 100644 index 00000000..1882e025 --- /dev/null +++ b/powerdevil/daemon/powerdevilprofilegenerator.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef POWERDEVIL_PROFILEGENERATOR_H +#define POWERDEVIL_PROFILEGENERATOR_H + +class KComponentData; +namespace PowerDevil { + +namespace ProfileGenerator +{ + enum GeneratorResult { + ResultFailed = 0, + ResultGenerated = 1, + ResultUpgraded = 2 + }; + + enum OldIdleAction { + None = 0, + Standby = 1, + S2Ram = 2, + S2Disk = 4, + Shutdown = 8, + Lock = 16, + ShutdownDialog = 32, + TurnOffScreen = 64 + }; + + enum NewMode { + NoneMode = 0, + ToRamMode = 1, + ToDiskMode = 2, + SuspendHybridMode = 4, + ShutdownMode = 8, + LogoutDialogMode = 16, + LockScreenMode = 32, + TurnOffScreenMode = 64 + }; + + GeneratorResult generateProfiles(bool toRam, bool toDisk, bool tryUpgrade = false); + void upgradeProfilesv1(bool toRam, bool toDisk); + void upgradeProfilesv2(); + unsigned int upgradeOldAction(unsigned int actionId); +} + +} + +#endif // POWERDEVIL_PROFILEGENERATOR_H diff --git a/powerdevil/kcmodule/CMakeLists.txt b/powerdevil/kcmodule/CMakeLists.txt new file mode 100644 index 00000000..bb3c13e9 --- /dev/null +++ b/powerdevil/kcmodule/CMakeLists.txt @@ -0,0 +1,10 @@ +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR}/common + ${CMAKE_CURRENT_BINARY_DIR}/common +) + +add_subdirectory(common) + +add_subdirectory(activities) +add_subdirectory(global) +add_subdirectory(profiles) diff --git a/powerdevil/kcmodule/activities/CMakeLists.txt b/powerdevil/kcmodule/activities/CMakeLists.txt new file mode 100644 index 00000000..a360f302 --- /dev/null +++ b/powerdevil/kcmodule/activities/CMakeLists.txt @@ -0,0 +1,24 @@ + +set( kcm_powerdevil_activities_SRCS + activitypage.cpp + activitywidget.cpp + ../common/ErrorOverlay.cpp +) + +kde4_add_ui_files(kcm_powerdevil_activities_SRCS + activityWidget.ui) + +kde4_add_kcfg_files(kcm_powerdevil_activities_SRCS ../../PowerDevilSettings.kcfgc) + +kde4_add_plugin(kcm_powerdevilactivitiesconfig ${kcm_powerdevil_activities_SRCS}) + +target_link_libraries(kcm_powerdevilactivitiesconfig + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBRARY} + ${KDE4_SOLID_LIBS} + ${KACTIVITIES_LIBRARY} + powerdevilconfigcommonprivate +) + +install(TARGETS kcm_powerdevilactivitiesconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) +install( FILES powerdevilactivitiesconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/powerdevil/kcmodule/activities/Messages.sh b/powerdevil/kcmodule/activities/Messages.sh new file mode 100644 index 00000000..c65284a8 --- /dev/null +++ b/powerdevil/kcmodule/activities/Messages.sh @@ -0,0 +1,5 @@ +#! /bin/sh +$EXTRACTRC `find -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp || exit 11 +$XGETTEXT `find -name \*.cpp -o -name \*.h` -o $podir/powerdevilactivitiesconfig.pot +rm -f rc.cpp + diff --git a/powerdevil/kcmodule/activities/activityWidget.ui b/powerdevil/kcmodule/activities/activityWidget.ui new file mode 100644 index 00000000..ec22df23 --- /dev/null +++ b/powerdevil/kcmodule/activities/activityWidget.ui @@ -0,0 +1,192 @@ + + + ActivityWidget + + + + 0 + 0 + 676 + 474 + + + + + + + + + Don't use special settings + + + true + + + + + + + + + Act like + + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Define a special behavior + + + + + + + 30 + + + + + Never shutdown the screen + + + + + + + Never suspend or shutdown the computer + + + + + + + 10 + + + + + Always + + + + + + + + + + after + + + + + + + min + + + 1 + + + 360 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Use separate settings (advanced users only) + + + + + + + 30 + + + + + + + + + Qt::Vertical + + + + 20 + 268 + + + + + + + + + KComboBox + QComboBox +
    kcombobox.h
    +
    +
    + + + + actLikeRadio + toggled(bool) + actLikeComboBox + setEnabled(bool) + + + 44 + 66 + + + 133 + 66 + + + + +
    diff --git a/powerdevil/kcmodule/activities/activitypage.cpp b/powerdevil/kcmodule/activities/activitypage.cpp new file mode 100644 index 00000000..d8f11693 --- /dev/null +++ b/powerdevil/kcmodule/activities/activitypage.cpp @@ -0,0 +1,219 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "activitypage.h" + +#include "activitywidget.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilActivitiesKCMFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(PowerDevilActivitiesKCMFactory("powerdevilactivitiesconfig","powerdevil")) + +ActivityPage::ActivityPage(QWidget *parent, const QVariantList &args) + : KCModule(PowerDevilActivitiesKCMFactory::componentData(), parent, args) + , m_activityConsumer(new KActivities::Consumer(this)) +{ + setButtons(Apply | Help); + + KAboutData *about = + new KAboutData("powerdevilactivitiesconfig", "powerdevilactivitiesconfig", ki18n("Activities Power Management Configuration"), + "", ki18n("A per-activity configurator of KDE Power Management System"), + KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), + ki18n("From this module, you can fine tune power management settings for each of your activities.")); + + about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", + "http://drfav.wordpress.com"); + + setAboutData(about); + + // Build the UI + KTabWidget *tabWidget = new KTabWidget(); + QVBoxLayout *lay = new QVBoxLayout(); + + foreach (const QString &activity, m_activityConsumer->listActivities()) { + KActivities::Info *info = new KActivities::Info(activity, this); + QString icon = info->icon(); + QString name = info->name(); + kDebug() << activity << info->isValid() << info->availability(); + + QScrollArea *scrollArea = new QScrollArea(); + scrollArea->setFrameShape(QFrame::NoFrame); + scrollArea->setFrameShadow(QFrame::Plain); + scrollArea->setLineWidth(0); + scrollArea->setWidgetResizable(true); + + ActivityWidget *activityWidget = new ActivityWidget(activity); + scrollArea->setWidget(activityWidget); + + activityWidget->load(); + m_activityWidgets.append(activityWidget); + + connect(activityWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + + tabWidget->addTab(scrollArea, KIcon(icon), name); + } + + // Message widget + m_messageWidget = new KMessageWidget(i18n("The activity service is running with bare functionalities.\n" + "Names and icons of the activities might not be available.")); + m_messageWidget.data()->setMessageType(KMessageWidget::Warning); + m_messageWidget.data()->hide(); + + lay->addWidget(m_messageWidget.data()); + lay->addWidget(tabWidget); + setLayout(lay); + + connect(m_activityConsumer, SIGNAL(serviceStatusChanged(KActivities::Consumer::ServiceStatus)), + this, SLOT(onActivityServiceStatusChanged(KActivities::Consumer::ServiceStatus))); + onActivityServiceStatusChanged(m_activityConsumer->serviceStatus()); + + QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForRegistration | + QDBusServiceWatcher::WatchForUnregistration, + this); + + connect(watcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); + connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onServiceUnregistered(QString))); + + if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + onServiceRegistered("org.kde.Solid.PowerManagement"); + } else { + onServiceUnregistered("org.kde.Solid.PowerManagement"); + } +} + +ActivityPage::~ActivityPage() +{ + +} + +void ActivityPage::load() +{ + foreach (ActivityWidget *widget, m_activityWidgets) { + widget->load(); + } + + emit changed(false); +} + +void ActivityPage::save() +{ + foreach (ActivityWidget *widget, m_activityWidgets) { + widget->save(); + } + + emit changed(false); + + // Ask to refresh status + QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "refreshStatus"); + + // Perform call + QDBusConnection::sessionBus().asyncCall(call); +} + +void ActivityPage::fillUi() +{ + +} + +void ActivityPage::onActivityServiceStatusChanged(KActivities::Consumer::ServiceStatus status) +{ + switch (status) { + case KActivities::Consumer::NotRunning: + // Create error overlay, if not present + if (m_errorOverlay.isNull()) { + m_errorOverlay = new ErrorOverlay(this, i18n("The activity service is not running.\n" + "It is necessary to have the activity manager running " + "to configure activity-specific power management behavior."), + this); + } + break; + case KActivities::Consumer::BareFunctionality: + // Show message widget + m_messageWidget.data()->show(); + break; + case KActivities::Consumer::FullFunctionality: + if (m_previousServiceStatus != KActivities::Consumer::FullFunctionality && + !m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + onServiceRegistered("org.kde.Solid.PowerManagement"); + } else { + onServiceUnregistered("org.kde.Solid.PowerManagement"); + } + } + if (m_messageWidget.data()->isVisible()) { + m_messageWidget.data()->hide(); + } + break; + } +} + +void ActivityPage::defaults() +{ + KCModule::defaults(); +} + +void ActivityPage::onServiceRegistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + } + + onActivityServiceStatusChanged(m_activityConsumer->serviceStatus()); +} + +void ActivityPage::onServiceUnregistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + return; + } + + m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running.\n" + "This can be solved by starting or scheduling it inside \"Startup and Shutdown\""), + this); +} + +#include "activitypage.moc" diff --git a/powerdevil/kcmodule/activities/activitypage.h b/powerdevil/kcmodule/activities/activitypage.h new file mode 100644 index 00000000..230f8354 --- /dev/null +++ b/powerdevil/kcmodule/activities/activitypage.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef ACTIVITYPAGE_H +#define ACTIVITYPAGE_H + +#include + +#include + +class ErrorOverlay; +class ActivityWidget; +class KMessageWidget; +class ActivityPage : public KCModule +{ + Q_OBJECT + +public: + ActivityPage(QWidget *parent, const QVariantList &args); + virtual ~ActivityPage(); + void fillUi(); + + void load(); + void save(); + virtual void defaults(); + +private Q_SLOTS: + void onActivityServiceStatusChanged(KActivities::Consumer::ServiceStatus status); + void onServiceRegistered(const QString &service); + void onServiceUnregistered(const QString &service); + +private: + KActivities::Consumer *m_activityConsumer; + QList< ActivityWidget* > m_activityWidgets; + QWeakPointer< ErrorOverlay > m_errorOverlay; + QWeakPointer< KMessageWidget > m_messageWidget; + KActivities::Consumer::ServiceStatus m_previousServiceStatus; +}; + +#endif // ACTIVITYPAGE_H diff --git a/powerdevil/kcmodule/activities/activitywidget.cpp b/powerdevil/kcmodule/activities/activitywidget.cpp new file mode 100644 index 00000000..8d9517a7 --- /dev/null +++ b/powerdevil/kcmodule/activities/activitywidget.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "activitywidget.h" + +#include "ui_activityWidget.h" + +#include "daemon/actions/bundled/suspendsession.h" + +#include +#include +#include +#include + +ActivityWidget::ActivityWidget(const QString& activity, QWidget* parent) + : QWidget(parent) + , m_ui(new Ui::ActivityWidget) + , m_profilesConfig(KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig)) + , m_activity(activity) + , m_activityConsumer(new KActivities::Consumer(this)) + , m_actionEditWidget(new ActionEditWidget(QString("Activities/%1/SeparateSettings").arg(activity))) +{ + m_ui->setupUi(this); + + m_ui->separateSettingsLayout->addWidget(m_actionEditWidget); + + for (int i = 0; i < m_ui->specialBehaviorLayout->count(); ++i) { + QWidget *widget = m_ui->specialBehaviorLayout->itemAt(i)->widget(); + if (widget) { + widget->setVisible(false); + connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), widget, SLOT(setVisible(bool))); + } else { + QLayout *layout = m_ui->specialBehaviorLayout->itemAt(i)->layout(); + if (layout) { + for (int j = 0; j < layout->count(); ++j) { + QWidget *widget = layout->itemAt(j)->widget(); + if (widget) { + widget->setVisible(false); + connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), widget, SLOT(setVisible(bool))); + } + } + } + } + } + + m_actionEditWidget->setVisible(false); + m_actionEditWidget->load(); + + connect(m_ui->separateSettingsRadio, SIGNAL(toggled(bool)), m_actionEditWidget, SLOT(setVisible(bool))); + + connect(m_ui->actLikeRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); + connect(m_ui->noSettingsRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); + connect(m_ui->separateSettingsRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); + connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); + connect(m_ui->actLikeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + connect(m_ui->alwaysActionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); + connect(m_ui->alwaysAfterSpin, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); + + connect(m_actionEditWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); +} + +ActivityWidget::~ActivityWidget() +{ + +} + +void ActivityWidget::load() +{ + KConfigGroup activitiesGroup(m_profilesConfig, "Activities"); + KConfigGroup config = activitiesGroup.group(m_activity); + + using namespace PowerDevil::BundledActions; + + QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); + + if (methods.contains(Solid::PowerManagement::SuspendState)) { + m_ui->alwaysActionBox->addItem(KIcon("system-suspend"), + i18n("Sleep"), (uint)SuspendSession::ToRamMode); + } + if (methods.contains(Solid::PowerManagement::HibernateState)) { + m_ui->alwaysActionBox->addItem(KIcon("system-suspend-hibernate"), + i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); + } + m_ui->alwaysActionBox->addItem(KIcon("system-shutdown"), i18n("Shutdown"), (uint)SuspendSession::ShutdownMode); + + m_ui->actLikeComboBox->clear(); + + m_ui->actLikeComboBox->addItem(KIcon("battery-charging"), i18n("PC running on AC power"), "AC"); + m_ui->actLikeComboBox->addItem(KIcon("battery-060"), i18n("PC running on battery power"), "Battery"); + m_ui->actLikeComboBox->addItem(KIcon("battery-low"), i18n("PC running on low battery"), "LowBattery"); + + foreach (const QString &activity, m_activityConsumer->listActivities()) { + if (activity == m_activity) { + continue; + } + + if (activitiesGroup.group(activity).readEntry("mode", "None") == "None" || + activitiesGroup.group(activity).readEntry("mode", "None") == "ActLike") { + continue; + } + + KActivities::Info *info = new KActivities::Info(activity, this); + QString icon = info->icon(); + QString name = i18nc("This is meant to be: Act like activity %1", + "Activity \"%1\"", info->name()); + + m_ui->actLikeComboBox->addItem(KIcon(icon), name, activity); + } + + // Proper loading routine + + if (config.readEntry("mode", QString()) == "ActLike") { + m_ui->actLikeRadio->setChecked(true); + m_ui->actLikeComboBox->setCurrentIndex(m_ui->actLikeComboBox->findData(config.readEntry("actLike", QString()))); + } else if (config.readEntry("mode", QString()) == "SpecialBehavior") { + m_ui->specialBehaviorRadio->setChecked(true); + KConfigGroup behaviorGroup = config.group("SpecialBehavior"); + + m_ui->noShutdownPCBox->setChecked(behaviorGroup.readEntry("noSuspend", false)); + m_ui->noShutdownScreenBox->setChecked(behaviorGroup.readEntry("noScreenManagement", false)); + m_ui->alwaysBox->setChecked(behaviorGroup.readEntry("performAction", false)); + + KConfigGroup actionConfig = behaviorGroup.group("ActionConfig"); + m_ui->alwaysActionBox->setCurrentIndex(m_ui->alwaysActionBox->findData(actionConfig.readEntry("suspendType", 0))); + m_ui->alwaysAfterSpin->setValue(actionConfig.readEntry("idleTime", 600000) / 60 / 1000); + } else if (config.readEntry("mode", QString()) == "SeparateSettings") { + m_ui->separateSettingsRadio->setChecked(true); + + m_actionEditWidget->load(); + } +} + +void ActivityWidget::save() +{ + KConfigGroup activitiesGroup(m_profilesConfig, "Activities"); + KConfigGroup config = activitiesGroup.group(m_activity); + + if (m_ui->actLikeRadio->isChecked()) { + config.writeEntry("mode", "ActLike"); + config.writeEntry("actLike", m_ui->actLikeComboBox->itemData(m_ui->actLikeComboBox->currentIndex()).toString()); + } else if (m_ui->specialBehaviorRadio->isChecked()) { + config.writeEntry("mode", "SpecialBehavior"); + + KConfigGroup behaviorGroup = config.group("SpecialBehavior"); + + behaviorGroup.writeEntry("noSuspend", m_ui->noShutdownPCBox->isChecked()); + behaviorGroup.writeEntry("noScreenManagement", m_ui->noShutdownScreenBox->isChecked()); + behaviorGroup.writeEntry("performAction", m_ui->alwaysBox->isChecked()); + + KConfigGroup actionConfig = behaviorGroup.group("ActionConfig"); + actionConfig.writeEntry("suspendType", m_ui->alwaysActionBox->itemData(m_ui->alwaysActionBox->currentIndex())); + actionConfig.writeEntry("idleTime", m_ui->alwaysAfterSpin->value() * 60 * 1000); + + actionConfig.sync(); + behaviorGroup.sync(); + } else if (m_ui->separateSettingsRadio->isChecked()) { + config.writeEntry("mode", "SeparateSettings"); + m_actionEditWidget->save(); + } else { + config.writeEntry("mode", "None"); + } + + config.sync(); +} + +void ActivityWidget::setChanged() +{ + emit changed(true); +} + + +#include "activitywidget.moc" diff --git a/powerdevil/kcmodule/activities/activitywidget.h b/powerdevil/kcmodule/activities/activitywidget.h new file mode 100644 index 00000000..992029d6 --- /dev/null +++ b/powerdevil/kcmodule/activities/activitywidget.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef ACTIVITYWIDGET_H +#define ACTIVITYWIDGET_H + +#include +#include + +class ActionEditWidget; +namespace KActivities +{ +class Consumer; +} // namespace KActivities + +namespace Ui { +class ActivityWidget; +} + +class ActivityWidget : public QWidget +{ + Q_OBJECT +public: + explicit ActivityWidget(const QString &activity, QWidget *parent = 0); + virtual ~ActivityWidget(); + +public Q_SLOTS: + void load(); + void save(); + + void setChanged(); + +Q_SIGNALS: + void changed(bool changed); + +private: + Ui::ActivityWidget *m_ui; + KSharedConfig::Ptr m_profilesConfig; + QString m_activity; + KActivities::Consumer *m_activityConsumer; + ActionEditWidget* m_actionEditWidget; +}; + +#endif // ACTIVITYWIDGET_H diff --git a/powerdevil/kcmodule/activities/powerdevilactivitiesconfig.desktop b/powerdevil/kcmodule/activities/powerdevilactivitiesconfig.desktop new file mode 100644 index 00000000..b0980312 --- /dev/null +++ b/powerdevil/kcmodule/activities/powerdevilactivitiesconfig.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Exec=kcmshell4 powerdevilactivitiesconfig +Icon=preferences-activities +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/powerdevil/index.html#activity-setting + +X-KDE-Library=kcm_powerdevilactivitiesconfig +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=power-management +X-KDE-Weight=50 + +Name=Activity Settings +Name[bs]=Postavke aktivnosti +Name[ca]=Arranjament d'activitat +Name[ca@valencia]=Arranjament d'activitat +Name[cs]=Nastavení aktivit +Name[da]=Aktivitetsindstillinger +Name[de]=Aktivitäten-Einstellungen +Name[el]=Ρυθμίσεις δραστηριοτήτων +Name[en_GB]=Activity Settings +Name[es]=Preferencias de la actividad +Name[et]=Tegevuse seadistused +Name[eu]=Jarduera-ezarpenak +Name[fi]=Aktiviteettiasetukset +Name[fr]=Configuration des activités +Name[ga]=Socruithe Gníomhaíochta +Name[gl]=Configuración da actividade +Name[he]=הגדרות של פעילות +Name[hu]=Aktivitásjellemzők +Name[ia]=Preferentias de activitate +Name[is]=Virknistillingar +Name[kk]=Істің параметрлері +Name[km]=ការ​កំណត់​សកម្មភាព +Name[ko]=활동 설정 +Name[lt]=Veiklos nustatymai +Name[mr]=कार्यपध्दती संयोजना +Name[nb]=Aktivitetsinnstillinger +Name[nds]=Aktiviteteninstellen +Name[nl]=Instellingen voor activiteiten +Name[pa]=ਐਕਟਵਿਟੀ ਸੈਟਿੰਗ +Name[pl]=Ustawienia działań +Name[pt]=Configuração da Actividade +Name[pt_BR]=Configurações da atividade +Name[ro]=Configurare activități +Name[ru]=Настройка для комнат +Name[sk]=Nastavenie aktivity +Name[sl]=Nastavitve dejavnosti +Name[sr]=Поставке активности +Name[sr@ijekavian]=Поставке активности +Name[sr@ijekavianlatin]=Postavke aktivnosti +Name[sr@latin]=Postavke aktivnosti +Name[sv]=Inställningar av aktiviteter +Name[tr]=Etkinlik Ayarları +Name[uk]=Параметри простору дій +Name[vi]=Thiết lập Hoạt động +Name[x-test]=xxActivity Settingsxx +Name[zh_CN]=活动设置 +Name[zh_TW]=活動設定 + +Comment=Configure per-activity Power Management +Comment[bs]=Konfiguracija po aktivnosti upravljanja napajanjem +Comment[ca]=Configura l'arranjament per activitat de gestió d'energia +Comment[ca@valencia]=Configura l'arranjament per activitat de gestió d'energia +Comment[cs]=Konfigurace správy napájení na činnost +Comment[da]=Indstil strømstyring pr. aktivitet +Comment[de]=Energieprofile pro Aktivität einzeln einrichten +Comment[el]=Διαμόρφωση ανά δραστηριότητα επιλογών διαχείρισης ενέργειας +Comment[en_GB]=Configure per-activity Power Management +Comment[es]=Configurar de las preferencias de la gestión de energía por actividad +Comment[et]=Toitehalduse seadistused tegevuste kaupa +Comment[eu]=Konfiguratu energia-kudeaketa jardueraka +Comment[fi]=Virranhallinnan aktiviteettikohtaiset asetukset +Comment[fr]=Configuration de la gestion d'énergie par activité +Comment[gl]=Configura a xestión da enerxía para cada actividade +Comment[he]=הגדרות צריכת חשמל לפי פעילות +Comment[hu]=Aktivitásonkénti energiakezelési beállítások módosítása +Comment[ia]=Configura gestion de energia per activitate +Comment[is]=Stilla orkustýringu á hverja virkni +Comment[kk]=Әрбір істің қуаттандыру параметрлерін баптау +Comment[km]=កំណត់​រចនាសម្ព័ន្ធក​នៃ​ការ​គ្រប់គ្រង​ថាមពល​ក្នុង​មួយ​សកម្មភាព +Comment[ko]=활동별 전원 관리 설정 +Comment[lt]=Konfigūruoti atskiros veiklos energijos valdymo nustatymus +Comment[mr]=प्रत्येक कार्यपध्दती साठी वीज व्यवस्थापन संयोजीत करा +Comment[nb]=Sett opp strømstyring per aktivitet +Comment[nds]=Stroompleeg för enkelte Aktiviteten instellen +Comment[nl]=Energiebeheer per activiteit instellen +Comment[pa]=ਪ੍ਰਤੀ-ਸਰਗਰਮੀ ਪਾਵਰ ਪਰਬੰਧ ਸੈਟਿੰਗ ਸੰਰਚਨਾ +Comment[pl]=Ustawienia zarządzania energią w zależności od działania +Comment[pt]=Configurar a Gestão de Energia por Actividade +Comment[pt_BR]=Configura o gerenciamento de energia por atividade +Comment[ro]=Configurează gestiunea alimentării per activitate +Comment[ru]=Настройка параметров энергосбережения для комнат +Comment[sk]=Nastaviť nastavenia správy napájania podľa aktivity +Comment[sl]=Nastavi upravljanje z energijo glede na dejavnost +Comment[sr]=Подешавање управљања напајањем према активности +Comment[sr@ijekavian]=Подешавање управљања напајањем према активности +Comment[sr@ijekavianlatin]=Podešavanje upravljanja napajanjem prema aktivnosti +Comment[sr@latin]=Podešavanje upravljanja napajanjem prema aktivnosti +Comment[sv]=Anpassa inställningar av strömhantering per aktivitet +Comment[tr]=Her Etkinlik için Genel Güç Yönetimi Ayarlarını Yapılandır +Comment[uk]=Налаштування окремих параметрів керування живленням простору дій +Comment[vi]=Cấu hình Quản lý năng lượng cho từng Hoạt động +Comment[x-test]=xxConfigure per-activity Power Managementxx +Comment[zh_CN]=配置基于活动的电源管理 +Comment[zh_TW]=設定個別活動的電源管理 + +X-KDE-Keywords=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities +X-KDE-Keywords[bs]=Sistem, Napajanje, Upravljanje napajanjem, energija, laptop, baterija, suspenzija, AC, suspendiraj, hiberniranje, osvljetljenje, perfomanse, kapak, aktivnost, aktivnosti +X-KDE-Keywords[ca]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspendre,hibernació,lluminositat,rendiment,tapa,activitat,activitats +X-KDE-Keywords[ca@valencia]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspendre,hibernació,lluminositat,rendiment,tapa,activitat,activitats +X-KDE-Keywords[da]=system,strøm,strømstyring,energi,laptop,bærbar,batteri,suspension,AC,strømforsyning,suspender,slumre,dvale,lysstyrke,ydelse,låg,aktivitet,aktiviteter +X-KDE-Keywords[de]=system,energie,energieverwaltung,laptop,notebook,akku,batterie,ruhezustand,tiefschlaf,helligkeit,leistung,deckel,aktivität +X-KDE-Keywords[el]=σύστημα,ενέργεια,διαχείριση ενέργειας,ενέργεια,φορητός,μπαταρία,αναστολή,AC,κοίμηση,νάρκη,λαμπρότητα,επιδόσεις,καπάκι,δραστηριότητα,δραστηριότητες +X-KDE-Keywords[en_GB]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities +X-KDE-Keywords[es]=sistema,energía,gestión de energía,energía,portátil,batería,suspensión,AC,suspender,hibernar,brillo,rendimiento,tapa,actividad,actividades +X-KDE-Keywords[et]=süsteem,energia,toide,toitehaldus,sülearvuti,aku,uneseisund,uni,talveuni, heledus,jõudlus,kaas,tegevus,tegevused +X-KDE-Keywords[eu]=sistema,energia,energia-kudeaketa,energia,eramangarria,bateria,egonean,korronte alternoa,egonean uztea,hibernatu,distira,errendimendua,tapa,jarduera,jarduerak +X-KDE-Keywords[fi]=järjestelmä,virta,virranhallinta,energia,kannettava,tietokone,läppäri,akku,lepotila,valmiustila,keskeytä,AC,virtalähde,kirkkaus,suorituskyky,kansi,aktiviteetti,aktiviteetit +X-KDE-Keywords[fr]=système, alimentation, gestion énergétique, énergie, portable, batterie, suspension, AC, suspendre, hiberner, luminosité, performance, capot, activité, activités +X-KDE-Keywords[gl]=sistema,enerxía,xestión da enerxía, xestión enerxética,carga,portátil,batería, suspender,corrente,hibernar,durmir,brillo,rendemento,tapa,actividade +X-KDE-Keywords[hu]=rendszer,energia,energiakezelés,energia,laptop,akkumulátor,AC,felfüggesztés,hibernálás,fényerő,teljesítmény,fedél,aktivitás,aktivitások +X-KDE-Keywords[ia]=systema,potentia,gestion de potentia,energia,laptop,batteria,suspension,CA,suspende,hiberna,brillantia,prestation,coperculo,activitate,activitates +X-KDE-Keywords[kk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities +X-KDE-Keywords[km]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities +X-KDE-Keywords[ko]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,시스템,전원,전원 관리,에너지,노트북,배터리,어댑터,절전,대기 모드,대기,최대 절전,최대 절전 모드,밝기,성능,덮개,상판,활동 +X-KDE-Keywords[mr]=प्रणाली, वीज, वीज व्यवस्थापन, ऊर्जा, लैपटॉप, बॅटरी, अकार्यक्षम, AC, अकार्यक्षम, हायबरनेट, प्रखरता, लिड, कार्य +X-KDE-Keywords[nb]=system,strøm,strømstyring,energi,bærbar,batteri,hvilemodus,AC,hvile,dvale,lysstyrke,ytelse,lokk,aktivitet,aktiviteter +X-KDE-Keywords[nds]=Systeem,Stroom,Stroompleeg,Energie,Klappreekner,Batterie,utsetten,AC,Wesselstroom,infreren,Helligkeit,Leisten,Aktiviteet,Aktiviteten +X-KDE-Keywords[nl]=systeem,energie,energiebeheer,laptop,batterij,accu,suspension,AC,onderbreken,slapen,helderheid,prestaties,deksel,activiteit,activiteiten +X-KDE-Keywords[pl]=system,moc,zarządzanie energią,energia,laptop,bateria,wstrzymanie,AC,wstrzymaj,hibernuj,jasność,wydajność,pokrywka,działanie,działania +X-KDE-Keywords[pt]=sistema,energia,gestão de energia,portátil,bateria,suspensão,AC,suspender,hibernar,brilho,performance,tampo,actividade,actividades +X-KDE-Keywords[pt_BR]=sistema,energia,gerenciamento de energia,energia,portátil,laptop,notebook,bateria,suspensão,AC,suspender,hibernar,brilho,desempenho,tampa,atividade,atividades +X-KDE-Keywords[ru]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,системное,питание,управление питанием,энергопотребление,ноутбук,батарея,спящий режим,гибернация,ждущий режим,яркость,производительность,крышка,комната,комнаты +X-KDE-Keywords[sk]=systém,napájanie,správa napájanie,energia,laptop,batéria,uspanie,AC,uspať,hibernovať,jas,výkon,kryt,aktivita,aktivity +X-KDE-Keywords[sl]=sistem,energija,upravljanje z energijo,prenosnik,prenosni računalnik,baterija,akumulator,pripravljenost,mirovanje,električno omrežje,svetlost,zmogljivost,pokrov,dejavnost,dejavnosti,napajanje +X-KDE-Keywords[sr]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац,активност +X-KDE-Keywords[sr@ijekavian]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац,активност +X-KDE-Keywords[sr@ijekavianlatin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac,aktivnost +X-KDE-Keywords[sr@latin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac,aktivnost +X-KDE-Keywords[sv]=system,kraft,krafthantering,energi,bärbar dator,batteri,viloläge,AC,gå till viloläge,dvala,ljusstyrka,prestanda,lock,aktivitet,aktiviteter +X-KDE-Keywords[tr]=sistem,güç,güç yönetimi,enerji,dizüstü,pil,askıya alma,Adaptör,uyku kipi,hazırda bekletme,parlaklık,performans,başarım,dizüstü kapağı,ekran parlaklığı,etkinlik,etkinlikler +X-KDE-Keywords[uk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,система,живлення,мережа,струм,керування,енергія,ноутбук,акумулятор,батарея,батареї,присипляння,призупинення,призупинка,яскравість,швидкодія,кришка,кришки,простір,дій,простори,активність +X-KDE-Keywords[x-test]=xxsystem,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activitiesxx +X-KDE-Keywords[zh_CN]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities,系统,电源,电源管理,能源,笔记本,电池,休眠,睡眠,交流,亮度,性能,活动 +X-KDE-Keywords[zh_TW]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,activity,activities diff --git a/powerdevil/kcmodule/common/CMakeLists.txt b/powerdevil/kcmodule/common/CMakeLists.txt new file mode 100644 index 00000000..be16362b --- /dev/null +++ b/powerdevil/kcmodule/common/CMakeLists.txt @@ -0,0 +1,19 @@ + +set( powerdevil_config_common_private_SRCS + actionconfigwidget.cpp + actioneditwidget.cpp + ErrorOverlay.cpp +) + +kde4_add_library(powerdevilconfigcommonprivate SHARED ${powerdevil_config_common_private_SRCS}) + +target_link_libraries(powerdevilconfigcommonprivate + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBRARY} + powerdevilcore + powerdevilui +) + +set_target_properties(powerdevilconfigcommonprivate PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION}) + +install( TARGETS powerdevilconfigcommonprivate ${INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/powerdevil/kcmodule/common/ErrorOverlay.cpp b/powerdevil/kcmodule/common/ErrorOverlay.cpp new file mode 100644 index 00000000..732e9962 --- /dev/null +++ b/powerdevil/kcmodule/common/ErrorOverlay.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "ErrorOverlay.h" + +#include +#include +#include + +#include +#include +#include + +static const KCatalogLoader loader("libpowerdevilcommonconfig"); + +ErrorOverlay::ErrorOverlay(QWidget *baseWidget, const QString &details, QWidget *parent) : + QWidget(parent ? parent : baseWidget->window()), + m_BaseWidget(baseWidget) +{ + // Build the UI + QVBoxLayout *layout = new QVBoxLayout; + layout->setSpacing(10); + + QLabel *pixmap = new QLabel(); + pixmap->setPixmap(KIcon("dialog-error").pixmap(64)); + + QLabel *message = new QLabel(i18n("Power Management configuration module could not be loaded.\n%1", details)); + + pixmap->setAlignment(Qt::AlignHCenter); + message->setAlignment(Qt::AlignHCenter); + + layout->addStretch(); + layout->addWidget(pixmap); + layout->addWidget(message); + layout->addStretch(); + + setLayout(layout); + + // Draw the transparent overlay background + QPalette p = palette(); + p.setColor(backgroundRole(), QColor(0, 0, 0, 128)); + p.setColor(foregroundRole(), Qt::white); + setPalette(p); + setAutoFillBackground(true); + + m_BaseWidget->installEventFilter(this); + + reposition(); +} + +ErrorOverlay::~ErrorOverlay() +{ +} + +void ErrorOverlay::reposition() +{ + if (!m_BaseWidget) { + return; + } + + // reparent to the current top level widget of the base widget if needed + // needed eg. in dock widgets + if (parentWidget() != m_BaseWidget->window()) { + setParent(m_BaseWidget->window()); + } + + // follow base widget visibility + // needed eg. in tab widgets + if (!m_BaseWidget->isVisible()) { + hide(); + return; + } + + show(); + + // follow position changes + const QPoint topLevelPos = m_BaseWidget->mapTo(window(), QPoint(0, 0)); + const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos); + move(parentPos); + + // follow size changes + // TODO: hide/scale icon if we don't have enough space + resize(m_BaseWidget->size()); +} + +bool ErrorOverlay::eventFilter(QObject * object, QEvent * event) +{ + if (object == m_BaseWidget && + (event->type() == QEvent::Move || event->type() == QEvent::Resize || + event->type() == QEvent::Show || event->type() == QEvent::Hide || + event->type() == QEvent::ParentChange)) { + reposition(); + } + return QWidget::eventFilter(object, event); +} + +#include "ErrorOverlay.moc" diff --git a/powerdevil/kcmodule/common/ErrorOverlay.h b/powerdevil/kcmodule/common/ErrorOverlay.h new file mode 100644 index 00000000..8081e758 --- /dev/null +++ b/powerdevil/kcmodule/common/ErrorOverlay.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef ERROROVERLAY_H +#define ERROROVERLAY_H + +#include + +#include + +class KDE_EXPORT ErrorOverlay : public QWidget +{ + Q_OBJECT +public: + explicit ErrorOverlay(QWidget *baseWidget, const QString &details, QWidget *parent = 0); + virtual ~ErrorOverlay(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + void reposition(); + +private: + QWidget *m_BaseWidget; +}; + +#endif // ERROROVERLAY_H diff --git a/powerdevil/kcmodule/common/Messages.sh b/powerdevil/kcmodule/common/Messages.sh new file mode 100644 index 00000000..e982c361 --- /dev/null +++ b/powerdevil/kcmodule/common/Messages.sh @@ -0,0 +1,2 @@ +#! /bin/sh +$XGETTEXT `find -name \*.cpp -o -name \*.h` -o $podir/libpowerdevilcommonconfig.pot diff --git a/powerdevil/kcmodule/common/actionconfigwidget.cpp b/powerdevil/kcmodule/common/actionconfigwidget.cpp new file mode 100644 index 00000000..1f291b62 --- /dev/null +++ b/powerdevil/kcmodule/common/actionconfigwidget.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sebastian Kugler * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "actionconfigwidget.h" + +#include +#include +#include +#include +#include +#include + +ActionConfigWidget::ActionConfigWidget(QWidget* parent) : QWidget(parent) +{ + m_gridLayout = new QGridLayout(this); + /* + QLabel* l = new QLabel( this ); + l->setText( "Hello World!" ); + + m_gridLayout->addWidget(l, 0, 0); + */ +} + +ActionConfigWidget::~ActionConfigWidget() +{} + + +void ActionConfigWidget::addWidgets(QList > configMap) +{ + int row = m_gridLayout->rowCount(); + row++; + + QCheckBox* currentSectionCheckbox = 0; + /* + //Clean the values + QList::const_iterator it; + for (it = list.constBegin(); it != list.constEnd(); ++it) { + QString tempString = *it; + tempString = tempString.trimmed(); + tempString = tempString.mid(1, tempString.length()-2); + versionList.append(tempString); + } + */ + QList >::const_iterator it; + for (it = configMap.constBegin(); it != configMap.constEnd(); ++it) { + //foreach (QPair line, configMap) { + QPair line = *it; + if (line.first.isEmpty()) { + // A title checkbox + currentSectionCheckbox = qobject_cast(line.second); + currentSectionCheckbox->setChecked(true); + currentSectionCheckbox->setStyleSheet("font-weight: bold;"); + m_gridLayout->addWidget(line.second, row, 0, 1, 3); + } else { + // connect enabled / disabled + QLabel* label = new QLabel(this); + label->setText(line.first); + + m_gridLayout->addItem(new QSpacerItem(50 ,3), row, 0); + m_gridLayout->addWidget(label, row, 1, Qt::AlignRight); + m_gridLayout->addWidget(line.second, row, 2); + + connect(currentSectionCheckbox, SIGNAL(toggled(bool)), + label, SLOT(setEnabled(bool))); + connect(currentSectionCheckbox, SIGNAL(toggled(bool)), + line.second, SLOT(setEnabled(bool))); + } + row++; + } +} + +#include "actionconfigwidget.moc" diff --git a/powerdevil/kcmodule/common/actionconfigwidget.h b/powerdevil/kcmodule/common/actionconfigwidget.h new file mode 100644 index 00000000..a8c72a10 --- /dev/null +++ b/powerdevil/kcmodule/common/actionconfigwidget.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sebastian Kugler * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef ACTIONCONFIG_H +#define ACTIONCONFIG_H + +#include +#include + +#include +#include +#include + +#include + +class KDE_EXPORT ActionConfigWidget : public QWidget +{ +Q_OBJECT +public: + ActionConfigWidget(QWidget* parent); + ~ActionConfigWidget(); + + void addWidgets(QList > configMap); + +private: + QGridLayout* m_gridLayout; +}; + +#endif // ActionConfigWidget_H diff --git a/powerdevil/kcmodule/common/actioneditwidget.cpp b/powerdevil/kcmodule/common/actioneditwidget.cpp new file mode 100644 index 00000000..116564fc --- /dev/null +++ b/powerdevil/kcmodule/common/actioneditwidget.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + * Copyright (C) 2008-2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "actioneditwidget.h" + +#include "actionconfigwidget.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +ActionEditWidget::ActionEditWidget(const QString &configName, QWidget *parent) + : QWidget(parent) + , m_configName(configName) +{ + m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig); + + ActionConfigWidget *actionConfigWidget = new ActionConfigWidget(0); + QMap< int, QList > > widgets; + + // Load all the services + KService::List offers = KServiceTypeTrader::self()->query("PowerDevil/Action", "(Type == 'Service')"); + + foreach (const KService::Ptr &offer, offers) { + // Does it have a runtime requirement? + if (offer->property("X-KDE-PowerDevil-Action-HasRuntimeRequirement", QVariant::Bool).toBool()) { + kDebug() << offer->name() << " has a runtime requirement"; + + QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "isActionSupported"); + call.setArguments(QVariantList() << offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String)); + QDBusPendingReply< bool > reply = QDBusConnection::sessionBus().asyncCall(call); + reply.waitForFinished(); + + if (reply.isValid()) { + if (!reply.value()) { + kDebug() << "The action " << offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String) << " appears not to be supported by the core."; + continue; + } + } else { + kDebug() << "There was a problem in contacting DBus!! Assuming the action is ok."; + } + } + + //try to load the specified library + KPluginFactory *factory = KPluginLoader(offer->property("X-KDE-PowerDevil-Action-UIComponentLibrary", + QVariant::String).toString()).factory(); + + if (!factory) { + kError() << "KPluginFactory could not load the plugin:" << offer->property("X-KDE-PowerDevil-Action-UIComponentLibrary", + QVariant::String).toString(); + continue; + } + + PowerDevil::ActionConfig *actionConfig = factory->create(); + if (!actionConfig) { + kError() << "KPluginFactory could not load the plugin:" << offer->property("X-KDE-PowerDevil-Action-UIComponentLibrary", + QVariant::String).toString(); + continue; + } + + connect(actionConfig, SIGNAL(changed()), this, SLOT(onChanged())); + + QCheckBox *checkbox = new QCheckBox(offer->name()); + if (!offer->icon().isEmpty()) { + checkbox->setIcon(KIcon(offer->icon())); + } + connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(onChanged())); + m_actionsHash.insert(offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String).toString(), checkbox); + m_actionsConfigHash.insert(offer->property("X-KDE-PowerDevil-Action-ID", QVariant::String).toString(), actionConfig); + + QList > offerWidgets = actionConfig->buildUi(); + offerWidgets.prepend(qMakePair(QString(), checkbox)); + widgets.insertMulti(100 - offer->property("X-KDE-PowerDevil-Action-ConfigPriority", QVariant::Int).toInt(), + offerWidgets); + } + + for (QMap< int, QList > >::const_iterator i = widgets.constBegin(); i != widgets.constEnd(); ++i) { + actionConfigWidget->addWidgets(i.value()); + } + + QVBoxLayout *lay = new QVBoxLayout; + lay->addWidget(actionConfigWidget); + lay->addStretch(); + setLayout(lay); +} + +ActionEditWidget::~ActionEditWidget() +{ + +} + +void ActionEditWidget::load() +{ + KConfigGroup group = configGroup(); + + kDebug() << m_profilesConfig.data()->entryMap().keys(); + + if (!group.isValid()) { + return; + } + kDebug() << "Ok, KConfigGroup ready" << group.entryMap().keys(); + + // Iterate over the possible actions + for (QHash< QString, QCheckBox* >::const_iterator i = m_actionsHash.constBegin(); i != m_actionsHash.constEnd(); ++i) { + i.value()->setChecked(group.groupList().contains(i.key())); + + KConfigGroup actionGroup = group.group(i.key()); + m_actionsConfigHash[i.key()]->setConfigGroup(actionGroup); + m_actionsConfigHash[i.key()]->load(); + } + + emit changed(false); +} + +void ActionEditWidget::save() +{ + KConfigGroup group = configGroup(); + + if (!group.isValid()) { + kDebug() << "Could not perform a save operation, group is not valid!"; + return; + } + + // Iterate over the possible actions + for (QHash< QString, QCheckBox* >::const_iterator i = m_actionsHash.constBegin(); i != m_actionsHash.constEnd(); ++i) { + if (i.value()->isChecked()) { + // Perform the actual save + m_actionsConfigHash[i.key()]->save(); + } else { + // Erase the group + group.deleteGroup(i.key()); + } + } + + group.sync(); + + // After saving, reload the config to make sure we'll pick up changes. + m_profilesConfig.data()->reparseConfiguration(); + + emit changed(false); +} + +void ActionEditWidget::onChanged() +{ + emit changed(true); +} + +QString ActionEditWidget::configName() const +{ + return m_configName; +} + +KConfigGroup ActionEditWidget::configGroup() +{ + if (!m_configName.contains('/')) { + return KConfigGroup(m_profilesConfig, m_configName); + } else { + QStringList names = m_configName.split('/'); + KConfigGroup retgroup(m_profilesConfig, names.first()); + + QStringList::const_iterator i = names.constBegin(); + ++i; + + while (i != names.constEnd()) { + retgroup = retgroup.group(*i); + ++i; + } + + return retgroup; + } +} + +#include "actioneditwidget.moc" diff --git a/powerdevil/kcmodule/common/actioneditwidget.h b/powerdevil/kcmodule/common/actioneditwidget.h new file mode 100644 index 00000000..7fcde8fc --- /dev/null +++ b/powerdevil/kcmodule/common/actioneditwidget.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2008-2011 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef ACTIONEDITWIDGET_H +#define ACTIONEDITWIDGET_H + +#include + +#include + +#include + +namespace PowerDevil +{ +class ActionConfig; +} + +class QCheckBox; +class KConfigGroup; + +class KDE_EXPORT ActionEditWidget : public QWidget +{ + Q_OBJECT +public: + explicit ActionEditWidget(const QString &configName, QWidget *parent = 0); + virtual ~ActionEditWidget(); + + QString configName() const; + +public Q_SLOTS: + void load(); + void save(); + +private Q_SLOTS: + void onChanged(); + +Q_SIGNALS: + void changed(bool changed); + +private: + KConfigGroup configGroup(); + +private: + QString m_configName; + KSharedConfig::Ptr m_profilesConfig; + QHash< QString, QCheckBox* > m_actionsHash; + QHash< QString, PowerDevil::ActionConfig* > m_actionsConfigHash; +}; + +#endif // ACTIONEDITWIDGET_H diff --git a/powerdevil/kcmodule/global/CMakeLists.txt b/powerdevil/kcmodule/global/CMakeLists.txt new file mode 100644 index 00000000..0c72dc65 --- /dev/null +++ b/powerdevil/kcmodule/global/CMakeLists.txt @@ -0,0 +1,23 @@ + +set( kcm_powerdevil_global_SRCS + GeneralPage.cpp +) + +kde4_add_ui_files(kcm_powerdevil_global_SRCS + generalPage.ui) + +kde4_add_kcfg_files(kcm_powerdevil_global_SRCS ../../PowerDevilSettings.kcfgc) + +kde4_add_plugin(kcm_powerdevilglobalconfig ${kcm_powerdevil_global_SRCS}) + +target_link_libraries(kcm_powerdevilglobalconfig + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBRARY} + ${KDE4_KIO_LIBS} + ${KDE4_SOLID_LIBS} + ${KDE4_KNOTIFYCONFIG_LIBRARY} + powerdevilconfigcommonprivate +) + +install(TARGETS kcm_powerdevilglobalconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) +install( FILES powerdevilglobalconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/powerdevil/kcmodule/global/GeneralPage.cpp b/powerdevil/kcmodule/global/GeneralPage.cpp new file mode 100644 index 00000000..fabeae5f --- /dev/null +++ b/powerdevil/kcmodule/global/GeneralPage.cpp @@ -0,0 +1,214 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "GeneralPage.h" + +#include "ErrorOverlay.h" +#include "PowerDevilSettings.h" + +#include "daemon/actions/bundled/suspendsession.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilGeneralKCMFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(PowerDevilGeneralKCMFactory("powerdevilglobalconfig","powerdevil")) + +typedef QMap< QString, QString > StringStringMap; +Q_DECLARE_METATYPE(StringStringMap) + +GeneralPage::GeneralPage(QWidget *parent, const QVariantList &args) + : KCModule(PowerDevilGeneralKCMFactory::componentData(), parent, args) +{ + qDBusRegisterMetaType< StringStringMap >(); + + setButtons(Apply | Help); + + KAboutData *about = + new KAboutData("powerdevilglobalconfig", "powerdevilglobalconfig", ki18n("Global Power Management Configuration"), + "", ki18n("A global power management configurator for KDE Power Management System"), + KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), + ki18n("From this module, you can configure the main Power Management daemon, assign profiles to " + "states, and do some advanced fine tuning on battery handling")); + + about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", + "http://drfav.wordpress.com"); + + setAboutData(about); + + setupUi(this); + + fillUi(); + + QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForRegistration | + QDBusServiceWatcher::WatchForUnregistration, + this); + + connect(watcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); + connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onServiceUnregistered(QString))); + + if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + onServiceRegistered("org.kde.Solid.PowerManagement"); + } else { + onServiceUnregistered("org.kde.Solid.PowerManagement"); + } +} + +GeneralPage::~GeneralPage() +{ +} + +void GeneralPage::fillUi() +{ + bool hasBattery = false; + + foreach(const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { + const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); + if(b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery) { + hasBattery = true; + break; + } + } + + eventsIconLabel->setPixmap(KIcon("preferences-desktop-notification").pixmap(24)); + batteryLevelsIconLabel->setPixmap(KIcon("battery").pixmap(24)); + + QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); + + BatteryCriticalCombo->addItem(KIcon("dialog-cancel"), i18n("Do nothing"), PowerDevil::BundledActions::SuspendSession::None); + if (methods.contains(Solid::PowerManagement::SuspendState)) { + BatteryCriticalCombo->addItem(KIcon("system-suspend"), i18n("Sleep"), PowerDevil::BundledActions::SuspendSession::ToRamMode); + } + if (methods.contains(Solid::PowerManagement::HibernateState)) { + BatteryCriticalCombo->addItem(KIcon("system-suspend-hibernate"), i18n("Hibernate"), PowerDevil::BundledActions::SuspendSession::ToDiskMode); + } + BatteryCriticalCombo->addItem(KIcon("system-shutdown"), i18n("Shutdown"), PowerDevil::BundledActions::SuspendSession::ShutdownMode); + + notificationsButton->setIcon(KIcon("preferences-desktop-notification")); + + // modified fields... + + connect(lockScreenOnResume, SIGNAL(stateChanged(int)), SLOT(changed())); + connect(doNotInhibitLid, SIGNAL(stateChanged(int)), SLOT(changed())); + + connect(notificationsButton, SIGNAL(clicked()), SLOT(configureNotifications())); + + connect(lowSpin, SIGNAL(valueChanged(int)), SLOT(changed())); + connect(criticalSpin, SIGNAL(valueChanged(int)), SLOT(changed())); + + connect(BatteryCriticalCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed())); + + // Disable stuff, eventually + if (!hasBattery) { + batteryLevelsIconLabel->hide(); + batteryLevelsLabel->hide(); + + BatteryCriticalLabel->hide(); + BatteryCriticalCombo->hide(); + lowLabel->hide(); + lowSpin->hide(); + criticalLabel->hide(); + criticalSpin->hide(); + } +} + +void GeneralPage::load() +{ + lockScreenOnResume->setChecked(PowerDevilSettings::configLockScreen()); + doNotInhibitLid->setChecked(PowerDevilSettings::doNotInhibitOnLidClose()); + + lowSpin->setValue(PowerDevilSettings::batteryLowLevel()); + criticalSpin->setValue(PowerDevilSettings::batteryCriticalLevel()); + + BatteryCriticalCombo->setCurrentIndex(BatteryCriticalCombo->findData(PowerDevilSettings::batteryCriticalAction())); +} + +void GeneralPage::configureNotifications() +{ + KNotifyConfigWidget::configure(this, "powerdevil"); +} + +void GeneralPage::save() +{ + PowerDevilSettings::setConfigLockScreen(lockScreenOnResume->isChecked()); + PowerDevilSettings::setDoNotInhibitOnLidClose(doNotInhibitLid->isChecked()); + + PowerDevilSettings::setBatteryLowLevel(lowSpin->value()); + PowerDevilSettings::setBatteryCriticalLevel(criticalSpin->value()); + + PowerDevilSettings::setBatteryCriticalAction(BatteryCriticalCombo->itemData(BatteryCriticalCombo->currentIndex()).toInt()); + + PowerDevilSettings::self()->writeConfig(); + + // Notify Daemon + QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "refreshStatus"); + + // Perform call + QDBusConnection::sessionBus().asyncCall(call); + + // And now we are set with no change + emit changed(false); +} + +void GeneralPage::defaults() +{ + KCModule::defaults(); +} + +void GeneralPage::onServiceRegistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + } +} + +void GeneralPage::onServiceUnregistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + } + + m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running.\n" + "This can be solved by starting or scheduling it inside \"Startup and Shutdown\""), + this); +} + +#include "GeneralPage.moc" diff --git a/powerdevil/kcmodule/global/GeneralPage.h b/powerdevil/kcmodule/global/GeneralPage.h new file mode 100644 index 00000000..a34d54f1 --- /dev/null +++ b/powerdevil/kcmodule/global/GeneralPage.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef GENERALPAGE_H +#define GENERALPAGE_H + +#include + +#include "ui_generalPage.h" + +class ErrorOverlay; +class GeneralPage : public KCModule, private Ui_generalPage +{ + Q_OBJECT + +public: + GeneralPage(QWidget *parent, const QVariantList &args); + virtual ~GeneralPage(); + void fillUi(); + + void load(); + void save(); + virtual void defaults(); + +private slots: + void configureNotifications(); + void onServiceRegistered(const QString &service); + void onServiceUnregistered(const QString &service); + +private: + QWeakPointer< ErrorOverlay > m_errorOverlay; +}; + +#endif /* GENERALPAGE_H */ diff --git a/powerdevil/kcmodule/global/Messages.sh b/powerdevil/kcmodule/global/Messages.sh new file mode 100755 index 00000000..e67d1b5e --- /dev/null +++ b/powerdevil/kcmodule/global/Messages.sh @@ -0,0 +1,5 @@ +#! /bin/sh +$EXTRACTRC `find -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp || exit 11 +$XGETTEXT `find -name \*.cpp -o -name \*.h` -o $podir/powerdevilglobalconfig.pot +rm -f rc.cpp + diff --git a/powerdevil/kcmodule/global/generalPage.ui b/powerdevil/kcmodule/global/generalPage.ui new file mode 100644 index 00000000..798b1ee6 --- /dev/null +++ b/powerdevil/kcmodule/global/generalPage.ui @@ -0,0 +1,301 @@ + + + generalPage + + + + 0 + 0 + 761 + 436 + + + + + + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + + + + + <b>Battery levels</b> + + + + + + + + + QFormLayout::ExpandingFieldsGrow + + + + + Battery is at low level at + + + lowSpin + + + + + + + + 100 + 16777215 + + + + Low battery level + + + Battery will be considered low when it reaches this level + + + % + + + 100 + + + + + + + Battery is at critical level at + + + criticalSpin + + + + + + + + 100 + 16777215 + + + + Critical battery level + + + Battery will be considered critical when it reaches this level + + + % + + + 100 + + + + + + + When battery is at critical level + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + BatteryCriticalCombo + + + + + + + + 300 + 16777215 + + + + + + + + + + 4 + + + + + + 24 + 24 + + + + + 16 + 16777215 + + + + + + + + + + + <b>Events</b> + + + + + + + + + 30 + + + + + Lock screen on resume + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lockScreenOnResume + + + + + + + Locks screen when waking up from suspension + + + + + + You will be asked for a password when resuming from sleep state + + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Configure Notifications... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + When this option is selected, applications will not be allowed to inhibit sleep when the lid is closed + + + When this option is selected, applications will not be allowed to inhibit sleep when the lid is closed + + + Never prevent an action on lid close + + + + + + + When this option is selected, applications will not be allowed to inhibit sleep when the lid is closed + + + When this option is selected, applications will not be allowed to inhibit sleep when the lid is closed + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + KComboBox + QComboBox +
    kcombobox.h
    +
    + + KIntSpinBox + QSpinBox +
    knuminput.h
    +
    +
    + + +
    diff --git a/powerdevil/kcmodule/global/powerdevilglobalconfig.desktop b/powerdevil/kcmodule/global/powerdevilglobalconfig.desktop new file mode 100644 index 00000000..011dbcac --- /dev/null +++ b/powerdevil/kcmodule/global/powerdevilglobalconfig.desktop @@ -0,0 +1,148 @@ +[Desktop Entry] +Exec=kcmshell4 powerdevilglobalconfig +Icon=preferences-other +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/powerdevil/index.html#advanced-settings + +X-KDE-Library=kcm_powerdevilglobalconfig +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=power-management +X-KDE-Weight=99 + +Name=Advanced Settings +Name[bs]=Napredne postavke +Name[ca]=Arranjament avançat +Name[ca@valencia]=Arranjament avançat +Name[cs]=Pokročilá nastavení +Name[da]=Avancerede indstillinger +Name[de]=Erweiterte Einstellungen +Name[el]=Προχωρημένες ρυθμίσεις +Name[en_GB]=Advanced Settings +Name[es]=Preferencias avanzadas +Name[et]=Muud seadistused +Name[eu]=Ezarpen aurreratuak +Name[fi]=Lisäasetukset +Name[fr]=Configuration avancée +Name[ga]=Ardsocruithe +Name[gl]=Configuración avanzada +Name[he]=הגדרות מתקדמות +Name[hu]=Speciális beállítások +Name[ia]=Preferentias Avantiate +Name[is]=Ítarlegar stillingar +Name[kk]=Жетелеп баптау +Name[km]=ការ​កំណត់​​កម្រិត​ខ្ពស់ +Name[ko]=고급 설정 +Name[lt]=Išsamesni nustatymai +Name[mr]=प्रगत संयोजना +Name[nb]=Avanserte innstillinger +Name[nds]=Verwiedert Instellen +Name[nl]=Geavanceerde instellingen +Name[pa]=ਤਕਨੀਕੀ ਸੈਟਿੰਗ +Name[pl]=Ustawienia zaawansowane +Name[pt]=Configuração Avançada +Name[pt_BR]=Configurações avançadas +Name[ro]=Configurări avansate +Name[ru]=Дополнительные параметры +Name[sk]=Pokročilé nastavenia +Name[sl]=Napredne nastavitve +Name[sr]=Напредне поставке +Name[sr@ijekavian]=Напредне поставке +Name[sr@ijekavianlatin]=Napredne postavke +Name[sr@latin]=Napredne postavke +Name[sv]=Avancerade inställningar +Name[tr]=Gelişmiş ayarlar +Name[uk]=Додаткові параметри +Name[vi]=Thiết lập nâng cao +Name[x-test]=xxAdvanced Settingsxx +Name[zh_CN]=高级设置 +Name[zh_TW]=進階設定 + +Comment=Configure Advanced Power Management Settings +Comment[bs]=Napredno podešavanje i upravljanje napajanjem +Comment[ca]=Configura l'arranjament avançat de gestió d'energia +Comment[ca@valencia]=Configura l'arranjament avançat de gestió d'energia +Comment[cs]=Nastavení pokročilého nastavení správy napájení +Comment[da]=Indstil avanceret strømstyring +Comment[de]=Erweiterte Energieprofile einrichten +Comment[el]=Διαμόρφωση προχωρημένων επιλογών διαχείρισης ενέργειας +Comment[en_GB]=Configure Advanced Power Management Settings +Comment[es]=Configurar las preferencias avanzadas de la gestión de energía +Comment[et]=Toitehalduse muud seadistused +Comment[eu]=Konfiguratu energia kudeatzeko ezarpen aurreratuak +Comment[fi]=Virranhallinnan lisäasetukset +Comment[fr]=Configuration avancée de la gestion d'énergie +Comment[ga]=Cumraigh Ardsocruithe Bhainisteoireacht Cumhachta +Comment[gl]=Configura a xestión avanzada da enerxía +Comment[he]=הגדרות מתקדמות של חיסכון בצריכת חשמל +Comment[hu]=Speciális energiakezelési beállítások módosítása +Comment[ia]=Configura preferentias avantiate de gestion de energia +Comment[is]=Stilla ítarlegar orkustillingar +Comment[kk]=Қуаттандыруның жетелеген параметрлерін баптау +Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​នៃ​ការ​កំណត់​ការ​គ្រប់គ្រង​ថាមពល +Comment[ko]=고급 전원 관리 설정 +Comment[lt]=Konfigūruoti išsamesnius energijos valdymo nustatymus +Comment[mr]=प्रगत वीज व्यवस्थापन संयोजीत करा +Comment[nb]=Sett avanserte strømstyringsinnstillinger +Comment[nds]=Verwiedert Stroompleeginstellen +Comment[nl]=Instellingen voor geavanceerd energiebeheer configureren +Comment[pa]=ਤਕਨੀਕੀ ਪਾਵਰ ਪਰਬੰਧ ਸੈਟਿੰਗ ਸੰਰਚਨਾ +Comment[pl]=Ustawienia zaawansowane zarządzania energią +Comment[pt]=Configurar a Gestão de Energia Avançada +Comment[pt_BR]=Configura as opções avançadas de gerenciamento de energia +Comment[ro]=Configurează opțiunile avansate de gestiune a alimentării +Comment[ru]=Настройка дополнительных параметров энергосбережения +Comment[sk]=Nastaviť nastavenia pokročilej správy napájania +Comment[sl]=Nastavi napredno upravljanje z energijo +Comment[sr]=Подешавање напредних поставки за управљање напајањем +Comment[sr@ijekavian]=Подешавање напредних поставки за управљање напајањем +Comment[sr@ijekavianlatin]=Podešavanje naprednih postavki za upravljanje napajanjem +Comment[sr@latin]=Podešavanje naprednih postavki za upravljanje napajanjem +Comment[sv]=Anpassa avancerade inställningar av strömhantering +Comment[tr]=Gelişmiş Güç Yönetimi Ayarlarını Yapılandır +Comment[uk]=Налаштування додаткових параметрів керування живленням +Comment[vi]=Cấu hình các thiết lập cho Quản lý năng lượng nâng cao +Comment[x-test]=xxConfigure Advanced Power Management Settingsxx +Comment[zh_CN]=配置高级电源管理设置 +Comment[zh_TW]=設定進階電源管理 + +X-KDE-Keywords=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[bs]=Sistem, Napajanje, Upravljanje napajanjem, energija, laptop, baterija, suspenzija, AC, suspendiraj, hiberniranje, osvljetljenje, kapak, +X-KDE-Keywords[ca]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspèn,hiberna,lluminositat,rendiment,tapa +X-KDE-Keywords[ca@valencia]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspèn,hiberna,lluminositat,rendiment,tapa +X-KDE-Keywords[da]=system,strøm,strømstyring,energi,laptop,bærbar,batteri,suspension,AC,strømforsyning,suspender,slumre,dvale,lysstyrke,ydelse,låg +X-KDE-Keywords[de]=system,energie,energieverwaltung,laptop,notebook,akku,batterie,ruhezustand,tiefschlaf,helligkeit,leistung,deckel +X-KDE-Keywords[el]=σύστημα,ενέργεια,διαχείριση ενέργειας,ενέργεια,φορητός,μπαταρία,αναστολή,AC,κοίμηση,νάρκη,λαμπρότητα,επιδόσεις,καπάκι +X-KDE-Keywords[en_GB]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[es]=sistema,energía,gestión de energía,energía,portátil,batería,suspensión,AC,suspender,hibernar,brillo,rendimiento,tapa +X-KDE-Keywords[et]=süsteem,energia,toide,toitehaldus,sülearvuti,aku,uneseisund,uni,talveuni, heledus,jõudlus,kaas +X-KDE-Keywords[eu]=sistema,energia,energia-kudeaketa,energia,eramangarria,bateria,egonean,korronte alternoa,egonean uztea,hibernatu,distira,errendimendua,tapa +X-KDE-Keywords[fi]=järjestelmä,virta,virranhallinta,energia,kannettava,tietokone,läppäri,akku,lepotila,valmiustila,AC,virtalähde,keskeytä,kirkkaus,suorituskyky,kansi +X-KDE-Keywords[fr]=système, alimentation, gestion énergétique, énergie, portable, batterie, suspension, AC, suspendre, hiberner, luminosité, performance, capot +X-KDE-Keywords[gl]=sistema,enerxía,xestión da enerxía, xestión enerxética,carga,portátil,batería, suspender,corrente,hibernar,durmir,brillo,rendemento,tapa +X-KDE-Keywords[hu]=rendszer,energia,energiakezelés,energia,laptop,akkumulátor,AC,felfüggesztés,hibernálás,fényerő,teljesítmény,fedél +X-KDE-Keywords[ia]=systema,potentia,gestion de potentia,energia,laptop,batteria,suspension,CA,suspende,hiberna,brillantia,prestation,coperculo +X-KDE-Keywords[kk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[km]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[ko]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,시스템,전원,전원 관리,에너지,노트북,배터리,어댑터,절전,대기 모드,대기,최대 절전,최대 절전 모드,밝기,성능,덮개,상판 +X-KDE-Keywords[mr]=प्रणाली, वीज, वीज व्यवस्थापन, ऊर्जा, लैपटॉप, बॅटरी, अकार्यक्षम, AC, अकार्यक्षम, हायबरनेट, प्रखरता, लिड +X-KDE-Keywords[nb]=system,strøm,strømstyring,energi,bærbar,batteri,hvilemodus,AC,hvile,dvale,lysstyrke,ytelse,lokk +X-KDE-Keywords[nds]=Systeem,Stroom,Stroompleeg,Energie,Klappreekner,Batterie,utsetten,AC,Wesselstroom,infreren,Helligkeit,Leisten +X-KDE-Keywords[nl]=systeem,energie,energiebeheer,laptop,batterij,accu,suspension,AC,onderbreken,slapen,helderheid,prestaties,deksel +X-KDE-Keywords[pl]=system,moc,zarządzanie energią,energia,laptop,bateria,wstrzymanie,AC,wstrzymaj,hibernuj,jasność,wydajność,pokrywka +X-KDE-Keywords[pt]=sistema,energia,gestão de energia,portátil,bateria,suspensão,AC,suspender,hibernar,brilho,performance,tampo +X-KDE-Keywords[pt_BR]=sistema,energia,gerenciamento de energia,energia,notebook,laptop,portátil,bateria,suspensão,AC,suspender,hibernar,brilho,desempenho,tampa +X-KDE-Keywords[ru]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,системное,питание,управление питанием,энергопотребление,ноутбук,батарея,спящий режим,гибернация,ждущий режим,яркость,производительность,крышка +X-KDE-Keywords[sk]=systém,napájanie,správa napájanie,energia,laptop,batéria,uspanie,AC,uspať,hibernovať,jas,výkon,kryt +X-KDE-Keywords[sl]=sistem,energija,upravljanje z energijo,prenosnik,prenosni računalnik,baterija,akumulator,pripravljenost,mirovanje,električno omrežje,svetlost,zmogljivost,pokrov,napajanje +X-KDE-Keywords[sr]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац +X-KDE-Keywords[sr@ijekavian]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац +X-KDE-Keywords[sr@ijekavianlatin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac +X-KDE-Keywords[sr@latin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac +X-KDE-Keywords[sv]=system,kraft,krafthantering,energi,bärbar dator,batteri,viloläge,AC,gå till viloläge,dvala,ljusstyrka,prestanda,lock +X-KDE-Keywords[tr]=sistem,güç,güç yönetimi,enerji,dizüstü,pil,askıya alma,Adaptör,uyku kipi,hazırda bekletme,parlaklık,performans,başarım,dizüstü kapağı,ekran parlaklığı +X-KDE-Keywords[uk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,система,живлення,мережа,струм,керування,енергія,ноутбук,акумулятор,батарея,батареї,присипляння,призупинення,призупинка,яскравість,швидкодія,кришка,кришки +X-KDE-Keywords[x-test]=xxsystem,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lidxx +X-KDE-Keywords[zh_CN]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,系统,电源,电源管理,能源,笔记本,电池,休眠,睡眠,交流,亮度,性能 +X-KDE-Keywords[zh_TW]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid diff --git a/powerdevil/kcmodule/profiles/CMakeLists.txt b/powerdevil/kcmodule/profiles/CMakeLists.txt new file mode 100644 index 00000000..f09c2ec1 --- /dev/null +++ b/powerdevil/kcmodule/profiles/CMakeLists.txt @@ -0,0 +1,24 @@ + +set( kcm_powerdevil_profiles_SRCS + EditPage.cpp + ../../daemon/powerdevilprofilegenerator.cpp +) + +kde4_add_ui_files(kcm_powerdevil_profiles_SRCS + profileEditPage.ui) + +kde4_add_kcfg_files(kcm_powerdevil_profiles_SRCS ../../PowerDevilSettings.kcfgc) + +kde4_add_plugin(kcm_powerdevilprofilesconfig ${kcm_powerdevil_profiles_SRCS}) + +target_link_libraries(kcm_powerdevilprofilesconfig + ${KDE4_KDECORE_LIBS} + ${KDE4_KDEUI_LIBRARY} + ${KDE4_KIO_LIBS} + ${KDE4_SOLID_LIBS} + powerdevilui + powerdevilconfigcommonprivate +) + +install(TARGETS kcm_powerdevilprofilesconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) +install( FILES powerdevilprofilesconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/powerdevil/kcmodule/profiles/EditPage.cpp b/powerdevil/kcmodule/profiles/EditPage.cpp new file mode 100644 index 00000000..0865b90e --- /dev/null +++ b/powerdevil/kcmodule/profiles/EditPage.cpp @@ -0,0 +1,300 @@ +/*************************************************************************** + * Copyright (C) 2008-2010 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "EditPage.h" + +#include "actioneditwidget.h" +#include "ErrorOverlay.h" + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +K_PLUGIN_FACTORY(PowerDevilProfilesKCMFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(PowerDevilProfilesKCMFactory("powerdevilprofilesconfig","powerdevil")) + +typedef QMap< QString, QString > StringStringMap; +Q_DECLARE_METATYPE(StringStringMap) + +EditPage::EditPage(QWidget *parent, const QVariantList &args) + : KCModule(PowerDevilProfilesKCMFactory::componentData(), parent, args) +{ + qDBusRegisterMetaType< StringStringMap >(); + + setButtons(Apply | Help | Default); + + KAboutData *about = + new KAboutData("powerdevilprofilesconfig", "powerdevilprofilesconfig", ki18n("Power Profiles Configuration"), + "", ki18n("A profile configurator for KDE Power Management System"), + KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), + ki18n("From this module, you can manage KDE Power Management System's power profiles, by tweaking " + "existing ones or creating new ones.")); + + about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", + "http://drfav.wordpress.com"); + + setAboutData(about); + + setupUi(this); + + m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig); + + if (m_profilesConfig->groupList().isEmpty()) { + // Use the generator + QSet methods = Solid::PowerManagement::supportedSleepStates(); + PowerDevil::ProfileGenerator::generateProfiles( + methods.contains(Solid::PowerManagement::SuspendState), + methods.contains(Solid::PowerManagement::HibernateState) + ); + m_profilesConfig->reparseConfiguration(); + } + + kDebug() << m_profilesConfig.data()->groupList() << m_profilesConfig.data()->entryMap().keys(); + + // Create widgets for each profile + ActionEditWidget *editWidget = new ActionEditWidget("AC"); + m_editWidgets.insert("AC", editWidget); + acWidgetLayout->addWidget(editWidget); + connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); + tabWidget->setTabIcon(0, KIcon("battery-charging")); + + editWidget = new ActionEditWidget("Battery"); + m_editWidgets.insert("Battery", editWidget); + batteryWidgetLayout->addWidget(editWidget); + connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); + tabWidget->setTabIcon(1, KIcon("battery-060")); + + editWidget = new ActionEditWidget("LowBattery"); + m_editWidgets.insert("LowBattery", editWidget); + lowBatteryWidgetLayout->addWidget(editWidget); + connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); + tabWidget->setTabIcon(2, KIcon("battery-low")); + + QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForRegistration | + QDBusServiceWatcher::WatchForUnregistration, + this); + + connect(watcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); + connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onServiceUnregistered(QString))); + + bool hasBattery = false; + foreach(const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { + const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); + if (b->isPowerSupply() && (b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery)) { + hasBattery = true; + break; + } + } + + if (!hasBattery) { + tabWidget->setTabEnabled(1, false); + tabWidget->setTabEnabled(2, false); + tabWidget->setTabBarHidden(true); + } + + if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { + onServiceRegistered("org.kde.Solid.PowerManagement"); + } else { + onServiceUnregistered("org.kde.Solid.PowerManagement"); + } +} + +EditPage::~EditPage() +{ +} + +void EditPage::onChanged(bool value) +{ + ActionEditWidget *editWidget = qobject_cast< ActionEditWidget* >(sender()); + if (!editWidget) { + return; + } + + m_profileEdited[editWidget->configName()] = value; + + if (value) { + emit changed(true); + } + + checkAndEmitChanged(); +} + +void EditPage::load() +{ + kDebug() << "Loading routine called"; + for (QHash< QString, ActionEditWidget* >::const_iterator i = m_editWidgets.constBegin(); + i != m_editWidgets.constEnd(); ++i) { + i.value()->load(); + + m_profileEdited[i.value()->configName()] = false; + } +} + +void EditPage::save() +{ + QStringList profiles; + + for (QHash< QString, ActionEditWidget* >::const_iterator i = m_editWidgets.constBegin(); + i != m_editWidgets.constEnd(); ++i) { + i.value()->save(); + if (m_profileEdited[i.value()->configName()]) { + profiles.append(i.value()->configName()); + } + + m_profileEdited[i.value()->configName()] = false; + } + // Notify the daemon + notifyDaemon(profiles); + + emit changed(false); +} + +void EditPage::notifyDaemon(const QStringList &editedProfiles) +{ + QDBusMessage call; + if (!editedProfiles.isEmpty()) { + call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "currentProfile"); + QDBusPendingReply< QString > reply = QDBusConnection::sessionBus().asyncCall(call); + reply.waitForFinished(); + + if (reply.isValid()) { + if (!editedProfiles.contains(reply.value())) { + // Ask to reparse config + kDebug() << "Inactive profile edited, reparsing configuration"; + call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "reparseConfiguration"); + + // Perform call + QDBusConnection::sessionBus().asyncCall(call); + return; + } + } + } + + // Refresh status + call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement", "refreshStatus"); + + // Perform call + QDBusConnection::sessionBus().asyncCall(call); +} + +void EditPage::restoreDefaultProfiles() +{ + // Confirm + int ret = KMessageBox::warningContinueCancel(this, i18n("The KDE Power Management System will now generate a set of defaults " + "based on your computer's capabilities. This will also erase " + "all existing modifications you made. " + "Are you sure you want to continue?"), i18n("Restore Default Profiles")); + if (ret == KMessageBox::Continue) { + kDebug() << "Restoring defaults."; + QSet methods = Solid::PowerManagement::supportedSleepStates(); + PowerDevil::ProfileGenerator::generateProfiles( + methods.contains(Solid::PowerManagement::SuspendState), + methods.contains(Solid::PowerManagement::HibernateState) + ); + + load(); + + // Notify the daemon + notifyDaemon(); + } +} + +void EditPage::openUrl(const QString &url) +{ + new KRun(KUrl(url), this); +} + +void EditPage::defaults() +{ + restoreDefaultProfiles(); +} + +void EditPage::checkAndEmitChanged() +{ + bool value = false; + for (QHash< QString, bool >::const_iterator i = m_profileEdited.constBegin(); + i != m_profileEdited.constEnd(); ++i) { + if (i.value()) { + value = i.value(); + } + } + + emit changed(value); +} + +void EditPage::onServiceRegistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + } +} + +void EditPage::onServiceUnregistered(const QString& service) +{ + Q_UNUSED(service); + + if (!m_errorOverlay.isNull()) { + m_errorOverlay.data()->deleteLater(); + } + + m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running.\n" + "This can be solved by starting or scheduling it inside \"Startup and Shutdown\""), + this); +} + +#include "EditPage.moc" diff --git a/powerdevil/kcmodule/profiles/EditPage.h b/powerdevil/kcmodule/profiles/EditPage.h new file mode 100644 index 00000000..27ccbed9 --- /dev/null +++ b/powerdevil/kcmodule/profiles/EditPage.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2008 by Dario Freddi * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef EDITPAGE_H +#define EDITPAGE_H + +#include + +#include "ui_profileEditPage.h" + +class ActionEditWidget; +namespace PowerDevil { +class ActionConfig; +} + +class ErrorOverlay; +class QCheckBox; +class KToolBar; + +class EditPage : public KCModule, private Ui_profileEditPage +{ + Q_OBJECT + +public: + explicit EditPage(QWidget *parent, const QVariantList &args); + ~EditPage(); + + void load(); + void save(); + virtual void defaults(); + +private slots: + void onChanged(bool changed); + + void restoreDefaultProfiles(); + + void notifyDaemon(const QStringList &editedProfiles = QStringList()); + + void openUrl(const QString &url); + + void onServiceRegistered(const QString &service); + void onServiceUnregistered(const QString &service); + + void checkAndEmitChanged(); + +private: + KSharedConfig::Ptr m_profilesConfig; + QHash< QString, bool > m_profileEdited; + QWeakPointer< ErrorOverlay > m_errorOverlay; + QHash< QString, ActionEditWidget* > m_editWidgets; +}; + +#endif /* EDITPAGE_H */ diff --git a/powerdevil/kcmodule/profiles/Messages.sh b/powerdevil/kcmodule/profiles/Messages.sh new file mode 100755 index 00000000..02ddd3e1 --- /dev/null +++ b/powerdevil/kcmodule/profiles/Messages.sh @@ -0,0 +1,5 @@ +#! /bin/sh +$EXTRACTRC `find -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp || exit 11 +$XGETTEXT `find -name \*.cpp -o -name \*.h` -o $podir/powerdevilprofilesconfig.pot +rm -f rc.cpp + diff --git a/powerdevil/kcmodule/profiles/powerdevilprofilesconfig.desktop b/powerdevil/kcmodule/profiles/powerdevilprofilesconfig.desktop new file mode 100644 index 00000000..105719db --- /dev/null +++ b/powerdevil/kcmodule/profiles/powerdevilprofilesconfig.desktop @@ -0,0 +1,148 @@ +[Desktop Entry] +Exec=kcmshell4 powerdevilprofilesconfig +Icon=preferences-system-power-management +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/powerdevil/index.html + +X-KDE-Library=kcm_powerdevilprofilesconfig +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=power-management +X-KDE-Weight=1 + +Name=Energy Saving +Name[bs]=Štednja energije +Name[ca]=Estalvi d'energia +Name[ca@valencia]=Estalvi d'energia +Name[cs]=Úsporný režim +Name[da]=Strømbesparelse +Name[de]=Energiesparen +Name[el]=Εξοικονόμηση ενέργειας +Name[en_GB]=Energy Saving +Name[es]=Ahorro de energía +Name[et]=Energia säästmine +Name[eu]=Energia-aurreztea +Name[fi]=Virransäästö +Name[fr]=Économie d'énergie +Name[ga]=Spáráil Fuinnimh +Name[gl]=Aforro enerxético +Name[he]=חיסכון בחשמל +Name[hu]=Energiatakarékosság +Name[ia]=Sparnio de energia +Name[is]=Orkusparnaður +Name[kk]=Қуатты үнемдеу +Name[km]=សន្សំ​ថាមពល​ +Name[ko]=에너지 절약 +Name[lt]=Energijos taupymas +Name[mr]=ऊर्जा बचत +Name[nb]=Energisparing +Name[nds]=Stroomsporen +Name[nl]=Energiebesparing +Name[pa]=ਊਰਜਾ ਬੱਚਤ +Name[pl]=Oszczędzanie energii +Name[pt]=Poupança de Energia +Name[pt_BR]=Economia de energia +Name[ro]=Economisire energie +Name[ru]=Энергосбережение +Name[sk]=Šetrenie energie +Name[sl]=Varčevanje z energijo +Name[sr]=Штедња енергије +Name[sr@ijekavian]=Штедња енергије +Name[sr@ijekavianlatin]=Štednja energije +Name[sr@latin]=Štednja energije +Name[sv]=Strömsparhantering +Name[tr]=Enerji Tasarrufu +Name[uk]=Заощадження енергії +Name[vi]=Tiết kiệm năng lượng +Name[x-test]=xxEnergy Savingxx +Name[zh_CN]=节能 +Name[zh_TW]=省電模式 + +Comment=Configure Energy Saving +Comment[bs]=Podesi štednju energije +Comment[ca]=Configura l'estalvi d'energia +Comment[ca@valencia]=Configura l'estalvi d'energia +Comment[cs]=Upravte šetření energie +Comment[da]=Indstillinger for strømbesparelse +Comment[de]=Energiespar-Einstellungen einrichten +Comment[el]=Διαμόρφωση της εξοικονόμησης ενέργειας +Comment[en_GB]=Configure Energy Saving +Comment[es]=Configurar el ahorro de energía +Comment[et]=Energia säästmise seadistused +Comment[eu]=Konfiguratu energia-aurreztea +Comment[fi]=Virransäästön asetukset +Comment[fr]=Configurer les économies d'énergie +Comment[ga]=Cumraigh Spáráil Fuinnimh +Comment[gl]=Configurar o aforro enerxético +Comment[he]=הגדרות חיסכון באנרגייה +Comment[hu]=Energiatakarékossági beállítások +Comment[ia]=Configura sparnio de energia +Comment[is]=Stilla orkusparnað +Comment[kk]=Қуат үнемдеуді баптау +Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​នៃ​​ការសន្សំ​ថាមពល +Comment[ko]=절전 설정 +Comment[lt]=Konfigūruoti energijos taupymą +Comment[mr]=ऊर्जा बचत संयोजीत करा +Comment[nb]=Sett opp strømsparing +Comment[nds]=Instellen för't Stroomsporen fastleggen +Comment[nl]=Energiebesparing instellen +Comment[pa]=ਊਰਜਾ ਬੱਚਤ ਸੰਰਚਨਾ +Comment[pl]=Ustawienia oszczędzania energii +Comment[pt]=Configurar a Poupança de Energia +Comment[pt_BR]=Configura a economia de energia +Comment[ro]=Configurează economisirea energiei +Comment[ru]=Параметры энергосбережения +Comment[sk]=Nastaviť šetrenie energie +Comment[sl]=Nastavi varčevanje z energijo +Comment[sr]=Подешавање штедње енергије +Comment[sr@ijekavian]=Подешавање штедње енергије +Comment[sr@ijekavianlatin]=Podešavanje štednje energije +Comment[sr@latin]=Podešavanje štednje energije +Comment[sv]=Anpassa strömsparhantering +Comment[tr]=Enerji Tasarrufunu Yapılandır +Comment[uk]=Налаштувати заощадження енергії +Comment[vi]=Cấu hình cho Tiết kiệm năng lượng +Comment[x-test]=xxConfigure Energy Savingxx +Comment[zh_CN]=保存能源设置 +Comment[zh_TW]=設定省電模式 + +X-KDE-Keywords=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[bs]=Sistem, Napajanje, Upravljanje napajanjem, energija, laptop, baterija, suspenzija, AC, suspendiraj, hiberniranje, osvljetljenje, kapak, +X-KDE-Keywords[ca]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspèn,hiberna,lluminositat,rendiment,tapa +X-KDE-Keywords[ca@valencia]=sistema,energia,gestió d'energia,corrent,portàtil,bateria,suspensió,AC,suspèn,hiberna,lluminositat,rendiment,tapa +X-KDE-Keywords[da]=system,strøm,strømstyring,energi,laptop,bærbar,batteri,suspension,AC,strømforsyning,suspender,slumre,dvale,lysstyrke,ydelse,låg +X-KDE-Keywords[de]=system,energie,energieverwaltung,laptop,notebook,akku,batterie,ruhezustand,tiefschlaf,helligkeit,leistung,deckel +X-KDE-Keywords[el]=σύστημα,ενέργεια,διαχείριση ενέργειας,ενέργεια,φορητός,μπαταρία,αναστολή,AC,κοίμηση,νάρκη,λαμπρότητα,επιδόσεις,καπάκι +X-KDE-Keywords[en_GB]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[es]=sistema,energía,gestión de energía,energía,portátil,batería,suspensión,AC,suspender,hibernar,brillo,rendimiento,tapa +X-KDE-Keywords[et]=süsteem,energia,toide,toitehaldus,sülearvuti,aku,uneseisund,uni,talveuni, heledus,jõudlus,kaas +X-KDE-Keywords[eu]=sistema,energia,energia-kudeaketa,energia,eramangarria,bateria,egonean,korronte alternoa,egonean uztea,hibernatu,distira,errendimendua,tapa +X-KDE-Keywords[fi]=järjestelmä,virta,virranhallinta,energia,kannettava,tietokone,läppäri,akku,lepotila,valmiustila,AC,virtalähde,keskeytä,kirkkaus,suorituskyky,kansi +X-KDE-Keywords[fr]=système, alimentation, gestion énergétique, énergie, portable, batterie, suspension, AC, suspendre, hiberner, luminosité, performance, capot +X-KDE-Keywords[gl]=sistema,enerxía,xestión da enerxía, xestión enerxética,carga,portátil,batería, suspender,corrente,hibernar,durmir,brillo,rendemento,tapa +X-KDE-Keywords[hu]=rendszer,energia,energiakezelés,energia,laptop,akkumulátor,AC,felfüggesztés,hibernálás,fényerő,teljesítmény,fedél +X-KDE-Keywords[ia]=systema,potentia,gestion de potentia,energia,laptop,batteria,suspension,CA,suspende,hiberna,brillantia,prestation,coperculo +X-KDE-Keywords[kk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[km]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid +X-KDE-Keywords[ko]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,시스템,전원,전원 관리,에너지,노트북,배터리,어댑터,절전,대기 모드,대기,최대 절전,최대 절전 모드,밝기,성능,덮개,상판 +X-KDE-Keywords[mr]=प्रणाली, वीज, वीज व्यवस्थापन, ऊर्जा, लैपटॉप, बॅटरी, अकार्यक्षम, AC, अकार्यक्षम, हायबरनेट, प्रखरता, लिड +X-KDE-Keywords[nb]=system,strøm,strømstyring,energi,bærbar,batteri,hvilemodus,AC,hvile,dvale,lysstyrke,ytelse,lokk +X-KDE-Keywords[nds]=Systeem,Stroom,Stroompleeg,Energie,Klappreekner,Batterie,utsetten,AC,Wesselstroom,infreren,Helligkeit,Leisten +X-KDE-Keywords[nl]=systeem,energie,energiebeheer,laptop,batterij,accu,suspension,AC,onderbreken,slapen,helderheid,prestaties,deksel +X-KDE-Keywords[pl]=system,moc,zarządzanie energią,energia,laptop,bateria,wstrzymanie,AC,wstrzymaj,hibernuj,jasność,wydajność,pokrywka +X-KDE-Keywords[pt]=sistema,energia,gestão de energia,portátil,bateria,suspensão,AC,suspender,hibernar,brilho,performance,tampo +X-KDE-Keywords[pt_BR]=sistema,energia,gerenciamento de energia,energia,notebook,laptop,portátil,bateria,suspensão,AC,suspender,hibernar,brilho,desempenho,tampa +X-KDE-Keywords[ru]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,системное,питание,управление питанием,энергопотребление,ноутбук,батарея,спящий режим,гибернация,ждущий режим,яркость,производительность,крышка +X-KDE-Keywords[sk]=systém,napájanie,správa napájanie,energia,laptop,batéria,uspanie,AC,uspať,hibernovať,jas,výkon,kryt +X-KDE-Keywords[sl]=sistem,energija,upravljanje z energijo,prenosnik,prenosni računalnik,baterija,akumulator,pripravljenost,mirovanje,električno omrežje,svetlost,zmogljivost,pokrov,napajanje +X-KDE-Keywords[sr]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац +X-KDE-Keywords[sr@ijekavian]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,систем,напајање,струја,управљање напајањем,лаптоп,батерија,суспендовање,АЦ,хибернација,светлина,осветљај,перформансе,поклопац +X-KDE-Keywords[sr@ijekavianlatin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac +X-KDE-Keywords[sr@latin]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,sistem,napajanje,struja,upravljanje napajanjem,laptop,baterija,suspendovanje,AC,hibernacija,svetlina,osvetljaj,performanse,poklopac +X-KDE-Keywords[sv]=system,kraft,krafthantering,energi,bärbar dator,batteri,viloläge,AC,gå till viloläge,dvala,ljusstyrka,prestanda,lock +X-KDE-Keywords[tr]=sistem,güç,güç yönetimi,enerji,dizüstü,pil,askıya alma,Adaptör,uyku kipi,hazırda bekletme,parlaklık,performans,başarım,dizüstü kapağı,ekran parlaklığı +X-KDE-Keywords[uk]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,система,живлення,мережа,струм,керування,енергія,ноутбук,акумулятор,батарея,батареї,присипляння,призупинення,призупинка,яскравість,швидкодія,кришка,кришки +X-KDE-Keywords[x-test]=xxsystem,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lidxx +X-KDE-Keywords[zh_CN]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid,系统,电源,电源管理,能源,笔记本,电池,休眠,睡眠,交流,亮度,性能 +X-KDE-Keywords[zh_TW]=system,power,power management,energy,laptop,battery,suspension,AC,suspend,hibernate,brightness,performance,lid diff --git a/powerdevil/kcmodule/profiles/profileEditPage.ui b/powerdevil/kcmodule/profiles/profileEditPage.ui new file mode 100644 index 00000000..dc265794 --- /dev/null +++ b/powerdevil/kcmodule/profiles/profileEditPage.ui @@ -0,0 +1,63 @@ + + + profileEditPage + + + + 0 + 0 + 683 + 293 + + + + + + + 0 + + + + On AC Power + + + + + + + + + + On Battery + + + + + + + + + + On Low Battery + + + + + + + + + + + + + + KTabWidget + QTabWidget +
    ktabwidget.h
    + 1 +
    +
    + + +
    diff --git a/powerdevil/powerdevil.notifyrc b/powerdevil/powerdevil.notifyrc new file mode 100644 index 00000000..52ec8be4 --- /dev/null +++ b/powerdevil/powerdevil.notifyrc @@ -0,0 +1,1575 @@ +[Global] +Name=KDE Power Management System +Name[bg]=Система за управление захранването на KDE +Name[bs]=KDE‑ov sistem za upravljanje napajanjem +Name[ca]=Sistema de gestió d'energia del KDE +Name[ca@valencia]=Sistema de gestió d'energia del KDE +Name[cs]=Systém správy napájení KDE +Name[da]=KDE's strømstyringssystem +Name[de]=KDE-Energieverwaltungssystem +Name[el]=Σύστημα διαχείρισης ενέργειας KDE +Name[en_GB]=KDE Power Management System +Name[es]=Sistema de gestión de energía de KDE +Name[et]=KDE toitehalduse süsteem +Name[eu]=KDEren energia kudeatzeko sistema +Name[fi]=KDE:n virranhallintajärjestelmä +Name[fr]=Système KDE de gestion de l'énergie +Name[ga]=Córas Bainisteoireachta Cumhachta KDE +Name[gl]=Sistema de xestión da enerxía de KDE +Name[he]=מערכת ניהול צריכת חשמל של KDE +Name[hi]=केडीई बिज़ली प्रबंधन तंत्र +Name[hr]=KDE-ov sustav upravljanja potrošnjom energije +Name[hu]=KDE energiakezelő rendszer +Name[ia]=Systema de gestion de energia de KDE +Name[is]=KDE orkustjórnunarkerfið +Name[ja]=KDE 電源管理 +Name[kk]=KDE-нің қуаттандыруды басқару жүйесі +Name[km]=ប្រព័ន្ធ​គ្រប់គ្រង​ថាមពល​របស់ KDE +Name[kn]=KDE ವಿದ್ಯುಚ್ಛಕ್ತಿ ನಿರ್ವಹಣಾ ವ್ಯವಸ್ಥೆ +Name[ko]=KDE 전원 관리 시스템 +Name[lt]=KDE energijos valdymo sistema +Name[lv]=KDE energokontroles sistēma +Name[mr]=केडीई वीज व्यवस्थापन प्रणाली +Name[nb]=Et strømstyringsverktøy for KDE +Name[nds]=Stroomkuntrullsysteem för KDE +Name[nl]=KDE-energiebeheersysteem +Name[pa]=KDE ਪਾਵਰ ਪਰਬੰਧਕ ਸਿਸਟਮ +Name[pl]=System zarządzania energią w KDE +Name[pt]=Sistema de Gestão de Energia do KDE +Name[pt_BR]=Sistema de Gerenciamento de Energia do KDE +Name[ro]=Sistemul KDE de gestiune a alimentării +Name[ru]=Система управления питанием KDE +Name[sk]=Systém správy napájania KDE +Name[sl]=KDE-jev sistem za upravljanje z energijo +Name[sr]=КДЕ‑ов систем за управљање напајањем +Name[sr@ijekavian]=КДЕ‑ов систем за управљање напајањем +Name[sr@ijekavianlatin]=KDE‑ov sistem za upravljanje napajanjem +Name[sr@latin]=KDE‑ov sistem za upravljanje napajanjem +Name[sv]=KDE:s strömsparhanteringssystem +Name[th]=ระบบจัดการพลังงานของ KDE +Name[tr]=KDE Güç Yönetim Sistemi +Name[ug]=ك د ئې(KDE) توك مەنبە باشقۇرۇش سىستېمىسى +Name[uk]=Система керування живленням KDE +Name[vi]=Hệ thống quản lý năng lượng KDE +Name[wa]=Sistinme di manaedjmint di l' enerdjeye di KDE +Name[x-test]=xxKDE Power Management Systemxx +Name[zh_CN]=KDE 电源管理系统 +Name[zh_TW]=KDE 電源管理系統 +IconName=preferences-system-power-management +Comment=Power Management System +Comment[bs]=Sistem za upravljanje napajanjem +Comment[ca]=Sistema de gestió d'energia +Comment[ca@valencia]=Sistema de gestió d'energia +Comment[cs]=Systém správy napájení +Comment[da]=Strømstyringssystem +Comment[de]=Energieverwaltungssystem +Comment[el]=Σύστημα διαχείρισης ενέργειας +Comment[en_GB]=Power Management System +Comment[es]=Sistema de gestión de energía +Comment[et]=Toitehalduse süsteem +Comment[eu]=Energia kudeatzeko sistema +Comment[fi]=Virranhallintajärjestelmä +Comment[fr]=Système de gestion de l'énergie +Comment[ga]=Córas Bainisteoireachta Cumhachta +Comment[gl]=Sistema de xestión da enerxía +Comment[he]=מערכת ניהול צריכת חשמל +Comment[hu]=Energiakezelő rendszer +Comment[ia]=Systema de gestion de energia +Comment[is]=Orkustjórnunarkerfi +Comment[kk]=Қуаттандыруды басқару жүйесі +Comment[ko]=전원 관리 시스템 +Comment[lt]=Energijos valdymo sistema +Comment[mr]=वीज व्यवस्थापन प्रणाली +Comment[nb]=Et strømstyringsverktøy +Comment[nds]=Stroompleegsysteem +Comment[nl]=Energiebeheersysteem +Comment[pa]=ਪਾਵਰ ਪਰਬੰਧ ਸਿਸਟਮ +Comment[pl]=System zarządzania energią +Comment[pt]=Sistema de Gestão de Energia +Comment[pt_BR]=Sistema de Gerenciamento de Energia +Comment[ro]=Sistemul de gestiune a alimentării +Comment[ru]=Система управления питанием +Comment[sk]=Systém správy napájania +Comment[sl]=Sistem za upravljanje z energijo +Comment[sr]=Систем за управљање напајањем +Comment[sr@ijekavian]=Систем за управљање напајањем +Comment[sr@ijekavianlatin]=Sistem za upravljanje napajanjem +Comment[sr@latin]=Sistem za upravljanje napajanjem +Comment[sv]=Strömsparhanteringssystem +Comment[tr]=Güç Yönetim Sistemi +Comment[uk]=Система керування живленням +Comment[x-test]=xxPower Management Systemxx +Comment[zh_CN]=电源管理系统 +Comment[zh_TW]=電源管理系統 +Version=2 + +[Context/warningnot] +Name=Warning +Name[af]=Waarskuwing +Name[ar]=إنذار +Name[as]=সতৰ্কবাণী +Name[ast]=Avisu +Name[be]=Папярэджанне +Name[be@latin]=Uvaha +Name[bg]=Предупреждение +Name[bn]=সতর্কবার্তা +Name[bn_IN]=সতর্কবার্তা +Name[bs]=Upozorenje +Name[ca]=Avís +Name[ca@valencia]=Avís +Name[cs]=Varování +Name[csb]=Bôczënk +Name[da]=Advarsel +Name[de]=Warnung +Name[el]=Προειδοποίηση +Name[en_GB]=Warning +Name[eo]=Averto +Name[es]=Aviso +Name[et]=Hoiatus +Name[eu]=Abisua +Name[fi]=Varoitus +Name[fr]=Avertissement +Name[fy]=Warskôging +Name[ga]=Rabhadh +Name[gl]=Aviso +Name[gu]=ચેતવણી +Name[he]=אזהרה +Name[hi]=चेतावनी +Name[hne]=चेतावनी +Name[hr]=Upozorenje +Name[hsb]=Kedźbu +Name[hu]=Figyelmeztetés +Name[ia]=Aviso +Name[id]=Peringatan +Name[is]=Aðvörun +Name[it]=Avviso +Name[ja]=警告 +Name[kk]=Ескерту +Name[km]=ការ​ព្រមាន +Name[kn]=ಎಚ್ಚರಿಕೆ +Name[ko]=경고 +Name[ku]=Hişyarî +Name[lt]=Dėmesio +Name[lv]=Brīdinājums +Name[mai]=चेतावनी +Name[mk]=Предупредување +Name[ml]=മുന്നറിയിപ്പു് +Name[mr]=इशारा +Name[nb]=Advarsel +Name[nds]=Wohrschoen +Name[ne]=चेतावनी +Name[nl]=Waarschuwing +Name[nn]=Åtvaring +Name[oc]=Alèrta +Name[or]=ଚେତାବନୀ +Name[pa]=ਚੇਤਾਵਨੀ +Name[pl]=Ostrzeżenie +Name[pt]=Aviso +Name[pt_BR]=Aviso +Name[ro]=Atenționare +Name[ru]=Предупреждение +Name[se]=Várrehus +Name[si]=අවවාදය +Name[sk]=Varovanie +Name[sl]=Opozorilo +Name[sr]=Упозорење +Name[sr@ijekavian]=Упозорење +Name[sr@ijekavianlatin]=Upozorenje +Name[sr@latin]=Upozorenje +Name[sv]=Varning +Name[ta]=எச்சரிக்கை +Name[te]=హెచ్చరిక +Name[tg]=Огоҳинома +Name[th]=คำเตือน +Name[tr]=Uyarı +Name[ug]=ئاگاھلاندۇرۇش +Name[uk]=Попередження +Name[uz]=Ogohnoma +Name[uz@cyrillic]=Огоҳнома +Name[vi]=Cảnh báo +Name[wa]=Adviertixhmint +Name[x-test]=xxWarningxx +Name[zh_CN]=警告 +Name[zh_TW]=警告 +Comment=Used for warning notifications +Comment[ar]=يُستخدم للتنبيهات التحذيرية +Comment[ast]=Usáu pa notificaciones d'avisu +Comment[be@latin]=Dla aścierahalnych paviedamleńniaŭ +Comment[bg]=Използва се за предупреждения +Comment[bn]=সতর্কীকরণ বিজ্ঞপ্তির জন্য ব্যবহৃত হয় +Comment[bs]=Koristi se za obavještenja o upozorenjima +Comment[ca]=S'usa per a les notificacions d'avís +Comment[ca@valencia]=S'usa per a les notificacions d'avís +Comment[cs]=Použito pro varování a upozornění +Comment[da]=Bruges til advarselsbekendtgørelser +Comment[de]=Verwendet für Warnmeldungen +Comment[el]=Χρησιμοποιείται για τις προειδοποιήσεις +Comment[en_GB]=Used for warning notifications +Comment[eo]=Uzita por avertmesaĝoj +Comment[es]=Usado para notificaciones de advertencia +Comment[et]=Hoiatuste jaoks +Comment[eu]=Abisu-jakinarazpenetarako erabiltzen da +Comment[fi]=Käytetään varoitusilmoituksiin +Comment[fr]=Utilisé pour les notifications d'avertissements +Comment[fy]=Brûkt faor warskôging notifikaasjes +Comment[ga]=Úsáidte do rabhaidh +Comment[gl]=Emprégase para as notificacións de aviso +Comment[gu]=ચેતવણી નોંધણીઓ આપવા માટે વપરાય છે +Comment[he]=משמש להתרעות אזהרה +Comment[hi]=चेतावनियाँ देने के लिए उपयोग में लिया जाता है +Comment[hne]=चेतावनी सूचना बर उपयोग होथे +Comment[hr]=Korišten za upozoravajuće obavijesti +Comment[hu]=Kezelőprogram figyelmeztető üzenetekhez +Comment[ia]=Usate pro notificationes de avisos +Comment[id]=Digunakan untuk notifikasi peringatan +Comment[is]=Notað fyrir aðvaranir +Comment[it]=Usato per notifiche di avviso +Comment[ja]=警告の通知に使用 +Comment[kk]=Ескерту хабарларға қолданылады +Comment[km]=បានប្រើ​សម្រាប់​ការ​ជូន​ព្រមាន +Comment[kn]=ಎಚ್ಚರಿಕೆ ಸೂಚನೆಗಳಿಗೆ ಬಳಸಲಾಗುತ್ತದೆ +Comment[ko]=경고 알림에 사용됨 +Comment[lt]=Naudojama perspėjimams +Comment[lv]=Izmanto brīdinājumu paziņojumiem +Comment[ml]=താക്കീത് അറിയിപ്പുകള്‍ക്കായി ഉപയോഗിക്കുന്നു +Comment[mr]=इशारा सूचना करिता वापरले जाते +Comment[nb]=Brukt til varselsmeldinger +Comment[nds]=Bi Wohrschoen bruukt +Comment[nl]=Wordt gebruikt voor waarschuwingsmeldingen +Comment[nn]=Er brukt til åtvaringsvarsel +Comment[or]=ଚେତାବନୀ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଇଁ ବ୍ୟବହୃତ ହୋଇଥାଏ +Comment[pa]=ਚੇਤਾਵਨੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ +Comment[pl]=Używane do ostrzeżeń +Comment[pt]=Usado para as notificações de aviso +Comment[pt_BR]=Usado para as notificações de aviso +Comment[ro]=Utilizat pentru notificări de avertizare +Comment[ru]=Используется для системных уведомлений +Comment[si]=අවවාද පණිවුඩ සඳහා යොදාගනී +Comment[sk]=Používa sa pre varovné upozornenia +Comment[sl]=Uporabljeno za obvestila z opozorili +Comment[sr]=Користи се за позорна обавештења +Comment[sr@ijekavian]=Користи се за позорна обавјештења +Comment[sr@ijekavianlatin]=Koristi se za pozorna obavještenja +Comment[sr@latin]=Koristi se za pozorna obaveštenja +Comment[sv]=Används för varningsmeddelanden +Comment[ta]=Used for warning notifications +Comment[te]=హెచ్చరిక నోటీసుల కొరకు వుపయోగించబడింది +Comment[tg]=Используется для надписей под значками на рабочем столе. +Comment[th]=ใช้สำหรับการแจ้งเตือนให้ทราบ +Comment[tr]=Uyarı bildirimleri için kullanılır +Comment[ug]=ئاگاھلاندۇرۇش ئۇقتۇرۇشلىرى ئۈچۈن ئىشلىتىلىدۇ. +Comment[uk]=Використовується для попереджень +Comment[vi]=Sử dụng cho thông tin cảnh báo +Comment[wa]=Eployî po des notifiaedjes d' adviertixhmint +Comment[x-test]=xxUsed for warning notificationsxx +Comment[zh_CN]=用于发出警告通知 +Comment[zh_TW]=用於警告通知 + +[Context/stdnot] +Name=Notification +Name[af]=Stelselboodskap +Name[ar]=إشعار +Name[ast]=Notificación +Name[be]=Абвяшчэнні +Name[be@latin]=Infarmavańnie +Name[bg]=Уведомяване +Name[bn]=বিজ্ঞপ্তি +Name[bn_IN]=সূচনা +Name[bs]=Obavještenje +Name[ca]=Notificació +Name[ca@valencia]=Notificació +Name[cs]=Hlášení +Name[csb]=Dôwanié wiédzë +Name[da]=Bekendtgørelse +Name[de]=Benachrichtigung +Name[el]=Ειδοποίηση +Name[en_GB]=Notification +Name[eo]=Atentigo +Name[es]=Notificación +Name[et]=Märguanne +Name[eu]=Jakinarazpena +Name[fi]=Ilmoitus +Name[fr]=Notification +Name[fy]=Notifikaasje +Name[ga]=Fógairt +Name[gl]=Notificación +Name[gu]=નોંધણી +Name[he]=הודעות +Name[hi]=अधिसूचना +Name[hne]=अधिसूचना +Name[hr]=Obavijest +Name[hsb]=Zdźělenka +Name[hu]=Rendszerüzenet +Name[ia]=Notification +Name[id]=Notifikasi +Name[is]=Kerfistilkynning +Name[kk]=Құлақтандыру +Name[km]=សេចក្តី​ជូន​ដំណឹង​ +Name[kn]=ಸೂಚನೆಗಳು +Name[ko]=알림 +Name[ku]=Agahdarî +Name[lt]=Pranešimas +Name[lv]=Paziņojums +Name[mai]=अधिसूचना +Name[mk]=Известување +Name[ml]=അറിയിപ്പു് +Name[mr]=सूचना +Name[nb]=Varsling +Name[nds]=Bescheed +Name[ne]=सूचना +Name[nl]=Melding +Name[nn]=Varsling +Name[oc]=Notificacion +Name[or]=ବିଜ୍ଞପ୍ତି +Name[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienie +Name[pt]=Notificação +Name[pt_BR]=Notificação +Name[ro]=Notificare +Name[ru]=Уведомление +Name[se]=Dieđiheapmi +Name[si]=දැනුම්දීම +Name[sk]=Upozornenie +Name[sl]=Obvestilo +Name[sr]=Обавештење +Name[sr@ijekavian]=Обавештење +Name[sr@ijekavianlatin]=Obaveštenje +Name[sr@latin]=Obaveštenje +Name[sv]=Underrättelse +Name[ta]=அறிவிப்பு +Name[te]=నో‍టీసు +Name[tg]=Огоҳинома +Name[th]=การแจ้งให้ทราบ +Name[tr]=Bildirim +Name[ug]=ئۇقتۇرۇش +Name[uk]=Сповіщення +Name[uz]=Xabarnoma +Name[uz@cyrillic]=Хабарнома +Name[wa]=Notifiaedje +Name[x-test]=xxNotificationxx +Name[zh_CN]=通知 +Name[zh_TW]=通知 +Comment=Used for standard notifications +Comment[ar]=يستخدم للتنبيهات العادية +Comment[ast]=Usáu pa notificaciones standard +Comment[be@latin]=Dla zvyčajnych infarmavańniaŭ +Comment[bg]=Използва се за стандартни уведомления +Comment[bn]=সাধারণ বিজ্ঞপ্তির জন্য ব্যবহৃত +Comment[bs]=Koristi se za standardna obavještenja +Comment[ca]=S'usa per a les notificacions estàndard +Comment[ca@valencia]=S'usa per a les notificacions estàndard +Comment[cs]=Použito pro běžná oznámení +Comment[csb]=Brëkòwóné dlô sztandardowi notifikacëji +Comment[da]=Bruges til almindelige bekendtgørelser +Comment[de]=Verwendet für Standard-Benachrichtigungen +Comment[el]=Χρησιμοποιείται για τυπικές ειδοποιήσεις +Comment[en_GB]=Used for standard notifications +Comment[es]=Usado para notificaciones estándar +Comment[et]=Tavaliste märguannete jaoks +Comment[eu]=Jakinarazpen estandarretarako erabilia +Comment[fi]=Käytetään normaaleihin ilmoituksiin +Comment[fr]=Utilisé pour les notifications standards +Comment[fy]=Brûkt foar standert notifikaasjes +Comment[ga]=Úsáidte d'fhógraí caighdeánacha +Comment[gl]=Emprégase para as notificacións estándar +Comment[gu]=પ્રમાણભૂત નોંધ કરવા માટે ઉપયોગ થાય છે +Comment[he]=משמש להודעות רגילות +Comment[hi]=मानक सूचनाओं के लिए उपयोग में लिया जाता है +Comment[hne]=स्टेन्डर्ड सूचना बर उपयोग मं आथे +Comment[hr]=Korišten za standardne obavijesti +Comment[hu]=Kezelő értesítő üzenetekhez +Comment[ia]=Usate pro notificationes standard +Comment[id]=Digunakan untuk notifikasi standar +Comment[is]=Notað fyrir venjulegar tilkynningar +Comment[ja]=通常の通知に使用 +Comment[kk]=Стандартты құлақтандырулар үшін қолданылады +Comment[km]=បាន​ប្រើ​សម្រាប់​ការ​ជូនដំណឹង​ស្តង់ដារ +Comment[kn]=ಪ್ರಮಾಣಿತ ಸೂಚನೆಗಳಿಗೆ ಬಳಸಲಾಗುತ್ತದೆ +Comment[ko]=표준 알림에 사용됨 +Comment[ku]=Ji bo hişyariyên standard tê karandin +Comment[lt]=Naudojamas standartiniams pranešimams +Comment[lv]=Izmanto standarta paziņojumiem +Comment[mk]=Се користи за стандардни известувања +Comment[ml]=സ്റ്റാന്‍ഡര്‍ഡ് അറിയിപ്പുകള്‍ക്കായി ഉപയോഗിക്കുന്നത് +Comment[mr]=प्रमाणित सूचना करिता वापरले जाते +Comment[nb]=Brukt til standardmeldinger +Comment[nds]=Bi Standardbescheden bruukt +Comment[nl]=Wordt gebruikt voor standaardmeldingen +Comment[nn]=Er brukt til standardvarsel +Comment[or]=ମାନକ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପାଇଁ ବ୍ୟବହୃତ ହୋଇଥାଏ +Comment[pa]=ਸਟੈਂਡਰਡ ਨੋਟੀਫਿਕੇਸ਼ਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ +Comment[pl]=Używane do zwykłych powiadomień +Comment[pt]=Usado para as notificações normais +Comment[pt_BR]=Usado para as notificações padrão +Comment[ro]=Utilizat pentru notificări obișnuite +Comment[ru]=Используется для уведомлений +Comment[si]=සම්මත දැන්වීම් සඳහා යොදාගනී +Comment[sk]=Používa sa pre bežné upozornenia +Comment[sl]=Za običajna obvestila +Comment[sr]=Користи се за стандардна обавештења +Comment[sr@ijekavian]=Користи се за стандардна обавјештења +Comment[sr@ijekavianlatin]=Koristi se za standardna obavještenja +Comment[sr@latin]=Koristi se za standardna obaveštenja +Comment[sv]=Används för standardmeddelanden +Comment[ta]=Used for standard notifications +Comment[tg]=Используется для надписей под значками на рабочем столе. +Comment[th]=ใช้สำหรับการแจ้งให้ทราบมาตรฐาน +Comment[tr]=Standart bildirimler için kullanılır +Comment[ug]=ئۆلچەملىك ئۇقتۇرۇشلار ئۈچۈن ئىشلىتىلىدۇ. +Comment[uk]=Використовується для звичайних сповіщень +Comment[wa]=Eployî po des standårds notifiaedjes +Comment[x-test]=xxUsed for standard notificationsxx +Comment[zh_CN]=用于标准通知 +Comment[zh_TW]=用於標準通知 + +[Context/criticalnot] +Name=Critical notification +Name[ar]=تنبيه حرج +Name[ast]=Notificación crítica +Name[be@latin]=Važnaje infarmavańnie +Name[bg]=Критични уведомления +Name[bn]=গুরুত্বপূর্ণ বিজ্ঞপ্তি +Name[bn_IN]=গুরুত্বপূর্ণ সূচনাবার্তা +Name[bs]=Kritično obavještenje +Name[ca]=Notificacions crítiques +Name[ca@valencia]=Notificacions crítiques +Name[cs]=Kritické hlášení +Name[csb]=Dôwanié kriticzny wiédzë +Name[da]=Kritisk bekendtgørelse +Name[de]=Kritische Benachrichtigung +Name[el]=Κρίσιμη ειδοποίηση +Name[en_GB]=Critical notification +Name[eo]=Grava Atentigo +Name[es]=Notificación crítica +Name[et]=Kriitiliste märguannete jaoks +Name[eu]=Jakinarazpen kritikoa +Name[fi]=Kriittinen ilmoitus +Name[fr]=Notification critique +Name[fy]=Kritike notifikaasje +Name[ga]=Fógairt ríthábhachtach +Name[gl]=Notificación crítica +Name[gu]=નિર્ણાયક નોંધણી +Name[he]=הודעות חשובות +Name[hi]=गंभीर सूचना +Name[hne]=गंभीर सूचना +Name[hr]=Kritična obavijest +Name[hu]=Kritikus fontosságú üzenet +Name[ia]=Notification critic +Name[id]=Notifikasi kritis +Name[is]=Hættutilkynning +Name[ja]=重大な通知 +Name[kk]=Маңызды құлақтандыру +Name[km]=ការ​ជូន​ដំណឹង​សំខាន់ +Name[kn]=ವಿಷಮ ಸೂಚನೆ +Name[ko]=치명적 알림 +Name[ku]=Hişyarî dana rexne +Name[lt]=Kritinis pranešimas +Name[lv]=Kritisks paziņojums +Name[mk]=Критично известување +Name[ml]=ഗുരുതര അറിയിപ്പു് +Name[mr]=महत्वाची सूचना +Name[nb]=Kritisk varsling +Name[nds]=Kritisch Bescheed +Name[nl]=Kritieke melding +Name[nn]=Viktig varsel +Name[or]=ଗମ୍ଭୀର ବିଜ୍ଞପ୍ତି +Name[pa]=ਨਾਜ਼ੁਕ ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienie krytyczne +Name[pt]=Notificação crítica +Name[pt_BR]=Notificação crítica +Name[ro]=Notificare critică +Name[ru]=Критичное уведомление +Name[si]=දරුණු පණිවුඩය +Name[sk]=Kritické upozornenie +Name[sl]=Kritična obvestila +Name[sr]=Критично обавештење +Name[sr@ijekavian]=Критично обавјештење +Name[sr@ijekavianlatin]=Kritično obavještenje +Name[sr@latin]=Kritično obaveštenje +Name[sv]=Kritisk underrättelse +Name[ta]=Critical notification +Name[tg]=Уведомление &на панели задач +Name[th]=การแจ้งให้ทราบขั้นวิกฤติ +Name[tr]=Kritik bildirim +Name[ug]=جىددىي ئۇقتۇرۇش +Name[uk]=Сповіщення про критичні події +Name[vi]=Thông báo quan trọng +Name[wa]=Notifiaedje critike +Name[x-test]=xxCritical notificationxx +Name[zh_CN]=危急通知 +Name[zh_TW]=緊急通知 +Comment=Notifies a critical event +Comment[ar]=ينبه على حدث حرج +Comment[ast]=Notifica un eventu críticu +Comment[be@latin]=Paviedamlaje pra važnuju padzieju +Comment[bg]=Уведомяване за критична ситуация +Comment[bn]=গুরুত্বপূর্ণ ঘটনার কথা জানায় +Comment[bs]=Obaveštava o kritičnom događaju +Comment[ca]=Notifiquen esdeveniments crítics +Comment[ca@valencia]=Notifiquen esdeveniments crítics +Comment[cs]=Upozorňuje na kritickou událost +Comment[csb]=Dôwô kriticzną wiedzã +Comment[da]=Bekendtgør en kritisk begivenhed +Comment[de]=Benachrichtigt über einen kritischen Zustand +Comment[el]=Ειδοποίηση ενός κρίσιμου γεγονότος +Comment[en_GB]=Notifies a critical event +Comment[eo]=Sciigi kritikan eventon +Comment[es]=Notifica un evento crítico +Comment[et]=Märguandmine kriitilisest sündmusest +Comment[eu]=Gertaera kritiko baten berri ematen du +Comment[fi]=Ilmoittaa kriittisestä tapahtumasta +Comment[fr]=Notifie un évènement critique +Comment[fy]=Meld krityk barren +Comment[ga]=Cuireann sé seo teagmhas criticiúil in iúl +Comment[gl]=Notifica un suceso crítico +Comment[gu]=ખતરાની ઘટનાની નોંધ આપે છે +Comment[he]=משמש להודיע על אירועים חשובים +Comment[hi]=गंभीर घटना की सूचना देता है +Comment[hne]=एक गंभीर घटना ल बताथे +Comment[hr]=Obavještava o kritičnom događaju +Comment[hu]=Kritikus fontosságú üzenetet jelez +Comment[ia]=Il notifica un evento critic +Comment[id]=Beritahukan sebuah acara kritis +Comment[is]=Gefur tilkynningu um krítíska atburði +Comment[ja]=重大なイベントを通知します +Comment[kk]=Дағдарысты оқиға туралы құлақтандыру +Comment[km]=ជូនដំណឹង​ព្រត្តិការណ៍​សំខាន់ +Comment[kn]=ವಿಷಮ ಘಟನೆಯೊಂದನ್ನು ಸೂಚಿಸುತ್ತದೆ +Comment[ko]=치명적인 사건을 알림 +Comment[lt]=Perspėja apie kritinį įvykį +Comment[lv]=Paziņo kritisku notikumu +Comment[mk]=Известува за критичен настан +Comment[ml]=ഒരു അത്യാവശ്യമായ സംഭവം അറിയിക്കുന്നു +Comment[mr]=महत्वाच्या घटना करिता सूचीत करतो +Comment[nb]=Varsler om en kritisk hendelse +Comment[nds]=Gifft över en kritisch Begeefnis bescheed +Comment[nl]=Meldt een kritieke gebeurtenis +Comment[nn]=Varslar om noko viktig +Comment[or]=ଗୋଟିଏ ଗମ୍ଭୀର ସ୍ଥିତିକୁ ଜଣାଇଥାଏ +Comment[pa]=ਇੱਕ ਨਾਜ਼ੁਕ ਈਵੈਂਟ ਲਈ ਸੂਚਨਾ +Comment[pl]=Powiadomienie o zdarzeniu krytycznym +Comment[pt]=Notifica um evento crítico +Comment[pt_BR]=Notifica um evento crítico +Comment[ro]=Notifică un eveniment critic +Comment[ru]=Уведомление о критическом событии +Comment[si]=දරුණු අවස්ථාවක් අඟවයි +Comment[sk]=Upozorňuje na kritickú udalosť +Comment[sl]=Obvestilo o kritičnem dogodku +Comment[sr]=Обавештава о критичном догађају +Comment[sr@ijekavian]=Обавјештава о критичном догађају +Comment[sr@ijekavianlatin]=Obavještava o kritičnom događaju +Comment[sr@latin]=Obaveštava o kritičnom događaju +Comment[sv]=Underrättar om en kritisk händelse +Comment[ta]=Notifies a critical event +Comment[te]=సంక్లిష్ట ఘటనను తెలుపుతుంది +Comment[tg]=Событие колеса в заголовке: +Comment[th]=แจ้งให้ทราบถึงเหตุการณ์ขั้นวิกฤติ +Comment[tr]=Bir kritik olayı bildirir +Comment[ug]=جىددىي ھادىسە ئۇقتۇرۇشى +Comment[uk]=Сповіщає про критичну подію +Comment[wa]=Notifieye èn evenmint critike +Comment[x-test]=xxNotifies a critical eventxx +Comment[zh_CN]=危急事件通知 +Comment[zh_TW]=通知緊急事件 + +[Event/lowbattery] +Name=Battery Low +Name[bs]=Nizak nivo baterije +Name[ca]=Bateria baixa +Name[ca@valencia]=Bateria baixa +Name[cs]=Baterie je téměř vybitá +Name[da]=Lavt batteri +Name[de]=Akku-Ladestand niedrig +Name[el]=Μπαταρία χαμηλή +Name[en_GB]=Battery Low +Name[es]=Batería baja +Name[et]=Aku laetus on madal +Name[eu]=Bateria baxua +Name[fi]=Akku vähissä +Name[fr]=Batterie faible +Name[ga]=Cadhnra Íseal +Name[gl]=Batería baixa +Name[he]=הסוללה במצב נמוכה +Name[hu]=Az akkumulátor gyenge +Name[ia]=Batteria basse +Name[is]=Lítið eftir á rafhlöðu +Name[kk]=Батареясы сарқылды +Name[ko]=배터리 부족 +Name[lt]=Akumuliatorius ištuštėjęs +Name[mr]=बॅटरी कमी +Name[nb]=Lavt batteri +Name[nds]=Batterie siet +Name[nl]=Accu op laag niveau +Name[pa]=ਘੱਟ ਬੈਟਰੀ +Name[pl]=Bateria na niskim poziomie +Name[pt]=Bateria Fraca +Name[pt_BR]=Bateria fraca +Name[ro]=Acumulator scăzut +Name[ru]=Низкий уровень заряда батареи +Name[sk]=Batéria je slabá +Name[sl]=Nizka raven baterije +Name[sr]=Батерија при крају +Name[sr@ijekavian]=Батерија при крају +Name[sr@ijekavianlatin]=Baterija pri kraju +Name[sr@latin]=Baterija pri kraju +Name[sv]=Dåligt batteri +Name[tr]=Pil Düşük +Name[uk]=Низький рівень заряду +Name[x-test]=xxBattery Lowxx +Name[zh_CN]=电池电量低 +Name[zh_TW]=電池電力偏低 +Comment=Your battery has reached low level +Comment[ar]=وصلت بطاريتك إلى مستوى منخفض +Comment[ast]=La batería llegó al nivel baxu +Comment[be@latin]=Tvaja batareja maje nizki zarad. +Comment[bg]=Батерията е достигнала ниско ниво +Comment[bn]=আপনার ব্যাটারি নিম্ন মাত্রায় পৌঁছেছে +Comment[bs]=Popunjenost baterije pala je nizak nivo +Comment[ca]=La bateria ha arribat al nivell baix +Comment[ca@valencia]=La bateria ha arribat al nivell baix +Comment[cs]=Baterie dosáhla nízké úrovně +Comment[csb]=Twòjô baterëjô mô nisczi stón naładowaniô +Comment[da]=Dit batteri har nået lavt niveau +Comment[de]=Der Ladestand Ihres Akkus hat einen niedrigen Wert erreicht. +Comment[el]=Η μπαταρία σας έχει βρεθεί σε χαμηλή στάθμη ενέργειας +Comment[en_GB]=Your battery has reached low level +Comment[eo]=Via baterio atingis malaltan nivelon +Comment[es]=Su batería ha llegado al nivel bajo +Comment[et]=Aku täituvus on madal +Comment[eu]=Bateria behe-mailara iritsi da +Comment[fi]=Akku on vähissä +Comment[fr]=Votre batterie a atteint un niveau bas +Comment[fy]=Jo batterij hat in leech nivo berikt +Comment[ga]=Shroich do chadhnra leibhéal íseal +Comment[gl]=A batería acadou o nivel de carga baixa +Comment[gu]=તમારી બેટ્રી નીચા સ્તર પર પહોંચી ગઇ છે +Comment[he]=הסוללה הגיע לרמה נמוכה +Comment[hi]=आपकी बैटरी का स्तर कम हो गया है +Comment[hne]=आपमन के बैटरी के पावर कम हो गे हे +Comment[hr]=Vaša baterija je oslabila +Comment[hsb]=Aku je nětko skoro prózdny. +Comment[hu]=A telepek feltöltöttsége alacsony szintű +Comment[ia]=Tu batteria ha attingite nivello basse +Comment[id]=Baterai anda telah mencapai level yang rendah +Comment[is]=Rafhlaðan er við lægstu mörk +Comment[ja]=バッテリ残量が低レベルに達しました +Comment[kk]=Батареяңыздың қуаты аз +Comment[km]=ថ្ម​របស់​​​អ្នក​បាន​ឈាន​ដល់​កម្រិត​ទាប +Comment[kn]=ನಿನ್ನ ವಿದ್ಯುತ್ಕೋಶವು ಕ್ಷೀಣ ಸ್ಥಿತಿಗೆ ತಲುಪಿದೆ +Comment[ko]=배터리에 남은 용량이 적습니다 +Comment[lt]=Jūsų akumuliatorius pasiekė žemą lygmenį +Comment[lv]=Jūsu baterija ir sasniegusi zemu līmeni +Comment[mai]=अहाँक बैटरीक स्तर कम भ' गेल अछि +Comment[mk]=Вашата батерија достигна ниско ниво +Comment[ml]=നിങ്ങളുടെ ബാറ്ററി കുറവായ നില എത്തിയിരിക്കുന്നു +Comment[mr]=बॅटरी किमान पातळी पर्यंत पोहचली आहे +Comment[nb]=Batteriet har nådd lavt nivå +Comment[nds]=Dien Batteriestoop is nu "Siet" +Comment[nl]=Uw accu heeft het lage niveau bereikt +Comment[nn]=Batterinivået er lågt +Comment[or]=ଆପଣଙ୍କର ବ୍ୟାଟେରୀ ନିମ୍ନ ସ୍ତରରେ ପହଞ୍ଚିଯାଇଛି +Comment[pa]=ਤੁਹਾਡੀ ਬੈਟਰੀ ਘੱਟ ਲੈਵਲ ਤੱਕ ਅੱਪੜ ਗਈ ਹੈ +Comment[pl]=Bateria osiągnęła niski poziom naładowania +Comment[pt]=A sua bateria atingiu um nível baixo +Comment[pt_BR]=Sua bateria atingiu um nível baixo +Comment[ro]=Acumulatorul a atins un nivel scăzut +Comment[ru]=Низкий уровень заряда батареи +Comment[si]=ඔබේ බැටරිය අවම ප්‍රමාණයට පැමිණ ඇත. +Comment[sk]=Batéria dosiahla nízku úroveň +Comment[sl]=Baterija je dosegla nizko raven napolnjenosti +Comment[sr]=Попуњеност батерије пала је низак ниво +Comment[sr@ijekavian]=Попуњеност батерије пала је низак ниво +Comment[sr@ijekavianlatin]=Popunjenost baterije pala je nizak nivo +Comment[sr@latin]=Popunjenost baterije pala je nizak nivo +Comment[sv]=Batteriet har nått en låg nivå +Comment[ta]=Your battery has reached low level +Comment[te]=మీ బ్యాటరీ కనిష్ట స్థాయికి చేరినది +Comment[tg]=Барқи батарея ба итмом мерасад +Comment[th]=ประจุแบตเตอรี่ของคุณอยู่ในระดับต่ำ +Comment[tr]=Pil seviyesi düşük düzeye ulaştı +Comment[ug]=توكدان توكى تۆۋەن سەۋىيىگە يەتتى +Comment[uk]=У вашому акумуляторі закінчується заряд +Comment[wa]=Vosse batreye a-st arivé å bas livea +Comment[x-test]=xxYour battery has reached low levelxx +Comment[zh_CN]=电池电量过低 +Comment[zh_TW]=您的電池電力已達不足的程度 +Contexts=warningnot +Sound=KDE-Sys-Warning.ogg +Action=Sound|Popup +IconName=battery-caution + +[Event/criticalbattery] +Name=Battery Critical +Name[bs]=Baterija kritična +Name[ca]=Bateria crítica +Name[ca@valencia]=Bateria crítica +Name[cs]=Baterie na kritické úrovni +Name[da]=Kritisk batteri +Name[de]=Akku-Ladestand kritisch +Name[el]=Μπαταρία κρίσιμη +Name[en_GB]=Battery Critical +Name[es]=Batería en nivel crítico +Name[et]=Aku kriitiline tase +Name[eu]=Bateria oso gutxi +Name[fi]=Akku kriittisellä tasolla +Name[fr]=Batterie critique +Name[ga]=Cadhnra Criticiúil +Name[gl]=Batería no nivel crítico +Name[he]=סוללה במצב קריטי +Name[hu]=Kritikus lemerültség +Name[ia]=Batteria critic +Name[is]=Rafhlaða að tæmast +Name[kk]=Батарея дағдарысты деңгейде +Name[ko]=배터리 바닥남 +Name[lt]=Akumuliatoriaus kritinis lygmuo +Name[mr]=बॅटरी संकटात +Name[nb]=Batteri på kritisk nivå +Name[nds]=Batterie kritisch +Name[nl]=Accu op kritiek niveau +Name[pa]=ਬੈਟਰੀ ਨਾਜ਼ੁਕ ਲੈਵਲ +Name[pl]=Bateria na poziomie krytycznym +Name[pt]=Bateria Crítica +Name[pt_BR]=Bateria em nível crítico +Name[ro]=Acumulator critic +Name[ru]=Критический уровень заряда батареи +Name[sk]=Kritická úroveň batérie +Name[sl]=Kritična raven baterije +Name[sr]=Батерија критична +Name[sr@ijekavian]=Батерија критична +Name[sr@ijekavianlatin]=Baterija kritična +Name[sr@latin]=Baterija kritična +Name[sv]=Kritiskt batteri +Name[tr]=Pil Seviyesi Kritik +Name[uk]=Заряд на критичному рівні +Name[x-test]=xxBattery Criticalxx +Name[zh_CN]=电池电量危急 +Name[zh_TW]=電池電力嚴重不足 +Comment=Your battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on. +Comment[ar]=وصلت بطاريتك إلى مستوى حرج. هذا التنبيه يطلق عداً تنازلياً قبل أن ينفذ الإجراء المضبوط مسبقا؛ لذا ينصح بشده تركه مفعلاً. +Comment[ast]=La batería llegó al nivel críticu. Esta notificación entama un cuntador enantes d'executar l'aición configurada, encamiéntase dexar esta configuración activada. +Comment[be@latin]=Tvaja batareja maje vielmi nizki zarad. Hetaje paviedamleńnie ŭklučaje ličylnik da času vykanańnia aznačanych dziejańniaŭ. My raim pakinuć jaho ŭklučanym. +Comment[bg]=Батерията се изтощи до критично ниво. Започва обратно броене и се препоръчва да го оставите. +Comment[bs]=Popunjenost baterija je spala na kritičan nivo. Ovo obavještenje okida odbrojavanje prije izvođenja podešene radnje, stoga vam ozbiljno savetujemo da ga ostavite uključenim. +Comment[ca]=La bateria ha arribat al nivell crític. Aquesta notificació activa un compte enrere abans d'efectuar l'acció configurada, per tant, es recomana deixar-ho actiu. +Comment[ca@valencia]=La bateria ha arribat al nivell crític. Esta notificació activa un compte arrere abans d'efectuar l'acció configurada, per tant, es recomana deixar-ho actiu. +Comment[cs]=Baterie dosáhla kritické úrovně. Tímto upozorněním se spustí odpočet a následně se provede nastavená činnost, proto je doporučeno nezasahovat. +Comment[da]=Dit batteri har nået kritisk niveau. Denne bekendtgørelse udløser en nedtælling før den konfigurerede handling udføres, derfor anbefales det kraftigt at lade den være slået til. +Comment[de]=Der Ladestand Ihres Akkus hat einen kritischen Wert erreicht. Diese Benachrichtigung löst einen Rückwärtszähler aus, bevor die eingestellte Aktion ausgeführt wird. Es wird dringend empfohlen, diese Einstellung aktiviert zu lassen. +Comment[el]=Η μπαταρία σας βρίσκεται σε κρίσιμη στάθμη ενέργειας. Η ειδοποίηση αυτή ενεργοποιεί μια αντίστροφη μέτρηση πριν την εκτέλεση της διαμορφωμένης ενέργειας. Συστήνεται έντονα η ενεργοποίηση αυτής της λειτουργίας. +Comment[en_GB]=Your battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on. +Comment[eo]=Via baterio atingis danĝeran nivelon. Tiu sciigo lanĉis nombradon ĝis nulo antaŭ lanĉi agordon, tiucele ni substrekas la neceson lasi tiun funkcion aktiva. +Comment[es]=Su batería ha llegado al nivel crítico. Esta notificación inicia un contador antes de ejecutar la acción configurada, se recomienda dejar esta configuración habilitada. +Comment[et]=Aku täituvus on jõudnud kriitilisele tasemele. See märguanne toob teatava aja pärast kaasa seadistatud toimingu, mistõttu see on väga soovitatav jätta sisselülitatuks. +Comment[eu]=Bateria maila kritikora iritsi da. Jakinarazpen honek atzekoz aurrerako zenbaketa bat abiarazten du konfiguratutako ekintza egin aurretik; beraz, oso gomendagarria da hori gaituta uztea. +Comment[fi]=Akkusi varaus on kriittisen vähissä. Tämä ilmoitus käynnistää lähtölaskennan ennen asetetun toiminnon tekemistä, joten on hyvin suositeltavaa jättää tämä päälle. +Comment[fr]=Votre batterie a atteint un niveau critique. Cette notification déclenche un compte à rebours avant de lancer l'action configurée. Il est par conséquent fortement recommandé de laisser cette fonction active. +Comment[fy]=Jo batterij hat in krityknivo berikt. Dizze notifikaasje aktivearet in ôftelling foardat de ynstelde aksje begjinne sil. It wurdt oanrêt dit ynskeakele te litten. +Comment[ga]=Shroich do chadhnra leibhéal criticiúil. Tosaíonn an fógra seo comhaireamh síos sula ndéanfar an gníomh cumraithe, agus mar sin moltar go láidir duit é a fhágáil ar siúl. +Comment[gl]=A batería acadou o nivel crítico. Esta notificación inicia unha conta-atrás previa a realizar a acción configurada, polo que se recomenda que a deixe seguir. +Comment[he]=הסוללה הגיע לרמה קריטית. הודעה זו מתחילה ספירה לאחור לפני ביצוע הפעולה המוגדרת, לפיכך מומלץ בחום להשאיר אותה פתוחה. +Comment[hne]=आपमन के बैटरी हर एकदम सिराय गे हे. ये सूचना एक उलटी गिनती चालू करही अउ पहिली से बताय काम करही. ते पाय एला अइसने रहिन देव. +Comment[hr]=Baterija je kritično oslabila. Ova obavijest uključuje odbrojavanje prije obavljanja podešene akcije, pa je zbog toga jako preporučeno da ostavite ovo upaljeno. +Comment[hsb]=Aku je kritisce prózdny. Tute skedźbnjenje startuje countdown před konfigurowanej akciju, tuž so doporuči jón nic přetorhnyć. +Comment[hu]=A telepek kritikus szintre merültek, visszaszámlálás után a rendszer végrehajtja a beállított műveletet (kérjük ne zárja be a számlálót). +Comment[ia]=Tu batteria ha attingite nivello critic. Iste notification pone in marcha un computo reverso ante que facer le action configurate, dunque tu es fortemente avisate de lassar lo connectite. +Comment[id]=Baterai anda telah mencapai level kritis. Notifikasi ini memicu penghitungan mundur sebelum melakukan aksi yang diatur, sehingga sangat disarankan untuk membiarkan aksi tersebut tetap hidup. +Comment[is]=Rafhlaðan hefur náð hættumörkum. Þessi aðvörun setur í gang niðurtalningu, sem síðan setur í gang ákveðna aðgerð sem stillt hefur verið. Þar með er ráðlegt að leyfa því ferli að hafa sinn gang. +Comment[ja]=バッテリ残量が危険レベルに達しました。この通知によって、このレベルに設定されているアクションのカウントダウンが開始されるので、有効にしておくことを強くお勧めします。 +Comment[kk]=Батареяңыз әбден сарқытылды. Бұл құлақтандырумен бұл жағдайға бағышталған амалға қалған уакыт санауы басталады, бұған кедергі қылмауы абзал. +Comment[km]=ថ្ម​របស់​អ្នក​បានដល់កម្រិត​សំខាន់ ។ ការ​ជូនដំណឹង​នេះ​កេះ​ឲ្យ​រាប់​ថយ​ក្រោយ​មុនធ្វើ​​សកម្មភាព​ដែល​បានកំណត់​រចនាសម្ព័ន្ធ ដូច្នេះ​វា​ត្រូវ​បានផ្ដល់​អនុសាសន៍​ឲ្យ​ទុក​វា​សិន ។ +Comment[ko]=배터리가 부족합니다. 설정된 동작을 실행할 때까지 잠깐 동안의 여유가 있으며, 그 시간 동안 작업을 정리하십시오. +Comment[lt]=Jūsų akumuliatoriaus įkrova pasiekė kritinį lygmenį. Šis perspėjimas sužadina atvirkštinį skaičiavimą, kuriam pasibaigus bus atliekamas konfigūruotas veiksmas, tad primygtinai siūlome palikti šį nustatymą įjungtą +Comment[lv]=Jūsu baterija ir sasniegisi kritisku līmeni. Šis paziņojums sāk laika atskaiti līdz konfigurētajai darbībai, tāpēc ir ļoti vēlams atstāt to redzamu. +Comment[mk]=Вашата батерија достигна критично ниво. Ова известување предизвикува одбројување пред да се изврши конфигурираното дејство и е многу препорачливо тоа да остане вклучено. +Comment[ml]=നിങ്ങളുടെ ബാറ്ററി ഗുരുതരമായ നിലയില്‍ എത്തിയിരിയ്ക്കുന്നു. ഈ അറിയിപ്പ് ഒരു കഴിഞ്ഞാല്‍ ക്രമീകരിച്ച പ്രവര്‍ത്തനം തുടങ്ങുന്നതിനു് മുമ്പു് ഒരു കൌണ്ട്ഡൌണ്‍ ആരംഭിയ്ക്കും, അതിനാല്‍ ഇതു് സജീവമായി വയ്ക്കാന്‍ ശക്തിയായി ഉപദേശിക്കുന്നു. +Comment[mr]=बॅटरी संकटाच्या पातळी पर्यंत पोहचली आहे. ही सूचना संयोजीत क्रिया करण्यापूर्वी काऊन्टडाउन सक्रिय करते, ज्यामुळे त्यांस वगळण्यास सूचविले जाते. +Comment[nb]=Batteriet har nådd kritisk nivå. Denne varslingen utløser en nedtelling før den innstilte handlinga utføres, så det tilrådes sterkt å la den stå på. +Comment[nds]=Dien Batterie is bi de kritische Stoop ankamen. Disse Bescheed tellt en Tiet daal, ehr he de instellte Akschoon utföhrt, laat em also beter an. +Comment[nl]=Uw accu heeft het kritieke niveau bereikt. Deze melding activeert een aftelling voordat de ingestelde actie zal worden uitgevoerd. Het wordt ten zeerste aanbevolen dit ingeschakeld te laten. +Comment[nn]=Batterinivået er kritisk lågt +Comment[pa]=ਤੁਹਾਡੀ ਬੈਟਰੀ ਨਾਜ਼ੁਕ ਲੈਵਲ ਤੱਕ ਘੱਟ ਗਈ ਹੈ। ਇਹ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੰਰਚਿਤ ਕੀਤੇ ਐਕਸ਼ਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਲਟੀ-ਗਿਣਟੀ ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ, ਇਸਕਰਕੇ ਇਸ ਨੂੰ ਚੱਲਣ ਦੀ ਸਲਾਹ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ। +Comment[pl]=Bateria osiągnęła krytyczny poziom. To powiadomienie rozpoczyna także odliczanie przed wykonaniem skonfigurowanego działania, więc dobrze jest je zostawić. +Comment[pt]=A sua bateria atingiu um nível crítico. Esta notificação despoleta uma contagem antes de efectuar a acção configurada; por isso, recomenda-se que deixe a opção ligada. +Comment[pt_BR]=Sua bateria atingiu um nível crítico. Esta notificação aciona uma contagem antes de realizar a ação configurada. Por isso, recomenda-se deixar a opção ativada. +Comment[ro]=Acumulatorul a atins nivelul critic. Această notificare declanșează o numărătoare inversă pînă la executarea acțiunii implicite, deci se recomandă să îl lăsați activat. +Comment[ru]=Заряд батареи достиг критического уровня. Это уведомление добавляет задержку перед выполнением выбранного действия, потому желательно его оставить включённым. +Comment[si]=ඔබේ බැටරිය දරුණු ලෙස පහළයි. මෙම දැන්වීම සැකසූ ක්‍රියාව ක්‍රියාත්මක කිරීමට පෙර අවරෝහණ ගණනයක් සිදු කරයි. එය සක්‍රීය කර තැබීම නිර්දේශිතයි. +Comment[sk]=Vaša batéria dosiahla kritickú úroveň nabitia. Toto upozornenie spustí odpočítavanie pred vykonaním prednastavenej akcie, preto je vysoko doporučené nechať ho zapnuté. +Comment[sl]=Baterija je dosegla kritično raven izpraznjenosti. To obvestilo sproži odštevanje do izvedbe nastavljenega dejanja, zato močno priporočamo, da to pustite omogočeno. +Comment[sr]=Попуњеност батерија је спала на критичан ниво. Ово обавештење окида одбројавање пре извођења подешене радње, стога вам озбиљно саветујемо да га оставите укљученим. +Comment[sr@ijekavian]=Попуњеност батерија је спала на критичан ниво. Ово обавјештење окида одбројавање прије извођења подешене радње, стога вам озбиљно савјетујемо да га оставите укљученим. +Comment[sr@ijekavianlatin]=Popunjenost baterija je spala na kritičan nivo. Ovo obavještenje okida odbrojavanje prije izvođenja podešene radnje, stoga vam ozbiljno savjetujemo da ga ostavite uključenim. +Comment[sr@latin]=Popunjenost baterija je spala na kritičan nivo. Ovo obaveštenje okida odbrojavanje pre izvođenja podešene radnje, stoga vam ozbiljno savetujemo da ga ostavite uključenim. +Comment[sv]=Batteriet har nått kritisk nivå. Den här underrättelsen utlöser en nerräkning innan den inställda åtgärden utförs, därmed råds du att lämna den på. +Comment[ta]=Your battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on. +Comment[te]=మీ బ్యాటరీ సంక్లిష్ట స్థాయిని చేరుకుంది. ఈ నోటీసు ఆకృతీకరించిన చర్యను జరుపుటకు ముందుగా కౌంట్‌డౌన్‌ (దిగువలెక్కింపు)ను జురుపుతుంది, అందుకని దానిని అలా వదిలి వేయమని గట్టిగా సిఫార్సు చేయడమైంది. +Comment[th]=แบตเตอรี่ของคุณเหลือประจุไฟอยู่ในระดับวิกฤติ การแจ้งให้ทราบนี้จะเริ่มการนับถอยหลัง ก่อนจะทำการกระทำตามที่ได้ปรับแต่งค่าเอาไว้ ซึ่งขอแนะนำให้คงการกระทำดังกล่าวเอาไว้ +Comment[tr]=Pil seviyeniz kritik duruma ulaştı. Bu bildirim yapılandırılmış eylemi gerçekleştirmeden önce bir geri sayım işlemini tetikler. Bu seçeneği açık bırakmanız şiddetle önerilir. +Comment[ug]=توكدان توكى جىددىي سەۋىيىگە يەتتى. سىستېما ئۇقتۇرۇشى بىر قېتىم ئاگاھلاندۇرغاندىن كېيىن سىز سەپلىگەن مەشغۇلاتنى ئىجرا قىلىدۇ. بۇ تەڭشەكنى ئوچۇق قويۇشىڭىزنى كۈچلۈك تەۋسىيە قىلىمىز. +Comment[uk]=Заряд акумулятора вашого комп’ютера досяг критичного рівня. За цим сповіщенням буде почато відлік часу до виконання відповідної налаштованої дії, отже, ми наполегливо рекомендуємо вам не вимикати цей пункт. +Comment[wa]=Vosse batreye a-st arivé a on livea critike. Ci notifiaedje enonde ene munutreye divant d' fé l' faitindje d' apontieye, dabôrd il est mo rcomandé di låtchî ça. +Comment[x-test]=xxYour battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on.xx +Comment[zh_CN]=电池电量达到危急等级。系统通知将会在一次倒计时后执行您配置的动作,强烈建议您保留此设定为开启。 +Comment[zh_TW]=您的電池電力已到嚴重警告區。這個通知發出後將會開始倒數計時,時間到後就會進行設定好的動作。建議您保持此項開啟。 +Contexts=warningnot +Sound=KDE-Sys-App-Error-Critical.ogg +Action=Sound|Popup +IconName=dialog-warning + +[Event/fullbattery] +Name=Charge Complete +Name[bs]=Gotovo punjenje +Name[ca]=Càrrega completada +Name[ca@valencia]=Càrrega completada +Name[cs]=Nabití bylo dokončeno +Name[da]=Opladning fuldført +Name[de]=Vollständig geladen +Name[el]=Φόρτιση πλήρης +Name[en_GB]=Charge Complete +Name[es]=Carga completa +Name[et]=Laadimine on tehtud +Name[eu]=Karga beteta +Name[fi]=Lataus valmis +Name[fr]=Charge terminée +Name[ga]=Luchtaithe +Name[gl]=Carga completa +Name[he]=טעינה הושלמה +Name[hu]=Töltés befejezve +Name[ia]=Cargamento completate +Name[is]=Full hleðsla +Name[kk]=Толтыруы бітті +Name[ko]=충전 완료됨 +Name[lt]=Įkrovimas baigtas +Name[mr]=चार्ज पूर्ण +Name[nb]=Fullført lading +Name[nds]=Opladen afslaten +Name[nl]=Laden voltooid +Name[pa]=ਚਾਰਜ ਪੂਰਾ +Name[pl]=Ukończono ładowanie +Name[pt]=Carga Completa +Name[pt_BR]=Carga completa +Name[ro]=Încărcare finalizată +Name[ru]=Зарядка завершена +Name[sk]=Nabíjanie ukončené +Name[sl]=Polnjenje zaključeno +Name[sr]=Пуњење довршено +Name[sr@ijekavian]=Пуњење довршено +Name[sr@ijekavianlatin]=Punjenje dovršeno +Name[sr@latin]=Punjenje dovršeno +Name[sv]=Laddning klar +Name[tr]=Şarj Tamamlandı +Name[uk]=Заряджання завершено +Name[x-test]=xxCharge Completexx +Name[zh_CN]=充电完成 +Name[zh_TW]=充電完成 +Comment=The battery is fully charged +Comment[bs]=Baterija je potpuno puna +Comment[ca]=La bateria està totalment carregada +Comment[ca@valencia]=La bateria està totalment carregada +Comment[cs]=Baterie je plně nabitá +Comment[da]=Batteriet er fuldt opladet +Comment[de]=Der Akku ist nun vollständig geladen +Comment[el]=Η μπαταρία έχει φορτιστεί πλήρως +Comment[en_GB]=The battery is fully charged +Comment[es]=La batería está completamente cargada +Comment[et]=Aku on täielikult laetud +Comment[eu]=Bateria erabat kargatuta dago +Comment[fi]=Akku on ladattu täyteen +Comment[fr]=La batterie est totalement chargée +Comment[gl]=A batería ten a carga completa +Comment[he]=הסוללה טעונה במלואה +Comment[hu]=Az akkumulátor teljesen feltöltve +Comment[ia]=Le batteria es cargate completemente +Comment[is]=Rafhlaðan er nú fullhlaðin +Comment[kk]=Батареясы әбден толды +Comment[ko]=배터리가 완전히 충전됨 +Comment[lt]=Akumuliatorius pilnai įkrautas +Comment[mr]=बॅटरी पूर्णतया चार्ज झालेली आहे +Comment[nb]=Batteriet er fullt ladet +Comment[nds]=De Batterie is heel laadt +Comment[nl]=De accu is volledig geladen +Comment[pa]=ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੈ +Comment[pl]=Bateria jest w pełni naładowana +Comment[pt]=A bateria está completamente carregada +Comment[pt_BR]=A bateria está completamente carregada +Comment[ro]=Acumulatorul este încărcat complet +Comment[ru]=Батарея полностью заряжена +Comment[sk]=Batéria je plne nabitá +Comment[sl]=Baterija je povsem napolnjena +Comment[sr]=Батерија је потпуно напуњена +Comment[sr@ijekavian]=Батерија је потпуно напуњена +Comment[sr@ijekavianlatin]=Baterija je potpuno napunjena +Comment[sr@latin]=Baterija je potpuno napunjena +Comment[sv]=Batteriet är fulladdat +Comment[tr]=Pil tam şarjlı +Comment[uk]=Акумулятор повністю заряджено +Comment[x-test]=xxThe battery is fully chargedxx +Comment[zh_CN]=电池已充满 +Comment[zh_TW]=電池已充飽 +Contexts=stdnot +Sound=KDE-Sys-App-Positive.ogg +Action= +IconName=battery-100 + +[Event/pluggedin] +Name=AC adaptor plugged in +Name[ar]=وصل قابس الطاقة +Name[ast]=Adautador de corriente coneutáu +Name[be@latin]=Padłučany blok siłkavańnia +Name[bg]=Адапторът е включен +Name[bn]=এ-সি অ্যাডাপ্টর লাগানো +Name[bs]=AC adapter utaknut +Name[ca]=Adaptador de CA endollat +Name[ca@valencia]=Adaptador de CA endollat +Name[cs]=AC adaptér zapojen +Name[csb]=Wëtkniãti zasëlôcz +Name[da]=Strømforsyning tilsluttet +Name[de]=Netzkabel angeschlossen +Name[el]=Σύνδεση με μετασχηματιστή AC +Name[en_GB]=AC adaptor plugged in +Name[es]=Adaptador de corriente conectado +Name[et]=Ühendati elektrivõrku +Name[eu]=Korronte alternoko egokigailua konektatuta +Name[fi]=Kytkettiin verkkovirtaan +Name[fr]=Adaptateur secteur branché +Name[fy]=AC adapter ynstútsen +Name[ga]=Tá an cuibheoir SA plugáilte isteach +Name[gl]=Enchufouse a alimentación externa +Name[gu]=AC એડપ્ટર લગાવવામાં આવ્યું +Name[he]=מתאם החשמל חובר +Name[hi]=एसी एडॉप्टर प्लग में लगा है +Name[hne]=एसी पिन प्लग मं लगे हे +Name[hr]=Priključen je AC adapter +Name[hsb]=Milinowy adapter přizamknjeny +Name[hu]=Tápcsatlakozó bedugva +Name[ia]=Adaptator AC connectite +Name[id]=Adaptor AC ditancapkan +Name[is]=AC spennubreytir tengdur +Name[ja]=AC アダプタが接続されました +Name[kk]=Айнымалы тоқ адаптері қосылған +Name[km]=បាន​ដោត​អាដាប់ទ័រ AC +Name[kn]=AC ವಿದ್ಯಚ್ಛಕ್ತಿ ಅನುಕಾರಕವನ್ನು (ಅಡಾಪ್ಟರ್) ಅಳವಡಿಸಲಾಗಿದೆ +Name[ko]=AC 어댑터 연결됨 +Name[ku]=Adaptora AC girêdayî ye +Name[lt]=Prijungtas AC adapteris +Name[lv]=Iesprausts barošanas vads +Name[mk]=AC-адаптерот е вклучен +Name[ml]=എസി അഡാപ്റ്റര്‍ കുത്തിയിരിക്കുന്നു +Name[mr]=AC अडॅप्टर प्लग केले +Name[nb]=Strømadapteret er koblet til +Name[nds]=Stroomkavel tokoppelt +Name[nl]=Netstroomadapter aangesloten +Name[nn]=Straumkontakten er kopla i +Name[or]=AC ଏଡ଼ପଟର ପ୍ଲଗ ହୋଇଛି +Name[pa]=AC ਐਡਪਟਰ ਪਲੱਗ ਲੱਗਾ ਹੈ +Name[pl]=Podłączenie zasilania zewnętrznego +Name[pt]=Ligado à corrente +Name[pt_BR]=Adaptador de energia conectado +Name[ro]=Adaptor de curent alternativ atașat +Name[ru]=Подключён к электрической сети +Name[si]=AC ඇඩැප්ටරය සවිකර ඇත +Name[sk]=Napájanie zo siete pripojené +Name[sl]=Napajanje iz električnega omrežja +Name[sr]=АЦ адаптер утакнут +Name[sr@ijekavian]=АЦ адаптер утакнут +Name[sr@ijekavianlatin]=AC adapter utaknut +Name[sr@latin]=AC adapter utaknut +Name[sv]=Nätadapter inkopplad +Name[ta]=AC adaptor plugged in +Name[te]=AC ఎడాప్టర్ ప్లగ్ చేయబడింది +Name[tg]=Сетевой адаптер: подключен +Name[th]=มีการเสียบสายตัวแปลงไฟเข้ามา +Name[tr]=AC adaptörünün fişi takıldı +Name[ug]=ئۆزگىرىشچان توك ماسلاشتۇرغۇچنى چاتقاندا +Name[uk]=Увімкнено живлення від мережі +Name[vi]=Đã gắn bộ sạc AC +Name[wa]=Adaptateu AC tchôkî +Name[x-test]=xxAC adaptor plugged inxx +Name[zh_CN]=已插入交流适配器 +Name[zh_TW]=AC 電源已插入 +Comment=The power adaptor has been plugged in +Comment[ar]=تم توصيل قابس الطاقة +Comment[ast]=Coneutóse l'adautador de corriente +Comment[be@latin]=Padłučany blok siłkavańnia. +Comment[bg]=Адапторът е включен +Comment[bn]=পাওয়ার অ্যাডাপ্টর লাগানো হয়েছে +Comment[bs]=Utaknut je adapter spoljašnjeg napajanja +Comment[ca]=L'adaptador de corrent s'ha endollat +Comment[ca@valencia]=L'adaptador de corrent s'ha endollat +Comment[cs]=Zdroj napájení byl připojen +Comment[csb]=Zasëlôcz òstôł wetkniãti +Comment[da]=Strømforsyningen er blevet tilsluttet +Comment[de]=Das Netzkabel ist angeschlossen worden. +Comment[el]=Ο μετασχηματιστής ρεύματος συνδέθηκε +Comment[en_GB]=The power adaptor has been plugged in +Comment[eo]=la energia ŝnuro konektiĝis +Comment[es]=Se ha conectado el adaptador de corriente +Comment[et]=Arvuti ühendati elektrivõrku +Comment[eu]=Elikagailua konektatu da +Comment[fi]=Tietokone kytkettiin verkkovirtaan +Comment[fr]=L'adaptateur secteur a été branché +Comment[fy]=In stroomadapter is ynstutsen +Comment[ga]=Tá an cuibheoir cumhachta plugáilte isteach +Comment[gl]=Enchufouse o transformador de corrente +Comment[gu]=પાવર એડપ્ટર લગાવવામાં આવેલ છે +Comment[he]=מתאם החשמל חובר +Comment[hi]=पावर एडॉप्टर को प्लग में लगाया गया +Comment[hne]=पावर के प्लग लगिस +Comment[hr]=Priključen je priključak utičnice +Comment[hsb]=Milinowy adapter je so přizamknył +Comment[hu]=Az áramellátást biztosító tápcsatlakozó bedugva +Comment[ia]=Le adaptator de energia ha essite connectite +Comment[id]=Adaptop daya telah ditancapkan +Comment[is]=Spennubreytirinn hefur verið tengdur +Comment[ja]=電源アダプタが接続されました +Comment[kk]=Қуаттандыру адаптері қосылып тұр +Comment[km]=អាដាប់ទ័រ​ថាមពល​ត្រូវ​បាន​ដោត +Comment[kn]=ವಿದ್ಯುಚ್ಛಕ್ತಿ ಅನುಕಾರಕವನ್ನು (ಅಡಾಪ್ಟರ್) ಅಳವಡಿಸಲಾಗಿದೆ +Comment[ko]=AC 어댑터가 연결되었습니다 +Comment[ku]=Adaptorê hêzê hate girêdan +Comment[lt]=Kintamosios srovės adapteris buvo prijungtas +Comment[lv]=Tika iesprausts strāvas vads +Comment[mai]=पावर एडाप्टर केँ प्लग मे लगाएल गेल अछि +Comment[mk]=Вклучен е адаптерот за ел. енергија +Comment[ml]=പവര്‍ അഡാപ്റ്റര്‍ പ്ലഗ്ഗിലേക്ക് കുത്തിയിരിക്കുന്നു +Comment[mr]=पॉवर अडॅप्टरला प्लग केले गेले आहे +Comment[nb]=Strømadapteret er koblet til +Comment[nds]=Dat Stroomkavel wöör tokoppelt +Comment[nl]=De netstroomadapter is aangesloten +Comment[nn]=Straumkontakten er vorten kopla i +Comment[or]=ଶକ୍ତି ଏଡ଼ପଟରକୁ ପ୍ଲଗରେ ଲଗାହୋଇଛି +Comment[pa]=ਪਾਵਰ ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਲਗਾਇਆ ਗਿਆ +Comment[pl]=Podłączono zasilanie zewnętrzne +Comment[pt]=O computador foi ligado à corrente +Comment[pt_BR]=O adaptador de energia foi conectado +Comment[ro]=Adaptorul de alimentare a fost atașat +Comment[ru]=Ноутбук подключён к электрической сети +Comment[si]=විදුලි ඇඩැප්ටරය සවිකර ඇත +Comment[sk]=Napájanie zo siete bolo pripojené +Comment[sl]=Priključeno je bilo napajanje iz električnega omrežja +Comment[sr]=Утакнут је адаптер спољашњег напајања +Comment[sr@ijekavian]=Утакнут је адаптер спољашњег напајања +Comment[sr@ijekavianlatin]=Utaknut je adapter spoljašnjeg napajanja +Comment[sr@latin]=Utaknut je adapter spoljašnjeg napajanja +Comment[sv]=Nätadaptern har kopplats in +Comment[ta]=The power adaptor has been plugged in +Comment[tg]=Подключен блок питания +Comment[th]=มีการเสียบปลั๊กตัวแปลงไฟเข้ามาเพื่อทำการชาร์จไฟ +Comment[tr]=Güç adaptörünün fişi takıldı +Comment[ug]=توك مەنبە ماسلاشتۇرغۇچنى چاتقاندا +Comment[uk]=Було увімкнено живлення від мережі +Comment[wa]=L' adaptateu d' corant a stî tchôkî +Comment[x-test]=xxThe power adaptor has been plugged inxx +Comment[zh_CN]=已插入电源适配器 +Comment[zh_TW]=市電電源已插上 +Contexts=stdnot +Sound=KDE-Sys-App-Positive.ogg +Action=None +IconName=battery-charging-low + +[Event/unplugged] +Name=AC adaptor unplugged +Name[ar]=نزع قابس الطاقة +Name[ast]=Adautador de corriente desconeutáu +Name[be@latin]=Adłučany blok siłkavańnia +Name[bg]=Адапторът е изключен. +Name[bn]=এ-সি অ্যাডাপ্টর খোলা +Name[bs]=AC adapter izvučen +Name[ca]=Adaptador de CA desendollat +Name[ca@valencia]=Adaptador de CA desendollat +Name[cs]=AC adaptér odpojen +Name[csb]=Zasëlôcz òstôł wëjãti +Name[da]=Strømforsyning frakoblet +Name[de]=Netzkabel entfernt +Name[el]=Ο μετασχηματιστής ρεύματος AC αποσυνδέθηκε +Name[en_GB]=AC adaptor unplugged +Name[es]=Adaptador de corriente desconectado +Name[et]=Lahutati elektrivõrgust +Name[eu]=Korronte alternoko egokigailua deskonektatuta +Name[fi]=Poistuttiin verkkovirrasta +Name[fr]=Adaptateur secteur débranché +Name[fy]=AC adapter der út helle +Name[ga]=Cuibheoir SA díphlugáilte +Name[gl]=Desenchufouse a alimentación externa +Name[gu]=AC એડપ્ટર નીકાળી લેવામાં આવ્યું +Name[he]=מתאם החשמל נותק +Name[hi]=एसी एडॉप्टर का प्लग निकाला गया है +Name[hne]=पावर के प्लग निकलिस +Name[hr]=Isključen je AC adapter +Name[hsb]=Milinowy adapter wućehnjeny +Name[hu]=Tápcsatlakozó kihúzva +Name[ia]=Adaptator de AC disconnectite +Name[id]=Adaptop AC dicabut +Name[is]=AC spennubreytir aftengdur +Name[ja]=AC アダプタが取り外されました +Name[kk]=Айнымалы тоқ адаптері ажыратылған +Name[km]=បានដក​អាដាប់ទ័រ AC ចេញ +Name[kn]=AC ವಿದ್ಯುಚ್ಛಕ್ತಿ ಅನುಕಾರಕವನ್ನು (ಅಡಾಪ್ಟರ್) ತೆಗೆಯಲಾಗಿದೆ +Name[ko]=AC 어댑터 연결 끊김 +Name[ku]=Adaptora AC negirêdayî ye +Name[lt]=Atjungtas AC adapteris +Name[lv]=Izrauts barošanas vads +Name[mk]=AC-адаптерот е исклучен +Name[ml]=എസി അഡാപ്റ്റര്‍ പുറത്തെടുത്തിരിക്കുന്നു +Name[mr]=AC अडॅप्टर काढून टाकले +Name[nb]=Strømadapteret er dratt ut +Name[nds]=Stroomkavel ruttrocken +Name[nl]=Netstroomadapter niet aangesloten +Name[nn]=Straumkontakten er kopla ut +Name[or]=AC ଏଡ଼ପଟର ପ୍ଲଗ ହୋଇନାହିଁ +Name[pa]=AC ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਕੱਢਿਆ +Name[pl]=Odłączenie zasilania zewnętrznego +Name[pt]=Desligado da corrente +Name[pt_BR]=Adaptador de energia desconectado +Name[ro]=Adaptor de curent alternativ detașat +Name[ru]=Отключение от электрической сети +Name[si]=AC ඇඩැප්ටරය ගලවා ඇත +Name[sk]=Napájanie zo siete odpojené +Name[sl]=Konec napajanja iz električnega omrežja +Name[sr]=АЦ адаптер извучен +Name[sr@ijekavian]=АЦ адаптер извучен +Name[sr@ijekavianlatin]=AC adapter izvučen +Name[sr@latin]=AC adapter izvučen +Name[sv]=Nätadapter frånkopplad +Name[ta]=AC adaptor unplugged +Name[te]=AC ఎడాప్టర్ అన్‌ప్లగ్ చేయబడింది +Name[tg]=Блок питания отключен +Name[th]=ตัวแปลงไฟถูกถอดออก +Name[tr]=AC adaptörünün fişi çekildi +Name[ug]=ئۆزگىرىشچان توك مەنبە ماسلاشتۇرغۇچ ئۈزۈلگەندە +Name[uk]=Вимкнено живлення від мережі +Name[vi]=Đã tháo bộ sạc AC +Name[wa]=Adaptateu AC distchôkî +Name[x-test]=xxAC adaptor unpluggedxx +Name[zh_CN]=已拔出交流适配器 +Name[zh_TW]=AC 電源已拔除 +Comment=The power adaptor has been unplugged +Comment[ar]=تم نزع قابس الطاقة +Comment[ast]=Desconeutáu l'adautador de corriente +Comment[be@latin]=Adłučany blok siłkavańnia. +Comment[bg]=Адапторът е изключен +Comment[bn]=পাওয়ার অ্যাডাপ্টর খুলে ফেলা হয়েছে +Comment[bs]=Izvučen je adapter spoljašnjeg napajanja +Comment[ca]=L'adaptador de corrent s'ha desendollat +Comment[ca@valencia]=L'adaptador de corrent s'ha desendollat +Comment[cs]=Zdroj napájení byl odpojen +Comment[csb]=Zasëlôcz òstôł wëjãti +Comment[da]=Strømforsyningen er blevet frakoblet +Comment[de]=Das Netzkabel ist vom Rechner getrennt worden. +Comment[el]=Ο μετασχηματιστής ρεύματος αποσυνδέθηκε +Comment[en_GB]=The power adaptor has been unplugged +Comment[eo]=la energia ŝnuro malkonektiĝis +Comment[es]=Se ha desconectado el adaptador de corriente +Comment[et]=Arvuti lahutati elektrivõrgust +Comment[eu]=Elikagailua deskonektatu da +Comment[fi]=Tietokone otettiin pois verkkovirrasta +Comment[fr]=L'adaptateur secteur a été débranché +Comment[fy]=In stroomadapter is der út lutsen +Comment[ga]=Bhí an cuibheoir cumhachta díphlugáilte +Comment[gl]=Desenchufouse a fonte de alimentación +Comment[gu]=પાવર એડપ્ટર કાઢી નાખવામાં આવેલ છે +Comment[he]=מתאם החשמל נותק +Comment[hi]=पावर एडॉप्टर को प्लग से निकाला गया है +Comment[hne]=पावर के प्लग हर निकल गिस +Comment[hr]=Odštekan je priključak utičnice +Comment[hsb]=Milinowy adapter bu wućehnjeny +Comment[hu]=Az áramellátást biztosító tápcsatlakozó kihúzva +Comment[ia]=Le adaptator de energia ha essite disconnectite +Comment[id]=Adaptor daya telah dicabut +Comment[is]=Spennubreytirinn hefur verið aftengdur +Comment[ja]=電源アダプタが取り外されました +Comment[kk]=Қуаттандыру адаптері ажыратылып тұр +Comment[km]=អាប់ដាប់ទ័រ​ថាមពល​ត្រូវ​បាន​ដកចេញ +Comment[kn]=ವಿದ್ಯುಚ್ಛಕ್ತಿ ಅನುಕಾರಕವನ್ನು (ಅಡಾಪ್ಟರ್) ತೆಗೆಯಲಾಗಿದೆ +Comment[ko]=AC 어댑터의 연결이 해제되었습니다 +Comment[ku]=Adaptorê hêzê hate qut kirin +Comment[lt]=Kintamosios srovės adapteris buvo atjungtas +Comment[lv]=Tika izrauts strāvas vads +Comment[mai]=पावर एडाप्टर केँ प्लग सँ निकालल गेल अछि +Comment[mk]=Исклучен е адаптерот за ел. енергија +Comment[ml]=പവര്‍ അഡാപ്റ്റര്‍ പ്ലഗ്ഗില്‍ നിന്നും ഊരിയിരിക്കുന്നു +Comment[mr]=पॉवर अडॅप्टरला काढून टाकण्यात आले आहे +Comment[nb]=Strømadapteret er koblet fra +Comment[nds]=Dat Stroomkavel wöör ruttrocken +Comment[nl]=De netstroomadapter is losgekoppeld +Comment[nn]=Straumkontakten er vorten kopla ut +Comment[or]=ଶକ୍ତି ଏଡ଼ପଟରଟି ପ୍ଲଗ ହୋଇନାହିଁ +Comment[pa]=ਪਾਵਰ ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਕੱਢਿਆ +Comment[pl]=Odłączono zasilanie zewnętrzne +Comment[pt]=O computador foi desligado da corrente +Comment[pt_BR]=O adaptador de energia foi desconectado +Comment[ro]=Adaptorul de alimentare a fost detașat +Comment[ru]=Ноутбук отключён от электрической сети +Comment[si]=විදුලි ඇඩැප්ටරය ගලවා ඇත +Comment[sk]=Napájanie zo siete bolo odpojené +Comment[sl]=Napajanje iz električnega omrežja je bilo prekinjeno +Comment[sr]=Извучен је адаптер спољашњег напајања +Comment[sr@ijekavian]=Извучен је адаптер спољашњег напајања +Comment[sr@ijekavianlatin]=Izvučen je adapter spoljašnjeg napajanja +Comment[sr@latin]=Izvučen je adapter spoljašnjeg napajanja +Comment[sv]=Nätadaptern har kopplats från +Comment[ta]=The power adaptor has been unplugged +Comment[tg]=Отключен блок питания +Comment[th]=มีการถอดสายชาร์จของตัวแปลงไฟออก +Comment[tr]=Güç adaptörünün fişi çekildi +Comment[ug]=توك مەنبە ماسلاشتۇرغۇچ ئۈزۈلگەندە +Comment[uk]=Було вимкнено живлення від мережі +Comment[wa]=L' adaptateu d' corant a stî distchôkî +Comment[x-test]=xxThe power adaptor has been unpluggedxx +Comment[zh_CN]=已拔出电源适配器 +Comment[zh_TW]=市電電源已拔除 +Contexts=stdnot +Sound=KDE-Sys-App-Negative.ogg +Action=Sound +IconName=battery-low + +[Event/powerdevilerror] +Name=Internal Error +Name[bs]=Interna greška +Name[ca]=Error intern +Name[ca@valencia]=Error intern +Name[cs]=Vnitřní chyba +Name[da]=Intern fejl +Name[de]=Interner Fehler +Name[el]=Εσωτερικό σφάλμα +Name[en_GB]=Internal Error +Name[es]=Error interno +Name[et]=Sisemine tõrge +Name[eu]=Barne-errorea +Name[fi]=Sisäinen virhe +Name[fr]=Erreur interne +Name[ga]=Earráid Inmheánach +Name[gl]=Erro interno +Name[he]=שגיאה פנימית +Name[hu]=Belső hiba +Name[ia]=Error Interne +Name[is]=Innri villa +Name[kk]=Ішкі қате +Name[ko]=내부 오류 +Name[lt]=Vidinė klaida +Name[mr]=अंतर्गत त्रुटी +Name[nb]=Intern feil +Name[nds]=Intern Fehler +Name[nl]=Interne fout +Name[pa]=ਅੰਦਰੂਨੀ ਗਲਤੀ +Name[pl]=Błąd wewnętrzny +Name[pt]=Erro Interno +Name[pt_BR]=Erro interno +Name[ro]=Eroare internă +Name[ru]=Внутренняя ошибка +Name[sk]=Interná chyba +Name[sl]=Notranja napaka +Name[sr]=Унутрашња грешка +Name[sr@ijekavian]=Унутрашња грешка +Name[sr@ijekavianlatin]=Unutrašnja greška +Name[sr@latin]=Unutrašnja greška +Name[sv]=Internt fel +Name[tr]=Dahili Hata +Name[uk]=Внутрішня помилка +Name[x-test]=xxInternal Errorxx +Name[zh_CN]=内部错误 +Name[zh_TW]=內部錯誤 +Comment=The KDE Power Management System has triggered an internal error +Comment[ar]=أطلق مراقب الطاقة خطأً داخلياً +Comment[bg]=Системата за управление на захранването предизвика вътрешна грешка +Comment[bs]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem +Comment[ca]=El sistema de gestió d'energia del KDE ha activat un error intern +Comment[ca@valencia]=El sistema de gestió d'energia del KDE ha activat un error intern +Comment[cs]=Systém správy napájení KDE vyvolal interní chybu +Comment[da]=KDE's strømstyringssystem har udløst en intern fejl +Comment[de]=Das KDE-Energieverwaltungssystem hat einen internen Fehler ausgelöst. +Comment[el]=Ο διαχειριστής ενέργειας συστήματος KDE προκάλεσε ένα εσωτερικό σφάλμα +Comment[en_GB]=The KDE Power Management System has triggered an internal error +Comment[es]=El sistema de gestión de energía de KDE ha sufrido un error interno +Comment[et]=KDE toitehalduse süsteemi tabas sisemine tõrge +Comment[eu]=KDEren energia kudeatzeko sistemak barne-errore bat eragin du +Comment[fi]=KDE:n virranhallintajärjestelmä on kohdannut sisäisen virheen +Comment[fr]=Le système de gestion de l'énergie de KDE a déclenché une erreur interne +Comment[gl]=O sistema de xestión da enerxía de KDE disparou un erro interno +Comment[he]=מערכת ניהול צריכת החשמל של KDE דיווחה על שגיאה פנימית +Comment[hr]=KDE-ov sustav upravljanja potrošnjom energije je naišao na internu pogrešku +Comment[hu]=A KDE Energiakezelő rendszere belső hibát okozott +Comment[ia]=Le systema de gestion de energia de KDE ha generate un error interne +Comment[is]=KDE orkustjórnunarkerfið kom af stað innri villu +Comment[ja]=KDE 電源管理に内部エラーが発生しました +Comment[kk]=KDE қуаттандыру басқару жүйесінде ішкі бір қатесі орын алды +Comment[km]=ប្រព័ន្ធ​គ្រប់គ្រង​ថាមពល KDE មាន​កំហុស​ខាង​ក្នុង +Comment[ko]=KDE 전원 관리 시스템에서 내부 오류가 발생하였습니다 +Comment[lt]=KDE energijos valdymo sistema sužadino vidinę klaidą +Comment[lv]=KDE energokontroles sistēmā radās iekšēja kļūda +Comment[mr]=केडीई वीज व्यवस्थापन प्रणालीने अंतर्गत त्रुटी सक्रिय केली आहे +Comment[nb]=KDE strømstyringssystem har utløst en intern feil +Comment[nds]=Dat KDE-Stroomkuntrullsysteem hett en intern Fehler hatt. +Comment[nl]=Het KDE-energiebeheersysteem activeerde een interne fout +Comment[pa]=KDE ਪਾਵਰ ਮੈਨਜੇਮੈਂਟ ਸਿਸਟਮ ਨੇ ਅੰਦਰੂਨੀ ਗਲਤੀ +Comment[pl]=Wystąpił wewnętrzny błąd systemu zarządzania energią KDE +Comment[pt]=O Sistema de Gestão de Energia do KDE originou um erro interno +Comment[pt_BR]=Ocorreu um erro interno no Sistema de Gerenciamento de Energia do KDE +Comment[ro]=Sistemul KDE de gestiune a alimentării a declanșat o eroare internă +Comment[ru]=Произошла внутренняя ошибка системы управления питанием KDE +Comment[sk]=Systém správy napájania KDE vyvolal internú chybu +Comment[sl]=V KDE-jevem sistemu za upravljanje z energijo je prišlo do notranje napake +Comment[sr]=Унутрашња грешка у КДЕ‑овом систему за управљање напајањем +Comment[sr@ijekavian]=Унутрашња грешка у КДЕ‑овом систему за управљање напајањем +Comment[sr@ijekavianlatin]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem +Comment[sr@latin]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem +Comment[sv]=KDE:s strömsparhanteringssystem har orsakat ett internt fel +Comment[th]=ระบบจัดการพลังงานของ KDE ส่งสัญญาณให้ทราบว่าเกิดข้อผิดพลาดภายในขึ้น +Comment[tr]=KDE Güç Yönetim Sistemi bir iç hata tetikledi +Comment[ug]=ئىچكى ك د ئې(KDE) توك مەنبە باشقۇرۇش سىستېما خاتالىقى كۆرۈلدى +Comment[uk]=У системі керування живленням KDE сталася внутрішня помилка +Comment[wa]=Li sistinme di manaedjmint di l' enerdjeye di KDE a eclitchî ene divantrinne aroke +Comment[x-test]=xxThe KDE Power Management System has triggered an internal errorxx +Comment[zh_CN]=KDE 电源管理系统触发了内部错误 +Comment[zh_TW]=KDE 電源管理系統觸發了一個內部錯誤 +Contexts=criticalnot +Sound=KDE-Sys-App-Error-Critical.ogg +Action=Sound|Popup +IconName=dialog-error + +[Event/inhibition] +Name=Suspension inhibited +Name[ar]=ثُبِّط التعليق +Name[ast]=Suspensión inhibida +Name[be@latin]=Son zabaronieny +Name[bg]=Спирането е задържано +Name[bn]=স্থগিতাবস্থায় যাওয়া বিরত +Name[bs]=Suspendovanje sprečeno +Name[ca]=La suspensió s'ha inhibit +Name[ca@valencia]=La suspensió s'ha inhibit +Name[cs]=Uspávání potlačeno +Name[da]=Suspendering undertrykt +Name[de]=Bereitschaftsmodus unterbunden +Name[el]=Αποτροπή αναστολής +Name[en_GB]=Suspension inhibited +Name[es]=Suspensión inhibida +Name[et]=Passiivseisundisse minekut takistati +Name[eu]=Egonean uztea galarazita +Name[fi]=Keskeytystila estetty +Name[fr]=Suspension désactivée +Name[fy]=Sliepstân tsjinhâlden +Name[ga]=Cuireadh cosc ar fhionraíocht +Name[gl]=Evitouse a suspensión +Name[gu]=સસ્પેન્શન રોકી દેવાયું +Name[he]=הפסקה בוטלה +Name[hi]=निलंबन निषेधित +Name[hne]=सस्पेंसन रोके गिस +Name[hr]=Odlazak na spavanje prekinut +Name[hu]=A felfüggesztés letiltva +Name[ia]=Suspension inhibite +Name[id]=Suspensi dicegah +Name[is]=Biðstaða hindruð +Name[ja]=サスペンドが阻止されました +Name[kk]=Аялдауы кідірілді +Name[km]=បានហាមឃាត់​ការ​ផ្អាក +Name[kn]=ತಡೆಹಿಡಿಯುವಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ +Name[ko]=대기 모드로 들어가지 않았음 +Name[lt]=Sustabdymas sutrukdytas +Name[lv]=Iemigšana aizkavēta +Name[ml]=മയങ്ങല്‍ തടഞ്ഞിരിയ്ക്കുന്നു +Name[mr]=अकार्यक्षम करणे थांबविले +Name[nb]=Suspensjon hindret +Name[nds]=Utsetten blockeert +Name[nl]=Slaapstand verhinderd +Name[nn]=Kvilemodus vart stoppa +Name[pa]=ਸਸਪੈਂਡ ਵਿੱਚ ਵਿਘਨ +Name[pl]=Wstrzymanie usypiania +Name[pt]=Suspensão inibida +Name[pt_BR]=Suspensão inibida +Name[ro]=Suspendare inhibată +Name[ru]=Отмена перехода в ждущий режим +Name[si]=අත්හිටුවීම නිෂේධිතයි +Name[sk]=Uspanie potlačené +Name[sl]=Začasna zaustavitev prekinjena +Name[sr]=Суспендовање спречено +Name[sr@ijekavian]=Суспендовање спријечено +Name[sr@ijekavianlatin]=Suspendovanje spriječeno +Name[sr@latin]=Suspendovanje sprečeno +Name[sv]=Viloläge förhindrat +Name[ta]=Suspension inhibited +Name[te]=సస్పెన్షన్ ఇన్హిబిటెడ్ +Name[tg]=0.5x2 дюйм, 12x50 мм (Решагии ҷудошудаи папкаи миёна ) +Name[th]=การหยุดพักชั่วคราวถูกยับยั้ง +Name[tr]=Askıya alma işlemi geciktirildi +Name[ug]=توڭلىتىش چەكلەندى +Name[uk]=Присипляння заблоковано +Name[wa]=Metaedje doirmi espaitchî +Name[x-test]=xxSuspension inhibitedxx +Name[zh_CN]=已禁止挂起 +Name[zh_TW]=禁止暫停 +Comment=The suspension has been inhibited because an application requested it +Comment[ar]=ثُبِّط التعليق لأن تطبيقاً طلب ذلك +Comment[ast]=La suspensión inhibióse porque lo solicitó una aplicación +Comment[be@latin]=Son zabaronieny niejkaj aplikacyjaj. +Comment[bg]=Спирането беше задържано заради програма +Comment[bn]=একটি অ্যাপলিকেশন-এর অনুরোধে কম্পিউটারকে স্থগিতাবস্থায় যাওয়া থেকে বিরত রাখা হয়েছে +Comment[bs]=Suspendovanje je sprečeno jer je neki program to zatražio +Comment[ca]=La suspensió s'ha inhibit perquè una aplicació ho ha sol·licitat +Comment[ca@valencia]=La suspensió s'ha inhibit perquè una aplicació ho ha sol·licitat +Comment[cs]=Uspávání bylo potlačeno na základě požadavku aplikace +Comment[da]=Suspendering er blevet undertrykt fordi et program anmodede om det +Comment[de]=Der Bereitschaftsmodus ist unterbunden worden, weil eine Anwendung dies angefordert hat. +Comment[el]=Η αναστολή αποτράπηκε επειδή μια εφαρμογή το απαίτησε +Comment[en_GB]=The suspension has been inhibited because an application requested it +Comment[es]=La suspensión se ha inhibido porque lo ha solicitado una aplicación +Comment[et]=Passiivseisundisse minekut takistas mingi rakendus +Comment[eu]=Egonean uztea galarazi da aplikazio batek hala eskatu duelako +Comment[fi]=Keskeytystila estetty koska sovellus vaati sitä +Comment[fr]=La suspension a été désactivée car une application en a fait la demande +Comment[fy]=De sliepstân is tsjinhâlden omdat in applikaasje der om frege hat +Comment[ga]=Cuireadh cosc ar fhionraíocht toisc go raibh feidhmchlár á iarraidh +Comment[gl]=Evitouse a suspensión porque así o pediu un programa +Comment[gu]=સસ્પેન્શન રોકી દેવામાં આવ્યું કારણકે કાર્યક્રમે તેની વિનંતી કરી હતી +Comment[he]=ההפסקה בוטלה עקב בקשת יישום +Comment[hne]=सस्पेंसन ल रोक दे गे काबर कि एक ठिन अनुपरयोग ह निवेदन करिस +Comment[hr]=Odlazak na spavanje je prekinut jer je aplikacija dala zahtjev za tim. +Comment[hu]=Egy alkalmazás a felfüggesztés letiltását kérte +Comment[ia]=Le suspension ha essite inhibite proque un application exigeva lo +Comment[id]=Suspensi telah dicegah karena sebuah aplikasi memintanya +Comment[is]=Biðstaðan var hindruð að kröfu forrits +Comment[ja]=アプリケーションの要求によりサスペンドが阻止されました +Comment[kk]=Аялдау режіміне өту бір бағдарламаның талабымен кідірілді +Comment[km]=ការ​ផ្អាក​ត្រូវ​បានហាមឃាត់​ ពីព្រោះ​កម្មវិធី​បាន​ស្នើ​វា +Comment[kn]=ತಡೆಹಿಡಿಯುವಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಏಕೆಂದರೆ ಅನ್ವಯವು ಹಾಗೆ ಮಾಡಲು ಮನವಿ ಸಲ್ಲಿಸಿತ್ತು +Comment[ko]=프로그램의 요청으로 대기 모드에 들어가지 않았습니다 +Comment[lt]=Sustabdymas sutrukdytas, nes to prašė programa +Comment[lv]=Iemigšana tika aizkavēta, jo to pieprasīja kāda programma +Comment[ml]=ഒരു പ്രയോഗം ആവശ്യപ്പെട്ട പ്രകാരം മയങ്ങള്‍ തടഞ്ഞിരിയ്ക്കുന്നു +Comment[mr]=एका अनुप्रयोगाने विनंती केल्यामुळे अकार्यक्षम करणे थांबविले आहे +Comment[nb]=Suspensjonen er blitt hindret fordi et program ba om det +Comment[nds]=Dat Utsetten wöör blockeert, en Programm hett dat anfraagt. +Comment[nl]=Het activeren van de slaapstand is verhinderd omdat een programma hierom verzocht +Comment[nn]=Kvilemodus vart stoppa fordi eit program ønskte det +Comment[pa]=ਸਸਪੈਂਡ ਕਰਨ ਨੂੰ ਰੋਕਿਆ ਗਿਆ, ਕਿਉਂਕਿ ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੇ ਇਸ ਲਈ ਮੰਗ ਕੀਤੀ ਸੀ। +Comment[pl]=Usypianie zostało wstrzymane na żądanie programu +Comment[pt]=A suspensão foi inibida porque uma aplicação o pediu +Comment[pt_BR]=A suspensão foi inibida por solicitação de um aplicativo +Comment[ro]=Suspendarea a fost inhibată pentru că o aplicație a cerut astfel +Comment[ru]=Переход в ждущий режим прерван по запросу приложения +Comment[si]=යෙදුමක් මගින් ඉල්ලා සිටින බැවින් අත්හිටුවීම නිෂේධිතයි. +Comment[sk]=Uspanie bolo potlačené, pretože aplikácia si to vyžiadala +Comment[sl]=Začasna zaustavitev je bila prekinjena, ker je to zahteval nek program +Comment[sr]=Суспендовање је спречено јер је неки програм то затражио +Comment[sr@ijekavian]=Суспендовање је спријечено јер је неки програм то затражио +Comment[sr@ijekavianlatin]=Suspendovanje je spriječeno jer je neki program to zatražio +Comment[sr@latin]=Suspendovanje je sprečeno jer je neki program to zatražio +Comment[sv]=Viloläget har förhindrats eftersom ett program begärde det +Comment[ta]=The suspension has been inhibited because an application requested it +Comment[te]=ఒక అనువర్తనము దానిని అభ్యర్దించుట వలన సస్పెన్షన్ ఇన్హిబిటెడ్ చేయబడింది +Comment[th]=หยุดชั่วคราวเพราะโปรแกรมร้องขอ +Comment[tr]=Bir uygulama istediği için askıya alma işlemi geciktirildi +Comment[ug]=بۇ توڭلىتىش چەكلەندى چۈنكى پروگرامما ئىلتىماس قىلدى +Comment[uk]=Присипляння було заблоковано на вимогу програми +Comment[wa]=Li metaedje doirmi a stî espaitchî paske on programe l' a dmandé +Comment[x-test]=xxThe suspension has been inhibited because an application requested itxx +Comment[zh_CN]=由于应用程序的要求,挂起已被禁止 +Comment[zh_TW]=暫停功能已被禁止,因為有應用程式如此要求 +Contexts=criticalnot +Sound=KDE-Sys-App-Error-Critical.ogg +Action=Sound|Popup +IconName=dialog-information + +[Event/brokenbattery] +Name=Broken battery notification +Name[ar]=تبليغ البطارية التالفة +Name[bg]=Повредена батерия +Name[bs]=Obavještenje o pokvarenoj bateriji +Name[ca]=Notificació de bateria trencada +Name[ca@valencia]=Notificació de bateria trencada +Name[cs]=Oznámení vadné baterie +Name[da]=Bekendtgørelse af defekt batteri +Name[de]=Benachrichtigung über defekten Akku +Name[el]=Ειδοποίηση χαλασμένης μπαταρίας +Name[en_GB]=Broken battery notification +Name[es]=Notificación de batería estropeada +Name[et]=Katkise aku märguanne +Name[eu]=Bateria hondatuaren jakinarazpena +Name[fi]=Ilmoitus rikkinäisestä akusta +Name[fr]=Notification de batterie endommagée +Name[gl]=Notificación de batería estragada +Name[he]=הודעת סוללה תקולה +Name[hr]=Obavijest o neispravnoj bateriji +Name[hu]=Hibás akkumulátor értesítés +Name[ia]=Notification de batteria rupte +Name[is]=Tilkynning um að rafhlaðan er ekki í lagi +Name[ja]=バッテリーの故障通知 +Name[kk]=Батареяның істен шыққаны туралы хабарлауы +Name[km]=ការ​ជូន​ដំណឹង​ថ្ម​ខូច +Name[kn]=ಬ್ಯಾಟರಿ ಹಾಳಾದ ಸೂಚನೆ +Name[ko]=배터리 문제 알림 +Name[lt]=Pranešimas apie sugedusią bateriją +Name[lv]=Bojātas baterijas paziņojums +Name[mr]=तुटलेली बॅटरी सूचना +Name[nb]=Varsling om ødelagt batteri +Name[nds]=Bescheed över Batteriefehlers +Name[nl]=Gebroken melding over accu +Name[pa]=ਖਰਾਬ ਨੈਟਰੀ ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienie o zepsutej baterii +Name[pt]=Notificação de baterias com problemas +Name[pt_BR]=Notificação de bateria com problema +Name[ro]=Notificare de acumulator defect +Name[ru]=Уведомления о неполадках батарей +Name[sk]=Upozornenie na poškodenú batériu +Name[sl]=Obvestilo o poškodovani bateriji +Name[sr]=Обавештење о поквареној батерији +Name[sr@ijekavian]=Обавјештење о поквареној батерији +Name[sr@ijekavianlatin]=Obavještenje o pokvarenoj bateriji +Name[sr@latin]=Obaveštenje o pokvarenoj bateriji +Name[sv]=Underrättelse om felaktigt batteri +Name[th]=การแจ้งให้ทราบถึงแบตเตอรี่เสียหาย +Name[tr]=Kırık pil bildirimi +Name[ug]=بۇزۇلغان توكدان ئۇقتۇرۇشى +Name[uk]=Сповіщення про пошкоджений акумулятор +Name[vi]=Thông tin pin hỏng +Name[wa]=Notifiaedje d' ene batreye di schetêye +Name[x-test]=xxBroken battery notificationxx +Name[zh_CN]=电池损坏通知 +Name[zh_TW]=電池損壞通知 +Comment=KDE Power Management System has detected some troubles with one of your batteries +Comment[bs]=KDE sistem za upravljanje napajanjem otkrio je problem sa nekom od baterija. +Comment[ca]=El sistema de gestió d'energia del KDE ha detectat algun problema amb alguna de les bateries +Comment[ca@valencia]=El sistema de gestió d'energia del KDE ha detectat algun problema amb alguna de les bateries +Comment[cs]=Správce napájení KDE zjistil problémy s jednou z vašich baterií +Comment[da]=KDE's strømstyringssystem har fundet nogle problemer med et af dine batterier +Comment[de]=Das KDE-Energieverwaltungssystem hat Probleme mit einer Ihrer Akkus entdeckt +Comment[el]=Το σύστημα διαχείρισης ενέργειας του KDE έχει εντοπίσει κάποια προβλήματα με κάποια από τις μπαταρίες σας +Comment[en_GB]=KDE Power Management System has detected some troubles with one of your batteries +Comment[es]=El sistema de gestión de energía de KDE ha detectado algún problema en una de sus baterías +Comment[et]=KDE toitehalduse süsteem tuvastas mingeid probleeme mõne su akuga +Comment[eu]=KDEren energia kudeatzeko sistemak baterietako batekin arazoak daudela detektatu du +Comment[fi]=KDE:n virranhallintajärjestelmä on havainnut ongelmia akuissasi +Comment[fr]=Le système de gestion de l'énergie de KDE a détecté des problèmes avec l'une de vos batteries +Comment[gl]=O sistema de xestión da enerxía de KDE detectou algúns problemas cunha das baterías +Comment[he]=מערכת ניהול צריכת חשמל של KDE זיהתה בעיות עם אחת הסוללות +Comment[hu]=A KDE energiakezelő rendszere hibát észlelt az egyik akkumulátorában +Comment[ia]=Le systema de gestion de energia de KDE releva alcun problemas con un de tu batterias +Comment[is]=Þessi tilkynning kemur upp ef KDE orkustjórnunarkerfið finnur einhver vandamál með rafhlöður +Comment[kk]=KDE қуаттандыруды басқару жүйесі батареяңыздың бір мәселелерін байқады +Comment[ko]=KDE 전원 관리 시스템에서 배터리에 문제를 발견하였습니다 +Comment[lt]=KDE energijos valdymo sistema aptiko bėdų su vienu iš Jūsų akumuliatorių +Comment[mr]=केडीई वीज व्यवस्थापन प्रणालीला तुमच्या बैटरीमध्ये काही समस्या वाटत आहे +Comment[nb]=KDE Strømstyringssystem har oppdaget vanskeligheter med et av batteriene dine +Comment[nds]=Dat KDE-Stroompleegsysteem hett Problemen mit een vun Dien Batterien opdeckt. +Comment[nl]=Deze melding verschijnt als het KDE energiebeheersysteem een probleem detecteert met één van uw accu's +Comment[pa]=ਕੇਡੀਈ ਊਰਜਾ ਪਰਬੰਧ ਸਿਸਟਮ ਨੂੰ ਤੁਹਾਡੀਆਂ ਬੈਟਰੀਆਂ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਮਿਲੀ ਹੈ +Comment[pl]=System zarządzania energią w KDE wykrył jakieś problemy z jedną z twoich baterii +Comment[pt]=O Sistema de Gestão de Energia do KDE detectou algum problema com alguma das suas baterias +Comment[pt_BR]=O Sistema de Gerenciamento de Energia do KDE detectou um problema com uma das suas baterias +Comment[ro]=Sistemul KDE de gestiune a alimentării a identificat probleme cu unul dintre acumulatoare +Comment[ru]=Система управления питанием KDE обнаружила, что одна из ваших батарей имеет проблемы. +Comment[sk]=Systém správy napájania KDE zistil problémy s jednou z vašich batérií +Comment[sl]=Sistem za upravljanje z energijo je zaznal težavo z eno izmed baterij +Comment[sr]=КДЕ‑ов систем за управљање напајањем открио је проблем са неком од батерија. +Comment[sr@ijekavian]=КДЕ‑ов систем за управљање напајањем открио је проблем са неком од батерија. +Comment[sr@ijekavianlatin]=KDE‑ov sistem za upravljanje napajanjem otkrio je problem sa nekom od baterija. +Comment[sr@latin]=KDE‑ov sistem za upravljanje napajanjem otkrio je problem sa nekom od baterija. +Comment[sv]=KDE:s strömsparhantering har detekterar vissa problem med något av batterierna +Comment[tr]=KDE Güç Yönetim Sistemi pillerinizden birinde bazı sorunlar algıladı. +Comment[uk]=Системою керування живленням KDE виявлено проблеми з одним з акумуляторів +Comment[x-test]=xxKDE Power Management System has detected some troubles with one of your batteriesxx +Comment[zh_CN]=KDE 电源管理系统检测到电池问题 +Comment[zh_TW]=KDE 電源管理系統發現您的電池有些問題 +Contexts=criticalnot +Sound=KDE-Sys-App-Error-Critical.ogg +Action=Sound|Popup +IconName=battery-missing diff --git a/qguiplatformplugin_kde/CMakeLists.txt b/qguiplatformplugin_kde/CMakeLists.txt new file mode 100644 index 00000000..18dd808f --- /dev/null +++ b/qguiplatformplugin_kde/CMakeLists.txt @@ -0,0 +1,15 @@ +project(qguiplatformplugin_kde) + +set(kde_SOURCES qguiplatformplugin_kde.cpp) +qt4_generate_moc(qguiplatformplugin_kde.cpp ${CMAKE_CURRENT_BINARY_DIR}/qguiplatformplugin_kde.moc) + + +add_library (kde SHARED ${kde_SOURCES}) + +target_link_libraries(kde ${KDE4_KIO_LIBS} ${QT_QTGUI_LIBRARY}) + +install (TARGETS kde LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/gui_platform) + + + + diff --git a/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp b/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp new file mode 100644 index 00000000..4f67cc55 --- /dev/null +++ b/qguiplatformplugin_kde/qguiplatformplugin_kde.cpp @@ -0,0 +1,387 @@ +/* This file is part of the KDE project + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qguiplatformplugin_p.h" + +#include + +/* + * Map a Qt filter string into a KDE one. + * (from kfiledialog.cpp) +*/ +static QString qt2KdeFilter(const QString &f) +{ + QString filter; + QTextStream str(&filter, QIODevice::WriteOnly); + const QStringList list(f.split(";;").replaceInStrings("/", "\\/")); + QStringList::const_iterator it(list.begin()), + end(list.end()); + bool first=true; + + for(; it!=end; ++it) + { + int ob=(*it).lastIndexOf('('), + cb=(*it).lastIndexOf(')'); + + if(-1!=cb && ob0 && + ('('==(*it)[pos-1] || ' '==(*it)[pos-1]) && + (*it).length()>=kde.length()+pos && + (')'==(*it)[pos+kde.length()] || ' '==(*it)[pos+kde.length()])) + { + *sel=*it; + return; + } + } +} + + +class KFileDialogBridge : public KFileDialog +{ +public: + KFileDialogBridge (const KUrl &startDir, const QString &filter, QFileDialog *original_) + : KFileDialog (startDir, filter, original_), original(original_) + { + connect(this, SIGNAL(fileSelected(QString)), original, SIGNAL(currentChanged(QString))); + } + + virtual void accept() + { + kDebug(); + KFileDialog::accept(); + QMetaObject::invokeMethod(original, "accept"); //workaround protected + } + + virtual void reject() + { + kDebug(); + KFileDialog::reject(); + QMetaObject::invokeMethod(original, "reject"); //workaround protected + } + + QFileDialog *original; +}; + +class KColorDialogBridge : public KColorDialog +{ +public: + KColorDialogBridge(QColorDialog* original_ = 0L) : KColorDialog(original_, true) , original(original_) + { + connect(this, SIGNAL(colorSelected(QColor)), original, SIGNAL(currentColorChanged(QColor))); + } + + QColorDialog *original; + + virtual void accept() + { + KColorDialog::accept(); + original->setCurrentColor(color()); + QMetaObject::invokeMethod(original, "accept"); //workaround protected + } + + virtual void reject() + { + KColorDialog::reject(); + QMetaObject::invokeMethod(original, "reject"); //workaround protected + } +}; + +Q_DECLARE_METATYPE(KFileDialogBridge *) +Q_DECLARE_METATYPE(KColorDialogBridge *) + +class KQGuiPlatformPlugin : public QGuiPlatformPlugin +{ + Q_OBJECT +public: + KQGuiPlatformPlugin() + { + QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); + } + + virtual QStringList keys() const { return QStringList() << QLatin1String("kde"); } + virtual QString styleName() + { + const QString defaultStyle = KStyle::defaultStyle(); + const KConfigGroup pConfig(KGlobal::config(), "General"); + return pConfig.readEntry("widgetStyle", defaultStyle); + } + virtual QPalette palette() + { + return KGlobalSettings::createApplicationPalette(); + } + virtual QString systemIconThemeName() + { + return KIconTheme::current(); + } + virtual QStringList iconThemeSearchPaths() + { + return KGlobal::dirs()->resourceDirs("icon"); + } + virtual QIcon fileSystemIcon(const QFileInfo &file) + { + return KIcon(KMimeType::findByPath(file.filePath(), 0, true)->iconName()); + } + virtual int platformHint(PlatformHint hint) + { + switch(hint) + { + case PH_ToolButtonStyle: { + KConfigGroup group(KGlobal::config(), "Toolbar style"); + QString style = group.readEntry("ToolButtonStyle", "TextUnderIcon").toLower(); + if (style == "textbesideicon" || style == "icontextright") + return Qt::ToolButtonTextBesideIcon; + else if (style == "textundericon" || style == "icontextbottom") + return Qt::ToolButtonTextUnderIcon; + else if (style == "textonly") + return Qt::ToolButtonTextOnly; + else + return Qt::ToolButtonIconOnly; + } + case PH_ToolBarIconSize: + return KIconLoader::global()->currentSize(KIconLoader::MainToolbar); + case PH_ItemView_ActivateItemOnSingleClick: + return KGlobalSettings::singleClick(); + default: + break; + } + return QGuiPlatformPlugin::platformHint(hint); + } + +public: // File Dialog integration +#define K_FD(QFD) KFileDialogBridge *kdefd = qvariant_cast(QFD->property("_k_bridge")) + virtual void fileDialogDelete(QFileDialog *qfd) + { + K_FD(qfd); + delete kdefd; + } + virtual bool fileDialogSetVisible(QFileDialog *qfd, bool visible) + { + K_FD(qfd); + if (!kdefd && visible) { + if(qfd->options() & QFileDialog::DontUseNativeDialog) + return false; + + kdefd = new KFileDialogBridge(KUrl::fromPath(qfd->directory().canonicalPath()), + qt2KdeFilter(qfd->nameFilters().join(";;")), qfd); + + qfd->setProperty("_k_bridge", QVariant::fromValue(kdefd)); + } + + if (visible) { + switch (qfd->fileMode()) { + case QFileDialog::AnyFile: + kdefd->setMode(KFile::LocalOnly | KFile::File); + break; + case QFileDialog::ExistingFile: + kdefd->setMode(KFile::LocalOnly | KFile::File | KFile::ExistingOnly); + break; + case QFileDialog::ExistingFiles: + kdefd->setMode(KFile::LocalOnly | KFile::Files | KFile::ExistingOnly); + break; + case QFileDialog::Directory: + case QFileDialog::DirectoryOnly: + kdefd->setMode(KFile::LocalOnly | KFile::Directory); + break; + } + + + kdefd->setOperationMode((qfd->acceptMode() == QFileDialog::AcceptSave) ? KFileDialog::Saving : KFileDialog::Opening); + kdefd->setCaption(qfd->windowTitle()); + kdefd->setConfirmOverwrite(qfd->confirmOverwrite()); + kdefd->setSelection(qfd->selectedFiles().value(0)); + } + kdefd->setVisible(visible); + return true; + } + virtual QDialog::DialogCode fileDialogResultCode(QFileDialog *qfd) + { + K_FD(qfd); + Q_ASSERT(kdefd); + return QDialog::DialogCode(kdefd->result()); + } + virtual void fileDialogSetDirectory(QFileDialog *qfd, const QString &directory) + { + K_FD(qfd); + kdefd->setUrl(KUrl::fromPath(directory)); + } + virtual QString fileDialogDirectory(const QFileDialog *qfd) const + { + K_FD(qfd); + Q_ASSERT(kdefd); + return kdefd->baseUrl().pathOrUrl(); + } + virtual void fileDialogSelectFile(QFileDialog *qfd, const QString &filename) + { + K_FD(qfd); + Q_ASSERT(kdefd); + kdefd->setSelection(filename); + } + virtual QStringList fileDialogSelectedFiles(const QFileDialog *qfd) const + { + K_FD(qfd); + Q_ASSERT(kdefd); + return kdefd->selectedFiles(); + } + /*virtual void fileDialogSetFilter(QFileDialog *qfd) + { + K_FD(qfd); + }*/ + virtual void fileDialogSetNameFilters(QFileDialog *qfd, const QStringList &filters) + { + K_FD(qfd); + Q_ASSERT(kdefd); + kdefd->setFilter(qt2KdeFilter(filters.join(";;"))); + } + /*virtual void fileDialogSelectNameFilter(QFileDialog *qfd, const QString &filter) + { + K_FD(qfd); + }*/ + virtual QString fileDialogSelectedNameFilter(const QFileDialog *qfd) const + { + K_FD(qfd); + Q_ASSERT(kdefd); + QString ret; + kde2QtFilter(qfd->nameFilters().join(";;"), kdefd->currentFilter(), &ret); + return ret; + } +public: // ColorDialog +#define K_CD(QCD) KColorDialogBridge *kdecd = qvariant_cast(QCD->property("_k_bridge")) + virtual void colorDialogDelete(QColorDialog *qcd) + { + K_CD(qcd); + delete kdecd; + + } + virtual bool colorDialogSetVisible(QColorDialog *qcd, bool visible) + { + K_CD(qcd); + if (!kdecd) { + kdecd = new KColorDialogBridge(qcd); + kdecd->setColor(qcd->currentColor()); + if (qcd->options() & QColorDialog::NoButtons) { + kdecd->setButtons(KDialog::None); + } + kdecd->setModal(qcd->isModal()); + qcd->setProperty("_k_bridge", QVariant::fromValue(kdecd)); + } + if (visible) { + kdecd->setCaption(qcd->windowTitle()); + kdecd->setAlphaChannelEnabled(qcd->options() & QColorDialog::ShowAlphaChannel); + } + kdecd->setVisible(visible); + return true; + } + virtual void colorDialogSetCurrentColor(QColorDialog *qcd, const QColor &color) + { + K_CD(qcd); + if (kdecd) { + kdecd->setColor(color); + } + } + +private slots: + void init() + { + connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()), this, SLOT(updateToolbarIcons())); + connect(KGlobalSettings::self(), SIGNAL(toolbarAppearanceChanged(int)), this, SLOT(updateToolbarStyle())); + connect(KGlobalSettings::self(), SIGNAL(kdisplayStyleChanged()), this, SLOT(updateWidgetStyle())); + } + + void updateToolbarStyle() + { + //from gtksymbol.cpp + QWidgetList widgets = QApplication::allWidgets(); + for (int i = 0; i < widgets.size(); ++i) { + QWidget *widget = widgets.at(i); + if (qobject_cast(widget)) { + QEvent event(QEvent::StyleChange); + QApplication::sendEvent(widget, &event); + } + } + } + + void updateToolbarIcons() + { + QWidgetList widgets = QApplication::allWidgets(); + for (int i = 0; i < widgets.size(); ++i) { + QWidget *widget = widgets.at(i); + if (qobject_cast(widget) || qobject_cast(widget)) { + QEvent event(QEvent::StyleChange); + QApplication::sendEvent(widget, &event); + } + } + } + + void updateWidgetStyle() + { + if (qApp) { + if (qApp->style()->objectName() != styleName()) { + qApp->setStyle(styleName()); + } + } + } +}; + +Q_EXPORT_PLUGIN2(KQGuiPlatformPlugin, KQGuiPlatformPlugin) + +#include "qguiplatformplugin_kde.moc" + diff --git a/qguiplatformplugin_kde/qguiplatformplugin_p.h b/qguiplatformplugin_kde/qguiplatformplugin_p.h new file mode 100644 index 00000000..9a44acfa --- /dev/null +++ b/qguiplatformplugin_kde/qguiplatformplugin_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGUIPLATFORM_P_H +#define QGUIPLATFORM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QPalette; +class QIcon; +class QFileDialog; +class QColorDialog; +class QFileInfo; + +struct Q_GUI_EXPORT QGuiPlatformPluginInterface : public QFactoryInterface +{ +}; + +#define QGuiPlatformPluginInterface_iid "com.nokia.qt.QGuiPlatformPluginInterface" + +Q_DECLARE_INTERFACE(QGuiPlatformPluginInterface, QGuiPlatformPluginInterface_iid) + +class Q_GUI_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformPluginInterface +{ + Q_OBJECT + Q_INTERFACES(QGuiPlatformPluginInterface:QFactoryInterface) + public: + explicit QGuiPlatformPlugin(QObject *parent = 0); + ~QGuiPlatformPlugin(); + + virtual QStringList keys() const { return QStringList() << QLatin1String("default"); }; + + virtual QString styleName(); + virtual QPalette palette(); + virtual QString systemIconThemeName(); + virtual QStringList iconThemeSearchPaths(); + virtual QIcon fileSystemIcon(const QFileInfo &); + + enum PlatformHint { PH_ToolButtonStyle, PH_ToolBarIconSize, PH_ItemView_ActivateItemOnSingleClick }; + virtual int platformHint(PlatformHint hint); + + + virtual void fileDialogDelete(QFileDialog *) {} + virtual bool fileDialogSetVisible(QFileDialog *, bool) { return false; } + virtual QDialog::DialogCode fileDialogResultCode(QFileDialog *) { return QDialog::Rejected; } + virtual void fileDialogSetDirectory(QFileDialog *, const QString &) {} + virtual QString fileDialogDirectory(const QFileDialog *) const { return QString(); } + virtual void fileDialogSelectFile(QFileDialog *, const QString &) {} + virtual QStringList fileDialogSelectedFiles(const QFileDialog *) const { return QStringList(); } + virtual void fileDialogSetFilter(QFileDialog *) {} + virtual void fileDialogSetNameFilters(QFileDialog *, const QStringList &) {} + virtual void fileDialogSelectNameFilter(QFileDialog *, const QString &) {} + virtual QString fileDialogSelectedNameFilter(const QFileDialog *) const { return QString(); } + + virtual void colorDialogDelete(QColorDialog *) {} + virtual bool colorDialogSetVisible(QColorDialog *, bool) { return false; } + virtual void colorDialogSetCurrentColor(QColorDialog *, const QColor &) {} +}; + +//internal +QGuiPlatformPlugin *qt_guiPlatformPlugin(); + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QGUIPLATFORMPLUGIN_H diff --git a/solid-actions-kcm/ActionEditor.cpp b/solid-actions-kcm/ActionEditor.cpp new file mode 100644 index 00000000..8cda2bbe --- /dev/null +++ b/solid-actions-kcm/ActionEditor.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "ActionEditor.h" + +#include + +#include + +ActionEditor::ActionEditor(QWidget *parent) : KDialog(parent) +{ + topItem = new PredicateItem( Solid::Predicate(), 0 ); + rootItem = 0; + rootModel = new PredicateModel( topItem, this ); + // Prepare the dialog + setInitialSize( QSize(600, 600) ); // Set a decent initial size + // setModal( true ); + // Set up the interface + ui.setupUi( mainWidget() ); + ui.TvPredicateTree->setHeaderHidden( true ); + ui.TvPredicateTree->setModel( rootModel ); + ui.IbActionIcon->setIconSize( KIconLoader::SizeLarge ); + + ui.CbDeviceType->addItems( actionData()->interfaceList() ); + + // Connect up with everything needed -> slot names explain + connect( ui.TvPredicateTree, SIGNAL(activated(QModelIndex)), this, SLOT(updateParameter()) ); + connect( ui.PbParameterSave, SIGNAL(clicked()), this, SLOT(saveParameter()) ); + connect( ui.PbParameterReset, SIGNAL(clicked()), this, SLOT(updateParameter()) ); + connect( ui.CbDeviceType, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePropertyList()) ); + connect( ui.CbParameterType, SIGNAL(currentIndexChanged(int)), this, SLOT(manageControlStatus()) ); + + if( !KGlobalSettings::singleClick() ) { + connect( ui.TvPredicateTree, SIGNAL(clicked(QModelIndex)), this, SLOT(updateParameter()) ); + } +} + +ActionEditor::~ActionEditor() +{ + delete topItem; +} + +void ActionEditor::setActionToEdit( ActionItem * item ) +{ + activeItem = item; + + // Set all the text appropriately + ui.IbActionIcon->setIcon( item->icon() ); + ui.LeActionFriendlyName->setText( item->name() ); + ui.LeActionCommand->setUrl( KUrl(item->exec()) ); + + setPredicate( item->predicate() ); + setCaption( i18n("Editing Action %1", item->name()) ); // Set a friendly i18n caption +} + +void ActionEditor::setPredicate( Solid::Predicate predicate ) +{ + delete topItem; + topItem = new PredicateItem( Solid::Predicate(), 0 ); + rootItem = new PredicateItem( predicate, topItem ); + rootModel->setRootPredicate( rootItem->parent() ); + + // Select the top item, not the hidden root + QModelIndex topItem = rootModel->index( 0, 0, QModelIndex() ); + ui.TvPredicateTree->setCurrentIndex( topItem ); + ui.TvPredicateTree->expandToDepth( 2 ); + updateParameter(); +} + +void ActionEditor::updateParameter() +{ + QModelIndex current = ui.TvPredicateTree->currentIndex(); + PredicateItem * currentItem = static_cast( current.internalPointer() ); + + ui.CbParameterType->setCurrentIndex( currentItem->itemType ); + updatePropertyList(); + ui.CbDeviceType->setCurrentIndex( actionData()->interfacePosition( currentItem->ifaceType ) ); + int valuePos = actionData()->propertyPosition( currentItem->ifaceType, currentItem->property ); + ui.CbValueName->setCurrentIndex( valuePos ); + ui.LeValueMatch->setText( currentItem->value.toString() ); + ui.CbValueMatch->setCurrentIndex( currentItem->compOperator ); +} + +void ActionEditor::saveParameter() +{ + QModelIndex current = ui.TvPredicateTree->currentIndex(); + PredicateItem * currentItem = static_cast( current.internalPointer() ); + + // Hold onto this so we can determine if the number of children has changed... + Solid::Predicate::Type oldType = currentItem->itemType; + + currentItem->setTypeByInt( ui.CbParameterType->currentIndex() ); + currentItem->ifaceType = actionData()->interfaceFromName( ui.CbDeviceType->currentText() ); + currentItem->property = actionData()->propertyInternal( currentItem->ifaceType, ui.CbValueName->currentText() ); + currentItem->value = QVariant( ui.LeValueMatch->text() ); + currentItem->setComparisonByInt( ui.CbValueMatch->currentIndex() ); + + rootModel->itemUpdated( current ); + rootModel->childrenChanging( current, oldType ); +} + +QString ActionEditor::predicateString() +{ + return rootItem->predicate().toString(); +} + +void ActionEditor::updatePropertyList() +{ + Solid::DeviceInterface::Type currentType; + currentType = actionData()->interfaceFromName( ui.CbDeviceType->currentText() ); + + ui.CbValueName->clear(); + ui.CbValueName->addItems( actionData()->propertyList( currentType ) ); +} + +void ActionEditor::manageControlStatus() +{ + bool atomEnable = false; + bool isEnable = false; + + switch( ui.CbParameterType->currentIndex() ) { + case Solid::Predicate::PropertyCheck: + atomEnable = true; + case Solid::Predicate::InterfaceCheck: + isEnable = true; + break; + default: + break; + } + ui.CbDeviceType->setEnabled( isEnable ); + ui.CbValueName->setEnabled( atomEnable ); + ui.CbValueMatch->setEnabled( atomEnable ); + ui.LeValueMatch->setEnabled( atomEnable ); +} + +SolidActionData * ActionEditor::actionData() +{ + return SolidActionData::instance(); +} + +void ActionEditor::accept() +{ + // Save any open parameter changes first... + saveParameter(); + + // Read the data and prepare to save + QString iconName = ui.IbActionIcon->icon(); + QString actionName = ui.LeActionFriendlyName->text(); + QString command = ui.LeActionCommand->text(); + QString predicate = predicateString(); + + // We need to ensure that they are all valid before applying + if (iconName.isEmpty() || actionName.isEmpty() || command.isEmpty() || !Solid::Predicate::fromString(predicate).isValid()) { + KMessageBox::error(this, i18n("It appears that the action name, command, icon or condition are not valid.\nTherefore, changes will not be applied."), i18n("Invalid action")); + return; + } + // apply the changes + if (iconName != activeItem->icon()) { // Has the icon changed? + activeItem->setIcon( ui.IbActionIcon->icon() ); // Write the change + } + if (actionName != activeItem->name()) { // Has the friendly name changed? + activeItem->setName( ui.LeActionFriendlyName->text() ); // Write the change + } + if (command != activeItem->exec()) { // Has the command changed? + activeItem->setExec( ui.LeActionCommand->text() ); // Write the change + } + if (predicate != activeItem->predicate().toString() ) { // Has it changed? + activeItem->setPredicate( predicate ); // Write the change + } + + KDialog::accept(); +} + +#include "ActionEditor.moc" diff --git a/solid-actions-kcm/ActionEditor.h b/solid-actions-kcm/ActionEditor.h new file mode 100644 index 00000000..6f8675e5 --- /dev/null +++ b/solid-actions-kcm/ActionEditor.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef ACTIONEDITOR_H +#define ACTIONEDITOR_H + +#include + +#include "ActionItem.h" +#include "PredicateItem.h" +#include "PredicateModel.h" +#include "SolidActionData.h" +#include "ui_ActionEditor.h" + +class ActionEditor : public KDialog +{ + Q_OBJECT +public: + ActionEditor(QWidget *parent = 0); + ~ActionEditor(); + + void setActionToEdit( ActionItem * item ); + +public slots: + virtual void accept(); + +private: + SolidActionData * actionData(); + QString predicateString(); + + Ui::ActionEditor ui; + ActionItem * activeItem; + PredicateItem * topItem; + PredicateItem * rootItem; + PredicateModel * rootModel; + +private slots: + void updatePropertyList(); + void manageControlStatus(); + void updateParameter(); + void saveParameter(); + void setPredicate( Solid::Predicate predicate ); + +}; + +#endif diff --git a/solid-actions-kcm/ActionEditor.ui b/solid-actions-kcm/ActionEditor.ui new file mode 100644 index 00000000..486149f9 --- /dev/null +++ b/solid-actions-kcm/ActionEditor.ui @@ -0,0 +1,335 @@ + + + ActionEditor + + + + 0 + 0 + 602 + 522 + + + + + + + + + + 0 + 0 + + + + + 80 + 80 + + + + + 75 + 75 + + + + Action icon, click to change it + + + + + + + Action name + + + + + + + + + + + + 80 + 0 + + + + Command: + + + + + + + Command that will trigger the action +This can include any or all of the following case insensitive expands: + +%f: The mountpoint for the device - Storage Access devices only +%d: Path to the device node - Block devices only +%i: The identifier of the device + + + + + + + + + + + + 80 + 0 + + + + Devices must match the following parameters for this action: + + + + + + + + + + + + Edit Parameter + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Parameter type: + + + + + + + + Property Match + + + + + Content Conjunction + + + + + Content Disjunction + + + + + Device Interface Match + + + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Device type: + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Value name: + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + + Equals + + + + + Contains + + + + + + + + + + + + + + + Qt::Horizontal + + + + 227 + 25 + + + + + + + + Reset Parameter + + + + + + + Save Parameter Changes + + + + + + + + + + + + + KIconButton + QPushButton +
    kicondialog.h
    +
    + + KUrlRequester + QFrame +
    kurlrequester.h
    +
    + + KLineEdit + QLineEdit +
    klineedit.h
    +
    + + KComboBox + QComboBox +
    kcombobox.h
    +
    +
    + + +
    diff --git a/solid-actions-kcm/ActionItem.cpp b/solid-actions-kcm/ActionItem.cpp new file mode 100644 index 00000000..c5fc69a3 --- /dev/null +++ b/solid-actions-kcm/ActionItem.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "ActionItem.h" +#include "SolidActionData.h" + +#include + +#include +#include +#include + +#include + +ActionItem::ActionItem(const QString& pathToDesktop, const QString& action, QObject *parent) +{ + Q_UNUSED(parent); + + desktopMasterPath = pathToDesktop; + actionName = action; + // Create the desktop file + desktopFileMaster = new KDesktopFile(desktopMasterPath); + desktopWritePath = desktopFileMaster->locateLocal(desktopMasterPath); + desktopFileWrite = new KDesktopFile(desktopWritePath); + // Now we can fill the action groups list + configGroups.append(desktopFileMaster->desktopGroup()); + actionGroups.insertMulti(ActionItem::GroupDesktop, &configGroups.last()); + configGroups.append(desktopFileMaster->actionGroup(actionName)); + actionGroups.insertMulti(ActionItem::GroupAction, &configGroups.last()); + configGroups.append(desktopFileWrite->desktopGroup()); + actionGroups.insertMulti(ActionItem::GroupDesktop, &configGroups.last()); + configGroups.append(desktopFileWrite->actionGroup(actionName)); + actionGroups.insertMulti(ActionItem::GroupAction, &configGroups.last()); + + QString predicateString = readKey(ActionItem::GroupDesktop, "X-KDE-Solid-Predicate", ""); + predicateItem = Solid::Predicate::fromString( predicateString ); +} + +ActionItem::~ActionItem() +{ + delete desktopFileWrite; + delete desktopFileMaster; +} + +/// Public functions below + +bool ActionItem::isUserSupplied() +{ + return hasKey(ActionItem::GroupDesktop, "X-KDE-Action-Custom"); +} + +QString ActionItem::icon() +{ + return readKey(ActionItem::GroupAction, "Icon", ""); +} + +QString ActionItem::exec() +{ + return readKey(ActionItem::GroupAction, "Exec", ""); +} + +QString ActionItem::name() +{ + return readKey(ActionItem::GroupAction, "Name", ""); +} + +Solid::Predicate ActionItem::predicate() const +{ + return predicateItem; +} + +QString ActionItem::involvedTypes() const +{ + SolidActionData * actData = SolidActionData::instance(); + QSet devTypeList = predicateItem.usedTypes(); + QStringList deviceTypes; + foreach( Solid::DeviceInterface::Type devType, devTypeList ) { + deviceTypes << actData->nameFromInterface( devType ); + } + + return deviceTypes.join(", "); +} + +void ActionItem::setIcon(const QString& nameOfIcon) +{ + setKey(ActionItem::GroupAction, "Icon", nameOfIcon); +} + +void ActionItem::setName(const QString& nameOfAction) +{ + setKey(ActionItem::GroupAction, "Name", nameOfAction); +} + +void ActionItem::setExec(const QString& execUrl) +{ + setKey(ActionItem::GroupAction, "Exec", execUrl); +} + +void ActionItem::setPredicate( const QString& newPredicate ) +{ + setKey(ActionItem::GroupDesktop, "X-KDE-Solid-Predicate", newPredicate); + predicateItem = Solid::Predicate::fromString( newPredicate ); +} + +/// Private functions below + +QString ActionItem::readKey(GroupType keyGroup, const QString& keyName, const QString& defaultValue) +{ + return configItem(ActionItem::DesktopRead, keyGroup, keyName)->readEntry(keyName, defaultValue); +} + +void ActionItem::setKey(GroupType keyGroup, const QString& keyName, const QString& keyContents) +{ + configItem(ActionItem::DesktopWrite, keyGroup)->writeEntry(keyName, keyContents); +} + +bool ActionItem::hasKey(GroupType keyGroup, const QString& keyName) +{ + return configItem(ActionItem::DesktopRead, keyGroup, keyName)->hasKey(keyName); +} + +KConfigGroup * ActionItem::configItem(DesktopAction actionType, GroupType keyGroup, const QString& keyName) +{ + int countAccess = 0; + + if (actionType == ActionItem::DesktopRead) { + foreach(KConfigGroup * possibleGroup, actionGroups.values(keyGroup)) { + if (possibleGroup->hasKey(keyName)) { + return possibleGroup; + break; + } + } + } else if (actionType == ActionItem::DesktopWrite) { + if (isUserSupplied()) { + countAccess = 1; + } + return actionGroups.values(keyGroup)[countAccess]; + } + return actionGroups.values(keyGroup)[0]; // Implement a backstop so a valid value is always returned +} + +#include "ActionItem.moc" diff --git a/solid-actions-kcm/ActionItem.h b/solid-actions-kcm/ActionItem.h new file mode 100644 index 00000000..509efb31 --- /dev/null +++ b/solid-actions-kcm/ActionItem.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef ACTION_ITEM_H +#define ACTION_ITEM_H + +#include +#include + +#include + +class QString; + +class KDesktopFile; +class KConfigGroup; + +class ActionItem: public QObject +{ + Q_OBJECT + +public: + ActionItem(const QString& pathToDesktop, const QString& action, QObject *parent = 0); + ~ActionItem(); + + bool isUserSupplied(); + + QString icon(); + QString exec(); + QString name(); + Solid::Predicate predicate() const; + QString involvedTypes() const; + void setIcon( const QString& nameOfIcon ); + void setName( const QString& nameOfAction ); + void setExec( const QString& execUrl ); + void setPredicate( const QString& newPredicate ); + + QString desktopMasterPath; + QString desktopWritePath; + QString actionName; + +private: + enum DesktopAction { DesktopRead = 0, DesktopWrite = 1 }; + enum GroupType { GroupDesktop = 0, GroupAction = 1 }; + + QString readKey(GroupType keyGroup, const QString& keyName, const QString& defaultValue); + void setKey(GroupType keyGroup, const QString& keyName, const QString& keyContents); + bool hasKey(GroupType keyGroup, const QString& keyName); + KConfigGroup * configItem(DesktopAction actionType, GroupType keyGroup, const QString& keyName = QString()); + + KDesktopFile * desktopFileMaster; + KDesktopFile * desktopFileWrite; + QMultiMap actionGroups; + QList configGroups; + Solid::Predicate predicateItem; + +}; + +Q_DECLARE_METATYPE( ActionItem * ) + +#endif diff --git a/solid-actions-kcm/ActionModel.cpp b/solid-actions-kcm/ActionModel.cpp new file mode 100644 index 00000000..de2d4f33 --- /dev/null +++ b/solid-actions-kcm/ActionModel.cpp @@ -0,0 +1,121 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * Copyright (C) 2007 Will Stephenson * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ + +#include "ActionModel.h" +#include "ActionItem.h" + +#include +#include +#include + +class ActionModel::Private { +public: + Private() {} + + QList actions; +}; + +static bool sortAction( ActionItem * left, ActionItem * right ) +{ + return left->name() > right->name(); +} + +ActionModel::ActionModel( QObject *parent ) + : QAbstractTableModel( parent ) + , d( new Private() ) +{ +} + +ActionModel::~ActionModel() +{ + qDeleteAll( d->actions ); + d->actions.clear(); + delete d; +} + +int ActionModel::columnCount( const QModelIndex &parent ) const +{ + Q_UNUSED( parent ); + return 2; +} + +int ActionModel::rowCount( const QModelIndex &parent ) const +{ + if( !parent.isValid() ) { + return d->actions.count(); + } + return 0; +} + +QVariant ActionModel::data( const QModelIndex &index, int role ) const +{ + QVariant theData; + if ( !index.isValid() ) { + return QVariant(); + } + + ActionItem * mi = d->actions.at( index.row() ); + switch ( role ) { + case Qt::DisplayRole: + if( index.column() == 0 ) { + theData.setValue( mi->name() ); + } else if( index.column() == 1 ) { + theData.setValue( mi->involvedTypes() ); + } + break; + case Qt::DecorationRole: + if( index.column() == 0 ) { + theData = QVariant( KIcon(mi->icon()) ); + } + break; + case Qt::UserRole: + theData.setValue( mi ); + break; + default: + break; + } + return theData; +} + +void ActionModel::buildActionList() +{ + qDeleteAll( d->actions ); + d->actions.clear(); + // Prepare to search for possible actions -> we only want solid types + QStringList allPossibleActions = KGlobal::dirs()->findAllResources("data", "solid/actions/"); + // Get service objects for those actions and add them to the display + foreach(const QString &desktop, allPossibleActions) { + // Get contained services list + QList services = KDesktopFileActions::userDefinedServices(desktop, true); + foreach( const KServiceAction &deviceAction, services ) { + ActionItem * actionItem = new ActionItem( desktop, deviceAction.name(), this ); // Create an action + d->actions.append( actionItem ); + } + } + qSort( d->actions.begin(), d->actions.end(), sortAction ); + reset(); +} + +QList ActionModel::actionList() const +{ + return d->actions; +} + +#include "ActionModel.moc" diff --git a/solid-actions-kcm/ActionModel.h b/solid-actions-kcm/ActionModel.h new file mode 100644 index 00000000..209fcbff --- /dev/null +++ b/solid-actions-kcm/ActionModel.h @@ -0,0 +1,48 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ + +#ifndef ACTIONMODEL_H +#define ACTIONMODEL_H + +#include + +class ActionItem; + +class ActionModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit ActionModel( QObject *parent = 0 ); + ~ActionModel(); + + QVariant data( const QModelIndex &index, int role ) const; + int rowCount( const QModelIndex &parent = QModelIndex() ) const; + int columnCount( const QModelIndex &parent = QModelIndex() ) const; + + void buildActionList(); + QList actionList() const; + +private: + + class Private; + Private * const d; +}; + +#endif diff --git a/solid-actions-kcm/AddAction.ui b/solid-actions-kcm/AddAction.ui new file mode 100644 index 00000000..745597e6 --- /dev/null +++ b/solid-actions-kcm/AddAction.ui @@ -0,0 +1,43 @@ + + + AddAction + + + + 0 + 0 + 289 + 40 + + + + + + + + + Action name: + + + + + + + Enter the name for your new action + + + + + + + + + + KLineEdit + QLineEdit +
    klineedit.h
    +
    +
    + + +
    diff --git a/solid-actions-kcm/CMakeLists.txt b/solid-actions-kcm/CMakeLists.txt new file mode 100644 index 00000000..bb7c289f --- /dev/null +++ b/solid-actions-kcm/CMakeLists.txt @@ -0,0 +1,49 @@ +PROJECT (solid-actions) + +# We allow this to be built seperately for convienence purposes +IF(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + + FIND_PACKAGE(KDE4 REQUIRED) + INCLUDE(KDE4Defaults) + ADD_DEFINITIONS(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) + +ENDIF(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + +INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) + +ADD_SUBDIRECTORY(device-actions) + +########### next target ############### + +SET(kcm_solid_actions_srcs + PredicateItem.cpp + PredicateModel.cpp + ActionItem.cpp + ActionModel.cpp + ActionEditor.cpp + SolidActionData.cpp + SolidActions.cpp ) + +SET(solid_action_desktop_gen_srcs + DesktopFileGenerator.cpp + SolidActionData.cpp ) + +KDE4_ADD_UI_FILES(kcm_solid_actions_srcs + SolidActions.ui + AddAction.ui + ActionEditor.ui ) + +KDE4_ADD_PLUGIN(kcm_solid_actions ${kcm_solid_actions_srcs}) +KDE4_ADD_EXECUTABLE(solid-action-desktop-gen ${solid_action_desktop_gen_srcs}) + +TARGET_LINK_LIBRARIES(kcm_solid_actions ${KDE4_KIO_LIBS} ${KDE4_SOLID_LIBS} ) +TARGET_LINK_LIBRARIES(solid-action-desktop-gen ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS} ) + +########### install files ############### + +INSTALL( TARGETS kcm_solid_actions DESTINATION ${PLUGIN_INSTALL_DIR} ) +INSTALL( TARGETS solid-action-desktop-gen ${INSTALL_TARGETS_DEFAULT_ARGS} ) +INSTALL( FILES solid-actions.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +INSTALL( FILES solid-action-template.desktop DESTINATION ${DATA_INSTALL_DIR}/kcmsolidactions ) +INSTALL( FILES solid-device-type.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) + diff --git a/solid-actions-kcm/DesktopFileGenerator.cpp b/solid-actions-kcm/DesktopFileGenerator.cpp new file mode 100644 index 00000000..a9f82c47 --- /dev/null +++ b/solid-actions-kcm/DesktopFileGenerator.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "SolidActionData.h" + +#include + +int main( int argc, char *argv[] ) +{ + KLocale::setMainCatalog("solid-action-desktop-gen"); + // About data + KAboutData aboutData("solid-action-desktop-gen", 0, ki18n("Solid Action Desktop File Generator"), "0.4", ki18n("Tool to automatically generate Desktop Files from Solid DeviceInterface classes for translation"), + KAboutData::License_GPL, ki18n("(c) 2009, Ben Cooksley")); + aboutData.addAuthor(ki18n("Ben Cooksley"), ki18n("Maintainer"), "ben@eclipse.endoftheinternet.org"); + KCmdLineArgs::init(argc, argv, &aboutData); + + KApplication application(false); + SolidActionData * availActions = SolidActionData::instance(); + foreach( Solid::DeviceInterface::Type internalType, availActions->interfaceTypeList() ) { + QString typeName = Solid::DeviceInterface::typeToString( internalType ); + KDesktopFile typeFile( "services", "solid-device-" + typeName + ".desktop" ); + KConfigGroup tConfig = typeFile.desktopGroup(); + + tConfig.writeEntry( "Name", "Solid Device" ); + tConfig.writeEntry( "X-KDE-ServiceTypes", "SolidDevice" ); + tConfig.writeEntry( "Type", "Service" ); + + if( !tConfig.hasKey("X-KDE-Solid-Actions-Type") ) { + tConfig.writeEntry( "X-KDE-Solid-Actions-Type", typeName ); + } + + QStringList typeValues = availActions->propertyInternalList( internalType ); + QString actionText = typeValues.join(";").append(";"); + tConfig.writeEntry( "Actions", actionText ); + + kWarning() << "Desktop file created: " + typeFile.fileName(); + foreach( const QString &tValue, typeValues ) { + KConfigGroup vConfig = typeFile.actionGroup( tValue ); + if( !vConfig.hasKey("Name") ) { + vConfig.writeEntry( "Name", availActions->propertyName( internalType, tValue ) ); + } + vConfig.sync(); + } + tConfig.sync(); + typeFile.sync(); + } + + kWarning() << "Generation now completed"; + return 0; +} diff --git a/solid-actions-kcm/Messages.sh b/solid-actions-kcm/Messages.sh new file mode 100644 index 00000000..c4c99925 --- /dev/null +++ b/solid-actions-kcm/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcm_solid_actions.pot +rm -f rc.cpp diff --git a/solid-actions-kcm/PredicateItem.cpp b/solid-actions-kcm/PredicateItem.cpp new file mode 100644 index 00000000..600148c3 --- /dev/null +++ b/solid-actions-kcm/PredicateItem.cpp @@ -0,0 +1,208 @@ +/*************************************************************************** +* Copyright 2009 Ben Cooksley * +* * +* 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; if not, write to the * +* Free Software Foundation, Inc., * +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * +***************************************************************************/ + +#include "PredicateItem.h" + +#include "ActionEditor.h" + +#include +#include + +#include +#include + +class PredicateItem::Private { + +public: + Private() {} + + PredicateItem * parent; + QList children; + +}; + +PredicateItem::PredicateItem( Solid::Predicate item, PredicateItem * itsParent ) + : d( new Private() ) +{ + d->parent = itsParent; + + if ( d->parent ) { + d->parent->children().append( this ); + } + + // Read data from Solid::Predicate + itemType = item.type(); + ifaceType = item.interfaceType(); + property = item.propertyName(); + value = item.matchingValue(); + compOperator = item.comparisonOperator(); + + if( itemType == Solid::Predicate::Disjunction || itemType == Solid::Predicate::Conjunction ) { + PredicateItem * child = new PredicateItem( item.firstOperand(), this ); + PredicateItem * child2 = new PredicateItem( item.secondOperand(), this ); + Q_UNUSED( child ) + Q_UNUSED( child2 ) + } + // We're now ready, no need to keep the Solid::Predicate for now +} + +PredicateItem::~PredicateItem() +{ + qDeleteAll( d->children ); + d->children.clear(); + delete d; +} + +PredicateItem * PredicateItem::child( int index ) const +{ + return d->children.at(index); +} + +PredicateItem * PredicateItem::parent() const +{ + return d->parent; +} + +QList& PredicateItem::children() const +{ + return d->children; +} + +Solid::Predicate PredicateItem::predicate() const +{ + Solid::Predicate item; + + switch( itemType ) { + case Solid::Predicate::InterfaceCheck: + item = Solid::Predicate( ifaceType ); + break; + case Solid::Predicate::Conjunction: + item = children().at(0)->predicate() & children().at(1)->predicate(); + break; + case Solid::Predicate::Disjunction: + item = children().at(0)->predicate() | children().at(1)->predicate(); + break; + default: + break; + } + + if( itemType != Solid::Predicate::PropertyCheck ) { + return item; + } + + switch( compOperator ) { + case Solid::Predicate::Equals: + item = Solid::Predicate( ifaceType, property, value ); + break; + case Solid::Predicate::Mask: + item = Solid::Predicate( ifaceType, property, value, Solid::Predicate::Mask ); + break; + default: + break; + } + + return item; +} + +QString PredicateItem::prettyName() const +{ + QString typeName; + QString compName; + + QString deviceName; + switch( itemType ) { + case Solid::Predicate::InterfaceCheck: + deviceName = SolidActionData::instance()->nameFromInterface(ifaceType); + typeName = i18n("The device must be of the type %1", deviceName); + break; + case Solid::Predicate::Disjunction: + typeName = i18n("Any of the contained properties must match"); + break; + case Solid::Predicate::Conjunction: + typeName = i18n("All of the contained properties must match"); + break; + default: + break; + } + + QString prettyProperty = SolidActionData::instance()->propertyName( ifaceType, property ); + switch( compOperator ) { + case Solid::Predicate::Equals: + compName = i18n("The device property %1 must equal %2", prettyProperty, value.toString()); + break; + case Solid::Predicate::Mask: + compName = i18n("The device property %1 must contain %2", prettyProperty, value.toString()); + break; + default: + break; + } + + if( itemType == Solid::Predicate::PropertyCheck ) { + return compName; + } + return typeName; +} + +void PredicateItem::setTypeByInt( int item ) +{ + Solid::Predicate::Type iType = Solid::Predicate::InterfaceCheck; + switch( item ) { + case Solid::Predicate::PropertyCheck: + iType = Solid::Predicate::PropertyCheck; + break; + case Solid::Predicate::Conjunction: + iType = Solid::Predicate::Conjunction; + break; + case Solid::Predicate::Disjunction: + iType = Solid::Predicate::Disjunction; + break; + case Solid::Predicate::InterfaceCheck: + iType = Solid::Predicate::InterfaceCheck; + break; + default: + break; + } + itemType = iType; +} + +void PredicateItem::setComparisonByInt( int item ) +{ + switch( item ) { + case Solid::Predicate::Equals: + compOperator = Solid::Predicate::Equals; + break; + case Solid::Predicate::Mask: + compOperator = Solid::Predicate::Mask; + break; + default: + break; + } +} + +void PredicateItem::updateChildrenStatus() +{ + if( itemType != Solid::Predicate::Disjunction && itemType != Solid::Predicate::Conjunction ) { + qDeleteAll( d->children ); + d->children.clear(); + } else if( d->children.count() == 0 ) { + Solid::Predicate templItem = Solid::Predicate::fromString("IS StorageVolume"); + new PredicateItem( templItem, this ); + new PredicateItem( templItem, this ); + } +} diff --git a/solid-actions-kcm/PredicateItem.h b/solid-actions-kcm/PredicateItem.h new file mode 100644 index 00000000..b1123a44 --- /dev/null +++ b/solid-actions-kcm/PredicateItem.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright 2009 Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef PREDICATEITEM_H +#define PREDICATEITEM_H + +#include + +class QString; +template class QList; + +class PredicateItem +{ +public: + PredicateItem( Solid::Predicate item, PredicateItem * itsParent ); + ~PredicateItem(); + + PredicateItem * child( int index ) const; + PredicateItem * parent() const; + QList& children() const; + Solid::Predicate predicate() const; + QString prettyName() const; + void setTypeByInt( int item ); + void setComparisonByInt( int item ); + void updateChildrenStatus(); + + Solid::Predicate::Type itemType; + Solid::DeviceInterface::Type ifaceType; + QString property; + QVariant value; + Solid::Predicate::ComparisonOperator compOperator; + +private: + class Private; + Private *const d; +}; + +Q_DECLARE_METATYPE( PredicateItem * ) + +#endif diff --git a/solid-actions-kcm/PredicateModel.cpp b/solid-actions-kcm/PredicateModel.cpp new file mode 100644 index 00000000..4031276d --- /dev/null +++ b/solid-actions-kcm/PredicateModel.cpp @@ -0,0 +1,176 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * Copyright (C) 2007 Will Stephenson * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ + +#include "PredicateModel.h" + +#include "PredicateItem.h" + +class PredicateModel::Private { +public: + Private() {} + + PredicateItem * rootItem; +}; + +PredicateModel::PredicateModel( PredicateItem * menuRoot, QObject *parent ) + : QAbstractItemModel( parent ) + , d( new Private() ) +{ + d->rootItem = menuRoot; +} + +PredicateModel::~PredicateModel() +{ + delete d; +} + +int PredicateModel::columnCount( const QModelIndex &parent ) const +{ + Q_UNUSED( parent ); + return 1; +} + +int PredicateModel::rowCount( const QModelIndex &parent ) const +{ + PredicateItem * mi; + if ( parent.isValid() ) { + mi = static_cast( parent.internalPointer() ); + } else { + mi = d->rootItem; + } + + return mi->children().count(); +} + +QVariant PredicateModel::data( const QModelIndex &index, int role ) const +{ + PredicateItem * mi = 0; + QVariant theData; + if ( !index.isValid() ) { + return QVariant(); + } + + mi = static_cast( index.internalPointer() ); + switch ( role ) { + case Qt::DisplayRole: + theData.setValue( mi->prettyName() ); + break; + case Qt::UserRole: + theData.setValue( mi ); + break; + default: + break; + } + return theData; +} + +Qt::ItemFlags PredicateModel::flags( const QModelIndex &index ) const +{ + if ( !index.isValid() ) { + return 0; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QModelIndex PredicateModel::index( int row, int column, const QModelIndex &parent ) const +{ + if ( !hasIndex(row, column, parent) ) { + return QModelIndex(); + } + + PredicateItem *parentItem; + if ( !parent.isValid() ) { + parentItem = d->rootItem; + } else { + parentItem = static_cast( parent.internalPointer() ); + } + + PredicateItem *childItem = parentItem->children().value(row); + if ( childItem ) { + return createIndex( row, column, childItem ); + } else { + return QModelIndex(); + } +} + +QModelIndex PredicateModel::parent( const QModelIndex &index ) const +{ + PredicateItem *childItem = static_cast( index.internalPointer() ); + if( !childItem ) { + return QModelIndex(); + } + + PredicateItem * parent = childItem->parent(); + PredicateItem * grandParent = parent->parent(); + + int childRow = 0; + if( grandParent ) { + childRow = grandParent->children().indexOf( parent ); + } + + if ( parent == d->rootItem ) { + return QModelIndex(); + } + return createIndex( childRow, 0, parent ); +} + +PredicateItem * PredicateModel::rootItem() const +{ + return d->rootItem; +} + +void PredicateModel::setRootPredicate( PredicateItem * item ) +{ + d->rootItem = item; + reset(); +} + +void PredicateModel::itemUpdated( const QModelIndex& item ) +{ + emit dataChanged( item, item ); +} + +void PredicateModel::childrenChanging( const QModelIndex& item, Solid::Predicate::Type oldType ) +{ + PredicateItem * currentItem = static_cast( item.internalPointer() ); + Solid::Predicate::Type newType = currentItem->itemType; + + if( oldType == newType ) { + return; + } + + if( rowCount(item) != 0 && newType != Solid::Predicate::Conjunction && newType != Solid::Predicate::Disjunction ) { + emit beginRemoveRows( item, 0, 1 ); + currentItem->updateChildrenStatus(); + emit endRemoveRows(); + return; + } + + bool hasChildren = (newType == Solid::Predicate::Conjunction || newType == Solid::Predicate::Disjunction); + + if( rowCount(item) == 0 && hasChildren ) { + emit beginInsertRows( item, 0, 1 ); + currentItem->updateChildrenStatus(); + emit endInsertRows(); + } +} + +#include "PredicateModel.moc" diff --git a/solid-actions-kcm/PredicateModel.h b/solid-actions-kcm/PredicateModel.h new file mode 100644 index 00000000..3c6f182c --- /dev/null +++ b/solid-actions-kcm/PredicateModel.h @@ -0,0 +1,56 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ + +#ifndef PREDICATEMODEL_H +#define PREDICATEMODEL_H + +#include + +#include + +class PredicateItem; + +class PredicateModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit PredicateModel( PredicateItem * menuRoot, QObject *parent = 0 ); + ~PredicateModel(); + + QVariant data( const QModelIndex &index, int role ) const; + Qt::ItemFlags flags( const QModelIndex &index ) const; + QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const; + QModelIndex parent( const QModelIndex &index ) const; + int rowCount( const QModelIndex &parent = QModelIndex() ) const; + int columnCount( const QModelIndex &parent = QModelIndex() ) const; + + void setRootPredicate( PredicateItem * item ); + void itemUpdated( const QModelIndex& item ); + void childrenChanging( const QModelIndex& item, Solid::Predicate::Type oldType ); + +protected: + PredicateItem * rootItem() const; + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/solid-actions-kcm/SolidActionData.cpp b/solid-actions-kcm/SolidActionData.cpp new file mode 100644 index 00000000..fd1fde4a --- /dev/null +++ b/solid-actions-kcm/SolidActionData.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "SolidActionData.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static SolidActionData * actData = 0; + +SolidActionData::SolidActionData(bool includeFiles) +{ + QStringList allPossibleDevices; + int propertyOffset = Solid::DeviceInterface::staticMetaObject.propertyOffset(); + + QList interfaceList = fillInterfaceList(); + foreach( const QMetaObject &interface, interfaceList ) { + QString ifaceName = interface.className(); + ifaceName.remove(0, ifaceName.lastIndexOf(':') + 1); + Solid::DeviceInterface::Type ifaceDev = Solid::DeviceInterface::stringToType( ifaceName ); + QString cleanName = Solid::DeviceInterface::typeDescription( ifaceDev ); + types.insert( ifaceDev, cleanName ); + + QMap deviceValues; + for( int doneProps = propertyOffset; interface.propertyCount() > doneProps; doneProps = doneProps + 1 ) { + QMetaProperty ifaceProp = interface.property(doneProps); + deviceValues.insert( ifaceProp.name(), generateUserString(ifaceProp.name()) ); + } + values.insert( ifaceDev, deviceValues ); + } + + if( includeFiles ) { + // Fill the lists of possible device types / device values + allPossibleDevices = KGlobal::dirs()->findAllResources("data", "solid/devices/"); + // List all the known device actions, then add their name and all values to the appropriate lists + foreach( const QString &desktop, allPossibleDevices ) { + KDesktopFile deviceFile(desktop); + KConfigGroup deviceType = deviceFile.desktopGroup(); // Retrieve the configuration group where the user friendly name is + + QString ifaceName = deviceType.readEntry("X-KDE-Solid-Actions-Type"); + Solid::DeviceInterface::Type ifaceDev = Solid::DeviceInterface::stringToType( ifaceName ); + QString cleanName = Solid::DeviceInterface::typeDescription( ifaceDev ); + + types.insert( ifaceDev, cleanName ); // Read the user friendly name + + QMap deviceValues = values.value( ifaceDev ); + foreach( const QString &text, deviceFile.readActions() ) { // We want every single action + KConfigGroup actionType = deviceFile.actionGroup( text ); + deviceValues.insert( text, actionType.readEntry("Name") ); // Add to the type - actions map + } + values.insert( ifaceDev, deviceValues ); + } + } +} + +QList SolidActionData::propertyList( Solid::DeviceInterface::Type devInterface ) +{ + return values.value( devInterface ).values(); +} + +QList SolidActionData::propertyInternalList( Solid::DeviceInterface::Type devInterface ) +{ + return values.value( devInterface ).keys(); +} + +QString SolidActionData::propertyInternal( Solid::DeviceInterface::Type devInterface, QString property ) +{ + return values.value( devInterface ).key( property ); +} + +QString SolidActionData::propertyName( Solid::DeviceInterface::Type devInterface, QString property ) +{ + return values.value( devInterface ).value( property ); +} + +int SolidActionData::propertyPosition( Solid::DeviceInterface::Type devInterface, QString property ) +{ + return values.value( devInterface ).keys().indexOf( property ); +} + +QList SolidActionData::interfaceList() +{ + return types.values(); +} + +QList SolidActionData::interfaceTypeList() +{ + return types.keys(); +} + +Solid::DeviceInterface::Type SolidActionData::interfaceFromName( const QString& name ) +{ + return types.key( name ); +} + +QString SolidActionData::nameFromInterface( Solid::DeviceInterface::Type devInterface ) +{ + return types.value( devInterface ); +} + +int SolidActionData::interfacePosition( Solid::DeviceInterface::Type devInterface ) +{ + return types.keys().indexOf( devInterface ); +} + +QString SolidActionData::generateUserString( QString className ) +{ + QString finalString; + QRegExp camelCase("([A-Z])"); // Create the split regexp + + finalString = className.remove(0, className.lastIndexOf(':') + 1); // Remove any Class information + finalString = finalString.replace( camelCase, " \\1" ); // Use Camel Casing to add spaces + finalString = KStringHandler::capwords( finalString ); // Captialise everything + return finalString.trimmed(); +} + +SolidActionData * SolidActionData::instance() +{ + if( actData == 0 ) { + actData = new SolidActionData( true ); + } + return actData; +} + +QList SolidActionData::fillInterfaceList() +{ + QList interfaces; + interfaces.append( Solid::AcAdapter::staticMetaObject ); + interfaces.append( Solid::AudioInterface::staticMetaObject ); + interfaces.append( Solid::Battery::staticMetaObject ); + interfaces.append( Solid::Block::staticMetaObject ); + interfaces.append( Solid::Button::staticMetaObject ); + interfaces.append( Solid::Camera::staticMetaObject ); + interfaces.append( Solid::DvbInterface::staticMetaObject ); + interfaces.append( Solid::NetworkInterface::staticMetaObject ); + interfaces.append( Solid::PortableMediaPlayer::staticMetaObject ); + interfaces.append( Solid::Processor::staticMetaObject ); + interfaces.append( Solid::SerialInterface::staticMetaObject ); + interfaces.append( Solid::StorageAccess::staticMetaObject ); + interfaces.append( Solid::StorageDrive::staticMetaObject ); + interfaces.append( Solid::OpticalDrive::staticMetaObject ); + interfaces.append( Solid::StorageVolume::staticMetaObject ); + interfaces.append( Solid::OpticalDisc::staticMetaObject ); + interfaces.append( Solid::Video::staticMetaObject ); + interfaces.append( Solid::SmartCardReader::staticMetaObject ); + return interfaces; +} + +#include "SolidActionData.moc" diff --git a/solid-actions-kcm/SolidActionData.h b/solid-actions-kcm/SolidActionData.h new file mode 100644 index 00000000..27337c62 --- /dev/null +++ b/solid-actions-kcm/SolidActionData.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef SOLIDACTIONDATA_H +#define SOLIDACTIONDATA_H + +#include +#include +#include + +#include + +class SolidActionData : public QObject +{ + Q_OBJECT + +public: + QList propertyList( Solid::DeviceInterface::Type devInterface ); + QList propertyInternalList( Solid::DeviceInterface::Type devInterface ); + QString propertyInternal( Solid::DeviceInterface::Type devInterface, QString property ); + QString propertyName( Solid::DeviceInterface::Type devInterface, QString property ); + int propertyPosition( Solid::DeviceInterface::Type devInterface, QString property ); + + QList interfaceList(); + QList interfaceTypeList(); + Solid::DeviceInterface::Type interfaceFromName( const QString& name ); + QString nameFromInterface( Solid::DeviceInterface::Type devInterface ); + int interfacePosition( Solid::DeviceInterface::Type devInterface ); + + static SolidActionData * instance(); + +private: + SolidActionData(bool includeFiles); + QString generateUserString(QString className); + QList fillInterfaceList(); + + QMap > values; + QMap types; +}; + +#endif diff --git a/solid-actions-kcm/SolidActions.cpp b/solid-actions-kcm/SolidActions.cpp new file mode 100644 index 00000000..e9575a63 --- /dev/null +++ b/solid-actions-kcm/SolidActions.cpp @@ -0,0 +1,231 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "SolidActions.h" +#include "ActionItem.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +K_PLUGIN_FACTORY( SolidActionsFactory, registerPlugin(); ) +K_EXPORT_PLUGIN( SolidActionsFactory("kcmsolidactions", "kcm_solid_actions") ) + +SolidActions::SolidActions(QWidget* parent, const QVariantList&) + : KCModule(SolidActionsFactory::componentData(), parent) +{ + KAboutData * about = new KAboutData("Device Actions", 0, ki18n("Solid Device Actions Editor"), "1.1", + ki18n("Solid Device Actions Control Panel Module"), + KAboutData::License_GPL, + ki18n("(c) 2009 Solid Device Actions team")); + about->addAuthor(ki18n("Ben Cooksley"), ki18n("Maintainer"), "ben@eclipse.endoftheinternet.org"); + setAboutData(about); + setButtons(KCModule::Help); + + // Prepare main display dialog + actionModel = new ActionModel( this ); + mainUi.setupUi( this ); + mainUi.TvActions->setModel( actionModel ); + mainUi.TvActions->setHeaderHidden( true ); + mainUi.TvActions->setRootIsDecorated( false ); + mainUi.TvActions->setSelectionMode( QAbstractItemView::SingleSelection ); + mainUi.PbAddAction->setGuiItem( KStandardGuiItem::add() ); + mainUi.PbEditAction->setIcon( KIcon("document-edit") ); + + connect( mainUi.PbAddAction, SIGNAL(clicked()), this, SLOT(slotShowAddDialog()) ); + connect( mainUi.PbEditAction, SIGNAL(clicked()), this, SLOT(editAction()) ); + connect( mainUi.PbDeleteAction, SIGNAL(clicked()), this, SLOT(deleteAction()) ); + connect( mainUi.TvActions->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(toggleEditDelete()) ); + connect( mainUi.TvActions, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editAction()) ); + + // Prepare + connect up with Edit dialog + editUi = new ActionEditor(this); + connect( editUi, SIGNAL(accepted()), this, SLOT(acceptActionChanges()) ); + + // Prepare + connect up add action dialog + addDialog = new KDialog(this); + addUi.setupUi( addDialog->mainWidget() ); + addDialog->setInitialSize( QSize(300, 100) ); // Set a sensible default size + + slotTextChanged( addUi.LeActionName->text() ); + connect( addUi.LeActionName, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString)) ); + connect( addDialog, SIGNAL(okClicked()), this, SLOT(addAction()) ); +} + +SolidActions::~SolidActions() +{ + delete editUi; + delete actionModel; +} + +void SolidActions::slotShowAddDialog() +{ + addDialog->show(); + addUi.LeActionName->setFocus(); + addUi.LeActionName->clear(); +} + +void SolidActions::slotTextChanged( const QString & text ) +{ + addDialog->enableButtonOk( !text.isEmpty() ); +} + +void SolidActions::load() +{ + fillActionsList(); +} + +void SolidActions::defaults() +{ +} + +void SolidActions::save() +{ +} + +void SolidActions::addAction() +{ + QString enteredName = addUi.LeActionName->text(); + KDesktopFile templateDesktop(KStandardDirs::locate("data", "kcmsolidactions/solid-action-template.desktop")); // Lets get the template + + // Lets get a desktop file + QString internalName = enteredName; // copy the name the user entered -> we will be making mods + internalName.replace(QChar(' '), QChar('-'), Qt::CaseSensitive); // replace spaces with dashes + QString filePath = KStandardDirs::locateLocal("data", 0); // Get the location on disk for "data" + filePath = filePath + "solid/actions/" + internalName + ".desktop"; // Create a file path for new action + + // Fill in an initial template + KDesktopFile * newDesktop = templateDesktop.copyTo(filePath); + newDesktop->actionGroup("open").writeEntry("Name", enteredName); // ditto + delete newDesktop; // Force file to be written + + // Prepare to open the editDialog + fillActionsList(); + QList actionList = actionModel->actionList(); + QModelIndex newAction; + foreach( ActionItem * newItem, actionList ) { // Lets find our new action + if( newItem->desktopMasterPath == filePath ) { + int position = actionList.indexOf( newItem ); + newAction = actionModel->index( position, 0, QModelIndex() ); // Grab it + break; + } + } + + mainUi.TvActions->setCurrentIndex( newAction ); // Set it as currently active + editAction(); // Open the edit dialog +} + +void SolidActions::editAction() +{ + ActionItem * selectedItem = selectedAction(); + if( !selectedItem ) { + return; + } + + // We should error out here if we have to + if( !selectedItem->predicate().isValid() ) { + KMessageBox::error(this, i18n("It appears that the predicate for this action is not valid."), i18n("Error Parsing Device Conditions")); + return; + } + + // Display us! + editUi->setActionToEdit( selectedItem ); + editUi->setWindowIcon( windowIcon() ); + editUi->show(); +} + +void SolidActions::deleteAction() +{ + ActionItem * action = selectedAction(); + if( action->isUserSupplied() ) { // Is the action user supplied? + KIO::NetAccess::del( KUrl(action->desktopMasterPath), this); // Remove the main desktop file then + } + KIO::NetAccess::del( KUrl(action->desktopWritePath), this); // Remove the modified desktop file now + fillActionsList(); // Update the list of actions +} + +ActionItem * SolidActions::selectedAction() +{ + QModelIndex action = mainUi.TvActions->currentIndex(); + ActionItem * actionItem = actionModel->data( action, Qt::UserRole ).value(); + return actionItem; +} + +void SolidActions::fillActionsList() +{ + mainUi.TvActions->selectionModel()->clearSelection(); + actionModel->buildActionList(); + mainUi.TvActions->header()->setResizeMode( 0, QHeaderView::Stretch ); + mainUi.TvActions->header()->setResizeMode( 1, QHeaderView::ResizeToContents ); + toggleEditDelete(); +} + +void SolidActions::acceptActionChanges() +{ + // Re-read the actions list to ensure changes are reflected + KBuildSycocaProgressDialog::rebuildKSycoca(this); + fillActionsList(); +} + +void SolidActions::toggleEditDelete() +{ + bool toggle = true; + + if( !mainUi.TvActions->currentIndex().isValid() ) { // Is an action selected? + mainUi.PbDeleteAction->setText( i18n("No Action Selected") ); // Set a friendly disabled text + mainUi.PbDeleteAction->setIcon( KIcon() ); + toggle = false; + } + + mainUi.PbEditAction->setEnabled(toggle); // Change them to the new state + mainUi.PbDeleteAction->setEnabled(toggle); // Ditto + + if( !toggle ) { + return; + } + + KUrl writeDesktopFile( selectedAction()->desktopWritePath ); // Get the write desktop file + // What functionality do we need to change? + if( selectedAction()->isUserSupplied() ) { + // We are able to directly delete it, enable full delete functionality + mainUi.PbDeleteAction->setGuiItem( KStandardGuiItem::remove() ); + } else if( KIO::NetAccess::exists(writeDesktopFile, KIO::NetAccess::SourceSide, this) ) { // Does the write file exist? + // We are able to revert, lets show it + mainUi.PbDeleteAction->setGuiItem( KStandardGuiItem::discard() ); + } else { + // We cannot do anything then, disable delete functionality + mainUi.PbDeleteAction->setText( i18n("Cannot be deleted") ); + mainUi.PbDeleteAction->setIcon( KIcon() ); + mainUi.PbDeleteAction->setEnabled( false ); + } +} + +#include "SolidActions.moc" diff --git a/solid-actions-kcm/SolidActions.h b/solid-actions-kcm/SolidActions.h new file mode 100644 index 00000000..1eb31cac --- /dev/null +++ b/solid-actions-kcm/SolidActions.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef SOLIDACTIONS_H +#define SOLIDACTIONS_H + +#include + +#include "SolidActions.h" +#include "ActionModel.h" +#include "ActionEditor.h" +#include "ui_AddAction.h" +#include "ui_SolidActions.h" + +class ActionItem; + +class SolidActions: public KCModule +{ + Q_OBJECT + +public: + SolidActions(QWidget* parent, const QVariantList&); + ~SolidActions(); + void load(); + void save(); + void defaults(); + +private slots: + void addAction(); + void editAction(); + void deleteAction(); + ActionItem * selectedAction(); + void fillActionsList(); + void acceptActionChanges(); + void toggleEditDelete(); + void slotTextChanged( const QString& ); + void slotShowAddDialog(); + +private: + Ui::SolidActions mainUi; + ActionModel * actionModel; + ActionEditor * editUi; + Ui::AddAction addUi; + KDialog * addDialog; + void clearActions(); + +}; + +#endif diff --git a/solid-actions-kcm/SolidActions.ui b/solid-actions-kcm/SolidActions.ui new file mode 100644 index 00000000..fd5e4ab9 --- /dev/null +++ b/solid-actions-kcm/SolidActions.ui @@ -0,0 +1,53 @@ + + + SolidActions + + + + 0 + 0 + 553 + 384 + + + + + + + + + + + + Add... + + + + + + + Edit... + + + + + + + Remove + + + + + + + + + + KPushButton + QPushButton +
    kpushbutton.h
    +
    +
    + + +
    diff --git a/solid-actions-kcm/device-actions/CMakeLists.txt b/solid-actions-kcm/device-actions/CMakeLists.txt new file mode 100644 index 00000000..a542b120 --- /dev/null +++ b/solid-actions-kcm/device-actions/CMakeLists.txt @@ -0,0 +1,3 @@ +FILE(GLOB desktopfile *.desktop) + +INSTALL( FILES ${desktopfile} DESTINATION ${DATA_INSTALL_DIR}/solid/devices ) diff --git a/solid-actions-kcm/device-actions/solid-device-AcAdapter.desktop b/solid-actions-kcm/device-actions/solid-device-AcAdapter.desktop new file mode 100644 index 00000000..d3a239c3 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-AcAdapter.desktop @@ -0,0 +1,120 @@ +[Desktop Action plugged] +# ctxt: AC adapter plugged in +Name=Plugged +Name[bs]=Utaknut +Name[ca]=Endollat +Name[ca@valencia]=Endollat +Name[cs]=Připojeno +Name[da]=I stikkontakten +Name[de]=Angeschlossen +Name[el]=Σε σύνδεση +Name[en_GB]=Plugged +Name[es]=Enchufado +Name[et]=Ühendatud +Name[eu]=Konektatuta +Name[fi]=Kytketty +Name[fr]=Branché +Name[ga]=Plugáilte +Name[gl]=Enchufado +Name[he]=מחובר +Name[hu]=Bedugva +Name[ia]=Connectite +Name[is]=Í sambandi +Name[kk]=Қосылған +Name[ko]=연결됨 +Name[lt]=Prijungtas +Name[mr]=प्लग केलेले +Name[nb]=Tilkoblet +Name[nds]=Tokoppelt +Name[nl]=Ingeplugd +Name[pa]=ਪਲੱਗ ਲੱਗਾ +Name[pl]=Podłączony +Name[pt]=Ligado +Name[pt_BR]=Conectado +Name[ro]=Atașat +Name[ru]=Подключён +Name[sk]=Pripojené +Name[sl]=Priključeno +Name[sr]=утакнут +Name[sr@ijekavian]=утакнут +Name[sr@ijekavianlatin]=utaknut +Name[sr@latin]=utaknut +Name[sv]=Ansluten +Name[tr]=Fişe takılı +Name[uk]=З’єднано +Name[x-test]=xxPluggedxx +Name[zh_CN]=已插入 +Name[zh_TW]=已插入 + +[Desktop Entry] +Actions=plugged; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=AcAdapter diff --git a/solid-actions-kcm/device-actions/solid-device-AudioInterface.desktop b/solid-actions-kcm/device-actions/solid-device-AudioInterface.desktop new file mode 100644 index 00000000..676ee3ee --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-AudioInterface.desktop @@ -0,0 +1,430 @@ +[Desktop Action deviceType] +Name=Device Type +Name[ar]=نوع الجهاز +Name[ast]=Triba de preséu +Name[bg]=Вид устройство +Name[bn]=ডিভাইস ধরন +Name[bs]=tip uređaja +Name[ca]=Tipus de dispositiu +Name[ca@valencia]=Tipus de dispositiu +Name[cs]=Typ zařízení +Name[csb]=Ôrt ùrządzenia +Name[da]=Enhedstype +Name[de]=Gerätetyp +Name[el]=Τύπος συσκευής +Name[en_GB]=Device Type +Name[eo]=Aparata Tipo +Name[es]=Tipo de dispositivo +Name[et]=Seadme tüüp +Name[eu]=Gailu mota +Name[fa]=نوع دستگاه +Name[fi]=Laitetyyppi +Name[fr]=Type de périphérique +Name[fy]=Apparaat type +Name[ga]=Cineál Gléis +Name[gl]=Tipo do dispositivo +Name[gu]=ઉપકરણ પ્રકાર +Name[he]=סוג ההתקן +Name[hi]=औज़ार प्रकार +Name[hr]=Tip uređaja +Name[hu]=Eszköztípus +Name[ia]=Typo de dispositivo +Name[id]=Tipe Divais +Name[is]=Tegund tækis +Name[ja]=デバイスのタイプ +Name[kk]=Құрылғының түрі +Name[km]=ប្រភេទ​ឧបករណ៍ +Name[kn]=ಸಾಧನದ ಬಗೆ +Name[ko]=장치 종류 +Name[lt]=Įrenginio tipas +Name[lv]=Ierīces tips +Name[mk]=Тип на уред +Name[ml]=ഉപകരണതരം +Name[mr]=साधन प्रकार +Name[nb]=Enhetstype +Name[nds]=Reedschaptyp +Name[nl]=Apparaattype +Name[nn]=Einingstype +Name[pa]=ਜੰਤਰ ਕਿਸਮ +Name[pl]=Typ urządzenia +Name[pt]=Tipo de Dispositivo +Name[pt_BR]=Tipo de dispositivo +Name[ro]=Tip dispozitiv +Name[ru]=Тип устройства +Name[si]=මෙවලම් වර්‍ගය +Name[sk]=Typ zariadenia +Name[sl]=Vrsta naprave +Name[sr]=тип уређаја +Name[sr@ijekavian]=тип уређаја +Name[sr@ijekavianlatin]=tip uređaja +Name[sr@latin]=tip uređaja +Name[sv]=Enhetstyp +Name[tg]=Дастгоҳҳо +Name[th]=ประเภทของอุปกรณ์ +Name[tr]=Aygıt Tipi +Name[ug]=ئۈسكۈنە تىپى +Name[uk]=Тип пристрою +Name[vi]=Kiểu thiết bị +Name[wa]=Sôre d' éndjin +Name[x-test]=xxDevice Typexx +Name[zh_CN]=设备类型 +Name[zh_TW]=裝置類型 + +[Desktop Action driver] +Name=Driver +Name[ar]=المشغل +Name[ast]=Controlador +Name[bg]=Драйвер +Name[bn]=ড্রাইভার +Name[bs]=drajver +Name[ca]=Controlador +Name[ca@valencia]=Controlador +Name[cs]=Ovladač +Name[csb]=Czérownik +Name[da]=Driver +Name[de]=Treiber +Name[el]=Οδηγός +Name[en_GB]=Driver +Name[eo]=Pelilo +Name[es]=Controlador +Name[et]=Draiver +Name[eu]=Gidaria +Name[fa]=گرداننده +Name[fi]=Ajuri +Name[fr]=Pilote +Name[fy]=Stjoerprogramma +Name[ga]=Tiománaí +Name[gl]=Controlador +Name[gu]=ડ્રાઇવર +Name[he]=מנהל התקן +Name[hi]=ड्राईवर +Name[hr]=Pogonski program +Name[hu]=Meghajtó +Name[ia]=Driver +Name[id]=Penggerak +Name[is]=Rekill +Name[ja]=ドライバ +Name[ka]=დრაივერი +Name[kk]=Драйвері +Name[km]=កម្មវិធី​បញ្ជា +Name[kn]=ಚಾಲಕ +Name[ko]=드라이버 +Name[lt]=Tvarkyklė +Name[lv]=Draiveris +Name[mai]=ड्राइवर +Name[mk]=Управувач +Name[ml]=സാരഥി +Name[mr]=ड्राइव्हर +Name[nb]=Driver +Name[nds]=Driever +Name[nl]=Stuurprogramma +Name[nn]=Drivar +Name[pa]=ਡਰਾਇਵਰ +Name[pl]=Sterownik +Name[pt]=Controlador +Name[pt_BR]=Driver +Name[ro]=Driver +Name[ru]=Драйвер +Name[si]=ධාවකය +Name[sk]=Ovládač +Name[sl]=Gonilnik +Name[sr]=драјвер +Name[sr@ijekavian]=драјвер +Name[sr@ijekavianlatin]=drajver +Name[sr@latin]=drajver +Name[sv]=Drivrutin +Name[tg]=Драйвер +Name[th]=ไดรเวอร์ +Name[tr]=Sürücü +Name[ug]=قوزغاتقۇ +Name[uk]=Драйвер +Name[vi]=Trình điều khiển +Name[wa]=Mineu +Name[x-test]=xxDriverxx +Name[zh_CN]=驱动 +Name[zh_TW]=驅動程式 + +[Desktop Action driverHandle] +Name=Driver Handle +Name[ar]=مقبض المشغل +Name[ast]=Controlador de preséu +Name[bg]=Управление на драйвера +Name[bn]=ড্রাইভার হ্যাণ্ডল +Name[bs]=ručka drajvera +Name[ca]=Gestor de controlador +Name[ca@valencia]=Gestor de controlador +Name[cs]=ID ovladače +Name[csb]=Czérownik Handle +Name[da]=Driver-handle +Name[de]=Treiber-Alias +Name[el]=Χειριστήριο οδηγού +Name[en_GB]=Driver Handle +Name[eo]=Pelila tenilo +Name[es]=Controlador de dispositivo +Name[et]=Draiveri pide +Name[eu]=Gidariaren heldulekua +Name[fi]=Ajuritunniste +Name[fr]=Gestionnaire du pilote +Name[fy]=Stjoerprograma regelaar +Name[ga]=Hanla an Tiománaí +Name[gl]=Xestión do controlador +Name[gu]=ડ્રાઇવ સંભાળનાર +Name[he]=ממשק מנהל ההתקן +Name[hi]=औजार हेंडल +Name[hr]=Pogonski program +Name[hu]=Meghajtóazonosító +Name[ia]=Maneator de driver +Name[id]=Penanganan Penggerak +Name[is]=Hald rekils +Name[ja]=ドライバハンドル +Name[kk]=Драйвер өңдеуі +Name[km]=កា​រគ្រប់គ្រង​កម្មវិធី​បញ្ជា +Name[ko]=드라이버 핸들 +Name[lt]=Tvarkyklės rankena +Name[lv]=Draivera rokturis +Name[ml]=ഉപരണത്തിന്റെ പിടി +Name[mr]=ड्राइव्हर हेंडल +Name[nb]=Drivernavn +Name[nds]=Drievergreep +Name[nl]=Stuurprogrammapook +Name[nn]=Drivarnamn +Name[pa]=ਡਰਾਇਵਰ ਹੈਂਡਲ +Name[pl]=Uchwyt sterownika +Name[pt]=Descritor do Controlador +Name[pt_BR]=Manipulador do driver +Name[ro]=Manipulare driver +Name[ru]=Драйверная ссылка на устройство +Name[si]=ධාවක අල්ලුව +Name[sk]=Rukoväť ovládača +Name[sl]=Ročica gonilnika +Name[sr]=ручка драјвера +Name[sr@ijekavian]=ручка драјвера +Name[sr@ijekavianlatin]=ručka drajvera +Name[sr@latin]=ručka drajvera +Name[sv]=Drivrutinreferens +Name[tg]=Плеери DJ-Mixer +Name[th]=การจัดการไดรเวอร์ +Name[tr]=Sürücü Tanıtıcı +Name[ug]=قوزغاتقۇ تۇتقۇسى +Name[uk]=Обробка драйвером +Name[vi]=Xử lý trình điều khiển +Name[wa]=Apougnî mineu +Name[x-test]=xxDriver Handlexx +Name[zh_CN]=驱动处理接口 +Name[zh_TW]=驅動程式處理 + +[Desktop Action name] +Name=Name +Name[ar]=الاسم +Name[ast]=Nome +Name[bg]=Име +Name[bn]=নাম +Name[bs]=ime +Name[ca]=Nom +Name[ca@valencia]=Nom +Name[cs]=Jméno +Name[csb]=Miono +Name[da]=Navn +Name[de]=Name +Name[el]=Όνομα +Name[en_GB]=Name +Name[eo]=Nomo +Name[es]=Nombre +Name[et]=Nimi +Name[eu]=Izena +Name[fa]=نام +Name[fi]=Nimi +Name[fr]=Nom +Name[fy]=Namme +Name[ga]=Ainm +Name[gl]=Nome +Name[gu]=નામ +Name[he]=שם +Name[hi]=नाम +Name[hr]=Ime +Name[hu]=Név +Name[ia]=Nomine +Name[id]=Nama +Name[is]=Heiti +Name[ja]=名前 +Name[ka]=სახელი +Name[kk]=Атауы +Name[km]=ឈ្មោះ +Name[kn]=ಹೆಸರು +Name[ko]=이름 +Name[lt]=Pavadinimas +Name[lv]=Nosaukums +Name[mk]=Име +Name[ml]=പേരു് +Name[mr]=नाव +Name[nb]=Navn +Name[nds]=Naam +Name[nl]=Naam +Name[nn]=Namn +Name[pa]=ਨਾਂ +Name[pl]=Nazwa +Name[pt]=Nome +Name[pt_BR]=Nome +Name[ro]=Denumire +Name[ru]=Имя +Name[si]=නම +Name[sk]=Názov +Name[sl]=Ime +Name[sr]=име +Name[sr@ijekavian]=име +Name[sr@ijekavianlatin]=ime +Name[sr@latin]=ime +Name[sv]=Namn +Name[tg]=Ном +Name[th]=ชื่อ +Name[tr]=İsim +Name[ug]=ئاتى +Name[uk]=Назва +Name[wa]=No +Name[x-test]=xxNamexx +Name[zh_CN]=名称 +Name[zh_TW]=名稱 + +[Desktop Action soundcardType] +Name=Soundcard Type +Name[ar]=نوع بطاقة الصوت +Name[ast]=Triba de tarxeta de soníu +Name[bg]=Вид звукова карта +Name[bn]=সাউণ্ডকার্ড ধরন +Name[bs]=tip zvučne kartice +Name[ca]=Tipus de targeta de so +Name[ca@valencia]=Tipus de targeta de so +Name[cs]=Typ zvukové karty +Name[csb]=Ôrt zwãkòwi kôrtë +Name[da]=Type af lydkort +Name[de]=Soundkartentyp +Name[el]=Τύπος κάρτας ήχου +Name[en_GB]=Soundcard Type +Name[eo]=Tipo de Sonkarto +Name[es]=Tipo de tarjeta de sonido +Name[et]=Helikaardi tüüp +Name[eu]=Soinu-txartel mota +Name[fi]=Äänikortin tyyppi +Name[fr]=Type de carte son +Name[fy]=Lûdskaart type +Name[ga]=Cineál an Chárta Fuaime +Name[gl]=Tipo de tarxeta de son +Name[gu]=સાઉન્ડકાર્ડ પ્રકાર +Name[he]=סוג כרטיס קול +Name[hi]=ध्वनिकार्ड प्रकार +Name[hr]=Tip zvučne kartice +Name[hu]=Hangkártyatípus +Name[ia]=Typo de carta de sono +Name[id]=Tipe Kartu Suara +Name[is]=Tegund hljóðkorts +Name[ja]=サウンドカードのタイプ +Name[kk]=Дыбыс картасының түрі +Name[km]=ប្រភេទ​កាត​សំឡេង +Name[kn]=ಧ್ವನಿಕಾರ್ಡಿನ ಬಗೆ +Name[ko]=사운드카드 종류 +Name[lt]=Garso plokštės tipas +Name[lv]=Skaņas kartes tips +Name[mai]=साउंडकार्ड प्रकार +Name[mk]=Тип на аудиокартичка +Name[ml]=സൌണ്ട് കാര്‍ഡിന്റെ തരം +Name[mr]=साउंडकार्ड प्रकार +Name[nb]=Lydkort-type +Name[nds]=Klangkoort-Typ +Name[nl]=Type geluidskaart +Name[nn]=Lydkorttype +Name[pa]=ਸਾਊਂਡ ਕਾਰਡ ਕਿਸਮ +Name[pl]=Typ karty dźwiękowej +Name[pt]=Tipo de Placa de Som +Name[pt_BR]=Tipo de placa de som +Name[ro]=Tipul plăcii de sunet +Name[ru]=Тип звуковой карты +Name[si]=ශබ්ද කාඩ්පත් වර්ගය +Name[sk]=Typ zvukovej karty +Name[sl]=Vrsta zvočne kartice +Name[sr]=тип звучне картице +Name[sr@ijekavian]=тип звучне картице +Name[sr@ijekavianlatin]=tip zvučne kartice +Name[sr@latin]=tip zvučne kartice +Name[sv]=Typ av ljudkort +Name[tg]=Намуди корти овозӣ +Name[th]=ประเภทของแผงวงจรเสียง +Name[tr]=Ses Kartı Tipi +Name[ug]=ئۈن كارتا تىپى +Name[uk]=Тип звукової картки +Name[wa]=Sôre di cwåte son +Name[x-test]=xxSoundcard Typexx +Name[zh_CN]=声卡类型 +Name[zh_TW]=音效卡類型 + +[Desktop Entry] +Actions=deviceType;driver;driverHandle;name;soundcardType; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=AudioInterface diff --git a/solid-actions-kcm/device-actions/solid-device-Battery.desktop b/solid-actions-kcm/device-actions/solid-device-Battery.desktop new file mode 100644 index 00000000..1ad9c880 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Battery.desktop @@ -0,0 +1,407 @@ +[Desktop Action chargePercent] +Name=Charge Percent +Name[ar]=نسبة الشحن +Name[ast]=Porcentaxe de carga +Name[bg]=Зареждане (%) +Name[bn]=শতকরা চার্জ +Name[bs]=popunjenost +Name[ca]=Percentatge de càrrega +Name[ca@valencia]=Percentatge de càrrega +Name[cs]=Procento nabití +Name[da]=Ladningsprocent +Name[de]=Ladestand +Name[el]=Ποσοστό φόρτισης +Name[en_GB]=Charge Percent +Name[eo]=Procento de Ŝargo +Name[es]=Porcentaje de carga +Name[et]=Täituvuse protsent +Name[eu]=Kargaren ehunekoa +Name[fi]=Latauksen tila prosenteissa +Name[fr]=Pourcentage de charge +Name[fy]=Batterijlading prosint +Name[ga]=Céatadán Luchtaithe +Name[gl]=Mudar a porcentaxe +Name[gu]=ચાર્જ ટકા +Name[he]=אחוז טעינה +Name[hi]=चार्ज प्रतिशत +Name[hr]=Postotak preostalog kapaciteta +Name[hu]=Feltöltöttségi százalék +Name[ia]=Percentage de cargamento +Name[id]=Persentase Pengisian +Name[is]=Prósentuhlutfall hleðslu +Name[it]=Percentuale di carica +Name[ja]=充電率 +Name[kk]=Толу пайызы +Name[km]=ភាគរយបញ្ចូលថ្ម +Name[kn]=ಚಾರ್ಜಿನ ಪ್ರತಿಶತ +Name[ko]=충전률 +Name[lt]=Įkrovimas procentais +Name[lv]=Uzlādes procenti +Name[mai]=चार्ज प्रतिशत +Name[mk]=Процент на полнеж +Name[ml]=ചാര്‍ജ്ജ് ശതമാനം +Name[mr]=चार्ज टक्केवारी +Name[nb]=Prosent lading +Name[nds]=Oplaadperzent +Name[nl]=Ladingspercentage +Name[nn]=Oppladingsprosent +Name[pa]=ਚਾਰਜ ਫੀਸਦੀ +Name[pl]=Poziom naładowania +Name[pt]=Percentagem de Carga +Name[pt_BR]=Porcentagem de carga +Name[ro]=Procentaj încărcare +Name[ru]=Уровень заряда +Name[si]=ආරෝපිත ප්‍රමාණය +Name[sk]=Percento nabitia +Name[sl]=Odstotek napolnjenosti +Name[sr]=попуњеност +Name[sr@ijekavian]=попуњеност +Name[sr@ijekavianlatin]=popunjenost +Name[sr@latin]=popunjenost +Name[sv]=Laddningsprocent +Name[tg]=Фоизи барқгирӣ +Name[th]=ร้อยละของประจุไฟ +Name[tr]=Şarj Yüzdesi +Name[ug]=پىرسەنتىنى ئۆزگەرت +Name[uk]=Рівень заряду +Name[vi]=Phần trăm sạc +Name[wa]=Åcintaedje di tcherdjaedje +Name[x-test]=xxCharge Percentxx +Name[zh_CN]=充电百分比 +Name[zh_TW]=充電百分比 + +[Desktop Action chargeState] +Name=Charge State +Name[ar]=حالة الشحن +Name[ast]=Estáu de carga +Name[bg]=Състояние на зареждането +Name[bn]=চার্জের অবস্থা +Name[bs]=stanje punjenja +Name[ca]=Estat de la càrrega +Name[ca@valencia]=Estat de la càrrega +Name[cs]=Stav nabití +Name[da]=Ladningstilstand +Name[de]=Ladestatus +Name[el]=Κατάσταση φόρτισης +Name[en_GB]=Charge State +Name[eo]=Stato de ŝarĝo +Name[es]=Estado de carga +Name[et]=Täituvuse olek +Name[eu]=Kargaren egoera +Name[fi]=Latauksen tila +Name[fr]=État de charge +Name[fy]=Batterijlading tastân +Name[ga]=Staid Luchtaithe +Name[gl]=Mudar o estado +Name[gu]=ચાર્જ સ્થિતિ +Name[he]=מצב טעינה +Name[hi]=चार्ज स्तिथि +Name[hr]=Stanje preostalog kapaciteta +Name[hu]=Feltöltöttségi állapot +Name[ia]=Stato de cargamento +Name[id]=Tingkat Pengisian +Name[is]=Staða hleðslu +Name[it]=Stato di carica +Name[ja]=充電の状態 +Name[kk]=Толтыру күй-жайы +Name[km]=ស្ថានភាព​បញ្ចូល​ថ្ម +Name[kn]=ಚಾರ್ಜಿನ ಸ್ಥಿತಿ +Name[ko]=충전 상태 +Name[lt]=Įkrovimo būklė +Name[lv]=Uzlādes stāvoklis +Name[mai]=चार्ज स्थिति +Name[mk]=Состојба на полнеж +Name[ml]=ചാര്‍ജ്ജ് സ്ഥിതി +Name[mr]=चार्ज स्थिती +Name[nb]=Ladingstilstand +Name[nds]=Oplaadtostand +Name[nl]=Ladingsstatus +Name[nn]=Oppladingsstatus +Name[pa]=ਚਾਰਜ ਹਾਲਤ +Name[pl]=Stan ładowania +Name[pt]=Estado da Carga +Name[pt_BR]=Estado da carga +Name[ro]=Starea încărcării +Name[ru]=Состояние заряда +Name[si]=ආරෝපණ තත්වය +Name[sk]=Stav nabitia +Name[sl]=Stanje napolnjenosti +Name[sr]=стање пуњења +Name[sr@ijekavian]=стање пуњења +Name[sr@ijekavianlatin]=stanje punjenja +Name[sr@latin]=stanje punjenja +Name[sv]=Laddningstillstånd +Name[tg]=Ҳолати қувва +Name[th]=สถานะการประจุไฟ +Name[tr]=Şarj Durumu +Name[ug]=ھالىتىنى ئۆزگەرت +Name[uk]=Стан зарядженості +Name[vi]=Trạng thái sạc +Name[wa]=Estat do tcherdjaedje +Name[x-test]=xxCharge Statexx +Name[zh_CN]=充电状态 +Name[zh_TW]=充電狀態 + +[Desktop Action plugged] +# ctxt: battery plugged in +Name=Plugged +Name[bs]=Utaknut +Name[ca]=Endollada +Name[ca@valencia]=Endollada +Name[cs]=Připojeno +Name[da]=I stikkontakten +Name[de]=Angeschlossen +Name[el]=Σε σύνδεση +Name[en_GB]=Plugged +Name[es]=Enchufado +Name[et]=Ühendatud +Name[eu]=Konektatuta +Name[fi]=Kytketty +Name[fr]=Branchée +Name[ga]=Plugáilte +Name[gl]=Enchufada +Name[he]=מחובר +Name[hu]=Bedugva +Name[ia]=Connectite +Name[is]=Í sambandi +Name[it]=Connessa +Name[kk]=Қосылған +Name[ko]=연결됨 +Name[lt]=Prijungtas +Name[mr]=प्लग केलेले +Name[nb]=Tilkoblet +Name[nds]=Tokoppelt +Name[nl]=Ingeplugd +Name[pa]=ਪਲੱਗ ਲੱਗਾ +Name[pl]=Podłączona +Name[pt]=Ligada +Name[pt_BR]=Conectada +Name[ro]=Atașat +Name[ru]=Подключён +Name[sk]=Pripojené +Name[sl]=Priključena +Name[sr]=утакнута +Name[sr@ijekavian]=утакнута +Name[sr@ijekavianlatin]=utaknuta +Name[sr@latin]=utaknuta +Name[sv]=Anslutet +Name[tr]=Fişe takılı +Name[uk]=З’єднано +Name[x-test]=xxPluggedxx +Name[zh_CN]=已插入 +Name[zh_TW]=已插入 + +[Desktop Action rechargeable] +Name=Rechargeable +Name[ar]=قابلة للشحن +Name[ast]=Recargable +Name[bg]=Презаредима +Name[bn]=রিচার্জযোগ্য +Name[bs]=punjiva +Name[ca]=Recarregable +Name[ca@valencia]=Recarregable +Name[cs]=Nabíjecí +Name[da]=Genopladeligt +Name[de]=Wiederaufladbar +Name[el]=Επαναφορτιζόμενη +Name[en_GB]=Rechargeable +Name[eo]=Reŝarĝebla +Name[es]=Recargable +Name[et]=Laetav +Name[eu]=Kargatzekoa +Name[fi]=Uudelleenladattavissa +Name[fr]=Rechargeable +Name[fy]=Oplaadbaar +Name[ga]=In-Athluchtaithe +Name[gl]=Recargábel +Name[he]=ניתן לטעינה חוזרת +Name[hi]=चार्जयोग्य +Name[hr]=Punjiva +Name[hu]=Újratölthető +Name[ia]=Recargabile +Name[id]=Dapat Diisi Ulang +Name[is]=Endurhlaðanlegt +Name[it]=Ricaricabile +Name[ja]=再充電可能 +Name[kk]=Қайта толтырылатын +Name[km]=អាច​បញ្ចូល​ថ្ម​បាន +Name[kn]=ಮರು ಚಾರ್ಜ್ ಮಾಡಬಹುದಾದ +Name[ko]=충전 가능 +Name[lt]=Iš naujo pakraunamas +Name[lv]=Lādējams +Name[mai]=फेर चार्ज करैयोग्य +Name[ml]=വീണ്ടും ചാര്‍ജ്ജ് ചെയ്യാവുന്നത് +Name[mr]=परत चार्ज करता येण्याजोगे +Name[nb]=Oppladbar +Name[nds]=Wedderlaadbor +Name[nl]=Oplaadbaar +Name[nn]=Oppladbart +Name[pa]=ਮੁੜ-ਚਾਰਜ ਯੋਗ +Name[pl]=Do wielokrotnego ładowania +Name[pt]=Recarregável +Name[pt_BR]=Recarregável +Name[ro]=Reîncărcabil +Name[ru]=Перезаряжаемая +Name[si]=නැවත ආරෝපනය කල හැකි +Name[sk]=Dobíjateľná +Name[sl]=Znova napolnljiva +Name[sr]=пуњива +Name[sr@ijekavian]=пуњива +Name[sr@ijekavianlatin]=punjiva +Name[sr@latin]=punjiva +Name[sv]=Uppladdningsbart +Name[th]=สามารถประจุไฟใหม่ได้ +Name[tr]=Yeniden şarj edilebilir +Name[ug]=توكلاشچان +Name[uk]=Перезарядка +Name[wa]=Ritcherdjåve +Name[x-test]=xxRechargeablexx +Name[zh_CN]=可充电 +Name[zh_TW]=可重新充電 + +[Desktop Action type] +Name=Type +Name[ar]=النوع +Name[ast]=Triba +Name[bg]=Вид +Name[bn]=ধরন +Name[bs]=tip +Name[ca]=Tipus +Name[ca@valencia]=Tipus +Name[cs]=Typ +Name[csb]=Ôrt +Name[da]=Type +Name[de]=Typ +Name[el]=Τύπος +Name[en_GB]=Type +Name[eo]=Tipo +Name[es]=Tipo +Name[et]=Tüüp +Name[eu]=Mota +Name[fa]=نوع +Name[fi]=Tyyppi +Name[fr]=Type +Name[fy]=Type +Name[ga]=Cineál +Name[gl]=Tipo +Name[gu]=પ્રકાર +Name[he]=סוג +Name[hi]=प्रकार +Name[hr]=Tip +Name[hu]=Típus +Name[ia]=Typo +Name[id]=Tipe +Name[is]=Tegund +Name[it]=Tipo +Name[ja]=タイプ +Name[ka]=ტიპი +Name[kk]=Түрі +Name[km]=ប្រភេទ +Name[kn]=ಬಗೆ +Name[ko]=종류 +Name[lt]=Tipas +Name[lv]=Tips +Name[mai]=प्रकार +Name[mk]=Тип +Name[ml]=തരം +Name[mr]=प्रकार +Name[nb]=Type +Name[nds]=Typ +Name[nl]=Type +Name[nn]=Type +Name[pa]=ਕਿਸਮ +Name[pl]=Typ +Name[pt]=Tipo +Name[pt_BR]=Tipo +Name[ro]=Tip +Name[ru]=Тип +Name[si]=වර්‍ගය +Name[sk]=Typ +Name[sl]=Vrsta +Name[sr]=тип +Name[sr@ijekavian]=тип +Name[sr@ijekavianlatin]=tip +Name[sr@latin]=tip +Name[sv]=Typ +Name[tg]=Намуд +Name[th]=ประเภท +Name[tr]=Tip +Name[ug]=تىپى +Name[uk]=Тип +Name[wa]=Sôre +Name[x-test]=xxTypexx +Name[zh_CN]=类型 +Name[zh_TW]=類型 + +[Desktop Entry] +Actions=chargePercent;chargeState;plugged;rechargeable;type; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Battery diff --git a/solid-actions-kcm/device-actions/solid-device-Block.desktop b/solid-actions-kcm/device-actions/solid-device-Block.desktop new file mode 100644 index 00000000..bbaff8d5 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Block.desktop @@ -0,0 +1,286 @@ +[Desktop Action device] +Name=Device +Name[ar]=الجهاز +Name[ast]=Preseos +Name[bg]=Устройство +Name[bn]=ডিভাইস +Name[bs]=uređaj +Name[ca]=Dispositiu +Name[ca@valencia]=Dispositiu +Name[cs]=Zařízení +Name[csb]=Ùrządzenié +Name[da]=Enhed +Name[de]=Gerät +Name[el]=Συσκευή +Name[en_GB]=Device +Name[eo]=Aparato +Name[es]=Dispositivo +Name[et]=Seade +Name[eu]=Gailua +Name[fa]=دستگاه +Name[fi]=Laite +Name[fr]=Périphérique +Name[fy]=Apparaat +Name[ga]=Gléas +Name[gl]=Dispositivo +Name[gu]=ઉપકરણ +Name[he]=התקן +Name[hi]=औज़ार +Name[hr]=Uređaj +Name[hu]=Eszköz +Name[ia]=Dispositivo +Name[id]=Divais +Name[is]=Tæki +Name[it]=Dispositivo +Name[ja]=デバイス +Name[ka]=მოწყობილობა +Name[kk]=Құрылғысы +Name[km]=ឧបករណ៍ +Name[kn]=ಸಾಧನ +Name[ko]=장치 +Name[lt]=Įrenginys +Name[lv]=Ierīce +Name[mk]=Уред +Name[ml]=ഉപകരണം +Name[mr]=साधन +Name[nb]=Enhet +Name[nds]=Reedschap +Name[nl]=Apparaat +Name[nn]=Eining +Name[pa]=ਜੰਤਰ +Name[pl]=Urządzenie +Name[pt]=Dispositivo +Name[pt_BR]=Dispositivo +Name[ro]=Dispozitiv +Name[ru]=Устройство +Name[si]=මෙවලම +Name[sk]=Zariadenie +Name[sl]=Naprava +Name[sr]=уређај +Name[sr@ijekavian]=уређај +Name[sr@ijekavianlatin]=uređaj +Name[sr@latin]=uređaj +Name[sv]=Enhet +Name[tg]=Дастгоҳ +Name[th]=อุปกรณ์ +Name[tr]=Aygıt +Name[ug]=ئۈسكۈنە +Name[uk]=Пристрій +Name[vi]=Thiết bị +Name[wa]=Éndjin +Name[x-test]=xxDevicexx +Name[zh_CN]=设备 +Name[zh_TW]=裝置 + +[Desktop Action major] +Name=Major +Name[ar]=عام +Name[ast]=Mayor +Name[bn]=মেজর +Name[bs]=Glavnii +Name[ca]=Major +Name[ca@valencia]=Major +Name[cs]=Velké +Name[csb]=Wësok +Name[da]=Stor +Name[de]=Hohe Kennzahl +Name[el]=Κύριο +Name[en_GB]=Major +Name[eo]=ĉefa +Name[es]=Mayor +Name[et]=Põhiversioon +Name[eu]=Handiagoa +Name[fi]=Ensisijainen +Name[fr]=Majeur +Name[fy]=Grut +Name[ga]=Príomh +Name[gl]=Maior +Name[gu]=મુખ્ય +Name[he]=ראשי +Name[hi]=प्रमुख +Name[hr]=Glavni +Name[hu]=Főszám +Name[ia]=Major +Name[id]=Mayor +Name[is]=Mest +Name[it]=Maggiore +Name[ja]=メジャー +Name[kk]=Негізгі +Name[km]=ធំ +Name[kn]=ಪ್ರಮುಖ +Name[ko]=주 +Name[lt]=Pagrindinis +Name[lv]=Galvenais +Name[mk]=Главен +Name[ml]=മുഖ്യം +Name[mr]=मोठा +Name[nb]=Hoved +Name[nds]=Hooch +Name[nl]=Hoofd +Name[nn]=Hovud +Name[pa]=ਮੇਜ਼ਰ +Name[pl]=Główny numer urządzenia +Name[pt]=Nº Maior +Name[pt_BR]=Maior +Name[ro]=Major +Name[ru]=Старший номер (major) +Name[si]=ප්‍රධාන +Name[sk]=Major +Name[sl]=Velika +Name[sr]=велики +Name[sr@ijekavian]=велики +Name[sr@ijekavianlatin]=veliki +Name[sr@latin]=veliki +Name[sv]=Huvudnummer +Name[tg]=Moria +Name[th]=หมายเลขหลัก +Name[tr]=Büyük +Name[ug]=ئاساسىي +Name[uk]=Головний +Name[wa]=Grand +Name[x-test]=xxMajorxx +Name[zh_CN]=主号 +Name[zh_TW]=主要 + +[Desktop Action minor] +Name=Minor +Name[ar]=فرعي +Name[ast]=Menor +Name[bn]=মাইনর +Name[bs]=Sporedni +Name[ca]=Menor +Name[ca@valencia]=Menor +Name[cs]=Malé +Name[csb]=Niskò +Name[da]=Mindre +Name[de]=Niedrige Kennzahl +Name[el]=Δευτερεύον +Name[en_GB]=Minor +Name[eo]=Malĉefa +Name[es]=Menor +Name[et]=Alamversioon +Name[eu]=Txikiagoa +Name[fi]=Toissijainen +Name[fr]=Mineur +Name[fy]=Lyts +Name[ga]=Mion +Name[gl]=Menor +Name[gu]=ગૌણ +Name[he]=משני +Name[hi]=अमुख्य +Name[hr]=Sporedni +Name[hu]=Alszám +Name[ia]=Minor +Name[id]=Minor +Name[is]=Minnst +Name[it]=Minore +Name[ja]=マイナー +Name[kk]=Қосалқы +Name[km]=តូច +Name[kn]=ಅಪ್ರಮುಖ +Name[ko]=부 +Name[lt]=Mažesnis +Name[lv]=Mazais +Name[mk]=Спореден +Name[ml]=നിസാരം +Name[mr]=लहान +Name[nb]=Under +Name[nds]=Siet +Name[nl]=Onder +Name[nn]=Del +Name[pa]=ਮਾਈਨਰ +Name[pl]=Podrzędny numer urządzenia +Name[pt]=Nº Menor +Name[pt_BR]=Menor +Name[ro]=Minor +Name[ru]=Младший номер (minor) +Name[si]=සුළු +Name[sk]=Minor +Name[sl]=Mala +Name[sr]=мали +Name[sr@ijekavian]=мали +Name[sr@ijekavianlatin]=mali +Name[sr@latin]=mali +Name[sv]=Delnummer +Name[tg]=Moria +Name[th]=หมายเลขรอง +Name[tr]=Küçük +Name[ug]=قوشۇمچە +Name[uk]=Додатковий +Name[wa]=Pitit +Name[x-test]=xxMinorxx +Name[zh_CN]=从号 +Name[zh_TW]=次要 + +[Desktop Entry] +Actions=device;major;minor; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Block diff --git a/solid-actions-kcm/device-actions/solid-device-Button.desktop b/solid-actions-kcm/device-actions/solid-device-Button.desktop new file mode 100644 index 00000000..9cfef04f --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Button.desktop @@ -0,0 +1,281 @@ +[Desktop Action hasState] +Name=Has State +Name[ar]=يملك حالة +Name[ast]=Tien estáu +Name[bs]=sa stanjem +Name[ca]=Té estat +Name[ca@valencia]=Té estat +Name[cs]=Má stav +Name[csb]=Mô stón +Name[da]=Har tilstanden +Name[de]=Hat den Status +Name[el]=Έχει κατάσταση +Name[en_GB]=Has State +Name[eo]=Havas Staton +Name[es]=Tiene estado +Name[et]=Olekuga +Name[eu]=Egoera dauka +Name[fi]=On tilassa +Name[fy]=Hat tastân +Name[ga]=Staid Aige +Name[gl]=Ten o estado +Name[gu]=આમાં સ્થિતિ છે +Name[he]=בעל מצב +Name[hi]=स्तिथि है +Name[hr]=Ima li stanje +Name[hu]=Van állapota +Name[ia]=Stato Has +Name[id]=Memiliki Tingkat +Name[is]=Er með stöðu +Name[ja]=状態あり +Name[kk]=Күй-жайы +Name[km]=មាន​ស្ថានភាព +Name[kn]=ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿದೆ +Name[ko]=상태 여부 +Name[lt]=Būklė +Name[lv]=Piemīt stāvoklis +Name[mai]=स्थिति राखैत अछि +Name[mk]=Има состојба +Name[ml]=സ്ഥിതിയുണ്ട് +Name[mr]=स्थिती आहे +Name[nb]=Har tilstand +Name[nds]=Hett en Status +Name[nl]=Heeft status +Name[nn]=Har status +Name[pa]=ਹਾਲਤ ਹੈ +Name[pl]=Ma stan +Name[pt]=Tem o Estado +Name[pt_BR]=Possui estado +Name[ro]=Are stare +Name[ru]=Переключатель +Name[si]=තත්වයක් ඇත +Name[sk]=Má stav +Name[sl]=Ima stanje +Name[sr]=има стање +Name[sr@ijekavian]=има стање +Name[sr@ijekavianlatin]=ima stanje +Name[sr@latin]=ima stanje +Name[sv]=Har tillstånd +Name[tg]=Дорои ҳолат +Name[th]=มีค่าสถานะ +Name[tr]=Duruma Sahip +Name[ug]=ھالەتلىك +Name[uk]=Має стан +Name[vi]=Có trạng thái +Name[wa]=A l' estat +Name[x-test]=xxHas Statexx +Name[zh_CN]=有状态 +Name[zh_TW]=有狀態 + +[Desktop Action stateValue] +Name=State Value +Name[ar]=قيمة الحالة +Name[ast]=Valor del estáu +Name[bs]=vrijednost stanja +Name[ca]=Valor de l'estat +Name[ca@valencia]=Valor de l'estat +Name[cs]=Hodnota stavu +Name[da]=Tilstandsværdi +Name[de]=Status-Wert +Name[el]=Τιμή κατάστασης +Name[en_GB]=State Value +Name[eo]=Valuo de Stato +Name[es]=Valor del estado +Name[et]=Oleku väärtus +Name[eu]=Egoeraren balioa +Name[fi]=Tilan arvo +Name[fy]=Tastân wearde +Name[ga]=Luach na Staide +Name[gl]=Valor do estado +Name[gu]=સ્થિતિ કિંમત +Name[he]=ערך מצב +Name[hi]=स्थिति मान +Name[hr]=Vrijednost stanja +Name[hu]=Állapotérték +Name[ia]=Valor de stato +Name[id]=Nilai Tingkat +Name[is]=Stöðugildi +Name[ja]=状態の値 +Name[kk]=Мөлшері +Name[km]=តម្លៃ​ស្ថានភាព +Name[kn]=ಸ್ಥಿತಿ ಮೌಲ್ಯ +Name[ko]=상태 값 +Name[lt]=Būklės vertė +Name[lv]=Stāvokļa vērtība +Name[mk]=Вредност на состојба +Name[ml]=അവസ്ഥാവില +Name[mr]=स्थिती मूल्य +Name[nb]=Tilstandsverdi +Name[nds]=Statusweert +Name[nl]=Statuswaarde +Name[nn]=Statusverdi +Name[pa]=ਹਾਲਤ ਮੁੱਲ +Name[pl]=Wartość stanu +Name[pt]=Valor do Estado +Name[pt_BR]=Valor do estado +Name[ro]=Valoarea stării +Name[ru]=Значение состояния +Name[si]=තත්ව අගය +Name[sk]=Hodnota stavu +Name[sl]=Vrednost stanja +Name[sr]=вредност стања +Name[sr@ijekavian]=вредност стања +Name[sr@ijekavianlatin]=vrednost stanja +Name[sr@latin]=vrednost stanja +Name[sv]=Tillståndsvärde +Name[tg]=Бозиҳои стратегӣ +Name[th]=ค่าของสถานะ +Name[tr]=Durum Değeri +Name[ug]=ھالەت قىممىتى +Name[uk]=Значення стану +Name[wa]=Valixhance d' estat +Name[x-test]=xxState Valuexx +Name[zh_CN]=状态值 +Name[zh_TW]=狀態值 + +[Desktop Action type] +Name=Type +Name[ar]=النوع +Name[ast]=Triba +Name[bg]=Вид +Name[bn]=ধরন +Name[bs]=tip +Name[ca]=Tipus +Name[ca@valencia]=Tipus +Name[cs]=Typ +Name[csb]=Ôrt +Name[da]=Type +Name[de]=Typ +Name[el]=Τύπος +Name[en_GB]=Type +Name[eo]=Tipo +Name[es]=Tipo +Name[et]=Tüüp +Name[eu]=Mota +Name[fa]=نوع +Name[fi]=Tyyppi +Name[fr]=Type +Name[fy]=Type +Name[ga]=Cineál +Name[gl]=Tipo +Name[gu]=પ્રકાર +Name[he]=סוג +Name[hi]=प्रकार +Name[hr]=Tip +Name[hu]=Típus +Name[ia]=Typo +Name[id]=Tipe +Name[is]=Tegund +Name[it]=Tipo +Name[ja]=タイプ +Name[ka]=ტიპი +Name[kk]=Түрі +Name[km]=ប្រភេទ +Name[kn]=ಬಗೆ +Name[ko]=종류 +Name[lt]=Tipas +Name[lv]=Tips +Name[mai]=प्रकार +Name[mk]=Тип +Name[ml]=തരം +Name[mr]=प्रकार +Name[nb]=Type +Name[nds]=Typ +Name[nl]=Type +Name[nn]=Type +Name[pa]=ਕਿਸਮ +Name[pl]=Typ +Name[pt]=Tipo +Name[pt_BR]=Tipo +Name[ro]=Tip +Name[ru]=Тип +Name[si]=වර්‍ගය +Name[sk]=Typ +Name[sl]=Vrsta +Name[sr]=тип +Name[sr@ijekavian]=тип +Name[sr@ijekavianlatin]=tip +Name[sr@latin]=tip +Name[sv]=Typ +Name[tg]=Намуд +Name[th]=ประเภท +Name[tr]=Tip +Name[ug]=تىپى +Name[uk]=Тип +Name[wa]=Sôre +Name[x-test]=xxTypexx +Name[zh_CN]=类型 +Name[zh_TW]=類型 + +[Desktop Entry] +Actions=hasState;stateValue;type; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Button diff --git a/solid-actions-kcm/device-actions/solid-device-Camera.desktop b/solid-actions-kcm/device-actions/solid-device-Camera.desktop new file mode 100644 index 00000000..021aa940 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Camera.desktop @@ -0,0 +1,215 @@ +[Desktop Action supportedDrivers] +Name=Supported Drivers +Name[ar]=المشغلات المدعومة +Name[ast]=Controladores sofitaos +Name[bg]=Поддържани драйвери +Name[bn]=সমর্থিত ড্রাইভার +Name[bs]=podržani drajveri +Name[ca]=Controladors acceptats +Name[ca@valencia]=Controladors acceptats +Name[cs]=Podporované ovladače +Name[csb]=Wspiéróné czérowniczi +Name[da]=Understøttede drivere +Name[de]=Unterstützte Treiber +Name[el]=Υποστηριζόμενοι οδηγοί +Name[en_GB]=Supported Drivers +Name[eo]=subtenataj Peliloj +Name[es]=Dispositivos soportados +Name[et]=Toetatud draiverid +Name[eu]=Onartutzen diren gidariak +Name[fi]=Tuetut ajurit +Name[fr]=Pilotes pris en charge +Name[fy]=Stipe stjoerprogramma's +Name[ga]=Tiománaithe a dTacaítear Leo +Name[gl]=Controladores soportados +Name[gu]=આધારિત ડ્રાઇવરો +Name[he]=מנהלי התקנים נתמכים +Name[hi]=समर्थित ड्राईवर +Name[hr]=Podržani pisači +Name[hu]=Támogatott meghajtók +Name[ia]=Drivers supportate +Name[id]=Penggerak Didukung +Name[is]=Studdir reklar +Name[it]=Driver supportati +Name[ja]=サポートされているドライバ +Name[kk]=Қолдайтын драйверлері +Name[km]=កម្មវិធី​បញ្ជា​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಚಾಲಕಗಳು +Name[ko]=지원하는 드라이버 +Name[lt]=Palaikomos tvarkyklės +Name[lv]=Atbalstītie draiveri +Name[mai]=समर्थित ड्राइवर +Name[mk]=Поддржани управувачи +Name[ml]=പിന്തുണയുള്ള സാരഥികള്‍ +Name[mr]=समर्थीत ड्राइव्हर्स +Name[nb]=Støttede drivere +Name[nds]=Ünnerstütt Drievers +Name[nl]=Ondersteunde stuurprogramma's +Name[nn]=Støtta drivarar +Name[pa]=ਸਹਾਇਕ ਡਰਾਇਵਰ +Name[pl]=Obsługiwane sterowniki +Name[pt]=Controladores Suportados +Name[pt_BR]=Drivers suportados +Name[ro]=Drivere susținute +Name[ru]=Поддерживаемые драйверы +Name[si]=සහාය දක්වන ධාවක +Name[sk]=Podporované ovládače +Name[sl]=Podprti gonilniki +Name[sr]=подржани драјвери +Name[sr@ijekavian]=подржани драјвери +Name[sr@ijekavianlatin]=podržani drajveri +Name[sr@latin]=podržani drajveri +Name[sv]=Drivrutiner som stöds +Name[tg]=Дастгоҳҳои мувофиқ +Name[th]=ไดรเวอร์ที่รองรับ +Name[tr]=Desteklenen Sürücüler +Name[ug]=قوللايدىغان قوزغاتقۇلار +Name[uk]=Підтримувані драйвери +Name[wa]=Mineus sopoirtés +Name[x-test]=xxSupported Driversxx +Name[zh_CN]=支持的驱动 +Name[zh_TW]=支援的驅動程式 + +[Desktop Action supportedProtocols] +Name=Supported Protocols +Name[ar]=البروتوكولات المدعومة +Name[ast]=Protocolos sofitaos +Name[bg]=Поддържани протоколи +Name[bn]=সমর্থিত প্রোটোকল +Name[bs]=podržani protokoli +Name[ca]=Protocols acceptats +Name[ca@valencia]=Protocols acceptats +Name[cs]=Podporované protokoly +Name[csb]=Wspiéróné protokòłë +Name[da]=Understøttede protokoller +Name[de]=Unterstützte Protokolle +Name[el]=Υποστηριζόμενα πρωτόκολλα +Name[en_GB]=Supported Protocols +Name[eo]=Subtenitaj Protokoloj +Name[es]=Protocolos soportados +Name[et]=Toetatud protokollid +Name[eu]=Onartzen diren protokoloak +Name[fi]=Tuetut yhteyskäytännöt +Name[fr]=Protocoles pris en charge +Name[fy]=Stipe protokollen +Name[ga]=Prótacail a dTacaítear Leo +Name[gl]=Protocolos soportados +Name[gu]=આધારિત પ્રોટોકોલ્સ +Name[he]=פרוטוקולים נתמכים +Name[hi]=समर्थित प्रोटोकॉल +Name[hr]=Podržani Protokoli +Name[hu]=Támogatott protokollok +Name[ia]=Protocollos supportate +Name[id]=Protokol Didukung +Name[is]=Studdar samskiptareglur +Name[it]=Protocolli supportati +Name[ja]=サポートされているプロトコル +Name[kk]=Қолдайтын протоколдары +Name[km]=ពិពីការ​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಪ್ರಕ್ರಮಗಳು (ಪ್ರೋಟೋಕಾಲ್) +Name[ko]=지원하는 프로토콜 +Name[lt]=Palaikomi protokolai +Name[lv]=Atbalstītie protokoli +Name[mk]=Поддржани протоколи +Name[ml]=പിന്തുണയ്ക്കുന്ന സമ്പ്രദായങ്ങള്‍ +Name[mr]=समर्थीत शिष्टाचार +Name[nb]=Støttede protokoller +Name[nds]=Ünnerstütt Protokollen +Name[nl]=Ondersteunde protocollen +Name[nn]=Støtta protokollar +Name[pa]=ਸਹਾਇਕ ਪਰੋਟੋਕਾਲ +Name[pl]=Obsługiwane protokoły +Name[pt]=Protocolos Suportados +Name[pt_BR]=Protocolos suportados +Name[ro]=Protocoale susținute +Name[ru]=Поддерживаемые протоколы +Name[si]=සහාය දක්වන ක්‍රියා පටිපාටි +Name[sk]=Podporované protokoly +Name[sl]=Podprti protokoli +Name[sr]=подржани протоколи +Name[sr@ijekavian]=подржани протоколи +Name[sr@ijekavianlatin]=podržani protokoli +Name[sr@latin]=podržani protokoli +Name[sv]=Protokoll som stöds +Name[tg]=Протоколҳо +Name[th]=โพรโทคอลที่รองรับ +Name[tr]=Desteklenen Protokoller +Name[ug]=قوللايدىغان كېلىشىملەر +Name[uk]=Підтримувані протоколи +Name[wa]=Protocoles sopoirtés +Name[x-test]=xxSupported Protocolsxx +Name[zh_CN]=支持的协议 +Name[zh_TW]=支援的協定 + +[Desktop Entry] +Actions=supportedDrivers;supportedProtocols; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Camera diff --git a/solid-actions-kcm/device-actions/solid-device-DvbInterface.desktop b/solid-actions-kcm/device-actions/solid-device-DvbInterface.desktop new file mode 100644 index 00000000..70d6e3f1 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-DvbInterface.desktop @@ -0,0 +1,360 @@ +[Desktop Action device] +Name=Device +Name[ar]=الجهاز +Name[ast]=Preseos +Name[bg]=Устройство +Name[bn]=ডিভাইস +Name[bs]=uređaj +Name[ca]=Dispositiu +Name[ca@valencia]=Dispositiu +Name[cs]=Zařízení +Name[csb]=Ùrządzenié +Name[da]=Enhed +Name[de]=Gerät +Name[el]=Συσκευή +Name[en_GB]=Device +Name[eo]=Aparato +Name[es]=Dispositivo +Name[et]=Seade +Name[eu]=Gailua +Name[fa]=دستگاه +Name[fi]=Laite +Name[fr]=Périphérique +Name[fy]=Apparaat +Name[ga]=Gléas +Name[gl]=Dispositivo +Name[gu]=ઉપકરણ +Name[he]=התקן +Name[hi]=औज़ार +Name[hr]=Uređaj +Name[hu]=Eszköz +Name[ia]=Dispositivo +Name[id]=Divais +Name[is]=Tæki +Name[it]=Dispositivo +Name[ja]=デバイス +Name[ka]=მოწყობილობა +Name[kk]=Құрылғысы +Name[km]=ឧបករណ៍ +Name[kn]=ಸಾಧನ +Name[ko]=장치 +Name[lt]=Įrenginys +Name[lv]=Ierīce +Name[mk]=Уред +Name[ml]=ഉപകരണം +Name[mr]=साधन +Name[nb]=Enhet +Name[nds]=Reedschap +Name[nl]=Apparaat +Name[nn]=Eining +Name[pa]=ਜੰਤਰ +Name[pl]=Urządzenie +Name[pt]=Dispositivo +Name[pt_BR]=Dispositivo +Name[ro]=Dispozitiv +Name[ru]=Устройство +Name[si]=මෙවලම +Name[sk]=Zariadenie +Name[sl]=Naprava +Name[sr]=уређај +Name[sr@ijekavian]=уређај +Name[sr@ijekavianlatin]=uređaj +Name[sr@latin]=uređaj +Name[sv]=Enhet +Name[tg]=Дастгоҳ +Name[th]=อุปกรณ์ +Name[tr]=Aygıt +Name[ug]=ئۈسكۈنە +Name[uk]=Пристрій +Name[vi]=Thiết bị +Name[wa]=Éndjin +Name[x-test]=xxDevicexx +Name[zh_CN]=设备 +Name[zh_TW]=裝置 + +[Desktop Action deviceAdapter] +Name=Device Adapter +Name[ar]=محول الجهاز +Name[ast]=Adautador de preséu +Name[bg]=Адаптор на устройството +Name[bn]=ডিভাইস অ্যাডাপ্টার +Name[bs]=adapter uređaja +Name[ca]=Adaptador de dispositius +Name[ca@valencia]=Adaptador de dispositius +Name[cs]=Adaptér zařízení +Name[csb]=Adapter ùrządzenia +Name[da]=Enhedsadapter +Name[de]=Geräteadapter +Name[el]=Προσαρμογέας συσκευής +Name[en_GB]=Device Adapter +Name[eo]=Aparata adaptilo +Name[es]=Adaptador de dispositivo +Name[et]=Seadme adapter +Name[eu]=Gailu-egokigailua +Name[fi]=Laitesovitin +Name[fr]=Adaptateur de périphériques +Name[fy]=Apparaat adapter +Name[ga]=Cuibheoir Gléis +Name[gl]=Adaptador de dispositivos +Name[gu]=ઉપકરણ એડપ્ટર +Name[he]=מתאם התקן +Name[hi]=उपकरण एडेपटर +Name[hr]=Prilagodnik uređaja +Name[hu]=Eszközadapter +Name[ia]=Adaptator del dispositivo +Name[id]=Adaptor Divais +Name[is]=Tengi tækis +Name[ja]=デバイスのアダプタ +Name[kk]=Құрылғы адаптері +Name[km]=អាដាប់ទ័រ​ឧបករណ៍​ +Name[kn]=ಸಾಧನದ ಅಡಾಪ್ಟರ್ +Name[ko]=장치 어댑터 +Name[lt]=Įrenginio adapteris +Name[lv]=Ierīces adapteris +Name[mk]=Адаптер за уред +Name[ml]=ഉപകരണത്തിന്റെ അഡാപ്റ്റര്‍ +Name[mr]=साधन अडॅप्टर +Name[nb]=Enhetsadapter +Name[nds]=Reedschap +Name[nl]=Apparaat-adapter +Name[nn]=Straumtilkopling for eining +Name[pa]=ਜੰਤਰ ਅਡਪੈਟਰ +Name[pl]=Adapter urządzenia +Name[pt]=Adaptador de Dispositivo +Name[pt_BR]=Adaptador de dispositivo +Name[ro]=Adaptor dispozitiv +Name[ru]=Адаптер устройства +Name[si]=මෙවලම් අනුහුරුව +Name[sk]=Adaptér zariadenia +Name[sl]=Vmesnik naprave +Name[sr]=адаптер уређаја +Name[sr@ijekavian]=адаптер уређаја +Name[sr@ijekavianlatin]=adapter uređaja +Name[sr@latin]=adapter uređaja +Name[sv]=Enhetsadapter +Name[tg]=Извещение о новых устройствах +Name[th]=อะแดปเตอร์อุปกรณ์ +Name[tr]=Aygıt Bağdaştırıcısı +Name[ug]=ئۈسكۈنە ماسلاشتۇرغۇچ +Name[uk]=Адаптер пристрою +Name[vi]=Bộ tiếp hợp cho thiết bị +Name[wa]=Adaptateu d' éndjin +Name[x-test]=xxDevice Adapterxx +Name[zh_CN]=设备适配器 +Name[zh_TW]=裝置接合器 + +[Desktop Action deviceIndex] +Name=Device Index +Name[ar]=فهرس الجهاز +Name[ast]=Índiz de preséu +Name[bg]=Индекс на устройство +Name[bn]=ডিভাইস ইন্ডেক্স +Name[bs]=indeks uređaja +Name[ca]=Índex de dispositius +Name[ca@valencia]=Índex de dispositius +Name[cs]=Index zařízení +Name[csb]=Indeks ùrządzeniów +Name[da]=Enhedsindeks +Name[de]=Geräteindex +Name[el]=Δείκτης συσκευής +Name[en_GB]=Device Index +Name[eo]=Indekso de Aparatoj +Name[es]=Índice de dispositivo +Name[et]=Seadme indeks +Name[eu]=Gailu-indizea +Name[fi]=Laiteindeksi +Name[fr]=Index du périphérique +Name[fy]=Apparat yndeks +Name[ga]=Innéacs Gléis +Name[gl]=Índice de dispositivos +Name[gu]=ઉપકરણ અનુક્રમ +Name[he]=אינדקס התקן +Name[hi]=उपकरण क्रमांक +Name[hr]=Indeks uređaja +Name[hu]=Eszközindex +Name[ia]=Indice del dispositivo +Name[id]=Indeks Divais +Name[is]=Yfirlit tækis +Name[ja]=デバイスのインデックス +Name[kk]=Құрылғы индексі +Name[km]=លិបិក្រម​ឧបករណ៍ +Name[kn]=ಸಾಧನದ ಸೂಚಿ (ಇಂಡೆಕ್ಸ್) +Name[ko]=장치 인덱스 +Name[lt]=Įrenginio indeksas +Name[lv]=Ierīces indekss +Name[mk]=Индекс на уреди +Name[ml]=ഉപകരണത്തിന്റെ സൂചിക +Name[mr]=साधन अनुक्रमणिका +Name[nb]=Enhetsindeks +Name[nds]=Reedschap-Index +Name[nl]=Apparaatindex +Name[nn]=Indeks for eining +Name[pa]=ਜੰਤਰ ਇੰਡੈਕਸ +Name[pl]=Indeks urządzenia +Name[pt]=Índice do Dispositivo +Name[pt_BR]=Índice do dispositivo +Name[ro]=Index dispozitiv +Name[ru]=Номер устройства +Name[si]=මෙවලම් සූචිය +Name[sk]=Index zariadenia +Name[sl]=Indeks naprave +Name[sr]=индекс уређаја +Name[sr@ijekavian]=индекс уређаја +Name[sr@ijekavianlatin]=indeks uređaja +Name[sr@latin]=indeks uređaja +Name[sv]=Enhetsindex +Name[tg]=Индекси роҳнамо +Name[th]=ดัชนีอุปกรณ์ +Name[tr]=Aygıt Dizini +Name[ug]=ئۈسكۈنە ئىندىكىسى +Name[uk]=Індекс пристрою +Name[vi]=Chỉ mục thiết bị +Name[wa]=Indecse di l' éndjin +Name[x-test]=xxDevice Indexxx +Name[zh_CN]=设备索引 +Name[zh_TW]=裝置索引 + +[Desktop Action deviceType] +Name=Device Type +Name[ar]=نوع الجهاز +Name[ast]=Triba de preséu +Name[bg]=Вид устройство +Name[bn]=ডিভাইস ধরন +Name[bs]=tip uređaja +Name[ca]=Tipus de dispositiu +Name[ca@valencia]=Tipus de dispositiu +Name[cs]=Typ zařízení +Name[csb]=Ôrt ùrządzenia +Name[da]=Enhedstype +Name[de]=Gerätetyp +Name[el]=Τύπος συσκευής +Name[en_GB]=Device Type +Name[eo]=Aparata Tipo +Name[es]=Tipo de dispositivo +Name[et]=Seadme tüüp +Name[eu]=Gailu mota +Name[fa]=نوع دستگاه +Name[fi]=Laitetyyppi +Name[fr]=Type de périphérique +Name[fy]=Apparaat type +Name[ga]=Cineál Gléis +Name[gl]=Tipo do dispositivo +Name[gu]=ઉપકરણ પ્રકાર +Name[he]=סוג ההתקן +Name[hi]=औज़ार प्रकार +Name[hr]=Tip uređaja +Name[hu]=Eszköztípus +Name[ia]=Typo de dispositivo +Name[id]=Tipe Divais +Name[is]=Tegund tækis +Name[ja]=デバイスのタイプ +Name[kk]=Құрылғының түрі +Name[km]=ប្រភេទ​ឧបករណ៍ +Name[kn]=ಸಾಧನದ ಬಗೆ +Name[ko]=장치 종류 +Name[lt]=Įrenginio tipas +Name[lv]=Ierīces tips +Name[mk]=Тип на уред +Name[ml]=ഉപകരണതരം +Name[mr]=साधन प्रकार +Name[nb]=Enhetstype +Name[nds]=Reedschaptyp +Name[nl]=Apparaattype +Name[nn]=Einingstype +Name[pa]=ਜੰਤਰ ਕਿਸਮ +Name[pl]=Typ urządzenia +Name[pt]=Tipo de Dispositivo +Name[pt_BR]=Tipo de dispositivo +Name[ro]=Tip dispozitiv +Name[ru]=Тип устройства +Name[si]=මෙවලම් වර්‍ගය +Name[sk]=Typ zariadenia +Name[sl]=Vrsta naprave +Name[sr]=тип уређаја +Name[sr@ijekavian]=тип уређаја +Name[sr@ijekavianlatin]=tip uređaja +Name[sr@latin]=tip uređaja +Name[sv]=Enhetstyp +Name[tg]=Дастгоҳҳо +Name[th]=ประเภทของอุปกรณ์ +Name[tr]=Aygıt Tipi +Name[ug]=ئۈسكۈنە تىپى +Name[uk]=Тип пристрою +Name[vi]=Kiểu thiết bị +Name[wa]=Sôre d' éndjin +Name[x-test]=xxDevice Typexx +Name[zh_CN]=设备类型 +Name[zh_TW]=裝置類型 + +[Desktop Entry] +Actions=device;deviceAdapter;deviceIndex;deviceType; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=DvbInterface diff --git a/solid-actions-kcm/device-actions/solid-device-NetworkInterface.desktop b/solid-actions-kcm/device-actions/solid-device-NetworkInterface.desktop new file mode 100644 index 00000000..7cdf9fd8 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-NetworkInterface.desktop @@ -0,0 +1,360 @@ +[Desktop Action hwAddress] +Name=Hw Address +Name[ar]=عنوان العتاد +Name[ast]=Direición HW +Name[bg]=Хардуерен адрес +Name[bn]=Hw অ্যাড্রেস +Name[bs]=hv. adresa +Name[ca]=Adreça maquinari +Name[ca@valencia]=Adreça maquinari +Name[cs]=Hw adresa +Name[csb]=Adresa Hw +Name[da]=HW-adresse +Name[de]=HW-Adresse +Name[el]=Διεύθυνση Hw +Name[en_GB]=Hw Address +Name[eo]=Hw Adreso +Name[es]=Dirección HW +Name[et]=Riistvara-aadress +Name[eu]=HW helbidea +Name[fi]=Rautaosoite +Name[fr]=Adresse matérielle +Name[fy]=Hw adres +Name[ga]=Seoladh Crua-Earraí +Name[gl]=Enderezo hardware +Name[gu]=હાર્ડવેર સરનામું +Name[he]=כתובת חומרה +Name[hi]=हार्डवेयर पता +Name[hr]=Hardverska adresa +Name[hu]=Hardveres cím +Name[ia]=Adresse Hw +Name[id]=Alamat Peranti Keras +Name[is]=HW vistfang +Name[ja]=HW アドレス +Name[kk]=Жабд. адресі +Name[km]=អាសយដ្ឋាន Hw +Name[kn]=Hw ವಿಳಾಸ +Name[ko]=하드웨어 주소 +Name[lt]=Aparatinis adresas +Name[lv]=Hw adrese +Name[mai]=Hw पता +Name[mk]=Адреса на хардвер +Name[ml]=എച്ച്ഡബ്ല്യൂ വിലാസം +Name[mr]=Hw पत्ता +Name[nb]=Hw-adresse +Name[nds]=Hardware-Adress +Name[nl]=HW-adres +Name[nn]=Maskinvareadresse +Name[pa]=Hw ਐਡਰੈੱਸ +Name[pl]=Adres sprzętowy +Name[pt]=Endereço de H/W +Name[pt_BR]=Endereço de hardware +Name[ro]=Adresă fizică +Name[ru]=Аппаратный адрес +Name[si]=Hw ලිපිනය +Name[sk]=Hw adresa +Name[sl]=Strojni naslov +Name[sr]=хв. адреса +Name[sr@ijekavian]=хв. адреса +Name[sr@ijekavianlatin]=hv. adresa +Name[sr@latin]=hv. adresa +Name[sv]=Hårdvaruadress +Name[tg]=Суроғаи Hw +Name[th]=ที่อยู่ฮาร์ดแวร์ +Name[tr]=Donanım Adresi +Name[ug]=قاتتىق دېتال ئادرېسى +Name[uk]=Апар. адреса +Name[vi]=Địa chỉ phần cứng +Name[wa]=Adresse Hw +Name[x-test]=xxHw Addressxx +Name[zh_CN]=硬件地址 +Name[zh_TW]=硬體位址 + +[Desktop Action ifaceName] +Name=Iface Name +Name[ar]=اسم الواجهة +Name[ast]=Nome d'interface +Name[bg]=Име на интерфейс +Name[bn]=Iface-এর নাম +Name[bs]=ime sučelja +Name[ca]=Nom d'interfície +Name[ca@valencia]=Nom d'interfície +Name[cs]=Název rozhraní +Name[csb]=Miono Iface +Name[da]=Navn på grænseflade +Name[de]=Schnittstellen-Name +Name[el]=Όνομα Iface +Name[en_GB]=Iface Name +Name[eo]=Iface Nomo +Name[es]=Nombre de interfaz +Name[et]=Liidese nimi +Name[eu]=Interfaze-izena +Name[fi]=Verkkoliitynnän nimi +Name[fr]=Nom « Iface » +Name[fy]=Iface namme +Name[ga]=Ainm an Chomhéadain +Name[gl]=Nome da interface +Name[gu]=ઇન્ટરફેસ નામ +Name[he]=שם Iface +Name[hi]=Iface नाम +Name[hr]=Ime sučelja +Name[hu]=Felületnév +Name[ia]=Nomine Iface +Name[id]=Nama Antarmuka +Name[is]=IFACE nafn +Name[ja]=インターフェース名 +Name[kk]=И-фейс атауы +Name[km]=ឈ្មោះ Iface +Name[kn]=Iface ಹೆಸರು +Name[ko]=인터페이스 이름 +Name[lt]=Sąsajos pavadinimas +Name[lv]=Sask. nosaukums +Name[mk]=Име на интерфејс +Name[ml]=ഐഫേസിന്റെ പേരു് +Name[mr]=Iface नाव +Name[nb]=G.snitt-navn +Name[nds]=Koppelsteed-Naam +Name[nl]=Iface-naam +Name[nn]=Grensesnittnamn +Name[pa]=Iface ਨਾਂ +Name[pl]=Nazwa interfejsu +Name[pt]=Nome da Interface +Name[pt_BR]=Nome da interface +Name[ro]=Denumire interfață +Name[ru]=Название интерфейса +Name[si]=Iface නාමය +Name[sk]=Názov rozhrania +Name[sl]=Ime vmesnika +Name[sr]=име сучеља +Name[sr@ijekavian]=име сучеља +Name[sr@ijekavianlatin]=ime sučelja +Name[sr@latin]=ime sučelja +Name[sv]=Gränssnittsnamn +Name[tg]=Бозиҳои Dice +Name[th]=ชื่อส่วนติดต่อ +Name[tr]=Iface Adı +Name[ug]=ئارايۈز ئاتى +Name[uk]=Назва Iface +Name[vi]=Tên Iface +Name[wa]=No Iface +Name[x-test]=xxIface Namexx +Name[zh_CN]=接口名称 +Name[zh_TW]=介面名稱 + +[Desktop Action macAddress] +Name=Mac Address +Name[ar]=عنوان Mac +Name[ast]=Direición MAC +Name[bg]=МАС-адрес +Name[bn]=ম্যাক অ্যাড্রেস +Name[bs]=MAC adresa +Name[ca]=Adreça MAC +Name[ca@valencia]=Adreça MAC +Name[cs]=Mac adresa +Name[csb]=Adresa Mac +Name[da]=MAC-adresse +Name[de]=MAC-Adresse +Name[el]=Διεύθυνση MAC +Name[en_GB]=Mac Address +Name[eo]=Maŝinadreso +Name[es]=Dirección MAC +Name[et]=MAC-aadress +Name[eu]=MAC helbidea +Name[fi]=Mac-osoite +Name[fr]=Adresse « Mac » +Name[fy]=Mac adres +Name[ga]=Seoladh MAC +Name[gl]=Enderezo MAC +Name[gu]=મેક સરનામું +Name[he]=כתובת MAC +Name[hi]=मेक पता +Name[hr]=MAC adresa +Name[hu]=MAC cím +Name[ia]=Adresse Mac +Name[id]=Alamat Mac +Name[is]=MAC vistfang +Name[ja]=Mac アドレス +Name[ka]=MAC მისამართი +Name[kk]=Mac адресі +Name[km]=អាសយដ្ឋាន Mac +Name[kn]=ಮ್ಯಾಕ್ ವಿಳಾಸ +Name[ko]=MAC 주소 +Name[lt]=Mac adresas +Name[lv]=Mac adrese +Name[mai]=Mac पता +Name[mk]=Mac-адреса +Name[ml]=മാക് വിലാസം +Name[mr]=Mac पत्ता +Name[nb]=MAC-adresse +Name[nds]=Mac-Adress +Name[nl]=MAC-adres +Name[nn]=MAC-adresse +Name[pa]=ਮੈਕ ਐਡਰੈੱਸ +Name[pl]=Adres Mac +Name[pt]=Endereço MAC +Name[pt_BR]=Endereço MAC +Name[ro]=Adresă MAC +Name[ru]=MAC-адрес +Name[si]=මැක් ලිපිනය +Name[sk]=Mac adresa +Name[sl]=Naslov MAC +Name[sr]=МАЦ адреса +Name[sr@ijekavian]=МАЦ адреса +Name[sr@ijekavianlatin]=MAC adresa +Name[sr@latin]=MAC adresa +Name[sv]=MAC-adress +Name[tg]=Суроғаи Mac +Name[th]=ค่าที่อยู่ Mac +Name[tr]=Mac Adresi +Name[ug]=MAC ئادرېس +Name[uk]=Mac-адреса +Name[vi]=Địa chỉ Mac +Name[wa]=Adresse Mac +Name[x-test]=xxMac Addressxx +Name[zh_CN]=Mac 地址 +Name[zh_TW]=Mac 位址 + +[Desktop Action wireless] +Name=Wireless +Name[ar]=لاسلكي +Name[ast]=Inalámbricu +Name[bg]=Безжична мрежа +Name[bn]=ওয়্যারলেস +Name[bs]=bežična +Name[ca]=Xarxa sense fils +Name[ca@valencia]=Xarxa sense fils +Name[cs]=Bezdrátové +Name[csb]=Bezkablowé +Name[da]=Trådløst +Name[de]=Drahtlos +Name[el]=Ασύρματο +Name[en_GB]=Wireless +Name[eo]=Sendrata reto +Name[es]=Inalámbrico +Name[et]=Juhtmeta +Name[eu]=Haririk gabea +Name[fa]=بی‌سیم +Name[fi]=Langaton +Name[fr]=Sans fil +Name[fy]=Triedleas +Name[ga]=Gan Sreang +Name[gl]=Sen fíos +Name[gu]=વાયરલેસ +Name[he]=אלחוטי +Name[hi]=बेतार +Name[hr]=Bežićna +Name[hu]=Vezeték nélküli +Name[ia]=Wireless (Sin Cablos) +Name[id]=Nirkabel +Name[is]=Þráðlaust +Name[ja]=ワイヤレス +Name[ka]=უმავთულო კავშირი +Name[kk]=Сымсыз +Name[km]=ឥតខ្សែ +Name[kn]=ವೈರ್ಲೆಸ್ +Name[ko]=무선 +Name[lt]=Bevielis +Name[lv]=Bezvadu +Name[mk]=Бежичен +Name[ml]=വയര്‍ലസ്സ് +Name[mr]=वायरलेस +Name[nb]=Trådløs +Name[nds]=Funk +Name[nl]=Draadloos +Name[nn]=Trådlaust +Name[pa]=ਬੇਤਾਰ +Name[pl]=Bezprzewodowy +Name[pt]=Sem-Fios +Name[pt_BR]=Sem fio +Name[ro]=Fără fir +Name[ru]=Беспроводная сеть +Name[si]=රැහැන් රහිත +Name[sk]=Bezdrôtové +Name[sl]=Brezžično +Name[sr]=бежична +Name[sr@ijekavian]=бежична +Name[sr@ijekavianlatin]=bežična +Name[sr@latin]=bežična +Name[sv]=Trådlöst +Name[tg]=Бесимӣ +Name[th]=อุปกรณ์ไร้สาย +Name[tr]=Kablosuz +Name[ug]=سىمسىز +Name[uk]=Бездротове +Name[wa]=Sins fyi +Name[x-test]=xxWirelessxx +Name[zh_CN]=无线 +Name[zh_TW]=無線 + +[Desktop Entry] +Actions=hwAddress;ifaceName;macAddress;wireless; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=NetworkInterface diff --git a/solid-actions-kcm/device-actions/solid-device-OpticalDisc.desktop b/solid-actions-kcm/device-actions/solid-device-OpticalDisc.desktop new file mode 100644 index 00000000..11f3b059 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-OpticalDisc.desktop @@ -0,0 +1,941 @@ +[Desktop Action appendable] +Name=Appendable +Name[ar]=قابل للإضافة +Name[ast]=Pue amestase +Name[bg]=Незавършен диск +Name[bn]=যোগ করা যাবে +Name[bs]=dopisiv +Name[ca]=Afegible +Name[ca@valencia]=Afegible +Name[cs]=Připojitelný +Name[csb]=Dodôwny +Name[da]=Data kan tilføjes +Name[de]=Anhängbar +Name[el]=Προσαρτήσιμο +Name[en_GB]=Appendable +Name[eo]=Aldonebla +Name[es]=Se puede añadir +Name[et]=Lisatav +Name[eu]=Gehi dakiokeena +Name[fi]=Liitettävä +Name[fr]=Opposable +Name[fy]=Kin taheakje +Name[ga]=In-iarcheangailte +Name[gl]=Poden engadírselle datos +Name[gu]=ઉમેરી શકાય તેવું +Name[he]=ניתן להוסיף עליו +Name[hi]=संल्गनक +Name[hr]=Može se dodavati +Name[hu]=Hozzáfűzhető +Name[ia]=On pote adjunger +Name[id]=Dapat Ditambahkan +Name[is]=Hægt að bæta við +Name[it]=Aggiungibile +Name[ja]=追記可能 +Name[kk]=Жалғасулы +Name[km]=អាច​បន្ថែមខាង​ចុង​បាន +Name[kn]=ಸೇರಿಸಬಹುದಾದ +Name[ko]=추가 가능 +Name[lt]=Pridedamas +Name[lv]=Papildināms +Name[ml]=വീണ്ടും എഴുതാവുന്നതു് +Name[mr]=जोडता येण्याजोगे +Name[nb]=Har plass igjen +Name[nds]=Nich afslaten +Name[nl]=Uitbreidbaar +Name[nn]=Tilleggbar +Name[pa]=ਜੋੜਨਯੋਗ +Name[pl]=Z możliwością dopisywania +Name[pt]=Adicionável +Name[pt_BR]=Anexável +Name[ro]=Completabil +Name[ru]=Дозаписываемый +Name[si]=ඇමිණිය හැකි +Name[sk]=Doplniteľné +Name[sl]=Dodajanje je mogoče +Name[sr]=дописив +Name[sr@ijekavian]=дописив +Name[sr@ijekavianlatin]=dopisiv +Name[sr@latin]=dopisiv +Name[sv]=Tilläggbar +Name[tg]=Намуди зоҳирӣ +Name[th]=สามารถเขียนเพิ่มเติมได้ +Name[tr]=Eklenebilir +Name[ug]=قوشۇشقا بولىدۇ +Name[uk]=Додавання +Name[vi]=Có thể ghi thêm +Name[wa]=Adjoutåve +Name[x-test]=xxAppendablexx +Name[zh_CN]=可追加 +Name[zh_TW]=可附加 + +[Desktop Action availableContent] +Name=Available Content +Name[ar]=المحتويات المتوفرة +Name[ast]=Conteníu disponible +Name[bg]=Налично съдържание +Name[bn]=পাওয়া যাচ্ছে +Name[bs]=dostupan sadržaj +Name[ca]=Contingut disponible +Name[ca@valencia]=Contingut disponible +Name[cs]=Dostupný obsah +Name[csb]=Przëstãpnô zamkłosc +Name[da]=Tilgængeligt indhold +Name[de]=Verfügbarer Inhalt +Name[el]=Διαθέσιμο περιεχόμενο +Name[en_GB]=Available Content +Name[eo]=Havebla Enhavo +Name[es]=Contenido disponible +Name[et]=Sisuga +Name[eu]=Eduki eskuragarria +Name[fi]=Käytettävissä oleva sisältö +Name[fr]=Contenu disponible +Name[fy]=Beskikbere ynhâld +Name[ga]=Ábhar Le Fáil +Name[gl]=Contido dispoñíbel +Name[gu]=પ્રાપ્ત વિગત +Name[he]=תוכן זמין +Name[hi]=उपलब्ध विषयवस्तु +Name[hr]=Dostupni sadržaj +Name[hu]=Elérhető tartalom +Name[ia]=Contento disponibile +Name[id]=Isi Tersedia +Name[is]=Aðgengilegt innihald +Name[it]=Contenuto disponibile +Name[ja]=利用可能なコンテンツ +Name[kk]=Бар мазмұны +Name[km]=មាតិកា​ដែល​អាច​ប្រើបាន +Name[kn]=ಲಭ್ಯವಿರುವ ವಿಷಯ +Name[ko]=사용 가능한 내용 +Name[lt]=Turimas turinys +Name[lv]=Pieejams saturs +Name[mai]=उपलब्ध सामग्री +Name[mk]=Достапна содржина +Name[ml]=ലഭ്യമായ ള്ളടക്കങ്ങള്‍ +Name[mr]=उपलब्ध मजकूर +Name[nb]=Tilgjengelig innhold +Name[nds]=Verföögbor Inholt +Name[nl]=Beschikbare inhoud +Name[nn]=Tilgjengeleg innhald +Name[pa]=ਉਪਲੱਬਧ ਸਮੱਗਰੀ +Name[pl]=Dostępna treść +Name[pt]=Conteúdo Disponível +Name[pt_BR]=Conteúdo disponível +Name[ro]=Conținut disponibil +Name[ru]=Содержимое +Name[si]=පවතින අන්තර්ගතය +Name[sk]=Dostupný obsah +Name[sl]=Razpoložljiva vsebina +Name[sr]=доступан садржај +Name[sr@ijekavian]=доступан садржај +Name[sr@ijekavianlatin]=dostupan sadržaj +Name[sr@latin]=dostupan sadržaj +Name[sv]=Tillgängligt innehåll +Name[tg]=Мазмуни дастрас +Name[th]=เนื้อหาที่มีอยู่ +Name[tr]=Kullanılabilir İçerik +Name[ug]=ئىشلەتكىلى بولىدىغان مەزمۇن +Name[uk]=Доступний вміст +Name[vi]=Nội dung hiện hữu +Name[wa]=Ådvins disponibe +Name[x-test]=xxAvailable Contentxx +Name[zh_CN]=可用内容 +Name[zh_TW]=可用的內容 + +[Desktop Action blank] +Name=Blank +Name[ar]=فارغ +Name[ast]=Baleru +Name[bg]=Празен диск +Name[bn]=ফাঁকা +Name[bs]=prazan +Name[ca]=En blanc +Name[ca@valencia]=En blanc +Name[cs]=Prázdné +Name[csb]=Czësti +Name[da]=Tom +Name[de]=Leer +Name[el]=Κενό +Name[en_GB]=Blank +Name[eo]=Malplena +Name[es]=En blanco +Name[et]=Tühi +Name[eu]=Hutsik +Name[fi]=Tyhjä +Name[fr]=Vide +Name[fy]=Leech +Name[ga]=Folamh +Name[gl]=Sen gravar +Name[gu]=ખાલી +Name[he]=ריק +Name[hi]=खाली +Name[hr]=Prazan +Name[hu]=Üres +Name[ia]=Vacue +Name[id]=Kosong +Name[is]=Tómur +Name[it]=Vuoto +Name[ja]=空 +Name[kk]=Бос +Name[km]=ទទេ +Name[kn]=ಖಾಲಿ +Name[ko]=비어 있음 +Name[lt]=Tuščias +Name[lv]=Tukšs +Name[mk]=Празен +Name[ml]=ശൂന്യം +Name[mr]=रिकामे +Name[nb]=Tom +Name[nds]=Leddig +Name[nl]=Blanco +Name[nn]=Tom +Name[pa]=ਖਾਲੀ +Name[pl]=Pusty +Name[pt]=Vazio +Name[pt_BR]=Vazio +Name[ro]=Gol +Name[ru]=Пустой +Name[si]=හිස් +Name[sk]=Prázdne +Name[sl]=Prazen +Name[sr]=празан +Name[sr@ijekavian]=празан +Name[sr@ijekavianlatin]=prazan +Name[sr@latin]=prazan +Name[sv]=Tom +Name[tg]=Холӣ +Name[th]=แผ่นเปล่า +Name[tr]=Boş +Name[ug]=بوش +Name[uk]=Порожньо +Name[vi]=Trống +Name[wa]=Vude +Name[x-test]=xxBlankxx +Name[zh_CN]=空 +Name[zh_TW]=空白 + +[Desktop Action capacity] +Name=Capacity +Name[ar]=السعة +Name[ast]=Capacidá +Name[bg]=Капацитет +Name[bn]=পরিমাপ +Name[bs]=kapacitet +Name[ca]=Capacitat +Name[ca@valencia]=Capacitat +Name[cs]=Kapacita +Name[csb]=Plac na diskù +Name[da]=Kapacitet +Name[de]=Kapazität +Name[el]=Χωρητικότητα +Name[en_GB]=Capacity +Name[eo]=Kapacito +Name[es]=Capacidad +Name[et]=Mahtuvus +Name[eu]=Edukiera +Name[fi]=Tilavuus +Name[fr]=Capacité +Name[fy]=kapisiteit +Name[ga]=Toilleadh +Name[gl]=Capacidade +Name[gu]=ક્ષમતા +Name[he]=קיבולת +Name[hi]=क्षमता +Name[hr]=Kapacitet +Name[hu]=Kapacitás +Name[ia]=Capacitate +Name[id]=Kapasitas +Name[is]=Rýmd +Name[it]=Capacità +Name[ja]=容量 +Name[ka]=მოცულობა +Name[kk]=Сыйымдылығы +Name[km]=សមត្ថភាព +Name[kn]=ಸಾಮರ್ಥ್ಯ +Name[ko]=용량 +Name[lt]=Galimybės +Name[lv]=Ietilpība +Name[mk]=Капацитет +Name[ml]=വലിപ്പം +Name[mr]=क्षमता +Name[nb]=Kapasitet +Name[nds]=Grött +Name[nl]=Capaciteit +Name[nn]=Kapasitet +Name[pa]=ਸਮਰੱਥਾ +Name[pl]=Pojemność +Name[pt]=Capacidade +Name[pt_BR]=Capacidade +Name[ro]=Capacitate +Name[ru]=Ёмкость +Name[si]=පරිමාව +Name[sk]=Kapacita +Name[sl]=Zmogljivost +Name[sr]=капацитет +Name[sr@ijekavian]=капацитет +Name[sr@ijekavianlatin]=kapacitet +Name[sr@latin]=kapacitet +Name[sv]=Kapacitet +Name[tg]=Audacity +Name[th]=ความจุ +Name[tr]=Kapasite +Name[ug]=سىغىمى +Name[uk]=Місткість +Name[vi]=Dung lượng +Name[wa]=Capacité +Name[x-test]=xxCapacityxx +Name[zh_CN]=容量 +Name[zh_TW]=空間 + +[Desktop Action discType] +Name=Disc Type +Name[ar]=نوع القرص +Name[ast]=Triba de discu +Name[bg]=Вид диск +Name[bn]=ডিস্ক ধরন +Name[bs]=tip diska +Name[ca]=Tipus de disc +Name[ca@valencia]=Tipus de disc +Name[cs]=Typ disku +Name[csb]=Ôrt diskù +Name[da]=Disktype +Name[de]=Disc-Typ +Name[el]=Τύπος δίσκου +Name[en_GB]=Disc Type +Name[eo]=Tipo de Disko +Name[es]=Tipo de disco +Name[et]=Plaadi tüüp +Name[eu]=Disko mota +Name[fi]=Levyn tyyppi +Name[fr]=Type de disque +Name[fy]=Skiif type +Name[ga]=Cineál an Diosca +Name[gl]=Tipo de disco +Name[gu]=ડિસ્ક પ્રકાર +Name[he]=סוג דיסק +Name[hi]=डिस्क प्रकार +Name[hr]=Tip diska +Name[hu]=Lemeztípus +Name[ia]=Typo disco +Name[id]=Tipe Cakram +Name[is]=Gerð disks +Name[it]=Tipo di disco +Name[ja]=ディスクのタイプ +Name[ka]=დისკის ტიპი +Name[kk]=Диск түрі +Name[km]=ប្រភេទ​ថាស +Name[kn]=ಡಿಸ್ಕಿನ ಬಗೆ +Name[ko]=디스크 종류 +Name[lt]=Disko tipas +Name[lv]=Tiska veids +Name[mai]=डिस्क प्रकार +Name[mk]=Тип на диск +Name[ml]=ഡിസ്കിന്റെ തരം +Name[mr]=डिस्क प्रकार +Name[nb]=Platetype +Name[nds]=Schiev-Typ +Name[nl]=Schijftype +Name[nn]=Disktype +Name[pa]=ਡਿਸਕ ਕਿਸਮ +Name[pl]=Typ dysku +Name[pt]=Tipo de Disco +Name[pt_BR]=Tipo de disco +Name[ro]=Tipul discului +Name[ru]=Тип диска +Name[si]=තැටි වර්ගය +Name[sk]=Typ disku +Name[sl]=Vrsta diska +Name[sr]=тип диска +Name[sr@ijekavian]=тип диска +Name[sr@ijekavianlatin]=tip diska +Name[sr@latin]=tip diska +Name[sv]=Skivtyp +Name[tg]=Намуди диск +Name[th]=ประเภทของแผ่นดิสก์ +Name[tr]=Disk Tipi +Name[ug]=دىسكا تىپى +Name[uk]=Тип диска +Name[vi]=Kiểu đĩa +Name[wa]=Sôre di plake +Name[x-test]=xxDisc Typexx +Name[zh_CN]=盘片类型 +Name[zh_TW]=磁碟型態 + +[Desktop Action fsType] +Name=Fs Type +Name[ar]=نوع نظام الملفات +Name[ast]=Triba de Fs +Name[bg]=Вид файлова система +Name[bn]=Fs ধরন +Name[bs]=tip fsis. +Name[ca]=Tipus de sistema de fitxers +Name[ca@valencia]=Tipus de sistema de fitxers +Name[cs]=Typ FS +Name[csb]=Ôrt Fs +Name[da]=FS-type +Name[de]=Dateisystemtyp +Name[el]=Τύπος συστήματος αρχείων +Name[en_GB]=Fs Type +Name[eo]=Dosiersistema Tipo +Name[es]=Tipo de s. a. +Name[et]=Failisüsteemi tüüp +Name[eu]=Fitxategi-sistema mota +Name[fi]=Tiedostojärjestelmän tyyppi +Name[fr]=Type de système de fichiers +Name[fy]=Fs type +Name[ga]=Cineál an Chórais Comhad +Name[gl]=Sistema de ficheiros +Name[gu]=Fs પ્રકાર +Name[he]=סוג מערכת קבצים +Name[hi]=Fs प्रकार +Name[hr]=Tip datotečnog sustava +Name[hu]=Fájlrendszer +Name[ia]=Typo Fs +Name[id]=Tipe Sistem Berkas +Name[is]=Tegund skráakerfis +Name[it]=Tipo di filesystem +Name[ja]=Fs タイプ +Name[kk]=ФЖ түрі +Name[km]=ប្រភេទ Fs +Name[kn]=Fs ಬಗೆ +Name[ko]=파일 시스템 종류 +Name[lt]=FS tipas +Name[lv]=FS tips +Name[mai]=Fs प्रकार +Name[mk]=Тип на дат. систем +Name[ml]=ഫയല്‍ വ്യവസ്ഥയുടെ തരം +Name[mr]=Fs प्रकार +Name[nb]=Filsystemtype +Name[nds]=Dateisysteem-Typ +Name[nl]=FS-type +Name[nn]=Filsystemtype +Name[pa]=Fs ਕਿਸਮ +Name[pl]=Typ systemu plików +Name[pt]=Tipo de SF +Name[pt_BR]=Tipo de sistema de arquivos +Name[ro]=Tipul SF +Name[ru]=Файловая система +Name[si]=Fs වර්ගය +Name[sk]=Typ FS +Name[sl]=Vrsta dat. sist. +Name[sr]=тип фсис. +Name[sr@ijekavian]=тип фсис. +Name[sr@ijekavianlatin]=tip fsis. +Name[sr@latin]=tip fsis. +Name[sv]=Filsystemtyp +Name[tg]=Намуди Fs +Name[th]=ประเภทของระบบแฟ้ม +Name[tr]=Dosya Sistemi Tipi +Name[ug]=ھۆججەت سىستېما تىپى +Name[uk]=Тип ФС +Name[vi]=Kiểu hệ thống tập tin +Name[wa]=Sôre di Fs +Name[x-test]=xxFs Typexx +Name[zh_CN]=文件系统类型 +Name[zh_TW]=檔案系統型態 + +[Desktop Action ignored] +Name=Ignored +Name[ar]=متجاهَل +Name[ast]=Inoráu +Name[bg]=Пренебрегнат +Name[bn]=উপেক্ষিত +Name[bs]=ignorisan +Name[ca]=Ignorat +Name[ca@valencia]=Ignorat +Name[cs]=Ignorováno +Name[csb]=Ignorowóné +Name[da]=Ignoreret +Name[de]=Ignoriert +Name[el]=Παράβλεψη +Name[en_GB]=Ignored +Name[eo]=Ignorita +Name[es]=Ignorado +Name[et]=Eiratav +Name[eu]=Ez ikusi eginda +Name[fi]=Ei otettu huomioon +Name[fr]=Ignoré +Name[fy]=Negearre +Name[ga]=Neamhaird Déanta De +Name[gl]=Ignorado +Name[gu]=અવગણેલ +Name[he]=התעלם +Name[hi]=उपेक्षित +Name[hr]=Zanemareno +Name[hu]=Nem kezelt +Name[ia]=Ignorate +Name[id]=Diabaikan +Name[is]=Hunsað +Name[it]=Ignorato +Name[ja]=無視 +Name[kk]=Еленбеген +Name[km]=បានមិនអើពើ +Name[kn]=ಆಲಕ್ಷಿತ +Name[ko]=무시됨 +Name[lt]=Ignoruota +Name[lv]=Ignorēts +Name[mk]=Игнорирано +Name[ml]=അവഗണിച്ചു +Name[mr]=उपेक्षित +Name[nb]=Ignorert +Name[nds]=Övergahn +Name[nl]=Genegeerd +Name[nn]=Oversett +Name[pa]=ਅਣਡਿੱਠ ਕੀਤਾ +Name[pl]=Ignorowany +Name[pt]=Ignorado +Name[pt_BR]=Ignorado +Name[ro]=Ignorat +Name[ru]=Игнорируется +Name[si]=නොතැකූ +Name[sk]=Ignorované +Name[sl]=Prezrto +Name[sr]=игнорисан +Name[sr@ijekavian]=игнорисан +Name[sr@ijekavianlatin]=ignorisan +Name[sr@latin]=ignorisan +Name[sv]=Ignorerad +Name[tg]=Радшуда +Name[th]=ไม่สนใจ +Name[tr]=Yoksayılmış +Name[ug]=پەرۋا قىلمىدى +Name[uk]=Ігнорується +Name[vi]=Bỏ qua +Name[wa]=Passé houte +Name[x-test]=xxIgnoredxx +Name[zh_CN]=已忽略 +Name[zh_TW]=忽略 + +[Desktop Action label] +Name=Label +Name[ar]=التسمية +Name[ast]=Etiqueta +Name[bg]=Етикет +Name[bn]=লেবেল +Name[bs]=etiketa +Name[ca]=Etiqueta +Name[ca@valencia]=Etiqueta +Name[cs]=Popisek +Name[csb]=Znakòwnik +Name[da]=Etiket +Name[de]=Beschriftung +Name[el]=Ετικέτα +Name[en_GB]=Label +Name[eo]=Labelo +Name[es]=Etiqueta +Name[et]=Pealdis +Name[eu]=Etiketa +Name[fa]=برچسب +Name[fi]=Nimike +Name[fr]=Étiquette +Name[fy]=Lebel +Name[ga]=Lipéad +Name[gl]=Etiqueta +Name[gu]=લેબલ +Name[he]=תוויות +Name[hi]=लेबल +Name[hr]=Natpis +Name[hu]=Címke +Name[ia]=Etiquetta +Name[id]=Label +Name[is]=Merking +Name[it]=Etichetta +Name[ja]=ラベル +Name[kk]=Тамғасы +Name[km]=ស្លាក +Name[kn]=ಗುರುತುಪಟ್ಟಿ +Name[ko]=레이블 +Name[lt]=Etiketė +Name[lv]=Etiķete +Name[mk]=Натпис +Name[ml]=ലേബല്‍ +Name[mr]=लेबल +Name[nb]=Etikett +Name[nds]=Beteker +Name[nl]=Label +Name[nn]=Merkelapp +Name[pa]=ਲੇਬਲ +Name[pl]=Etykieta +Name[pt]=Legenda +Name[pt_BR]=Rótulo +Name[ro]=Etichetă +Name[ru]=Метка +Name[si]=ලේබලය +Name[sk]=Štítok +Name[sl]=Oznaka +Name[sr]=етикета +Name[sr@ijekavian]=етикета +Name[sr@ijekavianlatin]=etiketa +Name[sr@latin]=etiketa +Name[sv]=Etikett +Name[tg]=Тамға +Name[th]=แถบป้าย +Name[tr]=Etiket +Name[ug]=ئەن +Name[uk]=Мітка +Name[vi]=Nhãn +Name[wa]=Etikete +Name[x-test]=xxLabelxx +Name[zh_CN]=标签 +Name[zh_TW]=標籤 + +[Desktop Action rewritable] +Name=Rewritable +Name[ar]=قابل للكتابة +Name[ast]=Regrabable +Name[bg]=Презаписваем диск +Name[bn]=আবার লেখা যাবে +Name[bs]=prebrisiv +Name[ca]=Regravable +Name[ca@valencia]=Regravable +Name[cs]=Přepisovatelný +Name[csb]=Wielorazowò zapisëwanlné +Name[da]=Genbrændbar +Name[de]=Wiederbeschreibbar +Name[el]=Επανεγγράψιμο +Name[en_GB]=Rewritable +Name[eo]=Re-skribitebla +Name[es]=Regrabable +Name[et]=Korduvkirjutatav +Name[eu]=Birgrabagarria +Name[fi]=Uudelleenkirjoitettavissa +Name[fr]=Réinscriptible +Name[fy]=Wer te beskriuwen +Name[ga]=In-Athscríofa +Name[gl]=Regravábel +Name[gu]=ફરી લખી શકાય તેવું +Name[he]=ניתן לכתיבה חוזרת +Name[hi]=फिर लिखनेयोग्य +Name[hr]=Prebrisiv +Name[hu]=Újraírható +Name[ia]=Que on pote scriber de nove +Name[id]=Dapat Ditulis Ulang +Name[is]=Endurskrifanlegt +Name[it]=Riscrivibile +Name[ja]=リライタブル +Name[kk]=Қайта жазылмалы +Name[km]=អាច​សរសេរ​បាន +Name[kn]=ಪುನಃ ಬರೆಯಬಹುದಾದ +Name[ko]=다시 쓸 수 있음 +Name[lt]=Perrašomas +Name[lv]=Pārrakstāms +Name[mai]=फेर लिखबा योग्य +Name[ml]=വീണ്ടും എഴുതാവുന്ന +Name[mr]=परत लिहिता येण्याजोगे +Name[nb]=Overskrivbar +Name[nds]=Wedderschriefbor +Name[nl]=Herschrijfbaar +Name[nn]=Omskrivbar +Name[pa]=ਮੁੜ-ਲਿਖਣਯੋਗ +Name[pl]=Z możliwością ponownego zapisu +Name[pt]=Regravável +Name[pt_BR]=Regravável +Name[ro]=Reinscriptibil +Name[ru]=Перезаписываемый +Name[si]=නැවත ලිවිය හැකි +Name[sk]=Prepisovateľné +Name[sl]=Prepisljiv +Name[sr]=пребрисив +Name[sr@ijekavian]=пребрисив +Name[sr@ijekavianlatin]=prebrisiv +Name[sr@latin]=prebrisiv +Name[sv]=Skrivbar +Name[tg]=Навишташаванда +Name[th]=สามารถเขียนใหม่ได้ +Name[tr]=Yeniden yazılabilir +Name[ug]=يېزىشقا بولىدىغان +Name[uk]=Перезапис +Name[wa]=Riscrijhåve +Name[x-test]=xxRewritablexx +Name[zh_CN]=可覆写 +Name[zh_TW]=可覆寫 + +[Desktop Action size] +Name=Size +Name[ar]=الحجم +Name[ast]=Tamañu +Name[bg]=Големина +Name[bn]=মাপ +Name[bs]=veličina +Name[ca]=Mida +Name[ca@valencia]=Mida +Name[cs]=Velikost +Name[csb]=Miara +Name[da]=Størrelse +Name[de]=Größe +Name[el]=Μέγεθος +Name[en_GB]=Size +Name[eo]=Grandeco +Name[es]=Tamaño +Name[et]=Suurus +Name[eu]=Neurria +Name[fa]=اندازه +Name[fi]=Koko +Name[fr]=Taille +Name[fy]=Grutte +Name[ga]=Méid +Name[gl]=Tamaño +Name[gu]=માપ +Name[he]=גודל +Name[hi]=आकार +Name[hr]=Veličina +Name[hu]=Méret +Name[ia]=Dimension +Name[id]=Ukuran +Name[is]=Stærð +Name[it]=Dimensione +Name[ja]=サイズ +Name[ka]=ზომა +Name[kk]=Көлемі +Name[km]=ទំហំ +Name[kn]=ಗಾತ್ರ +Name[ko]=크기 +Name[lt]=Dydis +Name[lv]=Izmērs +Name[mk]=Големина +Name[ml]=വലിപ്പം +Name[mr]=आकार +Name[nb]=Størrelse +Name[nds]=Grött +Name[nl]=Grootte +Name[nn]=Storleik +Name[pa]=ਸਾਈਜ਼ +Name[pl]=Rozmiar +Name[pt]=Tamanho +Name[pt_BR]=Tamanho +Name[ro]=Dimensiune +Name[ru]=Размер +Name[si]=ප්‍රමාණය +Name[sk]=Veľkosť +Name[sl]=Velikost +Name[sr]=величина +Name[sr@ijekavian]=величина +Name[sr@ijekavianlatin]=veličina +Name[sr@latin]=veličina +Name[sv]=Storlek +Name[tg]=Андоза +Name[th]=ขนาด +Name[tr]=Boyut +Name[ug]=چوڭلۇقى +Name[uk]=Розмір +Name[wa]=Grandeu +Name[x-test]=xxSizexx +Name[zh_CN]=大小 +Name[zh_TW]=大小 + +[Desktop Action usage] +Name=Usage +Name[ar]=الاستعمال +Name[ast]=Usu +Name[bg]=Използване +Name[bn]=ব্যবহার +Name[bs]=upotreba +Name[ca]=Ús +Name[ca@valencia]=Ús +Name[cs]=Použití +Name[csb]=Brëkòwóné +Name[da]=Brug +Name[de]=Verwendung +Name[el]=Χρήση +Name[en_GB]=Usage +Name[eo]=Uzado +Name[es]=Uso +Name[et]=Kasutus +Name[eu]=Erabilera +Name[fi]=Käyttötaso +Name[fr]=Usage +Name[fy]=Brûkens +Name[ga]=Úsáid +Name[gl]=Uso +Name[gu]=વપરાશ +Name[he]=שימוש +Name[hi]=उपयोग +Name[hr]=Iskorištenost +Name[hu]=Kihasználtság +Name[ia]=Usage +Name[id]=Penggunaan +Name[is]=Notkun +Name[it]=Uso +Name[ja]=使用率 +Name[ka]=გამოყენება +Name[kk]=Толуы +Name[km]=កា​រប្រើប្រាស់ +Name[kn]=ಬಳಕೆ +Name[ko]=사용량 +Name[lt]=Naudojimas +Name[lv]=Izlietojums +Name[mk]=Користење +Name[ml]=ഉപയോഗരീതി +Name[mr]=वापर +Name[nb]=Bruk +Name[nds]=Bruuk +Name[nl]=Gebruik +Name[nn]=Bruk +Name[pa]=ਵਰਤੋਂ +Name[pl]=Wykorzystanie +Name[pt]=Utilização +Name[pt_BR]=Uso +Name[ro]=Utilizare +Name[ru]=Использование +Name[si]=භාවිතය +Name[sk]=Použitie +Name[sl]=Poraba +Name[sr]=употреба +Name[sr@ijekavian]=употреба +Name[sr@ijekavianlatin]=upotreba +Name[sr@latin]=upotreba +Name[sv]=Användning +Name[tg]=Истифодабарӣ +Name[th]=วิธีใช้ +Name[tr]=Kullanım +Name[ug]=ئىشلىتىلىشى +Name[uk]=Використання +Name[wa]=Eployaedje +Name[x-test]=xxUsagexx +Name[zh_CN]=已用量 +Name[zh_TW]=使用量 + +[Desktop Action uuid] +Name=Uuid +Name[ar]=المعرف الفريد عالمياً (Uuid) +Name[ast]=Uuid +Name[bg]=Uuid +Name[bn]=Uuid +Name[bs]=UUID +Name[ca]=UUID +Name[ca@valencia]=UUID +Name[cs]=Uuid +Name[csb]=Uuid +Name[da]=Uuid +Name[de]=UUID +Name[el]=Uuid +Name[en_GB]=Uuid +Name[eo]=Uuid +Name[es]=Uuid +Name[et]=Uuid +Name[eu]=UUIDa +Name[fi]=Uuid +Name[fr]=Uuid +Name[fy]=Uuid +Name[ga]=Uuid +Name[gl]=Uuid +Name[gu]=Uuid +Name[he]=Uuid +Name[hi]=Uuid +Name[hr]=UUID +Name[hu]=UUID +Name[ia]=Uuid +Name[id]=Uuid +Name[is]=UUID +Name[it]=Uuid +Name[ja]=UUID +Name[ka]=Uuid +Name[kk]=Uuid +Name[km]=Uuid +Name[kn]=Uuid +Name[ko]=UUID +Name[lt]=Uuid +Name[lv]=Uuid +Name[mk]=Uuid +Name[ml]=യുയുഐഡി +Name[mr]=Uuid +Name[nb]=Uuid +Name[nds]=UUID +Name[nl]=Uuid +Name[nn]=UUID +Name[pa]=Uuid +Name[pl]=Uuid +Name[pt]=UUID +Name[pt_BR]=UUID +Name[ro]=Uuid +Name[ru]=UUID +Name[si]=Uuid +Name[sk]=Uuid +Name[sl]=UUID +Name[sr]=УУИД +Name[sr@ijekavian]=УУИД +Name[sr@ijekavianlatin]=UUID +Name[sr@latin]=UUID +Name[sv]=Uuid +Name[tg]=Phluid +Name[th]=ค่า Uuid +Name[tr]=Uuid +Name[ug]=Uuid +Name[uk]=Uuid +Name[wa]=Uuid +Name[x-test]=xxUuidxx +Name[zh_CN]=UUID +Name[zh_TW]=UUID + +[Desktop Entry] +Actions=appendable;availableContent;blank;capacity;discType;fsType;ignored;label;rewritable;size;usage;uuid; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=OpticalDisc diff --git a/solid-actions-kcm/device-actions/solid-device-OpticalDrive.desktop b/solid-actions-kcm/device-actions/solid-device-OpticalDrive.desktop new file mode 100644 index 00000000..edb85a19 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-OpticalDrive.desktop @@ -0,0 +1,723 @@ +[Desktop Action bus] +Name=Bus +Name[ar]=الناقل +Name[ast]=Bus +Name[bg]=Шина +Name[bn]=বাস +Name[bs]=magistrala +Name[ca]=Bus +Name[ca@valencia]=Bus +Name[cs]=Sběrnice +Name[csb]=Bus +Name[da]=Bus +Name[de]=Bus +Name[el]=Δίαυλος +Name[en_GB]=Bus +Name[eo]=Buso +Name[es]=Bus +Name[et]=Siin +Name[eu]=Busa +Name[fa]=گذرگاه +Name[fi]=Väylä +Name[fr]=Bus +Name[fy]=Bus +Name[ga]=Bus +Name[gl]=Bus +Name[gu]=બસ +Name[he]=אפיק +Name[hi]=बस +Name[hr]=Sabirnica +Name[hu]=Busz +Name[ia]=Bus +Name[id]=Bus +Name[is]=Rás (bus) +Name[it]=Bus +Name[ja]=バス +Name[ka]=სალტე +Name[kk]=Шинасы +Name[km]=ខ្សែបញ្ជូន +Name[kn]=ಬಸ್ +Name[ko]=버스 +Name[lt]=Magistralė +Name[lv]=Kopne +Name[mk]=Магистрала +Name[ml]=ബസ് +Name[mr]=बस +Name[nb]=Buss +Name[nds]=Bus +Name[nl]=Bus +Name[nn]=Buss +Name[pa]=ਬਸ +Name[pl]=Szyna +Name[pt]=Barramento +Name[pt_BR]=Barramento +Name[ro]=Magistrală +Name[ru]=Шина +Name[si]=Bus +Name[sk]=Zbernica +Name[sl]=Vodilo +Name[sr]=магистрала +Name[sr@ijekavian]=магистрала +Name[sr@ijekavianlatin]=magistrala +Name[sr@latin]=magistrala +Name[sv]=Buss +Name[tg]=Белоруссия +Name[th]=ระบบบัส +Name[tr]=Yol +Name[ug]=باش لىنىيە +Name[uk]=Шина +Name[wa]=Bus +Name[x-test]=xxBusxx +Name[zh_CN]=总线 +Name[zh_TW]=匯流排 + +[Desktop Action driveType] +Name=Drive Type +Name[ar]=نوع المشغل +Name[ast]=Triba de discu +Name[bg]=Вид устройство +Name[bn]=ড্রাইভ-এর ধরন +Name[bs]=tip jedinice +Name[ca]=Tipus d'unitat +Name[ca@valencia]=Tipus d'unitat +Name[cs]=Typ mechaniky +Name[csb]=Ôrt nëka +Name[da]=Drevtype +Name[de]=Laufwerkstyp +Name[el]=Τύπος οδηγού +Name[en_GB]=Drive Type +Name[eo]=Tipo de Diskingo +Name[es]=Tipo de disco +Name[et]=Seadme tüüp +Name[eu]=Unitate mota +Name[fi]=Asematyyppi +Name[fr]=Type de lecteur +Name[fy]=Stasjons type +Name[ga]=Cineál an Tiomántáin +Name[gl]=Tipo de dispositivo +Name[gu]=ડ્રાઇવ પ્રકાર +Name[he]=סוג כונן +Name[hi]=ड्राईव प्रकार +Name[hr]=Tip uređaja +Name[hu]=Meghajtótípus +Name[ia]=Typo de drive +Name[id]=Tipe Penggerak +Name[is]=Gerð drifs +Name[it]=Tipo di unità +Name[ja]=ドライブのタイプ +Name[ka]=ამძრავის ტიპი +Name[kk]=Жетек түрі +Name[km]=ប្រភេទ​ដ្រាយ +Name[kn]=ಡ್ರೈವಿನ ಬಗೆ +Name[ko]=드라이브 종류 +Name[lt]=Diskasukio tipas +Name[lv]=Dziņa tips +Name[mai]=ड्राइव प्रकार +Name[mk]=Тип на уред +Name[ml]=ഡ്രൈവിന്റെ തരം +Name[mr]=ड्राइव्ह प्रकार +Name[nb]=Drev-type +Name[nds]=Loopwark-Typ +Name[nl]=Apparaattype +Name[nn]=Einingstype +Name[pa]=ਡਰਾਇਵਰ ਕਿਸਮ +Name[pl]=Typ napędu +Name[pt]=Tipo de Unidade +Name[pt_BR]=Tipo de unidade +Name[ro]=Tip unitate +Name[ru]=Тип устройства +Name[si]=ධාවක වර්ගය +Name[sk]=Typ mechaniky +Name[sl]=Vrsta pogona +Name[sr]=тип јединице +Name[sr@ijekavian]=тип јединице +Name[sr@ijekavianlatin]=tip jedinice +Name[sr@latin]=tip jedinice +Name[sv]=Enhetstyp +Name[tg]=Намуди дастгоҳ +Name[th]=ประเภทของไดรฟ์ +Name[tr]=Sürücü Tipi +Name[ug]=قوزغاتقۇ تىپى +Name[uk]=Тип пристрою +Name[vi]=Kiểu trình điều khiển +Name[wa]=Sôre di lijheu +Name[x-test]=xxDrive Typexx +Name[zh_CN]=驱动类型 +Name[zh_TW]=磁碟型態 + +[Desktop Action hotpluggable] +Name=Hotpluggable +Name[ar]=قابل للتوصيل +Name[ast]=Conexón en caliente +Name[bn]=হট-প্লাগ-যোগ্য +Name[bs]=vruće uključiva +Name[ca]=Connectable en calent +Name[ca@valencia]=Connectable en calent +Name[cs]=Hotplug +Name[da]=Flytbar +Name[de]=Hotplug-fähig +Name[el]=Δυνατότητα Hotplug +Name[en_GB]=Hotpluggable +Name[eo]=Dumkure permutebla +Name[es]=Conexión en caliente +Name[et]=Töö ajal ühendatav +Name[eu]=Hotplug-erako gaitua +Name[fi]=Lennossakytkettävä +Name[fr]=Connectable à chaud +Name[fy]=Hotplug barren +Name[ga]=Inphlugáilte +Name[gl]=Conectábel en quente +Name[gu]=હોટપ્લગેબલ +Name[he]=החלפה חמה +Name[hi]=हाटप्लग योग्य +Name[hr]=Podržava brzo uštekavanje +Name[hu]=Menet közben csatlakoztatható +Name[ia]=Hotpluggable (On pote connecter lo con machina active) +Name[id]=Dapat di-Hotplug +Name[is]=Hraðtengjanlegt (hotplug) +Name[it]=Collegabile in marcia +Name[ja]=Hotplug 可能 +Name[kk]=Істеп турғанда қосылмалы +Name[km]=ដោតដើរ +Name[kn]=ಹಾಟ್‌ಪ್ಲಗ್‌ ಮಾಡಬಹುದಾದ +Name[ko]=핫플러그 가능 +Name[lt]=Greitai prijungiamas +Name[lv]=Karsti nomaināms +Name[ml]=ഹോട്ട്പ്ലഗ് ചെയ്യാവുന്ന +Name[mr]=हॉटप्लग करता येणारे +Name[nb]=Kan kobles til påslått +Name[nds]=Jümmers tokoppelbor +Name[nl]=Hotplugbaar +Name[nn]=Hotplug-kompatibel +Name[pa]=ਹਾਟਪਲੱਗਯੋਗ +Name[pl]=Podłączany "na gorąco" +Name[pt]=Conectável em Funcionamento +Name[pt_BR]=Conectável em funcionamento +Name[ro]=Detașabil +Name[ru]=Подключается в любое время +Name[si]=Hotpluggable +Name[sk]=Hotplug +Name[sl]=Priključljivo med delovanjem +Name[sr]=вруће укључива +Name[sr@ijekavian]=вруће укључива +Name[sr@ijekavianlatin]=vruće uključiva +Name[sr@latin]=vruće uključiva +Name[sv]=Inkopplingsbar +Name[tg]=Дастгоҳҳои пайвастшаванда +Name[th]=สามารถถอดเสียบได้ +Name[tr]=Çıkarılıp takılabilir +Name[ug]=ئىسسىق چېتىلىشچان +Name[uk]=«Гаряче» з’єднання +Name[vi]=Tháo lắp nóng +Name[wa]=Hotplugåve +Name[x-test]=xxHotpluggablexx +Name[zh_CN]=可热插拔 +Name[zh_TW]=可熱插拔 + +[Desktop Action readSpeed] +Name=Read Speed +Name[ar]=سرعة القراءة +Name[ast]=Velocidá de llectura +Name[bg]=Скорост на четене +Name[bn]=পড়ার গতি +Name[bs]=brzina čitanja +Name[ca]=Velocitat de lectura +Name[ca@valencia]=Velocitat de lectura +Name[cs]=Rychlost čtení +Name[csb]=Chùtkòsc czëtaniô +Name[da]=Læsehastighed +Name[de]=Lesegeschwindigkeit +Name[el]=Ταχύτητα ανάγνωσης +Name[en_GB]=Read Speed +Name[eo]=Leg-rapideco +Name[es]=Velocidad de lectura +Name[et]=Lugemiskiirus +Name[eu]=Irakurketa-abiadura +Name[fi]=Lukunopeus +Name[fr]=Vitesse de lecture +Name[fy]=Lês fluggens +Name[ga]=Luas Léite +Name[gl]=Velocidade de lectura +Name[gu]=લખવાની ઝડપ +Name[he]=מהירות קריאה +Name[hi]=पढ़ने की गति +Name[hr]=Brzina čitanja +Name[hu]=Olvasási sebesség +Name[ia]=Velocitate de lectura +Name[id]=Kecepatan Baca +Name[is]=Leshraði +Name[it]=Velocità in lettura +Name[ja]=読み取り速度 +Name[kk]=Оқу жылдамдығы +Name[km]=ល្បឿន​អាន +Name[kn]=ಓದುವ ವೇಗ +Name[ko]=읽기 속도 +Name[lt]=Skaitymo sparta +Name[lv]=Lasīšanas ātrums +Name[mk]=Брзина на читање +Name[ml]=വായനാ വേഗം +Name[mr]=वाचन वेग +Name[nb]=Lesehastighet +Name[nds]=Leesgauigkeit +Name[nl]=Leessnelheid +Name[nn]=Lesefart +Name[pa]=ਪੜ੍ਹਨ ਸਪੀਡ +Name[pl]=Szybkość odczytu +Name[pt]=Velocidade de Leitura +Name[pt_BR]=Velocidade de leitura +Name[ro]=Viteză de citire +Name[ru]=Скорость чтения +Name[si]=කියවුම් වේගය +Name[sk]=Rýchlosť čítania +Name[sl]=Hitrost branja +Name[sr]=брзина читања +Name[sr@ijekavian]=брзина читања +Name[sr@ijekavianlatin]=brzina čitanja +Name[sr@latin]=brzina čitanja +Name[sv]=Läshastighet +Name[tg]=Суръати хондан +Name[th]=ความเร็วในการอ่านข้อมูล +Name[tr]=Okuma hızı +Name[ug]=ئوقۇش تېزلىكى +Name[uk]=Швидкість читання +Name[wa]=Radisté d' lijhaedje +Name[x-test]=xxRead Speedxx +Name[zh_CN]=读取速度 +Name[zh_TW]=讀取速度 + +[Desktop Action removable] +Name=Removable +Name[ar]=قابل للإزالة +Name[ast]=Estrayible +Name[bg]=Преносим +Name[bn]=অপসারণযোগ্য +Name[bs]=uklonjiva +Name[ca]=Extraïble +Name[ca@valencia]=Extraïble +Name[cs]=Odpojitelný +Name[csb]=Przenosné +Name[da]=Flytbar +Name[de]=Wechselbar +Name[el]=Αφαιρούμενο μέσο +Name[en_GB]=Removable +Name[eo]=Demetebla +Name[es]=Extraíble +Name[et]=Eemaldatav +Name[eu]=Aldagarria +Name[fa]=جدا شدنی +Name[fi]=Poistettavissa +Name[fr]=Amovible +Name[fy]=Te ferwiderjen +Name[ga]=Inbhainte +Name[gl]=Eliminábel +Name[gu]=દૂર કરી શકાય તેવું +Name[he]=ניתן להסרה +Name[hi]=हटाने योग्य +Name[hr]=Moguće ga je izvaditi +Name[hu]=Cserélhető +Name[ia]=Removibile +Name[id]=Dapat Dilepaskan +Name[is]=Fjarlægjanlegt +Name[it]=Rimovibile +Name[ja]=リムーバブル +Name[kk]=Ауыстырмалы +Name[km]=អាច​យក​ចេញ​បាន +Name[kn]=ತೆಗೆಯಬಹುದಾದ +Name[ko]=제거 가능 +Name[lt]=Keičiamas +Name[lv]=Noņemams +Name[mai]=हटबैयोग्य +Name[mk]=Подвижен +Name[ml]=നീക്കം ചെയ്യാവുന്ന +Name[mr]=काढता येणारे +Name[nb]=Flyttbar +Name[nds]=Tuuschbor +Name[nl]=Verwijderbaar +Name[nn]=Flyttbar +Name[pa]=ਹਟਾਉਣਯੋਗ +Name[pl]=Wymienny +Name[pt]=Removível +Name[pt_BR]=Removível +Name[ro]=Amovibil +Name[ru]=Сменный носитель +Name[si]=ඉවත්කල හැකි +Name[sk]=Vymeniteľné +Name[sl]=Odstranljivo +Name[sr]=уклоњива +Name[sr@ijekavian]=уклоњива +Name[sr@ijekavianlatin]=uklonjiva +Name[sr@latin]=uklonjiva +Name[sv]=Flyttbar +Name[tg]=Дастгоҳи ҷудошаванда +Name[th]=ถอดเสียบได้ +Name[tr]=Çıkarılabilir +Name[ug]=كۆچمە +Name[uk]=Змінний пристрій +Name[wa]=Bodjåve +Name[x-test]=xxRemovablexx +Name[zh_CN]=移动 +Name[zh_TW]=可移除 + +[Desktop Action size] +Name=Size +Name[ar]=الحجم +Name[ast]=Tamañu +Name[bg]=Големина +Name[bn]=মাপ +Name[bs]=veličina +Name[ca]=Mida +Name[ca@valencia]=Mida +Name[cs]=Velikost +Name[csb]=Miara +Name[da]=Størrelse +Name[de]=Größe +Name[el]=Μέγεθος +Name[en_GB]=Size +Name[eo]=Grandeco +Name[es]=Tamaño +Name[et]=Suurus +Name[eu]=Neurria +Name[fa]=اندازه +Name[fi]=Koko +Name[fr]=Taille +Name[fy]=Grutte +Name[ga]=Méid +Name[gl]=Tamaño +Name[gu]=માપ +Name[he]=גודל +Name[hi]=आकार +Name[hr]=Veličina +Name[hu]=Méret +Name[ia]=Dimension +Name[id]=Ukuran +Name[is]=Stærð +Name[it]=Dimensione +Name[ja]=サイズ +Name[ka]=ზომა +Name[kk]=Көлемі +Name[km]=ទំហំ +Name[kn]=ಗಾತ್ರ +Name[ko]=크기 +Name[lt]=Dydis +Name[lv]=Izmērs +Name[mk]=Големина +Name[ml]=വലിപ്പം +Name[mr]=आकार +Name[nb]=Størrelse +Name[nds]=Grött +Name[nl]=Grootte +Name[nn]=Storleik +Name[pa]=ਸਾਈਜ਼ +Name[pl]=Rozmiar +Name[pt]=Tamanho +Name[pt_BR]=Tamanho +Name[ro]=Dimensiune +Name[ru]=Размер +Name[si]=ප්‍රමාණය +Name[sk]=Veľkosť +Name[sl]=Velikost +Name[sr]=величина +Name[sr@ijekavian]=величина +Name[sr@ijekavianlatin]=veličina +Name[sr@latin]=veličina +Name[sv]=Storlek +Name[tg]=Андоза +Name[th]=ขนาด +Name[tr]=Boyut +Name[ug]=چوڭلۇقى +Name[uk]=Розмір +Name[wa]=Grandeu +Name[x-test]=xxSizexx +Name[zh_CN]=大小 +Name[zh_TW]=大小 + +[Desktop Action supportedMedia] +Name=Supported Media +Name[ar]=الوسائط المدعومة +Name[ast]=Medios sofitaos +Name[bg]=Поддържана медия +Name[bn]=সমর্থিত মিডিয়া +Name[bs]=podržani medijumi +Name[ca]=Suports acceptats +Name[ca@valencia]=Suports acceptats +Name[cs]=Podporovaná média +Name[csb]=Wspiéróné media +Name[da]=Understøttede medier +Name[de]=Unterstützte Medien +Name[el]=Υποστηριζόμενα μέσα +Name[en_GB]=Supported Media +Name[eo]=subtenataj Aŭdvidaĵoj +Name[es]=Medios soportados +Name[et]=Toetatud meedia +Name[eu]=Onartzen diren euskarriak +Name[fi]=Tuetut mediat +Name[fr]=Média pris en charge +Name[fy]=Stipe media +Name[ga]=Meáin a dTacaítear Leo +Name[gl]=Medios soportados +Name[gu]=આધારિત મિડીઆ +Name[he]=מדיה נתמכת +Name[hi]=समर्थित मीडिया +Name[hr]=Podržani mediji +Name[hu]=Támogatott média +Name[ia]=Media supportate +Name[id]=Media Didukung +Name[is]=Studdir miðlar +Name[it]=Dispositivi supportati +Name[ja]=サポートされているメディア +Name[kk]=Тасушысы +Name[km]=មេឌៀ​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಮಾಧ್ಯಮ +Name[ko]=지원하는 미디어 +Name[lt]=Palaikomi media tipai +Name[lv]=Atbalstītie datu nesēji +Name[mai]=समर्थित मीडिआ +Name[mk]=Поддржани медиуми +Name[ml]=പിന്തുണയുള്ള മാദ്ധ്യമം +Name[mr]=समर्थीत मीडिया +Name[nb]=Støttede medier +Name[nds]=Ünnerstütt Schieven +Name[nl]=Ondersteunde media +Name[nn]=Støtta medium +Name[pa]=ਸਹਾਇਕ ਮੀਡਿਆ +Name[pl]=Obsługiwane nośniki +Name[pt]=Discos Suportados +Name[pt_BR]=Mídia suportada +Name[ro]=Mediu susținut +Name[ru]=Поддерживаемые носители +Name[si]=සහාය දක්වන මාධ්‍යය +Name[sk]=Podporované médiá +Name[sl]=Podprti nosilci +Name[sr]=подржани медијуми +Name[sr@ijekavian]=подржани медијуми +Name[sr@ijekavianlatin]=podržani medijumi +Name[sr@latin]=podržani medijumi +Name[sv]=Media som stöds +Name[tg]=Медиаи мувофиқ +Name[th]=สื่อที่รองรับ +Name[tr]=Desteklenen Ortam +Name[ug]=قوللايدىغان ۋاسىتىلەر +Name[uk]=Підтримувані носії +Name[wa]=Media sopoirté +Name[x-test]=xxSupported Mediaxx +Name[zh_CN]=支持的媒体 +Name[zh_TW]=支援的媒體 + +[Desktop Action writeSpeed] +Name=Write Speed +Name[ar]=سرعة الكتابة +Name[ast]=Velocidá d'escritura +Name[bg]=Скорост на запис +Name[bn]=লেখার গতি +Name[bs]=brzina pisanja +Name[ca]=Velocitat d'escriptura +Name[ca@valencia]=Velocitat d'escriptura +Name[cs]=Rychlost zápisu +Name[csb]=Chùtkòsc pisaniô +Name[da]=Brændehastighed +Name[de]=Schreibgeschwindigkeit +Name[el]=Ταχύτητα εγγραφής +Name[en_GB]=Write Speed +Name[eo]=Skribrapideco +Name[es]=Velocidad de escritura +Name[et]=Kirjutamiskiirus +Name[eu]=Idazketa-abiadura +Name[fi]=Kirjoitusnopeus +Name[fr]=Vitesse d'écriture +Name[fy]=Skriuw fluggens +Name[ga]=Luas Scríofa +Name[gl]=Velocidade de gravación +Name[gu]=લખવાની ઝડપ +Name[he]=מהירות כתיבה +Name[hi]=लेखन गति +Name[hr]=Brzina pisanja +Name[hu]=Írási sebesség +Name[ia]=Velocitate de scriptura +Name[id]=Kecepatan Tulis +Name[is]=Skrifhraði +Name[it]=Velocità in scrittura +Name[ja]=書き込み速度 +Name[ka]=ჩაწერის სიჩქარე +Name[kk]=Жазу жылдамдығы +Name[km]=ល្បឿនសរសេរ +Name[kn]=ಬರೆಯುವ ವೇಗ +Name[ko]=쓰기 속도 +Name[lt]=Rašymo greitis +Name[lv]=Rakstīšanas ātrums +Name[mai]=लेखन गति +Name[mk]=Брзина на запишување +Name[ml]=എഴുത്തിന്റെ വേഗത +Name[mr]=लिखाण वेग +Name[nb]=Skrivehastighet +Name[nds]=Schriev-Gauigkeit +Name[nl]=Schrijfsnelheid +Name[nn]=Skrivefart +Name[pa]=ਲਿਖਣ ਸਪੀਡ +Name[pl]=Szybkość zapisu +Name[pt]=Velocidade de Gravação +Name[pt_BR]=Velocidade de gravação +Name[ro]=Viteză de scriere +Name[ru]=Скорость записи +Name[si]=ලිවීම් වේගය +Name[sk]=Rýchlosť zápisu +Name[sl]=Hitrost zapisovanja +Name[sr]=брзина писања +Name[sr@ijekavian]=брзина писања +Name[sr@ijekavianlatin]=brzina pisanja +Name[sr@latin]=brzina pisanja +Name[sv]=Skrivhastighet +Name[tg]=Суръати навиштан +Name[th]=ความเร็วในการเขียนข้อมูล +Name[tr]=Yazma Hızı +Name[ug]=يېزىش تېزلىكى +Name[uk]=Швидкість запису +Name[wa]=Radisté d' sicrijhaedje +Name[x-test]=xxWrite Speedxx +Name[zh_CN]=写入速度 +Name[zh_TW]=寫入速度 + +[Desktop Action writeSpeeds] +Name=Write Speeds +Name[ar]=سرعات الكتابة +Name[ast]=Velocidaes d'escritura +Name[bg]=Скорости на запис +Name[bn]=লেখার গতি +Name[bs]=brzine pisanja +Name[ca]=Velocitats d'escriptura +Name[ca@valencia]=Velocitats d'escriptura +Name[cs]=Rychlosti zápisu +Name[csb]=Chùtkòscë pisaniô +Name[da]=Brændehastigheder +Name[de]=Schreibgeschwindigkeiten +Name[el]=Ταχύτητες εγγραφής +Name[en_GB]=Write Speeds +Name[eo]=Skribrapidecoj +Name[es]=Velocidades de escritura +Name[et]=Kirjutamiskiirus +Name[eu]=Idazketa-abiadurak +Name[fi]=Kirjoitusnopeudet +Name[fr]=Vitesses d'écriture +Name[fy]=Skriuw fluggens +Name[ga]=Luasanna Scríofa +Name[gl]=Velocidades de gravación +Name[gu]=લખવાની ઝડપો +Name[he]=מהירויות כתיבה +Name[hi]=लेखन गतियाँ +Name[hr]=Brzine pisanja +Name[hu]=Írási sebességek +Name[ia]=Velocitates de scriptura +Name[id]=Kecepatan Tulis +Name[is]=Skrifhraðar +Name[it]=Velocità in scrittura +Name[ja]=書き込み速度 +Name[ka]=ჩაწერის სიჩქარეები +Name[kk]=Жазу жылдамдықтары +Name[km]=ល្បឿន​សរសេរ +Name[kn]=ಬರೆಯುವ ವೇಗಗಳು +Name[ko]=지원하는 쓰기 속도 +Name[lt]=Rašymo greičiai +Name[lv]=Rakstīšanas ātrumi +Name[mai]=लेखन गति +Name[mk]=Брзини на запишување +Name[ml]=എഴുത്തിന്റെ വേഗതകള്‍ +Name[mr]=लिखाण वेग +Name[nb]=Skrivehastigheter +Name[nds]=Schriev-Gauigkeiten +Name[nl]=Schrijfsnelheden +Name[nn]=Skrivefartar +Name[pa]=ਲਿਖਣ ਸਪੀਡ +Name[pl]=Szybkości zapisu +Name[pt]=Velocidades de Gravação +Name[pt_BR]=Velocidades de gravação +Name[ro]=Viteze de scriere +Name[ru]=Скорости записи +Name[si]=ලිවීම් වේග +Name[sk]=Rýchlosti zápisu +Name[sl]=Hitrosti zapisovanja +Name[sr]=брзине писања +Name[sr@ijekavian]=брзине писања +Name[sr@ijekavianlatin]=brzine pisanja +Name[sr@latin]=brzine pisanja +Name[sv]=Skrivhastigheter +Name[tg]=Суръатҳои навиштан +Name[th]=ความเร็วในการเขียนข้อมูล +Name[tr]=yazma Hızları +Name[ug]=يېزىش تېزلىكى +Name[uk]=Швидкості запису +Name[wa]=Radistés d' sicrijhaedje +Name[x-test]=xxWrite Speedsxx +Name[zh_CN]=写入速度 +Name[zh_TW]=寫入速度 + +[Desktop Entry] +Actions=bus;driveType;hotpluggable;readSpeed;removable;size;supportedMedia;writeSpeed;writeSpeeds; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=OpticalDrive diff --git a/solid-actions-kcm/device-actions/solid-device-PortableMediaPlayer.desktop b/solid-actions-kcm/device-actions/solid-device-PortableMediaPlayer.desktop new file mode 100644 index 00000000..16702027 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-PortableMediaPlayer.desktop @@ -0,0 +1,215 @@ +[Desktop Action supportedDrivers] +Name=Supported Drivers +Name[ar]=المشغلات المدعومة +Name[ast]=Controladores sofitaos +Name[bg]=Поддържани драйвери +Name[bn]=সমর্থিত ড্রাইভার +Name[bs]=podržani drajveri +Name[ca]=Controladors acceptats +Name[ca@valencia]=Controladors acceptats +Name[cs]=Podporované ovladače +Name[csb]=Wspiéróné czérowniczi +Name[da]=Understøttede drivere +Name[de]=Unterstützte Treiber +Name[el]=Υποστηριζόμενοι οδηγοί +Name[en_GB]=Supported Drivers +Name[eo]=subtenataj Peliloj +Name[es]=Dispositivos soportados +Name[et]=Toetatud draiverid +Name[eu]=Onartutzen diren gidariak +Name[fi]=Tuetut ajurit +Name[fr]=Pilotes pris en charge +Name[fy]=Stipe stjoerprogramma's +Name[ga]=Tiománaithe a dTacaítear Leo +Name[gl]=Controladores soportados +Name[gu]=આધારિત ડ્રાઇવરો +Name[he]=מנהלי התקנים נתמכים +Name[hi]=समर्थित ड्राईवर +Name[hr]=Podržani pisači +Name[hu]=Támogatott meghajtók +Name[ia]=Drivers supportate +Name[id]=Penggerak Didukung +Name[is]=Studdir reklar +Name[it]=Driver supportati +Name[ja]=サポートされているドライバ +Name[kk]=Қолдайтын драйверлері +Name[km]=កម្មវិធី​បញ្ជា​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಚಾಲಕಗಳು +Name[ko]=지원하는 드라이버 +Name[lt]=Palaikomos tvarkyklės +Name[lv]=Atbalstītie draiveri +Name[mai]=समर्थित ड्राइवर +Name[mk]=Поддржани управувачи +Name[ml]=പിന്തുണയുള്ള സാരഥികള്‍ +Name[mr]=समर्थीत ड्राइव्हर्स +Name[nb]=Støttede drivere +Name[nds]=Ünnerstütt Drievers +Name[nl]=Ondersteunde stuurprogramma's +Name[nn]=Støtta drivarar +Name[pa]=ਸਹਾਇਕ ਡਰਾਇਵਰ +Name[pl]=Obsługiwane sterowniki +Name[pt]=Controladores Suportados +Name[pt_BR]=Drivers suportados +Name[ro]=Drivere susținute +Name[ru]=Поддерживаемые драйверы +Name[si]=සහාය දක්වන ධාවක +Name[sk]=Podporované ovládače +Name[sl]=Podprti gonilniki +Name[sr]=подржани драјвери +Name[sr@ijekavian]=подржани драјвери +Name[sr@ijekavianlatin]=podržani drajveri +Name[sr@latin]=podržani drajveri +Name[sv]=Drivrutiner som stöds +Name[tg]=Дастгоҳҳои мувофиқ +Name[th]=ไดรเวอร์ที่รองรับ +Name[tr]=Desteklenen Sürücüler +Name[ug]=قوللايدىغان قوزغاتقۇلار +Name[uk]=Підтримувані драйвери +Name[wa]=Mineus sopoirtés +Name[x-test]=xxSupported Driversxx +Name[zh_CN]=支持的驱动 +Name[zh_TW]=支援的驅動程式 + +[Desktop Action supportedProtocols] +Name=Supported Protocols +Name[ar]=البروتوكولات المدعومة +Name[ast]=Protocolos sofitaos +Name[bg]=Поддържани протоколи +Name[bn]=সমর্থিত প্রোটোকল +Name[bs]=podržani protokoli +Name[ca]=Protocols acceptats +Name[ca@valencia]=Protocols acceptats +Name[cs]=Podporované protokoly +Name[csb]=Wspiéróné protokòłë +Name[da]=Understøttede protokoller +Name[de]=Unterstützte Protokolle +Name[el]=Υποστηριζόμενα πρωτόκολλα +Name[en_GB]=Supported Protocols +Name[eo]=Subtenitaj Protokoloj +Name[es]=Protocolos soportados +Name[et]=Toetatud protokollid +Name[eu]=Onartzen diren protokoloak +Name[fi]=Tuetut yhteyskäytännöt +Name[fr]=Protocoles pris en charge +Name[fy]=Stipe protokollen +Name[ga]=Prótacail a dTacaítear Leo +Name[gl]=Protocolos soportados +Name[gu]=આધારિત પ્રોટોકોલ્સ +Name[he]=פרוטוקולים נתמכים +Name[hi]=समर्थित प्रोटोकॉल +Name[hr]=Podržani Protokoli +Name[hu]=Támogatott protokollok +Name[ia]=Protocollos supportate +Name[id]=Protokol Didukung +Name[is]=Studdar samskiptareglur +Name[it]=Protocolli supportati +Name[ja]=サポートされているプロトコル +Name[kk]=Қолдайтын протоколдары +Name[km]=ពិពីការ​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಪ್ರಕ್ರಮಗಳು (ಪ್ರೋಟೋಕಾಲ್) +Name[ko]=지원하는 프로토콜 +Name[lt]=Palaikomi protokolai +Name[lv]=Atbalstītie protokoli +Name[mk]=Поддржани протоколи +Name[ml]=പിന്തുണയ്ക്കുന്ന സമ്പ്രദായങ്ങള്‍ +Name[mr]=समर्थीत शिष्टाचार +Name[nb]=Støttede protokoller +Name[nds]=Ünnerstütt Protokollen +Name[nl]=Ondersteunde protocollen +Name[nn]=Støtta protokollar +Name[pa]=ਸਹਾਇਕ ਪਰੋਟੋਕਾਲ +Name[pl]=Obsługiwane protokoły +Name[pt]=Protocolos Suportados +Name[pt_BR]=Protocolos suportados +Name[ro]=Protocoale susținute +Name[ru]=Поддерживаемые протоколы +Name[si]=සහාය දක්වන ක්‍රියා පටිපාටි +Name[sk]=Podporované protokoly +Name[sl]=Podprti protokoli +Name[sr]=подржани протоколи +Name[sr@ijekavian]=подржани протоколи +Name[sr@ijekavianlatin]=podržani protokoli +Name[sr@latin]=podržani protokoli +Name[sv]=Protokoll som stöds +Name[tg]=Протоколҳо +Name[th]=โพรโทคอลที่รองรับ +Name[tr]=Desteklenen Protokoller +Name[ug]=قوللايدىغان كېلىشىملەر +Name[uk]=Підтримувані протоколи +Name[wa]=Protocoles sopoirtés +Name[x-test]=xxSupported Protocolsxx +Name[zh_CN]=支持的协议 +Name[zh_TW]=支援的協定 + +[Desktop Entry] +Actions=supportedDrivers;supportedProtocols; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=PortableMediaPlayer diff --git a/solid-actions-kcm/device-actions/solid-device-Processor.desktop b/solid-actions-kcm/device-actions/solid-device-Processor.desktop new file mode 100644 index 00000000..550b4671 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Processor.desktop @@ -0,0 +1,355 @@ +[Desktop Action canChangeFrequency] +Name=Can Change Frequency +Name[ar]=يمكنه تغير التردد +Name[ast]=Pues camudar la frecuencia +Name[bg]=Може да променя честотата +Name[bn]=কম্পাঙ্ক বদলাতে পারে +Name[bs]=može da mijenja takt +Name[ca]=Pot canviar la freqüència +Name[ca@valencia]=Pot canviar la freqüència +Name[cs]=Může měnit frekvenci +Name[da]=Kan skifte frekvens +Name[de]=Kann die Frequenz wechseln +Name[el]=Δυνατότητα αλλαγής συχνότητας +Name[en_GB]=Can Change Frequency +Name[es]=Puede cambiar la frecuencia +Name[et]=Muudetava sagedusega +Name[eu]=Maiztasuna alda daiteke +Name[fi]=Osaa vaihtaa taajuutta +Name[fr]=Fréquence modifiable +Name[fy]=Kin frekwinsje feroarje +Name[ga]=Is Féidir Minicíocht a Athrú +Name[gl]=Pode mudar a frecuencia +Name[gu]=આવૃત્તિ બદલી શકે છે +Name[he]=יכול לשנות תדירות +Name[hi]=आवृत्ति बदल सकता है +Name[hr]=Može mijenjati frekvenciju +Name[hu]=Frekvenciaváltás lehetséges +Name[ia]=Il pote cambiar frequentia +Name[id]=Dapat Mengubah Frekuensi +Name[is]=Getur breytt tíðni +Name[it]=Può cambiare frequenza +Name[ja]=周波数の変更が可能 +Name[kk]=Жиілігі өзгермелі +Name[km]=អាច​ផ្លាស់ប្ដូរ​ប្រេកង់​ +Name[kn]=ಕಂಪನ ದರ(frequency) ವನ್ನು ಬದಲಾಯಿಸಬಹುದು +Name[ko]=주파수 변경 가능 +Name[lt]=Gali leisti dažnumą +Name[lv]=Var mainīt frekvenci +Name[mai]=आवृति बदलि सकैत अछि +Name[mk]=Може да смени фреквенција +Name[ml]=ആവര്‍ത്തി മാറ്റാവുന്നത് +Name[mr]=फ्रिक्वेन्सी बदलू शकतो +Name[nb]=Kan endre frekvens +Name[nds]=Kann Frequenz wesseln +Name[nl]=Kan de frequentie wijzigen +Name[nn]=Frekvens som kan endrast +Name[pa]=ਫਰੀਕਿਊਂਸੀ ਬਦਲੀ ਜਾ ਸਕਦੀ ਹੈ +Name[pl]=Z możliwością zmiany częstotliwości +Name[pt]=Pode Variar a Frequência +Name[pt_BR]=Pode alterar a frequência +Name[ro]=Poate schimba frecvența +Name[ru]=Возможность изменения частоты +Name[si]=සංඛ්‍යාතය වෙනස් කල හැක +Name[sk]=Môže meniť frekvenciu +Name[sl]=Lahko spreminja hitrost +Name[sr]=може да мења такт +Name[sr@ijekavian]=може да мијења такт +Name[sr@ijekavianlatin]=može da mijenja takt +Name[sr@latin]=može da menja takt +Name[sv]=Kan ändra frekvens +Name[th]=สามารถเปลี่ยนความถี่ได้ +Name[tr]=Frekansı Değiştirilebilir +Name[ug]=چاستوتىسىنى ئۆزگەرتكىلى بولىدۇ +Name[uk]=Може змінювати частоту +Name[vi]=Có thể thay đổi tần số +Name[wa]=Sait candjî d frecwince +Name[x-test]=xxCan Change Frequencyxx +Name[zh_CN]=可更改频率 +Name[zh_TW]=可變更頻率 + +[Desktop Action instructionSets] +Name=Instruction Sets +Name[ar]=مجموعة الأوامر +Name[ast]=Conxuntu d'instrucciones +Name[bg]=Набор инструкции +Name[bn]=ইনস্ট্রাকশন সেট +Name[bs]=skup instrukcija +Name[ca]=Jocs d'instruccions +Name[ca@valencia]=Jocs d'instruccions +Name[cs]=Instrukční sady +Name[da]=Instruktionssæt +Name[de]=Instruktions-Sätze +Name[el]=Σύνολα εντολών +Name[en_GB]=Instruction Sets +Name[es]=Conjunto de instrucciones +Name[et]=Käsustikud +Name[eu]=Instrukzio sortak +Name[fi]=Käskyjoukko +Name[fr]=Jeux d'instructions +Name[fy]=Ynstruksje set +Name[ga]=Tacair Treoracha +Name[gl]=Xogo de instrucións +Name[gu]=સૂચના સમૂહો +Name[he]=אוסף פקודות +Name[hi]=अनुदेश सेट +Name[hr]=Instrukcijski skup +Name[hu]=Utasításkészletek +Name[ia]=Insimules de instruction +Name[id]=Perangkat Instruksi +Name[is]=Inntaksaðgerðir (instruction sets) +Name[it]=Serie di istruzioni +Name[ja]=命令セット +Name[kk]=Нұсқаулар жиыны +Name[km]=សំណុំ​សេចក្ដី​ណែនាំ +Name[kn]=ಸೂಚನೆಗಳು +Name[ko]=명령어 집합 +Name[lt]=Instrukcijų rinkiniai +Name[lv]=Instrukciju kopas +Name[mk]=Инструкциски множества +Name[ml]=നിര്‍ദ്ദേശ ഗണം +Name[mr]=आज्ञा संच +Name[nb]=Instruksjonssett +Name[nds]=Anwiesen-Setten +Name[nl]=Instructiesets +Name[nn]=Instruksjonssett +Name[pa]=ਹਦਾਇਤ ਸੈੱਟ +Name[pl]=Zestawy instrukcji +Name[pt]=Conjuntos de Instruções +Name[pt_BR]=Conjuntos de instruções +Name[ro]=Seturi de instrucțiuni +Name[ru]=Наборы команд +Name[si]=උපදෙස් මාලා +Name[sk]=Inštrukčné sady +Name[sl]=Nabori ukazov +Name[sr]=скуп инструкција +Name[sr@ijekavian]=скуп инструкција +Name[sr@ijekavianlatin]=skup instrukcija +Name[sr@latin]=skup instrukcija +Name[sv]=Instruktionsuppsättningar +Name[tg]=Тарзи вуруд +Name[th]=ชุดคำสั่งต่าง ๆ +Name[tr]=Yönerge Ayarları +Name[ug]=پەرمان توپلىمى +Name[uk]=Набори команд +Name[vi]=Tập lệnh +Name[wa]=Djeus d' instruccion +Name[x-test]=xxInstruction Setsxx +Name[zh_CN]=指令集 +Name[zh_TW]=指令集 + +[Desktop Action maxSpeed] +Name=Max Speed +Name[ar]=السرعة القصوى +Name[ast]=Velocidá máx. +Name[bg]=Макс. скорост +Name[bn]=সর্বোচ্চ গতি +Name[bs]=najveća brzina +Name[ca]=Velocitat màxima +Name[ca@valencia]=Velocitat màxima +Name[cs]=Maximální rychlost +Name[csb]=Maksymalnô chùtkòsc +Name[da]=Maks. hastighed +Name[de]=Maximalgeschwindigkeit +Name[el]=Μέγιστη ταχύτητα +Name[en_GB]=Max Speed +Name[eo]=Maksimuma Rapideco +Name[es]=Velocidad máx. +Name[et]=Maks. kiirus +Name[eu]=Gehienezko abiadura +Name[fi]=Enimmäisnopeus +Name[fr]=Vitesse maximale +Name[fy]=Maks. fluggens +Name[ga]=Uasluas +Name[gl]=Velocidade máxima +Name[gu]=મહત્તમ ઝડપ +Name[he]=מהירות מירבית +Name[hi]=अधिकतम गति +Name[hr]=Maksimalna brzina +Name[hu]=Max. sebesség +Name[ia]=Velocitate maxime +Name[id]=Kecepatan Maks +Name[is]=Mesti hraði +Name[it]=Velocità massima +Name[ja]=最大速度 +Name[ka]=მაქს. სიჩქარე +Name[kk]=Жылдамдығының шегі +Name[km]=ល្បឿន​អតិបរមា +Name[kn]=ಗರಿಷ್ಟ ವೇಗ +Name[ko]=최대 속도 +Name[lt]=Maksimalus greitis +Name[lv]=Maks ātrums +Name[mk]=Maкc. брзина +Name[ml]=കൂടിയ വേഗം +Name[mr]=कमाल वेग +Name[nb]=Maks. hastighet +Name[nds]=Hööchst Gauigkeit +Name[nl]=Maximale snelheid +Name[nn]=Maksfart +Name[pa]=ਵੱਧੋ-ਵੱਧ ਸਪੀਡ +Name[pl]=Maksymalna szybkość +Name[pt]=Velocidade Máxima +Name[pt_BR]=Velocidade máxima +Name[ro]=Viteză maximă +Name[ru]=Максимальная скорость +Name[si]=උපරිම වේගය +Name[sk]=Maximálna rýchlosť +Name[sl]=Največja hitrost +Name[sr]=највећа брзина +Name[sr@ijekavian]=највећа брзина +Name[sr@ijekavianlatin]=najveća brzina +Name[sr@latin]=najveća brzina +Name[sv]=Maximal hastighet +Name[tg]=Суръати тезтарин +Name[th]=ความเร็วสูงสุด +Name[tr]=En Yüksek Hız +Name[ug]=ئەڭ چوڭ تېزلىك +Name[uk]=Макс. швидкість +Name[wa]=Radisté macsimom +Name[x-test]=xxMax Speedxx +Name[zh_CN]=最大速度 +Name[zh_TW]=最大速率 + +[Desktop Action number] +Name=Number +Name[ar]=الرقم +Name[ast]=Númberu +Name[bg]=Номер +Name[bn]=সংখ্যা +Name[bs]=broj +Name[ca]=Número +Name[ca@valencia]=Número +Name[cs]=Číslo +Name[csb]=Numer +Name[da]=Nummer +Name[de]=Nummer +Name[el]=Αριθμός +Name[en_GB]=Number +Name[eo]=Nombro +Name[es]=Número +Name[et]=Arv +Name[eu]=Zenbakia +Name[fi]=Numero +Name[fr]=Numéro +Name[fy]=Nûmer +Name[ga]=Uimhir +Name[gl]=Número +Name[gu]=ક્રમ +Name[he]=מספר +Name[hi]=संख्या +Name[hr]=Broj +Name[hu]=Szám +Name[ia]=Numero +Name[id]=Nomor +Name[is]=Fjöldi +Name[it]=Numero +Name[ja]=番号 +Name[kk]=Нөмірі +Name[km]=លេខ +Name[kn]=ಸಂಖ್ಯೆ +Name[ko]=숫자 +Name[lt]=Skaičius +Name[lv]=Numurs +Name[mk]=Број +Name[ml]=അക്കം +Name[mr]=क्रमांक +Name[nb]=Tall +Name[nds]=Nummer +Name[nl]=Nummer +Name[nn]=Nummer +Name[pa]=ਗਿਣਤੀ +Name[pl]=Numer +Name[pt]=Número +Name[pt_BR]=Número +Name[ro]=Număr +Name[ru]=Номер +Name[si]=අංකය +Name[sk]=Číslo +Name[sl]=Število +Name[sr]=број +Name[sr@ijekavian]=број +Name[sr@ijekavianlatin]=broj +Name[sr@latin]=broj +Name[sv]=Antal +Name[tg]=Рақам +Name[th]=จำนวน +Name[tr]=Numara +Name[ug]=نومۇرى +Name[uk]=Номер +Name[wa]=Nombe +Name[x-test]=xxNumberxx +Name[zh_CN]=数值 +Name[zh_TW]=數字 + +[Desktop Entry] +Actions=canChangeFrequency;instructionSets;maxSpeed;number; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Processor diff --git a/solid-actions-kcm/device-actions/solid-device-SerialInterface.desktop b/solid-actions-kcm/device-actions/solid-device-SerialInterface.desktop new file mode 100644 index 00000000..a9c614eb --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-SerialInterface.desktop @@ -0,0 +1,258 @@ +[Desktop Action driverHandle] +Name=Driver Handle +Name[ar]=مقبض المشغل +Name[ast]=Controlador de preséu +Name[bg]=Управление на драйвера +Name[bn]=ড্রাইভার হ্যাণ্ডল +Name[bs]=ručka drajvera +Name[ca]=Gestor de controlador +Name[ca@valencia]=Gestor de controlador +Name[cs]=ID ovladače +Name[csb]=Czérownik Handle +Name[da]=Driver-handle +Name[de]=Treiber-Alias +Name[el]=Χειριστήριο οδηγού +Name[en_GB]=Driver Handle +Name[eo]=Pelila tenilo +Name[es]=Controlador de dispositivo +Name[et]=Draiveri pide +Name[eu]=Gidariaren heldulekua +Name[fi]=Ajuritunniste +Name[fr]=Gestionnaire du pilote +Name[fy]=Stjoerprograma regelaar +Name[ga]=Hanla an Tiománaí +Name[gl]=Xestión do controlador +Name[gu]=ડ્રાઇવ સંભાળનાર +Name[he]=ממשק מנהל ההתקן +Name[hi]=औजार हेंडल +Name[hr]=Pogonski program +Name[hu]=Meghajtóazonosító +Name[ia]=Maneator de driver +Name[id]=Penanganan Penggerak +Name[is]=Hald rekils +Name[ja]=ドライバハンドル +Name[kk]=Драйвер өңдеуі +Name[km]=កា​រគ្រប់គ្រង​កម្មវិធី​បញ្ជា +Name[ko]=드라이버 핸들 +Name[lt]=Tvarkyklės rankena +Name[lv]=Draivera rokturis +Name[ml]=ഉപരണത്തിന്റെ പിടി +Name[mr]=ड्राइव्हर हेंडल +Name[nb]=Drivernavn +Name[nds]=Drievergreep +Name[nl]=Stuurprogrammapook +Name[nn]=Drivarnamn +Name[pa]=ਡਰਾਇਵਰ ਹੈਂਡਲ +Name[pl]=Uchwyt sterownika +Name[pt]=Descritor do Controlador +Name[pt_BR]=Manipulador do driver +Name[ro]=Manipulare driver +Name[ru]=Драйверная ссылка на устройство +Name[si]=ධාවක අල්ලුව +Name[sk]=Rukoväť ovládača +Name[sl]=Ročica gonilnika +Name[sr]=ручка драјвера +Name[sr@ijekavian]=ручка драјвера +Name[sr@ijekavianlatin]=ručka drajvera +Name[sr@latin]=ručka drajvera +Name[sv]=Drivrutinreferens +Name[tg]=Плеери DJ-Mixer +Name[th]=การจัดการไดรเวอร์ +Name[tr]=Sürücü Tanıtıcı +Name[ug]=قوزغاتقۇ تۇتقۇسى +Name[uk]=Обробка драйвером +Name[vi]=Xử lý trình điều khiển +Name[wa]=Apougnî mineu +Name[x-test]=xxDriver Handlexx +Name[zh_CN]=驱动处理接口 +Name[zh_TW]=驅動程式處理 + +[Desktop Action port] +Name=Port +Name[ar]=المنفذ +Name[ast]=Puertu +Name[bg]=Порт +Name[bn]=পোর্ট +Name[bs]=port +Name[ca]=Port +Name[ca@valencia]=Port +Name[cs]=Port +Name[csb]=Pòrt +Name[da]=Port +Name[de]=Port +Name[el]=Θύρα +Name[en_GB]=Port +Name[eo]=Konektejo +Name[es]=Puerto +Name[et]=Port +Name[eu]=Ataka +Name[fa]=درگاه +Name[fi]=Portti +Name[fr]=Port +Name[fy]=Poarte +Name[ga]=Port +Name[gl]=Porto +Name[gu]=પોર્ટ +Name[he]=מפתח +Name[hi]=फोर्ट +Name[hr]=Port +Name[hu]=Csatlakozó +Name[ia]=Porto +Name[id]=Pangkalan +Name[is]=Gátt +Name[ja]=ポート +Name[ka]=პორტი +Name[kk]=Порты +Name[km]=ច្រក +Name[kn]=ಸಂಪರ್ಕಸ್ಥಾನ +Name[ko]=포트 +Name[lt]=Prievadas +Name[lv]=Ports +Name[mk]=Порта +Name[ml]=പോര്‍ട്ട് +Name[mr]=पोर्ट +Name[nb]=Port +Name[nds]=Port +Name[nl]=Poort +Name[nn]=Port +Name[pa]=ਪੋਰਟ +Name[pl]=Port +Name[pt]=Porta +Name[pt_BR]=Porta +Name[ro]=Port +Name[ru]=Порт +Name[si]=පේනුව +Name[sk]=Port +Name[sl]=Vrata +Name[sr]=порт +Name[sr@ijekavian]=порт +Name[sr@ijekavianlatin]=port +Name[sr@latin]=port +Name[sv]=Port +Name[tg]=Порт +Name[th]=พอร์ต +Name[tr]=Port +Name[ug]=ئېغىز +Name[uk]=Порт +Name[wa]=Pôrt +Name[x-test]=xxPortxx +Name[zh_CN]=端口 +Name[zh_TW]=連接埠 + +[Desktop Action serialType] +# ctxt: The physical type of serial port (ie. USB, RS232, etc) +Name=Serial Type +Name[bs]=Tip serijskog porta +Name[ca]=Tipus de sèrie +Name[ca@valencia]=Tipus de sèrie +Name[cs]=Typ sériového portu +Name[da]=Serialtype +Name[de]=Serieller Typ +Name[el]=Τύπος σειραϊκής +Name[en_GB]=Serial Type +Name[es]=Tipo de puerto serie +Name[et]=Jadaliidese tüüp +Name[eu]=Serie mota +Name[fi]=Sarjaportin tyyppi +Name[fr]=Type de port série +Name[gl]=Tipo de serie +Name[hu]=Csatlakozótípus +Name[ia]=Typo serial +Name[is]=Tegund raðtengis +Name[kk]=Тізбекті порт түрі +Name[ko]=시리얼 포트 종류 +Name[lt]=Serijinis tipas +Name[mr]=सिरीअल प्रकार +Name[nb]=Seriell type +Name[nds]=Seriell-Typ +Name[nl]=Type serieel +Name[pa]=ਸੀਰੀਅਲ ਟਾਈਪ +Name[pl]=Typ portu +Name[pt]=Tipo de Série +Name[pt_BR]=Tipo de serial +Name[ru]=Тип последовательного порта +Name[sk]=Sériový typ +Name[sl]=Vrsta zaporedne naprave +Name[sr]=тип серијског +Name[sr@ijekavian]=тип серијског +Name[sr@ijekavianlatin]=tip serijskog +Name[sr@latin]=tip serijskog +Name[sv]=Serietyp +Name[tr]=Seri Türü +Name[uk]=Тип послідовного інтерфейсу +Name[x-test]=xxSerial Typexx +Name[zh_CN]=串口类型 +Name[zh_TW]=序列類型 + +[Desktop Entry] +Actions=driverHandle;port;serialType; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=SerialInterface diff --git a/solid-actions-kcm/device-actions/solid-device-SmartCardReader.desktop b/solid-actions-kcm/device-actions/solid-device-SmartCardReader.desktop new file mode 100644 index 00000000..baafdd38 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-SmartCardReader.desktop @@ -0,0 +1,142 @@ +[Desktop Action readerType] +Name=Reader Type +Name[ar]=نوع القارئ +Name[ast]=Triba de llector +Name[bg]=Вид четец +Name[bn]=রিডার ধরন +Name[bs]=tip čitača +Name[ca]=Tipus de lector +Name[ca@valencia]=Tipus de lector +Name[cs]=Typ čtečky +Name[csb]=Ôrt czëtaniô +Name[da]=Læsertype +Name[de]=Lesertyp +Name[el]=Τύπος αναγνώστη +Name[en_GB]=Reader Type +Name[eo]=Tipo de Legilo +Name[es]=Tipo de lector +Name[et]=Lugeja tüüp +Name[eu]=Irakurgailu mota +Name[fi]=Lukijatyyppi +Name[fr]=Type de lecteur +Name[fy]=Lês type +Name[ga]=Cineál an Léitheora +Name[gl]=Tipo de lector +Name[gu]=વાંચન પ્રકાર +Name[he]=סוג קורא +Name[hi]=रीडर प्रकार +Name[hr]=Vrsta čitača +Name[hu]=Olvasótípus +Name[ia]=Typo de lector +Name[id]=Tipe Pembaca +Name[is]=Gerð lesara +Name[ja]=リーダーのタイプ +Name[kk]=Оқу құралының түрі +Name[km]=ប្រភេទ​កម្មវិធី​អាន +Name[kn]=ಓದುಗನ ಬಗೆ +Name[ko]=리더 종류 +Name[lt]=Skaitymo tipas +Name[lv]=Lasītāja tips +Name[mk]=Тип на читач +Name[ml]=റീഡറിന്റെ തരം +Name[mr]=वाचक प्रकार +Name[nb]=Lesertype +Name[nds]=Lesertyp +Name[nl]=Type reader +Name[nn]=Lesartype +Name[pa]=ਰੀਡਰ ਟਾਈਪ +Name[pl]=Typ czytnika +Name[pt]=Tipo de Leitor +Name[pt_BR]=Tipo de leitor +Name[ro]=Tip cititor +Name[ru]=Тип устройства чтения +Name[si]=කියවන්නාගේ වර්ගය +Name[sk]=Typ čítačky +Name[sl]=Vrsta bralnika +Name[sr]=тип читача +Name[sr@ijekavian]=тип читача +Name[sr@ijekavianlatin]=tip čitača +Name[sr@latin]=tip čitača +Name[sv]=Typ av läsare +Name[tg]=Намуди хондан +Name[th]=ประเภทของตัวอ่าน +Name[tr]=Okuyucu Tipi +Name[ug]=ئوقۇغۇچ تىپى +Name[uk]=Тип засобу зчитування +Name[wa]=Sôre do lijheu +Name[x-test]=xxReader Typexx +Name[zh_CN]=读取器类型 +Name[zh_TW]=讀取器型態 + +[Desktop Entry] +Actions=readerType; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=SmartCardReader diff --git a/solid-actions-kcm/device-actions/solid-device-StorageAccess.desktop b/solid-actions-kcm/device-actions/solid-device-StorageAccess.desktop new file mode 100644 index 00000000..256c6226 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-StorageAccess.desktop @@ -0,0 +1,217 @@ +[Desktop Action accessible] +Name=Accessible +Name[ar]=متاح +Name[ast]=Accesible +Name[bg]=Достъпен +Name[bn]=সহায়ক প্রযুক্তি +Name[bs]=pristupan +Name[ca]=Accessible +Name[ca@valencia]=Accessible +Name[cs]=Přístupné +Name[csb]=Pòmòce przëstãpù +Name[da]=Tilgængelig +Name[de]=Verfügbar +Name[el]=Προσβάσιμο +Name[en_GB]=Accessible +Name[eo]=Atingebla +Name[es]=Accesible +Name[et]=Juurdepääsuga +Name[eu]=Eskuragarri +Name[fi]=Saatavilla +Name[fr]=Accessible +Name[fy]=Tagonklik +Name[ga]=Inrochtana +Name[gl]=Accesíbel +Name[gu]=ઉપયોગી +Name[he]=נגיש +Name[hi]=पहुँच योग्य +Name[hr]=Pristupačan +Name[hu]=Elérhető +Name[ia]=Accessibile +Name[id]=Dapat Diakses +Name[is]=Aðgengilegt +Name[it]=Accessibile +Name[ja]=アクセス可能 +Name[kk]=Қол жетерлік +Name[km]=អាច​ចូលដំណើរការ​បាន +Name[kn]=ನಿಲುಕಬಲ್ಲ +Name[ko]=접근 가능 여부 +Name[lt]=Prieinamas +Name[lv]=Pieejams +Name[mk]=Пристапно +Name[ml]=സാമീപിയ്ക്കാവുന്നതു് +Name[mr]=सुलभ +Name[nb]=Tilgjengelig +Name[nds]=Togriepbor +Name[nl]=Toegankelijk +Name[nn]=Tilgjengeleg +Name[pa]=ਸਹੂਲਤਾਂ +Name[pl]=Dostępny +Name[pt]=Acessível +Name[pt_BR]=Acessível +Name[ro]=Accesibil +Name[ru]=Доступно +Name[si]=ප්‍රවේශවිය හැකි +Name[sk]=Prístupné +Name[sl]=Dostopno +Name[sr]=приступан +Name[sr@ijekavian]=приступан +Name[sr@ijekavianlatin]=pristupan +Name[sr@latin]=pristupan +Name[sv]=Tillgänglig +Name[tg]=Имкониятҳо +Name[th]=เข้าถึงได้ +Name[tr]=Erişilebilir +Name[ug]=زىيارەتچان +Name[uk]=Доступний +Name[vi]=Truy cập được +Name[wa]=Arinnåve +Name[x-test]=xxAccessiblexx +Name[zh_CN]=可访问 +Name[zh_TW]=可存取 + +[Desktop Action filePath] +Name=File Path +Name[ar]=مسار الملف +Name[ast]=Camín a ficheru +Name[bg]=Път до файл +Name[bn]=ফাইল পাথ +Name[bs]=putanja datoteke +Name[ca]=Camí al fitxer +Name[ca@valencia]=Camí al fitxer +Name[cs]=Cesta k souboru +Name[csb]=Stegna lopka +Name[da]=Filsti +Name[de]=Dateipfad +Name[el]=Διαδρομή αρχείου +Name[en_GB]=File Path +Name[eo]=Dosiervojo +Name[es]=Ruta a archivo +Name[et]=Faili asukoht +Name[eu]=Fitxategiaren bide-izena +Name[fa]=مسیر پرونده +Name[fi]=Tiedostopolku +Name[fr]=Emplacement du fichier +Name[fy]=Triem paad +Name[ga]=Conair Chomhaid +Name[gl]=Ruta ao ficheiro +Name[gu]=ફાઇલ પાથ +Name[he]=נתיב קובץ +Name[hi]=फ़ाइल पथ +Name[hr]=Putanja datoteke +Name[hu]=Elérési út +Name[ia]=Percurso de file +Name[id]=Alamat Berkas +Name[is]=Skráarslóð +Name[it]=Percorso di file +Name[ja]=ファイルのパス +Name[kk]=Файл жолы +Name[km]=ផ្លូវ​ឯកសារ +Name[kn]=ಕಡತದ ಮಾರ್ಗ +Name[ko]=파일 경로 +Name[lt]=Failo kelias +Name[lv]=Faila ceļš +Name[mk]=Патека на датотека +Name[ml]=ഫയല്‍ വഴി +Name[mr]=फाईलचा मार्ग +Name[nb]=Filsti +Name[nds]=Dateipadd +Name[nl]=Bestandspad +Name[nn]=Filadresse +Name[pa]=ਫਾਇਲ ਪਾਥ +Name[pl]=Ścieżka do pliku +Name[pt]=Localização do Ficheiro +Name[pt_BR]=Caminho do arquivo +Name[ro]=Calea fișierului +Name[ru]=Путь к файлу +Name[si]=ගොනු පෙත +Name[sk]=Cesta k súboru +Name[sl]=Pot do datoteke +Name[sr]=путања фајла +Name[sr@ijekavian]=путања фајла +Name[sr@ijekavianlatin]=putanja fajla +Name[sr@latin]=putanja fajla +Name[sv]=Filsökväg +Name[tg]=Роҳи файл +Name[th]=พาธของแฟ้ม +Name[tr]=Dosya Yolu +Name[ug]=ھۆججەت يولى +Name[uk]=Шлях до файла +Name[vi]=Đường dẫn tập tin +Name[wa]=Tchimin do fitchî +Name[x-test]=xxFile Pathxx +Name[zh_CN]=文件路径 +Name[zh_TW]=檔案路徑 + +[Desktop Entry] +Actions=accessible;filePath; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=StorageAccess diff --git a/solid-actions-kcm/device-actions/solid-device-StorageDrive.desktop b/solid-actions-kcm/device-actions/solid-device-StorageDrive.desktop new file mode 100644 index 00000000..5627c0b4 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-StorageDrive.desktop @@ -0,0 +1,434 @@ +[Desktop Action bus] +Name=Bus +Name[ar]=الناقل +Name[ast]=Bus +Name[bg]=Шина +Name[bn]=বাস +Name[bs]=magistrala +Name[ca]=Bus +Name[ca@valencia]=Bus +Name[cs]=Sběrnice +Name[csb]=Bus +Name[da]=Bus +Name[de]=Bus +Name[el]=Δίαυλος +Name[en_GB]=Bus +Name[eo]=Buso +Name[es]=Bus +Name[et]=Siin +Name[eu]=Busa +Name[fa]=گذرگاه +Name[fi]=Väylä +Name[fr]=Bus +Name[fy]=Bus +Name[ga]=Bus +Name[gl]=Bus +Name[gu]=બસ +Name[he]=אפיק +Name[hi]=बस +Name[hr]=Sabirnica +Name[hu]=Busz +Name[ia]=Bus +Name[id]=Bus +Name[is]=Rás (bus) +Name[it]=Bus +Name[ja]=バス +Name[ka]=სალტე +Name[kk]=Шинасы +Name[km]=ខ្សែបញ្ជូន +Name[kn]=ಬಸ್ +Name[ko]=버스 +Name[lt]=Magistralė +Name[lv]=Kopne +Name[mk]=Магистрала +Name[ml]=ബസ് +Name[mr]=बस +Name[nb]=Buss +Name[nds]=Bus +Name[nl]=Bus +Name[nn]=Buss +Name[pa]=ਬਸ +Name[pl]=Szyna +Name[pt]=Barramento +Name[pt_BR]=Barramento +Name[ro]=Magistrală +Name[ru]=Шина +Name[si]=Bus +Name[sk]=Zbernica +Name[sl]=Vodilo +Name[sr]=магистрала +Name[sr@ijekavian]=магистрала +Name[sr@ijekavianlatin]=magistrala +Name[sr@latin]=magistrala +Name[sv]=Buss +Name[tg]=Белоруссия +Name[th]=ระบบบัส +Name[tr]=Yol +Name[ug]=باش لىنىيە +Name[uk]=Шина +Name[wa]=Bus +Name[x-test]=xxBusxx +Name[zh_CN]=总线 +Name[zh_TW]=匯流排 + +[Desktop Action driveType] +Name=Drive Type +Name[ar]=نوع المشغل +Name[ast]=Triba de discu +Name[bg]=Вид устройство +Name[bn]=ড্রাইভ-এর ধরন +Name[bs]=tip jedinice +Name[ca]=Tipus d'unitat +Name[ca@valencia]=Tipus d'unitat +Name[cs]=Typ mechaniky +Name[csb]=Ôrt nëka +Name[da]=Drevtype +Name[de]=Laufwerkstyp +Name[el]=Τύπος οδηγού +Name[en_GB]=Drive Type +Name[eo]=Tipo de Diskingo +Name[es]=Tipo de disco +Name[et]=Seadme tüüp +Name[eu]=Unitate mota +Name[fi]=Asematyyppi +Name[fr]=Type de lecteur +Name[fy]=Stasjons type +Name[ga]=Cineál an Tiomántáin +Name[gl]=Tipo de dispositivo +Name[gu]=ડ્રાઇવ પ્રકાર +Name[he]=סוג כונן +Name[hi]=ड्राईव प्रकार +Name[hr]=Tip uređaja +Name[hu]=Meghajtótípus +Name[ia]=Typo de drive +Name[id]=Tipe Penggerak +Name[is]=Gerð drifs +Name[it]=Tipo di unità +Name[ja]=ドライブのタイプ +Name[ka]=ამძრავის ტიპი +Name[kk]=Жетек түрі +Name[km]=ប្រភេទ​ដ្រាយ +Name[kn]=ಡ್ರೈವಿನ ಬಗೆ +Name[ko]=드라이브 종류 +Name[lt]=Diskasukio tipas +Name[lv]=Dziņa tips +Name[mai]=ड्राइव प्रकार +Name[mk]=Тип на уред +Name[ml]=ഡ്രൈവിന്റെ തരം +Name[mr]=ड्राइव्ह प्रकार +Name[nb]=Drev-type +Name[nds]=Loopwark-Typ +Name[nl]=Apparaattype +Name[nn]=Einingstype +Name[pa]=ਡਰਾਇਵਰ ਕਿਸਮ +Name[pl]=Typ napędu +Name[pt]=Tipo de Unidade +Name[pt_BR]=Tipo de unidade +Name[ro]=Tip unitate +Name[ru]=Тип устройства +Name[si]=ධාවක වර්ගය +Name[sk]=Typ mechaniky +Name[sl]=Vrsta pogona +Name[sr]=тип јединице +Name[sr@ijekavian]=тип јединице +Name[sr@ijekavianlatin]=tip jedinice +Name[sr@latin]=tip jedinice +Name[sv]=Enhetstyp +Name[tg]=Намуди дастгоҳ +Name[th]=ประเภทของไดรฟ์ +Name[tr]=Sürücü Tipi +Name[ug]=قوزغاتقۇ تىپى +Name[uk]=Тип пристрою +Name[vi]=Kiểu trình điều khiển +Name[wa]=Sôre di lijheu +Name[x-test]=xxDrive Typexx +Name[zh_CN]=驱动类型 +Name[zh_TW]=磁碟型態 + +[Desktop Action hotpluggable] +Name=Hotpluggable +Name[ar]=قابل للتوصيل +Name[ast]=Conexón en caliente +Name[bn]=হট-প্লাগ-যোগ্য +Name[bs]=vruće uključiva +Name[ca]=Connectable en calent +Name[ca@valencia]=Connectable en calent +Name[cs]=Hotplug +Name[da]=Flytbar +Name[de]=Hotplug-fähig +Name[el]=Δυνατότητα Hotplug +Name[en_GB]=Hotpluggable +Name[eo]=Dumkure permutebla +Name[es]=Conexión en caliente +Name[et]=Töö ajal ühendatav +Name[eu]=Hotplug-erako gaitua +Name[fi]=Lennossakytkettävä +Name[fr]=Connectable à chaud +Name[fy]=Hotplug barren +Name[ga]=Inphlugáilte +Name[gl]=Conectábel en quente +Name[gu]=હોટપ્લગેબલ +Name[he]=החלפה חמה +Name[hi]=हाटप्लग योग्य +Name[hr]=Podržava brzo uštekavanje +Name[hu]=Menet közben csatlakoztatható +Name[ia]=Hotpluggable (On pote connecter lo con machina active) +Name[id]=Dapat di-Hotplug +Name[is]=Hraðtengjanlegt (hotplug) +Name[it]=Collegabile in marcia +Name[ja]=Hotplug 可能 +Name[kk]=Істеп турғанда қосылмалы +Name[km]=ដោតដើរ +Name[kn]=ಹಾಟ್‌ಪ್ಲಗ್‌ ಮಾಡಬಹುದಾದ +Name[ko]=핫플러그 가능 +Name[lt]=Greitai prijungiamas +Name[lv]=Karsti nomaināms +Name[ml]=ഹോട്ട്പ്ലഗ് ചെയ്യാവുന്ന +Name[mr]=हॉटप्लग करता येणारे +Name[nb]=Kan kobles til påslått +Name[nds]=Jümmers tokoppelbor +Name[nl]=Hotplugbaar +Name[nn]=Hotplug-kompatibel +Name[pa]=ਹਾਟਪਲੱਗਯੋਗ +Name[pl]=Podłączany "na gorąco" +Name[pt]=Conectável em Funcionamento +Name[pt_BR]=Conectável em funcionamento +Name[ro]=Detașabil +Name[ru]=Подключается в любое время +Name[si]=Hotpluggable +Name[sk]=Hotplug +Name[sl]=Priključljivo med delovanjem +Name[sr]=вруће укључива +Name[sr@ijekavian]=вруће укључива +Name[sr@ijekavianlatin]=vruće uključiva +Name[sr@latin]=vruće uključiva +Name[sv]=Inkopplingsbar +Name[tg]=Дастгоҳҳои пайвастшаванда +Name[th]=สามารถถอดเสียบได้ +Name[tr]=Çıkarılıp takılabilir +Name[ug]=ئىسسىق چېتىلىشچان +Name[uk]=«Гаряче» з’єднання +Name[vi]=Tháo lắp nóng +Name[wa]=Hotplugåve +Name[x-test]=xxHotpluggablexx +Name[zh_CN]=可热插拔 +Name[zh_TW]=可熱插拔 + +[Desktop Action removable] +Name=Removable +Name[ar]=قابل للإزالة +Name[ast]=Estrayible +Name[bg]=Преносим +Name[bn]=অপসারণযোগ্য +Name[bs]=uklonjiva +Name[ca]=Extraïble +Name[ca@valencia]=Extraïble +Name[cs]=Odpojitelný +Name[csb]=Przenosné +Name[da]=Flytbar +Name[de]=Wechselbar +Name[el]=Αφαιρούμενο μέσο +Name[en_GB]=Removable +Name[eo]=Demetebla +Name[es]=Extraíble +Name[et]=Eemaldatav +Name[eu]=Aldagarria +Name[fa]=جدا شدنی +Name[fi]=Poistettavissa +Name[fr]=Amovible +Name[fy]=Te ferwiderjen +Name[ga]=Inbhainte +Name[gl]=Eliminábel +Name[gu]=દૂર કરી શકાય તેવું +Name[he]=ניתן להסרה +Name[hi]=हटाने योग्य +Name[hr]=Moguće ga je izvaditi +Name[hu]=Cserélhető +Name[ia]=Removibile +Name[id]=Dapat Dilepaskan +Name[is]=Fjarlægjanlegt +Name[it]=Rimovibile +Name[ja]=リムーバブル +Name[kk]=Ауыстырмалы +Name[km]=អាច​យក​ចេញ​បាន +Name[kn]=ತೆಗೆಯಬಹುದಾದ +Name[ko]=제거 가능 +Name[lt]=Keičiamas +Name[lv]=Noņemams +Name[mai]=हटबैयोग्य +Name[mk]=Подвижен +Name[ml]=നീക്കം ചെയ്യാവുന്ന +Name[mr]=काढता येणारे +Name[nb]=Flyttbar +Name[nds]=Tuuschbor +Name[nl]=Verwijderbaar +Name[nn]=Flyttbar +Name[pa]=ਹਟਾਉਣਯੋਗ +Name[pl]=Wymienny +Name[pt]=Removível +Name[pt_BR]=Removível +Name[ro]=Amovibil +Name[ru]=Сменный носитель +Name[si]=ඉවත්කල හැකි +Name[sk]=Vymeniteľné +Name[sl]=Odstranljivo +Name[sr]=уклоњива +Name[sr@ijekavian]=уклоњива +Name[sr@ijekavianlatin]=uklonjiva +Name[sr@latin]=uklonjiva +Name[sv]=Flyttbar +Name[tg]=Дастгоҳи ҷудошаванда +Name[th]=ถอดเสียบได้ +Name[tr]=Çıkarılabilir +Name[ug]=كۆچمە +Name[uk]=Змінний пристрій +Name[wa]=Bodjåve +Name[x-test]=xxRemovablexx +Name[zh_CN]=移动 +Name[zh_TW]=可移除 + +[Desktop Action size] +Name=Size +Name[ar]=الحجم +Name[ast]=Tamañu +Name[bg]=Големина +Name[bn]=মাপ +Name[bs]=veličina +Name[ca]=Mida +Name[ca@valencia]=Mida +Name[cs]=Velikost +Name[csb]=Miara +Name[da]=Størrelse +Name[de]=Größe +Name[el]=Μέγεθος +Name[en_GB]=Size +Name[eo]=Grandeco +Name[es]=Tamaño +Name[et]=Suurus +Name[eu]=Neurria +Name[fa]=اندازه +Name[fi]=Koko +Name[fr]=Taille +Name[fy]=Grutte +Name[ga]=Méid +Name[gl]=Tamaño +Name[gu]=માપ +Name[he]=גודל +Name[hi]=आकार +Name[hr]=Veličina +Name[hu]=Méret +Name[ia]=Dimension +Name[id]=Ukuran +Name[is]=Stærð +Name[it]=Dimensione +Name[ja]=サイズ +Name[ka]=ზომა +Name[kk]=Көлемі +Name[km]=ទំហំ +Name[kn]=ಗಾತ್ರ +Name[ko]=크기 +Name[lt]=Dydis +Name[lv]=Izmērs +Name[mk]=Големина +Name[ml]=വലിപ്പം +Name[mr]=आकार +Name[nb]=Størrelse +Name[nds]=Grött +Name[nl]=Grootte +Name[nn]=Storleik +Name[pa]=ਸਾਈਜ਼ +Name[pl]=Rozmiar +Name[pt]=Tamanho +Name[pt_BR]=Tamanho +Name[ro]=Dimensiune +Name[ru]=Размер +Name[si]=ප්‍රමාණය +Name[sk]=Veľkosť +Name[sl]=Velikost +Name[sr]=величина +Name[sr@ijekavian]=величина +Name[sr@ijekavianlatin]=veličina +Name[sr@latin]=veličina +Name[sv]=Storlek +Name[tg]=Андоза +Name[th]=ขนาด +Name[tr]=Boyut +Name[ug]=چوڭلۇقى +Name[uk]=Розмір +Name[wa]=Grandeu +Name[x-test]=xxSizexx +Name[zh_CN]=大小 +Name[zh_TW]=大小 + +[Desktop Entry] +Actions=bus;driveType;hotpluggable;removable;size; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=StorageDrive diff --git a/solid-actions-kcm/device-actions/solid-device-StorageVolume.desktop b/solid-actions-kcm/device-actions/solid-device-StorageVolume.desktop new file mode 100644 index 00000000..8090b2d5 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-StorageVolume.desktop @@ -0,0 +1,507 @@ +[Desktop Action fsType] +Name=Fs Type +Name[ar]=نوع نظام الملفات +Name[ast]=Triba de Fs +Name[bg]=Вид файлова система +Name[bn]=Fs ধরন +Name[bs]=tip fsis. +Name[ca]=Tipus de sistema de fitxers +Name[ca@valencia]=Tipus de sistema de fitxers +Name[cs]=Typ FS +Name[csb]=Ôrt Fs +Name[da]=FS-type +Name[de]=Dateisystemtyp +Name[el]=Τύπος συστήματος αρχείων +Name[en_GB]=Fs Type +Name[eo]=Dosiersistema Tipo +Name[es]=Tipo de s. a. +Name[et]=Failisüsteemi tüüp +Name[eu]=Fitxategi-sistema mota +Name[fi]=Tiedostojärjestelmän tyyppi +Name[fr]=Type de système de fichiers +Name[fy]=Fs type +Name[ga]=Cineál an Chórais Comhad +Name[gl]=Sistema de ficheiros +Name[gu]=Fs પ્રકાર +Name[he]=סוג מערכת קבצים +Name[hi]=Fs प्रकार +Name[hr]=Tip datotečnog sustava +Name[hu]=Fájlrendszer +Name[ia]=Typo Fs +Name[id]=Tipe Sistem Berkas +Name[is]=Tegund skráakerfis +Name[it]=Tipo di filesystem +Name[ja]=Fs タイプ +Name[kk]=ФЖ түрі +Name[km]=ប្រភេទ Fs +Name[kn]=Fs ಬಗೆ +Name[ko]=파일 시스템 종류 +Name[lt]=FS tipas +Name[lv]=FS tips +Name[mai]=Fs प्रकार +Name[mk]=Тип на дат. систем +Name[ml]=ഫയല്‍ വ്യവസ്ഥയുടെ തരം +Name[mr]=Fs प्रकार +Name[nb]=Filsystemtype +Name[nds]=Dateisysteem-Typ +Name[nl]=FS-type +Name[nn]=Filsystemtype +Name[pa]=Fs ਕਿਸਮ +Name[pl]=Typ systemu plików +Name[pt]=Tipo de SF +Name[pt_BR]=Tipo de sistema de arquivos +Name[ro]=Tipul SF +Name[ru]=Файловая система +Name[si]=Fs වර්ගය +Name[sk]=Typ FS +Name[sl]=Vrsta dat. sist. +Name[sr]=тип фсис. +Name[sr@ijekavian]=тип фсис. +Name[sr@ijekavianlatin]=tip fsis. +Name[sr@latin]=tip fsis. +Name[sv]=Filsystemtyp +Name[tg]=Намуди Fs +Name[th]=ประเภทของระบบแฟ้ม +Name[tr]=Dosya Sistemi Tipi +Name[ug]=ھۆججەت سىستېما تىپى +Name[uk]=Тип ФС +Name[vi]=Kiểu hệ thống tập tin +Name[wa]=Sôre di Fs +Name[x-test]=xxFs Typexx +Name[zh_CN]=文件系统类型 +Name[zh_TW]=檔案系統型態 + +[Desktop Action ignored] +Name=Ignored +Name[ar]=متجاهَل +Name[ast]=Inoráu +Name[bg]=Пренебрегнат +Name[bn]=উপেক্ষিত +Name[bs]=ignorisan +Name[ca]=Ignorat +Name[ca@valencia]=Ignorat +Name[cs]=Ignorováno +Name[csb]=Ignorowóné +Name[da]=Ignoreret +Name[de]=Ignoriert +Name[el]=Παράβλεψη +Name[en_GB]=Ignored +Name[eo]=Ignorita +Name[es]=Ignorado +Name[et]=Eiratav +Name[eu]=Ez ikusi eginda +Name[fi]=Ei otettu huomioon +Name[fr]=Ignoré +Name[fy]=Negearre +Name[ga]=Neamhaird Déanta De +Name[gl]=Ignorado +Name[gu]=અવગણેલ +Name[he]=התעלם +Name[hi]=उपेक्षित +Name[hr]=Zanemareno +Name[hu]=Nem kezelt +Name[ia]=Ignorate +Name[id]=Diabaikan +Name[is]=Hunsað +Name[it]=Ignorato +Name[ja]=無視 +Name[kk]=Еленбеген +Name[km]=បានមិនអើពើ +Name[kn]=ಆಲಕ್ಷಿತ +Name[ko]=무시됨 +Name[lt]=Ignoruota +Name[lv]=Ignorēts +Name[mk]=Игнорирано +Name[ml]=അവഗണിച്ചു +Name[mr]=उपेक्षित +Name[nb]=Ignorert +Name[nds]=Övergahn +Name[nl]=Genegeerd +Name[nn]=Oversett +Name[pa]=ਅਣਡਿੱਠ ਕੀਤਾ +Name[pl]=Ignorowany +Name[pt]=Ignorado +Name[pt_BR]=Ignorado +Name[ro]=Ignorat +Name[ru]=Игнорируется +Name[si]=නොතැකූ +Name[sk]=Ignorované +Name[sl]=Prezrto +Name[sr]=игнорисан +Name[sr@ijekavian]=игнорисан +Name[sr@ijekavianlatin]=ignorisan +Name[sr@latin]=ignorisan +Name[sv]=Ignorerad +Name[tg]=Радшуда +Name[th]=ไม่สนใจ +Name[tr]=Yoksayılmış +Name[ug]=پەرۋا قىلمىدى +Name[uk]=Ігнорується +Name[vi]=Bỏ qua +Name[wa]=Passé houte +Name[x-test]=xxIgnoredxx +Name[zh_CN]=已忽略 +Name[zh_TW]=忽略 + +[Desktop Action label] +Name=Label +Name[ar]=التسمية +Name[ast]=Etiqueta +Name[bg]=Етикет +Name[bn]=লেবেল +Name[bs]=etiketa +Name[ca]=Etiqueta +Name[ca@valencia]=Etiqueta +Name[cs]=Popisek +Name[csb]=Znakòwnik +Name[da]=Etiket +Name[de]=Beschriftung +Name[el]=Ετικέτα +Name[en_GB]=Label +Name[eo]=Labelo +Name[es]=Etiqueta +Name[et]=Pealdis +Name[eu]=Etiketa +Name[fa]=برچسب +Name[fi]=Nimike +Name[fr]=Étiquette +Name[fy]=Lebel +Name[ga]=Lipéad +Name[gl]=Etiqueta +Name[gu]=લેબલ +Name[he]=תוויות +Name[hi]=लेबल +Name[hr]=Natpis +Name[hu]=Címke +Name[ia]=Etiquetta +Name[id]=Label +Name[is]=Merking +Name[it]=Etichetta +Name[ja]=ラベル +Name[kk]=Тамғасы +Name[km]=ស្លាក +Name[kn]=ಗುರುತುಪಟ್ಟಿ +Name[ko]=레이블 +Name[lt]=Etiketė +Name[lv]=Etiķete +Name[mk]=Натпис +Name[ml]=ലേബല്‍ +Name[mr]=लेबल +Name[nb]=Etikett +Name[nds]=Beteker +Name[nl]=Label +Name[nn]=Merkelapp +Name[pa]=ਲੇਬਲ +Name[pl]=Etykieta +Name[pt]=Legenda +Name[pt_BR]=Rótulo +Name[ro]=Etichetă +Name[ru]=Метка +Name[si]=ලේබලය +Name[sk]=Štítok +Name[sl]=Oznaka +Name[sr]=етикета +Name[sr@ijekavian]=етикета +Name[sr@ijekavianlatin]=etiketa +Name[sr@latin]=etiketa +Name[sv]=Etikett +Name[tg]=Тамға +Name[th]=แถบป้าย +Name[tr]=Etiket +Name[ug]=ئەن +Name[uk]=Мітка +Name[vi]=Nhãn +Name[wa]=Etikete +Name[x-test]=xxLabelxx +Name[zh_CN]=标签 +Name[zh_TW]=標籤 + +[Desktop Action size] +Name=Size +Name[ar]=الحجم +Name[ast]=Tamañu +Name[bg]=Големина +Name[bn]=মাপ +Name[bs]=veličina +Name[ca]=Mida +Name[ca@valencia]=Mida +Name[cs]=Velikost +Name[csb]=Miara +Name[da]=Størrelse +Name[de]=Größe +Name[el]=Μέγεθος +Name[en_GB]=Size +Name[eo]=Grandeco +Name[es]=Tamaño +Name[et]=Suurus +Name[eu]=Neurria +Name[fa]=اندازه +Name[fi]=Koko +Name[fr]=Taille +Name[fy]=Grutte +Name[ga]=Méid +Name[gl]=Tamaño +Name[gu]=માપ +Name[he]=גודל +Name[hi]=आकार +Name[hr]=Veličina +Name[hu]=Méret +Name[ia]=Dimension +Name[id]=Ukuran +Name[is]=Stærð +Name[it]=Dimensione +Name[ja]=サイズ +Name[ka]=ზომა +Name[kk]=Көлемі +Name[km]=ទំហំ +Name[kn]=ಗಾತ್ರ +Name[ko]=크기 +Name[lt]=Dydis +Name[lv]=Izmērs +Name[mk]=Големина +Name[ml]=വലിപ്പം +Name[mr]=आकार +Name[nb]=Størrelse +Name[nds]=Grött +Name[nl]=Grootte +Name[nn]=Storleik +Name[pa]=ਸਾਈਜ਼ +Name[pl]=Rozmiar +Name[pt]=Tamanho +Name[pt_BR]=Tamanho +Name[ro]=Dimensiune +Name[ru]=Размер +Name[si]=ප්‍රමාණය +Name[sk]=Veľkosť +Name[sl]=Velikost +Name[sr]=величина +Name[sr@ijekavian]=величина +Name[sr@ijekavianlatin]=veličina +Name[sr@latin]=veličina +Name[sv]=Storlek +Name[tg]=Андоза +Name[th]=ขนาด +Name[tr]=Boyut +Name[ug]=چوڭلۇقى +Name[uk]=Розмір +Name[wa]=Grandeu +Name[x-test]=xxSizexx +Name[zh_CN]=大小 +Name[zh_TW]=大小 + +[Desktop Action usage] +Name=Usage +Name[ar]=الاستعمال +Name[ast]=Usu +Name[bg]=Използване +Name[bn]=ব্যবহার +Name[bs]=upotreba +Name[ca]=Ús +Name[ca@valencia]=Ús +Name[cs]=Použití +Name[csb]=Brëkòwóné +Name[da]=Brug +Name[de]=Verwendung +Name[el]=Χρήση +Name[en_GB]=Usage +Name[eo]=Uzado +Name[es]=Uso +Name[et]=Kasutus +Name[eu]=Erabilera +Name[fi]=Käyttötaso +Name[fr]=Usage +Name[fy]=Brûkens +Name[ga]=Úsáid +Name[gl]=Uso +Name[gu]=વપરાશ +Name[he]=שימוש +Name[hi]=उपयोग +Name[hr]=Iskorištenost +Name[hu]=Kihasználtság +Name[ia]=Usage +Name[id]=Penggunaan +Name[is]=Notkun +Name[it]=Uso +Name[ja]=使用率 +Name[ka]=გამოყენება +Name[kk]=Толуы +Name[km]=កា​រប្រើប្រាស់ +Name[kn]=ಬಳಕೆ +Name[ko]=사용량 +Name[lt]=Naudojimas +Name[lv]=Izlietojums +Name[mk]=Користење +Name[ml]=ഉപയോഗരീതി +Name[mr]=वापर +Name[nb]=Bruk +Name[nds]=Bruuk +Name[nl]=Gebruik +Name[nn]=Bruk +Name[pa]=ਵਰਤੋਂ +Name[pl]=Wykorzystanie +Name[pt]=Utilização +Name[pt_BR]=Uso +Name[ro]=Utilizare +Name[ru]=Использование +Name[si]=භාවිතය +Name[sk]=Použitie +Name[sl]=Poraba +Name[sr]=употреба +Name[sr@ijekavian]=употреба +Name[sr@ijekavianlatin]=upotreba +Name[sr@latin]=upotreba +Name[sv]=Användning +Name[tg]=Истифодабарӣ +Name[th]=วิธีใช้ +Name[tr]=Kullanım +Name[ug]=ئىشلىتىلىشى +Name[uk]=Використання +Name[wa]=Eployaedje +Name[x-test]=xxUsagexx +Name[zh_CN]=已用量 +Name[zh_TW]=使用量 + +[Desktop Action uuid] +Name=Uuid +Name[ar]=المعرف الفريد عالمياً (Uuid) +Name[ast]=Uuid +Name[bg]=Uuid +Name[bn]=Uuid +Name[bs]=UUID +Name[ca]=UUID +Name[ca@valencia]=UUID +Name[cs]=Uuid +Name[csb]=Uuid +Name[da]=Uuid +Name[de]=UUID +Name[el]=Uuid +Name[en_GB]=Uuid +Name[eo]=Uuid +Name[es]=Uuid +Name[et]=Uuid +Name[eu]=UUIDa +Name[fi]=Uuid +Name[fr]=Uuid +Name[fy]=Uuid +Name[ga]=Uuid +Name[gl]=Uuid +Name[gu]=Uuid +Name[he]=Uuid +Name[hi]=Uuid +Name[hr]=UUID +Name[hu]=UUID +Name[ia]=Uuid +Name[id]=Uuid +Name[is]=UUID +Name[it]=Uuid +Name[ja]=UUID +Name[ka]=Uuid +Name[kk]=Uuid +Name[km]=Uuid +Name[kn]=Uuid +Name[ko]=UUID +Name[lt]=Uuid +Name[lv]=Uuid +Name[mk]=Uuid +Name[ml]=യുയുഐഡി +Name[mr]=Uuid +Name[nb]=Uuid +Name[nds]=UUID +Name[nl]=Uuid +Name[nn]=UUID +Name[pa]=Uuid +Name[pl]=Uuid +Name[pt]=UUID +Name[pt_BR]=UUID +Name[ro]=Uuid +Name[ru]=UUID +Name[si]=Uuid +Name[sk]=Uuid +Name[sl]=UUID +Name[sr]=УУИД +Name[sr@ijekavian]=УУИД +Name[sr@ijekavianlatin]=UUID +Name[sr@latin]=UUID +Name[sv]=Uuid +Name[tg]=Phluid +Name[th]=ค่า Uuid +Name[tr]=Uuid +Name[ug]=Uuid +Name[uk]=Uuid +Name[wa]=Uuid +Name[x-test]=xxUuidxx +Name[zh_CN]=UUID +Name[zh_TW]=UUID + +[Desktop Entry] +Actions=fsType;ignored;label;size;usage;uuid; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=StorageVolume diff --git a/solid-actions-kcm/device-actions/solid-device-Video.desktop b/solid-actions-kcm/device-actions/solid-device-Video.desktop new file mode 100644 index 00000000..fd8f79d9 --- /dev/null +++ b/solid-actions-kcm/device-actions/solid-device-Video.desktop @@ -0,0 +1,144 @@ +[Desktop Action supportedDrivers] +Name=Supported Drivers +Name[ar]=المشغلات المدعومة +Name[ast]=Controladores sofitaos +Name[bg]=Поддържани драйвери +Name[bn]=সমর্থিত ড্রাইভার +Name[bs]=podržani drajveri +Name[ca]=Controladors acceptats +Name[ca@valencia]=Controladors acceptats +Name[cs]=Podporované ovladače +Name[csb]=Wspiéróné czérowniczi +Name[da]=Understøttede drivere +Name[de]=Unterstützte Treiber +Name[el]=Υποστηριζόμενοι οδηγοί +Name[en_GB]=Supported Drivers +Name[eo]=subtenataj Peliloj +Name[es]=Dispositivos soportados +Name[et]=Toetatud draiverid +Name[eu]=Onartutzen diren gidariak +Name[fi]=Tuetut ajurit +Name[fr]=Pilotes pris en charge +Name[fy]=Stipe stjoerprogramma's +Name[ga]=Tiománaithe a dTacaítear Leo +Name[gl]=Controladores soportados +Name[gu]=આધારિત ડ્રાઇવરો +Name[he]=מנהלי התקנים נתמכים +Name[hi]=समर्थित ड्राईवर +Name[hr]=Podržani pisači +Name[hu]=Támogatott meghajtók +Name[ia]=Drivers supportate +Name[id]=Penggerak Didukung +Name[is]=Studdir reklar +Name[it]=Driver supportati +Name[ja]=サポートされているドライバ +Name[kk]=Қолдайтын драйверлері +Name[km]=កម្មវិធី​បញ្ជា​ដែលបានគាំទ្រ +Name[kn]=ಬೆಂಬಲಿತ ಚಾಲಕಗಳು +Name[ko]=지원하는 드라이버 +Name[lt]=Palaikomos tvarkyklės +Name[lv]=Atbalstītie draiveri +Name[mai]=समर्थित ड्राइवर +Name[mk]=Поддржани управувачи +Name[ml]=പിന്തുണയുള്ള സാരഥികള്‍ +Name[mr]=समर्थीत ड्राइव्हर्स +Name[nb]=Støttede drivere +Name[nds]=Ünnerstütt Drievers +Name[nl]=Ondersteunde stuurprogramma's +Name[nn]=Støtta drivarar +Name[pa]=ਸਹਾਇਕ ਡਰਾਇਵਰ +Name[pl]=Obsługiwane sterowniki +Name[pt]=Controladores Suportados +Name[pt_BR]=Drivers suportados +Name[ro]=Drivere susținute +Name[ru]=Поддерживаемые драйверы +Name[si]=සහාය දක්වන ධාවක +Name[sk]=Podporované ovládače +Name[sl]=Podprti gonilniki +Name[sr]=подржани драјвери +Name[sr@ijekavian]=подржани драјвери +Name[sr@ijekavianlatin]=podržani drajveri +Name[sr@latin]=podržani drajveri +Name[sv]=Drivrutiner som stöds +Name[tg]=Дастгоҳҳои мувофиқ +Name[th]=ไดรเวอร์ที่รองรับ +Name[tr]=Desteklenen Sürücüler +Name[ug]=قوللايدىغان قوزغاتقۇلار +Name[uk]=Підтримувані драйвери +Name[wa]=Mineus sopoirtés +Name[x-test]=xxSupported Driversxx +Name[zh_CN]=支持的驱动 +Name[zh_TW]=支援的驅動程式 + +[Desktop Entry] +Actions=supportedDrivers; +Name=Solid Device +Name[ar]=جهاز في سوليد +Name[ast]=Preseos de Solid +Name[bn]=সলিড ডিভাইস +Name[bs]=uređaj pod Solidom +Name[ca]=Dispositiu del Solid +Name[ca@valencia]=Dispositiu del Solid +Name[cs]=Solid zařízení +Name[da]=Solid-enhed +Name[de]=Solid-Gerät +Name[el]=Συμπαγής συσκευή +Name[en_GB]=Solid Device +Name[eo]=Solid-aparatoj +Name[es]=Dispositivo de Solid +Name[et]=Solidi seade +Name[eu]=Solid gailua +Name[fi]=Kiinteä laite +Name[fr]=Périphérique Solid +Name[fy]=Solid apparaat +Name[ga]=Gléas Solid +Name[gl]=Dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ +Name[he]=התקן Solid +Name[hi]=सोलिड औज़ार +Name[hr]=Solid uređaj +Name[hu]=Solid eszköz +Name[ia]=Dispositivo Solid +Name[id]=Divais Solid +Name[is]=Solid tæki +Name[it]=Dispositivo di Solid +Name[ja]=Solid デバイス +Name[kk]=Solid құрылғысы +Name[km]=ឧបករណ៍​យូ​តាន់ +Name[kn]=ಘನ ಸಾಧನ +Name[ko]=Solid 장치 +Name[lt]=Solid įrenginys +Name[lv]=Solid ierīce +Name[mk]=Полупроводнички уред +Name[ml]=സോളിഡ് ഉപകരണം +Name[mr]=सॉलिड साधन +Name[nb]=Solid-enhet +Name[nds]=Solid-Reedschap +Name[nl]=Solid-apparaat +Name[nn]=Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ +Name[pl]=Urządzenie Solid +Name[pt]=Dispositivo do Solid +Name[pt_BR]=Dispositivo do Solid +Name[ro]=Dispozitiv Solid +Name[ru]=Устройство Solid +Name[si]=දෘඩ මෙවලම් +Name[sk]=Zariadenie Solid +Name[sl]=Naprava Solid +Name[sr]=уређај под Солидом +Name[sr@ijekavian]=уређај под Солидом +Name[sr@ijekavianlatin]=uređaj pod Solidom +Name[sr@latin]=uređaj pod Solidom +Name[sv]=Solid-enhet +Name[tg]=Дастгоҳҳои ҷудошаванда +Name[th]=อุปกรณ์ผ่าน Solid +Name[tr]=Solid Aygıtı +Name[ug]=Solid ئۈسكۈنە +Name[uk]=Пристрій Solid +Name[wa]=Éndjins Solid +Name[x-test]=xxSolid Devicexx +Name[zh_CN]=Solid 设备 +Name[zh_TW]=實體裝置 +Type=Service +X-KDE-ServiceTypes=SolidDevice +X-KDE-Solid-Actions-Type=Video diff --git a/solid-actions-kcm/solid-action-template.desktop b/solid-actions-kcm/solid-action-template.desktop new file mode 100644 index 00000000..7c322ff8 --- /dev/null +++ b/solid-actions-kcm/solid-action-template.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Actions=open; +Type=Service +X-KDE-Action-Custom=true +X-KDE-Solid-Predicate=[ IS StorageVolume AND StorageVolume.ignored == false ] + +[Desktop Action open] +Icon=unknown +Exec= diff --git a/solid-actions-kcm/solid-actions.desktop b/solid-actions-kcm/solid-actions.desktop new file mode 100644 index 00000000..97744c49 --- /dev/null +++ b/solid-actions-kcm/solid-actions.desktop @@ -0,0 +1,178 @@ +[Desktop Entry] +Exec=kcmshell4 solid-actions +Icon=system-run +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/solid-actions/index.html + +X-KDE-Library=kcm_solid_actions +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=hardware + +Name=Device Actions +Name[ar]=إجراءات الأجهزة +Name[ast]=Aiciones del preséu +Name[bg]=Действия за устройства +Name[bn]=ডিভাইস অ্যাকশন +Name[bs]=Radnje uređaja +Name[ca]=Accions de dispositiu +Name[ca@valencia]=Accions de dispositiu +Name[cs]=Činnosti zařízení +Name[csb]=Dzejanié ùrządzenia +Name[da]=Enhedshandlinger +Name[de]=Geräte-Aktionen +Name[el]=Ενέργειες συσκευής +Name[en_GB]=Device Actions +Name[eo]=Aparataj agoj +Name[es]=Acciones del dispositivo +Name[et]=Seadme toimingud +Name[eu]=Gailuaren ekintzak +Name[fi]=Laitetoiminnot +Name[fr]=Actions du périphérique +Name[fy]=Apparaat aksjes +Name[ga]=Gníomhartha Gléis +Name[gl]=Accións do dispositivo +Name[gu]=ઉપકરણ ક્રિયાઓ +Name[he]=פעולות התקן +Name[hi]=औजार क्रियाएँ +Name[hr]=Akcije uređaja +Name[hu]=Eszközműveletek +Name[ia]=Actiones de dispositivos +Name[id]=Aksi Divais +Name[is]=Aðgerðir tækis +Name[it]=Azioni dei dispositivi +Name[ja]=デバイスに対するアクション +Name[kk]=Құрылғы әрекеттері +Name[km]=សកម្មភាព​ឧបករណ៍ +Name[kn]=ಸಾಧನದ ಕ್ರಿಯೆಗಳು +Name[ko]=장치 동작 +Name[lt]=Įrenginių veiksmai +Name[lv]=Ierīces darbības +Name[mk]=Дејства за уреди +Name[ml]=ഉപകരണത്തിനുള്ള പ്രവൃത്തികള്‍ +Name[mr]=साधन क्रिया +Name[nb]=Enhetshandlinger +Name[nds]=Reedschap-Akschonen +Name[nl]=Apparaatacties +Name[nn]=Einingshandlingar +Name[pa]=ਜੰਤਰ ਐਕਸ਼ਨ +Name[pl]=Działania na urządzeniach +Name[pt]=Acções do Dispositivo +Name[pt_BR]=Ações do dispositivo +Name[ro]=Acțiuni dispozitiv +Name[ru]=Действия для устройств +Name[si]=මෙවලම් ක්‍රියා +Name[sk]=Akcie zariadenia +Name[sl]=Dejanja za napravo +Name[sr]=Радње уређаја +Name[sr@ijekavian]=Радње уређаја +Name[sr@ijekavianlatin]=Radnje uređaja +Name[sr@latin]=Radnje uređaja +Name[sv]=Enhetsåtgärder +Name[tg]=Амалҳои пештанзимшуда +Name[th]=การกระทำต่าง ๆ กับอุปกรณ์ +Name[tr]=Aygıt Eylemleri +Name[ug]=ئۈسكۈنە مەشغۇلاتى +Name[uk]=Дії з пристроями +Name[vi]=Hành động cho thiết bị +Name[wa]=Accions di l' éndjin +Name[x-test]=xxDevice Actionsxx +Name[zh_CN]=设备动作 +Name[zh_TW]=裝置動作 + +Comment=Manage actions available to the user when connecting new devices +Comment[bs]=Upravljanje radnjama dostupnim korisniku pri povezivanju novih uređaja na računar. +Comment[ca]=Gestiona les accions disponibles per a l'usuari en connectar dispositius nous +Comment[ca@valencia]=Gestiona les accions disponibles per a l'usuari en connectar dispositius nous +Comment[cs]=Spravovat činnosti dostupné pro uživatele při připojení nových zařízení +Comment[da]=Håndtér de handlinger som er tilgængelige for brugeren når nye enheder tilsluttes +Comment[de]=Einrichtung der Aktionen, die für den Anwender verfügbar sein sollen, wenn neue Geräte an den Rechner angeschlossen werden. +Comment[el]=Διαχείριση ενεργειών διαθέσιμων στο χρήστη κατά τη σύνδεση νέων συσκευών +Comment[en_GB]=Manage actions available to the user when connecting new devices +Comment[es]=Gestionar las acciones disponibles para el usuario cuando conecta nuevos dispositivos +Comment[et]=Toimingute haldamine, mida kasutaja saab tarvitada uue seadme ühendamisel arvutiga +Comment[eu]=kudeatu gailu berriak konektatzean erabiltzaileak erabilgarri dituen ekintzak +Comment[fi]=Hallitse toimintoja, jotka ovat käyttäjän valittavissa, kun uusia laitteita kytketään +Comment[fr]=Gère les actions disponibles pour l'utilisateur lors de la connexion de nouveaux périphériques +Comment[ga]=Bainistigh na gníomhartha atá ar fáil don úsáideoir agus gléasanna nua á gceangal +Comment[gl]=Xestiona as accións dispoñíbeis para o usuario cando se conecten novos dispositivos +Comment[he]=מנהל פעילויות זמונית למשתמש בעת חיבור של התקנים חדשים +Comment[hu]=Új eszköz csatlakoztatásakor a felhasználónak elérhető műveletek kezelése +Comment[ia]=Gerer actiones disponibile al usator quando il connecte nove dispositivos al computator +Comment[is]=Stillingatól fyrir þær aðgerðir sem verða í boði fyrir notanda þegar ný tæki eru tengd við tölvuna +Comment[it]=Gestisci le azioni disponibili all'utente quando si collegano nuovi dispositivi +Comment[kk]=Жаңа құрылғыларды қосқанда қол жетерлік басқару амалдары +Comment[ko]=새 장치를 연결했을 때 표시할 동작을 관리합니다 +Comment[lt]=Tvarkyti veiksmus pasiekiamus naudotojui kai prijungiami nauji įrenginiai +Comment[mr]=नवीन साधने जोडल्यावर वापरकर्त्यास उपलब्ध असलेल्या क्रियांचे व्यवस्थापन करा +Comment[nb]=Håndter handlingene som er tilgjengelige for brukeren når nye enheter kobles til datamaskinen +Comment[nds]=Akschonen plegen, de för Brukers praatstaht, wenn nieg Reedschappen den Reekner tokoppelt warrt +Comment[nl]=Beheren van acties die beschikbaar zijn voor de gebruiker bij het aankoppelen van nieuwe apparaten +Comment[pa]=ਯੂਜ਼ਰ ਨੂੰ ਮਿਲਣ ਵਾਲੀਆਂ ਕਾਰਵਾਈਆਂ ਦਾ ਪਰਬੰਧ, ਜਦੋਂ ਨਵੇਂ ਜੰਤਰ ਕੁਨੈਕਟ ਕੀਤੇ ਜਾਂਦੇ ਹਨ +Comment[pl]=Zdecyduj o dostępnych dla użytkownika działaniach przy podłączaniu nowego urządzenia +Comment[pt]=Gerir as acções disponíveis para o utilizador, quando são ligados dispositivos novos ao computador +Comment[pt_BR]=Gerencia as ações disponíveis ao conectar novos dispositivos +Comment[ro]=Gestionează acțiunile oferite utilizatorului la conectarea noilor dispozitive +Comment[ru]=Настройка предлагаемых пользователю действий при подключении устройств +Comment[sk]=Spravovať akcie dostupné aktuálnemu používateľovi pri pripájaní nových zariadení +Comment[sl]=Upravljajte dejanja, ki so na voljo uporabniku, ko se priključi nova naprava +Comment[sr]=Одредите радње доступне кориснику при повезивању нових уређаја +Comment[sr@ijekavian]=Одредите радње доступне кориснику при повезивању нових уређаја +Comment[sr@ijekavianlatin]=Odredite radnje dostupne korisniku pri povezivanju novih uređaja +Comment[sr@latin]=Odredite radnje dostupne korisniku pri povezivanju novih uređaja +Comment[sv]=Hantera tillgängliga åtgärder för användare när nya enheter ansluts +Comment[tr]=Bilgisayara yeni bir aygıt takıldığında kullanıcı tarafından kullanılabilecek eylemleri yönet +Comment[uk]=Керування діями, доступними користувачеві після з’єднання пристроїв з комп’ютером +Comment[x-test]=xxManage actions available to the user when connecting new devicesxx +Comment[zh_CN]=管理当新设备连接时的系统动作 +Comment[zh_TW]=管理新增裝置到電腦時要做些什麼動作 + +X-KDE-Keywords=Solid Devices Actions +X-KDE-Keywords[bs]=Akcije čvrstih uređaja +X-KDE-Keywords[ca]=Accions de dispositiu del Solid +X-KDE-Keywords[ca@valencia]=Accions de dispositiu del Solid +X-KDE-Keywords[cs]=Činnosti zařízení Solid +X-KDE-Keywords[da]=Solid enhedshandlinger +X-KDE-Keywords[de]=Solid-Geräte-Aktionen +X-KDE-Keywords[el]=Ενέργειες συσκευής Solid +X-KDE-Keywords[en_GB]=Solid Devices Actions +X-KDE-Keywords[es]=Acciones de dispositivos Solid +X-KDE-Keywords[et]=Solidi seadmete toimingud +X-KDE-Keywords[eu]=Solid gailuen ekintzak +X-KDE-Keywords[fi]=solid, laitetoiminnot +X-KDE-Keywords[fr]=Actions du périphérique Solid +X-KDE-Keywords[ga]=Gníomhartha Gléasanna Solid +X-KDE-Keywords[gl]=Accións do dispositivo Solid +X-KDE-Keywords[he]=פעולות התקן של Solid +X-KDE-Keywords[hu]=Solid eszközműveletek +X-KDE-Keywords[ia]=Actiones de dispositivos solid +X-KDE-Keywords[is]=Aðgerðir Solid-tækja +X-KDE-Keywords[it]=Azioni dei dispositivi Solid +X-KDE-Keywords[kk]=Solid Devices Actions +X-KDE-Keywords[km]=សកម្មភាព​ឧបករណ៍​រឹង +X-KDE-Keywords[ko]=Solid 장치 동작 +X-KDE-Keywords[lt]=Solid įrenginių veiksmai +X-KDE-Keywords[lv]=Solid ierīces darbības +X-KDE-Keywords[mr]=सॉलिड साधन क्रिया +X-KDE-Keywords[nb]=Solid enhetshandlinger +X-KDE-Keywords[nds]=Solid,Reedschappen,Akschonen +X-KDE-Keywords[nl]=Solid-apparaatacties +X-KDE-Keywords[pa]=ਸਾਲਡ ਜੰਤਰ ਐਕਸ਼ਨ +X-KDE-Keywords[pl]=Działania na urządzeniach Solid +X-KDE-Keywords[pt]=Acções do Dispositivo Solid +X-KDE-Keywords[pt_BR]=Ações do dispositivo Solid +X-KDE-Keywords[ro]=Acțiuni dispozitiv Solid +X-KDE-Keywords[ru]=Действия для устройств Solid +X-KDE-Keywords[sk]=Akcie zariadení Solid +X-KDE-Keywords[sl]=solid,naprave,dejanja,strojna oprema +X-KDE-Keywords[sr]=Solid Devices Actions,Солидове радње над уређајима +X-KDE-Keywords[sr@ijekavian]=Solid Devices Actions,Солидове радње над уређајима +X-KDE-Keywords[sr@ijekavianlatin]=Solid Devices Actions,Solidove radnje nad uređajima +X-KDE-Keywords[sr@latin]=Solid Devices Actions,Solidove radnje nad uređajima +X-KDE-Keywords[sv]=Solid enhetsåtgärder +X-KDE-Keywords[tr]=Solid Aygıt Eylemleri +X-KDE-Keywords[uk]=solid,пристрій,пристрої,дія,дії +X-KDE-Keywords[x-test]=xxSolid Devices Actionsxx +X-KDE-Keywords[zh_CN]=Solid Devices Actions,设备动作 +X-KDE-Keywords[zh_TW]=Solid Devices Actions diff --git a/solid-actions-kcm/solid-device-type.desktop b/solid-actions-kcm/solid-device-type.desktop new file mode 100644 index 00000000..9997e1f4 --- /dev/null +++ b/solid-actions-kcm/solid-device-type.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=SolidDevice +Name=Solid Device Type +Name[ar]=نوع الجهاز في سوليد +Name[ast]=Triba de preséu de Solid +Name[bn]=সলিড ডিভাইস টাইপ +Name[bs]=tip uređaja pod Solidom +Name[ca]=Tipus de dispositiu del Solid +Name[ca@valencia]=Tipus de dispositiu del Solid +Name[cs]=Typ zařízení Solid +Name[da]=Solid enhedstype +Name[de]=Solid-Gerätetyp +Name[el]=Τύπος συμπαγής συσκευής +Name[en_GB]=Solid Device Type +Name[eo]=Solid Aparata Tipo +Name[es]=Tipo de dispositivo de Solid +Name[et]=Solidi seadme tüüp +Name[eu]=Solid gailu mota +Name[fi]=Kiintolaitetyyppi +Name[fr]=Type de périphérique Solid +Name[fy]=Solid apparaat type +Name[ga]=Cineál Gléis Solid +Name[gl]=Tipo do dispositivo de Solid +Name[gu]=સોલિડ ઉપકરણ પ્રકાર +Name[he]=סוג התקן Solid +Name[hi]=सोलिड औज़ार प्रकार +Name[hr]=Vrsta Solid uređaja +Name[hu]=Solid eszköztípus +Name[ia]=Typo de dispositivo de Solid +Name[id]=Tipe Divais Solid +Name[is]=Tegund Solid-tækis +Name[it]=Tipo di dispositivo Solid +Name[ja]=Solid デバイスのタイプ +Name[kk]=Solid құрылғысының түрі +Name[km]=ប្រភេទ​ឧបករណ៍​តាន់ +Name[kn]=ಘನ(ಸಾಲಿಡ್) ಸಾಧನ ಬಗೆ +Name[ko]=Solid 장치 종류 +Name[lt]=Solid įrenginio tipas +Name[lv]=Solid ierīces tips +Name[mk]=Полупроводнички тип на уред +Name[ml]=സോളിഡ് ഉപകരണതരം +Name[mr]=सॉलिड साधन प्रकार +Name[nb]=Type solid-enhet +Name[nds]=Solid-Reedschaptyp +Name[nl]=Solid-apparaattype +Name[nn]=Type Solid-eining +Name[pa]=ਸਾਲਡ ਜੰਤਰ ਕਿਸਮ +Name[pl]=Typ urządzenia Solid +Name[pt]=Tipo de Dispositivo do Solid +Name[pt_BR]=Tipo de dispositivo do Solid +Name[ro]=Tip dispozitiv solid +Name[ru]=Тип устройства Solid +Name[si]=දෘඩ මෙවලම් වර්‍ගය +Name[sk]=Typ zariadenia Solid +Name[sl]=Vrsta naprave Solid +Name[sr]=тип уређаја под Солидом +Name[sr@ijekavian]=тип уређаја под Солидом +Name[sr@ijekavianlatin]=tip uređaja pod Solidom +Name[sr@latin]=tip uređaja pod Solidom +Name[sv]=Solid-enhetstyp +Name[tg]=Намуди дастгоҳи ҷудошаванда +Name[th]=ประเภทอุปกรณ์ของ Solid +Name[tr]=Solid Aygıtı Tipi +Name[ug]=Solid ئۈسكۈنە تىپى +Name[uk]=Тип пристрою Solid +Name[wa]=Sôre d' éndjin Solid +Name[x-test]=xxSolid Device Typexx +Name[zh_CN]=Solid 设备类型 +Name[zh_TW]=實體裝置類型 diff --git a/startkde.cmake b/startkde.cmake new file mode 100644 index 00000000..afc2cfb8 --- /dev/null +++ b/startkde.cmake @@ -0,0 +1,405 @@ +#!/bin/sh +# +# DEFAULT KDE STARTUP SCRIPT ( @KDE4WORKSPACE_VERSION@ ) +# + +if test "x$1" = x--failsafe; then + KDE_FAILSAFE=1 # General failsafe flag + KWIN_COMPOSE=N # Disable KWin's compositing + export KWIN_COMPOSE KDE_FAILSAFE +fi + +# When the X server dies we get a HUP signal from xinit. We must ignore it +# because we still need to do some cleanup. +trap 'echo GOT SIGHUP' HUP + +# we have to unset this for Darwin since it will screw up KDE's dynamic-loading +unset DYLD_FORCE_FLAT_NAMESPACE + +# in case we have been started with full pathname spec without being in PATH +bindir=`echo "$0" | sed -n 's,^\(/.*\)/[^/][^/]*$,\1,p'` +if [ -n "$bindir" ]; then + qbindir=`$bindir/kde4-config --qt-binaries` + qdbus=$qbindir/qdbus + case $PATH in + $bindir|$bindir:*|*:$bindir|*:$bindir:*) ;; + *) PATH=$bindir:$PATH; export PATH;; + esac +else + qdbus=qdbus +fi + +# Check if a KDE session already is running and whether it's possible to connect to X +kcheckrunning +kcheckrunning_result=$? +if test $kcheckrunning_result -eq 0 ; then + echo "KDE seems to be already running on this display." + xmessage -geometry 500x100 "KDE seems to be already running on this display." > /dev/null 2>/dev/null + exit 1 +elif test $kcheckrunning_result -eq 2 ; then + echo "\$DISPLAY is not set or cannot connect to the X server." + exit 1 +fi + +# Boot sequence: +# +# kdeinit is used to fork off processes which improves memory usage +# and startup time. +# +# * kdeinit starts klauncher first. +# * Then kded is started. kded is responsible for keeping the sycoca +# database up to date. When an up to date database is present it goes +# into the background and the startup continues. +# * Then kdeinit starts kcminit. kcminit performs initialisation of +# certain devices according to the user's settings +# +# * Then ksmserver is started which takes control of the rest of the startup sequence + +# The user's personal KDE directory is usually ~/.kde, but this setting +# may be overridden by setting KDEHOME. + +kdehome=$HOME/@KDE_DEFAULT_HOME@ +test -n "$KDEHOME" && kdehome=`echo "$KDEHOME"|sed "s,^~/,$HOME/,"` + +# see kstartupconfig source for usage +mkdir -m 700 -p $kdehome +mkdir -m 700 -p $kdehome/share +mkdir -m 700 -p $kdehome/share/config +cat >$kdehome/share/config/startupconfigkeys </env/*.sh and /env/*.sh +# (where is $KDEHOME or ~/.kde, and is where KDE is installed) +# +# This is where you can define environment variables that will be available to +# all KDE programs, so this is where you can run agents using e.g. eval `ssh-agent` +# or eval `gpg-agent --daemon`. +# Note: if you do that, you should also put "ssh-agent -k" as a shutdown script +# +# (see end of this file). +# For anything else (that doesn't set env vars, or that needs a window manager), +# better use the Autostart folder. + +libpath=`kde4-config --path lib | tr : '\n'` + +for prefix in `echo "$libpath" | sed -n -e 's,/lib[^/]*/,/env/,p'`; do + for file in "$prefix"*.sh; do + test -r "$file" && . "$file" + done +done + +# Set the path for Qt plugins provided by KDE +QT_PLUGIN_PATH=${QT_PLUGIN_PATH+$QT_PLUGIN_PATH:}`kde4-config --path qtplugins` +export QT_PLUGIN_PATH + +# Activate the kde font directories. +# +# There are 4 directories that may be used for supplying fonts for KDE. +# +# There are two system directories. These belong to the administrator. +# There are two user directories, where the user may add her own fonts. +# +# The 'override' versions are for fonts that should come first in the list, +# i.e. if you have a font in your 'override' directory, it will be used in +# preference to any other. +# +# The preference order looks like this: +# user override, system override, X, user, system +# +# Where X is the original font database that was set up before this script +# runs. + +usr_odir=$HOME/.fonts/kde-override +usr_fdir=$HOME/.fonts + +if test -n "$KDEDIRS"; then + kdedirs_first=`echo "$KDEDIRS"|sed -e 's/:.*//'` + sys_odir=$kdedirs_first/share/fonts/override + sys_fdir=$kdedirs_first/share/fonts +else + sys_odir=$KDEDIR/share/fonts/override + sys_fdir=$KDEDIR/share/fonts +fi + +# We run mkfontdir on the user's font dirs (if we have permission) to pick +# up any new fonts they may have installed. If mkfontdir fails, we still +# add the user's dirs to the font path, as they might simply have been made +# read-only by the administrator, for whatever reason. + +test -d "$sys_odir" && xset +fp "$sys_odir" +test -d "$usr_odir" && (mkfontdir "$usr_odir" ; xset +fp "$usr_odir") +test -d "$usr_fdir" && (mkfontdir "$usr_fdir" ; xset fp+ "$usr_fdir") +test -d "$sys_fdir" && xset fp+ "$sys_fdir" + +# Ask X11 to rebuild its font list. +xset fp rehash + +# Set a left cursor instead of the standard X11 "X" cursor, since I've heard +# from some users that they're confused and don't know what to do. This is +# especially necessary on slow machines, where starting KDE takes one or two +# minutes until anything appears on the screen. +# +# If the user has overwritten fonts, the cursor font may be different now +# so don't move this up. +# +xsetroot -cursor_name left_ptr + +# Get Ghostscript to look into user's KDE fonts dir for additional Fontmap +if test -n "$GS_LIB" ; then + GS_LIB=$usr_fdir:$GS_LIB + export GS_LIB +else + GS_LIB=$usr_fdir + export GS_LIB +fi + +lnusertemp=`kde4-config --path exe --locate lnusertemp` +if test -z "$lnusertemp"; then + # Startup error + echo 'startkde: ERROR: Could not locate lnusertemp in '`kde4-config --path exe` 1>&2 +fi + +# Link "tmp" "socket" and "cache" resources to directory in /tmp +# Creates: +# - a directory /tmp/kde-$USER and links $KDEHOME/tmp-$HOSTNAME to it. +# - a directory /tmp/ksocket-$USER and links $KDEHOME/socket-$HOSTNAME to it. +# - a directory /var/tmp/kdecache-$USER and links $KDEHOME/cache-$HOSTNAME to it. +# Note: temporary locations can be overriden through the KDETMP and KDEVARTMP +# environment variables +for resource in tmp cache socket; do + if "$lnusertemp" $resource >/dev/null; then + : # ok + else + echo 'startkde: Call to lnusertemp failed (temporary directories full?). Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + xmessage -geometry 600x100 "Call to lnusertemp failed (temporary directories full?). Check your installation." + exit 1 + fi +done + +# In case of dcop sockets left by a previous session, cleanup +#dcopserver_shutdown + +echo 'startkde: Starting up...' 1>&2 + +# Make sure that the KDE prefix is first in XDG_DATA_DIRS and that it's set at all. +# The spec allows XDG_DATA_DIRS to be not set, but X session startup scripts tend +# to set it to a list of paths *not* including the KDE prefix if it's not /usr or +# /usr/local. +if test -z "$XDG_DATA_DIRS"; then + XDG_DATA_DIRS="@SHARE_INSTALL_PREFIX@:/usr/share:/usr/local/share" +else + XDG_DATA_DIRS="@SHARE_INSTALL_PREFIX@:$XDG_DATA_DIRS" +fi +export XDG_DATA_DIRS + +# Make sure that D-Bus is running +# D-Bus autolaunch is broken +if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then + eval `dbus-launch --sh-syntax --exit-with-session` +fi +if $qdbus >/dev/null 2>/dev/null; then + : # ok +else + echo 'startkde: Could not start D-Bus. Can you call qdbus?' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + xmessage -geometry 500x100 "Could not start D-Bus. Can you call qdbus?" + exit 1 +fi + + +# Mark that full KDE session is running (e.g. Konqueror preloading works only +# with full KDE running). The KDE_FULL_SESSION property can be detected by +# any X client connected to the same X session, even if not launched +# directly from the KDE session but e.g. using "ssh -X", kdesu. $KDE_FULL_SESSION +# however guarantees that the application is launched in the same environment +# like the KDE session and that e.g. KDE utilities/libraries are available. +# KDE_FULL_SESSION property is also only available since KDE 3.5.5. +# The matching tests are: +# For $KDE_FULL_SESSION: +# if test -n "$KDE_FULL_SESSION"; then ... whatever +# For KDE_FULL_SESSION property: +# xprop -root | grep "^KDE_FULL_SESSION" >/dev/null 2>/dev/null +# if test $? -eq 0; then ... whatever +# +# Additionally there is (since KDE 3.5.7) $KDE_SESSION_UID with the uid +# of the user running the KDE session. It should be rarely needed (e.g. +# after sudo to prevent desktop-wide functionality in the new user's kded). +# +# Since KDE4 there is also KDE_SESSION_VERSION, containing the major version number. +# Note that this didn't exist in KDE3, which can be detected by its absense and +# the presence of KDE_FULL_SESSION. +# +KDE_FULL_SESSION=true +export KDE_FULL_SESSION +xprop -root -f KDE_FULL_SESSION 8t -set KDE_FULL_SESSION true + +KDE_SESSION_VERSION=4 +export KDE_SESSION_VERSION +xprop -root -f KDE_SESSION_VERSION 32c -set KDE_SESSION_VERSION 4 + +KDE_SESSION_UID=`id -ru` +export KDE_SESSION_UID + +XDG_CURRENT_DESKTOP=KDE +export XDG_CURRENT_DESKTOP + +# At this point all the environment is ready, let's send it to kwalletd if running +if test -n "$PAM_KWALLET_LOGIN" ; then + env | socat STDIN UNIX-CONNECT:$PAM_KWALLET_LOGIN +fi + +# We set LD_BIND_NOW to increase the efficiency of kdeinit. +# kdeinit unsets this variable before loading applications. +LD_BIND_NOW=true @KDE4_LIBEXEC_INSTALL_DIR@/start_kdeinit_wrapper +kcminit_startup +if test $? -ne 0; then + # Startup error + echo 'startkde: Could not start kdeinit4. Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + xmessage -geometry 500x100 "Could not start kdeinit4. Check your installation." + exit 1 +fi + +# finally, give the session control to the session manager +# see kdebase/ksmserver for the description of the rest of the startup sequence +# if the KDEWM environment variable has been set, then it will be used as KDE's +# window manager instead of kwin. +# if KDEWM is not set, ksmserver will ensure kwin is started. +# kwrapper4 is used to reduce startup time and memory usage +# kwrapper4 does not return useful error codes such as the exit code of ksmserver. +# We only check for 255 which means that the ksmserver process could not be +# started, any problems thereafter, e.g. ksmserver failing to initialize, +# will remain undetected. +test -n "$KDEWM" && KDEWM="--windowmanager $KDEWM" +# If the session should be locked from the start (locked autologin), +# lock now and do the rest of the KDE startup underneath the locker. +KSMSERVEROPTIONS="" +test -n "$dl" && KSMSERVEROPTIONS=" --lockscreen" +kwrapper4 ksmserver $KDEWM $KSMSERVEROPTIONS +if test $? -eq 255; then + # Startup error + echo 'startkde: Could not start ksmserver. Check your installation.' 1>&2 + test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + xmessage -geometry 500x100 "Could not start ksmserver. Check your installation." +fi + +wait_drkonqi=`kreadconfig --file startkderc --group WaitForDrKonqi --key Enabled --default true` + +if test x"$wait_drkonqi"x = x"true"x ; then + # wait for remaining drkonqi instances with timeout (in seconds) + wait_drkonqi_timeout=`kreadconfig --file startkderc --group WaitForDrKonqi --key Timeout --default 900` + wait_drkonqi_counter=0 + while $qdbus | grep "^[^w]*org.kde.drkonqi" > /dev/null ; do + sleep 5 + wait_drkonqi_counter=$((wait_drkonqi_counter+5)) + if test "$wait_drkonqi_counter" -ge "$wait_drkonqi_timeout" ; then + # ask remaining drkonqis to die in a graceful way + $qdbus | grep 'org.kde.drkonqi-' | while read address ; do + $qdbus "$address" "/MainApplication" "quit" + done + break + fi + done +fi + +echo 'startkde: Shutting down...' 1>&2 +# just in case +test -n "$ksplash_pid" && kill "$ksplash_pid" 2>/dev/null + +# Clean up +kdeinit4_shutdown +# KDE3 support +kde3 kdeinit_shutdown 2>/dev/null +kde3 dcopserver_shutdown --wait 2>/dev/null + +echo 'startkde: Running shutdown scripts...' 1>&2 + +# Run scripts found in $KDEDIRS/shutdown +for prefix in `echo "$libpath" | sed -n -e 's,/lib[^/]*/,/shutdown/,p'`; do + for file in `ls "$prefix" 2> /dev/null | egrep -v '(~|\.bak)$'`; do + test -x "$prefix$file" && "$prefix$file" + done +done + +unset KDE_FULL_SESSION +xprop -root -remove KDE_FULL_SESSION +unset KDE_SESSION_VERSION +xprop -root -remove KDE_SESSION_VERSION +unset KDE_SESSION_UID + +echo 'startkde: Done.' 1>&2 diff --git a/statusnotifierwatcher/CMakeLists.txt b/statusnotifierwatcher/CMakeLists.txt new file mode 100644 index 00000000..308841e8 --- /dev/null +++ b/statusnotifierwatcher/CMakeLists.txt @@ -0,0 +1,26 @@ +project(StatusNotifierWatcher) + +set(kded_statusnotifierwatcher_SRCS statusnotifierwatcher.cpp ) + +QT4_ADD_DBUS_ADAPTOR(kded_statusnotifierwatcher_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.StatusNotifierWatcher.xml + statusnotifierwatcher.h StatusNotifierWatcher) + + +set(statusnotifieritem_xml ${KDE4_DBUS_INTERFACES_DIR}/org.kde.StatusNotifierItem.xml) +set_source_files_properties(${statusnotifieritem_xml} PROPERTIES + NO_NAMESPACE false + INCLUDE "systemtraytypedefs.h" + CLASSNAME OrgKdeStatusNotifierItemInterface +) +QT4_ADD_DBUS_INTERFACE(kded_statusnotifierwatcher_SRCS ${statusnotifieritem_xml} statusnotifieritem_interface) + +kde4_add_plugin(kded_statusnotifierwatcher ${kded_statusnotifierwatcher_SRCS}) + + +target_link_libraries(kded_statusnotifierwatcher ${KDE4_KIO_LIBS} ) + +install(TARGETS kded_statusnotifierwatcher DESTINATION ${PLUGIN_INSTALL_DIR}) + + +install( FILES statusnotifierwatcher.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded) + diff --git a/statusnotifierwatcher/statusnotifierwatcher.cpp b/statusnotifierwatcher/statusnotifierwatcher.cpp new file mode 100644 index 00000000..ef3e32b7 --- /dev/null +++ b/statusnotifierwatcher/statusnotifierwatcher.cpp @@ -0,0 +1,148 @@ +/*************************************************************************** + * Copyright 2009 by Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "statusnotifierwatcher.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include "statusnotifierwatcheradaptor.h" +#include "statusnotifieritem_interface.h" +#include + + +static inline KAboutData aboutData() +{ + return KAboutData("statusnotifierwatcher", 0, ki18n("statusnotifierwatcher"), WORKSPACE_VERSION_STRING); +} + +K_PLUGIN_FACTORY(StatusNotifierWatcherFactory, + registerPlugin(); + ) +K_EXPORT_PLUGIN(StatusNotifierWatcherFactory(aboutData())) + +StatusNotifierWatcher::StatusNotifierWatcher(QObject *parent, const QList&) + : KDEDModule(parent) +{ + setModuleName("StatusNotifierWatcher"); + new StatusNotifierWatcherAdaptor(this); + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerService("org.kde.StatusNotifierWatcher"); + dbus.registerObject("/StatusNotifierWatcher", this); + + m_serviceWatcher = new QDBusServiceWatcher(this); + m_serviceWatcher->setConnection(dbus); + m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + + connect(m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(serviceUnregistered(QString))); +} + +StatusNotifierWatcher::~StatusNotifierWatcher() +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.unregisterService("org.kde.StatusNotifierWatcher"); +} + + +void StatusNotifierWatcher::RegisterStatusNotifierItem(const QString &serviceOrPath) +{ + QString service; + QString path; + if (serviceOrPath.startsWith('/')) { + service = message().service(); + path = serviceOrPath; + } else { + service = serviceOrPath; + path = "/StatusNotifierItem"; + } + QString notifierItemId = service + path; + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() && + !m_registeredServices.contains(notifierItemId)) { + kDebug()<<"Registering" << notifierItemId << "to system tray"; + + //check if the service has registered a SystemTray object + org::kde::StatusNotifierItem trayclient(service, path, + QDBusConnection::sessionBus()); + if (trayclient.isValid()) { + m_registeredServices.append(notifierItemId); + m_serviceWatcher->addWatchedService(service); + emit StatusNotifierItemRegistered(notifierItemId); + } + } +} + +QStringList StatusNotifierWatcher::RegisteredStatusNotifierItems() const +{ + return m_registeredServices; +} + + +void StatusNotifierWatcher::serviceUnregistered(const QString& name) +{ + kDebug()<<"Service "<< name << "unregistered"; + m_serviceWatcher->removeWatchedService(name); + + QString match = name + '/'; + QStringList::Iterator it = m_registeredServices.begin(); + while (it != m_registeredServices.end()) { + if (it->startsWith(match)) { + QString name = *it; + it = m_registeredServices.erase(it); + emit StatusNotifierItemUnregistered(name); + } else { + ++it; + } + } + + if (m_statusNotifierHostServices.contains(name)) { + m_statusNotifierHostServices.remove(name); + emit StatusNotifierHostUnregistered(); + } +} + +void StatusNotifierWatcher::RegisterStatusNotifierHost(const QString &service) +{ + if (service.contains("org.kde.StatusNotifierHost-") && + QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() && + !m_statusNotifierHostServices.contains(service)) { + kDebug()<<"Registering"<addWatchedService(service); + emit StatusNotifierHostRegistered(); + } +} + +bool StatusNotifierWatcher::IsStatusNotifierHostRegistered() const +{ + return !m_statusNotifierHostServices.isEmpty(); +} + +int StatusNotifierWatcher::ProtocolVersion() const +{ + return 0; +} + +#include "statusnotifierwatcher.moc" diff --git a/statusnotifierwatcher/statusnotifierwatcher.desktop b/statusnotifierwatcher/statusnotifierwatcher.desktop new file mode 100644 index 00000000..bfb66731 --- /dev/null +++ b/statusnotifierwatcher/statusnotifierwatcher.desktop @@ -0,0 +1,128 @@ +[Desktop Entry] +Type=Service +Name=Status Notifier Manager +Name[ar]=مدير تنبيهات الحالة +Name[ast]=Xestor del notificador del estáu +Name[bn]=স্ট্যাটাস বিজ্ঞপ্তি ম্যানেজার +Name[bs]=Menadžer izveštavača o stanju +Name[ca]=Gestor del notificador d'estat +Name[ca@valencia]=Gestor del notificador d'estat +Name[cs]=Správce oznamování stavu +Name[da]=Håndtering af statusbekendtgørelser +Name[de]=Statusbenachrichtigungs-Verwaltung +Name[el]=Διαχειριστής των ειδοποιήσεων κατάστασης +Name[en_GB]=Status Notifier Manager +Name[es]=Gestor del notificador del estado +Name[et]=Oleku märguannete haldur +Name[eu]=Egoera-jakinarazlearen kudeatzailea +Name[fi]=Tilailmoittimen hallinta +Name[fr]=Gestionnaire du notificateur d'état +Name[gl]=Xestor das notificacións de estado +Name[he]=מנהל שירותי הודעות מצב +Name[hi]=स्थिति संकेत प्रबंधक +Name[hr]=Upravitelj glasnika stanja +Name[hu]=Állapotértesítés-kezelő +Name[ia]=Gerente de notificator de stato +Name[id]=Manajer Notifikasi Status +Name[is]=Stöðutilkynningaþjónn +Name[it]=Gestore del notificatore di stato +Name[ja]=ステータス通知マネージャ +Name[kk]=Күй-жайы туралы құлақтандырғыш менеджері +Name[km]=កម្មវិធី​គ្រប់គ្រង​ធាតុជូន​ដំណឹង​អំពី​ស្ថានភាព +Name[kn]= ಸ್ಥಿತಿ ಸೂಚನಾ ವ್ಯವಸ್ಥಾಪಕ +Name[ko]=상태 알림 관리자 +Name[lt]=Būsenos pranešimų valdymas +Name[lv]=Statusa paziņojumu pārvaldītājs +Name[mr]=स्थिती निदर्शक व्यवस्थापक +Name[nb]=Håndtering av statusvarsler +Name[nds]=Statusbescheed-Beluern +Name[nl]=Statusmeldingenbeheerder +Name[pa]=ਹਾਲਤ ਨੋਟੀਫਾਇਰ ਮੈਨੇਜਰ +Name[pl]=Zarządzanie powiadomieniami o stanie +Name[pt]=Gestor das Notificações de Estado +Name[pt_BR]=Gerenciador de notificações de status +Name[ro]=Gestionar notificator de stare +Name[ru]=Диспетчер уведомлений о состоянии +Name[si]=තත්ව දැන්වීමේ කළමනාකරු +Name[sk]=Správca oznámení stavu +Name[sl]=Upravljalnik obvestilnika o stanju +Name[sr]=Менаџер извештавача о стању +Name[sr@ijekavian]=Менаџер извјештавача о стању +Name[sr@ijekavianlatin]=Menadžer izvještavača o stanju +Name[sr@latin]=Menadžer izveštavača o stanju +Name[sv]=Hantering av statusunderrättelser +Name[tg]=Мудири ҳолатҳои система +Name[th]=ตัวจัดการการแจ้งสถานะให้ทราบ +Name[tr]=Durum Bildirim Yöneticisi +Name[ug]=ھالەت بىلدۈرگۈ باشقۇرغۇچ +Name[uk]=Керування сповіщенням про стан +Name[wa]=Manaedjeu do notifiaedje d' estat +Name[x-test]=xxStatus Notifier Managerxx +Name[zh_CN]=状态通知管理器 +Name[zh_TW]=狀態通知管理員 +Comment=Manages services that provide status notifier user interfaces +Comment[ar]=أدر الخدمات التي توفر واجهات المستخدم لمنبّهات الحالة +Comment[ast]=Xestiona servicios qu'ufren interfaces d'usuariu pal notificador d'estáu +Comment[bs]=Upravljanje servisima koji pružaju sučelje izveštavača o stanju +Comment[ca]=Gestiona serveis que proporcionen notificacions d'estat a les interfícies d'usuari +Comment[ca@valencia]=Gestiona serveis que proporcionen notificacions d'estat a les interfícies d'usuari +Comment[cs]=Nastavení služeb poskytujících rozhraní pro oznamování stavu +Comment[da]=Håndterer tjenester der giver brugerflader til statusbekendtgørelser +Comment[de]=Verwaltet Dienste, die eine Schnittstelle für Status-Informationen bereitstellen +Comment[el]=Διαχειρίζεται υπηρεσίες που παρέχουν περιβάλλοντα χρήστη για τις ειδοποιήσεις κατάστασης +Comment[en_GB]=Manages services that provide status notifier user interfaces +Comment[es]=Gestiona servicios que proporcionan interfaces de usuario para el notificador de estado +Comment[et]=Teenuste haldamine, mis pakuvad olekumärguannete kasutajaliidest +Comment[eu]=Egora-jakinarazlerako erabiltzaile-interfazeak hornitzen dituen zerbitzuak kudeatzen ditu +Comment[fi]=Hallitsee palveluja, jotka tarjoavat tilailmoitinkäyttöliittymät +Comment[fr]=Gère les services fournissant des interfaces utilisateurs pour la notification d'état +Comment[gl]=Xestiona servizos que fornecen interfaces de usuario para o notificador de estado +Comment[he]=ניהול שירותים המספקים ממשקי משתמש להודעות מצב +Comment[hr]=Upravlja uslugama koje omogućuju obavještavanje o stanju korisničkog sučelja +Comment[hu]=Kezeli az állapotértesítést nyújtó szolgáltatásokat +Comment[ia]=Il gere servicios que forni interfacies de usator pro notificator de stato +Comment[id]=Atur layanan yang menyediakan notifikasi status antarmuka pengguna +Comment[is]=Stjórnar þjónustum sem sjá um stöðutilkynningar notendaviðmóta +Comment[it]=Gestisce i servizi che forniscono interfacce utente al notificatore di stato +Comment[ja]=ステータス通知ユーザインターフェースを提供するサービスを管理 +Comment[kk]=Күй-жайы туралы құлақтандыру интерфейсін қамтамасыз ететін қызметін басқару +Comment[km]=គ្រប់គ្រង​សារ​ដែល​ផ្ដល់​កម្មវិធី​​ជូនដំណឹង​អំពី​ស្ថានភាព​ចំណុច​ប្រទាក់​អ្នកប្រើ +Comment[kn]=ಸ್ಥಿತಿಯನ್ನು ಸೂಚಿಸುವ ಬಳಕೆದಾರ ಸಂಪರ್ಕಸಾಧನಗಳನ್ನು ಒದಗಿಸುವ ಸೇವೆಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ +Comment[ko]=상태 알림 인터페이스를 제공하는 서비스를 관리합니다 +Comment[lt]=Valdo tarnybas, teikiančias būsenos pranešimų naudotojo sąsajas +Comment[lv]=Pārvalda servisus, kas sniedz statusa paziņojumu lietotāja saskarni +Comment[mr]=स्थितीबाबत सूचना दैणाऱ्या सेवांचे व्यवस्थापन करतो +Comment[nb]=Håndterer tjenester som tilbyr brukerflater for statusvarsler +Comment[nds]=Deensten plegen, de Statusbescheed-Brukerkoppelsteden praatstellt +Comment[nl]=Beheert services die statusmeldingen leveren aan gebruikersinterfaces +Comment[pa]=ਸਰਵਿਸਾਂ ਦਾ ਪਰਬੰਧ ਕਰਦਾ ਹੈ, ਜੋ ਕਿ ਹਾਲਤ ਨੋਟੀਫਾਇਰ ਯੂਜ਼ਰ ਇੰਟਰਫੇਸ ਦਿੰਦਾ ਹੈ +Comment[pl]=Zarządza usługami, które udostępniają interfejs użytkownika powiadomień o stanie +Comment[pt]=Faz a gestão dos serviços que fornecem interface de notificação do estado +Comment[pt_BR]=Gerencia os serviços que fornecem interfaces de notificação do status +Comment[ro]=Administrează serviciile care furnizează interfețe utilizator pentru notificări de stare +Comment[ru]=Управление службами интерфейсов уведомлений о состоянии +Comment[si]=පරිශීලක අතුරු මුහුණත් වලට තත්ව දැනුම් දීම් සපයන සේවා කළමනාකරනය කරයි +Comment[sk]=Spravuje služby, ktoré poskytujú užívateľské rozhrania pre oznámenie stavu +Comment[sl]=Upravlja s storitvami, ki ponujajo uporabniške vmesnike obvestilnika o stanju +Comment[sr]=Управљање сервисима који пружају сучеље извештавача о стању +Comment[sr@ijekavian]=Управљање сервисима који пружају сучеље извјештавача о стању +Comment[sr@ijekavianlatin]=Upravljanje servisima koji pružaju sučelje izvještavača o stanju +Comment[sr@latin]=Upravljanje servisima koji pružaju sučelje izveštavača o stanju +Comment[sv]=Hanterar tjänster som tillhandahåller användargränssnitt för statusunderrättelser +Comment[th]=จัดการบริการต่าง ๆ ที่แจ้งสถานะมาให้ผู้ใช้รับทราบ +Comment[tr]=Durum bildirimi kullanıcı arayüzünü sunan servisleri yönetir +Comment[ug]=ھالەت بىلدۈرگۈ ئىشلەتكۈچى ئارايۈزىنى تەمىنلەشنى باشقۇرۇش مۇلازىمىتى +Comment[uk]=Керує службами інтерфейсів користувача для сповіщення про стан +Comment[vi]=Quản lý các dịch vụ cung cấp thông báo trạng thái +Comment[wa]=Manaedje les siervices ki dnèt ls eterfaces uzeu d' notifiaedje di l' estat +Comment[x-test]=xxManages services that provide status notifier user interfacesxx +Comment[zh_CN]=状态通知协议的管理服务 +Comment[zh_TW]=管理提供狀態通知使用者介面的服務 + +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=statusnotifierwatcher +X-KDE-DBus-ModuleName=statusnotifierwatcher +X-KDE-Kded-autoload=true +X-KDE-Kded-load-on-demand=false +X-KDE-Kded-phase=1 + diff --git a/statusnotifierwatcher/statusnotifierwatcher.h b/statusnotifierwatcher/statusnotifierwatcher.h new file mode 100644 index 00000000..290f194f --- /dev/null +++ b/statusnotifierwatcher/statusnotifierwatcher.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright 2009 by Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef STATUSNOTIFIERWATCHER_H +#define STATUSNOTIFIERWATCHER_H + +#include + +#include +#include +#include +#include + +class QDBusServiceWatcher; + +class StatusNotifierWatcher : public KDEDModule, protected QDBusContext +{ + Q_OBJECT + Q_PROPERTY(QStringList RegisteredStatusNotifierItems READ RegisteredStatusNotifierItems) + Q_PROPERTY(bool IsStatusNotifierHostRegistered READ IsStatusNotifierHostRegistered) + Q_PROPERTY(int ProtocolVersion READ ProtocolVersion) + +public: + StatusNotifierWatcher(QObject *parent, const QList&); + ~StatusNotifierWatcher(); + + QStringList RegisteredStatusNotifierItems() const; + + bool IsStatusNotifierHostRegistered() const; + + int ProtocolVersion() const; + +public Q_SLOTS: + void RegisterStatusNotifierItem(const QString &service); + + void RegisterStatusNotifierHost(const QString &service); + +protected Q_SLOTS: + void serviceUnregistered(const QString& name); + +Q_SIGNALS: + void StatusNotifierItemRegistered(const QString &service); + //TODO: decide if this makes sense, the systray itself could notice the vanishing of items, but looks complete putting it here + void StatusNotifierItemUnregistered(const QString &service); + void StatusNotifierHostRegistered(); + void StatusNotifierHostUnregistered(); + +private: + QDBusServiceWatcher *m_serviceWatcher; + QStringList m_registeredServices; + QSet m_statusNotifierHostServices; +}; +#endif diff --git a/statusnotifierwatcher/systemtraytypedefs.h b/statusnotifierwatcher/systemtraytypedefs.h new file mode 100644 index 00000000..20e63044 --- /dev/null +++ b/statusnotifierwatcher/systemtraytypedefs.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * * + * Copyright (C) 2009 Marco Martin * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYTYPEDEFS_H +#define SYSTEMTRAYTYPEDEFS_H + +#include +#include +#include + +struct KDbusImageStruct { + int width; + int height; + QByteArray data; +}; + +typedef QVector KDbusImageVector; + +struct KDbusToolTipStruct { + QString icon; + KDbusImageVector image; + QString title; + QString subTitle; +}; + +Q_DECLARE_METATYPE(KDbusImageStruct) +Q_DECLARE_METATYPE(KDbusImageVector) +Q_DECLARE_METATYPE(KDbusToolTipStruct) + +#endif + diff --git a/systemsettings/CMakeLists.txt b/systemsettings/CMakeLists.txt new file mode 100644 index 00000000..f448eb63 --- /dev/null +++ b/systemsettings/CMakeLists.txt @@ -0,0 +1,17 @@ +PROJECT(systemsettings) + +IF(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + + FIND_PACKAGE(KDE4 REQUIRED) + INCLUDE(KDE4Defaults) + ADD_DEFINITIONS(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) + +ENDIF(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + +INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR}/core ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}) + +ADD_SUBDIRECTORY(core) +ADD_SUBDIRECTORY(app) +ADD_SUBDIRECTORY(categories) +ADD_SUBDIRECTORY(classic) +ADD_SUBDIRECTORY(icons) diff --git a/systemsettings/Mainpage.dox b/systemsettings/Mainpage.dox new file mode 100644 index 00000000..b812113d --- /dev/null +++ b/systemsettings/Mainpage.dox @@ -0,0 +1,7 @@ +/** @mainpage System Settings interface + * This is a collection of standard plugin interfaces to System Settings. + */ + +// DOXYGEN_ENABLE = YES +// DOXYGEN_SET_PROJECT_NAME = System Settings +// DOXYGEN_SET_EXCLUDE_PATTERNS += */app/* */icons/* */classic/* diff --git a/systemsettings/Messages.sh b/systemsettings/Messages.sh new file mode 100644 index 00000000..4ca6099f --- /dev/null +++ b/systemsettings/Messages.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC `find . -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp +$XGETTEXT `find . -name \*.cpp` -o $podir/systemsettings.pot +rm -f rc.cpp diff --git a/systemsettings/app/BaseConfig.kcfgc b/systemsettings/app/BaseConfig.kcfgc new file mode 100644 index 00000000..e420cdf9 --- /dev/null +++ b/systemsettings/app/BaseConfig.kcfgc @@ -0,0 +1,5 @@ +File=systemsettings.kcfg +ClassName=BaseConfig +Singleton=true +Mutators=true +SetUserTexts=true diff --git a/systemsettings/app/CMakeLists.txt b/systemsettings/app/CMakeLists.txt new file mode 100644 index 00000000..2a44e49b --- /dev/null +++ b/systemsettings/app/CMakeLists.txt @@ -0,0 +1,22 @@ +include_directories( ToolTips ) + +SET( systemsettings_SRCS + SystemSettingsApp.cpp + SettingsBase.cpp + ToolTips/ktooltip.cpp + ToolTips/ktooltipwindow.cpp + ToolTips/tooltipmanager.cpp + main.cpp ) + +KDE4_ADD_APP_ICON( systemsettings_SRCS "${KDE4_ICON_INSTALL_DIR}/oxygen/*/categories/preferences-system.png" ) +KDE4_ADD_UI_FILES( systemsettings_SRCS configDialog.ui ) +KDE4_ADD_KCFG_FILES( systemsettings_SRCS BaseConfig.kcfgc ) +QT4_ADD_DBUS_ADAPTOR( systemsettings_SRCS org.kde.systemsettings.xml SystemSettingsApp.h SystemSettingsApp ) + +KDE4_ADD_EXECUTABLE( systemsettings ${systemsettings_SRCS}) + +TARGET_LINK_LIBRARIES( systemsettings ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KCMUTILS_LIBS} systemsettingsview ) + +INSTALL( TARGETS systemsettings ${INSTALL_TARGETS_DEFAULT_ARGS} ) +INSTALL( FILES systemsettingsui.rc systemsettings.kcfg DESTINATION ${DATA_INSTALL_DIR}/systemsettings ) +INSTALL( PROGRAMS kdesystemsettings.desktop systemsettings.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) diff --git a/systemsettings/app/SettingsBase.cpp b/systemsettings/app/SettingsBase.cpp new file mode 100644 index 00000000..74ccd4f8 --- /dev/null +++ b/systemsettings/app/SettingsBase.cpp @@ -0,0 +1,401 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#include "SettingsBase.h" +#include "BaseConfig.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BaseData.h" +#include "ModuleView.h" + +SettingsBase::SettingsBase( QWidget * parent ) + : KXmlGuiWindow(parent) +{ + // Ensure delayed loading doesn't cause a crash + activeView = 0; + aboutDialog = 0; + configDialog = 0; + lostFound = 0; + // Prepare the view area + stackedWidget = new QStackedWidget( this ); + setCentralWidget(stackedWidget); + setWindowFlags( windowFlags() | Qt::WindowContextHelpButtonHint ); + // Initialise search + searchText = new KLineEdit( this ); + searchText->setClearButtonShown( true ); + searchText->setClickMessage( i18nc( "Search through a list of control modules", "Search" ) ); + searchText->setCompletionMode( KGlobalSettings::CompletionPopup ); + + spacerWidget = new QWidget( this ); + spacerWidget->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Maximum ); + // Initalise the window so we don't flicker + initToolBar(); + // We can now launch the delayed loading safely + QTimer::singleShot(0, this, SLOT(initApplication())); +} + +SettingsBase::~SettingsBase() +{ + delete rootModule; +} + +QSize SettingsBase::sizeHint() const +{ + return QSize(720, 600); +} + +void SettingsBase::initApplication() +{ + // Prepare the menu of all modules + categories = KServiceTypeTrader::self()->query("SystemSettingsCategory"); + modules = KServiceTypeTrader::self()->query("KCModule", "[X-KDE-System-Settings-Parent-Category] != ''"); + modules += KServiceTypeTrader::self()->query("SystemSettingsExternalApp"); + rootModule = new MenuItem( true, 0 ); + initMenuList(rootModule); + // Handle lost+found modules... + if (lostFound) { + for (int i = 0; i < modules.size(); ++i) { + const KService::Ptr entry = modules.at(i); + MenuItem * infoItem = new MenuItem(false, lostFound); + infoItem->setService( entry ); + kDebug() << "Added " << entry->name(); + } + } + + // Prepare the Base Data + BaseData::instance()->setMenuItem( rootModule ); + // Load all possible views + const KService::List pluginObjects = KServiceTypeTrader::self()->query( "SystemSettingsView" ); + const int nbPlugins = pluginObjects.count(); + for( int pluginsDone = 0; pluginsDone < nbPlugins ; ++pluginsDone ) { + KService::Ptr activeService = pluginObjects.at( pluginsDone ); + QString error; + BaseMode * controller = activeService->createInstance(this, QVariantList(), &error); + if( error.isEmpty() ) { + possibleViews.insert( activeService->library(), controller ); + controller->init( activeService ); + connect(controller, SIGNAL(changeToolBarItems(BaseMode::ToolBarItems)), this, SLOT(changeToolBar(BaseMode::ToolBarItems))); + connect(controller, SIGNAL(actionsChanged()), this, SLOT(updateViewActions())); + connect(searchText, SIGNAL(textChanged(QString)), controller, SLOT(searchChanged(QString))); + connect(controller, SIGNAL(viewChanged(bool)), this, SLOT(viewChange(bool))); + } else { + kWarning() << "View load error: " + error; + } + } + searchText->completionObject()->setIgnoreCase( true ); + searchText->completionObject()->setItems( BaseData::instance()->menuItem()->keywords() ); + changePlugin(); +} + +void SettingsBase::initToolBar() +{ + // Fill the toolbar with default actions + // Exit is the very last action + quitAction = actionCollection()->addAction( KStandardAction::Quit, "quit_action", this, SLOT(close()) ); + // Configure goes at the end + configureAction = actionCollection()->addAction( KStandardAction::Preferences, this, SLOT(configShow()) ); + configureAction->setShortcut(KShortcut(QKeySequence(Qt::CTRL + Qt::Key_M))); + configureAction->setText( i18n("Configure") ); + // Help after it + initHelpMenu(); + // Then a spacer so the search line-edit is kept separate + spacerAction = new KAction( this ); + spacerAction->setDefaultWidget(spacerWidget); + actionCollection()->addAction( "spacer", spacerAction ); + // Finally the search line-edit + searchAction = new KAction( this ); + searchAction->setDefaultWidget(searchText); + searchAction->setShortcut(KShortcut(QKeySequence(Qt::CTRL + Qt::Key_F))); + connect( searchAction, SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)), + searchText, SLOT(setFocus())); + actionCollection()->addAction( "searchText", searchAction ); + // Initialise the Window + setupGUI(Save|Create,QString()); + menuBar()->hide(); + // Toolbar & Configuration + helpActionMenu->setMenu( dynamic_cast( factory()->container("help", this) ) ); + setMinimumSize(620,430); + toolBar()->setMovable(false); // We don't allow any changes + changeToolBar( BaseMode::Search | BaseMode::Configure | BaseMode::Quit ); +} + +void SettingsBase::initHelpMenu() +{ + helpActionMenu = new KActionMenu( KIcon("system-help"), i18n("Help"), this ); + helpActionMenu->setDelayed( false ); + actionCollection()->addAction( "help_toolbar_menu", helpActionMenu ); + // Add the custom actions + aboutModuleAction = actionCollection()->addAction( KStandardAction::AboutApp, "help_about_module", this, SLOT(about()) ); + changeAboutMenu( 0, aboutModuleAction, i18n("About Active Module") ); + aboutViewAction = actionCollection()->addAction( KStandardAction::AboutApp, "help_about_view", this, SLOT(about()) ); +} + +void SettingsBase::initConfig() +{ + // Prepare dialog first + configDialog = new KConfigDialog( this, "systemsettingsconfig", BaseConfig::self() ); + configDialog->setButtons( KDialog::Ok | KDialog::Cancel ); + + // Add our page + QWidget * configPage = new QWidget( configDialog ); + configWidget.setupUi(configPage); + QString iconName = KGlobal::activeComponent().aboutData()->programIconName(); + configDialog->addPage( configPage, i18nc("General config for System Settings", "General"), iconName ); + QVBoxLayout * configLayout = new QVBoxLayout; + // Get the list of modules + foreach( BaseMode * mode, possibleViews ) { + mode->addConfiguration( configDialog ); + QRadioButton * radioButton = new QRadioButton( mode->service()->name(), configWidget.GbViewStyle ); + radioButton->setIcon( KIcon(mode->service()->icon()) ); + configLayout->addWidget( radioButton ); + viewSelection.addButton( radioButton, possibleViews.values().indexOf(mode) ); + } + configWidget.GbViewStyle->setLayout( configLayout ); + configDialog->restoreDialogSize( KGlobal::config()->group("ConfigDialog") ); + connect(configDialog, SIGNAL(okClicked()), this, SLOT(configUpdated())); +} + + +void SettingsBase::initMenuList(MenuItem * parent) +{ + // look for any categories inside this level, and recurse into them + for (int i = 0; i < categories.size(); ++i) { + const KService::Ptr entry = categories.at(i); + const QString parentCategory = entry->property("X-KDE-System-Settings-Parent-Category").toString(); + const QString parentCategory2 = entry->property("X-KDE-System-Settings-Parent-Category-V2").toString(); + if ( parentCategory == parent->category() || + // V2 entries must not be empty if they want to become a proper category. + ( !parentCategory2.isEmpty() && parentCategory2 == parent->category() ) ) { + MenuItem * menuItem = new MenuItem(true, parent); + menuItem->setService( entry ); + if( menuItem->category() == "lost-and-found" ) { + lostFound = menuItem; + continue; + } + initMenuList( menuItem ); + } + } + + KService::List removeList; + + // scan for any modules at this level and add them + for (int i = 0; i < modules.size(); ++i) { + const KService::Ptr entry = modules.at(i); + const QString category = entry->property("X-KDE-System-Settings-Parent-Category").toString(); + const QString category2 = entry->property("X-KDE-System-Settings-Parent-Category-V2").toString(); + if( !parent->category().isEmpty() && (category == parent->category() || category2 == parent->category()) ) { + // Add the module info to the menu + MenuItem * infoItem = new MenuItem(false, parent); + infoItem->setService( entry ); + removeList.append( modules.at(i) ); + } + } + + for (int i = 0; i < removeList.size(); ++i) { + modules.removeOne( removeList.at(i) ); + } + + parent->sortChildrenByWeight(); +} + +void SettingsBase::configUpdated() +{ + KConfigGroup dialogConfig = KGlobal::config()->group("ConfigDialog"); + configDialog->saveDialogSize( dialogConfig ); + BaseConfig::setActiveView( possibleViews.keys().at(viewSelection.checkedId()) ); + BaseConfig::setShowToolTips( configWidget.ChTooltips->isChecked() ); + activeView->saveConfiguration(); + changePlugin(); +} + +void SettingsBase::configShow() +{ + // Initialise the configuration dialog if it hasn't already + if( !configDialog ) { + initConfig(); + } + if( activeView && activeView->moduleView() && !activeView->moduleView()->resolveChanges() ) { + return; // It shouldn't be triggering anyway, since the action is disabled + } + + activeView->loadConfiguration(); + + const QStringList pluginList = possibleViews.keys(); + const int configIndex = pluginList.indexOf( BaseConfig::activeView() ); + if( configIndex != -1 ) { + viewSelection.button( configIndex )->setChecked(true); + } + configWidget.ChTooltips->setChecked( BaseConfig::showToolTips() ); + if( pluginList.isEmpty() ) { + KMessageBox::error(this, i18n("System Settings was unable to find any views, and hence nothing is available to configure."), i18n("No views found")); + } else { + configDialog->show(); + } +} + +bool SettingsBase::queryClose() +{ + bool changes = true; + if( activeView ) { + activeView->saveState(); + changes = activeView->moduleView()->resolveChanges(); + } + BaseConfig::self()->writeConfig(); + return changes; +} + +void SettingsBase::about() +{ + delete aboutDialog; + aboutDialog = 0; + + const KAboutData * about = 0; + if( sender() == aboutViewAction ) { + about = activeView->aboutData(); + } else if( sender() == aboutModuleAction && activeView->moduleView() ) { + about = activeView->moduleView()->aboutData(); + } + + if( about ) { + aboutDialog = new KAboutApplicationDialog(about, 0); + aboutDialog->show(); + } +} + +void SettingsBase::changePlugin() +{ + if( possibleViews.count() == 0 ) { // We should ensure we have a plugin available to choose + KMessageBox::error(this, i18n("System Settings was unable to find any views, and hence has nothing to display."), i18n("No views found")); + close(); + return; // Halt now! + } + + if( activeView ) { + activeView->saveState(); + activeView->leaveModuleView(); + } + + const QString viewToUse = BaseConfig::activeView(); + if( possibleViews.keys().contains(viewToUse) ) { // First the configuration entry + activeView = possibleViews.value(viewToUse); + } + else { // Otherwise we activate the failsafe + activeView = possibleViews.begin().value(); + } + + if( stackedWidget->indexOf(activeView->mainWidget()) == -1 ) { + stackedWidget->addWidget(activeView->mainWidget()); + } + + // Handle the tooltips + qDeleteAll( tooltipManagers ); + tooltipManagers.clear(); + if ( BaseConfig::showToolTips() ) { + QList theViews = activeView->views(); + foreach ( QAbstractItemView* view, theViews ) { + tooltipManagers << new ToolTipManager( view ); + } + } + + changeAboutMenu( activeView->aboutData(), aboutViewAction, i18n("About Active View") ); + viewChange(false); + + stackedWidget->setCurrentWidget(activeView->mainWidget()); + updateViewActions(); + + activeView->giveFocus(); +} + +void SettingsBase::viewChange(bool state) +{ + KCModuleInfo * moduleInfo = activeView->moduleView()->activeModule(); + configureAction->setDisabled(state); + if( moduleInfo ) { + setCaption( moduleInfo->moduleName(), state ); + } else { + setCaption( QString(), state ); + } + changeAboutMenu( activeView->moduleView()->aboutData(), aboutModuleAction, i18n("About Active Module") ); +} + +void SettingsBase::updateViewActions() +{ + guiFactory()->unplugActionList( this, "viewActions" ); + guiFactory()->plugActionList( this, "viewActions", activeView->actionsList() ); +} + +void SettingsBase::changeToolBar( BaseMode::ToolBarItems toolbar ) +{ + if( sender() != activeView ) { + return; + } + guiFactory()->unplugActionList( this, "configure" ); + guiFactory()->unplugActionList( this, "search" ); + guiFactory()->unplugActionList( this, "quit" ); + if ( BaseMode::Search & toolbar ) { + QList searchBarActions; + searchBarActions << spacerAction << searchAction; + guiFactory()->plugActionList( this, "search", searchBarActions ); + } + if ( BaseMode::Configure & toolbar ) { + QList configureBarActions; + configureBarActions << configureAction; + guiFactory()->plugActionList( this, "configure", configureBarActions ); + } + if ( BaseMode::Quit & toolbar ) { + QList quitBarActions; + quitBarActions << quitAction; + guiFactory()->plugActionList( this, "quit", quitBarActions ); + } +} + +void SettingsBase::changeAboutMenu( const KAboutData * menuAbout, KAction * menuItem, QString fallback ) +{ + if( !menuItem ) { + return; + } + + if( menuAbout ) { + menuItem->setText( i18n( "About %1", menuAbout->programName() ) ); + menuItem->setIcon( KIcon( menuAbout->programIconName() ) ); + menuItem->setEnabled(true); + } else { + menuItem->setText( fallback ); + menuItem->setIcon( KIcon( KGlobal::activeComponent().aboutData()->programIconName() ) ); + menuItem->setEnabled(false); + } +} + +#include "SettingsBase.moc" diff --git a/systemsettings/app/SettingsBase.h b/systemsettings/app/SettingsBase.h new file mode 100644 index 00000000..e1bd27f6 --- /dev/null +++ b/systemsettings/app/SettingsBase.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ben Cooksley * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + ***************************************************************************/ + +#ifndef SETTINGS_BASE_H +#define SETTINGS_BASE_H + +#include "MenuItem.h" +#include "BaseMode.h" +#include "tooltipmanager.h" +#include "ui_configDialog.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +class SettingsBase : public KXmlGuiWindow +{ + Q_OBJECT + +public: + explicit SettingsBase(QWidget * parent = 0); + ~SettingsBase(); + bool queryClose(); + +protected: + virtual QSize sizeHint() const; + +private slots: + void initApplication(); + void initToolBar(); + void initHelpMenu(); + void initConfig(); + void initMenuList(MenuItem * parent); + void configUpdated(); + void configShow(); + void about(); + void changePlugin(); + void viewChange(bool state); + void updateViewActions(); + void changeToolBar( BaseMode::ToolBarItems toolbar ); + void changeAboutMenu( const KAboutData * menuAbout, KAction * menuItem, QString fallback ); + +private: + // The plugins + QMap possibleViews; + QList tooltipManagers; + BaseMode * activeView; + // The search bar + KLineEdit * searchText; + QWidget * spacerWidget; + // The toolbar + KAction * searchAction; + KAction * spacerAction; + KAction * configureAction; + KAction * quitAction; + // The help menu + KAction * aboutViewAction; + KAction * aboutModuleAction; + KActionMenu * helpActionMenu; + // The configuration + KConfigDialog * configDialog; + Ui::ConfigDialog configWidget; + QButtonGroup viewSelection; + // The control module + QStackedWidget * stackedWidget; + // The module list + MenuItem * rootModule; + MenuItem * lostFound; + KService::List categories; + KService::List modules; + // The about dialog + KAboutApplicationDialog * aboutDialog; +}; +#endif diff --git a/systemsettings/app/SystemSettingsApp.cpp b/systemsettings/app/SystemSettingsApp.cpp new file mode 100644 index 00000000..2efceba8 --- /dev/null +++ b/systemsettings/app/SystemSettingsApp.cpp @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2009 Ben Cooksley + * + * 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 library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "SystemSettingsApp.h" + +SystemSettingsApp::SystemSettingsApp() + : KUniqueApplication() +{ + window = 0; +} + +SystemSettingsApp::~SystemSettingsApp() +{ +} + +void SystemSettingsApp::setMainWindow(SettingsBase * main) +{ + window = main; +} + +void SystemSettingsApp::quit() +{ + if( window ) { + if( !window->queryClose() ) { + return; + } + } + KUniqueApplication::quit(); +} + +#include "SystemSettingsApp.moc" diff --git a/systemsettings/app/SystemSettingsApp.h b/systemsettings/app/SystemSettingsApp.h new file mode 100644 index 00000000..466d88b6 --- /dev/null +++ b/systemsettings/app/SystemSettingsApp.h @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2009 Ben Cooksley + * + * 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 library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/** + * Any changes to this header file need to have the following command executed afterwards to regenerate the dbus interface + * qdbuscpp2xml SystemSettingsApp.h -o org.kde.systemsettings.xml + */ + +#ifndef SYSTEMSETTINGSAPP_H +#define SYSTEMSETTINGSAPP_H + +#include + +#include "SettingsBase.h" + +class SystemSettingsApp : public KUniqueApplication +{ + Q_OBJECT + +public: + SystemSettingsApp(); + ~SystemSettingsApp(); + + void setMainWindow(SettingsBase * main); + +public Q_SLOTS: + Q_SCRIPTABLE void quit(); + +private: + SettingsBase * window; +}; + +#endif diff --git a/systemsettings/app/ToolTips/ktooltip.cpp b/systemsettings/app/ToolTips/ktooltip.cpp new file mode 100644 index 00000000..99114106 --- /dev/null +++ b/systemsettings/app/ToolTips/ktooltip.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2008 by Fredrik Höglund * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "ktooltip.h" +#include "ktooltipwindow_p.h" +#include +#include +#include + +class KToolTipManager +{ +public: + ~KToolTipManager(); + + static KToolTipManager* instance(); + + void showTip(const QPoint& pos, QWidget* content); + void hideTip(); + +private: + KToolTipManager(); + + KToolTipWindow* m_window; + static KToolTipManager *s_instance; +}; + +KToolTipManager *KToolTipManager::s_instance = 0; + +KToolTipManager::KToolTipManager() : + m_window(0) +{ +} + +KToolTipManager::~KToolTipManager() +{ + delete m_window; + m_window = 0; +} + +KToolTipManager* KToolTipManager::instance() +{ + if (s_instance == 0) { + s_instance = new KToolTipManager(); + } + + return s_instance; +} + +void KToolTipManager::showTip(const QPoint& pos, QWidget* content) +{ + hideTip(); + Q_ASSERT(m_window == 0); + m_window = new KToolTipWindow(content); + m_window->move(pos); + m_window->show(); +} + +void KToolTipManager::hideTip() +{ + if (m_window != 0) { + m_window->hide(); + m_window->deleteLater(); + m_window = 0; + } +} + +namespace KToolTip +{ + void showText(const QPoint& pos, const QString& text) + { + QLabel* label = new QLabel(text); + label->setForegroundRole(QPalette::ToolTipText); + showTip(pos, label); + } + + void showTip(const QPoint& pos, QWidget* content) + { + KToolTipManager::instance()->showTip(pos, content); + } + + void hideTip() + { + KToolTipManager::instance()->hideTip(); + } +} + diff --git a/systemsettings/app/ToolTips/ktooltip.h b/systemsettings/app/ToolTips/ktooltip.h new file mode 100644 index 00000000..bd539b83 --- /dev/null +++ b/systemsettings/app/ToolTips/ktooltip.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2008 by Fredrik Höglund * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KTOOLTIP_H +#define KTOOLTIP_H + +class QPoint; +class QString; +class QWidget; + +/** + * Allows to show tooltips having a widget as content. + */ +namespace KToolTip +{ + void showText(const QPoint& pos, const QString& text); + + /** + * Shows the tip @p content at the global position indicated by @p pos. + * + * Ownership of the content widget is transferred to KToolTip. The widget will be deleted + * automatically when it is hidden. + * + * The tip is shown immediately when this function is called. + */ + void showTip(const QPoint& pos, QWidget* content); + void hideTip(); +} + +#endif diff --git a/systemsettings/app/ToolTips/ktooltipwindow.cpp b/systemsettings/app/ToolTips/ktooltipwindow.cpp new file mode 100644 index 00000000..fdff9862 --- /dev/null +++ b/systemsettings/app/ToolTips/ktooltipwindow.cpp @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2008 by Fredrik Höglund * + * Copyright (C) 2008 by Konstantin Heil * + * Copyright (C) 2009 by Peter Penz * + * Copyright (C) 2012 by Mark Gaiser * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + *******************************************************************************/ + +#include "ktooltipwindow_p.h" + +#include +#include +#include +#include + +// For the blurred tooltip background +#include + +KToolTipWindow::KToolTipWindow(QWidget* content) : + QWidget(0) +{ + setAttribute(Qt::WA_TranslucentBackground); + setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addWidget(content); +} + +KToolTipWindow::~KToolTipWindow() +{ +} + +void KToolTipWindow::paintEvent(QPaintEvent* event) +{ + QStylePainter painter(this); + QStyleOptionFrame option; + option.init(this); + painter.drawPrimitive(QStyle::PE_PanelTipLabel, option); + painter.end(); + + QWidget::paintEvent(event); +} + +void KToolTipWindow::showEvent(QShowEvent *) +{ + Plasma::WindowEffects::overrideShadow(winId(), true); + Plasma::WindowEffects::enableBlurBehind(winId(), true, mask()); +} + +#include "ktooltipwindow_p.moc" diff --git a/systemsettings/app/ToolTips/ktooltipwindow_p.h b/systemsettings/app/ToolTips/ktooltipwindow_p.h new file mode 100644 index 00000000..4ffe22ba --- /dev/null +++ b/systemsettings/app/ToolTips/ktooltipwindow_p.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2009 by Peter Penz * + * Copyright (C) 2012 by Mark Gaiser * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef KTOOLTIPWINDOW_H +#define KTOOLTIPWINDOW_H + +#include +class QPaintEvent; + +class KToolTipWindow : public QWidget +{ + Q_OBJECT + +public: + explicit KToolTipWindow(QWidget* content); + virtual ~KToolTipWindow(); + +protected: + virtual void paintEvent(QPaintEvent* event); + virtual void showEvent(QShowEvent *); +}; + +#endif diff --git a/systemsettings/app/ToolTips/tooltipmanager.cpp b/systemsettings/app/ToolTips/tooltipmanager.cpp new file mode 100644 index 00000000..2046b09b --- /dev/null +++ b/systemsettings/app/ToolTips/tooltipmanager.cpp @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (C) 2008 by Konstantin Heil * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + *******************************************************************************/ + +#include "tooltipmanager.h" + +#include "MenuItem.h" + +#include "ktooltip.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_X11 +#include +#endif + +#include +#include +#include + +class ToolTipManager::Private +{ +public: + Private() : + view(0), + timer(0) + { } + + QAbstractItemView* view; + QTimer* timer; + QModelIndex item; + QRect itemRect; +}; + +ToolTipManager::ToolTipManager(QAbstractItemView* parent) + : QObject(parent) + , d(new ToolTipManager::Private) +{ + d->view = parent; + + connect(parent, SIGNAL(viewportEntered()), this, SLOT(hideToolTip())); + connect(parent, SIGNAL(entered(QModelIndex)), this, SLOT(requestToolTip(QModelIndex))); + + d->timer = new QTimer(this); + d->timer->setSingleShot(true); + connect(d->timer, SIGNAL(timeout()), this, SLOT(prepareToolTip())); + + // When the mousewheel is used, the items don't get a hovered indication + // (Qt-issue #200665). To assure that the tooltip still gets hidden, + // the scrollbars are observed. + connect(parent->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip())); + connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip())); + + d->view->viewport()->installEventFilter(this); +} + +ToolTipManager::~ToolTipManager() +{ + delete d; +} + +bool ToolTipManager::eventFilter(QObject* watched, QEvent* event) +{ + if ( watched == d->view->viewport() ) { + switch ( event->type() ) { + case QEvent::Leave: + case QEvent::MouseButtonPress: + hideToolTip(); + break; + case QEvent::ToolTip: + return true; + default: + break; + } + } + + return QObject::eventFilter(watched, event); +} + +void ToolTipManager::requestToolTip(const QModelIndex& index) +{ + // only request a tooltip for the name column and when no selection or + // drag & drop operation is done (indicated by the left mouse button) + if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { + KToolTip::hideTip(); + + d->itemRect = d->view->visualRect(index); + const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); + d->itemRect.moveTo(pos); + d->item = index; + d->timer->start(300); + } else { + hideToolTip(); + } +} + +void ToolTipManager::hideToolTip() +{ + d->timer->stop(); + KToolTip::hideTip(); +} + +void ToolTipManager::prepareToolTip() +{ + showToolTip( d->item ); +} + +void ToolTipManager::showToolTip( QModelIndex menuItem ) +{ + if (QApplication::mouseButtons() & Qt::LeftButton) { + return; + } + + QWidget * tip = createTipContent( menuItem ); + + // calculate the x- and y-position of the tooltip + const QSize size = tip->sizeHint(); + const QRect desktop = QApplication::desktop()->screenGeometry( d->itemRect.bottomRight() ); + + // d->itemRect defines the area of the item, where the tooltip should be + // shown. Per default the tooltip is shown in the bottom right corner. + // If the tooltip content exceeds the desktop borders, it must be assured that: + // - the content is fully visible + // - the content is not drawn inside d->itemRect + const int margin = 3; + const bool hasRoomToLeft = (d->itemRect.left() - size.width() - margin >= desktop.left()); + const bool hasRoomToRight = (d->itemRect.right() + size.width() + margin <= desktop.right()); + const bool hasRoomAbove = (d->itemRect.top() - size.height() - margin >= desktop.top()); + const bool hasRoomBelow = (d->itemRect.bottom() + size.height() + margin <= desktop.bottom()); + if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { + delete tip; + tip = 0; + return; + } + + int x = 0; + int y = 0; + if (hasRoomBelow || hasRoomAbove) { + x = qMax(desktop.left(), d->itemRect.center().x() - size.width() / 2); + if (x + size.width() / 2 >= desktop.right()) { + x = desktop.right() - size.width(); + } + + y = hasRoomBelow ? d->itemRect.bottom() + margin : d->itemRect.top() - size.height() - margin; + } else { + Q_ASSERT(hasRoomToLeft || hasRoomToRight); + x = hasRoomToRight ? d->itemRect.right() + margin : d->itemRect.left() - size.width() - margin; + + // Put the tooltip at the bottom of the screen. The x-coordinate has already + // been adjusted, so that no overlapping with d->itemRect occurs. + y = desktop.bottom() - size.height(); + } + + // the ownership of tip is transferred to KToolTip + KToolTip::showTip(QPoint(x, y), tip); +} + +QWidget * ToolTipManager::createTipContent( QModelIndex item ) +{ + const QSize dialogIconSize = QSize(IconSize(KIconLoader::Dialog), IconSize(KIconLoader::Dialog)); + const QSize toolbarIconSize = QSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar)); + + QWidget * tipContent = new QWidget(); + QGridLayout* tipLayout = new QGridLayout(); + + QLayout * primaryLine = generateToolTipLine( &item, tipContent, dialogIconSize, true ); + tipLayout->addLayout( primaryLine, 0, 0 ); + + for ( int done = 0; d->view->model()->rowCount( item ) > done; done = 1 + done ) { + QModelIndex childItem = d->view->model()->index( done, 0, item ); + QLayout * subLine = generateToolTipLine( &childItem, tipContent, toolbarIconSize, false ); + tipLayout->addLayout( subLine, done + 2, 0 ); + } + + tipLayout->setVerticalSpacing( 0 ); + tipContent->setLayout( tipLayout ); + + if( d->view->model()->rowCount( item ) > 0 ) { + QFrame * separatorLine = new QFrame( tipContent ); + separatorLine->setFrameStyle( QFrame::HLine ); + tipLayout->addWidget( separatorLine, 1, 0 ); + } + + return tipContent; +} + +QLayout * ToolTipManager::generateToolTipLine( QModelIndex * item, QWidget * toolTip, QSize iconSize, bool comment ) +{ + // Get MenuItem + MenuItem * menuItem = d->view->model()->data( *item, Qt::UserRole ).value(); + + QString text = menuItem->name(); + if ( comment ) { + text = QString( "%1" ).arg( menuItem->name() ); + } + + // Generate text + if ( comment ) { + text += "
    "; + if ( !menuItem->service()->comment().isEmpty() ) { + text += menuItem->service()->comment(); + } else { + int childCount = d->view->model()->rowCount( *item ); + text += i18np( "Contains 1 item", "Contains %1 items", childCount ); + } + } + QLabel * textLabel = new QLabel( toolTip ); + textLabel->setForegroundRole(QPalette::ToolTipText); + textLabel->setText( text ); + + // Get icon + KIcon icon( menuItem->service()->icon() ); + QLabel * iconLabel = new QLabel( toolTip ); + iconLabel->setPixmap( icon.pixmap(iconSize) ); + iconLabel->setMaximumSize( iconSize ); + + // Generate layout + QHBoxLayout * layout = new QHBoxLayout(); + layout->addWidget( iconLabel ); + layout->addWidget( textLabel ); + + return layout; +} + +#include "tooltipmanager.moc" diff --git a/systemsettings/app/ToolTips/tooltipmanager.h b/systemsettings/app/ToolTips/tooltipmanager.h new file mode 100644 index 00000000..32966681 --- /dev/null +++ b/systemsettings/app/ToolTips/tooltipmanager.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (C) 2008 by Konstantin Heil * + * * + * 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; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + *******************************************************************************/ + +#ifndef TOOLTIPMANAGER_H +#define TOOLTIPMANAGER_H + +#include + +#include + +class QLayout; +class MenuItem; +class KToolTipItem; +class QAbstractItemView; + +/** + * @brief Manages the tooltips for an item view. + * + * When hovering an item, a tooltip is shown after + * a short timeout. The tooltip is hidden again when the + * viewport is hovered or the item view has been left. + */ +class ToolTipManager : public QObject +{ + Q_OBJECT + +public: + /** + * Standard constructor. The ToolTipManager will start handling ToolTip events on the provided + * view immediately. + * + * @param parent The view which will have the tooltips displayed for. + */ + explicit ToolTipManager(QAbstractItemView* parent); + virtual ~ToolTipManager(); + +public Q_SLOTS: + /** + * Hides the currently shown tooltip. Invoking this method is + * only needed when the tooltip should be hidden although + * an item is hovered. + */ + void hideToolTip(); + +protected: + /** + * Please see the Qt documentation for more details. + * + * @param watched The object that was being watched. + * @param event The event object. + * @returns true if the event was handled in this filter, or false if it was not. + */ + virtual bool eventFilter( QObject* watched, QEvent* event ); + +private Q_SLOTS: + void prepareToolTip(); + void requestToolTip(const QModelIndex& index); + +private: + void showToolTip( QModelIndex menuItem ); + QWidget * createTipContent( QModelIndex item ); + QLayout * generateToolTipLine( QModelIndex * item, QWidget * toolTip, QSize iconSize, bool comment ); + + class Private; + ToolTipManager::Private* d; +}; + +#endif diff --git a/systemsettings/app/configDialog.ui b/systemsettings/app/configDialog.ui new file mode 100644 index 00000000..ac19823a --- /dev/null +++ b/systemsettings/app/configDialog.ui @@ -0,0 +1,45 @@ + + + ConfigDialog + + + + 0 + 0 + 491 + 141 + + + + + + + View Style + + + + + + + Show detailed tooltips + + + + + + + Qt::Vertical + + + + 20 + 44 + + + + + + + + + diff --git a/systemsettings/app/kdesystemsettings.desktop b/systemsettings/app/kdesystemsettings.desktop new file mode 100755 index 00000000..83cda898 --- /dev/null +++ b/systemsettings/app/kdesystemsettings.desktop @@ -0,0 +1,113 @@ +[Desktop Entry] +Exec=systemsettings -caption %c %i +Icon=preferences-system +Type=Application +X-KDE-StartupNotify=true +NotShowIn=KDE; + +GenericName=KDE System Settings +GenericName[ar]=إعدادات نظام كدي +GenericName[bs]=Sistemske postavke KDE-a +GenericName[ca]=Arranjament del sistema del KDE +GenericName[ca@valencia]=Arranjament del sistema del KDE +GenericName[cs]=Nastavení systému KDE +GenericName[da]=KDE Systemindstillinger +GenericName[de]=KDE-Systemeinstellungen +GenericName[el]=Ρυθμίσεις συστήματος του KDE +GenericName[en_GB]=KDE System Settings +GenericName[es]=Preferencias del sistema de KDE +GenericName[et]=KDE Süsteemi seadistused +GenericName[eu]=KDE sistemaren ezarpenak +GenericName[fi]=KDE:n järjestelmäasetukset +GenericName[fr]=Configuration du système de KDE +GenericName[ga]=Socruithe an Chórais KDE +GenericName[gl]=Configuración do sistema KDE +GenericName[he]=הגדרות מערכת של KDE +GenericName[hu]=KDE Rendszerbeállítások +GenericName[ia]=Preferentias de systema KDE +GenericName[is]=KDE kerfisstillingar +GenericName[it]=Impostazioni di sistema KDE +GenericName[kk]=KDE жүйелік параметрлері +GenericName[km]=ការ​កំណត់​ប្រព័ន្ធ KDE +GenericName[ko]=KDE 시스템 설정 +GenericName[lt]=KDE sistemos nustatymai +GenericName[lv]=KDE sistēmas iestatījumi +GenericName[mr]=केडीई प्रणाली संयोजना +GenericName[nb]=KDE Systeminnstillinger +GenericName[nds]=KDE-Systeeminstellen +GenericName[nl]=KDE-systeeminstellingen +GenericName[pa]=KDE ਸਿਸਟਮ ਸੈਟਿੰਗ +GenericName[pl]=Ustawienia systemowe KDE +GenericName[pt]=Configuração do Sistema KDE +GenericName[pt_BR]=Configurações do sistema KDE +GenericName[ro]=Configurări de sistem +GenericName[ru]=Параметры системы KDE +GenericName[sk]=Nastavenie systému KDE +GenericName[sl]=KDE-jeve sistemske nastavitve +GenericName[sr]=КДЕ Системске поставке +GenericName[sr@ijekavian]=КДЕ Системске поставке +GenericName[sr@ijekavianlatin]=KDE Sistemske postavke +GenericName[sr@latin]=KDE Sistemske postavke +GenericName[sv]=KDE:s systeminställningar +GenericName[tr]=KDE Sistem Ayarları +GenericName[ug]=KDE سىستېما تەڭشىكى +GenericName[uk]=Системні параметри KDE +GenericName[vi]=Thiết lập hệ thống KDE +GenericName[x-test]=xxKDE System Settingsxx +GenericName[zh_CN]=KDE 系统设置 +GenericName[zh_TW]=KDE 系統設定 + +Name=KDE System Settings +Name[ar]=إعدادات نظام كدي +Name[bs]=Sistemske postavke KDE-a +Name[ca]=Arranjament del sistema del KDE +Name[ca@valencia]=Arranjament del sistema del KDE +Name[cs]=Nastavení systému KDE +Name[da]=KDE Systemindstillinger +Name[de]=KDE-Systemeinstellungen +Name[el]=Ρυθμίσεις συστήματος του KDE +Name[en_GB]=KDE System Settings +Name[es]=Preferencias del sistema de KDE +Name[et]=KDE Süsteemi seadistused +Name[eu]=KDE sistemaren ezarpenak +Name[fi]=KDE:n järjestelmäasetukset +Name[fr]=Configuration du système de KDE +Name[ga]=Socruithe an Chórais KDE +Name[gl]=Configuración do sistema KDE +Name[he]=הגדרות מערכת של KDE +Name[hu]=KDE Rendszerbeállítások +Name[ia]=Preferentias de systema KDE +Name[is]=KDE kerfisstillingar +Name[it]=Impostazioni di sistema KDE +Name[kk]=KDE жүйелік параметрлері +Name[km]=ការ​កំណត់​ប្រព័ន្ធ KDE +Name[ko]=KDE 시스템 설정 +Name[lt]=KDE sistemos nustatymai +Name[lv]=KDE sistēmas iestatījumi +Name[mr]=केडीई प्रणाली संयोजना +Name[nb]=KDE Systeminnstillinger +Name[nds]=KDE-Systeeminstellen +Name[nl]=KDE-systeeminstellingen +Name[pa]=KDE ਸਿਸਟਮ ਸੈਟਿੰਗ +Name[pl]=Ustawienia systemowe KDE +Name[pt]=Configuração do Sistema KDE +Name[pt_BR]=Configurações do sistema KDE +Name[ro]=Configurări de sistem KDE +Name[ru]=Параметры системы KDE +Name[sk]=Nastavenie systému KDE +Name[sl]=KDE-jeve sistemske nastavitve +Name[sr]=КДЕ Системске поставке +Name[sr@ijekavian]=КДЕ Системске поставке +Name[sr@ijekavianlatin]=KDE Sistemske postavke +Name[sr@latin]=KDE Sistemske postavke +Name[sv]=KDE:s systeminställningar +Name[tr]=KDE Sistem Ayarları +Name[ug]=KDE سىستېما تەڭشىكى +Name[uk]=Системні параметри KDE +Name[vi]=Thiết lập hệ thống KDE +Name[x-test]=xxKDE System Settingsxx +Name[zh_CN]=KDE 系统设置 +Name[zh_TW]=KDE 系統設定 + +X-DBUS-StartupType=Unique +Categories=Qt;KDE;Settings; diff --git a/systemsettings/app/main.cpp b/systemsettings/app/main.cpp new file mode 100644 index 00000000..340b8d80 --- /dev/null +++ b/systemsettings/app/main.cpp @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2009 Ben Cooksley + * + * This file was sourced from the System Settings package + * Copyright (C) 2005 Benjamin C Meyer + * + * + * 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 library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include "SystemSettingsApp.h" +#include "SettingsBase.h" + +int main( int argc, char *argv[] ) +{ + // About data + KAboutData aboutData("systemsettings", 0, ki18n("System Settings"), WORKSPACE_VERSION_STRING, ki18n("Central configuration center for KDE."), KAboutData::License_GPL, ki18n("(c) 2009, Ben Cooksley")); + aboutData.addAuthor(ki18n("Ben Cooksley"), ki18n("Maintainer"), "bcooksley@kde.org"); + aboutData.addAuthor(ki18n("Mathias Soeken"), ki18n("Developer"), "msoeken@informatik.uni-bremen.de"); + aboutData.addAuthor(ki18n("Will Stephenson"), ki18n("Internal module representation, internal module model"), "wstephenson@kde.org"); + + aboutData.setProgramIconName("preferences-system"); + KCmdLineArgs::init(argc, argv, &aboutData); + + SystemSettingsApp application; + + SettingsBase *mainWindow = new SettingsBase(); + mainWindow->show(); + application.setMainWindow(mainWindow); + return application.exec(); +} diff --git a/systemsettings/app/org.kde.systemsettings.xml b/systemsettings/app/org.kde.systemsettings.xml new file mode 100644 index 00000000..c4afba19 --- /dev/null +++ b/systemsettings/app/org.kde.systemsettings.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/systemsettings/app/systemsettings.desktop b/systemsettings/app/systemsettings.desktop new file mode 100755 index 00000000..ce2fbe88 --- /dev/null +++ b/systemsettings/app/systemsettings.desktop @@ -0,0 +1,178 @@ +[Desktop Entry] +Exec=systemsettings -caption %c %i +Icon=preferences-system +Type=Application +X-DocPath=systemsettings/index.html +X-KDE-StartupNotify=true +OnlyShowIn=KDE; + +GenericName=System Settings +GenericName[ar]=إعدادات النظام +GenericName[ast]=Preferencies del sistema +GenericName[be@latin]=Systemnyja nałady +GenericName[bg]=Системни настройки +GenericName[bn]=সিস্টেম সেটিংস +GenericName[bn_IN]=সিস্টেম সংক্রান্ত বৈশিষ্ট্য +GenericName[bs]=Sistemske postavke +GenericName[ca]=Arranjament del sistema +GenericName[ca@valencia]=Arranjament del sistema +GenericName[cs]=Nastavení systému +GenericName[csb]=Systemòwé ùstôwë +GenericName[da]=Systemindstillinger +GenericName[de]=Systemeinstellungen +GenericName[el]=Ρυθμίσεις συστήματος +GenericName[en_GB]=System Settings +GenericName[eo]=Sistema agordo +GenericName[es]=Preferencias del sistema +GenericName[et]=Süsteemi seadistused +GenericName[eu]=Sistemaren ezarpenak +GenericName[fi]=Järjestelmäasetukset +GenericName[fr]=Configuration du système +GenericName[fy]=Systeemynstellings +GenericName[ga]=Socruithe an Chórais +GenericName[gl]=Configuración do sistema +GenericName[gu]=સિસ્ટમ ગોઠવણીઓ +GenericName[he]=הגדרות מערכת +GenericName[hi]=तंत्र विन्यास +GenericName[hne]=तंत्र सेटिंग +GenericName[hr]=Postavke sustava +GenericName[hu]=Rendszerbeállítások +GenericName[ia]=Preferentias de systema +GenericName[id]=Pengaturan Sistem +GenericName[is]=Kerfisstillingar +GenericName[it]=Impostazioni di sistema +GenericName[ja]=システム設定 +GenericName[kk]=Жүйе параметрлері +GenericName[km]=ការ​កំណត់​ប្រព័ន្ធ​ +GenericName[kn]=ವ್ಯವಸ್ಥೆಯ ಸಂಯೋಜನೆಗಳು +GenericName[ko]=시스템 설정 +GenericName[ku]=Mîhengên Pergalê +GenericName[lt]=Sistemos nustatymai +GenericName[lv]=Sistēmas iestatījumi +GenericName[mai]=तंत्र बिन्यास +GenericName[mk]=Системски поставувања +GenericName[ml]=സിസ്റ്റം സജ്ജീകരണങ്ങള്‍ +GenericName[mr]=प्रणाली संयोजना +GenericName[nb]=Systeminnstillinger +GenericName[nds]=Systeeminstellen +GenericName[nl]=Systeeminstellingen +GenericName[nn]=Systemoppsett +GenericName[oc]=Configuracion del sistèma +GenericName[or]=ତନ୍ତ୍ର ବିନ୍ୟାସ +GenericName[pa]=ਸਿਸਟਮ ਸੈਟਿੰਗ +GenericName[pl]=Ustawienia systemowe +GenericName[pt]=Configuração do Sistema +GenericName[pt_BR]=Configurações do Sistema +GenericName[ro]=Configurări de sistem +GenericName[ru]=Параметры системы +GenericName[se]=Vuogádatheivehusat +GenericName[si]=පද්ධති සැකසුම් +GenericName[sk]=Systémové nastavenia +GenericName[sl]=Sistemske nastavitve +GenericName[sr]=Системске поставке +GenericName[sr@ijekavian]=Системске поставке +GenericName[sr@ijekavianlatin]=Sistemske postavke +GenericName[sr@latin]=Sistemske postavke +GenericName[sv]=Systeminställningar +GenericName[ta]=System Settings +GenericName[te]=సిస్టమ్ అమర్పులు +GenericName[tg]=Танзимотҳои система +GenericName[th]=ตั้งค่าระบบ +GenericName[tr]=Sistem Ayarları +GenericName[ug]=سىستېما تەڭشىكى +GenericName[uk]=Системні параметри +GenericName[uz]=Tizim moslamalari +GenericName[uz@cyrillic]=Тизим мосламалари +GenericName[wa]=Apontiaedjes do sistinme +GenericName[x-test]=xxSystem Settingsxx +GenericName[zh_CN]=系统设置 +GenericName[zh_TW]=系統設定 + +Name=System Settings +Name[ar]=إعدادات النظام +Name[ast]=Preferencies del sistema +Name[be]=Сістэмныя настаўленні +Name[be@latin]=Systemnyja nałady +Name[bg]=Системни настройки +Name[bn]=সিস্টেম সেটিংস +Name[bn_IN]=সিস্টেম সংক্রান্ত বৈশিষ্ট্য +Name[br]=Dibarzhoù ar reizhiad +Name[bs]=Sistemske postavke +Name[ca]=Arranjament del sistema +Name[ca@valencia]=Arranjament del sistema +Name[cs]=Nastavení systému +Name[csb]=Systemòwé ùstôwë +Name[da]=Systemindstillinger +Name[de]=Systemeinstellungen +Name[el]=Ρυθμίσεις συστήματος +Name[en_GB]=System Settings +Name[eo]=Sistema agordo +Name[es]=Preferencias del sistema +Name[et]=Süsteemi seadistused +Name[eu]=Sistemaren ezarpenak +Name[fa]=تنظیمات سیستم +Name[fi]=Järjestelmäasetukset +Name[fr]=Configuration du système +Name[fy]=Systeemynstellings +Name[ga]=Socruithe an Chórais +Name[gl]=Configuración do sistema +Name[gu]=સિસ્ટમ ગોઠવણીઓ +Name[he]=הגדרות מערכת +Name[hi]=तंत्र विन्यास +Name[hne]=तंत्र सेटिंग +Name[hr]=Postavke sustava +Name[hu]=Rendszerbeállítások +Name[ia]=Preferentias de systema +Name[id]=Pengaturan Sistem +Name[is]=Kerfisstillingar +Name[it]=Impostazioni di sistema +Name[ja]=KDE システム設定 +Name[kk]=Жүйе параметрлері +Name[km]=ការ​កំណត់​ប្រព័ន្ធ​ +Name[kn]=ವ್ಯವಸ್ಥೆಯ ಸಂಯೋಜನೆಗಳು +Name[ko]=시스템 설정 +Name[ku]=Mîhengên Pergalê +Name[lt]=Sistemos nustatymai +Name[lv]=Sistēmas iestatījumi +Name[mai]=तंत्र बिन्यास +Name[mk]=Системски поставувања +Name[ml]=സിസ്റ്റം സജ്ജീകരണങ്ങള്‍ +Name[mr]=प्रणाली संयोजना +Name[nb]=Systemoppsett +Name[nds]=Systeeminstellen +Name[ne]=प्रणाली सेटिङ +Name[nl]=Systeeminstellingen +Name[nn]=Systemoppsett +Name[oc]=Configuracion del sistèma +Name[or]=ତନ୍ତ୍ର ବିନ୍ୟାସ +Name[pa]=ਸਿਸਟਮ ਸੈਟਿੰਗ +Name[pl]=Ustawienia systemowe +Name[pt]=Configuração do Sistema +Name[pt_BR]=Configurações do Sistema +Name[ro]=Configurări de sistem +Name[ru]=Параметры системы +Name[se]=Vuogádatheivehusat +Name[si]=පද්ධති සැකසුම් +Name[sk]=Systémové nastavenia +Name[sl]=Sistemske nastavitve +Name[sr]=Системске поставке +Name[sr@ijekavian]=Системске поставке +Name[sr@ijekavianlatin]=Sistemske postavke +Name[sr@latin]=Sistemske postavke +Name[sv]=Systeminställningar +Name[ta]=System Settings +Name[te]=సిస్టమ్ అమర్పులు +Name[tg]=Танзимотҳои система +Name[th]=ตั้งค่าระบบ +Name[tr]=Sistem Ayarları +Name[ug]=سىستېما تەڭشىكى +Name[uk]=Системні параметри +Name[uz]=Tizim moslamalari +Name[uz@cyrillic]=Тизим мосламалари +Name[wa]=Apontiaedjes do sistinme +Name[x-test]=xxSystem Settingsxx +Name[zh_CN]=系统设置 +Name[zh_TW]=系統設定 + +X-DBUS-StartupType=Unique +Categories=Qt;KDE;Settings; diff --git a/systemsettings/app/systemsettings.kcfg b/systemsettings/app/systemsettings.kcfg new file mode 100644 index 00000000..60ec5032 --- /dev/null +++ b/systemsettings/app/systemsettings.kcfg @@ -0,0 +1,17 @@ + + + + + + + true + + + + icon_mode + + + diff --git a/systemsettings/app/systemsettingsui.rc b/systemsettings/app/systemsettingsui.rc new file mode 100644 index 00000000..e5ba899b --- /dev/null +++ b/systemsettings/app/systemsettingsui.rc @@ -0,0 +1,24 @@ + + + + + + + + + + + About System Settings + + + + + + + + diff --git a/systemsettings/categories/CMakeLists.txt b/systemsettings/categories/CMakeLists.txt new file mode 100644 index 00000000..648a915d --- /dev/null +++ b/systemsettings/categories/CMakeLists.txt @@ -0,0 +1,38 @@ + +install( FILES systemsettingscategory.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) + +install( FILES + settings-accessibility.desktop + settings-account-details.desktop + settings-application-and-system-notifications.desktop + settings-application-appearance-and-behavior.desktop + settings-application-appearance.desktop + settings-audio-and-video.desktop + settings-desktop-appearance.desktop + settings-display.desktop + settings-hardware.desktop + settings-input-devices.desktop + settings-locale.desktop + settings-lost-and-found.desktop + settings-network-and-connectivity.desktop + settings-network-settings.desktop + settings-permissions.desktop + settings-personal-information.desktop + settings-power-management.desktop + settings-removable-devices.desktop + settings-shortcuts-and-gestures.desktop + settings-startup-and-shutdown.desktop + settings-system-administration.desktop + settings-window-behaviour.desktop + settings-workspace-appearance-and-behavior.desktop + settings-workspace-behavior.desktop + DESTINATION ${SERVICES_INSTALL_DIR} ) + +if (NOT WIN32) + install( FILES + settings-bluetooth.desktop + #settings-desktop.desktop + settings-sharing.desktop + DESTINATION ${SERVICES_INSTALL_DIR} ) +endif (NOT WIN32) + diff --git a/systemsettings/categories/settings-accessibility.desktop b/systemsettings/categories/settings-accessibility.desktop new file mode 100644 index 00000000..7048e411 --- /dev/null +++ b/systemsettings/categories/settings-accessibility.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=accessibility +X-KDE-System-Settings-Parent-Category=workspace-appearance-and-behavior +Icon=preferences-desktop-accessibility + +Name=Accessibility +Name[af]=Toeganklikheid +Name[ar]=الإتاحة +Name[as]=অভিগম্যতা +Name[ast]=Accesibilidá +Name[be]=Даступнасць +Name[be@latin]=Dastupnaść +Name[bg]=Равностоен достъп +Name[bn]=সহায়ক প্রযুক্তি +Name[bn_IN]=বিশেষ ব্যবহারের সহায়তা +Name[br]=Haezadusted +Name[bs]=Pristupačnost +Name[ca]=Accessibilitat +Name[ca@valencia]=Accessibilitat +Name[cs]=Zpřístupnění +Name[csb]=Pòmòce przëstãpù +Name[cy]=Hygyrchedd +Name[da]=Tilgængelighed +Name[de]=Zugangshilfen +Name[el]=Προσιτότητα +Name[en_GB]=Accessibility +Name[eo]=Alirebleco +Name[es]=Accesibilidad +Name[et]=Hõlbustus +Name[eu]=Erabilerraztasuna +Name[fa]=دستیابی‌پذیری +Name[fi]=Esteettömyys +Name[fr]=Accessibilité +Name[fy]=Tagonklikens +Name[ga]=Inrochtaineacht +Name[gl]=Accesibilidade +Name[gu]=ઉપયોગિતા +Name[he]=נגישות +Name[hi]=पहुँच +Name[hne]=पहुंच +Name[hr]=Pristupačnost +Name[hsb]=Přistupnosć +Name[hu]=Kezelési segítség +Name[ia]=Accessibilitate +Name[id]=Aksesibilitas +Name[is]=Aðgengi +Name[it]=Accessibilità +Name[ja]=アクセシビリティ +Name[ka]=სპეციალური შესაძლბლობები +Name[kk]=Арнайы мүмкіндіктер +Name[km]=មធ្យោបាយ​ងាយស្រួល +Name[kn]=ನಿಲುಕಣೆ (ಆಕ್ಸೆಸಿಬಿಲಿಟಿ) +Name[ko]=내게 필요한 설정 +Name[ku]=Gihîştin +Name[lt]=Pritaikymas neįgaliesiems +Name[lv]=Pieejamība +Name[mai]=अभिगम्यता +Name[mk]=Пристапливост +Name[ml]=സാമീപ്യത +Name[mr]=सुलभता +Name[ms]=Kebolehcapaian +Name[nb]=Tilgjengelighet +Name[nds]=Toganghülp +Name[ne]=पहुँचता +Name[nl]=Toegankelijkheid +Name[nn]=Tilgjenge +Name[oc]=Accessibilitat +Name[or]=ଅଭିଗମ୍ୟତା +Name[pa]=ਸਹੂਲਤਾਂ +Name[pl]=Ułatwienia dostępu +Name[pt]=Acessibilidade +Name[pt_BR]=Acessibilidade +Name[ro]=Accesibilitate +Name[ru]=Специальные возможности +Name[se]=Álkkibut geavaheapmi +Name[si]=ප්‍රවේශණය +Name[sk]=Prístupnosť +Name[sl]=Dostopnost +Name[sr]=Приступачност +Name[sr@ijekavian]=Приступачност +Name[sr@ijekavianlatin]=Pristupačnost +Name[sr@latin]=Pristupačnost +Name[sv]=Handikappstöd +Name[ta]=அணுகல் +Name[te]=అందుబాటు +Name[tg]=Имкониятҳо +Name[th]=ช่วยการใช้งาน +Name[tr]=Erişilebilirlik +Name[ug]=قوشۇمچە ئىقتىدار +Name[uk]=Доступність +Name[uz]=Qulayliklar +Name[uz@cyrillic]=Қулайликлар +Name[vi]=Hỗ trợ truy cập +Name[wa]=Accessibilité +Name[xh]=Unikezelo +Name[x-test]=xxAccessibilityxx +Name[zh_CN]=辅助 +Name[zh_TW]=無障礙輔助 diff --git a/systemsettings/categories/settings-account-details.desktop b/systemsettings/categories/settings-account-details.desktop new file mode 100644 index 00000000..bb622a0f --- /dev/null +++ b/systemsettings/categories/settings-account-details.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=account-details +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-user + +Name=Account Details +Name[ar]=تفاصيل الحساب +Name[ast]=Detalles de cuentes +Name[bg]=Данни на сметката +Name[bn]=অ্যাকাউন্ট বিবরণ +Name[bs]=Detalji naloga +Name[ca]=Detalls del compte +Name[ca@valencia]=Detalls del compte +Name[cs]=Podrobnosti o účtu +Name[da]=Kontodetaljer +Name[de]=Benutzerkontodetails +Name[el]=Λεπτομέρειες λογαριασμού +Name[en_GB]=Account Details +Name[es]=Detalles de cuentas +Name[et]=Konto üksikasjad +Name[eu]=Kontuaren xehetasunak +Name[fi]=Käyttäjätilin tiedot +Name[fr]=Détails du compte +Name[ga]=Mionsonraí an Chuntais +Name[gl]=Detalles da conta +Name[gu]=ખાતા વિગતો +Name[he]=פרטי חשבון +Name[hi]=खाता विवरण +Name[hr]=Detalji korisničkog računa +Name[hu]=Felhasználói fiókadatok +Name[ia]=Detalios de conto +Name[id]=Detail Akun +Name[is]=Nánar um notanda +Name[it]=Dettagli dell'account +Name[ja]=アカウント詳細 +Name[kk]=Тіркелгі егжей-тегжейі +Name[km]=សេចក្ដី​លម្អិត​គណនី +Name[kn]=ಖಾತೆಯ ವಿವರ +Name[ko]=계정 정보 +Name[lt]=Paskyros detalės +Name[lv]=Konta detaļas +Name[mr]=खात्याचे तपशील +Name[nb]=Detaljer om kontoen +Name[nds]=Konto-Enkelheiten +Name[nl]=Accountdetails +Name[nn]=Konto­detaljar +Name[pa]=ਅਕਾਊਂਟ ਵੇਰਵਾ +Name[pl]=Szczegóły konta +Name[pt]=Detalhes da Conta +Name[pt_BR]=Detalhes da conta +Name[ro]=Detalii cont +Name[ru]=Учётная запись +Name[si]=ගිණුම් විස්තර +Name[sk]=Detaily účtu +Name[sl]=Podrobnosti računa +Name[sr]=Детаљи налога +Name[sr@ijekavian]=Детаљи налога +Name[sr@ijekavianlatin]=Detalji naloga +Name[sr@latin]=Detalji naloga +Name[sv]=Kontoinformation +Name[tg]=Тафсилоти ҳисоб +Name[th]=รายละเอียดบัญชีผู้ใช้ +Name[tr]=Hesap Detayları +Name[ug]=ھېسابات تەپسىلاتى +Name[uk]=Параметри облікового запису +Name[vi]=Chi tiết tài khoản +Name[wa]=Detays do conte +Name[x-test]=xxAccount Detailsxx +Name[zh_CN]=账户细节 +Name[zh_TW]=帳號詳細資料 + diff --git a/systemsettings/categories/settings-application-and-system-notifications.desktop b/systemsettings/categories/settings-application-and-system-notifications.desktop new file mode 100644 index 00000000..4a5ae567 --- /dev/null +++ b/systemsettings/categories/settings-application-and-system-notifications.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=application-and-system-notifications +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-notification + +Name=Application and System Notifications +Name[ar]=تنبيهات التطبيقات والنظام +Name[ast]=Notificaciones d'aplicaciones y del sistema +Name[bg]=Програмни и системни съобщения +Name[bn]=অ্যাপলিকেশন এবং সিস্টেম বিজ্ঞপ্তি +Name[bs]=Sistemska i programska obavještenja +Name[ca]=Notificacions de les aplicacions i del sistema +Name[ca@valencia]=Notificacions de les aplicacions i del sistema +Name[cs]=Oznamování aplikací a systému +Name[da]=Program- og systembekendtgørelser +Name[de]=Anwendungs- und Systembenachrichtigungen +Name[el]=Ειδοποιήσεις εφαρμογών και συστήματος +Name[en_GB]=Application and System Notifications +Name[es]=Notificaciones de aplicaciones y del sistema +Name[et]=Rakenduste ja süsteemi märguanded +Name[eu]=Aplikazio- eta sistema-jakinarazpenak +Name[fi]=Ohjelma- ja järjestelmäilmoitukset +Name[fr]=Notifications des applications et du système +Name[gl]=Notificacións dos programas e do sistema +Name[he]=הודעות מערכת והודעות יישום +Name[hi]=अनुप्रयोग व तंत्र सूचनाएँ +Name[hr]=Obavijesti sustava i aplikacija +Name[hu]=Alkalmazás- és rendszerértesítések +Name[ia]=Applicationes e notificationes de systema +Name[id]=Notifikasi Sistem dan Aplikasi +Name[is]=Tilkynningar kerfis og forrita +Name[it]=Notifiche delle applicazioni e di sistema +Name[ja]=アプリケーションとシステムの通知 +Name[kk]=Қолданба мен жүйелік құлақтандырулары +Name[km]=កា​រជូនដំណឹង​ប្រព័ន្ធ និង​កម្មវិធី​ +Name[kn]=ಅನ್ವಯ ಹಾಗು ವ್ಯವಸ್ಥೆಯ ಸೂಚನೆಗಳು +Name[ko]=프로그램 및 시스템 알림 +Name[lt]=Programų ir sistemos pranešimai +Name[lv]=Programmu un sistēmas paziņojumi +Name[mr]=अनुप्रयोग व प्रणाली सूचना +Name[nb]=Program- og systemvarsler +Name[nds]=Programm- un Systeembescheden +Name[nl]=Programma- en systeemmeldingen +Name[nn]=Program- og system­varslingar +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਤੇ ਸਿਸਟਮ ਨੋਟੀਫਿਕੇਸ਼ਨ +Name[pl]=Powiadomienia programów i systemu +Name[pt]=Notificações das Aplicações e do Sistema +Name[pt_BR]=Notificações dos aplicativos e do sistema +Name[ro]=Notificare aplicații și sistem +Name[ru]=Уведомления +Name[si]=යෙදුම් සහ පද්ධති දැනුම්දීම් +Name[sk]=Upozornenia aplikácií a systému +Name[sl]=Obvestila programov in sistema +Name[sr]=Системска и програмска обавештења +Name[sr@ijekavian]=Системска и програмска обавјештења +Name[sr@ijekavianlatin]=Sistemska i programska obavještenja +Name[sr@latin]=Sistemska i programska obaveštenja +Name[sv]=Program- och systemunderrättelser +Name[tg]=Барномаҳо ва огоҳномаҳои система +Name[th]=การแจ้งให้ทราบของโปรแกรมและระบบ +Name[tr]=Uygulama ve Sistem Bildirimleri +Name[ug]=پروگرامما ۋە سىستېما ئۇقتۇرۇشى +Name[uk]=Сповіщення програм і системи +Name[vi]=Thông báo hệ thống và ứng dụng +Name[wa]=Notifiaedjes des programes eyet do sistinme +Name[x-test]=xxApplication and System Notificationsxx +Name[zh_CN]=应用程序和系统通知 +Name[zh_TW]=應用程式與系統通知 diff --git a/systemsettings/categories/settings-application-appearance-and-behavior.desktop b/systemsettings/categories/settings-application-appearance-and-behavior.desktop new file mode 100644 index 00000000..767c56cc --- /dev/null +++ b/systemsettings/categories/settings-application-appearance-and-behavior.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=application-appearance-and-behavior +X-KDE-System-Settings-Parent-Category= +X-KDE-Weight=80 +Icon=preferences-desktop-theme + +Name=Common Appearance and Behavior +Name[ar]=المظهر والسلوك المشتركان +Name[ast]=Apariencia y comportamientu comunes +Name[bg]=Общ изглед и поведение +Name[bn]=সাধারণ চেহারা এবং আচরণ +Name[bs]=Opšti izgled i ponašanje +Name[ca]=Aparença i comportament usual +Name[ca@valencia]=Aparença i comportament usual +Name[da]=Fælles udseende og opførsel +Name[de]=Allgemeines Erscheinungsbild und Verhalten +Name[el]=Κοινή εμφάνιση και συμπεριφορά +Name[en_GB]=Common Appearance and Behaviour +Name[es]=Apariencia y comportamiento comunes +Name[et]=Üldine välimus ja käitumine +Name[eu]=Itxura eta portaera arruntak +Name[fi]=Yleinen ulkoasu ja toiminta +Name[gl]=Aparencia e comportamento comúns +Name[he]=התנהגות ומראה אחידים +Name[hi]=सामान्य रूप व स्वभाव +Name[hr]=Zajednički izgled i ponašanje +Name[hu]=Általános megjelenés és működés +Name[ia]=Apparentia e comportamento commun +Name[id]=Perilaku dan Tampilan Umum +Name[is]=Sameiginlegt útlit og hegðun +Name[kk]=Жалпы көрнісі мен тәртібі +Name[km]=រូបរាង និង​ឥរិយាបថ​ធម្មតា​ +Name[kn]=ಸಾಮಾನ್ಯ ಗೋಚರಿಕೆ ಹಾಗು ವರ್ತನೆ +Name[ko]=공통 모양과 행동 +Name[lt]=Bendra išvaizda ir elgsena +Name[lv]=Tipisks izskats un izturēšanās +Name[mr]=सामान्य दर्शनीयता व वर्तन +Name[nb]=Felles utseende og oppførsel +Name[nds]=Allmeen Utsehn un Bedregen +Name[nl]=Gemeenschappelijk uiterlijk en gedrag +Name[nn]=Vanleg utsjånad og oppførsel +Name[pa]=ਆਮ ਦਿੱਖ ਤੇ ਰਵੱਈਆ +Name[pl]=Powszechny wygląd i zachowanie +Name[pt]=Aparência e Comportamento Comuns +Name[pt_BR]=Aparência e comportamento comuns +Name[ro]=Aspect și comportament comun +Name[ru]=Основные параметры внешнего вида и поведения +Name[sk]=Spoločný vzhľad a správanie +Name[sl]=Splošen videz in obnašanje +Name[sr]=Општи изглед и понашање +Name[sr@ijekavian]=Општи изглед и понашање +Name[sr@ijekavianlatin]=Opšti izgled i ponašanje +Name[sr@latin]=Opšti izgled i ponašanje +Name[sv]=Gemensamt utseende och beteende +Name[tg]=Намуди зоҳирӣ ва рафтори умумӣ +Name[th]=รูปลักษณ์และพฤติกรรมทั่วไป +Name[tr]=Genel Görünüm ve Davranış +Name[ug]=ئاممىۋى قىياپەت ۋە مەشغۇلات +Name[uk]=Загальний вигляд і поведінка +Name[vi]=Diện mạo và hành vi chung +Name[wa]=Comone rivnance eyet dujhance +Name[x-test]=xxCommon Appearance and Behaviorxx +Name[zh_CN]=公共外观和行为 +Name[zh_TW]=通用外觀與行為 diff --git a/systemsettings/categories/settings-application-appearance.desktop b/systemsettings/categories/settings-application-appearance.desktop new file mode 100644 index 00000000..9374a32b --- /dev/null +++ b/systemsettings/categories/settings-application-appearance.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=application-appearance +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-theme + +Name=Application Appearance +Name[ar]=مظهر التطبيقات +Name[ast]=Apariencia de les aplicaciones +Name[bg]=Изглед на програмите +Name[bn]=অ্যাপলিকেশন-এর চেহারা +Name[bs]=Izgled programa +Name[ca]=Aparença de les aplicacions +Name[ca@valencia]=Aparença de les aplicacions +Name[cs]=Vzhled aplikací +Name[da]=Programmers udseende +Name[de]=Erscheinungsbild von Anwendungen +Name[el]=Εμφάνιση εφαρμογών +Name[en_GB]=Application Appearance +Name[es]=Apariencia de las aplicaciones +Name[et]=Rakenduste välimus +Name[eu]=Aplikazioen itxura +Name[fi]=Sovellusten ulkoasu +Name[fr]=Apparence des applications +Name[gl]=Aparencia dos programas +Name[he]=מראה יישום +Name[hi]=अनुप्रयोग रूप +Name[hr]=Izgled aplikacija +Name[hu]=Az alkalmazások megjelenése +Name[ia]=Apparentia de application +Name[id]=Tampilan Aplikasi +Name[is]=Útlit forrita +Name[it]=Aspetto delle applicazioni +Name[ja]=アプリケーションの外観 +Name[kk]=Қолданба көрінісі +Name[km]=រូបរាង​កម្មវិធី​ +Name[kn]=ಅನ್ವಯ ಗೋಚರಿಕೆ +Name[ko]=프로그램 모양 +Name[lt]=Programų išvaizda +Name[lv]=Programmu izskats +Name[mr]=अनुप्रयोग दर्शनीयता +Name[nb]=Programutseende +Name[nds]=Programmutsehn +Name[nl]=Uiterlijk van programma +Name[nn]=Program­utsjånad +Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਦਿੱਖ +Name[pl]=Wygląd programów +Name[pt]=Aparência das Aplicações +Name[pt_BR]=Aparência dos aplicativos +Name[ro]=Aspect aplicații +Name[ru]=Оформление приложений +Name[si]=යෙදුම් පෙනුම +Name[sk]=Vzhľad aplikácií +Name[sl]=Videz programov +Name[sr]=Изглед програма +Name[sr@ijekavian]=Изглед програма +Name[sr@ijekavianlatin]=Izgled programa +Name[sr@latin]=Izgled programa +Name[sv]=Programutseende +Name[tg]=Намуди зоҳирии барнома +Name[th]=รูปลักษณ์ของโปรแกรม +Name[tr]=Uygulama Görünümü +Name[ug]=پروگرامما كۆرۈنۈشى +Name[uk]=Вигляд вікон програм +Name[vi]=Diện mạo ứng dụng +Name[wa]=Rivnance des programes +Name[x-test]=xxApplication Appearancexx +Name[zh_CN]=应用程序外观 +Name[zh_TW]=應用程式外觀 diff --git a/systemsettings/categories/settings-audio-and-video.desktop b/systemsettings/categories/settings-audio-and-video.desktop new file mode 100644 index 00000000..40f94db5 --- /dev/null +++ b/systemsettings/categories/settings-audio-and-video.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=audio-and-video +X-KDE-System-Settings-Parent-Category=hardware +X-KDE-Weight=200 +Icon=applications-multimedia + +Name=Multimedia +Name[af]=Multimedia +Name[ar]=الوسائط المتعددة +Name[as]=মাল্টিমিডিয়া +Name[ast]=Multimedia +Name[be]=Мультымедыя +Name[be@latin]=Multymedyja +Name[bg]=Мултимедия +Name[bn]=মাল্টিমিডিয়া +Name[bn_IN]=মাল্টি-মিডিয়া +Name[br]=Liesvedia +Name[bs]=Multimedija +Name[ca]=Multimèdia +Name[ca@valencia]=Multimèdia +Name[cs]=Multimédia +Name[csb]=Mùltimedia +Name[cy]=Amlgyfryngau +Name[da]=Multimedie +Name[de]=Multimedia +Name[el]=Πολυμέσα +Name[en_GB]=Multimedia +Name[eo]=Aŭdvido +Name[es]=Multimedia +Name[et]=Multimeedia +Name[eu]=Multimedia +Name[fa]=چند رسانه‌ای +Name[fi]=Multimedia +Name[fr]=Multimédia +Name[fy]=Multimedia +Name[ga]=Ilmheáin +Name[gl]=Multimedia +Name[gu]=મલ્ટિમીડિઆ +Name[he]=מולטימדיה +Name[hi]=मल्टीमीडिया +Name[hne]=मल्टीमीडिया +Name[hr]=Multimedija +Name[hsb]=Multimedija +Name[hu]=Multimédia +Name[ia]=Multimedia +Name[id]=Multimedia +Name[is]=Margmiðlun +Name[it]=Multimedia +Name[ka]=მულტიმედია +Name[kk]=Мультимедиа +Name[km]=ពហុព័ត៌មាន +Name[kn]=ಬಹುಮಾಧ್ಯಮ +Name[ko]=멀티미디어 +Name[ku]=Multîmedya +Name[lt]=Multimedia +Name[lv]=Multivide +Name[mai]=मल्टीमीडिया +Name[mk]=Мултимедија +Name[ml]=മള്‍ട്ടീമീഡിയ +Name[mr]=मल्टीमीडिया +Name[ms]=Multimedia +Name[nb]=Multimedia +Name[nds]=Multimedia +Name[ne]=मल्टिमिडिया +Name[nl]=Multimedia +Name[nn]=Multimedia +Name[oc]=Multimedià +Name[or]=ବହୁମାଧ୍ଯମ +Name[pa]=ਮਲਟੀਮੀਡਿਆ +Name[pl]=Multimedia +Name[pt]=Multimédia +Name[pt_BR]=Multimídia +Name[ro]=Multimedia +Name[ru]=Мультимедиа +Name[se]=Multimedia +Name[si]=බහුමාධ්‍යය +Name[sk]=Multimédiá +Name[sl]=Predstavnost +Name[sr]=Мултимедија +Name[sr@ijekavian]=Мултимедија +Name[sr@ijekavianlatin]=Multimedija +Name[sr@latin]=Multimedija +Name[sv]=Multimedia +Name[ta]=பல்லூடகம் +Name[te]=బహుళ మాద్యమం +Name[tg]=Мултимедиа +Name[th]=มัลติมีเดีย +Name[tr]=Çoklu Ortam +Name[ug]=كۆپ ۋاسىتە +Name[uk]=Мультимедіа +Name[uz]=Multimedia +Name[uz@cyrillic]=Мултимедиа +Name[vi]=Nhạc/Ảnh +Name[wa]=Multimedia +Name[xh]=Iindlela ezininzi zokwenza +Name[x-test]=xxMultimediaxx +Name[zh_CN]=多媒体 +Name[zh_TW]=多媒體 diff --git a/systemsettings/categories/settings-bluetooth.desktop b/systemsettings/categories/settings-bluetooth.desktop new file mode 100644 index 00000000..1f050702 --- /dev/null +++ b/systemsettings/categories/settings-bluetooth.desktop @@ -0,0 +1,93 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=bluetooth +X-KDE-System-Settings-Parent-Category=network-and-connectivity +Icon=preferences-system-bluetooth + +Name=Bluetooth +Name[ar]=بلوتوث +Name[ast]=Bluetooth +Name[be]=Bluetooth +Name[be@latin]=Bluetooth +Name[bg]=Bluetooth +Name[bn]=ব্লু-টুথ +Name[bn_IN]=ব্লু-টুথ +Name[bs]=Blutut +Name[ca]=Bluetooth +Name[ca@valencia]=Bluetooth +Name[cs]=Bluetooth +Name[csb]=Bluetooth +Name[da]=Bluetooth +Name[de]=Bluetooth +Name[el]=Bluetooth +Name[en_GB]=Bluetooth +Name[eo]=Bluetooth +Name[es]=Bluetooth +Name[et]=Bluetooth +Name[eu]=Bluetootha +Name[fa]=بلوتوث +Name[fi]=Bluetooth +Name[fr]=Bluetooth +Name[fy]=Bluetooth +Name[ga]=Bluetooth +Name[gl]=Bluetooth +Name[gu]=બ્લ્યુટુથ +Name[he]=Bluetooth +Name[hi]=ब्लूटूथ +Name[hne]=ब्लूटूथ +Name[hr]=Bluetooth +Name[hu]=Bluetooth +Name[ia]=Bluetooth +Name[id]=Bluetooth +Name[is]=Blátönn +Name[it]=Bluetooth +Name[ja]=Bluetooth +Name[ka]=Bluetooth +Name[kk]=Bluetooth +Name[km]=ប៊្លូសធូស +Name[kn]=ಬ್ಲೂಟೂತ್ +Name[ko]=블루투스 +Name[ku]=Bluetooth +Name[lt]=Bluetooth +Name[lv]=Bluetooth +Name[mai]=ब्लूटूथ +Name[mk]=Bluetooth +Name[ml]=ബ്ലൂടൂത്ത് +Name[mr]=ब्लूटूथ +Name[ms]=Bluetooth +Name[nb]=Bluetooth +Name[nds]=Bluetooth +Name[ne]=ब्लुटुथ +Name[nl]=Bluetooth +Name[nn]=Bluetooth +Name[or]=ବ୍ଲୁଟୁଥ +Name[pa]=ਬਲਿਊਟੁੱਥ +Name[pl]=Bluetooth +Name[pt]=Bluetooth +Name[pt_BR]=Bluetooth +Name[ro]=Bluetooth +Name[ru]=Bluetooth +Name[se]=Bluetooth +Name[si]=Bluetooth +Name[sk]=Bluetooth +Name[sl]=Bluetooth +Name[sr]=Блутут +Name[sr@ijekavian]=Блутут +Name[sr@ijekavianlatin]=Bluetooth +Name[sr@latin]=Bluetooth +Name[sv]=Blåtand +Name[ta]=Bluetooth +Name[te]=బ్లూటూత్ +Name[tg]=Bluetooth +Name[th]=บลูทูธ +Name[tr]=Bluetooth +Name[ug]=كۆكچىش +Name[uk]=Bluetooth +Name[uz]=Bluetooth +Name[uz@cyrillic]=Bluetooth +Name[vi]=Bluetooth +Name[wa]=Bluetooth +Name[x-test]=xxBluetoothxx +Name[zh_CN]=蓝牙 +Name[zh_TW]=藍牙 diff --git a/systemsettings/categories/settings-desktop-appearance.desktop b/systemsettings/categories/settings-desktop-appearance.desktop new file mode 100644 index 00000000..57e0a148 --- /dev/null +++ b/systemsettings/categories/settings-desktop-appearance.desktop @@ -0,0 +1,131 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=desktop-appearance +X-KDE-System-Settings-Parent-Category=workspace-appearance-and-behavior +X-KDE-Weight=80 +Icon=preferences-desktop-theme + +Name=Workspace Appearance +Name[ar]=مظهر مساحة العمل +Name[ast]=Apariencia del espaciu de trabayu +Name[bg]=Изглед на работния плот +Name[bn]=ওয়ার্কস্পেস-এর চেহারা +Name[bs]=Izgled radnog prostora +Name[ca]=Aparença de l'espai de treball +Name[ca@valencia]=Aparença de l'espai de treball +Name[cs]=Vzhled pracovní plochy +Name[da]=Arbejdsområdets udseende +Name[de]=Erscheinungsbild der Arbeitsfläche +Name[el]=Εμφάνιση χώρου εργασίας +Name[en_GB]=Workspace Appearance +Name[es]=Apariencia del espacio de trabajo +Name[et]=Töötsooni välimus +Name[eu]=Laneko eremuaren itxura +Name[fi]=Työtilan ulkoasu +Name[fr]=Apparence de l'espace de travail +Name[ga]=Cuma an Spáis Oibre +Name[gl]=Aparencia do espazo de traballo +Name[he]=מראה סביבת העבודה +Name[hi]=कार्यक्षेत्र रूप +Name[hr]=Izgled radnog prostora +Name[hu]=Megjelenés +Name[ia]=Apparentia del spatio de labor (Workspace) +Name[id]=Tampilan Ruang Kerja +Name[is]=Útlit vinnusvæða +Name[it]=Aspetto dello spazio di lavoro +Name[ja]=ワークスペースの外観 +Name[kk]=Жұмыс орның көрінісі +Name[km]=រូបរាង​តំបន់​ធ្វើការ +Name[kn]=ಕಾರ್ಯಕ್ಷೇತ್ರ ಗೋಚರಿಕೆ +Name[ko]=작업 공간 모양 +Name[lt]=Darbo erdvės išvaizda +Name[lv]=Darba telpas izskats +Name[mr]=कार्यस्थान दर्शनीयता +Name[nb]=Utseende for arbeidsflaten +Name[nds]=Arbeitrebeet-Utsehn +Name[nl]=Uiterlijk van werkruimte +Name[nn]=Utsjånad på arbeids­område +Name[pa]=ਵਰਕਸਪੇਸ ਦਿੱਖ +Name[pl]=Wygląd przestrzeni roboczej +Name[pt]=Aparência da Área de Trabalho +Name[pt_BR]=Aparência do espaço de trabalho +Name[ro]=Aspect spațiu de lucru +Name[ru]=Оформление рабочей среды +Name[si]=වැඩබිම් පෙනුම +Name[sk]=Vzhľad pracovnej plochy +Name[sl]=Videz delovnega prostora +Name[sr]=Изглед радног простора +Name[sr@ijekavian]=Изглед радног простора +Name[sr@ijekavianlatin]=Izgled radnog prostora +Name[sr@latin]=Izgled radnog prostora +Name[sv]=Arbetsytans utseende +Name[tg]=Намуди зоҳирии муҳити корӣ +Name[th]=รูปลักษณ์ของพื้นที่ทำงาน +Name[tr]=Çalışma Alanı Görünümü +Name[ug]=خىزمەت بوشلۇقىنىڭ كۆرۈنۈشى +Name[uk]=Вигляд робочого простору +Name[vi]=Diện mạo không gian làm việc +Name[wa]=Rivnance di l' espåce di boutaedje +Name[x-test]=xxWorkspace Appearancexx +Name[zh_CN]=工作空间外观 +Name[zh_TW]=工作空間外觀與行為 +Comment=Customize the appearance of your desktop +Comment[ar]=خصص مظهر سطح المكتب الخاص بك +Comment[ast]=Personalizar l'apariencia del escritoriu +Comment[bg]=Настройки на изгледа на работния плот +Comment[bs]=Prilagodite izgled svoje površi +Comment[ca]=Personalitza l'aparença de l'escriptori +Comment[ca@valencia]=Personalitza l'aparença de l'escriptori +Comment[cs]=Upravit vzhled vaší plochy +Comment[da]=Tilpas skrivebordets udseende +Comment[de]=Arbeitsflächen-Design anpassen +Comment[el]=Προσαρμογή της εμφάνισης της επιφάνειας εργασίας +Comment[en_GB]=Customise the appearance of your desktop +Comment[es]=Personalizar la apariencia del escritorio +Comment[et]=Töölaua välimuse kohandamine +Comment[eu]=Pertsonalizatu mahaigainaren itxura +Comment[fi]=Mukauta työpöytäsi ulkoasua +Comment[fr]=Personnalise l'apparence de votre bureau +Comment[ga]=Cumraigh cuma do dheisce +Comment[gl]=Personaliza a aparencia do escritorio +Comment[he]=התאמה אישית של מראה שולחן העבודה +Comment[hi]=डेस्कटॉप प्रसंग मनपसंद बनाएँ +Comment[hr]=Prilagodite izgled Vaše radne površine +Comment[hu]=Az asztal megjelenésének testreszabása +Comment[ia]=Personalisa le apparentia de tu scriptorio +Comment[is]=Sérsníða útlit skjáborðsins +Comment[it]=Personalizza l'aspetto del desktop +Comment[ja]=デスクトップの外観をカスタマイズ +Comment[kk]=Үстел көрінісін өзінше баптап алу +Comment[km]=ប្ដូរ​រូបរាង​ផ្ទៃតុ​របស់​អ្នក​តាម​បំណង +Comment[kn]=ನಿಮ್ಮ ಗಣಕತೆರೆ ಪರಿಸರವಿನ್ಯಾಸವನ್ನು ಇಚ್ಛೆಗೆ ತಕ್ಕಂತೆ ಹೊಂದಿಸಿ +Comment[ko]=데스크톱 모습 사용자 정의 +Comment[lt]=Derinti jūsų darbastalio išvaizdą +Comment[lv]=Pielāgot jūsu darbvirsmas izskatu +Comment[mr]=डेस्कटॉप कसा दिसावा त्यात ऐच्छिक बदल करा +Comment[nb]=Tilpass utseendet for skrivebordet +Comment[nds]=Dat Schriefdischutsehn topassen +Comment[nl]=Pas het uiterlijk van uw bureaublad aan +Comment[pa]=ਆਪਣੇ ਡੈਸਕਟਾਪ ਲਈ ਦਿੱਖ ਬਦਲੋ +Comment[pl]=Dostosowywanie wyglądu pulpitu +Comment[pt]=Personalizar a aparência do seu ambiente de trabalho +Comment[pt_BR]=Personaliza a aparência da sua área de trabalho +Comment[ro]=Personalizați aspectul biroului +Comment[ru]=Настройка внешнего вида рабочего стола +Comment[sk]=Prispôsobenie vzhľadu vašej pracovnej plochy +Comment[sl]=Prilagodite videz svojega namizja +Comment[sr]=Прилагодите изглед своје површи +Comment[sr@ijekavian]=Прилагодите изглед своје површи +Comment[sr@ijekavianlatin]=Prilagodite izgled svoje površi +Comment[sr@latin]=Prilagodite izgled svoje površi +Comment[sv]=Anpassa skrivbordets utseende +Comment[th]=ปรับแต่งรูปลักษณ์ของพื้นที่ทำงาน +Comment[tr]=Masaüstünüzün görünümünü özelleştirin +Comment[ug]=ئۈستەلئۈستىڭىزنىڭ قىياپىتىنى ئۆزلەشتۈر +Comment[uk]=Налаштування зовнішнього вигляду вашої стільниці +Comment[vi]=Tuỳ chỉnh diện mạo màn hình làm việc của bạn +Comment[wa]=Mete a vosse môde li rivnance di vosse sicribanne +Comment[x-test]=xxCustomize the appearance of your desktopxx +Comment[zh_CN]=定制桌面外观 +Comment[zh_TW]=自訂桌面外觀 diff --git a/systemsettings/categories/settings-display.desktop b/systemsettings/categories/settings-display.desktop new file mode 100644 index 00000000..52ca39ab --- /dev/null +++ b/systemsettings/categories/settings-display.desktop @@ -0,0 +1,160 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=display +X-KDE-System-Settings-Parent-Category=hardware +Icon=preferences-desktop-display + +Name=Display and Monitor +Name[ar]=العرض والشاشة +Name[ast]=Pantalla y monitor +Name[bg]=Екран и монитор +Name[bn]=ডিসপ্লে ও মনিটর +Name[bs]=Prikaz i monitor +Name[ca]=Pantalla i monitor +Name[ca@valencia]=Pantalla i monitor +Name[cs]=Obrazovka a monitor +Name[da]=Skærm +Name[de]=Anzeige und Monitor +Name[el]=Απεικόνιση και οθόνη +Name[en_GB]=Display and Monitor +Name[es]=Pantalla y monitor +Name[et]=Ekraan ja monitor +Name[eu]=Bistaratzea eta monitorea +Name[fi]=Näyttö +Name[fr]=Affichage et surveillance +Name[ga]=Scáileán agus Monatóir +Name[gl]=Pantalla e monitor +Name[he]=תצוגה וצגים +Name[hr]=Zaslon i monitor +Name[hu]=Kijelző és monitor +Name[ia]=Monstrator e Monitor +Name[id]=Tampilan dan Monitor +Name[is]=Skjáir og birting +Name[it]=Schermo e video +Name[ja]=ディスプレイとモニタ +Name[kk]=Дисплей мен монитор +Name[km]=បង្ហាញ និង​ត្រួតពិនិត្យ +Name[kn]=ಪ್ರದರ್ಶಕ ಹಾಗು ವ್ಯವಸ್ಥಾಪಕ +Name[ko]=디스플레이와 모니터 +Name[lt]=Ekranas ir monitorius +Name[lv]=Ekrāns un monitors +Name[mr]=डिस्प्ले व मॉनिटर +Name[nb]=Skjerm og monitor +Name[nds]=Schirm un Monitor +Name[nl]=Scherm en monitor +Name[nn]=Skjerm og skjerm­bilete +Name[pa]=ਡਿਸਪਲੇਅ ਤੇ ਮਾਨੀਟਰ +Name[pl]=Wyświetlanie i monitor +Name[pt]=Ecrã e Monitor +Name[pt_BR]=Tela e monitor +Name[ro]=Afișaj și monitor +Name[ru]=Экран +Name[si]=ප්‍රදර්ශනය සහ මොනිටරය +Name[sk]=Obrazovka a monitor +Name[sl]=Zasloni in prikazovalniki +Name[sr]=Приказ и монитор +Name[sr@ijekavian]=Приказ и монитор +Name[sr@ijekavianlatin]=Prikaz i monitor +Name[sr@latin]=Prikaz i monitor +Name[sv]=Bildskärm +Name[th]=ระบบแสดงผลและจอภาพ +Name[tr]=Görüntü ve Ekran +Name[ug]=كۆرسىتىش ۋە كۆزەتكۈچ +Name[uk]=Показ зображення і монітор +Name[vi]=Màn hình và hiển thị +Name[wa]=Håynaedje eyet waitroûle +Name[x-test]=xxDisplay and Monitorxx +Name[zh_CN]=显示和监控 +Name[zh_TW]=顯示與螢幕 +Comment=Display Settings +Comment[af]=Skerm Instellings +Comment[ar]=إعدادات العرض +Comment[ast]=Preferencies de la pantalla +Comment[be]=Настаўленні экрану +Comment[be@latin]=Nałady ekrana +Comment[bg]=Настройки на екрана +Comment[bn]=ডিসপ্লে সেটিংস +Comment[bn_IN]=প্রদর্শন সংক্রান্ত বৈশিষ্ট্য +Comment[br]=Kefluniañ an diskwel +Comment[bs]=Postavke ekrana +Comment[ca]=Arranjament de la pantalla +Comment[ca@valencia]=Arranjament de la pantalla +Comment[cs]=Nastavení obrazovky +Comment[csb]=Ùstôw ekranu +Comment[cy]=Gosodiadau Arddangos +Comment[da]=Skærmindstillinger +Comment[de]=Anzeige-Einstellungen +Comment[el]=Ρυθμίσεις οθόνης +Comment[en_GB]=Display Settings +Comment[eo]=Vidigila agordo +Comment[es]=Preferencias de la pantalla +Comment[et]=Monitoride seadistused +Comment[eu]=Pantailaren ezarpenak +Comment[fa]=نمایش تنظیمات +Comment[fi]=Näytön asetukset +Comment[fr]=Configuration de l'affichage +Comment[fy]=Byldskerm ynstellings +Comment[ga]=Socruithe an Scáileáin +Comment[gl]=Configuración da pantalla +Comment[gu]=ડિસ્પ્લે ગોઠવણીઓ +Comment[he]=הגדרות תצוגה +Comment[hi]=प्रकटन विन्यास +Comment[hne]=देखइया सेटिंग +Comment[hr]=Postavke zaslona +Comment[hsb]=Nastajenja za wobrazowku +Comment[hu]=Megjelenési beállítások +Comment[ia]=Monstra preferentias +Comment[id]=Pengaturan Tampilan +Comment[is]=Stillingar skjás +Comment[it]=Impostazioni dello schermo +Comment[ja]=ディスプレイの設定 +Comment[ka]=დისპლეის კონფიგურირება +Comment[kk]=Дисплей баптаулары +Comment[km]=កំណត់​ការ​បង្ហាញ +Comment[kn]=ಪ್ರದರ್ಶಕದ ಸಂಯೋಜನೆಗಳು +Comment[ko]=디스플레이 설정 +Comment[ku]=Mîhengên Dîmenderê +Comment[lt]=Ekrano parametrai +Comment[lv]=Ekrāna parametri +Comment[mai]=जमावट देखाबू +Comment[mk]=Поставувања на приказот +Comment[ml]=പ്രദര്‍ശനത്തിന്റെ സജ്ജീകരണങ്ങള്‍ +Comment[mr]=डिस्प्ले संयोजना +Comment[ms]=Seting Paparan +Comment[nb]=Skjerminnstillinger +Comment[nds]=Dorstellen inrichten +Comment[ne]=सेटिङ प्रदर्शन गर्नुहोस् +Comment[nl]=Beeldscherminstellingen +Comment[nn]=Skjerminnstillingar +Comment[or]=ପ୍ରଦର୍ଶକ ସଂରଚନା +Comment[pa]=ਡਿਸਪਲੇਅ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia ekranu +Comment[pt]=Configuração do ecrã +Comment[pt_BR]=Configurações da tela +Comment[ro]=Configurări afișare +Comment[ru]=Настройка экрана +Comment[se]=Šearbmaheivehusat +Comment[si]=සංදර්ශන සැකසුම් +Comment[sk]=Nastavenie obrazovky +Comment[sl]=Nastavitve zaslona +Comment[sr]=Поставке екрана +Comment[sr@ijekavian]=Поставке екрана +Comment[sr@ijekavianlatin]=Postavke ekrana +Comment[sr@latin]=Postavke ekrana +Comment[sv]=Anpassa bildskärm +Comment[ta]=அமைப்புகளை காட்டு +Comment[te]=ప్రదర్శన అమరికలు +Comment[tg]=Танзимоти экран +Comment[th]=ตั้งค่าต่าง ๆ ของการแสดงผล +Comment[tr]=Ekran Ayarları +Comment[ug]=كۆرۈنمە يۈز تەڭشىكى +Comment[uk]=Налаштування дисплея +Comment[uz]=Displeyning moslamalari +Comment[uz@cyrillic]=Дисплейнинг мосламалари +Comment[vi]=Thiết lập hiển thị +Comment[wa]=Apontiaedjes do Håynaedje +Comment[x-test]=xxDisplay Settingsxx +Comment[zh_CN]=显示设置 +Comment[zh_TW]=顯示設定 + diff --git a/systemsettings/categories/settings-hardware.desktop b/systemsettings/categories/settings-hardware.desktop new file mode 100644 index 00000000..68bbc717 --- /dev/null +++ b/systemsettings/categories/settings-hardware.desktop @@ -0,0 +1,94 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=hardware +X-KDE-System-Settings-Parent-Category= +X-KDE-Weight=200 +Icon=preferences-desktop-peripherals + +Name=Hardware +Name[ar]=العتاد +Name[ast]=Hardware +Name[be]=Прылады +Name[be@latin]=Aparatura +Name[bg]=Хардуер +Name[bn]=হার্ডওয়্যার +Name[bn_IN]=হার্ডওয়্যার +Name[br]=Periantel +Name[bs]=Hardver +Name[ca]=Maquinari +Name[ca@valencia]=Maquinari +Name[cs]=Hardware +Name[cy]=Caledwedd +Name[da]=Hardware +Name[de]=Hardware +Name[el]=Υλικό +Name[en_GB]=Hardware +Name[eo]=Aparataro +Name[es]=Hardware +Name[et]=Riistvara +Name[eu]=Hardwarea +Name[fa]=سخت‌افزار +Name[fi]=Laitteisto +Name[fr]=Matériel +Name[fy]=Hardware +Name[ga]=Crua-Earraí +Name[gl]=Hardware +Name[gu]=હાર્ડવેર +Name[he]=חומרה +Name[hi]=हार्डवेयर +Name[hne]=हार्डवेयर +Name[hr]=Hardver +Name[hu]=Hardver +Name[ia]=Hardware +Name[id]=Peranti Keras +Name[is]=Vélbúnaður +Name[it]=Hardware +Name[ja]=ハードウェア +Name[ka]=მოწყობილობები +Name[kk]=Жабдық +Name[km]=ផ្នែក​រឹង +Name[kn]=ಯಂತ್ರಾಂಶ +Name[ko]=하드웨어 +Name[ku]=Reqalav +Name[lt]=Aparatinė įranga +Name[lv]=Aparatūra +Name[mai]=हार्डवेयर +Name[mk]=Хардвер +Name[ml]=ഹാര്‍ഡ്‌വെയര്‍ +Name[mr]=हार्डवेअर +Name[nb]=Maskinvare +Name[nds]=Hardware +Name[ne]=हार्डवेयर +Name[nl]=Hardware +Name[nn]=Maskinvare +Name[or]=ହାର୍ଡୱେର +Name[pa]=ਹਾਰਡਵੇਅਰ +Name[pl]=Sprzęt +Name[pt]='Hardware' +Name[pt_BR]=Hardware +Name[ro]=Echipament +Name[ru]=Оборудование +Name[se]=Mašiidnagálvu +Name[si]=දෘඩාංග +Name[sk]=Hardvér +Name[sl]=Strojna oprema +Name[sr]=Хардвер +Name[sr@ijekavian]=Хардвер +Name[sr@ijekavianlatin]=Hardver +Name[sr@latin]=Hardver +Name[sv]=Hårdvara +Name[ta]=Hardware +Name[te]=హార్డువేర్ +Name[tg]=Сахтафзор +Name[th]=ฮาร์ดแวร์ +Name[tr]=Donanım +Name[ug]=قاتتىق دېتال +Name[uk]=Обладнання +Name[uz]=Asbob-uskunalar +Name[uz@cyrillic]=Асбоб-ускуналар +Name[vi]=Phần cứng +Name[wa]=Éndjolreye +Name[x-test]=xxHardwarexx +Name[zh_CN]=硬件 +Name[zh_TW]=硬體 diff --git a/systemsettings/categories/settings-input-devices.desktop b/systemsettings/categories/settings-input-devices.desktop new file mode 100644 index 00000000..8f52ad93 --- /dev/null +++ b/systemsettings/categories/settings-input-devices.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=input-devices +X-KDE-System-Settings-Parent-Category=hardware +Icon=preferences-desktop-peripherals + +Name=Input Devices +Name[ar]=أجهزة الإدخال +Name[ast]=Preseos d'entrada +Name[bg]=Входни устройства +Name[bn]=ইনপুট ডিভাইস +Name[bs]=Uređaji +Name[ca]=Dispositius d'entrada +Name[ca@valencia]=Dispositius d'entrada +Name[cs]=Vstupní zařízení +Name[da]=Input-enheder +Name[de]=Eingabegeräte +Name[el]=Συσκευές εισόδου +Name[en_GB]=Input Devices +Name[es]=Dispositivos de entrada +Name[et]=Sisendseadmed +Name[eu]=Sarrerako gailuak +Name[fi]=Näppäimistö ja syöttölaitteet +Name[fr]=Périphériques d'entrée +Name[ga]=Gléasanna Ionchurtha +Name[gl]=Dispositivos de entrada +Name[gu]=ઇનપુટ ઉપકરણો +Name[he]=התקני קלט +Name[hi]=इंपुट औज़ार +Name[hr]=Ulazni uređaji +Name[hu]=Beviteli eszközök +Name[ia]=Dispositivos de Ingresso +Name[id]=Divais Masukan +Name[is]=Inntakstæki +Name[it]=Dispositivi di immissione +Name[ja]=入力デバイス +Name[kk]=Енгізу құрылғылар +Name[km]=ឧបករណ៍​បញ្ចូល +Name[kn]=ಇನ್ ಪುಟ್ ಸಾಧನಗಳು +Name[ko]=입력 장치 +Name[lt]=Įvedimo įrenginiai +Name[lv]=Ievades iekārtas +Name[mr]=इनपुट साधने +Name[nb]=Inndataenheter +Name[nds]=Ingaav-Reedschappen +Name[nl]=Invoerapparaten +Name[nn]=Inn­einingar +Name[pa]=ਇੰਪੁੱਟ ਜੰਤਰ +Name[pl]=Urządzenia wejściowe +Name[pt]=Dispositivos de Entrada +Name[pt_BR]=Dispositivos de entrada +Name[ro]=Dispozitive de intrare +Name[ru]=Устройства ввода +Name[si]=ආදාන මෙවලම් +Name[sk]=Vstupné zariadenia +Name[sl]=Vhodne naprave +Name[sr]=Улазни уређаји +Name[sr@ijekavian]=Улазни уређаји +Name[sr@ijekavianlatin]=Ulazni uređaji +Name[sr@latin]=Ulazni uređaji +Name[sv]=Inmatningsenheter +Name[tg]=Дастгоҳҳои воридотӣ +Name[th]=อุปกรณ์ป้อนข้อมูล +Name[tr]=Girdi Aygıtları +Name[ug]=كىرگۈزۈش ئۈسكۈنىسى +Name[uk]=Пристрої введення +Name[vi]=Thiết bị nhập +Name[wa]=Éndjins èn intrêye +Name[x-test]=xxInput Devicesxx +Name[zh_CN]=输入设备 +Name[zh_TW]=輸入裝置 + diff --git a/systemsettings/categories/settings-locale.desktop b/systemsettings/categories/settings-locale.desktop new file mode 100644 index 00000000..02c326ac --- /dev/null +++ b/systemsettings/categories/settings-locale.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=locale +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-locale + +Name=Locale +Name[ar]=المحليّة +Name[ast]=Llocal +Name[bn]=লোকেল +Name[bs]=Lokalitet +Name[ca]=Localització +Name[ca@valencia]=Localització +Name[cs]=Lokalizace +Name[da]=Lokalitet +Name[de]=Regionales +Name[el]=Τοπικότητα +Name[en_GB]=Locale +Name[es]=Local +Name[et]=Keeleseadistused +Name[eu]=Eskualde-ezarpenak +Name[fi]=Alue ja kieli +Name[fr]=Localisation +Name[ga]=Logchaighdeán +Name[gl]=Configuración rexional +Name[gu]=સ્થાનિય +Name[he]=מיקום +Name[hi]=लोकेल +Name[hr]=Lokalne postavke +Name[hu]=Nyelvi beállítások +Name[ia]=Local +Name[id]=Locale +Name[is]=Staðfærsla +Name[it]=Localizzazione +Name[ja]=ロケール +Name[ka]=ენა +Name[kk]=Жергілікті стандарттар +Name[km]=មូលដ្ឋាន +Name[kn]=ಪ್ರಾದೇಶಿಕ +Name[ko]=로캘 +Name[lt]=Lokalė +Name[lv]=Lokāle +Name[mr]=स्थानिक +Name[nb]=Lokale +Name[nds]=Spraakinstellen +Name[nl]=Taalregio +Name[nn]=Land og språk +Name[pa]=ਲੋਕੇਲ +Name[pl]=Ustawienia regionalne +Name[pt]=Localização +Name[pt_BR]=Localização +Name[ro]=Localizare +Name[ru]=Локаль +Name[si]=ස්ථානය +Name[sk]=Lokalizácia +Name[sl]=Krajevne nastavitve +Name[sr]=Локалитет +Name[sr@ijekavian]=Локалитет +Name[sr@ijekavianlatin]=Lokalitet +Name[sr@latin]=Lokalitet +Name[sv]=Plats +Name[tg]=Маҳаллӣ +Name[th]=ภาษาระบบ +Name[tr]=Yerel +Name[ug]=رايون +Name[uk]=Локаль +Name[vi]=Vùng +Name[wa]=Lingaedje/payis +Name[x-test]=xxLocalexx +Name[zh_CN]=语系 +Name[zh_TW]=地域 diff --git a/systemsettings/categories/settings-lost-and-found.desktop b/systemsettings/categories/settings-lost-and-found.desktop new file mode 100644 index 00000000..eb379e2d --- /dev/null +++ b/systemsettings/categories/settings-lost-and-found.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=lost-and-found +X-KDE-System-Settings-Parent-Category= +X-KDE-Weight=250 +Icon=applications-system + +Name=Lost and Found +Name[ar]=المفقودات +Name[ast]=Oxetos perdíos +Name[bn]=হারানো প্রাপ্তি +Name[bs]=Izgubljeno-nađeno +Name[ca]=Perdut i trobat +Name[ca@valencia]=Perdut i trobat +Name[cs]=Ztráty a nálezy +Name[da]=Hittegods +Name[de]=Nicht zuzuordnen +Name[el]=Χάθηκαν και βρέθηκαν +Name[en_GB]=Lost and Found +Name[es]=Objetos perdidos +Name[et]=Kaotatud ja leitud +Name[eu]=Galdutako gauzak +Name[fi]=Sekalaiset +Name[fr]=Objets perdus et retrouvés +Name[ga]=Earraí Caillte +Name[gl]=Obxectos perdidos +Name[gu]=ખોવાયેલ અને મળેલ +Name[he]=אבידות ומציאות +Name[hi]=खोया व पाया +Name[hr]=Izgubljeno i nađeno +Name[hu]=Elveszett és megtalált +Name[ia]=Trovate e perdite +Name[id]=Hilang dan Ditemukan +Name[is]=Tapað og fundið +Name[it]=Oggetti smarriti +Name[ja]=Lost and Found +Name[kk]=Жоғалған мен табылғандар +Name[km]=បាត់ ហើយ​រកឃើញ +Name[kn]=ಲುಪ್ತ ಮತ್ತು ಲಬ್ಧ +Name[ko]=기타 프로그램 +Name[lt]=Pamesta ir rasta +Name[lv]=Pazudis un atrasts +Name[mr]=हरवले व सापडले +Name[nb]=Tapt og funnet +Name[nds]=Passt narms sünst +Name[nl]=Verloren en gevonden +Name[nn]=Tapt og funne +Name[pa]=ਗੁਆਚੇ ਅਤੇ ਲੱਭੇ +Name[pl]=Zgubione i znalezione +Name[pt]=Perdidos e Achados +Name[pt_BR]=Achados e perdidos +Name[ro]=Pierdute și regăsite +Name[ru]=Прочее +Name[si]=නැතිවී සොයා ගැනුනි +Name[sk]=Straty a nálezy +Name[sl]=Izgubljeno in najdeno +Name[sr]=Изгубљено-нађено +Name[sr@ijekavian]=Изгубљено-нађено +Name[sr@ijekavianlatin]=Izgubljeno-nađeno +Name[sr@latin]=Izgubljeno-nađeno +Name[sv]=Hittegods +Name[th]=หาไม่เจอดูที่นี่ +Name[tr]=Kayıp ve Bulunanlar +Name[ug]=يوقالغان ۋە تېپىلغان +Name[uk]=Втрачено і знайдено +Name[vi]=Mất và tìm +Name[wa]=Pierdous eyet rtrovés +Name[x-test]=xxLost and Foundxx +Name[zh_CN]=未知类别 +Name[zh_TW]=Lost & Found diff --git a/systemsettings/categories/settings-network-and-connectivity.desktop b/systemsettings/categories/settings-network-and-connectivity.desktop new file mode 100644 index 00000000..639674bc --- /dev/null +++ b/systemsettings/categories/settings-network-and-connectivity.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=network-and-connectivity +X-KDE-System-Settings-Parent-Category= +Icon=preferences-system-network-connection + +Name=Network and Connectivity +Name[ar]=الشبكة والاتصال +Name[ast]=Rede y conectividá +Name[bg]=Мрежова свързаност +Name[bn]=নেটওয়ার্ক এবং সংযোগ +Name[bs]=Mreža i povezivost +Name[ca]=Xarxa i connectivitat +Name[ca@valencia]=Xarxa i connectivitat +Name[cs]=Síť a připojení +Name[da]=Netværk og forbindelse +Name[de]=Netzwerk und Verbindungen +Name[el]=Δίκτυο και συνδεσιμότητα +Name[en_GB]=Network and Connectivity +Name[es]=Red y conectividad +Name[et]=Võrk ja ühendused +Name[eu]=Sarea eta konektagarritasuna +Name[fi]=Verkko ja yhteydet +Name[fr]=Réseau et connectivité +Name[ga]=Líonra agus Comhcheangailteacht +Name[gl]=Rede e conectividade +Name[gu]=નેટવર્ક અને જોડાણ +Name[he]=רשת וחיבוריות +Name[hi]=नेटवर्क व जुडाव +Name[hr]=Mreža i spojivost +Name[hu]=Hálózat és kapcsolat +Name[ia]=Rete e connectivitate +Name[id]=Jaringan dan Konektivitas +Name[is]=Net og tengingar +Name[it]=Rete e connettività +Name[ja]=ネットワークと接続 +Name[kk]=Желі мен Байланыс +Name[km]=បណ្តាញ និង​ការតភ្ជាប់ +Name[kn]=ಜಾಲಬಂಧ ಮತ್ತು ಸಂಪರ್ಕ +Name[ko]=네트워크와 연결 +Name[lt]=Tinklas ir prisijungimai +Name[lv]=Tīkls un savienojumi +Name[mr]=संजाळ व जुळवणी +Name[nb]=Nettverk og tilkoblinger +Name[nds]=Nettwark un Verbinnen +Name[nl]=Netwerk en connectiviteit +Name[nn]=Nettverk og samband +Name[pa]=ਨੈੱਟਵਰਕ ਅਤੇ ਕੁਨੈਕਟਵਿਟੀ +Name[pl]=Sieć i łączność +Name[pt]=Rede e Conectividade +Name[pt_BR]=Rede e conectividade +Name[ro]=Rețea și conectivitate +Name[ru]=Сеть и связь +Name[si]=ජාල සහ සම්බන්ධතාවය +Name[sk]=Sieť a pripojenie +Name[sl]=Omrežje in povezljivost +Name[sr]=Мрежа и повезивост +Name[sr@ijekavian]=Мрежа и повезивост +Name[sr@ijekavianlatin]=Mreža i povezivost +Name[sr@latin]=Mreža i povezivost +Name[sv]=Nätverk och anslutningar +Name[tg]=Шабака ва пайвастшавӣ +Name[th]=เครือข่ายและการเชื่อมต่อ +Name[tr]=Ağ ve Bağlanabilirlik +Name[ug]=تور ۋە باغلىنىش +Name[uk]=Мережа і з'єднання +Name[vi]=Kết nối và mạng +Name[wa]=Rantoele eyet raloyaedje +Name[x-test]=xxNetwork and Connectivityxx +Name[zh_CN]=网络和连接 +Name[zh_TW]=網路與連線 diff --git a/systemsettings/categories/settings-network-settings.desktop b/systemsettings/categories/settings-network-settings.desktop new file mode 100644 index 00000000..a2c74d18 --- /dev/null +++ b/systemsettings/categories/settings-network-settings.desktop @@ -0,0 +1,95 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=network-settings +X-KDE-System-Settings-Parent-Category=network-and-connectivity +Icon=preferences-system-network + +Name=Network Settings +Name[ar]=إعدادات الشبكة +Name[ast]=Preferencies de rede +Name[be]=Настаўленні сеткі +Name[be@latin]=Nałady sietki +Name[bg]=Мрежови настройки +Name[bn]=নেটওয়ার্ক সেটিংস +Name[bn_IN]=নেটওয়ার্ক সংক্রান্ত বৈশিষ্ট্য +Name[br]=Kefluniadur ar Rouedad +Name[bs]=Mrežne postavke +Name[ca]=Paràmetres de xarxa +Name[ca@valencia]=Paràmetres de xarxa +Name[cs]=Nastavení sítě +Name[csb]=Sécowi nastôw +Name[da]=Netværksindstillinger +Name[de]=Netzwerkeinstellungen +Name[el]=Ρυθμίσεις δικτύου +Name[en_GB]=Network Settings +Name[eo]=Reta agordo +Name[es]=Preferencias de red +Name[et]=Võrguseadistused +Name[eu]=Sareko ezarpenak +Name[fa]=تنظیمات شبکه +Name[fi]=Verkkoasetukset +Name[fr]=Configuration de réseau +Name[fy]=Netwurk ynstellings +Name[ga]=Socruithe Líonra +Name[gl]=Configuración da rede +Name[gu]=નેટવર્ક ગોઠવણીઓ +Name[he]=הגדרות רשת +Name[hi]=नेटवर्क विन्यास +Name[hne]=नेटवर्क सेटिंग +Name[hr]=Postavke mreže +Name[hu]=Hálózati beállítások +Name[ia]=Preferentias de rete +Name[id]=Pengaturan Jaringan +Name[is]=Netstillingar +Name[it]=Impostazioni di rete +Name[ja]=ネットワークの設定 +Name[ka]=ქსელის პარამეტრები +Name[kk]=Желі параметрлері +Name[km]=ការ​កំណត់​បណ្តាញ​ +Name[kn]=ಜಾಲ ಸಂಯೋಜನೆಗಳು +Name[ko]=네트워크 설정 +Name[ku]=Mîhengên Torê +Name[lt]=Tinklo nustatymai +Name[lv]=Tīkla iestatījumi +Name[mai]=नेटवर्क विन्यास +Name[mk]=Поставувања за мрежа +Name[ml]=ശൃംഖലയുടെ സജ്ജീകരണങ്ങള്‍ +Name[mr]=संजाळ संयोजना +Name[ms]=Tetapan Rangkaian +Name[nb]=Nettverksinnstillinger +Name[nds]=Nettwarkinstellen +Name[ne]=सञ्जाल सेटिङ +Name[nl]=Netwerkinstellingen +Name[nn]=Nettverk +Name[oc]=Paramètres ret +Name[or]=ନେଟୱର୍କ ବିନ୍ୟାସ +Name[pa]=ਨੈੱਟਵਰਕ ਸੈਟਿੰਗ +Name[pl]=Ustawienia sieci +Name[pt]=Configuração da Rede +Name[pt_BR]=Configurações de rede +Name[ro]=Configurări rețea +Name[ru]=Настройка сети +Name[se]=Fierpmádatheivehusat +Name[si]=ජාල සැකසුම් +Name[sk]=Nastavenie siete +Name[sl]=Nastavitve omrežja +Name[sr]=Мрежне поставке +Name[sr@ijekavian]=Мрежне поставке +Name[sr@ijekavianlatin]=Mrežne postavke +Name[sr@latin]=Mrežne postavke +Name[sv]=Nätverksinställningar +Name[ta]=Network Settings +Name[te]=నెట్వర్‍క్ అమర్పులు +Name[tg]=Танзимотҳои Интернетӣ +Name[th]=ตั้งค่าระบบเครือข่าย +Name[tr]=Ağ Ayarları +Name[ug]=تور تەڭشەكلىرى +Name[uk]=Мережні параметри +Name[uz]=Tarmoqning moslamalari +Name[uz@cyrillic]=Тармоқнинг мосламалари +Name[vi]=Thiết lập mạng +Name[wa]=Apontiaedjes rantoele +Name[x-test]=xxNetwork Settingsxx +Name[zh_CN]=网络设置 +Name[zh_TW]=網路設定 diff --git a/systemsettings/categories/settings-permissions.desktop b/systemsettings/categories/settings-permissions.desktop new file mode 100644 index 00000000..6a5b8b49 --- /dev/null +++ b/systemsettings/categories/settings-permissions.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=permissions +X-KDE-System-Settings-Parent-Category=system-administration +Icon=preferences-other + +Name=Permissions +Name[ar]=الصلاحيات +Name[ast]=Permisos +Name[bg]=Права +Name[bn]=অনুমতি +Name[bs]=Dozvole +Name[ca]=Permisos +Name[ca@valencia]=Permisos +Name[cs]=Oprávnění +Name[da]=Rettigheder +Name[de]=Berechtigungen +Name[el]=Άδειες +Name[en_GB]=Permissions +Name[es]=Permisos +Name[et]=Õigused +Name[eu]=Baimenak +Name[fi]=Oikeudet +Name[fr]=Permissions +Name[ga]=Ceadanna +Name[gl]=Permisos +Name[gu]=પરવાનગીઓ +Name[he]=הרשאות +Name[hi]=अनुमतियाँ +Name[hr]=Dopuštenja +Name[hu]=Jogosultságok +Name[ia]=Permissiones +Name[id]=Hak Akses +Name[is]=Heimildir +Name[it]=Permessi +Name[ja]=許可 +Name[kk]=Рұқсаттар +Name[km]=សិទ្ធិ +Name[kn]=ಅನುಮತಿಗಳು +Name[ko]=권한 +Name[lt]=Leidimai +Name[lv]=Atļaujas +Name[mai]=अऩुमति +Name[mr]=परवानगी +Name[nb]=Rettigheter +Name[nds]=Verlöven +Name[nl]=Toegangsrechten +Name[nn]=Løyve +Name[pa]=ਅਧਿਕਾਰ +Name[pl]=Uprawnienia +Name[pt]=Permissões +Name[pt_BR]=Permissões +Name[ro]=Permisiuni +Name[ru]=Права доступа +Name[si]=අවසර +Name[sk]=Práva +Name[sl]=Dovoljenja +Name[sr]=Дозволе +Name[sr@ijekavian]=Дозволе +Name[sr@ijekavianlatin]=Dozvole +Name[sr@latin]=Dozvole +Name[sv]=Rättigheter +Name[tg]=Дастрасӣ +Name[th]=สิทธิ์ที่อนุญาต +Name[tr]=Yetkiler +Name[ug]=ھوقۇقلار +Name[uk]=Права доступу +Name[vi]=Quyền hạn +Name[wa]=Droets +Name[x-test]=xxPermissionsxx +Name[zh_CN]=权限 +Name[zh_TW]=權限 diff --git a/systemsettings/categories/settings-personal-information.desktop b/systemsettings/categories/settings-personal-information.desktop new file mode 100644 index 00000000..0efe607f --- /dev/null +++ b/systemsettings/categories/settings-personal-information.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=personal-information +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-user + +Name=Personal Information +Name[ar]=معلومات شخصية +Name[ast]=Información personal +Name[bg]=Лични данни +Name[bn]=ব্যক্তিগত তথ্য +Name[bs]=Lični podaci +Name[ca]=Informació personal +Name[ca@valencia]=Informació personal +Name[cs]=Osobní informace +Name[da]=Personlig information +Name[de]=Persönliche Informationen +Name[el]=Προσωπικές πληροφορίες +Name[en_GB]=Personal Information +Name[es]=Información personal +Name[et]=Isiklik teave +Name[eu]=Datu pertsonalak +Name[fa]=اطلاعات شخصی +Name[fi]=Henkilökohtaiset tiedot +Name[fr]=Informations personnelles +Name[ga]=Faisnéis Phearsanta +Name[gl]=Información persoal +Name[gu]=વ્યક્તિગત જાણકારી +Name[he]=פרטים אישיים +Name[hi]=व्यक्तिगत जानकारी +Name[hr]=Osobne informacije +Name[hu]=Személyi adatok +Name[ia]=Information personal +Name[id]=Informasi Personal +Name[is]=Persónulegar upplýsingar +Name[it]=Informazioni personali +Name[ja]=個人情報 +Name[kk]=Дербес мәлімет +Name[km]=ព័ត៌មាន​​ផ្ទាល់ខ្លួន +Name[kn]=ವೈಯಕ್ತಿಕ ಮಾಹಿತಿ +Name[ko]=개인 정보 +Name[lt]=Asmeninė informacija +Name[lv]=Personīgā informācija +Name[mr]=वैयक्तिक माहिती +Name[nb]=Personlige opplysninger +Name[nds]=Persöönliche Informatschonen +Name[nl]=Persoonlijke informatie +Name[nn]=Personleg informasjon +Name[pa]=ਨਿੱਜੀ ਜਾਣਕਾਰੀ +Name[pl]=Informacje osobiste +Name[pt]=Informação Pessoal +Name[pt_BR]=Informações pessoais +Name[ro]=Informații personale +Name[ru]=Личные данные +Name[si]=පුද්ගලික විස්තර +Name[sk]=Osobné informácie +Name[sl]=Osebni podatki +Name[sr]=Лични подаци +Name[sr@ijekavian]=Лични подаци +Name[sr@ijekavianlatin]=Lični podaci +Name[sr@latin]=Lični podaci +Name[sv]=Personlig information +Name[tg]=Иттилооти шахсӣ +Name[th]=ข้อมูลส่วนบุคคล +Name[tr]=Kişisel Bilgi +Name[ug]=شەخسىي ئۇچۇرلار +Name[uk]=Особисті відомості +Name[vi]=Thông tin cá nhân +Name[wa]=Informåcion da sinne +Name[x-test]=xxPersonal Informationxx +Name[zh_CN]=个人信息 +Name[zh_TW]=個人資訊 + diff --git a/systemsettings/categories/settings-power-management.desktop b/systemsettings/categories/settings-power-management.desktop new file mode 100644 index 00000000..8b3bdc05 --- /dev/null +++ b/systemsettings/categories/settings-power-management.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=power-management +X-KDE-System-Settings-Parent-Category=hardware +Icon=preferences-system-power-management + +Name=Power Management +Name[ar]=إدارة الطاقة +Name[ast]=Xestión d'enerxía +Name[be@latin]=Kiravańnie enerhijaj +Name[bg]=Управление на захранването +Name[bn]=পাওয়ার ব্যবস্থাপনা +Name[bn_IN]=বিদ্যুৎ সরবরাহ পরিচালনা +Name[bs]=Upravljanje napajanjem +Name[ca]=Gestió d'energia +Name[ca@valencia]=Gestió d'energia +Name[cs]=Správa napájení +Name[csb]=Sprôwianié mòcą +Name[da]=Strømstyring +Name[de]=Energieverwaltung +Name[el]=Διαχείριση ενέργειας +Name[en_GB]=Power Management +Name[eo]=Energiadministrado +Name[es]=Gestión de energía +Name[et]=Toitehaldus +Name[eu]=Energia-kudeaketa +Name[fi]=Virranhallinta +Name[fr]=Gestion de l'énergie +Name[fy]=Enerzjybehear +Name[ga]=Bainisteoireacht Cumhachta +Name[gl]=Xestión da enerxía +Name[gu]=પાવર વ્યવસ્થાપક +Name[he]=ניהול צריכת חשמל +Name[hi]=बिज़ली प्रबंधन +Name[hne]=पावर प्रबंधन +Name[hr]=Upravljanje potrošnjom energije +Name[hu]=Energiakezelő +Name[ia]=Gestion de energia +Name[id]=Manajemen Daya +Name[is]=Orkustjórnun +Name[it]=Gestione energetica +Name[ja]=電源管理 +Name[kk]=Қуаттандыруды басқару +Name[km]=ការ​គ្រប់គ្រង​ថាមពល +Name[kn]=ವಿದ್ಯುಚ್ಛಕ್ತಿ ವ್ಯವಸ್ಥಾಪನೆ +Name[ko]=전원 관리 +Name[ku]=Gerînendeyê hêzê +Name[lt]=Energijos valdymas +Name[lv]=Energokontrole +Name[mai]=पावर मैनेजमेंट +Name[mk]=Менаџмент на енергија +Name[ml]=വൈദ്യുതി നടത്തിപ്പു് +Name[mr]=वीज व्यवस्थापन +Name[nb]=Strømstyring +Name[nds]=Stroomkuntrull +Name[nl]=Energiebeheer +Name[nn]=Straumstyring +Name[or]=ଶକ୍ତି ପରିଚାଳନା +Name[pa]=ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ +Name[pl]=Zarządzanie energią +Name[pt]=Gestão de Energia +Name[pt_BR]=Gerenciamento de energia +Name[ro]=Gestiune energie +Name[ru]=Управление питанием +Name[si]=බල පරිපාලනය +Name[sk]=Správa napájania +Name[sl]=Upravljanje z energijo +Name[sr]=Управљање напајањем +Name[sr@ijekavian]=Управљање напајањем +Name[sr@ijekavianlatin]=Upravljanje napajanjem +Name[sr@latin]=Upravljanje napajanjem +Name[sv]=Strömsparhantering +Name[ta]=Power Management +Name[tg]=Идоракунии барқ +Name[th]=การจัดการพลังงาน +Name[tr]=Güç Yönetimi +Name[ug]=توك مەنبەسىنى باشقۇرۇش +Name[uk]=Керування живленням +Name[wa]=Manaedjmint di l' enerdjeye +Name[x-test]=xxPower Managementxx +Name[zh_CN]=电源管理 +Name[zh_TW]=電源管理 diff --git a/systemsettings/categories/settings-removable-devices.desktop b/systemsettings/categories/settings-removable-devices.desktop new file mode 100644 index 00000000..89cb6046 --- /dev/null +++ b/systemsettings/categories/settings-removable-devices.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=removable-devices +X-KDE-System-Settings-Parent-Category=hardware +Icon=drive-removable-media + +Name=Removable Devices +Name[ar]=أجهزة قابلة للإزالة +Name[ast]=Preseos estrayibles +Name[bg]=Преносими устройства +Name[bn]=অপসারণযোগ্য ডিভাইস +Name[bs]=Uklonjivi uređaji +Name[ca]=Dispositius extraïbles +Name[ca@valencia]=Dispositius extraïbles +Name[cs]=Odpojitelná zařízení +Name[csb]=Przenosné ùrządzenia +Name[da]=Flytbare enheder +Name[de]=Wechselmedien +Name[el]=Αφαιρούμενες συσκευές +Name[en_GB]=Removable Devices +Name[eo]=Demeteblaj Aparatoj +Name[es]=Dispositivos extraíbles +Name[et]=Eemaldatavad seadmed +Name[eu]=Gailu aldagarriak +Name[fa]=دستگاههای جداشدنی +Name[fi]=Irrotettavat laitteet +Name[fr]=Périphériques amovibles +Name[fy]=Utnimbere apparaten +Name[ga]=Gléasanna Inbhainte +Name[gl]=Dispositivos extraíbeis +Name[he]=התקנים נשלפים +Name[hi]=हटाने लायक औज़ार +Name[hr]=Uklonjivi uređaji +Name[hu]=Cserélhető eszközök +Name[ia]=Dispositivos removibile +Name[id]=Divais Dapat Dilepaskan +Name[is]=Útskiptanleg tæki +Name[it]=Dispositivi rimovibili +Name[ja]=リムーバブルデバイス +Name[kk]=Ауыстырмалы құрылғылар +Name[km]=ឧបករណ៍ចល័ត +Name[kn]=ತೆಗೆದೆಹಾಕಬಹುದಾದ ಸಾಧನಗಳು +Name[ko]=이동식 장치 +Name[lt]=Keičiamieji įrenginiai +Name[lv]=Noņemamās iekārtas +Name[mk]=Подвижни уреди +Name[ml]=നീക്കം ചെയ്യാവുന്ന ഉപകരണങ്ങള്‍ +Name[mr]=काढता येणारी साधने +Name[nb]=Flyttbar +Name[nds]=Tuuschbor Reedschappen +Name[nl]=Verwijderbare apparaten +Name[nn]=Flyttbare einingar +Name[pa]=ਹਟਾਉਣਯੋਗ ਜੰਤਰ +Name[pl]=Urządzenia wymienne +Name[pt]=Dispositivos Removíveis +Name[pt_BR]=Dispositivos removíveis +Name[ro]=Dispozitive amovibile +Name[ru]=Внешние носители +Name[si]=ඉවත් කල හැකි මෙවලම් +Name[sk]=Vymeniteľné zariadenia +Name[sl]=Odstranljive naprave +Name[sr]=Уклоњиви уређаји +Name[sr@ijekavian]=Уклоњиви уређаји +Name[sr@ijekavianlatin]=Uklonjivi uređaji +Name[sr@latin]=Uklonjivi uređaji +Name[sv]=Flyttbara enheter +Name[tg]=Дастгоҳи ҷудошаванда +Name[th]=อุปกรณ์ที่สามารถถอด/เสียบได้ +Name[tr]=Çıkarılabilir Aygıtlar +Name[ug]=Removable ئۈسكۈنىلەر +Name[uk]=Портативні пристрої +Name[vi]=Thiết bị gắn ngoài +Name[wa]=Oiståves éndjins +Name[x-test]=xxRemovable Devicesxx +Name[zh_CN]=移动设备 +Name[zh_TW]=可移除裝置 diff --git a/systemsettings/categories/settings-sharing.desktop b/systemsettings/categories/settings-sharing.desktop new file mode 100644 index 00000000..eb9bc5bb --- /dev/null +++ b/systemsettings/categories/settings-sharing.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=sharing +X-KDE-System-Settings-Parent-Category=network-and-connectivity +Icon=preferences-system-network-sharing + +Name=Sharing +Name[ar]=مشاركة +Name[ast]=Compartición +Name[be]=Абмен +Name[be@latin]=Supolny dostup +Name[bg]=Споделяне +Name[bn_IN]=যৌথ ব্যবহার +Name[br]=Rannañ +Name[bs]=Dijeljenje +Name[ca]=Compartició +Name[ca@valencia]=Compartició +Name[cs]=Sdílení +Name[csb]=Ùwòlnienié +Name[da]=Deling +Name[de]=Freigabe +Name[el]=Διαμοιρασμός +Name[en_GB]=Sharing +Name[eo]=Komunigo +Name[es]=Compartición +Name[et]=Jagamine +Name[eu]=Partekatzea +Name[fa]=اشتراک +Name[fi]=Verkkojaot +Name[fr]=Partage +Name[fy]=Diele +Name[ga]=Comhroinnt +Name[gl]=Compartición +Name[gu]=ભાગીદારી +Name[he]=שיתוף +Name[hi]=साझेदारी +Name[hne]=साझेदारी +Name[hr]=Dijeljenje +Name[hu]=Megosztás +Name[ia]=Compartir +Name[id]=Berbagi +Name[is]=Deiling +Name[it]=Condivisione +Name[ja]=共有 +Name[kk]=Ортақ ресурстар +Name[km]=ការ​ចែក​រំលែក +Name[kn]=ಹಂಚಿಕೊಳ್ಳುವಿಕೆ +Name[ko]=공유 +Name[ku]=Parvekirin +Name[lt]=Dalinimasis +Name[lv]=Koplietošana +Name[mai]=साझेदारी +Name[mk]=Споделување +Name[ml]=പങ്കിടല്‍ +Name[mr]=शेअरींग +Name[ms]=Perkongsian +Name[nb]=Deling +Name[nds]=Delen +Name[ne]=साझेदारी +Name[nl]=Delen +Name[nn]=Deling +Name[or]=ସହଭାଗ +Name[pa]=ਸਾਂਝ +Name[pl]=Współdzielenie +Name[pt]=Partilha +Name[pt_BR]=Compartilhamento +Name[ro]=Partajare +Name[ru]=Общий доступ +Name[se]=Juogádeapmi +Name[si]=හවුල් +Name[sk]=Zdieľanie +Name[sl]=Souporaba +Name[sr]=Дељење +Name[sr@ijekavian]=Дијељење +Name[sr@ijekavianlatin]=Dijeljenje +Name[sr@latin]=Deljenje +Name[sv]=Delning +Name[ta]=Sharing +Name[te]=భాగస్వామ్యం +Name[tg]=Дастрасӣ +Name[th]=การใช้งานร่วมกัน +Name[tr]=Paylaşım +Name[ug]=ھەمبەھىر +Name[uk]=Спільне користування +Name[uz]=Boʻlishish +Name[uz@cyrillic]=Бўлишиш +Name[vi]=Chia sẻ +Name[wa]=Pårtaedje +Name[x-test]=xxSharingxx +Name[zh_CN]=共享 +Name[zh_TW]=分享 diff --git a/systemsettings/categories/settings-shortcuts-and-gestures.desktop b/systemsettings/categories/settings-shortcuts-and-gestures.desktop new file mode 100644 index 00000000..d14bab15 --- /dev/null +++ b/systemsettings/categories/settings-shortcuts-and-gestures.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=shortcuts-and-gestures +X-KDE-System-Settings-Parent-Category=application-appearance-and-behavior +Icon=preferences-desktop-keyboard + +Name=Shortcuts and Gestures +Name[ar]=الاختصارات والإيماءات +Name[ast]=Accesos rápidos y xestos +Name[bg]=Бързи клавиши и жестове +Name[bn]=শর্টকাট এবং ভঙ্গি +Name[bs]=Prečice i gestovi +Name[ca]=Dreceres i gestos +Name[ca@valencia]=Dreceres i gestos +Name[cs]=Zkratky a gesta +Name[da]=Genveje og gestusser +Name[de]=Kurzbefehle und Gestensteuerung +Name[el]=Συντομεύσεις και χειρονομίες +Name[en_GB]=Shortcuts and Gestures +Name[es]=Accesos rápidos y gestos +Name[et]=Kiirklahvid ja žestid +Name[eu]=Lasterbideak eta keinuak +Name[fi]=Pikanäppäimet ja hiirieleet +Name[fr]=Raccourcis et gestes +Name[ga]=Aicearraí agus Gothaí +Name[gl]=Atallos e acenos do rato +Name[he]=קיצורים ותנועות +Name[hi]=शॉर्टकट व संकेत +Name[hr]=Prečaci i kretnje mišem +Name[hu]=Gyorsbillentyűk és mozdulatok +Name[ia]=Vias breve e gestures +Name[id]=Jalan Pintas dan Gerakan +Name[is]=Flýtilyklar og bendingar +Name[it]=Scorciatoie e gesti +Name[ja]=ショートカットとジェスチャー +Name[kk]=Тіркесімдер мен ым қимылдары +Name[km]=ផ្លូវកាត់ និងកាយវិការ +Name[kn]=ಶೀಘ್ರ ಮಾರ್ಗಗಳು (ಶಾರ್ಟ್ ಕಟ್) ಹಾಗು ಸೂಚ್ಯವರ್ತನೆಗಳು (ಗೆಸ್ಚರ್ಸ್) +Name[ko]=단축키와 제스처 +Name[lt]=Spartieji klavišai ir gestai +Name[lv]=Īsceļi un žesti +Name[mr]=शॉर्टकट व माऊस इशारे +Name[nb]=Snarveier og musebevegelser +Name[nds]=Tastkombinatschonen un Muustekens +Name[nl]=Sneltoetsen en gebaren +Name[nn]=Snarvegar og muserørsler +Name[pa]=ਸ਼ਾਰਟਕੱਟ ਤੇ ਜੈਸੱਚਰ +Name[pl]=Skróty i gesty +Name[pt]=Atalhos e Gestos +Name[pt_BR]=Atalhos e gestos +Name[ro]=Scurtături și gesturi +Name[ru]=Комбинации клавиш и росчерки +Name[si]=කෙටි මං සහ ඉඟි +Name[sk]=Skratky a gestá +Name[sl]=Bližnjice in kretnje +Name[sr]=Пречице и гестови +Name[sr@ijekavian]=Пречице и гестови +Name[sr@ijekavianlatin]=Prečice i gestovi +Name[sr@latin]=Prečice i gestovi +Name[sv]=Genvägar och gester +Name[th]=ปุ่มพิมพ์ลัดและการขยับเมาส์แบบต่าง ๆ +Name[tr]=Kısayollar ve Hareketler +Name[ug]=تېزلەتمىلەر ۋە قول ئىشارەتلىرى +Name[uk]=Скорочення і жести +Name[vi]=Phím tắt và cử chỉ +Name[wa]=Rascourtis eyet djesses +Name[x-test]=xxShortcuts and Gesturesxx +Name[zh_CN]=快捷方式和手势 +Name[zh_TW]=捷徑與手勢 + diff --git a/systemsettings/categories/settings-startup-and-shutdown.desktop b/systemsettings/categories/settings-startup-and-shutdown.desktop new file mode 100644 index 00000000..4ad9664a --- /dev/null +++ b/systemsettings/categories/settings-startup-and-shutdown.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=startup-and-shutdown +X-KDE-System-Settings-Parent-Category=system-administration +Icon=preferences-other + +Name=Startup and Shutdown +Name[ar]=بدء التشغيل والإطفاء +Name[ast]=Arranque y apagáu +Name[bg]=Зареждане и изключване +Name[bn]=স্টার্ট-আপ এবং শাটডাউন +Name[bs]=Podizanje i gašenje +Name[ca]=Engegada i aturada +Name[ca@valencia]=Engegada i parada +Name[cs]=Spuštění a ukončení +Name[da]=Opstart og nedlukning +Name[de]=Starten und Beenden +Name[el]=Εκκίνηση και τερματισμός +Name[en_GB]=Startup and Shutdown +Name[es]=Arranque y apagado +Name[et]=Käivitamine ja seiskamine +Name[eu]=Abioa eta itzaltzea +Name[fi]=Käynnistys ja sammutus +Name[fr]=Démarrage et arrêt +Name[ga]=Tosú agus Múchadh +Name[gl]=Inicio e saída +Name[he]=הפעלה וכיבוי +Name[hi]=स्टारटप व शटडाउन +Name[hr]=Pokretanje i isključivanje +Name[hu]=Indítás és leállítás +Name[ia]=Initia e claude (Shutdown) +Name[id]=Jalankan dan Matikan +Name[is]=Ræsing og stöðvun +Name[it]=Avvio e spegnimento +Name[ja]=起動と終了 +Name[kk]=Бастау мен сөндіру +Name[km]=ចាប់ផ្ដើម និង​បិទ +Name[kn]=ಪ್ರಾರಂಭಿಸು ಹಾಗು ಸ್ಥಗಿತಗೊಳಿಸು +Name[ko]=시작 및 종료 +Name[lt]=Įjungimas ir išjungimas +Name[lv]=Ieslēgšana un izslēgšana +Name[mr]=सुरुवात व समाप्ती +Name[nb]=Oppstart og avslutning +Name[nds]=An- un Utmaken +Name[nl]=Opstarten en afsluiten +Name[nn]=Oppstart og avslutting +Name[pa]=ਸ਼ੁਰੂਆਤ ਤੇ ਬੰਦ ਕਰਨਾ +Name[pl]=Uruchamianie i wyłączanie +Name[pt]=Arranque e Paragem +Name[pt_BR]=Inicialização e desligamento +Name[ro]=Pornire și oprire +Name[ru]=Запуск и завершение +Name[si]=ආරම්භ කිරීම සහ වැසීම +Name[sk]=Spustenie a vypnutie +Name[sl]=Zagon in izklop +Name[sr]=Подизање и гашење +Name[sr@ijekavian]=Подизање и гашење +Name[sr@ijekavianlatin]=Podizanje i gašenje +Name[sr@latin]=Podizanje i gašenje +Name[sv]=Start och avslutning +Name[th]=การเริ่มการทำงานและการปิดเครื่อง +Name[tr]=Başlatma ve Kapatma +Name[ug]=قوزغىلىش ۋە تاقاش +Name[uk]=Запуск і вихід +Name[vi]=Khởi động và tắt máy +Name[wa]=Enondaedje eyet aresse di l' éndjole +Name[x-test]=xxStartup and Shutdownxx +Name[zh_CN]=开机和关机 +Name[zh_TW]=啟動與關閉 diff --git a/systemsettings/categories/settings-system-administration.desktop b/systemsettings/categories/settings-system-administration.desktop new file mode 100644 index 00000000..bcf3d536 --- /dev/null +++ b/systemsettings/categories/settings-system-administration.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=system-administration +X-KDE-System-Settings-Parent-Category= +X-KDE-Weight=200 +Icon=preferences-system + +Name=System Administration +Name[ar]=إدارة النظام +Name[ast]=Alministración del sistema +Name[be]=Сістэмнае адміністраванне +Name[bg]=Системна администрация +Name[bn]=সিস্টেম অ্যাডমিনস্ট্রেশন +Name[br]=Melestradur ar Reizhiad +Name[bs]=Administracija sistema +Name[ca]=Administració del sistema +Name[ca@valencia]=Administració del sistema +Name[cs]=Administrace systému +Name[cy]=Gweinyddiaith Cysawd +Name[da]=Systemadministration +Name[de]=Systemverwaltung +Name[el]=Διαχείριση συστήματος +Name[en_GB]=System Administration +Name[es]=Administración del sistema +Name[et]=Süsteemi haldamine +Name[eu]=Sistema-administrazioa +Name[fa]=سرپرستی سیستم +Name[fi]=Järjestelmänhallinta +Name[fr]=Administration du système +Name[ga]=Riarachán Córais +Name[gl]=Administración do sistema +Name[gu]=સિસ્ટમ વહીવટ +Name[he]=ניהול המערכת +Name[hi]=तंत्र प्रशासक +Name[hr]=Administriranje sustava +Name[hu]=Rendszeradminisztráció +Name[ia]=Administration de systema +Name[id]=Administrasi Sistem +Name[is]=Kerfisstjórnun +Name[it]=Amministrazione di sistema +Name[ja]=システム管理 +Name[ka]=სისტემის ადმინისტრირება +Name[kk]=Жүйе әкімшілігі +Name[km]=ការ​គ្រប់គ្រង​ប្រព័ន្ធ +Name[kn]=ಗಣಕವ್ಯವಸ್ಥೆಯ ನಿರ್ವಹಣೆ +Name[ko]=시스템 관리 +Name[lt]=Sistemos administravimas +Name[lv]=Sistēmas administrācija +Name[mr]=प्रणाली प्रशासन +Name[nb]=Systemadministrasjon +Name[nds]=Systeempleeg +Name[ne]=प्रणाली प्रशासन +Name[nl]=Systeemadministratie +Name[nn]=Systemadministrasjon +Name[pa]=ਸਿਸਟਮ ਪਰਸ਼ਾਸ਼ਨ +Name[pl]=Administracja systemu +Name[pt]=Administração do Sistema +Name[pt_BR]=Administração do sistema +Name[ro]=Administrare sistem +Name[ru]=Системное администрирование +Name[se]=Vuogádathálddašeapmi +Name[si]=පද්ධති කළමනාකරනය +Name[sk]=Správa systému +Name[sl]=Skrbništvo sistema +Name[sr]=Администрација система +Name[sr@ijekavian]=Администрација система +Name[sr@ijekavianlatin]=Administracija sistema +Name[sr@latin]=Administracija sistema +Name[sv]=Systemadministration +Name[ta]=கணினி-நிர்வாகம் +Name[tg]=Мудири система +Name[th]=การดูแลบริหารระบบ +Name[tr]=Sistem Yönetimi +Name[ug]=سىستېما باشقۇرۇش +Name[uk]=Керування системою +Name[uz]=Tizimni boshqarish +Name[uz@cyrillic]=Тизимни бошқариш +Name[vi]=Quản trị hệ thống +Name[wa]=Manaedjmint d' sistinme +Name[xh]=Umphathi Wendlela yokusebenza +Name[x-test]=xxSystem Administrationxx +Name[zh_CN]=系统管理 +Name[zh_TW]=系統管理 diff --git a/systemsettings/categories/settings-window-behaviour.desktop b/systemsettings/categories/settings-window-behaviour.desktop new file mode 100644 index 00000000..6669cfbf --- /dev/null +++ b/systemsettings/categories/settings-window-behaviour.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=window-behaviour +X-KDE-System-Settings-Parent-Category=workspace-appearance-and-behavior +Icon=preferences-system-windows + +Name=Window Behavior +Name[af]=Venstergedrag +Name[ar]=سلوك النوافذ +Name[ast]=Comportamientu de la ventana +Name[be]=Паводзіны вокнаў +Name[be@latin]=Pavodziny akna +Name[bg]=Поведение на прозорците +Name[bn]=উইণ্ডো আচরণ +Name[bn_IN]=উইন্ডোর আচরণ +Name[br]=Emzalc'h ar prenester +Name[bs]=Ponašanje prozora +Name[ca]=Comportament de les finestres +Name[ca@valencia]=Comportament de les finestres +Name[cs]=Chování oken +Name[csb]=Ùchòwanié òkna +Name[cy]=Ymddygiad Ffenestri +Name[da]=Vinduesopførsel +Name[de]=Fensterverhalten +Name[el]=Συμπεριφορά παραθύρων +Name[en_GB]=Window Behaviour +Name[eo]=Fenestrokonduto +Name[es]=Comportamiento de la ventana +Name[et]=Akende käitumine +Name[eu]=Leihoaren portaera +Name[fa]=رفتار پنجره +Name[fi]=Ikkunoiden toiminta +Name[fr]=Comportement des fenêtres +Name[fy]=Finstergedrach +Name[ga]=Oibriú na bhFuinneog +Name[gl]=Comportamento das xanelas +Name[gu]=વિન્ડો વર્તણૂક +Name[he]=התנהגות חלונות +Name[hi]=विंडो व्यवहार +Name[hne]=विंडो व्यवहार +Name[hr]=Ponašanje prozora +Name[hu]=Ablakműveletek +Name[ia]=Comportamento de fenestra +Name[id]=Perilaku Jendela +Name[is]=Hegðun glugga +Name[it]=Comportamento delle finestre +Name[ja]=ウィンドウの挙動 +Name[ka]=ფანჯრის ქცევა +Name[kk]=Терезе қасиеттері +Name[km]=ឥរិយាបថ​បង្អួច +Name[kn]=ಕಿಟಕಿ ವರ್ತನೆ +Name[ko]=창 동작 +Name[ku]=Helwesta Paceyan +Name[lt]=Langų elgsena +Name[lv]=Logu izturēšanās +Name[mai]=विंडो व्यवहार +Name[mk]=Однесување на прозорци +Name[ml]=ജാലകത്തിന്റെ വിശേഷത +Name[mr]=चौकट वर्तन +Name[nb]=Vindusoppførsel +Name[nds]=Finsterbedregen +Name[ne]=सञ्झ्याल व्यवहार +Name[nl]=Venstergedrag +Name[nn]=Vindaugs­åtferd +Name[pa]=ਵਿੰਡੋ ਰਵੱਈਆ +Name[pl]=Zachowania okien +Name[pt]=Comportamento das Janelas +Name[pt_BR]=Comportamento da janela +Name[ro]=Comportament fereastră +Name[ru]=Поведение окон +Name[se]=Láseláhtten +Name[si]=කවුළු හැසිරීම +Name[sk]=Správanie okien +Name[sl]=Obnašanje oken +Name[sr]=Понашање прозора +Name[sr@ijekavian]=Понашање прозора +Name[sr@ijekavianlatin]=Ponašanje prozora +Name[sr@latin]=Ponašanje prozora +Name[sv]=Fönsterbeteende +Name[ta]=சாளர நடத்தை +Name[te]=విండో ప్రవర్తన +Name[tg]=Холати тиреза +Name[th]=พฤติกรรมของหน้าต่าง +Name[tr]=Pencere Davranışı +Name[ug]=كۆزنەكنىڭ ئىش-ھەرىكەتلىرى +Name[uk]=Поведінка вікон +Name[uz]=Oynaning xususiyatlari +Name[uz@cyrillic]=Ойнанинг хусусиятлари +Name[vi]=Ứng xử của Cửa sổ +Name[wa]=Dujhance des fniesses +Name[xh]=Ukuziphatha kwe Window +Name[x-test]=xxWindow Behaviorxx +Name[zh_CN]=窗口行为 +Name[zh_TW]=視窗行為 + diff --git a/systemsettings/categories/settings-workspace-appearance-and-behavior.desktop b/systemsettings/categories/settings-workspace-appearance-and-behavior.desktop new file mode 100644 index 00000000..64d07dfa --- /dev/null +++ b/systemsettings/categories/settings-workspace-appearance-and-behavior.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=workspace-appearance-and-behavior +X-KDE-System-Settings-Parent-Category= +X-KDE-Weight=80 +Icon=preferences-desktop-theme + +Name=Workspace Appearance and Behavior +Name[ar]=مظهر وسلوك مساحة العمل +Name[ast]=Apariencia y comportamientu del espaciu de trabayu +Name[bg]=Изглед и поведение на работната среда +Name[bn]=ওয়ার্কস্পেস-এর চেহারা এবং আচরণ +Name[bs]=Izgled i ponašanje radnog prostora +Name[ca]=Aparença i comportament de l'espai de treball +Name[ca@valencia]=Aparença i comportament de l'espai de treball +Name[cs]=Vzhled a chování oken +Name[da]=Arbejdsområdets udseende og opførsel +Name[de]=Erscheinungsbild und Verhalten der Arbeitsfläche +Name[el]=Εμφάνιση και συμπεριφορά χώρου εργασίας +Name[en_GB]=Workspace Appearance and Behaviour +Name[es]=Apariencia y comportamiento del espacio de trabajo +Name[et]=Töötsooni välimus ja käitumine +Name[eu]=Laneko eremuaren itxura eta portaera +Name[fi]=Työtilan ulkoasu ja toiminta +Name[fr]=Apparence et comportement de l'espace de travail +Name[gl]=Aparencia e comportamento do espazo de traballo +Name[he]=התנהגות ומראה סביבת העבודה +Name[hr]=Izgled i ponašanje radnog prostora +Name[hu]=A munkaterület megjelenése és működése +Name[ia]=Apparentia e comportamento del spatio de labor (Workspace) +Name[id]=Tampilan dan Perilaku Ruang Kerja +Name[is]=Útlit og hegðun vinnusvæðis +Name[it]=Aspetto e comportamento dello spazio di lavoro +Name[ja]=ワークスペースの外観と挙動 +Name[kk]=Жұмыс орның көрініс пен тәртібі +Name[km]=រូបរាង និង​ឥរិយាបថ​របស់​តំបន់​ធ្វើការ +Name[kn]=ಕಾರ್ಯಕ್ಷೇತ್ರ ಗೋಚರಿಕೆ ಹಾಗು ವರ್ತನೆ +Name[ko]=작업 공간 모양과 행동 +Name[lt]=Darbo erdvės išvaizda ir elgsena +Name[lv]=Darba telpas izskats un izturēšanās +Name[mr]=कार्यस्थान दर्शनीयता व वर्तन +Name[nb]=Utseende og oppførsel for arbeidsflaten +Name[nds]=Arbeitrebeet-Utsehn un -Bedregen +Name[nl]=Uiterlijk en gedrag van werkruimte +Name[nn]=Utsjånad og åtferd til arbeids­område +Name[pa]=ਵਰਕਸਪੇਸ ਦਿੱਖ ਤੇ ਰਵੱਈਆ +Name[pl]=Wygląd i zachowanie przestrzeni roboczej +Name[pt]=Aparência e Comportamento da Área de Trabalho +Name[pt_BR]=Comportamento e aparência do espaço de trabalho +Name[ro]=Aspect și comportament pentru spațiul de lucru +Name[ru]=Внешний вид и поведение среды рабочего стола +Name[si]=වැඩබිම් පෙනුම සහ හැසිරීම +Name[sk]=Vzhľad a správanie pracovnej plochy +Name[sl]=Videz in obnašanje delovnega prostora +Name[sr]=Изглед и понашање радног простора +Name[sr@ijekavian]=Изглед и понашање радног простора +Name[sr@ijekavianlatin]=Izgled i ponašanje radnog prostora +Name[sr@latin]=Izgled i ponašanje radnog prostora +Name[sv]=Arbetsytans utseende och beteende +Name[tg]=Рафтор ва намуди зоҳирии муҳити корӣ +Name[th]=รูปลักษณ์และพฤติกรรมของพื้นที่ทำงาน +Name[tr]=Çalışma Alanı Görünümü ve Davranışı +Name[ug]=خىزمەت بوشلۇقىنىڭ كۆرۈنۈشى ۋە ئىش-ھەرىكەتلىرى +Name[uk]=Вигляд і поведінка робочого простору +Name[vi]=Diện mạo và hành vi không gian làm việc +Name[wa]=Rivnance eyet dujhance di l' espåce di boutaedje +Name[x-test]=xxWorkspace Appearance and Behaviorxx +Name[zh_CN]=工作空间外观和行为 +Name[zh_TW]=工作空間外觀與行為 diff --git a/systemsettings/categories/settings-workspace-behavior.desktop b/systemsettings/categories/settings-workspace-behavior.desktop new file mode 100644 index 00000000..efdd5c8b --- /dev/null +++ b/systemsettings/categories/settings-workspace-behavior.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=SystemSettingsCategory +X-KDE-System-Settings-Category=workspace-behavior +X-KDE-System-Settings-Parent-Category=workspace-appearance-and-behavior +Icon=plasma + +Name=Workspace Behavior +Name[ar]=سلوك مساحة العمل +Name[ast]=Comportamientu del espaciu de trabayu +Name[bg]=Поведение на работната среда +Name[bs]=Ponašanje radnog prostora +Name[ca]=Comportament de l'espai de treball +Name[ca@valencia]=Comportament de l'espai de treball +Name[cs]=Chování pracovní plochy +Name[da]=Arbejdsområdets opførsel +Name[de]=Verhalten der Arbeitsfläche +Name[el]=Συμπεριφορά χώρου εργασίας +Name[en_GB]=Workspace Behaviour +Name[es]=Comportamiento del espacio de trabajo +Name[et]=Töötsooni käitumine +Name[eu]=Laneko eremuaren portaera +Name[fi]=Työtilan toiminta +Name[fr]=Comportement de l'espace de travail +Name[ga]=Oibriú an Spáis Oibre +Name[gl]=Comportamento do espazo de traballo +Name[gu]=વેબ વર્તણૂક +Name[he]=התנהגות סביבת העבודה +Name[hi]=कार्यक्षेत्र बर्ताव +Name[hr]=Ponašanje radnog prostora +Name[hu]=Működés +Name[ia]=Comportamento del spatio de labor +Name[is]=Hegðun vinnurýmis +Name[it]=Comportamento dello spazio di lavoro +Name[ja]=ワークスペースの挙動 +Name[kk]=Жұмыс орның қасиеттері +Name[km]=ឥរិយាបថ​តំបន់​ការងារ +Name[kn]=ಕಾರ್ಯಸ್ಥಳದ ವರ್ತನೆ +Name[ko]=작업 공간 행동 +Name[lt]=Darbo erdvės elgsena +Name[lv]=Darba telpas izturēšanās +Name[mr]=कार्यस्थान वर्तन +Name[nb]=Oppførsel for arbeidsflaten +Name[nds]=Arbeitrebeet-Bedregen +Name[nl]=Gedrag van werkruimte +Name[nn]=Åtferd til arbeids­område +Name[pa]=ਵਰਕਸਪੇਸ ਰਵੱਈਆ +Name[pl]=Zachowanie przestrzeni roboczej +Name[pt]=Comportamento da Área de Trabalho +Name[pt_BR]=Comportamento do espaço de trabalho +Name[ro]=Comportament spațiu de lucru +Name[ru]=Поведение рабочей среды +Name[sk]=Správanie pracovnej plochy +Name[sl]=Obnašanje delovnega prostora +Name[sr]=Понашање радног простора +Name[sr@ijekavian]=Понашање радног простора +Name[sr@ijekavianlatin]=Ponašanje radnog prostora +Name[sr@latin]=Ponašanje radnog prostora +Name[sv]=Arbetsytans beteende +Name[tg]=Рафтори муҳити корӣ +Name[th]=พฤติกรรมของพื้นที่ทำงาน +Name[tr]=Çalışma Alanı Davranışı +Name[ug]=خىزمەت بوشلۇقىنىڭ ئىش-ھەرىكەتلىرى +Name[uk]=Поведінка робочого простору +Name[vi]=Hành vi không gian làm việc +Name[wa]=Dujhance di l' espåce di boutaedje +Name[x-test]=xxWorkspace Behaviorxx +Name[zh_CN]=工作空间行为 +Name[zh_TW]=工作空間行為 diff --git a/systemsettings/categories/systemsettingscategory.desktop b/systemsettings/categories/systemsettingscategory.desktop new file mode 100644 index 00000000..3df3ad0c --- /dev/null +++ b/systemsettings/categories/systemsettingscategory.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=SystemSettingsCategory +Name=System Settings Category +Name[ar]=فئة إعدادات النظام +Name[ast]=Categoría de preferencies del sistema +Name[be]=Катэгорыя сістэмных настаўленняў +Name[be@latin]=Katehoryja systemnych naładaŭ +Name[bg]=Категория системни настройки +Name[bn]=সিস্টেম সেটিংস শ্রেণী +Name[bs]=Kategorija sistemskih postavki +Name[ca]=Categoria d'arranjament del sistema +Name[ca@valencia]=Categoria d'arranjament del sistema +Name[cs]=Kategorie systémových nastavení +Name[csb]=Kategòrëjô systemòwégò nastôwù +Name[da]=Kategori af Systemindstillinger +Name[de]=Systemeinstellungen-Kategorie +Name[el]=Κατηγορία ρυθμίσεων συστήματος +Name[en_GB]=System Settings Category +Name[eo]=Sistemagorda kategorio +Name[es]=Categoría de preferencias del sistema +Name[et]=Süsteemi seadistuste kategooria +Name[eu]=Sistema-ezarpenen kategoria +Name[fa]=دسته تنظیمات سیستم +Name[fi]=Järjestelmäasetusten luokka +Name[fr]=Catégorie des paramètres du système +Name[fy]=Systeem ynstellings katogory +Name[ga]=Catagóir Socruithe an Chórais +Name[gl]=Categoría de configuración do sistema +Name[gu]=સિસ્ટમ ગોઠવણીઓ વર્ગ +Name[he]=קטגוריית הגדרות מערכת +Name[hi]=तंत्र विन्यास वर्ग +Name[hne]=तंत्र सेटिंग वर्ग +Name[hr]=Kategorija sustavskih postavki +Name[hu]=Rendszerbeállítási kategória +Name[ia]=Categoria de preferentias de systema +Name[id]=Kategori Pengaturan Sistem +Name[is]=Kerfisstillingaflokkur +Name[it]=Categoria delle impostazioni di sistema +Name[ja]=システム設定のカテゴリ +Name[kk]=Жүйе параметрлер санаты +Name[km]=ប្រភេទ​ការ​កំណត់​ប្រព័ន្ធ​ +Name[kn]=ವ್ಯವಸ್ಥಾ ಸಂಯೋಜನೆಗಳ ಪಂಗಡ +Name[ko]=시스템 설정 분류 +Name[ku]=Kategoriya Mîhengên Pergalê +Name[lt]=Sistemos nustatymų kategorija +Name[lv]=Sistēmas iestatījumu kategorija +Name[mai]=तंत्र सेटिंग वर्ग +Name[mk]=Категорија со системски поставувања +Name[ml]=സിസ്റ്റം സജ്ജീകരണങ്ങളുടെ വിഭാഗം +Name[mr]=प्रणाली संयोजना वर्ग +Name[nb]=Kategori for systeminnstillinger +Name[nds]=Kategorie Systeeminstellen +Name[ne]=प्रणाली सेटिङ कोटि +Name[nl]=Systeeminstellingen-catagorie +Name[nn]=Kategori for systemval +Name[or]=ତନ୍ତ୍ର ବିନ୍ୟାସ ବିଭାଗ +Name[pa]=ਸਿਸਟਮ ਸੈਟਿੰਗ ਕੈਟਾਗਰੀ +Name[pl]=Kategoria ustawień systemowych +Name[pt]=Categoria da Configuração do Sistema +Name[pt_BR]=Categoria das configurações do sistema +Name[ro]=Categorie Configurări de sistem +Name[ru]=Настройка системы +Name[se]=Vuogádatheivehusaid láhki +Name[si]=පද්ධති සැකසුම් ප්‍රභේද +Name[sk]=Kategória systémových nastavení +Name[sl]=Kategorija sistemskih nastavitev +Name[sr]=Категорија системских поставки +Name[sr@ijekavian]=Категорија системских поставки +Name[sr@ijekavianlatin]=Kategorija sistemskih postavki +Name[sr@latin]=Kategorija sistemskih postavki +Name[sv]=Systeminställningskategori +Name[ta]=System Settings Category +Name[te]=సిస్టమ్ అమరికల వర్గము +Name[tg]=Категория параметров системы +Name[th]=หมวดหมู่การตั้งค่าระบบ +Name[tr]=Sistem Ayarları Kategorisi +Name[ug]=سىستېما تەڭشەك كاتېگورىيىسى +Name[uk]=Категорія системних параметрів +Name[vi]=Thể loại trong Thiết lập hệ thống +Name[wa]=Categoreye d' apontiaedjes do sistinme +Name[x-test]=xxSystem Settings Categoryxx +Name[zh_CN]=系统设置类别 +Name[zh_TW]=系統設定類別 + +# the category identifier +[PropertyDef::X-KDE-System-Settings-Category] +Type=QString + +# the parent category identifier +[PropertyDef::X-KDE-System-Settings-Parent-Category] +Type=QString + +# parent category identifier version 2 +[PropertyDef::X-KDE-System-Settings-Parent-Category-V2] +Type=QString diff --git a/systemsettings/classic/CMakeLists.txt b/systemsettings/classic/CMakeLists.txt new file mode 100644 index 00000000..3fab1c6c --- /dev/null +++ b/systemsettings/classic/CMakeLists.txt @@ -0,0 +1,14 @@ +SET(classic_mode_srcs + ClassicMode.cpp + CategoryList.cpp +) + +KDE4_ADD_UI_FILES( classic_mode_srcs configClassic.ui ) +KDE4_ADD_PLUGIN(classic_mode ${classic_mode_srcs}) + +TARGET_LINK_LIBRARIES(classic_mode ${KDE4_KCMUTILS_LIBS} ${KDE4_KHTML_LIBS} systemsettingsview ) + +INSTALL( TARGETS classic_mode DESTINATION ${PLUGIN_INSTALL_DIR} ) +INSTALL( FILES settings-classic-view.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) +INSTALL( FILES main.html systemsettings-classic.css DESTINATION ${DATA_INSTALL_DIR}/systemsettings/classic/ ) + diff --git a/systemsettings/classic/CategoryList.cpp b/systemsettings/classic/CategoryList.cpp new file mode 100644 index 00000000..2e9e3e03 --- /dev/null +++ b/systemsettings/classic/CategoryList.cpp @@ -0,0 +1,136 @@ +/* + Copyright (c) 2000,2001 Matthias Elter + Copyright (c) 2009 Ben Cooksley + + 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; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "CategoryList.h" + +#include "MenuItem.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char kcc_infotext[]= I18N_NOOP("System Settings"); +static const char title_infotext[]= I18N_NOOP("Configure your system"); +static const char intro_infotext[]= I18N_NOOP("Welcome to \"System Settings\", " + "a central place to configure your computer system."); + +class CategoryList::Private { +public: + Private() {} + + KHTMLPart * categoryView; + QModelIndex categoryMenu; + QAbstractItemModel * itemModel; + QMap itemMap; +}; + +CategoryList::CategoryList( QWidget *parent, QAbstractItemModel *model ) + : KHBox(parent), d( new Private() ) +{ + setMinimumSize( 400, 400 ); + d->itemModel = model; + + // set what's this help + this->setWhatsThis( i18n( intro_infotext ) ); + d->categoryView = new KHTMLPart( this ); + d->categoryView->view()->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + d->categoryView->widget()->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ); + connect( d->categoryView->browserExtension(), + SIGNAL( openUrlRequest( const KUrl&, + const KParts::OpenUrlArguments&, + const KParts::BrowserArguments& ) ), + this, SLOT(slotModuleLinkClicked(KUrl)) ); +} + +CategoryList::~CategoryList() +{ + delete d; +} + +void CategoryList::updatePixmap() +{ + QString content; + QString moduleName; + KIconLoader * iconL = KIconLoader::global(); + d->itemMap.clear(); + + const QString templatePath = KStandardDirs::locate( "data", "systemsettings/classic/main.html" ); + QFile templateFile( templatePath ); + templateFile.open( QIODevice::ReadOnly ); + QTextStream templateText( &templateFile ); + QString templateString = templateText.readAll(); + templateString = templateString.arg( KStandardDirs::locate( "data", "kdeui/about/kde_infopage.css" ) ); + if ( kapp->layoutDirection() == Qt::RightToLeft ) { + templateString = templateString.arg( "@import \"%1\";" ).arg( KStandardDirs::locate( "data", "kdeui/about/kde_infopage_rtl.css" ) ); + } else { + templateString = templateString.arg( QString() ); + } + templateString = templateString.arg( i18n( kcc_infotext ) ); + templateString = templateString.arg( i18n( title_infotext ) ); + templateString = templateString.arg( i18n( intro_infotext ) ); + if ( d->categoryMenu.isValid() ) { + moduleName = d->itemModel->data( d->categoryMenu, Qt::DisplayRole ).toString(); + } + content += "
    " + moduleName + "
    "; + content += "\n"; + for( int done = 0; d->itemModel->rowCount( d->categoryMenu ) > done; ++done ) { + QModelIndex childIndex = d->itemModel->index( done, 0, d->categoryMenu ); + MenuItem *childItem = d->itemModel->data( childIndex, Qt::UserRole ).value(); + KUrl link( "kcm://" ); + link.setFileName( childItem->item().fileName() ); + kDebug() << childItem->name() << childItem->item().fileName() << link.url(); + const QString szLink = ""; + content += "\n"; + } + content += "
    " + szLink + ""; + const QString szName = childItem->name(); + const QString szComment = childItem->service()->comment(); + content += szLink + szName + "" + szLink + szComment + ""; + content = content.arg( iconL->iconPath(childItem->service()->icon(), - KIconLoader::SizeSmallMedium ) ); + d->itemMap.insert( link.url(), childIndex ); + content += "
    "; + d->categoryView->begin( KUrl( templatePath ) ); + d->categoryView->write( templateString.arg( content ) ); + d->categoryView->end(); +} + +void CategoryList::changeModule( QModelIndex newItem ) +{ + d->categoryMenu = newItem; + updatePixmap(); +} + +void CategoryList::slotModuleLinkClicked( const KUrl& moduleName ) +{ + QModelIndex module = d->itemMap.value( moduleName.url() ); + kDebug() << "Link name: " + moduleName.url(); + emit moduleSelected( module ); +} + +#include "CategoryList.moc" diff --git a/systemsettings/classic/CategoryList.h b/systemsettings/classic/CategoryList.h new file mode 100644 index 00000000..9891819d --- /dev/null +++ b/systemsettings/classic/CategoryList.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2000,2001 Matthias Elter + + 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; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef CATEGORYLIST_H +#define CATEGORYLIST_H + +#include + +class QModelIndex; +class QAbstractItemModel; + +class KUrl; + +class CategoryList : public KHBox +{ + Q_OBJECT + +public: + explicit CategoryList( QWidget *parent, QAbstractItemModel *model ); + virtual ~CategoryList(); + + void changeModule( QModelIndex newItem); + +Q_SIGNALS: + void moduleSelected( QModelIndex itemSelected ); + +private Q_SLOTS: + void slotModuleLinkClicked( const KUrl& ); + +private: + void updatePixmap(); + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/systemsettings/classic/ClassicMode.cpp b/systemsettings/classic/ClassicMode.cpp new file mode 100644 index 00000000..d9e85608 --- /dev/null +++ b/systemsettings/classic/ClassicMode.cpp @@ -0,0 +1,265 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * Copyright (C) 2008 Mathias Soeken * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ + +#include "ClassicMode.h" +#include "ui_configClassic.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "MenuItem.h" +#include "MenuModel.h" +#include "ModuleView.h" +#include "CategoryList.h" +#include "MenuProxyModel.h" + +K_PLUGIN_FACTORY(ClassicModeFactory, registerPlugin();) +K_EXPORT_PLUGIN(ClassicModeFactory("classic_mode")) + +class ClassicMode::Private { +public: + Private() : moduleView( 0 ) {} + virtual ~Private() { + delete aboutClassic; + } + + QSplitter * classicWidget; + QTreeView * classicTree; + Ui::ConfigClassic classicConfig; + CategoryList * classicCategory; + QStackedWidget * stackedWidget; + ModuleView * moduleView; + QModelIndex currentItem; + + MenuProxyModel * proxyModel; + MenuModel * model; + KAboutData * aboutClassic; +}; + +ClassicMode::ClassicMode( QObject * parent, const QVariantList& ) + : BaseMode( parent ), d( new Private() ) +{ + d->aboutClassic = new KAboutData( "TreeView", 0, ki18n("Tree View"), + "1.0", ki18n("Provides a classic tree-based view of control modules."), + KAboutData::License_GPL, ki18n("(c) 2009, Ben Cooksley")); + d->aboutClassic->addAuthor(ki18n("Ben Cooksley"), ki18n("Author"), "bcooksley@kde.org"); + d->aboutClassic->addAuthor(ki18n("Mathias Soeken"), ki18n("Developer"), "msoeken@informatik.uni-bremen.de"); + d->aboutClassic->setProgramIconName("view-list-tree"); +} + +ClassicMode::~ClassicMode() +{ + if( !d->classicTree ) { + delete d->classicWidget; + } + delete d; +} + +void ClassicMode::initEvent() +{ + // Create the model + d->model = new MenuModel( rootItem(), this ); + + // Move items that are the sole child of a category up.... + moveUp( rootItem() ); + + // Create the proxy model + d->proxyModel = new MenuProxyModel( this ); + d->proxyModel->setSourceModel( d->model ); + d->proxyModel->sort( 0 ); + d->classicWidget = new QSplitter( Qt::Horizontal, 0 ); + d->classicWidget->setChildrenCollapsible( false ); + d->moduleView = new ModuleView( d->classicWidget ); + d->classicTree = 0; +} + +QWidget * ClassicMode::mainWidget() +{ + if( !d->classicTree ) { + initWidget(); + } + return d->classicWidget; +} + +KAboutData * ClassicMode::aboutData() +{ + return d->aboutClassic; +} + +ModuleView * ClassicMode::moduleView() const +{ + return d->moduleView; +} + +QList ClassicMode::views() const +{ + QList theViews; + theViews << d->classicTree; + return theViews; +} + +void ClassicMode::saveState() +{ + config().writeEntry( "viewLayout", d->classicWidget->sizes() ); + config().sync(); +} + +void ClassicMode::expandColumns() +{ + d->classicTree->resizeColumnToContents(0); +} + +void ClassicMode::searchChanged( const QString& text ) +{ + d->proxyModel->setFilterRegExp(text); + if( d->classicTree ) { + d->classicCategory->changeModule( d->classicTree->currentIndex() ); + } +} + +void ClassicMode::selectModule( const QModelIndex& selectedModule ) +{ + d->classicTree->setCurrentIndex( selectedModule ); + if( d->proxyModel->rowCount(selectedModule) > 0 ) { + d->classicTree->setExpanded(selectedModule, true); + } + changeModule( selectedModule ); +} + +void ClassicMode::changeModule( const QModelIndex& activeModule ) +{ + if( activeModule == d->currentItem ) { + return; + } + if( !d->moduleView->resolveChanges() ) { + return; + } + d->moduleView->closeModules(); + d->currentItem = activeModule; + if( d->proxyModel->rowCount(activeModule) > 0 ) { + d->stackedWidget->setCurrentWidget( d->classicCategory ); + d->classicCategory->changeModule(activeModule); + emit viewChanged( false ); + } else { + d->moduleView->loadModule( activeModule ); + } +} + +void ClassicMode::moduleLoaded() +{ + d->stackedWidget->setCurrentWidget( d->moduleView ); +} + +void ClassicMode::initWidget() +{ + // Create the widget + d->classicTree = new QTreeView( d->classicWidget ); + d->classicCategory = new CategoryList( d->classicWidget, d->proxyModel ); + + d->stackedWidget = new QStackedWidget( d->classicWidget ); + d->stackedWidget->layout()->setMargin(0); + d->stackedWidget->addWidget( d->classicCategory ); + d->stackedWidget->addWidget( d->moduleView ); + + d->classicWidget->addWidget( d->classicTree ); + d->classicWidget->addWidget( d->stackedWidget ); + + d->classicTree->setModel( d->proxyModel ); + d->classicTree->setHeaderHidden( true ); + d->classicTree->setIconSize( QSize( 24, 24 ) ); + d->classicTree->setSortingEnabled( true ); + d->classicTree->setMouseTracking( true ); + d->classicTree->setMinimumWidth( 200 ); + d->classicTree->setSelectionMode( QAbstractItemView::SingleSelection ); + d->classicTree->sortByColumn( 0, Qt::AscendingOrder ); + + d->classicCategory->changeModule( d->classicTree->rootIndex() ); + + connect( d->classicCategory, SIGNAL(moduleSelected(QModelIndex)), this, SLOT(selectModule(QModelIndex)) ); + connect( d->classicTree, SIGNAL(activated(QModelIndex)), this, SLOT(changeModule(QModelIndex)) ); + connect( d->classicTree, SIGNAL(collapsed(QModelIndex)), this, SLOT(expandColumns()) ); + connect( d->classicTree, SIGNAL(expanded(QModelIndex)), this, SLOT(expandColumns()) ); + connect( d->moduleView, SIGNAL(moduleChanged(bool)), this, SLOT(moduleLoaded()) ); + + if( !KGlobalSettings::singleClick() ) { + // Needed because otherwise activated() is not fired with single click, which is apparently expected for tree views + connect( d->classicTree, SIGNAL(clicked(QModelIndex)), this, SLOT(changeModule(QModelIndex)) ); + } + + if( config().readEntry( "autoExpandOneLevel", false ) ) { + for( int processed = 0; d->proxyModel->rowCount() > processed; processed++ ) { + d->classicTree->setExpanded( d->proxyModel->index( processed, 0 ), true ); + } + } + + expandColumns(); + QList defaultSizes; + defaultSizes << 250 << 500; + d->classicWidget->setSizes( config().readEntry( "viewLayout", defaultSizes ) ); +} + +void ClassicMode::leaveModuleView() +{ + d->moduleView->closeModules(); + d->stackedWidget->setCurrentWidget( d->classicCategory ); +} + +void ClassicMode::giveFocus() +{ + d->classicTree->setFocus(); +} + +void ClassicMode::addConfiguration( KConfigDialog * config ) +{ + QWidget * configWidget = new QWidget( config ); + d->classicConfig.setupUi( configWidget ); + config->addPage( configWidget, i18n("Tree View"), aboutData()->programIconName() ); +} + +void ClassicMode::loadConfiguration() +{ + d->classicConfig.CbExpand->setChecked( config().readEntry( "autoExpandOneLevel", false ) ); +} + +void ClassicMode::saveConfiguration() +{ + config().writeEntry("autoExpandOneLevel", d->classicConfig.CbExpand->isChecked()); +} + +void ClassicMode::moveUp( MenuItem * item ) +{ + foreach( MenuItem * child, item->children() ) { + if( child->children().count() == 1 ) { + d->model->addException( child ); + } + moveUp( child ); + } +} + +#include "ClassicMode.moc" diff --git a/systemsettings/classic/ClassicMode.h b/systemsettings/classic/ClassicMode.h new file mode 100644 index 00000000..23ba91da --- /dev/null +++ b/systemsettings/classic/ClassicMode.h @@ -0,0 +1,65 @@ +/************************************************************************** + * Copyright (C) 2009 Ben Cooksley * + * * + * 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; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301, USA. * +***************************************************************************/ +#ifndef CLASSICMODE_H +#define CLASSICMODE_H + +#include "BaseMode.h" + +class MenuItem; +class ModuleView; +class QModelIndex; + +class ClassicMode : public BaseMode +{ + Q_OBJECT + +public: + ClassicMode(QObject * parent, const QVariantList& ); + ~ClassicMode(); + void initEvent(); + void leaveModuleView(); + QWidget * mainWidget(); + KAboutData * aboutData(); + ModuleView * moduleView() const; + +protected: + QList views() const; + +public Q_SLOTS: + void expandColumns(); + void searchChanged( const QString& text ); + void selectModule( const QModelIndex& selectedModule ); + void changeModule( const QModelIndex& activeModule ); + void saveState(); + void giveFocus(); + void addConfiguration( KConfigDialog * config ); + void loadConfiguration(); + void saveConfiguration(); + +private Q_SLOTS: + void moduleLoaded(); + void initWidget(); + void moveUp( MenuItem * item ); + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/systemsettings/classic/configClassic.ui b/systemsettings/classic/configClassic.ui new file mode 100644 index 00000000..3a00b412 --- /dev/null +++ b/systemsettings/classic/configClassic.ui @@ -0,0 +1,38 @@ + + + ConfigClassic + + + + 0 + 0 + 400 + 66 + + + + + + + Expand the first level automatically + + + + + + + Qt::Vertical + + + + 20 + 28 + + + + + + + + + diff --git a/systemsettings/classic/main.html b/systemsettings/classic/main.html new file mode 100644 index 00000000..2d80b192 --- /dev/null +++ b/systemsettings/classic/main.html @@ -0,0 +1,59 @@ + + + + + + + + + +
    \n"; + QRegExp linkRx("\\{(.*)\\}"); + linkRx.setMinimal(true); + + bool isFirst=true; + while (!splitText.empty()) { + //150 n definitions retrieved - definitions follow + //151 word database name - text follows + //250 ok (optional timing information here) + //552 No match + QString currentLine = splitText.takeFirst(); + if (currentLine.startsWith(QLatin1String("151"))) { + isFirst = true; + continue; + } + + if (currentLine.startsWith('.')) { + def += ""; + continue; + } + + if (!(currentLine.startsWith(QLatin1String("150")) + || currentLine.startsWith(QLatin1String("151")) + || currentLine.startsWith(QLatin1String("250")) + || currentLine.startsWith(QLatin1String("552")))) { + currentLine.replace(linkRx,"\\1"); + + if (isFirst) { + def += "
    " + currentLine + "
    \n
    "; + isFirst = false; + continue; + } else { + if (currentLine.contains(QRegExp("([1-9]{1,2}:)"))) { + def += "\n
    \n"; + } + currentLine.replace(QRegExp("^([\\s\\S]*[1-9]{1,2}:)"), "\\1"); + def += currentLine; + continue; + } + } + + } + + def += "

    ;(=9WxI#+>Ytao^Sz!w; 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—!CHLPY)Kzu5_h6cSyzr8@>?4}H{DvmUig}qm3A9m;#NLO z7BB3Z8TZ_LnY;<+#+79kG*dbD4uC5+QvUqKG`uqpksXE$m*aqFiMX6RsZ_c0|T&zb0z}M0RUH>1pn*TjZ?ifGIob*tZA#L z8eGItT_-iqOR_L`1iXDT*>>@};l7cPohl~5%0bx(=PmPnmKjNCJ6+{eDYp3MbLI4b zj-W6E(75Lpz6Gqg5tmr4ltf{{$Wf;rROK^lQUfFDMm-XsE5iu_K4D#KT>? zPC;qKl0_&j$wzIK3j6(hwQCfrRxMvbeb%h`Y~6&P_wCiGEulvoq!?q2>2Hu~ZBmOi z$72^ZAC1HA@MQcDng}N^e{9(k0CSi1So2dP_MEt)S@Q|Hgei_2k)C;5RNd*uMrc%5 z>CDl1hOv=$Ob>6P?jXt-O1rZPE7EX>ffdNCU8 z>`>)sgXrNyp%j8klHo{PoHUm1kZnQHrlb~RaIm-Y^`Qf z0H8Uk#0DuzHO~p5D0YCii6^+I5ZGWZgu!Z~PPX}|&88T%I`2z%)sF+DjQ@yiF-9qnv!HaZgbRB|+` z@6nZd)U{uv+d29~DmN>w+uHLS>>)4A(T+b*M=TCfj4{UaHb~J!Sh8j7ePQb6iPipb z*m^7tKF4okrQa!hYvqc>iVUC2j3#ckrATj;|jcH!HhaTQ^B^P2&Yre_) zW@<8x#S$B&B-Kn=y$bO{IEoweIqr-fhEgF!)qXVyCxs9t4-L}nQJ3UFZafK@gFi>o z$U$^Z&ppYIX?|+&QtUZYSKLKW-fisIwpqJwZ8;0^v1d_Rr4-h(u)*7ldemLNx}6I= zd=SePFVx&ysVsq??=J0HSV$mNE?tbgJ84i?tB{>}lR|CRI%08Z z=YPFS^Zl9FASJnOeq=a82Y-Q#Zw;UnLX>j!VB{JOL+LkvMbm^4XddxIT6Wtqb zKNzHF?NM9rds1DJkBh5T;+V-a93J&Gjv9_Z@N^TJqqV;3NB;;&()-RqiZRBRekhk0 zA^rMQq^2a}WydqLXoG`(YHqB>s~694?Mf1zo6i5yo^-r;Dg=N(+7lJ&Y2SeFdr#UQ zws4U8Z+myw(l`)>aXg<{@M3QS1^1>`z7!?9ve06ut)*Js#aeKEPt&w9u}BsDFh@_o z!4-wMS(MCw;Kz{Mod*IBnLq#lUr&FpE1T;p5^hu_j;`e4{;u#?!aa^IWTU#O^XlAW z^1t_wbEilF0LtNXa3}|zwuIF+`M$Uy-{$AaO6Su#bzYsDOg<-fiWC5#d}V5|zbjp{ zEsbAWWu^1!oH{R=d|vJpDF8q@oed84`<1fN`N-t!=I&mkX4BmJhZO(-z}4&~6I-Ni z^VIu500017-Dc^lB9&3300017P1CV0QqLEO_kjQa0JzG>Be6v)Ph#%_0RRASm5qjC zi_~=-c^?P>0Dvp)PPRx*qD$`s0RRASHHj|77OCX&%=nUe->lDZOsT`=9^- z0IYw@lRehEo{Xi_ZrLJb%T&u4>HqG@-~J!(g988ncqvb_X)eWao@v+;_3ru^hEl0i j0002+%8xLV;LUmhL_}E7+o+tu00000NkvXXu0mjfy~|R3 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/pager-4-desktops.png b/doc/kcontrol/windowspecific/pager-4-desktops.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2b28324fd0ac1456c2a77b4be55b1f8d57d5d3 GIT binary patch literal 11817 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%0AnZ@jwkwl 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 literal 0 HcmV?d00001 diff --git a/doc/kcontrol/windowspecific/tbird-main-info.png b/doc/kcontrol/windowspecific/tbird-main-info.png new file mode 100644 index 0000000000000000000000000000000000000000..ecaff48479980592d4739239e81f7cdb544ea136 GIT binary patch literal 17472 zcmZ_01yo!y_b)m)6pFhRr??dvthhsQcPkFXZ75dUin|qecZcHcZpGbo;0@pZyX)Qi zWY!waIhmd0Bzxz#Eg|%qg5<{!gdYF^z(;8*F=YS%stNLyMudly9K!OTK`yXPBGRge zkdHT_X$a&Q$w5lX2>?Ltd;dZuFrX4a3Mrk%HJ!!GoJ@XLIyhU}+W|Bz?M&_6K8e~G zIXMA8S)158eK)hQ;iTyXOhU-<-^o=ioo&njvSQ+&MD6XIf7si6lD9W?u`wgyw6Wl^Oc^7sbjdS2 zkR!zqiERIqc1JXq{zM*w9t?}pU^4=$`pAXPI5OW+1Izqt(a_J7NP7MU7n8*}qt9FN z3`e`Fn#R5J#LZ2ckYy%^-tC-*ftuR_pV}IStzlR<9I`yR2qHPt_(25;Jir-%<4B}k zSJsSy0V$j^j5=F3!cT0HC*_?z`H4s#7}G-FV~G$pFhI}21E9mZ9*YQu)DDeL?ZQci zwn+RyM@klKnOH|mAc0FF0K-~C^7=Or{r89A!D!O2mc}UN&1D9ogV}i&fHjy}KyS#T zBEw%|gOyS%(-w1w$0_i`W2)EGO599|^^ckmZrujxwVB`>7^=V++yaMxtSG%*U6%IZ z1$jEHy3NT0)jpj){|*G5?=sL+veYAZ#~T)4D^Ajj6OcWUciHdGg|gL_A_!&*hY!Xc z5Xt|{ecp{W+N^7YB}|6;v=ZA}w^TWBkeQX8$B+Nt>MQeDdMfFl11x`~SP!vuMGQR;z`@x>QMeVs4dDdxvl1*${ucBgpG)E-qdm45jJ?gFYXCMoOr17LG@WL(oNTXTjL6b0it~LYQvr^`qve@{m|D)hoNZU{)oNK@PWWKA=>j?!jleWuF;D zc2@@GKJmEA49j3t$EYFrx9sa=qXSwyyyI6IO>Do_-y1j;#c7>WP-IjwQ|%DH>}4f( zTs{>89}@AA_k~8&6;GG!Qt#xqMtnJ700&0!qK75t-I(C#(dH1tp$>Zb@)`0Q%N4)+o5UNr$ zYiL#3>uaXr>v`(T9E9);^zE;l&zg6|VdzZH*nrKTIbS6Y7Q(>trQp73h16cf!DN`6 zkmlbkm!~O%Mc}roCzkY;20@%B48vCV{V3`H@H5)x!{yGPY0dUeID82SomH3T?hLN; zuzLnuwZmNgXV(~hFUH#k)`+mIwF&R$BNcU;l0`F*FOKm8vWUf>^a^xd503yof3Fl} z75^-|YrWOvyuyy_EFh!#$XWS9ijj|h|1IOCD}7nq;Wc?IEL~wKdquY7r})FsG~R*b zF#hpecA$cum(R$hsrRo;aGG>`|5a8L>vPK|f{42w5HWt|m4+$)23* z$)KjK9hS~44>Ej!Gy`Z-=ie~6dcJ=7j&oh{0&uN-#5)1)8L*uXqlKg!-lzH&FFz>+ z^!Xj^&hddu209s;!XA45ISxyNaK)}x84cPmhESr$o~AVVsH=U|>>vl(9OiPil3^TK zJN$xzeEpKTCA;k+RC|pjRe6nd8m=dhmF;Qvz#G!99gd`-4K(b|WH1k3Ki!Wz zukNP1ESn4Eyo^lGvMu_IET1G5n(Ut$h=fFb;-FP~EP4^MEv3)m6v|~h_HY)VJ1z&uhgmMa%-at^--v3W6IMtga> zixuV5N|23)tr;V|P&vNStgX=15z8tE&${kcL~`LF=UbX#MapBDR5I?&ja)`zqR@N_ zhz6ok0O~Dl6EAFj7?7yCw00x^01f_m9$&sEUy&=ceD`XG679FJemwf^-`qON1Ma8aGgKt%;*0!9SuDG1F9Y-SS+6cGz< z4N}f;XcjR$Ts*$qURm4cT?4iS4=b!keWSU& z46Mf-P)^5m4!_J>>DwLF-=9W8>Jh1q_3$%Hu9=AGf;Mn+UX>|#ciQ5SsVpl<`?zh( zmp0+6)Sfk1;#A%s+K>y)x`ZjgcGFI&936eEW>PT@bXdY~b%AB(Ij(xq*-OfQma%h+ zkhs+zp_gP+t1K78$8MsMWKs+VzN>E2P;mLdSotAf09CxWG*l8(n;sThQPMs;s|hi) zsUR6q50IOU?=aI;!<_hA0D)!9-A*e~3N*bA@!voq@ncWUiWD0rYTL9ODxCN^2*|b= zrMQ#$16IarjoCvRp0fQ+R-|cw+AqQ#l%HLVRFW=J;n2B0#WeMQw!zi+3(uLZs^$H9 z9aoJMi#zxcu6X!Ig|Tst)5oF)w;$CtSGGtMZDGw#jv}W&zVsOF3{_I`)X7dGWwuZ? zMU#q7w?@ScR@JNgn=z-!YI8rp$uOVPc-KO(_tcP93E2GIqvgsE| zHesqNm;U86hEfLT3ag{5Rv2PET>uAAYyMISHO0(tpq5{`WUMLU@X>gi|C5HCE8< z7Q(De7IUtZ7BLn8 zFu$>UmO0UrFbb+jWNfI<*z4IHlBtjz)fLf9T9jW}{EgxlS+NOq!N@XvVw$^OH;vUX ztW*8q(SUs!68P;%QcM@C4LAUuA-uLB8N+@@sk=e?y()W&D-Zq4+Y8Xb8dJxNATlGy z+^F_@Q!5&$NsTgE2?`FLDG8o$X~kOB7UMc1<$nIgbpD$ZAjXft{135e$nn6#7@J5eqCh1mB@@B79+?3&P9>m*6PCg$JurUW z;3Hk`Cnmot8XKbhg?w{;mQkhF-qxsAD!xl=k&iyJ5-<5nPAvgK#+*2VtFc!h=~CaQ zvviOW150|d8n>SErs~LNzI{J>Z2qtGo(kl(;>FYumbmm+nlsDAd)$x2Pap6x^e*7a zT|%Sy4MT4QGHQMUE_7iJS+#a`5RzNH?)DX2BI#g?k10^VjVl~f;;DXsOU(&Nos$P! z1};K5j1HU1rgXzjsB6?G^I=vRON+C_#1x;HnaM?m@@QDl6b{Be+&dly>@xNU3-_vZ zO*}0JCFD{`qf(kCFp?PEw(3l!WK({(YW)|Iy1@T6C4O{X3^HBoO6Ycv(|NSofBl9L zRb>=UW_Q!g(-O=;M;|0qEqz3Q9bhtw#jY)PZm$+~}rhR{87HELYQrl8t+4Bh( z)m=T8JFd;gb4y*FSm)(Xg@PfQGvK3*u7 zBsYg%5kpMvfOytl{eGk(@EvJuEizJIH9_W3oI=|O5u_4!hygp(V1~yhnR1ksZH%x5 zD0%zL6Sx_wyJT*^pJjmcHFz}n?1(Ba%fgeu6n@{CLTCXz;;E8xc;+6gLh=6S`> z9Z83lw@C{+5fv{Y&;eNQ=HRq>{}Z99TEOC{UhssKuk`k=t#HjK4-Ih%ofasCY1?)i z%D1m97&7;B-Ksk=>tN~lH+^*X_v3Nt`RQSO+wypw`41v)yNl7IGJ*{8FJKA_Ai!q1 zPKk$0-(AV&H!h zA8JK(5^u0Z>jAZqj&VzPyKEHCKFGYxB-_rR01|cZZ z1}aQf&-J*|qPn?z0&raKU=-$rHur`ZYh=<%?|jt>4;tWlwyNY~Z?Qj4GN*_>KRS7; z9B+YCn9$+0uWQGmy}40GnG=utye| z_CC4ziOHEWV0~$A_j%ryWiCH!iX@uXFi_9Tu*w7z7!^1*D^t6FnQFz~n}t<6=g=Or zx-O7cn`+(c2{-Hk`Piwb-O%?GJPg`-b()Qs+bq>AsmIlhUr%&qKh@Nn)V2;|TA1<9 zIASJ$afHa0wTtC-n>eIqS=h>*txlo-3bCW@MuV-)#b`;B?M6pAy+1NuCc+G-wQTB2 zBVXmSTAGrF3WnI`Y7jC>)|z};_UU5v+7!H(lk3?cg!!(j-s!FAtYfL4maZ5pzf>

  • &vl3$Mxu_()x8g#^bphEbnnCj<=~a2#DTP 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 SmBuL^?$B1(SF2WmNB$3&mQyJJ literal 0 HcmV?d00001 diff --git a/doc/kcontrol/khotkeys/shortcuts-action-command.png b/doc/kcontrol/khotkeys/shortcuts-action-command.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed9b2bbbd55acb07e1bce021249bb31eb6cb22c GIT binary patch literal 64061 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

    M~q&N0>a}$v#T|W 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

    TeHj2p+Ci3w4Uxp{=}5yq=N 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/ibeam b/cursors/Oxygen_Blue/cursors/ibeam new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/ibeam @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/left_ptr b/cursors/Oxygen_Blue/cursors/left_ptr new file mode 100644 index 0000000000000000000000000000000000000000..033662ef0be416ae97ef2c5cff53aab52a7447e6 GIT binary patch literal 32416 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 J8G-8|@PFrp>F@vm literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/left_ptr_watch b/cursors/Oxygen_Blue/cursors/left_ptr_watch new file mode 120000 index 00000000..3126613d --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/left_ptr_watch @@ -0,0 +1 @@ +half-busy \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/link b/cursors/Oxygen_Blue/cursors/link new file mode 100644 index 0000000000000000000000000000000000000000..2505958285836bf54159ce12dcbbfea4afc5c073 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/pencil b/cursors/Oxygen_Blue/cursors/pencil new file mode 100644 index 0000000000000000000000000000000000000000..cd6c843ab09df3381d355f4287cd80282d05f51e GIT binary patch literal 32416 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 K&d29Mm;VQjC)$Vr literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/pirate b/cursors/Oxygen_Blue/cursors/pirate new file mode 100644 index 0000000000000000000000000000000000000000..a492ef0f42d1838d71f2ce3aa9af988793b589c9 GIT binary patch literal 32416 zcmc(o1(;pOvFDGNnVH#=#bC)|W@fY)N6ajZm`2QC*&^GLEXyRBW2V?K#f~BL)V@07ueOMUF`8SeeKEAk+y$KLpwO3nZ0>(h5hXD1MbQ*@A*!; zM;5lXhf-SG@{UCeJm3=z%7kCGT1A3s3+^rG_`NWzgm)$rMQ7lxN{4Tp^$9g_ot>b zvC|Xl*om>#?7``c?P=-s$ix=5u3H)LU&fA3Ze=f}O>tMAdCzy!k)C`91{JroLC&Ur z4_*OfU2tY&U4tvxi7{1e|A1n4Y-A-nGpVjUx}v+ic0_iveXQ*s zQr#Y1-pyTk<~`p@M|$$@?vclK4611018;=Cc>UtR?zt^<+xeNzY-f+WN?TlcD%$A@ zwOqNKpV7qW_~M+F?#eUe$#>F`ep|QPj>baS3HXG&xB&g+%bF!bNVJbBwCt~pyYkF?zVGOs*S2)ZVsq}v zXXFPD_#(W%UCOKH8o9CsBl=elKAV3}emgt4fo#;cZ(nBVJF3_i26d z+kvt5X%qfPKJtSHd>%Jfwd3O#HxF!6hrpKJ6WGN1fz5B7&yJ6-Y)#5$v-=tbR;`Hg z#;(mPs{qEq;a~cbOgTSWU9oUuuRqW`r z*0!sEDQi|Cm#w}xt2M8b+x8BvXqQ$Du)SmMcIik@KJxdj8eGkj-PNrGet(lQYfzwJ z@nE6SyfvVD@Yl(bV};s*vnieIsnp^2!p{5b=C*NmX=xu@+pD7Sophvcs6K}L9#{M- zdZm=++U&;J{`bOW(viw^K?}(teT=Fjz0?bAhVJJ`zcY26cvoO!^lp;wNk@9}&1#(W z&(gzn>7#rczw|Y2b-R47KT2&M*s9jje^XZuUw5w({6XJ8E}18|Q6hKn7}vVRf=_s_ za{8Kdq$eN!8F*BlQ-nWZpDOQ0;^_|ynrEZ_{YS?N!3Wg~2M@}grz>4&0rjzg;I8P} zOxN!Eo}zS@l>S5VEo_k;+5RMa?eyKZ|GEwG%5K}}J@`5bY6;2+iU>3+39<{Q=l;q) zb*PvCT{IH(SN=7^0}kqMybf>=o`TU8+6nn|f4d*)phwwKx1hQuQ9efby zcV3G;#+dNzf*y8LW6M_#FR-`Itg@e6NVT7w-)L{1T4668NU}zIfu0cs_2wxOvjPc>JJ!`si+r^LJ}3 zzDL(x8kdIv-=93P&5h4__u-|@_T&3k*_+1}xN-D>agA-Ra6d>0u! z?>RJ1F0S_YDW{vpS!~OYS{irFb3A;0eZPJF_#tN>ZyZ}_uN|7>#;-qqV72tS$))-9 z(KN{u&MA1uH^#W6ef3a^cwgk&6c49h2+@~ z$#=lMdiuD7¿@AyU<(vpX~H#ZG;r}t(#?dt0OvX_-A^DU0=>nnTPlj{a(ygkBR6kYW9w(R*`&DlP@ zw8_~FcJ+&APC4K{w3$sV4Qa_kUT}cxG4ah6czAw0J20}E&2Ez2$pA0#B>rz_OYqP4 zJk3f48{u93xm{V&+pv#!&#ty7*7kREv1==O*purAX}mGPUfw(1PS0v@+XvRL9fNDz z`9-}oC*5w?*OyNocECOF_(mGil83zD02er!=K;*K9-P+5_6{lUcz_ppg13lAc#Z#f zrfhPR$P=`keRuHRDavzjd?S_f3^(U|SYtWn2ahc5;Aq`Yxxch$n(Y~0*Vc3`rTJPo z&syK3obomQhW+!7Z{ggojLSn_aDXf1zk{Q3Ze~+AS2;eavTf*D!r%p-;0+!lUgI*r zJNA{od*$E?@-EYy9eZRR{>c2c_Q14;5&!M&+VUPwZxTrw2}41gLL0jbM#36%+1#e zSOZ|40pOl@d`suQw95+)aDfxt&|vNdP3EIVM`+$UxV*s=yul;93Vh$7+fetiv8~9N z(khQ#U)4wJ31jWJaGV@hLpbZZGJR-X8+&|pZ)aDjy(-w+O!$Y-E&Z$7JExXA;6CI% zBmd+D2Q~^$a5Kk+7Br8HsNmKlPK>Eyvs>hHWdM)j*O!5}A#AEh&njVCzp+mRyS}=Q zU0&4D&G}gyV4i($Mq|5}a*titn#!vOW?5=)@sI6${kt*<^}M-XReSx&df*n*os}Ij zFJ_*``U!SP`98Y5yQ>#_N7YZ_J*>m)PH;m5TF`{H zU(eV+pq%3$9^q90&)$aUr^`)g5d0_npU^tNV_Msw+zv|qqbf(r^ZrS9*}3UWTz!6B z>mQFSACS&JYdSHwykem1Q|VW^kAI8T0dP26Y9qi64QN3V+WYzywxc5}*rAb?9slqM zuL3`|z=p7=ic{|n`9C(cmRqC4{*a$_vE!qwIK5D}uu=M+H%~0GeWUM=>TY`d+&`v~ z+Qlhu?ThsmP&g*77htzg`6ZdZ( zUt~|M8|eBa`X=sq$2a;f(sEB;#zWx3Zq5idG!nWO?LFfEsMet13EtolUL&4q^Ar4c zsu(;*n&q8}*`<_LcE8$zJ-zeUzWzm=EwYwH*;2ot_q68x@0?uf#*wV|zNhioJExba ztyF)|wS-+?*~T_Grxs90vx5c0^m?WRR}TPQ6?F^>*u;uOFUgFUr;#$E@jG)Yf(` zW>*$>cECOF_(mGivKC5SaG-a`yKrNx(1IrGT-=`;U&9u)E$H}%M|c&$v$r4WLis|u zf`J-)|AW3_-|(t#U6_7kcTcU^^ere{#U1`*TCY4gwz}3A>u8%ZU)9^q9GufMcK zOzH1d`P`rkW@~;&Tm10+do8s~9^2GOYkuAHNA+3j$tq`8rzIcjyYPZ88Fx{3@W?pE zjb*skJHC;|@vS`Q1{~mG?UMQm4QQ=vm(}*mhWMV+D!;d#8}JzM8gD=83z#R=(*D5+ ztug(bG1K<`&o0^;|pX zWRhI8iM-<*X-G>R@`3|g-~=}`)`)km2M3q29Rtd{@f$qB8$3q5#``boF>Mfb)uMIT z;3{P>t5Fu)tFk*cv$@?rt%+^voJV@eVH;R4?xc0y?gedkpJJk4$_{Fsl(80k(S~3X z*t7%P^Nw$%AuV~x3l4CB6Wpoov)SfO*;IdviubZMTVr^5fhTy2c!XC!pV6)B$0!fh z^y_Nn#Df$cIrJUYCh%2zUU$SHm0wvC$h8@d&-IZeX(BRs$hJPF_}u6x>keq7xcT36~p4MA(o z-$xIr8GL~Zv`Guw6wn?~{jgn9-{#l%cS65MZYPs#v&94L-`+k29dMtfcYJeu07^?9 zzXw2GcxP`VMf)t!f+n=#0bU}W;4OLVtXGbIWS~8zU1EGxThLbfnj>1437*i{`yb$( ze^1`T_|WY?um=&r_Rd*td)I8XqpNH|{Owfx?Eqf&j&G##=@Zw^8Z%11xh=ynGPIxx zZFq=yfv0$z>2en357C;^rdiA@o2WjhkD;GT&=>#f+oj9F9);hh zAWiafJT2c{|2U+q&2N^&paCstMzrApUi_FpKJU`&3_mA>_IX*4omIO?uuyC9U6jJf zpf$cGS?Q7bjaO1oAEps^Cds`S*_xAcu)<4hW@w%s< z*fFe*;~yH(f+n=#0bcM6$eZ1jgX8m7f0~yLR-t3|Ll!ny`>FielQPX4Y?Od+^IGRk zjIZE0mvL(wthX)Jo-R1S4Gm~P6WY`hc;UO&65qHL-~N5WlEGZ1{hIV1 z*aKUja!e8K$)dqNC*Rm#WPEpaW-A-rwwf(zoy``D7PhlfJ81Fxm5YyK9+zL2LQX>|xJ`zQon#2Cfd-aM`A}Bff3w zTS0p4ZjUVMVVCB&*W9_D^=?$w?y16bllaZ)_ds)^2wWtCi@h zzzJ^EQ`7#mqX~X^fS1zwf|j@A`BvYwUR17j(O^QS3c-1`ZNGz#)>GMwPv{5VlgrC{ z+Re=)?S|H*ftv#6zRzwQ$|=e zj`HdY#&@n5oEuvw_^oe?v|mpD?)2o!S!1MCS~uA{u8Cb-(#xLHnjrlCXzw)5&!^gz zRRitNq*kt-Nr}dklq)#E<=Y&|@>^&@^ZW9zvTCI=OOrl6_BJT{vzcnosAJQmv#GjH zP&p5i&e)Ik>Ave#>mW8-wlYCD!39omLjzhKk9ctQBb#QA?^}PWBU7j=bDL(DZCA0S z_ZDzI1FO}ZZBSc~sy1zHTdnWvd7k#psdLDncFP7!m$cvP+xsyXd~nY@zM*f@l83zD z02esH4Gn1Fr?9Y9F1NnKm_>NLR@*X90wj-n;xc7b8}%kMPfly)_A6f28XDuot?H+? zsy*8*8mra5%~v}iKOh?;K9t7>%6>IYH|?eWRsH90)#v}JdZFM`!Drgvr~m#P-$+AR z@{kuC-~uPOp#d%WHuhxR)1J-o$<17ONbVQKEaT+Ne#n(wY23cc{nMM<2NyQVhNo&y zl+{+=6WAirVP2{6Vb~_AtkqupUH(|V(%$DQnp;009NPrz1+cWDYVG-dML3wdFb+!o!GA9G(L2!pk``HQ zYu|FV;FX z1ap;ljc`0DTyF^H@4yXh56jyXvfV>#*s@mP{;GI8sC-2Q*#*fz_|L5|Qj-bwg5P@_ zT;*Hwrw$c@A6G9NoR`l9dYvd3EMRQfO2C>xO#$;~+C0X)jMtfu0^FAsR1{Pf+$Cr( z=qNy@34*!8y-75#h}H-AbHsU2egCt@me2%uPC@by{&`k! z1?UicHV{-5z!P&K){^k|U~a^^006G!d%ly7v3y|xyi^e&5B(GPp)*CWNVL<$!;`8% z*EFVIsdvyuA2|e>{iqwvanK<=qT3b%^jkx~d(SU+2#@3evPOU&JlyIX>9GO$Kqlk| zFZiK@zY9Jzy#>gF-a7~=JJOOrvmbQ%25*G~*cy8U%$d;}{6ZJLJde8l-an56eBcE? zbfAr%u{Y!aSaah&GL!FCKfZy_>xgSykGIPAL%fgEhEMDdc>wN_@f*BTDEJ6rd{F6Uu#=+~u>j+-aeJ-`Zbu{*wDF25vwXx?kws=}?)7z@gUuj%No&K6D&%Eb5 z=}1pL@`ESB2VP`OE`vBP`uzXx7w3cfxZSw&)1GmQ#wCNLy{ZJ)Ce;sq7jM(P?>%_H z2VU@tF8WH=RWfh?uay+1k6tK8rxW=xmeBYjMPttQzpoDNBp-C32VLO^?Zw+lOZ?H~NBUp4l5d{YnD80ht3CB|i+b6k>xSFS9h01Y*qiJn$Ounjv;}es@b7*VN@B|E+LC7y7a(`ZBL4U-#mC|ErYbX=Kog`u%D>ssxua zs^k=~z2YwoiUuyX|B7?RXurzx=9VZJygP&d$zhr@i6OkHYiA z6+Yotinvvs`@TBLOgFh}7751V*Bj?yuJ#)rT+l`3y2|GO$~nH{J}4LOA(A$X)lx8CB3?%UtBlzP1t81%^Q}8Zu&e*YbD!; z*3!Dq49OGvRpQ5rUEuGE@9XPF=i7_BCpll0*HzY(Iev=Bj^Cw=?~+d``H1=AijOJp z`R;V2^yDKyelOr-t?3Qv=56Wi4f&bE!}D6#d0KHkSC(|K_3{&9Z!D&#ui+m#B6*OD zdf{c&?RWb5^oh1cx$B9msYs4rkx38+-q+rPV5=Qmf-^j&&=cT z(|JR>di#|6Dfuzr+x*eP+ng?_KeRXad~)R(9r2xXq$eNw!2>?A+79LOWctWEkh1!bn2e8RaWPGfG%y!N=(Xz?+5|J-`}SaN)J zElp*-DBG|%~|{P_Nr&L*fM!~>#Jd@=D+CWenI&%6)g1w$Jm zAAT<2!B(&#@I!}nZesDC)tV;$f={OowQKS(!LRb9)@+F(it~>=QUr6+JJpfb5A~D0 zd8-r(h6{J1P7%X(Lw+mx4!tLzVB#I$74J`|%&so$=6v5MKh|NN+Y$N)zkXQ$&GKV) zJ}?i;$64!2A3d~L^6w1WaOs1->zB`-a@Q~POkLwU=}7;c@{u1r;KPR){Lq0OK6lW^ zm+YzagYAhm{ha^GdHH;tl&{2G#TLeN^fhuJUnD2;df9cG>CbGeWYr2s-!uiP1UgGmiJMggl!|(?r1`ppxVm6=MHrlQ6V)sud{_n)p*0xQ)x!VWT zv@?nmcyZqx`CIRBKH$V=hV|>HyYh^0INwP}dh(GUJm3rK(-cPsdeDVFd^{xIpli#z z+oRIgrMdUm{gdl!KdG|YfA+E<7xE!zB=5JiMd-)3Il1LOUu1BN;B}90w)_bmR=Y?0 zh@CSAxw&Pe^9x`PjlC$!?(x-qrNg07y_#+p7Ic&UqW6;|o)llbvhwXMZ`an3cD~uv zP5hkE3s;`;+2%Xx68?wX@S79}A9!EhKi$!R9(17(AMk@eB6`A)>OuK?9UrUs%AxqO zrnlM1hn$j|el6Z!>oLPGt{cV)#3?WHy5YKSY+cpuiSq5Aghk2KOx=yP1o9^W)hy4dO3<4-kaqFv^h_dZR!e$stQL;qy?e2EV9 zGSd$}NyNY6>*RdEv?rO`yF|R68FC`80J(3aBd;GzKdt`dQwwnA*Hy&R3E4 z@#)kd&Zh|a3H?O%>+!V%T$#S0_3KUQV-xyO*?T`{{F%M%+f;9Ua$$oT_b~PWc;>xN z6Z${P?lgBJcG>%HgC9Dy)zD3^U!ncLAHGlQ6XW}Iba(~ryUM5g-t_S{aw4yEbGv$m ze$X8{ELgQrFxKm4w)~tf&TXrBjFE1?h`laoK^H$aeBSVZ!}p%{k-ahYmd?%Z9O@?W zp?0y_lF!#KY{JWbb3+Sf7RMfcEw9(17(AMgWT@CTo#Ce)N) zSS{y+cNAYd`8gq%ml1i9JCYwgpbxT)836a=yQLh*ocGU8ae)5e1h}0j_k+jDDB3f%&?)5rT`-qoS z9*n;@kKwdzCe(km$RE4DYx{f~bY)2=m8D_;<&(d@hsxU3t+4OPOh4W>QsqCw{J{gy z{@d;J1Agd054zCzeHU#q?G8TO=m)+J$p`T8urjU#O_8XS0;^H^lGswCXdypRSFL+93K?#%;_2whyWi#{MMN zt(g6I9qbxb&&AFWKL_yaza{G@xsE{xdeDWwZ+l$ZEdJmVe({rp|3iZmGoXG9AJD~Z z3wZl6Wl;y${#?>H0>8#1ve9HeZ2WzR{lTAv zJ%8f+4&A5oGZOJ3@wUge(OkoJm-8vu@ASZPdOIFVAGJa2d>bwN(19Lwp${MMlkD3K z-|)|Q4#f4GP<+zruEi4iL2l$1B-b&$a^oZR+{$Yo{WGthodby#=-}oyln4Ie_`jon z*9NH{!#|8MhVRFiD>Bc%u()SJKN;#)!hRyT^?Y%0=;uy91n`WVggQ!3=icc(__gzbnQ=Z7u+T-_4C@D2a_<@uh>Nnua`Fbms$JZ_58urS+ z_~@{5&VCLJubj{iawES0JScyS#Fci|=GTg7a%U@XT35e7{v*@PZ#Y^j*-Up1ZNK`gAwuiP;W(JHKkhf*e-d z0PXX({#xUY`gr6J*}t~ME!F(LcL+Trdi=hmt$Hcd}zRcG%^`pc_(H1?Zw&+>S z?cbE`6NmY(bi`WG`wy(u+SppR9>{vv@yRW0QLEf`U{qbVe#06Lz%%dpPCC{P$wz+h zfDgRjhYs|h3w`=?>OJ+!^;yK>iC_4Jf7d=sZ^Zu0Yn|S|Blm6eKJbD+VK*6c6UN@aAAG_ueBM$L?3*s%xX zMt(tN^$Y#bE>+cjkla4Id8xit7BrIY z#7})b&O(9@V$>MFL(kPSr=!AQTjX_=A>K-{Rw^S`-!yh|abxP==z}whgJW#xfjI)e zcqS1WN8hddiC8n)b=XfS)+|HJme&n!PGJ}O0l&nEP|wgEecPh8g%Y|!UgVDCPoAgh zbvXCZm9riiR4y1S_4>ijb>FbcZobFd?}6!!Y-{K2ven$SCu)mad+l^YT?=FD=pW!C zY_~%_F$SPLV~m2Vj49DqsI!)C?92GqzvDaUNKZcUqi@E3&Sr!kI`k2)y-{5c?WVZX z1^mG${Bj0ZShuR!{^3>9eScNAkQccl`IF~hdhN!GjH?-6*AcXlFRF{zMo+V}{tsX9 zep%z`tvw3cx^~%Yz2fLLDgJOrPhvpTr_mm19M4>kI*uJvwq8%6J=J$(e`IA$j@;P9 zH$dQg*MOLh`97XDs=0hC*$Z?wh!5``oy|vEcwu%+^)Iz`##_OJj)>n&RZQ8Ap7j0U z_|dgVku4zy;}O~j`VC}c9VwwNwdb7qmH{GtkS^4T;vbbCJfU8^&6IcJKj=aqKH$ge zX3f1>Y<-7ZjxThXHn>6t|77GuUIB75#z7D0!>@7Z*7fzi4PuOax1gi^-hbkCl%lnO z!=tOa@;o-7zSf2AQmkP9gpP;--PkFQr7GTWTaQAP)<2BLP1jT9^!Q21$oK=hV*LS~ zB}4dL-<2+*6UA5}V_28aOIb$;deDVFd}P#(;*ok3P`j-8sm@1CX&#=tf?UXloRPeK zZjsp%70VOMl27{o@j9B;FuNTSzqARorI#19x1GIP!uc^c;b}e8#dKK0ggNlhBP}24*ruFbJ#qOw&q0R8|rr1Mfz<1J-o_yp75BR_f ze&`T`N-QVz9UtOnQwPOes@)+*hI^$l#vuL04| zR}nN6bky4HHu>DU_(JqFy-5x`IbLVcL^`^v^JLDbUD&Gl(v2OYBh~rPmK47l>1mVX za51c^lbgF2w%vV;yMBargS7zcAsKk@+7-4&c@?&Q`%mlN zq|d`wzQ4{$Jm>2fSI$q`rSnMXf86@B)?t~)vMxnT1mlezU30m!MYnb%9yp96PL+H+ zdnra;V-d!-jNw8k?#i0-_V4&kI?|Jm*kbU2k26cb@92nLS`@!atS)+D?33CfJ=WOs zjvUAn$%TB#c{|(DXQ!XI4bj(^640hM7IYE}YEdS5)YIWg+{2=F1?{xv_Ka1qCH8k2 zXAs*+9LJ8XjFof-sf$t8Ii#|A#@}u(O^mX}{s3{`9{fAn4$_gHeC`}m;+KUFygmkW zXE)9`4P&s;%^u~Or}-QF#rcJQP%p4{srNhirTX>X`gi!~pLmmPe3LFv;=x0nmj$wC`e6EF_E9qMAK4P|Q}Opcb~qki%=cTpPtNagVK=OQ z9a3AoxJ~-rG5o=&AXzuagIvgmoXAVvLH^tQybZ3R28WE-HkGylx>R(iPAd-7+dBkYE8=s}&k=j{i+;4k76e&L%k_PRl? zaJIWe( zyp15vy1!)mu6A-O{qP<<;7jOPeE?%8=2ZtZrstdkY#P4A=TL#u4Sd5tav)EO(!nO3 zxl%>nz1@5l-6*;HaTb5BVKsxd6Y+kEHIz>g=hR!DYQg7F!T z$SH~ML^n=B%}NI=nU?}_9T95^E#ggeW-tE5iLo_(D*V#t>`>e4Wf&Tr!GL`J-9Mur z@R1)I*_vLR<^5_k4j>-p}yTJR9lxk5l(y!uL0 z42_H1*1D1nk&b*DJ%{r_29|W=JK6-=P2})rJp54l0Uvl-(_pR0t*6PykMn6gFYpC_ z#FxV_e8WF-AP;hp7CG-sGitQ52gQ^>VHcZK->LIlH|p$z<>1$O3gZ=e>eU;+YH;Rt8p*4zWU#fCR(YGn0;m^Gw-@-Pz z)7SpA?zKWbmbHs#v0BB{Hp<35@a)0ARZx5BJet z3ls;E;1zp6BA-`$-dO*5ctHo-IHtAj)VXP^^uHQb>P&+ACDVat56SOWvwp0z-VUbd zd=l*yads?zkY^S9AGcfR!w3Apmv5Kh7rvAAgM7$&r@D!!m)}`+`BqI=%;zIIZ{dGJ zgZ`d2kaI9xU$3(mXbHl1GtX;(VHYsNh=nTIn@i$jo1->1e_lYmmF`erWZ*$NA^j)7W ze%yG6c1V1}FMPv4av%?K#pV1V?&V9JU1P2mO?6gMzv{t@8gKoLGLntbPdffMzk;%g z+uhn8rR_24hO?ll7x*7My)gy}{{+Qb%07rY!QYbj0qo>OossJO((v<3?N=!Se&|6L z{lEwOz!&_%C;Y-U{QnSoxD5{KDZrRKr~1W;+P6++tg1NKzv_Hb>s#%cc7(2GF*X|8 z!082<@n=c^I@mqY`7xsle8JEMeub~;tn=58>U_}MlkMn~mg=v=v-Q0Gz1=_;`tSii z@CAS3^V`-fl;j8bWr^F5*8X3V&&=Owhy1*QF*WDBz-uq{>Ad%H_$zk4Ni91XCg8F;5@ebB-1d}yFO|=bykGQ4qZFJ zSz*}Rt#rnFzLSo2g?!`(5BR_femBk$J?KIoKKwia{@@dS7q!qn;h$2uPrvIgi^h|cz0Mg|J+!Q!y`}&2!vC4T=Z3Xj#^~{Rhu6^>@v~6n$C+33BWf?* zxl(Ee+!;9zR!+a=xpMvT8ok!Ru$a<_g5X z5qm^TAHLY^DR{cf$y^zU$GOraY_s`&m4(-1i1L_JNUT*k<&kgOeXxufz`RU=CM?9uagPh{4y705sO8<5{ z9r2CvLP3qQ621xR*%H1+1B~PuEM(P0(3DId&0r7xWPf6pRpz6HFF>16(Tv>(vJx(;EEqqW2|qO53nch-+)9LeB$@#HxF+VLJK=#||$Bp}xrij{r4DsB_^!&5R?H`I${I$*x zdr9Z$9oKmd%ak7*K%UV8_T$h2^4}|9&$_7qACbERteMvo)DTdPTx$vH2^t94$74^1 zyyy>Hg9YH8B1jP|72OS@|A6>-P5k@@zC4e&yGl;#H}u%+$tk#9JLL6KSarXS>iaj& zkbsujlRv1=ysa4E^Et8xtA!IDy*>u$p7QtW_~-#0AUk`x(@J@MD z5g-?OK>mUP@aBymkFEgq9=?F&d!HtszOh$TNPrH(Syljz+Jc6HRs!s+k6@VKKEZ6k zV!>MRyKHp+ES6J~mfbP*;E+8VhI>&3Q|Kf@kUobvW6!s_Gs3!oC3Rnct&N&&)=?3;rKEjn`G2?_}G;zNw48?e{j1OkOwSzmuP*hh8b8%@bM}0*r|f;^+jQwW zeoTWp{CTC$PxbGg)OjL5*Xvu6`zCtrQa5vinhA+}p4AjG)VE_|2Pxf=F1L5im0goN**j{geq=7$K2vfAq)6_d zruv>a){dI2|CZLjXG|;EH~u|sL-pz}k2mt)+A&*>&iGVL%>G>N?4D=xSG7ODd+WH5 z<;sTfa&7ZuDcL$xO190A^Go|n;mV;_f7#xJ))ysPXUP5;U1RDGV;Na!mCbKI7X;(dv;>ylJB9&MdjJXMvPy`u4;+d3-uc9v)dGW&0K@ zZZqXjdXJd!d0zkC*)!i{zP~?19vxdpkvF4@Tv|KEboOw1&zSJ8=)L9pgZI_s{8rKX{qKp3fZHRn ze`1fsmE`tHevhPJ_&**2kAO$OBj6E8as(PQXwb1?!-mDWe|^Fpwp@C`Z{$hDW+GS9 zrcM7-PUiA$5b`8q8zQ*Nxb}_Y!m>e9x-(tVT)DkVliug6&6oOVinWKliPi^BXD%!o zX!d%k+U(e&rRooGsX*=PNdG)ZK>1BJY(@MHIep)djXi%Q*}Yzu+yRZPKW;^QC$u3^ z<-dje+h$2l|2HLfU}N?9G?A@?n+1KL?Q-KIQRT;e#$UB#`0r)s$aiJes6WW=(JiAo zl=$*1{^~Qq7nV2S1KIy&YfT@T{xGI%Q~nC(cashMVeI0&I+E62j!y4rzPCHO=E)tM zi=6z=xyE&UsO_RKrSXZ>AHrgxE3^Sa9E`Q6m7H{a58RCemL4f9`Z6@ z-P|%w3Rex6+1*=OTjH@kC~meVIF;U2E~&5U%KCBU(?tFoDnGu`QpKLNihr{X6lM-H zKjNjeqwV>=Z+wzBwxroy6znC^?Ve}+MjqNg8Oq++GF5dk{_^Lq7^MF3;Wn=` zKOUaiPW}3y$(aS+Rc8iR+pcC!Fxip&?!HBG|G-j9-1Ce!kOv$nLs^qw`^VuFFZ|Ez z`wB9L>iqr}IWY0Ba%5Tu>;EYB>&BSAFb^?izdpRu{O0)1x#tbSUSgpeM+}BFz55l2>o~Z{hVuD z_YW1#2TmULKdfPlPuf5~piA__{ryX$@>f*f%l_TT&)mqKfN}A3Z!t~3*DbQ|crM?| zman4sIk{M4nM>?@+Isd#6KuU=oR(@|xO^4W_p*O?a`D}j^|g?FhOTo(Yew4K!v5|? zZdxMCZ|g(B^1-?;jgIW^0_?A`2hzlzHPX%+pWmz7Uv7O^(C>Zw?p>to8`!hYVQw$X z94;Ay+nD_EnBS`_e`VK)c+T%N(S}GrB%S}Tx^4I6Jpvv9kAO$OBk*HFz?~7|Ts3Ee zxRQ8I@@Iq;1pmh);1Tc$cmzBG9s!SlN5CWC5%36j1Uv#B0gpfx5U5+XZj)DEeKlA4 zdjE9a9$$1N4|yq5g;ynAk$Uy&wbAcn|9%l3FM3WH$|hZdV-Oe}s0ua?Gs^xy>k;F` zwYBX#ugmftDRN%VVRB~6&f;?(Kaw~n3vWELPcv!PqM`dXF4Pf2mn2oz@O-nfR};g9 zGe4Y}c{agY2oh&E*7R>4#fLhQs?jkB>vV_f`Ha4Heuy(fa0l!ROZ2K|Up3}~OZm$O zM)9F+46jV8tYLhD^Hq9YTgTSc!A&Hq`!6J`$1i1LkJpTQv3+RsC}wa1!ex`H(J=@c zZexk^IN)-iKbw00S~m6hjco4QNOJnUq3KQIc!YH-TsDSRCRNsO8*eFBgxDjbEyOn& zs9YC~ak5SMF58Cu&Qj@4&hNoRdU|$@I+CihxmNi*(F?$|cc`TZu*@mQPoTG*b#ju4Fw#0Xqs}|v4djmfFp5uY z+G}BbKCWW~-qNMD8fy#vfuD!|C~u88YH%Nju||Kx6|i+%F}k8W0&oEj%EK){|ES}p z>Kk03AUT{=pWusP=c^7;7j;rM@8Dhe%AE_#R$Gf$SO&Ocra!Ak$?j3DY`+J0+Huub zn~u%sBqx;v25<4);$G&zaOF5F4}T%5bE*gE0{X`@ej^X>pbWkb>M#zZ)(JQC2Ku98 zxj6eNmkk*c2A>EgmHjY#VD@_ZQ(N2G4cD1@n3#R%7KN};ok3T?!1%7pl{7t5-YVSH zKri4=PO?1YMbDxbXo;avvJQe?0xc(moia|v@Yrlc&O-)=24wXG<@>mG#jsH zn8hZ*R`?&?v2oQq%713Opf|Le{WSYz)+y%Xdm8VMWSnSy#&6^yFJ&l8f54@NU&=UR zd|lt9<154!O_cG4obZ#8nYazuPuL1J?`W(__BUbOA;u(g3gd<`gf9bZzyyvaoI&Fa z!q?Pi{6-$~QiihBVdE^KLpJ{;C_aoC)(zI70~!+|Z^HX#HyoMP-uA`BDq!9rZYO!3 z>dsVK@7dQ7zY=U7DG&GY$qkmc4>+xhZ6D2g4j=ug4h^+BEgq=xyqTvaB;5GIHoy-W zaP)`UI{!?Z0p?xfWa5iw9L+agBjbko1^pm~sBwN3n;*_@)|3-)fA!ywj;~cd^D23u z_`xZ^n@2najisPOM&4(JOEy*#l{x z(*|O;f(dp5aa!-?WtjiV@X>Y$oal9i%lC@WcgpYnHi8f1&EZ2?>ack!f{(>H(6xQ{ zlul9osm=Xi*uMDey~eU}*dK$KyO~3DpQn38U5m}mP?>Fga{EKw*D;=g_yQSG{c&>- zJa;(z-<{rQym#(-26hh)E?50w-d0Yn)`6YD{t(-R{@6F|bLsxk+fjUK)4r&VeTt2M zU3FLI9L9&^raMl0FwWM?BjwjuhMOK9Pwu|9?Njz$RrPPUF@_#k{1aW9h-<=n&O8K8 z%+16!W?Z>8SN56+{tdS;t%`pP-v)Mg*`9^A?=`!OdCBw&yM2*7JWO1GOk2MyiwpA& zV+xs^e93YRx6$^45sWO}fSa3mrZ|D!gM-WD0kH>kz6qC2miERfXSj`KV`0ndxMIHx zMy$`a#+mPaRUT2rbA-z#OM7FLGu*~Y8t=mCOTmhvW|x?MguS=go!DpibIhls<1Jh^ z*7qh${%{+yW%+*zqBw0x)v*tWbl>+$j1`v2W@v>0xME7k9)@xzMLcU`n* zv=r&s;tGEJ{};VKc{hqrZQ4`u#-}>=8e=mN?5TKTR8@N|k?g5>V-$dGW%Ux_p4pmGY5}Ue)YorGY+t}#vB4~Lez(+dYUey0}4Rnn(>^~vBLU+tXj7PZLhE*)Lr z`jpM|52c3{H+q5Njy_KX?u%{H+}xM$ao_G+;1ZwC?07G@(K6Bt#{=L$zh<s0>ge8{-OX)ywXFMM>om79v9|ki$4s}hb6Hp8kzlRzUP%Vh zQNHLHD|#+~f6u6TZguBkZf&P=KI<+WTjhF{&iHrX zrw+(S_%gaFe}1c?Zu_w3-K?ew?wvW^)yDnZv1#p%?la4V*qz_JKRDrKw{PrA?&QqQ zhJQf0OvrEn0WuQ4OeTAj3jV%-d{ei&OL4b#V0Cxs_2zE-kXm*>GP#xb)yQ%8?{|-^ z>$VN5?pAat9L8T%h-t&{6_d$BlUle{;`92RW!<*H)!nY)FBpx`3SLh$@3$mYF}|&6 zFZ@SWx+wj{gg735OeT*_YvE#==l6E+E$nM|ep3eDNk`kKg#Px$g1;P}(b;Vu zT+?WS7xXdko?SlFom(}+?)>IG->JjS;m^At4li>ZOJw+qcylHG=P#c-*s-8(N%!7@ zzLpmnPrcdGaDK9Wy!&j^>yA5R@t*HT-)QZ=-t(qg*T1$SzwqZ5Bqu+)vSbJvG$|B( zJ+DnEcV_u8({CTI8*6yK+CJ0pe6?ei`+Un3_lM1s-B;>Y-ydA!HV%5xk&pbsolB6c z{OkS0>C*+3D&-0G_9>m==Xq^PxI=HWcOR`8}ar;F)*V z%y=6lcsh45s(Y#6Z;Vw#E8gj*G%o1+mPzM$$G6*n#4D1JHDmCg`s2_2%V?hPMqBsO z(N*q`C)PUVgl{w|;P^(GDkgQuOb z>~7Ehb1R42`f5q51f!q%Fl{iTQg%=O-AbR@@lRQ9`UU-rmyDyiJ^g329$|g3_?5gy z|AqChNe9ge)6bgjE&+2UZ~(XBqFg`k$nWWYZ(%>JKVNqXUVg~vr#+aPh4{}rgdr0- zqW-s{4wQ)uLj&_eTfb3<)0(G#v}Tl>-{gLy|AWN?+{bIjxFMAz@}s%m>WX=S1vxSY zrIas=fOhcx!PkX*T3+CXcbI2b50~})e|uIJ_u-O(?#)K`xv90%S$)o~7~+OT>G$b$ z|5w8T!I4L@2lbTS&)jY8^8~wuX_8bI0;?h0xOZ(6mBr=NKx^jG#}AJ&@rxYqj%nm;5N%BeM5Yxj=q7bmq&Wv#lYcLmuY z>T4}F${m~D$@SO#Ze9Q9Y<+fN!vwcubTexgt!w`L*xf;M^_5u_9}Z^bxFfcX47ZDl zzOL(v^dFqi)NBfiUwOoAJ%=VXcPB(AHkggQo_352%i0!jXO<4O_2j;ZZDp64>Mrh@ znWaQkEjWBvf2;rTY%A6Ch3wYrm_b8&+${j0dM8XMk| zT?soJX_vN6knS3!b^ScIq*GbM(%CPfyG8TAJl+1jOE$DU zBV{L)&23HBl1B3evlW(e8+(^e0@x1uM!iV8s&i4Z|IiQM{l0N8xp|Fqx;gdlR(%#* zI}Ca@tF?hB%`fn_1Zcb3#$ZhOb#bEM_xm~}~>D=DY4cyz(GpF9{ z<=)jeaAZmww=J=n+cvO<*(I?bQEb%z4@v;ARE?t?4xQY_1Jt2`=N9aWA`!1(Bao#k?pUKjUCv-FCAMM zPe0o^jQz|3kfAGG(9d_9XCiyhzhgvwqko-vg-q`nR>y5ltfBIHJ8Y_32Uc@CWUGar z(0NMyJuF)-?E~=4JHC;IwB(8Kyq)RbEd#2`mRrOvYn@-~xMlJ5KO>qL`x!&8ML)bp z)?)L_ePbKRhTp>QFK=5=HrJAFyVi_5hdt+Z$cDK!v8vfUdB(1c?c8Wr-==@_%sal3 z1{*1Pu-}?ZUHu)KI=IopKO9;TPk$xR!`KP^=#%6wFFVLsl6fY2{m7(OOwX*4u7Umy zz00|6;^X!qHI1J;hu4YFEggb=nLGzHz8UD5cYF1XdXU!IKy}z8`#&~iaDsbj>wGpY z#L0hU(FFa>0j@?rZS#wHCbEw`m;DIz-};`V-KIVj+!l>P+XvUO@rro@G#-4dnPVJ2 ztomZ_2YBWk-$+AR#yIkV16<$)H{%}rem6irZIoo5i5>c==9;D_yOpvw-`u~F#;O{| zOQT)m7<&lNdrW$Wx#@A~9e`)v`TYy_e#k>RfCF5}(Hh~V4Q_yb+6MY*tBPLFAD`C2 z_8``FDHY}YGm$!yqb4>BMoUI?NHC{5DxnCrasTa z+Te%7*Uf+E|HV9$^4Zs5FAF}wFZv+;kv%5nK+pxRNz2?5{m$9|;F))PBMoWELtb!z zE7k_;2RDm;*#ZBLHaIo!Rq6Gf8fVIwtfD*M8!|xuWUnzodskb7y}O`~&2`>iG(h9m z0DI;g>&=tm18K=aUT|0&(3jN@7@x!RLxXsl(*En^hyD198hif-`cG?ri9IIT7@ddA z?ivxwB#W#Z2&HCnm*OuTzLG2251pL z)3x*``X|K_bme|i(j=(?oF?%zn+-h(c}aA*sngjVyNcJBW!KY z`krUr@r^Xd5_#y);6SH>6Ws4F?r*vWTQK%)Xb?>)8NdA4>-A@uat{XUp?^|?M^yG8 zcV^jOo3}FtF)ks)%vq3Y>K z73F2mll^!24*k2vw{m?ox1~(VhK49D&;)Jp`ASzdT@%QsBQ_b%7`IgD%cfj80#oceZZ}%=RxVU?s?24*~d=kFgKFxit zZ+U_R6?Tnl?k3fLG)6NxzzJ^3 zpsZ+_lno8gk`mgL%r5Ha>wrGZDPT@PTRbaxLAJ9**=qK6C>H78;rgWXnY`ct7dWH1 zDTA^old@AwyRz8j>%f>szsLT793}`TgZ=Irg8F%~1!JGQKUk}^{r=|@f)DWrXje4& zkDjH1p8=kE$2ZcDmOSK*;s6&o69kk&S(HiHso}elC%LGDuLtr+9|AYJjPbCLpoD<+ z9eSd=ptb;BVylHdfM?$EjWnbs4|%}>E^vaIGBOD~-IRZ$7dQaMXK-T+XP$?@1Le}k zX!HDn!h$CR@UwUnc;+47NJCokkQW@_0w=gB! zJqzR)`T(AJ$2ZcDmOSJIM_5jLIeMLDmoLND1)f0z{DU4}FX;2&-;;*4fX-D~@M~P!6D#r513~}i9t+mU=Jz3Y ze)Im#@-LFc5keYkzerd#G@p{KfVdr(D2Xj{JAJUL*C=3FrxZ> zVg9gQ{CDCJ{Gq+66LrfLmLGfxzSn*uJ{;^pdj8-i#Cyj45!G{s`NP^jo=1B1o4mrZ zgMHvGLC!FL*z^Bp-+Z&pvcKv1gZ-KJ*kDH{q9Qffdf7ttA zuL!?g_QySc&dax&_xPHPtdT1$Kg1DX^8(**xu3<$4*lYOLCkLhKC%D&x%$%QTc^lx zD&i*(kC+GXp1qYg{uB@nY_Qn{@%@Z4e=C>g4}E}oAUl`_EdJHY5c{sg@Y0{~Kk@SO z!Qw=F&%V>Br1Ha>9{VZwNct=NmNLR)+HZkR(CGCteF43ZASms5!=0E*_6F%s#M^rQ zFs|{Qz0oj#@@5ZSEtxAAtF=Zm?E`@iJ1so&eJ!3(w=1taf3Vlm&h)K!e=n=Raw1E1*6 zo>#Z4T!s0AE@i)k{p70QI^vsUd*BOt8-J!hpGoVl%;pyk&+rBD{8`wxgxfd1nawHp zjCsk;Xp}cLu7R`2y+L>NxqRw-^%cw5SNFPiX0*L2c;)vUkg4S4O0R#_E6gAEbl?yB zRMo@$!M}nv82&$;7csML7CRT=$Qx}G3*E=PFTaOz&p+&Tjef~|8_vl`0zZe3*Nu^W z8tayJC>G<9_a_SD=ecR2;B>A?A7l^A%hj#!gPuRgI{abYQe03YO#gui&14(vEdQ=9 zlApY8cD-zFPJ_G6=a0D~>$5!*UJ;-A$=^aT5$bdJkf4`7kv|2zn%W?Dj7MSI;pg7+ zgHj(Hr}9(N2bDa{u6X`1w*QhpHGkVW9a8O4ezmdorABxtXPY#<~#GY{Du7) z0QmJ2^Z)L`J{EVu__lLIy%>L1>#U5Eif=%+K9K)BJ`{=N?}&ZRpTm3~?o&)jE$wp; zq7SN1;ztnQ2ch3XS}-X&{xEl`8E)5o@?FFS`l$RXm$rILKIpkDo(8`x&eOmqgx@qi zfW#IM>jA(c#y5O<&{G4-W^@Oo>%ZJSL%uKaB~dKD`Q>Zfi;oGuT$J0rWbogeiU)rR z)4;RF!Lu3%%ZWbZ9bM)7Us~}fW&DwU9e!%WfDkjWpxJ|Nq2lfE-?XzkAC$ERX46we#~J30=I5pVq7 zw;%h`f=6Ng__^~h9ppKH(P`gV2+e8UESAJU1LU5!6|wNEm$SpnhfWPVGBr?hjknk6LR zoyNf~;t_fZSxO5YdEOwSlmUP6c`hl4+2(1tee!)LZsDL{x#Dh?w0z9uWB14xOs@A_fLMMR}`xR4|*8x5@cC zarR!0x|R(7D{Ch62T6`cs=^IjUKW{SzC?>51d;e4+P3e^!Z?Z}McMbDlZi_;0i(=Y#40%p5B4ypg z=kL|Nal{XH=ZHFPzv7$hj4An~;~R}1_x^EB+*X~Bh0i|w8uSz9jHfhL#E+fzJ^uHc zvBh`Nah?|Qf|Jp6pO_yIAIN!Gt2#X)9x6_#TS>)xRCNb*Ru}Ut;@Q57#{0n|FF#TK z;KGt1Ko5ocn0}_{fyu4gZifA3d;_Cll(c+`<^$`8a`y}sDo-}=EKC= z?h${`$-Bj)In4`L3@tH;oCj#U5l?(9B6Az&#_wz0#Tez|5yN-hv&P4#o%HzlM`Avb z@(4b#SIhZdK3373DS5zBLxA>M44#&zb)A1qB&f9t2Z_j6|@6O7gS$2W?^ zB`F@3n70p?4YKc~0kJ$ql2(L zV59LmT8~$~;$;WkB7^zS`<_4OUh2Tyc(wXJb2jEB>${h>*tN(Rca2mZ#S@A*>@RQC zxp|!57m4eWZW2FOlTyz;k~_w^81P%~`A$0cNv#uf@Znfqm%xj73W(;57qpap1b)xXR z>0jc$h;u?0b8a4TU_22IEZ$VQh;@etbd$xNMtMhi@{u1r;PX6Ud}FS}7-@4P(E&ZI zWv;@X8sbTD0rMdE!x)wl{S)7}lC`}@&M0gx9i(#?HFsma#(2y8mpR@>wd*e9gW6r= z5OvyVys2Y4ig^({K=(2(vED+DdEhti`5uXFt#A2=s{~I{9w|mt;}_*pK6F42XFQ~U zKeYYz@CSX4UZ!uM=abmpk@=%j;Lj@-Tgsf4xO(Qo%=ehTSiGHd(zYQH-q0uMKQ^Z} zzKAD^1GIQ5$suEU4D_4#e1})YC+UCkgXc1js#rOcN4b;_9niB>b^!KhuQ30qsXDQy zzFz*&AJIL@+TIV!HW-P?Z>=^fVe3lff5Y8;d8F zK0~J&$Sz{B#rlpukMQYooOFyw!f$cLDlgX0L#=#_e6YQ;99dutWd1j5BRCc2MO5-!S75#y( zp^o$;Z-3@IA@+cX`HaM+D;}KqbbjkS-?3AZo_xk5;Q=3bnIqAEZEhr)MRrYwIEzJN z*|&;$Oe6gq<_~%v{>09aVNTCkCGcpiXz}sw=mB&xb3(KKm_BY|`Xkb(JZ~cV7x04p z3yXW#`js^-VEc-CZ|ekGKXi@p2t4Q`#x-;iE!El3-$>+w`<%wld!TbfQ*+uAu!(i!Mj^a!!##QB@dC_j8)|BE%2 z-&3`9nSS%0@4g)JksmzZi|C?8aWbScGooV|;{`FZ@$y4Gs86(CT<`eq`D6MAe4O*` z*B7TnH|s&xKlFD$-(d}gJ}|wbwq?E-=~w9U$QciwH^>Qm!KT69Ao1ambvk#}`>fA( zhJw;v=8-=KqK)ANe?*2NdWiC^k7+)Ho=%QG)FZ^7>zzL{{|S#@)pUOQSDrun+4t1? z8`?Q@hcVssGV^4{EY0J*?AW;@(jDkx`sHcK9{G?H)}5@$@$+Df{*l(~-1%*5b?g|? za>!?Eb>Tr5fj1^YDvxrRS3?K%>=;rz;s+Y%YfU{=w`zjxU4O9-fj`WD*nec5TeaFF z!9mZTC7nu}FFf`MXxaG~tcuA&q6s86$d{IrXy^U+??Y`%8z$_Asai^@-LiK2BS& zuX;)JY@HTAf38^g-e9`t&w%oo)VFl5g7t$z+Jow3ZO8f%eaSkLF@`xXW3!hX+e?;B z3%S8A#{LaFVULFWEjw32cYYhM^qq91=ZrS;dl>>R_-!mxc@aIWwb`I*CWoFk*zd>I ziJTt*{nSHstSBfVNUiR=QhxQWp`WpF67nux2^bq)2f6$k0Z6}@g ziOzEMyy3p*wN^3Nfqv={tq=90eylT7YCrV+!LEvJ3}3*<1h&7G`>tTL_!ArF*Yv6y zwf{+HpgRQkv-mXxeSk5Cc?>!h89?UHG4vzjjrhUYu7A+^`}lHl=Qn)fJLyPIKJtSH zeBkwc?2veLRyylPo#hbb&51d^WBc>a4gIQ1?Pz_d7xhbx{TcoM83cX|V~z2I0GVv4 z|66n1%MkZvUCWz1V@Cx(R)4`x`mV+|{12E*GG@^?Oeaeg=vVY1_Ki8~ByzsSbn`*@ za{F}q&3nFEUsHOMA?a%HfR8?lY@S;szJ%<|op^{}7h@3hq`uTU zC6|{WbP%$K3?>MWp&I(wtoCEU=`fEtv*OgeK6cI|dr-iqItSGIuX3geeGof6W0T2_ z&V4~nj5j*xKon$hkeAuzislR=u{&#Wb96P7e^TXfqU0B|; zTC7h&C-g!$^hfKFpu6u|)RQrZdZ*+f9qH*~_+`Ok^n4*fSwSs9GyPwclVKhaN4cs; zCDTct>bwv3qdxQfhBIaGPm!-UXS8r83;e)eMEHJj zm-67Zq3_t+FL4Hn_Pabk{QZ*j@CnJx(C8W7o;K)&-YDJBPd%s)^`d^%GqwEjJVI|} z6|m3FT(hvCjDU7{sd%nnx%_To^G0auS2n$y-}Wi1z zjM59;&`&+65A~vco;N9#A7wFFBR&1n_cL%Z--Q44HTFpAWXlwE)7drWJze4Z&`Md| z@~#!!@mbyN|DW(bRlbpIu-^erCR?2C2yZy! z6j|e}o)4D~mw!}WcW6pSx2A6`H@@z}h9`_S^vv177oY=rqI5wYbS4O(JItHZ_A6yi za={mL0NmOtJoAHw;;2VU?~4&_D5rF`gs9_WHT=!9PAhJM=mX7EO6?D9PFvV>gH2DAk> zd}J2cg&z7i?Z!A!QGiUL0~+eAgqHW*5%kZSEqGmi4vX|Z%eGX_8ytHvUvQpzt$Zv0 zik~xge)FF1q|^UAT1-Cjg9m(3yx^xC%A;J$hYsJDpwG)pxIg(i>GMsyJWhBIg!z%>RhVG=E z&kB$MfHBcO^PcadBR%=Z4<7I(2*6J{lt;Og4;|10UGaShx_^y}ay*3jM8C@-puf|G z(413nzkqt=5g`8wg8YJl0_s{=P$UHW<~`p@mmnY?`N0D|@PeOmD35X}|5oxv#V5Hu zkGR7p0QxcsJg;caFu%~3tP80h?M|Nnur+w_@AytS(vvUD5Ab@PP#)!a8p3qx^)0`` z^u+Tj%rE4gI#D;~uka0^U&Mp|Mmo<6^22w}k1O#68gAF?O1z?Ny}qJeo^RCE%Nup~ z_4n_6TJBz-Bqt}gGfzZ%vR6E>!oPhTQ*saIi+@hG;NS4e`1+;h_iwn`zmxtu2Y%uI_z>f#|sqPxqP_`#C9DnzbtoFNbPFPBeGZmTDI~Nqj{SBT$ zNcz|oa%X$2ytjUwyt|;U;&XdjOrhMrPI)tU?ZBF{V{%(r+S^Cg^sgp-9(S|jWKs)L zP<;6KTv}E(b30Zyo2q!2{*AoN!ZA(Fv&=Am8UKd)>c^gM`I5#DbaQ+;@BXop6;fN};_~{jaw{`Jc1`aj%_^FN z!npt4T?-|tueSRpqyPM3?T zL*)FjVY<#N@8cs4E0_@lxj)zM>1|7YGtJ-qk5gK?earQVbCPXbGxK@1vZg~p?(h8W z_YtskBpU5 zoqB~EcBpO=X8RlYxvhOQv*;CmuFyX^sJ=PNzHb;>L$W8fls(hi%YoUQss)yz- zA1;^Hj7ERMLY?*%ey*@T>IV6* z3f=a19K(qPK|-76#Jrwza8^gzGo__$d&dvcHs0@v4C?9MNmutxr^;sN^?xHrx*3osf?}>ffC4EFyxxY6-{V9>{?B0Jq z&ysis4e$*9IH!$^TuYrMAHkPF-@}>sfpR4BZP_)knf5!ePYJcF?!iX<lRXD8?PmVMLPNLFZVN$FQcHVp7ooAb%hwGz>`$n@V6 z&!ByHYx9?dUCRU8B>8yn5_vCioSa_RPY%p%uX4}6r}XoX54Xn1qeCmvf7habKm8_N zKBdhF;=gTj2bGO`yB2-d|M2Ji?_X9n^!I?zB2pgiUnX;kPXE1|SIU#0(@TbH-)?0^ zYX2{;3YK@{0%dDx9Z3!>C8-0;%P-UC=p5#JvGe*#`R7rgPaTs({I8}=QhaqC+AvAi z(~H;-=%>h@&=m8yirh?}Eg$cRmm<{v5`*iT>oFbNg?+ue_8rN=KDIYJK>d>`!~NtK z_TmdGN6A&Jt(@B*V;?R;{Woo@n1#fDIribiA+;sCL&+C(qKLLGk~*@!Tv|6)_u?Xk zzj1RhrTf-3hr(N#|KK>rHZ#vU)iAqic$x|As+z5nTbO_0>ycRVv!}l$x3Z#jd__e5 z^JW3|0ykIVD{cNi1G>p%B!38-#XVC~qA{c{rbph~zAaVv$!KD^xUQh^TZ zeg(RT^=1DmCW_C}YS3YxVH^n)(ogFbFm*K53M7IqPij0H$rk(j+FQw z6$EnjTlAkXD!U%}_-_o?{e1hl`f4}jpsyF8w^0ARk{Bk}Q>V(!EwiAv%$B&$Wf_P2 z1|6@A#`$QsBftNfX3B$oOEqq@zL%@&T8!OZUN;7I?07tvnL56kuwyAtSg$Uj)78;R z*sb&UVXOZi0NY0gS4bLSPRW5KB{R6D+I=VI^;UVh4Sk*Q?Q<(awf}EaH0$tnuC+y? z|2H!tkiAn|$%)uJo$*8HDv#j%*cZ`5`;Yx|Cpyg#52-YEJFNcS*|9)A zJ(UXiuc%yt&BH27c32ZR9MMV6EFK73JWpr5l^G>b@Oe-d!`{HqlwJ2TtN-_Q$IItu zH!JRx|5VtiTVZeSo!VNCMR&y*2B_Z7`AZ%E=P;f@Ci-6y&2BPe^`HC}`okELX55%- z5IHIIJyDJh&v{E_=}O{w#Kea|2X^H%_$NFA>KS&M!&d(v9a=5FxwKR53a;^2lP2i; zPkV{`KrYU-r^r`1yJWB=4XtfGg9Yfn-H!bJA6%tANy-q{N!oU_vEKvUm#`n_!2imA zlM8bssx$1^=CJ*YguP+Dwp-`%!}QxzmgjdaC$XJ8B_^PZ`h@A1q;HA#>1=QF5CZ5^+ zo;N2)2tYUwCjw3coCr7(a3bJDz=?np0Ve`Z1e^%`KShANT;!F7wy0#L6;?w&9n*as z{y9CHwR*fZ5%V^@r)pGQ6? zV?pGHlUsTXT*3F#rfPhhoJ{h1$*pD%sm=l8iDTQan6Pz~j3pIEQS<=3WIdw8oO5)KLw= zQ< zxtcsdc`@Xxw zj;vA6pUyFGhRC})G$%l7-Moy?wGETySI5?CK1?yehwC%fAC}3gg?c&B*8DoVY?S;O z`w+Q=zKOI$mGJ}0J*N=M`^A)LM6Hn%QkP}o)yh_I*|`q8^eSY7d8n6QlToi$J|py^QwxKzmo<@e=!g6aa|w$f zK5ockYDa9?_J+R&UT2tcI~5b=^ucC56wz6dht-yhF-^6e68HNYhIh_VaOCufKeb=}qy-WlkeMTV>7qY-~VjIT+a!va?V* z%hu}-Y`@#ePX0A9Latrx=qBa~+Ee6(Zb7ZRAyAZj@gb{JR&C@W2L2FE3y^bkBsM62 zF7~fyPUPRb_*_t@c1NRK#+oc_yr#d1jn_VCe(+%jcB^HMK%R8(v*gA)zg^R;$LEUU zLEV~-`Vkv3vtHx1rFSzo$`?4b>*i~=0VmB#CO*R(n)e}(%sqN-2Rg*Q*dA8j*k`N1 zw(l4A_5bx7e4Tw^e2exi<;u;&-BkB2XL_KfU$cd*HMjII*-~Z8YM< z=g0MejnC6sCwOh)hs)w~Ag5Vt6%m)!sEKOXdp0=z9etv}$sePpOcAFFXv`CwjHCEf~h}*7UCmoW7rrMqM^}n4cV&(^*cS=GhY1Qx-<3 z0n+PlHHO#uJ1^j~BILPWWuf{TXzN^9H7c*>74rQPhtv|+uu7LF||nR)29!>>gz<3lb0{Z%{Rw_`3cYY4HvoYq2sUzl+`=7-ZC!J22RGr)KY z{WmA$2IR{R*8N!E!}=T41swKx5uZ@_I#;RPmx=iI2Gq7n4l1K@7UtYiM(ER{e~P{= z)(ButsXN=}!M7eKJEwKX#|M6%Ab`TX&Y@+<7M~ofKkD~}FPL#$#w(c{&f45N$2U@6 z6?1!)i?V)<`Wik$?DGM9dBm0a0oR|2&CQ>IOLH{ZP7clMdI2BoU(9u;?`g}hD#F@; ztWU@ICF7XnR~(<)9saCADodPK#O4XU!)ECO;3{1QE{)KrCsCJl*g0m4PwtvA%0ptU z^(~MY#&a3hO&?iJ`4k6GQ;zi=SfifvjJ{*WWj;BPBG)&~%AZ@%7g=k@4~^>&=U1`7 z=K?rvj72e)$v8nCK4rg;5B4dp&sGhLPr&WkAK5D(AMEWBz=SoV81J&|TU1H-hehm;{(d~Rk$DKGTP^O?Gzvt|?PH*t<711IuH z$(bZZtOLy&xU@mY^`dUgMtdX{e`Ci+h5~>M*J+2x=hoJ_;1%ytZs^S|v*rB_Q!wVS zS_|j&q5-<*P&Z_}m%MIbp^ZFd*k(CZp-I}vaq;6%WQfD-{H0!{>+2sjb=DFpr(cN#RO literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/size_fdiag b/cursors/Oxygen_Blue/cursors/size_fdiag new file mode 100644 index 0000000000000000000000000000000000000000..ca91aed89a59db6af0ff7b5711d45f940de0204f GIT binary patch literal 32416 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 NB48q5BJesR@c&Gvp6>tv literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/size_ver b/cursors/Oxygen_Blue/cursors/size_ver new file mode 100644 index 0000000000000000000000000000000000000000..ce8bc8b3cc0e7f110323544b625ce9a9fb20b178 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/split_h b/cursors/Oxygen_Blue/cursors/split_h new file mode 100644 index 0000000000000000000000000000000000000000..18480987b49b56dc4ec29df8c60114624544a077 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/split_v b/cursors/Oxygen_Blue/cursors/split_v new file mode 100644 index 0000000000000000000000000000000000000000..cc9f078ea90209b8cc623caa1f87c18fc12fb103 GIT binary patch literal 32416 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 literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/text b/cursors/Oxygen_Blue/cursors/text new file mode 120000 index 00000000..18632c40 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/text @@ -0,0 +1 @@ +xterm \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/up_arrow b/cursors/Oxygen_Blue/cursors/up_arrow new file mode 100644 index 0000000000000000000000000000000000000000..0efc3e1caf3c3ec7a57169e05ed7e3c7a298e6f9 GIT binary patch literal 32416 zcmeHPd0bW17TyS&AUKODsR)9CC?KLjj^I3prexv(Zvk^^4q#@0M48hv7Tkz3_Z@{GQ%SsYX|?F`o;B-xN;>Q;Wi{oBga<&r2mG zhPZsyu!guBWMuxh5b$QElNr|ZNLq%5=i2KUj#J#_lg-x&8vbM_G zo!(XcvU83co*OS+8mQwqPbhf(kE9BolZb{blX25NYS54x;?Zx7dc7{ruIHl>>a_nQ1+wVCitVuzH-F zdooc@J^qj!nAS@shL`)<#YNS<#qui!R#Qt7g4B1}?LFnl>;dxb{-yHb+B8|*x4t9< zyL=N=T|J4iJ#Mjl;>xy1)TyLaPi$GZ%A}TV?7y_jY*$GoFW9nWt?Q_Fo7PZ^Q7G+BNhaC?+DVqn z?~<|&D9U-0nIm!j#Fxcy3g<~o#hfD*-t_yQd=zbaty=DCVE;zy<%gQ6_c6u{z&Ya2 zDPBqH4vH(W#Cmb=SGAmrYCa@LeVQ8KB55tk$>`?l@0H5yDXBB-kI{4Auv#j2Vz`oh z(;ko`a|UBBqNGjws&CkrnZNh>OQ8q`YF4875VFl_44_d%`&$~UEK!% zswx$AuLj|Ja+Wq2y{Upa1!4Yuns}dDJW@V6zD_UfDcV)(rHPWxYJ))y>)R#`akP^m&CUP-%yc~qzvZ{YIS^YqD_(hTO`i@z0c*XlMN61LXQ&kdw3$w zSGOUmuG)@!8$j-aO*MK`1J4hGPM;$7n-W9i^rDAlPinMmOAe78W5Q+UxE7K>IuyTK z!2g;gXP-=#^hj43AF6(?>8^(0{ySk)+3zYr{JlNY1nTsR4xZ4D-dc8yZ6SLm-7ov5 zbkaWWzRB%n_k`B)fqTitH4|m)xHkG73~sDGgpW!+stUPXHq~J7jb}y;3RE8v`z?vh z;7fPc_1rhPgZ9^t&v`(O&xw@Cp_~?(b?(sBj2`W5VsQr>sBieZ%|fs{O40+!#;UG(1RSeDblu^4yBiasf8z67>Dj zx^%gaGal<3De}T9u5l#Ev-2L5jmhCM8U3BQSH94vzn%5x9HvfPPn9_?RQ-o-piFJ+ zE;$be1N(>N)h*e2P3+B`bG7ZioR=lf%#4#|4+hF)_%qC(5~hBJ@39txE=bB$LW4Xd%-m%V%G*T_})rtWiP+N{=77L57(6bIpyC+1Be zg!6_wfjJ)gn~CkveH!1L9P6JR<@K+t_3wl0bYbuGybV?OzeGIw4x%0FKRMb~{~owr z3&On4me?1nL!xd_|L(ZXd9zi2fKbB8!oP$8EoN~R{>22WgtJ@tmoT8kEY8Ben1GdV zb_@R!2DF&PS@;(duoBL0;a|dl7PGkP;-7xae{uHtKYj8x#(#Nx?-HRD@gKY4I(;-} z^k3-5(=QKa{eMf~zjwlQwvq43*%Ir|wG_X;{_2ur{Ral9w{VTz0j^s!ud^ktL2xgL zYvFzna-it1Q@CC34ktzs2>#SImH}1EAFVG zl`I5G7Xpn?UGl9tsIz17o5J%(EAFXse=6eI#O)Xy!RgtK z`~4whY0NkMieohSCXpTMsbi+iyVJYKYg?zwYx%Qe$JlUL+}TBP2G)|dcg>S4SpT`S zVTzUebn^Df%9vlYUvZ2MLHou|2vffhpV_h1wWRQ+!-I^3E zn-iNrrvl`}yn%=T$db!>nUb3jV$-3x0QClN34@fzG2hr^&UO4C(TJ%%Y;Uh3DJ{Woj@Gft z`=)dha-jF7x09zPMhS7+pAoD1=NEG)f;-&Jh7UNEKf=c+FOKiPjQM;w&YFx(HglcE zsAwnjg)7t@a-#DRn`2X7_25f{!FZpK6qH^y>P4rO=K{Pw4zU&Qa^f`@b* z_VX*p$kKlGY#71Ezkp|O-bjCr@5GtsjYV~bHaRk&np$f5)%>ni<>^Un!PQ3FGdk*i zL|q{kLVT#-oVNvGzGLfK8Li!9Vb2D#!Z}sZZQUG$AotBSkF3| z_fGsd9|t}i@Jw>eogE*uhT(_*02z{e)ekj##P6(VcUc+V2==#|oL?~tV|N4K|IdsV9I7$9ZSBKgK?D9fST+ zOZ2g+h~LmQs3=C}_sm%Qcgj^ig0UQhy!^%THh$B$cn*DTUXR)`5it_x9*qmu)v%ZT z)_q=T2A&fEq3$^Q8mt-LsYCSFX%Fa2c13*Y?DjtDTw+u8L(z8f_Y%aMzOiGrymxRJ z)_&H=M@MqxUBoWXx0v14+YT4l`|t680Y|+msBtJa2GR_|cTsfRjP-EV#JbTw5+m;4 zug360pkYaG$!If;dBi)vokd9aHn=*?hgmO01R-YGT7?Xps6E|6#NadqG1{ zMi&TmhHF6_3#d2r^=SW`85>kjC!ZlpZOM~8^x^{_mrmzhh_u1b# zha*PaAfpWicKE>d6vfA*yqbu-9U%b_`l1}eOH+SBb#IuAE*YCdJ!%OVcs+cwV!U-+ z7Ow-J5y;EFNq^UjQKhXvq3SnGMvu(=ItaPDUJsv)PTqP?^(sE`$jkg@y^z?H#YBv# zL$pQgE3r3;&tT+j4B`Bb_p_X`nAk4b4X%m$Lv*|&F>^Kzdo6rmpDlbW z{Xt)FOjiGLM8y8s!p9yD$0G|LM?~z8Eqv_pa6Gc`aYV%a*uuvi562@5A4f#&k1c%c z@o+q{@Nq=M{@B9D9uLPO3m->B?2j#c?D23svhZ<4#QxaA#~u&IBMTo#MC^|(eC+XX zJhJd{M8y8s!p9yD$0G|LM?~z8Eqv_pa6BpwK0legG3=jO`#VMX35EMR7CtxLAH19K zA-BvAa{c|&j^2*=a6g*+(s#rDDe>`zv^O?}aqla}bhSxZR3+PgXT$!G7sdT(?n`rj zns%%#Cbo-wDRP_0O>AZGxzRW9>5aUMWg>s5tm8wj6!~Q2fHfTupx(R@HjIA<=a3vv z@)(_&+l=a!NFsNKHiUhw9yronT6n8ma8e5(pB0h4IKKwE6N`L|TQ#<)ta5+QM4i~j zs6*sQvCZU!kyA*{WpfC1h2KpfJWs9}c`eM(`^u{ALDOu>U_?$LZ4q%I$CZ7~2#<*i zuQMO*7VofG0*e*-J&;Ws$DYrK$~(sF?sB6yo(PkJnrI` QZ#CUQz(T-6;ARl`A8boDO8@`> literal 0 HcmV?d00001 diff --git a/cursors/Oxygen_Blue/cursors/v_double_arrow b/cursors/Oxygen_Blue/cursors/v_double_arrow new file mode 120000 index 00000000..fb54fee2 --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/v_double_arrow @@ -0,0 +1 @@ +size_ver \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/w-resize b/cursors/Oxygen_Blue/cursors/w-resize new file mode 120000 index 00000000..e0da659c --- /dev/null +++ b/cursors/Oxygen_Blue/cursors/w-resize @@ -0,0 +1 @@ +size_hor \ No newline at end of file diff --git a/cursors/Oxygen_Blue/cursors/wait b/cursors/Oxygen_Blue/cursors/wait new file mode 100644 index 0000000000000000000000000000000000000000..556453a4301535b6d01ee30b046b40be9455bf54 GIT binary patch literal 1034800 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