From 066aaaeb73a8bb908b1c0d8c45f110b2f799f7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Mon, 21 Mar 2016 20:35:05 +0100 Subject: [PATCH] Initial import of baghira 0.8 --- AUTHORS | 1 + COPYING | 280 ++ ChangeLog | 1 + INSTALL | 167 + Makefile.am | 31 + NEWS | 1 + README | 707 ++++ TODO | 1 + bab/Makefile.am | 22 + bab/Themes/Brushed | 15 + bab/Themes/Jaguar | 14 + bab/Themes/Makefile.am | 3 + bab/Themes/Milk | 15 + bab/Themes/Panther | 14 + bab/Themes/Tiger | 14 + bab/bab.desktop | 10 + bab/bab.h | 108 + bab/bab.lsm | 16 + bab/bab_iface.h | 41 + bab/main.cpp | 615 +++ bab/styleconfdialog.cpp | 63 + bab/styleconfdialog.h | 53 + colorscheme/AquaBlue.kcsrc | 26 + colorscheme/AquaGraphite.kcsrc | 26 + colorscheme/Makefile.am | 3 + config.h.in | 253 ++ config/Makefile.am | 21 + config/about.ui | 705 ++++ config/colordialog.cpp | 300 ++ config/colordialog.h | 90 + config/colorpicker.cpp | 81 + config/colorpicker.h | 39 + config/configdialog.ui | 3039 +++++++++++++++ config/generatePixmaps.sh | 13 + config/help.ui | 305 ++ config/kstyle_baghira_config.cpp | 1243 ++++++ config/kstyle_baghira_config.h | 163 + configure.files | 5 + configure.in.in | 6 + deco/Doxyfile | 247 ++ deco/Makefile.am | 28 + deco/baghira.desktop | 5 + deco/baghiraclient.cc | 2636 +++++++++++++ deco/baghiraclient.h | 445 +++ deco/config/Makefile.am | 23 + deco/config/aquariusbutton.cc | 162 + deco/config/aquariusbutton.h | 37 + deco/config/baghiraconfig.cc | 729 ++++ deco/config/baghiraconfig.cc.new | 730 ++++ deco/config/baghiraconfig.h | 145 + deco/config/baghiraconfig.h.new | 149 + deco/config/colorpicker.cc | 124 + deco/config/colorpicker.h | 44 + deco/config/configdialog.ui | 3088 +++++++++++++++ deco/config/configdialog.ui.new | 398 ++ deco/config/customdecosettings.ui | 586 +++ deco/config/generatePixmaps.sh | 10 + deco/generatePixmaps.sh | 28 + deco/masks.h | 81 + icons/Makefile.am | 1 + icons/cr128-app-baghira.png | Bin 0 -> 6532 bytes icons/cr128-app-baghira_blue.png | Bin 0 -> 8739 bytes icons/cr128-app-baghira_grey.png | Bin 0 -> 7737 bytes icons/cr128-app-baghira_white.png | Bin 0 -> 10444 bytes icons/cr128-app-baghira_yellow.png | Bin 0 -> 8826 bytes icons/cr16-app-baghira.png | Bin 0 -> 870 bytes icons/cr16-app-baghira_blue.png | Bin 0 -> 941 bytes icons/cr16-app-baghira_grey.png | Bin 0 -> 922 bytes icons/cr16-app-baghira_white.png | Bin 0 -> 965 bytes icons/cr16-app-baghira_yellow.png | Bin 0 -> 899 bytes icons/cr22-action-bab_itunes.png | Bin 0 -> 1439 bytes icons/cr22-action-bab_jaguar.png | Bin 0 -> 1438 bytes icons/cr22-action-bab_milk.png | Bin 0 -> 1410 bytes icons/cr22-action-bab_panther.png | Bin 0 -> 1325 bytes icons/cr22-action-bab_tiger.png | Bin 0 -> 1373 bytes icons/cr22-app-baghira.png | Bin 0 -> 1325 bytes icons/cr22-app-baghira_blue.png | Bin 0 -> 1438 bytes icons/cr22-app-baghira_grey.png | Bin 0 -> 1439 bytes icons/cr22-app-baghira_white.png | Bin 0 -> 1410 bytes icons/cr22-app-baghira_yellow.png | Bin 0 -> 1373 bytes icons/cr32-app-baghira.png | Bin 0 -> 2005 bytes icons/cr32-app-baghira_blue.png | Bin 0 -> 2333 bytes icons/cr32-app-baghira_grey.png | Bin 0 -> 2252 bytes icons/cr32-app-baghira_white.png | Bin 0 -> 2166 bytes icons/cr32-app-baghira_yellow.png | Bin 0 -> 2235 bytes icons/cr48-app-baghira.png | Bin 0 -> 3118 bytes icons/cr48-app-baghira_blue.png | Bin 0 -> 3867 bytes icons/cr48-app-baghira_grey.png | Bin 0 -> 3564 bytes icons/cr48-app-baghira_white.png | Bin 0 -> 3464 bytes icons/cr48-app-baghira_yellow.png | Bin 0 -> 3736 bytes icons/cr64-app-baghira.png | Bin 0 -> 4216 bytes icons/cr64-app-baghira_blue.png | Bin 0 -> 5498 bytes icons/cr64-app-baghira_grey.png | Bin 0 -> 4888 bytes icons/cr64-app-baghira_white.png | Bin 0 -> 4682 bytes icons/cr64-app-baghira_yellow.png | Bin 0 -> 5244 bytes icons/readme | 7 + icons/svgs.tar.bz2 | Bin 0 -> 1896 bytes imagebase/AboutBaghira | Bin 0 -> 9546 bytes imagebase/brush-me | Bin 0 -> 1476 bytes imagebase/brushed-gradient | Bin 0 -> 160112 bytes imagebase/brushed-tile | Bin 0 -> 40109 bytes imagebase/button-base | Bin 0 -> 3197 bytes imagebase/button-glow | Bin 0 -> 4193 bytes imagebase/button-jaguar | Bin 0 -> 3197 bytes imagebase/button-milk | Bin 0 -> 1044 bytes imagebase/button-shadow | Bin 0 -> 531 bytes imagebase/button_jaguar | Bin 0 -> 923 bytes imagebase/button_jaguar_down | Bin 0 -> 923 bytes imagebase/button_jaguar_menu | Bin 0 -> 1283 bytes imagebase/button_jaguar_menu_down | Bin 0 -> 1283 bytes imagebase/button_milk | Bin 0 -> 923 bytes imagebase/button_milk_down | Bin 0 -> 923 bytes imagebase/button_milk_menu | Bin 0 -> 1283 bytes imagebase/button_milk_menu_down | Bin 0 -> 1283 bytes imagebase/button_panther | Bin 0 -> 923 bytes imagebase/button_panther_menu | Bin 0 -> 1283 bytes imagebase/checkbox | Bin 0 -> 645 bytes imagebase/checkbox-milk | Bin 0 -> 285 bytes imagebase/checkboxdown | Bin 0 -> 762 bytes imagebase/checkboxdown-milk | Bin 0 -> 509 bytes imagebase/checkboxdown.bak2 | Bin 0 -> 764 bytes imagebase/combo | Bin 0 -> 3785 bytes imagebase/combo-jaguar | Bin 0 -> 3785 bytes imagebase/combo-milk | Bin 0 -> 927 bytes imagebase/combo-shadow | Bin 0 -> 469 bytes imagebase/deco_glossy | Bin 0 -> 1911 bytes imagebase/icon_above | Bin 0 -> 923 bytes imagebase/icon_behind | Bin 0 -> 923 bytes imagebase/icon_close | Bin 0 -> 923 bytes imagebase/icon_help | Bin 0 -> 923 bytes imagebase/icon_maximize | Bin 0 -> 923 bytes imagebase/icon_minimize | Bin 0 -> 923 bytes imagebase/icon_shade | Bin 0 -> 923 bytes imagebase/icon_sticky | Bin 0 -> 923 bytes imagebase/poof.png | Bin 0 -> 57693 bytes imagebase/preview | Bin 0 -> 1883 bytes imagebase/preview-menu | Bin 0 -> 2603 bytes imagebase/progress | Bin 0 -> 491 bytes imagebase/progress2 | Bin 0 -> 3748 bytes imagebase/radio | Bin 0 -> 1108 bytes imagebase/radio-milk | Bin 0 -> 666 bytes imagebase/radio_down | Bin 0 -> 1108 bytes imagebase/radio_down-milk | Bin 0 -> 691 bytes imagebase/rectbutton | Bin 0 -> 3393 bytes imagebase/roundFrame | Bin 0 -> 2554 bytes imagebase/sbIslider_mid | Bin 0 -> 1348 bytes imagebase/sb_subadd | Bin 0 -> 708 bytes imagebase/sb_subadd-milk | Bin 0 -> 207 bytes imagebase/sbgroove_btm | Bin 0 -> 388 bytes imagebase/sbgroove_btm-milk | Bin 0 -> 227 bytes imagebase/sbgroove_mid | Bin 0 -> 1188 bytes imagebase/sbgroove_mid-milk | Bin 0 -> 237 bytes imagebase/sbgroove_top | Bin 0 -> 388 bytes imagebase/sbgroove_top-milk | Bin 0 -> 238 bytes imagebase/sbslider_btm | Bin 0 -> 439 bytes imagebase/sbslider_btm-milk | Bin 0 -> 306 bytes imagebase/sbslider_btm_shd | Bin 0 -> 545 bytes imagebase/sbslider_mid | Bin 0 -> 1348 bytes imagebase/sbslider_mid-milk | Bin 0 -> 314 bytes imagebase/sbslider_top | Bin 0 -> 439 bytes imagebase/sbslider_top-milk | Bin 0 -> 322 bytes imagebase/sbslider_top_shd | Bin 0 -> 545 bytes imagebase/sliderarrow | Bin 0 -> 863 bytes imagebase/sliderarrow-milk | Bin 0 -> 656 bytes imagebase/tab | Bin 0 -> 9287 bytes imagebase/tab-jaguar | Bin 0 -> 9287 bytes imagebase/tab-milk | Bin 0 -> 1105 bytes kickermenu-3.3/Makefile.am | 20 + kickermenu-3.3/b_menuapplet.desktop | 9 + kickermenu-3.3/menuapplet.cpp | 623 +++ kickermenu-3.3/menuapplet.h | 135 + kickermenu/Makefile.am | 15 + kickermenu/configure.in.in | 2 + kickermenu/menuapplet.cpp | 704 ++++ kickermenu/menuapplet.h | 138 + sessionapplet/Makefile.am | 15 + sessionapplet/dmctl.cpp | 322 ++ sessionapplet/dmctl.h | 91 + sessionapplet/usermanager.cpp | 281 ++ sessionapplet/usermanager.desktop | 8 + sessionapplet/usermanager.h | 78 + sessionapplet/usermanager.lsm | 16 + sidebar/Makefile.am | 17 + sidebar/baghiralinkdrag.cpp | 1 + sidebar/baghiralinkdrag.h | 1 + sidebar/baghirasidebar.cpp | 68 + sidebar/baghirasidebar.desktop | 12 + sidebar/baghirasidebar.h | 50 + sidebar/baghirasidebar_add.desktop | 10 + sidebar/baghirasidebariface.h | 35 + sidebar/configure.in.in | 2 + sidebar/dndlistbox.cpp | 685 ++++ sidebar/dndlistbox.h | 126 + sidebar/eject.xbm | 9 + sidebar/linkconfig.ui | 187 + sidebar/linkview.cpp | 199 + sidebar/linkview.h | 46 + sidebar/listboxlink.cpp | 78 + sidebar/listboxlink.h | 64 + sidebar/lock.xbm | 9 + starter/Makefile.am | 18 + starter/Themes/Apple Aqua/bStarter.png | Bin 0 -> 1099 bytes starter/Themes/Apple Aqua/bStarter_down.png | Bin 0 -> 1633 bytes starter/Themes/Apple Aqua/bStarter_hover.png | Bin 0 -> 1558 bytes starter/Themes/Apple Graphite/bStarter.png | Bin 0 -> 1363 bytes .../Themes/Apple Graphite/bStarter_down.png | Bin 0 -> 1070 bytes .../Themes/Apple Graphite/bStarter_hover.png | Bin 0 -> 1564 bytes starter/Themes/Apple Panther/README | 1 + starter/Themes/Apple Panther/base.png | Bin 0 -> 1162 bytes starter/Themes/Apple Panther/down.png | Bin 0 -> 915 bytes starter/Themes/Apple Panther/hover.png | Bin 0 -> 896 bytes starter/Themes/kickerbg-b.png | Bin 0 -> 3285 bytes starter/Themes/kickerbg-g.png | Bin 0 -> 2961 bytes starter/baghiralinkdrag.cpp | 125 + starter/baghiralinkdrag.h | 24 + starter/config.ui | 575 +++ starter/cr22-action-bStarter.png | Bin 0 -> 1209 bytes starter/cr22-action-bStarter_down.png | Bin 0 -> 1409 bytes starter/cr22-action-bStarter_hover.png | Bin 0 -> 1410 bytes starter/help.ui | 123 + starter/linkconfig.ui | 184 + starter/menu.cpp | 2249 +++++++++++ starter/menu.h | 320 ++ starter/mykey.h | 73 + starter/po/Makefile.am | 1 + starter/po/de.po | 351 ++ starter/po/starter.pot | 299 ++ starter/starter.cpp | 483 +++ starter/starter.desktop | 7 + starter/starter.h | 72 + starter/starterconfig.ui | 872 +++++ starter/starterhelp.ui | 121 + starter/starteriface.h | 34 + starter/subdirs | 1 + style/Makefile.am | 16 + style/baghira.cpp | 3384 +++++++++++++++++ style/baghira.h | 627 +++ style/baghira.themerc | 6 + style/bitmaps.h | 21 + style/configure.in.in | 5 + style/eventfilter.cpp | 990 +++++ style/fracts.h | 74 + style/generatePixmaps.sh | 54 + style/optionHandler.cpp | 251 ++ style/polish.cpp | 878 +++++ style/utils.cpp | 1418 +++++++ subdirs | 11 + 247 files changed, 35937 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 bab/Makefile.am create mode 100644 bab/Themes/Brushed create mode 100644 bab/Themes/Jaguar create mode 100644 bab/Themes/Makefile.am create mode 100644 bab/Themes/Milk create mode 100644 bab/Themes/Panther create mode 100644 bab/Themes/Tiger create mode 100644 bab/bab.desktop create mode 100644 bab/bab.h create mode 100644 bab/bab.lsm create mode 100644 bab/bab_iface.h create mode 100644 bab/main.cpp create mode 100644 bab/styleconfdialog.cpp create mode 100644 bab/styleconfdialog.h create mode 100644 colorscheme/AquaBlue.kcsrc create mode 100644 colorscheme/AquaGraphite.kcsrc create mode 100644 colorscheme/Makefile.am create mode 100644 config.h.in create mode 100644 config/Makefile.am create mode 100644 config/about.ui create mode 100644 config/colordialog.cpp create mode 100644 config/colordialog.h create mode 100644 config/colorpicker.cpp create mode 100644 config/colorpicker.h create mode 100644 config/configdialog.ui create mode 100755 config/generatePixmaps.sh create mode 100644 config/help.ui create mode 100644 config/kstyle_baghira_config.cpp create mode 100644 config/kstyle_baghira_config.h create mode 100644 configure.files create mode 100644 configure.in.in create mode 100644 deco/Doxyfile create mode 100644 deco/Makefile.am create mode 100644 deco/baghira.desktop create mode 100644 deco/baghiraclient.cc create mode 100644 deco/baghiraclient.h create mode 100644 deco/config/Makefile.am create mode 100644 deco/config/aquariusbutton.cc create mode 100644 deco/config/aquariusbutton.h create mode 100644 deco/config/baghiraconfig.cc create mode 100644 deco/config/baghiraconfig.cc.new create mode 100644 deco/config/baghiraconfig.h create mode 100644 deco/config/baghiraconfig.h.new create mode 100644 deco/config/colorpicker.cc create mode 100644 deco/config/colorpicker.h create mode 100644 deco/config/configdialog.ui create mode 100644 deco/config/configdialog.ui.new create mode 100644 deco/config/customdecosettings.ui create mode 100755 deco/config/generatePixmaps.sh create mode 100755 deco/generatePixmaps.sh create mode 100644 deco/masks.h create mode 100644 icons/Makefile.am create mode 100644 icons/cr128-app-baghira.png create mode 100644 icons/cr128-app-baghira_blue.png create mode 100644 icons/cr128-app-baghira_grey.png create mode 100644 icons/cr128-app-baghira_white.png create mode 100644 icons/cr128-app-baghira_yellow.png create mode 100644 icons/cr16-app-baghira.png create mode 100644 icons/cr16-app-baghira_blue.png create mode 100644 icons/cr16-app-baghira_grey.png create mode 100644 icons/cr16-app-baghira_white.png create mode 100644 icons/cr16-app-baghira_yellow.png create mode 100644 icons/cr22-action-bab_itunes.png create mode 100644 icons/cr22-action-bab_jaguar.png create mode 100644 icons/cr22-action-bab_milk.png create mode 100644 icons/cr22-action-bab_panther.png create mode 100644 icons/cr22-action-bab_tiger.png create mode 100644 icons/cr22-app-baghira.png create mode 100644 icons/cr22-app-baghira_blue.png create mode 100644 icons/cr22-app-baghira_grey.png create mode 100644 icons/cr22-app-baghira_white.png create mode 100644 icons/cr22-app-baghira_yellow.png create mode 100644 icons/cr32-app-baghira.png create mode 100644 icons/cr32-app-baghira_blue.png create mode 100644 icons/cr32-app-baghira_grey.png create mode 100644 icons/cr32-app-baghira_white.png create mode 100644 icons/cr32-app-baghira_yellow.png create mode 100644 icons/cr48-app-baghira.png create mode 100644 icons/cr48-app-baghira_blue.png create mode 100644 icons/cr48-app-baghira_grey.png create mode 100644 icons/cr48-app-baghira_white.png create mode 100644 icons/cr48-app-baghira_yellow.png create mode 100644 icons/cr64-app-baghira.png create mode 100644 icons/cr64-app-baghira_blue.png create mode 100644 icons/cr64-app-baghira_grey.png create mode 100644 icons/cr64-app-baghira_white.png create mode 100644 icons/cr64-app-baghira_yellow.png create mode 100644 icons/readme create mode 100644 icons/svgs.tar.bz2 create mode 100644 imagebase/AboutBaghira create mode 100644 imagebase/brush-me create mode 100644 imagebase/brushed-gradient create mode 100644 imagebase/brushed-tile create mode 100644 imagebase/button-base create mode 100644 imagebase/button-glow create mode 100644 imagebase/button-jaguar create mode 100644 imagebase/button-milk create mode 100644 imagebase/button-shadow create mode 100644 imagebase/button_jaguar create mode 100644 imagebase/button_jaguar_down create mode 100644 imagebase/button_jaguar_menu create mode 100644 imagebase/button_jaguar_menu_down create mode 100644 imagebase/button_milk create mode 100644 imagebase/button_milk_down create mode 100644 imagebase/button_milk_menu create mode 100644 imagebase/button_milk_menu_down create mode 100644 imagebase/button_panther create mode 100644 imagebase/button_panther_menu create mode 100644 imagebase/checkbox create mode 100644 imagebase/checkbox-milk create mode 100644 imagebase/checkboxdown create mode 100644 imagebase/checkboxdown-milk create mode 100644 imagebase/checkboxdown.bak2 create mode 100644 imagebase/combo create mode 100644 imagebase/combo-jaguar create mode 100644 imagebase/combo-milk create mode 100644 imagebase/combo-shadow create mode 100644 imagebase/deco_glossy create mode 100644 imagebase/icon_above create mode 100644 imagebase/icon_behind create mode 100644 imagebase/icon_close create mode 100644 imagebase/icon_help create mode 100644 imagebase/icon_maximize create mode 100644 imagebase/icon_minimize create mode 100644 imagebase/icon_shade create mode 100644 imagebase/icon_sticky create mode 100644 imagebase/poof.png create mode 100644 imagebase/preview create mode 100644 imagebase/preview-menu create mode 100644 imagebase/progress create mode 100644 imagebase/progress2 create mode 100644 imagebase/radio create mode 100644 imagebase/radio-milk create mode 100644 imagebase/radio_down create mode 100644 imagebase/radio_down-milk create mode 100644 imagebase/rectbutton create mode 100644 imagebase/roundFrame create mode 100644 imagebase/sbIslider_mid create mode 100644 imagebase/sb_subadd create mode 100644 imagebase/sb_subadd-milk create mode 100644 imagebase/sbgroove_btm create mode 100644 imagebase/sbgroove_btm-milk create mode 100644 imagebase/sbgroove_mid create mode 100644 imagebase/sbgroove_mid-milk create mode 100644 imagebase/sbgroove_top create mode 100644 imagebase/sbgroove_top-milk create mode 100644 imagebase/sbslider_btm create mode 100644 imagebase/sbslider_btm-milk create mode 100644 imagebase/sbslider_btm_shd create mode 100644 imagebase/sbslider_mid create mode 100644 imagebase/sbslider_mid-milk create mode 100644 imagebase/sbslider_top create mode 100644 imagebase/sbslider_top-milk create mode 100644 imagebase/sbslider_top_shd create mode 100644 imagebase/sliderarrow create mode 100644 imagebase/sliderarrow-milk create mode 100644 imagebase/tab create mode 100644 imagebase/tab-jaguar create mode 100644 imagebase/tab-milk create mode 100644 kickermenu-3.3/Makefile.am create mode 100644 kickermenu-3.3/b_menuapplet.desktop create mode 100644 kickermenu-3.3/menuapplet.cpp create mode 100644 kickermenu-3.3/menuapplet.h create mode 100644 kickermenu/Makefile.am create mode 100644 kickermenu/configure.in.in create mode 100644 kickermenu/menuapplet.cpp create mode 100644 kickermenu/menuapplet.h create mode 100644 sessionapplet/Makefile.am create mode 100644 sessionapplet/dmctl.cpp create mode 100644 sessionapplet/dmctl.h create mode 100644 sessionapplet/usermanager.cpp create mode 100644 sessionapplet/usermanager.desktop create mode 100644 sessionapplet/usermanager.h create mode 100644 sessionapplet/usermanager.lsm create mode 100644 sidebar/Makefile.am create mode 120000 sidebar/baghiralinkdrag.cpp create mode 120000 sidebar/baghiralinkdrag.h create mode 100644 sidebar/baghirasidebar.cpp create mode 100644 sidebar/baghirasidebar.desktop create mode 100644 sidebar/baghirasidebar.h create mode 100644 sidebar/baghirasidebar_add.desktop create mode 100644 sidebar/baghirasidebariface.h create mode 100644 sidebar/configure.in.in create mode 100644 sidebar/dndlistbox.cpp create mode 100644 sidebar/dndlistbox.h create mode 100644 sidebar/eject.xbm create mode 100644 sidebar/linkconfig.ui create mode 100644 sidebar/linkview.cpp create mode 100644 sidebar/linkview.h create mode 100644 sidebar/listboxlink.cpp create mode 100644 sidebar/listboxlink.h create mode 100644 sidebar/lock.xbm create mode 100644 starter/Makefile.am create mode 100644 starter/Themes/Apple Aqua/bStarter.png create mode 100644 starter/Themes/Apple Aqua/bStarter_down.png create mode 100644 starter/Themes/Apple Aqua/bStarter_hover.png create mode 100644 starter/Themes/Apple Graphite/bStarter.png create mode 100644 starter/Themes/Apple Graphite/bStarter_down.png create mode 100644 starter/Themes/Apple Graphite/bStarter_hover.png create mode 100644 starter/Themes/Apple Panther/README create mode 100644 starter/Themes/Apple Panther/base.png create mode 100644 starter/Themes/Apple Panther/down.png create mode 100644 starter/Themes/Apple Panther/hover.png create mode 100644 starter/Themes/kickerbg-b.png create mode 100644 starter/Themes/kickerbg-g.png create mode 100644 starter/baghiralinkdrag.cpp create mode 100644 starter/baghiralinkdrag.h create mode 100644 starter/config.ui create mode 100644 starter/cr22-action-bStarter.png create mode 100644 starter/cr22-action-bStarter_down.png create mode 100644 starter/cr22-action-bStarter_hover.png create mode 100644 starter/help.ui create mode 100644 starter/linkconfig.ui create mode 100644 starter/menu.cpp create mode 100644 starter/menu.h create mode 100644 starter/mykey.h create mode 100644 starter/po/Makefile.am create mode 100644 starter/po/de.po create mode 100644 starter/po/starter.pot create mode 100644 starter/starter.cpp create mode 100644 starter/starter.desktop create mode 100644 starter/starter.h create mode 100644 starter/starterconfig.ui create mode 100644 starter/starterhelp.ui create mode 100644 starter/starteriface.h create mode 100644 starter/subdirs create mode 100644 style/Makefile.am create mode 100644 style/baghira.cpp create mode 100644 style/baghira.h create mode 100644 style/baghira.themerc create mode 100644 style/bitmaps.h create mode 100644 style/configure.in.in create mode 100644 style/eventfilter.cpp create mode 100644 style/fracts.h create mode 100755 style/generatePixmaps.sh create mode 100644 style/optionHandler.cpp create mode 100644 style/polish.cpp create mode 100644 style/utils.cpp create mode 100644 subdirs diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..df25431 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Thomas Lübking diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..187727f --- /dev/null +++ b/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..df70813 --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +see readme \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..02a4a07 --- /dev/null +++ b/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3569e38 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,31 @@ + +if HAVE_3_4 +KICKERMENUDIR=kickermenu +SIDEBARDIR=sidebar +else +KICKERMENUDIR=kickermenu-3.3 +SIDEBARDIR= +endif + +SUBDIRS = bab colorscheme config deco icons sessionapplet starter style $(KICKERMENUDIR) $(SIDEBARDIR) + +$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ; + +$(top_srcdir)/subdirs: + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs + +$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in + @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4 + +MAINTAINERCLEANFILES = configure.in acinclude.m4 configure.files + +package-messages: + $(MAKE) -f admin/Makefile.common package-messages + $(MAKE) -C po merge + +EXTRA_DIST = admin COPYING configure.in.in + +dist-hook: + cd $(top_distdir) && perl admin/am_edit -padmin + cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..389a971 --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +see README diff --git a/README b/README new file mode 100644 index 0000000..dbc57ec --- /dev/null +++ b/README @@ -0,0 +1,707 @@ +Baghira +======= +For all you Apple Junkies out there... (like me) ;-) +Bases upon mosfet-liquid0.9.6pre4... the last heir of mosfet. +Suggestions welcomed. + +Installation +----------------- +tar -xjf baghira.tar.bz2 +cd baghira/baghira +either try ./install.sh or +./configure --prefix=`kde-config --prefix` --disable-debug [--enable-final] +(!!!BEGINNERS: the direction of the accents is _important_ (top-left to bottom-right), the rectangular brackets mean "this is optional" - don't type them!!!) +make +and finally as root: +make install + +Changelog +---------------- +*** IF YOU HAVE A 64 BIT MACHINE, UPDATE TO QT 3.3.3 *** +will fix the horizontal slider problem, rotating pixmaps in general + +0.8 +---- +after a long time, this is a snapshot of the current cvs version and probably the last baghira for Qt3 ever. +there won't be Baghira for Qt4, don't ask. +- several bugfixes, minor changes, whatever. + +0.7a +---- +- [style] Reincluded workaround for kpdf < 3.4.3 +- [style] added Milk style +- [style] some code enhancements/cleanups +- [bab] removed "start QString name int deco" dcop interface (useless anyway) +- [bab] added "start QString name QString settings" dcop interface to allow starting a program with the rules set for another one (or a general rule like "Milk" ;) +- [menubar applet] size fix (using an own settings value ;) + +0.7 +---- +Many? - see cvs log... +- New Konqueror Sidebar (Hardware access + Drag 'n Drop link list) +- New search oriented Application Launcher +- More speed and less bugs in the style and the deco +- New look on the brushed metal design +- New Tiger design +- New management to the menubar applet (in matters of size) +.... and much more i forgot over the time ;) + +0.6e +---- +Maintainance release (mainly) +- Fixed compile error on kde3.3 +- Made resize grip optionally (off by default, disable if you get querky problems with the deco) +- starter applet will auto correct size +- added new widget color "Smoke" by Anton + +0.6d +---- +========================== +BECAUSE OF COLOR PREFIXES: +If you think you've got an interesting colorset, that should be part of further releases, please drop me a mail. +----- +widget colors must include: +- a name ("my colorset") +- {R,G,B}, where R,G,B must be [0-255],[0-255],[0-255] +----- +deco colors must include: +- a name ("my colorset") +- {{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B},{R,G,B}} in order: +inactiveColor, closeColor, minColor, maxColor, menuColor, helpColor, stickyColor, aboveColor, behindColor, shadeColor +(10 values) +----- +inclusion depends on my arbitrariness ;) +============================== +* (style) update: slightly changed the appereance of the scrollbar sliders (on DementedPixel note) +* (style) update: appereance of groupboxes w/o title (improved the code resulting in more speed as well) +* (config) feature: added color presets for the widget colors +* (config) update: reorganized appereance a bit - NO changes on the config protocol though +* (deco) feature: added a resize handle drag - this will probaby be optional on future releases, but currently im interested in FEEDBACK +* (deco) update: corrected the button spacing (on DementedPixel note) +* (deco) feature: added color presets for the buttons +* (deco) feature: added option to remove captions as i saw some ppl interested on this. +however in general i do not suggest this, as apps often use the title to indicate states (like e.g. unsaved) +* (bab) bugfix: misbehaviour on dcop bab default start x command (start x y was ok) +* (starter) bugfix: compile error on non final compilations +* (menuapplet) bugfix: compile error because of gcc/kde_export misbehaviour (3.3 problem?) + baghira will compile a 3.3 or 3.4 version depending on the current running system + (binary packagers should note this) +* (menuapplet) update: improved Indicator title calculation +* (menuapplet) update: ported modal window handling (0.6b) to 3.4 version +* (icons) update: dfsw compliant license + +0.6c +---- +* (overall) feature: if you compile yourself, you may try the ./install.sh script, being a GUI wizzard leading you through the installation (especially if you're unexperienced - everyone else: this was just for some lazy hour and playing around with kdialog, i'd personally never click through dialogs instead of ./configure; make; make install ;) +* (overall) bugfix: included 0.6b fixes +* (style) feature: because i was in some kind of nostalgic mood, i added jaguar (liquidlike) buttons. also as jaguar used darker stipples if and only if you use the bab dcop starter or predefinitions, using jaguar will lead to darker stipples (+4 to your default) +* (style) note: this leads to new (consistent) settings: "0" is jaguar in style and deco, so calling +dcop bab default start kcalc 0 0 +will bring you a jaguar kcalc +dcop bab default start kcalc 1 2 +will instead bring you panther kcakc with a b/m deco +THIS HAS ALSO IMPACT ON THE PREDEFINITIONS! +You can either update them by hand or ONCE(!) call ./updatePredefs from the baghira topsrc dir +* (style) update: better handling for icons on buttons +* (style) update: improved editlines (thanks to Gav Wood for suggestion) +* (config) bugfix: writing valid value for visible toolbuttons +* (config) update: added option to replace kickers menu applet +* (deco) update: removed left/right side lines if not using comicframe (looked as if the deco was smaller than the window) +* (deco) update: corrected appereance of the left/right b/m resize handles +* (kickermenu) bugfix: kde3.4 support - i don't know if it will still work correctly with kde3.3 +* (starter) new: i was sucked by kickers startbutton displaying the tooltip on hover, so i wrote a kickerapplet as startmenubutton replacement. you can use any png as button. +name them bStarter.png, bStarter_hover.png, bStarter_down.png, and settle them in 22x22/action - defaults are included +as i don't have such nice access on the startmenu as the button has, its not possible to close the menu by clicking again _AFFTER_ you left the button once, also the default KDE binding to the startmenu (alt+f1, windows key) will display the menu in the screen center instead below the (nonexistent) button + +0.6b +---- +* (style) feature: animated pushbuttons +* (style) bugfix: konqueror crashes on repolishes +* (style) update: improved the look of (colored) iTunes (rectangular) buttons +* (configuration) feature: look predefinition for each application (deco needs kde 3.4b1 and up to work) +* (configuration) bugfix: skipped various unnecessary repolishes +* (bab) update: rewrote the way design switching stuff according to kde 3.4, removed all imperfect workaround stuff -> works much better, but needs kde 3.4 to work properly +* (kickermenu) update: using XClassHint to display the appname (better than relying on the netwm info) +* (kickermenu) update: using app menu instead of desktop menu for modal dialogs +* (kickermenu) note: kicker from kde 3.4 has a special menupanel that autoloads the kicker menuapplet to display the menu. you can remove this menu and readd the baghiramenu, but you'll have to do that after every kde start. -> open [kdeprefix - e.g. usr]/share/apps/kicker/applets/menuapplet.desktop, change "X-KDE-Library=menu_panelapplet" to "X-KDE-Library=b_menu_panelapplet" or (as root) run the following script (simply using sed to update the file): +--------------------start--------------- +#!/bin/sh +sed s/"X-KDE-Library=menu_panelapplet"/"X-KDE-Library=b_menu_panelapplet"/g $(kde-config --prefix)/share/apps/kicker/applets/menuapplet.desktop > _baghirabuffer_ +rm -f $(kde-config --prefix)/share/apps/kicker/applets/menuapplet.desktop +mv _baghirabuffer_ $(kde-config --prefix)/share/apps/kicker/applets/menuapplet.desktop +---------------------end---------------- + +0.6a +---- +* (style) serious bugfix: drawing groupbox frames on non groupboxes +* (style) bugfix: popup menu painting +* (style) bugfix: handles ksplash and kontact splash problem +* (configuration) bugfix: resetting settings +* (configuration) feature: save/restore settings to/from file +* (icons) update: copyright notice +* (general) bugfix: big endian (ppc/sparc) architecture support +* (general) bugfix: openBSD support (thanks to Damir Naden) + + +0.6 +--- +* stripped all fake translucency/shadows code, honoring the fact x.org 6.8 now supports true alpha handling +* fixed OOo error (stupid one, btw. - only had to see it :) +* tricked OOo to get background colored menubar/menus and keep nice button colors +* better support for OOo scrollbars (allways displayd as active, as OOo does not support the MousOver effect) +* better animation code - cpu hunger of some apps should be gone +* completely new settings handling to avoid conflicts of concurring file accesses - unfortunately you'll have to recreate all your settings :( + + +0.5f +---- +bugfix release only +bab started apps shouldn't hang +konqueror shouldn't crash, NOTICE: +the error occured, when updating the palette (applying a new background) to the toolbuttons (seems to be some very specific ones), +please don't ask me why this worked before - i don't know (but i think it's related to the redesign of the eventhandler which now responds much faster) +so the only solution i found was to disable the palette update for the toolbuttons, therefore you should display the inactive toolbuttons for b/m (e.g. by applying "brushed metal" or "both" in the last bab setting) + +0.5e +---- +style: +- fixed the "kde toolbar widget" thing (location bar/juk slider etc.) +- worked around brushed metal kicker translucency support +- changed the appereance of the kicker executor (like konqueror combobox) +- worked around konqueror statusbar offset +- flattened statusbars in genereal +bab: +- most important change: + bab supports a new dcop command to start applications with individual style settings, so + dcop bab babInterface start konqueror 1 2 + will open konqueror b/m + the first argument is the command you want to execute. + if you want to use switches, use "" to combine them, i.e. + dcop bab babInterface start "konqueror --profile webbrowsing --caption Safari" 1 2 + will start konqueror, b/m mode, show the about screen and renames the title to "Safari" + unfortunately the command may not contain a '"' or blanks, so if your app is named "kde application" you will not be able to pass it to bab, maybe i'll implement support for escape chars (\) if there's demand in the future. + the first digit addresses the style (so '0' means aqua, '1' means b/m) the second one the deco (predefined deco 0/1/2) + in addition there's a second command + dcop bab babInterface start xterm 0 + only differing by the fact it only changes the deco design. + USE THIS ONE FOR NONE KDE APPS (i.e. everything that doesn't get styled by baghira) as the other function won't be able to reset the settings for style and deco. + The good thing about this: + 1. You don't have to run complex scripts (maybe just check if dcop is running), bab does all for you + 2. bab does not reset the settings until the app read them - so you will get style and deco you wanted + The "bad" thing: + Though much better than the solution before, this is not process relative, i.e.: + - start an app with long startup time (e.g. juk) + - start another app with short startup time directly after starting juk + the startups will interfere (i.e. the fast app will change the settings and the slow app will get uncertain settings) +- just for cute... bab now "shapes" the upper corners of your screen (so any kickerbar there will be rounded as well:), but don't ask me about the perverse way i found to do so... ;) + +0.5d +---- +- completely remodeled the eventfilter -> faster! (reload the library) +- added some colored throbbers and an xcf so you can create your own colors +- sorting headers appear colored +- put the menuapplet into its own library, so it won't conflict with the kde one and is installed by default +- corrected kwin (stippled) frame to align the style +- corercted brushed toolbars (disalignment) + +0.5c +---- +Added a patched version of the kicker menu applet, main difference: +shows current window name left of the menu (you can also click this indicator to get a windowlist, as the menu takes space that's usually used for the taskbar) +*** THIS MENU APPLET WOULD REPLACE THE ORIGINAL ONE, THEREFORE IT'S NOT AUTOINSTALLED *** +to install it with baghira, edit the "subdirs" file and remove the "#" in front of "kickermenu" _before_ (!!!) ./configure + +*** KAnimWidget (Throbbers) now usefully support translucent pixmaps, so the throbber is now translucent (and i removed the ugly frame :) *** +anyway, i don't know since which version this holds, therefore maybe you want to keep the old throbber to prevent uncleaned repaints +(if someone wants to create the nice iTunes throbber - hey thanks, i don't have iTunes) + +Mainly kde3.3 alignments +- fixed juk toolbar stuff (and any other) +- fixed new kwin buttons +- toplevelmenubars are not set to stipples anymore, honoring the fact, that the kicker menuapplet recolors them itself to kicker background +- arrows will are dark grey rather than black - makes them appear more smooth + +- remodelled the include structure +- fixed repolishment errors +- fixed taskbar +- deco can be set to have a frame in maximized mode as well +- toolbuttons are not connected, if inactive toolbuttons are not shown + +0.5b +---- +Style: +- code improvements: should give some overall speed, closed a slight memory leak (lists of pointers in b/m mode) +- rewrote the groupbox code -> 1. faster, 2. aligned stipples +- combos on toolbars (konqueror :) look like the safari combo +- changed the appereance of inactive sliders (no bubbles) +- did anyone notice, i changed the stiopples again (figured out that apple uses bright-mid-dark-mid, while mosfet's stipple were dark-dark-bright-bright) + imho this leads to better readable text +- corrected alignment of left side tile in b/m mode +- handled amaroK in b/m mode + +Deco: +- added option to auto add spycing between buttons (making use of the kde spacing leads to unhappy effects, i the window misses a button (e.g. minimize in baghira help)) +- corrected alignment of left side tile in b/m mode + +Bab: +- fixed some saving issues + +Goodies: +The stuff in this folder is not autoinstalled. +Look into it and use whatever you want, however you want (except claiming cr and suing me for nonliterally copying ;) +- added new stuff: bootsplash, konqui tile, kdm picture, lilo-bootscreen +*** read the readme! *** + +0.5a +---- +- BUGFIX (style): konqueror address label +- BUGFIX (style): tab hovering for b/m +- WORKAROUND (style) kiconedit crashes on startup (notice that this error lies in kiconedit and the workaround will be removed as soon as kiconedit is fixed) +- (style) corrected size of the add/remove tab buttons (prevetning from overlaying the tabs) +- (deco): slightly modified coloring function (light dots on button top) + + +0.5 +--- +STYLE +===== +- well, light gradient, right ;) +- highlight color appears as gradient +- TOPLEVEL (mac like) MENUABRS (read this): + The light gradient causes (of course) some trouble on the top level menubars, as the gradient is arranged to the corresponding application window - not to kicker. + As there was interference with the stipples, when using e.g. toplevel brushed metal menus embedded into aqua style kicker, i decided to force toplevel menubars appearing in aqua mode (stippled) assuming you're using an aqua like kicker. this will cause problems if you're using b/m kicker. in this case, i suggest to avoid toplevel menus to get a consistent look (while using auqa mode kicker is preferred) + +DECO +==== +- new brushed style/removed flat brushed +- BUGFIX: bottombar draws void +- some graphical adjustments, corresponding to the brushed metal stuff +- buttons masked on brushed metal design + +ICONS +===== +- new license, read "readme.copyright" + + +0.4d +---- +- several bugfixes, notable: + 1. kicker children appear brushed metaled (if wished), thanks to A. Quincey + 2. that bookmark button thing... + please notice, that this could not really be fixed (the kbookmarkbar somehow accesses the toolbar iterator while i'm using it to check the toolbar layout - what confuses both of us) but i excluded the bookmarkbar by it's name (that could easily differ in other kde versions) and assume it's structure (bunch of combined buttons - no breaks / spacers) + 3. Corrected listviewheader hovering behaviour (wasn't that hard, after all...) +- highlights of this version (gee... what a shameless self promotion :) + 1. configurable deco button colors (added support for kde 3.3 buttons, well - hopefully, as i couldn't test yet) + 2. tabs hover on mouseover + 3. (round) iTunes like rectangular buttons + +0.4c +---- +- (hopefully) fixed compiler stuff - code cleanup: later +- redesigned the dialogs for the windeco 1024x768 compatible now (allmost 800x600 :) +- fixed the toolbutton stuff +- removed any listviewheader correction as this caused more problems that it could ever solve (if you worry about listviews, having too short headers and therefore paint void areas - complain to the appropriate author) + +0.4b +----- +code should be more iso-cpp compatible (especially the preprocessor stuff (#include/#define)) +it compiles nice on gcc-3.4.1, i have no idea about gcc-3.4.0 + +STYLE +===== +- (initial support) of conjuncted toolbuttons (use smooth tool for best effect) + restrictions: + o only works with kde toolbars (not on toolbars in plain qt applications, e.g. qt-designer) + o only works when the kde toolbar uses kde toolbarbuttons (rather than qt toolbuttons) - most kde applications do, well - some do not (you'll see) + +DECO +==== +- includes version that was meant for 0.4a (see changelog for this version) +- addidionally you can choose individual decos (_not_ buttons) for active and inactive windows + + +0.4a +----- +fixed the and cleant up the makefiles - maybe you've got some useless stuff (menuentries, icons) in your system due to old releases +call ./cleanMySystem / from the baghira topdir if you wish to delete them (if you're paraniod, you can use this script as help for deleting them by hand as well) +where is the prefix you gave when configuring baghira + +STYLE +===== +- fixed some graphical errors (toolbar stuff etc) +- it's now possible to tint the brushed metal style (autoapplied to the the deco as well) +- tricked back the konqueror statusbar (gee.., we don't like to be recolored, right?) +- found a (hopefully) better solution for the listviewheaders (setting only too small ones to be expanded) + +DECO +==== +- fixed (and improved :) frame painting +- new deco "glossy" using the aquarius coloring function + +CONFIG +====== +- added color picker for the aquarius function + *notice* this is only a _color picker_ + to not mess up with your color scheme arrangement, it will not touch the current color settings + +0.4 (finally :) +---------------- +YOU WILL NEED KDE 3.2 TO SUCCESSFULLY COMPILE THIS PACKAGE ! +Though i applied all kindly provided gcc-3.4 patches, i yet did not install this compiler, so i don't guarantee it will work, patched versions of gcc-3.3 (gcc-3.3-x) may also fail + +STYLE +===== +- new coloring function "Aquarius" - replacing the "icy" style. + as the two functions are incompatible on pixmap layer, there's no way back - sorry +- ended the stipple experiment +- fixed some stuff (missing pixel on tabs, tabclosebutton position, ... whatever (more stuff i forgot - test if your main issue is fixed and complain if not :P )) +- improved scrollbar animation code, fixed the juk problem as side effect. the deactivation is yet not functional (forgot to implement) expect for 0.4a +- improved the popuptranslucency for menubars - as a sideefeect, the dynamic offscreen buffer (to prevent artefacts) now works on toplevel menus (macstyle menus) + +DECO +==== +- now shipped with package :P +- better 3D effect for the title (dark/bright offset like Apple does, to provide distinction from any background) +- comic frame in titleblend color (right, resp. bottom color) +- complete change of big bottom bar - change to 6px thick bar to only provide shaped framing +- fixed several issues with the frame size (eg. width on maximized windows) + +BAB +=== +- bab now also provides dcop acces to the windeco style + +CONFIG DIALOG +============= +- completely new, though tested, some settings could have unexpected results (i couldn't really test everything), please notice if you find something (besides deactivation of scrollbar animation - see above) +- attaches to the style dialog +- the old dialog remains in system unless you remove it by hand (look for "kcm_kcmbaghira.la", "kcm_kcmbaghira.so" in $(PREFIX)/lib/kde3/ and "kcmbaghira.desktop" in $(PREFIX)/share/applnk/Settings/LookNFeel) +- test the about dialog =) +- click help +- more intuitive interface with a later release (setting dependend deactivation of widgets, etc.) + +COLORSCHEMES +============ +Christian Lehmann provided two new Colorschemes for the new function, AquaBlue and AquaGraphite - they're auto installed +as starting point, you could try rgb = 84,140,242 for the button - avoid very low or very high saturated color (result is uncolored/flat colored) + +ICONS +===== +Due to massive request (protest?) the icons for bab and the black and blue paw are installed to your system... NO COMPLAINTS ABOUT THAT, PLEASE... +The throbber is _not_ installed (sorry, but this would be much too invasive) - if you want it, copy it by hand + +SCRIPTS +======= +- added a script terminal to roughly show bab/dcop/windeco functionality (the script uses sleep - if it does not work on your system, use kstart similar to the other sripts and remove the sleep call) +- scripts are not installed, as they're just examples + +FINAL WORDS +=========== +haha...! i even had some letters left ;) + +----------------------------------------------------------------------------------- +=================================================================================== +----------------------------------------------------------------------------------- + +0.3s +- tweaked several graphics + o i was annoyed by the raised panels in knetscan, so i forced panels to appear sunken, similar to the editframes + o changed appereance of the toolbarhandlers (the old where too loud) + o fixed bug on splitters (well, somehow - obviously noone cares about the direction flag) + o fixed "bug" that lead to black frames under combos in some apps (e.g. amaroK) +- bugfixed the setting stuff (misdisplayd groupboxes, ability to unset shadows under popups...) +- Tab vs. Chooser is now optional + o the default setting is somewhat clever, i.e. if the toplevel widget is a dialog, tabs appear as choosers, as oldstyle tabs elsewise + -> result: apps like konqueror, kdevelop, quanta, konsole... will show tabs, dialogs will show choosers + o you can define the tab behaviour for aqua and brushed metal individually in the bab menu +- fixed menu animation stuff +- fixed bookmark menu behaviour (so could have told me...) +- fixed toolbutton repolishment +- "--enable-final" should work again +- bab: + o added a dropdownmenu (rightclick), currently mainly to allow you to set a default style (so you don't have to care about the setting when shutting down kde) +- lightweightened the stipples (more aqua like) and improved alignment (!you do not need to set the align stipples checkbox - it's useless!) +- new icons, created by timur ((c) 2004 TKdesign-studio.com. All rights reserved.) + +- ppc users: i added an endian definition to baghira.h - try to set it to big endian (but i don't know if it'll help) + +0.3r +- scrollbars: + o no useless sliders are drawn + o code should be faster now +- changed the tabbars to look like apples chooser widgets (button tabs) + this is a bit hackish, as qt doesn't know choosers + i don't knwow if i can easily make this optional, so i'll probably rely on reactions... +- went through the polishment code, uhmmm... that was really necessary +- option to brush me... + +0.3q +- new arrows on scrollbars + combos (thanks to Narcis Tesa for providing the pix) +- added option to fade in popup menus (works with translucency) +- Tabbar Bases will follow tabs colors :) + +0.3p +- redesigned groupboxes (twice as fast :) +- corrected wrongly shadowed widgets (flat groupboxes) +- redesigned scrollbars + +0.3o +- IMPROVED MEMORY MANAGEMENT - menus won't eat your memory anymore +- fixed bugs that may have caused crashes on some systems +- thanks to "mbllos" for some code optimization and a bugfix in the button coloring function +- slight changes to the toolbuttons (especially the round version) +- pressed sliders aren't animated, better slider hover behaviour at all, "hand" cursor on sliders +- included throbber for konqueror - copy to your icon folder (global is $KDEPREFIX/share/icons/default.kde) +- fixed nasty bug when trying to remove nonexistent popupmenushadows (crashed tear off menus) + + +0.3n +- fixed error that lead korganizer to crash (well, it's rather a workaround - as the KOAgenda class doesn't like foreign eventhandlers, i removed my - on cost of slider behaviour) +- fixed graphical error on some scrollbars +- fixed qtoolbutton error (some non stippled and miscolored buttonbackgrounds in toolbars) +- fixed error on some scrollviews (that didn't highlight the scrollers) +- fixed graphical problem with stipple unalignment on toolbars +- better support for toolbuttons besides toolbars (e.g. k3b) +- some further (minor) graphical improvements +- better menu-indicator/shadow related behaviour... yes, i said this wouldn't be possible, but it annoyed me too much, so i did it. (anyone here may thank RenderMan for this, he asked and this followed me so i really had to fix this :) + +0.3m +- speedUps, speedUps anywhere... ;-) + 1. by avoiding permanent repaint (update) of animated widgets (scrollers/progressbar)) - nice sideeffect: scrollers are back on wished behaviour again ;-) + 2. by avoiding useless searching the dictionaries (restructured popup code - allmost feared it'd never compile anymore...) and some calculations ;-) +- especially for jos added a new option for even smoother taskbar butoons ;-) +- fixed miinor error in kcmbaghira (you couldn't set opacity in gradient mode / stuck to custom opacity) +- removed annoying progress percent display + +0.3l +- modified dropshadow behaviour (menus < shadowoffset won't draw any shadow at the too small side) +- slightly changed sublying pixmap for scrollbar sliders +- new progressbar for "apple" style +- new progressbar behaviour ;-) (try apple or liquid - i'm sorry i denied this was possible... i'm just a little fool):\ +- also new Scrollbar bahaviour (side effect: if there are more scrollable areas in an app, all scrollers will be paint active if you enter one. +- slightly rounded the rect toolbuttons +- more apple like shadows - i hope to soon provide fast blurring AND I DO NOT LIKE THE MS STYLE!!! (yes, this means you, RenderMan! ;-) + (notice that 1. the current implementation is subefficient - i'll enhace that for next release; 2. this totally messed up my translucency code - so if you notice any artefacts, fractions or shifts: please drop me a mail ;-) +0.3k (serious bugfix release, recommanded over 0.3j) +- better support for groupboxes of kicker apps (e.g. button background) +- fixed error on small popupmenus (thanks to RenderMan for the hint!) +- (rough) support for bottom Tabs (cause konsole will use them in 3.2) +- included math.h - i still do not understand, why some compilers (gcc versions!!!) do not suppport exp and pow internal? %) +0.3j +- corrected slider geometrics (won't slide out of sliderarea, you can grip the whole slider) +- corrected highlighted menutext color when using custom menu colors +- set the very small pushbuttons to new gradient style +- set minimum tab height to 27 pixels (regarding to tabs on apples homepage) +- reordered dropshadow calling process +- changed behaviour of kicker headers (task buttons - to say it the ms way...:) - highlightning/coloring assumes them to be NOT button colored (rather background) +- corrected slider color on groupboxes also for my friends, who don't like stipples... ignoramuses ;-) +- added gradient translucency (but please don't expect this to be a speed wonder - the gradient has to be rendered for every menu (as they can be of different width) and then blended to the background completely (different from common translucency, where i can often take parts out of the buffer) +However: it's at least ghost free and not rendered twice - if you close and then reopen a submenu (e.g. from a menubar) +- added buffer to provide ghost free shadows (this leads to double buffering for translucency, well - gradients are and keep doublebuffered anyway) +- added free sizable menu drop shadows (w/o kde bug on shadows that run out of screen) / the shadows could need a gaussian blur (otherwise big shadows look too sharp) - we'll hopefullly see that next time... (for the moment, i suggest to use bright shadows (1 - not 0) to lower this effect) +- disaligned menuchecks should no be (vertically) aligned +- hopefully fixed a polishment bug about combos on toolbars (?!) +===================================================== +AND: IMPORTANT TO ANYONE!!! DEACTIVATE KDE DROPSHADOWS!!! +(as they'll produce artefacts in traslucent menus + + artefacts within themselves + + artefacts in my shadows + + unnecessary slow down menus) +===================================================== + +0.3i +- fixed drawing error on horizontal splitters +- added new sliderarrow (thanks to Narcis Tesa for the picture) +!!! NOTICE: The new Image is (allthough applelike) very big and vertical asymmetrical displayed - this can lead to inadequate look if i can't change its size - e.g. if it settles on a toolbar (open juk to see what i mean) the only way to handle this, is resetting the toolbarsize to at least 24 pixels. As e.g. only provides a maximum of 22 pixels, you have to edit its config file by hand: open ~/.kde/share/config/jukrc, look for the [MainWindow Toolbar playToolBar] section and set "IconSize=24". - sorry for this. +- slightly changed the tabbarbase on icy buttons (by user request and because it was necessary:) +- scroller activation now also works with kwrite and dependent apps (gideon, etc) +- improved support for custom menu colors (child menu triangles, checkmarks, splitters) +- improved (generalized) toolbar color handling (background seperators leaded to uncolored konqueror completition box - this shouldn't happen to any widget anymore) +============================================================================ +=== R E A D T H I S ! ! ! ============================================================= +============================================================================ +I stole the whole menudropshadow stuff from kstyle (thanks to the developers) to call them at the moment I (yes: ME:-) want! +PLEASE TEST THEM EXCESSIVLY and tell me, if you notice any ghosts from them by doing anything. thanks. +I WON'T MODIFY FOREIGN APPS SETTINGS! therefore you have to DEACTIVATE KDE MENU DROPSHADOWS yourself! - sorry for the inconvenience. +as they're active by default it's a good idea to deactivate menudropshadows in kde's style settings +( i know that they're still ghost effects in the shadow itself - i'll try to fix that soon ) +============================================================================ +- stole kstyle function for double buffered sliders and adjusted it for use with shadowed groupboxes (allows slider moving without artefacts) - you can read it. i'm a thief. i stole it - their precious - and THEY WANTS IT! ;-) + +0.3h (for massive (!) but unserious bugfix) +- added smooth toolbuttons option +- hacked around smudge error on automoving sliders (does NOT hold for sliders on groupboxes, if shadows activated) +- you now can choose between liquid, old and newstyle baghira progress bar (honestly i prefer the original baghira style, too - well, apple's not always perfect ;-) +... +HOLY SH**, i can't believe, nobody mentioned that before: did you never try to change to a custom menu style (color, unstippled translucency???) didn't you see there was something terribly wrong??? e.g.: IT JUST DIDN'T WORK? +- fixed that, so menu styling now behaves as it should. (hell on earth, i've to do everything myself - even kickin' my butt... ;-) +(head over to resexcellence and look at the milk screenshot, if you want to know why - black translucent menus look really cool (imho), allthough qt seems to have problems displaying bright text on a dark background) +- kde's menu dropshadows sometimes still mess up with my code (and theirs, too) the reason is that I (and they) have to sync qt with xfree before i can take a screenshot - the result is that the menushadow can appear during this time and then is also captured (if i don't capture it, it will leave a white ghost instead of a black one). +for the moment i have to suggest to deactivate menu dropshadows to get better translucency results - i'll try to write my own dropshadows for a future release. +- fixed minor unpolishment bug (accidently removed moustracking for all scrollviews - bad on combos, if not reactivated by new style..., well, i guess you didn't do that anyway ;)) +- slightly changed colortheme +- made the splitter more decent + +0.3g (dedicated to howard shores score of "the return of the king", which kept me awake tonight =) +- corrected position of new triangles on srollbars etc. a bit +- found (tricky) solution for Toolbar Separators (please consult README about this!!! - especially if toolbuttons seem to misbehave): +[well, seems you did :) +OK, the following Part is a bit tricky! +QT uses the Button Color to draw seperators on Toolbars. +Unfortunately we cannot change this directly, so we have to set the button color of Toolbar Widgets to the background color. +Unhappy Effect: Toolbuttons will lose the ability to highlight, as their Buttoncolor now changed to Background mode. (f***!) +Solution: We reset the the Buttoncolor of Toolbuttons to Buttoncolor right after that. +Unhappy Effect: Toolbuttons loose the ability to use redefined colors. +Solution: Check, if button uses backgroud for color: then reset it to button +Unhappy effect: An application cannot be redefine a Toolbutton color to background color. +(The alternative would be to exclude apps like korn, that are known to redefine toolbutton color, but i think, this is the MUCH better way!)] +- ...well now korn (and other apps) now also can have redefined toolbutton colors if you enable "draw toolbutton frames" (tststs..., sometimes i wonder if i can code anyway... :) +- added an option to remove bevel around kicker (user request) +- changed look of progressbar to fit apple's bevel rather than liquids +- added an option to user liquid's progressbar (user request, as an offer, on the new progress bar groove - tell me your opinion) + +0.3f +- menu translucency should now be PERFECT (i really like the word - howerver: never say never again... :) + this means: there won't be any ghostshadows anymore - no matter what you do. also no menu will be calculated twice if not nessecary (but don't forget: this is only pseudo translucency, this means, you won't capture background changes (animations aso.) as long as you don't close the menu) + Also menu dropshadows are supported +- scrollbars now change to active (with visual notification, what means they're colored) when you enter a scrollable area. (unfortunately currently doesn't work with some apps that don't inherit QScrollview - e.g. kwrite, so ill try to catch that) +- Kicker now draws (improved) smooth headers +- fixed rect buttons stucked to non stipple background (thanks to RenderMan for the notice) +- further minor graphical improvements... +- i hate the groupshadows... :) anyway, i found a rather simple solution to put a proper background to the buttons and sliders... (i could also apply this to the combos, but as they are almost rectangular, it wouldn't make much a difference. anyway: if someone is annoyed cause he runs a 320x240 ressolution, i'll improve that by request) +- removed any (virtual) support for kde menutranslucency, as it's really not a good idea to have both enabled at the same time... +- fixed an error to LVH triangles (thanks to Narcis Tesa for the hint) +- changed triangles on scrollbars and menus to fit listview expander look +- removed bevel around kicker for user request. i'll make that configurable with the next release. +- improved header hover behaviour after scrolling (on slight speed loss) - however it's still not perfect. (header hovering is a bit a hack and qt seems to have a problem with updating the header position...) +=========================================== ++++ you can download the new enchicked wallpaper from here: +http://stud.uni-karlsruhe.de/~uhvh/panther-jolene.png.bz2 + +0.3e +- added a slider to configure degree of saturation for icy buttons +- forcing rect buttons now also affects combos - for a more consistent look... +- menutranslucency improvement (1): + submenus won't be creatd multiple times, as long as lowest level menu is shown + this also holds (in most cases) for menubar-popups (e.g. when flying through your menus) +- menutranslucency improvement (2): + BE BANISHED TO WHERE THOU CAMEST FROM, HELLISH GHASTLY GRIM GHOSTSHADOWS ON POPUPMENUS !!! :) + (also improves menu buildup speed, as they are partially taken out of memory. btw, how's kde 3.2 state on this? - still nice ghosts?:) + (notice: the function isn't perfect, yet: menus are not overcaptured, therefore menushadows will still draw (slim white) artefacts. Also, you can trick it if you don't move left - right, but follow a bow above the menubar, as then the pixmapbuffer probably will be deleted - i'll try to fix this in the next release. for the moment, need you for beta-testing. so please tell me, if you find more drawing errors!) + +0.3d +- added more saturation to the icy buttons (icy buttons are now active by default - i think :) +- again brighter shadows for buttons and combos +- minor graphical changes (e.g. a toolbutton frame) +- option to force rectangular buttons (sorry 'eggnogg' - combos as buttons looked really crap, especially when buttons and combos appear at the same time) +- sunken button effect now wanted - therefore constant behaviour (they sometimes did funny things before) +- some codeimprovements... +- header + kicker (was there?) flicker resettled to nirvana +- solved renderman's problem with disaligned submenu triangles (with massive help of renderman, to state this) +- toolbuttons now also can have individual colors (affects e.g. korn) + +0.3c +- changed look of smooth LVH (hope RenderMan can live with that now...) ;-) +- no smooth LVH for kicker (looked crap because of the shadow) +- new Images for the buttons (but of same style) +- slightly reworked comboboxes (smoother shape, lighter shadow) +- set toolbuttons back to iTunes style - independent of the smooth LVH (thanks to Ercin Eker for the hint) +- added new widget coloring function (it's slower at app startup, but you'll need a profiler to notice that on a current computer) +- new button pressing effect (to be honest, this happened due an accident - originally i wanted to use the outline as an alternative hover but set a wrong if check..., however it now looks like glow effect - tell me your opinion) + +for multiple request: +============ +1. you can download binaries (NO WARRANTY they will work) from here: +http://stud.uni-karlsruhe.de/~uhvh/baghira-binary.tar.bz2 +2. you can download the enchicked version of the wallpaper from here: +http://stud.uni-karlsruhe.de/~uhvh/panther-padma.png.bz2 + +0.3b +- fixed menu translucency behaviour (veeeeeery stupid bug...) +- flattened the menu indicator + use of highlightened text (blame or thank RenderMan...) :) +- changed listheader indicator arrow +- stipples aligned by default - also, removed brute force alignment (leads to some very unhappy errors) - if you seea widget, that is disharmonic stippled: just drop me a mail! (groupboxes work... partially) - therefore "Align Stipples" option is (currently) useless... +- made and fixed a stupid bug tthat allmost costed my brain... ;-) (sometimes i'm really so stupid...) +- rectangular combos (e.g. html) are now rather combos - not complete highlighted buttons +- combos however are reworked and base upon their own pixmaps - not perfect at all... need better submittal?! +- you (RenderMan) can activate smoother ListViewHeaders - basing upon the new combos... +- fixed some minor bugs +================== += REQUEST !!! ========= +================== +Apple seems to use a nonlinear coloring process for buttons and stuff (e.g. light parts tend to be yellow). +Mosfet's linear coloring function results in quite flat Buttons. +If anyone can recommand good literature about coloring precesses - thanks ;-) +================================================================= +================================================================= + +0.3a +heyheyhey... consistent source (./configure;make;make install from topdir)... finally. YEAHHH BABY! +ok, now the important stuff: +- tabs now also follow inactive button style +- fixed a popupmenu bug (for aligned stipples) +- reworked the polishment process -> should be much faster now, also lost some errors (e.g. open juk with 0.3, did nobody see this??? ) +- added icons for the kcmdialog - just copy the iconfolders in "icons" to your icon-directory +- new "iTunes" styled rect buttons + +0.3 +- configdialog of course! +- new centerd tabs (thanks to shm for the patch) +- faster html (and other stuff?) scrolling +- fixed color error to the toolbar +- fixed major (but uncritical) bug to kicker (and child process) groupboxes +- other stuff i forgot... +================================================================================ +NOTES to configuration +---------------------------------- +- usually inactive buttons follow the background: therefore they can appear flat to very bright backgrounds (on black backgrounds on the other hand you won't see them anymore)... try to set them to "original" +- custom translucency doesn't work as it should (inverse behaviour, may overrun the defined area what leads to funny colors...) +- stipple alignement is only partially implemented - therefore it's not really slow (but won't work on groupboxes) +- centertabs should work on qt 3.1.2 and above. below this it's not tested (but may work anyway) +- "fasten the filebrowser" will lead to a stippled background (if you use stipples) and will remove the possibility to choose custom backgrounds +==================================================================================== + +0.2b +- Better Support for unstippled Background +- No more flicker ?! +- New Button behaviour (to hopefully get some feedback) +- more graphical stuff corrected (eg line near groupboxes) +- you now can configure the first items (kcm will follow soon, probably next few days) +to ~/.qt/qtrc add and modify: + +[Baghira] +drawDotlines=true +drawGroupBoxShadow=true +plusMinus=false +squeezeSbSlider=true +shadowSbSlider=false + +... not colors so far, as you would have to set hexdecimals... + +0.2a +- Fixed some graphical... insufficiencies (thanks, craigD) +- redid lines for listview so that Marcel can handle his massive email traffic again ;-) + (this will be choosable when the confdialog...) +- also triangles should look a bit cleaner now +- feedback for checkboxes and radiobuttons +- shadowed groups now won't fall to button color if you use the button color for menus +- about menu effects: fade in and animation happily works, as long as you don't use transparent menus + if you use transp menus, always the button color will be used for the effect. I *can* fix that - on a little speed loss. + However I do suggest to NOT use transparent menus with menu effects, as the menu will become more solid everytime you open it. + (Maybe I will support qt transparency for the unstippled menu in the future) + + + +0.2 +- new icons in listview (nice triangles instead of windows like '+' & '-', no lines) +- 3d effect for editlines +- removed shadows and annoying triangle from active button text +- changed scrollbar -> hover effect (sunken when pushed), more grippy + + +To the people who sign responsable for mosfet's parting: +------------------------------------------------------------------------------------ +After working on mosfet's code for some days now, i think i'm really competent to say this. +I do not know, what you did or said or just why - but hey: you stole us a really great coder... shame on you. + + +mailto:baghira-style@gmx.net diff --git a/TODO b/TODO new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ + diff --git a/bab/Makefile.am b/bab/Makefile.am new file mode 100644 index 0000000..bf7a71e --- /dev/null +++ b/bab/Makefile.am @@ -0,0 +1,22 @@ +## Makefile.am for bab + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# these are the headers for your project +noinst_HEADERS = bab.h bab_iface.h styleconfdialog.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kdedcoptest.pot + +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = bab + +# the application source, library search path, and link libraries +bab_SOURCES = main.cpp styleconfdialog.cpp bab_iface.skel +bab_LDFLAGS = $(KDE_RPATH) $(all_libraries) +bab_LDADD = $(LIB_KDEUI) diff --git a/bab/Themes/Brushed b/bab/Themes/Brushed new file mode 100644 index 0000000..0354f24 --- /dev/null +++ b/bab/Themes/Brushed @@ -0,0 +1,15 @@ +2 +2 +1 +2 +1 +1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +0 diff --git a/bab/Themes/Jaguar b/bab/Themes/Jaguar new file mode 100644 index 0000000..01bde8f --- /dev/null +++ b/bab/Themes/Jaguar @@ -0,0 +1,14 @@ +0 +0 +0 +0 +0 +1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/bab/Themes/Makefile.am b/bab/Themes/Makefile.am new file mode 100644 index 0000000..2ae716a --- /dev/null +++ b/bab/Themes/Makefile.am @@ -0,0 +1,3 @@ +lnkdir = $HOME/.baghira +lnk_DATA = Brushed Milk Jaguar Tiger Panther +EXTRA_DIST = $(lnk_DATA) diff --git a/bab/Themes/Milk b/bab/Themes/Milk new file mode 100644 index 0000000..83b9864 --- /dev/null +++ b/bab/Themes/Milk @@ -0,0 +1,15 @@ +4 +4 +4 +4 +1 +0 +-592138 +-4930834 +-1 +-16777216 +-13009982 +-1 +-16777216 +-1116417 +1 diff --git a/bab/Themes/Panther b/bab/Themes/Panther new file mode 100644 index 0000000..c313570 --- /dev/null +++ b/bab/Themes/Panther @@ -0,0 +1,14 @@ +1 +1 +1 +1 +1 +1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/bab/Themes/Tiger b/bab/Themes/Tiger new file mode 100644 index 0000000..825a5c1 --- /dev/null +++ b/bab/Themes/Tiger @@ -0,0 +1,14 @@ +3 +3 +1 +1 +1 +1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/bab/bab.desktop b/bab/bab.desktop new file mode 100644 index 0000000..534daa4 --- /dev/null +++ b/bab/bab.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=bab +Name[xx]=xxbabxx +Exec=bab %i %m -caption "%c" +Icon=baghira +Type=Application +DocPath= +Comment=Access to the big black cat +Terminal=0 diff --git a/bab/bab.h b/bab/bab.h new file mode 100644 index 0000000..cc28882 --- /dev/null +++ b/bab/bab.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2004 by Thomas Lübking * + * thomas@home * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BAB_H_ +#define _BAB_H_ + +#ifdef HAVE_CONFIG_H +#include +#endif +//#include +#include "bab_iface.h" +#include +#include +#include +#include +#include + +class bab; + +class BabSwitcher : public KSystemTray , public babInterface{ + Q_OBJECT +public: + + enum State {Jaguar = 0, Panther, iTunes, Tiger, Milk}; + + BabSwitcher(bab *parent=0, const char *name=0); + ~BabSwitcher(); + + void toggle(); + void setStyle(QString); + QString style(); + void setDeco(QString); + QString deco(); + void start(QString name, QString settings); + void emitStyleChanged(); + static QPoint *globalPos; + +protected: + void mousePressEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *ev); + +private: + + int state_; + int decoState_; + QPixmap JaguarIcon; + QPixmap PantherIcon; + QPixmap iTunesIcon; + QPixmap TigerIcon; + QPixmap MilkIcon; +}; + + +class QComboBox; +class QCheckBox; +/** + * @short Application Main Window + * @author Thomas Lübking + * @version 0.1 + */ +class bab : public KMainWindow +{ + Q_OBJECT +public: + + enum TabState {Tab = 0, Clever, Chooser}; + bab(); + void showEvent(QShowEvent *e); + QCheckBox *cornerCheck; + virtual ~bab(); +private: + BabSwitcher* bSwitcher; + QComboBox *DefStyle; + +private slots: + void saveSettings(); + void configureBaghira(); + +}; + +class Corner : public QWidget +{ + Q_OBJECT + public: + enum Side {left = 0, right}; + Corner(Side side); +public slots: + void toggle(bool); +}; + +#endif // _BAB_H_ diff --git a/bab/bab.lsm b/bab/bab.lsm new file mode 100644 index 0000000..842281c --- /dev/null +++ b/bab/bab.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: bab -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Thomas Lübking +Maintained-by: Thomas Lübking +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx bab-0.1.tar.gz + xxx bab-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/bab/bab_iface.h b/bab/bab_iface.h new file mode 100644 index 0000000..bf63d92 --- /dev/null +++ b/bab/bab_iface.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2004 by Thomas Lübking * + * thomas@home * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BAB_INTERFACE_H_ +#define _BAB_INTERFACE_H_ + +#include + +class babInterface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + + virtual void toggle() = 0; + virtual QString style() = 0; + virtual void setStyle(QString state) = 0; + virtual QString deco() = 0; + virtual void setDeco(QString state) = 0; + virtual void start(QString name, QString settings) = 0; + virtual void emitStyleChanged() = 0; + +}; + +#endif diff --git a/bab/main.cpp b/bab/main.cpp new file mode 100644 index 0000000..14b23d1 --- /dev/null +++ b/bab/main.cpp @@ -0,0 +1,615 @@ +/*************************************************************************** + * Copyright (C) 2004 by Thomas Lübking * + * thomas@home * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "bab.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#if KDE_IS_VERSION(3,4,0) +#include +#endif +#include +#include +#include + +#include "styleconfdialog.h" + +static const char description[] = + I18N_NOOP("Baghira Aqua/Brushed"); + +static const char version[] = "cvs"; + +static KCmdLineOptions options[] = +{ +// { "+[URL]", I18N_NOOP( "Document to open." ), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("bab", I18N_NOOP("BAB - Baghira Aqua/Brushed Switcher"), version, description, + KAboutData::License_GPL, "(C) 2004/2005 Thomas Lübking", 0, 0, "baghira-style@gmx.net"); + about.addAuthor( "Thomas Lübking", 0, "baghira-style@gmx.net" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + DCOPClient* client = app.dcopClient(); + client->registerAs( "bab", false); + client->setDefaultObject( "babInterface" ); + bab* mainBAB = 0; + mainBAB = new bab; + app.setMainWidget(mainBAB); + Corner leftCorner(Corner::left); + Corner rightCorner(Corner::right); +#if KDE_IS_VERSION(3,4,0) + KWin::setShadowSize(leftCorner.winId(), 0); + KWin::setShadowSize(rightCorner.winId(), 0); +#endif + if (!mainBAB->cornerCheck->isChecked()) + { + leftCorner.hide(); + rightCorner.hide(); + } + leftCorner.connect( mainBAB->cornerCheck, SIGNAL(toggled(bool)), SLOT(toggle(bool)) ); + rightCorner.connect( mainBAB->cornerCheck, SIGNAL(toggled(bool)), SLOT(toggle(bool)) ); + + int ret = app.exec(); + if (mainBAB) delete mainBAB; + return ret; +} + + +bab::bab() : KMainWindow(0,"bab",Qt::WStyle_StaysOnTop | Qt::WX11BypassWM ){ + bSwitcher = new BabSwitcher(this,"switcher"); + QToolTip::add(bSwitcher, i18n("leftclick toggles state
rightclick toggles setupmenu")); + bSwitcher->show(); + + QDir d( QDir::homeDirPath() + "/.baghira"); + if (!d.exists()) + d.mkdir(QDir::homeDirPath() + "/.baghira"); + d = QDir( QDir::homeDirPath() + "/.baghira/.bab"); + if (!d.exists()) + d.mkdir(QDir::homeDirPath() + "/.baghira/.bab"); + FILE *file = NULL; + QString tmpString = QDir::homeDirPath() + "/.baghira/Jaguar"; + if (!QFile::exists(tmpString)) + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"0\n0\n0\n0\n0\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n"); + fclose(file); + } + } + tmpString = QDir::homeDirPath() + "/.baghira/Panther"; + if (!QFile::exists(tmpString)) + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"1\n1\n1\n1\n1\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n"); + fclose(file); + } + } + tmpString = QDir::homeDirPath() + "/.baghira/Brushed"; + if (!QFile::exists(tmpString)) + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"2\n2\n1\n2\n1\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n0\n"); + fclose(file); + } + } + tmpString = QDir::homeDirPath() + "/.baghira/Tiger"; + if (!QFile::exists(tmpString)) + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"3\n3\n1\n1\n0\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n"); + fclose(file); + } + } + tmpString = QDir::homeDirPath() + "/.baghira/Milk"; + if (!QFile::exists(tmpString)) + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"4\n4\n4\n4\n1\n0\n-592138\n-4930834\n-1\n-16777216\n-13009982\n-1\n-16777216\n-1116417\n1\n"); + fclose(file); + } + } + + QVBox *vb = new QVBox(this); + vb->setLineWidth(2); + vb->setMargin(2); +// vb->setFrameStyle(QFrame::Panel | QFrame::Plain ); + + QLabel *DefStyleLabel = new QLabel("Default Style is", vb); + DefStyle = new QComboBox(vb); + DefStyle->insertItem ( "Jaguar" ); + DefStyle->insertItem ( "Panther" ); + DefStyle->insertItem ( "Brushed" ); + DefStyle->insertItem ( "Tiger" ); + DefStyle->insertItem ( "Milk" ); + cornerCheck = new QCheckBox("Round upper screen corners", vb); + QSettings config; + config.beginGroup("/baghira/BAB"); + DefStyle->setCurrentItem(config.readNumEntry("defaultState", BabSwitcher::Panther )); + cornerCheck->setChecked( config.readBoolEntry("roundCorners", true ) ); + config.endGroup(); + QPushButton *configBaghira = new QPushButton("Configure Baghira", vb); + QPushButton *Quit = new QPushButton("Quit BAB", vb); + QPushButton *Close = new QPushButton("Close Menu", vb); + vb->adjustSize(); + bSwitcher->setStyle(DefStyle->currentText()); + bSwitcher->setDeco(DefStyle->currentText()); + + connect(DefStyle, SIGNAL(activated(int)), this, SLOT(saveSettings())); + connect(cornerCheck, SIGNAL(toggled(bool)), this, SLOT(saveSettings())); + connect(configBaghira, SIGNAL(clicked()), this, SLOT(configureBaghira())); + connect(Close, SIGNAL(clicked()), this, SLOT(hide())); + connect(Quit, SIGNAL(clicked()), this, SLOT(close())); + + resize(vb->width(),vb->height()); + +// show(); +} + +bab::~ bab() +{ + bSwitcher->setStyle(DefStyle->currentText()); + bSwitcher->setDeco(DefStyle->currentText()); + if (bSwitcher) delete bSwitcher; +} + +/*Taken from kcontrol, kcmshell style*/ +void bab::configureBaghira() +{ + + + // Use KLibLoader to get the library, handling + // any errors that arise + KLibLoader* loader = KLibLoader::self(); + + KLibrary* library = loader->library( QFile::encodeName("kstyle_baghira_config") ); + if (!library) + { + qWarning("There was an error loading the configuration dialog for this style."); + return; + } + + void* allocPtr = library->symbol("allocate_kstyle_config"); + + if (!allocPtr) + { + qWarning("There was an error loading the configuration dialog for this style."); + return; + } + + //Create the container dialog + StyleConfigDialog* dial = new StyleConfigDialog(this, "Baghira Configuration"); + dial->enableButtonSeparator(true); + + typedef QWidget*(* factoryRoutine)( QWidget* parent ); + + //Get the factory, and make the widget. + factoryRoutine factory = (factoryRoutine)(allocPtr); + QWidget* styleConfig = factory( dial ); + + QTabWidget* tw = (QTabWidget*)styleConfig->child("tabWidget"); + + QWidget* decoConfig = 0; + QObject *decoObject = 0; + if (tw) + { + KLibrary* library2 = loader->library( QFile::encodeName("kwin_baghira_config") ); + if (!library2) + { + qWarning("There was an error loading the configuration dialog for the deco."); + return; + } + void* allocPtr2 = library2->symbol("allocate_config"); + if (!allocPtr2) + { + qWarning("There was an error loading the configuration dialog for this style."); + return; + } + typedef QObject*(* factoryRoutine2)( KConfig* conf, QWidget* parent ); + factoryRoutine2 factory2 = (factoryRoutine2)(allocPtr2); + decoObject = factory2( 0, tw ); + decoConfig = (QWidget*)tw->child("ConfigDialog"); + tw->addTab(decoConfig, "Decoration"); + } + + //Insert it in... + dial->setMainWidget( styleConfig ); + + QWidget *desktop = QApplication::desktop(); + QPoint nPos((desktop->width() - dial->width())/2, (desktop->height() - dial->height() - 100)/2); + dial->move(nPos); + //..and connect it to the wrapper + connect(styleConfig, SIGNAL(changed(bool)), dial, SLOT(setStyleDirty(bool))); + connect(decoObject, SIGNAL(changed()), dial, SLOT(setDecoDirty())); + connect(dial, SIGNAL(defaults()), styleConfig, SLOT(defaults())); + connect(dial, SIGNAL(save()), styleConfig, SLOT(save())); + connect(dial, SIGNAL(defaults()), decoObject, SLOT(defaults())); + connect(dial, SIGNAL(save(KConfig*)), decoObject, SLOT(save(KConfig*))); + + if (dial->exec() == QDialog::Accepted) + { + //For now, ask all KDE apps to recreate their styles to apply the setitngs + if (dial->isStyleDirty()) + { + KIPC::sendMessageAll(KIPC::StyleChanged); + KIPC::sendMessageAll(KIPC::ToolbarStyleChanged); + } + if (dial->isDecoDirty()) + kapp->dcopClient()->send("kwin", "KWinInterface", "reconfigure()", QByteArray()); + } + tw->removeChild( decoObject ); + dial->insertChild( decoObject ); + decoConfig->reparent(dial, QPoint(0,0)); + delete dial; +} + +/* overwrite the show event for repositioning the window on top + of the icon, adapted from kkeyled */ +void bab::showEvent(QShowEvent *e){ + if ( bSwitcher->globalPos->x() >= 0) { + QWidget *desktop = QApplication::desktop(); + int w = desktop->width(); + QPoint nPos; + if (bSwitcher->globalPos->y() - height() >= 0 ) + { // it's not on top + nPos.setY(bSwitcher->globalPos->y() -height()); + nPos.setX(bSwitcher->globalPos->x() - (width() / 2)); + } + else if ( bSwitcher->globalPos->y() >= 0 ) + { + nPos.setY(bSwitcher->globalPos->y() + bSwitcher->height() ); + nPos.setX(bSwitcher->globalPos->x() - (width() / 2)); + } + if ( nPos.x() < 0 ) + { + nPos.setX(bSwitcher->globalPos->x() + bSwitcher->width()); + } + else if ( bSwitcher->globalPos->x() + (width() / 2) > w ) + { + nPos.setX(bSwitcher->globalPos->x() - width()); + } + move(nPos); + } + + // If it was set by the normal sessionmanagement it needs + // to set the Flags again + setWFlags(Qt::WStyle_StaysOnTop | Qt::WX11BypassWM); + QWidget::showEvent(e); // execute the normal showevent + raise(); +} + +void bab::saveSettings(){ + QSettings *config = new QSettings(); +// KConfig *config = new KConfig("baghirarc"); + config->beginGroup("/baghira/BAB"); + config->writeEntry("defaultState", DefStyle->currentItem()); + config->writeEntry("roundCorners", cornerCheck->isChecked()); + config->endGroup(); + delete config; +} + +QPoint *BabSwitcher::globalPos = new QPoint::QPoint(0,0); + +BabSwitcher::BabSwitcher(bab *parent, const char *name) + : KSystemTray(parent,name), DCOPObject("babInterface") { + KIconLoader* iLoader = KGlobal::iconLoader(); + JaguarIcon = iLoader->loadIcon("bab_jaguar", KIcon::Small, 22); + PantherIcon = iLoader->loadIcon("bab_panther", KIcon::Small, 22); + iTunesIcon = iLoader->loadIcon("bab_itunes", KIcon::Small, 22); + TigerIcon = iLoader->loadIcon("bab_tiger", KIcon::Small, 22); + MilkIcon = iLoader->loadIcon("bab_milk", KIcon::Small, 22); + installEventFilter(this); +} + +BabSwitcher::~BabSwitcher(){ +} + +void BabSwitcher::toggle() +{ + if ( state_ < Milk ) + state_++; + else + state_ = Jaguar; + decoState_ = state_; + QString nameString; + switch (state_) + { + case Jaguar: + nameString = "Jaguar"; + break; + case Panther: + nameString = "Panther"; + break; + case iTunes: + nameString = "Brushed"; + break; + case Tiger: + nameString = "Tiger"; + break; + case Milk: + nameString = "Milk"; + } + QString tmpString = QDir::homeDirPath() + "/.baghira/" + nameString; + QString tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/.style"; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); + tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/.deco"; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); + repaint(); +} + +void BabSwitcher::setStyle(QString style) +{ + if (style == "Jaguar") + state_ = Jaguar; + else if (style == "Brushed") + state_ = iTunes; + else if (style == "Tiger") + state_ = Tiger; + else if (style == "Milk") + state_ = Milk; + else + { + if (style != "Panther") + style = "Panther"; + state_ = Panther; + } + QString tmpString = QDir::homeDirPath() + "/.baghira/" + style; + QString tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/.style"; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); + repaint(); +} + +void BabSwitcher::setDeco(QString deco) +{ + if (deco == "Jaguar") + decoState_ = Jaguar; + else if (deco == "Brushed") + decoState_ = iTunes; + else if (deco == "Tiger") + decoState_ = Tiger; + else if (deco == "Milk") + decoState_ = Milk; + else + { + if (deco != "Panther") + deco = "Panther"; + decoState_ = Panther; + } + QString tmpString = QDir::homeDirPath() + "/.baghira/" + deco; + QString tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/.deco"; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); +} + +QString BabSwitcher::style() +{ + switch (state_) + { + case Jaguar: + return "Jaguar"; + case Panther: + return "Panther"; + case iTunes: + return "Brushed"; + case Tiger: + return "Tiger"; + case Milk: + return "Milk"; + } +} + +QString BabSwitcher::deco() +{ + switch (decoState_) + { + case Jaguar: + return "Jaguar"; + case Panther: + return "Panther"; + case iTunes: + return "Brushed"; + case Tiger: + return "Tiger"; + case Milk: + return "Milk"; + } +} + +void BabSwitcher::start(QString name, QString settings) +{ + KProcess proc; + QString section; int i = 0; bool done = false; + if (name.contains(' ')) + { + while (!done) + { + section = name.section(' ',i,i); + if (i == 0) + { + QString tmpString = QDir::homeDirPath() + "/.baghira/" + settings; + QString tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/" + section; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); + } + if (!section.isEmpty()) + proc << section; + else + done = true; + i++; + } + } + else + { + QString tmpString = QDir::homeDirPath() + "/.baghira/" + settings; + QString tmpString2 = QDir::homeDirPath() + "/.baghira/.bab/" + name; + remove(tmpString2.latin1()); + symlink (tmpString.latin1(), tmpString2.latin1()); + proc << name; + } + proc.start(KProcess::DontCare); + proc.detach(); +} + +void BabSwitcher::emitStyleChanged() +{ + KIPC::sendMessageAll(KIPC::StyleChanged); + KIPC::sendMessageAll(KIPC::ToolbarStyleChanged); +} + +void BabSwitcher::mousePressEvent(QMouseEvent *e){ + + QWidget *daddy = parentWidget(); + + globalPos->setX(e->globalX() - e->x()); + globalPos->setY(e->globalY() - e->y()); + + switch ( e->button() ) + { + case LeftButton: + { + toggle(); + break; + } + case RightButton: + default: + { + if ( daddy->isVisible() ) + daddy->hide(); + else + daddy->show(); + } + } +} + +void BabSwitcher::paintEvent(QPaintEvent *ev){ + KSystemTray::paintEvent(ev); + QPainter icyApainter(this); + switch (state_) + { + case Jaguar: + JaguarIcon.isNull() ? icyApainter.fillRect(rect(), Qt::blue) : icyApainter.drawPixmap(0, 0, JaguarIcon); + break; + case Panther: + PantherIcon.isNull() ? icyApainter.fillRect(rect(), Qt::black) : icyApainter.drawPixmap(0, 0, PantherIcon); + break; + case iTunes: + iTunesIcon.isNull() ? icyApainter.fillRect(rect(), Qt::gray) : icyApainter.drawPixmap(0, 0, iTunesIcon); + break; + case Tiger: + TigerIcon.isNull() ? icyApainter.fillRect(rect(), Qt::yellow) : icyApainter.drawPixmap(0, 0, TigerIcon); + break; + case Milk: + MilkIcon.isNull() ? icyApainter.fillRect(rect(), Qt::white) : icyApainter.drawPixmap(0, 0, MilkIcon); + default: + break; + } + icyApainter.end(); +} + +Corner::Corner(Side side) : QWidget(0, (side == left)?"left_corner":"right_corner", Qt::WType_TopLevel | Qt::WStyle_NoBorder | Qt::WStyle_StaysOnTop | Qt::WX11BypassWM ) +{ + if (side == left) { + setFixedSize(5,4); + move(0,0); + show(); + setPaletteBackgroundColor(Qt::black); + XRectangle* xrects = new XRectangle[4]; + xrects[ 0 ].x = 0; + xrects[ 0 ].y = 0; + xrects[ 0 ].width = 5; + xrects[ 0 ].height = 1; + xrects[ 1 ].x = 0; + xrects[ 1 ].y = 1; + xrects[ 1 ].width = 3; + xrects[ 1 ].height = 1; + xrects[ 2 ].x = 0; + xrects[ 2 ].y = 2; + xrects[ 2 ].width = 2; + xrects[ 2 ].height = 1; + xrects[ 3 ].x = 0; + xrects[ 3 ].y = 3; + xrects[ 3 ].width = 1; + xrects[ 3 ].height = 2; + XShapeCombineRectangles( qt_xdisplay(), winId(), ShapeBounding, 0, 0, + xrects, 4, ShapeSet, 0 ); + delete[] xrects; + } + else { + setFixedSize(5,4); + move(QApplication::desktop()->width()-5,0); + show(); + setPaletteBackgroundColor(Qt::black); + XRectangle* xrects = new XRectangle[4]; + xrects[ 0 ].x = 0; + xrects[ 0 ].y = 0; + xrects[ 0 ].width = 5; + xrects[ 0 ].height = 1; + xrects[ 1 ].x = 2; + xrects[ 1 ].y = 1; + xrects[ 1 ].width = 3; + xrects[ 1 ].height = 1; + xrects[ 2 ].x = 3; + xrects[ 2 ].y = 2; + xrects[ 2 ].width = 2; + xrects[ 2 ].height = 1; + xrects[ 3 ].x = 4; + xrects[ 3 ].y = 3; + xrects[ 3 ].width = 1; + xrects[ 3 ].height = 2; + XShapeCombineRectangles( qt_xdisplay(), winId(), ShapeBounding, 0, 0, + xrects, 4, ShapeSet, 0 ); + delete[] xrects; + } +} + +void Corner::toggle(bool b) +{ + b?show():hide(); +} + +#include "bab.moc" diff --git a/bab/styleconfdialog.cpp b/bab/styleconfdialog.cpp new file mode 100644 index 0000000..245f5ab --- /dev/null +++ b/bab/styleconfdialog.cpp @@ -0,0 +1,63 @@ +/* + * KCMStyle's container dialog for custom style setup dialogs + * + * (c) 2003 Maksim Orlovich + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "styleconfdialog.h" +#include + +StyleConfigDialog::StyleConfigDialog(QWidget* parent, QString styleName): + KDialogBase(parent, "StyleConfigDialog", + true, /*modal*/ + styleName, + KDialogBase::Default | KDialogBase::Ok | KDialogBase::Cancel, + KDialogBase::Cancel) +{ + m_styleDirty = false; + m_decoDirty = false; + connect( this, SIGNAL( defaultClicked() ), this, SIGNAL( defaults() )); + connect( this, SIGNAL( okClicked() ), this, SIGNAL( save() )); + connect( this, SIGNAL( okClicked() ), this, SLOT( saveDeco() )); +} + +void StyleConfigDialog::saveDeco() +{ + emit save(0); +} + +bool StyleConfigDialog::isStyleDirty() const +{ + return m_styleDirty; +} + +void StyleConfigDialog::setStyleDirty(bool dirty) +{ + m_styleDirty = dirty; +} + +bool StyleConfigDialog::isDecoDirty() const +{ + return m_decoDirty; +} + +void StyleConfigDialog::setDecoDirty() +{ + m_decoDirty = TRUE; +} + +#include diff --git a/bab/styleconfdialog.h b/bab/styleconfdialog.h new file mode 100644 index 0000000..9a125d7 --- /dev/null +++ b/bab/styleconfdialog.h @@ -0,0 +1,53 @@ +/* + * KCMStyle's container dialog for custom style setup dialogs + * + * (c) 2003 Maksim Orlovich + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef STYLE_CONF_DIALOG +#define STYLE_CONF_DIALOG + +#include + +class KConfig; +class StyleConfigDialog: public KDialogBase +{ + Q_OBJECT +public: + StyleConfigDialog(QWidget* parent, QString styleName); + + bool isStyleDirty() const; + bool isDecoDirty() const; + +public slots: + void setStyleDirty(bool dirty); + void setDecoDirty(); + +private slots: + void saveDeco(); + +signals: + void defaults(); + void save(); + void save(KConfig*); + +private: + bool m_styleDirty; + bool m_decoDirty; +}; + +#endif diff --git a/colorscheme/AquaBlue.kcsrc b/colorscheme/AquaBlue.kcsrc new file mode 100644 index 0000000..63a6847 --- /dev/null +++ b/colorscheme/AquaBlue.kcsrc @@ -0,0 +1,26 @@ +[Color Scheme] +Name=Aqua Blue +activeBackground=255,255,255 +activeBlend=225,225,225 +activeForeground=0,0,0 +activeTitleBtnBg=80,132,185 +alternateBackground=238,246,255 +background=250,250,250 +buttonBackground=97,136,215 +buttonForeground=0,0,0 +contrast=0 +foreground=0,0,0 +frame=255,255,255 +handle=255,255,255 +inactiveBackground=225,225,225 +inactiveBlend=225,225,225 +inactiveForeground=35,35,35 +inactiveFrame=255,255,255 +inactiveHandle=255,255,255 +inactiveTitleBtnBg=218,238,255 +linkColor=0,0,192 +selectBackground=57,109,181 +selectForeground=255,255,255 +visitedLinkColor=128,0,128 +windowBackground=255,255,255 +windowForeground=0,0,0 diff --git a/colorscheme/AquaGraphite.kcsrc b/colorscheme/AquaGraphite.kcsrc new file mode 100644 index 0000000..a34ddbc --- /dev/null +++ b/colorscheme/AquaGraphite.kcsrc @@ -0,0 +1,26 @@ +[Color Scheme] +Name=Aqua Graphite +activeBackground=255,255,255 +activeBlend=225,225,225 +activeForeground=0,0,0 +activeTitleBtnBg=131,142,155 +alternateBackground=238,246,255 +background=255,255,255 +buttonBackground=137,145,155 +buttonForeground=0,0,0 +contrast=0 +foreground=0,0,0 +frame=255,255,255 +handle=255,255,255 +inactiveBackground=225,225,225 +inactiveBlend=225,225,225 +inactiveForeground=35,35,35 +inactiveFrame=255,255,255 +inactiveHandle=255,255,255 +inactiveTitleBtnBg=218,238,255 +linkColor=0,0,192 +selectBackground=104,121,140 +selectForeground=255,255,255 +visitedLinkColor=128,0,128 +windowBackground=255,255,255 +windowForeground=0,0,0 diff --git a/colorscheme/Makefile.am b/colorscheme/Makefile.am new file mode 100644 index 0000000..1949d7d --- /dev/null +++ b/colorscheme/Makefile.am @@ -0,0 +1,3 @@ +lnkdir = $(kde_datadir)/kdisplay/color-schemes +lnk_DATA = AquaBlue.kcsrc AquaGraphite.kcsrc +EXTRA_DIST = $(lnk_DATA) diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..490b9f3 --- /dev/null +++ b/config.h.in @@ -0,0 +1,253 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_CARBON_CARBON_H + +/* Define if you have the CoreAudio API */ +#undef HAVE_COREAUDIO + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRT_EXTERNS_H + +/* Defines if your system has the crypt function */ +#undef HAVE_CRYPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have libjpeg */ +#undef HAVE_LIBJPEG + +/* Define if you have libpng */ +#undef HAVE_LIBPNG + +/* Define if you have a working libpthread (will enable threaded code) */ +#undef HAVE_LIBPTHREAD + +/* Define if you have libz */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if your system needs _NSGetEnviron to set up the environment */ +#undef HAVE_NSGETENVIRON + +/* Define if you have res_init */ +#undef HAVE_RES_INIT + +/* Define if you have the res_init prototype */ +#undef HAVE_RES_INIT_PROTO + +/* Define if you have a STL implementation by SGI */ +#undef HAVE_SGI_STL + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have strlcat */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcat prototype */ +#undef HAVE_STRLCAT_PROTO + +/* Define if you have strlcpy */ +#undef HAVE_STRLCPY + +/* Define if you have the strlcpy prototype */ +#undef HAVE_STRLCPY_PROTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_XCOMPOSITE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_XDAMAGE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_XRENDER_H + +/* Suffix for lib directories */ +#undef KDELIBSUFF + +/* Define a safe value for MAXPATHLEN */ +#undef KDEMAXPATHLEN + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of a `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of a `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of a `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of a `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of a `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Defined if compiling without arts */ +#undef WITHOUT_ARTS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* + * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system + * headers and I'm too lazy to write a configure test as long as only + * unixware is related + */ +#ifdef _UNIXWARE +#define HAVE_BOOLEAN +#endif + + + +/* + * AIX defines FD_SET in terms of bzero, but fails to include + * that defines bzero. + */ + +#if defined(_AIX) +#include +#endif + + + +#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) +# include +# include +# define environ (*_NSGetEnviron()) +#endif + + + +#if !defined(HAVE_RES_INIT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +int res_init(void); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCAT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcat(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCPY_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcpy(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + + +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +#if !defined(HAVE_VSNPRINTF) || defined(hpux) +#if __STDC__ +#include +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" +#endif +int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); +#ifdef __cplusplus +extern "C" +#endif +int snprintf(char *str, size_t n, char const *fmt, ...); +#endif + + + +#if defined(__SVR4) && !defined(__svr4__) +#define __svr4__ 1 +#endif + + +/* type to use in place of socklen_t if not defined */ +#undef kde_socklen_t + +/* type to use in place of socklen_t if not defined (deprecated, use + kde_socklen_t) */ +#undef ksize_t diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 0000000..7cd149a --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,21 @@ +INCLUDES = $(all_includes) +noinst_HEADERS = about.h configdialog.h help.h kstyle_baghira_config.h colordialog.h colorpicker.h +METASOURCES = AUTO + +# Install this plugin in the KDE modules directory +kde_module_LTLIBRARIES = kstyle_baghira_config.la + +kstyle_baghira_config_la_SOURCES = kstyle_baghira_config.cpp colordialog.cpp colorpicker.cpp configdialog.ui help.ui about.ui +# kstyle_baghira_config_la_METASOURCES = AUTO +kstyle_baghira_config_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO) +kstyle_baghira_config_la_LDFLAGS = -module -avoid-version $(all_libraries) -no-undefined $(KDE_PLUGIN) + + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kstyle_baghira_config.pot + +pixmaps.h: $(srcdir)/generatePixmaps.sh + $(SHELL) $(srcdir)/generatePixmaps.sh $(top_srcdir) +CLEANFILES = pixmaps.h +kstyle_baghira_config.lo: pixmaps.h + diff --git a/config/about.ui b/config/about.ui new file mode 100644 index 0000000..bbe3ed7 --- /dev/null +++ b/config/about.ui @@ -0,0 +1,705 @@ + +About + + + About + + + + 0 + 0 + 380 + 531 + + + + + 7 + 7 + 0 + 0 + + + + + 380 + 450 + + + + + 1000 + 1000 + + + + About This Cat + + + true + + + NoFocus + + + false + + + + unnamed + + + + layout4 + + + + unnamed + + + + spacer3_2 + + + Horizontal + + + Expanding + + + + 216 + 20 + + + + + + + + layout11 + + + + unnamed + + + + crLabel + + + + 124 + 124 + 124 + + + + + + + AlignCenter + + + + + + + spacer19 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + layout6 + + + + unnamed + + + + spacer7 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + buttonInfo + + + NoFocus + + + More Info... + + + false + + + + + spacer8 + + + Horizontal + + + Expanding + + + + 111 + 20 + + + + + + + + textLabel2_2 + + + + + + image0 + + + + + spacer24 + + + Horizontal + + + Expanding + + + + 101 + 20 + + + + + + spacer25 + + + Horizontal + + + Expanding + + + + 91 + 20 + + + + + + spacer19_2 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + layout11 + + + + unnamed + + + + cpuLabel + + + unkonwn + + + AlignVCenter|AlignLeft + + + + + kdeLabel + + + unknown + + + AlignVCenter|AlignLeft + + + + + spacer20 + + + Vertical + + + Fixed + + + + 5 + 16 + + + + + + spacer2 + + + Horizontal + + + Fixed + + + + 5 + 20 + + + + + + spacer18 + + + Horizontal + + + Fixed + + + + 5 + 20 + + + + + + spacer19_6 + + + Horizontal + + + Expanding + + + + 80 + 20 + + + + + + textLabel5 + + + + 1 + + + + System + + + AlignVCenter|AlignRight + + + + + systemLabel + + + unknown + + + AlignVCenter|AlignLeft + + + + + spacer1 + + + Horizontal + + + Fixed + + + + 5 + 20 + + + + + + spacer9_4 + + + Horizontal + + + Expanding + + + + 80 + 20 + + + + + + spacer17 + + + Horizontal + + + Expanding + + + + 100 + 20 + + + + + + textLabel1_2 + + + + 1 + + + + CPU + + + AlignVCenter|AlignRight + + + + + spacer19_3 + + + Vertical + + + Fixed + + + + 5 + 16 + + + + + + spacer9_3 + + + Horizontal + + + Expanding + + + + 80 + 20 + + + + + + spacer9_2 + + + Horizontal + + + Expanding + + + + 100 + 20 + + + + + + spacer9 + + + Horizontal + + + Expanding + + + + 104 + 20 + + + + + + textLabel3 + + + + 1 + + + + KDE + + + AlignVCenter|AlignRight + + + + + + + spacer19_4 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + layout5 + + + + unnamed + + + + spacer5_2 + + + Horizontal + + + Expanding + + + + 91 + 20 + + + + + + buttonDownload + + + + 1 + 0 + 0 + 0 + + + + NoFocus + + + Download Update... + + + false + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 91 + 20 + + + + + + + + layout8 + + + + unnamed + + + + textLabel2 + + + Version + + + AlignVCenter|AlignRight + + + + + versionLabel + + + unknown + + + AlignVCenter|AlignLeft + + + + + + + layout10 + + + + unnamed + + + + textLabel1 + + + + 18 + 1 + + + + Baghira/QT + + + AlignCenter + + + + + + + spacer19_5 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + spacer26 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + + + 89504e470d0a1a0a0000000d4948445200000080000000800806000000c33e61cb0000200049444154789ced7d7f9c1d5595e797ceed700a5ea05ee8403fa19516a374244043f8d14c1cd37cb29a6951b135cea4978c93561ce99575d83633a33de0ba6c66063391d519c30a6e83e28611c7880bf44427cb8b10ed08986684a115908e26c36b4da00afa993aa6afedfe513fdeadaa5bf5ea75f7cb0b6ebe7cf8dc54bf7a55e7dd3ae7dcf3eb9e028ee3388ee3388ee3ff539cd06802b2a0ebf22e83993b21703a244e80804d82f68eee197db9d1b4bdda71cc3340d78aae0d00de4339ba1802a71b304e70a46333f3e3ccbc8388fe7174cfe864a3e97cb5e2986580ce0b3b5711d1ff28b4152e686d6d854106880890eee756d9826ddb28ed2fbdc265fecce8e3a39b1a4b71189d2b3a9790a02600bf1add335a6e343d49382619a0f3c2ceeb0bad85cf777474a0b5a5152c1990004b0609028361920906030c8cef1bc7c4b3138f03e81bdd33fa6c2368ee5ed5bdc0b6edf791a07740e02212743680052cf96566fe5700df21a2af8cee193dd808fa9270cc3140e7859dd7b79fddfef98ee51d20106cb641c2937c516102ff180230c9c4c4e404c6c7c65fb1d97ee7d8e3630f1f659aaf25a28d85b6c252d3349137f300e032ab6438b6837da57d281d28bd04e0e3634f8cdd7934e94bc331c5009d1776beb5fdacf65d1d9d1d000066d63f7c0dcc9c89497b127b1fdb0b66febdd13da3dfaf37bd5d97772d65e62fb59fddfefb1d1d1da01c81406066977e78f40a9719260f4c62ef937b611fb2ef187b6aecc3f5a62f0b16349a001f5d97779120f1e8f9cbcf374493001f66a00990331202023cc3eee4ce30c48c7b2c9a0458baa37dd886699ac89f9cc7fe17f6af6b3bbbedab077e7ea06e5e42e78ace778926f1d0f2cee5e774beb9133cc3902cc187191212e5236508084829218f4830335a16b7a0edcc36d865fb6241a2edd02f0ffd9f7ad19715c70c03b4b5b6ddd2dede7e655b6b1bca87cb20419052829a5c354a4deeda4fa88c98018410807447795822d7928358209a0ffdf2d03b0e1c38f00ff5a0b5ebf2ae0db985b97fbcf4b24b45fb6bda61dbb6fb81bf2c79f444c1471862a1405b5b1bca2f952fca9d927b617272726f3d68cc8a638201ba56769d0e60fbb28e65e023aefa9433323e3601525646d1e469025446292596b42cc121fbd0692d8b5b4e3f70e0c0c8bcd27a79d73500be7ce9c597c25c6ce2d04b87b4742469aa3297410b098b4e5d84d281d2556daf6dfbc28103070ecf278db5a0a9513756c1cc1f2db4162aebbbd49ce449966f13f80696aa1118156fa1a3bd0300067a56f7ac982f3abb5777af84c4dd1d1d1d305b4cd8b61d7825513a82314aaf207099d1dad28af6a5ed277099ff7abee89b0d1ace005d2bbb9a007c8816b90fdf918e7e647764c9d54706284728b4166095ad79b1b8bb57779f66dbf68e7c6b1eed6755d4beeaa256a38b40c1b15db65138ab00103ed4b5b2eb8cf9a0713668380390a05524a860e64cb0641830e0c07147a98cc2d06b0640af1904c15c6202c0793d6b7a7ae74ca8c43f11d1c91ded1db0d9d6fd8e900d10d083644d659289f6d6f613b8ccd7cc99be59a2e10cc0ccef0c227c322cf95126f0ffae1ba31267b38d7c2e0fca111c76e61425ec59d3f311bb6caf2a140a00c5e9f47e877bb2c7a45a4da0d1149ee67bff5ce89b0b1ace0000de0200a0ca64fa93e84b7ea0116ad50c02c8e7f260e6737bafeaed9e0d71bd57f59ee2949d5b4d32619a2608a4bfbf40321d0aa2710dd33401e092ee95dda7cf86beb9a2a10cd0b3ba27cf922f308451099e4424c4914e45e224d235820cdb0c2408641048102cb63e361b1a2db63ecb60327206f2b93c2cb6aa6b24a9a127a2291c76028621a2135872d76ce89b2b1aca000e9c379320e14847bb86277e4f91bc906640583259b29b400260c07847efd5bd2db5d0d77355cfeb007c1012301799d9ef9f408faa297cfa0c61b87f03ceab7902e7010d65000346bbffef4003b0622d2b6b66746dd5495c48323daf01002000473a021257d744a0c44d8141e7ab7865798ade3fc98651e9d1690ceff7beb126dae6098dd60067fa120f59899dc7ac66c9557301404432bdd13fdf93b87766a5adf7eaded31ce9acf72594882a364a0a54498fd2133085a7197c78bffbccacb4cd271a6d042e6154ac76d54fd6f9cf356b06789a45000e1c0058d5b7ae6f6116c258f2070d18cdc143acfc3dd5ef0fe215aca727aa2998d9ff0da766a16bbed15806903825b08a1d5712229f57245fe74f57d30c8a55ee3dc45320912d3228d11f7c4f44fc7ac49932290e90e13efef793555b1dd1581b40180bfdc9b3ca16c01ac94ef00eb26a069bedb0ba9de64baad1d5bbb6f70248bc49d11c5a3a62f74fa033a04ba33926ad49ffef0dc9cb34da06384135b0ec291b269971495210ab0fd06806750dc6b4f23d17cbab12368df778967958fd83e3f717a46586c4dc80a2311c760086af617e3397b99c2d1aed051cf1ffcd60307310664d94a82c11376f6476ff0721582e20b1ac2a61127f10399ed5fdd34600e032c32a5b7e42a9ba85590734da089cf2252d4f7938ec0413ac9398403368a0954ce6f0e700207066dfdabe84ab00fdebfbcf60f045fef924c85d067c173063c40f50ce93f15c015051ff9e068827188e021acb00020743ea5a009665b9d28b94b5556785ab9229dc6376b4ccd4024262d895255f4220a1aa774318b09d2a9a292ae1510da1c63904c12edb706c4765e8176631837346a33540c95f638311066ccb0ee7d381d4b5342699d263002512a848f4490016a7d074b17f7ea8a6cfabf50be5ff235e40aa37a01c3318b66587bc17431813f336ab35a0a10c4082f6478323beba9d3c38190487008df5add3109e343133eca9783571f010402727d1c4929741284129e53eec70aa4b5ad51bf0ef6133ac4356e8fa0e9c67e6757233a2d14bc08f836c9faa09bc07694fd99584899a2b48a9bcf11f54b0e67b46bc699895638113934822d06ba3f7f38f6311cbb44a20cde82f4da552297c5d300c61fc683ea7362b1aca00dbefdb7ec081f3330386dec0937055a5a7ce03498646137816bf6d29b654335c37b019e069ae1c03bfd5d1d3bfbebf89a7b9529da3680eff3ef6546db64048f2bd87ef5f5b31584b8e74c66b99bbf942a36d00e429ff4300c1c35725c38fc0b1e3a9df298d81252be1549ee640d2a999d246bd1d4f38959ac96580e6047a40602be25d5459f301cdc357bf2ff0bde2cee24c0dd3366f68380340e0fbea8484c2bb8a7af71fb63d655718c2ff7f9a03096730a8b96aa1665215ee493ccd275133059a2309f6945d895cfa06a8d01c33832d46e96049fdcd15b889a25db39bbcb9a3e10c40cdf46d202269d151863582f7bdcad8ac1cabd6bbfe7abf868095408e11304f8206f155370982ed78cce8bba0fee06b24cb3546adb215d836a16ca57f3de081d9cddedcd17006d8f6f56d4f91a0676261557058a254786bba56d223ae58542201bc6890a1dd4e4ea0053a8d11b2217c28c52b702a9ac9b69451b29b02a68897232ad94008ec19d931f2b3f99ed7ac683803000004be514d7283355991c8d4f3233645704cb47fcbad5b821074840e276a9d6b354ef4fa4273be5f89a47837316f07409ef277659ca5bae098600032e82eade4abf0ad79686c83244d1185fbf9d3299f970138da448f7fdfa826f0109c1f4955fb080a5c6548134c33f89e4c9354271c130cb0ed9e6dcf988bcc5140b3662b9247a0745b2169546d07a2c793e83084f132093a987a3d23a20934de824e33c534010c18c2181e7960e495ec3335ffa8263331745ddef55e00ab019ca7f4ecf90524c688e811838c7f1ed931527b470c81bf86c0fda1e28ee85a9f5430aa865955bf5ddd8ee5076380ef2691b0e5d62dbfe9dfd07f00c06b438e62c4ca0f34423345e30bda14b11aa65635419ef29fa9799ee61999fb03745ddef5872cf9a6424b619999776be421dcd8bdc516b8ec1a3e4ed92941e0cebc99fffbedf76dd71a5b49e8bdbaf7c700de042098dce89aeb43f770a3f9fad843042686ef1c7e7d1a0d03d70edc65b3fd81688c3f041d33a0422f4fa787ad3dfabfb2fd81ed1fa8657eea814c1aa06b45d71789e8c39d1d9dc8b7e443bd7a00a05554dab84c4c4e1426f74f7eb234591ae8b9aa6768e48191ad59893117991fb3a7ec1d3ac98f529df4f0a38919753473e6bd1966e451027d20148f883241828d10780b487ff8de35fe22ebbcd413556d80ce159df7e65bf21fbea2eb0a145a0bee8f29578a2d5832ecb21d4845c71b3ad07949273a9676988eed7ca1674dcfb77ad7f6e6b210337cf7f0b7c9a022a613ac7c917ded37c98cfddd20e34bd56830c82846ef1bedf4917a7f4f63051149c49998886eaa553bd60ba90cd0b9a2f3d38596c2daae4bba5cae2f572a76d4d42be0256124075ba6dbcf6d47c7f20e5865eb5d6cf158efdade4c65cf44b41ecd988965fb74fe7992f5aff93b091ad972eb96e7aadd7fcbad5bc689683c94f049b1eefdfb850a46fd6540c92104df13787afb7ddb6fce32174703890cd0b5b26b1911ddd4b9bcd39d6c8ed7c4c5e01b625e24ac7056019dcb3be148e70d3cc5dfeb5bd757950986ef1cfe7733677e5027613a49d4497a302ab1f8bc99ffcb8c730212f4555d36306d54238480a70934df37179973dfa93c8f4864002ef3d68ea51d00b9929fb93247ad806197093a9676c061e775f694fd78dfbabeaadbb386ef1cbe0b02b7ab865c28c2a7d2195deb351a229fcb7f71d3e64d4f669d142367dc0ee037da1c45350de41b88d3e1cf190c7391b961db3ddb7e92958ea3012d03745ddeb5dc34cdb7e6cd7c10df0e24429387d7ba66f07ebcc7048542014ed96965877766216cdbdddbfe94043d1844dc40fe3f2af4a81138b5f247ade327fa19043e5acba46cd9bce5503e97ff5c703d44344d8a2d10d0d71cd644e622f3966df76cbbab163a8e06b46e60e78acecfb5b7b6ff676f0d0f6f6c54112973d2ba6270c3a276d9c6f8f8b83f19776efbfab6fe2c04f66fe8ff064beef51e66f5fb7af0cab7d8308df3b76cde5273f3c8c11b064fb4cad60148b4647205556f4186bd01739179dbb67bb60dd44a838f9e353d6758656b3524deca929792a0d358f20c817ece929f3273e67dc5ddc5476773ed180374afec6eb2d9fe496747e71bf2ad150d90faf065d860d2310be50813cf4d60b234091204336ff60cdf3dfccf59881cb876e0ef987930660324d8221e3d2fe673f9359b366f4a8cfc55c3e00d836fb16cebe1a00e202d2e00af7c4d2a4c31cd20833ebbed9e6d83b3b97fcf9a9ea54ed9b981c17d05b3702ae50966ce0ceee997be95264b60e611cad18da3bb476bea3a166380aecbbb2e0430d6b1bc03f99c5baa1d6bd220942dcf2ad224d3cb8d8f8f8ffbe5512f9a79f3cce13b877f9d85d081eb0656b3e4cf307367cc308c2c4b79cadf0fc247b66cde32e74adb81eb07d67399bfa2de0f40d80b12619bc87bf8d3e6227360f8eee1aaae6714831b074fd8fbd8de5b9879b0d05a686a6f6f779b53e87eaf64709931363e86d2be1240f8e8d8e3635fc87aafd876a4b6b3dade0e81abdb0a6d9090414b36a34961821965bfbb6a45ccb89311f4f7f389f45aa7898502f8b5db20490871124e8078f2a927ff6f16421f7bfcb1e7c7f68e7df16d6f7ddbb368c2020171064b36823e820bc9c2428c2cc92d19bae5d65b3e35fafdd1a9ac93907adf471ffbd195dd57fe0012ab59728e9a0812eeeff35bd7f90f5d1e916e7fc085d8d1726acb7b6fbff3f66fd77abfdeab7bcf1f7f66fcc145272d7a5fc7f28e1396bf69b93b6f1228731972c66d3a2966dc967312124484a5e72c85385160f285c99ec259057bf285c91f64b95f4c0374aee8fcef66ce1c6a5fdaae35ec000492aea63843d92eb5d841d1082699281d2a61dffe7d4191a49937970cdf397ca8d6891afac4d0c9903887259f4a443680894d7fb3a96e5db9076f186c71d8b99199d7015812ad0206709888ee87c0edc3770c3f349b7bf45eddbbb63459bab7d05a40c7f20e9864ba41b68c304d13e3cf8d636c740c94a3d5a37b46ab0a976e09b803021feaece84c0d14eb7af700488dd9fbcbc0c444a504de5c647e76f8eee159ad918dc0d0c6a1bcc5d62590b800122741c001f0148027b6deb675d64b4eefd5bdd7960e956e6f2fb4a3e3dc8e20f0566bbacecc99187d621413e31307cd16f3cce2aee274daf9710658d1752f086bdbdbdbe1b76e4bb2ee03443582622b84cef7ce2b4d962a75fbcd38dc6ab69eb1f58eadc76c4ffd7aa36f6ddfda89d2c4bd8596023a3a3a40822afd1234364e62ee03e4baa11278a8f81058f227c61e1ffbdbb47bc7e300020bc015bf3b693f7e0852df01c3dfee15db232742d73f8965e3fae4351a7debfa2e2859a57bf3b93cdadbdbb33f7c50cc0b0300b0eb2eb7b7b783cbbcb17b6577aa0ed10582a6191cae7f8fec8ed5edc7d7f5c0d175d38a65cfc060e60d739bc65727fad7f79f6c5bf6772081d6422bcc5c65cdd74558b53b8f3832c28dda9aa60933672e66c93d6934c4188004bda2eead0b41e5b80827eac2a13a8d108a174cc3fffea503d70db4d5367daf7ed853f6d720717a3e9747a1a5107b3946749f81aee055cd5904cb000379d36d92098977a5d110630006ff8204c1b2dd8e1db15dae69a38c7366b4278ec556e57c4f0378e787f7e4ff8ea3776deffb59f23b1c3830979895201287356aecd817ca94e7e2ffdbc819b0d94eed3fa8d30013fe0dec29db4d064945d2552455c624246e20dd0aa280b3a72b3606805975f27c35a26f7d5f33a6711ba4dbc9349fcbc7fa0fe8fa0a4653f0d540824082cee95ed95d483a476703fcd8cf5e59b6155ef3912ce9d5b2833ed1165bc1b9a12a5fe68bb2fdacdf0148fc054b5e0ce915998af43e8289a34c18119aff13012496c1c518c0dba57a90849bc0e1290e67dd7492ae409b355452a604021cb8bb74a72bde00807306ae1b38aba6897c15a27f437f8ea7f8937e202c28af1361c3593b56eb48aada5abe97e53eb7d392e88931c0c8ce9132041e03dc87e3251ad225bc068d1044b6943a7feff30548e1d4df1530f34700184a85900ba56a38714c927819f7be7c5bc05b9e13fb2168eb0108e4e6ec3de24a074b6149977a49d756e3fae7bb6ade6ddb22bc7cb962037856ecefbc0660873fe6ff5e7f9f43b44bfaaca1681248c029075e5762f5b7be2288107a9b15971993a5c990ab97e60df8be685403f8c5a400c2bb7911b83069ad5b5ef5e85fdfbf8a259f150baa4535a5cc3842337a9d512db6d4865bac21074002031477167f4a82dc65c0937cab6cc13e68eb1344513f34aa193cc26cc7ae1475789b29426b95e4936a98cf571d58f235414a59b189aa45fc1247a919bde7e30b9b779c98514a0e130afc4f485ca2c69a2ddb82231d14f285f0da2510043142912bffc79611ebd913dbebe7fe88babcc872f32d9bcf60e66e4874b2e437c3cde69d406e9f806748d0130c2e6eba7953ddba74f4adeb6b62c97f108ae8a93583febc413346cf8b8cc1bcfb3590228ff1836ef5150b06817e994457220318c2b89bc1b742e014f561729951e2921b69f25c18c0ad9953cf0b8a152483a7146fc1e77c65e78f52ce35afcd126ffef4cd6b9979fde4e4e4db01c49a447b93fe567ff206370e7edf24f36e087ce5c64fdd38afaf7223a20bd9e2d744133800aaaffd51ff5fd1b8b14d2ae406f1fc4c22093a0881e7932e9d58153cb273649a88b644833d7e8ca074a884d2c152653fbcd7d0c9663be8d5c35395871fe2642836c074487dbd98713e5371f3a76ffea3c18d837b6ddbbed72a5bef04b0309395cdb8a274a8749b7dc8fef1d0c6a1ebe783161fcc7c051089e92b91bf4c9156650c3aaa4673019231694dc22e071af9d9e2ae622233a7668a0c616c81c09fb3e49355c906104408c1950d8f6a674e1fa1d83fc275f3b18d9fe039354a18ba71e82d606cb60fd997558ba869b39795e29636879dcf0f5c3ff0a17c2eff679bfe6653712e7479b8305643e907c480e4355db3c647c7502e86dd743b515084f3581a51a93b8346768efc0a027fa95da3148343cdfa85d45974678c028d06f83581665533bff996cd0b06370edeca363f6cb1751910916c1119a14f54a9dff342b3e75b87ac87066f189cd35bc70080259f13ad2206e076208d58f5d1c86be8d88fccea34870026f64f84990a9cb81b1ac8b037b0b8abf80f00fe2d905c84253adaf12258e395f3d5e3944e1f4f6fbd63ebc16af44471f38d375f3e7960f22930fe2ccb3b7baabed3270a015865eb9383d70f3e3eb871b0a356fa7c10a82de41df9f3e12d9b7e44302ad9558f5129b79bdc3fe9bed052047f3f428252cbc232358820a2b5ba840f80a0e74d4cf295f3439f47ad7faf7e1e0235d7d10d7d62e8a3a543a55107ceb9b1fa03cd2be6027a915caf1040c9b6110856d9bad8b19dc707ae1fa8edbd4300fa37f49fc4d36c02610deadf576d3455b55bba662441d857da87d2a4db894c61b2ef147715531b50646280e2cee2783e97ff13dde68f682d608853115fa3621140ff58d057b3d0e26368e3d056cbb6fe3ef11d3dea9aaea95d4c2c6df711cd72fa710ac63707ae1fa869a7118045004e546d2855833aec043d104359d40c91411284c9d224ac49ab925b007c83fdae6adfafc9efee5ed57d1b337f24fa708d5c7812759b45428923bfc7ce345c6659447bb7ddb3ede22c340c7d62a899cbfc2d473ad5eb077ccda30b4f27206460f91a0cf1ef13d1a6adb76dfdab2cd7ec5fdf5f98b4269ff3cadfb49b4bbc8e21fe9b4411d3b851e1f3682a1d2c05f99508ddbf24a2c2e8eed1d4069435f5082aee2a5e4744f74763fffe4b1a0322107ef8fedf01546c00e5fb44f4e759ee3ff489a1455ce6ef3b5cfde16bad7f20ddef49a9788a4640997968e0da812d59e866309320a91506855eab6c056e75503ba919fdd8cac4fe0970d9a531aa794d323f57ede103b3681255dc557c1709fa66742db3d88a45b474d6bfdf4bc7765c6305cdf8c6f09dc355ebd7076f186cb56ceb87165b2bd4fb260553a25e49cc4b49a9a851253f35e7c1fc5ffaafedff5c35da21f13224caba9a3e955e7f39f0c3ee3cc595cea8debf4b074b28954a989874adfd587cc5a5ff5710a84e17343b83b260dfbe7d5f3bff8de7b796657945c0c933809c9158b4701124a4cb91337077ca00aee47bfcc8473cc96ac27ef364f3cab11f8da52ae8a18d438ba70e4f8db2e437e84aa2437e70563401901e7ddec83361c997d2fd1d72a6429e68f2ce87008321a4b8acf3b2cedf8eed1d4b74b79e7ceac9df762ceb58c733fc1a7f4751f4bacd4dcdee8eab2603d2fb8f99218fb8231f61940f972159baf3da248026851e857e10861e79f89154f74f9d86596164e7c87579caff09245e062a592aab6ce9235c5eaf7da57a75c25c645e317cf7706af877f086c1bc655b8f32f339fef5a2c111f5fea1114767e4327fba7f437fb5ddbf3f09bea7e92b107ba96484a975cb06005d59decf46778ffe5d155a02cca94fe0c8ce912f1b39e35c087c4925ce7f31b2c50a3328356f24e881d67ceb8ae1bb870fa45d7ff086c166879d224b3e4757fd9ab85942315013fd68cdf743750ed5ea1f22358fccfc85fe0dfd896f26a5667a2c1acb57bfafed28aad82e315bca875a3d0cc0cc997f9c36a751cc5bf6ad674dcf7900d63bd2e901705e106ef5395ae01512f45d18f8e2f6af6f7f30cb3507ae1df8aecdf6ef27fde8d0881a53ab912c5a929710f30a92cef78f05966dbb675b2cabd8b7b6ef5c7bca1ed7d28fca71a893a87a5d859e10e3a9cc4cf4d9d1dda3356db3ab4bfab5f7aadee51058c292cf2641bf05f0736aa6a7b77d7d5ba9ea973d0c5c37703797f99ac4b55ddd781a8d91d7f0f0539920ae5ef586ad7f9ec3a0663a40269d337cc770ac1f71cf553d4f40e202409313885e0fe160964a5f2ce7e2deffb1d13da397a6cfaa7e1ae71ddb1fd89eb91f8f0e03d70e7cca2edbd7e81e565472a2b1f09a46f5fb1cbebed6d6d06c8bd3c4f6cf32613e08e03f447f1719b4992dfeaa8e0e6d2f6120fef02311406ffc390456cf66ae1bf2bad2340c5c37d06b1fb66f9b95b5eff527f035839432fd5863dd6b251eecf603f0bfef7bd711eb5bce48882681f291f2eb2fb9e092a6279f7e72974adef8d3e34f2e5db6f41ae788b3b8b9a9d9b5c09adceb3537b90192c01b80eb0d184d86db9f4118eef56744701feffe2f12d1ef3df2f023bf98cd7c1f13cda27d0c5c3770b66ddbdf00aa58fb9a31aa1e636ff88ce6cdabbd9318fafb6a2551c969f8c7f6947d53dfbabed8ae1c12b43e50eb12611b0009594a258b19ead328f01c115d52dc559cf52be78e2906b0cbf683b15c42ca1a1eb2a623d6704c53447215a1f3658201a96a1e151afa8078eec09eb2bfd9b7ae2fd45c7efb7ddbf78070532885aed0a7be3f517dbf0000b5c60f44b493882e9dcbc3078ea125a06f7ddf3024dee6ab65bffd8a94f1919a28683b131a85004b86684a186784fe7b703f8fddcfa703085f074ad0689a810595e0164b77b960c9c00c722cf98dcf3ef3ec3fa9bff5d9679e7d78e91b970a7944febe9412cd68ae88a2ef0dcc84dfa3a868b4dfd042bab1b8bbf8e17dfbf6c52b706ac431c100fd1bfaff501e91f1a28be89a8e48efa1e8381371d9a2c769de419312f993719f50177163306801414ebb6bb37f1d5f73c81909cce0bce5e72d7f62fcc7e3a16297679f7bb6b8ecbc65cfc819f916c9f2e4e6a66638479c900de0480738e232974b04eea51cfd51715771fb7ccd7d5ddcc05ad0bfa1bf85cbfc02839bab1a7c3aff3fa2ce55972e748c4ad955e2753488c501fceca0ff56312fa399e44a7ad6fdcb4454d87edff658d4b3e7aa9ec590f8a0c34e0f2456b264a1d0e500788204fd0b80af15771593df76324b349c01fad6f5fd0ba4ebc2e8ea071291160788c603923e4ff2c33d446d00b58845fb5e80e8f594e04e9ef25fdafec0f66bd37e52cf9a9eb3009ce64867b1218c92231dbbb8b33899712a6785863240fffafe3fb6a7ec2f27bee72fea97eb62e169986d1d40c2b20120c866aadfd3dd4367cde773f9ceed0f6c7fa2b61f515f34cc0be85fdf7f9a3d657f29a80ecef2f0333ecc00359c9f2957a0bc4cd2ef069e745f5dc32c66beb3c65f5077348c016cb6ff178066b53a184048adfa634d71808cc7a151eafdfa907f3f1dd600ecb0ab15347ebc3f466b0e1de95cd8b3a6e7fdb399af7aa1214b40dfbabe6e76f82100b1172fc5f60b64d50c550c44ddf989de81b2c6ab6b7d080ad3a87f8b2674a2b17c4318ff0ee0b5233b471af2aee0281aa201d8e12f0612e744242baa09a29258a366483b3ffad083fba668243f7ae7f73aca22f9a1f3d83913027f3aab89ab038e3a03f4adebbb16c0d26ad67e502dacbe3d6cbac6946fb5713a2cf1ed2a95070000066d4944415421d74e4524c2c89211ab46ceb2cfc03f9f9d4fcddf8cce0d473d10d4d2d23262909153d570908869aa1c872282d1710120a7e761d45c5f4df404f408259278c45df79d1907cd680e45ec5475ef07934211c4ca7572ed6f6c7f7edff3fb7e7434e63c0d47550374afeefe4f9038c3b2adf4d87c0aa292aa6a0a758c7eae3d4e4252ae4059f375fb0d74929fe45d40e2bfd53a7ff5c051d300ddabbb9bc17890c1869c919047240c3242b1f5605462f831cd704406295420414320fe79f4988fe8af1f92d468ae2022f940c6dc8177bdd0f27384cda5e72e1ddbf7fcbe86be43e8a8690003c6008317fb3b632001cbb610ec9449cac2452471be4a5852b382ba94b0444ce27d7f3f1835d74f8c2b0802181be7e7d7cc1e478d01acb2f57140b1cae1560997ec1258b236151b3a3f5241536b5c20f388f068b1db15256917b1ae1772744caa6b60c92bbb5775b7cf6e46e707478501ba5775bf070267a96bbc2af94129b95f01945607806cbb66a37e7fb4b033cd3b00e04a3c2b7b09a36bbc4e13a5d51744e9aba0a18db28f8e0690f8589a4412dcb6264ed9a9ec7fd71559e8fe5ecdcfcf2089b1f3b97ae7cea4fdf9c11865e6240dc6dcd0c860dd2381ddabba5fcfcc3f0dfea0cbe245d77ee1f6d09d377f5fa74974f7571a5cfb059a4a042fbe853c0569e707cce6b57423419dc5ddc5862489eaae0158f27f04108b99eb2422d8f8e8d9060e3ba1b5b9d6c85fe218adca6577479317af07a08de085ae93f27bf5e72bbf5b29ebf2bff68ed48bd611f55f0224de9b69cd5477f4c05b43cb0ca7ecc0293b41ec3db44346ce7e04dc87e4b0535db215faabc629223589a1e3a837233c2610b8329d80faa1ae4b40f7aaee73ecb2fd9c2e91a345868a1f00f0edb4a4f716ea108dd1a7198ceab1ca742a6afd7e95f115838cd347768c647a87e27ca22e1b437cb0e4d559ebfa132b7aa2a3b776120816acf8c349d9e1a3aee9a97186a8c648a057bd5feaf7ab8fa700380fc00f6b9ee439a2be4b80c415695677ad63e83a8a4dc092830da8c128e379fe4c3b8412e20ea971855a77246946473a0de9945e6f1be0bca47c7e3509d34952c80688f8eda9f183481c21533c206a33cc4eb2338f8630ceacf3b3d0a26e0cd0b5b22b0789f64c113ec4254d2b7109129beaffd7e01ac6be5feb1ec36a9a255d032c99f787900175630012b484c1f95409833e829788044954bfaff526b230414423a55e3fe97e3a4d95c56b016008a321d559756300967c4acd1287e435374096b538e9f32aa3ff30637f9f65c431913e8da670a4f352cd933c0fa8a706f86d4d11ba882465ad0f08618e6bf6ac228baa26d3792d691a00210db06fde26bf06d453031c22d4c00419bd85986688b87c99acf684314ba2288b268bfd9e14c957e87f642ef33d5bd44f03802601ec9b75cc3ecd465035c33cd60754cd46ce92fe34c9f72282f78fec1899d5fefeb9a26e0c50dc5d9c81c077e692b001aaaca9296392a648d310356513b3d09f4df2670c61ccebbb096a415de3002468cbbc67f312344335bf3df5387a3d40bb8667d210b5483e00838c778fec1899d37b12e682bad604eefbf9be97da5edbf6b298116be68d096622fbf393f6fb571f7f2a841803f01312f40abbbb724f0efa0f480ef723881ea7d12722b585225ee308000619ef1bd931f2ad7a3e836a382abe67d7caae8f83b1795e35418a046a6c0607024f03f82e113d06602f249e2fee2e068ab8674dcfa98e749602b89299df4ea02b55d7306b1c419bc88a63ca93fcf97813c99c70d4820f5d2bbbde0dc66d0c2ed49d0940003006814721b09304ed29ee2a1ea885deee55dd6f06f07e967c0d80d767721553b27e4a0af8070619eb471e187976fe67b9761cd5e853d7ca2e9340ffd57b7dea89f32cf9cf00d84d82f600f86e7177f199f9a0b967758f70e0f442623d4bbe6a0e92ff1b43187f3bb273e4afe683aef94243c28fdd2bbb5fc792fb00bc9b255f368b877d10c01880e720f03d02fd6b7177f1dfea4d77cfea9e658e74d60278174bbe2893e403af1864fc6f009f1dd931f25cbd69ac150def10d2bdaafbf52cf90202bd8925b742a0151227c3ddbf3305815f41e220093ac8e09f92a0e701bc50dc559c6a24dd3d6b7ace83c42a001738d2b908c0a9001641600a122f1bc2d80b815108dc3ff2c048cdef423a5a683803a8e85ed97d1a839790a09358f234817ec5e0c324e8c5e2ae6274cbe63101afadcb72473a7903c66207ce4b86302c004f8dec18d9df68fa8ee3388ee3388ee3388ee33874f87fa1ff8da830a4956c0000000049454e44ae426082 + + + + diff --git a/config/colordialog.cpp b/config/colordialog.cpp new file mode 100644 index 0000000..3466082 --- /dev/null +++ b/config/colordialog.cpp @@ -0,0 +1,300 @@ +#include "colordialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "colorpicker.h" +#include "pixmaps.h" + +#include "config.h" + +#ifndef CLAMP +#define CLAMP(x,l,u) x < l ? l :\ +x > u ? u :\ +x +#endif + +#define SATURATION_COLOR2(S,R,G,B) \ +int max = (int)(255+0.65*(100-S)); \ +destR = CLAMP((srcR + R - 128), 0, max); \ +destG = CLAMP((srcG + G - 128), 0, max); \ +destB = CLAMP((srcB + B - 128), 0, max); \ +destR = (S*destR + (100-S)*R)/100; \ +destG = (S*destG + (100-S)*G)/100; \ +destB = (S*destB + (100-S)*B)/100; + +#define COLOR_SPACE(R,G,B) \ +if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \ +if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \ +if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255; + +ColorDialog::ColorDialog(QWidget* parent, const char* name) : QDialog( parent, name) +{ + QVBoxLayout *vertical = new QVBoxLayout(this); + QHBoxLayout *top = new QHBoxLayout(vertical); + demo = new DemoWindow(this); + top->addWidget(demo); + QVBoxLayout *topRight = new QVBoxLayout(top); + QLabel *info = new QLabel("Select custom colors or grab directly from screen.
Click image left to switch between items.
",this); + topRight->addWidget(info); + QIconSet icon = KGlobal::iconLoader()->loadIconSet("colorpicker", KIcon::Small); + buttonCP = new QPushButton(icon, QString::null, this); + topRight->addWidget(buttonCP); + QLabel *lb = new QLabel("From other app:",this); + topRight->addWidget(lb); + other = new QComboBox(this); + topRight->addWidget(other); + topRight->addStretch(); + buttonOk = new QPushButton("&Ok", this); + topRight->addWidget(buttonOk); + buttonCancel = new QPushButton("&Cancel", this); + topRight->addWidget(buttonCancel); + const char *title[NUMCOLORS] = {"Background", "Button", "Base", "Text", "Highlight", "Highlighted Text", "Button Text", "Alternate Background"}; + for (int i = 0; i < NUMCOLORS; i++) + { + picker[i] = new ColorPicker(this, title[i]); + vertical->addWidget(picker[i]); + connect (picker[i], SIGNAL(colorChanged(QColor)), demo, SLOT(smartRepaint())); + picker[i]->hide(); + } + for (int i = 0; i < NUMCOLORS; i++) + picker[i]->blockSignals(true); + picker[Back]->setColor(colorGroup().background()); + picker[Button]->setColor(colorGroup().button()); + picker[Base]->setColor(colorGroup().base()); + picker[Text]->setColor(colorGroup().text()); + picker[High]->setColor(colorGroup().highlight()); + picker[HighText]->setColor(colorGroup().highlightedText()); + picker[ButText]->setColor(colorGroup().buttonText ()); + picker[Alternate]->setColor(KGlobalSettings::alternateBackgroundColor()); + for (int i = 0; i < NUMCOLORS; i++) + picker[i]->blockSignals(false); +// demo->repaint(false); + + picker[Button]->show(); + connect (buttonOk, SIGNAL(clicked()), this, SLOT(close())); + connect (buttonCP, SIGNAL(clicked()), this, SLOT(grabColor())); + connect (buttonCancel, SIGNAL(clicked()), this, SLOT(close())); + connect (other, SIGNAL(activated (const QString &)), this, SLOT(getFromOther(const QString &))); +} + +ColorDialog::~ColorDialog() +{ +} + +void ColorDialog::show() +{ + other->clear(); + QDir d( QDir::homeDirPath() + "/.baghira", 0L, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::Readable | QDir::Writable ); + if (d.exists()) + { + for ( uint i = 0; i < d.count(); i++ ) + other->insertItem(d[i]); + } + QDialog::show(); + demo->show(); +// demo->repaint(false); +} + +void ColorDialog::getFromOther( const QString & string ) +{ + FILE *file = NULL; + QString tmpString = QDir::homeDirPath() + "/.baghira/" + string; + if( (file = fopen(tmpString.latin1(), "r")) != NULL ) + { + uint k; + int colors[NUMCOLORS]; + for (int i = 0; i < NUMCOLORS; i++) + colors[i] = -1; + fscanf(file,"%u\n%u\n%u\n%u\n%u\n%u\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",&k,&k,&k,&k,&k,&k,&colors[0],&colors[1],&colors[2],&colors[3],&colors[4],&colors[5],&colors[6],&colors[7]); + fclose(file); + for (int i = 0; i < NUMCOLORS; i++) + { + picker[i]->blockSignals(true); + if (colors[i] != -1) picker[i]->setColor(QColor(colors[i])); + picker[i]->blockSignals(false); + } + demo->repaint(false); + } +} + +void ColorDialog::grabColor() +{ + gettingColorFromScreen = true; + grabMouse(crossCursor); + grabKeyboard(); +} + +void ColorDialog::mouseReleaseEvent(QMouseEvent* me) +{ + if (gettingColorFromScreen) + { + gettingColorFromScreen = false; + releaseMouse(); + releaseKeyboard(); + for (int i = 0; i < NUMCOLORS; i++) + { + if (picker[i]->isShown()) + { + picker[i]->setColor(KColorDialog::grabColor(me->globalPos())); + break; + } + } + } + else + QDialog::mouseReleaseEvent(me); +} + +//extern QImage uic_findiImage(const QString& name); +//extern void qInitImages_baghira(); +//extern void qCleanupImages_baghira(); + + +DemoWindow::DemoWindow( ColorDialog* parent, const char* name) : QWidget(parent, name) +{ + setBackgroundMode ( Qt::NoBackground ); + colorDialog_ = parent; + setFixedSize(320,120); + pm = new QPixmap(320,120); + pp = new QPainter(); + p = new QPainter(); + (const_cast(&p->font()))->setPixelSize(16); + baseRect = QRect(20, 10, 200, 100); + buttonRect = QRect(230, 90, 37, 21); + buttonTextRect = QRect(236, 91, 20, 18); + highlightRect = QRect(21, 42, 198, 22); + textRect = QRect(25, 21, 100, 18); + highTextRect = QRect(25, 42, 120, 22); + alternateRect = QRect(21, 86, 198, 22); + baseImage = uic_findImage("button-base"); + dest = QImage( baseImage.width(), baseImage.height(), 32 ); + dest.setAlphaBuffer( true ); +} + +DemoWindow::~DemoWindow(){} + +void DemoWindow::mousePressEvent ( QMouseEvent * me ) +{ + for (int i = 0; i < NUMCOLORS; i++) + colorDialog_->picker[i]->hide(); + + if (buttonTextRect.contains(me->pos())) + colorDialog_->picker[ButText]->show(); + else if (buttonRect.contains(me->pos())) + colorDialog_->picker[Button]->show(); + else if (textRect.contains(me->pos())) + colorDialog_->picker[Text]->show(); + else if (highTextRect.contains(me->pos())) + colorDialog_->picker[HighText]->show(); + else if (highlightRect.contains(me->pos())) + colorDialog_->picker[High]->show(); + else if (alternateRect.contains(me->pos())) + colorDialog_->picker[Alternate]->show(); + else if (baseRect.contains(me->pos())) + colorDialog_->picker[Base]->show(); + else + colorDialog_->picker[Back]->show(); +} + +void DemoWindow::paintEvent ( QPaintEvent * ) +{ + pp->begin(pm); + pp->fillRect(0,0,pm->width(),pm->height(), colorDialog_->picker[Back]->color()); + style().drawPrimitive( QStyle::PE_PanelLineEdit, pp, rect(), colorGroup() ); + pp->fillRect(baseRect, colorDialog_->picker[Base]->color()); + pp->fillRect(highlightRect, colorDialog_->picker[High]->color()); + pp->fillRect(alternateRect, colorDialog_->picker[Alternate]->color()); + pp->setPen ( colorDialog_->picker[Text]->color() ); + pp->drawText ( textRect, Qt::AlignAuto | Qt::AlignVCenter, "Common Text"); + pp->drawText ( alternateRect, Qt::AlignAuto | Qt::AlignVCenter, "Alt. Background"); + pp->setPen ( colorDialog_->picker[HighText]->color() ); + pp->drawText ( highTextRect, Qt::AlignAuto | Qt::AlignVCenter, "Highlighted Text"); + pp->drawPixmap(buttonRect, tintButton(baseImage, colorDialog_->picker[Button]->color())); + pp->setPen ( colorDialog_->picker[ButText]->color() ); + pp->drawText ( buttonTextRect, Qt::AlignCenter, "B"); + style().drawPrimitive( QStyle::PE_PanelLineEdit, pp, baseRect, colorGroup()); + pp->end(); + p->begin(this); + p->drawPixmap(0,0, *pm); + p->end(); +} + +void DemoWindow::smartRepaint() +{ + if (colorDialog_->picker[Back]->isShown()) + { + QWidget::repaint(false); + return; + } + if (colorDialog_->picker[Button]->isShown()) + { + QWidget::repaint(buttonRect, false); + return; + } + if (colorDialog_->picker[Base]->isShown()) + { + QWidget::repaint(false); + return; + } + if (colorDialog_->picker[Text]->isShown()) + { + QWidget::repaint(textRect, false); + return; + } + if (colorDialog_->picker[High]->isShown()) + { + QWidget::repaint(highlightRect, false); + return; + } + if (colorDialog_->picker[HighText]->isShown()) + { + QWidget::repaint(highTextRect, false); + return; + } + if (colorDialog_->picker[Alternate]->isShown()) + { + QWidget::repaint(alternateRect, false); + return; + } + if (colorDialog_->picker[ButText]->isShown()) + { + QWidget::repaint(buttonTextRect, false); + return; + } +} + +QImage & DemoWindow::tintButton(QImage &src, QColor & c) +{ +// dest = QImage( src.width(), src.height(), 32, 0, _ENDIAN_ ); + unsigned int *data = ( unsigned int * ) src.bits(); + unsigned int *destData = ( unsigned int* ) dest.bits(); + int total = src.width() * src.height(); + int red, green, blue; + int destR, destG, destB, alpha; + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + // float srcPercent, destPercent; + for ( int current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + blue = qBlue( data[ current ] ); + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + SATURATION_COLOR2(sq, red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} diff --git a/config/colordialog.h b/config/colordialog.h new file mode 100644 index 0000000..23c4808 --- /dev/null +++ b/config/colordialog.h @@ -0,0 +1,90 @@ +#ifndef COLORDIALOG_H +#define COLORDIALOG_H + +#include +#include +#include + +class QPushButton; +class QComboBox; +class QGroupBox; +class QPainter; +class ColorDialog; +class QImage; +class QPixmap; + +enum Colors { Back = 0, Button, Base, Text, High, HighText, ButText, Alternate, NUMCOLORS }; + +class DemoWindow : public QWidget +{ + Q_OBJECT + +public: + DemoWindow( ColorDialog* parent = 0, const char* name = 0); + ~DemoWindow(); + +private slots: + void smartRepaint(); + +protected: + void mousePressEvent ( QMouseEvent * e ); + void paintEvent ( QPaintEvent * ); + +private: + QPainter *p; + QPainter *pp; + QPixmap *pm; + ColorDialog* colorDialog_; + QRect baseRect; + QRect buttonRect; + QRect buttonTextRect; + QRect highlightRect; + QRect textRect; + QRect highTextRect; + QRect alternateRect; + QImage baseImage; + QImage dest; + +private: + QImage & tintButton(QImage &src, QColor & c); + +signals: + void selected(Colors c); + +}; + +class ColorPicker; + +class ColorDialog : public QDialog +{ + friend class DemoWindow; + friend class AppSetter; + Q_OBJECT + +public: + ColorDialog( QWidget* parent = 0, const char* name = 0); + ~ColorDialog(); + QPushButton *buttonOk; + QPushButton *buttonCancel; + void show(); + +protected: + ColorPicker *picker[NUMCOLORS]; + void mouseReleaseEvent(QMouseEvent* me); + DemoWindow *demo; + +private: + QPushButton *buttonCP; + bool gettingColorFromScreen; + QComboBox *other; + +private slots: + void grabColor(); + void getFromOther( const QString & string ); + +signals: + void colorChanged(QColor color); + +}; + +#endif // COLORPICKER_H diff --git a/config/colorpicker.cpp b/config/colorpicker.cpp new file mode 100644 index 0000000..263ef0d --- /dev/null +++ b/config/colorpicker.cpp @@ -0,0 +1,81 @@ +#include "colorpicker.h" +#include +#include +#include + +ColorPicker::ColorPicker(QWidget* parent, const char* name) : QGroupBox( parent, name) +{ + setTitle(name); + setColumnLayout(0, Qt::Vertical ); + layout()->setSpacing( 6 ); + layout()->setMargin( 11 ); + + QVBoxLayout *vLayout = new QVBoxLayout(layout()); + + red = new KIntNumInput(this, "red"); + red->setRange(0, 255, 1, true); + red->setLabel("R"); + vLayout->addWidget(red); + green = new KIntNumInput(this, "green"); + green->setRange(0, 255, 1, true); + green->setLabel("G"); + vLayout->addWidget(green); + blue = new KIntNumInput(this, "blue"); + blue->setRange(0, 255, 1, true); + blue->setLabel("B"); + vLayout->addWidget(blue); + connect (red, SIGNAL(valueChanged( int )), this, SLOT(emitChange())); + connect (green, SIGNAL(valueChanged( int )), this, SLOT(emitChange())); + connect (blue, SIGNAL(valueChanged( int )), this, SLOT(emitChange())); +} + +ColorPicker::~ColorPicker() +{ +} + +void ColorPicker::emitChange() +{ + emit colorChanged(QColor(red->value(), green->value(), blue->value())); +} + +void ColorPicker::setColor(const QColor & color) +{ + red->setValue( color.red() ); + green->setValue( color.green() ); + blue->setValue( color.blue() ); + emit colorChanged(color); +} + +void ColorPicker::setRed(int r) +{ + red->setValue( r ); + emit colorChanged(QColor(r, green->value(), blue->value())); +} + +void ColorPicker::setGreen(int g) +{ + green->setValue( g ); + emit colorChanged(QColor(red->value(), g, blue->value())); +} + +void ColorPicker::setBlue(int b) +{ + blue->setValue( b ); + emit colorChanged(QColor(red->value(), green->value(), b)); +} + +QColor & ColorPicker::color() +{ + color__ = QColor(red->value(), green->value(), blue->value()); + return color__; +} + +void ColorPicker::reset() +{ + setColor(color_); +} + +void ColorPicker::init() +{ + color_ = color(); +} diff --git a/config/colorpicker.h b/config/colorpicker.h new file mode 100644 index 0000000..6f813b2 --- /dev/null +++ b/config/colorpicker.h @@ -0,0 +1,39 @@ +#ifndef COLORPICKER_H +#define COLORPICKER_H + +#include + +class KIntNumInput; +class QColor; + +class ColorPicker : public QGroupBox +{ + Q_OBJECT + +public: + ColorPicker( QWidget* parent = 0, const char* name = 0); + ~ColorPicker(); + QColor & color(); + +public slots: + void setColor(const QColor & color); + void setRed(int red); + void emitChange(); + void setGreen(int green); + void setBlue(int blue); + void reset(); + void init(); + +protected: + KIntNumInput *red; + KIntNumInput *green; + KIntNumInput *blue; + QColor color_; + QColor color__; + +signals: + void colorChanged(QColor color); + +}; + +#endif // COLORPICKER_H diff --git a/config/configdialog.ui b/config/configdialog.ui new file mode 100644 index 0000000..870e4cf --- /dev/null +++ b/config/configdialog.ui @@ -0,0 +1,3039 @@ + +Config + + + Config + + + + 0 + 0 + 643 + 646 + + + + + 7 + 7 + 0 + 0 + + + + Configure Your Cat + + + + unnamed + + + + layout55 + + + + unnamed + + + + buttonHelp + + + &Help + + + F1 + + + true + + + + + buttonAbout + + + About + + + + + spacer37_2 + + + Horizontal + + + Expanding + + + + 210 + 20 + + + + + + statusWarning + + + + 1 + + + + + + + + + spacer35_2 + + + Horizontal + + + Expanding + + + + 160 + 20 + + + + + + buttonLoad + + + Load... + + + + + buttonSaveAs + + + Save As... + + + + + + + tabWidget + + + + 7 + 7 + 0 + 0 + + + + + Widget8 + + + General Design + + + + unnamed + + + + spacer35_5 + + + Vertical + + + Expanding + + + + 20 + 38 + + + + + + groupBox13 + + + Groupboxes + + + + unnamed + + + + layout22 + + + + unnamed + + + + shadowGroups + + + Sink Groupboxes + + + + + layout7 + + + + unnamed + + + + textLabel5 + + + Depth + + + + + shadowIntensity + + + 10 + + + 1 + + + 1 + + + Horizontal + + + Below + + + 10 + + + + + layout6 + + + + unnamed + + + + textLabel6 + + + Flat + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 81 + 20 + + + + + + textLabel7 + + + Deep + + + + + + + + + + + + + groupBox12 + + + Coloring + + + + unnamed + + + + textLabel12 + + + Color function + + + + + + Aquarius + + + + + Liquid (depreached) + + + + colorMode + + + "Aquarius" is very Aqua like<br>"Liquid" bases upon mosfet's original Code + + + + + layout123 + + + + unnamed + + + + + Fixed + + + + + Background + + + + + Active Button + + + + + Custom + + + + inactiveColorType + + + "Background" is ok, as long as you don't use a very dark color scheme. In this case use "Fixed" or "Custom" to get more control over the appereance + + + + + customInactiveColor + + + + + + + + + + textLabel13 + + + Unhovered / Inactive Widget Color + + + + + line14_2 + + + HLine + + + Sunken + + + Horizontal + + + + + + + groupBox11 + + + Scanlines + + + + unnamed + + + + stippleBackground + + + Use Scanlines in Aqua Design + + + + + layout4 + + + + unnamed + + + + textLabel2 + + + Scanline contrast + + + + + stippleContrast + + + 10 + + + 1 + + + 1 + + + true + + + Horizontal + + + NoMarks + + + 10 + + + + + layout3 + + + + unnamed + + + + textLabel3 + + + Low + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 221 + 20 + + + + + + textLabel4 + + + High + + + + + + + + + line13 + + + HLine + + + Sunken + + + Horizontal + + + + + + + groupButtonPreview + + + Button Color + + + <b>This now will affect your button color, but <i>not</i> touch the color settings</b> + + + + unnamed + + + + layout59 + + + + unnamed + + + + layout58 + + + + unnamed + + + + spacer38 + + + Vertical + + + Expanding + + + + 20 + 10 + + + + + + pixmapButtonPreview + + + true + + + + + spacer39 + + + Vertical + + + Expanding + + + + 20 + 10 + + + + + + + + layout55 + + + + unnamed + + + + textLabel1_5 + + + R + + + + + textLabel2_5 + + + G + + + + + textLabel3_4 + + + B + + + + + + + layout53 + + + + unnamed + + + + sliderButtonRed + + + 255 + + + Horizontal + + + + + sliderButtonGreen + + + 255 + + + Horizontal + + + + + sliderButtonBlue + + + 255 + + + Horizontal + + + + + + + layout56 + + + + unnamed + + + + valueButtonRed + + + 0 + + + + + valueButtonGreen + + + 0 + + + + + valueButtonBlue + + + 0 + + + + + + + + + + + textLabel1_10 + + + Color presets + + + + + colorPresets + + + + + spacer36_2 + + + Horizontal + + + Expanding + + + + 207 + 20 + + + + + + spacer37_4 + + + Horizontal + + + Expanding + + + + 316 + 20 + + + + + + animateButtons + + + Animate Buttons + + + + + groupBox10 + + + Generation + + + + unnamed + + + + line2 + + + VLine + + + Sunken + + + Vertical + + + + + layout48 + + + + unnamed + + + + textLabel1 + + + Default Design is + + + + + + Jaguar + + + + + Panther + + + + + iTunes + + + + + Tiger + + + + + Milk + + + + defaultStyle + + + + + + + + line14 + + + HLine + + + Sunken + + + Horizontal + + + + + spacer36_3 + + + Vertical + + + Expanding + + + + 20 + 49 + + + + + + + + textLabel1_9 + + + Buttons look like + + + + + textLabel2_8 + + + Toolbuttons look like + + + + + + Jaguar + + + + + Panther + + + + + iTunes + + + + + Tiger + + + + + Milk + + + + buttonStyle + + + + + + Jaguar + + + + + Panther + + + + + iTunes + + + + + Tiger + + + + + Milk + + + + toolbuttonStyle + + + + + + + + + Widget9 + + + Special Widgets + + + + unnamed + + + + groupBox9 + + + Tabs + + + <qt>Panther introduced so called choosers<br>Qt has only Tabs, but you can influence their appereance here a bit</qt> + + + + unnamed + + + + + Tabs + + + + + Clever + + + + + Choosers + + + + brushedTabs + + + + + textLabel3_7 + + + Brushed Tabs are + + + + + + Tabs + + + + + Clever + + + + + Choosers + + + + aquaTabs + + + + + textLabel2_7 + + + Aqua tabs are + + + + + line4 + + + HLine + + + Sunken + + + Horizontal + + + + + centerTabs + + + Center Align Tabs + + + + + + + groupBox2 + + + Scrollbars + + + + unnamed + + + + animateSlider + + + Animate Hovered Slider + + + + + squeezeSlider + + + Squeeze pressed Slider + + + + + shadowSlider + + + Shadow Slider + + + + + + + spacer31_2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + groupBox1 + + + ListViews + + + + unnamed + + + + layout68 + + + + unnamed + + + + layout67 + + + + unnamed + + + + drawTreeLines + + + + 4 + 0 + 0 + 0 + + + + Draw Tree Lines + + + + + spacer60 + + + Horizontal + + + Expanding + + + + 31 + 20 + + + + + + + + layout66 + + + + unnamed + + + + textLabel8 + + + + 4 + 5 + 0 + 0 + + + + Expanders look like + + + + + spacer61 + + + Horizontal + + + Expanding + + + + 31 + 20 + + + + + + + + layout65 + + + + unnamed + + + + useCustomExpanderColor + + + Use Custom Expander Color + + + + + spacer59 + + + Horizontal + + + Expanding + + + + 31 + 20 + + + + + + + + + + layout71 + + + + unnamed + + + + layout70 + + + + unnamed + + + + + Lines + + + + + Dots + + + + treeLineMode + + + + + treeLineColor + + + + 4 + 0 + 0 + 0 + + + + + + + + + + + + Apple + + + + + M$ + + + + expanderMode + + + + 1 + 0 + 0 + 0 + + + + Expanders are the little icons you can click to open a new Layer in the tree + + + + + layout69 + + + + unnamed + + + + spacer15 + + + Horizontal + + + Expanding + + + + 150 + 20 + + + + + + customExpanderColor + + + + + + + + + + + + line5 + + + HLine + + + Sunken + + + Horizontal + + + + + useRectLVH + + + Use flatter Listview Header + + + Makes Listview Headers look like the rectangular Buttons + + + + + bevelHighlights + + + Use Bevel as Highlight Color + + + + + + + groupBox4 + + + Kicker + + + + unnamed + + + + roundTasks + + + Use Round Taskbuttons + + + + + line6 + + + HLine + + + Sunken + + + Horizontal + + + + + replaceMenubar + + + Replace menubar extension (display app name) + + + + + layout49 + + + + unnamed + + + + textLabel1_11 + + + Maximum width + + + + + menuMaxWidth + + + px + + + 10000 + + + + + startKRuler + + + Start KRuler + + + + + spacer37_5 + + + Horizontal + + + Expanding + + + + 80 + 20 + + + + + + + + removeKickerBevel + + + Remove Bevel + + + + + + + layout53 + + + + unnamed + + + + groupBox3 + + + Progressbars + + + + unnamed + + + + layout39 + + + + unnamed + + + + textLabel11 + + + Style + + + + + + Apple + + + + + Liquid + + + + + Baghira + + + + progressType + + + + + + + layout52 + + + + unnamed + + + + showProgressValue + + + Show Value + + + + + spacer39_2 + + + Horizontal + + + Expanding + + + + 120 + 20 + + + + + + + + + + groupBox5 + + + Toolbars + + + + unnamed + + + + + Aqua + + + + + Brushed Metal + + + + + Both + + + + + None + + + + unhoveredToolButtons + + + + + textLabel1_8 + + + Show unhovered buttons for + + + + + layout50 + + + + unnamed + + + + textLabel1_12 + + + Highlight Color + + + + + toolbuttonHighColor + + + + + + + + spacer38_2 + + + Horizontal + + + Expanding + + + + 91 + 20 + + + + + + + + + + + + + + tab + + + Menus + + + + unnamed + + + + spacer36 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + spacer37_3 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + transGroup + + + true + + + Look + + + + unnamed + + + + layout64 + + + + unnamed + + + + textLabel1_4 + + + + 1 + 5 + 0 + 0 + + + + Background + + + + + + Default + + + + + Plain + + + + + Stipples + + + + + Gradient + + + + menuBackground + + + true + + + + 3 + 0 + 0 + 0 + + + + Solid is fastest, Gradient is slowest - choose by your personal preferences and the speed of your machine + + + + + + + layout55 + + + + unnamed + + + + drawMenuStripe + + + Draw menu stripe + + + + + menuStripeColor + + + + + + + + spacer27_2 + + + Horizontal + + + Expanding + + + + 481 + 20 + + + + + + + + line10 + + + HLine + + + Sunken + + + Horizontal + + + + + line7 + + + HLine + + + Sunken + + + Horizontal + + + + + layout61 + + + + unnamed + + + + textLabel2_2 + + + Opacity + + + + + menuOpacity + + + 100 + + + 1 + + + 1 + + + Horizontal + + + NoMarks + + + 10 + + + + + + + + layout28 + + + + unnamed + + + + textLabel3_2 + + + Translucent + + + + + spacer17 + + + Horizontal + + + Expanding + + + + 81 + 20 + + + + + + textLabel4_2 + + + Opaque + + + + + + + + + line8 + + + HLine + + + Sunken + + + Horizontal + + + + + layout54 + + + + unnamed + + + + textLabel2_4 + + + Text + + + + + menuTextColorHigh + + + + + + + + spacer29_2 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel3_6 + + + Background + + + + + menuColorHigh + + + + + + + + + + textLabel1_7 + + + Highlighted + + + + + line9 + + + HLine + + + Sunken + + + Horizontal + + + + + layout62 + + + + unnamed + + + + textLabel1_2 + + + Text + + + + + menuTextColor + + + + 4 + 0 + 0 + 0 + + + + + + + + + spacer37 + + + Horizontal + + + Expanding + + + + 280 + 20 + + + + + + textLabel2_3 + + + Background + + + + + menuColor + + + + + + + + textLabel2_3_2 + + + Background 2 + + + + + menuColor2 + + + + + + + + + + layout46 + + + + unnamed + + + + textLabel5_2 + + + + 4 + 5 + 0 + 0 + + + + Color + + + + + + Background + + + + + Button + + + + + Custom + + + + menuColorMode + + + + 1 + 0 + 0 + 0 + + + + Qt usually uses the button color for the menus... well, Apple does not. + + + + + + + glossyMenus + + + Use glossy highlights + + + + + shadowMenuText + + + Shadow itemtext + + + + + + + spacer34_2 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + groupBox14 + + + Sidebar + + + + unnamed + + + + + 16x16 + + + + + 22x22 + + + + + 32x32 + + + + + 48x48 + + + + + 64x64 + + + + + 128x128 + + + + linkIconSize + + + + + textLabel1_13 + + + Hardware Iconsize + + + + + textLabel2_9 + + + Link Iconsize + + + + + + 16x16 + + + + + 22x22 + + + + + 32x32 + + + + + 48x48 + + + + + 64x64 + + + + + 128x128 + + + + hwIconSize + + + + + spacer39_3 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + + + tab + + + Custom Colors + + + + unnamed + + + + useCustomColors + + + Use Custom Widget Colors + + + These Widgets default to the Button Color, however you can customize them here + + + + + colorFrame + + + StyledPanel + + + Raised + + + + unnamed + + + + layout62 + + + + unnamed + + + + layout58 + + + + unnamed + + + + textLabel4_3 + + + Radiobutton ("Off") + + + + + spacer27 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + radioOffColor + + + + + + + + + + layout60 + + + + unnamed + + + + textLabel5_3 + + + Unchecked Box + + + + + spacer31 + + + Horizontal + + + Expanding + + + + 71 + 20 + + + + + + checkOffColor + + + + + + + + + + layout62 + + + + unnamed + + + + textLabel7_3 + + + Scrollbar Slider + + + + + spacer30 + + + Horizontal + + + Expanding + + + + 121 + 20 + + + + + + sliderColor + + + + + + + + + + layout64 + + + + unnamed + + + + textLabel9_2 + + + Pressed Slider + + + + + spacer33 + + + Horizontal + + + Expanding + + + + 111 + 20 + + + + + + pressedSliderColor + + + + + + + + + + layout65 + + + + unnamed + + + + textLabel11_3 + + + Inactive Tab + + + + + spacer34 + + + Horizontal + + + Expanding + + + + 71 + 20 + + + + + + inactiveTabColor + + + + + + + + + + + + layout61 + + + + unnamed + + + + layout59 + + + + unnamed + + + + textLabel3_3 + + + Radiobutton ("On") + + + + + spacer28 + + + Horizontal + + + Expanding + + + + 31 + 20 + + + + + + radioOnColor + + + + + + + + + + layout61 + + + + unnamed + + + + textLabel6_3 + + + Checked Box + + + + + spacer29 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + checkOnColor + + + + + + + + + + layout63 + + + + unnamed + + + + textLabel8_3 + + + Hovered Slider + + + + + spacer32 + + + Horizontal + + + Expanding + + + + 121 + 20 + + + + + + hoverSliderColorColor + + + + + + + + + + layout52 + + + + unnamed + + + + textLabel1_3 + + + Slider Groove + + + + + spacer35_3 + + + Horizontal + + + Expanding + + + + 231 + 20 + + + + + + sliderGrooveColor + + + + + + + + + + layout66 + + + + unnamed + + + + textLabel10 + + + Active Tab + + + + + spacer35 + + + Horizontal + + + Expanding + + + + 71 + 20 + + + + + + activeTabColor + + + + + + + + + + + + line11 + + + VLine + + + Sunken + + + Vertical + + + + + spacer32_2 + + + Vertical + + + Expanding + + + + 20 + 51 + + + + + + brushBox + + + Tint the Brush + + + + unnamed + + + + layout62 + + + + unnamed + + + + layout59 + + + + unnamed + + + + textLabel1_6 + + + R + + + + + sliderBrushRed + + + 255 + + + Horizontal + + + + + + + layout60 + + + + unnamed + + + + textLabel2_6 + + + G + + + + + sliderBrushGreen + + + 255 + + + Horizontal + + + + + + + layout61 + + + + unnamed + + + + textLabel3_5 + + + B + + + + + sliderBrushBlue + + + 255 + + + Horizontal + + + + + + + + + pixmapBrushPreview + + + true + + + + + + + tintBrush + + + Tint Brushed Metal + + + + + line12 + + + HLine + + + Sunken + + + Horizontal + + + + + + + + + + + + + + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + + diff --git a/config/generatePixmaps.sh b/config/generatePixmaps.sh new file mode 100755 index 0000000..e0de14c --- /dev/null +++ b/config/generatePixmaps.sh @@ -0,0 +1,13 @@ +#!/bin/sh +top_srcdir="${1:-../..}" +imagebase="$top_srcdir/imagebase" +UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ") +echo -e "#ifndef SCPIXMAPS_H\n#define SCPIXMAPS_H\n" > pixmaps.h +$UIC -embed baghira \ +$imagebase/button-base \ +$imagebase/button-shadow \ +$imagebase/brush-me | \ +sed -e "s/void qInitImages_baghira()$/static void qInitImages_baghira()/" -e "s/void qCleanupImages_baghira()$/static void qCleanupImages_baghira()/ ">> pixmaps.h +echo -e "#endif //SCPIXMAPS_H\n" >> pixmaps.h + +#$imagebase/AboutBaghira \ diff --git a/config/help.ui b/config/help.ui new file mode 100644 index 0000000..5fdae0a --- /dev/null +++ b/config/help.ui @@ -0,0 +1,305 @@ + +Help + + + Help + + + + 0 + 0 + 457 + 720 + + + + + 7 + 5 + 0 + 0 + + + + + 32767 + 32767 + + + + Baghira Help + + + false + + + + unnamed + + + + layout2 + + + + unnamed + + + + spacer2_2 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + closeButton + + + Close + + + + + + + tabWidget2 + + + + tab + + + BAB + + + + unnamed + + + + layout3 + + + + unnamed + + + + spacer3 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + startBAB + + + Start BAB + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + kActiveLabel2 + + + + 7 + 7 + 0 + 0 + + + + Manual + + + Auto + + + Auto + + + <b>"BAB"</b> is a little Systray Application to give you more control about the look of your Baghiranced Desktop.<br> +You can start if from a shell or the KDE executor or by just simply clicking the button below.<br> +<br> +<b>How does it work?</b><br> +a) Simply leftclick the icon to switch between the different generations ( Blue:Jaguar, Black:Panther, Grey:Brushed Metal, Yellow:Tiger, White:Milk)<br><br> +b) Righclick to get a config menu, providing direct acces to Baghiras config dialog<br><br> +c) BAB is also a DCOP interface to the Baghira Style and Windeco + + + + + + + tab + + + DCOP + + + + unnamed + + + + kActiveLabel4 + + + <br><b>How to acces bab via DCOP</br> +<br>Well, if you're a coder, i assume you know hot to access the dcop server from within your code +<br>If you're a user, the main way to acces dcop is the <b>dcop command line tool</b><br><br> +To see, which functions are provided by bab (the list will probably grow), open a shell and enter<br><br> +<i><b>dcop bab default</b></i><br> +<br> +The most interesting function is<br><br> +<i><b>start(QString name,QString settings)</b></i><br> +<br> +use it like:<br><br> +<i><b>start &lt;appName&gt; &lt;design&gt;</b></i><br><br> +where <i><b>&lt;appName&gt;</b></i> is the (KDE) application command (try "konqueror") you want to start and <i><b>&lt;design&gt;</b></i> is a predefined Design you set in the rules section (Baghiracomes with "Jaguar", "Panther", "Brushed", "Tiger" and "Milk") + + + + + + + tab + + + Coloring + + + + unnamed + + + + kActiveLabel3 + + + The new coloring Function <i>"Aquarius"</i> replaces the former "<i>icy</i>" style. +<br>Though you can use any color, i suggest to avoid very high or very low saturated colors. +<br>- High saturation will lead to a flat look +<br>- Low saturation will look uncolored +<br> +<br>I suggest to use a button color like rgb = 84,140,242 as a starting Point and modify the color to yoour wishes +<br><b>Notice</b> that the coloring function is probably not fixed yet - especially not in the high saturated area +<br>So please do not complain if you worked hard to optimize the color and get a different result in one of the next versions. +<br> +<br>Additionally, there are two color schemes by Christian Lehmann included. + + + + + + + tab + + + Credits + + + + unnamed + + + + kActiveLabel1 + + + Auto + + + Auto + + + <b>Apple Computer, Inc.</b><br>For being such great Designers =)<p> +<b>Christian Lehmann</b><br>For the SuSE binaries and Supporting my Ego<p> +<b>Elias Probst</b><br>For the Gentoo ebuild<p> +<b>Mosfet</b> (Of Course)<br>For the initial Liquid Code<p> +<b>Narcis Tesa</b><br>For the Mandrake binaries and being the worst nitpicker on this Planet<p><b>Timur</b><br>For the cute icons<p> +Everyone else who supported me with suggestions, bug reports and Help on the fores.<p> +<a href="http://www.kde-look.org/">KDE-Look</a><br> +and<br> +<a href="http://www.sf.net/">Sourceforge</a><br> +for hosting the Project + + + + + textLabel1 + + + + 1 + + + + Thanks To (alphabetical): + + + + + + + + + + + + closeButton + clicked() + Help + close() + + + + + kactivelabel.h + kactivelabel.h + kactivelabel.h + kactivelabel.h + + diff --git a/config/kstyle_baghira_config.cpp b/config/kstyle_baghira_config.cpp new file mode 100644 index 0000000..1e838e8 --- /dev/null +++ b/config/kstyle_baghira_config.cpp @@ -0,0 +1,1243 @@ +/*************************************************************************** + * Copyright (C) 2004 by Thomas Lübking * + * thomas@home * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#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 +#include +#include +#include + +#include +#include +#include +#include + +#include "kstyle_baghira_config.h" +#include "pixmaps.h" +#include "colordialog.h" +#include "colorpicker.h" + +#include "config.h" + +//#define VERSION "0.7" + +#ifndef KDE_VERSION_STRING +#define KDE_VERSION_STRING "error" +#endif +#ifndef QT_BUILD_KEY +#define QT_BUILD_KEY "error error error error" +#endif + +#define CLAMP(x,l,u) x < l ? l :\ + x > u ? u :\ + x + +#define SATURATION_COLOR(R,G,B) \ + grey = (299 * R + 587 * G + 114 * B) / 1000; \ + delta = 255 - grey; \ + grey = (grey *(10 - 5)) / 10; \ + iGrey = 255 - grey;\ + destR = (iGrey * (srcR - delta) + grey * R) / 255; \ + destG = (iGrey * (srcG - delta) + grey * G) / 255; \ + destB = (iGrey * (srcB - delta) + grey * B) / 255; + +#define SATURATION_COLOR2(S,R,G,B) \ + int max = (int)(255+0.65*(100-S)); \ + destR = CLAMP((srcR + R - 128), 0, max); \ + destG = CLAMP((srcG + G - 128), 0, max); \ + destB = CLAMP((srcB + B - 128), 0, max); \ + destR = (S*destR + (100-S)*R)/100; \ + destG = (S*destG + (100-S)*G)/100; \ + destB = (S*destB + (100-S)*B)/100; + +#define COLOR_SPACE(R,G,B) \ + if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \ + if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \ + if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255; + + +void kstyle_baghira_config::openHtml1() +{ + QStringList args; + args << "exec" << "http://baghira.sf.net/"; + kapp->kdeinitExec("kfmclient", args); +} + +void kstyle_baghira_config::openHtml2() +{ + QStringList args; + args << "exec" << "http://www.sf.net/projects/baghira/files/"; + kapp->kdeinitExec("kfmclient", args); +} + +void kstyle_baghira_config::startBab() +{ + kapp->kdeinitExec("bab"); +} + +void kstyle_baghira_config::startKRuler() +{ + kapp->kdeinitExec("kruler"); +} + +QImage* kstyle_baghira_config::tintButton(QImage &src, QColor c) +{ + QImage *dest = new QImage( src.width(), src.height(), 32, 0 ); + dest->setAlphaBuffer( true ); + unsigned int *data = ( unsigned int * ) src.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = src.width() * src.height(); + int red, green, blue; + int destR, destG, destB, alpha; + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + // float srcPercent, destPercent; + for ( int current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + blue = qBlue( data[ current ] ); + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + SATURATION_COLOR2(sq, red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +QImage* kstyle_baghira_config::tintBrush( QImage &img, QColor c) +{ + QImage *dest = new QImage( img.width(), img.height(), 32, 0 ); + unsigned int *data = ( unsigned int * ) img.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = img.width() * img.height(); + int current; + int delta; + int red, green, blue, grey, iGrey; + int destR, destG, destB, alpha; + + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + + + // float srcPercent, destPercent; + for ( current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + blue = qBlue( data[ current ] ); + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + SATURATION_COLOR(red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +void kstyle_baghira_config::sliderButtonRedChanged(int value) +{ + sliderButtonRedValue = value; + dialog_->valueButtonRed->setNum(value); + dialog_->pixmapButtonPreview->setPixmap(*tintButton(baseImage, QColor(sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue))); + dialog_->pixmapButtonPreview->repaint(false); + configChanged(); +} + +void kstyle_baghira_config::sliderButtonGreenChanged(int value) +{ + sliderButtonGreenValue = value; + dialog_->valueButtonGreen->setNum(value); + dialog_->pixmapButtonPreview->setPixmap(*tintButton(baseImage, QColor(sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue))); + dialog_->pixmapButtonPreview->repaint(false); + configChanged(); +} + +void kstyle_baghira_config::sliderButtonBlueChanged(int value) +{ + sliderButtonBlueValue = value; + dialog_->valueButtonBlue->setNum(value); + dialog_->pixmapButtonPreview->setPixmap(*tintButton(baseImage, QColor(sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue))); + dialog_->pixmapButtonPreview->repaint(false); + configChanged(); +} + +void kstyle_baghira_config::sliderBrushRedChanged(int value) +{ + sliderBrushRedValue = value; + dialog_->pixmapBrushPreview->setPixmap(*tintBrush(baseImage2, QColor(sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue))); + dialog_->pixmapBrushPreview->repaint(false); + configChanged(); +} + +void kstyle_baghira_config::sliderBrushGreenChanged(int value) +{ + sliderBrushGreenValue = value; + dialog_->pixmapBrushPreview->setPixmap(*tintBrush(baseImage2, QColor(sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue))); + dialog_->pixmapBrushPreview->repaint(false); + configChanged(); +} + +void kstyle_baghira_config::sliderBrushBlueChanged(int value) +{ + sliderBrushBlueValue = value; + dialog_->pixmapBrushPreview->setPixmap(*tintBrush(baseImage2, QColor(sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue))); + dialog_->pixmapBrushPreview->repaint(false); + configChanged(); +} + +// void kstyle_baghira_config::sliderBrushSaturationChanged(int value) +// { +// sliderBrushSaturationValue = value; +// dialog_->pixmapBrushPreview->setPixmap(*tintBrush(baseImage2, QColor(sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue), sliderBrushSaturationValue)); +// dialog_->pixmapBrushPreview->repaint(false); +// emit changed(true); +// } + +// button color preset table - internal only, AND DON'T CHANGE ONLY ONE! + +enum ColorPreset {Aqua = 0, Graphite, GraphiteDark, Orange, Lime, Black, Smoke, Girlie, Smaragd, Emerald, Yellow, DeepBlueSea, Blood, Turquoise, Lilac, NUMBEROFCOLORS}; + +const char * presetColorName[NUMBEROFCOLORS] = { + "Aqua", "Graphite", "Graphite (Dark)", "Orange", "Lime", "Black", "Smoke", "Girlie", "Smaragd", "Emerald", "Yellow", "Deep Blue Sea", "Blood", "Turquoise", "Lilac" +}; + +int presetColor[NUMBEROFCOLORS][3] = {{84,144,218},{130,170,190},{103,118,134},{200,130,30},{130,180,80},{0,0,0},{106,110,120},{255,130,200},{100,160,75},{255,100,90},{160,160,70},{50,100,200},{150,25,25},{60,170,190},{150,130,220}}; + +// -------------------------------- + +typedef KGenericFactory kstyle_baghira_configFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_kstyle_baghira_config, kstyle_baghira_configFactory("kcmkstyle_baghira_config")) + +//extern QImage uic_findImage(const QString& name); +//extern void qInitImages_baghira(); +//extern void qCleanupImages_baghira(); + +void kstyle_baghira_config::updateCR() +{ + if (!about_->isShown()) + { + timer->stop(); + return; + } + if (crCurrent < 2) + crCurrent++; + else + crCurrent = 0; + about_->crLabel->setText(crNotes[crCurrent]); +} + +void kstyle_baghira_config::showAbout() +{ + crCurrent = 0; + about_->crLabel->setText(crNotes[0]); + timer->start( 4000 ); + about_->exec(); +} + +kstyle_baghira_config::kstyle_baghira_config(QWidget *parent, const char *name, const QStringList&) : QWidget(parent, name )//, myAboutData(0) +{ + loadDone = false; + if (parent) parent->setCaption("Configure Your Cat"); + QVBoxLayout *layout = new QVBoxLayout(this); + dialog_ = new Config(this); + + for (int i = 0; i < NUMBEROFCOLORS; i++) + dialog_->colorPresets->insertItem ( presetColorName[i], i ); + + QWidget *rulesWidget = new QWidget(dialog_->tabWidget); + QHBoxLayout *rwlh = new QHBoxLayout(rulesWidget); + applist = new KListView(rulesWidget); + applist->setFullWidth(true); +#if KDE_IS_VERSION(3,3,91) + applist->setShadeSortColumn(false); +#endif + applist->setAllColumnsShowFocus( true ); + applist->setSelectionMode(QListView::Single); + applist->addColumn ( i18n("Name") ); + applist->addColumn ( i18n("Links to") ); + QDir d( QDir::homeDirPath() + "/.baghira", 0L, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::Readable | QDir::Writable ); + if (!d.exists()) + d.mkdir(QDir::homeDirPath() + "/.baghira"); + else + { + for ( uint i = 0; i < d.count(); i++ ) + { + QFileInfo FI = QFileInfo(d, d[i]); + if (FI.isSymLink()) + applist->insertItem(new KListViewItem(applist, d[i], FI.readLink().section('/',-1,-1))); + else + applist->insertItem(new KListViewItem(applist, d[i])); + } + } + rwlh->addWidget(applist); +// rwlh->addLayout(rwlv); + QVBoxLayout *rwlv = new QVBoxLayout(rwlh); + rwlv->addStretch(); + QPushButton *btnNew = new QPushButton("New...", rulesWidget); + QPushButton *btnEdit = new QPushButton("Edit...", rulesWidget); + QPushButton *btnDel = new QPushButton("Remove", rulesWidget); + QPushButton *btnDet = new QPushButton("Detect", rulesWidget); + rwlv->addWidget(btnNew); + rwlv->addWidget(btnEdit); + rwlv->addWidget(btnDel); + rwlv->addSpacing( 5 ); + rwlv->addWidget(btnDet); + rwlv->addStretch(); + dialog_->tabWidget->addTab( rulesWidget, QString("Rules") ); + appsetter = new AppSetter(this); + connect(btnNew, SIGNAL(clicked()), appsetter, SLOT(show())); + connect(btnEdit, SIGNAL(clicked()), this, SLOT(editApp())); + connect(this, SIGNAL(editApp(QString, QString)), appsetter, SLOT(show(QString, QString))); + connect(btnDel, SIGNAL(clicked()), this, SLOT(removeApp())); + connect(btnDet, SIGNAL(clicked()), this, SLOT(selectWindow())); + connect(appsetter, SIGNAL(addApp(QString, QString)), this, SLOT(addApp(QString, QString))); + connect(appsetter, SIGNAL(removeApp(QString)), this, SLOT(removeApp(QString))); + // preview stuff + baseImage = uic_findImage("button-base"); + + layout->addWidget(dialog_); + + dialog_->show(); + help_ = new Help(dialog_); + about_ = new About(dialog_); + about_->versionLabel->setText(VERSION); + about_->kdeLabel->setText(KDE_VERSION_STRING); + crCurrent = 0; + crNotes[0] = "© 2003-2005 by Thomas Lübking
http://baghira.SourceForge.net
"; + crNotes[1] = "© \"Design\" 2001-2005 by Apple inc.
http://www.apple.com"; + crNotes[2] = "© \"Milk\" 2002-2005 by Max Rudberg
http://www.maxthemes.com
"; + timer = new QTimer(); + connect( timer, SIGNAL(timeout()), this, SLOT(updateCR()) ); + QString tmpString(QT_BUILD_KEY); + about_->systemLabel->setText(tmpString.section(' ',1,1)); + about_->cpuLabel->setText(tmpString.section(' ',0,0)); + about_->setFixedSize (380, 430); + + // connections + // buttons + connect(dialog_->buttonHelp, SIGNAL(clicked()), help_, SLOT(exec())); + connect(dialog_->buttonAbout, SIGNAL(clicked()), this, SLOT(showAbout())); + connect(about_->buttonInfo, SIGNAL(clicked()), this, SLOT(openHtml1())); + connect(about_->buttonDownload, SIGNAL(clicked()), this, SLOT(openHtml2())); + connect(help_->startBAB, SIGNAL(clicked()), this, SLOT(startBab())); + connect(dialog_->startKRuler, SIGNAL(clicked()), this, SLOT(startKRuler())); + connect(dialog_->buttonLoad, SIGNAL(clicked()), this, SLOT(buttonLoadAction())); + connect(dialog_->buttonSaveAs, SIGNAL(clicked()), this, SLOT(buttonSaveAsAction())); + connect(dialog_->colorPresets, SIGNAL(activated(int)), this, SLOT(setPresetColor(int))); + + // changes + connect(dialog_->defaultStyle, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->buttonStyle, SIGNAL(activated(int)), this, SLOT(handleButtonStyles(int))); + connect(dialog_->toolbuttonStyle, SIGNAL(activated(int)), this, SLOT(handleButtonStyles(int))); + connect(dialog_->animateButtons, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->stippleBackground, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->bevelHighlights, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->stippleContrast, SIGNAL(valueChanged (int)), this, SLOT(configChanged())); + connect(dialog_->shadowGroups, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->shadowIntensity, SIGNAL(valueChanged (int)), this, SLOT(configChanged())); + connect(dialog_->centerTabs, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->colorMode, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->inactiveColorType, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->animateSlider, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->shadowSlider, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->squeezeSlider, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->unhoveredToolButtons, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->aquaTabs, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->brushedTabs, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->drawTreeLines, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->useCustomExpanderColor, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->treeLineMode, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->expanderMode, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->useCustomExpanderColor, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->useRectLVH, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->removeKickerBevel, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->replaceMenubar, SIGNAL(toggled(bool)), this, SLOT(menuToggled(bool))); + connect(dialog_->roundTasks, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->showProgressValue, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->progressType, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->menuBackground, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->menuOpacity, SIGNAL(valueChanged (int)), this, SLOT(configChanged())); + connect(dialog_->shadowMenuText, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->menuColorMode, SIGNAL(activated(int)), this, SLOT(configChanged())); + connect(dialog_->useCustomColors, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->drawMenuStripe, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + connect(dialog_->glossyMenus, SIGNAL(stateChanged(int)), this, SLOT(configChanged())); + + connect(dialog_->customInactiveColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); +connect(dialog_->toolbuttonHighColor, SIGNAL(changed(const QColor &)), this, SLOT(changeTooluttonHighlightColor(const QColor &))); + connect(dialog_->treeLineColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->customExpanderColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuTextColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuTextColorHigh, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuColorHigh, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuColor2, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->radioOffColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->radioOnColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->checkOffColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->checkOnColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->sliderColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->hoverSliderColorColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->pressedSliderColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->inactiveTabColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->activeTabColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + connect(dialog_->menuStripeColor, SIGNAL(changed(const QColor &)), this, SLOT(configChanged())); + + connect(dialog_->sliderButtonRed, SIGNAL(valueChanged (int)), this, SLOT(sliderButtonRedChanged(int))); + connect(dialog_->sliderButtonGreen, SIGNAL(valueChanged (int)), this, SLOT(sliderButtonGreenChanged(int))); + connect(dialog_->sliderButtonBlue, SIGNAL(valueChanged (int)), this, SLOT(sliderButtonBlueChanged(int))); + + connect(dialog_->sliderBrushRed, SIGNAL(valueChanged (int)), this, SLOT(sliderBrushRedChanged(int))); + connect(dialog_->sliderBrushGreen, SIGNAL(valueChanged (int)), this, SLOT(sliderBrushGreenChanged(int))); + connect(dialog_->sliderBrushBlue, SIGNAL(valueChanged (int)), this, SLOT(sliderBrushBlueChanged(int))); + + // GUI + connect (dialog_->defaultStyle, SIGNAL(activated(int)), this, SLOT(setDesign(int))); + connect (dialog_->inactiveColorType, SIGNAL(activated(int)), this, SLOT(enableInButtonColor(int))); + connect (dialog_->drawTreeLines, SIGNAL(toggled(bool)), dialog_->treeLineMode, SLOT(setEnabled(bool))); + connect (dialog_->drawTreeLines, SIGNAL(toggled(bool)), dialog_->treeLineColor, SLOT(setEnabled(bool))); + connect (dialog_->useCustomExpanderColor, SIGNAL(toggled(bool)), dialog_->customExpanderColor, SLOT(setEnabled(bool))); + connect (dialog_->menuColorMode, SIGNAL(activated(int)), this, SLOT(enableMenuColorStuff(int))); + connect (dialog_->menuBackground, SIGNAL(activated(int)), this, SLOT(enableMenuColorStuff(int))); + connect (dialog_->drawMenuStripe, SIGNAL(toggled(bool)), dialog_->menuStripeColor, SLOT(setEnabled(bool))); +// connect (dialog_->tintBrush, SIGNAL(toggled(bool)), dialog_->brushBox, SLOT(setEnabled(bool))); + connect (dialog_->useCustomColors, SIGNAL(toggled(bool)), dialog_->colorFrame, SLOT(setEnabled(bool))); + + // load settings + load(); + loadDone = true; + + dialog_->pixmapButtonPreview->setPixmap(*tintButton(baseImage, QColor(sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue))); + +}; + +kstyle_baghira_config::~kstyle_baghira_config() +{ + if (timer) delete timer; +} + +void kstyle_baghira_config::setPresetColor(int i) +{ + dialog_->sliderButtonRed->setValue(presetColor[i][0]); + dialog_->sliderButtonGreen->setValue(presetColor[i][1]); + dialog_->sliderButtonBlue->setValue(presetColor[i][2]); +} + +void kstyle_baghira_config::load() +{ + QString tmpString = QDir::homeDirPath() + "/.qt/baghirarc"; + load (tmpString); +} + +void kstyle_baghira_config::load(QString &fileName) +{ + KConfig *config = new KConfig(fileName); +// QSettings config; + config->setGroup("BAB"); + // general Design + dialog_->defaultStyle->setCurrentItem(config->readNumEntry("defaultState", 0 )); +// config->endGroup(); + config->setGroup("Style"); + dialog_->buttonStyle->setCurrentItem(config->readNumEntry("Special_ButtonStyle", 1 )); + dialog_->toolbuttonStyle->setCurrentItem(config->readNumEntry("Special_ToolbuttonStyle", 1 )); + dialog_->stippleBackground->setChecked( config->readBoolEntry( "Design_StippleBackground", true)); + dialog_->animateButtons->setChecked( config->readBoolEntry( "Design_AnimateButtons", true)); + dialog_->stippleContrast->setValue( config->readNumEntry( "Design_StippleContrast", 3)); + dialog_->shadowGroups->setChecked( config->readBoolEntry( "Design_ShadowGroupBoxes", true)); + dialog_->shadowIntensity->setValue( config->readNumEntry( "Design_GroupBoxeShadowDarkness", 6)); + dialog_->bevelHighlights->setChecked( config->readBoolEntry( "Design_BevelAsHighlight", true)); + dialog_->colorMode->setCurrentItem(config->readNumEntry("Design_ButtonStyle", 0)); + dialog_->inactiveColorType->setCurrentItem(config->readNumEntry( "Design_InactiveButtonStyle", 1)); + dialog_->customInactiveColor->setColor(QColor(config->readNumEntry("Design_InactiveButtonColor",(int)colorGroup().background().rgb()))); + dialog_->centerTabs->setChecked( config->readBoolEntry( "Design_CenterTabs", true)); + // button color stuff + QColor tmpColor = QColor(config->readNumEntry("Design_ButtonColor",(int)colorGroup().button().rgb())); + dialog_->sliderButtonRed->setValue(sliderButtonRedValue = tmpColor.red()); + dialog_->sliderButtonGreen->setValue(sliderButtonGreenValue = tmpColor.green()); + dialog_->sliderButtonBlue->setValue(sliderButtonBlueValue = tmpColor.blue()); + dialog_->valueButtonRed->setNum(sliderButtonRedValue); + dialog_->valueButtonGreen->setNum(sliderButtonGreenValue); + dialog_->valueButtonBlue->setNum(sliderButtonBlueValue); + + // special Widgets + //ListViews + dialog_->useRectLVH->setChecked( config->readBoolEntry( "Special_UseFlatLVH", false)); + dialog_->drawTreeLines->setChecked( config->readBoolEntry( "Special_DrawTreeLines", false)); + dialog_->treeLineMode->setCurrentItem(config->readNumEntry( "Special_TreelineStyle", 0)); + dialog_->treeLineColor->setColor( QColor( config->readNumEntry( "Special_TreelineColor", (int) colorGroup().mid().rgb()))); + dialog_->expanderMode->setCurrentItem(config->readNumEntry( "Special_ExpanderStyle", 0)); + dialog_->useCustomExpanderColor->setChecked( config->readBoolEntry( "Special_CustomExpanderColor", false)); + dialog_->customExpanderColor->setColor( QColor( config->readNumEntry( "Special_ExpanderColor", (int) colorGroup().text().rgb()))); + //Kicker + dialog_->removeKickerBevel->setChecked( config->readBoolEntry( "Special_RemoveKickerBevel", true)); + dialog_->roundTasks->setChecked( config->readBoolEntry( "Special_RoundTaskbuttons", false)); + QFile file(QDir::homeDirPath() + "/.kde/share/apps/kicker/applets/menuapplet.desktop"); + dialog_->replaceMenubar->setChecked( menuReplaced = file.exists() ); + //Scrollbars + dialog_->animateSlider->setChecked( config->readBoolEntry( "Special_AnimateSlider", true)); + dialog_->shadowSlider->setChecked( config->readBoolEntry( "Special_ShadowSlider", false)); + dialog_->squeezeSlider->setChecked( config->readBoolEntry( "Special_SqueezeSlider", false)); + //Progress + dialog_->progressType->setCurrentItem( config->readNumEntry( "Special_ProgressStyle", 0)); + dialog_->showProgressValue->setChecked( config->readBoolEntry( "Special_ShowProgressValue", false)); + //Toolbars + dialog_->unhoveredToolButtons->setCurrentItem(config->readNumEntry( "Special_UnhoveredToolButtons", 2)); + //Tabs + dialog_->aquaTabs->setCurrentItem(config->readNumEntry("Design_TabStyleAqua", 0 )); + dialog_->brushedTabs->setCurrentItem(config->readNumEntry("Design_TabStyleBrushed", 1 )); + + // menus + dialog_->menuBackground->setCurrentItem( config->readNumEntry( "Menu_Background", 0)); + dialog_->menuOpacity->setValue( config->readNumEntry( "Menu_Opacity", 70)); + //Look + dialog_->shadowMenuText->setChecked( config->readBoolEntry( "Menu_ShadowText", true)); + dialog_->menuColorMode->setCurrentItem(config->readNumEntry("Menu_ColorStyle")); + dialog_->menuTextColor->setColor( QColor( config->readNumEntry( "Menu_TextColor", (int) colorGroup().text().rgb()))); + dialog_->menuTextColorHigh->setColor( QColor( config->readNumEntry( "Menu_TextColorHighlight", (int) colorGroup().highlightedText().rgb()))); + dialog_->menuColor->setColor( QColor( config->readNumEntry( "Menu_Color1", (int) colorGroup().background().rgb()))); + dialog_->menuColor2->setColor( QColor( config->readNumEntry( "Menu_Color2", (int) colorGroup().background().dark(130).rgb()))); + dialog_->menuColorHigh->setColor( QColor( config->readNumEntry( "Menu_ColorHighlight", (int) colorGroup().highlight().rgb()))); + dialog_->drawMenuStripe->setChecked(config->readBoolEntry( "Menu_DrawMenuStripe", false)); + dialog_->glossyMenus->setChecked(config->readBoolEntry( "Menu_Glossy", true)); + dialog_->menuStripeColor->setColor( QColor( config->readNumEntry( "Menu_StripeColor", (int) Qt::white.rgb()))); + + // custom colors + dialog_->useCustomColors->setChecked( config->readBoolEntry( "Colors_UseCustomColors", false)); + dialog_->radioOffColor->setColor( QColor( config->readNumEntry( "Colors_RadioOff", ( int ) colorGroup().background().rgb()))); + dialog_->radioOnColor->setColor( QColor( config->readNumEntry( "Colors_RadioOn", ( int ) colorGroup().button().rgb()))); + dialog_->checkOffColor->setColor( QColor( config->readNumEntry( "Colors_CheckOff", ( int ) colorGroup().background().rgb()))); + dialog_->checkOnColor->setColor( QColor( config->readNumEntry( "Colors_CheckOn", ( int ) colorGroup().button().rgb()))); + dialog_->sliderColor->setColor( QColor( config->readNumEntry( "Colors_Slider", ( int ) colorGroup().button().rgb()))); + dialog_->hoverSliderColorColor->setColor(QColor(config->readNumEntry("Colors_SliderHovered",(int)colorGroup().button().rgb()))); + dialog_->pressedSliderColor->setColor(QColor(config->readNumEntry("Colors_SliderPressed",(int) colorGroup().button().dark(110).rgb()))); + dialog_->sliderGrooveColor->setColor(QColor(config->readNumEntry("Colors_SliderGroove",(int)colorGroup().background().rgb()))); + dialog_->inactiveTabColor->setColor(QColor(config->readNumEntry("Colors_TabInactive",(int) colorGroup().background().rgb()))); + dialog_->activeTabColor->setColor(QColor(config->readNumEntry("Colors_TabActive",(int)colorGroup().button().rgb()))); + dialog_->tintBrush->setChecked( config->readBoolEntry( "Colors_TintBrushedMetal", false)); + brushTint = QColor(config->readNumEntry("Colors_BrushTint",(int)colorGroup().background().rgb())); +// dialog_->brushTintSaturaion->setValue(settings.readNumEntry( "/qt/Baghira/brushTintSaturation", 3)); + baseImage2 = uic_findImage("brush-me"); + dialog_->pixmapBrushPreview->setPixmap(*tintBrush(baseImage2, brushTint)); + dialog_->sliderBrushRed->setValue(sliderBrushRedValue = brushTint.red()); + dialog_->sliderBrushGreen->setValue(sliderBrushGreenValue = brushTint.green()); + dialog_->sliderBrushBlue->setValue(sliderBrushBlueValue = brushTint.blue()); + config->setGroup("Menubar"); + dialog_->menuMaxWidth->setValue(config->readNumEntry("Width", QDesktopWidget().availableGeometry().width())); + config->setGroup("Sidebar"); + delete config; + + config = new KConfig("kdeglobals"); + config->setGroup( "Toolbar style" ); + dialog_->toolbuttonHighColor->setColor(config->readColorEntry("HighlightColor", new QColor(103,141,178)) ); + delete config; +} + + +void kstyle_baghira_config::defaults() +{ + dialog_->defaultStyle->setCurrentItem(0); + dialog_->buttonStyle->setCurrentItem(1); + dialog_->toolbuttonStyle->setCurrentItem(1); + dialog_->animateButtons->setChecked( true); + dialog_->stippleBackground->setChecked( true); + dialog_->stippleContrast->setValue( 30); + dialog_->shadowGroups->setChecked( true); + dialog_->shadowIntensity->setValue( 50); + dialog_->bevelHighlights->setChecked( true ); + dialog_->centerTabs->setChecked( true); + dialog_->colorMode->setCurrentItem(0); + dialog_->inactiveColorType->setCurrentItem(1); + dialog_->customInactiveColor->setColor(colorGroup().background().rgb()); + // button color stuff + dialog_->sliderButtonRed->setValue(sliderButtonRedValue = colorGroup().button().red()); + dialog_->sliderButtonGreen->setValue(sliderButtonGreenValue = colorGroup().button().green()); + dialog_->sliderButtonBlue->setValue(sliderButtonBlueValue = colorGroup().button().blue()); + dialog_->valueButtonRed->setNum(sliderButtonRedValue); + dialog_->valueButtonGreen->setNum(sliderButtonGreenValue); + dialog_->valueButtonBlue->setNum(sliderButtonBlueValue); + + // special Widgets +// dialog_->animateSlider; + dialog_->shadowSlider->setChecked( false); + dialog_->squeezeSlider->setChecked( false); + dialog_->unhoveredToolButtons->setCurrentItem(2); + dialog_->toolbuttonHighColor->setColor( QColor(103,141,178) ); + dialog_->drawTreeLines->setChecked( false); + dialog_->useCustomExpanderColor->setChecked( false); + dialog_->treeLineMode->setCurrentItem(0); + dialog_->treeLineColor->setColor( colorGroup().mid().rgb()); + dialog_->expanderMode->setCurrentItem(0); + dialog_->customExpanderColor->setColor( colorGroup().text().rgb()); + dialog_->useRectLVH->setChecked( false); + dialog_->removeKickerBevel->setChecked( true); + dialog_->roundTasks->setChecked( false); + dialog_->showProgressValue->setChecked( false); + dialog_->progressType->setCurrentItem( 0); + dialog_->aquaTabs->setCurrentItem( 0 ); + dialog_->brushedTabs->setCurrentItem(1); + + // menus +// dialog_->transGroup; + dialog_->menuBackground->setCurrentItem(0); + dialog_->menuOpacity->setValue( 70); + dialog_->shadowMenuText->setChecked( true); + dialog_->menuColorMode->setCurrentItem(0); + dialog_->menuTextColor->setColor( colorGroup().text().rgb()); + dialog_->menuTextColorHigh->setColor( colorGroup().highlightedText().rgb()); + dialog_->menuColor->setColor( colorGroup().background().rgb()); + dialog_->menuColor2->setColor( colorGroup().background().dark(130).rgb()); + dialog_->menuColorHigh->setColor( colorGroup().highlight().rgb()); + dialog_->drawMenuStripe->setChecked(false); + dialog_->glossyMenus->setChecked(true); + dialog_->menuStripeColor->setColor( Qt::white.rgb()); + + // custom colors + dialog_->useCustomColors->setChecked( false); + dialog_->radioOffColor->setColor( colorGroup().background().rgb()); + dialog_->radioOnColor->setColor( colorGroup().button().rgb()); + dialog_->checkOffColor->setColor( colorGroup().background().rgb()); + dialog_->checkOnColor->setColor( colorGroup().button().rgb()); + dialog_->sliderColor->setColor( colorGroup().button().rgb()); + dialog_->hoverSliderColorColor->setColor(colorGroup().button().rgb()); + dialog_->pressedSliderColor->setColor(colorGroup().button().dark(110).rgb()); + dialog_->sliderGrooveColor->setColor(colorGroup().background().rgb()); + dialog_->inactiveTabColor->setColor(colorGroup().background().rgb()); + dialog_->activeTabColor->setColor(colorGroup().button().rgb()); + dialog_->tintBrush->setChecked( false); + emit changed(true); +} + +void kstyle_baghira_config::save() +{ + QString tmpString = QDir::homeDirPath() + "/.qt/baghirarc"; + save(tmpString); +// emit changed(true); +} + +void kstyle_baghira_config::changeTooluttonHighlightColor(const QColor & color) +{ + KConfig *config = new KConfig("kdeglobals"); + config->setGroup( "Toolbar style" ); + config->writeEntry("HighlightColor", color); + delete config; +} + +void kstyle_baghira_config::handleButtonStyles(int i) +{ + if (i != 2 && sender() == dialog_->buttonStyle && dialog_->toolbuttonStyle->currentItem() != 2) + dialog_->toolbuttonStyle->setCurrentItem(i); + else if (i != 2 && sender() == dialog_->toolbuttonStyle && dialog_->buttonStyle->currentItem() != 2) + dialog_->buttonStyle->setCurrentItem(i); + configChanged(); +} + +void kstyle_baghira_config::save(QString &fileName) +{ +// QSettings *config = new QSettings; + KConfig *config = new KConfig(fileName); + config->setGroup("BAB"); + //General Design + config->writeEntry("defaultState", dialog_->defaultStyle->currentItem()); +// config->endGroup(); + config->setGroup("Style"); + config->writeEntry("Special_ButtonStyle", dialog_->buttonStyle->currentItem()); + config->writeEntry("Special_ToolbuttonStyle", dialog_->toolbuttonStyle->currentItem()); + config->writeEntry("Design_AnimateButtons", dialog_->animateButtons->isOn()); + config->writeEntry("Design_Default", dialog_->defaultStyle->currentItem()); + config->writeEntry("Design_StippleBackground", dialog_->stippleBackground->isOn()); + config->writeEntry("Design_StippleContrast", dialog_->stippleContrast->value()); + config->writeEntry("Design_ShadowGroupBoxes", dialog_->shadowGroups->isOn()); + config->writeEntry("Design_GroupBoxeShadowDarkness", dialog_->shadowIntensity->value()); + config->writeEntry("Design_BevelAsHighlight", dialog_->bevelHighlights->isOn()); + config->writeEntry("Design_ButtonStyle", dialog_->colorMode->currentItem()); + config->writeEntry("Design_InactiveButtonStyle", dialog_->inactiveColorType->currentItem()); + config->writeEntry("Design_InactiveButtonColor", (int)dialog_->customInactiveColor->color().rgb()); + config->writeEntry("Design_CenterTabs", dialog_->centerTabs->isOn()); + //button color stuff + config->writeEntry("Design_ButtonColor", (int)(QColor(sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue).rgb())); + + // special Widgets + //listviews +// dialog_->animateSlider; + config->writeEntry("Special_UseFlatLVH", dialog_->useRectLVH->isOn()); + config->writeEntry("Special_DrawTreeLines", dialog_->drawTreeLines->isOn()); + config->writeEntry("Special_TreelineStyle", dialog_->treeLineMode->currentItem()); + config->writeEntry("Special_TreelineColor", (int)dialog_->treeLineColor->color().rgb()); + config->writeEntry("Special_ExpanderStyle", dialog_->expanderMode->currentItem()); + config->writeEntry("Special_CustomExpanderColor", dialog_->useCustomExpanderColor->isOn()); + config->writeEntry("Special_ExpanderColor", (int)dialog_->customExpanderColor->color().rgb()); + //Kicker + config->writeEntry("Special_RemoveKickerBevel", dialog_->removeKickerBevel->isOn()); + config->writeEntry("Special_RoundTaskbuttons", dialog_->roundTasks->isOn()); + QDir tmpDir(QDir::homeDirPath() + "/.kde"); + if (!tmpDir.exists()) tmpDir.mkdir(QDir::homeDirPath() + "/.kde"); + tmpDir.setPath(QDir::homeDirPath() + "/.kde/share"); + if (!tmpDir.exists()) tmpDir.mkdir(QDir::homeDirPath() + "/.kde/share"); + tmpDir.setPath(QDir::homeDirPath() + "/.kde/share/apps"); + if (!tmpDir.exists()) tmpDir.mkdir(QDir::homeDirPath() + "/.kde/share/apps"); + tmpDir.setPath(QDir::homeDirPath() + "/.kde/share/apps/kicker"); + if (!tmpDir.exists()) tmpDir.mkdir(QDir::homeDirPath() + "/.kde/share/apps/kicker"); + tmpDir.setPath(QDir::homeDirPath() + "/.kde/share/apps/kicker/applets"); + if (!tmpDir.exists()) tmpDir.mkdir(QDir::homeDirPath() + "/.kde/share/apps/kicker/applets"); + QFile file(QDir::homeDirPath() + "/.kde/share/apps/kicker/applets/menuapplet.desktop"); + if (dialog_->replaceMenubar->isOn()) + { + file.open(IO_WriteOnly); + const char *msg = +"[Desktop Entry]\n\ +Hidden=true\n\ +Type=Plugin\n\ +Encoding=UTF-8\n\ +Name=BaghiraMenu\n\ +X-KDE-Library=b_menu_panelapplet\n\ +X-KDE-UniqueApplet=true\n"; + file.writeBlock( msg, qstrlen(msg) ); + file.close(); + } + else + file.remove(); + if (dialog_->replaceMenubar->isOn() != menuReplaced) + KApplication::dcopClient()->send("kicker", "default", "restart()", ""); + //Srollbars + config->writeEntry("Special_AnimateSlider", dialog_->animateSlider->isOn()); + config->writeEntry("Special_ShadowSlider", dialog_->shadowSlider->isOn()); + config->writeEntry("Special_SqueezeSlider", dialog_->squeezeSlider->isOn()); + //Progress + config->writeEntry("Special_ProgressStyle", dialog_->progressType->currentItem()); + config->writeEntry("Special_ShowProgressValue", dialog_->showProgressValue->isOn()); + //Toolbars + config->writeEntry("Special_UnhoveredToolButtons", dialog_->unhoveredToolButtons->currentItem()); + //Tabs + config->writeEntry("Design_TabStyleAqua", dialog_->aquaTabs->currentItem() ); + config->writeEntry("Design_TabStyleBrushed", dialog_->brushedTabs->currentItem() ); + // menus + config->writeEntry("Menu_Background", dialog_->menuBackground->currentItem()); + config->writeEntry("Menu_Opacity", dialog_->menuOpacity->value()); + //Look + config->writeEntry("Menu_ShadowText", dialog_->shadowMenuText->isOn()); + config->writeEntry("Menu_ColorStyle", dialog_->menuColorMode->currentItem()); + config->writeEntry("Menu_TextColor", (int)dialog_->menuTextColor->color().rgb()); + config->writeEntry("Menu_TextColorHighlight", (int)dialog_->menuTextColorHigh->color().rgb()); + config->writeEntry("Menu_Color1", (int)dialog_->menuColor->color().rgb()); + config->writeEntry("Menu_Color2", (int)dialog_->menuColor2->color().rgb()); + config->writeEntry("Menu_ColorHighlight", (int)dialog_->menuColorHigh->color().rgb()); + config->writeEntry("Menu_DrawMenuStripe", dialog_->drawMenuStripe->isOn()); + config->writeEntry("Menu_Glossy", dialog_->glossyMenus->isOn()); + config->writeEntry("Menu_StripeColor", (int)dialog_->menuStripeColor->color().rgb()); + + // custom colors + config->writeEntry("Colors_UseCustomColors", dialog_->useCustomColors->isOn()); + config->writeEntry("Colors_RadioOff", (int)dialog_->radioOffColor->color().rgb()); + config->writeEntry("Colors_RadioOn", (int)dialog_->radioOnColor->color().rgb()); + config->writeEntry("Colors_CheckOff",(int) dialog_->checkOffColor->color().rgb()); + config->writeEntry("Colors_CheckOn", (int)dialog_->checkOnColor->color().rgb()); + config->writeEntry("Colors_Slider",(int) dialog_->sliderColor->color().rgb()); + config->writeEntry("Colors_SliderHovered", (int)dialog_->hoverSliderColorColor->color().rgb()); + config->writeEntry("Colors_SliderPressed", (int)dialog_->pressedSliderColor->color().rgb()); + config->writeEntry("Colors_SliderGroove",(int) dialog_->sliderGrooveColor->color().rgb()); + config->writeEntry("Colors_TabInactive",(int) dialog_->inactiveTabColor->color().rgb()); + config->writeEntry("Colors_TabActive", (int)dialog_->activeTabColor->color().rgb()); + config->writeEntry("Colors_TintBrushedMetal", dialog_->tintBrush->isOn()); + config->writeEntry("Colors_BrushTint",(int)qRgb(sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue)); + config->setGroup("Menubar"); + config->writeEntry("Width", dialog_->menuMaxWidth->value()); + config->sync(); +// config->endGroup(); + delete config; +} + + +void kstyle_baghira_config::configChanged() +{ + if (loadDone) + { + dialog_->statusWarning->setText("Config changed"); + emit changed(true); + } +} + + +QString kstyle_baghira_config::quickHelp() const +{ + return i18n("Configure Your Cat"); +} + +void kstyle_baghira_config::setDesign(int d) +{ + bool b = (d == 0); + dialog_->stippleBackground->setEnabled(b); + dialog_->stippleContrast->setEnabled(b); + dialog_->shadowGroups->setEnabled(b); + dialog_->shadowIntensity->setEnabled(b); +} + +void kstyle_baghira_config::enableInButtonColor(int d) +{ + dialog_->customInactiveColor->setEnabled(d == 3); +} + +void kstyle_baghira_config::enableMenuColorStuff(int d) +{ + bool b = (d == 2); + dialog_->menuTextColor->setEnabled(b); + dialog_->menuColor->setEnabled(b && dialog_->menuBackground->currentItem() > 0); + dialog_->menuColor2->setEnabled(b && dialog_->menuBackground->currentItem() > 1); +} + +void kstyle_baghira_config::buttonLoadAction() +{ + QString tmpString = KFileDialog::getOpenFileName(QDir::homeDirPath(), "*", this, "Select a Baghira config file"); + if (!tmpString.isEmpty()) + load(tmpString); +} + +void kstyle_baghira_config::buttonSaveAsAction() +{ + QString tmpString = KFileDialog::getSaveFileName(QDir::homeDirPath(), "*", this, "Save current Baghira configuration as"); + save(tmpString); +} + +void kstyle_baghira_config::editApp() +{ + emit editApp(applist->currentItem()->text(0), applist->currentItem()->text(1)); +} + +void kstyle_baghira_config::removeApp() +{ + QString string = QDir::homeDirPath() + "/.baghira/" + applist->currentItem()->text(0); + QFile::remove(string); + applist->takeItem(applist->currentItem()); +} + +void kstyle_baghira_config::removeApp(QString name) +{ + QString string = QDir::homeDirPath() + "/.baghira/" + name; + QFile::remove(string); + applist->takeItem(applist->findItem(name, 0, Qt::ExactMatch)); +} + +void kstyle_baghira_config::addApp(QString string, QString linkString) +{ + applist->insertItem(new KListViewItem(applist, string, linkString)); + applist->sort(); +} + +void kstyle_baghira_config::selectWindow() +// taken from kcmkwin +{ + // use a dialog, so that all user input is blocked + // use WX11BypassWM and moving away so that it's not actually visible + // grab only mouse, so that keyboard can be used e.g. for switching windows + grabber = new QDialog( NULL, NULL, true, WX11BypassWM ); + grabber->move( -1000, -1000 ); + grabber->show(); + grabber->grabMouse( crossCursor ); + grabber->installEventFilter( this ); +} + +Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False ); +// Atom wm_state = XInternAtom( qt_xdisplay(), "WM_COMMAND", False ); + +bool kstyle_baghira_config::eventFilter( QObject* o, QEvent* e ) +// adapted from kcmkwin... again ;) +{ + if( o != grabber ) + return false; + if( e->type() != QEvent::MouseButtonRelease ) + return false; + delete grabber; + grabber = NULL; + if( static_cast< QMouseEvent* >( e )->button() != LeftButton ) + return true; + WId winId = findWindow(); + XClassHint classHint; + if (XGetClassHint(qt_xdisplay(), winId, &classHint)) + { + QString tmpString = QString( classHint.res_class ).lower() + " (uncertain)"; + appsetter->show(tmpString, QString()); +// qWarning("class: %s",QString( classHint.res_class ).lower().ascii()); + XFree( classHint.res_name ); + XFree( classHint.res_class ); + } + return true; +} + +WId kstyle_baghira_config::findWindow() +// taken from kcmkwin... as well =) +{ + Window root; + Window child; + uint mask; + int rootX, rootY, x, y; + Window parent = qt_xrootwin(); +// Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False ); + for( int i = 0; + i < 10; + ++i ) + { + XQueryPointer( qt_xdisplay(), parent, &root, &child, + &rootX, &rootY, &x, &y, &mask ); + if( child == None ) + return 0; + Atom type; + int format; + unsigned long nitems, after; + unsigned char* prop; + if( XGetWindowProperty( qt_xdisplay(), child, wm_state, 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &prop ) == Success ) + { + if( prop != NULL ) + XFree( prop ); + if( type != None ) + return child; + } + parent = child; + } + return 0; +} + + +void kstyle_baghira_config::menuToggled(bool active) +{ + if (!active || !loadDone) + return; + KConfigGroup menuConfig(KGlobal::config(), "KDE"); + if (!menuConfig.readBoolEntry("macStyle", false)) + if (KMessageBox::questionYesNo(0, i18n("You just selected to replace kickers menu applet for the Mac like Menubar on top of the screen, but the Mac like style isn't selected anyway
Do you want to activate it now?
"), 0L, KStdGuiItem::yes(), KStdGuiItem::no()) == KMessageBox::Yes) + { + KProcess proc; + proc << "kcmshell" << "desktopbehavior"; + proc.start(KProcess::DontCare); + proc.detach(); + } + configChanged(); +} + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + QWidget* allocate_kstyle_config(QWidget* parent){ + return(new kstyle_baghira_config(parent, "BaghiraConfig")); + } +} + +AppSetter::AppSetter(QWidget *parent, const char *name) : QWidget(parent, name, Qt::WType_Dialog | Qt::WShowModal ) +{ + isEdit = FALSE; + + QLabel *label1 = new QLabel(i18n("Application Name"), this); + command = new QLineEdit(this); + + QLabel *linkTo = new QLabel(i18n("Just like"),this); + link = new QComboBox(this); + + box = new QGroupBox(2,Qt::Horizontal,i18n("Custom Settings"),this); + box->setCheckable( true ); + + new QLabel(i18n("Style"), box); + new QLabel("Deco", box); + + style = new QComboBox(box); + style->insertItem(i18n("Don't set")); + style->insertItem("Jaguar"); + style->insertItem("Panther"); + style->insertItem("Brushed Metal"); + style->insertItem("Tiger"); + style->insertItem("Milk"); + + deco = new QComboBox(box); + deco->insertItem(i18n("Don't set")); + deco->insertItem("Jaguar"); + deco->insertItem("Panther"); + deco->insertItem("Brushed Metal"); + deco->insertItem("Tiger"); + deco->insertItem("Milk"); + + new QLabel(i18n("Buttons"), box); + new QLabel(i18n("Toolbuttons"), box); + + buttons = new QComboBox(box); + buttons->insertItem("Jaguar"); + buttons->insertItem("Panther"); + buttons->insertItem("iTunes"); + buttons->insertItem("Tiger"); + buttons->insertItem("Milk"); + + + toolButtons = new QComboBox(box); + toolButtons->insertItem("Jaguar"); + toolButtons->insertItem("Panther"); + toolButtons->insertItem("iTunes"); + toolButtons->insertItem("Tiger"); + toolButtons->insertItem("Milk"); + + new QLabel(i18n("Tab vs. Chooser"), box); + new QLabel(i18n("Inactive Button"), box); + + tabs = new QComboBox(box); + tabs->insertItem(i18n("Don't set")); + tabs->insertItem("Tabs"); + tabs->insertItem("Adaptive"); + tabs->insertItem("Choosers"); + + + inbutton = new QComboBox(box); + inbutton->insertItem("Fixed"); + inbutton->insertItem("Background"); + inbutton->insertItem("Active Button"); + + scanlines = new QCheckBox("Show scanlines", box); + + QWidget *dumb = new QWidget(box); + customColors = new QCheckBox(dumb); + buttonColors = new QPushButton("Custom Colors", dumb); + QHBoxLayout *clh = new QHBoxLayout(dumb); + clh->addWidget(customColors); + clh->addWidget(buttonColors); + + QVBoxLayout *lv = new QVBoxLayout(this,11,6); + lv->addWidget(label1); + lv->addWidget(command); + QHBoxLayout *lh0 = new QHBoxLayout(lv); + lh0->addWidget(linkTo); + lh0->addWidget(link); + lv->addWidget(box); + QHBoxLayout *lh = new QHBoxLayout(lv); + QPushButton *cancel = new QPushButton("Cancel",this); + lh->addWidget(cancel); + QPushButton *ok = new QPushButton("Ok",this); + lh->addWidget(ok); + + colorDialog = new ColorDialog(this); + + connect(box, SIGNAL(toggled( bool )), link, SLOT(setDisabled(bool))); + connect(box, SIGNAL(toggled( bool )), linkTo, SLOT(setDisabled(bool))); + connect(style, SIGNAL(activated( int )), this, SLOT(handler(int))); + connect(buttons, SIGNAL(activated( int )), this, SLOT(handleButtonStyles(int))); + connect(toolButtons, SIGNAL(activated( int )), this, SLOT(handleButtonStyles(int))); + connect(cancel, SIGNAL(clicked()), this, SLOT(reset())); + connect(ok, SIGNAL(clicked()), this, SLOT(save())); + connect(customColors, SIGNAL(toggled( bool )), buttonColors, SLOT(setEnabled(bool))); + connect(buttonColors, SIGNAL(clicked()), colorDialog, SLOT(exec())); + connect(colorDialog->buttonOk, SIGNAL(clicked()), this, SLOT(updateColors())); + connect(colorDialog->buttonCancel, SIGNAL(clicked()), this, SLOT(resetColorPicker())); + reset(); +} + +AppSetter::~AppSetter() +{ +} + +void AppSetter::handleButtonStyles(int i) +{ + if (i != 2 && sender() == buttons && toolButtons->currentItem() != 2) + toolButtons->setCurrentItem(i); + else if (i != 2 && sender() == toolButtons && buttons->currentItem() != 2) + buttons->setCurrentItem(i); +} + +void AppSetter::handler(int i) +{ + scanlines->setEnabled(i != 3); +} + +void AppSetter::updateColors() +{ + for (int i = 0; i < 8; i++) + colors[i] = (int)colorDialog->picker[i]->color().rgb(); +} + +void AppSetter::show() +{ + link->clear(); + QDir d( QDir::homeDirPath() + "/.baghira", 0L, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks | QDir::Readable | QDir::Writable ); + for ( uint i = 0; i < d.count(); i++ ) + link->insertItem(d[i]); + QWidget::show(); +} + +void AppSetter::show(QString appName, QString linkString) +{ + isEdit = true; + oldName = appName; + oldLink = linkString; + command->setText(appName); + FILE *file = NULL; + QString tmpString = QDir::homeDirPath() + "/.baghira/" + appName; + if( (file = fopen(tmpString.latin1(), "r")) != NULL ) + { + uint s, d, b, t, tc, sc, ib; + s = d = 4; + b = t = sc = 2; + tc = 3; + for (int i = 0; i < 8; i++) + colors[i] = -1; + fscanf(file,"%u\n%u\n%u\n%u\n%u\n%u\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",&s,&d,&b,&t,&tc,&sc,&colors[0],&colors[1],&colors[2],&colors[3],&colors[4],&colors[5],&colors[6],&colors[7],&ib); + fclose(file); + if (s < 5) style->setCurrentItem(s+1); + if (d < 5) deco->setCurrentItem(d+1); + if (b < 5) buttons->setCurrentItem(b); + if (t < 5) toolButtons->setCurrentItem(t); + if (tc < 3) tabs->setCurrentItem(tc+1); + if (ib < 3) inbutton->setCurrentItem(ib); + scanlines->setChecked(sc < 2 ? sc : true); + scanlines->setEnabled(s != 2); + customColors->setChecked(colors[0] != -1); + buttonColors->setEnabled(customColors->isChecked()); + resetColorPicker(); + } + show(); + if (!linkString.isNull()) + { + for (int i = 0; i < link->count(); i++) + { + if (link->text(i) == linkString) + { + link->setCurrentItem(i); + break; + } + } + } + else + { + box->setChecked(true); + } +} + +void AppSetter::resetColorPicker() +{ + if (colors[0] != -1) + { + for (int i = 0; i < 8; i++) + { + colorDialog->picker[i]->blockSignals(true); + colorDialog->picker[i]->setColor(QColor(colors[i])); + colorDialog->picker[i]->blockSignals(false); + } + ((QWidget*)colorDialog->demo)->repaint(false); + } + else + { + for (int i = 0; i < 8; i++) + colorDialog->picker[i]->blockSignals(true); + colorDialog->picker[Back]->setColor(colorGroup().background()); + colorDialog->picker[Button]->setColor(colorGroup().button()); + colorDialog->picker[Base]->setColor(colorGroup().base()); + colorDialog->picker[Text]->setColor(colorGroup().text()); + colorDialog->picker[High]->setColor(colorGroup().highlight()); + colorDialog->picker[HighText]->setColor(colorGroup().highlightedText()); + colorDialog->picker[ButText]->setColor(colorGroup().buttonText ()); + colorDialog->picker[Alternate]->setColor(KGlobalSettings::alternateBackgroundColor()); + for (int i = 0; i < 8; i++) + colorDialog->picker[i]->blockSignals(false); + ((QWidget*)colorDialog->demo)->repaint(false); + } +} + +void AppSetter::save() +{ + if (command->text() != "" && (!box->isChecked() || (style->currentItem() != 0 && deco->currentItem() != 0))) + { + if (!isEdit) + emit addApp(command->text(), box->isChecked() ? QString() : link->currentText()); + else if (command->text() != oldName || link->currentText() != oldLink) + { + emit removeApp(oldName); + emit addApp(command->text(), box->isChecked() ? QString() : link->currentText()); + } + if (!customColors->isChecked()) + { + for (int i = 0; i < 8; i++) + colors[i] = -1; + } + FILE *file = NULL; + QString tmpString = QDir::homeDirPath() + "/.baghira/" + command->text(); + if (box->isChecked()) // custom settings + { + if( (file = fopen(tmpString.latin1(), "w")) != NULL ) + { + fprintf(file,"%u\n%u\n%u\n%u\n%u\n%u\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",style->currentItem()-1, deco->currentItem()-1, buttons->currentItem(), toolButtons->currentItem(), tabs->currentItem()-1, scanlines->isChecked(), colors[0], colors[1], colors[2], colors[3], colors[4], colors[5], colors[6], colors[7], inbutton->currentItem()); + fclose(file); + } + } + else // just link + { + QString tmpString2 = QDir::homeDirPath() + "/.baghira/" + link->currentText(); + QFile::remove(tmpString); // just to be sure ;) + symlink (tmpString2.latin1(), tmpString.latin1()); + } + } + reset(); +} + +void AppSetter::reset() +{ + hide(); + isEdit = false; + style->setCurrentItem(0); + deco->setCurrentItem(0); + buttons->setCurrentItem(1); + inbutton->setCurrentItem(0); + toolButtons->setCurrentItem(1); + tabs->setCurrentItem(0); + scanlines->setChecked(false); + command->clear(); + customColors->setChecked(false); + for (int i = 0; i < 8; i++) + colors[i] = -1; + box->setChecked ( false ); +} + +#include "kstyle_baghira_config.moc" diff --git a/config/kstyle_baghira_config.h b/config/kstyle_baghira_config.h new file mode 100644 index 0000000..35830dd --- /dev/null +++ b/config/kstyle_baghira_config.h @@ -0,0 +1,163 @@ +/*************************************************************************** + * Copyright (C) 2004 by Thomas Lübking * + * thomas@home * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _KSTYLE_BAGHIRA_CONFIG_H_ +#define _KSTYLE_BAGHIRA_CONFIG_H_ + +//#include +#include +#include +#include +#include "configdialog.h" +#include "help.h" +#include "about.h" + +class KListView; +class QPushButton; +class AppSetter; +class QTimer; +class QCheckBox; +class QComboBox; +class QGroupBox; + +class kstyle_baghira_config: public QWidget +{ + Q_OBJECT + +public: + kstyle_baghira_config( QWidget *parent=0, const char *name=0, const QStringList& = QStringList() ); + ~kstyle_baghira_config(); + + virtual void load(); + void load(QString &fileName); + void save(QString &fileName); +// virtual int buttons(); + virtual QString quickHelp() const; + virtual const KAboutData *aboutData()const + { return myAboutData; }; + +public slots: + void configChanged(); + void openHtml1(); + void openHtml2(); + void startBab(); + void startKRuler(); + void sliderButtonRedChanged(int); + void sliderButtonGreenChanged(int); + void sliderButtonBlueChanged(int); + void sliderBrushRedChanged(int); + void sliderBrushGreenChanged(int); + void sliderBrushBlueChanged(int); + virtual void save(); + virtual void defaults(); + +signals: + void changed(bool); + void editApp(QString, QString); + +protected: + bool eventFilter( QObject* o, QEvent* e ); + +private: + QString crNotes[3]; + AppSetter *appsetter; + KListView *applist; + QImage* tintButton(QImage &src, QColor c); + QImage* tintBrush( QImage &img, QColor c/*, int saturation*/ ); + WId findWindow(); + KAboutData *myAboutData; + Config *dialog_; + Help* help_; + About* about_; + QImage baseImage, baseImage2; + QDialog *grabber; + QColor buttonColor; + QColor brushTint; + int sliderButtonRedValue, sliderButtonGreenValue, sliderButtonBlueValue; + int sliderBrushRedValue, sliderBrushGreenValue, sliderBrushBlueValue/*, sliderBrushSaturationValue*/; + bool loadDone; + bool menuReplaced; + QTimer *timer; + int crCurrent; +private slots: + void updateCR(); + void showAbout(); + void editApp(); + void addApp(QString, QString); + void removeApp(); + void removeApp(QString); + void setDesign(int); + void menuToggled(bool); + void enableInButtonColor(int d); + void enableMenuColorStuff(int d); + void buttonLoadAction(); + void buttonSaveAsAction(); + void setPresetColor(int i); + void selectWindow(); + void changeTooluttonHighlightColor(const QColor &); + void handleButtonStyles(int i); +}; + +class ColorDialog; + +class AppSetter : public QWidget +{ +Q_OBJECT +public: + AppSetter(QWidget *parent=0, const char *name=0); + ~AppSetter(); +public slots: + void show(); + void show(QString appName, QString link); + +private: + bool isEdit; + int index_; + int colors[8]; + QString oldName; + QString oldLink; + QLineEdit *command; + QComboBox *link; + QGroupBox *box; + QComboBox *style; + QComboBox *deco; + QComboBox *buttons; + QComboBox *toolButtons; + QComboBox *tabs; + QComboBox *inbutton; + QCheckBox *scanlines; + QCheckBox *customColors; + QPushButton *buttonColors; + ColorDialog *colorDialog; + +signals: + void addApp(QString, QString); + void removeApp(QString); + +private slots: + void save(); + void reset(); + void handler(int); + void updateColors(); + void resetColorPicker(); + void handleButtonStyles(int i); +}; + +#endif diff --git a/configure.files b/configure.files new file mode 100644 index 0000000..09c5968 --- /dev/null +++ b/configure.files @@ -0,0 +1,5 @@ +./admin/configure.in.min +configure.in.in +./kickermenu/configure.in.in +./sidebar/configure.in.in +./style/configure.in.in diff --git a/configure.in.in b/configure.in.in new file mode 100644 index 0000000..778345c --- /dev/null +++ b/configure.in.in @@ -0,0 +1,6 @@ +#MIN_CONFIG(3.0.0) +KDE_USE_QT(3.3.0) + +AM_INIT_AUTOMAKE(baghira, cvs) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN diff --git a/deco/Doxyfile b/deco/Doxyfile new file mode 100644 index 0000000..f90d99c --- /dev/null +++ b/deco/Doxyfile @@ -0,0 +1,247 @@ +# Doxyfile 1.3.5-KDevelop + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = baghira_deco.kdevelop +PROJECT_NUMBER = $VERSION$ +OUTPUT_DIRECTORY = +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/thomas/Desktop/baghira-deco-2/client +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm \ + *.dox +RECURSIVE = yes +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = yes +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/deco/Makefile.am b/deco/Makefile.am new file mode 100644 index 0000000..6d435f2 --- /dev/null +++ b/deco/Makefile.am @@ -0,0 +1,28 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = config + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) -I$(kde_includes)/kwin + +kwindir = $(kde_datadir)/kwin/ +kwin_DATA = baghira.desktop + +EXTRA_DIST = $(kwin_DATA) images + +noinst_HEADERS = baghiraclient.h pixmaps.h masks.h + +kde_module_LTLIBRARIES = kwin3_baghira.la +kwin3_baghira_la_SOURCES = baghiraclient.cc +kwin3_baghira_la_LIBADD = $(kde_libraries)/libkdecorations.la +kwin3_baghira_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -lkdecore -module +kwin3_baghira_la_METASOURCES = AUTO + +DISTCLEANFILES = $(kwin3_baghira_la_METASOURCES) + +pixmaps.h: $(srcdir)/generatePixmaps.sh + $(SHELL) $(srcdir)/generatePixmaps.sh $(top_srcdir) +CLEANFILES = pixmaps.h +baghiraclient.lo: pixmaps.h + diff --git a/deco/baghira.desktop b/deco/baghira.desktop new file mode 100644 index 0000000..1514386 --- /dev/null +++ b/deco/baghira.desktop @@ -0,0 +1,5 @@ +# KDE Desktop Entry +[Desktop Entry] +Encoding=UTF-8 +Name=Baghira +X-KDE-Library=kwin3_baghira diff --git a/deco/baghiraclient.cc b/deco/baghiraclient.cc new file mode 100644 index 0000000..30d6c8d --- /dev/null +++ b/deco/baghiraclient.cc @@ -0,0 +1,2636 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraclient.h +// ------------------- +// Baghira window decoration for KDE +// ------------------- +// Copyright (c) 2004, 2005 Thomas Lübking +// Please see the header file for copyright and license information. +////////////////////////////////////////////////////////////////////////////// + +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "baghiraclient.h" +#include "pixmaps.h" +#include "masks.h" +#include "config.h" + +#define COLOR_SPACE(R,G,B) \ + if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \ + if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \ + if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255; + +#define SATURATION_COLOR(R,G,B) \ + grey = (299 * R + 587 * G + 114 * B) / 1000; \ + delta = 255 - grey; \ + grey = (grey *(10 - 5)) / 10; \ + iGrey = 255 - grey;\ + destR = (iGrey * (srcR - delta) + grey * R) / 255; \ + destG = (iGrey * (srcG - delta) + grey * G) / 255; \ + destB = (iGrey * (srcB - delta) + grey * B) / 255; + +#define CLAMP(x,l,u) x < l ? l :\ + x > u ? u :\ + x + +#define SATURATION_COLOR2(S,R,G,B,cR,cG,cB) \ + int max = 255+0.65*(100-S); \ + destR = CLAMP((cR + R - 128), 0, max); \ + destG = CLAMP((cG + G - 128), 0, max); \ + destB = CLAMP((cB + B - 128), 0, max); \ + destR = (S*destR + (100-S)*R)/100; \ + destG = (S*destG + (100-S)*G)/100; \ + destB = (S*destB + (100-S)*B)/100; + +using namespace Baghira; + +static const int BUTTONSIZE = 15; +static const int MENUBUTTONWIDTH = 20; +static const int DECOSIZE = 8; +int TITLESIZE;// = 26; +static const int TITLESIZESMALL = 18; +static const int MARGIN = 6; + +////////////////////////////////////////////////////////////////////////////// +// BaghiraFactory Class // +////////////////////////////////////////////////////////////////////////////// + +bool BaghiraFactory::initialized_ = false; +Baghira::TitlebarType BaghiraFactory::effect_[5][2]; +Qt::AlignmentFlags BaghiraFactory::titlealign_; +QColor BaghiraFactory::colors_[5][ ColorTypeCount ][ 2 ]; +KPixmap BaghiraFactory::pix_[5][ PixmapTypeCount ][ 2 ][ 2 ]; +int BaghiraFactory::bordersize_[5] = {0,0,6,0,0};//{BorderTiny, BorderTiny, BorderVeryHuge}; +QPixmap BaghiraFactory::ButtonPixmap_[5][WindowStateAmount][ButtonTypeAmount][ButtonStateAmount][2]; +QColor BaghiraFactory::brushedMetalColor; +QColor BaghiraFactory::ButtonColor_[ButtonTypeAmount+1]; +QPixmap BaghiraFactory::nostalgia_[5][3][2]; +int BaghiraFactory::contrast_; +int BaghiraFactory::_3DImpact_[5]; +int BaghiraFactory::LineImpact_[5]; +bool BaghiraFactory::bgStipple_; +bool BaghiraFactory::comicFrame_; +bool BaghiraFactory::addAutoSpacing_; +bool BaghiraFactory::maxResizable_; +bool BaghiraFactory::shape_ul[5]; +bool BaghiraFactory::shape_ur[5]; +bool BaghiraFactory::shape_ll[5]; +bool BaghiraFactory::shape_lr[5]; +bool BaghiraFactory::allowEasyClosing_; +bool BaghiraFactory::resizeGrip_; +uint BaghiraFactory::defaultMode_; +bool BaghiraFactory::drawIcon_[5]; +bool BaghiraFactory::tintBrush_; +bool BaghiraFactory::showTitle_; +QColor BaghiraFactory::brushTint; +int BaghiraFactory::minimumTitleHeight_; +ButtonStyle BaghiraFactory::buttonStyle_[5]; + +QBitmap BaghiraFactory::helpMask; +QBitmap BaghiraFactory::jaguarDownMask; +QBitmap BaghiraFactory::jaguarMenuDownMask; +QBitmap BaghiraFactory::jaguarMenuMask; +QBitmap BaghiraFactory::jaguarMask; +QBitmap BaghiraFactory::milkMenuDownMask; +QBitmap BaghiraFactory::milkMenuMask; +QBitmap BaghiraFactory::milkMask; +QBitmap BaghiraFactory::pantherMenuMask; +QBitmap BaghiraFactory::pantherMask; +QBitmap BaghiraFactory::milkDownMask; +QBitmap BaghiraFactory::arrowUp; +QBitmap BaghiraFactory::arrowDown; +DeMaximizer BaghiraFactory::deMaximizer_; +bool BaghiraFactory::fullSpec_; +bool BaghiraFactory::noModalDeco_; +bool BaghiraFactory::delAppname_; + +Atom baghira_deco_design = XInternAtom(qt_xdisplay(), "BAGHIRA_DECO_DESIGN", False); + +extern "C" KDecorationFactory* create_factory() { + return new Baghira::BaghiraFactory(); +} + +DeMaximizer::DeMaximizer() : QWidget(0, "deMaximizer", Qt::WType_TopLevel | Qt::WStyle_NoBorder | Qt::WX11BypassWM ) +{ + client_ = 0L; + setFixedSize(16,16); + setMouseTracking(TRUE); + setAutoMask(TRUE); + move(QApplication::desktop()->availableGeometry().right()-17,QApplication::desktop()->availableGeometry().top()+2); + setBackgroundMode( NoBackground ); +// setBackgroundMode (Qt::X11ParentRelative); +// setPaletteBackgroundColor(Qt::green); +} + +void DeMaximizer::mouseReleaseEvent( QMouseEvent *) +{ + hasMouse()?setState(1):setState(0); + if (client_) client_->demaxButtonPressed(); +} + +void DeMaximizer::mousePressEvent ( QMouseEvent *) +{ + setState(2); +} + +void DeMaximizer::enterEvent ( QEvent *) +{ + setState(1); +} + +void DeMaximizer::leaveEvent ( QEvent *) +{ + setState(0); +} + +void DeMaximizer::setState(int i) +{ + erase(); + QPainter p(this); + p.drawPixmap(0,0,pixmap[i]); + p.end(); +} + +void DeMaximizer::setPixmap(int i, QImage &image ) +{ + pixmap[i] = QPixmap(image); +} + + +void DeMaximizer::setClient(BaghiraClient *client) +{ + if (client_) + { + QObject::disconnect ( client_, SIGNAL(hide()), this, SLOT(hide()) ); + client_ = 0L; + } + if (client) + { + client_ = client; + connect ( client_, SIGNAL(hide()), SLOT(hide()) ); + setState(0); + } +// repaint(); +} + +#if KDE_IS_VERSION(3,3,91) +////////////////////////////////////////////////////////////////////////////// +// ResizeHandle() +// --------------- +// Constructor +ResizeHandle::ResizeHandle(BaghiraClient * parent) : QWidget(parent->widget(), 0, 0) +{ + if (!parent->widget()) + return; + client = parent; + setCursor(QCursor(Qt::SizeFDiagCursor)); + setFixedSize(16,16); + updateLook(FALSE); + WId root, daddy = 0; + WId *kids = 0L; + uint numKids = 0; + XQueryTree(qt_xdisplay(), parent->windowId(), &root, &daddy, &kids, &numKids); + if (daddy) + XReparentWindow( qt_xdisplay(), winId(), daddy, 0, 0 ); + else return; + move(client->width()-2*BaghiraFactory::borderSize(parent->currentStyle)-16,client->height()-client->titleheight_-16); + shape(); + parent->widget()->installEventFilter(this); + raise(); + show(); +} + +void ResizeHandle::updateLook(bool rp) +{ + pix = QPixmap(16,16); + QPainter p(&pix); + p.fillRect(pix.rect(), BaghiraFactory::effect(client->currentStyle, client->isActive()) == Baghira::Brushed ? BaghiraFactory::BrushedMetalColor().light(110):paletteBackgroundColor()); + p.setPen( BaghiraFactory::effect(client->currentStyle, client->isActive()) == Baghira::Brushed ? Qt::black:paletteForegroundColor() ); + p.drawLine(0,16,16,0); + p.drawLine(4,16,16,4); + p.drawLine(8,16,16,8); + p.drawLine(12,16,16,12); + p.end(); + setPaletteBackgroundPixmap(pix); + if (rp) repaint(); +} + +void ResizeHandle::shape() +{ + XRectangle* xrects = new XRectangle[16]; + for (int i = 0; i < 16; i++) + { + xrects[ i ].x = 15-i; + xrects[ i ].y = i; + xrects[ i ].width = i+1; + xrects[ i ].height = 1; + } + XShapeCombineRectangles( qt_xdisplay(), winId(), ShapeBounding, 0, 0, + xrects, 16, ShapeSet, 0 ); + delete[] xrects; +} + +bool ResizeHandle::eventFilter(QObject *obj, QEvent *e) +{ + if ( obj != parent() ) + return false; + if ( e->type() == QEvent::Resize) + { + if (client->maximizeMode() == BaghiraClient::MaximizeFull) + move(client->width() - 16, client->height() - client->titleheight_ - 16); + else + move(client->width() - 2*BaghiraFactory::borderSize(client->currentStyle) - 16, client->height() - client->titleheight_ - BaghiraFactory::borderSize(client->currentStyle) - 16); +// shape(); + return FALSE; + } + return FALSE; +} + +void ResizeHandle::mousePressEvent ( QMouseEvent * ) +{ + client->performWindowOperation(/*Unrestricted*/KDecoration::ResizeOp); +} +void ResizeHandle::mouseReleaseEvent ( QMouseEvent * ) +{ + client->performWindowOperation(KDecoration::NoOp); + repaint(TRUE); +} +void ResizeHandle::paintEvent ( QPaintEvent * ) +{ + QPainter p(this); + p.drawPixmap(0,0,pix); +} + +#endif + +////////////////////////////////////////////////////////////////////////////// +// BaghiraFactory() +// --------------- +// Constructor + +BaghiraFactory::BaghiraFactory() { + helpMask = QBitmap( 14, 15, help_bits, true ); + jaguarDownMask = QBitmap( 14, 15, jaguar2_bits, true ); + jaguarMenuDownMask = QBitmap( 20, 15, jaguar_menu_down_bits, true ); + jaguarMenuMask = QBitmap( 20, 15, jaguar_menu_bits, true ); + jaguarMask = QBitmap( 14, 15, jaguar_bits, true ); + milkMenuDownMask = QBitmap( 20, 15, milk_menu_down_bits, true ); + milkMenuMask = QBitmap( 20, 15, milk_menu_bits, true ); + milkMask = QBitmap( 14, 15, milk_bits, true ); + pantherMenuMask = QBitmap( 20, 15, panther_menu_bits, true ); + pantherMask = QBitmap( 14, 15, panther_bits, true ); + milkDownMask = QBitmap( 14, 15, milk_pressed_bits, true ); + arrowUp = QBitmap( 8, 4, arrowUp_bits, true ); + arrowUp.setMask( arrowUp ); + arrowDown = QBitmap( 8, 4, arrowDown_bits, true ); + arrowDown.setMask( arrowDown ); + readConfig(); + createPixmaps(); + initialized_ = true; +} + +////////////////////////////////////////////////////////////////////////////// +// ~BaghiraFactory() +// ---------------- +// Destructor + +BaghiraFactory::~BaghiraFactory() +{ + deMaximizer_.setClient(NULL); + initialized_ = false; +} + +////////////////////////////////////////////////////////////////////////////// +// createDecoration() +// ------------------ +// Create the decoration + +KDecoration* BaghiraFactory::createDecoration( KDecorationBridge* b ) { + return new BaghiraClient( b, this ); +} + +////////////////////////////////////////////////////////////////////////////// +// reset() +// ------- +// Reset the handler. Returns true if decorations need to be remade + +QString BaghiraFactory::indexedString(QString s, int i){ + QString result; + result.setNum(i+1); + result.prepend("_"); + result.prepend(s); +// qWarning("%s",result.ascii()); + return result; +} + +bool BaghiraFactory::reset( unsigned long changed ) { + initialized_ = false; + changed |= readConfig(); + if ( changed & ( SettingColors | SettingDecoration | SettingBorder ) ) { + createPixmaps(); + } + initialized_ = true; + + if ( changed & ( SettingColors | SettingDecoration | SettingFont | + SettingButtons | SettingBorder ) ) { + return true; + } else { + resetDecorations( changed ); + return false; + } +} + +////////////////////////////////////////////////////////////////////////////// +// readConfig() +// ------------ +// Read in the configuration file + +unsigned long BaghiraFactory::readConfig() { + + QSettings config; + config.beginGroup("/baghira/Style"); +// KConfig config( "baghirarc" ); +// config.setGroup( "Style" ); + bgStipple_ = config.readBoolEntry( "Design_StippleBackground", false); + contrast_ = config.readNumEntry( "Design_StippleContrast", 30 ); + tintBrush_ = config.readBoolEntry( "Colors_TintBrushedMetal", false ); + if (tintBrush_) + brushTint.setRgb( config.readNumEntry( "Colors_BrushTint")); + + QColor oldcolor; + unsigned long changed = 0; + oldcolor = colors_[3][ Baghira::ColorTitleBar ][ false ]; + colors_[3][ Baghira::ColorTitleBar ][ false ] = qApp->palette().active().background(); + if ( oldcolor != colors_[3][ Baghira::ColorTitleBar ][ false ] ) + changed |= SettingColors; + + oldcolor = colors_[3][ Baghira::ColorTitleBlend ][ false ]; + colors_[3][ Baghira::ColorTitleBlend ][ false ] = colors_[3][ Baghira::ColorTitleBar ][ false ].dark(100 + config.readNumEntry( "Design_StippleContrast", 3)); + if ( oldcolor != colors_[3][ Baghira::ColorTitleBlend ][ false ] ) + changed |= SettingColors; + + config.endGroup(); + config.beginGroup( "/baghira/Deco" ); + + + // common settings + + bool oldNoModalDeco = noModalDeco_; + noModalDeco_ = config.readBoolEntry( "NoModalDeco", false ); + if (oldNoModalDeco != noModalDeco_) + changed |= SettingDecoration; + + bool oldDelAppname = delAppname_; + delAppname_ = config.readBoolEntry( "RemoveAppname", true ); + if (oldDelAppname != delAppname_) + changed |= SettingDecoration; + + int oldMinTH = minimumTitleHeight_; + minimumTitleHeight_ = (ButtonStyle) config.readNumEntry( "minimumTitleHeight", 18 ); + if ( oldMinTH != minimumTitleHeight_ ) + { + QFontMetrics fm(options()->font(true, false)); + TITLESIZE = QMAX(minimumTitleHeight_, fm.height()); + changed |= SettingFont; + changed |= SettingDecoration; + } + + bool allowEasyClosing__ = allowEasyClosing_; + allowEasyClosing_ = config.readBoolEntry( "allowEasyClosing", false ); + if ( allowEasyClosing__ != allowEasyClosing_ ) + changed |= SettingDecoration; + + bool resizeGrip__ = resizeGrip_; + resizeGrip_ = config.readBoolEntry( "ResizeGrip", false ); + if ( resizeGrip__ != resizeGrip_ ) + changed |= SettingDecoration; + + bool defaultMode__ = defaultMode_; + defaultMode_ = config.readNumEntry( "defaultMode", 1 ); + if ( defaultMode__ != defaultMode_ ) + changed |= SettingDecoration; + + Qt::AlignmentFlags oldalign = titlealign_; + QString value = config.readEntry( "TitleAlignment", "AlignHCenter" ); + showTitle_ = TRUE; + if ( value == "AlignLeft" ) + titlealign_ = Qt::AlignLeft; + else if ( value == "AlignHCenter" ) + titlealign_ = Qt::AlignHCenter; + else if ( value == "AlignRight" ) + titlealign_ = Qt::AlignRight; + else if ( value == "noTitle" ) + { + showTitle_ = FALSE; + titlealign_ = Qt::AlignAuto; + } + if ( oldalign != titlealign_ ) + changed |= SettingFont; + + bool oldComic = comicFrame_; + comicFrame_ = config.readBoolEntry( "DrawComicFrame", false ); + if ( oldComic != comicFrame_ ) + changed |= SettingBorder; changed |= SettingDecoration; + + bool oldAutoSpacing = addAutoSpacing_; + addAutoSpacing_ = config.readBoolEntry( "AddAutoSpacing", true ); + if ( oldAutoSpacing != addAutoSpacing_ ) + changed |= SettingDecoration; + + bool oldMaxResizable = maxResizable_; + maxResizable_ = config.readBoolEntry( "MaxResizable", true ); + if ( oldMaxResizable != maxResizable_ ) + changed |= SettingDecoration; + + bool oldSpec = fullSpec_; + fullSpec_ = config.readBoolEntry( "FullSpec", false ); + if ( oldSpec != fullSpec_ ) + changed |= SettingDecoration; + + // custom settings + + for (int i = 0; i < 5; i++){ + + int oldbordersize = bordersize_[i]; + bordersize_[i] = config.readNumEntry( indexedString("BorderSize",i), i == 2 ? 6 : 0 ); + if ( oldbordersize != bordersize_[i] ) + changed |= SettingBorder; + + ButtonStyle oldButtons = buttonStyle_[i]; + buttonStyle_[i] = (ButtonStyle) config.readNumEntry( indexedString("ButtonStyle",i), i == 0 ? 1 : 0 ); + if ( oldButtons != buttonStyle_[i] ) + changed |= SettingDecoration; + + + bool oldShUL = shape_ul[i]; + shape_ul[i] = config.readBoolEntry( indexedString("ShapeUL",i), true ); + if ( oldShUL != shape_ul[i] ){ + changed |= SettingBorder; changed |= SettingDecoration; + } + + bool oldShUR = shape_ur[i]; + shape_ur[i] = config.readBoolEntry( indexedString("ShapeUR",i), true ); + if ( oldShUR != shape_ur[i] ){ + changed |= SettingBorder; changed |= SettingDecoration; + } + + bool oldShLL = shape_ll[i]; + shape_ll[i] = config.readBoolEntry( indexedString("ShapeLL",i), i == 2 ); + if ( oldShLL != shape_ll[i] ){ + changed |= SettingBorder; changed |= SettingDecoration; + } + + bool oldShLR = shape_lr[i]; + shape_lr[i] = config.readBoolEntry( indexedString("ShapeLR",i), i == 2 ); + if ( oldShLR != shape_lr[i] ){ + changed |= SettingBorder; changed |= SettingDecoration; + } + + + bool oldDrawIcon_ = drawIcon_[i]; + drawIcon_[i] = config.readBoolEntry( indexedString("drawIcon",i), true ); + if ( oldDrawIcon_ = drawIcon_[i] ) + changed |= SettingFont; + changed |= SettingDecoration; + + if (i != 3) + { + Baghira::TitlebarType oldeffect = effect_[i][1]; + effect_[i][1] = ( Baghira::TitlebarType ) config.readNumEntry( indexedString("TitleEffect",i), i == 0 ? Baghira::Stipples : (i == 1 || i == 4) ? Baghira::Gradient : Baghira::Brushed); + // qWarning("%d",effect_[i]); + if ( oldeffect != effect_[i][1] ) + changed |= SettingDecoration; + + oldeffect = effect_[i][0]; + effect_[i][0] = ( Baghira::TitlebarType ) config.readNumEntry( indexedString("inactiveTitleEffect",i), i == 0 ? Baghira::Stipples : (i == 1 || i == 4) ? Baghira::Gradient : Baghira::Brushed); + // qWarning("%d",effect_[i]); + if ( oldeffect != effect_[i][0] ) + changed |= SettingDecoration; + + int oldLineImpact = LineImpact_[i]; + LineImpact_[i] = config.readNumEntry( indexedString("LineImpact",i), i == 2 ? 0 : 40 ); + if ( oldLineImpact != LineImpact_[i] ) + changed |= SettingDecoration; + + oldcolor = colors_[i][ Baghira::ColorTitleBar ][ false ]; + colors_[i][ Baghira::ColorTitleBar ][ false ].setRgb((unsigned int)config.readNumEntry( indexedString("inactiveColor1",i), i == 0 ? QColor(204,214,230).rgb() : i == 1 ? QColor(246,242,246).rgb() : i == 3 ? QColor(200,200,200).rgb() : QColor(230,230,230).rgb())); + if ( oldcolor != colors_[i][ Baghira::ColorTitleBar ][ false ] ) + changed |= SettingColors; + + oldcolor = colors_[i][ Baghira::ColorTitleBlend ][ false ]; + colors_[i][ Baghira::ColorTitleBlend ][ false ].setRgb((unsigned int)config.readNumEntry( indexedString("inactiveColor2",i), i == 0 ? QColor(194,196,211).rgb() : i == 1 ? QColor(238,238,238).rgb() : i == 3 ? QColor(150,150,150).rgb() : QColor(250,250,250).rgb())); + if ( oldcolor != colors_[i][ Baghira::ColorTitleBlend ][ false ] ) + changed |= SettingColors; + } + else + { + effect_[3][1] = Baghira::Gradient; + effect_[3][0] = Baghira::FlatStipples; + LineImpact_[3] = 0; + } + + int old3DImpact = _3DImpact_[i]; + _3DImpact_[i] = config.readNumEntry( indexedString("3DImpact",i), 20 ); + if ( old3DImpact != _3DImpact_[i] ) + changed |= SettingDecoration; + + oldcolor = colors_[i][ Baghira::ColorTitleBar ][ true ]; + colors_[i][ Baghira::ColorTitleBar ][ true ].setRgb((unsigned int)config.readNumEntry( indexedString("activeColor1",i), i == 0 ? QColor(255,255,255).rgb() : i == 1 ? QColor(238,238,238).rgb() : i == 2 ? QColor(202,202,202).rgb() : i == 3 ? QColor(238,238,238).rgb() : QColor(250,250,250).rgb())); + if ( oldcolor != colors_[i][ Baghira::ColorTitleBar ][ true ] ) + changed |= SettingColors; + + oldcolor = colors_[i][ Baghira::ColorTitleBlend ][ true ]; + colors_[i][ Baghira::ColorTitleBlend ][ true ].setRgb((unsigned int)config.readNumEntry( indexedString("activeColor2",i), i == 0 ? QColor(238,234,238).rgb() : i == 1 ? QColor(205,202,205).rgb() : i == 2 ? QColor(150,150,150).rgb() : i == 3 ? QColor(211,208,211).rgb() : QColor(230,230,230).rgb())); + if ( oldcolor != colors_[i][ Baghira::ColorTitleBlend ][ true ] ) + changed |= SettingColors; + + } + + oldcolor = ButtonColor_[MinButton]; + ButtonColor_[MinButton].setRgb((unsigned int)config.readNumEntry( "MinButtonColor", QColor(230,155,40).rgb() )); + if ( oldcolor != ButtonColor_[MinButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[MaxButton]; + ButtonColor_[MaxButton].setRgb((unsigned int)config.readNumEntry( "MaxButtonColor", QColor(121,180,54).rgb() )); + if ( oldcolor != ButtonColor_[MaxButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[CloseButton]; + ButtonColor_[CloseButton].setRgb((unsigned int)config.readNumEntry( "CloseButtonColor", QColor(200,85,70).rgb() )); + if ( oldcolor != ButtonColor_[CloseButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[StickyButton]; + ButtonColor_[StickyButton].setRgb((unsigned int)config.readNumEntry( "StickyButtonColor", QColor(74,140,242).rgb() )); + if ( oldcolor != ButtonColor_[StickyButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[AboveBelowButton]; + ButtonColor_[AboveBelowButton].setRgb((unsigned int)config.readNumEntry( "AboveButtonColor", QColor(74,140,242).rgb() )); + if ( oldcolor != ButtonColor_[AboveBelowButton] ) + changed |= SettingColors; + oldcolor = ButtonColor_[ShadeButton]; + ButtonColor_[ShadeButton].setRgb((unsigned int)config.readNumEntry( "ShadeButtonColor", QColor(74,140,242).rgb() )); + if ( oldcolor != ButtonColor_[ShadeButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[MenuButton]; + ButtonColor_[MenuButton].setRgb((unsigned int)config.readNumEntry( "MenuButtonColor", QColor(74,140,242).rgb() )); + if ( oldcolor != ButtonColor_[MenuButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[HelpButton]; + ButtonColor_[HelpButton].setRgb((unsigned int)config.readNumEntry( "HelpButtonColor", QColor(0,0,0).rgb() )); + if ( oldcolor != ButtonColor_[HelpButton] ) + changed |= SettingColors; + + oldcolor = ButtonColor_[InactiveButton]; + ButtonColor_[InactiveButton].setRgb((unsigned int)config.readNumEntry( "InactiveButtonColor", QColor(255,255,255).rgb() )); + if ( oldcolor != ButtonColor_[InactiveButton] ) + changed |= SettingColors; + + + config.endGroup(); + return changed; +} + +QImage* BaghiraFactory::tintGlossy( const QImage &src, const QColor &c ) const +{ + QImage *dest = new QImage( src.width(), src.height(), 32); + dest->setAlphaBuffer( true ); + unsigned int *data = ( unsigned int * ) src.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = src.width() * src.height(); + int u3rd = src.width()*4; + int red, green, blue; + int destR, destG, destB, alpha; + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + // float srcPercent, destPercent; + for ( int current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + if (alpha < 230){ + destData[ current ] = data[ current ]; + continue; //do not handle translucent parts to not affect blending + } + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + blue = qBlue( data[ current ] ); + if ( current > u3rd || red < 223 ){ + SATURATION_COLOR2(sq, red, green, blue, srcR, srcG, srcB) + } else { + SATURATION_COLOR2(sq, red, green, blue, 255, 255, 255); + } + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +QImage* BaghiraFactory::tintBrush( const QImage &img, const QColor &c ) const +{ + +// if ( img.depth() != 32 ) +// img = img.convertDepth( 32 ); + QImage *dest = new QImage( img.width(), img.height(), 32); + unsigned int *data = ( unsigned int * ) img.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = img.width() * img.height(); + int current; + int delta; + int red, green, blue, grey, iGrey; + int destR, destG, destB, alpha; + + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + + SATURATION_COLOR(180, 180, 180); + COLOR_SPACE(destR, destG, destB); + brushedMetalColor = QColor(destR, destG, destB); + + // float srcPercent, destPercent; + for ( current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + blue = qBlue( data[ current ] ); + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + SATURATION_COLOR(red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +void BaghiraFactory::createOS8Buttons(int style){ + QPainter p; + QColor initColor; + for ( int active = 0; active <= 1; ++active ){ + for (int t = 0; t < 3; t++){ + initColor = QColor(color(style, Baghira::ColorTitleBar, active ).dark(100 + t*15)); + nostalgia_[style][t][active] = QPixmap(BUTTONSIZE, BUTTONSIZE); + p.begin(&nostalgia_[style][t][active]); + p.setPen(color(style, Baghira::ColorTitleBar, active )); + p.drawPoint(0,BUTTONSIZE-1); + p.drawPoint(BUTTONSIZE-1,0); + p.setPen(initColor); + // dark color + // outer relief =============================== + p.drawLine(0,0,0,BUTTONSIZE-2); + p.drawLine(0,0,BUTTONSIZE-2,0); + // ============================================= + // inner relief ================================ + if (t < 2){ + p.drawLine(3,BUTTONSIZE-3,BUTTONSIZE-3,BUTTONSIZE-3); + p.drawLine(BUTTONSIZE-3,3,BUTTONSIZE-3,BUTTONSIZE-3); + } + else{ + p.drawLine(2,2,2,BUTTONSIZE-4); + p.drawLine(2,2,BUTTONSIZE-4,2); + } + // ======================================== + for (int i = 0; i < BUTTONSIZE - 6; i++){ + if (i == BUTTONSIZE - 7){ + p.drawPoint(2, BUTTONSIZE - 3); + p.drawPoint(BUTTONSIZE - 3, 2); + } + for (int j = 0; j < i+1; j++){ + p.setPen(initColor.light(100 + (i + j)*3)); + p.drawPoint(i+3,j+3); + if (i != j) p.drawPoint(j+3,i+3); + } + } + // Color is now Bright ;-) + // inner relief =============================== + if (t < 2){ + p.drawLine(2,2,2,BUTTONSIZE-4); + p.drawLine(2,2,BUTTONSIZE-4,2); + } + else{ + p.drawLine(3,BUTTONSIZE-3,BUTTONSIZE-3,BUTTONSIZE-3); + p.drawLine(BUTTONSIZE-3,3,BUTTONSIZE-3,BUTTONSIZE-3); + } + // ================================ + // outer relief ====================================== + p.drawLine(1,BUTTONSIZE-1,BUTTONSIZE-1,BUTTONSIZE-1); + p.drawLine(BUTTONSIZE-1,1,BUTTONSIZE-1,BUTTONSIZE-1); + //================================== + // black frame + p.setPen(Qt::black); + p.drawRect(1,1,BUTTONSIZE-2,BUTTONSIZE-2); + p.end(); + } + } +} + +QPixmap &BaghiraFactory::ButtonPixmap( Baghira::WindowState wState, + Baghira::ButtonType type, Baghira::ButtonState state, int style, bool small ) { + return ButtonPixmap_[style][ wState ][ type ][ state ][small]; +} + +QImage* BaghiraFactory::DecoImage( QPixmap *pix, int x, int y, int width, int height ) { + QPixmap tmpPix( width, height ); + bitBlt ( &tmpPix, 0, 0, pix, x, y, width, height ); + QImage *returnImage = new QImage( tmpPix.convertToImage() ); + return returnImage; +} + +/////////////////////////////////////////////////////////////////////////// +// createGradient() +// ---------------- +// Create a gradient + +void BaghiraFactory::createGradient(KPixmap &pix, const QColor &light, const QColor &dark, Baghira::TitlebarType effect) +{ + if (pix.width() == 0) return; + + QPainter p; + switch( effect ){ + case Baghira::Stipples: + KPixmapEffect::unbalancedGradient(pix, light, light.dark(110), KPixmapEffect::VerticalGradient, 0); + p.begin(&pix); + p.setPen(dark); + for( int i = 0; i < pix.height(); i+=4 ){ + p.drawLine(0,i,pix.width(),i); + p.drawLine(0,i+1,pix.width(),i+1); + } + p.end(); + break; + case Baghira::FlatStipples: + { + p.begin(&pix); + p.fillRect(pix.rect(),light); + QColor mid; + mid.setRgb((light.red()+2*dark.red())/3,(light.green()+2*dark.green())/3,(light.blue()+2*dark.blue())/3); + p.setPen(mid); + for( int i = pix.height() - 1; i > 0; i-=4 ) + { + p.drawLine(0,i,pix.width(),i); + p.drawLine(0,i-2,pix.width(),i-2); + } + p.setPen(dark); + for( int i = pix.height() - 2; i > 0; i-=4 ) + { + p.drawLine(0,i,pix.width(),i); + } + p.end(); + break; + } + case Baghira::Nostalgia: + p.begin(&pix); + p.fillRect(pix.rect(),light); + p.setPen(light.light(120)); + for (int i = (pix.height() - 1) / 4; i < (pix.height() - 1) / 4 * 3 + 1; i +=2) + p.drawLine(0,i,pix.width()-1,i); + p.setPen(light.dark(120)); + for (int i = (pix.height() - 1) / 4; i < (pix.height() - 1) / 4 * 3 + 1; i +=2) + p.drawLine(0,i+1,pix.width()-1,i+1); + p.end(); + break; + case Baghira::Gradient: + default: + KPixmapEffect::gradient(pix, light, dark, KPixmapEffect::VerticalGradient, 0); + break; + } +} + +static bool blend( const QImage & upper, const QImage & lower, QImage & output) +// adopted from kimageeffect::blend - what is not endian safe... +{ + if + ( + upper.width() > lower.width() || + upper.height() > lower.height() || + upper.depth() != 32 || + lower.depth() != 32 + ) + return false; + + output = lower.copy(); + + register uchar *i, *o; + register int a; + register int col; + register int w = upper.width(); + int row(upper.height() - 1); + + do + { + i = upper.scanLine(row); + o = output.scanLine(row); + + col = w << 2; + + --col; + + do + { +#ifdef WORDS_BIGENDIAN + while (!(a = i[col-3]) && (col != 3)) +#else + while (!(a = i[col]) && (col != 3)) +#endif + { + --col; --col; --col; --col; + } +#ifndef WORDS_BIGENDIAN + --col; +#endif + o[col] += ((i[col] - o[col]) * a) >> 8; + + --col; + o[col] += ((i[col] - o[col]) * a) >> 8; + + --col; + o[col] += ((i[col] - o[col]) * a) >> 8; + +#ifdef WORDS_BIGENDIAN + --col; +#endif + + } while (col--); + } while (row--); + return true; +} + +////////////////////////////////////////////////////////////////////////////// +// createPixmaps() +// --------------- +// Create all our pixmaps +void BaghiraFactory::createPixmaps() { +// QPainter painter; + QColorGroup group; + QPainter icyAPainter; + QImage tmpResult; + QImage tmpResult2; + QImage tmpDeco; + QImage buttonImage; + QImage btnIcons[MenuButton]; + btnIcons[AboveBelowButton] = QImage(); + // load icon images - useless for nostalgia style, but i assume they'll be used at least once ;) + btnIcons[MinButton] = uic_findImage( "icon_minimize" ); + btnIcons[MaxButton] = uic_findImage( "icon_maximize" ); + btnIcons[CloseButton] = uic_findImage( "icon_close" ); + btnIcons[StickyButton] = uic_findImage( "icon_sticky" ); +// btnIcons[AboveBelowButton] = uic_findImage( "icon_above" ); + btnIcons[ShadeButton] = uic_findImage( "icon_shade" ); + + int B_3 = 0; + int B_6 = 0; +// int bt, bs; + int xoff = 0; + int yoff = 1; + bool brushedMode; + + for (int style = 0; style < 5; style++){ + for ( int active = 0; active <= 1; ++active ) { + for ( int small = 0; small <= 1; ++small ) { + KPixmap &tbar = pix_[style][ TitleBar ][ active ][ small ]; + KPixmap &tcenter = pix_[style][ TitleCenter ][ active ][ small ]; + brushedMode = effect_[style][active] == Baghira::Brushed; + + // create gradients and fills + // if (effect_ == Baghira::Gradient || effect_ == Baghira::Stipples /*|| effect_ == Baghira::Glossy * / + if (effect_[style][active] < Baghira::Glossy || effect_[style][active] == Baghira::FlatStipples){ + // resize pixmap + tbar.resize( 100, small ? TITLESIZESMALL : TITLESIZE ); + createGradient( tbar, color(style, Baghira::ColorTitleBar, active ), color(style, Baghira::ColorTitleBlend, active ), effect_[style][active] ); + } + else if (brushedMode){ + QPixmap brushTile; + QPixmap brushGradient; + if (tintBrush_){ + brushTile = QPixmap(*tintBrush(uic_findImage( "brushed-tile" ), brushTint)); + brushGradient = QPixmap(*tintBrush(uic_findImage( "brushed-gradient" ), brushTint)); + } + else{ + brushTile = uic_findImage( "brushed-tile" ); + brushGradient = uic_findImage( "brushed-gradient" ); + brushedMetalColor = QColor(180,180,180); + } + // resize pixmap + tbar.resize( 256, small ? TITLESIZESMALL : TITLESIZE ); + tcenter.resize( 1024, small ? TITLESIZESMALL : TITLESIZE ); + QPainter painter(&tbar); + painter.drawTiledPixmap( 0,0, tbar.width(), tbar.height(), brushTile ); + painter.end(); + painter.begin(&tcenter); + painter.drawTiledPixmap( 0,0, tcenter.width(), tcenter.height(), brushGradient ); + } + else{ + tbar.resize( 32, small ? TITLESIZESMALL : TITLESIZE); + KPixmap tmp = QPixmap(*tintGlossy(uic_findImage( "deco_glossy" ), color(style, Baghira::ColorTitleBar, active ))); + if (tbar.height() > 18){ + for (int i = 8; i < tbar.height() - 10; i++){ + bitBlt(&tbar, 0, i, &tmp, 0, 8, 32, 1); + } + } + bitBlt(&tbar, 0, tbar.height() - 11, &tmp, 0, 9, 32, 10); + bitBlt(&tbar, 0, 0, &tmp, 0, 0, 32, 8); + } + + switch ( buttonStyle_[style] ) { + + // Load Jaguar Buttons ========================================================================= + + case Jaguar: + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, BUTTONSIZE, BUTTONSIZE ); + + // unpressed buttons + buttonImage = uic_findImage( "button_jaguar"); + + for (int bt = MinButton; bt < MenuButton; bt++){ + for (int bs = ButtonInactive; bs < Pressed; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs == ButtonInactive ? + ButtonColor_[InactiveButton] : + ButtonColor_[bt] ); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + if (bs > ButtonActive) blend( btnIcons[bt], tmpResult, tmpResult ); + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( tmpResult ); + } + } + + // pressed buttons // as jaguar buttons shift + buttonImage = uic_findImage( "button_jaguar_down"); + + for (int bt = MinButton; bt < MenuButton; bt++){ + tmpResult2 = *tintGlossy( buttonImage, ButtonColor_[bt].dark(120)); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + KImageEffect::blendOnLower( xoff, yoff, btnIcons[bt], tmpResult); // must shift as well + ButtonPixmap_[style][ active ][ bt ][ Pressed ][small] = QPixmap( tmpResult ); + } + + + // HelpButton + buttonImage = uic_findImage( "icon_help"); + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs == ButtonInactive ? + ButtonColor_[InactiveButton] : + bs == Hovered ? + ButtonColor_[HelpButton].light(120) : + bs == Pressed ? + ButtonColor_[HelpButton].dark(120) : + ButtonColor_[HelpButton] ); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ HelpButton ][ bs ][small] = QPixmap( tmpResult ); + } + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, MENUBUTTONWIDTH, BUTTONSIZE ); + + // MenuButton + buttonImage = uic_findImage( "button_jaguar_menu"); + for (int bs = ButtonInactive; bs < Pressed; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs < Hovered ? + ButtonColor_[InactiveButton] : + ButtonColor_[MenuButton] ); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ MenuButton ][ bs ][small] = QPixmap( tmpResult ); + } + + + + // pressed MenuButton // as jaguar buttons shift + buttonImage = uic_findImage( "button_jaguar_menu_down"); + tmpResult2 = *tintGlossy( buttonImage, ButtonColor_[MenuButton].dark(120)); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ MenuButton ][ Pressed ][small] = QPixmap( tmpResult ); + + + break; + + // Load Milk Buttons ========================================================================= + + case Milk: + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, BUTTONSIZE, BUTTONSIZE ); + + // unpressed buttons + buttonImage = uic_findImage( "button_milk"); + + + for (int bt = MinButton; bt < MenuButton; bt++){ + for (int bs = ButtonInactive; bs < Pressed; bs++){ + /*brushedMode ? blend( buttonImage, tmpDeco, tmpResult ) : */blend( buttonImage, tmpDeco, tmpResult ); + if (bs > ButtonActive) blend( btnIcons[bt], tmpResult, tmpResult ); + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( tmpResult ); + } + } + + // pressed buttons // as pressed milk buttons differ + buttonImage = uic_findImage( "button_milk_down"); + for (int bt = MinButton; bt < MenuButton; bt++){ + /*brushedMode ? blend( buttonImage, tmpDeco, tmpResult ) : */blend( buttonImage, tmpDeco, tmpResult ); + blend( btnIcons[bt], tmpResult, tmpResult ); + ButtonPixmap_[style][ active ][ bt ][ Pressed ][small] = QPixmap( tmpResult ); + } + + // HelpButton + buttonImage = uic_findImage( "icon_help"); + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + /*brushedMode ? blend( buttonImage, tmpDeco, tmpResult ) : */blend( buttonImage, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ HelpButton ][ bs ][small] = QPixmap( tmpResult ); + } + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, MENUBUTTONWIDTH, BUTTONSIZE ); + + // MenuButton + buttonImage = uic_findImage( "button_milk_menu"); + for (int bs = ButtonInactive; bs < Pressed; bs++){ + /*brushedMode ? blend( buttonImage, tmpDeco, tmpResult ) : */blend( buttonImage, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ MenuButton ][ bs ][small] = QPixmap( tmpResult ); + } + + // pressed MenuButton // as pressed milk buttons differ + buttonImage = uic_findImage( "button_milk_menu_down"); + /*brushedMode ? blend( buttonImage, tmpDeco, tmpResult ) : */blend( buttonImage, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ MenuButton ][ Pressed ][small] = QPixmap( tmpResult ); + + break; + + // Create Nostalgia Buttons ========================================================================= + + case NostalgiaButton: + createOS8Buttons(style); + B_3 = (int)((BUTTONSIZE -1 )/ 3); + B_6 = B_3*2; + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, MENUBUTTONWIDTH, BUTTONSIZE ); + + for (int bt = MinButton; bt < ButtonTypeAmount; bt++){ + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + if (bs < Hovered) + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( nostalgia_[style][1][active] ); + else if (bs == Hovered) + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( nostalgia_[style][0][active] ); + else + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( nostalgia_[style][2][active] ); + if (bs > ButtonInactive){ + icyAPainter.begin(&ButtonPixmap_[style][ active ][ bt ][ bs ][small]); + icyAPainter.setPen(Qt::black); + if (bt == MinButton){ + icyAPainter.drawLine(2,B_3,BUTTONSIZE - 3,B_3); + icyAPainter.drawLine(2,B_6,BUTTONSIZE - 3,B_6); + icyAPainter.end(); + continue; + } + if (bt == MaxButton){ + icyAPainter.drawLine(2,B_6,B_6,B_6); + icyAPainter.drawLine(B_6,2,B_6,B_6); + icyAPainter.end(); + continue; + } + if (bt == StickyButton){ + icyAPainter.fillRect(BUTTONSIZE/2-1,BUTTONSIZE/2-1,2,2,Qt::black); + icyAPainter.end(); + continue; + } + if (bt == ShadeButton){ + icyAPainter.drawLine(2,B_3,BUTTONSIZE-3,B_3); + icyAPainter.drawLine(2,B_3+3,BUTTONSIZE-3,B_3+3); + icyAPainter.drawLine(2,B_3+6,BUTTONSIZE-3,B_3+6); + icyAPainter.end(); + continue; + } + if (bt == HelpButton){ + QFont tmpFont = QFont(options() ->font( true, false )); + tmpFont.setPixelSize(BUTTONSIZE - 4); + icyAPainter.setFont(tmpFont); + icyAPainter.drawText( 0, 0, BUTTONSIZE, BUTTONSIZE, Qt::AlignHCenter | Qt::AlignVCenter, "?" ); + icyAPainter.end(); + continue; + } + if (bt == MenuButton){ + icyAPainter.drawLine(2,B_3,BUTTONSIZE-3,B_3); + icyAPainter.end(); + + } + icyAPainter.end(); + } + if (bt == MenuButton){ + buttonImage = ButtonPixmap_[style][ active ][ bt ][ bs ][small].convertToImage(); + blend( buttonImage , tmpDeco, tmpDeco ); + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap(tmpDeco); + } + } + } + break; + + // Load Panther Buttons ========================================================================= + + case Panther: + default: + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, BUTTONSIZE, BUTTONSIZE ); + + // unpressed buttons + buttonImage = uic_findImage( "button_panther"); + + for (int bt = MinButton; bt < MenuButton; bt++){ + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs == ButtonInactive ? + ButtonColor_[InactiveButton] : + bs == Pressed ? + ButtonColor_[bt].dark(120) : + ButtonColor_[bt] ); + if (bs > ButtonActive) blend( btnIcons[bt], tmpResult2, tmpResult2 ); + if (bt == MaxButton && bs > ButtonInactive) deMaximizer_.setPixmap(bs - 1, tmpResult2); + blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ bt ][ bs ][small] = QPixmap( tmpResult ); + } + } + + + // HelpButton + buttonImage = uic_findImage( "icon_help"); + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs == ButtonInactive ? + ButtonColor_[InactiveButton] : + bs == Hovered ? + ButtonColor_[HelpButton].light(120) : + bs == Pressed ? + ButtonColor_[HelpButton].dark(120) : + ButtonColor_[HelpButton] ); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ HelpButton ][ bs ][small] = QPixmap( tmpResult ); + } + + tmpDeco = *DecoImage( &tbar, 0, ( tbar.height() - BUTTONSIZE ) / 2, MENUBUTTONWIDTH, BUTTONSIZE ); + + // MenuButton + buttonImage = uic_findImage( "button_panther_menu"); + for (int bs = ButtonInactive; bs < ButtonStateAmount; bs++){ + tmpResult2 = *tintGlossy( buttonImage, bs < Hovered ? + ButtonColor_[InactiveButton] : + bs == Pressed ? + ButtonColor_[MenuButton].dark(120) : + ButtonColor_[MenuButton] ); + /*brushedMode ? blend( tmpResult2, tmpDeco, tmpResult ) : */blend( tmpResult2, tmpDeco, tmpResult ); + ButtonPixmap_[style][ active ][ MenuButton ][ bs ][small] = QPixmap( tmpResult ); + } + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// borderSizes() +// ------------- +// Return list of valid border sizes + +QValueList BaghiraFactory::borderSizes() const { + return QValueList() << BorderTiny << BorderNormal + << BorderLarge << BorderVeryLarge + << BorderHuge << BorderVeryHuge; +} + +////////////////////////////////////////////////////////////////////////////// +// BaghiraButton Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// BaghiraButton() +// -------------- +// Constructor + +BaghiraButton::BaghiraButton( BaghiraClient *parent, const char *name, const QString& tip, bool small, ButtonType type, int style ) +: QButton( parent->widget(), name ), client_( parent ), type_( type ), deco_( 0 ), icon_(), small_( small ), lastmouse_( 0 ), mouseover_( false ), _blocked(false) { + setBackgroundMode( NoBackground ); + setCursor( arrowCursor ); + QToolTip::add( this, tip ); + down_ = false; + mouseover_ = false; + mask = NULL; + maskDown = NULL; + + setFixedSize( type == Baghira::MenuButton ? MENUBUTTONWIDTH : BUTTONSIZE, BUTTONSIZE ); + for ( int bs = Baghira::ButtonInactive; bs <= Baghira::Pressed; bs++ ) { + pixmap[ Baghira::WindowInactive ][ ( Baghira::ButtonState ) bs ] = + &BaghiraFactory::ButtonPixmap( Baghira::WindowInactive, type, + ( Baghira::ButtonState ) bs, style, small ); + pixmap[ Baghira::WindowActive ][ ( Baghira::ButtonState ) bs ] = + &BaghiraFactory::ButtonPixmap( Baghira::WindowActive, type, + ( Baghira::ButtonState ) bs, style, small ); + } +} + +BaghiraButton::~BaghiraButton() +{ + if ( deco_ ) + delete deco_; +} + + +////////////////////////////////////////////////////////////////////////////// +// sizeHint() +// ---------- +// Return size hint + +QSize BaghiraButton::sizeHint() const { + return QSize( BUTTONSIZE, BUTTONSIZE ); +} + +////////////////////////////////////////////////////////////////////////////// +// enterEvent() +// ------------ +// Mouse has entered the button + +void BaghiraButton::enterEvent( QEvent *e ) { +#if 0 + if (type_ == CloseButton) + { + _blocked = true; + QTimer::singleShot(250,this,SLOT(delayedEnterEvent())); + QButton::enterEvent( e ); + return; + } +#endif + mouseover_ = true; + repaint( false ); + QButton::enterEvent( e ); +} + +void BaghiraButton::delayedEnterEvent() +{ + if (hasMouse()) + { + _blocked = false; + mouseover_ = true; + repaint( false ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// leaveEvent() +// ------------ +// Mouse has left the button + +void BaghiraButton::leaveEvent( QEvent *e ) +{ + mouseover_ = false; + if ( type_ == Baghira::MenuButton ) + down_ = false; + repaint( false ); + QButton::leaveEvent( e ); +} + +////////////////////////////////////////////////////////////////////////////// +// mousePressEvent() +// ----------------- +// Button has been pressed + +void BaghiraButton::mousePressEvent( QMouseEvent* e ) +{ + if (_blocked && !(e->state() & Qt::ControlButton)) + return; + lastmouse_ = e->button(); + + //update mask + if (maskDown) + { + clearMask(); + setMask(*maskDown); + } + // translate and pass on mouse event + int button = LeftButton; + if ( ( type_ != MaxButton ) && ( e->button() != LeftButton ) ) + { + button = NoButton; // middle & right buttons inappropriate + } + down_ = true; + QMouseEvent me( e->type(), e->pos(), e->globalPos(), button, e->state() ); + repaint( false ); + QButton::mousePressEvent( &me ); +} + +// void BaghiraButton::setOn(bool on) +// { +// QButton::setOn(on); +// } + +////////////////////////////////////////////////////////////////////////////// +// mouseReleaseEvent() +// ----------------- +// Button has been released + +void BaghiraButton::mouseReleaseEvent( QMouseEvent* e ) { + lastmouse_ = e->button(); + + if (mask){ + clearMask(); + setMask(*mask); + } + // translate and pass on mouse event + int button = LeftButton; + if ( ( type_ != MaxButton ) && ( e->button() != LeftButton ) ) { + button = NoButton; // middle & right buttons inappropriate + } + down_ = false; + QMouseEvent me( e->type(), e->pos(), e->globalPos(), button, e->state() ); + repaint( false ); + QButton::mouseReleaseEvent( &me ); +} + +inline ButtonState BaghiraButton::state() { + if ( down_ || isDown() ) + return Pressed; + else if ( mouseover_ ) + return Hovered; + else if ( client_->isActive() ) + return ButtonActive; + else + return ButtonInactive; +} + +////////////////////////////////////////////////////////////////////////////// +// drawButton() +// ------------ +// Draw the button + +void BaghiraButton::drawButton( QPainter *painter ) { + if ( !BaghiraFactory::initialized() ) + return ; + + bool active = client_->isActive(); + + if ( type_ == Baghira::StickyButton && client_->isOnAllDesktops() ) + painter->drawPixmap( 0, 0, BaghiraFactory::ButtonPixmap( ( Baghira::WindowState ) active, type_, state() == Pressed ? Pressed : Hovered, client_->currentStyle, client_->isTool() )); + else + painter->drawPixmap( 0, 0, BaghiraFactory::ButtonPixmap( ( Baghira::WindowState ) active, type_, state() , client_->currentStyle, client_->isTool() )); + + if (type_ == Baghira::AboveBelowButton) + { + if (client_->keepAbove()) + { + painter->drawPixmap((width()-8)/2,height()/2-4,BaghiraFactory::arrowUp); + } + else if (client_->keepBelow()) + { + painter->drawPixmap((width()-8)/2,height()/2,BaghiraFactory::arrowDown); + } + } +} + +void BaghiraButton::setMasks(QBitmap *bitmask, QBitmap *bitmaskDown){ + clearMask(); + mask = bitmask; + maskDown = bitmaskDown; + if (mask) setMask(*mask); +} +////////////////////////////////////////////////////////////////////////////// +// BaghiraClient Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// BaghiraClient() +// ------------- +// Constructor + +BaghiraClient::BaghiraClient( KDecorationBridge *b, KDecorationFactory *f ) + : KDecoration( b, f ) +{ + ; +} + +BaghiraClient::~BaghiraClient() +{ + if (noDeco_) + return; + BaghiraFactory::deMaximizer().setClient(NULL); + for ( int n = 0; n < ButtonTypeAmount; n++ ) + { + if ( button[ n ] ) + delete button[ n ]; + } +} + +////////////////////////////////////////////////////////////////////////////// +// init() +// ------ +// Real initialization + +void BaghiraClient::init() +{ + if (BaghiraFactory::noModalDeco() && isModal() && !isMinimizable() && !isResizable()) + { + noDeco_ = true; + createMainWidget( WResizeNoErase | WRepaintNoErase ); + widget() ->setBackgroundMode( NoBackground ); + return; + } + noDeco_ = false; +#if KDE_IS_VERSION(3,3,91) + //first try if there's an X setting + unsigned char *data = 0; + Atom actual; + int format, result; + unsigned long n, left; + currentStyle = BaghiraFactory::defaultMode(); + result = XGetWindowProperty(qt_xdisplay(), windowId(), baghira_deco_design, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data); + if (result == Success && data != None) // found set design + { + memcpy (¤tStyle, data, sizeof (unsigned int)); + currentStyle = currentStyle>4?4:currentStyle; + } + else // try if there's a definition file + { + XClassHint classHint; + FILE *file = NULL; + if ( XGetClassHint( qt_xdisplay(), windowId(), &classHint ) ) + { + QString tmpString; + // overwrite file from bab starter? - don't worry, if there's been one and deleted by the style we've got the X setting (much better as it will take care of all subwindows) + tmpString = QDir::homeDirPath() + "/.baghira/.bab/" + QString( classHint.res_class ).lower(); + if( (file = fopen(tmpString.latin1(), "r")) != NULL ) + { + fscanf(file,"%d\n%d\n", &format, ¤tStyle); + fclose(file); + remove(tmpString.latin1()); // this is only temporary + } + else + { + tmpString = QDir::homeDirPath() + "/.baghira/" + QString( classHint.res_class ).lower(); + if( (file = fopen(tmpString.latin1(), "r")) != NULL ) + { + fscanf(file,"%d\n%d\n", &format, ¤tStyle); + fclose(file); + } + } + XFree( classHint.res_name ); + XFree( classHint.res_class ); + } + if (file == NULL) + { + QString tmpString = QDir::homeDirPath() + "/.baghira/.bab/.deco"; + if( (file = fopen(tmpString.latin1(), "r")) != NULL ) + { + fscanf(file,"%d\n%d\n", &format, ¤tStyle); + fclose(file); + } + } + } + if (currentStyle > 4) + currentStyle = BaghiraFactory::defaultMode(); +#else + QSettings config; + config.beginGroup("/baghira/Style"); + if (config.readBoolEntry( "Design_Default", 1 ) == 2) + { + currentStyle = 2; + config.endGroup(); + } + else + { + config.endGroup(); + config.beginGroup("/baghira/Deco"); + int tmp = config.readNumEntry( "defaultMode", 1 ); + currentStyle = (tmp > -1 && tmp < 5) ? tmp : 1; + config.endGroup(); + } +#endif + createMainWidget( WResizeNoErase | WRepaintNoErase ); + widget() ->installEventFilter( this ); + widget() ->setBackgroundMode( NoBackground ); + + if ( isTool() ) // tool windows have tiny titlebars + titleheight_ = TITLESIZESMALL; + else + titleheight_ = TITLESIZE; + + // setup layout + QVBoxLayout *mainlayout = new QVBoxLayout( widget() ); + QHBoxLayout *titlelayout = new QHBoxLayout(); + windowlayout = new QHBoxLayout(); + + titlebar_ = new QSpacerItem( 1, titleheight_, QSizePolicy::Expanding, QSizePolicy::Fixed ); + mainlayout->setResizeMode( QLayout::FreeResize ); + mainlayout->addLayout( titlelayout ); + mainlayout->addLayout( windowlayout ); + + windowlayout->addSpacing( BaghiraFactory::borderSize(currentStyle) ); + if ( isPreview() ) + windowlayout->addWidget( new QLabel( i18n( "
Baghira preview
" ), widget() ) ); + else + windowlayout->addItem( new QSpacerItem( 0, 18 ) ); + + windowlayout->addSpacing( BaghiraFactory::borderSize(currentStyle) ); + + leftClose = false; + rightClose = false; + performEasyClose = false; + + // setup titlebar + for ( int n = 0; n < ButtonTypeAmount; n++ ) + button[ n ] = 0; + plusminus = 1; + addButtons( titlelayout, options() ->titleButtonsLeft() ); + titlelayout->addItem( titlebar_ ); + plusminus = -1; + isFaded = false; + addButtons( titlelayout, options() ->titleButtonsRight() ); +#if KDE_IS_VERSION(3,3,91) + grip = 0; +#endif + + if (BaghiraFactory::effect(currentStyle, true) >= Baghira::Brushed || BaghiraFactory::effect(currentStyle, false) >= Baghira::Brushed) + HandlePix = QPixmap(BaghiraFactory::pix(currentStyle, TitleBar, isActive(), false )); + else if ( BaghiraFactory::bgStipple() ) + { + HandlePix = QPixmap( 32, 32); + QPainter painter; + QColor c = widget()->colorGroup().background(); + HandlePix.fill(c); + painter.begin( &HandlePix ); + painter.setPen( c.dark( 100 + (BaghiraFactory::contrast()/2) ) ); + + for ( int i = 1; i < 32; i += 4 ) + { + painter.drawLine( 0, i, 31, i ); + painter.drawLine( 0, i+2, 31, i+2 ); + } + + painter.setPen( c.dark( 100 + BaghiraFactory::contrast() ) ); + + for ( int i = 2; i < 31; i += 4 ) + painter.drawLine( 0, i, 31, i ); + + painter.end(); + } +} + +QString BaghiraClient::caption() const +{ + if (!BaghiraFactory::delAppname()) + return KDecoration::caption(); + if (caption_.isNull()) + // generate first + { + const_cast( this )->caption_ = KDecoration::caption(); + int pos; + if (caption_.startsWith( "tvtime" )) + { + pos = caption_.find(": "); + if (pos > -1) + const_cast( this )->caption_ = const_cast( this )->caption_.remove(0, pos+1); + } + else + { + pos = caption_.findRev(" - "); + if (pos > -1) + const_cast( this )->caption_ = caption_.left(pos); + } + } + return caption_; +} + +////////////////////////////////////////////////////////////////////////////// +// addButtons() +// ------------ +// Add buttons to title layout + +void BaghiraClient::addButtons( QBoxLayout *layout, const QString& s ) +{ + if (noDeco_) + return; + // const unsigned char *bitmap; + QString tip; + QBitmap *m = NULL; + QBitmap *mn = NULL; + QBitmap *mD = NULL; + QBitmap *mnD = NULL; + QBitmap *mH = NULL; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed){ + m = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + &BaghiraFactory::pantherMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMask : + NULL; + mn = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + &BaghiraFactory::pantherMenuMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMenuMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMenuMask : + NULL; + mD = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + NULL : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarDownMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkDownMask : + NULL; + mnD = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + NULL : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMenuDownMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMenuDownMask : + NULL; + mH = &BaghiraFactory::helpMask; + } + if ( s.length() > 0 ) { +// qWarning("%s",s.ascii()); + layout->addSpacing( MARGIN ); + excursion = excursion + plusminus * MARGIN; + bool buttonAdded; + for ( unsigned n = 0; n < s.length(); n++ ) { + buttonAdded = false; + switch ( s[ n ].latin1() ) { + case 'M': // Menu button + if ( !button[ MenuButton ] ) { + button[ MenuButton ] = new BaghiraButton( this, "menu", + i18n( "Menu" ), isTool(), MenuButton ); + connect( button[ MenuButton ], SIGNAL( pressed() ), this, + SLOT( menuButtonPressed() ) ); + layout->addWidget( button[ MenuButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * MENUBUTTONWIDTH; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ MenuButton ]->setMasks(mn, mnD); + } + break; + + case 'S': // Sticky button + if ( !button[ StickyButton ] ) { + if ( isOnAllDesktops() ) { + tip = i18n( "Un-Sticky" ); + } else { + tip = i18n( "Sticky" ); + } + button[ StickyButton ] = new BaghiraButton( this, "sticky", + tip, isTool(), StickyButton ); + connect( button[ StickyButton ], SIGNAL( clicked() ), this, + SLOT( toggleOnAllDesktops() ) ); + layout->addWidget( button[ StickyButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ StickyButton ]->setMasks(m, mD); + } + break; + + case 'H': // Help button + if ( ( !button[ HelpButton ] ) && providesContextHelp() ) { + button[ HelpButton ] = new BaghiraButton( this, "help", + i18n( "Help" ), isTool(), HelpButton ); + connect( button[ HelpButton ], SIGNAL( clicked() ), this, + SLOT( showContextHelp() ) ); + layout->addWidget( button[ HelpButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ HelpButton ]->setMasks(mH, NULL); + } + break; + + case 'I': // Minimize button + if ( ( !button[ MinButton ] ) && isMinimizable() ) { + button[ MinButton ] = new BaghiraButton( this, "iconify", + i18n( "Minimize" ), isTool(), MinButton ); + connect( button[ MinButton ], SIGNAL( clicked() ), this, + SLOT( minimize() ) ); + layout->addWidget( button[ MinButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ MinButton ]->setMasks(m, mD); + } + break; + + case 'A': // Maximize button + if ( ( !button[ MaxButton ] ) && isMaximizable() ) { + if ( maximizeMode() == MaximizeFull ) { + tip = i18n( "Restore" ); + } else { + tip = i18n( "Maximize" ); + } + button[ MaxButton ] = new BaghiraButton( this, "maximize", + tip, isTool(), MaxButton ); + connect( button[ MaxButton ], SIGNAL( clicked() ), this, + SLOT( maxButtonPressed() ) ); + layout->addWidget( button[ MaxButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ MaxButton ]->setMasks(m, mD); + } + break; + + case 'X': // Close button + if ( ( !button[ CloseButton ] ) && isCloseable() ) { + button[ CloseButton ] = new BaghiraButton( this, "close", + i18n( "Close" ), isTool(), CloseButton ); + connect( button[ CloseButton ], SIGNAL( clicked() ), this, + SLOT( closeWindow() ) ); + layout->addWidget( button[ CloseButton ] ); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (plusminus == 1 && n == 0) // left Button + leftClose = true; + if (plusminus == -1 && n == s.length() - 1) // right Button + rightClose = true; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ CloseButton ]->setMasks(m, mD); + } + break; + + case 'F': // Above button + case 'B': // Below button + if ((!button[AboveBelowButton])) + { + button[AboveBelowButton] = new BaghiraButton(this, "above", i18n("Keep Above/Below Others"), isTool(), AboveBelowButton); + button[AboveBelowButton]->setDown( keepAbove() || keepBelow() ); + connect(button[AboveBelowButton], SIGNAL(clicked()), this, SLOT(aboveBelowButtonPressed())); + layout->addWidget(button[AboveBelowButton]); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ AboveBelowButton ]->setMasks(m, mD); + } + break; + case 'L': // Shade button + if ((!button[ShadeButton] && isShadeable())) { + button[ShadeButton] = new BaghiraButton(this, "shade", isSetShade() ? tip = i18n("Unshade") : tip = i18n("Shade"), isTool(), ShadeButton); + button[ShadeButton]->setDown( isShade() ); + connect(button[ShadeButton], SIGNAL(clicked()), this, SLOT(shadeButtonPressed())); + layout->addWidget(button[ShadeButton]); + buttonAdded = true; + excursion = excursion + plusminus * BUTTONSIZE; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ ShadeButton ]->setMasks(m, mD); + } + break; +// case 'R': // Shade button +// if ((!button[ShadeButton] && isShadeable())) { +// button[ShadeButton] = new BaghiraButton(this, "shade", isSetShade() ? tip = i18n("Unshade") : tip = i18n("Shade"), isTool(), ShadeButton); +// button[ShadeButton]->setDown( isShade() ); +// connect(button[ShadeButton], SIGNAL(clicked()), this, SLOT(shadeButtonPressed())); +// layout->addWidget(button[ShadeButton]); +// buttonAdded = true; +// excursion = excursion + plusminus * BUTTONSIZE; +// if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed) button[ ShadeButton ]->setMasks(m, mD); +// } +// break; + + case '_': // Spacer item + layout->addSpacing( MARGIN ); + excursion = excursion + plusminus * MARGIN; + } + if (BaghiraFactory::addAutoSpacing() && buttonAdded){ + layout->addSpacing( MARGIN ); + excursion = excursion + plusminus * MARGIN; + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// eventFilter() +// ------------- +// Event filter + +bool BaghiraClient::eventFilter( QObject *obj, QEvent *e ) +{ + if ( obj != widget() ) + return false; + + switch ( e->type() ) { + case QEvent::MouseButtonDblClick: { + mouseDoubleClickEvent( static_cast( e ) ); + return true; + } + case QEvent::MouseButtonPress: { + if (titlebar_->geometry().contains( static_cast(e)->pos() ) && static_cast(e)->state() == Qt::ControlButton){ + currentStyle < 4 ? currentStyle++ : currentStyle = 0; +#if KDE_IS_VERSION(3,3,91) + unsigned long wmDesign = currentStyle; + XChangeProperty(qt_xdisplay(), windowId(), baghira_deco_design, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &wmDesign, 1L); +#endif + widget()->repaint(); + QBitmap *m = NULL; + QBitmap *mn = NULL; + QBitmap *mD = NULL; + QBitmap *mnD = NULL; + QBitmap *mH = NULL; + if (BaghiraFactory::effect(currentStyle, true) == Baghira::Brushed){ + m = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + &BaghiraFactory::pantherMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMask : + NULL; + mn = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + &BaghiraFactory::pantherMenuMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMenuMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMenuMask : + NULL; + mD = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + NULL : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarDownMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkDownMask : + NULL; + mnD = BaghiraFactory::buttonStyle(currentStyle) == Baghira::Panther ? + NULL : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Jaguar ? + &BaghiraFactory::jaguarMenuDownMask : + BaghiraFactory::buttonStyle(currentStyle) == Baghira::Milk ? + &BaghiraFactory::milkMenuDownMask : + NULL; + mH = &BaghiraFactory::helpMask; + } + for (int i = 0; i < ButtonTypeAmount; i++){ + if (button[i]){ + button[i]->setMasks(i < Baghira::MenuButton ? m : + i == Baghira::MenuButton ? mn : + mH, i < Baghira::MenuButton ? mD : + i == Baghira::MenuButton ? mnD : + NULL); + button[i]->repaint(); + } + } +#if KDE_IS_VERSION(3,3,91) + if (grip) + grip->updateLook(TRUE); +#endif + doShape(); + return true; + } + if (BaghiraFactory::allowEasyClosing()){ + if (maximizeMode() == MaximizeFull && isActive() && (leftClose && static_cast( e )->x() == 0 && static_cast( e )->y() == 0) || (rightClose && static_cast( e )->x() == ((QWidget *)obj)->width() -1 && static_cast( e )->y() == 0)) + performEasyClose = true; + else processMousePressEvent( static_cast( e ) ); + } + else processMousePressEvent( static_cast( e ) ); + return true; + } + case QEvent::MouseButtonRelease:{ + if (performEasyClose && maximizeMode() == MaximizeFull && (leftClose && static_cast( e )->x() == 0 && static_cast( e )->y() == 0) || (rightClose && static_cast( e )->x() == ((QWidget *)obj)->width() -1 && static_cast( e )->y() == 0)){ + closeWindow(); + performEasyClose = false; + return true; + } + return FALSE; + } + case QEvent::Paint: { + paintEvent( static_cast( e ) ); + return true; + } + case QEvent::Resize: { + resizeEvent( static_cast( e ) ); + return true; + } + case QEvent::Show: { +#if KDE_IS_VERSION(3,3,91) + if (!grip && BaghiraFactory::resizeGrip() && isResizable()) grip = new ResizeHandle(this); +#endif + showEvent( static_cast( e ) ); + return true; + } + case QEvent::Hide: { + emit hide(); + } + case QEvent::Wheel: { + wheelEvent(static_cast( e )); + return true; + } + default: { + return false; + } + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// mouseCoubleClickEvent() +// ----------------------- +// Doubleclick on title + +void BaghiraClient::mouseDoubleClickEvent( QMouseEvent *e ) +{ + if ( titlebar_->geometry().contains( e->pos() ) ) + titlebarDblClickOperation(); +} + +void BaghiraClient::wheelEvent( QWheelEvent *e ) +{ + if (titlebar_->geometry().contains( e->pos() ) && e->state() == Qt::ControlButton){ + // surf through the desktops :) + int target, cD; + if (e->delta() > 0){ + (cD = KWin::currentDesktop()) == KWin::numberOfDesktops() ? target = 1 : target = cD + 1; + } + else{ + (cD = KWin::currentDesktop()) == 1 ? target = KWin::numberOfDesktops() : target = cD - 1; + } + setDesktop (target); + KWin::setCurrentDesktop (target); + } +} + +////////////////////////////////////////////////////////////////////////////// +// paintEvent() +// ------------ +// Repaint the window + +void BaghiraClient::paintEvent( QPaintEvent* ) +{ + if ( !BaghiraFactory::initialized() || noDeco_) + return ; + + QPainter painter( widget() ); + QColorGroup group; + + QRect title( 0, 0, width(), titlebar_->geometry().height() ); + QRect left( 0, title.height(), BaghiraFactory::borderSize(currentStyle), height() - + title.height() ); + QRect right( width() - BaghiraFactory::borderSize(currentStyle), title.height(), + BaghiraFactory::borderSize(currentStyle), height() - title.height() ); + QRect handle( 0, height() - BaghiraFactory::borderSize(currentStyle), + width(), BaghiraFactory::borderSize(currentStyle) ); + + int x, y, x2, y2, h, w; + + title.rect( &x, &y, &w, &h ); + + // draw title bar + if (BaghiraFactory::effect(currentStyle, isActive()) == Baghira::Brushed) + { + if (w > 1024) + { + int w1 = (w - 1024)/2; + int w2 = w - 1024 - w1; + painter.drawTiledPixmap( 0,0, w1, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ),256-w1,0 ); + painter.drawPixmap( w1, 0/*, 1024, h*/, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ) ); + painter.drawTiledPixmap( w1 + 1024, 0, w2, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ); + } + else + painter.drawTiledPixmap( 0, 0, w, h, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ), (1024-w)/2, 0 ); + } + else + painter.drawTiledPixmap( title, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ); + + x2 = title.right(); + y2 = title.bottom(); + int shapeW = w; + + const QColor *ttbar = &(BaghiraFactory::color(currentStyle, Baghira::ColorTitleBar, isActive())); + + int tmp3Dimpact_ = 100 + BaghiraFactory::_3DImpact(currentStyle); + + painter.setPen( ttbar->light(tmp3Dimpact_)); + painter.drawLine( x+1, y+1, x2-1, y+1 ); + + if (!(BaghiraFactory::allowEasyClosing() && maximizeMode() == MaximizeFull)) + { + // draw around the corners ;-) + if (BaghiraFactory::shapeUL(currentStyle)) + { + // Draw edge of top-left corner inside the area removed by the mask. + painter.drawPoint( 3, 2 ); + painter.drawPoint( 4, 2 ); + painter.drawPoint( 2, 3 ); + painter.drawPoint( 2, 4 ); + } + if (BaghiraFactory::shapeUR(currentStyle)) + { + // Draw edge of top-right corner inside the area removed by the mask. + painter.drawPoint( shapeW - 5, 2 ); + painter.drawPoint( shapeW - 4, 2 ); + painter.drawPoint( shapeW - 3, 3 ); + painter.drawPoint( shapeW - 3, 4 ); + } + } + + + painter.setPen( ttbar->dark(tmp3Dimpact_) ); + if (BaghiraFactory::drawComicFrame() && !(BaghiraFactory::allowEasyClosing() && maximizeMode() == MaximizeFull)) + { + painter.drawLine(x,y,x, y2); + painter.drawLine(x2,y,x2, y2); + } + painter.drawLine( x, y, x2, y ); + + if (!(BaghiraFactory::allowEasyClosing() && maximizeMode() == MaximizeFull)) + { + // draw around the corners ;-) + if (BaghiraFactory::shapeUL(currentStyle)) + { + // Draw edge of top-left corner inside the area removed by the mask. + painter.drawPoint( 3, 1 ); + painter.drawPoint( 4, 1 ); + painter.drawPoint( 2, 2 ); + painter.drawPoint( 1, 3 ); + painter.drawPoint( 1, 4 ); + } + if (BaghiraFactory::shapeUR(currentStyle)) + { + // Draw edge of top-right corner inside the area removed by the mask. + painter.drawPoint( shapeW - 5, 1 ); + painter.drawPoint( shapeW - 4, 1 ); + painter.drawPoint( shapeW - 3, 2 ); + painter.drawPoint( shapeW - 2, 3 ); + painter.drawPoint( shapeW - 2, 4 ); + } + } + + const QColor *ttblend = &(BaghiraFactory::color(currentStyle, Baghira::ColorTitleBlend, isActive())); + + if (BaghiraFactory::LineImpact(currentStyle) > 0) + { + painter.setPen( ttblend->dark(100 + BaghiraFactory::LineImpact(currentStyle)) ); + painter.drawLine( x, y2, x2, y2 ); + } + + // draw title text + titlebar_->geometry().rect( &x, &y, &w, &h ); + int iconLeft; + int iconWidth; + if (BaghiraFactory::showTitle()) + { + painter.setFont( options() ->font( isActive(), isTool() ) ); + painter.setPen( options()->color( ColorFont, isActive() ) ); + BaghiraFactory::drawIcon(currentStyle) ? iconWidth = 16 : iconWidth = 0; + if (BaghiraFactory::drawIcon(currentStyle) || BaghiraFactory::effect(currentStyle, isActive()) == Baghira::Nostalgia) + { + QRect textBound = painter.boundingRect ( x + 2 * MARGIN + iconWidth, y, w - MARGIN * 2 - iconWidth, h, BaghiraFactory::titleAlign() | AlignVCenter, caption() ); + iconLeft = textBound.x() - MARGIN - iconWidth; + if ( iconLeft < x + MARGIN ) iconLeft = x + MARGIN; + + if (BaghiraFactory::drawIcon(currentStyle)) + { + ICONX = iconLeft; + ICONY = y + ( titleheight_ - 16 ) / 2; + painter.drawPixmap( ICONX, ICONY, icon().pixmap( QIconSet::Small, QIconSet::Normal ) ); + } + + if (BaghiraFactory::effect(currentStyle, isActive()) == Baghira::Nostalgia) + { + painter.fillRect( iconLeft - 5, y + 1, textBound.right() - iconLeft + 10, h - 2, BaghiraFactory::color(currentStyle, Baghira::ColorTitleBar, isActive() ) ); + painter.fillRect( title.x(), y + 1, x - title.x()+5, h - 2, *ttbar ); + painter.fillRect( x+w-5, y + 1, title.right() - w + 5, h - 2, *ttbar ); + } + } + painter.drawText( x + 2 * MARGIN + iconWidth, y, w - MARGIN * 2 - iconWidth, h, BaghiraFactory::titleAlign() | AlignVCenter, caption() ); + } + else if (BaghiraFactory::drawIcon(currentStyle)) + { + iconLeft = (width()-16)/2; + if ( iconLeft < x + MARGIN ) + iconLeft = x + MARGIN; + ICONX = iconLeft; + ICONY = y + ( titleheight_ - 16 ) / 2; + painter.drawPixmap( ICONX, ICONY, icon().pixmap( QIconSet::Small, QIconSet::Normal ) ); + } + + // draw outer frame + if ( !isShade() ) + { + QColor background = widget() ->colorGroup().background(); + + // left side + left.rect( &x, &y, &w, &h ); + if (w > 0){ + if (BaghiraFactory::effect(currentStyle,isActive()) == Baghira::Brushed) + { + width() > 1024 ? + painter.drawTiledPixmap( x, y, w, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ) : + painter.drawTiledPixmap( x, y, w, h, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ), (1024-width())/2 ); + } + else + { + BaghiraFactory::bgStipple() ? + painter.drawTiledPixmap( x, y, w, h, HandlePix ) : + painter.fillRect( x, y, w, h, background ); + } + } + + // right side + right.rect( &x, &y, &w, &h ); + if (w > 0){ + if (BaghiraFactory::effect(currentStyle,isActive()) == Baghira::Brushed) + { + width() > 1024 ? + painter.drawTiledPixmap( x, y, w, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ) : + painter.drawTiledPixmap( x, y, w, h, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ), (1024-width())/2+width()-w ); + } + else + { + BaghiraFactory::bgStipple() ? + painter.drawTiledPixmap( x, y, w, h, HandlePix ) : + painter.fillRect( x, y, w, h, background ); + } + } + + // draw handle ===================================================== + // bottom bar + // handle middle + handle.rect( &x, &y, &w, &h ); + if (BaghiraFactory::effect(currentStyle,isActive()) == Baghira::Brushed){ + if (w > 1024){ + int w1 = (w - 1024)/2; + int w2 = w - 1024 - w1; + painter.drawTiledPixmap( 0, y, w1, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ); + painter.drawPixmap( w1, y, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ) ); + painter.drawTiledPixmap( w1 + 1024, y, w2, h, BaghiraFactory::pix(currentStyle, TitleBar, isActive(), isTool() ) ); + } + else{ + painter.drawPixmap( x, y, BaghiraFactory::pix(currentStyle, TitleCenter, isActive(), isTool() ), (1024-w)/2, 0, w, h ); + } + + int b = handle.bottom() - 1; +// painter.setPen( ttbar->light(tmp3Dimpact_)); + painter.setPen( ttbar->dark(tmp3Dimpact_*1.1) ); + painter.drawLine( x, b, w-1, b ); + if (maximizeMode() != MaximizeFull) + { + if (BaghiraFactory::shapeLL(currentStyle)){ + // Draw edge of bottom-left corner inside the area removed by the mask. + painter.drawPoint(3, b); + painter.drawPoint(4, b); + painter.drawPoint(2, b-1); + painter.drawPoint(1, b-2); + painter.drawPoint(1, b-3); + painter.drawPoint(0, b-4); + } + if (BaghiraFactory::shapeLR(currentStyle)){ + // Draw edge of bottom-right corner inside the area removed by the mask. + painter.drawPoint(shapeW - 5, b); + painter.drawPoint(shapeW - 4, b); + painter.drawPoint(shapeW - 3, b-1); + painter.drawPoint(shapeW - 2, b-2); + painter.drawPoint(shapeW - 2, b-3); + painter.drawPoint(shapeW - 1, b-4); + } + } + painter.setPen( ttbar->dark(tmp3Dimpact_*1.3) ); + painter.drawLine( x+1, b+1, w-2, b+1 ); + if (maximizeMode() != MaximizeFull) + { + if (BaghiraFactory::shapeLL(currentStyle)){ + // Draw edge of bottom-left corner inside the area removed by the mask. + painter.drawPoint(4, b); + painter.drawPoint(5, b); + painter.drawPoint(3, b-1); + painter.drawPoint(2, b-2); +// painter.drawPoint(2, b-3); + } + if (BaghiraFactory::shapeLR(currentStyle)){ + // Draw edge of bottom-right corner inside the area removed by the mask. + painter.drawPoint(shapeW - 6, b); + painter.drawPoint(shapeW - 5, b); + painter.drawPoint(shapeW - 4, b-1); + painter.drawPoint(shapeW - 3, b-2); +// painter.drawPoint(shapeW - 3, b-3); + } + } + if (BaghiraFactory::drawComicFrame()) + { + painter.drawLine(x,title.y(),x, b); + painter.drawLine(handle.right(),title.y(),x2, b); + } + } + else{ + BaghiraFactory::bgStipple() ? painter.drawTiledPixmap( x, y, w, h, HandlePix ) : + painter.fillRect( x, y, w, h, background ); + + x2 = handle.right(); + y2 = handle.bottom(); + if (BaghiraFactory::drawComicFrame() && maximizeMode() != MaximizeFull){ + painter.setPen(ttblend->dark(tmp3Dimpact_)); + painter.drawLine( handle.x()/*+7*/, y2, x2/*-7*/, y2 ); + painter.drawLine(0,title.bottom(),0, y2); + painter.drawLine(x2,title.bottom(),x2, y2); + } + } + if (BaghiraFactory::drawComicFrame() && maximizeMode() != MaximizeFull){ + int b = handle.bottom() - 1; + if (BaghiraFactory::shapeLL(currentStyle)){ + // Draw edge of bottom-left corner inside the area removed by the mask. + painter.drawPoint(3, b); + painter.drawPoint(4, b); + painter.drawPoint(2, b-1); + painter.drawPoint(1, b-2); + painter.drawPoint(1, b-3); + } + if (BaghiraFactory::shapeLR(currentStyle)){ + // Draw edge of bottom-right corner inside the area removed by the mask. + painter.drawPoint(shapeW - 5, b); + painter.drawPoint(shapeW - 4, b); + painter.drawPoint(shapeW - 3, b-1); + painter.drawPoint(shapeW - 2, b-2); + painter.drawPoint(shapeW - 2, b-3); + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// resizeEvent() +// ------------- +// Window is being resized + +void BaghiraClient::resizeEvent( QResizeEvent* ) +{ + if (noDeco_) + return; + /*if ( widget() ->isShown() ) { + QRegion region = widget() ->rect(); + region = region.subtract( titlebar_->geometry() ); + widget() ->erase( region ); + }*/ +// widget()->repaint(); + doShape(); +} + +///////////////////////////////////////////////////////////////////////////// +// shape Corners +// =) ==================================================================0 + +void BaghiraClient::doShape() +{ +// return; + QRegion mask; + + if (!(BaghiraFactory::allowEasyClosing() && maximizeMode() == MaximizeFull)){ + int r = width(); + int b = height() - 1; + mask = QRegion( 0, 0, r, b+1 ); + + if (BaghiraFactory::shapeUL(currentStyle)){ + // Remove top-left corner. + mask -= QRegion( 0, 0, 5, 1 ); + mask -= QRegion( 0, 1, 3, 1 ); + mask -= QRegion( 0, 2, 2, 1 ); + mask -= QRegion( 0, 3, 1, 2 ); + } + if (BaghiraFactory::shapeUR(currentStyle)){ + // Remove top-right corner. + mask -= QRegion( r - 5, 0, 5, 1 ); + mask -= QRegion( r - 3, 1, 3, 1 ); + mask -= QRegion( r - 2, 2, 2, 1 ); + mask -= QRegion( r - 1, 3, 1, 2 ); + } + + if (BaghiraFactory::shapeLL(currentStyle)){ + // Remove bottom-left corner. + mask -= QRegion(0, b-0, 5, 1); + mask -= QRegion(0, b-1, 3, 1); + mask -= QRegion(0, b-2, 2, 1); + mask -= QRegion(0, b-4, 1, 2); + } + if (BaghiraFactory::shapeLR(currentStyle)){ + // Remove bottom-right corner. + mask -= QRegion(r - 5, b-0, 5, 1); + mask -= QRegion(r - 3, b-1, 3, 1); + mask -= QRegion(r - 2, b-2, 2, 1); + mask -= QRegion(r - 1, b-4, 1, 2); + } + } + setMask( mask, 1 ); +} + + +////////////////////////////////////////////////////////////////////////////// +// showEvent() +// ----------- +// Window is being shown + +void BaghiraClient::showEvent( QShowEvent* ) +{ + if (noDeco_) + return; + doShape(); + widget() ->repaint(); +} + +////////////////////////////////////////////////////////////////////////////// +// activeChange() +// -------------- +// window active state has changed + +void BaghiraClient::activeChange() +{ + if (noDeco_) + return; + if (BaghiraFactory::fullSpec() && maximizeMode() == MaximizeFull) + { + if (isActive()) + { + BaghiraFactory::deMaximizer().show(); + BaghiraFactory::deMaximizer().setClient(this); + } + } + else + { + BaghiraFactory::deMaximizer().hide(); + for ( int n = 0; n < ButtonTypeAmount; n++ ) + { + if ( button[ n ] ) + { + button[n]->setAutoMask( BaghiraFactory::effect(currentStyle, isActive()) == Baghira::Brushed); + button[ n ] ->reset(); + } + } + widget() ->repaint( false ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// captionChange() +// --------------- +// The title has changed + +void BaghiraClient::captionChange() +{ + if (noDeco_) + return; + if (BaghiraFactory::showTitle()) + { + if (BaghiraFactory::delAppname()) + { + caption_ = KDecoration::caption(); + int pos; + if (caption_.startsWith( "tvtime" )) + { + pos = caption_.find(": "); + if (pos > -1) + caption_ = caption_.remove(0, pos+1); + } + else + { + pos = caption_.findRev(" - "); + if (pos > -1) + caption_ = caption_.left(pos); + } + } + widget() ->repaint( titlebar_->geometry(), false ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// desktopChange() +// --------------- +// Sticky state has changed + +void BaghiraClient::desktopChange() +{ + if (noDeco_) + return; + bool d = isOnAllDesktops(); + if ( button[ StickyButton ] ) + { + QToolTip::remove + ( button[ StickyButton ] ); + QToolTip::add + ( button[ StickyButton ], d ? i18n( "Un-Sticky" ) : i18n( "Sticky" ) ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// iconChange() +// ------------ +// The title has changed + +void BaghiraClient::iconChange() +{ + if (noDeco_) + return; + if (BaghiraFactory::drawIcon(currentStyle)) widget()->repaint(ICONX, ICONY, 16, 16, false); +} + +////////////////////////////////////////////////////////////////////////////// +// maximizeChange() +// ---------------- +// Maximized state has changed + +void BaghiraClient::maximizeChange() +{ + if (noDeco_) //shouldn't happen - windo's not maximizable + return; + bool m = ( maximizeMode() == MaximizeFull ); + if (BaghiraFactory::fullSpec() && m){ + if (isActive()){ + BaghiraFactory::deMaximizer().show(); + BaghiraFactory::deMaximizer().setClient(this); + } + } + else { + BaghiraFactory::deMaximizer().setClient(NULL); + BaghiraFactory::deMaximizer().hide(); + } + if ( button[ MaxButton ] ) { + QToolTip::remove + ( button[ MaxButton ] ); + QToolTip::add + ( button[ MaxButton ], m ? i18n( "Restore" ) : i18n( "Maximize" ) ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// shadeChange() +// ------------- +// Called when window shading changes + +void BaghiraClient::shadeChange() { + ; +} + +////////////////////////////////////////////////////////////////////////////// +// borders() +// ---------- +// Get the size of the borders + +void BaghiraClient::borders( int &l, int &r, int &t, int &b ) const +{ + if (noDeco_) + { + l = r = t = b = 0; + return; + } + bool m = ( maximizeMode() == MaximizeFull); + t = (BaghiraFactory::fullSpec() && m) ? 0 : titleheight_; + if (m || maximizeMode() == MaximizeHorizontal) + l = r = BaghiraFactory::maxResizable() ? 1 : 0; + else + l = r = BaghiraFactory::borderSize(currentStyle); + if ( m || isShade() || (maximizeMode() == MaximizeVertical)) + b = BaghiraFactory::maxResizable() ? 1 : 0; + else + b = BaghiraFactory::borderSize(currentStyle); +} + +////////////////////////////////////////////////////////////////////////////// +// resize() +// -------- +// Called to resize the window + +void BaghiraClient::resize( const QSize &size ) +{ + if (noDeco_) + return; + widget() ->resize( size ); +} + +////////////////////////////////////////////////////////////////////////////// +// minimumSize() +// ------------- +// Return the minimum allowable size for this decoration + +QSize BaghiraClient::minimumSize() const +{ + return QSize( 100, 60 ); +} + +////////////////////////////////////////////////////////////////////////////// +// mousePosition() +// --------------- +// Return mouse position (for resizing) + +KDecoration::Position BaghiraClient::mousePosition( const QPoint &point ) const +{ + if (noDeco_) + return PositionCenter; + Position pos = PositionCenter; + if ( point.y() < ( height() - BaghiraFactory::borderSize(currentStyle) ) ) { // inside client + pos = KDecoration::mousePosition( point ); + } else { + if ( point.x() >= ( width() - 16 ) ) + pos = PositionBottomRight; + else if ( point.x() <= 16 ) + pos = PositionBottomLeft; + else + pos = PositionBottom; + } + return pos; +} + + +////////////////////////////////////////////////////////////////////////////// +// maxButtonPressed() +// ----------------- +// Max button was pressed + + +void BaghiraClient::demaxButtonPressed() { + maxButtonPressed(); +} + +void BaghiraClient::maxButtonPressed() { + if ( !BaghiraFactory::fullSpec() || (maximizeMode() != MaximizeFull) && button[ MaxButton ]) { + switch ( button[ MaxButton ] ->lastMousePress() ) { + case MidButton: + maximize( maximizeMode() ^ MaximizeVertical ); + break; + case RightButton: + maximize( maximizeMode() ^ MaximizeHorizontal ); + break; + default: + if ( maximizeMode() == MaximizeFull ) { + maximize( MaximizeRestore ); + } + else { + maximize( MaximizeFull ); + } + } + } + else{ + maximize( MaximizeRestore ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// menuButtonPressed() +// ------------------- +// Menu button was pressed + +void BaghiraClient::menuButtonPressed() { + if ( button[ MenuButton ] ) { + QPoint pt( button[ MenuButton ] ->rect().bottomLeft().x(), + button[ MenuButton ] ->rect().bottomLeft().y() + 4 ); + KDecorationFactory* f = factory(); + showWindowMenu( button[ MenuButton ] ->mapToGlobal( pt ) ); + if ( !f->exists( this ) ) + return ; // we have been destroyed + button[ MenuButton ] ->setDown( false ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// new stuff + +void BaghiraClient::aboveBelowButtonPressed() +{ + if (keepAbove()) + { + button[ AboveBelowButton ] ->setDown(true); + setKeepAbove(false ); + setKeepBelow(true ); + button[ AboveBelowButton ] ->repaint( false ); + } + else if (keepBelow()) + { + button[ AboveBelowButton ] ->setDown(false); + setKeepBelow(false ); + setKeepAbove(false ); + button[ AboveBelowButton ] ->repaint( false ); + } + else + { + button[ AboveBelowButton ] ->setDown(true); + setKeepBelow(false ); + setKeepAbove(true ); + button[ AboveBelowButton ] ->repaint( false ); + } +} + +void BaghiraClient::shadeButtonPressed(){ + button[ ShadeButton ]->setDown(!isShade()); + setShade( !isShade() ); +} + +////////////////////////////////////////////////////////////////////////////// +// isTool() +// -------- +// Is this a tool window? + +bool BaghiraClient::isTool() const { + static const unsigned long winmask = NET::DesktopMask | NET::DialogMask | + NET::DockMask | NET::MenuMask | + NET::NormalMask | NET::OverrideMask | + NET::SplashMask | NET::ToolbarMask | + NET::TopMenuMask | NET::UtilityMask; + + NET::WindowType type = windowType( winmask ); + return ( type == NET::Menu || type == NET::Toolbar || type == NET::Utility ); +} + +#include "baghiraclient.moc" diff --git a/deco/baghiraclient.h b/deco/baghiraclient.h new file mode 100644 index 0000000..c77ea0d --- /dev/null +++ b/deco/baghiraclient.h @@ -0,0 +1,445 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraclient.h +// ------------------- +// Baghira window decoration for KDE +// ------------------- +// Copyright (c) 2004, 2005 Thomas Lübking +// +// 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 BAGHIRACLIENT_H +#define BAGHIRACLIENT_H + +#include +#include +#include +#include +#include +#include +/* +#define BUTTONSIZE 15; +#define MENUBUTTONWIDTH 20; +#define DECOSIZE 8; +#define TITLESIZESMALL 18; +#define MARGIN 4;*/ + +class QSpacerItem; +class QPoint; +class QBitmap; +class KWinModule; + +namespace Baghira { + + +enum PixmapType { + TitleBar = 0, + TitleCenter, + PixmapTypeCount +}; + +enum ColorType { + ColorTitleBar=0, + ColorTitleBlend, + ColorTypeCount +}; + +enum ButtonType{ + MinButton = 0, + MaxButton, + CloseButton, + StickyButton, + ShadeButton, + AboveBelowButton, + MenuButton, + HelpButton, + ButtonTypeAmount, + InactiveButton = ButtonTypeAmount +}; + +enum ButtonStyle{ + Panther = 0, + Jaguar, + Milk, + NostalgiaButton +}; + +enum ButtonState{ + ButtonInactive, + ButtonActive, + Hovered, + Pressed, + ButtonStateAmount +}; + +enum WindowState{ + WindowInactive, + WindowActive, + WindowStateAmount +}; + +enum TitlebarType{ + Gradient, + Stipples, + Nostalgia, + Glossy, + Brushed, + FlatStipples +}; + +class BaghiraClient; + +// #if KDE_IS_VERSION(3,3,91) +class ResizeHandle : public QWidget +{ +//#if KDE_IS_VERSION(3,3,91) +friend class BaghiraClient; + Q_OBJECT +#if KDE_IS_VERSION(3,3,91) +public: + ResizeHandle(BaghiraClient *parent); +protected: + virtual void mousePressEvent ( QMouseEvent * ); + virtual void mouseReleaseEvent ( QMouseEvent * ); + virtual void paintEvent ( QPaintEvent * ); + void updateLook(bool rp = FALSE); +private: + bool eventFilter(QObject *obj, QEvent *e); + void shape(); + BaghiraClient *client; + QPixmap pix; +#endif +}; +// #endif + +class DeMaximizer : public QWidget +{ +friend class BaghiraClient; +friend class BaghiraFactory; + Q_OBJECT +public: + DeMaximizer(); + void setClient(BaghiraClient *); +protected: + void mouseReleaseEvent( QMouseEvent * e ); + void mousePressEvent ( QMouseEvent * e ); + void enterEvent ( QEvent * e ); + void leaveEvent ( QEvent * e ); + void setPixmap(int i, QImage &image); +private: + BaghiraClient *client_; + QPixmap pixmap[5]; + void setState(int i); +}; + +// BaghiraFactory ////////////////////////////////////////////////////////////// + +class BaghiraFactory: public KDecorationFactory +{ +public: + BaghiraFactory(); + virtual ~BaghiraFactory(); + virtual KDecoration *createDecoration(KDecorationBridge *b); + virtual bool reset(unsigned long changed); + virtual QValueList borderSizes() const; + static QPixmap &ButtonPixmap(Baghira::WindowState wState, Baghira::ButtonType type, Baghira::ButtonState state, int current, bool small); + QImage* DecoImage(QPixmap *pix, int x, int y, int width, int height); + + static QBitmap helpMask, jaguarDownMask, jaguarMenuDownMask, + jaguarMenuMask, jaguarMask, milkMenuDownMask, + milkMenuMask, milkMask, pantherMenuMask, pantherMask, milkDownMask, arrowUp, arrowDown; + + static bool initialized(); + static bool noModalDeco(); + static bool delAppname(); + static QColor &color(int current, Baghira::ColorType c, bool active=true); + static KPixmap &pix(int current, PixmapType p, bool active=true, bool small=false); + static TitlebarType &effect(int current, bool active); + static ButtonStyle buttonStyle(int current); + static Qt::AlignmentFlags titleAlign(); + static int borderSize(int current); + static int contrast(); + static int _3DImpact(int current); + static int LineImpact(int current); + static bool bgStipple(); + static bool resizeGrip(); + static uint defaultMode(); + static bool drawComicFrame(); + static bool shapeUL(int current); + static bool shapeUR(int current); + static bool shapeLL(int current); + static bool shapeLR(int current); + static bool drawIcon(int current); + static bool showTitle(); + static bool allowEasyClosing(); + static bool addAutoSpacing(); + static bool maxResizable(); + TitlebarType titleEffect(); + static DeMaximizer &deMaximizer(); + static bool fullSpec(); + static QColor &BrushedMetalColor(); + +private: +// bool blend( const QImage & upper, const QImage & lower, QImage & output); + unsigned long readConfig(); + void createPixmaps(); + void createGradient(KPixmap &pix, const QColor &light, const QColor &dark, Baghira::TitlebarType effect); + void createOS8Buttons(int style); + QString indexedString(QString s, int index); + QImage* tintBrush( const QImage &img, const QColor &c ) const; + QImage* tintGlossy(const QImage &src, const QColor &c ) const; + +private: + + static bool initialized_; + static bool noModalDeco_; + static bool delAppname_; + static bool bgStipple_; + static bool comicFrame_; + static bool resizeGrip_; + static bool shape_ul[5], shape_ur[5], shape_ll[5], shape_lr[5]; + static bool allowEasyClosing_; + static bool addAutoSpacing_; + static bool maxResizable_; + static bool drawIcon_[5]; + static ButtonStyle buttonStyle_[5]; + static TitlebarType effect_[5][2]; + static Qt::AlignmentFlags titlealign_; + static QColor colors_[5][ColorTypeCount][2]; + static KPixmap pix_[5][PixmapTypeCount][2][2]; + static QPixmap ButtonPixmap_[5][WindowStateAmount][ButtonTypeAmount][ButtonStateAmount][2]; + static QColor ButtonColor_[ButtonTypeAmount+1]; + static QColor brushedMetalColor; + static QPixmap nostalgia_[5][3][2]; + + static int contrast_; + static int bordersize_[5]; + static uint defaultMode_; + static int minimumTitleHeight_; + static int _3DImpact_[5]; + static int LineImpact_[5]; + + static bool tintBrush_; + static bool showTitle_; + static QColor brushTint; + static DeMaximizer deMaximizer_; + static bool fullSpec_; + +}; + +inline bool BaghiraFactory::fullSpec() + { return fullSpec_; } +inline bool BaghiraFactory::noModalDeco() +{ return noModalDeco_; } +inline bool BaghiraFactory::delAppname() +{ return delAppname_; } + +inline DeMaximizer &BaghiraFactory::deMaximizer() + { return deMaximizer_; } + +inline bool BaghiraFactory::shapeUL(int current) + { return shape_ul[current]; } +inline bool BaghiraFactory::shapeUR(int current) + { return shape_ur[current]; } +inline bool BaghiraFactory::shapeLL(int current) + { return shape_ll[current]; } +inline bool BaghiraFactory::shapeLR(int current) + { return shape_lr[current]; } + +inline bool BaghiraFactory::allowEasyClosing() + { return allowEasyClosing_; } + +inline bool BaghiraFactory::addAutoSpacing() + { return addAutoSpacing_; } + +inline bool BaghiraFactory::maxResizable() + { return maxResizable_; } + +inline bool BaghiraFactory::resizeGrip() + { return resizeGrip_; } + +inline uint BaghiraFactory::defaultMode() + { return defaultMode_; } + +inline bool BaghiraFactory::drawIcon(int current) + { return drawIcon_[current]; } + +inline bool BaghiraFactory::showTitle() +{ return showTitle_; } + +inline int BaghiraFactory::contrast() + { return contrast_; } + +inline int BaghiraFactory::_3DImpact(int current) + { return _3DImpact_[current]; } + +inline int BaghiraFactory::LineImpact(int current) + { return LineImpact_[current]; } + +inline bool BaghiraFactory::drawComicFrame() + { return comicFrame_; } + +inline bool BaghiraFactory::bgStipple() + { return bgStipple_; } + +inline ButtonStyle BaghiraFactory::buttonStyle(int current) + { return BaghiraFactory::buttonStyle_[current]; } + +inline bool BaghiraFactory::initialized() + { return initialized_; } + +inline QColor &BaghiraFactory::BrushedMetalColor() + { return brushedMetalColor; } + +inline QColor &BaghiraFactory::color(int current, Baghira::ColorType c, bool active) + { return colors_[current][c][active]; } + +inline KPixmap &BaghiraFactory::pix(int current, PixmapType p, bool active, bool small) + { return pix_[current][p][active][small]; } + +inline Baghira::TitlebarType &BaghiraFactory::effect(int current, bool active) + { return effect_[current][active]; } + +inline Qt::AlignmentFlags BaghiraFactory::titleAlign() + { return titlealign_; } + +inline int BaghiraFactory::borderSize(int current) +{ return bordersize_[current]; } + +// BaghiraButton /////////////////////////////////////////////////////////////// + +class BaghiraButton : public QButton +{ + Q_OBJECT +public: + BaghiraButton(BaghiraClient *parent=0, const char *name=0, const QString &tip=NULL, bool small=false, ButtonType type=MinButton, int style=0); + ~BaghiraButton(); + + QSize sizeHint() const; + int lastMousePress() const; + void reset(); + inline void setMasks(QBitmap *bitmask, QBitmap *bitmaskDown); + Baghira::ButtonState state(); + inline void setType(Baghira::ButtonType type) + {type_ = type; } + QBitmap *mask; + QBitmap *maskDown; + +private: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void drawButton(QPainter *painter); + +private slots: + void delayedEnterEvent(); + +private: + bool _blocked; + BaghiraClient *client_; + ButtonType type_; + QBitmap *deco_; + QPixmap *pixmap[2][5]; + KPixmap icon_; + bool small_; + int lastmouse_; + bool mouseover_; + bool down_; +}; + +inline int BaghiraButton::lastMousePress() const + { return lastmouse_; } + +inline void BaghiraButton::reset() + { repaint(false); } + +// BaghiraClient /////////////////////////////////////////////////////////////// + +class BaghiraClient : public KDecoration +{ +friend class BaghiraButton; +friend class ResizeHandle; + Q_OBJECT +public: + BaghiraClient(KDecorationBridge *b, KDecorationFactory *f); + virtual ~BaghiraClient(); + + virtual void init(); + QString caption() const; + + virtual void activeChange(); + virtual void desktopChange(); + virtual void captionChange(); + virtual void iconChange(); + virtual void maximizeChange(); + virtual void shadeChange(); + void demaxButtonPressed(); + + virtual void borders(int &l, int &r, int &t, int &b) const; + virtual void resize(const QSize &size); + virtual QSize minimumSize() const; + virtual Position mousePosition(const QPoint &point) const; + uint currentStyle; + +signals: + void hide(); + +protected: + bool isTool() const; + int titleheight_; + +private: + void addButtons(QBoxLayout* layout, const QString& buttons); + + bool eventFilter(QObject *obj, QEvent *e); + void mouseDoubleClickEvent(QMouseEvent *e); + void wheelEvent(QWheelEvent *e); + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + void showEvent(QShowEvent *); + +private slots: + void doShape(); + void maxButtonPressed(); + void menuButtonPressed(); + void aboveBelowButtonPressed(); + void shadeButtonPressed(); + +private: + BaghiraButton *button[ButtonTypeAmount]; + + QSpacerItem *titlebar_; + QPixmap HandlePix; + int excursion; // skewness because of unequality of left/right buttons - bad for center aligned titles... + int plusminus; + bool isFaded; + bool leftClose; + bool rightClose; + bool performEasyClose; + bool noDeco_; + QHBoxLayout *windowlayout; + int ICONX, ICONY; + ResizeHandle *grip; + QString caption_; +}; + +} // namespace Baghira + +#endif // BAGHIRACLIENT_H diff --git a/deco/config/Makefile.am b/deco/config/Makefile.am new file mode 100644 index 0000000..b9b97ae --- /dev/null +++ b/deco/config/Makefile.am @@ -0,0 +1,23 @@ +AUTOMAKE_OPTIONS = foreign + +KDE_CXXFLAGS = -DQT_PLUGIN + +INCLUDES = $(all_includes) -I$(srcdir)/../../config + +noinst_HEADERS = baghiraconfig.h aquariusbutton.h colorpicker.h pixmaps.h + +kde_module_LTLIBRARIES = kwin_baghira_config.la +kwin_baghira_config_la_SOURCES = baghiraconfig.cc aquariusbutton.cc colorpicker.cc configdialog.ui +kwin_baghira_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +kwin_baghira_config_la_LIBADD = $(LIB_KDEUI) +kwin_baghira_config_la_METASOURCES = AUTO + +DISTCLEANFILES = $(kwin_baghira_config_la_METASOURCES) + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kwin_baghira_config.pot + +pixmaps.h: $(srcdir)/generatePixmaps.sh + $(SHELL) $(srcdir)/generatePixmaps.sh $(top_srcdir) +CLEANFILES = pixmaps.h +baghiraconfig.lo: pixmaps.h diff --git a/deco/config/aquariusbutton.cc b/deco/config/aquariusbutton.cc new file mode 100644 index 0000000..6201abc --- /dev/null +++ b/deco/config/aquariusbutton.cc @@ -0,0 +1,162 @@ +#include "aquariusbutton.h" +#include +#include +#include +#include +#include "config.h" + + +#define COLOR_SPACE(R,G,B) \ + if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \ + if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \ + if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255; + +#define SATURATION_COLOR(R,G,B) \ + grey = (299 * R + 587 * G + 114 * B) / 1000; \ + delta = 255 - grey; \ + grey = (grey *(10 - 5)) / 10; \ + iGrey = 255 - grey;\ + destR = (iGrey * (srcR - delta) + grey * R) / 255; \ + destG = (iGrey * (srcG - delta) + grey * G) / 255; \ + destB = (iGrey * (srcB - delta) + grey * B) / 255; + +#define CLAMP(x,l,u) x < l ? l :\ + x > u ? u :\ + x + +#define SATURATION_COLOR2(S,R,G,B) \ + int max = 255+0.65*(100-S); \ + destR = CLAMP((srcR + R - 128), 0, max); \ + destG = CLAMP((srcG + G - 128), 0, max); \ + destB = CLAMP((srcB + B - 128), 0, max); \ + destR = (S*destR + (100-S)*R)/100; \ + destG = (S*destG + (100-S)*G)/100; \ + destB = (S*destB + (100-S)*B)/100; + +static bool blend( const QImage & upper, const QImage & lower, QImage & output) +// adopted from kimageeffect::blend - what is not endian safe... +{ + if + ( + upper.width() > lower.width() || + upper.height() > lower.height() || + upper.depth() != 32 || + lower.depth() != 32 + ) + return false; + + output = lower.copy(); + + register uchar *i, *o; + register int a; + register int col; + register int w = upper.width(); + int row(upper.height() - 1); + + do + { + i = upper.scanLine(row); + o = output.scanLine(row); + + col = w << 2; + + --col; + + do + { +#ifdef WORDS_BIGENDIAN + while (!(a = i[col-3]) && (col != 3)) +#else + while (!(a = i[col]) && (col != 3)) +#endif + { + --col; --col; --col; --col; + } +#ifndef WORDS_BIGENDIAN + --col; +#endif + o[col] += ((i[col] - o[col]) * a) >> 8; + + --col; + o[col] += ((i[col] - o[col]) * a) >> 8; + + --col; + o[col] += ((i[col] - o[col]) * a) >> 8; + +#ifdef WORDS_BIGENDIAN + --col; +#endif + + } while (col--); + } while (row--); + return true; +} + +AquariusButton::AquariusButton( QPixmap &pixmap, QWidget* parent, const char* name) : QWidget( parent, name){ + pixmap = pixmap; + image = pixmap.convertToImage(); + setFixedSize( pixmap.size() ); +} + +AquariusButton::~AquariusButton(){ +} + +QColor AquariusButton::Color(){ + return color; +} + +void AquariusButton::setColor(QColor c){ + color = c; + tint(color); + repaint(false); +} + +void AquariusButton::tint(QColor &c){ + QImage dest( image.width(), image.height(), 32, 0 ); + dest.setAlphaBuffer( true ); + unsigned int *data = ( unsigned int * ) image.bits(); + unsigned int *destData = ( unsigned int* ) dest.bits(); + int total = image.width() * image.height(); + int red, green, blue; + int destR, destG, destB, alpha; + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + // float srcPercent, destPercent; + for ( int current = 0 ; current < total ; ++current ) { + alpha = qAlpha( data[ current ] ); + if (alpha < 230){ + destData[ current ] = data[ current ]; + continue; //do not handle translucent parts to not affect blending + } + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + blue = qBlue( data[ current ] ); + SATURATION_COLOR2(sq, red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + QPixmap backPix = QPixmap(dest.size()); + QPainter tmpPainter(&backPix); + tmpPainter.fillRect(0, 0, dest.width(),dest.height(), backgroundBrush()); + tmpPainter.end(); + QImage back = backPix.convertToImage(); + blend(dest,back,back); + pixmap = QPixmap(back); +} + +void AquariusButton::mousePressEvent( QMouseEvent *e ){ + emit clicked(); +} + +void AquariusButton::paintEvent( QPaintEvent *e){ + QPainter tmpPainter(this); + tmpPainter.drawPixmap(0,0, pixmap); +} + +// void AquariusButton::clicked(){ +// } diff --git a/deco/config/aquariusbutton.h b/deco/config/aquariusbutton.h new file mode 100644 index 0000000..04fec0d --- /dev/null +++ b/deco/config/aquariusbutton.h @@ -0,0 +1,37 @@ +#ifndef AQUARIUSBUTTON_H +#define AQUARIUSBUTTON_H + +//#include +#include +#include + +class QPixmap; +class QColor; + +class AquariusButton : public QWidget +{ + Q_OBJECT + +public: + AquariusButton( QPixmap &pixmap, QWidget* parent = 0, const char* name = 0); + ~AquariusButton(); + QColor Color(); + +public slots: + void setColor(QColor c); + +protected: + QPixmap pixmap; + QImage image; + QColor color; + void tint(QColor &c); + void mousePressEvent( QMouseEvent *e ); + void paintEvent( QPaintEvent *e); + + +signals: + void clicked(); + +}; + +#endif // AQUARIUSBUTTON_H diff --git a/deco/config/baghiraconfig.cc b/deco/config/baghiraconfig.cc new file mode 100644 index 0000000..2054976 --- /dev/null +++ b/deco/config/baghiraconfig.cc @@ -0,0 +1,729 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraconfig.cc +// ------------------- +// Config module for Baghira window decoration +// ------------------- +// Copyright (c) 2004 Thomas Lübking +// Please see the header file for copyright and license information. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "baghiraconfig.h" +#include "configdialog.h" +#include "pixmaps.h" + +////////////////////////////////////////////////////////////////////////////// +// BaghiraConfig Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// BaghiraConfig() +// ------------- +// Constructor + +BaghiraConfig::BaghiraConfig(KConfig*, QWidget* parent) + : QObject(parent), /*config_(0),*/ dialog_(0) +{ +// config_ = new KConfig("baghirarc"); +// config_ = new QSettings; +// config_->beginGroup("/baghira/Deco"); + KGlobal::locale()->insertCatalogue("kwin_baghira_config"); + + dialog_ = new ConfigDialog(parent); + buttonDialog_ = new ButtonColors(parent, "Button Colors"); + load(0L); + + dialog_->show(); + + connect(dialog_->ButtonColorConfig, SIGNAL(clicked()), buttonDialog_, SLOT(exec())); + connect(buttonDialog_->ok, SIGNAL(clicked()), SIGNAL(changed())); + + // connections + connect(dialog_->titlealign, SIGNAL(clicked(int)), SIGNAL(changed())); + connect(dialog_->drawComicFrame, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->addAutoSpacing, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->allowEasyClosing, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->ResizeGrip, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->maxResizable, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->fullSpec, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->noModalDeco, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->delAppname, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->defaultMode, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->minTH, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_T, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_T, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_T, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->_3DImpact_T, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_T, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); +// config_->endGroup(); + +} + +////////////////////////////////////////////////////////////////////////////// +// ~BaghiraConfig() +// -------------- +// Destructor + +BaghiraConfig::~BaghiraConfig() +{ + if (dialog_) delete dialog_; +// if (config_) delete config_; +} + +////////////////////////////////////////////////////////////////////////////// +// load() +// ------ +// Load configuration data + +void BaghiraConfig::load(KConfig*) +{ + QSettings *config_ = new QSettings; + config_->beginGroup("/baghira/Deco"); + + QString value = config_->readEntry("TitleAlignment", "AlignHCenter"); + QRadioButton *button = (QRadioButton*)dialog_->titlealign-> + child((const char *)value.latin1()); + if (button) button->setChecked(true); + + dialog_->minTH->setValue(config_->readNumEntry("minimumTitleHeight",18)); + dialog_->ResizeGrip->setChecked(config_->readBoolEntry("ResizeGrip",false)); + dialog_->allowEasyClosing->setChecked(config_->readBoolEntry("allowEasyClosing",false)); + dialog_->drawComicFrame->setChecked(config_->readBoolEntry("DrawComicFrame",false)); + dialog_->maxResizable->setChecked(config_->readBoolEntry("MaxResizable",false)); + dialog_->fullSpec->setChecked(config_->readBoolEntry("FullSpec",false)); + dialog_->addAutoSpacing->setChecked(config_->readBoolEntry("AddAutoSpacing",true)); + dialog_->defaultMode->setCurrentItem(config_->readNumEntry("defaultMode",1)); + dialog_->noModalDeco->setChecked(config_->readBoolEntry("NoModalDeco",false)); + dialog_->delAppname->setChecked(config_->readBoolEntry("RemoveAppname",false)); + + dialog_->activeColor1_J->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_1",QColor(255,255,255).rgb()))); + dialog_->inactiveColor1_J->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_1",QColor(204,214,230).rgb()))); + dialog_->activeColor2_J->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_1",QColor(238,234,238).rgb()))); + dialog_->inactiveColor2_J->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_1",QColor(194,196,211).rgb()))); + dialog_->buttonStyle_J->setCurrentItem(config_->readNumEntry("ButtonStyle_1",1)); + dialog_->titleeffect_J->setCurrentItem(config_->readNumEntry("TitleEffect_1", 1)); + dialog_->i_titleeffect_J->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_1", 1)); + dialog_->shapeUL_J->setChecked(config_->readBoolEntry("ShapeUL_1",true)); + dialog_->shapeUR_J->setChecked(config_->readBoolEntry("ShapeUR_1",true)); + dialog_->shapeLL_J->setChecked(config_->readBoolEntry("ShapeLL_1",false)); + dialog_->shapeLR_J->setChecked(config_->readBoolEntry("ShapeLR_1",false)); + dialog_->drawIcon_J->setChecked(config_->readBoolEntry("drawIcon_1",true)); + dialog_->_3DImpact_J->setValue(config_->readNumEntry("3DImpact_1",20)); + dialog_->LineImpact_J->setValue(config_->readNumEntry("LineImpact_1",40)); + dialog_->borderSize_J->setValue(config_->readNumEntry("BorderSize_1",0)); + + dialog_->activeColor1_P->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_2",QColor(238,238,238).rgb()))); + dialog_->inactiveColor1_P->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_2",QColor(246,242,246).rgb()))); + dialog_->activeColor2_P->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_2",QColor(205,202,205).rgb()))); + dialog_->inactiveColor2_P->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_2",QColor(238,238,238).rgb()))); + dialog_->buttonStyle_P->setCurrentItem(config_->readNumEntry("ButtonStyle_2",0)); + dialog_->titleeffect_P->setCurrentItem(config_->readNumEntry("TitleEffect_2", 0)); + dialog_->i_titleeffect_P->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_2", 0)); + dialog_->shapeUL_P->setChecked(config_->readBoolEntry("ShapeUL_2",true)); + dialog_->shapeUR_P->setChecked(config_->readBoolEntry("ShapeUR_2",true)); + dialog_->shapeLL_P->setChecked(config_->readBoolEntry("ShapeLL_2",false)); + dialog_->shapeLR_P->setChecked(config_->readBoolEntry("ShapeLR_2",false)); + dialog_->drawIcon_P->setChecked(config_->readBoolEntry("drawIcon_2",true)); + dialog_->_3DImpact_P->setValue(config_->readNumEntry("3DImpact_2",20)); + dialog_->LineImpact_P->setValue(config_->readNumEntry("LineImpact_2",40)); + dialog_->borderSize_P->setValue(config_->readNumEntry("BorderSize_2",0)); + + dialog_->activeColor1_B->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_3",QColor(202,202,202).rgb()))); + dialog_->inactiveColor1_B->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_3",QColor(200,200,200).rgb()))); + dialog_->activeColor2_B->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_3",QColor(150,150,150).rgb()))); + dialog_->inactiveColor2_B->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_3",QColor(150,150,150).rgb()))); + dialog_->buttonStyle_B->setCurrentItem(config_->readNumEntry("ButtonStyle_3",0)); + dialog_->titleeffect_B->setCurrentItem(config_->readNumEntry("TitleEffect_3", 4)); + dialog_->i_titleeffect_B->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_3", 4)); + dialog_->shapeUL_B->setChecked(config_->readBoolEntry("ShapeUL_3",true)); + dialog_->shapeUR_B->setChecked(config_->readBoolEntry("ShapeUR_3",true)); + dialog_->shapeLL_B->setChecked(config_->readBoolEntry("ShapeLL_3",true)); + dialog_->shapeLR_B->setChecked(config_->readBoolEntry("ShapeLR_3",true)); + dialog_->drawIcon_B->setChecked(config_->readBoolEntry("drawIcon_3",true)); + dialog_->_3DImpact_B->setValue(config_->readNumEntry("3DImpact_3",20)); + dialog_->LineImpact_B->setValue(config_->readNumEntry("LineImpact_3",0)); + dialog_->borderSize_B->setValue(config_->readNumEntry("BorderSize_3",6)); + + dialog_->activeColor1_T->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_4",QColor(238,238,238).rgb()))); + dialog_->activeColor2_T->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_4",QColor(205,202,205).rgb()))); + dialog_->buttonStyle_T->setCurrentItem(config_->readNumEntry("ButtonStyle_4",0)); + dialog_->shapeUL_T->setChecked(config_->readBoolEntry("ShapeUL_4",true)); + dialog_->shapeUR_T->setChecked(config_->readBoolEntry("ShapeUR_4",true)); + dialog_->shapeLL_T->setChecked(config_->readBoolEntry("ShapeLL_4",false)); + dialog_->shapeLR_T->setChecked(config_->readBoolEntry("ShapeLR_4",false)); + dialog_->drawIcon_T->setChecked(config_->readBoolEntry("drawIcon_4",true)); + dialog_->_3DImpact_T->setValue(config_->readNumEntry("3DImpact_4",20)); + dialog_->borderSize_T->setValue(config_->readNumEntry("BorderSize_4",0)); + + dialog_->activeColor1_S->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_5",QColor(250,250,250).rgb()))); + dialog_->inactiveColor1_S->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_5",QColor(230,230,230).rgb()))); + dialog_->activeColor2_S->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_5",QColor(230,230,230).rgb()))); + dialog_->inactiveColor2_S->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_5",QColor(250,250,250).rgb()))); + dialog_->buttonStyle_S->setCurrentItem(config_->readNumEntry("ButtonStyle_5",0)); + dialog_->titleeffect_S->setCurrentItem(config_->readNumEntry("TitleEffect_5", 0)); + dialog_->i_titleeffect_S->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_5", 0)); + dialog_->shapeUL_S->setChecked(config_->readBoolEntry("ShapeUL_5",true)); + dialog_->shapeUR_S->setChecked(config_->readBoolEntry("ShapeUR_5",true)); + dialog_->shapeLL_S->setChecked(config_->readBoolEntry("ShapeLL_5",false)); + dialog_->shapeLR_S->setChecked(config_->readBoolEntry("ShapeLR_5",false)); + dialog_->drawIcon_S->setChecked(config_->readBoolEntry("drawIcon_5",true)); + dialog_->_3DImpact_S->setValue(config_->readNumEntry("3DImpact_5",20)); + dialog_->LineImpact_S->setValue(config_->readNumEntry("LineImpact_5",30)); + dialog_->borderSize_S->setValue(config_->readNumEntry("BorderSize_5",0)); + + buttonDialog_->inactiveColor->setColor(QColor((unsigned int)config_->readNumEntry("InactiveButtonColor", QColor(255,255,255).rgb()))); + buttonDialog_->closeColor->setColor(QColor((unsigned int)config_->readNumEntry("CloseButtonColor", QColor(200,85,70).rgb()))); + buttonDialog_->minColor->setColor(QColor((unsigned int)config_->readNumEntry("MinButtonColor", QColor(230,155,40).rgb()))); + buttonDialog_-> maxColor->setColor(QColor((unsigned int)config_->readNumEntry("MaxButtonColor", QColor(121,180,54).rgb()))); + buttonDialog_->menuColor->setColor(QColor((unsigned int)config_->readNumEntry("MenuButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->helpColor->setColor(QColor((unsigned int)config_->readNumEntry("HelpButtonColor", QColor(0,0,0).rgb()))); + buttonDialog_->stickyColor->setColor(QColor((unsigned int)config_->readNumEntry("StickyButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->aboveColor->setColor(QColor((unsigned int)config_->readNumEntry("AboveButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->behindColor->setColor(QColor((unsigned int)config_->readNumEntry("BehindButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->shadeColor->setColor(QColor((unsigned int)config_->readNumEntry("ShadeButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->init(); + config_->endGroup(); + delete config_; + +} + +////////////////////////////////////////////////////////////////////////////// +// save() +// ------ +// Save configuration data + +void BaghiraConfig::save(KConfig*) +{ + QSettings *config_ = new QSettings; + config_->beginGroup("/baghira/Deco"); + + QRadioButton *button = (QRadioButton*)dialog_->titlealign->selected(); + if (button) config_->writeEntry("TitleAlignment", QString(button->name())); + config_->writeEntry("DrawComicFrame", dialog_->drawComicFrame->isChecked()); + config_->writeEntry("AddAutoSpacing", dialog_->addAutoSpacing->isChecked()); + config_->writeEntry("ResizeGrip", dialog_->ResizeGrip->isChecked()); + config_->writeEntry("allowEasyClosing", dialog_->allowEasyClosing->isChecked()); + config_->writeEntry("MaxResizable", dialog_->maxResizable->isChecked()); + config_->writeEntry("FullSpec", dialog_->fullSpec->isChecked()); + config_->writeEntry("defaultMode", dialog_->defaultMode->currentItem()); + config_->writeEntry("minimumTitleHeight", dialog_->minTH->value()); + config_->writeEntry("NoModalDeco", dialog_->noModalDeco->isChecked()); + config_->writeEntry("RemoveAppname", dialog_->delAppname->isChecked()); + + config_->writeEntry("activeColor1_1", (int)dialog_->activeColor1_J->color().rgb()); + config_->writeEntry("activeColor2_1", (int)dialog_->activeColor2_J->color().rgb()); + config_->writeEntry("inactiveColor1_1", (int)dialog_->inactiveColor1_J->color().rgb()); + config_->writeEntry("inactiveColor2_1", (int)dialog_->inactiveColor2_J->color().rgb()); + config_->writeEntry("ButtonStyle_1", dialog_->buttonStyle_J->currentItem()); + config_->writeEntry("TitleEffect_1", dialog_->titleeffect_J->currentItem()); + config_->writeEntry("inactiveTitleEffect_1", dialog_->i_titleeffect_J->currentItem()); + config_->writeEntry("ShapeUL_1", dialog_->shapeUL_J->isChecked()); + config_->writeEntry("ShapeUR_1", dialog_->shapeUR_J->isChecked()); + config_->writeEntry("ShapeLL_1", dialog_->shapeLL_J->isChecked()); + config_->writeEntry("ShapeLR_1", dialog_->shapeLR_J->isChecked()); + config_->writeEntry("drawIcon_1", dialog_->drawIcon_J->isChecked()); + config_->writeEntry("3DImpact_1", dialog_->_3DImpact_J->value()); + config_->writeEntry("LineImpact_1", dialog_->LineImpact_J->value()); + config_->writeEntry("BorderSize_1", dialog_->borderSize_J->value()); + + config_->writeEntry("activeColor1_2", (int)dialog_->activeColor1_P->color().rgb()); + config_->writeEntry("activeColor2_2", (int)dialog_->activeColor2_P->color().rgb()); + config_->writeEntry("inactiveColor1_2", (int)dialog_->inactiveColor1_P->color().rgb()); + config_->writeEntry("inactiveColor2_2", (int)dialog_->inactiveColor2_P->color().rgb()); + config_->writeEntry("ButtonStyle_2", dialog_->buttonStyle_P->currentItem()); + config_->writeEntry("TitleEffect_2", dialog_->titleeffect_P->currentItem()); + config_->writeEntry("inactiveTitleEffect_2", dialog_->i_titleeffect_P->currentItem()); + config_->writeEntry("ShapeUL_2", dialog_->shapeUL_P->isChecked()); + config_->writeEntry("ShapeUR_2", dialog_->shapeUR_P->isChecked()); + config_->writeEntry("ShapeLL_2", dialog_->shapeLL_P->isChecked()); + config_->writeEntry("ShapeLR_2", dialog_->shapeLR_P->isChecked()); + config_->writeEntry("drawIcon_2", dialog_->drawIcon_P->isChecked()); + config_->writeEntry("3DImpact_2", dialog_->_3DImpact_P->value()); + config_->writeEntry("LineImpact_2", dialog_->LineImpact_P->value()); + config_->writeEntry("BorderSize_2", dialog_->borderSize_P->value()); + + config_->writeEntry("activeColor1_3", (int)dialog_->activeColor1_B->color().rgb()); + config_->writeEntry("activeColor2_3", (int)dialog_->activeColor2_B->color().rgb()); + config_->writeEntry("inactiveColor1_3", (int)dialog_->inactiveColor1_B->color().rgb()); + config_->writeEntry("inactiveColor2_3", (int)dialog_->inactiveColor2_B->color().rgb()); + config_->writeEntry("ButtonStyle_3", dialog_->buttonStyle_B->currentItem()); + config_->writeEntry("TitleEffect_3", dialog_->titleeffect_B->currentItem()); + config_->writeEntry("inactiveTitleEffect_3", dialog_->i_titleeffect_B->currentItem()); + config_->writeEntry("ShapeUL_3", dialog_->shapeUL_B->isChecked()); + config_->writeEntry("ShapeUR_3", dialog_->shapeUR_B->isChecked()); + config_->writeEntry("ShapeLL_3", dialog_->shapeLL_B->isChecked()); + config_->writeEntry("ShapeLR_3", dialog_->shapeLR_B->isChecked()); + config_->writeEntry("drawIcon_3", dialog_->drawIcon_B->isChecked()); + config_->writeEntry("3DImpact_3", dialog_->_3DImpact_B->value()); + config_->writeEntry("LineImpact_3", dialog_->LineImpact_B->value()); + config_->writeEntry("BorderSize_3", dialog_->borderSize_B->value()); + + config_->writeEntry("activeColor1_4", (int)dialog_->activeColor1_T->color().rgb()); + config_->writeEntry("activeColor2_4", (int)dialog_->activeColor2_T->color().rgb()); + config_->writeEntry("ButtonStyle_4", dialog_->buttonStyle_T->currentItem()); + config_->writeEntry("ShapeUL_4", dialog_->shapeUL_T->isChecked()); + config_->writeEntry("ShapeUR_4", dialog_->shapeUR_T->isChecked()); + config_->writeEntry("ShapeLL_4", dialog_->shapeLL_T->isChecked()); + config_->writeEntry("ShapeLR_4", dialog_->shapeLR_T->isChecked()); + config_->writeEntry("drawIcon_4", dialog_->drawIcon_T->isChecked()); + config_->writeEntry("3DImpact_4", dialog_->_3DImpact_T->value()); + config_->writeEntry("BorderSize_4", dialog_->borderSize_T->value()); + + config_->writeEntry("activeColor1_5", (int)dialog_->activeColor1_S->color().rgb()); + config_->writeEntry("activeColor2_5", (int)dialog_->activeColor2_S->color().rgb()); + config_->writeEntry("inactiveColor1_5", (int)dialog_->inactiveColor1_S->color().rgb()); + config_->writeEntry("inactiveColor2_5", (int)dialog_->inactiveColor2_S->color().rgb()); + config_->writeEntry("ButtonStyle_5", dialog_->buttonStyle_S->currentItem()); + config_->writeEntry("TitleEffect_5", dialog_->titleeffect_S->currentItem()); + config_->writeEntry("inactiveTitleEffect_5", dialog_->i_titleeffect_S->currentItem()); + config_->writeEntry("ShapeUL_5", dialog_->shapeUL_S->isChecked()); + config_->writeEntry("ShapeUR_5", dialog_->shapeUR_S->isChecked()); + config_->writeEntry("ShapeLL_5", dialog_->shapeLL_S->isChecked()); + config_->writeEntry("ShapeLR_5", dialog_->shapeLR_S->isChecked()); + config_->writeEntry("drawIcon_5", dialog_->drawIcon_S->isChecked()); + config_->writeEntry("3DImpact_5", dialog_->_3DImpact_S->value()); + config_->writeEntry("LineImpact_5", dialog_->LineImpact_S->value()); + config_->writeEntry("BorderSize_5", dialog_->borderSize_S->value()); + + if (buttonDialog_->save){ + config_->writeEntry("InactiveButtonColor", (int)buttonDialog_->inactiveColor->Color().rgb()); + config_->writeEntry("CloseButtonColor", (int)buttonDialog_->closeColor->Color().rgb()); + config_->writeEntry("MinButtonColor", (int)buttonDialog_->minColor->Color().rgb()); + config_->writeEntry("MaxButtonColor", (int)buttonDialog_->maxColor->Color().rgb()); + config_->writeEntry("MenuButtonColor", (int)buttonDialog_->menuColor->Color().rgb()); + config_->writeEntry("HelpButtonColor", (int)buttonDialog_->helpColor->Color().rgb()); + config_->writeEntry("StickyButtonColor", (int)buttonDialog_->stickyColor->Color().rgb()); + config_->writeEntry("AboveButtonColor", (int)buttonDialog_->aboveColor->Color().rgb()); + config_->writeEntry("BehindButtonColor", (int)buttonDialog_->behindColor->Color().rgb()); + config_->writeEntry("ShadeButtonColor", (int)buttonDialog_->shadeColor->Color().rgb()); + } + config_->endGroup(); + delete config_; + +// config_->sync(); +} + +////////////////////////////////////////////////////////////////////////////// +// defaults() +// ---------- +// Set configuration defaults + +void BaghiraConfig::defaults() +{ + QRadioButton *button = (QRadioButton*)dialog_->titlealign->child("AlignHCenter"); + if (button) button->setChecked(true); + dialog_->allowEasyClosing->setChecked(false); + dialog_->minTH->setValue(22); + dialog_->ResizeGrip->setChecked(false); + dialog_->drawComicFrame->setChecked(false); + dialog_->addAutoSpacing->setChecked(true); + dialog_->maxResizable->setChecked(false); + dialog_->fullSpec->setChecked(false); + dialog_->defaultMode->setCurrentItem(1); + dialog_->noModalDeco->setChecked(false); + dialog_->delAppname->setChecked(false); + + dialog_->activeColor1_J->setColor(QColor(255,255,255)); + dialog_->inactiveColor1_J->setColor(QColor(204,214,230)); + dialog_->activeColor2_J->setColor(QColor(238,234,238)); + dialog_->inactiveColor2_J->setColor(QColor(194,196,211)); + dialog_->buttonStyle_J->setCurrentItem(1); + dialog_->titleeffect_J->setCurrentItem(1); + dialog_->i_titleeffect_J->setCurrentItem(1); + dialog_->shapeUL_J->setChecked(true); + dialog_->shapeUR_J->setChecked(true); + dialog_->shapeLL_J->setChecked(false); + dialog_->shapeLR_J->setChecked(false); + dialog_->drawIcon_J->setChecked(true); + dialog_->_3DImpact_J->setValue(20); + dialog_->LineImpact_J->setValue(40); + dialog_->borderSize_J->setValue(0); + + dialog_->activeColor1_P->setColor(QColor(238,238,238)); + dialog_->inactiveColor1_P->setColor(QColor(246,242,246)); + dialog_->activeColor2_P->setColor(QColor(205,202,205)); + dialog_->inactiveColor2_P->setColor(QColor(238,238,238)); + dialog_->buttonStyle_P->setCurrentItem(0); + dialog_->titleeffect_P->setCurrentItem(0); + dialog_->i_titleeffect_P->setCurrentItem(0); + dialog_->shapeUL_P->setChecked(true); + dialog_->shapeUR_P->setChecked(true); + dialog_->shapeLL_P->setChecked(false); + dialog_->shapeLR_P->setChecked(false); + dialog_->drawIcon_P->setChecked(true); + dialog_->_3DImpact_P->setValue(20); + dialog_->LineImpact_P->setValue(30); + dialog_->borderSize_P->setValue(0); + + dialog_->activeColor1_B->setColor(QColor(210,210,210)); + dialog_->inactiveColor1_B->setColor(QColor(200,200,200)); + dialog_->activeColor2_B->setColor(QColor(150,150,150)); + dialog_->inactiveColor2_B->setColor(QColor(140,140,140)); + dialog_->buttonStyle_B->setCurrentItem(0); + dialog_->titleeffect_B->setCurrentItem(4); + dialog_->i_titleeffect_B->setCurrentItem(4); + dialog_->shapeUL_B->setChecked(true); + dialog_->shapeUR_B->setChecked(true); + dialog_->shapeLL_B->setChecked(false); + dialog_->shapeLR_B->setChecked(false); + dialog_->drawIcon_B->setChecked(true); + dialog_->_3DImpact_B->setValue(20); + dialog_->LineImpact_B->setValue(0); + dialog_->borderSize_B->setValue(6); + + dialog_->activeColor1_T->setColor(QColor(238,238,238)); + dialog_->activeColor2_T->setColor(QColor(211,208,211)); + dialog_->buttonStyle_T->setCurrentItem(0); + dialog_->shapeUL_T->setChecked(true); + dialog_->shapeUR_T->setChecked(true); + dialog_->shapeLL_T->setChecked(false); + dialog_->shapeLR_T->setChecked(false); + dialog_->drawIcon_T->setChecked(true); + dialog_->_3DImpact_T->setValue(20); + dialog_->borderSize_T->setValue(0); + + dialog_->activeColor1_S->setColor(QColor(250,250,250)); + dialog_->inactiveColor1_S->setColor(QColor(230,230,230)); + dialog_->activeColor2_S->setColor(QColor(230,230,230)); + dialog_->inactiveColor2_S->setColor(QColor(250,250,250)); + dialog_->buttonStyle_S->setCurrentItem(0); + dialog_->titleeffect_S->setCurrentItem(0); + dialog_->i_titleeffect_S->setCurrentItem(0); + dialog_->shapeUL_S->setChecked(true); + dialog_->shapeUR_S->setChecked(true); + dialog_->shapeLL_S->setChecked(false); + dialog_->shapeLR_S->setChecked(false); + dialog_->drawIcon_S->setChecked(true); + dialog_->_3DImpact_S->setValue(20); + dialog_->LineImpact_S->setValue(30); + dialog_->borderSize_S->setValue(0); + +// buttonDialog_->defaults(); + + +} + +enum ColorPresets{Aqua = 0, Graphite, GraphiteDark, NUMBEROFCOLORS}; + +const char * presetColorName[NUMBEROFCOLORS] = {"Aqua", "Graphite", "Graphite (Dark)" }; + +typedef int ColorTable[10][3]; + +const int aquaPreset[10][3] = {{255,255,255},{200,85,70},{230,155,40},{121,180,54},{74,140,242},{0,0,0},{74,140,242},{74,140,242},{74,140,242},{74,140,242}}; +const int graphitePreset[10][3] = {{255,255,255},{130,170,190},{130,170,190},{130,170,190},{130,170,190},{0,0,0},{130,170,190},{130,170,190},{130,170,190},{130,170,190}}; +const int graphiteDarkPreset[10][3] = {{255,255,255},{103,118,134},{103,118,134},{103,118,134},{103,118,134},{0,0,0},{103,118,134},{103,118,134},{103,118,134},{103,118,134}}; +const ColorTable* presetColors[NUMBEROFCOLORS] = {&aquaPreset, &graphitePreset, &graphiteDarkPreset}; + + +ButtonColors::ButtonColors(QWidget *parent, const char * name) : QDialog(parent, name){ + save = false; + layout = new QGridLayout(this,2,2,11,6, "Grid"); + buttonLayout = new QVBoxLayout(0,0,6); + + QPixmap tmpPix = QPixmap(uic_findImage("preview")); + inactiveButton = new AquariusButton(tmpPix,this, "Inactive Button"); + buttonLayout->addWidget(inactiveButton); + closeButton = new AquariusButton(tmpPix,this, "Close Button"); + buttonLayout->addWidget(closeButton); + minButton = new AquariusButton(tmpPix,this, "Minimize Button"); + buttonLayout->addWidget(minButton); + maxButton = new AquariusButton(tmpPix,this, "Maximize Button"); + buttonLayout->addWidget(maxButton); + stickyButton = new AquariusButton(tmpPix,this, "Sticky Button"); + buttonLayout->addWidget(stickyButton); + aboveButton = new AquariusButton(tmpPix,this, "Above Button"); + buttonLayout->addWidget(aboveButton); + behindButton = new AquariusButton(tmpPix,this, "Behind Button"); + buttonLayout->addWidget(behindButton); + shadeButton = new AquariusButton(tmpPix,this, "Shade Button"); + buttonLayout->addWidget(shadeButton); + tmpPix = QPixmap(uic_findImage("preview-menu")); + menuButton = new AquariusButton(tmpPix,this, "Menu Button"); + buttonLayout->addWidget(menuButton); + tmpPix = QPixmap(uic_findImage("icon_help")); + helpButton = new AquariusButton(tmpPix,this, "Help Button"); + buttonLayout->addWidget(helpButton); + + + twoButts = new QHBoxLayout(0,0,6); + presets_ = new QComboBox(this); + for (int i = 0; i < NUMBEROFCOLORS; i++) + presets_->insertItem ( presetColorName[i], i ); + twoButts->addWidget(presets_); + cancel = new QPushButton("Cancel", this); + cancel->setDefault( true ); + twoButts->addWidget(cancel); + twoButts->addStretch(); + layout->addLayout(twoButts,1,0); + ok = new QPushButton("OK", this); + layout->addWidget(ok,1,1); + + layout->addLayout(buttonLayout,0,1); + + pickerLayout = new QVBoxLayout(0,0,6,0); + + indicator = new QLabel(inactiveButton->name(), this); + indicator->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter | Qt::ExpandTabs); + QFont tmpFont = font(); + tmpFont.setBold( true ); + tmpFont.setPointSize( 24 ); + indicator->setFont(tmpFont); + pickerLayout->addWidget(indicator); + + inactiveColor = new ColorPicker(this); + pickerLayout->addWidget(inactiveColor); + currentPicker = inactiveColor; + closeColor = new ColorPicker(this); + pickerLayout->addWidget(closeColor); + closeColor->hide(); + minColor = new ColorPicker(this); + pickerLayout->addWidget(minColor); + minColor->hide(); + maxColor = new ColorPicker(this); + pickerLayout->addWidget(maxColor); + maxColor->hide(); + menuColor = new ColorPicker(this); + pickerLayout->addWidget(menuColor); + menuColor->hide(); + helpColor = new ColorPicker(this); + pickerLayout->addWidget(helpColor); + helpColor->hide(); + stickyColor = new ColorPicker(this); + pickerLayout->addWidget(stickyColor); + stickyColor->hide(); + aboveColor = new ColorPicker(this); + pickerLayout->addWidget(aboveColor); + aboveColor->hide(); + behindColor = new ColorPicker(this); + pickerLayout->addWidget(behindColor); + behindColor->hide(); + shadeColor = new ColorPicker(this); + pickerLayout->addWidget(shadeColor); + shadeColor->hide(); + + indicator->lower(); + + layout->addLayout(pickerLayout,0,0); + + resize( QSize(485, 177).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + connect(presets_,SIGNAL(activated(int)), this, SLOT(setColorGroup(int))); + connect(ok, SIGNAL(clicked()), this, SLOT(setSave())); + connect(ok, SIGNAL(clicked()), this, SLOT(close()) ); + connect(ok, SIGNAL(clicked()), this, SLOT(init()) ); + connect(cancel, SIGNAL(clicked()), this, SLOT(close()) ); + connect(cancel, SIGNAL(clicked()), this, SLOT(reset()) ); + + connect(inactiveButton, SIGNAL(clicked()), this, SLOT(activateInactive()) ); + connect(closeButton, SIGNAL(clicked()), this, SLOT(activateClose()) ); + connect(minButton, SIGNAL(clicked()), this, SLOT(activateMin()) ); + connect(maxButton, SIGNAL(clicked()), this, SLOT(activateMax()) ); + connect(menuButton, SIGNAL(clicked()), this, SLOT(activateMenu()) ); + connect(helpButton, SIGNAL(clicked()), this, SLOT(activateHelp()) ); + connect(stickyButton, SIGNAL(clicked()), this, SLOT(activateSticky()) ); + connect(aboveButton, SIGNAL(clicked()), this, SLOT(activateAbove()) ); + connect(behindButton, SIGNAL(clicked()), this, SLOT(activateBehind()) ); + connect(shadeButton, SIGNAL(clicked()), this, SLOT(activateShade()) ); + + connect(inactiveColor, SIGNAL(colorChanged(QColor)), inactiveButton, SLOT(setColor(QColor)) ); + connect(closeColor, SIGNAL(colorChanged(QColor)), closeButton, SLOT(setColor(QColor)) ); + connect(minColor, SIGNAL(colorChanged(QColor)), minButton, SLOT(setColor(QColor)) ); + connect(maxColor, SIGNAL(colorChanged(QColor)), maxButton, SLOT(setColor(QColor)) ); + connect(menuColor, SIGNAL(colorChanged(QColor)), menuButton, SLOT(setColor(QColor)) ); + connect(helpColor, SIGNAL(colorChanged(QColor)), helpButton, SLOT(setColor(QColor)) ); + connect(stickyColor, SIGNAL(colorChanged(QColor)), stickyButton, SLOT(setColor(QColor)) ); + connect(aboveColor, SIGNAL(colorChanged(QColor)), aboveButton, SLOT(setColor(QColor)) ); + connect(behindColor, SIGNAL(colorChanged(QColor)), behindButton, SLOT(setColor(QColor)) ); + connect(shadeColor, SIGNAL(colorChanged(QColor)), shadeButton, SLOT(setColor(QColor)) ); + +} + +ButtonColors::~ButtonColors(){ +} + +void ButtonColors::setColorGroup(int i){ + inactiveColor->setColor(QColor((*presetColors[i])[0][0],(*presetColors[i])[0][1],(*presetColors[i])[0][2]).rgb()); + closeColor->setColor(QColor((*presetColors[i])[1][0],(*presetColors[i])[1][1],(*presetColors[i])[1][2]).rgb()); + minColor->setColor(QColor((*presetColors[i])[2][0],(*presetColors[i])[2][1],(*presetColors[i])[2][2]).rgb()); + maxColor->setColor(QColor((*presetColors[i])[3][0],(*presetColors[i])[3][1],(*presetColors[i])[3][2]).rgb()); + menuColor->setColor(QColor((*presetColors[i])[4][0],(*presetColors[i])[4][1],(*presetColors[i])[4][2]).rgb()); + helpColor->setColor(QColor((*presetColors[i])[5][0],(*presetColors[i])[5][1],(*presetColors[i])[5][2]).rgb()); + stickyColor->setColor(QColor((*presetColors[i])[6][0],(*presetColors[i])[6][1],(*presetColors[i])[6][2]).rgb()); + aboveColor->setColor(QColor((*presetColors[i])[7][0],(*presetColors[i])[7][1],(*presetColors[i])[7][2]).rgb()); + behindColor->setColor(QColor((*presetColors[i])[8][0],(*presetColors[i])[8][1],(*presetColors[i])[8][2]).rgb()); + shadeColor->setColor(QColor((*presetColors[i])[9][0],(*presetColors[i])[9][1],(*presetColors[i])[9][2]).rgb()); +} + +void ButtonColors::setPicker(ColorPicker *picker){ + if (currentPicker) currentPicker->hide(); + currentPicker = picker; + currentPicker->show(); +} + +void ButtonColors::activateInactive(){ + setPicker(inactiveColor); + indicator->setText( inactiveButton->name() ); +} +void ButtonColors::activateClose(){ + setPicker(closeColor); + indicator->setText( closeButton->name() ); +} +void ButtonColors::activateMin(){ + setPicker(minColor); + indicator->setText( minButton->name() ); +} +void ButtonColors::activateMax(){ + setPicker(maxColor); + indicator->setText( maxButton->name() ); +} +void ButtonColors::activateMenu(){ + setPicker(menuColor); + indicator->setText( menuButton->name() ); +} +void ButtonColors::activateHelp(){ + setPicker(helpColor); + indicator->setText( helpButton->name() ); +} +void ButtonColors::activateSticky(){ + setPicker(stickyColor); + indicator->setText( stickyButton->name() ); +} +void ButtonColors::activateAbove(){ + setPicker(aboveColor); + indicator->setText( aboveButton->name() ); +} +void ButtonColors::activateBehind(){ + setPicker(behindColor); + indicator->setText( behindButton->name() ); +} +void ButtonColors::activateShade(){ + setPicker(shadeColor); + indicator->setText( shadeButton->name() ); +} + +void ButtonColors::reset(){ + inactiveColor->reset(); + closeColor->reset(); + minColor->reset(); + maxColor->reset(); + menuColor->reset(); + helpColor->reset(); + stickyColor->reset(); + aboveColor->reset(); + behindColor->reset(); + shadeColor->reset(); +} + +void ButtonColors::init(){ + inactiveColor->init(); + closeColor->init(); + minColor->init(); + maxColor->init(); + menuColor->init(); + helpColor->init(); + stickyColor->init(); + aboveColor->init(); + behindColor->init(); + shadeColor->init(); +} + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + QObject* allocate_config(KConfig* config, QWidget* parent) { + return(new BaghiraConfig(config, parent)); + } +} + +#include "baghiraconfig.moc" diff --git a/deco/config/baghiraconfig.cc.new b/deco/config/baghiraconfig.cc.new new file mode 100644 index 0000000..8d83666 --- /dev/null +++ b/deco/config/baghiraconfig.cc.new @@ -0,0 +1,730 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraconfig.cc +// ------------------- +// Config module for Baghira window decoration +// ------------------- +// Copyright (c) 2004 Thomas Lübking +// Please see the header file for copyright and license information. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "baghiraconfig.h" +#include "configdialog.h" +#include "customdecosettings.h" +#include "pixmaps.h" + +////////////////////////////////////////////////////////////////////////////// +// BaghiraConfig Class // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// BaghiraConfig() +// ------------- +// Constructor + +BaghiraConfig::BaghiraConfig(KConfig*, QWidget* parent) + : QObject(parent), /*config_(0),*/ dialog_(0) +{ +// config_ = new KConfig("baghirarc"); +// config_ = new QSettings; +// config_->beginGroup("/baghira/Deco"); + KGlobal::locale()->insertCatalogue("kwin_baghira_config"); + + dialog_ = new ConfigDialog(parent); + buttonDialog_ = new ButtonColors(parent, "Button Colors"); + load(0L); + + dialog_->show(); + + connect(dialog_->ButtonColorConfig, SIGNAL(clicked()), buttonDialog_, SLOT(exec())); + connect(buttonDialog_->ok, SIGNAL(clicked()), SIGNAL(changed())); + + // connections + connect(dialog_->titlealign, SIGNAL(clicked(int)), SIGNAL(changed())); + connect(dialog_->drawComicFrame, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->addAutoSpacing, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->allowEasyClosing, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->ResizeGrip, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->maxResizable, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->fullSpec, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->noModalDeco, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->delAppname, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->defaultMode, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->minTH, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_J, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_J, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_J, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_J, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_P, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_P, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_P, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_P, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_B, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_B, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_B, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_B, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_T, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_T, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_T, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_T, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->_3DImpact_T, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_T, SIGNAL(valueChanged(int)), SIGNAL(changed())); + + connect(dialog_->activeColor1_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->activeColor2_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor1_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->inactiveColor2_S, SIGNAL(clicked()), SIGNAL(changed())); + connect(dialog_->buttonStyle_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->shapeUL_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeUR_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLL_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->shapeLR_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->drawIcon_S, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(dialog_->titleeffect_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->i_titleeffect_S, SIGNAL(activated(int)), SIGNAL(changed())); + connect(dialog_->_3DImpact_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->LineImpact_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); + connect(dialog_->borderSize_S, SIGNAL(valueChanged(int)), SIGNAL(changed())); +// config_->endGroup(); + +} + +////////////////////////////////////////////////////////////////////////////// +// ~BaghiraConfig() +// -------------- +// Destructor + +BaghiraConfig::~BaghiraConfig() +{ + if (dialog_) delete dialog_; +// if (config_) delete config_; +} + +////////////////////////////////////////////////////////////////////////////// +// load() +// ------ +// Load configuration data + +void BaghiraConfig::load(KConfig*) +{ + QSettings *config_ = new QSettings; + config_->beginGroup("/baghira/Deco"); + + QString value = config_->readEntry("TitleAlignment", "AlignHCenter"); + QRadioButton *button = (QRadioButton*)dialog_->titlealign-> + child((const char *)value.latin1()); + if (button) button->setChecked(true); + + dialog_->minTH->setValue(config_->readNumEntry("minimumTitleHeight",18)); + dialog_->ResizeGrip->setChecked(config_->readBoolEntry("ResizeGrip",false)); + dialog_->allowEasyClosing->setChecked(config_->readBoolEntry("allowEasyClosing",false)); + dialog_->drawComicFrame->setChecked(config_->readBoolEntry("DrawComicFrame",false)); + dialog_->maxResizable->setChecked(config_->readBoolEntry("MaxResizable",false)); + dialog_->fullSpec->setChecked(config_->readBoolEntry("FullSpec",false)); + dialog_->addAutoSpacing->setChecked(config_->readBoolEntry("AddAutoSpacing",true)); + dialog_->defaultMode->setCurrentItem(config_->readNumEntry("defaultMode",1)); + dialog_->noModalDeco->setChecked(config_->readBoolEntry("NoModalDeco",false)); + dialog_->delAppname->setChecked(config_->readBoolEntry("RemoveAppname",false)); + + dialog_->activeColor1_J->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_1",QColor(255,255,255).rgb()))); + dialog_->inactiveColor1_J->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_1",QColor(204,214,230).rgb()))); + dialog_->activeColor2_J->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_1",QColor(238,234,238).rgb()))); + dialog_->inactiveColor2_J->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_1",QColor(194,196,211).rgb()))); + dialog_->buttonStyle_J->setCurrentItem(config_->readNumEntry("ButtonStyle_1",1)); + dialog_->titleeffect_J->setCurrentItem(config_->readNumEntry("TitleEffect_1", 1)); + dialog_->i_titleeffect_J->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_1", 1)); + dialog_->shapeUL_J->setChecked(config_->readBoolEntry("ShapeUL_1",true)); + dialog_->shapeUR_J->setChecked(config_->readBoolEntry("ShapeUR_1",true)); + dialog_->shapeLL_J->setChecked(config_->readBoolEntry("ShapeLL_1",false)); + dialog_->shapeLR_J->setChecked(config_->readBoolEntry("ShapeLR_1",false)); + dialog_->drawIcon_J->setChecked(config_->readBoolEntry("drawIcon_1",true)); + dialog_->_3DImpact_J->setValue(config_->readNumEntry("3DImpact_1",20)); + dialog_->LineImpact_J->setValue(config_->readNumEntry("LineImpact_1",40)); + dialog_->borderSize_J->setValue(config_->readNumEntry("BorderSize_1",0)); + + dialog_->activeColor1_P->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_2",QColor(238,238,238).rgb()))); + dialog_->inactiveColor1_P->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_2",QColor(246,242,246).rgb()))); + dialog_->activeColor2_P->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_2",QColor(205,202,205).rgb()))); + dialog_->inactiveColor2_P->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_2",QColor(238,238,238).rgb()))); + dialog_->buttonStyle_P->setCurrentItem(config_->readNumEntry("ButtonStyle_2",0)); + dialog_->titleeffect_P->setCurrentItem(config_->readNumEntry("TitleEffect_2", 0)); + dialog_->i_titleeffect_P->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_2", 0)); + dialog_->shapeUL_P->setChecked(config_->readBoolEntry("ShapeUL_2",true)); + dialog_->shapeUR_P->setChecked(config_->readBoolEntry("ShapeUR_2",true)); + dialog_->shapeLL_P->setChecked(config_->readBoolEntry("ShapeLL_2",false)); + dialog_->shapeLR_P->setChecked(config_->readBoolEntry("ShapeLR_2",false)); + dialog_->drawIcon_P->setChecked(config_->readBoolEntry("drawIcon_2",true)); + dialog_->_3DImpact_P->setValue(config_->readNumEntry("3DImpact_2",20)); + dialog_->LineImpact_P->setValue(config_->readNumEntry("LineImpact_2",40)); + dialog_->borderSize_P->setValue(config_->readNumEntry("BorderSize_2",0)); + + dialog_->activeColor1_B->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_3",QColor(202,202,202).rgb()))); + dialog_->inactiveColor1_B->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_3",QColor(200,200,200).rgb()))); + dialog_->activeColor2_B->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_3",QColor(150,150,150).rgb()))); + dialog_->inactiveColor2_B->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_3",QColor(150,150,150).rgb()))); + dialog_->buttonStyle_B->setCurrentItem(config_->readNumEntry("ButtonStyle_3",0)); + dialog_->titleeffect_B->setCurrentItem(config_->readNumEntry("TitleEffect_3", 4)); + dialog_->i_titleeffect_B->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_3", 4)); + dialog_->shapeUL_B->setChecked(config_->readBoolEntry("ShapeUL_3",true)); + dialog_->shapeUR_B->setChecked(config_->readBoolEntry("ShapeUR_3",true)); + dialog_->shapeLL_B->setChecked(config_->readBoolEntry("ShapeLL_3",true)); + dialog_->shapeLR_B->setChecked(config_->readBoolEntry("ShapeLR_3",true)); + dialog_->drawIcon_B->setChecked(config_->readBoolEntry("drawIcon_3",true)); + dialog_->_3DImpact_B->setValue(config_->readNumEntry("3DImpact_3",20)); + dialog_->LineImpact_B->setValue(config_->readNumEntry("LineImpact_3",0)); + dialog_->borderSize_B->setValue(config_->readNumEntry("BorderSize_3",6)); + + dialog_->activeColor1_T->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_4",QColor(238,238,238).rgb()))); + dialog_->activeColor2_T->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_4",QColor(205,202,205).rgb()))); + dialog_->buttonStyle_T->setCurrentItem(config_->readNumEntry("ButtonStyle_4",0)); + dialog_->shapeUL_T->setChecked(config_->readBoolEntry("ShapeUL_4",true)); + dialog_->shapeUR_T->setChecked(config_->readBoolEntry("ShapeUR_4",true)); + dialog_->shapeLL_T->setChecked(config_->readBoolEntry("ShapeLL_4",false)); + dialog_->shapeLR_T->setChecked(config_->readBoolEntry("ShapeLR_4",false)); + dialog_->drawIcon_T->setChecked(config_->readBoolEntry("drawIcon_4",true)); + dialog_->_3DImpact_T->setValue(config_->readNumEntry("3DImpact_4",20)); + dialog_->borderSize_T->setValue(config_->readNumEntry("BorderSize_4",0)); + + dialog_->activeColor1_S->setColor(QColor((unsigned int)config_->readNumEntry("activeColor1_5",QColor(250,250,250).rgb()))); + dialog_->inactiveColor1_S->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor1_5",QColor(230,230,230).rgb()))); + dialog_->activeColor2_S->setColor(QColor((unsigned int)config_->readNumEntry("activeColor2_5",QColor(230,230,230).rgb()))); + dialog_->inactiveColor2_S->setColor(QColor((unsigned int)config_->readNumEntry("inactiveColor2_5",QColor(250,250,250).rgb()))); + dialog_->buttonStyle_S->setCurrentItem(config_->readNumEntry("ButtonStyle_5",0)); + dialog_->titleeffect_S->setCurrentItem(config_->readNumEntry("TitleEffect_5", 0)); + dialog_->i_titleeffect_S->setCurrentItem(config_->readNumEntry("inactiveTitleEffect_5", 0)); + dialog_->shapeUL_S->setChecked(config_->readBoolEntry("ShapeUL_5",true)); + dialog_->shapeUR_S->setChecked(config_->readBoolEntry("ShapeUR_5",true)); + dialog_->shapeLL_S->setChecked(config_->readBoolEntry("ShapeLL_5",false)); + dialog_->shapeLR_S->setChecked(config_->readBoolEntry("ShapeLR_5",false)); + dialog_->drawIcon_S->setChecked(config_->readBoolEntry("drawIcon_5",true)); + dialog_->_3DImpact_S->setValue(config_->readNumEntry("3DImpact_5",20)); + dialog_->LineImpact_S->setValue(config_->readNumEntry("LineImpact_5",30)); + dialog_->borderSize_S->setValue(config_->readNumEntry("BorderSize_5",0)); + + buttonDialog_->inactiveColor->setColor(QColor((unsigned int)config_->readNumEntry("InactiveButtonColor", QColor(255,255,255).rgb()))); + buttonDialog_->closeColor->setColor(QColor((unsigned int)config_->readNumEntry("CloseButtonColor", QColor(200,85,70).rgb()))); + buttonDialog_->minColor->setColor(QColor((unsigned int)config_->readNumEntry("MinButtonColor", QColor(230,155,40).rgb()))); + buttonDialog_-> maxColor->setColor(QColor((unsigned int)config_->readNumEntry("MaxButtonColor", QColor(121,180,54).rgb()))); + buttonDialog_->menuColor->setColor(QColor((unsigned int)config_->readNumEntry("MenuButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->helpColor->setColor(QColor((unsigned int)config_->readNumEntry("HelpButtonColor", QColor(0,0,0).rgb()))); + buttonDialog_->stickyColor->setColor(QColor((unsigned int)config_->readNumEntry("StickyButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->aboveColor->setColor(QColor((unsigned int)config_->readNumEntry("AboveButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->behindColor->setColor(QColor((unsigned int)config_->readNumEntry("BehindButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->shadeColor->setColor(QColor((unsigned int)config_->readNumEntry("ShadeButtonColor", QColor(74,140,242).rgb()))); + buttonDialog_->init(); + config_->endGroup(); + delete config_; + +} + +////////////////////////////////////////////////////////////////////////////// +// save() +// ------ +// Save configuration data + +void BaghiraConfig::save(KConfig*) +{ + QSettings *config_ = new QSettings; + config_->beginGroup("/baghira/Deco"); + + QRadioButton *button = (QRadioButton*)dialog_->titlealign->selected(); + if (button) config_->writeEntry("TitleAlignment", QString(button->name())); + config_->writeEntry("DrawComicFrame", dialog_->drawComicFrame->isChecked()); + config_->writeEntry("AddAutoSpacing", dialog_->addAutoSpacing->isChecked()); + config_->writeEntry("ResizeGrip", dialog_->ResizeGrip->isChecked()); + config_->writeEntry("allowEasyClosing", dialog_->allowEasyClosing->isChecked()); + config_->writeEntry("MaxResizable", dialog_->maxResizable->isChecked()); + config_->writeEntry("FullSpec", dialog_->fullSpec->isChecked()); + config_->writeEntry("defaultMode", dialog_->defaultMode->currentItem()); + config_->writeEntry("minimumTitleHeight", dialog_->minTH->value()); + config_->writeEntry("NoModalDeco", dialog_->noModalDeco->isChecked()); + config_->writeEntry("RemoveAppname", dialog_->delAppname->isChecked()); + + config_->writeEntry("activeColor1_1", (int)dialog_->activeColor1_J->color().rgb()); + config_->writeEntry("activeColor2_1", (int)dialog_->activeColor2_J->color().rgb()); + config_->writeEntry("inactiveColor1_1", (int)dialog_->inactiveColor1_J->color().rgb()); + config_->writeEntry("inactiveColor2_1", (int)dialog_->inactiveColor2_J->color().rgb()); + config_->writeEntry("ButtonStyle_1", dialog_->buttonStyle_J->currentItem()); + config_->writeEntry("TitleEffect_1", dialog_->titleeffect_J->currentItem()); + config_->writeEntry("inactiveTitleEffect_1", dialog_->i_titleeffect_J->currentItem()); + config_->writeEntry("ShapeUL_1", dialog_->shapeUL_J->isChecked()); + config_->writeEntry("ShapeUR_1", dialog_->shapeUR_J->isChecked()); + config_->writeEntry("ShapeLL_1", dialog_->shapeLL_J->isChecked()); + config_->writeEntry("ShapeLR_1", dialog_->shapeLR_J->isChecked()); + config_->writeEntry("drawIcon_1", dialog_->drawIcon_J->isChecked()); + config_->writeEntry("3DImpact_1", dialog_->_3DImpact_J->value()); + config_->writeEntry("LineImpact_1", dialog_->LineImpact_J->value()); + config_->writeEntry("BorderSize_1", dialog_->borderSize_J->value()); + + config_->writeEntry("activeColor1_2", (int)dialog_->activeColor1_P->color().rgb()); + config_->writeEntry("activeColor2_2", (int)dialog_->activeColor2_P->color().rgb()); + config_->writeEntry("inactiveColor1_2", (int)dialog_->inactiveColor1_P->color().rgb()); + config_->writeEntry("inactiveColor2_2", (int)dialog_->inactiveColor2_P->color().rgb()); + config_->writeEntry("ButtonStyle_2", dialog_->buttonStyle_P->currentItem()); + config_->writeEntry("TitleEffect_2", dialog_->titleeffect_P->currentItem()); + config_->writeEntry("inactiveTitleEffect_2", dialog_->i_titleeffect_P->currentItem()); + config_->writeEntry("ShapeUL_2", dialog_->shapeUL_P->isChecked()); + config_->writeEntry("ShapeUR_2", dialog_->shapeUR_P->isChecked()); + config_->writeEntry("ShapeLL_2", dialog_->shapeLL_P->isChecked()); + config_->writeEntry("ShapeLR_2", dialog_->shapeLR_P->isChecked()); + config_->writeEntry("drawIcon_2", dialog_->drawIcon_P->isChecked()); + config_->writeEntry("3DImpact_2", dialog_->_3DImpact_P->value()); + config_->writeEntry("LineImpact_2", dialog_->LineImpact_P->value()); + config_->writeEntry("BorderSize_2", dialog_->borderSize_P->value()); + + config_->writeEntry("activeColor1_3", (int)dialog_->activeColor1_B->color().rgb()); + config_->writeEntry("activeColor2_3", (int)dialog_->activeColor2_B->color().rgb()); + config_->writeEntry("inactiveColor1_3", (int)dialog_->inactiveColor1_B->color().rgb()); + config_->writeEntry("inactiveColor2_3", (int)dialog_->inactiveColor2_B->color().rgb()); + config_->writeEntry("ButtonStyle_3", dialog_->buttonStyle_B->currentItem()); + config_->writeEntry("TitleEffect_3", dialog_->titleeffect_B->currentItem()); + config_->writeEntry("inactiveTitleEffect_3", dialog_->i_titleeffect_B->currentItem()); + config_->writeEntry("ShapeUL_3", dialog_->shapeUL_B->isChecked()); + config_->writeEntry("ShapeUR_3", dialog_->shapeUR_B->isChecked()); + config_->writeEntry("ShapeLL_3", dialog_->shapeLL_B->isChecked()); + config_->writeEntry("ShapeLR_3", dialog_->shapeLR_B->isChecked()); + config_->writeEntry("drawIcon_3", dialog_->drawIcon_B->isChecked()); + config_->writeEntry("3DImpact_3", dialog_->_3DImpact_B->value()); + config_->writeEntry("LineImpact_3", dialog_->LineImpact_B->value()); + config_->writeEntry("BorderSize_3", dialog_->borderSize_B->value()); + + config_->writeEntry("activeColor1_4", (int)dialog_->activeColor1_T->color().rgb()); + config_->writeEntry("activeColor2_4", (int)dialog_->activeColor2_T->color().rgb()); + config_->writeEntry("ButtonStyle_4", dialog_->buttonStyle_T->currentItem()); + config_->writeEntry("ShapeUL_4", dialog_->shapeUL_T->isChecked()); + config_->writeEntry("ShapeUR_4", dialog_->shapeUR_T->isChecked()); + config_->writeEntry("ShapeLL_4", dialog_->shapeLL_T->isChecked()); + config_->writeEntry("ShapeLR_4", dialog_->shapeLR_T->isChecked()); + config_->writeEntry("drawIcon_4", dialog_->drawIcon_T->isChecked()); + config_->writeEntry("3DImpact_4", dialog_->_3DImpact_T->value()); + config_->writeEntry("BorderSize_4", dialog_->borderSize_T->value()); + + config_->writeEntry("activeColor1_5", (int)dialog_->activeColor1_S->color().rgb()); + config_->writeEntry("activeColor2_5", (int)dialog_->activeColor2_S->color().rgb()); + config_->writeEntry("inactiveColor1_5", (int)dialog_->inactiveColor1_S->color().rgb()); + config_->writeEntry("inactiveColor2_5", (int)dialog_->inactiveColor2_S->color().rgb()); + config_->writeEntry("ButtonStyle_5", dialog_->buttonStyle_S->currentItem()); + config_->writeEntry("TitleEffect_5", dialog_->titleeffect_S->currentItem()); + config_->writeEntry("inactiveTitleEffect_5", dialog_->i_titleeffect_S->currentItem()); + config_->writeEntry("ShapeUL_5", dialog_->shapeUL_S->isChecked()); + config_->writeEntry("ShapeUR_5", dialog_->shapeUR_S->isChecked()); + config_->writeEntry("ShapeLL_5", dialog_->shapeLL_S->isChecked()); + config_->writeEntry("ShapeLR_5", dialog_->shapeLR_S->isChecked()); + config_->writeEntry("drawIcon_5", dialog_->drawIcon_S->isChecked()); + config_->writeEntry("3DImpact_5", dialog_->_3DImpact_S->value()); + config_->writeEntry("LineImpact_5", dialog_->LineImpact_S->value()); + config_->writeEntry("BorderSize_5", dialog_->borderSize_S->value()); + + if (buttonDialog_->save){ + config_->writeEntry("InactiveButtonColor", (int)buttonDialog_->inactiveColor->Color().rgb()); + config_->writeEntry("CloseButtonColor", (int)buttonDialog_->closeColor->Color().rgb()); + config_->writeEntry("MinButtonColor", (int)buttonDialog_->minColor->Color().rgb()); + config_->writeEntry("MaxButtonColor", (int)buttonDialog_->maxColor->Color().rgb()); + config_->writeEntry("MenuButtonColor", (int)buttonDialog_->menuColor->Color().rgb()); + config_->writeEntry("HelpButtonColor", (int)buttonDialog_->helpColor->Color().rgb()); + config_->writeEntry("StickyButtonColor", (int)buttonDialog_->stickyColor->Color().rgb()); + config_->writeEntry("AboveButtonColor", (int)buttonDialog_->aboveColor->Color().rgb()); + config_->writeEntry("BehindButtonColor", (int)buttonDialog_->behindColor->Color().rgb()); + config_->writeEntry("ShadeButtonColor", (int)buttonDialog_->shadeColor->Color().rgb()); + } + config_->endGroup(); + delete config_; + +// config_->sync(); +} + +////////////////////////////////////////////////////////////////////////////// +// defaults() +// ---------- +// Set configuration defaults + +void BaghiraConfig::defaults() +{ + QRadioButton *button = (QRadioButton*)dialog_->titlealign->child("AlignHCenter"); + if (button) button->setChecked(true); + dialog_->allowEasyClosing->setChecked(false); + dialog_->minTH->setValue(22); + dialog_->ResizeGrip->setChecked(false); + dialog_->drawComicFrame->setChecked(false); + dialog_->addAutoSpacing->setChecked(true); + dialog_->maxResizable->setChecked(false); + dialog_->fullSpec->setChecked(false); + dialog_->defaultMode->setCurrentItem(1); + dialog_->noModalDeco->setChecked(false); + dialog_->delAppname->setChecked(false); + + dialog_->activeColor1_J->setColor(QColor(255,255,255)); + dialog_->inactiveColor1_J->setColor(QColor(204,214,230)); + dialog_->activeColor2_J->setColor(QColor(238,234,238)); + dialog_->inactiveColor2_J->setColor(QColor(194,196,211)); + dialog_->buttonStyle_J->setCurrentItem(1); + dialog_->titleeffect_J->setCurrentItem(1); + dialog_->i_titleeffect_J->setCurrentItem(1); + dialog_->shapeUL_J->setChecked(true); + dialog_->shapeUR_J->setChecked(true); + dialog_->shapeLL_J->setChecked(false); + dialog_->shapeLR_J->setChecked(false); + dialog_->drawIcon_J->setChecked(true); + dialog_->_3DImpact_J->setValue(20); + dialog_->LineImpact_J->setValue(40); + dialog_->borderSize_J->setValue(0); + + dialog_->activeColor1_P->setColor(QColor(238,238,238)); + dialog_->inactiveColor1_P->setColor(QColor(246,242,246)); + dialog_->activeColor2_P->setColor(QColor(205,202,205)); + dialog_->inactiveColor2_P->setColor(QColor(238,238,238)); + dialog_->buttonStyle_P->setCurrentItem(0); + dialog_->titleeffect_P->setCurrentItem(0); + dialog_->i_titleeffect_P->setCurrentItem(0); + dialog_->shapeUL_P->setChecked(true); + dialog_->shapeUR_P->setChecked(true); + dialog_->shapeLL_P->setChecked(false); + dialog_->shapeLR_P->setChecked(false); + dialog_->drawIcon_P->setChecked(true); + dialog_->_3DImpact_P->setValue(20); + dialog_->LineImpact_P->setValue(30); + dialog_->borderSize_P->setValue(0); + + dialog_->activeColor1_B->setColor(QColor(210,210,210)); + dialog_->inactiveColor1_B->setColor(QColor(200,200,200)); + dialog_->activeColor2_B->setColor(QColor(150,150,150)); + dialog_->inactiveColor2_B->setColor(QColor(140,140,140)); + dialog_->buttonStyle_B->setCurrentItem(0); + dialog_->titleeffect_B->setCurrentItem(4); + dialog_->i_titleeffect_B->setCurrentItem(4); + dialog_->shapeUL_B->setChecked(true); + dialog_->shapeUR_B->setChecked(true); + dialog_->shapeLL_B->setChecked(false); + dialog_->shapeLR_B->setChecked(false); + dialog_->drawIcon_B->setChecked(true); + dialog_->_3DImpact_B->setValue(20); + dialog_->LineImpact_B->setValue(0); + dialog_->borderSize_B->setValue(6); + + dialog_->activeColor1_T->setColor(QColor(238,238,238)); + dialog_->activeColor2_T->setColor(QColor(211,208,211)); + dialog_->buttonStyle_T->setCurrentItem(0); + dialog_->shapeUL_T->setChecked(true); + dialog_->shapeUR_T->setChecked(true); + dialog_->shapeLL_T->setChecked(false); + dialog_->shapeLR_T->setChecked(false); + dialog_->drawIcon_T->setChecked(true); + dialog_->_3DImpact_T->setValue(20); + dialog_->borderSize_T->setValue(0); + + dialog_->activeColor1_S->setColor(QColor(250,250,250)); + dialog_->inactiveColor1_S->setColor(QColor(230,230,230)); + dialog_->activeColor2_S->setColor(QColor(230,230,230)); + dialog_->inactiveColor2_S->setColor(QColor(250,250,250)); + dialog_->buttonStyle_S->setCurrentItem(0); + dialog_->titleeffect_S->setCurrentItem(0); + dialog_->i_titleeffect_S->setCurrentItem(0); + dialog_->shapeUL_S->setChecked(true); + dialog_->shapeUR_S->setChecked(true); + dialog_->shapeLL_S->setChecked(false); + dialog_->shapeLR_S->setChecked(false); + dialog_->drawIcon_S->setChecked(true); + dialog_->_3DImpact_S->setValue(20); + dialog_->LineImpact_S->setValue(30); + dialog_->borderSize_S->setValue(0); + +// buttonDialog_->defaults(); + + +} + +enum ColorPresets{Aqua = 0, Graphite, GraphiteDark, NUMBEROFCOLORS}; + +const char * presetColorName[NUMBEROFCOLORS] = {"Aqua", "Graphite", "Graphite (Dark)" }; + +typedef int ColorTable[10][3]; + +const int aquaPreset[10][3] = {{255,255,255},{200,85,70},{230,155,40},{121,180,54},{74,140,242},{0,0,0},{74,140,242},{74,140,242},{74,140,242},{74,140,242}}; +const int graphitePreset[10][3] = {{255,255,255},{130,170,190},{130,170,190},{130,170,190},{130,170,190},{0,0,0},{130,170,190},{130,170,190},{130,170,190},{130,170,190}}; +const int graphiteDarkPreset[10][3] = {{255,255,255},{103,118,134},{103,118,134},{103,118,134},{103,118,134},{0,0,0},{103,118,134},{103,118,134},{103,118,134},{103,118,134}}; +const ColorTable* presetColors[NUMBEROFCOLORS] = {&aquaPreset, &graphitePreset, &graphiteDarkPreset}; + + +ButtonColors::ButtonColors(QWidget *parent, const char * name) : QDialog(parent, name){ + save = false; + layout = new QGridLayout(this,2,2,11,6, "Grid"); + buttonLayout = new QVBoxLayout(0,0,6); + + QPixmap tmpPix = QPixmap(uic_findImage("preview")); + inactiveButton = new AquariusButton(tmpPix,this, "Inactive Button"); + buttonLayout->addWidget(inactiveButton); + closeButton = new AquariusButton(tmpPix,this, "Close Button"); + buttonLayout->addWidget(closeButton); + minButton = new AquariusButton(tmpPix,this, "Minimize Button"); + buttonLayout->addWidget(minButton); + maxButton = new AquariusButton(tmpPix,this, "Maximize Button"); + buttonLayout->addWidget(maxButton); + stickyButton = new AquariusButton(tmpPix,this, "Sticky Button"); + buttonLayout->addWidget(stickyButton); + aboveButton = new AquariusButton(tmpPix,this, "Above Button"); + buttonLayout->addWidget(aboveButton); + behindButton = new AquariusButton(tmpPix,this, "Behind Button"); + buttonLayout->addWidget(behindButton); + shadeButton = new AquariusButton(tmpPix,this, "Shade Button"); + buttonLayout->addWidget(shadeButton); + tmpPix = QPixmap(uic_findImage("preview-menu")); + menuButton = new AquariusButton(tmpPix,this, "Menu Button"); + buttonLayout->addWidget(menuButton); + tmpPix = QPixmap(uic_findImage("icon_help")); + helpButton = new AquariusButton(tmpPix,this, "Help Button"); + buttonLayout->addWidget(helpButton); + + + twoButts = new QHBoxLayout(0,0,6); + presets_ = new QComboBox(this); + for (int i = 0; i < NUMBEROFCOLORS; i++) + presets_->insertItem ( presetColorName[i], i ); + twoButts->addWidget(presets_); + cancel = new QPushButton("Cancel", this); + cancel->setDefault( true ); + twoButts->addWidget(cancel); + twoButts->addStretch(); + layout->addLayout(twoButts,1,0); + ok = new QPushButton("OK", this); + layout->addWidget(ok,1,1); + + layout->addLayout(buttonLayout,0,1); + + pickerLayout = new QVBoxLayout(0,0,6,0); + + indicator = new QLabel(inactiveButton->name(), this); + indicator->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter | Qt::ExpandTabs); + QFont tmpFont = font(); + tmpFont.setBold( true ); + tmpFont.setPointSize( 24 ); + indicator->setFont(tmpFont); + pickerLayout->addWidget(indicator); + + inactiveColor = new ColorPicker(this); + pickerLayout->addWidget(inactiveColor); + currentPicker = inactiveColor; + closeColor = new ColorPicker(this); + pickerLayout->addWidget(closeColor); + closeColor->hide(); + minColor = new ColorPicker(this); + pickerLayout->addWidget(minColor); + minColor->hide(); + maxColor = new ColorPicker(this); + pickerLayout->addWidget(maxColor); + maxColor->hide(); + menuColor = new ColorPicker(this); + pickerLayout->addWidget(menuColor); + menuColor->hide(); + helpColor = new ColorPicker(this); + pickerLayout->addWidget(helpColor); + helpColor->hide(); + stickyColor = new ColorPicker(this); + pickerLayout->addWidget(stickyColor); + stickyColor->hide(); + aboveColor = new ColorPicker(this); + pickerLayout->addWidget(aboveColor); + aboveColor->hide(); + behindColor = new ColorPicker(this); + pickerLayout->addWidget(behindColor); + behindColor->hide(); + shadeColor = new ColorPicker(this); + pickerLayout->addWidget(shadeColor); + shadeColor->hide(); + + indicator->lower(); + + layout->addLayout(pickerLayout,0,0); + + resize( QSize(485, 177).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + connect(presets_,SIGNAL(activated(int)), this, SLOT(setColorGroup(int))); + connect(ok, SIGNAL(clicked()), this, SLOT(setSave())); + connect(ok, SIGNAL(clicked()), this, SLOT(close()) ); + connect(ok, SIGNAL(clicked()), this, SLOT(init()) ); + connect(cancel, SIGNAL(clicked()), this, SLOT(close()) ); + connect(cancel, SIGNAL(clicked()), this, SLOT(reset()) ); + + connect(inactiveButton, SIGNAL(clicked()), this, SLOT(activateInactive()) ); + connect(closeButton, SIGNAL(clicked()), this, SLOT(activateClose()) ); + connect(minButton, SIGNAL(clicked()), this, SLOT(activateMin()) ); + connect(maxButton, SIGNAL(clicked()), this, SLOT(activateMax()) ); + connect(menuButton, SIGNAL(clicked()), this, SLOT(activateMenu()) ); + connect(helpButton, SIGNAL(clicked()), this, SLOT(activateHelp()) ); + connect(stickyButton, SIGNAL(clicked()), this, SLOT(activateSticky()) ); + connect(aboveButton, SIGNAL(clicked()), this, SLOT(activateAbove()) ); + connect(behindButton, SIGNAL(clicked()), this, SLOT(activateBehind()) ); + connect(shadeButton, SIGNAL(clicked()), this, SLOT(activateShade()) ); + + connect(inactiveColor, SIGNAL(colorChanged(QColor)), inactiveButton, SLOT(setColor(QColor)) ); + connect(closeColor, SIGNAL(colorChanged(QColor)), closeButton, SLOT(setColor(QColor)) ); + connect(minColor, SIGNAL(colorChanged(QColor)), minButton, SLOT(setColor(QColor)) ); + connect(maxColor, SIGNAL(colorChanged(QColor)), maxButton, SLOT(setColor(QColor)) ); + connect(menuColor, SIGNAL(colorChanged(QColor)), menuButton, SLOT(setColor(QColor)) ); + connect(helpColor, SIGNAL(colorChanged(QColor)), helpButton, SLOT(setColor(QColor)) ); + connect(stickyColor, SIGNAL(colorChanged(QColor)), stickyButton, SLOT(setColor(QColor)) ); + connect(aboveColor, SIGNAL(colorChanged(QColor)), aboveButton, SLOT(setColor(QColor)) ); + connect(behindColor, SIGNAL(colorChanged(QColor)), behindButton, SLOT(setColor(QColor)) ); + connect(shadeColor, SIGNAL(colorChanged(QColor)), shadeButton, SLOT(setColor(QColor)) ); + +} + +ButtonColors::~ButtonColors(){ +} + +void ButtonColors::setColorGroup(int i){ + inactiveColor->setColor(QColor((*presetColors[i])[0][0],(*presetColors[i])[0][1],(*presetColors[i])[0][2]).rgb()); + closeColor->setColor(QColor((*presetColors[i])[1][0],(*presetColors[i])[1][1],(*presetColors[i])[1][2]).rgb()); + minColor->setColor(QColor((*presetColors[i])[2][0],(*presetColors[i])[2][1],(*presetColors[i])[2][2]).rgb()); + maxColor->setColor(QColor((*presetColors[i])[3][0],(*presetColors[i])[3][1],(*presetColors[i])[3][2]).rgb()); + menuColor->setColor(QColor((*presetColors[i])[4][0],(*presetColors[i])[4][1],(*presetColors[i])[4][2]).rgb()); + helpColor->setColor(QColor((*presetColors[i])[5][0],(*presetColors[i])[5][1],(*presetColors[i])[5][2]).rgb()); + stickyColor->setColor(QColor((*presetColors[i])[6][0],(*presetColors[i])[6][1],(*presetColors[i])[6][2]).rgb()); + aboveColor->setColor(QColor((*presetColors[i])[7][0],(*presetColors[i])[7][1],(*presetColors[i])[7][2]).rgb()); + behindColor->setColor(QColor((*presetColors[i])[8][0],(*presetColors[i])[8][1],(*presetColors[i])[8][2]).rgb()); + shadeColor->setColor(QColor((*presetColors[i])[9][0],(*presetColors[i])[9][1],(*presetColors[i])[9][2]).rgb()); +} + +void ButtonColors::setPicker(ColorPicker *picker){ + if (currentPicker) currentPicker->hide(); + currentPicker = picker; + currentPicker->show(); +} + +void ButtonColors::activateInactive(){ + setPicker(inactiveColor); + indicator->setText( inactiveButton->name() ); +} +void ButtonColors::activateClose(){ + setPicker(closeColor); + indicator->setText( closeButton->name() ); +} +void ButtonColors::activateMin(){ + setPicker(minColor); + indicator->setText( minButton->name() ); +} +void ButtonColors::activateMax(){ + setPicker(maxColor); + indicator->setText( maxButton->name() ); +} +void ButtonColors::activateMenu(){ + setPicker(menuColor); + indicator->setText( menuButton->name() ); +} +void ButtonColors::activateHelp(){ + setPicker(helpColor); + indicator->setText( helpButton->name() ); +} +void ButtonColors::activateSticky(){ + setPicker(stickyColor); + indicator->setText( stickyButton->name() ); +} +void ButtonColors::activateAbove(){ + setPicker(aboveColor); + indicator->setText( aboveButton->name() ); +} +void ButtonColors::activateBehind(){ + setPicker(behindColor); + indicator->setText( behindButton->name() ); +} +void ButtonColors::activateShade(){ + setPicker(shadeColor); + indicator->setText( shadeButton->name() ); +} + +void ButtonColors::reset(){ + inactiveColor->reset(); + closeColor->reset(); + minColor->reset(); + maxColor->reset(); + menuColor->reset(); + helpColor->reset(); + stickyColor->reset(); + aboveColor->reset(); + behindColor->reset(); + shadeColor->reset(); +} + +void ButtonColors::init(){ + inactiveColor->init(); + closeColor->init(); + minColor->init(); + maxColor->init(); + menuColor->init(); + helpColor->init(); + stickyColor->init(); + aboveColor->init(); + behindColor->init(); + shadeColor->init(); +} + +////////////////////////////////////////////////////////////////////////////// +// Plugin Stuff // +////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + QObject* allocate_config(KConfig* config, QWidget* parent) { + return(new BaghiraConfig(config, parent)); + } +} + +#include "baghiraconfig.moc" diff --git a/deco/config/baghiraconfig.h b/deco/config/baghiraconfig.h new file mode 100644 index 0000000..07b04a5 --- /dev/null +++ b/deco/config/baghiraconfig.h @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraconfig.h +// ------------------- +// Config module for Baghira window decoration +// ------------------- +// Copyright (c) 2004 Thomas Lübking +// +// 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 BAGHIRACONFIG_H +#define BAGHIRACONFIG_H + +#include +#include +#include "colorpicker.h" +#include "aquariusbutton.h" + +class KConfig; +class QSettings; +class ConfigDialog; +class QLabel; +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QPushButton; +class QComboBox; + +class ButtonColors : public QDialog +{ + Q_OBJECT +public: + ButtonColors(QWidget* parent, const char * name = 0); + ~ButtonColors(); + ColorPicker *inactiveColor; + ColorPicker *closeColor; + ColorPicker *minColor; + ColorPicker *maxColor; + ColorPicker *menuColor; + ColorPicker *helpColor; + ColorPicker *stickyColor; + ColorPicker *aboveColor; + ColorPicker *behindColor; + ColorPicker *shadeColor; + ColorPicker *currentPicker; + + AquariusButton *inactiveButton; + AquariusButton *closeButton; + AquariusButton *minButton; + AquariusButton *maxButton; + AquariusButton *menuButton; + AquariusButton *helpButton; + AquariusButton *stickyButton; + AquariusButton *aboveButton; + AquariusButton *behindButton; + AquariusButton *shadeButton; + + QHBoxLayout *twoButts; + QPushButton *cancel; + QPushButton *ok; + QComboBox *presets_; + bool save; + +public slots: +// void defaults(); + void setColorGroup(int); + void init(); + + +private: + +/* + |------------|---| + | Indicator | B | + |------------|---| + | | T | + | Picker |---| + | | N | + |------------|---| +*/ + + QVBoxLayout *buttonLayout; + QVBoxLayout *pickerLayout; + QGridLayout *layout; + QLabel *indicator; + + void setPicker(ColorPicker *picker); + +private slots: + void activateInactive(); + void activateClose(); + void activateMin(); + void activateMax(); + void activateMenu(); + void activateHelp(); + void activateSticky(); + void activateAbove(); + void activateBehind(); + void activateShade(); + void setSave(){ + save = true; + } + void reset(); +}; + + +class BaghiraConfig : public QObject +{ + Q_OBJECT +public: + BaghiraConfig(KConfig* config, QWidget* parent); + ~BaghiraConfig(); + +signals: + void changed(); + +public slots: + void load(KConfig* conf); + void save(KConfig* conf); + void defaults(); + +private: +// QSettings *config_; + ConfigDialog *dialog_; + ButtonColors *buttonDialog_; +}; + + +#endif // BAGHIRACONFIG_H diff --git a/deco/config/baghiraconfig.h.new b/deco/config/baghiraconfig.h.new new file mode 100644 index 0000000..0f75139 --- /dev/null +++ b/deco/config/baghiraconfig.h.new @@ -0,0 +1,149 @@ +////////////////////////////////////////////////////////////////////////////// +// baghiraconfig.h +// ------------------- +// Config module for Baghira window decoration +// ------------------- +// Copyright (c) 2004 Thomas Lübking +// +// 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 BAGHIRACONFIG_H +#define BAGHIRACONFIG_H + +#include +#include +#include +#include "colorpicker.h" +#include "aquariusbutton.h" + +class KConfig; +class QSettings; +class ConfigDialog; +class QLabel; +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QPushButton; +class QComboBox; + +class ButtonColors : public QDialog +{ + Q_OBJECT +public: + ButtonColors(QWidget* parent, const char * name = 0); + ~ButtonColors(); + ColorPicker *inactiveColor; + ColorPicker *closeColor; + ColorPicker *minColor; + ColorPicker *maxColor; + ColorPicker *menuColor; + ColorPicker *helpColor; + ColorPicker *stickyColor; + ColorPicker *aboveColor; + ColorPicker *behindColor; + ColorPicker *shadeColor; + ColorPicker *currentPicker; + + AquariusButton *inactiveButton; + AquariusButton *closeButton; + AquariusButton *minButton; + AquariusButton *maxButton; + AquariusButton *menuButton; + AquariusButton *helpButton; + AquariusButton *stickyButton; + AquariusButton *aboveButton; + AquariusButton *behindButton; + AquariusButton *shadeButton; + + QHBoxLayout *twoButts; + QPushButton *cancel; + QPushButton *ok; + QComboBox *presets_; + bool save; + +public slots: +// void defaults(); + void setColorGroup(int); + void init(); + + +private: + +/* + |------------|---| + | Indicator | B | + |------------|---| + | | T | + | Picker |---| + | | N | + |------------|---| +*/ + + QVBoxLayout *buttonLayout; + QVBoxLayout *pickerLayout; + QGridLayout *layout; + QLabel *indicator; + + void setPicker(ColorPicker *picker); + +private slots: + void activateInactive(); + void activateClose(); + void activateMin(); + void activateMax(); + void activateMenu(); + void activateHelp(); + void activateSticky(); + void activateAbove(); + void activateBehind(); + void activateShade(); + void setSave(){ + save = true; + } + void reset(); +}; + +class CustomDecoSettings; + +class BaghiraConfig : public QObject +{ + Q_OBJECT +public: + BaghiraConfig(KConfig* config, QWidget* parent); + ~BaghiraConfig(); + +signals: + void changed(); + +public slots: + void load(KConfig* conf); + void save(KConfig* conf); + void defaults(); + +private: +// QSettings *config_; + ConfigDialog *dialog_; + ButtonColors *buttonDialog_; + typedef QValueList DecoList; + DecoList decoList; +}; + + +#endif // BAGHIRACONFIG_H diff --git a/deco/config/colorpicker.cc b/deco/config/colorpicker.cc new file mode 100644 index 0000000..5e11312 --- /dev/null +++ b/deco/config/colorpicker.cc @@ -0,0 +1,124 @@ +#include "colorpicker.h" +#include +#include +#include +#include + +ColorPicker::ColorPicker(QWidget* parent, const char* name) : QGroupBox( parent, name){ +// box = new QGroupBox(parent); +// setFrameShape(QFrame::GroupBoxPanel); +// setFrameShadow(QFrame::Sunken); + setColumnLayout(0, Qt::Vertical ); + layout()->setSpacing( 6 ); + layout()->setMargin( 11 ); + + QVBoxLayout *vLayout = new QVBoxLayout(layout()); +// gridLayout->setAlignment( Qt::AlignTop ); + + QHBoxLayout *redLayout = new QHBoxLayout(); + redSlider = new QSlider(0, 255, 1, 0, Qt::Horizontal, this, "redSlider"); + redLayout->addWidget(redSlider); + + redValue = new QSpinBox(0,255,1,this); + redValue->setValue(0); + redLayout->addWidget(redValue); + + vLayout->addLayout(redLayout); + + QHBoxLayout *greenLayout = new QHBoxLayout(); + greenSlider = new QSlider(0, 255, 1, 0, Qt::Horizontal, this, "greenSlider"); + greenLayout->addWidget(greenSlider); + + greenValue = new QSpinBox(0,255,1,this); + greenValue->setValue(0); + greenLayout->addWidget(greenValue); + + vLayout->addLayout(greenLayout); + + QHBoxLayout *blueLayout = new QHBoxLayout(); + blueSlider = new QSlider(0, 255, 1, 0, Qt::Horizontal, this, "blueSlider"); + blueLayout->addWidget(blueSlider); + + blueValue = new QSpinBox(0,255,1,this); + blueValue->setValue(0); + blueLayout->addWidget(blueValue); + + vLayout->addLayout(blueLayout); + +// resize( QSize(350, 100).expandedTo(minimumSizeHint()) ); + + //connections + connect(redSlider, SIGNAL(valueChanged (int)), this, SLOT(setRed(int))); + connect(greenSlider, SIGNAL(valueChanged (int)), this, SLOT(setGreen(int))); + connect(blueSlider, SIGNAL(valueChanged (int)), this, SLOT(setBlue(int))); + connect(redValue, SIGNAL(valueChanged (int)), this, SLOT(setRed(int))); + connect(greenValue, SIGNAL(valueChanged (int)), this, SLOT(setGreen(int))); + connect(blueValue, SIGNAL(valueChanged (int)), this, SLOT(setBlue(int))); +} + +ColorPicker::~ColorPicker(){ +} + +void ColorPicker::setColor(QColor color){ + redSlider->blockSignals(true); + redSlider->setValue( color.red() ); + redSlider->blockSignals(false); + redValue->blockSignals(true); + redValue->setValue(redSlider->value()); + redValue->blockSignals(false); + greenSlider->blockSignals(true); + greenSlider->setValue( color.green() ); + greenSlider->blockSignals(false); + greenValue->blockSignals(true); + greenValue->setValue(greenSlider->value()); + greenValue->blockSignals(false); + blueSlider->blockSignals(true); + blueSlider->setValue( color.blue() ); + blueSlider->blockSignals(false); + blueValue->blockSignals(true); + blueValue->setValue(blueSlider->value()); + blueValue->blockSignals(false); + emit colorChanged(color); +} + +void ColorPicker::setRed(int red){ + redSlider->blockSignals(true); + redSlider->setValue( red ); + redSlider->blockSignals(false); + redValue->blockSignals(true); + redValue->setValue(red); + redValue->blockSignals(false); + emit colorChanged(QColor(red, greenSlider->value(), blueSlider->value())); +} + +void ColorPicker::setGreen(int green){ + greenSlider->blockSignals(true); + greenSlider->setValue( green ); + greenSlider->blockSignals(false); + greenValue->blockSignals(true); + greenValue->setValue(green); + greenValue->blockSignals(false); + emit colorChanged(QColor(redSlider->value(), green, blueSlider->value())); +} + +void ColorPicker::setBlue(int blue){ + blueSlider->blockSignals(true); + blueSlider->setValue( blue ); + blueSlider->blockSignals(false); + blueValue->blockSignals(true); + blueValue->setValue(blue); + blueValue->blockSignals(false); + emit colorChanged(QColor(redSlider->value(), greenSlider->value(), blue)); +} + +QColor ColorPicker::Color(){ + return QColor(redSlider->value(), greenSlider->value(), blueSlider->value()); +} + +void ColorPicker::reset(){ + setColor(color_); +} + +void ColorPicker::init(){ + color_ = Color(); +} \ No newline at end of file diff --git a/deco/config/colorpicker.h b/deco/config/colorpicker.h new file mode 100644 index 0000000..3b4ec48 --- /dev/null +++ b/deco/config/colorpicker.h @@ -0,0 +1,44 @@ +#ifndef COLORPICKER_H +#define COLORPICKER_H + +//#include +#include + +class QSlider; +class QSpinBox; +class QColor; +//class QGroupBox; + +class ColorPicker : public QGroupBox +{ + Q_OBJECT + +public: + ColorPicker( QWidget* parent = 0, const char* name = 0); + ~ColorPicker(); + QColor Color(); + +public slots: + void setColor(QColor color); + void setRed(int red); + void setGreen(int green); + void setBlue(int blue); + void reset(); + void init(); + +protected: + QSlider *redSlider; + QSlider *greenSlider; + QSlider *blueSlider; + QSpinBox *redValue; + QSpinBox *greenValue; + QSpinBox *blueValue; + QColor color_; +// QGroupBox *box; + +signals: + void colorChanged(QColor color); + +}; + +#endif // COLORPICKER_H diff --git a/deco/config/configdialog.ui b/deco/config/configdialog.ui new file mode 100644 index 0000000..a52dadf --- /dev/null +++ b/deco/config/configdialog.ui @@ -0,0 +1,3088 @@ + +ConfigDialog + + + ConfigDialog + + + + 0 + 0 + 778 + 498 + + + + Configure Baghira Window Decoration + + + + unnamed + + + + generalbox + + + GroupBoxPanel + + + Sunken + + + Common Settings + + + + unnamed + + + + layout133 + + + + unnamed + + + + textLabel1_3 + + + Minimum Title Height + + + + + spacer6 + + + Horizontal + + + Expanding + + + + 53 + 20 + + + + + + minTH + + + 30 + + + 18 + + + The Titlebar height will follow your font setting.<br>However, you can set a minmum value to extend the Titlebar if you prefer small fonts.<br>18 is the minimum due to the Buttons :) + + + + + + + ResizeGrip + + + Show resize grip + + + Starts in Brushed Metal mode instead of default, if the Style is set to Brushed Metal + + + + + addAutoSpacing + + + Add auto spacing + + + + + fullSpec + + + Fullscreen maximized + + + Check this to have any window in fullscreen Mode - demaximize the window by clicking into the top right corner of your screen + + + + + drawComicFrame + + + Draw Comic Frame + + + Draws a black frame around the window (not the Titlebar).<br>Anyway i suggest to get the kwin dropshadow patch. + + + + + noModalDeco + + + Hide deco for fixed size modal windows + + + + + maxResizable + + + Keep maximized resizable + + + + + allowEasyClosing + + + Allow Easy Closing + + + Allows Closing by clicking into the top left or right corner <br> Close Button must be most left or right element (also no spacers) <br> Closes on Mouse Button release (so you have the chance to move the mouse away and keep the Window) <br> The Window must be active and maximized <br> Unfortunately you will not be able tho resize the Window from that corner + + + + + + Jaguar + + + + + Panther + + + + + Brushed Metal + + + + + Tiger + + + + + Milk + + + + defaultMode + + + + + textLabel1_7 + + + Default Mode is + + + + + line3 + + + HLine + + + Sunken + + + Horizontal + + + + + delAppname + + + Try to remove application name +from multipart titles + + + + + + + titlealign + + + Title &Alignment + + + + + + Use these buttons to set the alignment of the window title + + + + unnamed + + + + AlignLeft + + + Left + + + + + + + + spacer78 + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + AlignHCenter + + + Center + + + true + + + + + + + + spacer77 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + AlignRight + + + Right + + + + + + + + noTitle + + + None + + + + + spacer23_2 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + spacer79 + + + Vertical + + + Expanding + + + + 20 + 59 + + + + + + ButtonColorConfig + + + Configure Button Colors + + + + + spacer33 + + + Vertical + + + Expanding + + + + 20 + 25 + + + + + + tab + + + + jaguarTab + + + Jaguar + + + + unnamed + + + + layout7_3 + + + + unnamed + + + + textLabel1_4_3 + + + 3D Intensity + + + + + spacer4_3 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact_J + + + 100 + + + 20 + + + + + + + layout10 + + + + unnamed + + + + textLabel2 + + + Titleshadow Intensity + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + LineImpact_J + + + UpDownArrows + + + 100 + + + 40 + + + + + + + layout40 + + + + unnamed + + + + layout35 + + + + unnamed + + + + textLabel1_2_4_3 + + + ButtonStyle + + + + + textLabel1_8_3 + + + Active Titlebar Effect + + + titleeffect + + + + + textLabel1_8_3_2 + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + spacer18_2_3 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + layout39 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle_J + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + titleeffect_J + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + i_titleeffect_J + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + + layout38 + + + + unnamed + + + + textLabel1 + + + Colors + + + AlignCenter + + + + + layout33 + + + + unnamed + + + + activeColor1_J + + + + + + + + activeColor2_J + + + + + + + + + + layout34 + + + + unnamed + + + + inactiveColor1_J + + + + + + + + inactiveColor2_J + + + + + + + + + + + + + + groupBox2_4 + + + Round Corners + + + + unnamed + + + + layout45 + + + + unnamed + + + + shapeUL_J + + + + + + + + spacer16 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL_J + + + + + + + + + + layout44 + + + + unnamed + + + + shapeUR_J + + + + + + + + spacer17 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR_J + + + + + + + + + + spacer24_3 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + borderSize_J + + + 16 + + + + + textLabel1_6_3 + + + Border Size + + + + + spacer27_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer27 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer15 + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + + + drawIcon_J + + + Draw Icon + + + + + + + pantherTab + + + Panther + + + + unnamed + + + + layout10_2 + + + + unnamed + + + + textLabel2_2 + + + Titleshadow Intensity + + + + + spacer5_2 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + LineImpact_P + + + UpDownArrows + + + 100 + + + 40 + + + + + + + groupBox2_3 + + + Round Corners + + + + unnamed + + + + layout51 + + + + unnamed + + + + shapeUL_P + + + + + + + + spacer20 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL_P + + + + + + + + + + layout52 + + + + unnamed + + + + shapeUR_P + + + + + + + + spacer19 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR_P + + + + + + + + + + spacer18 + + + Horizontal + + + Expanding + + + + 50 + 20 + + + + + + spacer24_2 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + borderSize_P + + + 16 + + + + + textLabel1_6_2 + + + Border Size + + + + + spacer28 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer28_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + layout7_2 + + + + unnamed + + + + textLabel1_4_4 + + + 3D Intensity + + + + + spacer4_4 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact_P + + + 100 + + + 20 + + + + + + + layout50 + + + + unnamed + + + + layout31 + + + + unnamed + + + + textLabel1_2_4 + + + ButtonStyle + + + + + textLabel1_8 + + + Active Titlebar Effect + + + titleeffect + + + + + textLabel1_8_4 + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + spacer18_2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + layout30 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle_P + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + titleeffect_P + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + i_titleeffect_P + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + + layout49 + + + + unnamed + + + + textLabel1_2 + + + Colors + + + AlignCenter + + + + + layout47 + + + + unnamed + + + + activeColor1_P + + + + + + + + activeColor2_P + + + + + + + + + + layout48 + + + + unnamed + + + + inactiveColor1_P + + + + + + + + inactiveColor2_P + + + + + + + + + + + + + + drawIcon_P + + + Draw Icon + + + + + + + brushedTab + + + Brushed + + + + unnamed + + + + layout10_3 + + + + unnamed + + + + textLabel2_3 + + + Titleshadow Intensity + + + + + spacer5_3 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + LineImpact_B + + + UpDownArrows + + + 100 + + + 40 + + + + + + + layout7 + + + + unnamed + + + + textLabel1_4 + + + 3D Intensity + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact_B + + + 100 + + + 20 + + + + + + + layout57 + + + + unnamed + + + + layout27 + + + + unnamed + + + + textLabel1_2_4_2 + + + ButtonStyle + + + + + textLabel1_8_2 + + + Active Titlebar Effect + + + titleeffect + + + + + textLabel1_8_2_2 + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + spacer18_2_2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + layout26 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle_B + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + titleeffect_B + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + i_titleeffect_B + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + + layout56 + + + + unnamed + + + + textLabel1_5 + + + Colors + + + AlignCenter + + + + + layout54 + + + + unnamed + + + + activeColor1_B + + + + + + + + activeColor2_B + + + + + + + + + + layout55 + + + + unnamed + + + + inactiveColor1_B + + + + + + + + inactiveColor2_B + + + + + + + + + + + + + + groupBox2_2 + + + Round Corners + + + + unnamed + + + + layout58 + + + + unnamed + + + + shapeUL_B + + + + + + + + spacer21 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL_B + + + + + + + + + + layout59 + + + + unnamed + + + + shapeUR_B + + + + + + + + spacer22 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR_B + + + + + + + + + + spacer23 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + textLabel1_6 + + + Border Size + + + + + borderSize_B + + + 16 + + + 6 + + + + + spacer24 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + spacer29 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer29_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + drawIcon_B + + + Draw Icon + + + + + + + TabPage + + + Tiger + + + + unnamed + + + + layout7_4 + + + + unnamed + + + + textLabel1_4_2 + + + 3D Intensity + + + + + spacer4_2 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact_T + + + 100 + + + 20 + + + + + + + groupBox2_2_2 + + + Round Corners + + + + unnamed + + + + layout58_2 + + + + unnamed + + + + shapeUL_T + + + + + + + + spacer21_2 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL_T + + + + + + + + + + layout59_2 + + + + unnamed + + + + shapeUR_T + + + + + + + + spacer22_2 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR_T + + + + + + + + + + spacer23_3 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + textLabel1_6_4 + + + Border Size + + + + + borderSize_T + + + 16 + + + 6 + + + + + spacer24_4 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + spacer29_3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer29_2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + layout42 + + + + unnamed + + + + layout27_2 + + + + unnamed + + + + textLabel1_2_4_2_2 + + + ButtonStyle + + + + + textLabel1_8_2_3 + + + Active Titlebar Effect + + + titleeffect + + + + + textLabel1_8_2_2_2 + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + spacer18_2_2_2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + layout82 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle_T + + + + + textLabel1_9 + + + (Gradient) + + + + + textLabel1_9_2 + + + (Scanlines) + + + + + + + layout41 + + + + unnamed + + + + textLabel1_5_2 + + + Colors + + + AlignCenter + + + + + layout54_2 + + + + unnamed + + + + activeColor1_T + + + + + + + + activeColor2_T + + + + + + + + + + textLabel1_10 + + + (Background) + + + AlignCenter + + + + + + + + + drawIcon_T + + + Draw Icon + + + + + + + TabPage + + + Special + + + + unnamed + + + + drawIcon_S + + + Draw Icon + + + + + layout7_5 + + + + unnamed + + + + textLabel1_4_5 + + + 3D Intensity + + + + + spacer4_5 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact_S + + + 100 + + + 20 + + + + + + + layout57_2 + + + + unnamed + + + + layout27_3 + + + + unnamed + + + + textLabel1_2_4_2_3 + + + ButtonStyle + + + + + textLabel1_8_2_4 + + + Active Titlebar Effect + + + titleeffect + + + + + textLabel1_8_2_2_3 + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + spacer18_2_2_3 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + layout26_2 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle_S + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + titleeffect_S + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + i_titleeffect_S + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + + layout56_2 + + + + unnamed + + + + textLabel1_5_3 + + + Colors + + + AlignCenter + + + + + layout54_3 + + + + unnamed + + + + activeColor1_S + + + + + + + + activeColor2_S + + + + + + + + + + layout55_2 + + + + unnamed + + + + inactiveColor1_S + + + + + + + + inactiveColor2_S + + + + + + + + + + + + + + groupBox2_2_3 + + + Round Corners + + + + unnamed + + + + layout58_3 + + + + unnamed + + + + shapeUL_S + + + + + + + + spacer21_3 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL_S + + + + + + + + + + layout59_3 + + + + unnamed + + + + shapeUR_S + + + + + + + + spacer22_3 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR_S + + + + + + + + + + spacer23_4 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + textLabel1_6_5 + + + Border Size + + + + + borderSize_S + + + 16 + + + 6 + + + + + spacer24_5 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + spacer29_4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer29_2_3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + layout10_3_2 + + + + unnamed + + + + textLabel2_3_2 + + + Titleshadow Intensity + + + + + spacer5_3_2 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + LineImpact_S + + + UpDownArrows + + + 100 + + + 40 + + + + + + + + + + + + + + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + + diff --git a/deco/config/configdialog.ui.new b/deco/config/configdialog.ui.new new file mode 100644 index 0000000..b17dbd1 --- /dev/null +++ b/deco/config/configdialog.ui.new @@ -0,0 +1,398 @@ + +ConfigDialog + + + ConfigDialog + + + + 0 + 0 + 657 + 476 + + + + Configure Baghira Window Decoration + + + + unnamed + + + + titlealign + + + Title &Alignment + + + + + + Use these buttons to set the alignment of the window title + + + + unnamed + + + + AlignLeft + + + Left + + + + + + + + spacer78 + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + AlignHCenter + + + Center + + + true + + + + + + + + spacer77 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + AlignRight + + + Right + + + + + + + + noTitle + + + None + + + + + spacer23_2 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + generalbox + + + GroupBoxPanel + + + Sunken + + + Common Settings + + + + unnamed + + + + + Jaguar + + + + + Panther + + + + + Brushed Metal + + + + + Tiger + + + + + Milk + + + + defaultMode + + + + + delAppname + + + Try to remove application name +from multipart titles + + + + + line3 + + + HLine + + + Sunken + + + Horizontal + + + + + drawComicFrame + + + Draw Comic Frame + + + Draws a black frame around the window (not the Titlebar).<br>Anyway i suggest to get the kwin dropshadow patch. + + + + + noModalDeco + + + Hide deco for fixed size modal windows + + + + + maxResizable + + + Keep maximized resizable + + + + + ResizeGrip + + + Show resize grip + + + Starts in Brushed Metal mode instead of default, if the Style is set to Brushed Metal + + + + + textLabel1_7 + + + Default Mode is + + + + + fullSpec + + + Fullscreen maximized + + + Check this to have any window in fullscreen Mode - demaximize the window by clicking into the top right corner of your screen + + + + + allowEasyClosing + + + Allow Easy Closing + + + Allows Closing by clicking into the top left or right corner <br> Close Button must be most left or right element (also no spacers) <br> Closes on Mouse Button release (so you have the chance to move the mouse away and keep the Window) <br> The Window must be active and maximized <br> Unfortunately you will not be able tho resize the Window from that corner + + + + + addAutoSpacing + + + Add auto spacing + + + + + layout133 + + + + unnamed + + + + textLabel1_3 + + + Minimum Title Height + + + + + spacer6 + + + Horizontal + + + Expanding + + + + 53 + 20 + + + + + + minTH + + + 30 + + + 18 + + + The Titlebar height will follow your font setting.<br>However, you can set a minmum value to extend the Titlebar if you prefer small fonts.<br>18 is the minimum due to the Buttons :) + + + + + + + ButtonColorConfig + + + Configure Button Colors + + + + + + + decoStack + + + StyledPanel + + + Sunken + + + 2 + + + + WStackPage + + + 0 + + + + textLabel2 + + + + 99 + 99 + 74 + 20 + + + + Blablabla + + + + + + + pushButton2 + + + Add style + + + + + pushButton3 + + + Remove Style + + + + + + diff --git a/deco/config/customdecosettings.ui b/deco/config/customdecosettings.ui new file mode 100644 index 0000000..2533091 --- /dev/null +++ b/deco/config/customdecosettings.ui @@ -0,0 +1,586 @@ + +CustomDecoSettings + + + CustomDecoSettings + + + + 0 + 0 + 416 + 325 + + + + CustomDecoSettings + + + + unnamed + + + + boxCorner + + + Round Corners + + + + unnamed + + + + layout45 + + + + unnamed + + + + shapeUL + + + + + + + + spacer16 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLL + + + + + + + + + + layout44 + + + + unnamed + + + + shapeUR + + + + + + + + spacer17 + + + Vertical + + + Expanding + + + + 20 + 31 + + + + + + shapeLR + + + + + + + + + + spacer24_3 + + + Horizontal + + + Expanding + + + + 60 + 20 + + + + + + borderSize + + + 16 + + + + + labelBorderSize + + + Border Size + + + + + spacer27_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer27 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + spacer15 + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + + + layout10 + + + + unnamed + + + + labelTitleshadow + + + Titleshadow Intensity + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 61 + 20 + + + + + + LineImpact + + + UpDownArrows + + + 100 + + + 40 + + + + + + + layout7_3 + + + + unnamed + + + + label3D + + + 3D Intensity + + + + + spacer4_3 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + _3DImpact + + + 100 + + + 20 + + + + + + + layout35 + + + + unnamed + + + + labelButtonstyle + + + ButtonStyle + + + + + labelTitle + + + Active Titlebar Effect + + + titleeffect + + + + + labelInTitle + + + Inactive Titlebar Effect + + + titleeffect + + + + + + + layout38 + + + + unnamed + + + + labelColors + + + Colors + + + AlignCenter + + + + + layout33 + + + + unnamed + + + + activeColor1 + + + + + + + + activeColor2 + + + + + + + + + + layout34 + + + + unnamed + + + + inactiveColor1 + + + + + + + + inactiveColor2 + + + + + + + + + + + + layout39 + + + + unnamed + + + + + Panther + + + + + Jaguar + + + + + Milk + + + + + Nostalgia + + + + buttonStyle + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + titleeffect + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + Gradient + + + + + Stippled + + + + + Nostalgia + + + + + Glossy + + + + + Brushed + + + + + Scanlines + + + + i_titleeffect + + + + 0 + 22 + + + + Select an effect for the titlebar to change its appearance + + + + + + + spacer18_2_3 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + drawIcon + + + Draw Icon + + + + + DecoName + + + + 14 + 1 + + + + Name + + + + + + + + + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + + diff --git a/deco/config/generatePixmaps.sh b/deco/config/generatePixmaps.sh new file mode 100755 index 0000000..7c392a2 --- /dev/null +++ b/deco/config/generatePixmaps.sh @@ -0,0 +1,10 @@ +#!/bin/sh +top_srcdir="${1:-../..}" +imagebase="$top_srcdir/imagebase" +UIC=$(grep "UIC = " ../../Makefile | cut -f3- -d" ") +echo -e "#ifndef DCPIXMAPS_H\n#define DCPIXMAPS_H\n" > pixmaps.h +$UIC -embed baghira \ +$imagebase/icon_help \ +$imagebase/preview \ +$imagebase/preview-menu >> pixmaps.h +echo -e "#endif //DCPIXMAPS_H\n" >> pixmaps.h diff --git a/deco/generatePixmaps.sh b/deco/generatePixmaps.sh new file mode 100755 index 0000000..6fff33b --- /dev/null +++ b/deco/generatePixmaps.sh @@ -0,0 +1,28 @@ +#!/bin/sh +top_srcdir="${1:-../..}" +imagebase="$top_srcdir/imagebase" +UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ") +echo -e "#ifndef DPIXMAPS_H\n#define DPIXMAPS_H\n" > pixmaps.h +$UIC -embed baghira \ +$imagebase/brushed-gradient \ +$imagebase/brushed-tile \ +$imagebase/button_jaguar \ +$imagebase/button_jaguar_down \ +$imagebase/button_jaguar_menu \ +$imagebase/button_jaguar_menu_down \ +$imagebase/button_milk \ +$imagebase/button_milk_down \ +$imagebase/button_milk_menu \ +$imagebase/button_milk_menu_down \ +$imagebase/button_panther \ +$imagebase/button_panther_menu \ +$imagebase/deco_glossy \ +$imagebase/icon_above \ +$imagebase/icon_behind \ +$imagebase/icon_close \ +$imagebase/icon_help \ +$imagebase/icon_maximize \ +$imagebase/icon_minimize \ +$imagebase/icon_shade \ +$imagebase/icon_sticky >> pixmaps.h +echo -e "#endif //DPIXMAPS_H\n" >> pixmaps.h diff --git a/deco/masks.h b/deco/masks.h new file mode 100644 index 0000000..75c2fe2 --- /dev/null +++ b/deco/masks.h @@ -0,0 +1,81 @@ +#define help_width 14 +#define help_height 15 +static unsigned char help_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x07, 0x00, 0x06, 0x00, 0x07, + 0x80, 0x03, 0xc0, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00 }; +#define jaguar2_width 14 +#define jaguar2_height 15 +static unsigned char jaguar2_bits[] = { + 0x00, 0x00, 0xf8, 0x07, 0xfe, 0x1f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0x3f, + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, + 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07 }; +#define jaguar_menu_down_width 20 +#define jaguar_menu_down_height 15 +static unsigned char jaguar_menu_down_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0xfc, 0xff, 0x03, + 0xfe, 0xff, 0x07, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, + 0xfa, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#define jaguar_menu_width 20 +#define jaguar_menu_height 15 +static unsigned char jaguar_menu_bits[] = { + 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0xfc, 0xff, 0x03, 0xfe, 0xff, 0x07, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0x07, + 0xfc, 0xff, 0x01, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00 }; +#define jaguar_width 14 +#define jaguar_height 15 +static unsigned char jaguar_bits[] = { + 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, + 0xff, 0x3f, 0xfe, 0x1f, 0xfc, 0x0f }; +#define milk_menu_down_width 20 +#define milk_menu_down_height 15 +static unsigned char milk_menu_down_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0xfe, 0xff, 0x03, + 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, + 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xfe, 0xff, 0x03, 0xfc, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#define milk_menu_width 20 +#define milk_menu_height 15 +static unsigned char milk_menu_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x0e, 0x80, 0x03, + 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x01, 0x00, 0x04, 0x01, 0x00, 0x04, + 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x0e, 0x80, 0x03, 0xfc, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#define milk_width 14 +#define milk_height 15 +static unsigned char milk_bits[] = { + 0xf0, 0x03, 0x3c, 0x0f, 0x0e, 0x1c, 0x06, 0x18, 0x03, 0x30, 0x03, 0x30, + 0x01, 0x20, 0x01, 0x20, 0x03, 0x30, 0x03, 0x30, 0x06, 0x18, 0x0e, 0x1c, + 0x3c, 0x0f, 0xf0, 0x03, 0x00, 0x00 }; +#define panther_menu_width 20 +#define panther_menu_height 15 +static unsigned char panther_menu_bits[] = { + 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x07, + 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#define panther_width 14 +#define panther_height 15 +static unsigned char panther_bits[] = { + 0xf8, 0x07, 0xfc, 0x0f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, + 0xfe, 0x1f, 0xfc, 0x0f, 0xf8, 0x07 }; +#define milk_pressed_width 14 +#define milk_pressed_height 15 +static unsigned char milk_pressed_bits[] = { + 0xf0, 0x03, 0xfc, 0x0f, 0xfe, 0x1f, 0xfe, 0x1f, 0xff, 0x3f, 0xff, 0x3f, + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xfe, 0x1f, 0xfe, 0x1f, + 0xfc, 0x0f, 0xf0, 0x03, 0x00, 0x00 }; + +#define arrowUp_width 8 +#define arrowUp_height 4 +static unsigned char arrowUp_bits[] = { + 0x18, 0x3c, 0x7e, 0xff }; + +#define arrowDown_width 8 +#define arrowDown_height 4 +static unsigned char arrowDown_bits[] = { + 0xff, 0x7e, 0x3c, 0x18 }; diff --git a/icons/Makefile.am b/icons/Makefile.am new file mode 100644 index 0000000..e5515a8 --- /dev/null +++ b/icons/Makefile.am @@ -0,0 +1 @@ +KDE_ICON = AUTO diff --git a/icons/cr128-app-baghira.png b/icons/cr128-app-baghira.png new file mode 100644 index 0000000000000000000000000000000000000000..bf8df39fbc902af53330b1f99793b446dcaf553e GIT binary patch literal 6532 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 F^FJl15wrjR literal 0 HcmV?d00001 diff --git a/icons/cr128-app-baghira_blue.png b/icons/cr128-app-baghira_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c12ea7186eac8e76dd2e56874c713a68ac2eb1c9 GIT binary patch literal 8739 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 N002ovPDHLkV1kX&8WsQm literal 0 HcmV?d00001 diff --git a/icons/cr128-app-baghira_grey.png b/icons/cr128-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..4bef378b452c93d64bf1533aadd52f398b48fbb5 GIT binary patch literal 7737 zcmYkBbzD>5AI9&-fJqBeQb3%Dlt@UI0Hh zUhqO@^;k_Ayn>$-rG`N8a>Y&E*c|{U8U8yVz^61O@K16Nl%@*#80j@i79ib+Wd;Cl zbfA$xEo*vvWL0gF~l)CWwkEZoQ()u!5xe5KJ zI?vIHrjt$U_5AgfhQ`+>R3@8B%v5alg5Hxov{oyE!=HwTVG(8zr!KE zRjXp?eQ3>jzx$;5G+#tErL1TUKOpIeTSov&!pQ$Seuo}6>-$WUnJSC2G%4sJV)=U? zin2s|d3byfG%DwO09ysP6^xBjV)NG;NEMT{M-ILyb3u?O=#V`kv~9ud@#Dw3k01A% z(8?YR%7rnK z0Ttb5lIF5@S`N8J3$QJGdQtt$x#l+?dY7NwjabyI076A}Vb3Q6d1;O@04J6cu7E}2B>w#QV|Foy4>;^vD|>-PSL8M} zo>w$BHinqtz1bD%M9-P^^=k~jE$#KO$@+SH|Mr&Bb&JvEhk2{3y*&?|%ASC}J}S3k z6dAA1l;|Tv1`z`d!{gyd%|4--ibrTyuvGMVH?!lZ)`uZ*V{-aL9Db}QlU)DCO zh%aZW?1&jRp$e}S+pmZd_cIw_3o1c)Q>SR$wPd&qk#S{td8@Rruu#kH1|Ki)t46b( z2L&U>SvcOoh-=5Er?1$&KN45ZeEwZtXex0l+@WfdS$C6AWi5JhAqLDN4)OmoGamk0 zS-JGw{_*we8qVCtX1TDWq{Ni1)6^ldiZMx7FH#YCPFSRF-_$&1+yut|-b-jMY@Fq9z@-zrWxK@nZH)>#g|p`37UDqkoa z3@xchH)Vjytp+qGj3i=Md(l5ki$=G);%_af=su6BcO|Q2cfJ*jOhC=Q`WglYfa3~X zVx=Od5|_fW`EF(rTZzp8@lNzTMF1+MQ`P6 z{$8^etAXq5>$dJ}-U5#f+qeNzxpgz)6c_-6((hQ2V3!kdgSD9mG9+m#kZ1meqmu?|m!iYB43#ioJ_ z)?2wseH9ow(`9MZ(93F$M569=qQ$Mq@~%Il-Z{Wb-`)K;Br5xAkX}K5?8<3a1y@MC zYPk}bB3*#9e!+{*7*mar1CQs2nd->qea9p?Ra+EGA54P0Alq`cKgY#Z=|NJj&6?Yg zXw%@Pd3vSk6-=f6PmrRK^uHSBEHm`1k zTd3VS=c9Xs4jCi2(4DRNc)dKLIlGG>MD>I+4k<|ua4stUJs@n@ae?=OXQL$8VrUGg z3D1IJSY4{1<_%s_>4sVBO1h(LY29o-r_5$G)*dbgX4-e+a5x;+uJY%N3w0799_g4T z%jLIhRM?OGn8TP|7cYpdDSe6p>i2~ydHS=ia>lEN5VM3I3�R=?a4;V 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 literal 0 HcmV?d00001 diff --git a/icons/cr16-app-baghira.png b/icons/cr16-app-baghira.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8f3afd0a594d8e02451c33d4ba999984626ec4 GIT binary patch literal 870 zcmV-s1DX7ZP)B zg9W=9hE8MXCNoLCBwsSgmrTC#vRh`m@A>)tczJkaT)I-Jq-dIUQgb-VuPUrWcD7ugH zWEdV98Nur6>buoy^|?x=f^xb1fvTz}TU%RqyWQ@B5CW1U-2(9U1#?LtM^RMsJP&D_ zqTlapGcz-9s;atR+cqer$n(5B%n$$|geZ!l)Hvtv$;ruoNs{1^gp7`kzG#}}mGkp+ zIF6GEAs#%@0U<=%+}!+VZf@=i(=;bt*FBVFxp8)OcEz%+BSOeNA>vWgh=J->FJ5Ry}eI4=US`PS~3jd(DS^XUDqwrH2o}&l8` zR#xsD92``WB&h+oPF&Y@_V@SyP!#1x6h#1VjSx~^TwJ`VY1;dg($ewq@ppz{{4hH^ zd)qLKYP;P=9LE`eo-BkIbUGa)2!hva+nxmQ)5gZe#P;^~=aow36-km_QdPB?rs;qX z^0H}~bzRrNIsXN~mofk(Nn%q)P5{w7a`|H_NhXlv4P-CT%2{`99$8iK>Yy-f*0F0-W zI6puCmJnjmG)+)S;kqt--$xJxV2putt^qiI3_l@|Bnji=DGz@jd!AQ4Jv~K|Bw&njN~uXH4SnCQ$8lT+kO7FFn)0I#3SHN~_dHKY wlH_3!1c!{Vqdd<;Aw&bf3V;@XKZgbX1EHV3O;un!i~s-t07*qoM6N<$g4NuU^#A|> literal 0 HcmV?d00001 diff --git a/icons/cr16-app-baghira_blue.png b/icons/cr16-app-baghira_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..27b35efad9fde31ecacc7879ac0c23d01090d75e GIT binary patch literal 941 zcmV;e15*5nP)$a|RZP(t9_V#}C_I~&zDJuWBe{#<6oczzB@Gk{|A@%>phSsnH|H-uP-VUmE>lL8$3HxE}y^A2>Sl!PkE!o;x$W z=xyomt*$4l4MkCS=7n7^u|8kG;}6yOcI+Q(Y=5Hdm3PKZfURpb*>Jnd$6kCSfFMXp zG-xhgvY?kORQ!>S*518)5R7ck7EOqng^KM`{{gVUn!u*!9i0y2_x!oIy0j`;5L6q6 z4N#%RhBevsreq63(a>EXKK~HF>-AEH$4{RaKK1SOnxRk6O-34pFR1xn_D{iy1n(SO#nbO@>?6;JAU$v%G9^U?dE85d0|$#b?Jgs zDCW)SFF#XPrv50n9Gy!i7n$1=XJ0!sHrBH5f`HilDY_+vxD_*yz~%ALle8kdiA%6)IRS*tjnmB{7?v60Ja&noHcpFQ1HK zWBv~P08qT2-uf8l+xhbA@5&|>kTerY*@0@h&`bx0LvvD5qtzcjdKFT91)3lM09}34 zuKvM6gKg~0iDgK-gS=`%)@&3E8;W70%tjuEU9taZe&`bkk^;+j#}bl7tjQME3l_49 zi=660P#ws+jS9(zu&If!9$K{lLFP2qONthBqv9y4Rut2T1xc30VxYZOCj#}b3Xk8D(wmhL*fNYn4?E{L}r2JQYJJy@t%KnQFk_QvjZ*<{nVB P00000NkvXXu0mjf-+;ri literal 0 HcmV?d00001 diff --git a/icons/cr16-app-baghira_grey.png b/icons/cr16-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..ca3e367e08955b10be2c88c6b4dcd03418873482 GIT binary patch literal 922 zcmV;L17-Y)P)0hilX?Sqoac_m&+vp za6KLm2!bH^e7+zdM2G*=)YMe+@bD0))9JHBA|V0*B$G*TZEfwhm6esBqtWQyoBf_! zg~tQQWbz%3<06qrpJ|#F&FAx(o}QjZ#bVKy%jLFJRsFHIxA*OnlM}SJ zx3_(8aPUc2S69$=UD`Cw79Eer`BWw&vorPl{QP&zvR+mcm`LzkDA%JuNAPoyXc1_uXUt=H=`#u!Sa5@3v>TCF|<0RY$D-hSt%>9Y+y z9uG|j2^9(jAcTOf>sQ5M@lTAgZrk=itJU(`wryILW&A6^wrzWTef?`)*S*zhwIoSW wCZEr58-}6BVzEb&NaS@wh*YUme!U6!3wp<{%r>?)vj6}907*qoM6N<$f{t#kZ~y=R literal 0 HcmV?d00001 diff --git a/icons/cr16-app-baghira_white.png b/icons/cr16-app-baghira_white.png new file mode 100644 index 0000000000000000000000000000000000000000..6aee8c76138b66d367d6485f8d4c422a23a8fb91 GIT binary patch literal 965 zcmV;$13LVPP)HyDcXtHd7wzrsk3>e+_M0rr zSdt{NyuAEpU0q#$ZRvf0-|r7N9F7llT?ebxY91UM9J#!_d^0gI@hu^QMhF4Nai3VN zRvSX-zjpwts%o015kd%HjG?8a#T^cZ`&gE>YnlcaW4OJ&Eg^)|ngW;0^>HW^>d#~{ z=NA_jXSrNXcDvm!!!V#+E|(aFslymkx~>Dp7!D5)_Y_4b*0#pu@mG>08TsjJ^fdfWs=Ec$no*9-rwKI-N)) zlA5N0VHm(L3{ziU|3Pze^G9=Yb1ybGH+R?9*Z-QHo_=n#*_=H+J&(O!Z=0ehU>FA6 z+}y~fm6esBoKB~wx3_md6vclq#%OhQ_2t08z+;RtV2mLc47PI|7r45*k`O`^LI@B- zMk0}TNdW-Z?eS$4Dg7r>ZLGx?W3FRq@{5-rs(|-`CjK_#l}~t}iVu zJ$uWEv$L~{ilP{$Qi&7_1#*3TO(aPoxm=E9vssc#rR3q^;io*$4_Yji2LJ$cb(rJ0 zz|_>#cQj2?gphY^P6&b4)>bFWvW@9_teuCB1p=W`o|@!nry7={W4gP#Kc zRqfRP9*@UkHk%m$0Gg(Oq9~|TDoU|fECB#e6jkk0_o2045Cq{ulBA-^WU`!}pJ!63 zRBCs3_f@4*sf>@0KM9A!U#Y5!c6N6D0D#(!{{y(vn!ya^Rb>DG02+E!SaefwW^{L9 na%BJjc-jljPsuFEPss!T4om|)&yoi~00000NkvXXu0mjf@D9Ap literal 0 HcmV?d00001 diff --git a/icons/cr16-app-baghira_yellow.png b/icons/cr16-app-baghira_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..3523a6ec238425dabff6762577ce399b1dfce502 GIT binary patch literal 899 zcmV-}1AP36P)o2MFv_Nufty>@xcEA^3`MvZ+q_V3j4{z&xIaK$bcu<(;L608CEj@uq@Yo-I~$G;YTM zsVIV70j;gUEw|)XF!;Z`{L1}(M()8>=m#xwV4pY)Ffh<`cw%hp?cq64rfw7a*5LVJF$B;E4X1!V72oZ7@}EL0WMU9Wqw^OQ?A-bT6) z9d!3}?kYT#Pp^{80XD9G2%Jvg*w!TcAVoa7v?%o?dd{X=McWyu1~8L#$t8uaA+!;s^Bo!YbJZ!XW5>NmE)IFV9R6GzKGCn9 zsHstuqx~F}M#dAF17n3s)uO0cmXwjXwFR%6Crkr>cupC4_Ju(6;GplLuHD6l13vSC zeL=goQW0|Jy`@gOSPf23!^8|%ZjAGZSl{OMCW701?0KfA!~gyVt!EnQ(_RV*3h_LN zCCS}ck(-VvAqUnYkws?Df6tpUQAV|OK`hN=ZN1BQ{SDvO4fVR0H3O?qqEwI+OCXTm zRLZu$y39Z-%TzYc0)V#hru}`c=R1SB{gh2?!@$gz(RIk@!7!kqPIl*4h^@n$K2Z^H zU~lnpvAm>~Vi|I=RnjTQW+9gYT?bWRtItFG#-@KwpeU$SbJdfK*q8-a)+x^~ifAk$ z4Tm6DE#q2Sqf)L=_*cQ2g>~UuF=VbNjzo%hD9p{!gd8uBN0Y@V5gIKOQa Z{0Rn?a(x}OA4vcJ002ovPDHLkV1isjvG)J~ literal 0 HcmV?d00001 diff --git a/icons/cr22-action-bab_itunes.png b/icons/cr22-action-bab_itunes.png new file mode 100644 index 0000000000000000000000000000000000000000..762c12b6337a7be9d721e58529a38e18c2810333 GIT binary patch literal 1439 zcmV;Q1z`G#P)5OL`-yML#A_c5p)ql#FsgYvIKoZ!^nIyKJYLh(LLZYU-se>6J4Sv z3o#i?L}g8e869b9O5yg;y|?#Y@4ctDJ-&=(LFRT|znovbeBb%L1Mokmp`pRw)YKHD zD2m!1qiLFA7>0h--A4wF9Xr-FIXU@lZ*T91k|g1HJRT*45CDMA&d!$6(b0*nuC8}^ zo==OSn0_MI>-Dl1FJ7GN?Cg9UAynsfyI)*gU0uxQ^NIcY_Xnq@rY?7PcMq~Gdyo(k zT3%lM!M1JdVT0NUZftA}Mk0~tZQBL_0FL8oTU%R)D2jsN;o&pw?d>mXng*(>0>^RB zcs!oac4J4FW!YVX5RYx!P%4$cwr%iwz0Wo_Hntu)a^wxmvOrZ;&@>H9({xf4<$fX< zV{8kdD>+0%iL!nSdRaI5> z=H@1!NF>$@g#w782&$@rVHl>%FLWo zJw4+L!*s8#tjseEQwauxukbvNc%FwuBJo=?nY`B3)%CU{NxRbNG-NUv9F0c5$Y!$( z9LKRVP1EIax%>b=ckbMK0|Nsemr5m zKA*46;cz^cPNz$E?%bJ)#bRIe_xB$^d-m*?`}Xa7GnGoM=(?U^?w6q%A%s|#1*g*q zfk5DREEYR7Gcz+B3 zYc)-Sj*bp9m&=`D001OO5-rODj4=>GfTn5Zo;`bd6N$w4u~_UU004)>K_i4{Ns_XQ zi;FV=0HIJQFfuao86l*0tL843E5fquE(QQ#Zf^yuN;yLUgGNF;#gc~BGu%H?vA5P}&1 zfLph2{eJ!W^`GnN>IMWsfJ&tTx~^{o0)d+I=g(g_apJ`Lgb=qRNzm5T_EtC??z?p9 z(r9&cb%f`6M>3g&jg1X3O%nt`_`|X+g$4kyEUUD-x*A0Yg)Ph4t0+n`pU;0iF){H; zUtiw`l}g2lF$Tjhpja$YZnrz^^?IMOZM(>E+~IgU4%uuLbX`x~zI}VVSS)U$hu&E=kp*40_1YJQam32#p!f*YMQoJQ4~HJ zjeZ)7#jXGVFb~6qVF-p{%$`1d`nCT4{*h9tMBBCv<#HJ;%Yv;2V~oMJZ3jZAV|I4- zbBuA7D2fZYT<)(ei`hOg9*?JLXlUpohr>~G9{|%dLDRGc<82rQn5GF7MKx6_7547k zyVH-|6$cI+Xm4+CKfHBW(=;d)3LwiesHzI8s)DZTpzAtVmWBL&|4Tc41pmo65{VoF z0DqxS0L!wVSS*6B>!7MC$g&KIqCD7a7-Mj|-OUb%!);lX`oA#4FnhDvEZVB6X_{ad z256cFilPujQIIUlU>F8eDiuHoQ2>A*n{g(S5jHk9%C>FOmSvSyRh2h4H)Hqi-J8#3 zG6}!m|EkC1=|KopBZNpUmz%>FYmbHJ=jX363{%Z58 literal 0 HcmV?d00001 diff --git a/icons/cr22-action-bab_jaguar.png b/icons/cr22-action-bab_jaguar.png new file mode 100644 index 0000000000000000000000000000000000000000..97f63f34f46e33800655dbb0ed1ff0257efe4361 GIT binary patch literal 1438 zcmV;P1!4M$P)Zvo5!yhvfih*wBLo=g9EpPOG4k^%)GN-P`T)8AhXzV+S>?HiwZbAPz`jt5ntFenfF`ZGM@0l<=# zcU^n))>qyNFIm@_)y-ONzgSX#gMy-pOrWM#?fd=8#WH)eitr-OyTn&Fv37mM~dB)?8!_7c3B+gIW3c z5&#@Ma`;H`wVUK|-51g9Kk-0uAw<6ziIx`Lc;EKTv4tz{&k|7@Jbm;~@3$YkmyMqs ztXp!^4XPNaxu{r3suZfj0msUK5>oi-hMG0oWs`wH0F=T0n!5UVo1fbK zMoHb(x21K@C+QTtuxhEleDRu|eNSxF5vm%LT`{h>7|l{Ro&by;?}9BGJ^*0UW$EEl z$Fov2toe##T#5fyt#y6;_><4PT-9{VTHSU2OzI>4syalP+PqsY$G?C)I7K@g+l?Ga+ofl zJDh1IbyXtHQf)5SE(Zh=V4e%^P5Yas!E!1&JgS(Q$AthPu4QPMQEjxpXQIFRuq9uJ zdlk#uN%?hm^H~KY;GE)o*VnKVZK@+o%M>gO6*sS4B?iJ#JCjJ*V}oZMIiBFea3|MR sj)ao=H7Kf@2kKb3*nJH4ggMpu13!fXh+nYPl>h($07*qoM6N<$f+zg9v;Y7A literal 0 HcmV?d00001 diff --git a/icons/cr22-action-bab_milk.png b/icons/cr22-action-bab_milk.png new file mode 100644 index 0000000000000000000000000000000000000000..8737ca8d2217e04857f7308d2f99207c509e4e28 GIT binary patch literal 1410 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 literal 0 HcmV?d00001 diff --git a/icons/cr22-app-baghira_grey.png b/icons/cr22-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..762c12b6337a7be9d721e58529a38e18c2810333 GIT binary patch literal 1439 zcmV;Q1z`G#P)5OL`-yML#A_c5p)ql#FsgYvIKoZ!^nIyKJYLh(LLZYU-se>6J4Sv z3o#i?L}g8e869b9O5yg;y|?#Y@4ctDJ-&=(LFRT|znovbeBb%L1Mokmp`pRw)YKHD zD2m!1qiLFA7>0h--A4wF9Xr-FIXU@lZ*T91k|g1HJRT*45CDMA&d!$6(b0*nuC8}^ zo==OSn0_MI>-Dl1FJ7GN?Cg9UAynsfyI)*gU0uxQ^NIcY_Xnq@rY?7PcMq~Gdyo(k zT3%lM!M1JdVT0NUZftA}Mk0~tZQBL_0FL8oTU%R)D2jsN;o&pw?d>mXng*(>0>^RB zcs!oac4J4FW!YVX5RYx!P%4$cwr%iwz0Wo_Hntu)a^wxmvOrZ;&@>H9({xf4<$fX< zV{8kdD>+0%iL!nSdRaI5> z=H@1!NF>$@g#w782&$@rVHl>%FLWo zJw4+L!*s8#tjseEQwauxukbvNc%FwuBJo=?nY`B3)%CU{NxRbNG-NUv9F0c5$Y!$( z9LKRVP1EIax%>b=ckbMK0|Nsemr5m zKA*46;cz^cPNz$E?%bJ)#bRIe_xB$^d-m*?`}Xa7GnGoM=(?U^?w6q%A%s|#1*g*q zfk5DREEYR7Gcz+B3 zYc)-Sj*bp9m&=`D001OO5-rODj4=>GfTn5Zo;`bd6N$w4u~_UU004)>K_i4{Ns_XQ zi;FV=0HIJQFfuao86l*0tL843E5fquE(QQ#Zf^yuN;yLUgGNF;#gc~BGu%H?vA5P}&1 zfLph2{eJ!W^`GnN>IMWsfJ&tTx~^{o0)d+I=g(g_apJ`Lgb=qRNzm5T_EtC??z?p9 z(r9&cb%f`6M>3g&jg1X3O%nt`_`|X+g$4kyEUUD-x*A0Yg)Ph4t0+n`pU;0iF){H; zUtiw`l}g2lF$Tjhpja$YZnrz^^?IMOZM(>E+~IgU4%uuLbX`x~zI}VVSS)U$hu&E=kp*40_1YJQam32#p!f*YMQoJQ4~HJ zjeZ)7#jXGVFb~6qVF-p{%$`1d`nCT4{*h9tMBBCv<#HJ;%Yv;2V~oMJZ3jZAV|I4- zbBuA7D2fZYT<)(ei`hOg9*?JLXlUpohr>~G9{|%dLDRGc<82rQn5GF7MKx6_7547k zyVH-|6$cI+Xm4+CKfHBW(=;d)3LwiesHzI8s)DZTpzAtVmWBL&|4Tc41pmo65{VoF z0DqxS0L!wVSS*6B>!7MC$g&KIqCD7a7-Mj|-OUb%!);lX`oA#4FnhDvEZVB6X_{ad z256cFilPujQIIUlU>F8eDiuHoQ2>A*n{g(S5jHk9%C>FOmSvSyRh2h4H)Hqi-J8#3 zG6}!m|EkC1=|KopBZNpUmz%>FYmbHJ=jX363{%Z58 literal 0 HcmV?d00001 diff --git a/icons/cr22-app-baghira_white.png b/icons/cr22-app-baghira_white.png new file mode 100644 index 0000000000000000000000000000000000000000..8737ca8d2217e04857f7308d2f99207c509e4e28 GIT binary patch literal 1410 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 Ds?uFi literal 0 HcmV?d00001 diff --git a/icons/cr32-app-baghira_grey.png b/icons/cr32-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..cc57c2f9641be3bd14718100ce688d37fbd0f2e3 GIT binary patch literal 2252 zcmV;-2s8JIP)Y?AEGY@F(WEP51xjfd>_ZuwwzWc)nnIa21{xAbL+c7c8rw7w+deR9Ql%j= zq)k=D%G7O0FrtE{rYH#*OcFwzkl3-GpWpv??|t{aeQ2JQ0HGzl(vfZH`kvoC|E~w0 zVtG8Cr`i6+&io>q{C+>Tef#!xd-m+v)6&wiYHDg~N>LQ~aeE_?NT9vF{h4Sq+NkTg zObD^RH07IbzWMU#=;%ZylX0$HyT(qOIB~7Hxq0Qo`?|Win$Mp<|6XrzZ~ol5b7D_V z&zW#IT=S(YkW414PM$n@sDJ4i-Zsi0I+P?vbxi!PoG(} zYSnj5(+sMrTH*8gR+UPn$xJ5mzxmGRKM!E-+O^LllgTc|*k^y>dEht>VzJnk=H}*& z002Ip5BBZbx2L_m{aYAgz!(D|1PCGChK7c33xZIwV1SmEmK7e4C+s-RT+?|x!N$hM zZ2$lr9UaN7TerSWDdh+uU|AMemIVkQ@Or(?e!oAmU;xK)Y6u}br4%ToVB0ph->a*u zS9`tQ&*|SAlC{K@gTyRaHgX+S;C_ zlzI?CplKTDx(>RoyC5nx( zfU2sXX&RWO3A(P|BZQRZJAaO8{C>Zurlw{wLWn7fB2r4(z`#JdP$=XCL0BrwGH9As zhA>T2a~uZ+0)c?0X;3PaK$hh)1VRY%`TP~zw#nxL)YsQn9y)aBXNg4O`$I!R^z!A) z?_arc<@a~*-W|Dq{rZ1bu3Y(=BuU^xSe6C4t`FsMx!m2mcg0{Z2$Cd~A#_~_P18ok z$Hy-|$-?D2uy^m?*LUyUeIghP)-%THd_LcLj^h$zV`Kj=7K;C;GF~*>28c34FQA*n#$3cC4eP?ak)+3R~bE>LVNRs4a zGMNwh`}< z6oZYrm!_$|w&2V49{TisA!8 z2)L!xh2c1ki$(;Hl zt5>i7Yiw+6+_hkLcXwM`TiZ8h;;Eb+hG75zFvgfRCk-!Ny!emq?(V&WkeDP%psFem zLV)8qAcR@fg$oyc^Wldd{uLpF zTUuIHGsYH)q6mdT0Yp&*Ns?fus>+I@r01kzKA)cs27{q+IJ~}4DDZ_s0SvE6!H&R1Gn zTQ_I3S;*ybkj-YHSS$i#3?xbVIF(BMfl`V+v-}6c!^8bvuXiy3bZDC9aU2H>!x$MH z9DH}jjvecc969pGs;a7`wrvAr3@D{803d__W9+N1uYZmZlK1(1d^{e1IhV^pE|-IR zJ`WgUV2qi!Zryr!dV0EVjs*Y!EX%S+Mng(_Ce`oXN%@xOv9s5%# z6l!#pJB|akZI_k1Ef`}g)YR0hRum=e^Z7bOQ4CB^PrJT%GMUVKH*elN#TX+10FOlW ztO)lo#%M=JNBr#Bv*+XS`15XdxNX@qO;A;}EN-N$stWh--@l~mdZDti@;jDgd2QQP z$H&M2^696a{?agv{9~KZ?8O+Pfk41>;J|?c@p$}sLI^O%%0el1r=GIdwq2G`DD?Fk zH*Wk?mgNupet%q+<-Tk-`|-oAd0qejfOYHEeRacz4X@3v3-0Y*v(Nbc5pf(RxMg7tl2p~`{r(waepI( zfH4L<&qHNpWpqInAcQO~l}fzpf7cBzglp=V$!HD)rL=sGZQFQ30H$f8QmF)P`ndoz z8Q`d@TFT{e>1;MT?DzYV6%`e05kh|3{_H8paU3wluqcXy3j#=`QdiRH^d~hnH7jS7 znwqBNve|5EY;3G|XlUr;si~>7VHk2nMMWf$NW9wA)bztpD74Ju@l-O#(B$Og`x6rr zA3X_R-by(0{AyXgeEDjOF)vBdv@FZ_MN!NmgdS^FzuzAYg+ld$AVe8snj}dhPkIvo a0Q?^)a4XfG_EA6p0000yKkOw(Bw$ItK47cEd| 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 IM6N<$f+)?_(*OVf literal 0 HcmV?d00001 diff --git a/icons/cr48-app-baghira_blue.png b/icons/cr48-app-baghira_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..14bb2e3852e8fc4cea0b2520d4240fe071668973 GIT binary patch literal 3867 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 literal 0 HcmV?d00001 diff --git a/icons/cr48-app-baghira_grey.png b/icons/cr48-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..f11f3db1113f76a1921654419bbba5c485139264 GIT binary patch literal 3564 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 literal 0 HcmV?d00001 diff --git a/icons/cr48-app-baghira_white.png b/icons/cr48-app-baghira_white.png new file mode 100644 index 0000000000000000000000000000000000000000..1bab2342dacb9736935391f07ce12b47440521cc GIT binary patch literal 3464 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 literal 0 HcmV?d00001 diff --git a/icons/cr64-app-baghira_grey.png b/icons/cr64-app-baghira_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..f729b7d9aa850a173919ec0bf67b48d0bf5c46cc GIT binary patch literal 4888 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 Lx~k>M_|X3YMQh8l literal 0 HcmV?d00001 diff --git a/icons/cr64-app-baghira_yellow.png b/icons/cr64-app-baghira_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9300df08d70bb4cfa8f0ef9b575915d2de22b2 GIT binary patch literal 5244 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 literal 0 HcmV?d00001 diff --git a/imagebase/AboutBaghira b/imagebase/AboutBaghira new file mode 100644 index 0000000000000000000000000000000000000000..2f439584bce866b99a71f548483b45e9c4343b64 GIT binary patch literal 9546 zcmXY%1ymGo7sh7+VWrz8qy#}iIs~Kyq(lva?CSh`D) zZt4E!f6ljicITYgn3?yz_rAa9xf7+Q^OTI3kr)5~GIcd&18^Ji-wR3zzPHI)^?(~f zYt5(1z|DWpoTkDgaL;WwH4{$&Affs11p(4BVBk(7FLiAdq7g!}+bql{t)UkHzy_!* zD;oJtZ3p`M(ZcIb0(4#?W;65HnVj^X0R*9;JTPSynA;CBJpvUXw@-t(TTkseben?a z@3JDxrv2 ze;elp#4?I+NW?Fd9i6?l@yik%^1fSyVNBs%r%}zCEmUtGb1BoPEAeC1IDe8izXWCwhEKnZPZ^jz&vvV$xr zT_z?b%EvK3qV_^W8u1?C;&W3F`3jT-kd2KE%iXyqZ7jdV(S9eZ>&=6U*VkvOg0w38 zl8*z9nV&y@4h>ZR!0U+>{)!=fuSO8hDo-vhE=~rx-CSQ?e9XQTB0k+x_cVcJS~Y=% zEUh3kmq!4q`zYk>g%AwwCPmudyGsa%b8k&mJFTwo?B2TbLP#$$4|#QQlKtG&l=%Di z?+Q=|91ac^0KjY({8=cK+!ot!PqYNfi%CdaciyphUGY^k_R+A(Tlt_%Kh{on)&xdz zjdqwFsu@1)eb)=&>Z6l_?CS0g)#D)m&rI@YcRm>I?S14>N!<~DH$Ys;zUPy$4IwFm z2mt^jc60JXCsI8-RLeKW;UV_g93#`v&|ssEiltJia77?y8^HN+dGqFtZc0juxhXiE z-L^xC6UNr9q+yMXvJ3uMGCo@qbk)_>H$iE%jnmIl0&Ol&_nr0isg%Fy>%psUJrfBx zPC;6l(1ZV*)7%{7<>KP99Yw=^?Bfr_vdTBVU8<|q(9{GkIIRFl*yp%nmRYDhEVedQ z%GAEJf2qe~{pB2A%$i1k<0aI5$#`e|e=?0J)R(m97R=Z~*6mtED>Zwrwg6n7_a z-;^|+`%fZ2A~@BD_}U^VTvcCtwv?PZUNXo0VxuKibZ~eOt@Q?5c zP^JB)Fy9=gn1UP->r3v^$$7_lJM0G=c(7b$4&mA!JcZ$^V!tfhM6WTrnn{hjU!gS2 zQV7~@i`6#&`M|K?(jYNU{nxKwl%$00$r_W?Q|ewOO@=(QcuHL*4@m$xoDUWOiLKz` z^TrQzA7g5H2B(vX4_9CVFc|Xhi_v@!9kg!>bhES4weDwsj!w_zDZBDazdF=|Crih5 zn0pPXs36FJj}}4xl8EuA9B5~|=3xbCcVI(;UWJNMDTn9xY$?Ioa9Y8chlfY&?nyX* zPl|OHF|9H44?nV7MQl*D;VO~_X21)<8c%7x{oz5a2~x7PW798-D8fnsKFU}2eI+f- z`P_Fo`Ps1{?eZM}08@}ssV_s;CFJOzIh5TJMhIm`BB+2>>sZBMF+KQb%7hOwJy7RC z7-1D+1y)_-;VLKWh%O5R0KfZME?c0%H~q>b7s5_ZUq-PJEv?{+x$MTyC}jmuL3GCT zBB_<2LkbPQojOsypWc`A{FViP6l5rJvUkhZV5=8ZL_?GlsAVS5)WAW+(+-o2IrrDk zX`Gr;O%m#B=AQK$)^6-AQ;2mENmK&GD-&1QCEVpeV!O8W$6&#YKGspfWo|3es_%J3973=z9_rDK$!Mq9!Dt05TP zZ~RV;okA2fH)8jIwM4N>9jl!rxJ9h8tHd5Z$)G*$;=a^3eiGo_Rx}5j22m8!1pFCg z%r6mTu}!>=A615gapU)?Z-Yf&s6%yUFkr02q^31n)J{j3-BzqA%L7o+H+@^^>_x># zBf(4_j=_AuM>jANwZgK+`t2jE*cjvRa0jgiuSKoX?CR)xBqPkw~S3-LIzCTBYdxh z=2fk6_u(dE0z`h(-3qZ1_{?fEGpl%=AZ)JNrvQhiyF<$Nf#OsO!0q2(bv@cQ(nWyH z>%1OFh}EayPj8bLoQd%^xP|b45Ywv0C?)36w@WfZA{k_3u|dDD9az^4#6^W?+ry|h z`FoV4m?P9U@nmsKcj1xs8Bj};~E$fqHROoWW20Z(Z$yIzUfB6c5C6U#l<~qT!*!!ZLjB+rCO(5TM%tRTH;(e z?kOJ3L}>+zVvK!KQ6*Ku=O)8q;2?oRAi{=Cy#k|sr2cFry`pUM*Ge<&;-l96^eApY zBCa5jR5T5@j;&NEWUo_P`=Y+bJ>;|LHu!`#S z=2*d0t2bhBt364aMH5}`V@1=gVBq9hSHMoMf-GSj9)Ai`McL8dyeZk(+*_+BXYND- znJnRV(`hztNYZDBd?-r7fv^gT42EH}TkEMd%nJ&UVQw+oc%+r?HZ=MC9ZX zo%Y(KWuw8$`m7+k>ny8JhH}}vPnmrBCLp+toEf%c4dfw(^z_ocRGvW*Dyqa7K$+Ay zwndPQBIrT>lf~W4MokziyK%%0H^Cy#Iz4fZxu*d(2VaZg10zA97#3pkFC^KpRpkTH()ITraWT)-l!2vrZ)D}-dEM{E-W;2q`eXd*V@yXZ!$BfXbPOQ{3n_>)46G6=;+eOx{7(=F1P(;L`D|(Ljc3D! zy218W=SRW&Q>hAUZoaZC^Y&afaW{5tkk}ndecERMdz!EL)rU%bf`BEvC2P8k;%|$3 zD{t8A%fi{96h4Ien;3i$lO4U?-S=}z9@YV`jy7(gDZ#J=^GYF+6HKtw6ZU#ly!J zZq*i{$eUa*O&ztBF7A|4h{Of81hXi;{bW})svrYtdwu%4`3NU>u~qAW3kF%YWkqVo ziQ6LVtTB1Wf!u%r@L9<8ojYq8P-pbfJC2CTJ?+~2(`JTNnoY4a?AJ3ezdt;p@b^TW`gAp` z9=&MMhrceilriDTM(MX+RG4+nK>}RT*_1qb+;bade6C^I`F*=ja{jVl7=Pg>iJ+_? zjMV%ENL3)ZddH<39v5?}4;1RM^6>K$s3*PxDYMU9`uJau;5<9@r}P)yxivp`Phy7W zF5*2{Uz8}1uKbl()BJ95e=lUFE_8oV_0}VSlk68wua1b^e@ z?~Zdia+g(Y_~0_fEae73*+K03SZ-3e;v;xBLq7O=9%<4XuR65GC|zhbyeFij_8W&| z-T#}Ui$ci$0~3+v=O4GYvdvpwMQNGcb`oT9n?$$S*`Pm3il3EV!=0kUKrmbcxz8kJ zIR;{xQ?_|lUq++UMFH&P^F;5yJ{)|?T1x`l*ZLH~rGAcD8~B_LqF-uA1f5LHfx8*v zUNi^u<5#qfj*hLX2Z}B(JBQCK0=>gO>O6c=w>M86)lR(;^@aU8-#7h-Z-nLOh~ES? zd#w-Yn#$~*%muir*w`%jY;4xvYcx4z;LC)D?Hw|?Hdf?`hkh3F7SBLuIx4ySSM!1+!x#L)|X`$I+*GR?cI`~+6{piWRz7zTsc`nZ%( z0hES?SpEQQeSQ6oe21q-+?1big(mErN$PJqmq5bEwt^kU2sWR#YCb*Lnmo8_4!kf= zlX73QiWPnWeQ+QB_QNS`Ni`c+D+eQ$JKUB5pm=T=GK zg#sTwdprv(QCQdcEyj*B^~g7oPeAZ>NxG9(Uox0uCnv`jiOf$F0E|URMLicNq&71@n4P{+_l2>A6gYefyzqI) zx$c`CbiPhwat5JPiWMg5;4Phe!QJ_gYwCqw=myQYt=hRk5FEbh17F0Yi96YHQkw`s z@kn7pY@!F58|+hbIe4db=4jk%I2bERBB_^s=-V_CB|wOa$Ddk03_?DwLT1!Z zb`Xm6qMLqI2=*S{Cp;*$YV3|0p(g-cV3qT zqmzzOp0Lz6MHp$9KR@3DHZTI#6%*-L{yWQm|0)Cp1y!oArZ}#6#qsxm`O41CO~k2Q zFKq^7w8Eb7)8nfr@^3qHvprAN7iH-vwTRV*k2)ZtPAlzjSzJB;=m6mC?5vMBzh0ZI zw#uuX6hW(^2S57htkOzl`huM?4)q#h{BNenIhqODt36z$Sx>pS3YHiW&=%o|ewUOq zTms~0#`;=c8GETW^bu)gNL3UfES{49%z2ff)KLnc%8nrUq*?tboTcNYFMECW>%q@3 z{Ma2{;2rWz5i#CCqr?WX1GR2n?qJ__ty!TOF2D4l;`q@u;5JhXJ!NM1O0i;0#xs&W`n9^{A7PDpR;;)#CjP>?xNmp~wf|)nO)359++A2x!^_3p7>^kAc zt8tlSY=iB77Cjj$GGvHE(@eW_H120`s;BHA0ZTFM&ENuj1^o{e8}$!|NUhRtZ71jG zM82006Bn4p%YwYC8J5JqyvaB{KR+i8*f*#f)L_Uve#!CPK84%P);FynbDvouF;8pI zkr7$-uh>sO%BoP3C)%2H`HM4TudE_TTU%Q|VIl8y@Q#SfshZQ`V11xO=>qDyOltX zEmTV=$tlk5Sbn^u%0GF1lJ<)-RFR)P+*U;WfTk_06qu5V56~a3sxUH9gd#VN(Mq3D z@Wzr18PywkgsMvoIX~cLDuI1{x!)NBE@aB^QGL)Q;6~FHOj?IoeR@LLwq*xHZQ3L} z_L;(X^`?pvX(o#GDQ%ggGz#BI^TI-V=~K%#2PP)$N2)ilgg~26IU70)67u4ejU&Ur z_H+AW(uNNL+QT9aLo3P}e1=5qBW1s+SpyFTQxiG+ii?ZWiGjvAe{bPi`-xndKEz>r z#GUSf^2ZZ4+x5vzJ=j&Jw6Pv3oewrcZzNZCV{fLDJA_*(1QaGGCe$|RGumOn*~w4< zI9&**pv_v%#`;l#TIA;+p^@?NC!EyXoDn?Hcpw;pGUquz;eQjLQEmDlIO3!9C`s8`;rfqqqrvV`;4K$y() zC?M87otR7Za<7dpN_jEik6YbL&k;%imSGT>o|bm)HIDEVpj6q<%Gdnp@{$iQfIz{JcqD*^T*Qk&=7z_A7IcVqy2P(ril?QS&xma@9wb;dcDyL>bh(?k zzHCrmR_jPMzmy=~FAEL}4s;n^bn^|CQM2vQYsSlVkhJpCWTd|`C-tPqZqv#2=Td+T zP5MnbTO%JkbrEum`%1t#?#wLXLrSaCjh+$iNG=6U@z$D`)7N)xE|c-6Yx)+d6Q3Eg zsqv)|r3je$h)jnDu6>StcnTVPbR3Q98UBF8-m-dE9M2w8&8wCG*d`lhC|n! zf>6@5SyV~pJ^iUF1j{v@39OMF9jXgb@y8Y&u;79FK%UAEE$*}Jl-gYaymJmvIyS}c zgc7mTRet_#^$~-4vZaBo&-b2&v|VQM_t^aWv&RiCBq!pN#|L9(u1A~oEZE`0rG3AS z*ELDoI%Vc5$UlF(llH*Dkl@p7!)_I9PuEITGXSiw_kN6nz|rjQ7Rx`Z?K0UN7~cGi zH(jx5xB23lI!-ma)^H6wiyMzRjj;UGQdG3QZEmC{L}sU~VaGIEjgvkAnPh&S)8`0Ma~?-DFzH{v8`3EqfKV}&m()tu^-ajK%( zaa7NX5gnjct)dTF?({ktQt#QD6&pv^>#uzpAZ(=+{3}u}rDrPke&hDHq^RcVIsia{ z_7{;XwLCYd7PRsWhD&H4*K+jh(1$SX_pL7NpFWA97kKsC3CtiP$w76^t{&`6F3bCh zolp#BU|;|M9SX40iqaXy?RL4(c!Jijo45dWu5e{-@Jsm#=tFa|+kTzYx5_^=~ z^8o-Top(Vxn@V!QA+WaU32K}M`3_V5<|^^&x9#(}pGQf`=&<+vdjrDYEQk*cgX<=s z+(;JJZb+g`v@rro&vj@V=~TMg4ZgOprD~xvWC!g(c<2_>wYj&<2e%D=d7A7)q`*kv z3fkAlZ0O70Pw&*L^^2JUU&YfWs`*~C=JJ@IpRHyWKm2We0^%zotsq(2|0mYuiEF2D zMqT)*9UR^RK90a{##EY_Mc`4goY&ewI+VSsH>nM?rFGs6@`{KtUTM2hWp!U_SBEbp z!Jp4y*gSj15N^C{~bfg`5WTyYjeqwy=i%8@KxKJEJ}(DUTD=(*p)U#mD&K zLzBxNH@}1e2mD@rF&Q?${m%jHjZ6S(v76unK|%TNuJdwcg+1S_+8!Fiz0v;3A4cPO zQ2pw-VRhT(7NJv1Ofd!{yQ?}^ARW5fa&xVrPaC->+tSNJZqIL;m`57DuE7R&U{=p= z`uqB>Ci%)64VJua0(QPf#;ATV6W3<4^ckyr;9}03DwP^xj%uk8ta!eKtDO&O*zV7R zEj{)j7w7I@Hu7)pux;UDVyrPce0hGjj>KU4@1eB{nb^}csw6-UVEy3C+_VzaCoOpL z;+v&nel8D9AB2-HTghpnC7s-|kdzUEk}bsWf|Ap!y!qTQ=Ii3tWMw4iYz4lIEvpY5 zdL4XDx-=%dUpyira_* z)H@N<%0djr@x_?_?_o$twbOXeV9LB8D1-FX6IW`u9%hjd3CUDWE%FbEmFh|{n-c*a z)3dt|E?MbROptVQ-j&WJb%~0Nm!LTNI~MC5>HKVCgkHeZ3&HW;??;(Y@wBttUE`3u zg92}LGi|P(#==4=n5Dk;oi>)YT%X4%h7_gLw*{xziuZdCv%&M z64r@Q-Nei6NO9B0T+KRuo28X+KpIT)W4r?5Gl>Sjk`CQV)shnlINqW+d6di3{{`I} zK{K#dAzVaga|zl5HnlIO$2J63rRjjh{Znbl?HLSVc@l^%F_N{3zUD7FjdP-ZS-ax0 z9;b^oFPXVE!Iwc>=kuf2UR04Zl(FKWq!mehxjgYsB>OVS(7NRmvui{B4-d@k!ZXRX zYl;igxfVtREeUCloYR^~sFer<5BemXVsVeb)Hwe9BoZ5)tCc4@MNDugI{WH=pljUf zS)?zhq1M1UU|`nSWC&PZU!GNh0yX?@=xkLGALWEQmEc$i&G@(a{@yh0s5Im~)!2#P zy@emB7z8=1T%-5t-k(TXl_EV_E=w-#*ACt4p!g-@i`UIee0+TKj^!0k?`mI8yEK%7 zHuWe6T8ewQvnN8&T-<>>exd#L7NB%>Os@F#?fmZUS-;FKr-0VV4wnChBUwZH8T^O? zF>caUnFL$9B5iBL3H7F%)i^&Im|L3v1JvzzFwKvPy~Ixb+FUu^SGsgo4jcX_#Jywr zVq!hd2Fx*M&@v*)JePSnRV9~JuuP*=e-9lGE-Z76{s#`FymOy{Pm->40#VA=`NQXs z!sP+;nXfL``Qm2-{i09pS`69MU-j>vB$zh%YzM6=m$n^~HGKIzWE47Thz?7 z#fUHbWfyb2(lJ*mY(c+U$WaV$zPY~GmESdBw*2?EyCsFQNQyD8=G*Wrt(;_Vv-`Uy zg7}#%WbFg`(eoyP_Zj@*VBh6|Cn+ggNXA8VS zl_cZ-OlRjS=gF4TZ9AI>eh{!_)dC6eZ6F|88!aAZM2vgJm6@A%N4r$-h~2C7Ch+&h zpI#^YAUb#zyk#3?CIw;7vmMA$6l8tm!TDMhe<4xx;df*G4{wYwNCu=NXAL^y-F%`m z?*7)V3lRNzn2~@RXI&qxJvusSCPNI!M^W?i{G0V* zl)eSp+L88RX%9FY=*GMa@Meuq{e<^pE3;Bustp%=QF#op#treNsU^|5USI9@ssix1 zwbMrAQ?-Itk+rVGP(@16_%T5>S3RvX;OL9uGyfiWhKS9nA>m0qF{D&+A35Hhmf=+M zno0&c8?F-6|4Mavh#H84#;bFR$@cHD6v9V$vCobrDb`-!l_ERhS~ za;ZUMd#2nyjH{`DCL9kJ*o=?*0s75lqomk_Llej^eqz%v+je|~+n6-ztFcRFnVjh( zDt05k0uuGJDha0{vNB!A;}2JI}|+ejWgJb#0D{GaKl1 zv8?<dO-8zoN5Set0O*(ry`}tTQ}ea|{^`=8 z8Ta&jch4&AW%uufmCwp$`=XuhPUEF!zKgMVt?_qdzz#wBRL&DAydMuTr^#qnJk3)+ z)Dlv%`~s|CD-YLld`#PZFn2y49Sg7(-Q0e=<0Vxp_nR<-(6e83pGpZdR#1(gQ#g9} zR>*KYTV8#A{ht|6T%3K{@xgJkuam(qt(t3J*is;WPY~FOGL+_%Tv(oSsURsQ&cUrV zSb=8M&8@o=LDbWpKhd{O3Jr?nuQ>&6n;K=Kgylkn%WPpNiVnZ>0*Cov(CJKtXBie~ zb>Bmij)-j=z~P0CX+A}FtZO1pp`X99K}Eq3siTvw1MTC;n1}WDs=UdsKyx5V{Vv6XVOiniyw4rsFluZ@9cx0_8nX{9&L`ZM(7L#8SEOW zsHlL=>R@%(Y~HG3k??)?2rD^jSOKxki|>IK$4|E1=QRbJKBzzug$`4)aCo^h{=PV< zGAF7WhHoNtMx@)Xp6lxmCQynzg^x0Tq*)s_!7bczL8&wkvIsu=;bbIh(CO&<&dKse z3%OWI5kvTB@on}mkEQ+7{IY_Rtv(e>I#28gcwxu>&?$j;BAjp5%l+5%tuH%KV}$^E zluG)*+k0r8f`nb6j(M9{ClCYZx4VLLQ$_N%#*fs|@7|-|4c3>fuGeRU3&(SyIbcgo zpk)6EE1w0~QhhCt%)6l9$jIn#;TP*5K+g-2a1Tul{cH$QiH03>tHW@?5j#4gaPt+| z>Tj@#WujDygMJqL@1!WCz?+Eve=iZZ*+g&OKvXSGD~L_*SAt>}P*>4WE>p4$`ya0D BJ)i&p literal 0 HcmV?d00001 diff --git a/imagebase/brush-me b/imagebase/brush-me new file mode 100644 index 0000000000000000000000000000000000000000..97ffbf89bc00c8f5837366fc41fa5420ce35e86f GIT binary patch literal 1476 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 C$)&0Q literal 0 HcmV?d00001 diff --git a/imagebase/button-base b/imagebase/button-base new file mode 100644 index 0000000000000000000000000000000000000000..a29a3e68b5306c3e6e31bfea3894eecdc0a6c4e8 GIT binary patch literal 3197 zcmbtWZAhe56uvX>JL5Rc_yOtUsFSIgBx*zoWhQP)`e$5pK@^nzlaL}}frV_a6eyYH z55dGm3QJ{wxTp~;MQCWdp(~UhAb#g(XyE8*jygJ>=Vi|@yZ+c_=D?l%&VAqWoacPp zbMNQZt?wH3X1x%?SdgDvMDt5D!gX5u{dM!@dqNm;3vzRAe5_KvVR&Fy(ef3UoSc;F z>+91_Pfs%r4-d=jcDtG8=bTPwph~4uUr~6*g3IN)lx6uOI5_wpqtUoc^LGIO0Ta#5 z&3~q+r#qikze1|8u<-fi<>mMH_V(UOOiT<*O-5AoPwW5h|Ky<9*w_#= zGc#g(dfKtDu&^H<9)2f2KK|>$!NI>hfu11M*w`4_-Q9g(lBCybYHH-<f3 zS@||8De0Zc%1S9BB0?d94?zZ?{*q!GV1nH4?yl(U?7WztpZ_H;F7D>g(9n)z4?i6p z9n$*x`e(%YT6uZ76c!eSWpQ$Hq6~NlQULOGaHJR$_^<=1}88NM`tvw=ge@P`J zB{7?uo1eT&l97=i2L=WzL|7RFJxMC4KK!tgObCv$gGejYnU;8j=H%r3uBIJv5o7kQ2`zZf)og1osKZ&w4l@}L}lvO|88w<32K^d zn+AhHU>5?wlbFBh111O|2$+FK#qACRcz};gXV1gM#l;tjii%|9nL`Oe@CF1S2s1~` z&EAU#jt*2183^hYHrOulaDtCa?djIQz`$$NCtit+j8r~GDp?6L$msQYzYCosg!2?d z4m&7vVAF;Z`}_L~+1c5*q?VSJ!>Oq$iMnZ4US6ISHHDNx0pZ5r=y57R(%XTEATk)J zBMhVunZR>bSJx5QYOb!X{#nk<%yiY&)!iK%8+(&l{q?f4vH*Al0-iO5^kL0c0VasC zpvc)yZ*TAE_V)IVSy@?k!N+||pzA{%b<^9$#l_ar($WxC#td@YXFS)vd1iggp3>LX zchKM8KScMn+jMPO!8gwtr6B83>bd@mC1&=ZrOnlS|aXuD20lj%<{l~M5 zYUsSRwRLfHbo3jlp(P(k(45Wl~T1fNl(Lkr?TqR+-Iaztcx4 z66CaNe0jnnNKpJ`+o3;7k}!x1A7H|*4%s7Zhrb7O2Wcf literal 0 HcmV?d00001 diff --git a/imagebase/button-glow b/imagebase/button-glow new file mode 100644 index 0000000000000000000000000000000000000000..b0c3521d76a1f279b6b0d65f1345d1313a1c1dc6 GIT binary patch literal 4193 zcmd6q%}x_h6vx}?v{ON(s1<0eAH*1>MqdF9M%fT!+!+%e!ySn`Uc{C0E!@ij6B0mD zf>1zOP>js9GyeXUxn*D}rSv9e&iy{WIrrX~bLU>pJRj&Q^`%m&f$0}huh0*W(R_~Q zr;_(3l`4!+Pd$14KAkQXs`d2j>?|$EsZyzA)9G|SGL*?=hLMuvI0bsR>P3C}xcAv} zQ4|GX7&cn1)&{zU>{55Y%*};`g-8~RVQWf&0zz)Nt~-X55d#UE?b}I6c%mj?d(CEZ z9a#hRJ5r^t4p(pj(gNbSv1~T`D3{CKCx0E_%K& zPD~l#v3+C%ur*`_S*3oL$pc+$+mNv}y^-#{KKdt}tAZqCQYfcA+wmkwZ0!O01FcV? d?El7)0hGbHw_n`;@Z-Gl)6Zt6K0kf;;UDaJ)Jy;X literal 0 HcmV?d00001 diff --git a/imagebase/button-jaguar b/imagebase/button-jaguar new file mode 100644 index 0000000000000000000000000000000000000000..1037901427d324285e62861b912edbf9369f1d73 GIT binary patch literal 3197 zcmb`JTS#VA6vy}X`FX!zQyEkcO=U!VN<{_3A$^&m=1BtUrH2rths5YjB$ysW!GQ#Q zEf^Ae5J^Rn5=8Kp7Zeo7yqov?t@YdEl9NsJNiH~NopbiO{P%yawa^jV$DRS@#)zH4D&!IhGdaxKGFdU|@omX?dKlCgA0*3Cs|opU8SX^_37#9 zV+92TuLta?F|HeJReyhfQfq7L&qG5)X%`n4CN?(KBqSu5z`#Hg78Yi0{Qdo%E?z&M zo}QZX^K-Mmzi$>77tQMGDsc~si;G(;D=WV$DJeN3*!=vw>lRdBUtdCFV`H}fdK@1g zZ!$76Oj=r+2?+@?!NI|QOAg56<6{ff8|`#HJUld8TU%ykX2#6T&GCF$R8;g!b#?Xo zqW7@%;nvyN8P(j}+&eNd@)&k9Gc!$IUY?1Jj5Oil;U+XR)I>!^8IQ+fH9ow1tJMz; z2|yAr1tjq%=PuPkvh&eIyzcwXlNL9udJ-RH9S20QA9+9odpcw z6c7+#o%F^sBL7!wJSIjSNFb*W5;itA_FTX{a!*W5d?ALxfWiPnKR-WcRe!4w4h}3J z^nFC_RjV(xNFG+=1{91%%WhENBOiVcDg!`{0UByqcRGbGRDeRSrGIyK*HZ3{X1TB< zj$RuZ8#dsE? z&#at>K@!54v)J`Jn$BbNFA{teJwyZgQ~5hkjvp>=!N+}wnW7jD_!UkFoc z2gX=B`PE$tj^72(x9+;Sx(^AxkQf*%z z@TPG!PghqLOZO@@HTC1#+S)(uuez|X@TZ)doKI!rT9adp866$9Gk8E8{|E&`>!k3?Wft}fqwUI> zn;-UlHSwjxFJ%k*LuzPHx_nnA`kNdGzOS#ZKXm5*uH~C&KelDH@U7y>)3TTEep3Gz DeEpX1 literal 0 HcmV?d00001 diff --git a/imagebase/button-milk b/imagebase/button-milk new file mode 100644 index 0000000000000000000000000000000000000000..2752228eb9c877ee6a7f12474734dc9888295a2c GIT binary patch literal 1044 zcmV+v1nc{WP)3OU79ddoTCpnhaN**BZkQaz}ilj`Flu1L2=z_M` zVij#@L3Dt3=@5<yOpd)gR^H;Na)uaXepu^X*MIO z%F)pgF~%ZZU0p5i?CfA>+}+*L>-8862DpQng9?gcCfQHv4s#69%C`VhJQXmn&QLHb z^;O1@4OAT?%c}|^&}=rDpPy%8VS$Z}4PL!^6=S#CrQL2*6a^pqANla1M^O~GkIao6 z{s)zqo_sbzV_zc5U{IiTv)$G@O22~`4Tw*0vfJFq6KqEE~x7-$1>ycXjRb{J| z-wYJP&?z1xZh2N3F`aC?Y5Q57D2hlxM5X|{qbQ9KC}MzAc5AfK@wnTpw5nq+7PB|C zDV`aTh^b}y5|EX^m6~n9bo7;qVuTQAgpg(2$AA-HZe>a2F(QCVENf5@aomM~BM2^| z^g#gd2yv1p9>?e6wT=+PDJ5&RrF?hC35ev9FgH>?!af}0l2Z{v08>m$M>g_UPO5Rn ztF+cLI?b!ogY#S+W7(SRP>w}aaLE`ez{8ZVY^9+=k!;6{a0U@=L7#0NqL4!`ryjh8`B_mNAYs33{JVpWm zk#e)tf!Ct%<+D$1?ui91H65=l$=dtKM&0hjmBk&iyq;4^6h&DQtyYW6PKU48zRFJ2 zaM#%>2Xl&)xa@RjwOYjGXP)K*t17S6ft9?AoH0-god1mcpV^CjE@ z3jw_X!vZW0fL?UA>Z>S_x{RZER}9poL=D&gskJss)I&X0s4pP%SKpNoktd^3zP?w% zVWOrU2<+5AA)F7^Q?Jd88oDhB&jl3bFu-lWV)WU!r13d{!dwaP0CW@0p@vtba{`56 z4dC9CJQ&LeV~%|GRmDEH;R3^GvgY3Gs49xwJ0o*kX>d_7)DrkMa_gxoR#mlfAQQ*f z$f+kX$6Wn&ExZ9Pw$^6Sauc}rslj}pk=B1};tRn?JJ;_D~o9D&u=$G_2^9#`! Vtji8PKgj?9002ovPDHLkV1gQ1;(Gu9 literal 0 HcmV?d00001 diff --git a/imagebase/button_jaguar b/imagebase/button_jaguar new file mode 100644 index 0000000000000000000000000000000000000000..609dd1add21f6967cdcb22b4b61bcc9c917977dd GIT binary patch literal 923 zcmY+D%WG3X6voeeA%tMePKm_22qL9!iik^br-zJX}a$Uwp1<_l!3q4Q39`WYI8;+nT0b0~fh5oldvG*YSA#9u~EVS9f-HoQVFxKuY%$iNs1g9@pG%H&c_t z!$aBI+f&r*b!j%6%7!xJ`1m+ptJStmoS2P9qxxVlkaD>!2L}gYnx^1DW~vSvjYcYE zh=jgdTU%KQ6Rd|um&>J`9S+BT!pUSJwDtRaRXa7N*Xs?>&d#b0)?`_h@cnGWUau$Z zc3b&yjX+^!Wj1X#TZmB!4pNa>4+o<$5*nz4tQmVv6DL%$2n7NGC1it`mag-bPHLox z8PL{fG=v%xi_K1_bH(X&YD^QeY7QI3fz~S#h3rGO+nu88n|h^E`GSl6$#j?=qfyNH zEZn0HeW_s~^N4ETq##=DLt`|iMn^_rjciD@TAk){x$V`})sKk$gF+V;I_|KG`!V+S z_ceSW2Aoaa>Bh!JzfdSN@X3{n#o}l9eurk0w|pL40x@tIgn>puGS$$El!S-6=^zq|2Zui^tG#kaQCv4KrHu)cH7K6~xG_CDu(b1#*!7`;X!vLx@s@AGVB*z{Wd z{=Bk%PNY0e#%~_Kl%xmB`!!qtZ%BV>n1N$OQSM5Tbe(Y(XS?05&iJ<3Y(DY!155y% zWrkO))xL;EqbKQfS_uRKVP*$ipa@Av8Q z@=~DN?b2{K6gDn{R;yLG-EP-aj+pZM{qkb5plY>ByE>jjR9%5}8pC2C^X&H&75!GoKArj?m(T+v#))A{qo)vW#2W*9a06z&02R z2pp9c=ab1Kq}S^u$mCfx2MxmD)(aAd=)-h6-Er5?fsFYOID-#- z!9gKK&U%d_xwzGKZj1zJa6}f=h=#OUtz9;ot>^RkFP!<+{<4H9ItvDaNBkJPp-{-i zFGUY?r_-62%jI#gSiC5eO5fRZ0{bBm`*#cv!@}4XNrYeMH>1PgziU5k7)L*zj-KVQ NOWsb!Ki+zD`Uf!<0nq>e literal 0 HcmV?d00001 diff --git a/imagebase/button_jaguar_menu b/imagebase/button_jaguar_menu new file mode 100644 index 0000000000000000000000000000000000000000..5c9b2c8218773d0fbedf29c2d2d945ee3bffbb9a GIT binary patch literal 1283 zcmb_cOGq1G5T4C$HV?BVnwVnMyg;;q2wG1T`#@<0E4DNU9;&_d)JiWcISLg7!BaJ- zdKGGlP_MQgib+F65DhA+1`{74nnV*dA#T!{ACw+!52XXU|G%^UeDlqGvpd?`^H9>> z)B=Fi^{C@1t|q+nY7y^IchU(U_`5ppKYPb<--LU4^!`8F-riPnmvH<0`&=@aRLA3S zJ^6CE9O(6W{^H_7lx0~#zGAT`WV2aWqtRqlDpe6(X*`pzudk;)GX@wAhefyBJ?Qa# zdWE1Bg#v&=p&$UB<2VBX^0_Df}K}ksosMTuN+S<|u0)ftv zkrA)3yuAD#`(doDt%XD)0SgNYj28BZ0iB$jQ0Y)wS_(d&4|twuekz}AcXt;Y4hI|@ z99W~#Xs>`wZdFxPv4EqaBgkYjfC(5Q3LvJ$W@l%IF{VWMd>&{e;pn3F7>!1V#bPgn z)6-K{LSG-8NDMgGKyJUT_wO94DhlnyWI|`8qi85 zQ4nQD<=Hcf{_TbUu)e;|s-m-$RIu4>aqLY6^{2715lki%E0N-e5gGZeGZLq)tPEym zW&laaI2}YPENww+M0}21qTKOTx_t% z#>Sp_Jf4q{NW?(pQ`1S=zZs1bmMCNYQgwB8OE`zGo0^(J0tL0Vx6k6NZ3ctEmni*h zY`g^lRruK%Nb&RY^AxT!9+d?_NT7HTRQV?g7s1(Fs;;gM3=Iu2wXVKp0-m3rSD-WfbX-IJcG|UWLIcwYr85X6bf-1&KZZ9uAF%ApX~7PP=O<8 XR(^eZ$1pnlgFw1EdpbTp7##iurW}X9 literal 0 HcmV?d00001 diff --git a/imagebase/button_jaguar_menu_down b/imagebase/button_jaguar_menu_down new file mode 100644 index 0000000000000000000000000000000000000000..73b3af53feb4278138f2c75ecaf82a4689ca9d9c GIT binary patch literal 1283 zcmd5)OKVzD5T5J3zF$o=DOQa!5U@fhD1k29lC%xjU`r+7qDg;1yJ$Bhn?j+1LLjTE zP)fE!OKPuAcP39i$sF)f%O$lQ1s?@=77*e+I0rbow;+)eCL~Q&IkYE1HI;k z1_1O659gksH{&v@6!-0=^KuV3wQdMy~1{MbR_47{7R(~*Jw0U)oRs9 zxn8daMx&7*3?|J)2EpxigGNJh__v*(p92zs&CN|nBoY;$&*$IR*hunTulG?j8hte}F`-{t zS^|&9!@%0@HXu7_wOXK1D4^MF!ua?&6pKYbcA(SgK&#b)N~MCs!$Vy|K4y&RqJF;*WC2;s}=axfhUr4*svl`y3HaXCXA($Hn7GdQd8F$^Nb*K{xWt${beWJgu~&G zRsTd4@{z71wpe(c1b=lE`2%5MzGI zAd%w_w4+1c_a#Y2G8!eohb20W7SHoU>**OBW|x1w+$HE^@4`ga{W^{R6AOZc$(DB- zQDYM*EG`Bs#w4~Sw)Gu|O-Q^;&ZH@E+@Z4qYyu2q8Dq?;kfUB-Bgy4*f~q9{`{dej yr;%V_DhywsOIh*7qU|a3k+)jyn8W-3on$o)|NZ;b_3T6Gh$*%0di8Sa=_vomDdc5AIxi%2PhI=~n^ z=bYz+5ZQx+gHuYW(tcN{MUhCP+p?@^PfrgW9v-%Pdmq}Gu)Y0Dtgfz#-Q8VPDwXzg zx!j%>)4C`e4#%dar{(1H$&jS71Da+n#GYqLk<9Y)*VDztMV8O!)2_JdZdZs|Y-na? zhE7aOM6r3C64kB~W=1 z88SG(Zwg^i&Mf2_x~g7PAp|9Hl_-b8(Q*FIyI*Vu?^dWo;!|H)G^Ij0at5yOG}H5+B^sbgXLH(RxwRe zg5)5dDsX}MZ}_&c@!HbTQWikkYKIpJg}-xib2Ob!hy8y4ABaytDgZek1MC1lwP=2R zo)wG5y-X&P{oitJZEf8?pD)_q-%rQJ#_YktLAT}B*VlzU-sa|}DwoUqM@L83Er-?I z58KnezP`}q;tJz)j59pK(sB)e^RkwUmHcz$qO4OeTY?MCGzHmaD;cLi^A!o6TA{ z?f_pv=rWpRep@USK8#zzBw#<89q)!=Bt7Makh#zJm`6Ai_UyFZ??+8$vo#6y$zXU- z>-hmBA+y2$DHS@hzU3Y T{CRNvmFmX9Vg3F67sr19&aN(B literal 0 HcmV?d00001 diff --git a/imagebase/button_milk_menu_down b/imagebase/button_milk_menu_down new file mode 100644 index 0000000000000000000000000000000000000000..6f5dbde911942992900e7fbd3a017e620be5c74e GIT binary patch literal 1283 zcmd6m&ubb{5Xax_uDV^2pfrL>(P~324PJuaK`mA-t(Q8>V zxo22!LN;_K=HvI17eZ*C^SOu5-w=J$(lcnU`JmBgM2L~%@%YYsJ`b9v>BHF|jH_ao z82C0-RrOTUv_ZSw{*JTs`~8xE3Scph#}iH@66eWea_0BnB1MrZjMhP=Wsx}=9m__e z;b=CS`eZWc0r~|%ivoebUBLDVg@TMkB6k3}EhTN>LI-$jfE*poh~yvG{_J+UKZ?a7 z0eUzb4v#cWGnGpHy|=r2Uy+yJU1{{t$}N+EHJ3F;ZX_TVSs|Fv8$2XVoX zhBw!&0fV37yb*ayp$t z*LC}Pa1aFp76<_BB*C+__Qcn*`Nf6ozZ@DW^{drt8F;@FCQ7V1DQ8%(*H?{gTVPs%`FJI0X?tn4OT>T3CEYdOzCIYd T^vyne2|3v}RDFL~Ia>1hHd8s6)4ah?AgOUE=QO zq7K;h-fmg z7EfZgLmVa*zdt?0=S1?;MEuU9my)z0f9y*zkJrS+#PwdU_dt@Q800EDbX~7P3h;e_ z@5kuy7&I6Rn@*=Qy}G&@3Wvkw_xl;5Mx#MHJ3CY^mush|r&?v53fZU*dzb||)my0@` z4xe3CP?HN$1!yvv1ZXrGX#}H-q-mM}`C`;aUa!}!%+1YpacB~YY&IJ)gqewSIV6K< zh5)%?TnaPF{QUeM7_MAI;YRV zI@?%pwOTwXEfR_3%uL>%NxMrm{8!^1-=7K_8BrKMk6TU)P0 z>(IH!nM`IIuf&hhsEdn>;vsN7$H&K1uh;3|;6Q`Dkxr*ypyQv%!veffDwSRr3I#Xb zrww(hJQB2CLl---Sgak5M)7S(pE!dt$bSGwu-!n-5!4f68=l*5z~7*j0exp1udhbe Tl@EWH-?5&!w;s>lee&iX7*im( literal 0 HcmV?d00001 diff --git a/imagebase/button_panther_menu b/imagebase/button_panther_menu new file mode 100644 index 0000000000000000000000000000000000000000..cfb488577d687102a89ee0da2dcaa6bb9e48422c GIT binary patch literal 1283 zcmd5*J#11@6h80qK!H+dsUg5nnph2lbm_pT7!+yJ28nid>1JYL7>qKQCJqj64kqH@ zVmo2t&^Bok;=;f}80=75O)UjNN%%?W5AOkf=f>9<(SV z4S%UrA^=`c2GE87HwT~uK$@PO4n(6--^|R6RoUL&ez&^1dj0(ToRY~TMIsTh+wEj9 z7^v6l3Cm!5{ENAWo6RO|ZEaCHoi?njtXu`-7x>QbrdqAaOG`^MH#bL$q7Wykswynx z6K{@r@jKpph7u5@5~NZtmygrfDL9ElXpD45VMk zV7$8BE}fj5P%s#zy}i9l3g7H@y9MCk;UQTp7LjN)8U>IJ%wW72P+$CxOT`zuTrNU` zNkO7IK0a=AI-O*-T4{82lu!%7P6uH&y3fh{p6ko9AycqqpGhbHXoKYh*I{yUQq%+& z(An9UkjZR*2V|dBaWYTD?(QyO+^ANou{uqeot2r z%tE)!a%^l&T+A%j*Vic=4j)lIpZ`2RKd+%N!&E9Y#9TrZrdHF$MvX+w5BBwQjt>qF zM2_F@A0`rsR-sUMCZV%;An^(2D7dz^=0s!oFBL7+2OGKchtC~San^&XUOXQEzPPyf zq0wl(mok}*jAmSc#4se>b2uE=Fggy@N=764kjTHC0RW=CI8$-ffjvTFzO~!!e5=*^ iQm@y4#9}cG-~H$7wbq0P?Oj7vRak2Q5&@FF@2TsW^Yin;cakIz1UmXY0A^*S`9YSXgMf_3 zW1Mr8Wy$^hJ;oTc)&PVM2%%kz3C0*gdyh%YFM*;c*xTE~T1yClEX#)OX_^Ayy+j$xBh-fY^FBuobkb+t)7R+Wdc6N4#;)gMAxc9RDdK1}x+}}_9WYkwF&t0=TY&uI fj0127+yKo_Xsi}jnt^I}00000NkvXXu0mjfEN>XV literal 0 HcmV?d00001 diff --git a/imagebase/checkbox-milk b/imagebase/checkbox-milk new file mode 100644 index 0000000000000000000000000000000000000000..0b26db795b0e819265bbe2d088dc285932fb7c7e GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#DwmvqI7hPnhNnQGJ)SO(Ar`0CPCm%nY{28Xf3^Xma7kMk(9J_QU;FY zFL>r8>G)JBwJQj6{oU^I-rjN|a|{oo!)23?K9v$|O3&{oAN!GaTdXwpaMbSTq_m#L z9qV2@xSV(C=5XRzv1*k@!m|>;rpkE>R~_A0tj8Jhb%I0aMxE1P3Q7rS63Jz(mrWd9 zwlxVb^%%My{1uj+7ykXhekLWY{J3K`gaS^v2_)Opw<~gM&2*C?3^UAu1BVOuUhX~j!WW=ctNjR= zv$L~>NzD38+J}dStAN?u-28o-yuQ9(cO2)zah$Q%+9;)r*4k+88PD_HYi;J{=1i$n zGEz#jx3~8aumR-k>}+ReXUE*#-I;E;Ymy`}S(ce38JZ*+zSoIqG#W-qX|}eujQ^zC z0)zylWm&UP6pj7Z-$K$amj<&!2z%umng6$f77LDJ5x|lIJ;6 z%Kt6y`1lxr{r!DhS5Yo&3*MD%K$gp8j4|~4eVWZCQ52EqIcb`brYR>UC-izf*4Eb8 zu1Dm>8?XuhVFS|l{b_gK_sO!1qoX4pA0KJA+r)8(BK2eY)K)N-2Pn0D>?K zUoS5&lOzcn8yj3*U2%VZ&tNd%{QR6wr^EL4HmcL*2m-X$ zRI61gl?qW5A%q}~V{UJ6@qM4?&%dEksSt)CT9xw#?meI|!wwcBlKwHovD z^V4K0B}Gwupo>B>snu@ZO@4^4JJ3u<8{X&I7$ssI2007*qoM6N<$f{YqmtpET3 literal 0 HcmV?d00001 diff --git a/imagebase/checkboxdown-milk b/imagebase/checkboxdown-milk new file mode 100644 index 0000000000000000000000000000000000000000..cb102564dea306058e00af3e1fdfc5dfaeac1f72 GIT binary patch literal 509 zcmVQ9 z?G{bb07xd2uYULSdd0SFBuRP*o2JQdI0PV_PNOKwUthp+99-9Z2z#E#Xf)zvDs`0hr_hn?Yjv*eV#~?M61;zpU>mEF3aT- zfO@@7JRS$|&ATfA5DJCRG>uZJ1VApAqgX5=2tokk`=zxI0d_Moxw-f+WRjmSle#rh`uh;W;+Htg$i|P@_00000NkvXXu0mjfNCw)g literal 0 HcmV?d00001 diff --git a/imagebase/checkboxdown.bak2 b/imagebase/checkboxdown.bak2 new file mode 100644 index 0000000000000000000000000000000000000000..d6f8ccc1771100acbf9bb882bb3fbf34914c0171 GIT binary patch literal 764 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 BzApd( literal 0 HcmV?d00001 diff --git a/imagebase/combo-shadow b/imagebase/combo-shadow new file mode 100644 index 0000000000000000000000000000000000000000..b7cfedf1e0bdbc08533e6ba6c20817fcd02835a9 GIT binary patch literal 469 zcmV;`0V@89P)CKMDWZOrDgh@wOdn|KyEl4VP_ zrFYI8kI$shXp}I(5a&3<5t28pUhhL~oacDPAG~0Z1NH;H#Bq%iR6PNAuuIJF3y=7T zX~qRcxW`vq#vm&FYKaEZU>qQ2+~5{>_!REeJ;Y#>(?gs_L}8xsIUN2N4`k)2UYY3z zlg{Dm7)ib5#Xd6JDaWi|;;M>O;WTcf4WRpuM%v=^F@{y-quv7Bm(qr1wMJbP@NvDz z^;8v**XjS{}mPk!88lTNyfJ*7AczB$y&usJv-aPuH!q#8RLLjMl`Ovc3%MS0#5<^ zfX9sAE3hxojgJf2A}uh%k1%$UyC#pnF`D7puDLIV+hCdn*E5<|$-h;w4(jw700000 LNkvXXu0mjfpbXBc literal 0 HcmV?d00001 diff --git a/imagebase/deco_glossy b/imagebase/deco_glossy new file mode 100644 index 0000000000000000000000000000000000000000..e27e88a0bfd23b69067bb476da2b559eac458b9f GIT binary patch literal 1911 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E(!2~4hzRg&`z`$Eakt!N_RLe&z?`%2ba4!+U}OwuUhxMgItoY) z0d1g$X+Yc##Ddr~Gh-1{28!hX@opey1!6}aJ_E$RfEXu`0m}3Pu?tiM3y{tN;wm8K yfQn&IVnC5jAht!5VFL1#fVdclK`s~tGz)>P4jf+foPW-OEbw&ob6Mw<&;$T$C>S*W literal 0 HcmV?d00001 diff --git a/imagebase/icon_behind b/imagebase/icon_behind new file mode 100644 index 0000000000000000000000000000000000000000..5e2126f189ac2a260a125deed9a054c32fa5c6e6 GIT binary patch literal 923 zcmeAS@N?(olHy`uVBq!ia0vp^d_c_4!3HF+i2N&IU|>%2ba4!+U}OwuUhxMgItpkS z0<1vOfuYWj48%-mHrWFCT|g{`CJyIv09n;QoCU-zP*GPPJpqVipnNdJh|Gbqd4O~o z5WffF`#|gh#2}4#fS4c<0;=c$;^{!FO;Giy0@M&VYQpi`K!<%INYvBS&t;ucLK6Ui CxEMYF literal 0 HcmV?d00001 diff --git a/imagebase/icon_close b/imagebase/icon_close new file mode 100644 index 0000000000000000000000000000000000000000..e68d91c5944155ad77dea97f34958ec24ca71b22 GIT binary patch literal 923 zcmeAS@N?(olHy`uVBq!ia0vp^d_c_4!3HF+i2N&IU|>%2ba4!+U}OwuUhxMgI%Gj^ zZthWZ$72&?LROTLl5+Ibt5*yl8YYfS3?#=0QvjobgM*L$`0;~*iwhLM3=H4CePiI@ z;9yw0cC9r`4T#3j2oekn3p@J#`*#qNfs>PyVb!WtD4IaxEFc0MaC37rFfl=V0kauh z4TgLk194NxV!VHrpO|k}IQBhHb|Ns9p uz~s%2ba4!+U}OwuUh#)9GBOe< zLpoq0T?<49HjTzWsg*$d5{Q2R@f9Er24WO|O=B)l#TOt>0b)NOehS2^fY=m>;eZ9s zLNE$|%nt}I!*M9z4M?AciDR=7SrbT|6;$yfm?jX7O(U{A$Zu%2ba4!+U}OwuUhxMgI^;n} zNXStT#^n(fToT{Ef5#;S7RRaa%a<>BH8LX0T3J~gWoBk(U}9ndW02hc|Nj~O{rku8 z_wQeZqeqWg!_=eL$jQmc0MZD;jEoR7K^j5$&mSVAE-WnUC%2ba4!+U}OwuUhxMgItr*B z0*uHehJ=J1WnyAtU}R(jW02hc|Np`G-@kthYu2o>hN)+PF+emsJ39kRBZv<&09hkQ cY!nR25Rg7DCha=uxIV~np00i_>zopr0NYq4P5=M^ literal 0 HcmV?d00001 diff --git a/imagebase/icon_shade b/imagebase/icon_shade new file mode 100644 index 0000000000000000000000000000000000000000..721dfd3c7c3d9a9f9afb352a83bb4dafb58ff992 GIT binary patch literal 923 zcmeAS@N?(olHy`uVBq!ia0vp^d_c_4!3HF+i2N&IU|>%2ba4!+U}OwuUhxMgI*5QP z&@CN6401BjfC;Fw7l@5;=>RFf2Bd(3JV1O2nNGuQlD(nJcEn+nc ZVs&ndc(RUoU)~LJqNl5$%Q~loCID3u9Jl}g literal 0 HcmV?d00001 diff --git a/imagebase/icon_sticky b/imagebase/icon_sticky new file mode 100644 index 0000000000000000000000000000000000000000..b59d50b25a310e29a3559b305db92135a4dba39f GIT binary patch literal 923 zcmeAS@N?(olHy`uVBq!ia0vp^d_c_4!3HF+i2N&IU|>%2ba4!+U}OwuUhxMgItp-w z03!|wP*{pU<=z14UpUlZ2x|aE7D6$IO*DuEs(b~-AT|cTCyIfptLq4$K-Q aXdD6tA{^4`hks^)tnqa9b6Mw<&;$V0uNPtf literal 0 HcmV?d00001 diff --git a/imagebase/poof.png b/imagebase/poof.png new file mode 100644 index 0000000000000000000000000000000000000000..990068d5e4b99cc68ec7dae78226528af32e88e2 GIT binary patch literal 57693 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�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 AF8}}l literal 0 HcmV?d00001 diff --git a/imagebase/preview b/imagebase/preview new file mode 100644 index 0000000000000000000000000000000000000000..4bb20c078f78aaf88c8c3160cd101baf0755c9da GIT binary patch literal 1883 zcmZ8iOH89x82$R7Ern7j6iXrUG7u8Nqb(FjG}K@iG!R23xPi%RB*wU5GjXR*+{`Q_ zZrtcfH%N>-O`N#s#+1r{ASSJW=@3%d^6Jp=Dg|24xzGl@$@%a7@4e?c-{ao@fAap= zu*K{&i-=|9-q1Mu*8!`^falS(&%P5eHjNDV?tiM$yk<IUtizH6B84<_V#wE zsHjkTz>&4JHJP8Ezgk#W_$HIdJjFsx$5nVYZL`_F8XX<2ot~Z+pU)?)t*z41(jpxl z9cm1MJsOSr&d$#EL0Km6ra{y2A6;4l21%{=ns!Ec{qycyXDGwm>IECT# zgPxwA$8NV8uqn@lDp%nf;QdW%D$gelH?;jq}YwziZo(wf9ov(qVpb{ILc#zsCPWk9sc znqw`gudAy&g9se82oDDrVdxH#X{0C*91W7Qv~+!?5kVAlb{tS8oVP*8*%&cJnE}on z92_v}sJ_0w{sjznFG-JLD5=?d|;ysmSoukz_WT3w2@%XpD0l9~~Xh+l6T=`xpL6bi&4_m^Pz&%^$ew=){t($Rz$;)I c;2mV23YS-XzWU1a5ymp|&e+h;Z$EteACr+J!2kdN literal 0 HcmV?d00001 diff --git a/imagebase/preview-menu b/imagebase/preview-menu new file mode 100644 index 0000000000000000000000000000000000000000..a16374ea19168905eb302233d11b83f1083e2666 GIT binary patch literal 2603 zcmd5-Sx8)G6h3!m936FZT%y&)B>}4rCP8iLLmpC#sY_yNOi>V8(}#pURfsRe3WZXI zLO@blpKP_wLqe*yw77r&pqcm z>;1CeQnuAU+FwMhxj9*dSnYU%{mgiO^~3w)B9_hEtjza5(X<82Yun)d|7l`k!bck( z9@b`OXA7pLrar|Q_5AsBx69?y+-|oR3#|rZ zyS~1@9sf3{?Ckhc zr%nYxu0fZboSZb@x^?SnQ`3(h1MCs_PUi{C2;DXSHBtwI;^X7v!hQ=pf9xk?Vq$)- zuCD&IqN3t=>eHa;&)c_e+u^C<`t|FQm6b)0#b`9j{{FsNDX5>k<(WA@lR|N+&ZE z5D*}Kett4OJ|5WD*LNO~?KVNcKu>pecBHGTOHd~YENVyr;mY(dq6DZrLXe~vFJ1_v zkdl%jV`F2!iiuZ$e}5I~EevHLYin!r;K2iRMg0T_r^ zaY7as7vtDNCPpeMDoO$6B~wFTq*5u;0qY6~R43lCIp|1aWTYUP`jsGZ$!Ibmkk!>y zRr>(0B1j=dmeHG@o>md21H{6WI{6SwSXh`WEiHX$0w70dXs8bv3^^6kGe%4Y_wt^g zc+dJ}`WYEUm3um;lg?uh$cGJ;PL>He+*?Z2O`9wM67L9-#BZKFc|xF(CJ1f7lW;1C zi;Gh=M*)7obdz2N$~`@&aZZTQ(NRHam?B2NJDLboPcQ2jU95D|dFp0h*o=BGl%azc zfXUF%kkU_C+BBi)S2{X6!ZI>4wCLz)iI0z0;`EY4uzL41YCLmgR6{~Slu-g|YipCt z%*^G74XM%wN|b46Xz*Z6dho3?Cnx8RmX?+)8an+Qr2594J9koATU*1>Q2g7fmevP8 zG<%2t!Je(@!2Le5uwPJ6Fi})g^!>`p%D3mvo!imD-n@D9a#K^&cW}tYsIz4F{b59# zNVN-?))NyGA7hS|oj!efRBLW-HlT@)ARUa?GBy; zyiKgjD2Z{*!(KGPZ%>~-ozBh8_0}lCAX^$zZyy{S{0MdY2IOL)%NJR(aROi@u48pU z)P-rXhPt1D?J@Mr3})-&W5NZ(sfVF90}500000 literal 0 HcmV?d00001 diff --git a/imagebase/progress b/imagebase/progress new file mode 100644 index 0000000000000000000000000000000000000000..ff65b87e86523c8d5271a52740b20885645c5df0 GIT binary patch literal 491 zcmVJQL=(C3~ZA~XFPzz zRH$-nZ|6v{;|&D0eIJpSSMtGxl4ZA>wDxkjlv2zZ)>?UXUB`>MKw=z6Lc}f17!yK} zItJ&QC66%@5q&-%0SNeXI&rClAWJDRMqZ?4St?`*;rV=O6~e5M#u$3P-o07xnAb~~ucg@G;&v+g5hQUE2^21w!OV=!lHnbd#;+rJM;ep%GS2FzP@gr8m{`)oq~I= z;Uk($_hi%1I3(!=L8WPCgx)1L*LHR{s6vE=mG6bX2+>0dXq#B8lf zDs8Nmy0l!U*TJw1z#gT+wKLU7TO~$0B>;TOd_X$l3R9)g!k+##0Gv{UsNb??Hx+{l zB2h^&PM*rwW-*br+Ea16yu7Trw{swqfZ#O4%;$4b0MU^w=c3uNTkiIgYG-F>s-#?1 zbTWpwpV+&ZJg)J}4Kf1LPESwG?GvMg4KEl#Or!*vVZdKYtj=)(?dwQqd2w+81>yi` zRhP&?RAWk}bv~Aq;7JidLCd(-5lU@!bydo4F%rEM^;6m&3;^LxVY(gXbJU2W8runm zZ?jqV-O3>m5bO1O*dD!WDYH1aXx*V!+uGV1d9RG3TV@G*vPVc6?IT+K>KZmsZPV$L z#Fb_1-Sa_OQUa2rv3#Oe=l3>(obUlOw8>;*PKS!IWKx^~Rq&%kl*c>j0*xbR8&Zo4 z`Mm*~F|ZrBN_}qjFv5{XNJV4JNX514CAe<)<>jGC;Bw2BR^hR%TQ26y2ZXu?lmJ8@ z1~1p$4@qj4UDRhQL-bI>FL%9f(ViuC?Xn9$^ z6PNv9uCA_f#Q?{Ns2Ks(Ua}n@AKPl5I4XcF5kOBGAZrR%2Pd(vU{hi{Iy$;ZyFi~3 zVPXRajtUH&v3Dw#agCawot*IhzkAP(QTHzdI|OL?jp!vbra=!t?i3~lG=F;k^Tn@6 Rfq`B4eq+<(P;Gj;o+gDR;&F`C=@M& z!O(U%9HotojmKB@mjGK^Tkm#ucAki$C^(%?7#|;J`a+=q$H&J|E|=?mzyI~}^70D_ zBm*`#H>10|yQ^qPGc`2@X0sWzS}iD*O6YVtaC&+Q>2w;7j*hB6pD!K^244~6hD2&M zo7+~ab2h?e@+3f9Nu^1X}61D%cv z03-wgND$hSH>5!WVki_!k&dSc-CCHOoP?2)5#~0zesT2sedzUipjN9vrBZ>#Vxc#8 zNW%bVMI^G(Xk;Fc7nprH{#L8S0Nrkv8JL)u0IU*=lL3e{G&BUm!^5D_XqY9kMlO@( zcDv2iv$Hb>rd1j;pi-%T-EIey$pnf5);wCXhx1K+2EH<;uolF*oUH$R7OL0wfZNm3%(0!avU(cHeJ& o*u}m$$J&3Jo}MlT0)e-Zme#K`wZTs-fmQnLU0Cvbxc4;n7yrfsQ~&?~ literal 0 HcmV?d00001 diff --git a/imagebase/radio-milk b/imagebase/radio-milk new file mode 100644 index 0000000000000000000000000000000000000000..4999d93cc69f449df4f0f8768facda67479a4b7d GIT binary patch literal 666 zcmV;L0%iS)P)kbwas9gbj-vg({avqVF^uJ+WNy;oWp;yn)GGihrfKeFvsor0)o!zh?yHp zOH1u)wOX2*nwo%zVW=97hT}L+iioOG%1>i}Wm&hG`D3kC8efTU+0n&1M3? zLn-Bf1^~>wwz#->cvUk1EH5w57Yc=60M-D2DwWDy9LMhJ>gtV|nHj=0G#Ct2yY>UXN0#ln0=k0I-lwr*8&9fFKC|O_m6{ zuEQ`4Ff)#ij}b-D1TdLQYQFC;BmfXI9|$4lP8;Gl#$YfQ=R%0d{S!q1kN~iAbaVt= z*YQ8%CjmfqyWQ7u9INT+>1z#fG#bJ8{j3ne7Ow05&gb)mAP9_Nv1ke*a8<0Y zuYc}zI`3`Uexsd0pYQJOCLPD|bX~_~;W*CT_V#ufzzYBn0C4gP+jZS1zVGkna=El& z7&LxW6NsV+8yg$_&CN|Fq7^CSmvhHtSyo0V^-?KSGfne*CX*qhl;(LJI-O2d)3hcL zJ#DpG`xjp0DbOvYR2e`Hz#jl#0ep~B{ygjb3(OY!CXMhe5C8xG07*qoM6N<$f(WA` A*8l(j literal 0 HcmV?d00001 diff --git a/imagebase/radio_down b/imagebase/radio_down new file mode 100644 index 0000000000000000000000000000000000000000..c4fd3320b9a65e6d98f3f7cf6edb1e1f92580240 GIT binary patch literal 1108 zcmbtTPe|Hf7=CqX>XQ8`|KJu0RuFW^!&o5X=CoRu7(>=!2;0R&U2KQ72sZWNJPbB4 zc9(f6+M(E`+hQc`P)iWHB>fpUCY4Oh`H%KKUsGtb(?0lq-@oU3-uHRl?-#j0KC07R z*AkI#?4J7pj}p3C#a~PQ>Fevu1OkDFf8#F@%+JriTU=axBuSF4zrUY)dU^zYcXyX|c6KP6%@!vnCSFfY zPQGjqH3_28XmDw1=@~~-4-5=YXJ;pAG#XMWl~k=(>FDT)*4EZ2l}hD29#3RyYU&k8 zt~8iRrP6}MV!39uT1ltViS5(VQ(_rZEEWZcLZKkWsS}CB&Aq+72taatrl+SDT3cHU z-QC@!)uI3dAc3Gkf;F-Mh66}`zkdZdLBMGZ_xARZ$z-CAjt*iED4kA|&*u~U@bFM% z#b%PxXr!*LE=alEB;Y6#nDu%+84Lyi3Wvi~tJOru9K<*S2EjNZp;G}CGyuS^R;#I{ zrG;d&roUotHk+wXC=i!bjOVxhNWkLw_*m$N3`B{?<3clZW8U80E@Z&qTrStRPa*?E zWM|24w-cO38yXs-gM))65EFP%sZ?llb5mrAJz*m2|HfsZ_4Re^{j(u`yoLS!ed2Qe z08kJ(9F8|Cm5TTw(aMUb&ZQ(cTV7s@t}QArS9>nwgoobAbSh+1c68TU%SV>h*ew`&E9z;-$h!R0aMF4h|+lp^zPT zv}Ok9OQKjT_B5GHs`%$|a;<;z#TviPGp>EwX0v6zUhmrm7Nhw~Zq)t4_7(H7;c@qe IyN^S^0SVv$S^xk5 literal 0 HcmV?d00001 diff --git a/imagebase/radio_down-milk b/imagebase/radio_down-milk new file mode 100644 index 0000000000000000000000000000000000000000..8d634ea5cea44d273135a78587c3d2f9934dc5ac GIT binary patch literal 691 zcmV;k0!;mhP){DHsV!h(K67skCG;40e` zf}JO%U1Sq*Aq)m<2Gll#ZIY3RF~gYmTv$TWmed0m-n;MI^A7iN3D=-dDBKl7JOS|V zJaq)%9q0V}WiDO35kh<@l}f)enaq96K(pEWTC3GU z03LD9PZaTbK>$@%p{gqC^*Sn*3L=pRip3&wxg31ohwu9sjYbrU#T?gl z^C1B1@pydE^E`N-_ph@=s8lLwwORlG&-1Xlx;o_|8jUKh>#m0YkPzaOF}6I*He+mh z{zL%)ga91%`+bDN;VFV)7*prV@4a4+033w?@LsR?W;`Ct`T6-t6SLVYvf1plZbqXK zT-Qx9#!P10_OG?IwY2AX>c+-~#u&p*ad2?(soU+oH%;@caxVI!-EK!M%W}fuFlL2i zS;wtbD-Pf#05AYJcVXJL{nT~clT<1dS5=iJzbXtt5a96eaL{Np1Q8WE=bx`EldkIt zDdj6EWl7VtZ;3>Lq?C%|IOuk}Nkvg=MD%QbfB)p#ZM-0KTS}P+kOJ@rz!v~@&iRka Z+`q7K`Gsa1yq*96002ovPDHLkV1igdG=~5H literal 0 HcmV?d00001 diff --git a/imagebase/rectbutton b/imagebase/rectbutton new file mode 100644 index 0000000000000000000000000000000000000000..33aee9b96e885e7ec9bfe7a13970c5bf1a602444 GIT binary patch literal 3393 zcmc&%%}x_h6#k~2zZSa0pbL^FE=Y(32rreKXlXq$9j_&WT7FY^NYqZB|8i~V}d7kmk&(9Hy#X=ccG$Qd|BabA3E{}s2 z$Y}1l>VaVxn9t6KPh>DSIOy%|?ZI&zcwV!Gz|!sZnx;Y5b#!)iVrgkf(=wTiS11&a zPNzX*^!NAQF5)HDR#sM!&1R9$=LJ{m>FM#hy1FniF>#6d-HN8Brcf%C5Ubbg7#bR( zaPmcssA9TQ&z%Zg&_`~uo~ZdctasUurJUEWWd0TrP)N?N}1@zc^8?RVSQ zPB0ty)wm2W3x~Bs7*^S5e$45(}2(1{0uj^|}uxI0S2JYv7t>*;Yur zIKeEmlw@)H>IIb6auRX~Y;l5@a$M+-!y%sd;V2eM_)*!1VHpH%AqE$&t3Gg= zzjLmH?kl-2#16=!D@I5_He)feO;3D$$_ZNV^W=nTc@^yz9UntHD!hG zicJ|QA&LAWDoII993LMGiqU4n5G4wOctCsb)8Zy>sHKqs8OcpKC5g#rcXsv@dV70e zCjE2lFgK3EBuAQN*Y+cNE9qp>k&`GrVJv=Gr1EV-PbQP7RLY23^hzgONe>#s;UmfF z+;mvF@0851esg3)N?(FXrY*K@IdCa!8DH=2?#9N(1{UV#FfcHHj*bqsLP#+Y)wpPM zbr(Q8ZPr$k@=+Pf%gZ>ZRKWQ1*)u&o?bT{EDX%W4^Bp%nmbPspl}cf9lK%N<#+#X$ n@i<2O@U9wfmcJ{<$HznLkDnhr&VB2D!I+~%W108Q-n{(-dh#Yn literal 0 HcmV?d00001 diff --git a/imagebase/roundFrame b/imagebase/roundFrame new file mode 100644 index 0000000000000000000000000000000000000000..0c03c009c81a24a0bff4d2e5c335e112c96119cb GIT binary patch literal 2554 zcmb_eT})eL7(VB;6xu@v@>59pDJ0Oe;v(F*u?&ogo5W->?UqnNg9-6cZf`ZvoK~x~-eR$wN>5L(HX4m?gTWw+qL>uS`TP6(%HH1I#Lmvn&zqZ@_hYfxkkjd$ zObWz5j7=f*dcDOtIXS+iytJ@S56?TUc%OvLaj$p6!-G-vSV^`(mFOa_T9|P%xAs5y(+1Z zlUiC@ib3{4O-;=?x7!`XHr_+-`am=el1DIw3)Be?j$8;9BqIJH7C4TaznGDc;m6LL zHJME3v6x76b91=Azkg08EGjDUL0J>YY&P340lbM}A8bY5ccWCw{&4suDz znM+G>2u_~HV||E;!=oM|a!ITnywq^$s`T+Vh*d0NlY?BWQxmwb#{vFa42@$#LS^`6 zdwZKDPOr-P_*{TPI#n!UlY?9mF60lWe=@2;DID@4fesx;Ok$G*CGWn33O}^Ex*7wq z7tS&uahs1rB{3vo5*wWZcRxC;R`5U|@X_@2^eFmS6IPRrAO@r#F29)ViA+r zgM)(~5<_in=v{0hKSm-EKayJq$BDlwJ&Ib!>dH2@#}479biJ^92SzPd$x zIrt0=3^>vC>oYSmYd~0p%AbpB!Edn?LVR94M!r@-`1{7j#shTwq3Y`Dl#eKK{C4Z} U8>Ux$pYXl$%?k}TUw`-VpKm~wCIA2c literal 0 HcmV?d00001 diff --git a/imagebase/sbIslider_mid b/imagebase/sbIslider_mid new file mode 100644 index 0000000000000000000000000000000000000000..5cf1ecf9c3ab1f14aaa2bc1dd5b9dccc965ced31 GIT binary patch literal 1348 zcmeAS@N?(olHy`uVBq!ia0vp@K&-&Q1SH*drygctVCD97aSW+oWMp9d|BI1_hr6Vt z)W^q%o16R1n>VXgt&*0OR#jCM6BDzsu>orO_3IZWCnrcdF#xEJkw|sKC}SYO-cj?g zgurO{VF?tV5DmiRKX#i?MQLC!ss%WB!^mE$mM;_5^SUSXF7^Zko2RRv%Q~loCIHF+ B9F710 literal 0 HcmV?d00001 diff --git a/imagebase/sb_subadd b/imagebase/sb_subadd new file mode 100644 index 0000000000000000000000000000000000000000..306da73e36a13aa5a0b158dd087286ecc34ec785 GIT binary patch literal 708 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)1SFjfCgm|OFm-#nIEGX(GBz;P|7HCB`}ebF z&tAQH_3`7!FJHdAeft*3U}IyGmX>B=VPRro5)u-Uk&yvuCkBkF!yZbb;etI}?r?~l TTy7-z5G3pA>gTe~DWM4frBozE literal 0 HcmV?d00001 diff --git a/imagebase/sb_subadd-milk b/imagebase/sb_subadd-milk new file mode 100644 index 0000000000000000000000000000000000000000..8f6a76f7db285801ac9a441ad573ab065a27e623 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp@KrFz)1|-ie{%Q%N*pj^6T^Rm@;DWu&Cj&(|3p^r= z85p?vL6~vUPv)gSLG}_)Usv|4T=Gn^<{djyHGx7go-U3d8t2bW@aAhU;Bb+@^FPWq zgqyLv_u7#OdRK04n5lm$%3I8ZCGD6*^1XZ3X>Gd~iwFpIa4@Wj5?&dX8Ks)`%tu%C wF35>FqA}bE0_p{FU5)iYhPa0oudh>FVdQ&MBb@0Bqw!n*aa+ literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_btm b/imagebase/sbgroove_btm new file mode 100644 index 0000000000000000000000000000000000000000..6c7c6ba3eb152d5714481505ef51d0b05a5cc78c GIT binary patch literal 388 zcmW+yOHPAO6y?!Jr67e8I+26{=??4y)IhW`X^iOtT!5pF96NId4vlkNKqt&t0!c@v zl8~k(G<*szKRxYD-hJ=hbMDEx@9klFD+w0@!!Xk1&U!rFI6TiHe_6lp3`6cG*7fX# zkSpS}WImsB9H(g-Aw(2Kp63-s>GgVoAPk2?mSvM9F-`M0o~9{^rYWncYTFhWQI=&G zhCvXlRzKiS0C5~QO_S&6vRoHMk!9K0DeAgLzb^lfDU<==g&_n8Q0jKOolfU8oX2s7 z0Xi5A(2b%9N|Ge?`~BT+M=3oV4(Q~04n?4JG#X(E$8lg~yWL^~kRS|;;GrCkFJYAU zzQ0&3P`j?XTrRQGe!m9~!iHhkwyo}@C_I)@xaGL+{g3m QvsBSzCic|&zIl562ie}RtN;K2 literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_btm-milk b/imagebase/sbgroove_btm-milk new file mode 100644 index 0000000000000000000000000000000000000000..1629f4de0ad74ab208ca3c8da79ed89123615ffb GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mj;0wgOd`6mJ?rX+877l!}s{b%+Ad7K3vk;M!Q z-25QSIO!+zQjq!*PhVH|t6cI-8Y=6|pE&}BN<3X0LpZL-p5DlJFo41B;rn}G9LGwBvUL&n!s{27HBX-NfB43Cl8>A`W<+;YVk*RZy4>%2}LzIp99Q{v===TDZI7?_!U{`Qsmb)w>_ Trl6oyp#2P{ literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_mid b/imagebase/sbgroove_mid new file mode 100644 index 0000000000000000000000000000000000000000..e1dee0a2b90bf5ab60b6dc6f3789891763a57f74 GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp@KrF+-1SCzF7l|@3uw;9>IEGX(GA6Lh|IJuXP{75- zB`7G!$jHde&CS8VAs`^Y$;rvX!y_y#%*x8j$H&La%nZ^_44|qyCLkcjQlJ{@sRMeJ zSpO2G?(g5fKYsln&VB!g@W)SvpG5ih-_L&_by$P&H_PuIEI)qz`UN%#Fp^kSFjff@lG% z!QnnsBY~-kD0QIVL)D3sH$du$^Di)biE|a%7dRjLFx2GvhD|C RHkV3}R!>(ymvv4FO#m(fJV*cl literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_mid-milk b/imagebase/sbgroove_mid-milk new file mode 100644 index 0000000000000000000000000000000000000000..30044763a4659cc1f3ee77187654dc2ef2d8054b GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp@KrF+-1|)YSnmPd~wj^(N7l!{JxM1({$v_d#0*}aI z1_o|^5N4e8lX)pnkiEpy*OmP$mpqf4+DTP037}Awr;B5V#p$<`4)PsQ;BZNIc)tE` z>5a)NGcWg6-N>1>PdJc;y>0E*l5!6xP1Z>P*{v!&tUZ!cj1wOpw0y|-x>K+*Qpb2> zS7Nify^--5zfbL_W3M`YDmb!cS?%F(3QBr&-*x$9zhd>Q`+x7o&ik<@d)xljA6{pX boLwa^!fD2r<*xVw=n4i;S3j3^P6T literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_top b/imagebase/sbgroove_top new file mode 100644 index 0000000000000000000000000000000000000000..0424c8cfce66b76bfc8a2d225ff73f99637e4a1e GIT binary patch literal 388 zcmXAlzfOZt6vnybmO{&)7Q!M)r}_$=)j+f{X^b%rb@2gw0B1Mfz$b9ixtlX9Lz@;{ zIuUKt5TyJGpx>2~aPA@e?)QC%=d0O9H&e!>}z)75yckzo4tAAIC43$Pj4Ox zIUyf4`TDQLViAU6S(cin>AFrSZME19p64;N+ijZXx$C-;B(2x$)oK;Tah7EuR8<`g zhmPY|mQ__1KOT>hB$?0WzVFv{Ez5Gh-vmL3GL2uz zv%T;crm_qnx!3E#9TN(wklgLQp-r(`6N?anWX)f|0LU~=yut^};PYYddYjuAxrsBi J-_P!!{s7*Hd-MPR literal 0 HcmV?d00001 diff --git a/imagebase/sbgroove_top-milk b/imagebase/sbgroove_top-milk new file mode 100644 index 0000000000000000000000000000000000000000..2850aadb19d9ecd0192460462495156c2797ef68 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x0wg>1_qqTnrX+877l!}s{b%+Ad7K3vk;M!Q z-25QSIO!+zQlKDviKnkC`&BM^CMCTsyw9%!h3Y+B978y+ho1B1b_`@-c=&$K>x}_Z zax}u^p8j92`;#?n(o_vi*P^|Bt=(seW*u$G4Ej(~JpJ_D7~3iLs`64_FIl#9Ewh)* z*&LJJt8-;_a=%V(&75`P^~w_|MuD3?m6@63+_+sC* gN@D4v|Nc^Oimz0KwC;cD0y>4k)78&qol`;+0Dx6kKmY&$ literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_btm b/imagebase/sbslider_btm new file mode 100644 index 0000000000000000000000000000000000000000..0e5e76793c71ee93d855ce82371406301e14ce84 GIT binary patch literal 439 zcmX|7Jx{_=6g{P-ZHf?6;zC!#0yIH}CQK;BiYCOU18({Uh{naqfz9aTf2e~4ql*)Z zvNl2>u7oec03-wm*xFkXPjc_ex%Zs=?t2d>MI$IhBmlv}p?*rI8-mEY`Rn>K0x
    r_(_?oxW#lwc3Ya7;?Yg*OtqrC!*;DGSHymaOkbAD9UrWTz=%JnaN~c#^dpY zYuuqX5oo|-u>i+$a2yA*SnM^CNK~oEP$HP7dE96;&YI2U6&XlO9}y0R5sgO8WHMRF x<#OMo{WlRI)a&(KcO}W^^KH5D;~IZcsg$+pZgNns`sfRW5l(1}@!SziWX)vL&t&CC>S|xv6<249-QVi6yBi3gww4 z844j8sS56%z5(x3RP%reXL-6fhHzZhJ-L^wDS*M@;p0&0L&p|$+*`5M{l&vMEg9Ke zN>X=@&eG3H*sm1${d}9%2jAnf%ejTw82DNr^*VhtyzQW}+54k3Tldn#4=cn@`UK23 zYCrlX)5;<3N>kS4X-nM}U&xS|Ry}iBh+S`vOT7svJ6o@7v3B|C+A}BF<=iXtDm&+O vtTVD-6aIUK%;S&Qr)DS$>Y9oQJ>bq;8?<@nbP0l+XkKK*MfH literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_btm_shd b/imagebase/sbslider_btm_shd new file mode 100644 index 0000000000000000000000000000000000000000..066653ae90e84402cb212196b7f85b50cbf46203 GIT binary patch literal 545 zcmY+BNlHUO6h-UX#%SztpiY#4C{A2M}t>DoL@C zusjPx&HhrM)(_1_K?eW; literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_mid b/imagebase/sbslider_mid new file mode 100644 index 0000000000000000000000000000000000000000..5cd2f776590040da0ed7d9c5f8ebabaf74fe2f05 GIT binary patch literal 1348 zcmeH{zfJ-{5XN`mj$D94La40l@g=LU@Ye1Atobym;9h{fUQ%v|6p; z`R8z`>;oXIV+d9}ieh9-0L+`p^Bh2??@x!o6Db5;1y{xxQZZq!dAIZV95GDtRo%cQ zA+!aS>Q-H4Gd&5TR4V2iD;}x3z(WnDx}L{Dy-PqOFhLBxt^QOFzxhn!dA-m$Kr_UH zcjuufgW^s@gCQUZUsqAsfZz5nbhQh-(xLXxja4Po-2eXZLJqKhd%iD!-@nhd>BsZY Q%cx`7I;J! zGca%qgD@k*tT_@uLG}_)Usv|4T=EQ>Y>6kFx`0BmC9V-A&iT2ysd*&~&PAz-C8;S2 z<(VZJ3LzP(3hti10q;{(^MDHHdAc};Se$-4(O0NhfyXVr>D~qB3eWeff*$5a9d{S6 zxqNPhXk^Rxzb8z5?amj=9WQ)fyEW_#kFoMG4=+w*<)u@mr%Fx{Ui{9_pD`fRg{47& zi9yMUBe9_T+(bR=Ra^5W&AM~9PIBenn)%DWz5AZ+X@9brU+WPS22G59Bv&mg%{*f22WQ%mvv4FO#qo_ Bb3_0D literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_top b/imagebase/sbslider_top new file mode 100644 index 0000000000000000000000000000000000000000..1682308ae2c68f3e9911864703e961bc0f73f066 GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mj;1|%;R9G7BXV65|WaSW+oWGrUv`Ns$pMgd)2 zUAx}DfB)|P|Nl?EfB)_wEiL`5tgOrpSrJ@QV`Jmw)2C18{Qmu$;m40346LlI3|w4X z3`|T+45Ff{z|YUmz{khOAR;2dz`?=6 z02Eh#`}QqUWMrh$o;`bZfo<~g@_P00<3~}D0yZ`_1_=oXuuUM_1O){dn3sR)z#G*?Ck8o&H~v0 nbU#=jNHNGjn5`g9j~+eJS>BQydpb>HHpu^;u6{1-oD!M-5N literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_top-milk b/imagebase/sbslider_top-milk new file mode 100644 index 0000000000000000000000000000000000000000..aa6ae7c9d9e3212b8a1f6a147f4052d9151c9f7c GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mj;0wgOd`6mJ?rX+877l!}s{b%+Ad7K3vk;M!Q z+`=Ht$S`Y;1W0{}r>`sfRW5l(2HAC*b-RES|xv6<249-QVi6yBi3gww4 z844j8sS56%z5(x3RP%reS9!WPhHzZhJ?qGQFo5B}$N$y0ooCHDoN+m(WlPKy**i6i zs_c(WsDI(T^W=$=cwxk%B{F3*u1m4k#XnI0@v*RQLq}zSGLwKqqhGxV$Lq$>>RA2u zw|V=Yc_cC1{g|~YKpux^_taXueq!_*I4J2gA>xrQdqqr*~TO*!nL# zu`s}c=Tw};qgfVj9sUJR=5b~F!PqyWX4*<4MkAA1EWOX>=AF?mU7@)objdyqpsN`? MUHx3vIVCg!0HH;8kN^Mx literal 0 HcmV?d00001 diff --git a/imagebase/sbslider_top_shd b/imagebase/sbslider_top_shd new file mode 100644 index 0000000000000000000000000000000000000000..ba62b8e7cb2f19483b4a53ee03ea83380a711724 GIT binary patch literal 545 zcmYk2xk>|36o&7(Wx*&yOdvMFAc%#Q*3l6&O%U+`tbGEpw6pagEcHdwSXgT50uj-| z1vL77GIz**WayGTh$OkE$gNGzECO8@O?VDI0_+o%+l_`agy97%cF$f zDnSb_%3g1KK%@Bj;N1BGZ4e-%2=1V^2O5xjw2?w|sL z*h#?#w88PF!O`vX33hQ${|&6x0|hIv2v+k17E~eF8K^`N8CcJujm`Rl=xpjE@2coAkmjD0& literal 0 HcmV?d00001 diff --git a/imagebase/sliderarrow b/imagebase/sliderarrow new file mode 100644 index 0000000000000000000000000000000000000000..8d49a65714145987833fe03db5ef4b55d474ad12 GIT binary patch literal 863 zcmY*X&#Mwq7`@}2@mFeM(xNu{%3j(cY9THJDSW&{cto@bTC{1=qIIp`?k!!k3t-ag{>x79k4B^A~}l=@^R6jMMop-l7Zl$9L~J-#OnmbMo-$FzCPHXN(045Au&_ z$GqruW6fPVc*PjMQOMtW{8~}2@`0rki^a=6pYMsw<$CHk&Rs=OT!8*JaKFX-8TQI@ zxztsU$Fmm-g`TI=>08NUlBuftm$2P#<=NG4x9`;Jb)Rk9UkGuNbDlsJHW&;9NP>}F zl9*|l4EKAO`zn}GWOr{i8@5<17?Ekfrr0T_^Lo8zZVZqvsmKP7%2ultBO(DLkXT5{ z;DlM0CEf%cWKjnSWT;PMmnsxc0wRz-de=0KQ6rp4B*FrLfViNnG^C;ku#gKPjK^a~ z1;|GC%xE-;SlJM=NE3-n!mEa1{6cUJwd?SUUS;K!A({=q*qtW;Pg>O(c zK(Iw~L~nOXE|*i`KZ5qA5{bkie$pxwz9QKa1WRJyzPK>6kKeqcxNvZkKfV9#_z$p3 B8%zKI literal 0 HcmV?d00001 diff --git a/imagebase/sliderarrow-milk b/imagebase/sliderarrow-milk new file mode 100644 index 0000000000000000000000000000000000000000..4c25763e624b5484ac688f21800316f9f50a5d91 GIT binary patch literal 656 zcmV;B0&o3^P)cFJ7WNh?jzncK7e`9=3!8VMozU z!cKUMoi>FnOB-Yxu-B|J@4YU&Vrlfdd@sKbzt7?K75q7OfEq9Zlz>S<0|Vd$_yYVI zFN-T#0q(7=tUO*=SeS1#8qHFvR2~clr@dY;-rwIp*xK5919X9JfDEhzzL(lW%Uq%!~VRv_T-)?Mdyf{8Seg}M2KmgodUtfQ|w6yd{N-4Nuq?BTAZmt=I z;qAS>y^p|m1vHkIm!GVzu0B&r2_bG|0kGCmtyUXpnhv_%?k5S%v|6osDWx>VV6FWp zXpBKhDO;`9JTT({VZB~&=6Qa(q?AHRc@1>Vk>@$}dc6sR9xxFELAfXjoO5`dhjWgr z`p!A5wG>5xF@_)r%D{vN43i`|Etktx-}kZBBBi_$w$_s8IZ2Y70z(ft@Av!h)YMef zIfqgTA;dLp=N!fuj4|~4{TMixz*!VU2U(Wci;D}gEaN|EqbNE6&J@7m;i0b8YIiG@ zN^^W+tZIy*D2hw%PN%cIxw-ig=qbPg^62R3M;M0Q^z?K?2qDJc7#a?THj1L{cDwyb zYyAN@QGf$7t+noSI_z9$=LJUStD}Dn=;yd-_oFfeY00000RE?fvX?df`_; zc;q`Lj-5HS*=$Zc{N0CswCJBK&lmQNLVowRbDPbVHV;4a%^&~b(4h-w_x^ckfiIK0 z?z-#m7cN{l{`T8%fBEB&Ki*^9+1WYp`RJpME}JvJwnfau;|TjSd%khcc^JKo!$>*y zXZwDz{IfSNX3mQ(E}buZ=+L2yCr_UI*Gn(G^p*Tqyvcp{-S^kG-g@i)#~yoZ?|}y% z*euSO4vIMd#-L>BOy=ZDg~F%3*opC(GJSA1pFWL0&Bo_y_N(FXrt^F6z4tcHKmYvZ zsi&UWy#D&@|5(Of<+GmD2OoU!_s>52>`xzm{PE4XbLTeKU3XpaYf~bjcXxL;mo8np z49|J`U9FkZ*Em11bG}ZNkI5NUQ}drb*(Pse{`t=F#Ngyg*uG`oW{mfP4?ftu_~MJ3 zC!Tm>bH^Qb{N?GVpFX$C_}p{Pef{pc@7|m}dv+z$wB=}Tme+sPhYufKgUz#j_~C~_ z59aG+`G6Nk6I@d!9uND(^PgPtRKvEdx!B1&$N8k=qDeW}=iGQ=jd9;_!ws8z@4a{P z%rnn?gWt}RPd<77Liojd?zv|*BG-LdfMDb1Fyrv)1M}n~0m(PbPU0yJ7T?5-$;8Bx zZJp0{Ou1%l7cX8ss1;srzRionH?hV}G`aK6JE`N#!Tinc3opFzy`|HK-Jvpj-ff&eX|2YsCmW2o zGEba1v3dFBm%qQe+y`IV+uPe5JLVU|e+dN5Kx5=nCMKEZNSiatD{nN+y-+%wq?mO?ibMnZMBWo;UJ6Hgc$Rp%j zkrmZxsEG8mhtY8wdkqsj%TKz^_19m&LUL|%%sQ$wEeLm<_>7MpJ^BfZFMIsWTU)vF zp~=i;Ts`%1_l-B+IPIb(K#k>OymWm%))wh_&*Yjved`3N&N=8vzqYGt>k=?^0?>!YV#W5e+2mxpu^b{5jJb$I!~zZ!jT6jUQ; z@<A%O!I3T&RvuW~a55JeZ#MH{ zXbWeIgyE8p;39EskBezD=-I~|9q#9pU`ZpHV+q`SbkAG}OtK0y7cXIc;wxB=7G?~$ z`|80_jv8w|r2|mD8PlR+-T<-ch_h3cjyoSUc&fj6HO>bvS5hB$BV7I-iGnrtES3&I$eMT?26oaUt3amD8q zZ8O(_(&)bZ-8uWl~;qC#q+^eeBtvOfL9LMmv^JH2*w+t#AQ zk#^dcEqU|JH!tH1$4BJb=7LXbJ2yLQ{>v~QaaYS(+*~7U%H*-ZQ`lh2A}Wo;b}^K6~$PI5K#HBRDJ&)kgj=g+S$yNYxdbRU>&i~vM%J0Y=MQP8PV zrw+bg8uM?A**s3;PHo)H6@~Zan{Pg7TE(X=V)?V$>IYL-@#@7-!_-;>)H->Kk@L0J zUR(Xu!%rODCd-pQ4!AmrT&@`Z)>m87wX@!-h$ZqXz=@rr;9G9FWxXEwO_7wicet1X@bPaSG z#82M%%jt0NoAox9r~G`($;4WVdgQe(V;o|fQ1csaym38D=K9#(y56ZseJcuz95F`$ zq-JR1eErxI#_nM=$K?e3W+!;teY{SNobo7;CgR!nvg1^|(;%)oZQiy_{_5sa((CVNBeEz$Bd-t*GjDeg@|lY@ zmQ17g^A!^poZ$3oDi|gXR=!@Z79<8X?bVfyT~n%$Jzh3>)S)i9ZNjXJPchlHq2b5{OQsNZMb!v|UKf6_q`5f$M0|or1M*8xdvP-t%)+|Y z%!{qwv^WPv4W8~pxco4J&%9@@!`eM$#`sS#4wVB$);smgnKPT)Z@+zQMC55jB{RWX zD^piNhe5*4ZKKa7Bm)YjHSoj>9f0kH>4RTtSKclYhyFYv6 z(O)lR@A!WK+$(kaN{jxi1lPh|L#_q)wcxZ_HpZPxb^!lti?|kz`8+uLqTF%M`PQDV l#^;gX|Bb^*?QmZD^Z7p=`QdN>pa&0s`;mwK_^qG+^4|##0Y3l$ literal 0 HcmV?d00001 diff --git a/imagebase/tab-jaguar b/imagebase/tab-jaguar new file mode 100644 index 0000000000000000000000000000000000000000..4510fdc115002b10be58a8eff88b91f498d6b1c1 GIT binary patch literal 9287 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 XCN_4QB5wkJ00000NkvXXu0mjfak2u> literal 0 HcmV?d00001 diff --git a/kickermenu-3.3/Makefile.am b/kickermenu-3.3/Makefile.am new file mode 100644 index 0000000..4d219df --- /dev/null +++ b/kickermenu-3.3/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = b_menu_panelapplet.la + +b_menu_panelapplet_la_SOURCES = menuapplet.cpp menuapplet.skel + +noinst_HEADERS = menuapplet.h + +b_menu_panelapplet_la_METASOURCES = AUTO + +lnkdir = $(kde_datadir)/kicker/applets +lnk_DATA = b_menuapplet.desktop + +EXTRA_DIST = $(lnk_DATA) + +b_menu_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +b_menu_panelapplet_la_LIBADD = $(LIB_KDEUI) + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kmenuapplet.pot diff --git a/kickermenu-3.3/b_menuapplet.desktop b/kickermenu-3.3/b_menuapplet.desktop new file mode 100644 index 0000000..6328532 --- /dev/null +++ b/kickermenu-3.3/b_menuapplet.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Baghira Menu +Comment=Applet embedding standalone menubars (Patched baghira version) + +Icon=menu + +X-KDE-Library=b_menu_panelapplet +X-KDE-UniqueApplet=true diff --git a/kickermenu-3.3/menuapplet.cpp b/kickermenu-3.3/menuapplet.cpp new file mode 100644 index 0000000..205ed63 --- /dev/null +++ b/kickermenu-3.3/menuapplet.cpp @@ -0,0 +1,623 @@ +/***************************************************************** + +Copyright (c) 2002 Siegfried Nijssen +Copyright (c) 2003 Lubos Lunak + +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 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 _MENUAPPLET_CPP_ + +#include // avoid X11 #define's + +#include "menuapplet.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + + KMenuBar from KDE3.1 and older won't work very well with this applet. + This is because QMenuBar tries really hard to keep its preffered size, + se even if the X window for the menubar has the size enforced by this + applet, Qt thinks it has the size Qt wants. This results in parts + of the menubar not being repainted. Also, old KMenuBar always forced + with to be the width of the screen, so even if the menubar has only + few entries, this applet will still indicate the menubar doesn't + fit completely in it. There's no way to fix this, besides upgrading + to KDE3.2. + +*/ + + +extern Time qt_x_time; + +extern "C" +{ + KPanelApplet* init( QWidget* parent_P, const QString& configFile_P ) + { + KGlobal::locale()->insertCatalogue("kmenuapplet"); + return new KickerMenuApplet::Applet( configFile_P, parent_P ); + } +} + +namespace KickerMenuApplet +{ + +static const int MOVE_DIFF = 100; // size increment for left/right menu moving +static const int GROW_WIDTH = 10; // width of grow buttons + +const long SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask + | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask + | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask; + +Applet::Applet( const QString& configFile_P, QWidget* parent_P ) + : KPanelApplet( configFile_P, Stretch, 0, parent_P, "menuapplet" ), + DCOPObject( "menuapplet" ), + module( NULL ), + active_menu( NULL ), + grow_indicator_left( this, LeftArrow ), + grow_indicator_right( this, RightArrow ), + selection( NULL ), + selection_watcher( NULL ), + desktop_menu( false ) + { + // for windowindicator + setBackgroundOrigin(AncestorOrigin); + QIntDict(97); //allowing 97 entries - should be enough, if not - who cares: just a label and hashtables are slightly faster than lists... + windowIndicator = new QMenuBar(this); + windowList = new KWindowListMenu(windowIndicator); + connect(windowList, SIGNAL(aboutToShow()), this, SLOT(initPopup())); + windowIndicator->insertItem( "KDE", windowList, 0); + windowIndicator->move(0,-1); + windowIndicator->show(); + windowIndicator->adjustSize(); + windowIndicator->setFixedSize(windowIndicator->size()); + //============== + dcopclient.registerAs( "menuapplet", false ); + grow_indicator_left.hide(); + grow_indicator_right.hide(); + connect( &grow_indicator_left, SIGNAL( clicked()), SLOT( growClicked())); + connect( &grow_indicator_right, SIGNAL( clicked()), SLOT( growClicked())); + // toolbarAppearanceChanged(int) is sent when changing macstyle + connect( kapp, SIGNAL( toolbarAppearanceChanged( int )), + this, SLOT( readSettings())); + claimSelection(); + readSettings(); + } + +Applet::~Applet() + { + lostSelection(); // release all menu's before really loosing the selection + /*if (windowIndicator) */delete windowIndicator; + delete selection; + delete selection_watcher; + delete module; + KGlobal::locale()->removeCatalogue("kmenuapplet"); + } + +void Applet::initPopup() + // helper to allow connecting windowlist activation to reinit - must be, as the list doesn't update itself + { + windowList->init(); + } + +void Applet::windowRemoved(WId w_P) + // another helping slot + { + windowTitleDict.setAutoDelete(TRUE); + windowTitleDict.remove(w_P); + } + +void Applet::windowAdded( WId w_P ) + { + QString* title; + NETWinInfo info( qt_xdisplay(), w_P, qt_xrootwin(), NET::WMWindowType); + XClassHint classHint; + if (!windowTitleDict[w_P] && w_P != qt_xrootwin() && XGetClassHint( qt_xdisplay(), w_P, &classHint ) ) + { + // much better way to get a nice name! + title = new QString( classHint.res_class ); + XFree( classHint.res_name ); + XFree( classHint.res_class ); + windowTitleDict.insert(w_P, title); + } + else + { //fallback + // for windowindicator + if (!windowTitleDict[w_P] && w_P != qt_xrootwin()){ + KWin::WindowInfo tmpInfo = KWin::windowInfo( w_P, NET::WMName ); + //generate title: + title = new QString(tmpInfo.name()); + if (title->contains("K3b")){ + // hack, weil herr trueg zwar ein erstklassiges brennprogramm schreiben, sich aber leider nicht an windowmanager konventionen halten kan... ;) + *title = "K3b"; + } + else if (title->contains("GIMP")){ + *title = "GIMP"; //seems as if the title is "The Gimp" in english versions?!? + } + else { + if (title->contains(" - ")) + *title = title->section(" - ", -1, -1); // get rid of application subinfo + if (title->contains(" ")) + *title = title->section(" ", 0, 0); // get rid of version numbers + } + // add title + windowTitleDict.insert(w_P, title); + } + } + // ========= + if( info.windowType() != NET::TopMenu ) + return; +// kdDebug() << "embedding:" << w_P << endl; + Window transient_for = KWin::transientFor( w_P ); + if( transient_for == None ) + return; + MenuEmbed* embed; + if( transient_for == qt_xrootwin()) + embed = new MenuEmbed( transient_for, true, this ); + else + { + KWin::WindowInfo info2 = KWin::windowInfo( transient_for, NET::WMWindowType ); + embed = new MenuEmbed( transient_for, + info2.windowType( SUPPORTED_WINDOW_TYPES ) == NET::Desktop, this ); + } + + embed->hide(); + embed->move( 0, 0 ); + embed->resize(size()); + embed->embed( w_P ); + //embed->setMinimumSize( size()); + embed->setMinimumSize( 0,0); + if( embed->embeddedWinId() == None ) + { + delete embed; + return; + } + embed->installEventFilter( this ); + menus.append( embed ); + // in case the app mapped its menu after its mainwindow, check which menu should be shown + activeWindowChanged( module->activeWindow()); + } + +// - if the active window has its topmenu -> show the menu +// - if desktop menu is enabled (i.e. explicitly in kdesktop) : +// - show it +// - otherwise show nothing +void Applet::activeWindowChanged( WId w_P ) + { +// kdDebug() << "active:" << w_P << endl; + QFont tmpFont; + for( WId window = w_P; + window != None; + window = tryTransientFor( window )) + { + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + { + if( window == (*it)->mainWindow()) + { + tmpFont = (*it)->font(); + tmpFont.setBold(true); + windowIndicator->setFont(tmpFont); + QString *newTitle = windowTitleDict[w_P]; + newTitle ? + windowIndicator->changeItem(0, *newTitle): + windowIndicator->changeItem(0, "KDE"); + windowIndicator->setMinimumSize(0, windowIndicator->height()); + windowIndicator->setMaximumSize(20000, windowIndicator->height()); + windowIndicator->adjustSize(); + windowIndicator->setFixedSize(windowIndicator->size()); + (*it)->setFixedSize(width() - windowIndicator->width()-1, height()); + activateMenu( *it ); + return; + } + } + } +// kdDebug() << "no active" << endl; + // No menu for active window found - if desktop menu + // (in kdesktoprc) is enabled, use kdesktop's menu instead of none. + bool try_desktop = desktop_menu; + if( !try_desktop && w_P != None ) + { // also use the desktop menu if the active window is desktop + KWin::WindowInfo info = KWin::windowInfo( w_P, NET::WMWindowType ); + if( info.windowType( SUPPORTED_WINDOW_TYPES ) == NET::Desktop ) + try_desktop = true; + } + if( try_desktop ) + { + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + { + if( (*it)->isDesktopMenu()) + { + tmpFont = (*it)->font(); + tmpFont.setBold(true); + windowIndicator->setFont(tmpFont); + QString *newTitle = windowTitleDict[w_P]; + newTitle ? + windowIndicator->changeItem(0, *newTitle): + windowIndicator->changeItem(0, "KDE"); + windowIndicator->setMinimumSize(0, windowIndicator->height()); + windowIndicator->setMaximumSize(20000, windowIndicator->height()); + windowIndicator->adjustSize(); + windowIndicator->setFixedSize(windowIndicator->size()); + (*it)->setFixedSize(width() - windowIndicator->width()-1, height()); + activateMenu( *it ); + return; + } + } + } + QString *newTitle = windowTitleDict[w_P]; + newTitle ? + windowIndicator->changeItem(0, *newTitle): + windowIndicator->changeItem(0, "KDE"); + windowIndicator->setMinimumSize(0, windowIndicator->height()); + windowIndicator->setMaximumSize(20000, windowIndicator->height()); + windowIndicator->adjustSize(); + windowIndicator->setFixedSize(windowIndicator->size()); + if (active_menu) active_menu->setFixedSize(width() - windowIndicator->width()-1, height()); + activateMenu( NULL ); + } + +void Applet::activateMenu( MenuEmbed* embed_P ) + { + if( embed_P != active_menu ) + { +// kdDebug() << "activate:" << embed_P << endl; + if( active_menu != NULL ){ + active_menu->hide(); + } + active_menu = embed_P; + if( active_menu != NULL ){ + active_menu->show(); + } + } + moveMenu( NULL ); + } + +bool Applet::eventFilter( QObject* obj_P, QEvent* ev_P ) + { + if( ev_P->type() == QEvent::Resize && obj_P == active_menu ) + moveMenu( NULL ); + return false; + } + +void Applet::growClicked() + { + moveMenu( static_cast< const QWidget* >( sender())); + } + +void Applet::updateGrowIndicators() + { +// kdDebug() << "ACT:" << active_menu << ":" << ( active_menu ? active_menu->x() : -1 ) << ":" << ( active_menu ? active_menu->x() + active_menu->width() : -1 ) << ":" << width() << endl; + if( active_menu != NULL && active_menu->x() < 0 ) + { + grow_indicator_left.raise(); + grow_indicator_left.setGeometry( 0, 0, GROW_WIDTH, height()); + grow_indicator_left.show(); + } + else + grow_indicator_left.hide(); + if( active_menu != NULL && active_menu->x() + active_menu->width() > width()) + { + grow_indicator_right.raise(); + grow_indicator_right.setGeometry( width() - GROW_WIDTH, 0, GROW_WIDTH, height()); + grow_indicator_right.show(); + } + else + grow_indicator_right.hide(); + } + +void Applet::moveMenu( const QWidget* indicator_P ) + { + if( active_menu == NULL ) + { + updateGrowIndicators(); + return; + } + if( indicator_P == NULL ) // no indicator -> reset pos + active_menu->move( 0 + windowIndicator->width() + 1, 0 ); + else if( indicator_P == &grow_indicator_right ) // -> move left + { // negative x + if( windowIndicator->width() + 1 + active_menu->width() + active_menu->x() > width()) + { + int newx = windowIndicator->width() + 1 + active_menu->x() - MOVE_DIFF; + if( active_menu->width() + newx < width()) + newx = windowIndicator->width() + 1 + width() - active_menu->width(); + active_menu->move( newx, 0 ); + } + } + else // indicator_P == &grow_indicator_left // -> move right + { + if( active_menu->x() < 0 ) + { + int newx = active_menu->x() + windowIndicator->width() + 1 + MOVE_DIFF; + newx = (( newx - MOVE_DIFF + 1 ) / MOVE_DIFF ) * MOVE_DIFF; + active_menu->move( newx, 0 ); + } + } + updateGrowIndicators(); + } + +// If there's no menu for the window, try finding menu for its mainwindow +// (where the window's WM_TRANSIENT_FOR property points). +// If the window is modal (_NET_WM_STATE_MODAL), stop. +WId Applet::tryTransientFor( WId w_P ) + { +/* KWin::WindowInfo info = KWin::windowInfo( w_P, NET::WMState ); + if( info.state() & NET::Modal ) + return None;*/ + WId ret = KWin::transientFor( w_P ); + if( ret == qt_xrootwin()) + ret = None; + return ret; + } + +void Applet::menuLost( MenuEmbed* embed ) + { + for( QValueList< MenuEmbed* >::Iterator it = menus.begin(); + it != menus.end(); + ++it ) + { + if( *it == embed ) + { + menus.remove( it ); + embed->deleteLater(); +// kdDebug() << "deleting:" << (*it)->mainWindow() << endl; + if( embed == active_menu ) + { + active_menu = NULL; + updateGrowIndicators(); + // trigger selecting new active menu + activeWindowChanged( module->activeWindow()); + } + return; + } + } + } + +void Applet::resizeEvent( QResizeEvent* ev ) + { + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + (*it)->setFixedSize( width() - windowIndicator->width()-1 ,height()); + KPanelApplet::resizeEvent( ev ); + moveMenu( NULL ); + } + +void Applet::paletteChange(const QPalette & /* oldPalette */) + { + if( active_menu != NULL ) + { + active_menu->hide(); + active_menu->show(); + } + } + +void Applet::claimSelection() + { + assert( selection == NULL ); + selection = new KSelectionOwner( makeSelectionAtom(), DefaultScreen( qt_xdisplay())); +// force taking the selection, but don't kill previous owner + if( selection->claim( true, false )) + { + delete selection_watcher; + selection_watcher = NULL; + connect( selection, SIGNAL( lostOwnership()), SLOT( lostSelection())); + module = new KWinModule; + connect( module, SIGNAL( windowAdded( WId )), this, SLOT( windowAdded( WId ))); + connect( module, SIGNAL( windowRemoved( WId )), this, SLOT( windowRemoved( WId ))); + connect( module, SIGNAL( activeWindowChanged( WId )), + this, SLOT( activeWindowChanged( WId ))); + QValueList< WId > windows = module->windows(); + for( QValueList< WId >::ConstIterator it = windows.begin(); + it != windows.end(); + ++it ) + windowAdded( *it ); + activeWindowChanged( module->activeWindow()); + } + else + lostSelection(); + } + +void Applet::lostSelection() + { + if( selection == NULL ) + return; +// kdDebug() << "lost selection" << endl; + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + delete (*it); // delete all MenuEmbed's = release all menus + menus.clear(); + active_menu = NULL; + if( selection_watcher == NULL ) + { + selection_watcher = new KSelectionWatcher( makeSelectionAtom(), DefaultScreen( qt_xdisplay())); + connect( selection_watcher, SIGNAL( lostOwner()), this, SLOT( claimSelection())); + } + delete module; + module = NULL; + selection->deleteLater(); + selection = NULL; + // selection_watcher stays + } + +void Applet::readSettings() + { + KConfig cfg( "kdesktoprc", true ); + cfg.setGroup( "Menubar" ); + desktop_menu = cfg.readBoolEntry( "ShowMenubar", false ); + cfg.setGroup( "KDE" ); + if( cfg.readBoolEntry( "macStyle", false ) || desktop_menu ) + QToolTip::remove( this ); + else + QToolTip::add( this, i18n( + "You do not appear to have enabled the standalone menubar; " + "enable it in the Behavior control module for desktop." )); + if( !isDisabled() && active_menu == NULL ) + activeWindowChanged( module->activeWindow()); //enforce desktop_menu + } + +void Applet::configure() + { + readSettings(); + } + +int Applet::widthForHeight( int ) const + { + return 200; // we're stretch applet + } + +int Applet::heightForWidth( int ) const + { + // *shrug* running this applet in vertical mode is a bad idea anyway + return 50; + } + +static Atom selection_atom = None; +static Atom msg_type_atom = None; + +static +void initAtoms() + { + char nm[ 100 ]; + sprintf( nm, "_KDE_TOPMENU_OWNER_S%d", DefaultScreen( qt_xdisplay())); + char nm2[] = "_KDE_TOPMENU_MINSIZE"; + char* names[ 2 ] = { nm, nm2 }; + Atom atoms[ 2 ]; + XInternAtoms( qt_xdisplay(), names, 2, False, atoms ); + selection_atom = atoms[ 0 ]; + msg_type_atom = atoms[ 1 ]; + } + +Atom Applet::makeSelectionAtom() + { + if( selection_atom == None ) + initAtoms(); + return selection_atom; + } + +MenuEmbed::MenuEmbed( WId mainwindow_P, bool desktop_P, + QWidget* parent_P, const char* name_P ) + : QXEmbed( parent_P, name_P ), + main_window( mainwindow_P ), + desktop( desktop_P ) + { + setAutoDelete( false ); + setBackgroundOrigin(AncestorOrigin); + } + +void MenuEmbed::windowChanged( WId w_P ) + { + if( w_P == None ) + static_cast< Applet* >( parent())->menuLost( this ); + } + +bool MenuEmbed::x11Event( XEvent* ev_P ) + { + if( ev_P->type == ConfigureRequest + && ev_P->xconfigurerequest.window == embeddedWinId() + && ev_P->xconfigurerequest.value_mask & ( CWWidth | CWHeight )) + { + XConfigureRequestEvent& ev = ev_P->xconfigurerequest; + QSize new_size = size(); + if( ev.value_mask & CWWidth ) + new_size.setWidth( ev.width ); + if( ev.value_mask & CWHeight ) + new_size.setHeight( ev.height ); + // resize when the embedded window resizes (still obey min size) +// kdDebug() << "RES:" << embeddedWinId() << ":" << ev.width << ":" << ev.height << endl; + if( ev.width != width() || ev.height != height()) + resize( ev.width, ev.height ); + sendSyntheticConfigureNotifyEvent(); +// int x, y; +// unsigned int w, h, d, b; +// Window root; +// XGetGeometry( qt_xdisplay(), embeddedWinId(), &root, &x, &y, &w, &h, &b, &d ); +// kdDebug() << "RES3:" << width() << ":" << height() << ":" << w << ":" << h << endl; + return true; + } + return QXEmbed::x11Event( ev_P ); + } + +void MenuEmbed::sendSyntheticConfigureNotifyEvent() +{ + QPoint globalPos = mapToGlobal(QPoint(0,0)); + if (embeddedWinId()) { + XConfigureEvent c; + memset(&c, 0, sizeof(c)); + c.type = ConfigureNotify; + c.display = qt_xdisplay(); + c.send_event = True; + c.event = embeddedWinId(); + c.window = winId(); + c.x = globalPos.x(); + c.y = globalPos.y(); + c.width = width(); + c.height = height(); + c.border_width = 0; + c.above = None; + c.override_redirect = 0; + XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c ); + } +} + +void MenuEmbed::setMinimumSize( int w, int h ) +{ + QXEmbed::setMinimumSize( w, h ); + // tell the menubar also the allowed minimum size + // the applet won't allow resizing to smaller size + if( embeddedWinId() != None ) + { +// kdDebug() << "RES2:" << width() << ":" << height() << ":" << minimumWidth() << ":" << minimumHeight() << endl; + XEvent ev; + ev.xclient.display = qt_xdisplay(); + ev.xclient.type = ClientMessage; + ev.xclient.window = embeddedWinId(); + assert( msg_type_atom != None ); + ev.xclient.message_type = msg_type_atom; + ev.xclient.format = 32; + ev.xclient.data.l[0] = qt_x_time; + ev.xclient.data.l[1] = minimumWidth(); + ev.xclient.data.l[2] = minimumHeight(); + ev.xclient.data.l[3] = 0; + ev.xclient.data.l[4] = 0; + XSendEvent( qt_xdisplay(), embeddedWinId(), False, NoEventMask, &ev ); + } +} + +} // namespace + +#include "menuapplet.moc" diff --git a/kickermenu-3.3/menuapplet.h b/kickermenu-3.3/menuapplet.h new file mode 100644 index 0000000..7825bd2 --- /dev/null +++ b/kickermenu-3.3/menuapplet.h @@ -0,0 +1,135 @@ +/***************************************************************** + +Copyright (c) 2002 Siegfried Nijssen +Copyright (c) 2003 Lubos Lunak + +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 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 _MENUAPPLET_H_ +#define _MENUAPPLET_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace KickerMenuApplet +{ + +class MenuEmbed; + +class Applet : public KPanelApplet, public DCOPObject + { + Q_OBJECT + K_DCOP + k_dcop: + ASYNC configure(); + public: + Applet( const QString& configFile, QWidget *parent ); + virtual ~Applet(); + virtual int widthForHeight( int height ) const; + virtual int heightForWidth( int width ) const; + virtual bool eventFilter( QObject* obj, QEvent* ev ); + void menuLost( MenuEmbed* embed ); + protected: + virtual void resizeEvent( QResizeEvent* ); + virtual void paletteChange(const QPalette& ); + private slots: + void windowAdded( WId w ); + void activeWindowChanged( WId w ); + void lostSelection(); + void readSettings(); + void claimSelection(); + void growClicked(); + // to show current active window (not necessary equal to the menubar) + void initPopup(); + void windowRemoved(WId w); + private: + bool isDisabled() const; // does it own the manager selection? + void updateGrowIndicators(); + void moveMenu( const QWidget* indicator ); + WId tryTransientFor( WId w ); + void activateMenu( MenuEmbed* embed ); + static Atom makeSelectionAtom(); + KWinModule* module; + QValueList< MenuEmbed* > menus; + MenuEmbed* active_menu; + KArrowButton grow_indicator_left, grow_indicator_right; + KSelectionOwner* selection; + KSelectionWatcher* selection_watcher; + bool desktop_menu; + DCOPClient dcopclient; + // to show current active window (not necessary equal to the menubar) + QMenuBar *windowIndicator; + QIntDictwindowTitleDict; + KWindowListMenu* windowList; + }; + +class MenuEmbed + : public QXEmbed + { + Q_OBJECT + public: + MenuEmbed( WId mainwindow, bool desktop, + QWidget* parent = NULL, const char* name = NULL ); + WId mainWindow() const; + bool isDesktopMenu() const; + virtual void setMinimumSize( int w, int h ); + void setMinimumSize( const QSize& s ) { setMinimumSize( s.width(), s.height()); } + protected: + virtual void windowChanged( WId w ); + virtual bool x11Event( XEvent* ev ); + private: + void sendSyntheticConfigureNotifyEvent(); + WId main_window; + bool desktop; + }; + +inline +bool Applet::isDisabled() const + { + assert( ( selection == NULL && selection_watcher != NULL ) + || ( selection != NULL && selection_watcher == NULL )); + return selection == NULL; + } + +inline +WId MenuEmbed::mainWindow() const + { + return main_window; + } + +inline +bool MenuEmbed::isDesktopMenu() const + { + return desktop; + } + +} // namespace + +#endif diff --git a/kickermenu/Makefile.am b/kickermenu/Makefile.am new file mode 100644 index 0000000..5ab6cd5 --- /dev/null +++ b/kickermenu/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = b_menu_panelapplet.la + +b_menu_panelapplet_la_SOURCES = menuapplet.cpp menuapplet.skel + +noinst_HEADERS = menuapplet.h + +b_menu_panelapplet_la_METASOURCES = AUTO + +b_menu_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +b_menu_panelapplet_la_LIBADD = $(LIB_KDEUI) + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kmenuapplet.pot diff --git a/kickermenu/configure.in.in b/kickermenu/configure.in.in new file mode 100644 index 0000000..72f8843 --- /dev/null +++ b/kickermenu/configure.in.in @@ -0,0 +1,2 @@ +AM_CONDITIONAL( HAVE_3_4, test $(kde-config --version | grep "KDE:" | cut -d" " -f2 | cut -d"." -f2) -gt 3 ) + diff --git a/kickermenu/menuapplet.cpp b/kickermenu/menuapplet.cpp new file mode 100644 index 0000000..97e35de --- /dev/null +++ b/kickermenu/menuapplet.cpp @@ -0,0 +1,704 @@ +/***************************************************************** + +Copyright (c) 2002 Siegfried Nijssen +Copyright (c) 2003 Lubos Lunak + +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 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 _MENUAPPLET_CPP_ + +#include +#include +#include +#include +#include +#include +#include // avoid X11 #define's +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "menuapplet.h" + +/* + + KMenuBar from KDE3.1 and older won't work very well with this applet. + This is because QMenuBar tries really hard to keep its preffered size, + se even if the X window for the menubar has the size enforced by this + applet, Qt thinks it has the size Qt wants. This results in parts + of the menubar not being repainted. Also, old KMenuBar always forced + with to be the width of the screen, so even if the menubar has only + few entries, this applet will still indicate the menubar doesn't + fit completely in it. There's no way to fix this, besides upgrading + to KDE3.2. + +*/ + + +extern Time qt_x_time; + +extern "C" +{ + KDE_EXPORT KPanelApplet* init( QWidget* parent_P, const QString& configFile_P ) + { + KGlobal::locale()->insertCatalogue("kmenuapplet"); + return new KickerMenuApplet::Applet( configFile_P, parent_P ); + } +} + + + +namespace KickerMenuApplet +{ + +static int _maxWidth; +static const int MOVE_DIFF = 100; // size increment for left/right menu moving +static const int GROW_WIDTH = 10; // width of grow buttons + +const long SUPPORTED_WINDOW_TYPES = NET::NormalMask | NET::DesktopMask | NET::DockMask + | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask + | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask; + +Applet::Applet( const QString& configFile_P, QWidget* parent_P ) : KPanelApplet( configFile_P, Normal, 0, parent_P, "menuapplet" ), DCOPObject( "menuapplet" ), module( NULL ), active_menu( NULL ), selection( NULL ), selection_watcher( NULL ), desktop_menu( false ), topEdgeOffset( 0 ) +{ + KConfig config(QDir::homeDirPath() + "/.qt/baghirarc"); + config.setGroup("Menubar"); + _maxWidth = config.readNumEntry("Width", QDesktopWidget().availableGeometry().width()); + _menuMover = new QLabel("<<|>>", this ); + _menuMover->adjustSize(); + _menuMover->setFixedSize(_menuMover->size()); + _menuMover->move(_maxWidth - _menuMover->width(),0); + _menuMover->hide(); + _menuMover->installEventFilter(this); + windowIndicator = new QMenuBar(this); + windowIndicator->installEventFilter(this); + windowIndicator->setBackgroundOrigin(QWidget::WidgetOrigin); + windowIndicator->setLineWidth(0); + windowList = new KWindowListMenu(windowIndicator); + connect(windowList, SIGNAL(aboutToShow()), this, SLOT(initPopup())); + windowIndicator->insertItem( "KDE", windowList, 0); + QFont tmpFont = KGlobalSettings::menuFont(); + windowIndicator->setFont(tmpFont); +// windowIndicator->adjustSize(); +// int tmpHeight = windowIndicator->height(); + tmpFont.setBold(true); + windowIndicator->setFont(tmpFont); + windowIndicator->adjustSize(); +// windowIndicator->setMargin((tmpHeight-windowIndicator->height())); + windowIndicator->move(0,0); + windowIndicator->show(); + windowIndicator->setFixedWidth(windowIndicator->width() + 1); + //============== + // toolbarAppearanceChanged(int) is sent when changing macstyle + connect( kapp, SIGNAL( toolbarAppearanceChanged( int )), this, SLOT( readSettings())); + connect( kapp, SIGNAL( kdisplayFontChanged()), this, SLOT( fontChanged())); + claimSelection(); + readSettings(); + updateTopEdgeOffset(); +} + +Applet::~Applet() +{ + lostSelection(); // release all menu's before really loosing the selection + delete selection; + delete selection_watcher; + delete module; + KGlobal::locale()->removeCatalogue("kmenuapplet"); +} + +void Applet::fontChanged() +{ + if (!windowIndicator) + return; + QFont tmpFont = KGlobalSettings::menuFont(); +// windowIndicator->setFont(tmpFont); +// windowIndicator->adjustSize(); +// int tmpHeight = windowIndicator->height(); + tmpFont.setBold(true); + windowIndicator->setFont(tmpFont); + windowIndicator->adjustSize(); +// windowIndicator->setMargin((tmpHeight-windowIndicator->height())/2); +} + +void Applet::showWindowList() +{ + /* + if (windowIndicator->isItemActive(0)) + windowList->close(); + else + */ + windowIndicator->activateItemAt(0); +} + +void Applet::initPopup() +// helper to allow connecting windowlist activation to reinit - must be, as the list doesn't update itself +{ + windowList->init(); +} + +void Applet::moveMenu() +{ + if (!wannaMove) + return; + active_menu->move( active_menu->x() + menuDX, active_menu->y()); + QTimer::singleShot(100, this, SLOT(moveMenu())); +} + +bool Applet::eventFilter(QObject *o, QEvent *ev) + { + if (o == _menuMover) + { + if (ev->type() == QEvent::MouseButtonPress && active_menu) + { + if (((QMouseEvent*)ev)->x() < _menuMover->width()/2) + { + menuDX = -5; + wannaMove = true; + active_menu->move( active_menu->x() - 5, active_menu->y()); + QTimer::singleShot(200, this, SLOT(moveMenu())); + } + else + { + menuDX = 5; + wannaMove = true; + active_menu->move( active_menu->x() + 5, active_menu->y()); + QTimer::singleShot(200, this, SLOT(moveMenu())); + } + return false; + } + if (ev->type() == QEvent::MouseButtonRelease) + { + wannaMove = false; + return false; + } + return false; + } +#if 0 + // to fake menu consistency - doesn't work to good so far + if (o == windowIndicator && ev->type() == QEvent::MouseMove && + (((QMouseEvent*)ev)->x() == windowIndicator->width()-1) && + windowIndicator->isItemActive( 0 )) + // moving out to the right + { +// windowIndicator->activateItemAt ( -1 ); + windowList->close(); + return FALSE; + } + else +// #endif + if (ev->type() == QEvent::PaletteChange) + { // this is necessary as the background origin is set from somwhere outside - it's no kmenubar - so we set it back + QWidget *w = (QWidget*)o; +// #if 0 + if (w == windowIndicator) +// #endif + { + if (w->backgroundOrigin() != QWidget::WidgetOrigin) + { + w->blockSignals(TRUE); // to avoid loops + w->setBackgroundOrigin(QWidget::WidgetOrigin); + w->blockSignals(FALSE); + } + } +// #if 0 + else if (w->backgroundOrigin() != QWidget::ParentOrigin) + { + w->blockSignals(TRUE); + w->setBackgroundOrigin(QWidget::ParentOrigin); + w->blockSignals(FALSE); + } + return FALSE; + } +#endif + return FALSE; + } + +void Applet::windowAdded( WId w_P ) +{ + NETWinInfo info( qt_xdisplay(), w_P, qt_xrootwin(), NET::WMWindowType ); + Window transient_for = KWin::transientFor( w_P ); + + if( info.windowType( SUPPORTED_WINDOW_TYPES ) != NET::TopMenu ) + return; +// kdDebug() << "embedding:" << w_P << endl; + if( transient_for == None ) + return; + + MenuEmbed* embed; + if( transient_for == qt_xrootwin()) + { + embed = new MenuEmbed( transient_for, true, this ); + } + else + { + KWin::WindowInfo info2 = KWin::windowInfo( transient_for, NET::WMWindowType | NET::WMName ); + embed = new MenuEmbed( transient_for, info2.windowType( SUPPORTED_WINDOW_TYPES ) == NET::Desktop, this ); + // ========= NAMING =================== + QString title(info2.name()); + XClassHint classHint; + if (XGetClassHint( qt_xdisplay(), w_P, &classHint ) ) + { // much better way to get a nice name! + QString name( classHint.res_class ); + if (name.contains("SDL_App")) + goto titlejump; // mainly for scummvm apps - jumps to netwm caption parsing + XFree( classHint.res_name ); + XFree( classHint.res_class ); + int i = title.findRev( name, -1, FALSE ); + if (i > -1) + { + int j = title.find(' ',i); + title = title.mid(i, (j>-1)?j-i:title.length()-i); // use intersection between X and netwm and expand to netwm name, using nice formated netwm name ;) + } + else +// *title = name; // use straight x class hint - better in most cases + goto titlejump; // jumps to netwm caption parsing + if (title == "Kdesktop" || title == "kicker") title ="KDE"; //just for promotion ;) - it's the same menu anyway + } + else // netwm caption parsing, used as fallback - probably never reached + { + // exception - hopefully never necessary + if (title.contains("K3b")) //hack, working around strange k3b naming policy - shouldn't be reached ever in best case (catched upwards) + title = "K3b"; + else if (title.contains("GIMP")) //seems as if the title is "The Gimp" in english versions?!? + title = "GIMP"; + // exceptions done here + else + { + titlejump: // real parsing + if (title.contains(" - ")) + { + title = title.section(" - ", -1, -1); // get rid of application subinfo + if (title.contains(" ")) + title = title.section(" ", -1, -1); // get rid of prefixes + } + else if (title.contains(" ")) + title = title.section(" ", 0, 0); // get rid of version number etc. + } + } + embed->title = title; + } + // ========= NAMING DONE ============== +#if 0 + embed->installEventFilter(this); +#endif + embed->hide(); + embed->move( 0, -topEdgeOffset ); + embed->resize( embed->width(), height() + topEdgeOffset ); + embed->embed( w_P ); + if( embed->embeddedWinId() == None ) + { + delete embed; + return; + } + menus.append( embed ); + activeWindowChanged( module->activeWindow()); + windowIndicator->raise(); +// in case the app mapped its menu after its mainwindow, check which menu should be shown +} + +// - if the active window has its topmenu -> show the menu +// - if desktop menu is enabled (i.e. explicitly in kdesktop) : +// - show it +// - otherwise show nothing +void Applet::activeWindowChanged( WId w_P ) +{ +// kdDebug() << "active:" << w_P << endl; + for( WId window = w_P; + window != None; + window = tryTransientFor( window )) + { + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + { + if( window == (*it)->mainWindow()) + { + windowIndicator->changeItem(0, (*it)->title); + windowIndicator->setMinimumWidth(0);//, windowIndicator->height()); + windowIndicator->setMaximumWidth(20000);//, windowIndicator->height()); + windowIndicator->adjustSize(); +// windowIndicator->resize(windowIndicator->width() + 1, height()); + windowIndicator->setFixedWidth(windowIndicator->width() + 1);//, oldheight + topEdgeOffset); + activateMenu( *it ); + if (active_menu->width() + windowIndicator->width() > _maxWidth) + { +// _menuMover->move(width() - _menuMover->width(),0); + _menuMover->raise(); + _menuMover->show(); + } + else + _menuMover->hide(); + return; + } + } + } +// kdDebug() << "no active" << endl; + // No menu for active window found - if desktop menu + // (in kdesktoprc) is enabled, use kdesktop's menu instead of none. +#if 0 + bool try_desktop = desktop_menu; + if( !try_desktop && w_P != None ) + { // also use the desktop menu if the active window is desktop + KWin::WindowInfo info = KWin::windowInfo( w_P, NET::WMWindowType ); + if( info.windowType( SUPPORTED_WINDOW_TYPES ) == NET::Desktop ) + try_desktop = true; + } + if( try_desktop ) +#endif + { + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + { + if( (*it)->isDesktopMenu()) + { + windowIndicator->changeItem(0, "KDE"); + windowIndicator->setMinimumWidth(0);//, windowIndicator->height()); + windowIndicator->setMaximumWidth(20000);//, windowIndicator->height()); + windowIndicator->adjustSize(); +// windowIndicator->resize(windowIndicator->width() + 1, height()); + windowIndicator->setFixedWidth(windowIndicator->width() + 1);//, oldheight + topEdgeOffset); + activateMenu( *it ); + if (active_menu->width() + windowIndicator->width() > _maxWidth) + { +// _menuMover->move(width() - _menuMover->width(),0); + _menuMover->raise(); + _menuMover->show(); + } + else + _menuMover->hide(); + return; + } + } + } + windowIndicator->changeItem(0, "KDE"); + windowIndicator->setMinimumWidth(0);//, windowIndicator->height()); + windowIndicator->setMaximumWidth(20000);//, windowIndicator->height()); + windowIndicator->adjustSize(); +// windowIndicator->resize(windowIndicator->width() + 1, height()); + windowIndicator->setFixedWidth(windowIndicator->width() + 1);//, oldheight + topEdgeOffset); + activateMenu( NULL ); +} + +void Applet::activateMenu( MenuEmbed* embed_P ) +{ + if( embed_P != active_menu ) + { +// kdDebug() << "activate:" << embed_P << endl; + if( active_menu != NULL ) + active_menu->hide(); + active_menu = embed_P; + } + if( active_menu != NULL) + { + active_menu->setMinimumSize( width() - windowIndicator->width(), height() + topEdgeOffset ); + active_menu->move(windowIndicator->width(),-topEdgeOffset); + active_menu->show(); + if (!active_menu->isDesktopMenu()) + emit updateLayout(); + } +} + +void Applet::updateMenuGeometry( MenuEmbed* embed ) +{ + if( embed == active_menu ) + emit updateLayout(); +} + +// If there's no menu for the window, try finding menu for its mainwindow +// (where the window's WM_TRANSIENT_FOR property points). +// If the window is modal (_NET_WM_STATE_MODAL), stop. +WId Applet::tryTransientFor( WId w_P ) + { + /*KWin::WindowInfo info = KWin::windowInfo( w_P, NET::WMState ); + if( info.state() & NET::Modal ) + return None;*/ + WId ret = KWin::transientFor( w_P ); + if( ret == qt_xrootwin()) + ret = None; + return ret; + } + +void Applet::menuLost( MenuEmbed* embed ) +{ + for( QValueList< MenuEmbed* >::Iterator it = menus.begin(); it != menus.end(); ++it ) + { + if( *it == embed ) + { + menus.remove( it ); + embed->deleteLater(); + // kdDebug() << "deleting:" << (*it)->mainWindow() << endl; + if( embed == active_menu ) + { + active_menu = NULL; + // trigger selecting new active menu + activeWindowChanged( module->activeWindow()); + } + return; + } + } +} + +void Applet::positionChange( Position ) +{ + updateTopEdgeOffset(); +} + +// Detect mouse movement at the top screen edge also if the menubar +// has a popup open - in such case, Qt has a grab, and this avoids +// Kicker's FittsLawFrame. Therefore move the menubar a bit higher, +// so that it actually is positioned exactly at the screen edge +// (i.e. at a negative y coordinate within this applet, due to +// Kicker's frame). +void Applet::updateTopEdgeOffset() +{ + QPoint p = topLevelWidget()->mapToGlobal( QPoint( 0, 0 )); + if( p.y() <= 2 ) // 2 = work also when running in appletproxy + topEdgeOffset = mapToGlobal( QPoint( 0, 0 )).y() - p.y(); + else + topEdgeOffset = 0; + if( active_menu != NULL ) + active_menu->move( active_menu->x(), -topEdgeOffset ); +// if (windowIndicator) +// { +// windowIndicator->resize(windowIndicator->width(), height() + topEdgeOffset ); +// windowIndicator->move(windowIndicator->x(), -topEdgeOffset ); +// } +} + +void Applet::paletteChange(const QPalette & /* oldPalette */) +{ + if( active_menu != NULL ) + { + active_menu->hide(); + active_menu->show(); + } +} + +void Applet::claimSelection() +{ + assert( selection == NULL ); + selection = new KSelectionOwner( makeSelectionAtom(), DefaultScreen( qt_xdisplay())); +// force taking the selection, but don't kill previous owner + if( selection->claim( true, false )) + { + delete selection_watcher; + selection_watcher = NULL; + connect( selection, SIGNAL( lostOwnership()), SLOT( lostSelection())); + module = new KWinModule; + connect( module, SIGNAL( windowAdded( WId )), this, SLOT( windowAdded( WId ))); + connect( module, SIGNAL( activeWindowChanged( WId )), this, SLOT( activeWindowChanged( WId ))); + QValueList< WId > windows = module->windows(); + for( QValueList< WId >::ConstIterator it = windows.begin(); it != windows.end(); ++it ) + windowAdded( *it ); + activeWindowChanged( module->activeWindow()); + } + else + lostSelection(); +} + +void Applet::lostSelection() + { + if( selection == NULL ) + return; +// kdDebug() << "lost selection" << endl; + for( QValueList< MenuEmbed* >::ConstIterator it = menus.begin(); + it != menus.end(); + ++it ) + delete (*it); // delete all MenuEmbed's = release all menus + menus.clear(); + active_menu = NULL; + if( selection_watcher == NULL ) + { + selection_watcher = new KSelectionWatcher( makeSelectionAtom(), DefaultScreen( qt_xdisplay())); + connect( selection_watcher, SIGNAL( lostOwner()), this, SLOT( claimSelection())); + } + delete module; + module = NULL; + selection->deleteLater(); + selection = NULL; + // selection_watcher stays + } + +void Applet::readSettings() + { + KConfig cfg( "kdesktoprc", true ); + cfg.setGroup( "Menubar" ); + desktop_menu = cfg.readBoolEntry( "ShowMenubar", false ); + cfg.setGroup( "KDE" ); + if( cfg.readBoolEntry( "macStyle", false ) || desktop_menu ) + QToolTip::remove( this ); + else + QToolTip::add( this, i18n( + "You do not appear to have enabled the standalone menubar; " + "enable it in the Behavior control module for desktop." )); + if( !isDisabled() && active_menu == NULL ) + activeWindowChanged( module->activeWindow()); //enforce desktop_menu + } + +void Applet::configure() + { + readSettings(); + } + +int Applet::widthForHeight( int ) const + { + if (active_menu) + { + int w = active_menu->width() + windowIndicator->width(); + if (w > _maxWidth) w = _maxWidth; + return w; + } + return 0; // we're stretch applet + } + +int Applet::heightForWidth( int ) const + { + // *shrug* running this applet in vertical mode is a bad idea anyway + return 50; + } + +static Atom selection_atom = None; +static Atom msg_type_atom = None; + +static +void initAtoms() + { + char nm[ 100 ]; + sprintf( nm, "_KDE_TOPMENU_OWNER_S%d", DefaultScreen( qt_xdisplay())); + char nm2[] = "_KDE_TOPMENU_MINSIZE"; + char* names[ 2 ] = { nm, nm2 }; + Atom atoms[ 2 ]; + XInternAtoms( qt_xdisplay(), names, 2, False, atoms ); + selection_atom = atoms[ 0 ]; + msg_type_atom = atoms[ 1 ]; + } + +Atom Applet::makeSelectionAtom() + { + if( selection_atom == None ) + initAtoms(); + return selection_atom; + } + +MenuEmbed::MenuEmbed( WId mainwindow_P, bool desktop_P, + QWidget* parent_P, const char* name_P ) + : QXEmbed( parent_P, name_P ), + main_window( mainwindow_P ), + desktop( desktop_P ) + { + setAutoDelete( false ); + } + +void MenuEmbed::windowChanged( WId w_P ) + { + if( w_P == None ) + static_cast< Applet* >( parent())->menuLost( this ); + } + +bool MenuEmbed::x11Event( XEvent* ev_P ) +{ + if( ev_P->type == ConfigureRequest && + ev_P->xconfigurerequest.window == embeddedWinId() + && ev_P->xconfigurerequest.value_mask & ( CWWidth | CWHeight )) + { + XConfigureRequestEvent& ev = ev_P->xconfigurerequest; + QSize new_size = size(); + if( ev.value_mask & CWWidth ) + new_size.setWidth( ev.width ); + if( ev.value_mask & CWHeight ) + new_size.setHeight( ev.height ); + // resize when the embedded window resizes (still obey min size) +// kdDebug() << "RES:" << embeddedWinId() << ":" << ev.width << ":" << ev.height << endl; + if( ev.width != width() || ev.height != height()) + { + resize( ev.width > _maxWidth ? _maxWidth : ev.width, ev.height ); + static_cast< Applet* >( parent())->updateMenuGeometry( this ); +// windowIndicator->resize(windowIndicator->width(), ev.height); + } + sendSyntheticConfigureNotifyEvent(); +// int x, y; +// unsigned int w, h, d, b; +// Window root; +// XGetGeometry( qt_xdisplay(), embeddedWinId(), &root, &x, &y, &w, &h, &b, &d ); +// kdDebug() << "RES3:" << width() << ":" << height() << ":" << w << ":" << h << endl; + return true; + } + return QXEmbed::x11Event( ev_P ); +} + +void MenuEmbed::sendSyntheticConfigureNotifyEvent() +{ + QPoint globalPos = mapToGlobal(QPoint(0,0)); + if (embeddedWinId()) { + XConfigureEvent c; + memset(&c, 0, sizeof(c)); + c.type = ConfigureNotify; + c.display = qt_xdisplay(); + c.send_event = True; + c.event = embeddedWinId(); + c.window = winId(); + c.x = globalPos.x(); + c.y = globalPos.y(); + c.width = width(); + c.height = height(); + c.border_width = 0; + c.above = None; + c.override_redirect = 0; + XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c ); + } +} + +void MenuEmbed::setMinimumSize( int w, int h ) +{ + QXEmbed::setMinimumSize( w, h ); + // tell the menubar also the allowed minimum size + // the applet won't allow resizing to smaller size + if( embeddedWinId() != None ) + { +// kdDebug() << "RES2:" << width() << ":" << height() << ":" << minimumWidth() << ":" << minimumHeight() << endl; + XEvent ev; + ev.xclient.display = qt_xdisplay(); + ev.xclient.type = ClientMessage; + ev.xclient.window = embeddedWinId(); + assert( msg_type_atom != None ); + ev.xclient.message_type = msg_type_atom; + ev.xclient.format = 32; + ev.xclient.data.l[0] = qt_x_time; + ev.xclient.data.l[1] = minimumWidth(); + ev.xclient.data.l[2] = minimumHeight(); + ev.xclient.data.l[3] = 0; + ev.xclient.data.l[4] = 0; + XSendEvent( qt_xdisplay(), embeddedWinId(), False, NoEventMask, &ev ); + } +} + +} // namespace + +#include "menuapplet.moc" diff --git a/kickermenu/menuapplet.h b/kickermenu/menuapplet.h new file mode 100644 index 0000000..f353869 --- /dev/null +++ b/kickermenu/menuapplet.h @@ -0,0 +1,138 @@ +/***************************************************************** + +Copyright (c) 2002 Siegfried Nijssen +Copyright (c) 2003 Lubos Lunak + +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 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 _MENUAPPLET_H_ +#define _MENUAPPLET_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QHBoxLayout; +class QLabel; + +namespace KickerMenuApplet +{ + +class MenuEmbed; + +class Applet : public KPanelApplet, public DCOPObject +{ + Q_OBJECT + K_DCOP +k_dcop: + ASYNC configure(); + virtual void showWindowList(); +public: + friend class MenuEmbed; + Applet( const QString& configFile, QWidget *parent ); + virtual ~Applet(); + virtual int widthForHeight( int height ) const; + virtual int heightForWidth( int width ) const; + void menuLost( MenuEmbed* embed ); + void updateMenuGeometry( MenuEmbed* embed ); +protected: + virtual void paletteChange(const QPalette& ); + virtual void positionChange( Position p ); + bool eventFilter(QObject *, QEvent *ev); + QMenuBar *windowIndicator; +private slots: + void moveMenu(); + void windowAdded( WId w ); + void activeWindowChanged( WId w ); + void lostSelection(); + void readSettings(); + void claimSelection(); + // to show current active window (not necessary equal to the menubar) + void initPopup(); + void fontChanged(); +private: + bool isDisabled() const; // does it own the manager selection? + WId tryTransientFor( WId w ); + void activateMenu( MenuEmbed* embed ); + static Atom makeSelectionAtom(); + void updateTopEdgeOffset(); + KWinModule* module; + QValueList< MenuEmbed* > menus; + MenuEmbed* active_menu; + KSelectionOwner* selection; + KSelectionWatcher* selection_watcher; + bool desktop_menu; + DCOPClient dcopclient; + int topEdgeOffset; + KWindowListMenu* windowList; + QHBoxLayout *layout; + QLabel *_menuMover; + bool wannaMove; + int menuDX; +}; + +class MenuEmbed : public QXEmbed +{ + Q_OBJECT +public: + MenuEmbed( WId mainwindow, bool desktop, QWidget* parent = NULL, const char* name = NULL ); + WId mainWindow() const; + bool isDesktopMenu() const; + virtual void setMinimumSize( int w, int h ); + void setMinimumSize( const QSize& s ) { setMinimumSize( s.width(), s.height()); } + QString title; +protected: + virtual void windowChanged( WId w ); + virtual bool x11Event( XEvent* ev ); +private: + void sendSyntheticConfigureNotifyEvent(); + WId main_window; + bool desktop; +}; + +inline bool Applet::isDisabled() const +{ + assert( ( selection == NULL && selection_watcher != NULL ) + || ( selection != NULL && selection_watcher == NULL )); + return selection == NULL; +} + +inline WId MenuEmbed::mainWindow() const +{ + return main_window; +} + +inline bool MenuEmbed::isDesktopMenu() const +{ + return desktop; +} + +} // namespace + +#endif diff --git a/sessionapplet/Makefile.am b/sessionapplet/Makefile.am new file mode 100644 index 0000000..4472c36 --- /dev/null +++ b/sessionapplet/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES= $(all_includes) +METASOURCES = AUTO + +lib_LTLIBRARIES = usermanager_panelapplet.la + +usermanager_panelapplet_la_SOURCES = usermanager.cpp dmctl.cpp +usermanager_panelapplet_la_LDFLAGS = -module -avoid-version $(all_libraries) +usermanager_panelapplet_la_LIBADD = $(LIB_KDEUI) + +usermanager_DATA = usermanager.desktop +usermanagerdir = $(kde_datadir)/kicker/applets + +messages: rc.cpp + $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/usermanager.pot diff --git a/sessionapplet/dmctl.cpp b/sessionapplet/dmctl.cpp new file mode 100644 index 0000000..a6d5bf9 --- /dev/null +++ b/sessionapplet/dmctl.cpp @@ -0,0 +1,322 @@ +/* + Copyright (C) 2004 Oswald Buddenhagen + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "dmctl.h" + +#ifdef Q_WS_X11 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static enum { Dunno, NoDM, NewKDM, OldKDM/*, GDM*/ } DMType = Dunno; +static const char *ctl, *dpy; + +DM::DM() : fd( -1 ) +{ + char *ptr; + struct sockaddr_un sa; + + if (DMType == Dunno) { + if (!(dpy = ::getenv( "DISPLAY" ))) + DMType = NoDM; + else if ((ctl = ::getenv( "DM_CONTROL" ))) + DMType = NewKDM; + else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') + DMType = OldKDM; + else + DMType = NoDM; + } + switch (DMType) { + default: + return; + case NewKDM: + if ((fd = ::socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) + return; + sa.sun_family = AF_UNIX; + if ((ptr = strchr( dpy, ':' ))) + ptr = strchr( ptr, '.' ); + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl-%.*s/socket", ctl, ptr ? ptr - dpy : 512, dpy ); + if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { + ::close( fd ); + fd = -1; + } + break; + case OldKDM: + { + QString tf( ctl ); + tf.truncate( tf.find( ',' ) ); + fd = ::open( tf.latin1(), O_WRONLY ); + } + break; + } +} + +DM::~DM() +{ + if (fd >= 0) + close( fd ); +} + +bool +DM::exec( const char *cmd ) +{ + QCString buf; + + return exec( cmd, buf ); +} + +/** + * Execute a KDM remote control command. + * @param cmd the command to execute. FIXME: undocumented yet. + * @param ret the result buffer. + * @return result: + * @li If true, the command was successfully executed. + * @p ret might contain addional results. + * @li If false and @p ret is empty, a communication error occurred + * (most probably KDM is not running). + * @li If false and @p ret is non-empty, it contains the error message + * from KDM. + */ +bool +DM::exec( const char *cmd, QCString &buf ) +{ + bool ret = false; + int tl; + unsigned len = 0; + + if (fd < 0) + goto busted; + + if (::write( fd, cmd, (tl = strlen( cmd )) ) != tl) { + bust: + ::close( fd ); + fd = -1; + busted: + buf.resize( 0 ); + return false; + } + if (DMType == OldKDM) { + buf.resize( 0 ); + return true; + } + for (;;) { + if (buf.size() < 128) + buf.resize( 128 ); + else if (buf.size() < len * 2) + buf.resize( len * 2 ); + if ((tl = ::read( fd, buf.data() + len, buf.size() - len)) <= 0) { + if (tl < 0 && errno == EINTR) + continue; + goto bust; + } + len += tl; + if (buf[len - 1] == '\n') { + buf[len - 1] = 0; + if (len > 2 && buf[0] == 'o' && buf[1] == 'k' && buf[2] < 32) + ret = true; + break; + } + } + return ret; +} + +bool +DM::canShutdown() +{ + if (DMType == OldKDM) + return strstr( ctl, ",maysd" ) != 0; + + QCString re; + + return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0; +} + +void +DM::shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption ) +{ + if (!bootOption.isEmpty() && DMType != NewKDM) + return; + + if (shutdownType != KApplication::ShutdownTypeNone) { + QCString cmd( "shutdown\t" ); + cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? + "reboot\t" : "halt\t" ); + if (!bootOption.isNull()) + cmd.append( "=" ).append( bootOption.local8Bit() ).append( "\t" ); + cmd.append( shutdownMode == KApplication::ShutdownModeInteractive ? + "ask\n" : + shutdownMode == KApplication::ShutdownModeForceNow ? + "forcenow\n" : + shutdownMode == KApplication::ShutdownModeTryNow ? + "trynow\n" : "schedule\n" ); + exec( cmd.data() ); + } +} + +bool +DM::bootOptions( QStringList &opts, int &defopt, int ¤t ) +{ + if (DMType != NewKDM) + return false; + + QCString re; + if (!exec( "listbootoptions\n", re )) + return false; + + opts = QStringList::split( '\t', QString::fromLocal8Bit( re.data() ) ); + if (opts.size() < 4) + return false; + + bool ok; + defopt = opts[2].toInt( &ok ); + if (!ok) + return false; + current = opts[3].toInt( &ok ); + if (!ok) + return false; + + opts = QStringList::split( ' ', opts[1] ); + for (QStringList::Iterator it = opts.begin(); it != opts.end(); ++it) + (*it).replace( "\\s", " " ); + + return true; +} + +void +DM::setLock( bool on ) +{ + exec( on ? "lock\n" : "unlock\n" ); +} + +bool +DM::isSwitchable() +{ + if (DMType == OldKDM) + return dpy[0] == ':'; + + QCString re; + + return exec( "caps\n", re ) && re.find( "\tlocal" ) >= 0; +} + +int +DM::numReserve() +{ + if (DMType == OldKDM) + return strstr( ctl, ",rsvd" ) ? 1 : -1; + + QCString re; + int p; + + if (!(exec( "caps\n", re ) && (p = re.find( "\treserve " )) >= 0)) + return -1; + return atoi( re.data() + p + 9 ); +} + +void +DM::startReserve() +{ + exec("reserve\n"); +} + +bool +DM::localSessions( SessList &list ) +{ + if (DMType == OldKDM) + return false; + + QCString re; + + if (!exec( "list\talllocal\n", re )) + return false; + QStringList sess = QStringList::split( QChar('\t'), re.data() + 3 ); + for (QStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + QStringList ts = QStringList::split( QChar(','), *it, true ); + SessEnt se; + se.display = ts[0]; + if (ts[1][0] == '@') + se.from = ts[1].mid( 1 ), se.vt = 0; + else + se.vt = ts[1].mid( 2 ).toInt(); + se.user = ts[2]; + se.session = ts[3]; + se.self = (ts[4].find( '*' ) >= 0); + se.tty = (ts[4].find( 't' ) >= 0); + list.append( se ); + } + return true; +} + +void +DM::sess2Str2( const SessEnt &se, QString &user, QString &loc ) +{ + if (se.tty) { + user = i18n("user: ...", "%1: TTY login").arg( se.user ); + loc = se.vt ? QString("vt%1").arg( se.vt ) : se.display ; + } else { + user = + se.user.isEmpty() ? + se.session.isEmpty() ? + i18n("Unused") : + se.session == "" ? + i18n("X login on remote host") : + i18n("... host", "X login on %1").arg( se.session ) : + i18n("user: session type", "%1: %2") + .arg( se.user ).arg( se.session ); + loc = + se.vt ? + QString("%1, vt%2").arg( se.display ).arg( se.vt ) : + se.display; + } +} + +QString +DM::sess2Str( const SessEnt &se ) +{ + QString user, loc; + + sess2Str2( se, user, loc ); + return i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ); +} + +bool +DM::switchVT( int vt ) +{ + return exec( QString("activate\tvt%1\n").arg(vt).latin1() ); +} + +void +DM::lockSwitchVT( int vt ) +{ + if (switchVT( vt )) + kapp->dcopClient()->send( "kdesktop", "KScreensaverIface", "lock()", "" ); +} + +#endif // Q_WS_X11 diff --git a/sessionapplet/dmctl.h b/sessionapplet/dmctl.h new file mode 100644 index 0000000..bc58fcb --- /dev/null +++ b/sessionapplet/dmctl.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2004,2005 Oswald Buddenhagen + Copyright (C) 2005 Stephan Kulow + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DMCTL_H +#define DMCTL_H + +#include + +struct SessEnt { + QString display, from, user, session; + int vt; + bool self:1, tty:1; +}; + +typedef QValueList SessList; + +class DM { + +#ifdef Q_WS_X11 + +public: + DM(); + ~DM(); + + bool canShutdown(); + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption = QString::null ); + + void setLock( bool on ); + + bool isSwitchable(); + int numReserve(); + void startReserve(); + bool localSessions( SessList &list ); + bool switchVT( int vt ); + void lockSwitchVT( int vt ); + + bool bootOptions( QStringList &opts, int &dflt, int &curr ); + + static QString sess2Str( const SessEnt &se ); + static void sess2Str2( const SessEnt &se, QString &user, QString &loc ); + +private: + int fd; + + bool exec( const char *cmd, QCString &ret ); + bool exec( const char *cmd ); + +#else // Q_WS_X11 + +public: + DM() {} + + bool canShutdown() { return false; } + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption = QString::null ) {} + + void setLock( bool ) {} + + bool isSwitchable() { return false; } + int numReserve() { return -1; } + void startReserve() {} + bool localSessions( SessList &list ) { return false; } + void switchVT( int vt ) {} + + bool bootOptions( QStringList &opts, int &dflt, int &curr ); + +#endif // Q_WS_X11 + +}; // class DM + +#endif // DMCTL_H diff --git a/sessionapplet/usermanager.cpp b/sessionapplet/usermanager.cpp new file mode 100644 index 0000000..faf491f --- /dev/null +++ b/sessionapplet/usermanager.cpp @@ -0,0 +1,281 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dmctl.h" +#include "usermanager.h" + +#define _ICONSET_(i) KGlobal::iconLoader()->loadIconSet(i, KIcon::Small, 0, false) + + +UserManager::UserManager(const QString& configFile, Type type, int actions, QWidget *parent, const char *name) + : KPanelApplet(configFile, type, actions, parent, name) +{ + + // Get the current application configuration handle + ksConfig = config(); + lockIcon = _ICONSET_("lock"); + fileSaveIcon = _ICONSET_("filesave"); + exitIcon = _ICONSET_("exit"); + setFixedWidth(600); + + menu = new KMenuBar(this); + menu->setTopLevelMenu(false); + menu->setFrameShape ( QFrame::NoFrame ); + menu->setMargin ( 0 ); + menu->setLineWidth ( 0 ); + + // sessions + sessionPopup = new QPopupMenu(this); + menu->insertItem ( getenv("USER"), sessionPopup, 0); + connect( sessionPopup, SIGNAL(aboutToShow()), SLOT(slotPopulateSessions()) ); + connect( sessionPopup, SIGNAL(activated(int)), SLOT(slotSessionActivated(int)) ); + + // languages + langPopup = new QPopupMenu(this); + + KConfigBase *config = KGlobal::config(); + config->setGroup("Locale"); + langList = config->readListEntry ("Language", ':'); +// QString flag( locate( "locale", QString::fromLatin1( "l10n/%1/flag.png" ).arg(langList[0]) ) ); +// langLabel = new QLabel(this); +// langLabel->setPixmap(_ICONSET_(flag).pixmap()); + + menu->insertItem ( '[' + langList[0].section('_',0,0) + ']', langPopup, 1 ); + menu->connectItem ( 1, this, SLOT(slotPopulateLanguages()) ); + connect( langPopup, SIGNAL(aboutToShow()), SLOT(slotPopulateLanguages()) ); + connect( langPopup, SIGNAL(activated(int)), SLOT(slotLanguageActivated(int)) ); + + menu->adjustSize(); + + setFixedWidth(menu->width()+5); + + mainView = menu; + menu->move(menu->mapToParent(QPoint(0,0)).x(),0); + menu->show(); +} + +UserManager::~UserManager() +{ +} + +int UserManager::widthForHeight(int) const +{ + return menu->width(); +} + +int UserManager::heightForWidth(int) const +{ + return menu->height(); +} + +void UserManager::about() +{ + KMessageBox::information(0, i18n("This is an about box")); +} + +void UserManager::lock() +{ + QCString appname( "kdesktop" ); +// if ( kicker_screen_number ) +// appname.sprintf("kdesktop-screen-%d", kicker_screen_number); + kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", ""); +} + +void UserManager::logout() +{ + kapp->requestShutDown(); +} + + +void UserManager::slotPopulateLanguages() +{ + langPopup->clear(); + KConfig *config = new KConfig("kdeglobals"); + config->setGroup("Locale"); + langList = config->readListEntry ("Language", ':'); + int i = 0; + for ( QStringList::ConstIterator it = langList.begin(); + it != langList.end(); ++it ) + { + KConfig entry(locate( "locale", QString::fromLatin1( "%1/entry.desktop" ).arg(*it) )); + entry.setGroup("KCM Locale"); + QString name = entry.readEntry("Name", i18n("without name")); + + QString flag( locate( "locale", QString::fromLatin1( "%1/flag.png" ).arg(*it) ) ); + langPopup->insertItem( _ICONSET_(flag), name, i ); + i++; + } +// langPopup->popup(langLabel->mapToGlobal(QPoint(0,height()))); +} + +void UserManager::slotLanguageActivated( int i ) +{ + if (i == 0) + return; // no change, no action + menu->changeItem ( 1, '[' + langList[i].section('_',0,0) + ']'/**langPopup->pixmap(i)*/ ); +// langLabel->setPixmap(*langPopup->pixmap(i)); + KConfig *config = new KConfig("kdeglobals"); + config->setGroup("Locale"); + QString tmp = langList[i]; + langList.remove(langList.at(i)); + langList.prepend(tmp); + config->writeEntry ("Language", langList, ':'); + config->sync(); +// KService::rebuildKSycoca(this); + delete config; +} + +void UserManager::slotPopulateSessions() +{ + int p = 0; + DM dm; + + sessionPopup->clear(); + // lock + if (kapp->authorize("lock_screen")) + { + sessionPopup->insertItem(lockIcon, i18n("Lock Session"), 102); + } + sessionPopup->insertSeparator(); + // switch + if (kapp->authorize("start_new_session") && (p = dm.numReserve()) >= 0) + { + if (kapp->authorize("lock_screen")) + sessionPopup->insertItem(/*_ICONSET_("lockfork"),*/ i18n("Lock&&Load Session..."), 100 ); + sessionPopup->insertItem(_ICONSET_("fork"), i18n("New Session..."), 101 ); + if (!p) { + sessionPopup->setItemEnabled( 100, false ); + sessionPopup->setItemEnabled( 101, false ); + } + sessionPopup->insertSeparator(); + } + SessList sess; + if (dm.localSessions( sess )) + for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + int id = sessionPopup->insertItem( DM::sess2Str( *it ), (*it).vt ); + if (!(*it).vt) + sessionPopup->setItemEnabled( id, false ); + if ((*it).self) + sessionPopup->setItemChecked( id, true ); + } + // save + sessionPopup->insertSeparator(); + KConfig ksmserver("ksmserverrc", false, false); + ksmserver.setGroup("General"); + if (ksmserver.readEntry( "loginMode" ) == "restoreSavedSession") + { + sessionPopup->insertItem(fileSaveIcon, i18n("Save Session"), 103); + } + // logout + if (kapp->authorize("logout")) + { + sessionPopup->insertItem(exitIcon, i18n("Log Out..."), 104); + } +} + +void UserManager::slotSessionActivated( int ent ) +{ + switch (ent) + { + case 100: + doNewSession( true ); + break; + case 101: + doNewSession( false ); + break; + case 102: + lock(); + break; + case 103: + saveSession(); + break; + case 104: + logout(); + break; + default: + if (!sessionPopup->isItemChecked( ent )) + DM().lockSwitchVT( ent ); + } +} + +void UserManager::doNewSession( bool lock_ ) +{ + int result = KMessageBox::warningContinueCancel( + kapp->desktop()->screen(kapp->desktop()->screenNumber(this)), + 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.

    ") + .arg(7).arg(8), + i18n("Warning - New Session"), + KGuiItem(i18n("&Start New Session"), "fork"), + ":confirmNewSession", +#if KDE_IS_VERSION(3,4,0) //3.4 + KMessageBox::PlainCaption | +#endif + KMessageBox::Notify); + + if (result==KMessageBox::Cancel) + return; + + if (lock_) + lock(); + + DM().startReserve(); +} + +void UserManager::saveSession() +{ + QByteArray data; + kapp->dcopClient()->send( "ksmserver", "default", + "saveCurrentSession()", data ); +} + + +extern "C" +{ + KPanelApplet* init( QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("usermanager"); + return new UserManager(configFile, KPanelApplet::Normal, KPanelApplet::About, parent, "usermanager"); + } +} diff --git a/sessionapplet/usermanager.desktop b/sessionapplet/usermanager.desktop new file mode 100644 index 0000000..31c61cf --- /dev/null +++ b/sessionapplet/usermanager.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=Session Control, Lock, Logout, Change +Name=SessionManager +Name[xx]=xxSessionManagerxx +Icon=fork +X-KDE-Library=usermanager_panelapplet +X-KDE-UniqueApplet = true diff --git a/sessionapplet/usermanager.h b/sessionapplet/usermanager.h new file mode 100644 index 0000000..87f8864 --- /dev/null +++ b/sessionapplet/usermanager.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#ifndef USERMANAGER_H +#define USERMANAGER_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +class KMenuBar; +class QPopunMenu; +// class QLabel; + +class UserManager : public KPanelApplet +{ + Q_OBJECT + +public: + UserManager(const QString& configFile, Type t = Normal, int actions = 0, + QWidget *parent = 0, const char *name = 0); + /** destructor */ + ~UserManager(); + + virtual void about(); + int heightForWidth(int) const; + int widthForHeight(int) const; + +protected slots: + void slotPopulateSessions(); + void slotSessionActivated( int ); + void slotPopulateLanguages(); + void slotLanguageActivated( int ); + +protected: + void lock(); + void logout(); + void saveSession(); + void doNewSession(bool lock_); + +private: + KConfig *ksConfig; + QWidget *mainView; + KMenuBar *menu; + QPopupMenu *sessionPopup; + QPopupMenu *langPopup; + QStringList langList; + QIconSet exitIcon; + QIconSet lockIcon; + QIconSet fileSaveIcon; +// QLabel *langLabel; +}; + +#endif diff --git a/sessionapplet/usermanager.lsm b/sessionapplet/usermanager.lsm new file mode 100644 index 0000000..cb6f2cd --- /dev/null +++ b/sessionapplet/usermanager.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: UserManager -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Thomas Lübking +Maintained-by: Thomas Lübking +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx usermanager-0.1.tar.gz + xxx usermanager-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/sidebar/Makefile.am b/sidebar/Makefile.am new file mode 100644 index 0000000..779e77d --- /dev/null +++ b/sidebar/Makefile.am @@ -0,0 +1,17 @@ +INCLUDES= $(all_includes) +METASOURCES = AUTO + +kde_module_LTLIBRARIES=konqsidebar_baghirasidebar.la +include_HEADERS = baghirasidebar.h linkview.h listboxlink.h dndlistbox.h baghirasidebariface.h +noinst_HEADERS = baghiralinkdrag.h baghirasidebar.h linkview.h listboxlink.h dndlistbox.h baghirasidebariface.h + +konqsidebar_baghirasidebar_la_SOURCES = baghiralinkdrag.cpp baghirasidebar.cpp linkview.cpp listboxlink.cpp dndlistbox.cpp linkconfig.ui baghirasidebariface.skel +konqsidebar_baghirasidebar_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -lkonqsidebarplugin +konqsidebar_baghirasidebar_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) + +baghirasidebar_entry_DATA = baghirasidebar.desktop +baghirasidebar_entrydir = $(kde_datadir)/konqsidebartng/entries +baghirasidebar_add_DATA = baghirasidebar_add.desktop +baghirasidebar_adddir = $(kde_datadir)/konqsidebartng/add +poof_DATA = ../imagebase/poof.png +poofdir = $(kde_datadir)/baghira diff --git a/sidebar/baghiralinkdrag.cpp b/sidebar/baghiralinkdrag.cpp new file mode 120000 index 0000000..4997e26 --- /dev/null +++ b/sidebar/baghiralinkdrag.cpp @@ -0,0 +1 @@ +../starter/baghiralinkdrag.cpp \ No newline at end of file diff --git a/sidebar/baghiralinkdrag.h b/sidebar/baghiralinkdrag.h new file mode 120000 index 0000000..20f50f7 --- /dev/null +++ b/sidebar/baghiralinkdrag.h @@ -0,0 +1 @@ +../starter/baghiralinkdrag.h \ No newline at end of file diff --git a/sidebar/baghirasidebar.cpp b/sidebar/baghirasidebar.cpp new file mode 100644 index 0000000..0969bad --- /dev/null +++ b/sidebar/baghirasidebar.cpp @@ -0,0 +1,68 @@ + +#include +#include +#include +#include +#include "dndlistbox.h" +#include "listboxlink.h" +#include "linkview.h" +#include "baghirasidebar.h" +#include "baghirasidebar.moc" + +baghiraSidebar::baghiraSidebar(KInstance *inst,QObject *parent,QWidget *widgetParent, QString &desktopName, const char* name): + KonqSidebarPlugin(inst,parent,widgetParent,desktopName,name) +{ + scrollView = new LinkView(widgetParent); + scrollView->setHScrollBarMode(QScrollView::AlwaysOff); + connect (scrollView->Hardware(), SIGNAL(clicked(QListBoxItem *)), this, SLOT(callURL(QListBoxItem *))); + connect (scrollView->Locations(), SIGNAL(clicked(QListBoxItem *)), this, SLOT(callURL(QListBoxItem *))); +} + +baghiraSidebar::~baghiraSidebar() +{ +} + +void baghiraSidebar::callURL(QListBoxItem *item) +{ + emit openURLRequest(KURL(((ListBoxLink*)(item))->URL()), KParts::URLArgs(true,0,0)); +} + +void baghiraSidebar::handleURL(const KURL &url) +{ + int item = scrollView->Hardware()->currentItem(); + if ( scrollView->Hardware()->isSelected(item) && + KURL(((ListBoxLink*)(scrollView->Hardware()->item(item)))->URL()).url() != url.url() ) + { + scrollView->Hardware()->setSelected(item, FALSE); + return; + } + item = scrollView->Locations()->KListBox::currentItem(); + if (scrollView->Locations()->isSelected(item) && + KURL(((ListBoxLink*)(scrollView->Locations()->item(item)))->URL()).url() != url.url() ) + { + scrollView->Locations()->setSelected(item, FALSE); + return; + } +} + +extern "C" { + KDE_EXPORT bool add_konqsidebar_baghirasidebar(QString* fn, QString* param, QMap *map) { + Q_UNUSED(param); + + map->insert("Type", "Link"); + map->insert("Icon", "bab_brushed"); + map->insert("Name", "Baghira Sidebar"); + map->insert("Open", "true"); + map->insert("X-KDE-KonqSidebarModule","konqsidebar_baghirasidebar"); + fn->setLatin1("baghirasidebar%1.desktop"); + return true; + } +} + +extern "C" +{ + void* create_konqsidebar_baghirasidebar(KInstance *instance,QObject *par,QWidget *widp,QString &desktopname,const char *name) + { + return new baghiraSidebar(instance,par,widp,desktopname,name); + } +}; diff --git a/sidebar/baghirasidebar.desktop b/sidebar/baghirasidebar.desktop new file mode 100644 index 0000000..ba6b560 --- /dev/null +++ b/sidebar/baghirasidebar.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Link +URL= +Icon=bab_brushed +Comment=Baghira Sidebar +Name=baghirasidebar +Name[xx]=xxbaghirasidebarxx + +Open=false +X-KDE-KonqSidebarModule=konqsidebar_baghirasidebar + diff --git a/sidebar/baghirasidebar.h b/sidebar/baghirasidebar.h new file mode 100644 index 0000000..dae8fc5 --- /dev/null +++ b/sidebar/baghirasidebar.h @@ -0,0 +1,50 @@ + +#ifndef BAGHIRASIDEBAR_H +#define BAGHIRASIDEBAR_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +class LinkView; +class KListBox; +class QListBoxItem; + +class baghiraSidebar : public KonqSidebarPlugin +{ + Q_OBJECT + +public: + /** + * Construct a @ref KonqSidebarPlugin. + * + * @param inst The sidebar's kinstance class. + * @param parent The sidebar internal button info class responsible for this plugin. + * @param widgetParent The container which will contain the plugins widget. + * @param desktopName The filename of the configuration file. + * @param name A Qt object name for your plugin. + **/ + baghiraSidebar(KInstance *inst,QObject *parent, QWidget *widgetParent, QString &desktopName, const char* name=0); + + /** destructor */ + ~baghiraSidebar(); + + virtual QWidget *getWidget(){return scrollView;} + virtual void *provides(const QString &) {return 0;} + +protected: + LinkView *scrollView; + virtual void handleURL(const KURL &url); + +private slots: + void callURL(QListBoxItem *); + +signals: + void openURLRequest(const KURL &url, const KParts::URLArgs &args); + +}; + +#endif diff --git a/sidebar/baghirasidebar_add.desktop b/sidebar/baghirasidebar_add.desktop new file mode 100644 index 0000000..634b658 --- /dev/null +++ b/sidebar/baghirasidebar_add.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Comment=Baghira Sidebar +Encoding=UTF-8 +Icon=filetypes +Name=Add Baghira Sidebar +Name[de]=Baghira Sideabr hinzufügen +Open=false +Type=Link +URL= +X-KDE-KonqSidebarAddModule=konqsidebar_baghirasidebar diff --git a/sidebar/baghirasidebariface.h b/sidebar/baghirasidebariface.h new file mode 100644 index 0000000..c5e160d --- /dev/null +++ b/sidebar/baghirasidebariface.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BAGHIRASIDEBARIFACE_H_ +#define _BAGHIRASIDEBARIFACE_H_ + +#include + +class BaghiraSidebarIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual void mediumAdded(const QString &name) = 0; + virtual void mediumRemoved(const QString &name) = 0; + virtual void mediumChanged(const QString &name) = 0; +}; + +#endif diff --git a/sidebar/configure.in.in b/sidebar/configure.in.in new file mode 100644 index 0000000..72f8843 --- /dev/null +++ b/sidebar/configure.in.in @@ -0,0 +1,2 @@ +AM_CONDITIONAL( HAVE_3_4, test $(kde-config --version | grep "KDE:" | cut -d" " -f2 | cut -d"." -f2) -gt 3 ) + diff --git a/sidebar/dndlistbox.cpp b/sidebar/dndlistbox.cpp new file mode 100644 index 0000000..8fe78cf --- /dev/null +++ b/sidebar/dndlistbox.cpp @@ -0,0 +1,685 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "listboxlink.h" +#include "linkconfig.h" +#include "dndlistbox.h" +#include "baghiralinkdrag.h" +#include "dndlistbox.moc" + +#define ID 0 +#define NAME 1 +#define LABEL 2 +#define USER_LABEL 3 +#define MOUNTABLE 4 +#define DEVICE_NODE 5 +#define MOUNT_POINT 6 +#define FS_TYPE 7 +#define MOUNTED 8 +#define BASE_URL 9 +#define MIME_TYPE 10 +#define ICON_NAME 11 +#define MEDIA_PROPS 12 +#define MEDIALIST_PROPS 13 + +ResizingLinkBox::ResizingLinkBox( QWidget * parent, const char * name, WFlags f ) : KListBox( parent, name, f) +{ + KConfig config(QDir::homeDirPath() + "/.qt/baghirarc"); + config.setGroup("Sidebar"); + size_ = config.readNumEntry (QString(name) + "_IconSize", 48); + popupMenu = new KPopupMenu; + popupMenu->insertTitle (i18n("Icon Size"),122,122); + popupMenu->insertItem("16x16", this, SLOT(setIconSize(int)),0,16,123); + popupMenu->insertItem("22x22", this, SLOT(setIconSize(int)),0,22,124); + popupMenu->insertItem("32x32", this, SLOT(setIconSize(int)),0,32,125); + popupMenu->insertItem("48x48", this, SLOT(setIconSize(int)),0,48,126); + popupMenu->insertItem("64x64", this, SLOT(setIconSize(int)),0,64,127); + popupMenu->insertItem("128x128", this, SLOT(setIconSize(int)),0,128,128); +} + +void ResizingLinkBox::insertItem( const QListBoxItem *lbi, int index ) +{ + KListBox::insertItem( lbi, index ); + if (height() <= numRows()*itemHeight()) + emit itemNumberChanged(TRUE); +} + +void ResizingLinkBox::insertItem( const QListBoxItem *lbi, const QListBoxItem *after ) +{ + KListBox::insertItem( lbi, after ); + if (height() <= numRows()*itemHeight()) + emit itemNumberChanged(TRUE); +} + + +void ResizingLinkBox::insertItem( const QString & icon, const QString & title, const QString & url ) +{ + insertItem( new ListBoxLink(icon, size_, title, url ) ); +} + +void ResizingLinkBox::removeItem( int index ) +{ + blockSignals ( true ); + KListBox::removeItem(index); + blockSignals ( false ); + emit itemNumberChanged(FALSE); +} + +void ResizingLinkBox::setIconSize(int size) +{ + size_ = size; + KConfig *config = new KConfig(QDir::homeDirPath() + "/.qt/baghirarc"); + config->setGroup("Sidebar"); + config->writeEntry (QString(name()) + "_IconSize", size); + config->sync(); + ListBoxLink *runner; + ListBoxDevice *current; + blockSignals ( true ); + for (uint i = 0; i < count(); i++) + { + runner = (ListBoxLink*)item(i); + if (dynamic_cast(runner)) + { + current = (ListBoxDevice*)runner; + insertItem( new ListBoxDevice(current->icon(), size, current->text(), current->URL(), current->name(), current->mountPoint(), current->mounted(), current->ejectable(), current->removable(), current->id()), i ); + } + else + { + insertItem( new ListBoxLink(runner->icon(), size, runner->text(), runner->URL()), i ); + } + KListBox::removeItem(i+1); + } + blockSignals ( false ); +} + +void ResizingLinkBox::mousePressEvent ( QMouseEvent *mpe ) +{ + KListBox::mousePressEvent( mpe ); +} + +void ResizingLinkBox::mouseReleaseEvent ( QMouseEvent *mpe ) +{ + if (mpe->button() == Qt::LeftButton) + { + ListBoxLink *link = (ListBoxLink*)itemAt(mpe->pos()); + if (isSelected(link)) emit clicked(link); + KListBox::mousePressEvent( mpe ); + return; + } + KListBox::mouseReleaseEvent( mpe ); +} + +void ResizingLinkBox::contentsWheelEvent ( QWheelEvent * we ) +{ + if (we->state() == Qt::ControlButton) + KListBox::contentsWheelEvent ( we ); + else + emit scrolled(0, -we->delta()); +} + +MediaListBox::MediaListBox( QWidget * parent, const char * name, WFlags f ) : ResizingLinkBox(parent, name, f), DCOPObject("BaghiraSidebarIface") +{ + KConfig config(QDir::homeDirPath() + "/.qt/baghirarc"); + config.setGroup("Sidebar"); + hiddenDevices = config.readListEntry("HiddenDevices"); + currentFloppy = 0L; + devicePopup = new KPopupMenu(this); + devicePopup->setCheckable ( true ); + popupMenu->insertItem(i18n("Device List"), devicePopup, 1, 0); + popupMenu->insertSeparator( 0 ); + +#if KDE_IS_VERSION(3,4,90) + insertItem(new ListBoxDevice("system", size_, i18n("My Computer"), "system:/", "", "", TRUE, FALSE, FALSE)); + insertItem(new ListBoxDevice("network", size_, i18n("Network"), "remote:/", "", "", TRUE, FALSE, FALSE)); +#else + insertItem(new ListBoxDevice("system", size_, i18n("My Computer"), "media:/", "", "", TRUE, FALSE, FALSE)); + insertItem(new ListBoxDevice("network", size_, i18n("Network"), "lan:/localhost", "", "", TRUE, FALSE, FALSE)); +#endif + insertItem(new ListBoxDevice("hdd_mount", size_, i18n("Startvolume"), QDir::rootDirPath(), "", "", TRUE, FALSE, FALSE)); + client = KApplication::dcopClient(); + client->connectDCOPSignal("kded", "mediamanager", "mediumAdded(QString)", "BaghiraSidebarIface", "mediumAdded(QString)", FALSE); + client->connectDCOPSignal("kded", "mediamanager", "mediumRemoved(QString)", "BaghiraSidebarIface", "mediumRemoved(const QString)", FALSE); + client->connectDCOPSignal("kded", "mediamanager", "mediumChanged(QString)", "BaghiraSidebarIface", "mediumChanged(QString)", FALSE); + /* Get the media info - huhhh ;) */ + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << ""; // ask for the full list + if (!client->call("kded", "mediamanager", "fullList()", data, replyType, replyData)) + qDebug("there was some error using DCOP."); + else + { + QDataStream reply(replyData, IO_ReadOnly); + if (replyType == "QStringList") + { + QStringList result; + reply >> result; + blockSignals ( true ); + for (uint i = 0; i < result.size()/MEDIALIST_PROPS; i++) + { + if (result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/hdd_mounted" && + result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/hdd_unmounted" && + result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/nfs_mounted" && + result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/nfs_unmounted" && + result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/smb_mounted" && + result[MEDIALIST_PROPS*i+MIME_TYPE] != "media/smb_unmounted") + { + ListBoxDevice *dev = createListBoxDevice(result, i); + if (hiddenDevices.contains(dev->name())) + { + deviceList.append(dev); + devicePopup->setItemChecked(dev->id(),false); + } + else + { + insertItem(dev); + devicePopup->setItemChecked(dev->id(),true); + } + } + } + blockSignals ( false ); + } + else + qWarning("fullList() returned an unexpected type of reply!"); + } +// setCurrentItem( 0 ); +} + +MediaListBox::~MediaListBox() +{ + hiddenDevices.clear(); + ListBoxDevice *runner; + for ( runner = deviceList.first(); runner; runner = deviceList.next() ) + hiddenDevices.append(runner->name()); + KConfig config(QDir::homeDirPath() + "/.qt/baghirarc"); + config.setGroup("Sidebar"); + config.writeEntry("HiddenDevices", hiddenDevices); +} + +void MediaListBox::removeItem( int index ) +{ + devicePopup->removeItem(((ListBoxDevice*)item( index ))->id()); + ResizingLinkBox::removeItem(index); +} + +void MediaListBox::kfloppy() +{ + if (currentFloppy) + { + KProcess proc; + proc << "kfloppy" << currentFloppy->mountPoint(); + proc.start(KProcess::DontCare); + proc.detach(); + currentFloppy = 0L; + } + return; +} + +void MediaListBox::toggleDevice(int id) +{ + ListBoxDevice *runner; + if (devicePopup->isItemChecked(id)) // remove the device! + { + devicePopup->setItemChecked(id, false); + for (uint i = 0; i < count(); i++) + { + runner = (ListBoxDevice*)item(i); + if (runner->id() == id) + { + deviceList.append(runner); + blockSignals ( true ); + takeItem(runner); + blockSignals ( false ); + break; + } + } + } + else // add the device! + { + devicePopup->setItemChecked(id, true); + for ( runner = deviceList.first(); runner; runner = deviceList.next() ) + if (runner->id() == id) + { + insertItem(deviceList.take()); + break; + } + } +} + +ListBoxDevice *MediaListBox::createListBoxDevice(QStringList & deviceProperties, uint n) +{ + QString icon; + icon = deviceProperties[MEDIALIST_PROPS*n+ICON_NAME]; + if (icon.isNull()) + { + icon = deviceProperties[MEDIALIST_PROPS*n+MIME_TYPE]; + icon = icon.section( '/', -1 ); + icon.truncate( icon.length()-2 ); + if (icon.contains("floppy")) icon.prepend("3"); + } + QString label; + label = deviceProperties[MEDIALIST_PROPS*n+USER_LABEL]; + if (label.isNull()) + { + label = deviceProperties[MEDIALIST_PROPS*n+LABEL]; + label = i18n(label.section( " (", 0, 0 ).utf8()); + } +#if KDE_IS_VERSION(3,4,90) + return new ListBoxDevice( icon, size_, label, "system:/media/"+deviceProperties[MEDIALIST_PROPS*n+NAME], deviceProperties[MEDIALIST_PROPS*n+NAME], deviceProperties[MEDIALIST_PROPS*n+DEVICE_NODE], deviceProperties[MEDIALIST_PROPS*n+MOUNTED] == "true", icon.contains("dvd") || icon.contains("cdrom") || icon.contains("cdwriter"),icon.contains("floppy"), devicePopup->insertItem(deviceProperties[MEDIALIST_PROPS*n+NAME], this, SLOT(toggleDevice(int)))); +#else + return new ListBoxDevice( icon, size_, label, "media:/"+deviceProperties[MEDIALIST_PROPS*n+NAME], deviceProperties[MEDIALIST_PROPS*n+NAME], deviceProperties[MEDIALIST_PROPS*n+DEVICE_NODE], deviceProperties[MEDIALIST_PROPS*n+MOUNTED] == "true", icon.contains("dvd") || icon.contains("cdrom") || icon.contains("cdwriter"),icon.contains("floppy"),devicePopup->insertItem(deviceProperties[MEDIALIST_PROPS*n+NAME], this, SLOT(toggleDevice(int)))); +#endif +} + +int MediaListBox::index (const QString & name ) +{ + ListBoxDevice *device; + for (uint i = 0; i < count(); i++) + { + device = (ListBoxDevice*)item(i); + if (device && device->name() == name) return i; + } + return -1; +} + +void MediaListBox::mediumAdded(const QString &name) +{ + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << name; // ask for this item only + if (!client->call("kded", "mediamanager", "properties(QString)", data, replyType, replyData)) + qDebug("there was some error using DCOP."); + else + { + QDataStream reply(replyData, IO_ReadOnly); + if (replyType == "QStringList") + { + QStringList result; + reply >> result; + ListBoxDevice *dev = createListBoxDevice(result); + if (hiddenDevices.contains(dev->name())) + { + deviceList.append(dev); + devicePopup->setItemChecked(dev->id(),false); + } + else + { + insertItem(dev); + devicePopup->setItemChecked(dev->id(),true); + } + } + else + qWarning("properties() returned an unexpected type of reply!"); + } +} + +void MediaListBox::mediumRemoved(const QString &name) +{ + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << name; // ask for this item only + if (!client->call("kded", "mediamanager", "properties(QString)", data, replyType, replyData)) + qDebug("there was some error using DCOP."); + else + { + QDataStream reply(replyData, IO_ReadOnly); + if (replyType == "QStringList") + { + QStringList result; + reply >> result; + int i = index(name); + if (i<0) + return; + if (i == currentItem()) setCurrentItem(0); + removeItem(i); + } + else + qWarning("properties() returned an unexpected type of reply!"); + } +} + +void MediaListBox::mediumChanged(const QString &name) +{ + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << name; // ask for this item only + if (!client->call("kded", "mediamanager", "properties(QString)", data, replyType, replyData)) + qDebug("there was some error using DCOP."); + else + { + QDataStream reply(replyData, IO_ReadOnly); + if (replyType == "QStringList") + { + QStringList result; + reply >> result; + int i = index(name); + if (i<0) + return; + + ListBoxDevice *device = createListBoxDevice(result); + if (hiddenDevices.contains(device->name())) + { + deviceList.append(device); + devicePopup->setItemChecked(device->id(),false); + return; + } + devicePopup->setItemChecked(device->id(),true); + blockSignals(true); + if (i == currentItem()) // changing current item - take some care of updating stuff + { + if (((ListBoxDevice*)item(i))->mounted() && !device->mounted()) // unmounted the device - we certainly do not wanna select it anymore + { + setCurrentItem(0); + removeItem(i); + insertItem(device, i); + } + else // we're selected and wanna keep selection + { + removeItem(i); + insertItem(device, i); + setSelected( i, true ); + } + } + else // ordinary change + { + removeItem(i); + insertItem(device, i); + } + blockSignals(false); + } + else + qWarning("properties() returned an unexpected type of reply!"); + } +} + +#define _FLOPPYID_ 0 +#define _FLOPPYINDEX_ 0 + +void MediaListBox::mousePressEvent ( QMouseEvent *mpe ) +{ + if (mpe->button() == Qt::RightButton) + { + popupMenu->removeItem(_FLOPPYID_); + ListBoxDevice *device = (ListBoxDevice*)itemAt(mpe->pos()); + if (device && device->name().contains("fd")) + { + currentFloppy = device; + popupMenu->insertItem(i18n("Format disk..."), this, SLOT(kfloppy()),0,_FLOPPYID_,_FLOPPYINDEX_); + } + popupMenu->popup(mpe->globalPos()); + return; + } + if (mpe->button() == Qt::LeftButton && mpe->x() > width()-22) + { + ListBoxDevice *device = (ListBoxDevice*)itemAt(mpe->pos()); + int dy = itemRect(device).y(); + if ((device->removable() || device->ejectable()) && device->mounted() && mpe->y() > dy+11 && mpe->y() < dy+33) + { + KProcess proc; + device->ejectable()? + proc << "kdeeject" /*<< "-q"*/ << device->mountPoint(): + proc << "umount" << device->mountPoint(); // umount? + proc.start(KProcess::DontCare); + proc.detach(); + return; + } + } + ResizingLinkBox::mousePressEvent( mpe ); +} + +void MediaListBox::resizeEvent ( QResizeEvent * re) +{ + if (width() != re->oldSize().width()) + { + for (uint i = 0; i < count(); i++) + if (((ListBoxDevice*)item(i))->ejectable() && ((ListBoxDevice*)item(i))->mounted() && !isSelected(i)) updateItem(i); + } + ResizingLinkBox::resizeEvent(re); +} + +DnDListBox::DnDListBox( QWidget * parent, const char * name, WFlags f ): +ResizingLinkBox( parent, name, f), _poof(0), _poofIndex(0), _poofAnimPix(0), _poofPix(0) +{ + setAcceptDrops(true); + dialog = new LinkConfig(); + connect(dialog->buttonOk, SIGNAL(clicked()), this, SLOT(updateLink())); + setCursor(Qt::PointingHandCursor); +} + +DnDListBox::~DnDListBox() +{ +} + +void DnDListBox::poof(ListBoxLink *link) +{ + _poofIndex = 0; + _poofPix = new QPixmap(locateLocal("data", "baghira/poof.png"), "png"); + _poofAnimPix = new QPixmap(_poofPix->width(), _poofPix->width()); + if (!_poof) + _poof = new QWidget(0,0, Qt::WType_TopLevel | Qt::WStyle_NoBorder | Qt::WStyle_StaysOnTop | Qt::WX11BypassWM); + KWin::setShadowSize(_poof->winId(), 0); + _poof->setFixedSize(_poofPix->width(), _poofPix->width()); + int x = QCursor::pos().x() - _poof->width()/2; + int y = QCursor::pos().y() - _poof->height()/2; + QPixmap bgPix = QPixmap::grabWindow( qt_xrootwin(), x, y, _poofPix->width(), _poofPix->width()); + _poof->move(x,y); + _poof->show(); + _poof->setBackgroundOrigin(QWidget::WidgetOrigin); + _poof->setPaletteBackgroundPixmap( bgPix ); + runPoof(); + removeItem ( index(link) ); +} + +void DnDListBox::runPoof() +{ + if (_poofIndex > 4) + { + _poof->hide(); + delete _poofPix; + _poofPix = 0L; +// delete _poof; +// _poof = 0L; + delete _poofAnimPix; + _poofAnimPix = 0L; + _poofIndex = 0; + return; + } + _poof->erase(); + bitBlt(_poof, 0 ,0, _poofPix, 0, _poofIndex * _poofPix->width(), _poofPix->width(), _poofPix->width(), Qt::AndROP); + ++_poofIndex; + QTimer::singleShot ( 70, this, SLOT(runPoof()) ); // around 15 fps +} + +void DnDListBox::dragEnterEvent ( QDragEnterEvent *dee ) +{ +// dragging_ = true; + if (QUriDrag::canDecode(dee) || BaghiraLinkDrag::canDecode(dee) || QTextDrag::canDecode(dee)) + dee->accept(true); +} + +void DnDListBox::dropEvent ( QDropEvent *de ) +{ + QStrList list; + QString title; + QString command; + QString icon; + int oldIndex; + QCString subtype; + if (BaghiraLinkDrag::decode(de, &title, &command, &icon, &oldIndex)) // internal move + { + BaghiraLinkDrag::setAccepted(); + QListBoxItem *after = itemAt(de->pos()); + int newIndex = index(after); + if (!dragging_ || oldIndex < 0 || oldIndex > count()-2) + insertItem (new ListBoxLink(icon, size_, title, command), after?newIndex:count()); + else if (oldIndex != newIndex) + { + insertItem (new ListBoxLink(*((ListBoxLink*)item(oldIndex))), after?newIndex:count()); + removeItem ( (newIndex < 0 || oldIndex < newIndex) ? oldIndex : oldIndex + 1 ); + } + } + else if ( QUriDrag::decode(de, list) ) + { + char *uri; + KURL url; + QListBoxItem *after = itemAt(de->pos()); + for ( uri = list.first(); uri; uri = list.next() ) + { + url = KURL(uri); + if (url.protocol() == "http") + insertItem(new ListBoxLink("html", size_, url.host()+(url.path()=="/"?QString(""):url.path()), uri), after?index(after):count()); + else + { + KFileItem item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); + insertItem(new ListBoxLink(item.iconName(), size_, url.fileName().isEmpty()?url.prettyURL():url.fileName(), uri), after?index(after):count()); + } + } + } + else if (QTextDrag::decode(de, command, subtype)) + { + KURL url(command); + if (url.isValid()) + { + QListBoxItem *after = itemAt(de->pos()); + if (url.protocol() == "http") + insertItem(new ListBoxLink("html", size_, url.host()+(url.path()=="/"?QString(""):url.path()), command), after?index(after):count()); + else + { + KFileItem item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); + insertItem(new ListBoxLink(item.iconName(), size_, url.fileName().isEmpty()?url.prettyURL():url.fileName(), command), after?index(after):count()); + } + } + else if (command.contains('@')) + { + QListBoxItem *after = itemAt(de->pos()); + command.replace(" ",""); + insertItem(new ListBoxLink("kmail", size_, command, "mailto:"+command), after?index(after):count()); + } + else if (command.contains("'at'")) //last chance for anti-spam addy + { + QListBoxItem *after = itemAt(de->pos()); + command.replace(" ",""); + command.replace("'at'","@"); + insertItem(new ListBoxLink("kmail", size_, command, "mailto:"+command), after?index(after):count()); + } + } +} + +void DnDListBox::mousePressEvent ( QMouseEvent *mpe ) +{ + if (mpe->button() == Qt::RightButton) + { + currentItem = 0; + popupMenu->removeItem(0); + ListBoxDevice *device = (ListBoxDevice*)itemAt(mpe->pos()); + if (device) + { + currentItem = device; + popupMenu->insertItem("Edit link...", this, SLOT(configureLink()),0,0,0); + } + popupMenu->popup(mpe->globalPos()); + return; + } + if (mpe->button() == Qt::MidButton) + { + pasteURL(QClipboard::Selection, itemAt(mpe->pos())); + return; + } + ResizingLinkBox::mousePressEvent( mpe ); +} + +void DnDListBox::mouseReleaseEvent ( QMouseEvent *mre ) +{ + if (!dragging_) ResizingLinkBox::mouseReleaseEvent( mre ); +} + +void DnDListBox::mouseMoveEvent ( QMouseEvent * mme ) +{ + if (mme->state() & Qt::LeftButton) + { + if (!dragging_) + { + ListBoxLink *link = (ListBoxLink*)itemAt(mme->pos()); + if (link) + { + dragging_ = true; + BaghiraLinkDrag *d = new BaghiraLinkDrag( link->text(), link->URL(), link->icon(), index(link), this ); + d->setPixmap(*link->pixmap(),QPoint(22,22)); + d->drag(); + if (mme->state() & Qt::ControlButton || BaghiraLinkDrag::accepted()) + return; + poof(link); + // do NOT delete d. + } + } + } + else // ensure to release from drag + dragging_ = false; +} + +void DnDListBox::pasteURL(int mode, QListBoxItem *after) +{ + QString string = qApp->clipboard()->text( (QClipboard::Mode)mode ); + KURL url(string); + if (url.isValid()) + { + if (url.protocol() == "http") + insertItem(new ListBoxLink("html", size_, url.host()+(url.path()=="/"?QString(""):url.path()), string), after?index(after):count()); + else + { + KFileItem item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); + insertItem(new ListBoxLink(item.iconName(),size_, url.fileName().isEmpty()?url.prettyURL():url.fileName(), string), after?index(after):count()); + } + } + else if (string.contains('@')) + { + string.replace(" ",""); + insertItem(new ListBoxLink("kmail", size_, string, "mailto:"+string), after?index(after):count()); + } + else if (string.contains("'at'")) //last chance for anti-spam addy + { + string.replace(" ",""); + string.replace("'at'","@"); + insertItem(new ListBoxLink("kmail", size_, string, "mailto:"+string), after?index(after):count()); + } +} + +void DnDListBox::configureLink() +{ + if (currentItem == 0L) + return; + dialog->title->setText(currentItem->text()); + dialog->url->setURL(currentItem->URL()); + dialog->icon->setIcon(currentItem->icon()); + dialog->show(); +} + +void DnDListBox::updateLink() +{ + if (currentItem) + { + int index_ = index(currentItem); + bool wasSelected = isSelected(index_); + insertItem( new ListBoxLink(dialog->icon->icon(), size_, dialog->title->text(),dialog->url->url()), index_ +1); + removeItem( index_ ); + setSelected(index_, wasSelected); + } +} diff --git a/sidebar/dndlistbox.h b/sidebar/dndlistbox.h new file mode 100644 index 0000000..b84dbcc --- /dev/null +++ b/sidebar/dndlistbox.h @@ -0,0 +1,126 @@ + +#ifndef DNDLISTBOX_H +#define DNDLISTBOX_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include "baghirasidebariface.h" + +class DCOPClient; +class QDragEnterEvent; +class QDragMoveEvent; +class QDragLeaveEvent; +class QDropEvent; +class QKeyEvent; +class QPoint; +class KPopupMenu; +class LinkConfig; +class ListBoxLink; +class ListBoxDevice; +class QResizeEvent; + +class ResizingLinkBox : public KListBox +{ + Q_OBJECT + +public: + ResizingLinkBox( QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); + ~ResizingLinkBox(){}; + void insertItem( const QListBoxItem *, int index=-1 ); + void insertItem( const QListBoxItem *lbi, const QListBoxItem *after ); + void insertItem( const QString & icon, const QString & title, const QString & url ); + void insertItem( const QString &text, int index=-1 ) + { + insertItem( new QListBoxText(text), index ); + } + void insertItem( const QPixmap &pixmap, int index=-1 ) + { + insertItem( new QListBoxPixmap(pixmap), index ); + } + void insertItem( const QPixmap &pixmap, const QString &text, int index=-1 ){ + insertItem( new QListBoxPixmap(pixmap, text), index ); + } + + void removeItem( int index ); +protected: + void mousePressEvent ( QMouseEvent * ); + void mouseReleaseEvent ( QMouseEvent * ); + void contentsWheelEvent ( QWheelEvent * ); + KPopupMenu *popupMenu; + uint size_; +private slots: + void setIconSize(int); +signals: + void itemNumberChanged(bool); + void scrolled(int,int); +}; + +class MediaListBox : public ResizingLinkBox, virtual public BaghiraSidebarIface +{ + Q_OBJECT +public: + MediaListBox( QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); + ~MediaListBox(); + ListBoxDevice *createListBoxDevice(QStringList & deviceProperties, uint n = 0); + void mediumAdded(const QString &name); + void mediumRemoved(const QString &name); + void mediumChanged(const QString &name); + int index (const QString & name ); + void removeItem( int index ); +protected: + void mousePressEvent ( QMouseEvent * ); + void resizeEvent ( QResizeEvent * ); +private: + KPopupMenu *devicePopup; + DCOPClient *client; + ListBoxDevice *currentFloppy; + typedef QPtrList DeviceList; + DeviceList deviceList; + QStringList hiddenDevices; +private slots: + void kfloppy(); + void toggleDevice(int id); +}; + +class DnDListBox : public ResizingLinkBox +{ + Q_OBJECT + +public: + DnDListBox( QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); + + /** destructor */ + ~DnDListBox(); + void poof(ListBoxLink *link); + +protected: + void mousePressEvent ( QMouseEvent * ); + void mouseReleaseEvent ( QMouseEvent * ); + void mouseMoveEvent ( QMouseEvent * e ); + void dragEnterEvent ( QDragEnterEvent * ); +// void dragMoveEvent ( QDragMoveEvent * ); +// void dragLeaveEvent ( QDragLeaveEvent * ); + void dropEvent ( QDropEvent * ); + void startDrag(); +private: + ListBoxLink *currentItem; //TODO: unshadow int KListBox::currentItem() + LinkConfig *dialog; + bool dragging_; + void pasteURL(int mode, QListBoxItem *after = 0); + bool _draggedMe; + int _poofIndex; + QPixmap *_poofPix; + QPixmap *_poofAnimPix; + QWidget *_poof; +private slots: + void configureLink(); + void updateLink(); + void runPoof(); +}; + +#endif diff --git a/sidebar/eject.xbm b/sidebar/eject.xbm new file mode 100644 index 0000000..3230a26 --- /dev/null +++ b/sidebar/eject.xbm @@ -0,0 +1,9 @@ +#define eject_width 22 +#define eject_height 22 +static unsigned char eject_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x07, 0x00, + 0x80, 0x0f, 0x00, 0xc0, 0x1f, 0x00, 0xe0, 0x3f, 0x00, 0xf0, 0x7f, 0x00, + 0xf8, 0xff, 0x00, 0xfc, 0xff, 0x01, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, + 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/sidebar/linkconfig.ui b/sidebar/linkconfig.ui new file mode 100644 index 0000000..14ccf55 --- /dev/null +++ b/sidebar/linkconfig.ui @@ -0,0 +1,187 @@ + +LinkConfig + + + LinkConfig + + + + 0 + 0 + 403 + 164 + + + + Configure Link + + + true + + + + unnamed + + + + layout11 + + + + unnamed + + + + textLabel1 + + + <b>Title</b> + + + + + title + + + + + textLabel2 + + + + 5 + 5 + 0 + 0 + + + + <b>URL</b> + + + + + url + + + + + + + layout10 + + + + unnamed + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 206 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + icon + + + + 0 + 0 + 0 + 0 + + + + + 64 + 64 + + + + + 64 + 64 + + + + + + + 48 + + + false + + + + + + + + + buttonOk + clicked() + LinkConfig + accept() + + + buttonCancel + clicked() + LinkConfig + reject() + + + + + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + kicondialog.h + + diff --git a/sidebar/linkview.cpp b/sidebar/linkview.cpp new file mode 100644 index 0000000..8becf29 --- /dev/null +++ b/sidebar/linkview.cpp @@ -0,0 +1,199 @@ + +#include +#include +#include +#include +#include +#include +#include +#include "dndlistbox.h" +#include "listboxlink.h" +#include "linkview.h" +#include "linkview.moc" + +// internal class to eat invalid leave envents (i.e. leave that does not leave the rect but just enters the splitter, as styles (like baghira ;) may post install eventfilters that'd cause useless repaints and therefore flicker if the scroller appereance changes ;) +class EventKiller : public QObject +{ +protected: + virtual bool eventFilter( QObject *o, QEvent *e) + { + if (e->type() == QEvent::Leave) + return ((QScrollView*)o)->rect().contains(((QScrollView*)o)->mapFromGlobal (QCursor::pos())); + return false; + } +}; + +LinkView::LinkView(QWidget * parent, const char * name, WFlags f): + QScrollView(parent, name, f) +{ + setFrameShape( QFrame::StyledPanel ); + setFrameShadow( QFrame::Sunken ); + setBackgroundMode(Qt::PaletteBase); + _blocked = FALSE; + splitter = new QSplitter( Qt::Vertical, viewport() ); + addChild(splitter); + splitter->setMargin(5); + splitter->setBackgroundMode(Qt::PaletteBase); + splitter->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); + splitter->setFrameShape( QFrame::NoFrame ); + splitter->setChildrenCollapsible(TRUE); + splitter->setHandleWidth( 3 ); + splitter->setOpaqueResize(); + hardware = new MediaListBox(splitter, "hardware"); + splitter->setResizeMode( hardware, QSplitter::KeepSize ); + hardware->setFrameShape( QFrame::NoFrame ); + hardware->setHScrollBarMode(QScrollView::AlwaysOff); + hardware->setVScrollBarMode(QScrollView::AlwaysOff); + locations = new DnDListBox(splitter, "locations"); +// splitter->setResizeMode( locations, QSplitter::KeepSize ); + locations->setFrameShape( QFrame::NoFrame ); + locations->setHScrollBarMode(QScrollView::AlwaysOff); + locations->setVScrollBarMode(QScrollView::AlwaysOff); + // custom area, locations + loadLinks(); + locations->setCurrentItem(0); + locations->setSelected( locations->selectedItem(), false ); + hardware->installEventFilter(this); + connect (hardware, SIGNAL(highlighted( int )), this, SLOT(unselectLocations())); + connect (locations, SIGNAL(highlighted( int )), this, SLOT(unselectHardware())); + connect (hardware, SIGNAL(scrolled(int,int)), this, SLOT(scrollBy(int,int))); + connect (locations, SIGNAL(scrolled(int,int)), this, SLOT(scrollBy(int,int))); + connect (hardware, SIGNAL(itemNumberChanged(bool)), this, SLOT(adjustSplitter2Hardware(bool))); + connect (locations, SIGNAL(itemNumberChanged(bool)), this, SLOT(adjustSplitter2Locations())); + QTimer::singleShot(50, this, SLOT(adjustSplitter2Locations())); + QTimer::singleShot(60, this, SLOT(postInstallEventFilter())); +} + +static EventKiller *eventKiller = 0L; + +LinkView::~LinkView() +{ + + saveLinks(); + delete eventKiller; eventKiller = 0L; +} + +void LinkView::postInstallEventFilter() +{ + eventKiller = new EventKiller; + installEventFilter(eventKiller); +} + +bool LinkView::eventFilter(QObject *o, QEvent *e) +{ + if (o != hardware) + return QScrollView::eventFilter(o, e); + if (_blocked || e->type() != QEvent::Resize) + return FALSE; // not a resize - non of our business + QResizeEvent *rev = (QResizeEvent*)e; + if (rev->size().height() == rev->oldSize().height()) + return FALSE; // height didn't change + int tmpH = rev->size().height() + locations->numRows()*locations->itemHeight()+20; + if (tmpH < viewport()->height()) + tmpH = viewport()->height(); + if (tmpH != splitter->height()) + { + _blocked = TRUE; + splitter->resize ( splitter->width(), tmpH ); + _blocked = FALSE; + } + + return FALSE; +} + +void LinkView::adjustSplitter2Locations() +{ + int tmpH = hardware->height() + locations->numRows()*locations->itemHeight()+20; + if (tmpH < viewport()->height()) + tmpH = viewport()->height(); + if (tmpH != splitter->height()) + splitter->resize ( viewport()->width(), tmpH ); +} + +void LinkView::adjustSplitter2Hardware(bool added) +{ + if (added) + { + if (hardware->height() < hardware->numRows()*hardware->itemHeight()) + hardware->resize ( hardware->width(), hardware->numRows()*hardware->itemHeight() ); + } + else + if (hardware->height() > hardware->numRows()*hardware->itemHeight()) + hardware->resize ( hardware->width(), hardware->numRows()*hardware->itemHeight() ); +} + +void LinkView::viewportResizeEvent( QResizeEvent *rev ) +{ + int tmpH = hardware->height() + locations->numRows()*locations->itemHeight()+20; + if (tmpH < rev->size().height()) + tmpH = rev->size().height(); + splitter->resize(rev->size().width(), tmpH); +} + +void LinkView::unselectLocations() +{ + if (locations) locations->setSelected( locations->selectedItem(), FALSE ); +} + +void LinkView::unselectHardware() +{ + if (hardware) hardware->setSelected( hardware->selectedItem(), FALSE ); +} + +void LinkView::loadLinks() +{ + if (!locations) + return; + KConfig config(QDir::homeDirPath() + "/.qt/baghirarc"); + config.setGroup("Sidebar"); + splitter->setSizes(config.readIntListEntry ("Sizes")); + loadedLinks = (uint)config.readNumEntry("NumLinks", 0); + locations->blockSignals ( true ); + if (loadedLinks == 0) // no settings stored - load defaults + { + locations->insertItem("desktop", i18n("Desktop"), QDir::homeDirPath()+"/Desktop"); + locations->insertItem("folder_home", getenv("USER"), QDir::homeDirPath()); + locations->insertItem("kmenu", i18n("Programs"), "programs:/"); + } + QString num; + for (uint i = 0; i < loadedLinks; i++) + { + QString title; + QString icon; + QString url; + num.setNum(i); + title = config.readEntry("Link_"+num+"_Title", "???"); + icon = config.readEntry("Link_"+num+"_Icon", "empty"); + url = config.readEntry("Link_"+num+"_URL", QDir::homeDirPath()); + locations->insertItem(icon, title, url); + } + locations->blockSignals ( false ); +} + +void LinkView::saveLinks() +{ + if (!locations) + return; + KConfig *config = new KConfig(QDir::homeDirPath() + "/.qt/baghirarc"); + config->setGroup("Sidebar"); + config->writeEntry("Sizes", splitter->sizes()); + config->writeEntry("NumLinks", (int)locations->count()); + QString num; + for (uint i = 0; i < locations->count(); i++) + { + num.setNum(i); + ListBoxLink *current = (ListBoxLink*)locations->item(i); + config->writeEntry("Link_"+num+"_Title", current->text()); + config->writeEntry("Link_"+num+"_Icon", current->icon()); + config->writeEntry("Link_"+num+"_URL", current->URL()); + } + // reduced links, remove them from settings + for (uint i = locations->count(); i < loadedLinks; i++) + { + num.setNum(i); + config->deleteEntry("Link_"+num+"_Title"); + config->deleteEntry("Link_"+num+"_Icon"); + config->deleteEntry("Link_"+num+"_URL"); + } + delete config; +} diff --git a/sidebar/linkview.h b/sidebar/linkview.h new file mode 100644 index 0000000..ebe54ef --- /dev/null +++ b/sidebar/linkview.h @@ -0,0 +1,46 @@ + +#ifndef LINKVIEW_H +#define LINKVIEW_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +class ListBoxLink; +class DnDListBox; +class MediaListBox; + +class LinkView : public QScrollView +{ + Q_OBJECT + +public: + LinkView(QWidget * parent = 0, const char * name = 0, WFlags f = 0); + + /** destructor */ + ~LinkView(); + MediaListBox *Hardware(){return hardware;} + DnDListBox *Locations(){return locations;} + void loadLinks(); + void saveLinks(); + +protected: + void viewportResizeEvent( QResizeEvent * ); + bool eventFilter(QObject *, QEvent *); +private: + MediaListBox *hardware; + DnDListBox *locations; + QSplitter *splitter; + bool _blocked; + uint loadedLinks; +private slots: + void postInstallEventFilter(); + void unselectLocations(); + void unselectHardware(); + void adjustSplitter2Locations(); + void adjustSplitter2Hardware(bool added); +}; + +#endif diff --git a/sidebar/listboxlink.cpp b/sidebar/listboxlink.cpp new file mode 100644 index 0000000..47adb88 --- /dev/null +++ b/sidebar/listboxlink.cpp @@ -0,0 +1,78 @@ + +#include +#include "listboxlink.h" +#include +#include +#include "eject.xbm" +#include "lock.xbm" + +static QBitmap eject = QBitmap( eject_width, eject_height, eject_bits, true ); +static QBitmap locked = QBitmap( lock_width, lock_height, lock_bits, true ); + +ListBoxLink::ListBoxLink( const QString & icon, uint size, const QString & title, const QString & url): QListBoxPixmap(KGlobal::iconLoader()->loadIcon(icon, KIcon::Desktop, size), title),url_(url),icon_(icon) +{ +} + +ListBoxLink::ListBoxLink( const QPixmap & pixmap, const QString & title, const QString & url) : QListBoxPixmap(pixmap, title), url_(url), icon_(0) +{ +} + +ListBoxLink::ListBoxLink(ListBoxLink & link) : QListBoxPixmap(*link.pixmap(), link.text()), url_(link.URL()), icon_(link.icon()) +{ +} + +ListBoxLink::~ListBoxLink() +{ +} + +void ListBoxLink::setURL(const QString & url) +{ + url_ = url; +} + +void ListBoxLink::setIcon(const QString & icon) +{ + icon_ = icon; +} + +int ListBoxLink::height ( const QListBox * lb ) const +{ + return (QListBoxPixmap::height ( lb ) + 4); +} + +ListBoxDevice::ListBoxDevice(const QString & icon, uint size, const QString & title, const QString & url, const QString & name, const QString & mountPoint, bool mounted, bool ejectable, bool removable, int id) : ListBoxLink(icon, size, title, url), name_(name), mountPoint_(mountPoint), mounted_(mounted), ejectable_(ejectable), removable_(removable),id_(id) +{ + if (!eject.mask()) + eject.setMask(eject); + if (!locked.mask()) + locked.setMask(locked); +} + +ListBoxDevice::ListBoxDevice(const QPixmap & pixmap, const QString & title, const QString & url, const QString & name, const QString & mountPoint, bool mounted, bool ejectable, bool removable, int id) : ListBoxLink(pixmap, title, url), name_(name), mountPoint_(mountPoint), mounted_(mounted), ejectable_(ejectable), removable_(removable),id_(id) +{ + if (!eject.mask()) + eject.setMask(eject); + if (!locked.mask()) + locked.setMask(locked); +} + +int ListBoxDevice::width ( const QListBox * lb ) const +{ + if (ejectable_ && mounted_ && lb) + return lb->width(); + return ListBoxLink::width(lb); +} + +void ListBoxDevice::paint( QPainter * p ) +{ + if ((ejectable_ || removable_) && mounted_) + { + p->save(); + ListBoxLink::paint(p); + p->setBrush(isSelected()?listBox()->colorGroup().highlightedText():listBox()->colorGroup().text()); + p->drawPixmap(listBox()->width()-22, 11, ejectable_?eject:locked); + p->restore(); + } + else + ListBoxLink::paint(p); +} diff --git a/sidebar/listboxlink.h b/sidebar/listboxlink.h new file mode 100644 index 0000000..6614920 --- /dev/null +++ b/sidebar/listboxlink.h @@ -0,0 +1,64 @@ + +#ifndef LISTBOXLINK_H +#define LISTBOXLINK_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +class KListBox; +class QPainter; +class QPixmap; +class QStringList; +class KURL; + +class ListBoxLink : public QListBoxPixmap +{ +friend class DnDListBox; + +public: + ListBoxLink(const QString & icon, uint size, const QString & title, const QString & url); + ListBoxLink(const QPixmap & pixmap, const QString & title, const QString & url); + ListBoxLink(ListBoxLink & link); + ~ListBoxLink(); + QString & URL(){return url_;} + void setURL(const QString & url); + QString & icon(){return icon_;} + void setIcon(const QString & icon); + int height ( const QListBox * lb ) const; + +private: + QString url_; //TODO: make this KURL?! + QString icon_; +}; + +class ListBoxDevice : public ListBoxLink +{ + friend class MediaListBox; +public: + ListBoxDevice(const QString & icon, uint size, const QString & title, const QString & url, const QString & name, const QString & mountPoint, bool mounted, bool ejectable = FALSE, bool removable = FALSE, int id = 0); + ListBoxDevice(const QPixmap & pixmap, const QString & title, const QString & url, const QString & name, const QString & mountPoint, bool mounted, bool ejectable = FALSE, bool removable = FALSE, int id = 0); + ~ListBoxDevice(){}; + QString & name(){return name_;} + bool mounted(){return mounted_;} + bool ejectable(){return ejectable_;} + bool removable(){return removable_;} + QString & mountPoint(){return mountPoint_;} + int id(){return id_;} + int width ( const QListBox * lb ) const; + +protected: + void paint( QPainter * p ); + +private: + QString name_; + QString mountPoint_; + bool mounted_; + bool ejectable_; + bool removable_; + int id_; +}; + +#endif diff --git a/sidebar/lock.xbm b/sidebar/lock.xbm new file mode 100644 index 0000000..6f7caaf --- /dev/null +++ b/sidebar/lock.xbm @@ -0,0 +1,9 @@ +#define lock_width 22 +#define lock_height 22 +static unsigned char lock_bits[] = { + 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0xf8, 0x7f, 0x00, 0x3c, 0xf0, 0x00, + 0x0e, 0xc0, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, + 0x06, 0x80, 0x01, 0x06, 0x80, 0x01, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, + 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0x03, 0x00, 0x03, 0xff, 0xff, 0x03, + 0x03, 0x00, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, + 0xff, 0xff, 0x03, 0x00, 0x00, 0x00 }; diff --git a/starter/Makefile.am b/starter/Makefile.am new file mode 100644 index 0000000..6fee0e8 --- /dev/null +++ b/starter/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES= $(all_includes) +METASOURCES = AUTO +KDE_ICON = AUTO + +lib_LTLIBRARIES = libbaghirastarter.la + +libbaghirastarter_la_SOURCES = baghiralinkdrag.cpp menu.cpp starter.cpp starterconfig.ui starterhelp.ui config.ui help.ui linkconfig.ui starteriface.skel +libbaghirastarter_la_LDFLAGS = -module -avoid-version $(all_libraries) +libbaghirastarter_la_LIBADD = -lXtst $(LIB_KDEUI) + +starter_DATA = starter.desktop +starterdir = $(kde_datadir)/kicker/applets +poof_DATA = ../imagebase/poof.png +poofdir = $(kde_datadir)/baghira + +messages: rc.cpp + $(EXTRACTRC) *.ui >> rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/starter.pot diff --git a/starter/Themes/Apple Aqua/bStarter.png b/starter/Themes/Apple Aqua/bStarter.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb6924fc70f23a1655993ee95702a68373ba118 GIT binary patch literal 1099 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 IM6N<$f`qo_82|tP literal 0 HcmV?d00001 diff --git a/starter/Themes/Apple Graphite/bStarter.png b/starter/Themes/Apple Graphite/bStarter.png new file mode 100644 index 0000000000000000000000000000000000000000..6fcac0e1eaacbfed8e356aa8743889a952e3ebf3 GIT binary patch literal 1363 zcmV-Z1+4msP)KgvRmdi|x0r<9NRN z@UuJbA1wd~iwI;6`%!WchPoFemfDq|nHdliF$-KVn5k90dD1*NySwq>7kAco8)v_7 zZr#7TL4*i1q7{(rQ-&yx<2cp*C=$8!3jzv&FcT3V4)ZXBXvXuj)jmEwTU%ND`tuE~ zX#cR;kK7a3+-$roMIF>GgV!<0z$0 zT4%3H451K94(KoNJuCJ{osoAeL+ud%t6lhh%)%FA8AbrAu zh=z@bXv3UuF#xN#9Z4fnWkyKAAR-U z)0Jw;vYduzJN2FYLuL_?0*{tu=2UXf6M1A8MDdts5fSmtQ$E)5%PC1rr`uhe_Y1-ifL53sHk!;5#c{bDIF3_5 z6aZqAh=@`O23>Dl$Ip1-=CdBi0=OXMC6UE^Gw^~|I z-e}b7!vY;k;w1nGBA#{n#Z%TJ_~heTNs>fyVr-pGLFU>p8)jxU#xS#p5RSo`X2-A) zZ20xt#&98+q$mO+{P^9Ydv|WRjx+OuLqsCVy2}1JQuIn#)-+FdngXO~>z|!*`LCc> zE&uTCqlIckW-T`v2P=e9N-0ItCS?{-F$ggTf;YSSr=7kjGM~;epI~IW{6a&AFA4(R(GJlJ zQCUQotvW=603x8R+EdoN(cyxURi0a&pW8odL~&eOUX0_UdD7~1FI>l2sVyzcR~pUJ z`qA-Rr5yNvF-z-9Au2){E^erG*z0ShDC_K@DZy|*u(Dn;7)L4aw5Ib;w{_lT7T@z~ zON(im9@d-nMpG$TT9|iTXXfH;-6^HAezH50<7hqnitB*e$eCHXgltTZv1VPa2^+?*^N+~Jj zZwyE&9mnbS`@aOLl(KD``MwW7!vA56rIZ+BjIq|9==AY;e06noa&of1zJ7Fcl%c6j zqzUJobIv@^O9UaMB!s{zlcJPT-rU?AA0H2g!=0TS&+{^r3HgaC7z&%i7<0~r5R7vk z#{qXVqmu$1jYi#Wx7X_}FE4LxZE?;gVpJ)ml+xCH-xor#AP6E*G|KQnxmZV|QNQ1J zUAI=N5kd^ZXti3+W^*_kzQ4aW8V$>`a-*!RXqqv`LI^1(6G8y|h?nYH;5ysJ9Bj6{kA5P-t{WT2XPl$V`B5S*QzWtR&=XmfLO zcXxMsdK&0SI}=c%Q2A?NiO=Ypx#=&ZyuZKC9Sw(vhn8hQJ!E(u?l$2BKnQ(ReZ05F zM?fNIA;fq*MtL$fHwVR=tp-NHA4)0uu6n~T*vrdHB2Yp|IP_^ieczv&nu=s(Tpk`C zs?}<4(noBC9s6r4gyRzTUL^@as8lNDW=N;gaa~vCi8ieT;-HiwI3}PPPSZ4j#$K=2 zbAh(o?M|m-+jgS4u)wjps^I4jqY<}2H4Hb614`-Y>S}IGZQE|Q+i!1gx}G8|M&hOk zqLflfNtyxeP;N?Lj8|4xDwRquR>qiN7;&{YyLuw(Yas+ljOkbY5(3m_OSM{UwOW>C zWdq&V*r?TNfHf`jI-}qd3Ln}&BZMT9r+2(;cER<%y}j4h*KW5Po=;&}T3XuP-Yyo4 zD6cn%%>n&F2udl_-8C^H|B?w(%Guf3gM$Oc*kCZAl$Oh7(=ve>X@B48U<3M$J09K_`0?^0`^DjV!5Nm5|#bR+V7?`HnXf!I7%4jrtdV2c&{9IUA zXf~Uib9kFbYsr!5>$%Sua~ua>US6hEpH8Ffxd(njt-$7?cNzc`1cC4SK@g-ZKoOLb zQe98*NDu@pvQDG#*Shcm6;VhO=*+O4#AEW+v|}Y7-$x-nV380agaC)xU@(Xep~!mw o%h%C~1o}7n&Nm?hV~lhD2hrt;m}%IOCIA2c07*qoM6N<$f|QE(HUIzs literal 0 HcmV?d00001 diff --git a/starter/Themes/Apple Graphite/bStarter_hover.png b/starter/Themes/Apple Graphite/bStarter_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..914c5b8316f118f25660d7e4649cf18f05d2bbfb GIT binary patch literal 1564 zcmV+%2IKjOP)W_PE%%7>m^E?1n9PcAe- zVESX%S6_8i*V3JP|G{ZfRZ$U9FItWx{6HfR(X-zadKy9nXNby(0~E}}%-y87eD^Ec zYIi5RsH&)nsPi(gDRCZ+JjO(fC!5Xt_aDZka-~|j{r0U>Lq>WoK2Em*c?}1HHdFQx+eg6RKuVB{R6}NldG2v z^I!jU@0)KPP1UB8q|Z!v-u+Qk03w|Ls@{L~@bUWU+Pw#lo!2x?S65aRFD+X8oYKs^5SW;V6iP(SIT5kWI~5R( z@d&Y~iiiS4GzmC;^#0!d?(Y7={0o;CU#wQk7iVhUZZ_998r4c^>BiM7moNAFZuNf~ z2Zu-Xdd*r}Ks0E{1T_WjeT#uP;lAWa92%|^9adG8OuyS8v4vIanXu6|{1X&hFr#W$}n{`<4a z>iPyiwOXwp`2gv#H+e6^CZ*Q7H0OWFdmm)WCz|$q$*W zD&D(17!ikJ_MSrVdkWO*OIYMumIBpzpqNsC8r}g4&wV>yyqIuYVy4_5@PY3;4y&lDJ zVdQYm0Wih{zuvhhF4^YRR?z$uQ35lI_W*^|j{`=Qe{IIINf)NeHjZ7AfcS9#pxtWc zM-_Y#u>m07kNP*CU{t~ioiwnV%;Drx5O42xiyzpk!Ovb^^4_JcFY3=aXXF|HL`1w3 z??t@#UPM%tiI|9qPZj_XKYBKw1&kImiT7VVT=9}ya6}-&pZ@snOD``)wiJ#mSVYXm z5OKJBM9gdem{)K87RX-oY-KH(guJ``RrFrlC;c=^zB(b&U z&rMe=m7}BMKY#F1tJ5u&D>jOmi(U~T3gb{vhnZoms#;>A)2~G~YK_7sP~me@DjA(V zzp=6L{y&n1g@t~vzq7sFY8}UMJU2f-J3I5_+s4zKX0=u?SE|Jb$eGBZ1urfFkqtJ&BxWX@ffiQ@Qq zKbR2QnbC{~@?M~b;>d;gN@2rj7p#MD)9<$OBewcFr O0000N=q?L{6?i_yeLVpRxD3nbV@LS3LNSYQ`+x$K46oy(cy!vgWiv zJ7*^O&TqcV_n+?o|8XPtEARuomnx~G^l&pXKKtFbz23<~^ahMSgwcm(b9_m*2quOb!)qDu=7c9C?M-wm;N; z{8-IPjrD;BDiCdLb9;JbemP{a^jXTXEo!lntq-<<5s5CYBxB)Q(SgM3Uwz5(_mc$< zSWOzAzxYOPPuqKEo_tVMJqiqqBbm{$63>|NjkMt^mgRu2gbGw3hQ+X%%wjaOY>kdD ze6==v=$W*v%HhQ%dK*0hERYyu+eWbIlLgxgjvC02K&Cfk31LA{F+0iBckq#ZI@kZZI}Clqpz1EfHa*ZBL(4T;67n#{rj9hC>#i zNc3MXS*CC*N{#BT_5|CXo0u8zPZy?4*jgr=j1DQm;F&;)LMgqA_vZp-p1}Di(?kFl z0OSf%=+|aPey(fom@9FXHOWPH{;Nwsu#wJU`PRtxe(r1E0b@75pGkB+^|f`h=3~9e#!+s06=6nS2lIi-VnXD5BvQ-)#Z?&=@y?~iksoN+nM;*HX~FL z9dZ$|K@eVy8&`hl`ziF}#~%Vba#+q}imN+LztDK%+1I?PuWCISS)C7!{Js^7L}ZsL zS2cCDRtDQzh#)HSlOq#z*9JakhBgYoJWPj9P5?~+sRZ~sfCT`_okm*)P`mTY;?6x2 c|J&W!-vj;Y0J{fk=Kufz07*qoM6N<$f=KopfdBvi literal 0 HcmV?d00001 diff --git a/starter/Themes/Apple Panther/down.png b/starter/Themes/Apple Panther/down.png new file mode 100644 index 0000000000000000000000000000000000000000..69e2884ef3e3963fa92cca99d7c9de3a7820d8ae GIT binary patch literal 915 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 TIffIF00000NkvXXu0mjfOPNN* literal 0 HcmV?d00001 diff --git a/starter/Themes/kickerbg-g.png b/starter/Themes/kickerbg-g.png new file mode 100644 index 0000000000000000000000000000000000000000..a59138ff6049769490c3bfb409c6949adba391fc GIT binary patch literal 2961 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 Hu0mjfVwj=S literal 0 HcmV?d00001 diff --git a/starter/baghiralinkdrag.cpp b/starter/baghiralinkdrag.cpp new file mode 100644 index 0000000..9c54011 --- /dev/null +++ b/starter/baghiralinkdrag.cpp @@ -0,0 +1,125 @@ +#include +#include "baghiralinkdrag.h" + +static bool _accepted; + +#define _TLO_ 0 +#define _TO_ 4*sizeof(int) +#define _CLO_ 1*sizeof(int) +#define _CO_ 4*sizeof(int) + title.length()*sizeof(QChar) +#define _CO2_ 4*sizeof(int) + title->length()*sizeof(QChar) +#define _ILO_ 2*sizeof(int) +#define _IO_ 4*sizeof(int) + (title.length()+command.length())*sizeof(QChar) +#define _IO2_ 4*sizeof(int) + (title->length()+command->length())*sizeof(QChar) +#define _IxO_ 3*sizeof(int) + +BaghiraLinkDrag::BaghiraLinkDrag(QString title, QString command, QString icon, int index, QWidget* dragSource) : QDragObject(dragSource, 0) + +{ + _accepted = false; + a.resize((title.length()+command.length()+icon.length())*sizeof(QChar)+4*sizeof(int)); + + QChar* tmpChar; + int tmpLength; + + tmpChar = const_cast(title.unicode()); + tmpLength = title.length(); + memcpy(a.data(), &tmpLength, sizeof(int)); + memcpy(a.data() + _TO_ , tmpChar, tmpLength*sizeof(QChar)); + + tmpChar = const_cast(command.unicode()); + tmpLength = command.length(); + memcpy(a.data() + _CLO_ , &tmpLength, sizeof(int)); + memcpy(a.data() + _CO_, tmpChar, tmpLength*sizeof(QChar)); + + tmpChar = const_cast(icon.unicode()); + tmpLength = icon.length(); + memcpy(a.data() + _ILO_, &tmpLength, sizeof(int)); + memcpy(a.data() + _IO_, tmpChar, tmpLength*sizeof(QChar)); + + memcpy(a.data() + _IxO_, &index, sizeof(int)); +} + +BaghiraLinkDrag::~BaghiraLinkDrag() +{ +} + +bool BaghiraLinkDrag::decode( const QMimeSource * e, QString * title, QString * command, QString * icon, int * index) +{ + QByteArray a = e->encodedData("application/baghiralink"); + + if (a.size() < 4*sizeof(int)) // some empty stuff + { + return false; + } + + QChar* tmpChar; + int tmpLength; + + memcpy(&tmpLength, a.data(), sizeof(int)); + tmpChar = new QChar[tmpLength]; + memcpy(tmpChar, a.data() + _TO_, tmpLength*sizeof(QChar)); + title->setUnicode(tmpChar, tmpLength); + delete tmpChar; + + memcpy(&tmpLength, a.data() + _CLO_, sizeof(int)); + tmpChar = new QChar[tmpLength]; + memcpy(tmpChar, a.data() + _CO2_, tmpLength*sizeof(QChar)); + command->setUnicode(tmpChar, tmpLength); + delete tmpChar; + + memcpy(&tmpLength, a.data() + _ILO_, sizeof(int)); + tmpChar = new QChar[tmpLength]; + memcpy(tmpChar, a.data() + _IO2_, tmpLength*sizeof(QChar)); + icon->setUnicode(tmpChar, tmpLength); + delete tmpChar; tmpChar = 0L; + + memcpy(index, a.data() + _IxO_, sizeof(int)); + + return true; +} + +bool BaghiraLinkDrag::accepted() +{ + return _accepted; +} + +bool BaghiraLinkDrag::canDecode( const QMimeSource * e ) +{ + return e->provides("application/baghiralink"); +#if 0 + if (!e->provides("application/baghiralink")) + { + return false; + } + QByteArray a = e->encodedData("application/baghiralink"); + if (a.size() != BAGHIRALINK_BUFSIZE) + { + return false; + } + return true; +#endif +} + +void BaghiraLinkDrag::setAccepted() +{ + _accepted = true; +} + +const char * BaghiraLinkDrag::format ( int i ) const +{ + if (i == 0) + { + return "application/baghiralink"; + } + return 0; +} + +QByteArray BaghiraLinkDrag::encodedData ( const char * mimeType) const +{ + if (QString("application/baghiralink") == mimeType) + { + return a; + } + return QByteArray(); +} diff --git a/starter/baghiralinkdrag.h b/starter/baghiralinkdrag.h new file mode 100644 index 0000000..3aca9ec --- /dev/null +++ b/starter/baghiralinkdrag.h @@ -0,0 +1,24 @@ +#ifndef _BAGHIRALINKDRAG_H_ +#define _BAGHIRALINKDRAG_H_ + +#include +#include + +class BaghiraLinkDrag : public QDragObject +{ +// Q_OBJECT + +public: + BaghiraLinkDrag(QString title, QString command, QString icon, int index = -1, QWidget* dragSource = 0); + ~BaghiraLinkDrag(); + static bool decode( const QMimeSource * e, QString * title, QString * command, QString * icon, int * index); + static bool canDecode( const QMimeSource * e); + static void setAccepted( ); + virtual const char * format ( int i = 0 ) const; + virtual QByteArray encodedData ( const char * ) const; + static bool accepted( ); +private: + QByteArray a; +}; + +#endif diff --git a/starter/config.ui b/starter/config.ui new file mode 100644 index 0000000..ebc7956 --- /dev/null +++ b/starter/config.ui @@ -0,0 +1,575 @@ + +ConfigDialog + + + ConfigDialog + + + + 0 + 0 + 658 + 629 + + + + New Entry + + + true + + + + unnamed + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + F1 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + buttonDetail + + + Extended Mode + + + true + + + + + baseGroup + + + GroupBoxPanel + + + Basic Settings + + + + unnamed + + + + category + + + true + + + AfterCurrent + + + true + + + false + + + false + + + + + textLabel2 + + + Is a + + + + + appName + + + + + command + + + + 1 + 0 + 0 + 0 + + + + + + genericName + + + + + iconButton + + + + 0 + 0 + 0 + 0 + + + + + 60 + 60 + + + + + 60 + 60 + + + + + + + false + + + 48 + + + + + textLabel5 + + + <b>Command</b> + + + + + textLabel1_2 + + + <i>Keywords</i> + + + + + textLabel1 + + + <i><b>Name</b></i> + + + + + textLabel4 + + + <i><b>Category</b></i> + + + + + keywords + + + + + startupFeedback + + + Activate startup feedback + + + + + showInSystray + + + Show in system tray + + + + + description + + + + 3 + 3 + 0 + 0 + + + + + 0 + 0 + + + + + + textLabel3 + + + Description + + + + + line4 + + + VLine + + + Sunken + + + Vertical + + + + + + + extendedGroup + + + Extended Settings + + + + unnamed + + + + textLabel7 + + + Working directory + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + startInTerminal + + + Start in terminal + + + + + textLabel9 + + + false + + + Terminal settings + + + + + terminalSettings + + + false + + + + + line2 + + + HLine + + + Sunken + + + Horizontal + + + + + startAsUser + + + Start as different user + + + + + textLabel6 + + + false + + + Username + + + + + username + + + false + + + + + line3 + + + HLine + + + Sunken + + + Horizontal + + + + + textLabel8 + + + Shortcut + + + + + workingDir + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 250 + 20 + + + + + + shortcut + + + None + + + + + spacer3 + + + Horizontal + + + Fixed + + + + 31 + 20 + + + + + + + + + + + + buttonOk + clicked() + ConfigDialog + accept() + + + buttonCancel + clicked() + ConfigDialog + reject() + + + startInTerminal + toggled(bool) + textLabel9 + setEnabled(bool) + + + startInTerminal + toggled(bool) + terminalSettings + setEnabled(bool) + + + startAsUser + toggled(bool) + textLabel6 + setEnabled(bool) + + + startAsUser + toggled(bool) + username + setEnabled(bool) + + + buttonDetail + toggled(bool) + extendedGroup + setShown(bool) + + + buttonDetail + released() + ConfigDialog + adjustSize() + + + + appName + genericName + category + command + keywords + startupFeedback + showInSystray + iconButton + description + buttonDetail + workingDir + startInTerminal + terminalSettings + startAsUser + username + shortcut + buttonHelp + buttonOk + buttonCancel + + + + kcombobox.h + klineedit.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + klineedit.h + kicondialog.h + klineedit.h + ktextedit.h + klineedit.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + kkeybutton.h + + diff --git a/starter/cr22-action-bStarter.png b/starter/cr22-action-bStarter.png new file mode 100644 index 0000000000000000000000000000000000000000..51c829f8a2eac4305bd74829b0fa26ec8696bf9d GIT binary patch literal 1209 zcmV;q1V;ObP)8cV97jmbE<^Ln3!Wbo}-G#&7H4qTYwaPB$(^K$=3NGTQn zW6_el%yAsn*4EhB+4-YhDTPwW=F13zAd!n)*X7QgJJ`03VHlK3C5|6I9_!cF*LnK% zDMAQJr4mPv9!;hKVHlFcdGX=}pFe*_N{Qn*%+Jr`c^+XH^5)GO78e(>Z5!LRSzcZy zDZh!eP_0&@*XtprL`q4s*`!*n0W z>h(JLe4cu}PBxoG2!RlSPN$RDJQzZVL;#GAj`Hl;Gn7(jnnn-=c%DbI*#w~1>!Is9 zuIrM`W-$ySnHlJ3Vzaf*`=QZ5+qp z)TvVp>i5?(Pz97y%+1Zk!B0+3GCe)b>C>lKTU#TQN?}@g9i_C`SN9Qxg4K9ed5fSGi0+_04`j(!0PHM zxm=E`SFe)EWGI)*tgo+QSr!*BUSwosWFP>d+wJapk~TIrxO?|*3?P+Ckxr+Xot^zx z8{hXa3pI)p+hj5sq?EjR^@y28}~(Zf+(*#g5}}`}S?x?KYaGA%s9FMHEGZVMu>zoSB*7-o1M?8V&OKJlC&Z zXMBA8?=$h@;v!pHTXFDx`4NDWk_QhSaP#I(TCEm^LSfI0Y-rlv_qkfFM!8%@*Y%$O z^w}~DLtNJ-2m)TeeoeJnrC2QfJtF&69zA+QyWJ*}$&gB=egY5#0lx1OMNtgs$&)9X zIC0{?0l@P-UcP*Z@B4JST{KOL+oB)vk3NJDynFX9{@ycyy|z#kMYyg@7=}bqgr;fn zuHRpu`#$>r!^6YB&B~x6I-QP6qJ{3?zmIL(=(^64BS)B+n4nlJl1inhR4P1w{v6Nq z7#| zK~z}7)tJj`B*z`cKUG~lt$FD&(rDj$>}oB0jlwQ?6D9Z+Hn%l~n1Jy$2_Zfh495S0 zF@!)8atP$$Qy>R}+t&RX#{r5!w@lIv zSjp~@rOoc{E@2pwbuCf#v(eUo*24l=YX7Uz_B>qIMM}w(7ZcPfoS*AaE+0rNgrHKX z5C$$|dV~P3J1l@;w`n;W1f)_agb=u{i|y8#a3sF(<2VjlYd%@OPb$AM^qNNi3|jY} zNqHyY%6yOedm;a6PP5j?v3hbJr4)|iP^vbFO^W?ii{h9IaWO zLW1kk*HBKvtCs_wUygbCvf;bw8^lvf{Q1TfaU2tdAs?<)$rVpWcmuYGhtf`SB<>Q7G@?o)I-luAvMQarPi=HqMk*(yB6o4IkYuVb`#9GU_c%3_( z#c@-E1B5|;)3nZUbM133F3;h49$ITAoGyON#~Uw#3k4@;Jk{ggzJtmyqVgb;kV}(3 zo0|=cF$f{()OKjg4yo+G00E`V@&39_lHycGx>BQDcLoP=JCSy4Qd6Dtk}!_6KkA z+-etq_x`=l^yM*r@j^t#*131DhB1aQoA8sB3ctGU(`gx+%_dP4VT@sY{WCWFS+X{b z?F|CZJ4m5)w*RSP={YLyOZ@V0e0mv?yg+85*=e}&ArJ4_LqfdD{~&Mh-_W)W)>e*8oiH!4xt+k0r#j4>Ev zh~t>tnB+T!yZr7JOti04X+!41OH9q5M>>O_0}2cSHGl(i0G`Kjx534!J+{9nVXb`# z@P7rg*7SNkmXA5y>72sPe2)`emQ-#AF_gVFhbfd9!bVujYVLE^?`|LHa%4l+TC~<^ ztue+RrDREMuzBiPq)Lt8BtA@`q3moNFq4$2*Xu|rADTIUBuT!ah!BD^InCY14(XZs zkyr@@hG9O2?6zn%>u9Z!QWD28LI|w2SZh&AA*Fl>5r!d2QbVOi24Dv);=@K})BNRw z4IV2ha@j1+R*MIfI;H&%%`Ox&ij{>T^QTX;Q>pU)-8#pw7Kd8%NCF=K6lRAAF*8B! z=^ya^KmST^tBTBwlb>5<`pNU0nLb9Z-Qwf_-sJkNPa!?Q;tM}w=G-ZS92tONe5l)< zWPIvz=DzU=Ce}ztA&=Anz`~_R(NTzW6w32Pb{__VAor1lV_(ysDiyv2U&2FPe%ZV( P00000NkvXXu0mjfe}S7< literal 0 HcmV?d00001 diff --git a/starter/cr22-action-bStarter_hover.png b/starter/cr22-action-bStarter_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6932d46cbc3b85237ac5a835103d5512d8464a GIT binary patch literal 1410 zcmV-|1%3L7P)#H7?ARWAJn?vDddA(`)m_EG#@gjJ zKbN#rr;@&^NAFu-z14!8wS0y@1@Ow!V2b%VB%g%rsu6_i-al#W(U5XroBz@LF+jc6 zf3aNJ;l+yr8^fDRxB07_#Tm*1Fp?hf++;#FJ>++b0SBd7gb;&MAUNp1&=;~zf_g#_ z1bnXOapUG&G|yeZv6`!MhZNG7AP9Ig-s0NU7+$V85P*T`X^p`ND(vm;5k(PE6fu=n zNTLoGof>}HW_Nd&Fbo-1mQH15uxCK){)(8?vftXLEHk*Si5hn-r3G~>|-T9lMRYfY!q;iGEA(85ID zsvm2QgcR4MtD&5fs~0Ns*6>L zH{bbyp!^8gQju}5&4>uPUi;nwDGE}Q*QK8A14`nM?d>K?DZV`IbNhok)XqJ@&t83% zsNJG)`DwDJPjRO+#jjucBVn^n)t_SiTTk-cnKqXve0Hi;e(~Nmarsh@3LFD;>&G~a zSX*1e_kCQ~MF_!}XaoD;cPLK2j7c;@`4Un&oSuD%AeX}n+bm3+=c&^X3q{Mu#yZwo zCWB=*$`^24uXlj3(=9-bcNahA(Ya|dnG9NMMz~As(*VCXhH#)jLXMdA(7`Lt;1xln zAqztR>+21SF$f`O*LDa-56R?u2I%mYYxyqwevZ{ZF*>wKsZ>HK#pYIn8~=_OE2sSU zS-F|B~4S5G<@&z z5Bd3xG9RsOFx&0hsgP-j!h4|Td?3o#?N%_Gy?lPpesn%*I zLCqM0F@_{b81W@fo?YTse}}Q;UsM|4TzH4T5F6kNGVwuS>yfU6{PY8a1$R}NcE9RWYS^6sZg)iky4(7Ie;`x?^8qw!MUR5 z-Ear5bZ#I~qE8EfN?HVsI$CR_lq5-l5CUs0)>@QONGVSsqA(9iidq_V|?tw2+xID*rX&l{Y@t>u)`Nvy}SiivZx35x~nMBBe0T}Xq zz3wFW(FLX-zDSyAq*6G_y|24WKX!>E3XkTz%)s8mU=ZZqu`vD_{i#yrzc^<{b(+M2 QZ2$lO07*qoM6N<$f}@YF-v9sr literal 0 HcmV?d00001 diff --git a/starter/help.ui b/starter/help.ui new file mode 100644 index 0000000..dbb5416 --- /dev/null +++ b/starter/help.ui @@ -0,0 +1,123 @@ + +HelpDialog + + + HelpDialog + + + + 0 + 0 + 600 + 480 + + + + Help + + + + unnamed + + + + kTextEdit2 + + + LineEditPanel + + + Sunken + + + 0 + + + <p align="center"><font size="+3"><b>Menu entry editor</b></font></p> +<p align="center">----------------------------------------------------------------------------------</p> +<h3>Introduction</h3> + +By default, you will only see the basic settings for the new entry. Clicking "Show More" will give you access to some extended settings that can be interesting but mostly useless for you.<br><br> +<b>Bold options must be entered</b> for a usefull entry, i<i>talic ones are respected by the search feature</i>. +<br><br> +<h3>Basic settings</h3> + +<b>Name:</b><br> +This is the visible name of your new entry and can be any string, e.g. "The Gimp".<br> +(Necessary, searchkey) +<br><br> +<b>Is a:</b><br> +Describes the applications genre (generic name), e.g. "Image manipulation"<br> +(Optional, yet not searched - maybe later) +<br><br> +<b>Category:</b><br> +Choose an existing group or add a new one. The hierarchy is represented by seperating slashes ("/"), if you want to enter a slash, you must escape it ("\/")<br> +(Necessary, searchkey) +<br><br> +<b>Command:</b><br> +The command to start the application, e.g. "gimp-remote". On *nix systems, is usually not necessary to pass the full path to the executably, but you can do so, if you want to start an executable that is shadowed by the executable in the path dir, e.g. "/usr/local/gimp-1.3/gimp-remote"<br> +(Necessary, not searched) +<br><br> +<b>Keywords:</b><br> +Comma separated list of keywords that refer to this application during search, e.g. "image manipulation,pixel,photoshop".<br> +Please note:<br> +1. search is <i>not</i> case sensitive<br> +2. search finds partial matches, so it's <i>not</i> necessary to add e.g. "image,image manipulation"<br> +3. different from the applications name, the keyword list will be translated (if) so if you think like "'KImage' allready contains 'image', so i don't need it as keyword" <b>you're wrong!</b><br> +4. Finding good keywords is not simple, but in general use striking ones! "editor" is not a very good keyword, as allmost everything is an editor. (Gimp is a pixel-editor, KHexedit is a hex-editor, KEdit is a text-editor, a config dialog is a config-editor, ...)<br> +(Optional, searchkey) +<br><br> +<b>Description:</b><br> +This is the longtext description of your application (not a helptext, though ;), e.g. "A powerfull image manipulator with a UI similar to photoshop. Supports Layers, filters, scripting, blahblahblah..." +You can use Qt richtext tags and there's no limit on the size, but keep it usefull ;) let's say something about 200 chars at max.<br> +(Optional, not searched) + + + true + + + false + + + + + buttonClose + + + Close + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 231 + 20 + + + + + + + + + + buttonClose + released() + HelpDialog + close() + + + + + ktextedit.h + + diff --git a/starter/linkconfig.ui b/starter/linkconfig.ui new file mode 100644 index 0000000..b156900 --- /dev/null +++ b/starter/linkconfig.ui @@ -0,0 +1,184 @@ + +LinkConfig + + + LinkConfig + + + + 0 + 0 + 438 + 173 + + + + Configure Link + + + true + + + + unnamed + + + + layout10 + + + + unnamed + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 206 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + icon + + + + 0 + 0 + 0 + 0 + + + + + 64 + 64 + + + + + 64 + 64 + + + + + + + 48 + + + false + + + + + layout3 + + + + unnamed + + + + textLabel1 + + + <b>Title</b> + + + + + title + + + + + textLabel2 + + + + 5 + 5 + 0 + 0 + + + + <b>Command</b> + + + + + command + + + + + + + + + + + buttonOk + clicked() + LinkConfig + accept() + + + buttonCancel + clicked() + LinkConfig + reject() + + + + + kicondialog.h + klineedit.h + + diff --git a/starter/menu.cpp b/starter/menu.cpp new file mode 100644 index 0000000..81611d0 --- /dev/null +++ b/starter/menu.cpp @@ -0,0 +1,2249 @@ +#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 +#include +#include +#include +#include +#include +#include +#include +//WARNING: THIS IS NOT PORTABLE! +// #include +// #include +#include +#include +#include +#include +// TO HERE -------- +//#include "kdrawer.h" +#include "baghiralinkdrag.h" +#include "menu.h" +#include "config.h" +#include "help.h" +#include "linkconfig.h" +#define OPAQUE 0xffffffff +#define OPACITY "_KDE_WM_WINDOW_OPACITY" + +#define _BIGSIZE_(_s_) ((_s_ == 16) ? 22 :\ +(_s_ == 22) ? 32 :\ +(_s_ == 32) ? 48 :\ +(_s_ == 48) ? 64 :\ +(_s_ == 64) ? 128 :\ +(int)(_s_*1.4)) + +//TODO: sort functions alphabetically, split files by classes... refactoring sucks ;) + +static QColor commentColor; +static QColor infoColor; +static KConfig *config; +static bool useKTTS; + + +QString spell(const QString text) +{ + QString result; + for (uint i = 0; i < text.length(); i++) + { + result += " "; result += text[i]; + } + return result; +} + +/* + Internal class to get access to protected QBoxLayout-members +*/ +class MyVBoxLayout : public QVBoxLayout +{ + friend class AppList; +public: + MyVBoxLayout( QLayout * parentLayout, int spacing = -1, const char * name = 0 ) + : QVBoxLayout( parentLayout, spacing, name ) {} +}; + +StartMenuButton::StartMenuButton( int size, QString icon, QString title, QString command, Orientation orientation, QWidget* parent, const char * name) : QWidget(parent, name), m_title(title), m_command(command), m_icon(icon), m_orientation(orientation), _moving(false) +{ + setBackgroundOrigin(QWidget::ParentOrigin); + int bigSize = _BIGSIZE_(size); + m_pix = KGlobal::iconLoader()->loadIcon(icon, KIcon::Desktop, size); + m_hoverPix = KGlobal::iconLoader()->loadIcon(icon, KIcon::Desktop, bigSize); + m_pixmapLabel = new QLabel(this, name); + m_pixmapLabel->setPixmap(m_pix); + m_pixmapLabel->setBackgroundOrigin(QWidget::AncestorOrigin); + QBoxLayout* layout; + if (orientation == Horizontal) + { + m_titleLabel = new QLabel("" + title + "", this, name); + m_titleLabel->setBackgroundOrigin(QWidget::AncestorOrigin); + m_titleLabel->setTextFormat( Qt::RichText ); + m_titleLabel->setAlignment ( Qt::AlignLeft | Qt::AlignVCenter ); + m_pixmapLabel->setFixedSize(bigSize+2,bigSize+2); + m_pixmapLabel->setAlignment ( Qt::AlignCenter ); + layout = new QHBoxLayout ( this ); + layout->addSpacing ( 5 ); + layout->addWidget(m_pixmapLabel,0,Qt::AlignCenter); + layout->addSpacing ( 2 ); + layout->addWidget(m_titleLabel,1); + layout->addSpacing ( 5 ); + } + else if (orientation == Vertical) + { + m_titleLabel = new QLabel("" + title + "", this, name); + m_titleLabel->setBackgroundOrigin(QWidget::AncestorOrigin); + m_titleLabel->setTextFormat( Qt::RichText ); + m_titleLabel->setAlignment ( Qt::AlignHCenter | Qt::AlignTop ); + m_pixmapLabel->setFixedSize(bigSize+2,bigSize+2); + m_pixmapLabel->setAlignment ( Qt::AlignCenter ); + layout = new QVBoxLayout ( this ); + layout->addSpacing ( 5 ); + layout->addWidget(m_pixmapLabel,0,Qt::AlignCenter); + layout->addSpacing ( 2 ); + layout->addWidget(m_titleLabel,1); + layout->addSpacing ( 5 ); + } + else + { + setFixedSize(bigSize+2,bigSize+2); + m_pixmapLabel->setAlignment ( Qt::AlignCenter ); + m_pixmapLabel->setFixedSize(bigSize+2,bigSize+2); + } + setCursor(Qt::PointingHandCursor); +} + +void StartMenuButton::reloadIcon(int size) +{ + int bigSize = _BIGSIZE_(size); + if (m_orientation == Status) + setFixedSize(bigSize+2,bigSize+2); + m_pixmapLabel->setFixedSize(bigSize+2,bigSize+2); + m_pix = KGlobal::iconLoader()->loadIcon(m_icon, KIcon::Desktop, size); + m_hoverPix = KGlobal::iconLoader()->loadIcon(m_icon, KIcon::Desktop, bigSize); + m_pixmapLabel->setPixmap(m_pix); +} + +void StartMenuButton::smartMove(QPoint &pt) +{ +} + +void StartMenuButton::smartMove(int x, int y) +{ + if (!dynamic_cast(parentWidget())) + return; + StartMenuButton *bt = 0L; + QObjectList *kids = const_cast(parentWidget()->children()); + QRect dRect(QPoint(x,y), size()); + QRect bRect; + if (kids && !kids->isEmpty()) + { + QObject *o; + for ( o = kids->first(); o; o = kids->next() ) + if ((o != this) && (bt = (dynamic_cast(o)))) + { + bRect = QRect(bt->pos(), bt->size()); + if (dRect.intersects(bRect)) + break; + bt = 0L; + } + } + if (!bt) + { + move(dRect.topLeft()); + int dst; + if (((Panel*)parentWidget())->orientation() == Qt::Horizontal) + { + dst = pos().x() + width() - parentWidget()->width(); + if (dst > 0) + emit updateSize(1); + else if (pos().x() < 0) + emit updateSize(-1); + } + else + { + dst = pos().y() + height() - parentWidget()->height(); + if (dst > 0) + emit updateSize(1); + else if (pos().y() < 0) + emit updateSize(-1); + } + ((Panel*)parentWidget())->ensureVisible(dRect); + } + else if ( + // left of center of left + (dRect.right() > bRect.right() && dRect.x() < bRect.right() - bRect.width() / 2) || + // right of center of right + (dRect.x() < bRect.x() && dRect.right() > bRect.x() + bRect.width() / 2) || + // up of center of upper + (dRect.bottom() > bRect.bottom() && dRect.y() < bRect.bottom() - bRect.height() / 2) || + // below center of lower + (dRect.y() < bRect.y() && dRect.bottom() > bRect.y() + bRect.height() / 2) + ) + { + QPoint bPt = bt->pos(); + bt->move(pos()); + move(bPt); + } +} + +void StartMenuButton::mouseReleaseEvent ( QMouseEvent * mre) +{ + if (mre->state() & Qt::LeftButton) + { + if (_moving) { _moving = false; return; } + emit pressed(m_command); + return; + } + if (mre->state() & Qt::RightButton) + { + if (!dynamic_cast(parentWidget())) + return; + ((Panel*)parentWidget())->linkConfigDialog->setCaption ( i18n("Configure Link") ); + ((Panel*)parentWidget())->linkConfigDialog->title->setText(m_title); + ((Panel*)parentWidget())->linkConfigDialog->command->setText(m_command); + ((Panel*)parentWidget())->linkConfigDialog->icon->setIcon(m_icon); + disconnect(((Panel*)parentWidget())->linkConfigDialog->buttonOk, SIGNAL(clicked()), 0, 0); + connect(((Panel*)parentWidget())->linkConfigDialog->buttonOk, SIGNAL(clicked()), ((Panel*)parentWidget())->linkConfigDialog, SLOT(accept())); + connect(((Panel*)parentWidget())->linkConfigDialog->buttonOk, SIGNAL(clicked()), this, SLOT(edit())); + ((Panel*)parentWidget())->linkConfigDialog->exec(); + } +} + +void StartMenuButton::edit() +{ + if (!dynamic_cast(parentWidget())) + return; + m_command = ((Panel*)parentWidget())->linkConfigDialog->command->text(); + if (m_command.isEmpty()) + { + deleteLater(); + return; + } + m_icon = ((Panel*)parentWidget())->linkConfigDialog->icon->icon(); + m_title = ((Panel*)parentWidget())->linkConfigDialog->title->text(); + int bigSize = _BIGSIZE_(((Panel*)parentWidget())->_size); + m_pix = KGlobal::iconLoader()->loadIcon(m_icon, KIcon::Desktop, ((Panel*)parentWidget())->_size); + m_hoverPix = KGlobal::iconLoader()->loadIcon(m_icon, KIcon::Desktop, bigSize); + m_pixmapLabel->setPixmap(m_pix); + if (m_orientation == Horizontal || m_orientation == Vertical) + m_titleLabel->setText("" + m_title + ""); + ((Panel*)parentWidget())->linkConfigDialog->close(); +} + +void Panel::addIcon() +{ + if (!linkConfigDialog->command->text().isEmpty()) + addIcon ( linkConfigDialog->icon->icon(), linkConfigDialog->title->text(), linkConfigDialog->command->text(), iconAddPosition ); +} + +void StartMenuButton::mouseMoveEvent ( QMouseEvent * mme ) +{ + if (!dynamic_cast(parentWidget())) + return; + if (mme->state() & Qt::LeftButton) + { + _moving = true; + QPoint pt = mapToParent(mme->pos()); + if (!(mme->state() & Qt::ShiftButton)) + { + if (pt.y() < -5 || pt.y() > parentWidget()->height() + 5 || pt.x() < -5 || pt.x() > parentWidget()->width() + 5) + { + BaghiraLinkDrag *d = new BaghiraLinkDrag( m_title, m_command, m_icon, -1, parentWidget() ); + d->setPixmap(m_hoverPix, QPoint(m_hoverPix.width()/2, m_hoverPix.height()/2)); + d->drag(); + if ((mme->state() & Qt::ControlButton) || BaghiraLinkDrag::accepted()) + return; + ((Panel*)parentWidget())->poof(); + // do NOT delete d. + return; + } + } + if (((Panel*)parentWidget())->orientation() == Qt::Horizontal) + smartMove(pt.x() - width()/2, pos().y()); + else + smartMove(pos().x(), pt.y() - height()/2); + } + else + _moving = false; +} + + +void StartMenuButton::enterEvent( QEvent * ) +{ + if (m_orientation == Status) emit hovered(m_title); + m_pixmapLabel->setPixmap(m_hoverPix); +} + +void StartMenuButton::leaveEvent( QEvent * ) +{ + if (m_orientation == Status) emit unhovered(); + m_pixmapLabel->setPixmap(m_pix); +} + + +StartMenuEntry::StartMenuEntry(KService * service, QString relPath, int size, bool newbie, QWidget * parent) : QWidget(parent) +{ + groupPath = relPath; + forNewbie = newbie; + if (config) // might be first use ever... + { + QString tmpString = config->readEntry(service->desktopEntryName()); + if (tmpString != QString::null) + { + usage = tmpString.section ( ' ', 0, 0 ).toUInt(); + lastUse = QDate::fromString(tmpString.section ( ' ', 1, 1 ), Qt::ISODate); + // ranking is naiv but hopefully usefull for the beginning: often usage increases rank, time to the last usage decreases. "8" is just a "random" offset - the idea is that apps that have been used within the last week should have a higher rank than apps that don't appear in the list - setting these to - infinity isn't a good idea as well, as they might be brand new + rank = 8 + usage - lastUse.daysTo(QDate::currentDate()); + } + else + { + usage = 0; + rank = 0; // neutral rank + } + } + else + { + qWarning("no valid config!"); + usage = 0; + rank = 0; // neutral rank + } + int bigSize = _BIGSIZE_(size); + isCurrent = false; + m_service = service; + exec = m_service->exec(); + display = false; + m_pix = m_service->pixmap( KIcon::Desktop, size ); + m_hoverPix = m_service->pixmap( KIcon::Desktop, bigSize ); + m_titleLabel = new QLabel("

    " + m_service->name() + "

    ", this); + m_titleLabel->setTextFormat( Qt::RichText ); + m_commentLabel = new QLabel(m_service->comment(), this); + m_commentLabel->setPaletteForegroundColor(commentColor); + m_commentLabel->setTextFormat( Qt::RichText ); + m_pixmapLabel = new QLabel(this); + m_pixmapLabel->setFixedSize ( bigSize+2, bigSize+2 ); + m_pixmapLabel->setAlignment(Qt::AlignCenter); + m_pixmapLabel->setPixmap(m_pix); + QVBoxLayout* spacer = new QVBoxLayout ( this ); + spacer->addSpacing ( 1 ); + QHBoxLayout* layout = new QHBoxLayout ( spacer ); + layout->addWidget(m_pixmapLabel); + layout->addSpacing ( 2 ); + QVBoxLayout* textLayout = new QVBoxLayout ( layout ); + layout->setStretchFactor ( textLayout, 1 ); + textLayout->addWidget(m_titleLabel); + textLayout->addWidget(m_commentLabel); + layout->addStretch(); + spacer->addSpacing ( 1 ); + setCursor(Qt::PointingHandCursor); +} + +void StartMenuEntry::reloadIcon(int size) +{ + int bigSize = _BIGSIZE_(size); + m_pixmapLabel->setFixedSize(bigSize+2,bigSize+2); + m_pix = m_service->pixmap( KIcon::Desktop, size ); + m_hoverPix = m_service->pixmap( KIcon::Desktop, bigSize ); + m_pixmapLabel->setPixmap(m_pix); +} + +StartMenuEntry::~StartMenuEntry() +{ +// if (m_service) delete m_service; m_service = 0L; +} + +void StartMenuEntry::saveStats() +{ + if (usage > 0) + config->writeEntry(m_service->desktopEntryName(), QString::number(usage) + " " + lastUse.toString(Qt::ISODate)); +} + +bool StartMenuEntry::operator==( const StartMenuEntry& se ) const +{ + return rank == se.rank; +} +bool StartMenuEntry::operator!=( const StartMenuEntry& se ) const +{ + return rank != se.rank; +} +bool StartMenuEntry::operator<( const StartMenuEntry& se ) const +{ + /* + if (rank == se.rank) + return m_titleLabel->text() < se.title(); + else + */ + return rank > se.rank; // to have descending sort order (we could also use a negative ranking...) +} +bool StartMenuEntry::operator>( const StartMenuEntry& se ) const +{ + /* + if (rank == se.rank) + return m_titleLabel->text() > se.title(); + else + */ + return rank < se.rank; // to have descending sort order (we could also use a negative ranking...) +} +bool StartMenuEntry::operator==( const double& d ) const +{ + return rank == d; +} +bool StartMenuEntry::operator!=( const double& d ) const +{ + return rank != d; +} +bool StartMenuEntry::operator<( const double& d ) const +{ + return rank > d; // to have descending sort order (we could also use a negative ranking...) +} +bool StartMenuEntry::operator>( const double& d ) const +{ + return rank < d; // to have descending sort order (we could also use a negative ranking...) +} + +void StartMenuEntry::mouseReleaseEvent ( QMouseEvent * e ) +//TODO: do funny stuff with other buttons (e.g. provide edit dialog) +{ + if (e->button() == Qt::LeftButton) + { + m_pixmapLabel->setPixmap(m_pix); + execute(); + if (!(e->state() & Qt::ControlButton)) + emit pressed(); + } + if (e->button() == Qt::RightButton) + { + emit popup(this); + } +} + +void StartMenuEntry::mouseMoveEvent ( QMouseEvent * mme ) +{ + if (mme->state() & Qt::LeftButton && (mme->pos().y() < 0 || mme->pos().y() > height() || mme->pos().x() < 0 || mme->pos().x() > width())) + { + BaghiraLinkDrag *d = new BaghiraLinkDrag( m_service->name(), m_service->exec(), m_service->icon(), -1, parentWidget() ); + d->setPixmap(m_hoverPix, QPoint(m_hoverPix.width()/2, m_hoverPix.height()/2)); + d->dragCopy(); + // do NOT delete d. + } +} + +void StartMenuEntry::keyPressEvent ( QKeyEvent * e ) +{ + switch (e->key()) + { + case Qt::Key_Escape: + emit closeMenu(); + break; + case Qt::Key_Return: + case Qt::Key_Enter: + execute(); + if (!(e->state() & Qt::ControlButton)) + emit pressed(); + break; + case Qt::Key_Down: + emit appDown(); + break; + case Qt::Key_Up: + emit appUp(); + break; + case Qt::Key_Home: // ->searchline + select + case Qt::Key_Left: + emit appLeft(); + break; + default: + break; + } +} + +QString StartMenuEntry::title() +{ + return m_titleLabel->text(); +} + +void StartMenuEntry::focusInEvent ( QFocusEvent * ) +{ + isCurrent = true; + emit hovered("[ " + groupPath + " ] " + exec); + if (useKTTS) + { + QString text = i18n("for TTS output, telling which item is focussed (keyboard) and than reads the comment", "%1 focussed. %2").arg(m_titleLabel->text()).arg(m_commentLabel->text()); + emit sayText(text); + } + setPaletteBackgroundColor(KGlobalSettings::highlightColor()); + m_commentLabel->setPaletteBackgroundColor(KGlobalSettings::highlightColor()); + setPaletteForegroundColor(KGlobalSettings::highlightedTextColor()); + m_commentLabel->setPaletteForegroundColor(KGlobalSettings::highlightedTextColor()); +} + +void StartMenuEntry::focusOutEvent ( QFocusEvent * ) +{ + emit unhovered(); + isCurrent = false; + setPaletteBackgroundColor(KGlobalSettings::baseColor()); + m_commentLabel->setPaletteBackgroundColor(KGlobalSettings::baseColor()); + if (hasMouse()) + { + setPaletteForegroundColor(KGlobalSettings::highlightColor()); + m_commentLabel->setPaletteForegroundColor(KGlobalSettings::highlightColor()); + } + else + { + setPaletteForegroundColor(KGlobalSettings::textColor()); + m_commentLabel->setPaletteForegroundColor(commentColor); + } +} + +void StartMenuEntry::enterEvent( QEvent * ) +{ + emit hovered("[ " + groupPath + " ] " + exec); + if (useKTTS) + { + QString text = i18n("for TTS output, telling which item is hovered (mouse) and than reads the comment", "%1 hovered. %2").arg(m_titleLabel->text()).arg(m_commentLabel->text()); + emit sayText(text); + } + if (!isCurrent) + { + setPaletteForegroundColor(KGlobalSettings::highlightColor()); + m_commentLabel->setPaletteForegroundColor(KGlobalSettings::highlightColor()); + } + m_pixmapLabel->setPixmap(m_hoverPix); +} + +void StartMenuEntry::leaveEvent( QEvent * ) +{ + emit unhovered(); + if (!isCurrent) + { + setPaletteForegroundColor(KGlobalSettings::textColor()); + m_commentLabel->setPaletteForegroundColor(commentColor); + } + m_pixmapLabel->setPixmap(m_pix); +} + +void StartMenuEntry::execute() +{ + usage++; + lastUse = QDate::currentDate(); + rank = 8 + usage; + KApplication::startServiceByDesktopPath(m_service->desktopEntryPath(), QStringList(), 0, 0, 0, "", true); + emit executed(); +} + +Panel::Panel(int size, QWidget * parent, const char * name) : QWidget(parent, name), _size(size), _draggedMe(false), _count(0), _orientation(Qt::Horizontal), _poof(0), _poofIndex(0), _poofAnimPix(0), _poofPix(0) +{ + linkConfigDialog = new LinkConfig(); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); +// setPaletteBackgroundColor(KGlobalSettings::highlightColor()); + setAcceptDrops(true); + config->setGroup("Panel"); + QStringList commands = config->readListEntry("Commands", '§'); + QStringList icons = config->readListEntry("Icons", '§'); + QStringList offsets = config->readListEntry("Offsets", '§'); + QStringList titles = config->readListEntry("Titles", '§'); + QStringList::Iterator it1 = commands.begin(); + QStringList::Iterator it2 = icons.begin(); + QStringList::Iterator it3 = offsets.begin(); + QStringList::Iterator it4 = titles.begin(); + while (it1 != commands.end() && + it2 != icons.end() && + it3 != offsets.end() && + it4 != titles.end()) + { + addIcon(*it2, *it4, *it1, QPoint((*it3).toInt(),0)); + ++it1; + ++it2; + ++it3; + ++it4; + } +} + +void Panel::save(KConfig *config) +{ + config->setGroup("Panel"); + QObjectList *kids = const_cast(children()); + StartMenuButton *bt = 0; + if (kids && !kids->isEmpty()) + { + QStringList icons; + QStringList titles; + QStringList commands; + QStringList offsets; + QObject *o; + for ( o = kids->first(); o; o = kids->next() ) + if (bt = (dynamic_cast(o))) + { + icons.append(bt->icon()); + titles.append(bt->title()); + commands.append(bt->command()); + _orientation == Qt::Horizontal ? + offsets.append(QString::number(bt->x())) : + offsets.append(QString::number(bt->y())); + } + config->writeEntry("Commands", commands, '§'); + config->writeEntry("Icons", icons, '§'); + config->writeEntry("Offsets", offsets, '§'); + config->writeEntry("Titles", titles, '§'); + } +} + +void Panel::reloadIcons( int size) +{ + _size = size; + if (_orientation == Qt::Horizontal) + { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setFixedHeight(_BIGSIZE_(_size)+4); + setMaximumWidth(32767); + } + else + { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + setFixedWidth(_BIGSIZE_(_size)+4); + setMaximumHeight(32767); + } + QObjectList *kids = const_cast(children()); + StartMenuButton *bt = 0; + if (kids && !kids->isEmpty()) + { + QObject *o; + for ( o = kids->first(); o; o = kids->next() ) + if (bt = (dynamic_cast(o))) + { + bt->reloadIcon(size); + } + } +} + +void Panel::ensureVisible(QRect & rect) +{ + int dx = 0; int dy = 0; + if (rect.width() > clipRegion().boundingRect().width()) + dx = (rect.width() - clipRegion().boundingRect().width())/2 - rect.x(); + else if (rect.right() > clipRegion().boundingRect().right()) + dx = clipRegion().boundingRect().right() - rect.right(); + else if (rect.x() < clipRegion().boundingRect().x()) + dx = clipRegion().boundingRect().x() - rect.x(); + if (rect.height() > clipRegion().boundingRect().height()) + dy = (rect.height() - clipRegion().boundingRect().height())/2 - rect.y(); + else if (rect.bottom() > clipRegion().boundingRect().bottom()) + dy = clipRegion().boundingRect().bottom() - rect.bottom(); + else if (rect.y() < clipRegion().boundingRect().y()) + dy = clipRegion().boundingRect().y() - rect.y(); + scroll(dx, dy); +} + +void Panel::updateSize(int dst) +{ + if (dst > 0) + { + if (_orientation == Qt::Horizontal) + { + resize(width()+dst, height()); + } + else + { + resize(width(), height()+dst); + } + } + else // more complex: resize and reposition all children, so first one is on (0,0) + { + QObjectList *kids = const_cast(children()); + if (kids && !kids->isEmpty()) + { + QObject *o; + StartMenuButton *bt; + if (_orientation == Qt::Horizontal) + { + resize(width()-dst, height()); + for ( o = kids->first(); o; o = kids->next() ) + if (bt = (dynamic_cast(o))) + bt->move(QPoint(bt->x()-dst, bt->y())); + } + else + { + resize(width(), height()-dst); + for ( o = kids->first(); o; o = kids->next() ) + if (bt = (dynamic_cast(o))) + bt->move(QPoint(bt->x(), bt->y()-dst)); + } + } + } +} + +void Panel::wheelEvent ( QWheelEvent * we ) +{ + if (_orientation == Qt::Vertical) + { + if (we->delta() > 0) + { + if (childrenRect().y() < clipRegion().boundingRect().y()) + { + if (childrenRect().y() + we->delta() < clipRegion().boundingRect().y()) + scroll ( 0, we->delta() ); + else + scroll ( 0, clipRegion().boundingRect().y() - childrenRect().y() ); + } + } + else + { + if (childrenRect().bottom() > clipRegion().boundingRect().bottom()) + { + if (childrenRect().bottom() + we->delta() > clipRegion().boundingRect().bottom()) + scroll ( 0, we->delta() ); + else + scroll ( 0, clipRegion().boundingRect().bottom() - childrenRect().bottom() ); + } + } + } + else + { + if (we->delta() > 0) + { + if (childrenRect().x() < clipRegion().boundingRect().x()) + { + if (childrenRect().x() + we->delta() < clipRegion().boundingRect().x()) + scroll ( we->delta(), 0 ); + else + scroll ( clipRegion().boundingRect().x() - childrenRect().x(), 0 ); + } + } + else + { + if (childrenRect().right() > clipRegion().boundingRect().right()) + { + if (childrenRect().right() + we->delta() > clipRegion().boundingRect().right()) + scroll ( we->delta(), 0 ); + else + scroll ( clipRegion().boundingRect().right() - childrenRect().right(), 0 ); + } + } + } +} + +void Panel::resizeEvent ( QResizeEvent * e) +{ + if (_orientation == Qt::Horizontal) + { + if (e->size().height() != e->oldSize().height()) + { + int h = e->size().height(); + KPixmap bgPix = QPixmap(32, h); + KPixmap bgPix1 = QPixmap(32, h/2); + KPixmap bgPix2 = QPixmap(32, h - bgPix1.height()); + QColor color = palette().color(QPalette::Active, QColorGroup::Background); + KPixmapEffect::gradient( bgPix1, color.light(130), color.dark(105), KPixmapEffect::VerticalGradient, 0); + KPixmapEffect::gradient( bgPix2, color.dark(120), color.light(110), KPixmapEffect::VerticalGradient, 0); + QPainter p(&bgPix); + p.drawPixmap(0,0,bgPix1); + p.drawPixmap(0,bgPix1.height(),bgPix2); + p.end(); + setPaletteBackgroundPixmap( bgPix ); + } + } + else if (_orientation == Qt::Vertical) + { + if (e->size().width() != e->oldSize().width()) + { + int w = e->size().width(); + KPixmap bgPix = QPixmap(w, 32); + KPixmap bgPix1 = QPixmap(w/2, 32); + KPixmap bgPix2 = QPixmap(w - bgPix1.width(), 32); + QColor color = palette().color(QPalette::Active, QColorGroup::Background); + KPixmapEffect::gradient( bgPix1, color.light(110), color.dark(120), KPixmapEffect::HorizontalGradient, 0); + KPixmapEffect::gradient( bgPix2, color.dark(105), color.light(130), KPixmapEffect::HorizontalGradient, 0); + QPainter p(&bgPix); + p.drawPixmap(0,0,bgPix1); + p.drawPixmap(bgPix1.width(),0,bgPix2); + p.end(); + setPaletteBackgroundPixmap( bgPix ); + } + } + QWidget::resizeEvent( e ); +} + +void Panel::poof() +{ + /*if (_draggedMe) + { + _draggedMe = false; + return; + }*/ + QObjectList *kids = const_cast(children()); + if (kids && !kids->isEmpty()) + { + QObject *o; + StartMenuButton *bt = 0L; + for ( o = kids->first(); o; o = kids->next() ) + { + bt = 0L; + if ((bt = (dynamic_cast(o))) && bt->isMoving()) + { + bt->hide(); bt->deleteLater(); bt = 0L; + --_count; + } + } + _poofIndex = 0; + _poofPix = new QPixmap(locateLocal("data", "baghira/poof.png"), "png"); + _poofAnimPix = new QPixmap(_poofPix->width(), _poofPix->width()); + if (!_poof) + _poof = new QWidget(0,0, Qt::WType_TopLevel | Qt::WStyle_NoBorder | Qt::WStyle_StaysOnTop | Qt::WX11BypassWM); +#if KDE_IS_VERSION(3,3,91) //3.4 beta + KWin::setShadowSize(_poof->winId(), 0); +#endif + _poof->setFixedSize(_poofPix->width(), _poofPix->width()); + int x = QCursor::pos().x() - _poof->width()/2; + int y = QCursor::pos().y() - _poof->height()/2; + QPixmap bgPix = QPixmap::grabWindow( qt_xrootwin(), x, y, _poofPix->width(), _poofPix->width()); + _poof->move(x,y); + _poof->show(); + _poof->setBackgroundOrigin(QWidget::WidgetOrigin); + _poof->setPaletteBackgroundPixmap( bgPix ); + runPoof(); + } +} + +void Panel::runPoof() +{ + if (_poofIndex > 4) + { + _poof->hide(); + delete _poofPix; + _poofPix = 0L; +// delete _poof; +// _poof = 0L; + delete _poofAnimPix; + _poofAnimPix = 0L; + _poofIndex = 0; + return; + } + _poof->erase(); + bitBlt(_poof, 0 ,0, _poofPix, 0, _poofIndex * _poofPix->width(), _poofPix->width(), _poofPix->width(), Qt::AndROP); + ++_poofIndex; + QTimer::singleShot ( 70, this, SLOT(runPoof()) ); // around 15 fps +} + +void Panel::mouseReleaseEvent ( QMouseEvent * mre ) +{ + if (mre->state() & Qt::RightButton) + { + iconAddPosition = mre->pos(); + linkConfigDialog->setCaption ( i18n("New Link") ); + linkConfigDialog->title->clear(); + linkConfigDialog->command->clear(); + linkConfigDialog->icon->resetIcon(); + disconnect(linkConfigDialog->buttonOk, SIGNAL(clicked()), 0, 0); + connect(linkConfigDialog->buttonOk, SIGNAL(clicked()), linkConfigDialog, SLOT(accept())); + connect(linkConfigDialog->buttonOk, SIGNAL(clicked()), this, SLOT(addIcon())); + linkConfigDialog->exec(); + } +} + +void Panel::dragEnterEvent ( QDragEnterEvent *dee ) +{ + if (BaghiraLinkDrag::canDecode(dee)) + { + QObjectList *kids = const_cast(children()); + if (kids && !kids->isEmpty()) + { + QObject *o; + StartMenuButton *bt = 0L; + for ( o = kids->first(); o; o = kids->next() ) + if ((bt = (dynamic_cast(o))) && bt->isMoving()) + // this is just some icon the user drags around ad that accidently left the panel + { + BaghiraLinkDrag::setAccepted(); + // as we cannot access Qts dragmanager and qdragobject doesn't provide a function to cancel the drag, we just emit a virtual escape key... + _draggedMe = true; // ensure to please not poof ;P + XTestFakeKeyEvent(qt_xdisplay(),XKeysymToKeycode(qt_xdisplay(), XK_Escape), true, 0); + XTestFakeKeyEvent(qt_xdisplay(),XKeysymToKeycode(qt_xdisplay(), XK_Escape), false, 0); + XFlush(qt_xdisplay()); + repositionIcon(bt, mapFromGlobal(dee->pos())); + return; + } + } + dee->accept(TRUE); + } + else if (QUriDrag::canDecode(dee) || QTextDrag::canDecode(dee)) + dee->accept(TRUE); +} + +void Panel::dropEvent ( QDropEvent *de ) +{ + QStrList list; + QString title; + QString command; + QString icon; + int index; + if ( BaghiraLinkDrag::decode(de, &title, &command, &icon, &index) ) + { + addIcon ( icon, title, command, QPoint(de->pos().x() - (_BIGSIZE_(_size)/2), de->pos().y() - (_BIGSIZE_(_size)/2))); + BaghiraLinkDrag::setAccepted(); + } + else if ( QUriDrag::decode(de, list) ) + { + char *uri; + KURL url; + for ( uri = list.first(); uri; uri = list.next() ) + { + url = KURL(uri); + if (url.protocol() == "http") + addIcon ( "html", url.host()+(url.path()=="/"?QString(""):url.path()), uri, de->pos() ); + else + { + KFileItem item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); + addIcon ( item.iconName(), url.fileName().isEmpty()?url.prettyURL():url.fileName(), uri, de->pos() ); + } + } + } + else if (QTextDrag::decode(de, command)) + { + KURL url(command); + if (url.isValid()) + { + if (url.protocol() == "http") + addIcon ( "html", url.host()+(url.path()=="/"?QString(""):url.path()), command, de->pos() ); + else + { + KFileItem item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); + addIcon ( item.iconName(), url.fileName().isEmpty()?url.prettyURL():url.fileName(), command, de->pos() ); + } + } + else if (command.contains('@')) + { + command.replace(" ",""); + addIcon ( "kmail", command, "mailto:"+command, de->pos() ); + } + else if (command.contains("'at'")) //last chance for anti-spam addy + { + command.replace(" ",""); + command.replace("'at'","@"); + addIcon ( "kmail", command, "mailto:"+command, de->pos() ); + } + else // ok, just take this as siple unknown command and hope the user knows, what she's ;) doing... + { + StartMenuButton *bt = addIcon ( command, command, command, de->pos() ); + } + } +} + +void Panel::repositionIcon(StartMenuButton *button, QPoint pt) +{ + QObjectList *kids = const_cast(children()); + if (!kids || kids->isEmpty()) // the easy one ;) + return; + if (kids->count() == 1) // button's for certain the only child ;) + { + if (_orientation == Qt::Horizontal) + button->move(pt.x(),0); + else + button->move(0,pt.y()); + return; + } + QObject *o; + StartMenuButton *bt = 0L; + int xy = 0; + if (_orientation == Qt::Horizontal) + { + if (pt.x() < 0) // append horizontally + { + for ( o = kids->first(); o; o = kids->next() ) + if ((bt = dynamic_cast(o)) && bt != button && bt->x() + bt->width() > xy ) + xy = bt->x() + bt->width(); + button->move(xy,0); + } + else // inject horizontally + { + // first find possible icon under the position + for ( o = kids->first(); o; o = kids->next() ) + { + if ((bt = dynamic_cast(o)) && QRect(bt->pos(), bt->size()).contains(pt)) + break; + else + bt = 0l; + } + if (bt) // found? - decide whether to insert left or right + { + if (bt->x() + bt->width()/2 > pt.x()) // move to old icon place + { + button->move(bt->x(), 0); + } + else // move to right + { + button->move(bt->x() + bt->width(), 0); + } + // adjust right icons + for ( o = kids->first(); o; o = kids->next() ) + if ((bt = dynamic_cast(o)) && bt->x() >= button->x() && bt != button ) + { + bt->move(bt->x() + button->width(), 0); + } + } + else // no collision, just move there + button->move(pt.x(), 0); + } + } + else + { + if (pt.y() < 0) // append vertically + { + for ( o = kids->first(); o; o = kids->next() ) + if ((bt = dynamic_cast(o)) && bt != button && bt->y() + bt->height() > xy ) + xy = bt->y() + bt->height(); + button->move(0, xy); + } + else // inject vertically + { + // first find possible icon under the position + for ( o = kids->first(); o; o = kids->next() ) + { + if ((bt = dynamic_cast(o)) && QRect(bt->pos(), bt->size()).contains(pt)) + break; + else + bt = 0l; + } + if (bt) // found? - decide whether to insert up or down + { + if (bt->y() + bt->height()/2 > pt.y()) // move to old icon place + button->move(0, bt->y()); + else // move to right + button->move(0, bt->y() + bt->height()); + // adjust lower icons + for ( o = kids->first(); o; o = kids->next() ) + if ((bt = dynamic_cast(o)) && bt->y() >= button->y() && bt != button ) + bt->move(0, bt->y() + button->height()); + } + else // no collision, just move there + button->move(0, pt.y()); + } + } +} + +StartMenuButton* Panel::addIcon ( QString icon, QString title, QString command, QPoint pt ) +{ + StartMenuButton *tmpButton = new StartMenuButton(_size, icon, title, command, StartMenuButton::Status, this); + // reposition icon + repositionIcon(tmpButton, pt); + // connections + connect (tmpButton, SIGNAL(hovered(const QString &)), this, SIGNAL(message(const QString &))); + connect (tmpButton, SIGNAL(unhovered()), this, SIGNAL(clearStatus())); + connect (tmpButton, SIGNAL(updateSize(int)), this, SLOT(updateSize(int))); + connect (tmpButton, SIGNAL(pressed(const QString &)), parent(), SLOT(execute(const QString &))); + connect (tmpButton, SIGNAL(pressed(const QString &)), parent(), SLOT(close())); + // done + // inc counter + _count++; + tmpButton->show(); + return tmpButton; +} + +void Panel::setOrientation ( Orientation ori ) +{ + if (_orientation == ori) + return; + _orientation = ori; + QObjectList *kids = const_cast(children()); + if (!kids || kids->isEmpty()) + return; + QObject *o; + StartMenuButton *bt = 0L; + for ( o = kids->first(); o; o = kids->next() ) + if (bt = (dynamic_cast(o))) + bt->move(QPoint(bt->pos().y(), bt->pos().x())); +} + +AppList::AppList(int size, QWidget * parent) : QScrollView(parent), _size(size) +{ + popupBlocked_ = false; + enableClipper( true ); + setFrameStyle(QFrame::LineEditPanel | QFrame::Sunken ); + configDialog_ = new ConfigDialog; + helpDialog_ = new HelpDialog; + connect (((QObject*)configDialog_->buttonHelp), SIGNAL(clicked()), ((QObject*)helpDialog_), SLOT(exec())); + connect (((QObject*)configDialog_->buttonCancel), SIGNAL(clicked()), this, SLOT(unblockPopup())); + m_widget = new QFrame(viewport()); + m_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + m_widget->setPaletteBackgroundColor(KGlobalSettings::baseColor()); + addChild(m_widget,0,0); + setResizePolicy(QScrollView::AutoOneFit); + m_widget->show(); + infoLayout = new QVBoxLayout(m_widget); + infoLabel = new QLabel(m_widget); + infoLabel->setPaletteBackgroundColor(infoColor); + infoLabel->setTextFormat( Qt::RichText ); + infoLayout->addWidget(infoLabel); + m_VLayout = new QVBoxLayout(infoLayout); + m_iconLoader = KGlobal::iconLoader(); + m_popup = new KPopupMenu(this); + m_popup->insertItem(i18n("Edit Entry"), this, SLOT(editDialog())); + m_popup->insertItem(i18n("Remove Entry"), this, SLOT(removeEntry())); + m_popup->insertSeparator(); + m_popup->insertItem(i18n("Add Entry"), this, SLOT(addDialog())); + init(); +} + +void AppList::mouseReleaseEvent ( QMouseEvent * e ) +{ + if (e->button() == Qt::RightButton) + addDialog(); +} + +void AppList::windowActivationChange ( bool oldActive ) +{ + if (isActiveWindow() && entryList.current()) + entryList.current()->setFocus(); + QScrollView::windowActivationChange ( oldActive ); +} + +void AppList::reloadIcons( int size) +{ + _size = size; + QPtrListIterator it(entryList); + StartMenuEntry *runner; + while( (runner = it.current()) != 0 ) + { + ++it; + runner->reloadIcon(size); + } +} + +void AppList::addDialog() +{ + disconnect (((QObject*)configDialog_->buttonOk), SIGNAL(clicked()), this, 0); + connect (((QObject*)configDialog_->buttonOk), SIGNAL(clicked()), this, SLOT(addEntry())); + configDialog_->appName->clear(); + configDialog_->category->clearEdit(); + configDialog_->command->clear(); + configDialog_->genericName->clear(); + configDialog_->iconButton->resetIcon(); + configDialog_->keywords->clear(); + configDialog_->startupFeedback->setChecked( true ); + configDialog_->showInSystray->setChecked( false ); + configDialog_->description->clear(); + configDialog_->startInTerminal->setChecked( false ); + configDialog_->terminalSettings->clear(); + configDialog_->startAsUser->setChecked( false ); + configDialog_->username->clear(); + configDialog_->workingDir->clear(); + configDialog_->shortcut->setShortcut(KShortcut::null(), false); + + configDialog_->setCaption ( i18n("New Entry") ); + ((QWidget*)(configDialog_->extendedGroup))->hide(); + configDialog_->buttonDetail->setDown ( false ); + configDialog_->adjustSize(); + configDialog_->show(); +} + +void AppList::addEntry() +{ + QString fullpath = configDialog_->category->currentText(); + while (fullpath[0] == '/') // remove leading "/"'s + { + fullpath.remove(0,1); + } + fullpath = KService::newServicePath(true, fullpath + configDialog_->appName->text()); +//qWarning("%s",fullpath.ascii()); + writeEntry(fullpath); + KService *s = new KService(fullpath); + QStringList list(KServiceGroup::group(configDialog_->category->currentText())->caption()); + StartMenuEntry *sme = addApp(s, list, configDialog_->category->currentText()); + sme->rank = 0xFFFFFF; // hype rank to max, i.e. keep this entry on top of everything - for this session or until first use + sme->show(); + sort(); +} + +void AppList::removeEntry() +{ + popupBlocked_ = true; + if (KMessageBox::questionYesNo (this, i18n("Are you sure you want to remove
    %1
    ").arg(handledEntry->title()), i18n("Remove ALI entry")) == KMessageBox::Yes) + { + qWarning("gonna delete!"); + writeEntry(handledEntry->m_service->locateLocal(), true); + handledEntry->hide(); + entryList.removeRef(handledEntry); + delete handledEntry; + handledEntry = 0L; + } + popupBlocked_ = false; +} + +void AppList::editDialog() +{ + if (!handledEntry) + return; + popupBlocked_ = true; + disconnect (((QObject*)configDialog_->buttonOk), SIGNAL(clicked()), this, 0); + connect (((QObject*)configDialog_->buttonOk), SIGNAL(clicked()), this, SLOT(editEntry())); + configDialog_->appName->setText(handledEntry->m_service->name()); + configDialog_->category->setCurrentItem (handledEntry->groupPath, false); + configDialog_->showInSystray->setChecked( handledEntry->m_service->exec().contains("ksystraycmd ") ); + if (!configDialog_->showInSystray->isChecked()) + configDialog_->command->setURL(handledEntry->m_service->exec()); + else + configDialog_->command->setURL(handledEntry->m_service->exec().right(handledEntry->m_service->exec().length() - (handledEntry->m_service->exec().findRev("ksystraycmd ") + 12))); + configDialog_->genericName->setText(handledEntry->m_service->genericName()); + configDialog_->iconButton->setIcon(handledEntry->m_service->icon ()); + configDialog_->keywords->setText(handledEntry->m_service->keywords().join(",")); + configDialog_->startupFeedback->setChecked( handledEntry->m_service->property ( "StartupNotify" ).toBool()); + configDialog_->description->setText(handledEntry->m_service->comment()); + configDialog_->startInTerminal->setChecked( handledEntry->m_service->terminal() ); + configDialog_->terminalSettings->setText(handledEntry->m_service->terminalOptions()); + configDialog_->startAsUser->setChecked( handledEntry->m_service->substituteUid() ); + configDialog_->username->setText(handledEntry->m_service->username()); + configDialog_->workingDir->setURL(handledEntry->m_service->path()); +// KKeyButton* shortcut; + + configDialog_->setCaption ( i18n("Edit Entry") ); + ((QWidget*)(configDialog_->extendedGroup))->hide(); + configDialog_->buttonDetail->setDown ( false ); + configDialog_->adjustSize(); + configDialog_->show(); +} + +void AppList::editEntry() +{ + QString fullpath; + if (handledEntry->groupPath == configDialog_->category->currentText()) // group not changed + fullpath = handledEntry->m_service->locateLocal(); // find a local replacement path + else // more complex: remove (del/shadow) entry from old group and create one in the new group + { + writeEntry(handledEntry->m_service->locateLocal(), true); //hide from old group + fullpath = configDialog_->category->currentText(); + while (fullpath[0] == '/') // remove leading "/"'s + fullpath.remove(0,1); + fullpath = KService::newServicePath(true, fullpath + configDialog_->appName->text()); // find new path + } + writeEntry(fullpath); + handledEntry->hide(); + QDate lu = handledEntry->lastUse; + uint u = handledEntry->usage; + entryList.removeRef(handledEntry); + delete handledEntry; + handledEntry = 0L; + KService *s = new KService(fullpath); + QStringList list(KServiceGroup::group(configDialog_->category->currentText())->caption()); + StartMenuEntry *sme = addApp(s, list, configDialog_->category->currentText()); + sme->lastUse = lu; + sme->usage = u; + sme->rank = 8 + u - lu.daysTo(QDate::currentDate()); + if (!config) config = new KConfig("bStarter", false, false); + config->setGroup("Statistics"); + sme->saveStats(); + delete config; + config = 0L; + sme->show(); + sort(); + popupBlocked_ = false; +} + +void AppList::writeEntry(QString path, bool hidden ) +{ + KConfig *config = new KConfig(path); + config->setDesktopGroup(); + + if (!configDialog_->description->text().isEmpty()) + config->writeEntry("Comment", configDialog_->description->text()); + if (!configDialog_->command->url().isEmpty()) + if (configDialog_->showInSystray->isChecked()) + config->writeEntry("Exec", "ksystraycmd " + configDialog_->command->url()); + else + config->writeEntry("Exec", configDialog_->command->url()); + if (!configDialog_->genericName->text().isEmpty()) + config->writeEntry("GenericName", configDialog_->genericName->text()); + if (hidden) + config->writeEntry("Hidden", true); + else if (config->readBoolEntry("Hidden", false)) + config->writeEntry("Hidden", false); + if (!configDialog_->iconButton->icon().isNull()) + config->writeEntry("Icon", configDialog_->iconButton->icon()); + if (!configDialog_->keywords->text().isEmpty()) + config->writeEntry("Keywords", QStringList::split(',', configDialog_->keywords->text())); + if (!configDialog_->appName->text().isEmpty()) + config->writeEntry("Name", configDialog_->appName->text()); + if (!configDialog_->workingDir->url().isEmpty()) + config->writeEntry("Path", configDialog_->workingDir->url()); + if (configDialog_->startupFeedback->isChecked()) + config->writeEntry("StartupNotify", true); + if (configDialog_->startInTerminal->isChecked()) + { + config->writeEntry("Terminal", 1); + if (!configDialog_->terminalSettings->text().isEmpty()) + config->writeEntry("TerminalOptions", configDialog_->terminalSettings->text()); + } + config->writeEntry("Type", "Application"); + if (configDialog_->startAsUser->isChecked()) + { + config->writeEntry("X-KDE-SubstituteUID", true); + if (!configDialog_->username->text().isEmpty()) + config->writeEntry("X-KDE-Username", configDialog_->username->text()); + } + + delete config; + +// configDialog_->category->setCurrentItem (handledEntry->m_service->categories().join("/"), true); +} + +void AppList::popup(StartMenuEntry* entry) +{ + if (popupBlocked_ && configDialog_->isShown()) + return; + handledEntry = entry; + m_popup->popup(QCursor::pos()); +} + +void AppList::sort() +{ + // first clean the layout (i assume that QLayout::remove() will search from beginning so removing over the current order will be quite fast) + QPtrListIterator it(entryList); + StartMenuEntry *runner; + while( (runner = it.current()) != 0 ) + { + ++it; + m_VLayout->remove ( runner ); + } + ((MyVBoxLayout*)m_VLayout)->deleteAllItems(); // get rid of the stretch + // then sort the list + entryList.sort(); + it.toFirst(); + // now rebuild the layout from new list + while( (runner = it.current()) != 0 ) + { + ++it; + m_VLayout->addWidget ( runner ); + } + m_VLayout->addStretch(1); // add final stretch +} + +void AppList::init() +{ + m_root = KServiceGroup::group(QString::null); + + if (!m_root || !m_root->isValid()) + { + qWarning("ROOT NOT FOUND"); + return; + } + favItemAmount = config->readNumEntry("FavItemAmount", 10); + neewbieApps << "konqueror" << "kmail" << "kppp"; + if (newbie = config->readBoolEntry("firstUse", true)) // '/' is certainly not unescaped part of a filename ;) + { + infoLabel->setText ( i18n("First Session Applications") ); +// delete config; +// config = 0L; + } + else + { + infoLabel->setText ( i18n("Favorite Applications
    ") ); + } + config->setGroup("Statistics"); + QStringList captions, paths; + insertGroup(m_root, captions, paths); + paths.sort(); + configDialog_->category->insertStringList(paths); + configDialog_->category->completionObject()->setCompletionMode( KGlobalSettings::CompletionPopupAuto ); + configDialog_->category->completionObject()->insertItems(paths); +// if (config) { delete config; config = 0L; } + sort(); + reset(); +} + +void AppList::save(KConfig *config) +{ + config->setGroup("Statistics"); + QPtrListIterator it(entryList); + StartMenuEntry *runner; + while( (runner = it.current()) != 0 ) + { + ++it; + runner->saveStats(); + } +} + +void AppList::insertGroup(KServiceGroup *g, QStringList & captions, QStringList & paths) +{ + KServiceGroup::List list = g->entries(true, true, false, false); + + if (list.isEmpty()) + { + return; + } + else + { + captions.append(g->caption()); + if (!categories.contains(g->caption())) + categories.append(g->caption()); + if (!paths.contains(g->relPath())) + paths.append(g->relPath()); + for( KServiceGroup::List::ConstIterator it = list.begin(); it != list.end(); it++) + { + KSycocaEntry *p = (*it); + if (p->isType(KST_KService)) + { + KService *s = static_cast(p); + if ((s->name().at(0) == '.')) + continue; + if (s->type() == "Application") + { + addApp(s, captions, g->relPath()); + } + } + else if (p->isType(KST_KServiceGroup)) + { + KServiceGroup *g2 = static_cast(p); + if ((g2->name().at(0) == '.')) + continue; + insertGroup(g2,captions, paths); + } + } + captions.remove(g->caption()); + } +} + +StartMenuEntry* AppList::addApp(KService * s, QStringList & captions, QString relPath) +{ + StartMenuEntry * tmp = new StartMenuEntry(s, relPath, _size, neewbieApps.find(s->desktopEntryName()) != neewbieApps.end(), m_widget); + connect (tmp, SIGNAL(appUp()), this, SLOT(appUp())); + connect (tmp, SIGNAL(appDown()), this, SLOT(appDown())); + connect (tmp, SIGNAL(appLeft()), this, SLOT(appLeft())); + connect (tmp, SIGNAL(hovered(const QString&)), this, SIGNAL(message(const QString&))); + if (useKTTS) connect (tmp, SIGNAL(sayText(const QString&)), this, SIGNAL(sayText(const QString&))); + connect (tmp, SIGNAL(unhovered()), this, SIGNAL(clearStatus())); + connect (tmp, SIGNAL(pressed()), parent(), SLOT(close())); + connect (tmp, SIGNAL(popup(StartMenuEntry*)), this, SLOT(popup(StartMenuEntry*))); + connect (tmp, SIGNAL(closeMenu()), parent(), SLOT(close())); + connect (tmp, SIGNAL(executed()), this, SLOT(sort())); + m_VLayout->addWidget(tmp); + tmp->hide(); + entryList.append(tmp); + KeyWordList::Iterator it; + if (!(s->name().isNull() || s->name().isEmpty())) + { + it = m_keywordList.insert(s->name(), StartMenuEntryList(), false); + it.data().append( tmp ); + } + QStringList kw; +#if 0 + kw = s->categories(); // THIS IS ****IMPORTANT***** kicker will crash on init if you try to grep through the pointers! + if (!kw.isEmpty()) + { + QStringList::Iterator key; + for ( key = kw.begin(); key != kw.end(); ++key ) + { + if (!((*key).isNull() || (*key).isEmpty())) + { + it = m_keywordList.insJediKnightert(*key, StartMenuEntryList(), false); + it.data().append( tmp ); + } + } + } +#endif + kw = s->keywords(); // THIS IS ****IMPORTANT***** kicker will crash on init if you try to grep through the pointers! + if (!kw.isEmpty()) + { + for ( QStringList::Iterator key = kw.begin(); key != kw.end(); ++key ) + { + if (!((*key).isNull() || (*key).isEmpty())) + { + it = m_keywordList.insert(*key, StartMenuEntryList(), false); + it.data().append( tmp ); + } + } + } + // group captions (so Games/IDSoftware/Quake3 will appear in Games and IDSoftware) + if (!captions.isEmpty()) + { + for ( QStringList::Iterator key = captions.begin(); key != captions.end(); ++key ) + { + if (!((*key).isNull() || (*key).isEmpty())) + { + it = m_groupList.insert(*key, StartMenuEntryList(), false); + it.data().append( tmp ); + } + } + } + return tmp; +} + +void AppList::finish() +{ + entryList.last(); entryList.next(); + m_VLayout->addStretch(1); + categories.sort(); +} + +void AppList::appDown() +{ + StartMenuEntry *save; + if (entryList.current() == 0L/*entryList.getLast()*/) + { + entryList.first(); + save = 0L; + } + else + { + save = entryList.current(); + entryList.next(); + } + for ( StartMenuEntry *runner = entryList.current(); runner; runner = entryList.next() ) + if (runner->isShown()) + { + if (save) save->clearFocus(); + runner->setFocus(); + QPoint pt(0,runner->height()); + pt = runner->mapToParent(pt); + ensureVisible ( pt.x(), pt.y()); + return; + } +// if (currentEntry == entryList.end()) +// currentEntry = entryList.begin(); // keep this somewhere valid +} + +void AppList::appUp() +{ + if (entryList.current() == entryList.getFirst()) + { + entryList.current()->clearFocus(); + entryList.last(); entryList.next(); // we jump out + emit looseKey(); + return; + } + StartMenuEntry *save = entryList.current(); + StartMenuEntry *runner; + if (entryList.current()) + runner = entryList.prev(); + else + runner = entryList.last(); + for ( ; runner != entryList.getFirst(); runner = entryList.prev()) + if (runner->isShown()) + { + if (save) save->clearFocus(); + runner->setFocus(); + QPoint pt(0,0); + pt = runner->mapToParent(pt); + ensureVisible ( pt.x(), pt.y()); + return; + } + if (runner == entryList.getFirst()) + { + if (save) save->clearFocus(); + if (runner->isShown()) + { + runner->setFocus(); + QPoint pt(0,0); + pt = runner->mapToParent(pt); + ensureVisible ( pt.x(), pt.y()); + } + else + { + entryList.last(); entryList.next();// we jump out + emit looseKey(); + } + } +} +void AppList::appLeft() +{ + if (entryList.current()) + { + entryList.current()->clearFocus(); + entryList.last(); entryList.next(); // we jump out + } + emit looseKey(); +} + +void AppList::showCategory(const QString & string) +{ + infoLabel->setText(string); + infoLabel->show(); + StartMenuEntry *it2; + KeyWordList::Iterator it; + for ( it = m_groupList.begin(); it != m_groupList.end(); ++it ) + { + if (it.key() == string) + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = true; + } + else + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = it2->display || false; + } + } + uint visibleItems = 0; + for ( it2 = entryList.first(); it2; it2 = entryList.next()) + { + if (it2->display) + { + visibleItems++; + it2->show(); + } + else + it2->hide(); + it2->display = false; + } + if (useKTTS && visibleItems == 0) + { + QString text = i18n("for TTS output, informs the user that no entries are in the currently selected group", "Warning! No Applications in group %1").arg(string); + emit sayText(text); + } +} + +void AppList::search(const QString & string) +{ + StartMenuEntry *it2; + if (string == QString::null || string == "") // empty line - remove all and exit + { + infoLabel->setText ( i18n("Favorite Applications
    ") ); + infoLabel->show(); + int i = 0; + for ( it2 = entryList.first(); it2; it2 = entryList.next() ) + { + i < favItemAmount ? it2->show() : it2->hide(); + i++; + } + return; + } + infoLabel->hide(); + // ok, we need a 2pass search: 1st to figure out which to show, 2nd to show or hide things + // the implementation also prevents us from spending time on showing/hiding things and some onscreen flicker, O(k*n(k)*n) + KeyWordList::Iterator it; + //keywords + for ( it = m_keywordList.begin(); it != m_keywordList.end(); ++it ) + { + if (it.key().contains(string, false) > 0) + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = true; + } + else + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = it2->display || false; + } + } + //groups + for ( it = m_groupList.begin(); it != m_groupList.end(); ++it ) + { + if (it.key().contains(string, false) > 0) + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = true; + } + else + { + for ( it2 = it.data().first(); it2; it2 = it.data().next()) + it2->display = it2->display || false; + } + } + //items + uint visibleItems = 0; + for ( it2 = entryList.first(); it2; it2 = entryList.next()) + { + if (it2->display && visibleItems < 50) //limit this to a healthy size + { + visibleItems++; + it2->show(); + } + else + it2->hide(); + it2->display = false; + } + if (useKTTS && visibleItems == 0) + { + QString text = i18n("for TTS output, no entries match the current search text", "Warning! No more Applications left. The entered Text is %1").arg(spell(string)); + emit sayText(text); + } +} + +void AppList::clear() +{ + for ( StartMenuEntry *it = entryList.first(); it; it = entryList.next()) + it->hide(); +} + +void AppList::reset() +{ + newbie ? + infoLabel->setText ( i18n("First Session Applications") ) : + infoLabel->setText ( i18n("Favorite Applications
    ") ); + infoLabel->show(); + if (newbie) + { + for ( StartMenuEntry *it = entryList.first(); it; it = entryList.next()) + { + it->forNewbie ? it->show() : it->hide(); + } + } + else + { + uint i = 0; + for ( StartMenuEntry *it = entryList.first(); it; it = entryList.next()) + { + i < favItemAmount ? it->show() : it->hide(); + i++; + } + } + setContentsPos(0, 0); +} + +StartMenu::StartMenu( int size, QWidget * parent, WFlags f ) : QWidget(parent, "StartMenu", f), _size(size), inMove(false) +{ + m_panelPos = StartMenu::Nowhere; + panelLayout = new QGridLayout ( this, 3, 3 ); + config = new KConfig("bStarter", true, false); + config->setGroup("Shell"); + history = config->readListEntry("History"); + config->setGroup("Settings"); + if (useKTTS = config->readBoolEntry("useKTTS", false)) + m_spokenText = 0; + _filterData = new KURIFilterData(); + int r,g,b,r2,g2,b2; + KGlobalSettings::baseColor().getRgb(&r,&g,&b); + KGlobalSettings::textColor().getRgb(&r2,&g2,&b2); + commentColor.setRgb((r+r2)/2,(g+g2)/2,(b+b2)/2); + infoColor.setRgb((3*r+r2)/4,(3*g+g2)/4,(3*b+b2)/4); + currentHistoryItem = history.end(); + header = new QWidget(this, "_B_ALI_HEADER"); + header->installEventFilter(this); + QHBoxLayout *headerLayout = new QHBoxLayout(header, 5, 3); + userButton = new StartMenuButton(_size, "folder_home", QString(getenv("USER")), "~", StartMenuButton::Status, header, "_B_ALI_HEADER"); + headerLayout->addWidget(userButton); + header->setPaletteBackgroundColor(KGlobalSettings::highlightColor()); + connect (userButton, SIGNAL(pressed(const QString &)), this, SLOT(execute(const QString &))); + connect (userButton, SIGNAL(pressed(const QString &)), this, SLOT(close())); + QBoxLayout *mainLayout = new QVBoxLayout(); + panelLayout->addLayout(mainLayout, 1, 1); + mainLayout->addWidget(header); + mainLayout->addSpacing ( 3 ); + QBoxLayout *centerLayout = new QHBoxLayout( mainLayout ); + centerLayout->addSpacing ( 3 ); + + appList = new AppList(_size, this); + appList->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + appList->finish(); + + searchLine = new SearchLine(header); + categoryCombo = new QComboBox(header, "_B_ALI_HEADER"); + headerLayout->addWidget(categoryCombo); + categoryCombo->setLineEdit ( searchLine ); + categoryCombo->insertStringList(appList->categories); + categoryCombo->setEditable ( true ); + categoryCombo->setInsertionPolicy(QComboBox::NoInsertion); + searchLine->installEventFilter(this); + searchLine->setCompletionMode(KGlobalSettings::CompletionAuto); + config->setGroup("Shortcuts"); + // read shortcuts... + QStringList cuts = config->readListEntry ("Shortcuts", ','); + QStringList cats = config->readListEntry ("Categories", ','); + QStringList::Iterator it; + QStringList::Iterator it2 = cats.begin(); + for ( it = cuts.begin(); it != cuts.end(); ++it ) + { + if (it2 == cats.end()) break; + shortcutList.insert(MyKey((*it)),(*it2)); + it2++; + } + //--- + QString PATH(getenv("PATH")); + int n = PATH.contains(':', false); + QStringList list; + for (int i = 0; i < n; i++) + { + QDir execDir(PATH.section(':', i, i)); + list = execDir.entryList(QDir::Files | QDir::Executable, QDir::Name | QDir::IgnoreCase ); + searchLine->completionObject()->insertItems(list); + } + + connect (categoryCombo, SIGNAL(activated( const QString &)), appList, SLOT(showCategory(const QString &))); + connect (searchLine, SIGNAL(typedTextChanged(const QString &)), appList, SLOT(search(const QString &))); + connect (searchLine, SIGNAL(textChanged(const QString &)), this, SLOT(endHistory())); + connect (appList, SIGNAL(looseKey()), searchLine, SLOT(setFocus())); + connect (appList, SIGNAL(looseKey()), searchLine, SLOT(selectAll() )); + connect (kapp, SIGNAL(shutDown()), this, SLOT(save() )); + if (useKTTS) connect (appList, SIGNAL(sayText(const QString&)), this, SLOT(sayText(const QString&) )); + + centerLayout->addWidget(appList,10); + centerLayout->addSpacing ( 3 ); + + m_panel = new Panel(_size, this, "_B_ALI_HEADER"); +// m_panel->installEventFilter(this); + m_panel->setFixedHeight(_BIGSIZE_(_size)+4); + + statusBar = new KSqueezedTextLabel(this); + QFont tmpFnt = statusBar->font(); + tmpFnt.setBold(true); + statusBar->setFont(tmpFnt); + connect (appList, SIGNAL(message(const QString&)), this, SLOT(message(const QString&) )); + connect (appList, SIGNAL(clearStatus()), this, SLOT(clearStatus() )); + connect (m_panel, SIGNAL(message(const QString&)), this, SLOT(centerMessage(const QString&) )); + connect (m_panel, SIGNAL(clearStatus()), this, SLOT(clearStatus() )); + + mainLayout->addSpacing ( 3 ); + mainLayout->addWidget ( statusBar ); + panelLayout->addWidget ( m_panel, 2, 1 ); + m_panel->hide(); + + if (config) { delete config; config = 0L; } +// KDrawer *drawer = new KDrawer(this, KDrawer::Bottom); +} + +void StartMenu::save() +{ + config = new KConfig("bStarter", false, false); + config->setGroup("Shell"); + QStringList lst; + for ( QStringList::Iterator it = history.begin(); it != history.end(); ++it ) + lst.prepend(*it); + config->writeEntry("History", lst); + config->setGroup("Settings"); + config->writeEntry("firstUse", false); + appList->save(config); + m_panel->save(config); + delete config; config = 0L; +} +#if 0 +extern int kicker_screen_number; + +void StartMenu::slotLock() +{ + QCString appname( "kdesktop" ); +// if ( kicker_screen_number ) +// appname.sprintf("kdesktop-screen-%d", kicker_screen_number); + kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", ""); +} +#endif + +void StartMenu::reloadIcons( int size) +{ + _size = size; + m_panel->reloadIcons(size); + appList->reloadIcons(size); +} + +void StartMenu::setCategory(const QString & category) +{ + categoryCombo->setCurrentItem ( categoryCombo->listBox()->index(categoryCombo->listBox()->findItem(category, Qt::ExactMatch))); + //emit categoryCombo->activated ( category ); // dunno if i'll need that once, needs protected access + appList->showCategory(category); +} + +void StartMenu::updateShortcuts(ShortcutList & list) +{ + shortcutList = list; +} + +void StartMenu::toggleKTTS(bool on) +{ + useKTTS = on; + if (useKTTS) + { + m_spokenText = 0; + QPtrListIterator it(appList->entryList); + StartMenuEntry *runner; + while( (runner = it.current()) != 0 ) + { + ++it; + connect (runner, SIGNAL(sayText(const QString&)), this, SIGNAL(sayText(const QString&))); + } + connect (appList, SIGNAL(sayText(const QString&)), this, SLOT(sayText(const QString&) )); + } + else + { + QPtrListIterator it(appList->entryList); + StartMenuEntry *runner; + while( (runner = it.current()) != 0 ) + { + ++it; + disconnect (runner, SIGNAL(sayText(const QString&)), this, SIGNAL(sayText(const QString&))); + } + disconnect (appList, SIGNAL(sayText(const QString&)), this, SLOT(sayText(const QString&) )); + } +} + +SearchLine::SearchLine( QWidget * parent ) : KLineEdit(parent){blocked = false;}; + +void SearchLine::makeCompletion (const QString & string) +{ + if (blocked) {blocked = false; return;} + emit typedTextChanged(string); + KLineEdit::makeCompletion (string); +} + +StartMenu::~StartMenu() +{ +// appList->save(); +} + +void StartMenu::sayText(const QString &text) +{ + // strip tags + QString cleanText; + bool copy = true; + for (uint i = 0; i < text.length(); i++) + { + if (!copy && text[i] == '>') // end tag, set copy true and move on + { + copy = true; + continue; + } + if (copy && text[i] == '<') // tag start, set copy false and move on + { + copy = false; + continue; + } + if (copy) //copy char ;) + cleanText += text[i]; + } + // done + QByteArray data1; + QDataStream arg1(data1, IO_WriteOnly); + arg1 << m_spokenText; // stop what we messaged before (if) + if (!kapp->dcopClient()->send("kttsd", "kspeech", "stopText(uint)", data1)) + qDebug("there was some error using DCOP."); + + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << cleanText << ""; // ask for the full list + if (!kapp->dcopClient()->call("kttsd", "kspeech", "sayText(QString, QString)", data, replyType, replyData)) + qDebug("there was some error using DCOP."); + else + { + QDataStream reply(replyData, IO_ReadOnly); + if (replyType == "uint") + reply >> m_spokenText; + else + qWarning("properties() returned an unexpected type of reply (%s)!",QString(replyType).ascii()); + } +} + +void StartMenu::show() +{ + m_panel->setBackgroundOrigin(QWidget::WidgetOrigin); + statusBar->setBackgroundOrigin(QWidget::ParentOrigin); + searchLine->setText(i18n("Type to search or enter a command")); + searchLine->selectAll(); + searchLine->setFocus(); +// KWin::setOpacity(winId(), 80); + QWidget::show(); +} + +void StartMenu::hide() +{ + emit aboutToHide(); + searchLine->clear(); + appList->reset(); + QWidget::hide(); +} + +void StartMenu::message(const QString &text) +{ + statusBar->setAlignment ( Qt::AlignAuto | Qt::AlignVCenter ); + statusBar->setText(text); +} + +void StartMenu::centerMessage(const QString &text) +{ + statusBar->setAlignment ( Qt::AlignCenter ); + statusBar->setText(text); +} + +void StartMenu::clearStatus() +{ + statusBar->clear(); +} + +void StartMenu::setPanelPosition(PanelPosition p) +{ + if (p == m_panelPos) + return; + panelLayout->remove(m_panel); + switch (p) + { + case StartMenu::South: + m_panel->show(); + if (m_panelPos == StartMenu::Nowhere || m_panelPos == StartMenu::West || m_panelPos == StartMenu::East ) + { +// m_panel->set2SizePolicies(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + m_panel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_panel->setOrientation ( Qt::Horizontal ); + m_panel->setFixedHeight(_BIGSIZE_(_size)+4); + m_panel->setMaximumWidth(32767); + } + panelLayout->addWidget(m_panel, 2, 1); + break; + case StartMenu::West: + m_panel->show(); + if (m_panelPos == StartMenu::Nowhere || m_panelPos == StartMenu::South || m_panelPos == StartMenu::North ) + { +// m_panel->set2SizePolicies(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); + m_panel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + m_panel->setOrientation ( Qt::Vertical ); + m_panel->setFixedWidth(_BIGSIZE_(_size)+4); + m_panel->setMaximumHeight(32767); + } + panelLayout->addWidget(m_panel, 1, 0); + break; + case StartMenu::East: + m_panel->show(); + if (m_panelPos == StartMenu::Nowhere || m_panelPos == StartMenu::South || m_panelPos == StartMenu::North ) + { +// m_panel->set2SizePolicies(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); + m_panel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + m_panel->setOrientation ( Qt::Vertical ); + m_panel->setFixedWidth(_BIGSIZE_(_size)+4); + m_panel->setMaximumHeight(32767); + } + panelLayout->addWidget(m_panel, 1, 2); + break; + case StartMenu::North: + m_panel->show(); + if (m_panelPos == StartMenu::Nowhere || m_panelPos == StartMenu::West || m_panelPos == StartMenu::East ) + { +// m_panel->set2SizePolicies(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + m_panel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_panel->setOrientation ( Qt::Horizontal ); + m_panel->setFixedHeight(_BIGSIZE_(_size)+4); + m_panel->setMaximumWidth(32767); + } + panelLayout->addWidget(m_panel, 0, 1); + break; + default: + m_panel->hide(); +// break; + } + m_panelPos = p; +} + +void StartMenu::execute(const QString& command) +// adapted from kicker run applet - far more convenient ;) +{ + history.remove(command); + history.append(command); // all - the list is not stored and the user may want to easily correct mistypes of LOOOOOOOOOOOOOOOOOOOONG commands with a lot of "\ "... ;P + QString exec; + + kapp->propagateSessionManager(); + + _filterData->setData( command.stripWhiteSpace() ); + QStringList filters; + filters << "kurisearchfilter" << "kshorturifilter"; + KURIFilter::self()->filterURI( *(_filterData), filters ); + + QString cmd = (_filterData->uri().isLocalFile() ? _filterData->uri().path():_filterData->uri().url()); + + // Nothing interesting. Quit! + if ( cmd.isEmpty() ) + { + return; + } + else if (cmd == "logout") + { + close(); + kapp->requestShutDown(); + } + else + { + switch( _filterData->uriType() ) + { + case KURIFilterData::LOCAL_FILE: + case KURIFilterData::LOCAL_DIR: + case KURIFilterData::NET_PROTOCOL: + case KURIFilterData::HELP: + { + (void) new KRun( _filterData->uri() ); + return; + } + case KURIFilterData::EXECUTABLE: + case KURIFilterData::SHELL: + { + exec = cmd; + if( _filterData->hasArgsAndOptions() ) + cmd += _filterData->argsAndOptions(); + break; + } + case KURIFilterData::UNKNOWN: + case KURIFilterData::ERROR: + default: + return; + } + } + KRun::runCommand( cmd, exec, "" ); + return; +} + + +void StartMenu::endHistory() +{ + currentHistoryItem = history.end(); +} + +void StartMenu::search(const QString & string) +{ + disconnect (searchLine, SIGNAL(textChanged ( const QString & )), this, SLOT(search(const QString &))); + appList->search(string); +} + +bool StartMenu::eventFilter ( QObject * o, QEvent * e ) +{ + if (o == header) + { + if (e->type() == QEvent::MouseButtonPress && ((QMouseEvent*)e)->button() == Qt::LeftButton) + { + inMove = true; + movePoint = ((QMouseEvent*)e)->pos(); + header->grabMouse(Qt::SizeAllCursor); + return true; + } + else if (e->type() == QEvent::MouseButtonRelease && ((QMouseEvent*)e)->button() == Qt::LeftButton) + { + inMove = false; + header->releaseMouse(); + return true; + } + else if (e->type() == QEvent::MouseMove && inMove) + { + move(((QMouseEvent*)e)->globalPos() - movePoint); + return true; + } + else if (e->type() == QEvent::Resize && ((QResizeEvent*)e)->size().height() != ((QResizeEvent*)e)->oldSize().height()) + { + int height = ((QResizeEvent*)e)->size().height(); + KPixmap bgPix = QPixmap(32, height); + KPixmap bgPix1 = QPixmap(32, height/2); + KPixmap bgPix2 = QPixmap(32, height - bgPix1.height()); + QColor buttonColor = ((QWidget*)o)->palette().color(QPalette::Active, QColorGroup::Button); + KPixmapEffect::gradient( bgPix1, buttonColor.light(130), buttonColor, KPixmapEffect::VerticalGradient, 0); + KPixmapEffect::gradient( bgPix2, buttonColor.dark(120), buttonColor.light(110), KPixmapEffect::VerticalGradient, 0); + QPainter p(&bgPix); + p.drawPixmap(0,0,bgPix1); + p.drawPixmap(0,bgPix1.height(),bgPix2); + p.end(); + ((QWidget*)o)->setPaletteBackgroundPixmap( bgPix ); + } + return false; + } + if (o != searchLine) + return false; + QLineEdit *le = (QLineEdit *)o; + if (e->type() == QEvent::KeyPress) + { + QKeyEvent *ke = (QKeyEvent*)e; + if (ke->state() & Qt::ControlButton || ke->state() & Qt::AltButton) + // might be shortcut, set category + { + if (ke->state() == Qt::ControlButton) + { + if (ke->key() == Qt::Key_Up) + { + if (categoryCombo->currentItem() > 0) + { + categoryCombo->setCurrentItem ( categoryCombo->currentItem() - 1 ); + appList->showCategory(categoryCombo->currentText()); + } + return true; + } + if (ke->key() == Qt::Key_Down) + { + if (categoryCombo->currentItem() < categoryCombo->count()) + { + categoryCombo->setCurrentItem ( categoryCombo->currentItem() + 1 ); + appList->showCategory(categoryCombo->currentText()); + } + return true; + } + } + if (ke->key() == Qt::Key_Shift || ke->key() == Qt::Key_Control || ke->key() == Qt::Key_Alt) + return false; + ShortcutList::Iterator it; + for ( it = shortcutList.begin(); it != shortcutList.end(); ++it ) + { + if (it.key().modFlags() == ke->state() && it.key().key() == ke->key()) + setCategory( it.data() ); + } + return true; //fire event to prevent lienedit action like ctrl+d -> del etc. + } + switch(ke->key()) + { + case Qt::Key_Return: + case Qt::Key_Enter: + { + execute(le->text()); + if (!(ke->state() & Qt::ControlButton)) + close(); //bye + return true; //don't do anything else + } + case Qt::Key_Backspace: + case Qt::Key_Delete: + { + connect (le, SIGNAL(textChanged ( const QString & )), this, SLOT(search(const QString &))); + break; + } + case Qt::Key_Down: + { + if (history.isEmpty() || currentHistoryItem == history.end()) + { + appList->appDown(); + } + else // navigate history + { + le->blockSignals(true); + le->setText(*currentHistoryItem); + le->blockSignals(false); + currentHistoryItem++; + if (currentHistoryItem == history.end()) + le->selectAll(); + } + return true; //don't scroll the categories + } + case Qt::Key_Up: + { + if (!(history.isEmpty() || currentHistoryItem == history.begin())) + { + currentHistoryItem--; + le->blockSignals(true); + le->setText(*currentHistoryItem); + le->blockSignals(false); + } + return true; //don't scroll the categories + } + case Qt::Key_Escape: + { + close(); //bye + break; + } + default: + break; + } + return false; + } + else if (isVisible() && useKTTS && e->type() == QEvent::FocusIn) + { + QString text = i18n("TTS output", "The searchline has now the focus."); + sayText(text); + } + return false; +} diff --git a/starter/menu.h b/starter/menu.h new file mode 100644 index 0000000..d11a651 --- /dev/null +++ b/starter/menu.h @@ -0,0 +1,320 @@ + +#ifndef STARTMENU_H +#define STARTMENU_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mykey.h" + +class KIconLoader; +class QPaintEvent; +class QMouseEvent; +class QEvent; +class QPixmap; +class QVBoxLayout; +class QComboBox; +class StartMenuButton; +class KConfig; +class LinkConfig; + +class Panel : public QWidget//QScrollView +{ + friend class StartMenu; + friend class StartMenuButton; +Q_OBJECT + +public: + Panel(int size = 32, QWidget * parent = 0, const char * name = 0); + Orientation orientation(){ return _orientation; } + void setOrientation ( Orientation o ); +// void addItem ( QWidget *w ); + StartMenuButton* addIcon ( QString icon, QString title, QString command, QPoint pt = QPoint(-1,-1) ); + void save(KConfig* config); + void repositionIcon ( StartMenuButton* bt, QPoint pt ); + void ensureVisible(QRect & rect); + void reloadIcons(int size); + void poof(); +public slots: + void updateSize(int); +protected: + void wheelEvent ( QWheelEvent * ); + void dragEnterEvent ( QDragEnterEvent * ); + void dropEvent ( QDropEvent * ); + void mouseReleaseEvent ( QMouseEvent * e ); + void resizeEvent ( QResizeEvent * ); + LinkConfig *linkConfigDialog; + int _size; +private: + int _count; + Orientation _orientation; + bool _draggedMe; + int _poofIndex; + QPoint iconAddPosition; + QPixmap *_poofPix; + QPixmap *_poofAnimPix; + QWidget *_poof; +private slots: + void addIcon(); + void runPoof(); +signals: + void message(const QString&); + void clearStatus(); +}; + +class QTextDrag; + +class StartMenuButton : public QWidget +{ + friend class Panel; + Q_OBJECT + +public: + enum Orientation { Horizontal = 0, Vertical, Status }; + StartMenuButton ( int size, QString icon, QString title, QString command, Orientation orientation, QWidget* parent = 0, const char * name = 0); + void smartMove(QPoint & pt); // prevents collisions with other childs of parentWidget() + void smartMove(int x, int y); + void reloadIcon(int size); +public slots: + void edit(); +protected: + QString & command(){return m_command;} + QString & title(){return m_title;} + QString & icon(){return m_icon;} + void mouseReleaseEvent ( QMouseEvent * e ); + void mouseMoveEvent ( QMouseEvent * e ); + void enterEvent( QEvent * ); + void leaveEvent( QEvent * ); + bool isMoving() {return _moving;} +private: + Orientation m_orientation; + bool _moving; + QTextDrag *myDrag; + QString m_command; + QString m_title; + QString m_icon; + QLabel* m_titleLabel; + QLabel* m_pixmapLabel; + QPixmap m_pix; + QPixmap m_hoverPix; +signals: + void pressed(const QString &); + void hovered(const QString &); + void unhovered(); + void updateSize(int); +}; + +class KService; +class QDate; +class AppList; + +class StartMenuEntry : public QWidget +{ + friend class AppList; + Q_OBJECT +public: + StartMenuEntry(KService * service, QString relPath, int size = 32, bool neewbie = false, QWidget * parent = 0); + ~StartMenuEntry(); + void reloadIcon(int size); + bool display; + QString title(); + void saveStats(); + int rank; + bool forNewbie; + //--- operators to allow use of qHeapSort() + bool operator==( const StartMenuEntry& se ) const; + bool operator!=( const StartMenuEntry& se ) const; + bool operator<( const StartMenuEntry& se ) const; + bool operator>( const StartMenuEntry& se ) const; + bool operator==( const double& d ) const; + bool operator!=( const double& d ) const; + bool operator<( const double& d ) const; + bool operator>( const double& d ) const; +protected: + void focusInEvent ( QFocusEvent * ); + void focusOutEvent ( QFocusEvent * ); + void mouseReleaseEvent ( QMouseEvent * e ); + void mouseMoveEvent ( QMouseEvent * mme ); + void keyPressEvent ( QKeyEvent * e ); + void enterEvent( QEvent * ); + void leaveEvent( QEvent * ); + KService* m_service; + QString groupPath; + QDate lastUse; + uint usage; +private: + void execute(); + QString exec; + bool isCurrent; + QLabel* m_titleLabel; + QLabel* m_commentLabel; + QLabel* m_pixmapLabel; + QPixmap m_pix; + QPixmap m_hoverPix; +signals: + void closeMenu(); + void pressed(); + void appDown(); + void appUp(); + void appLeft(); + void hovered(const QString &); + void sayText(const QString&); + void unhovered(); + void popup(StartMenuEntry*); + void executed(); +}; + +class KPopupMenu; +class ConfigDialog; +class HelpDialog; + +class AppList : public QScrollView +{ + friend class StartMenu; +Q_OBJECT + +public: + AppList(int size = 32, QWidget * parent = 0); + StartMenuEntry* addApp(KService * service, QStringList & captions, QString relPath); + void finish(); + StartMenuEntry* handledEntry; // for rightclick menu action + void writeEntry(QString path, bool hidden = false); // for add/edit + void reloadIcons(int size); +public slots: + void addEntry(); + void addDialog(); + void removeEntry(); + void editEntry(); + void editDialog(); + void clear(); + void reset(); + void search(const QString & string); + void appDown(); + void appUp(); + void appLeft(); + void sort(); + void showCategory(const QString & string); + void unblockPopup(){popupBlocked_ = false;} +protected: + QStringList categories; + int favItemAmount; + void save(KConfig* config); + void mouseReleaseEvent ( QMouseEvent * e ); + void windowActivationChange ( bool oldActive ); +private: + void init(); + void insertGroup(KServiceGroup *g, QStringList & captions, QStringList & paths); + KServiceGroup::Ptr m_root; + KIconLoader *m_iconLoader; + QLabel *infoLabel; + QVBoxLayout * infoLayout; + QVBoxLayout * m_VLayout; + QFrame * m_widget; + bool newbie; + QStringList neewbieApps; + KPopupMenu *m_popup; + bool popupBlocked_; + int _size; + typedef QSortedList StartMenuEntryList; + typedef QMap KeyWordList; + StartMenuEntryList entryList; + KeyWordList m_keywordList; + KeyWordList m_groupList; + ConfigDialog* configDialog_; + HelpDialog* helpDialog_; +private slots: + void popup(StartMenuEntry*); +signals: + void looseKey(); + void message(const QString&); + void sayText(const QString&); + void clearStatus(); +}; + +class QStringList; + +class SearchLine : public KLineEdit +{ + Q_OBJECT +public: + SearchLine( QWidget * parent ); + bool blocked; +protected slots: + void makeCompletion (const QString &); + void block(){blocked = true;} +signals: + void typedTextChanged(const QString & string); +}; + +class KURIFilterData; +class StarterConfig; +class QSignalMapper; +class KSqueezedTextLabel; + +class StartMenu : public QWidget +{ + friend class starter; // to allow setting the shortcutlis directly + Q_OBJECT +public: + enum PanelPosition { North = 0, South, West, East, Nowhere }; + StartMenu ( int size = 32, QWidget * parent = 0, WFlags f = 0 ); + ~StartMenu(); + void show(); + void hide(); + void reloadIcons(int size); + QStringList & categories(){return appList->categories;}; + typedef QMap ShortcutList; + void updateShortcuts(ShortcutList &); + void setFavItemAmount(int i) {if (appList) appList->favItemAmount = i;} + void setPanelPosition(PanelPosition p); +public slots: + void sayText(const QString &text); + void toggleKTTS(bool); + void setCategory(const QString & category); + void save(); +protected: + bool eventFilter ( QObject * o, QEvent * e ); + ShortcutList shortcutList; +private slots: + void message(const QString &text); + void centerMessage(const QString &text); + void clearStatus(); + void execute(const QString & command); + void search(const QString & string); + void endHistory(); +// void slotLock(); +private: + bool inMove; + uint m_spokenText; + int _size; + QWidget *header; + QPoint movePoint; + KURIFilterData *_filterData; + AppList *appList; + QComboBox *categoryCombo; + SearchLine *searchLine; + KSqueezedTextLabel *statusBar; + Panel *m_panel; + QStringList history; + QStringList::Iterator currentHistoryItem; + PanelPosition m_panelPos; + StartMenuButton *userButton; + QGridLayout *panelLayout; + +signals: + void aboutToHide(); +}; + +#endif diff --git a/starter/mykey.h b/starter/mykey.h new file mode 100644 index 0000000..36a32d2 --- /dev/null +++ b/starter/mykey.h @@ -0,0 +1,73 @@ + +#ifndef MYKEY_H +#define MYKEY_H +#include + +class MyKey +{ +public: + MyKey(short key, short modFlags){modFlags_ = modFlags; key_ = key;} + MyKey(){modFlags_ = 0; key_ = 0;} + MyKey(QString & string) + { + QString tmpString = string.left(string.findRev('+')); + modFlags_ = 0; + if (tmpString.contains("256")) // QString.setNum(Qt::ShiftButton) + modFlags_ |= Qt::ShiftButton; + if (tmpString.contains("512")) // QString.setNum(Qt::ControlButton) + modFlags_ |= Qt::ControlButton; + if (tmpString.contains("1024")) // QString.setNum(Qt::AltButton) + modFlags_ |= Qt::AltButton; + tmpString = string.right(string.length() - string.findRev('+') - 1); + key_ = tmpString.toShort(); + } + short modFlags() const {return modFlags_;} + short key()const {return key_;} + bool operator==( const MyKey& myKey ) const + { + return (modFlags_ == myKey.modFlags() && key_ == myKey.key()); + } + bool operator!=( const MyKey& myKey ) const + { + return (modFlags_ != myKey.modFlags() || key_ != myKey.key()); + } + bool operator<( const MyKey& myKey ) const + { + return (!(modFlags_ < myKey.modFlags()) || key_ < myKey.key()); + } + bool operator>( const MyKey& myKey ) const + { + return (!(modFlags_ > myKey.modFlags()) && key_ > myKey.key()); + } + QString toString() const + { + QString string; + QString numString; + if (modFlags_ & Qt::ShiftButton) + { + numString.setNum(Qt::ShiftButton); + string += numString; + string += '+'; + } + if (modFlags_ & Qt::ControlButton) + { + numString.setNum(Qt::ControlButton); + string += numString; + string += '+'; + } + if (modFlags_ & Qt::AltButton) + { + numString.setNum(Qt::AltButton); + string += numString; + string += '+'; + } + numString.setNum(key_); + string += numString; + return string; + } +private: + short modFlags_; + short key_; +}; + +#endif diff --git a/starter/po/Makefile.am b/starter/po/Makefile.am new file mode 100644 index 0000000..0fa209c --- /dev/null +++ b/starter/po/Makefile.am @@ -0,0 +1 @@ +POFILES = AUTO diff --git a/starter/po/de.po b/starter/po/de.po new file mode 100644 index 0000000..1e9061d --- /dev/null +++ b/starter/po/de.po @@ -0,0 +1,351 @@ +# translation of de.po to German +# translation of starter.po to German +# This file is put in the public domain. +# Thomas Lübking , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: de\n" +"POT-Creation-Date: 2005-07-19 21:15+0200\n" +"PO-Revision-Date: 2005-07-19 22:15+0200\n" +"Last-Translator: Thomas Lübking \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10\n" + +#. i18n: file buttons.ui line 16 +#: buttons.cpp:98 rc.cpp:3 rc.cpp:141 +#, no-c-format +msgid "Select Button Images" +msgstr "Skins auswählen" + +#. i18n: file buttons.ui line 103 +#: buttons.cpp:103 rc.cpp:14 rc.cpp:152 +#, no-c-format +msgid "Down" +msgstr "Gedrückt" + +#. i18n: file buttons.ui line 111 +#: buttons.cpp:104 rc.cpp:17 rc.cpp:155 +#, no-c-format +msgid "Hover" +msgstr "Unter Maus" + +#. i18n: file buttons.ui line 119 +#: buttons.cpp:105 rc.cpp:20 rc.cpp:158 +#, no-c-format +msgid "Base" +msgstr "Normal" + +#. i18n: file config.ui line 16 +#: config.cpp:285 menu.cpp:419 rc.cpp:23 rc.cpp:161 +#, no-c-format +msgid "New Entry" +msgstr "Neue Verknüpfung" + +#. i18n: file config.ui line 47 +#: config.cpp:287 rc.cpp:29 rc.cpp:167 +#, no-c-format +msgid "F1" +msgstr "" + +#. i18n: file config.ui line 108 +#: config.cpp:292 rc.cpp:40 rc.cpp:178 +#, no-c-format +msgid "Extended Mode" +msgstr "Erweiterte Einstellungen" + +#. i18n: file config.ui line 122 +#: config.cpp:293 rc.cpp:43 rc.cpp:181 +#, no-c-format +msgid "Basic Settings" +msgstr "Basiseinstellungen" + +#. i18n: file config.ui line 153 +#: config.cpp:294 rc.cpp:46 rc.cpp:184 +#, no-c-format +msgid "Is a" +msgstr "Ist ein" + +#. i18n: file config.ui line 218 +#: config.cpp:296 rc.cpp:50 rc.cpp:188 +#, no-c-format +msgid "Command" +msgstr "Kommando" + +#. i18n: file config.ui line 226 +#: config.cpp:297 rc.cpp:53 rc.cpp:191 +#, no-c-format +msgid "Keywords" +msgstr "Schlüsselworte" + +#. i18n: file config.ui line 234 +#: config.cpp:298 rc.cpp:56 rc.cpp:194 +#, no-c-format +msgid "Name" +msgstr "Name" + +#. i18n: file config.ui line 242 +#: config.cpp:299 rc.cpp:59 rc.cpp:197 +#, no-c-format +msgid "Category" +msgstr "Kategorie" + +#. i18n: file config.ui line 255 +#: config.cpp:300 rc.cpp:62 rc.cpp:200 +#, no-c-format +msgid "Activate startup feedback" +msgstr "Startrückmeldung aktivieren" + +#. i18n: file config.ui line 263 +#: config.cpp:301 rc.cpp:65 rc.cpp:203 +#, no-c-format +msgid "Show in system tray" +msgstr "Im Systray anzeigen" + +#. i18n: file config.ui line 290 +#: config.cpp:302 rc.cpp:68 rc.cpp:206 +#, no-c-format +msgid "Description" +msgstr "Beschreibung" + +#. i18n: file config.ui line 314 +#: config.cpp:303 rc.cpp:71 rc.cpp:209 +#, no-c-format +msgid "Extended Settings" +msgstr "Erweiterte Einstellungen" + +#. i18n: file config.ui line 325 +#: config.cpp:304 rc.cpp:74 rc.cpp:212 +#, no-c-format +msgid "Working directory" +msgstr "Arbeitsverzeichnis" + +#. i18n: file config.ui line 347 +#: config.cpp:305 rc.cpp:77 rc.cpp:215 +#, no-c-format +msgid "Start in terminal" +msgstr "Im Terminal ausführen" + +#. i18n: file config.ui line 358 +#: config.cpp:306 rc.cpp:80 rc.cpp:218 +#, no-c-format +msgid "Terminal settings" +msgstr "Terminal Einstellungen" + +#. i18n: file config.ui line 388 +#: config.cpp:307 rc.cpp:83 rc.cpp:221 +#, no-c-format +msgid "Start as different user" +msgstr "Als anderer Benutzer starten" + +#. i18n: file config.ui line 399 +#: config.cpp:308 rc.cpp:86 rc.cpp:224 +#, no-c-format +msgid "Username" +msgstr "Benutzername" + +#. i18n: file config.ui line 429 +#: config.cpp:309 rc.cpp:89 rc.cpp:227 +#, no-c-format +msgid "Shortcut" +msgstr "Tastenkürzel" + +#. i18n: file config.ui line 459 +#: config.cpp:310 rc.cpp:92 rc.cpp:230 +#, no-c-format +msgid "None" +msgstr "" + +#. i18n: file help.ui line 73 +#: help.cpp:72 rc.cpp:98 rc.cpp:236 +#, no-c-format +msgid "" +"

    Menu entry editor

    \n" +"

    ----------------------------------------------------------------------------------" +"

    \n" +"

    Introduction

    \n" +"\n" +"By default, you will only see the basic settings for the new entry. Clicking " +"\"Show More\" will give you access to some extended settings that can be " +"interesting but mostly useless for you.

    \n" +"Bold options must be entered for a usefull entry, italic ones are " +"respected by the search feature.\n" +"

    \n" +"

    Basic settings

    \n" +"\n" +"Name:
    \n" +"This is the visible name of your new entry and can be any string, e.g. \"The " +"Gimp\".
    \n" +"(Necessary, searchkey)\n" +"

    \n" +"Is a:
    \n" +"Describes the applications genre (generic name), e.g. \"Image manipulation" +"\"
    \n" +"(Optional, yet not searched - maybe later)\n" +"

    \n" +"Category:
    \n" +"Choose an existing group or add a new one. The hierarchy is represented by " +"seperating slashes (\"/\"), if you want to enter a slash, you must escape it " +"(\"\\/\")
    \n" +"(Necessary, searchkey)\n" +"

    \n" +"Command:
    \n" +"The command to start the application, e.g. \"gimp-remote\". On *nix systems, " +"is usually not necessary to pass the full path to the executably, but you " +"can do so, if you want to start an executable that is shadowed by the " +"executable in the path dir, e.g. \"/usr/local/gimp-1.3/gimp-remote\"
    \n" +"(Necessary, not searched)\n" +"

    \n" +"Keywords:
    \n" +"Comma separated list of keywords that refer to this application during " +"search, e.g. \"image manipulation,pixel,photoshop\".
    \n" +"Please note:
    \n" +"1. search is not case sensitive
    \n" +"2. search finds partial matches, so it's not necessary to add e.g. " +"\"image,image manipulation\"
    \n" +"3. different from the applications name, the keyword list will be translated " +"(if) so if you think like \"'KImage' allready contains 'image', so i don't " +"need it as keyword\" you're wrong!
    \n" +"4. Finding good keywords is not simple, but in general use striking ones! " +"\"editor\" is not a very good keyword, as allmost everything is an editor. " +"(Gimp is a pixel-editor, KHexedit is a hex-editor, KEdit is a text-editor, a " +"config dialog is a config-editor, ...)
    \n" +"(Optional, searchkey)\n" +"

    \n" +"Description:
    \n" +"This is the longtext description of your application (not a helptext, " +"though ;), e.g. \"A powerfull image manipulator with a UI similar to " +"photoshop. Supports Layers, filters, scripting, blahblahblah...\"\n" +"You can use Qt richtext tags and there's no limit on the size, but keep it " +"usefull ;) let's say something about 200 chars at max.
    \n" +"(Optional, not searched)" +msgstr "" +"

    Verknüpfungseditor

    \n" +"

    ----------------------------------------------------------------------------------" +"

    \n" +"

    Einführung

    \n" +"\n" +"Standardmäßig werden nur die Basiseinstellungen für die neue Verknüpfung angezeigt. Indem man auf \"Erweiterte Einstellungen\" clickt, erhält man Zugriff auf einige weniger gebräuchliche Optionen.

    \n" +"Fettgedruckte Felder müssen für eine brauchbare Verknüpfung ausgefüllt werden, kursive werden von der Suchfunktion berücksichtigt.\n" +"

    \n" +"

    Basiseinstellungen

    \n" +"\n" +"Name:
    \n" +"Der sichtbare Name der Verknüpfung. Jede Zeichenkette ist erlaubt, z.B.\"The " +"Gimp\".
    \n" +"(Notwendig, Suchschlüssel)\n" +"

    \n" +"Ist ein:
    \n" +"Das Genre der Anwendung (genericName), z.B. \"Bildbearbeitung" +"\"
    \n" +"(Optional, derzeit nicht bei der Suche berücksichtigt)\n" +"

    \n" +"Kategorie:
    \n" +"Wählen Sie eine existierende Gruppe oder fügen sie eine neue hinzu. Die Hierarchie wird durch den \"/\" als Trennzeichen gekennzeichnet,wenn \"/\" Teil des Namens sein soll, muß ein \"\\\" vorangestellt werden (\"\\/\")
    \n" +"(Notwendig, Suchschlüssel (Der übersetzte Begriff))\n" +"

    \n" +"Kommando:
    \n" +"Das Kommando zum starten der Anwendung, z.B. \"gimp-remote\". Auf *nix Systemen ist es normalerweise nicht notwendig den vollen Pfad anzugeben, aber Sie können das tun, um eine Anwendung zu starten die durch eine andere überlagert wird, z.B. \"/usr/local/gimp-1.3/gimp-remote\"
    \n" +"(Notewndig, nicht durchsucht)\n" +"

    \n" +"Schlüsselworte:
    \n" +"Kommagetrennte Liste von Schlüsselworten für diese Anwendung, z.B. \"bildbearbeitung,pixel,photoshop\".
    \n" +"Anmerkungen:
    \n" +"1. Die Suche unterscheidet nicht zwischen GROSS und kleinschreibung
    \n" +"2. Die Suche findet auch Teilbegriffe, es ist also nicht notwendig z.B.\"Bild,Bildbearbeitung\" einzutragen
    \n" +"3. Anders als der Name der Anwendung, werden die Schlüssel übersetzt (wenn).- KImage hätte zwar \"image\" als schlüsselwort, aber nicht \"bild\"
    \n" +"4. Die Suche nach guten Schlüsselworten ist nicht immer leicht, aber sie sollten vor allem aussagekräftig sein!" +"\"editor\" ist kein besonders gutes Schlüsselwort, denn fast alles ist irgendwie ein Editor." +"(Gimp ist ein Pixel-Editor, KHexedit ist ein Hex-Editor, KEdit ist ein Text-Editor, ein Konfigurationsdialog ist ein Config-Editor, ...)
    \n" +"(Optional, Suchschlüssel)\n" +"

    \n" +"Beschreibung:
    \n" +"Die (längere) Beschreibung der Anwendung (aber kein Hilfetext ;), z.B. \"Eine mächtige Bildbearbeitung mit einer Photoshop ähnlichen Oberfläche. Unterstützt Ebenen, Filter, Scripte, blahblahblah...\"\n" +"Sie können Qt RichText tags verwenden und die Zeichenlänge ist nicht limitiert, sollte aber im vernünftigen Rahmen gehelten werden - maximal 200 Zeichen.
    \n" +"(Optional, nicht durchsucht)" + +#: menu.cpp:307 +msgid "" +"for TTS output, telling which item is focussed (keyboard) and than reads the " +"comment" +msgstr "" + +#: menu.cpp:338 +msgid "" +"for TTS output, telling which item is hovered (mouse) and than reads the " +"comment" +msgstr "" + +#: menu.cpp:392 menu.cpp:483 +msgid "Edit Entry" +msgstr "Verknüpfung modifizieren..." + +#: menu.cpp:393 +msgid "Remove Entry" +msgstr "Verknüpfung entfernen..." + +#: menu.cpp:395 +msgid "Add Entry" +msgstr "Neue Verknüpfung..." + +#: menu.cpp:446 +msgid "Are you sure you want to remove
    %1
    " +msgstr "Sind Sie sicher, daß sie
    %1
    eintfernen möchten?
    " + +#: menu.cpp:446 +msgid "Remove ALI entry" +msgstr "ALI Verknüpung entfernen" + +#: menu.cpp:614 +msgid "First Session Applications" +msgstr "Erstbenutzer Anwendungen" + +#: menu.cpp:620 menu.cpp:882 menu.cpp:954 +msgid "Favorite Applications
    " +msgstr "Beliebte Anwendungen
    " + +#: menu.cpp:872 +msgid "" +"for TTS output, informs the user that no entries are in the currently " +"selected group" +msgstr "" + +#: menu.cpp:939 +msgid "for TTS output, no entries match the current search text" +msgstr "" + +#: menu.cpp:953 +msgid "" +"First Session Applications
    This is a list of Applications you " +"might want to try out
    " +msgstr "" + +#: menu.cpp:1049 +msgid "Lock Session" +msgstr "" + +#: menu.cpp:1056 +msgid "Switch User" +msgstr "" + +#: menu.cpp:1062 +msgid "Logout" +msgstr "" + +#: menu.cpp:1160 +msgid "Type to search or enter a command" +msgstr "Tippen sie, um zu suchen oder ein Kommando direkt einzugeben" + +#: menu.cpp:1326 +msgid "TTS output" +msgstr "" + +#: starter.cpp:43 +msgid "Select Button Images ..." +msgstr "Skins auswählen..." + diff --git a/starter/po/starter.pot b/starter/po/starter.pot new file mode 100644 index 0000000..c2ecc2c --- /dev/null +++ b/starter/po/starter.pot @@ -0,0 +1,299 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2005-07-19 22:15+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. i18n: file buttons.ui line 16 +#: buttons.cpp:98 rc.cpp:3 rc.cpp:141 +#, no-c-format +msgid "Select Button Images" +msgstr "" + +#. i18n: file buttons.ui line 103 +#: buttons.cpp:103 rc.cpp:14 rc.cpp:152 +#, no-c-format +msgid "Down" +msgstr "" + +#. i18n: file buttons.ui line 111 +#: buttons.cpp:104 rc.cpp:17 rc.cpp:155 +#, no-c-format +msgid "Hover" +msgstr "" + +#. i18n: file buttons.ui line 119 +#: buttons.cpp:105 rc.cpp:20 rc.cpp:158 +#, no-c-format +msgid "Base" +msgstr "" + +#. i18n: file config.ui line 16 +#: config.cpp:285 menu.cpp:419 rc.cpp:23 rc.cpp:161 +#, no-c-format +msgid "New Entry" +msgstr "" + +#. i18n: file config.ui line 47 +#: config.cpp:287 rc.cpp:29 rc.cpp:167 +#, no-c-format +msgid "F1" +msgstr "" + +#. i18n: file config.ui line 108 +#: config.cpp:292 rc.cpp:40 rc.cpp:178 +#, no-c-format +msgid "Extended Mode" +msgstr "" + +#. i18n: file config.ui line 122 +#: config.cpp:293 rc.cpp:43 rc.cpp:181 +#, no-c-format +msgid "Basic Settings" +msgstr "" + +#. i18n: file config.ui line 153 +#: config.cpp:294 rc.cpp:46 rc.cpp:184 +#, no-c-format +msgid "Is a" +msgstr "" + +#. i18n: file config.ui line 218 +#: config.cpp:296 rc.cpp:50 rc.cpp:188 +#, no-c-format +msgid "Command" +msgstr "" + +#. i18n: file config.ui line 226 +#: config.cpp:297 rc.cpp:53 rc.cpp:191 +#, no-c-format +msgid "Keywords" +msgstr "" + +#. i18n: file config.ui line 234 +#: config.cpp:298 rc.cpp:56 rc.cpp:194 +#, no-c-format +msgid "Name" +msgstr "" + +#. i18n: file config.ui line 242 +#: config.cpp:299 rc.cpp:59 rc.cpp:197 +#, no-c-format +msgid "Category" +msgstr "" + +#. i18n: file config.ui line 255 +#: config.cpp:300 rc.cpp:62 rc.cpp:200 +#, no-c-format +msgid "Activate startup feedback" +msgstr "" + +#. i18n: file config.ui line 263 +#: config.cpp:301 rc.cpp:65 rc.cpp:203 +#, no-c-format +msgid "Show in system tray" +msgstr "" + +#. i18n: file config.ui line 290 +#: config.cpp:302 rc.cpp:68 rc.cpp:206 +#, no-c-format +msgid "Description" +msgstr "" + +#. i18n: file config.ui line 314 +#: config.cpp:303 rc.cpp:71 rc.cpp:209 +#, no-c-format +msgid "Extended Settings" +msgstr "" + +#. i18n: file config.ui line 325 +#: config.cpp:304 rc.cpp:74 rc.cpp:212 +#, no-c-format +msgid "Working directory" +msgstr "" + +#. i18n: file config.ui line 347 +#: config.cpp:305 rc.cpp:77 rc.cpp:215 +#, no-c-format +msgid "Start in terminal" +msgstr "" + +#. i18n: file config.ui line 358 +#: config.cpp:306 rc.cpp:80 rc.cpp:218 +#, no-c-format +msgid "Terminal settings" +msgstr "" + +#. i18n: file config.ui line 388 +#: config.cpp:307 rc.cpp:83 rc.cpp:221 +#, no-c-format +msgid "Start as different user" +msgstr "" + +#. i18n: file config.ui line 399 +#: config.cpp:308 rc.cpp:86 rc.cpp:224 +#, no-c-format +msgid "Username" +msgstr "" + +#. i18n: file config.ui line 429 +#: config.cpp:309 rc.cpp:89 rc.cpp:227 +#, no-c-format +msgid "Shortcut" +msgstr "" + +#. i18n: file config.ui line 459 +#: config.cpp:310 rc.cpp:92 rc.cpp:230 +#, no-c-format +msgid "None" +msgstr "" + +#. i18n: file help.ui line 73 +#: help.cpp:72 rc.cpp:98 rc.cpp:236 +#, no-c-format +msgid "" +"

    Menu entry editor

    \n" +"

    ----------------------------------------------------------------------------------" +"

    \n" +"

    Introduction

    \n" +"\n" +"By default, you will only see the basic settings for the new entry. Clicking " +"\"Show More\" will give you access to some extended settings that can be " +"interesting but mostly useless for you.

    \n" +"Bold options must be entered for a usefull entry, italic ones are " +"respected by the search feature.\n" +"

    \n" +"

    Basic settings

    \n" +"\n" +"Name:
    \n" +"This is the visible name of your new entry and can be any string, e.g. \"The " +"Gimp\".
    \n" +"(Necessary, searchkey)\n" +"

    \n" +"Is a:
    \n" +"Describes the applications genre (generic name), e.g. \"Image manipulation" +"\"
    \n" +"(Optional, yet not searched - maybe later)\n" +"

    \n" +"Category:
    \n" +"Choose an existing group or add a new one. The hierarchy is represented by " +"seperating slashes (\"/\"), if you want to enter a slash, you must escape it " +"(\"\\/\")
    \n" +"(Necessary, searchkey)\n" +"

    \n" +"Command:
    \n" +"The command to start the application, e.g. \"gimp-remote\". On *nix systems, " +"is usually not necessary to pass the full path to the executably, but you " +"can do so, if you want to start an executable that is shadowed by the " +"executable in the path dir, e.g. \"/usr/local/gimp-1.3/gimp-remote\"
    \n" +"(Necessary, not searched)\n" +"

    \n" +"Keywords:
    \n" +"Comma separated list of keywords that refer to this application during " +"search, e.g. \"image manipulation,pixel,photoshop\".
    \n" +"Please note:
    \n" +"1. search is not case sensitive
    \n" +"2. search finds partial matches, so it's not necessary to add e.g. " +"\"image,image manipulation\"
    \n" +"3. different from the applications name, the keyword list will be translated " +"(if) so if you think like \"'KImage' allready contains 'image', so i don't " +"need it as keyword\" you're wrong!
    \n" +"4. Finding good keywords is not simple, but in general use striking ones! " +"\"editor\" is not a very good keyword, as allmost everything is an editor. " +"(Gimp is a pixel-editor, KHexedit is a hex-editor, KEdit is a text-editor, a " +"config dialog is a config-editor, ...)
    \n" +"(Optional, searchkey)\n" +"

    \n" +"Description:
    \n" +"This is the longtext description of your application (not a helptext, " +"though ;), e.g. \"A powerfull image manipulator with a UI similar to " +"photoshop. Supports Layers, filters, scripting, blahblahblah...\"\n" +"You can use Qt richtext tags and there's no limit on the size, but keep it " +"usefull ;) let's say something about 200 chars at max.
    \n" +"(Optional, not searched)" +msgstr "" + +#: menu.cpp:307 +msgid "" +"for TTS output, telling which item is focussed (keyboard) and than reads the " +"comment" +msgstr "" + +#: menu.cpp:338 +msgid "" +"for TTS output, telling which item is hovered (mouse) and than reads the " +"comment" +msgstr "" + +#: menu.cpp:392 menu.cpp:483 +msgid "Edit Entry" +msgstr "" + +#: menu.cpp:393 +msgid "Remove Entry" +msgstr "" + +#: menu.cpp:395 +msgid "Add Entry" +msgstr "" + +#: menu.cpp:446 +msgid "Are you sure you want to remove
    %1
    " +msgstr "" + +#: menu.cpp:446 +msgid "Remove ALI entry" +msgstr "" + +#: menu.cpp:614 menu.cpp:953 +msgid "First Session Applications" +msgstr "" + +#: menu.cpp:620 menu.cpp:882 menu.cpp:954 +msgid "Favorite Applications
    " +msgstr "" + +#: menu.cpp:872 +msgid "" +"for TTS output, informs the user that no entries are in the currently " +"selected group" +msgstr "" + +#: menu.cpp:939 +msgid "for TTS output, no entries match the current search text" +msgstr "" + +#: menu.cpp:1049 +msgid "Lock Session" +msgstr "" + +#: menu.cpp:1056 +msgid "Switch User" +msgstr "" + +#: menu.cpp:1062 +msgid "Logout" +msgstr "" + +#: menu.cpp:1160 +msgid "Type to search or enter a command" +msgstr "" + +#: menu.cpp:1326 +msgid "TTS output" +msgstr "" + +#: starter.cpp:43 +msgid "Select Button Images ..." +msgstr "" diff --git a/starter/starter.cpp b/starter/starter.cpp new file mode 100644 index 0000000..9740888 --- /dev/null +++ b/starter/starter.cpp @@ -0,0 +1,483 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "starter.h" +#include "starterconfig.h" +#include "starterhelp.h" +#include "menu.h" + +#define _SIZE2VALUE_(_s_) (_s_ == 16) ? 0 :\ +(_s_ == 22) ? 1 :\ +(_s_ == 32) ? 2 :\ +(_s_ == 48) ? 3 : 4 + +#define _VALUE2SIZE_(_v_) (_v_ == 0) ? 16 :\ +(_v_ == 1) ? 22 :\ +(_v_ == 2) ? 32 :\ +(_v_ == 3) ? 48 : 64 + +starter::starter(const QString& configFile, Type type, int actions, QWidget *parent, const char *name) +: DCOPObject("StarterIface"), KPanelApplet(configFile, type, actions, parent, name) +{ + configPopup = new KPopupMenu(this); + popupBlocked = false; + mainView = new QLabel(this); + + configDialog = new StarterConfig(this); + QRect desktop = QDesktopWidget().availableGeometry( configDialog ); + configDialog->move((desktop.width() - configDialog->width())/2, (desktop.height() - configDialog->height())/2); + KConfig config("bStarter", false, false); + config.setGroup("Settings"); + configDialog->buttonShortcut->setEnabled(false); + configDialog->BaseURL->setURL(config.readEntry("BaseImage", "" )); + configDialog->HoverURL->setURL(config.readEntry("HoverImage", "" )); + configDialog->DownURL->setURL(config.readEntry("DownImage", "" )); + configDialog->useKTTS->setChecked(config.readBoolEntry("useKTTS", false )); + + configDialog->customPopupSize->setChecked(config.readBoolEntry("CustomPopupSize", false )); + configDialog->customDialogSize->setChecked(config.readBoolEntry("CustomDialogSize", false )); + configDialog->customDialogPos->setChecked(config.readBoolEntry("CustomDialogPos", false )); + configDialog->fixedDialogPos->setChecked(config.readBoolEntry("FixedDialogPos", false )); + configDialog->dialogFollowMouse->setChecked(config.readBoolEntry("DialogFollowMouse", false )); + configDialog->showDialogTitlebar->setChecked(config.readBoolEntry("ShowDialogTitlebar", false )); + configDialog->popupW->setValue(config.readNumEntry("PopupW", 0 )); + configDialog->popupH->setValue(config.readNumEntry("PopupH", 0 )); + configDialog->dialogW->setValue(config.readNumEntry("DialogW", 0 )); + configDialog->dialogH->setValue(config.readNumEntry("DialogH", 0 )); + configDialog->dialogX->setValue(config.readNumEntry("DialogX", 0 )); + configDialog->dialogY->setValue(config.readNumEntry("DialogY", 0 )); + configDialog->favItemAmount->setValue(config.readNumEntry("FavItemAmount", 10 )); + configDialog->dialogPanelPos->setCurrentItem(config.readNumEntry("DialogPanelPos", 1 )); + configDialog->popupPanelPos->setCurrentItem(config.readNumEntry("PopupPanelPos", 2 )); + _iconSize = config.readNumEntry("IconSize", 32 ); + configDialog->iconSize->setCurrentItem(_SIZE2VALUE_(_iconSize)); + + startMenu = new StartMenu(_iconSize, this, Qt::WType_Popup); + shortcutList = startMenu->shortcutList; + configDialog->categoryList->insertStringList(startMenu->categories()); + connect (startMenu, SIGNAL(aboutToHide()), this, SLOT(unblockPopupDelayed())); + connect(configDialog->useKTTS, SIGNAL(toggled( bool )), startMenu, SLOT(toggleKTTS(bool))); + + //--- + connect(configDialog->categoryList, SIGNAL(highlighted(int)), this, SLOT(activateShortcutButton(int))); + connect(configDialog->buttonShortcut, SIGNAL(capturedShortcut (const KShortcut &)), this, SLOT(addShortcut(const KShortcut &))); + connect(configDialog->categoryList, SIGNAL(highlighted ( const QString & )), this, SLOT(updateShortcutButton(const QString &))); + connect(configDialog->buttonOk, SIGNAL(clicked()), this, SLOT(updateSettings())); + StarterHelp *helpDialog = new StarterHelp(configDialog); + connect(configDialog->buttonHelp, SIGNAL(clicked()), helpDialog, SLOT(show())); + //----- + configPopup->insertItem(i18n("Configure the Startmenu"), configDialog, SLOT(show())); + configDialog->BaseURL->setFilter( "*.png" ); + configDialog->HoverURL->setFilter( "*.png" ); + configDialog->DownURL->setFilter( "*.png" ); + mainView->move(0,0); + if (parent) move(parent->x(),parent->y()); + mainView->installEventFilter(this); + reloadImages(); + mainView->setPixmap(pixmap); + mainView->show(); +} + +void starter::activateShortcutButton(int i) +{ + configDialog->buttonShortcut->setEnabled(bool(i)); +} + +void starter::addShortcut(const KShortcut &cut) +{ + // in case of empty shortcut, remove the entry from the list and return + if (!short(cut.keyCodeQt())) + { + ShortcutList::Iterator it; + for ( it = shortcutList.begin(); it != shortcutList.end(); ++it ) + if (it.data() == configDialog->categoryList->currentText()) + { + shortcutList.remove(it); + break; + } + configDialog->buttonShortcut->setShortcut(KShortcut::null(), false); + return; + } + // generate MyKey + short state = 0; + if (cut.seq(0).key(0).modFlags() & KKey::CTRL) + state |= Qt::ControlButton; + if (cut.seq(0).key(0).modFlags() & KKey::ALT) + state |= Qt::AltButton; + if (cut.seq(0).key(0).modFlags() & KKey::SHIFT) + state |= Qt::ShiftButton; + MyKey key(cut.seq(0).keyCodeQt(), state); + // Test if this is a valid shotrcut, i.e. contains 'ctrl' or 'alt', returns iff not + if (!(state & Qt::ControlButton || state & Qt::AltButton)) + { + KMessageBox::sorry(this, i18n("To ensure usefull behaviour of the searchline, the shortcut must contain a metabutton, i.e. 'ctrl' and/or 'alt'"), i18n("Sorry, invalid Shortcut")); + return; + } + // test if the cut was allready bound to another category and ask the user whta to do (return iff not rebind) + ShortcutList::Iterator it = shortcutList.find(key); + if ((it != shortcutList.end() && KMessageBox::questionYesNo(this, i18n("The selected shortcut is allready bound to the category \"%1\".
    Do you want to rebind it?
    ").arg(it.data()), i18n("Rebind Shortcut?")) == KMessageBox::No)) + return; + // if rebind (it is not end and we did not return ;) remove the old shortcut + if (it != shortcutList.end()) + { + shortcutList.remove(it); + } + // test if another shortcut is bound to this category and remove it in case + for ( it = shortcutList.begin(); it != shortcutList.end(); ++it ) + if (it.data() == configDialog->categoryList->currentText()) + { + shortcutList.remove(it); + break; + } + // add new shortcut/category map entry + shortcutList[key] = configDialog->categoryList->currentText(); + // update UI + configDialog->buttonShortcut->setShortcut(cut, false); +} + +void starter::updateShortcutButton(const QString & category) +{ + ShortcutList::Iterator it; + for ( it = shortcutList.begin(); it != shortcutList.end(); ++it ) + if (it.data() == category) + { + QKeyEvent qke( QEvent::KeyPress, it.key().key(), 0, it.key().modFlags()); + KKey kkey(&qke); + KShortcut ksc(kkey); + configDialog->buttonShortcut->setShortcut(ksc, false); + return; + } + configDialog->buttonShortcut->setShortcut(KShortcut::null(), false); +} + +starter::~starter() +{ +} + +void starter::updateSettings() +{ + startMenu->updateShortcuts(shortcutList); + KConfig *config = new KConfig("bStarter", false, false); + config->setGroup("Settings"); + config->writeEntry("BaseImage", configDialog->BaseURL->url()); + config->writeEntry("HoverImage", configDialog->HoverURL->url()); + config->writeEntry("DownImage", configDialog->DownURL->url()); + config->writeEntry("useKTTS", configDialog->useKTTS->isChecked()); + config->writeEntry("CustomPopupSize", configDialog->customPopupSize->isChecked()); + config->writeEntry("CustomDialogSize", configDialog->customDialogSize->isChecked()); + config->writeEntry("CustomDialogPos", configDialog->customDialogPos->isChecked()); + config->writeEntry("FixedDialogPos", configDialog->fixedDialogPos->isChecked()); + config->writeEntry("DialogFollowMouse", configDialog->dialogFollowMouse->isChecked()); + config->writeEntry("ShowDialogTitlebar", configDialog->showDialogTitlebar->isChecked()); + config->writeEntry("PopupW", configDialog->popupW->value()); + config->writeEntry("PopupH", configDialog->popupH->value()); + config->writeEntry("DialogW", configDialog->dialogW->value()); + config->writeEntry("DialogH", configDialog->dialogH->value()); + config->writeEntry("DialogX", configDialog->dialogX->value()); + config->writeEntry("DialogY", configDialog->dialogY->value()); + config->writeEntry("FavItemAmount", configDialog->favItemAmount->value()); + config->writeEntry("DialogPanelPos", configDialog->dialogPanelPos->currentItem()); + config->writeEntry("PopupPanelPos", configDialog->popupPanelPos->currentItem()); + if (_iconSize != (_VALUE2SIZE_(configDialog->iconSize->currentItem()))) + { + _iconSize = _VALUE2SIZE_(configDialog->iconSize->currentItem()); + config->writeEntry("IconSize", _iconSize); + startMenu->reloadIcons(_iconSize); + } + startMenu->setFavItemAmount(configDialog->favItemAmount->value()); + config->setGroup("Shortcuts"); + QStringList cuts; QStringList cats; + ShortcutList::Iterator it; + for ( it = shortcutList.begin(); it != shortcutList.end(); ++it ) + { + cuts.append(it.key().toString()); + cats.append(it.data()); + } + config->writeEntry("Shortcuts", cuts, ','); + config->writeEntry("Categories", cats, ','); + reloadImages(); + delete config; +} + +#define _VALID_(_url_) configDialog && !configDialog->_url_->url().isEmpty() && QFile::exists(configDialog->_url_->url()) + +void starter::reloadImages() +{ + KIconLoader* iLoader = KGlobal::iconLoader(); + QString pth; + if (_VALID_(BaseURL)) + pth = configDialog->BaseURL->url(); + else + pth = iLoader->iconPath("bStarter", KIcon::Small, true); + if (pth) + pixmap = QImage(pth); + if (!pth || pixmap.isNull()) + { + pixmap = QPixmap(22,22); + pixmap.fill(Qt::black); + } + pth = QString(); + if (_VALID_(HoverURL)) + pth = configDialog->HoverURL->url(); + else + pth = iLoader->iconPath("bStarter_hover", KIcon::Small, true); + if (pth) + hoverPixmap = QImage(pth); + if (!pth || hoverPixmap.isNull()) + { + hoverPixmap = QPixmap(22,22); + hoverPixmap.fill(Qt::black); + } + pth = QString(); + if (_VALID_(DownURL)) + pth = configDialog->DownURL->url(); + else + pth = iLoader->iconPath("bStarter_down", KIcon::Small, true); + if (pth) + downPixmap = QImage(pth); + if (!pth || downPixmap.isNull()) + { + downPixmap = QPixmap(22,22); + downPixmap.fill(Qt::white); + } + int wd = pixmap.width(); + int ht = pixmap.height(); + if (wd < hoverPixmap.width()) wd = hoverPixmap.width(); + if (wd < downPixmap.width()) wd = downPixmap.width(); + if (ht < hoverPixmap.height()) ht = hoverPixmap.height(); + if (ht < downPixmap.height()) ht = downPixmap.height(); + mainView->setFixedSize(wd,ht); + repaint(); +} + +void starter::resizeEvent ( QResizeEvent *rev ) +{ + pixmap = pixmap.convertToImage().smoothScale(rev->size().height()*pixmap.width()/pixmap.height(),rev->size().height()); + downPixmap = downPixmap.convertToImage().smoothScale(rev->size().height()*downPixmap.width()/downPixmap.height(),rev->size().height()); + hoverPixmap = hoverPixmap.convertToImage().smoothScale(rev->size().height()*hoverPixmap.width()/hoverPixmap.height(),rev->size().height()); + mainView->setFixedSize(rev->size().height()*mainView->width()/mainView->height(),rev->size().height()); + mainView->setPixmap(pixmap); + KPanelApplet::resizeEvent(rev); +} + +void starter::configureMenu() +{ + KApplication::startServiceByDesktopName("kmenuedit", QStringList(), 0, 0, 0, "", true); +} + +void starter::preferences() +{ + KApplication::startServiceByDesktopName("kmenuedit", QStringList(), 0, 0, 0, "", true); +} + +int starter::widthForHeight(int height) const +{ + return mainView->width(); +} + +int starter::heightForWidth(int width) const +{ + return mainView->height(); +} + +void starter::unblockPopupDelayed() +{ + popupBlocked = true; + QTimer::singleShot ( 50, this, SLOT(unblockPopup()) ); +} + +void starter::unblockPopup() +{ + popupBlocked = false; + if (mainView->hasMouse()) + mainView->setPixmap(hoverPixmap); + else + mainView->setPixmap(startMenu->isShown() ? downPixmap : pixmap); + mainView->repaint(); +} + +#define _MAX_(a,b) (a > b ? a : b) +void starter::popupMenu() +{ + if (popupBlocked) + return; + { +// if (!isDialog_) +// return; + startMenu->setMinimumSize ( 0, 0 ); + startMenu->setMaximumSize ( 32767, 32767 ); + setActiveWindow(); + startMenu->setPanelPosition((StartMenu::PanelPosition)configDialog->popupPanelPos->currentItem()); + if (configDialog->customPopupSize->isChecked()) + { + startMenu->resize(configDialog->popupW->value(),configDialog->popupH->value()); + startMenu->setFixedSize(startMenu->size()); +// startMenu->setFixedSize(_MAX_(configDialog->popupW->value(), startMenu->minimumWidth()), _MAX_(configDialog->popupH->value(), startMenu->minimumHeight())); + } + else + { + QRect desktop = QDesktopWidget().availableGeometry( startMenu ); + startMenu->resize(desktop.width()/5, 2*desktop.height()/3); + startMenu->setFixedSize(startMenu->size()); +// startMenu->setFixedSize(_MAX_(startMenu->minimumWidth(), desktop.width()/5) ,_MAX_(startMenu->minimumHeight(), 2*desktop.height()/3)); // 1/5 screen width, 2/3 screen height + } + + QPoint pt = mapToGlobal(pos()); + QRect desktop = QDesktopWidget().availableGeometry( startMenu ); + int x = pt.x(); + int y = pt.y(); + + switch(position()) + { + case pTop: + y += height() + 1; + if (x + startMenu->width() > desktop.right()) + x = desktop.right() - startMenu->width(); + if (x < 0) x = 0; + break; + case pLeft: + x += width() + 1; + if (y + startMenu->height() > desktop.bottom()) + y = desktop.bottom() - startMenu->height(); + if (y < 0) y = 0; + break; + case pBottom: + y -= startMenu->height() - 1; + if (x + startMenu->width() > desktop.right()) + x = desktop.right() - startMenu->width(); + if (x < 0) x = 0; + break; + case pRight: + x -= startMenu->width() - 1; + if (y + startMenu->height() > desktop.bottom()) + y = desktop.bottom() - startMenu->height(); + if (y < 0) y = 0; + } + pt = QPoint(x, y); + + startMenu->reparent(this, Qt::WType_Popup, pt, true); + } +} + +void starter::showMenu() +{ + startMenu->setMinimumSize ( 0, 0 ); + startMenu->setMaximumSize ( 32767, 32767 ); + startMenu->setPanelPosition((StartMenu::PanelPosition)configDialog->dialogPanelPos->currentItem()); + if (configDialog->customDialogSize->isChecked()) + { + startMenu->resize(configDialog->dialogW->value(), configDialog->dialogH->value()); + startMenu->setFixedSize(startMenu->size()); +// startMenu->setFixedSize(_MAX_(configDialog->dialogW->value(), startMenu->minimumWidth()), _MAX_(startMenu->minimumHeight(), configDialog->dialogH->value())); + } + else + { + QRect desktop = QDesktopWidget().availableGeometry( startMenu ); +// setActiveWindow(); + startMenu->resize(desktop.width()/2, desktop.width()*9/32); + startMenu->setFixedSize(startMenu->size()); +// startMenu->setFixedSize(_MAX_(startMenu->minimumWidth(), desktop.width()/2) , _MAX_(startMenu->minimumHeight(), desktop.width()*9/32)); // 16:9 window, width == 1/2 screen + } + QPoint pt; + if (configDialog->customDialogPos->isChecked()) + { + if (configDialog->dialogFollowMouse->isChecked()) + { + QRect desktop = QDesktopWidget().availableGeometry( startMenu ); + int x,y; + x = QCursor::pos().x() + startMenu->width()/2 < desktop.width() ? QCursor::pos().x() - startMenu->width()/2 : desktop.width() - startMenu->width(); + if (x < 0) x = 0; + y = QCursor::pos().y() + startMenu->height()/2 < desktop.height() ? QCursor::pos().y() - startMenu->height()/2 : desktop.height() - startMenu->height(); + if (y < 0) y = 0; + pt = QPoint(x, y); + } + else + pt = QPoint(configDialog->dialogX->value(), configDialog->dialogY->value()); + } + else + { + QRect desktop = QDesktopWidget().availableGeometry( startMenu ); + pt = QPoint((desktop.right() - startMenu->width())/2, (desktop.bottom() - startMenu->height())/2); + } + if (configDialog->showDialogTitlebar->isChecked()) + startMenu->reparent(this, Qt::WType_TopLevel, pt, true); + else + startMenu->reparent(this, Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_NoBorder, pt, true); +} + +bool starter::eventFilter( QObject*, QEvent *e ) +{ + switch (e->type()) + { + case QEvent::Enter: + { + mainView->setPixmap(hoverPixmap); + mainView->repaint(); + return TRUE; + } + case QEvent::Leave: + { + mainView->setPixmap(startMenu->isShown() ? downPixmap : pixmap); + mainView->repaint(); + return TRUE; + } + case QEvent::MouseButtonPress: + { + if (((QMouseEvent*)e)->button() == Qt::RightButton) + { + configPopup->popup(((QMouseEvent*)e)->globalPos()); + return TRUE; + } + if (((QMouseEvent*)e)->button() == Qt::LeftButton) + { + mainView->setPixmap(downPixmap); + mainView->repaint(); + popupMenu(); + } + return TRUE; + } + case QEvent::MouseButtonRelease: + { + if (((QMouseEvent*)e)->button() != Qt::LeftButton) + return FALSE; + if (mainView->hasMouse()) + mainView->setPixmap(hoverPixmap); + else + mainView->setPixmap(startMenu->isShown() ? downPixmap : pixmap); + mainView->repaint(); + return TRUE; + } + default: + return FALSE; + } +} + +extern "C" +{ + KPanelApplet* init( QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("starter"); + return new starter(configFile, KPanelApplet::Normal, + KPanelApplet::Preferences, + parent, "baghirastarter"); + } +} diff --git a/starter/starter.desktop b/starter/starter.desktop new file mode 100644 index 0000000..cfc27dc --- /dev/null +++ b/starter/starter.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Baghira Starter +Icon=bStarter +X-KDE-Library=libbaghirastarter +X-KDE-UniqueApplet=true + diff --git a/starter/starter.h b/starter/starter.h new file mode 100644 index 0000000..39c72b9 --- /dev/null +++ b/starter/starter.h @@ -0,0 +1,72 @@ + +#ifndef STARTER_H +#define STARTER_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +// #include +#include +#include +#include "starteriface.h" +#include "mykey.h" + +class DCOPClient; +class QLabel; +class KPopupMenu; +class StartMenu; +class StarterConfig; + +class starter : public KPanelApplet, virtual public StarterIface +{ + Q_OBJECT + +public: + starter(const QString& configFile, Type t = Normal, int actions = 0, + QWidget *parent = 0, const char *name = 0); + ~starter(); + + virtual int widthForHeight(int height) const; + virtual int heightForWidth(int width) const; + virtual void preferences(); + void popupMenu(); + void showMenu(); +protected: + virtual void resizeEvent ( QResizeEvent * ); + +private: + enum State {Default, Hover, Down}; + State state; + int _iconSize; + bool eventFilter( QObject *o, QEvent *e ); + bool popupBlocked; +// bool isDialog_; + QLabel *mainView; +// QPainter m_painter; + DCOPClient *client; + KPopupMenu *configPopup; + StartMenu *startMenu; + QPixmap pixmap; + QPixmap hoverPixmap; + QPixmap downPixmap; + StarterConfig *configDialog; + typedef QMap ShortcutList; + ShortcutList shortcutList; +private slots: + void addShortcut(const KShortcut&); + void updateShortcutButton(const QString&); + void configureMenu(); + void reloadImages(); + void updateSettings(); +// void blockMenu(); + void unblockPopupDelayed(); + void unblockPopup(); + void activateShortcutButton(int); +}; + +#endif diff --git a/starter/starterconfig.ui b/starter/starterconfig.ui new file mode 100644 index 0000000..a703e45 --- /dev/null +++ b/starter/starterconfig.ui @@ -0,0 +1,872 @@ + +StarterConfig + + + StarterConfig + + + + 0 + 0 + 492 + 674 + + + + Baghira Starter Config + + + true + + + + unnamed + + + + groupBox5 + + + Startbutton images + + + + unnamed + + + + BaseURL + + + + + textLabel2_3 + + + <b>Hover</b> + + + + + HoverURL + + + + + textLabel1_2 + + + <b>Base</b> + + + + + textLabel3 + + + <b>Down</b> + + + + + DownURL + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + F1 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + buttonGroup1 + + + Dialog options + + + + unnamed + + + + layout10 + + + + unnamed + + + + customDialogSize + + + true + + + Custom dialog size + + + + + dialogW + + + false + + + 3000 + + + + + textLabel2 + + + x + + + + + dialogH + + + false + + + 2000 + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 111 + 20 + + + + + + + + dialogFollowMouse + + + false + + + Show dialog under mouse + + + + + layout12 + + + + unnamed + + + + fixedDialogPos + + + false + + + Fixed + + + + + dialogX + + + false + + + + + textLabel2_2 + + + : + + + + + dialogY + + + false + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 80 + 20 + + + + + + + + customDialogPos + + + Custom dialog position + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + showDialogTitlebar + + + Show titlebar for dialog + + + + + line2 + + + HLine + + + Sunken + + + Horizontal + + + + + line2_3 + + + HLine + + + Sunken + + + Horizontal + + + + + layout6 + + + + unnamed + + + + textLabel1_3 + + + true + + + Panel Position + + + + + + North + + + + + South + + + + + West + + + + + East + + + + + Nowhere + + + + dialogPanelPos + + + true + + + 1 + + + + + + + + + groupBox6 + + + Popup options + + + + unnamed + + + + layout11 + + + + unnamed + + + + customPopupSize + + + true + + + Custom popup size + + + + + popupW + + + false + + + 3000 + + + + + textLabel1 + + + x + + + + + popupH + + + false + + + 2000 + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 141 + 20 + + + + + + + + line2_2 + + + HLine + + + Sunken + + + Horizontal + + + + + layout6_2 + + + + unnamed + + + + textLabel1_3_2 + + + true + + + Panel Position + + + + + + North + + + + + South + + + + + West + + + + + East + + + + + Nowhere + + + + popupPanelPos + + + true + + + 2 + + + + + + + + + groupBox4 + + + + + + + unnamed + + + + layout9 + + + + unnamed + + + + textLabel2_4 + + + Items in favorite list + + + + + favItemAmount + + + 10 + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + line1_2 + + + HLine + + + Sunken + + + Horizontal + + + + + useKTTS + + + Talk to me (via KTTS) + + + + + layout9 + + + + unnamed + + + + textLabel1_4 + + + Icon SIze + + + + + + 16/22 + + + + + 22/32 + + + + + 32/48 + + + + + 48/64 + + + + + 64/128 + + + + iconSize + + + + + + + + + groupBox7 + + + Shortcuts + + + + unnamed + + + + categoryList + + + AlwaysOff + + + + + layout18 + + + + unnamed + + + + spacer14 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonShortcut + + + None + + + + + spacer15 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + + + buttonOk + clicked() + StarterConfig + accept() + + + buttonCancel + clicked() + StarterConfig + reject() + + + customPopupSize + toggled(bool) + popupW + setEnabled(bool) + + + customPopupSize + toggled(bool) + popupH + setEnabled(bool) + + + buttonCancel + toggled(bool) + dialogX + setEnabled(bool) + + + customDialogSize + toggled(bool) + dialogW + setEnabled(bool) + + + customDialogSize + toggled(bool) + dialogH + setEnabled(bool) + + + customDialogPos + toggled(bool) + fixedDialogPos + setEnabled(bool) + + + customDialogPos + toggled(bool) + dialogFollowMouse + setEnabled(bool) + + + fixedDialogPos + toggled(bool) + dialogX + setEnabled(bool) + + + fixedDialogPos + toggled(bool) + dialogY + setEnabled(bool) + + + customDialogPos + toggled(bool) + fixedDialogPos + setChecked(bool) + + + customDialogPos + toggled(bool) + dialogFollowMouse + setChecked(bool) + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + kurlrequester.h + klineedit.h + kpushbutton.h + kurlrequester.h + klineedit.h + kpushbutton.h + kkeybutton.h + + diff --git a/starter/starterhelp.ui b/starter/starterhelp.ui new file mode 100644 index 0000000..a0bf868 --- /dev/null +++ b/starter/starterhelp.ui @@ -0,0 +1,121 @@ + +StarterHelp + + + StarterHelp + + + + 0 + 0 + 510 + 582 + + + + Baghira Starter Config Help + + + + unnamed + + + + tabWidget2 + + + + tab + + + Filterline + + + + unnamed + + + + textLabel5 + + + <qt>The filterline provides several functions +<ul> +<li>It filters the below entry list</li> +<li>It autocompletes to executable entries in $PATH</li> +<li>The applied listbox lets you select the available categories</li> +<li>You can navigate through the categories either by using the mousewheel or by holding <b>ctrl+up/down</b></li> +<li>The category is also selected when calling the applied shortcut</li> +<li>It supports all protocols you know from Konqueror, e.g. "gg:Baghira" will google for "Baghira" etc.</li> +</ul> +Pressing <b>Enter</b> will execute the (autocompleted) binary in $PATH or the entered kfm protocol call<br> +Pressing <b>down</b> will move the keyboard focus to the below entry list +</qt> + + + + + + + tab + + + Entry Field + + + + unnamed + + + + textLabel6 + + + <qt>The entry field shows up all your menu entries (filtered)<br><br> +You can start an application by clicking the <b>left mouse button</b> above the item (highlighted text) or by pressing <b>Enter</b> if the entry has the keyboard focus (highlighted background).<br><br> +You may navigate by either scrolling the <b>mousewheel</b> or using the <b>up/down</b> keys (this will also shift the keyboard focus)<br><br> +Pressing the <b>left</b> key will put focus on the filterline and select the whole text (i.e. start typing will change a complete new filter action)<br><br> +Pressing the <b>up</b> key on the topmost item will act as above.</qt> + + + + + + + TabPage + + + Panel + + + + unnamed + + + + textLabel1 + + + <qt>The panel allow you to store often used links, independent from the application links in the entry list<br><br> +To <b>add a link</b>, either:<br> +- rightclick the panel<br> +- drag and drop a link out of the entry list<br> +- drag and drop any url or text or command (uris and mails are handled, the rest is interpreted as simple command, any command that works on the filterline works here as well)<br> +<br> +To <b>remove a link</b>, simply drag it out and drop it outside. (The panel interacts with the linklist from the baghira sidebar, links won't be removed, but copied if dragged from one to the other)<br> +<br> +To <b>configure a link</b>, simply rightclick it<br><br> +To <b>move a link</b>, just drag it and move i around.<br><br> + +Te panel is <b>scrollable (mousewheel)</b> and you can configure <b>individual positions</b> for the popup and the dialog<br><br> +More poofs can be found e.g. here: <a href="http://www.resexcellence.com/user_poofs.shtml">www.resexcellence.com/user_poofs.shtml</a> +</qt> + + + + + + + + + diff --git a/starter/starteriface.h b/starter/starteriface.h new file mode 100644 index 0000000..be1469f --- /dev/null +++ b/starter/starteriface.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _STARTERIFACE_H_ +#define _STARTERIFACE_H_ + +#include + +class StarterIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual void popupMenu() = 0; + virtual void showMenu() = 0; +}; + +#endif diff --git a/starter/subdirs b/starter/subdirs new file mode 100644 index 0000000..6cddb31 --- /dev/null +++ b/starter/subdirs @@ -0,0 +1 @@ +po diff --git a/style/Makefile.am b/style/Makefile.am new file mode 100644 index 0000000..2094915 --- /dev/null +++ b/style/Makefile.am @@ -0,0 +1,16 @@ +AM_CPPFLAGS = -DQT_PLUGIN + +INCLUDES = -I$(top_srcdir)/kdefx $(all_includes) +noinst_HEADERS = baghira.h pixmaps.h bitmaps.h +METASOURCES = AUTO +kde_style_LTLIBRARIES = baghira.la +baghira_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +baghira_la_LIBADD = -lkdefx -lXtst $(LIB_KDEUI) +baghira_la_SOURCES = baghira.cpp optionHandler.cpp polish.cpp utils.cpp +lnkdir = $(kde_datadir)/kstyle/themes +lnk_DATA = baghira.themerc +EXTRA_DIST = $(lnk_DATA) +pixmaps.h: $(srcdir)/generatePixmaps.sh + $(SHELL) $(srcdir)/generatePixmaps.sh $(top_srcdir) +CLEANFILES = pixmaps.h +baghira.lo: pixmaps.h diff --git a/style/baghira.cpp b/style/baghira.cpp new file mode 100644 index 0000000..bae1611 --- /dev/null +++ b/style/baghira.cpp @@ -0,0 +1,3384 @@ +#include "baghira.h" +#include "bitmaps.h" +#include "pixmaps.h" +//#include "../deco/baghiradecobuttons.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +#define PRINTDEVICE(p) qWarning("device is %s", (p->device()->devType() == QInternal::Widget) ?\ +"Widget": (p->device()->devType() == QInternal::Pixmap) ?\ +"Pixmap": (p->device()->devType() == QInternal::Printer) ?\ +"Printer": (p->device()->devType() == QInternal::Picture) ?\ +"Picture": (p->device()->devType() == QInternal::UndefinedDevice) ?\ +"UndefinedDevice": "fuckdevice!" ); + +#define GCC_VERSION (__GNUC__ * 10000 \ ++ __GNUC_MINOR__ * 100 \ ++ __GNUC_PATCHLEVEL__) + +static const int windowsItemFrame = 1; // menu item frame width +static const int windowsSepHeight = 2; // separator item height +static const int windowsItemHMargin = 3; // menu item hor text margin +static const int windowsItemVMargin = 1; // menu item ver text margin +static const int windowsArrowHMargin = 6; // arrow horizontal margin +static const int windowsTabSpacing = 12; // space between text and tab +static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark +static const int windowsRightBorder = 12; // right border on windows +static const int windowsCheckMarkWidth = 12; // checkmarks width on windows + +// options +int OptionHandler::menuBackground; +int OptionHandler::menuOpacity; +bool OptionHandler::menuColorButton; +bool OptionHandler::shadowText; +//color +QColor OptionHandler::customButtonColor, OptionHandler::menuStripeColor_; +//widgets +bool OptionHandler::customWidgetColor; +QColor OptionHandler::customColors[ 10 ]; +//menu +bool OptionHandler::useCustomMenuColor; +QColor OptionHandler::color, OptionHandler::color2, OptionHandler::colorHigh, OptionHandler::fgColor, OptionHandler::fgColorHigh; +//Panel +// bool OptionHandler::panelCustom; +// QColor OptionHandler::customPanelColor; +//incativeButton +int OptionHandler::inactiveButtonColor; +QColor OptionHandler::customInactiveButtonColor; + +//Design +//stipples +bool OptionHandler::bgStipple, /*OptionHandler::panelStipple,*/ OptionHandler::bevelHighlights_, OptionHandler::drawMenuStripe_, OptionHandler::glossyMenus_; +Style OptionHandler::style_; +int OptionHandler::contrast; +//shadows +bool OptionHandler::groupboxshadow; +int OptionHandler::shadowDarkness; +//istviews; +bool OptionHandler::drawDotlines, OptionHandler::useCustomExpanderColor; +int OptionHandler::expanderStyle; +QColor OptionHandler::expanderColor, OptionHandler::dotlineColor; +int OptionHandler::dotlineStyle; +//slider +bool OptionHandler::squeezesbslider; +bool OptionHandler::shadowsbslider; +bool OptionHandler::animateSlider; +bool OptionHandler::animateProgress; +//toolbar +bool OptionHandler::reverseBtnColor, OptionHandler::tbFrame; +//tweaks +bool OptionHandler::centerTabs; +bool OptionHandler::smoothListViewHeaders; +bool OptionHandler::smootherLVH; +bool OptionHandler::icyButtons; +Style OptionHandler::_buttonStyle; +int OptionHandler::progressBar; +bool OptionHandler::removeKickerBevel; +Style OptionHandler::_toolbuttonStyle; +bool OptionHandler::drawProgressLabel; +QColor OptionHandler::brushTint; +QColor OptionHandler::aDecoColor1_; +QColor OptionHandler::aDecoColor2_; +QColor OptionHandler::titleColor_[2]; +QColor OptionHandler::titleButtonColor_[3]; +bool OptionHandler::tintBrush; +tabStyle OptionHandler::tabStyle_; +unsigned long OptionHandler::wmDesign; +bool OptionHandler::animateButton; +int OptionHandler::custCols[8]; + +QPixmap LiquidStyle::popupBack; + +//============ + +class KAccessToolBarButton : public KToolBarButton +{ +// to get me access to the toolbbar + friend class LiquidStyle; +public: + KAccessToolBarButton( QWidget* parent=0, const char* name=0 ) + : KToolBarButton( parent, name ) {} +}; + + +class LiquidStylePlugin : public QStylePlugin { + public: + LiquidStylePlugin() { + ; + } + ~LiquidStylePlugin() { + ; + } + + QStringList keys() const { + return ( QStringList() << "Baghira" ); + } + QStyle *create( const QString & ); + }; + +QStyle *LiquidStylePlugin::create( const QString &s ) { + if ( s.lower() == "baghira" ) + return ( new LiquidStyle() ); + return ( 0 ); + } + +Q_EXPORT_PLUGIN( LiquidStylePlugin ) + +static const int itemFrame = 1; +static const int itemHMargin = 3; +static const int itemVMargin = 1; +static const int arrowHMargin = 6; +static const int rightBorder = 12; + + +LiquidStyle::LiquidStyle() : KStyle( AllowMenuTransparency | FilledFrameWorkaround, ThreeButtonScrollBar ) +{ + QIntDictbfi(31);// assuming 31 btns will be enough - a pointer list would be more accurate, but we need to lookup this every 50ms... + QIntDictbtnShadowedDict(223);// we need around 10/color, 3 colors/button assuming 10 different colors (e.g. kcalc) + QIntDictbuttonGlowDict(109); + QIntDictbuttonDict(331); + headerHoverID = -1; + headerSortID = -1; + hoveredTabIndex = -1; + currentTabBar = 0L; + paintWidget = 0L; + highlightWidget = 0L; + currentTaskContainer = 0L; + taskContainerHover = false; + isTaskContainer = false; + isHTMLButton = false; + inExitPolish = false; + inactiveRoundFrame = 0L; + activeRoundFrame = 0L; + eventKiller = new EventKiller; + bmShower = 0L; // only if b/m + + btnDict.setAutoDelete( true ); + btnShadowedDict.setAutoDelete( true ); + bfi.setAutoDelete( true ); +// inverseTabDict.setAutoDelete( true ); +// tabDict.setAutoDelete( true ); + initialPaletteLoaded = false; + qtrcModificationTime = 0; + + // animations kram! + progAnimShift = 0; + prog2AnimShift = 0; + sliderAnimShift = 0; + QTimer* timer = new QTimer( this ); + timer->start(50, false); +// if (optionHandler->AnimateProgress()) + connect(timer, SIGNAL(timeout()), this, SLOT(updateProgressPos())); + activeScroller = NULL; + //-------------------------------------- + + tooltipPalette = qApp->palette(); + tooltipPalette.setBrush( QColorGroup::Background, QColor( 255, 255, 220 ) ); + tooltipPalette.setBrush( QColorGroup::Foreground, Qt::black ); + + rMatrix.rotate( 90.0 ); + lMatrix.rotate( 270.0 ); + iMatrix.rotate( 180.0 ); + mMatrix.setMatrix ( -1, 0, 0, 1, 0, 0); + m2Matrix.setMatrix ( 1, 0, 0, -1, 0, 0); + + optionHandler = new OptionHandler( this ); + if (optionHandler->style() != Milk && optionHandler->AnimateSlider()) + connect(timer, SIGNAL(timeout()), this, SLOT(updateSliderPos())); + if (optionHandler->style() == Brushed) + bmShower = new BMShower(this); + + switch (optionHandler->buttonStyle()) + { + case Jaguar: + btnBorderImg = new QImage( uic_findImage("button-jaguar") ); + btnShadowImg = new QImage( uic_findImage( "button-shadow" ) ); + buttonGlow = new QImage( uic_findImage( "button-glow" ) ); + combo = new QImage( uic_findImage("combo-jaguar") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + if (optionHandler->toolbuttonStyle() == Brushed || !optionHandler->SmoothListViewHeaders()) + rectbutton = new QImage( uic_findImage( "rectbutton" ) ); + else rectbutton = 0L; + break; + case Panther: + case Tiger: + btnBorderImg = new QImage( uic_findImage("button-base") ); + btnShadowImg = new QImage( uic_findImage( "button-shadow" ) ); + buttonGlow = new QImage( uic_findImage( "button-glow" ) ); + combo = new QImage( uic_findImage("combo") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + if (optionHandler->toolbuttonStyle() == Brushed || !optionHandler->SmoothListViewHeaders()) + rectbutton = new QImage( uic_findImage( "rectbutton" ) ); + else rectbutton = 0L; + break; + case Brushed: + btnBorderImg = 0L; + btnShadowImg = 0L; + buttonGlow = 0L; + rectbutton = new QImage( uic_findImage( "rectbutton" ) ); + switch (optionHandler->toolbuttonStyle()) + { + case Jaguar: + combo = new QImage( uic_findImage("combo-jaguar") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + break; + case Panther: + case Tiger: + case Brushed: + combo = new QImage( uic_findImage("combo") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + break; + case Milk: + combo = new QImage( uic_findImage("combo-milk") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + default: + break; + } + break; + case Milk: + btnBorderImg = new QImage( uic_findImage("button-milk") ); + btnShadowImg = 0L; + buttonGlow = 0L; + combo = new QImage( uic_findImage("combo-milk") ); + comboShadow = new QImage( uic_findImage( "combo-shadow" ) ); + if (optionHandler->toolbuttonStyle() == Brushed || !optionHandler->SmoothListViewHeaders()) + rectbutton = new QImage( uic_findImage( "rectbutton" ) ); + else rectbutton = 0L; + default: + break; + } + + if ( btnBorderImg && btnBorderImg->depth() < 32 ) + * btnBorderImg = btnBorderImg->convertDepth( 32 ); + + if ( btnShadowImg && btnShadowImg->depth() < 32 ) + * btnShadowImg = btnShadowImg->convertDepth( 32 ); + + if ( buttonGlow && buttonGlow->depth() < 32 ) + * buttonGlow = buttonGlow->convertDepth( 32 ); + + if ( combo && combo->depth() < 32 ) + * combo = combo->convertDepth( 32 ); + + if ( comboShadow && comboShadow->depth() < 32 ) + * comboShadow = comboShadow->convertDepth( 32 ); + + if ( rectbutton && rectbutton->depth() < 32 ) + * rectbutton = rectbutton->convertDepth( 32 ); + + if (optionHandler->style() == Milk) + { + slider_top = new QImage( uic_findImage( "sbslider_top-milk" ) ); + slider_btm = new QImage( uic_findImage( "sbslider_btm-milk" ) ); + } + else + { + slider_top = new QImage( uic_findImage( "sbslider_top" ) ); + slider_btm = new QImage( uic_findImage( "sbslider_btm" ) ); + } + + if ( slider_top->depth() < 32 ) + * slider_top = slider_top->convertDepth( 32 ); + + if ( slider_btm->depth() < 32 ) + * slider_btm = slider_btm->convertDepth( 32 ); + + if (optionHandler->shadowSbSlider()) + { + slider_top_shd = new QImage( uic_findImage( "sbslider_top_shd" ) ); + if ( slider_top_shd->depth() < 32 ) + * slider_top_shd = slider_top_shd->convertDepth( 32 ); + + slider_btm_shd = new QImage( uic_findImage( "sbslider_btm_shd" ) ); + if ( slider_btm_shd->depth() < 32 ) + * slider_btm_shd = slider_btm_shd->convertDepth( 32 ); + } + else + { + slider_top_shd = 0L; + slider_btm_shd = 0L; + } + + roundFrame = new QImage( uic_findImage( "roundFrame" ) ); + if ( roundFrame->depth() < 32 ) + * roundFrame = roundFrame->convertDepth( 32 ); + + menuPix = NULL; + tmpBtnPix = NULL; + + int i; + for ( i = 0; i < BITMAP_ITEMS; ++i ) { + pixmaps[ i ] = NULL; + } + + sbLeft = new QBitmap( 6, 7, sbarrow_left_bits, true ); + sbLeft->setMask( *sbLeft ); + sbRight = new QBitmap( 6, 7, sbarrow_right_bits, true ); + sbRight->setMask( *sbRight ); + sbUp = new QBitmap( 7, 6, sbarrow_up_bits, true ); + sbUp->setMask( *sbUp ); + sbDown = new QBitmap( 7, 6, sbarrow_down_bits, true ); + sbDown->setMask( *sbDown ); + checkmark = new QBitmap( 6, 7, checkmark_bits, true ); + checkmark->setMask( *checkmark ); + + isKicker = ( qstrcmp( qApp->argv() [ 0 ], "kicker" ) == 0 ) || + ( qstrcmp( qApp->argv() [ 0 ], "appletproxy" ) == 0 ); + isOOO = !qstrcmp( qApp->argv() [ 0 ], "soffice.bin" ); + + groupShadow = new QPixmap( 64, 64 ); + QColor c; + optionHandler->custCols[0] != -1 ? c = QColor(optionHandler->custCols[0]) : c= QColor(qApp->palette().color(QPalette::Active, isKicker?QColorGroup::Button:QColorGroup::Background)); + + groupShadow->fill( ( c.dark( 100 + optionHandler->ShadowDarkness() ) ).rgb() ); + if ( (optionHandler->style() != Brushed) && optionHandler->useBgStipple() ) { + QPainter p; + p.begin( groupShadow ); + p.setPen( c.dark( 100 + optionHandler->ShadowDarkness() + (int)(optionHandler->stippleContrast()/2) ) ); + for ( int i = 1; i < 64; i += 4 ) { + p.drawLine( 0, i, 63, i ); + p.drawLine( 0, i+2, 63, i+2 ); + } + p.setPen( c.dark( 100 + optionHandler->ShadowDarkness() + optionHandler->stippleContrast()) ); + for ( int i = 2; i < 63; i += 4 ) { + p.drawLine( 0, i, 63, i ); + } + } + + if (optionHandler->style() == Brushed) + { + plainBrush = optionHandler->TintBrush() ? + *tintBrush(uic_findImage( "brushed-tile" ), optionHandler->BrushTint()) : + uic_findImage( "brushed-tile" ); + gradBrush = optionHandler->TintBrush() ? + *tintBrush(uic_findImage( "brushed-gradient" ), optionHandler->BrushTint()) : + uic_findImage( "brushed-gradient" ); + } +} + +LiquidStyle::~LiquidStyle() { +// btnDict.setAutoDelete(true); + btnDict.clear(); +// btnShadowedDict.setAutoDelete(true); + btnShadowedDict.clear(); +// buttonGlowDict.setAutoDelete(true); + buttonGlowDict.clear(); +// comboDict.setAutoDelete(true); + comboDict.clear(); +// comboShadowedDict.setAutoDelete(true); + comboShadowedDict.clear(); +// if (! tabDict.isEmpty()) tabDict.clear(); +// if (! inverseTabDict.isEmpty()) inverseTabDict.clear(); +// rectBtnDict.setAutoDelete(true); + rectBtnDict.clear(); +// progress2Dict.setAutoDelete(true); + progress2Dict.clear(); +// bfi.setAutoDelete(true); + bfi.clear(); +// fadeColorMap.setAutoDelete(true); + fadeColorMap.clear(); + + delete optionHandler; + + delete sbUp; + delete sbDown; + delete sbLeft; + delete sbRight; + delete checkmark; + + + if ( btnBorderImg ) + delete btnBorderImg; + if ( btnShadowImg ) + delete btnShadowImg; + if (combo) + delete combo; + if (comboShadow) + delete comboShadow; + if (buttonGlow) + delete buttonGlow; + delete slider_top; + delete slider_btm; + if (slider_top_shd) + delete slider_top_shd; + if (slider_btm_shd) + delete slider_btm_shd; + if (rectbutton) + delete rectbutton; + delete roundFrame; + + if ( tmpBtnPix ) + delete tmpBtnPix; + if ( menuPix ) + delete menuPix; + + int i; + for ( i = 0; i < BITMAP_ITEMS; ++i ) { + if ( pixmaps[ i ] ) + delete pixmaps[ i ]; + } + if ( groupShadow ) + delete groupShadow; + + } + +inline void LiquidStyle::updateProgressPos() +{ + progAnimShift = (progAnimShift + 1) % 20; + prog2AnimShift = (prog2AnimShift + 1) % 38; + //Update the registered progressbars. + QMap::iterator iter; + for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); iter++) + { + if ( !::qt_cast(iter.key()) ) + continue; + (iter.key())->repaint(false); + } +} + +inline void LiquidStyle::updateSliderPos(){ + sliderAnimShift = (sliderAnimShift + 1) % 32; + if (activeScroller) + activeScroller->repaint(false); +} + +void LiquidStyle::progressBarDestroyed(QObject* obj){ + progAnimWidgets.remove(static_cast(obj)); +} + +bool LiquidStyle::isPlain() const { + return ( !optionHandler->useBgStipple() ); + } + + +void LiquidStyle::drawPrimitive( PrimitiveElement pe, QPainter *p, + const QRect &r, const QColorGroup &cg, + SFlags flags, const QStyleOption &opt ) const +{ + bool down = flags & Style_Down; + bool on = flags & Style_On; + + switch ( pe ) + { + case PE_TabBarBase: + { + bool isDialog = false; + if (p->device() && p->device()->devType() == QInternal::Widget) + { + QWidget *w = (QWidget*)p->device(); + if (w && ::qt_cast(w) && w->children()) + { + QObjectListIt it( *w->children() ); // iterate over the buttons + QObject *obj; + QTabBar *tabBar = 0L; + while ( (obj = it.current()) != 0 ) + { + ++it; + if (::qt_cast(obj)) + { + tabBar = (QTabBar*)obj; + break; + } + } + if (!tabBar || !tabBar->isVisible()) + break; + } + isDialog = optionHandler->TabStyle() == Clever && w->topLevelWidget()->inherits("QDialog"); + } + if (isDialog || optionHandler->TabStyle() == Chooser) + { + int x = r.x(); int right = r.right(); int bottom = r.bottom(); int y2 = r.y() + 1; + QColor bright( cg.background().dark( 110 ) ); + QColor mid( cg.background().dark( 130 ) ); + QColor dark( cg.background().dark( 150 ) ); + p->setPen( dark ); + p->drawLine( x + 6, y2, right - 6, y2 ); + p->drawPoint(x+3,y2+1);p->drawPoint(x+4,y2+1); + p->drawPoint(x+2,y2+2); + p->drawPoint(x+1,y2+3); + p->drawPoint(right-3,y2+1);p->drawPoint(right-4,y2+1); + p->drawPoint(right-2,y2+2); + p->drawPoint(right-1,y2+3); + p->drawLine(x,y2+5,x,bottom); + p->drawLine(right,y2+5,right,bottom); + + p->setPen( mid ); + p->drawPoint(x+4, y2);p->drawPoint(x+5,y2); + p->drawPoint(right-4, y2);p->drawPoint(right-5,y2); + p->drawPoint(x+2, y2+1); + p->drawPoint(right-2, y2+1); + p->drawLine(x+5,y2 + 1, right - 5, y2 + 1); + p->drawPoint(x+1,y2+2); + p->drawPoint(right-1,y2+2); + p->drawPoint(x+2,y2+3); + p->drawPoint(right-2,y2+3); + p->drawPoint(x,y2+4);p->drawPoint(x+1,y2+4); + p->drawPoint(right,y2+4);p->drawPoint(right+1,y2+4); + + p->setPen(bright); + p->drawPoint(x+3,y2);p->drawPoint(right-3,y2); + p->drawLine(x+4,y2+2,right-4,y2+2); + p->drawPoint(x,y2+3);p->drawPoint(x+3,y2+3); + p->drawPoint(right,y2+3);p->drawPoint(right-3,y2+3); + p->drawPoint(x+2,y2+4);p->drawPoint(right-2,y2+4); + p->drawLine(x+1,y2+5,x+1,bottom); + p->drawLine(right-1,y2+5,right-1,bottom); + break; + } + else + { + drawCombo( p, cg, cg.button(), r.x()+1, r.y()+1, r.width()-2, r.height()+1, false, false, false, center); + QPen oldPen = p->pen(); +// p->setClipping ( false ); + p->setPen( cg.button().dark( 158 ) ); + p->drawRect(r); +// p->fillRect(r, Qt::red); +// p->flush(); + p->setPen(oldPen); + } + break; + } + case PE_ButtonCommand: + case PE_ButtonDefault: + { + bool sunken = on || down; + bool hover = flags & Style_MouseOver; + bool focused = flags & Style_HasFocus; + QColor newColor = sunken ? cg.button().dark( 110 ) : hover || focused ? cg.button() : optionHandler->InactiveButtonColor(); + if (optionHandler->AnimateButton() && (sunken || hover || focused)) + { + ButtonFadeInfo *bfi_ = /*(::qt_cast(*/opt.widget()/*))*/ ? bfi[opt.widget()->winId()] : 0L; + if (bfi_) + { + int index = bfi_->index; + newColor = mapFadeColor(newColor, index); + } + } + + if (optionHandler->buttonStyle() == Brushed) + { + drawRectangularButton( p, cg, newColor, r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full); + } + else if ( ( r.width() < 21 || r.height() < 25 )) + { + drawCombo( p, cg, newColor, r.x(), r.y(), r.width(), r.height()+2, sunken, hover, false, center, isHTMLButton ); + QPen oldpen(p->pen()); + p->setPen( newColor.dark(150)); + p->drawRect(r.x(), r.y(), r.width(), r.height()); + if (sunken) + { + p->setPen(newColor.dark(180)); + p->drawRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); + } + p->setPen(oldpen); + break; + } + else if (optionHandler->buttonStyle() == Milk) + drawCombo( p, cg, newColor, r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full, isHTMLButton ); + else + { + drawRoundButton( p, cg, newColor, r.x(), r.y(), r.width(), r.height(), sunken, hover, btnOffset.x(), btnOffset.y() ); + } + break; + } + case PE_ButtonBevel: + case PE_ButtonDropDown: + { + bool sunken = on || down; + bool hover = flags & Style_MouseOver; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full); + else + drawCombo( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full ); + break; + } + case PE_ButtonTool: + { + bool sunken = on || down; + bool hover = flags & Style_MouseOver; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full); + else + drawCombo( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, full ); + break; + } + case PE_HeaderSection: + { + bool sunken = on || down; + bool hover = flags & Style_MouseOver; + QPen oldpen(p->pen()); + if ( isTaskContainer ) // is kicker? + { + if (optionHandler->SmoothListViewHeaders()) + { + drawCombo( p, cg, sunken ? cg.button() : taskContainerHover ? cg.button().light( 110 ) : cg.background(), r.x(), r.y(), r.width(), isKicker ? r.height() + 2 : r.height(), sunken, hover, false, optionHandler->SmootherLVH() ? full : center ); + if (isKicker && !optionHandler->SmootherLVH()) + { + p->setPen(cg.background().dark(150)); + p->drawRect(r.x(), r.y(), r.width(), r.height()); + if (sunken) + { + p->setPen(cg.background().dark(200)); + p->drawRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2); + } + } + } + else + { + drawRectangularButton( p, cg, sunken ? cg.button() : taskContainerHover ? cg.button().light( 110 ) : cg.background(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, center); + p->setPen(cg.background().dark(150)); + p->drawLine(r.x(),r.y()+1,r.x(),r.height()-2); + } + const_cast( this ) ->isTaskContainer = false; + const_cast( this ) ->taskContainerHover = false; + } + else + { + if ( (p->device() && p->device()->devType() == QInternal::Widget) && ::qt_cast((QWidget*)p->device()) ) + { + QHeader *header = (QHeader*)p->device(); + int id = header->orientation() == Qt::Horizontal ? header->sectionAt( r.x() + 2 + header->offset() ) : header->sectionAt( r.y() + 2 + header->offset() ); + hover = ((id != -1) && ((currentHeader == header && id == headerHoverID ) || id == headerSortID)); + if (header->mapToIndex(id) == header->count()-1 && (r.bottom() < header->rect().bottom() || r.right() < header->rect().right())) + { + bool hadClip = p->hasClipping(); + p->setClipping( false ); + if (header->orientation() == Qt::Horizontal) + p->fillRect(r.right()+1, r.y(), header->width()-r.right(), r.height(), cg.base()); + else + p->fillRect(r.x(), r.bottom()+1, r.width(), header->height()-r.bottom(), cg.base()); + p->setClipping( hadClip ); + } + } + if (optionHandler->SmoothListViewHeaders()) + { + drawCombo( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, center); + } + else + drawRectangularButton( p, cg, sunken ? cg.button().dark( 110 ) : hover ? cg.button() : optionHandler->InactiveButtonColor(), r.x(), r.y(), r.width(), r.height(), sunken, hover, false, center); + } + p->setPen(oldpen); + break; + } + case PE_FocusRect: + { + p->drawWinFocusRect( r ); + break; + } + case PE_ScrollBarSlider: + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: + { + QColor sbBgColor = optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBGroove ) : + qApp->palette().active().background(); + + bool isActive = optionHandler->ScrollerActive(); + bool isHover = currentScrollBar->hasMouse(); + bool isPressed = currentScrollBar->draggingSlider(); + bool drawSlider = currentScrollBar->minValue() < currentScrollBar->maxValue(); + + // horizontal slider + if ( flags & Style_Horizontal ) + { + int extent = currentScrollBar->height(); + QRect bgR( extent, 0, currentScrollBar->width() - extent * 3 + 1, extent ); + if ( sbBuffer.size() != currentScrollBar->size() ) + const_cast( this )->sbBuffer.resize( currentScrollBar->size() ); + QPainter painter; + painter.begin( &sbBuffer ); + // pixmaps + if (drawSlider) + { + painter.drawPixmap( bgR.x(), bgR.y() + 1, *getPixmap( HSBSliderBtmBg ) ); + painter.drawTiledPixmap( bgR.x() + 7, bgR.y() + 1, bgR.width() - 15, 13, *getPixmap( HSBSliderMidBg ) ); + painter.drawPixmap( bgR.right() - 8, bgR.y() + 1, *getPixmap( HSBSliderTopBg ) ); + } + else + painter.drawTiledPixmap( bgR.x(), bgR.y() + 1, bgR.width(), 13, *getPixmap( HSBSliderMidBg ) ); + + // lines + painter.setPen( sbBgColor.dark( 110 ) ); + painter.drawLine( bgR.x(), bgR.y(), bgR.right(), bgR.y()); + painter.drawLine( bgR.x(), bgR.bottom(), bgR.right(), bgR.bottom()); + + if ( pe == PE_ScrollBarSlider && drawSlider) + { + int offset = isPressed * ( optionHandler->squeezeSbSlider() + optionHandler->shadowSbSlider()*2); + int offset2 = optionHandler->shadowSbSlider()*2 + (isPressed && optionHandler->squeezeSbSlider()); + + painter.drawPixmap( r.x() + offset, r.y() + 1, + isPressed ? *getPixmap( HSBSliderBtmPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( HSBSliderBtmActive ) : + *getPixmap( HSBSliderBtm)); + + painter.drawPixmap( r.right() - 6 - offset2, r.y() + 1, + isPressed ? *getPixmap( HSBSliderTopPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( HSBSliderTopActive ) : + *getPixmap( HSBSliderTop ) ); + // mid part last, as i have to redefine clip section + painter.setClipRect(r.x() + 7 + offset2, r.y() + 1, r.width() - 14 - 2*offset2, 13, QPainter::CoordPainter); + painter.drawTiledPixmap( r.x() + 7 + offset2 + ((isHover && !isPressed) ? (sliderAnimShift - 32) : 0), r.y() + 1, r.width() - 14 - 2*offset2 - ((isHover && !isPressed) ? + (sliderAnimShift - 32) : 0), 13, isPressed ? *getPixmap( HSBSliderMidPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( HSBSliderMidActive ) : + *getPixmap( HSBSliderMid ), isPressed?r.x() : 0, 0); + } + + painter.end(); + } + + // vertical slider + else + { + int extent = currentScrollBar->width(); + QRect bgR( 0, extent, extent, currentScrollBar->height() - extent * 3 + 1 ); + + if ( sbBuffer.size() != currentScrollBar->size() ) + const_cast( this ) -> sbBuffer.resize( currentScrollBar->size() ); + QPainter painter; + painter.begin( &sbBuffer ); // set painter to pixelbuffer + if (drawSlider) + { + // top slidergroove rounder + painter.drawPixmap( bgR.x() + 1, bgR.y(), *getPixmap( VSBSliderTopBg ) ); + // the groove + painter.drawTiledPixmap( bgR.x() + 1, bgR.y() + 8, 13, bgR.height() - 15, *getPixmap( VSBSliderMidBg ) ); + // bottom slidergroove rounder + painter.drawPixmap( bgR.x() + 1, bgR.bottom() - 7, *getPixmap( VSBSliderBtmBg ) ); + } + else + painter.drawTiledPixmap( bgR.x() + 1, bgR.y(), 13, bgR.height(), *getPixmap( VSBSliderMidBg ) ); + + painter.setPen( sbBgColor.dark( 110 ) ); + painter.drawLine( bgR.x(), bgR.y(), bgR.x(), bgR.bottom() ); + painter.drawLine( bgR.right(), bgR.y(), bgR.right(), bgR.bottom() ); + + // here we are, now the slider + if ( pe == PE_ScrollBarSlider && drawSlider ) + { + int offset = isPressed * ( optionHandler->squeezeSbSlider() + optionHandler->shadowSbSlider()*2); + int offset2 = (isPressed * optionHandler->squeezeSbSlider()) + optionHandler->shadowSbSlider()*2; + + painter.drawPixmap( r.x() + 1, r.y() + offset, isPressed ? + *getPixmap( VSBSliderTopPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( VSBSliderTopActive ) : + *getPixmap( VSBSliderTop)); + painter.drawPixmap( r.x() + 1, r.bottom() - 6 - offset2, isPressed ? + *getPixmap( VSBSliderBtmPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( VSBSliderBtmActive ) : + *getPixmap( VSBSliderBtm ) ); + // mid part last, as i have to redefine clipping section + painter.setClipRect(r.x() + 1, r.y() + 7+offset2, 13, r.height() - 14 - 2*offset2, QPainter::CoordPainter); + painter.drawTiledPixmap( r.x() + 1, r.y() + 7 + offset2 - ((isHover && !isPressed) ? sliderAnimShift : 0), + 13, r.height() - 14 - 2*offset2 + ((isHover && !isPressed) ? + sliderAnimShift : 0), isPressed ? *getPixmap( VSBSliderMidPressed ) : + (isHover || isActive || isOOO) ? *getPixmap( VSBSliderMidActive ) : + *getPixmap( VSBSliderMid ),0,isPressed?r.y():0 ); + } + painter.end(); + } + p->drawPixmap( r.x(), r.y(), sbBuffer, r.x(), r.y(), r.width(), r.height() ); + break; + } + case PE_ScrollBarAddLine: + { + QColor c( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBGroove ) : + qApp->palette().active().background() ); + QColor pixColor = flags & Style_Down ? qApp->palette().active().button() : c; + + bool drawSlider = currentScrollBar->minValue() < currentScrollBar->maxValue(); + + if ( flags & Style_Horizontal ) + { + p->drawTiledPixmap( r.x(), r.y() + 1, r.width(), 13, *getPixmap(drawSlider ? HSBSliderMidBgI : HSBSliderMidBg)); + p->setPen( c.dark( 110 ) ); + p->drawLine( r.x(), r.y(), r.right(), r.y()); + p->drawLine( r.x(), r.bottom(), r.right(), r.bottom()); + } + else + { + p->drawTiledPixmap( r.x() + 1, r.y(), 13, r.height(), *getPixmap(drawSlider ? VSBSliderMidBgI : VSBSliderMidBg)); + p->setPen( c.dark( 110 ) ); + p->drawLine( r.x(), r.y(), r.x(), r.bottom()); + p->drawLine( r.right(), r.y(), r.right(), r.bottom()); + } + if (drawSlider) + { + p->setPen( flags & Style_Down ? cg.button() : QColor(85,85,85) ); + p->setBrush( flags & Style_Down ? cg.button() : QColor(85,85,85) ); + p->drawPixmap( r.x() + 4, r.y() + 4, flags & Style_Horizontal ? *sbRight : *sbDown ); + } + break; + } + case PE_ScrollBarSubLine: + { + QColor c( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBGroove ) : + qApp->palette().active().background() ); + QColor pixColor = flags & Style_Down ? qApp->palette().active().button() : c; + bool top = flags & Style_Horizontal ? r.x() == 0 : r.y() == 0; + + bool drawSlider = currentScrollBar->minValue() < currentScrollBar->maxValue(); + + if ( flags & Style_Horizontal ) + { + if ( top ) + { + p->drawTiledPixmap( r.x(), r.y() + 1, r.width(), 13, *getPixmap(drawSlider ? HSBSliderMidBgI : HSBSliderMidBg)); + } + else + { + p->drawTiledPixmap( r.x(), r.y() + 1, r.width(), 13, *getPixmap(drawSlider ? HSBSliderMidBgI : HSBSliderMidBg)); + } + p->setPen( c.dark( 110 ) ); + p->drawLine( r.x(), r.y(), r.right(), r.y()); + p->drawLine( r.x(), r.bottom(), r.right(), r.bottom()); + } + else + { + if ( top ) + { + p->drawTiledPixmap( r.x() + 1, r.y(), 13, r.height(), *getPixmap(drawSlider ? VSBSliderMidBgI : VSBSliderMidBg)); + } + else + { + p->drawTiledPixmap( r.x() + 1, r.y(), 13, r.height(), *getPixmap(drawSlider ? VSBSliderMidBgI : VSBSliderMidBg)); + } + p->setPen( c.dark( 110 ) ); + p->drawLine( r.x(), r.y(), r.x(), r.bottom()); + p->drawLine( r.right(), r.y(), r.right(), r.bottom()); + } + if (drawSlider) + { + p->setPen( flags & Style_Down ? cg.button() : QColor(85,85,85) ); + p->setBrush( flags & Style_Down ? cg.button() : QColor(85,85,85) ); + if (currentScrollBar->minValue() < currentScrollBar->maxValue()) p->drawPixmap( r.x() + 4, r.y() + 4, flags & Style_Horizontal ? *sbLeft : *sbUp ); + } + break; + } + case PE_Indicator: + { + bool hover = flags & Style_MouseOver; + bool pressed = flags & Style_Down; +// bool isMasked = p->device() && p->device() ->devType() == QInternal::Widget && ( ( QWidget * ) p->device() ) ->autoMask(); +#if 0 + if ( isMasked ) + { + if ( !( flags & Style_Off ) ) + p->drawPixmap( r.x(), r.y(), + hover ? *getPixmap( HTMLCBDownHover ) : + *getPixmap( HTMLCBDown ) ); + else + p->drawPixmap( r.x(), r.y(), hover ? + *getPixmap( HTMLCBHover ) : *getPixmap( HTMLCB ) ); + } + else +#endif + { + if ( flags & Style_On ) + p->drawPixmap( r.x(), r.y(), + pressed ? *getPixmap( CBDownPressed ) : + hover ? *getPixmap( CBDownHover ) : + *getPixmap( CBDown ) ); + else if ( flags & Style_Off ) + p->drawPixmap( r.x(), r.y(), + pressed ? *getPixmap( CBPressed ) : + hover ? *getPixmap( CBHover ) : + *getPixmap( CB ) ); + else //tristate + p->drawPixmap( r.x(), r.y(), + pressed ? *getPixmap( CBTriPressed ) : + hover ? *getPixmap( CBTriHover ) : + *getPixmap( CBTri ) ); + } + break; + } + case PE_IndicatorMask: + { + p->fillRect( r, Qt::color1 ); + break; + } + case PE_ExclusiveIndicator: + { + bool hover = flags & Style_MouseOver; + bool pressed = flags & Style_Down; + + if ( on || down ) + p->drawPixmap( r.x(), r.y(), + pressed ? *getPixmap( RadioOnPressed ) : + hover ? *getPixmap( RadioOnHover ) : + *getPixmap( RadioOn ) ); + else + p->drawPixmap( r.x(), r.y(), + pressed ? *getPixmap( RadioOffPressed ) : + hover ? *getPixmap( RadioOffHover ) : + *getPixmap( RadioOff ) ); + break; + } + case PE_ExclusiveIndicatorMask: + { + break; + } + case PE_Splitter: + case PE_DockWindowResizeHandle: + { + QPen oldpen(p->pen()); + QBrush oldbrush(p->brush()); + if (highlightWidget == p->device()) + { + if (flags & Style_Horizontal) + { //vertical? + p->setPen(cg.mid()); + p->drawLine(r.x(), r.y(), r.x(), r.bottom()); + p->drawLine(r.right(), r.y(), r.right(), r.bottom()); + p->setPen(cg.button().dark(140)); + p->setBrush(cg.button().dark(140)); + p->drawEllipse(r.x()+1,r.y() + (int)(r.height() / 2.5), 4, 4); + } + else + { + p->setPen(cg.mid()); + p->drawLine(r.x(), r.y(), r.right(), r.y()); + p->drawLine(r.x(), r.bottom(), r.right(), r.bottom()); + p->setPen(cg.button().dark(140)); + p->setBrush(cg.button().dark(140)); + p->drawEllipse(r.x()+r.width()/2,r.y() + 1, 4, 4); + } + + } + else + { + if (flags & Style_Horizontal) + { + p->setPen(cg.mid()); + p->drawLine(r.x(), r.y(), r.x(), r.bottom()); + p->drawLine(r.right(), r.y(), r.right(), r.bottom()); + p->setPen(cg.background().dark(130)); + p->setBrush(cg.background().dark(150)); + p->drawEllipse(r.x()+1,r.y() + (int)(r.height() / 2.5), 4, 4); + } + else + { + p->setPen(cg.mid()); + p->drawLine(r.x(), r.y(), r.right(), r.y()); + p->drawLine(r.x(), r.bottom(), r.right(), r.bottom()); + p->setPen(cg.background().dark(130)); + p->setBrush(cg.background().dark(150)); + p->drawEllipse(r.x()+r.width()/2,r.y() + 1, 4, 4); + } + } + p->setPen(oldpen); + p->setBrush(oldbrush); + break; + } +// case PE_BoxFrame: + case PE_PanelGroupBox: + case PE_GroupBoxFrame: + { + QColor bgColor; + QWidget* w = (p->device() && p->device()->devType() == QInternal::Widget) ? + (QWidget*)(p->device()) : 0; + QGroupBox* gb = ::qt_cast(w); + + optionHandler->drawGroupBoxShadow() ? + bgColor = QColor(cg.background().dark( 100 + optionHandler->ShadowDarkness() )) : + bgColor = QColor(cg.background()); + QColor bright( bgColor.dark( 110 ) ); + QColor mid( bgColor.dark( 130 ) ); + QColor dark( bgColor.dark( 150 ) ); + + int titleHeight = (gb && !gb->title().isEmpty() && pe == PE_PanelGroupBox) ? + p->fontMetrics().height()+(gb->isCheckable()?4:1) : 0; + + int x = r.x(); int right = r.right(); int bottom = r.bottom(); + int y2 = r.y(); + + /*** + ok, to get the sunken look somwhat efficient and less glitchy + we reset the groupbox brush and only repaint the title + (saves us from several is item in groupbox checks as well) + only problem left: draw the parents brush on the title window aligned... + ***/ + + if (gb && titleHeight) + { + bool hadClip = p->hasClipping(); + QRegion oldClip = p->clipRegion(); + if (gb->parentWidget()) + { + const QPixmap *pix = gb->parentWidget()->paletteBackgroundPixmap(); + + if (optionHandler->drawGroupBoxShadow()) + { + QPointArray pa1(3); + pa1.setPoint(0, x,y2); + pa1.setPoint(1, x+5,y2); + pa1.setPoint(2, x,y2+5); + QPointArray pa2(3); + pa2.setPoint(0, right-5,y2); + pa2.setPoint(1, right,y2); + pa2.setPoint(2, right,y2+5); + QPointArray pa3(3); + pa3.setPoint(0, right,bottom-5); + pa3.setPoint(1, right,bottom); + pa3.setPoint(2, right-5,bottom); + QPointArray pa4(3); + pa4.setPoint(0, x+5,bottom); + pa4.setPoint(1, x,bottom); + pa4.setPoint(2, x,bottom-5); + + QRegion reg2(0,0, r.right(), titleHeight); + p->setClipRegion(QRegion(pa1)+QRegion(pa2)+QRegion(pa3)+QRegion(pa4)+reg2); + } + else + p->setClipRect(0,0,r.right(),titleHeight); + pix ? p->drawTiledPixmap( QRect( 0, 0, w->width(), w->height()), *pix, w->backgroundOffset()) : p->fillRect(QRect(0, 0, w->width(), w->height()),w->parentWidget()->backgroundBrush()); + } + if (gb && !gb->isCheckable()) + { + QString title = gb->title(); + QFont font( p->font() ); + font.setBold( true ); + p->setFont( font ); + drawItem( p, QRect(10,0,r.width(),titleHeight), ShowPrefix, cg, flags & Style_Enabled, 0, title, -1, &cg.text() ); + } + p->setClipRegion(oldClip); + p->setClipping(hadClip); + } + + //outer rect + // top + p->setPen( dark ); + if (pe == PE_PanelGroupBox) + { + p->drawLine( x + 6, y2, right - 6, y2 ); + // left points + p->drawPoint(x+3,y2+1);p->drawPoint(x+4,y2+1); + p->drawPoint(x+2,y2+2); + p->drawPoint(x+1,y2+3); + // right points + p->drawPoint(right-3,y2+1);p->drawPoint(right-4,y2+1); + p->drawPoint(right-2,y2+2); + p->drawPoint(right-1,y2+3); + // vertcal outer lines + p->drawLine(x,y2+5,x,bottom-5); + p->drawLine(right,y2+5,right,bottom-5); + } + else + { + // vertcal outer lines + p->drawLine(x,y2,x,bottom-5); + p->drawLine(right,y2,right,bottom-5); + } + + p->setPen( mid ); + if (pe == PE_PanelGroupBox) + { + // top stuff + p->drawPoint(x+4, y2);p->drawPoint(x+5,y2); + p->drawPoint(right-4, y2);p->drawPoint(right-5,y2); + p->drawPoint(x+2, y2+1); + p->drawPoint(right-2, y2+1); + p->drawLine(x+5,y2 + 1, right - 5, y2 + 1); + p->drawPoint(x+1,y2+2); + p->drawPoint(right-1,y2+2); + p->drawPoint(x+2,y2+3); + p->drawPoint(right-2,y2+3); + p->drawPoint(x,y2+4);p->drawPoint(x+1,y2+4); + p->drawPoint(right,y2+4);p->drawPoint(right+1,y2+4); + } + // bottom stuff + p->drawPoint(x,bottom - 4); p->drawPoint(x+1,bottom - 4); + p->drawPoint(right,bottom - 4); p->drawPoint(right-1,bottom - 4); + p->drawPoint(x+1,bottom - 3); + p->drawPoint(right-1,bottom - 3); + p->drawPoint(x+1,bottom - 2); p->drawPoint(x+2,bottom - 2); + p->drawPoint(right-1,bottom - 2); p->drawPoint(right-2,bottom - 2); + p->drawPoint(x+2, bottom - 1); p->drawPoint(x+3, bottom - 1); + p->drawPoint(right-2, bottom - 1); p->drawPoint(right-3, bottom - 1); + p->drawLine(x + 4, bottom,right - 4, bottom); + + p->setPen(bright); + // top stuff + if (pe == PE_PanelGroupBox) + { + p->drawPoint(x+3,y2);p->drawPoint(right-3,y2); + p->drawLine(x+4,y2+2,right-4,y2+2); + p->drawPoint(x,y2+3);p->drawPoint(x+3,y2+3); + p->drawPoint(right,y2+3);p->drawPoint(right-3,y2+3); + p->drawPoint(x+2,y2+4);p->drawPoint(right-2,y2+4); + // vertical lines + p->drawLine(x+1,y2+5,x+1,bottom-5); + p->drawLine(right-1,y2+5,right-1,bottom-5); + } + else + { + // vertical lines + p->drawLine(x+1,y2,x+1,bottom-5); + p->drawLine(right-1,y2,right-1,bottom-5); + } + // bottom stuff + p->drawPoint(x, bottom-3);p->drawPoint(right, bottom-3); + p->drawPoint(x+3, bottom);p->drawPoint(right-3, bottom); + + break; + } + case PE_StatusBarSection: + { + break; + } + case PE_WindowFrame: + { + drawEditFrame( p, r, cg, false, false, true ); + break; + } + case PE_Panel: + { + bool sunken = flags & Style_Sunken; + if (!(isKicker && optionHandler->RemoveKickerBevel())) + sunken ? drawEditFrame( p, r, cg ) : drawEditFrame( p, r, cg, false, false, true ); + break; + } + case PE_PanelTabWidget: + { + // don't ask + bool isDialog = optionHandler->TabStyle() == Clever && + (p->device() && p->device()->devType() == QInternal::Widget)&& + ((QWidget*)p->device())->topLevelWidget()->inherits("QDialog"); + + QColor bright( cg.background().dark( 110 ) ); + QColor mid( cg.background().dark( 130 ) ); + QColor dark( cg.background().dark( 150 ) ); + int x = r.x(); int right = r.right(); int bottom = r.bottom(); int y2 = r.y(); + if (isDialog || optionHandler->TabStyle() == Chooser) + { + //outer rect + // top + p->setPen( dark ); + // vertcal outer lines + p->drawLine(x,y2,x,bottom-5); + p->drawLine(right,y2,right,bottom-5); + + p->setPen( mid ); + // bottom stuff + p->drawPoint(x,bottom - 4); p->drawPoint(x+1,bottom - 4); + p->drawPoint(right,bottom - 4); p->drawPoint(right-1,bottom - 4); + p->drawPoint(x+1,bottom - 3); + p->drawPoint(right-1,bottom - 3); + p->drawPoint(x+1,bottom - 2); p->drawPoint(x+2,bottom - 2); + p->drawPoint(right-1,bottom - 2); p->drawPoint(right-2,bottom - 2); + p->drawPoint(x+2, bottom - 1); p->drawPoint(x+3, bottom - 1); + p->drawPoint(right-2, bottom - 1); p->drawPoint(right-3, bottom - 1); + p->drawLine(x + 4, bottom,right - 4, bottom); + + p->setPen(bright); + // top stuff + // vertical lines + p->drawLine(x+1,y2,x+1,bottom-5); + p->drawLine(right-1,y2,right-1,bottom-5); + + // bottom stuff + p->drawPoint(x, bottom-3);p->drawPoint(right, bottom-3); + p->drawPoint(x+3, bottom);p->drawPoint(right-3, bottom); + break; + } + else + { + p->setPen( mid ); + p->drawLine( x, y2, x, bottom-2 ); + p->drawLine( right, y2, right, bottom-2 ); + p->setPen( dark ); + p->drawLine( x, bottom-1, right, bottom-1 ); + p->drawLine( x, bottom, right, bottom ); + break; + } + } + case PE_PanelLineEdit: + { + bool focused = flags & Style_HasFocus; + bool isHTML = p->device() && p->device()->devType() == QInternal::Widget && isHTMLWidget((QWidget*)p->device()); + drawEditFrame( p, r, cg, isHTML, focused, false); + break; + } + case PE_PanelPopup: + { + int x, y, w , h; + r.rect( &x, &y, &w, &h ); + QColor c( optionHandler->UseCustomMenuColor()? + optionHandler->Color(): + optionHandler->MenuColorButton()? + optionHandler->buttonColor(): + optionHandler->bgColor() ); + p->setPen( c.dark( 140 ) ); + p->drawRect( x, y, w, h ); + p->setPen( c.light( 120 ) ); + p->drawRect( x + 1, y + 1, w - 2, h - 2 ); + break; + } + case PE_PanelMenuBar: + { + break; + } + case PE_PanelDockWindow: + { + break; + } + case PE_Separator: + case PE_DockWindowSeparator: + { + break; //don't draw anything + if (!(p->device() && p->device()->devType() == QInternal::Widget && ::qt_cast((QWidget*)p->device()))) + { + if ( !( flags & Style_Horizontal ) ) + { + p->setPen( cg.mid() ); + p->drawLine( 4, r.height() / 2, r.width() - 5, r.height() / 2 ); + p->setPen( cg.light() ); + p->drawLine( 4, r.height() / 2 + 1, r.width() - 5, r.height() / 2 + 1 ); + } + else + { + p->setPen( cg.mid() ); + p->drawLine( r.width() / 2, 4, r.width() / 2, r.height() - 5 ); + p->setPen( cg.light() ); + p->drawLine( r.width() / 2 + 1, 4, r.width() / 2 + 1, r.height() - 5 ); + } + } + break; + } + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: + { + bool sunken = on || down; + bool hover = flags & Style_MouseOver; + int x = r.x() + ( r.width() - 7 ) / 2; + int y = pe == PE_SpinWidgetDown ? r.y() + 1 : r.bottom() - 7; + QPen oldPen( p->pen() ); + QBrush oldBrush( p->brush() ); + p->setPen( sunken ? cg.button() : hover ? cg.mid() : cg.text() ); + p->setBrush( sunken ? cg.button() : hover ? cg.mid() : cg.text() ); + p->drawPixmap( x, y, pe == PE_SpinWidgetUp ? *sbUp : *sbDown ); + p->setBrush( oldBrush ); + p->setPen( oldPen ); + break; + } + case PE_CheckMark: + { + QPen oldPen( p->pen() ); + p->setPen( flags & Style_On ? cg.highlightedText() : optionHandler->textColor() ); + p->drawPixmap(r.x() + r.width()/2 - 4,r.y() + r.height()/2 - 4,*checkmark); + p->setPen( oldPen ); + break; + } + default: + { + if ( (pe >= PE_ArrowUp && pe <= PE_ArrowLeft ) || pe == PE_HeaderArrow) + { + QBrush oldBrush(p->brush()); + QColor tmpC = flags & Style_Enabled ? (flags & Style_Down || flags & Style_Sunken) && pe != PE_HeaderArrow ? cg.light() : cg.buttonText() : cg.mid(); + if (tmpC == Qt::black) tmpC = QColor(85,85,85); + p->setBrush(tmpC); + int x = r.width() > 7 ? r.x() + r.width()/2 - 4 : r.right() - 7; + int y = r.height() > 7 ? r.y() + r.height()/2 - 4 : r.bottom() - 7; + + switch ( pe ) + { + case PE_ArrowRight: + { + p->drawPixmap(x,y,*sbRight); + break; + } + case PE_ArrowUp: + { + p->drawPixmap(x,y,*sbUp); + break; + } + case PE_ArrowDown: + { + p->drawPixmap(x,y,*sbDown); + break; + } + case PE_HeaderArrow: + { + if (flags & Style_Up) + p->drawPixmap(x,y,*sbUp); + else + p->drawPixmap(x,y,*sbDown); + break; + } + default: + { + p->drawPixmap(x,y,*sbLeft); + break; + } + } + p->setBrush( oldBrush ); + } + else + KStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } + } // general switch +} + +void LiquidStyle::drawKStylePrimitive( KStylePrimitive kpe, QPainter* p, + const QWidget* widget, const QRect &r, + const QColorGroup &cg, SFlags flags, + const QStyleOption &opt ) const +{ + switch ( kpe ) + { + case KPE_ToolBarHandle: + { + if (widget && widget->parentWidget() && widget->parentWidget()->hasMouse()) + { + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + w = (int)((w-3)/2); + QColor c( (optionHandler->style() == Brushed) ? cg.background() : cg.background().dark(120) ); + p->setPen(c); + p->setBrush(c); + for (int i = 0; i < h-3; i += 5 ) + p->drawEllipse(x+w,y+i,3,3); + } + break; + } + case KPE_GeneralHandle: + { + if (!widget) + break; + if ( widget->inherits( "AppletHandleDrag" ) ) + { + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + w = (int)((w-3)/2); + QColor c( widget->hasMouse() ? cg.button() : cg.background().dark(110) ); + p->setPen(c); + p->setBrush(c); + for (int i = 0; i < h-3; i += 5 ) + p->drawEllipse(x+w,y+i,3,3); + break; + } + else if (widget->hasMouse()) + { + if (optionHandler->style() == Brushed) + { + drawCombo( p, cg, cg.button(), r.x(), r.y(), r.width(), r.height()+2, false, false, false, center); + } + else + { + p->fillRect(r,cg.button()); + p->setPen(cg.button().dark( 100 + optionHandler->stippleContrast() )); + int x=r.x(); + int y=r.y(); + int w=r.width(); + int h=r.height(); + for (int i = y;i < y+h; i += 4 ) + { + p->drawLine( x, i, x+w, i ); + p->drawLine( x, i + 1, x+w, i + 1 ); + } + } + } + else if (optionHandler->style() == Brushed && widget->parentWidget()) // needs alignment + { + p->drawTiledPixmap(r, *widget->paletteBackgroundPixmap(), widget->parentWidget()->backgroundOffset()); + } + break; + } + case KPE_SliderGroove: + { + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + if (qstrcmp( qApp->argv() [ 0 ], "kmix" ) == 0) x = x+3; + if ( ( ( const QSlider * ) widget ) ->orientation() == Qt::Horizontal ) + { + int x2 = x + w - 1; + y = y + ( h - 5 ) / 2; + p->setPen( cg.background().dark( 135 ) ); + p->drawLine( x + 1, y, x2 - 1, y ); //1 + p->drawLine( x, y + 4, x2, y + 4 ); //5 + p->setPen( cg.background().dark( 150 ) ); + p->drawLine( x, y + 1, x2, y + 1 ); //2 + p->setPen( cg.background().dark( 115 ) ); + p->drawLine( x, y + 2, x2, y + 2 ); //3 + p->drawLine( x, y + 3, x2, y + 3 ); //4 + p->setPen( cg.background().light( 130 ) ); + p->drawLine( x + 1, y + 5, x2 - 1, y + 5 ); //6 + } + else + { + int y2 = y + h - 1; + x = x + ( w - 5 ) / 2; + p->setPen( cg.background().dark( 135 ) ); + p->drawLine( x, y + 1, x, y2 - 1 ); + p->drawLine( x + 4, y, x + 4, y2 ); + p->setPen( cg.background().dark( 150 ) ); + p->drawLine( x + 1, y, x + 1, y2 ); + p->setPen( cg.background().dark( 115 ) ); + p->drawLine( x + 2, y, x + 2, y2 ); + p->drawLine( x + 3, y, x + 3, y2 ); + p->setPen( cg.background().light( 130 ) ); + p->drawLine( x + 5, y + 1, x + 5, y2 - 1 ); + } + break; + } + case KPE_SliderHandle: + { + if (!widget) + { + p->drawPixmap( r.x(), r.y(), *getPixmap( flags & Style_Enabled ? RadioOffHover : RadioOff)); + break; + } + if ((( const QSlider * ) widget ) ->orientation() == Qt::Horizontal) + (widget && widget->height() < 17) ? p->drawPixmap( r.x(), r.y(), *getPixmap( flags & Style_Enabled ? RadioOffHover : RadioOff)) : p->drawPixmap( r.x(), (optionHandler->style() == Milk) ? r.y() : r.y()+2, *getPixmap( flags & Style_Enabled ? HSlider : HSliderInactive)); + else + { + bool right = (( const QSlider * ) widget )->tickmarks() == QSlider::NoMarks || (( const QSlider * ) widget )->tickmarks() == QSlider::Right; + (widget && widget->width() < 17) ? p->drawPixmap( r.x()+2, r.y(), *getPixmap( flags & Style_Enabled ? RadioOffHover : RadioOff)) : p->drawPixmap( (optionHandler->style() == Milk) ? r.x() : right ? r.x()+5 : r.x()-3, r.y(), *getPixmap( flags & Style_Enabled ? (right ? VSlider : VSliderAbove) : (right ? VSliderInactive : VSliderAboveInactive))); + } + break; + } + case KPE_ListViewExpander: + { + p->fillRect(r,Qt::green); + // int radius = ( r.width() - 4 ) / 2; + // int centerx = r.x() + r.width() / 2; + // int centery = r.y() + r.height() / 2; + // + // int red, green, blue; + // red = ( cg.dark().red() >> 1 ) + ( cg.base().red() >> 1 ); + // green = ( cg.dark().green() >> 1 ) + ( cg.base().green() >> 1 ); + // blue = ( cg.dark().blue() >> 1 ) + ( cg.base().blue() >> 1 ); + // QColor blendColor( red, green, blue ); + // + // p->setPen( cg.dark() ); + // p->drawLine( r.x() + 1, r.y(), r.right() - 1, r.y() ); + // p->drawLine( r.x() + 1, r.bottom(), r.right() - 1, r.bottom() ); + // p->drawLine( r.x(), r.y() + 1, r.x(), r.bottom() - 1 ); + // p->drawLine( r.right(), r.y() + 1, r.right(), r.bottom() - 1 ); + // p->setPen( blendColor ); + // p->drawPoint( r.x(), r.y() ); + // p->drawPoint( r.right(), r.y() ); + // p->drawPoint( r.x(), r.bottom() ); + // p->drawPoint( r.right(), r.bottom() ); + // p->setPen( cg.light() ); + // p->drawRect( r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2 ); + // p->fillRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4, + // cg.background() ); + // p->setPen( cg.text() ); + // p->drawLine( centerx - radius, centery, centerx + radius, centery ); + // if ( flags & Style_On ) + // p->drawLine( centerx, centery - radius, centerx, centery + radius ); + break; + } + default: + KStyle::drawKStylePrimitive( kpe, p, widget, r, cg, flags, opt ); + } +} + +void LiquidStyle::drawControl( ControlElement element, QPainter *p, + const QWidget *widget, const QRect &r, + const QColorGroup &cg, SFlags flags, + const QStyleOption &opt ) const +{ + switch ( element ) + { + case CE_ProgressBarGroove: + { + p->setPen(cg.background().dark(160)); + p->drawRect(r); + drawCombo( p, cg, cg.background(), r.x()+1, r.y()+1, r.width()-2, r.height()+1, false, false, false, center ); + break; + } + case CE_ProgressBarContents: + { +// qWarning("%s - %s,%s : %s,%s",qApp->argv()[0],widget->className(),widget->name(),widget->parentWidget()->className(),widget->parentWidget()->name()); + const QProgressBar *progress = ( const QProgressBar * ) widget; + QRect contentsR( subRect( SR_ProgressBarContents, widget ) ); + double val = progress->progress(); + bool reverse = QApplication::reverseLayout(); + val = val / progress->totalSteps(); + if ( val > 0.0 ) + { + int w = QMIN( contentsR.width(), ( int ) (val * contentsR.width() ) ); + if ( w > 1 ) + { + int x = contentsR.x(); + int y = contentsR.y(); + QRect progressRect; + if (reverse) + progressRect = QRect(x+(contentsR.width()-w), y, w, contentsR.height()+1); + else + progressRect = QRect(x, y, w, contentsR.height()+1); + if (optionHandler->ProgressBar() == liquid) + { + int x2 = x + w - 1; + int y2 = contentsR.bottom(); + //Clip to the old rectangle + p->setClipRect(progressRect, QPainter::CoordPainter); + //Expand + progressRect.setLeft(progressRect.x() - progAnimShift); + p->setPen(cg.button().dark(120)); + p->drawLine(x, y, x2, y); + p->drawLine(x, y, x, y2); + p->drawLine(x+1, y2+1, x2-1, y2+1); + p->setPen(cg.button().dark(110)); + p->drawLine(x2, y, x2, y2); + p->drawLine(x, y2, x2, y2); + QPixmap * pix = getPixmap( Progress ); + p->drawTiledPixmap(/*x+1, y+1, w-2, contentsR.height()-2*/progressRect, *pix); + } + else if (optionHandler->ProgressBar() == baghira) + { + drawCombo( p, cg, cg.button(), r.x()-1, r.y()-1, w, contentsR.height()+5, false, false, false, center); + } + else + { + ButtonTile *progress2Tile = progress2Dict.find( cg.button().rgb() ); + if ( !progress2Tile ) + { + QPixmap *pix = getPixmap(progress2); + progress2Tile = separateTiles( pix, 0, 15, 38, 1, 0, true); + if ( !progress2Tile ) + { + qWarning( "Progress tile is NULL!" ); + return ; + } + else + { + LiquidStyle *ptr = const_cast( this ); + ptr->progress2Dict.insert( cg.button().rgb(), progress2Tile ); + } + } + //Clip to the old rectangle + p->setClipRect(progressRect, QPainter::CoordPainter); + //Expand + progressRect.setLeft(progressRect.x() - 38 + prog2AnimShift); + int h; /*x, y, w;*/ + progressRect.rect(&x, &y, &w, &h); + bool tooSmall = h < 32; + int mid = h/2; + p->drawTiledPixmap(x,tooSmall ? mid + 1 : progressRect.bottom()-15,w,16, *progress2Tile->pixmap(TileBtm)); + p->drawTiledPixmap(x,tooSmall ? mid : y+15,w,tooSmall ? 1 : h-31, *progress2Tile->pixmap(TileMiddle)); + p->drawTiledPixmap(x,tooSmall ? mid - 15 : y,w,15, *progress2Tile->pixmap(TileTop)); + } + } + } + break; + }/* + case CE_ToolButtonLabel: + { + const QToolButton *toolbutton = (const QToolButton *) widget; + QRect rect = r; + Qt::ArrowType arrowType = opt.isDefault() + ? Qt::DownArrow : opt.arrowType(); + + int shiftX = 0; + int shiftY = 0; + if (flags & (Style_Down | Style_On)) { + shiftX = pixelMetric(PM_ButtonShiftHorizontal, widget); + shiftY = pixelMetric(PM_ButtonShiftVertical, widget); + } + + if (!opt.isDefault()) + { + PrimitiveElement pe; + switch (arrowType) + { + case Qt::LeftArrow: pe = PE_ArrowLeft; break; + case Qt::RightArrow: pe = PE_ArrowRight; break; + case Qt::UpArrow: pe = PE_ArrowUp; break; + default: + case Qt::DownArrow: pe = PE_ArrowDown; break; + } + + rect.moveBy(shiftX, shiftY); + drawPrimitive(pe, p, rect, cg, flags, opt); + } + else + { + QColor btext = Qt::black;//(flags & (Style_Down | Style_On)) ? qApp->palette().color(QPalette::Active,QColorGroup::ButtonText) : toolbutton->paletteForegroundColor(); + + if (toolbutton->iconSet().isNull() && + ! toolbutton->text().isNull() && + ! toolbutton->usesTextLabel()) { + int alignment = AlignCenter | ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + rect.moveBy(shiftX, shiftY); + drawItem(p, rect, alignment, cg, + flags & Style_Enabled, 0, toolbutton->text(), + toolbutton->text().length(), &btext); + } else { + QPixmap pm; + QIconSet::Size size = + toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small; + QIconSet::State state = + toolbutton->isOn() ? QIconSet::On : QIconSet::Off; + QIconSet::Mode mode; + if (! toolbutton->isEnabled()) + mode = QIconSet::Disabled; + else if (flags & (Style_Down | Style_On) || + (flags & Style_Raised) && (flags & Style_AutoRaise)) + mode = QIconSet::Active; + else + mode = QIconSet::Normal; + pm = toolbutton->iconSet().pixmap( size, mode, state ); + + if ( toolbutton->usesTextLabel() ) + { + p->setFont( toolbutton->font() ); + QRect pr = rect, tr = rect; + int alignment = ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + if ( toolbutton->textPosition() == QToolButton::Under ) + { + int fh = p->fontMetrics().height(); + pr.addCoords( 0, 1, 0, -fh-3 ); + tr.addCoords( 0, pr.bottom(), 0, -3 ); + pr.moveBy(shiftX, shiftY); + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignCenter; + } + else + { + pr.setWidth( pm.width() + 8 ); + tr.addCoords( pr.right(), 0, 0, 0 ); + pr.moveBy(shiftX, shiftY); + + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignLeft | AlignVCenter; + } + + tr.moveBy(shiftX, shiftY); + drawItem( p, tr, alignment, cg, + flags & Style_Enabled, 0, toolbutton->textLabel(), + toolbutton->textLabel().length(), &btext); + } + else + { + rect.moveBy(shiftX, shiftY); + drawItem( p, rect, AlignCenter, cg, TRUE, &pm, QString::null ); + } + } + } + + break; + }*/ + +/* + case CE_HeaderLabel: + { + QRect rect = r; + const QHeader* header = (const QHeader *) widget; + int section = opt.headerSection(); + + QIconSet* icon = header->iconSet( section ); + if ( icon ) { + QPixmap pixmap = icon->pixmap( QIconSet::Small, + flags & Style_Enabled ? + QIconSet::Normal : QIconSet::Disabled ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + // "pixh - 1" because of tricky integer division + + QRect pixRect = rect; + pixRect.setY( rect.center().y() - (pixh - 1) / 2 ); + drawItem ( p, pixRect, AlignVCenter, cg, flags & Style_Enabled, + &pixmap, QString::null ); + rect.setLeft( rect.left() + pixw + 2 ); + } + drawItem ( p, rect, AlignVCenter, cg, flags & Style_Enabled, + 0, header->label( section ), -1, (isTaskContainer && (flags & Style_MouseOver)) ? &(qApp->palette().color(QPalette::Active,QColorGroup::ButtonText)) : &(cg.buttonText()) ); + break; + }*/ + case CE_ProgressBarLabel: + { + if (optionHandler->DrawProgressLabel()) + { + QRect contentsR( subRect( SR_ProgressBarContents, widget ) ); + if ( !contentsR.isValid() ) + return ; + QFont font( p->font() ); + font.setBold( true ); + p->setFont( font ); + p->setPen( widget->colorGroup().buttonText() ); + p->setClipRect(r, QPainter::CoordPainter); + p->drawText( contentsR, AlignCenter, ( ( const QProgressBar * ) widget ) ->progressString() ); + } + break; + } + case CE_TabBarTab: + { // new style with tiled pixmaps + if ( !widget || !widget->parentWidget(true) ) + break; + const QTabBar *tabBar = ( const QTabBar * ) widget; + bool selected = flags & Style_Selected; + bool hover = currentTabBar && currentTabBar == tabBar && tabBar->indexOf(opt.tab()->identifier()) == hoveredTabIndex; + + myPosition pos; + if (tabBar->count() == 1) + pos = full; + else if ((tabBar->indexOf(opt.tab()->identifier()) == 0)) + pos = left; + else if (tabBar->indexOf(opt.tab()->identifier()) == tabBar->count() - 1) + pos = right; + else + pos = center; + + QColor c; + if (hover || selected) + { + if (optionHandler->useCustomColors()) + c = optionHandler->customColor(CustomTabOn); + else + c = optionHandler->buttonColor(); + } + else + { + if (optionHandler->useCustomColors()) + c = optionHandler->customColor(CustomTabOff); + else + c = optionHandler->InactiveButtonColor(); + } + + bool isDialog = optionHandler->TabStyle() == Clever && widget->topLevelWidget()->inherits("QDialog"); + if (isDialog || optionHandler->TabStyle() == Chooser) + drawCombo( p, cg, c, r.x(), r.y(), r.width(), r.height(), false, false, false, pos ); + else + { + LiquidStyle *ptr = const_cast( this ); + bool above = tabBar->shape() == QTabBar::RoundedAbove || tabBar->shape() == QTabBar::TriangularAbove; + QPixmap *pix; + if (above) + pix = selected ? getPixmap( TabDown ) : getPixmap( Tab ); + else + pix = selected ? getPixmap( belowTabDown ) : getPixmap( belowTab ); + ButtonTile *tabTile = above ? tabDict.find( c.rgb() ) : inverseTabDict.find(c.rgb()); + if ( !tabTile ) + tabTile = separateTiles( pix, 9, 15, 67, 1, 0, false); + if ( !tabTile ) + { + qWarning( "Tab tile is NULL!" ); + return ; + } + else + above ? ptr->tabDict.insert( c.rgb(), tabTile ) : ptr->inverseTabDict.insert( c.rgb(), tabTile ); + + int offset; + selected ? offset = 0 : offset = 2; + + if ( r.width() > 18 ) + { + p->drawTiledPixmap( r.x() + 9, r.y() + offset, r.width() - 18, 15, *tabTile->pixmap( TileTop ) ); + p->drawTiledPixmap( r.x() + 9, r.height() - 11, r.width() - 18, 11, *tabTile->pixmap( TileBtm ) ); + } + if ( r.height() + offset > 26 ) + { + p->drawTiledPixmap( r.x() + 0, r.y() + 15 + offset, 9, r.height() - 26 - offset, *tabTile->pixmap( TileLeft ) ); + p->drawTiledPixmap( r.right() - 8, r.y() + 15 + offset, 9, r.height() - 26 - offset, *tabTile->pixmap( TileRight ) ); + } + if ( r.width() > 18 && r.height() + offset > 22 ) + p->drawTiledPixmap( r.x() + 9, r.y() + 15 + offset, r.width() - 18, r.height() - 26 - offset, *tabTile->pixmap( TileMiddle ) ); + p->drawPixmap( r.x() + 0, r.y() + offset, *tabTile->pixmap( TileTopLeft ) ); + p->drawPixmap( r.right() - 8, r.y() + offset, *tabTile->pixmap( TileTopRight ) ); + p->drawPixmap( r.x() + 0, r.height() - 11, *tabTile->pixmap( TileBtmLeft ) ); + p->drawPixmap( r.right() - 8, r.height() - 11, *tabTile->pixmap( TileBtmRight ) ); + + p->setPen( optionHandler->buttonColor()); + bool drawPoint = optionHandler->CenterTabs() || pos == center || pos == right; + if ( selected ) + { + if (drawPoint) p->drawPoint(r.x(), above ? r.bottom() : r.y()); + p->drawPoint(r.right(), above ? r.bottom() : r.y()); + } + else + { + p->drawLine( r.x() + drawPoint ? 0 : 1, above ? r.bottom() : r.y(), r.right(), above ? r.bottom() : r.y() ); + p->setPen( optionHandler->buttonColor().dark( 158 )); + p->drawLine( r.x() + drawPoint ? 0 : 1, above ? r.bottom()-1 : r.y()+1, r.right(), above ? r.bottom()-1 : r.y() + 1 ); + } + } + break; + } + case CE_TabBarLabel: + { + if ( opt.isDefault() ) + return ; + QTab *t = opt.tab(); + const QTabBar * tb = ( const QTabBar * ) widget; + if ( ( tb->currentTab() != t->identifier() )) + { + if (optionHandler->TabStyle() == TrueTab || + (optionHandler->TabStyle() == Clever && !(widget->topLevelWidget()->inherits("QDialog")))) + { + drawItem( p, QRect( r.x(), r.y() + 1, r.width(), r.height() ), AlignCenter | ShowPrefix, cg, flags & Style_Enabled, 0, t->text(), -1/*, &cg.text()*/ ); + break; + } + drawItem( p, QRect( r.x(), r.y(), r.width(), r.height() ), AlignCenter | ShowPrefix, cg, flags & Style_Enabled, 0, t->text(), -1/*, &cg.text()*/ ); + break; + } + drawItem( p, QRect( r.x(), r.y(), r.width(), r.height() ), AlignCenter | ShowPrefix, cg, flags & Style_Enabled, 0, t->text(), -1/*, &cg.text()*/ ); + break; + } + case CE_PushButton: + { + // if (_htmlWidgetWId == widget->winId()) + // return; + QPushButton *btn = ( QPushButton* ) widget; + const_cast( this ) ->isHTMLButton = isHTMLWidget( btn ); + ButtonFadeInfo *bfi_ = bfi[btn->winId()]; + if ( widget == highlightWidget || (bfi_ && !bfi_->fadeIn) ) + flags |= Style_MouseOver; + if (btn->isDefault()) + flags |= Style_HasFocus; + // Qt messes this up with WindowOrigin, so we do it ourselves :P + if ( !isPlain() && !btn->autoMask() ) + const_cast( this ) ->btnOffset = btn->backgroundOffset(); + const_cast( this ) ->paintWidget = const_cast( widget ); + drawPrimitive( PE_ButtonDefault, p, r, cg, flags, QStyleOption( btn )); + const_cast( this ) ->paintWidget = 0L; + const_cast( this ) ->isHTMLButton = false; + break; + } + case CE_PushButtonLabel: + { + // if (_htmlWidgetWId == widget->winId()) + // return; + const QPushButton *btn = ( const QPushButton* ) widget; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if ( btn->isOn() || btn->isDown() ) + flags |= Style_Sunken; + + int xoff = x; + if ( btn->iconSet() && !btn->iconSet() ->isNull() ) + { + QIconSet::Mode mode = btn->isEnabled() ? QIconSet::Normal : QIconSet::Disabled; + if ( mode == QIconSet::Normal && btn->hasFocus() ) + mode = QIconSet::Active; + + QIconSet::State state = QIconSet::Off; + if ( btn->isToggleButton() && btn->isOn() ) + state = QIconSet::On; + + QPixmap pix( btn->iconSet() ->pixmap( QIconSet::Small, mode, state ) ); + xoff += (x<6?8:2); + if (btn->text().isEmpty() && !btn->pixmap()) + p->drawPixmap( x + w/2 - pix.width()/2, y + h / 2 - pix.height() / 2, pix ); + else + p->drawPixmap( x<6?6:x, y + ( h - pix.height() ) / 2, pix ); + } + + if ( btn->isMenuButton() ) + { + drawPrimitive( PE_ArrowDown, p, QRect( w-14, (int)(h/2), 7, 7 ) , cg, flags, opt ); + w -= 14; + } + QColor tmp; + + tmp = btn->isDown() && !optionHandler->IcyButtons() ? btn->colorGroup().highlightedText() : btn->colorGroup().buttonText(); + drawItem( p, QRect( xoff, optionHandler->style() == Milk ? y-1 : y, w, h ), AlignCenter | ShowPrefix, cg, btn->isEnabled(), btn->pixmap(), btn->text(), -1, &tmp ); + break; + } + case CE_MenuBarItem: + { + QMenuItem *mi = opt.menuItem(); + bool active = flags & Style_Active; + bool focused = flags & Style_HasFocus; + + if ( active && focused ) + { + optionHandler->glossyMenus() ? + drawCombo( p, cg, cg.highlight(), r.x(), r.y()-1, r.width(), r.height() + 5, false, false, false, center ) : + p->fillRect(r,cg.highlight()); + } + + // QColor tmpColor( cg.background().dark( 120 ) ); + if ( optionHandler->useShadowText() && !( active && focused )) + { + p->setPen(cg.background().dark( 120 )); + p->drawText(r, AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, mi->text()); + } + // drawItem( p, QRect( r.x() + 1, r.y() + 1, r.width(), r.height() ), AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, cg, flags & Style_Enabled, mi->pixmap(), mi->text(), -1, &tmpColor ); + + // drawItem( p, r, AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, cg, flags & Style_Enabled, mi->pixmap(), mi->text(), -1, active && focused ? &(cg.highlightedText()) : &(cg.text()) ); + p->setPen(active && focused ? cg.highlightedText() : cg.text()); + p->drawText(r, AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, mi->text()); + break; + } + case CE_PopupMenuItem: + { + int x,y,w, h; + r.rect( &x, &y, &w, &h ); + + const QPopupMenu *popupmenu = ( const QPopupMenu * ) widget; + QMenuItem *mi = opt.menuItem(); + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = mi && !mi->isEnabled(); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + bool enabled = flags & Style_Enabled; + int checkcol = maxpmw; + + QColor menuBgColor( optionHandler->UseCustomMenuColor() ? optionHandler->Color() : optionHandler->bgColor() ); + + if ( checkable ) + checkcol = QMAX( maxpmw, 20 ); + + if ( mi && mi->isSeparator() ) + { + p->setPen( menuBgColor.dark( 130 ) ); + p->drawLine( x + 1, y, x + w - 1, y ); + p->setPen( menuBgColor.light( 120 ) ); + p->drawLine( x+1, y + 1, x + w - 1 , y + 1 ); + return ; + } + if ( act && mi && enabled) + { + optionHandler->glossyMenus() ? + drawCombo( p, cg, cg.highlight(), r.x(), r.y(), r.width(), r.height() + 2, false/*sunken*/, false/*hover*/, false, center ) : + p->fillRect(x,y,w,h,cg.highlight()); + } + else + { + if (popupBack.isNull()) + p->fillRect( x, y, w, h, popupmenu->backgroundBrush() ); + else + p->drawTiledPixmap( x, y, w, h, popupBack ); + + if (act) + { + p->setPen(cg.highlight()); + p->drawRect(x,y,w,h); + } + } + if ( !mi ) + return ; + + // Menu contents drawing code based on Qt's styles. Qt is property of + // TrollTech: www.trolltech.com. Used with permission. + int xpos = x; + QRect vrect = visualRect( QRect( xpos, y, checkcol, h ), r ); + int xvis = vrect.x(); + + // icon + if (optionHandler->drawMenuStripe()) + p->fillRect(x,y,h,h, optionHandler->menuStripeColor()); + if ( mi->iconSet() ) + { + QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; + if ( act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( vrect.center() ); + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } + else if ( checkable ) + { + if ( mi->isChecked() ) + { + int xp = xpos + windowsItemFrame; + + SFlags cflags = Style_Default; + if ( !dis ) + cflags |= Style_Enabled; + if ( act ) + cflags |= Style_On; + drawPrimitive( PE_CheckMark, p, visualRect( QRect( xp, y + windowsItemFrame, checkcol - 2 * windowsItemFrame, h - 2 * windowsItemFrame ), r ), cg, cflags ); + } + } + QColor discol; + if ( dis ) + { + discol = cg.text(); + p->setPen( discol ); + } + + int xm = windowsItemFrame + checkcol + windowsItemHMargin; + xpos += xm; + + vrect = visualRect( QRect( xpos, y + windowsItemVMargin, w - xm - tab + 1, h - 2 * windowsItemVMargin ), r ); + xvis = vrect.x(); + if ( mi->custom() ) + { + p->save(); + if ( dis && !act ) + { + p->setPen( cg.light() ); + mi->custom() ->paint( p, cg, act, !dis, xvis + 1, y + windowsItemVMargin + 1, w - xm - tab + 1, h - 2 * windowsItemVMargin ); + p->setPen( discol ); + } + mi->custom() ->paint( p, cg, act, !dis, xvis, y + windowsItemVMargin, w - xm - tab + 1, h - 2 * windowsItemVMargin ); + p->restore(); + } + + // Text + QString s = mi->text(); + if ( !s.isNull() ) + { + QColor textColor, shadowColor; + shadowColor = optionHandler->bgColor().dark( 130 ); + + if ( dis ) + textColor = shadowColor.light( 115 ); + else if (/*!optionHandler->glossyMenus() && */act && mi) + textColor = cg.highlightedText(); + else if ( optionHandler->UseCustomMenuColor()) + textColor = optionHandler->textColor(); + else + textColor = cg.text(); + + int t = s.find( '\t' ); + int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; + text_flags |= ( QApplication::reverseLayout() ? AlignRight : AlignLeft ); + if ( t >= 0 ) + { // draw tab text + int xp; + xp = x + w - tab - 20 - windowsItemHMargin - windowsItemFrame + 1; + QString tabStr( s.right( s.length() - t - 1 ) ); + if ( !tabStr.isEmpty() ) + { + if ( optionHandler->useShadowText() ) + { + p->setPen( shadowColor ); + p->drawText( xp + 1, y + windowsItemVMargin + 1, w - xm - tab + 1, h - 2 * windowsItemVMargin, text_flags, tabStr ); + } + p->setPen( textColor ); + p->drawText( xp, y + windowsItemVMargin, w - xm - tab + 1, h - 2 * windowsItemVMargin, text_flags, tabStr ); + } + s = s.left( t ); + } + if ( optionHandler->useShadowText() && !(act && mi) ) + { + p->setPen( shadowColor ); + p->drawText( xvis + 1, y + windowsItemVMargin + 1, w - xm - tab + 1, h - 2 * windowsItemVMargin, text_flags, s, t ); + } + p->setPen( textColor ); + p->drawText( xvis, y + windowsItemVMargin, w - xm - tab + 1, h - 2 * windowsItemVMargin, text_flags, s, t ); + } + else if ( mi->pixmap() ) + // draw pixmap + { + QPixmap * pixmap = mi->pixmap(); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( xvis, y + windowsItemFrame, *pixmap ); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + // Child menu + if ( mi->popup() ) + { + int dim = (int)((float)( h - 2 * windowsItemFrame ) / 2); + PrimitiveElement arrow; + arrow = ( QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight ); + xpos = x + w - windowsArrowHMargin - windowsItemFrame/* - dim*/-8; + vrect = visualRect( QRect( xpos, y + h / 2 - dim / 2, /*dim*/8, dim ), r ); + if ( act ) + { + if ( !dis ) + discol = cg.highlightedText(); + QColorGroup g2( discol, cg.highlight(), white, white, dis ? discol : white, discol, white ); + drawPrimitive( arrow, p, vrect, g2, Style_Enabled ); + } + else + { + if ( !dis ) + discol = optionHandler->textColor(); + QColorGroup g2( discol, cg.background(), white, white, dis ? discol : white, discol, white ); + drawPrimitive( arrow, p, vrect, g2, mi->isEnabled() ? Style_Enabled : Style_Default ); + } + } + break; + } + /* + case CE_ToolBoxTab: + { + break; + }*/ + default: + KStyle::drawControl( element, p, widget, r, cg, flags, opt ); + } +} + + +// void LiquidStyle::drawControlMask( ControlElement element, QPainter *p, const QWidget *widget, const QRect &r, const QStyleOption& opt ) const { +// switch ( element ) { +// case CE_PushButton: { +// p->fillRect( r, Qt::color1 ); +// break; +// } +// default: +// KStyle::drawControlMask( element, p, widget, r, opt ); +// break; +// } +// } + +// void LiquidStyle::drawComplexControlMask( ComplexControl control, QPainter *p, const QWidget *widget, const QRect &r, const QStyleOption &opt ) const { +// // switch ( control ) { +// // case CC_ComboBox: { +// // drawControlMask( CE_PushButton, p, widget, r, opt ); +// // break; +// // } +// // default: +// KStyle::drawComplexControlMask( control, p, widget, r, opt ); +// // } +// } + +void LiquidStyle::drawComplexControl( ComplexControl control, QPainter *p, const QWidget *widget, const QRect &r, const QColorGroup &cg, SFlags flags, SCFlags controls, SCFlags active, const QStyleOption &opt ) const +{ + switch ( control ) + { + case CC_ComboBox: + { + bool sunken = (active & SC_ComboBoxArrow);// || (flags & Style_Active) || (flags & Style_Sunken) || (active & SC_ComboBoxListBoxPopup); + bool hovered = (widget == highlightWidget) || (flags & Style_HasFocus); + // bool isHtml = isHTMLWidget( widget ); + const_cast( this ) ->paintWidget = const_cast( widget ); + QPen oldPen( p->pen() ); + if ( controls & SC_ComboBoxArrow ) + { + if ( controls & SC_ComboBoxEditField && ( ( const QComboBox * ) widget ) ->editable()) + { // editable? +#if 0 + if ( optionHandler->buttonStyle() == Brushed ) + { // rectangular? + drawRectangularButton( p, cg, sunken ? cg.button().light( 110 ) : cg.button(), r.x(), r.y(), r.width(), r.height(), sunken, hovered, true, full/*, isHtml*/); + p->fillRect( r.x() + 6, r.y() +2, r.width()-32, r.height() - 7, cg.background()); + p->setPen( oldPen ); + return ; + } + else +#endif + { // round frame + drawRoundFrame( p, r, cg, (flags & Style_HasFocus) || sunken , widget->backgroundOffset()); + p->setPen(cg.mid()); + p->drawPixmap(r.right() - 16, r.height()/2 - 2, *sbDown); + p->setPen( oldPen ); + // return; + } +#if 0 + else + { // default! + drawCombo( p, cg, active == SC_ComboBoxArrow ? cg.button().light( 110 ) : cg.button(), r.x(), r.y(), r.width(), r.height(), sunken, hovered, true, full ); + p->fillRect( r.x() + 6, r.y() +2, r.width()-32, r.height() - 7, cg.background()); + p->setPen( oldPen ); + return; + } +#endif + } + else + { // end editable - default handling + if ( optionHandler->buttonStyle() == Brushed ) + { // retangular? + drawRectangularButton( p, cg, sunken ? cg.button().light( 110 ) : cg.button(), r.x(), r.y(), r.width(), r.height(), sunken, hovered, true, full, isHTMLWidget( widget )); + // p->setPen( oldPen ); + // return ; + } + else + { //default plain good old combobox... ;) + drawCombo( p, cg, active == SC_ComboBoxArrow ? cg.button().light( 110 ) : cg.button(), r.x(), r.y(), r.width(), r.height(), sunken, hovered, true, full, isHTMLWidget( widget ) ); + // p->setPen( oldPen ); + // return; + } + } + } + const_cast( this ) ->paintWidget = 0L; + break; + } + case CC_ToolButton: + { + const QToolButton *toolbutton = ( const QToolButton * ) widget; + const_cast( this ) ->paintWidget = const_cast( widget ); + const KAccessToolBarButton *toolbutton2 = 0L; + QRect button, menuarea; + button = querySubControlMetrics( control, widget, SC_ToolButton, opt ); + menuarea = querySubControlMetrics( control, widget, SC_ToolButtonMenu, opt ); + if (::qt_cast(toolbutton)) + { + toolbutton2 = (const KAccessToolBarButton*)toolbutton; +#if GCC_VERSION < 40000 + if (toolbutton2->iconTextMode() == 3) + button.setBottom(button.bottom() - p->fontMetrics().height() - 1); +#endif + } + else if (toolbutton->usesTextLabel() && toolbutton->textPosition() == QToolButton::BelowIcon) + button.setBottom(button.bottom() - p->fontMetrics().height()); + menuarea.setX(menuarea.x() - 1); + SFlags bflags = flags, mflags = flags; + + if ( active & SC_ToolButton ) + bflags |= Style_Down; + if ( active & SC_ToolButtonMenu ) + mflags |= Style_Down; + + if ( widget == highlightWidget ) + bflags |= Style_MouseOver; + if ( controls & SC_ToolButton ) + { + bool sunken = mflags & ( Style_Down /*| Style_On*/ ); + bool hover = bflags & (Style_MouseOver | Style_On ); + + if ( !optionHandler->useToolButtonFrame())// || !(toolbutton->parentWidget() && ( ::qt_cast(toolbutton->parentWidget()) || toolbutton->parentWidget()->inherits("KonqFrameTabs")))) + { + if ((!(hover || sunken) || (toolbutton->usesTextLabel() && toolbutton->textPosition() == QToolButton::BelowIcon)) && toolbutton->parentWidget() && !::qt_cast(toolbutton->parent()) && toolbutton->parentWidget()->paletteBackgroundPixmap() && !toolbutton->parentWidget()->paletteBackgroundPixmap()->isNull()) + { + QPixmap pixmap = *(toolbutton->parentWidget()->paletteBackgroundPixmap()); + if (hover || sunken) + p->drawTiledPixmap( r.x(), button.bottom()+1, r.width(), p->fontMetrics().height(), pixmap, toolbutton->x(), toolbutton->y()+button.height() ); + else + p->drawTiledPixmap( r, pixmap, toolbutton->pos() ); + } + if (hover || sunken) + { + const_cast( this ) ->paintWidget = const_cast( widget ); + if (optionHandler->toolbuttonStyle() != Brushed) + drawCombo( p, cg, sunken ? cg.button().light( 110 ) : + (hover || (cg.button() != qApp->palette().active().button())) ? cg.button() : + optionHandler->InactiveButtonColor(), button.x(), button.y(), button.width(), + button.height(), sunken, hover, false, full ); + else + drawRectangularButton( p, cg, sunken ? cg.button().light( 110 ) : cg.button(), + button.x(), button.y(), button.width(), button.height(), + sunken, hover, false); + const_cast( this ) ->paintWidget = 0L; + } + } + else + { + myPosition pos = full; + KToolBar *bar = NULL; + + if (toolbutton2 && toolbutton2->parentWidget() && ::qt_cast(toolbutton2->parentWidget()) ) + { //position calculation - would be nice if ktoolbarbutton provided this as flag + bar = (KToolBar*)toolbutton2->parentWidget(); + int buttonId = toolbutton2->id(); + int buttonIndex = bar->itemIndex(buttonId); + + // ok, this is a very hackish heck of a hack... + // kbookmarkbar (e.g. used by konqueror) accesses the iterator of the toolbar + // this confuses the iterator of the toolbar a bit, as it is used from the bookmark stuff and my function at the same time (seems, as if kbookmarkbar acts on shown toolbars) + // unfortunately, there's no way to figure out if it does for this specific toolbar + // so i check for the toolbars name, knowing this will work for current konqueror - but may fail on further versions + // even worse - the stuff is hardcoded (assuming first item to be left aligned, last one right and the rest centered) + // this is crap at all - so if the best thing would be to patch qtoolbutton to provide conjuncted buttons - i'll ask them (maybe qt4) + if (bar && ( qstrcmp( bar->name(), "bookmarkToolBar" ) == 0 )) + { + return; + buttonIndex == 0 ? + pos = left : + buttonIndex == bar->count() - 1 ? + pos = right : + pos = center; + } + else if (bar->orientation() == Qt::Horizontal) + { + if (buttonIndex == 0) + { + KToolBarButton *tmpButton = bar->getButton(bar->idAt(buttonIndex+1)); + (tmpButton && tmpButton->x() == toolbutton2->x()+toolbutton2->width()) ? pos = left : pos = full; + } + else if (buttonIndex == bar->count() - 1) + { + KToolBarButton *tmpButton = NULL; + tmpButton = bar->getButton(bar->idAt(buttonIndex-1)); + (tmpButton && tmpButton->x() + tmpButton->width() == toolbutton2->x()) ? pos = right : pos = full; + } + else + { + KToolBarButton *tmpButton1 = bar->getButton(bar->idAt(buttonIndex-1)); + KToolBarButton *tmpButton2 = bar->getButton(bar->idAt(buttonIndex+1)); + tmpButton1 && tmpButton1->x() + tmpButton1->width() == toolbutton2->x() ? + pos = center : pos = left; + if (!(tmpButton2 && tmpButton2->x() == toolbutton2->x()+toolbutton2->width())) + pos == left ? pos = full : pos = right; + } + } + else + { + if (buttonIndex == 0) + { + KToolBarButton *tmpButton = bar->getButton(bar->idAt(buttonIndex+1)); + (tmpButton && tmpButton->y() == toolbutton2->y()+toolbutton2->height()) ? + pos = left : pos = full; + } + else if (buttonIndex == bar->count() - 1) + { + KToolBarButton *tmpButton = NULL; + tmpButton = bar->getButton(bar->idAt(buttonIndex-1)); + (tmpButton && tmpButton->y() + tmpButton->height() == toolbutton2->y()) ? + pos = right : pos = full; + } + else + { + KToolBarButton *tmpButton1 = bar->getButton(bar->idAt(buttonIndex-1)); + KToolBarButton *tmpButton2 = bar->getButton(bar->idAt(buttonIndex+1)); + tmpButton1 && tmpButton1->y() + tmpButton1->height() == toolbutton2->y() ? + pos = center : pos = left; + if (!(tmpButton2 && tmpButton2->y() == toolbutton2->y()+toolbutton2->height())) + pos == left ? pos = full : pos = right; + } + } + } + + if (optionHandler->toolbuttonStyle() != Brushed) + { + (bar && bar->orientation() == Qt::Vertical) ? + drawCombo( p, cg, sunken ? cg.button().light( 110 ) : (hover || (cg.button() != qApp->palette().active().button())) ? cg.button() : optionHandler->InactiveButtonColor(), button.x(), (pos == full || pos == left) ? button.y() : button.y() - 7, button.width(), (pos == full) ? button.height()+2 : (pos == center) ? button.height()+16 : button.height()+9, sunken, hover, false, center ) : + drawCombo( p, cg, sunken ? cg.button().light( 110 ) : (hover || (cg.button() != qApp->palette().active().button())) ? cg.button() : optionHandler->InactiveButtonColor(), button.x(), button.y(), button.width(), button.height()/*+2*/, sunken, hover, false, pos ); + } + else + { + (bar && bar->orientation() == Qt::Vertical) ? + drawRectangularButton( p, cg, sunken ? cg.button().light( 110 ) : (hover || (cg.button() != qApp->palette().active().button())) ? cg.button() : optionHandler->InactiveButtonColor(), button.x(), (pos == full || pos == left) ? button.y() : button.y()-4, button.width(), (pos == full) ? button.height() : (pos == center) ? button.height()+8 : button.height()+4, sunken, hover, false) : + drawRectangularButton( p, cg, sunken ? cg.button().light( 110 ) : (hover || (cg.button() != qApp->palette().active().button())) ? cg.button() : optionHandler->InactiveButtonColor(), button.x(), button.y(), button.width(), button.height(), sunken, hover, false, pos); + } + } + } + // Draw a toolbutton menu indicator if required + if ( controls & SC_ToolButtonMenu ) + { + if ( mflags & ( Style_Down | Style_On | Style_Raised ) ) + drawPrimitive( PE_ButtonDropDown, p, menuarea, cg, mflags, opt ); + drawPrimitive( PE_ArrowDown, p, menuarea, cg, mflags, opt ); + } +#if 0 + if ( toolbutton->hasFocus() && !toolbutton->focusProxy() ) + { + QRect fr = toolbutton->rect(); + fr.addCoords( 3, 3, -3, -3 ); + drawPrimitive( PE_FocusRect, p, fr, cg ); + } +#endif + const_cast( this ) ->paintWidget = 0L; + break; + } + case CC_ScrollBar: + { + const_cast( this ) ->currentScrollBar = ( QScrollBar * ) widget; + KStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); + break; + } + case CC_SpinWidget: { + const QSpinWidget * sw = (const QSpinWidget *) widget; + SFlags flags; + PrimitiveElement pe; + + if ( controls & SC_SpinWidgetFrame ) + drawEditFrame( p, r, cg, false, sw->hasFocus()); + + if ( controls & SC_SpinWidgetUp ) { + flags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetUp ) { + flags |= Style_On; + flags |= Style_Sunken; + } else + flags |= Style_Raised; + pe = PE_SpinWidgetUp; + + QRect re = sw->upRect(); + QColorGroup ucg = sw->isUpEnabled() ? cg : sw->palette().disabled(); + p->fillRect(re, ucg.base()); + drawPrimitive(pe, p, re, ucg, flags); + } + + if ( controls & SC_SpinWidgetDown ) { + flags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetDown ) { + flags |= Style_On; + flags |= Style_Sunken; + } else + flags |= Style_Raised; + pe = PE_SpinWidgetDown; + + QRect re = sw->downRect(); + QColorGroup dcg = sw->isDownEnabled() ? cg : sw->palette().disabled(); + p->fillRect(re, dcg.base()); + drawPrimitive(pe, p, re, dcg, flags); + } + break; } + + // SLIDER - KDE code for double buffering + // ------------------------------------------------------------------- + case CC_Slider: { + const QSlider* slider = (const QSlider*)widget; + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt); + QRect handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt); + + // Double-buffer slider for no flicker + QPixmap pix(widget->size()); + QPainter p2; + p2.begin(&pix); + if ( slider->parentWidget() && + (slider->parentWidget()->paletteBackgroundPixmap() && !slider->parentWidget()->paletteBackgroundPixmap()->isNull() )) { + QPixmap pixmap = *(slider->parentWidget()->backgroundPixmap()); + if (QWidget *topDaddy = slider->topLevelWidget()){ + QPoint zero = QPoint(0,0); +#if 0 + zero = slider->mapTo(topDaddy, zero); + int zxmpw = zero.x()%pixmap.width(); + int zymph; +#endif + // probably due to argb mismatches in drawpixmap, this fails on kompmgr startups + p2.drawTiledPixmap(r, pixmap, slider->mapTo(topDaddy, zero)); +#if 0 + for (int dx = 0; dx < pix.width(); dx += pixmap.width()) + { + zymph = zero.y()%pixmap.height(); + for (int dy = 0; dy < pix.height(); dy += pixmap.height()) + { + copyBlt (&pix, dx, dy, &pixmap, + zxmpw, zymph, + pix.width()-dx>pixmap.width()-zxmpw?pixmap.width()-zxmpw:pix.width()-dx, pix.height()-dy>pixmap.height()-zymph?pixmap.height()-zymph:pix.height()-dy); + zymph=0; + } + zxmpw=0; + } +#endif + } else + { + // probably due to argb mismatches in drawpixmap, this fails on kompmgr startups + p2.drawTiledPixmap(r, pixmap, slider->pos()); +#if 0 + for (int dx = 0; dx < pix.width(); dx += pixmap.width()) + for (int dy = 0; dy < pix.height(); dy += pixmap.height()) + copyBlt (&pix, dx, dy, &pixmap, 0, 0, + pix.width()-dx>pixmap.width()?pixmap.width():pix.width()-dx, pix.height()-dy>pixmap.height()?pixmap.height():pix.height()-dy); +#endif + } + // p2.begin(&pix); + } else{ + // p2.begin(&pix); + pix.fill(cg.background()); + } + + // Draw slider groove + if ((controls & SC_SliderGroove) && groove.isValid()) { + drawKStylePrimitive( KPE_SliderGroove, &p2, widget, groove, cg, flags, opt ); + + // Draw the focus rect around the groove + /* if (slider->hasFocus()) + drawPrimitive(PE_FocusRect, &p2, groove, cg);*/ + } + + // Draw the tickmarks + if (controls & SC_SliderTickmarks) + QCommonStyle::drawComplexControl(control, &p2, widget, + r, cg, flags, SC_SliderTickmarks, active, opt); + + // Draw the slider handle + if ((controls & SC_SliderHandle) && handle.isValid()) { + if (active == SC_SliderHandle) + flags |= Style_Active; + drawKStylePrimitive( KPE_SliderHandle, &p2, widget, handle, cg, flags, opt ); + } + + p2.end(); + bitBlt((QWidget*)widget, r.x(), r.y(), &pix); + break; + } + +#ifndef QT_NO_LISTVIEW + case CC_ListView: { + if ( controls & SC_ListView ) { + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); + } + if ( controls & ( SC_ListViewBranch | SC_ListViewExpand ) ) { + if ( opt.isDefault() ) + break; + + QListViewItem *item = opt.listViewItem(); + QListViewItem *child = item->firstChild(); + QListView* v = item->listView(); + bool drawDotlines = optionHandler->DrawDotlines(); + static QBitmap *verticalLine = 0, *horizontalLine = 0; + static QCleanupHandler qlv_cleanup_bitmap; + int dotoffset = 0; + + if (drawDotlines && (optionHandler->DotlineStyle() == Dots)){ + if ( !verticalLine ) { + // make 128*1 and 1*128 bitmaps that can be used for + // drawing the right sort of lines. + verticalLine = new QBitmap( 1, 128, TRUE ); + horizontalLine = new QBitmap( 128, 1, TRUE ); + QPointArray a( 64 ); + QPainter p; + p.begin( verticalLine ); + int i; + for( i=0; i<64; i++ ) + a.setPoint( i, 0, i*2+1 ); + p.setPen( optionHandler->DotlineColor() ); + p.drawPoints( a ); + p.end(); + QApplication::flushX(); + verticalLine->setMask( *verticalLine ); + p.begin( horizontalLine ); + for( i=0; i<64; i++ ) + a.setPoint( i, i*2+1, 0 ); + p.setPen( optionHandler->DotlineColor() ); + p.drawPoints( a ); + p.end(); + QApplication::flushX(); + horizontalLine->setMask( *horizontalLine ); + qlv_cleanup_bitmap.add( &verticalLine ); + qlv_cleanup_bitmap.add( &horizontalLine ); + } + } + + + int y = r.y(); + int c; + QPointArray dotlines; + if ( drawDotlines && active == SC_All && controls == SC_ListViewExpand ) { + c = 2; + dotlines.resize( 2 ); + dotlines[ 0 ] = QPoint( r.right(), r.top() ); + dotlines[ 1 ] = QPoint( r.right(), r.bottom() ); + } + else { + int linetop = 0, linebot = 0; + // each branch needs at most two lines, ie. four end points + dotoffset = (item->itemPos() + item->height() - y) %2; + dotlines.resize( item->childCount() * 4 ); + c = 0; + + // skip the stuff above the exposed rectangle + while ( child && y + child->height() <= 0 ) { + y += child->totalHeight(); + child = child->nextSibling(); + } + + int bx = r.width() / 2; + + // paint stuff in the magical area + while ( child && y < r.height() ) { + int lh; + if ( !item->multiLinesEnabled() ) + lh = child ? child->height() : 0; + else + lh = p->fontMetrics().height() + 2 * v->itemMargin(); + lh = QMAX( lh, QApplication::globalStrut().height() ); + if ( lh % 2 > 0 ) + lh++; + linebot = y + lh / 2; + if ( ( child->isExpandable() || child->childCount() ) && ( child->height() > 0 ) ) { + if ( optionHandler->ExpanderStyle() == MS ) { // f****** M$ +/- style :-( + // needs a box + p->setPen( optionHandler->DotlineColor() ); + p->drawRect( bx - 4, linebot - 4, 9, 9 ); + // plus or minus + p->setPen( optionHandler->UseCustomExpanderColor() ? optionHandler->CustomExpanderColor() : cg.text() ); + p->drawLine( bx - 2, linebot, bx + 2, linebot ); + if ( !child->isOpen() ) + p->drawLine( bx, linebot - 2, bx, linebot + 2 ); + } else { // ultracool triangles ;-) + QPointArray a; + p->setPen( optionHandler->UseCustomExpanderColor() ? optionHandler->CustomExpanderColor() : cg.text() ); + if ( child->isOpen() ) { + a.setPoints( 3, bx - 4, linebot - 2, + bx, linebot + 2, + bx + 4, linebot - 2 ); + } //DownArrow + else { + a.setPoints( 3, bx - 2, linebot - 4, + bx + 2, linebot, + bx - 2, linebot + 4 ); + } //RightArrow + p->setBrush( optionHandler->UseCustomExpanderColor() ? optionHandler->CustomExpanderColor() : cg.text() ); + p->drawPolygon( a ); + + p->setBrush( NoBrush ); + } + // dotlinery + if ( drawDotlines ) { + dotlines[ c++ ] = QPoint( bx, linetop ); + dotlines[ c++ ] = QPoint( bx, linebot - (/* optionHandler->plusMinus() ? 4 : */5 ) ); + dotlines[ c++ ] = QPoint( bx + 5, linebot ); + dotlines[ c++ ] = QPoint( r.width(), linebot ); + linetop = linebot + 5; + } + } else { + // just dotlinery + if ( drawDotlines ) { + dotlines[ c++ ] = QPoint( bx + 2, linebot ); + dotlines[ c++ ] = QPoint( r.width(), linebot ); + } + } + + y += child->totalHeight(); + child = child->nextSibling(); + } + + // Expand line height to edge of rectangle if there's a + // child, and it's visible + if ( child && ( child->height() > 0 ) ) { + linebot = r.height(); + } + + if ( drawDotlines ) { + if ( linetop < linebot ) { + dotlines[ c++ ] = QPoint( bx, linetop ); + dotlines[ c++ ] = QPoint( bx, linebot ); + } + } + } + + if ( drawDotlines && optionHandler->DotlineStyle() == Line) { + int line; // index into dotlines + p->setPen( optionHandler->DotlineColor() ); + + if ( controls & SC_ListViewBranch ) + for ( line = 0; line < c; line += 2 ) { + p->drawLine( dotlines[ line ].x(), dotlines[ line ].y(), + dotlines[ line + 1 ].x(), dotlines[ line + 1 ].y() ); + } + + } + else if (drawDotlines && (optionHandler->DotlineStyle() == Dots)) { + int line; // index into dotlines + if ( controls & SC_ListViewBranch ){ + p->setPen( optionHandler->DotlineColor() ); + for( line = 0; line < c; line += 2 ) { + // assumptions here: lines are horizontal or vertical. + // lines always start with the numerically lowest + // coordinate. + + // point ... relevant coordinate of current point + // end ..... same coordinate of the end of the current line + // other ... the other coordinate of the current point/line + if ( dotlines[line].y() == dotlines[line+1].y() ) { + int end = dotlines[line+1].x(); + int point = dotlines[line].x(); + int other = dotlines[line].y(); + while( point < end ) { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( point, other, *horizontalLine, 0, 0, i, 1 ); + point += i; + } + } + else { + int end = dotlines[line+1].y(); + int point = dotlines[line].y(); + int other = dotlines[line].x(); + int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0; + while( point < end ) { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( other, point, *verticalLine, 0, pixmapoffset, 1, i ); + point += i; + } + } + } + } + } + } + + break; + } +#endif // QT_NO_LISTVIEW + +#ifndef QT_NO_TITLEBAR + case CC_TitleBar: + { + switch (optionHandler->style()) + { + case Jaguar: + if (!widget->isActiveWindow()) p->drawTiledPixmap(r, *getPixmap( TitleBar )); + p->setPen(optionHandler->titleColor(1).dark(180)); + p->drawLine(r.left(), r.bottom(), r.right(), r.bottom()); + break; + case Panther: + case Tiger: + case Milk: + { + if (widget->isActiveWindow()) p->drawTiledPixmap(r, *getPixmap( TitleBar )); + p->setPen(optionHandler->titleColor(1).dark(180)); + p->drawLine(r.left(), r.bottom(), r.right(), r.bottom()); + break; + } + case Brushed: + break; + } + if ( controls & SC_TitleBarLabel ) + { + QRect ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarLabel ), widget ); + p->setPen( cg.text() ); + p->drawText(ir.x()+2, ir.y(), ir.width()-2, ir.height(), AlignCenter | AlignVCenter | SingleLine, widget->caption() ); + } + + QRect ir; + bool down = FALSE; + QPixmap pm; + + if ( controls & SC_TitleBarCloseButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarCloseButton ), widget ); + down = active & SC_TitleBarCloseButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? optionHandler->titleButtonColor(0).dark(120) : optionHandler->titleButtonColor(0), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? optionHandler->titleButtonColor(0).dark(120) : optionHandler->titleButtonColor(0), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + if ( controls & SC_TitleBarSysMenu ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarSysMenu ), widget ); + down = active & SC_TitleBarSysMenu; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + + if ( controls & SC_TitleBarMaxButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMaxButton ), widget ); + down = active & SC_TitleBarMaxButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? optionHandler->titleButtonColor(2).dark(120) : optionHandler->titleButtonColor(2), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? optionHandler->titleButtonColor(2).dark(120) : optionHandler->titleButtonColor(2), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + + if ( controls & SC_TitleBarMinButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMinButton ), widget ); + down = active & SC_TitleBarMinButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? optionHandler->titleButtonColor(1).dark(120) : optionHandler->titleButtonColor(1), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? optionHandler->titleButtonColor(1).dark(120) : optionHandler->titleButtonColor(1), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + if ( controls & SC_TitleBarNormalButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarNormalButton ), widget ); + down = active & SC_TitleBarNormalButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? optionHandler->titleButtonColor(1).dark(120) : optionHandler->titleButtonColor(1), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? optionHandler->titleButtonColor(1).dark(120) : optionHandler->titleButtonColor(1), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + + if ( controls & SC_TitleBarShadeButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarShadeButton ), widget ); + down = active & SC_TitleBarShadeButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + + if ( controls & SC_TitleBarUnshadeButton ) + { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarUnshadeButton ), widget ); + down = active & SC_TitleBarUnshadeButton; + if (optionHandler->buttonStyle() == Brushed) + drawRectangularButton( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height(), down, false, false, full); + else + drawCombo( p, cg, down ? cg.button().dark(120) : cg.button(), ir.x(), ir.y(), ir.width(), ir.height()+2, down, false, false, full ); + } + break; + } +#endif //QT_NO_TITLEBAR + + default: + KStyle::drawComplexControl( control, p, widget, + r, cg, flags, controls, active, opt ); + break; + } +} + +int LiquidStyle::styleHint(StyleHint sh, const QWidget * w, const QStyleOption & opt, QStyleHintReturn * shr) const +{ + switch (sh) + { + case QStyle::SH_GUIStyle: + // if (w && ::qt_cast(w)) + // return WindowsStyle; + return MacStyle; + case QStyle::SH_TabBar_Alignment: + if (optionHandler->CenterTabs() && !QApplication::reverseLayout()) + return AlignHCenter; + else + return KStyle::styleHint(sh, w, opt, shr); + default: + return KStyle::styleHint(sh, w, opt, shr); + } +} + +QRect LiquidStyle::subRect( SubRect r, const QWidget *widget ) const { + if (r == SR_ComboBoxFocusRect){ + return querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ); + } + return ( KStyle::subRect( r, widget ) ); +} + +int LiquidStyle::pixelMetric( PixelMetric m, const QWidget *widget ) const +{ + switch ( m ) + { + case PM_ButtonMargin: + return ( 5 ); + case PM_ButtonDefaultIndicator: + return ( 0 ); + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + return ( 16 ); + case PM_IndicatorWidth: + case PM_IndicatorHeight: + return ( 16 ); + case PM_ScrollBarExtent: + return ( 15 ); + case PM_ScrollBarSliderMin: + if (isOOO) return 10; return ( 40 ); + case PM_SplitterWidth: + return 6; + case PM_SliderControlThickness: + return(15); + case PM_SliderThickness: + return ( 22 ); + /* if (widget && (widget->width() < widget->height() && widget->width() < 17) || (widget->width() > widget->height() && widget->height() < 17)) + return (16);*/ + case PM_SliderLength: + return ( optionHandler->style() == Milk ? 15 : 13 ); + case PM_TabBarTabOverlap: + return 0; + case PM_DefaultFrameWidth: + { + /* + if (widget && ::qt_cast(widget) && ((QFrame*)widget)->frameShape() == QFrame::LineEditPanel) + return 6;*/ + if (widget && widget->parentWidget() && ::qt_cast(widget->parentWidget()) && widget->parentWidget()->parentWidget() && (widget->parentWidget()->parentWidget()->inherits("KonqMainWindow") || widget->parentWidget()->parentWidget()->inherits("KonqFrameContainer"))) //for the konqueror statusbar offset, thanks konqueror team... ... ... f***f***f***!!! + return 0; + return 2; + } + case PM_TabBarBaseOverlap: + case PM_TabBarBaseHeight: + { + if (!widget || !::qt_cast(widget) || !widget->children()) + return 0; + QObjectListIt it( *widget->children() ); // iterate over the buttons + QObject *obj; + QTabBar *tabBar = 0L; + while ( (obj = it.current()) != 0 ) + { + ++it; + if (::qt_cast(obj)) + { + tabBar = (QTabBar*)obj; + break; + } + } + if (!tabBar || !tabBar->isVisible()) + return 0; + if (optionHandler->TabStyle() == Chooser || (optionHandler->TabStyle() == Clever && widget && widget->topLevelWidget()->inherits("QDialog"))) + return 12; + if (m == PM_TabBarBaseOverlap) + return 2; + return 7; + } + case PM_TabBarTabHSpace: + if (optionHandler->TabStyle() == Chooser || (optionHandler->TabStyle() == Clever && widget && widget->topLevelWidget()->inherits("QDialog"))) return 18; + return 24; + case PM_TabBarTabVSpace: + { + if (optionHandler->TabStyle() == Chooser || (optionHandler->TabStyle() == Clever && widget && widget->topLevelWidget()->inherits("QDialog"))) return 6; + return 10; + } + case PM_TabBarTabShiftHorizontal: + return 0; + case PM_TabBarTabShiftVertical: + if (optionHandler->TabStyle() == Chooser || (optionHandler->TabStyle() == Clever && widget && widget->topLevelWidget()->inherits("QDialog"))) return 0; + return 2; + case PM_ButtonShiftHorizontal: + return 0; + case PM_ButtonShiftVertical: + return 0; + default: + return KStyle::pixelMetric( m, widget ); + } +} + +QSize LiquidStyle::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentSize, + const QStyleOption& opt ) const { + switch ( contents ) { + case CT_PushButton: { + // this is a little funky - we give values not based on pixelMetric + // because we want a custom width/height and we can only give one + // value in pixelMetric (used in sizeHint). Odd but works well + const QPushButton * button = ( const QPushButton* ) widget; + + int w = contentSize.width() + 26 > 80 ? contentSize.width() + 26 : 80; + int h = contentSize.height() > 24 ? contentSize.height() : 25; + + if ( button->text().isEmpty() ) + return ( QSize( contentSize.width() + 2 * pixelMetric( PM_ButtonMargin, widget ), h ) ); + + return ( QSize( w, h ) ); + } + + case CT_ToolButton: { + if (widget->parentWidget() && ::qt_cast(widget->parentWidget())){ + return QSize(contentSize.width() + 6, contentSize.height() + 5); + } + else{ + int w = contentSize.width() + 6; + int sh = contentSize.height() + 5; + int sw = (int)(1.3*sh); + if (w < sw) + return QSize(sw, sh); + else + return QSize(w, sh); + } + } + + case CT_Slider: { + int h = contentSize.height() > 24 ? contentSize.height() : 24; + return ( QSize( contentSize.width(), h ) ); + } + + case CT_ComboBox: { + // QSize sz = KStyle::sizeFromContents( contents, widget, contentSize, opt ); + // return ( QSize( sz.width()+3, sz.height() > 25 ? sz.height() : 25 ) ); + if ( ::qt_cast(widget) && ((const QComboBox *)widget)->editable()) + return ( QSize( contentSize.width()+27, contentSize.height() + 4 > 22 ? contentSize.height() + 4 : 26 ) ); + else + return ( QSize( contentSize.width()+27, contentSize.height() + 2 > 24 ? contentSize.height() + 2 : 24 ) ); + } + case CT_PopupMenuItem: { + if ( ! widget || opt.isDefault() ) + break; + + const QPopupMenu *popup = ( const QPopupMenu * ) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = contentSize.width(); + int h = contentSize.height(); + + if ( mi->custom() ) { + w = mi->custom() ->sizeHint().width(); + h = mi->custom() ->sizeHint().height(); + if ( !mi->custom() ->fullSpan() ) + h += 2 * windowsItemVMargin + 2 * windowsItemFrame; + } else if ( mi->widget() ) {} + else if ( mi->isSeparator() ) { + w = 10; + h = windowsSepHeight; + } else { + if ( mi->pixmap() ) + h = QMAX( h, mi->pixmap() ->height() + 2 * windowsItemFrame ); + else if ( ! mi->text().isNull() ) + h = QMAX( h, popup->fontMetrics().height() + 2 * windowsItemVMargin + + 2 * windowsItemFrame ); + if ( mi->iconSet() != 0 ) + h = QMAX( h, mi->iconSet() ->pixmap( QIconSet::Small, + QIconSet::Normal ).height() + + 2 * windowsItemFrame ); + } + if ( !mi->text().isNull() && mi->text().find( '\t' ) >= 0 ) + w += windowsTabSpacing; + else if ( mi->popup() ) + w += 2 * windowsArrowHMargin; + if ( checkable && maxpmw < 20 ) + w += 20 - maxpmw; + if ( maxpmw ) + w += maxpmw + 6; + if ( checkable || maxpmw > 0 ) + w += windowsCheckMarkHMargin; + w += 20; + return ( QSize( w, h ) ); + } + default: + break; + } + return KStyle::sizeFromContents( contents, widget, contentSize, opt ); +} + + +QPixmap LiquidStyle::stylePixmap( StylePixmap stylepixmap, + const QWidget* widget, + const QStyleOption& opt ) const { + return KStyle::stylePixmap( stylepixmap, widget, opt ); +} + +#include "eventfilter.cpp" + +QRect LiquidStyle::querySubControlMetrics( ComplexControl control, const QWidget *widget, SubControl subcontrol, const QStyleOption &opt ) const +{ + if ( control == CC_ComboBox && subcontrol == SC_ComboBoxEditField ) + return QRect( 8, 3, widget->width() - 32, widget->height() - 7 ); + if (control == CC_TitleBar) + { + switch (subcontrol) + { + case SC_TitleBarSysMenu: + return QRect( widget->width() - 24, 1, 16, 16 ); + case SC_TitleBarMinButton: + return QRect( 26, 1, 16, 16 ); + case SC_TitleBarMaxButton: + return QRect( 47, 1, 16, 16 ); + case SC_TitleBarCloseButton: + return QRect( 5, 1, 16, 16 ); + case SC_TitleBarLabel: + return QRect( 68, 1, widget->width() - 107, 16 ); + case SC_TitleBarNormalButton: + return QRect( 26, 1, 16, 16 ); + case SC_TitleBarShadeButton: + return QRect( widget->width() - 29, 1, 24, 16 ); + case SC_TitleBarUnshadeButton: + return QRect( widget->width() - 29, 1, 24, 16 ); + default: + return ( KStyle::querySubControlMetrics( control, widget, subcontrol, opt ) ); + } + } + else + return ( KStyle::querySubControlMetrics( control, widget, subcontrol, opt ) ); +} + +QImage LiquidStyle::fetchImage( const char *name ){ + return uic_findImage( name ); +} + +QColor LiquidStyle::mapFadeColor(QColor &color, int index) const +{ + QRgb **rgb = fadeColorMap.find(color.rgb()); + if (rgb) + return QColor((*rgb)[index]); + // no color map found, create one and return the queried value + rgb = new QRgb*; + *rgb = new QRgb[10]; + int iRed = optionHandler->InactiveButtonColor().red(); + int iGreen = optionHandler->InactiveButtonColor().green(); + int iBlue = optionHandler->InactiveButtonColor().blue(); + int cRed = color.red(); + int cGreen = color.green(); + int cBlue = color.blue(); + for (int i = 10; i < 20; i++) + { + (*rgb)[i-10] = qRgb( iRed + (cRed-iRed)*(i)/20, iGreen + (cGreen-iGreen)*(i)/20, iBlue + (cBlue-iBlue)*(i)/20); + } + LiquidStyle *ptr = const_cast( this ); + ptr->fadeColorMap.insert(color.rgb(), rgb); + return QColor((*rgb)[index]); +} + +QPixmap* LiquidStyle::processEmbedded( const char *label, const QColor &c, bool blend, const QColor *bg ) const { + QImage img( uic_findImage( label ) ); + img.detach(); + if ( img.isNull() ) { // shouldn't happen, been tested + qWarning( "Invalid embedded label %s", label ); + return ( NULL ); + } + return ( adjustHSV( img, c, bg ) ); +} + +QPixmap* LiquidStyle::getPixmap( BitmapData item ) const +{ + if ( pixmaps[ item ] ) + return ( pixmaps[ item ] ); + QColor bgColor( optionHandler->InactiveButtonColor() ); + QColor btnColor( isOOO ? optionHandler->CustomButtonColor() : qApp->palette().active().button() ); + QColor btnHoverColor( isOOO ? optionHandler->CustomButtonColor().light(120) : btnColor.light( 120 ) ); + QColor sbGrooveColor( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBGroove ) : bgColor ); + QColor sbSliderColor( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBSlider ) : bgColor ); + QColor sbSliderHoverColor( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBSliderHover ) : isOOO?optionHandler->CustomButtonColor():btnColor ); + QColor sbSliderPressedColor( optionHandler->useCustomColors() ? + optionHandler->customColor( CustomSBSliderPressed ) : btnColor.dark(110) ); + LiquidStyle *ptr = const_cast( this ); + switch ( item ) + { + case RadioOn: + ptr->pixmaps[ RadioOn ] = processEmbedded( (optionHandler->style() == Milk) ? "radio_down-milk" : "radio_down", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOn ) : btnColor, true ); + break; + case RadioOff: + ptr->pixmaps[ RadioOff ] = processEmbedded( (optionHandler->style() == Milk) ? "radio-milk" : "radio", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOff ) : bgColor, true ); + break; + case RadioOnHover: + ptr->pixmaps[ RadioOnHover ] = processEmbedded( (optionHandler->style() == Milk) ? "radio_down-milk" : "radio_down", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOn ).light( 110 ) : btnHoverColor, true ); + break; + case RadioOffHover: + ptr->pixmaps[ RadioOffHover ] = processEmbedded( (optionHandler->style() == Milk) ? "radio-milk" : "radio", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOn ) : btnColor, true ); + case RadioOnPressed: + ptr->pixmaps[ RadioOnPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "radio_down-milk" : "radio_down", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOn ).dark( 120 ) : btnHoverColor.dark( 120 ), true ); + break; + case RadioOffPressed: + ptr->pixmaps[ RadioOffPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "radio-milk" : "radio", optionHandler->useCustomColors() ? optionHandler->customColor( CustomRadioOn ).dark( 120 ) : btnColor.dark( 120 ), true ); + break; + case Tab: + ptr->pixmaps[ Tab ] = processEmbedded( (optionHandler->style() == Jaguar) ? "tab-jaguar" : (optionHandler->style() == Milk) ? "tab-milk" : "tab", optionHandler->useCustomColors() ? optionHandler->customColor( CustomTabOff ) : optionHandler->InactiveButtonColor(), true ); + break; + case belowTab: + ptr->pixmaps[ belowTab ] = processEmbedded( (optionHandler->style() == Jaguar) ? "tab-jaguar" : (optionHandler->style() == Milk) ? "tab-milk" : "tab", optionHandler->useCustomColors() ? optionHandler->customColor( CustomTabOff ) : optionHandler->InactiveButtonColor(), true ); + *ptr->pixmaps[ belowTab ] = ptr->pixmaps[ belowTab ] ->xForm( iMatrix ); + break; + case TabDown: + ptr->pixmaps[ TabDown ] = processEmbedded( (optionHandler->style() == Jaguar) ? "tab-jaguar" : (optionHandler->style() == Milk) ? "tab-milk" : "tab", optionHandler->useCustomColors() ? optionHandler->customColor( CustomTabOn ) : btnColor, true ); + break; + case belowTabDown: + ptr->pixmaps[ belowTabDown ] = processEmbedded( (optionHandler->style() == Jaguar) ? "tab-jaguar" : (optionHandler->style() == Milk) ? "tab-milk" : "tab", optionHandler->useCustomColors() ? optionHandler->customColor( CustomTabOn ) : btnColor, true ); + *ptr->pixmaps[ belowTabDown ] = ptr->pixmaps[ belowTabDown ] ->xForm( iMatrix ); + break; + case TabFocus: + ptr->pixmaps[ TabFocus ] = processEmbedded( (optionHandler->style() == Jaguar) ? "tab-jaguar" : (optionHandler->style() == Milk) ? "tab-milk" : "tab", optionHandler->useCustomColors() ? optionHandler->customColor( CustomTabOn ).light( 120 ) : btnHoverColor, true ); + break; + case CB: + ptr->pixmaps[ CB ] = processEmbedded( (optionHandler->style() == Milk) ? "checkbox-milk" : "checkbox", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOff ) : bgColor, true ); + break; + case CBDown: + ptr->pixmaps[ CBDown ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ) : btnColor, true ); + break; + case CBDownHover: + ptr->pixmaps[ CBDownHover ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ).light( 110 ) : btnHoverColor, true ); + break; + case CBTri: + ptr->pixmaps[ CBTri ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ) : btnColor, true ); + *ptr->pixmaps[ CBTri ] = ptr->pixmaps[ CBTri ] ->xForm( mMatrix ); + break; + case CBTriHover: + ptr->pixmaps[ CBTriHover ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ).light( 110 ) : btnHoverColor, true ); + *ptr->pixmaps[ CBTriHover ] = ptr->pixmaps[ CBTriHover ] ->xForm( mMatrix ); + break; + case CBHover: + ptr->pixmaps[ CBHover ] = processEmbedded( (optionHandler->style() == Milk) ? "checkbox-milk" : "checkbox", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ) : btnColor, true ); + break; + case CBDownPressed: + ptr->pixmaps[ CBDownPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ).dark( 120 ) : btnHoverColor.dark( 120 ), true ); + break; + case CBTriPressed: + ptr->pixmaps[ CBTriPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "checkboxdown-milk" : "checkboxdown", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ).dark( 120 ) : btnHoverColor.dark( 120 ), true ); + *ptr->pixmaps[ CBTriPressed ] = ptr->pixmaps[ CBTriPressed ] ->xForm( mMatrix ); + break; + case CBPressed: + ptr->pixmaps[ CBPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "checkbox-milk" : "checkbox", optionHandler->useCustomColors() ? optionHandler->customColor( CustomCBOn ).dark( 120 ) : btnColor.dark( 120 ), true ); + break; + case HSlider: + ptr->pixmaps[ HSlider ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", btnColor, true ); + break; + case VSlider: + ptr->pixmaps[ VSlider ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", btnColor, true ); + *ptr->pixmaps[ VSlider ] = ptr->pixmaps[ VSlider ] ->xForm( lMatrix ); + break; + case VSliderAbove: + ptr->pixmaps[ VSliderAbove ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", btnColor, true ); + *ptr->pixmaps[ VSliderAbove ] = ptr->pixmaps[ VSliderAbove ] ->xForm( rMatrix ); + break; + case HSliderInactive: + ptr->pixmaps[ HSliderInactive ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", bgColor, true ); + break; + case VSliderInactive: + ptr->pixmaps[ VSliderInactive ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", bgColor, true ); + *ptr->pixmaps[ VSliderInactive ] = ptr->pixmaps[ VSliderInactive ] ->xForm( lMatrix ); + break; + case VSliderAboveInactive: + ptr->pixmaps[ VSliderAboveInactive ] = processEmbedded( (optionHandler->style() == Milk) ? "sliderarrow-milk" : "sliderarrow", bgColor, true ); + *ptr->pixmaps[ VSliderAboveInactive ] = ptr->pixmaps[ VSliderAboveInactive ] ->xForm( rMatrix ); + break; + case VSBSliderTop: + ptr->pixmaps[ VSBSliderTop ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderColor, sbGrooveColor.dark( 120 ), true) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderColor, true, &sbGrooveColor ); + break; + case VSBSliderBtm: + ptr->pixmaps[ VSBSliderBtm ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderColor, sbGrooveColor.dark( 120 ), false) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderColor, true, &sbGrooveColor ); + break; + case VSBSliderMid: + ptr->pixmaps[ VSBSliderMid ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbIslider_mid", sbSliderColor, &sbGrooveColor ); + break; + case VSBSliderTopActive: + ptr->pixmaps[ VSBSliderTopActive ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderHoverColor, sbGrooveColor.dark( 120 ), true) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderHoverColor, true, &sbGrooveColor ); + break; + case VSBSliderBtmActive: + ptr->pixmaps[ VSBSliderBtmActive ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderHoverColor, sbGrooveColor.dark( 120 ), false) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderHoverColor, true, &sbGrooveColor ); + break; + case VSBSliderMidActive: + ptr->pixmaps[ VSBSliderMidActive ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbslider_mid", sbSliderHoverColor, false, &sbGrooveColor ); + break; + case VSBSliderTopPressed: + ptr->pixmaps[ VSBSliderTopPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderPressedColor, true, &sbGrooveColor ); + *ptr->pixmaps[ VSBSliderTopPressed ] = ptr->pixmaps[ VSBSliderTopPressed ] ->xForm( mMatrix ); + break; + case VSBSliderBtmPressed: + ptr->pixmaps[ VSBSliderBtmPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderPressedColor, true, &sbGrooveColor ); + *ptr->pixmaps[ VSBSliderBtmPressed ] = ptr->pixmaps[ VSBSliderBtmPressed ] ->xForm( mMatrix ); + break; + case VSBSliderMidPressed: + ptr->pixmaps[ VSBSliderMidPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbslider_mid", sbSliderPressedColor, false, &sbGrooveColor ); + if (optionHandler->style() == Milk) + *ptr->pixmaps[ VSBSliderMidPressed ] = ptr->pixmaps[ VSBSliderMidPressed ] ->xForm( iMatrix ); + break; + + case HSBSliderTop: + ptr->pixmaps[ HSBSliderTop ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderColor, sbGrooveColor.dark( 120 ), true) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderTop ] = ptr->pixmaps[ HSBSliderTop ]->xForm( rMatrix ); + break; + case HSBSliderBtm: + ptr->pixmaps[ HSBSliderBtm ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderColor, sbGrooveColor.dark( 120 ), false) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderBtm ] = ptr->pixmaps[ HSBSliderBtm ] ->xForm( rMatrix ); + break; + case HSBSliderMid: + ptr->pixmaps[ HSBSliderMid ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbIslider_mid", sbSliderColor, false, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderMid ] = ptr->pixmaps[ HSBSliderMid ]->xForm( rMatrix ); + break; + case HSBSliderTopActive: + ptr->pixmaps[ HSBSliderTopActive ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderHoverColor, sbGrooveColor.dark( 120 ), true) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderHoverColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderTopActive ] = ptr->pixmaps[ HSBSliderTopActive ] ->xForm( rMatrix ); + break; + case HSBSliderBtmActive: + ptr->pixmaps[ HSBSliderBtmActive ] = optionHandler->shadowSbSlider() ? createSliderEnd( sbSliderHoverColor, sbGrooveColor.dark( 120 ), false) : processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderHoverColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderBtmActive ] = ptr->pixmaps[ HSBSliderBtmActive ] ->xForm( rMatrix ); + break; + case HSBSliderMidActive: + ptr->pixmaps[ HSBSliderMidActive ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbslider_mid", sbSliderHoverColor, false, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderMidActive ] = ptr->pixmaps[ HSBSliderMidActive ] ->xForm( rMatrix ); + break; + case HSBSliderTopPressed: + ptr->pixmaps[ HSBSliderTopPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_top-milk" : "sbslider_top", sbSliderPressedColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderTopPressed ] = ptr->pixmaps[ HSBSliderTopPressed ] ->xForm( mMatrix ); + *ptr->pixmaps[ HSBSliderTopPressed ] = ptr->pixmaps[ HSBSliderTopPressed ] ->xForm( rMatrix ); + break; + case HSBSliderBtmPressed: + ptr->pixmaps[ HSBSliderBtmPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_btm-milk" : "sbslider_btm", sbSliderPressedColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderBtmPressed ] = ptr->pixmaps[ HSBSliderBtmPressed ] ->xForm( mMatrix ); + *ptr->pixmaps[ HSBSliderBtmPressed ] = ptr->pixmaps[ HSBSliderBtmPressed ] ->xForm( rMatrix ); + break; + case HSBSliderMidPressed: + ptr->pixmaps[ HSBSliderMidPressed ] = processEmbedded( (optionHandler->style() == Milk) ? "sbslider_mid-milk" : "sbslider_mid", sbSliderPressedColor, false, &sbGrooveColor ); + if (optionHandler->style() == Milk) + *ptr->pixmaps[ HSBSliderMidPressed ] = ptr->pixmaps[ HSBSliderMidPressed ] ->xForm( lMatrix ); + else + *ptr->pixmaps[ HSBSliderMidPressed ] = ptr->pixmaps[ HSBSliderMidPressed ] ->xForm( rMatrix ); + break; + case VSBSliderTopBg: + ptr->pixmaps[ VSBSliderTopBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_top-milk" : "sbgroove_top", sbGrooveColor, true, &sbGrooveColor ); + break; + case VSBSliderBtmBg: + ptr->pixmaps[ VSBSliderBtmBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_btm-milk" : "sbgroove_btm", sbGrooveColor, true, &sbGrooveColor ); + break; + case VSBSliderMidBg: + ptr->pixmaps[ VSBSliderMidBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_mid-milk" : "sbgroove_mid", sbGrooveColor, false, &sbGrooveColor ); + break; + case VSBSliderMidBgI: + ptr->pixmaps[ VSBSliderMidBgI ] = processEmbedded( (optionHandler->style() == Milk) ? "sb_subadd-milk" : "sb_subadd", sbGrooveColor, false, &sbGrooveColor ); + break; + case HSBSliderTopBg: + ptr->pixmaps[ HSBSliderTopBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_top-milk" : "sbgroove_top", sbGrooveColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderTopBg ] = ptr->pixmaps[ HSBSliderTopBg ] ->xForm( rMatrix ); + break; + case HSBSliderBtmBg: + ptr->pixmaps[ HSBSliderBtmBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_btm-milk" : "sbgroove_btm", sbGrooveColor, true, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderBtmBg ] = ptr->pixmaps[ HSBSliderBtmBg ] ->xForm( rMatrix ); + break; + case HSBSliderMidBg: + ptr->pixmaps[ HSBSliderMidBg ] = processEmbedded( (optionHandler->style() == Milk) ? "sbgroove_mid-milk" : "sbgroove_mid", sbGrooveColor, false, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderMidBg ] = ptr->pixmaps[ HSBSliderMidBg ] ->xForm( rMatrix ); + break; + case HSBSliderMidBgI: + ptr->pixmaps[ HSBSliderMidBgI ] = processEmbedded( (optionHandler->style() == Milk) ? "sb_subadd-milk" : "sb_subadd", sbGrooveColor, false, &sbGrooveColor ); + *ptr->pixmaps[ HSBSliderMidBgI ] = ptr->pixmaps[ HSBSliderMidBgI ] ->xForm( rMatrix ); + break; + + case Progress: + ptr->pixmaps[ Progress ] = processEmbedded( "progress", btnColor ); + break; + case progress2: + ptr->pixmaps[ progress2 ] = processEmbedded( "progress2", btnColor ); + break; + + case TitleBar: + { + if (optionHandler->style() == Jaguar) + { + ptr->pixmaps[ TitleBar ] = new QPixmap(32,22); + ptr->pixmaps[ TitleBar ]->fill( optionHandler->titleColor(0) ); + QPainter p; + p.begin( ptr->pixmaps[ TitleBar ] ); + p.setPen( QColor( + (optionHandler->titleColor(0).red()+optionHandler->titleColor(1).red())/2, + (optionHandler->titleColor(0).green()+optionHandler->titleColor(1).green())/2, + (optionHandler->titleColor(0).blue()+optionHandler->titleColor(1).blue())/2 )); + for ( int i = 1; i < 22; i += 4 ) + { + p.drawLine( 0, i, 31, i ); + p.drawLine( 0, i+2, 31, i+2 ); + } + p.setPen( optionHandler->titleColor(1)); + for ( int i = 2; i < 22; i += 4 ) + p.drawLine( 0, i, 31, i ); + p.end(); + } + else + ptr->pixmaps[ TitleBar ] = &KPixmapEffect::gradient (*((KPixmap*)(new QPixmap(32,22))), optionHandler->titleColor(0), optionHandler->titleColor(1), KPixmapEffect::VerticalGradient, 22); + break; + } + default: + break; + } + return ( pixmaps[ item ] ); +} + + +#include "baghira.moc" diff --git a/style/baghira.h b/style/baghira.h new file mode 100644 index 0000000..1336ac2 --- /dev/null +++ b/style/baghira.h @@ -0,0 +1,627 @@ +#ifndef __LIQUID_STYLE_H +#define __LIQUID_STYLE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #define BITMAP_ITEMS 75 // Don't worry, they're demand loaded ;-) +#define LIQUID_MENU_CHANGE 667 +#define MOSFET_BUTTON_CHANGE 661 + +class QColor; +class QHeader; +class QImage; +class QMenuBar; +class QPalette; +class QPoint; +class QPushButton; +class QRect; +class QScrollBar; +class QSize; +class QString; +class QTabBar; +class LiquidStyle; + +enum BitmapData{RadioOn = 0, RadioOff, RadioOnHover, RadioOffHover, RadioOnPressed, RadioOffPressed, + VSBSliderTop, VSBSliderMid, VSBSliderBtm, + VSBSliderTopActive, VSBSliderMidActive, VSBSliderBtmActive, + VSBSliderTopPressed, VSBSliderMidPressed, VSBSliderBtmPressed, + VSBSliderTopBg, VSBSliderMidBg, VSBSliderMidBgI, VSBSliderBtmBg, + HSBSliderTop, HSBSliderMid, HSBSliderBtm, + HSBSliderTopActive, HSBSliderMidActive, HSBSliderBtmActive, + HSBSliderTopPressed, HSBSliderMidPressed, HSBSliderBtmPressed, + HSBSliderTopBg, HSBSliderMidBg, HSBSliderMidBgI, HSBSliderBtmBg, + Tab, TabDown, TabFocus, belowTab, belowTabDown, + ButtonShadow, CB, CBDown, CBTri, CBHover, CBDownHover, CBTriHover, CBPressed, CBDownPressed, CBTriPressed, + HSlider, VSlider, VSliderAbove, HSliderInactive, VSliderInactive, VSliderAboveInactive, + Progress, rectbutton, combo, comboShadow, progress2, TitleBar, BITMAP_ITEMS}; + +enum CustomColor{CustomCBOn = 0, CustomCBOff, CustomRadioOn, CustomRadioOff, + CustomTabOn, CustomTabOff, CustomSBSlider, CustomSBSliderHover, CustomSBSliderPressed, CustomSBGroove}; + +enum PulseType{PushButton, ComboBox, AppletHandle, Splitter, ToolButton}; + +enum MenuBackground{Standard=0, Plain, Stipples, Gradient}; + +enum InactiveButtonColor{Original=0, Background, Active, Custom}; + +enum myExpanderStyle{Apple=0, MS}; + +enum progressStyle{mac=0, liquid, baghira}; + +enum DotlineStyle{Line=0, Dots}; + +enum Tile{TileTopLeft = 0, TileTop, TileTopRight, + TileLeft, TileMiddle, TileRight, TileBtmLeft, TileBtm, TileBtmRight}; + +enum myPosition{left = 0, center, right, full}; + +enum tabStyle {TrueTab = 0, Clever, Chooser}; + +enum Style {Jaguar = 0, Panther, Brushed, Tiger, Milk, NUMSTYLES }; + +class ButtonTile + { + public: + ButtonTile() + { + for ( int i = 0;i < 9;++i ) + pixmaps[ i ] = 0; + } + ~ButtonTile() + { + for ( int i = 0;i < 9;++i ) + if ( pixmaps[ i ] ) delete pixmaps[ i ]; + } + QPixmap* pixmap( Tile pos ) + { + return ( pixmaps[ ( int ) pos ] ); + } + void setPixmap( Tile pos, QPixmap *pix ) + { + pixmaps[ ( int ) pos ] = pix; + } + protected: + QPixmap *pixmaps[ 9 ]; + }; + + +class OptionHandler : public QObject +{ + Q_OBJECT +public: + OptionHandler( QObject *parent ); + void reloadSettings(); + inline static bool useShadowText() + { + return ( shadowText ); + } + const QColor& textColor(); + const QColor& bgColor(); + const QColor& buttonColor(); + static int custCols[8]; + + inline void reset() + { + menusProcessed = false; + } + + inline static bool glossyMenus() + { + return glossyMenus_; + } + + inline static bool drawMenuStripe() + { + return (drawMenuStripe_); + } + + inline static QColor menuStripeColor() + { + return menuStripeColor_; + } + + inline static QColor textColorHigh() + { + return fgColorHigh; + } + + inline static QColor menuColorHigh() + { + return colorHigh; + } + + inline static bool bevelHighlights() + { + return (bevelHighlights_); + } + inline static bool useBgStipple() + { + return ( bgStipple ); + } + inline static Style style() + { + return (style_); + } + inline static int stippleContrast() + { + return ( contrast ); + } + inline static bool useReverseBtnColor() + { + return ( reverseBtnColor ); + } + inline static bool useToolButtonFrame() + { + return ( tbFrame ); + } + + inline static bool useCustomColors() + { + return ( customWidgetColor ); + } + inline static const QColor& customColor( int idx ) + { + return ( customColors[ idx ] ); + } + + inline static bool DrawDotlines() + { + return ( drawDotlines ); + } + inline static bool squeezeSbSlider() + { + return ( squeezesbslider ); + } + inline static bool shadowSbSlider() + { + return (shadowsbslider); + } + inline static bool drawGroupBoxShadow() + { + return ( groupboxshadow ); + } + inline static int ShadowDarkness() + { + return ( shadowDarkness ); + } + inline static int InactiveButtonColorType() + { + return ( inactiveButtonColor ); + } + inline static int MenuBackground() + { + return (menuBackground); + } + inline static int MenuOpacity() + { + return (menuOpacity); + } + inline static bool UseCustomMenuColor() + { + return (useCustomMenuColor); + } + inline static int DotlineStyle() + { + return (dotlineStyle); + } + inline static bool MenuColorButton() + { + return (menuColorButton); + } + inline static int ExpanderStyle() + { + return (expanderStyle); + } + inline static bool UseCustomExpanderColor() + { + return (useCustomExpanderColor); + } + inline static QColor CustomExpanderColor() + { + return (expanderColor); + } + inline static QColor DotlineColor() + { + return (dotlineColor); + } + inline QColor InactiveButtonColor() + { + switch (inactiveButtonColor) + { + case 0 : return (QColor(232,232,232)); + case 1 : return (bgColor()); + case 2 : return (buttonColor()); + case 3 : return (customInactiveButtonColor); + } + } + inline static bool CenterTabs() + { + return centerTabs; + } + + inline static bool SmoothListViewHeaders() + { + return smoothListViewHeaders; + } + + inline static bool SmootherLVH() + { + return smootherLVH; + } + + inline static bool IcyButtons() + { + return icyButtons; + } + + inline static Style buttonStyle() + { + return _buttonStyle; + } + + inline static int ProgressBar() + { + return progressBar; + } + + inline static bool RemoveKickerBevel() + { + return removeKickerBevel; + } + + inline static Style toolbuttonStyle() + { + return _toolbuttonStyle; + } + + inline void setGroupShadowButton() + { + groupShadowButton = true; + } + inline void setNotGroupShadowButton() + { + groupShadowButton = false; + } + inline bool GroupShadowButton() + { + return groupShadowButton; + } + + inline void setScrollerActive() + { + scrollerActive = true; + } + + inline void setScrollerInactive() + { + scrollerActive = false; + } + + inline bool ScrollerActive() + { + return scrollerActive; + } + + inline static QColor Color() + { + return color; + } + + inline static QColor Color2() + { + return color2; + } + + inline static bool DrawProgressLabel() + { + return drawProgressLabel; + } + + inline static tabStyle TabStyle() + { + return tabStyle_; + } + + inline static QColor & BrushTint() + { + return brushTint; + } + + inline static bool TintBrush() + { + return tintBrush; + } + + inline static bool AnimateSlider() + { + return animateSlider; + } + inline static bool AnimateProgress() + { + return animateProgress; + } + inline static QColor CustomButtonColor() + { + return customButtonColor; + } + + inline static bool AnimateButton() + { + return animateButton; + } + + inline static QColor aDecoColor1() + { + return aDecoColor1_; + } + inline static QColor aDecoColor2() + { + return aDecoColor2_; + } + inline static QColor titleColor( int i ) + { + return titleColor_[i]; + } + inline static QColor titleButtonColor( int i ) + { + return titleButtonColor_[i]; + } + + QMenuBar *currentMenu; + QPixmap *indicatedMenuItemPix; + QRect *indicatedMenuItemRect; + QPixmap *lastIndicatedMenuItemPix; + QRect *lastIndicatedMenuItemRect; + bool mouseOverMenu; + WId lastIndicatedMenuItemID; + static unsigned long wmDesign; + + +public slots: + inline void warningSlot() + { + qWarning("widget destroyed"); + } + +protected: + static QColor titleColor_[2]; + static QColor titleButtonColor_[3]; + + // menu + static int menuBackground; + static int menuOpacity; + static bool menuColorButton; + static bool animateButton; + static bool shadowText; + static bool drawMenuStripe_; + static QColor menuStripeColor_; + static bool glossyMenus_; + //color + static QColor customButtonColor; + //widgets + static bool customWidgetColor; + static QColor customColors[ 10 ]; + //menu + static bool useCustomMenuColor; + static QColor color, color2, colorHigh, fgColor, fgColorHigh; + //incativeButton + static int inactiveButtonColor; + static QColor customInactiveButtonColor; + + //Design + //stipples + static bool bgStipple, bevelHighlights_; + static Style style_; + static int contrast; + //shadows + static bool groupboxshadow; + static int shadowDarkness; + //istviews; + static bool drawDotlines, useCustomExpanderColor; + static int expanderStyle; + static QColor expanderColor, dotlineColor; + static int dotlineStyle; + //slider + static bool squeezesbslider; + static bool shadowsbslider; + //toolbar + static bool reverseBtnColor, tbFrame; + //tweaks + static bool centerTabs; + static bool smoothListViewHeaders; + static bool smootherLVH; + static bool icyButtons; + static Style _buttonStyle; + bool menusProcessed; + bool scrollerActive; + int menuLevelCounter; + bool groupShadowButton; + static int progressBar; + static bool removeKickerBevel; + static Style _toolbuttonStyle; + static bool drawProgressLabel; + static tabStyle tabStyle_; + + QString colorStr, fgColorStr/*, panelColorStr*/; + static QColor brushTint; + static QColor aDecoColor1_; + static QColor aDecoColor2_; + static bool tintBrush; + static bool animateSlider; + static bool animateProgress; +}; + +class EventKiller : public QObject +{ + Q_OBJECT +public: + bool eventFilter( QObject *, QEvent *) + { + return TRUE; + } +}; + +class BMShower : public QObject +{ + Q_OBJECT +public: + BMShower(QObject *parent); + bool eventFilter( QObject *object, QEvent *event ); +}; + +class ButtonFadeInfo +{ +public: + ButtonFadeInfo() + { + timerId=0; index=0; fadeIn=TRUE; + } +public: + int timerId; + int index; + bool fadeIn; +}; + +class LiquidStyle : public KStyle +{ + Q_OBJECT +public: + friend class OptionHandler; + LiquidStyle(); + virtual ~LiquidStyle(); + bool isPlain() const; + + virtual void polish( QWidget *w ); +// virtual void polishPopupMenu( QPopupMenu *w ); + virtual void unPolish( QWidget *w ); + virtual void polish( QPalette &p ); + virtual void unPolish( QApplication *a ); + int styleHint(StyleHint sh, const QWidget * w, const QStyleOption & opt, QStyleHintReturn * shr) const; + void drawKStylePrimitive( KStylePrimitive kpe, QPainter* p, const QWidget* widget, const QRect &r, const QColorGroup &cg, SFlags flags = Style_Default, const QStyleOption& = QStyleOption::Default ) const; + void drawPrimitive( PrimitiveElement pe, QPainter* p, const QRect &r, const QColorGroup &cg, SFlags flags = Style_Default, const QStyleOption& = QStyleOption::Default ) const; + void drawControl( ControlElement element, QPainter *p, const QWidget *widget, const QRect &r, const QColorGroup &cg, SFlags flags = Style_Default, const QStyleOption& = QStyleOption::Default ) const; +// void drawControlMask( ControlElement element, QPainter *p, const QWidget *widget, const QRect &r, const QStyleOption& = QStyleOption::Default ) const; + void drawComplexControl( ComplexControl control, QPainter *p, const QWidget *widget, const QRect &r, const QColorGroup &cg, SFlags flags = Style_Default, SCFlags controls = SC_All, SCFlags active = SC_None, const QStyleOption& = QStyleOption::Default ) const; +// void drawComplexControlMask( ComplexControl control, QPainter *p, const QWidget *widget, const QRect &r, const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric m, const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, const QWidget *widget, const QSize &contentSize, const QStyleOption& opt ) const; + QRect subRect( SubRect r, const QWidget *widget ) const; + QRect querySubControlMetrics( ComplexControl control, const QWidget *widget, SubControl subcontrol, const QStyleOption &opt = QStyleOption::Default ) const; + // Fix Qt3's wacky image positions + QPixmap stylePixmap( StylePixmap stylepixmap, const QWidget *widget = 0, const QStyleOption& = QStyleOption::Default ) const; + bool eventFilter( QObject *object, QEvent *event ); + +private slots: + void updateProgressPos(); + void updateSliderPos(); + void progressBarDestroyed(QObject*); + void fakeMouse(); + +protected: + void clearImage( QImage &img ) const; + ButtonTile* createButtonTile( const QColor &c, const QColor &bgColor, QImage *buttonImage, QImage *shadowImage, QImage *glowImage, QIntDict *buttonDict, QIntDict*shadowDict, QIntDict*glowDict, int w, int h, int xOff, int yOff, int centerW, int centerH, int shadowH, int glowWH, bool sunken) const; + ButtonTile* createRoundFrameTile(QImage &img, const QColor &color, const QColor *bg, const QColor &baseColor ) const; + QPixmap* createSliderEnd( const QColor &c, const QColor &bgColor, bool top/*, bool vertical*/ ) const; + ButtonTile* separateTiles( QPixmap *pix, int xO, int yO, int w, int h, int sh, bool sunken) const; + + QPixmap* getPixmap( BitmapData item ) const; + QPixmap* adjustHSV( QImage &img, const QColor &c, const QColor *bg = NULL ) const; + QImage* adjustHSVImage( QImage &img, const QColor &c, const QColor *bg = NULL ) const; + void adjustHSV( QPixmap &pix, const QColor &c ) const; + QImage* tintBrush( const QImage &img, const QColor &c ) const; + QPixmap* processEmbedded( const char *label, const QColor &c, bool blend = false, const QColor *bg = NULL ) const; + void drawRoundButton( QPainter *p, const QColorGroup &cg, const QColor &c, /*const QColor &bg,*/ int x, int y, int w, int h, bool pushedDown = false, bool hover = false, int bgX = -1, int bgY = -1) const; + void drawRectangularButton( QPainter *p, const QColorGroup &cg, const QColor &c, int x, int y, int w, int h, bool sunken = false, bool hover = false, bool isCombo = false, int position = full, bool isHtml = false) const; + void drawCombo( QPainter *painter, const QColorGroup &cg, const QColor &c, int x, int y, int w, int h, bool sunken, bool hover, bool isCombo, int position = full, bool isHTML = false ) const; + void drawEditFrame( QPainter *p, const QRect &r, const QColorGroup &cg, bool isHTML = false, bool focused = false, bool inverse = false/*, bool round = false*/ ) const; + void drawRoundFrame( QPainter *p, const QRect &r, const QColorGroup &cg, bool focused, QPoint offset ) const; + void drawHTMLCBBorder( const QPixmap &pix, const QColor &c ) const; + bool isHTMLWidget( const QWidget *w ) const; + + +private: + LiquidStyle( const LiquidStyle & ); + LiquidStyle& operator=( const LiquidStyle & ); + int getBrightness(unsigned int rgb) const; + QImage fetchImage( const char *name ); + QColor mapFadeColor(QColor &color, int index) const; + void fadeIn(QPushButton *button); + void fadeOut(QPushButton *button); + QColor brushedMetalColor(QColor &c) const; + QColor originalBgColor; + + + QBitmap *sbLeft, *sbRight, *sbUp, *sbDown, *checkmark; + QImage *btnBorderImg, *btnShadowImg, *slider_top, *slider_btm, *slider_top_shd, *slider_btm_shd, *rectbutton, *combo, *comboShadow, *buttonGlow, *roundFrame; + QPixmap *btnBlendPix, *menuPix, *groupShadow ; + QPixmap plainBrush, gradBrush; + QBrush pagerBrush, pagerHoverBrush; + + QPixmap *pixmaps[ BITMAP_ITEMS ]; + QPixmap sbBuffer; + QScrollBar *currentScrollBar; + QWMatrix lMatrix; + QWMatrix rMatrix; + QWMatrix iMatrix; + QWMatrix mMatrix; + QWMatrix m2Matrix; + + bool isKicker, isOOO, isHTMLButton, initialPaletteLoaded, inExitPolish; + + QHeader *currentHeader; + QTabBar *currentTabBar; + int headerHoverID; + int headerSortID; + QPoint btnOffset; + QPoint cursorPos_; + QWidget *currentTaskContainer; + KPixmap activeToolbarPix; + bool isTaskContainer, taskContainerHover; + + QPalette polishedPalette, tooltipPalette; + unsigned int qtrcModificationTime; + + int progAnimShift; + int prog2AnimShift; + int sliderAnimShift; + int hoveredTabIndex; + bool mouseButtonPressed_; + + OptionHandler *optionHandler; + + QIntDictbtnDict; + QIntDictbfi; + QIntDictfadeColorMap; + QIntDictbtnShadowedDict; + QIntDictbuttonGlowDict; + QIntDictcomboDict; + QIntDictcomboShadowedDict; + QIntDicttabDict; + QIntDictinverseTabDict; + QIntDictrectBtnDict; + QIntDictprogress2Dict; + QMap progAnimWidgets; + + QPixmap *tmpBtnPix; + ButtonTile *inactiveRoundFrame; + ButtonTile *activeRoundFrame; + + QWidget *highlightWidget; + QScrollBar *activeScroller; + EventKiller *eventKiller; + BMShower *bmShower; + static QPixmap popupBack; + QWidget *paintWidget; +}; + +#endif diff --git a/style/baghira.themerc b/style/baghira.themerc new file mode 100644 index 0000000..d6bfd1f --- /dev/null +++ b/style/baghira.themerc @@ -0,0 +1,6 @@ +[Misc] +Name=Baghira +Comment=The Big Black Cat +ConfigPage=kstyle_baghira_config +[KDE] +WidgetStyle=Baghira diff --git a/style/bitmaps.h b/style/bitmaps.h new file mode 100644 index 0000000..a4fafc4 --- /dev/null +++ b/style/bitmaps.h @@ -0,0 +1,21 @@ +#ifndef __BITMAPS_H +#define __BITMAPS_H + +static unsigned char sbarrow_down_bits[] = { +// 0x00, 0x00, 0x7f, 0x7f, 0x3e, 0x1c, 0x08}; + 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08 }; +static unsigned char sbarrow_left_bits[] = { +// 0x18, 0x1c, 0x1e, 0x1f, 0x1e, 0x1c, 0x18}; + 0x20, 0x38, 0x3e, 0x3f, 0x3e, 0x38, 0x20 }; +static unsigned char sbarrow_right_bits[] = { +// 0x0c, 0x1c, 0x3c, 0x7c, 0x3c, 0x1c, 0x0c}; + 0x01, 0x07, 0x1f, 0x3f, 0x1f, 0x07, 0x01 }; +static unsigned char sbarrow_up_bits[] = { +// 0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x00, 0x00}; + 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f }; +static unsigned char checkmark_bits[] = { + 0x40, 0x60, 0x71, 0x3b, 0x1f, 0x0e, 0x04 }; + +#endif + + diff --git a/style/configure.in.in b/style/configure.in.in new file mode 100644 index 0000000..b0f4a88 --- /dev/null +++ b/style/configure.in.in @@ -0,0 +1,5 @@ +compile_kompmgr=yes +KDE_CHECK_HEADERS(X11/extensions/Xdamage.h,,compile_kompmgr=no,[#include ]) +KDE_CHECK_HEADERS(X11/extensions/Xcomposite.h,,compile_kompmgr=no,[#include ]) +KDE_CHECK_HEADERS(X11/extensions/Xrender.h,,compile_kompmgr=no,[#include ]) +AM_CONDITIONAL(include_kompmgr, test "$compile_kompmgr" = "yes" ) diff --git a/style/eventfilter.cpp b/style/eventfilter.cpp new file mode 100644 index 0000000..ada0475 --- /dev/null +++ b/style/eventfilter.cpp @@ -0,0 +1,990 @@ +#include +#include +#include +#include +#include + +bool LiquidStyle::eventFilter( QObject *obj, QEvent *ev ) +{ +// qWarning("%s, %s <- %s, %s: %d", obj->className(), obj->name(), obj->parent() ? obj->parent()->className() : "none", obj->parent()?obj->parent()->name():"none",ev->type()); + switch (ev->type()) + { + case QEvent::None: + case QEvent::Timer: + { + // first check if this is one of our fading pushbuttons - return elsewise + if (!(optionHandler->AnimateButton() && ::qt_cast(obj))) + return false; + ButtonFadeInfo *bfi_ = bfi[((QPushButton*)obj)->winId()]; + if (!bfi_ || ((QTimerEvent*)ev)->timerId() != bfi_->timerId) + return false; + // ok, this is one of our fading buttons asking for repaint + ((QPushButton*)obj)->repaint(false); + int index = bfi_->fadeIn?bfi_->index + 1:bfi_->index - 1; + // handle border cases + if (index < 0) // fade-out run has finished, either stop fading stuff, or start fade-in + { + bfi_->fadeIn=true; + if (((QPushButton*)obj)->isDefault()) + { + bfi_->index=0; + } + else + { + obj->killTimer(bfi_->timerId); + // qWarning("%u: stopped (%d)", ((QPushButton*)obj)->winId(), bfi_->timerId); + bfi_->timerId=0; + ((QPushButton*)obj)->repaint(false); // must be to clean out button + } + } + else if (index > 9) // fade-in run has finished, either stop fading stuff, or start fade-out + { + if (((QPushButton*)obj)->isDefault()) + { + bfi_->fadeIn=false; + bfi_->index=9; + } + else + { + obj->killTimer(bfi_->timerId); + // qWarning("%u: stopped (%d)", ((QPushButton*)obj)->winId(), bfi_->timerId); + bfi_->timerId=0; + } + } + else + bfi_->index = index; + } + case QEvent::MouseMove: + if (::qt_cast(obj)) + { + QTabBar *tb = (QTabBar*)obj; + QRect tmpRect; + bool done = false; + QMouseEvent *me = ( QMouseEvent*)ev; + int oldTab = hoveredTabIndex; + if (hoveredTabIndex == -1) + { + for (int i = 0; i < tb->count(); i++) + { + if (tb->tabAt(i)) + { + tmpRect = tb->tabAt(i)->rect(); + if ( tmpRect.x() < me->x() && me->x() < tmpRect.right()) + { + hoveredTabIndex = i; + break; + } + } + } + } + else + { + if ((oldTab > 0) && tb->tabAt(oldTab-1)) + { + tmpRect = tb->tabAt(oldTab-1)->rect(); + if ((tmpRect.x() < me->x()) && (me->x() < tmpRect.right())) + { + hoveredTabIndex = oldTab-1; + done = true; + } + } + if (!done && (oldTab < tb->count()-1) && tb->tabAt(oldTab+1)) + { + tmpRect = tb->tabAt(oldTab+1)->rect(); + if ((tmpRect.x() < me->x()) && (me->x() < tmpRect.right())) + { + hoveredTabIndex = oldTab+1; + } + } + } + if ( oldTab != hoveredTabIndex ) + { + // reset old tab + if ( oldTab != -1 ) + if (tb->tabAt(oldTab)) tb->repaint( tb->tabAt(oldTab)->rect(), false ); + if ( hoveredTabIndex != -1 ) + tb->repaint( tmpRect, false ); + } + return false; + } + else if ( ::qt_cast(obj) ) + { + QHeader *hw = (QHeader*)obj; + QMouseEvent * me = ( QMouseEvent * ) ev; + int oldHeader = headerHoverID; + headerHoverID = hw->orientation() == Qt::Horizontal ? hw->sectionAt( me->x() + hw->offset() ) : hw->sectionAt( me->y() + hw->offset() ); + if ( oldHeader != headerHoverID ) + { + // reset old header + if ( oldHeader != -1 ) + hw->repaint(hw->sectionRect ( oldHeader ), false); +// hw->repaint( hw->sectionPos( oldHeader )-hw->offset(), 0, hw->sectionSize( oldHeader ), hw->height(), false ); + if ( headerHoverID != -1 ) + hw->repaint(hw->sectionRect ( headerHoverID ), false); +// hw->repaint( hw->sectionPos( headerHoverID )-hw->offset(), 0, hw->sectionSize( headerHoverID ), hw->height(), false ); + } + return false; + } + return false; + case QEvent::Paint: + if ( ::qt_cast(obj) ) + { + QToolButton * btn = ( QToolButton * ) obj; + if (!obj->inherits( "TaskContainer" )) + { + if (btn->backgroundOrigin() != QWidget::WindowOrigin) + btn->setBackgroundOrigin( QWidget::WindowOrigin ); + } + else + { + isTaskContainer = true; + if ( currentTaskContainer == btn ) + taskContainerHover = true; + else + taskContainerHover = false; + } + return false; + } + else if (::qt_cast(obj)) + { + QWidget *w = (QWidget *)obj; + if(w->backgroundMode() != Qt::PaletteBackground) + { + w->setBackgroundMode(PaletteBackground); + w->setBackgroundOrigin(QWidget::WindowOrigin); + } + return false; + } + else if ( ::qt_cast(obj) ) + { + QHeader *hw = (QHeader*)obj; + if (hw->parentWidget() && ::qt_cast(hw->parentWidget())) + headerSortID = ((QListView*)hw->parentWidget())->sortColumn(); + return false; + } + else if ( obj->inherits( "QDockWindow" ) ) + { + if (KStyle::eventFilter( obj, ev )) + return true; + QWidget * w = ( QWidget * ) obj; + if ( w->backgroundMode() != Qt::PaletteBackground ) + { + w->setBackgroundMode( Qt::PaletteBackground ); + w->setBackgroundOrigin( QWidget::WindowOrigin ); + } + return false; + } + else if ( obj->inherits( "QRadioButton" ) || obj->inherits( "QCheckBox" ) ) + { + QButton * btn = ( QButton * ) obj; + bool isStatusChild = btn->parent() && ( btn->parent() ->inherits( "QStatusBar" ) || btn->parent() ->inherits( "KonqFrameStatusBar" ) ); + bool isRadio = obj->inherits( "QRadioButton" ); + btn->erase(); + QPainter p; + p.begin( btn ); + QFontMetrics fm = btn->fontMetrics(); + QSize lsz = fm.size( ShowPrefix, btn->text() ); + QSize sz = isRadio ? + QSize( pixelMetric( PM_ExclusiveIndicatorWidth ), pixelMetric( PM_ExclusiveIndicatorHeight ) ) : + QSize( pixelMetric( PM_IndicatorWidth ), pixelMetric( PM_IndicatorHeight ) ); + int x = 0; + int y = isStatusChild ? 0 : ( btn->height() - lsz.height() + fm.height() - sz.height() ) / 2; + SFlags flags = Style_Default; + if ( btn->isEnabled() ) + flags |= Style_Enabled; + if ( btn->hasFocus() ) + flags |= Style_HasFocus; + if ( btn->isDown() ) + flags |= Style_Down; + if ( highlightWidget == btn ) + flags |= Style_MouseOver; + if ( btn->state() == QButton::On ) + flags |= Style_On; + else if ( btn->state() == QButton::Off ) + flags |= Style_Off; + if ( isRadio ) + drawControl( CE_RadioButton, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + else + drawControl( CE_CheckBox, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + x = sz.width() + 6; + y = 0; + if ( btn->hasFocus() ) + { + QColor tmp( btn->colorGroup().background().dark( 130 ) ); + drawItem( &p, QRect( sz.width() + 6 + 2, 1, btn->width() - ( sz.width() + 6 + 1 ), btn->height() ), AlignLeft | AlignVCenter | ShowPrefix, btn->colorGroup(), btn->isEnabled(), btn->pixmap(), btn->text(), -1, &tmp ); + drawItem( &p, QRect( sz.width() + 6 + 3, 2, btn->width() - ( sz.width() + 6 + 1 ), btn->height() ), AlignLeft | AlignVCenter | ShowPrefix, btn->colorGroup(), btn->isEnabled(), btn->pixmap(), btn->text(), -1, &tmp ); + } + drawItem( &p, QRect( sz.width() + 6 + 1, 0, btn->width() - ( sz.width() + 6 + 1 ), btn->height() ), AlignLeft | AlignVCenter | ShowPrefix, btn->colorGroup(), btn->isEnabled(), btn->pixmap(), btn->text() ); + p.end(); + return true; + } + else if (obj->inherits("KColorGrid") && !(((QWidget*)obj)->width() && ((QWidget*)obj)->height())) + return true; + return false; + case QEvent::KeyPress: + case QEvent::KeyRelease: + return false; + case QEvent::Wheel: + if ( ::qt_cast(obj) ) + { + optionHandler->setScrollerActive(); + return false; + } + return false; + case QEvent::Enter: + if ( ::qt_cast(obj) ) + { + bool isTask = obj->inherits( "TaskContainer" ); + QToolButton * btn = ( QToolButton * ) obj; + if (isTask) + { + currentTaskContainer = btn; + btn->repaint( false ); + return false; + } + else if ( btn->isEnabled() ) + { + highlightWidget = btn; + btn->repaint( false ); + return false; + } + } + else if ( ::qt_cast(obj) || ::qt_cast(obj) || obj->inherits( "QSplitterHandle" ) || obj->inherits( "AppletHandleDrag" ) ) + { + QWidget * btn = ( QWidget * ) obj; + if ( btn->isEnabled() ) + { + highlightWidget = btn; + btn->repaint( false ); + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + fadeIn((QPushButton*)obj); + } + return false; + } + else if (::qt_cast(obj)) + { + QObjectList *handlerList = obj->queryList( "QDockWindowHandle" ); + for (uint i= 0; i < handlerList->count(); i++) + ((QWidget*)(handlerList->at(i)))->repaint(false); + return false; + } + if ( ::qt_cast(obj) ) + { + QScrollBar * sb = ( QScrollBar * ) obj; + if ( !sb->draggingSlider() ) + { + if ( sb->isEnabled() ) + { + activeScroller = sb; + highlightWidget = sb; + sb->repaint( false ); + } + } + return false; + } + else if ( ::qt_cast(obj) ) + { + QScrollView *sv = ( QScrollView * ) obj; + if (sv->vScrollBarMode() == QScrollView::AlwaysOff && sv->hScrollBarMode() == QScrollView::AlwaysOff) + return false; + optionHandler->setScrollerActive(); + if (!(highlightWidget == sv->verticalScrollBar())) + sv->verticalScrollBar()->repaint(false); + if (!(highlightWidget == sv->horizontalScrollBar())) + sv->horizontalScrollBar()->repaint(false); + return false; + } + else if ( ::qt_cast(obj) ) + { + currentHeader = (QHeader*)obj; + headerHoverID = -1; + return false; + } + else if (::qt_cast(obj)) + { + currentTabBar = (QTabBar*)obj; + hoveredTabIndex = -1; + return false; + } + else if ( obj->inherits( "KateView" ) || obj->inherits( "TEWidget") || obj->inherits("CHexViewWidget")) + { + QObjectList *scrollerList = obj->queryList( "QScrollBar" ); + optionHandler->setScrollerActive(); + for (uint i= 0; i < scrollerList->count(); i++) + ((QWidget*)(scrollerList->at(i)))->repaint(false); + return false; + } + else if (obj->inherits("KDockWidgetAbstractHeaderDrag")) + { + ((QWidget *)obj)->repaint(); + return false; + } + else if (obj->inherits( "KAnimWidget" )) + { + return true; + } + else if ( obj->inherits( "QLineEdit" ) && obj->parent() && ::qt_cast(obj->parent())) + { + QWidget * btn = ( QWidget * ) obj->parent(); + if ( btn->isEnabled() ) + { + highlightWidget = btn; + btn->repaint( false ); + } + return false; + } + else if ( obj->inherits( "QRadioButton" ) || obj->inherits( "QCheckBox" ) ) + { + QButton * btn = ( QButton * ) obj; + if (btn->isEnabled()) + { + bool isStatusChild = btn->parent() && ( btn->parent() ->inherits( "QStatusBar" ) || btn->parent() ->inherits( "KonqFrameStatusBar" ) ); + bool isRadio = obj->inherits( "QRadioButton" ); + highlightWidget = btn; + QFontMetrics fm = btn->fontMetrics(); + QSize lsz = fm.size( ShowPrefix, btn->text() ); + QSize sz = isRadio ? + QSize( pixelMetric( PM_ExclusiveIndicatorWidth ), pixelMetric( PM_ExclusiveIndicatorHeight ) ) : + QSize( pixelMetric( PM_IndicatorWidth ), pixelMetric( PM_IndicatorHeight ) ); + int x = 0; + int y = isStatusChild ? 0 : ( btn->height() - lsz.height() + fm.height() - sz.height() ) / 2; + QPainter p; + p.begin( btn ); + SFlags flags = Style_Default; + if ( btn->isEnabled() ) + flags |= Style_Enabled; + if ( btn->hasFocus() ) + flags |= Style_HasFocus; + if ( btn->isDown() ) + flags |= Style_Down; + if ( highlightWidget == btn ) + flags |= Style_MouseOver; + if ( btn->state() == QButton::On ) + flags |= Style_On; + else if ( btn->state() == QButton::Off ) + flags |= Style_Off; + if ( isRadio ) + drawControl( CE_RadioButton, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + else + drawControl( CE_CheckBox, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + p.end(); + } + return false; + } + return false; + case QEvent::Leave: + if ( ::qt_cast(obj) ) + { + QToolButton * btn = ( QToolButton * ) obj; + if (obj->inherits( "TaskContainer" )) + { + currentTaskContainer = NULL; + btn->repaint( false ); + return false; + } + else if ( btn == highlightWidget ) + { + highlightWidget = NULL; + btn->repaint( false ); + return false; + } + } + else if ( ::qt_cast(obj) || ::qt_cast(obj) || obj->inherits( "QSplitterHandle" ) || obj->inherits( "AppletHandleDrag" ) ) + { + QWidget * btn = ( QWidget * ) obj; + if ( btn == highlightWidget ) + { + highlightWidget = NULL; + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + fadeOut((QPushButton*)obj); + else + btn->repaint( false ); + } + return false; + } + else if (::qt_cast(obj)) + { + QObjectList *handlerList = obj->queryList( "QDockWindowHandle" ); + for (uint i= 0; i < handlerList->count(); i++) + ((QWidget*)(handlerList->at(i)))->repaint(false); + return false; + } + if ( ::qt_cast(obj) ) + { + QScrollBar * sb = ( QScrollBar * ) obj; + if ( sb == highlightWidget && !sb->draggingSlider() ) + { + activeScroller = NULL; + highlightWidget = NULL; + sb->repaint( false ); + } + return false; + } + else if ( ::qt_cast(obj) ) + { + QScrollView *sv = (QScrollView*)obj; +// if (sv->clipRegion().boundingRect().contains(sv->mapFromGlobal(QCursor::pos()))) +// return false; // mouse is still in the scrollview + if (sv->vScrollBarMode() == QScrollView::AlwaysOff && sv->hScrollBarMode() == QScrollView::AlwaysOff) + return false; // no sliders available - don't mess up things + optionHandler->setScrollerInactive(); + if (!(highlightWidget == sv->verticalScrollBar())) + sv->verticalScrollBar()->repaint(false); + if (!(highlightWidget == sv->horizontalScrollBar())) + sv->horizontalScrollBar()->repaint(false); + return false; + } + else if ( ::qt_cast(obj) ) + { + QHeader *hw = (QHeader*)obj; + currentHeader = NULL; + if ( headerHoverID != -1 ) + hw->repaint( hw->sectionPos( headerHoverID )-hw->offset(), 0, hw->sectionSize( headerHoverID ), hw->height(), false ); + headerHoverID = -1; + return false; + } + else if (::qt_cast(obj)) + { + QTabBar *tb = (QTabBar*)obj; + currentTabBar = NULL; + if ( hoveredTabIndex != -1 ) + { + QTab *tmpTab = tb->tabAt(hoveredTabIndex); + if (tmpTab) tb->repaint( tmpTab->rect(), false ); + } + hoveredTabIndex = -1; + return false; + } + else if ( obj->inherits( "KateView" ) || obj->inherits( "TEWidget") || obj->inherits("CHexViewWidget")) + { + QObjectList *scrollerList = obj->queryList( "QScrollBar" ); + optionHandler->setScrollerInactive(); + for (uint i= 0; i < scrollerList->count(); i++) + ((QWidget*)(scrollerList->at(i)))->repaint(false); + return false; + } + else if (obj->inherits("KDockWidgetAbstractHeaderDrag")) + { + ((QWidget *)obj)->repaint(); + return false; + } + else if (obj->inherits( "KAnimWidget" )){ + return true; + } + else if ( obj->inherits( "QLineEdit" ) && obj->parent() && ::qt_cast(obj->parent())) { + QWidget *btn = (QWidget*)obj->parent(); + if ( btn == highlightWidget ) + highlightWidget = NULL; + btn->repaint( false ); + return false; + } + else if ( obj->inherits( "QRadioButton" ) || obj->inherits( "QCheckBox" ) ) + { + QButton * btn = ( QButton * ) obj; + if (btn == highlightWidget) + { + bool isRadio = obj->inherits( "QRadioButton" ); + bool isStatusChild = btn->parent() && ( btn->parent() ->inherits( "QStatusBar" ) || btn->parent() ->inherits( "KonqFrameStatusBar" ) ); + highlightWidget = NULL; + QFontMetrics fm = btn->fontMetrics(); + QSize lsz = fm.size( ShowPrefix, btn->text() ); + QSize sz = isRadio ? + QSize( pixelMetric( PM_ExclusiveIndicatorWidth ), pixelMetric( PM_ExclusiveIndicatorHeight ) ) : + QSize( pixelMetric( PM_IndicatorWidth ), pixelMetric( PM_IndicatorHeight ) ); + int x = 0; + int y = isStatusChild ? 0 : ( btn->height() - lsz.height() + fm.height() - sz.height() ) / 2; + QPainter p; + p.begin( btn ); + SFlags flags = Style_Default; + if ( btn->isEnabled() ) + flags |= Style_Enabled; + if ( btn->hasFocus() ) + flags |= Style_HasFocus; + if ( btn->isDown() ) + flags |= Style_Down; + if ( highlightWidget == btn ) + flags |= Style_MouseOver; + if ( btn->state() == QButton::On ) + flags |= Style_On; + else if ( btn->state() == QButton::Off ) + flags |= Style_Off; + if ( isRadio ) + drawControl( CE_RadioButton, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + else + drawControl( CE_CheckBox, &p, btn, QRect( x, y, sz.width(), sz.height() ), btn->colorGroup(), flags ); + p.end(); + } + return false; + } + return false; + case QEvent::MouseButtonPress: +// qWarning("class: %s, name: %s",obj->className(), obj->name()); + if ( optionHandler->style() > Panther && ::qt_cast(obj)) + { + QMouseEvent *mev = (QMouseEvent *) ev; + if (mev->button() != Qt::LeftButton) + return false; + mouseButtonPressed_ = true; + cursorPos_ = mev->globalPos(); + QTimer::singleShot(50,this,SLOT(fakeMouse())); + return true; // fire this event + } + if ( ::qt_cast(obj) && ((QMouseEvent*)ev)->button() != Qt::RightButton) + { + QScrollBar * sb = ( QScrollBar * ) obj; + activeScroller = NULL; + sb->repaint( false ); + return false; + } + else if (obj->inherits( "KAnimWidget" )) + { + ((QFrame *)obj)->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + return false; + } + return false; + case QEvent::MouseButtonRelease: + if ( mouseButtonPressed_ ) + { + mouseButtonPressed_= false; + } + if ( ::qt_cast(obj) ) + { + QScrollBar * sb = ( QScrollBar * ) obj; + QMouseEvent * me = ( QMouseEvent * ) ev; + if ( sb == highlightWidget) + { + if ( sb->rect().contains( me->pos() ) ) + { + activeScroller = sb; + sb->repaint( false ); + } + else + { + // this assumes, scrollers are right/bottom to scrollview + if ( ((sb->orientation() == Vertical) && (me->pos().x() < 0)) || ((sb->orientation() == Horizontal) && (me->pos().y() < 0)) ) + { + optionHandler->setScrollerActive(); + sb->repaint( false ); + } + } + } + return false; + } + else if ( ::qt_cast(obj) && obj->parent() && ::qt_cast(obj->parent())) + { + QMouseEvent * me = ( QMouseEvent * ) ev; + headerSortID = ((QHeader*)obj)->sectionAt( me->x() + ((QHeader*)obj)->offset()); + return false; + } + else if (obj->inherits( "KAnimWidget" )){ + ((QFrame *)obj)->setFrameShape(QFrame::NoFrame); + return false; + } + return false; + case QEvent::FocusIn: + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + { + fadeIn((QPushButton*)obj); + return false; + } + if ( obj->inherits( "QLineEdit" ) ) + { + QObject *daddy = obj->parent(); + if ( daddy && daddy->inherits( "QSpinWidget" )) + ((QWidget*)daddy)->repaint(false); + else + ((QWidget*)obj)->repaint(false); + return false; + } + return false; + case QEvent::FocusOut: + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + { + fadeOut((QPushButton*)obj); + return false; + } + if ( obj->inherits( "QLineEdit" ) ) + { + if ( obj->parent() && obj->parent()->inherits( "QSpinWidget" )) + ((QWidget*)obj->parent())->repaint(false); + else + ((QWidget*)obj)->repaint(false); + return false; + } + return false; + case QEvent::Move: + if ( !(::qt_cast(obj) || obj->inherits( "KActiveLabel" ))) + return false; + case QEvent::Show: + if (optionHandler->style() == Tiger && ::qt_cast(obj)) + { + QToolBar *tb = (QToolBar*)obj; + QPoint pt = tb->mapTo(tb->topLevelWidget(), QPoint(0,0)); + if (pt.y() == 0) + { + activeToolbarPix = QPixmap(32,tb->height()); + KPixmapEffect::gradient(activeToolbarPix, optionHandler->aDecoColor1(), optionHandler->aDecoColor2(), KPixmapEffect::VerticalGradient, 0); + QPainter painter(&activeToolbarPix); + painter.setPen( optionHandler->aDecoColor2().dark(130) ); + painter.drawLine ( 0, tb->height()-1, 31, tb->height()-1 ); + painter.end(); + tb->installEventFilter(eventKiller); + if (tb->isActiveWindow()) + { + tb->setPaletteBackgroundColor(optionHandler->aDecoColor2()); + tb->setPaletteBackgroundPixmap(activeToolbarPix); + } + else + { + QPalette pal( tb->palette() ); + pal.setColor( QColorGroup::Background, qApp->palette().color(QPalette::Active, QColorGroup::Background) ); + pal.setBrush ( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background) ); + tb->setPalette( pal ); + } + tb->removeEventFilter(eventKiller); + } + else + { + QPalette pal( tb->palette() ); + pal.setBrush ( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background) ); + tb->installEventFilter(eventKiller); + tb->setPalette( pal ); + tb->removeEventFilter(eventKiller); + } + } + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + { + ButtonFadeInfo *bfi_ = bfi[((QPushButton*)obj)->winId()]; + if (bfi_) + return false; + bfi_ = new ButtonFadeInfo(); + bfi.insert(((QPushButton*)obj)->winId(),bfi_); + if (((QPushButton*)obj)->isDefault()) + fadeIn((QPushButton*)obj); + return false; + } + if (::qt_cast(obj)) + { + progAnimWidgets[(QWidget*)obj] = 0; + return false; + } + if ( !qstrcmp(obj->name(), "kde toolbar widget") ) + { + QWidget* lb = static_cast(obj); + if (lb->backgroundMode() == Qt::PaletteButton) + lb->setBackgroundMode(Qt::PaletteBackground); + lb->removeEventFilter(this); + return false; + } + else if ( !obj->inherits( "KActiveLabel" )) + return false; + case QEvent::Resize:{ + QResizeEvent* rev = (QResizeEvent*) ev; + if (::qt_cast(obj) && optionHandler->MenuBackground() == Gradient) + { + KPixmap tmpPix = QPixmap(rev->size().width(),32); + ((QWidget *)obj)->setPaletteBackgroundPixmap(KPixmapEffect::unbalancedGradient(tmpPix, optionHandler->Color(), optionHandler->Color2(), KPixmapEffect::HorizontalGradient, 100, 100)); + } + else if (optionHandler->style() == Tiger && ::qt_cast(obj) && rev->size().height() != rev->oldSize().height()) + { + QToolBar *tb = (QToolBar*)obj; + QPoint pt = tb->mapTo(tb->topLevelWidget(), QPoint(0,0)); + if (pt.y() == 0) + { + activeToolbarPix = QPixmap(32,rev->size().height()); + KPixmapEffect::gradient(activeToolbarPix, optionHandler->aDecoColor1(), optionHandler->aDecoColor2(), KPixmapEffect::VerticalGradient, 0); + QPainter painter(&activeToolbarPix); + painter.setPen( optionHandler->aDecoColor2().dark(130) ); + painter.drawLine ( 0, rev->size().height()-1, 31, rev->size().height()-1 ); + painter.end(); + tb->installEventFilter(eventKiller); + if (tb->isActiveWindow()) + { + tb->setPaletteBackgroundColor(optionHandler->aDecoColor2()); + tb->setPaletteBackgroundPixmap(activeToolbarPix); + } + else + { + QPalette pal( tb->palette() ); + pal.setColor( QColorGroup::Background, qApp->palette().color(QPalette::Active, QColorGroup::Background) ); + pal.setBrush ( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background) ); + tb->setPalette( pal ); + } + tb->removeEventFilter(eventKiller); + } + else + { + QPalette pal( tb->palette() ); + pal.setBrush ( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background) ); + tb->installEventFilter(eventKiller); + tb->setPalette( pal ); + tb->removeEventFilter(eventKiller); + } + } + /*hmhmhmm... this may break qgroupbox children?!?*/ + else if (::qt_cast(obj)) + { + QGroupBox* gb = (QGroupBox*)(obj); + if(gb->title().isEmpty()) return false; + QResizeEvent * e = (QResizeEvent*)ev; + int fm = gb->fontMetrics().height()+(gb->isCheckable()?4:1); + gb->setFrameRect(QRect(gb->rect().x(), gb->rect().y()+fm, e->size().width(), e->size().height()-fm/*-gb->frameWidth()*/)); + if(gb->layout()) + gb->layout()->setGeometry(QRect(gb->rect().x(), gb->rect().y(), e->size().width(), e->size().height())); + return true; + } + else if ( obj->inherits( "KActiveLabel" )) + { + QWidget * w = ( QWidget * ) obj; + QPalette pal( w->palette() ); + QPixmap *tile = pal.brush( QPalette::Active, QColorGroup::Background ).pixmap(); + if ( tile ) + { + QSize sz( ev->type() == QEvent::Resize ? rev->size() : w->size() ); + QPixmap pix( sz.width(), sz.height() ); + QPainter p; + if (optionHandler->style() == Brushed) + { + p.begin( &pix ); + // calc brush offsets + QWidget *window = w->topLevelWidget(); + int leftWidth; + int rightWidth; + if (window) + { + QPoint zero = w->mapTo(window, QPoint(0,0)); + leftWidth = (window->width()-1024)/2 - zero.x(); + rightWidth = pix.width() - (1024 + leftWidth); + if (leftWidth > 0) + p.drawTiledPixmap(0, 0, leftWidth, sz.height(), plainBrush); + p.drawTiledPixmap(leftWidth>0?leftWidth:0, 0, + pix.width()-(leftWidth>0?leftWidth:0)-(rightWidth>0?rightWidth:0), sz.height(), + gradBrush,leftWidth>0?0:(zero.x()-(window->width()-1024)/2)); + if (rightWidth > 0) + p.drawTiledPixmap(pix.width()-rightWidth, 0, rightWidth, sz.height(), plainBrush); + } + else if (pix.width() > 1024) + { + leftWidth = (pix.width()-1024)/2; + rightWidth = pix.width() - leftWidth; + p.drawTiledPixmap(0, 0, leftWidth, sz.height(), plainBrush); + p.drawTiledPixmap(leftWidth, 0, 1024, sz.height(), gradBrush); + p.drawTiledPixmap(leftWidth + 1024, 0, rightWidth, sz.height(), plainBrush); + } + else + p.drawTiledPixmap(0, 0, pix.width(), sz.height(), gradBrush, (1024-pix.width())/2, 0); + p.end(); + QBrush brush( pal.active().background(), pix ); + pal.setBrush( QColorGroup::Base, brush ); + w->setPalette( pal ); + } + else + { + p.begin(w); + p.drawTiledPixmap(QRect(0,0,sz.width(),sz.height()), *tile, w->backgroundOffset()); + } + } + return false; + } + else if ((optionHandler->style() == Brushed) && obj->isWidgetType() && ((QWidget*)obj)->isTopLevel() && + !(::qt_cast(obj) || ::qt_cast(obj) || ((QWidget*)obj)->isDesktop () || ::qt_cast(obj) || + obj->inherits("QTipLabel") || obj->inherits("AlphaWidget") || obj->inherits("ScrollWidget") ) && (ev->type() == QEvent::Show || + rev->size().width() != rev->oldSize().width())) + { + QWidget* widget = (QWidget*)obj; + // create new brushpix + QPixmap tmpBrushPix(ev->type() == QEvent::Show?widget->width():rev->size().width(), plainBrush.height()); + QPainter lightMe(&tmpBrushPix); + // calc brush offsets + int tmpWidth; + if ((tmpWidth = tmpBrushPix.width()) > 1024) + { + int leftWidth = (tmpWidth-1024)/2; + int rightWidth = tmpWidth - leftWidth; + lightMe.drawTiledPixmap(0, 0, leftWidth, plainBrush.height(), plainBrush,256-leftWidth,0); + lightMe.drawPixmap(leftWidth, 0, gradBrush); + lightMe.drawTiledPixmap(leftWidth + 1024, 0, rightWidth, plainBrush.height(), plainBrush); + } + else + lightMe.drawPixmap(0, 0, gradBrush, (1024-tmpWidth)/2, 0, tmpWidth); + lightMe.end(); + //update palette + QPalette pal( qApp->palette()); + QBrush brush( pal.active().background(), tmpBrushPix ); + pal.setBrush ( QColorGroup::Background, brush ); + //reset apps palette + qApp->installEventFilter(eventKiller); // pssst... don't let anyone know... + qApp->setPalette(pal); + pal = QPalette(widget->palette()); + pal.setBrush ( QColorGroup::Background, brush ); + widget->installEventFilter(eventKiller); // pssst... don't let anyone know... + widget->setPalette(pal); + widget->removeEventFilter(eventKiller); // ...that we just replaced the palette + QObjectList *kids = widget->queryList("QWidget"); //TODO: implement a faster version, depending on ::qt_cast() + for (uint i= 0; i < kids->count(); i++) + { + QWidget *kid = (QWidget*)kids->at(i); + if (kid && kid->paletteBackgroundPixmap() && !(kid->isTopLevel() || kid->inherits( "KonqIconViewWidget" ) || kid->inherits( "khtml") || kid->inherits( "KActiveLabel") || qstrcmp( kid->name(), "_B_ALI_HEADER" ) == 0 || (kid->parentWidget() && kid->parentWidget()->inherits("Thumbnail") || kid->parentWidget()->inherits("MarkListItem")) )) + { + //we can loose those kids anytime - especially if the user plays on konqueror... + if (::qt_cast(kid)) + kid->setErasePixmap(tmpBrushPix); + else + { + pal = QPalette(kid->palette()); + pal.setBrush ( QColorGroup::Background, brush ); + kid->installEventFilter(eventKiller); // pssst... don't let anyone know... + kid->setPalette(pal); + kid->removeEventFilter(eventKiller); // ...that we just replaced the palette + } + } + } + delete kids; + qApp->removeEventFilter(eventKiller); // ...that we just replaced the palette + return false; + } + return false; + } + case QEvent::Hide: + if (optionHandler->AnimateButton() && ::qt_cast(obj)) + { + ButtonFadeInfo *bfi_ = bfi[((QPushButton*)obj)->winId()]; + if (bfi_) + { + obj->killTimer(bfi_->timerId); + // qWarning("%u: stopped (%d)", ((QPushButton*)obj)->winId(), bfi_->timerId); + bfi_->index=0; + bfi_->timerId=0; + } + } + case QEvent::ApplicationPaletteChange: + if ( obj->inherits( "QTipLabel" ) ) + { + ( ( QWidget* ) obj ) ->setPalette( tooltipPalette ); + return true; + } + return false; + case QEvent::PaletteChange: + if (obj->inherits("QStatusBar")) + { + obj->installEventFilter(eventKiller); + ((QWidget*)obj)->setPalette(qApp->palette()); + obj->removeEventFilter(eventKiller); + return true; + } + if ( obj->inherits( "QTipLabel" ) ) + { + ( ( QWidget* ) obj ) ->setPalette( tooltipPalette ); + return true; + } + if (obj->inherits("KCalcButton")) + { + QWidget *w = (QWidget*)obj; + QPalette pal( w->palette() ); + pal.setBrush( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background)); + w->installEventFilter(eventKiller); + w->setPalette( pal ); + w->removeEventFilter(eventKiller); + w->setBackgroundOrigin( QWidget::WindowOrigin ); + return true; + } + return false; + case QEvent::WindowActivate: + if (optionHandler->style() == Tiger && ::qt_cast(obj)) + { + QToolBar *tb = (QToolBar*)obj; + QPoint pt = tb->mapTo(tb->topLevelWidget(), QPoint(0,0)); + if (pt.y() == 0) + { + tb->installEventFilter(eventKiller); + tb->setPaletteBackgroundColor(optionHandler->aDecoColor2()); + tb->setPaletteBackgroundPixmap(activeToolbarPix); + tb->removeEventFilter(eventKiller); + } + } + return false; + case QEvent::WindowDeactivate: + if (optionHandler->style() == Tiger && ::qt_cast(obj)) + { + QToolBar *tb = (QToolBar*)obj; + QPoint pt = tb->mapTo(tb->topLevelWidget(), QPoint(0,0)); + if (pt.y() == 0) + { + QPalette pal( tb->palette() ); + pal.setColor( QColorGroup::Background, qApp->palette().color(QPalette::Active, QColorGroup::Background) ); + pal.setBrush ( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background) ); + tb->installEventFilter(eventKiller); + tb->setPalette( pal ); + obj->removeEventFilter(eventKiller); + } + } + return false; + default: + return false; + } +} + +void LiquidStyle::fakeMouse() +{ + if (mouseButtonPressed_) // delayed mousepress for move event + { + QCursor::setPos ( cursorPos_ ); + XTestFakeButtonEvent(qt_xdisplay(),1, false, 0); + XTestFakeKeyEvent(qt_xdisplay(),XKeysymToKeycode(qt_xdisplay(), XK_Alt_L), true, 0); + XTestFakeButtonEvent(qt_xdisplay(),1, true, 0); + XTestFakeKeyEvent(qt_xdisplay(),XKeysymToKeycode(qt_xdisplay(), XK_Alt_L), false, 0); + XFlush(qt_xdisplay()); + } +} + +void LiquidStyle::fadeIn(QPushButton *button) +{ + ButtonFadeInfo *bfi_ = bfi[button->winId()]; + if (!bfi_) + { + bfi_ = new ButtonFadeInfo(); + bfi.insert(button->winId(),bfi_); + } + bfi_->fadeIn = true; + if (bfi_->timerId == 0) + { + bfi_->index = 0; + bfi_->timerId = button->startTimer(button->isDefault()?100:50); + // qWarning("%u: started (%d)", button->winId(), bfi_->timerId); + } +} + +void LiquidStyle::fadeOut(QPushButton *button) +{ + ButtonFadeInfo *bfi_ = bfi[button->winId()]; + if (!bfi_) + { + bfi_ = new ButtonFadeInfo(); + bfi.insert(button->winId(),bfi_); + } + bfi_->fadeIn = false; + if (bfi_->timerId == 0) + { + bfi_->index = 9; + bfi_->timerId = button->startTimer(50); + // qWarning("%u: started (%d)", button->winId(), bfi_->timerId); + } +} + +BMShower::BMShower(QObject *parent) : QObject(parent) +{ +} + +bool BMShower::eventFilter( QObject *obj, QEvent *ev ) +{ + if (ev->type() == QEvent::Show && (obj->isWidgetType() && ((QWidget*)obj)->isTopLevel() && + !(::qt_cast(obj) || ::qt_cast(obj) || ((QWidget*)obj)->isDesktop () || ::qt_cast(obj) || + obj->inherits("QTipLabel") || obj->inherits("AlphaWidget") || obj->inherits("ScrollWidget") ))) + { + QResizeEvent* rev = new QResizeEvent(((QWidget*)obj)->size(), QSize(0,0)); + parent()->eventFilter( obj, rev ); + obj->removeEventFilter(this); + delete rev; + } + return false; +} diff --git a/style/fracts.h b/style/fracts.h new file mode 100644 index 0000000..1774e93 --- /dev/null +++ b/style/fracts.h @@ -0,0 +1,74 @@ +#ifndef FRACTS_H +#define FRACTS_H + +/* +If you wish to replace the button or combo Images, you may end up with very querky results. +The reason is, that the style internally fracts those images into 9 tiles. + +To get valid results, you need to adjust the values below, so they fit your images. +the format is: +w, h, xOff, yOff, centerW, centerH, shadowH, glowWH + +- w, h are width and height of the whole button. +- xOff (yOff) is the distance of the central fraction from left (upper) button side. +- centerW (centerH) is the width (height) of the central button fraction. +- shadowH is the height of the buttons shadow +- glowWH is the size of the frame the glow draws around the button + +an image may be helpful (make sure your editor uses a monospace font) + +[- - - - - - - - - - - - - - - w - - - - - - - - - - - - -]--- +|----------------|--------------------------|-----------------| | +| | | | +| yOff | | | +| | | | +|----- xOff----->o--------- centerW --------|-----------------| | +| | | | +| | centerH | h +| | | | +|----------------|--------------------------|-----------------| | +| | | | +| | | | | +| | | | +| | | | | +|----------------|--------------------------|-----------------| | +. --- + +Also please notice, that the Button tiles are treated different from the rectangualr ones, namely, (S: static, T: tiled, TH: tiled horizontally, TV: tiled vertically) + +Round Button, Combo: +|----------------|--------------------------|-----------------| +| | | | +| S | TH | S | +| | | | +|----------------|--------------------------|-----------------| +| | | | +| TV | T | TV | +| | | | +|----------------|--------------------------|-----------------| +| | | | +| | | | +| S | TH | S | +| | | | +|----------------|--------------------------|-----------------| + +Rectangular Button: +|----------------|--------------------------|-----------------| +| | | | +| TV | TH | TV | +| | | | +|----------------|--------------------------|-----------------| +| | | | +| S | TH | S | +| | | | +|----------------|--------------------------|-----------------| +| | | | +| | | | +| TV | TH | TV | +| | | | +|----------------|--------------------------|-----------------| + +*/ + + +#endif diff --git a/style/generatePixmaps.sh b/style/generatePixmaps.sh new file mode 100755 index 0000000..388b002 --- /dev/null +++ b/style/generatePixmaps.sh @@ -0,0 +1,54 @@ +#!/bin/sh +top_srcdir="${1:-../..}" +imagebase="$top_srcdir/imagebase" +UIC=$(grep "UIC = " ../Makefile | cut -f3- -d" ") +echo -e "#ifndef SPIXMAPS_H\n#define SPIXMAPS_H\n" > pixmaps.h +$UIC -embed baghira \ +$imagebase/brushed-gradient \ +$imagebase/brushed-tile \ +$imagebase/button-base \ +$imagebase/button-milk \ +$imagebase/button-glow \ +$imagebase/button-jaguar \ +$imagebase/button-shadow \ +$imagebase/checkbox \ +$imagebase/checkboxdown \ +$imagebase/checkbox-milk \ +$imagebase/checkboxdown-milk \ +$imagebase/combo \ +$imagebase/combo-milk \ +$imagebase/combo-jaguar \ +$imagebase/combo-shadow \ +$imagebase/htmlradio \ +$imagebase/htmlradio_down \ +$imagebase/progress \ +$imagebase/progress2 \ +$imagebase/radio \ +$imagebase/radio_down \ +$imagebase/radio-milk \ +$imagebase/radio_down-milk \ +$imagebase/rectbutton \ +$imagebase/roundFrame \ +$imagebase/sbgroove_btm \ +$imagebase/sbgroove_mid \ +$imagebase/sbgroove_top \ +$imagebase/sbIslider_mid \ +$imagebase/sbslider_btm \ +$imagebase/sbslider_btm_shd \ +$imagebase/sbslider_mid \ +$imagebase/sbslider_top \ +$imagebase/sbslider_top_shd \ +$imagebase/sb_subadd \ +$imagebase/sliderarrow \ +$imagebase/sbgroove_btm-milk \ +$imagebase/sbgroove_mid-milk \ +$imagebase/sbgroove_top-milk \ +$imagebase/sbslider_btm-milk \ +$imagebase/sbslider_mid-milk \ +$imagebase/sbslider_top-milk \ +$imagebase/sb_subadd-milk \ +$imagebase/sliderarrow-milk \ +$imagebase/tab \ +$imagebase/tab-milk \ +$imagebase/tab-jaguar >> pixmaps.h +echo -e "#endif //SPIXMAPS_H\n" >> pixmaps.h diff --git a/style/optionHandler.cpp b/style/optionHandler.cpp new file mode 100644 index 0000000..d96b700 --- /dev/null +++ b/style/optionHandler.cpp @@ -0,0 +1,251 @@ +#include "baghira.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#include +#include + +#define _SCALE_ 65536 +#define _NORMALIZE_ >>16 + +#define CLAMP(x,l,u) x < l ? l :\ +x > u ? u :\ +x + +OptionHandler::OptionHandler( QObject *parent ) : QObject( parent ) { + scrollerActive = false; + groupShadowButton = false; + reloadSettings(); + } + + +const QColor& OptionHandler::textColor() { + return ( useCustomMenuColor ? fgColor : qApp->palette().active().text() ); + } + +const QColor& OptionHandler::bgColor() { + return qApp->palette().active().background(); + } + +const QColor& OptionHandler::buttonColor() { + LiquidStyle * style = ( LiquidStyle* ) parent(); + /*if (style->isKicker) return style->origPanelBrush.color(); + else */if (style->isOOO) return CustomButtonColor(); + else return qApp->palette().active().button(); + } + +void OptionHandler::reloadSettings() { + // gather options... + QSettings config; + config.beginGroup("/baghira/Style"); + //we need that first to make sure we use some proper settings ;) + customButtonColor = QColor(config.readNumEntry("Design_ButtonColor",(int)qApp->palette().active().button().rgb())); + // design handling: + // first try file: + QString tmpString; + FILE *file = NULL; + wmDesign = 5; + for (int i = 0; i < 8; i++) + custCols[i] = -1; + if (qstrcmp( qApp->argv() [ 0 ], "ksplash" ) == 0) + { + style_ = Panther; + _toolbuttonStyle = Panther; + _buttonStyle = Panther; + tabStyle_ = Clever; + bgStipple = false; + inactiveButtonColor = Background; + } + else + { + // first try for a tmp file from bab starter + int tmpFile = 0; + tmpString = QDir::homeDirPath() + "/.baghira/.bab/" + qApp->argv() [ 0 ]; + file = fopen(tmpString.latin1(), "r"); + if( file == NULL ) + { + tmpFile = 1; + tmpString = QDir::homeDirPath() + "/.baghira/" + qApp->argv() [ 0 ]; + file = fopen(tmpString.latin1(), "r"); + if( file == NULL ) + { + tmpFile = 2; + tmpString = QDir::homeDirPath() + "/.baghira/.bab/.style"; + file = fopen(tmpString.latin1(), "r"); + } + } + if (file != NULL) + { + style_ = _buttonStyle = _toolbuttonStyle = Panther; int i3 = inactiveButtonColor = -1; tabStyle_ = (tabStyle)-1; + fscanf(file,"%u\n%u\n%u\n%u\n%u\n%u\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",&style_, &wmDesign, &_buttonStyle, &_toolbuttonStyle, &tabStyle_, &i3, &custCols[0], &custCols[1], &custCols[2], &custCols[3], &custCols[4], &custCols[5], &custCols[6], &custCols[7], &inactiveButtonColor); + fclose(file); + if (_toolbuttonStyle < 0 || _toolbuttonStyle >= NUMSTYLES) + _toolbuttonStyle = (Style)config.readNumEntry( "Special_ToolbuttonStyle", style_); + if (_buttonStyle < 0 || _buttonStyle >= NUMSTYLES) + _buttonStyle = (Style)config.readNumEntry( "Special_ButtonStyle", style_); + if (tabStyle_ < 0 || tabStyle_ > 2) + tabStyle_ = (tabStyle) config.readNumEntry( (style_ == Brushed)?"Design_TabStyleBrushed":"Design_TabStyleAqua", Clever); + if (inactiveButtonColor < 0 || inactiveButtonColor > 3) + inactiveButtonColor = config.readNumEntry( "Design_InactiveButtonStyle", Background); + if (style_ == Brushed) + bgStipple = TRUE; + else if (i3 == 0) + bgStipple = FALSE; + else + bgStipple = config.readBoolEntry( "Design_StippleBackground", true ); + // inactive Button + if (tmpFile == 0) + remove(tmpString.latin1()); // remove TEMPORARY file + else if (tmpFile == 2) + { + tmpString = QDir::homeDirPath() + "/.baghira/.bab/.deco"; + if ((file = fopen(tmpString.latin1(), "r")) != NULL) + { + fscanf(file,"%u\n%u\n",&i3, &wmDesign); + fclose(file); + } + } + } + else + { + style_ = (Style)config.readNumEntry( "Design_Default", Panther ); + _toolbuttonStyle = (Style)config.readNumEntry( "Special_ToolbuttonStyle", style_); + _buttonStyle = (Style)config.readNumEntry( "Special_ButtonStyle", style_); + tabStyle_ = (tabStyle) config.readNumEntry( (style_ == Brushed)?"Design_TabStyleBrushed":"Design_TabStyleAqua", Clever); + bgStipple = (style_ == Brushed) ? true : config.readBoolEntry( "Design_StippleBackground", true ); + inactiveButtonColor = config.readNumEntry( "Design_InactiveButtonStyle", Background); + } + } + contrast = 0; + if (wmDesign > 4) + wmDesign = style_; + if (style_ == Jaguar) + contrast = 4; + else if (style_ == Brushed) + { + tintBrush = config.readBoolEntry( "Colors_TintBrushedMetal", false ); + if (tintBrush) + brushTint.setRgb( config.readNumEntry( "Colors_BrushTint", ( int ) bgColor().rgb())); + } + // menu stuff + glossyMenus_ = config.readBoolEntry( "Menu_Glossy", true ); + menuBackground = config.readNumEntry( "Menu_Background", Standard); + menuOpacity = config.readNumEntry( "Menu_Opacity", 70); + int menuColorStyle = config.readNumEntry( "Menu_ColorStyle", 0); + menuColorButton = (menuColorStyle == 1); + useCustomMenuColor = (menuColorStyle == 2); + shadowText = config.readBoolEntry( "Menu_ShadowText", false); + if (useCustomMenuColor){ + color = QColor( config.readNumEntry( "Menu_Color1", 0 ) ); + color2 = QColor( config.readNumEntry( "Menu_Color2", 0 ) ); + colorHigh = QColor( config.readNumEntry( "Menu_ColorHighlight", 0 ) ); + fgColor = QColor( config.readNumEntry( "Menu_TextColor", 0 ) ); + fgColorHigh = QColor( config.readNumEntry( "Menu_TextColorHighlight", 0 ) ); + } + else if (menuColorButton){ + color = customButtonColor; + color2 = customButtonColor.dark(130); + } + else { + color = qApp->palette().active().background(); + color2 = qApp->palette().active().background().dark(130); + } + drawMenuStripe_ = config.readBoolEntry("Menu_DrawMenuStripe", false); + if (drawMenuStripe_) + menuStripeColor_ = QColor(config.readNumEntry("Menu_StripeColor"),(int)Qt::white.rgb()); + // color stuff + // widgets + customWidgetColor = config.readBoolEntry( "Colors_UseCustomColors", false); + if ( customWidgetColor ) { + customColors[ CustomRadioOn ].setRgb( config.readNumEntry( "Colors_RadioOn", ( int ) buttonColor().rgb() ) ); + customColors[ CustomRadioOff ].setRgb( config.readNumEntry( "Colors_RadioOff", ( int ) bgColor().rgb() ) ); + customColors[ CustomCBOn ].setRgb( config.readNumEntry( "Colors_CheckOn", ( int ) buttonColor().rgb() ) ); + customColors[ CustomCBOff ].setRgb( config.readNumEntry( "Colors_CheckOff", ( int ) bgColor().rgb() ) ); + customColors[ CustomTabOn ].setRgb( config.readNumEntry( "Colors_TabActive", ( int ) buttonColor().rgb() ) ); + customColors[ CustomTabOff ].setRgb( config.readNumEntry( "Colors_TabInactive", ( int ) bgColor().rgb() ) ); + customColors[ CustomSBSlider ].setRgb( config.readNumEntry( "Colors_Slider", ( int ) bgColor().rgb() ) ); + customColors[ CustomSBSliderHover ].setRgb( config.readNumEntry( "Colors_SliderHovered", ( int ) buttonColor().rgb() ) ); + customColors[ CustomSBSliderPressed ].setRgb( config.readNumEntry( "Colors_SliderPressed", ( int ) buttonColor().dark(110).rgb() ) ); + customColors[ CustomSBGroove ].setRgb( config.readNumEntry( "Colors_SliderGroove", ( int ) bgColor().rgb() ) ); + } + if (inactiveButtonColor == Custom) + customInactiveButtonColor = QColor( config.readNumEntry( "Design_InactiveButtonColor", (int) bgColor().rgb())); + contrast += config.readNumEntry( "Design_StippleContrast", 3); + bevelHighlights_ = config.readBoolEntry( "Design_BevelAsHighlight", true); + //shadows +groupboxshadow = (style_ == Brushed) ? false : config.readBoolEntry( "Design_ShadowGroupBoxes", true ); + shadowDarkness = config.readNumEntry( "Design_GroupBoxeShadowDarkness", 6); + //ListViews + expanderStyle = config.readNumEntry( "Special_ExpanderStyle", Apple); + useCustomExpanderColor = config.readBoolEntry( "Special_CustomExpanderColor", false); + if (useCustomExpanderColor) + expanderColor = QColor( config.readNumEntry( "Special_ExpanderColor", (int) qApp->palette().active().text().rgb())); + drawDotlines = config.readBoolEntry( "Special_DrawTreeLines", true); + if (drawDotlines){ + dotlineStyle = config.readNumEntry( "Special_TreelineStyle", Line); + dotlineColor = QColor( config.readNumEntry( "Special_TreelineColor", (int) qApp->palette().active().mid().rgb())); + } + //slider + squeezesbslider = config.readBoolEntry( "Special_SqueezeSlider", false ); + shadowsbslider = config.readBoolEntry( "Special_ShadowSlider", false ); + animateSlider = config.readBoolEntry( "Special_AnimateSlider", true ); + // toolbar + int utb = config.readNumEntry( "Special_UnhoveredToolButtons", 2 ); + tbFrame = (utb == 2) || ((style_ == Brushed) && (utb == 1)) || ((style_ != Brushed) && (utb == 0)); + + // tweaks + centerTabs = config.readBoolEntry( "Design_CenterTabs", true); + smoothListViewHeaders = (style_ == Milk) ? true : !config.readBoolEntry( "Special_UseFlatLVH", false); + smootherLVH = config.readBoolEntry( "Special_RoundTaskbuttons", false); + icyButtons = config.readNumEntry( "Design_ButtonStyle", 0) == 0; + progressBar = config.readNumEntry( "Special_ProgressStyle", baghira); + removeKickerBevel = config.readBoolEntry( "Special_RemoveKickerBevel", false); + animateButton = config.readBoolEntry( "Design_AnimateButtons", true); + animateProgress = config.readBoolEntry( "Design_AnimateProgress", true); + drawProgressLabel = config.readBoolEntry( "Special_ShowProgressValue", false); + config.endGroup(); + + config.beginGroup("/baghira/Deco"); + titleButtonColor_[0] = QColor((unsigned int)config.readNumEntry( "CloseButtonColor", QColor(200,85,70).rgb())); + titleButtonColor_[1] = QColor((unsigned int)config.readNumEntry( "MinButtonColor", QColor(230,155,40).rgb())); + titleButtonColor_[2] = QColor((unsigned int)config.readNumEntry( "MaxButtonColor", QColor(121,180,54).rgb())); + if (style_ == Jaguar) + { + titleColor_[0] = QColor((unsigned int)config.readNumEntry( "inactiveColor1_1", QColor(204,214,230).rgb())); + titleColor_[1] = QColor((unsigned int)config.readNumEntry( "inactiveColor2_1", QColor(194,196,211).rgb())); + } + else if (style_ != Brushed) + { + titleColor_[0] = QColor((unsigned int)config.readNumEntry( "activeColor1_2", QColor(238,238,238).rgb())); + titleColor_[1] = QColor((unsigned int)config.readNumEntry( "activeColor2_2", QColor(205,202,205).rgb())); + } + if (style_ == Tiger) + { + int r,g,b; + aDecoColor1_ = QColor((unsigned int)config.readNumEntry( "activeColor2_4", (unsigned int) QColor(205,202,205).rgb())); + aDecoColor2_ = QColor((unsigned int)config.readNumEntry( "activeColor1_4", (unsigned int) QColor(238,238,238).rgb())); + r = (int)CLAMP(aDecoColor1_.red() * pow((double)aDecoColor1_.red() / (double)aDecoColor2_.red(),2.0),0,255); + g = (int)CLAMP(aDecoColor1_.green() * pow((double)aDecoColor1_.green() / (double)aDecoColor2_.green(),2.0),0,255); + b = (int)CLAMP(aDecoColor1_.blue() * pow((double)aDecoColor1_.blue() / (double)aDecoColor2_.blue(),2.0),0,255); + aDecoColor2_.setRgb(r,g,b); + } + else + { + aDecoColor1_ = Qt::black; + aDecoColor2_ = Qt::black; + } + config.endGroup(); + // Option gathered + } diff --git a/style/polish.cpp b/style/polish.cpp new file mode 100644 index 0000000..f845d2b --- /dev/null +++ b/style/polish.cpp @@ -0,0 +1,878 @@ +//#include +#include "baghira.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 +#include +#include +#include +#include +#include +#include + +#include +#define OPAQUE 0xffffffff +#define OPACITY "_KDE_WM_WINDOW_OPACITY" +#define _FORCE_SCROLLBARS_ 0 + +#ifndef CLAMP +#define CLAMP(x,l,u) x < l ? l :\ +x > u ? u :\ +x +#endif + + +void LiquidStyle::polish( QPalette &pal ) +{ + if ( inExitPolish ) + return ; + // clear out all old colorized pixmaps + int i; + for ( i = 0; i < BITMAP_ITEMS; ++i ) + { + if ( pixmaps[ i ] ) + { + delete pixmaps[ i ]; + pixmaps[ i ] = NULL; + } + } + // clear out all dicts + btnDict.clear(); + btnShadowedDict.clear(); + // reset brushes + pagerHoverBrush = QBrush(); + pagerBrush = QBrush(); + + bool newPalette = false; + struct stat buffer; + if ( stat( QFile::encodeName( QDir::homeDirPath() + "/.qt/qtrc" ), &buffer ) == 0 ) + { + unsigned int lastModTime = ( unsigned int ) buffer.st_mtime; + if ( lastModTime > qtrcModificationTime ) + { + qtrcModificationTime = lastModTime; + newPalette = true; + } + } + else if ( !initialPaletteLoaded ) // Hack, should always have qtrc in KDE + newPalette = true; + initialPaletteLoaded = true; + + if ( !newPalette ) + { + pal = polishedPalette; + return ; + } + + originalBgColor = pal.color(QPalette::Active, QColorGroup::Background); + if (optionHandler->style() == Brushed) + pal.setColor(QColorGroup::Background, brushedMetalColor(optionHandler->BrushTint())); + if (isOOO) + pal.setColor( QColorGroup::Button, pal.active().background() ); + else if (optionHandler->custCols[0] != -1) + { + pal.setColor(QColorGroup::Background, QColor(optionHandler->custCols[0])); + pal.setColor(QColorGroup::Button, QColor(optionHandler->custCols[1])); + pal.setColor(QColorGroup::Base, QColor(optionHandler->custCols[2])); + pal.setColor(QPalette::Active, QColorGroup::Text, QColor(optionHandler->custCols[3])); + pal.setColor(QPalette::Active, QColorGroup::Foreground, QColor(optionHandler->custCols[3])); + pal.setColor(QColorGroup::Highlight, QColor(optionHandler->custCols[4])); + pal.setColor(QPalette::Active, QColorGroup::HighlightedText, QColor(optionHandler->custCols[5])); + pal.setColor(QPalette::Active, QColorGroup::ButtonText, QColor(optionHandler->custCols[6])); + pal.setColor(QColorGroup::Mid, QColor((qRed(optionHandler->custCols[2])+qRed(optionHandler->custCols[3]))/2,(qGreen(optionHandler->custCols[2])+qGreen(optionHandler->custCols[3]))/2,(qBlue(optionHandler->custCols[2])+qBlue(optionHandler->custCols[3]))/2)); + + pal.setColor(QPalette::Inactive, QColorGroup::Text, QColor(optionHandler->custCols[3])); + pal.setColor(QPalette::Inactive, QColorGroup::HighlightedText, QColor(optionHandler->custCols[5])); + pal.setColor(QPalette::Inactive, QColorGroup::ButtonText, QColor(optionHandler->custCols[6])); + } + else + pal.setColor( QColorGroup::Button, optionHandler->CustomButtonColor() ); +#if 0 + if ( isKicker ) + { + origPanelBrush = pal.brush( QPalette::Active, QColorGroup::Background ); + origPanelPalette = pal; + QColor c( pal.active().background() ); + + if ( optionHandler->usePanelCustomColor() && optionHandler->panelCustomColor().isValid() ) + c = optionHandler->panelCustomColor(); + + kickerColor = c; + + pal.setColor( QColorGroup::Mid, optionHandler->CustomButtonColor().dark( 110 ) ); + pal.setColor( QColorGroup::Dark, optionHandler->CustomButtonColor().dark( 130 ) ); + pal.setColor( QColorGroup::Midlight, optionHandler->CustomButtonColor().light( 110 ) ); + pal.setColor( QColorGroup::Light, optionHandler->CustomButtonColor().light( 115 ) ); + pal.setColor( QColorGroup::Button, optionHandler->CustomButtonColor()); + + if (optionHandler->style() == Brushed) + { + QBrush brush( c, gradBrush ); + pal.setBrush( QColorGroup::Background, brush ); + } + else if ( optionHandler->usePanelStipple() ) + { + QPixmap stipple( 64, 64 ); + stipple.fill( c.rgb() ); + QPainter p( &stipple ); + p.setPen( c.dark( 100 + (int)(optionHandler->stippleContrast()/4) ) ); + for ( int i = 1; i < 64; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + p.drawLine( 0, i+2, 63, i+2 ); + } + p.setPen( c.dark( 100 + optionHandler->stippleContrast()) ); + for ( int i = 2; i < 63; i += 4 ) + p.drawLine( 0, i, 63, i ); + p.end(); + QBrush brush( c, stipple ); + pal.setBrush( QColorGroup::Background, brush ); + } + else + pal.setBrush( QColorGroup::Background, c ); + } +#endif + /*else*/ if (optionHandler->style() == Brushed) + { + QColor c( pal.active().background() ); + QBrush brush( c, gradBrush ); + pal.setBrush( QColorGroup::Background, brush ); + } + else if ( !isPlain() ) + { + QColor c( pal.active().background() ); + QPixmap stipple( 64, 64 ); + stipple.fill( c.rgb() ); + QPainter p; + p.begin( &stipple ); + p.setPen( c.dark( 100 + (int)(optionHandler->stippleContrast()/2) ) ); + for ( i = 1; i < 64; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + p.drawLine( 0, i+2, 63, i+2 ); + } + p.setPen( c.dark( 100 + optionHandler->stippleContrast() ) ); + for ( i = 2; i < 63; i += 4 ) + p.drawLine( 0, i, 63, i ); + p.end(); + QBrush brush( c, stipple ); + pal.setBrush( QColorGroup::Background, brush ); + } + + if (optionHandler->bevelHighlights()) + { + QColor c(pal.active().highlight()); + QColor c2(c.light(140)); + QPixmap pix2 = QPixmap(48,48); + QPainter coolPainter(&pix2); + KPixmap pix = QPixmap(48,24); + KPixmapEffect::gradient(pix,c,c2,KPixmapEffect::VerticalGradient,0); + coolPainter.drawPixmap(0,0,pix); + KPixmapEffect::gradient(pix,c2,c,KPixmapEffect::VerticalGradient,0); + coolPainter.drawPixmap(0,24,pix); + QBrush brush(c, pix2); + pal.setBrush(QColorGroup::Highlight, brush); + } + polishedPalette = pal; + optionHandler->reset(); +} + +void LiquidStyle::unPolish( QApplication *app ) +{ + popupBack.resize(0,0); + QPalette pal( app->palette() ); + inExitPolish = true; + + if ( !isPlain() ) + { + // reset any stipples + if ( pal.brush( QPalette::Active, QColorGroup::Background ).pixmap() ) + pal.setBrush( QColorGroup::Background, pal.active().background() ); + if ( pal.brush( QPalette::Active, QColorGroup::Button ).pixmap() ) + pal.setBrush( QColorGroup::Button, pal.active().button() ); +// app->blockSignals( TRUE ); + app->setPalette( pal ); +// app->blockSignals( FALSE ); + } + + inExitPolish = false; +} + +Atom baghira_deco_design = XInternAtom(qt_xdisplay(), "BAGHIRA_DECO_DESIGN", False); + +void LiquidStyle::polish( QWidget *w ) +{ +// bool testWidget = w->inherits("Splash"); +// int testInt = 0; +// if (w->sizePolicy().horData() == QSizePolicy::Minimum || w->sizePolicy().horData() == QSizePolicy::MinimumExpanding) +// qWarning("%s, \"%s\"",w->className(), w->name()); +// w->installEventFilter(this); + + bool tmpBool = false; + bool isViewport = qstrcmp( w->name(), "qt_viewport" ) == 0 || + qstrcmp( w->name(), "qt_clipped_viewport" ) == 0; + bool isViewportChild = w->parent() && + ( ( qstrcmp( w->parent() ->name(), "qt_viewport" ) == 0 ) || + ( qstrcmp( w->parent() ->name(), "qt_clipped_viewport" ) == 0 ) ); + + if (w->isTopLevel()) + { + if ( ::qt_cast(w)) // popup menu designs + { + switch (optionHandler->MenuBackground()) + { + case Plain: + w->setBackgroundMode( QWidget::PaletteBackground ); + if (optionHandler->UseCustomMenuColor()) + w->setPaletteBackgroundColor(optionHandler->Color()); + else if (optionHandler->MenuColorButton()) + w->setPaletteBackgroundColor(optionHandler->buttonColor()); + else + w->setPaletteBackgroundColor(optionHandler->bgColor()); + break; + case Stipples: + { + QColor c; + if (optionHandler->UseCustomMenuColor()) + c = QColor( optionHandler->Color() ); + else if (optionHandler->MenuColorButton()) + c = QColor( optionHandler->buttonColor() ); + else + c = QColor( originalBgColor ); + if (popupBack.isNull()) + { + popupBack = QPixmap(64,64); + QPixmap *stipple = &popupBack; + stipple->fill( c.rgb() ); + QPainter p; + p.begin( stipple ); + if (optionHandler->UseCustomMenuColor()) + { + QColor c2 = QColor( optionHandler->Color2() ); + p.setPen(QColor((3*c.red()+c2.red())/4, + (3*c.green()+c2.green())/4, + (3*c.blue()+c2.blue())/4)); + for ( int i = 1; i < 64; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + p.drawLine( 0, i+2, 63, i+2 ); + } + p.setPen(c2); + for ( int i = 2; i < 63; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + } + } + else + { + p.setPen( c.dark( 100 + (int)(optionHandler->stippleContrast()/4) ) ); + for ( int i = 1; i < 64; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + p.drawLine( 0, i+2, 63, i+2 ); + } + p.setPen( c.dark( 100 + optionHandler->stippleContrast() ) ); + for ( int i = 2; i < 63; i += 4 ) + { + p.drawLine( 0, i, 63, i ); + } + } + p.end(); + } + w->setBackgroundMode( QWidget::NoBackground ); + break; + } + case Gradient: + { + w->setBackgroundMode( QWidget::PaletteBackground ); + KPixmap tmpPix = QPixmap(w->width(), 32); + w->setPaletteBackgroundPixmap(KPixmapEffect::unbalancedGradient(tmpPix, optionHandler->Color(), optionHandler->Color2(),KPixmapEffect::HorizontalGradient, 100, 100, 16)); + w->installEventFilter( this ); + break; + } + default: + w->setBackgroundMode( QWidget::PaletteBackground ); + break; + } + //set popup menu opacity for them as they bypass the windowmanager + unsigned long opacity = optionHandler->MenuOpacity()/100.0*OPAQUE; + XChangeProperty(qt_xdisplay(), w->winId(), XInternAtom(qt_xdisplay(), OPACITY, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &opacity, 1L); + goto kstpolish; + } + else + { + if (optionHandler->wmDesign < 5) // set deco design X Property + { + unsigned char *data = 0; + Atom actual; + int format, result; + unsigned long n, left; + result = XGetWindowProperty(qt_xdisplay(), w->winId(), baghira_deco_design, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data); + if (result != Success || data == None) // not found set design + { + int tmp = optionHandler->wmDesign != Tiger ? optionHandler->wmDesign : Panther; + XChangeProperty(qt_xdisplay(), w->winId(), baghira_deco_design, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &(tmp), 1L); + } + } + if ((optionHandler->style() == Brushed) && !( ::qt_cast(w) || ::qt_cast(w) || w->isDesktop() || ::qt_cast(w) || w->inherits("QTipLabel") || w->inherits("AlphaWidget") || w->inherits("ScrollWidget") || w->inherits("PlayerWidget"))) + // install resize event filter, allowing us to update the b/m gradient on horizontal resizes. some widgets must be excluded though + { + if (!isKicker) + w->installEventFilter( bmShower ); + w->installEventFilter( this ); + } + } + } // TopLevel Widgets + + if (w->inherits("KURLBar")/*ListBox*/) + { + w->setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QColorGroup::Base)); +// ((QListBox*)w)->viewport()->setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QColorGroup::Base)); + goto kstpolish; + } + + + if (w->inherits("KColorGrid")) + { + // kiconedit doesn't check for the paintevent rect size, but tries to create a (possibly) NULL Pixmap (after palette change event e.g.) + // so we catch it's paint event and destroy it if the size is NULL + // remove this after kiconedit corrected its code + w->installEventFilter( this ); + goto kstpolish; + } + + if (w->inherits("BGMonitor") || w->inherits("mapWidget") || w->isA("MyButton") || (w->parentWidget() && w->parentWidget()->inherits("Thumbnail"))) + // don't touch these widgets at all - they don't like it + { + goto kstpolish; + } + + + + if (qstrcmp( w->name(), "kde toolbar widget" ) == 0 ) + w->installEventFilter( this ); + + if (::qt_cast(w)) + { + w->setBackgroundOrigin(QWidget::WindowOrigin); + if (::qt_cast(w)) + { + if (w->inherits("KKeyButton")) + { + w->setBackgroundMode( QWidget::PaletteBackground); + QPalette pal( w->palette() ); + pal.setBrush( QColorGroup::Background, qApp->palette().active().background() ); + w->setPalette( pal ); + } + else if (w->inherits("KCalcButton")) + { + w->setBackgroundMode( QWidget::PaletteBackground); + QPalette pal( w->palette() ); + pal.setBrush( QColorGroup::Background, qApp->palette().brush(QPalette::Active, QColorGroup::Background)); + w->setPalette( pal ); + } + else +#if !KDE_IS_VERSION(3,4,3) + if (!(w->parent() && w->parent()->inherits("MiniBar"))) +#endif + w->setBackgroundMode( QWidget::NoBackground); + w->installEventFilter( this ); + goto kstpolish; + } + else if (w->inherits( "QRadioButton" ) || w->inherits( "QCheckBox" )) + { + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter( this ); + goto kstpolish; + } + } + + if ( ::qt_cast(w)) + { + if (optionHandler->useToolButtonFrame() && w->inherits("KToolBar")) + ((QToolBar*)w)->boxLayout()->setSpacing( 0 ); + ((QToolBar*)w)->setMargin( 4 ); + w->setBackgroundMode(PaletteBackground); + w->setBackgroundOrigin(QWidget::WindowOrigin); + if (optionHandler->style() > Panther) + { + w->installEventFilter( this ); + if (optionHandler->wmDesign == Tiger) + { + XChangeProperty(qt_xdisplay(), w->topLevelWidget()->winId(), baghira_deco_design, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &(optionHandler->wmDesign), 1L); + } + } + + goto kstpolish ; + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + + if (tmpBool = ::qt_cast(w) || w->inherits( "QToolBarSeparator" ) || w->inherits( "KToolBarSeparator" ) ) + { + if (tmpBool && w->parentWidget() && ::qt_cast(w->parentWidget()) ) + { + w->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + } + w->setBackgroundMode( QWidget::PaletteBackground ); + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter( this ); + goto kstpolish; + } + + if (::qt_cast(w)) + { + w->setBackgroundMode(NoBackground); + w->installEventFilter( this ); + w->setBackgroundOrigin(QWidget::WindowOrigin); + goto kstpolish; + } + + if (w->inherits("TaskBar")) + { + w->setBackgroundOrigin(QWidget::WidgetOrigin); + goto kstpolish; + } + + if (w->inherits("QSpinWidget") || w->inherits("KDockWidgetAbstractHeaderDrag")){ + w->installEventFilter( this ); + goto kstpolish; + } + + if ( !isPlain () && (w->inherits( "KonqIconViewWidget" ) || w->inherits( "khtml")/* || w->inherits( "QtVisionView")*/)) + { + // if you want custom backgrounds in konqueror, you have to reset pixmap, since Konq animation can't handle it + // original liquid did this on khtml, too (at speed loss) so we'll see, if we get errors from this... + QPalette pal( w->palette() ); + pal.setBrush( QColorGroup::Background, pal.active().background() ); + w->setPalette( pal ); + } + + if (::qt_cast(w)) + { + //avoid flicker + w->setBackgroundMode( QWidget::NoBackground ); + goto kstpolish; + } + + if ((::qt_cast(w) || w->inherits("KateView") || w->inherits("TEWidget") || w->inherits("CHexViewWidget")) && !(w->isA("KOAgenda"))) + { + if (::qt_cast(w) && optionHandler->custCols[7] != -1 && ((KListView*)w)->alternateBackground() == KGlobalSettings::alternateBackgroundColor()) + { + ((KListView*)w)->setAlternateBackground(QColor(optionHandler->custCols[7])); + } +#if _FORCE_SCROLLBARS_ + if (::qt_cast(w) && !w->inherits( "KActiveLabel" )) + { + ((QScrollView*)w)->setVScrollBarMode(QScrollView::AlwaysOn); + } +#endif + if (::qt_cast(w) && w->isTopLevel()) + //set opacity for them as they bypass the windowmanager + { + uint opacity = 0.8*OPAQUE; + XChangeProperty(qt_xdisplay(), w->winId(), XInternAtom(qt_xdisplay(), OPACITY, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &opacity, 1L); + } +#if 0 + // doesn't work properly - best would be to have the items drawn via style() + int height = ((QListBox*)w)->itemHeight(); + if (height > 0) + { + QPalette pal = w->palette(); + QColor c(pal.active().highlight()); + QColor c2(c.light(140)); + KPixmap pix = QPixmap(48,height); + KPixmapEffect::gradient(pix,c2,c,KPixmapEffect::VerticalGradient,0); + QBrush brush(c, pix); + pal.setBrush(QColorGroup::Highlight, brush); + w->setPalette(pal); + } +#endif + // listen to enter events - highlightning the scrollbars + w->setMouseTracking( true ); + w->installEventFilter( this ); + goto kstpolish; + } + + if (w->inherits("QStatusBar")) + { + w->setBackgroundOrigin(QWidget::WindowOrigin); + if ( qstrcmp( w->name(), "KonquerorFrameStatusBar" ) == 0 ) + // konqueror resets the statusbars background to Qt::White as soon as you open a new tab - our eventfilter will block this + { + w->installEventFilter( this ); + } + goto kstpolish; + } + + if (w->inherits( "QLineEdit" ) || w->inherits("QSplitterHandle") || w->isA( "AppletHandleDrag" ) || w->inherits( "KMiniPagerButton" )) + { + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter( this ); + goto kstpolish; + } + + if (w->inherits( "TaskContainer" )) + { + w->installEventFilter( this ); + goto kstpolish; + } + + if (w->inherits( "KickerTip" )) + // kickers new tooltip uses backgroundColor() instead of paletteBackgroundColor() - causing Qt::black + { + w->setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QColorGroup::Button)); + w->setBackgroundMode( QWidget::NoBackground ); + goto kstpolish; + } + + if ( !isPlain() ) + { + if ( !isViewport && w->parent() && qstrcmp( w->parent() ->name(), "proxyview" ) == 0 ) + { + w->setBackgroundOrigin( QWidget::WindowOrigin ); + goto kstpolish ; + } + + if ( w->inherits( "PanelButtonBase" ) ) + goto kstpolish ; + if ( !isKicker&& !isViewport && !isViewportChild && !w->testWFlags( WType_Popup ) && !w->inherits( "KDesktop" ) && !w->inherits( "PasswordDlg" )) + { + if ( w->backgroundMode() == QWidget::PaletteBackground || w->backgroundMode() == QWidget::PaletteButton ) + { + w->setBackgroundOrigin( QWidget::WindowOrigin ); + } + } + } + if ( ::qt_cast(w) || ::qt_cast(w)) goto kstpolish; + if ( ::qt_cast(w)) + { +// if (optionHandler->SupportAppleBar() && w->isTopLevel()){ +// // QPalette pal(w->palette()); +// qWarning("resetting erase pixmap"); +// QColor c( w->palette().active().background() ); +// QPixmap stipple( 64, 64 ); +// stipple.fill( c.rgb() ); +// QPainter p; +// p.begin( &stipple ); +// p.setPen( c.dark( 100 + (int)(optionHandler->stippleContrast()/2) ) ); +// for (int i = 1; i < 64; i += 4 ) { +// p.drawLine( 0, i, 63, i ); +// p.drawLine( 0, i+2, 63, i+2 ); +// } +// p.setPen( c.dark( 100 + optionHandler->stippleContrast()) ); +// for ( int i = 2; i < 63; i += 4 ) { +// p.drawLine( 0, i, 63, i ); +// } +// p.end(); +// // QBrush brush( c, stipple ); +// // pal.setBrush( QColorGroup::Background, brush ); +// // w->setPalette( pal ); +// w->setErasePixmap(stipple); +// } + w->setBackgroundMode( QWidget::PaletteBackground ); + if (optionHandler->UseCustomMenuColor()) + { + QPalette pal( w->palette() ); + pal.setBrush( QColorGroup::Highlight, optionHandler->menuColorHigh() ); + pal.setBrush( QColorGroup::HighlightedText, optionHandler->textColorHigh() ); + w->setPalette( pal ); + } + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter( this ); +#if 0 + if (!::qt_cast(w)) + { + bool bold = w->font().bold(); + bool italic = w->font().italic(); + bool underline = w->font().underline(); + bool overline = w->font().overline(); + w->setFont(KGlobalSettings::menuFont()); + if (bold) + (const_cast(&w->font()))->setBold(true); + if (italic) + (const_cast(&w->font()))->setItalic(true); + if (underline) + (const_cast(&w->font()))->setUnderline(true); + if (overline) + (const_cast(&w->font()))->setOverline(true); + } +#endif + goto kstpolish ; + } + + if (::qt_cast(w)) + { + w->setBackgroundOrigin(QWidget::WindowOrigin); + if ( ::qt_cast(w)) + { + if (w->parentWidget() && w->parentWidget()->inherits("Kontact::Splash")) + goto kstpolish; + else if ( !isPlain() && !(w->inherits( "QTipLabel" ) || w->inherits( "KSystemTray" ))) + { + w->setBackgroundMode( QWidget::PaletteBackground ); + } + else if ( w->inherits( "QTipLabel" ) ) + { + w->setPalette( tooltipPalette ); + w->setBackgroundOrigin(QWidget::WidgetOrigin); + w->installEventFilter( this ); + } + } + if (qstrcmp( w->name(), "backdrop" ) == 0) //kscd + { + ((QFrame *)w)->setFrameShape(QFrame::LineEditPanel); + ((QFrame *)w)->setFrameShadow(QFrame::Sunken); + goto kstpolish; + } + if (w->inherits( "KWinInternal::TabBox" )) + { + uint opacity = 0.8*OPAQUE; + XChangeProperty(qt_xdisplay(), w->winId(), XInternAtom(qt_xdisplay(), OPACITY, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &opacity, 1L); + goto kstpolish; + } + else if (w->inherits( "KAnimWidget" )) + { + ((QFrame *)w)->setFrameShape(QFrame::NoFrame); + w->installEventFilter( this ); // the widget resets it's frameshape on mouseevents - looks crap! + goto kstpolish ; + } + else if (((QFrame *)w)->frameShape() >= QFrame::Box && ((QFrame *)w)->frameShape() <= QFrame::WinPanel){ + ((QFrame *)w)->setFrameShape(QFrame::StyledPanel); + goto kstpolish ; + } + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + + + if ( w->parentWidget() && ( ( ::qt_cast(w) && ::qt_cast(w->parentWidget())) || w->inherits( "KCompletionBox" ) ) ) { + QListBox* listbox = (QListBox*) w; + listbox->setBackgroundMode( NoBackground ); + w->installEventFilter( this ); + goto kstpolish; + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + + + if (::qt_cast(w)){ +// if (::qt_cast(w->parentWidget())) +// headerSortID = ((QListView*)w->parentWidget())->sortColumn(); +// if (w->parentWidget()) qWarning(w->parentWidget()->className()); + w->setBackgroundMode( NoBackground ); + w->installEventFilter( this ); + goto kstpolish; + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + + + if (::qt_cast(w)){ +// qWarning("installing tab event"); + w->setMouseTracking( true ); + w->installEventFilter( this ); + w->setBackgroundOrigin(QWidget::WindowOrigin); + goto kstpolish; + } + + if (::qt_cast(w) && ((QGroupBox*)w)->frameShape() == QFrame::GroupBoxPanel && !((QGroupBox*)w)->isFlat()) + { + if ( optionHandler->drawGroupBoxShadow() ) + { + w->setPaletteBackgroundPixmap ( *groupShadow ); + if (((QGroupBox*)w)->isCheckable()) + { + QWidget *cb = (QWidget*)w->child("qt_groupbox_checkbox",0,false); + cb->setPalette(w->parentWidget() ? w->parentWidget()->palette() : qApp->palette()); + QFont font( cb->font() ); + font.setBold( true ); + cb->setFont( font ); + } + } + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter(this); + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + + + if (w->inherits("QProgressBar")) + { + w->setBackgroundMode( NoBackground ); + w->installEventFilter(this); + connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*))); + goto kstpolish; + } + + if ( w->inherits( "QDockWindow" ) ) { + w->setBackgroundMode( QWidget::PaletteBackground ); + w->setBackgroundOrigin(QWidget::WindowOrigin); + w->installEventFilter( this ); + goto kstpolish ; + } + + if ( ::qt_cast(w)) { + QCursor tmpCursor(Qt::PointingHandCursor); + w->setCursor(tmpCursor); + w->installEventFilter( this ); + w->setBackgroundMode( QWidget::NoBackground ); + goto kstpolish ; + } + if ( w->inherits( "KdetvView")) { + w->setBackgroundMode( QWidget::NoBackground ); + } + //if (testWidget) qWarning("testwidget stage %d",testInt++); + kstpolish: KStyle::polish( w ); // nothing of all above? do default kde stuff +} + + + +void LiquidStyle::unPolish( QWidget *w ) { + + bool isViewport; + bool isViewportChild; + + // general - better than querying for each and ever widget if it got one... + w->removeEventFilter( this ); + + + if (w->inherits("KColorGrid")){ + goto kstunpolish; + } + + if ( w->inherits("QToolBar") || qstrcmp( w->name(), "kde toolbar widget" ) == 0 ) { + w->setBackgroundOrigin( QWidget::WidgetOrigin ); +// w->unsetPalette(); + goto kstunpolish; + } + if ( w->inherits( "QPopupMenu" ) ) { + w->unsetPalette(); + w->setBackgroundMode( QWidget::PaletteButton ); + w->removeEventFilter( this ); + XDeleteProperty (qt_xdisplay(), w->winId(), XInternAtom(qt_xdisplay(), OPACITY, False)); + goto kstunpolish; + } + if (::qt_cast(w) && w->isTopLevel()){ + XDeleteProperty (qt_xdisplay(), w->winId(), XInternAtom(qt_xdisplay(), OPACITY, False)); + goto kstunpolish; + } + if ( !isPlain () && w->inherits( "KonqIconViewWidget" ) || + w->inherits( "KHTMLView" ) ) { + w->unsetPalette(); + goto kstunpolish; + } + if (w->inherits("KateView") || w->inherits("TEWidget") || w->inherits("CHexViewWidget")){ +// w->setMouseTracking( false ); + goto kstunpolish; + } + + if (w->isA( "QViewportWidget" ) || w->inherits( "QClipperWidget" ) ) + goto kstunpolish; + + if ( !isPlain() ) { + if ( w->inherits( "KActiveLabel" ) || w->inherits( "QTipLabel" ) ) { + w->unsetPalette(); + goto kstunpolish; + } + /* + else if(w->inherits("KdmClock")){ + ; // Check this! + return; + }*/ + } + else if ( w->inherits( "QMenuBar" ) ) { + w->setBackgroundMode( QWidget::PaletteButton ); + if ( !isPlain() ) + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + goto kstunpolish; + }else if ( w->inherits( "QDockWindow" ) ) { + w->setBackgroundMode( QWidget::PaletteButton ); + if ( !isPlain() ) + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + goto kstunpolish; + } else if ( w->inherits( "QComboBox" ) || w->inherits( "QPushButton" ) ) { + if (w->inherits( "QPushButton" )) + { + ButtonFadeInfo *bfi_ = bfi[w->winId()]; + if (bfi_){ + if (bfi_->timerId != 0) + w->killTimer(bfi_->timerId); + bfi.setAutoDelete(TRUE); + bfi.remove(w->winId()); + } + } + w->setBackgroundMode( QWidget::PaletteButton ); + } else if ( w->inherits( "QScrollBar" ) ) { +// if (!w->isEnabled()) w->setEnabled(true); + w->setBackgroundMode( QWidget::PaletteBackground ); + goto kstunpolish; + } else if ( w->inherits( "QHeader" ) ) { + w->setMouseTracking( false ); + } + + if ( w->inherits( "QToolButton" ) ) { +// w->unsetPalette(); + w->setBackgroundMode( QWidget::PaletteButton ); + if ( !isPlain() ) + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + goto kstunpolish; + } + + isViewport = qstrcmp( w->name(), "qt_viewport" ) == 0 || + qstrcmp( w->name(), "qt_clipped_viewport" ) == 0; + isViewportChild = w->parent() && + ( ( qstrcmp( w->parent() ->name(), "qt_viewport" ) == 0 ) || + ( qstrcmp( w->parent() ->name(), "qt_clipped_viewport" ) == 0 ) ); + + if ( isViewportChild ) { + if ( w->inherits( "QRadioButton" ) || w->inherits( "QComboBox" ) || w->inherits( "QPushButton" ) ) { + if ( isHTMLWidget( w ) ) { + w->setBackgroundMode( QWidget::PaletteBackground ); + goto kstunpolish; + } + } + } + + if ( !isPlain() ) { + if ( !isViewport && w->parent() && qstrcmp( w->parent() ->name(), "proxyview" ) == 0 ) { + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + goto kstunpolish; + } + if ( w->ownPalette() && !w->inherits( "QButton" ) && !w->inherits( "QComboBox" ) ) + goto kstunpolish; + if ( w->inherits( "PanelButtonBase" ) ) + goto kstunpolish; + + if ( !isViewport && !isViewportChild && !w->testWFlags( WType_Popup ) && + !w->inherits( "KDesktop" ) && !w->inherits( "PasswordDlg" ) ) { + + if ( w->backgroundOrigin() == QWidget::WindowOrigin ) + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + goto kstunpolish; + } + } +kstunpolish: KStyle::unPolish( w ); + } diff --git a/style/utils.cpp b/style/utils.cpp new file mode 100644 index 0000000..dd24986 --- /dev/null +++ b/style/utils.cpp @@ -0,0 +1,1418 @@ +#include "baghira.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + + +#include "config.h" + +#ifndef CLAMP +#define CLAMP(x,l,u) x < l ? l :\ + x > u ? u :\ + x +#endif + +#define ALPHA_COLOR(A,R,G,B) \ + destR = ((A * destR) + (255 - A) * R) / 255; \ + destG = ((A * destG) + (255 - A) * G) / 255; \ + destB = ((A * destB) + (255 - A) * B) / 255; \ + A = 255; + +#define ALPHA_COLOR2(A1,A2,R,G,B) \ + destR = ((A1 * destR) + (255 - A1) * R) / 255; \ + destG = ((A1 * destG) + (255 - A1) * G) / 255; \ + destB = ((A1 * destB) + (255 - A1) * B) / 255; \ + A1 = CLAMP(A1 + A2,0,255); + +#define DELTA_COLOR(D,R,G,B) \ + delta = (255 - qRed(D))/2; \ + destR = R - delta; \ + destG = G - delta; \ + destB = B - delta; + +#define SATURATION_COLOR(R,G,B) \ + grey = (299 * R + 587 * G + 114 * B) / 1000; \ + delta = 255 - grey; \ + grey = (grey *(10 - 5)) / 10; \ + iGrey = 255 - grey;\ + destR = (iGrey * (srcR - delta) + grey * R) / 255; \ + destG = (iGrey * (srcG - delta) + grey * G) / 255; \ + destB = (iGrey * (srcB - delta) + grey * B) / 255; + +#define SATURATION_COLOR2(S,R,G,B) \ + int max = 255+(int)(0.65*(100-S)); \ + destR = CLAMP((srcR + R - 128), 0, max); \ + destG = CLAMP((srcG + G - 128), 0, max); \ + destB = CLAMP((srcB + B - 128), 0, max); \ + destR = (S*destR + (100-S)*R)/100; \ + destG = (S*destG + (100-S)*G)/100; \ + destB = (S*destB + (100-S)*B)/100; + +#define TINT_WHITE(S,R,G,B) \ + int max = 255+(int)(0.65*(100-S)); \ + destR = CLAMP((128 + R), 0, max); \ + destG = CLAMP((128 + G), 0, max); \ + destB = CLAMP((128 + B), 0, max); \ + destR = (S*destR + (100-S)*R)/100; \ + destG = (S*destG + (100-S)*G)/100; \ + destB = (S*destB + (100-S)*B)/100; + + +#define SATURATION_COLOR3(S,R,G,B) \ + destR = (S*(srcR + R - 128)/100 + R)/2; \ + destG = (S*(srcG + G - 128)/100 + G)/2; \ + destB = (S*(srcB + B - 128)/100 + B)/2; + +#define GM_COLOR(R,G,B)\ + destR = CLAMP(destR + R - 128, 0, 255);\ + destG = CLAMP(destG + G - 128, 0, 255);\ + destB = CLAMP(destB + B - 128, 0, 255); + + +#define COLOR_SPACE(R,G,B) \ + if ( R < 0 ) R = 0; else if ( R > 255 ) R = 255; \ + if ( G < 0 ) G = 0; else if ( G > 255 ) G = 255; \ + if ( B < 0 ) B = 0; else if ( B > 255 ) B = 255; + +#ifndef PRINTDEVICE +#define PRINTDEVICE(_p_) qWarning("device is %s", (_p_->device()->devType() == QInternal::Widget) ?\ +"Widget": (_p_->device()->devType() == QInternal::Pixmap) ?\ +"Pixmap": (_p_->device()->devType() == QInternal::Printer) ?\ +"Printer": (_p_->device()->devType() == QInternal::Picture) ?\ +"Picture": (_p_->device()->devType() == QInternal::UndefinedDevice) ?\ +"UndefinedDevice": "fuckdevice!" ); +#endif + +int LiquidStyle::getBrightness(unsigned int rgb) const { + int red = qRed( rgb ); + int green = qGreen( rgb ); + int blue = qBlue( rgb ); + int V = red; + if (green > V) V = green; + if (blue > V) V = blue; + return V; +} + +QPixmap* LiquidStyle::adjustHSV( QImage &img, const QColor &c, const QColor *bg ) const +{ + QImage * tmp = adjustHSVImage( img, c, bg ); + + QPixmap *pix = new QPixmap; + pix->convertFromImage( *tmp ); + delete tmp; + return ( pix ); +} + + +ButtonTile* LiquidStyle::createRoundFrameTile(QImage &img, const QColor &color, const QColor *bg, const QColor &baseColor ) const +{ + QColor bgColor( bg ? *bg : qApp->palette().active().background() ); + + if ( img.depth() != 32 ) + img = img.convertDepth( 32 ); + QImage *dest = new QImage( img.width(), img.height(), 32, 0 ); + dest->setAlphaBuffer( true ); + unsigned int *data = ( unsigned int * ) img.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = img.width() * img.height(); + int current; + int delta; + int red, green, blue, grey, iGrey; + int destR, destG, destB, alpha; + int x,y; + + int srcR = color.red(); + int srcG = color.green(); + int srcB = color.blue(); + + if (!optionHandler->IcyButtons()) + { + srcR += 20; + srcG += 20; + srcB += 20; + COLOR_SPACE(srcR, srcG, srcB); + } + + for ( current = 0 ; current < total ; ++current ) + { + alpha = qAlpha( data[ current ] ); + if (alpha) + { + if (optionHandler->IcyButtons()) + { + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + blue = qBlue( data[ current ] ); + SATURATION_COLOR(red, green, blue); + } + else + { + // the coloring itself + DELTA_COLOR(data[ current ], srcR, srcG, srcB); + } + } +#if 1 + if ( alpha && alpha != 255 ) + { + // only on translucent pixels - alphablending + y = (int)(current/img.width()); + x = current - y*img.width(); + if (red < 180 || x < 2 || y < 2 || y > img.height() - 2 || x > img.width() - 3) + { + ALPHA_COLOR(alpha, bgColor.red(), bgColor.green(), bgColor.blue()); + } + else + { + ALPHA_COLOR(alpha, baseColor.red(), baseColor.green(), baseColor.blue()); + } + } +#endif + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + QPixmap destPix; + destPix = *dest; + ButtonTile *ret = separateTiles( &destPix, 11, 10, 6, 1, 0, false); + delete dest; + return ret; +} + +QImage* LiquidStyle::adjustHSVImage( QImage &img, const QColor &c, const QColor *bg ) const +{ + QColor bgColor( bg ? *bg : qApp->palette().active().background() ); + + if ( img.depth() != 32 ) + img = img.convertDepth( 32 ); + QImage *dest = new QImage( img.width(), img.height(), 32, 0 ); + dest->setAlphaBuffer( true ); + unsigned int *data = ( unsigned int * ) img.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = img.width() * img.height(); + int current; + int delta; + int red, green, blue; + int destR, destG, destB, alpha; + + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + + + if (!optionHandler->IcyButtons()) + { + srcR += 20; + srcG += 20; + srcB += 20; + COLOR_SPACE(srcR, srcG, srcB); + } + + // float srcPercent, destPercent; + for ( current = 0 ; current < total ; ++current ) + { + alpha = qAlpha( data[ current ] ); + if (optionHandler->IcyButtons()) + { + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + blue = qBlue( data[ current ] ); + SATURATION_COLOR2(sq, red, green, blue); + } + else + { + // the coloring itself + DELTA_COLOR(data[ current ], srcR, srcG, srcB); + } + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +QImage* LiquidStyle::tintBrush( const QImage &img, const QColor &c ) const +{ +// if ( img.depth() != 32 ) +// img = img.convertDepth( 32 ); + QImage *dest = new QImage( img.width(), img.height(), 32, 0 ); + unsigned int *data = ( unsigned int * ) img.bits(); + unsigned int *destData = ( unsigned int* ) dest->bits(); + int total = img.width() * img.height(); + int current; + int delta; + int red, green, blue, grey, iGrey; + int destR, destG, destB, alpha; + + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + + // float srcPercent, destPercent; + for ( current = 0 ; current < total ; ++current ) + { + alpha = qAlpha( data[ current ] ); + blue = qBlue( data[ current ] ); + red = qRed( data[ current ] ); + green = qGreen( data[ current ] ); + SATURATION_COLOR(red, green, blue); + // force back to valid colorspace ! + COLOR_SPACE(destR, destG, destB); + destData[ current ] = qRgba( destR, destG, destB, alpha ); + } + return ( dest ); +} + +QColor LiquidStyle::brushedMetalColor(QColor &c) const +{ + if (optionHandler->TintBrush()) + { + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + int destR, destG, destB, grey, iGrey, delta; + SATURATION_COLOR(180, 180, 180); + COLOR_SPACE(destR, destG, destB); + return QColor(destR, destG, destB); + } + else + return QColor (180,180,180); +} + + + + +void LiquidStyle::clearImage( QImage &img ) const +{ + int x, y; + int w = img.width(); + int h = img.height(); + unsigned int pixel = qRgba( 0, 0, 0, 0 ); + unsigned int *data; + + for ( y = 0 ; y < h ; ++y ) + for ( data = (unsigned int *) img.scanLine( y ), x = 0 ; x < w ; data[ x++ ] = pixel ) ; + // img.fill( pixel ); +} + +void LiquidStyle::adjustHSV( QPixmap &pix, const QColor &c ) const +{ + QImage img = pix.convertToImage(); + QPixmap *result = adjustHSV( img, c); + pix = *result; + delete result; +} + + +/* buttons are fractioned to 9 parts. +w, h are width and height of the whole button. +xOff (yOff) is the distance of the central fraction from left (upper) button side. +centerW (centerH) is the width (height) of the central button fraction. +shadowH is the height of the buttons shadow*/ +ButtonTile* LiquidStyle::createButtonTile( const QColor &c, + const QColor &bgColor, + QImage *buttonImage, + QImage *shadowImage, + QImage *glowImage, + QIntDict*buttonDict, + QIntDict*shadowDict, + QIntDict*glowDict, + int w, int h, int xOff, int yOff, + int centerW, int centerH, + int shadowH, int glowWH, + bool sunken) const +{ + int x, y, delta; + int red, green, blue; + int destR, destG, destB, alpha; + bool rect = (buttonDict == &rectBtnDict); + + int hue, s, v; + c.getHsv( &hue, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + + int srcR = c.red(); + int srcG = c.green(); + int srcB = c.blue(); + + if (!optionHandler->IcyButtons()) + { + srcR += 20; + srcG += 20; + srcB += 20; + + COLOR_SPACE(srcR, srcG, srcB); + } + + unsigned int *data, *destData; + ButtonTile *tile; + + int shadowOverhead; + shadowH > glowWH ? shadowOverhead = shadowH - glowWH : shadowOverhead = 0; + QImage img( w + 2*glowWH, h + 2*glowWH + shadowOverhead, 32, 0 ); + img.setAlphaBuffer( !isPlain() || optionHandler->drawGroupBoxShadow() ? true : false); + clearImage( img ); + + // For unpressed buttons things are a little more complex. First + // we color adjust the shadow with the background color then we + // adjust the button to the button color. Finally we overlay the + // button on the shadow, (in the same loop as color adjusting). + // Technically we probably could of gotten away + // with just adjusting both the shadow and the button to the button + // color since the shadow is quite dark, but this is more correct and + // would allow configurable shadow brightness. If the shadow was + // just the button color, if someone configured it to be a rather + // light brightness, and they had a dark background color it wouldn't + // look right if based off the button color. + // + // Luckily this is only done once when the button is created for any + // given color ;-) + + // first do the shadow + if ((!sunken || optionHandler->buttonStyle() == Milk) && shadowImage) + for ( y = 0 ; y < h + shadowH ; ++y ) + { + data = ( unsigned int * ) shadowImage->scanLine( y ); + destData = ( unsigned int * ) img.scanLine( y + glowWH ); // glowWH is the yOffset -> distance of visable button to top of complete button + if (optionHandler->buttonStyle() == Jaguar) // has brighter shadows... + { + for ( x = 0 ; x < w ; ++x ) + if ((alpha = qAlpha( data[ x ] ))) + { + destData[ x + glowWH ] = qRgba( qRed(data[ x ]), qGreen(data[ x ]), qBlue(data[ x ]), alpha >> 1 ); + } + } + else + { + for ( x = 0 ; x < w ; ++x ) + if ((alpha = qAlpha( data[ x ] ))) + { + destData[ x + glowWH ] = data[x]; + } + } + } + // ... or the glow + else if (glowImage) + for ( y = 0 ; y < h + 2*glowWH ; ++y ) + { + data = ( unsigned int * ) glowImage->scanLine( y ); + destData = ( unsigned int * ) img.scanLine( y ); + for ( x = 0 ; x < w + 2*glowWH ; ++x ) + if ((alpha = qAlpha( data[ x ] ))) + { + DELTA_COLOR(data[ x ], srcR, srcG, srcB); + COLOR_SPACE(destR, destG, destB); + destData[ x ] = qRgba( destR, destG, destB, alpha ); + } + } + + // then the button and overlay + for ( y = 0 ; y < h ; ++y ) + { + data = ( unsigned int * ) buttonImage->scanLine( y ); + destData = ( unsigned int * ) img.scanLine( y + glowWH ); + for ( x = 0 ; x < w ; ++x ) + if ((alpha = qAlpha( data[ x ] ))) + { + if (!rect || (y > 1 && y < h-2 && x > 0 && x < w-1) ) + { + if (optionHandler->IcyButtons()) + { + red = qRed( data[ x ] ); + green = qGreen( data[ x ] ); + blue = qBlue( data[ x ] ); + SATURATION_COLOR2(sq, red, green, blue); + } + else + { + DELTA_COLOR(data[ x ], srcR, srcG, srcB); + } + } + else + { + red = qRed( data[ x ] ); + green = qGreen( data[ x ] ); + blue = qBlue( data[ x ] ); + TINT_WHITE(55, red, green, blue); + } + if (alpha != 255) + { + if ( qAlpha( destData[ x + glowWH ] ) ) + { + ALPHA_COLOR2(alpha, qAlpha( destData[ x + glowWH ] ), qRed( destData[ x + glowWH ]), qGreen( destData[ x + glowWH ]), qBlue( destData[ x + glowWH ])); + } + } + COLOR_SPACE(destR, destG, destB); + destData[ x + glowWH ] = qRgba( destR, destG, destB, alpha ); + } + } + + QPixmap *pix = new QPixmap; + pix->convertFromImage( img ); + tile = separateTiles( pix, xOff+glowWH, yOff+glowWH, centerW, centerH, shadowH, sunken); + + if ( sunken && glowDict) + glowDict->insert(c.rgb(),tile); + else if (!sunken && shadowDict) + shadowDict->insert( c.rgb(), tile ); + else + buttonDict->insert( c.rgb(), tile ); + + delete pix; + return ( tile ); +} + +QPixmap* LiquidStyle::createSliderEnd( const QColor &c, const QColor &bgColor, bool top) const +{ + + int x, y, delta; + int red, green, blue; + int destR, destG, destB, alpha; + + int h, s, v; + c.getHsv( &h, &s, &v ); + int sq = CLAMP((int)((45.0/128.0)*s+55),0,100); + + int srcR = bgColor.red(); + int srcG = bgColor.green(); + int srcB = bgColor.blue(); + + unsigned int *data, *destData; + + QImage img( 13, 9, 32, 0 ); + img.setAlphaBuffer( true ); // we need this always, as the slider groove is nevernever plain! + clearImage( img ); + + // just stole that from above... + // first do the shadow + for ( y = 0 ; y < 9 ; ++y ) { + top ? data = ( unsigned int * ) slider_top_shd->scanLine( y ) : data = ( unsigned int * ) slider_btm_shd->scanLine( y ); + destData = ( unsigned int * ) img.scanLine( y ); + for ( x = 0; x < 13; ++x ) + if ((alpha = qAlpha( data[ x ] ))) { + DELTA_COLOR(data[ x ], bgColor.red(), bgColor.green(), bgColor.blue()); + COLOR_SPACE(destR, destG, destB); + destData[ x ] = qRgba( destR, destG, destB, alpha ); + } + } + // then the button and overlay + + srcR = c.red(); + srcG = c.green(); + srcB = c.blue(); + + if (!optionHandler->IcyButtons()){ + srcR +=20; + srcG += 20; + srcB += 20; + + COLOR_SPACE(srcR, srcG, srcB); + } + + for ( y = 0 ; y < 7 ; ++y ) { + top ? data = ( unsigned int * ) slider_top->scanLine( y ) : data = ( unsigned int * ) slider_btm->scanLine( y ); + destData = ( unsigned int * ) img.scanLine( top ? y + 2 : y ); + for ( x = 0 ; x < 13 ; ++x ) + if ((alpha = qAlpha( data[ x ] ))) { + if (optionHandler->IcyButtons()) { + red = qRed( data[ x ] ); + green = qGreen( data[ x] ); + blue = qBlue( data[ x] ); + SATURATION_COLOR2(sq, red, green, blue); + } + else { + DELTA_COLOR(data[ x ], srcR, srcG, srcB); + } + if (alpha != 255) { + if ( qAlpha( destData[ x ] ) ) { + ALPHA_COLOR2(alpha, qAlpha( destData[ x ]), qRed( destData[ x ]), qGreen( destData[ x ]), qBlue( destData[ x ])); + } + } + COLOR_SPACE(destR, destG, destB); + destData[ x ] = qRgba( destR, destG, destB, alpha ); + } + } + QPixmap *pix = new QPixmap; + pix->convertFromImage( img ); + return ( pix ); +} + + + +// 0 / xO / xO + w +// ------------------------------------- +// | xO | w | width()-xO-w | : yO / 0 +// ------------------------------------- +// | xO | w | width()-xO-w | : h / yO +// ------------------------------------- +// | xO | w | width()-xO-w | : height()-yO-h / yO+h +// ------------------------------------- +// Overload of mosfet's original function, takes 6 more parameters to use the funktion on variable bitmaps (mosfet's function does only work for very special bitmaps) +// by giving position and dimension of the central tile + the shadow height (panther doesn't seem to have a right shadow-offset) +ButtonTile* LiquidStyle::separateTiles( QPixmap *pix, + int xO, int yO, int w, int h, + int, bool sunken) const +{ + ButtonTile * tile = new ButtonTile(); + QPixmap *tmp; + + int w1 = xO; + int w2 = w; + int w3 = pix->width() - xO - w; + int h1 = yO; + int h2 = h; + int h3 = pix->height() - yO - h; + + int xO1 = 0; + int xO2 = xO; + int xO3 = xO + w; + int yO1 = 0; + int yO2 = yO; + int yO3 = yO + h; + + if ( !sunken ) { + // Top tiles + tmp = new QPixmap( w1, h1 ); + // bitBlt(...,x,y,width,height) + copyBlt( tmp, 0, 0, pix, xO1, yO1, w1, h1 ); + tile->setPixmap( TileTopLeft, tmp ); + tmp = new QPixmap( w2, h1 ); + copyBlt( tmp, 0, 0, pix, xO2, yO1, w2, h1 ); + tile->setPixmap( TileTop, tmp ); + tmp = new QPixmap( w3, h1 ); + copyBlt( tmp, 0, 0, pix, xO3, yO1, w3, h1 ); + tile->setPixmap( TileTopRight, tmp ); + + // Middle tiles + tmp = new QPixmap( w1, h2 ); + copyBlt( tmp, 0, 0, pix, xO1, yO2, w1, h2 ); + tile->setPixmap( TileLeft, tmp ); + tmp = new QPixmap( w2, h2 ); + copyBlt( tmp, 0, 0, pix, xO2, yO2, w2, h2 ); + tile->setPixmap( TileMiddle, tmp ); + tmp = new QPixmap( w3, h2 ); + copyBlt( tmp, 0, 0, pix, xO3, yO2, w3, h2 ); + tile->setPixmap( TileRight, tmp ); + + // Bottom tiles + tmp = new QPixmap( w1, h3 ); + copyBlt( tmp, 0, 0, pix, xO1, yO3, w1, h3 ); + tile->setPixmap( TileBtmLeft, tmp ); + tmp = new QPixmap( w2, h3 ); + copyBlt( tmp, 0, 0, pix, xO2, yO3, w2, h3 ); + tile->setPixmap( TileBtm, tmp ); + tmp = new QPixmap( w3, h3 ); + copyBlt( tmp, 0, 0, pix, xO3, yO3, w3, h3 ); + tile->setPixmap( TileBtmRight, tmp ); + + } + else { + // Top tiles + tmp = new QPixmap( w1, h3 ); + // bitBlt(...,x,y,width,height) + copyBlt( tmp, 0, 0, pix, xO1, yO1, w1, h3 ); + tile->setPixmap( TileTopLeft, tmp ); + tmp = new QPixmap( w2, h3 ); + copyBlt( tmp, 0, 0, pix, xO2, yO1, w2, h3 ); + tile->setPixmap( TileTop, tmp ); + tmp = new QPixmap( w3, h3 ); + copyBlt( tmp, 0, 0, pix, xO3, yO1, w3, h3 ); + tile->setPixmap( TileTopRight, tmp ); + + // Middle tiles + tmp = new QPixmap( w1, h2 ); + copyBlt( tmp, 0, 0, pix, xO1, yO2 + h3 - h1, w1, h2 ); + tile->setPixmap( TileLeft, tmp ); + tmp = new QPixmap( w2, h2 ); + copyBlt( tmp, 0, 0, pix, xO2, yO2 + h3 - h1, w2, h2 ); + tile->setPixmap( TileMiddle, tmp ); + tmp = new QPixmap( w3, h2 ); + copyBlt( tmp, 0, 0, pix, xO3, yO2 + h3 - h1, w3, h2 ); + tile->setPixmap( TileRight, tmp ); + + // Bottom tiles + tmp = new QPixmap( w1, h1 ); + copyBlt( tmp, 0, 0, pix, xO1, yO3 + h3 - h1, w1, h1 ); + tile->setPixmap( TileBtmLeft, tmp ); + tmp = new QPixmap( w2, h1 ); + copyBlt( tmp, 0, 0, pix, xO2, yO3 + h3 - h1, w2, h1 ); + tile->setPixmap( TileBtm, tmp ); + tmp = new QPixmap( w3, h1 ); + copyBlt( tmp, 0, 0, pix, xO3, yO3 + h3 - h1, w3, h1 ); + tile->setPixmap( TileBtmRight, tmp ); + } + return ( tile ); +} + +#define _LOFF_ tile->pixmap( TileLeft )->width() +#define _ROFF_ tile->pixmap( TileRight )->width() +#define _TOFF_ tile->pixmap( TileTop )->height() +#define _BOFF_ tile->pixmap( TileBtm )->height() +#define _MWIDTH_ tile->pixmap( TileMiddle )->width() +#define _MHEIGHT_ tile->pixmap( TileMiddle )->height() +#define _LRWIDTH_ (_LOFF_ + _ROFF_) +#define _TBHEIGHT_ (_TOFF_ + _BOFF_) + +void LiquidStyle::drawRoundButton( QPainter *painter, const QColorGroup &cg, const QColor &c, int x, int y, int w, int h, bool pushedDown, bool hover, int bgX, int bgY ) const +{ + + QColor myC =(isOOO && (hover || pushedDown))?optionHandler->CustomButtonColor():c; + LiquidStyle *ptr = const_cast( this ); + ButtonTile *tile = pushedDown ? btnDict.find( myC.rgb() ) : btnShadowedDict.find( myC.rgb() ); + + if ( !tile ) + { + tile = createButtonTile( myC, qApp->palette().color(QPalette::Active, QColorGroup::Background), ptr->btnBorderImg, ptr->btnShadowImg, ptr->buttonGlow, &(ptr->btnDict), &(ptr->btnShadowedDict), &(ptr->buttonGlowDict), 37, 21, 10, 11, 17, 1, 2, 2, pushedDown); + } + + if ( !tile ) + { + qWarning( "Button tile is NULL!" ); + return ; + } + + QPainter *p; + QPen oldPen = painter->pen(); + if (!isHTMLButton) + { + if ( !tmpBtnPix ) + ptr->tmpBtnPix = new QPixmap( w, h ); + else if ( w > tmpBtnPix->width() || h > tmpBtnPix->height() ) + { + // make temp pixmap size == largest button + ptr->tmpBtnPix->resize(w,h); + } + p = new QPainter(tmpBtnPix); + + if (!isPlain()) + { + QPixmap *stipple; + if (paintWidget && paintWidget->parentWidget()) + { + stipple = const_cast(paintWidget->parentWidget()->palette().brush(QPalette::Active, QColorGroup::Background).pixmap()); + if (!stipple || stipple->isNull()) + p->fillRect(0,0,w,h, paintWidget->parentWidget()->palette().brush(QPalette::Active, QColorGroup::Background) ); + else + p->drawTiledPixmap( 0, 0, w, h, *stipple, bgX, bgY ); + } + else + { + stipple = cg.brush( QColorGroup::Background ).pixmap(); + stipple ? p->drawTiledPixmap( 0, 0, w, h, *stipple, bgX, bgY ) : + p->fillRect(0,0,w,h, cg.brush( QColorGroup::Background )); + } + } + else + p->fillRect(0,0,w,h, cg.brush( QColorGroup::Background )); + } + else + { + p = painter; + } + +// QPainter p(tmpBtnPix); + + // tiled fills + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( _LOFF_, 0, w - _LRWIDTH_, _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( _LOFF_, h - _BOFF_, w - _LRWIDTH_, _BOFF_, *tile->pixmap( TileBtm ) ); + } + if ( h > _TBHEIGHT_ ) + { + p->drawTiledPixmap( 0, _TOFF_, _LOFF_, h - _TBHEIGHT_, *tile->pixmap( TileLeft ) ); + p->drawTiledPixmap( w - _ROFF_, _TOFF_, _ROFF_, h - _TBHEIGHT_, *tile->pixmap( TileRight ) ); + } + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + p->drawTiledPixmap( _LOFF_, _TOFF_, w - _LRWIDTH_, h - _TBHEIGHT_, *tile->pixmap( TileMiddle ) ); + // corners + p->drawPixmap( 0, 0, *tile->pixmap( TileTopLeft ) ); + p->drawPixmap( w - _ROFF_, 0, *tile->pixmap( TileTopRight ) ); + p->drawPixmap( 0, h - _BOFF_, *tile->pixmap( TileBtmLeft ) ); + p->drawPixmap( w - _ROFF_, h - _BOFF_, *tile->pixmap( TileBtmRight ) ); + + if (!isHTMLButton) + { + p->end(); + delete p; + painter->drawPixmap( x, y, *tmpBtnPix, 0, 0, w, h ); + } + else + p->setPen(oldPen); +} + + +void LiquidStyle::drawRectangularButton( QPainter *painter, + const QColorGroup &cg, const QColor &c, + int x, int y, int w, int h, + bool sunken, bool hover, bool isCombo, int position, bool isHTML) const +{ +#define _HEIGHT_ ptr->rectbutton->height() +#define _WIDTH_ ptr->rectbutton->width() + LiquidStyle *ptr = const_cast( this ); + + QColor tmpColor; + tmpColor = isCombo && !(hover || sunken) ? optionHandler->InactiveButtonColor() : c; + + int xOffset, width; + int cw = 0; + + ButtonTile *tile = rectBtnDict.find( tmpColor.rgb() ); + if ( !tile ) + tile = createButtonTile( tmpColor, cg.background(), ptr->rectbutton, ((QImage*)0L), ((QImage*)0L), &(ptr->rectBtnDict), (QIntDict*)0L, (QIntDict*)0L, 33, 25, 10, 5, 13, 15, 0, 0, sunken); + + if ( !tile ) + { + qWarning( "Button tile is NULL!" ); + return ; + } + + switch (position) + { + case left: + xOffset = _LOFF_; + width = w - _LOFF_; + cw = 24; + break; + case center: + xOffset = 0; + width = w; + cw = 24; + break; + case right: + xOffset = 0; + width = w - _ROFF_; + cw = 24-_ROFF_; + break; + case full: + xOffset = _LOFF_; + width = w - _LRWIDTH_; + cw = 24-_ROFF_; + break; + } + + QPainter *p; + QPen oldPen = painter->pen(); + if (!isHTML) + { + if ( !tmpBtnPix ) + ptr->tmpBtnPix = new QPixmap( w, h ); + else if ( w > tmpBtnPix->width() || h > tmpBtnPix->height() ) + { + // make temp pixmap size == largest button + ptr->tmpBtnPix->resize(w,h); + } + p = new QPainter(tmpBtnPix); + + if (position != center && paintWidget && paintWidget->parentWidget()) + { + if (this->paintWidget->parentWidget()->paletteBackgroundPixmap ()) + p->drawTiledPixmap(QRect(0, 0, w, h), *this->paintWidget->parentWidget()->paletteBackgroundPixmap(), ((QWidget *)this->paintWidget)->backgroundOffset()); + else + p->fillRect( 0, 0, w, h, this->paintWidget->parentWidget()->paletteBackgroundColor()); + } + else + p->fillRect( 0, 0, w, h, cg.background() ); + } + else + { + p = painter; + } + + int tileH = 0; + QPixmap tmpPix(_LOFF_, 1); + + if (position == left || position == full) + { + p->drawPixmap( 0, 0, *tile->pixmap( TileTopLeft ) ); + p->drawPixmap( 0, h - _BOFF_, *tile->pixmap( TileBtmLeft ) ); + } + + if (!isCombo || hover || sunken) + { + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( xOffset, 0, width, _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( xOffset, h - _BOFF_, width, _BOFF_, *tile->pixmap( TileBtm ) ); + } + + if ( h > _TBHEIGHT_ ) + { + tileH = (int)((h-_HEIGHT_)/2); + if (position == left || position == full) + { + if (h > _HEIGHT_) + { + p->drawPixmap(0, _TOFF_+tileH, *tile->pixmap( TileLeft )); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 0, _LOFF_, 1 ); + p->drawTiledPixmap(0, _TOFF_, _LOFF_, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, _MHEIGHT_-1, _LOFF_, 1 ); + p->drawTiledPixmap(0, _TOFF_+tileH+_MHEIGHT_, _LOFF_, h-_HEIGHT_-tileH, tmpPix); + } + else //tileH is negative in this case + p->drawPixmap( 0, _TOFF_, *tile->pixmap( TileLeft ), 0, -tileH, _LOFF_, _MHEIGHT_+2*tileH+1); + } + if (position == right || position == full) + { + if (h > _HEIGHT_) + { + tmpPix.resize(_ROFF_, 1); + p->drawPixmap(w-_ROFF_, _TOFF_+tileH, *tile->pixmap( TileRight )); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 0, _ROFF_, 1 ); + p->drawTiledPixmap(w-_ROFF_, _TOFF_, _ROFF_, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, _MHEIGHT_-1, _ROFF_, 1 ); + p->drawTiledPixmap(w-_ROFF_, _TOFF_+tileH+_MHEIGHT_, _ROFF_, h-_HEIGHT_-tileH, tmpPix); + } + else + p->drawPixmap( w-_ROFF_, _TOFF_, *tile->pixmap(TileRight), 0, -tileH, _ROFF_, _MHEIGHT_+2*tileH+1 /*tileH is negative in this case*/ ); + } + } + + + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + { + if (h > _HEIGHT_) + { + tmpPix.resize(_MWIDTH_, 1); + p->drawTiledPixmap(xOffset, _TOFF_+tileH, width, _MHEIGHT_, *tile->pixmap(TileMiddle)); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, _MWIDTH_, 1 ); + p->drawTiledPixmap(xOffset, _TOFF_, width, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, _MHEIGHT_-1, _MWIDTH_, 1 ); + p->drawTiledPixmap(xOffset, _TOFF_+tileH+_MHEIGHT_, width, h-_HEIGHT_-tileH, tmpPix); + } + else //tileH is negative in this case + p->drawTiledPixmap( xOffset, _TOFF_, width, h-_TBHEIGHT_, *tile->pixmap(TileMiddle), 0, -tileH); + } + + + if (position == right || position == full) + { + p->drawPixmap( w - _ROFF_, 0, *tile->pixmap( TileTopRight ) ); + p->drawPixmap( w - _ROFF_, h - _BOFF_, *tile->pixmap( TileBtmRight ) ); + } + + } + else // split combo... + { + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( xOffset, 0, width-(24-_ROFF_), _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( xOffset, h - _BOFF_, width-(24-_ROFF_), _BOFF_, *tile->pixmap( TileBtm ) ); + } + if ( h > _TBHEIGHT_) + { + tileH = (int)((h-_HEIGHT_)/2); + if (position == left || position == full) + { + if (h > _HEIGHT_) + { + tmpPix.resize(_LOFF_, 1); + p->drawPixmap(0, _TOFF_+tileH, *tile->pixmap( TileLeft )); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, 0, _LOFF_, 1 ); + p->drawTiledPixmap(0, _TOFF_, _LOFF_, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileLeft), 0, _MHEIGHT_-1, _LOFF_, 1 ); + p->drawTiledPixmap(0, _TOFF_+tileH+_MHEIGHT_, _LOFF_, h-_HEIGHT_-tileH, tmpPix); + } + else //tileH is negative in this case + p->drawPixmap( 0, _TOFF_, *tile->pixmap( TileLeft ), 0, -tileH, _LOFF_, _MHEIGHT_+2*tileH+1); + } + } + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + { + if (h > _HEIGHT_) + { + tmpPix.resize(_MWIDTH_, 1); + p->drawTiledPixmap(xOffset, _TOFF_+tileH, width-(24-_ROFF_), _MHEIGHT_, *tile->pixmap(TileMiddle)); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, _MWIDTH_, 1 ); + p->drawTiledPixmap(xOffset, _TOFF_, width-(24-_ROFF_), tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, _MHEIGHT_-1, _MWIDTH_, 1 ); + p->drawTiledPixmap(xOffset, _TOFF_+tileH+_MHEIGHT_, width-(24-_ROFF_), h-_HEIGHT_-tileH, tmpPix); + } + else //tileH is negative in this case + p->drawTiledPixmap( xOffset, _TOFF_, width-(24-_ROFF_), h-_TBHEIGHT_, *tile->pixmap(TileMiddle), 0, -tileH); + } + + // second part of combos if needed + tile = rectBtnDict.find( c.rgb() ); + if ( !tile ) + tile = createButtonTile( c, cg.background(), ptr->rectbutton, ((QImage*)0L), ((QImage*)0L), &(ptr->rectBtnDict), (QIntDict*)0L, (QIntDict*)0L, 33, 25, 10, 5, 13, 15, 0, 0, sunken); + if ( !tile ) + { + qWarning( "Button tile is NULL!" ); + return ; + } + + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( w-24, 0, cw, _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( w-24, h - _BOFF_, cw, _BOFF_, *tile->pixmap( TileBtm ) ); + } + + tileH = (int)((h-_HEIGHT_)/2); + if (position == right || position == full) + { + if (h > _HEIGHT_) + { + tileH = (int)((h-_HEIGHT_)/2); + tmpPix.resize(_ROFF_, 1); + p->drawPixmap(w-_ROFF_, _TOFF_+tileH, *tile->pixmap( TileRight )); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, 0, _ROFF_, 1 ); + p->drawTiledPixmap(w-_ROFF_, _TOFF_, _ROFF_, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileRight), 0, _MHEIGHT_-1, _ROFF_, 1 ); + p->drawTiledPixmap(w-_ROFF_, _TOFF_+tileH+_MHEIGHT_, _ROFF_, h-_HEIGHT_-tileH, tmpPix); + } + else if ( h > _TBHEIGHT_)//tileH is negative in this case + { + tileH = (int)((h-_HEIGHT_)/2); + p->drawPixmap( w-_ROFF_, _TOFF_, *tile->pixmap( TileRight ), 0, -tileH, _ROFF_, _MHEIGHT_+2*tileH+1); + } + p->drawPixmap( w - _ROFF_, 0, *tile->pixmap( TileTopRight ) ); + p->drawPixmap( w - _ROFF_, h - _BOFF_, *tile->pixmap( TileBtmRight ) ); + } + + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + { + if (h > _HEIGHT_) + { + tmpPix.resize(_MWIDTH_, 1); + p->drawTiledPixmap(w-24, _TOFF_+tileH, cw, _MHEIGHT_, *tile->pixmap(TileMiddle)); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, 0, _MWIDTH_, 1 ); + p->drawTiledPixmap(w-24, _TOFF_, cw, tileH, tmpPix); + copyBlt( &tmpPix, 0, 0, tile->pixmap(TileMiddle), 0, _MHEIGHT_-1, _MWIDTH_, 1 ); + p->drawTiledPixmap(w-24, _TOFF_+tileH+_MHEIGHT_, cw, h-_HEIGHT_-tileH, tmpPix); + } + else //tileH is negative in this case + p->drawTiledPixmap( w-24, _TOFF_, cw, h-_TBHEIGHT_, *tile->pixmap(TileMiddle), 0, -tileH); + } + } + if (position == center) + { + p->setPen(c.dark(130)); + if (sunken || hover) p->drawLine(0,1,0,h-2); + p->drawLine(w-1,2,w-1,h-2); + } + else if (position == left) + { + p->setPen(c.dark(130)); + p->drawLine(w-1,2,w-1,h-2); + } + else if (position == right && (sunken || hover)) + { + p->setPen(c.dark(130)); + p->drawLine(0,2,0,h-2); + } + if (isCombo) + { + p->setPen(c); + p->drawLine(w-24,2,w-24,h-2); + + int ax = w - 15; + int ay = h/3 - 1; + + p->setPen(cg.text()); + p->setBrush( cg.text() ); + p->drawPixmap(ax, ay-1, *sbUp, 1, 0, 5, 4); + p->drawPixmap(ax, ay+6, *sbDown, 1, 2, 5, 4); + } + if (!isHTML) + { + p->end(); + delete p; + painter->drawPixmap( x, y, *tmpBtnPix, 0, 0, w, h ); + } + else + p->setPen(oldPen); +#undef _HEIGHT_ +#undef _WIDTH_ +} + + +void LiquidStyle::drawCombo( QPainter *painter, + const QColorGroup &cg, + const QColor &c, + int x, int y, int w, int h, + bool sunken, bool hover, bool isCombo, + int position, bool isHTML ) const +{ + + LiquidStyle *ptr = const_cast( this ); + + QColor myC =(isOOO && isCombo)?optionHandler->CustomButtonColor():c; + QColor tmpColor = isCombo && !(hover || sunken) ? optionHandler->InactiveButtonColor() : myC; + + ButtonTile *tile = sunken ? comboDict.find( tmpColor.rgb() ) : comboShadowedDict.find( tmpColor.rgb() ); + if ( !tile ) + { + if (optionHandler->buttonStyle() == Milk && sunken) + tile = createButtonTile( tmpColor, cg.background(), ptr->btnBorderImg, ptr->comboShadow, ((QImage*)0L), &(ptr->comboDict), &(ptr->comboShadowedDict), (QIntDict*)0L, 44, 21, 7, 9, 30, 1, 2, 0, true); + else + tile = createButtonTile( tmpColor, cg.background(), ptr->combo, ptr->comboShadow, ((QImage*)0L), &(ptr->comboDict), &(ptr->comboShadowedDict), (QIntDict*)0L, 44, 21, 7, 9, 30, 1, 2, 0, sunken); + } + + if ( !tile ) + { + qWarning( "Button tile is NULL!" ); + return ; + } + + int xOffset, width, cw; + + switch (position) + { + case full: + xOffset = _LOFF_; + width = w - _LRWIDTH_; + cw = 24 - _ROFF_; + break; + case left: + xOffset = _LOFF_; + width = w - _LOFF_; + cw = 24; + break; + case center: + xOffset = 0; + width = w; + cw = 24; + break; + case right: + xOffset = 0; + width = w - _ROFF_; + cw = 24 - _ROFF_; + break; + } + + QPainter *p; + QPen oldPen = painter->pen(); + if (!isHTML) + { + if ( !tmpBtnPix ) + ptr->tmpBtnPix = new QPixmap( w, h ); + else if ( w > tmpBtnPix->width() || h > tmpBtnPix->height() ) + { + // make temp pixmap size == largest button + ptr->tmpBtnPix->resize(w,h); + } + p = new QPainter(tmpBtnPix); + +#if 0 + QPixmap *stipple = cg.brush( QColorGroup::Background ).pixmap(); + if ( !stipple ) // button may have custom colorgroup + stipple = qApp->palette().active().brush( QColorGroup::Background ).pixmap(); + if ( stipple ) + p->drawTiledPixmap( 0, 0, w, h, *stipple); + else + p->fillRect( 0, 0, w, h, cg.background() ); +#endif + if (position != center && paintWidget && paintWidget->parentWidget()) + { + if (this->paintWidget->parentWidget()->paletteBackgroundPixmap ()) + p->drawTiledPixmap(QRect(0, 0, w, h), *this->paintWidget->parentWidget()->paletteBackgroundPixmap(), ((QWidget *)this->paintWidget)->backgroundOffset()); + else + p->fillRect( 0, 0, w, h, this->paintWidget->parentWidget()->paletteBackgroundColor()); + } + else + p->fillRect( 0, 0, w, h, cg.background() ); + } + else + { + p = painter; + } + + if (position == left || position == full) + { + p->drawPixmap( 0, 0, *tile->pixmap( TileTopLeft ) ); + p->drawPixmap( 0, h - _BOFF_, *tile->pixmap( TileBtmLeft ) ); + } + + if (!isCombo || hover || sunken) + { + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( xOffset, 0, width, _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( xOffset, h - _BOFF_, width, _BOFF_, *tile->pixmap( TileBtm ) ); + } + if ( h > _TBHEIGHT_ ) + { + if (position == left || position == full) + p->drawTiledPixmap( 0, _TOFF_, _LOFF_, h - _TBHEIGHT_, *tile->pixmap( TileLeft ) ); + if (position == right || position == full) + p->drawTiledPixmap( w - _ROFF_, _TOFF_, _ROFF_, h - _TBHEIGHT_, *tile->pixmap( TileRight ) ); + } + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + p->drawTiledPixmap( xOffset, _TOFF_, width, h - _TBHEIGHT_, *tile->pixmap( TileMiddle ) ); + if (position == right || position == full) + { + p->drawPixmap( w - _ROFF_, 0, *tile->pixmap( TileTopRight ) ); + p->drawPixmap( w - _ROFF_, h - _BOFF_, *tile->pixmap( TileBtmRight ) ); + } + } + else // split combo... + { + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( xOffset, 0, width-(24 - _ROFF_), _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( xOffset, h - _BOFF_, width-(24 - _ROFF_), _BOFF_, *tile->pixmap( TileBtm ) ); + } + if ( h > _TBHEIGHT_ && (position == left || position == full)) + p->drawTiledPixmap( 0, _TOFF_, _LOFF_, h - _TBHEIGHT_, *tile->pixmap( TileLeft ) ); + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + p->drawTiledPixmap( xOffset, _TOFF_, width-(24 - _ROFF_), h - _TBHEIGHT_, *tile->pixmap( TileMiddle ) ); + + // second part of combos if needed + tile = comboShadowedDict.find( myC.rgb() ); + if ( !tile ) + { + tile = createButtonTile( myC, cg.background(), ptr->combo, ptr->comboShadow, ((QImage*)0L), &(ptr->comboDict), &(ptr->comboShadowedDict), (QIntDict*)0L, 44, 21, 7, 9, 30, 1, 2, 0, sunken); + } + if ( !tile ) + { + qWarning( "Button tile is NULL!" ); + return ; + } + if ( w > _LRWIDTH_ ) + { + p->drawTiledPixmap( w-24, 0, cw, _TOFF_, *tile->pixmap( TileTop ) ); + p->drawTiledPixmap( w-24, h - _BOFF_, cw, _BOFF_, *tile->pixmap( TileBtm ) ); + } + if ( h > _TBHEIGHT_ ) + p->drawTiledPixmap( w - _ROFF_, _TOFF_, _ROFF_, h - _TBHEIGHT_, *tile->pixmap( TileRight ) ); + if ( w > _LRWIDTH_ && h > _TBHEIGHT_ ) + p->drawTiledPixmap( w-24, _TOFF_, cw, h - _TBHEIGHT_, *tile->pixmap( TileMiddle ) ); + if (position == right || position == full) + { + p->drawPixmap( w - _ROFF_, 0, *tile->pixmap( TileTopRight ) ); + p->drawPixmap( w - _ROFF_, h - _BOFF_, *tile->pixmap( TileBtmRight ) ); + } + } + + switch (position) + { + case left: + p->setPen(optionHandler->InactiveButtonColor().dark(130)); + p->drawLine(w-1,3,w-1,h-6); + break; + case center: + p->setPen(optionHandler->InactiveButtonColor().dark(130)); + if (sunken || hover) p->drawLine(0,3,0,h-6); + p->drawLine(w-1,3,w-1,h-6); + break; + case right: + if (sunken || hover) + { + p->setPen(optionHandler->InactiveButtonColor().dark(130)); + p->drawLine(0,3,0,h-6); + } + break; + default: + break; + } + + if (isCombo) + { + p->setPen(c); + p->drawLine(w-24,1,w-24,h-4); + + int ax = w - 15; + int ay = h/3 - 1; + + p->setPen(cg.text()); + p->setBrush( cg.text() ); + p->drawPixmap(ax, ay-1, *sbUp, 1, 0, 5, 4); + p->drawPixmap(ax, ay+6, *sbDown, 1, 2, 5, 4); + } + + if (!isHTML) + { + p->end(); + delete p; + painter->drawPixmap( x, y, *tmpBtnPix, 0, 0, w, h ); + } + else + p->setPen(oldPen); +} + +void LiquidStyle::drawRoundFrame( QPainter *p, const QRect &r, + const QColorGroup &cg, bool focused, QPoint offset ) const +{ + ButtonTile *tile = focused ? activeRoundFrame : inactiveRoundFrame; + if (!tile) tile = createRoundFrameTile(*roundFrame, focused ? cg.button() : optionHandler->InactiveButtonColor(), &cg.background(), cg.base() ); + + // first: fill background (tiled) + // outer + QPixmap *stipple = cg.brush( QColorGroup::Background ).pixmap(); + if (stipple) + { + p->drawTiledPixmap( r.x(),r.y(), 7, 8, *stipple, offset.x(), offset.y()); + p->drawTiledPixmap( r.right() - 7, r.y(), 8, 8, *stipple, offset.x()+r.width()-6, offset.y()); + p->drawTiledPixmap( r.x(), r.bottom()-7, 8, 8, *stipple, offset.x(), offset.y() + r.height()-6); + p->drawTiledPixmap( r.right() - 7, r.bottom()-7, 8, 8, *stipple, offset.x() + r.width() - 6, offset.y() + r.height()-6); + } + else + { + p->fillRect(r.x(),r.y(), 7, 8, cg.background()); + p->fillRect(r.right() - 7, r.y(), 8, 8, cg.background()); + p->fillRect(r.x(), r.bottom()-7, 8, 8, cg.background()); + p->fillRect(r.right() - 7, r.bottom()-7, 8, 8, cg.background()); + } + // inner + p->fillRect(r.x()+3,r.y()+4,r.width()-6,r.height()-7,cg.base()); + + // now draw frame + p->drawPixmap(0,0, *tile->pixmap( TileTopLeft )); + p->drawPixmap(r.right()-10,0, *tile->pixmap( TileTopRight )); + p->drawPixmap(0,r.bottom()-10, *tile->pixmap( TileBtmLeft )); + p->drawPixmap(r.right()-10,r.bottom()-10, *tile->pixmap( TileBtmRight )); + if (r.width() > 22) + { + p->drawTiledPixmap(11,0,r.width()-22,10, *tile->pixmap( TileTop )); + p->drawTiledPixmap(11,r.bottom()-10,r.width()-22,11, *tile->pixmap( TileBtm )); + } + if (r.height() > 21) + { + p->drawTiledPixmap(0,10,11,r.height()-21, *tile->pixmap( TileLeft )); + p->drawTiledPixmap(r.right()-10,10,11,r.height()-21, *tile->pixmap( TileRight )); + } + if (focused) + { + p->setPen(cg.button()); + p->drawLine(r.x()+8,r.bottom()-1,r.right()-8,r.bottom()-1); + } +} + +void LiquidStyle::drawEditFrame( QPainter *p, const QRect &r, + const QColorGroup &cg, bool isHTML, bool focused, bool inverse ) const +{ + QColor fill( cg.background().dark( 105 ) ); + QColor tmp(0,0,0); + QColor light1( 0, 0, 0 ); + QColor light2( 0, 0, 0 ); + + QColor dark1( 0, 0, 0 ); + QColor dark2( 0, 0, 0 ); + QColor dark3( 0, 0, 0 ); + + if ( !focused ) + { + if (optionHandler->style() == Brushed) + { + light1 = cg.background().light( 140 ); + light2 = cg.background().light( 120 ); + } + else + { + light1 = cg.background().dark( 115 ); + light2 = cg.background().dark( 120 ); + } + + dark1 = cg.background().dark( 140 ); + dark2 = cg.background().dark( 160 ); + dark3 = cg.background().dark( 200 ); + } + else + { + int h,s,v; + cg.button().getHsv( &h, &s, &v ); + tmp.setHsv(h, (int)(s/1.5) ,v); + light1 = tmp; + light2 = tmp.light( 120 ); + + dark1 = tmp.dark( 110 ); + dark2 = tmp.dark( 120 ); + dark3 = tmp.dark( 140 ); + } + + int x = r.x(); + int y = inverse ? r.bottom() - 1: r.y(); + int right = r.right(); + int bottom = inverse ? r.y() + 1 : r.bottom(); + + if ( !isHTML ) + { + p->setPen( fill ); + p->drawPoint( x, y ); + p->drawPoint( x, bottom ); + p->drawPoint( right, y ); + p->drawPoint( right, bottom ); + + // outer rect + // top + p->setPen( light1 ); + p->drawPoint( x + 1, y ); + p->drawPoint( right - 1, y ); + p->drawPoint( x, y + 1 ); + p->drawPoint( right, y + 1 ); + // bottom + p->drawPoint( x, bottom - 1 ); + p->drawPoint( right, bottom - 1 ); + p->drawPoint( x + 1, bottom ); + p->drawPoint( right - 1, bottom ); + // top + focused ? p->setPen( light2 ) : p->setPen( dark1 ); + p->drawLine( x + 2, y, right - 2, y ); + // bottom, left and right + if (!focused) p->setPen( light2 ); + p->drawLine( x, y + 2, x, bottom - 2 ); + p->drawLine( right, y + 2, right, bottom - 2 ); + if (!focused) p->setPen( light1 ); + p->drawLine( x + 2, bottom, right - 2, bottom ); + } + else + { + p->setPen( light2 ); + p->drawLine( x, y, right, y ); + p->drawLine( x, y, x, bottom ); + p->setPen( dark1 ); + p->drawLine( x, bottom, right, bottom ); + p->drawLine( right, y, right, bottom ); + } + // inner rect + p->setPen( dark1 ); + p->drawPoint( x + 1, y + 1 ); + p->drawPoint( x + 1, bottom - 1 ); + p->drawPoint( right - 1, y + 1 ); + p->drawPoint( right - 1, bottom - 1 ); + p->drawLine( x + 2, bottom - 1, right - 2, bottom - 1 ); + p->setPen( dark3 ); + p->drawLine( x + 2, y + 1, right - 2, y + 1 ); + p->setPen( dark2 ); + p->drawLine( x + 1, y + 2, x + 1, bottom - 2 ); + p->drawLine( right - 1, y + 2, right - 1, bottom - 2 ); +} + +bool LiquidStyle::isHTMLWidget( const QWidget *widget ) const +{ + const QObject * w = widget->parent(); + if ( w ) + { + if ( !w->inherits( "QClipperWidget" ) ) + return ( false ); + w = w->parent(); + if ( w ) + { + w = w->parent(); + if ( w && w->inherits( "KHTMLView" ) ) + return ( true ); + } + } + return ( false ); +} + +void LiquidStyle::drawHTMLCBBorder( const QPixmap &pix, const QColor &c ) const +{ + QPainter p; + p.begin( &pix ); + p.setPen( c.dark( 200 ) ); + p.drawRect( 0, 0, 16, 16 ); + p.end(); +} diff --git a/subdirs b/subdirs new file mode 100644 index 0000000..b745c8e --- /dev/null +++ b/subdirs @@ -0,0 +1,11 @@ +bab +colorscheme +config +deco +icons +kickermenu +kickermenu-3.3 +sessionapplet +sidebar +starter +style