From e72a3fe21a157985ec56f45f4f95197935bf4c12 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 12:39:06 +0530 Subject: [PATCH 01/53] ... --- session.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.vim b/session.vim index 83336b5993..4ded6d1bf3 100644 --- a/session.vim +++ b/session.vim @@ -2,7 +2,7 @@ let $PYFLAKES_BUILTINS = "_,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext" " Include directories for C modules -let g:syntastic_c_include_dirs = [ '/usr/include/podofo'] +let g:syntastic_cpp_include_dirs = [ '/usr/include/podofo'] fun! CalibreLog() " Setup buffers to edit the calibre changelog and version info prior to From 866a489eb220f978cc55342c907b857eb7f9837f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 14:07:12 +0530 Subject: [PATCH 02/53] ... --- src/calibre/gui2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 4f0463417b..30588a8866 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -719,9 +719,9 @@ qt_app = None class Application(QApplication): def __init__(self, args): + self.file_event_hook = None qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args] QApplication.__init__(self, qargs) - self.file_event_hook = None global gui_thread, qt_app gui_thread = QThread.currentThread() self._translator = None From 41502a9c49bb9493c63b123ba9278776f28f13fb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 16:26:53 +0530 Subject: [PATCH 03/53] ... --- src/calibre/gui2/preferences/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py index 4a4eaa2bad..66c3cd8e51 100644 --- a/src/calibre/gui2/preferences/main.py +++ b/src/calibre/gui2/preferences/main.py @@ -210,6 +210,7 @@ class Preferences(QMainWindow): self.wizard_button.setIcon(QIcon(I('wizard.png'))) self.wizard_button.clicked.connect(self.run_wizard, type=Qt.QueuedConnection) + self.bb.button(self.bb.Close).setDefault(True) self.cw.layout().addWidget(self.bb) self.bb.rejected.connect(self.close, type=Qt.QueuedConnection) self.setCentralWidget(self.cw) From 415f08afd9a10455e0cb7fdd89f7835b742e31cb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 20:11:19 +0530 Subject: [PATCH 04/53] Ad QT Curve to the windows and OS X builds --- setup/installer/osx/app/main.py | 4 ++++ setup/installer/windows/freeze.py | 9 +++++++++ setup/installer/windows/notes.rst | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/setup/installer/osx/app/main.py b/setup/installer/osx/app/main.py index 2cf7e1df48..b7eb864de0 100644 --- a/setup/installer/osx/app/main.py +++ b/setup/installer/osx/app/main.py @@ -296,6 +296,10 @@ class Py2App(object): self.add_qt_framework(f) for d in glob.glob(join(SW, 'qt', 'plugins', '*')): shutil.copytree(d, join(self.contents_dir, 'MacOS', basename(d))) + sty = join(self.contents_dir, 'MacOS', 'styles') + os.mkdir(sty) + shutil.copyfile(glob.glob(join(SW, 'build', 'QtCurve*', 'build', 'style', + 'qtcurve.so'))[-1], join(sty, 'qtcurve.dylib')) for l in glob.glob(join(self.contents_dir, 'MacOS', '*/*.dylib')): self.fix_dependencies_in_lib(l) x = os.path.relpath(l, join(self.contents_dir, 'MacOS')) diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py index 448d888505..dc331699f3 100644 --- a/setup/installer/windows/freeze.py +++ b/setup/installer/windows/freeze.py @@ -16,6 +16,7 @@ from setup.installer.windows.wix import WixMixIn OPENSSL_DIR = r'Q:\openssl' QT_DIR = 'Q:\\Qt\\4.8.1' QT_DLLS = ['Core', 'Gui', 'Network', 'Svg', 'WebKit', 'Xml', 'XmlPatterns'] +QTCURVE = r'C:\plugins\styles' LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' SW = r'C:\cygwin\home\kovid\sw' IMAGEMAGICK = os.path.join(SW, 'build', 'ImageMagick-6.7.6', @@ -247,6 +248,14 @@ class Win32Freeze(Command, WixMixIn): if os.path.exists(tg): shutil.rmtree(tg) shutil.copytree(imfd, tg) + self.info('\nAdding QtCurve...') + qtcurve = self.j(QTCURVE, 'qtcurve.dll') + tg = self.j(tdir, 'styles') + if os.path.exists(tg): + shutil.rmtree(tg) + os.mkdir(tg) + shutil.copy2(qtcurve, tg) + for dirpath, dirnames, filenames in os.walk(tdir): for x in filenames: if not x.endswith('.dll'): diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index 7fe978d30b..349141d658 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -101,6 +101,14 @@ Now, run configure and make:: Add the path to the bin folder inside the Qt dir to your system PATH. +Now build QtCurve +cd qmake +edit the qmake.pro file setting the TARGET to Release + +qmake && nmake + +The plugin will be in c:\plugins\styles + SIP ----- From fc97864a2d788837923fa6658ba6914c0771157f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 20:14:12 +0530 Subject: [PATCH 05/53] Rabble.ca by timtoo --- recipes/rabble_ca.recipe | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 recipes/rabble_ca.recipe diff --git a/recipes/rabble_ca.recipe b/recipes/rabble_ca.recipe new file mode 100644 index 0000000000..6c19d39f5b --- /dev/null +++ b/recipes/rabble_ca.recipe @@ -0,0 +1,51 @@ +from calibre.web.feeds.news import BasicNewsRecipe +import re + +class RabbleCa(BasicNewsRecipe): + title = u'Rabble.ca' + __author__ = 'timtoo' + language = 'en_CA' + oldest_article = 7 + max_articles_per_feed = 100 + + cover_url = 'https://upload.wikimedia.org/wikipedia/en/4/44/Rabble.png' + masthead_url = 'http://rabble.ca/sites/rabble/files/dreamyrabble_logo.jpg' + + feeds = [(u'Rabble.ca', u'http://feeds.feedburner.com/rabble-news')] + + preprocess_regexps = [ + (re.compile(r'.*?to post comments', re.DOTALL|re.IGNORECASE), + lambda match: 'Tags:'), + ] + + extra_css = """ + .print-taxonomy { display: inline } + .print-taxonomy ul { display: inline; margin: 0px } + .print-taxonomy ul li { display: inline; list-style: none } + .field-type-date div { display: inline } + .field-type-link div { display: inline } + .field-type-text div { display: inline } + .field-label { font-style: italic } + """ + + def print_version(self, url): + return url.replace('http://rabble.ca/', 'http://rabble.ca/print/') + + remove_tags = [ + # print version of the web page + dict(name='div', attrs={'class': ['print-logo']}), + dict(name='div', attrs={'class': ['print-site_name']}), + dict(name='hr', attrs={'class': ['print-hr']}), + dict(name='div', attrs={'class': ['print-links']}), + + # regular web page in case you need to download them + dict(name='div', attrs={'id': ['header']}), + dict(name='div', attrs={'class': ['container-submenu']}), + dict(name='div', attrs={'id': ['sidebar']}), + dict(name='div', attrs={'id': ['footer']}), + dict(name='div', attrs={'class': ['rabble-nodelinks rabble-nodelinks-top']}), + dict(name='div', attrs={'class': ['rabble-nodelinks rabble-nodelinks-bottom']}), + dict(name='div', attrs={'class': ['tags-issues']}), + dict(name='div', attrs={'class': ['field field-type-text field-field-summary']}), + dict(name='span', attrs={'class': ['print-footnote']}), + ] From 9662f691c6e99bf32bbebfc03aaf08cd80d3ad49 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 21:27:39 +0530 Subject: [PATCH 06/53] Add a new 'Calibre style' interface in case you are tired of the system default look. You can select it via Preferences->Look & Feel->User interface style. --- src/calibre/gui2/__init__.py | 34 ++++--- src/calibre/gui2/preferences/look_feel.py | 3 + src/calibre/gui2/preferences/look_feel.ui | 103 ++++++++++++---------- 3 files changed, 83 insertions(+), 57 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 30588a8866..b07dacf572 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -8,7 +8,7 @@ from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QByteArray, QTranslator, QCoreApplication, QThread, QEvent, QTimer, pyqtSignal, QDateTime, QDesktopServices, QFileDialog, QFileIconProvider, QSettings, - QIcon, QApplication, QDialog, QUrl, QFont) + QIcon, QApplication, QDialog, QUrl, QFont, QPalette) ORG_NAME = 'KovidsBrain' APP_UID = 'libprs500' @@ -106,6 +106,7 @@ gprefs.defaults['auto_add_path'] = None gprefs.defaults['auto_add_check_for_duplicates'] = False gprefs.defaults['blocked_auto_formats'] = [] gprefs.defaults['auto_add_auto_convert'] = True +gprefs.defaults['widget_style'] = 'system' # }}} NONE = QVariant() #: Null value to return from the data function of item models @@ -737,17 +738,26 @@ class Application(QApplication): if s is not None: font.setStretch(s) QApplication.setFont(font) - st = self.style() - if st is not None: - st = unicode(st.objectName()).lower() - if (islinux or isbsd) and st in ('windows', 'motif', 'cde'): - from PyQt4.Qt import QStyleFactory - styles = set(map(unicode, QStyleFactory.keys())) - if 'Plastique' in styles and os.environ.get('KDE_FULL_SESSION', - False): - self.setStyle('Plastique') - elif 'Cleanlooks' in styles: - self.setStyle('Cleanlooks') + self.setup_styles() + + def setup_styles(self): + if gprefs['widget_style'] != 'system': + # On OS X QtCurve resets the palette, so we preserve it explicitly + orig_pal = QPalette(self.palette()) + QApplication.setStyle('QtCurve') + self.setPalette(orig_pal) + else: + st = self.style() + if st is not None: + st = unicode(st.objectName()).lower() + if (islinux or isbsd) and st in ('windows', 'motif', 'cde'): + from PyQt4.Qt import QStyleFactory + styles = set(map(unicode, QStyleFactory.keys())) + if 'Plastique' in styles and os.environ.get('KDE_FULL_SESSION', + False): + self.setStyle('Plastique') + elif 'Cleanlooks' in styles: + self.setStyle('Cleanlooks') def _send_file_open_events(self): with self._file_open_lock: diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 2117de009c..2c675d1ee2 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -101,6 +101,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('gui_layout', config, restart_required=True, choices= [(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) + r('widget_style', gprefs, restart_required=True, choices= + [(_('System default'), 'system'), (_('Calibre style'), + 'calibre')]) r('cover_flow_queue_length', config, restart_required=True) diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index 73e0a85a68..792dd25ec1 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -28,7 +28,34 @@ Main Interface - + + + + Choose &language (requires restart): + + + opt_language + + + + + + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + 20 + + + + + + + Enable system &tray icon (needs restart) + + + + User Interface &layout (needs restart): @@ -38,7 +65,7 @@ - + @@ -54,34 +81,7 @@ - - - - Choose &language (requires restart): - - - opt_language - - - - - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - 20 - - - - - - - Enable system &tray icon (needs restart) - - - - + Disable all animations. Useful if you have a slow/old computer. @@ -91,21 +91,21 @@ - + Disable &notifications in system tray - + Show &splash screen at startup - + &Toolbar @@ -140,7 +140,20 @@ - + + + + Qt::Vertical + + + + 20 + 40 + + + + + @@ -161,25 +174,25 @@ - + Change &font (needs restart) - - - - Qt::Vertical + + + + User interface &style (needs restart): - - - 20 - 40 - + + opt_widget_style - + + + + From 9077ff9d837c354a22bb9a0fa08346d2127e8ae2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 21:52:43 +0530 Subject: [PATCH 07/53] ... --- src/calibre/gui2/__init__.py | 5 ++++- src/calibre/gui2/preferences/look_feel.py | 7 ++++++- src/calibre/gui2/preferences/look_feel.ui | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index b07dacf572..1ddc4743d2 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -753,7 +753,10 @@ class Application(QApplication): if (islinux or isbsd) and st in ('windows', 'motif', 'cde'): from PyQt4.Qt import QStyleFactory styles = set(map(unicode, QStyleFactory.keys())) - if 'Plastique' in styles and os.environ.get('KDE_FULL_SESSION', + if 'QtCurve' in styles and os.environ.get('KDE_FULL_SESSION', + False): + self.setStyle('QtCurve') + elif 'Plastique' in styles and os.environ.get('KDE_FULL_SESSION', False): self.setStyle('Plastique') elif 'Cleanlooks' in styles: diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 2c675d1ee2..294d7a644c 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -6,7 +6,7 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' from PyQt4.Qt import (QApplication, QFont, QFontInfo, QFontDialog, - QAbstractListModel, Qt, QIcon, QKeySequence) + QAbstractListModel, Qt, QIcon, QKeySequence, QStyleFactory) from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList from calibre.gui2.preferences.look_feel_ui import Ui_Form @@ -104,6 +104,11 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('widget_style', gprefs, restart_required=True, choices= [(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) + styles = set(map(unicode, QStyleFactory.keys())) + if 'QtCurve' not in styles: + # Can happen in linux + for x in ('opt', 'label'): + getattr(self, x+'_widget_style').setVisible(False) r('cover_flow_queue_length', config, restart_required=True) diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index 792dd25ec1..0162d429fe 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -182,7 +182,7 @@ - + User interface &style (needs restart): From 27a3a14d6ef582d0d4e46838d16d4543068a6de6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 31 May 2012 22:18:49 +0530 Subject: [PATCH 08/53] Fix #1006996 (Alt-A doesn't work after update to v0.8.54) --- src/calibre/gui2/tag_browser/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index 5a760639fb..913ff8f4a6 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -388,7 +388,7 @@ class TagBrowserWidget(QWidget): # {{{ type=Qt.QueuedConnection) parent.alter_tb = l = QPushButton(parent) - l.setText(_('&Alter Tag Browser')) + l.setText(_('Alter Tag Browser')) l.setIcon(QIcon(I('tags.png'))) l.m = QMenu() l.setMenu(l.m) From 86434c9ab790d09a9be56bf392600b7abe394b23 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 16:34:21 +0530 Subject: [PATCH 09/53] ... --- src/calibre/gui2/metadata/single.py | 4 +--- src/calibre/gui2/viewer/toc.py | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 367068b7f2..fd0d0a6953 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -45,7 +45,7 @@ class MetadataSingleDialogBase(ResizableDialog): ResizableDialog.__init__(self, parent) def setupUi(self, *args): # {{{ - self.resize(990, 650) + self.resize(990, 670) self.download_shortcut = QShortcut(self) self.download_shortcut.setKey(QKeySequence('Ctrl+D', @@ -82,7 +82,6 @@ class MetadataSingleDialogBase(ResizableDialog): self.l = QVBoxLayout(self) self.setLayout(self.l) - self.l.setMargin(0) self.l.addWidget(self.scroll_area) ll = self.button_box_layout = QHBoxLayout() self.l.addLayout(ll) @@ -623,7 +622,6 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ self.tabs[0].middle = w = QWidget(self) w.l = l = QGridLayout() w.setLayout(w.l) - l.setMargin(0) self.splitter.addWidget(w) def create_row2(row, widget, button=None, front_button=None): row += 1 diff --git a/src/calibre/gui2/viewer/toc.py b/src/calibre/gui2/viewer/toc.py index 327a5363cf..bcaa4f289f 100644 --- a/src/calibre/gui2/viewer/toc.py +++ b/src/calibre/gui2/viewer/toc.py @@ -69,7 +69,11 @@ class TOCItem(QStandardItem): if si == self.abspath: spos = i break - am = getattr(spine[i], 'anchor_map', {}) + try: + am = getattr(spine[i], 'anchor_map', {}) + except UnboundLocalError: + # Spine was empty? + am = {} frag = self.fragment if (self.fragment and self.fragment in am) else None self.starts_at = spos self.start_anchor = frag From 48688ff2125c5f61a445fc693d48b014e1a28476 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 17:08:37 +0530 Subject: [PATCH 10/53] Allow fork_job() to be uused in plugins --- src/calibre/utils/ipc/simple_worker.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/calibre/utils/ipc/simple_worker.py b/src/calibre/utils/ipc/simple_worker.py index fceb04cbfe..5a89b91461 100644 --- a/src/calibre/utils/ipc/simple_worker.py +++ b/src/calibre/utils/ipc/simple_worker.py @@ -186,7 +186,13 @@ def main(): args = conn.recv() try: mod, func, args, kwargs = args - mod = importlib.import_module(mod) + try: + mod = importlib.import_module(mod) + except ImportError: + # Load plugins incase fork_job() is being used in a plugin + import calibre.customize.ui as u + u + mod = importlib.import_module(mod) func = getattr(mod, func) res = {'result':func(*args, **kwargs)} except: From 89278e3d08b07fd677f6baacb079f07b6667c4a1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 17:12:32 +0530 Subject: [PATCH 11/53] Mimetype icon for docx --- resources/images/mimetypes/docx.png | Bin 0 -> 12735 bytes src/calibre/gui2/__init__.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 resources/images/mimetypes/docx.png diff --git a/resources/images/mimetypes/docx.png b/resources/images/mimetypes/docx.png new file mode 100644 index 0000000000000000000000000000000000000000..0e4bf9a16b8408c38d1988c266398e2ccd55c6e1 GIT binary patch literal 12735 zcmV;wF+k3VP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh$ z3MMTTLcX>D03ZNKL_t(|+UL5P@yY42BuAc#Xl~1)I$nj2CPPu#JSl5?T>Rt)*#oOWm#BYhQAG z@7{Cf$6embtg5bRbyjsXbVg)l*312!?K|H&_gvt@= zz$@Va0weGefF1y4qY%Lb1z2?jkjCm~&9T@hgj^{Qm<|C2Bm7=-KfIs-tF8bsfSUO~ z0#G&b5i6kpY4jhYa6kb-k(vMCf=td~9xudAZCFgKLOh@9Wnv z7z{xSVq+Y{05g~v0&HFfFq`Ad25%>?Wd^_mWgK zcybFCc-1u{_>4sT{0t6`)-hg{P()Bt zp%Lp_sR%?y&_r6GoI2t5B$E}QRsz`P86j$nOzySm{}X}h6U)R4zgPNm+mxpLzSh)~ zGFUC(^#95ITp@$r?mX)CIwmJ4F*rDgAP818gaoT6{P`i^?mc7pqx+6&!2!=qhB4r4Wb#MR2aWsTh#TcyUhN zAAs=0JP5@0AFD4c%w2aNbx)+Ymh@}pGcn=}&P&UCF2d{-vp%GxRy<;_YhMADC;X{e zjQ4-}0LEq`5D{X<_{h&+il4i71G2tA=zFLu#^{_xT>^@@<@~b|csic4`3$zA=9Ji3 zBr!JqM#Qb}DU#O_r-YXB*hs62yJ^!9qhQGgnfvCr5GIKe=1qk@rWE7l+luGJ>vTK> zEEey7cw`QD-E#!`kwPV6%tQ)O>G$(er0 zU=W-fDUlJg0dR&qWfN~XC0%A=;(Ou&w4#Z$|44ndc@MI`J9!RR0D>T#5)fDjr(9M) zgnfJS9+LUAsQbJR0bhFT6#nYLlW4>WBi%Xt<$t>xJBPcVh;ec@Mk7wjS-ubsJPQyA zEiS-;ITk{nTnp|XjP<6GxRn<>yai7`-y{JomdYu#t`#S(076U807fAMh#3MR@giUd zvhSqBks$4Tg!NKZIgBP~jL8c~|2z%>>F@mQA5G#j51s-MU=<}Nhkiab##OB12NTkPP1mG+&u}}z3tl0>YrEt$RaD)j-%mN-K|3e6{g8n@^w!!{BAR4j44Lkbq;kWEUBnhXgq}^Q#4JE=b7HO1$JL5td?28R-7yRF(y`mcc-CZ4 zJ+k4!D3W4F&@dRpgiN4AkF=?#upvjF9;t+&aUMjpWempsC-DFP;0b|j#y52ho<|xB zSTM;DM&K3-G4ZOEkyk7PFf;z>+s9CC#Q2C|_)gBorktsNU?vcF_dlJ05CXoJ5G+D) zOJQuRBJtE6TQE^on5f1O@QiCuTeYwb0iFjuaG;7m|K2GSe4$UMGWiu5)`tir2_O5V zow#gM5&KUzv>mc``Q3#8@BZC~F<8!+N+7!`;Jor~OI1&&sM|M{@rD0=BlaGxVtiJ% z8V3U;1O#!Co_d;-f+>Kl2H;y!1-NI=I21F6%US%~wHwfg6dJJ$;}8(Yd7AcoW;9Cr z2F&B0rcNN3P^l|CbhLr%*5@!WCqYamBpASG(mOWC@>vgm|HLF-7;nNS4Y!#9Pf3k6 zBtfw59e8NpG+zI*emrxuj!cl`;=U*F;*kobyF;Te`T>zv29pv921qeHW9v#0UUl_4 zo*~Q76E}mwDbe41Pbsv69NS8KQIHqj5k~{jI1wEj~OX^ z1R_F10p&FzO7AKyJ(M=nUb2Qh=l1GA=l$&f?L+WkIwxQf6N zI=2!AdYSxPpF|Iy0G>Ro`zS-tI0pkLl}X`5n#LBX3SnD1?s-Uv!}a^gYZ*?M$0MqzG@^ zQ9u;4`xU|y5T5ZAMgV~?aPJFsN3~Kaw|9KM?E(Vh$zydWa^;q!JS^HvI>6X$jC!On zP!3%uk-nWT=v2zGU{JP7)?3cvqD@^Gn~4y+<`g)P$bpl_#nkNSC@_`z*IHX zojg+ErdymhAR$%ghuR4U=WCs zP8?4N-2Xxa`HW|>Cj;9&;n+V{Y!Cv+CL5TpN(^=dki@#zfP^8aIPo4ps;ubzLYppV zCa|j*;G#`kI5OVQ#E#V6NlNLfWCBTsB8Fmp%gj&;j>t;uoYO@U0@Bw`7l}He0DF$i zf)rtMe*s;E3}z#SC)x-Zp&7H;nDA2@bBR?t;n*kXn@lKhd`_aL;6qZ1kh?w{=E&MyXuWrl$@qX7F))gUF|#$5vdfO?$D@mV)qveI9< zDH%6y${{9G1r!N~z=9JlT?jlk5uuRrO^v|x?t#FhT#;zJrZ8EPDP~VVPzp4OR6cHG z`q+V4W$?E1frPmOK;qUS@Ruq{7-rq6_dsTN`HaZA?8T;OWr_ zJ;eaAvWjHF0ei-J1SV?|vkkH>0g1N(S~3m$U?%kN?@x>)@CCAg=PI=pi3=xM;lylf z7Mvoy?Bn(62Hth+HXIvoKq!DE0n%8yxw0}mheE14$q8Orz@0DT{^x~(wUP!-&BaiX zFw~Q4t!(L1mlF&L{iio0(3|s7SE*XMW7viB94D(fpALPSGI7Ggv$nL!n#5FHA(Lhh zT?20z9;aFAB;I(f|LQ71fUY35(~iij~F$F_8wVMhRl6&sD8)W(@(I^b#FWfLc>R5}~J%(UmQ3t#+`hjcdNY zE90X-2OOI-RWw0PP?`tS@A2Gt3`LA`&ck#~CJdk=D03p7INoq>Odwr-vF%&zYB4bU z{n&{r0HBl$aDtm)2F9ivc<^uD1gX;rj7~T4D|dYlL8>>cr8@|WC|3C8H*W(2I62wC zehE!V6l9Cq*lc6T~g5Y`jUaZbtM@UB$AXYlYbr(Wc*dR)}Yn%kkgMB#<#ULqi z2#8b*mqU-(KOR96qmc12UWwrw+mi;YWdjWWebGvi2yRWe1X}y={Za;ZKRSvVcJ*N2 zQFg%Y#8}N)`=0$%@B_`>af@;#w~dCvJ6^XHld};Ho~)K+F5ukq}>chP9O$u0W)UE`ou2 zRbjLu(VY=chJA~P5RpO%fgc=?A-op0DQV_R6>CIm`4PS^aR0NDI(*e))FTNgfk?6I zIy*7ZNSU%o*c{UqBm}T)YZ(JQS^V?&PQerA_o=p!kt!hzoAR2{xBx?VIRA+tfIy1O ziXB^4rG$vFV4rmJrBaL=MzV-vZS8t}9ytrP3BT|KzIC9A-eQQ?UDAv7<*XBs=LBOiMcTTl)ymoYPm-Wwb4)TwK@&s^D8T8mfYXJBbD{u5+|mi-7G>C0 zC`L0u+ZQHXW83wcLNC(|!Yy0!P;S+) zDZ7xZxDf)u_{NXs9E@fLd;x6i&7rrLL#)Vk0$U}rUcfenvZ*kpL8f3}rW)hWsX8_d z=Fw;>5Sh5GG&q}_X&S~YW%8*sv(}99mYX)>`}=1Q_`(#HEVZn!TKJ{_M4BAZ^e`K; z$Ph-L^IHMbJP*LGm75I<=b4qZwvVqNf!A!#p%D>S5d;w|IWA1)%wxvfT-;hBH?HrQ zlXX*YF-@7~^E9`vTsya5a{d2;QeJ=<&mF74_XLLfa*&cVVMC0GnFb=M=3{OFw~Dy8 zD~q143?AD%4G1G_Wt2cMq-FdFCMC2A0apoB=9rW?zZHP2>rUrDEgdw;@@ru#Wl}L- zHk5MTQAa&eT5;S`Z{0a8((4FV=;v4p$@Gc%9`NwK zDR`bhPbo-N=y<^1!!rnd(XwVB0kc3OQux)M-GNBz(k{z{<0qx@5GzU@OXy$cB~(fY z_&g5*q>^5H0bS#Fu0J(6!P2*!0@qv0ffhb71S?aZH>n^KLcw_C#aip_0jSPw3u$hu|q$UDT|_c<@k;7* zTf6-P_@!xEbIb$q{lm3(+5wLqsu;{bsTM9kkOC9XUkY)_`T|I~L?s!@V9xjPV{^JP zSn^O)P1I!*l}3aU<8{}z>3&NJbPo>Zv1O!)W8-zyn+l5cv=YS{=-C30G9gK^4F?3J z;DDj76VUk&0-d`}NhsYW@49!8$_N<9c)*5osHLNH?1yQZ6r|m`2gZrnNaGB^#rZvl zDlI*FS_yO#9!rHcT+xf0FX@4j2V4NSl1sDK}w4Y2r`BK6*DBajC*k(cwVJ}P5|y-k*t_; zi|2Gnm{Kco35<*SLKC+Q51@mh_9(ixis?#>xrTE2@x6OzY@eCy+Y>NF8&YUA6yA32 zAa1^-2hG^L&TJBsG+DrQ& zgustpoHOoUTRbbB4m!5a93#_mM#_c>Xr&<1(?C>P27A8M0+O{;NE)#0LJQkEO(I#J zuX~}v3|!Km)ksLRS6q^Ga%?WfY(t@^pug@H9v;*Ef&|n3YlLsux@_R#@=ZldRV0cT z->v_LX&<*(APhWw^Wl>KfOouV6BvxY`_~tBn;IoO0m(W8ARBtP@}gdhPBk%GmFUU` zsjn?sibbu&PU?uzMJXr&5*in*RJCu_LI5jn`TC-zP5>xQia$0T1Tiie$U-W1)^2ZI zH!cy5PehomCnxEvkBuYrG^Z?tbQpvcLl9xt`W#AGAM45?Huq%>HqeiGoDfI4$%HUE z)dT>HPe-WKl;#aYvew^{Oactw6S(g30eth3qX6qQ5Yhraq9pfM+{Ox;EZ2k!GNFP^ zig;c(gtRQ|L&BOdr%54hnQv}affYgzy9Y8LX&Dq_$%YRQia?~W|70BiaA>@dFfGu4 zkCma54f@~KpGPt0W1yTtUn!HKgoU$Y%M17(u;+PA<-T~ThKcEB@|#?9LDJh;E(Pf8 z&f;5-A4jAbn5oWSx;BeSy^2^W-L-5|J4LqFz_@$M{F(fpDN%y+yB1(`d3)yE@-4J< z^O9NhW0zSofQd?st4H#XvC>wrlqQ0dGMoS*BY^K6(Cysc-aCVwFCfS~-&nTg4TuO^ z266~}556a`eJBqmf&jxaAk!@tHJ16q13Dc%K32o@T+=XqX6zg#*-RA0_{G<40{|4W z0X$FW!M#eN9yKsIH;M6?3DlbnC`FDGvKfJLijcH|k?|1cbw5CQ2t!hnvrC>t+rm#h z1V~E4Y(t?DF>cse#AhBjiA=$7?cXye-v{GA_G%$Ld|<{geb(xklQJ?B(^N%;oxyiG~M&y31k8UB3Rk60TLJSaVsV9(A3*_6dZ)yap*4j#wbV}zcY>cL2?Ci^6|5)8E7f*^eYhx`eSr-}k`Gxb^xCxb^xCc;VO_{{7Koc=q5FUN|;`T0&-n?l^OJrtj-_V8k{oEyJG!-W2nt1e?QGE96`*D1GzF{70jlE@8RW<#421BFb08+Uf;9LX?u znk})MzCtb(_{80Zbpr^gghRJW#1zo1N&NBxLVD+`HlWss!IG2jYP|*#N;w~&{)hd@ zXZ#e4nJfea0X^jmc5LigH1=9WNGn7x>tp>u0dKo`E57#e*Ws)G_ZD2Udl2PP2mwYj zQm8kYn4FrxM?dozo_KBoVfd29{-5Izfb<&omW5SlN?@k03>ZwU_ct<#nhG~w(Tii# zO_Vbps!h{!mFh3Bojg)8ZfaKk0tZjPU|$m@6a8clZ-A(GmGc}_m# zJK+jWPY~7bwXQFVjq3_$6??Y~m+*UcUWZyk;@N{!czo|TzV@9%n3!&$8A-f&s)p|F zUS#w6^UMRZOkHF*iK7xJ%+_Tx)zdbJAerxz$#@v<&0xp6JhGmrX2x8o@tEWZy)*{0|;L2@X$<%NweAY|6lL3^JP`|d&WbO|1WHHd2>&WRU z@Y#PohC?SR9p(L376Y^_2mz`Qq1Lp> zzm*<#JOBe*`*RQg`br_PzAliv+5ZAbE0Z$<*5SOiXfvcCX%`oO%_>N^W>VY3ECf)k zOT7Ixn^)8oGc$U+a`=VU?}9REL4S!cIy#Q$UM%9`%{^;71aQiNsAY7Unf+@9K@k&@ zmDr4t-mH6@pSflbjk+|9prJ@@nb>p;fe4;5W8w^`1QYTZ54$&&<^eH#|N7m1dL@qC z?ZcLBDCLfj?lFXG0SiM9mu&6s82NHK@JK}PeGmWngCqFd*B%GORgCm!*LX1qNl$-@ z4c0c4v z09-$w9Rx|KeQ`(tQIl}_mZG*oA)FFy-PR4I2%ahU2!jcr;1t8Pkhy+9LMh{+rxY$Y zPLG+fWw-!kx`;I`O{NFI0zGAzK~4`gLcOW*&Re&w8Y*YjYYwMpYS`X$5`cTdo~|ipg0yGdq`$)L0c;5oAS(niB80dBc)c z`nH=kAePFl7UGsRG0{pA8KvwhhPdkD-W75Gi-iQK81Mb9ui%OAKZ46I>RtP3plD|T zg=pC~$*t{YT?J7D?A}yxId<9u+;Y_bqDX1Zz^o5QjofgRKj9il8TD$6cf4lfl5zI! zui1oJUAmqGVfy^_0BO~_uG@x=i+hpF`m5spH3rb%?Okua9J_X3fkL6M_FKXh>7i}t|kn>k91P~Fv^o^%*^3+MZ^B3NNTrRivJpib^9E_Gu+Lpca z1dtDXlna5Ig_pL}o??J4gE_reL@7O>A+=5*0qthwiX`0figio6Rb8|Z*nM%InFf+t zL+%L7)|q@l2wZz<|EgI(Go#*An5{5&U%DHa+{!b89r6G)Z`e3Smu<0K$;z;4GH>_VW{@aOVueoNO9th>ukf*dXy#$OI zQWAdpy5Uu`emhD1;irycuserr7@QvpAlh45-BMhn1}E$LO-Z<7^Wr;XWkL@l{kcTo zob(2|#iM2ebvrix<(KrfxcbGzfWUQ^_d`kDNa|Ww7Mi&u1f(MD+S0vh*3Zm1K3YMu zHj9fl7u}5I^S}eJ+kL}z1-Inz!lC`aa)?~$pH^5mUD2=i(4!=4aP8l$fuUzG!AM^Y zBYnALdH`VC`VxwH-|XKrfAXIdeiSRb>rLBN)%t}H_~ru#5qOMZK3pB%p;NVh^nO1` z?V@FwKrkbcz*XByOA70!U%n1eQ<|m>hEPevXX}DJfx(^(hWeJzlx$2~e|ehxoxi+APY`Lx z6{!uI7>unWOM8^|%jZ6FBPtcSXx{}hP|WL7Ly6tI+lg7-r`Koniq=3sk8O)5ITBcOuRN@WzX;R135uonBQR+pn{DqHkdiP_jrDLTW`v=S;l2Vg8UKtu z!uWIpk3V|~8;85FYumt*eTSXI1D)A3$P98$7&UI;2qMY2YHM*>*1rb8*kjYpm0}0@Erz$XbS;$)Vi(-bQgS-3!%#hR#OS=rVvaDo)GYT(IWiQ38#HC zY)vQoD3^Q`^C4;tiP@?^ts&8fbbVsH(!@XB`vR0A4EGnXaioM-UcG*a?+9c=f&QNS zf-4$n91lS0kYL+sbjfwgK-Qg5aSr@H5ko3Qy(uw0*VGk3@EHTQ^m9E=psSd{ z$Up&CUOa%8T|9tdE=`YR>A|LiFCK0k#Qj!fehZrO3#_c(lF4&zfbj0_Y|$_MiVyO8y- zISkN_0!51b6VUYU!snD7&}wzNFAYsEbb>v-8x4HV2O=Pr(#g15mzb$E9g*4JokL%D z?j?By8zu_50Iz!adffQ3VZ7z$E!eQGblTMQpTBbm13fuhwX5Hy$mtUKLdwudFWMm< zpuHoA-9p^01Gz;7X$ME!CDK|@dZ4uDrCPJaSs6c=J@`IQ$a~1=Lev^DD%A+mYy=_A zM6W}~X0h+^G}iUzFw|c_Hlw}6QhdWg$9&(z`oZF&uM{?^cip|6Tznb1cV zc<3r-uz93}<6|`(IWgzJ>Rc_t^h^^6kItbPN$lFzihIK`394cYca0x^Gg_p!n z2qExifB!6YZtlXxo4b|-cBkE0m zx1Pt97x&>6mknWLu!#Pi(`OTZ@lShE%m;YwD~4P9DO)ls(K3i4tpurFfe1jHQi9c2 z09D8#>&FfQFbfPXv+{Qu=;j2O&jrZm0!T%OV}+Ty2;(yikQw?sG1J6}@j8SD1irxf z{vtMwbj?$Qvmt%}#EVT!5$cPvEhqPU7;52k`!1 zymHaco2^9HcW4UzJvnS#mv@F^dlb^{UWjxvh;RnwdBEPidmjZ*H%f5s6u|DR>H9ta zy@S|R$Nrsdx{_4BJON}gK86Mg7#b*Gw$jAOi5j>r5lKcPBFLC9I#$O6KRk);o4T-T zYcC3h>{*VBK3y!fFDd3j6mlUpyt;(9zIq!Ted-kMefS8N6=voXZuzOr^B6k~9QAj2 z;phzNjTo=GY5*Q2q9`>6m(s%5VAH-%lTJXrUdQ;uKUtr(CY3zA!0>xa2 zEgMSMGTeosfg-{{EV+gt{h9W@6$CRQj$)u7rzM0y5C-slAHL_o^E||HjOpoV)M_>P zv5$T1R~~ufk)uWd&aDT?hCUz!D%B=D0bH^^3n?X(`C;jPwuM&io-NxI_yT?9Ec&~1 zxN>Jdj-INbT94rg#`shd$Hr=S{>54BJ2;I?w)fz&9sMZf!+Bk|rxQLiLrOW1o43cK zD1t8t8wUc+%uJif;Hrh!pP89~5FYwVF+@qAUax^jnVEvhRTzEGM-T)EDMTg=fgnJ& zT1Bl^Lli~y#V>yG&b#lvdmn&`2>~(i(zYGx3=w3B8{Z5%B9)9kO{XnF0B6Z#FGn#p z4kc~pLjy5-%2`CQ!m-gR4ji7vv(HbVznsI?ja?|@boR1oxP)xzEgB9M5`24+MoI}O zCE_?n6h)9yK}xCj2(Uw?NkK_zp0At&Fq3xkzK<{rk;!C`$>?6kYPE`Hvx#Q2iF@z8 z_kVu+)1Q6-!0ZCne{MX0T^Xb;UbJ?z&ST4$7Gx*6?s73id3!IUVsw|Xn5#8${A3Mt z4T-0pn?w+Jh$Z2XJtxss$YAHzZtU1tb`z|GAt7jAYJIn;?l|j{d zjB;t^h8et6&tT^SZQEEjgiiyb6EzSNloXIk;@GJgnv(Ivv*UR7`AJ;7r3d9=2IW$K zu0pt^^(&lI;zzwDwQf4jXL5ub^=d_1?%?h_Zu1-!iEhS(AU=orIZu8y*+sF z;J@8|`|bY^z)Yuv-$5o&e}z&Zv!eZ8o$?F=y*W4Vsos>xWqgbb)-W+$$J9&%r>2_N zcW~N`wB5F$3zzTg)mzjqq5wqX+;pW8D}&}OWl9TdnZoOI!^l$am(S`N z{O~{?!vlHDRw7KzH9-U%JypTzWCI6|=qlmsuOC6V6f6n^Z3t*I8mQK4s8y?wQo{2* z6bc2DySuS&a1a|eZp84gCV8FnYm}?__Ix=9k^DBeaxcgrY`D2CKRrFEJ=grs_ zg75KypwPN^r6i)UK;O9z4U2iN4w8V>N}}K_ckv6<{@I@tp}ET*w>Pt4{qi;FC&0DxIdU9~nU=lWFk) z?ZV%;Z{Od(|NZa(y*Q4iQZYYT>6pJV3IIOqI{&$j{inBdETRayqNk*Ul6nNK=lR&Y zdCO@j-aUKv{P~@C-uWjfw4ZM3Sk++K@hM?HE|TCp+hITVGv?qcmzZ=&*~eEhJ4_G z2Y&a%AO7&)p|zo7Rb&2&D8T%cLFe|e96YfU53n5e(CuX;fKYErh@qi%^Q^yCt5xp4 z`|c0@{_p?(eVE_Pqt2!IbZ$n_kGl&vjk0;3hcFD$)uq=Wq=Db;?CjVVzVL+)eE##F z|DkdD9qZ;EK>#5{3-CL9`0&5pe*5ho9v>f{Or?2e)xLcmc!2ZIf?ulQCd;;b_)ClnM*<^@wCqIk1&ATyjg$xdV>vl6iRG<;ZXfzt? z%U}NTuYdBBpZs15?5&A3uM-N8wt8uV-Y`E>yOF@da906AAqO&h?=jnr87bL~o4IwL zVKa$a*uDGg2=`>WF}JZJr-7!K8x({Ax+THShwy@MMLw%#QEIDi(DMK*mD(ph@rhsj z%2&R!*I50UL;9!naLas703ZjT44@Z4kGY>?=6}FX=w<)@{g1roJ@5JN4?XnIaTD*? zyvu*73g80>0Tcn0%ry@nYjA}3V=ilM3xlz7@wL>oxmJ;WCqjUY{S9+0HX0uo;ftRz z1yCs^h>(nFq4P=jI0L~6BWT|U-8Way!QvnP%R)+^Qb3Pz9`d2$44*67g#MEv{DqW& z+bsUPq(a46JpU(2@Ta4_7#A)VE*CBrE*CBrF6ZCn{{tk72*>bBtylm6002ovPDHLk FV1jkj0;vE1 literal 0 HcmV?d00001 diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 1ddc4743d2..f0f069639a 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -471,6 +471,7 @@ class FileIconProvider(QFileIconProvider): 'djvu' : 'djvu', 'xps' : 'xps', 'oxps' : 'xps', + 'docx' : 'docx', } def __init__(self): From b689b6facd2ea2faf6bcc1719aebd5d52cdf54e6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 17:24:36 +0530 Subject: [PATCH 12/53] ... --- src/calibre/gui2/viewer/documentview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index d07e9516fd..84204027c9 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -649,7 +649,7 @@ class DocumentView(QWebView): # {{{ def current_page_image(self, overlap=-1): if overlap < 0: overlap = self.height() - img = QImage(self.width(), overlap, QImage.Format_ARGB32) + img = QImage(self.width(), overlap, QImage.Format_ARGB32_Premultiplied) painter = QPainter(img) self.document.mainFrame().render(painter, QRegion(0, 0, self.width(), overlap)) painter.end() From 2fe4e54ce4111d4e387471ff78ee753b046673f7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 17:37:13 +0530 Subject: [PATCH 13/53] Save single format to disk: Only show the format available in the selected books. Fixes #1007287 (Save single format to disc menu) --- src/calibre/gui2/actions/delete.py | 5 +-- src/calibre/gui2/actions/save_to_disk.py | 37 ++++++++-------------- src/calibre/gui2/dialogs/select_formats.py | 8 +++++ 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/calibre/gui2/actions/delete.py b/src/calibre/gui2/actions/delete.py index f902708bca..161a4788c2 100644 --- a/src/calibre/gui2/actions/delete.py +++ b/src/calibre/gui2/actions/delete.py @@ -116,7 +116,7 @@ class DeleteAction(InterfaceAction): for action in list(self.delete_menu.actions())[1:]: action.setEnabled(enabled) - def _get_selected_formats(self, msg, ids, exclude=False): + def _get_selected_formats(self, msg, ids, exclude=False, single=False): from calibre.gui2.dialogs.select_formats import SelectFormats c = Counter() db = self.gui.library_view.model().db @@ -125,7 +125,8 @@ class DeleteAction(InterfaceAction): if fmts_: for x in frozenset([x.lower() for x in fmts_.split(',')]): c[x] += 1 - d = SelectFormats(c, msg, parent=self.gui, exclude=exclude) + d = SelectFormats(c, msg, parent=self.gui, exclude=exclude, + single=single) if d.exec_() != d.Accepted: return None return d.selected_formats diff --git a/src/calibre/gui2/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py index b2bb8fb547..8fb9146689 100644 --- a/src/calibre/gui2/actions/save_to_disk.py +++ b/src/calibre/gui2/actions/save_to_disk.py @@ -8,30 +8,11 @@ __docformat__ = 'restructuredtext en' import os from functools import partial -from PyQt4.Qt import QMenu, pyqtSignal from calibre.utils.config import prefs from calibre.gui2 import (error_dialog, Dispatcher, gprefs, choose_dir, warning_dialog, open_local_file) from calibre.gui2.actions import InterfaceAction -from calibre.ebooks import BOOK_EXTENSIONS - -class SaveMenu(QMenu): # {{{ - - save_fmt = pyqtSignal(object) - - def __init__(self, parent): - QMenu.__init__(self, _('Save single format to disk...'), parent) - for ext in sorted(BOOK_EXTENSIONS): - action = self.addAction(ext.upper()) - setattr(self, 'do_'+ext, partial(self.do, ext)) - action.triggered.connect( - getattr(self, 'do_'+ext)) - - def do(self, ext, *args): - self.save_fmt.emit(ext) - -# }}} class SaveToDiskAction(InterfaceAction): @@ -54,9 +35,8 @@ class SaveToDiskAction(InterfaceAction): _('Save only %s format to disk in a single directory')% prefs['output_format'].upper(), triggered=partial(self.save_single_fmt_to_single_dir, False)) - self.save_sub_menu = SaveMenu(self.gui) - self.save_sub_menu_action = self.save_menu.addMenu(self.save_sub_menu) - self.save_sub_menu.save_fmt.connect(self.save_specific_format_disk) + cm('specific format', _('Save single format to disk...'), + triggered=self.save_specific_format_disk) def location_selected(self, loc): enabled = loc == 'library' @@ -74,8 +54,17 @@ class SaveToDiskAction(InterfaceAction): def save_single_format_to_disk(self, checked): self.save_to_disk(checked, False, prefs['output_format']) - def save_specific_format_disk(self, fmt): - self.save_to_disk(False, False, fmt) + def save_specific_format_disk(self): + rb = self.gui.iactions['Remove Books'] + ids = rb._get_selected_ids(err_title= + _('Cannot save to disk')) + if not ids: return + fmts = rb._get_selected_formats( + _('Choose format to save to disk'), ids, + single=True) + if not fmts: + return + self.save_to_disk(False, False, list(fmts)[0]) def save_to_single_dir(self, checked): self.save_to_disk(checked, True) diff --git a/src/calibre/gui2/dialogs/select_formats.py b/src/calibre/gui2/dialogs/select_formats.py index 0d43864816..58085176a4 100644 --- a/src/calibre/gui2/dialogs/select_formats.py +++ b/src/calibre/gui2/dialogs/select_formats.py @@ -50,6 +50,7 @@ class SelectFormats(QDialog): def __init__(self, fmt_count, msg, single=False, parent=None, exclude=False): QDialog.__init__(self, parent) self._l = QVBoxLayout(self) + self.single_fmt = single self.setLayout(self._l) self.setWindowTitle(_('Choose formats')) self._m = QLabel(msg) @@ -57,6 +58,8 @@ class SelectFormats(QDialog): self._l.addWidget(self._m) self.formats = Formats(fmt_count) self.fview = QListView(self) + self.fview.doubleClicked.connect(self.double_clicked, + type=Qt.QueuedConnection) if exclude: self.fview.setStyleSheet(''' QListView { background-color: #FAE7B5} @@ -82,6 +85,11 @@ class SelectFormats(QDialog): self.selected_formats.add(self.formats.fmt(idx)) QDialog.accept(self, *args) + def double_clicked(self, index): + if self.single_fmt: + self.accept() + + if __name__ == '__main__': from PyQt4.Qt import QApplication app = QApplication([]) From 178da653f3539feb3dfb63f9ca809f0a43ea3c2d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 19:56:26 +0530 Subject: [PATCH 14/53] ... --- src/calibre/gui2/tag_browser/view.py | 1 + src/calibre/gui2/viewer/toc.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 57d7e54c56..4535241f77 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -117,6 +117,7 @@ class TagsView(QTreeView): # {{{ QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; + border-radius: 8px; } ''') diff --git a/src/calibre/gui2/viewer/toc.py b/src/calibre/gui2/viewer/toc.py index bcaa4f289f..cb105630e6 100644 --- a/src/calibre/gui2/viewer/toc.py +++ b/src/calibre/gui2/viewer/toc.py @@ -32,6 +32,7 @@ class TOCView(QTreeView): QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; + border-radius: 8px; } QHeaderView::section { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, From f5f964401d4748e4293e2c46500fd2a62cad0fdd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 21:10:26 +0530 Subject: [PATCH 15/53] Fix #1007468 (Untranslated cli strings) --- src/calibre/translations/calibre.pot | 525 ++++++++++++++------------- src/calibre/utils/config.py | 5 + 2 files changed, 280 insertions(+), 250 deletions(-) diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 307c7c47c6..ae7132f881 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.8.54\n" -"POT-Creation-Date: 2012-05-31 07:22+IST\n" -"PO-Revision-Date: 2012-05-31 07:22+IST\n" +"POT-Creation-Date: 2012-06-01 21:10+IST\n" +"PO-Revision-Date: 2012-06-01 21:10+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -142,8 +142,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:82 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:116 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:418 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:419 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:427 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:397 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:400 @@ -173,7 +173,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:84 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:245 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:264 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:390 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:389 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:172 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:176 #: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:204 @@ -245,8 +245,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:20 #: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:197 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:287 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:310 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:206 msgid "Preferences" msgstr "" @@ -1014,8 +1014,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1092 #: /home/kovid/work/calibre/src/calibre/gui2/actions/fetch_news.py:73 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:469 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1163 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1165 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1164 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1166 #: /home/kovid/work/calibre/src/calibre/library/database2.py:346 #: /home/kovid/work/calibre/src/calibre/library/database2.py:359 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3165 @@ -3072,7 +3072,7 @@ msgid "Producer" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:773 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:941 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:939 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:157 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:245 msgid "Comments" @@ -3218,7 +3218,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1434 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1273 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:953 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:951 #: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 msgid "Cover" msgstr "" @@ -3355,7 +3355,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1275 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:199 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/toc.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/toc.py:159 msgid "Table of Contents" msgstr "" @@ -3657,144 +3657,144 @@ msgstr "" msgid "Table of Contents:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:121 msgid "Send file to storage card instead of main memory by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:122 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:123 msgid "Confirm before deleting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:125 msgid "Main window geometry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127 msgid "Notify when a new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:129 msgid "Use Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:131 msgid "Sort tags list by name, popularity, or rating" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:133 msgid "Match tags by any or all." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:135 msgid "Number of covers to show in the cover browsing mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:137 msgid "Defaults for conversion to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:139 msgid "Options for the LRF ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:143 msgid "Formats that are viewed using the internal viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:145 msgid "Columns to be displayed in the book list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:145 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:146 msgid "Automatically launch content server on application startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:147 msgid "Oldest news kept in database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:147 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:148 msgid "Show system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:149 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:150 msgid "Upload downloaded news to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:152 msgid "Delete news books from library after uploading to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:154 msgid "Show the cover flow in a separate window instead of in the main calibre window" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:156 msgid "Disable notifications from the system tray icon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:158 msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:163 msgid "Start searching as you type. If this is disabled then search will only take place when the Enter or Return key is pressed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:165 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:166 msgid "When searching, show all books with search results highlighted instead of showing only the matches. You can use the N or F3 keys to go to the next match." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:190 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:191 msgid "Maximum number of simultaneous conversion/news download jobs. This number is twice the actual value for historical reasons." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:193 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:194 msgid "Download social metadata (tags/rating/etc.)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:196 msgid "Overwrite author and title with new metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:198 msgid "Automatically download the cover, if available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:199 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:200 msgid "Limit max simultaneous jobs to number of CPUs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:201 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:202 msgid "The layout of the user interface. Wide has the book details panel on the right and narrow has it at the bottom." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:205 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:206 msgid "Show the average rating per item indication in the tag browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:208 msgid "Disable UI animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:213 msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:267 msgid "WARNING:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:277 msgid "ERROR:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:289 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:258 msgid "Show this confirmation again" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:537 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:539 msgid "Choose Files" msgstr "" @@ -3908,7 +3908,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:178 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:242 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:80 msgid "No books selected" msgstr "" @@ -3974,7 +3974,7 @@ msgid "Add to library" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:380 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:137 #: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:115 @@ -4278,7 +4278,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:496 #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:501 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:224 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:89 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:960 msgid "Not allowed" msgstr "" @@ -4449,68 +4449,68 @@ msgstr "" msgid "Remove matching books from device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:134 msgid "Cannot delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:146 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:147 msgid "Choose formats to be deleted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:165 msgid "Choose formats not to be deleted.

Note that this will never remove all formats from a book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:191 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:192 msgid "All formats for the selected books will be deleted from your library.
The book metadata will be kept. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:212 msgid "Cannot delete books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:213 msgid "No device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:223 msgid "Main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:224 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:527 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:536 msgid "Storage Card A" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:225 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:529 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:538 msgid "Storage Card B" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:230 msgid "No books to delete" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:231 msgid "None of the selected books are on the device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:247 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:341 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:296 msgid "Some of the selected books are on the attached device. Where do you want the selected files deleted from?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:308 msgid "The selected books will be permanently deleted and the files removed from your calibre library. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/delete.py:333 msgid "The selected books will be permanently deleted from your device. Are you sure?" msgstr "" @@ -4833,60 +4833,65 @@ msgstr "" msgid "Restart" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:24 -msgid "Save single format to disk..." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:20 msgid "S" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:20 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:48 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:29 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:50 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:68 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:31 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:48 #, python-format msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:54 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:71 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:35 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:51 #, python-format msgid "Save only %s format to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:38 +msgid "Save single format to disk..." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:79 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:63 +msgid "Choose format to save to disk" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:82 msgid "Choose destination directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:90 msgid "You are trying to save files into the calibre library. This can cause corruption of your library. Save to disk is meant to export files from your calibre library elsewhere." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:121 msgid "Error while saving" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:122 msgid "There was an error while saving." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:140 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:130 msgid "Could not save some books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:131 msgid "Click the show details button to see which ones." msgstr "" @@ -5066,7 +5071,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:105 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comments_dialog.py:25 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/template_dialog.py:242 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:234 #: /usr/src/qt-everywhere-opensource-src-4.8.0/src/gui/widgets/qdialogbuttonbox.cpp:667 msgid "&Cancel" msgstr "" @@ -5576,7 +5581,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/conversion_ui.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/custom_columns_ui.py:81 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/email_ui.py:65 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:229 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard_ui.py:113 @@ -8112,13 +8117,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/device_category_editor.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor.py:186 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:897 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:898 msgid "Item is blank" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/device_category_editor.py:87 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_list_editor.py:187 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:898 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:899 msgid "An item cannot be set to nothing. Delete it instead." msgstr "" @@ -8241,17 +8246,17 @@ msgid "Copy to author" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:313 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:948 msgid "Invalid author name" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:314 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:948 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:949 msgid "Author names cannot contain & characters." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog_ui.py:88 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:136 msgid "Manage authors" msgstr "" @@ -8392,7 +8397,7 @@ msgid "Standard metadata" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:62 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:922 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:920 msgid "Custom metadata" msgstr "" @@ -8546,7 +8551,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:561 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:562 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:191 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:190 msgid "Open Tag Editor" msgstr "" @@ -8683,13 +8688,13 @@ msgid "Set from &ebook file(s)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:608 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:561 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:727 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:560 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:725 msgid "&Basic metadata" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:609 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:568 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:567 msgid "&Custom metadata" msgstr "" @@ -9694,7 +9699,7 @@ msgstr "" msgid "There are %(count)d book(s) with the %(fmt)s format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/select_formats.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/select_formats.py:55 msgid "Choose formats" msgstr "" @@ -10302,7 +10307,7 @@ msgid "Regular expression (?P)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/init.py:108 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:284 msgid "Cover Browser" msgstr "" @@ -10311,7 +10316,7 @@ msgid "Shift+Alt+B" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/init.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:279 msgid "Tag Browser" msgstr "" @@ -10335,7 +10340,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/init.py:215 #: /home/kovid/work/calibre/src/calibre/gui2/init.py:226 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:247 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:255 msgid "Book Details" msgstr "" @@ -10613,7 +10618,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:786 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:1398 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:313 msgid "The lookup/search name is \"{0}\"" msgstr "" @@ -10625,7 +10630,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:875 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:103 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:441 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:440 msgid "Permission denied" msgstr "" @@ -10922,7 +10927,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:442 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:441 #, python-format msgid "Could not open %s. Is it being used by another program?" msgstr "" @@ -11209,117 +11214,117 @@ msgstr "" msgid "Previous" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:118 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:117 msgid "" "Automatically create the title sort entry based on the current title entry.\n" "Using this button to create title sort will change title sort from red to green." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:128 msgid "Automatically create the author sort entry based on the current author entry. Using this button to create author sort will change author sort from red to green. There is a menu of functions available under this button. Click and hold on the button to see it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:134 msgid "Set author sort from author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:135 msgid "Set author from author sort" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:138 msgid "Copy author to author sort" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:140 msgid "Copy author sort to author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:151 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:157 msgid "Manage authors. Use to rename authors and correct individual author's sort values" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:165 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:164 msgid "Clear series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:200 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:199 msgid "Clear Ids" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:203 msgid "Paste the contents of the clipboard into the identifiers box prefixed with isbn:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:216 msgid "&Download metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:228 msgid "Configure download metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:233 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:232 msgid "Change how calibre downloads metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:294 #, python-format msgid " [%(num)d of %(tot)d]" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:326 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:332 msgid "Could not read cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:327 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:326 #, python-format msgid "Could not read cover from %s format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:333 #, python-format msgid "The cover in the %s format is invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:509 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:513 #, python-format msgid "Save changes and edit the metadata of %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:611 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:816 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:610 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:814 msgid "Change cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:670 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:668 msgid "Co&mments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:710 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:857 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:708 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:855 msgid "&Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:715 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:713 msgid "&Cover and formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:785 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:783 msgid "C&ustom metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:797 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:795 msgid "&Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:863 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:861 msgid "Basic metadata" msgstr "" @@ -12309,127 +12314,139 @@ msgstr "" msgid "Wide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:105 +msgid "Calibre style" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:105 +msgid "System default" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:142 msgid "Off" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:142 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:143 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:143 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:146 msgid "Always" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:146 msgid "If there is enough room" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:147 msgid "Never" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:142 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:511 msgid "By first letter" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:150 msgid "Disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:151 msgid "Partitioned" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:184 msgid "Column coloring" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel.py:190 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:132 #: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:223 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:227 msgid " or " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:223 -msgid "User Interface &layout (needs restart):" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:230 msgid "Choose &language (requires restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:231 msgid "Enable system &tray icon (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:226 -msgid "Disable all animations. Useful if you have a slow/old computer." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:227 -msgid "Disable &animations" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:228 -msgid "Disable ¬ifications in system tray" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:229 -msgid "Show &splash screen at startup" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:230 -msgid "&Toolbar" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:231 -msgid "&Icon size:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:232 -msgid "Show &text under icons:" +msgid "User Interface &layout (needs restart):" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:233 -msgid "Interface font:" +msgid "Disable all animations. Useful if you have a slow/old computer." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:234 -msgid "Change &font (needs restart)" +msgid "Disable &animations" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:235 -msgid "Main Interface" +msgid "Disable ¬ifications in system tray" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:236 -msgid "Select displayed metadata" +msgid "Show &splash screen at startup" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:237 -msgid "Move up" +msgid "&Toolbar" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:238 -msgid "Move down" +msgid "&Icon size:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:239 -msgid "Default author link template:" +msgid "Show &text under icons:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:240 +msgid "Interface font:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:241 +msgid "Change &font (needs restart)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:242 +msgid "User interface &style (needs restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:243 +msgid "Main Interface" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:244 +msgid "Select displayed metadata" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:245 +msgid "Move up" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:246 +msgid "Move down" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:247 +msgid "Default author link template:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:248 msgid "" "

Enter a template to be used to create a link for\n" "an author in the books information dialog. This template will\n" @@ -12438,19 +12455,19 @@ msgid "" "{author_sort}, and any template function." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:253 msgid "Use &Roman numerals for series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:246 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:254 msgid "Note that comments will always be displayed at the end, regardless of the position you assign here." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:248 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:256 msgid "Tags browser category &partitioning method:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:257 msgid "" "Choose how tag browser subcategories are displayed when\n" "there are more items than the limit. Select by first\n" @@ -12459,21 +12476,21 @@ msgid "" "if you never want subcategories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:254 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:262 msgid "&Collapse when more items than:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:255 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:263 msgid "" "If a Tag Browser category has more than this number of items, it is divided\n" "up into subcategories. If the partition method is set to disable, this value is ignored." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:265 msgid "Categories not to partition:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:266 msgid "" "A comma-separated list of categories that are not to\n" "be partitioned even if the number of items is larger than\n" @@ -12482,15 +12499,15 @@ msgid "" "a few top-level elements." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:271 msgid "Show &average ratings in the tags browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:272 msgid "Categories with &hierarchical items:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:273 msgid "" "A comma-separated list of categories in which items containing\n" "periods are displayed in the tag browser trees. For example, if\n" @@ -12500,58 +12517,58 @@ msgid "" "then the tags will be displayed each on their own line." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:280 msgid "Show cover &browser in a separate window (needs restart)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:281 msgid "&Number of covers to show in browse mode (needs restart):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:282 msgid "When showing cover browser in separate window, show it &fullscreen" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:275 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:283 #, python-format msgid "You can press the %s keys to toggle full screen mode." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:231 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks_ui.py:123 msgid "&Apply" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:238 msgid "Restore &defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:239 msgid "Save changes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:240 msgid "Cancel and return to overview" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:296 msgid "Restoring to defaults not supported for" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:332 msgid "Some of the changes you made require a restart. Please restart calibre as soon as possible." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:335 msgid "The changes you have made require calibre be restarted immediately. You will not be allowed to set any more preferences, until you restart." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:340 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:134 msgid "Restart needed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/main.py:342 msgid "Restart calibre now" msgstr "" @@ -13967,44 +13984,44 @@ msgstr "" msgid "%p%" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:308 msgid "The grouped search term name is \"{0}\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:734 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:735 msgid "Changing the authors for several books can take a while. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:739 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:740 msgid "Changing the metadata for that many books can take a while. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:826 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:827 #: /home/kovid/work/calibre/src/calibre/library/database2.py:469 msgid "Searches" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:903 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:923 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:932 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:904 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:924 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:933 msgid "Rename user category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:904 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:905 msgid "You cannot use periods in the name when renaming user categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:924 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:933 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:925 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:934 #, python-format msgid "The name %s is already used" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:952 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:953 msgid "Duplicate search name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:953 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:954 #, python-format msgid "The saved search name %s is already used." msgstr "" @@ -14026,13 +14043,13 @@ msgid "Manage Tags" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:480 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:484 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:494 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:498 msgid "Manage User Categories" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:472 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:486 msgid "Manage Saved Searches" msgstr "" @@ -14121,7 +14138,7 @@ msgid "No More Matches.

Click Find again to go to first match" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:391 -msgid "&Alter Tag Browser" +msgid "Alter Tag Browser" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:397 @@ -14169,110 +14186,110 @@ msgstr "" msgid "All of these category_managers are available by right-clicking on items in the tag browser above" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:353 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:392 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:422 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:367 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:406 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:436 #, python-format msgid "Rename %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:359 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:373 #, python-format msgid "Delete %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:377 #, python-format msgid "Edit sort for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:380 #, python-format msgid "Edit link for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:373 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:387 #, python-format msgid "Add %s to user category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:386 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:400 #, python-format msgid "Children of %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:396 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:410 #, python-format msgid "Delete search %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:401 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:415 #, python-format msgid "Remove %(item)s from category %(cat)s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:409 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:423 #, python-format msgid "Search for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:414 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:428 #, python-format msgid "Search for everything but %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:426 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:440 #, python-format msgid "Add sub-category to %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:430 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:444 #, python-format msgid "Delete user category %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:449 #, python-format msgid "Hide category %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:439 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:453 msgid "Show category" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:449 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:463 #, python-format msgid "Search for books in category %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:455 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:469 #, python-format msgid "Search for books not in category %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:464 -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:469 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:483 #, python-format msgid "Manage %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:491 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:505 msgid "Show all categories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:494 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:508 msgid "Change sub-categorization scheme" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:509 msgid "Disable" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:513 msgid "Partition" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:528 msgid "First letter is usable only when sorting by name" msgstr "" @@ -16672,6 +16689,14 @@ msgstr "" msgid "Whenever you pass arguments to %prog that have spaces in them, enclose the arguments in quotation marks." msgstr "" +#: /home/kovid/work/calibre/src/calibre/utils/config.py:92 +msgid "show this help message and exit" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:93 +msgid "show program's version number and exit" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/utils/config_base.py:377 msgid "Path to the database in which books are stored" msgstr "" diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index b5b8b566ba..a4ebcb28a1 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -89,6 +89,11 @@ class OptionParser(_OptionParser): formatter=CustomHelpFormatter(), conflict_handler=conflict_handler, **kwds) self.gui_mode = gui_mode + for o, msg in {'-h':_('show this help message and exit'), '--version': + _("show program's version number and exit")}.iteritems(): + opt = self.get_option(o) + if opt is not None: + opt.help = msg def error(self, msg): if self.gui_mode: From 7f8a5c51ff7eedca57874b5c5942f96ecb1af3c4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 21:25:22 +0530 Subject: [PATCH 16/53] Fix different background color for custom fields area in alt1 edit metadata layout dialog --- src/calibre/gui2/metadata/single.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index fd0d0a6953..064d12909e 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -785,7 +785,6 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{ gb.setLayout(gbl) sr = QScrollArea(tab0) sr.setWidgetResizable(True) - sr.setBackgroundRole(QPalette.Base) sr.setFrameStyle(QFrame.NoFrame) sr.setWidget(w) gbl.addWidget(sr) From b43c1c55499129a190b59f3eefb96781aa41fcb0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 21:25:48 +0530 Subject: [PATCH 17/53] ... --- src/calibre/gui2/metadata/single.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 064d12909e..151ba8a18b 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -922,7 +922,6 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{ sr = QScrollArea(gb) sr.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) sr.setWidgetResizable(True) - sr.setBackgroundRole(QPalette.Base) sr.setFrameStyle(QFrame.NoFrame) sr.setWidget(w) gbl.addWidget(sr) From a982f3c9dc2605658717b3b191ca1e5803fc5edc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 21:26:02 +0530 Subject: [PATCH 18/53] ... --- src/calibre/gui2/metadata/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 151ba8a18b..292a4e907b 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -13,7 +13,7 @@ from datetime import datetime from PyQt4.Qt import (Qt, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QGridLayout, pyqtSignal, QDialogButtonBox, QScrollArea, QFont, QTabWidget, QIcon, QToolButton, QSplitter, QGroupBox, QSpacerItem, - QSizePolicy, QPalette, QFrame, QSize, QKeySequence, QMenu, QShortcut) + QSizePolicy, QFrame, QSize, QKeySequence, QMenu, QShortcut) from calibre.ebooks.metadata import authors_to_string, string_to_authors from calibre.gui2 import ResizableDialog, error_dialog, gprefs, pixmap_to_data From e737f3c98a0d187a3f2b5e33f4608d58221cddbd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 23:04:26 +0530 Subject: [PATCH 19/53] ... --- session.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.vim b/session.vim index 4ded6d1bf3..f098c13cd3 100644 --- a/session.vim +++ b/session.vim @@ -2,7 +2,7 @@ let $PYFLAKES_BUILTINS = "_,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext" " Include directories for C modules -let g:syntastic_cpp_include_dirs = [ '/usr/include/podofo'] +let g:syntastic_cpp_include_dirs = [ '/usr/include/podofo', '/usr/include/qt4/QtCore', '/usr/include/qt4/QtGui', '/usr/include/qt4'] fun! CalibreLog() " Setup buffers to edit the calibre changelog and version info prior to From 69806aff7bc5b34a43501727afbb38913ac47626 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 23:16:58 +0530 Subject: [PATCH 20/53] ... --- src/calibre/library/cli.py | 2 +- src/calibre/translations/calibre.pot | 30 ++++++++++++++++++---------- src/calibre/utils/config.py | 10 +++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/calibre/library/cli.py b/src/calibre/library/cli.py index eb53cadb34..89241dc601 100644 --- a/src/calibre/library/cli.py +++ b/src/calibre/library/cli.py @@ -40,7 +40,7 @@ def write_dirtied(db): def get_parser(usage): parser = OptionParser(usage) - go = parser.add_option_group('GLOBAL OPTIONS') + go = parser.add_option_group(_('GLOBAL OPTIONS')) go.add_option('--library-path', '--with-library', default=None, help=_('Path to the calibre library. Default is to use the path stored in the settings.')) return parser diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index ae7132f881..21c895d0e2 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.8.54\n" -"POT-Creation-Date: 2012-06-01 21:10+IST\n" -"PO-Revision-Date: 2012-06-01 21:10+IST\n" +"POT-Creation-Date: 2012-06-01 23:16+IST\n" +"PO-Revision-Date: 2012-06-01 23:16+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -3072,7 +3072,7 @@ msgid "Producer" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:773 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:939 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:937 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/metadata_sources.py:157 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:245 msgid "Comments" @@ -3218,7 +3218,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1434 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1273 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:951 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:949 #: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41 msgid "Cover" msgstr "" @@ -8397,7 +8397,7 @@ msgid "Standard metadata" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:62 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:920 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:919 msgid "Custom metadata" msgstr "" @@ -11299,7 +11299,7 @@ msgid "Save changes and edit the metadata of %s" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:610 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:814 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:813 msgid "Change cover" msgstr "" @@ -11308,7 +11308,7 @@ msgid "Co&mments" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:708 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:855 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:854 msgid "&Metadata" msgstr "" @@ -11320,11 +11320,11 @@ msgstr "" msgid "C&ustom metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:795 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:794 msgid "&Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:861 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:860 msgid "Basic metadata" msgstr "" @@ -15765,6 +15765,10 @@ msgstr "" msgid "Folders raising exception" msgstr "" +#: /home/kovid/work/calibre/src/calibre/library/cli.py:43 +msgid "GLOBAL OPTIONS" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/library/cli.py:44 msgid "Path to the calibre library. Default is to use the path stored in the settings." msgstr "" @@ -16689,11 +16693,15 @@ msgstr "" msgid "Whenever you pass arguments to %prog that have spaces in them, enclose the arguments in quotation marks." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:92 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:94 +msgid "Options" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/config.py:95 msgid "show this help message and exit" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:93 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:96 msgid "show program's version number and exit" msgstr "" diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index a4ebcb28a1..65e59afbeb 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -89,11 +89,11 @@ class OptionParser(_OptionParser): formatter=CustomHelpFormatter(), conflict_handler=conflict_handler, **kwds) self.gui_mode = gui_mode - for o, msg in {'-h':_('show this help message and exit'), '--version': - _("show program's version number and exit")}.iteritems(): - opt = self.get_option(o) - if opt is not None: - opt.help = msg + if False: + # Translatable string from optparse + _("Options") + _("show this help message and exit") + _("show program's version number and exit") def error(self, msg): if self.gui_mode: From ececf6f9bbd51aebfd54c3f3bff733aa884a48be Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 23:18:40 +0530 Subject: [PATCH 21/53] ... --- session.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.vim b/session.vim index f098c13cd3..185e51ae0d 100644 --- a/session.vim +++ b/session.vim @@ -1,7 +1,7 @@ " Project wide builtins let $PYFLAKES_BUILTINS = "_,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext" -" Include directories for C modules +" Include directories for C++ modules let g:syntastic_cpp_include_dirs = [ '/usr/include/podofo', '/usr/include/qt4/QtCore', '/usr/include/qt4/QtGui', '/usr/include/qt4'] fun! CalibreLog() From f6f6d5236eb5b7780975843fdbe2b0ffa470959c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 00:54:08 +0530 Subject: [PATCH 22/53] Ensure that push buttons with no icons are not narrower than push buttons with icons --- src/calibre/gui2/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index f0f069639a..8ad0291d19 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -762,6 +762,11 @@ class Application(QApplication): self.setStyle('Plastique') elif 'Cleanlooks' in styles: self.setStyle('Cleanlooks') + # Ensure that pushbuttons with no icons are not narrower than + # pushbuttons with icons + from PyQt4.Qt import QPushButton + w = QPushButton() + self.setStyleSheet('QPushButton { min-height: %dpx }'%w.iconSize().height()) def _send_file_open_events(self): with self._file_open_lock: From 1122e26a00585989b6050f9f72d569080c243e13 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 09:24:09 +0530 Subject: [PATCH 23/53] Instapaper updated --- recipes/instapaper.recipe | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/recipes/instapaper.recipe b/recipes/instapaper.recipe index 40992e4d75..789b60ad73 100644 --- a/recipes/instapaper.recipe +++ b/recipes/instapaper.recipe @@ -1,9 +1,13 @@ -#v2 2011-07-25 +# Calibre recipe for Instapaper.com (Stable version) +# +# Homepage: http://khromov.wordpress.com/projects/instapaper-calibre-recipe/ +# Code Repository: https://bitbucket.org/khromov/calibre-instapaper + from calibre.web.feeds.news import BasicNewsRecipe class AdvancedUserRecipe1299694372(BasicNewsRecipe): title = u'Instapaper' - __author__ = 'Darko Miletic, Stanislav Khromov' + __author__ = 'Darko Miletic, Stanislav Khromov, Jim Ramsay' publisher = 'Instapaper.com' category = 'info, custom, Instapaper' oldest_article = 365 @@ -11,25 +15,27 @@ class AdvancedUserRecipe1299694372(BasicNewsRecipe): no_stylesheets = True remove_javascript = True remove_tags = [ - dict(name='div', attrs={'id':'text_controls_toggle'}) - ,dict(name='script') - ,dict(name='div', attrs={'id':'text_controls'}) - ,dict(name='div', attrs={'id':'editing_controls'}) - ,dict(name='div', attrs={'class':'bar bottom'}) + dict(name='div', attrs={'id':'text_controls_toggle'}) + ,dict(name='script') + ,dict(name='div', attrs={'id':'text_controls'}) + ,dict(name='div', attrs={'id':'editing_controls'}) + ,dict(name='div', attrs={'class':'bar bottom'}) ,dict(name='div', attrs={'id':'controlbar_container'}) ,dict(name='div', attrs={'id':'footer'}) - ] + ] use_embedded_content = False needs_subscription = True INDEX = u'http://www.instapaper.com' LOGIN = INDEX + u'/user/login' - feeds = [ - (u'Instapaper Unread', u'http://www.instapaper.com/u'), + (u'Instapaper Unread', u'http://www.instapaper.com/u') (u'Instapaper Starred', u'http://www.instapaper.com/starred') ] + #Adds the title tag to the body of the recipe. Use this if your articles miss headings. + add_title_tag = False; + def get_browser(self): br = BasicNewsRecipe.get_browser() if self.username is not None: @@ -67,7 +73,10 @@ class AdvancedUserRecipe1299694372(BasicNewsRecipe): article.title = soup.find('title').contents[0].strip() def postprocess_html(self, soup, first_fetch): - for link_tag in soup.findAll(attrs={"id" : "story"}): - link_tag.insert(0,'

'+soup.find('title').contents[0].strip()+'

') + #adds the title to each story, as it is not always included + if self.add_title_tag: + for link_tag in soup.findAll(attrs={"id" : "story"}): + link_tag.insert(0,'

'+soup.find('title').contents[0].strip()+'

') + #print repr(soup) return soup From 5a4ea8c01ceae48603ccb348bcbef1d054edfc1b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 10:02:33 +0530 Subject: [PATCH 24/53] ... --- src/calibre/devices/scanner.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index 012708b0da..8460ecbdef 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -8,6 +8,7 @@ manner. import sys, os, re from threading import RLock +from calibre import prints, as_unicode from calibre.constants import iswindows, isosx, plugins, islinux, isfreebsd osx_scanner = win_scanner = linux_scanner = None @@ -53,7 +54,10 @@ class WinPNPScanner(object): ans = True try: win32file.GetDiskFreeSpaceEx(letter+':\\') - except: + except Exception as e: + if debug: + prints('Unable to get free space for drive:', letter) + prints(as_unicode(e)) ans = False return ans finally: From caaad4498308ecc723e1dfa5ad3c83dde82e30e8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 10:18:26 +0530 Subject: [PATCH 25/53] ... --- src/calibre/gui2/metadata/single_download.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py index 4736cf3ca2..a59b7fb57a 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -49,7 +49,9 @@ class RichTextDelegate(QStyledItemDelegate): # {{{ doc = QTextDocument() if option is not None and option.state & QStyle.State_Selected: p = option.palette - c = p.color(p.Active, p.HighlightedText) + group = (p.Active if option.state & QStyle.State_Active else + p.Inactive) + c = p.color(group, p.HighlightedText) c = 'rgb(%d, %d, %d)'%c.getRgb()[:3] doc.setDefaultStyleSheet(' * { color: %s }'%c) doc.setHtml(index.data().toString()) From 8bb3c0a7452d1110646c8933183fd87d4c46531b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 10:37:22 +0530 Subject: [PATCH 26/53] ... --- src/calibre/gui2/metadata/single.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 292a4e907b..9256739d22 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -57,9 +57,7 @@ class MetadataSingleDialogBase(ResizableDialog): if sc: self.download_shortcut.setKey(sc[0]) - self.button_box = QDialogButtonBox( - QDialogButtonBox.Ok|QDialogButtonBox.Cancel, Qt.Horizontal, - self) + self.button_box = bb = QDialogButtonBox(self) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.next_button = QPushButton(QIcon(I('forward.png')), _('Next'), @@ -70,9 +68,11 @@ class MetadataSingleDialogBase(ResizableDialog): self) self.prev_button.setShortcut(QKeySequence('Alt+Left')) - self.button_box.addButton(self.prev_button, self.button_box.ActionRole) - self.button_box.addButton(self.next_button, self.button_box.ActionRole) + self.button_box.addButton(self.prev_button, bb.ActionRole) + self.button_box.addButton(self.next_button, bb.ActionRole) self.prev_button.clicked.connect(self.prev_clicked) + bb.setStandardButtons(bb.Ok|bb.Cancel) + bb.button(bb.Ok).setDefault(True) self.scroll_area = QScrollArea(self) self.scroll_area.setFrameShape(QScrollArea.NoFrame) @@ -508,15 +508,14 @@ class MetadataSingleDialogBase(ResizableDialog): tip = (_('Save changes and edit the metadata of %s')+ ' [Alt+Right]')%next_ self.next_button.setToolTip(tip) - self.next_button.setVisible(next_ is not None) + self.next_button.setEnabled(next_ is not None) if prev is not None: tip = (_('Save changes and edit the metadata of %s')+ ' [Alt+Left]')%prev self.prev_button.setToolTip(tip) - self.prev_button.setVisible(prev is not None) + self.prev_button.setEnabled(prev is not None) self(self.db.id(self.row_list[self.current_row])) - def break_cycles(self): # Break any reference cycles that could prevent python # from garbage collecting this dialog From 3d15f57526d0f3f5b4c2fb3afa4503a18ad47a85 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 11:39:49 +0530 Subject: [PATCH 27/53] Better error message when viewing corrupted epub files --- src/calibre/gui2/viewer/main.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 0ce6c3d48b..ee0d3bd361 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -28,6 +28,7 @@ from calibre.customize.ui import available_input_formats from calibre.gui2.viewer.dictionary import Lookup from calibre import as_unicode, force_unicode, isbytestring from calibre.ptempfile import reset_base_dir +from calibre.utils.zipfile import BadZipfile vprefs = JSONConfig('viewer') @@ -37,6 +38,11 @@ class Worker(Thread): try: Thread.run(self) self.exception = self.traceback = None + except BadZipfile: + self.exception = _( + 'This ebook is corrupted and cannot be opened. If you ' + 'downloaded it from somewhere, try downloading it again.') + self.traceback = '' except Exception as err: self.exception = err self.traceback = traceback.format_exc() From 98d308dfcfcf366a884ddccea7a2c3e14fedfbd4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 14:13:08 +0530 Subject: [PATCH 28/53] Infrastructure for dynamically loading Qt style plugins from python --- .../progress_indicator/QProgressIndicator.cpp | 23 +++++++++++++++++++ .../progress_indicator/QProgressIndicator.h | 9 ++++++++ .../progress_indicator/QProgressIndicator.sip | 7 ++++++ 3 files changed, 39 insertions(+) diff --git a/src/calibre/gui2/progress_indicator/QProgressIndicator.cpp b/src/calibre/gui2/progress_indicator/QProgressIndicator.cpp index 24d69bc164..64fd346674 100644 --- a/src/calibre/gui2/progress_indicator/QProgressIndicator.cpp +++ b/src/calibre/gui2/progress_indicator/QProgressIndicator.cpp @@ -1,6 +1,10 @@ #include "QProgressIndicator.h" #include +#include +#include +#include +#include QProgressIndicator::QProgressIndicator(QWidget* parent, int size) : QWidget(parent), @@ -122,3 +126,22 @@ void QProgressIndicator::paintEvent(QPaintEvent * /*event*/) p.restore(); } } + +int load_style(QString &path, QString &name) { + int ret = 0; + QStyle *s; + QPluginLoader pl(path); + QObject *o = pl.instance(); + if (o != 0) { + QStylePlugin *sp = qobject_cast(o); + if (sp != 0) { + s = sp->create(name); + if (s != 0) { + s->setObjectName(name); + QApplication::setStyle(s); + ret = 1; + } + } + } + return ret; +} diff --git a/src/calibre/gui2/progress_indicator/QProgressIndicator.h b/src/calibre/gui2/progress_indicator/QProgressIndicator.h index c2098ffe64..0fd82a99f5 100644 --- a/src/calibre/gui2/progress_indicator/QProgressIndicator.h +++ b/src/calibre/gui2/progress_indicator/QProgressIndicator.h @@ -91,3 +91,12 @@ private: QColor m_color; }; +/* Utility function that can be used to load a QStyle from a Qt plugin. This is + * here so that there is no need to create a separate PyQt plugin just for this + * simple functionality. + * \param path The full path to the DLL containing the plugin + * \param name The name of the style plugin to load + * \return 1 if succeeds 0 otherwise. The objectName of the loaded style is set to name + */ +int load_style(QString &path, QString &name); + diff --git a/src/calibre/gui2/progress_indicator/QProgressIndicator.sip b/src/calibre/gui2/progress_indicator/QProgressIndicator.sip index 3db47d668a..03c6dacdd6 100644 --- a/src/calibre/gui2/progress_indicator/QProgressIndicator.sip +++ b/src/calibre/gui2/progress_indicator/QProgressIndicator.sip @@ -6,6 +6,10 @@ %Import QtCore/QtCoremod.sip %Import QtGui/QtGuimod.sip +%ModuleHeaderCode +int load_style(QString &path, QString &name); +%End + class QProgressIndicator : QWidget { %TypeHeaderCode @@ -50,3 +54,6 @@ protected: virtual void paintEvent(QPaintEvent * event); }; + +int load_style(QString &path, QString &name); + From fdfac7f3df458a0d6ac54eeb703862403669448a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 14:16:36 +0530 Subject: [PATCH 29/53] Update Marketing Magazine --- recipes/marketing_magazine.recipe | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/marketing_magazine.recipe b/recipes/marketing_magazine.recipe index d004f274af..613b15fd42 100644 --- a/recipes/marketing_magazine.recipe +++ b/recipes/marketing_magazine.recipe @@ -17,5 +17,5 @@ class AdvancedUserRecipe1327062445(BasicNewsRecipe): remove_tags = [ dict(name='ul', attrs={'id':'ads0'}) ] - masthead_url = 'http://www.simrendeogun.com/wp-content/uploads/2011/06/New-Marketing-Magazine-Logo.jpg' - feeds = [(u'My Marketing', u'http://feed43.com/0537744466058428.xml'), (u'My Marketing_', u'http://feed43.com/8126723074604845.xml'), (u'MarketingArena', u'http://feeds.feedburner.com/marketingarena'), (u'Marketing Journal', u'http://feeds.feedburner.com/marketingjournal/jPwA'), (u'Venturini', u'http://robertoventurini.blogspot.com/feeds/posts/default?alt=rss'), (u'Brandforum news', u'http://www.brandforum.it/rss/news'), (u'Brandforum papers', u'http://www.brandforum.it/rss/papers'), (u'minimarketing', u'http://feeds.feedburner.com/minimarketingit'), (u'[4]marketing.biz', u'http://feeds.feedburner.com/4marketing'), (u'Ninja Marketing', u'http://feeds.feedburner.com/NinjaMarketing'), (u'Bloguerrilla', u'http://feeds.feedburner.com/Bloguerrilla'), (u'Nonconvenzionale', u'http://feeds.feedburner.com/nonconvenzionale'), (u'Comunitàzione', u'http://www.comunitazione.it/feed/novita.asp'), (u'Disambiguando', u'http://giovannacosenza.wordpress.com/feed/')] + masthead_url = 'http://www.linkedin-marketing.it/blog/wp-content/uploads/2012/03/pb.jpg' + feeds = [(u'MarketingArena', u'http://feeds.feedburner.com/marketingarena'), (u'My Marketing', u'http://feed43.com/0537744466058428.xml'), (u'My Marketing_', u'http://feed43.com/8126723074604845.xml'), (u'Marketing Journal', u'http://feeds.feedburner.com/marketingjournal/jPwA'), (u'Venturini', u'http://robertoventurini.blogspot.com/feeds/posts/default?alt=rss'), (u'Brandforum news', u'http://www.brandforum.it/rss/news'), (u'Brandforum papers', u'http://www.brandforum.it/rss/papers'), (u'SintBlog', u'http://sint-blog.blogspot.com/feeds/posts/default'), (u'Ninja Marketing', u'http://feeds.feedburner.com/NinjaMarketing'), (u'Bloguerrilla', u'http://feeds.feedburner.com/Bloguerrilla'), (u'Nonconvenzionale', u'http://feeds.feedburner.com/nonconvenzionale'), (u'Disambiguando', u'http://giovannacosenza.wordpress.com/feed/')] From eb9861b5a1a16f6c09637a0478711d4f1dee8621 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 23:28:53 +0530 Subject: [PATCH 30/53] ... --- src/calibre/gui2/__init__.py | 9 ++++++--- src/calibre/gui2/metadata/single.py | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 8ad0291d19..55c59b3677 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -731,6 +731,9 @@ class Application(QApplication): qt_app = self self._file_open_paths = [] self._file_open_lock = RLock() + self.setup_styles() + + def setup_styles(self): self.original_font = QFont(QApplication.font()) fi = gprefs['font'] if fi is not None: @@ -739,9 +742,7 @@ class Application(QApplication): if s is not None: font.setStretch(s) QApplication.setFont(font) - self.setup_styles() - def setup_styles(self): if gprefs['widget_style'] != 'system': # On OS X QtCurve resets the palette, so we preserve it explicitly orig_pal = QPalette(self.palette()) @@ -766,7 +767,9 @@ class Application(QApplication): # pushbuttons with icons from PyQt4.Qt import QPushButton w = QPushButton() - self.setStyleSheet('QPushButton { min-height: %dpx }'%w.iconSize().height()) + self.setStyleSheet('QPushButton { min-height: %dpx }'% + (w.iconSize().height())) + def _send_file_open_events(self): with self._file_open_lock: diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 9256739d22..eb00e8365a 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -87,7 +87,6 @@ class MetadataSingleDialogBase(ResizableDialog): self.l.addLayout(ll) ll.addSpacing(10) ll.addWidget(self.button_box) - ll.addSpacing(10) self.setWindowIcon(QIcon(I('edit_input.png'))) self.setWindowTitle(BASE_TITLE) From ac500c4c8c0a69a38b861781194f1d1057b44646 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 2 Jun 2012 23:58:20 +0530 Subject: [PATCH 31/53] Fix #1007900 (LG Android Phone fails to connect) --- src/calibre/devices/android/driver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index 6641b631a6..c4abb54556 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -122,9 +122,9 @@ class ANDROID(USBMS): # LG 0x1004 : { - 0x61c5 : [0x100, 0x226, 0x9999], - 0x61cc : [0x100], - 0x61ce : [0x100], + 0x61c5 : [0x100, 0x226, 0x227, 0x9999], + 0x61cc : [0x226, 0x227, 0x9999, 0x100], + 0x61ce : [0x226, 0x227, 0x9999, 0x100], 0x618e : [0x226, 0x227, 0x9999, 0x100], 0x6205 : [0x226, 0x227, 0x9999, 0x100], }, From 43bf3cc68dfc72ef6f1612aff081971f351db49a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 01:15:17 +0530 Subject: [PATCH 32/53] ... --- src/calibre/gui2/__init__.py | 7 ------- src/calibre/gui2/metadata/single.py | 12 +++++++++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 55c59b3677..f55e4c571e 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -763,13 +763,6 @@ class Application(QApplication): self.setStyle('Plastique') elif 'Cleanlooks' in styles: self.setStyle('Cleanlooks') - # Ensure that pushbuttons with no icons are not narrower than - # pushbuttons with icons - from PyQt4.Qt import QPushButton - w = QPushButton() - self.setStyleSheet('QPushButton { min-height: %dpx }'% - (w.iconSize().height())) - def _send_file_open_events(self): with self._file_open_lock: diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index eb00e8365a..85d543d8ca 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -96,11 +96,21 @@ class MetadataSingleDialogBase(ResizableDialog): if len(self.db.custom_column_label_map): self.create_custom_metadata_widgets() - self.do_layout() geom = gprefs.get('metasingle_window_geometry3', None) if geom is not None: self.restoreGeometry(bytes(geom)) + self.title.resizeEvent = self.fix_push_buttons + + def fix_push_buttons(self, *args): + # Ensure all PushButtons stay the same consistent height throughout this + # dialog. Without this, the buttons inside scrollareas get shrunk, + # while the buttons outside them do not, leading to weirdness. + ht = self.title.height() + for but in self.findChildren(QPushButton): + but.setMaximumHeight(ht) + but.setMinimumHeight(ht) + return TitleEdit.resizeEvent(self.title, *args) # }}} def create_basic_metadata_widgets(self): # {{{ From 4c99108b03b2a1f1af842b5511963c16babdb8a8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 01:20:23 +0530 Subject: [PATCH 33/53] ... --- src/calibre/gui2/metadata/single.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 85d543d8ca..51e63429ee 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -106,6 +106,8 @@ class MetadataSingleDialogBase(ResizableDialog): # Ensure all PushButtons stay the same consistent height throughout this # dialog. Without this, the buttons inside scrollareas get shrunk, # while the buttons outside them do not, leading to weirdness. + # Further, buttons with and without icons have different minimum sizes + # so things look even more out of whack. ht = self.title.height() for but in self.findChildren(QPushButton): but.setMaximumHeight(ht) From e545b5eb360c822f4bee219d8af1cf359c81cde4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 09:46:09 +0530 Subject: [PATCH 34/53] ... --- recipes/instapaper.recipe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/instapaper.recipe b/recipes/instapaper.recipe index 789b60ad73..4481866550 100644 --- a/recipes/instapaper.recipe +++ b/recipes/instapaper.recipe @@ -29,7 +29,7 @@ class AdvancedUserRecipe1299694372(BasicNewsRecipe): LOGIN = INDEX + u'/user/login' feeds = [ - (u'Instapaper Unread', u'http://www.instapaper.com/u') + (u'Instapaper Unread', u'http://www.instapaper.com/u'), (u'Instapaper Starred', u'http://www.instapaper.com/starred') ] From 5cc583c3bd2017f9016385fa02f762d088489b71 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 11:34:25 +0530 Subject: [PATCH 35/53] Dont try to start VMs if already running --- setup/installer/__init__.py | 8 ++++++++ setup/installer/windows/__init__.py | 1 + 2 files changed, 9 insertions(+) diff --git a/setup/installer/__init__.py b/setup/installer/__init__.py index 8374f93e38..e8bdda069f 100644 --- a/setup/installer/__init__.py +++ b/setup/installer/__init__.py @@ -67,6 +67,7 @@ class VMInstaller(Command): INSTALLER_EXT = None VM = None VM_NAME = None + VM_CHECK = None FREEZE_COMMAND = None FREEZE_TEMPLATE = 'python setup.py {freeze_command}' SHUTDOWN_CMD = ['sudo', 'poweroff'] @@ -117,6 +118,13 @@ class VMInstaller(Command): def run_vm(self): + pat = '/%s/'%(self.VM_CHECK or self.VM_NAME) + pids= [pid for pid in os.listdir('/proc') if pid.isdigit()] + for pid in pids: + cmdline = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read() + if 'vmware-vmx' in cmdline and pat in cmdline: + return + self.__p = subprocess.Popen([self.vm]) def start_vm(self, sleep=75): diff --git a/setup/installer/windows/__init__.py b/setup/installer/windows/__init__.py index 324dea6e0f..a7b4a62af4 100644 --- a/setup/installer/windows/__init__.py +++ b/setup/installer/windows/__init__.py @@ -28,6 +28,7 @@ class Win32(VMInstaller): INSTALLER_EXT = 'exe' VM_NAME = 'xp_build' VM = '/vmware/bin/%s'%VM_NAME + VM_CHECK = 'calibre_windows_xp_home' FREEZE_COMMAND = 'win32_freeze' FREEZE_TEMPLATE = 'python -OO setup.py {freeze_command} --no-ice' INSTALLER_EXT = 'msi' From 28d6e8591369c128361da6dd4eb4f418a2a17364 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 11:50:33 +0530 Subject: [PATCH 36/53] Import QtCurve into the calibre source tree so I can fix the various platform specific bugs myself --- COPYRIGHT | 6 + setup/extensions.py | 99 + setup/installer/osx/app/main.py | 4 - setup/installer/windows/freeze.py | 10 +- setup/installer/windows/notes.rst | 8 - src/calibre/gui2/__init__.py | 23 +- src/qtcurve/AUTHORS | 1 + src/qtcurve/COPYING | 340 + src/qtcurve/common/check_on.png | Bin 0 -> 179 bytes src/qtcurve/common/check_x_on.png | Bin 0 -> 154 bytes src/qtcurve/common/colorutils.c | 342 + src/qtcurve/common/colorutils.h | 11 + src/qtcurve/common/common.c | 728 ++ src/qtcurve/common/common.h | 1383 +++ src/qtcurve/common/config_file.c | 3563 ++++++ src/qtcurve/common/config_file.h | 49 + src/qtcurve/common/dot.png | Bin 0 -> 130 bytes src/qtcurve/common/radio_frame.png | Bin 0 -> 419 bytes src/qtcurve/common/radio_inner.png | Bin 0 -> 276 bytes src/qtcurve/common/radio_light.png | Bin 0 -> 236 bytes src/qtcurve/common/radio_on.png | Bin 0 -> 221 bytes src/qtcurve/common/radio_on_small.png | Bin 0 -> 258 bytes src/qtcurve/common/shadow.png | Bin 0 -> 1856 bytes src/qtcurve/common/shadow0.png | Bin 0 -> 243 bytes src/qtcurve/common/shadow1.png | Bin 0 -> 632 bytes src/qtcurve/common/shadow2.png | Bin 0 -> 262 bytes src/qtcurve/common/shadow3.png | Bin 0 -> 825 bytes src/qtcurve/common/shadow4.png | Bin 0 -> 297 bytes src/qtcurve/common/shadow5.png | Bin 0 -> 807 bytes src/qtcurve/common/shadow6.png | Bin 0 -> 260 bytes src/qtcurve/common/shadow7.png | Bin 0 -> 591 bytes src/qtcurve/common/slider.png | Bin 0 -> 311 bytes src/qtcurve/common/slider_light.png | Bin 0 -> 199 bytes src/qtcurve/style/blurhelper.cpp | 227 + src/qtcurve/style/blurhelper.h | 188 + src/qtcurve/style/dialogpixmaps.h | 343 + src/qtcurve/style/fixx11h.h | 306 + src/qtcurve/style/macmenu-dbus.h | 51 + src/qtcurve/style/macmenu.cpp | 502 + src/qtcurve/style/macmenu.h | 82 + src/qtcurve/style/pixmaps.h | 36 + src/qtcurve/style/qtcurve.cpp | 13918 ++++++++++++++++++++++++ src/qtcurve/style/qtcurve.h | 379 + src/qtcurve/style/qtcurve.themerc | 10 + src/qtcurve/style/shadow.h | 320 + src/qtcurve/style/shadowhelper.cpp | 285 + src/qtcurve/style/shadowhelper.h | 126 + src/qtcurve/style/shortcuthandler.cpp | 179 + src/qtcurve/style/shortcuthandler.h | 65 + src/qtcurve/style/utils.cpp | 81 + src/qtcurve/style/utils.h | 41 + src/qtcurve/style/windowmanager.cpp | 793 ++ src/qtcurve/style/windowmanager.h | 325 + 53 files changed, 24794 insertions(+), 30 deletions(-) create mode 100644 src/qtcurve/AUTHORS create mode 100644 src/qtcurve/COPYING create mode 100644 src/qtcurve/common/check_on.png create mode 100644 src/qtcurve/common/check_x_on.png create mode 100644 src/qtcurve/common/colorutils.c create mode 100644 src/qtcurve/common/colorutils.h create mode 100644 src/qtcurve/common/common.c create mode 100644 src/qtcurve/common/common.h create mode 100644 src/qtcurve/common/config_file.c create mode 100644 src/qtcurve/common/config_file.h create mode 100644 src/qtcurve/common/dot.png create mode 100644 src/qtcurve/common/radio_frame.png create mode 100644 src/qtcurve/common/radio_inner.png create mode 100644 src/qtcurve/common/radio_light.png create mode 100644 src/qtcurve/common/radio_on.png create mode 100644 src/qtcurve/common/radio_on_small.png create mode 100644 src/qtcurve/common/shadow.png create mode 100644 src/qtcurve/common/shadow0.png create mode 100644 src/qtcurve/common/shadow1.png create mode 100644 src/qtcurve/common/shadow2.png create mode 100644 src/qtcurve/common/shadow3.png create mode 100644 src/qtcurve/common/shadow4.png create mode 100644 src/qtcurve/common/shadow5.png create mode 100644 src/qtcurve/common/shadow6.png create mode 100644 src/qtcurve/common/shadow7.png create mode 100644 src/qtcurve/common/slider.png create mode 100644 src/qtcurve/common/slider_light.png create mode 100644 src/qtcurve/style/blurhelper.cpp create mode 100644 src/qtcurve/style/blurhelper.h create mode 100644 src/qtcurve/style/dialogpixmaps.h create mode 100644 src/qtcurve/style/fixx11h.h create mode 100644 src/qtcurve/style/macmenu-dbus.h create mode 100644 src/qtcurve/style/macmenu.cpp create mode 100644 src/qtcurve/style/macmenu.h create mode 100644 src/qtcurve/style/pixmaps.h create mode 100644 src/qtcurve/style/qtcurve.cpp create mode 100644 src/qtcurve/style/qtcurve.h create mode 100644 src/qtcurve/style/qtcurve.themerc create mode 100644 src/qtcurve/style/shadow.h create mode 100644 src/qtcurve/style/shadowhelper.cpp create mode 100644 src/qtcurve/style/shadowhelper.h create mode 100644 src/qtcurve/style/shortcuthandler.cpp create mode 100644 src/qtcurve/style/shortcuthandler.h create mode 100644 src/qtcurve/style/utils.cpp create mode 100644 src/qtcurve/style/utils.h create mode 100644 src/qtcurve/style/windowmanager.cpp create mode 100644 src/qtcurve/style/windowmanager.h diff --git a/COPYRIGHT b/COPYRIGHT index 2a45fdb1c1..eb4433f96d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -16,6 +16,12 @@ License: BSD The full text of the BSD license is distributed as in /usr/share/common-licenses/BSD on Debian systems. +Files: src/qtcurve/* +Copyright: Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com +License: GPL-2 + The full text of the GPL is distributed as in + /usr/share/common-licenses/GPL-2 on Debian systems. + Files: src/calibre/ebooks/chardet/* Copyright: Copyright (C) 1998-2001 Netscape Communications Corporation License: LGPL-2.1+ diff --git a/setup/extensions.py b/setup/extensions.py index dadb84233d..a264885a8b 100644 --- a/setup/extensions.py +++ b/setup/extensions.py @@ -8,6 +8,7 @@ __docformat__ = 'restructuredtext en' import textwrap, os, shlex, subprocess, glob, shutil from distutils import sysconfig +from multiprocessing import cpu_count from PyQt4.pyqtconfig import QtGuiModuleMakefile @@ -268,6 +269,7 @@ class Build(Command): self.obj_dir = os.path.join(os.path.dirname(SRC), 'build', 'objects') if not os.path.exists(self.obj_dir): os.makedirs(self.obj_dir) + self.build_style(self.j(self.SRC, 'calibre', 'plugins')) for ext in extensions: if opts.only != 'all' and opts.only != ext.name: continue @@ -362,6 +364,103 @@ class Build(Command): print "Error while executing: %s\n" % (cmdline) raise + def build_style(self, dest): + self.info('\n####### Building calibre style', '#'*7) + sdir = self.j(self.SRC, 'qtcurve') + def path(x): + return '"%s"'%self.j(sdir, x).replace(os.sep, '/') + headers = [ + "common/colorutils.h", + "common/common.h", + "common/config_file.h", + "style/blurhelper.h", + "style/dialogpixmaps.h", + "style/fixx11h.h", + "style/pixmaps.h", + "style/qtcurve.h", + "style/shortcuthandler.h", + "style/utils.h", + "style/windowmanager.h", + ] + sources = [ + "common/colorutils.c", + "common/common.c", + "common/config_file.c", + "style/blurhelper.cpp", + "style/qtcurve.cpp", + "style/shortcuthandler.cpp", + "style/utils.cpp", + "style/windowmanager.cpp", + ] + if not iswindows and not isosx: + headers.append( "style/shadowhelper.h") + sources.append('style/shadowhelper.cpp') + + pro = textwrap.dedent(''' + TEMPLATE = lib + CONFIG += qt plugin release + CONFIG -= embed_manifest_dll + VERSION = 1.0.0 + DESTDIR = . + TARGET = calibre + QT *= svg + INCLUDEPATH *= . {inc} + win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS + + # Force C++ language + *g++*:QMAKE_CFLAGS *= -x c++ + *msvc*:QMAKE_CFLAGS *= -TP + *msvc*:QMAKE_CXXFLAGS += /MP + + ''').format(inc=path('common')) + if isosx: + pro += '\nCONFIG += x86 x86_64\n' + else: + pro += '\nunix:QT *= dbus\n' + + for x in headers: + pro += 'HEADERS += %s\n'%path(x) + for x in sources: + pro += 'SOURCES += %s\n'%path(x) + config = textwrap.dedent(''' + #pragma once + + /* #define VERSION "1.5.3" */ + #define KDE3PREFIX "/usr" + #define KDE4PREFIX "/usr" + + #define QTC_QT_ONLY + /* #undef QTC_OLD_NVIDIA_ARROW_FIX */ + #undef QTC_STYLE_SUPPORT + /* #undef QTC_KWIN_MAX_BUTTON_HACK */ + ''') + odir = self.j(self.d(self.SRC), 'build', 'qtcurve') + if not os.path.exists(odir): + os.makedirs(odir) + ocwd = os.getcwdu() + os.chdir(odir) + try: + if not os.path.exists('qtcurve.pro') or (open('qtcurve.pro', + 'rb').read() != pro): + with open('qtcurve.pro', 'wb') as f: + f.write(pro) + if not os.path.exists('config.h') or (open('config.h', + 'rb').read() != config): + with open('config.h', 'wb') as f: + f.write(config) + qmc = [QMAKE, '-o', 'Makefile'] + if iswindows: + qmc += ['-spec', 'win32-msvc2008'] + self.check_call(qmc + ['qtcurve.pro']) + self.check_call([make]+([] if iswindows else ['-j%d'%(cpu_count() + or 1)])) + src = (glob.glob('*.so') + glob.glob('release/*.dll') + + glob.glob('*.dylib')) + ext = 'pyd' if iswindows else 'so' + shutil.copy2(src[0], self.j(dest, 'calibre_style.'+ext)) + finally: + os.chdir(ocwd) + def build_qt_objects(self, ext): obj_pat = 'release\\*.obj' if iswindows else '*.o' objects = glob.glob(obj_pat) diff --git a/setup/installer/osx/app/main.py b/setup/installer/osx/app/main.py index b7eb864de0..2cf7e1df48 100644 --- a/setup/installer/osx/app/main.py +++ b/setup/installer/osx/app/main.py @@ -296,10 +296,6 @@ class Py2App(object): self.add_qt_framework(f) for d in glob.glob(join(SW, 'qt', 'plugins', '*')): shutil.copytree(d, join(self.contents_dir, 'MacOS', basename(d))) - sty = join(self.contents_dir, 'MacOS', 'styles') - os.mkdir(sty) - shutil.copyfile(glob.glob(join(SW, 'build', 'QtCurve*', 'build', 'style', - 'qtcurve.so'))[-1], join(sty, 'qtcurve.dylib')) for l in glob.glob(join(self.contents_dir, 'MacOS', '*/*.dylib')): self.fix_dependencies_in_lib(l) x = os.path.relpath(l, join(self.contents_dir, 'MacOS')) diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py index dc331699f3..f87d587f21 100644 --- a/setup/installer/windows/freeze.py +++ b/setup/installer/windows/freeze.py @@ -248,13 +248,6 @@ class Win32Freeze(Command, WixMixIn): if os.path.exists(tg): shutil.rmtree(tg) shutil.copytree(imfd, tg) - self.info('\nAdding QtCurve...') - qtcurve = self.j(QTCURVE, 'qtcurve.dll') - tg = self.j(tdir, 'styles') - if os.path.exists(tg): - shutil.rmtree(tg) - os.mkdir(tg) - shutil.copy2(qtcurve, tg) for dirpath, dirnames, filenames in os.walk(tdir): for x in filenames: @@ -494,7 +487,8 @@ class Win32Freeze(Command, WixMixIn): # Add the .pyds from python and calibre to the zip file for x in (self.plugins_dir, self.dll_dir): for pyd in os.listdir(x): - if pyd.endswith('.pyd') and pyd != 'sqlite_custom.pyd': + if pyd.endswith('.pyd') and pyd not in { + 'sqlite_custom.pyd', 'calibre_style.pyd'}: # sqlite_custom has to be a file for # sqlite_load_extension to work self.add_to_zipfile(zf, pyd, x) diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index 349141d658..7fe978d30b 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -101,14 +101,6 @@ Now, run configure and make:: Add the path to the bin folder inside the Qt dir to your system PATH. -Now build QtCurve -cd qmake -edit the qmake.pro file setting the TARGET to Release - -qmake && nmake - -The plugin will be in c:\plugins\styles - SIP ----- diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index f55e4c571e..a0fbab7bbc 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -733,6 +733,16 @@ class Application(QApplication): self._file_open_lock = RLock() self.setup_styles() + def load_calibre_style(self): + # On OS X QtCurve resets the palette, so we preserve it explicitly + orig_pal = QPalette(self.palette()) + from calibre.constants import plugins + pi = plugins['progress_indicator'][0] + path = os.path.join(sys.extensions_location, 'calibre_style.'+( + 'pyd' if iswindows else 'so')) + pi.load_style(path, 'Calibre') + self.setPalette(orig_pal) + def setup_styles(self): self.original_font = QFont(QApplication.font()) fi = gprefs['font'] @@ -744,10 +754,7 @@ class Application(QApplication): QApplication.setFont(font) if gprefs['widget_style'] != 'system': - # On OS X QtCurve resets the palette, so we preserve it explicitly - orig_pal = QPalette(self.palette()) - QApplication.setStyle('QtCurve') - self.setPalette(orig_pal) + self.load_calibre_style() else: st = self.style() if st is not None: @@ -755,12 +762,8 @@ class Application(QApplication): if (islinux or isbsd) and st in ('windows', 'motif', 'cde'): from PyQt4.Qt import QStyleFactory styles = set(map(unicode, QStyleFactory.keys())) - if 'QtCurve' in styles and os.environ.get('KDE_FULL_SESSION', - False): - self.setStyle('QtCurve') - elif 'Plastique' in styles and os.environ.get('KDE_FULL_SESSION', - False): - self.setStyle('Plastique') + if os.environ.get('KDE_FULL_SESSION', False): + self.load_calibre_style() elif 'Cleanlooks' in styles: self.setStyle('Cleanlooks') diff --git a/src/qtcurve/AUTHORS b/src/qtcurve/AUTHORS new file mode 100644 index 0000000000..5f68aed5b4 --- /dev/null +++ b/src/qtcurve/AUTHORS @@ -0,0 +1 @@ +Craig Drummond diff --git a/src/qtcurve/COPYING b/src/qtcurve/COPYING new file mode 100644 index 0000000000..d60c31a97a --- /dev/null +++ b/src/qtcurve/COPYING @@ -0,0 +1,340 @@ + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/qtcurve/common/check_on.png b/src/qtcurve/common/check_on.png new file mode 100644 index 0000000000000000000000000000000000000000..472578e47d9276c2c6104094c280a95512538545 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VRh}-6Arezd&*}0VN)Tvy*j~WE z=WwY1#lZ_4>lzPSEnw9Qd(=lP&$z>0vw_5*BD^oia^{^w7GvZO-?SwUf zstJAE_ab?4;L|gy> literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/check_x_on.png b/src/qtcurve/common/check_x_on.png new file mode 100644 index 0000000000000000000000000000000000000000..1be26e1a4034c88c815193f7f8d74a0d2ee45ff9 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{ViJmTwArez_`yB-j7;vy`Z*G3o zv7qDSW~o(-vKIp!|HcRW06!~C&{>CMsWelFKelF{r5}E)N C(>A#P literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/colorutils.c b/src/qtcurve/common/colorutils.c new file mode 100644 index 0000000000..52b2183208 --- /dev/null +++ b/src/qtcurve/common/colorutils.c @@ -0,0 +1,342 @@ +/* + This file is taken from kcolorspaces.cpp and kcolorutils.cpp from kdelibs +The code has been modified to work with QColor (Qt3 &Qt4) and GdkColor +*/ + +/* This file is part of the KDE project + * Copyright (C) 2007 Matthew Woehlke + * Copyright (C) 2007 Olaf Schmidt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "config.h" +#include "common.h" + +#ifdef __cplusplus +#include +#endif + +#if !(defined QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY) + +#include + +#if defined _WIN32 && defined QT_VERSION && (QT_VERSION >= 0x040000) +#include +#include +#include + +static int isnan(double x) +{ + return _isnan(x); +} +#endif + +#ifdef __cplusplus +static inline int qtcLimit(double c) +{ + return c < 0.0 ? 0 : (c > 255.0 ? 255 : (int)c); +} +#else +static inline int qtcLimit(double c) +{ + return c < 0.0 + ? 0 + : c > 65535.0 + ? 65535 + : (int)c; +} +#endif + +#ifdef __cplusplus +#if defined QT_VERSION && (QT_VERSION >= 0x040000) +#define FLOAT_COLOR(VAL, COL) (VAL).COL##F() +#define TO_COLOR(R, G, B) QColor::fromRgbF(R, G, B) +#else +#define FLOAT_COLOR(VAL, COL) ((double)(((VAL).COL()*1.0)/255.0)) +#define TO_COLOR(R, G, B) QColor(qtcLimit(R*255.0), qtcLimit(G*255.0), qtcLimit(B*255.0)) +#endif +#else +#define inline +#define FLOAT_COLOR(VAL, COL) ((double)(((VAL).COL*1.0)/65535.0)) +static GdkColor qtcGdkColor(double r, double g, double b) +{ + GdkColor col; + + col.red=qtcLimit(r*65535); + col.green=qtcLimit(g*65535); + col.blue=qtcLimit(b*65535); + + return col; +} + +#define TO_COLOR(R, G, B) qtcGdkColor(R, G, B) +#endif + +static inline double ColorUtils_normalize(double a) +{ + return (a < 1.0 ? (a > 0.0 ? a : 0.0) : 1.0); +} + +static inline double ColorUtils_wrap(double a) +{ + static double d = 1.0; + double r = fmod(a, d); + return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0)); +} + +#define HCY_REC 709 // use 709 for now +#if HCY_REC == 601 +static const double yc[3] = { 0.299, 0.587, 0.114 }; +#elif HCY_REC == 709 +static const double yc[3] = {0.2126, 0.7152, 0.0722}; +#else // use Qt values +static const double yc[3] = { 0.34375, 0.5, 0.15625 }; +#endif + +static inline double ColorUtils_HCY_gamma(double n) +{ + return pow(ColorUtils_normalize(n), 2.2); +} + +static inline double ColorUtils_HCY_igamma(double n) +{ + return pow(ColorUtils_normalize(n), 1.0/2.2); +} + +static inline double ColorUtils_HCY_lumag(double r, double g, double b) +{ + return r*yc[0] + g*yc[1] + b*yc[2]; +} + +typedef struct +{ + double h, c, y; +} ColorUtils_HCY; + +// static ColorUtils_HCY ColorUtils_HCY_fromValues(double h_, double c_, double y_/*, double a_*/) +// { +// h = h_; +// c = c_; +// y = y_; +// // a = a_; +// } + +static ColorUtils_HCY ColorUtils_HCY_fromColor(const color *color) +{ + ColorUtils_HCY hcy; + double r = ColorUtils_HCY_gamma(FLOAT_COLOR(*color, red)); + double g = ColorUtils_HCY_gamma(FLOAT_COLOR(*color, green)); + double b = ColorUtils_HCY_gamma(FLOAT_COLOR(*color, blue)); +// a = color.alphaF(); + + // luma component + hcy.y = ColorUtils_HCY_lumag(r, g, b); + + // hue component + double p = MAX(MAX(r, g), b); + double n = MIN(MIN(r, g), b); + double d = 6.0 * (p - n); + if (n == p) + hcy.h = 0.0; + else if (r == p) + hcy.h = ((g - b) / d); + else if (g == p) + hcy.h = ((b - r) / d) + (1.0 / 3.0); + else + hcy.h = ((r - g) / d) + (2.0 / 3.0); + + // chroma component + if (0.0 == hcy.y || 1.0 == hcy.y) + hcy.c = 0.0; + else + hcy.c = MAX( (hcy.y - n) / hcy.y, (p - hcy.y) / (1 - hcy.y) ); + return hcy; +} + +static color ColorUtils_HCY_toColor(ColorUtils_HCY *hcy) +{ + // start with sane component values + double _h = ColorUtils_wrap(hcy->h); + double _c = ColorUtils_normalize(hcy->c); + double _y = ColorUtils_normalize(hcy->y); + + // calculate some needed variables + double _hs = _h * 6.0, th, tm; + if (_hs < 1.0) { + th = _hs; + tm = yc[0] + yc[1] * th; + } + else if (_hs < 2.0) { + th = 2.0 - _hs; + tm = yc[1] + yc[0] * th; + } + else if (_hs < 3.0) { + th = _hs - 2.0; + tm = yc[1] + yc[2] * th; + } + else if (_hs < 4.0) { + th = 4.0 - _hs; + tm = yc[2] + yc[1] * th; + } + else if (_hs < 5.0) { + th = _hs - 4.0; + tm = yc[2] + yc[0] * th; + } + else { + th = 6.0 - _hs; + tm = yc[0] + yc[2] * th; + } + + // calculate RGB channels in sorted order + double tn, to, tp; + if (tm >= _y) { + tp = _y + _y * _c * (1.0 - tm) / tm; + to = _y + _y * _c * (th - tm) / tm; + tn = _y - (_y * _c); + } + else { + tp = _y + (1.0 - _y) * _c; + to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm); + tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm); + } + + // return RGB channels in appropriate order + if (_hs < 1.0) + return TO_COLOR(ColorUtils_HCY_igamma(tp), ColorUtils_HCY_igamma(to), ColorUtils_HCY_igamma(tn)); + else if (_hs < 2.0) + return TO_COLOR(ColorUtils_HCY_igamma(to), ColorUtils_HCY_igamma(tp), ColorUtils_HCY_igamma(tn)); + else if (_hs < 3.0) + return TO_COLOR(ColorUtils_HCY_igamma(tn), ColorUtils_HCY_igamma(tp), ColorUtils_HCY_igamma(to)); + else if (_hs < 4.0) + return TO_COLOR(ColorUtils_HCY_igamma(tn), ColorUtils_HCY_igamma(to), ColorUtils_HCY_igamma(tp)); + else if (_hs < 5.0) + return TO_COLOR(ColorUtils_HCY_igamma(to), ColorUtils_HCY_igamma(tn), ColorUtils_HCY_igamma(tp)); + else + return TO_COLOR(ColorUtils_HCY_igamma(tp), ColorUtils_HCY_igamma(tn), ColorUtils_HCY_igamma(to)); +} + +// #ifndef __cplusplus +static inline double ColorUtils_HCY_luma(const color *color) +{ + return ColorUtils_HCY_lumag(ColorUtils_HCY_gamma(FLOAT_COLOR(*color, red)), + ColorUtils_HCY_gamma(FLOAT_COLOR(*color, green)), + ColorUtils_HCY_gamma(FLOAT_COLOR(*color, blue))); +} + +static inline double ColorUtils_mixQreal(double a, double b, double bias) +{ + return a + (b - a) * bias; +} + +double ColorUtils_luma(const color *color) +{ + return ColorUtils_HCY_luma(color); +} + +static double ColorUtils_contrastRatio(const color *c1, const color *c2) +{ + double y1 = ColorUtils_luma(c1), y2 = ColorUtils_luma(c2); + if (y1 > y2) + return (y1 + 0.05) / (y2 + 0.05); + else + return (y2 + 0.05) / (y1 + 0.05); +} + +color ColorUtils_lighten(const color *color, double ky, double kc) +{ + ColorUtils_HCY c=ColorUtils_HCY_fromColor(color); + + c.y = 1.0 - ColorUtils_normalize((1.0 - c.y) * (1.0 - ky)); + c.c = 1.0 - ColorUtils_normalize((1.0 - c.c) * kc); + return ColorUtils_HCY_toColor(&c); +} + +color ColorUtils_darken(const color *color, double ky, double kc) +{ + ColorUtils_HCY c=ColorUtils_HCY_fromColor(color); + c.y = ColorUtils_normalize(c.y * (1.0 - ky)); + c.c = ColorUtils_normalize(c.c * kc); + return ColorUtils_HCY_toColor(&c); +} + +color ColorUtils_shade(const color *color, double ky, double kc) +{ + ColorUtils_HCY c=ColorUtils_HCY_fromColor(color); + c.y = ColorUtils_normalize(c.y + ky); + c.c = ColorUtils_normalize(c.c + kc); + return ColorUtils_HCY_toColor(&c); +} + +color ColorUtils_mix(const color *c1, const color *c2, double bias); + +static color ColorUtils_tintHelper(const color *base, const color *col, double amount) +{ + color mixed=ColorUtils_mix(base, col, pow(amount, 0.3)); + ColorUtils_HCY c=ColorUtils_HCY_fromColor(&mixed); + c.y = ColorUtils_mixQreal(ColorUtils_luma(base), c.y, amount); + + return ColorUtils_HCY_toColor(&c); +} + +color ColorUtils_tint(const color *base, const color *col, double amount) +{ + if (amount <= 0.0) return *base; + if (amount >= 1.0) return *col; + if (isnan(amount)) return *base; + + double ri = ColorUtils_contrastRatio(base, col); + double rg = 1.0 + ((ri + 1.0) * amount * amount * amount); + double u = 1.0, l = 0.0; + color result; + int i; + for (i = 12 ; i ; --i) { + double a = 0.5 * (l+u); + result = ColorUtils_tintHelper(base, col, a); + double ra = ColorUtils_contrastRatio(base, &result); + if (ra > rg) + u = a; + else + l = a; + } + return result; +} + +color ColorUtils_mix(const color *c1, const color *c2, double bias) +{ + if (bias <= 0.0) return *c1; + if (bias >= 1.0) return *c2; + if (isnan(bias)) return *c1; + + { + double r = ColorUtils_mixQreal(FLOAT_COLOR(*c1, red), FLOAT_COLOR(*c2, red), bias); + double g = ColorUtils_mixQreal(FLOAT_COLOR(*c1, green), FLOAT_COLOR(*c2, green), bias); + double b = ColorUtils_mixQreal(FLOAT_COLOR(*c1, blue), FLOAT_COLOR(*c2, blue), bias); + /*double a = ColorUtils_mixQreal(FLOAT_COLOR(*c1, alpha), FLOAT_COLOR(*c2, alpha), bias);*/ + + return TO_COLOR(r, g, b); + } +} + +// #endif +/* Added!!! */ +// static color ColorUtils_shade_qtc(const color *color, double k) +// { +// ColorUtils_HCY c=ColorUtils_HCY_fromColor(color); +// c.y = ColorUtils_normalize(c.y * (k>1.0 ? (k*1.1) : (k<1.0 ? (k*0.9) : k))); +// return ColorUtils_HCY_toColor(&c); +// } + +#endif // !(defined QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY) diff --git a/src/qtcurve/common/colorutils.h b/src/qtcurve/common/colorutils.h new file mode 100644 index 0000000000..6bcecdd30f --- /dev/null +++ b/src/qtcurve/common/colorutils.h @@ -0,0 +1,11 @@ +#ifndef QTC_COLOR_UTILS_H +#define QTC_COLOR_UTILS_H + +extern color ColorUtils_lighten(const color *color, double ky, double kc); +extern color ColorUtils_darken(const color *color, double ky, double kc); +extern color ColorUtils_shade(const color *color, double ky, double kc); +extern color ColorUtils_tint(const color *base, const color *col, double amount); +extern color ColorUtils_mix(const color *c1, const color *c2, double bias); +extern double ColorUtils_luma(const color *color); + +#endif diff --git a/src/qtcurve/common/common.c b/src/qtcurve/common/common.c new file mode 100644 index 0000000000..b09e5848bd --- /dev/null +++ b/src/qtcurve/common/common.c @@ -0,0 +1,728 @@ +#include +#include +#include +#include "common.h" +#include "colorutils.h" + +#ifdef __cplusplus +#include +#else +#include +#endif + +/* Taken from rgb->hsl routines taken from KColor + Copyright 2007 Matthew Woehlke +*/ +static inline double normalize(double a) +{ + return (a < 0.0 ? 0.0 : a > 1.0 ? 1.0 : a); +} + +static inline double mix(double a, double b, double k) +{ + return a + ( ( b - a ) * k ); +} + +static inline double wrap(double a, double d) +{ + register double r = fmod( a, d ); + return ( r < 0.0 ? d + r : ( r > 0.0 ? r : 0.0 ) ); +} + +static inline double h2c(double h, double m1, double m2) +{ + h = wrap( h, 6.0 ); + + if ( h < 1.0 ) + return mix( m1, m2, h ); + if ( h < 3.0 ) + return m2; + if ( h < 4.0 ) + return mix( m1, m2, 4.0 - h ); + return m1; +} + +static inline void rgbToHsl(double r, double g, double b, double *h, double *s, double *l) +{ + double min=MIN(MIN(r, g), b), + max=MAX(MAX(r, g), b); + + *l = 0.5 * (max + min); + *s = 0.0; + *h = 0.0; + + if (max != min) + { + double delta = max - min; + + if ( *l <= 0.5 ) + *s = delta / ( max + min ); + else + *s = delta / ( 2.0 - max - min ); + + if ( r == max ) + *h = ( g - b ) / delta; + else if ( g == max ) + *h = 2.0 + ( b - r ) / delta; + else if ( b == max ) + *h = 4.0 + ( r - g ) / delta; + + *h /= 6.0; + if ( *h < 0.0 ) + (*h) += 1.0; + } +} + +static inline void hslToRgb(double h, double s, double l, double *r, double *g, double *b) +{ + double m1, m2; + + // TODO h2rgb( h, r, g, b ); + h *= 6.0; + + if ( l <= 0.5 ) + m2 = l * ( 1.0 + s ); + else + m2 = l + s * ( 1.0 - l ); + m1 = 2.0 * l - m2; + + *r = h2c( h + 2.0, m1, m2 ); + *g = h2c( h, m1, m2 ); + *b = h2c( h - 2.0, m1, m2 ); +} + +void qtcRgbToHsv(double r, double g, double b, double *h, double *s, double *v) +{ + double min=MIN(MIN(r, g), b), + max=MAX(MAX(r, g), b), + delta=max - min; + + *v=max; + if(max != 0) + *s=delta / max; + else + *s=0; + + if (*s==0.0) + *h = 0.0; + else + { + if(r == max) + *h=(g - b) / delta; /* between yellow & magenta */ + else if(g == max) + *h=2 + (b - r) / delta; /* between cyan & yellow */ + else if(b == max) + *h=4 + (r - g) / delta; /* between magenta & cyan */ + *h *= 60; /* degrees */ + if(*h < 0) + *h += 360; + } +} + +void qtcHsvToRgb(double *r, double *g, double *b, double h, double s, double v) +{ + if(0==s) + *r=*g=*b=v; + else + { + int i; + double f, + p; + + h /= 60; /* sector 0 to 5 */ + i=(int)floor(h); + f=h - i; /* factorial part of h */ + p=v * (1 - s); + switch(i) + { + case 0: + *r=v; + *g=v * (1 - s * (1 - f)); + *b=p; + break; + case 1: + *r=v * (1 - s * f); + *g=v; + *b=p; + break; + case 2: + *r=p; + *g=v; + *b=v * (1 - s * (1 - f)); + break; + case 3: + *r=p; + *g=v * (1 - s * f); + *b=v; + break; + case 4: + *r=v * (1 - s * (1 - f)); + *g=p; + *b=v; + break; + /* case 5: */ + default: + *r=v; + *g=p; + *b=v * (1 - s * f); + break; + } + } +} + +#ifdef __cplusplus +static inline int qtcLimit(double c) +{ + return c < 0.0 ? 0 : (c > 255.0 ? 255 : (int)c); +} +#else +static inline int qtcLimit(double c) +{ + return c < 0.0 + ? 0 + : c > 65535.0 + ? 65535 + : (int)c; +} +#endif + +#ifdef __cplusplus +void qtcShade(const Options *opts, const color &ca, color *cb, double k) +#else +void qtcShade(const Options *opts, const color *ca, color *cb, double k) +#endif +{ + if(qtcEqual(k, 1.0)) + { +#ifdef __cplusplus + *cb=ca; +#else + cb->red = ca->red; + cb->green = ca->green; + cb->blue = ca->blue; +#endif + } + else + switch(opts->shading) + { + case SHADING_SIMPLE: + { + #ifdef __cplusplus + int v=(int)(255.0*(k-1.0)); + + cb->setRgb(qtcLimit(ca.red()+v), qtcLimit(ca.green()+v), qtcLimit(ca.blue()+v)); + #else + double v=65535.0*(k-1.0); + + cb->red = qtcLimit(ca->red+v); + cb->green = qtcLimit(ca->green+v); + cb->blue = qtcLimit(ca->blue+v); + #endif + break; + } + case SHADING_HSL: + { + #ifdef __cplusplus + double r(ca.red()/255.0), + g(ca.green()/255.0), + b(ca.blue()/255.0); + #else + double r=ca->red/65535.0, + g=ca->green/65535.0, + b=ca->blue/65535.0; + #endif + double h, s, l; + + rgbToHsl(r, g, b, &h, &s, &l); + l=normalize(l*k); + s=normalize(s*k); + hslToRgb(h, s, l, &r, &g, &b); + #ifdef __cplusplus + cb->setRgb(qtcLimit(r*255.0), qtcLimit(g*255.0), qtcLimit(b*255.0)); + #else + cb->red=qtcLimit(r*65535.0); + cb->green=qtcLimit(g*65535.0); + cb->blue=qtcLimit(b*65535.0); + #endif + break; + } + case SHADING_HSV: + { + #ifdef __cplusplus + double r(ca.red()/255.0), + g(ca.green()/255.0), + b(ca.blue()/255.0); + #else + double r=ca->red/65535.0, + g=ca->green/65535.0, + b=ca->blue/65535.0; + #endif + double h, s, v; + + qtcRgbToHsv(r, g, b, &h, &s, &v); + + v*=k; + if (v > 1.0) + { + s -= v - 1.0; + if (s < 0) + s = 0; + v = 1.0; + } + qtcHsvToRgb(&r, &g, &b, h, s, v); + #ifdef __cplusplus + cb->setRgb(qtcLimit(r*255.0), qtcLimit(g*255.0), qtcLimit(b*255.0)); + #else + cb->red=qtcLimit(r*65535.0); + cb->green=qtcLimit(g*65535.0); + cb->blue=qtcLimit(b*65535.0); + #endif + break; + } + case SHADING_HCY: + { + #define HCY_FACTOR 0.15 + #if defined QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY + if(k>1.0) + *cb=KColorUtils::lighten(ca, (k*(1+HCY_FACTOR))-1.0, 1.0); + else + *cb=KColorUtils::darken(ca, 1.0-(k*(1-HCY_FACTOR)), 1.0); + #elif defined __cplusplus + if(k>1.0) + *cb=ColorUtils_lighten(&ca, (k*(1+HCY_FACTOR))-1.0, 1.0); + else + *cb=ColorUtils_darken(&ca, 1.0-(k*(1-HCY_FACTOR)), 1.0); + #else + if(k>1.0) + *cb=ColorUtils_lighten(ca, (k*(1+HCY_FACTOR))-1.0, 1.0); + else + *cb=ColorUtils_darken(ca, 1.0-(k*(1-HCY_FACTOR)), 1.0); + #endif + } + } +#if defined __cplusplus && defined QT_VERSION && (QT_VERSION >= 0x040000) + cb->setAlpha(ca.alpha()); +#endif +#ifndef __cplusplus + cb->pixel = ca->pixel; +#endif +} + +static unsigned char checkBounds(int num) +{ + return num < 0 ? 0 : + num > 255 ? 255 : + num; +} + +void qtcAdjustPix(unsigned char *data, int numChannels, int w, int h, int stride, int ro, int go, int bo, double shade) +{ + int width=w*numChannels, + offset=0, + row, + r=(int)((ro*shade)+0.5), + g=(int)((go*shade)+0.5), + b=(int)((bo*shade)+0.5); + + for(row=0; rowborder=border; +#ifndef __cplusplus + grad->numStops=numStops; + grad->stops=malloc(sizeof(GradientStop) * numStops); +#endif + va_start(ap, numStops); + for(i=0; istops.insert(GradientStop(pos, val)); +#else + grad->stops[i].pos=pos; + grad->stops[i].val=val; + grad->stops[i].alpha=1.0; +#endif + } + va_end(ap); +} + +const Gradient * qtcGetGradient(EAppearance app, const Options *opts) +{ + if(IS_CUSTOM(app)) + { +#ifdef __cplusplus + GradientCont::const_iterator grad(opts->customGradient.find(app)); + + if(grad!=opts->customGradient.end()) + return &((*grad).second); +#else + Gradient *grad=opts->customGradient[app-APPEARANCE_CUSTOM1]; + + if(grad) + return grad; +#endif + app=APPEARANCE_RAISED; + } + + { + static Gradient stdGradients[NUM_STD_APP]; + static bool init=false; + + if(!init) + { + qtcSetupGradient(&stdGradients[APPEARANCE_FLAT-APPEARANCE_FLAT], GB_3D,2,0.0,1.0,1.0,1.0); + qtcSetupGradient(&stdGradients[APPEARANCE_RAISED-APPEARANCE_FLAT], GB_3D_FULL,2,0.0,1.0,1.0,1.0); + qtcSetupGradient(&stdGradients[APPEARANCE_DULL_GLASS-APPEARANCE_FLAT], GB_LIGHT,4,0.0,1.05,0.499,0.984,0.5,0.928,1.0,1.0); + qtcSetupGradient(&stdGradients[APPEARANCE_SHINY_GLASS-APPEARANCE_FLAT], GB_LIGHT,4,0.0,1.2,0.499,0.984,0.5,0.9,1.0,1.06); + qtcSetupGradient(&stdGradients[APPEARANCE_AGUA-APPEARANCE_FLAT], GB_SHINE, 2,0.0,0.6,1.0,1.1); + qtcSetupGradient(&stdGradients[APPEARANCE_SOFT_GRADIENT-APPEARANCE_FLAT], GB_3D,2,0.0,1.04,1.0,0.98); + qtcSetupGradient(&stdGradients[APPEARANCE_GRADIENT-APPEARANCE_FLAT], GB_3D,2,0.0,1.1,1.0,0.94); + qtcSetupGradient(&stdGradients[APPEARANCE_HARSH_GRADIENT-APPEARANCE_FLAT], GB_3D,2,0.0,1.3,1.0,0.925); + qtcSetupGradient(&stdGradients[APPEARANCE_INVERTED-APPEARANCE_FLAT], GB_3D,2,0.0,0.93,1.0,1.04); + qtcSetupGradient(&stdGradients[APPEARANCE_DARK_INVERTED-APPEARANCE_FLAT], GB_NONE,3,0.0,0.8,0.7,0.95,1.0,1.0); + qtcSetupGradient(&stdGradients[APPEARANCE_SPLIT_GRADIENT-APPEARANCE_FLAT], GB_3D,4,0.0,1.06,0.499,1.004,0.5,0.986,1.0,0.92); + qtcSetupGradient(&stdGradients[APPEARANCE_BEVELLED-APPEARANCE_FLAT], GB_3D,4,0.0,1.05,0.1,1.02,0.9,0.985,1.0,0.94); + qtcSetupGradient(&stdGradients[APPEARANCE_LV_BEVELLED-APPEARANCE_FLAT], GB_3D,3,0.0,1.00,0.85,1.0,1.0,0.90); + qtcSetupGradient(&stdGradients[APPEARANCE_AGUA_MOD-APPEARANCE_FLAT], GB_NONE,3,0.0,1.5,0.49,0.85,1.0,1.3); + qtcSetupGradient(&stdGradients[APPEARANCE_LV_AGUA-APPEARANCE_FLAT], GB_NONE,4,0.0,0.98,0.35,0.95,0.4,0.93,1.0,1.15); + init=true; + } + + return &stdGradients[app-APPEARANCE_FLAT]; + } + + return 0L; /* Will never happen! */ +} + +#ifdef __cplusplus +EAppearance qtcWidgetApp(EWidget w, const Options *opts, bool active) +#else +EAppearance qtcWidgetApp(EWidget w, const Options *opts) +#endif +{ + switch(w) + { + case WIDGET_SB_BGND: + return opts->sbarBgndAppearance; + case WIDGET_LISTVIEW_HEADER: + return opts->lvAppearance; + case WIDGET_SB_BUTTON: + case WIDGET_SLIDER: + case WIDGET_SB_SLIDER: + return opts->sliderAppearance; + case WIDGET_FILLED_SLIDER_TROUGH: + return opts->sliderFill; + case WIDGET_TAB_TOP: + case WIDGET_TAB_BOT: + return opts->tabAppearance; + case WIDGET_MENU_ITEM: + return opts->menuitemAppearance; + case WIDGET_PROGRESSBAR: +#ifndef __cplusplus + case WIDGET_ENTRY_PROGRESSBAR: +#endif + return opts->progressAppearance; + case WIDGET_PBAR_TROUGH: + return opts->progressGrooveAppearance; + case WIDGET_SELECTION: + return opts->selectionAppearance; +#ifdef __cplusplus + case WIDGET_DOCK_WIDGET_TITLE: + return opts->dwtAppearance; + case WIDGET_MDI_WINDOW: + case WIDGET_MDI_WINDOW_TITLE: + return active ? opts->titlebarAppearance : opts->inactiveTitlebarAppearance; + case WIDGET_MDI_WINDOW_BUTTON: + return opts->titlebarButtonAppearance; + case WIDGET_DIAL: + return IS_FLAT(opts->appearance) ? APPEARANCE_RAISED : APPEARANCE_SOFT_GRADIENT; +#endif + case WIDGET_TROUGH: + case WIDGET_SLIDER_TROUGH: + return opts->grooveAppearance; +#ifndef __cplusplus + case WIDGET_SPIN_UP: + case WIDGET_SPIN_DOWN: +#endif + case WIDGET_SPIN: + return MODIFY_AGUA(opts->appearance); + case WIDGET_TOOLBAR_BUTTON: + return APPEARANCE_NONE==opts->tbarBtnAppearance ? opts->appearance : opts->tbarBtnAppearance; + default: + break; + } + + return opts->appearance; +}; + +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + +#define CAN_EXTRA_ROUND(MOD) \ + (IS_EXTRA_ROUND_WIDGET(widget) && \ + (IS_SLIDER(widget) || WIDGET_TROUGH==widget || \ + ( ( (w>(MIN_ROUND_EXTRA_SIZE(widget)+MOD)) || (WIDGET_NO_ETCH_BTN==widget || WIDGET_MENU_BUTTON==widget) ) &&\ + (h>(MIN_ROUND_EXTRA_SIZE(widget)+MOD))))) +#define CAN_FULL_ROUND(MOD) (w>(MIN_ROUND_FULL_SIZE+MOD) && h>(MIN_ROUND_FULL_SIZE+MOD)) + +// **NOTE** MUST KEEP IN SYNC WITH getRadius/RADIUS_ETCH !!! +ERound qtcGetWidgetRound(const Options *opts, int w, int h, EWidget widget) +{ + ERound r=opts->round; + + if( ((WIDGET_PBAR_TROUGH==widget || WIDGET_PROGRESSBAR==widget) && (opts->square&SQUARE_PROGRESS)) || + (WIDGET_ENTRY==widget && (opts->square&SQUARE_ENTRY)) || + (WIDGET_SCROLLVIEW==widget && (opts->square&SQUARE_SCROLLVIEW)) ) + return ROUND_NONE; + + if((WIDGET_CHECKBOX==widget || WIDGET_FOCUS==widget) && ROUND_NONE!=r) + r=ROUND_SLIGHT; + +#if defined __cplusplus && (defined QT_VERSION && (QT_VERSION >= 0x040000)) + if((WIDGET_MDI_WINDOW_BUTTON==widget && (opts->titlebarButtons&TITLEBAR_BUTTON_ROUND)) || + WIDGET_RADIO_BUTTON==widget || WIDGET_DIAL==widget) + return ROUND_MAX; +#endif +#ifndef __cplusplus + if(WIDGET_RADIO_BUTTON==widget) + return ROUND_MAX; +#endif + +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + if(WIDGET_SLIDER==widget && + (SLIDER_ROUND==opts->sliderStyle || SLIDER_ROUND_ROTATED==opts->sliderStyle || SLIDER_CIRCULAR==opts->sliderStyle)) + return ROUND_MAX; +#endif + + switch(r) + { + case ROUND_MAX: + if(IS_SLIDER(widget) || WIDGET_TROUGH==widget || + (w>(MIN_ROUND_MAX_WIDTH+2) && h>(MIN_ROUND_MAX_HEIGHT+2) && IS_MAX_ROUND_WIDGET(widget))) + return ROUND_MAX; + case ROUND_EXTRA: + if(CAN_EXTRA_ROUND(2)) + return ROUND_EXTRA; + case ROUND_FULL: + if(CAN_FULL_ROUND(2)) + return ROUND_FULL; + case ROUND_SLIGHT: + return ROUND_SLIGHT; + case ROUND_NONE: + return ROUND_NONE; + } + + return ROUND_NONE; +} + +double qtcGetRadius(const Options *opts, int w, int h, EWidget widget, ERadius rad) +{ + ERound r=opts->round; + + if((WIDGET_CHECKBOX==widget || WIDGET_FOCUS==widget) && ROUND_NONE!=r) + r=ROUND_SLIGHT; + + if( ((WIDGET_PBAR_TROUGH==widget || WIDGET_PROGRESSBAR==widget) && (opts->square&SQUARE_PROGRESS)) || + (WIDGET_ENTRY==widget && (opts->square&SQUARE_ENTRY)) || + (WIDGET_SCROLLVIEW==widget && (opts->square&SQUARE_SCROLLVIEW)) ) + return 0.0; + +#if defined __cplusplus && (defined QT_VERSION && (QT_VERSION >= 0x040000)) + if((WIDGET_MDI_WINDOW_BUTTON==widget && (opts->titlebarButtons&TITLEBAR_BUTTON_ROUND)) || + WIDGET_RADIO_BUTTON==widget || WIDGET_DIAL==widget) + return (w>h ? h : w)/2.0; +#endif +#ifndef __cplusplus + if(WIDGET_RADIO_BUTTON==widget) + return (w>h ? h : w)/2.0; +#endif + +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + if(WIDGET_SLIDER==widget && + (SLIDER_ROUND==opts->sliderStyle || SLIDER_ROUND_ROTATED==opts->sliderStyle || SLIDER_CIRCULAR==opts->sliderStyle)) + return (w>h ? h : w)/2.0; +#endif + + if(RADIUS_EXTERNAL==rad && !opts->fillProgress && (WIDGET_PROGRESSBAR==widget +#ifndef __cplusplus + || WIDGET_ENTRY_PROGRESSBAR==widget +#endif + )) + rad=RADIUS_INTERNAL; + + switch(rad) + { + case RADIUS_SELECTION: + switch(r) + { + case ROUND_MAX: + case ROUND_EXTRA: + if(/* (WIDGET_RUBBER_BAND==widget && w>14 && h>14) || */(w>48 && h>48)) + return 6.0; + case ROUND_FULL: +// if( /*(WIDGET_RUBBER_BAND==widget && w>11 && h>11) || */(w>48 && h>48)) +// return 3.0; + if(w>MIN_ROUND_FULL_SIZE && h>MIN_ROUND_FULL_SIZE) + return 3.0; + case ROUND_SLIGHT: + return 2.0; + case ROUND_NONE: + return 0; + } + case RADIUS_INTERNAL: + switch(r) + { + case ROUND_MAX: + if(IS_SLIDER(widget) || WIDGET_TROUGH==widget) + { + double r=((w>h ? h : w)-(WIDGET_SLIDER==widget ? 1 : 0))/2.0; + return r>MAX_RADIUS_INTERNAL ? MAX_RADIUS_INTERNAL : r; + } + if(w>(MIN_ROUND_MAX_WIDTH-2) && h>(MIN_ROUND_MAX_HEIGHT-2) && IS_MAX_ROUND_WIDGET(widget)) + { + double r=((w>h ? h : w)-2.0)/2.0; + return r>9.5 ? 9.5 : r; + } + case ROUND_EXTRA: + if(CAN_EXTRA_ROUND(-2)) + return EXTRA_INNER_RADIUS; + case ROUND_FULL: + if(CAN_FULL_ROUND(-2)) + return FULL_INNER_RADIUS; + case ROUND_SLIGHT: + return SLIGHT_INNER_RADIUS; + case ROUND_NONE: + return 0; + } + case RADIUS_EXTERNAL: + switch(r) + { + case ROUND_MAX: + if(IS_SLIDER(widget) || WIDGET_TROUGH==widget) + { + double r=((w>h ? h : w)-(WIDGET_SLIDER==widget ? 1 : 0))/2.0; + return r>MAX_RADIUS_EXTERNAL ? MAX_RADIUS_EXTERNAL : r; + } + if(w>MIN_ROUND_MAX_WIDTH && h>MIN_ROUND_MAX_HEIGHT && IS_MAX_ROUND_WIDGET(widget)) + { + double r=((w>h ? h : w)-2.0)/2.0; + return r>10.5 ? 10.5 : r; + } + case ROUND_EXTRA: + if(CAN_EXTRA_ROUND(0)) + return EXTRA_OUTER_RADIUS; + case ROUND_FULL: + if(CAN_FULL_ROUND(0)) + return FULL_OUTER_RADIUS; + case ROUND_SLIGHT: + return SLIGHT_OUTER_RADIUS; + case ROUND_NONE: + return 0; + } + case RADIUS_ETCH: + // **NOTE** MUST KEEP IN SYNC WITH getWidgetRound !!! + switch(r) + { + case ROUND_MAX: + if(IS_SLIDER(widget) || WIDGET_TROUGH==widget) + { + double r=((w>h ? h : w)-(WIDGET_SLIDER==widget ? 1 : 0))/2.0; + return r>MAX_RADIUS_EXTERNAL ? MAX_RADIUS_EXTERNAL : r; + } + if(w>(MIN_ROUND_MAX_WIDTH+2) && h>(MIN_ROUND_MAX_HEIGHT+2) && IS_MAX_ROUND_WIDGET(widget)) + { + double r=((w>h ? h : w)-2.0)/2.0; + return r>11.5 ? 11.5 : r; + } + case ROUND_EXTRA: + if(CAN_FULL_ROUND(2)) + return EXTRA_ETCH_RADIUS; + case ROUND_FULL: + if(w>(MIN_ROUND_FULL_SIZE+2) && h>(MIN_ROUND_FULL_SIZE+2)) + return FULL_ETCH_RADIUS; + case ROUND_SLIGHT: + return SLIGHT_ETCH_RADIUS; + case ROUND_NONE: + return 0; + } + } + + return 0; +} + +double qtcRingAlpha[3]={0.125, 0.125, 0.5}; + +void qtcCalcRingAlphas(const color *bgnd) +{ +#ifdef __cplusplus + double r=bgnd->red()/255.0, + g=bgnd->green()/255.0, + b=bgnd->blue()/255.0, +#else + double r=bgnd->red/65535.0, + g=bgnd->green/65535.0, + b=bgnd->blue/65535.0, +#endif + h=0, + s=0, + v=0; + qtcRgbToHsv(r, g, b, &h, &s, &v); + qtcRingAlpha[0]=v*0.26; + qtcRingAlpha[1]=v*0.14; + qtcRingAlpha[2]=v*0.55; +} + +double qtcShineAlpha(const color *bgnd) +{ +#ifdef __cplusplus + double r=bgnd->red()/255.0, + g=bgnd->green()/255.0, + b=bgnd->blue()/255.0, +#else + double r=bgnd->red/65535.0, + g=bgnd->green/65535.0, + b=bgnd->blue/65535.0, +#endif + h=0, + s=0, + v=0; + qtcRgbToHsv(r, g, b, &h, &s, &v); + return v*0.8; +} + +#endif // !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) diff --git a/src/qtcurve/common/common.h b/src/qtcurve/common/common.h new file mode 100644 index 0000000000..7d5ed7e181 --- /dev/null +++ b/src/qtcurve/common/common.h @@ -0,0 +1,1383 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + +/* + QtCurve (C) Craig Drummond, 2003 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistr ibute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#define MAKE_VERSION(a, b) (((a) << 16) | ((b) << 8)) +#define MAKE_VERSION3(a, b, c) (((a) << 16) | ((b) << 8) | (c)) + +/* + The following #define disables the rounding when scrollbar type==none. +#define SIMPLE_SCROLLBARS +*/ + +/* + The following #define controls whether a scrollbar's slider should overlap + the scrollbar buttons when at min/max. This removes the thick looking line + between the slider and the buttons. +*/ +#define INCREASE_SB_SLIDER + +typedef enum +{ + SHADING_SIMPLE=0, + SHADING_HSL=1, + SHADING_HSV=2, + SHADING_HCY=3 +} EShading; + +#ifdef __cplusplus +#include +#include +#include +#include +#if defined QT_VERSION && (QT_VERSION >= 0x040000) +#include +#endif // defined QT_VERSION && (QT_VERSION >= 0x040000) +#else // __cplusplus +#include +#endif // __cplusplus + +#ifdef __cplusplus +#define IS_BLACK(A) (0==(A).red() && 0==(A).green() && 0==(A).blue()) +#else +#define IS_BLACK(A) (0==(A).red && 0==(A).green && 0==(A).blue) +#endif + +#ifdef __cplusplus +#include +class QColor; +typedef QColor color; + +#if defined QT_VERSION && (QT_VERSION >= 0x040000) +#include +typedef QSet Strings; +#else // QT_VERSION && (QT_VERSION >= 0x040000) +typedef QStringList Strings; +#endif // QT_VERSION && (QT_VERSION >= 0x040000) + +#else // __cplusplus +#include +#include +typedef gboolean bool; +typedef GdkColor color; +typedef gchar ** Strings; +#define true TRUE +#define false FALSE +#endif // __cplusplus + +#define SETTINGS_GROUP "Settings" +#define KWIN_GROUP "KWin" + +/* qtc_.themerc support */ +#define KDE_PREFIX(V) ((4==(V)) ? KDE4PREFIX : KDE3PREFIX) +#define THEME_DIR "/share/apps/kstyle/themes/" +#define THEME_DIR4 "/share/kde4/apps/kstyle/themes/" +#define THEME_PREFIX "qtc_" +#define THEME_SUFFIX ".themerc" +#define BORDER_SIZE_FILE "windowBorderSizes" + +#define LV_SIZE 7 + +#define LARGE_ARR_WIDTH 7 +#define LARGE_ARR_HEIGHT 4 +#define SMALL_ARR_WIDTH 5 +#define SMALL_ARR_HEIGHT 3 + +#define NUM_STD_SHADES 6 +#define NUM_EXTRA_SHADES 3 + +enum +{ + ALPHA_ETCH_LIGHT = 0, + ALPHA_ETCH_DARK, + NUM_STD_ALPHAS +}; + +#define TOTAL_SHADES NUM_STD_SHADES+NUM_EXTRA_SHADES +#define ORIGINAL_SHADE TOTAL_SHADES + +#define SHADE_ORIG_HIGHLIGHT NUM_STD_SHADES +#define SHADE_4_HIGHLIGHT NUM_STD_SHADES+1 +#define SHADE_2_HIGHLIGHT NUM_STD_SHADES+2 + +/* 3d effect - i.e. buttons, etc */ +#define SHADES \ + static const double shades[2][11][NUM_STD_SHADES]=\ + { \ + { /* HSV & HSL */ \ + { 1.05, 1.04, 0.90, 0.800, 0.830, 0.82 }, \ + { 1.06, 1.04, 0.90, 0.790, 0.831, 0.78 }, \ + { 1.07, 1.04, 0.90, 0.785, 0.832, 0.75 }, \ + { 1.08, 1.05, 0.90, 0.782, 0.833, 0.72 }, \ + { 1.09, 1.05, 0.90, 0.782, 0.834, 0.70 }, \ + { 1.10, 1.06, 0.90, 0.782, 0.836, 0.68 }, \ + { 1.12, 1.06, 0.90, 0.782, 0.838, 0.63 }, \ + { 1.16, 1.07, 0.90, 0.782, 0.840, 0.62 }, /* default */ \ + { 1.18, 1.07, 0.90, 0.783, 0.842, 0.60 }, \ + { 1.20, 1.08, 0.90, 0.784, 0.844, 0.58 }, \ + { 1.22, 1.08, 0.90, 0.786, 0.848, 0.55 } \ + }, \ + { /* SIMPLE */ \ + { 1.07, 1.03, 0.91, 0.780, 0.834, 0.75 }, \ + { 1.08, 1.03, 0.91, 0.781, 0.835, 0.74 }, \ + { 1.09, 1.03, 0.91, 0.782, 0.836, 0.73 }, \ + { 1.10, 1.04, 0.91, 0.783, 0.837, 0.72 }, \ + { 1.11, 1.04, 0.91, 0.784, 0.838, 0.71 }, \ + { 1.12, 1.05, 0.91, 0.785, 0.840, 0.70 }, \ + { 1.13, 1.05, 0.91, 0.786, 0.842, 0.69 }, \ + { 1.14, 1.06, 0.91, 0.787, 0.844, 0.68 }, /* default */ \ + { 1.16, 1.06, 0.91, 0.788, 0.846, 0.66 }, \ + { 1.18, 1.07, 0.91, 0.789, 0.848, 0.64 }, \ + { 1.20, 1.07, 0.91, 0.790, 0.850, 0.62 } \ + } \ + } ; + +#define SIMPLE_SHADING (!shading) +#define DEFAULT_CONTRAST 7 + +#define THIN_SBAR_MOD ((opts.sliderWidthDEFAULT_SLIDER_WIDTH ? (opts.sliderWidth-9)/2 : 4)+(EFFECT_NONE==opts.buttonEffect ? 1 : 0)) +#define SLIDER_SIZE (opts.sliderWidth10 || c<0 || s>=NUM_STD_SHADES || s<0 \ + ? 1.0 \ + : opts.darkerBorders && (STD_BORDER==i || DISABLED_BORDER==i) \ + ? shades[SHADING_SIMPLE==opts.shading ? 1 : 0][c][s] - 0.1 \ + : shades[SHADING_SIMPLE==opts.shading ? 1 : 0][c][s] ) + +#define TAB_APPEARANCE(A) (A) /* (APPEARANCE_GLASS==(A) ? APPEARANCE_GRADIENT : (A)) */ + +#define INVERT_SHADE(A) (1.0+(1.0-(A))) + +#define ROUNDED (ROUND_NONE!=opts.round) + +#define TOOLBAR_SEP_GAP (opts.fadeLines ? 5 : 6) +#define FADE_SIZE 0.4 +#define ETCHED_DARK 0.95 + +#define IS_GLASS(A) (APPEARANCE_DULL_GLASS==(A) || APPEARANCE_SHINY_GLASS==(A)) +#define IS_CUSTOM(A) ((A)>=APPEARANCE_CUSTOM1 && (A)<(APPEARANCE_CUSTOM1+NUM_CUSTOM_GRAD)) +#define IS_FLAT(A) (APPEARANCE_FLAT==(A) || APPEARANCE_RAISED==(A) || APPEARANCE_FADE==(A)) +#define IS_FLAT_BGND(A) (APPEARANCE_FLAT==(A) || APPEARANCE_RAISED==(A)) + +#ifdef __cplusplus +#define MENUBAR_DARK_LIMIT 160 +#define TOO_DARK(A) ((A).red()=MAKE_VERSION(1,7) && \ + USE_BORDER(qtcGetGradient(opts.menuBgndAppearance, &opts)->border)) + +#define USE_GLOW_FOCUS(mouseOver) (FOCUS_GLOW==opts.focus && (MO_GLOW!=opts.coloredMouseOver || !(mouseOver))) + +#define USE_SHADED_MENU_BAR_COLORS (SHADE_CUSTOM==opts.shadeMenubars || SHADE_BLEND_SELECTED==opts.shadeMenubars) +#define MENUBAR_GLASS_SELECTED_DARK_FACTOR 0.9 + +#define MENUITEM_FADE_SIZE 48 + +#define NUM_SPLITTER_DASHES 21 + +#ifdef __cplusplus +#define WIDGET_BUTTON(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || WIDGET_DIAL==(w) || \ + WIDGET_COMBO==(w) || WIDGET_COMBO_BUTTON==(w) || WIDGET_MDI_WINDOW_BUTTON==(w) || \ + WIDGET_TOOLBAR_BUTTON==(w) ) +#define ETCH_WIDGET(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || WIDGET_SLIDER_TROUGH==(w) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || WIDGET_DIAL==(w) || \ + (WIDGET_SLIDER==(w) && MO_GLOW==opts.coloredMouseOver) || \ + WIDGET_FILLED_SLIDER_TROUGH==(w) || WIDGET_MDI_WINDOW_BUTTON==(w) || WIDGET_TOOLBAR_BUTTON==(w)) +#define AGUA_WIDGET(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || IS_SLIDER((w)) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || \ + WIDGET_COMBO==(w) WIDGET_COMBO_BUTTON==(w) || WIDGET_MDI_WINDOW_BUTTON==(w)) +#else // __cplusplus +#define WIDGET_BUTTON(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || WIDGET_TOGGLE_BUTTON==(w) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || \ + WIDGET_RADIO_BUTTON==(w) || WIDGET_COMBO==(w) || WIDGET_COMBO_BUTTON==(w) || WIDGET_UNCOLOURED_MO_BUTTON==(w) || \ + WIDGET_TOOLBAR_BUTTON==(w)) +#define ETCH_WIDGET(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || WIDGET_TOGGLE_BUTTON==(w) || WIDGET_SLIDER_TROUGH==(w) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || \ + (WIDGET_SLIDER==(w) && MO_GLOW==opts.coloredMouseOver) || \ + WIDGET_FILLED_SLIDER_TROUGH==(w) || WIDGET_COMBO==(w) || WIDGET_UNCOLOURED_MO_BUTTON==(w) || \ + WIDGET_TOOLBAR_BUTTON==(w)) +#define AGUA_WIDGET(w) (WIDGET_STD_BUTTON==(w) || WIDGET_DEF_BUTTON==(w) || WIDGET_TOGGLE_BUTTON==(w) || IS_SLIDER((w)) || \ + WIDGET_CHECKBOX==(w) || WIDGET_RADIO_BUTTON==(w) || \ + WIDGET_COMBO==(w) WIDGET_COMBO_BUTTON==(w)) +#endif // __cplusplus + +#define SLIDER(w) (WIDGET_SB_SLIDER==(w) || WIDGET_SLIDER==(w)) +#define CIRCULAR_SLIDER(w) (WIDGET_SLIDER==(w) && SLIDER_CIRCULAR==opts.sliderStyle) + +#define MODIFY_AGUA_X(A, X) (APPEARANCE_AGUA==(A) ? (X) : (A)) +#define MODIFY_AGUA(A) MODIFY_AGUA_X((A), APPEARANCE_AGUA_MOD) +#define AGUA_MAX 32.0 +#define AGUA_MID_SHADE 0.85 + +#define COLORED_BORDER_SIZE 3 +#define PROGRESS_CHUNK_WIDTH 10 +#define STRIPE_WIDTH 10 +#define DRAW_LIGHT_BORDER(SUKEN, WIDGET, APP) \ + (!(SUKEN) && (GB_LIGHT==qtcGetGradient(APP, &opts)->border) && WIDGET_MENU_ITEM!=(WIDGET) && !IS_TROUGH(WIDGET) && \ + (WIDGET_DEF_BUTTON!=(WIDGET) || IND_COLORED!=opts.defBtnIndicator)) + +#define DRAW_3D_FULL_BORDER(SUNKEN, APP) \ + (!(SUNKEN) && GB_3D_FULL==qtcGetGradient((APP), &opts)->border) + +#define DRAW_3D_BORDER(SUNKEN, APP) \ + (!(SUNKEN) && GB_3D==qtcGetGradient((APP), &opts)->border) + +#define DRAW_SHINE(SUNKEN, APP) \ + (!(SUNKEN) && GB_SHINE==qtcGetGradient((APP), &opts)->border) + +#define LIGHT_BORDER(APP) (APPEARANCE_DULL_GLASS==(APP) ? 1 : 0) + +#define PROGRESS_ANIMATION 100 +#define MIN_SLIDER_SIZE(A) (LINE_DOTS==(A) ? 24 : 20) + +#define CR_SMALL_SIZE 13 +#define CR_LARGE_SIZE 15 + +#define TAB_APP(A) (APPEARANCE_BEVELLED==(A) || APPEARANCE_SPLIT_GRADIENT==(A) ? APPEARANCE_GRADIENT : (A)) +#define NORM_TAB_APP TAB_APP(opts.tabAppearance) +#define SEL_TAB_APP TAB_APP(opts.activeTabAppearance) + +#define SLIDER_MO_SHADE (SHADE_SELECTED==opts.shadeSliders ? 1 : (SHADE_BLEND_SELECTED==opts.shadeSliders ? 0 : ORIGINAL_SHADE)) +#define SLIDER_MO_PLASTIK_BORDER (SHADE_SELECTED==opts.shadeSliders || SHADE_BLEND_SELECTED==opts.shadeSliders ? 2 : 1) +#define SLIDER_MO_LEN (SLIDER_TRIANGULAR==opts.sliderStyle ? 2 : (SHADE_SELECTED==opts.shadeSliders || SHADE_BLEND_SELECTED==opts.shadeSliders ? 4 : 3)) +#define SB_SLIDER_MO_LEN(A) ((A)<22 && !FULLLY_ROUNDED \ + ? 2 \ + : ((A)<32 || (SHADE_SELECTED!=opts.shadeSliders && SHADE_BLEND_SELECTED!=opts.shadeSliders) \ + ? 4 \ + : 6)) + +#define CR_MO_FILL 1 +#define MO_DEF_BTN 2 +#define MO_PLASTIK_DARK(W) (WIDGET_DEF_BUTTON==(W) && IND_COLORED==opts.defBtnIndicator ? 3 : 2) /*? 2 : 1) */ +#define MO_PLASTIK_LIGHT(W) (WIDGET_DEF_BUTTON==(W) && IND_COLORED==opts.defBtnIndicator ? 4 : 1) /*? 2 : 0) */ + +#define MO_STD_DARK(W) (MO_GLOW==opts.coloredMouseOver \ + ? 1 \ + : MO_PLASTIK_DARK(W)) +#define MO_STD_LIGHT(W, S) (MO_GLOW==opts.coloredMouseOver \ + ? 1 \ + : MO_PLASTIK_LIGHT(W)) + +#define FULLLY_ROUNDED (opts.round>=ROUND_FULL) +#define DO_EFFECT (EFFECT_NONE!=opts.buttonEffect) +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) +#define SLIDER_GLOW (DO_EFFECT && MO_GLOW==opts.coloredMouseOver /*&& SLIDER_TRIANGULAR!=opts.sliderStyle*/ ? 2 : 0) +#endif + +#define ENTRY_MO (opts.unifyCombo && opts.unifySpin) + +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) +#define FOCUS_ALPHA 0.08 +#define FOCUS_GLOW_LINE_ALPHA 0.5 +#if !defined __cplusplus +#define BORDER_BLEND_ALPHA(W) (WIDGET_ENTRY==(W) || WIDGET_SCROLLVIEW==(W) || WIDGET_SPIN==(W) || WIDGET_COMBO_BUTTON==(W) ? 0.4 : 0.7) +#else // !defined __cplusplus +#define BORDER_BLEND_ALPHA(W) (WIDGET_ENTRY==(W) || WIDGET_SCROLLVIEW==(W) ? 0.45 : 0.7) +#endif // !defined __cplusplus + +#define ETCH_TOP_ALPHA 0.055 +#define ETCH_BOTTOM_ALPHA 0.1 +// #if defined QT_VERSION && (QT_VERSION >= 0x040000) +// #define ETCH_RADIO_TOP_ALPHA 0.055 +// #define ETCH_RADIO_BOTTOM_ALPHA 0.80 +// #else +#define ETCH_RADIO_TOP_ALPHA 0.09 +#define ETCH_RADIO_BOTTOM_ALPHA 1.0 +// #endif + +#define RINGS_INNER_ALPHA(T) qtcRingAlpha[IMG_PLAIN_RINGS==(T) ? 1 : 0] //(IMG_PLAIN_RINGS==opts.bgndImage.type ? 0.25 : 0.125) +#define RINGS_OUTER_ALPHA qtcRingAlpha[2] //0.5 +#define RINGS_WIDTH(T) (IMG_SQUARE_RINGS==T ? 260 : 450) +#define RINGS_HEIGHT(T) (IMG_SQUARE_RINGS==T ? 220 : 360) + +#define RINGS_SQUARE_LARGE_ALPHA (RINGS_OUTER_ALPHA*0.675) +#define RINGS_SQUARE_SMALL_ALPHA (RINGS_OUTER_ALPHA*0.50) +#define RINGS_SQUARE_LINE_WIDTH 20.0 +#define RINGS_SQUARE_RADIUS 18.0 +#define RINGS_SQUARE_LARGE_SIZE 120.0 +#define RINGS_SQUARE_SMALL_SIZE 100.0 + +#if !defined __cplusplus +#define MENU_AND_TOOLTIP_RADIUS (opts.round>=ROUND_FULL ? 5.0 : 3.5) +#else // !defined __cplusplus +#define MENU_AND_TOOLTIP_RADIUS (opts.round>=ROUND_FULL ? 5.0 : 2.5) +#endif // !defined __cplusplus + +#define CUSTOM_BGND (!(IS_FLAT_BGND(opts.bgndAppearance)) || IMG_NONE!=opts.bgndImage.type || 100!=opts.bgndOpacity || 100!=opts.dlgOpacity) + +#define GLOW_PROG_ALPHA 0.55 + +#endif // !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + +#if defined __cplusplus && defined QT_VERSION && (QT_VERSION >= 0x040000) + +#include +typedef enum +{ + QtC_Round = QStyle::PM_CustomBase, + QtC_TitleBarButtonAppearance, + QtC_TitleAlignment, + QtC_TitleBarButtons, + QtC_TitleBarIcon, + QtC_TitleBarIconColor, + QtC_TitleBarEffect, + QtC_BlendMenuAndTitleBar, + QtC_ShadeMenubarOnlyWhenActive, + QtC_ToggleButtons, + QtC_MenubarColor, + QtC_WindowBorder, + QtC_CustomBgnd, + QtC_TitleBarApp +} QtCMetrics; + +#define QtC_StateKWin ((QStyle::StateFlag)0x10000000) +// PE_FrameWindow +#define QtC_StateKWinNotFull ((QStyle::StateFlag)0x20000000) +// CC_TitleBar +#define QtC_StateKWinFillBgnd ((QStyle::StateFlag)0x20000000) +#define QtC_StateKWinNoBorder ((QStyle::StateFlag)0x40000000) +#define QtC_StateKWinCompositing ((QStyle::StateFlag)0x80000000) +#define QtC_StateKWinTabDrag ((QStyle::StateFlag)0x00000001) + +#define QtC_PE_DrawBackground ((QStyle::PrimitiveElement)(QStyle::PE_CustomBase+10000)) + +#define CLOSE_COLOR QColor(191, 82, 82) +#define DARK_WINDOW_TEXT(A) ((A).red()<230 || (A).green()<230 || (A).blue()<230) +#define HOVER_BUTTON_ALPHA(A) (DARK_WINDOW_TEXT(A) ? 0.25 : 0.65) +#define WINDOW_TEXT_SHADOW_ALPHA(A) (EFFECT_SHADOW==(A) ? 0.10 : 0.60) +#define WINDOW_SHADOW_COLOR(A) (EFFECT_SHADOW==(A) ? Qt::black : Qt::white) + +#endif //defined __cplusplus && defined QT_VERSION && (QT_VERSION >= 0x040000) + +#if defined QT_VERSION && (QT_VERSION >= 0x040000) +#define QTCURVE_PREVIEW_CONFIG "QTCURVE_PREVIEW_CONFIG" +#define QTCURVE_PREVIEW_CONFIG_FULL "QTCURVE_PREVIEW_CONFIG_FULL" + +typedef enum +{ + DWT_BUTTONS_AS_PER_TITLEBAR = 0x0001, + DWT_COLOR_AS_PER_TITLEBAR = 0x0002, + DWT_FONT_AS_PER_TITLEBAR = 0x0004, + DWT_TEXT_ALIGN_AS_PER_TITLEBAR = 0x0008, + DWT_EFFECT_AS_PER_TITLEBAR = 0x0010, + DWT_ROUND_TOP_ONLY = 0x0020, + DWT_ICON_COLOR_AS_PER_TITLEBAR = 0x0040 +} EDwtSettingsFlags; + +typedef enum +{ + TITLEBAR_BUTTON_ROUND = 0x0001, + TITLEBAR_BUTTON_HOVER_FRAME = 0x0002, + TITLEBAR_BUTTON_HOVER_SYMBOL = 0x0004, + TITLEBAR_BUTTON_NO_FRAME = 0x0008, + TITLEBAR_BUTTON_COLOR = 0x0010, + TITLEBAR_BUTTON_COLOR_INACTIVE = 0x0020, + TITLEBAR_BUTTON_COLOR_MOUSE_OVER = 0x0040, + TITLEBAR_BUTTON_STD_COLOR = 0x0080, + TITLEBAR_BUTTON_COLOR_SYMBOL = 0x0100, + TITLEBAR_BUTTON_HOVER_SYMBOL_FULL = 0x0200, + TITLEBAR_BUTTON_SUNKEN_BACKGROUND = 0x0400, + TITLEBAR_BUTTOM_ARROW_MIN_MAX = 0x0800, + TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW = 0x1000, + TITLEBAR_BUTTON_ICON_COLOR = 0x2000, + TITLEBAR_BUTTON_USE_HOVER_COLOR = 0x4000 +} ETitleBarButtonFlags; + +typedef enum +{ + TITLEBAR_ICON_NONE, + TITLEBAR_ICON_MENU_BUTTON, + TITLEBAR_ICON_NEXT_TO_TITLE +} ETitleBarIcon; + +typedef enum +{ + TITLEBAR_CLOSE, + TITLEBAR_MIN, + TITLEBAR_MAX, + TITLEBAR_HELP, + TITLEBAR_MENU, + TITLEBAR_SHADE, + TITLEBAR_ALL_DESKTOPS, + TITLEBAR_KEEP_ABOVE, + TITLEBAR_KEEP_BELOW, + NUM_TITLEBAR_BUTTONS +} ETitleBarButtons; + +#define TBAR_VERSION_HACK 65535 +#define TBAR_BORDER_VERSION_HACK (TBAR_VERSION_HACK+1000) + +typedef std::map TBCols; +#endif // defined QT_VERSION && (QT_VERSION >= 0x040000) + +typedef enum +{ + WINDOW_BORDER_COLOR_TITLEBAR_ONLY = 0x01, // colorTitlebarOnly + WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR = 0x02, // titlebarMenuColor + WINDOW_BORDER_ADD_LIGHT_BORDER = 0x04, // titlebarBorder + WINDOW_BORDER_BLEND_TITLEBAR = 0x08, // titlebarBlend + WINDOW_BORDER_SEPARATOR = 0x10, + WINDOW_BORDER_FILL_TITLEBAR = 0x20 +} EWindowBorder; + +typedef enum +{ + IMG_NONE, + IMG_BORDERED_RINGS, + IMG_PLAIN_RINGS, + IMG_SQUARE_RINGS, + IMG_FILE +} EImageType; + +typedef struct +{ +#if defined __cplusplus + QString file; + QPixmap img; +#else // __cplusplus + const char *file; + GdkPixbuf *img; +#endif // __cplusplus +} QtCPixmap; + +#define BGND_IMG_ON_BORDER (IMG_FILE==opts.bgndImage.type && opts.bgndImage.onBorder) + +typedef enum +{ + PP_TL, + PP_TM, + PP_TR, + PP_BL, + PP_BM, + PP_BR, + PP_LM, + PP_RM, + PP_CENTRED, +} EPixPos; + +typedef struct +{ + EImageType type; + bool loaded, + onBorder; + QtCPixmap pixmap; + int width, + height; + EPixPos pos; +} QtCImage; + +typedef enum +{ + THIN_BUTTONS = 0x0001, + THIN_MENU_ITEMS = 0x0002, + THIN_FRAMES = 0x0004 +} EThinFlags; + +typedef enum +{ + SQUARE_NONE = 0x0000, + SQUARE_ENTRY = 0x0001, + SQUARE_PROGRESS = 0x0002, + SQUARE_SCROLLVIEW = 0x0004, + SQUARE_LISTVIEW_SELECTION = 0x0008, + SQUARE_FRAME = 0x0010, + SQUARE_TAB_FRAME = 0x0020, + SQUARE_SLIDER = 0x0040, + SQUARE_SB_SLIDER = 0x0080, + SQUARE_WINDOWS = 0x0100, + SQUARE_TOOLTIPS = 0x0200, + SQUARE_POPUP_MENUS = 0x0400, + + SQUARE_ALL = 0xFFFF +} ESquare; + +typedef enum +{ + WM_DRAG_NONE = 0, + WM_DRAG_MENUBAR = 1, + WM_DRAG_MENU_AND_TOOLBAR = 2, + WM_DRAG_ALL = 3 +} EWmDrag; + +typedef enum +{ + EFFECT_NONE, + EFFECT_ETCH, + EFFECT_SHADOW +} EEffect; + +typedef enum +{ + PIX_CHECK, +#ifdef __cplusplus +#if defined QT_VERSION && (QT_VERSION < 0x040000) + PIX_RADIO_ON, + PIX_RADIO_BORDER, + PIX_RADIO_INNER, + PIX_RADIO_LIGHT, + PIX_SLIDER, + PIX_SLIDER_LIGHT, + PIX_SLIDER_V, + PIX_SLIDER_LIGHT_V, +#endif // defined QT_VERSION && (QT_VERSION < 0x040000) + PIX_DOT +#else // __cplusplus + PIX_BLANK +#endif // __cplusplus +} EPixmap; + +typedef enum +{ + WIDGET_TAB_TOP, + WIDGET_TAB_BOT, + WIDGET_STD_BUTTON, + WIDGET_DEF_BUTTON, + WIDGET_TOOLBAR_BUTTON, + WIDGET_LISTVIEW_HEADER, + WIDGET_SLIDER, + WIDGET_SLIDER_TROUGH, + WIDGET_FILLED_SLIDER_TROUGH, + WIDGET_SB_SLIDER, + WIDGET_SB_BUTTON, + WIDGET_SB_BGND, + WIDGET_TROUGH, + WIDGET_CHECKBOX, + WIDGET_RADIO_BUTTON, + WIDGET_COMBO, + WIDGET_COMBO_BUTTON, + WIDGET_MENU_ITEM, + WIDGET_PROGRESSBAR, + WIDGET_PBAR_TROUGH, +#ifndef __cplusplus + WIDGET_ENTRY_PROGRESSBAR, + WIDGET_TOGGLE_BUTTON, + WIDGET_SPIN_UP, + WIDGET_SPIN_DOWN, + WIDGET_UNCOLOURED_MO_BUTTON, +#else // __cplusplus + WIDGET_CHECKBUTTON, // Qt4 only + WIDGET_MDI_WINDOW, // Qt4 only + WIDGET_MDI_WINDOW_TITLE, // Qt4 only + WIDGET_MDI_WINDOW_BUTTON, // Qt4 only + WIDGET_DOCK_WIDGET_TITLE, + WIDGET_DIAL, +#endif // __cplusplus + WIDGET_SPIN, + WIDGET_ENTRY, + WIDGET_SCROLLVIEW, + WIDGET_SELECTION, + WIDGET_FRAME, + WIDGET_NO_ETCH_BTN, + WIDGET_MENU_BUTTON, // Qt4 only + WIDGET_FOCUS, + WIDGET_TAB_FRAME, + WIDGET_TOOLTIP, + WIDGET_OTHER +} EWidget; + +typedef enum +{ + APP_ALLOW_BASIC, + APP_ALLOW_FADE, + APP_ALLOW_STRIPED, + APP_ALLOW_NONE +} EAppAllow; + +typedef enum +{ + APPEARANCE_CUSTOM1, + APPEARANCE_CUSTOM2, + APPEARANCE_CUSTOM3, + APPEARANCE_CUSTOM4, + APPEARANCE_CUSTOM5, + APPEARANCE_CUSTOM6, + APPEARANCE_CUSTOM7, + APPEARANCE_CUSTOM8, + APPEARANCE_CUSTOM9, + APPEARANCE_CUSTOM10, + APPEARANCE_CUSTOM11, + APPEARANCE_CUSTOM12, + APPEARANCE_CUSTOM13, + APPEARANCE_CUSTOM14, + APPEARANCE_CUSTOM15, + APPEARANCE_CUSTOM16, + APPEARANCE_CUSTOM17, + APPEARANCE_CUSTOM18, + APPEARANCE_CUSTOM19, + APPEARANCE_CUSTOM20, + APPEARANCE_CUSTOM21, + APPEARANCE_CUSTOM22, + APPEARANCE_CUSTOM23, + + NUM_CUSTOM_GRAD, + + APPEARANCE_FLAT = NUM_CUSTOM_GRAD, + APPEARANCE_RAISED, + APPEARANCE_DULL_GLASS, + APPEARANCE_SHINY_GLASS, + APPEARANCE_AGUA, + APPEARANCE_SOFT_GRADIENT, + APPEARANCE_GRADIENT, + APPEARANCE_HARSH_GRADIENT, + APPEARANCE_INVERTED, + APPEARANCE_DARK_INVERTED, + APPEARANCE_SPLIT_GRADIENT, + APPEARANCE_BEVELLED, + APPEARANCE_FADE, /* Only for poupmenu items! */ + APPEARANCE_STRIPED = APPEARANCE_FADE, /* Only for windows and menus */ + APPEARANCE_NONE = APPEARANCE_FADE, /* Only for titlebars */ + APPEARANCE_FILE, /* Only for windows and menus */ + APPEARANCE_LV_BEVELLED, /* To be used only with qtcGetGradient */ + APPEARANCE_AGUA_MOD, + APPEARANCE_LV_AGUA, + NUM_STD_APP = (APPEARANCE_LV_AGUA-NUM_CUSTOM_GRAD)+1 +} EAppearance; + +#define IS_SLIDER(W) (WIDGET_SLIDER==(W) || WIDGET_SB_SLIDER==(W)) +#define IS_TROUGH(W) (WIDGET_SLIDER_TROUGH==(W) || WIDGET_PBAR_TROUGH==(W) || WIDGET_TROUGH==(W) || WIDGET_FILLED_SLIDER_TROUGH==(W)) +#ifndef __cplusplus +#define IS_TOGGLE_BUTTON(W) (WIDGET_TOGGLE_BUTTON==(W) || WIDGET_CHECKBOX==(W)) +#endif // __cplusplus + +typedef enum +{ + CORNER_TL = 0x1, + CORNER_TR = 0x2, + CORNER_BR = 0x4, + CORNER_BL = 0x8 +} ECornerBits; + +#define ROUNDED_NONE 0x0 +#define ROUNDED_TOP (CORNER_TL|CORNER_TR) +#define ROUNDED_BOTTOM (CORNER_BL|CORNER_BR) +#define ROUNDED_LEFT (CORNER_TL|CORNER_BL) +#define ROUNDED_RIGHT (CORNER_TR|CORNER_BR) +#define ROUNDED_TOPRIGHT CORNER_TR +#define ROUNDED_BOTTOMRIGHT CORNER_BR +#define ROUNDED_TOPLEFT CORNER_TL +#define ROUNDED_BOTTOMLEFT CORNER_BL +#define ROUNDED_ALL (CORNER_TL|CORNER_TR|CORNER_BR|CORNER_BL) + +typedef enum +{ + IND_CORNER, + IND_FONT_COLOR, + IND_COLORED, + IND_TINT, + IND_GLOW, + IND_DARKEN, + IND_SELECTED, + IND_NONE +} EDefBtnIndicator; + +typedef enum +{ + LINE_NONE, + LINE_SUNKEN, + LINE_FLAT, + LINE_DOTS, + LINE_1DOT, + LINE_DASHES, +} ELine; + +typedef enum +{ + TB_NONE, + TB_LIGHT, + TB_DARK, + TB_LIGHT_ALL, + TB_DARK_ALL +} ETBarBorder; + +typedef enum +{ + TBTN_STANDARD, + TBTN_RAISED, + TBTN_JOINED +} ETBarBtn; + +typedef enum +{ + BORDER_FLAT, + BORDER_RAISED, + BORDER_SUNKEN, + BORDER_LIGHT +} EBorder; + +/* + This whole EShade enum is a complete mess! + For menubars, we dont blend - so blend is selected, and selected is darken + For check/radios - we dont blend, so blend is selected, and we dont allow darken +*/ +typedef enum +{ + SHADE_NONE, + SHADE_CUSTOM, + SHADE_SELECTED, + SHADE_BLEND_SELECTED, + SHADE_DARKEN, + SHADE_WINDOW_BORDER +} EShade; + +typedef enum +{ + ECOLOR_BASE, + ECOLOR_BACKGROUND, + ECOLOR_DARK, +} EColor; + +typedef enum +{ + ROUND_NONE, + ROUND_SLIGHT, + ROUND_FULL, + ROUND_EXTRA, + ROUND_MAX +} ERound; + +typedef enum +{ + SCROLLBAR_KDE, + SCROLLBAR_WINDOWS, + SCROLLBAR_PLATINUM, + SCROLLBAR_NEXT, + SCROLLBAR_NONE +} EScrollbar; + +typedef enum +{ + FRAME_NONE, + FRAME_PLAIN, + FRAME_LINE, + FRAME_SHADED, + FRAME_FADED +} EFrame; + +typedef enum +{ + GB_LBL_BOLD = 0x01, + GB_LBL_CENTRED = 0x02, + GB_LBL_INSIDE = 0x04, + GB_LBL_OUTSIDE = 0x08 +} EGBLabel; + +#define NO_FRAME(A) (FRAME_NONE==(A) || FRAME_LINE==(A)) + +typedef enum +{ + MO_NONE, + MO_COLORED, + MO_COLORED_THICK, + MO_PLASTIK, + MO_GLOW +} EMouseOver; + +typedef enum +{ + STRIPE_NONE, + STRIPE_PLAIN, + STRIPE_DIAGONAL, + STRIPE_FADE +} EStripe; + +typedef enum +{ + SLIDER_PLAIN, + SLIDER_ROUND, + SLIDER_PLAIN_ROTATED, + SLIDER_ROUND_ROTATED, + SLIDER_TRIANGULAR, + SLIDER_CIRCULAR +} ESliderStyle; + +#define ROTATED_SLIDER (SLIDER_PLAIN_ROTATED==opts.sliderStyle || SLIDER_ROUND_ROTATED==opts.sliderStyle) + +typedef enum +{ + FOCUS_STANDARD, + FOCUS_RECTANGLE, + FOCUS_FULL, + FOCUS_FILLED, + FOCUS_LINE, + FOCUS_GLOW +} EFocus; + +typedef enum +{ + TAB_MO_TOP, + TAB_MO_BOTTOM, + TAB_MO_GLOW +} ETabMo; + +typedef enum +{ + GT_HORIZ, + GT_VERT +} EGradType; + +typedef enum +{ + GLOW_NONE, + GLOW_START, + GLOW_MIDDLE, + GLOW_END +} EGlow; + +#define FULL_FOCUS (FOCUS_FULL==opts.focus || FOCUS_FILLED==opts.focus) + +enum +{ + HIDE_NONE = 0x00, + HIDE_KEYBOARD = 0x01, + HIDE_KWIN = 0x02 +}; + +#if defined __cplusplus +typedef enum +{ + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_FULL_CENTER, + ALIGN_RIGHT +} EAlign; +#endif + +#ifdef __cplusplus +#include + +inline bool qtcEqual(double d1, double d2) +{ + return (fabs(d1 - d2) < 0.0001); +} +#else // __cplusplus +#define qtcEqual(A, B) (fabs(A - B) < 0.0001) +#endif // __cplusplus + +#ifdef __cplusplus +struct GradientStop +#else // __cplusplus +typedef struct +#endif // __cplusplus +{ +#ifdef __cplusplus + GradientStop(double p=0.0, double v=0.0, double a=1.0) : pos(p), val(v), alpha(a) { } + + bool operator==(const GradientStop &o) const + { + return qtcEqual(pos, o.pos) && qtcEqual(val, o.val) && qtcEqual(alpha, o.alpha); + } + + bool operator<(const GradientStop &o) const + { + return pos +{ + GradientStopCont fix() const + { + GradientStopCont c(*this); + if(size()) + { + GradientStopCont::const_iterator first(c.begin()); + GradientStopCont::reverse_iterator last(c.rbegin()); + + if((*first).pos>0.001) + c.insert(GradientStop(0.0, 1.0)); + if((*last).pos<0.999) + c.insert(GradientStop(1.0, 1.0)); + } + return c; + } +}; +struct Gradient +#else // __cplusplus +typedef struct +#endif // __cplusplus +{ +#ifdef __cplusplus + Gradient() : border(GB_3D) { } + + bool operator==(const Gradient &o) const + { + return border==o.border && stops==o.stops; + } +#endif // __cplusplus + EGradientBorder border; +#ifdef __cplusplus + GradientStopCont stops; +#else // __cplusplus + int numStops; + GradientStop *stops; +#endif // __cplusplus +} +#ifndef __cplusplus +Gradient +#endif // __cplusplus +; + +#define USE_CUSTOM_SHADES(A) ((A).customShades[0]>0.00001) +#define USE_CUSTOM_ALPHAS(A) ((A).customAlphas[0]>0.00001) + +#ifdef __cplusplus +typedef std::map GradientCont; +struct Options +#else // __cplusplus +typedef struct +#endif // __cplusplus +{ + + int version, + contrast, + passwordChar, + highlightFactor, + lighterPopupMenuBgnd, + menuDelay, + sliderWidth, + tabBgnd, + colorSelTab, + expanderHighlight, + crHighlight, + splitterHighlight, + crSize, + gbFactor, + gbLabel, + thin; + ERound round; + bool embolden, + highlightTab, + roundAllTabs, + animatedProgress, +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + fixParentlessDialogs, +#endif + customMenuTextColor, + menubarMouseOver, + useHighlightForMenu, + shadeMenubarOnlyWhenActive, + lvButton, + drawStatusBarFrames, + fillSlider, + roundMbTopOnly, + gtkScrollViews, + stdSidebarButtons, + toolbarTabs, + gtkComboMenus, + mapKdeIcons, + gtkButtonOrder, + fadeLines, + reorderGtkButtons, + borderMenuitems, + colorMenubarMouseOver, + darkerBorders, + vArrows, + xCheck, + crButton, + smallRadio, + fillProgress, + comboSplitter, + highlightScrollViews, + etchEntry, + colorSliderMouseOver, + thinSbarGroove, + flatSbarButtons, + borderSbarGroove, + borderProgress, + popupBorder, + unifySpinBtns, + unifyCombo, + unifySpin, + borderTab, + borderInactiveTab, + doubleGtkComboArrow, + menuIcons, +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + stdBtnSizes, + xbar, +#endif // defined QT_VERSION && (QT_VERSION >= 0x040000) + forceAlternateLvCols, + invertBotTab, + boldProgress, + coloredTbarMo, + borderSelection, + stripedSbar, + shadePopupMenu, + hideShortcutUnderline; + EFrame groupBox; + EGlow glowProgress; + bool lvLines; + EGradType bgndGrad, + menuBgndGrad; + int menubarHiding, + statusbarHiding, + square, + windowDrag, + windowBorder, + bgndOpacity, + menuBgndOpacity, + dlgOpacity; +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + int dwtSettings; + int titlebarButtons; + TBCols titlebarButtonColors; + ETitleBarIcon titlebarIcon; +#endif // defined QT_VERSION && (QT_VERSION >= 0x040000) + EStripe stripedProgress; + ESliderStyle sliderStyle; + EMouseOver coloredMouseOver; + ETBarBorder toolbarBorders; + ETBarBtn tbarBtns; + EDefBtnIndicator defBtnIndicator; + ELine sliderThumbs, + handles, + toolbarSeparators, + splitters; + ETabMo tabMouseOver; +/* NOTE: If add an appearance setting, increase the number of custmo gradients to match! */ + EAppearance appearance, + bgndAppearance, + menuBgndAppearance, + menubarAppearance, + menuitemAppearance, + toolbarAppearance, + lvAppearance, + tabAppearance, + activeTabAppearance, + sliderAppearance, + titlebarAppearance, + inactiveTitlebarAppearance, +#ifdef __cplusplus + titlebarButtonAppearance, + dwtAppearance, +#endif // __cplusplus + selectionAppearance, + menuStripeAppearance, + progressAppearance, + progressGrooveAppearance, + grooveAppearance, + sunkenAppearance, + sbarBgndAppearance, + sliderFill, + tooltipAppearance, + tbarBtnAppearance; + EShade shadeSliders, + shadeMenubars, + menuStripe, + shadeCheckRadio, + comboBtn, + sortedLv, + crColor, + progressColor; + EColor progressGrooveColor; + EEffect buttonEffect, + tbarBtnEffect; + EScrollbar scrollbarType; + EFocus focus; + color customMenubarsColor, + customSlidersColor, + customMenuNormTextColor, + customMenuSelTextColor, + customMenuStripeColor, + customCheckRadioColor, + customComboBtnColor, + customSortedLvColor, + customCrBgndColor, + customProgressColor; + EShading shading; +#if defined __cplusplus + EAlign titlebarAlignment; + EEffect titlebarEffect; + bool centerTabText; +#endif //__cplusplus + double customShades[NUM_STD_SHADES], + customAlphas[NUM_STD_ALPHAS]; +#ifdef __cplusplus + GradientCont customGradient; +#else // __cplusplus + Gradient *customGradient[NUM_CUSTOM_GRAD]; +#endif // __cplusplus + QtCPixmap bgndPixmap; + QtCPixmap menuBgndPixmap; + QtCImage bgndImage, + menuBgndImage; +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + /* NOTE: If add any more settings here, need to alter copyOpts/freeOpts/defaultSettings in config_file.c */ + Strings noBgndGradientApps, + noBgndOpacityApps, + noMenuBgndOpacityApps, + noBgndImageApps; +#endif +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + Strings noDlgFixApps; +#endif + Strings noMenuStripeApps; +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + Strings menubarApps, + statusbarApps, + useQtFileDialogApps, + windowDragWhiteList, + windowDragBlackList; +#endif // defined QT_VERSION && (QT_VERSION >= 0x040000) + +#ifndef __cplusplus +} Options; +#else // __cplusplus +}; +#endif // __cplusplus + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((b) < (a) ? (a) : (b)) +#endif + +#if defined QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY +#include +#define tint(COLA, COLB, FACTOR) KColorUtils::tint((COLA), (COLB), (FACTOR)) +#define midColor(COLA, COLB) KColorUtils::mix((COLA), (COLB), 0.5) +#else // QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY +#include "colorutils.h" +#ifdef __cplusplus +#define tint(COLA, COLB, FACTOR) ColorUtils_tint(&(COLA), &(COLB), (FACTOR)) +#define midColor(COLA, COLB) ColorUtils_mix(&(COLA), &(COLB), 0.5) +#define midColorF(COLA, COLB, FACTOR) ColorUtils_mix(&(COLA), &(COLB), FACTOR-0.5) +#else // __cplusplus +#define tint(COLA, COLB, FACTOR) ColorUtils_tint((COLA), (COLB), (FACTOR)) +#define midColor(COLA, COLB) ColorUtils_mix((COLA), (COLB), 0.5) +#endif // __cplusplus +#endif // QT_VERSION && (QT_VERSION >= 0x040000) && !defined QTC_QT_ONLY + +extern void qtcRgbToHsv(double r, double g, double b, double *h, double *s, double *v); +extern void qtcRgbToHsv(double r, double g, double b, double *h, double *s, double *v); +#ifdef __cplusplus +extern void qtcShade(const Options *opts, const color &ca, color *cb, double k); +#else +extern void qtcShade(const Options *opts, const color *ca, color *cb, double k); +#endif + +extern void qtcAdjustPix(unsigned char *data, int numChannels, int w, int h, int stride, int ro, int go, int bo, double shade); +extern void qtcSetupGradient(Gradient *grad, EGradientBorder border, int numStops, ...); +extern const Gradient * qtcGetGradient(EAppearance app, const Options *opts); + +#ifdef __cplusplus +extern EAppearance qtcWidgetApp(EWidget w, const Options *opts, bool active=true); +#else +extern EAppearance qtcWidgetApp(EWidget w, const Options *opts); +#endif + +typedef enum +{ + RADIUS_SELECTION, + RADIUS_INTERNAL, + RADIUS_EXTERNAL, + RADIUS_ETCH +} ERadius; + +#define MIN_ROUND_MAX_HEIGHT 12 +#define MIN_ROUND_MAX_WIDTH 24 +#define BGND_SHINE_SIZE 300 +#define BGND_SHINE_STEPS 8 + +#define MIN_ROUND_FULL_SIZE 8 +#ifdef __cplusplus +#define MIN_ROUND_EXTRA_SIZE(W) (WIDGET_SPIN==(W) ? 7 : 14) +#else // __cplusplus +#define MIN_ROUND_EXTRA_SIZE(W) (WIDGET_SPIN_UP==(W) || WIDGET_SPIN_DOWN==(W) || WIDGET_SPIN==(W) ? 7 : 14) +#endif // __cplusplus + +#if defined __cplusplus +#define IS_MAX_ROUND_WIDGET(A) \ + (WIDGET_STD_BUTTON==A || WIDGET_DEF_BUTTON==A /*|| WIDGET_MENU_BUTTON==A*/) +#define IS_EXTRA_ROUND_WIDGET(A) \ + (A!=WIDGET_MENU_ITEM && A!=WIDGET_TAB_FRAME && A!=WIDGET_PBAR_TROUGH && A!=WIDGET_PROGRESSBAR && \ + A!=WIDGET_MDI_WINDOW && A!=WIDGET_MDI_WINDOW_TITLE) + +#define EXTRA_INNER_RADIUS 3.5 +#define EXTRA_OUTER_RADIUS 4.5 +#define EXTRA_ETCH_RADIUS 5.5 +#define FULL_INNER_RADIUS 1.5 +#define FULL_OUTER_RADIUS 2.5 +#define FULL_ETCH_RADIUS 3.5 + +#if defined QT_VERSION && (QT_VERSION < 0x040600) +#define SLIGHT_INNER_RADIUS 0.5 +#define SLIGHT_OUTER_RADIUS 1.5 +#define SLIGHT_ETCH_RADIUS 2.5 +#else // QT_VERSION && (QT_VERSION < 0x040600) +#define SLIGHT_INNER_RADIUS 0.75 +#define SLIGHT_OUTER_RADIUS 1.75 +#define SLIGHT_ETCH_RADIUS 2.75 +#endif //QT_VERSION && (QT_VERSION < 0x040600) + +#else // __cplusplus + +#define IS_MAX_ROUND_WIDGET(A) \ + (WIDGET_STD_BUTTON==A || WIDGET_DEF_BUTTON==A || WIDGET_TOGGLE_BUTTON==A /*|| WIDGET_MENU_BUTTON==A*/) +#define IS_EXTRA_ROUND_WIDGET(A) \ + (A!=WIDGET_MENU_ITEM && A!=WIDGET_TAB_FRAME && A!=WIDGET_PBAR_TROUGH && A!=WIDGET_PROGRESSBAR) + +#define EXTRA_INNER_RADIUS 4 +#define EXTRA_OUTER_RADIUS 5 +#define EXTRA_ETCH_RADIUS 6 +#define FULL_INNER_RADIUS 2 +#define FULL_OUTER_RADIUS 3 +#define FULL_ETCH_RADIUS 4 +#define SLIGHT_INNER_RADIUS 1 +#define SLIGHT_OUTER_RADIUS 2 +#define SLIGHT_ETCH_RADIUS 3 + +#endif // __cplusplus + +#define MAX_RADIUS_INTERNAL 9.0 +#define MAX_RADIUS_EXTERNAL (MAX_RADIUS_INTERNAL+2.0) + +extern double qtcRingAlpha[3]; +extern ERound qtcGetWidgetRound(const Options *opts, int w, int h, EWidget widget); +extern double qtcGetRadius(const Options *opts, int w, int h, EWidget widget, ERadius rad); +extern double qtcShineAlpha(const color *bgnd); +extern void qtcCalcRingAlphas(const color *bgnd); + +#endif // __COMMON_H__ diff --git a/src/qtcurve/common/config_file.c b/src/qtcurve/common/config_file.c new file mode 100644 index 0000000000..3b4d732acc --- /dev/null +++ b/src/qtcurve/common/config_file.c @@ -0,0 +1,3563 @@ + /* + QtCurve (C) Craig Drummond, 2003 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "common.h" +#include "config_file.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#include +#endif + +#ifndef _WIN32 +#include +#include +#endif + +#if defined _WIN32 && defined QT_VERSION && (QT_VERSION >= 0x040000) +#include +#include +#include + +static int lstat(const char* fileName, struct stat* s) +{ + return stat(fileName, s); +} +#endif + +#define CONFIG_FILE "stylerc" +#define OLD_CONFIG_FILE "qtcurvestylerc" +#define VERSION_KEY "version" + +#ifdef __cplusplus + +#if QT_VERSION >= 0x040000 +#include +#include +#include +#define TO_LATIN1(A) A.toLatin1().constData() +#else +#define TO_LATIN1(A) A.latin1() + +#include +#include +#include +#endif + +#endif // __cplusplus + +const char *qtcConfDir(); + +#ifdef __cplusplus +static QString determineFileName(const QString &file) +{ + if(file.startsWith("/")) + return file; + return qtcConfDir()+file; +} + +#else +static const char * determineFileName(const char *file) +{ + if('/'==file[0]) + return file; + + static char *filename=NULL; + + filename=realloc(filename, strlen(qtcConfDir())+strlen(file)+1); + sprintf(filename, "%s%s", qtcConfDir(), file); + return filename; +} +#endif + +static int c2h(char ch) +{ + return (ch>='0' && ch<='9') ? ch-'0' : + (ch>='a' && ch<='f') ? 10+(ch-'a') : + (ch>='A' && ch<='F') ? 10+(ch-'A') : + 0; +} + +#define ATOH(str) ((c2h(*str)<<4)+c2h(*(str+1))) + +void qtcSetRgb(color *col, const char *str) +{ + if(str && strlen(str)>6) + { + int offset='#'==str[0] ? 1 : 0; +#ifdef __cplusplus + col->setRgb(ATOH(&str[offset]), ATOH(&str[offset+2]), ATOH(&str[offset+4])); +#else + col->red=ATOH(&str[offset])<<8; + col->green=ATOH(&str[offset+2])<<8; + col->blue=ATOH(&str[offset+4])<<8; + col->pixel=0; +#endif + } + else +#ifdef __cplusplus + col->setRgb(0, 0, 0); +#else + col->red=col->green=col->blue=col->pixel=0; +#endif +} + +#ifdef __cplusplus +static bool loadImage(const QString &file, QtCPixmap *pixmap) +#else +static bool loadImage(const char *file, QtCPixmap *pixmap) +#endif +{ +#ifdef __cplusplus + // Need to store filename for config dialog! + QString f(determineFileName(file)); + pixmap->file=f; + return pixmap->img.load(f); +#else // __cplusplus + pixmap->img=gdk_pixbuf_new_from_file(determineFileName(file), NULL); + return NULL!=pixmap->img; +#endif // __cplusplus +} + +static EDefBtnIndicator toInd(const char *str, EDefBtnIndicator def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "fontcolor", 9) || 0==memcmp(str, "border", 6)) + return IND_FONT_COLOR; + if(0==memcmp(str, "none", 4)) + return IND_NONE; + if(0==memcmp(str, "corner", 6)) + return IND_CORNER; + if(0==memcmp(str, "colored", 7)) + return IND_COLORED; + if(0==memcmp(str, "tint", 4)) + return IND_TINT; + if(0==memcmp(str, "glow", 4)) + return IND_GLOW; + if(0==memcmp(str, "darken", 6)) + return IND_DARKEN; + if(0==memcmp(str, "origselected", 12)) + return IND_SELECTED; + } + + return def; +} + +static ELine toLine(const char *str, ELine def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "dashes", 6)) + return LINE_DASHES; + if(0==memcmp(str, "none", 4)) + return LINE_NONE; + if(0==memcmp(str, "sunken", 6)) + return LINE_SUNKEN; + if(0==memcmp(str, "dots", 4)) + return LINE_DOTS; + if(0==memcmp(str, "flat", 4)) + return LINE_FLAT; + if(0==memcmp(str, "1dot", 5)) + return LINE_1DOT; + } + return def; +} + +static ETBarBorder toTBarBorder(const char *str, ETBarBorder def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "dark", 4)) + return 0==memcmp(&str[4], "-all", 4) ? TB_DARK_ALL : TB_DARK; + if(0==memcmp(str, "none", 4)) + return TB_NONE; + if(0==memcmp(str, "light", 5)) + return 0==memcmp(&str[5], "-all", 4) ? TB_LIGHT_ALL : TB_LIGHT; + } + return def; +} + +static EMouseOver toMouseOver(const char *str, EMouseOver def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "true", 4) || 0==memcmp(str, "colored", 7)) + return MO_COLORED; + if(0==memcmp(str, "thickcolored", 12)) + return MO_COLORED_THICK; + if(0==memcmp(str, "plastik", 7)) + return MO_PLASTIK; + if(0==memcmp(str, "glow", 4)) + return MO_GLOW; + if(0==memcmp(str, "false", 4) || 0==memcmp(str, "none", 4)) + return MO_NONE; + } + return def; +} + +static EAppearance toAppearance(const char *str, EAppearance def, EAppAllow allow, QtCPixmap *pix, bool checkImage) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "flat", 4)) + return APPEARANCE_FLAT; + if(0==memcmp(str, "raised", 6)) + return APPEARANCE_RAISED; + if(0==memcmp(str, "dullglass", 9)) + return APPEARANCE_DULL_GLASS; + if(0==memcmp(str, "glass", 5) || 0==memcmp(str, "shinyglass", 10)) + return APPEARANCE_SHINY_GLASS; + if(0==memcmp(str, "agua", 4)) +#if defined __cplusplus && !defined CONFIG_DIALOG && defined QT_VERSION && QT_VERSION < 0x040000 + return APPEARANCE_AGUA_MOD; +#else + return APPEARANCE_AGUA; +#endif + if(0==memcmp(str, "soft", 4)) + return APPEARANCE_SOFT_GRADIENT; + if(0==memcmp(str, "gradient", 8) || 0==memcmp(str, "lightgradient", 13)) + return APPEARANCE_GRADIENT; + if(0==memcmp(str, "harsh", 5)) + return APPEARANCE_HARSH_GRADIENT; + if(0==memcmp(str, "inverted", 8)) + return APPEARANCE_INVERTED; + if(0==memcmp(str, "darkinverted", 12)) + return APPEARANCE_DARK_INVERTED; + if(0==memcmp(str, "splitgradient", 13)) + return APPEARANCE_SPLIT_GRADIENT; + if(0==memcmp(str, "bevelled", 8)) + return APPEARANCE_BEVELLED; + if(APP_ALLOW_FADE==allow && 0==memcmp(str, "fade", 4)) + return APPEARANCE_FADE; + if(APP_ALLOW_STRIPED==allow && 0==memcmp(str, "striped", 7)) + return APPEARANCE_STRIPED; + if(APP_ALLOW_NONE==allow && 0==memcmp(str, "none", 4)) + return APPEARANCE_NONE; + if(NULL!=pix && APP_ALLOW_STRIPED==allow && 0==memcmp(str, "file", 4) && strlen(str)>9) + return loadImage(&str[5], pix) || !checkImage ? APPEARANCE_FILE : def; + + if(0==memcmp(str, "customgradient", 14) && strlen(str)>14) + { + int i=atoi(&str[14]); + + i--; + if(i>=0 && i= 0x040000)) +static ETitleBarIcon toTitlebarIcon(const char *str, ETitleBarIcon def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "none", 4)) + return TITLEBAR_ICON_NONE; + if(0==memcmp(str, "menu", 4)) + return TITLEBAR_ICON_MENU_BUTTON; + if(0==memcmp(str, "title", 5)) + return TITLEBAR_ICON_NEXT_TO_TITLE; + } + return def; +} +#endif + +static EImageType toImageType(const char *str, EImageType def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "none", 4)) + return IMG_NONE; + if(0==memcmp(str, "plainrings", 10)) + return IMG_PLAIN_RINGS; + if(0==memcmp(str, "rings", 5)) + return IMG_BORDERED_RINGS; + if(0==memcmp(str, "squarerings", 11)) + return IMG_SQUARE_RINGS; + if(0==memcmp(str, "file", 4)) + return IMG_FILE; + } + return def; +} + +static EGlow toGlow(const char *str, EGlow def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "none", 4)) + return GLOW_NONE; + if(0==memcmp(str, "start", 5)) + return GLOW_START; + if(0==memcmp(str, "middle", 6)) + return GLOW_MIDDLE; + if(0==memcmp(str, "end", 3)) + return GLOW_END; + } + return def; +} + +static ETBarBtn toTBarBtn(const char *str, ETBarBtn def) +{ + if(str && 0!=str[0]) + { + if(0==memcmp(str, "standard", 8)) + return TBTN_STANDARD; + if(0==memcmp(str, "raised", 6)) + return TBTN_RAISED; + if(0==memcmp(str, "joined", 6)) + return TBTN_JOINED; + } + return def; +} + +const char * qtcGetHome() +{ + static const char *home=NULL; + +#ifdef _WIN32 + home = getenv("HOMEPATH"); +#else + if(!home) + { + struct passwd *p=getpwuid(getuid()); + + if(p) + home=p->pw_dir; + else + { + char *env=getenv("HOME"); + + if(env) + home=env; + } + + if(!home) + home="/tmp"; + } +#endif + return home; +} + +#ifdef __cplusplus + +#if defined QTC_QT_ONLY || QT_VERSION < 0x040000 +#if QT_VERSION < 0x040000 +#include +#include +#else +#include +#endif +// Take from KStandardDirs::makeDir +static bool makeDir(const QString& dir, int mode) +{ + // we want an absolute path + if (QDir::isRelativePath(dir)) + return false; + +#ifdef Q_WS_WIN + return QDir().mkpath(dir); +#else + QString target = dir; + uint len = target.length(); + + // append trailing slash if missing + if (dir.at(len - 1) != '/') + target += '/'; + + QString base; + uint i = 1; + + while( i < len ) + { + struct stat st; +#if QT_VERSION >= 0x040000 + int pos = target.indexOf('/', i); +#else + int pos = target.find('/', i); +#endif + base += target.mid(i - 1, pos - i + 1); + QByteArray baseEncoded = QFile::encodeName(base); + // bail out if we encountered a problem + if (stat(baseEncoded, &st) != 0) + { + // Directory does not exist.... + // Or maybe a dangling symlink ? + if (lstat(baseEncoded, &st) == 0) + (void)unlink(baseEncoded); // try removing + + if (mkdir(baseEncoded, static_cast(mode)) != 0) + { +#if QT_VERSION >= 0x040000 + baseEncoded.prepend("trying to create local folder "); + perror(baseEncoded.constData()); +#else + perror("trying to create QtCurve config folder "); +#endif + return false; // Couldn't create it :-( + } + } + i = pos + 1; + } + return true; +#endif +} + +#else +#include +#endif +#endif + +const char *qtcConfDir() +{ + static char *cfgDir=NULL; + + if(!cfgDir) + { + static const char *home=NULL; + +#if 0 + char *env=getenv("XDG_CONFIG_HOME"); + + /* + Check the setting of XDG_CONFIG_HOME + For some reason, sudo leaves the env vars set to those of the + caller - so XDG_CONFIG_HOME would point to the users setting, and + not roots. + + Therefore, check that home is first part of XDG_CONFIG_HOME + */ + + if(env && 0==getuid()) + { + if(!home) + home=qtcGetHome(); + if(home && home!=strstr(env, home)) + env=NULL; + } +#else + /* + Hmm... for 'root' dont bother to check env var, just set to ~/.config + - as problems would arise if "sudo kcmshell style", and then + "sudo su" / "kcmshell style". The 1st would write to ~/.config, but + if root has a XDG_ set then that would be used on the second :-( + */ +#ifndef _WIN32 + char *env=0==getuid() ? NULL : getenv("XDG_CONFIG_HOME"); +#else + char *env=0; +#endif + +#endif + + if(!env) + { + if(!home) + home=qtcGetHome(); + + cfgDir=(char *)malloc(strlen(home)+18); + sprintf(cfgDir, "%s/.config/qtcurve/", home); + } + else + { + cfgDir=(char *)malloc(strlen(env)+10); + sprintf(cfgDir, "%s/qtcurve/", env); + } + +//#if defined CONFIG_WRITE || !defined __cplusplus + { + struct stat info; + + if(0!=lstat(cfgDir, &info)) + { +#ifdef __cplusplus +#if defined QTC_QT_ONLY || QT_VERSION < 0x040000 + makeDir(cfgDir, 0755); +#else + KStandardDirs::makeDir(cfgDir, 0755); +#endif +#else + g_mkdir_with_parents(cfgDir, 0755); +#endif + } + } +//#endif + } + + return cfgDir; +} + +#ifdef __cplusplus +WindowBorders qtcGetWindowBorderSize(bool force) +#else +WindowBorders qtcGetWindowBorderSize(bool force) +#endif +{ + static WindowBorders def={24, 18, 4, 4}; + static WindowBorders sizes={-1, -1, -1, -1}; + + if(-1==sizes.titleHeight || force) + { +#ifdef __cplusplus + QFile f(qtcConfDir()+QString(BORDER_SIZE_FILE)); + +#if QT_VERSION >= 0x040000 + if(f.open(QIODevice::ReadOnly)) +#else + if(f.open(IO_ReadOnly)) +#endif + { + QTextStream stream(&f); + QString line; + + sizes.titleHeight=stream.readLine().toInt(); + sizes.toolTitleHeight=stream.readLine().toInt(); + sizes.bottom=stream.readLine().toInt(); + sizes.sides=stream.readLine().toInt(); + f.close(); + } +#else // __cplusplus + char *filename=(char *)malloc(strlen(qtcConfDir())+strlen(BORDER_SIZE_FILE)+1); + FILE *f=NULL; + + sprintf(filename, "%s"BORDER_SIZE_FILE, qtcConfDir()); + if((f=fopen(filename, "r"))) + { + char *line=NULL; + size_t len; + getline(&line, &len, f); + sizes.titleHeight=atoi(line); + getline(&line, &len, f); + sizes.toolTitleHeight=atoi(line); + getline(&line, &len, f); + sizes.bottom=atoi(line); + getline(&line, &len, f); + sizes.sides=atoi(line); + if(line) + free(line); + fclose(f); + } + free(filename); +#endif // __cplusplus + } + + return sizes.titleHeight<12 ? def : sizes; +} + +#if (!defined QT_VERSION || QT_VERSION >= 0x040000) && !defined CONFIG_DIALOG + +#ifdef __cplusplus +bool qtcBarHidden(const QString &app, const char *prefix) +{ + return QFile::exists(QFile::decodeName(qtcConfDir())+prefix+app); +} + +void qtcSetBarHidden(const QString &app, bool hidden, const char *prefix) +{ + if(!hidden) + QFile::remove(QFile::decodeName(qtcConfDir())+prefix+app); + else + QFile(QFile::decodeName(qtcConfDir())+prefix+app).open(QIODevice::WriteOnly); +} + +#else // __cplusplus +static bool qtcFileExists(const char *name) +{ + struct stat info; + + return 0==lstat(name, &info) && S_ISREG(info.st_mode); +} + +static char * qtcGetBarFileName(const char *app, const char *prefix) +{ + static char *filename=NULL; + + filename=(char *)realloc(filename, strlen(qtcConfDir())+strlen(prefix)+strlen(app)+1); + sprintf(filename, "%s%s%s", qtcConfDir(), prefix, app); + + return filename; +} + +bool qtcBarHidden(const char *app, const char *prefix) +{ + return qtcFileExists(qtcGetBarFileName(app, prefix)); +} + +void qtcSetBarHidden(const char *app, bool hidden, const char *prefix) +{ + if(!hidden) + unlink(qtcGetBarFileName(app, prefix)); + else + { + FILE *f=fopen(qtcGetBarFileName(app, prefix), "w"); + + if(f) + fclose(f); + } +} + +#endif // __cplusplus + +#ifdef __cplusplus +#include +#include +#endif // __cplusplus + +void qtcLoadBgndImage(QtCImage *img) +{ + if(!img->loaded && + ( (img->width>16 && img->width<1024 && img->height>16 && img->height<1024) || (0==img->width && 0==img->height)) ) + { + img->loaded=true; +#ifdef __cplusplus + img->pixmap.img=QPixmap(); + QString file(determineFileName(img->pixmap.file)); + + if(!file.isEmpty()) + { + bool loaded=false; + if(0!=img->width && (file.endsWith(".svg", Qt::CaseInsensitive) || file.endsWith(".svgz", Qt::CaseInsensitive))) + { + QSvgRenderer svg(file); + + if(svg.isValid()) + { + img->pixmap.img=QPixmap(img->width, img->height); + img->pixmap.img.fill(Qt::transparent); + QPainter painter(&img->pixmap.img); + svg.render(&painter); + painter.end(); + loaded=true; + } + } + if(!loaded && img->pixmap.img.load(file) && 0!=img->width && + (img->pixmap.img.height()!=img->height || img->pixmap.img.width()!=img->width)) + img->pixmap.img=img->pixmap.img.scaled(img->width, img->height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } +#else // __cplusplus + img->pixmap.img=0L; + if(img->pixmap.file) + { + img->pixmap.img=0==img->width + ? gdk_pixbuf_new_from_file(determineFileName(img->pixmap.file), NULL) + : gdk_pixbuf_new_from_file_at_scale(determineFileName(img->pixmap.file), img->width, img->height, FALSE, NULL); + if(img->pixmap.img && 0==img->width && img->pixmap.img) + { + img->width=gdk_pixbuf_get_width(img->pixmap.img); + img->height=gdk_pixbuf_get_height(img->pixmap.img); + } + } +#endif // __cplusplus + } +} + +#endif // (!defined QT_VERSION || QT_VERSION >= 0x040000) && !defined CONFIG_DIALOG + +static void checkColor(EShade *s, color *c) +{ + if(SHADE_CUSTOM==*s && IS_BLACK(*c)) + *s=SHADE_NONE; +} + +#ifdef __cplusplus + +class QtCConfig +{ + public: + + QtCConfig(const QString &filename); + + bool ok() const { return values.count()>0; } + bool hasKey(const QString &key) { return values.contains(key); } + const QString & readEntry(const QString &key, const QString &def=QString::null); + + private: + + QMap values; +}; + +QtCConfig::QtCConfig(const QString &filename) +{ + QFile f(filename); + +#if QT_VERSION >= 0x040000 + if(f.open(QIODevice::ReadOnly)) +#else + if(f.open(IO_ReadOnly)) +#endif + { + QTextStream stream(&f); + QString line; + + while(!stream.atEnd()) + { + line = stream.readLine(); +#if QT_VERSION >= 0x040000 + int pos=line.indexOf('='); +#else + int pos=line.find('='); +#endif + if(-1!=pos) + values[line.left(pos)]=line.mid(pos+1); + } + f.close(); + } +} + +inline const QString & QtCConfig::readEntry(const QString &key, const QString &def) +{ + return values.contains(key) ? values[key] : def; +} + +inline QString readStringEntry(QtCConfig &cfg, const QString &key) +{ + return cfg.readEntry(key); +} + +static int readNumEntry(QtCConfig &cfg, const QString &key, int def) +{ + const QString &val(readStringEntry(cfg, key)); + + return val.isEmpty() ? def : val.toInt(); +} + +static int readVersionEntry(QtCConfig &cfg, const QString &key) +{ + const QString &val(readStringEntry(cfg, key)); + int major, minor, patch; + + return !val.isEmpty() && 3==sscanf(TO_LATIN1(val), "%d.%d.%d", &major, &minor, &patch) + ? MAKE_VERSION3(major, minor, patch) + : 0; +} + +static bool readBoolEntry(QtCConfig &cfg, const QString &key, bool def) +{ + const QString &val(readStringEntry(cfg, key)); + + return val.isEmpty() ? def : (val=="true" ? true : false); +} + +static void readDoubleList(QtCConfig &cfg, const char *key, double *list, int count) +{ +#if (defined QT_VERSION && (QT_VERSION >= 0x040000)) + QStringList strings(readStringEntry(cfg, key).split(',', QString::SkipEmptyParts)); +#else + QStringList strings(QStringList::split(',', readStringEntry(cfg, key))); +#endif + bool ok(count==strings.size()); + + if(ok) + { + QStringList::ConstIterator it(strings.begin()); + int i; + + for(i=0; iENTRY=def->ENTRY; \ + else \ + qtcSetRgb(&(opts->ENTRY), TO_LATIN1(sVal)); \ + } + +#define CFG_READ_IMAGE(ENTRY) \ + { \ + opts->ENTRY.type=toImageType(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY.type); \ + opts->ENTRY.loaded=false; \ + opts->ENTRY.width=opts->ENTRY.height=0; \ + opts->ENTRY.onBorder=false; \ + opts->ENTRY.pos=PP_TR; \ + if(IMG_FILE==opts->ENTRY.type) \ + { \ + QString file(cfg.readEntry(#ENTRY ".file")); \ + if(!file.isEmpty()) \ + { \ + opts->ENTRY.pixmap.file=file; \ + opts->ENTRY.width=readNumEntry(cfg, #ENTRY ".width", 0); \ + opts->ENTRY.height=readNumEntry(cfg, #ENTRY ".height", 0); \ + opts->ENTRY.onBorder=readBoolEntry(cfg, #ENTRY ".onBorder", false); \ + opts->ENTRY.pos=(EPixPos)readNumEntry(cfg, #ENTRY ".pos", (int)PP_TR); \ + } \ + else \ + opts->ENTRY.type=IMG_NONE; \ + } \ + } + +#if QT_VERSION >= 0x040000 + #define CFG_READ_STRING_LIST(ENTRY) \ + { \ + QString val=readStringEntry(cfg, #ENTRY); \ + Strings set=val.isEmpty() ? Strings() : Strings::fromList(val.split(",", QString::SkipEmptyParts)); \ + opts->ENTRY=set.count() || cfg.hasKey(#ENTRY) ? set : def->ENTRY; \ + } +#else + #define CFG_READ_STRING_LIST(ENTRY) \ + { \ + QString val=readStringEntry(cfg, #ENTRY); \ + Strings list=val.isEmpty() ? Strings() : Strings::split(",", val, false); \ + opts->ENTRY=list.count() || cfg.hasKey(#ENTRY) ? list : def->ENTRY; \ + } +#endif + +#else + +static char * lookupCfgHash(GHashTable **cfg, char *key, char *val) +{ + char *rv=NULL; + + if(!*cfg) + *cfg=g_hash_table_new(g_str_hash, g_str_equal); + else + rv=(char *)g_hash_table_lookup(*cfg, key); + + if(!rv && val) + { + g_hash_table_insert(*cfg, g_strdup(key), g_strdup(val)); + rv=(char *)g_hash_table_lookup(*cfg, key); + } + + return rv; +} + +static GHashTable * loadConfig(const char *filename) +{ + FILE *f=fopen(filename, "r"); + GHashTable *cfg=NULL; + + if(f) + { + char line[MAX_CONFIG_INPUT_LINE_LEN]; + + while(NULL!=fgets(line, MAX_CONFIG_INPUT_LINE_LEN-1, f)) + { + char *eq=strchr(line, '='); + int pos=eq ? eq-line : -1; + + if(pos>0) + { + char *endl=strchr(line, '\n'); + + if(endl) + *endl='\0'; + + line[pos]='\0'; + + lookupCfgHash(&cfg, line, &line[pos+1]); + } + } + + fclose(f); + } + + return cfg; +} + +static void releaseConfig(GHashTable *cfg) +{ + g_hash_table_destroy(cfg); +} + +static char * readStringEntry(GHashTable *cfg, char *key) +{ + return lookupCfgHash(&cfg, key, NULL); +} + +static int readNumEntry(GHashTable *cfg, char *key, int def) +{ + char *str=readStringEntry(cfg, key); + + return str ? atoi(str) : def; +} + +static int readVersionEntry(GHashTable *cfg, char *key) +{ + char *str=readStringEntry(cfg, key); + int major, minor, patch; + + return str && 3==sscanf(str, "%d.%d.%d", &major, &minor, &patch) + ? MAKE_VERSION3(major, minor, patch) + : 0; +} + +static gboolean readBoolEntry(GHashTable *cfg, char *key, gboolean def) +{ + char *str=readStringEntry(cfg, key); + + return str ? (0==memcmp(str, "true", 4) ? true : false) : def; +} + +static void readDoubleList(GHashTable *cfg, char *key, double *list, int count) +{ + char *str=readStringEntry(cfg, key); + + if(str && 0!=str[0]) + { + int j, + comma=0; + bool ok=true; + + for(j=0; str[j]; ++j) + if(','==str[j]) + comma++; + + ok=(count-1)==comma; + if(ok) + { + for(j=0; jENTRY), str); \ + else \ + opts->ENTRY=def->ENTRY; \ + } +#define CFG_READ_IMAGE(ENTRY) \ + { \ + opts->ENTRY.type=toImageType(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY.type); \ + opts->ENTRY.loaded=false; \ + if(IMG_FILE==opts->ENTRY.type) \ + { \ + const char *file=readStringEntry(cfg, #ENTRY ".file"); \ + if(file) \ + { \ + opts->ENTRY.pixmap.file=file; \ + opts->ENTRY.width=readNumEntry(cfg, #ENTRY ".width", 0); \ + opts->ENTRY.height=readNumEntry(cfg, #ENTRY ".height", 0); \ + opts->ENTRY.onBorder=readBoolEntry(cfg, #ENTRY ".onBorder", false); \ + opts->ENTRY.pos=(EPixPos)readNumEntry(cfg, #ENTRY ".pos", (int)PP_TR); \ + } \ + else \ + { \ + opts->ENTRY.type=IMG_NONE; \ + } \ + } \ + } +#define CFG_READ_STRING_LIST(ENTRY) \ + { \ + const gchar *str=readStringEntry(cfg, #ENTRY); \ + if(str && 0!=str[0]) \ + opts->ENTRY=g_strsplit(str, ",", -1); \ + else if(def->ENTRY) \ + { \ + opts->ENTRY=def->ENTRY; \ + def->ENTRY=NULL; \ + } \ + } + +#endif + +#define CFG_READ_BOOL(ENTRY) \ + opts->ENTRY=readBoolEntry(cfg, #ENTRY, def->ENTRY); + +#define CFG_READ_ROUND(ENTRY) \ + opts->ENTRY=toRound(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_INT(ENTRY) \ + opts->ENTRY=readNumEntry(cfg, #ENTRY, def->ENTRY); + +#define CFG_READ_INT_BOOL(ENTRY, DEF) \ + if(readBoolEntry(cfg, #ENTRY, false)) \ + opts->ENTRY=DEF; \ + else \ + opts->ENTRY=readNumEntry(cfg, #ENTRY, def->ENTRY); + +#define CFG_READ_TB_BORDER(ENTRY) \ + opts->ENTRY=toTBarBorder(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_MOUSE_OVER(ENTRY) \ + opts->ENTRY=toMouseOver(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_APPEARANCE(ENTRY, ALLOW) \ + opts->ENTRY=toAppearance(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY, ALLOW, NULL, false); + +#define CFG_READ_APPEARANCE_PIXMAP(ENTRY, ALLOW, PIXMAP, CHECK) \ + opts->ENTRY=toAppearance(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY, ALLOW, PIXMAP, CHECK); + +/* +#define CFG_READ_APPEARANCE(ENTRY) \ + opts->ENTRY=toAppearance(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); +*/ + +#define CFG_READ_STRIPE(ENTRY) \ + opts->ENTRY=toStripe(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_SLIDER(ENTRY) \ + opts->ENTRY=toSlider(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_DEF_BTN(ENTRY) \ + opts->ENTRY=toInd(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_LINE(ENTRY) \ + opts->ENTRY=toLine(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_SHADE(ENTRY, AD, MENU_STRIPE, COL) \ + opts->ENTRY=toShade(TO_LATIN1(readStringEntry(cfg, #ENTRY)), AD, def->ENTRY, MENU_STRIPE, COL); + +#define CFG_READ_SCROLLBAR(ENTRY) \ + opts->ENTRY=toScrollbar(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_FRAME(ENTRY) \ + opts->ENTRY=toFrame(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_EFFECT(ENTRY) \ + opts->ENTRY=toEffect(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_SHADING(ENTRY) \ + opts->ENTRY=toShading(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_ECOLOR(ENTRY) \ + opts->ENTRY=toEColor(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_FOCUS(ENTRY) \ + opts->ENTRY=toFocus(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_TAB_MO(ENTRY) \ + opts->ENTRY=toTabMo(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_GRAD_TYPE(ENTRY) \ + opts->ENTRY=toGradType(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_LV_LINES(ENTRY) \ + opts->ENTRY=toLvLines(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#ifdef __cplusplus +#define CFG_READ_ALIGN(ENTRY) \ + opts->ENTRY=toAlign(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); +#endif + +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) +#define CFG_READ_TB_ICON(ENTRY) \ + opts->ENTRY=toTitlebarIcon(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); +#endif + +#define CFG_READ_GLOW(ENTRY) \ + opts->ENTRY=toGlow(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +#define CFG_READ_TBAR_BTN(ENTRY) \ + opts->ENTRY=toTBarBtn(TO_LATIN1(readStringEntry(cfg, #ENTRY)), def->ENTRY); + +static void checkAppearance(EAppearance *ap, Options *opts) +{ + if(*ap>=APPEARANCE_CUSTOM1 && *ap<(APPEARANCE_CUSTOM1+NUM_CUSTOM_GRAD)) + { +#ifdef __cplusplus + if(opts->customGradient.end()==opts->customGradient.find(*ap)) +#else + if(!opts->customGradient[*ap-APPEARANCE_CUSTOM1]) +#endif + { + if(ap==&opts->appearance) + *ap=APPEARANCE_FLAT; + else + *ap=opts->appearance; + } + } +} + +void qtcDefaultSettings(Options *opts); + +#ifndef __cplusplus +static void copyGradients(Options *src, Options *dest) +{ + if(src && dest && src!=dest) + { + int i; + + for(i=0; icustomGradient[i] && src->customGradient[i]->numStops>0) + { + dest->customGradient[i]=malloc(sizeof(Gradient)); + dest->customGradient[i]->numStops=src->customGradient[i]->numStops; + dest->customGradient[i]->stops=malloc(sizeof(GradientStop) * dest->customGradient[i]->numStops); + memcpy(dest->customGradient[i]->stops, src->customGradient[i]->stops, + sizeof(GradientStop) * dest->customGradient[i]->numStops); + dest->customGradient[i]->border=src->customGradient[i]->border; + } + else + dest->customGradient[i]=NULL; + } +} + +static void copyOpts(Options *src, Options *dest) +{ + if(src && dest && src!=dest) + { + memcpy(dest, src, sizeof(Options)); + dest->noBgndGradientApps=src->noBgndGradientApps; + dest->noBgndOpacityApps=src->noBgndOpacityApps; + dest->noMenuBgndOpacityApps=src->noMenuBgndOpacityApps; + dest->noBgndImageApps=src->noBgndImageApps; +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + dest->noDlgFixApps=src->noDlgFixApps; + src->noDlgFixApps=NULL; +#endif + dest->noMenuStripeApps=src->noMenuStripeApps; + src->noBgndGradientApps=src->noBgndOpacityApps=src->noMenuBgndOpacityApps=src->noBgndImageApps=src->noMenuStripeApps=NULL; + memcpy(dest->customShades, src->customShades, sizeof(double)*NUM_STD_SHADES); + memcpy(dest->customAlphas, src->customAlphas, sizeof(double)*NUM_STD_ALPHAS); + copyGradients(src, dest); + } +} + +static void freeOpts(Options *opts) +{ + if(opts) + { + int i; + + if(opts->noBgndGradientApps) + g_strfreev(opts->noBgndGradientApps); + if(opts->noBgndOpacityApps) + g_strfreev(opts->noBgndOpacityApps); + if(opts->noMenuBgndOpacityApps) + g_strfreev(opts->noMenuBgndOpacityApps); + if(opts->noBgndImageApps) + g_strfreev(opts->noBgndImageApps); +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + if(opts->noDlgFixApps) + g_strfreev(opts->noDlgFixApps); + opts->noDlgFixApps=NULL +#endif + if(opts->noMenuStripeApps) + g_strfreev(opts->noMenuStripeApps); + opts->noBgndGradientApps=opts->noBgndOpacityApps=opts->noMenuBgndOpacityApps=opts->noBgndImageApps=opts->noMenuStripeApps=NULL; + for(i=0; icustomGradient[i]) + { + if(opts->customGradient[i]->stops) + free(opts->customGradient[i]->stops); + free(opts->customGradient[i]); + opts->customGradient[i]=NULL; + } + } +} +#endif + +void qtcCheckConfig(Options *opts) +{ + /* **Must** check appearance first, as the rest will default to this */ + checkAppearance(&opts->appearance, opts); + checkAppearance(&opts->bgndAppearance, opts); + checkAppearance(&opts->menuBgndAppearance, opts); + checkAppearance(&opts->menubarAppearance, opts); + checkAppearance(&opts->menuitemAppearance, opts); + checkAppearance(&opts->toolbarAppearance, opts); + checkAppearance(&opts->lvAppearance, opts); + checkAppearance(&opts->tabAppearance, opts); + checkAppearance(&opts->activeTabAppearance, opts); + checkAppearance(&opts->sliderAppearance, opts); + checkAppearance(&opts->selectionAppearance, opts); + checkAppearance(&opts->titlebarAppearance, opts); + checkAppearance(&opts->inactiveTitlebarAppearance, opts); +#ifdef __cplusplus + checkAppearance(&opts->titlebarButtonAppearance, opts); + checkAppearance(&opts->selectionAppearance, opts); + checkAppearance(&opts->dwtAppearance, opts); +#endif + checkAppearance(&opts->menuStripeAppearance, opts); + checkAppearance(&opts->progressAppearance, opts); + checkAppearance(&opts->progressGrooveAppearance, opts); + checkAppearance(&opts->grooveAppearance, opts); + checkAppearance(&opts->sunkenAppearance, opts); + checkAppearance(&opts->sbarBgndAppearance, opts); + checkAppearance(&opts->sliderFill, opts); + checkAppearance(&opts->tooltipAppearance, opts); + + if(SHADE_BLEND_SELECTED==opts->shadeCheckRadio) + opts->shadeCheckRadio=SHADE_SELECTED; + + checkColor(&opts->shadeMenubars, &opts->customMenubarsColor); + checkColor(&opts->shadeSliders, &opts->customSlidersColor); + checkColor(&opts->shadeCheckRadio, &opts->customCheckRadioColor); + checkColor(&opts->menuStripe, &opts->customMenuStripeColor); + checkColor(&opts->comboBtn, &opts->customComboBtnColor); + checkColor(&opts->sortedLv, &opts->customSortedLvColor); + if(APPEARANCE_BEVELLED==opts->toolbarAppearance) + opts->toolbarAppearance=APPEARANCE_GRADIENT; + else if(APPEARANCE_RAISED==opts->toolbarAppearance) + opts->toolbarAppearance=APPEARANCE_FLAT; + + if(APPEARANCE_BEVELLED==opts->menubarAppearance) + opts->menubarAppearance=APPEARANCE_GRADIENT; + else if(APPEARANCE_RAISED==opts->menubarAppearance) + opts->menubarAppearance=APPEARANCE_FLAT; + + if(APPEARANCE_BEVELLED==opts->sliderAppearance) + opts->sliderAppearance=APPEARANCE_GRADIENT; + + if(APPEARANCE_BEVELLED==opts->tabAppearance) + opts->tabAppearance=APPEARANCE_GRADIENT; + + if(APPEARANCE_BEVELLED==opts->activeTabAppearance) + opts->activeTabAppearance=APPEARANCE_GRADIENT; + + if(APPEARANCE_RAISED==opts->selectionAppearance) + opts->selectionAppearance=APPEARANCE_FLAT; + else if(APPEARANCE_BEVELLED==opts->selectionAppearance) + opts->selectionAppearance=APPEARANCE_GRADIENT; + + if(APPEARANCE_RAISED==opts->menuStripeAppearance) + opts->menuStripeAppearance=APPEARANCE_FLAT; + else if(APPEARANCE_BEVELLED==opts->menuStripeAppearance) + opts->menuStripeAppearance=APPEARANCE_GRADIENT; + + if(opts->highlightFactorhighlightFactor>MAX_HIGHLIGHT_FACTOR) + opts->highlightFactor=DEFAULT_HIGHLIGHT_FACTOR; + + if(opts->crHighlightcrHighlight>MAX_HIGHLIGHT_FACTOR) + opts->crHighlight=DEFAULT_CR_HIGHLIGHT_FACTOR; + + if(opts->splitterHighlightsplitterHighlight>MAX_HIGHLIGHT_FACTOR) + opts->splitterHighlight=DEFAULT_SPLITTER_HIGHLIGHT_FACTOR; + +#if !defined __cplusplus || defined CONFIG_DIALOG + if(opts->expanderHighlightexpanderHighlight>MAX_HIGHLIGHT_FACTOR) + opts->expanderHighlight=DEFAULT_EXPANDER_HIGHLIGHT_FACTOR; +#endif + + if(0==opts->menuDelay) /* Qt seems to have issues if delay is 0 - so set this to 1 :-) */ + opts->menuDelay=MIN_MENU_DELAY; + else if(opts->menuDelaymenuDelay>MAX_MENU_DELAY) + opts->menuDelay=DEFAULT_MENU_DELAY; + + if(0==opts->sliderWidth%2) + opts->sliderWidth++; + + if(opts->sliderWidthsliderWidth>MAX_SLIDER_WIDTH) + opts->sliderWidth=DEFAULT_SLIDER_WIDTH; + + if(opts->sliderWidthsquare|=SQUARE_SB_SLIDER; + + if(opts->sliderWidththinSbarGroove=false; + + if(opts->sliderWidthsliderThumbs=LINE_NONE; + + if(opts->lighterPopupMenuBgndlighterPopupMenuBgnd>MAX_LIGHTER_POPUP_MENU) + opts->lighterPopupMenuBgnd=DEF_POPUPMENU_LIGHT_FACTOR; + + if(opts->tabBgndtabBgnd>MAX_TAB_BGND) + opts->tabBgnd=DEF_TAB_BGND; + + if(opts->animatedProgress && !opts->stripedProgress) + opts->animatedProgress=false; + + if(0==opts->gbFactor && FRAME_SHADED==opts->groupBox) + opts->groupBox=FRAME_PLAIN; + + if(opts->gbFactorgbFactor>MAX_GB_FACTOR) + opts->gbFactor=DEF_GB_FACTOR; + + if(!opts->gtkComboMenus) + opts->doubleGtkComboArrow=false; + +#if defined __cplusplus && defined QT_VERSION && QT_VERSION < 0x040000 && !defined CONFIG_DIALOG + opts->crSize=CR_SMALL_SIZE; + if(SLIDER_CIRCULAR==opts->sliderStyle) + opts->sliderStyle=SLIDER_ROUND; + if(STRIPE_FADE==opts->stripedProgress) + opts->stripedProgress=STRIPE_PLAIN; +#endif + /* For now, only 2 sizes... */ + if(opts->crSize!=CR_SMALL_SIZE && opts->crSize!=CR_LARGE_SIZE) + opts->crSize=CR_SMALL_SIZE; + +/* +?? + if(SHADE_CUSTOM==opts->shadeMenubars || SHADE_BLEND_SELECTED==opts->shadeMenubars || !opts->borderMenuitems) + opts->colorMenubarMouseOver=true; +*/ + +#if defined __cplusplus && defined QT_VERSION && QT_VERSION < 0x040000 && !defined CONFIG_DIALOG + if(opts->round>ROUND_FULL) + opts->round=ROUND_FULL; +#endif +#ifndef CONFIG_DIALOG + if(MO_GLOW==opts->coloredMouseOver && EFFECT_NONE==opts->buttonEffect) + opts->coloredMouseOver=MO_COLORED_THICK; + + if(IND_GLOW==opts->defBtnIndicator && EFFECT_NONE==opts->buttonEffect) + opts->defBtnIndicator=IND_TINT; + + if(opts->round>ROUND_EXTRA && FOCUS_GLOW!=opts->focus) + opts->focus=FOCUS_LINE; + + if(EFFECT_NONE==opts->buttonEffect) + { + opts->etchEntry=false; + if(FOCUS_GLOW==opts->focus) + opts->focus=FOCUS_FULL; + } + +// if(opts->squareScrollViews) +// opts->highlightScrollViews=false; + + if(SHADE_WINDOW_BORDER==opts->shadeMenubars) + opts->shadeMenubarOnlyWhenActive=true; + + if(MO_GLOW==opts->coloredMouseOver) + opts->coloredTbarMo=true; + + if(ROUND_NONE==opts->round) + opts->square=SQUARE_ALL; +#endif + + if(opts->bgndOpacity<0 || opts->bgndOpacity>100) + opts->bgndOpacity=100; + if(opts->dlgOpacity<0 || opts->dlgOpacity>100) + opts->dlgOpacity=100; + if(opts->menuBgndOpacity<0 || opts->menuBgndOpacity>100) + opts->menuBgndOpacity=100; + +#ifndef CONFIG_DIALOG + opts->bgndAppearance=MODIFY_AGUA(opts->bgndAppearance); + opts->selectionAppearance=MODIFY_AGUA(opts->selectionAppearance); + opts->lvAppearance=MODIFY_AGUA_X(opts->lvAppearance, APPEARANCE_LV_AGUA); + opts->sbarBgndAppearance=MODIFY_AGUA(opts->sbarBgndAppearance); + opts->tooltipAppearance=MODIFY_AGUA(opts->tooltipAppearance); + opts->progressGrooveAppearance=MODIFY_AGUA(opts->progressGrooveAppearance); + opts->menuBgndAppearance=MODIFY_AGUA(opts->menuBgndAppearance); + opts->menuStripeAppearance=MODIFY_AGUA(opts->menuStripeAppearance); + opts->grooveAppearance=MODIFY_AGUA(opts->grooveAppearance); + opts->progressAppearance=MODIFY_AGUA(opts->progressAppearance); + opts->sliderFill=MODIFY_AGUA(opts->sliderFill); + opts->tabAppearance=MODIFY_AGUA(opts->tabAppearance); + opts->activeTabAppearance=MODIFY_AGUA(opts->activeTabAppearance); + opts->menuitemAppearance=MODIFY_AGUA(opts->menuitemAppearance); + + if(!opts->borderProgress && (!opts->fillProgress || !(opts->square&SQUARE_PROGRESS))) + opts->borderProgress=true; + + opts->titlebarAppearance=MODIFY_AGUA(opts->titlebarAppearance); + opts->inactiveTitlebarAppearance=MODIFY_AGUA(opts->inactiveTitlebarAppearance); + + if(opts->shadePopupMenu && SHADE_NONE==opts->shadeMenubars) + opts->shadePopupMenu=false; + +#ifdef __cplusplus + +#if defined QT_VERSION && QT_VERSION >= 0x040000 + if(!(opts->titlebarButtons&TITLEBAR_BUTTON_ROUND)) +#endif + opts->titlebarButtonAppearance=MODIFY_AGUA(opts->titlebarButtonAppearance); + opts->dwtAppearance=MODIFY_AGUA(opts->dwtAppearance); +#endif + if(opts->windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR && + (opts->windowBorder&WINDOW_BORDER_BLEND_TITLEBAR || SHADE_WINDOW_BORDER==opts->shadeMenubars)) + opts->windowBorder-=WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR; + + if(APPEARANCE_FLAT==opts->tabAppearance) + opts->tabAppearance=APPEARANCE_RAISED; + if(EFFECT_NONE==opts->buttonEffect) + opts->etchEntry=false; + if(opts->colorSliderMouseOver && + (SHADE_NONE==opts->shadeSliders || SHADE_DARKEN==opts->shadeSliders)) + opts->colorSliderMouseOver=false; +#endif /* ndef CONFIG_DIALOG */ + + if(LINE_1DOT==opts->toolbarSeparators) + opts->toolbarSeparators=LINE_DOTS; +} + +#ifdef __cplusplus +bool qtcReadConfig(const QString &file, Options *opts, Options *defOpts, bool checkImages) +#else +bool qtcReadConfig(const char *file, Options *opts, Options *defOpts) +#endif +{ +#ifdef __cplusplus + if(file.isEmpty()) + { + const char *env=getenv("QTCURVE_CONFIG_FILE"); + + if(NULL!=env) + return qtcReadConfig(env, opts, defOpts); + else + { + const char *cfgDir=qtcConfDir(); + + if(cfgDir) + { + QString filename(QFile::decodeName(cfgDir)+CONFIG_FILE); + + if(!QFile::exists(filename)) + filename=QFile::decodeName(cfgDir)+"../"OLD_CONFIG_FILE; + return qtcReadConfig(filename, opts, defOpts); + } + } + } +#else + bool checkImages=true; + if(!file) + { + const char *env=getenv("QTCURVE_CONFIG_FILE"); + + if(NULL!=env) + return qtcReadConfig(env, opts, defOpts); + else + { + const char *cfgDir=qtcConfDir(); + + if(cfgDir) + { + char *filename=(char *)malloc(strlen(cfgDir)+strlen(OLD_CONFIG_FILE)+4); + bool rv=false; + + sprintf(filename, "%s"CONFIG_FILE, cfgDir); + if(!qtcFileExists(filename)) + sprintf(filename, "%s../"OLD_CONFIG_FILE, cfgDir); + rv=qtcReadConfig(filename, opts, defOpts); + free(filename); + return rv; + } + } + } +#endif + else + { +#ifdef __cplusplus + QtCConfig cfg(file); + + if(cfg.ok()) + { +#else + GHashTable *cfg=loadConfig(file); + + if(cfg) + { +#endif + int i; + + opts->version=readVersionEntry(cfg, VERSION_KEY); + +#ifdef __cplusplus + Options newOpts; + + if(defOpts) + newOpts=*defOpts; + else + qtcDefaultSettings(&newOpts); + + Options *def=&newOpts; + + if(opts!=def) + opts->customGradient=def->customGradient; + +#else + Options newOpts; + Options *def=&newOpts; +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + opts->noDlgFixApps=NULL; +#endif + opts->noBgndGradientApps=opts->noBgndOpacityApps=opts->noMenuBgndOpacityApps=opts->noBgndImageApps=opts->noMenuStripeApps=NULL; + for(i=0; icustomGradient[i]=NULL; + + if(defOpts) + copyOpts(defOpts, &newOpts); + else + qtcDefaultSettings(&newOpts); + if(opts!=def) + copyGradients(def, opts); +#endif + + /* Check if the config file expects old default values... */ + if(opts->versiongroupBox=framelessGroupBoxes ? (groupBoxLine ? FRAME_LINE : FRAME_NONE) : FRAME_PLAIN; + opts->gbLabel=framelessGroupBoxes ? GB_LBL_BOLD : 0; + opts->gbFactor=0; + def->focus=FOCUS_LINE; + def->crHighlight=3; + } + else + { + CFG_READ_FRAME(groupBox) + CFG_READ_INT(gbLabel) + } + + if(opts->versionwindowBorder= + (readBoolEntry(cfg, "colorTitlebarOnly", def->windowBorder&WINDOW_BORDER_COLOR_TITLEBAR_ONLY) + ? WINDOW_BORDER_COLOR_TITLEBAR_ONLY : 0)+ + (readBoolEntry(cfg, "titlebarBorder", def->windowBorder&WINDOW_BORDER_ADD_LIGHT_BORDER) + ? WINDOW_BORDER_ADD_LIGHT_BORDER : 0)+ + (readBoolEntry(cfg, "titlebarBlend", def->windowBorder&WINDOW_BORDER_BLEND_TITLEBAR) + ? WINDOW_BORDER_BLEND_TITLEBAR : 0); + } + else + CFG_READ_INT(windowBorder); + + if(opts->versionwindowBorder|=WINDOW_BORDER_FILL_TITLEBAR; + def->square=SQUARE_POPUP_MENUS; + } + + if(opts->versionsquare= + (readBoolEntry(cfg, "squareLvSelection", def->square&SQUARE_LISTVIEW_SELECTION) ? SQUARE_LISTVIEW_SELECTION : SQUARE_NONE)+ + (readBoolEntry(cfg, "squareScrollViews", def->square&SQUARE_SCROLLVIEW) ? SQUARE_SCROLLVIEW : SQUARE_NONE)+ + (readBoolEntry(cfg, "squareProgress", def->square&SQUARE_PROGRESS) ? SQUARE_PROGRESS : SQUARE_NONE)+ + (readBoolEntry(cfg, "squareEntry", def->square&SQUARE_ENTRY)? SQUARE_ENTRY : SQUARE_NONE); + } + else + CFG_READ_INT(square) + if(opts->versiontbarBtns=TBTN_STANDARD; + opts->thin=(readBoolEntry(cfg, "thinnerMenuItems", def->thin&THIN_MENU_ITEMS) ? THIN_MENU_ITEMS : 0)+ + (readBoolEntry(cfg, "thinnerBtns", def->thin&THIN_BUTTONS) ? THIN_BUTTONS : 0); + } + else + { + CFG_READ_INT(thin) + } + if(opts->versionsquare|=SQUARE_TOOLTIPS; + if(opts->versionsquare|=SQUARE_POPUP_MENUS; + if(opts->versioncrSize=CR_SMALL_SIZE; + if(opts->versionroundAllTabs=false; + def->smallRadio=false; + def->splitters=LINE_FLAT; + def->handles=LINE_SUNKEN; + def->crHighlight=0; +#ifdef __cplusplus + def->dwtAppearance=APPEARANCE_FLAT; +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + def->dwtSettings=0; +#endif +#endif + def->inactiveTitlebarAppearance=APPEARANCE_CUSTOM2; + } + if(opts->versiondoubleGtkComboArrow=false; + if(opts->versionmenuStripeAppearance=APPEARANCE_GRADIENT; + def->etchEntry=true; + def->gtkScrollViews=false; + def->thinSbarGroove=false; +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + def->titlebarButtons=TITLEBAR_BUTTON_HOVER_FRAME; + def->titlebarIcon=TITLEBAR_ICON_MENU_BUTTON; +#endif + } + if(opts->versiontabMouseOver=TAB_MO_BOTTOM; + def->activeTabAppearance=APPEARANCE_FLAT; + def->unifySpin=false; + def->unifyCombo=false; + def->borderTab=false; + def->thin=0; + } + if(opts->versiontabMouseOver=TAB_MO_TOP; + def->sliderStyle=SLIDER_TRIANGULAR; +#ifdef __cplusplus + def->titlebarAlignment=ALIGN_LEFT; +#endif + } + if(opts->versiontitlebarAppearance=APPEARANCE_GRADIENT; + def->inactiveTitlebarAppearance=APPEARANCE_GRADIENT; + def->round=ROUND_FULL; + def->appearance=APPEARANCE_DULL_GLASS; + def->sliderAppearance=APPEARANCE_DULL_GLASS; + def->menuitemAppearance=APPEARANCE_DULL_GLASS; + def->useHighlightForMenu=true; + def->tabAppearance=APPEARANCE_GRADIENT; + def->highlightFactor=5; + def->toolbarSeparators=LINE_NONE; + def->menubarAppearance=APPEARANCE_SOFT_GRADIENT; + def->crButton=false; + def->customShades[0]=0; + def->stripedProgress=STRIPE_DIAGONAL; + def->sunkenAppearance=APPEARANCE_INVERTED; + def->focus=FOCUS_FILLED; + } + if(opts->versioncoloredMouseOver=MO_PLASTIK; + def->buttonEffect=EFFECT_NONE; + def->defBtnIndicator=IND_TINT; + def->vArrows=false; + def->toolbarAppearance=APPEARANCE_GRADIENT; + def->focus=FOCUS_STANDARD; + def->selectionAppearance=APPEARANCE_FLAT; + def->flatSbarButtons=false; + def->comboSplitter=true; + def->handles=LINE_DOTS; + def->lighterPopupMenuBgnd=15; + def->activeTabAppearance=APPEARANCE_GRADIENT; + def->gbLabel=GB_LBL_BOLD; + def->groupBox=FRAME_NONE; + def->shadeSliders=SHADE_BLEND_SELECTED; + def->progressGrooveColor=ECOLOR_BASE; + def->shadeMenubars=SHADE_DARKEN; + opts->highlightTab=true; + } + + if(opts!=def) + { + opts->customShades[0]=0; + opts->customAlphas[0]=0; + if(USE_CUSTOM_SHADES(*def)) + memcpy(opts->customShades, def->customShades, sizeof(double)*NUM_STD_SHADES); + } + + CFG_READ_INT(gbFactor) + CFG_READ_INT(passwordChar) + CFG_READ_ROUND(round) + CFG_READ_INT(highlightFactor) + CFG_READ_INT(menuDelay) + CFG_READ_INT(sliderWidth) + CFG_READ_INT(tabBgnd) + CFG_READ_TB_BORDER(toolbarBorders) + CFG_READ_APPEARANCE(appearance, APP_ALLOW_BASIC) + if(opts->versiontbarBtnAppearance=APPEARANCE_NONE; + opts->tbarBtnEffect=EFFECT_NONE; + } + else + { + CFG_READ_APPEARANCE(tbarBtnAppearance, APP_ALLOW_NONE) + CFG_READ_EFFECT(tbarBtnEffect); + } + CFG_READ_APPEARANCE_PIXMAP(bgndAppearance, APP_ALLOW_STRIPED, &(opts->bgndPixmap), checkImages) + CFG_READ_GRAD_TYPE(bgndGrad) + CFG_READ_GRAD_TYPE(menuBgndGrad) + CFG_READ_INT_BOOL(lighterPopupMenuBgnd, def->lighterPopupMenuBgnd) + CFG_READ_APPEARANCE_PIXMAP(menuBgndAppearance, APP_ALLOW_STRIPED, &(opts->menuBgndPixmap), checkImages) + + if(APPEARANCE_FLAT==opts->menuBgndAppearance && 0==opts->lighterPopupMenuBgnd && opts->versionmenuBgndAppearance=APPEARANCE_RAISED; + +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + CFG_READ_BOOL(fixParentlessDialogs) + CFG_READ_STRING_LIST(noDlgFixApps) +#endif + CFG_READ_STRIPE(stripedProgress) + CFG_READ_SLIDER(sliderStyle) + CFG_READ_BOOL(animatedProgress) + CFG_READ_BOOL(embolden) + CFG_READ_DEF_BTN(defBtnIndicator) + CFG_READ_LINE(sliderThumbs) + CFG_READ_LINE(handles) + CFG_READ_BOOL(highlightTab) + CFG_READ_INT_BOOL(colorSelTab, DEF_COLOR_SEL_TAB_FACTOR) + CFG_READ_BOOL(roundAllTabs) + CFG_READ_TAB_MO(tabMouseOver) + CFG_READ_SHADE(shadeSliders, true, false, &opts->customSlidersColor) + CFG_READ_SHADE(shadeMenubars, true, false, &opts->customMenubarsColor) + CFG_READ_SHADE(shadeCheckRadio, false, false, &opts->customCheckRadioColor) + CFG_READ_SHADE(sortedLv, true, false, &opts->customSortedLvColor) + CFG_READ_SHADE(crColor, true, false, &opts->customCrBgndColor) + CFG_READ_SHADE(progressColor, false, false, &opts->customProgressColor) + CFG_READ_APPEARANCE(menubarAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(menuitemAppearance, APP_ALLOW_FADE) + CFG_READ_APPEARANCE(toolbarAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(selectionAppearance, APP_ALLOW_BASIC) +#ifdef __cplusplus + CFG_READ_APPEARANCE(dwtAppearance, APP_ALLOW_BASIC) +#endif + CFG_READ_LINE(toolbarSeparators) + CFG_READ_LINE(splitters) + CFG_READ_BOOL(customMenuTextColor) + CFG_READ_MOUSE_OVER(coloredMouseOver) + CFG_READ_BOOL(menubarMouseOver) + CFG_READ_BOOL(useHighlightForMenu) + CFG_READ_BOOL(shadeMenubarOnlyWhenActive) + CFG_READ_TBAR_BTN(tbarBtns) + if(opts->versioncustomSlidersColor)) + CFG_READ_COLOR(customSlidersColor) + if(IS_BLACK(opts->customMenubarsColor)) + CFG_READ_COLOR(customMenubarsColor) + if(IS_BLACK(opts->customCheckRadioColor)) + CFG_READ_COLOR(customCheckRadioColor) + } + CFG_READ_COLOR(customMenuSelTextColor) + CFG_READ_COLOR(customMenuNormTextColor) + CFG_READ_SCROLLBAR(scrollbarType) + CFG_READ_EFFECT(buttonEffect) + CFG_READ_APPEARANCE(lvAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(tabAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(activeTabAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(sliderAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(progressAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(progressGrooveAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(grooveAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(sunkenAppearance, APP_ALLOW_BASIC) + CFG_READ_APPEARANCE(sbarBgndAppearance, APP_ALLOW_BASIC) + if(opts->versiontooltipAppearance=APPEARANCE_FLAT; + else + { + CFG_READ_APPEARANCE(tooltipAppearance, APP_ALLOW_BASIC) + } + + if(opts->versionsliderFill=IS_FLAT(opts->appearance) ? opts->grooveAppearance : APPEARANCE_GRADIENT; + else + { + CFG_READ_APPEARANCE(sliderFill, APP_ALLOW_BASIC) + } + CFG_READ_ECOLOR(progressGrooveColor) + CFG_READ_FOCUS(focus) + CFG_READ_BOOL(lvButton) + CFG_READ_LV_LINES(lvLines) + CFG_READ_BOOL(drawStatusBarFrames) + CFG_READ_BOOL(fillSlider) + CFG_READ_BOOL(roundMbTopOnly) + CFG_READ_BOOL(borderMenuitems) + CFG_READ_BOOL(darkerBorders) + CFG_READ_BOOL(vArrows) + CFG_READ_BOOL(xCheck) + CFG_READ_BOOL(fadeLines) + CFG_READ_GLOW(glowProgress) + CFG_READ_BOOL(colorMenubarMouseOver) + CFG_READ_INT_BOOL(crHighlight, opts->highlightFactor) + CFG_READ_BOOL(crButton) + CFG_READ_BOOL(smallRadio) + CFG_READ_BOOL(fillProgress) + CFG_READ_BOOL(comboSplitter) + CFG_READ_BOOL(highlightScrollViews) + CFG_READ_BOOL(etchEntry) + CFG_READ_INT_BOOL(splitterHighlight, opts->highlightFactor) + CFG_READ_INT(crSize) + CFG_READ_BOOL(flatSbarButtons) + CFG_READ_BOOL(borderSbarGroove) + CFG_READ_BOOL(borderProgress) + CFG_READ_BOOL(popupBorder) + CFG_READ_BOOL(unifySpinBtns) + CFG_READ_BOOL(unifySpin) + CFG_READ_BOOL(unifyCombo) + CFG_READ_BOOL(borderTab) + CFG_READ_BOOL(borderInactiveTab) + CFG_READ_BOOL(thinSbarGroove) + CFG_READ_BOOL(colorSliderMouseOver) + CFG_READ_BOOL(menuIcons) + CFG_READ_BOOL(forceAlternateLvCols) + CFG_READ_BOOL(invertBotTab) + CFG_READ_INT_BOOL(menubarHiding, HIDE_KEYBOARD) + CFG_READ_INT_BOOL(statusbarHiding, HIDE_KEYBOARD) + CFG_READ_BOOL(boldProgress) + CFG_READ_BOOL(coloredTbarMo) + CFG_READ_BOOL(borderSelection) + CFG_READ_BOOL(stripedSbar) + CFG_READ_INT_BOOL(windowDrag, WM_DRAG_MENUBAR) + CFG_READ_BOOL(shadePopupMenu) + CFG_READ_BOOL(hideShortcutUnderline) + +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + CFG_READ_BOOL(stdBtnSizes) + CFG_READ_INT(titlebarButtons) + CFG_READ_TB_ICON(titlebarIcon) +#endif +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + CFG_READ_BOOL(xbar) + CFG_READ_INT(dwtSettings) +#endif + CFG_READ_INT(bgndOpacity) + CFG_READ_INT(menuBgndOpacity) + CFG_READ_INT(dlgOpacity) + CFG_READ_SHADE(menuStripe, true, true, &opts->customMenuStripeColor) + CFG_READ_APPEARANCE(menuStripeAppearance, APP_ALLOW_BASIC) + if(opts->versioncustomMenuStripeColor)) + CFG_READ_COLOR(customMenuStripeColor) + CFG_READ_SHADE(comboBtn, true, false, &opts->customComboBtnColor); + CFG_READ_BOOL(gtkScrollViews) + CFG_READ_BOOL(doubleGtkComboArrow) + CFG_READ_BOOL(stdSidebarButtons) + CFG_READ_BOOL(toolbarTabs) + CFG_READ_BOOL(gtkComboMenus) +#ifdef __cplusplus + CFG_READ_ALIGN(titlebarAlignment) + CFG_READ_EFFECT(titlebarEffect) + CFG_READ_BOOL(centerTabText) +/* +#else + CFG_READ_BOOL(setDialogButtonOrder) +*/ +#endif +#if !defined __cplusplus || defined CONFIG_DIALOG + CFG_READ_INT(expanderHighlight) + CFG_READ_BOOL(mapKdeIcons) +#endif +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) || !defined __cplusplus + CFG_READ_BOOL(gtkButtonOrder) +#endif +#if !defined __cplusplus || (defined CONFIG_DIALOG && defined QT_VERSION && (QT_VERSION >= 0x040000)) + CFG_READ_BOOL(reorderGtkButtons) +#endif + CFG_READ_APPEARANCE(titlebarAppearance, APP_ALLOW_NONE) + CFG_READ_APPEARANCE(inactiveTitlebarAppearance, APP_ALLOW_NONE) + + if(APPEARANCE_BEVELLED==opts->titlebarAppearance) + opts->titlebarAppearance=APPEARANCE_GRADIENT; + else if(APPEARANCE_RAISED==opts->titlebarAppearance) + opts->titlebarAppearance=APPEARANCE_FLAT; + if((opts->windowBorder&WINDOW_BORDER_BLEND_TITLEBAR) && !(opts->windowBorder&WINDOW_BORDER_COLOR_TITLEBAR_ONLY)) + opts->windowBorder-=WINDOW_BORDER_BLEND_TITLEBAR; + if(APPEARANCE_BEVELLED==opts->inactiveTitlebarAppearance) + opts->inactiveTitlebarAppearance=APPEARANCE_GRADIENT; + else if(APPEARANCE_RAISED==opts->inactiveTitlebarAppearance) + opts->inactiveTitlebarAppearance=APPEARANCE_FLAT; +#ifdef __cplusplus + CFG_READ_APPEARANCE(titlebarButtonAppearance, APP_ALLOW_BASIC) +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + if(opts->xbar && opts->menubarHiding) + opts->xbar=false; +#endif +#endif + CFG_READ_SHADING(shading) + CFG_READ_IMAGE(bgndImage) + CFG_READ_IMAGE(menuBgndImage) + CFG_READ_STRING_LIST(noMenuStripeApps) +#if !defined __cplusplus || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + CFG_READ_STRING_LIST(noBgndGradientApps) + CFG_READ_STRING_LIST(noBgndOpacityApps) + CFG_READ_STRING_LIST(noMenuBgndOpacityApps) + CFG_READ_STRING_LIST(noBgndImageApps) +#ifdef CONFIG_DIALOG + if(opts->versionnoMenuBgndOpacityApps << "gtk"; +#endif +#endif +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + CFG_READ_STRING_LIST(menubarApps) + CFG_READ_STRING_LIST(statusbarApps) + CFG_READ_STRING_LIST(useQtFileDialogApps) + CFG_READ_STRING_LIST(windowDragWhiteList) + CFG_READ_STRING_LIST(windowDragBlackList) +#endif + readDoubleList(cfg, "customShades", opts->customShades, NUM_STD_SHADES); + readDoubleList(cfg, "customAlphas", opts->customAlphas, NUM_STD_ALPHAS); + +#ifdef __cplusplus +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + if(opts->titlebarButtons&TITLEBAR_BUTTON_COLOR || opts->titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR) + { +#if (defined QT_VERSION && (QT_VERSION >= 0x040000)) + QStringList cols(readStringEntry(cfg, "titlebarButtonColors").split(',', QString::SkipEmptyParts)); +#else + QStringList cols(QStringList::split(',', readStringEntry(cfg, "titlebarButtonColors"))); +#endif + if(cols.count() && 0==(cols.count()%NUM_TITLEBAR_BUTTONS) && cols.count()<=(NUM_TITLEBAR_BUTTONS*3)) + { + QStringList::ConstIterator it(cols.begin()), + end(cols.end()); + + for(int i=0; it!=end; ++it, ++i) + { + QColor col; + qtcSetRgb(&col, TO_LATIN1((*it))); + opts->titlebarButtonColors[i]=col; + } + if(cols.count()<(NUM_TITLEBAR_BUTTONS+1)) + opts->titlebarButtons&=~TITLEBAR_BUTTON_ICON_COLOR; + } + else + { + opts->titlebarButtons&=~TITLEBAR_BUTTON_COLOR; + opts->titlebarButtons&=~TITLEBAR_BUTTON_ICON_COLOR; + } + } +#endif + + for(i=APPEARANCE_CUSTOM1; i<(APPEARANCE_CUSTOM1+NUM_CUSTOM_GRAD); ++i) + { + QString gradKey; + + gradKey.sprintf("customgradient%d", (i-APPEARANCE_CUSTOM1)+1); + +#if (defined QT_VERSION && (QT_VERSION >= 0x040000)) + QStringList vals(readStringEntry(cfg, gradKey).split(',', QString::SkipEmptyParts)); +#else + QStringList vals(QStringList::split(',', readStringEntry(cfg, gradKey))); +#endif + + if(vals.size()) + opts->customGradient.erase((EAppearance)i); + + if(vals.size()>=5) + { + QStringList::ConstIterator it(vals.begin()), + end(vals.end()); + bool ok(true), + haveAlpha(false); + Gradient grad; + int j; + + grad.border=toGradientBorder(TO_LATIN1((*it)), &haveAlpha); + ok=vals.size()%(haveAlpha ? 3 : 2); + + for(++it, j=0; it!=end && ok; ++it, ++j) + { + double pos=(*it).toDouble(&ok), + val=ok ? (*(++it)).toDouble(&ok) : 0.0, + alpha=haveAlpha && ok ? (*(++it)).toDouble(&ok) : 1.0; + + ok=ok && (pos>=0 && pos<=1.0) && (val>=0.0 && val<=2.0) && (alpha>=0.0 && alpha<=1.0); + + if(ok) + grad.stops.insert(GradientStop(pos, val, alpha)); + } + + if(ok) + { + opts->customGradient[(EAppearance)i]=grad; + opts->customGradient[(EAppearance)i].stops=grad.stops.fix(); + } + } + } +#else + for(i=0; icustomGradient[i]) + { + if(opts->customGradient[i]->stops) + free(opts->customGradient[i]->stops); + free(opts->customGradient[i]); + opts->customGradient[i]=0L; + } + + if(comma>=4) + { + char *c=strchr(str, ','); + + if(c) + { + bool haveAlpha=false; + EGradientBorder border=toGradientBorder(str, &haveAlpha); + int parts=haveAlpha ? 3 : 2; + bool ok=0==comma%parts; + + *c='\0'; + + if(ok) + { + opts->customGradient[i]=malloc(sizeof(Gradient)); + opts->customGradient[i]->numStops=comma/parts; + opts->customGradient[i]->stops=malloc(sizeof(GradientStop) * opts->customGradient[i]->numStops); + opts->customGradient[i]->border=border; + str=c+1; + for(j=0; jcustomGradient[i]->stops[stop].pos=g_ascii_strtod(str, NULL); + str=c+1; + c=str ? strchr(str, ',') : 0L; + + if(c || str) + { + if(c) + *c='\0'; + opts->customGradient[i]->stops[stop].val=g_ascii_strtod(str, NULL); + str=c ? c+1 : c; + if(haveAlpha) + { + c=str ? strchr(str, ',') : 0L; + if(c || str) + { + if(c) + *c='\0'; + opts->customGradient[i]->stops[stop].alpha=g_ascii_strtod(str, NULL); + str=c ? c+1 : c; + } + else + ok=false; + } + else + opts->customGradient[i]->stops[stop].alpha=1.0; + } + else + ok=false; + } + else + ok=false; + + ok=ok && + (opts->customGradient[i]->stops[stop].pos>=0 && opts->customGradient[i]->stops[stop].pos<=1.0) && + (opts->customGradient[i]->stops[stop].val>=0.0 && opts->customGradient[i]->stops[stop].val<=2.0) && + (opts->customGradient[i]->stops[stop].alpha>=0.0 && opts->customGradient[i]->stops[stop].alpha<=1.0); + } + + if(ok) + { + int addStart=0, + addEnd=0; + if(opts->customGradient[i]->stops[0].pos>0.001) + addStart=1; + if(opts->customGradient[i]->stops[opts->customGradient[i]->numStops-1].pos<0.999) + addEnd=1; + + if(addStart || addEnd) + { + int newSize=opts->customGradient[i]->numStops+addStart+addEnd; + GradientStop *stops=malloc(sizeof(GradientStop) * newSize); + + if(addStart) + { + stops[0].pos=0.0; + stops[0].val=1.0; + stops[0].alpha=1.0; + } + memcpy(&stops[addStart], opts->customGradient[i]->stops, sizeof(GradientStop) * opts->customGradient[i]->numStops); + if(addEnd) + { + stops[opts->customGradient[i]->numStops+addStart].pos=1.0; + stops[opts->customGradient[i]->numStops+addStart].val=1.0; + stops[opts->customGradient[i]->numStops+addStart].alpha=1.0; + } + opts->customGradient[i]->numStops=newSize; + free(opts->customGradient[i]->stops); + opts->customGradient[i]->stops=stops; + } + } + else + { + free(opts->customGradient[i]->stops); + free(opts->customGradient[i]); + opts->customGradient[i]=0L; + } + } + } + } + } + } +#endif + + qtcCheckConfig(opts); + +#ifndef __cplusplus + if(!defOpts) + { + int i; + + for(i=0; icustomGradient[i]) + free(def->customGradient[i]); + } + releaseConfig(cfg); + freeOpts(defOpts); +#endif + return true; + } + else + { +#ifdef __cplusplus + if(defOpts) + *opts=*defOpts; + else + qtcDefaultSettings(opts); +#else + if(defOpts) + copyOpts(defOpts, opts); + else + qtcDefaultSettings(opts); +#endif + return true; + } + } + + return false; +} + +static bool fileExists(const char *path) +{ + struct stat info; + + return 0==lstat(path, &info) && (info.st_mode&S_IFMT)==S_IFREG; +} + +static const char * getSystemConfigFile() +{ + static const char * constFiles[]={ /*"/etc/qt4/"OLD_CONFIG_FILE, "/etc/qt3/"OLD_CONFIG_FILE, "/etc/qt/"OLD_CONFIG_FILE,*/ "/etc/"OLD_CONFIG_FILE, NULL }; + + int i; + + for(i=0; constFiles[i]; ++i) + if(fileExists(constFiles[i])) + return constFiles[i]; + return NULL; +} + +void qtcDefaultSettings(Options *opts) +{ + /* Set hard-coded defaults... */ +#ifndef __cplusplus + int i; + + for(i=0; icustomGradient[i]=0L; + opts->customGradient[APPEARANCE_CUSTOM1]=malloc(sizeof(Gradient)); + opts->customGradient[APPEARANCE_CUSTOM2]=malloc(sizeof(Gradient)); + qtcSetupGradient(opts->customGradient[APPEARANCE_CUSTOM1], GB_3D,3,0.0,1.2,0.5,1.0,1.0,1.0); + qtcSetupGradient(opts->customGradient[APPEARANCE_CUSTOM2], GB_3D,3,0.0,0.9,0.5,1.0,1.0,1.0); +#else + // Setup titlebar gradients... + qtcSetupGradient(&(opts->customGradient[APPEARANCE_CUSTOM1]), GB_3D,3,0.0,1.2,0.5,1.0,1.0,1.0); + qtcSetupGradient(&(opts->customGradient[APPEARANCE_CUSTOM2]), GB_3D,3,0.0,0.9,0.5,1.0,1.0,1.0); +#endif + opts->customShades[0]=1.16; + opts->customShades[1]=1.07; + opts->customShades[2]=0.9; + opts->customShades[3]=0.78; + opts->customShades[4]=0.84; + opts->customShades[5]=0.75; + opts->customAlphas[0]=0; + opts->contrast=7; + opts->passwordChar=0x25CF; + opts->gbFactor=DEF_GB_FACTOR; + opts->highlightFactor=DEFAULT_HIGHLIGHT_FACTOR; + opts->crHighlight=DEFAULT_CR_HIGHLIGHT_FACTOR; + opts->splitterHighlight=DEFAULT_SPLITTER_HIGHLIGHT_FACTOR; + opts->crSize=CR_LARGE_SIZE; + opts->menuDelay=DEFAULT_MENU_DELAY; + opts->sliderWidth=DEFAULT_SLIDER_WIDTH; + opts->selectionAppearance=APPEARANCE_HARSH_GRADIENT; + opts->fadeLines=true; + opts->glowProgress=GLOW_NONE; +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) || !defined __cplusplus + opts->round=ROUND_EXTRA; + opts->gtkButtonOrder=false; +#else + opts->round=ROUND_FULL; +#endif +#ifdef __cplusplus + opts->dwtAppearance=APPEARANCE_CUSTOM1; +#endif +#if !defined __cplusplus || (defined CONFIG_DIALOG && defined QT_VERSION && (QT_VERSION >= 0x040000)) + opts->reorderGtkButtons=false; +#endif + opts->bgndImage.type=IMG_NONE; + opts->bgndImage.width=opts->bgndImage.height=0; + opts->bgndImage.onBorder=false; + opts->bgndImage.pos=PP_TR; + opts->menuBgndImage.type=IMG_NONE; + opts->menuBgndImage.width=opts->menuBgndImage.height=0; + opts->menuBgndImage.onBorder=false; + opts->menuBgndImage.pos=PP_TR; + opts->lighterPopupMenuBgnd=DEF_POPUPMENU_LIGHT_FACTOR; + opts->tabBgnd=DEF_TAB_BGND; + opts->animatedProgress=false; + opts->stripedProgress=STRIPE_NONE; + opts->sliderStyle=SLIDER_PLAIN; + opts->highlightTab=false; + opts->colorSelTab=0; + opts->roundAllTabs=true; + opts->tabMouseOver=TAB_MO_GLOW; + opts->embolden=false; + opts->bgndGrad=GT_HORIZ; + opts->menuBgndGrad=GT_HORIZ; + opts->appearance=APPEARANCE_SOFT_GRADIENT; + opts->tbarBtnAppearance=APPEARANCE_NONE; + opts->tbarBtnEffect=EFFECT_NONE; + opts->bgndAppearance=APPEARANCE_FLAT; + opts->menuBgndAppearance=APPEARANCE_FLAT; + opts->lvAppearance=APPEARANCE_BEVELLED; + opts->tabAppearance=APPEARANCE_SOFT_GRADIENT; + opts->activeTabAppearance=APPEARANCE_SOFT_GRADIENT; + opts->sliderAppearance=APPEARANCE_SOFT_GRADIENT; + opts->menubarAppearance=APPEARANCE_FLAT; + opts->menuitemAppearance=APPEARANCE_FADE; + opts->toolbarAppearance=APPEARANCE_FLAT; + opts->progressAppearance=APPEARANCE_DULL_GLASS; + opts->progressGrooveAppearance=APPEARANCE_INVERTED; + opts->progressGrooveColor=ECOLOR_DARK; + opts->grooveAppearance=APPEARANCE_INVERTED; + opts->sunkenAppearance=APPEARANCE_SOFT_GRADIENT; + opts->sbarBgndAppearance=APPEARANCE_FLAT; + opts->tooltipAppearance=APPEARANCE_GRADIENT; + opts->sliderFill=APPEARANCE_GRADIENT; + opts->defBtnIndicator=IND_GLOW; + opts->sliderThumbs=LINE_FLAT; + opts->handles=LINE_1DOT; + opts->shadeSliders=SHADE_NONE; + opts->shadeMenubars=SHADE_NONE; + opts->shadeCheckRadio=SHADE_NONE; + opts->sortedLv=SHADE_NONE; + opts->toolbarBorders=TB_NONE; + opts->toolbarSeparators=LINE_SUNKEN; + opts->splitters=LINE_1DOT; +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + opts->fixParentlessDialogs=false; +#ifdef __cplusplus + opts->noDlgFixApps << "kate" << "plasma" << "plasma-desktop" << "plasma-netbook"; +#else + opts->noDlgFixApps=NULL; +#endif +#endif + opts->customMenuTextColor=false; + opts->coloredMouseOver=MO_GLOW; + opts->menubarMouseOver=true; + opts->useHighlightForMenu=false; + opts->shadeMenubarOnlyWhenActive=false; + opts->thin=THIN_BUTTONS; + opts->tbarBtns=TBTN_STANDARD; + opts->scrollbarType=SCROLLBAR_KDE; + opts->buttonEffect=EFFECT_SHADOW; + opts->focus=FOCUS_GLOW; + opts->lvButton=false; + opts->lvLines=false; /*LV_NONE;*/ + opts->drawStatusBarFrames=false; + opts->fillSlider=true; + opts->roundMbTopOnly=true; + opts->borderMenuitems=false; + opts->darkerBorders=false; + opts->vArrows=true; + opts->xCheck=false; + opts->colorMenubarMouseOver=true; + opts->crButton=true; + opts->crColor=SHADE_NONE; + opts->progressColor=SHADE_SELECTED; + opts->smallRadio=true; + opts->fillProgress=true; + opts->comboSplitter=false; + opts->highlightScrollViews=false; + opts->etchEntry=false; + opts->flatSbarButtons=true; + opts->borderSbarGroove=true; + opts->borderProgress=true; + opts->popupBorder=true; + opts->unifySpinBtns=false; + opts->unifySpin=true; + opts->unifyCombo=true; + opts->borderTab=true; + opts->borderInactiveTab=false; + opts->thinSbarGroove=true; + opts->colorSliderMouseOver=false; + opts->menuIcons=true; + opts->forceAlternateLvCols=false; + opts->invertBotTab=true; + opts->menubarHiding=HIDE_NONE; + opts->statusbarHiding=HIDE_NONE; + opts->boldProgress=true; + opts->coloredTbarMo=false; + opts->borderSelection=false; + opts->square=SQUARE_POPUP_MENUS|SQUARE_TOOLTIPS; + opts->stripedSbar=false; + opts->windowDrag=WM_DRAG_NONE; + opts->shadePopupMenu=false; + opts->hideShortcutUnderline=false; + opts->windowBorder=WINDOW_BORDER_ADD_LIGHT_BORDER|WINDOW_BORDER_FILL_TITLEBAR; + opts->groupBox=FRAME_FADED; + opts->gbFactor=DEF_GB_FACTOR; + opts->gbLabel=GB_LBL_BOLD|GB_LBL_OUTSIDE; +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + opts->stdBtnSizes=false; + opts->titlebarButtons=TITLEBAR_BUTTON_ROUND|TITLEBAR_BUTTON_HOVER_SYMBOL; + opts->titlebarIcon=TITLEBAR_ICON_NEXT_TO_TITLE; +#endif + opts->menuStripe=SHADE_NONE; + opts->menuStripeAppearance=APPEARANCE_DARK_INVERTED; + opts->shading=SHADING_HSL; + opts->gtkScrollViews=true; + opts->comboBtn=SHADE_NONE; + opts->doubleGtkComboArrow=true; + opts->stdSidebarButtons=false; + opts->toolbarTabs=false; + opts->bgndOpacity=opts->dlgOpacity=opts->menuBgndOpacity=100; + opts->gtkComboMenus=false; +#ifdef __cplusplus + opts->customMenubarsColor.setRgb(0, 0, 0); + opts->customSlidersColor.setRgb(0, 0, 0); + opts->customMenuNormTextColor.setRgb(0, 0, 0); + opts->customMenuSelTextColor.setRgb(0, 0, 0); + opts->customCheckRadioColor.setRgb(0, 0, 0); + opts->customComboBtnColor.setRgb(0, 0, 0); + opts->customMenuStripeColor.setRgb(0, 0, 0); + opts->customProgressColor.setRgb(0, 0, 0); + opts->titlebarAlignment=ALIGN_FULL_CENTER; + opts->titlebarEffect=EFFECT_SHADOW; + opts->centerTabText=false; +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + opts->xbar=false; + opts->dwtSettings=DWT_BUTTONS_AS_PER_TITLEBAR|DWT_ROUND_TOP_ONLY; + opts->menubarApps << "amarok" << "arora" << "kaffeine" << "kcalc" << "smplayer" << "VirtualBox"; + opts->statusbarApps << "kde"; + opts->useQtFileDialogApps << "googleearth-bin"; + opts->noMenuBgndOpacityApps << "inkscape" << "sonata" << "totem" << "vmware" << "vmplayer" << "gtk"; + opts->noBgndOpacityApps << "smplayer" << "kaffeine" << "dragon" << "kscreenlocker" << "inkscape" << "sonata" << "totem" << "vmware" << "vmplayer"; +#endif + opts->noMenuStripeApps << "gtk" << "soffice.bin"; +#else + opts->noBgndGradientApps=NULL; + opts->noBgndOpacityApps=g_strsplit("inkscape,sonata,totem,vmware,vmplayer",",", -1);; + opts->noBgndImageApps=NULL; + opts->noMenuStripeApps=g_strsplit("gtk",",", -1); + opts->noMenuBgndOpacityApps=g_strsplit("inkscape,sonata,totem,vmware,vmplayer,gtk",",", -1); +/* + opts->setDialogButtonOrder=false; +*/ + opts->customMenubarsColor.red=opts->customMenubarsColor.green=opts->customMenubarsColor.blue=0; + opts->customSlidersColor.red=opts->customSlidersColor.green=opts->customSlidersColor.blue=0; + opts->customMenuNormTextColor.red=opts->customMenuNormTextColor.green=opts->customMenuNormTextColor.blue=0; + opts->customMenuSelTextColor.red=opts->customMenuSelTextColor.green=opts->customMenuSelTextColor.blue=0; + opts->customCheckRadioColor.red=opts->customCheckRadioColor.green=opts->customCheckRadioColor.blue=0; + opts->customComboBtnColor.red=opts->customCheckRadioColor.green=opts->customCheckRadioColor.blue=0; + opts->customMenuStripeColor.red=opts->customMenuStripeColor.green=opts->customMenuStripeColor.blue=0; + opts->customProgressColor.red=opts->customProgressColor.green=opts->customProgressColor.blue=0; +#endif + +#if !defined __cplusplus || defined CONFIG_DIALOG + opts->mapKdeIcons=true; + opts->expanderHighlight=DEFAULT_EXPANDER_HIGHLIGHT_FACTOR; +#endif + opts->titlebarAppearance=APPEARANCE_CUSTOM1; + opts->inactiveTitlebarAppearance=APPEARANCE_CUSTOM1; +#ifdef __cplusplus + opts->titlebarButtonAppearance=APPEARANCE_GRADIENT; +#endif + /* Read system config file... */ + { + static const char * systemFilename=NULL; + + if(!systemFilename) + systemFilename=getSystemConfigFile(); + + if(systemFilename) + qtcReadConfig(systemFilename, opts, opts); + } + +#if !defined CONFIG_DIALOG && defined QT_VERSION && (QT_VERSION < 0x040000) + if(FOCUS_FILLED==opts->focus) + opts->focus=FOCUS_FULL; +#endif +} + +#ifdef CONFIG_WRITE +#include +#include + +static const char *toStr(EDefBtnIndicator ind) +{ + switch(ind) + { + case IND_NONE: + return "none"; + case IND_FONT_COLOR: + return "fontcolor"; + case IND_CORNER: + return "corner"; + case IND_TINT: + return "tint"; + case IND_GLOW: + return "glow"; + case IND_DARKEN: + return "darken"; + case IND_SELECTED: + return "origselected"; + default: + return "colored"; + } +} + +static const char *toStr(ELine ind, bool dashes) +{ + switch(ind) + { + case LINE_1DOT: + return "1dot"; + case LINE_DOTS: + return "dots"; + case LINE_DASHES: + return dashes ? "dashes" : "none"; + case LINE_NONE: + return "none"; + case LINE_FLAT: + return "flat"; + default: + return "sunken"; + } +} + +static const char *toStr(ETBarBorder ind) +{ + switch(ind) + { + case TB_DARK: + return "dark"; + case TB_DARK_ALL: + return "dark-all"; + case TB_LIGHT_ALL: + return "light-all"; + case TB_NONE: + return "none"; + default: + return "light"; + } +} + +static const char *toStr(EMouseOver mo) +{ + switch(mo) + { + case MO_COLORED: + return "colored"; + case MO_COLORED_THICK: + return "thickcolored"; + case MO_NONE: + return "none"; + case MO_GLOW: + return "glow"; + default: + return "plastik"; + } +} + +static QString toStr(EAppearance exp, EAppAllow allow, const QtCPixmap *pix) +{ + switch(exp) + { + case APPEARANCE_FLAT: + return "flat"; + case APPEARANCE_RAISED: + return "raised"; + case APPEARANCE_DULL_GLASS: + return "dullglass"; + case APPEARANCE_SHINY_GLASS: + return "shinyglass"; + case APPEARANCE_AGUA: + return "agua"; + case APPEARANCE_SOFT_GRADIENT: + return "soft"; + case APPEARANCE_GRADIENT: + return "gradient"; + case APPEARANCE_HARSH_GRADIENT: + return "harsh"; + case APPEARANCE_INVERTED: + return "inverted"; + case APPEARANCE_DARK_INVERTED: + return "darkinverted"; + case APPEARANCE_SPLIT_GRADIENT: + return "splitgradient"; + case APPEARANCE_BEVELLED: + return "bevelled"; + case APPEARANCE_FILE: + // When savng, strip users config dir from location. + return QLatin1String("file:")+ + (pix->file.startsWith(qtcConfDir()) + ? pix->file.mid(strlen(qtcConfDir())+1) + : pix->file); + case APPEARANCE_FADE: + switch(allow) + { + case APP_ALLOW_BASIC: // Should not get here! + case APP_ALLOW_FADE: + return "fade"; + case APP_ALLOW_STRIPED: + return "striped"; + case APP_ALLOW_NONE: + return "none"; + } + default: + { + QString app; + + app.sprintf("customgradient%d", (exp-APPEARANCE_CUSTOM1)+1); + return app; + } + } +} + +static QString toStr(const QColor &col) +{ + QString colorStr; + + colorStr.sprintf("#%02X%02X%02X", col.red(), col.green(), col.blue()); + return colorStr; +} + +static QString toStr(EShade exp, const QColor &col) +{ + switch(exp) + { + default: + case SHADE_NONE: + return "none"; + case SHADE_BLEND_SELECTED: + return "selected"; + case SHADE_CUSTOM: + return toStr(col); + case SHADE_SELECTED: + return "origselected"; + case SHADE_DARKEN: + return "darken"; + case SHADE_WINDOW_BORDER: + return "wborder"; + } +} + +static const char *toStr(ERound exp) +{ + switch(exp) + { + case ROUND_NONE: + return "none"; + case ROUND_SLIGHT: + return "slight"; + case ROUND_EXTRA: + return "extra"; + case ROUND_MAX: + return "max"; + default: + case ROUND_FULL: + return "full"; + } +} + +static const char *toStr(EScrollbar sb) +{ + switch(sb) + { + case SCROLLBAR_KDE: + return "kde"; + default: + case SCROLLBAR_WINDOWS: + return "windows"; + case SCROLLBAR_PLATINUM: + return "platinum"; + case SCROLLBAR_NEXT: + return "next"; + case SCROLLBAR_NONE: + return "none"; + } +} + +static const char *toStr(EFrame sb) +{ + switch(sb) + { + case FRAME_NONE: + return "none"; + case FRAME_PLAIN: + return "plain"; + case FRAME_LINE: + return "line"; + case FRAME_SHADED: + return "shaded"; + case FRAME_FADED: + default: + return "faded"; + } +} + +static const char *toStr(EEffect e) +{ + switch(e) + { + case EFFECT_NONE: + return "none"; + default: + case EFFECT_SHADOW: + return "shadow"; + case EFFECT_ETCH: + return "etch"; + } +} + +inline const char * toStr(bool b) { return b ? "true" : "false"; } + +static const char *toStr(EShading s) +{ + switch(s) + { + case SHADING_SIMPLE: + return "simple"; + default: + case SHADING_HSL: + return "hsl"; + case SHADING_HSV: + return "hsv"; + case SHADING_HCY: + return "hcy"; + } +} + +static const char *toStr(EStripe s) +{ + switch(s) + { + default: + case STRIPE_PLAIN: + return "plain"; + case STRIPE_NONE: + return "none"; + case STRIPE_DIAGONAL: + return "diagonal"; + case STRIPE_FADE: + return "fade"; + } +} + +static const char *toStr(ESliderStyle s) +{ + switch(s) + { + case SLIDER_PLAIN: + return "plain"; + case SLIDER_TRIANGULAR: + return "triangular"; + case SLIDER_ROUND_ROTATED: + return "r-round"; + case SLIDER_PLAIN_ROTATED: + return "r-plain"; + case SLIDER_CIRCULAR: + return "circular"; + default: + case SLIDER_ROUND: + return "round"; + } +} + +static const char *toStr(EColor s) +{ + switch(s) + { + case ECOLOR_BACKGROUND: + return "background"; + case ECOLOR_DARK: + return "dark"; + default: + case ECOLOR_BASE: + return "base"; + } +} + +static const char *toStr(EFocus f) +{ + switch(f) + { + default: + case FOCUS_STANDARD: + return "standard"; + case FOCUS_RECTANGLE: + return "rect"; + case FOCUS_FILLED: + return "filled"; + case FOCUS_FULL: + return "full"; + case FOCUS_LINE: + return "line"; + case FOCUS_GLOW: + return "glow"; + } +} + +static const char *toStr(ETabMo f) +{ + switch(f) + { + default: + case TAB_MO_BOTTOM: + return "bot"; + case TAB_MO_TOP: + return "top"; + case TAB_MO_GLOW: + return "glow"; + } +} + +static const char *toStr(EGradientBorder g) +{ + switch(g) + { + case GB_NONE: + return "none"; + case GB_LIGHT: + return "light"; + case GB_3D_FULL: + return "3dfull"; + case GB_SHINE: + return "shine"; + default: + case GB_3D: + return "3d"; + } +} + +static const char *toStr(EAlign ind) +{ + switch(ind) + { + default: + case ALIGN_LEFT: + return "left"; + case ALIGN_CENTER: + return "center"; + case ALIGN_FULL_CENTER: + return "center-full"; + case ALIGN_RIGHT: + return "right"; + } +} + +static const char * toStr(ETitleBarIcon icn) +{ + switch(icn) + { + case TITLEBAR_ICON_NONE: + return "none"; + default: + case TITLEBAR_ICON_MENU_BUTTON: + return "menu"; + case TITLEBAR_ICON_NEXT_TO_TITLE: + return "title"; + } +} + +static const char * toStr(EGradType gt) +{ + switch(gt) + { + case GT_VERT: + return "vert"; + default: + case GT_HORIZ: + return "horiz"; + } +} + +#if 0 +static const char * toStr(ELvLines lv) +{ + switch(lv) + { + case LV_NEW: + return "new"; + case LV_OLD: + return "old"; + default: + case LV_NONE: + return "none"; + } +} +#endif + +static const char * toStr(EImageType lv) +{ + switch(lv) + { + default: + case IMG_NONE: + return "none"; + case IMG_PLAIN_RINGS: + return "plainrings"; + case IMG_BORDERED_RINGS: + return "rings"; + case IMG_SQUARE_RINGS: + return "squarerings"; + case IMG_FILE: + return "file"; + } +} + +static const char * toStr(EGlow lv) +{ + switch(lv) + { + default: + case GLOW_NONE: + return "none"; + case GLOW_START: + return "start"; + case GLOW_MIDDLE: + return "middle"; + case GLOW_END: + return "end"; + } +} + +static const char * toStr(ETBarBtn tb) +{ + switch(tb) + { + default: + case TBTN_STANDARD: + return "standard"; + case TBTN_RAISED: + return "raised"; + case TBTN_JOINED: + return "joined"; + } +} + +#if QT_VERSION >= 0x040000 +#include +#define CFG config +#else +#define CFG (*cfg) +#endif + +#define CFG_WRITE_ENTRY(ENTRY) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY)); + +#define CFG_WRITE_APPEARANCE_ENTRY(ENTRY, ALLOW) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY, ALLOW, NULL)); + +#define CFG_WRITE_APPEARANCE_ENTRY_PIXMAP(ENTRY, ALLOW, PIXMAP) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY, ALLOW, &opts.PIXMAP)); + +#define CFG_WRITE_ENTRY_B(ENTRY, B) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY, B)); + +#define CFG_WRITE_ENTRY_NUM(ENTRY) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, opts.ENTRY); + +#define CFG_WRITE_SHADE_ENTRY(ENTRY, COL) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY, opts.COL)); + +#define CFG_WRITE_IMAGE_ENTRY(ENTRY) \ + if (!exportingStyle && def.ENTRY.type==opts.ENTRY.type) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, toStr(opts.ENTRY.type)); \ + if(IMG_FILE!=opts.ENTRY.type) \ + { \ + CFG.deleteEntry(#ENTRY ".file"); \ + CFG.deleteEntry(#ENTRY ".width"); \ + CFG.deleteEntry(#ENTRY ".height"); \ + CFG.deleteEntry(#ENTRY ".onBorder"); \ + CFG.deleteEntry(#ENTRY ".pos"); \ + } \ + else \ + { \ + CFG.writeEntry(#ENTRY ".file", opts.ENTRY.pixmap.file); \ + CFG.writeEntry(#ENTRY ".width", opts.ENTRY.width); \ + CFG.writeEntry(#ENTRY ".height", opts.ENTRY.height); \ + CFG.writeEntry(#ENTRY ".onBorder", opts.ENTRY.onBorder); \ + CFG.writeEntry(#ENTRY ".pos", (int)(opts.ENTRY.pos)); \ + } + +#define CFG_WRITE_STRING_LIST_ENTRY(ENTRY) \ + if (!exportingStyle && def.ENTRY==opts.ENTRY) \ + CFG.deleteEntry(#ENTRY); \ + else \ + CFG.writeEntry(#ENTRY, QStringList(opts.ENTRY.toList()).join(",")); \ + +bool qtcWriteConfig(KConfig *cfg, const Options &opts, const Options &def, bool exportingStyle) +{ + if(!cfg) + { + const char *cfgDir=qtcConfDir(); + + if(cfgDir) + { +#if QT_VERSION >= 0x040000 + KConfig defCfg(QFile::decodeName(cfgDir)+CONFIG_FILE, KConfig::SimpleConfig); +#else + KConfig defCfg(QFile::decodeName(cfgDir)+CONFIG_FILE, false, false); +#endif + + if(qtcWriteConfig(&defCfg, opts, def, exportingStyle)) + { + const char *oldFiles[]={ OLD_CONFIG_FILE, "qtcurve.gtk-icons", 0}; + + for(int i=0; oldFiles[i]; ++i) + { + QString oldFileName(QFile::decodeName(cfgDir)+QString("../")+oldFiles[i]); + + if(QFile::exists(oldFileName)) + QFile::remove(oldFileName); + } + } + } + } + else + { +#if QT_VERSION >= 0x040000 + KConfigGroup config(cfg, SETTINGS_GROUP); +#else + cfg->setGroup(SETTINGS_GROUP); +#endif + CFG.writeEntry(VERSION_KEY, VERSION); + CFG_WRITE_ENTRY_NUM(passwordChar) + CFG_WRITE_ENTRY_NUM(gbFactor) + CFG_WRITE_ENTRY(round) + CFG_WRITE_ENTRY_NUM(highlightFactor) + CFG_WRITE_ENTRY_NUM(menuDelay) + CFG_WRITE_ENTRY_NUM(sliderWidth) + CFG_WRITE_ENTRY(toolbarBorders) + CFG_WRITE_APPEARANCE_ENTRY(appearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(tbarBtnAppearance, APP_ALLOW_NONE) + CFG_WRITE_ENTRY(tbarBtnEffect) + CFG_WRITE_APPEARANCE_ENTRY_PIXMAP(bgndAppearance, APP_ALLOW_STRIPED, bgndPixmap) + CFG_WRITE_ENTRY(bgndGrad) + CFG_WRITE_ENTRY(menuBgndGrad) + CFG_WRITE_APPEARANCE_ENTRY_PIXMAP(menuBgndAppearance, APP_ALLOW_STRIPED, menuBgndPixmap) +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + CFG_WRITE_ENTRY(fixParentlessDialogs) +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + CFG_WRITE_STRING_LIST_ENTRY(noDlgFixApps) +#endif +#endif + CFG_WRITE_ENTRY(stripedProgress) + CFG_WRITE_ENTRY(sliderStyle) + CFG_WRITE_ENTRY(animatedProgress) + CFG_WRITE_ENTRY_NUM(lighterPopupMenuBgnd) + CFG_WRITE_ENTRY_NUM(tabBgnd) + CFG_WRITE_ENTRY(embolden) + CFG_WRITE_ENTRY(defBtnIndicator) + CFG_WRITE_ENTRY_B(sliderThumbs, false) + CFG_WRITE_ENTRY_B(handles, true) + CFG_WRITE_ENTRY(highlightTab) + CFG_WRITE_ENTRY_NUM(colorSelTab) + CFG_WRITE_ENTRY(roundAllTabs) + CFG_WRITE_ENTRY(tabMouseOver) + CFG_WRITE_APPEARANCE_ENTRY(menubarAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(menuitemAppearance, APP_ALLOW_FADE) + CFG_WRITE_APPEARANCE_ENTRY(toolbarAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(selectionAppearance, APP_ALLOW_BASIC) +#ifdef __cplusplus + CFG_WRITE_APPEARANCE_ENTRY(dwtAppearance, APP_ALLOW_BASIC) + CFG_WRITE_ENTRY(titlebarEffect) +#endif + CFG_WRITE_APPEARANCE_ENTRY(menuStripeAppearance, APP_ALLOW_BASIC) + CFG_WRITE_ENTRY_B(toolbarSeparators, false) + CFG_WRITE_ENTRY_B(splitters, true) + CFG_WRITE_ENTRY(customMenuTextColor) + CFG_WRITE_ENTRY(coloredMouseOver) + CFG_WRITE_ENTRY(menubarMouseOver) + CFG_WRITE_ENTRY(useHighlightForMenu) + CFG_WRITE_ENTRY(shadeMenubarOnlyWhenActive) + CFG_WRITE_ENTRY_NUM(thin) + CFG_WRITE_SHADE_ENTRY(shadeSliders, customSlidersColor) + CFG_WRITE_SHADE_ENTRY(shadeMenubars, customMenubarsColor) + CFG_WRITE_SHADE_ENTRY(sortedLv, customSortedLvColor) + CFG_WRITE_ENTRY(customMenuSelTextColor) + CFG_WRITE_ENTRY(customMenuNormTextColor) + CFG_WRITE_SHADE_ENTRY(shadeCheckRadio, customCheckRadioColor) + CFG_WRITE_ENTRY(scrollbarType) + CFG_WRITE_ENTRY(buttonEffect) + CFG_WRITE_APPEARANCE_ENTRY(lvAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(tabAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(activeTabAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(sliderAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(progressAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(progressGrooveAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(grooveAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(sunkenAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(sbarBgndAppearance, APP_ALLOW_BASIC) + CFG_WRITE_APPEARANCE_ENTRY(tooltipAppearance, APP_ALLOW_BASIC) + CFG_WRITE_ENTRY(sliderFill) + CFG_WRITE_ENTRY(progressGrooveColor) + CFG_WRITE_ENTRY(focus) + CFG_WRITE_ENTRY(lvButton) + CFG_WRITE_ENTRY(lvLines) + CFG_WRITE_ENTRY(drawStatusBarFrames) + CFG_WRITE_ENTRY(fillSlider) + CFG_WRITE_ENTRY(roundMbTopOnly) + CFG_WRITE_ENTRY(borderMenuitems) + CFG_WRITE_ENTRY(darkerBorders) + CFG_WRITE_ENTRY(vArrows) + CFG_WRITE_ENTRY(xCheck) + CFG_WRITE_ENTRY(groupBox) + CFG_WRITE_ENTRY_NUM(gbLabel) + CFG_WRITE_ENTRY(fadeLines) + CFG_WRITE_ENTRY(glowProgress) + CFG_WRITE_IMAGE_ENTRY(bgndImage) + CFG_WRITE_IMAGE_ENTRY(menuBgndImage) + CFG_WRITE_ENTRY(colorMenubarMouseOver) + CFG_WRITE_ENTRY_NUM(crHighlight) + CFG_WRITE_ENTRY(crButton) + CFG_WRITE_SHADE_ENTRY(crColor, customCrBgndColor) + CFG_WRITE_SHADE_ENTRY(progressColor, customProgressColor) + CFG_WRITE_ENTRY(smallRadio) + CFG_WRITE_ENTRY(fillProgress) + CFG_WRITE_ENTRY(comboSplitter) + CFG_WRITE_ENTRY(highlightScrollViews) + CFG_WRITE_ENTRY(etchEntry) + CFG_WRITE_ENTRY_NUM(splitterHighlight) + CFG_WRITE_ENTRY_NUM(expanderHighlight) + CFG_WRITE_ENTRY_NUM(crSize) + CFG_WRITE_ENTRY(flatSbarButtons) + CFG_WRITE_ENTRY(borderSbarGroove) + CFG_WRITE_ENTRY(borderProgress) + CFG_WRITE_ENTRY(popupBorder) + CFG_WRITE_ENTRY(unifySpinBtns) + CFG_WRITE_ENTRY(unifySpin) + CFG_WRITE_ENTRY(unifyCombo) + CFG_WRITE_ENTRY(borderTab) + CFG_WRITE_ENTRY(borderInactiveTab) + CFG_WRITE_ENTRY(thinSbarGroove) + CFG_WRITE_ENTRY(colorSliderMouseOver) + CFG_WRITE_ENTRY(menuIcons) + CFG_WRITE_ENTRY(forceAlternateLvCols) + CFG_WRITE_ENTRY_NUM(square) + CFG_WRITE_ENTRY(invertBotTab) + CFG_WRITE_ENTRY_NUM(menubarHiding) + CFG_WRITE_ENTRY_NUM(statusbarHiding) + CFG_WRITE_ENTRY(boldProgress) + CFG_WRITE_ENTRY(coloredTbarMo) + CFG_WRITE_ENTRY(borderSelection) + CFG_WRITE_ENTRY(stripedSbar) + CFG_WRITE_ENTRY_NUM(windowDrag) + CFG_WRITE_ENTRY(shadePopupMenu) + CFG_WRITE_ENTRY(hideShortcutUnderline) + CFG_WRITE_ENTRY_NUM(windowBorder) + CFG_WRITE_ENTRY(tbarBtns) +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + CFG_WRITE_ENTRY(xbar) + CFG_WRITE_ENTRY_NUM(dwtSettings) +#endif + CFG_WRITE_ENTRY_NUM(bgndOpacity) + CFG_WRITE_ENTRY_NUM(menuBgndOpacity) + CFG_WRITE_ENTRY_NUM(dlgOpacity) +#if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) + CFG_WRITE_ENTRY(stdBtnSizes) + CFG_WRITE_ENTRY_NUM(titlebarButtons) + CFG_WRITE_ENTRY(titlebarIcon) + + if((opts.titlebarButtons&TITLEBAR_BUTTON_COLOR || opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR) && + opts.titlebarButtonColors.size() && 0==(opts.titlebarButtonColors.size()%NUM_TITLEBAR_BUTTONS)) + { + QString val; +#if QT_VERSION >= 0x040000 + QTextStream str(&val); +#else + QTextStream str(&val, IO_WriteOnly); +#endif + for(unsigned int i=0; i= 0x040000)) + CFG_WRITE_ENTRY(reorderGtkButtons) +#endif + CFG_WRITE_ENTRY(mapKdeIcons) + CFG_WRITE_ENTRY(shading) + CFG_WRITE_ENTRY(titlebarAlignment) + CFG_WRITE_ENTRY(centerTabText) +#if defined QT_VERSION && (QT_VERSION >= 0x040000) + CFG_WRITE_STRING_LIST_ENTRY(noBgndGradientApps) + CFG_WRITE_STRING_LIST_ENTRY(noBgndOpacityApps) + CFG_WRITE_STRING_LIST_ENTRY(noMenuBgndOpacityApps) + CFG_WRITE_STRING_LIST_ENTRY(noBgndImageApps) + CFG_WRITE_STRING_LIST_ENTRY(noMenuStripeApps) + CFG_WRITE_STRING_LIST_ENTRY(menubarApps) + CFG_WRITE_STRING_LIST_ENTRY(statusbarApps) + CFG_WRITE_STRING_LIST_ENTRY(useQtFileDialogApps) +#endif + + for(int i=APPEARANCE_CUSTOM1; i<(APPEARANCE_CUSTOM1+NUM_CUSTOM_GRAD); ++i) + { + GradientCont::const_iterator cg(opts.customGradient.find((EAppearance)i)); + QString gradKey; + + gradKey.sprintf("customgradient%d", (i-APPEARANCE_CUSTOM1)+1); + + if(cg==opts.customGradient.end()) + CFG.deleteEntry(gradKey); + else + { + GradientCont::const_iterator d; + + if(exportingStyle || (d=def.customGradient.find((EAppearance)i))==def.customGradient.end() || !((*d)==(*cg))) + { + QString gradVal; +#if QT_VERSION >= 0x040000 + QTextStream str(&gradVal); +#else + QTextStream str(&gradVal, IO_WriteOnly); +#endif + GradientStopCont stops((*cg).second.stops.fix()); + GradientStopCont::const_iterator it(stops.begin()), + end(stops.end()); + bool haveAlpha(false); + + for(; it!=end && !haveAlpha; ++it) + if((*it).alpha<1.0) + haveAlpha=true; + + str << toStr((*cg).second.border); + if(haveAlpha) + str << "-alpha"; + + for(it=stops.begin(); it!=end; ++it) + if(haveAlpha) + str << ',' << (*it).pos << ',' << (*it).val << ',' << (*it).alpha; + else + str << ',' << (*it).pos << ',' << (*it).val; + CFG.writeEntry(gradKey, gradVal); + } + else + CFG.deleteEntry(gradKey); + } + } + + if(opts.customShades[0]==0 || + exportingStyle || + opts.customShades[0]!=def.customShades[0] || + opts.customShades[1]!=def.customShades[1] || + opts.customShades[2]!=def.customShades[2] || + opts.customShades[3]!=def.customShades[3] || + opts.customShades[4]!=def.customShades[4] || + opts.customShades[5]!=def.customShades[5]) + { + QString shadeVal; +#if QT_VERSION >= 0x040000 + QTextStream str(&shadeVal); +#else + QTextStream str(&shadeVal, IO_WriteOnly); +#endif + if(0==opts.customShades[0]) + str << 0; + else + for(int i=0; i= 0x040000 + QTextStream str(&shadeVal); +#else + QTextStream str(&shadeVal, IO_WriteOnly); +#endif + if(0==opts.customAlphas[0]) + str << 0; + else + for(int i=0; isync(); + return true; + } + return false; +} +#endif diff --git a/src/qtcurve/common/config_file.h b/src/qtcurve/common/config_file.h new file mode 100644 index 0000000000..4fba82c29f --- /dev/null +++ b/src/qtcurve/common/config_file.h @@ -0,0 +1,49 @@ +#ifndef QTC_CONFIG_FILE_H +#define QTC_CONFIG_FILE_H + +#include "common.h" + +#define MAX_CONFIG_FILENAME_LEN 1024 +#define MAX_CONFIG_INPUT_LINE_LEN 256 + +#if !defined QT_VERSION || QT_VERSION >= 0x040000 + +#define QTC_MENU_FILE_PREFIX "menubar-" +#define QTC_STATUS_FILE_PREFIX "statusbar-" + +#define qtcMenuBarHidden(A) qtcBarHidden((A), QTC_MENU_FILE_PREFIX) +#define qtcSetMenuBarHidden(A, H) qtcSetBarHidden((A), (H), QTC_MENU_FILE_PREFIX) +#define qtcStatusBarHidden(A) qtcBarHidden((A), QTC_STATUS_FILE_PREFIX) +#define qtcSetStatusBarHidden(A, H) qtcSetBarHidden((A), (H), QTC_STATUS_FILE_PREFIX) + +#ifdef __cplusplus +extern bool qtcBarHidden(const QString &app, const char *prefix); +extern void qtcSetBarHidden(const QString &app, bool hidden, const char *prefix); +#else // __cplusplus +extern gboolean qtcBarHidden(const char *app, const char *prefix); +extern void qtcSetBarHidden(const char *app, bool hidden, const char *prefix); +#endif // __cplusplus + +extern void qtcLoadBgndImage(QtCImage *img); + +#endif // !defined QT_VERSION || QT_VERSION >= 0x040000) + +extern const char * qtcGetHome(); +extern const char *qtcConfDir(); +extern void qtcSetRgb(color *col, const char *str); +extern void qtcDefaultSettings(Options *opts); +extern void qtcCheckConfig(Options *opts); +#ifdef __cplusplus +extern bool qtcReadConfig(const QString &file, Options *opts, Options *defOpts=0L, bool checkImages=true); +extern WindowBorders qtcGetWindowBorderSize(bool force=false); +#else +extern bool qtcReadConfig(const char *file, Options *opts, Options *defOpts); +extern WindowBorders qtcGetWindowBorderSize(gboolean force); +#endif + +#ifdef CONFIG_WRITE +class KConfig; +extern bool qtcWriteConfig(KConfig *cfg, const Options &opts, const Options &def, bool exportingStyle=false); +#endif + +#endif diff --git a/src/qtcurve/common/dot.png b/src/qtcurve/common/dot.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ba6645e1d5f7f9224ef02591bb94f733e6f0fb GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$60wmSb-sJ%)#^NA%Cx&(BWL^R}OiAAEE)4(M z`_JqL^7K4i978y+C#O6}>PQYq`ElH!zfrN-v9}Qj7WOqRoX*HKL*k#&fkrK7;}%AS Y?NeCOBPQM90qSJ%boFyt=akR{0F%KdhX4Qo literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/radio_frame.png b/src/qtcurve/common/radio_frame.png new file mode 100644 index 0000000000000000000000000000000000000000..1faf08200b81df1e90289129082c177e3616d5c2 GIT binary patch literal 419 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4u6ByT*@`Od(=nC0o>7$PCb7|*!iA5atwL>WpL zt}^@w;t~c?h!7K)ie|XOpvX|lV9Zd=puljKAsQmd0AyTZuz+!ZvdP2L>x7 z2@ul^C??9xkj3znVFsGiQwDhkIR>D`Ah)6ef1o(fRd(p&K)xlze^}_8Eztb`U}H+hG3x4{tR;&z9J+* Z8nA_-fLd`wz0w5O||%Q~loCIILaHKG6j literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/radio_inner.png b/src/qtcurve/common/radio_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..94201cd88f136829fa74bc7f0a0706c999b4f9d3 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4u6ByT*@`3|HQi-X*q7}lMWc?sk&C3(BMFfgp@ zRW<_hI14-?iy0WWg+Z8+Vb&Z8pdfpRr>`sf4IVBY1HP34x5a@%Gdx`!LnJP@_84*< zau9HpPntSgLM;0u$Fi?1W>JxOiL<#`&M@i}@nqXJwkoi28@fugHkdU=@Jvc|_;XeI z-XH#Y<0Hx?drovXJ=9ov(;)R^EBoesft&c{it~)fLRGPDdukD%c!)Qmt~wa`Pd>=N%jP)RT&|qFNT^|2f0{{)L)ezUHQQ Qpc@%HUHx3vIVCg!06(`}c>n+a literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/radio_light.png b/src/qtcurve/common/radio_light.png new file mode 100644 index 0000000000000000000000000000000000000000..4f102cfb87805282c81b7adf7b581b73f3d05540 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4u6ByT*@`3|I*lDyqr82-2SpV<%OaTa()7Bet# z3xhBt!>lCZ`@vs*6P|yt{Ufk8xR6aQncLfc`j*mdAxqa@yPG@V_`8QS d3s~wuG4fOkz5bQs{T%2J22WQ%mvv4FO#r@8SONe5 literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/radio_on.png b/src/qtcurve/common/radio_on.png new file mode 100644 index 0000000000000000000000000000000000000000..7584dbf5a06ff3c9003bed35eb9b4470a0c9cc48 GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uAB#T}@sR2@q#X;^)4C~IxyaaOClDyqr82*Fc zg1yTp14TFsJR*x37`TN&n2}-D90{Nxdx@v7EBj3rK`vb`%@yuZK%rPq7sn8d^H(oy zQMKE>|X{q|Hq%$y1ds^H`rbqj!3N z;je|NYbGo_#&>rAq!uCekQ>M6?DL%*meI>p9%Fb|NL|K$S)ulp1Kj-&q&{1OhQAQH wWnyty_t4zua~E6oujSo#-`U#C)tDtWKD#XI4|ENKr>mdKI;Vst03!HW_5c6? literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow.png b/src/qtcurve/common/shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3d66aad124cc9cee4c25a2f58ff68cb3dbbcde GIT binary patch literal 1856 zcmeHH`#aMM9R9kDxvk7BS!Ytl%%#$FsHI%SHeq4txHJ;dGh_bo$b0icIu(@ z4bX-dBV!ZOUAy;~?Zuk^Zeh6}chJh()(&s)Kp;7jkGi_KQ#?GqynX$s{y`z9LTO?2 z@QA3m^YICZNf(nZUCGGI%FfNZmS0d-Syf$A+rVn$bo4&&A1W`(`vd^;T%w(|d&t}Q zBH@{x_{}N&Dr8PRtCiQ(?;Yv_?$3a5JfW98%^L`&*&V^n^QA<7^ z>|~j3!kl(tR^MZau?;;N4(139l1$WIi=U08ep;a#KQHoA>>WZl zAI0=FM#~2)h_4Je`a8h-bV9q0x*BtPdP=G?dz0JE9JlcKQ`?CtOMFha!IYY|bO5ELTqrP9p~`edzQ?T}C$@Vs)Q8xvj3wDzlSUV1V{48E?xPT1ZpPY0r5(H?)K^hD0hHdcaEeh3GO z_q$(-OG{&ZQGGrU&>s}B@3iJfi0v~k(8R*$g)?+|YzX5gMBsqa$g%`%x|PMone5#V z5R@lc{U{Os?D9Q)evRdE7owc*d-1EeS%zvtRy2SakThV5Z7odJWZD%ufid-yt$$V75Hie(XwSB9 zD@@Tui)WOUKJ2l&pM4pU)~9uly*>G)^qB4u7%C@EP3Kndr9NAlYi1pB*iS|Qe1@ck zj)S_=0$%C8;BrKvc(TNgF$OFVY)Dn7v|UU!A8{z-s;;mec7eq+KhbIC(=8_JqwZxhKjpciP8s^Jd>R*D`M?tq3mB@Y~h zb?W&bM^7PtH7tCjVr62|W8_L|{%ne1Oe|V|H$Hpx-1ULLW{>aR-?{;Iu~~S|JdzCJ zCV0^>H~G}J;jy*D1aHp3sO)ZPm_}rO=tM=yNDQ29eJ6t|jh(Cz;xJv^uIT0Poe^@I*6xF1uusx9L!7WsR9s1vCwgPWY245R3da|>q2%Pba}PY2Ak^G3@o@i(C=ImTCW z9D-Iy<2%nTETIaV{{Vl6Fq8lQ literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow0.png b/src/qtcurve/common/shadow0.png new file mode 100644 index 0000000000000000000000000000000000000000..130ba881a7a03bb295b99c614b0173f4e942d345 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL3?z5Yp7kC`F&8^|hH!9j+sNvT!AzY)YsRChKAbP+Z!7jYiVhDc&J!dSlHWZnVFf{*w|QF zT3T5d+Sr&_TAEmynVFlLG8kR^4Adr6666=mz{teR!pg?Z$-^foCZ%NPmU`H7as^P< z%+tj&#N&8!f&}a01d*PmKnLanCp@N^skJ>^-P>AtC7)SJ#re>-hcc6#ouw}ue7ikg dF`$%z;od>ULI6*3#1Q@K6D=Ei5d6Ts=KKpoqP_ zmX(#2nVFf3v9XJbF;LdV#s;Xs)YR0*#=z3j(%jq}$OfvnH8uu{167)sm;kw!mWH-w zW;Qk^KtU@j6H7~Dpp?0}p_P@Xr6pL<)D)=K%G4BSyrm_W4N?G91~dnx-pbs>(##C# z7NDs>ODut0b5jN}$$3C`+m;0R1v4-*F|)9;v2$>8ar5x-^6~Qv2nq>{iit}|N=nPf z%E>D#sid0xmXzC`r z8|U0q6uqyPF0)oMT=_IcYC7+_USD;AD$6T{9WE=>7Ze1ECCad!XqRg}RC;b{rjWaZ zLvTdlRpZ$=lO~?MB+-7za_QtVvH9kwbEdf{&T^Q(`;iZ4b=98RYxO%1a~Or&Zk}6P zzwd2+_)X25pKs3BI5*||-2H!Q-sDgFJXwPMXMMoz&2jtZy*C$6KUw%<^Lgo&8{d5Y ln^a kFSW@hQ;cT%s7>A*eUnWz*THl87N7wPp00i_>zopr01Hh*Hvj+t literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow3.png b/src/qtcurve/common/shadow3.png new file mode 100644 index 0000000000000000000000000000000000000000..9166dffec7392de2a331c6d68755b56921b2702b GIT binary patch literal 825 zcmV-91IGM`P)IIoL^EYXMP)xfUOYWYI5{^pH77qa7(6`x zIXV9~H}f?$=`%CnJu~1sI@dNf(KIy5Gc&_EF}*oCy*D?vJvO;KJgho8r#LvOJT;*@ zI-EB*l{Yt=Ha3?zG>|tpiaR@pIy!_oIf6Ggf;c#OH#c}UH+?oXdOJ6AIXQ1PH)}UH zZ#p(@IXP@NIB7aIX*f7$H#cB8HDNh9VL3TmH#c25IbAq7TQ@gWIX6@{H&8e@P&zkI zIyg@_I8He>N;fx4IyXp)BCx{%002>RQchC<0RjUA1qKHQ2?`4g3=Iws4-gR&6BHE| z7Z@2C8XO%SA0HqgA|oUwCn+f^EG{oFF*7zdH#j^#KtMr4L`FzTOiWNxRaRJGWoT(_ zaddZkeB10s0004iNklUUha7ZO0`X60#42a&^R>gArJ!Z<@YZ>8EreT+44PMZr_JGRj`Iw#rj zfV#@oPzO9aIM1ysp1GC#_n#?bsnmJAasZhATUoo%2nRNly_LL8wsBIH)RC-ovP5g7 z;HnC$;nMj5EWw)6AvRTLnN5c+sj3>OrLElOG{fLBNG!78ygcVD-&yLpu8DSk-52vg@vh=xv|`8!!n?`vL!)& z!3>N{%q*;I>>QljJiL7T0z#rtBDC^i{JRTMP|**iLeEHC%ilH%suq84v&56st-5Zq1NvTYvw=6*De3#gTe~DWM4fF@sGZ literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow5.png b/src/qtcurve/common/shadow5.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c9498e87293aa1f9ad4ae4ffe7326dd5d5af56 GIT binary patch literal 807 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL3?z5Yp7kC`F&8^|hH!9j+LI6*3#1Q@K6D=Ei5d6Ts=KKpoqP_ zmX(#2nVFf3v9XJbF;LdV#s;Xs)YKHH$HvCM($do0+#JXSYOysowz4t=DmF1O0dg%3 z4J|DV&CT^~&CG0UOsuSoff{X0O|7g<%*}z~=0KH}CLp%8wV9Qbsih^5Z4R{D+#HBN zvexFtmX@XvF3=H{mSz?fCO`(zexRVGDNqX#0Tr8orGSDamgYc1Oo0ll%uTHN{%q*;I>>Qk2+&nzIeEj?Zf&o% zs0BUBn2-?XdsuVnMz%A)3LFRSojhyuy0A-xbK8l%ng?^|{OrrEel=~~w;r_|g}}68 zwcD4EzRr-oahR*rTIU5zq>}DbLx=MV%&x8roECLOfRo*Ak&9=qK~7FGx8=RKZ*pa< z&*oZB%_-2}lwvdB-D|k>;m^pn?N`K#Ea%r`TrshZco=bdXXngKT_C%<_`&*v-^3p) tnD?x`%eL|G)STaP2md|(zoA`rtNj=2m}_>cld3>z+0)g}Wt~$(69DwK4H^Id literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow6.png b/src/qtcurve/common/shadow6.png new file mode 100644 index 0000000000000000000000000000000000000000..78e498880fa9a8b68f727803667ffd189638f299 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL3?z5Yp7kC`F&8^|hH!9j+9= iF`DV4Hu+@Arh0MjjZ8Vm8?IddIn>kD&t;ucLK6Viokphs literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/shadow7.png b/src/qtcurve/common/shadow7.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d91c592db2e47612919be6efe834f26f63c13a GIT binary patch literal 591 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL3?z5Yp7kC`F&8^|hH!9j+LI6*3#1Q@K6D=Ei5d6Ts=KKpoqP_ zmX(#2nVFf3v9XJbF;LdV#s;Xs)YR0*#=z3j(%jq}$OfvnH8!@gG6bqLF);yhEiDag z&CG0UOn{25tV}E|je%0;=7v^Qrk0jqK~qzpUMo{mpz)TLU^YmBiMhG4r5RAf*vi}l z$N;*?gz|xX%{L;M_%mp*TzHZS~(u>_y^74{>$Hu~A0zF5Q za>S2uCFsZ{yI#nB)I4F&%*W2+vSxkvw&d&)c)@XU->1;;H*ebCE--l(IkPGwXJ2IK zLC#*^a-GA*=C`{;#jRicOwtaob#k99>cYZM70vmZdA4FBqhEP+sQK;*0!_(MvpZaL z^b%L5e4ggxp|(I}x5#1}QyszPfEzcyKRR>x?v1Y&zjfx!G{3(#=in>Bh6yowbx+Qh um;HUuA#i9@cisGj+ZM)6TQL70(Y)*K0-AbW|YuPgg?Hc4(pHV$!{;0N3 z&KjMy%`T2Px++^I*iE<>qZ)T0L{oUf2eGaur!_7?5ge8dm(H~H_C7k-+^AV6XZ*qb zpRmCpA$##TsdM;UJ+~IrAK+H2I5z$BorDH|n}=6B3;L|D7k0aT`BVF|qpxVoBK43D zeX%ulk;hh~XC$cc8k-oI6nd!GE|{6v8l{xUyP7BZi?HYKi|P-g_f9(G_oe00yu1s0 zgKiwNx_^1kiajlw_dYcKZFRky+;RN!qDkBSb1!{o-rjIQUK{8i22WQ%mvv4FO#t0f Bc%1+M literal 0 HcmV?d00001 diff --git a/src/qtcurve/common/slider_light.png b/src/qtcurve/common/slider_light.png new file mode 100644 index 0000000000000000000000000000000000000000..8c8030488927e8a4eb2799595a1038f6cadc95bd GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^q98U08<2FHq?!Pv`aE46Lo7}|y=2IBD1oQ#A$zpI z67_=Dibswfbo{_`_uu6ghI@Lt!v$nwSlHRi7wWAn5z^j2S-yqE>0V9ahvca%CSKs{ z5GhWTzw*@b+l{2o)9h}`B9hx#`6^1zT5U61!4?;BG)8#NbRn~NhWo3IYKiAuS-pPe y0@o*oc@|Ggs*dnXp5yoaqto*{{qaAnZ5c(+$~^lKdvqhvWelFKelF{r5}E+&{Z38* literal 0 HcmV?d00001 diff --git a/src/qtcurve/style/blurhelper.cpp b/src/qtcurve/style/blurhelper.cpp new file mode 100644 index 0000000000..b658d9ab6f --- /dev/null +++ b/src/qtcurve/style/blurhelper.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////////// +// oxygenblurhelper.cpp +// handle regions passed to kwin for blurring +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Loosely inspired (and largely rewritten) from BeSpin style +// Copyright (C) 2007 Thomas Luebking +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include "blurhelper.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_X11 +#include +#include +#include "fixx11h.h" +#include +#endif + +namespace QtCurve +{ + + //___________________________________________________________ + BlurHelper::BlurHelper( QObject* parent ): + QObject( parent ), + _enabled( false ) + { + + #ifdef Q_WS_X11 + + // create atom + _atom = XInternAtom( QX11Info::display(), "_KDE_NET_WM_BLUR_BEHIND_REGION", False); + + #endif + + } + + //___________________________________________________________ + void BlurHelper::registerWidget( QWidget* widget ) + { Utils::addEventFilter(widget, this); } + + //___________________________________________________________ + void BlurHelper::unregisterWidget( QWidget* widget ) + { + widget->removeEventFilter( this ); + if( isTransparent( widget ) ) clear( widget ); + } + + //___________________________________________________________ + bool BlurHelper::eventFilter( QObject* object, QEvent* event ) + { + + // do nothing if not enabled + if( !enabled() ) return false; + + switch( event->type() ) + { + + case QEvent::Hide: + { + QWidget* widget( qobject_cast( object ) ); + if( widget && isOpaque( widget ) ) + { + QWidget* window( widget->window() ); + if (window && isTransparent(window) && !_pendingWidgets.contains(window) ) + { + _pendingWidgets.insert( window, window ); + delayedUpdate(); + } + } + break; + + } + + case QEvent::Show: + case QEvent::Resize: + { + + // cast to widget and check + QWidget* widget( qobject_cast( object ) ); + if( !widget ) break; + if( isTransparent( widget ) ) + { + + _pendingWidgets.insert( widget, widget ); + delayedUpdate(); + + } else if( isOpaque( widget ) ) { + + QWidget* window( widget->window() ); + if( isTransparent( window ) ) + { + _pendingWidgets.insert( window, window ); + delayedUpdate(); + } + + } + + break; + } + + default: break; + + } + + // never eat events + return false; + + } + + //___________________________________________________________ + QRegion BlurHelper::blurRegion( QWidget* widget ) const + { + if( !widget->isVisible() ) return QRegion(); + + // get main region + QRegion region = widget->mask().isEmpty() ? widget->rect():widget->mask(); + + + // trim blur region to remove unnecessary areas + trimBlurRegion( widget, widget, region ); + return region; + + } + + //___________________________________________________________ + void BlurHelper::trimBlurRegion( QWidget* parent, QWidget* widget, QRegion& region ) const + { + + + // loop over children + foreach( QObject* childObject, widget->children() ) + { + QWidget* child( qobject_cast( childObject ) ); + if( !(child && child->isVisible()) ) continue; + + if( isOpaque( child ) ) + { + + const QPoint offset( child->mapTo( parent, QPoint( 0, 0 ) ) ); + if( child->mask().isEmpty() ) region -= child->rect().translated( offset ); + else region -= child->mask().translated( offset ); + + } else { trimBlurRegion( parent, child, region ); } + + } + + return; + + } + + //___________________________________________________________ + void BlurHelper::update( QWidget* widget ) const + { + + #ifdef Q_WS_X11 + + /* + directly from bespin code. Supposibly prevent playing with some 'pseudo-widgets' + that have winId matching some other -random- window + */ + if( !(widget->testAttribute(Qt::WA_WState_Created) || widget->internalWinId() )) + { return; } + + const QRegion region( blurRegion( widget ) ); + if( region.isEmpty() ) { + + clear( widget ); + + } else { + + QVector data; + foreach( const QRect& rect, region.rects() ) + { data << rect.x() << rect.y() << rect.width() << rect.height(); } + + XChangeProperty( + QX11Info::display(), widget->winId(), _atom, XA_CARDINAL, 32, PropModeReplace, + reinterpret_cast(data.constData()), data.size() ); + + } + + // force update + if( widget->isVisible() ) + { widget->update(); } + + #endif + + } + + + //___________________________________________________________ + void BlurHelper::clear( QWidget* widget ) const + { + #ifdef Q_WS_X11 + XChangeProperty( QX11Info::display(), widget->winId(), _atom, XA_CARDINAL, 32, PropModeReplace, 0, 0 ); + #endif + + } + +} diff --git a/src/qtcurve/style/blurhelper.h b/src/qtcurve/style/blurhelper.h new file mode 100644 index 0000000000..0b90d48f6d --- /dev/null +++ b/src/qtcurve/style/blurhelper.h @@ -0,0 +1,188 @@ +#ifndef blurhelper_h +#define blurhelper_h + +////////////////////////////////////////////////////////////////////////////// +// oxygenblurhelper.h +// handle regions passed to kwin for blurring +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Loosely inspired (and largely rewritten) from BeSpin style +// Copyright (C) 2007 Thomas Luebking +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#ifdef Q_WS_X11 +#include +#endif + +namespace QtCurve +{ + class BlurHelper: public QObject + { + + Q_OBJECT + + public: + + //! constructor + BlurHelper( QObject* ); + + //! destructor + virtual ~BlurHelper( void ) + {} + + //! enable state + void setEnabled( bool value ) + { _enabled = value; } + + //! enabled + bool enabled( void ) const + { return _enabled; } + + //! register widget + void registerWidget( QWidget* ); + + //! register widget + void unregisterWidget( QWidget* ); + + //! event filter + virtual bool eventFilter( QObject*, QEvent* ); + + protected: + + //! timer event + /*! used to perform delayed blur region update of pending widgets */ + virtual void timerEvent( QTimerEvent* event ) + { + + if( event->timerId() == _timer.timerId() ) + { + _timer.stop(); + update(); + } else QObject::timerEvent( event ); + + } + + //! get list of blur-behind regions matching a given widget + QRegion blurRegion( QWidget* ) const; + + //! trim blur region to remove unnecessary areas (recursive) + void trimBlurRegion( QWidget*, QWidget*, QRegion& ) const; + + //! update blur region for all pending widgets + /*! a timer is used to allow some buffering of the update requests */ + void delayedUpdate( void ) + { + if( !_timer.isActive() ) + { _timer.start( 10, this ); } + } + + //! update blur region for all pending widgets + void update( void ) + { + + foreach( const WidgetPointer& widget, _pendingWidgets ) + { if( widget ) update( widget.data() ); } + + _pendingWidgets.clear(); + + } + + //! update blur regions for given widget + void update( QWidget* ) const; + + //! clear blur regions for given widget + void clear( QWidget* ) const; + + //! returns true if a given widget is opaque + bool isOpaque( const QWidget* widget ) const + { + + return + (!widget->isWindow()) && + ( (widget->autoFillBackground() && widget->palette().color( widget->backgroundRole() ).alpha() == 0xff ) || + widget->testAttribute(Qt::WA_OpaquePaintEvent) ); + + } + + //! true if widget is a transparent window + /*! some additional checks are performed to make sure stuff like plasma tooltips + don't get their blur region overwritten */ + inline bool isTransparent( const QWidget* widget ) const; + + private: + + //! enability + bool _enabled; + + //! list of widgets for which blur region must be updated + typedef QPointer WidgetPointer; + typedef QHash WidgetSet; + WidgetSet _pendingWidgets; + + //! delayed update timer + QBasicTimer _timer; + + #ifdef Q_WS_X11 + //! blur atom + Atom _atom; + #endif + + }; + + bool BlurHelper::isTransparent( const QWidget* widget ) const + { + return + widget->isWindow() && + widget->testAttribute( Qt::WA_TranslucentBackground ) && + + // widgets using qgraphicsview + !( widget->graphicsProxyWidget() || + widget->inherits( "Plasma::Dialog" ) ) && + + // flags and special widgets + ( widget->testAttribute( Qt::WA_StyledBackground ) || + qobject_cast( widget ) || + qobject_cast( widget ) || + qobject_cast( widget ) || + + // konsole (thought that should be handled + // internally by the application + widget->inherits( "Konsole::MainWindow" ) ) && + + Utils::hasAlphaChannel( widget ); + } +} + +#endif diff --git a/src/qtcurve/style/dialogpixmaps.h b/src/qtcurve/style/dialogpixmaps.h new file mode 100644 index 0000000000..4d530f3e06 --- /dev/null +++ b/src/qtcurve/style/dialogpixmaps.h @@ -0,0 +1,343 @@ +#ifndef __DIALOG_PIXMAPS_H__ +#define __DIALOG_PIXMAPS_H__ + +// Oxygen icons - created with Qt3's qembed... + +static const unsigned int dialog_error_png_len = 1527; +static const unsigned char dialog_error_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x08,0x06,0x00,0x00, + 0x00,0x73,0x7a,0x7a,0xf4,0x00,0x00,0x00,0x04,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0x08,0x7c,0x08,0x64,0x88,0x00,0x00,0x00,0x09,0x70,0x48,0x59, + 0x73,0x00,0x00,0x03,0x76,0x00,0x00,0x03,0x76,0x01,0x7d,0xd5,0x82,0xcc, + 0x00,0x00,0x00,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61, + 0x72,0x65,0x00,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70, + 0x65,0x2e,0x6f,0x72,0x67,0x9b,0xee,0x3c,0x1a,0x00,0x00,0x05,0x74,0x49, + 0x44,0x41,0x54,0x78,0xda,0xed,0x57,0x4d,0x68,0x54,0x57,0x14,0xfe,0xee, + 0x7b,0x93,0x99,0x24,0xa6,0x69,0x13,0x53,0x7f,0xea,0xa4,0x93,0x68,0x6d, + 0xab,0x16,0x44,0x4a,0x15,0x17,0xd2,0x85,0x60,0xf7,0x62,0x40,0xa4,0x8a, + 0x55,0x54,0x50,0xc4,0x2a,0x8a,0x28,0x62,0x15,0x17,0x8a,0x0b,0xa1,0xdd, + 0xb8,0xb0,0x5d,0xb8,0x15,0xbb,0xb1,0x1b,0x75,0x61,0xd5,0x4a,0x4d,0x2b, + 0x58,0x0b,0x41,0x29,0xa2,0x26,0xc6,0x9f,0x54,0x13,0x33,0x4e,0x26,0x99, + 0x99,0xf7,0xe6,0xdd,0xdb,0xef,0xcc,0x7d,0xc9,0x8b,0x99,0x98,0xa9,0xb4, + 0xc5,0x4d,0x2f,0x7c,0x9c,0x7b,0xef,0x7b,0xe7,0x9c,0xef,0x9d,0x7b,0xce, + 0x79,0xef,0x29,0x63,0x0c,0x5e,0xe7,0x70,0xf0,0x9a,0x47,0x6c,0xbc,0xcd, + 0x83,0x4a,0xb9,0x8d,0x21,0xb9,0x37,0x00,0x85,0x7f,0x38,0x06,0x00,0xf3, + 0x0c,0xd0,0x5f,0x19,0x13,0x60,0xcc,0x78,0xe1,0x08,0x7e,0xda,0xb5,0xab, + 0x6d,0x52,0x2a,0xf5,0x4d,0x2e,0x9d,0x9e,0xc2,0x7d,0xe5,0x56,0x55,0xc1, + 0x11,0xc4,0x62,0x8a,0xc0,0xf0,0x5a,0xb9,0x2e,0x64,0xed,0x50,0x42,0x29, + 0x80,0x36,0x74,0x10,0x40,0x17,0x8b,0x30,0x22,0x7d,0x1f,0x01,0xc1,0xb5, + 0xc0,0xc8,0xba,0x98,0xcf,0x1b,0xaf,0xaf,0xaf,0xab,0x98,0xc9,0x6c,0xfb, + 0xec,0xe4,0xc9,0x1f,0xc6,0x8d,0x40,0x4d,0x32,0xf9,0xf5,0xe4,0xd6,0xd6, + 0x69,0x0d,0x0d,0x0d,0x70,0x69,0xe8,0x5f,0x1a,0x8a,0x40,0xe0,0xba,0xea, + 0xcf,0xfb,0xf7,0x5b,0x0b,0x9e,0xf7,0x1d,0x80,0x29,0x65,0x04,0x24,0xec, + 0x1f,0x6f,0xd8,0x30,0xa5,0x65,0xce,0x1c,0xe4,0x3b,0x3a,0xf0,0x5f,0x8c, + 0x86,0x96,0x16,0xfc,0x7e,0xe1,0x42,0xe3,0xf7,0xf4,0x15,0x1e,0x47,0x44, + 0x40,0xce,0xfc,0xc9,0xad,0x5b,0x2a,0x18,0x18,0x80,0x5f,0x28,0xfc,0xcd, + 0x47,0x8b,0x86,0x41,0xe5,0x51,0x45,0xdb,0xdd,0xed,0xed,0x2a,0xcc,0xaf, + 0xa0,0xec,0x08,0xfa,0xee,0xde,0x85,0x9f,0xcb,0xa1,0x40,0x44,0x4e,0x88, + 0x68,0x5e,0x4e,0xe2,0x25,0xce,0x4d,0x24,0xa3,0xeb,0xb4,0xdb,0x7b,0xe7, + 0x0e,0x12,0xe5,0x55,0x60,0xb3,0xbd,0xe7,0xd1,0x23,0x78,0xbc,0xc9,0xcf, + 0xe7,0xa1,0xc6,0x3a,0x57,0x9c,0x55,0x20,0x13,0x68,0x6d,0xef,0x23,0x64, + 0xd8,0x04,0x8f,0x48,0x28,0xda,0xed,0x7f,0xf0,0x00,0xb3,0x39,0x1d,0xb7, + 0x0f,0x68,0xc2,0x1f,0x1a,0x92,0x8c,0xb5,0xe0,0x51,0x08,0x02,0xc2,0x9d, + 0x3c,0x19,0x33,0x77,0xef,0x86,0xc3,0x73,0x94,0x7b,0x02,0x5e,0x1f,0x8d, + 0x5c,0x26,0x83,0xb7,0xdb,0xda,0xd0,0xbc,0x65,0x0b,0xbc,0xe1,0x7d,0xab, + 0x6f,0x21,0x6b,0xea,0xe9,0x89,0x1a,0x51,0x20,0x18,0x1c,0x14,0x45,0x0b, + 0x2a,0x69,0x22,0x46,0xe7,0x2d,0x9b,0x36,0xc1,0x89,0xc7,0xd1,0xfa,0xf9, + 0xe7,0x40,0x2a,0x55,0x22,0xa1,0x79,0x8f,0x20,0x9b,0x4e,0x63,0xea,0xaa, + 0x55,0x78,0x6b,0xee,0x5c,0x24,0x84,0xe8,0xf6,0xed,0xf0,0x45,0x57,0x10, + 0x91,0xb1,0x72,0x22,0x02,0x86,0x08,0x72,0x43,0x44,0x0e,0x9a,0x10,0xe5, + 0xaa,0xc6,0x46,0xcc,0xda,0xb6,0x4d,0x6a,0x7f,0xf8,0x2c,0xf0,0x01,0xc9, + 0x78,0xc9,0x24,0xfc,0x6c,0x16,0xd9,0xbe,0x3e,0x4c,0x5f,0xb3,0x06,0x4d, + 0x0b,0x16,0x60,0x78,0x54,0x37,0x35,0x61,0x16,0xa3,0xe5,0x91,0x64,0x48, + 0xc2,0xda,0xa3,0x6d,0x53,0x29,0x02,0xc5,0x6c,0xd6,0x2a,0x90,0xb1,0xa1, + 0x1c,0x62,0x5e,0x14,0x69,0xc8,0x8e,0x28,0x1f,0xe6,0xef,0xd8,0x81,0xa1, + 0xe6,0x66,0x4c,0x5d,0xb7,0x0e,0xd3,0x16,0x2d,0xc2,0xd8,0x31,0xd8,0xdd, + 0x3d,0xf2,0x10,0x26,0xb4,0x27,0xeb,0xa0,0xe2,0x11,0x0c,0x0d,0x8e,0x84, + 0xd6,0x10,0x78,0xfe,0x1c,0xd7,0xb7,0x6e,0x85,0x97,0xc9,0x94,0x91,0xf8, + 0x64,0xef,0x5e,0x24,0x97,0x2c,0x29,0x73,0xfe,0xf8,0xea,0x55,0xdc,0x3b, + 0x72,0x04,0x71,0xe9,0x8c,0xa1,0x1d,0x2d,0xc8,0x57,0x20,0xa0,0xc3,0x1c, + 0x10,0xc6,0x20,0x5b,0x43,0x28,0xce,0x27,0x31,0x2a,0xbf,0xae,0x5d,0x8b, + 0x42,0x3a,0x5d,0x46,0x62,0xec,0xe8,0xbe,0x78,0x11,0x0f,0x0f,0x1d,0x42, + 0xbd,0x31,0xa2,0x2b,0x28,0xd9,0x01,0x41,0x12,0x15,0x92,0x50,0x11,0xd9, + 0x01,0x21,0x40,0x58,0x65,0x87,0x70,0xa9,0x3c,0xd5,0xf3,0xf0,0xcb,0xca, + 0x95,0xc8,0xf5,0xf7,0xe3,0x65,0xe3,0xde,0xf9,0xf3,0x78,0x7a,0xe0,0x00, + 0x9a,0x48,0xcc,0x15,0x3d,0xea,0xc4,0x13,0x09,0xa8,0x20,0x80,0xc7,0x48, + 0xf6,0xdd,0xf8,0x8d,0x3e,0x26,0x78,0x1b,0x1a,0x09,0x5f,0x7b,0x3b,0xaa, + 0xe3,0x35,0xa8,0xad,0xab,0x43,0x6d,0x4d,0x0d,0x62,0x84,0x5b,0x5d,0x8d, + 0x38,0x93,0xb0,0x8e,0x91,0xe8,0xb9,0x76,0x0d,0xad,0xcb,0x96,0x95,0x39, + 0x97,0x9a,0xef,0x3a,0x73,0x06,0x29,0xad,0xe1,0x32,0x67,0xa4,0xf4,0x3c, + 0x46,0xac,0xbf,0xab,0x0b,0x39,0xee,0x15,0x78,0xdd,0x73,0x0c,0x0c,0x26, + 0x20,0x10,0x08,0x06,0x32,0xf0,0x82,0x01,0xa8,0xa7,0x4f,0xc5,0x2a,0x8c, + 0x52,0xa5,0xfd,0x5e,0x1a,0xd1,0xac,0xf1,0x99,0x0b,0x17,0x22,0x4d,0xc3, + 0x0c,0xff,0x08,0xc4,0xb9,0x60,0xde,0xce,0x9d,0xf8,0x79,0xf9,0x72,0xbc, + 0x7f,0xf3,0x26,0x14,0x00,0xcd,0x6b,0x09,0x91,0xbc,0x26,0x73,0xe3,0xa0, + 0x42,0x0e,0x50,0xcb,0x55,0xaa,0xc4,0xaa,0x4a,0xc0,0x79,0x9c,0xb2,0x20, + 0x1d,0x8e,0xa5,0x37,0x77,0xdf,0x3e,0x68,0xce,0x05,0x01,0xc3,0x5a,0x64, + 0x92,0xf9,0xbe,0x2f,0xb2,0xb4,0x76,0xeb,0xeb,0xb1,0xf8,0xf4,0x69,0x74, + 0xb2,0x1f,0x08,0x81,0x04,0x1d,0xc7,0x43,0x3b,0x62,0x2f,0x66,0x7d,0x4c, + 0x40,0xc0,0x90,0xc0,0x18,0x12,0x45,0x1a,0x89,0x6d,0xdc,0x88,0xd9,0xfb, + 0xf7,0x87,0xce,0x23,0xfc,0x78,0xf8,0x30,0x3a,0x2f,0x5d,0x7a,0x61,0xcf, + 0x21,0x89,0x05,0xa7,0x4e,0xe1,0xf1,0xbc,0x79,0x30,0xd6,0xb1,0x75,0x2e, + 0x79,0xe1,0x28,0xfa,0xa8,0x10,0x01,0xa5,0xec,0xa6,0x2b,0x90,0xb0,0xb1, + 0xf5,0x26,0xf7,0xec,0x29,0x73,0x7e,0xf9,0xe0,0x41,0x4c,0x3f,0x76,0x0c, + 0xd7,0xd9,0x19,0xbb,0x2e,0x5f,0x2e,0x23,0x91,0x3a,0x7a,0xb4,0x74,0xee, + 0xae,0x38,0xa1,0x1d,0x87,0x73,0x8a,0x0a,0x11,0x20,0xa2,0xeb,0x76,0x5e, + 0xcb,0x24,0x7a,0xb8,0x79,0x33,0x02,0xcf,0x1b,0x71,0x70,0x9d,0x99,0x3e, + 0xf3,0xf8,0x71,0x2c,0xa6,0xc5,0x2f,0x98,0x6c,0xb7,0x57,0xaf,0xc6,0xa3, + 0x51,0x24,0xf2,0xd4,0x79,0xb2,0x7e,0x3d,0xde,0x2c,0x7f,0x71,0x55,0x7e, + 0x17,0x18,0x45,0x20,0x82,0x4b,0xd4,0x9d,0x3d,0x8b,0x87,0x4c,0x40,0x21, + 0x71,0x9b,0x4f,0x9e,0x3a,0x71,0x02,0x1f,0x49,0x74,0x42,0x03,0x6d,0x24, + 0xf1,0x84,0x7d,0xe2,0xd9,0x95,0x2b,0xc8,0x77,0x76,0xe2,0xf1,0x8a,0x15, + 0x48,0xf6,0xf4,0x40,0x8d,0xd8,0xb1,0x09,0x29,0x1b,0xc1,0x44,0x55,0xa0, + 0x15,0x61,0x89,0x10,0xf6,0xfc,0x45,0x26,0xa8,0xdc,0x78,0xee,0x1c,0x7a, + 0x96,0x2e,0xc5,0x74,0x3e,0xdd,0x0c,0xae,0xf5,0x98,0xcf,0xf9,0x4f,0x49, + 0xa2,0x83,0x6d,0x39,0xc7,0xf0,0xb7,0xf4,0xf6,0xa2,0x28,0x36,0xc2,0x0a, + 0xf2,0xad,0x9d,0xb0,0x1a,0xca,0x08,0x44,0x5f,0xae,0xda,0x08,0x01,0xde, + 0x4c,0xe9,0x53,0xd9,0x1b,0x4e,0x20,0x2a,0x56,0x53,0xbe,0xc3,0xfe,0x1e, + 0xe7,0xbe,0x1f,0x96,0x95,0x43,0xa8,0xb0,0x54,0x85,0xf8,0x6c,0x36,0x1f, + 0x5f,0xea,0x9f,0xeb,0x02,0x50,0xd2,0x2f,0x88,0x1d,0xde,0xe3,0x97,0x08, + 0x09,0x09,0xeb,0x6b,0xfc,0x08,0x10,0x45,0x1b,0x32,0x9b,0x34,0xe2,0x04, + 0x88,0x6a,0x3d,0x7c,0xaa,0xa2,0x3d,0x9a,0xe8,0x1a,0xc2,0xc8,0x85,0xa4, + 0x85,0x40,0x9e,0x32,0x47,0x99,0xa3,0x5e,0x61,0x74,0x14,0x5e,0x76,0x04, + 0xf2,0xdd,0x1e,0x40,0xe9,0xbc,0xd2,0x4e,0x95,0x74,0x0c,0xeb,0x54,0xa4, + 0x25,0x46,0xe9,0x53,0xc6,0x87,0x4b,0xca,0x92,0x8c,0xc8,0x87,0xc4,0x04, + 0x85,0x10,0x79,0xeb,0xdc,0x76,0xc1,0x92,0x0d,0x2d,0xca,0xfa,0x99,0x67, + 0xf4,0xb8,0xff,0x05,0xeb,0x6a,0x63,0x37,0xe6,0x34,0xe9,0xf9,0x33,0xb2, + 0x2e,0x5c,0xed,0x20,0x6e,0xa4,0x89,0x44,0x0d,0x29,0x6c,0x26,0x51,0x69, + 0x8d,0xfa,0x26,0xd4,0xe1,0x19,0x0b,0x01,0x3f,0x24,0xe2,0xc9,0x3c,0xdc, + 0xcb,0x29,0xca,0x64,0x80,0x8e,0x7e,0xfc,0x71,0xf4,0x41,0xf0,0xe1,0xb8, + 0x47,0xd0,0x3c,0xc9,0xd9,0x11,0xab,0x37,0xdf,0x9e,0xcd,0x04,0xef,0x3e, + 0xcf,0x16,0x15,0x38,0x6c,0xf2,0x46,0x25,0xa3,0x22,0x8c,0x1d,0x51,0xc6, + 0x47,0x73,0xbb,0xcf,0x89,0xeb,0x2a,0xfd,0x5e,0xbf,0xba,0x33,0xa3,0xc6, + 0xf9,0xb2,0xec,0xcf,0xe8,0x55,0x7f,0xcd,0xea,0xc7,0xf7,0x8f,0x0c,0x60, + 0x5e,0xf5,0xd7,0xec,0xff,0xbf,0xe3,0xbf,0x00,0x0f,0x56,0x81,0xab,0xdc, + 0x79,0x68,0x79,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, + 0x82 +}; + +/* Generated by qembed */ +static const unsigned int dialog_information_png_len = 1636; +static const unsigned char dialog_information_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x08,0x06,0x00,0x00, + 0x00,0x73,0x7a,0x7a,0xf4,0x00,0x00,0x00,0x04,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0x08,0x7c,0x08,0x64,0x88,0x00,0x00,0x00,0x09,0x70,0x48,0x59, + 0x73,0x00,0x00,0x03,0x76,0x00,0x00,0x03,0x76,0x01,0x7d,0xd5,0x82,0xcc, + 0x00,0x00,0x00,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61, + 0x72,0x65,0x00,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70, + 0x65,0x2e,0x6f,0x72,0x67,0x9b,0xee,0x3c,0x1a,0x00,0x00,0x05,0xe1,0x49, + 0x44,0x41,0x54,0x78,0xda,0xc5,0x57,0x5b,0x6c,0x54,0x45,0x18,0xfe,0xe6, + 0xdc,0x76,0xb7,0xbb,0xdd,0x76,0xb1,0x2d,0xb4,0x05,0xa5,0x11,0xd1,0x8a, + 0x82,0x48,0x49,0x04,0x1e,0x00,0xc5,0x48,0x34,0x12,0x89,0x11,0x02,0x3c, + 0x60,0x8c,0x06,0xf1,0x12,0xa5,0xf2,0xe0,0x0b,0x62,0x13,0x8d,0x09,0x09, + 0x98,0x28,0x31,0xe1,0x92,0x28,0x3e,0x11,0x8c,0xe2,0x2d,0x12,0x2e,0xb1, + 0x34,0x62,0x23,0xa1,0x11,0x12,0x2e,0x2a,0x88,0x94,0x3b,0x94,0x16,0xe9, + 0xee,0x76,0x77,0xcf,0x6d,0xc6,0x7f,0x7a,0x26,0x29,0xcb,0xee,0x76,0x0b, + 0x2f,0x7e,0xc9,0xb7,0x33,0x3b,0x3b,0x73,0xbe,0xef,0xbf,0xe4,0x9c,0xb3, + 0x4c,0x08,0x81,0xdb,0x00,0x23,0x6a,0x8a,0x4c,0x51,0x42,0x28,0xf2,0xa1, + 0x71,0x64,0x30,0x30,0x02,0x28,0x41,0x93,0x18,0x21,0x56,0x12,0x63,0xc4, + 0x0a,0xb5,0xc6,0x88,0x1e,0x31,0x4b,0x4c,0x13,0x93,0xc4,0x0c,0xd1,0x19, + 0x89,0x11,0x63,0x04,0x11,0x5b,0x4a,0xb0,0x66,0xeb,0xee,0xa3,0xb3,0x4f, + 0x9c,0xbb,0xbe,0x50,0xd3,0xf4,0xc9,0x95,0x15,0x56,0xbc,0x32,0x12,0x0a, + 0x6b,0x1a,0x43,0xc6,0x76,0xed,0x54,0xd6,0x4d,0x09,0xc1,0x4f,0x34,0x37, + 0x26,0x76,0x2e,0x9f,0xd7,0xbc,0x1f,0x40,0x8f,0x32,0x63,0x13,0x4b,0xa6, + 0x79,0xb8,0x12,0x68,0x2a,0xe2,0x9a,0xd6,0x4d,0xed,0x2f,0xf5,0xa5,0x9d, + 0x95,0x93,0x9a,0xea,0x6a,0xeb,0x13,0x55,0x30,0x74,0x9d,0xa8,0xc1,0x34, + 0x34,0x68,0x60,0xe0,0x22,0xa8,0xc0,0x40,0xce,0x45,0x4f,0x32,0x8d,0x93, + 0xe7,0xfb,0xae,0x57,0x47,0xcd,0xcd,0x1f,0xbd,0x38,0x6b,0xab,0x32,0x92, + 0x21,0xfa,0x23,0x36,0xa0,0xc4,0x2b,0xd6,0x7f,0x7d,0x70,0xda,0xbe,0xc3, + 0xe7,0xb7,0x4c,0xbc,0xbb,0xf6,0xbe,0xa9,0x13,0xc6,0x81,0xfb,0x0c,0x7d, + 0x69,0x1b,0xa5,0x3c,0x4b,0x43,0x89,0x98,0x09,0x26,0x38,0x4e,0x5c,0xba, + 0x86,0x53,0xe7,0x7a,0xcf,0x3c,0xf1,0x70,0xe3,0xab,0xaf,0x2f,0x98,0x7a, + 0x50,0x95,0xc7,0x1f,0x89,0x01,0x46,0x8c,0x2c,0x69,0xfb,0xe6,0xd9,0x8b, + 0xc9,0xdc,0xe6,0x39,0x8f,0x4e,0x8c,0x8f,0xab,0x4d,0xe0,0xea,0xbf,0x36, + 0x6e,0x07,0x63,0x12,0x16,0xae,0xf6,0x0f,0xe0,0xd7,0x63,0xdd,0xe9,0xc6, + 0x78,0xe8,0xb5,0x2d,0xef,0xcc,0xdf,0xa9,0x32,0xc1,0xcb,0x19,0x30,0xe7, + 0xbc,0xf5,0xc5,0xd3,0x0e,0x8c,0xaf,0x9e,0x9b,0x3d,0xc5,0xf4,0xb9,0x41, + 0x35,0xf6,0x70,0x27,0xa8,0xb0,0x0c,0x44,0xc3,0xc0,0xb7,0x9d,0x27,0xdc, + 0xa8,0xc6,0x97,0xfd,0xf0,0xe1,0x0b,0xdf,0x03,0xb0,0x87,0x33,0xc0,0xa6, + 0xbd,0xbc,0xb1,0xf9,0x72,0xd2,0x3b,0xb0,0x6c,0xfe,0xcc,0x84,0xa6,0x59, + 0x28,0x85,0x09,0xf5,0x95,0x98,0xf7,0xc8,0x18,0x48,0xec,0x3b,0x72,0x05, + 0x7f,0x5f,0x4e,0xa1,0x14,0x62,0x11,0xe0,0xcb,0xdd,0x87,0x6e,0x34,0xd5, + 0x44,0xe7,0xec,0x59,0xb7,0xf4,0xe8,0xcd,0x59,0xd0,0x70,0x13,0xda,0xda, + 0xda,0x18,0x75,0xf9,0xb6,0xc9,0x13,0xc7,0x27,0x98,0x66,0xc2,0xf1,0xfc, + 0xa2,0xcc,0x39,0x0e,0x9e,0x9f,0x39,0x16,0x4d,0xa3,0xa3,0x92,0x72,0x2e, + 0xd7,0x4a,0xee,0x1f,0xc8,0x09,0xcc,0x98,0xd4,0x54,0xdd,0x75,0xf2,0xf2, + 0xe7,0x1d,0x1d,0x1d,0x4a,0xb3,0x88,0x81,0xf7,0xf7,0x64,0x97,0x54,0x56, + 0x56,0xb6,0x34,0x37,0x35,0xd2,0x21,0x8f,0x0e,0xf3,0xa2,0x14,0x5c,0xa0, + 0x3a,0x3a,0x94,0x1d,0x39,0xe7,0x9c,0x97,0xdc,0x9f,0xca,0x7a,0x68,0xa8, + 0x1d,0x85,0x9a,0x44,0xd5,0xd4,0xa7,0x3e,0xe8,0x58,0x5a,0xd4,0x00,0x23, + 0x40,0xd3,0xd6,0xce,0x6d,0x79,0x08,0xa9,0x8c,0x0f,0xdb,0x2d,0xcd,0xfe, + 0x8c,0x8b,0x03,0xc7,0x2f,0x03,0x0a,0x07,0x8e,0x5d,0x42,0x92,0xd6,0x86, + 0x3b,0xd3,0xdb,0xef,0xe0,0x89,0x96,0x07,0x60,0xfb,0x58,0x43,0x4a,0xac, + 0xa0,0x07,0xd8,0xf4,0xd5,0x33,0x6a,0x1a,0xea,0x3a,0x9f,0x79,0x7c,0x16, + 0x38,0x47,0x59,0xd8,0x94,0xf2,0xa6,0x9a,0x30,0x24,0xce,0x5c,0xcb,0x21, + 0x14,0xb2,0x50,0x0e,0xf1,0x88,0x89,0x1f,0x7f,0xe9,0xc2,0xd9,0xd3,0xdd, + 0xb3,0xc4,0x6f,0xeb,0x3a,0xf3,0xef,0x84,0x9a,0xbf,0x78,0x74,0x6d,0x1d, + 0xd5,0xd2,0xc7,0x70,0x10,0x82,0x03,0x22,0x78,0x0c,0xfc,0x73,0xcd,0x96, + 0x21,0x28,0x43,0x1e,0x98,0xc6,0x30,0x1c,0x7a,0x53,0x3e,0xee,0x1f,0xdf, + 0x88,0xb3,0xdd,0xe7,0x17,0x03,0xb8,0xc5,0x00,0x63,0xb3,0xe2,0xf1,0x38, + 0xa5,0xcb,0x43,0x29,0x70,0x9f,0xe3,0xbb,0x35,0xf3,0x50,0x0c,0x0b,0xda, + 0xf6,0x42,0x37,0x75,0x94,0x43,0xac,0x22,0x22,0xb5,0x66,0x16,0x7b,0x16, + 0xd4,0x99,0xa6,0x3e,0xd8,0xb5,0xa5,0xe0,0x7b,0x02,0xa5,0x90,0xf3,0x38, + 0x4c,0xdd,0x90,0x29,0x22,0x96,0x7e,0x20,0x5a,0xda,0x60,0xe1,0xeb,0xf2, + 0x9a,0x90,0x11,0xc0,0x30,0x4a,0xd3,0xc8,0x80,0xcb,0x0b,0xe9,0x11,0x7d, + 0x06,0x17,0x0c,0x4f,0xbe,0xb7,0x17,0xb3,0xdf,0xdd,0x55,0xd8,0x13,0x1e, + 0x06,0xf7,0x38,0x5c,0x52,0xcd,0xbd,0xbc,0xeb,0x90,0x38,0xc9,0x31,0x00, + 0x02,0x77,0x31,0xc2,0xad,0x19,0x60,0x39,0x47,0xc0,0x12,0x3e,0xf2,0x30, + 0x78,0x48,0x12,0x44,0x5d,0x7e,0x27,0x01,0xbf,0xd0,0x00,0x17,0x00,0x89, + 0x13,0x82,0x51,0x08,0x44,0x2d,0x13,0x61,0x13,0xb8,0x91,0xce,0x12,0x6d, + 0x74,0x5d,0x4d,0xe1,0xc6,0x80,0x0d,0x0c,0x9d,0x0f,0x0c,0x08,0x02,0x7b, + 0xac,0x35,0x99,0xca,0x66,0xa3,0x31,0x16,0x46,0xa0,0x86,0x40,0x58,0x48, + 0x13,0x2c,0x30,0x02,0x22,0xd7,0x48,0xac,0x48,0x6a,0x2d,0x1d,0xe1,0x88, + 0x05,0x2e,0x8d,0x50,0x10,0xe9,0xac,0x8d,0xd3,0x17,0xfa,0x71,0xb1,0x37, + 0x09,0xf8,0x2e,0x94,0xa8,0x2a,0x91,0x97,0x14,0x84,0xfc,0x0c,0x08,0x71, + 0xe3,0x78,0x77,0x4f,0x3d,0x33,0x4c,0xe8,0x8c,0xc1,0xb4,0x2c,0x98,0x66, + 0x08,0x3a,0x45,0x61,0x99,0x34,0xa7,0x31,0x12,0x0a,0x41,0x33,0x01,0x3b, + 0xcb,0x61,0xdb,0xb6,0x34,0x4e,0x82,0x7c,0x70,0xec,0x3c,0x9d,0x86,0x6f, + 0x79,0xa0,0x85,0x40,0x8c,0xd3,0xdc,0x27,0xea,0x06,0x14,0x82,0x75,0x21, + 0x7f,0x17,0xfd,0xc5,0x9a,0xf0,0x77,0xf8,0x76,0xb3,0xd0,0x4d,0xc8,0x5e, + 0xf3,0xe8,0x23,0x2b,0x37,0xfb,0x44,0xc7,0x03,0x72,0x0c,0xd0,0x01,0x68, + 0xf4,0x61,0xbb,0xc8,0x64,0x32,0xf9,0x0d,0x2a,0x4b,0x6a,0x58,0x4a,0x5c, + 0x93,0x0b,0x18,0x0a,0x0e,0x4a,0x98,0xe8,0xe5,0x02,0xad,0x82,0x5b,0xb1, + 0x27,0xb6,0xc3,0x4e,0x01,0xcc,0x20,0x21,0x59,0x6b,0x23,0x10,0xd3,0x0d, + 0xa2,0x79,0xd3,0x68,0x05,0xeb,0xf9,0x50,0x7b,0x2d,0x45,0x33,0xff,0x9c, + 0xa6,0xae,0x67,0x84,0x00,0x3b,0x09,0x70,0x6c,0x2f,0x34,0x70,0xef,0xa5, + 0x5d,0xc8,0x25,0xfb,0x28,0xd7,0xaa,0xd9,0xf2,0x58,0x70,0xd1,0x02,0x48, + 0xd3,0x46,0x9e,0x78,0xe1,0x35,0xa8,0xbc,0x83,0x1a,0x4d,0x17,0x7f,0x2a, + 0x30,0x20,0x76,0xec,0xf0,0x21,0xf8,0x27,0xe8,0x3b,0x05,0x84,0x63,0x41, + 0x03,0xaa,0x83,0x2a,0x1b,0x41,0x0a,0xed,0x81,0xc1,0xda,0x16,0xc0,0x75, + 0x81,0x6c,0x32,0xa8,0xbd,0x66,0xe6,0x9f,0x93,0x34,0x2b,0x80,0xde,0x3f, + 0x01,0x21,0x3e,0x95,0x5a,0x45,0xdf,0x07,0xd8,0xa2,0x45,0x3a,0xce,0x8e, + 0x3d,0x8f,0xba,0x09,0xf5,0x88,0xd5,0x03,0x3a,0x0b,0x52,0x6a,0x28,0xba, + 0x36,0xae,0xaf,0x6f,0xc1,0x70,0x18,0xb5,0x9a,0xca,0x1b,0x8a,0x02,0xbe, + 0x03,0x78,0x8a,0xb2,0xfe,0xfd,0x17,0x80,0x2b,0x27,0xaf,0xe0,0x9e,0x0b, + 0x63,0x95,0x81,0xa1,0x0c,0xe4,0x65,0x81,0x8b,0x45,0xe8,0x3d,0x65,0x83, + 0x71,0x95,0x05,0x22,0x93,0x54,0x11,0x95,0x83,0xaa,0xb9,0xdc,0xaf,0xce, + 0x07,0x06,0x7a,0xfe,0x72,0xe0,0xfb,0x8b,0xa4,0x46,0xd9,0x97,0x52,0x36, + 0x7d,0xd5,0x4a,0x44,0x2a,0x36,0x22,0xde,0xa0,0xa1,0xbe,0x39,0xf0,0x69, + 0x58,0xca,0x25,0x94,0x08,0x51,0x57,0x42,0xdc,0x27,0xba,0x20,0x01,0x65, + 0x98,0x0d,0x45,0xde,0x99,0x05,0xaa,0xf7,0x73,0x64,0xb3,0x6f,0x8a,0x43, + 0x1b,0x3e,0x1b,0xe9,0x5b,0x31,0x99,0x68,0x7d,0x03,0x86,0xd8,0x80,0x86, + 0x29,0x26,0x6a,0x27,0x02,0x0c,0x41,0x17,0xab,0x72,0x0c,0xcd,0x4d,0x12, + 0x73,0x55,0xba,0x6d,0x35,0x3a,0x81,0xa9,0xab,0x54,0xf3,0x8b,0x87,0x5d, + 0x78,0x68,0x15,0x87,0x3e,0xde,0x58,0xf6,0xb5,0xbc,0xd0,0xc4,0xdb,0x73, + 0x98,0xa6,0xed,0x14,0xd1,0xaa,0x6a,0x8c,0x1a,0x0f,0x8c,0x9d,0x1a,0x44, + 0xa7,0x9b,0x52,0x7c,0x28,0xdd,0x52,0xcc,0xf7,0xa4,0x91,0x20,0xea,0xfd, + 0xd7,0x80,0xaa,0x9f,0xa1,0x65,0x53,0xfd,0xdc,0x15,0x0b,0x45,0xd7,0x86, + 0xf6,0xdb,0xff,0x63,0xa2,0xc0,0xe6,0xb6,0x19,0x46,0x2e,0xb9,0x1e,0x3a, + 0x5b,0xe1,0xc5,0x46,0x87,0xd0,0x30,0x19,0x70,0xb2,0x40,0xa4,0x0a,0xa8, + 0x88,0x07,0x86,0x72,0x69,0x20,0xd3,0x1f,0x64,0xe5,0xc2,0x11,0x98,0xb9, + 0x5e,0x87,0x71,0xb1,0xd9,0x31,0x63,0xab,0x44,0xfb,0x5a,0x0f,0x84,0x32, + 0x06,0xca,0x83,0xb5,0xac,0x30,0xad,0x70,0x62,0xb9,0x1e,0x62,0xaf,0x70, + 0xe0,0x41,0x1f,0x08,0x73,0xcf,0xd7,0x85,0x6c,0x35,0xd3,0xf0,0x75,0xc6, + 0x72,0x1a,0xf0,0x07,0x77,0xf8,0x26,0x67,0xe0,0xfa,0x36,0xd1,0xb5,0xc9, + 0x85,0x42,0x59,0x03,0x77,0x0a,0xc6,0xe6,0xaa,0x87,0x59,0xfb,0x70,0x51, + 0x96,0x37,0xf0,0x7f,0xe2,0x3f,0x0c,0x08,0x36,0xef,0x65,0xe9,0x4f,0x36, + 0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +static const unsigned int dialog_warning_png_len = 1354; +static const unsigned char dialog_warning_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x08,0x06,0x00,0x00, + 0x00,0x73,0x7a,0x7a,0xf4,0x00,0x00,0x00,0x04,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0x08,0x7c,0x08,0x64,0x88,0x00,0x00,0x00,0x09,0x70,0x48,0x59, + 0x73,0x00,0x00,0x03,0x76,0x00,0x00,0x03,0x76,0x01,0x7d,0xd5,0x82,0xcc, + 0x00,0x00,0x00,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61, + 0x72,0x65,0x00,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70, + 0x65,0x2e,0x6f,0x72,0x67,0x9b,0xee,0x3c,0x1a,0x00,0x00,0x04,0xc7,0x49, + 0x44,0x41,0x54,0x78,0xda,0xd5,0x97,0x5d,0x6c,0x14,0x55,0x14,0xc7,0xff, + 0xe7,0xde,0x3b,0x1f,0xfb,0xd5,0xee,0xb6,0x6c,0xbf,0x68,0x2b,0xa4,0x50, + 0xa4,0xd0,0x42,0x04,0xa2,0x24,0x04,0x31,0x10,0xa3,0x01,0x4c,0x24,0xd1, + 0x48,0x30,0xbc,0x48,0xf4,0xc9,0x44,0x7d,0xd5,0x60,0x88,0x31,0xc6,0x04, + 0x13,0x8d,0xe8,0x83,0x2f,0xfa,0xce,0x03,0x3e,0x69,0x82,0x98,0xf0,0xa2, + 0x2f,0x86,0x34,0x62,0x00,0xbf,0xa2,0x21,0x5a,0xd0,0xb6,0xd0,0xee,0xee, + 0xcc,0x6c,0xe7,0xf3,0x7a,0xa7,0x3b,0x75,0x9a,0xdd,0x54,0x49,0x69,0x25, + 0x9e,0xe4,0x97,0x73,0x32,0xf7,0x9e,0x39,0xff,0x73,0x66,0xe7,0x63,0x49, + 0x4a,0x89,0x7b,0x69,0x4c,0xf1,0x3f,0x16,0x70,0x96,0xf8,0x3c,0x77,0x61, + 0xcb,0xbf,0x04,0x9f,0x52,0x11,0xbd,0xc5,0xe3,0xf0,0x67,0x6b,0x08,0x70, + 0x0e,0xfb,0xe4,0xec,0x7f,0x27,0xe0,0x3c,0xe5,0x22,0x9d,0x7f,0x1d,0xb5, + 0x9f,0x18,0x03,0x24,0xd8,0xec,0xc7,0x97,0x59,0x9b,0xbf,0x1b,0x3b,0xa4, + 0xb3,0xfa,0x97,0xe0,0x22,0x89,0x48,0x63,0x2f,0x06,0x76,0xe7,0xa8,0xe8, + 0x78,0x1a,0xa2,0xed,0x30,0x82,0x19,0x7d,0x34,0xb2,0xc4,0x4b,0x00,0xf1, + 0xd5,0x17,0x10,0x20,0x27,0x5d,0xf6,0xb2,0x68,0x7f,0x8a,0x60,0x74,0x00, + 0x99,0x1e,0x88,0x8e,0x63,0x14,0xd9,0x78,0x05,0x17,0x90,0x5f,0x35,0x01, + 0x69,0xf7,0xe2,0xd5,0xd0,0xeb,0xea,0x62,0xbd,0x07,0x01,0xaf,0x3a,0x0f, + 0xeb,0x7b,0x0c,0xa1,0x53,0xe8,0x84,0x10,0x27,0xe3,0x3d,0xab,0x27,0xa0, + 0x80,0x62,0x54,0xa7,0x13,0x62,0xcd,0x11,0x80,0x73,0xc0,0xaf,0x02,0x81, + 0x02,0x21,0x44,0xf7,0x93,0x08,0x1c,0x7a,0x0e,0x40,0x71,0x75,0x04,0x7c, + 0x44,0x5a,0x54,0xe3,0x6f,0x4a,0xea,0x2d,0xb1,0xf2,0x1e,0x44,0xaa,0xf8, + 0xed,0xe9,0xba,0xc2,0x41,0xa4,0x44,0xf0,0xd2,0x4e,0x48,0x59,0x6a,0x8f, + 0x38,0x7f,0x2b,0x9e,0xc2,0xca,0x0b,0xd8,0x82,0x72,0xe4,0xb2,0xa3,0xac, + 0x74,0x10,0x90,0x2e,0x1c,0xcb,0x46,0x75,0xca,0x46,0x65,0xd2,0x81,0x6d, + 0x39,0x80,0xb4,0xc1,0x8b,0xfb,0x11,0xda,0xec,0x19,0x70,0x94,0x57,0x56, + 0xc0,0x25,0xd5,0xbd,0xcf,0xde,0x89,0xf8,0x60,0x81,0xb7,0x8f,0x02,0x51, + 0x0d,0x81,0x5b,0x43,0x54,0x57,0x38,0x16,0xfc,0xb9,0x1a,0x10,0x55,0xc1, + 0x72,0xeb,0x21,0xd1,0x95,0xf7,0x7d,0xf6,0x5e,0x9c,0xb3,0x72,0x02,0x7c, + 0xac,0xf5,0x1d,0x7a,0x82,0x97,0xf6,0x03,0x91,0x35,0x5f,0x8c,0xb3,0xaa, + 0x12,0x60,0x21,0x74,0x6a,0xe0,0xbc,0x0a,0xc8,0x98,0x0a,0x78,0xfb,0x2e, + 0x25,0x8a,0x0e,0xc1,0x45,0xdf,0xca,0x08,0x38,0x4b,0x7a,0x60,0xb1,0xf7, + 0x49,0x1f,0xce,0xf2,0x4c,0x1f,0x10,0x35,0x8a,0x71,0xa1,0x04,0xa8,0xe2, + 0x52,0x4d,0x41,0xe8,0x15,0x00,0x35,0x85,0x3a,0x6e,0xe6,0x01,0x31,0x90, + 0x09,0x6c,0xf6,0x61,0x9c,0x7b,0x77,0x02,0x88,0x08,0x1d,0xd8,0x10,0xd6, + 0xe9,0x51,0xde,0xb9,0x1b,0x20,0x4b,0x91,0x14,0x52,0x45,0x65,0xdd,0x56, + 0x58,0x4a,0x40,0x15,0xa0,0x04,0xcc,0x40,0x94,0x86,0x10,0xd8,0x74,0x20, + 0xce,0x05,0x11,0x2d,0x5f,0xc0,0x67,0xd0,0xfd,0x80,0x9d,0x41,0x76,0xab, + 0xce,0xcd,0x4c,0x5c,0x58,0x51,0x9b,0x47,0x18,0x95,0xf9,0xee,0xa5,0xa3, + 0xe2,0x4c,0x05,0x60,0xb5,0x86,0x38,0xe5,0xb9,0xe9,0x02,0xe6,0xda,0x38, + 0xf7,0x03,0x5c,0x81,0xb6,0x4c,0x01,0x44,0x68,0xd3,0xb6,0x7b,0x16,0xdf, + 0x23,0xca,0x5b,0x00,0xaa,0x34,0x04,0xb0,0x06,0xdc,0xa8,0x82,0x3c,0x0b, + 0xe4,0x5b,0xaa,0x60,0xa5,0x71,0x9c,0x27,0xeb,0x34,0x0b,0xad,0xdc,0x0b, + 0xbf,0x86,0x3d,0xb8,0xa5,0x6d,0x03,0x96,0x9e,0x82,0xc0,0x52,0xf6,0x09, + 0x0c,0xaf,0x1c,0xbc,0xcb,0xf3,0xc3,0x1a,0x17,0x53,0x00,0x74,0x40,0x33, + 0x00,0x12,0x8a,0x0c,0x20,0x02,0x98,0xe5,0x1c,0x88,0x6b,0x80,0xae,0x03, + 0xb9,0x08,0x80,0x6c,0x20,0x01,0x4e,0x04,0x9a,0x9a,0x10,0xde,0xec,0xc4, + 0x19,0xfd,0x73,0xec,0xc5,0xe3,0x70,0xef,0x5c,0xc0,0x29,0x62,0xd8,0x27, + 0x1e,0xf6,0x6e,0xb0,0x5d,0xe6,0x7d,0xd3,0xc0,0xdc,0x0f,0x00,0x25,0xf3, + 0xa2,0x98,0x38,0xc8,0xc3,0xfb,0x2d,0x0f,0xe9,0xda,0x80,0x53,0x01,0xdc, + 0x64,0x2d,0x36,0xd9,0x70,0x5a,0x77,0x37,0xea,0x57,0xe4,0x4e,0xd6,0xc3, + 0xf7,0x8a,0x53,0xf4,0x25,0x5e,0x97,0xd1,0x9d,0x09,0x18,0x81,0x51,0xbf, + 0x15,0xbe,0xcd,0xda,0x7a,0xb8,0x28,0xfc,0xfe,0x77,0xe1,0xd4,0x47,0xca, + 0x57,0x91,0xe9,0x6a,0x74,0x0b,0xae,0x30,0x91,0x58,0x2a,0x40,0x18,0xd3, + 0x60,0xa5,0x6e,0xe6,0xcd,0x4e,0x9e,0x16,0x23,0x78,0x08,0x40,0xfd,0x0e, + 0x7e,0x03,0xc4,0xc2,0x4e,0x7e,0xd8,0xbb,0x9d,0x1d,0xd3,0x7b,0x5d,0x40, + 0x47,0x03,0x23,0xc1,0x4c,0xbc,0x06,0xf4,0x3f,0x5b,0x43,0xff,0xf1,0x5a, + 0xb2,0xde,0x84,0xae,0xd0,0x42,0x98,0x43,0x1a,0xbc,0x49,0x1a,0x0d,0xdb, + 0xf8,0xa1,0x78,0xb2,0xff,0xfe,0x41,0x72,0x93,0xb2,0xd6,0x17,0x18,0xa7, + 0x35,0x1b,0x86,0x73,0x9b,0x7e,0x06,0x58,0xd2,0x21,0x4b,0xa0,0x34,0x76, + 0x7e,0xd4,0xc1,0x32,0x12,0xe6,0x3a,0x7f,0xa1,0xeb,0xd8,0xa7,0x44,0xb1, + 0x67,0xb0,0xc7,0x07,0x20,0xa7,0xae,0xff,0x94,0xdf,0x8a,0xed,0xcd,0x1f, + 0x2d,0xac,0xf9,0x1b,0xcf,0x1f,0x67,0xc7,0xfc,0x4a,0xc7,0x46,0x73,0x5d, + 0x15,0xd0,0x16,0x3a,0x49,0x58,0xd4,0xe9,0xcc,0x85,0x1c,0x6e,0x9e,0x2e, + 0x62,0xe2,0x8d,0x12,0xac,0x71,0x73,0xa1,0xeb,0x74,0xbf,0x48,0xe0,0x11, + 0x32,0xf7,0x13,0xdc,0x49,0x6d,0xa3,0x7f,0x83,0x1d,0x05,0x88,0x2d,0x2d, + 0x60,0x10,0x39,0xe7,0xba,0x7c,0x4d,0xdf,0xd8,0x47,0xbc,0x30,0x09,0x08, + 0xa4,0x68,0xa9,0x8f,0x8b,0xf9,0xbf,0x0a,0x70,0xc2,0x3c,0xde,0x2f,0x5a, + 0x5a,0x98,0x2f,0x9a,0x18,0x35,0x60,0xd9,0xeb,0x30,0xb7,0xae,0x87,0x3a, + 0xf7,0x49,0x5c,0x45,0xb6,0x49,0x40,0xda,0xbd,0x3b,0xc1,0x5e,0x08,0x9c, + 0x9e,0x41,0x73,0x68,0x32,0x5e,0x69,0x61,0xf1,0x89,0xdb,0x0f,0xd6,0x61, + 0x74,0xa9,0xee,0x06,0x42,0x14,0x0e,0xd4,0x81,0x08,0xad,0xc8,0x85,0x58, + 0x22,0xb3,0x29,0x80,0x3b,0x6d,0x0e,0xd6,0xaf,0xb1,0xe7,0xe3,0x5a,0xad, + 0xbf,0x81,0x8b,0x54,0x9c,0xf9,0x86,0xae,0x19,0xdb,0x1e,0xe8,0xc9,0x6e, + 0xbe,0xb4,0xb8,0x60,0x0a,0x6f,0xba,0x1b,0x90,0xf8,0xe8,0x1f,0x08,0x13, + 0x54,0x6c,0x5f,0x1b,0x83,0xfb,0xed,0x77,0x7f,0x76,0x3c,0x22,0x87,0xf1, + 0xa0,0xac,0xa6,0x13,0x20,0x22,0x70,0x6c,0x73,0xa7,0x8c,0x6e,0x63,0xd0, + 0x6e,0x4a,0x4e,0x08,0x14,0x7e,0x82,0xbb,0x88,0xba,0x62,0x2e,0x89,0x3d, + 0xb4,0xe2,0xa7,0xb9,0x99,0x21,0x06,0xbf,0x62,0x76,0xa9,0x78,0x73,0xeb, + 0x73,0x80,0x21,0xd2,0xbb,0xdb,0x24,0xa8,0x9f,0x20,0x28,0xed,0x34,0x36, + 0x6a,0x7e,0xc8,0xa4,0x3e,0x89,0x13,0xd2,0xfd,0xad,0xf9,0x04,0x78,0x59, + 0x98,0x1b,0xb2,0x00,0xab,0x47,0xad,0x97,0xe0,0x2a,0xe5,0xe7,0xbe,0xd7, + 0xce,0x85,0x9e,0xb9,0xdf,0x9b,0x2e,0x91,0x73,0xf9,0x0f,0xac,0xa4,0xf1, + 0x62,0x01,0xc6,0x00,0x97,0x99,0xfe,0x99,0xf3,0xe6,0xa0,0x7f,0x24,0xbe, + 0x1d,0x5b,0x9f,0x03,0x5f,0x51,0x01,0xbe,0xd8,0x01,0x4d,0xae,0x45,0xb3, + 0x85,0x0a,0x8e,0x74,0xb3,0x5c,0x22,0x66,0x2a,0x0e,0x17,0xaa,0x26,0x31, + 0x0b,0x65,0x3c,0x61,0x00,0x37,0x90,0xc7,0x65,0x8c,0x49,0xbb,0x69,0x02, + 0x4d,0xef,0x81,0x11,0x10,0x56,0xc3,0xae,0x42,0x36,0xbf,0x0f,0xee,0xf9, + 0xdf,0xf3,0xbf,0x00,0xdc,0x19,0x00,0xc3,0x09,0xc5,0x7a,0xd4,0x00,0x00, + 0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +#endif diff --git a/src/qtcurve/style/fixx11h.h b/src/qtcurve/style/fixx11h.h new file mode 100644 index 0000000000..c2a8c6d87c --- /dev/null +++ b/src/qtcurve/style/fixx11h.h @@ -0,0 +1,306 @@ +/**************************************************************************** + + 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 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. + +****************************************************************************/ + + +//#ifdef don't do this, this file is supposed to be included +//#define multiple times + +#include + +#ifdef Q_WS_X11 + +/* Usage: + + If you get compile errors caused by X11 includes (the line + where first error appears contains word like None, Unsorted, + Below, etc.), put #include in the .cpp file + (not .h file!) between the place where X11 headers are + included and the place where the file with compile + error is included (or the place where the compile error + in the .cpp file occurs). + + This file remaps X11 #defines to const variables or + inline functions. The side effect may be that these + symbols may now refer to different variables + (e.g. if X11 #defined NoButton, after this file + is included NoButton would no longer be X11's + NoButton, but Qt::NoButton instead). At this time, + there's no conflict known that could cause problems. + + The original X11 symbols are still accessible + (e.g. for None) as X::None, XNone, and also still + None, unless name lookup finds different None + first (in the current class, etc.) + + Use 'Unsorted', 'Bool' and 'index' as templates. + +*/ + +namespace X +{ + +// template ---> +// Affects: Should be without side effects. +#ifdef Unsorted +#ifndef FIXX11H_Unsorted +#define FIXX11H_Unsorted +const int XUnsorted = Unsorted; +#undef Unsorted +const int Unsorted = XUnsorted; +#endif +#undef Unsorted +#endif +// template <--- + +// Affects: Should be without side effects. +#ifdef None +#ifndef FIXX11H_None +#define FIXX11H_None +const XID XNone = None; +#undef None +const XID None = XNone; +#endif +#undef None +#endif + +// template ---> +// Affects: Should be without side effects. +#ifdef Bool +#ifndef FIXX11H_Bool +#define FIXX11H_Bool +#ifdef _XTYPEDEF_BOOL /* Xdefs.h has typedef'ed Bool already */ + #undef Bool +#else + typedef Bool XBool; + #undef Bool + typedef XBool Bool; +#endif +#endif +#undef Bool +#define _XTYPEDEF_BOOL +#endif +// template <--- + +// Affects: Should be without side effects. +#ifdef KeyPress +#ifndef FIXX11H_KeyPress +#define FIXX11H_KeyPress +const int XKeyPress = KeyPress; +#undef KeyPress +const int KeyPress = XKeyPress; +#endif +#undef KeyPress +#endif + +// Affects: Should be without side effects. +#ifdef KeyRelease +#ifndef FIXX11H_KeyRelease +#define FIXX11H_KeyRelease +const int XKeyRelease = KeyRelease; +#undef KeyRelease +const int KeyRelease = XKeyRelease; +#endif +#undef KeyRelease +#endif + +// Affects: Should be without side effects. +#ifdef Above +#ifndef FIXX11H_Above +#define FIXX11H_Above +const int XAbove = Above; +#undef Above +const int Above = XAbove; +#endif +#undef Above +#endif + +// Affects: Should be without side effects. +#ifdef Below +#ifndef FIXX11H_Below +#define FIXX11H_Below +const int XBelow = Below; +#undef Below +const int Below = XBelow; +#endif +#undef Below +#endif + +// Affects: Should be without side effects. +#ifdef FocusIn +#ifndef FIXX11H_FocusIn +#define FIXX11H_FocusIn +const int XFocusIn = FocusIn; +#undef FocusIn +const int FocusIn = XFocusIn; +#endif +#undef FocusIn +#endif + +// Affects: Should be without side effects. +#ifdef FocusOut +#ifndef FIXX11H_FocusOut +#define FIXX11H_FocusOut +const int XFocusOut = FocusOut; +#undef FocusOut +const int FocusOut = XFocusOut; +#endif +#undef FocusOut +#endif + +// Affects: Should be without side effects. +#ifdef Always +#ifndef FIXX11H_Always +#define FIXX11H_Always +const int XAlways = Always; +#undef Always +const int Always = XAlways; +#endif +#undef Always +#endif + +// Affects: Should be without side effects. +#ifdef Success +#ifndef FIXX11H_Success +#define FIXX11H_Success +const int XSuccess = Success; +#undef Success +const int Success = XSuccess; +#endif +#undef Success +#endif + +// Affects: Should be without side effects. +#ifdef GrayScale +#ifndef FIXX11H_GrayScale +#define FIXX11H_GrayScale +const int XGrayScale = GrayScale; +#undef GrayScale +const int GrayScale = XGrayScale; +#endif +#undef GrayScale +#endif + +// Affects: Should be without side effects. +#ifdef Status +#ifndef FIXX11H_Status +#define FIXX11H_Status +typedef Status XStatus; +#undef Status +typedef XStatus Status; +#endif +#undef Status +#endif + +// Affects: Should be without side effects. +#ifdef CursorShape +#ifndef FIXX11H_CursorShape +#define FIXX11H_CursorShape +const int XCursorShape = CursorShape; +#undef CursorShape +const int CursorShape = CursorShape; +#endif +#undef CursorShape +#endif + +// template ---> +// Affects: Should be without side effects. +#ifdef CursorShape +#ifndef FIXX11H_CursorShape +#define FIXX11H_CursorShape +const int XCursorShape = CursorShape; +#undef CursorShape +const int CursorShape = XCursorShape; +#endif +#undef CursorShape +#endif +// template <--- + +// template ---> +// Affects: Should be without side effects. +#ifdef FontChange +#ifndef FIXX11H_FontChange +#define FIXX11H_FontChange +const int XFontChange = FontChange; +#undef FontChange +const int FontChange = XFontChange; +#endif +#undef FontChange +#endif +// template <--- + +// Affects: Should be without side effects. +#ifdef NormalState +#ifndef FIXX11H_NormalState +#define FIXX11H_NormalState +const int XNormalState = NormalState; +#undef NormalState +const int NormalState = XNormalState; +#endif +#undef NormalState +#endif + +// template ---> +// Affects: Should be without side effects. +#ifdef index +#ifndef FIXX11H_index +#define FIXX11H_index +inline +const char* Xindex( const char* s, int c ) + { + return index( s, c ); + } +#undef index +inline +const char* index( const char* s, int c ) + { + return Xindex( s, c ); + } +#endif +#undef index +#endif +// template <--- + +#ifdef rindex +// Affects: Should be without side effects. +#ifndef FIXX11H_rindex +#define FIXX11H_rindex +inline +const char* Xrindex( const char* s, int c ) + { + return rindex( s, c ); + } +#undef rindex +inline +const char* rindex( const char* s, int c ) + { + return Xrindex( s, c ); + } +#endif +#undef rindex +#endif +} + +using namespace X; + +#endif diff --git a/src/qtcurve/style/macmenu-dbus.h b/src/qtcurve/style/macmenu-dbus.h new file mode 100644 index 0000000000..f74378eeb1 --- /dev/null +++ b/src/qtcurve/style/macmenu-dbus.h @@ -0,0 +1,51 @@ +/* Bespin mac-a-like XBar KDE4 +Copyright (C) 2007 Thomas Luebking + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License version 2 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef MAC_MENU_ADAPTOR_H +#define MAC_MENU_ADAPTOR_H + +#include +#include "macmenu.h" + +namespace Bespin +{ + +class MacMenuAdaptor : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.XBarClient") + +private: + MacMenu *mm; + +public: + MacMenuAdaptor(MacMenu *macMenu) : QDBusAbstractAdaptor(macMenu), mm(macMenu) { } + +public slots: + Q_NOREPLY void activate() { mm->activate(); } + Q_NOREPLY void deactivate() { mm->deactivate(); } + Q_NOREPLY void popup(qlonglong key, int idx, int x, int y) + { mm->popup(key, idx, x, y); } + Q_NOREPLY void hover(qlonglong key, int idx, int x, int y) + { mm->hover(key, idx, x, y); } + Q_NOREPLY void popDown(qlonglong key) { mm->popDown(key); } + Q_NOREPLY void raise(qlonglong key) { mm->raise(key); } +}; +} // namespace + +#endif //MAC_MENU_ADAPTOR_H diff --git a/src/qtcurve/style/macmenu.cpp b/src/qtcurve/style/macmenu.cpp new file mode 100644 index 0000000000..edf171aa53 --- /dev/null +++ b/src/qtcurve/style/macmenu.cpp @@ -0,0 +1,502 @@ +/* Bespin mac-a-like XBar KDE4 +Copyright (C) 2007 Thomas Luebking + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License version 2 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "macmenu.h" +#include "macmenu-dbus.h" + +#include + +using namespace Bespin; + +static MacMenu *instance = 0; +#define MSG(_FNC_) QDBusMessage::createMethodCall( "org.kde.XBar", "/XBar", "org.kde.XBar", _FNC_ ) +#define XBAR_SEND( _MSG_ ) QDBusConnection::sessionBus().send( _MSG_ ) + +bool +FullscreenWatcher::eventFilter(QObject *o, QEvent *ev) +{ + QWidget *window = qobject_cast(o); + if (!(window && ev->type() == QEvent::WindowStateChange)) + return false; + if (window->windowState() & Qt::WindowFullScreen) + instance->deactivate(window); + else + instance->activate(window); + return false; +} + +static FullscreenWatcher *fullscreenWatcher = 0; + +MacMenu::MacMenu() : QObject() +{ + usingMacMenu = QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.XBar"); + service = QString("org.kde.XBar-%1").arg(QCoreApplication::applicationPid()); + // register me + QDBusConnection::sessionBus().registerService(service); + QDBusConnection::sessionBus().registerObject("/XBarClient", this); + + connect (qApp, SIGNAL(aboutToQuit()), this, SLOT(deactivate())); +} + + +void +MacMenu::manage(QMenuBar *menu) +{ + if (!menu) // ... + return; + + // we only accept menus that are placed on a QMainWindow - for the moment, and probably ever + QWidget *dad = menu->parentWidget(); + if (!(dad && dad->isWindow() && dad->inherits("QMainWindow") && dad->layout() && dad->layout()->menuBar() == menu)) + return; + +// if ((dad = dad->parentWidget()) && dad->inherits("QMdiSubWindow")) +// return; + + + if (!instance) + { + instance = new MacMenu; + /*MacMenuAdaptor *adapt = */new MacMenuAdaptor(instance); + fullscreenWatcher = new FullscreenWatcher; + } + else if (instance->items.contains(menu)) + return; // no double adds please! + + if (instance->usingMacMenu) + instance->activate(menu); + + connect (menu, SIGNAL(destroyed(QObject *)), instance, SLOT(_release(QObject *))); + + instance->items.append(menu); +} + +void +MacMenu::release(QMenuBar *menu) +{ + if (!instance) + return; + instance->_release(menu); +} + +bool +MacMenu::isActive() +{ + return instance && instance->usingMacMenu; +} + +void +MacMenu::_release(QObject *o) +{ + XBAR_SEND( MSG("unregisterMenu") << (qlonglong)o ); + + QMenuBar *menu = qobject_cast(o); + if (!menu) return; + + items.removeAll(menu); + menu->removeEventFilter(this); + QWidget *dad = menu->parentWidget(); + if (dad && dad->layout()) + dad->layout()->setMenuBar(menu); + menu->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + menu->adjustSize(); +// menu->updateGeometry(); +} + +void +MacMenu::activate() +{ + MenuList::iterator menu = items.begin(); + while (menu != items.end()) + { + if (*menu) + { activate(*menu); ++menu; } + else + { actions.remove(*menu); menu = items.erase(menu); } + } + usingMacMenu = true; +} + +void +MacMenu::activate(QMenuBar *menu) +{ + menu->removeEventFilter(this); + + // and WOWWWW - no more per window menubars... + menu->setFixedSize(0,0); + //NOTICE i used to set the menu's parent->layout()->setMenuBar(0) to get rid of the free space + // but this leeds to side effects (e.g. kcalc won't come up anymore...) + // so now the stylehint for the free space below checks the menubar height and returns + // a negative value so that final result will be 1 px heigh... + menu->updateGeometry(); + + // we need to hold a copy of this list to handle action removes + // (as we get the event after the action has been removed from the widget...) + actions[menu] = menu->actions(); + + // find a nice header + QString title = menu->window()->windowTitle(); + const QStringList appArgs = QCoreApplication::arguments(); + QString name = appArgs.isEmpty() ? "" : appArgs.at(0).section('/', -1); + if (title.isEmpty()) + title = name; + else + { + int i = title.indexOf(name, 0, Qt::CaseInsensitive); + if (i > -1) + title = title.mid(i, name.length()); + } + title = title.section(" - ", -1); + if (title.isEmpty()) + { + if (!menu->actions().isEmpty()) + title = menu->actions().at(0)->text(); + if (title.isEmpty()) + title = "QApplication"; + } + + // register the menu via dbus + QStringList entries; + foreach (QAction* action, menu->actions()) + if (action->isSeparator()) + entries << ""; + else + entries << action->text(); + XBAR_SEND( MSG("registerMenu") << service << (qlonglong)menu << title << entries ); + // TODO cause of now async call, the following should - maybe - attached to the above?!! + if (menu->isActiveWindow()) + XBAR_SEND( MSG("requestFocus") << (qlonglong)menu ); + + // take care of several widget events! + menu->installEventFilter(this); + if (menu->window()) + { + menu->window()->removeEventFilter(fullscreenWatcher); + menu->window()->installEventFilter(fullscreenWatcher); + } +} + +void +MacMenu::activate(QWidget *window) +{ + MenuList::iterator menu = items.begin(); + while (menu != items.end()) + { + if (*menu) + { + if ((*menu)->window() == window) + { activate(*menu); return; } + ++menu; + } + else + { actions.remove(*menu); menu = items.erase(menu); } + } +} + +void +MacMenu::deactivate() +{ + usingMacMenu = false; + + MenuList::iterator i = items.begin(); + QMenuBar *menu = 0; + while (i != items.end()) + { + actions.remove(*i); + if ((menu = *i)) + { + deactivate(menu); + ++i; + } + else + i = items.erase(i); + } +} + +void +MacMenu::deactivate(QMenuBar *menu) +{ + menu->removeEventFilter(this); + QWidget *dad = menu->parentWidget(); + if (dad && dad->layout()) + dad->layout()->setMenuBar(menu); + menu->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + menu->adjustSize(); + // menu->updateGeometry(); +} + +void +MacMenu::deactivate(QWidget *window) +{ + MenuList::iterator menu = items.begin(); + while (menu != items.end()) + { + if (*menu) + { + if ((*menu)->window() == window) + { deactivate(*menu); return; } + ++menu; + } + else + { actions.remove(*menu); menu = items.erase(menu); } + } +} + +QMenuBar * +MacMenu::menuBar(qlonglong key) +{ + MenuList::iterator i = items.begin(); + QMenuBar *menu; + while (i != items.end()) + { + if (!(menu = *i)) + { + actions.remove(menu); + i = items.erase(i); + } + else + { + if ((qlonglong)menu == key) + return menu; + else + ++i; + } + } + return NULL; +} + +void +MacMenu::popup(qlonglong key, int idx, int x, int y) +{ + QMenuBar *menu = menuBar(key); + if (!menu) return; + + QMenu *pop; + for (int i = 0; i < menu->actions().count(); ++i) + { + if (!(pop = menu->actions().at(i)->menu())) + continue; + + if (i == idx) { + if (!pop->isVisible()) + { + connect (pop, SIGNAL(aboutToHide()), this, SLOT(menuClosed())); + XBAR_SEND( MSG("setOpenPopup") << idx ); + pop->popup(QPoint(x,y)); + } + else + { + XBAR_SEND( MSG("setOpenPopup") << -1000 ); + pop->hide(); + } + } + else + pop->hide(); + } +} + +void +MacMenu::popDown(qlonglong key) +{ + QMenuBar *menu = menuBar(key); + if (!menu) return; + + QWidget *pop; + for (int i = 0; i < menu->actions().count(); ++i) + { + if (!(pop = menu->actions().at(i)->menu())) + continue; + disconnect (pop, SIGNAL(aboutToHide()), this, SLOT(menuClosed())); + pop->hide(); +// menu->activateWindow(); + break; + } +} + +static bool inHover = false; + +void +MacMenu::hover(qlonglong key, int idx, int x, int y) +{ + QMenuBar *menu = menuBar(key); + if (!menu) return; + + QWidget *pop; + for (int i = 0; i < menu->actions().count(); ++i) + { + if ((i == idx) || !(pop = menu->actions().at(i)->menu())) + continue; + if (pop->isVisible()) + { + inHover = true; + popup(key, idx, x, y); // TODO: this means a useless second pass above... + inHover = false; + break; + } + } +} + +static QMenuBar *bar4menu(QMenu *menu) +{ + if (!menu->menuAction()) + return 0; + if (menu->menuAction()->associatedWidgets().isEmpty()) + return 0; + foreach (QWidget *w, menu->menuAction()->associatedWidgets()) + if (qobject_cast(w)) + return static_cast(w); + return 0; +} + +void +MacMenu::menuClosed() +{ + QObject * _sender = sender(); + + if (!_sender) + return; + + disconnect (sender(), SIGNAL(aboutToHide()), this, SLOT(menuClosed())); + if (!inHover) + { + XBAR_SEND( MSG("setOpenPopup") << -500 ); + + if (QMenu *menu = qobject_cast(_sender)) + if (QMenuBar *bar = bar4menu(menu)) + bar->activateWindow(); + } +} + +void +MacMenu::changeAction(QMenuBar *menu, QActionEvent *ev) +{ + int idx; + const QString title = ev->action()->isSeparator() ? "" : ev->action()->text(); + if (ev->type() == QEvent::ActionAdded) + { + idx = ev->before() ? menu->actions().indexOf(ev->before())-1 : -1; + XBAR_SEND( MSG("addEntry") << (qlonglong)menu << idx << title ); + actions[menu].insert(idx, ev->action()); + return; + } + if (ev->type() == QEvent::ActionChanged) + { + idx = menu->actions().indexOf(ev->action()); + XBAR_SEND( MSG("changeEntry") << (qlonglong)menu << idx << title ); + } + else + { // remove + idx = actions[menu].indexOf(ev->action()); + actions[menu].removeAt(idx); + XBAR_SEND( MSG("removeEntry") << (qlonglong)menu << idx ); + } +} + +void +MacMenu::raise(qlonglong key) +{ + if (QMenuBar *menu = menuBar(key)) + { + if (QWidget *win = menu->window()) + { + win->showNormal(); + win->activateWindow(); + win->raise(); + } + } +} + +bool +MacMenu::eventFilter(QObject *o, QEvent *ev) +{ + QMenuBar *menu = qobject_cast(o); + if (!menu) + return false; + + if (!usingMacMenu) + return false; + + QString func; + switch (ev->type()) + { + case QEvent::Resize: +// menu->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); + if (menu->size() != QSize(0,0)) + { + menu->setFixedSize(0,0); + menu->updateGeometry(); + } + break; + case QEvent::ActionAdded: + case QEvent::ActionChanged: + case QEvent::ActionRemoved: + changeAction(menu, static_cast(ev)); + break; +// case QEvent::ParentChange: +// qDebug() << o << ev; +// return false; + case QEvent::EnabledChange: + if (static_cast(o)->isEnabled()) + XBAR_SEND( MSG("requestFocus") << (qlonglong)menu ); + else + XBAR_SEND( MSG("releaseFocus") << (qlonglong)menu ); + break; + + // TODO: test whether this is the only one and show it? (e.g. what about dialogs...?!) + case QEvent::ApplicationActivate: +// if (items.count() > 1) +// break; + case QEvent::WindowActivate: + XBAR_SEND( MSG("requestFocus") << (qlonglong)menu ); + break; + + case QEvent::WindowDeactivate: +// if (items.count() == 1) +// break; + case QEvent::WindowBlocked: + case QEvent::ApplicationDeactivate: + XBAR_SEND( MSG("releaseFocus") << (qlonglong)menu ); + break; + default: + return false; + +// maybe these need to be passed through...?! +// QEvent::GrabKeyboard +// QEvent::GrabMouse +// QEvent::KeyPress +// QEvent::KeyRelease +// QEvent::UngrabKeyboard +// QEvent::UngrabMouse +// --- and what about these --- +// QEvent::MenubarUpdated +// QEvent::ParentChange +// ------------------- + } + return false; +} + +#undef MSG +#undef XBAR_SEND diff --git a/src/qtcurve/style/macmenu.h b/src/qtcurve/style/macmenu.h new file mode 100644 index 0000000000..b1b1addb01 --- /dev/null +++ b/src/qtcurve/style/macmenu.h @@ -0,0 +1,82 @@ +/* Bespin mac-a-like XBar KDE4 +Copyright (C) 2007 Thomas Luebking + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License version 2 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef MAC_MENU_H +#define MAC_MENU_H + +#include +#include +#include + +class QMenuBar; +class QAction; +class QActionEvent; + + +namespace Bespin +{ + +class FullscreenWatcher : public QObject +{ +public: + FullscreenWatcher() : QObject() {}; +protected: + bool eventFilter(QObject *o, QEvent *ev); +}; + +class MacMenu : public QObject +{ + Q_OBJECT +public: + static void manage(QMenuBar *menu); + static void release(QMenuBar *menu); + static bool isActive(); + void popup(qlonglong key, int idx, int x, int y); + void hover(qlonglong key, int idx, int x, int y); + void popDown(qlonglong key); + void raise(qlonglong key); +public slots: + void activate(); + void deactivate(); +protected: + bool eventFilter(QObject *o, QEvent *ev); +protected: + friend class FullscreenWatcher; + void deactivate(QWidget *window); + void activate(QWidget *window); +private: + Q_DISABLE_COPY(MacMenu) + MacMenu(); + void activate(QMenuBar *menu); + void changeAction(QMenuBar *menu, QActionEvent *ev); + void deactivate(QMenuBar *menu); + typedef QPointer QMenuBar_p; + typedef QList MenuList; + MenuList items; + QMenuBar *menuBar(qlonglong key); + QMap< QMenuBar_p, QList > actions; + bool usingMacMenu; + QString service; +private slots: + void menuClosed(); + void _release(QObject *); +}; + +} // namespace + +#endif //MAC_MENU_H diff --git a/src/qtcurve/style/pixmaps.h b/src/qtcurve/style/pixmaps.h new file mode 100644 index 0000000000..a5b811292a --- /dev/null +++ b/src/qtcurve/style/pixmaps.h @@ -0,0 +1,36 @@ +#ifndef _QEMBED_1804289383 +#define _QEMBED_1804289383 +static const unsigned int check_on_png_len = 179; +static const unsigned char check_on_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x08,0x06,0x00,0x00, + 0x00,0xe0,0x91,0x06,0x10,0x00,0x00,0x00,0x7a,0x49,0x44,0x41,0x54,0x18, + 0x95,0x75,0xce,0x2d,0x0e,0xc2,0x60,0x10,0x84,0xe1,0x87,0x70,0x00,0x0e, + 0x40,0xc2,0x8f,0xe8,0xc1,0xd0,0x08,0xae,0x81,0xc0,0xd5,0x70,0x05,0x2e, + 0xc0,0x39,0xa8,0x03,0x89,0x04,0x51,0x09,0x69,0x41,0x60,0xb6,0xc9,0xa6, + 0xe1,0x1b,0xb5,0x3b,0xfb,0x66,0x76,0x26,0xca,0x5a,0xe1,0x88,0x59,0x09, + 0x58,0xe2,0x8e,0xdb,0x60,0xac,0x51,0x25,0x60,0x8e,0x0b,0xde,0x58,0x0c, + 0xe6,0x13,0x1d,0xf6,0xb1,0xef,0xf0,0x45,0x9d,0xa3,0xb7,0xe8,0xf1,0xc1, + 0x06,0x2d,0x5e,0xff,0x3a,0x1c,0x02,0xea,0x23,0xe5,0x54,0x2a,0xdb,0x04, + 0xd0,0xe5,0x2e,0x63,0x55,0xf1,0xa6,0x19,0x1f,0xa6,0x69,0x6e,0xf1,0xc0, + 0x19,0xd7,0x0c,0xfd,0x00,0x7a,0x3f,0x1a,0x54,0x34,0x8d,0x19,0xdc,0x00, + 0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +/* Generated by qembed */ +static const unsigned int check_x_on_png_len = 154; +static const unsigned char check_x_on_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x08,0x06,0x00,0x00, + 0x00,0xe0,0x91,0x06,0x10,0x00,0x00,0x00,0x61,0x49,0x44,0x41,0x54,0x18, + 0x95,0x6d,0x8f,0x41,0x11,0xc0,0x30,0x08,0x04,0xb7,0x83,0x83,0xea,0x88, + 0xa0,0x88,0xe9,0xb3,0x1a,0xaa,0x01,0x1d,0xd1,0x50,0x41,0xfd,0x5c,0x12, + 0x60,0xca,0xef,0x60,0xe1,0x0e,0x03,0x2e,0xe0,0x01,0x4e,0x60,0xb0,0x6b, + 0xf5,0x0f,0xe0,0x0d,0x03,0x07,0x6e,0x01,0x7d,0x36,0x4d,0x17,0x9a,0x74, + 0x93,0xee,0x71,0xd1,0x64,0x51,0xc1,0x74,0xd9,0x24,0x2a,0x18,0xad,0x99, + 0x50,0xca,0x50,0xac,0x87,0xfd,0x00,0x5e,0x33,0x9a,0xde,0xac,0x16,0x29, + 0x63,0xfc,0x6e,0x65,0x28,0x19,0xfd,0x03,0xc4,0xa9,0x14,0xf0,0x37,0xcf, + 0xd8,0xd2,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +#endif diff --git a/src/qtcurve/style/qtcurve.cpp b/src/qtcurve/style/qtcurve.cpp new file mode 100644 index 0000000000..dea39b343f --- /dev/null +++ b/src/qtcurve/style/qtcurve.cpp @@ -0,0 +1,13918 @@ +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#ifdef Q_WS_X11 +#include +#endif +#include "qtcurve.h" +#include "windowmanager.h" +#include "blurhelper.h" +#include "shortcuthandler.h" +#include "pixmaps.h" +#include +#include "config_file.h" + +// WebKit seems to just use the values from ::pixelMetric to get button sizes. So, in pixelMetric we add some extra padding to PM_ButtonMargin +// if we're max rounding - this gives a nicer border. However, dont want this on real buttons - so in sizeFromContents we remove this padding +// in CT_PushButton and CT_ComboBox +#define MAX_ROUND_BTN_PAD (ROUND_MAX==opts.round ? 3 : 0) + +#ifdef Q_WS_X11 +#include "macmenu.h" +#include "shadowhelper.h" +#include +#include +#include "fixx11h.h" +#include +#include +#endif + +#ifndef QTC_QT_ONLY +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040500 +#include +#endif + +#endif // QTC_QT_ONLY + +// TODO! REMOVE THIS WHEN KDE'S ICON SETTINGS ACTUALLY WORK!!! +#define FIX_DISABLED_ICONS + +#define MO_ARROW_X(MO, COL) (state&State_Enabled \ + ? (MO_NONE!=opts.coloredMouseOver && (MO) \ + ? itsMouseOverCols[ARROW_MO_SHADE] \ + : palette.color(COL)) \ + : palette.color(QPalette::Disabled, COL)) +#define MO_ARROW(COL) MO_ARROW_X(state&State_MouseOver, COL) + +#ifndef QTC_QT_ONLY +typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options); +extern _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook; + +typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); +extern _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook; + +typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); +extern _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook; + +typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); +extern _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook; +#endif + +namespace QtCurve +{ + +#if defined FIX_DISABLED_ICONS && !defined QTC_QT_ONLY +QPixmap getIconPixmap(const QIcon &icon, const QSize &size, QIcon::Mode mode, QIcon::State) +{ + QPixmap pix=icon.pixmap(size, QIcon::Normal); + + if(QIcon::Disabled==mode) + { + QImage img=pix.toImage(); + KIconEffect::toGray(img, 1.0); + KIconEffect::semiTransparent(img); + pix=QPixmap::fromImage(img); + } + + return pix; +} + +#else +inline QPixmap getIconPixmap(const QIcon &icon, const QSize &size, QIcon::Mode mode, QIcon::State state=QIcon::Off) +{ + return icon.pixmap(size, mode, state); +} +#endif +inline QPixmap getIconPixmap(const QIcon &icon, int size, QIcon::Mode mode, QIcon::State state=QIcon::Off) +{ + return getIconPixmap(icon, QSize(size, size), mode, state); +} + +inline QPixmap getIconPixmap(const QIcon &icon, int size, int flags, QIcon::State state=QIcon::Off) +{ + return getIconPixmap(icon, QSize(size, size), flags&QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, state); +} + +inline QPixmap getIconPixmap(const QIcon &icon, const QSize &size, int flags, QIcon::State state=QIcon::Off) +{ + return getIconPixmap(icon, size, flags&QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, state); +} + +static Style::Icon pix2Icon(QStyle::StandardPixmap pix) +{ + switch(pix) + { + case QStyle::SP_TitleBarNormalButton: + return Style::ICN_RESTORE; + case QStyle::SP_TitleBarShadeButton: + return Style::ICN_SHADE; + case QStyle::SP_ToolBarHorizontalExtensionButton: + return Style::ICN_RIGHT; + case QStyle::SP_ToolBarVerticalExtensionButton: + return Style::ICN_DOWN; + case QStyle::SP_TitleBarUnshadeButton: + return Style::ICN_UNSHADE; + default: + case QStyle::SP_DockWidgetCloseButton: + case QStyle::SP_TitleBarCloseButton: + return Style::ICN_CLOSE; + } +} + +static Style::Icon subControlToIcon(QStyle::SubControl sc) +{ + switch(sc) + { + case QStyle::SC_TitleBarMinButton: + return Style::ICN_MIN; + case QStyle::SC_TitleBarMaxButton: + return Style::ICN_MAX; + case QStyle::SC_TitleBarCloseButton: + default: + return Style::ICN_CLOSE; + case QStyle::SC_TitleBarNormalButton: + return Style::ICN_RESTORE; + case QStyle::SC_TitleBarShadeButton: + return Style::ICN_SHADE; + case QStyle::SC_TitleBarUnshadeButton: + return Style::ICN_UNSHADE; + case QStyle::SC_TitleBarSysMenu: + return Style::ICN_MENU; + } +} + +static void drawTbArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton, const QRect &rect, QPainter *painter, + const QWidget *widget = 0) +{ + QStyle::PrimitiveElement pe; + switch (toolbutton->arrowType) + { + case Qt::LeftArrow: + pe = QStyle::PE_IndicatorArrowLeft; + break; + case Qt::RightArrow: + pe = QStyle::PE_IndicatorArrowRight; + break; + case Qt::UpArrow: + pe = QStyle::PE_IndicatorArrowUp; + break; + case Qt::DownArrow: + pe = QStyle::PE_IndicatorArrowDown; + break; + default: + return; + } + + QStyleOption arrowOpt; + arrowOpt.rect = rect; + arrowOpt.palette = toolbutton->palette; + arrowOpt.state = toolbutton->state; + style->drawPrimitive(pe, &arrowOpt, painter, widget); +} + +#define WINDOWTITLE_SPACER 0x10000000 +#define STATE_REVERSE (QStyle::StateFlag)0x10000000 +#define STATE_MENU (QStyle::StateFlag)0x20000000 +#define STATE_VIEW (QStyle::StateFlag)0x40000000 +#define STATE_KWIN_BUTTON (QStyle::StateFlag)0x40000000 +#define STATE_TBAR_BUTTON (QStyle::StateFlag)0x80000000 +#define STATE_DWT_BUTTON (QStyle::StateFlag)0x20000000 +#define STATE_TOGGLE_BUTTON (QStyle::StateFlag)0x10000000 + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static const int constMenuPixmapWidth=22; + +static enum +{ + APP_PLASMA, + APP_KRUNNER, + APP_KWIN, + APP_SYSTEMSETTINGS, + APP_SKYPE, + APP_KONQUEROR, + APP_KONTACT, + APP_ARORA, + APP_REKONQ, + APP_OPERA, + APP_QTDESIGNER, + APP_QTCREATOR, + APP_KDEVELOP, + APP_K3B, + APP_OPENOFFICE, + APP_KONSOLE, + APP_OTHER +} theThemedApp=APP_OTHER; + +static QString appName; + +static inline bool isOOWidget(const QWidget *widget) +{ + return APP_OPENOFFICE==theThemedApp && !widget; +} + +static bool blendOOMenuHighlight(const QPalette &pal, const QColor &highlight) +{ + QColor text(pal.text().color()), + hl(pal.highlightedText().color()); + + return (text.red()<50) && (text.green()<50) && (text.blue()<50) && + (hl.red()>127) && (hl.green()>127) && (hl.blue()>127) && + TOO_DARK(highlight); +} + +int static toHint(int sc) +{ + switch(sc) + { + case QStyle::SC_TitleBarSysMenu: + return Qt::WindowSystemMenuHint; + case QStyle::SC_TitleBarMinButton: + return Qt::WindowMinimizeButtonHint; + case QStyle::SC_TitleBarMaxButton: + return Qt::WindowMaximizeButtonHint; + case QStyle::SC_TitleBarCloseButton: + return 0; + case QStyle::SC_TitleBarNormalButton: + return 0; + case QStyle::SC_TitleBarShadeButton: + case QStyle::SC_TitleBarUnshadeButton: + return Qt::WindowShadeButtonHint; + case QStyle::SC_TitleBarContextHelpButton: + return Qt::WindowContextHelpButtonHint; + default: + return 0; + } +} + +static const char *constBoldProperty="qtc-set-bold"; + +static void setBold(QWidget *widget) +{ + QVariant prop(widget->property(constBoldProperty)); + if(!prop.isValid() || !prop.toBool()) + { + QFont font(widget->font()); + + if(!font.bold()) + { + font.setBold(true); + widget->setFont(font); + widget->setProperty(constBoldProperty, true); + } + } +} + +static void unSetBold(QWidget *widget) +{ + QVariant prop(widget->property(constBoldProperty)); + + if(prop.isValid() && prop.toBool()) + { + QFont font(widget->font()); + + font.setBold(false); + widget->setFont(font); + widget->setProperty(constBoldProperty, false); + } +} + +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT +static QWidget * getActiveWindow(QWidget *widget) +{ + QWidget *activeWindow=QApplication::activeWindow(); + + return activeWindow && activeWindow!=widget ? activeWindow : 0L; +} +#endif + +static void adjustToolbarButtons(const QWidget *widget, const QToolBar *toolbar, int &leftAdjust, int &topAdjust, + int &rightAdjust, int &bottomAdjust, int &round) +{ + const int constAdjust=6; + const int d = 1; + QRect geo(widget->geometry()); + + if (Qt::Horizontal==toolbar->orientation()) + { + bool haveLeft=qobject_cast(toolbar->childAt(geo.x()-d, geo.y())), + haveRight=qobject_cast(toolbar->childAt(geo.right()+d, geo.y())); + + if(haveLeft && haveRight) + leftAdjust=-constAdjust, rightAdjust=constAdjust, round=ROUNDED_NONE; + else if(haveLeft) + leftAdjust=-constAdjust, round=ROUNDED_RIGHT; + else if(haveRight) + rightAdjust=constAdjust, round=ROUNDED_LEFT; + } + else + { + bool haveTop=qobject_cast(toolbar->childAt(geo.x(), geo.y()-d)), + haveBot=qobject_cast(toolbar->childAt(geo.x(), geo.bottom()+d)); + + if(haveTop && haveBot) + topAdjust=-constAdjust, bottomAdjust=constAdjust, round=ROUNDED_NONE; + else if(haveTop) + topAdjust=-constAdjust, round=ROUNDED_BOTTOM; + else if(haveBot) + bottomAdjust=constAdjust, round=ROUNDED_TOP; + } +} + +static const QToolBar * getToolBar(const QWidget *w/*, bool checkQ3*/) +{ + return w + ? qobject_cast(w) // || (checkQ3 && w->inherits("Q3ToolBar")) + ? static_cast(w) + : getToolBar(w->parentWidget()/*, checkQ3*/) + : 0L; +} + +static inline QList getStatusBars(QWidget *w) +{ + return w ? w->findChildren() : QList(); +} + +static QToolBar * getToolBarChild(QWidget *w) +{ + const QObjectList children = w->children(); + + foreach (QObject* child, children) + { + if (child->isWidgetType()) + { + if(qobject_cast(child)) + return static_cast(child); + QToolBar *tb=getToolBarChild((QWidget *) child); + if(tb) + return tb; + } + } + + return 0L; +} + +static void setStyleRecursive(QWidget *w, QStyle *s, int minSize) +{ + w->setStyle(s); + if(qobject_cast(w)) + w->setMinimumSize(1, minSize); + + const QObjectList children = w->children(); + + foreach (QObject *child, children) + { + if (child->isWidgetType()) + setStyleRecursive((QWidget *) child, s, minSize); + } +} + +// +// OK, Etching looks cr*p on plasma widgets, and khtml... +// CPD:TODO WebKit? +static QSet theNoEtchWidgets; + +static bool isA(const QObject *w, const char *type) +{ + return w && (0==strcmp(w->metaObject()->className(), type) || (w->parent() && 0==strcmp(w->parent()->metaObject()->className(), type))); +} + +static bool isInQAbstractItemView(const QObject *w) +{ + int level=8; + + while(w && --level>0) + { + if(qobject_cast(w)) + return true; + if(qobject_cast(w)/* || qobject_cast(w)*/) + return false; + w=w->parent(); + } + + return false; +} + +static bool isKontactPreviewPane(const QWidget *widget) +{ + return APP_KONTACT==theThemedApp && widget && widget->parentWidget() && widget->parentWidget()->parentWidget() && + widget->inherits("KHBox") && ::qobject_cast(widget->parentWidget()) && + widget->parentWidget()->parentWidget()->inherits("KMReaderWin"); +} + +static bool isKateView(const QWidget *widget) +{ + return widget && widget->parentWidget() && ::qobject_cast(widget) && widget->parentWidget()->inherits("KateView"); +} + +static bool isNoEtchWidget(const QWidget *widget) +{ + if(APP_KRUNNER==theThemedApp) + return true; + + if(APP_PLASMA==theThemedApp) + { + const QWidget *top=widget->window(); + + return !top || (!qobject_cast(top) && !qobject_cast(top)); + } + + if(widget && widget->inherits("QWebView")) + return true; + + // KHTML: widget -> QWidget -> QWidget -> KHTMLView + const QObject *w=widget && widget->parent() && widget->parent()->parent() ? widget->parent()->parent()->parent() : 0L; + + return (w && isA(w, "KHTMLView")) || (widget && isInQAbstractItemView(widget->parentWidget())); +} + +static QWidget * scrollViewFrame(QWidget *widget) +{ + QWidget *w=widget; + + for(int i=0; i<10 && w; ++i, w=w->parentWidget()) + { + if( (qobject_cast(w) && ((QFrame *)w)->frameWidth()>0) || qobject_cast(w)) + return w; + } + return 0L; +} + +static QColor checkColour(const QStyleOption *option, QPalette::ColorRole role) +{ + QColor col(option->palette.brush(role).color()); + + if(col.alpha()==255 && IS_BLACK(col)) + return QApplication::palette().brush(role).color(); + return col; +} + +static QColor blendColors(const QColor &foreground, const QColor &background, double alpha) +{ +#if defined QTC_QT_ONLY + return ColorUtils_mix(&background, &foreground, alpha); +#else + return KColorUtils::mix(background, foreground, alpha); +#endif +} + +static void addStripes(QPainter *p, const QPainterPath &path, const QRect &rect, bool horizontal) +{ + QColor col(Qt::white); + QLinearGradient patternGradient(rect.topLeft(), rect.topLeft()+(horizontal ? QPoint(STRIPE_WIDTH, 0) : QPoint(0, STRIPE_WIDTH))); + + col.setAlphaF(0.0); + patternGradient.setColorAt(0.0, col); + col.setAlphaF(0.15); + patternGradient.setColorAt(1.0, col); + patternGradient.setSpread(QGradient::ReflectSpread); + if(path.isEmpty()) + p->fillRect(rect, patternGradient); + else + { + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + p->fillPath(path, patternGradient); + p->restore(); + } +} + +static QRegion windowMask(const QRect &r, bool full) +{ + int x, y, w, h; + r.getRect(&x, &y, &w, &h); + + if(full) + { + QRegion region(x + 4, y + 0, w-4*2, h-0*2); + region += QRegion(x + 0, y + 4, w-0*2, h-4*2); + region += QRegion(x + 2, y + 1, w-2*2, h-1*2); + region += QRegion(x + 1, y + 2, w-1*2, h-2*2); + return region; + } + else + { + QRegion region(x+1, y+1, w-2, h-2); + region += QRegion(x, y+2, w, h-4); + region += QRegion(x+2, y, w-4, h); + return region; + } +} + +enum WindowsStyleConsts +{ + windowsItemFrame = 2, // menu item frame width + windowsSepHeight = 9, // separator item height + windowsItemHMargin = 3, // menu item hor text margin + windowsItemVMargin = 2, // menu item ver text margin + windowsRightBorder = 15, // right border on windows + windowsCheckMarkWidth = 12, // checkmarks width on windows + windowsArrowHMargin = 6 // arrow horizontal margin +}; + +static const int constWindowMargin = 2; +static const int constProgressBarFps = 20; +static const int constTabPad = 6; + +static const QLatin1String constDwtClose("qt_dockwidget_closebutton"); +static const QLatin1String constDwtFloat("qt_dockwidget_floatbutton"); + +#define SB_SUB2 ((QStyle::SubControl)(QStyle::SC_ScrollBarGroove << 1)) + +#ifdef Q_WS_X11 +static bool canAccessId(const QWidget *w) +{ + return w && w->testAttribute(Qt::WA_WState_Created) && w->internalWinId(); +} + +void setOpacityProp(QWidget *w, unsigned short opacity) +{ + if(w && canAccessId(w)) + { + static const Atom constAtom = XInternAtom(QX11Info::display(), OPACITY_ATOM, False); + XChangeProperty(QX11Info::display(), w->window()->winId(), constAtom, XA_CARDINAL, 16, PropModeReplace, (unsigned char *)&opacity, 1); + } +} + +void setBgndProp(QWidget *w, unsigned short app, bool haveBgndImage) +{ + if(w && canAccessId(w)) + { + static const Atom constAtom = XInternAtom(QX11Info::display(), BGND_ATOM, False); + unsigned long prop=((IS_FLAT_BGND(app) ? (unsigned short)(haveBgndImage ? APPEARANCE_RAISED : APPEARANCE_FLAT) : app)&0xFF) | + (w->palette().background().color().rgb()&0x00FFFFFF)<<8; + + XChangeProperty(QX11Info::display(), w->window()->winId(), constAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&prop, 1); + } +} + +void setSbProp(QWidget *w) +{ + if(w && canAccessId(w->window())) + { + static const char * constStatusBarProperty="qtcStatusBar"; + QVariant prop(w->property(constStatusBarProperty)); + + if(!prop.isValid() || !prop.toBool()) + { + static const Atom constAtom = XInternAtom(QX11Info::display(), STATUSBAR_ATOM, False); + + unsigned short s=1; + w->setProperty(constStatusBarProperty, true); + XChangeProperty(QX11Info::display(), w->window()->winId(), constAtom, XA_CARDINAL, 16, PropModeReplace, (unsigned char *)&s, 1); + } + } +} +#endif + +#if defined QTC_QT_ONLY +static void setRgb(QColor *col, const QStringList &rgb) +{ + if(3==rgb.size()) + *col=QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt()); +} +#endif + +#if defined QTC_STYLE_SUPPORT || defined QTC_QT_ONLY +static bool useQt3Settings() +{ + static const char *full = getenv("KDE_FULL_SESSION"); + static const char *vers = full ? getenv("KDE_SESSION_VERSION") : 0; + static bool use = full && (!vers || atoi(vers)<4); + + return use; +} + +static QString kdeHome() +{ + static QString kdeHomePath; + if (kdeHomePath.isEmpty()) + { + kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME")); + if (kdeHomePath.isEmpty()) + { + QDir homeDir(QDir::homePath()); + QString kdeConfDir(QLatin1String("/.kde")); + if (!useQt3Settings() && homeDir.exists(QLatin1String(".kde4"))) + kdeConfDir = QLatin1String("/.kde4"); + kdeHomePath = QDir::homePath() + kdeConfDir; + } + } + return kdeHomePath; +} +#endif + +#ifdef QTC_STYLE_SUPPORT +static void getStyles(const QString &dir, const char *sub, QSet &styles) +{ + QDir d(dir+sub); + + if(d.exists()) + { + QStringList filters; + + filters << QString(THEME_PREFIX"*"THEME_SUFFIX); + d.setNameFilters(filters); + + QStringList entries(d.entryList()); + QStringList::ConstIterator it(entries.begin()), + end(entries.end()); + + for(; it!=end; ++it) + { + QString style((*it).left((*it).lastIndexOf(THEME_SUFFIX))); + + if(!styles.contains(style)) + styles.insert(style); + } + } +} + +static void getStyles(const QString &dir, QSet &styles) +{ + getStyles(dir, THEME_DIR, styles); + getStyles(dir, THEME_DIR4, styles); +} + +static QString themeFile(const QString &dir, const QString &n, const char *sub) +{ + QString name(dir+sub+n+THEME_SUFFIX); + + return QFile(name).exists() ? name : QString(); +} + +static QString themeFile(const QString &dir, const QString &n, bool kde3=false) +{ + QString name(themeFile(dir, n, kde3 ? THEME_DIR : THEME_DIR4)); + + if(name.isEmpty()) + name=themeFile(dir, n, kde3 ? THEME_DIR4 : THEME_DIR); + return name; +} +#endif + +class QtCurveDockWidgetTitleBar : public QWidget +{ + public: + + QtCurveDockWidgetTitleBar(QWidget* parent) : QWidget(parent) { } + virtual ~QtCurveDockWidgetTitleBar() { } + QSize sizeHint() const { return QSize(0, 0); } +}; + +class StylePlugin : public QStylePlugin +{ + public: + + StylePlugin(QObject *parent=0) : QStylePlugin( parent ) {} + ~StylePlugin() {} + + QStringList keys() const + { + QSet styles; + styles.insert("Calibre"); // Changed by Kovid + +#ifdef QTC_STYLE_SUPPORT + getStyles(kdeHome(), styles); + getStyles(KDE_PREFIX(useQt3Settings() ? 3 : 4), styles); + getStyles(KDE_PREFIX(useQt3Settings() ? 4 : 3), styles); +#endif + return styles.toList(); + } + + QStyle * create(const QString &key) + { + return "calibre"==key.toLower() // Changed by Kovid + ? new Style +#ifdef QTC_STYLE_SUPPORT + : 0==key.indexOf(THEME_PREFIX) + ? new Style(key) +#endif + : 0; + } +}; + +Q_EXPORT_PLUGIN2(Style, StylePlugin) + +inline int numButtons(EScrollbar type) +{ + switch(type) + { + default: + case SCROLLBAR_KDE: + return 3; + break; + case SCROLLBAR_WINDOWS: + case SCROLLBAR_PLATINUM: + case SCROLLBAR_NEXT: + return 2; + break; + case SCROLLBAR_NONE: + return 0; + } +} + +static inline void drawRect(QPainter *p, const QRect &r) +{ + p->drawRect(r.x(), r.y(), r.width()-1, r.height()-1); +} + +static inline void drawAaLine(QPainter *p, int x1, int y1, int x2, int y2) +{ + p->drawLine(QLineF(x1+0.5, y1+0.5, x2+0.5, y2+0.5)); +} + +static inline void drawAaPoint(QPainter *p, int x, int y) +{ + p->drawPoint(QPointF(x+0.5, y+0.5)); +} + +static inline void drawAaRect(QPainter *p, const QRect &r) +{ + p->drawRect(QRectF(r.x()+0.5, r.y()+0.5, r.width()-1, r.height()-1)); +} + +static void drawDots(QPainter *p, const QRect &r, bool horiz, int nLines, int offset, + const QColor *cols, int startOffset, int dark) +{ + int space((nLines*2)+(nLines-1)), + x(horiz ? r.x() : r.x()+((r.width()-space)>>1)), + y(horiz ? r.y()+((r.height()-space)>>1) : r.y()), + i, j, + numDots((horiz ? (r.width()-(2*offset))/3 : (r.height()-(2*offset))/3)+1); + + p->setRenderHint(QPainter::Antialiasing, true); + if(horiz) + { + if(startOffset && y+startOffset>0) + y+=startOffset; + + p->setPen(cols[dark]); + for(i=0; isetPen(cols[0]); + for(i=1; i0) + x+=startOffset; + + p->setPen(cols[dark]); + for(i=0; isetPen(cols[0]); + for(i=1; isetRenderHint(QPainter::Antialiasing, false); +} + +static bool isHoriz(const QStyleOption *option, EWidget w, bool joinedTBar) +{ + return option->state&QStyle::State_Horizontal || + (WIDGET_BUTTON(w) && (!joinedTBar || (WIDGET_TOOLBAR_BUTTON!=w && WIDGET_NO_ETCH_BTN!=w && WIDGET_MENU_BUTTON!=w))); +} + +static bool isOnToolbar(const QWidget *widget) +{ + const QWidget *wid=widget ? widget->parentWidget() : 0L; + + while(wid) + { + if(qobject_cast(wid) || wid->inherits("Q3ToolBar")) + return true; + wid=wid->parentWidget(); + } + + return false; +} + +#define PIXMAP_DIMENSION 10 + +/* +Cache key: + widgettype 2 + app 5 + size 15 + horiz 1 + alpha 8 + blue 8 + green 8 + red 8 + type 1 (0 for widget, 1 for pixmap) + ------------ + 56 +*/ +enum ECacheType +{ + CACHE_STD, + CACHE_PBAR, + CACHE_TAB_TOP, + CACHE_TAB_BOT +}; + +static QtcKey createKey(qulonglong size, const QColor &color, bool horiz, int app, EWidget w) +{ + ECacheType type=WIDGET_TAB_TOP==w + ? CACHE_TAB_TOP + : WIDGET_TAB_BOT==w + ? CACHE_TAB_BOT + : WIDGET_PROGRESSBAR==w + ? CACHE_PBAR + : CACHE_STD; + + return (color.rgba()<<1)+ + (((qulonglong)(horiz ? 1 : 0))<<33)+ + (((qulonglong)(size&0xFFFF))<<34)+ + (((qulonglong)(app&0x1F))<<50)+ + (((qulonglong)(type&0x03))<<55); +} + +static QtcKey createKey(const QColor &color, EPixmap p) +{ + return 1+ + ((color.rgb()&RGB_MASK)<<1)+ + (((qulonglong)(p&0x1F))<<33)+ + (((qulonglong)1)<<38); +} + +#if !defined QTC_QT_ONLY +static void parseWindowLine(const QString &line, QList &data) +{ + int len(line.length()); + + for(int i=0; idevice()->devType()) + return static_cast(p->device()); + else + { + QPaintDevice *dev = QPainter::redirected(p->device()); + if (dev && QInternal::Widget==dev->devType()) + return static_cast(dev) ; + } + } + return 0L; +} + +static const QImage * getImage(const QPainter *p) +{ + return p && p->device() && QInternal::Image==p->device()->devType() ? static_cast(p->device()) : 0L; +} + +static const QAbstractButton * getButton(const QWidget *w, const QPainter *p) +{ + const QWidget *widget=w ? w : getWidget(p); + return widget ? ::qobject_cast(widget) : 0L; +} + +inline bool isMultiTabBarTab(const QAbstractButton *button) +{ + // Check for isFlat fails in KDE SC4.5 + return button && ( (::qobject_cast(button) && // ((QPushButton *)button)->isFlat() && + button->inherits("KMultiTabBarTab")) || + (APP_KDEVELOP==theThemedApp && ::qobject_cast(button) && + button->inherits("Sublime::IdealToolButton")) ); +} + +#ifdef QTC_STYLE_SUPPORT +Style::Style(const QString &name) +#else +Style::Style() +#endif + : itsPopupMenuCols(0L), + itsSliderCols(0L), + itsDefBtnCols(0L), + itsComboBtnCols(0L), + itsCheckRadioSelCols(0L), + itsSortedLvColors(0L), + itsOOMenuCols(0L), + itsProgressCols(0L), + itsSaveMenuBarStatus(false), + itsUsePixmapCache(true), + itsInactiveChangeSelectionColor(false), + itsIsPreview(PREVIEW_FALSE), + itsSidebarButtonsCols(0L), + itsActiveMdiColors(0L), + itsMdiColors(0L), + itsPixmapCache(150000), + itsActive(true), + itsSbWidget(0L), + itsClickedLabel(0L), + itsProgressBarAnimateTimer(0), + itsAnimateStep(0), + itsTitlebarHeight(0), + itsPos(-1, -1), + itsHoverWidget(0L), +#ifdef Q_WS_X11 + itsDBus(0), + itsShadowHelper(new ShadowHelper(this)), +#endif + itsSViewSBar(0L), + itsWindowManager(new WindowManager(this)), + itsBlurHelper(new BlurHelper(this)), + itsShortcutHandler(new ShortcutHandler(this)) +#ifdef QTC_STYLE_SUPPORT + , itsName(name) +#endif +{ + const char *env=getenv(QTCURVE_PREVIEW_CONFIG); + if(env && 0==strcmp(env, QTCURVE_PREVIEW_CONFIG)) + { + // To enable preview of QtCurve settings, the style config module will set QTCURVE_PREVIEW_CONFIG + // and use CE_QtC_SetOptions to set options. If this is set, we do not use the QPixmapCache as it + // will interfere with that of the kcm's widgets! + itsIsPreview=PREVIEW_MDI; + itsUsePixmapCache=false; + } + else if(env && 0==strcmp(env, QTCURVE_PREVIEW_CONFIG_FULL)) + { + // As above, but preview is in window - so can use opacity settings! + itsIsPreview=PREVIEW_WINDOW; + itsUsePixmapCache=false; + } + else + init(true); +} + +void Style::init(bool initial) +{ + if(!initial) + freeColors(); + +#if !defined QTC_QT_ONLY + if(initial) + { + if(KGlobal::hasMainComponent()) + itsComponentData=KGlobal::mainComponent(); + else + { + QString name(QApplication::applicationName()); + + if(name.isEmpty()) + name=qAppName(); + + if(name.isEmpty()) + name="QtApp"; + + itsComponentData=KComponentData(name.toLatin1(), name.toLatin1(), KComponentData::SkipMainComponentRegistration); + } + } +#endif + + if(itsIsPreview) + { + if(PREVIEW_WINDOW!=itsIsPreview) + opts.bgndOpacity=opts.dlgOpacity=opts.menuBgndOpacity=100; + } + else + { +#ifdef QTC_STYLE_SUPPORT + QString rcFile; + if(!itsName.isEmpty()) + { + rcFile=themeFile(kdeHome(), itsName); + + if(rcFile.isEmpty()) + { + rcFile=themeFile(KDE_PREFIX(useQt3Settings() ? 3 : 4), itsName, useQt3Settings()); + if(rcFile.isEmpty()) + rcFile=themeFile(KDE_PREFIX(useQt3Settings() ? 4 : 3), itsName, !useQt3Settings()); + } + } + qtcReadConfig(rcFile, &opts); +#else + qtcReadConfig(QString(), &opts); +#endif + +#ifdef Q_WS_X11 + if(initial) + { + QDBusConnection::sessionBus().connect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", + "notifyChange", this, SLOT(kdeGlobalSettingsChange(int, int))); + QDBusConnection::sessionBus().connect("org.kde.kwin", "/KWin", "org.kde.KWin", + "compositingToggled", this, SLOT(compositingToggled())); + + if(!qApp || QString(qApp->argv()[0])!="kwin") + { + QDBusConnection::sessionBus().connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "borderSizesChanged", this, SLOT(borderSizesChanged())); + if(opts.menubarHiding&HIDE_KWIN) + QDBusConnection::sessionBus().connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "toggleMenuBar", this, SLOT(toggleMenuBar(unsigned int))); + + if(opts.statusbarHiding&HIDE_KWIN) + QDBusConnection::sessionBus().connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "toggleStatusBar", this, SLOT(toggleStatusBar(unsigned int))); + } + } +#endif + } + + opts.contrast=QSettings(QLatin1String("Trolltech")).value("/Qt/KDE/contrast", DEFAULT_CONTRAST).toInt(); + if(opts.contrast<0 || opts.contrast>10) + opts.contrast=DEFAULT_CONTRAST; + + shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), itsHighlightCols); + shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Background), itsBackgroundCols); + shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Button), itsButtonCols); + + // Set defaults for Hover and Focus, these will be changed when KDE4 palette is applied... + shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), itsFocusCols); + shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), itsMouseOverCols); +// Dont setup KDE4 fonts/colours here - seems to mess things up when using proxy styles. +// See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638629 +//#if !defined QTC_QT_ONLY +// setupKde4(); +//#endif + + itsWindowManager->initialize(opts.windowDrag, opts.windowDragWhiteList.toList(), opts.windowDragBlackList.toList()); + + switch(opts.shadeSliders) + { + default: + case SHADE_DARKEN: + case SHADE_NONE: + break; + case SHADE_SELECTED: + itsSliderCols=itsHighlightCols; + break; + case SHADE_BLEND_SELECTED: + case SHADE_CUSTOM: + if(!itsSliderCols) + itsSliderCols=new QColor [TOTAL_SHADES+1]; + shadeColors(SHADE_BLEND_SELECTED==opts.shadeSliders + ? midColor(itsHighlightCols[ORIGINAL_SHADE], + itsButtonCols[ORIGINAL_SHADE]) + : opts.customSlidersColor, + itsSliderCols); + } + + switch(opts.defBtnIndicator) + { + case IND_GLOW: + case IND_SELECTED: + itsDefBtnCols=itsHighlightCols; + break; + case IND_TINT: + itsDefBtnCols=new QColor [TOTAL_SHADES+1]; + shadeColors(tint(itsButtonCols[ORIGINAL_SHADE], + itsHighlightCols[ORIGINAL_SHADE], DEF_BNT_TINT), itsDefBtnCols); + break; + default: + break; + case IND_COLORED: + if(SHADE_BLEND_SELECTED==opts.shadeSliders) + itsDefBtnCols=itsSliderCols; + else + { + itsDefBtnCols=new QColor [TOTAL_SHADES+1]; + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], + itsButtonCols[ORIGINAL_SHADE]), itsDefBtnCols); + } + } + + switch(opts.comboBtn) + { + default: + case SHADE_DARKEN: + case SHADE_NONE: + break; + case SHADE_SELECTED: + itsComboBtnCols=itsHighlightCols; + break; + case SHADE_BLEND_SELECTED: + if(opts.shadeSliders==SHADE_BLEND_SELECTED) + { + itsComboBtnCols=itsSliderCols; + break; + } + case SHADE_CUSTOM: + if(opts.shadeSliders==SHADE_CUSTOM && opts.customSlidersColor==opts.customComboBtnColor) + { + itsComboBtnCols=itsSliderCols; + break; + } + if(!itsComboBtnCols) + itsComboBtnCols=new QColor [TOTAL_SHADES+1]; + shadeColors(SHADE_BLEND_SELECTED==opts.comboBtn + ? midColor(itsHighlightCols[ORIGINAL_SHADE], + itsButtonCols[ORIGINAL_SHADE]) + : opts.customComboBtnColor, + itsComboBtnCols); + } + + switch(opts.sortedLv) + { + case SHADE_DARKEN: + if(!itsSortedLvColors) + itsSortedLvColors=new QColor [TOTAL_SHADES+1]; + shadeColors(shade(opts.lvButton ? itsButtonCols[ORIGINAL_SHADE] : itsBackgroundCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), itsSortedLvColors); + break; + default: + case SHADE_NONE: + break; + case SHADE_SELECTED: + itsSortedLvColors=itsHighlightCols; + break; + case SHADE_BLEND_SELECTED: + if(SHADE_BLEND_SELECTED==opts.shadeSliders) + { + itsSortedLvColors=itsSliderCols; + break; + } + else if(SHADE_BLEND_SELECTED==opts.comboBtn) + { + itsSortedLvColors=itsComboBtnCols; + break; + } + case SHADE_CUSTOM: + if(opts.shadeSliders==SHADE_CUSTOM && opts.customSlidersColor==opts.customSortedLvColor) + { + itsSortedLvColors=itsSliderCols; + break; + } + if(opts.comboBtn==SHADE_CUSTOM && opts.customComboBtnColor==opts.customSortedLvColor) + { + itsSortedLvColors=itsComboBtnCols; + break; + } + if(!itsSortedLvColors) + itsSortedLvColors=new QColor [TOTAL_SHADES+1]; + shadeColors(SHADE_BLEND_SELECTED==opts.sortedLv + ? midColor(itsHighlightCols[ORIGINAL_SHADE], + (opts.lvButton ? itsButtonCols[ORIGINAL_SHADE] : itsBackgroundCols[ORIGINAL_SHADE])) + : opts.customSortedLvColor, + itsSortedLvColors); + } + + switch(opts.crColor) + { + default: + case SHADE_NONE: + itsCheckRadioSelCols=itsButtonCols; + break; + case SHADE_DARKEN: + if(!itsCheckRadioSelCols) + itsCheckRadioSelCols=new QColor [TOTAL_SHADES+1]; + shadeColors(shade(itsButtonCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), itsCheckRadioSelCols); + break; + case SHADE_SELECTED: + itsCheckRadioSelCols=itsHighlightCols; + break; + case SHADE_CUSTOM: + if(SHADE_CUSTOM==opts.shadeSliders && opts.customSlidersColor==opts.customCrBgndColor) + itsCheckRadioSelCols=itsSliderCols; + else if(SHADE_CUSTOM==opts.comboBtn && opts.customComboBtnColor==opts.customCrBgndColor) + itsCheckRadioSelCols=itsComboBtnCols; + else if(SHADE_CUSTOM==opts.sortedLv && opts.customSortedLvColor==opts.customCrBgndColor) + itsCheckRadioSelCols=itsSortedLvColors; + else + { + if(!itsCheckRadioSelCols) + itsCheckRadioSelCols=new QColor [TOTAL_SHADES+1]; + shadeColors(opts.customCrBgndColor, itsCheckRadioSelCols); + } + break; + case SHADE_BLEND_SELECTED: + if(SHADE_BLEND_SELECTED==opts.shadeSliders) + itsCheckRadioSelCols=itsSliderCols; + else if(SHADE_BLEND_SELECTED==opts.comboBtn) + itsCheckRadioSelCols=itsComboBtnCols; + else if(SHADE_BLEND_SELECTED==opts.sortedLv) + itsCheckRadioSelCols=itsSortedLvColors; + else + { + if(!itsCheckRadioSelCols) + itsCheckRadioSelCols=new QColor [TOTAL_SHADES+1]; + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsButtonCols[ORIGINAL_SHADE]), itsCheckRadioSelCols); + } + } + + switch(opts.progressColor) + { + case SHADE_NONE: + itsProgressCols=itsBackgroundCols; + break; + default: + // Not set! + break; + case SHADE_CUSTOM: + if(SHADE_CUSTOM==opts.shadeSliders && opts.customSlidersColor==opts.customProgressColor) + itsProgressCols=itsSliderCols; + else if(SHADE_CUSTOM==opts.comboBtn && opts.customComboBtnColor==opts.customProgressColor) + itsProgressCols=itsComboBtnCols; + else if(SHADE_CUSTOM==opts.sortedLv && opts.customSortedLvColor==opts.customProgressColor) + itsProgressCols=itsSortedLvColors; + else if(SHADE_CUSTOM==opts.crColor && opts.customCrBgndColor==opts.customProgressColor) + itsProgressCols=itsCheckRadioSelCols; + else + { + if(!itsProgressCols) + itsProgressCols=new QColor [TOTAL_SHADES+1]; + shadeColors(opts.customProgressColor, itsProgressCols); + } + break; + case SHADE_BLEND_SELECTED: + if(SHADE_BLEND_SELECTED==opts.shadeSliders) + itsProgressCols=itsSliderCols; + else if(SHADE_BLEND_SELECTED==opts.comboBtn) + itsProgressCols=itsComboBtnCols; + else if(SHADE_BLEND_SELECTED==opts.sortedLv) + itsProgressCols=itsSortedLvColors; + else + { + if(!itsProgressCols) + itsProgressCols=new QColor [TOTAL_SHADES+1]; + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsBackgroundCols[ORIGINAL_SHADE]), itsProgressCols); + } + } + + setMenuColors(QApplication::palette().color(QPalette::Active, QPalette::Background)); + + switch(opts.shadeCheckRadio) + { + default: + itsCheckRadioCol=QApplication::palette().color(QPalette::Active, opts.crButton ? QPalette::ButtonText : QPalette::Text); + break; + case SHADE_BLEND_SELECTED: + case SHADE_SELECTED: + itsCheckRadioCol=QApplication::palette().color(QPalette::Active, QPalette::Highlight); + break; + case SHADE_CUSTOM: + itsCheckRadioCol=opts.customCheckRadioColor; + } + + if(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR && opts.titlebarButtonColors.size()>=NUM_TITLEBAR_BUTTONS) + for(int i=0; isetEnabled(100!=opts.bgndOpacity || 100!=opts.dlgOpacity || 100!=opts.menuBgndOpacity); + +#if !defined QTC_QT_ONLY + // Ensure the link to libkio is not stripped, by placing a call to a kio function. + // NOTE: This call will never actually happen, its only here so that the qtcurve.so + // contains a kio link so that this is not removed by some 'optimisation' of the + // link process. + if(itsPos.x()>65534) + (void)KFileDialog::getSaveFileName(); + + // We need to set the decoration colours for the preview now... + if(itsIsPreview) + setDecorationColors(); +#endif +} + +Style::~Style() +{ + freeColors(); +#ifdef Q_WS_X11 + if(itsDBus) + delete itsDBus; +#endif +} + +void Style::freeColor(QSet &freedColors, QColor **cols) +{ + if(!freedColors.contains(*cols) && + *cols!=itsHighlightCols && + *cols!=itsBackgroundCols && + *cols!=itsMenubarCols && + *cols!=itsFocusCols && + *cols!=itsMouseOverCols && + *cols!=itsButtonCols && + *cols!=itsColoredButtonCols && + *cols!=itsColoredBackgroundCols && + *cols!=itsColoredHighlightCols) + { + freedColors.insert(*cols); + delete [] *cols; + } + *cols=0L; +} + +void Style::freeColors() +{ + if(0!=itsProgressBarAnimateTimer) + killTimer(itsProgressBarAnimateTimer); + + QSet freedColors; + + freeColor(freedColors, &itsSidebarButtonsCols); + freeColor(freedColors, &itsPopupMenuCols); + freeColor(freedColors, &itsActiveMdiColors); + freeColor(freedColors, &itsMdiColors); + freeColor(freedColors, &itsProgressCols); + freeColor(freedColors, &itsCheckRadioSelCols); + freeColor(freedColors, &itsSortedLvColors); + freeColor(freedColors, &itsComboBtnCols); + freeColor(freedColors, &itsDefBtnCols); + freeColor(freedColors, &itsSliderCols); + + if(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) + for(int i=0; iargv()[0]); + + if("kwin"==appName) + theThemedApp=APP_KWIN; + else if("systemsettings"==appName) + theThemedApp=APP_SYSTEMSETTINGS; + else if("plasma"==appName || appName.startsWith("plasma-")) + theThemedApp=APP_PLASMA; + else if("krunner"==appName || "krunner_lock"==appName || "kscreenlocker"==appName) + theThemedApp=APP_KRUNNER; + else if("konqueror"==appName) + theThemedApp=APP_KONQUEROR; + else if("kontact"==appName) + theThemedApp=APP_KONTACT; + else if("k3b"==appName) + theThemedApp=APP_K3B; + else if("skype"==appName) + theThemedApp=APP_SKYPE; + else if("arora"==appName) + theThemedApp=APP_ARORA; + else if("rekonq"==appName) + theThemedApp=APP_REKONQ; + else if("Designer"==QCoreApplication::applicationName()) + theThemedApp=APP_QTDESIGNER; + else if("QtCreator"==QCoreApplication::applicationName()) + theThemedApp=APP_QTCREATOR; + else if("kdevelop"==appName || "kdevelop.bin"==appName) + theThemedApp=APP_KDEVELOP; + else if("soffice.bin"==appName) + theThemedApp=APP_OPENOFFICE; + else if("kdmgreet"==appName) + opts.forceAlternateLvCols=false; + else if("konsole"==appName) + theThemedApp=APP_KONSOLE; + else if("Kde4ToolkitLibrary"==appName) + theThemedApp=APP_OPERA; + + if(NULL!=getenv("QTCURVE_DEBUG")) + { + QByteArray l1(appName.toLatin1()); + std::cout << "QtCurve: Application name: \"" << l1.constData() << "\"\n"; + } + + if(APP_REKONQ==theThemedApp) + opts.statusbarHiding=0; + if(opts.menubarHiding) + itsSaveMenuBarStatus=opts.menubarApps.contains("kde") || opts.menubarApps.contains(appName); + if(opts.statusbarHiding) + itsSaveStatusBarStatus=opts.statusbarApps.contains("kde") || opts.statusbarApps.contains(appName); + + if(!IS_FLAT_BGND(opts.bgndAppearance) && opts.noBgndGradientApps.contains(appName)) + opts.bgndAppearance=APPEARANCE_FLAT; + if(IMG_NONE!=opts.bgndImage.type && opts.noBgndImageApps.contains(appName)) + opts.bgndImage.type=IMG_NONE; + if(SHADE_NONE!=opts.menuStripe && opts.noMenuStripeApps.contains(appName)) + opts.menuStripe=SHADE_NONE; + +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + // Plasma and Kate do not like the 'Fix parentless dialogs' option... + if(opts.fixParentlessDialogs && (APP_PLASMA==theThemedApp || opts.noDlgFixApps.contains(appName) || opts.noDlgFixApps.contains("kde"))) + opts.fixParentlessDialogs=false; +#endif + + if((100!=opts.bgndOpacity || 100!=opts.dlgOpacity) && (opts.noBgndOpacityApps.contains(appName) || appName.endsWith(".kss"))) + opts.bgndOpacity=opts.dlgOpacity=100; + if(100!=opts.menuBgndOpacity && opts.noMenuBgndOpacityApps.contains(appName)) + opts.menuBgndOpacity=100; + + if(APP_PLASMA==theThemedApp) + opts.bgndOpacity=100; + else if(APP_KWIN==theThemedApp) + opts.bgndOpacity=opts.dlgOpacity=100, opts.bgndAppearance=APPEARANCE_FLAT; + else if(APP_OPENOFFICE==theThemedApp) + { + opts.scrollbarType=SCROLLBAR_WINDOWS; + if(APPEARANCE_FADE==opts.menuitemAppearance) + opts.menuitemAppearance=APPEARANCE_FLAT; + opts.borderMenuitems=opts.etchEntry=false; + + if(opts.useHighlightForMenu && blendOOMenuHighlight(QApplication::palette(), itsHighlightCols[ORIGINAL_SHADE])) + { + itsOOMenuCols=new QColor [TOTAL_SHADES+1]; + shadeColors(tint(popupMenuCols()[ORIGINAL_SHADE], itsHighlightCols[ORIGINAL_SHADE], 0.5), itsOOMenuCols); + } + opts.menubarHiding=opts.statusbarHiding=HIDE_NONE; + opts.square|=SQUARE_POPUP_MENUS|SQUARE_TOOLTIPS; + if(!IS_FLAT_BGND(opts.menuBgndAppearance) && 0==opts.lighterPopupMenuBgnd) + opts.lighterPopupMenuBgnd=1; // shade so that we dont have 3d-ish borders... + opts.menuBgndAppearance=APPEARANCE_FLAT; + } + +#ifndef QTC_QT_ONLY + if(opts.useQtFileDialogApps.contains(appName)) + { + qt_filedialog_existing_directory_hook=0L; + qt_filedialog_open_filename_hook=0L; + qt_filedialog_open_filenames_hook=0L; + qt_filedialog_save_filename_hook=0L; + } +#endif + + BASE_STYLE::polish(app); + if(opts.hideShortcutUnderline) + Utils::addEventFilter(app, itsShortcutHandler); +} + +void Style::polish(QPalette &palette) +{ + int contrast(QSettings(QLatin1String("Trolltech")).value("/Qt/KDE/contrast", DEFAULT_CONTRAST).toInt()); + bool newContrast(false); + + if(contrast<0 || contrast>10) + contrast=DEFAULT_CONTRAST; + + if(contrast!=opts.contrast) + { + opts.contrast=contrast; + newContrast=true; + } + + bool newHighlight(newContrast || + itsHighlightCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Highlight)), + newGray(newContrast || + itsBackgroundCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Background)), + newButton(newContrast || + itsButtonCols[ORIGINAL_SHADE]!=palette.color(QPalette::Active, QPalette::Button)), + newSlider(itsSliderCols && itsHighlightCols!=itsSliderCols && SHADE_BLEND_SELECTED==opts.shadeSliders && + (newButton || newHighlight)), + newDefBtn(itsDefBtnCols && (IND_COLORED!=opts.defBtnIndicator || SHADE_BLEND_SELECTED!=opts.shadeSliders) && + IND_SELECTED!=opts.defBtnIndicator && IND_GLOW!=opts.defBtnIndicator && + (newContrast || newButton || newHighlight)), + newComboBtn(itsComboBtnCols && itsHighlightCols!=itsComboBtnCols && itsSliderCols!=itsComboBtnCols && + SHADE_BLEND_SELECTED==opts.comboBtn && + (newButton || newHighlight)), + newSortedLv(itsSortedLvColors && ( (SHADE_BLEND_SELECTED==opts.sortedLv && itsDefBtnCols!=itsSortedLvColors && + itsSliderCols!=itsSortedLvColors && itsComboBtnCols!=itsSortedLvColors) || + SHADE_DARKEN==opts.sortedLv) && + (newContrast || (opts.lvButton ? newButton : newGray))), + newCheckRadioSelCols(itsCheckRadioSelCols && ( (SHADE_BLEND_SELECTED==opts.crColor && itsDefBtnCols!=itsCheckRadioSelCols && + itsSliderCols!=itsCheckRadioSelCols && itsComboBtnCols!=itsCheckRadioSelCols && + itsSortedLvColors!=itsCheckRadioSelCols) || + SHADE_DARKEN==opts.crColor) && + (newContrast || newButton)), + newProgressCols(itsProgressCols && SHADE_BLEND_SELECTED==opts.progressColor && + itsSliderCols!=itsProgressCols && itsComboBtnCols!=itsProgressCols && + itsSortedLvColors!=itsProgressCols && itsCheckRadioSelCols!=itsProgressCols && (newContrast || newButton)); + + if(newGray) + { + shadeColors(palette.color(QPalette::Active, QPalette::Background), itsBackgroundCols); + if(IMG_PLAIN_RINGS==opts.bgndImage.type || IMG_BORDERED_RINGS==opts.bgndImage.type || + IMG_SQUARE_RINGS==opts.bgndImage.type || + IMG_PLAIN_RINGS==opts.menuBgndImage.type || IMG_BORDERED_RINGS==opts.menuBgndImage.type || + IMG_SQUARE_RINGS==opts.menuBgndImage.type) + { + qtcCalcRingAlphas(&itsBackgroundCols[ORIGINAL_SHADE]); + if(itsUsePixmapCache) + QPixmapCache::clear(); + } + } + + if(newButton) + shadeColors(palette.color(QPalette::Active, QPalette::Button), itsButtonCols); + + if(newHighlight) + shadeColors(palette.color(QPalette::Active, QPalette::Highlight), itsHighlightCols); + +// Dont set these here, they will be updated in setDecorationColors()... +// shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), itsFocusCols); +// if(opts.coloredMouseOver) +// shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), itsMouseOverCols); + + setMenuColors(palette.color(QPalette::Active, QPalette::Background)); + + if(newSlider) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsButtonCols[ORIGINAL_SHADE]), itsSliderCols); + + if(newDefBtn) + { + if(IND_TINT==opts.defBtnIndicator) + shadeColors(tint(itsButtonCols[ORIGINAL_SHADE], + itsHighlightCols[ORIGINAL_SHADE], DEF_BNT_TINT), itsDefBtnCols); + else if(IND_GLOW!=opts.defBtnIndicator) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], + itsButtonCols[ORIGINAL_SHADE]), itsDefBtnCols); + } + + if(newComboBtn) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsButtonCols[ORIGINAL_SHADE]), itsComboBtnCols); + + if(newSortedLv) + { + if(SHADE_BLEND_SELECTED==opts.sortedLv) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], + opts.lvButton ? itsButtonCols[ORIGINAL_SHADE] : itsBackgroundCols[ORIGINAL_SHADE]), itsSortedLvColors); + else + shadeColors(shade(opts.lvButton ? itsButtonCols[ORIGINAL_SHADE] : itsBackgroundCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), + itsSortedLvColors); + } + + if(itsSidebarButtonsCols && SHADE_BLEND_SELECTED!=opts.shadeSliders && + IND_COLORED!=opts.defBtnIndicator) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], + itsButtonCols[ORIGINAL_SHADE]), itsSidebarButtonsCols); + + switch(opts.shadeCheckRadio) + { + default: + itsCheckRadioCol=palette.color(QPalette::Active, opts.crButton ? QPalette::ButtonText : QPalette::Text); + break; + case SHADE_BLEND_SELECTED: + case SHADE_SELECTED: + itsCheckRadioCol=palette.color(QPalette::Active, QPalette::Highlight); + break; + case SHADE_CUSTOM: + itsCheckRadioCol=opts.customCheckRadioColor; + } + + if(newCheckRadioSelCols) + { + if(SHADE_BLEND_SELECTED==opts.crColor) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsButtonCols[ORIGINAL_SHADE]), itsCheckRadioSelCols); + else + shadeColors(shade(itsButtonCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), itsCheckRadioSelCols); + } + + if(newProgressCols) + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsBackgroundCols[ORIGINAL_SHADE]), itsProgressCols); + + if(APP_OPENOFFICE==theThemedApp && opts.useHighlightForMenu && (newGray || newHighlight)) + { + if(blendOOMenuHighlight(palette, itsHighlightCols[ORIGINAL_SHADE])) + { + if(!itsOOMenuCols) + itsOOMenuCols=new QColor [TOTAL_SHADES+1]; + shadeColors(tint(popupMenuCols()[ORIGINAL_SHADE], itsHighlightCols[ORIGINAL_SHADE], 0.5), itsOOMenuCols); + } + else if(itsOOMenuCols) + { + delete [] itsOOMenuCols; + itsOOMenuCols=0L; + } + } + + palette.setColor(QPalette::Active, QPalette::Light, itsBackgroundCols[0]); + palette.setColor(QPalette::Active, QPalette::Dark, itsBackgroundCols[STD_BORDER]); + palette.setColor(QPalette::Inactive, QPalette::Light, itsBackgroundCols[0]); + palette.setColor(QPalette::Inactive, QPalette::Dark, itsBackgroundCols[STD_BORDER]); + palette.setColor(QPalette::Inactive, QPalette::WindowText, palette.color(QPalette::Active, QPalette::WindowText)); + palette.setColor(QPalette::Disabled, QPalette::Light, itsBackgroundCols[0]); + palette.setColor(QPalette::Disabled, QPalette::Dark, itsBackgroundCols[STD_BORDER]); + + palette.setColor(QPalette::Disabled, QPalette::Base, palette.color(QPalette::Active, QPalette::Background)); + palette.setColor(QPalette::Disabled, QPalette::Background, palette.color(QPalette::Active, QPalette::Background)); + + // Fix KDE4's palette... + if(palette.color(QPalette::Active, QPalette::Highlight)!=palette.color(QPalette::Inactive, QPalette::Highlight)) + itsInactiveChangeSelectionColor=true; + + for(int i=QPalette::WindowText; isetAttribute(Qt::WA_TranslucentBackground); + + #ifdef Q_WS_WIN + //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly + widget->setWindowFlags(widget->windowFlags()|Qt::FramelessWindowHint); + #endif +} + +static QWidget *getParent(QWidget *w, int level) +{ + QWidget *wid=w; + for(int i=0; iparentWidget(); + return wid; +} + +#ifdef QTC_QT_ONLY +static bool parentIs(QWidget *w, int level, const char *className) +{ + QWidget *wid=getParent(w, level); + return wid && wid->inherits(className); +} +#endif + +void Style::polish(QWidget *widget) +{ + if(!widget) + return; + + bool enableMouseOver(opts.highlightFactor || opts.coloredMouseOver); + + /* + { + for(QWidget *w=widget; w; w=w->parentWidget()) + printf("%s ", w->metaObject()->className()); + printf("\n"); + } + */ + + // 'Fix' konqueror's large menubar... + if(!opts.xbar && APP_KONQUEROR==theThemedApp && widget->parentWidget() && qobject_cast(widget) && qobject_cast(widget->parentWidget())) + widget->parentWidget()->setMaximumSize(32768, konqMenuBarSize((QMenuBar *)widget->parentWidget())); + + if(EFFECT_NONE!=opts.buttonEffect && !USE_CUSTOM_ALPHAS(opts) && isNoEtchWidget(widget)) + { + theNoEtchWidgets.insert(static_cast(widget)); + connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } + + itsWindowManager->registerWidget(widget); +#ifdef Q_WS_X11 + itsShadowHelper->registerWidget(widget); +#endif + + // Need to register all widgets to blur helper, in order to have proper blur_behind region set have proper regions removed for opaque widgets. + // Note: that the helper does nothing as long as compositing and ARGB are not enabled + if( (100!=opts.menuBgndOpacity && qobject_cast(widget)) || + (100!=opts.bgndOpacity && (!widget->topLevelWidget() || Qt::Dialog!=(widget->topLevelWidget()->windowFlags() & Qt::WindowType_Mask))) || + (100!=opts.dlgOpacity && (!widget->topLevelWidget() || Qt::Dialog==(widget->topLevelWidget()->windowFlags() & Qt::WindowType_Mask))) ) + itsBlurHelper->registerWidget(widget); + + // Sometimes get background errors with QToolBox (e.g. in Bespin config), and setting WA_StyledBackground seems to + // fix this,.. + if(CUSTOM_BGND || FRAME_SHADED==opts.groupBox || FRAME_FADED==opts.groupBox) + { + switch (widget->windowFlags() & Qt::WindowType_Mask) + { + case Qt::Window: + case Qt::Dialog: + { + // For non-transparent widgets, only need to set WA_StyledBackground - and PE_Widget will be called to + // render background... + widget->setAttribute(Qt::WA_StyledBackground); + + // Hack: stop here if application is of type Plasma + /* + Right now we need to reject window candidates if the application is of type plasma + because it conflicts with some widgets embedded into the SysTray. Ideally one would + rather find a "generic" reason, not to handle them + */ + if(APP_PLASMA==theThemedApp && !widget->inherits("QDialog")) + break; + +#ifdef Q_WS_X11 + Utils::addEventFilter(widget, this); +#endif + int opacity=Qt::Dialog==(widget->windowFlags() & Qt::WindowType_Mask) ? opts.dlgOpacity : opts.bgndOpacity; + +#ifdef Q_WS_X11 + if(APP_KONSOLE==theThemedApp && 100!=opacity && widget->testAttribute(Qt::WA_TranslucentBackground) && + widget->inherits("Konsole::MainWindow")) + { + // Background translucency does not work for konsole :-( + // So, just set titlebar opacity... + setOpacityProp(widget, (unsigned short)opacity); + break; + } + else +#endif + if(100==opacity || !widget->isWindow() || Qt::Desktop==widget->windowType() || widget->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop) || + widget->testAttribute(Qt::WA_TranslucentBackground) || widget->testAttribute(Qt::WA_NoSystemBackground) || + widget->testAttribute(Qt::WA_PaintOnScreen) || widget->inherits("KScreenSaver") || widget->inherits( "QTipLabel") || + widget->inherits( "QSplashScreen") || widget->windowFlags().testFlag(Qt::FramelessWindowHint) || + !(widget->testAttribute(Qt::WA_WState_Created) || widget->internalWinId())) + break; + + // whenever you set the translucency flag, Qt will create a new widget under the hood, replacing the old + // ...unfortunately some properties are lost, among them the window icon. + QIcon icon(widget->windowIcon()); + + setTranslucentBackground(widget); + widget->setWindowIcon(icon); + // WORKAROUND: somehow the window gets repositioned to <1,<1 and thus always appears in the upper left corner + // we just move it faaaaar away so kwin will take back control and apply smart placement or whatever + if(!widget->isVisible()) + { + QWidget *pw=Qt::Dialog==(widget->windowFlags() & Qt::WindowType_Mask) + ? widget->parentWidget() + ? widget->parentWidget()->topLevelWidget() + : QApplication::activeWindow() + : 0L; + + if(pw && pw!=widget) + { + widget->adjustSize(); + widget->move(pw->pos()+QPoint((pw->size().width()-widget->size().width())/2, + (pw->size().height()-widget->size().height())/2)); + } + else + widget->move(900000, 900000); + } + + // PE_Widget is not called for transparent widgets, so need event filter here... + Utils::addEventFilter(widget, this); + itsTransparentWidgets.insert(widget); + connect(widget, SIGNAL(destroyed(QObject *)), SLOT(widgetDestroyed(QObject *))); + break; + } + case Qt::Popup: // we currently don't want that kind of gradient on menus etc + case Qt::Tool: // this we exclude as it is used for dragging of icons etc + default: + break; + } + if(qobject_cast(widget)) + widget->setBackgroundRole(QPalette::NoRole); + + if (widget->autoFillBackground() && widget->parentWidget() && + "qt_scrollarea_viewport"==widget->parentWidget()->objectName() && + widget->parentWidget()->parentWidget() && //grampa + qobject_cast(widget->parentWidget()->parentWidget()) && + widget->parentWidget()->parentWidget()->parentWidget() && // grangrampa + widget->parentWidget()->parentWidget()->parentWidget()->inherits("QToolBox")) + { + widget->parentWidget()->setAutoFillBackground(false); + widget->setAutoFillBackground(false); + } + } + + if(itsIsPreview && qobject_cast(widget)) + widget->setAttribute(Qt::WA_StyledBackground); + + if(opts.menubarHiding && qobject_cast(widget) && static_cast(widget)->menuWidget()) + { + Utils::addEventFilter(widget, this); + if(itsSaveMenuBarStatus) + Utils::addEventFilter(static_cast(widget)->menuWidget(), this); + if(itsSaveMenuBarStatus && qtcMenuBarHidden(appName)) + { + static_cast(widget)->menuWidget()->setHidden(true); +#ifdef Q_WS_X11 + if(BLEND_TITLEBAR || opts.menubarHiding&HIDE_KWIN || opts.windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR) + emitMenuSize(static_cast(widget)->menuWidget(), 0); +#endif + } + } + + if(opts.statusbarHiding && qobject_cast(widget)) + { + QList sb=getStatusBars(widget); + + if(sb.count()) + { + Utils::addEventFilter(widget, this); + QList::ConstIterator it(sb.begin()), + end(sb.end()); + for(; it!=end; ++it) + { + if(itsSaveStatusBarStatus) + Utils::addEventFilter(*it, this); + if(itsSaveStatusBarStatus && qtcStatusBarHidden(appName)) + (*it)->setHidden(true); + } +#ifdef Q_WS_X11 + setSbProp(widget); + emitStatusBarState(sb.first()); +#endif + } + } + + // Enable hover effects in all itemviews + if (QAbstractItemView *itemView = qobject_cast(widget)) + { + QWidget *viewport=itemView->viewport(); + viewport->setAttribute(Qt::WA_Hover); + + if(opts.forceAlternateLvCols && + viewport->autoFillBackground() && // Dolphins Folders panel + //255==viewport->palette().color(itemView->viewport()->backgroundRole()).alpha() && // KFilePlacesView + !widget->inherits("KFilePlacesView") && + // Exclude non-editable combo popup... + !(opts.gtkComboMenus && widget->inherits("QComboBoxListView") && widget->parentWidget() && widget->parentWidget()->parentWidget() && + qobject_cast(widget->parentWidget()->parentWidget()) && + !static_cast(widget->parentWidget()->parentWidget())->isEditable()) && + // Exclude KAboutDialog... +#ifdef QTC_QT_ONLY + !parentIs(widget, 5, "KAboutApplicationDialog") && +#else + !qobject_cast(getParent(widget, 5)) && +#endif + (qobject_cast(widget) || (qobject_cast(widget) && QListView::IconMode!=((QListView *)widget)->viewMode()))) + itemView->setAlternatingRowColors(true); + } + + if(APP_KONTACT==theThemedApp && qobject_cast(widget)) + ((QToolButton *)widget)->setAutoRaise(true); + + if(enableMouseOver && + (qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || +// qobject_cast(widget) || + widget->inherits("QWorkspaceTitleBar") || + widget->inherits("QDockSeparator") || + widget->inherits("QDockWidgetSeparator") || + widget->inherits("Q3DockWindowResizeHandle"))) + widget->setAttribute(Qt::WA_Hover, true); + + if (qobject_cast(widget)) + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + else if (qobject_cast(widget)) + { + if(enableMouseOver) + widget->setAttribute(Qt::WA_Hover, true); + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + if(!opts.gtkScrollViews) + Utils::addEventFilter(widget, this); + } + else if (qobject_cast(widget) && widget->inherits("KFilePlacesView")) + { + if(CUSTOM_BGND) + polishScrollArea(static_cast(widget), true); + Utils::addEventFilter(widget, this); + } + else if (qobject_cast(widget)) + { + if(widget->palette().color(QPalette::Inactive, QPalette::HighlightedText)!=widget->palette().color(QPalette::Active, QPalette::HighlightedText)) + { + QPalette pal(widget->palette()); + pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Active, QPalette::HighlightedText)); + widget->setPalette(pal); + } + + if(opts.boldProgress) + setBold(widget); + Utils::addEventFilter(widget, this); + } + else if (widget->inherits("Q3Header")) + { + widget->setMouseTracking(true); + Utils::addEventFilter(widget, this); + } + else if(opts.highlightScrollViews && widget->inherits("Q3ScrollView")) + { + Utils::addEventFilter(widget, this); + widget->setAttribute(Qt::WA_Hover, true); + } + else if(qobject_cast(widget)) + { +#ifdef Q_WS_X11 + if (opts.xbar && + (!((APP_QTDESIGNER==theThemedApp || APP_KDEVELOP==theThemedApp) && widget->inherits("QDesignerMenuBar")))) + Bespin::MacMenu::manage((QMenuBar *)widget); + + if(BLEND_TITLEBAR || opts.menubarHiding&HIDE_KWIN || opts.windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR) + emitMenuSize(widget, PREVIEW_MDI==itsIsPreview || !widget->isVisible() ? 0 : widget->rect().height()); +#endif + if(CUSTOM_BGND) + widget->setBackgroundRole(QPalette::NoRole); + + widget->setAttribute(Qt::WA_Hover, true); + +// if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars) + Utils::addEventFilter(widget, this); + + setMenuTextColors(widget, true); + } + else if(qobject_cast(widget)) + { + Utils::addEventFilter(widget, this); + if(WM_DRAG_ALL==opts.windowDrag && + ((QLabel *)widget)->textInteractionFlags().testFlag(Qt::TextSelectableByMouse) && + widget->parentWidget() && widget->parentWidget()->parentWidget() && ::qobject_cast(widget->parentWidget()) && +#ifdef QTC_QT_ONLY + widget->parentWidget()->parentWidget()->inherits("KTitleWidget") +#else + ::qobject_cast(widget->parentWidget()->parentWidget()) +#endif + ) + ((QLabel *)widget)->setTextInteractionFlags(((QLabel *)widget)->textInteractionFlags()&~Qt::TextSelectableByMouse); + + } + else if(/*!opts.gtkScrollViews && */qobject_cast(widget)) + { + if(CUSTOM_BGND) + polishScrollArea(static_cast(widget)); + if(!opts.gtkScrollViews && (((QFrame *)widget)->frameWidth()>0)) + Utils::addEventFilter(widget, this); + if(APP_KONTACT==theThemedApp && widget->parentWidget()) + { + QWidget *frame=scrollViewFrame(widget->parentWidget()); + + if(frame) + { + Utils::addEventFilter(frame, this); + itsSViewContainers[frame].insert(widget); + connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + connect(frame, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } + } + } + else if(qobject_cast(widget) && widget->inherits("QPrintPropertiesDialog") && + widget->parentWidget() && widget->parentWidget()->topLevelWidget() && + widget->topLevelWidget() && widget->topLevelWidget()->windowTitle().isEmpty() && + !widget->parentWidget()->topLevelWidget()->windowTitle().isEmpty()) + { + widget->topLevelWidget()->setWindowTitle(widget->parentWidget()->topLevelWidget()->windowTitle()); + } + else if(widget->inherits("QWhatsThat")) + { + QPalette pal(widget->palette()); + QColor shadow(pal.shadow().color()); + + shadow.setAlpha(32); + pal.setColor(QPalette::Shadow, shadow); + widget->setPalette(pal); + widget->setMask(QRegion(widget->rect().adjusted(0, 0, -6, -6))+QRegion(widget->rect().adjusted(6, 6, 0, 0))); + } + else if(qobject_cast(widget) && + widget->parentWidget() && + widget->parentWidget()->parentWidget() && + widget->parentWidget()->parentWidget()->parentWidget() && + qobject_cast(widget->parentWidget()) && + widget->parentWidget()->parentWidget()->inherits("KFileWidget") /*&& + widget->parentWidget()->parentWidget()->parentWidget()->inherits("KFileDialog")*/) + ((QDockWidget *)widget)->setTitleBarWidget(new QtCurveDockWidgetTitleBar(widget)); +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + else if(opts.fixParentlessDialogs && qobject_cast(widget) && widget->windowFlags()&Qt::WindowType_Mask && + (!widget->parentWidget()) /*|| widget->parentWidget()->isHidden())*/) + { + QWidget *activeWindow=getActiveWindow(widget); + + if(activeWindow) + { + itsReparentedDialogs[widget]=widget->parentWidget(); + widget->setParent(activeWindow, widget->windowFlags()); + } + Utils::addEventFilter(widget, this); + } +#endif + else if((!IS_FLAT_BGND(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) && + widget->inherits("QComboBoxPrivateContainer") && !widget->testAttribute(Qt::WA_TranslucentBackground)) + setTranslucentBackground(widget); + + if(widget->inherits("QTipLabel") && !IS_FLAT(opts.tooltipAppearance) && APP_OPERA!=theThemedApp) + { + widget->setBackgroundRole(QPalette::NoRole); + setTranslucentBackground(widget); + } + + if (!widget->isWindow()) + if (QFrame *frame = qobject_cast(widget)) + { + // kill ugly frames... + if (QFrame::Box==frame->frameShape() || QFrame::Panel==frame->frameShape() || QFrame::WinPanel==frame->frameShape()) + frame->setFrameShape(QFrame::StyledPanel); + //else if (QFrame::HLine==frame->frameShape() || QFrame::VLine==frame->frameShape()) + Utils::addEventFilter(widget, this); + +#ifdef QTC_QT_ONLY + if(widget->parent() && widget->parent()->inherits("KTitleWidget")) +#else + if(widget->parent() && qobject_cast(widget->parent())) +#endif + { + if(CUSTOM_BGND) + frame->setAutoFillBackground(false); + else + frame->setBackgroundRole(QPalette::Window); + + QLayout *layout(frame->layout()); + + if(layout) + layout->setMargin(0); + } + + QWidget *p=0L; + + if(opts.gtkComboMenus && widget->parentWidget() && (p=widget->parentWidget()->parentWidget()) && + qobject_cast(p) && !((QComboBox *)(p))->isEditable()) + { + QPalette pal(widget->palette()); + QColor col(popupMenuCols()[ORIGINAL_SHADE]); + + if(!IS_FLAT_BGND(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) + col.setAlphaF(0); + + pal.setBrush(QPalette::Active, QPalette::Base, col); + pal.setBrush(QPalette::Active, QPalette::Window, col); + widget->setPalette(pal); + if(opts.shadePopupMenu) + setMenuTextColors(widget, false); + } + } + + if(qobject_cast(widget)/* && !(widget->parentWidget() && +#ifdef QTC_QT_ONLY + widget->inherits("KMenu") && widget->parentWidget()->inherits("KXmlGuiWindow") +#else + qobject_cast(widget) && qobject_cast(widget->parentWidget()) +#endif + && QLatin1String("QtCurvePreview")==widget->parentWidget()->objectName())*/) + { + if(!IS_FLAT_BGND(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) + { + Utils::addEventFilter(widget, this); + if((100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) && !widget->testAttribute(Qt::WA_TranslucentBackground)) + setTranslucentBackground(widget); + } + if(USE_LIGHTER_POPUP_MENU || opts.shadePopupMenu) + { + QPalette pal(widget->palette()); + + pal.setBrush(QPalette::Active, QPalette::Window, popupMenuCols()[ORIGINAL_SHADE]); + widget->setPalette(pal); + if(opts.shadePopupMenu) + setMenuTextColors(widget, false); + if(IMG_NONE!=opts.menuBgndImage.type) + Utils::addEventFilter(widget, this); + } + } + + if((!IS_FLAT_BGND(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) && + widget->inherits("QComboBoxPrivateContainer")) + { + Utils::addEventFilter(widget, this); + if((100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) && !widget->testAttribute(Qt::WA_TranslucentBackground)) + setTranslucentBackground(widget); + } + + bool parentIsToolbar(false); + + // Using dark menubars - konqueror's combo box texts get messed up. Seems to be when a plain QWidget has widget->setBackgroundRole(QPalette::Window); + // and widget->setAutoFillBackground(false); set (below). These onyl happen if 'parentIsToolbar' - so dont bather detecting this if the widget + // is a plain QWidget + // + // QWidget QComboBoxListView QComboBoxPrivateContainer SearchBarCombo KToolBar KonqMainWindow + // QWidget KCompletionBox KLineEdit SearchBarCombo KToolBar KonqMainWindow + if(strcmp(widget->metaObject()->className(), "QWidget")) + { + QWidget *wid=widget ? widget->parentWidget() : 0L; + + while(wid && !parentIsToolbar) + { + parentIsToolbar=qobject_cast(wid) || wid->inherits("Q3ToolBar"); + wid=wid->parentWidget(); + } + } + + if(APP_QTCREATOR==theThemedApp && qobject_cast(widget) && static_cast(widget)->menuWidget()) + static_cast(widget)->menuWidget()->setStyle(this); + + if(APP_QTCREATOR==theThemedApp && qobject_cast(widget) && +#ifdef QTC_QT_ONLY + widget->inherits("KFileDialog") +#else + qobject_cast(widget) +#endif + ) + { + QToolBar *tb=getToolBarChild(widget); + + if(tb) + { + int size = pixelMetric(PM_ToolBarIconSize); + tb->setIconSize(QSize(size, size)); + tb->setMinimumSize(QSize(size+14, size+14)); + setStyleRecursive(tb, this, size+4); + } + } + + if(parentIsToolbar && (qobject_cast(widget) || qobject_cast(widget))) + widget->setFont(QApplication::font()); + + if (qobject_cast(widget) || widget->inherits("Q3ToolBar") || qobject_cast(widget) || parentIsToolbar) + widget->setBackgroundRole(QPalette::Window); + + if(!IS_FLAT(opts.toolbarAppearance) && parentIsToolbar) + widget->setAutoFillBackground(false); + + if(APP_SYSTEMSETTINGS==theThemedApp && + widget && widget->parentWidget() && widget->parentWidget()->parentWidget() && + qobject_cast(widget) && QFrame::NoFrame!=((QFrame *)widget)->frameShape() && + qobject_cast(widget->parentWidget()) && + qobject_cast(widget->parentWidget()->parentWidget())) + ((QFrame *)widget)->setFrameShape(QFrame::NoFrame); + + if (QLayout *layout = widget->layout()) + { + // explicitely check public layout classes, QMainWindowLayout doesn't work here + if (qobject_cast(layout) +#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) + || qobject_cast(layout) +#endif + || qobject_cast(layout) + || qobject_cast(layout)) + polishLayout(layout); + } + + if( (APP_K3B==theThemedApp && widget->inherits("K3b::ThemedHeader") && qobject_cast(widget)) || + widget->inherits("KColorPatch")) + { + ((QFrame *)widget)->setLineWidth(0); + ((QFrame *)widget)->setFrameShape(QFrame::NoFrame); + } + + if(APP_KDEVELOP==theThemedApp && !opts.stdSidebarButtons && widget->inherits("Sublime::IdealButtonBarWidget") && widget->layout()) + { + widget->layout()->setSpacing(0); + widget->layout()->setMargin(0); + } + +#ifdef Q_WS_X11 + QWidget *window=widget->window(); + + if((100!=opts.bgndOpacity && Qt::Window==(window->windowFlags() & Qt::WindowType_Mask)) || + (100!=opts.dlgOpacity && Qt::Dialog==(window->windowFlags() & Qt::WindowType_Mask)) ) + { + widget->removeEventFilter(this); + Utils::addEventFilter(widget, this); + + if(widget->inherits("KFilePlacesView")) + { + widget->setAutoFillBackground(false); + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + } + } +#endif + +#if !defined QTC_QT_ONLY + // Make file selection button in QPrintDialog appear more KUrlRequester like... + if(qobject_cast(widget) && + widget->parentWidget() && widget->parentWidget()->parentWidget() && widget->parentWidget()->parentWidget()->parentWidget() && + qobject_cast(widget->parentWidget()) && + qobject_cast(widget->parentWidget()->parentWidget()->parentWidget()) && + static_cast(widget)->text()==QLatin1String("...")) + { + static_cast(widget)->setIcon(KIcon("document-open")); + static_cast(widget)->setAutoRaise(false); + } +#endif +} + +#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) +static QFontMetrics styledFontMetrics(const QStyleOption *option, const QWidget *widget) +{ + return option + ? option->fontMetrics + : widget + ? widget->fontMetrics() + : qApp->fontMetrics(); +} + +static int fontHeight(const QStyleOption *option, const QWidget *widget) +{ + return styledFontMetrics(option, widget).height(); +} + +// Taken from skulpture 0.2.3 +void Style::polishFormLayout(QFormLayout *layout) +{ + int widgetSize=-1; + + if (layout->labelAlignment() & Qt::AlignVCenter) + return; + + int addedHeight = -1; + for (int row = 0; row < layout->rowCount(); ++row) + { + QLayoutItem *labelItem = layout->itemAt(row, QFormLayout::LabelRole); + if (!labelItem) + continue; + + QLayoutItem *fieldItem = layout->itemAt(row, QFormLayout::FieldRole); + if (!fieldItem) + continue; + + QWidget *label = labelItem->widget(); + if (!label) + continue; + + int labelHeight; + if (addedHeight < 0) + addedHeight = 4 + 2 * widgetSize; + if (qobject_cast(label)) + labelHeight = label->sizeHint().height() + addedHeight; + else if (qobject_cast(label)) + labelHeight = label->sizeHint().height(); + else + continue; + + int fieldHeight = fieldItem->sizeHint().height(); +#if QT_VERSION < 0x040600 + // work around KIntNumInput::sizeHint() bug + if (fieldItem->widget() && fieldItem->widget()->inherits("KIntNumInput")) + { + fieldHeight -= 2; + fieldItem->widget()->setMaximumHeight(fieldHeight); + } +#endif + /* for large fields, we don't center */ + if (fieldHeight <= 2 * fontHeight(0, label) + addedHeight) + { + if (fieldHeight > labelHeight) + labelHeight = fieldHeight; + } +// else if (verticalTextShift(label->fontMetrics()) & 1) +// labelHeight += 1; + if (qobject_cast(label)) + label->setMinimumHeight(labelHeight); + else + { +#if QT_VERSION >= 0x040602 + label->setMinimumHeight((labelHeight * 4 + 6) / 7); +#else + // QFormLayout determines label size as height * 5 / 4, so revert that + label->setMinimumHeight((labelHeight * 4 + 4) / 5); +#endif + } + } +} + +void Style::polishLayout(QLayout *layout) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) + if (QFormLayout *formLayout = qobject_cast(layout)) + polishFormLayout(formLayout); +#endif + // recurse into layouts + for (int i = 0; i < layout->count(); ++i) + if (QLayout *l = layout->itemAt(i)->layout()) + polishLayout(l); +} +#endif + +// Taken from oxygen! +void Style::polishScrollArea(QAbstractScrollArea *scrollArea, bool isKFilePlacesView) const +{ + if(!scrollArea) + return; + + // HACK: add exception for KPIM transactionItemView, which is an overlay widget and must have filled background. This is a temporary workaround + // until a more robust solution is found. + if(scrollArea->inherits("KPIM::TransactionItemView")) + { + // also need to make the scrollarea background plain (using autofill background) so that optional vertical scrollbar background is not + // transparent either. + // TODO: possibly add an event filter to use the "normal" window background instead of something flat. + scrollArea->setAutoFillBackground(true); + return; + } + + // check frame style and background role + if(QFrame::NoFrame!=scrollArea->frameShape() || QPalette::Window!=scrollArea->backgroundRole()) + return; + + // get viewport and check background role + QWidget *viewport(scrollArea->viewport()); + if(!(viewport && QPalette::Window==viewport->backgroundRole()) && !isKFilePlacesView) + return; + + // change viewport autoFill background. + // do the same for children if the background role is QPalette::Window + viewport->setAutoFillBackground(false); + QList children(viewport->findChildren()); + foreach(QWidget* child, children) + { + if(child->parent() == viewport && QPalette::Window==child->backgroundRole()) + child->setAutoFillBackground(false); + } +} + +void Style::unpolish(QApplication *app) +{ + if(opts.hideShortcutUnderline) + app->removeEventFilter(itsShortcutHandler); + BASE_STYLE::unpolish(app); +} + +void Style::unpolish(QWidget *widget) +{ + if(!widget) + return; + + if(EFFECT_NONE!=opts.buttonEffect && theNoEtchWidgets.contains(widget)) + { + theNoEtchWidgets.remove(static_cast(widget)); + disconnect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } + + itsWindowManager->unregisterWidget(widget); +#ifdef Q_WS_X11 + itsShadowHelper->unregisterWidget(widget); +#endif + itsBlurHelper->unregisterWidget(widget); + unregisterArgbWidget(widget); + + // Sometimes get background errors with QToolBox (e.g. in Bespin config), and setting WA_StyledBackground seems to + // fix this,.. + if(CUSTOM_BGND || FRAME_SHADED==opts.groupBox || FRAME_FADED==opts.groupBox) + { + switch (widget->windowFlags() & Qt::WindowType_Mask) + { + case Qt::Window: + case Qt::Dialog: + widget->removeEventFilter(this); + widget->setAttribute(Qt::WA_StyledBackground, false); + break; + case Qt::Popup: // we currently don't want that kind of gradient on menus etc + case Qt::Tool: // this we exclude as it is used for dragging of icons etc + default: + break; + } + + if(qobject_cast(widget)) + widget->setBackgroundRole(QPalette::Window); + } + + if(itsIsPreview && qobject_cast(widget)) + widget->setAttribute(Qt::WA_StyledBackground, false); + + if(opts.menubarHiding && qobject_cast(widget) && static_cast(widget)->menuWidget()) + { + widget->removeEventFilter(this); + if(itsSaveMenuBarStatus) + static_cast(widget)->menuWidget()->removeEventFilter(this); + } + + if(opts.statusbarHiding && qobject_cast(widget)) + { + QList sb=getStatusBars(widget); + + if(sb.count()) + { + widget->removeEventFilter(this); + if(itsSaveStatusBarStatus) + { + QList::ConstIterator it(sb.begin()), + end(sb.end()); + for(; it!=end; ++it) + (*it)->removeEventFilter(this); + } + } + } + + if(qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || + qobject_cast(widget) || +// qobject_cast(widget) || + widget->inherits("QWorkspaceTitleBar") || + widget->inherits("QDockSeparator") || + widget->inherits("QDockWidgetSeparator") || + widget->inherits("Q3DockWindowResizeHandle")) + widget->setAttribute(Qt::WA_Hover, false); + if (qobject_cast(widget)) + { + widget->setAttribute(Qt::WA_Hover, false); + if(ROUNDED && !opts.flatSbarButtons) + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + if(!opts.gtkScrollViews) + widget->removeEventFilter(this); + } + else if (qobject_cast(widget)) + { + widget->removeEventFilter(this); + if(opts.boldProgress) + unSetBold(widget); + itsProgressBars.remove((QProgressBar *)widget); + } + else if (widget->inherits("Q3Header")) + { + widget->setMouseTracking(false); + widget->removeEventFilter(this); + } + else if(opts.highlightScrollViews && widget->inherits("Q3ScrollView")) + widget->removeEventFilter(this); + else if(qobject_cast(widget)) + { +#ifdef Q_WS_X11 + if(opts.xbar) + Bespin::MacMenu::release((QMenuBar *)widget); +#endif + + widget->setAttribute(Qt::WA_Hover, false); + + if(CUSTOM_BGND) + widget->setBackgroundRole(QPalette::Background); + +// if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars) + widget->removeEventFilter(this); + + if(SHADE_WINDOW_BORDER==opts.shadeMenubars || opts.customMenuTextColor || SHADE_BLEND_SELECTED==opts.shadeMenubars || + SHADE_SELECTED==opts.shadeMenubars || (SHADE_CUSTOM==opts.shadeMenubars &&TOO_DARK(itsMenubarCols[ORIGINAL_SHADE]))) + widget->setPalette(QApplication::palette()); + } + else if(qobject_cast(widget)) + widget->removeEventFilter(this); + else if(/*!opts.gtkScrollViews && */qobject_cast(widget)) + { + if(!opts.gtkScrollViews && (((QFrame *)widget)->frameWidth()>0)) + widget->removeEventFilter(this); + if(APP_KONTACT==theThemedApp && widget->parentWidget()) + { + QWidget *frame=scrollViewFrame(widget->parentWidget()); + + if(frame) + { + if(itsSViewContainers.contains(frame)) + { + itsSViewContainers[frame].remove(widget); + if(0==itsSViewContainers[frame].count()) + { + frame->removeEventFilter(this); + itsSViewContainers.remove(frame); + disconnect(frame, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } + } + } + } + } + else if(qobject_cast(widget) && + ((QDockWidget *)widget)->titleBarWidget() && + dynamic_cast(((QDockWidget *)widget)->titleBarWidget()) && + widget->parentWidget() && + widget->parentWidget()->parentWidget() && + widget->parentWidget()->parentWidget()->parentWidget() && + qobject_cast(widget->parentWidget()) && + widget->parentWidget()->parentWidget()->inherits("KFileWidget") /*&& + widget->parentWidget()->parentWidget()->parentWidget()->inherits("KFileDialog")*/) + { + delete ((QDockWidget *)widget)->titleBarWidget(); + ((QDockWidget *)widget)->setTitleBarWidget(0L); + } +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + else if(opts.fixParentlessDialogs && qobject_cast(widget)) + widget->removeEventFilter(this); +#endif + else if(opts.boldProgress && "CE_CapacityBar"==widget->objectName()) + unSetBold(widget); + + if(widget->inherits("QTipLabel") && !IS_FLAT(opts.tooltipAppearance) && APP_OPERA!=theThemedApp) + { + widget->setAttribute(Qt::WA_PaintOnScreen, false); + widget->setAttribute(Qt::WA_NoSystemBackground, false); + widget->clearMask(); + } + + if (!widget->isWindow()) + if (QFrame *frame = qobject_cast(widget)) + { +// if (QFrame::HLine==frame->frameShape() || QFrame::VLine==frame->frameShape()) + widget->removeEventFilter(this); + +#ifdef QTC_QT_ONLY + if(widget->parent() && widget->parent()->inherits("KTitleWidget")) +#else + if(widget->parent() && qobject_cast(widget->parent())) +#endif + { + if(CUSTOM_BGND) + frame->setAutoFillBackground(true); + else + frame->setBackgroundRole(QPalette::Base); + + QLayout *layout(frame->layout()); + + if(layout) + layout->setMargin(6); + } + + QWidget *p=0L; + + if(opts.gtkComboMenus && widget->parentWidget() && (p=widget->parentWidget()->parentWidget()) && + qobject_cast(p) && !((QComboBox *)(p))->isEditable()) + widget->setPalette(QApplication::palette()); + } + + if(qobject_cast(widget)) + { + widget->removeEventFilter(this); + widget->setAttribute(Qt::WA_PaintOnScreen, false); + widget->setAttribute(Qt::WA_NoSystemBackground, false); + widget->setAttribute(Qt::WA_TranslucentBackground, false); + widget->clearMask(); + + if(USE_LIGHTER_POPUP_MENU || opts.shadePopupMenu) + widget->setPalette(QApplication::palette()); + } + + if((!IS_FLAT_BGND(opts.menuBgndAppearance) || 100!=opts.menuBgndOpacity || !(opts.square&SQUARE_POPUP_MENUS)) && + widget->inherits("QComboBoxPrivateContainer")) + { + widget->removeEventFilter(this); + widget->setAttribute(Qt::WA_PaintOnScreen, false); + widget->setAttribute(Qt::WA_NoSystemBackground, false); + widget->setAttribute(Qt::WA_TranslucentBackground, false); + widget->clearMask(); + } + + if (qobject_cast(widget) || + widget->inherits("Q3ToolBar") || + qobject_cast(widget) || + (widget && qobject_cast(widget->parent()))) + widget->setBackgroundRole(QPalette::Button); +#ifdef Q_WS_X11 + QWidget *window=widget->window(); + + if((100!=opts.bgndOpacity && Qt::Window==(window->windowFlags() & Qt::WindowType_Mask)) || + (100!=opts.dlgOpacity && Qt::Dialog==(window->windowFlags() & Qt::WindowType_Mask)) ) + { + widget->removeEventFilter(this); + } +#endif +} + +// +// QtCurve's menu's have a 2 pixel border all around - but want the top, and left edges to +// active the nearest menu item. Therefore, when we get a mouse event in that region then +// adjsut its position... +static bool updateMenuBarEvent(QMouseEvent *event, QMenuBar *menu) +{ + struct HackEvent : public QMouseEvent + { + bool adjust() + { + if(p.x()<2 || p.y()<2) + { + p=QPoint(p.x()<2 ? p.x()+2 : p.x(), p.y()<2 ? p.y()+2 : p.y()); + g=QPoint(p.x()<2 ? g.x()+2 : g.x(), p.y()<2 ? g.y()+2 : g.y()); + return true; + } + return false; + } + }; + + struct HackedMenu : public QMenuBar + { + void send(QMouseEvent *ev) { event(ev); } + }; + + if(((HackEvent *)event)->adjust()) + { + ((HackedMenu *)menu)->send(event); + return true; + } + return false; +} + +bool Style::eventFilter(QObject *object, QEvent *event) +{ + bool isSViewCont=APP_KONTACT==theThemedApp && itsSViewContainers.contains((QWidget*)object); + + if(::qobject_cast(object) && dynamic_cast(event)) + { + if(updateMenuBarEvent((QMouseEvent *)event, (QMenuBar*)object)) + return true; + } + + if (QEvent::Show==event->type() && qobject_cast(object) && object->inherits("KFilePlacesView")) + { + QWidget *view = ((QAbstractScrollArea *)object)->viewport(); + QPalette palette = view->palette(); + QColor color = ((QWidget *)object)->palette().background().color(); + + if(CUSTOM_BGND) + color.setAlphaF(0.0); + + palette.setColor(view->backgroundRole(), color); + view->setPalette(palette); + object->removeEventFilter(this); + } + + if((!opts.gtkScrollViews && ::qobject_cast(object)) || isSViewCont) + { + QPoint pos; + switch(event->type()) + { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + pos=((QMouseEvent *)event)->pos(); + break; + case QEvent::Wheel: + pos=((QWheelEvent *)event)->pos(); + default: + break; + } + + if(!pos.isNull()) + { + QAbstractScrollArea *area=0L; + QPoint mapped(pos); + + if(isSViewCont) + { + QSet::ConstIterator it(itsSViewContainers[(QWidget *)object].begin()), + end(itsSViewContainers[(QWidget *)object].end()); + + for(; it!=end && !area; ++it) + if((*it)->isVisible()) + { + mapped=(*it)->mapFrom((QWidget *)object, pos); + if((*it)->rect().adjusted(0, 0, 4, 4).contains(mapped)) + area=(QAbstractScrollArea *)(*it); + } + } + else + area=(QAbstractScrollArea *)object; + + if(area) + { + QScrollBar *sbars[2]={area->verticalScrollBar(), area->horizontalScrollBar() }; + + for(int i=0; i<2; ++i) + if(sbars[i]) + { + QRect r(i ? 0 : area->rect().right()-3, i ? area->rect().bottom()-3 : 0, + sbars[i]->rect().width(), sbars[i]->rect().height()); + + if(r.contains(pos) || + (sbars[i]==itsSViewSBar && + (QEvent::MouseMove==event->type() || + QEvent::MouseButtonRelease==event->type()))) + { + if(QEvent::Wheel!=event->type()) + { + struct HackEvent : public QMouseEvent + { + void set(const QPoint &mapped, bool vert) + { + p=QPoint(vert ? 0 : mapped.x(), vert ? mapped.y() : 0); + g=QPoint(g.x()+(vert ? 0 : -3), g.y()+(vert ? -3 : 0)); + } + }; + + ((HackEvent *)event)->set(mapped, 0==i); + } + sbars[i]->event(event); + if(QEvent::MouseButtonPress==event->type()) + itsSViewSBar=sbars[i]; + else if(QEvent::MouseButtonRelease==event->type()) + itsSViewSBar=0L; + return true; + } + } + } + } + } + + switch((int)(event->type())) + { + case QEvent::Timer: + case QEvent::Move: + return false; // just for performance - they can occur really often + case QEvent::Resize: + if(!(opts.square&SQUARE_POPUP_MENUS) && object->inherits("QComboBoxPrivateContainer")) + { + QWidget *widget=static_cast(object); + if(Utils::hasAlphaChannel(widget)) + widget->clearMask(); + else + widget->setMask(windowMask(widget->rect(), opts.round>ROUND_SLIGHT)); + return false; + } +#ifdef Q_WS_X11 + else if((BLEND_TITLEBAR || opts.windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR || opts.menubarHiding&HIDE_KWIN) && + qobject_cast(object)) + { + QResizeEvent *re = static_cast(event); + + if (re->size().height() != re->oldSize().height()) + emitMenuSize((QMenuBar *)object, PREVIEW_MDI==itsIsPreview || !((QMenuBar *)object)->isVisible() + ? 0 : re->size().height()); + } +#endif + break; + case QEvent::ShortcutOverride: + if((opts.menubarHiding || opts.statusbarHiding) && qobject_cast(object)) + { + QMainWindow *window=static_cast(object); + + if(window->isVisible()) + { + if(opts.menubarHiding&HIDE_KEYBOARD && window->menuWidget()) + { + QKeyEvent *k=static_cast(event); + + if(k->modifiers()&Qt::ControlModifier && k->modifiers()&Qt::AltModifier && Qt::Key_M==k->key()) + toggleMenuBar(window); + } + if(opts.statusbarHiding&HIDE_KEYBOARD) + { + QKeyEvent *k=static_cast(event); + + if(k->modifiers()&Qt::ControlModifier && k->modifiers()&Qt::AltModifier && Qt::Key_S==k->key()) + toggleStatusBar(window); + } + } + } + break; + case QEvent::ShowToParent: + if(opts.menubarHiding && itsSaveMenuBarStatus && qobject_cast(object) && + qtcMenuBarHidden(appName)) + static_cast(object)->setHidden(true); + if(opts.statusbarHiding && itsSaveStatusBarStatus && qobject_cast(object) && + qtcStatusBarHidden(appName)) + static_cast(object)->setHidden(true); + break; +#ifdef Q_WS_X11 + case QEvent::PaletteChange: + { + QWidget *widget=qobject_cast(object); + + if(widget && widget->isWindow() && ((widget->windowFlags()&Qt::WindowType_Mask) & (Qt::Window|Qt::Dialog))) + setBgndProp(widget, opts.bgndAppearance, IMG_NONE!=opts.bgndImage.type); + break; + } +#endif + case QEvent::Paint: + { + if(CUSTOM_BGND) + { + QWidget *widget=qobject_cast(object); + + if(widget && widget->testAttribute(Qt::WA_StyledBackground) && + (widget->isWindow() && ((widget->windowFlags()&Qt::WindowType_Mask) & (Qt::Window|Qt::Dialog)) && + widget->testAttribute(Qt::WA_TranslucentBackground))) + { + bool isDialog=qobject_cast(widget); + + if((100!=opts.bgndOpacity && !isDialog) || (100!=opts.dlgOpacity && isDialog) || + !(IS_FLAT_BGND(opts.bgndAppearance)) || IMG_NONE!=opts.bgndImage.type) + { + QPainter p(widget); + p.setClipRegion(static_cast(event)->region()); + drawBackground(&p, widget, isDialog ? BGND_DIALOG : BGND_WINDOW); + } + } + } + + //bool isCombo=false; + if((!IS_FLAT_BGND(opts.menuBgndAppearance) || IMG_NONE!=opts.menuBgndImage.type || 100!=opts.menuBgndOpacity || + !(opts.square&SQUARE_POPUP_MENUS)) && + (qobject_cast(object) || (/*isCombo=*/object->inherits("QComboBoxPrivateContainer")))) + { + QWidget *widget=qobject_cast(object); + QPainter p(widget); + QRect r(widget->rect()); + double radius=MENU_AND_TOOLTIP_RADIUS; + QStyleOption opt; + opt.init(widget); + const QColor *use(popupMenuCols(&opt)); + + p.setClipRegion(static_cast(event)->region()); + if(!opts.popupBorder) + { + p.setRenderHint(QPainter::Antialiasing, true); + p.setPen(use[ORIGINAL_SHADE]); + p.drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius)); + p.setRenderHint(QPainter::Antialiasing, false); + } + if(!(opts.square&SQUARE_POPUP_MENUS)) // && !isCombo) + p.setClipRegion(windowMask(r, opts.round>ROUND_SLIGHT), Qt::IntersectClip); + + // In case the gradient uses alpha, we need to fill with the background colour - this makes it consistent with Gtk. + if(100==opts.menuBgndOpacity) + p.fillRect(r, opt.palette.brush(QPalette::Background)); + drawBackground(&p, widget, BGND_MENU); + if(opts.popupBorder) + { + EGradientBorder border=qtcGetGradient(opts.menuBgndAppearance, &opts)->border; + + p.setClipping(false); + p.setPen(use[STD_BORDER]); + // For now dont round combos - getting weird effects with shadow/clipping in Gtk2 style :-( + if(opts.square&SQUARE_POPUP_MENUS) // || isCombo) + drawRect(&p, r); + else + { + p.setRenderHint(QPainter::Antialiasing, true); + p.drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, radius)); + } + + if(USE_BORDER(border) && APPEARANCE_FLAT!=opts.menuBgndAppearance) + { + QRect ri(r.adjusted(1, 1, -1, -1)); + + p.setPen(use[0]); + if(GB_LIGHT==border) + { + if(opts.square&SQUARE_POPUP_MENUS) // || isCombo) + drawRect(&p, ri); + else + p.drawPath(buildPath(ri, WIDGET_OTHER, ROUNDED_ALL, radius-1.0)); + } + else if(opts.square&SQUARE_POPUP_MENUS) // || isCombo) + { + if(GB_3D!=border) + { + p.drawLine(ri.x(), ri.y(), ri.x()+ri.width()-1, ri.y()); + p.drawLine(ri.x(), ri.y(), ri.x(), ri.y()+ri.height()-1); + } + p.setPen(use[FRAME_DARK_SHADOW]); + p.drawLine(ri.x(), ri.y()+ri.height()-1, ri.x()+ri.width()-1, ri.y()+ri.height()-1); + p.drawLine(ri.x()+ri.width()-1, ri.y(), ri.x()+ri.width()-1, ri.y()+ri.height()-1); + } + else + { + QPainterPath tl, + br; + + buildSplitPath(ri, ROUNDED_ALL, radius-1.0, tl, br); + if(GB_3D!=border) + p.drawPath(tl); + p.setPen(use[FRAME_DARK_SHADOW]); + p.drawPath(br); + } + } + } + } + else if(itsClickedLabel==object && qobject_cast(object) && ((QLabel *)object)->buddy() && ((QLabel *)object)->buddy()->isEnabled()) + { + // paint focus rect + QLabel *lbl = (QLabel *)object; + QPainter painter(lbl); + QStyleOptionFocusRect opts; + + opts.palette = lbl->palette(); + opts.rect = QRect(0, 0, lbl->width(), lbl->height()); + drawPrimitive(PE_FrameFocusRect, &opts, &painter, lbl); + } + else + { + QFrame *frame = qobject_cast(object); + + if (frame) + { + if(QFrame::HLine==frame->frameShape() || QFrame::VLine==frame->frameShape()) + { + QPainter painter(frame); + QRect r(QFrame::HLine==frame->frameShape() + ? QRect(frame->rect().x(), frame->rect().y()+ (frame->rect().height()/2), frame->rect().width(), 1) + : QRect(frame->rect().x()+(frame->rect().width()/2), frame->rect().y(), 1, frame->rect().height())); + + drawFadedLine(&painter, r, backgroundColors(frame->palette().window().color())[STD_BORDER], true, true, + QFrame::HLine==frame->frameShape()); + return true; + } + else + return false; + } + } + break; + } + case QEvent::MouseButtonPress: + if(dynamic_cast(event) && qobject_cast(object) && ((QLabel *)object)->buddy()) + { + QLabel *lbl = (QLabel *)object; + QMouseEvent *mev = (QMouseEvent *)event; + + if (lbl->rect().contains(mev->pos())) + { + itsClickedLabel=lbl; + lbl->repaint(); + } + } + break; + case QEvent::MouseButtonRelease: + if(dynamic_cast(event) && qobject_cast(object) && ((QLabel *)object)->buddy()) + { + QLabel *lbl = (QLabel *)object; + QMouseEvent *mev = (QMouseEvent *)event; + + if(itsClickedLabel) + { + itsClickedLabel=0; + lbl->update(); + } + + // set focus to the buddy... + if (lbl->rect().contains(mev->pos())) + ((QLabel *)object)->buddy()->setFocus(Qt::ShortcutFocusReason); + } + break; + case QEvent::StyleChange: + case QEvent::Show: + { + QProgressBar *bar = qobject_cast(object); + + if(bar) + { + itsProgressBars.insert(bar); + if (1==itsProgressBars.size()) + { + itsTimer.start(); + itsProgressBarAnimateTimer = startTimer(1000 / constProgressBarFps); + } + } + else if(!(opts.square&SQUARE_POPUP_MENUS) && object->inherits("QComboBoxPrivateContainer")) + { + QWidget *widget=static_cast(object); + if(Utils::hasAlphaChannel(widget)) + widget->clearMask(); + else + widget->setMask(windowMask(widget->rect(), opts.round>ROUND_SLIGHT)); + return false; + } +#ifdef Q_WS_X11 + else if((BLEND_TITLEBAR || opts.windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR || opts.menubarHiding&HIDE_KWIN) && + qobject_cast(object)) + { + QMenuBar *mb=(QMenuBar *)object; + emitMenuSize((QMenuBar *)mb, PREVIEW_MDI==itsIsPreview || !((QMenuBar *)mb)->isVisible() ? 0 : mb->size().height(), true); + } + else if(QEvent::Show==event->type()) + { + QWidget *widget=qobject_cast(object); + + if(widget && widget->isWindow() && ((widget->windowFlags()&Qt::WindowType_Mask) & (Qt::Window|Qt::Dialog))) + { + setBgndProp(widget, opts.bgndAppearance, IMG_NONE!=opts.bgndImage.type); + + int opacity=Qt::Dialog==(widget->windowFlags() & Qt::WindowType_Mask) ? opts.dlgOpacity : opts.bgndOpacity; + setOpacityProp(widget, (unsigned short)opacity); + } + } +#endif + break; + } + case QEvent::Destroy: + case QEvent::Hide: + { +#ifdef Q_WS_X11 + if((BLEND_TITLEBAR || opts.windowBorder&WINDOW_BORDER_USE_MENUBAR_COLOR_FOR_TITLEBAR || opts.menubarHiding&HIDE_KWIN) && + qobject_cast(object)) + { + QMenuBar *mb=(QMenuBar *)object; + emitMenuSize((QMenuBar *)mb, 0); + } +#endif + if(itsHoverWidget && object==itsHoverWidget) + { + itsPos.setX(-1); + itsPos.setY(-1); + itsHoverWidget=0L; + } + + // The Destroy event is sent from ~QWidget, which happens after ~QProgressBar - therefore, we can't cast to a QProgressBar. + // So we have to check on object. + if(object && !itsProgressBars.isEmpty()) + { + itsProgressBars.remove(reinterpret_cast(object)); + if (itsProgressBars.isEmpty()) + { + killTimer(itsProgressBarAnimateTimer); + itsProgressBarAnimateTimer = 0; + } + } +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + if(opts.fixParentlessDialogs && qobject_cast(object) && itsReparentedDialogs.contains((QWidget*)object)) + { + QWidget *widget=(QWidget*)object; + + // OK, reset back to its original parent.. + if(widget->windowFlags()&Qt::WindowType_Mask) + { + widget->removeEventFilter(this); + widget->setParent(itsReparentedDialogs[widget]); + Utils::addEventFilter(widget, this); + } + itsReparentedDialogs.remove(widget); + } +#endif + break; + } + case QEvent::Enter: + if(object->isWidgetType() && object->inherits("Q3Header")) + { + itsHoverWidget=(QWidget *)object; + + if(itsHoverWidget && !itsHoverWidget->isEnabled()) + itsHoverWidget=0L; + } + break; + case QEvent::Leave: + if(itsHoverWidget && object==itsHoverWidget) + { + itsPos.setX(-1); + itsPos.setY(-1); + itsHoverWidget=0L; + ((QWidget *)object)->repaint(); + } + break; + case QEvent::MouseMove: // Only occurs for widgets with mouse tracking enabled + { + QMouseEvent *me = dynamic_cast(event); + + if(me && itsHoverWidget && object->isWidgetType() && object->inherits("Q3Header")) + { + if(!me->pos().isNull() && me->pos()!=itsPos) + itsHoverWidget->repaint(); + itsPos=me->pos(); + } + break; + } + case QEvent::FocusIn: + case QEvent::FocusOut: + if(opts.highlightScrollViews && object->isWidgetType() && object->inherits("Q3ScrollView")) + { + ((QWidget *)object)->update(); + return false; + } + break; + case QEvent::WindowActivate: + if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars && qobject_cast(object)) + { + itsActive=true; + ((QWidget *)object)->repaint(); + return false; + } + break; + case QEvent::WindowDeactivate: + if(opts.shadeMenubarOnlyWhenActive && SHADE_NONE!=opts.shadeMenubars && qobject_cast(object)) + { + itsActive=false; + ((QWidget *)object)->repaint(); + return false; + } + break; +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + case 70: // QEvent::ChildInserted - QT3_SUPPORT + if(opts.fixParentlessDialogs && qobject_cast(object)) + { + QDialog *dlg=(QDialog *)object; + + // The parent->isHidden is needed for KWord. It's insert picture file dialog is a child of the insert picture dialog - but the file + // dialog is shown *before* the picture dialog! + if(dlg && dlg->windowFlags()&Qt::WindowType_Mask && (!dlg->parentWidget() || dlg->parentWidget()->isHidden())) + { + QWidget *activeWindow=getActiveWindow((QWidget *)object); + + if(activeWindow) + { + dlg->removeEventFilter(this); + dlg->setParent(activeWindow, dlg->windowFlags()); + dlg->installEventFilter(this); + itsReparentedDialogs[(QWidget *)dlg]=dlg->parentWidget(); + return false; + } + } + } +#endif + default: + break; + } + + return BASE_STYLE::eventFilter(object, event); +} + +void Style::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == itsProgressBarAnimateTimer) + { + itsAnimateStep = itsTimer.elapsed() / (1000 / constProgressBarFps); + foreach (QProgressBar *bar, itsProgressBars) + if ((opts.animatedProgress && 0==itsAnimateStep%2 && bar->value()!=bar->minimum() && bar->value()!=bar->maximum()) || + (0==bar->minimum() && 0==bar->maximum())) + bar->update(); + } + + event->ignore(); +} + +int Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +{ + switch((int)metric) + { + case PM_ToolTipLabelFrameWidth: + return !ROUNDED || opts.square&SQUARE_TOOLTIPS ? BASE_STYLE::pixelMetric(metric, option, widget) : 3; + case PM_MdiSubWindowFrameWidth: + return 3; + case PM_DockWidgetTitleMargin: + return !(opts.dwtSettings&DWT_TEXT_ALIGN_AS_PER_TITLEBAR) || ALIGN_LEFT==opts.titlebarAlignment ? 4 : 0; + case PM_DockWidgetTitleBarButtonMargin: + return 4; + case PM_DockWidgetFrameWidth: + return 2; + case PM_ToolBarExtensionExtent: + return 15; +#ifdef QTC_QT_ONLY + case PM_SmallIconSize: + return 16; + case PM_ToolBarIconSize: + return 22; + case PM_IconViewIconSize: + case PM_LargeIconSize: + return 32; +#else +#if QT_VERSION >= 0x040500 + case PM_TabCloseIndicatorWidth: + case PM_TabCloseIndicatorHeight: +#endif + case PM_SmallIconSize: + case PM_ButtonIconSize: + return KIconLoader::global()->currentSize(KIconLoader::Small); + case PM_ToolBarIconSize: + return KIconLoader::global()->currentSize(KIconLoader::Toolbar); + case PM_IconViewIconSize: + case PM_LargeIconSize: + return KIconLoader::global()->currentSize(KIconLoader::Dialog); + case PM_MessageBoxIconSize: + // TODO return KIconLoader::global()->currentSize(KIconLoader::MessageBox); + return KIconLoader::SizeHuge; +#endif +#if QT_VERSION >= 0x040500 + case PM_SubMenuOverlap: + return -2; + case PM_ScrollView_ScrollBarSpacing: +#else + case PM_TextCursorWidth+3: +#endif + return opts.etchEntry ? 2 : 3; + case PM_MenuPanelWidth: + return opts.popupBorder ? pixelMetric(PM_DefaultFrameWidth, option, widget) : 0; + case PM_SizeGripSize: + return SIZE_GRIP_SIZE; + case PM_TabBarScrollButtonWidth: + return 18; + case PM_HeaderMargin: + return 3; + case PM_DefaultChildMargin: + return isOOWidget(widget) + ? /*opts.round>=ROUND_FULL && !(opts.square&SQUARE_SCROLLVIEW) + ?*/ 2 + /*: 1*/ + : 6; + case PM_DefaultTopLevelMargin: + return 9; + case PM_LayoutHorizontalSpacing: + case PM_LayoutVerticalSpacing: + return -1; // use layoutSpacingImplementation + case PM_DefaultLayoutSpacing: + return 6; + case PM_LayoutLeftMargin: + case PM_LayoutTopMargin: + case PM_LayoutRightMargin: + case PM_LayoutBottomMargin: + return pixelMetric((option && (option->state&QStyle::State_Window)) || (widget && widget->isWindow()) + ? PM_DefaultTopLevelMargin + : PM_DefaultChildMargin, option, widget); + case PM_MenuBarItemSpacing: + return 0; + case PM_ToolBarItemMargin: + return 0; + case PM_ToolBarItemSpacing: + return TBTN_JOINED==opts.tbarBtns ? 0 : 1; + case PM_ToolBarFrameWidth: + // Remove because, in KDE4 at least, if have two locked toolbars together then the last/first items are too close + return /*TB_NONE==opts.toolbarBorders ? 0 : */1; + case PM_FocusFrameVMargin: + case PM_FocusFrameHMargin: + return 2; + case PM_MenuBarVMargin: + case PM_MenuBarHMargin: + // Bangarang (media player) has a 4 pixel high menubar at the top - when it doesn't actually have a menubar! + // Seems to be because of the return 2 below (which was previously always returned unless XBar support and + // size was 0). So, if we are askes for these metrics for a widet whose size<6, then return 0. + return widget && widget->size().height() < 6 ? 0 : 2; + case PM_MenuHMargin: + case PM_MenuVMargin: + return 0; + case PM_MenuButtonIndicator: + return (DO_EFFECT ? 10 : 9)+ + (!widget || qobject_cast(widget) ? 6 : 0); + case PM_ButtonMargin: + return (DO_EFFECT + ? (opts.thin&THIN_BUTTONS) ? 4 : 6 + : (opts.thin&THIN_BUTTONS) ? 2 : 4)+MAX_ROUND_BTN_PAD; + case PM_TabBarTabShiftVertical: +#if QT_VERSION < 0x040500 + if (const QStyleOptionTab *tab = qstyleoption_cast(option)) + { + if((QTabBar::RoundedSouth==tab->shape || QTabBar::TriangularSouth==tab->shape)) + return -2; + } +#endif + return 2; + case PM_TabBarTabShiftHorizontal: + return 0; + case PM_ButtonShiftHorizontal: + // return Qt::RightToLeft==QApplication::layoutDirection() ? -1 : 1; + case PM_ButtonShiftVertical: + return APP_KDEVELOP==theThemedApp && !opts.stdSidebarButtons && widget && isMultiTabBarTab(getButton(widget, 0L)) ? 0 : 1; + case PM_ButtonDefaultIndicator: + return 0; + case PM_DefaultFrameWidth: + if ((/*!opts.popupBorder || */opts.gtkComboMenus) && widget && widget->inherits("QComboBoxPrivateContainer")) + return opts.gtkComboMenus ? (opts.borderMenuitems || !(opts.square&SQUARE_POPUP_MENUS) ? 2 : 1) : 0; + + if ((!opts.gtkScrollViews || (opts.square&SQUARE_SCROLLVIEW)) && isKateView(widget)) + return (opts.square&SQUARE_SCROLLVIEW) ? 1 : 0; + + if ((opts.square&SQUARE_SCROLLVIEW) && widget && !opts.etchEntry && + (::qobject_cast(widget) || isKontactPreviewPane(widget) || widget->inherits("Q3ScrollView"))) + return (opts.gtkScrollViews || opts.thinSbarGroove || !opts.borderSbarGroove) && (!opts.highlightScrollViews) ? 1 : 2; + + if (!DRAW_MENU_BORDER && !opts.borderMenuitems && opts.square&SQUARE_POPUP_MENUS && qobject_cast(widget)) + return 1; + + if(DO_EFFECT && opts.etchEntry && + (!widget || // !isFormWidget(widget) && + ::qobject_cast(widget) || ::qobject_cast(widget) || + widget->inherits("Q3ScrollView") /*|| isKontactPreviewPane(widget)*/)) + return 3; + else + return 2; + case PM_SpinBoxFrameWidth: + return DO_EFFECT && opts.etchEntry ? 3 : 2; + case PM_IndicatorWidth: + case PM_IndicatorHeight: + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + case PM_CheckListControllerSize: + case PM_CheckListButtonSize: + return DO_EFFECT ? opts.crSize+2 : opts.crSize; + case PM_TabBarTabOverlap: + return TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1; + case PM_ProgressBarChunkWidth: + return 4; +// case PM_DockWindowHandleExtent: +// return 10; + case PM_DockWidgetSeparatorExtent: + case PM_SplitterWidth: + return LINE_1DOT==opts.splitters ? 7 : 6; + case PM_ToolBarHandleExtent: + return LINE_1DOT==opts.handles ? 7 : 8; + case PM_ScrollBarSliderMin: + return opts.sliderWidth+1; + case PM_SliderThickness: + return (SLIDER_CIRCULAR==opts.sliderStyle + ? CIRCULAR_SLIDER_SIZE+6 + : SLIDER_TRIANGULAR==opts.sliderStyle + ? 19 + : (SLIDER_SIZE+(ROTATED_SLIDER ? 11 : 6)))+SLIDER_GLOW; + case PM_SliderControlThickness: + return (SLIDER_CIRCULAR==opts.sliderStyle + ? CIRCULAR_SLIDER_SIZE + : SLIDER_TRIANGULAR==opts.sliderStyle + ? 11 + : (SLIDER_SIZE+(ROTATED_SLIDER ? 6 : -2)))+SLIDER_GLOW; + case PM_SliderTickmarkOffset: + return SLIDER_TRIANGULAR==opts.sliderStyle ? 5 : 4; + case PM_SliderSpaceAvailable: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + { + int size(pixelMetric(PM_SliderControlThickness, slider, widget)); + + if (slider->tickPosition & QSlider::TicksBelow) + ++size; + if (slider->tickPosition & QSlider::TicksAbove) + ++size; + return size; + } + return BASE_STYLE::pixelMetric(metric, option, widget); + case PM_SliderLength: + return (SLIDER_CIRCULAR==opts.sliderStyle + ? CIRCULAR_SLIDER_SIZE + : SLIDER_TRIANGULAR==opts.sliderStyle + ? 11 + : (SLIDER_SIZE+(ROTATED_SLIDER ? -2 : 6)))+SLIDER_GLOW; + case PM_ScrollBarExtent: + return opts.sliderWidth; + case PM_MaximumDragDistance: + return -1; + case PM_TabBarTabHSpace: + return 14; + case PM_TabBarTabVSpace: + return opts.highlightTab ? 10 : 8; + case PM_TitleBarHeight: + return qMax(widget ? widget->fontMetrics().lineSpacing() + : option ? option->fontMetrics.lineSpacing() + : 0, 24); + case PM_MenuBarPanelWidth: + return 0; + case QtC_Round: + return (int)((opts.square&SQUARE_WINDOWS && opts.round>ROUND_SLIGHT) ? ROUND_SLIGHT : opts.round); + case QtC_WindowBorder: + return opts.windowBorder; + case QtC_CustomBgnd: + return CUSTOM_BGND; + case QtC_TitleBarButtonAppearance: + return (int)opts.titlebarButtonAppearance; + case QtC_TitleAlignment: + switch(opts.titlebarAlignment) + { + default: + case ALIGN_LEFT: + return Qt::AlignLeft; + case ALIGN_CENTER: + return Qt::AlignHCenter|Qt::AlignVCenter; + case ALIGN_FULL_CENTER: + return Qt::AlignHCenter; + case ALIGN_RIGHT: + return Qt::AlignRight; + } + case QtC_TitleBarButtons: + return opts.titlebarButtons; + case QtC_TitleBarIcon: + return opts.titlebarIcon; + case QtC_TitleBarIconColor: + return titlebarIconColor(option).rgb(); + case QtC_TitleBarEffect: + return opts.titlebarEffect; + case QtC_BlendMenuAndTitleBar: + return BLEND_TITLEBAR; + case QtC_ShadeMenubarOnlyWhenActive: + return opts.shadeMenubarOnlyWhenActive; + case QtC_ToggleButtons: + return (opts.menubarHiding&HIDE_KWIN ? 0x1 : 0)+ + (opts.statusbarHiding&HIDE_KWIN ? 0x2 : 0); + case QtC_MenubarColor: + return itsMenubarCols[ORIGINAL_SHADE].rgb(); + case QtC_TitleBarApp: + return !option || option->state&State_Active ? opts.titlebarAppearance : opts.inactiveTitlebarAppearance; +// The following is a somewhat hackyish fix for konqueror's show close button on tab setting... +// ...its hackish in the way that I'm assuming when KTabBar is positioning the close button and it +// asks for these options, it only passes in a QStyleOption not a QStyleOptionTab +//......... + case PM_TabBarBaseHeight: +#ifdef QTC_QT_ONLY + if(widget && widget->inherits("KTabBar") && !qstyleoption_cast(option)) +#else + if(widget && qobject_cast(widget) && !qstyleoption_cast(option)) +#endif + return 10; + return BASE_STYLE::pixelMetric(metric, option, widget); + case PM_TabBarBaseOverlap: +#ifdef QTC_QT_ONLY + if(widget && widget->inherits("KTabBar") && !qstyleoption_cast(option)) +#else + if(widget && qobject_cast(widget) && !qstyleoption_cast(option)) +#endif + return 0; + // Fall through! +//......... + default: + return BASE_STYLE::pixelMetric(metric, option, widget); + } +} + +int Style::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const +{ + switch (hint) + { + case SH_ToolTip_Mask: + case SH_Menu_Mask: + if((SH_ToolTip_Mask==hint && (opts.square&SQUARE_TOOLTIPS)) || + (SH_Menu_Mask==hint && (opts.square&SQUARE_POPUP_MENUS))) + return BASE_STYLE::styleHint(hint, option, widget, returnData); + else + { + if(!Utils::hasAlphaChannel(widget) && (!widget || widget->isWindow())) + if(QStyleHintReturnMask *mask = qstyleoption_cast(returnData)) + mask->region = windowMask(option->rect, opts.round>ROUND_SLIGHT); + return true; + } + case SH_ComboBox_ListMouseTracking: + case SH_PrintDialog_RightAlignButtons: + case SH_ItemView_ArrowKeysNavigateIntoChildren: + case SH_ToolBox_SelectedPageTitleBold: + case SH_ScrollBar_MiddleClickAbsolutePosition: + case SH_SpinControls_DisableOnBounds: + case SH_Slider_SnapToValue: + case SH_FontDialog_SelectAssociatedText: + case SH_Menu_MouseTracking: + return true; + case SH_UnderlineShortcut: + return widget && opts.hideShortcutUnderline ? itsShortcutHandler->showShortcut(widget) : true; + case SH_GroupBox_TextLabelVerticalAlignment: + if (const QStyleOptionGroupBox *frame = qstyleoption_cast(option)) + { + if (frame->features & QStyleOptionFrameV2::Flat) + return Qt::AlignVCenter; + } + return opts.gbLabel&GB_LBL_INSIDE + ? Qt::AlignBottom + : opts.gbLabel&GB_LBL_OUTSIDE + ? Qt::AlignTop + : Qt::AlignVCenter; + case SH_MessageBox_CenterButtons: + case SH_ProgressDialog_CenterCancelButton: + case SH_DitherDisabledText: + case SH_EtchDisabledText: + case SH_Menu_AllowActiveAndDisabled: + case SH_ItemView_ShowDecorationSelected: // Controls whether the highlighting of listview/treeview items highlights whole line. + case SH_MenuBar_AltKeyNavigation: + return false; + case SH_ItemView_ChangeHighlightOnFocus: // gray out selected items when losing focus. + return false; + case SH_WizardStyle: + return QWizard::ClassicStyle; + case SH_RubberBand_Mask: + { + const QStyleOptionRubberBand *opt = qstyleoption_cast(option); + if (!opt) + return true; + if (QStyleHintReturnMask *mask = qstyleoption_cast(returnData)) + { + mask->region = option->rect; + mask->region -= option->rect.adjusted(1,1,-1,-1); + } + return true; + } + case SH_Menu_SubMenuPopupDelay: + return opts.menuDelay; + case SH_ToolButton_PopupDelay: + return 250; + case SH_ComboBox_PopupFrameStyle: + return opts.popupBorder || !(opts.square&SQUARE_POPUP_MENUS) ? QFrame::StyledPanel|QFrame::Plain : QFrame::NoFrame; + case SH_TabBar_Alignment: + return Qt::AlignLeft; + case SH_Header_ArrowAlignment: + return Qt::AlignLeft; + case SH_WindowFrame_Mask: + if (QStyleHintReturnMask *mask = qstyleoption_cast(returnData)) + { + QRect r(option->rect); + + switch((opts.square&SQUARE_WINDOWS && opts.round>ROUND_SLIGHT) ? ROUND_SLIGHT : opts.round) + { + case ROUND_NONE: + mask->region=r; + break; + case ROUND_SLIGHT: + mask->region=QRegion(r.x()+1, r.y(), r.width()-2, r.height()); + mask->region += QRegion(r.x()+0, r.y()+1, 1, r.height()-2); + mask->region += QRegion(r.x()+r.width()-1, r.y()+1, 1, r.height()-2); + break; + default: // ROUND_FULL + mask->region=QRegion(r.x()+5, r.y(), r.width()-10, r.height()); + mask->region += QRegion(r.x()+0, r.y()+5, 1, r.height()-5); + mask->region += QRegion(r.x()+1, r.y()+3, 1, r.height()-2); + mask->region += QRegion(r.x()+2, r.y()+2, 1, r.height()-1); + mask->region += QRegion(r.x()+3, r.y()+1, 2, r.height()); + mask->region += QRegion(r.x()+r.width()-1, r.y()+5, 1, r.height()-5); + mask->region += QRegion(r.x()+r.width()-2, r.y()+3, 1, r.height()-2); + mask->region += QRegion(r.x()+r.width()-3, r.y()+2, 1, r.height()-1); + mask->region += QRegion(r.x()+r.width()-5, r.y()+1, 2, r.height()-0); + } + } + return 1; + case SH_TitleBar_NoBorder: + case SH_TitleBar_AutoRaise: + return 1; + case SH_MainWindow_SpaceBelowMenuBar: +#ifdef Q_WS_X11 + if(opts.xbar) + if (const QMenuBar *menubar = qobject_cast(widget)) + if (0==menubar->height() && !menubar->actions().isEmpty()) + { // we trick menubars if we use macmenus - hehehe... + // NOTICE the final result NEEDS to be > "0" (i.e. "1") to avoid side effects... + return -menubar->actionGeometry(menubar->actions().first()).height() + 1; + } +#endif + return 0; + case SH_DialogButtonLayout: + return opts.gtkButtonOrder ? QDialogButtonBox::GnomeLayout : QDialogButtonBox::KdeLayout; + case SH_MessageBox_TextInteractionFlags: + return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse; + case SH_LineEdit_PasswordCharacter: + if(opts.passwordChar) + { + int chars[4]={opts.passwordChar, 0x25CF, 0x2022, 0}; + const QFontMetrics &fm(option ? option->fontMetrics + : (widget ? widget->fontMetrics() : QFontMetrics(QFont()))); + for(int i=0; chars[i]; ++i) + if (fm.inFont(QChar(chars[i]))) + return chars[i]; + return '*'; + } + else + return '\0'; + case SH_MenuBar_MouseTracking: + // Always return 1, as setting to 0 dissables the effect when a menu is shown. + return 1; // opts.menubarMouseOver ? 1 : 0; + case SH_ScrollView_FrameOnlyAroundContents: + return widget && widget->isWindow() + ? false + : opts.gtkScrollViews && (!widget || !widget->inherits("QComboBoxListView")); + case SH_ComboBox_Popup: + if(opts.gtkComboMenus) + { + if (widget && widget->inherits("Q3ComboBox")) + return 0; + if (const QStyleOptionComboBox *cmb = qstyleoption_cast(option)) + return !cmb->editable; + } + return 0; +#if QT_VERSION >= 0x040400 + case SH_FormLayoutFormAlignment: + return Qt::AlignLeft | Qt::AlignTop; // KDE4 HIG, align the contents in a form layout to the left + case SH_FormLayoutLabelAlignment: + return Qt::AlignRight; // KDE4 HIG, align the labels in a form layout to the right + case SH_FormLayoutFieldGrowthPolicy: + return QFormLayout::ExpandingFieldsGrow; + case SH_FormLayoutWrapPolicy: + return QFormLayout::DontWrapRows; +#endif +#if !defined QTC_QT_ONLY + case SH_DialogButtonBox_ButtonsHaveIcons: + return KGlobalSettings::showIconsOnPushButtons(); + case SH_ItemView_ActivateItemOnSingleClick: + return KGlobalSettings::singleClick(); +#endif + default: +#if !defined QTC_QT_ONLY + // Tell the calling app that we can handle certain custom widgets... + if(hint>=SH_CustomBase && widget) + if("CE_CapacityBar"==widget->objectName()) + { + if (opts.boldProgress) + setBold((QWidget *)widget); + return CE_QtC_KCapacityBar; + } +#endif + return BASE_STYLE::styleHint(hint, option, widget, returnData); + } +} + +QPalette Style::standardPalette() const +{ +#if defined QTC_QT_ONLY + return BASE_STYLE::standardPalette(); +#else + return KGlobalSettings::createApplicationPalette(KSharedConfig::openConfig(itsComponentData)); +#endif +} + +#if defined QTC_QT_ONLY +#include "dialogpixmaps.h" + +static QIcon load(const unsigned int len, const unsigned char *data) +{ + QImage img; + img.loadFromData(data, len); + + return QIcon(QPixmap::fromImage(img)); +} +#endif + +QIcon Style::standardIconImplementation(StandardPixmap pix, const QStyleOption *option, const QWidget *widget) const +{ + switch(pix) + { +// case SP_TitleBarMenuButton: +// case SP_TitleBarMinButton: +// case SP_TitleBarMaxButton: +// case SP_TitleBarContextHelpButton: + case SP_TitleBarNormalButton: + case SP_TitleBarShadeButton: + case SP_TitleBarUnshadeButton: + case SP_DockWidgetCloseButton: + case SP_TitleBarCloseButton: + { + QPixmap pm(13, 13); + + pm.fill(Qt::transparent); + + QPainter painter(&pm); + + drawIcon(&painter, Qt::color1, QRect(0, 0, pm.width(), pm.height()), false, pix2Icon(pix), + SP_TitleBarShadeButton==pix || SP_TitleBarUnshadeButton==pix); + return QIcon(pm); + } + case SP_ToolBarHorizontalExtensionButton: + case SP_ToolBarVerticalExtensionButton: + { + QPixmap pm(9, 9); + + pm.fill(Qt::transparent); + + QPainter painter(&pm); + + drawIcon(&painter, Qt::color1, QRect(0, 0, pm.width(), pm.height()), false, pix2Icon(pix), true); + return QIcon(pm); + } +#if defined QTC_QT_ONLY + case SP_MessageBoxQuestion: + case SP_MessageBoxInformation: + { + static QIcon icn(load(dialog_information_png_len, dialog_information_png_data)); + return icn; + } + case SP_MessageBoxWarning: + { + static QIcon icn(load(dialog_warning_png_len, dialog_warning_png_data)); + return icn; + } + case SP_MessageBoxCritical: + { + static QIcon icn(load(dialog_error_png_len, dialog_error_png_data)); + return icn; + } +/* + case SP_DialogYesButton: + case SP_DialogOkButton: + { + static QIcon icn(load(dialog_ok_png_len, dialog_ok_png_data)); + return icn; + } + case SP_DialogNoButton: + case SP_DialogCancelButton: + { + static QIcon icn(load(dialog_cancel_png_len, dialog_cancel_png_data)); + return icn; + } + case SP_DialogHelpButton: + { + static QIcon icn(load(help_contents_png_len, help_contents_png_data)); + return icn; + } + case SP_DialogCloseButton: + { + static QIcon icn(load(dialog_close_png_len, dialog_close_png_data)); + return icn; + } + case SP_DialogApplyButton: + { + static QIcon icn(load(dialog_ok_apply_png_len, dialog_ok_apply_png_data)); + return icn; + } + case SP_DialogResetButton: + { + static QIcon icn(load(document_revert_png_len, document_revert_png_data)); + return icn; + } +*/ +#else + case SP_MessageBoxInformation: + return KIcon("dialog-information"); + case SP_MessageBoxWarning: + return KIcon("dialog-warning"); + case SP_MessageBoxCritical: + return KIcon("dialog-error"); + case SP_MessageBoxQuestion: + return KIcon("dialog-information"); + case SP_DesktopIcon: + return KIcon("user-desktop"); + case SP_TrashIcon: + return KIcon("user-trash"); + case SP_ComputerIcon: + return KIcon("computer"); + case SP_DriveFDIcon: + return KIcon("media-floppy"); + case SP_DriveHDIcon: + return KIcon("drive-harddisk"); + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + return KIcon("media-optical"); + case SP_DriveNetIcon: + return KIcon("network-server"); + case SP_DirOpenIcon: + return KIcon("document-open"); + case SP_DirIcon: + case SP_DirClosedIcon: + return KIcon("folder"); +// case SP_DirLinkIcon: + case SP_FileIcon: + return KIcon("application-x-zerosize"); +// case SP_FileLinkIcon: + case SP_FileDialogStart: + return KIcon(Qt::RightToLeft==QApplication::layoutDirection() ? "go-edn" : "go-first"); + case SP_FileDialogEnd: + return KIcon(Qt::RightToLeft==QApplication::layoutDirection() ? "go-first" : "go-end"); + case SP_FileDialogToParent: + return KIcon("go-up"); + case SP_FileDialogNewFolder: + return KIcon("folder-new"); + case SP_FileDialogDetailedView: + return KIcon("view-list-details"); +// case SP_FileDialogInfoView: +// return KIcon("dialog-ok"); +// case SP_FileDialogContentsView: +// return KIcon("dialog-ok"); + case SP_FileDialogListView: + return KIcon("view-list-icons"); + case SP_FileDialogBack: + return KIcon(Qt::RightToLeft==QApplication::layoutDirection() ? "go-next" : "go-previous"); + case SP_DialogOkButton: + return KIcon("dialog-ok"); + case SP_DialogCancelButton: + return KIcon("dialog-cancel"); + case SP_DialogHelpButton: + return KIcon("help-contents"); + case SP_DialogOpenButton: + return KIcon("document-open"); + case SP_DialogSaveButton: + return KIcon("document-save"); + case SP_DialogCloseButton: + return KIcon("dialog-close"); + case SP_DialogApplyButton: + return KIcon("dialog-ok-apply"); + case SP_DialogResetButton: + return KIcon("document-revert"); +// case SP_DialogDiscardButton: +// return KIcon("dialog-cancel"); + case SP_DialogYesButton: + return KIcon("dialog-ok"); + case SP_DialogNoButton: + return KIcon("dialog-cancel"); + case SP_ArrowUp: + return KIcon("arrow-up"); + case SP_ArrowDown: + return KIcon("arrow-down"); + case SP_ArrowLeft: + return KIcon("arrow-left"); + case SP_ArrowRight: + return KIcon("arrow-right"); + case SP_ArrowBack: + return KIcon(Qt::RightToLeft==QApplication::layoutDirection() ? "go-next" : "go-previous"); + case SP_ArrowForward: + return KIcon(Qt::RightToLeft==QApplication::layoutDirection() ? "go-previous" : "go-next"); + case SP_DirHomeIcon: + return KIcon("user-home"); +// case SP_CommandLink: +// case SP_VistaShield: + case SP_BrowserReload: + return KIcon("view-refresh"); + case SP_BrowserStop: + return KIcon("process-stop"); + case SP_MediaPlay: + return KIcon("media-playback-start"); + case SP_MediaStop: + return KIcon("media-playback-stop"); + case SP_MediaPause: + return KIcon("media-playback-pause"); + case SP_MediaSkipForward: + return KIcon("media-skip-forward"); + case SP_MediaSkipBackward: + return KIcon("media-skip-backward"); + case SP_MediaSeekForward: + return KIcon("media-seek-forward"); + case SP_MediaSeekBackward: + return KIcon("media-seek-backward"); + case SP_MediaVolume: + return KIcon("player-volume"); + case SP_MediaVolumeMuted: + return KIcon("player-volume-muted"); +#endif + default: + break; + } + return BASE_STYLE::standardIconImplementation(pix, option, widget); +} + +int Style::layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, + const QStyleOption *option, const QWidget *widget) const +{ + Q_UNUSED(control1); Q_UNUSED(control2); Q_UNUSED(orientation); + + return pixelMetric(PM_DefaultLayoutSpacing, option, widget); +} + +void Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + QRect r(option->rect); + QFlags state(option->state); + const QPalette &palette(option->palette); + bool reverse(Qt::RightToLeft==option->direction); + + switch ((int)element) + { +#if (QT_VERSION >= 0x040500) && !defined QTC_QT_ONLY + case PE_IndicatorTabClose: + { + int size(pixelMetric(QStyle::PM_SmallIconSize)); + QIcon::Mode mode(state&State_Enabled + ? state& State_Raised + ? QIcon::Active + : QIcon::Normal + : QIcon::Disabled); + + if (!(state&State_Raised) && !(state&State_Sunken) && !(state&QStyle::State_Selected)) + mode = QIcon::Disabled; + + drawItemPixmap(painter, r, Qt::AlignCenter, KIcon("dialog-close").pixmap(size, mode, state&State_Sunken + ? QIcon::On : QIcon::Off)); + break; + } +#endif + case PE_Widget: + if(widget && widget->testAttribute(Qt::WA_StyledBackground) && + ( (!widget->testAttribute(Qt::WA_NoSystemBackground) && + ((widget->windowFlags()&Qt::WindowType_Mask) & (Qt::Window|Qt::Dialog)) && widget->isWindow()) || + (itsIsPreview && qobject_cast(widget)) ) ) + { + bool isDialog=qobject_cast(widget); + + if(CUSTOM_BGND || itsIsPreview || (isDialog && opts.dlgOpacity!=100) || (!isDialog && opts.bgndOpacity!=100)) + drawBackground(painter, widget, isDialog ? BGND_DIALOG : BGND_WINDOW); + } + break; + case PE_PanelScrollAreaCorner: + // disable painting of PE_PanelScrollAreaCorner + // the default implementation fills the rect with the window background color which does not work for windows that have gradients. + // ...but need to for WebView!!! + if(!opts.gtkScrollViews || !CUSTOM_BGND || (widget && widget->inherits("WebView"))) + painter->fillRect(r, palette.brush(QPalette::Window)); + break; + case PE_IndicatorBranch: + { + int middleH((r.x() + r.width() / 2)-1), + middleV(r.y() + r.height() / 2), +#if 0 + beforeH(middleH), +#endif + beforeV(middleV), + afterH(middleH), + afterV(middleV); + + painter->save(); + + if (state&State_Children) + { + QRect ar(r.x()+((r.width()-(LV_SIZE+4))>>1), r.y()+((r.height()-(LV_SIZE+4))>>1), LV_SIZE+4, + LV_SIZE+4); + if(/*LV_OLD==*/opts.lvLines) + { + beforeV=ar.y()-1; + afterH=ar.x()+LV_SIZE+4; + afterV=ar.y()+LV_SIZE+4; +#if 0 + beforeH=ar.x(); + int lo(ROUNDED ? 2 : 0); + + painter->setPen(palette.mid().color()); + painter->drawLine(ar.x()+lo, ar.y(), (ar.x()+ar.width()-1)-lo, ar.y()); + painter->drawLine(ar.x()+lo, ar.y()+ar.height()-1, (ar.x()+ar.width()-1)-lo, ar.y()+ar.height()-1); + painter->drawLine(ar.x(), ar.y()+lo, ar.x(), (ar.y()+ar.height()-1)-lo); + painter->drawLine(ar.x()+ar.width()-1, ar.y()+lo, ar.x()+ar.width()-1, (ar.y()+ar.height()-1)-lo); + + if(ROUNDED) + { + painter->drawPoint(ar.x()+1, ar.y()+1); + painter->drawPoint(ar.x()+1, ar.y()+ar.height()-2); + painter->drawPoint(ar.x()+ar.width()-2, ar.y()+1); + painter->drawPoint(ar.x()+ar.width()-2, ar.y()+ar.height()-2); + + QColor col(palette.mid().color()); + + col.setAlphaF(0.5); + painter->setPen(col); + painter->drawLine(ar.x()+1, ar.y()+1, ar.x()+2, ar.y()); + painter->drawLine(ar.x()+ar.width()-2, ar.y(), ar.x()+ar.width()-1, ar.y()+1); + painter->drawLine(ar.x()+1, ar.y()+ar.height()-2, ar.x()+2, ar.y()+ar.height()-1); + painter->drawLine(ar.x()+ar.width()-2, ar.y()+ar.height()-1, ar.x()+ar.width()-1, ar.y()+ar.height()-2); + } +#endif + } + drawArrow(painter, ar, state&State_Open + ? PE_IndicatorArrowDown + : reverse + ? PE_IndicatorArrowLeft + : PE_IndicatorArrowRight, MO_ARROW(QPalette::ButtonText)); + } + + const int constStep=/*LV_OLD==*/opts.lvLines + ? 0 + : widget && qobject_cast(widget) + ? ((QTreeView *)widget)->indentation() : 20; + + if(opts.lvLines /*&& (LV_OLD==opts.lvLines || (r.x()>=constStep && constStep>0))*/) + { + painter->setPen(palette.mid().color()); + if (state&State_Item) + { + if (reverse) + painter->drawLine(r.left(), middleV, afterH, middleV); + else + { +#if 0 + if(LV_NEW==opts.lvLines) + { + if(state&State_Children) + painter->drawLine(middleH-constStep, middleV, r.right()-constStep, middleV); + else + drawFadedLine(painter, QRect(middleH-constStep, middleV, r.right()-(middleH-constStep), middleV), palette.mid().color(), + false, true, true); + } + else +#endif + painter->drawLine(afterH, middleV, r.right(), middleV); + } + } + if (state&State_Sibling && afterVdrawLine(middleH-constStep, afterV, middleH-constStep, r.bottom()); + if (state & (State_Open | State_Children | State_Item | State_Sibling) && (/*LV_NEW==opts.lvLines || */beforeV>r.y())) + painter->drawLine(middleH-constStep, r.y(), middleH-constStep, beforeV); + } + painter->restore(); + break; + } + case PE_IndicatorViewItemCheck: + { + QStyleOption opt(*option); + + opt.state &= ~State_MouseOver; + opt.state |= STATE_VIEW; + drawPrimitive(PE_IndicatorCheckBox, &opt, painter, widget); + break; + } + case PE_IndicatorHeaderArrow: + if (const QStyleOptionHeader *header = qstyleoption_cast(option)) + drawArrow(painter, r, header->sortIndicator & QStyleOptionHeader::SortUp ? PE_IndicatorArrowUp : PE_IndicatorArrowDown, + MO_ARROW(QPalette::ButtonText)); + break; + case PE_IndicatorArrowUp: + case PE_IndicatorArrowDown: + case PE_IndicatorArrowLeft: + case PE_IndicatorArrowRight: + if(State_None==state) + state|=State_Enabled; + if((QStyle::State_Enabled|QtC_StateKWin)==state) + drawArrow(painter, r, element, Qt::color1, false, true); + else + { + QColor col(MO_ARROW(QPalette::Text)); + if(state&(State_Sunken|State_On) && + !(widget && ( (opts.unifySpin && qobject_cast(widget)) || + (opts.unifyCombo && qobject_cast(widget) && + ((const QComboBox *)widget)->isEditable())))) + r.adjust(1, 1, 1, 1); + if(col.alpha()<255 && PE_IndicatorArrowRight==element && widget && widget->inherits("KUrlButton")) + col=blendColors(col, palette.background().color(), col.alphaF()); + + drawArrow(painter, r, element, col, false, false); + } + break; + case PE_IndicatorSpinMinus: + case PE_IndicatorSpinPlus: + case PE_IndicatorSpinUp: + case PE_IndicatorSpinDown: + { + QRect sr(r); + const QColor *use(buttonColors(option)), + col(MO_ARROW(QPalette::ButtonText)); + bool down(PE_IndicatorSpinDown==element || PE_IndicatorSpinMinus==element); + + if((!opts.unifySpinBtns || state&State_Sunken) && !opts.unifySpin) + drawLightBevel(painter, sr, option, widget, down + ? reverse + ? ROUNDED_BOTTOMLEFT + : ROUNDED_BOTTOMRIGHT + : reverse + ? ROUNDED_TOPLEFT + : ROUNDED_TOPRIGHT, + getFill(option, use), use, true, WIDGET_SPIN); + + if(PE_IndicatorSpinUp==element || PE_IndicatorSpinDown==element) + { + sr.setY(sr.y()+(down ? -2 : 1)); + + if(opts.unifySpin) + { + sr.adjust(reverse ? 1 : -1, 0, reverse ? 1 : -1, 0); + if(!opts.vArrows) + sr.setY(sr.y()+(down ? -2 : 2)); + } + else if(state&State_Sunken) + sr.adjust(1, 1, 1, 1); + + drawArrow(painter, sr, PE_IndicatorSpinUp==element ? PE_IndicatorArrowUp : PE_IndicatorArrowDown, + col, !opts.unifySpin); + } + else + { + int l(qMin(r.width()-6, r.height()-6)); + QPoint c(r.x()+(r.width()/2), r.y()+(r.height()/2)); + + l/=2; + if(l%2 != 0) + --l; + + if(state&State_Sunken && !opts.unifySpin) + c+=QPoint(1, 1); + + painter->setPen(col); + painter->drawLine(c.x()-l, c.y(), c.x()+l, c.y()); + if(!down) + painter->drawLine(c.x(), c.y()-l, c.x(), c.y()+l); + } + break; + } + case PE_IndicatorToolBarSeparator: + { + painter->save(); + switch(opts.toolbarSeparators) + { + case LINE_NONE: + break; + case LINE_FLAT: + case LINE_SUNKEN: + if(r.width()restore(); + break; + } + case PE_FrameGroupBox: + if(FRAME_NONE==opts.groupBox) + break; + if (const QStyleOptionFrame *frame = qstyleoption_cast(option)) + { + QStyleOptionFrameV2 frameV2(*frame); + if (frameV2.features & QStyleOptionFrameV2::Flat || FRAME_LINE==opts.groupBox) + drawFadedLine(painter, QRect(r.x(), r.y(), r.width(), 1), backgroundColors(option)[STD_BORDER], + opts.gbLabel&GB_LBL_CENTRED || reverse, opts.gbLabel&GB_LBL_CENTRED || !reverse, true); + else + { + if(opts.gbLabel&GB_LBL_OUTSIDE) + r.adjust(0, 2, 0, 0); + + if(FRAME_SHADED==opts.groupBox || FRAME_FADED==opts.groupBox) + { + int round=opts.square&SQUARE_FRAME ? ROUNDED_NONE : ROUNDED_ALL; + QPainterPath path(buildPath(r, WIDGET_FRAME, round, + ROUNDED_ALL==round + ? qtcGetRadius(&opts, r.width(), r.height(), WIDGET_FRAME, RADIUS_EXTERNAL) + : 0.0)); + + painter->save(); + painter->setClipping(false); + if(0!=opts.gbFactor) + { + QColor col(opts.gbFactor<0 ? Qt::black : Qt::white); + + col.setAlphaF(TO_ALPHA(opts.gbFactor)); + if(FRAME_SHADED==opts.groupBox) + painter->fillPath(path, col); + else + { + QLinearGradient grad(r.topLeft(), r.bottomLeft()); + + grad.setColorAt(0, col); + col.setAlphaF(0.0); + grad.setColorAt(1, col); + painter->fillPath(path, grad); + } + } + + if(!(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE))) + painter->restore(); + + if(FRAME_SHADED==opts.groupBox) + drawBorder(painter, r, option, round, backgroundColors(option), WIDGET_FRAME, + /*state&State_Raised && opts.gbFactor<0 ? BORDER_RAISED : */BORDER_SUNKEN); + else + { + QColor col(backgroundColors(option)[STD_BORDER]); + QLinearGradient grad(r.topLeft(), r.bottomLeft()); + + col.setAlphaF(1.0); + grad.setColorAt(0, col); + col.setAlphaF(0.0); + grad.setColorAt(1, col); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(QPen(QBrush(grad), 1)); + painter->drawPath(path); + } + if(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE)) + painter->restore(); + } + else + { + frameV2.state &= ~(State_Sunken | State_HasFocus); + frameV2.rect=r; + drawPrimitive(PE_Frame, &frameV2, painter, widget); + } + } + } + break; + case PE_Frame: + { + // Dont draw OO.o status bar frames... + if(isOOWidget(widget) && r.height()<22) + break; + +#ifdef QTC_QT_ONLY + if(widget && widget->parent() && widget->parent()->inherits("KTitleWidget")) + break; +#else + if(widget && widget->parent() && qobject_cast(widget->parent())) + break; +#endif + else if(widget && widget->parent() && qobject_cast(widget->parent())) + { + if(opts.gtkComboMenus && !((QComboBox *)(widget->parent()))->isEditable()) + drawPrimitive(PE_FrameMenu, option, painter, widget); + else if(opts.square&SQUARE_POPUP_MENUS) + { + const QColor *use(APP_KRUNNER==theThemedApp ? itsBackgroundCols : backgroundColors(option)); + + painter->save(); + painter->setPen(use[STD_BORDER]); + drawRect(painter, r); + painter->setPen(palette.base().color()); + drawRect(painter, r.adjusted(1, 1, -1, -1)); + painter->restore(); + } + } + else + { + const QStyleOptionFrame *fo = qstyleoption_cast(option); + + if(APP_K3B==theThemedApp && !(state&(State_Sunken|State_Raised)) && fo && 1==fo->lineWidth) + { + painter->save(); + painter->setPen(backgroundColors(option)[STD_BORDER]); + drawRect(painter, r); + painter->restore(); + } + else if((QtC_StateKWin==state || (QtC_StateKWin|State_Active)==state) && fo && 1==fo->lineWidth && 1==fo->midLineWidth) + { + QColor border; + if(fo->version==(TBAR_BORDER_VERSION_HACK+2)) + border=palette.color(QPalette::Active, QPalette::Shadow); + else + { + const QColor *borderCols(opts.windowBorder&WINDOW_BORDER_COLOR_TITLEBAR_ONLY + ? backgroundColors(palette.color(QPalette::Active, QPalette::Window)) + : theThemedApp==APP_KWIN + ? buttonColors(option) + : getMdiColors(option, state&State_Active)); + border=borderCols[fo->version==TBAR_BORDER_VERSION_HACK ? 0 : STD_BORDER]; + } + + border.setAlphaF(1.0); + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setPen(border); + drawRect(painter, r); + painter->restore(); + } + else + { + bool kateView(isKateView(widget)), + kontactPreview(!kateView && isKontactPreviewPane(widget)), + sv(isOOWidget(widget) || + ::qobject_cast(widget) || + (widget && widget->inherits("Q3ScrollView")) || + ((opts.square&SQUARE_SCROLLVIEW) && (kateView || kontactPreview))), + squareSv(sv && ((opts.square&SQUARE_SCROLLVIEW) || (widget && widget->isWindow()))), + inQAbstractItemView(widget && widget->parentWidget() && isInQAbstractItemView(widget->parentWidget())); + + if(sv && (opts.etchEntry || squareSv || isOOWidget(widget))) + { + // For some reason, in KPackageKit, the KTextBrower when polished is not in the scrollview, + // but is when painted. So check here if it should not be etched. + // Also, see not in getLowerEtchCol() + if(DO_EFFECT && !USE_CUSTOM_ALPHAS(opts) && widget && widget->parentWidget() && + !theNoEtchWidgets.contains(widget) && inQAbstractItemView) + theNoEtchWidgets.insert(widget); + + // If we are set to have sunken scrollviews, then the frame width is set to 3. + // ...but it we are a scrollview within a scrollview, then we dont draw sunken, therefore + // need to draw inner border... + bool doEtch=DO_EFFECT && opts.etchEntry, + noEtchW=doEtch && !USE_CUSTOM_ALPHAS(opts) && theNoEtchWidgets.contains(widget); + + if(doEtch && noEtchW) + { + painter->setPen(palette.brush(QPalette::Base).color()); + drawRect(painter, r.adjusted(2, 2, -2, -2)); + } + + if(!opts.highlightScrollViews && fo) + { + QStyleOptionFrame opt(*fo); + opt.state&=~State_HasFocus; + drawEntryField(painter, r, widget, &opt, squareSv ? ROUNDED_NONE : ROUNDED_ALL, false, doEtch && !noEtchW, WIDGET_SCROLLVIEW); + } + else + drawEntryField(painter, r, widget, option, squareSv ? ROUNDED_NONE : ROUNDED_ALL, false, + doEtch && !noEtchW, WIDGET_SCROLLVIEW); + } + // K3b's Disk usage status bar, etc... +// else if(APP_K3B==theThemedApp && widget && widget->inherits("K3b::FillStatusDisplay")) + else if (fo && fo->lineWidth>0) + { + bool kwinTab(APP_KWIN==theThemedApp && widget && !widget->parentWidget() && + 0==strcmp(widget->metaObject()->className(), "KWin::TabBox")); + QStyleOption opt(*option); + + painter->save(); + + if(kwinTab) + r.adjust(-1, -1, 1, 1); + + if(!opts.highlightScrollViews) + opt.state&=~State_HasFocus; + + if(opts.round && IS_FLAT_BGND(opts.bgndAppearance) && 100==opts.bgndOpacity && + widget && widget->parentWidget() && !inQAbstractItemView/* && + widget->palette().background().color()!=widget->parentWidget()->palette().background().color()*/) + { + painter->setPen(widget->parentWidget()->palette().background().color()); + painter->drawRect(r); + painter->drawRect(r.adjusted(1, 1, -1, -1)); + } + + if(sv || kateView || kontactPreview) + { + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(option->palette.brush(opts.thin&THIN_FRAMES && !(opts.square&SQUARE_SCROLLVIEW) + ? QPalette::Window + : QPalette::Base).color()); + painter->drawPath(buildPath(r.adjusted(1, 1, -1, -1), WIDGET_SCROLLVIEW, ROUNDED_ALL, + qtcGetRadius(&opts, r.width()-2, r.height()-2, WIDGET_SCROLLVIEW, RADIUS_INTERNAL))); + painter->setRenderHint(QPainter::Antialiasing, false); + } + + drawBorder(painter, r, &opt, + opts.round ? getFrameRound(widget) : ROUND_NONE, backgroundColors(option), + sv || kateView || kontactPreview ? WIDGET_SCROLLVIEW : WIDGET_FRAME, + state&State_Sunken || state&State_HasFocus + ? BORDER_SUNKEN + : state&State_Raised + ? BORDER_RAISED + : BORDER_FLAT); + painter->restore(); + } + } + } + break; + } + case PE_PanelMenuBar: + if (widget && widget->parentWidget() && (qobject_cast(widget->parentWidget()) || + widget->parentWidget()->inherits("Q3MainWindow"))) + { + painter->save(); + if(!opts.xbar || (!widget || 0!=strcmp("QWidget", widget->metaObject()->className()))) + drawMenuOrToolBarBackground(widget, painter, r, option); + if(TB_NONE!=opts.toolbarBorders) + { + const QColor *use=itsActive + ? itsMenubarCols + : backgroundColors(option); + bool dark(TB_DARK==opts.toolbarBorders || TB_DARK_ALL==opts.toolbarBorders); + + if(TB_DARK_ALL==opts.toolbarBorders || TB_LIGHT_ALL==opts.toolbarBorders) + { + painter->setPen(use[0]); + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); + painter->setPen(use[dark ? 3 : 4]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + } + else + { + painter->setPen(use[dark ? 3 : 4]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + } + } + painter->restore(); + } + break; + case PE_FrameTabBarBase: + if (const QStyleOptionTabBarBase *tbb = qstyleoption_cast(option)) + { + if(tbb->shape != QTabBar::RoundedNorth && tbb->shape != QTabBar::RoundedWest && + tbb->shape != QTabBar::RoundedSouth && tbb->shape != QTabBar::RoundedEast) + BASE_STYLE::drawPrimitive(element, option, painter, widget); + else + { + static const int constSidePad=16*2; + const QColor *use(backgroundColors(option)); + QRegion region(tbb->rect); + QLine topLine(tbb->rect.bottomLeft() - QPoint(0, 1), tbb->rect.bottomRight() - QPoint(0, 1)), + bottomLine(tbb->rect.bottomLeft(), tbb->rect.bottomRight()); + bool horiz(QTabBar::RoundedNorth==tbb->shape || QTabBar::RoundedSouth==tbb->shape); + double size=horiz ? tbb->rect.width() : tbb->rect.height(), + tabRectSize=horiz ? tbb->tabBarRect.width() : tbb->tabBarRect.height(), + tabFadeSize=tabRectSize+constSidePad > size ? 0.0 : 1.0-((tabRectSize+constSidePad)/size), + minFadeSize=1.0-((size-constSidePad)/size), + fadeSizeStart=minFadeSize, + fadeSizeEnd=tabFadeSizeFADE_SIZE ? FADE_SIZE : tabFadeSize); + + if(reverse && horiz) + fadeSizeStart=fadeSizeEnd, fadeSizeEnd=minFadeSize; + + region -= tbb->tabBarRect; + + painter->save(); + painter->setClipRegion(region); + bool fadeState=true, fadeEnd=true; + + // Dont fade start/end of tabbar in KDevelop's menubar + if(APP_KDEVELOP==theThemedApp && widget && widget->parentWidget() && widget->parentWidget()->parentWidget() && + qobject_cast(widget) && qobject_cast(widget->parentWidget()->parentWidget())) + fadeState=fadeEnd=false; + + drawFadedLine(painter, QRect(topLine.p1(), topLine.p2()), + QTabBar::RoundedSouth==tbb->shape && APPEARANCE_FLAT==opts.appearance + ? palette.background().color() + : use[QTabBar::RoundedNorth==tbb->shape ? STD_BORDER + : (opts.borderTab ? 0 : FRAME_DARK_SHADOW)], + fadeState, fadeEnd, horiz, fadeSizeStart, fadeSizeEnd); + if(!(opts.thin&THIN_FRAMES)) + drawFadedLine(painter, QRect(bottomLine.p1(), bottomLine.p2()), + use[QTabBar::RoundedNorth==tbb->shape ? 0 : STD_BORDER], + fadeState, fadeEnd, horiz, fadeSizeStart, fadeSizeEnd); + painter->restore(); + } + } + break; + case PE_FrameStatusBar: + if(!opts.drawStatusBarFrames) + break; + case PE_FrameMenu: + if((opts.square&SQUARE_POPUP_MENUS) && + (IS_FLAT_BGND(opts.menuBgndAppearance) || + (opts.gtkComboMenus && widget && widget->parent() && qobject_cast(widget->parent())))) + { + const QColor *use(popupMenuCols(option)); + EGradientBorder border=qtcGetGradient(opts.menuBgndAppearance, &opts)->border; + painter->save(); + painter->setPen(use[STD_BORDER]); + drawRect(painter, r); + + if(USE_BORDER(border) && APPEARANCE_FLAT!=opts.menuBgndAppearance) + { + painter->setPen(use[0]); + if(GB_LIGHT==border) + drawRect(painter, r.adjusted(1, 1, -1, -1)); + else + { + if(GB_3D!=border) + { + painter->drawLine(r.x()+1, r.y()+1, r.x()+r.width()-2, r.y()+1); + painter->drawLine(r.x()+1, r.y()+1, r.x()+1, r.y()+r.height()-2); + } + painter->setPen(use[FRAME_DARK_SHADOW]); + painter->drawLine(r.x()+1, r.y()+r.height()-2, r.x()+r.width()-2, r.y()+r.height()-2); + painter->drawLine(r.x()+r.width()-2, r.y()+1, r.x()+r.width()-2, r.y()+r.height()-2); + } + } + painter->restore(); + } + break; + case PE_FrameDockWidget: + { + const QColor *use(backgroundColors(option)); + + painter->save(); + painter->setPen(use[0]); + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); + painter->setPen(use[APPEARANCE_FLAT==opts.appearance ? ORIGINAL_SHADE : STD_BORDER]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + painter->restore(); + break; + } + case PE_FrameButtonTool: + case PE_PanelButtonTool: + if(isMultiTabBarTab(getButton(widget, painter))) + { + if(!opts.stdSidebarButtons) + drawSideBarButton(painter, r, option, widget); + else if( (state&State_Enabled) || !(state&State_AutoRaise) ) + { + QStyleOption opt(*option); + opt.state|=STATE_TBAR_BUTTON; + drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget); + } + break; + } + case PE_IndicatorButtonDropDown: // This should never be called, but just in case - draw as a normal toolbutton... + { + bool dwt(widget && widget->inherits("QDockWidgetTitleButton")), + koDwt(!dwt && widget && widget->parentWidget() && widget->parentWidget()->inherits("KoDockWidgetTitleBar")); + + if( ((state&State_Enabled) || !(state&State_AutoRaise)) && + (!widget || !(dwt || koDwt)|| (state&State_MouseOver)) ) + { + QStyleOption opt(*option); + + if(dwt || koDwt) + opt.state|=STATE_DWT_BUTTON; + drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget); + } + break; + } + case PE_IndicatorDockWidgetResizeHandle: + { + QStyleOption dockWidgetHandle = *option; + bool horizontal = state&State_Horizontal; + if (horizontal) + dockWidgetHandle.state &= ~State_Horizontal; + else + dockWidgetHandle.state |= State_Horizontal; + drawControl(CE_Splitter, &dockWidgetHandle, painter, widget); + break; + } + case PE_PanelLineEdit: + if (const QStyleOptionFrame *panel = qstyleoption_cast(option)) + { + if(panel->lineWidth > 0) + { + QRect r2(r.adjusted(1, 1, -1, (DO_EFFECT ? -2 : -1))); + painter->fillPath(buildPath(r2, WIDGET_ENTRY, ROUNDED_ALL, qtcGetRadius(&opts, r2.width(), r2.height(), WIDGET_ENTRY, RADIUS_INTERNAL)), + palette.brush(QPalette::Base)); + drawPrimitive(PE_FrameLineEdit, option, painter, widget); + } + else + painter->fillRect(r.adjusted(2, 2, -2, -2), palette.brush(QPalette::Base)); + } + break; + case PE_FrameLineEdit: + if (const QStyleOptionFrame *lineEdit = qstyleoption_cast(option)) + { + if ((lineEdit->lineWidth>0 || isOOWidget(widget)) && + !(widget && + (qobject_cast(widget->parentWidget()) || + qobject_cast(widget->parentWidget())))) + { + QStyleOptionFrame opt(*lineEdit); + + if(opt.state&State_Enabled && state&State_ReadOnly) + opt.state^=State_Enabled; + + if(DO_EFFECT && opts.etchEntry && APP_ARORA==theThemedApp && widget && + widget->parentWidget() && 0==strcmp(widget->metaObject()->className(), "LocationBar")) + { + const QToolBar *tb=getToolBar(widget->parentWidget()/*, false*/); + + if(tb) + { + QRect r2(r); + + struct TB : public QToolBar + { + void initOpt(QStyleOptionToolBar *opt) { initStyleOption(opt); } + }; + + QStyleOptionToolBar opt; + + ((TB *)tb)->initOpt(&opt); + + painter->save(); + + // Only need to adjust coords if toolbar has a gradient... + if(!IS_FLAT(opts.toolbarAppearance)) + { + r2.setY(-widget->mapTo((QWidget *)tb, QPoint(r.x(), r.y())).y()); + r2.setHeight(tb->rect().height()); + } + painter->setClipRegion(QRegion(r2).subtract(QRegion(r2.adjusted(2, 2, -2, -2)))); + drawMenuOrToolBarBackground(widget, painter, r2, &opt, false, true); + painter->restore(); + } + } + painter->save(); + bool isOO(isOOWidget(widget)); + QRect rect(r); + int round(ROUNDED_ALL); + + if(isOO) + { + // This (hopefull) checks is we're OO.o 3.2 - in which case no adjustment is required... + const QImage *img=getImage(painter); + + if(!img || img->rect()!=r) // OO.o 3.1? + rect.adjust(1, 2, -1, -2); + else + { + round=ROUNDED_NONE; + painter->fillRect(r, palette.brush(QPalette::Window)); + rect.adjust(1, 1, -1, -1); + } + } + + drawEntryField(painter, rect, widget, &opt, round, isOO, !isOO && DO_EFFECT); + painter->restore(); + } + } + break; + case PE_Q3CheckListIndicator: + if (const QStyleOptionQ3ListView *lv = qstyleoption_cast(option)) + { + if(lv->items.isEmpty()) + break; + + QStyleOptionQ3ListViewItem item(lv->items.at(0)); + int x(lv->rect.x()), + w(lv->rect.width()), + marg(lv->itemMargin); + + if (state & State_Selected && !lv->rootIsDecorated && !(item.features & QStyleOptionQ3ListViewItem::ParentControl)) + painter->fillRect(0, 0, x + marg + w + 4, item.height, palette.brush(QPalette::Highlight)); + } + + r.setX(r.x()+((r.width()-opts.crSize)/2)-1); + r.setY(r.y()+((r.height()-opts.crSize)/2)-1); + r.setWidth(opts.crSize); + r.setHeight(opts.crSize); + case PE_IndicatorMenuCheckMark: + case PE_IndicatorCheckBox: + { + bool menu(state&STATE_MENU), + view(state&STATE_VIEW), + doEtch(DO_EFFECT && + (opts.crButton ||(PE_IndicatorMenuCheckMark!=element && !menu && + r.width()>=opts.crSize+2 && r.height()>=opts.crSize+2))), + isOO(isOOWidget(widget)), + selectedOOMenu(isOO && (r==QRect(0, 0, 15, 15) || r==QRect(0, 0, 14, 15)) && // OO.o 3.2 =14x15? + ((State_Sunken|State_Enabled)==state || (State_Sunken|State_Enabled|State_Selected)==state)); + int crSize(opts.crSize+(doEtch ? 2 : 0)); + QRect rect(r.x(), r.y()+(view ? -1 : 0), crSize, crSize); + + painter->save(); + + // For OO.o 3.2 need to fill widget background! + if(isOO) + painter->fillRect(r, palette.brush(QPalette::Window)); + + if(selectedOOMenu) + { + if(r==QRect(0, 0, 14, 15)) // OO.o 3.2 =14x15? + rect.adjust(-1, -1, -1, -1); + painter->setPen(option ? option->palette.text().color() : QApplication::palette().text().color()); + drawRect(painter, r); + // LibreOffice its 15x15 - and arrow is not centred, so adjust this... + if(r==QRect(0, 0, 15, 15)) + rect.adjust(-1, -1, -1, -1); + } + else + { + if(isOO && r==QRect(0, 0, opts.crSize, opts.crSize)) + rect.adjust(0, -1, 0, -1); + + if(CR_SMALL_SIZE!=opts.crSize) + { + if(menu) + rect.adjust(0, -1, 0, -1); + else if(r.height()>crSize) // Can only adjust position if there is space! + rect.adjust(0, 1, 0, 1); // ...when used in a listview, usually there is no space. + } + + if(opts.crButton) + { + const QColor *use(checkRadioColors(option)); + QStyleOption opt(*option); + + if(menu || selectedOOMenu) + opt.state&=~(State_MouseOver|State_Sunken); + opt.state&=~State_On; + opt.state|=State_Raised; + opt.rect=rect; + drawLightBevel(painter, rect, &opt, widget, ROUNDED_ALL, getFill(&opt, use, true, false), + use, true, WIDGET_CHECKBOX); + } + else + { + bool sunken(!menu && !selectedOOMenu && (state&State_Sunken)), + mo(!sunken && state&State_MouseOver && state&State_Enabled), + glow(doEtch && MO_GLOW==opts.coloredMouseOver && mo); + const QColor *bc(sunken ? 0L : borderColors(option, 0L)), + *btn(checkRadioColors(option)), + *use(bc ? bc : btn); + const QColor &bgnd(state&State_Enabled && !sunken + ? MO_NONE==opts.coloredMouseOver && !opts.crHighlight && mo + ? use[CR_MO_FILL] + : palette.base().color() + : palette.background().color()); + bool lightBorder=DRAW_LIGHT_BORDER(false, WIDGET_TROUGH, APPEARANCE_INVERTED); + + rect=QRect(doEtch ? rect.adjusted(1, 1, -1, -1) : rect); + + if(IS_FLAT(opts.appearance)) + painter->fillRect(rect.adjusted(1, 1, -1, -1), bgnd); + else + drawBevelGradient(bgnd, painter, rect.adjusted(1, 1, -1, -1), true, false, APPEARANCE_INVERTED, WIDGET_TROUGH); + + if(MO_NONE!=opts.coloredMouseOver && !glow && mo) + { + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(use[CR_MO_FILL]); + drawAaRect(painter, rect.adjusted(1, 1, -1, -1)); + painter->setRenderHint(QPainter::Antialiasing, false); + } + else + { + painter->setPen(midColor(state&State_Enabled ? palette.base().color() + : palette.background().color(), use[3])); + if(lightBorder) + drawRect(painter, rect.adjusted(1, 1, -1, -1)); + else + { + painter->drawLine(rect.x()+1, rect.y()+1, rect.x()+1, rect.y()+rect.height()-2); + painter->drawLine(rect.x()+1, rect.y()+1, rect.x()+rect.width()-2, rect.y()+1); + } + } + + if(doEtch && !view) + { + if(glow && !(opts.thin&THIN_FRAMES)) + drawGlow(painter, r, WIDGET_CHECKBOX); + else + drawEtch(painter, r, widget, WIDGET_CHECKBOX, opts.crButton && EFFECT_SHADOW==opts.buttonEffect ? !sunken : false); + } + + drawBorder(painter, rect, option, ROUNDED_ALL, use, WIDGET_CHECKBOX); + } + } + + if(state&State_On || selectedOOMenu) + { + QPixmap *pix(getPixmap(checkRadioCol(option), PIX_CHECK, 1.0)); + + painter->drawPixmap(rect.center().x()-(pix->width()/2), rect.center().y()-(pix->height()/2), *pix); + } + else if (state&State_NoChange) // tri-state + { + int x(rect.center().x()), y(rect.center().y()); + + painter->setPen(checkRadioCol(option)); + painter->drawLine(x-3, y, x+3, y); + painter->drawLine(x-3, y+1, x+3, y+1); + } + + painter->restore(); + break; + } + case PE_Q3CheckListExclusiveIndicator: + if (const QStyleOptionQ3ListView *lv = qstyleoption_cast(option)) + { + if(lv->items.isEmpty()) + break; + + QStyleOptionQ3ListViewItem item(lv->items.at(0)); + int x(lv->rect.x()), + w(lv->rect.width()), + marg(lv->itemMargin); + + if (state & State_Selected && !lv->rootIsDecorated && !(item.features & QStyleOptionQ3ListViewItem::ParentControl)) + painter->fillRect(0, 0, x + marg + w + 4, item.height, palette.brush(QPalette::Highlight)); + } + + r.setX(r.x()+((r.width()-opts.crSize)/2)-1); + r.setY(r.y()+((r.height()-opts.crSize)/2)-1); + r.setWidth(opts.crSize); + r.setHeight(opts.crSize); + case PE_IndicatorRadioButton: + { + bool isOO(isOOWidget(widget)), + selectedOOMenu(isOO && (r==QRect(0, 0, 15, 15) || r==QRect(0, 0, 14, 15)) && // OO.o 3.2 =14x15? + ((State_Sunken|State_Enabled)==state || (State_Sunken|State_Enabled|State_Selected)==state)); + + if(isOO) + painter->fillRect(r, palette.brush(QPalette::Background)); + + if(selectedOOMenu) + drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); + else + { + bool menu(state&STATE_MENU); + int x(r.x()), y(r.y()); + + painter->save(); + + if(opts.crButton) + { + const QColor *use(checkRadioColors(option)); + QStyleOption opt(*option); + bool doEtch(DO_EFFECT); + QRect rect(r.x(), r.y(), opts.crSize+(doEtch ? 2 : 0), opts.crSize+(doEtch ? 2 : 0)); + + if(CR_SMALL_SIZE!=opts.crSize && menu) + rect.adjust(0, -1, 0, -1), y++; + + if(isOO && r==QRect(0, 0, opts.crSize, opts.crSize)) + rect.adjust(-1, -1, -1, -1), --x, --y; + + if(menu || selectedOOMenu) + opt.state&=~(State_MouseOver|State_Sunken); + opt.state&=~State_On; + opt.state|=State_Raised; + opt.rect=rect; + + if(doEtch) + x++, y++; + if(CR_SMALL_SIZE!=opts.crSize && menu) + y-=2; + + drawLightBevel(painter, rect, &opt, widget, ROUNDED_ALL, getFill(&opt, use, true, false), use, true, WIDGET_RADIO_BUTTON); + } + else + { + bool sunken(!menu && !selectedOOMenu && (state&State_Sunken)), + doEtch(!menu + && r.width()>=opts.crSize+2 && r.height()>=opts.crSize+2 + && DO_EFFECT), + mo(!sunken && state&State_MouseOver && state&State_Enabled), + glow(doEtch && MO_GLOW==opts.coloredMouseOver && mo), + coloredMo(MO_NONE!=opts.coloredMouseOver && !glow && mo && !sunken); + bool lightBorder=DRAW_LIGHT_BORDER(false, WIDGET_TROUGH, APPEARANCE_INVERTED), + doneShadow=false; + QRect rect(doEtch ? r.adjusted(1, 1, -1, -1) : r); + const QColor *bc(sunken ? 0L : borderColors(option, 0L)), + *btn(checkRadioColors(option)), + *use(bc ? bc : btn); + + if(doEtch) + x++, y++; + + const QColor &bgnd(state&State_Enabled && !sunken + ? MO_NONE==opts.coloredMouseOver && !opts.crHighlight && mo + ? use[CR_MO_FILL] + : palette.base().color() + : palette.background().color()); + QPainterPath path; + + path.addEllipse(QRectF(rect).adjusted(0.5, 0.5, -1.0, -1.0)); + drawBevelGradient(bgnd, painter, rect.adjusted(1, 1, -1, -1), path, true, false, APPEARANCE_INVERTED, WIDGET_TROUGH); + painter->setRenderHint(QPainter::Antialiasing, true); + if(coloredMo) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(use[CR_MO_FILL]); + painter->drawArc(QRectF(x+1, y+1, opts.crSize-2, opts.crSize-2), 0, 360*16); + painter->drawArc(QRectF(x+2, y+2, opts.crSize-4, opts.crSize-4), 0, 360*16); + } + + painter->setBrush(Qt::NoBrush); + if(!doneShadow && doEtch && (glow || EFFECT_NONE!=opts.buttonEffect || sunken)) + { + QColor topCol(glow ? itsMouseOverCols[GLOW_MO] : Qt::black); + + if(!glow) + topCol.setAlphaF(ETCH_RADIO_TOP_ALPHA); + + painter->setPen(topCol); + painter->drawArc(QRectF(x-0.5, y-0.5, opts.crSize+1, opts.crSize+1), 45*16, 180*16); + if(!glow) + painter->setPen(getLowerEtchCol(widget)); + painter->drawArc(QRectF(x-0.5, y-0.5, opts.crSize+1, opts.crSize+1), 225*16, 180*16); + } + + painter->setPen(use[BORDER_VAL(state&State_Enabled)]); + painter->drawArc(QRectF(x+0.25, y+0.25, opts.crSize-0.5, opts.crSize-0.5), 0, 360*16); + if(!coloredMo) + { + painter->setPen(btn[state&State_MouseOver ? 3 : 4]); + painter->drawArc(QRectF(x+0.75, y+0.75, opts.crSize-1.5, opts.crSize-1.5), lightBorder ? 0 : 45*16, lightBorder ? 360*16 : 180*16); + } + } + if(state&State_On || selectedOOMenu) + { + QPainterPath path; + double radius=opts.smallRadio ? 2.75 : 3.75, + offset=(opts.crSize/2.0)-radius; + + path.addEllipse(QRectF(x+offset, y+offset, radius*2.0, radius*2.0)); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->fillPath(path, checkRadioCol(option)); + } + + painter->restore(); + } + break; + } + case PE_IndicatorToolBarHandle: + painter->save(); + drawHandleMarkers(painter, r, option, true, opts.handles); + painter->restore(); + break; + case PE_FrameFocusRect: + if (const QStyleOptionFocusRect *focusFrame = qstyleoption_cast(option)) + { + if (!(focusFrame->state&State_KeyboardFocusChange) || + (widget && widget->inherits("QComboBoxListView"))) + return; + + if(widget && FOCUS_GLOW==opts.focus) + { + if(::qobject_cast(widget)) + { + if(!::qobject_cast(widget) || !static_cast(widget)->autoRaise()) + return; + } + else if(::qobject_cast(widget) || ::qobject_cast(widget) || + ::qobject_cast(widget)) + return; + } + + QRect r2(r); + + if(widget && (::qobject_cast(widget) || ::qobject_cast(widget)) && + ((QAbstractButton *)widget)->text().isEmpty() && r.height()<=widget->rect().height()-2 && r.width()<=widget->rect().width()-2 && + r.x()>=1 && r.y()>=1) + { + int adjust=qMin(qMin(abs(widget->rect().x()-r.x()), 2), abs(widget->rect().y()-r.y())); + r2.adjust(-adjust, -adjust, adjust, adjust); + } + + if(widget && ::qobject_cast(widget)) + r2.adjust(0, 2, 0, 0); + + if(FOCUS_STANDARD==opts.focus) + { + // Taken from QWindowsStyle... + painter->save(); + painter->setBackgroundMode(Qt::TransparentMode); + QColor bgCol(focusFrame->backgroundColor); + if (!bgCol.isValid()) + bgCol = painter->background().color(); + // Create an "XOR" color. + QColor patternCol((bgCol.red() ^ 0xff) & 0xff, + (bgCol.green() ^ 0xff) & 0xff, + (bgCol.blue() ^ 0xff) & 0xff); + painter->setBrush(QBrush(patternCol, Qt::Dense4Pattern)); + painter->setBrushOrigin(r.topLeft()); + painter->setPen(Qt::NoPen); + painter->drawRect(r.left(), r.top(), r.width(), 1); // Top + painter->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom + painter->drawRect(r.left(), r.top(), 1, r.height()); // Left + painter->drawRect(r.right(), r.top(), 1, r.height()); // Right + painter->restore(); + } + else + { + //Figuring out in what beast we are painting... + bool view(state&State_Item || + ((widget && ((qobject_cast(widget)) || + widget->inherits("Q3ScrollView"))) || + (widget && widget->parent() && + ((qobject_cast(widget->parent())) || + widget->parent()->inherits("Q3ScrollView")))) ); + + if(!view && !widget) + { + // Try to determine if we are in a KPageView... + const QWidget *wid=getWidget(painter); + + if(wid && wid->parentWidget()) + { + if(wid->parentWidget()->inherits("KDEPrivate::KPageListView")) + { + r2.adjust(2, 2, -2, -2); + view=true; + } + else if(APP_KONTACT==theThemedApp && (wid->parentWidget()->inherits("KMail::MainFolderView") || + wid->parentWidget()->inherits("MessageList::Core::View"))) + { + view=true; + } + } + } + painter->save(); + QColor c(view && state&State_Selected + ? palette.highlightedText().color() + : itsFocusCols[FOCUS_SHADE(state&State_Selected)]); + + if(FOCUS_LINE==opts.focus || FOCUS_GLOW==opts.focus) + { + if(!(state&State_Horizontal) && widget && qobject_cast(widget)) + drawFadedLine(painter, QRect(r2.x()+r2.width()-1, r2.y(), 1, r2.height()), c, true, true, false); + else + drawFadedLine(painter, QRect(r2.x(), r2.y()+r2.height()-(view ? 3 : 1), r2.width(), 1), c, true, true, true); + } + else + { + //if(FOCUS_GLOW==opts.focus) + // c.setAlphaF(FOCUS_GLOW_LINE_ALPHA); + painter->setPen(c); + if(FOCUS_FILLED==opts.focus) + { + c.setAlphaF(FOCUS_ALPHA); + painter->setBrush(c); + } + + if(ROUNDED) + { + bool square((opts.square&SQUARE_LISTVIEW_SELECTION) && + ( (/*(!widget && r.height()<=40 && r.width()>=48) || */ + (widget && !widget->inherits("KFilePlacesView") && + (qobject_cast(widget) || + (qobject_cast(widget) && + QListView::IconMode!=((const QListView *)widget)->viewMode())))) || + (!widget && view) ) ); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawPath(buildPath(r2, WIDGET_SELECTION, ROUNDED_ALL, + square ? SLIGHT_INNER_RADIUS : qtcGetRadius(&opts, r2.width(), r2.height(), WIDGET_OTHER, + FULL_FOCUS ? RADIUS_EXTERNAL : RADIUS_SELECTION))); + } + else + drawRect(painter, r2); + } + painter->restore(); + } + } + break; + case PE_FrameButtonBevel: + case PE_PanelButtonBevel: + case PE_PanelButtonCommand: + { + if(state&STATE_DWT_BUTTON && (opts.dwtSettings&DWT_BUTTONS_AS_PER_TITLEBAR)) + break; + + bool doEtch(DO_EFFECT); + + // This fixes the "Sign in" button at mail.lycos.co.uk + // ...basically if KHTML gices us a fully transparent background colour, then + // dont paint the button. + if(0==option->palette.button().color().alpha()) + { + if(state&State_MouseOver && state&State_Enabled && MO_GLOW==opts.coloredMouseOver && doEtch && !(opts.thin&THIN_FRAMES)) + drawGlow(painter, r, WIDGET_STD_BUTTON); + return; + } + + if(!widget) + widget=getWidget(painter); + + const QColor *use(buttonColors(option)); + bool isDefault(false), + isFlat(false), + isKWin(state&QtC_StateKWin), + isDown(state&State_Sunken || state&State_On), + isOnListView(!isKWin && widget && qobject_cast(widget)); + QStyleOption opt(*option); + + if(PE_PanelButtonBevel==element) + opt.state|=State_Enabled; + + if (const QStyleOptionButton *button = qstyleoption_cast(option)) + { + isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state&State_Enabled); + isFlat = (button->features & QStyleOptionButton::Flat); + } + + if(!(opt.state&State_Enabled)) + opt.state&=~State_MouseOver; + + // For some reason with OO.o not all buttons are set as raised! + if(!(opt.state&State_AutoRaise)) + opt.state|=State_Raised; + + isDefault=isDefault || (doEtch && FULL_FOCUS && MO_GLOW==opts.coloredMouseOver && + opt.state&State_HasFocus && opt.state&State_Enabled); + if(isFlat && !isDown && !(opt.state&State_MouseOver)) + return; + + painter->save(); + + if(isOnListView) + opt.state|=State_Horizontal|State_Raised; + + if(isDefault && state&State_Enabled && (IND_TINT==opts.defBtnIndicator || IND_SELECTED==opts.defBtnIndicator)) + use=itsDefBtnCols; + else if(state&STATE_DWT_BUTTON && widget && opts.titlebarButtons&TITLEBAR_BUTTON_COLOR && + coloredMdiButtons(state&State_Active, state&State_MouseOver) && + !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL)) + { + if(constDwtClose==widget->objectName()) + use=itsTitleBarButtonsCols[TITLEBAR_CLOSE]; + else if(constDwtFloat==widget->objectName()) + use=itsTitleBarButtonsCols[TITLEBAR_MAX]; + else if(widget->parentWidget() && widget->parentWidget()->parentWidget() && + widget->parentWidget()->inherits("KoDockWidgetTitleBar") && + ::qobject_cast(widget->parentWidget()->parentWidget())) + { + QDockWidget *dw = (QDockWidget *)widget->parentWidget()->parentWidget(); + QWidget *koDw = widget->parentWidget(); + int fw = dw->isFloating() + ? pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, dw) + : 0; + QRect geom(widget->geometry()); + QStyleOptionDockWidgetV2 dwOpt; + dwOpt.initFrom(dw); + dwOpt.rect = QRect(QPoint(fw, fw), QSize(koDw->geometry().width() - (fw * 2), + koDw->geometry().height() - (fw * 2))); + dwOpt.title = dw->windowTitle(); + dwOpt.closable = (dw->features()&QDockWidget::DockWidgetClosable)==QDockWidget::DockWidgetClosable; + dwOpt.floatable = (dw->features()&QDockWidget::DockWidgetFloatable)==QDockWidget::DockWidgetFloatable; + + if(dwOpt.closable && + subElementRect(QStyle::SE_DockWidgetCloseButton, &dwOpt, widget->parentWidget()->parentWidget())==geom) + use=itsTitleBarButtonsCols[TITLEBAR_CLOSE]; + else if(dwOpt.floatable && + subElementRect(QStyle::SE_DockWidgetFloatButton, &dwOpt, + widget->parentWidget()->parentWidget())==geom) + use=itsTitleBarButtonsCols[TITLEBAR_MAX]; + else + use=itsTitleBarButtonsCols[TITLEBAR_SHADE]; + } + } + + if(isKWin) + opt.state|=STATE_KWIN_BUTTON; + + bool coloredDef=isDefault && state&State_Enabled && IND_COLORED==opts.defBtnIndicator; + + if(widget && qobject_cast(widget) && (static_cast(widget))->isCheckable()) + opt.state|=STATE_TOGGLE_BUTTON; + + drawLightBevel(painter, r, &opt, widget, ROUNDED_ALL, + coloredDef ? itsDefBtnCols[MO_DEF_BTN] + : getFill(&opt, use, false, + isDefault && state&State_Enabled && IND_DARKEN==opts.defBtnIndicator), + coloredDef ? itsDefBtnCols : use, + true, isKWin || state&STATE_DWT_BUTTON + ? WIDGET_MDI_WINDOW_BUTTON + : isOnListView + ? WIDGET_NO_ETCH_BTN + : isDefault && state&State_Enabled + ? WIDGET_DEF_BUTTON + : state&STATE_TBAR_BUTTON + ? WIDGET_TOOLBAR_BUTTON + : WIDGET_STD_BUTTON); + + if (isDefault && state&State_Enabled) + switch(opts.defBtnIndicator) + { + case IND_CORNER: + { + QPainterPath path; + int offset(isDown ? 5 : 4), + etchOffset(doEtch ? 1 : 0); + double xd(r.x()+0.5), + yd(r.y()+0.5); + const QColor *cols(itsFocusCols ? itsFocusCols : itsHighlightCols); + + path.moveTo(xd+offset+etchOffset, yd+offset+etchOffset); + path.lineTo(xd+offset+6+etchOffset, yd+offset+etchOffset); + path.lineTo(xd+offset+etchOffset, yd+offset+6+etchOffset); + path.lineTo(xd+offset+etchOffset, yd+offset+etchOffset); + painter->setBrush(cols[isDown ? 0 : 4]); + painter->setPen(cols[isDown ? 0 : 4]); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawPath(path); + painter->setRenderHint(QPainter::Antialiasing, false); + break; + } + case IND_COLORED: + { + int offset=COLORED_BORDER_SIZE+(doEtch ? 1 : 0); + QRect r2(r.adjusted(offset, offset, -offset, -offset)); + + drawBevelGradient(getFill(&opt, use), painter, r2, true, state &(State_On | State_Sunken), opts.appearance, WIDGET_STD_BUTTON); + } + default: + break; + } + painter->restore(); + break; + } + case PE_FrameDefaultButton: + break; + case PE_FrameWindow: + { + bool colTbarOnly=opts.windowBorder&WINDOW_BORDER_COLOR_TITLEBAR_ONLY, + fillBgnd=!(state&QtC_StateKWin) && !itsIsPreview && !IS_FLAT_BGND(opts.bgndAppearance); + const QColor *bgndCols(colTbarOnly || fillBgnd ? backgroundColors(palette.color(QPalette::Active, QPalette::Window)) : 0L), + *borderCols(colTbarOnly + ? bgndCols + : theThemedApp==APP_KWIN + ? buttonColors(option) + : getMdiColors(option, state&State_Active)); + QColor light(borderCols[0]), + dark(option->version==(TBAR_BORDER_VERSION_HACK+2) + ? palette.color(QPalette::Active, QPalette::Shadow) + : borderCols[option && option->version==TBAR_BORDER_VERSION_HACK ? 0 : STD_BORDER]); + bool isKWin=state&QtC_StateKWin, + addLight=opts.windowBorder&WINDOW_BORDER_ADD_LIGHT_BORDER && (!isKWin || qtcGetWindowBorderSize().sides>1); + + light.setAlphaF(1.0); + dark.setAlphaF(1.0); + + painter->save(); + + if(fillBgnd) + painter->fillRect(r, bgndCols[ORIGINAL_SHADE]); + if(opts.roundsetRenderHint(QPainter::Antialiasing, false); + + if(addLight) + { + painter->setPen(light); + painter->drawLine(r.x()+1, r.y(), r.x()+1, r.y()+r.height()-1); + } + painter->setPen(dark); + drawRect(painter, r); + } + else + { + if(addLight) + { + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setPen(light); + painter->drawLine(r.x()+1, r.y(), r.x()+1, r.y()+r.height()-(1+(opts.round>ROUND_SLIGHT && state&QtC_StateKWin ? 3 : 1))); + } + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(dark); + painter->drawPath(buildPath(r, WIDGET_OTHER, ROUNDED_ALL, + opts.round>ROUND_SLIGHT && state&QtC_StateKWin + ? 6.0 + : 2.0)); + + if(FULLLY_ROUNDED && !(state&QtC_StateKWinCompositing)) + { + QColor col(opts.windowBorder&WINDOW_BORDER_COLOR_TITLEBAR_ONLY + ? backgroundColors(option)[STD_BORDER] + : buttonColors(option)[STD_BORDER]); + + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setPen(col); + painter->drawPoint(r.x()+2, r.y()+r.height()-3); + painter->drawPoint(r.x()+r.width()-3, r.y()+r.height()-3); + painter->drawLine(r.x()+1, r.y()+r.height()-5, r.x()+1, r.y()+r.height()-4); + painter->drawLine(r.x()+3, r.y()+r.height()-2, r.x()+4, r.y()+r.height()-2); + painter->drawLine(r.x()+r.width()-2, r.y()+r.height()-5, r.x()+r.width()-2, r.y()+r.height()-4); + painter->drawLine(r.x()+r.width()-4, r.y()+r.height()-2, r.x()+r.width()-5, r.y()+r.height()-2); + } + } + painter->restore(); + break; + } + case PE_FrameTabWidget: + { + int round(opts.square&SQUARE_TAB_FRAME ? ROUNDED_NONE : ROUNDED_ALL); + + painter->save(); + + if(const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast(option)) + if((opts.round || (/*CUSTOM_BGND && */0==opts.tabBgnd)) && + widget && ::qobject_cast(widget)) + { + struct QtcTabWidget : public QTabWidget + { + bool tabsVisible() const { return tabBar() && tabBar()->isVisible(); } + QRect currentTabRect() const { return tabBar()->tabRect(tabBar()->currentIndex()); } + }; + + const QTabWidget *tw((const QTabWidget *)widget); + + if(tw->count()>0 && ((const QtcTabWidget *)widget)->tabsVisible()) + { + if(!reverse && /*CUSTOM_BGND && */0==opts.tabBgnd) // Does not work for reverse :-( + { + QRect tabRect(((const QtcTabWidget *)widget)->currentTabRect()); + int adjust(TAB_MO_GLOW==opts.tabMouseOver && !(opts.thin&THIN_FRAMES) ? 2 : 1); + + switch(tw->tabPosition()) + { + case QTabWidget::South: + tabRect=QRect(tabRect.x()+adjust, r.y()+r.height()-2, tabRect.width()-(2*adjust), 4); + break; + case QTabWidget::North: + { + int leftAdjust=twf->leftCornerWidgetSize.width()>0 ? twf->leftCornerWidgetSize.width() : 0; + tabRect.adjust(leftAdjust+adjust, 0, leftAdjust-adjust, 2); + break; + } + case QTabWidget::West: + tabRect.adjust(0, adjust, 2, -adjust); + break; + case QTabWidget::East: + tabRect=QRect(r.x()+r.width()-2, tabRect.y()+adjust, 4, tabRect.height()-(2*adjust)); + break; + } + + painter->setClipRegion(QRegion(r).subtract(tabRect), Qt::IntersectClip); + } + + if(!(opts.square&SQUARE_TAB_FRAME) && 0==tw->currentIndex()) + { + bool reverse(Qt::RightToLeft==twf->direction); + + switch(tw->tabPosition()) + { + case QTabWidget::North: + if(reverse && twf->rightCornerWidgetSize.isEmpty()) + round-=CORNER_TR; + else if(!reverse && twf->leftCornerWidgetSize.isEmpty()) + round-=CORNER_TL; + break; + case QTabWidget::South: + if(reverse && twf->rightCornerWidgetSize.isEmpty()) + round-=CORNER_BR; + else if(!reverse && twf->leftCornerWidgetSize.isEmpty()) + round-=CORNER_BL; + break; + case QTabWidget::West: + round-=CORNER_TL; + break; + case QTabWidget::East: + round-=CORNER_TR; + break; + } + } + } + } + + QStyleOption opt(*option); + const QColor *use=backgroundColors(option); + + opt.state|=State_Enabled; + if(0!=opts.tabBgnd) + { + QColor bgnd(shade(use[ORIGINAL_SHADE], TO_FACTOR(opts.tabBgnd))); + + painter->fillRect(r.adjusted(0, 1, 0, -1), bgnd); + painter->fillRect(r.adjusted(1, 0, -1, 0), bgnd); + } + drawBorder(painter, r, &opt, round, use, WIDGET_TAB_FRAME, opts.borderTab ? BORDER_LIGHT : BORDER_RAISED, false); + painter->restore(); + break; + } +#if QT_VERSION >= 0x040400 + case PE_PanelItemViewItem: + { + const QStyleOptionViewItemV4 *v4Opt = qstyleoption_cast(option); + const QAbstractItemView *view = qobject_cast(widget); + bool hover = state&State_MouseOver && state&State_Enabled && (!view || + QAbstractItemView::NoSelection!=view->selectionMode()), + hasCustomBackground = v4Opt->backgroundBrush.style() != Qt::NoBrush && + !(option->state & State_Selected), + hasSolidBackground = !hasCustomBackground || Qt::SolidPattern==v4Opt->backgroundBrush.style(); + + if (!hover && !(state & State_Selected) && !hasCustomBackground && + !(v4Opt->features & QStyleOptionViewItemV2::Alternate)) + break; + + QPalette::ColorGroup cg(state&State_Enabled + ? state&State_Active + ? QPalette::Normal + : QPalette::Inactive + : QPalette::Disabled); + + if (v4Opt && (v4Opt->features & QStyleOptionViewItemV2::Alternate)) + painter->fillRect(r, option->palette.brush(cg, QPalette::AlternateBase)); + + if (!hover && !(state&State_Selected) && !hasCustomBackground) + break; + + if(hasCustomBackground) + { + const QPointF prevOrigin(painter->brushOrigin()); + + painter->setBrushOrigin(r.topLeft()); + painter->fillRect(r, v4Opt->backgroundBrush); + painter->setBrushOrigin(prevOrigin); + } + + if(state&State_Selected || hover) + { + if(!widget) + { + widget=getWidget(painter); + if(widget) + widget=widget->parentWidget(); + } + + QColor color(hasCustomBackground && hasSolidBackground + ? v4Opt->backgroundBrush.color() + : palette.color(cg, QPalette::Highlight)); + bool square((opts.square&SQUARE_LISTVIEW_SELECTION) && + (/*(!widget && r.height()<=40 && r.width()>=48) || */ + (widget && !widget->inherits("KFilePlacesView") && + (qobject_cast(widget) || + (qobject_cast(widget) && + QListView::IconMode!=((const QListView *)widget)->viewMode()))))), + modAlpha(!(state&State_Active) && itsInactiveChangeSelectionColor); + + if (hover && !hasCustomBackground) + { + if (!(state & State_Selected)) + color.setAlphaF(APP_PLASMA==theThemedApp && !widget ? (0.5 * (modAlpha ? 0.75 : 1.0)) : 0.20); + else + { + color = color.lighter(110); + if(modAlpha) + color.setAlphaF(INACTIVE_SEL_ALPHA); + } + } + else if(modAlpha) + color.setAlphaF(color.alphaF()*INACTIVE_SEL_ALPHA); + + if(square) + drawBevelGradient(color, painter, r, true, false, opts.selectionAppearance, WIDGET_SELECTION); + else + { + QPixmap pix; + QString key; + + key.sprintf("qtc-sel-%x-%x", r.height(), color.rgba()); + if(!itsUsePixmapCache || !QPixmapCache::find(key, pix)) + { + pix=QPixmap(QSize(24, r.height())); + pix.fill(Qt::transparent); + + QPainter pixPainter(&pix); + QRect border(0, 0, pix.width(), pix.height()); + double radius(qtcGetRadius(&opts, r.width(), r.height(), WIDGET_OTHER, RADIUS_SELECTION)); + + pixPainter.setRenderHint(QPainter::Antialiasing, true); + drawBevelGradient(color, &pixPainter, border, buildPath(QRectF(border), WIDGET_OTHER, ROUNDED_ALL, radius), true, + false, opts.selectionAppearance, WIDGET_SELECTION, false); + if(opts.borderSelection) + { + pixPainter.setBrush(Qt::NoBrush); + pixPainter.setPen(color); + pixPainter.drawPath(buildPath(border, WIDGET_SELECTION, ROUNDED_ALL, radius)); + } + pixPainter.end(); + if(itsUsePixmapCache) + QPixmapCache::insert(key, pix); + } + + bool roundedLeft = false, + roundedRight = false; + + if (v4Opt) + { + roundedLeft = (QStyleOptionViewItemV4::Beginning==v4Opt->viewItemPosition); + roundedRight = (QStyleOptionViewItemV4::End==v4Opt->viewItemPosition); + if (QStyleOptionViewItemV4::OnlyOne==v4Opt->viewItemPosition || + QStyleOptionViewItemV4::Invalid==v4Opt->viewItemPosition || + (view && view->selectionBehavior() != QAbstractItemView::SelectRows)) + { + roundedLeft=roundedRight=true; + } + } + + int size(roundedLeft && roundedRight ? qMin(8, r.width()/2) : 8); + + if (!reverse ? roundedLeft : roundedRight) + { + painter->drawPixmap(r.topLeft(), pix.copy(0, 0, size, r.height())); + r.adjust(size, 0, 0, 0); + } + if (!reverse ? roundedRight : roundedLeft) + { + painter->drawPixmap(r.right() - size + 1, r.top(), pix.copy(24-size, 0, size, r.height())); + r.adjust(0, 0, -size, 0); + } + if (r.isValid()) + painter->drawTiledPixmap(r, pix.copy(7, 0, 8, r.height())); + } + } + break; + } +#endif + case QtC_PE_DrawBackground: + if (const QtCurve::Style::BgndOption *bgnd = qstyleoption_cast(option)) + if(state&QtC_StateKWin) + { + QColor col(palette.brush(QPalette::Window).color()); + int opacity(col.alphaF()*100); + + col.setAlphaF(1.0); + drawBackground(painter, col, r, opacity, BGND_WINDOW, bgnd->app, bgnd->path); + // APPEARANCE_RAISED is used to signal flat background, but have background image! + if(APPEARANCE_FLAT!=bgnd->app) + { + painter->save(); + painter->setClipRect(bgnd->rect, Qt::IntersectClip); + drawBackgroundImage(painter, true, BGND_IMG_ON_BORDER ? bgnd->rect : bgnd->widgetRect); + painter->restore(); + } + } + break; + // TODO: This is the only part left from QWindowsStyle - but I dont think its actually used! + // case PE_IndicatorProgressChunk: + case PE_PanelTipLabel: + { + bool haveAlpha=Utils::hasAlphaChannel(widget) && APP_OPERA!=theThemedApp, + rounded=!(opts.square&SQUARE_TOOLTIPS) && APP_OPERA!=theThemedApp; + QPainterPath path=rounded ? buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, MENU_AND_TOOLTIP_RADIUS) : QPainterPath(); + QColor col=palette.toolTipBase().color(); + + #ifdef Q_WS_X11 + if(widget && widget->window()) + itsShadowHelper->registerWidget(widget->window()); + #endif + painter->save(); + if(rounded) + painter->setRenderHint(QPainter::Antialiasing, true); + if(haveAlpha) + col.setAlphaF(0.875); + drawBevelGradient(col, painter, r, path, true, false, opts.tooltipAppearance, WIDGET_TOOLTIP, !haveAlpha); + if(IS_FLAT(opts.tooltipAppearance)) + { + painter->setPen(QPen(palette.toolTipText(), 0)); + drawRect(painter, r); + } + painter->restore(); + break; + } + // Fall through! + default: + BASE_STYLE::drawPrimitive(element, option, painter, widget); + break; + } +} + +void Style::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + QRect r(option->rect); + const QFlags &state(option->state); + const QPalette &palette(option->palette); + bool reverse(Qt::RightToLeft==option->direction); + + switch((int)element) + { + case CE_QtC_SetOptions: + if (const PreviewOption *preview = qstyleoption_cast(option)) + { + if(!painter && widget && QLatin1String("QtCurveConfigDialog")==widget->objectName()) + { + Style *that=(Style *)this; + opts=preview->opts; + qtcCheckConfig(&opts); + that->init(true); + } + } + break; + case CE_QtC_Preview: + if (const PreviewOption *preview = qstyleoption_cast(option)) + { + if(widget && widget && QLatin1String("QtCurveConfigDialog-GradientPreview")==widget->objectName()) + { + Options old=opts; + const QColor *use(buttonColors(option)); + opts=preview->opts; + + drawLightBevelReal(painter, r, option, widget, ROUNDED_ALL, getFill(option, use, false, false), use, + true, WIDGET_STD_BUTTON, false, opts.round, false); + opts=old; + } + } + break; + case CE_QtC_KCapacityBar: + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(option)) + { + QStyleOptionProgressBar mod(*bar); + + if(mod.rect.height()>16 && widget->parentWidget() && + (qobject_cast(widget->parentWidget()) || + widget->parentWidget()->inherits("DolphinStatusBar"))) + { + int m=(mod.rect.height()-16)/2; + mod.rect.adjust(0, m, 0, -m); + } + drawControl(CE_ProgressBarGroove, &mod, painter, widget); + if(DO_EFFECT && opts.borderProgress) + mod.rect.adjust(1, 1, -1, -1); + drawControl(CE_ProgressBarContents, &mod, painter, widget); + drawControl(CE_ProgressBarLabel, &mod, painter, widget); + } + break; + case CE_ToolBoxTabShape: + { + const QStyleOptionToolBox *tb = qstyleoption_cast(option); + if(!(tb && widget)) + break; + + const QColor *use = backgroundColors(widget->palette().color(QPalette::Window)); + QPainterPath path; + int y = r.height()*15/100; + + painter->save(); + if (reverse) + { + path.moveTo(r.left()+52, r.top()); + path.cubicTo(QPointF(r.left()+50-8, r.top()), QPointF(r.left()+50-10, r.top()+y), QPointF(r.left()+50-10, r.top()+y)); + path.lineTo(r.left()+18+9, r.bottom()-y); + path.cubicTo(QPointF(r.left()+18+9, r.bottom()-y), QPointF(r.left()+19+6, r.bottom()-1-0.3), QPointF(r.left()+19, r.bottom()-1-0.3)); + } + else + { + path.moveTo(r.right()-52, r.top()); + path.cubicTo(QPointF(r.right()-50+8, r.top()), QPointF(r.right()-50+10, r.top()+y), QPointF(r.right()-50+10, r.top()+y)); + path.lineTo(r.right()-18-9, r.bottom()-y); + path.cubicTo(QPointF(r.right()-18-9, r.bottom()-y), QPointF(r.right()-19-6, r.bottom()-1-0.3), QPointF(r.right()-19, r.bottom()-1-0.3)); + } + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->translate(0, 1); + painter->setPen(use[0]); + painter->drawPath(path); + painter->translate(0, -1); + painter->setPen(use[4]); + painter->drawPath(path); + painter->setRenderHint(QPainter::Antialiasing, false); + if (reverse) + { + painter->drawLine(r.left()+50-1, r.top(), r.right(), r.top()); + painter->drawLine(r.left()+20, r.bottom()-2, r.left(), r.bottom()-2); + painter->setPen(use[0]); + painter->drawLine(r.left()+50, r.top()+1, r.right(), r.top()+1); + painter->drawLine(r.left()+20, r.bottom()-1, r.left(), r.bottom()-1); + } + else + { + painter->drawLine(r.left(), r.top(), r.right()-50+1, r.top()); + painter->drawLine(r.right()-20, r.bottom()-2, r.right(), r.bottom()-2); + painter->setPen(use[0]); + painter->drawLine(r.left(), r.top()+1, r.right()-50, r.top()+1); + painter->drawLine(r.right()-20, r.bottom()-1, r.right(), r.bottom()-1); + } + painter->restore(); + break; + } + case CE_MenuScroller: + { + const QColor *use(popupMenuCols()); + painter->fillRect(r, use[ORIGINAL_SHADE]); + painter->setPen(use[STD_BORDER]); + drawRect(painter, r); + drawPrimitive(((state&State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp), option, painter, widget); + break; + } + case CE_RubberBand: // Rubber band used in such things as iconview. + { + if(r.width()>0 && r.height()>0) + { + painter->save(); + QColor c(itsHighlightCols[ORIGINAL_SHADE]); + + painter->setClipRegion(r); + painter->setPen(c); + c.setAlpha(50); + painter->setBrush(c); + drawRect(painter, r); + painter->restore(); + } + break; + } + case CE_Splitter: + { + const QColor *use(buttonColors(option)); + const QColor *border(borderColors(option, use)); + // In Amarok nightly (2.2) State_Horizontal doesn't seem to always be set... + bool horiz(state&State_Horizontal || (r.height()>6 && r.height()>r.width())); + + painter->save(); + if(/*IS_FLAT_BGND(opts.bgndAppearance) || */state&State_MouseOver && state&State_Enabled) + { + QColor color(palette.color(QPalette::Active, QPalette::Window)); + + if(state&State_MouseOver && state&State_Enabled && opts.splitterHighlight) + if(ROUND_NONE!=opts.round) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + double radius(qtcGetRadius(&opts, r.width(), r.height(), WIDGET_OTHER, RADIUS_SELECTION)); + + drawBevelGradient(shade(palette.background().color(), TO_FACTOR(opts.splitterHighlight)), + painter, r, buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, radius), + !(state&State_Horizontal), false, opts.selectionAppearance, WIDGET_SELECTION, false); + painter->restore(); + } + else + drawBevelGradient(shade(palette.background().color(), TO_FACTOR(opts.splitterHighlight)), painter, + r, !(state&State_Horizontal), false, opts.selectionAppearance, WIDGET_SELECTION); + else + painter->fillRect(r, color); + } + + switch(opts.splitters) + { + case LINE_NONE: + break; + case LINE_1DOT: + painter->drawPixmap(r.x()+((r.width()-5)/2), r.y()+((r.height()-5)/2), *getPixmap(border[STD_BORDER], PIX_DOT, 1.0)); + break; + default: + case LINE_DOTS: + drawDots(painter, r, horiz, NUM_SPLITTER_DASHES, 1, border, 0, 5); + break; + case LINE_FLAT: + case LINE_SUNKEN: + case LINE_DASHES: + drawLines(painter, r, horiz, NUM_SPLITTER_DASHES, 3, border, 0, 3, opts.splitters); + } + painter->restore(); + break; + } + case CE_SizeGrip: + { + QPolygon triangle(3); + Qt::Corner corner; + int size=SIZE_GRIP_SIZE-2; + + if (const QStyleOptionSizeGrip *sgrp = qstyleoption_cast(option)) + corner = sgrp->corner; + else if (Qt::RightToLeft==option->direction) + corner = Qt::BottomLeftCorner; + else + corner = Qt::BottomRightCorner; + + switch(corner) + { + case Qt::BottomLeftCorner: + triangle.putPoints(0, 3, 0,0, size,size, 0,size); + triangle.translate(r.x(), r.y()+(r.height()-(SIZE_GRIP_SIZE-1))); + break; + case Qt::BottomRightCorner: + triangle.putPoints(0, 3, size,0, size,size, 0,size); + triangle.translate(r.x()+(r.width()-(SIZE_GRIP_SIZE-1)), r.y()+(r.height()-(SIZE_GRIP_SIZE-1))); + break; + case Qt::TopRightCorner: + triangle.putPoints(0, 3, 0,0, size,0, size,size); + triangle.translate(r.x()+(r.width()-(SIZE_GRIP_SIZE-1)), r.y()); + break; + case Qt::TopLeftCorner: + triangle.putPoints(0, 3, 0,0, size,0, 0,size); + triangle.translate(r.x(), r.y()); + } + painter->save(); + painter->setPen(itsBackgroundCols[2]); + painter->setBrush(itsBackgroundCols[2]); + painter->drawPolygon(triangle); + painter->restore(); + break; + } + case CE_ToolBar: + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast(option)) + { + if(!widget || !widget->parent() || qobject_cast(widget->parent())) + { + painter->save(); + drawMenuOrToolBarBackground(widget, painter, r, option, false, Qt::NoToolBarArea==toolbar->toolBarArea || + Qt::BottomToolBarArea==toolbar->toolBarArea || + Qt::TopToolBarArea==toolbar->toolBarArea); + if(TB_NONE!=opts.toolbarBorders) + { + const QColor *use=/*PE_PanelMenuBar==pe && itsActive + ? itsMenubarCols + : */ backgroundColors(option); + bool dark(TB_DARK==opts.toolbarBorders || TB_DARK_ALL==opts.toolbarBorders); + + if(TB_DARK_ALL==opts.toolbarBorders || TB_LIGHT_ALL==opts.toolbarBorders) + { + painter->setPen(use[0]); + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); + painter->setPen(use[dark ? 3 : 4]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + } + else + { + bool paintH(true), + paintV(true); + + switch (toolbar->toolBarArea) + { + case Qt::BottomToolBarArea: + case Qt::TopToolBarArea: + paintV=false; + break; + case Qt::RightToolBarArea: + case Qt::LeftToolBarArea: + paintH=false; + default: + break; + } + + painter->setPen(use[0]); + if(paintH) + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + if(paintV) + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); + painter->setPen(use[dark ? 3 : 4]); + if(paintH) + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + if(paintV) + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + } + } + painter->restore(); + } + } + break; + case CE_DockWidgetTitle: + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast(option)) + { +#if QT_VERSION >= 0x040300 + const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast(dwOpt); + bool verticalTitleBar(v2 == 0 ? false : v2->verticalTitleBar); +#else + bool verticalTitleBar(false); +#endif + bool isKOffice(widget && widget->inherits("KoDockWidgetTitleBar")); + QRect fillRect(r); + + // This fixes the look of KOffice's dock widget titlebars... + if(isKOffice) + fillRect.adjust(-r.x(), -r.y(), 0, 0); + + if(!IS_FLAT(opts.dwtAppearance)) + { + painter->save(); + + QColor col((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR) + ? getMdiColors(option, state&State_Active)[ORIGINAL_SHADE] + : palette.background().color()); + if(opts.round= 0x040300 + if(opts.dwtSettings&DWT_ROUND_TOP_ONLY) + round=verticalTitleBar ? ROUNDED_LEFT : ROUNDED_TOP; +#endif + painter->setRenderHint(QPainter::Antialiasing, true); + drawBevelGradient(col, painter, fillRect, buildPath(QRectF(fillRect), WIDGET_OTHER, round, radius), !verticalTitleBar, + false, opts.dwtAppearance, WIDGET_DOCK_WIDGET_TITLE, false); + } + + painter->restore(); + } + + if (!dwOpt->title.isEmpty()) + { +#if QT_VERSION >= 0x040300 + QRect titleRect(subElementRect(SE_DockWidgetTitleBarText, option, widget)); + + if (verticalTitleBar) + { + QRect rVert(r); + QSize s(rVert.size()); + + s.transpose(); + rVert.setSize(s); + + titleRect = QRect(rVert.left() + r.bottom() - titleRect.bottom(), + rVert.top() + titleRect.left() - r.left(), + titleRect.height(), titleRect.width()); + + painter->translate(rVert.left(), rVert.top() + rVert.width()); + painter->rotate(-90); + painter->translate(-rVert.left(), -rVert.top()); + } +#else + const int margin(4); + QRect titleRect(visualRect(dwOpt->direction, r, r.adjusted(margin, 0, -margin * 2 - 26, 0))); +#endif +#if !defined QTC_QT_ONLY + if(opts.dwtSettings&DWT_FONT_AS_PER_TITLEBAR) + painter->setFont(KGlobalSettings::windowTitleFont()); +#endif + QFontMetrics fm(painter->fontMetrics()); + QString title(fm.elidedText(dwOpt->title, Qt::ElideRight, titleRect.width(), QPalette::WindowText)); + painter->save(); + getMdiColors(option, state&State_Active); + + QColor textColor((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR) + ? state&State_Active + ? itsActiveMdiTextColor + : itsMdiTextColor + : palette.color(QPalette::WindowText)), + shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect)); + int textOpt(Qt::AlignVCenter); // TODO: dwtPosAsPerTitleBar ? + + if(opts.dwtSettings&DWT_TEXT_ALIGN_AS_PER_TITLEBAR) + switch(opts.titlebarAlignment) + { + case ALIGN_FULL_CENTER: + if(!verticalTitleBar && !reverse) + { + QFontMetrics fm(painter->fontMetrics()); + int width=fm.boundingRect(title).width(); + + if(((fillRect.width()+width)/2)<=titleRect.width()+(isKOffice ? r.x() : 0)) + { + titleRect=fillRect; + textOpt|=Qt::AlignHCenter; + } + else + textOpt|=Qt::AlignRight; + break; + } + case ALIGN_CENTER: + textOpt|=Qt::AlignHCenter; + break; + case ALIGN_RIGHT: + textOpt|=Qt::AlignRight; + break; + default: + case ALIGN_LEFT: + textOpt|=Qt::AlignLeft; + } + else + textOpt|=Qt::AlignLeft; + + if (!styleHint(SH_UnderlineShortcut, dwOpt, widget)) + textOpt|=Qt::TextHideMnemonic; + else + textOpt|=Qt::TextShowMnemonic; + + if((opts.dwtSettings&DWT_EFFECT_AS_PER_TITLEBAR) && + EFFECT_NONE!=opts.titlebarEffect) + { + shadow.setAlphaF(WINDOW_TEXT_SHADOW_ALPHA(opts.titlebarEffect)); + painter->setPen(shadow); + painter->drawText(titleRect.adjusted(1, 1, 1, 1), textOpt, title); + + if (!(state&State_Active) && DARK_WINDOW_TEXT(textColor)) + textColor.setAlpha((textColor.alpha() * 180) >> 8); + } + painter->setPen(textColor); + painter->drawText(titleRect, textOpt, title); + painter->restore(); + } + } + break; +#if QT_VERSION >= 0x040300 + case CE_HeaderEmptyArea: + { + const QStyleOptionHeader *ho = qstyleoption_cast(option); + bool horiz(ho ? Qt::Horizontal==ho->orientation : state&State_Horizontal); + QStyleOption opt(*option); + const QColor *use(opts.lvButton ? buttonColors(option) : backgroundColors(option)); + + opt.state&=~State_MouseOver; + painter->save(); + + drawBevelGradient(getFill(&opt, use), painter, r, horiz, false, opts.lvAppearance, WIDGET_LISTVIEW_HEADER); + + painter->setRenderHint(QPainter::Antialiasing, true); + if(APPEARANCE_RAISED==opts.lvAppearance) + { + painter->setPen(use[4]); + if(horiz) + drawAaLine(painter, r.x(), r.y()+r.height()-2, r.x()+r.width()-1, r.y()+r.height()-2); + else + drawAaLine(painter, r.x()+r.width()-2, r.y(), r.x()+r.width()-2, r.y()+r.height()-1); + } + + painter->setPen(use[STD_BORDER]); + if(horiz) + drawAaLine(painter, r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + else if(reverse) + drawAaLine(painter, r.x(), r.y(), r.x(), r.y()+r.height()-1); + else + drawAaLine(painter, r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->restore(); + break; + } +#endif + case CE_HeaderSection: + if (const QStyleOptionHeader *ho = qstyleoption_cast(option)) + { + const QColor *use(state&State_Enabled && itsSortedLvColors && QStyleOptionHeader::None!=ho->sortIndicator + ? itsSortedLvColors + : opts.lvButton ? buttonColors(option) : backgroundColors(option)); + + painter->save(); + + if(state & (State_Raised | State_Sunken)) + { + bool sunken(state &(/*State_Down |*/ /*State_On | */State_Sunken)), + q3Header(widget && widget->inherits("Q3Header")); + QStyleOption opt(*option); + + opt.state&=~State_On; + if(q3Header && widget && widget->underMouse() && itsHoverWidget && r.contains(itsPos)) + opt.state|=State_MouseOver; + + if(-1==ho->section && !(state&State_Enabled) && widget && widget->isEnabled()) + opt.state|=State_Enabled; + + drawBevelGradient(getFill(&opt, use), painter, r, Qt::Horizontal==ho->orientation, sunken, opts.lvAppearance, WIDGET_LISTVIEW_HEADER); + + painter->setRenderHint(QPainter::Antialiasing, true); + if(APPEARANCE_RAISED==opts.lvAppearance) + { + painter->setPen(use[4]); + if(Qt::Horizontal==ho->orientation) + drawAaLine(painter, r.x(), r.y()+r.height()-2, r.x()+r.width()-1, r.y()+r.height()-2); + else + drawAaLine(painter, r.x()+r.width()-2, r.y(), r.x()+r.width()-2, r.y()+r.height()-1); + } + + if(Qt::Horizontal==ho->orientation) + { + painter->setPen(use[STD_BORDER]); + drawAaLine(painter, r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + if(opts.coloredMouseOver && state&State_MouseOver && state&State_Enabled) + drawHighlight(painter, QRect(r.x(), r.y()+r.height()-2, r.width(), 2), true, true); + + if(q3Header || + (QStyleOptionHeader::End!=ho->position && QStyleOptionHeader::OnlyOneSection!=ho->position)) + { + drawFadedLine(painter, QRect(r.x()+r.width()-2, r.y()+5, 1, r.height()-10), use[STD_BORDER], true, true, false); + drawFadedLine(painter, QRect(r.x()+r.width()-1, r.y()+5, 1, r.height()-10), use[0], true, true, false); + } + } + else + { + painter->setPen(use[STD_BORDER]); + if(reverse) + drawAaLine(painter, r.x(), r.y(), r.x(), r.y()+r.height()-1); + else + drawAaLine(painter, r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + + if(q3Header || + (QStyleOptionHeader::End!=ho->position && QStyleOptionHeader::OnlyOneSection!=ho->position)) + { + drawFadedLine(painter, QRect(r.x()+5, r.y()+r.height()-2, r.width()-10, 1), use[STD_BORDER], true, true, true); + drawFadedLine(painter, QRect(r.x()+5, r.y()+r.height()-1, r.width()-10, 1), use[0], true, true, true); + } + if(opts.coloredMouseOver && state&State_MouseOver && state&State_Enabled) + drawHighlight(painter, QRect(r.x(), r.y()+r.height()-3, r.width(), 2), true, true); + } + painter->setRenderHint(QPainter::Antialiasing, false); + } + else if(!IS_FLAT(opts.lvAppearance) && !reverse && ((State_Enabled|State_Active)==state || State_Enabled==state)) + { + QPolygon top; + const QColor &col(getFill(option, use)); + + top.setPoints(3, r.x(), r.y(), r.x()+r.width(), r.y(), r.x()+r.width(), r.y()+r.height()); + painter->setClipRegion(QRegion(top)); + drawBevelGradient(col, painter, r, true, false, opts.lvAppearance, WIDGET_LISTVIEW_HEADER); + painter->setClipRegion(QRegion(r).eor(QRegion(top))); + drawBevelGradient(col, painter, r, false, false, opts.lvAppearance, WIDGET_LISTVIEW_HEADER); + } + else + painter->fillRect(r, getFill(option, use)); + painter->restore(); + } + break; + case CE_HeaderLabel: + if (const QStyleOptionHeader *header = qstyleoption_cast(option)) + { + if (!header->icon.isNull()) + { + QPixmap pixmap(getIconPixmap(header->icon, pixelMetric(PM_SmallIconSize), header->state)); + int pixw(pixmap.width()); + QRect aligned(alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size(), r)), + inter(aligned.intersected(r)); + + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height()); + + if (header->direction == Qt::LeftToRight) + r.setLeft(r.left() + pixw + 2); + else + r.setRight(r.right() - pixw - 2); + } + drawItemTextWithRole(painter, r, header->textAlignment, palette, state&State_Enabled, header->text, QPalette::ButtonText); + } + break; + case CE_ProgressBarGroove: + { + bool doEtch(DO_EFFECT && opts.borderProgress), + horiz(true); + QColor col; + + if (const QStyleOptionProgressBarV2 *bar = qstyleoption_cast(option)) + horiz = Qt::Horizontal==bar->orientation; + + painter->save(); + + if(doEtch) + r.adjust(1, 1, -1, -1); + + switch(opts.progressGrooveColor) + { + default: + case ECOLOR_BASE: + col=palette.base().color(); + break; + case ECOLOR_BACKGROUND: + col=palette.background().color(); + break; + case ECOLOR_DARK: + col=itsBackgroundCols[2]; + } + + drawBevelGradient(col, painter, r, opts.borderProgress + ? buildPath(r, WIDGET_PBAR_TROUGH, ROUNDED_ALL, + qtcGetRadius(&opts, r.width(), r.height(), WIDGET_PBAR_TROUGH, RADIUS_EXTERNAL)) + : QPainterPath(), + horiz, false, opts.progressGrooveAppearance, WIDGET_PBAR_TROUGH); + + if(doEtch) + drawEtch(painter, r.adjusted(-1, -1, 1, 1), widget, WIDGET_PBAR_TROUGH); + else if(!opts.borderProgress) + { + painter->setPen(itsBackgroundCols[STD_BORDER]); + if(horiz) + { + painter->drawLine(r.topLeft(), r.topRight()); + painter->drawLine(r.bottomLeft(), r.bottomRight()); + } + else + { + painter->drawLine(r.topLeft(), r.bottomLeft()); + painter->drawLine(r.topRight(), r.bottomRight()); + } + } + + if(opts.borderProgress) + drawBorder(painter, r, option, ROUNDED_ALL, backgroundColors(option), WIDGET_PBAR_TROUGH, + IS_FLAT(opts.progressGrooveAppearance) && ECOLOR_DARK!=opts.progressGrooveColor ? BORDER_SUNKEN : BORDER_FLAT); + painter->restore(); + break; + } + case CE_ProgressBarContents: + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(option)) + { + bool vertical(false), + inverted(false), + indeterminate(0==bar->minimum && 0==bar->maximum); + + // Get extra style options if version 2 + if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast(option)) + { + vertical = Qt::Vertical==bar2->orientation; + inverted = bar2->invertedAppearance; + } + + if (!indeterminate && -1==bar->progress) + break; + + bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; + + if (inverted) + reverse = !reverse; + + painter->save(); + + if(indeterminate) //Busy indicator + { + int chunkSize(PROGRESS_CHUNK_WIDTH*3.4), + measure(vertical ? r.height() : r.width()); + + if(chunkSize>(measure/2)) + chunkSize=measure/2; + + int step(itsAnimateStep % ((measure-chunkSize) * 2)); + QStyleOption opt(*option); + + if (step > (measure-chunkSize)) + step = 2 * (measure-chunkSize) - step; + + opt.state|=State_Raised|State_Horizontal; + drawProgress(painter, vertical ? QRect(r.x(), r.y()+step, r.width(), chunkSize) : QRect(r.x()+step, r.y(), chunkSize, r.height()), + option, vertical); + } + else if(r.isValid() && bar->progress>0) + { + qint64 progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar + double pg = ((progress - qint64(bar->minimum)) / + qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum)))); + + if(vertical) + { + int height(qMin(r.height(), (int)(pg * r.height()))); + + if(inverted) + drawProgress(painter, QRect(r.x(), r.y(), r.width(), height), option, true); + else + drawProgress(painter, QRect(r.x(), r.y()+(r.height()-height), r.width(), height), option, true); + } + else + { + int width(qMin(r.width(), (int)(pg * r.width()))); + + if(reverse || inverted) + drawProgress(painter, QRect(r.x()+(r.width()-width), r.y(), width, r.height()), option, false, true); + else + drawProgress(painter, QRect(r.x(), r.y(), width, r.height()), option); + } + } + + painter->restore(); + } + break; + case CE_ProgressBarLabel: + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(option)) + { + // The busy indicator doesn't draw a label + if (0==bar->minimum && 0==bar->maximum) + return; + + bool vertical(false), + inverted(false), + bottomToTop(false); + + // Get extra style options if version 2 + if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast(option)) + { + vertical = (bar2->orientation == Qt::Vertical); + inverted = bar2->invertedAppearance; + bottomToTop = bar2->bottomToTop; + } + +#if QT_VERSION < 0x040300 + if(vertical) + return; +#endif + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + +#if QT_VERSION >= 0x040300 + if (vertical) + { + r = QRect(r.left(), r.top(), r.height(), r.width()); // flip width and height + + QTransform m; + if (bottomToTop) + { + m.translate(0.0, r.width()); + m.rotate(-90); + } + else + { + m.translate(r.height(), 0.0); + m.rotate(90); + } + painter->setTransform(m); + } +#endif + + int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) / + qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum) * r.width(); + bool flip((!vertical && (((Qt::RightToLeft==bar->direction) && !inverted) || + ((Qt::LeftToRight==bar->direction) && inverted))) || + (vertical && ((!inverted && !bottomToTop) || (inverted && bottomToTop)))); + QRect leftRect; + QRegion rightRect(r); + QPalette::ColorGroup cg=state&State_Enabled || State_None==state ? QPalette::Active : QPalette::Current; + + if (flip) + { + int indicatorPos(r.width() - progressIndicatorPos); + + if (indicatorPos >= 0 && indicatorPos <= r.width()) + { + painter->setPen(palette.brush(cg, QPalette::Base).color()); + leftRect = QRect(r.left(), r.top(), indicatorPos, r.height()); + //rightRect = QRect(r.left()+indicatorPos, r.top(), r.width()-indicatorPos, r.height()); + } + else if (indicatorPos > r.width()) + painter->setPen(palette.brush(cg, QPalette::Text).color()); + else + painter->setPen(palette.brush(cg, QPalette::HighlightedText).color()); + } + else + { + if (progressIndicatorPos >= 0 && progressIndicatorPos <= r.width()) + { + leftRect = QRect(r.left(), r.top(), progressIndicatorPos, r.height()); + //rightRect = QRect(r.left()+progressIndicatorPos, r.top(), r.width()-progressIndicatorPos, r.height()); + } + else if (progressIndicatorPos > r.width()) + painter->setPen(palette.brush(cg, QPalette::HighlightedText).color()); + else + painter->setPen(palette.brush(cg, QPalette::Text).color()); + } + + QString text = bar->fontMetrics.elidedText(bar->text, Qt::ElideRight, r.width()); + + rightRect = rightRect.subtracted(leftRect); + painter->setClipRegion(rightRect); + painter->drawText(r, text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter)); + if (!leftRect.isNull()) + { + painter->setPen(palette.brush(cg, flip ? QPalette::Text : QPalette::HighlightedText).color()); + painter->setClipRect(leftRect); + painter->drawText(r, text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter)); + } + + painter->restore(); + } + break; + case CE_MenuBarItem: + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(option)) + { + bool down(state&(State_On|State_Sunken)), + active(state&State_Enabled && (down || (state&State_Selected && opts.menubarMouseOver))); + uint alignment(Qt::AlignCenter|Qt::TextShowMnemonic|Qt::TextDontClip|Qt::TextSingleLine); + QPixmap pix(getIconPixmap(mbi->icon, pixelMetric(PM_SmallIconSize), mbi->state)); + + if (!styleHint(SH_UnderlineShortcut, mbi, widget)) + alignment|=Qt::TextHideMnemonic; + + painter->save(); + + if(!opts.xbar || (!widget || 0!=strcmp("QWidget", widget->metaObject()->className()))) + drawMenuOrToolBarBackground(widget, painter, mbi->menuRect, option); + + if(active) + drawMenuItem(painter, !opts.roundMbTopOnly && !(opts.square&SQUARE_POPUP_MENUS) ? r.adjusted(1, 1, -1, -1) : r, + option, MENU_BAR, + (down || APP_OPENOFFICE==theThemedApp) && opts.roundMbTopOnly ? ROUNDED_TOP : ROUNDED_ALL, + opts.useHighlightForMenu && (opts.colorMenubarMouseOver || down || APP_OPENOFFICE==theThemedApp) + ? (itsOOMenuCols ? itsOOMenuCols : itsHighlightCols) : itsBackgroundCols); + + if (!pix.isNull()) + drawItemPixmap(painter, mbi->rect, alignment, pix); + else + { + const QColor &col=state&State_Enabled + ? ((opts.colorMenubarMouseOver && active) || (!opts.colorMenubarMouseOver && down)) + ? opts.customMenuTextColor + ? opts.customMenuSelTextColor + : opts.useHighlightForMenu + ? palette.highlightedText().color() + : palette.foreground().color() + : palette.foreground().color() + : palette.foreground().color(); + + painter->setPen(col); + painter->drawText(r, alignment, mbi->text); + } + painter->restore(); + } + break; + case CE_MenuItem: + if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(option)) + { + bool comboMenu(qobject_cast(widget)), + reverse(Qt::RightToLeft==menuItem->direction), + isOO(isOOWidget(widget)); + int checkcol(qMax(menuItem->maxIconWidth, 20)), + stripeWidth(qMax(checkcol, constMenuPixmapWidth)-2); + const QColor * use(popupMenuCols(option)); + +#if QT_VERSION < 0x040600 + if(!(comboMenu && opts.gtkComboMenus)) + r.adjust(0, 0, -1, 0); +#endif + QRect rx(r); + + if(isOO) + { + if(opts.borderMenuitems) + r.adjust(2, 0, -2, 0); + else if(APPEARANCE_FADE==opts.menuitemAppearance) + r.adjust(1, 0, -1, 0); + } + + painter->save(); + + if (QStyleOptionMenuItem::Separator==menuItem->menuItemType) + { + bool isMenu(!widget || qobject_cast(widget)), + doStripe(isMenu && opts.menuStripe && !comboMenu); + + if(doStripe) + drawBevelGradient(menuStripeCol(), painter, QRect(reverse ? r.right()-stripeWidth : r.x(), r.y(), + stripeWidth, r.height()), + false, false, opts.menuStripeAppearance, WIDGET_OTHER); + + if(!menuItem->text.isEmpty()) + { + QStyleOption opt; + opt.rect = r.adjusted(2, 2, -3, -2); + opt.state=State_Raised|State_Enabled|State_Horizontal; + drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL, getFill(&opt, use), use, true, WIDGET_NO_ETCH_BTN); + + QFont font(menuItem->font); + + font.setBold(true); + painter->setFont(font); + drawItemTextWithRole(painter, r, Qt::AlignHCenter | Qt::AlignVCenter, + palette, state&State_Enabled, menuItem->text, QPalette::Text); + } + else + { + QRect miRect(menuItem->rect.left() + 3 + + (!reverse && doStripe ? stripeWidth : 0), + menuItem->rect.center().y(), + menuItem->rect.width() - (7 + (doStripe ? stripeWidth : 0)), + 1); + drawFadedLine(painter, miRect, use[MENU_SEP_SHADE], true, true, true); + } + + if(isOO) + { + painter->setPen(use[STD_BORDER]); + painter->drawLine(rx.topLeft(), rx.bottomLeft()); + painter->drawLine(rx.topRight(), rx.bottomRight()); + } + painter->restore(); + break; + } + + bool selected(state&State_Selected), + checkable(QStyleOptionMenuItem::NotCheckable!=menuItem->checkType), + checked(menuItem->checked), + enabled(state&State_Enabled); + + if(opts.menuStripe && !comboMenu) + drawBevelGradient(menuStripeCol(), painter, + QRect(reverse ? r.right()-stripeWidth : r.x(), r.y(), stripeWidth, r.height()), + false, false, opts.menuStripeAppearance, WIDGET_OTHER); + + if (selected && enabled) + drawMenuItem(painter, r, option, /*comboMenu ? MENU_COMBO : */MENU_POPUP, ROUNDED_ALL, + opts.useHighlightForMenu ? (itsOOMenuCols ? itsOOMenuCols : itsHighlightCols) : use); + + if(comboMenu) + { + if (menuItem->icon.isNull()) + checkcol = 0; + else + checkcol = menuItem->maxIconWidth; + } + else + { + // Check + QRect checkRect(r.left() + 3, r.center().y() - 6, opts.crSize, opts.crSize); + checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect); + if (checkable) + { + if ((menuItem->checkType & QStyleOptionMenuItem::Exclusive) && menuItem->icon.isNull()) + { + QStyleOptionButton button; + button.rect = checkRect; + button.state = menuItem->state|STATE_MENU; + if (checked) + button.state |= State_On; + button.palette = palette; + drawPrimitive(PE_IndicatorRadioButton, &button, painter, widget); + } + else + { + if (menuItem->icon.isNull() || !opts.menuIcons) + { + QStyleOptionButton button; + button.rect = checkRect; + button.state = menuItem->state|STATE_MENU; + if (checked) + button.state |= State_On; + button.palette = palette; + drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget); + } + else if (checked) + { + int iconSize(qMax(menuItem->maxIconWidth, 20)); + QRect sunkenRect(r.left() + 1, r.top() + (r.height() - iconSize) / 2, + iconSize, iconSize); + QStyleOption opt(*option); + + sunkenRect = visualRect(menuItem->direction, menuItem->rect, sunkenRect); + opt.state = menuItem->state; + opt.state|=State_Raised|State_Horizontal; + if (checked) + opt.state |= State_On; + drawLightBevel(painter, sunkenRect, &opt, widget, ROUNDED_ALL, getFill(&opt, itsButtonCols), itsButtonCols); + } + } + } + } + + // Text and icon, ripped from windows style + bool dis(!(state&State_Enabled)), + act(state&State_Selected); + QRect vCheckRect(visualRect(option->direction, menuItem->rect, + QRect(menuItem->rect.x(), menuItem->rect.y(), checkcol, menuItem->rect.height()))); + + if (opts.menuIcons && !menuItem->icon.isNull()) + { + QIcon::Mode mode(dis ? QIcon::Disabled : QIcon::Normal); + + if (act && !dis) + mode = QIcon::Active; + + QPixmap pixmap(getIconPixmap(menuItem->icon, pixelMetric(PM_SmallIconSize), mode, + checked ? QIcon::On : QIcon::Off)); + + int pixw(pixmap.width()), + pixh(pixmap.height()); + QRect pmr(0, 0, pixw, pixh); + + pmr.moveCenter(vCheckRect.center()); + painter->setPen(palette.text().color()); + if (checkable && checked) + painter->drawPixmap(QPoint(pmr.left() + 1, pmr.top() + 1), pixmap); + else + painter->drawPixmap(pmr.topLeft(), pixmap); + } + + painter->setPen(dis + ? palette.text().color() + : selected && opts.useHighlightForMenu && !itsOOMenuCols + ? palette.highlightedText().color() + : palette.foreground().color()); + + int x, y, w, h, + tab(menuItem->tabWidth); + + menuItem->rect.getRect(&x, &y, &w, &h); + + int xm(windowsItemFrame + checkcol + windowsItemHMargin -2), + xpos(menuItem->rect.x() + xm); + QRect textRect(xpos, y + windowsItemVMargin, + opts.menuIcons ? (w - xm - windowsRightBorder - tab + 1) + : (w - ((xm*2) + tab)), + h - 2 * windowsItemVMargin), + vTextRect = visualRect(option->direction, menuItem->rect, textRect); + QString s(menuItem->text); + + if (!s.isEmpty()) // draw text + { + int t(s.indexOf(QLatin1Char('\t'))), + textFlags(Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine); + + if (!styleHint(SH_UnderlineShortcut, menuItem, widget)) + textFlags |= Qt::TextHideMnemonic; + textFlags |= Qt::AlignLeft; + + if (t >= 0) + { + QRect vShortcutRect(visualRect(option->direction, menuItem->rect, + QRect(textRect.topRight(), QPoint(menuItem->rect.right(), textRect.bottom())))); + + painter->drawText(vShortcutRect, textFlags, s.mid(t + 1)); + s = s.left(t); + } + + QFont font(menuItem->font); + + if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) + font.setBold(true); + + painter->setFont(font); + painter->drawText(vTextRect, textFlags, s.left(t)); + } + + // Arrow + if (QStyleOptionMenuItem::SubMenu==menuItem->menuItemType) // draw sub menu arrow + { + int dim((menuItem->rect.height() - 4) / 2), + xpos(menuItem->rect.left() + menuItem->rect.width() - 3 - dim); + PrimitiveElement arrow(Qt::RightToLeft==option->direction ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight); + QRect vSubMenuRect(visualRect(option->direction, menuItem->rect, + QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim))); + + drawArrow(painter, vSubMenuRect, arrow, + opts.useHighlightForMenu && state&State_Enabled && state&State_Selected && !itsOOMenuCols + ? palette.highlightedText().color() + : palette.text().color()); + } + + if(isOO) + { + painter->setPen(use[STD_BORDER]); + painter->drawLine(rx.topLeft(), rx.bottomLeft()); + painter->drawLine(rx.topRight(), rx.bottomRight()); + } + painter->restore(); + } + break; + case CE_MenuHMargin: + case CE_MenuVMargin: + case CE_MenuEmptyArea: + break; + case CE_PushButton: + if(const QStyleOptionButton *btn = qstyleoption_cast(option)) + { + // For OO.o 3.2 need to fill widget background! + if(isOOWidget(widget)) + painter->fillRect(r, palette.brush(QPalette::Window)); + drawControl(CE_PushButtonBevel, btn, painter, widget); + + QStyleOptionButton subopt(*btn); + + subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); + drawControl(CE_PushButtonLabel, &subopt, painter, widget); + + if (state&State_HasFocus && + !(state&State_MouseOver && FULL_FOCUS && MO_NONE!=opts.coloredMouseOver)) + { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + break; + case CE_PushButtonBevel: + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) + { + int dbi(pixelMetric(PM_ButtonDefaultIndicator, btn, widget)); + + if (btn->features & QStyleOptionButton::DefaultButton) + drawPrimitive(PE_FrameDefaultButton, option, painter, widget); + if (btn->features & QStyleOptionButton::AutoDefaultButton) + r.setCoords(r.left() + dbi, r.top() + dbi, r.right() - dbi, r.bottom() - dbi); + if ( !(btn->features & (QStyleOptionButton::Flat +#if QT_VERSION >= 0x040300 + |QStyleOptionButton::CommandLinkButton +#endif + )) || + state&(State_Sunken | State_On | State_MouseOver)) + { + QStyleOptionButton tmpBtn(*btn); + + tmpBtn.rect = r; + drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget); + } + if (btn->features & QStyleOptionButton::HasMenu) + { + int mbi(pixelMetric(PM_MenuButtonIndicator, btn, widget)); + QRect ar(Qt::LeftToRight==btn->direction + ? btn->rect.right() - (mbi+6) + : btn->rect.x() + 6, + ((btn->rect.height() - mbi)/2), + mbi, mbi); + + if(option->state &(State_On | State_Sunken)) + ar.adjust(1, 1, 1, 1); + + drawArrow(painter, ar, PE_IndicatorArrowDown, MO_ARROW(QPalette::ButtonText)); + } + } + break; + case CE_PushButtonLabel: + if (const QStyleOptionButton *button = qstyleoption_cast(option)) + { + uint tf(Qt::AlignVCenter | Qt::TextShowMnemonic); + + if (!styleHint(SH_UnderlineShortcut, button, widget)) + tf |= Qt::TextHideMnemonic; + + if (!button->icon.isNull()) + { + //Center both icon and text + QIcon::Mode mode(button->state&State_Enabled ? QIcon::Normal : QIcon::Disabled); + + if (QIcon::Normal==mode && button->state&State_HasFocus) + mode = QIcon::Active; + + QIcon::State state((button->state&State_On) || (button->state&State_Sunken) ? QIcon::On : QIcon::Off); + QPixmap pixmap(getIconPixmap(button->icon, button->iconSize, mode, state)); + int labelWidth(pixmap.width()), + labelHeight(pixmap.height()), + iconSpacing (4);//### 4 is currently hardcoded in QPushButton::sizeHint() + + if (!button->text.isEmpty()) + labelWidth += (button->fontMetrics.boundingRect(r, tf, button->text).width() + iconSpacing); + + QRect iconRect(r.x() + (r.width() - labelWidth) / 2, + r.y() + (r.height() - labelHeight) / 2, + pixmap.width(), pixmap.height()); + + iconRect = visualRect(button->direction, r, iconRect); + + tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead + + if (Qt::RightToLeft==button->direction) + r.setRight(iconRect.left() - iconSpacing); + else + r.setLeft(iconRect.left() + iconRect.width() + iconSpacing); + + if (button->state & (State_On|State_Sunken)) + iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, option, widget), + pixelMetric(PM_ButtonShiftVertical, option, widget)); + painter->drawPixmap(iconRect, pixmap); + } + else + tf |= Qt::AlignHCenter; + + if (button->state & (State_On|State_Sunken)) + r.translate(pixelMetric(PM_ButtonShiftHorizontal, option, widget), + pixelMetric(PM_ButtonShiftVertical, option, widget)); + + // The following is mainly for DejaVu Sans 11... + if(button->fontMetrics.height()==19 && r.height()==(23+((opts.thin&THIN_BUTTONS) ? 0 : 2))) + r.translate(0, 1); + + if (button->features&QStyleOptionButton::HasMenu) + { + int mbi(pixelMetric(PM_MenuButtonIndicator, button, widget)); + + if (Qt::LeftToRight==button->direction) + r = r.adjusted(0, 0, -mbi, 0); + else + r = r.adjusted(mbi, 0, 0, 0); + + if(APP_SKYPE==theThemedApp) + { + // Skype seems to draw a blurry arrow in the lower right corner, + // ...draw over this with a nicer sharper arrow... + QRect ar(button->rect.x()+(button->rect.width()-(LARGE_ARR_WIDTH+3)), + button->rect.y()+(button->rect.height()-(LARGE_ARR_HEIGHT+2)), + LARGE_ARR_WIDTH, + LARGE_ARR_HEIGHT); + + if(option->state &(State_On | State_Sunken)) + ar.adjust(1, 1, 1, 1); + drawArrow(painter, ar, PE_IndicatorArrowDown, MO_ARROW(QPalette::ButtonText)); + } + } + + int num(opts.embolden && button->features&QStyleOptionButton::DefaultButton ? 2 : 1); + + for(int i=0; istate&State_Enabled), + button->text, QPalette::ButtonText); + } + break; + case CE_ComboBoxLabel: + if (const QStyleOptionComboBox *comboBox = qstyleoption_cast(option)) + { + QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget); + bool sunken=!comboBox->editable && (state&(State_On|State_Sunken)); + int shiftH=sunken ? pixelMetric(PM_ButtonShiftHorizontal, option, widget) : 0, + shiftV=sunken ? pixelMetric(PM_ButtonShiftVertical, option, widget) : 0; + + painter->save(); + + if (!comboBox->currentIcon.isNull()) + { + QPixmap pixmap = getIconPixmap(comboBox->currentIcon, comboBox->iconSize, state); + QRect iconRect(editRect); + + iconRect.setWidth(comboBox->iconSize.width() + 5); + if(!comboBox->editable) + iconRect = alignedRect(QApplication::layoutDirection(), Qt::AlignLeft|Qt::AlignVCenter, + iconRect.size(), editRect); + if (comboBox->editable) + { + int adjust=opts.etchEntry ? 2 : 1; + + if(opts.square&SQUARE_ENTRY || opts.roundfillRect(iconRect.adjusted(adjust-1, adjust, -(adjust-1), -adjust), palette.brush(QPalette::Base)); + else + { + painter->fillRect(iconRect.adjusted(1, adjust, -1, -adjust), palette.brush(QPalette::Base)); + painter->fillRect(iconRect.adjusted(0, adjust+1, 0, -(adjust+1)), palette.brush(QPalette::Base)); + } + } + + if (sunken) + iconRect.translate(shiftH, shiftV); + + drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); + + if (reverse) + editRect.translate(-4 - comboBox->iconSize.width(), 0); + else + editRect.translate(comboBox->iconSize.width() + 4, 0); + } + + if (!comboBox->currentText.isEmpty() && !comboBox->editable) + { + if (sunken) + editRect.translate(shiftH, shiftV); + + int margin=comboBox->frame && widget && widget->rect().height()<(DO_EFFECT ? 22 : 20) ? 4 : 0; + editRect.adjust(1, -margin, -1, margin); + painter->setClipRect(editRect); + drawItemTextWithRole(painter, editRect, Qt::AlignLeft|Qt::AlignVCenter, palette, + state&State_Enabled, comboBox->currentText, QPalette::ButtonText); + } + painter->restore(); + } + break; + case CE_MenuBarEmptyArea: + { + painter->save(); + + if(!opts.xbar || (!widget || 0!=strcmp("QWidget", widget->metaObject()->className()))) + drawMenuOrToolBarBackground(widget, painter, r, option); + if (TB_NONE!=opts.toolbarBorders && widget && widget->parentWidget() && + (qobject_cast(widget->parentWidget()) || widget->parentWidget()->inherits("Q3MainWindow"))) + { + const QColor *use=menuColors(option, itsActive); + bool dark(TB_DARK==opts.toolbarBorders || TB_DARK_ALL==opts.toolbarBorders); + + if(TB_DARK_ALL==opts.toolbarBorders || TB_LIGHT_ALL==opts.toolbarBorders) + { + painter->setPen(use[0]); + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.width()-1); + painter->setPen(use[dark ? 3 : 4]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + } + else + { + painter->setPen(use[dark ? 3 : 4]); + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + } + } + painter->restore(); + } + break; + case CE_TabBarTabLabel: + if (const QStyleOptionTab *tab = qstyleoption_cast(option)) + { +#if QT_VERSION >= 0x040500 + QStyleOptionTabV3 tabV2(*tab); +#else + QStyleOptionTabV2 tabV2(*tab); +#endif + bool verticalTabs(QTabBar::RoundedEast==tabV2.shape || QTabBar::RoundedWest==tabV2.shape || + QTabBar::TriangularEast==tabV2.shape || QTabBar::TriangularWest==tabV2.shape), + toolbarTab=!opts.toolbarTabs && widget && widget->parentWidget() && + qobject_cast(widget->parentWidget()); + + if (verticalTabs) + { + painter->save(); + int newX, newY, newRot; + if (QTabBar::RoundedEast==tabV2.shape || QTabBar::TriangularEast==tabV2.shape) + { + newX = r.width(); + newY = r.y(); + newRot = 90; + } + else + { + newX = 0; + newY = r.y() + r.height(); + newRot = -90; + } + r.setRect(0, 0, r.height(), r.width()); + + QTransform m; + m.translate(newX, newY); + m.rotate(newRot); + painter->setTransform(m, true); + } + + int alignment(Qt::AlignVCenter | Qt::TextShowMnemonic | (opts.centerTabText ? Qt::AlignHCenter : Qt::AlignLeft)); + + if (!styleHint(SH_UnderlineShortcut, option, widget)) + alignment |= Qt::TextHideMnemonic; + +#if QT_VERSION >= 0x040500 + if(toolbarTab) + tabV2.state&=~State_Selected; + r = subElementRect(SE_TabBarTabText, &tabV2, widget); +#else + r.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), + pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + + if (!toolbarTab && state&State_Selected) + { + r.setBottom(r.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + r.setRight(r.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); + } +#endif + if (!tabV2.icon.isNull()) + { + QSize iconSize(tabV2.iconSize); + if (!iconSize.isValid()) + { + int iconExtent(pixelMetric(PM_SmallIconSize)); + iconSize = QSize(iconExtent, iconExtent); + } + + QPixmap tabIcon(getIconPixmap(tabV2.icon, iconSize, state&State_Enabled)); + QSize tabIconSize = tabV2.icon.actualSize(iconSize, tabV2.state&State_Enabled + ? QIcon::Normal + : QIcon::Disabled); + + int offset = 4, + left = option->rect.left(); +#if QT_VERSION >= 0x040500 + if (tabV2.leftButtonSize.isNull() || tabV2.leftButtonSize.width()<=0) + offset += 2; + else + left += tabV2.leftButtonSize.width() + 2; +#endif + QRect iconRect = QRect(left + offset, r.center().y() - tabIcon.height() / 2, + tabIconSize.width(), tabIconSize.height()); + if (!verticalTabs) + iconRect = visualRect(option->direction, option->rect, iconRect); + painter->drawPixmap(iconRect.x(), iconRect.y(), tabIcon); +#if QT_VERSION < 0x040500 + r.adjust(reverse ? 0 : tabIconSize.width(), 0, reverse ? -tabIconSize.width() : 0, 0); +#endif + } + + if(!tab->text.isEmpty()) + { +#if QT_VERSION < 0x040500 + r.adjust(constTabPad, 0, -constTabPad, 0); +#endif + drawItemTextWithRole(painter, r, alignment, tab->palette, tab->state&State_Enabled, tab->text, + !opts.stdSidebarButtons && toolbarTab && state&State_Selected + ? QPalette::HighlightedText : QPalette::WindowText); + } + + if (verticalTabs) + painter->restore(); + + if (tabV2.state & State_HasFocus) + { + const int constOffset = 1 + pixelMetric(PM_DefaultFrameWidth); + + int x1=tabV2.rect.left(), + x2=tabV2.rect.right() - 1; + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*tab); + fropt.rect.setRect(x1 + 1 + constOffset, tabV2.rect.y() + constOffset, + x2 - x1 - 2*constOffset, tabV2.rect.height() - 2*constOffset); + + fropt.state|=State_Horizontal; + if(FOCUS_LINE!=opts.focus) + { + if(QTabBar::RoundedNorth==tabV2.shape || QTabBar::TriangularNorth==tabV2.shape) + fropt.rect.adjust(0, 1, 0, 0); + } + else if(TAB_MO_BOTTOM==opts.tabMouseOver && FOCUS_LINE==opts.focus) + switch(tabV2.shape) + { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + fropt.rect.adjust(0, 0, 0, 1); + break; + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + fropt.rect.adjust(-2, 0, -(fropt.rect.width()+1), 0); + fropt.state&=~State_Horizontal; + break; + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + fropt.rect.adjust(0, 0, 0, 1); + break; + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + fropt.rect.adjust(0, 0, 2, 0); + fropt.state&=~State_Horizontal; + default: + break; + } + + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + break; + case CE_TabBarTabShape: + if(!opts.toolbarTabs && widget && widget->parentWidget() && qobject_cast(widget->parentWidget())) + { + QStyleOption opt(*option); + if(state&State_Selected) + opt.state|=State_On; + if(opts.stdSidebarButtons) + { + if(state&(State_Selected|State_MouseOver)) + { + opt.state|=STATE_TBAR_BUTTON; + drawPrimitive(PE_PanelButtonTool, &opt, painter, widget); + } + } + else + drawSideBarButton(painter, r, &opt, widget); + } + else if (const QStyleOptionTab *tab = qstyleoption_cast(option)) + { + bool onlyTab(widget && widget->parentWidget() + ? qobject_cast(widget->parentWidget()) ? false : true + : false), + selected(state&State_Selected), + horiz(QTabBar::RoundedNorth==tab->shape || QTabBar::RoundedSouth==tab->shape); + +#if QT_VERSION >= 0x040500 + QStyleOptionTabV3 tabV3(*tab); +#endif + QRect r2(r); + bool rtlHorTabs(Qt::RightToLeft==tab->direction && horiz), + oneTab(QStyleOptionTab::OnlyOneTab==tab->position), + leftCornerWidget(tab->cornerWidgets&QStyleOptionTab::LeftCornerWidget), + rightCornerWidget(tab->cornerWidgets&QStyleOptionTab::RightCornerWidget), + firstTab((tab->position == (Qt::LeftToRight==tab->direction || !horiz ? + QStyleOptionTab::Beginning : QStyleOptionTab::End)) || oneTab), + lastTab((tab->position == (Qt::LeftToRight==tab->direction || !horiz ? + QStyleOptionTab::End : QStyleOptionTab::Beginning)) || oneTab); + int tabBarAlignment(styleHint(SH_TabBar_Alignment, tab, widget)), + tabOverlap(oneTab ? 0 : pixelMetric(PM_TabBarTabOverlap, option, widget)), + moOffset(ROUNDED_NONE==opts.round || TAB_MO_TOP!=opts.tabMouseOver ? 1 : opts.round), + highlightOffset(opts.highlightTab && opts.round>ROUND_SLIGHT ? 2 : 1), + highlightBorder(opts.round>ROUND_FULL ? 4 : 3), + sizeAdjust(!selected && TAB_MO_GLOW==opts.tabMouseOver ? 1 : 0); + bool leftAligned((!rtlHorTabs && Qt::AlignLeft==tabBarAlignment) || + (rtlHorTabs && Qt::AlignRight==tabBarAlignment)), + rightAligned((!rtlHorTabs && Qt::AlignRight==tabBarAlignment) || + (rtlHorTabs && Qt::AlignLeft==tabBarAlignment)), + docMode( +#if QT_VERSION >= 0x040500 + tabV3.documentMode +#else + false +#endif + ), + docFixLeft(!leftCornerWidget && leftAligned && firstTab && (docMode || onlyTab)), + fixLeft(!onlyTab && !leftCornerWidget && leftAligned && firstTab && !docMode), + fixRight(!onlyTab && !rightCornerWidget && rightAligned && lastTab && !docMode), + mouseOver(state&State_Enabled && state&State_MouseOver), + glowMo(!selected && mouseOver && opts.coloredMouseOver && TAB_MO_GLOW==opts.tabMouseOver), + thin(opts.thin&THIN_FRAMES), + drawOuterGlow(glowMo && !thin); + const QColor *use(backgroundColors(option)); + QColor fill(getTabFill(selected, mouseOver, use)); + double radius=qtcGetRadius(&opts, r.width(), r.height(), WIDGET_TAB_TOP, RADIUS_EXTERNAL); + EBorder borderProfile(selected || opts.borderInactiveTab + ? opts.borderTab + ? BORDER_LIGHT + : BORDER_RAISED + : BORDER_FLAT); + + painter->save(); + + if(!selected && (100!=opts.bgndOpacity || 100!=opts.dlgOpacity)) + { + QWidget *top=widget ? widget->topLevelWidget() : 0L; + bool isDialog=top && Qt::Dialog==(top->windowFlags() & Qt::WindowType_Mask); + + // Note: opacity is divided by 150 to make dark inactive tabs more translucent + if(isDialog && 100!=opts.dlgOpacity) + fill.setAlphaF(opts.dlgOpacity/150.0); + else if(!isDialog && 100!=opts.bgndOpacity) + fill.setAlphaF(opts.bgndOpacity/150.0); + } + + switch(tab->shape) + { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + { + int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs + ? ROUNDED_TOP + : firstTab + ? ROUNDED_TOPLEFT + : lastTab + ? ROUNDED_TOPRIGHT + : ROUNDED_NONE; + if(!selected) + r.adjust(0, 2, 0, -2); + + if(!firstTab) + r.adjust(-tabOverlap, 0, 0, 0); + painter->setClipPath(buildPath(r.adjusted(0, 0, 0, 4), WIDGET_TAB_TOP, round, radius)); + fillTab(painter, r.adjusted(1+sizeAdjust, 1, -(1+sizeAdjust), 0), option, fill, true, WIDGET_TAB_TOP, (docMode || onlyTab)); + // This clipping (for selected) helps with plasma's tabs and nvidia + if(selected || thin) + painter->setClipRect(r2.adjusted(-1, 0, 1, -1)); + else + painter->setClipping(false); + drawBorder(painter, r.adjusted(sizeAdjust, 0, -sizeAdjust, 4), option, round, glowMo ? itsMouseOverCols : 0L, + WIDGET_TAB_TOP, borderProfile, false); + if(drawOuterGlow) + drawGlow(painter, r.adjusted(0, -1, 0, 5), WIDGET_TAB_TOP); + + if(selected || thin) + painter->setClipping(false); + + if(selected) + { + if(!thin) + { + painter->setPen(use[0]); + + // The point drawn below is because of the clipping above... + if(fixLeft) + painter->drawPoint(r2.x()+1, r2.y()+r2.height()-1); + else + painter->drawLine(r2.left()-1, r2.bottom(), r2.left(), r2.bottom()); + if(!fixRight) + painter->drawLine(r2.right()-1, r2.bottom(), r2.right(), r2.bottom()); + } + + if(docFixLeft) + { + QColor col(use[STD_BORDER]); + col.setAlphaF(0.5); + painter->setPen(col); + painter->drawPoint(r2.x(), r2.y()+r2.height()-1); + } + } + else + { + int l(fixLeft ? r2.left()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME) ? 2 : 1) : r2.left()-1), + r(fixRight ? r2.right()-2 : r2.right()+1); + painter->setPen(use[STD_BORDER]); + painter->drawLine(l, r2.bottom()-1, r, r2.bottom()-1); + if(!thin) + { + painter->setPen(use[0]); + painter->drawLine(l, r2.bottom(), r, r2.bottom()); + } + } + + if(selected) + { + if(opts.highlightTab) + { + QColor col(itsHighlightCols[0]); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(col); + drawAaLine(painter, r.left()+highlightOffset, r.top()+1, r.right()-highlightOffset, r.top()+1); + col.setAlphaF(0.5); + painter->setPen(col); + drawAaLine(painter, r.left()+1, r.top()+2, r.right()-1, r.top()+2); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setClipRect(QRect(r.x(), r.y(), r.width(), highlightBorder)); + drawBorder(painter, r, option, ROUNDED_ALL, itsHighlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3); + } + + if(opts.colorSelTab) + colorTab(painter, r.adjusted(1+sizeAdjust, 1, -(1+sizeAdjust), 0), true, WIDGET_TAB_TOP, round); + } + else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver) + drawHighlight(painter, QRect(r.x()+(firstTab ? moOffset : 1), + r.y()+(TAB_MO_TOP==opts.tabMouseOver ? 0 : r.height()-1), + r.width()-(firstTab || lastTab ? moOffset : 1), 2), + true, TAB_MO_TOP==opts.tabMouseOver); + break; + } + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + { + int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs + ? ROUNDED_BOTTOM + : firstTab + ? ROUNDED_BOTTOMLEFT + : lastTab + ? ROUNDED_BOTTOMRIGHT + : ROUNDED_NONE; + if(!selected) + r.adjust(0, 2, 0, -2); + if(!firstTab) + r.adjust(-tabOverlap, 0, 0, 0); + + painter->setClipPath(buildPath(r.adjusted(0, -4, 0, 0), WIDGET_TAB_BOT, round, radius)); + fillTab(painter, r.adjusted(1+sizeAdjust, 0, -(1+sizeAdjust), -1), option, fill, true, WIDGET_TAB_BOT, (docMode || onlyTab)); + if(thin) + painter->setClipRect(r2.adjusted(0, 1, 0, 0)); + else + painter->setClipping(false); + drawBorder(painter, r.adjusted(sizeAdjust, -4, -sizeAdjust, 0), option, round, glowMo ? itsMouseOverCols : 0L, + WIDGET_TAB_BOT, borderProfile, false); + if(thin) + painter->setClipping(false); + if(drawOuterGlow) + drawGlow(painter, r.adjusted(0, -5, 0, 1), WIDGET_TAB_BOT); + + if(selected) + { + if(!thin) + { + painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]); + if(!fixLeft) + painter->drawPoint(r2.left()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.top()); + if(!fixRight) + painter->drawLine(r2.right()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.top(), r2.right(), r2.top()); + } + if(docFixLeft) + { + QColor col(use[STD_BORDER]); + col.setAlphaF(0.5); + painter->setPen(col); + painter->drawPoint(r2.x(), r2.y()); + } + } + else + { + int l(fixLeft ? r2.left()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.left()-1), + r(fixRight ? r2.right()-2 : r2.right()); + painter->setPen(use[STD_BORDER]); + painter->drawLine(l, r2.top()+1, r, r2.top()+1); + if(!thin) + { + painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]); + painter->drawLine(l, r2.top(), r, r2.top()); + } + } + + if(selected) + { + if(opts.highlightTab) + { + QColor col(itsHighlightCols[0]); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(col); + drawAaLine(painter, r.left()+highlightOffset, r.bottom()-1, r.right()-highlightOffset, r.bottom()-1); + col.setAlphaF(0.5); + painter->setPen(col); + drawAaLine(painter, r.left()+1, r.bottom()-2, r.right()-1, r.bottom()-2); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setClipRect(QRect(r.x(), r.y()+r.height()-highlightBorder, r.width(), r.y()+r.height()-1)); + drawBorder(painter, r, option, ROUNDED_ALL, itsHighlightCols, WIDGET_TAB_BOT, BORDER_FLAT, false, 3); + } + + if(opts.colorSelTab) + colorTab(painter, r.adjusted(1+sizeAdjust, 0, -(1+sizeAdjust), -1), true, WIDGET_TAB_BOT, round); + } + else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver) + drawHighlight(painter, QRect(r.x()+(firstTab ? moOffset : 1), + r.y()+(TAB_MO_TOP==opts.tabMouseOver ? r.height()-2 : -1), + r.width()-(firstTab || lastTab ? moOffset : 1), 2), + true, TAB_MO_TOP!=opts.tabMouseOver); + break; + } + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + { + int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs + ? ROUNDED_LEFT + : firstTab + ? ROUNDED_TOPLEFT + : lastTab + ? ROUNDED_BOTTOMLEFT + : ROUNDED_NONE; + if(!selected) + r.adjust(2, 0, -2, 0); + + if(!firstTab) + r.adjust(0, -tabOverlap, 0, 0); + painter->setClipPath(buildPath(r.adjusted(0, 0, 4, 0), WIDGET_TAB_TOP, round, radius)); + fillTab(painter, r.adjusted(1, sizeAdjust, 0, -(1+sizeAdjust)), option, fill, false, WIDGET_TAB_TOP, (docMode || onlyTab)); + if(thin) + painter->setClipRect(r2.adjusted(0, 0, -1, 0)); + else + painter->setClipping(false); + drawBorder(painter, r.adjusted(0, sizeAdjust, 4, -sizeAdjust), option, round, glowMo ? itsMouseOverCols : 0L, + WIDGET_TAB_TOP, borderProfile, false); + if(thin) + painter->setClipping(false); + if(drawOuterGlow) + drawGlow(painter, r.adjusted(-1, 0, 5, 0), WIDGET_TAB_TOP); + + if(selected) + { + if(!thin) + { + painter->setPen(use[0]); + if(!firstTab) + painter->drawPoint(r2.right(), r2.top()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1)); + painter->drawLine(r2.right(), r2.bottom()-1, r2.right(), r2.bottom()); + } + } + else + { + int t(firstTab ? r2.top()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.top()-1), + b(/*lastTab ? r2.bottom()-2 : */ r2.bottom()+1); + + painter->setPen(use[STD_BORDER]); + painter->drawLine(r2.right()-1, t, r2.right()-1, b); + if(!thin) + { + painter->setPen(use[0]); + painter->drawLine(r2.right(), t, r2.right(), b); + } + } + + if(selected) + { + if(opts.highlightTab) + { + QColor col(itsHighlightCols[0]); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(col); + drawAaLine(painter, r.left()+1, r.top()+highlightOffset, r.left()+1, r.bottom()-highlightOffset); + col.setAlphaF(0.5); + painter->setPen(col); + drawAaLine(painter, r.left()+2, r.top()+1, r.left()+2, r.bottom()-1); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setClipRect(QRect(r.x(), r.y(), highlightBorder, r.height())); + drawBorder(painter, r, option, ROUNDED_ALL, itsHighlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3); + } + + if(opts.colorSelTab) + colorTab(painter, r.adjusted(1, sizeAdjust, 0, -(1+sizeAdjust)), false, WIDGET_TAB_TOP, round); + } + else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver) + drawHighlight(painter, QRect(r.x()+(TAB_MO_TOP==opts.tabMouseOver ? 0 : r.width()-1), + r.y()+(firstTab ? moOffset : 1), + 2, r.height()-(firstTab || lastTab ? moOffset : 1)), + false, TAB_MO_TOP==opts.tabMouseOver); + break; + } + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + { + int round=selected || oneTab || TAB_MO_GLOW==opts.tabMouseOver || opts.roundAllTabs + ? ROUNDED_RIGHT + : firstTab + ? ROUNDED_TOPRIGHT + : lastTab + ? ROUNDED_BOTTOMRIGHT + : ROUNDED_NONE; + if(!selected) + r.adjust(2, 0, -2, 0); + + if(!firstTab) + r.adjust(0, -tabOverlap, 0, 0); + painter->setClipPath(buildPath(r.adjusted(-4, 0, 0, 0), WIDGET_TAB_BOT, round, radius)); + fillTab(painter, r.adjusted(0, sizeAdjust, -1, -(1+sizeAdjust)), option, fill, false, WIDGET_TAB_BOT, (docMode || onlyTab)); + if(thin) + painter->setClipRect(r2.adjusted(1, 0, 0, 0)); + else + painter->setClipping(false); + drawBorder(painter, r.adjusted(-4, sizeAdjust, 0, -sizeAdjust), option, round, glowMo ? itsMouseOverCols : 0L, + WIDGET_TAB_BOT, borderProfile, false); + if(thin) + painter->setClipping(false); + if(drawOuterGlow) + drawGlow(painter, r.adjusted(-5, 0, 1, 0), WIDGET_TAB_BOT); + + if(selected) + { + if(!thin) + { + painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]); + if(!firstTab) + painter->drawPoint(r2.left(), r2.top()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1)); + painter->drawLine(r2.left(), r2.bottom()-(TAB_MO_GLOW==opts.tabMouseOver ? 0 : 1), r2.left(), r2.bottom()); + } + } + else + { + int t(firstTab ? r2.top()+(opts.round>ROUND_SLIGHT && !(opts.square&SQUARE_TAB_FRAME)? 2 : 1) : r2.top()-1), + b(/*lastTab ? r2.bottom()-2 : */ r2.bottom()+1); + + painter->setPen(use[STD_BORDER]); + painter->drawLine(r2.left()+1, t, r2.left()+1, b); + if(!thin) + { + painter->setPen(use[opts.borderTab ? 0 : FRAME_DARK_SHADOW]); + painter->drawLine(r2.left(), t, r2.left(), b); + } + } + + if(selected) + { + if(opts.highlightTab) + { + QColor col(itsHighlightCols[0]); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(col); + drawAaLine(painter, r.right()-1, r.top()+highlightOffset, r.right()-1, r.bottom()-highlightOffset); + col.setAlphaF(0.5); + painter->setPen(col); + drawAaLine(painter, r.right()-2, r.top()+1, r.right()-2, r.bottom()-1); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setClipRect(QRect(r.x()+r.width()-highlightBorder, r.y(), r.x()+r.width()-1, r.height())); + drawBorder(painter, r, option, ROUNDED_ALL, itsHighlightCols, WIDGET_TAB_TOP, BORDER_FLAT, false, 3); + } + + if(opts.colorSelTab) + colorTab(painter, r.adjusted(0, sizeAdjust, -1, -(1+sizeAdjust)), false, WIDGET_TAB_BOT, round); + } + else if(mouseOver && opts.coloredMouseOver && TAB_MO_GLOW!=opts.tabMouseOver) + drawHighlight(painter, QRect(r.x()+(TAB_MO_TOP==opts.tabMouseOver ? r.width()-2 : -1), + r.y()+(firstTab ? moOffset : 1), + 2, r.height()-(firstTab || lastTab ? moOffset : 1)), + false, TAB_MO_TOP!=opts.tabMouseOver); + break; + } + } + painter->restore(); + } + break; + case CE_ScrollBarAddLine: + case CE_ScrollBarSubLine: + { + QRect br(r), + ar(r); + const QColor *use(state&State_Enabled ? itsButtonCols : itsBackgroundCols); // buttonColors(option)); + bool reverse(option && Qt::RightToLeft==option->direction); + PrimitiveElement pe=state&State_Horizontal + ? CE_ScrollBarAddLine==element ? (reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight) + : (reverse ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft) + : CE_ScrollBarAddLine==element ? PE_IndicatorArrowDown : PE_IndicatorArrowUp; + int round=PE_IndicatorArrowRight==pe ? ROUNDED_RIGHT : + PE_IndicatorArrowLeft==pe ? ROUNDED_LEFT : + PE_IndicatorArrowDown==pe ? ROUNDED_BOTTOM : + PE_IndicatorArrowUp==pe ? ROUNDED_TOP : ROUNDED_NONE; + + switch(opts.scrollbarType) + { + default: + case SCROLLBAR_WINDOWS: + break; + case SCROLLBAR_KDE: + case SCROLLBAR_PLATINUM: + if(!reverse && PE_IndicatorArrowLeft==pe && r.x()>3) + { + round=ROUNDED_NONE; + br.adjust(0, 0, 1, 0); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(1, 0, 1, 0); + } + else if(reverse && PE_IndicatorArrowRight==pe && r.x()>3) + { + if(SCROLLBAR_PLATINUM==opts.scrollbarType) + { + round=ROUNDED_NONE; + br.adjust(-1, 0, 0, 0); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(-1, 0, -1, 0); + } + else + { + if(r.x()3) + { + round=ROUNDED_NONE; + br.adjust(0, 0, 0, 1); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(0, 1, 0, 1); + } + break; + case SCROLLBAR_NEXT: + if(!reverse && PE_IndicatorArrowRight==pe) + { + round=ROUNDED_NONE; + br.adjust(-1, 0, 0, 0); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(-1, 0, 0, -1); + } + else if(reverse && PE_IndicatorArrowLeft==pe) + { + round=ROUNDED_NONE; + br.adjust(0, 0, 1, 0); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(-1, 0, 0, 1); + } + else if(PE_IndicatorArrowDown==pe) + { + round=ROUNDED_NONE; + br.adjust(0, -1, 0, 0); + if(opts.flatSbarButtons || !opts.vArrows) + ar.adjust(0, -1, 0, -1); + } + break; + } + + painter->save(); + if(opts.flatSbarButtons && !IS_FLAT(opts.sbarBgndAppearance) /*&& SCROLLBAR_NONE!=opts.scrollbarType*/) + drawBevelGradientReal(palette.brush(QPalette::Background).color(), painter, r, state&State_Horizontal, false, + opts.sbarBgndAppearance, WIDGET_SB_BGND); + + QStyleOption opt(*option); + + opt.state|=State_Raised; + + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + { + if((CE_ScrollBarSubLine==element && slider->sliderValue==slider->minimum) || + (CE_ScrollBarAddLine==element && slider->sliderValue==slider->maximum)) + opt.state&=~(State_MouseOver|State_Sunken|State_On); + + if(slider->minimum==slider->maximum && opt.state&State_Enabled) + opt.state^=State_Enabled; + } + + if(opts.flatSbarButtons) + opt.state&=~(State_Sunken|State_On); + else + drawLightBevel(painter, br, &opt, widget, round, getFill(&opt, use), use, true, WIDGET_SB_BUTTON); + + opt.rect = ar; + + if(!(opt.state&State_Enabled)) + opt.palette.setCurrentColorGroup(QPalette::Disabled); + + if(opt.palette.text().color()!=opt.palette.buttonText().color()) // The following fixes gwenviews scrollbars... + opt.palette.setColor(QPalette::Text, opt.palette.buttonText().color()); + + drawPrimitive(pe, &opt, painter, widget); + painter->restore(); + break; + } + case CE_ScrollBarSubPage: + case CE_ScrollBarAddPage: + { + const QColor *use(itsBackgroundCols); // backgroundColors(option)); + int borderAdjust(0); + + painter->save(); +#ifndef SIMPLE_SCROLLBARS + if(ROUNDED && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)) + painter->fillRect(r, palette.background().color()); +#endif + + switch(opts.scrollbarType) + { + case SCROLLBAR_KDE: + case SCROLLBAR_WINDOWS: + borderAdjust=1; + break; + case SCROLLBAR_PLATINUM: + if(CE_ScrollBarAddPage==element) + borderAdjust=1; + break; + case SCROLLBAR_NEXT: + if(CE_ScrollBarSubPage==element) + borderAdjust=1; + default: + break; + } + + if(state&State_Horizontal) + { + if(IS_FLAT(opts.appearance)) + painter->fillRect(r.x(), r.y()+1, r.width(), r.height()-2, use[2]); + else + drawBevelGradient(use[2], painter, QRect(r.x(), r.y()+1, r.width(), r.height()-2), + true, false, opts.grooveAppearance, WIDGET_TROUGH); + +#ifndef SIMPLE_SCROLLBARS + if(ROUNDED && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)) + { + if(CE_ScrollBarAddPage==element) + drawBorder(painter, r.adjusted(-5, 0, 0, 0), option, ROUNDED_RIGHT, use, WIDGET_TROUGH); + else + drawBorder(painter, r.adjusted(0, 0, 5, 0), option, ROUNDED_LEFT, use, WIDGET_TROUGH); + } + else +#endif + if(CE_ScrollBarAddPage==element) + drawBorder(painter, r.adjusted(-5, 0, borderAdjust, 0), option, ROUNDED_NONE, use, WIDGET_TROUGH); + else + drawBorder(painter, r.adjusted(-borderAdjust, 0, 5, 0), option, ROUNDED_NONE, use, WIDGET_TROUGH); + } + else + { + if(IS_FLAT(opts.appearance)) + painter->fillRect(r.x()+1, r.y(), r.width()-2, r.height(), use[2]); + else + drawBevelGradient(use[2], painter, QRect(r.x()+1, r.y(), r.width()-2, r.height()), + false, false, opts.grooveAppearance, WIDGET_TROUGH); + +#ifndef SIMPLE_SCROLLBARS + if(ROUNDED && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)) + { + if(CE_ScrollBarAddPage==element) + drawBorder(painter, r.adjusted(0, -5, 0, 0), option, ROUNDED_BOTTOM, use, WIDGET_TROUGH); + else + drawBorder(painter, r.adjusted(0, 0, 0, 5), option, ROUNDED_TOP, use, WIDGET_TROUGH); + } + else +#endif + if(CE_ScrollBarAddPage==element) + drawBorder(painter, r.adjusted(0, -5, 0, borderAdjust), option, ROUNDED_NONE, use, WIDGET_TROUGH); + else + drawBorder(painter, r.adjusted(0, -borderAdjust, 0, 5), option, ROUNDED_NONE, use, WIDGET_TROUGH); + } + painter->restore(); + break; + } + case CE_ScrollBarSlider: + painter->save(); + drawSbSliderHandle(painter, r, option); + painter->restore(); + break; +#ifdef FIX_DISABLED_ICONS + // Taken from QStyle - only required so that we can corectly set the disabled icon!!! + case CE_ToolButtonLabel: + if (const QStyleOptionToolButton *tb = qstyleoption_cast(option)) + { + int shiftX = 0, + shiftY = 0; + if (state & (State_Sunken|State_On)) + { + shiftX = pixelMetric(PM_ButtonShiftHorizontal, tb, widget); + shiftY = pixelMetric(PM_ButtonShiftVertical, tb, widget); + } + + // Arrow type always overrules and is always shown + bool hasArrow = tb->features & QStyleOptionToolButton::Arrow; + + if (((!hasArrow && tb->icon.isNull()) && !tb->text.isEmpty()) || Qt::ToolButtonTextOnly==tb->toolButtonStyle) + { + int alignment = Qt::AlignCenter|Qt::TextShowMnemonic; + + if (!styleHint(SH_UnderlineShortcut, option, widget)) + alignment |= Qt::TextHideMnemonic; + + r.translate(shiftX, shiftY); + + drawItemTextWithRole(painter, r, alignment, palette, state&State_Enabled, tb->text, QPalette::ButtonText); + } + else + { + QPixmap pm; + QSize pmSize = tb->iconSize; + QRect pr = r; + + if (!tb->icon.isNull()) + { + QIcon::State state = tb->state & State_On ? QIcon::On : QIcon::Off; + QIcon::Mode mode=!(tb->state & State_Enabled) + ? QIcon::Disabled + : (state&State_MouseOver) && (state&State_AutoRaise) + ? QIcon::Active + : QIcon::Normal; + QSize iconSize = tb->iconSize; + + if (!iconSize.isValid()) + { + int iconExtent = pixelMetric(PM_ToolBarIconSize); + iconSize = QSize(iconExtent, iconExtent); + } + /* Not required? + else if(iconSize.width()>iconSize.height()) + iconSize.setWidth(iconSize.height()); + else if(iconSize.width()tb->rect.size().width()) + iconSize=QSize(tb->rect.size().width(), tb->rect.size().width()); + if(iconSize.height()>tb->rect.size().height()) + iconSize=QSize(tb->rect.size().height(), tb->rect.size().height()); + + pm=getIconPixmap(tb->icon, iconSize, mode, state); + pmSize = pm.size(); // tb->icon.actualSize(iconSize, mode); + /*if(pmSize.width()toolButtonStyle) + { + QRect tr = r; + int alignment = Qt::TextShowMnemonic; + + painter->setFont(tb->font); + if (!styleHint(SH_UnderlineShortcut, option, widget)) + alignment |= Qt::TextHideMnemonic; + + if (Qt::ToolButtonTextUnderIcon==tb->toolButtonStyle) + { + pr.setHeight(pmSize.height() + 6); + + tr.adjust(0, pr.bottom()-3, 0, 0); // -3); + pr.translate(shiftX, shiftY); + if (hasArrow) + drawTbArrow(this, tb, pr, painter, widget); + else + drawItemPixmap(painter, pr, Qt::AlignCenter, pm); + alignment |= Qt::AlignCenter; + } + else + { + pr.setWidth(pmSize.width() + 8); + tr.adjust(pr.right(), 0, 0, 0); + pr.translate(shiftX, shiftY); + if (hasArrow) + drawTbArrow(this, tb, pr, painter, widget); + else + drawItemPixmap(painter, QStyle::visualRect(option->direction, r, pr), Qt::AlignCenter, pm); + alignment |= Qt::AlignLeft | Qt::AlignVCenter; + } + tr.translate(shiftX, shiftY); + drawItemTextWithRole(painter, QStyle::visualRect(option->direction, r, tr), alignment, palette, + state & State_Enabled, tb->text, QPalette::ButtonText); + } + else + { + pr.translate(shiftX, shiftY); + + if (hasArrow) + drawTbArrow(this, tb, pr, painter, widget); + else + { + if (!(tb->subControls&SC_ToolButtonMenu) && tb->features&QStyleOptionToolButton::HasMenu && + pr.width()>pm.width() && ((pr.width()-pm.width())>LARGE_ARR_WIDTH)) + pr.adjust(-LARGE_ARR_WIDTH, 0, 0, 0); + drawItemPixmap(painter, pr, Qt::AlignCenter, pm); + } + } + } + } + break; + case CE_RadioButtonLabel: + case CE_CheckBoxLabel: + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) + { + uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter); + QPixmap pix; + QRect textRect = r; + + if (!styleHint(SH_UnderlineShortcut, btn, widget)) + alignment |= Qt::TextHideMnemonic; + + if (!btn->icon.isNull()) + { + pix = getIconPixmap(btn->icon, btn->iconSize, btn->state); + drawItemPixmap(painter, r, alignment, pix); + if (reverse) + textRect.setRight(textRect.right() - btn->iconSize.width() - 4); + else + textRect.setLeft(textRect.left() + btn->iconSize.width() + 4); + } + if (!btn->text.isEmpty()) + drawItemTextWithRole(painter, textRect, alignment | Qt::TextShowMnemonic, + palette, state&State_Enabled, btn->text, QPalette::WindowText); + } + break; + case CE_ToolBoxTabLabel: + if (const QStyleOptionToolBox *tb = qstyleoption_cast(option)) + { + bool enabled = state & State_Enabled, + selected = state & State_Selected; + QPixmap pm = getIconPixmap(tb->icon, pixelMetric(QStyle::PM_SmallIconSize, tb, widget) ,state); + QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget); + QRect tr, ir; + int ih = 0; + + if (pm.isNull()) + { + tr = cr; + tr.adjust(4, 0, -8, 0); + } + else + { + int iw = pm.width() + 4; + ih = pm.height(); + ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih); + tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height()); + } + + if (selected && styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb, widget)) + { + QFont f(painter->font()); + f.setBold(true); + painter->setFont(f); + } + + QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width()); + + if (ih) + painter->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm); + + int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic; + if (!styleHint(QStyle::SH_UnderlineShortcut, tb, widget)) + alignment |= Qt::TextHideMnemonic; + drawItemTextWithRole(painter, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText); + + if (!txt.isEmpty() && state&State_HasFocus) + { + QStyleOptionFocusRect opt; + opt.rect = tr; + opt.palette = palette; + opt.state = QStyle::State_None; + drawPrimitive(PE_FrameFocusRect, &opt, painter, widget); + } + } + break; +#endif + case CE_RadioButton: + case CE_CheckBox: + if (opts.crHighlight && (r.width()>opts.crSize*2)) + if (const QStyleOptionButton *button = qstyleoption_cast(option)) + { + QStyleOptionButton copy(*button); + + copy.rect.adjust(2, 0, -2, 0); + + if(button->state&State_MouseOver && button->state&State_Enabled) + { + QRect highlightRect(subElementRect(CE_RadioButton==element ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, + option, widget)); + + if(Qt::RightToLeft==button->direction) + highlightRect.setRight(r.right()); + else + highlightRect.setX(r.x()); + highlightRect.setWidth(highlightRect.width()+1); + + if(ROUND_NONE!=opts.round) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + double radius(qtcGetRadius(&opts, highlightRect.width(), highlightRect.height(), + WIDGET_OTHER, RADIUS_SELECTION)); + + drawBevelGradient(shade(palette.background().color(), TO_FACTOR(opts.crHighlight)), + painter, highlightRect, + buildPath(QRectF(highlightRect), WIDGET_OTHER, ROUNDED_ALL, radius), true, + false, opts.selectionAppearance, WIDGET_SELECTION, false); + painter->restore(); + } + else + drawBevelGradient(shade(palette.background().color(), TO_FACTOR(opts.crHighlight)), painter, + highlightRect, true, false, opts.selectionAppearance, WIDGET_SELECTION); + } + BASE_STYLE::drawControl(element, ©, painter, widget); + break; + } + // Fall through! + default: + BASE_STYLE::drawControl(element, option, painter, widget); + } +} + +void Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const +{ + QRect r(option->rect); + const QFlags &state(option->state); + const QPalette &palette(option->palette); + bool reverse(Qt::RightToLeft==option->direction); + + switch (control) + { + case CC_Dial: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + { + r.adjust(1, 1, -1, -1); + + QStyleOptionComplex opt(*option); + bool mo(state&State_Enabled && state&State_MouseOver); + QRect outer(r); + int sliderWidth = /*qMin(2*r.width()/5, */CIRCULAR_SLIDER_SIZE/*)*/; +#ifdef DIAL_DOT_ON_RING + int halfWidth=sliderWidth/2; +#endif + + opt.state|=State_Horizontal; + + // Outer circle... + if (outer.width() > outer.height()) + { + outer.setLeft(outer.x()+(outer.width()-outer.height())/2); + outer.setWidth(outer.height()); + } + else + { + outer.setTop(outer.y()+(outer.height()-outer.width())/2); + outer.setHeight(outer.width()); + } + + opt.state&=~State_MouseOver; +#ifdef DIAL_DOT_ON_RING + opt.rect=outer.adjusted(halfWidth, halfWidth, -halfWidth, -halfWidth); +#else + opt.rect=outer; +#endif + drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL, + getFill(&opt, itsBackgroundCols), itsBackgroundCols, + true, WIDGET_DIAL); + + // Inner 'dot' + if(mo) + opt.state|=State_MouseOver; + + // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA. + qreal angle(0); + if(slider->maximum == slider->minimum) + angle = M_PI / 2; + else + { + const qreal fraction(qreal(slider->sliderValue - slider->minimum)/ + qreal(slider->maximum - slider->minimum)); + if(slider->dialWrapping) + angle = 1.5*M_PI - fraction*2*M_PI; + else + angle = (M_PI*8 - fraction*10*M_PI)/6; + } + + QPoint center = outer.center(); +#ifdef DIAL_DOT_ON_RING + const qreal radius=0.5*(outer.width() - sliderWidth); +#else + const qreal radius=0.5*(outer.width() - 2*sliderWidth); +#endif + center += QPoint(radius*cos(angle), -radius*sin(angle)); + + opt.rect=QRect(outer.x(), outer.y(), sliderWidth, sliderWidth); + opt.rect.moveCenter(center); + + const QColor *use(buttonColors(option)); + + drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL, + getFill(&opt, use), use, true, WIDGET_RADIO_BUTTON); + + // Draw value... +#ifdef DIAL_DOT_ON_RING + drawItemTextWithRole(painter, outer.adjusted(sliderWidth, sliderWidth, -sliderWidth, -sliderWidth), + Qt::AlignCenter, palette, state&State_Enabled, + QString::number(slider->sliderValue), QPalette::ButtonText); +#else + int adjust=2*sliderWidth; + drawItemTextWithRole(painter, outer.adjusted(adjust, adjust, -adjust, -adjust), + Qt::AlignCenter, palette, state&State_Enabled, + QString::number(slider->sliderValue), QPalette::ButtonText); +#endif + + if(state&State_HasFocus) + { + QStyleOptionFocusRect fr; + fr.rect = outer.adjusted(-1, -1, 1, 1); + drawPrimitive(PE_FrameFocusRect, &fr, painter, widget); + } + } + break; + case CC_ToolButton: + // For OO.o 3.2 need to fill widget background! + if(isOOWidget(widget)) + painter->fillRect(r, palette.brush(QPalette::Window)); + if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(option)) + { + int widthAdjust(0), + heightAdjust(0); + + if (widget) + { + if((opts.dwtSettings&DWT_BUTTONS_AS_PER_TITLEBAR) && + (widget->inherits("QDockWidgetTitleButton") || + (widget->parentWidget() && widget->parentWidget()->inherits("KoDockWidgetTitleBar")))) + { + ETitleBarButtons btn=TITLEBAR_CLOSE; + Icon icon=ICN_CLOSE; + + if(constDwtFloat==widget->objectName()) + btn=TITLEBAR_MAX, icon=ICN_RESTORE; + else if(constDwtClose!=widget->objectName() && + widget->parentWidget() && widget->parentWidget()->parentWidget() && + widget->parentWidget()->inherits("KoDockWidgetTitleBar") && + ::qobject_cast(widget->parentWidget()->parentWidget())) + { + QDockWidget *dw = (QDockWidget *)widget->parentWidget()->parentWidget(); + QWidget *koDw = widget->parentWidget(); + int fw = dw->isFloating() + ? pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, dw) + : 0; + QRect geom(widget->geometry()); + QStyleOptionDockWidgetV2 dwOpt; + dwOpt.initFrom(dw); + dwOpt.rect = QRect(QPoint(fw, fw), QSize(koDw->geometry().width() - (fw * 2), + koDw->geometry().height() - (fw * 2))); + dwOpt.title = dw->windowTitle(); + dwOpt.closable = (dw->features()&QDockWidget::DockWidgetClosable)==QDockWidget::DockWidgetClosable; + dwOpt.floatable = (dw->features()&QDockWidget::DockWidgetFloatable)== + QDockWidget::DockWidgetFloatable; + + if(dwOpt.closable && subElementRect(QStyle::SE_DockWidgetCloseButton, &dwOpt, + widget->parentWidget()->parentWidget())==geom) + btn=TITLEBAR_CLOSE, icon=ICN_CLOSE; + else if(dwOpt.floatable && subElementRect(QStyle::SE_DockWidgetFloatButton, &dwOpt, + widget->parentWidget()->parentWidget())==geom) + btn=TITLEBAR_MAX, icon=ICN_RESTORE; + else + btn=TITLEBAR_SHADE, icon=dw && dw->widget() && dw->widget()->isVisible() + ? ICN_SHADE + : ICN_UNSHADE; + } + + QColor shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect)); + const QColor *bgndCols((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR) + ? getMdiColors(option, state&State_Active) + : buttonColors(option)), + *btnCols((opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR) + ? opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR + ? buttonColors(option) + : getMdiColors(option, state&State_Active) + : bgndCols); + + drawDwtControl(painter, state, r.adjusted(-1, -1, 1, 1), btn, icon, option->palette.color(QPalette::WindowText), btnCols, + bgndCols); + break; + } + if(qobject_cast(widget->parentWidget())) + { + QStyleOptionToolButton btn(*toolbutton); + + if(Qt::LeftArrow==toolbutton->arrowType || Qt::RightArrow==toolbutton->arrowType) + btn.rect.adjust(0, 4, 0, -4); + else + btn.rect.adjust(4, 0, -4, 0); + if(!(btn.state&State_Enabled)) + btn.state&=~State_MouseOver; + drawPrimitive(PE_PanelButtonTool, &btn, painter, widget); + if(opts.vArrows) + switch(toolbutton->arrowType) + { + case Qt::LeftArrow: + btn.rect.adjust(-1, 0, -1, 0); + break; + case Qt::RightArrow: + btn.rect.adjust(1, 0, 1, 0); + break; + case Qt::UpArrow: + btn.rect.adjust(0, -1, 0, -1); + break; + case Qt::DownArrow: + btn.rect.adjust(0, 1, 0, 1); + default: + break; + } + drawTbArrow(this, &btn, btn.rect, painter, widget); + break; + } + + const QToolButton *btn = qobject_cast(widget); + + if(btn && btn->isDown() && Qt::ToolButtonTextBesideIcon==btn->toolButtonStyle() && + widget->parentWidget() && qobject_cast(widget->parentWidget())) + { + painter->save(); + if(opts.menuStripe) + { + int stripeWidth(qMax(20, constMenuPixmapWidth)); + + drawBevelGradient(menuStripeCol(), + painter, QRect(reverse ? r.right()-stripeWidth : r.x(), r.y(), + stripeWidth, r.height()), false, + false, opts.menuStripeAppearance, WIDGET_OTHER); + } + +#if 0 + // For some reason the MenuTitle has a larger border on the left, so adjust the width by 1 pixel to make this look nicer. + //drawBorder(painter, r.adjusted(2, 2, -3, -2), option, ROUNDED_ALL, 0L, WIDGET_OTHER, BORDER_SUNKEN); + QStyleOptionToolButton opt(*toolbutton); + opt.rect = r.adjusted(2, 2, -3, -2); + opt.state=State_Raised|State_Enabled|State_Horizontal; + drawLightBevel(painter, opt.rect, &opt, widget, ROUNDED_ALL, + getFill(&opt, itsBackgroundCols), itsBackgroundCols, true, WIDGET_NO_ETCH_BTN); +#else + if(!opts.menuStripe) + drawFadedLine(painter, QRect(r.x()+3, r.y()+r.height()-1, r.width()-7, 1), + popupMenuCols(option)[MENU_SEP_SHADE], true, true, true); +#endif + QFont font(toolbutton->font); + + font.setBold(true); + painter->setFont(font); + drawItemTextWithRole(painter, r, Qt::AlignHCenter | Qt::AlignVCenter, + palette, state&State_Enabled, toolbutton->text, QPalette::Text); + painter->restore(); + break; + } + + // Amarok's toolbars (the one just above the collection list) are much thinner then normal, + // and QToolBarExtension does not seem to take this into account - so adjust the size here... + if(widget->inherits("QToolBarExtension") && widget->parentWidget()) + { + if(r.height()>widget->parentWidget()->rect().height()) + heightAdjust=(r.height()-widget->parentWidget()->rect().height())+2; + if(r.width()>widget->parentWidget()->rect().width()) + widthAdjust=(r.width()-widget->parentWidget()->rect().width())+2; + } + } + QRect button(subControlRect(control, toolbutton, SC_ToolButton, widget)), + menuarea(subControlRect(control, toolbutton, SC_ToolButtonMenu, widget)); + State bflags(toolbutton->state); + bool etched(DO_EFFECT), + raised=widget && (TBTN_RAISED==opts.tbarBtns || TBTN_JOINED==opts.tbarBtns), + horizTBar(true); + int round=ROUNDED_ALL, + leftAdjust(0), topAdjust(0), rightAdjust(0), bottomAdjust(0); + + if(raised) + { + const QToolBar *toolbar=getToolBar(widget); + + if(toolbar) + { + if(TBTN_JOINED==opts.tbarBtns) + { + horizTBar=Qt::Horizontal==toolbar->orientation(); + adjustToolbarButtons(widget, toolbar, leftAdjust, topAdjust, rightAdjust, bottomAdjust, round); + } + } + else + raised=false; + } + + if (!(bflags&State_Enabled)) + bflags &= ~(State_MouseOver/* | State_Raised*/); + + if(bflags&State_MouseOver) + bflags |= State_Raised; + else if(!raised && (bflags&State_AutoRaise)) + bflags &= ~State_Raised; + + if(state&State_AutoRaise || toolbutton->subControls&SC_ToolButtonMenu) + bflags|=STATE_TBAR_BUTTON; + + State mflags(bflags); + + if(!isOOWidget(widget)) + { +#if QT_VERSION >= 0x040500 + if (state&State_Sunken && !(toolbutton->activeSubControls&SC_ToolButton)) + bflags&=~State_Sunken; +#else + if (toolbutton->activeSubControls&SC_ToolButtonMenu && state&State_Enabled) + mflags |= State_Sunken; +#endif + } + + bool drawMenu=TBTN_JOINED==opts.tbarBtns + ? mflags & (State_Sunken | State_On) + : raised || (mflags & (State_Sunken | State_On | State_Raised)), + drawnBevel=false; + QStyleOption tool(0); + tool.palette = toolbutton->palette; + + if ( raised || + (toolbutton->subControls&SC_ToolButton && (bflags & (State_Sunken | State_On | State_Raised))) || + (toolbutton->subControls&SC_ToolButtonMenu && drawMenu)) + { + const QColor *use(buttonColors(toolbutton)); + + tool.rect = (toolbutton->subControls&SC_ToolButtonMenu ? button.united(menuarea) : button) + .adjusted(leftAdjust, topAdjust, rightAdjust, bottomAdjust); + tool.state = bflags|State_Horizontal; + + if(raised && TBTN_JOINED==opts.tbarBtns && !horizTBar) + tool.state &= ~State_Horizontal; + + tool.rect.adjust(0, 0, -widthAdjust, -heightAdjust); + if(!(bflags&State_Sunken) && (mflags&State_Sunken)) + tool.state &= ~State_MouseOver; + drawnBevel=true; + drawLightBevel(painter, tool.rect, &tool, widget, round, getFill(&tool, use), use, true, WIDGET_TOOLBAR_BUTTON); + + if(raised && TBTN_JOINED==opts.tbarBtns) + { + const int constSpace=4; + + QRect br(tool.rect.adjusted(-leftAdjust, -topAdjust, -rightAdjust, -bottomAdjust)); + + if(leftAdjust) + drawFadedLine(painter, QRect(br.x(), br.y()+constSpace, 1, br.height()-(constSpace*2)), use[0], true, true, false); + if(topAdjust) + drawFadedLine(painter, QRect(br.x()+constSpace, br.y(), br.width()-(constSpace*2), 1), use[0], true, true, true); + if(rightAdjust) + drawFadedLine(painter, QRect(br.x()+br.width()-1, br.y()+constSpace, 1, br.height()-(constSpace*2)), + use[STD_BORDER], true, true, false); + if(bottomAdjust) + drawFadedLine(painter, QRect(br.x()+constSpace, br.y()+br.height()-1, br.width()-(constSpace*2), 1), + use[STD_BORDER], true, true, true); + } + } + + if (toolbutton->subControls&SC_ToolButtonMenu) + { + if(etched) + { + if(reverse) + menuarea.adjust(1, 1, 0, -1); + else + menuarea.adjust(0, 1, -1, -1); + } + + tool.state = mflags|State_Horizontal; + + if(drawMenu) + { + const QColor *use(buttonColors(option)); + int mRound=reverse ? ROUNDED_LEFT : ROUNDED_RIGHT; + + if(mflags&State_Sunken) + tool.state&=~State_MouseOver; + + if(raised && TBTN_JOINED==opts.tbarBtns) + { + if(!horizTBar) + tool.state &= ~State_Horizontal; + painter->save(); + painter->setClipRect(menuarea, Qt::IntersectClip); + if((reverse && leftAdjust) || (!reverse && rightAdjust)) + mRound=ROUNDED_NONE; + if(reverse) + tool.rect.adjust(1, 0, 0, 0); + else + tool.rect.adjust(0, 0, -1, 0); + } + else + tool.rect = menuarea; + + drawLightBevel(painter, tool.rect, &tool, widget, mRound, getFill(&tool, use), use, true, + MO_GLOW==opts.coloredMouseOver ? WIDGET_MENU_BUTTON : WIDGET_NO_ETCH_BTN); + if(raised && TBTN_JOINED==opts.tbarBtns) + painter->restore(); + } + + tool.rect = menuarea; + + if(mflags&State_Sunken) + tool.rect.adjust(1, 1, 1, 1); + drawArrow(painter, tool.rect, PE_IndicatorArrowDown, + MO_ARROW_X(toolbutton->activeSubControls&SC_ToolButtonMenu, + QPalette::ButtonText)); + } + + if ((FOCUS_GLOW!=opts.focus || !drawnBevel) && toolbutton->state&State_HasFocus) + { + QStyleOptionFocusRect fr; + + fr.QStyleOption::operator=(*toolbutton); + if(FULL_FOCUS) + { + if(etched) + fr.rect.adjust(1, 1, -1, -1); + } + else + { + if(FOCUS_GLOW==opts.focus) + fr.rect.adjust(1, 1, -1, -1); + else if(etched) + fr.rect.adjust(4, 4, -4, -4); + else + fr.rect.adjust(3, 3, -3, -3); + +#if QT_VERSION >= 0x040300 + if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) +#else + if (toolbutton->features & QStyleOptionToolButton::Menu) +#endif + fr.rect.adjust(0, 0, -(pixelMetric(QStyle::PM_MenuButtonIndicator, toolbutton, widget)-1), 0); + } + if(!(state&State_MouseOver && FULL_FOCUS && MO_NONE!=opts.coloredMouseOver)) + drawPrimitive(PE_FrameFocusRect, &fr, painter, widget); + } + QStyleOptionToolButton label = *toolbutton; + int fw = pixelMetric(PM_DefaultFrameWidth, option, widget); + label.rect = button.adjusted(fw, fw, -(fw+widthAdjust), -(fw+heightAdjust)); + label.state = bflags; + drawControl(CE_ToolButtonLabel, &label, painter, widget); + + if (!(toolbutton->subControls&SC_ToolButtonMenu) && + (toolbutton->features&QStyleOptionToolButton::HasMenu)) + { + QRect arrow(r.right()-(LARGE_ARR_WIDTH+(etched ? 3 : 2)), + r.bottom()-(LARGE_ARR_HEIGHT+(etched ? 4 : 3)), + LARGE_ARR_WIDTH, LARGE_ARR_HEIGHT); + + if(bflags&State_Sunken) + arrow.adjust(1, 1, 1, 1); + + drawArrow(painter, arrow, PE_IndicatorArrowDown, MO_ARROW(QPalette::ButtonText)); + } + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(option)) { + // Draw frame + QRect textRect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); + QRect checkBoxRect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); + if (groupBox->subControls & QStyle::SC_GroupBoxFrame) + { + QStyleOptionFrameV2 frame; + frame.QStyleOption::operator=(*groupBox); + frame.features = groupBox->features; + frame.lineWidth = groupBox->lineWidth; + frame.midLineWidth = groupBox->midLineWidth; + frame.rect = /*proxy()->*/subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); + + if((groupBox->features&QStyleOptionFrameV2::Flat) || !(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE))) + { + painter->save(); + QRegion region(r); + if (!groupBox->text.isEmpty()) + region -= QRect(groupBox->subControls&QStyle::SC_GroupBoxCheckBox + ? checkBoxRect.united(textRect).adjusted(reverse ? 0 : -2, 0, reverse ? 2 : 0, 0) + : textRect); + painter->setClipRegion(region); + } + /*proxy()->*/drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); + if((groupBox->features&QStyleOptionFrameV2::Flat) || !(opts.gbLabel&(GB_LBL_INSIDE|GB_LBL_OUTSIDE))) + painter->restore(); + } + + // Draw title + if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) + { + QColor textColor = groupBox->textColor; + if (textColor.isValid()) + painter->setPen(textColor); + int alignment = int(groupBox->textAlignment); + if (!/*proxy()->*/styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + alignment |= Qt::TextHideMnemonic; + + if(opts.gbLabel&GB_LBL_BOLD) + { + QFont font(painter->font()); + + font.setBold(true); + painter->save(); + painter->setFont(font); + } + /*proxy()->*/drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, + palette, state & State_Enabled, groupBox->text, + textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); + + if(opts.gbLabel&GB_LBL_BOLD) + painter->restore(); + + if (state & State_HasFocus) + { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*groupBox); + fropt.rect = textRect; + /*proxy()->*/drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + + // Draw checkbox + if (groupBox->subControls & SC_GroupBoxCheckBox) + { + QStyleOptionButton box; + box.QStyleOption::operator=(*groupBox); + box.rect = checkBoxRect; + /*proxy()->*/drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget); + } + } + break; + case CC_Q3ListView: + if (const QStyleOptionQ3ListView *lv = qstyleoption_cast(option)) + { + int i; + if (lv->subControls&SC_Q3ListView) + QCommonStyle::drawComplexControl(control, lv, painter, widget); + if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) + { + if (lv->items.isEmpty()) + break; + + QStyleOptionQ3ListViewItem item(lv->items.at(0)); + int y(r.y()), + c; + QPolygon lines; + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, false); + if ((lv->activeSubControls&SC_All) && (lv->subControls&SC_Q3ListViewExpand)) + { + c = 2; + if(opts.lvLines) + { + lines.resize(2); + lines[0] = QPoint(r.right(), r.top()); + lines[1] = QPoint(r.right(), r.bottom()); + } + } + else + { + int linetop(0), + linebot(0); + // each branch needs at most two lines, ie. four end points + lines.resize(item.childCount * 4); + c = 0; + + // skip the stuff above the exposed rectangle + for (i = 1; i < lv->items.size(); ++i) + { + QStyleOptionQ3ListViewItem child = lv->items.at(i); + if (child.height + y > 0) + break; + y += child.totalHeight; + } + int bx(r.width() / 2); + + // paint stuff in the magical area + while (i < lv->items.size() && y < r.height()) + { + QStyleOptionQ3ListViewItem child = lv->items.at(i); + if (child.features & QStyleOptionQ3ListViewItem::Visible) + { + int lh(!(item.features & QStyleOptionQ3ListViewItem::MultiLine) + ? child.height + : painter->fontMetrics().height() + 2 * lv->itemMargin); + + lh = qMax(lh, QApplication::globalStrut().height()); + if (lh % 2 > 0) + ++lh; + linebot = y + lh / 2; + if (child.features & QStyleOptionQ3ListViewItem::Expandable + || (child.childCount > 0 && child.height > 0)) + { + + QRect ar(bx-4, linebot-4, 11, 11); + +#if 0 + if(LV_OLD==opts.lvLines) + { + int lo(ROUNDED ? 2 : 0); + + painter->setPen(palette.mid().color()); + painter->drawLine(ar.x()+lo, ar.y(), (ar.x()+ar.width()-1)-lo, ar.y()); + painter->drawLine(ar.x()+lo, ar.y()+ar.height()-1, (ar.x()+ar.width()-1)-lo, ar.y()+ar.height()-1); + painter->drawLine(ar.x(), ar.y()+lo, ar.x(), (ar.y()+ar.height()-1)-lo); + painter->drawLine(ar.x()+ar.width()-1, ar.y()+lo, ar.x()+ar.width()-1, (ar.y()+ar.height()-1)-lo); + + if(ROUNDED) + { + painter->drawPoint(ar.x()+1, ar.y()+1); + painter->drawPoint(ar.x()+1, ar.y()+ar.height()-2); + painter->drawPoint(ar.x()+ar.width()-2, ar.y()+1); + painter->drawPoint(ar.x()+ar.width()-2, ar.y()+ar.height()-2); + + QColor col(palette.mid().color()); + + col.setAlphaF(0.5); + painter->setPen(col); + painter->drawLine(ar.x()+1, ar.y()+1, ar.x()+2, ar.y()); + painter->drawLine(ar.x()+ar.width()-2, ar.y(), ar.x()+ar.width()-1, ar.y()+1); + painter->drawLine(ar.x()+1, ar.y()+ar.height()-2, ar.x()+2, ar.y()+ar.height()-1); + painter->drawLine(ar.x()+ar.width()-2, ar.y()+ar.height()-1, ar.x()+ar.width()-1, ar.y()+ar.height()-2); + } + } +#endif + + drawArrow(painter, ar, + child.state&State_Open + ? PE_IndicatorArrowDown + : reverse + ? PE_IndicatorArrowLeft + : PE_IndicatorArrowRight, + palette.text().color()); + + if(opts.lvLines) + { + lines[c++] = QPoint(bx+1, linetop); + lines[c++] = QPoint(bx+1, linebot - 4); + lines[c++] = QPoint(bx + 6, linebot); + lines[c++] = QPoint(r.width(), linebot); + linetop = linebot + 6; + } + } + else if(opts.lvLines) + { + // just dotlinery + lines[c++] = QPoint(bx+1, linebot -1); + lines[c++] = QPoint(r.width(), linebot -1); + } + y += child.totalHeight; + } + ++i; + } + + if(opts.lvLines) + { + // Expand line height to edge of rectangle if there's any + // visible child below + while (i < lv->items.size() && lv->items.at(i).height <= 0) + ++i; + + if (i < lv->items.size()) + linebot = r.height(); + + if (linetop < linebot) + { + lines[c++] = QPoint(bx+1, linetop); + lines[c++] = QPoint(bx+1, linebot-1); + } + } + } + + if (opts.lvLines && (lv->subControls&SC_Q3ListViewBranch)) + { + painter->setPen(palette.mid().color()); + + for(int line = 0; line < c; line += 2) + if (lines[line].y() == lines[line+1].y()) + painter->drawLine(lines[line].x(), lines[line].y(), lines[line + 1].x(), lines[line].y()); + else + painter->drawLine(lines[line].x(), lines[line].y(), lines[line].x(), lines[line + 1].y()); + } + painter->restore(); + } + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) + { + QRect frame(subControlRect(CC_SpinBox, option, SC_SpinBoxFrame, widget)), + up(subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget)), + down(subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget)), + all(frame.united(up).united(down)); + bool doFrame(spinBox->frame && frame.isValid()), + sunken(state&State_Sunken), + enabled(state&State_Enabled), + mouseOver(state&State_MouseOver), + upIsActive(SC_SpinBoxUp==spinBox->activeSubControls), + downIsActive(SC_SpinBoxDown==spinBox->activeSubControls), + doEtch(DO_EFFECT && opts.etchEntry), + isOO(isOOWidget(widget)), + oldUnify=opts.unifySpin; // See Krita note below... + + if(!doFrame && isOO && !opts.unifySpin) + { + doFrame=true; + frame=all; + } + + if(isOO) + painter->fillRect(r, palette.brush(QPalette::Window)); + + if(up.isValid()) + { + if(reverse) + frame.adjust(up.width(), 0, 0, 0); + else + frame.adjust(0, 0, -up.width(), 0); + } + + if(doEtch) + { + drawEtch(painter, all, widget, WIDGET_SPIN, false, + opts.square&SQUARE_ENTRY + ? opts.unifySpin + ? ROUNDED_NONE + : reverse + ? ROUNDED_LEFT + : ROUNDED_RIGHT + : ROUNDED_ALL); + down.adjust(reverse ? 1 : 0, 0, reverse ? 0 : -1, -1); + up.adjust(reverse ? 1 : 0, 1, reverse ? 0 : -1, 0); + frame.adjust(reverse ? 0 : 1, 1, reverse ? -1 : 0, -1); + all.adjust(1, 1, -1, -1); + } + + // Krita/KOffice uses a progressbar with spin buttons at the end + // ...when drawn, the frame part is not set - so in this case dont draw the background behind the buttons! + if(!isOO && !doFrame) + opts.unifySpin=true; // So, set this to true to fake the above scenario! + else + if(opts.unifySpin) + drawEntryField(painter, all, widget, option, ROUNDED_ALL, true, false); + else + { + if(opts.unifySpinBtns) + { + QRect btns=up.united(down); + const QColor *use(buttonColors(option)); + QStyleOption opt(*option); + + opt.state&=~(State_Sunken|State_MouseOver); + opt.state|=State_Horizontal; + + drawLightBevel(painter, btns, &opt, widget, reverse ? ROUNDED_LEFT : ROUNDED_RIGHT, + getFill(&opt, use), use, true, WIDGET_SPIN); + + if(state&State_MouseOver && state&State_Enabled && !(state&State_Sunken)) + { + opt.state|=State_MouseOver; + painter->save(); + painter->setClipRect(upIsActive ? up : down); + drawLightBevel(painter, btns, &opt, widget, reverse ? ROUNDED_LEFT : ROUNDED_RIGHT, + getFill(&opt, use), use, true, WIDGET_SPIN); + painter->restore(); + } + drawFadedLine(painter, down.adjusted(2, 0, -2, 0), use[BORDER_VAL(state&State_Enabled)], true, true, true); + } + } + + if(up.isValid()) + { + QStyleOption opt(*option); + + up.setHeight(up.height()+1); + opt.rect=up; + opt.direction=option->direction; + opt.state=(enabled && (spinBox->stepEnabled&QAbstractSpinBox::StepUpEnabled || + (QAbstractSpinBox::StepNone==spinBox->stepEnabled && isOO)) + ? State_Enabled : State_None)| + (upIsActive && sunken ? State_Sunken : State_Raised)| + (upIsActive && !sunken && mouseOver ? State_MouseOver : State_None)|State_Horizontal; + + drawPrimitive(QAbstractSpinBox::PlusMinus==spinBox->buttonSymbols ? PE_IndicatorSpinPlus : PE_IndicatorSpinUp, + &opt, painter, widget); + } + + if(down.isValid()) + { + QStyleOption opt(*option); + + opt.rect=down; + opt.state=(enabled && (spinBox->stepEnabled&QAbstractSpinBox::StepDownEnabled || + (QAbstractSpinBox::StepNone==spinBox->stepEnabled && isOO)) + ? State_Enabled : State_None)| + (downIsActive && sunken ? State_Sunken : State_Raised)| + (downIsActive && !sunken && mouseOver ? State_MouseOver : State_None)|State_Horizontal; + opt.direction=option->direction; + + drawPrimitive(QAbstractSpinBox::PlusMinus==spinBox->buttonSymbols ? PE_IndicatorSpinMinus : PE_IndicatorSpinDown, + &opt, painter, widget); + } + if(doFrame && !opts.unifySpin) + { + if(reverse) + frame.setX(frame.x()-1); + else + frame.setWidth(frame.width()+1); + drawEntryField(painter, frame, widget, option, reverse ? ROUNDED_RIGHT : ROUNDED_LEFT, true, false); + } + opts.unifySpin=oldUnify; + } + break; + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + { + QRect groove(subControlRect(CC_Slider, option, SC_SliderGroove, widget)), + handle(subControlRect(CC_Slider, option, SC_SliderHandle, widget)), + ticks(subControlRect(CC_Slider, option, SC_SliderTickmarks, widget)); + bool horizontal(slider->orientation == Qt::Horizontal), + ticksAbove(slider->tickPosition & QSlider::TicksAbove), + ticksBelow(slider->tickPosition & QSlider::TicksBelow); + + //The clickable region is 5 px wider than the visible groove for improved usability +// if (groove.isValid()) +// groove = horizontal ? groove.adjusted(0, 5, 0, -5) : groove.adjusted(5, 0, -5, 0); + + if ((option->subControls&SC_SliderGroove) && groove.isValid()) + drawSliderGroove(painter, groove, handle, slider, widget); + + if ((option->subControls&SC_SliderHandle) && handle.isValid()) + { + QStyleOptionSlider s(*slider); + if(!(s.activeSubControls & QStyle::SC_SliderHandle)) + { + s.state &= ~QStyle::State_MouseOver; + s.state &= ~QStyle::State_Sunken; + } + + drawSliderHandle(painter, handle, &s); + + if (state&State_HasFocus && FOCUS_GLOW!=opts.focus) + { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*slider); + fropt.rect = slider->rect; + + if(horizontal) + fropt.rect.adjust(0, 0, 0, -1); + else + fropt.rect.adjust(0, 0, -1, 0); + + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + + if (option->subControls&SC_SliderTickmarks) + { + QPen oldPen = painter->pen(); + painter->setPen(backgroundColors(option)[STD_BORDER]); + int tickSize(pixelMetric(PM_SliderTickmarkOffset, option, widget)), + available(pixelMetric(PM_SliderSpaceAvailable, slider, widget)), + interval(slider->tickInterval); + if (interval <= 0) + { + interval = slider->singleStep; + if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, + available) + - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + 0, available) < 3) + interval = slider->pageStep; + } + if (interval <= 0) + interval = 1; + + int sliderLength(slider->maximum - slider->minimum + 1), + nticks(sliderLength / interval); // add one to get the end tickmark + if (sliderLength % interval > 0) + nticks++; // round up the number of tick marks + + int v(slider->minimum), + len(pixelMetric(PM_SliderLength, slider, widget)); + + while (v <= slider->maximum + 1) + { + if (v == slider->maximum + 1 && interval == 1) + break; + + int pos(sliderPositionFromValue(slider->minimum, slider->maximum, + qMin(v, slider->maximum), (horizontal + ? slider->rect.width() + : slider->rect.height()) - len, + slider->upsideDown) + len / 2); + + int extra(2); // - ((v == slider->minimum || v == slider->maximum) ? 1 : 0); + + if (horizontal) + { + if (ticksAbove) + painter->drawLine(QLine(pos, slider->rect.top() + extra, + pos, slider->rect.top() + tickSize)); + if (ticksBelow) + painter->drawLine(QLine(pos, slider->rect.bottom() - extra, + pos, slider->rect.bottom() - tickSize)); + } + else + { + if (ticksAbove) + painter->drawLine(QLine(slider->rect.left() + extra, pos, + slider->rect.left() + tickSize, pos)); + if (ticksBelow) + painter->drawLine(QLine(slider->rect.right() - extra, pos, + slider->rect.right() - tickSize, pos)); + } + + // in the case where maximum is max int + int nextInterval = v + interval; + if (nextInterval < v) + break; + v = nextInterval; + } + painter->setPen(oldPen); + } + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast(option)) + { + painter->save(); + + EAppearance app=qtcWidgetApp(WIDGET_MDI_WINDOW_TITLE, &opts, option->state&State_Active); + bool active(state&State_Active), + kwin(theThemedApp==APP_KWIN || titleBar->titleBarState&QtC_StateKWin); + const QColor *bgndCols(APPEARANCE_NONE==app + ? kwin ? backgroundColors(option) : backgroundColors(palette.color(QPalette::Active, QPalette::Window)) + : kwin ? buttonColors(option) : getMdiColors(titleBar, active)), + *btnCols(kwin || opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR + ? buttonColors(option) + : getMdiColors(titleBar, active)), + *titleCols(APPEARANCE_NONE==app + ? bgndCols + : kwin || !(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR) + ? btnCols : getMdiColors(titleBar, active)); + QColor textColor(theThemedApp==APP_KWIN + ? option->palette.color(QPalette::WindowText) + : active + ? itsActiveMdiTextColor + : itsMdiTextColor), + iconColor(textColor), + shadow(WINDOW_SHADOW_COLOR(opts.titlebarEffect)); + QStyleOption opt(*option); + QRect tr(r), + menuRect(subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget)); + ERound round=(opts.square&SQUARE_WINDOWS && opts.round>ROUND_SLIGHT) ? ROUND_SLIGHT : opts.round; + QColor borderCol(kwin && option->version==(TBAR_BORDER_VERSION_HACK+2) + ? palette.color(QPalette::Active, QPalette::Shadow) + : titleCols[kwin && option->version==TBAR_BORDER_VERSION_HACK ? 0 : STD_BORDER]); + + if(!kwin && widget && BLEND_TITLEBAR && qobject_cast(widget)) + { + const QWidget *w=NULL; + if(qobject_cast(widget)) + w=widget; + else if (static_cast(widget)->widget()) + w=qobject_cast(static_cast(widget)->widget()); + if(w) + { + const QMenuBar *menuBar=static_cast(w)->menuBar(); + + if(menuBar) + tr.adjust(0, 0, 0, menuBar->rect().height()); + } + } + + opt.state=State_Horizontal|State_Enabled|State_Raised|(active ? State_Active : State_None); + +#ifdef QTC_QT_ONLY + QPainterPath path; +#else +#if KDE_IS_VERSION(4, 3, 0) + QPainterPath path(roundROUND_SLIGHT /*&& kwin*/ ? 6.0 : 2.0))); +#else + QPainterPath path; +#endif +#endif + if(!kwin && !CUSTOM_BGND) + painter->fillRect(tr, borderCol); + + painter->setRenderHint(QPainter::Antialiasing, true); + + if(kwin && (state&QtC_StateKWinFillBgnd)) + drawBevelGradient(titleCols[ORIGINAL_SHADE], painter, tr, path, true, false, APPEARANCE_FLAT, WIDGET_MDI_WINDOW, false); + if((!kwin && !itsIsPreview) || + (APPEARANCE_NONE!=app && (!IS_FLAT(app) || (titleCols[ORIGINAL_SHADE]!=QApplication::palette().background().color())))) + drawBevelGradient(titleCols[ORIGINAL_SHADE], painter, tr, path, true, false, app, WIDGET_MDI_WINDOW, false); + + if(!(state&QtC_StateKWinNoBorder)) + { + QColor light(titleCols[0]), + dark(borderCol); + bool addLight=opts.windowBorder&WINDOW_BORDER_ADD_LIGHT_BORDER && (!kwin || qtcGetWindowBorderSize().sides>1); + + if(kwin) + { + light.setAlphaF(1.0); + dark.setAlphaF(1.0); + } + + if(addLight) + { + painter->setPen(light); + painter->save(); + painter->setClipRect(r.adjusted(0, 0, -1, -1)); + painter->drawPath(buildPath(r.adjusted(1, 1, 0, 1), WIDGET_MDI_WINDOW_TITLE, ROUNDED_TOP, + roundROUND_SLIGHT /*&& kwin*/ + ? 5.0 + : 1.0)); + painter->restore(); + } + + painter->setPen(dark); + painter->drawPath(buildPath(r, WIDGET_MDI_WINDOW_TITLE, ROUNDED_TOP, + roundROUND_SLIGHT /*&& kwin*/ + ? 6.0 + : 2.0)); + + painter->setRenderHint(QPainter::Antialiasing, false); + + if(addLight) + { + painter->setPen(light); + painter->drawPoint(r.x()+1, r.y()+r.height()-1); + } + + if(round>ROUND_SLIGHT && FULLLY_ROUNDED) + { + if(!(state&QtC_StateKWinCompositing)) + { + painter->setPen(dark); + + painter->drawLine(r.x()+1, r.y()+4, r.x()+1, r.y()+3); + painter->drawPoint(r.x()+2, r.y()+2); + painter->drawLine(r.x()+3, r.y()+1, r.x()+4, r.y()+1); + painter->drawLine(r.x()+r.width()-2, r.y()+4, r.x()+r.width()-2, r.y()+3); + painter->drawPoint(r.x()+r.width()-3, r.y()+2); + painter->drawLine(r.x()+r.width()-4, r.y()+1, r.x()+r.width()-5, r.y()+1); + } + + if(addLight && + (APPEARANCE_SHINY_GLASS!=(active ? opts.titlebarAppearance : opts.inactiveTitlebarAppearance))) + { + painter->setPen(light); + painter->drawLine(r.x()+2, r.y()+4, r.x()+2, r.y()+3); + painter->drawLine(r.x()+3, r.y()+2, r.x()+4, r.y()+2); + painter->drawLine(r.x()+r.width()-4, r.y()+2, r.x()+r.width()-5, r.y()+2); + } + } + + if(opts.windowBorder&WINDOW_BORDER_BLEND_TITLEBAR && (!kwin || !(state&QtC_StateKWinNoBorder))) + { + static const int constFadeLen=8; + QPoint start(0, r.y()+r.height()-(1+constFadeLen)), + end(start.x(), start.y()+constFadeLen); + QLinearGradient grad(start, end); + + grad.setColorAt(0, dark); + grad.setColorAt(1, itsBackgroundCols[STD_BORDER]); + painter->setPen(QPen(QBrush(grad), 1)); + painter->drawLine(r.x(), start.y(), r.x(), end.y()); + painter->drawLine(r.x()+r.width()-1, start.y(), r.x()+r.width()-1, end.y()); + + if(addLight) + { + grad.setColorAt(0, light); + grad.setColorAt(1, itsBackgroundCols[0]); + painter->setPen(QPen(QBrush(grad), 1)); + painter->drawLine(r.x()+1, start.y(), r.x()+1, end.y()); + } + } + } + else + painter->setRenderHint(QPainter::Antialiasing, false); + + if(kwin) + { + painter->restore(); + break; + } + + int adjust(0); + QRect captionRect(subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget)); + + if(opts.titlebarButtons&TITLEBAR_BUTTON_SUNKEN_BACKGROUND && captionRect!=r) + { + bool menuIcon=TITLEBAR_ICON_MENU_BUTTON==opts.titlebarIcon, + menuLeft=menuRect.isValid() && !titleBar->icon.isNull() && menuRect.left()<(r.left()+constWindowMargin+4); + int height=r.height()-(1+(2*constWindowMargin)); + + adjust=1; + if(captionRect.left()>(r.left()+constWindowMargin)) + { + int width=captionRect.left()-(r.left()+(2*constWindowMargin)); + + if(!(menuIcon && menuLeft) || width>(height+4)) + drawSunkenBevel(painter, QRect(r.left()+constWindowMargin+1, r.top()+constWindowMargin+1, width, height), titleCols[ORIGINAL_SHADE]); + } + if(captionRect.right()<(r.right()-constWindowMargin)) + { + int width=r.right()-(captionRect.right()+(2*constWindowMargin)); + + if(!(menuIcon && !menuLeft) || width>(height+4)) + drawSunkenBevel(painter, QRect(captionRect.right()+constWindowMargin, r.top()+constWindowMargin+1, width, height), titleCols[ORIGINAL_SHADE]); + } + } + + bool showIcon=TITLEBAR_ICON_NEXT_TO_TITLE==opts.titlebarIcon && !titleBar->icon.isNull(); + int iconSize=showIcon ? pixelMetric(QStyle::PM_SmallIconSize) : 0, + iconX=r.x(); + QPixmap pixmap; + + if(showIcon) + pixmap=getIconPixmap(titleBar->icon, iconSize, titleBar->state); + + if(!titleBar->text.isEmpty()) + { + static const int constPad=4; + + Qt::Alignment alignment((Qt::Alignment)pixelMetric((QStyle::PixelMetric)QtC_TitleAlignment, 0L, 0L)); + bool alignFull(Qt::AlignHCenter==alignment), + iconRight((!reverse && alignment&Qt::AlignRight) || (reverse && alignment&Qt::AlignLeft)); + QRect textRect(alignFull + ? QRect(r.x(), captionRect.y(), r.width(), captionRect.height()) + : captionRect); + +#ifdef QTC_QT_ONLY + QFont font(painter->font()); + font.setBold(true); + painter->setFont(font); +#else + painter->setFont(KGlobalSettings::windowTitleFont()); +#endif + + QFontMetrics fm(painter->fontMetrics()); + QString str(fm.elidedText(titleBar->text, Qt::ElideRight, textRect.width(), QPalette::WindowText)); + + int textWidth=alignFull || (showIcon && alignment&Qt::AlignHCenter) + ? fm.boundingRect(str).width()+(showIcon ? iconSize+constPad : 0) : 0; + + if(alignFull && + ( (captionRect.left()>((textRect.width()-textWidth)>>1)) || + (captionRect.right()<((textRect.width()+textWidth)>>1)) ) ) + { + alignment=Qt::AlignVCenter|Qt::AlignRight; + textRect=captionRect; + } + + if(alignment&Qt::AlignLeft && constWindowMargin==textRect.x()) + textRect.adjust(showIcon ? 4 : 6, 0, 0, 0); + + if(showIcon) + { + if(alignment&Qt::AlignHCenter) + { + if(reverse) + { + iconX=((textRect.width()-textWidth)/2.0)+0.5+textWidth+iconSize; + textRect.setX(textRect.x()-(iconSize+constPad)); + } + else + { + iconX=((textRect.width()-textWidth)/2.0)+0.5; + textRect.setX(iconX+iconSize+constPad); + alignment=Qt::AlignVCenter|Qt::AlignLeft; + } + } + else if((!reverse && alignment&Qt::AlignLeft) || (reverse && alignment&Qt::AlignRight)) + { + iconX=textRect.x(); + textRect.setX(textRect.x()+(iconSize+constPad)); + } + else if((!reverse && alignment&Qt::AlignRight) || (reverse && alignment&Qt::AlignLeft)) + { + if(iconRight) + { + iconX=textRect.x()+textRect.width()-iconSize; + textRect.setWidth(textRect.width()-(iconSize+constPad)); + } + else + { + iconX=textRect.x()+textRect.width()-textWidth; + if(iconXsetPen(shadow); + painter->setPen(blendColors(WINDOW_SHADOW_COLOR(opts.titlebarEffect), titleCols[ORIGINAL_SHADE], + WINDOW_TEXT_SHADOW_ALPHA(opts.titlebarEffect))); + painter->drawText(EFFECT_SHADOW==opts.titlebarEffect + ? textRect.adjusted(1, 1, 1, 1) + : textRect.adjusted(0, 1, 0, 1), + str, textOpt); + + if (!active && DARK_WINDOW_TEXT(textColor)) + { + //textColor.setAlpha((textColor.alpha() * 180) >> 8); + textColor=blendColors(textColor, titleCols[ORIGINAL_SHADE], ((255 * 180) >> 8)/256.0); + } + } + painter->setPen(textColor); + painter->drawText(textRect, str, textOpt); + } + + if(showIcon && iconX>=0) + painter->drawPixmap(iconX, r.y()+((r.height()-iconSize)/2)+1, pixmap); + + if ((titleBar->subControls&SC_TitleBarMinButton) && (titleBar->titleBarFlags&Qt::WindowMinimizeButtonHint) && + !(titleBar->titleBarState&Qt::WindowMinimized)) + drawMdiControl(painter, titleBar, SC_TitleBarMinButton, widget, TITLEBAR_MIN, iconColor, btnCols, bgndCols, + adjust, active); + + if ((titleBar->subControls&SC_TitleBarMaxButton) && (titleBar->titleBarFlags&Qt::WindowMaximizeButtonHint) && + !(titleBar->titleBarState&Qt::WindowMaximized)) + drawMdiControl(painter, titleBar, SC_TitleBarMaxButton, widget, TITLEBAR_MAX, iconColor, btnCols, bgndCols, + adjust, active); + + if ((titleBar->subControls&SC_TitleBarCloseButton) && (titleBar->titleBarFlags&Qt::WindowSystemMenuHint)) + drawMdiControl(painter, titleBar, SC_TitleBarCloseButton, widget, TITLEBAR_CLOSE, iconColor, btnCols, bgndCols, + adjust, active); + + if ((titleBar->subControls&SC_TitleBarNormalButton) && + (((titleBar->titleBarFlags&Qt::WindowMinimizeButtonHint) && + (titleBar->titleBarState&Qt::WindowMinimized)) || + ((titleBar->titleBarFlags&Qt::WindowMaximizeButtonHint) && + (titleBar->titleBarState&Qt::WindowMaximized)))) + drawMdiControl(painter, titleBar, SC_TitleBarNormalButton, widget, TITLEBAR_MAX, iconColor, btnCols, bgndCols, + adjust, active); + + if (titleBar->subControls&SC_TitleBarContextHelpButton && (titleBar->titleBarFlags&Qt::WindowContextHelpButtonHint)) + drawMdiControl(painter, titleBar, SC_TitleBarContextHelpButton, widget, TITLEBAR_HELP, iconColor, btnCols, bgndCols, + adjust, active); + + if (titleBar->subControls&SC_TitleBarShadeButton && (titleBar->titleBarFlags&Qt::WindowShadeButtonHint)) + drawMdiControl(painter, titleBar, SC_TitleBarShadeButton, widget, TITLEBAR_SHADE, iconColor, btnCols, bgndCols, + adjust, active); + + if (titleBar->subControls&SC_TitleBarUnshadeButton && (titleBar->titleBarFlags&Qt::WindowShadeButtonHint)) + drawMdiControl(painter, titleBar, SC_TitleBarUnshadeButton, widget, TITLEBAR_SHADE, iconColor, btnCols, bgndCols, + adjust, active); + + if ((titleBar->subControls&SC_TitleBarSysMenu) && (titleBar->titleBarFlags&Qt::WindowSystemMenuHint)) + { + if(TITLEBAR_ICON_MENU_BUTTON==opts.titlebarIcon) + { + bool hover((titleBar->activeSubControls&SC_TitleBarSysMenu) && (titleBar->state&State_MouseOver)); + + if(active || hover || !(opts.titlebarButtons&TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW)) + { + if (menuRect.isValid()) + { + bool sunken((titleBar->activeSubControls&SC_TitleBarSysMenu) && (titleBar->state&State_Sunken)); + int offset(sunken ? 1 : 0); + +// if(!(opts.titlebarButtons&TITLEBAR_BUTTON_ROUND)) +// drawMdiButton(painter, menuRect, hover, sunken, +// coloredMdiButtons(state&State_Active, hover) +// ? itsTitleBarButtonsCols[TITLEBAR_MENU] : btnCols); + + if (!titleBar->icon.isNull()) + titleBar->icon.paint(painter, menuRect.adjusted(offset, offset, offset, offset)); + else + { + QStyleOption tool(0); + + tool.palette = palette; + tool.rect = menuRect; + painter->save(); + drawItemPixmap(painter, menuRect.adjusted(offset, offset, offset, offset), Qt::AlignCenter, + standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16)); + painter->restore(); + } + } + } + } + else + drawMdiControl(painter, titleBar, SC_TitleBarSysMenu, widget, TITLEBAR_MENU, iconColor, btnCols, bgndCols, + adjust, active); + + if(active && opts.windowBorder&WINDOW_BORDER_SEPARATOR) + { + QColor color(active ? itsActiveMdiTextColor : itsMdiTextColor); + Qt::Alignment align(pixelMetric((QStyle::PixelMetric)QtC_TitleAlignment, 0L, 0L)); + QRect lr(r.x(), captionRect.y(), r.width(), captionRect.height()); + + lr.adjust(16, lr.height()-2, -16, 0); + color.setAlphaF(0.5); + drawFadedLine(painter, lr, color, align&(Qt::AlignHCenter|Qt::AlignRight), + align&(Qt::AlignHCenter|Qt::AlignLeft), true); + } + } + + painter->restore(); + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast(option)) + { + bool useThreeButtonScrollBar(SCROLLBAR_KDE==opts.scrollbarType), + horiz(Qt::Horizontal==scrollbar->orientation), + maxed(scrollbar->minimum == scrollbar->maximum), + atMin(maxed || scrollbar->sliderValue==scrollbar->minimum), + atMax(maxed || scrollbar->sliderValue==scrollbar->maximum)/*, + inStack(0!=opts.tabBgnd && inStackWidget(widget))*/; + QRect subline(subControlRect(control, option, SC_ScrollBarSubLine, widget)), + addline(subControlRect(control, option, SC_ScrollBarAddLine, widget)), + subpage(subControlRect(control, option, SC_ScrollBarSubPage, widget)), + addpage(subControlRect(control, option, SC_ScrollBarAddPage, widget)), + slider(subControlRect(control, option, SC_ScrollBarSlider, widget)), + first(subControlRect(control, option, SC_ScrollBarFirst, widget)), + last(subControlRect(control, option, SC_ScrollBarLast, widget)), + subline2(addline), + sbRect(scrollbar->rect); + QStyleOptionSlider opt(*scrollbar); + + // For OO.o 3.2 need to fill widget background! + if(isOOWidget(widget)) + painter->fillRect(r, palette.brush(QPalette::Window)); + + if(reverse && horiz) + { + bool tmp(atMin); + + atMin=atMax; + atMax=tmp; + } + + if (useThreeButtonScrollBar) + { + int sbextent(pixelMetric(PM_ScrollBarExtent, scrollbar, widget)); + + if(horiz && reverse) + subline2=QRect((r.x()+r.width()-1)-sbextent, r.y(), sbextent, sbextent); + else if (horiz) + subline2.translate(-addline.width(), 0); + else + subline2.translate(0, -addline.height()); + + if (horiz) + subline.setWidth(sbextent); + else + subline.setHeight(sbextent); + } + + // Draw trough... + bool noButtons(ROUNDED && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)); + QRect s2(subpage), a2(addpage); + +#ifndef SIMPLE_SCROLLBARS + if(noButtons) + { + // Increase clipping to allow trough to "bleed" into slider corners... + a2.adjust(-3, -3, 3, 3); + s2.adjust(-3, -3, 3, 3); + } +#endif + + painter->save(); + + bool needsBaseBgnd=(opts.thinSbarGroove || opts.flatSbarButtons) && + widget && widget->parentWidget() && widget->parentWidget()->parentWidget() && + (widget->parentWidget()->parentWidget()->inherits("QComboBoxListView")/* || + !opts.gtkScrollViews && widget->parentWidget()->parentWidget()->inherits("QAbstractScrollArea")*/); + + if(needsBaseBgnd) + painter->fillRect(r, palette.brush(QPalette::Base)); + else if(opts.thinSbarGroove && APP_ARORA==theThemedApp && widget && widget->inherits("WebView")) + painter->fillRect(r, itsBackgroundCols[ORIGINAL_SHADE]); + + if(!opts.gtkScrollViews || + (opts.flatSbarButtons && !IS_FLAT(opts.sbarBgndAppearance)/* && SCROLLBAR_NONE!=opts.scrollbarType*/)) + drawBevelGradientReal(palette.brush(QPalette::Background).color(), painter, r, horiz, false, + opts.sbarBgndAppearance, WIDGET_SB_BGND); + + if(noButtons || opts.flatSbarButtons) + { + int mod=THIN_SBAR_MOD; + // Draw complete groove here, as we want to round both ends... + opt.rect=subpage.united(addpage); + opt.state=scrollbar->state; + opt.state&=~(State_MouseOver|State_Sunken|State_On); + + if(opts.thinSbarGroove && slider.isValid()) + { + painter->save(); + painter->setClipRegion(QRegion(opt.rect).subtract(slider.adjusted(1, 1, -1, -1))); + } + drawLightBevel(painter, opts.thinSbarGroove + ? horiz + ? opt.rect.adjusted(0, mod, 0, -mod) + : opt.rect.adjusted(mod, 0, -mod, 0) + : opt.rect, &opt, widget, + #ifndef SIMPLE_SCROLLBARS + !(opts.square&SQUARE_SB_SLIDER) && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons) + ? ROUNDED_ALL : + #endif + ROUNDED_NONE, + itsBackgroundCols[2], itsBackgroundCols, true, + opts.thinSbarGroove ? WIDGET_SLIDER_TROUGH : WIDGET_TROUGH); + if(opts.thinSbarGroove && slider.isValid()) + painter->restore(); + } + else + { + if((option->subControls&SC_ScrollBarSubPage) && subpage.isValid()) + { + opt.state=scrollbar->state; + opt.rect = subpage; +// if (!(scrollbar->activeSubControls&SC_ScrollBarSubPage)) + opt.state &= ~(State_Sunken|State_MouseOver|State_On); + drawControl(CE_ScrollBarSubPage, &opt, painter, widget); + } + + if((option->subControls&SC_ScrollBarAddPage) && addpage.isValid()) + { + opt.state=scrollbar->state; + opt.rect = addpage; +// if (!(scrollbar->activeSubControls&SC_ScrollBarAddPage)) + opt.state &= ~(State_Sunken|State_MouseOver|State_On); + drawControl(CE_ScrollBarAddPage, &opt, painter, widget); + } + } + + if((option->subControls&SC_ScrollBarSubLine) && subline.isValid()) + { + opt.rect=subline; + opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/; + if(maxed || atMin) + opt.state&=~State_Enabled; + if (!(scrollbar->activeSubControls&SC_ScrollBarSubLine) || + (useThreeButtonScrollBar && itsSbWidget && itsSbWidget==widget)) + opt.state &= ~(State_Sunken | State_MouseOver); + + drawControl(CE_ScrollBarSubLine, &opt, painter, widget); + + if (useThreeButtonScrollBar && subline2.isValid()) + { + opt.rect=subline2; + opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/; + if(maxed || atMin) + opt.state&=~State_Enabled; + if ((!(scrollbar->activeSubControls&SC_ScrollBarSubLine)) || (itsSbWidget && itsSbWidget!=widget)) + opt.state &= ~(State_Sunken | State_MouseOver); + + drawControl(CE_ScrollBarSubLine, &opt, painter, widget); + } + } + + if((option->subControls&SC_ScrollBarAddLine) && addline.isValid()) + { + opt.rect=addline; + opt.state=scrollbar->state/*|(inStack ? NO_BGND_BUTTON : State_None)*/; + if(maxed || atMax) + opt.state&=~State_Enabled; + if (!(scrollbar->activeSubControls&SC_ScrollBarAddLine)) + opt.state &= ~(State_Sunken | State_MouseOver); + drawControl(CE_ScrollBarAddLine, &opt, painter, widget); + } + + if((option->subControls&SC_ScrollBarFirst) && first.isValid()) + { + opt.rect=first; + opt.state=scrollbar->state; + if (!(scrollbar->activeSubControls&SC_ScrollBarFirst)) + opt.state &= ~(State_Sunken | State_MouseOver); + drawControl(CE_ScrollBarFirst, &opt, painter, widget); + } + + if((option->subControls&SC_ScrollBarLast) && last.isValid()) + { + opt.rect=last; + opt.state=scrollbar->state; + if (!(scrollbar->activeSubControls&SC_ScrollBarLast)) + opt.state &= ~(State_Sunken | State_MouseOver); + drawControl(CE_ScrollBarLast, &opt, painter, widget); + } + + if(((option->subControls&SC_ScrollBarSlider) || noButtons) && slider.isValid()) + { + // If "SC_ScrollBarSlider" wasn't specified, then we only want to draw the portion + // of the slider that overlaps with the trough. So, once again set the clipping + // region... + + // NO! Seeems to mess things up with Arora, su just dsiable all clipping when drawing + // the slider... + painter->setClipping(false); +#ifdef INCREASE_SB_SLIDER + if(!opts.flatSbarButtons) + { + if(atMax) + switch(opts.scrollbarType) + { + case SCROLLBAR_KDE: + case SCROLLBAR_WINDOWS: + case SCROLLBAR_PLATINUM: + if(horiz) + slider.adjust(0, 0, 1, 0); + else + slider.adjust(0, 0, 0, 1); + default: + break; + } + if(atMin) + switch(opts.scrollbarType) + { + case SCROLLBAR_KDE: + case SCROLLBAR_WINDOWS: + case SCROLLBAR_NEXT: + if(horiz) + slider.adjust(-1, 0, 0, 0); + else + slider.adjust(0, -1, 0, 0); + default: + break; + } + } +#endif + opt.rect=slider; + opt.state=scrollbar->state; + if (!(scrollbar->activeSubControls&SC_ScrollBarSlider)) + opt.state &= ~(State_Sunken | State_MouseOver); + drawControl(CE_ScrollBarSlider, &opt, painter, widget); + + // ### perhaps this should not be able to accept focus if maxedOut? + if(state&State_HasFocus) + { + opt.state=scrollbar->state; + opt.rect=QRect(slider.x()+2, slider.y()+2, slider.width()-5, slider.height()-5); + drawPrimitive(PE_FrameFocusRect, &opt, painter, widget); + } + } + painter->restore(); + } + break; + case CC_ComboBox: + if (const QStyleOptionComboBox *comboBox = qstyleoption_cast(option)) + { + painter->save(); + + QRect frame(subControlRect(CC_ComboBox, option, SC_ComboBoxFrame, widget)), + arrow(subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget)), + field(subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget)); + const QColor *use(buttonColors(option)); + bool sunken(state&State_On), // comboBox->listBox() ? comboBox->listBox()->isShown() : false), + glowOverFocus(state&State_MouseOver && FULL_FOCUS && + MO_GLOW==opts.coloredMouseOver && DO_EFFECT && !sunken && !comboBox->editable && + state&State_Enabled && state&State_HasFocus), + doEffect(DO_EFFECT && (!comboBox->editable || opts.etchEntry)), + isOO(isOOWidget(widget)), + isOO31(isOO); + + if(isOO) + { + // This (hopefull) checks is we're OO.o 3.2 - in which case no adjustment is required... + const QImage *img=getImage(painter); + + isOO31=!img || img->rect()!=r; + + if(isOO31) + frame.adjust(0, 0, 0, -2), arrow.adjust(0, 0, 0, -2), field.adjust(0, 0, 0, -2); + else + arrow.adjust(1, 0, 0, 0); + } + +// painter->fillRect(r, Qt::transparent); + if(doEffect) + { + bool glowFocus(state&State_HasFocus && state&State_Enabled && USE_GLOW_FOCUS(state&State_MouseOver)); + + if(!glowOverFocus && !(opts.thin&THIN_FRAMES) && !sunken && MO_GLOW==opts.coloredMouseOver && + (((FULL_FOCUS || glowFocus) && state&State_HasFocus) || state&State_MouseOver) && + state&State_Enabled && !comboBox->editable) + drawGlow(painter, r, FULL_FOCUS && state&State_HasFocus ? WIDGET_DEF_BUTTON : WIDGET_COMBO, + glowFocus ? itsFocusCols : 0L); + else + drawEtch(painter, r, widget, WIDGET_COMBO, + !comboBox->editable && EFFECT_SHADOW==opts.buttonEffect && !sunken, + comboBox->editable && opts.square&SQUARE_ENTRY + ? opts.unifyCombo + ? ROUNDED_NONE + : reverse + ? ROUNDED_LEFT + : ROUNDED_RIGHT + : ROUNDED_ALL); + + frame.adjust(1, 1, -1, -1); + } + + if(/*comboBox->frame &&*/ frame.isValid() && (!comboBox->editable || !opts.unifyCombo)) + { + const QColor *cols=itsComboBtnCols && comboBox->editable && state&State_Enabled ? itsComboBtnCols : use; + + QStyleOption frameOpt(*option); + + if (comboBox->editable && !(comboBox->activeSubControls&SC_ComboBoxArrow)) + frameOpt.state &= ~(State_Sunken | State_MouseOver); + + if(!sunken) + frameOpt.state|=State_Raised; + + //if(opts.coloredMouseOver && frameOpt.state&State_MouseOver && comboBox->editable && !sunken) + // frame.adjust(reverse ? 0 : 1, 0, reverse ? 1 : 0, 0); + + drawLightBevel(painter, frame, &frameOpt, widget, + comboBox->editable ? (reverse ? ROUNDED_LEFT : ROUNDED_RIGHT) : ROUNDED_ALL, + getFill(&frameOpt, cols, false, + (SHADE_DARKEN==opts.comboBtn || (SHADE_NONE!=opts.comboBtn && + !(state&State_Enabled))) && + comboBox->editable), + cols, true, comboBox->editable ? WIDGET_COMBO_BUTTON : WIDGET_COMBO); + } + + if(/*controls&SC_ComboBoxEditField &&*/ field.isValid()) + { + if(comboBox->editable) + { + if(opts.unifyCombo) + { + field=r; + if(doEffect) + field.adjust(1, 1, -1, -1); + if(isOO31) + field.adjust(0, 0, 0, -2); + } + else if(doEffect) + field.adjust(reverse ? -4 : -3, -1, reverse ? 3 : 4, 1); + else + field.adjust(reverse ? -4 : -2, -1, reverse ? 2 : 4, 1); + drawEntryField(painter, field, widget, option, opts.unifyCombo ? ROUNDED_ALL : reverse ? ROUNDED_RIGHT : ROUNDED_LEFT, + true, false); + } + else if(opts.comboSplitter && !(SHADE_DARKEN==opts.comboBtn || itsComboBtnCols)) + { + drawFadedLine(painter, QRect(reverse ? arrow.right()+1 : arrow.x()-1, arrow.top()+2, + 1, arrow.height()-4), + use[BORDER_VAL(state&State_Enabled)], true, true, false); + if(!sunken) + drawFadedLine(painter, QRect(reverse ? arrow.right()+2 : arrow.x(), arrow.top()+2, + 1, arrow.height()-4), + use[0], true, true, false); + } + } + + if(/*controls&SC_ComboBoxArrow && */arrow.isValid()) + { + bool mouseOver=comboBox->editable && !(comboBox->activeSubControls&SC_ComboBoxArrow) + ? false : (state&State_MouseOver ? true : false); + + if(!comboBox->editable && (SHADE_DARKEN==opts.comboBtn || itsComboBtnCols)) + { + if(!comboBox->editable && isOO && !isOO31) + arrow.adjust(reverse ? 0 : 1, 0, reverse ? -1 : 0, 0); + + QStyleOption frameOpt(*option); + QRect btn(arrow.x(), frame.y(), arrow.width()+1, frame.height()); + const QColor *cols=SHADE_DARKEN==opts.comboBtn || !(state&State_Enabled) ? use : itsComboBtnCols; + if(!sunken) + frameOpt.state|=State_Raised; + painter->save(); + painter->setClipRect(btn, Qt::IntersectClip); + drawLightBevel(painter, opts.comboSplitter + ? btn.adjusted(reverse ? -2 : 0, 0, reverse ? 2 : 1, 0) + : btn.adjusted(reverse ? -3 : -2, 0, reverse ? 2 : 1, 0), + &frameOpt, widget, reverse ? ROUNDED_LEFT : ROUNDED_RIGHT, + getFill(&frameOpt, cols, false, + SHADE_DARKEN==opts.comboBtn || (SHADE_NONE!=opts.comboBtn && + !(state&State_Enabled))), + cols, true, WIDGET_COMBO); + painter->restore(); + } + + if(sunken && (!comboBox->editable || !opts.unifyCombo)) + arrow.adjust(1, 1, 1, 1); + + QColor arrowColor(MO_ARROW_X(mouseOver, QPalette::ButtonText)); + if(comboBox->editable || !(opts.gtkComboMenus && opts.doubleGtkComboArrow)) + drawArrow(painter, arrow, PE_IndicatorArrowDown, arrowColor, false); + else + { + int middle=arrow.y()+(arrow.height()>>1), + gap=(opts.vArrows ? 2 : 1); + + QRect ar=QRect(arrow.x(), middle-(LARGE_ARR_HEIGHT+gap), arrow.width(), LARGE_ARR_HEIGHT); + drawArrow(painter, ar, PE_IndicatorArrowUp, arrowColor, false); + ar=QRect(arrow.x(), middle+gap, arrow.width(), LARGE_ARR_HEIGHT); + drawArrow(painter, ar, PE_IndicatorArrowDown, arrowColor, false); + } + } + + if(state&State_Enabled && state&State_HasFocus && + /*state&State_KeyboardFocusChange &&*/ !comboBox->editable && FOCUS_GLOW!=opts.focus) + { + QStyleOptionFocusRect focus; + bool listViewCombo=comboBox->frame && widget && widget->rect().height()<(DO_EFFECT ? 22 : 20); + + if(FULL_FOCUS) + focus.rect=frame; + else if(opts.comboSplitter) + { + focus.rect=reverse + ? field.adjusted(0, -1, 1, 1) + : field.adjusted(-1, -1, 0, 1); + + if(listViewCombo) + focus.rect.adjust(0, -2, 0, 2); + } + else if(listViewCombo) + focus.rect=frame.adjusted(1, 1, -1, -1); + else + focus.rect=frame.adjusted(3, 3, -3, -3); + + // Draw glow over top of filled focus + if(glowOverFocus && !(opts.thin&THIN_FRAMES)) + drawGlow(painter, frame.adjusted(-1, -1, 1, 1), WIDGET_COMBO); + else + drawPrimitive(PE_FrameFocusRect, &focus, painter, widget); + } + painter->restore(); + } + break; + default: + BASE_STYLE::drawComplexControl(control, option, painter, widget); + break; + } +} + +// Use 'drawItemTextWithRole' when already know which role to use. +void Style::drawItemTextWithRole(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, + const QString &text, QPalette::ColorRole textRole) const +{ + BASE_STYLE::drawItemText(painter, rect, flags, pal, enabled, text, textRole); +} + +void Style::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, + QPalette::ColorRole textRole) const +{ + if(QPalette::ButtonText==textRole && !opts.stdSidebarButtons) + { + const QAbstractButton *button=getButton(NULL, painter); + + if(button && isMultiTabBarTab(button) && button->isChecked()) + { + QPalette p(pal); + + if(itsInactiveChangeSelectionColor && QPalette::Inactive==p.currentColorGroup()) + p.setCurrentColorGroup(QPalette::Active); + BASE_STYLE::drawItemText(painter, rect, flags, p, enabled, text, QPalette::HighlightedText); + return; + } + } + + BASE_STYLE::drawItemText(painter, rect, flags, pal, enabled, text, textRole); +} + +QSize Style::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const +{ + QSize newSize(BASE_STYLE::sizeFromContents(type, option, size, widget)); + + switch (type) + { + case CT_TabBarTab: + newSize+=QSize(1, 1); + break; + case CT_Splitter: + { + int sw=pixelMetric(PM_SplitterWidth, 0L, 0L); + return QSize(sw, sw); + } + case CT_PushButton: + { + newSize=size; + newSize.setWidth(newSize.width()+(ROUND_MAX==opts.round ? 12 : 8)); + + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) + { + if(!opts.stdBtnSizes) + { + bool dialogButton= + // Cant rely on AutoDefaultButton - as VirtualBox does not set this!!! + // btn->features&QStyleOptionButton::AutoDefaultButton && + widget && widget->parentWidget() && + (::qobject_cast(widget->parentWidget()) || widget->parentWidget()->inherits("KFileWidget")); + + if(dialogButton) + { + int iconHeight=btn->icon.isNull() ? btn->iconSize.height() : 16; + if(size.height()features&QStyleOptionButton::HasMenu) + newSize+=QSize(4, 0); + + if (!btn->text.isEmpty() && "..."!=btn->text && newSize.width() < 80) + newSize.setWidth(80); + + newSize.rheight() += ((1 - newSize.rheight()) & 1); + } + break; + } +// case CT_RadioButton: +// ++newSize.rheight(); +// ++newSize.rwidth(); +// break; + case CT_RadioButton: + case CT_CheckBox: + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) + { + bool isRadio = CT_RadioButton==type; + int w = /*proxy()->*/pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth : PM_IndicatorWidth, btn, widget), + h = /*proxy()->*/pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight : PM_IndicatorHeight, btn, widget), + margins = 0; + + newSize=size; + // we add 4 pixels for label margins + if (btn->icon.isNull() || !btn->text.isEmpty()) + margins = 0+/*proxy()->*/pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, option, widget)+ + (opts.crHighlight ? 4 : 0); + + newSize += QSize(w + margins, 4); + newSize.setHeight(qMax(newSize.height(), h)); + } + break; + case CT_ScrollBar: + if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) + { + int scrollBarExtent(pixelMetric(PM_ScrollBarExtent, option, widget)), + scrollBarSliderMinimum(pixelMetric(PM_ScrollBarSliderMin, option, widget)); + + if (scrollBar->orientation == Qt::Horizontal) + newSize = QSize(scrollBarExtent * numButtons(opts.scrollbarType) + scrollBarSliderMinimum, scrollBarExtent); + else + newSize = QSize(scrollBarExtent, scrollBarExtent * numButtons(opts.scrollbarType) + scrollBarSliderMinimum); + } + break; + case CT_LineEdit: + if (const QStyleOptionFrame *f = qstyleoption_cast(option)) + newSize = size+QSize(2*f->lineWidth, 2*f->lineWidth); + break; + case CT_SpinBox: + if(!opts.unifySpin) + newSize.rheight() -= ((1 - newSize.rheight()) & 1); + break; + case CT_ToolButton: + { + newSize = QSize(size.width()+8, size.height()+8); + // -- from kstyle & oxygen -- + // We want to avoid super-skiny buttons, for things like "up" when icons + text + // For this, we would like to make width >= height. + // However, once we get here, QToolButton may have already put in the menu area + // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things + // up, and add it back in. So much for class-independent rendering... + int menuAreaWidth(0); + + if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast(option)) + { + // Make Kate/KWrite's option toolbuton have the same size as the next/prev buttons... + if(widget && !getToolBar(widget) && !tbOpt->text.isEmpty() && + tbOpt->features&QStyleOptionToolButton::MenuButtonPopup) + { + QStyleOptionButton btn; + + btn.init(widget); + btn.text=tbOpt->text; + btn.icon=tbOpt->icon; + btn.iconSize=tbOpt->iconSize; + btn.features=tbOpt->features&QStyleOptionToolButton::MenuButtonPopup + ? QStyleOptionButton::HasMenu : QStyleOptionButton::None; + return sizeFromContents(CT_PushButton, &btn, size, widget); + } + + if (!tbOpt->icon.isNull() && !tbOpt->text.isEmpty() && Qt::ToolButtonTextUnderIcon==tbOpt->toolButtonStyle) + newSize.setHeight(newSize.height()-4); + + if (tbOpt->features & QStyleOptionToolButton::MenuButtonPopup) + menuAreaWidth = pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget); + else if (tbOpt->features & QStyleOptionToolButton::HasMenu) + switch(tbOpt->toolButtonStyle) + { + case Qt::ToolButtonIconOnly: + newSize.setWidth(newSize.width()+LARGE_ARR_WIDTH+2); + break; + case Qt::ToolButtonTextBesideIcon: + newSize.setWidth(newSize.width()+3); + break; + case Qt::ToolButtonTextOnly: + newSize.setWidth(newSize.width()+8); + break; + case Qt::ToolButtonTextUnderIcon: + newSize.setWidth(newSize.width()+8); + break; + default: + break; + } + } + + newSize.setWidth(newSize.width() - menuAreaWidth); + if (newSize.width() < newSize.height()) + newSize.setWidth(newSize.height()); + newSize.setWidth(newSize.width() + menuAreaWidth); + + break; + } + case CT_ComboBox: + { + newSize=size; + newSize.setWidth(newSize.width()+4); + + const QStyleOptionComboBox *combo = qstyleoption_cast(option); + + int margin = (pixelMetric(PM_ButtonMargin, option, widget)+ + (pixelMetric(PM_DefaultFrameWidth, option, widget) * 2))-MAX_ROUND_BTN_PAD, + textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1), + // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... + other = qMax(DO_EFFECT ? 20 : 18, 2*textMargins + pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)); + bool editable=combo ? combo->editable : false; + newSize+=QSize(margin+other, margin-2); + newSize.rheight() += ((1 - newSize.rheight()) & 1); + + if(!opts.etchEntry && DO_EFFECT && editable) + newSize.rheight()-=2; + // KWord's zoom combo clips 'Fit Page Width' without the following... + if(editable) + newSize.rwidth()+=6; + break; + } + case CT_MenuItem: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast(option)) + { + // Taken from QWindowStyle... + int w = size.width(); + + if (QStyleOptionMenuItem::Separator==mi->menuItemType) + newSize = QSize(10, windowsSepHeight); + else if (mi->icon.isNull()) + { + newSize.setHeight(newSize.height() - 2); + w -= 6; + } + + if (QStyleOptionMenuItem::Separator!=mi->menuItemType && !mi->icon.isNull()) + { + int iconExtent = pixelMetric(PM_SmallIconSize, option, widget); + newSize.setHeight(qMax(newSize.height(), + mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + + 2 * windowsItemFrame)); + } + int maxpmw = mi->maxIconWidth, + tabSpacing = 20; + + if (mi->text.contains(QLatin1Char('\t'))) + w += tabSpacing; + else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) + w += 2 * windowsArrowHMargin; + else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) + { + // adjust the font and add the difference in size. + // it would be better if the font could be adjusted in the initStyleOption qmenu func!! + QFontMetrics fm(mi->font); + QFont fontBold = mi->font; + fontBold.setBold(true); + QFontMetrics fmBold(fontBold); + w += fmBold.width(mi->text) - fm.width(mi->text); + } + + int checkcol = qMax(maxpmw, windowsCheckMarkWidth); // Windows always shows a check column + w += checkcol + windowsRightBorder + 10; + newSize.setWidth(w); + // .... + + int h(newSize.height()-8); // Fix mainly for Qt4.4 + + if (QStyleOptionMenuItem::Separator==mi->menuItemType && mi->text.isEmpty()) + h = 7; + else + { + h = qMax(h, mi->fontMetrics.height()); + if (!mi->icon.isNull()) + h = qMax(h, mi->icon.pixmap(pixelMetric(PM_SmallIconSize), QIcon::Normal).height()); + + if (h < 18) + h = 18; + h+=((opts.thin&THIN_MENU_ITEMS) ? 2 : 4); + + if(QStyleOptionMenuItem::Separator==mi->menuItemType) + h+=4; + } + + newSize.setHeight(h); + // Gtk2's icon->text spacing is 2 pixels smaller - so adjust here... + newSize.setWidth(newSize.width()-2); + } + break; + case CT_MenuBarItem: +#if QT_VERSION >= 0x040500 + if (!size.isEmpty()) + newSize=size+QSize((windowsItemHMargin * 4)+2, windowsItemVMargin+1); +#else + if (!size.isEmpty()) + newSize=size+QSize((windowsItemHMargin * 4)+2, windowsItemVMargin); +#endif + break; + case CT_MenuBar: + if(APP_KONQUEROR==theThemedApp && widget && qobject_cast(widget)) + { + int height=konqMenuBarSize((const QMenuBar *)widget); + if(!opts.xbar || (size.height()>height)) + newSize.setHeight(height); + } + break; + default: + break; + } + + return newSize; +} + +QRect Style::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const +{ + QRect rect; + switch (element) + { + case SE_SliderFocusRect: + case SE_ToolBoxTabContents: + return visualRect(option->direction, option->rect, option->rect); + case SE_DockWidgetTitleBarText: + { + const QStyleOptionDockWidgetV2 *v2= qstyleoption_cast(option); + bool verticalTitleBar = v2 ? v2->verticalTitleBar : false; + int m = pixelMetric(PM_DockWidgetTitleMargin, option, widget); + + rect = BASE_STYLE::subElementRect(element, option, widget); + + if (verticalTitleBar) + rect.adjust(0, 0, 0, -m); + else if (Qt::LeftToRight==option->direction ) + rect.adjust(m, 0, 0, 0); + else + rect.adjust(0, 0, -m, 0); + return rect; + } +#if QT_VERSION >= 0x040500 + case SE_TabBarTabLeftButton: + return BASE_STYLE::subElementRect(element, option, widget).translated(-2, -1); + case SE_TabBarTabRightButton: + return BASE_STYLE::subElementRect(element, option, widget).translated(2, -1); + case SE_TabBarTabText: + if (const QStyleOptionTab *tab = qstyleoption_cast(option)) + { + QStyleOptionTabV3 tabV2(*tab); + bool verticalTabs=QTabBar::RoundedEast==tabV2.shape || QTabBar::RoundedWest==tabV2.shape || + QTabBar::TriangularEast==tabV2.shape || QTabBar::TriangularWest==tabV2.shape; + + rect=tabV2.rect; + if (verticalTabs) + rect.setRect(0, 0, rect.height(), rect.width()); + int verticalShift = pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget), + horizontalShift = pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget); + if (tabV2.shape == QTabBar::RoundedSouth || tabV2.shape == QTabBar::TriangularSouth) + verticalShift = -verticalShift; + rect.adjust(0, 0, horizontalShift, verticalShift); + bool selected = tabV2.state & State_Selected; + if (selected) + { + rect.setBottom(rect.bottom() - verticalShift); + rect.setRight(rect.right() - horizontalShift); + } + + // left widget + if(opts.centerTabText) + { + if (!tabV2.leftButtonSize.isEmpty()) // left widget + rect.setLeft(rect.left() + constTabPad + + (verticalTabs ? tabV2.leftButtonSize.height() : tabV2.leftButtonSize.width())); + if (!tabV2.rightButtonSize.isEmpty()) // right widget + rect.setRight(rect.right() - constTabPad - + (verticalTabs ? tabV2.rightButtonSize.height() : tabV2.rightButtonSize.width())); + } + else + { + if (tabV2.leftButtonSize.isNull()) + rect.setLeft(rect.left()+constTabPad); + else if(tabV2.leftButtonSize.width()>0) + rect.setLeft(rect.left() + constTabPad + 2 + + (verticalTabs ? tabV2.leftButtonSize.height() : tabV2.leftButtonSize.width())); + else if(tabV2.icon.isNull()) + rect.setLeft(rect.left()+constTabPad); + else + rect.setLeft(rect.left() + 2); + } + + // icon + if (!tabV2.icon.isNull()) + { + QSize iconSize = tabV2.iconSize; + if (!iconSize.isValid()) + { + int iconExtent = pixelMetric(PM_SmallIconSize); + iconSize = QSize(iconExtent, iconExtent); + } + QSize tabIconSize = tabV2.icon.actualSize(iconSize, + (tabV2.state & State_Enabled) ? QIcon::Normal + : QIcon::Disabled); + int offset = 4; + + if (!opts.centerTabText && tabV2.leftButtonSize.isNull()) + offset += 2; + + QRect iconRect = QRect(rect.left() + offset, rect.center().y() - tabIconSize.height() / 2, + tabIconSize.width(), tabIconSize .height()); + if (!verticalTabs) + iconRect = visualRect(option->direction, option->rect, iconRect); + rect.setLeft(rect.left() + tabIconSize.width() + offset + 2); + } + + // right widget + if (!opts.centerTabText && !tabV2.rightButtonSize.isNull() && tabV2.rightButtonSize.width()>0) + rect.setRight(rect.right() - constTabPad - 2 - + (verticalTabs ? tabV2.rightButtonSize.height() : tabV2.rightButtonSize.width())); + else + rect.setRight(rect.right() - constTabPad); + + + if (!verticalTabs) + rect = visualRect(option->direction, option->rect, rect); + return rect; + } + break; +#endif + case SE_RadioButtonIndicator: + rect = visualRect(option->direction, option->rect, + BASE_STYLE::subElementRect(element, option, widget)).adjusted(0, 0, 1, 1); + break; + case SE_ProgressBarContents: + return opts.fillProgress + ? DO_EFFECT && opts.borderProgress + ? option->rect.adjusted(1, 1, -1, -1) + : option->rect + : DO_EFFECT && opts.borderProgress + ? option->rect.adjusted(3, 3, -3, -3) + : option->rect.adjusted(2, 2, -2, -2); + case SE_ProgressBarGroove: + case SE_ProgressBarLabel: + return option->rect; +#if QT_VERSION >= 0x040300 + case SE_GroupBoxLayoutItem: + rect = option->rect; +// if (const QStyleOptionGroupBox *groupBoxOpt = qstyleoption_cast(option)) +// if (groupBoxOpt->subControls & (SC_GroupBoxCheckBox | SC_GroupBoxLabel)) +// rect.setTop(rect.top() + 2); // eat the top margin a little bit + break; +#endif + case SE_PushButtonFocusRect: + if(FULL_FOCUS) + { + rect=subElementRect(SE_PushButtonContents, option, widget); + if(DO_EFFECT) + rect.adjust(-1, -1, 1, 1); + else + rect.adjust(-2, -2, 2, 2); + } + else + { + rect=BASE_STYLE::subElementRect(element, option, widget); + if(DO_EFFECT) + rect.adjust(1, 1, -1, -1); + } + return rect; + default: + return BASE_STYLE::subElementRect(element, option, widget); + } + + return visualRect(option->direction, option->rect, rect); +} + +QRect Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const +{ + QRect r(option->rect); + bool reverse(Qt::RightToLeft==option->direction); + + switch (control) + { + case CC_ComboBox: + if (const QStyleOptionComboBox *comboBox = qstyleoption_cast(option)) + { + bool ed(comboBox->editable), + doEtch((!ed || opts.etchEntry) && DO_EFFECT); + int x(r.x()), + y(r.y()), + w(r.width()), + h(r.height()); + + switch (subControl) + { + case SC_ComboBoxFrame: + if(ed) + { + int btnWidth(doEtch ? 22 : 20); + + r=QRect(x+w-btnWidth, y, btnWidth, h); + } + break; + case SC_ComboBoxArrow: + { + int bmarg(comboBox->frame ? 2 : 0); + + r.setRect(x + w - bmarg - (doEtch ? 17 : 16), y + bmarg, 16, h - 2*bmarg); + if(ed && opts.unifyCombo) + r.adjust(-1, 0, 0, 0); + break; + } + case SC_ComboBoxEditField: + { + int margin(comboBox->frame ? 3 : 0); + + r.setRect(x + margin+(opts.unifyCombo ? 0 : 2), y + margin, + w - 2 * margin - (opts.unifyCombo ? 15 : 23), h - 2 * margin); + if(doEtch) + r.adjust(ed ? 0 : 1, 1, ed ? 0 : -1, -1); + if(ed) + r.adjust(-1, -2, 1, 2); + break; + } + case SC_ComboBoxListBoxPopup: + default: + break; + } + return visualRect(comboBox->direction, comboBox->rect, r); + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast(option)) + { + int fw(spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0); + QSize bs; + + bs.setHeight(r.height()>>1); + if(bs.height()< 8) + bs.setHeight(8); + bs.setWidth(DO_EFFECT && opts.etchEntry ? 16 : 15); + bs=bs.expandedTo(QApplication::globalStrut()); + + int y(0), x(reverse ? 0 : r.width()-bs.width()); + + switch(subControl) + { + case SC_SpinBoxUp: + return QAbstractSpinBox::NoButtons==spinbox->buttonSymbols + ? QRect() + : QRect(x, y, bs.width(), bs.height()); + case SC_SpinBoxDown: + if(QAbstractSpinBox::NoButtons==spinbox->buttonSymbols) + return QRect(); + else + return QRect(x, y+bs.height(), bs.width(), bs.height()+(bs.height()*2==r.height() ? 0 : 1)); + case SC_SpinBoxEditField: + { + int pad=opts.round>ROUND_FULL ? 2 : 0; + + if (QAbstractSpinBox::NoButtons==spinbox->buttonSymbols) + return QRect(fw, fw, (x-fw*2)-pad, r.height()-2*fw); + else + return QRect(fw+(reverse ? bs.width() : 0), fw, (x-fw*2)-pad, r.height()-2*fw); + } + case SC_SpinBoxFrame: + default: + return visualRect(spinbox->direction, spinbox->rect, spinbox->rect); + } + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) + { + // Taken from kstyle.cpp (KDE 3) , and modified so as to allow for no scrollbar butttons... + bool threeButtonScrollBar(SCROLLBAR_KDE==opts.scrollbarType), + platinumScrollBar(SCROLLBAR_PLATINUM==opts.scrollbarType), + nextScrollBar(SCROLLBAR_NEXT==opts.scrollbarType), + noButtons(SCROLLBAR_NONE==opts.scrollbarType); + QRect ret; + bool horizontal(Qt::Horizontal==scrollBar->orientation); + int sbextent(pixelMetric(PM_ScrollBarExtent, scrollBar, widget)), + sliderMaxLength(((scrollBar->orientation == Qt::Horizontal) ? + scrollBar->rect.width() : scrollBar->rect.height()) - (sbextent * numButtons(opts.scrollbarType))), + sliderMinLength(pixelMetric(PM_ScrollBarSliderMin, scrollBar, widget)), + sliderLength; + + if (scrollBar->maximum != scrollBar->minimum) + { + uint valueRange = scrollBar->maximum - scrollBar->minimum; + sliderLength = (scrollBar->pageStep * sliderMaxLength) / (valueRange + scrollBar->pageStep); + + if (sliderLength < sliderMinLength || (!isOOWidget(widget) && valueRange > INT_MAX / 2)) + sliderLength = sliderMinLength; + if (sliderLength > sliderMaxLength) + sliderLength = sliderMaxLength; + } + else + sliderLength = sliderMaxLength; + + int sliderstart(sliderPositionFromValue(scrollBar->minimum, + scrollBar->maximum, + scrollBar->sliderPosition, + sliderMaxLength - sliderLength, + scrollBar->upsideDown)); + + switch(opts.scrollbarType) + { + case SCROLLBAR_KDE: + case SCROLLBAR_WINDOWS: + sliderstart+=sbextent; + break; + case SCROLLBAR_NEXT: + sliderstart+=sbextent*2; + default: + break; + } + + // Subcontrols + switch(subControl) + { + case SC_ScrollBarSubLine: + if(noButtons) + return QRect(); + + // top/left button + if (platinumScrollBar) + if (horizontal) + ret.setRect(scrollBar->rect.width() - 2 * sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, scrollBar->rect.height() - 2 * sbextent, sbextent, sbextent); + else if(threeButtonScrollBar) + if (horizontal) + ret.setRect(0, 0, scrollBar->rect.width() - sbextent +1, sbextent); + else + ret.setRect(0, 0, sbextent, scrollBar->rect.height() - sbextent +1); + else + ret.setRect(0, 0, sbextent, sbextent); + break; + case SB_SUB2: + if(threeButtonScrollBar) + if (horizontal) + if(reverse) + ret.setRect(sbextent, 0, sbextent, sbextent); + else + ret.setRect(scrollBar->rect.width() - 2 * sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, scrollBar->rect.height() - 2 * sbextent, sbextent, sbextent); + else + return QRect(); + break; + case SC_ScrollBarAddLine: + if(noButtons) + return QRect(); + + // bottom/right button + if (nextScrollBar) + if (horizontal) + ret.setRect(sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, sbextent, sbextent, sbextent); + else + if (horizontal) + ret.setRect(scrollBar->rect.width() - sbextent, 0, sbextent, sbextent); + else + ret.setRect(0, scrollBar->rect.height() - sbextent, sbextent, sbextent); + break; + case SC_ScrollBarSubPage: + // between top/left button and slider + if (platinumScrollBar) + if (horizontal) + ret.setRect(0, 0, sliderstart, sbextent); + else + ret.setRect(0, 0, sbextent, sliderstart); + else if (nextScrollBar) + if (horizontal) + ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent); + else + ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent); + else + if (horizontal) + ret.setRect(noButtons ? 0 : sbextent, 0, + noButtons ? sliderstart + : (sliderstart - sbextent), sbextent); + else + ret.setRect(0, noButtons ? 0 : sbextent, sbextent, + noButtons ? sliderstart : (sliderstart - sbextent)); + break; + case SC_ScrollBarAddPage: + { + // between bottom/right button and slider + int fudge; + + if (platinumScrollBar) + fudge = 0; + else if (nextScrollBar) + fudge = 2*sbextent; + else if(noButtons) + fudge = 0; + else + fudge = sbextent; + + if (horizontal) + ret.setRect(sliderstart + sliderLength, 0, + sliderMaxLength - sliderstart - sliderLength + fudge, sbextent); + else + ret.setRect(0, sliderstart + sliderLength, sbextent, + sliderMaxLength - sliderstart - sliderLength + fudge); + break; + } + case SC_ScrollBarGroove: + if(noButtons) + { + if (horizontal) + ret=QRect(0, 0, scrollBar->rect.width(), scrollBar->rect.height()); + else + ret=QRect(0, 0, scrollBar->rect.width(), scrollBar->rect.height()); + } + else + { + int multi = threeButtonScrollBar ? 3 : 2, + fudge; + + if (platinumScrollBar) + fudge = 0; + else if (nextScrollBar) + fudge = 2*sbextent; + else + fudge = sbextent; + + if (horizontal) + ret=QRect(fudge, 0, scrollBar->rect.width() - sbextent * multi, scrollBar->rect.height()); + else + ret=QRect(0, fudge, scrollBar->rect.width(), scrollBar->rect.height() - sbextent * multi); + } + break; + case SC_ScrollBarSlider: + if (horizontal) + ret=QRect(sliderstart, 0, sliderLength, sbextent); + else + ret=QRect(0, sliderstart, sbextent, sliderLength); + break; + default: + ret = BASE_STYLE::subControlRect(control, option, subControl, widget); + break; + } + return visualRect(scrollBar->direction/*Qt::LeftToRight*/, scrollBar->rect, ret); + } + break; + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + { + if(SLIDER_TRIANGULAR==opts.sliderStyle) + { + int tickSize(pixelMetric(PM_SliderTickmarkOffset, option, widget)), + mod=MO_GLOW==opts.coloredMouseOver && DO_EFFECT ? 2 : 0; + QRect rect(BASE_STYLE::subControlRect(control, option, subControl, widget)); + + switch (subControl) + { + case SC_SliderHandle: + if (slider->orientation == Qt::Horizontal) + { + rect.setWidth(11+mod); + rect.setHeight(15+mod); + int centerY(r.center().y() - rect.height() / 2); + if (slider->tickPosition & QSlider::TicksAbove) + centerY += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + centerY -= (tickSize-1); + rect.moveTop(centerY); + } + else + { + rect.setWidth(15+mod); + rect.setHeight(11+mod); + int centerX(r.center().x() - rect.width() / 2); + if (slider->tickPosition & QSlider::TicksAbove) + centerX += tickSize; + if (slider->tickPosition & QSlider::TicksBelow) + centerX -= (tickSize-1); + rect.moveLeft(centerX); + } + break; + case SC_SliderGroove: + { + QPoint grooveCenter(r.center()); + + if (Qt::Horizontal==slider->orientation) + { + rect.setHeight(13); + --grooveCenter.ry(); + if (slider->tickPosition & QSlider::TicksAbove) + grooveCenter.ry() += (tickSize+2); + if (slider->tickPosition & QSlider::TicksBelow) + grooveCenter.ry() -= (tickSize-1); + } + else + { + rect.setWidth(13); + --grooveCenter.rx(); + if (slider->tickPosition & QSlider::TicksAbove) + grooveCenter.rx() += (tickSize+2); + if (slider->tickPosition & QSlider::TicksBelow) + grooveCenter.rx() -= (tickSize-1); + } + rect.moveCenter(grooveCenter); + break; + } + default: + break; + } + return rect; + } + else + { + bool horizontal(Qt::Horizontal==slider->orientation); + int thickness(pixelMetric(PM_SliderControlThickness, slider, widget)), + tickOffset(slider->tickPosition&QSlider::TicksAbove || + slider->tickPosition&QSlider::TicksBelow + ? pixelMetric(PM_SliderTickmarkOffset, slider, widget) + : ((horizontal ? r.height() : r.width()) - thickness)/2); + + switch (subControl) + { + case SC_SliderHandle: + { + int len(pixelMetric(PM_SliderLength, slider, widget)), + sliderPos(sliderPositionFromValue(slider->minimum, slider->maximum, + slider->sliderPosition, + (horizontal ? r.width() + : r.height()) - len, + slider->upsideDown)); + + if (horizontal) + r.setRect(r.x() + sliderPos, r.y() + tickOffset, len, thickness); + else + r.setRect(r.x() + tickOffset, r.y() + sliderPos, thickness, len); + break; + } + case SC_SliderGroove: + if (horizontal) + r.setRect(r.x(), r.y() + tickOffset, r.width(), thickness); + else + r.setRect(r.x() + tickOffset, r.y(), thickness, r.height()); + break; + default: + break; + } + return visualRect(slider->direction, r, r); + } + } + break; + case CC_GroupBox: + if(SC_GroupBoxCheckBox==subControl || SC_GroupBoxLabel==subControl) + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(option)) + { + QFont font(widget ? widget->font() : QApplication::font()); + + font.setBold(opts.gbLabel&GB_LBL_BOLD); + + QFontMetrics fontMetrics(font); + int h(fontMetrics.height()), + tw(fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width()), + marg((groupBox->features & QStyleOptionFrameV2::Flat) || + NO_FRAME(opts.groupBox) || opts.gbLabel&GB_LBL_OUTSIDE + ? 0 + : opts.gbLabel&GB_LBL_INSIDE + ? 2 + : 6), + indicatorWidth(pixelMetric(PM_IndicatorWidth, option, widget)), + indicatorSpace(pixelMetric(PM_CheckBoxLabelSpacing, option, widget) - 1); + bool hasCheckBox(groupBox->subControls & QStyle::SC_GroupBoxCheckBox); + int checkBoxSize(hasCheckBox ? (indicatorWidth + indicatorSpace) : 0), + checkAdjust(NO_FRAME(opts.groupBox) || opts.gbLabel&GB_LBL_OUTSIDE ? 0 : 2); + + if(0==checkAdjust) + checkBoxSize-=2; + + r.adjust(marg, 0, -marg, 0); + if(!NO_FRAME(opts.groupBox) && opts.gbLabel&GB_LBL_INSIDE) + r.adjust(0, 2, 0, 2); + r.setHeight(h); + + // Adjusted rect for label + indicatorWidth + indicatorSpace + Qt::Alignment align(groupBox->textAlignment); + if(opts.gbLabel&GB_LBL_CENTRED) + { + align&=~(Qt::AlignLeft|Qt::AlignRight); + align|=Qt::AlignHCenter; + } + r=alignedRect(groupBox->direction, align, QSize(tw + checkBoxSize, h), r); + + // Adjust totalRect if checkbox is set + if (hasCheckBox) + { + if (SC_GroupBoxCheckBox==subControl) // Adjust for check box + { + int indicatorHeight(pixelMetric(PM_IndicatorHeight, option, widget)), + top(r.top() + (fontMetrics.height() - indicatorHeight) / 2); + + r.setRect(reverse ? (r.right() - indicatorWidth) : r.left()+checkAdjust, top, indicatorWidth, indicatorHeight); + } + else // Adjust for label + r.setRect(reverse ? r.left() : (r.left() + checkBoxSize), r.top(), r.width() - checkBoxSize, r.height()); + } + return r; + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast(option)) + { + bool isMinimized(tb->titleBarState&Qt::WindowMinimized), + isMaximized(tb->titleBarState&Qt::WindowMaximized); + + if( (isMaximized && SC_TitleBarMaxButton==subControl) || + (isMinimized && SC_TitleBarMinButton==subControl) || + (isMinimized && SC_TitleBarShadeButton==subControl) || + (!isMinimized && SC_TitleBarUnshadeButton==subControl)) + return QRect(); + + readMdiPositions(); + + const int controlSize(tb->rect.height() - constWindowMargin *2); + + QList::ConstIterator it(itsMdiButtons[0].begin()), + end(itsMdiButtons[0].end()); + int sc(SC_TitleBarUnshadeButton==subControl + ? SC_TitleBarShadeButton + : SC_TitleBarNormalButton==subControl + ? isMaximized + ? SC_TitleBarMaxButton + : SC_TitleBarMinButton + : subControl), + pos(0), + totalLeft(0), + totalRight(0); + bool rhs(false), + found(false); + + for(; it!=end; ++it) + if(SC_TitleBarCloseButton==(*it) || WINDOWTITLE_SPACER==(*it) || tb->titleBarFlags&(toHint(*it))) + { + totalLeft+=WINDOWTITLE_SPACER==(*it) ? controlSize/2 : controlSize; + if(*it==sc) + found=true; + else if(!found) + pos+=WINDOWTITLE_SPACER==(*it) ? controlSize/2 : controlSize; + } + + if(!found) + { + pos=0; + rhs=true; + } + + it=itsMdiButtons[1].begin(); + end=itsMdiButtons[1].end(); + for(; it!=end; ++it) + if(SC_TitleBarCloseButton==(*it) || WINDOWTITLE_SPACER==(*it) || tb->titleBarFlags&(toHint(*it))) + { + if(WINDOWTITLE_SPACER!=(*it) || totalRight) + totalRight+=WINDOWTITLE_SPACER==(*it) ? controlSize/2 : controlSize; + if(rhs) + { + if(*it==sc) + { + pos+=controlSize; + found=true; + } + else if(found) + pos+=WINDOWTITLE_SPACER==(*it) ? controlSize/2 : controlSize; + } + } + + totalLeft+=(constWindowMargin*(totalLeft ? 2 : 1)); + totalRight+=(constWindowMargin*(totalRight ? 2 : 1)); + + if(SC_TitleBarLabel==subControl) + r.adjust(totalLeft, 0, -totalRight, 0); + else if(!found) + return QRect(); + else if(rhs) + r.setRect(r.right()-(pos+constWindowMargin), r.top()+constWindowMargin, controlSize, controlSize); + else + r.setRect(r.left()+constWindowMargin+pos, r.top()+constWindowMargin, controlSize, controlSize); + if(0==(r.height()%2)) + r.adjust(0, 0, 1, 1); + return visualRect(tb->direction, tb->rect, r); + } + default: + break; + } + + return BASE_STYLE::subControlRect(control, option, subControl, widget); +} + +QStyle::SubControl Style::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget) const +{ + itsSbWidget=0L; + switch (control) + { + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollBar = qstyleoption_cast(option)) + { + if (subControlRect(control, scrollBar, SC_ScrollBarSlider, widget).contains(pos)) + return SC_ScrollBarSlider; + + if (subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget).contains(pos)) + return SC_ScrollBarAddLine; + + if (subControlRect(control, scrollBar, SC_ScrollBarSubPage, widget).contains(pos)) + return SC_ScrollBarSubPage; + + if (subControlRect(control, scrollBar, SC_ScrollBarAddPage, widget).contains(pos)) + return SC_ScrollBarAddPage; + + if (subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget).contains(pos)) + { + if (SCROLLBAR_KDE==opts.scrollbarType && subControlRect(control, scrollBar, SB_SUB2, widget).contains(pos)) + itsSbWidget=widget; + return SC_ScrollBarSubLine; + } + } + default: + break; + } + + return BASE_STYLE::hitTestComplexControl(control, option, pos, widget); +} + +void Style::drawSideBarButton(QPainter *painter, const QRect &r, const QStyleOption *option, const QWidget *widget) const +{ + const QPalette &palette(option->palette); + QRect r2(r); + QStyleOption opt(*option); + + if(r2.height()>r2.width() || (r2.height()save(); + if(opt.state&State_On || opt.state&State_MouseOver) + { + r2.adjust(-1, -1, 1, 1); + drawLightBevel(painter, r2, &opt, widget, ROUNDED_NONE, getFill(&opt, use), use, false, WIDGET_MENU_ITEM); + } + else + painter->fillRect(r2, palette.background().color()); + + if(opt.state&State_MouseOver && opts.coloredMouseOver) + { + r2=r; + if(MO_PLASTIK==opts.coloredMouseOver) + if(horiz) + r2.adjust(0, 1, 0, -1); + else + r2.adjust(1, 0, -1, 0); + else + r2.adjust(1, 1, -1, -1); + + if(MO_GLOW==opts.coloredMouseOver) + { + QColor col(itsMouseOverCols[opt.state&State_On ? 0 : 1]); + + col.setAlphaF(GLOW_ALPHA(false)); + painter->setPen(col); + drawRect(painter, r); + col=itsMouseOverCols[opt.state&State_On ? 4 : 3]; + col.setAlphaF(0.8); + painter->setPen(col); + drawRect(painter, r2); + } + else + { + painter->setPen(itsMouseOverCols[opt.state&State_On ? 0 : 1]); + + if(horiz || MO_PLASTIK!=opts.coloredMouseOver) + { + painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); + painter->drawLine(r2.x(), r2.y(), r2.x()+r2.width()-1, r2.y()); + } + + if(!horiz || MO_PLASTIK!=opts.coloredMouseOver) + { + painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); + painter->drawLine(r2.x(), r2.y(), r2.x(), r2.y()+r2.height()-1); + if(MO_PLASTIK!=opts.coloredMouseOver) + painter->setPen(itsMouseOverCols[opt.state&State_On ? 1 : 2]); + } + + if(horiz || MO_PLASTIK!=opts.coloredMouseOver) + { + painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r2.x(), r2.y()+r2.height()-1, r2.x()+r2.width()-1, r2.y()+r2.height()-1); + } + + if(!horiz || MO_PLASTIK!=opts.coloredMouseOver) + { + painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); + painter->drawLine(r2.x()+r2.width()-1, r2.y(), r2.x()+r2.width()-1, r2.y()+r2.height()-1); + } + } + } + + painter->restore(); +} + +void Style::drawHighlight(QPainter *p, const QRect &r, bool horiz, bool inc) const +{ + QColor col1(itsMouseOverCols[ORIGINAL_SHADE]); + + col1.setAlphaF(0.5); + drawFadedLine(p, r, inc ? col1 : itsMouseOverCols[ORIGINAL_SHADE], true, true, horiz); + drawFadedLine(p, r.adjusted(horiz ? 0 : 1, horiz ? 1 : 0, 0, 0), inc ? itsMouseOverCols[ORIGINAL_SHADE] : col1, true, true, horiz); +} + +void Style::drawFadedLine(QPainter *p, const QRect &r, const QColor &col, bool fadeStart, bool fadeEnd, bool horiz, + double fadeSizeStart, double fadeSizeEnd) const +{ + bool aa(p->testRenderHint(QPainter::Antialiasing)); + QPointF start(r.x()+(aa ? 0.5 : 0.0), r.y()+(aa ? 0.5 : 0.0)), + end(r.x()+(horiz ? r.width()-1 : 0)+(aa ? 0.5 : 0.0), + r.y()+(horiz ? 0 : r.height()-1)+(aa ? 0.5 : 0.0)); + + if(opts.fadeLines && (fadeStart || fadeEnd)) + { + QLinearGradient grad(start, end); + QColor fade(col); + + fade.setAlphaF(0.0); + grad.setColorAt(0, fadeStart && opts.fadeLines ? fade : col); + if(fadeSizeStart>=0 && fadeSizeStart<=1.0) + grad.setColorAt(fadeSizeStart, col); + if(fadeSizeEnd>=0 && fadeSizeEnd<=1.0) + grad.setColorAt(1.0-fadeSizeEnd, col); + grad.setColorAt(1, fadeEnd && opts.fadeLines ? fade : col); + p->setPen(QPen(QBrush(grad), 1)); + } + else + p->setPen(col); + p->drawLine(start, end); +} + +void Style::drawLines(QPainter *p, const QRect &r, bool horiz, int nLines, int offset, const QColor *cols, int startOffset, + int dark, ELine type) const +{ + int space((nLines*2)+(LINE_DASHES!=type ? (nLines-1) : 0)), + step(LINE_DASHES!=type ? 3 : 2), + etchedDisp(LINE_SUNKEN==type ? 1 : 0), + x(horiz ? r.x() : r.x()+((r.width()-space)>>1)), + y(horiz ? r.y()+((r.height()-space)>>1) : r.y()), + x2(r.x()+r.width()-1), + y2(r.y()+r.height()-1), + i; + QPen dp(cols[dark], 1), + lp(cols[0], 1); + + if(opts.fadeLines && (horiz ? r.width() : r.height())>16) + { + QLinearGradient grad(r.topLeft(), horiz ? r.topRight() : r.bottomLeft()); + QColor fade(cols[dark]); + + fade.setAlphaF(0.0); + grad.setColorAt(0, fade); + grad.setColorAt(0.4, cols[dark]); + grad.setColorAt(0.6, cols[dark]); + grad.setColorAt(1, fade); + + dp=QPen(QBrush(grad), 1); + + if(LINE_FLAT!=type) + { + fade=QColor(cols[0]); + + fade.setAlphaF(0.0); + grad.setColorAt(0, fade); + grad.setColorAt(0.4, cols[0]); + grad.setColorAt(0.6, cols[0]); + grad.setColorAt(1, fade); + lp=QPen(QBrush(grad), 1); + } + } + + p->setRenderHint(QPainter::Antialiasing, true); + if(horiz) + { + if(startOffset && y+startOffset>0) + y+=startOffset; + + p->setPen(dp); + for(i=0; isetPen(lp); + x+=etchedDisp; + x2+=etchedDisp; + for(i=1; i0) + x+=startOffset; + + p->setPen(dp); + for(i=0; isetPen(lp); + y+=etchedDisp; + y2+=etchedDisp; + for(i=1; isetRenderHint(QPainter::Antialiasing, false); +} + +void Style::drawProgressBevelGradient(QPainter *p, const QRect &origRect, const QStyleOption *option, bool horiz, EAppearance bevApp, + const QColor *cols) const +{ + bool vertical(!horiz), + inCache(true); + QRect r(0, 0, horiz ? PROGRESS_CHUNK_WIDTH*2 : origRect.width(), + horiz ? origRect.height() : PROGRESS_CHUNK_WIDTH*2); + QtcKey key(createKey(horiz ? r.height() : r.width(), cols[ORIGINAL_SHADE], horiz, bevApp, WIDGET_PROGRESSBAR)); + QPixmap *pix(itsPixmapCache.object(key)); + + if(!pix) + { + pix=new QPixmap(r.width(), r.height()); + + QPainter pixPainter(pix); + + if(IS_FLAT(bevApp)) + pixPainter.fillRect(r, cols[ORIGINAL_SHADE]); + else + drawBevelGradientReal(cols[ORIGINAL_SHADE], &pixPainter, r, horiz, false, bevApp, WIDGET_PROGRESSBAR); + + switch(opts.stripedProgress) + { + default: + case STRIPE_NONE: + break; + case STRIPE_PLAIN: + { + QRect r2(horiz + ? QRect(r.x(), r.y(), PROGRESS_CHUNK_WIDTH, r.height()) + : QRect(r.x(), r.y(), r.width(), PROGRESS_CHUNK_WIDTH)); + + if(IS_FLAT(bevApp)) + pixPainter.fillRect(r2, cols[1]); + else + drawBevelGradientReal(cols[1], &pixPainter, r2, horiz, false, bevApp, WIDGET_PROGRESSBAR); + break; + } + case STRIPE_DIAGONAL: + { + QRegion reg; + int size(vertical ? origRect.width() : origRect.height()); + + for(int offset=0; offset<(size*2); offset+=(PROGRESS_CHUNK_WIDTH*2)) + { + QPolygon a; + + if(vertical) + a.setPoints(4, r.x(), r.y()+offset, + r.x()+r.width(), (r.y()+offset)-size, + r.x()+r.width(), (r.y()+offset+PROGRESS_CHUNK_WIDTH)-size, + r.x(), r.y()+offset+PROGRESS_CHUNK_WIDTH); + else + a.setPoints(4, r.x()+offset, r.y(), + r.x()+offset+PROGRESS_CHUNK_WIDTH, r.y(), + (r.x()+offset+PROGRESS_CHUNK_WIDTH)-size, r.y()+r.height(), + (r.x()+offset)-size, r.y()+r.height()); + + reg+=QRegion(a); + } + + pixPainter.setClipRegion(reg); + if(IS_FLAT(bevApp)) + pixPainter.fillRect(r, cols[1]); + else + drawBevelGradientReal(cols[1], &pixPainter, r, horiz, false, bevApp, WIDGET_PROGRESSBAR); + } + } + + pixPainter.end(); + int cost(pix->width()*pix->height()*(pix->depth()/8)); + + if(coststate&STATE_REVERSE ? PROGRESS_CHUNK_WIDTH : -PROGRESS_CHUNK_WIDTH; + + if(vertical || option->state&STATE_REVERSE) + animShift -= (itsAnimateStep/2) % (PROGRESS_CHUNK_WIDTH*2); + else + animShift += (itsAnimateStep/2) % (PROGRESS_CHUNK_WIDTH*2); + + if(horiz) + fillRect.adjust(animShift-PROGRESS_CHUNK_WIDTH, 0, PROGRESS_CHUNK_WIDTH, 0); + else + fillRect.adjust(0, animShift-PROGRESS_CHUNK_WIDTH, 0, PROGRESS_CHUNK_WIDTH); + } + + p->save(); + p->setClipRect(origRect, Qt::IntersectClip); + p->drawTiledPixmap(fillRect, *pix); + if(STRIPE_FADE==opts.stripedProgress && fillRect.width()>4 && fillRect.height()>4) + addStripes(p, QPainterPath(), fillRect, !vertical); + p->restore(); + + if(!inCache) + delete pix; +} + +void Style::drawBevelGradient(const QColor &base, QPainter *p, const QRect &origRect, const QPainterPath &path, + bool horiz, bool sel, EAppearance bevApp, EWidget w, bool useCache) const +{ + if(origRect.width()<1 || origRect.height()<1) + return; + + if(IS_FLAT(bevApp)) + { + if((WIDGET_TAB_TOP!=w && WIDGET_TAB_BOT!=w) || !CUSTOM_BGND || opts.tabBgnd || !sel) + { + if(path.isEmpty()) + p->fillRect(origRect, base); + else + p->fillPath(path, base); + } + } + else + { + bool tab(WIDGET_TAB_TOP==w || WIDGET_TAB_BOT==w), + selected(tab ? false : sel); + EAppearance app(selected + ? opts.sunkenAppearance + : WIDGET_LISTVIEW_HEADER==w && APPEARANCE_BEVELLED==bevApp + ? APPEARANCE_LV_BEVELLED + : APPEARANCE_BEVELLED!=bevApp || WIDGET_BUTTON(w) || WIDGET_LISTVIEW_HEADER==w || + WIDGET_TROUGH==w || WIDGET_NO_ETCH_BTN==w || WIDGET_MENU_BUTTON==w + ? bevApp + : APPEARANCE_GRADIENT); + + if(WIDGET_PROGRESSBAR==w || !useCache) + drawBevelGradientReal(base, p, origRect, path, horiz, sel, app, w); + else + { + QRect r(0, 0, horiz ? PIXMAP_DIMENSION : origRect.width(), + horiz ? origRect.height() : PIXMAP_DIMENSION); + QtcKey key(createKey(horiz ? r.height() : r.width(), base, horiz, app, w)); + QPixmap *pix(itsPixmapCache.object(key)); + bool inCache(true); + + if(!pix) + { + pix=new QPixmap(r.width(), r.height()); + pix->fill(Qt::transparent); + + QPainter pixPainter(pix); + + drawBevelGradientReal(base, &pixPainter, r, horiz, sel, app, w); + pixPainter.end(); + + int cost(pix->width()*pix->height()*(pix->depth()/8)); + + if(costsave(); + p->setClipPath(path, Qt::IntersectClip); + } + + p->drawTiledPixmap(origRect, *pix); + if(!path.isEmpty()) + p->restore(); + if(!inCache) + delete pix; + } + } +} + +void Style::drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r, const QPainterPath &path, + bool horiz, bool sel, EAppearance app, EWidget w) const +{ + bool topTab(WIDGET_TAB_TOP==w), + botTab(WIDGET_TAB_BOT==w), + dwt(CUSTOM_BGND && WIDGET_DOCK_WIDGET_TITLE==w), + titleBar(opts.windowBorder&WINDOW_BORDER_BLEND_TITLEBAR && + (WIDGET_MDI_WINDOW==w || WIDGET_MDI_WINDOW_TITLE==w || + (opts.dwtSettings&DWT_COLOR_AS_PER_TITLEBAR && + WIDGET_DOCK_WIDGET_TITLE==w && !dwt))), + reverse(Qt::RightToLeft==QApplication::layoutDirection()); + const Gradient *grad=qtcGetGradient(app, &opts); + QLinearGradient g(r.topLeft(), horiz ? r.bottomLeft() : r.topRight()); + GradientStopCont::const_iterator it(grad->stops.begin()), + end(grad->stops.end()); + int numStops(grad->stops.size()); + + for(int i=0; it!=end; ++it, ++i) + { + QColor col; + + if(/*sel && */(topTab || botTab || dwt || titleBar) && i==numStops-1) + { + if(titleBar) + { + col=itsBackgroundCols[ORIGINAL_SHADE]; + //if(APPEARANCE_STRIPED==opts.bgndAppearance) + col.setAlphaF(0.0); + } + else + { + col=base; + if((sel /*&& CUSTOM_BGND*/ && 0==opts.tabBgnd && !reverse) || dwt) + col.setAlphaF(0.0); + } + } + else + shade(base, &col, botTab && opts.invertBotTab ? qMax(INVERT_SHADE((*it).val), 0.9) : (*it).val); + if(WIDGET_TOOLTIP!=w && (*it).alpha<1.0) + col.setAlphaF(col.alphaF()*(*it).alpha); + g.setColorAt(botTab ? 1.0-(*it).pos : (*it).pos, col); + } + + if(APPEARANCE_AGUA==app && !(topTab || botTab || dwt) && (horiz ? r.height() : r.width())>AGUA_MAX) + { + QColor col; + double pos=AGUA_MAX/((horiz ? r.height() : r.width())*2.0); + shade(base, &col, AGUA_MID_SHADE); + g.setColorAt(pos, col); + g.setColorAt(1.0-pos, col); + } + + //p->fillRect(r, base); + if(path.isEmpty()) + p->fillRect(r, QBrush(g)); + else + p->fillPath(path, QBrush(g)); +} + +void Style::drawSunkenBevel(QPainter *p, const QRect &r, const QColor &col) const +{ + double radius=opts.titlebarButtons&TITLEBAR_BUTTON_ROUND + ? r.height()/2.0 + : opts.round>ROUND_FULL + ? 5.0 + : opts.round>ROUND_SLIGHT + ? 3.0 + : 2.0; + QPainterPath path(buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, radius)); + QLinearGradient g(r.topLeft(), r.bottomLeft()); + QColor black(Qt::black), + white(Qt::white); + + black.setAlphaF(SUNKEN_BEVEL_DARK_ALPHA(col)); + white.setAlphaF(SUNKEN_BEVEL_LIGHT_ALPHA(col)); + g.setColorAt(0, black); + g.setColorAt(1, white); + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + p->fillPath(path, QBrush(g)); + p->restore(); +} + +void Style::drawLightBevel(QPainter *p, const QRect &r, const QStyleOption *option, const QWidget *widget, int round, const QColor &fill, + const QColor *custom, bool doBorder, EWidget w) const +{ + bool onToolbar=APPEARANCE_NONE!=opts.tbarBtnAppearance && (WIDGET_TOOLBAR_BUTTON==w || (WIDGET_BUTTON(w) && isOnToolbar(widget))); + + if(WIDGET_PROGRESSBAR==w || WIDGET_SB_BUTTON==w || (WIDGET_SPIN==w && !opts.unifySpin)/* || !itsUsePixmapCache*/) + drawLightBevelReal(p, r, option, widget, round, fill, custom, doBorder, w, true, opts.round, onToolbar); + else + { + static const int constMaxCachePixmap = 128; + + int endSize=0, + middleSize=8; + bool horiz(CIRCULAR_SLIDER(w) || isHoriz(option, w, TBTN_JOINED==opts.tbarBtns)), + circular( (WIDGET_MDI_WINDOW_BUTTON==w && (opts.titlebarButtons&TITLEBAR_BUTTON_ROUND)) || + WIDGET_RADIO_BUTTON==w || WIDGET_DIAL==w || CIRCULAR_SLIDER(w)); + double radius=0; + ERound realRound=qtcGetWidgetRound(&opts, r.width(), r.height(), w); + + if(!circular) + { + switch(realRound) + { + case ROUND_SLIGHT: + case ROUND_NONE: + case ROUND_FULL: + endSize=SLIDER(w) && MO_PLASTIK==opts.coloredMouseOver && option->state&State_MouseOver ? 9 : 5; + break; + case ROUND_EXTRA: + endSize=7; + break; + case ROUND_MAX: + { + radius=qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_ETCH); + endSize=SLIDER(w) + ? qMax((opts.sliderWidth/2)+1, (int)(radius+1.5)) + : (int)(radius+2.5); + middleSize=(MIN_ROUND_MAX_WIDTH-(endSize*2))+4; + if(middleSize<4) + middleSize=4; + break; + } + } + } + + int size((2*endSize)+middleSize); + + if(size>constMaxCachePixmap) + drawLightBevelReal(p, r, option, widget, round, fill, custom, doBorder, w, true, realRound, onToolbar); + else + { + QString key; + bool small(circular || (horiz ? r.width() : r.height())<(2*endSize)); + QPixmap pix; + QSize pixSize(small ? QSize(r.width(), r.height()) : QSize(horiz ? size : r.width(), horiz ? r.height() : size)); + uint state(option->state&(State_Raised|State_Sunken|State_On|State_Horizontal|State_HasFocus|State_MouseOver| + (WIDGET_MDI_WINDOW_BUTTON==w ? State_Active : State_None))); + + key.sprintf("qtc-%x-%x-%x-%x-%x-%x-%x-%x-%x", w, onToolbar ? 1 : 0, round, (int)realRound, pixSize.width(), pixSize.height(), + state, fill.rgba(), (int)(radius*100)); + if(!itsUsePixmapCache || !QPixmapCache::find(key, pix)) + { + pix=QPixmap(pixSize); + pix.fill(Qt::transparent); + + QPainter pixPainter(&pix); + ERound oldRound=opts.round; + opts.round=realRound; + drawLightBevelReal(&pixPainter, QRect(0, 0, pix.width(), pix.height()), option, widget, round, fill, custom, + doBorder, w, false, realRound, onToolbar); + opts.round=oldRound; + pixPainter.end(); + + if(itsUsePixmapCache) + QPixmapCache::insert(key, pix); + } + + if(small) + p->drawPixmap(r.topLeft(), pix); + else if(horiz) + { + int middle(qMin(r.width()-(2*endSize), middleSize)); + if(middle>0) + p->drawTiledPixmap(r.x()+endSize, r.y(), r.width()-(2*endSize), pix.height(), pix.copy(endSize, 0, middle, pix.height())); + p->drawPixmap(r.x(), r.y(), pix.copy(0, 0, endSize, pix.height())); + p->drawPixmap(r.x()+r.width()-endSize, r.y(), pix.copy(pix.width()-endSize, 0, endSize, pix.height())); + } + else + { + int middle(qMin(r.height()-(2*endSize), middleSize)); + if(middle>0) + p->drawTiledPixmap(r.x(), r.y()+endSize, pix.width(), r.height()-(2*endSize), + pix.copy(0, endSize, pix.width(), middle)); + p->drawPixmap(r.x(), r.y(), pix.copy(0, 0, pix.width(), endSize)); + p->drawPixmap(r.x(), r.y()+r.height()-endSize, pix.copy(0, pix.height()-endSize, pix.width(), endSize)); + } + + if(WIDGET_SB_SLIDER==w && opts.stripedSbar) + { + QRect rx(r.adjusted(1, 1, -1, -1)); + addStripes(p, buildPath(rx, WIDGET_SB_SLIDER, realRound, qtcGetRadius(&opts, rx.width()-1, rx.height()-1, WIDGET_SB_SLIDER, + RADIUS_INTERNAL)), + rx, horiz); + } + } + } +} + +void Style::drawLightBevelReal(QPainter *p, const QRect &rOrig, const QStyleOption *option, const QWidget *widget, int round, + const QColor &fill, const QColor *custom, bool doBorder, EWidget w, bool useCache, ERound realRound, + bool onToolbar) const +{ + EAppearance app(qtcWidgetApp(onToolbar ? WIDGET_TOOLBAR_BUTTON : w, &opts, option->state&State_Active)); + QRect r(rOrig); + bool bevelledButton((WIDGET_BUTTON(w) || WIDGET_NO_ETCH_BTN==w || WIDGET_MENU_BUTTON==w) && APPEARANCE_BEVELLED==app), + sunken(option->state &(/*State_Down | */State_On | State_Sunken)), + flatWidget( (WIDGET_MDI_WINDOW_BUTTON==w && + (opts.round==ROUND_MAX || opts.titlebarButtons&TITLEBAR_BUTTON_ROUND)) || + (WIDGET_PROGRESSBAR==w && !opts.borderProgress)), + lightBorder(!flatWidget && DRAW_LIGHT_BORDER(sunken, w, app)), + draw3dfull(!flatWidget && !lightBorder && DRAW_3D_FULL_BORDER(sunken, app)), + draw3d(!flatWidget && (draw3dfull || ( + !lightBorder && DRAW_3D_BORDER(sunken, app)))), + drawShine(DRAW_SHINE(sunken, app)), + doColouredMouseOver(doBorder && option->state&State_Enabled && + WIDGET_MDI_WINDOW_BUTTON!=w && + WIDGET_SPIN!=w && WIDGET_COMBO_BUTTON!=w && WIDGET_SB_BUTTON!=w && + (!SLIDER(w) || !opts.colorSliderMouseOver) && + !(option->state&STATE_KWIN_BUTTON) && + (opts.coloredTbarMo || !(option->state&STATE_TBAR_BUTTON)) && + opts.coloredMouseOver && option->state&State_MouseOver && + WIDGET_PROGRESSBAR!=w && + (option->state&STATE_TOGGLE_BUTTON || !sunken)), + plastikMouseOver(doColouredMouseOver && MO_PLASTIK==opts.coloredMouseOver), + colouredMouseOver(doColouredMouseOver && WIDGET_MENU_BUTTON!=w && + (MO_COLORED==opts.coloredMouseOver || + MO_COLORED_THICK==opts.coloredMouseOver || + (MO_GLOW==opts.coloredMouseOver && !DO_EFFECT))), + doEtch(doBorder && ETCH_WIDGET(w) && DO_EFFECT), + glowFocus(doEtch && USE_GLOW_FOCUS(option->state&State_MouseOver) && option->state&State_HasFocus && + option->state&State_Enabled), + horiz(CIRCULAR_SLIDER(w) || isHoriz(option, w, TBTN_JOINED==opts.tbarBtns)), + sunkenToggleMo(sunken && !(option->state&State_Sunken) && option->state&(State_MouseOver|STATE_TOGGLE_BUTTON)); + const QColor *cols(custom ? custom : itsBackgroundCols), + *border(colouredMouseOver ? borderColors(option, cols) : cols); + + p->save(); + + if(doEtch) + r.adjust(1, 1, -1, -1); + + if(WIDGET_TROUGH==w && !opts.borderSbarGroove) + doBorder=false; + + p->setRenderHint(QPainter::Antialiasing, true); + + if(r.width()>0 && r.height()>0) + { + if(WIDGET_PROGRESSBAR==w && STRIPE_NONE!=opts.stripedProgress) + drawProgressBevelGradient(p, opts.borderProgress ? r.adjusted(1, 1, -1, -1) : r, option, horiz, app, custom); + else + { + drawBevelGradient(fill, p, WIDGET_PROGRESSBAR==w && opts.borderProgress ? r.adjusted(1, 1, -1, -1) : r, + doBorder + ? buildPath(r, w, round, qtcGetRadius(&opts, r.width()-2, r.height()-2, w, RADIUS_INTERNAL)) + : buildPath(QRectF(r), w, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL)), + horiz, sunken, app, w, useCache); + + if(!sunken || sunkenToggleMo) + if(plastikMouseOver) // && !sunken) + { + p->save(); + p->setClipPath(buildPath(r.adjusted(0, 0, 0, -1), w, round, + qtcGetRadius(&opts, r.width()-2, r.height()-2, w, RADIUS_INTERNAL))); + if(SLIDER(w)) + { + int len(SB_SLIDER_MO_LEN(horiz ? r.width() : r.height())+1), + so(lightBorder ? SLIDER_MO_PLASTIK_BORDER : 1), + eo(len+so), + col(SLIDER_MO_SHADE); + + if(horiz) + { + drawBevelGradient(itsMouseOverCols[col], p, QRect(r.x()+so-1, r.y(), len, r.height()-1), horiz, sunken, app, w, useCache); + drawBevelGradient(itsMouseOverCols[col], p, QRect(r.x()+r.width()-eo+1, r.y(), len, r.height()-1), horiz, sunken, app, w, useCache); + } + else + { + drawBevelGradient(itsMouseOverCols[col], p, QRect(r.x(), r.y()+so-1, r.width()-1, len), horiz, sunken, app, w, useCache); + drawBevelGradient(itsMouseOverCols[col], p, QRect(r.x(), r.y()+r.height()-eo+1, r.width()-1, len), horiz, sunken, app, w, useCache); + } + } + else + { + bool horizontal((horiz && WIDGET_SB_BUTTON!=w)|| (!horiz && WIDGET_SB_BUTTON==w)), + thin(WIDGET_SB_BUTTON==w || WIDGET_SPIN==w || ((horiz ? r.height() : r.width())<16)); + + p->setPen(itsMouseOverCols[MO_PLASTIK_DARK(w)]); + if(horizontal) + { + drawAaLine(p, r.x()+1, r.y()+1, r.x()+r.width()-2, r.y()+1); + drawAaLine(p, r.x()+1, r.y()+r.height()-2, r.x()+r.width()-2, r.y()+r.height()-2); + } + else + { + drawAaLine(p, r.x()+1, r.y()+1, r.x()+1, r.y()+r.height()-2); + drawAaLine(p, r.x()+r.width()-2, r.y()+1, r.x()+r.width()-2, r.y()+r.height()-2); + } + if(!thin) + { + p->setPen(itsMouseOverCols[MO_PLASTIK_LIGHT(w)]); + if(horizontal) + { + drawAaLine(p, r.x()+1, r.y()+2, r.x()+r.width()-2, r.y()+2); + drawAaLine(p, r.x()+1, r.y()+r.height()-3, r.x()+r.width()-2, r.y()+r.height()-3); + } + else + { + drawAaLine(p, r.x()+2, r.y()+1, r.x()+2, r.y()+r.height()-2); + drawAaLine(p, r.x()+r.width()-3, r.y()+1, r.x()+r.width()-3, r.y()+r.height()-2); + } + } + } + p->restore(); + } + } + + if(drawShine) + { + bool mo(option->state&State_Enabled && option->state&State_MouseOver && opts.highlightFactor); + QColor white(Qt::white); + + if(WIDGET_MDI_WINDOW_BUTTON==w || WIDGET_RADIO_BUTTON==w || CIRCULAR_SLIDER(w)) + { + QRectF ra(r.x()+0.5, r.y()+0.5, r.width(), r.height()); + double topSize=(ra.height()*0.4), + topWidthAdjust=WIDGET_RADIO_BUTTON==w || WIDGET_SLIDER==w ? 4 : 4.75; + QRectF topGradRect(ra.x()+topWidthAdjust, ra.y(), + ra.width()-(topWidthAdjust*2)-1, topSize-1); + QLinearGradient topGrad(topGradRect.topLeft(), topGradRect.bottomLeft()); + + white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.8 : 0.7) : 0.75); + topGrad.setColorAt(0.0, white); + white.setAlphaF(/*mo ? (opts.highlightFactor>0 ? 0.3 : 0.1) : */0.2); + topGrad.setColorAt(1.0, white); + p->fillPath(buildPath(topGradRect, w, round, topSize), QBrush(topGrad)); + } + else + { + QRectF ra(r.x()+0.5, r.y()+0.5, r.width(), r.height()); + double size=(MIN((horiz ? ra.height() : ra.width())/2.0, 16)), + rad=size/2.0; + int mod=4; + + if(horiz) + { + if(!(ROUNDED_LEFT&round)) + ra.adjust(-8, 0, 0, 0); + if(!(ROUNDED_RIGHT&round)) + ra.adjust(0, 0, 8, 0); + } + else + { + if(!(ROUNDED_TOP&round)) + ra.adjust(0, -8, 0, 0); + if(!(ROUNDED_BOTTOM&round)) + ra.adjust(0, 0, 0, 8); + } + + if(realRound>1; + } + + QRectF gr(horiz ? QRectF(ra.x()+mod, ra.y(), ra.width()-(mod*2)-1, size-1) + : QRectF(ra.x(), ra.y()+mod, size-1, ra.height()-(mod*2)-1)); + QLinearGradient g(gr.topLeft(), horiz ? gr.bottomLeft() : gr.topRight()); + + white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.95 : 0.85) : 0.9); + g.setColorAt(0.0, white); + white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.3 : 0.1) : 0.2); + g.setColorAt(1.0, white); + if(WIDGET_SB_BUTTON==w) + { + p->save(); + p->setClipRect(r); + } + p->fillPath(buildPath(gr, w, round, rad), QBrush(g)); + if(WIDGET_SB_BUTTON==w) + p->restore(); + } + } + } + + r.adjust(1, 1, -1, -1); + + if(plastikMouseOver && (!sunken || sunkenToggleMo)) + { + bool thin(WIDGET_SB_BUTTON==w || WIDGET_SPIN==w || ((horiz ? r.height() : r.width())<16)), + horizontal(SLIDER(w) ? !horiz : (horiz && WIDGET_SB_BUTTON!=w)|| (!horiz && WIDGET_SB_BUTTON==w)); + int len(SLIDER(w) ? SB_SLIDER_MO_LEN(horiz ? r.width() : r.height()) : (thin ? 1 : 2)); + + p->save(); + if(horizontal) + p->setClipRect(r.x(), r.y()+len, r.width(), r.height()-(len*2)); + else + p->setClipRect(r.x()+len, r.y(), r.width()-(len*2), r.height()); + } + + if(!colouredMouseOver && lightBorder) + { + p->setPen(cols[LIGHT_BORDER(app)]); + p->drawPath(buildPath(r, w, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_INTERNAL))); + } + else if(colouredMouseOver || (draw3d && option->state&State_Raised)) + { + QPainterPath innerTlPath, + innerBrPath; + int dark(/*bevelledButton ? */2/* : 4*/); + + buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_INTERNAL), + innerTlPath, innerBrPath); + + p->setPen(border[colouredMouseOver ? MO_STD_LIGHT(w, sunken) : (sunken ? dark : 0)]); + p->drawPath(innerTlPath); + if(colouredMouseOver || bevelledButton || draw3dfull) + { + p->setPen(border[colouredMouseOver ? MO_STD_DARK(w) : (sunken ? 0 : dark)]); + p->drawPath(innerBrPath); + } + } + if(plastikMouseOver && (!sunken || sunkenToggleMo)) + p->restore(); + p->setRenderHint(QPainter::Antialiasing, false); + + if(doEtch || glowFocus) + { + if( !(opts.thin&THIN_FRAMES) && (!sunken || sunkenToggleMo || + (sunken && glowFocus && widget && ::qobject_cast(widget) && + static_cast(widget)->isCheckable())) && + ((WIDGET_OTHER!=w && WIDGET_SLIDER_TROUGH!=w && MO_GLOW==opts.coloredMouseOver && option->state&State_MouseOver) || + (WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator) || + glowFocus) ) + drawGlow(p, rOrig, WIDGET_DEF_BUTTON==w && option->state&State_MouseOver ? WIDGET_STD_BUTTON : w, + glowFocus ? itsFocusCols : 0L); + else + drawEtch(p, rOrig, widget, w, EFFECT_SHADOW==opts.buttonEffect && WIDGET_BUTTON(w) && !sunken); + } + + if(doBorder) + { + const QColor *borderCols=glowFocus || ( (WIDGET_COMBO==w || WIDGET_MENU_BUTTON==w || (WIDGET_NO_ETCH_BTN==w && ROUNDED_ALL!=round)) && + USE_GLOW_FOCUS(option->state&State_MouseOver) && + option->state&State_HasFocus && option->state&State_Enabled) + ? itsFocusCols + : (WIDGET_COMBO==w || WIDGET_COMBO_BUTTON==w) && border==itsComboBtnCols + ? option->state&State_MouseOver && MO_GLOW==opts.coloredMouseOver && !sunken + ? itsMouseOverCols + : itsButtonCols + : cols; + + r.adjust(-1, -1, 1, 1); + if(!sunken && option->state&State_Enabled && !glowFocus && + ( ( ( (doEtch && WIDGET_OTHER!=w && WIDGET_SLIDER_TROUGH!=w) || SLIDER(w) || WIDGET_COMBO==w || WIDGET_MENU_BUTTON==w ) && + (MO_GLOW==opts.coloredMouseOver/* || MO_COLORED==opts.colorMenubarMouseOver*/) && option->state&State_MouseOver) || + glowFocus || (doEtch && WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator))) + drawBorder(p, r, option, round, + WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator && !(option->state&State_MouseOver) + ? itsDefBtnCols : itsMouseOverCols, w); + else + drawBorder(p, r, option, round, + colouredMouseOver && MO_COLORED_THICK==opts.coloredMouseOver ? itsMouseOverCols : borderCols, w); + } + + p->restore(); +} + +void Style::drawGlow(QPainter *p, const QRect &r, EWidget w, const QColor *cols) const +{ + bool def(WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator), + defShade=def && (!itsDefBtnCols || + (itsDefBtnCols[ORIGINAL_SHADE]==itsMouseOverCols[ORIGINAL_SHADE])); + QColor col(cols ? cols[GLOW_MO] + : def && itsDefBtnCols + ? itsDefBtnCols[GLOW_DEFBTN] : itsMouseOverCols[GLOW_MO]); + + col.setAlphaF(GLOW_ALPHA(defShade)); + p->setBrush(Qt::NoBrush); + p->setRenderHint(QPainter::Antialiasing, true); + p->setPen(col); + p->drawPath(buildPath(r, w, ROUNDED_ALL, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_ETCH))); + p->setRenderHint(QPainter::Antialiasing, false); +} + +void Style::drawEtch(QPainter *p, const QRect &r, const QWidget *widget, EWidget w, bool raised, int round) const +{ + QPainterPath tl, + br; + QColor col(Qt::black); + + if(WIDGET_TOOLBAR_BUTTON==w && EFFECT_ETCH==opts.tbarBtnEffect) + raised=false; + + buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_ETCH), tl, br); + + col.setAlphaF(USE_CUSTOM_ALPHAS(opts) ? opts.customAlphas[ALPHA_ETCH_DARK] : ETCH_TOP_ALPHA); + p->setBrush(Qt::NoBrush); + p->setRenderHint(QPainter::Antialiasing, true); + p->setPen(col); + + if(!raised && WIDGET_SLIDER!=w) + { + p->drawPath(tl); + if(WIDGET_SLIDER_TROUGH==w && opts.thinSbarGroove && widget && qobject_cast(widget)) + { + QColor col(Qt::white); + col.setAlphaF(USE_CUSTOM_ALPHAS(opts) ? opts.customAlphas[ALPHA_ETCH_LIGHT] : ETCH_BOTTOM_ALPHA); // 0.25); + p->setPen(col); + } + else + p->setPen(getLowerEtchCol(widget)); + } + + p->drawPath(br); + p->setRenderHint(QPainter::Antialiasing, false); +} + +void Style::drawBgndRing(QPainter &painter, int x, int y, int size, int size2, bool isWindow) const +{ + double width=(size-size2)/2.0, + width2=width/2.0; + QColor col(Qt::white); + + col.setAlphaF(RINGS_INNER_ALPHA(isWindow ? opts.bgndImage.type : opts.menuBgndImage.type)); + painter.setPen(QPen(col, width)); + painter.drawEllipse(QRectF(x+width2, y+width2, size-width, size-width)); + + if(IMG_BORDERED_RINGS==(isWindow ? opts.bgndImage.type : opts.menuBgndImage.type)) + { + col.setAlphaF(RINGS_OUTER_ALPHA); + painter.setPen(QPen(col, 1)); + painter.drawEllipse(QRectF(x, y, size, size)); + if(size2) + painter.drawEllipse(QRectF(x+width, y+width, size2, size2)); + } +} + +QPixmap Style::drawStripes(const QColor &color, int opacity) const +{ + QPixmap pix; + QString key; + QColor col(color); + + if(100!=opacity) + col.setAlphaF(opacity/100.0); + + key.sprintf("qtc-stripes-%x", col.rgba()); + if(!itsUsePixmapCache || !QPixmapCache::find(key, pix)) + { + pix=QPixmap(QSize(64, 64)); + + if(100!=opacity) + pix.fill(Qt::transparent); + + QPainter pixPainter(&pix); + QColor col2(shade(col, BGND_STRIPE_SHADE)); + + if(100!=opacity) + { + col2.setAlphaF(opacity/100.0); + pixPainter.setPen(col); + for(int i=0; idrawTiledPixmap(r, APPEARANCE_STRIPED==app || APPEARANCE_FILE==app || scaledSize==pix.size() + ? pix : pix.scaled(scaledSize, Qt::IgnoreAspectRatio)); + else + { + const QPointF prevOrigin(p->brushOrigin()); + p->setBrushOrigin(r.x(), r.y()); + p->fillPath(path, + QBrush(APPEARANCE_STRIPED==app || APPEARANCE_FILE==app || scaledSize==pix.size() + ? pix : pix.scaled(scaledSize, Qt::IgnoreAspectRatio))); + p->setBrushOrigin(prevOrigin); + } + + if(isWindow && APPEARANCE_STRIPED!=app && APPEARANCE_FILE!=app && GT_HORIZ==grad && GB_SHINE==qtcGetGradient(app, &opts)->border) + { + int size=qMin(BGND_SHINE_SIZE, qMin(r.height()*2, r.width())); + + QString key; + key.sprintf("qtc-radial-%x", size/BGND_SHINE_STEPS); + + if(!itsUsePixmapCache || !QPixmapCache::find(key, pix)) + { + size/=BGND_SHINE_STEPS; + size*=BGND_SHINE_STEPS; + pix=QPixmap(size, size/2); + pix.fill(Qt::transparent); + QRadialGradient gradient(QPointF(pix.width()/2.0, 0), pix.width()/2.0, QPointF(pix.width()/2.0, 0)); + QColor c(Qt::white); + double alpha(qtcShineAlpha(&col)); + + c.setAlphaF(alpha); + gradient.setColorAt(0, c); + c.setAlphaF(alpha*0.625); + gradient.setColorAt(0.5, c); + c.setAlphaF(alpha*0.175); + gradient.setColorAt(0.75, c); + c.setAlphaF(0); + gradient.setColorAt(1, c); + QPainter pixPainter(&pix); + pixPainter.fillRect(QRect(0, 0, pix.width(), pix.height()), gradient); + pixPainter.end(); + if(itsUsePixmapCache) + QPixmapCache::insert(key, pix); + } + + p->drawPixmap(r.x()+((r.width()-pix.width())/2), r.y(), pix); + } + } + else + { + QColor col(bgnd); + + if(100!=opacity) + col.setAlphaF(opacity/100.0); + if(path.isEmpty()) + p->fillRect(r, col); + else + { + const QPointF prevOrigin(p->brushOrigin()); + p->setBrushOrigin(r.x(), r.y()); + p->fillPath(path, col); + p->setBrushOrigin(prevOrigin); + } + } +} + +void Style::drawBackgroundImage(QPainter *p, bool isWindow, const QRect &r) const +{ + QtCImage &img=isWindow || (opts.bgndImage.type==opts.menuBgndImage.type && + (IMG_FILE!=opts.bgndImage.type || + (opts.bgndImage.height==opts.bgndImage.height && + opts.bgndImage.width==opts.bgndImage.width && + opts.bgndImage.pixmap.file==opts.menuBgndImage.pixmap.file))) + ? opts.bgndImage : opts.menuBgndImage; + int imgWidth=IMG_FILE==img.type ? img.width : RINGS_WIDTH(img.type), + imgHeight=IMG_FILE==img.type ? img.height : RINGS_HEIGHT(img.type); + + switch(img.type) + { + case IMG_NONE: + break; + case IMG_FILE: + qtcLoadBgndImage(&img); + if(!img.pixmap.img.isNull()) + { + switch(img.pos) + { + case PP_TL: + p->drawPixmap(r.x(), r.y(), img.pixmap.img); + break; + case PP_TM: + p->drawPixmap(r.x()+((r.width()-img.pixmap.img.width())/2), r.y(), img.pixmap.img); + break; + default: + case PP_TR: + p->drawPixmap(r.right()-img.pixmap.img.width(), r.y(), img.pixmap.img); + break; + case PP_BL: + p->drawPixmap(r.x(), r.bottom()-img.pixmap.img.height(), img.pixmap.img); + break; + case PP_BM: + p->drawPixmap(r.x()+((r.width()-img.pixmap.img.width())/2), r.bottom()-img.pixmap.img.height(), img.pixmap.img); + break; + case PP_BR: + p->drawPixmap(r.right()-img.pixmap.img.width(), r.bottom()-img.pixmap.img.height(), img.pixmap.img); + break; + case PP_LM: + p->drawPixmap(r.left(), r.y()+((r.height()-img.pixmap.img.height())/2), img.pixmap.img); + break; + case PP_RM: + p->drawPixmap(r.right()-img.pixmap.img.width(), r.y()+((r.height()-img.pixmap.img.height())/2), img.pixmap.img); + break; + case PP_CENTRED: + p->drawPixmap(r.x()+((r.width()-img.pixmap.img.width())/2), + r.y()+((r.height()-img.pixmap.img.height())/2), + img.pixmap.img); + } + } + break; + case IMG_PLAIN_RINGS: + case IMG_BORDERED_RINGS: + if(img.pixmap.img.isNull()) + { + img.pixmap.img=QPixmap(imgWidth, imgHeight); + img.pixmap.img.fill(Qt::transparent); + QPainter pixPainter(&img.pixmap.img); + + pixPainter.setRenderHint(QPainter::Antialiasing); + drawBgndRing(pixPainter, 0, 0, 200, 140, isWindow); + + drawBgndRing(pixPainter, 210, 10, 230, 214, isWindow); + drawBgndRing(pixPainter, 226, 26, 198, 182, isWindow); + drawBgndRing(pixPainter, 300, 100, 50, 0, isWindow); + + drawBgndRing(pixPainter, 100, 96, 160, 144, isWindow); + drawBgndRing(pixPainter, 116, 112, 128, 112, isWindow); + + drawBgndRing(pixPainter, 250, 160, 200, 140, isWindow); + drawBgndRing(pixPainter, 310, 220, 80, 0, isWindow); + pixPainter.end(); + } + p->drawPixmap(r.right()-img.pixmap.img.width(), r.y()+1, img.pixmap.img); + break; + case IMG_SQUARE_RINGS: + if(img.pixmap.img.isNull()) + { + img.pixmap.img=QPixmap(imgWidth, imgHeight); + img.pixmap.img.fill(Qt::transparent); + QPainter pixPainter(&img.pixmap.img); + QColor col(Qt::white); + double halfWidth=RINGS_SQUARE_LINE_WIDTH/2.0; + + col.setAlphaF(RINGS_SQUARE_SMALL_ALPHA); + pixPainter.setRenderHint(QPainter::Antialiasing); + pixPainter.setPen(QPen(col, RINGS_SQUARE_LINE_WIDTH, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); + pixPainter.drawPath(buildPath(QRectF(halfWidth+0.5, halfWidth+0.5, + RINGS_SQUARE_SMALL_SIZE, RINGS_SQUARE_SMALL_SIZE), + WIDGET_OTHER, ROUNDED_ALL, RINGS_SQUARE_RADIUS)); + pixPainter.drawPath(buildPath(QRectF(halfWidth+0.5+(imgWidth-(RINGS_SQUARE_SMALL_SIZE+RINGS_SQUARE_LINE_WIDTH)), + halfWidth+0.5+(imgHeight-(RINGS_SQUARE_SMALL_SIZE+RINGS_SQUARE_LINE_WIDTH)), + RINGS_SQUARE_SMALL_SIZE, RINGS_SQUARE_SMALL_SIZE), + WIDGET_OTHER, ROUNDED_ALL, RINGS_SQUARE_RADIUS)); + col.setAlphaF(RINGS_SQUARE_LARGE_ALPHA); + pixPainter.setPen(QPen(col, RINGS_SQUARE_LINE_WIDTH, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin)); + pixPainter.drawPath(buildPath(QRectF(halfWidth+0.5+((imgWidth-RINGS_SQUARE_LARGE_SIZE-RINGS_SQUARE_LINE_WIDTH)/2.0), + halfWidth+0.5+((imgHeight-RINGS_SQUARE_LARGE_SIZE-RINGS_SQUARE_LINE_WIDTH)/2.0), + RINGS_SQUARE_LARGE_SIZE, RINGS_SQUARE_LARGE_SIZE), + WIDGET_OTHER, ROUNDED_ALL, RINGS_SQUARE_RADIUS)); + pixPainter.end(); + } + p->drawPixmap(r.right()-img.pixmap.img.width(), r.y()+1, img.pixmap.img); + break; + } +} + +void Style::drawBackground(QPainter *p, const QWidget *widget, BackgroundType type) const +{ + bool isWindow(BGND_MENU!=type), + previewMdi(isWindow && itsIsPreview && qobject_cast(widget)); + const QWidget *window = itsIsPreview ? widget : widget->window(); + int opacity = BGND_MENU==type + ? opts.menuBgndOpacity + : BGND_DIALOG==type + ? opts.dlgOpacity + : opts.bgndOpacity; + QRect bgndRect(widget->rect()), + imgRect(bgndRect); + + if(100!=opacity && !QtCurve::Utils::hasAlphaChannel(window)) + opacity=100; + + p->setClipRegion(widget->rect(), Qt::IntersectClip); + + if(isWindow) + { + if(!previewMdi) + { + WindowBorders borders=qtcGetWindowBorderSize(); + bgndRect.adjust(-borders.sides, -borders.titleHeight, borders.sides, borders.bottom); + } + else + { + bgndRect.adjust(0, -pixelMetric(PM_TitleBarHeight, 0L, widget), 0, 0); + } + if(BGND_IMG_ON_BORDER) + imgRect=bgndRect; + } + + drawBackground(p, isWindow ? window->palette().window().color() : popupMenuCols()[ORIGINAL_SHADE], bgndRect, opacity, type, + BGND_MENU!=type ? opts.bgndAppearance : opts.menuBgndAppearance); + drawBackgroundImage(p, isWindow, imgRect); +} + +QPainterPath Style::buildPath(const QRectF &r, EWidget w, int round, double radius) const +{ + QPainterPath path; + + if(WIDGET_RADIO_BUTTON==w || WIDGET_DIAL==w || + (WIDGET_MDI_WINDOW_BUTTON==w && opts.titlebarButtons&TITLEBAR_BUTTON_ROUND) || + CIRCULAR_SLIDER(w)) + { + path.addEllipse(r); + return path; + } + + if(ROUND_NONE==opts.round || (radius<0.01)) + round=ROUNDED_NONE; + + double diameter(radius*2); + + if (WIDGET_MDI_WINDOW_TITLE!=w && round&CORNER_BR) + path.moveTo(r.x()+r.width(), r.y()+r.height()-radius); + else + path.moveTo(r.x()+r.width(), r.y()+r.height()); + + if (round&CORNER_TR) + path.arcTo(r.x()+r.width()-diameter, r.y(), diameter, diameter, 0, 90); + else + path.lineTo(r.x()+r.width(), r.y()); + + if (round&CORNER_TL) + path.arcTo(r.x(), r.y(), diameter, diameter, 90, 90); + else + path.lineTo(r.x(), r.y()); + + if (WIDGET_MDI_WINDOW_TITLE!=w && round&CORNER_BL) + path.arcTo(r.x(), r.y()+r.height()-diameter, diameter, diameter, 180, 90); + else + path.lineTo(r.x(), r.y()+r.height()); + + if(WIDGET_MDI_WINDOW_TITLE!=w) + { + if (round&CORNER_BR) + path.arcTo(r.x()+r.width()-diameter, r.y()+r.height()-diameter, diameter, diameter, 270, 90); + else + path.lineTo(r.x()+r.width(), r.y()+r.height()); + } + + return path; +} + +QPainterPath Style::buildPath(const QRect &r, EWidget w, int round, double radius) const +{ + return buildPath(QRectF(r.x()+0.5, r.y()+0.5, r.width()-1, r.height()-1), w, round, radius); +} + +void Style::buildSplitPath(const QRect &r, int round, double radius, QPainterPath &tl, QPainterPath &br) const +{ + double xd(r.x()+0.5), + yd(r.y()+0.5), + diameter(radius*2); + bool rounded=diameter>0.0; + int width(r.width()-1), + height(r.height()-1); + + if (rounded && round&CORNER_TR) + { + tl.arcMoveTo(xd+width-diameter, yd, diameter, diameter, 45); + tl.arcTo(xd+width-diameter, yd, diameter, diameter, 45, 45); + if(width>diameter) + tl.lineTo(xd+width-diameter, yd); + } + else + tl.moveTo(xd+width, yd); + + if (rounded && round&CORNER_TL) + tl.arcTo(xd, yd, diameter, diameter, 90, 90); + else + tl.lineTo(xd, yd); + + if (rounded && round&CORNER_BL) + { + tl.arcTo(xd, yd+height-diameter, diameter, diameter, 180, 45); + br.arcMoveTo(xd, yd+height-diameter, diameter, diameter, 180+45); + br.arcTo(xd, yd+height-diameter, diameter, diameter, 180+45, 45); + } + else + { + tl.lineTo(xd, yd+height); + br.moveTo(xd, yd+height); + } + + if (rounded && round&CORNER_BR) + br.arcTo(xd+width-diameter, yd+height-diameter, diameter, diameter, 270, 90); + else + br.lineTo(xd+width, yd+height); + + if (rounded && round&CORNER_TR) + br.arcTo(xd+width-diameter, yd, diameter, diameter, 0, 45); + else + br.lineTo(xd+width, yd); +} + +void Style::drawBorder(QPainter *p, const QRect &r, const QStyleOption *option, int round, const QColor *custom, EWidget w, + EBorder borderProfile, bool doBlend, int borderVal) const +{ + if(ROUND_NONE==opts.round) + round=ROUNDED_NONE; + + State state(option->state); + bool enabled(state&State_Enabled), + entry(WIDGET_ENTRY==w || (WIDGET_SCROLLVIEW==w && opts.highlightScrollViews)), + hasFocus(enabled && entry && state&State_HasFocus), + hasMouseOver(enabled && entry && state&State_MouseOver && ENTRY_MO); + const QColor *cols(enabled && hasMouseOver && opts.coloredMouseOver && entry + ? itsMouseOverCols + : enabled && hasFocus && itsFocusCols && entry + ? itsFocusCols + : custom + ? custom + : APP_KRUNNER==theThemedApp ? itsBackgroundCols : backgroundColors(option)); + QColor border(WIDGET_DEF_BUTTON==w && IND_FONT_COLOR==opts.defBtnIndicator && enabled + ? option->palette.buttonText().color() + : cols[WIDGET_PROGRESSBAR==w + ? PBAR_BORDER + : !enabled && (WIDGET_BUTTON(w) || WIDGET_SLIDER_TROUGH==w) + ? DISABLED_BORDER + : itsMouseOverCols==cols && IS_SLIDER(w) + ? SLIDER_MO_BORDER_VAL + : borderVal]); + + p->setRenderHint(QPainter::Antialiasing, true); + p->setBrush(Qt::NoBrush); + + if(WIDGET_TAB_BOT==w || WIDGET_TAB_TOP==w) + cols=itsBackgroundCols; + + if(!(opts.thin&THIN_FRAMES) && (WIDGET_SCROLLVIEW!=w || !(opts.square&SQUARE_SCROLLVIEW) || opts.highlightScrollViews)) + switch(borderProfile) + { + case BORDER_FLAT: + break; + case BORDER_RAISED: + case BORDER_SUNKEN: + case BORDER_LIGHT: + { + int dark=FRAME_DARK_SHADOW; + QColor tl(cols[BORDER_RAISED==borderProfile || BORDER_LIGHT==borderProfile ? 0 : dark]), + br(cols[BORDER_RAISED==borderProfile ? dark : 0]); + QPainterPath topPath, + botPath; + + if( ((hasMouseOver || hasFocus) && WIDGET_ENTRY==w) || + (hasFocus && WIDGET_SCROLLVIEW==w)) + { + tl.setAlphaF(ENTRY_INNER_ALPHA); + br.setAlphaF(ENTRY_INNER_ALPHA); + } + else if(doBlend) + { + tl.setAlphaF(BORDER_BLEND_ALPHA(w)); + br.setAlphaF(BORDER_SUNKEN==borderProfile ? 0.0 : BORDER_BLEND_ALPHA(w)); + } + + QRect inner(r.adjusted(1, 1, -1, -1)); + + buildSplitPath(inner, round, qtcGetRadius(&opts, inner.width(), inner.height(), w, RADIUS_INTERNAL), topPath, botPath); + + p->setPen((enabled || BORDER_SUNKEN==borderProfile) /*&& + (BORDER_RAISED==borderProfile || BORDER_LIGHT==borderProfile || hasFocus || APPEARANCE_FLAT!=app)*/ + ? tl + : option->palette.background().color()); + p->drawPath(topPath); + if(WIDGET_SCROLLVIEW==w || // Because of list view headers, need to draw dark line on right! + (! ( (WIDGET_ENTRY==w && !hasFocus && !hasMouseOver) || + (WIDGET_ENTRY!=w && doBlend && BORDER_SUNKEN==borderProfile) ) ) ) + { + if(!hasFocus && !hasMouseOver && BORDER_LIGHT!=borderProfile && WIDGET_SCROLLVIEW!=w) + p->setPen(/*WIDGET_SCROLLVIEW==w && !hasFocus + ? checkColour(option, QPalette::Window) + : WIDGET_ENTRY==w && !hasFocus + ? checkColour(option, QPalette::Base) + : */enabled && (BORDER_SUNKEN==borderProfile || hasFocus || /*APPEARANCE_FLAT!=app ||*/ + WIDGET_TAB_TOP==w || WIDGET_TAB_BOT==w) + ? br + : checkColour(option, QPalette::Window)); + p->drawPath(botPath); + } + } + } + + if(BORDER_SUNKEN==borderProfile && + (WIDGET_FRAME==w || ((WIDGET_ENTRY==w || WIDGET_SCROLLVIEW==w) && !opts.etchEntry && !hasFocus && !hasMouseOver))) + { + QPainterPath topPath, + botPath; + QColor col(border); + + col.setAlphaF(LOWER_BORDER_ALPHA); + buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL), topPath, botPath); + p->setPen(/*enabled ? */border/* : col*/); + p->drawPath(topPath); +// if(enabled) + p->setPen(col); + p->drawPath(botPath); + } + else + { + p->setPen(border); + p->drawPath(buildPath(r, w, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL))); + } + + p->setRenderHint(QPainter::Antialiasing, false); +} + +void Style::drawMdiControl(QPainter *p, const QStyleOptionTitleBar *titleBar, SubControl sc, const QWidget *widget, + ETitleBarButtons btn, const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols, + int adjust, bool activeWindow) const +{ + bool hover((titleBar->activeSubControls&sc) && (titleBar->state&State_MouseOver)); + + if(!activeWindow && !hover && opts.titlebarButtons&TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW) + return; + + QRect rect(subControlRect(CC_TitleBar, titleBar, sc, widget)); + + if (rect.isValid()) + { + rect.adjust(adjust, adjust, -adjust, -adjust); + + bool sunken((titleBar->activeSubControls&sc) && (titleBar->state&State_Sunken)), + colored(coloredMdiButtons(titleBar->state&State_Active, hover)), + useBtnCols(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR && + (hover || + !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER) || + opts.titlebarButtons&TITLEBAR_BUTTON_COLOR)); + const QColor *buttonColors=colored && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL) + ? itsTitleBarButtonsCols[btn] : (useBtnCols ? btnCols : bgndCols); + const QColor &icnColor=opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR + ? opts.titlebarButtonColors[btn+(NUM_TITLEBAR_BUTTONS*(titleBar->state&State_Active ? 1 : 2))] + : colored && opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL + ? itsTitleBarButtonsCols[btn][ORIGINAL_SHADE] + : SC_TitleBarCloseButton==sc && hover && !sunken && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) + ? CLOSE_COLOR + : SC_TitleBarCloseButton!=sc && hover && !sunken && itsMouseOverCols && + !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) && + opts.titlebarButtons&TITLEBAR_BUTTON_USE_HOVER_COLOR + ? itsMouseOverCols[ORIGINAL_SHADE] + : iconColor; + + bool drewFrame=drawMdiButton(p, rect, hover, sunken, buttonColors); + drawMdiIcon(p, icnColor, (drewFrame ? buttonColors : bgndCols)[ORIGINAL_SHADE], + rect, hover, sunken, subControlToIcon(sc), true, drewFrame); + } +} + +void Style::drawDwtControl(QPainter *p, const QFlags &state, const QRect &rect, ETitleBarButtons btn, Icon icon, + const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols) const +{ + bool sunken(state&State_Sunken), + hover(state&State_MouseOver), + colored(coloredMdiButtons(state&State_Active, hover)), + useBtnCols(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR && + (hover || + !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER) || + opts.titlebarButtons&TITLEBAR_BUTTON_COLOR)); + const QColor *buttonColors=colored && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL) + ? itsTitleBarButtonsCols[btn] : (useBtnCols ? btnCols : bgndCols); + const QColor &icnColor=opts.dwtSettings&DWT_ICON_COLOR_AS_PER_TITLEBAR && opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR + ? opts.titlebarButtonColors[btn+(NUM_TITLEBAR_BUTTONS/**(titleBar->state&State_Active ? 1 : 2)*/)] + : colored && opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL + ? itsTitleBarButtonsCols[btn][ORIGINAL_SHADE] + : (TITLEBAR_CLOSE==btn && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) && (hover || sunken) + ? CLOSE_COLOR + : iconColor); + + bool drewFrame=drawMdiButton(p, rect, hover, sunken, buttonColors); + drawMdiIcon(p, icnColor, (drewFrame ? buttonColors : bgndCols)[ORIGINAL_SHADE], rect, hover, sunken, icon, false, drewFrame); +} + +bool Style::drawMdiButton(QPainter *painter, const QRect &r, bool hover, bool sunken, const QColor *cols) const +{ + if(!(opts.titlebarButtons&TITLEBAR_BUTTON_NO_FRAME) && + (hover || sunken || !(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_FRAME))) + { + QStyleOption opt; + + opt.rect=r; // .adjusted(1, 1, -1, -1); + if(opts.titlebarButtons&TITLEBAR_BUTTON_ROUND) + opt.rect.adjust(1, 1, -1, -1); + opt.state=State_Enabled|State_Horizontal|State_Raised; + if(hover) + opt.state|=State_MouseOver; + if(sunken) + opt.state|=State_Sunken; + + drawLightBevel(painter, opt.rect, &opt, 0L, ROUNDED_ALL, getFill(&opt, cols), cols, true, WIDGET_MDI_WINDOW_BUTTON); + return true; + } + + return false; +} + +void Style::drawMdiIcon(QPainter *painter, const QColor &color, const QColor &bgnd, const QRect &r, bool hover, bool sunken, Icon icon, + bool stdSize, bool drewFrame) const +{ + if(!(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL_FULL) || hover || sunken) + { + bool faded=!sunken && !hover && opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL; + + if(!sunken && !faded && EFFECT_NONE!=opts.titlebarEffect) + // // && hover && !(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL) && !customCol) + { + EEffect effect=opts.titlebarEffect; + + if(EFFECT_ETCH==opts.titlebarEffect && drewFrame) + effect=EFFECT_SHADOW; + + drawIcon(painter, blendColors(WINDOW_SHADOW_COLOR(effect), bgnd, WINDOW_TEXT_SHADOW_ALPHA(effect)), + EFFECT_SHADOW==effect + ? r.adjusted(1, 1, 1, 1) + : r.adjusted(0, 1, 0, 1), + sunken, icon, stdSize); + } + + QColor col(color); + + if(faded) + col=blendColors(col, bgnd, HOVER_BUTTON_ALPHA(col)); + + drawIcon(painter, col, r, sunken, icon, stdSize); + } +} + +void Style::drawIcon(QPainter *painter, const QColor &color, const QRect &r, bool sunken, Icon icon, bool stdSize) const +{ + static const int constIconSize=9; + static const int constSmallIconSize=7; + + painter->setPen(color); + + QSize iconSize(stdSize + ? constIconSize + : constSmallIconSize, + stdSize + ? constIconSize + : (ICN_RESTORE==icon && !(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) + ? constSmallIconSize+1 + : constSmallIconSize)); + QRect br(r.x()+((r.width()-iconSize.width())>>1), + r.y()+((r.height()-iconSize.height())>>1), + iconSize.width(), iconSize.height()); + if(sunken) + br.adjust(1, 1, 1, 1); + + switch(icon) + { + case ICN_MIN: + if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) + drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, PE_IndicatorArrowDown, color, false); + else + drawRect(painter, QRect(br.left(), br.bottom()-1, br.width(), 2)); + break; + case ICN_MAX: + if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) + drawArrow(painter, opts.vArrows ? br.adjusted(0, -1, 0, -1) : br, PE_IndicatorArrowUp, color, false); + else + { + drawRect(painter, br); + painter->drawLine(br.left() + 1, br.top() + 1, br.right() - 1, br.top() + 1); + } + break; + case ICN_CLOSE: + if(stdSize && opts.titlebarButtons&TITLEBAR_BUTTON_SUNKEN_BACKGROUND) + br.adjust(1, 1, -1, -1); + painter->save(); + painter->setClipRect(br); + painter->setPen(QPen(color, 2)); + painter->drawLine(br.left(), br.top(), br.right(), br.bottom()); + painter->drawLine(br.right(), br.top(), br.left(), br.bottom()); + painter->restore(); + break; + case ICN_RESTORE: + if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) + { + painter->drawLine(br.x()+1, br.y(), br.x()+br.width()-2, br.y()); + painter->drawLine(br.x()+1, br.y()+br.height()-1, br.x()+br.width()-2, br.y()+br.height()-1); + painter->drawLine(br.x(), br.y()+1, br.x(), br.y()+br.height()-2); + painter->drawLine(br.x()+br.width()-1, br.y()+1, br.x()+br.width()-1, br.y()+br.height()-2); + drawRect(painter, br.adjusted(1, 1, -1, -1)); + } + else + { + drawRect(painter, QRect(br.x(), br.y()+3, br.width()-2, br.height()-3)); + painter->drawLine(br.x()+1, br.y()+4, br.x()+br.width()-4, br.y()+4); + painter->drawLine(br.x()+2, br.y(), br.x()+br.width()-1, br.y()); + painter->drawLine(br.x()+2, br.y()+1, br.x()+br.width()-1, br.y()+1); + painter->drawLine(br.x()+br.width()-1, br.y()+2, br.x()+br.width()-1, br.y()+(stdSize ? 5 : 4)); + painter->drawPoint(br.x()+br.width()-2, br.y()+(stdSize ? 5 : 4)); + painter->drawPoint(br.x()+2, br.y()+2); + } + break; + case ICN_UP: + drawArrow(painter, br, PE_IndicatorArrowUp, color, false); + break; + case ICN_DOWN: + drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, PE_IndicatorArrowDown, color, false); + break; + case ICN_RIGHT: + drawArrow(painter, br, PE_IndicatorArrowRight, color, false); + break; + case ICN_MENU: + for(int i=1; i<=constIconSize; i+=3) + painter->drawLine(br.left() + 1, br.top() + i, br.right() - 1, br.top() + i); + break; + case ICN_SHADE: + case ICN_UNSHADE: + { + bool isDwt=opts.dwtSettings&DWT_BUTTONS_AS_PER_TITLEBAR; + br.adjust(0, -2, 0, 0); + drawRect(painter, isDwt ? QRect(br.left(), br.bottom(), br.width(), 2) : QRect(br.left()+1, br.bottom()-1, br.width()-2, 2)); + br.adjust(0, ICN_SHADE==icon ? -3 : -5, 0, 0); + drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, + ICN_SHADE==icon ? PE_IndicatorArrowDown : PE_IndicatorArrowUp, color, false); + break; + } + default: + break; + } +} + +void Style::drawEntryField(QPainter *p, const QRect &rx, const QWidget *widget, const QStyleOption *option, + int round, bool fill, bool doEtch, EWidget w) const +{ + QRect r(rx); + + if(doEtch && opts.etchEntry) + r.adjust(1, 1, -1, -1); + + p->setRenderHint(QPainter::Antialiasing, true); + if(fill) + p->fillPath(buildPath(QRectF(r).adjusted(1, 1, -1, -1), WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, round, + qtcGetRadius(&opts, r.width()-2, r.height()-2, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, RADIUS_INTERNAL)), + option->palette.brush(QPalette::Base)); + else + { + p->setPen(WIDGET_SCROLLVIEW!=w || !(opts.square&SQUARE_SCROLLVIEW) || opts.highlightScrollViews ? checkColour(option, QPalette::Base) + : backgroundColors(option)[ORIGINAL_SHADE]); + p->drawPath(buildPath(r.adjusted(1, 1, -1, -1), WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, round, + qtcGetRadius(&opts, r.width()-2, r.height()-2, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, RADIUS_INTERNAL))); + } + p->setRenderHint(QPainter::Antialiasing, false); + + if(doEtch && opts.etchEntry) + drawEtch(p, rx, widget, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, false); + + drawBorder(p, r, option, round, 0L, w, BORDER_SUNKEN); +} + +void Style::drawMenuItem(QPainter *p, const QRect &r, const QStyleOption *option, MenuItemType type, int round, const QColor *cols) const +{ + int fill=opts.useHighlightForMenu && ((MENU_BAR!=type) || itsHighlightCols==cols || APP_OPENOFFICE==theThemedApp) ? ORIGINAL_SHADE : 4, + border=opts.borderMenuitems ? 0 : fill; + + if(itsHighlightCols!=cols && MENU_BAR==type && !(option->state&(State_On|State_Sunken)) && + !opts.colorMenubarMouseOver && (opts.borderMenuitems || !IS_FLAT(opts.menuitemAppearance))) + fill=ORIGINAL_SHADE; + + if(MENU_BAR!=type && APPEARANCE_FADE==opts.menuitemAppearance) + { + bool reverse=Qt::RightToLeft==option->direction; + QColor trans(Qt::white); + QRect r2(ROUNDED ? r.adjusted(1, 1, -1, -1) : r); + QRectF rf(r2); + double fadePercent=((double)MENUITEM_FADE_SIZE)/rf.width(); + QLinearGradient grad(r2.topLeft(), r2.topRight()); + + trans.setAlphaF(0.0); + grad.setColorAt(0, reverse ? trans : cols[fill]); + grad.setColorAt(reverse ? fadePercent : 1.0-fadePercent, cols[fill]); + grad.setColorAt(1, reverse ? cols[fill] : trans); + if(ROUNDED) + { + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + p->fillPath(buildPath(rf, WIDGET_OTHER, reverse ? ROUNDED_RIGHT : ROUNDED_LEFT, 4), QBrush(grad)); + p->restore(); + } + else + p->fillRect(r2, QBrush(grad)); + } + else if(MENU_BAR==type || opts.borderMenuitems) + { + bool stdColor(MENU_BAR!=type || (SHADE_BLEND_SELECTED!=opts.shadeMenubars && SHADE_SELECTED!=opts.shadeMenubars)); + + QStyleOption opt(*option); + + opt.state|=State_Horizontal|State_Raised; + opt.state&=~(State_Sunken|State_On); + + if(stdColor && opts.borderMenuitems) + drawLightBevel(p, r, &opt, 0L, round, cols[fill], cols, stdColor, WIDGET_MENU_ITEM); + else + { + QRect fr(r); + + fr.adjust(1, 1, -1, -1); + + if(fr.width()>0 && fr.height()>0) + drawBevelGradient(cols[fill], p, fr, true, false, opts.menuitemAppearance, WIDGET_MENU_ITEM); + drawBorder(p, r, &opt, round, cols, WIDGET_MENU_ITEM, BORDER_FLAT, false, border); + } + } + else + { + // For now dont round combos - getting weird effects with shadow/clipping in Gtk2 style :-( + if(/*MENU_COMBO==type || */opts.square&SQUARE_POPUP_MENUS) + drawBevelGradient(cols[fill], p, r, true, false, opts.menuitemAppearance, WIDGET_MENU_ITEM); + else + { + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + drawBevelGradient(cols[fill], p, r, buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, + MENU_AND_TOOLTIP_RADIUS-(opts.round>ROUND_SLIGHT ? 1.0 : 0.5)), true, false, + opts.menuitemAppearance, WIDGET_MENU_ITEM, false); + p->restore(); + } + } +} + +void Style::drawProgress(QPainter *p, const QRect &r, const QStyleOption *option, bool vertical, bool reverse) const +{ + QStyleOption opt(*option); + QRect rx(r); + + opt.state|=State_Raised; + + if(vertical) + opt.state&=~State_Horizontal; + else + opt.state|=State_Horizontal; + + if(reverse) + opt.state|=STATE_REVERSE; + else + opt.state&=~STATE_REVERSE; + + if((vertical ? r.height() : r.width())<1) + return; + + if(vertical && r.height()<3) + rx.setHeight(3); + + if(!vertical && rx.width()<3) + rx.setWidth(3); + + // KTorrent's progressbars seem to have state==State_None + const QColor *use=option->state&State_Enabled || State_None==option->state || ECOLOR_BACKGROUND==opts.progressGrooveColor + ? itsProgressCols + ? itsProgressCols + : highlightColors(option, true) + : itsBackgroundCols; + + drawLightBevel(p, rx, &opt, 0L, ROUNDED_ALL, use[ORIGINAL_SHADE], use, opts.borderProgress, WIDGET_PROGRESSBAR); + + if(opts.glowProgress && (vertical ? rx.height() : rx.width())>3) + { + QRect ri(opts.borderProgress ? rx.adjusted(1, 1, -1, -1) : rx); + QLinearGradient grad(0, 0, vertical ? 0 : 1, vertical ? 1 : 0); + QColor glow(Qt::white), + blank(Qt::white); + + blank.setAlphaF(0); + glow.setAlphaF(GLOW_PROG_ALPHA); + grad.setCoordinateMode(QGradient::ObjectBoundingMode); + grad.setColorAt(0, (reverse ? GLOW_END : GLOW_START)==opts.glowProgress ? glow : blank); + if(GLOW_MIDDLE==opts.glowProgress) + grad.setColorAt(0.5, glow); + grad.setColorAt(1, (reverse ? GLOW_START : GLOW_END)==opts.glowProgress ? glow : blank); + p->fillRect(ri, grad); + } + + if(!opts.borderProgress) + { + p->setPen(use[PBAR_BORDER]); + if(!vertical) + { + p->drawLine(rx.topLeft(), rx.topRight()); + p->drawLine(rx.bottomLeft(), rx.bottomRight()); + } + else + { + p->drawLine(rx.topLeft(), rx.bottomLeft()); + p->drawLine(rx.topRight(), rx.bottomRight()); + } + } +} + +static QPolygon rotate(const QPolygon &p, double angle) +{ + QMatrix matrix; + matrix.rotate(angle); + return matrix.map(p); +} + +void Style::drawArrow(QPainter *p, const QRect &rx, PrimitiveElement pe, QColor col, bool small, bool kwin) const +{ + QPolygon a; + QPainterPath path; + QRect r(rx); + int m=!small && kwin ? ((r.height()-7)/2) : 0; + + if(small) + a.setPoints(opts.vArrows ? 6 : 3, 2,0, 0,-2, -2,0, -2,1, 0,-1, 2,1); + else + a.setPoints(opts.vArrows ? 8 : 3, 3+m,1+m, 0,-2, -(3+m),1+m, -(3+m),2+m, -(2+m),2+m, 0,0, 2+m,2+m, 3+m,2+m); + + switch(pe) + { + case PE_IndicatorArrowUp: + if(m) + r.adjust(0, -m, 0, -m); + break; + case PE_IndicatorArrowDown: + if(m) + r.adjust(0, m, 0, m); + a=rotate(a, 180); + break; + case PE_IndicatorArrowRight: + a=rotate(a, 90); + break; + case PE_IndicatorArrowLeft: + a=rotate(a, 270); + break; + default: + return; + } + + a.translate((r.x()+(r.width()>>1)), (r.y()+(r.height()>>1))); + +#ifdef QTC_OLD_NVIDIA_ARROW_FIX + path.moveTo(a[0].x()+0.5, a[0].y()+0.5); + for(int i=1; isave(); + col.setAlpha(255); +#ifdef QTC_OLD_NVIDIA_ARROW_FIX + p->setRenderHint(QPainter::Antialiasing, true); +#endif + p->setPen(col); + p->setBrush(col); +#ifdef QTC_OLD_NVIDIA_ARROW_FIX + p->fillPath(path, col); +#endif + p->setRenderHint(QPainter::Antialiasing, false); + p->drawPolygon(a); + p->restore(); +} + +void Style::drawSbSliderHandle(QPainter *p, const QRect &rOrig, const QStyleOption *option, bool slider) const +{ + QStyleOption opt(*option); + QRect r(rOrig); + + if(opt.state&(State_Sunken|State_On)) + opt.state|=State_MouseOver; + + if(r.width()>r.height()) + opt.state|=State_Horizontal; + + opt.state&=~(State_Sunken|State_On); + opt.state|=State_Raised; + + if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) + if(slider->minimum==slider->maximum) + opt.state&=~(State_MouseOver|State_Enabled); + + int min(MIN_SLIDER_SIZE(opts.sliderThumbs)); + const QColor *use(sliderColors(&opt)); + + drawLightBevel(p, r, &opt, 0L, (slider && (!(opts.square&SQUARE_SLIDER) || + (SLIDER_ROUND==opts.sliderStyle || SLIDER_ROUND_ROTATED==opts.sliderStyle))) +#ifndef SIMPLE_SCROLLBARS + || (!slider && !(opts.square&SQUARE_SB_SLIDER) && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)) +#endif + ? ROUNDED_ALL : ROUNDED_NONE, + getFill(&opt, use, false, SHADE_DARKEN==opts.shadeSliders), use, true, + slider ? WIDGET_SLIDER : WIDGET_SB_SLIDER); + + if(LINE_NONE!=opts.sliderThumbs && (slider || ((opt.state&State_Horizontal && r.width()>=min)|| r.height()>=min)) && + (!slider || SLIDER_CIRCULAR!=opts.sliderStyle)) + { + const QColor *markers(use); + bool horiz(opt.state&State_Horizontal); + + if(LINE_SUNKEN==opts.sliderThumbs) + if(horiz) + r.adjust(0, -1, 0, 0); + else + r.adjust(-1, 0, 0, 0); + else + r.adjust(horiz ? 1 : 0, horiz ? 0 : 1, 0, 0); + + switch(opts.sliderThumbs) + { + case LINE_1DOT: + p->drawPixmap(r.x()+((r.width()-5)/2), r.y()+((r.height()-5)/2), *getPixmap(markers[STD_BORDER], PIX_DOT, 1.0)); + break; + case LINE_FLAT: + drawLines(p, r, !horiz, 3, 5, markers, 0, 5, opts.sliderThumbs); + break; + case LINE_SUNKEN: + drawLines(p, r, !horiz, 4, 3, markers, 0, 3, opts.sliderThumbs); + break; + case LINE_DOTS: + default: + drawDots(p, r, !horiz, slider ? 3 : 5, slider ? 4 : 2, markers, 0, 5); + } + } +} + +void Style::drawSliderHandle(QPainter *p, const QRect &r, const QStyleOptionSlider *option) const +{ + bool horiz(SLIDER_TRIANGULAR==opts.sliderStyle ? r.height()>r.width() : r.width()>r.height()); + QStyleOption opt(*option); + + if(!(option->activeSubControls&SC_SliderHandle) || !(opt.state&State_Enabled)) + opt.state&=~State_MouseOver; + + if(SLIDER_TRIANGULAR==opts.sliderStyle) + { + if(r.width()>r.height()) + opt.state|=State_Horizontal; + opt.state&=~(State_Sunken|State_On); + + opt.state|=State_Raised; + + const QColor *use(sliderColors(&opt)), + *border(opt.state&State_MouseOver && (MO_GLOW==opts.coloredMouseOver || + MO_COLORED==opts.coloredMouseOver) + ? itsMouseOverCols : use); + const QColor &fill(getFill(&opt, use, false, SHADE_DARKEN==opts.shadeSliders)); + int x(r.x()), + y(r.y()); + PrimitiveElement direction(horiz ? PE_IndicatorArrowDown : PE_IndicatorArrowRight); + QPolygon clipRegion; + bool drawLight(MO_PLASTIK!=opts.coloredMouseOver || !(opt.state&State_MouseOver)); + int size(SLIDER_TRIANGULAR==opts.sliderStyle ? 15 : 13), + borderVal(itsMouseOverCols==border ? SLIDER_MO_BORDER_VAL : BORDER_VAL(opt.state&State_Enabled)); + + if(option->tickPosition & QSlider::TicksBelow) + direction=horiz ? PE_IndicatorArrowDown : PE_IndicatorArrowRight; + else if(option->tickPosition & QSlider::TicksAbove) + direction=horiz ? PE_IndicatorArrowUp : PE_IndicatorArrowLeft; + + if(MO_GLOW==opts.coloredMouseOver && DO_EFFECT) + x++, y++; + + switch(direction) + { + default: + case PE_IndicatorArrowDown: + clipRegion.setPoints(7, x, y+2, x+2, y, x+8, y, x+10, y+2, x+10, y+9, x+5, y+14, x, y+9); + break; + case PE_IndicatorArrowUp: + clipRegion.setPoints(7, x, y+12, x+2, y+14, x+8, y+14, x+10, y+12, x+10, y+5, x+5, y, x, y+5); + break; + case PE_IndicatorArrowLeft: + clipRegion.setPoints(7, x+12, y, x+14, y+2, x+14, y+8, x+12, y+10, x+5, y+10, x, y+5, x+5, y ); + break; + case PE_IndicatorArrowRight: + clipRegion.setPoints(7, x+2, y, x, y+2, x, y+8, x+2, y+10, x+9, y+10, x+14, y+5, x+9, y); + } + + p->save(); + p->setClipRegion(QRegion(clipRegion)); // , QPainter::CoordPainter); + if(IS_FLAT(opts.sliderAppearance)) + { + p->fillRect(r, fill); + + if(MO_PLASTIK==opts.coloredMouseOver && opt.state&State_MouseOver && !opts.colorSliderMouseOver) + { + int col(SLIDER_MO_SHADE), + len(SLIDER_MO_LEN); + + if(horiz) + { + p->fillRect(QRect(x+1, y+1, len, size-2), itsMouseOverCols[col]); + p->fillRect(QRect(x+r.width()-(1+len), y+1, len, r.height()-2), itsMouseOverCols[col]); + } + else + { + p->fillRect(QRect(x+1, y+1, size-2, len), itsMouseOverCols[col]); + p->fillRect(QRect(x+1, y+r.height()-(1+len), r.width()-2, len), itsMouseOverCols[col]); + } + } + } + else + { + drawBevelGradient(fill, p, QRect(x, y, horiz ? r.width()-1 : size, horiz ? size : r.height()-1), + horiz, false, MODIFY_AGUA(opts.sliderAppearance)); + + if(MO_PLASTIK==opts.coloredMouseOver && opt.state&State_MouseOver && !opts.colorSliderMouseOver) + { + int col(SLIDER_MO_SHADE), + len(SLIDER_MO_LEN); + + if(horiz) + { + drawBevelGradient(itsMouseOverCols[col], p, QRect(x+1, y+1, len, size-2), + horiz, false, MODIFY_AGUA(opts.sliderAppearance)); + drawBevelGradient(itsMouseOverCols[col], p, QRect(x+r.width()-(1+len), y+1, len, size-2), + horiz, false, MODIFY_AGUA(opts.sliderAppearance)); + } + else + { + drawBevelGradient(itsMouseOverCols[col], p, QRect(x+1, y+1, size-2, len), + horiz, false, MODIFY_AGUA(opts.sliderAppearance)); + drawBevelGradient(itsMouseOverCols[col], p,QRect(x+1, y+r.height()-(1+len), size-2, len), + horiz, false, MODIFY_AGUA(opts.sliderAppearance)); + } + } + } + + p->restore(); + p->save(); + + QPainterPath path; + double xd(x+0.5), + yd(y+0.5), + radius(2.5), + diameter(radius*2), + xdg(x-0.5), + ydg(y-0.5), + radiusg(radius+1), + diameterg(radiusg*2); + bool glowMo(MO_GLOW==opts.coloredMouseOver && opt.state&State_MouseOver); + QColor glowCol(border[GLOW_MO]); + + glowCol.setAlphaF(GLOW_ALPHA(false)); + + p->setPen(glowMo ? glowCol : border[borderVal]); + + switch(direction) + { + default: + case PE_IndicatorArrowDown: + p->setRenderHint(QPainter::Antialiasing, true); + if(glowMo) + { + path.moveTo(xdg+12-radiusg, ydg); + path.arcTo(xdg, ydg, diameterg, diameterg, 90, 90); + path.lineTo(xdg, ydg+10.5); + path.lineTo(xdg+6, ydg+16.5); + path.lineTo(xdg+12, ydg+10.5); + path.arcTo(xdg+12-diameterg, ydg, diameterg, diameterg, 0, 90); + p->drawPath(path); + path=QPainterPath(); + p->setPen(border[borderVal]); + } + path.moveTo(xd+10-radius, yd); + path.arcTo(xd, yd, diameter, diameter, 90, 90); + path.lineTo(xd, yd+9); + path.lineTo(xd+5, yd+14); + path.lineTo(xd+10, yd+9); + path.arcTo(xd+10-diameter, yd, diameter, diameter, 0, 90); + p->drawPath(path); + p->setRenderHint(QPainter::Antialiasing, false); + if(drawLight) + { + p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); + p->drawLine(x+1, y+2, x+1, y+8); + p->drawLine(x+2, y+1, x+7, y+1); + } + break; + case PE_IndicatorArrowUp: + p->setRenderHint(QPainter::Antialiasing, true); + if(glowMo) + { + path.moveTo(xdg, ydg+6); + path.arcTo(xdg, ydg+16-diameterg, diameterg, diameterg, 180, 90); + path.arcTo(xdg+12-diameterg, ydg+16-diameterg, diameterg, diameterg, 270, 90); + path.lineTo(xdg+12, ydg+5.5); + path.lineTo(xdg+6, ydg-0.5); + path.lineTo(xdg, ydg+5.5); + p->drawPath(path); + path=QPainterPath(); + p->setPen(border[borderVal]); + } + path.moveTo(xd, yd+5); + path.arcTo(xd, yd+14-diameter, diameter, diameter, 180, 90); + path.arcTo(xd+10-diameter, yd+14-diameter, diameter, diameter, 270, 90); + path.lineTo(xd+10, yd+5); + path.lineTo(xd+5, yd); + path.lineTo(xd, yd+5); + p->drawPath(path); + p->setRenderHint(QPainter::Antialiasing, false); + if(drawLight) + { + p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); + p->drawLine(x+5, y+1, x+1, y+5); + p->drawLine(x+1, y+5, x+1, y+11); + } + break; + case PE_IndicatorArrowLeft: + p->setRenderHint(QPainter::Antialiasing, true); + if(glowMo) + { + path.moveTo(xdg+6, ydg+12); + path.arcTo(xdg+16-diameterg, ydg+12-diameterg, diameterg, diameterg, 270, 90); + path.arcTo(xdg+16-diameterg, ydg, diameterg, diameterg, 0, 90); + path.lineTo(xdg+5.5, ydg); + path.lineTo(xdg-0.5, ydg+6); + path.lineTo(xdg+5.5, ydg+12); + p->drawPath(path); + path=QPainterPath(); + p->setPen(border[borderVal]); + } + path.moveTo(xd+5, yd+10); + path.arcTo(xd+14-diameter, yd+10-diameter, diameter, diameter, 270, 90); + path.arcTo(xd+14-diameter, yd, diameter, diameter, 0, 90); + path.lineTo(xd+5, yd); + path.lineTo(xd, yd+5); + path.lineTo(xd+5, yd+10); + p->drawPath(path); + p->setRenderHint(QPainter::Antialiasing, false); + if(drawLight) + { + p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); + p->drawLine(x+1, y+5, x+5, y+1); + p->drawLine(x+5, y+1, x+11, y+1); + } + break; + case PE_IndicatorArrowRight: + p->setRenderHint(QPainter::Antialiasing, true); + if(glowMo) + { + path.moveTo(xdg+11, ydg); + path.arcTo(xdg, ydg, diameterg, diameterg, 90, 90); + path.arcTo(xdg, ydg+12-diameterg, diameterg, diameterg, 180, 90); + path.lineTo(xdg+10.5, ydg+12); + path.lineTo(xdg+16.5, ydg+6); + path.lineTo(xdg+10.5, ydg); + p->drawPath(path); + path=QPainterPath(); + p->setPen(border[borderVal]); + } + path.moveTo(xd+9, yd); + path.arcTo(xd, yd, diameter, diameter, 90, 90); + path.arcTo(xd, yd+10-diameter, diameter, diameter, 180, 90); + path.lineTo(xd+9, yd+10); + path.lineTo(xd+14, yd+5); + path.lineTo(xd+9, yd); + p->drawPath(path); + p->setRenderHint(QPainter::Antialiasing, false); + if(drawLight) + { + p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); + p->drawLine(x+2, y+1, x+7, y+1); + p->drawLine(x+1, y+2, x+1, y+8); + } + break; + } + + p->restore(); + } + else + { + if(ROTATED_SLIDER) + opt.state^=State_Horizontal; + + drawSbSliderHandle(p, r, &opt, true); + } +} + +void Style::drawSliderGroove(QPainter *p, const QRect &groove, const QRect &handle, const QStyleOptionSlider *slider, + const QWidget *widget) const +{ + bool horiz(Qt::Horizontal==slider->orientation); + QRect grv(groove); + QStyleOptionSlider opt(*slider); + + opt.state&=~(State_HasFocus|State_On|State_Sunken|State_MouseOver); + + if(horiz) + { + int dh=(grv.height()-5)>>1; + grv.adjust(0, dh, 0, -dh); + opt.state|=State_Horizontal; + + if(DO_EFFECT) + grv.adjust(0, -1, 0, 1); + } + else + { + int dw=(grv.width()-5)>>1; + grv.adjust(dw, 0, -dw, 0); + opt.state&=~State_Horizontal; + + if(DO_EFFECT) + grv.adjust(-1, 0, 1, 0); + } + + if(grv.height()>0 && grv.width()>0) + { + drawLightBevel(p, grv, &opt, widget, + opts.square&SQUARE_SLIDER ? ROUNDED_NONE : ROUNDED_ALL, + itsBackgroundCols[slider->state&State_Enabled ? 2 : ORIGINAL_SHADE], + itsBackgroundCols, true, WIDGET_SLIDER_TROUGH); + + if(opts.fillSlider && slider->maximum!=slider->minimum && slider->state&State_Enabled) + { + const QColor *usedCols=itsSliderCols ? itsSliderCols : itsHighlightCols; + + if (horiz) + if (slider->upsideDown) + grv=QRect(handle.right()-4, grv.top(), (grv.right()-handle.right())+4, grv.height()); + else + grv=QRect(grv.left(), grv.top(), handle.left()+4, grv.height()); + else + if (slider->upsideDown) + grv=QRect(grv.left(), handle.bottom()-4, grv.width(), (grv.height() - handle.bottom())+4); + else + grv=QRect(grv.left(), grv.top(), grv.width(), (handle.top() - grv.top())+4); + + if(grv.height()>0 && grv.width()>0) + drawLightBevel(p, grv, &opt, widget, opts.square&SQUARE_SLIDER ? ROUNDED_NONE : ROUNDED_ALL, + usedCols[ORIGINAL_SHADE], usedCols, true, WIDGET_FILLED_SLIDER_TROUGH); + } + } +} + + +int Style::getOpacity(const QWidget *widget, QPainter *p) const +{ + if(opts.bgndOpacity==opts.dlgOpacity) + return opts.bgndOpacity; + + if(opts.bgndOpacity!=100 || opts.dlgOpacity!=100) + { + const QWidget *w=widget ? widget : getWidget(p); + + if(!w) + return opts.bgndOpacity; + else + return w->topLevelWidget() && Qt::Dialog==(w->topLevelWidget()->windowFlags() & Qt::WindowType_Mask) + ? opts.dlgOpacity : opts.bgndOpacity; + } + return 100; +} + +void Style::drawMenuOrToolBarBackground(const QWidget *widget, QPainter *p, const QRect &r, const QStyleOption *option, + bool menu, bool horiz) const +{ + // LibreOffice - when drawMenuOrToolBarBackground is called with menuRect, this is empty! + if(r.width()<1 || r.height()<1) + return; + + EAppearance app=menu ? opts.menubarAppearance : opts.toolbarAppearance; + if(!CUSTOM_BGND || !IS_FLAT(app) || (menu && SHADE_NONE!=opts.shadeMenubars)) + { + QRect rx(r); + QColor col(menu && (option->state&State_Enabled || SHADE_NONE!=opts.shadeMenubars) + ? menuColors(option, itsActive)[ORIGINAL_SHADE] + : option->palette.background().color()); + int opacity(getOpacity(widget, p)); + + if(menu && BLEND_TITLEBAR) + rx.adjust(0, -qtcGetWindowBorderSize().titleHeight, 0, 0); + + if(opacity<100) + col.setAlphaF(opacity/100.0); + drawBevelGradient(col, p, rx, horiz, false, MODIFY_AGUA(app)); + } +} + +void Style::drawHandleMarkers(QPainter *p, const QRect &rx, const QStyleOption *option, bool tb, ELine handles) const +{ + if(rx.width()<2 || rx.height()<2) + return; + + QRect r(rx); + + if(APP_OPENOFFICE==theThemedApp) + { + r.setX(r.x()+2); + r.setWidth(10); + } + + // CPD: Mouse over of toolbar handles not working - the whole toolbar seems to be active :-( + QStyleOption opt(*option); + + opt.state&=~State_MouseOver; + + const QColor *border(borderColors(&opt, itsBackgroundCols)); + + switch(handles) + { + case LINE_NONE: + break; + case LINE_1DOT: + p->drawPixmap(r.x()+((r.width()-5)/2), r.y()+((r.height()-5)/2), *getPixmap(border[STD_BORDER], PIX_DOT, 1.0)); + break; + case LINE_DOTS: + drawDots(p, r, !(option->state&State_Horizontal), 2, tb ? 5 : 3, border, tb ? -2 : 0, 5); + break; + case LINE_DASHES: + if(option->state&State_Horizontal) + drawLines(p, QRect(r.x()+(tb ? 2 : (r.width()-6)/2), r.y(), 3, r.height()), true, (r.height()-8)/2, + tb ? 0 : (r.width()-5)/2, border, 0, 5, handles); + else + drawLines(p, QRect(r.x(), r.y()+(tb ? 2 : (r.height()-6)/2), r.width(), 3), false, (r.width()-8)/2, + tb ? 0 : (r.height()-5)/2, border, 0, 5, handles); + break; + case LINE_FLAT: + drawLines(p, r, !(option->state&State_Horizontal), 2, tb ? 4 : 2, border, tb ? -2 : 0, 4, handles); + break; + default: + drawLines(p, r, !(option->state&State_Horizontal), 2, tb ? 4 : 2, border, tb ? -2 : 0, 3, handles); + } +} + +void Style::fillTab(QPainter *p, const QRect &r, const QStyleOption *option, const QColor &fill, bool horiz, EWidget tab, + bool tabOnly) const +{ + bool invertedSel=option->state&State_Selected && APPEARANCE_INVERTED==opts.appearance; + QColor col(invertedSel ? option->palette.background().color() : fill); + + if(opts.tabBgnd && !tabOnly) + col=shade(col, TO_FACTOR(opts.tabBgnd)); + + if(invertedSel) + p->fillRect(r, col); + else + { + bool selected(option->state&State_Selected); + EAppearance app(selected ? SEL_TAB_APP : NORM_TAB_APP); + + drawBevelGradient(col, p, r, horiz, selected, app, tab); + } +} + +void Style::colorTab(QPainter *p, const QRect &r, bool horiz, EWidget tab, int round) const +{ + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + QLinearGradient grad(r.topLeft(), horiz ? r.bottomLeft() : r.topRight()); + QColor start(itsHighlightCols[ORIGINAL_SHADE]), + end(itsHighlightCols[ORIGINAL_SHADE]); + + start.setAlphaF(TO_ALPHA(opts.colorSelTab)); + end.setAlphaF(0.0); + grad.setColorAt(0, WIDGET_TAB_TOP==tab ? start : end); + grad.setColorAt(1, WIDGET_TAB_TOP==tab ? end : start); + p->fillPath(buildPath(r, tab, round, qtcGetRadius(&opts, r.width(), r.height(), tab, RADIUS_EXTERNAL)), grad); + p->restore(); +} + +void Style::shadeColors(const QColor &base, QColor *vals) const +{ + SHADES + + bool useCustom(USE_CUSTOM_SHADES(opts)); + double hl=TO_FACTOR(opts.highlightFactor); + + for(int i=0; iversion>=TBAR_VERSION_HACK && + option->versionstate&State_Active, option->state&(State_MouseOver|State_Sunken))) + return itsTitleBarButtonsCols[option->version-TBAR_VERSION_HACK]; + + if(option && option->palette.button()!=itsButtonCols[ORIGINAL_SHADE]) + { + shadeColors(option->palette.button().color(), itsColoredButtonCols); + return itsColoredButtonCols; + } + + return itsButtonCols; +} + +QColor Style::titlebarIconColor(const QStyleOption *option) const +{ + if(option && option->version>=TBAR_VERSION_HACK) + { + if(opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR && option->versionversion-TBAR_VERSION_HACK]; + if(option->versionstate&State_Active, option->state&(State_MouseOver|State_Sunken))) + return itsTitleBarButtonsCols[option->version-TBAR_VERSION_HACK][ORIGINAL_SHADE]; + } + + return buttonColors(option)[ORIGINAL_SHADE]; +} + +const QColor * Style::popupMenuCols(const QStyleOption *option) const +{ + return USE_LIGHTER_POPUP_MENU || opts.shadePopupMenu || !option ? itsPopupMenuCols : backgroundColors(option); +} + +const QColor * Style::checkRadioColors(const QStyleOption *option) const +{ + return opts.crColor && option && option->state&State_Enabled && (option->state&State_On || option->state&State_NoChange) + ? itsCheckRadioSelCols + : buttonColors(option); +} + +const QColor * Style::sliderColors(const QStyleOption *option) const +{ + return (option && option->state&State_Enabled) + ? SHADE_NONE!=opts.shadeSliders && itsSliderCols && + (!opts.colorSliderMouseOver || option->state&State_MouseOver) + ? itsSliderCols + : itsButtonCols //buttonColors(option) + : itsBackgroundCols; +} + +const QColor * Style::backgroundColors(const QColor &col) const +{ + if(col.alpha()!=0 && col!=itsBackgroundCols[ORIGINAL_SHADE]) + { + shadeColors(col, itsColoredBackgroundCols); + return itsColoredBackgroundCols; + } + + return itsBackgroundCols; +} + +const QColor * Style::highlightColors(const QColor &col) const +{ + if(col.alpha()!=0 && col!=itsHighlightCols[ORIGINAL_SHADE]) + { + shadeColors(col, itsColoredHighlightCols); + return itsColoredHighlightCols; + } + + return itsHighlightCols; +} + +const QColor * Style::borderColors(const QStyleOption *option, const QColor *use) const +{ + return opts.coloredMouseOver && option && option->state&State_MouseOver && option->state&State_Enabled ? itsMouseOverCols : use; +} + +const QColor * Style::getSidebarButtons() const +{ + if(!itsSidebarButtonsCols) + { + if(SHADE_BLEND_SELECTED==opts.shadeSliders) + itsSidebarButtonsCols=itsSliderCols; + else if(IND_COLORED==opts.defBtnIndicator) + itsSidebarButtonsCols=itsDefBtnCols; + else + { + itsSidebarButtonsCols=new QColor [TOTAL_SHADES+1]; + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsButtonCols[ORIGINAL_SHADE]), + itsSidebarButtonsCols); + } + } + + return itsSidebarButtonsCols; +} + +void Style::setMenuColors(const QColor &bgnd) +{ + switch(opts.shadeMenubars) + { + case SHADE_NONE: + memcpy(itsMenubarCols, itsBackgroundCols, sizeof(QColor)*(TOTAL_SHADES+1)); + break; + case SHADE_BLEND_SELECTED: + shadeColors(midColor(itsHighlightCols[ORIGINAL_SHADE], itsBackgroundCols[ORIGINAL_SHADE]), itsMenubarCols); + break; + case SHADE_SELECTED: + shadeColors(IS_GLASS(opts.appearance) + ? shade(itsHighlightCols[ORIGINAL_SHADE], MENUBAR_GLASS_SELECTED_DARK_FACTOR) + : itsHighlightCols[ORIGINAL_SHADE], + itsMenubarCols); + break; + case SHADE_CUSTOM: + shadeColors(opts.customMenubarsColor, itsMenubarCols); + break; + case SHADE_DARKEN: + shadeColors(shade(bgnd, MENUBAR_DARK_FACTOR), itsMenubarCols); + break; + case SHADE_WINDOW_BORDER: + break; + } + + QColor *base=opts.shadePopupMenu + ? SHADE_WINDOW_BORDER==opts.shadeMenubars + ? (QColor *)getMdiColors(0L, true) // TODO: option!!! + : itsMenubarCols + : itsBackgroundCols; + + if(USE_LIGHTER_POPUP_MENU) + { + if(!itsPopupMenuCols) + itsPopupMenuCols=new QColor [TOTAL_SHADES+1]; + shadeColors(shade(base[ORIGINAL_SHADE], TO_FACTOR(opts.lighterPopupMenuBgnd)), itsPopupMenuCols); + } + else + itsPopupMenuCols=base; +} + +void Style::setMenuTextColors(QWidget *widget, bool isMenuBar) const +{ + if(SHADE_WINDOW_BORDER==opts.shadeMenubars) + { + QPalette pal(widget->palette()); + QStyleOption opt; + + opt.init(widget); + getMdiColors(&opt, false); + + pal.setBrush(QPalette::Active, QPalette::Foreground, itsActiveMdiTextColor); + pal.setBrush(QPalette::Active, QPalette::Text, pal.brush(QPalette::Active, QPalette::Foreground)); + if(isMenuBar) + { + pal.setBrush(QPalette::Inactive, QPalette::Foreground, + opts.shadeMenubarOnlyWhenActive ? itsMdiTextColor : itsActiveMdiTextColor); + pal.setBrush(QPalette::Inactive, QPalette::Text, pal.brush(QPalette::Inactive, QPalette::Foreground)); + } + else if(opts.shadePopupMenu) + { + pal.setBrush(QPalette::Disabled, QPalette::Foreground, midColor(itsActiveMdiTextColor, popupMenuCols()[ORIGINAL_SHADE])); + pal.setBrush(QPalette::Disabled, QPalette::Text, pal.brush(QPalette::Disabled, QPalette::Foreground)); + } + + widget->setPalette(pal); + } + else if(opts.customMenuTextColor || SHADE_BLEND_SELECTED==opts.shadeMenubars || + SHADE_SELECTED==opts.shadeMenubars || + (SHADE_CUSTOM==opts.shadeMenubars && TOO_DARK(itsMenubarCols[ORIGINAL_SHADE]))) + { + QPalette pal(widget->palette()); + + pal.setBrush(QPalette::Active, QPalette::Foreground, opts.customMenuTextColor + ? opts.customMenuNormTextColor + : pal.highlightedText().color()); + pal.setBrush(QPalette::Active, QPalette::Text, pal.brush(QPalette::Active, QPalette::Foreground)); + + if(isMenuBar && !opts.shadeMenubarOnlyWhenActive) + { + pal.setBrush(QPalette::Inactive, QPalette::Foreground, opts.customMenuTextColor + ? opts.customMenuNormTextColor + : pal.highlightedText().color()); + pal.setBrush(QPalette::Inactive, QPalette::Text, pal.brush(QPalette::Inactive, QPalette::Foreground)); + } + else if(!isMenuBar && opts.shadePopupMenu) + { + pal.setBrush(QPalette::Disabled, QPalette::Foreground, + midColor(pal.brush(QPalette::Active, QPalette::Foreground).color(), popupMenuCols()[ORIGINAL_SHADE])); + pal.setBrush(QPalette::Disabled, QPalette::Text, pal.brush(QPalette::Disabled, QPalette::Foreground)); + } + widget->setPalette(pal); + } +} + +const QColor * Style::menuColors(const QStyleOption *option, bool active) const +{ + return SHADE_WINDOW_BORDER==opts.shadeMenubars + ? getMdiColors(option, active) + : SHADE_NONE==opts.shadeMenubars || (opts.shadeMenubarOnlyWhenActive && !active) + ? backgroundColors(option) + : itsMenubarCols; +} + +bool Style::coloredMdiButtons(bool active, bool mouseOver) const +{ + return opts.titlebarButtons&TITLEBAR_BUTTON_COLOR && + (active + ? (mouseOver || !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER)) + : ( (opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER && mouseOver) || + (!(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER) && + opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_INACTIVE)) ); +} + +const QColor * Style::getMdiColors(const QStyleOption *option, bool active) const +{ + if(!itsActiveMdiColors) + { +#if defined QTC_QT_ONLY + itsActiveMdiTextColor=option ? option->palette.text().color() : QApplication::palette().text().color(); + itsMdiTextColor=option ? option->palette.text().color() : QApplication::palette().text().color(); + + QFile f(kdeHome()+"/share/config/kdeglobals"); + + if(f.open(QIODevice::ReadOnly)) + { + QTextStream in(&f); + bool inPal(false); + + while (!in.atEnd()) + { + QString line(in.readLine()); + + if(inPal) + { + if(!itsActiveMdiColors && 0==line.indexOf("activeBackground=")) + { + QColor col; + + setRgb(&col, line.mid(17).split(",")); + + if(col!=itsHighlightCols[ORIGINAL_SHADE]) + { + itsActiveMdiColors=new QColor [TOTAL_SHADES+1]; + shadeColors(col, itsActiveMdiColors); + } + } + else if(!itsMdiColors && 0==line.indexOf("inactiveBackground=")) + { + QColor col; + + setRgb(&col, line.mid(19).split(",")); + if(col!=itsButtonCols[ORIGINAL_SHADE]) + { + itsMdiColors=new QColor [TOTAL_SHADES+1]; + shadeColors(col, itsMdiColors); + } + } + else if(0==line.indexOf("activeForeground=")) + setRgb(&itsActiveMdiTextColor, line.mid(17).split(",")); + else if(0==line.indexOf("inactiveForeground=")) + setRgb(&itsMdiTextColor, line.mid(19).split(",")); + else if (-1!=line.indexOf('[')) + break; + } + else if(0==line.indexOf("[WM]")) + inPal=true; + } + f.close(); + } +#else + Q_UNUSED(option) + + QColor col=KGlobalSettings::activeTitleColor(); + + if(col!=itsBackgroundCols[ORIGINAL_SHADE]) + { + itsActiveMdiColors=new QColor [TOTAL_SHADES+1]; + shadeColors(col, itsActiveMdiColors); + } + + col=KGlobalSettings::inactiveTitleColor(); + if(col!=itsBackgroundCols[ORIGINAL_SHADE]) + { + itsMdiColors=new QColor [TOTAL_SHADES+1]; + shadeColors(col, itsMdiColors); + } + + itsActiveMdiTextColor=KGlobalSettings::activeTextColor(); + itsMdiTextColor=KGlobalSettings::inactiveTextColor(); +#endif + + if(!itsActiveMdiColors) + itsActiveMdiColors=(QColor *)itsBackgroundCols; + if(!itsMdiColors) + itsMdiColors=(QColor *)itsBackgroundCols; + + if(opts.shadeMenubarOnlyWhenActive && SHADE_WINDOW_BORDER==opts.shadeMenubars && + itsActiveMdiColors[ORIGINAL_SHADE]==itsMdiColors[ORIGINAL_SHADE]) + opts.shadeMenubarOnlyWhenActive=false; + } + + return active ? itsActiveMdiColors : itsMdiColors; +} + +void Style::readMdiPositions() const +{ + if(0==itsMdiButtons[0].size() && 0==itsMdiButtons[1].size()) + { + // Set defaults... + itsMdiButtons[0].append(SC_TitleBarSysMenu); + itsMdiButtons[0].append(SC_TitleBarShadeButton); + + itsMdiButtons[1].append(SC_TitleBarContextHelpButton); + itsMdiButtons[1].append(SC_TitleBarMinButton); + itsMdiButtons[1].append(SC_TitleBarMaxButton); + itsMdiButtons[1].append(WINDOWTITLE_SPACER); + itsMdiButtons[1].append(SC_TitleBarCloseButton); + +#if !defined QTC_QT_ONLY + KConfig cfg("kwinrc"); + KConfigGroup grp(&cfg, "Style"); + + if(grp.readEntry("CustomButtonPositions", false)) + { + QString left=grp.readEntry("ButtonsOnLeft"), + right=grp.readEntry("ButtonsOnRight"); + + if(!left.isEmpty() || !right.isEmpty()) + itsMdiButtons[0].clear(), itsMdiButtons[1].clear(); + + if(!left.isEmpty()) + parseWindowLine(left, itsMdiButtons[0]); + + if(!right.isEmpty()) + parseWindowLine(right, itsMdiButtons[1]); + + // Designer uses shade buttons, not min/max - so if we dont have shade in our kwin config. then add this button near the max button... + if(-1==itsMdiButtons[0].indexOf(SC_TitleBarShadeButton) && -1==itsMdiButtons[1].indexOf(SC_TitleBarShadeButton)) + { + int maxPos=itsMdiButtons[0].indexOf(SC_TitleBarMaxButton); + + if(-1==maxPos) // Left doesnt have max button, assume right does and add shade there + { + int minPos=itsMdiButtons[1].indexOf(SC_TitleBarMinButton); + maxPos=itsMdiButtons[1].indexOf(SC_TitleBarMaxButton); + + itsMdiButtons[1].insert(minPosmaxPos ? (minPos==-1 ? 0 : minPos) + : (maxPos==-1 ? 0 : maxPos), SC_TitleBarShadeButton); + } + } + } +#endif + } +} + +const QColor & Style::getFill(const QStyleOption *option, const QColor *use, bool cr, bool darker) const +{ + return !option || !(option->state&State_Enabled) + ? use[darker ? 2 : ORIGINAL_SHADE] + : option->state&State_Sunken // State_Down ???? + ? use[darker ? 5 : 4] + : option->state&State_MouseOver + ? !cr && option->state&State_On + ? use[darker ? 3 : SHADE_4_HIGHLIGHT] + : use[darker ? SHADE_2_HIGHLIGHT : SHADE_ORIG_HIGHLIGHT] + : !cr && option->state&State_On + ? use[darker ? 5 : 4] + : use[darker ? 2 : ORIGINAL_SHADE]; +} + +QPixmap * Style::getPixmap(const QColor col, EPixmap p, double shade) const +{ + QtcKey key(createKey(col, p)); + QPixmap *pix=itsPixmapCache.object(key); + + if(!pix) + { + if(PIX_DOT==p) + { + pix=new QPixmap(5, 5); + pix->fill(Qt::transparent); + + QColor c(col); + QPainter p(pix); + QLinearGradient g1(0, 0, 5, 5), + g2(0, 0, 3, 3); + + g1.setColorAt(0.0, c); + c.setAlphaF(0.4); + g1.setColorAt(1.0, c); + c=Qt::white; + c.setAlphaF(0.9); + g2.setColorAt(0.0, c); + c.setAlphaF(0.7); + g2.setColorAt(1.0, c); + p.setRenderHint(QPainter::Antialiasing, true); + p.setPen(Qt::NoPen); + p.setBrush(g1); + p.drawEllipse(0, 0, 5, 5); + p.setBrush(g2); + p.drawEllipse(1, 1, 4, 4); + p.end(); + } + else + { + pix=new QPixmap(); + + QImage img; + + switch(p) + { + case PIX_CHECK: + if(opts.xCheck) + img.loadFromData(check_x_on_png_data, check_x_on_png_len); + else + img.loadFromData(check_on_png_data, check_on_png_len); + break; + default: + break; + } + + if (img.depth()<32) + img=img.convertToFormat(QImage::Format_ARGB32); + + qtcAdjustPix(img.bits(), 4, img.width(), img.height(), img.bytesPerLine(), col.red(), col.green(), col.blue(), shade); + *pix=QPixmap::fromImage(img); + } + itsPixmapCache.insert(key, pix, pix->depth()/8); + } + + return pix; +} + +int Style::konqMenuBarSize(const QMenuBar *menu) const +{ + const QFontMetrics fm(menu->fontMetrics()); + QSize sz(100, fm.height()); + + QStyleOptionMenuItem opt; + opt.fontMetrics = fm; + opt.state = QStyle::State_Enabled; + opt.menuRect = menu->rect(); + opt.text = "File"; + sz = sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, menu); + return sz.height()+6; +} + +const QColor & Style::getTabFill(bool current, bool highlight, const QColor *use) const +{ + return current + ? use[ORIGINAL_SHADE] + : highlight + ? use[SHADE_2_HIGHLIGHT] + : use[2]; +} + +QColor Style::menuStripeCol() const +{ + switch(opts.menuStripe) + { + default: + case SHADE_NONE: + return itsBackgroundCols[ORIGINAL_SHADE]; + case SHADE_CUSTOM: + return opts.customMenuStripeColor; + case SHADE_BLEND_SELECTED: + // Hack! Use opts.customMenuStripeColor to store this setting! + if(IS_BLACK(opts.customMenuStripeColor)) + opts.customMenuStripeColor=midColor(itsHighlightCols[ORIGINAL_SHADE], popupMenuCols()[ORIGINAL_SHADE]); + return opts.customMenuStripeColor; + case SHADE_SELECTED: + return itsHighlightCols[MENU_STRIPE_SHADE]; + case SHADE_DARKEN: + return popupMenuCols()[MENU_STRIPE_SHADE]; + } +} + +const QColor & Style::checkRadioCol(const QStyleOption *opt) const +{ + return opt->state&State_Enabled + ? itsCheckRadioCol + : opts.crButton + ? opt->palette.buttonText().color() + : opt->palette.text().color(); +} + +QColor Style::shade(const QColor &a, double k) const +{ + QColor mod; + + ::qtcShade(&opts, a, &mod, k); + return mod; +} + +void Style::shade(const color &ca, color *cb, double k) const +{ + ::qtcShade(&opts, ca, cb, k); +} + +QColor Style::getLowerEtchCol(const QWidget *widget) const +{ + if(USE_CUSTOM_ALPHAS(opts)) + { + QColor col(Qt::white); + col.setAlphaF(opts.customAlphas[ALPHA_ETCH_LIGHT]); + return col; + } + + if(IS_FLAT_BGND(opts.bgndAppearance)) + { + bool doEtch=widget && widget->parentWidget() && !theNoEtchWidgets.contains(widget); +// CPD: Don't really want to check here for every widget, when (so far) on problem seems to be in +// KPackageKit, and thats with its KTextBrowser - so just check when we draw scrollviews... +// if(doEtch && isInQAbstractItemView(widget->parentWidget())) +// { +// doEtch=false; +// theNoEtchWidgets.insert(widget); +// } + + if(doEtch) + { + QColor bgnd(widget->parentWidget()->palette().color(widget->parentWidget()->backgroundRole())); + + if(bgnd.alpha()>0) + return shade(bgnd, 1.06); + } + } + + QColor col(Qt::white); + col.setAlphaF(0.1); // IS_FLAT_BGND(opts.bgndAppearance) ? 0.25 : 0.4); + + return col; +} + +int Style::getFrameRound(const QWidget *widget) const +{ + if(opts.square&SQUARE_FRAME) + return ROUNDED_NONE; + + const QWidget *window=widget ? widget->window() : 0L; + + if(window) + { + QRect widgetRect(widget->rect()), + windowRect(window->rect()); + + if(widgetRect==windowRect) + return ROUNDED_NONE; + } + + if((opts.square&SQUARE_ENTRY) && widget && qobject_cast(widget)) + return ROUNDED_NONE; + + return ROUNDED_ALL; +} + +void Style::unregisterArgbWidget(QWidget *w) +{ + if(itsTransparentWidgets.contains(w)) + { + w->setAttribute(Qt::WA_NoSystemBackground, false); + w->setAttribute(Qt::WA_TranslucentBackground, false); + } +} + +void Style::widgetDestroyed(QObject *o) +{ + QWidget *w=static_cast(o); + theNoEtchWidgets.remove(w); + if(APP_KONTACT==theThemedApp) + { + itsSViewContainers.remove(w); + QMap >::Iterator it(itsSViewContainers.begin()), + end(itsSViewContainers.end()); + QSet rem; + + for(; it!=end; ++it) + { + (*it).remove(w); + if((*it).isEmpty()) + rem.insert(it.key()); + } + + QSet::ConstIterator r(rem.begin()), + remEnd(rem.end()); + + for(; r!=remEnd; ++r) + itsSViewContainers.remove(*r); + } + unregisterArgbWidget(w); +} + +#if !defined QTC_QT_ONLY +void Style::setupKde4() +{ + if(kapp) + setDecorationColors(); + else + { + applyKdeSettings(true); + applyKdeSettings(false); + } +} + +void Style::setDecorationColors() +{ + KColorScheme kcs(QPalette::Active); + if(opts.coloredMouseOver) + shadeColors(kcs.decoration(KColorScheme::HoverColor).color(), itsMouseOverCols); + shadeColors(kcs.decoration(KColorScheme::FocusColor).color(), itsFocusCols); +} + +void Style::applyKdeSettings(bool pal) +{ + if(pal) + { + if(!kapp) + QApplication::setPalette(standardPalette()); + setDecorationColors(); + } + else + { + KConfigGroup g(KGlobal::config(), "General"); + QFont mnu=g.readEntry("menuFont", QApplication::font()); + + QApplication::setFont(g.readEntry("font", QApplication::font())); + QApplication::setFont(mnu, "QMenuBar"); + QApplication::setFont(mnu, "QMenu"); + QApplication::setFont(mnu, "KPopupTitle"); + QApplication::setFont(KGlobalSettings::toolBarFont(), "QToolBar"); + } +} +#endif + +void Style::kdeGlobalSettingsChange(int type, int) +{ +#if defined QTC_QT_ONLY + Q_UNUSED(type) +#else + switch(type) + { + case KGlobalSettings::StyleChanged: + { + KGlobal::config()->reparseConfiguration(); + if(itsUsePixmapCache) + QPixmapCache::clear(); + init(false); + + QWidgetList tlw=QApplication::topLevelWidgets(); + QWidgetList::ConstIterator it(tlw.begin()), + end(tlw.end()); + + for(; it!=end; ++it) + (*it)->update(); + break; + } + case KGlobalSettings::PaletteChanged: + KGlobal::config()->reparseConfiguration(); + applyKdeSettings(true); + if(itsUsePixmapCache) + QPixmapCache::clear(); + break; + case KGlobalSettings::FontChanged: + KGlobal::config()->reparseConfiguration(); + applyKdeSettings(false); + break; + } +#endif + + itsBlurHelper->setEnabled(Utils::compositingActive()); + itsWindowManager->initialize(opts.windowDrag); +} + +void Style::borderSizesChanged() +{ +#if !defined QTC_QT_ONLY + int old=qtcGetWindowBorderSize().titleHeight; + + if(old!=qtcGetWindowBorderSize(true).titleHeight) + { + QWidgetList tlw=QApplication::topLevelWidgets(); + QWidgetList::ConstIterator it(tlw.begin()), + end(tlw.end()); + + for(; it!=end; ++it) + if(qobject_cast(*it) && static_cast(*it)->menuBar()) + static_cast(*it)->menuBar()->update(); + } +#endif +} + +#ifdef Q_WS_X11 +static QMainWindow * getWindow(unsigned int xid) +{ + QWidgetList tlw=QApplication::topLevelWidgets(); + QWidgetList::ConstIterator it(tlw.begin()), + end(tlw.end()); + + for(; it!=end; ++it) + { + if(qobject_cast(*it) && (*it)->winId()==xid) + return static_cast(*it); + } + return 0L; +} + +static bool diffTime(struct timeval *lastTime) +{ + struct timeval now, diff; + + gettimeofday(&now, NULL); + timersub(&now, lastTime, &diff); + *lastTime=now; + return diff.tv_sec>0 || diff.tv_usec>500000; +} +#endif + +void Style::toggleMenuBar(unsigned int xid) +{ +#ifdef Q_WS_X11 + static unsigned int lastXid = 0; + static struct timeval lastTime = {0, 0}; + + if(diffTime(&lastTime) || lastXid!=xid) + { + QMainWindow *win=getWindow(xid); + if(win) + toggleMenuBar(win); + } + lastXid=xid; +#else + Q_UNUSED(xid); +#endif +} + +void Style::toggleStatusBar(unsigned int xid) +{ +#ifdef Q_WS_X11 + static unsigned int lastXid = 0; + static struct timeval lastTime = {0, 0}; + + if(diffTime(&lastTime) || lastXid!=xid) + { + QMainWindow *win=getWindow(xid); + if(win) + toggleStatusBar(win); + } + lastXid=xid; +#else + Q_UNUSED(xid); +#endif +} + +void Style::compositingToggled() +{ +#ifdef Q_WS_X11 + QWidgetList tlw=QApplication::topLevelWidgets(); + QWidgetList::ConstIterator it(tlw.begin()), + end(tlw.end()); + + for(; it!=end; ++it) + (*it)->update(); +#endif +} + +void Style::toggleMenuBar(QMainWindow *window) +{ + bool triggeredAction(false); + +#ifndef QTC_QT_ONLY + if(qobject_cast(window)) + { + KActionCollection *collection=static_cast(window)->actionCollection(); + QAction *act=collection ? collection->action(KStandardAction::name(KStandardAction::ShowMenubar)) : 0L; + if(act) + { + act->trigger(); + triggeredAction=true; + } + } +#endif + if(!triggeredAction) + { + QWidget *menubar=window->menuWidget(); + if(itsSaveMenuBarStatus) + qtcSetMenuBarHidden(appName, menubar->isVisible()); + + window->menuWidget()->setHidden(menubar->isVisible()); + } +} + +void Style::toggleStatusBar(QMainWindow *window) +{ + bool triggeredAction(false); + +#ifndef QTC_QT_ONLY + if(qobject_cast(window)) + { + KActionCollection *collection=static_cast(window)->actionCollection(); + QAction *act=collection ? collection->action(KStandardAction::name(KStandardAction::ShowStatusbar)) : 0L; + if(act) + { + act->trigger(); + triggeredAction=true; +#ifdef Q_WS_X11 + //emitStatusBarState(true); // TODO: ??? +#endif + } + } +#endif + if(!triggeredAction) + { + QList sb=getStatusBars(window); + + if(sb.count()) + { + if(itsSaveStatusBarStatus) + qtcSetStatusBarHidden(appName, sb.first()->isVisible()); + + QList::ConstIterator it(sb.begin()), + end(sb.end()); + for(; it!=end; ++it) + (*it)->setHidden((*it)->isVisible()); + +#ifdef Q_WS_X11 + emitStatusBarState(sb.first()); +#endif + } + } +} + +#ifdef Q_WS_X11 +void Style::emitMenuSize(QWidget *w, unsigned short size, bool force) +{ + if(w && canAccessId(w->window())) + { + static const char * constMenuSizeProperty="qtcMenuSize"; + + unsigned short oldSize=2000; + + if(!force) + { + QVariant prop(w->property(constMenuSizeProperty)); + + if(prop.isValid()) + { + bool ok; + oldSize=prop.toUInt(&ok); + if(!ok) + oldSize=2000; + } + } + + if(oldSize!=size) + { + static const Atom constQtCMenuSize = XInternAtom(QX11Info::display(), MENU_SIZE_ATOM, False); + + w->setProperty(constMenuSizeProperty, size); + XChangeProperty(QX11Info::display(), w->window()->winId(), + constQtCMenuSize, XA_CARDINAL, 16, PropModeReplace, (unsigned char *)&size, 1); + if(!itsDBus) + itsDBus=new QDBusInterface("org.kde.kwin", "/QtCurve", "org.kde.QtCurve"); + itsDBus->call(QDBus::NoBlock, "menuBarSize", (unsigned int)w->window()->winId(), (int)size); + } + } +} + +void Style::emitStatusBarState(QStatusBar *sb) +{ + if(opts.statusbarHiding&HIDE_KWIN) + { + if(!itsDBus) + itsDBus=new QDBusInterface("org.kde.kwin", "/QtCurve", "org.kde.QtCurve"); + itsDBus->call(QDBus::NoBlock, "statusBarState", (unsigned int)sb->window()->winId(), sb->isVisible()); + } +} + +#endif + +} diff --git a/src/qtcurve/style/qtcurve.h b/src/qtcurve/style/qtcurve.h new file mode 100644 index 0000000000..547f2dd2c7 --- /dev/null +++ b/src/qtcurve/style/qtcurve.h @@ -0,0 +1,379 @@ +#ifndef __QTCURVE_H__ +#define __QTCURVE_H__ + +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) +#include +#endif +#include +typedef qulonglong QtcKey; +#include "common.h" + +#if !defined QTC_QT_ONLY +#include +#endif + +// #ifdef QTC_KSTYLE +// #include +// #define BASE_STYLE KStyle +// #else +#include +#define BASE_STYLE QCommonStyle +// #endif + +class QStyleOptionSlider; +class QLabel; +class QMenuBar; +class QScrollBar; +class QDBusInterface; +class QMainWindow; +class QStatusBar; +class QAbstractScrollArea; + +namespace QtCurve +{ + class WindowManager; + class BlurHelper; + class ShortcutHandler; +#ifdef Q_WS_X11 + class ShadowHelper; +#endif + +class Style : public QCommonStyle +{ + Q_OBJECT + Q_CLASSINFO("X-KDE-CustomElements", "true") + + public: + + enum BackgroundType + { + BGND_WINDOW, + BGND_DIALOG, + BGND_MENU + }; + + enum MenuItemType + { + MENU_POPUP, + MENU_BAR, + MENU_COMBO + }; + + enum CustomElements + { + CE_QtC_KCapacityBar = CE_CustomBase+0x00FFFF00, + CE_QtC_Preview, + CE_QtC_SetOptions + }; + + enum PreviewType + { + PREVIEW_FALSE, + PREVIEW_MDI, + PREVIEW_WINDOW + }; + + class PreviewOption : public QStyleOption + { + public: + + Options opts; + }; + + class BgndOption : public QStyleOption + { + public: + + EAppearance app; + QPainterPath path; + QRect widgetRect; + }; + + enum Icon + { + ICN_MIN, + ICN_MAX, + ICN_MENU, + ICN_RESTORE, + ICN_CLOSE, + ICN_UP, + ICN_DOWN, + ICN_RIGHT, + ICN_SHADE, + ICN_UNSHADE + }; + +#ifdef QTC_STYLE_SUPPORT + Style(const QString &name=QString()); +#else + Style(); +#endif + + ~Style(); + + void init(bool initial); + void freeColor(QSet &freedColors, QColor **cols); + void freeColors(); + + Options & options() { return opts; } + + void polish(QApplication *app); + void polish(QPalette &palette); + void polish(QWidget *widget); + +#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) + void polishFormLayout(QFormLayout *layout); + void polishLayout(QLayout *layout); +#endif + void polishScrollArea(QAbstractScrollArea *scrollArea, bool isKFilePlacesView=false) const; + + void unpolish(QApplication *app); + void unpolish(QWidget *widget); + bool eventFilter(QObject *object, QEvent *event); + void timerEvent(QTimerEvent *event); + int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const; + int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData=0) const; + QPalette standardPalette() const; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; + void drawControl(ControlElement control, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const; + void drawItemTextWithRole(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, + QPalette::ColorRole textRole) const; + void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, const QString &text, + QPalette::ColorRole textRole = QPalette::NoRole) const; + QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const; + QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const; + QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const; + SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget) const; + + private: + + void drawSideBarButton(QPainter *painter, const QRect &r, const QStyleOption *option, const QWidget *widget) const; + void drawHighlight(QPainter *p, const QRect &r, bool horiz, bool inc) const; + void drawFadedLine(QPainter *p, const QRect &r, const QColor &col, bool fadeStart, bool fadeEnd, bool horiz, + double fadeSizeStart=FADE_SIZE, double fadeSizeEnd=FADE_SIZE) const; + void drawLines(QPainter *p, const QRect &r, bool horiz, int nLines, int offset, const QColor *cols, int startOffset, + int dark, ELine type) const; + void drawProgressBevelGradient(QPainter *p, const QRect &origRect, const QStyleOption *option, bool horiz, + EAppearance bevApp, const QColor *cols) const; + void drawBevelGradient(const QColor &base, QPainter *p, QRect const &r, const QPainterPath &path, + bool horiz, bool sel, EAppearance bevApp, EWidget w=WIDGET_OTHER, bool useCache=true) const; + void drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r, const QPainterPath &path, + bool horiz, bool sel, EAppearance bevApp, EWidget w) const; + + void drawBevelGradient(const QColor &base, QPainter *p, QRect const &r, + bool horiz, bool sel, EAppearance bevApp, EWidget w=WIDGET_OTHER, bool useCache=true) const + { + drawBevelGradient(base, p, r, QPainterPath(), horiz, sel, bevApp, w, useCache); + } + void drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r, bool horiz, bool sel, + EAppearance bevApp, EWidget w) const + { + drawBevelGradientReal(base, p, r, QPainterPath(), horiz, sel, bevApp, w); + } + + void drawSunkenBevel(QPainter *p, const QRect &r, const QColor &col) const; + void drawLightBevel(QPainter *p, const QRect &r, const QStyleOption *option, const QWidget *widget, int round, const QColor &fill, + const QColor *custom=0, bool doBorder=true, EWidget w=WIDGET_OTHER) const; + void drawLightBevelReal(QPainter *p, const QRect &r, const QStyleOption *option, const QWidget *widget, int round, const QColor &fill, + const QColor *custom, bool doBorder, EWidget w, bool useCache, ERound realRound, bool onToolbar) const; + void drawGlow(QPainter *p, const QRect &r, EWidget w, const QColor *cols=0L) const; + void drawEtch(QPainter *p, const QRect &r, const QWidget *widget, EWidget w, bool raised=false, int round=ROUNDED_ALL) const; + void drawBgndRing(QPainter &painter, int x, int y, int size, int size2, bool isWindow) const; + QPixmap drawStripes(const QColor &color, int opacity) const; + void drawBackground(QPainter *p, const QColor &bgnd, const QRect &r, int opacity, BackgroundType type, EAppearance app, + const QPainterPath &path=QPainterPath()) const; + void drawBackgroundImage(QPainter *p, bool isWindow, const QRect &r) const; + void drawBackground(QPainter *p, const QWidget *widget, BackgroundType type) const; + QPainterPath buildPath(const QRectF &r, EWidget w, int round, double radius) const; + QPainterPath buildPath(const QRect &r, EWidget w, int round, double radius) const; + void buildSplitPath(const QRect &r, int round, double radius, QPainterPath &tl, QPainterPath &br) const; + void drawBorder(QPainter *p, const QRect &r, const QStyleOption *option, int round, const QColor *custom=0, + EWidget w=WIDGET_OTHER, EBorder borderProfile=BORDER_FLAT, bool doBlend=true, int borderVal=STD_BORDER) const; + void drawMdiControl(QPainter *p, const QStyleOptionTitleBar *titleBar, SubControl sc, const QWidget *widget, + ETitleBarButtons btn, const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols, + int adjust, bool activeWindow) const; + void drawDwtControl(QPainter *p, const QFlags &state, const QRect &rect, ETitleBarButtons btn, Icon icon, + const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols) const; + bool drawMdiButton(QPainter *painter, const QRect &r, bool hover, bool sunken, const QColor *cols) const; + void drawMdiIcon(QPainter *painter, const QColor &color, const QColor &bgnd, const QRect &r, + bool hover, bool sunken, Icon iclearcon, bool stdSize, bool drewFrame) const; + void drawIcon(QPainter *painter, const QColor &color, const QRect &r, bool sunken, Icon icon, bool stdSize=true) const; + void drawEntryField(QPainter *p, const QRect &rx, const QWidget *widget, const QStyleOption *option, int round, + bool fill, bool doEtch, EWidget w=WIDGET_ENTRY) const; + void drawMenuItem(QPainter *p, const QRect &r, const QStyleOption *option, MenuItemType type, int round, const QColor *cols) const; + void drawProgress(QPainter *p, const QRect &r, const QStyleOption *option, bool vertical=false, bool reverse=false) const; + void drawArrow(QPainter *p, const QRect &rx, PrimitiveElement pe, QColor col, bool small=false, bool kwin=false) const; + void drawSbSliderHandle(QPainter *p, const QRect &r, const QStyleOption *option, bool slider=false) const; + void drawSliderHandle(QPainter *p, const QRect &r, const QStyleOptionSlider *option) const; + void drawSliderGroove(QPainter *p, const QRect &groove, const QRect &handle, const QStyleOptionSlider *slider, const QWidget *widget) const; + int getOpacity(const QWidget *widget, QPainter *p) const; + void drawMenuOrToolBarBackground(const QWidget *widget, QPainter *p, const QRect &r, const QStyleOption *option, bool menu=true, + bool horiz=true) const; + void drawHandleMarkers(QPainter *p, const QRect &r, const QStyleOption *option, bool tb, ELine handles) const; + void fillTab(QPainter *p, const QRect &r, const QStyleOption *option, const QColor &fill, bool horiz, EWidget tab, bool tabOnly) const; + void colorTab(QPainter *p, const QRect &r, bool horiz, EWidget tab, int round) const; + void shadeColors(const QColor &base, QColor *vals) const; + const QColor * buttonColors(const QStyleOption *option) const; + QColor titlebarIconColor(const QStyleOption *option) const; + const QColor * popupMenuCols(const QStyleOption *option=0L) const; + const QColor * checkRadioColors(const QStyleOption *option) const; + const QColor * sliderColors(const QStyleOption *option) const; + const QColor * backgroundColors(const QColor &col) const; + const QColor * backgroundColors(const QStyleOption *option) const + { return option ? backgroundColors(option->palette.background().color()) : itsBackgroundCols; } + const QColor * highlightColors(const QColor &col) const; + const QColor * highlightColors(const QStyleOption *option, bool useActive) const + { return highlightColors(option->palette.brush(useActive ? QPalette::Active : QPalette::Current, QPalette::Highlight).color()); } + const QColor * borderColors(const QStyleOption *option, const QColor *use) const; + const QColor * getSidebarButtons() const; + void setMenuColors(const QColor &bgnd); + void setMenuTextColors(QWidget *widget, bool isMenuBar) const; + const QColor * menuColors(const QStyleOption *option, bool active) const; + bool coloredMdiButtons(bool active, bool mouseOver) const; + const QColor * getMdiColors(const QStyleOption *option, bool active) const; + void readMdiPositions() const; + const QColor & getFill(const QStyleOption *option, const QColor *use, bool cr=false, bool darker=false) const; + const QColor & getTabFill(bool current, bool highlight, const QColor *use) const; + QColor menuStripeCol() const; + QPixmap * getPixmap(const QColor col, EPixmap p, double shade=1.0) const; + int konqMenuBarSize(const QMenuBar *menu) const; + const QColor & checkRadioCol(const QStyleOption *opt) const; + QColor shade(const QColor &a, double k) const; + void shade(const color &ca, color *cb, double k) const; + QColor getLowerEtchCol(const QWidget *widget) const; + int getFrameRound(const QWidget *widget) const; + void unregisterArgbWidget(QWidget *w); + + private Q_SLOTS: + + void widgetDestroyed(QObject *o); + QIcon standardIconImplementation(StandardPixmap pix, const QStyleOption *option=0, const QWidget *widget=0) const; + int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, + Qt::Orientation orientation, const QStyleOption *option, + const QWidget *widget) const; + void kdeGlobalSettingsChange(int type, int); + void borderSizesChanged(); + void toggleMenuBar(unsigned int xid); + void toggleStatusBar(unsigned int xid); + void compositingToggled(); + + private: + + void toggleMenuBar(QMainWindow *window); + void toggleStatusBar(QMainWindow *window); + +#if !defined QTC_QT_ONLY + void setupKde4(); + + + void setDecorationColors(); + void applyKdeSettings(bool pal); +#endif +#ifdef Q_WS_X11 + bool isWindowDragWidget(QObject *o); + void emitMenuSize(QWidget *w, unsigned short size, bool force=false); + void emitStatusBarState(QStatusBar *sb); +#endif + + private: + + mutable Options opts; + QColor itsHighlightCols[TOTAL_SHADES+1], + itsBackgroundCols[TOTAL_SHADES+1], + itsMenubarCols[TOTAL_SHADES+1], + itsFocusCols[TOTAL_SHADES+1], + itsMouseOverCols[TOTAL_SHADES+1], + *itsPopupMenuCols, + *itsSliderCols, + *itsDefBtnCols, + *itsComboBtnCols, + *itsCheckRadioSelCols, + *itsSortedLvColors, + *itsOOMenuCols, + *itsProgressCols, + itsButtonCols[TOTAL_SHADES+1], + itsCheckRadioCol; + bool itsSaveMenuBarStatus, + itsSaveStatusBarStatus, + itsUsePixmapCache, + itsInactiveChangeSelectionColor; + PreviewType itsIsPreview; + mutable QColor *itsSidebarButtonsCols; + mutable QColor *itsActiveMdiColors; + mutable QColor *itsMdiColors; + mutable QColor itsActiveMdiTextColor; + mutable QColor itsMdiTextColor; + mutable QColor itsColoredButtonCols[TOTAL_SHADES+1]; + mutable QColor itsColoredBackgroundCols[TOTAL_SHADES+1]; + mutable QColor itsColoredHighlightCols[TOTAL_SHADES+1]; + mutable QCache itsPixmapCache; + mutable bool itsActive; + mutable const QWidget *itsSbWidget; + mutable QLabel *itsClickedLabel; + QSet itsProgressBars; + QSet itsTransparentWidgets; + int itsProgressBarAnimateTimer, + itsAnimateStep; + QTime itsTimer; + mutable QMap itsTitleBarButtonsCols; +#ifdef QTC_ENABLE_PARENTLESS_DIALOG_FIX_SUPPORT + mutable QMap itsReparentedDialogs; +#endif + mutable QList itsMdiButtons[2]; // 0=left, 1=right + mutable int itsTitlebarHeight; + + // Required for Q3Header hover... + QPoint itsPos; + QWidget *itsHoverWidget; +#ifdef Q_WS_X11 + QDBusInterface *itsDBus; + QtCurve::ShadowHelper *itsShadowHelper; +#endif + mutable QScrollBar *itsSViewSBar; + mutable QMap > itsSViewContainers; +#if !defined QTC_QT_ONLY + KComponentData itsComponentData; +#endif + QtCurve::WindowManager *itsWindowManager; + QtCurve::BlurHelper *itsBlurHelper; + QtCurve::ShortcutHandler *itsShortcutHandler; +#ifdef QTC_STYLE_SUPPORT + QString itsName; +#endif +}; + +} + +#endif diff --git a/src/qtcurve/style/qtcurve.themerc b/src/qtcurve/style/qtcurve.themerc new file mode 100644 index 0000000000..7cd4821d91 --- /dev/null +++ b/src/qtcurve/style/qtcurve.themerc @@ -0,0 +1,10 @@ +[Misc] +Name=QtCurve +Comment=Highly configurable style +Comment[zh_CN]=可高度定制的风格 +Comment[zh_HK]=可高度定制的樣式 +Comment[zh_TW]=可高度定制的樣式 +ConfigPage=kstyle_qtcurve_config +[KDE] +WidgetStyle=QtCurve + diff --git a/src/qtcurve/style/shadow.h b/src/qtcurve/style/shadow.h new file mode 100644 index 0000000000..c3ab65224f --- /dev/null +++ b/src/qtcurve/style/shadow.h @@ -0,0 +1,320 @@ +#ifndef _QEMBED_1804289383 +#define _QEMBED_1804289383 +static const unsigned int shadow0_png_len = 243; +static const unsigned char shadow0_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0x36,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x38,0x38,0x38,0x3f,0x3f,0x2a,0x36,0x36,0x36,0x3c,0x3c, + 0x3c,0x39,0x39,0x39,0x3a,0x3a,0x31,0x3c,0x3c,0x34,0x39,0x39,0x34,0x3a, + 0x36,0x36,0x37,0x37,0x35,0x00,0x32,0xd6,0xf3,0x00,0x00,0x00,0x12,0x74, + 0x52,0x4e,0x53,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x0c,0x0e, + 0x11,0x16,0x1a,0x22,0x31,0x46,0x65,0xc3,0x39,0x93,0x78,0x00,0x00,0x00, + 0x36,0x49,0x44,0x41,0x54,0x48,0xc7,0x63,0x60,0x18,0x05,0xa3,0x60,0x14, + 0x8c,0x82,0x51,0x40,0x03,0xc0,0xc8,0x48,0x96,0x36,0x26,0x86,0xe1,0xab, + 0x8d,0x85,0x71,0xd4,0x6f,0x03,0x1a,0x24,0x43,0xc2,0xb6,0xe1,0x1c,0x92, + 0x43,0x43,0x1b,0xd3,0x30,0xf6,0xdb,0x9f,0x21,0x50,0x75,0x00,0x00,0xde, + 0xc1,0x01,0x63,0xb8,0x00,0x44,0xf1,0x00,0x00,0x00,0x00,0x49,0x45,0x4e, + 0x44,0xae,0x42,0x60,0x82 +}; + +/* Generated by qembed */ +static const unsigned int shadow1_png_len = 632; +static const unsigned char shadow1_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0xb7,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x33,0x33,0x33,0x2e,0x2e, + 0x2e,0x2a,0x2a,0x2a,0x3f,0x3f,0x2a,0x3a,0x3a,0x3a,0x36,0x36,0x36,0x44, + 0x33,0x33,0x44,0x44,0x33,0x3f,0x3f,0x3f,0x3c,0x3c,0x3c,0x38,0x38,0x38, + 0x35,0x35,0x35,0x3c,0x3c,0x30,0x39,0x39,0x39,0x37,0x37,0x37,0x35,0x35, + 0x35,0x33,0x33,0x33,0x3d,0x33,0x33,0x38,0x38,0x38,0x36,0x36,0x36,0x34, + 0x34,0x34,0x33,0x33,0x33,0x39,0x39,0x31,0x3d,0x36,0x36,0x3c,0x3c,0x34, + 0x38,0x38,0x38,0x3a,0x3a,0x34,0x39,0x39,0x33,0x36,0x36,0x36,0x37,0x37, + 0x31,0x3a,0x3a,0x35,0x39,0x39,0x34,0x38,0x38,0x38,0x3a,0x35,0x35,0x37, + 0x37,0x37,0x3a,0x35,0x35,0x3a,0x3a,0x36,0x39,0x39,0x35,0x37,0x37,0x37, + 0x3a,0x36,0x36,0x37,0x37,0x33,0x36,0x36,0x33,0x38,0x38,0x34,0x39,0x39, + 0x33,0x3a,0x37,0x34,0x39,0x36,0x36,0x38,0x38,0x33,0x38,0x38,0x36,0x37, + 0x37,0x35,0x39,0x37,0x34,0x39,0x37,0x35,0x00,0x16,0x19,0x9e,0x00,0x00, + 0x00,0x3d,0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x13, + 0x15,0x16,0x17,0x18,0x19,0x19,0x1b,0x1c,0x1d,0x1e,0x1f,0x21,0x22,0x24, + 0x27,0x28,0x2a,0x2e,0x30,0x31,0x32,0x34,0x37,0x39,0x3d,0x3e,0x40,0x46, + 0x4a,0x4b,0x4d,0x50,0x53,0x54,0x5e,0x63,0x65,0x66,0x6e,0x2d,0xaa,0x55, + 0x29,0x00,0x00,0x01,0x0f,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0xd1,0xd9, + 0x72,0x83,0x20,0x18,0x86,0x61,0x25,0xb1,0x89,0x92,0x88,0x62,0xd5,0xa6, + 0x6d,0x6c,0x9b,0xbd,0x5b,0xba,0xef,0xbd,0xff,0xeb,0x2a,0x20,0xa2,0x76, + 0x14,0xc1,0x99,0x9c,0xf1,0x9e,0x3f,0xf3,0xfd,0xa2,0x65,0x99,0x4c,0x26, + 0x93,0xe9,0x10,0xd9,0xbc,0x9e,0x4c,0x53,0xda,0xb5,0x7a,0x32,0x65,0x68, + 0xdb,0xbd,0x20,0x60,0x69,0x43,0x20,0xd2,0x72,0xa0,0x9a,0x3a,0x04,0xa0, + 0x19,0x76,0xb0,0x41,0x9e,0xae,0x1b,0xd2,0x6a,0x52,0xc9,0x0d,0x8b,0x4a, + 0xa8,0xe2,0x1c,0xda,0x3f,0xa8,0xe0,0x1c,0x1e,0x87,0xb5,0x41,0x09,0x3b, + 0xa2,0x95,0xb2,0x3e,0xd8,0xce,0x46,0x24,0x21,0x4b,0xd7,0x75,0xa6,0x3b, + 0x26,0x31,0xa9,0xe5,0x5c,0x1a,0x97,0x0d,0xae,0x8d,0x4d,0x27,0x10,0x7a, + 0x39,0xd4,0x71,0x88,0x44,0xa8,0x27,0xa0,0x70,0x52,0x16,0x61,0x1c,0x06, + 0xc8,0x87,0x1e,0x85,0xc2,0x75,0xce,0xa5,0x69,0x12,0x47,0x38,0x40,0x53, + 0x58,0x71,0xd5,0x33,0x9b,0xd9,0x62,0x91,0xcd,0xd2,0x18,0x87,0xc2,0x39, + 0xa5,0x93,0xcc,0x5d,0x6f,0x37,0xcb,0x6c,0x96,0x44,0x21,0x9a,0x40,0x97, + 0xbb,0xe2,0x4c,0x09,0x7b,0x7a,0xbc,0xdb,0xad,0x2f,0x89,0xc3,0x08,0x32, + 0x57,0x3d,0xb3,0x9d,0x7d,0x7f,0xbe,0xed,0x6f,0x57,0xd9,0x29,0xd9,0xf3, + 0xd9,0x9f,0x28,0xce,0x94,0xcf,0x9d,0xbf,0xfc,0x7c,0xec,0x6f,0x96,0xf3, + 0x93,0x18,0x07,0xf9,0x7f,0x50,0x9b,0xb3,0x5e,0xbf,0x9e,0xef,0x37,0x17, + 0x67,0xc9,0x71,0xe8,0xb3,0xcf,0x1b,0xa9,0xb1,0xec,0xf7,0xfd,0x61,0x77, + 0x35,0x27,0xcf,0xc9,0x5f,0x93,0xcf,0xc9,0xd8,0x1f,0xae,0x80,0x13,0xce, + 0x98,0x27,0x21,0xc2,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42, + 0x60,0x82 +}; + +static const unsigned int shadow2_png_len = 262; +static const unsigned char shadow2_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0x45,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x13,0x00, + 0x00,0x00,0x7f,0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33, + 0x2a,0x2a,0x2a,0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x2e,0x2e, + 0x2e,0x3f,0x3f,0x2a,0x44,0x33,0x33,0x3f,0x3f,0x3f,0x35,0x35,0x35,0x35, + 0x35,0x35,0x34,0x34,0x34,0x3a,0x3a,0x32,0x37,0x37,0x37,0x37,0x37,0x37, + 0x37,0x37,0x34,0x38,0x38,0x36,0x58,0x89,0x9a,0x95,0x00,0x00,0x00,0x17, + 0x74,0x52,0x4e,0x53,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x09,0x0b,0x0c,0x0f,0x10,0x13,0x18,0x1d,0x23,0x33,0x40,0x58,0x71,0xb6, + 0x80,0xa9,0xcd,0x00,0x00,0x00,0x35,0x49,0x44,0x41,0x54,0x48,0xc7,0xed, + 0xcb,0xa1,0x0d,0x00,0x20,0x14,0xc4,0xd0,0x7e,0x12,0x06,0x60,0xff,0x5d, + 0x39,0x1c,0x24,0x04,0x85,0x6e,0x4d,0xd5,0x2b,0x18,0x3d,0x27,0xc2,0x1e, + 0x10,0x00,0x26,0x57,0xd5,0xf8,0x4a,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c, + 0x26,0x93,0xbd,0x5b,0xd9,0x06,0x15,0x6d,0x40,0x49,0x97,0xb4,0x00,0x00, + 0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +static const unsigned int shadow3_png_len = 825; +static const unsigned char shadow3_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0xf3,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x12,0xed,0x7f, + 0x7f,0xf6,0x55,0x57,0xa4,0x3f,0x3f,0xfb,0x33,0x33,0xfc,0x2a,0x2b,0x52, + 0x48,0x4a,0xb4,0x3f,0x3f,0x7d,0x38,0x3a,0x36,0x33,0x33,0xfe,0x2e,0x2f, + 0xcf,0x2a,0x2b,0xa9,0x3f,0x3f,0xa9,0x3a,0x3b,0x9b,0x36,0x37,0x7e,0x44, + 0x33,0x65,0x44,0x45,0x65,0x3f,0x3f,0x5e,0x3c,0x3d,0x4a,0x38,0x39,0x37, + 0x35,0x35,0x27,0x3f,0x33,0x18,0x3c,0x3c,0xff,0x39,0x39,0xff,0x37,0x37, + 0xf3,0x35,0x35,0xe9,0x33,0x33,0xe0,0x3d,0x33,0xe0,0x3a,0x3a,0xd7,0x36, + 0x36,0xd1,0x34,0x34,0xca,0x33,0x33,0xc3,0x39,0x31,0xbd,0x39,0x39,0xbd, + 0x37,0x37,0xb7,0x3d,0x36,0xb9,0x3c,0x3c,0xac,0x3a,0x3a,0xa7,0x38,0x38, + 0xaa,0x3c,0x35,0xa1,0x3a,0x3a,0x9c,0x37,0x37,0x95,0x37,0x37,0x9b,0x36, + 0x36,0x97,0x39,0x34,0x90,0x37,0x37,0x8a,0x3b,0x3b,0x87,0x3a,0x3a,0x84, + 0x39,0x39,0x82,0x37,0x37,0x82,0x38,0x38,0x7a,0x37,0x37,0x78,0x37,0x37, + 0x7d,0x36,0x36,0x7a,0x3b,0x37,0x72,0x39,0x39,0x6f,0x37,0x37,0x6b,0x37, + 0x37,0x6f,0x3a,0x36,0x6d,0x39,0x39,0x6c,0x38,0x38,0x69,0x3a,0x36,0x69, + 0x38,0x38,0x66,0x37,0x37,0x60,0x39,0x35,0x61,0x39,0x39,0x61,0x39,0x39, + 0x5c,0x37,0x37,0x5d,0x39,0x39,0x5d,0x38,0x38,0x5b,0x37,0x37,0x56,0x39, + 0x37,0x54,0x37,0x37,0x50,0x38,0x38,0x50,0x3a,0x37,0x50,0x3a,0x38,0x4f, + 0x38,0x38,0x4e,0x39,0x36,0x4a,0x37,0x37,0x4b,0x3a,0x37,0x48,0x8a,0x22, + 0xb0,0xc3,0x00,0x00,0x00,0x51,0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x19,0x1a,0x1c,0x1d, + 0x1e,0x1f,0x1f,0x20,0x21,0x22,0x23,0x24,0x26,0x27,0x29,0x29,0x2a,0x2c, + 0x2e,0x2f,0x30,0x31,0x33,0x36,0x37,0x37,0x38,0x3c,0x3e,0x40,0x40,0x41, + 0x42,0x44,0x46,0x48,0x4a,0x4c,0x4c,0x50,0x52,0x55,0x56,0x58,0x61,0x65, + 0x68,0x69,0x6d,0x71,0x74,0x77,0x7b,0x7c,0xdb,0xec,0x46,0x00,0x00,0x01, + 0x80,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x95,0xb1,0x72,0x83,0x30,0x10, + 0x44,0xf7,0xf0,0x35,0xf9,0x8a,0x74,0x49,0x97,0x99,0xfc,0xff,0x67,0x25, + 0x85,0x0d,0xba,0xdd,0x14,0x48,0x20,0xc0,0x80,0xec,0x99,0x74,0x96,0xc7, + 0x2e,0xec,0x7b,0x7e,0xab,0xd3,0x01,0x06,0xbc,0x7f,0xf5,0x3f,0xd7,0xdf, + 0xdb,0x30,0x04,0x83,0x20,0x24,0x09,0x82,0x04,0x40,0xc0,0xf4,0x59,0xaf, + 0x0e,0xf8,0x10,0x3b,0x98,0x75,0xd6,0x99,0x75,0xb0,0xe9,0x27,0xcb,0xef, + 0x7b,0xcb,0xdf,0x3f,0xdf,0xfa,0x08,0xc1,0x60,0x30,0x13,0x00,0x98,0x4c, + 0x26,0x1c,0x2d,0xff,0x66,0x62,0x30,0xa0,0xfc,0x9a,0x65,0x47,0xa0,0xf7, + 0xe4,0x90,0x52,0x50,0x34,0x58,0x16,0x9d,0xa8,0x00,0x78,0xaf,0x48,0xc3, + 0x10,0x5a,0xb9,0xce,0xb1,0x21,0x86,0x08,0x8a,0x82,0x4e,0xa2,0x55,0xd8, + 0x95,0x8c,0x48,0x8c,0x18,0x65,0x8d,0x42,0xbf,0x49,0x11,0x91,0x48,0xe8, + 0x81,0x94,0xde,0x4b,0x64,0x62,0x12,0xa5,0x07,0xf6,0x96,0x40,0x32,0x28, + 0xe6,0xa9,0x68,0x6b,0x8d,0xf7,0x90,0x48,0x11,0x04,0xab,0xfa,0x13,0xd6, + 0x43,0x92,0x24,0x0a,0x2c,0xb5,0x0d,0x3a,0x4f,0x80,0x40,0x49,0x12,0xca, + 0x00,0x63,0x1a,0xe0,0x3d,0xde,0x05,0x49,0x79,0xea,0x77,0x5c,0xba,0x17, + 0x12,0x40,0xe6,0x66,0xe5,0x69,0x4e,0x07,0x91,0xc3,0x69,0xea,0xe5,0x9e, + 0xa3,0xc2,0x38,0x43,0x39,0x6f,0xa5,0xda,0x45,0x7d,0x8c,0x35,0x6f,0x4e, + 0x9b,0x0b,0x5a,0x3b,0xb6,0xd1,0x37,0x3a,0x27,0xd9,0xf1,0x80,0xba,0xca, + 0xd6,0x50,0x07,0x3c,0x3b,0x38,0xcf,0xad,0x2b,0x9e,0xb9,0x95,0xfb,0xf7, + 0x9f,0x29,0x64,0xa9,0xd4,0x79,0xbc,0x72,0x00,0x98,0xfe,0x5b,0x59,0xbb, + 0xd0,0x08,0x07,0x36,0x94,0xbd,0x95,0xbc,0x4d,0xb6,0x71,0x52,0x96,0xd4, + 0x91,0xac,0x74,0xb2,0x44,0x6b,0xa4,0xe0,0xaa,0x0a,0xaa,0xe1,0xd2,0xf9, + 0x01,0x2c,0xc1,0x9a,0xd2,0x21,0x36,0x55,0x68,0x99,0x4d,0x87,0x2d,0xa9, + 0xaa,0x1a,0xa9,0xa5,0xad,0xe5,0x92,0x59,0xdb,0xb4,0x9e,0xf8,0x23,0xfa, + 0x62,0xab,0x12,0xa1,0x81,0x2a,0xd8,0x63,0x50,0x0e,0xb9,0xad,0x6d,0x19, + 0xe5,0x6d,0x65,0xd3,0x4c,0xae,0xcb,0x1a,0x3a,0x79,0xd9,0x7e,0xd5,0xf2, + 0x00,0xf1,0x67,0xa0,0x0d,0xd6,0xfa,0xa8,0xf2,0x27,0x98,0x0a,0x7b,0x00, + 0x79,0xad,0xd7,0xfa,0xd7,0xf5,0x07,0x87,0x35,0x6e,0x77,0xf8,0xc7,0x73, + 0x23,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +static const unsigned int shadow4_png_len = 297; +static const unsigned char shadow4_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0x57,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x2e,0x2e,0x2e,0x3f,0x3f, + 0x2a,0x3a,0x3a,0x3a,0x36,0x36,0x36,0x44,0x44,0x33,0x3f,0x3f,0x3f,0x38, + 0x38,0x38,0x3c,0x3c,0x30,0x39,0x39,0x39,0x3d,0x32,0x32,0x34,0x34,0x34, + 0x3c,0x3c,0x34,0x3a,0x3a,0x34,0x3b,0x3b,0x36,0x36,0x36,0x36,0x3a,0x36, + 0x36,0x37,0x37,0x34,0x38,0x38,0x35,0x3a,0x37,0x33,0x1e,0xab,0x31,0x76, + 0x00,0x00,0x00,0x1d,0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03,0x04,0x05, + 0x06,0x07,0x08,0x09,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x12,0x15,0x16,0x19, + 0x1d,0x22,0x27,0x2f,0x38,0x46,0x52,0x68,0x7b,0xd0,0xa6,0x2f,0x41,0x00, + 0x00,0x00,0x40,0x49,0x44,0x41,0x54,0x48,0xc7,0x63,0x60,0xa0,0x27,0x60, + 0x14,0x21,0x4b,0x1b,0x0b,0x07,0x79,0xda,0xfe,0x8f,0x6a,0x1b,0xd5,0x36, + 0xb8,0xb4,0x31,0x31,0x8c,0x06,0xc9,0x08,0x8a,0x80,0xd1,0xe8,0x1e,0x9a, + 0x11,0xc0,0xcc,0x48,0x4f,0x6d,0x64,0x3a,0x92,0xbe,0xda,0x98,0x19,0x86, + 0xaf,0xdf,0xc8,0xd4,0x36,0x0a,0x46,0x01,0xcd,0x00,0x00,0xa7,0x1f,0x18, + 0x8d,0x3d,0xb2,0x05,0x84,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae, + 0x42,0x60,0x82 +}; + +static const unsigned int shadow5_png_len = 807; +static const unsigned char shadow5_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0xf3,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x33,0x33,0x33,0x2e,0x2e, + 0x2e,0x2a,0x2a,0x2a,0x3f,0x3f,0x2a,0x3a,0x3a,0x3a,0x36,0x36,0x36,0x44, + 0x33,0x33,0x44,0x44,0x33,0x3f,0x3f,0x3f,0x3c,0x3c,0x3c,0x38,0x38,0x38, + 0x35,0x35,0x35,0x3f,0x33,0x33,0x3c,0x3c,0x30,0x39,0x39,0x39,0x37,0x37, + 0x37,0x35,0x35,0x35,0x33,0x33,0x33,0x3d,0x33,0x33,0x3a,0x3a,0x31,0x36, + 0x36,0x36,0x34,0x34,0x34,0x33,0x33,0x33,0x39,0x31,0x31,0x39,0x39,0x31, + 0x37,0x37,0x2f,0x3d,0x36,0x36,0x3c,0x3c,0x34,0x3a,0x3a,0x33,0x38,0x38, + 0x38,0x3c,0x35,0x35,0x3a,0x3a,0x34,0x37,0x37,0x31,0x37,0x37,0x37,0x36, + 0x36,0x36,0x39,0x34,0x34,0x37,0x37,0x31,0x3b,0x3b,0x36,0x3a,0x3a,0x35, + 0x39,0x39,0x34,0x37,0x37,0x37,0x38,0x38,0x33,0x37,0x37,0x33,0x37,0x37, + 0x37,0x36,0x36,0x36,0x3b,0x37,0x33,0x39,0x39,0x35,0x37,0x37,0x33,0x37, + 0x37,0x37,0x3a,0x36,0x36,0x39,0x39,0x36,0x38,0x38,0x34,0x3a,0x36,0x36, + 0x38,0x38,0x35,0x37,0x37,0x33,0x39,0x35,0x35,0x39,0x39,0x35,0x39,0x39, + 0x33,0x37,0x37,0x34,0x39,0x39,0x36,0x38,0x38,0x35,0x37,0x37,0x34,0x39, + 0x37,0x34,0x37,0x37,0x35,0x38,0x38,0x35,0x3a,0x37,0x35,0x3a,0x38,0x35, + 0x38,0x38,0x36,0x39,0x36,0x34,0x38,0x38,0x36,0x3a,0x37,0x33,0x37,0x71, + 0x96,0x1c,0x00,0x00,0x00,0x51,0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x19,0x1a,0x1c,0x1d, + 0x1e,0x1f,0x1f,0x20,0x21,0x22,0x23,0x24,0x26,0x27,0x29,0x29,0x2a,0x2c, + 0x2e,0x2f,0x30,0x31,0x33,0x36,0x37,0x37,0x38,0x3c,0x3e,0x40,0x40,0x41, + 0x42,0x44,0x46,0x48,0x4a,0x4c,0x4c,0x50,0x52,0x55,0x56,0x58,0x61,0x65, + 0x68,0x69,0x6d,0x71,0x74,0x76,0x7b,0x65,0xc0,0xdd,0x07,0x00,0x00,0x01, + 0x6e,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x95,0x49,0x76,0x83,0x30,0x10, + 0x44,0xab,0xaa,0x71,0x86,0xf7,0x92,0x0b,0x64,0x91,0x65,0xee,0x7f,0x95, + 0x5c,0x21,0xd7,0x88,0xad,0xca,0x42,0x58,0xb2,0x41,0x08,0x91,0xb5,0x1b, + 0x1e,0x63,0x7f,0xaa,0x27,0x80,0x58,0x19,0xcb,0x96,0x04,0x41,0x92,0x10, + 0x14,0x8a,0xd3,0xe9,0xf9,0xed,0xe5,0xfd,0xe9,0xfb,0x07,0x42,0xdb,0x58, + 0xf8,0x7c,0x26,0x52,0x14,0x09,0x25,0x7f,0x01,0xb1,0xa1,0x96,0x31,0x12, + 0x84,0x40,0x92,0x12,0x15,0x11,0xa7,0x08,0xbd,0x7e,0x5e,0xba,0x18,0x31, + 0x2f,0x24,0x44,0x31,0x34,0x69,0x8a,0xc0,0xd3,0xc7,0x3e,0x36,0xa7,0x46, + 0x51,0x94,0x24,0x01,0x29,0x4d,0x18,0x35,0xc3,0xb0,0x2f,0xbf,0x41,0x07, + 0xc7,0xd4,0x66,0x49,0x4a,0x10,0x9c,0x30,0xaa,0x66,0x02,0xa6,0x2f,0xe2, + 0x99,0x8e,0xb3,0x86,0x83,0x34,0x6d,0xa4,0x74,0x26,0x52,0xe2,0x68,0x90, + 0x60,0x5e,0x4d,0xc3,0x29,0xa5,0xb1,0x06,0xcc,0x4d,0x20,0x08,0xc0,0xde, + 0xc9,0xcd,0x34,0xeb,0x71,0x8a,0x14,0x09,0xb6,0xc8,0xbd,0x29,0xc1,0x6d, + 0x9c,0xf9,0x8e,0x6d,0x7b,0xea,0x96,0xae,0xf6,0x8c,0x26,0x6c,0x20,0x51, + 0x66,0x73,0x26,0xdb,0xd3,0xc5,0xeb,0x68,0x1b,0xd8,0xc3,0x0a,0x75,0x3b, + 0x2c,0xe8,0x04,0x59,0x22,0x2d,0x95,0x31,0x40,0xcf,0xa0,0x36,0xd5,0xae, + 0x51,0x96,0x5a,0xd4,0x10,0x09,0x07,0x46,0xa2,0x44,0x49,0x8d,0x30,0x6c, + 0x6c,0x63,0x0b,0x39,0xde,0x5e,0xf6,0x1e,0x76,0x05,0xe6,0x9d,0x3b,0x95, + 0x6c,0x70,0x28,0x09,0x1a,0x06,0x30,0x0d,0xbd,0x31,0xb9,0xe1,0xf9,0x59, + 0x86,0xb7,0xd4,0x16,0x72,0x39,0x9f,0x7c,0x68,0xd4,0x34,0x3b,0x58,0xe1, + 0x58,0xcb,0xb9,0x89,0xb5,0xb9,0x79,0x5c,0xb6,0xd5,0x9a,0x5c,0xc5,0xf7, + 0xb0,0xfb,0x2a,0xd6,0x87,0x6d,0x62,0x0b,0xee,0x0e,0xea,0xa8,0x2d,0xb2, + 0x67,0x9d,0x38,0xf4,0xb1,0x25,0x77,0x7b,0x3e,0x80,0xb5,0xdc,0x7b,0xd8, + 0xda,0x89,0x23,0x6a,0x4b,0xff,0x65,0x63,0x8e,0x81,0x23,0xd8,0x4a,0x67, + 0x10,0x6b,0x7b,0x73,0xe0,0xaf,0xc1,0xf6,0x17,0xe3,0x20,0x37,0x8c,0xad, + 0xdd,0x06,0xb1,0xc3,0x95,0x6c,0xfb,0x1e,0xc1,0xfe,0xe3,0xff,0xb0,0x87, + 0x1d,0xb5,0x3f,0xf4,0x3b,0x5c,0xd6,0x3e,0xab,0x62,0x7a,0x00,0x00,0x00, + 0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +static const unsigned int shadow6_png_len = 260; +static const unsigned char shadow6_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0x45,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x2e,0x2e,0x2e,0x3f,0x3f, + 0x2a,0x44,0x33,0x33,0x3f,0x3f,0x3f,0x35,0x35,0x35,0x35,0x35,0x35,0x36, + 0x36,0x36,0x34,0x34,0x34,0x3a,0x3a,0x32,0x37,0x37,0x37,0x37,0x37,0x37, + 0x37,0x37,0x34,0x38,0x38,0x36,0x84,0xea,0xd7,0xaa,0x00,0x00,0x00,0x17, + 0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, + 0x0b,0x0c,0x0f,0x10,0x13,0x18,0x1c,0x1d,0x23,0x33,0x40,0x58,0x71,0xe5, + 0xe3,0x45,0xdc,0x00,0x00,0x00,0x33,0x49,0x44,0x41,0x54,0x48,0xc7,0xed, + 0xcb,0x21,0x02,0x00,0x30,0x08,0xc3,0xc0,0x86,0xff,0x3f,0x16,0x3d,0x35, + 0x87,0xd9,0x14,0x3a,0x11,0xad,0x3a,0xf2,0xc4,0x2c,0x84,0xc0,0x1c,0x05, + 0xc0,0xe9,0x54,0x56,0xc9,0x64,0x32,0x99,0x4c,0x26,0x93,0xc9,0x64,0xb2, + 0x7f,0x17,0x4b,0xb1,0x02,0x6c,0xc7,0x80,0xd6,0xd0,0x00,0x00,0x00,0x00, + 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + +static const unsigned int shadow7_png_len = 591; +static const unsigned char shadow7_png_data[] = { + 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48, + 0x44,0x52,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x36,0x08,0x03,0x00,0x00, + 0x00,0xbb,0x9b,0x9a,0xef,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x08, + 0x08,0x08,0xdb,0xe1,0x4f,0xe0,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73, + 0x00,0x00,0x0b,0x89,0x00,0x00,0x0b,0x89,0x01,0x37,0xc9,0xcb,0xad,0x00, + 0x00,0x00,0xb7,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x7f, + 0x7f,0x7f,0x55,0x55,0x55,0x3f,0x3f,0x3f,0x33,0x33,0x33,0x2a,0x2a,0x2a, + 0x48,0x48,0x24,0x3f,0x3f,0x3f,0x38,0x38,0x38,0x33,0x33,0x33,0x2e,0x2e, + 0x2e,0x2a,0x2a,0x2a,0x3f,0x3f,0x2a,0x3a,0x3a,0x3a,0x36,0x36,0x36,0x44, + 0x33,0x33,0x44,0x44,0x33,0x3f,0x3f,0x3f,0x3c,0x3c,0x3c,0x38,0x38,0x38, + 0x35,0x35,0x35,0x3c,0x3c,0x30,0x39,0x39,0x39,0x37,0x37,0x37,0x35,0x35, + 0x35,0x33,0x33,0x33,0x3d,0x33,0x33,0x3a,0x3a,0x31,0x36,0x36,0x36,0x34, + 0x34,0x34,0x33,0x33,0x33,0x39,0x39,0x31,0x3d,0x36,0x36,0x3c,0x3c,0x34, + 0x38,0x38,0x38,0x3a,0x3a,0x34,0x39,0x39,0x33,0x36,0x36,0x36,0x37,0x37, + 0x31,0x3a,0x3a,0x35,0x39,0x39,0x34,0x38,0x38,0x38,0x3a,0x35,0x35,0x37, + 0x37,0x37,0x3a,0x35,0x35,0x3a,0x3a,0x36,0x39,0x39,0x35,0x37,0x37,0x37, + 0x3a,0x36,0x36,0x37,0x37,0x34,0x37,0x37,0x33,0x39,0x36,0x36,0x39,0x39, + 0x33,0x3a,0x37,0x34,0x39,0x36,0x36,0x38,0x38,0x33,0x38,0x38,0x36,0x37, + 0x37,0x35,0x39,0x37,0x34,0x39,0x37,0x35,0x69,0x11,0xda,0xe4,0x00,0x00, + 0x00,0x3d,0x74,0x52,0x4e,0x53,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x13, + 0x15,0x16,0x17,0x18,0x19,0x19,0x1a,0x1c,0x1d,0x1e,0x1f,0x21,0x22,0x24, + 0x27,0x28,0x2a,0x2e,0x30,0x31,0x32,0x34,0x37,0x39,0x3d,0x3e,0x40,0x46, + 0x49,0x4a,0x4b,0x50,0x53,0x54,0x5e,0x63,0x65,0x66,0x6e,0x1e,0x62,0xb1, + 0x6f,0x00,0x00,0x00,0xe6,0x49,0x44,0x41,0x54,0x48,0xc7,0xed,0x94,0x41, + 0x8e,0x83,0x30,0x10,0x04,0xa7,0xba,0xc7,0x89,0xf2,0xff,0x7f,0xe5,0x1f, + 0xbb,0x1f,0x58,0xed,0x6d,0x0f,0x60,0x04,0x84,0x60,0xc7,0xd2,0xde,0xe8, + 0x03,0x70,0x98,0x56,0xf5,0xb4,0x2d,0x22,0x2e,0x5d,0xba,0x74,0xe9,0xd2, + 0x3f,0x88,0xb1,0x71,0xc6,0x10,0x8c,0xc5,0x62,0x6c,0x17,0xc6,0x0a,0x60, + 0x2c,0x1e,0x63,0x45,0xd0,0x6d,0xe2,0x83,0x90,0xbc,0x99,0xe3,0x43,0x17, + 0x1d,0x36,0x8e,0xde,0xb4,0x6c,0xbc,0x10,0xe8,0x08,0xc9,0xbe,0xf2,0x55, + 0xf7,0xd9,0xd9,0x3f,0xdb,0x70,0x34,0xe6,0x59,0x99,0x7a,0x68,0x6c,0xbe, + 0x59,0x55,0xc1,0x09,0x8d,0x4d,0x77,0x2c,0xc3,0x33,0x37,0xdb,0x8b,0x55, + 0x17,0x3b,0xea,0xf9,0x62,0x2b,0x57,0x7d,0x42,0x47,0x93,0x15,0x44,0x04, + 0x00,0x7a,0x5b,0x09,0xfb,0x03,0x9b,0x21,0x81,0x01,0x4e,0x77,0x5b,0x55, + 0x37,0xbb,0x90,0x10,0x82,0x63,0x1a,0x9b,0x88,0x44,0x2c,0x2e,0x61,0xa9, + 0x64,0xf3,0x96,0x4c,0x48,0x26,0xa0,0x24,0xbb,0x14,0xa3,0x3c,0x35,0x2c, + 0x11,0x83,0x50,0xd8,0xd8,0xf7,0xe2,0xcc,0xc3,0xdd,0xd8,0xf5,0x38,0xfb, + 0x2c,0x9c,0x99,0x37,0xdf,0xad,0x6c,0xc1,0xea,0x11,0x80,0x90,0x5c,0x6e, + 0x7e,0xe4,0xcf,0x77,0x76,0xfd,0xef,0x08,0x10,0xc2,0xb2,0x8b,0x7e,0x9f, + 0xa1,0xb6,0xa1,0x5e,0x91,0xa9,0x4a,0xd9,0x5f,0x11,0x7f,0xe8,0x0a,0x06, + 0x53,0xfb,0x2a,0xa1,0x09,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae, + 0x42,0x60,0x82 +}; + +#endif diff --git a/src/qtcurve/style/shadowhelper.cpp b/src/qtcurve/style/shadowhelper.cpp new file mode 100644 index 0000000000..e9a07dc608 --- /dev/null +++ b/src/qtcurve/style/shadowhelper.cpp @@ -0,0 +1,285 @@ +////////////////////////////////////////////////////////////////////////////// +// oxygenshadowhelper.h +// handle shadow _pixmaps passed to window manager via X property +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include "shadowhelper.h" +#include "shadow.h" +#include "utils.h" + +#include +#include +#include +#include +#include + +#ifdef Q_WS_X11 +#include +#include +#include +#endif + +namespace QtCurve +{ + + const char* const ShadowHelper::netWMShadowAtomName( "_KDE_NET_WM_SHADOW" ); + const char* const ShadowHelper::netWMForceShadowPropertyName( "_KDE_NET_WM_FORCE_SHADOW" ); + const char* const ShadowHelper::netWMSkipShadowPropertyName( "_KDE_NET_WM_SKIP_SHADOW" ); + + //_____________________________________________________ + ShadowHelper::ShadowHelper( QObject* parent ): + QObject( parent ), + #ifdef Q_WS_X11 + _atom( None ) + #endif + { + createPixmapHandles(); + } + + //_______________________________________________________ + ShadowHelper::~ShadowHelper( void ) + { + + #ifdef Q_WS_X11 + for(int i=0; itestAttribute(Qt::WA_WState_Created) && installX11Shadows( widget ) ) + { _widgets.insert( widget, widget->winId() ); } + + connect( widget, SIGNAL( destroyed( QObject* ) ), SLOT( objectDeleted( QObject* ) ) ); + + return true; + + } + + //_______________________________________________________ + void ShadowHelper::unregisterWidget( QWidget* widget ) + { + if( _widgets.remove( widget ) ) + { uninstallX11Shadows( widget ); } + } + + //_______________________________________________________ + bool ShadowHelper::eventFilter( QObject* object, QEvent* event ) + { + + // check event type + if( event->type() != QEvent::WinIdChange ) return false; + + // cast widget + QWidget* widget( static_cast( object ) ); + + // install shadows and update winId + if( installX11Shadows( widget ) ) + { _widgets.insert( widget, widget->winId() ); } + + return false; + + } + + //_______________________________________________________ + void ShadowHelper::objectDeleted( QObject* object ) + { _widgets.remove( static_cast( object ) ); } + + //_______________________________________________________ + bool ShadowHelper::isMenu( QWidget* widget ) const + { return qobject_cast( widget ); } + + //_______________________________________________________ + bool ShadowHelper::acceptWidget( QWidget* widget ) const + { + + if( widget->property( netWMSkipShadowPropertyName ).toBool() ) return false; + if( widget->property( netWMForceShadowPropertyName ).toBool() ) return true; + + // menus + if( qobject_cast( widget ) ) return true; + + // combobox dropdown lists + if( widget->inherits( "QComboBoxPrivateContainer" ) ) return true; + + // tooltips + if( (widget->inherits( "QTipLabel" ) || (widget->windowFlags() & Qt::WindowType_Mask) == Qt::ToolTip ) && + !widget->inherits( "Plasma::ToolTip" ) ) + { return true; } + + // detached widgets + if( qobject_cast( widget ) || qobject_cast( widget ) ) + { return true; } + + // reject + return false; + } + + //______________________________________________ + void ShadowHelper::createPixmapHandles( ) + { + + /*! + shadow atom and property specification available at + http://community.kde.org/KWin/Shadow + */ + + // create atom + #ifdef Q_WS_X11 + if( !_atom ) _atom = XInternAtom( QX11Info::display(), netWMShadowAtomName, False); + #endif + + _pixmaps[0]=createPixmap(shadow0_png_data, shadow0_png_len); + _pixmaps[1]=createPixmap(shadow1_png_data, shadow1_png_len); + _pixmaps[2]=createPixmap(shadow2_png_data, shadow2_png_len); + _pixmaps[3]=createPixmap(shadow3_png_data, shadow3_png_len); + _pixmaps[4]=createPixmap(shadow4_png_data, shadow4_png_len); + _pixmaps[5]=createPixmap(shadow5_png_data, shadow5_png_len); + _pixmaps[6]=createPixmap(shadow6_png_data, shadow6_png_len); + _pixmaps[7]=createPixmap(shadow7_png_data, shadow7_png_len); + } + + //______________________________________________ + Qt::HANDLE ShadowHelper::createPixmap( const uchar *buf, int len ) + { + QImage source; + source.loadFromData(buf, len); + + // do nothing for invalid _pixmaps + if( source.isNull() ) return 0; + + _size=source.width(); + + /* + in some cases, pixmap handle is invalid. This is the case notably + when Qt uses to RasterEngine. In this case, we create an X11 Pixmap + explicitly and draw the source pixmap on it. + */ + + #ifdef Q_WS_X11 + const int width( source.width() ); + const int height( source.height() ); + + // create X11 pixmap + Pixmap pixmap = XCreatePixmap( QX11Info::display(), QX11Info::appRootWindow(), width, height, 32 ); + + // create explicitly shared QPixmap from it + QPixmap dest( QPixmap::fromX11Pixmap( pixmap, QPixmap::ExplicitlyShared ) ); + + // create surface for pixmap + { + QPainter painter( &dest ); + painter.setCompositionMode( QPainter::CompositionMode_Source ); + painter.drawImage( 0, 0, source ); + } + + + return pixmap; + #else + return 0; + #endif + + } + +//_______________________________________________________ + bool ShadowHelper::installX11Shadows( QWidget* widget ) + { + + // check widget and shadow + if( !widget ) return false; + + #ifdef Q_WS_X11 + #ifndef QT_NO_XRENDER + + // TODO: also check for NET_WM_SUPPORTED atom, before installing shadow + + /* + From bespin code. Supposibly prevent playing with some 'pseudo-widgets' + that have winId matching some other -random- window + */ + if( !(widget->testAttribute(Qt::WA_WState_Created) || widget->internalWinId() )) + { return false; } + + // create data + // add pixmap handles + QVector data; + for(int i=0; iwinId(), _atom, XA_CARDINAL, 32, PropModeReplace, + reinterpret_cast(data.constData()), data.size() ); + + return true; + + #endif + #endif + + return false; + + } + + //_______________________________________________________ + void ShadowHelper::uninstallX11Shadows( QWidget* widget ) const + { + + #ifdef Q_WS_X11 + if( !( widget && widget->testAttribute(Qt::WA_WState_Created) ) ) return; + XDeleteProperty(QX11Info::display(), widget->winId(), _atom); + #endif + + } + + //_______________________________________________________ + void ShadowHelper::uninstallX11Shadows( WId id ) const + { + + #ifdef Q_WS_X11 + XDeleteProperty(QX11Info::display(), id, _atom); + #endif + + } + +} diff --git a/src/qtcurve/style/shadowhelper.h b/src/qtcurve/style/shadowhelper.h new file mode 100644 index 0000000000..c5199779c2 --- /dev/null +++ b/src/qtcurve/style/shadowhelper.h @@ -0,0 +1,126 @@ +#ifndef shadowhelper_h +#define shadowhelper_h + +////////////////////////////////////////////////////////////////////////////// +// oxygenshadowhelper.h +// handle shadow pixmaps passed to window manager via X property +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#ifdef Q_WS_X11 +#include +#endif + +class QPixmap; + +namespace QtCurve +{ + //! handle shadow pixmaps passed to window manager via X property + class ShadowHelper: public QObject + { + Q_OBJECT + + public: + + //!@name property names + static const char* const netWMShadowAtomName; + static const char* const netWMForceShadowPropertyName; + static const char* const netWMSkipShadowPropertyName; + + //! constructor + ShadowHelper( QObject* ); + + //! destructor + virtual ~ShadowHelper( void ); + + //! register widget + bool registerWidget( QWidget*, bool force = false ); + + //! unregister widget + void unregisterWidget( QWidget* ); + + //! event filter + virtual bool eventFilter( QObject*, QEvent* ); + + protected Q_SLOTS: + + //! unregister widget + void objectDeleted( QObject* ); + + protected: + + //! true if widget is a menu + bool isMenu( QWidget* ) const; + + //! accept widget + bool acceptWidget( QWidget* ) const; + + // create pixmap handles from tileset + void createPixmapHandles( ); + + // create pixmap handle from pixmap + Qt::HANDLE createPixmap( const uchar *buf, int len ); + + //! install shadow X11 property on given widget + /*! + shadow atom and property specification available at + http://community.kde.org/KWin/Shadow + */ + bool installX11Shadows( QWidget* ); + + //! uninstall shadow X11 property on given widget + void uninstallX11Shadows( QWidget* ) const; + + //! uninstall shadow X11 property on given window + void uninstallX11Shadows( WId ) const; + + private: + + //! set of registered widgets + QMap _widgets; + + //! number of pixmaps + enum { numPixmaps = 8 }; + + //!@name pixmaps + //@{ + Qt::HANDLE _pixmaps[numPixmaps]; + //@} + + //! shadow size + int _size; + + #ifdef Q_WS_X11 + //! shadow atom + Atom _atom; + #endif + + }; + +} + +#endif diff --git a/src/qtcurve/style/shortcuthandler.cpp b/src/qtcurve/style/shortcuthandler.cpp new file mode 100644 index 0000000000..d04ce7b8fb --- /dev/null +++ b/src/qtcurve/style/shortcuthandler.cpp @@ -0,0 +1,179 @@ +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "shortcuthandler.h" +#include + +namespace QtCurve +{ + +ShortcutHandler::ShortcutHandler(QObject *parent) + : QObject(parent) + , itsAltDown(false) +{ +} + +ShortcutHandler::~ShortcutHandler() +{ +} + +bool ShortcutHandler::hasSeenAlt(const QWidget *widget) const +{ + if(widget && !widget->isEnabled()) + return false; + + if(qobject_cast(widget)) + return itsOpenMenus.count() && itsOpenMenus.last()==widget; +// { +// const QWidget *w=widget; +// +// while(w) +// { +// if(itsSeenAlt.contains((QWidget *)w)) +// return true; +// w=w->parentWidget(); +// } +// } + else + return itsOpenMenus.isEmpty() && itsSeenAlt.contains((QWidget *)(widget->window())); + + return false; +} + +bool ShortcutHandler::showShortcut(const QWidget *widget) const +{ + return itsAltDown && hasSeenAlt(widget); +} + +void ShortcutHandler::widgetDestroyed(QObject *o) +{ + itsUpdated.remove(static_cast(o)); + itsOpenMenus.removeAll(static_cast(o)); +} + +void ShortcutHandler::updateWidget(QWidget *w) +{ + if(!itsUpdated.contains(w)) + { + itsUpdated.insert(w); + w->update(); + connect(w, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } +} + +bool ShortcutHandler::eventFilter(QObject *o, QEvent *e) +{ + if (!o->isWidgetType()) + return QObject::eventFilter(o, e); + + QWidget *widget = qobject_cast(o); + switch(e->type()) + { + case QEvent::KeyPress: + if (Qt::Key_Alt==static_cast(e)->key()) + { + itsAltDown = true; + if(qobject_cast(widget)) + { + itsSeenAlt.insert(widget); + updateWidget(widget); + if(widget->parentWidget() && widget->parentWidget()->window()) + itsSeenAlt.insert(widget->parentWidget()->window()); + } + else + { + widget = widget->window(); + itsSeenAlt.insert(widget); + QList l = qFindChildren(widget); + for (int pos=0 ; pos < l.size() ; ++pos) + { + QWidget *w = l.at(pos); + if (!(w->isWindow() || !w->isVisible())) // || w->style()->styleHint(QStyle::SH_UnderlineShortcut, 0, w))) + updateWidget(w); + } + + QList m = qFindChildren(widget); + for (int i = 0; i < m.size(); ++i) + updateWidget(m.at(i)); + } + } + break; + case QEvent::WindowDeactivate: + case QEvent::KeyRelease: + if (QEvent::WindowDeactivate==e->type() || Qt::Key_Alt==static_cast(e)->key()) + { + itsAltDown = false; + QSet::ConstIterator it(itsUpdated.constBegin()), + end(itsUpdated.constEnd()); + + for (; it!=end; ++it) + (*it)->update(); + if(!itsUpdated.contains(widget)) + widget->update(); + itsSeenAlt.clear(); + itsUpdated.clear(); + } + break; + case QEvent::Show: + if(qobject_cast(widget)) + { + QWidget *prev=itsOpenMenus.count() ? itsOpenMenus.last() : 0L; + itsOpenMenus.append(widget); + if(itsAltDown && prev) + prev->update(); + connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *))); + } + break; + case QEvent::Hide: + if(qobject_cast(widget)) + { + itsSeenAlt.remove(widget); + itsUpdated.remove(widget); + itsOpenMenus.removeAll(widget); + if(itsAltDown) + { + if(itsOpenMenus.count()) + itsOpenMenus.last()->update(); + else if(widget->parentWidget() && widget->parentWidget()->window()) + widget->parentWidget()->window()->update(); + } + } + break; + case QEvent::Close: + // Reset widget when closing + itsSeenAlt.remove(widget); + itsUpdated.remove(widget); + itsSeenAlt.remove(widget->window()); + itsOpenMenus.removeAll(widget); + if(itsAltDown) + { + if(itsOpenMenus.count()) + itsOpenMenus.last()->update(); + else if(widget->parentWidget() && widget->parentWidget()->window()) + widget->parentWidget()->window()->update(); + } + break; + default: + break; + } + return QObject::eventFilter(o, e); +} + +} diff --git a/src/qtcurve/style/shortcuthandler.h b/src/qtcurve/style/shortcuthandler.h new file mode 100644 index 0000000000..503bd86412 --- /dev/null +++ b/src/qtcurve/style/shortcuthandler.h @@ -0,0 +1,65 @@ +#ifndef __SHORTCUT_HANDLER_H__ +#define __SHORTCUT_HANDLER_H__ + +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +class QWidget; + +namespace QtCurve +{ + +class ShortcutHandler : public QObject +{ + Q_OBJECT + + public: + + explicit ShortcutHandler(QObject *parent = 0); + virtual ~ShortcutHandler(); + + bool hasSeenAlt(const QWidget *widget) const; + bool isAltDown() const { return itsAltDown; } + bool showShortcut(const QWidget *widget) const; + + private Q_SLOTS: + + void widgetDestroyed(QObject *o); + + protected: + + void updateWidget(QWidget *w); + bool eventFilter(QObject *watched, QEvent *event); + + private: + + bool itsAltDown; + QSet itsSeenAlt, + itsUpdated; + QList itsOpenMenus; +}; + +} + +#endif \ No newline at end of file diff --git a/src/qtcurve/style/utils.cpp b/src/qtcurve/style/utils.cpp new file mode 100644 index 0000000000..cc3b84f7b7 --- /dev/null +++ b/src/qtcurve/style/utils.cpp @@ -0,0 +1,81 @@ +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "utils.h" +#include "config.h" +#include +#ifdef Q_WS_X11 +#include +#include +#include "fixx11h.h" +#include +#endif + +#if defined QTC_QT_ONLY +#undef KDE_IS_VERSION +#define KDE_IS_VERSION(A, B, C) 0 +#else +#include +#include +#endif + +namespace QtCurve +{ + namespace Utils + { + bool compositingActive() + { + #if defined QTC_QT_ONLY || !KDE_IS_VERSION(4, 4, 0) + #ifdef Q_WS_X11 + static bool haveAtom=false; + static Atom atom; + if(!haveAtom) + { + Display *dpy = QX11Info::display(); + char string[100]; + + sprintf(string, "_NET_WM_CM_S%d", DefaultScreen(dpy)); + + atom = XInternAtom(dpy, string, False); + haveAtom=true; + } + + return XGetSelectionOwner(QX11Info::display(), atom) != None; + #else // Q_WS_X11 + return false; + #endif // Q_WS_X11 + #else // QTC_QT_ONLY + return KWindowSystem::compositingActive(); + #endif // QTC_QT_ONLY + } + + bool hasAlphaChannel(const QWidget *widget) + { + #ifdef Q_WS_X11 + if(compositingActive()) + return 32 == (widget ? widget->x11Info().depth() : QX11Info().appDepth()) ; + else + return false; + #else + return compositingActive(); + #endif + } + } +} diff --git a/src/qtcurve/style/utils.h b/src/qtcurve/style/utils.h new file mode 100644 index 0000000000..3c8d735185 --- /dev/null +++ b/src/qtcurve/style/utils.h @@ -0,0 +1,41 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +/* + QtCurve (C) Craig Drummond, 2007 - 2010 craig.p.drummond@gmail.com + + ---- + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +namespace QtCurve +{ + namespace Utils + { + inline void addEventFilter(QObject *object, QObject *filter) + { + object->removeEventFilter(filter); + object->installEventFilter(filter); + } + + extern bool compositingActive(); + extern bool hasAlphaChannel(const QWidget *widget); + } +} + +#endif \ No newline at end of file diff --git a/src/qtcurve/style/windowmanager.cpp b/src/qtcurve/style/windowmanager.cpp new file mode 100644 index 0000000000..cc03d3a239 --- /dev/null +++ b/src/qtcurve/style/windowmanager.cpp @@ -0,0 +1,793 @@ +// krazy:excludeall=qclasses + +// Copied from oxygenwindowmanager.cpp svnversion: 1139230 + +////////////////////////////////////////////////////////////////////////////// +// oxygenwindowmanager.cpp +// pass some window mouse press/release/move event actions to window manager +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Largely inspired from BeSpin style +// Copyright (C) 2007 Thomas Luebking +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include "windowmanager.h" +#include "qtcurve.h" +#include "common.h" +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef QTC_QT_ONLY +#include +#endif + +#ifdef Q_WS_X11 +#include +#ifdef QTC_QT_ONLY +#include +#include +#include "fixx11h.h" +#else +#include +#endif +#endif + +namespace QtCurve +{ + +#if QT_VERSION < 0x040600 + QtCPointer & QtCPointer::operator=(QWidget *w) +{ + widget_=w; + if(widget_) + Utils::addEventFilter(widget_, this); + return *this; + } + + void QtCPointer::clear() + { + if(widget_) + widget_->removeEventFilter(this); + widget_=0L; + } + + bool QtCPointer::eventFilter(QObject *o, QEvent *e) + { + if(o==widget_ && QEvent::Destroy==e->type()) + widget_=0L; + return false; + } +#endif + + //_____________________________________________________________ + WindowManager::WindowManager( QObject* parent ): + QObject( parent ), + _enabled( true ), +#ifdef Q_WS_X11 + _useWMMoveResize( true ), +#else + _useWMMoveResize( false ), +#endif + _dragMode( WM_DRAG_NONE ), +#ifdef QTC_QT_ONLY + _dragDistance( QApplication::startDragDistance() ), +#else + _dragDistance( KGlobalSettings::dndEventDelay() ), +#endif + _dragDelay( QApplication::startDragTime() ), + _dragAboutToStart( false ), + _dragInProgress( false ), + _locked( false ), + _cursorOverride( false ) + { + + // install application wise event filter + _appEventFilter = new AppEventFilter( this ); + qApp->installEventFilter( _appEventFilter ); + + } + + //_____________________________________________________________ + void WindowManager::initialize( int windowDrag, const QStringList &whiteList, const QStringList &blackList ) + { + + setEnabled( windowDrag ); + setDragMode( windowDrag ); +//CPD: Why??? setUseWMMoveResize( OxygenStyleConfigData::useWMMoveResize() ); + +#ifndef QTC_QT_ONLY + setDragDistance( KGlobalSettings::dndEventDelay() ); +#endif + setDragDelay( QApplication::startDragTime() ); + + initializeWhiteList( whiteList ); + initializeBlackList( blackList ); + + } + + //_____________________________________________________________ + void WindowManager::registerWidget( QWidget* widget ) + { + + if( isBlackListed( widget ) ) + { + + /* + also install filter for blacklisted widgets + to be able to catch the relevant events and prevent + the drag to happen + */ + Utils::addEventFilter(widget, this); + + } else if( isDragable( widget ) ) { + Utils::addEventFilter(widget, this); + } + + } + + //_____________________________________________________________ + void WindowManager::unregisterWidget( QWidget* widget ) + { + if( widget ) + { widget->removeEventFilter( this ); } + } + + //_____________________________________________________________ + void WindowManager::initializeWhiteList( const QStringList &list ) + { + + _whiteList.clear(); + + // add user specified whitelisted classnames + _whiteList.insert( ExceptionId( "MplayerWindow" ) ); + _whiteList.insert( ExceptionId( "ViewSliders@kmix" ) ); + _whiteList.insert( ExceptionId( "Sidebar_Widget@konqueror" ) ); + + foreach( const QString& exception, list ) + { + ExceptionId id( exception ); + if( !id.className().isEmpty() ) + { _whiteList.insert( exception ); } + } + } + + //_____________________________________________________________ + void WindowManager::initializeBlackList( const QStringList &list ) + { + + _blackList.clear(); + _blackList.insert( ExceptionId( "CustomTrackView@kdenlive" ) ); + _blackList.insert( ExceptionId( "MuseScore" ) ); + foreach( const QString& exception, list ) + { + ExceptionId id( exception ); + if( !id.className().isEmpty() ) + { _blackList.insert( exception ); } + } + + } + + //_____________________________________________________________ + bool WindowManager::eventFilter( QObject* object, QEvent* event ) + { + if( !enabled() ) return false; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + return mousePressEvent( object, event ); + break; + + case QEvent::MouseMove: + if ( object == _target.data() ) return mouseMoveEvent( object, event ); + break; + + case QEvent::MouseButtonRelease: + if ( _target ) return mouseReleaseEvent( object, event ); + break; + + default: + break; + + } + + return false; + + } + + //_____________________________________________________________ + void WindowManager::timerEvent( QTimerEvent* event ) + { + + if( event->timerId() == _dragTimer.timerId() ) + { + _dragTimer.stop(); + if( _target ) + { startDrag( _target.data(), _globalDragPoint ); } + + } else { + + return QObject::timerEvent( event ); + + } + + } + + //_____________________________________________________________ + bool WindowManager::mousePressEvent( QObject* object, QEvent* event ) + { + + // cast event and check buttons/modifiers + QMouseEvent *mouseEvent = static_cast( event ); + if( !( mouseEvent->modifiers() == Qt::NoModifier && mouseEvent->button() == Qt::LeftButton ) ) + { return false; } + + // check lock + if( isLocked() ) return false; + else setLocked( true ); + + // cast to widget + QWidget *widget = static_cast( object ); + + // check if widget can be dragged from current position + if( isBlackListed( widget ) || !canDrag( widget ) ) return false; + + // retrieve widget's child at event position + QPoint position( mouseEvent->pos() ); + QWidget* child = widget->childAt( position ); + if( !canDrag( widget, child, position ) ) return false; + + // save target and drag point + _target = widget; + _dragPoint = position; + _globalDragPoint = mouseEvent->globalPos(); + _dragAboutToStart = true; + + // send a move event to the current child with same position + // if received, it is caught to actually start the drag + QPoint localPoint( _dragPoint ); + if( child ) localPoint = child->mapFrom( widget, localPoint ); + else child = widget; + QMouseEvent localMouseEvent( QEvent::MouseMove, localPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier ); + qApp->sendEvent( child, &localMouseEvent ); + + // never eat event + return false; + + } + + //_____________________________________________________________ + bool WindowManager::mouseMoveEvent( QObject* object, QEvent* event ) + { + + Q_UNUSED( object ); + + // stop timer + if( _dragTimer.isActive() ) _dragTimer.stop(); + + // cast event and check drag distance + QMouseEvent *mouseEvent = static_cast( event ); + if( !_dragInProgress ) + { + + if( _dragAboutToStart ) + { + if( mouseEvent->globalPos() == _globalDragPoint ) + { + // start timer, + _dragAboutToStart = false; + if( _dragTimer.isActive() ) _dragTimer.stop(); + _dragTimer.start( _dragDelay, this ); + + } else resetDrag(); + + } else if( QPoint( mouseEvent->globalPos() - _globalDragPoint ).manhattanLength() >= _dragDistance ) + { _dragTimer.start( 0, this ); } + return true; + + } else if( !useWMMoveResize() ) { + + // use QWidget::move for the grabbing + /* this works only if the sending object and the target are identical */ + QWidget* window( _target.data()->window() ); + window->move( window->pos() + mouseEvent->pos() - _dragPoint ); + return true; + + } else return false; + + } + + //_____________________________________________________________ + bool WindowManager::mouseReleaseEvent( QObject* object, QEvent* event ) + { + Q_UNUSED( object ); + Q_UNUSED( event ); + resetDrag(); + return false; + } + + //_____________________________________________________________ + bool WindowManager::isDragable( QWidget* widget ) + { + + // check widget + if( !widget ) return false; + + // accepted default types + if( + ( qobject_cast( widget ) && widget->isWindow() ) || + ( qobject_cast( widget ) && widget->isWindow() ) || + qobject_cast( widget ) ) + { return true; } + + // more accepted types, provided they are not dock widget titles + if( ( qobject_cast( widget ) || + qobject_cast( widget ) || + qobject_cast( widget ) || + qobject_cast( widget ) ) && + !isDockWidgetTitle( widget ) ) + { return true; } + + if( widget->inherits( "KScreenSaver" ) && widget->inherits( "KCModule" ) ) + { return true; } + + if( isWhiteListed( widget ) ) + { return true; } + + // flat toolbuttons + if( QToolButton* toolButton = qobject_cast( widget ) ) + { if( toolButton->autoRaise() ) return true; } + + // viewports + /* + one needs to check that + 1/ the widget parent is a scrollarea + 2/ it matches its parent viewport + 3/ the parent is not blacklisted + */ + if( QListView* listView = qobject_cast( widget->parentWidget() ) ) + { if( listView->viewport() == widget && !isBlackListed( listView ) ) return true; } + + if( QTreeView* treeView = qobject_cast( widget->parentWidget() ) ) + { if( treeView->viewport() == widget && !isBlackListed( treeView ) ) return true; } + + //if( QGraphicsView* graphicsView = qobject_cast( widget->parentWidget() ) ) + //{ if( graphicsView->viewport() == widget && !isBlackListed( graphicsView ) ) return true; } + + /* + catch labels in status bars. + this is because of kstatusbar + who captures buttonPress/release events + */ + if( QLabel* label = qobject_cast( widget ) ) + { + if( label->textInteractionFlags().testFlag( Qt::TextSelectableByMouse ) ) return false; + + QWidget* parent = label->parentWidget(); + while( parent ) + { + if( qobject_cast( parent ) ) return true; + parent = parent->parentWidget(); + } + } + + return false; + + } + + //_____________________________________________________________ + bool WindowManager::isBlackListed( QWidget* widget ) + { + + // check against noAnimations propery + QVariant propertyValue( widget->property( "_kde_no_window_grab" ) ); + if( propertyValue.isValid() && propertyValue.toBool() ) return true; + + // list-based blacklisted widgets + QString appName( qApp->applicationName() ); + foreach( const ExceptionId& id, _blackList ) + { + if( !id.appName().isEmpty() && id.appName() != appName ) continue; + if( id.className() == "*" && !id.appName().isEmpty() ) + { + // if application name matches and all classes are selected + // disable the grabbing entirely + setEnabled( false ); + return true; + } + if( widget->inherits( id.className().toLatin1() ) ) return true; + } + + return false; + } + + //_____________________________________________________________ + bool WindowManager::isWhiteListed( QWidget* widget ) const + { + + QString appName( qApp->applicationName() ); + foreach( const ExceptionId& id, _whiteList ) + { + if( !id.appName().isEmpty() && id.appName() != appName ) continue; + if( widget->inherits( id.className().toLatin1() ) ) return true; + } + + return false; + } + + //_____________________________________________________________ + bool WindowManager::canDrag( QWidget* widget ) + { + + // check if enabled + if( !enabled() ) return false; + + // assume isDragable widget is already passed + // check some special cases where drag should not be effective + + // check mouse grabber + if( QWidget::mouseGrabber() ) return false; + + /* + check cursor shape. + Assume that a changed cursor means that some action is in progress + and should prevent the drag + */ + if( widget->cursor().shape() != Qt::ArrowCursor ) return false; + + // accept + return true; + + } + + //_____________________________________________________________ + bool WindowManager::canDrag( QWidget* widget, QWidget* child, const QPoint& position ) + { + + // retrieve child at given position and check cursor again + if( child && child->cursor().shape() != Qt::ArrowCursor ) return false; + + /* + check against children from which drag should never be enabled, + even if mousePress/Move has been passed to the parent + */ + if( child && ( + qobject_cast(child ) || + qobject_cast( child ) ) ) + { return false; } + + // tool buttons + if( QToolButton* toolButton = qobject_cast( widget ) ) + { + if( dragMode() < WM_DRAG_ALL && !qobject_cast(widget->parentWidget() ) ) return false; + return toolButton->autoRaise() && !toolButton->isEnabled(); + } + + // check menubar + if( QMenuBar* menuBar = qobject_cast( widget ) ) + { + + // check if there is an active action + if( menuBar->activeAction() && menuBar->activeAction()->isEnabled() ) return false; + + // check if action at position exists and is enabled + if( QAction* action = menuBar->actionAt( position ) ) + { + if( action->isSeparator() ) return true; + if( action->isEnabled() ) return false; + } + + // return true in all other cases + return true; + + } + + if(dragMode() < WM_DRAG_MENU_AND_TOOLBAR && qobject_cast( widget )) + return false; + + /* + in MINIMAL mode, anything that has not been already accepted + and does not come from a toolbar is rejected + */ + if( dragMode() < WM_DRAG_ALL ) + { + if( qobject_cast( widget ) ) return true; + else return false; + } + + /* following checks are relevant only for WD_FULL mode */ + + // tabbar. Make sure no tab is under the cursor + if( QTabBar* tabBar = qobject_cast( widget ) ) + { return tabBar->tabAt( position ) == -1; } + + /* + check groupboxes + prevent drag if unchecking grouboxes + */ + if( QGroupBox *groupBox = qobject_cast( widget ) ) + { + // non checkable group boxes are always ok + if( !groupBox->isCheckable() ) return true; + + // gather options to retrieve checkbox subcontrol rect + QStyleOptionGroupBox opt; + opt.initFrom( groupBox ); + if( groupBox->isFlat() ) opt.features |= QStyleOptionFrameV2::Flat; + opt.lineWidth = 1; + opt.midLineWidth = 0; + opt.text = groupBox->title(); + opt.textAlignment = groupBox->alignment(); + opt.subControls = (QStyle::SC_GroupBoxFrame | QStyle::SC_GroupBoxCheckBox); + if (!groupBox->title().isEmpty()) opt.subControls |= QStyle::SC_GroupBoxLabel; + + opt.state |= (groupBox->isChecked() ? QStyle::State_On : QStyle::State_Off); + + // check against groupbox checkbox + if( groupBox->style()->subControlRect(QStyle::CC_GroupBox, &opt, QStyle::SC_GroupBoxCheckBox, groupBox ).contains( position ) ) + { return false; } + + // check against groupbox label + if( !groupBox->title().isEmpty() && groupBox->style()->subControlRect(QStyle::CC_GroupBox, &opt, QStyle::SC_GroupBoxLabel, groupBox ).contains( position ) ) + { return false; } + + return true; + + } + + // labels + if( QLabel* label = qobject_cast( widget ) ) + { if( label->textInteractionFlags().testFlag( Qt::TextSelectableByMouse ) ) return false; } + + // abstract item views + QAbstractItemView* itemView( NULL ); + if( + ( itemView = qobject_cast( widget->parentWidget() ) ) || + ( itemView = qobject_cast( widget->parentWidget() ) ) ) + { + if( widget == itemView->viewport() ) + { + // QListView + if( itemView->frameShape() != QFrame::NoFrame ) return false; + else if( + itemView->selectionMode() != QAbstractItemView::NoSelection && + itemView->selectionMode() != QAbstractItemView::SingleSelection && + itemView->model() && itemView->model()->rowCount() ) return false; + else if( itemView->model() && itemView->indexAt( position ).isValid() ) return false; + } + + } else if( ( itemView = qobject_cast( widget->parentWidget() ) ) ) { + + + if( widget == itemView->viewport() ) + { + // QAbstractItemView + if( itemView->frameShape() != QFrame::NoFrame ) return false; + else if( itemView->indexAt( position ).isValid() ) return false; + } + + } else if( QGraphicsView* graphicsView = qobject_cast( widget->parentWidget() ) ) { + + if( widget == graphicsView->viewport() ) + { + // QGraphicsView + if( graphicsView->frameShape() != QFrame::NoFrame ) return false; + else if( graphicsView->dragMode() != QGraphicsView::NoDrag ) return false; + else if( graphicsView->itemAt( position ) ) return false; + } + + } + + return true; + + } + + //____________________________________________________________ + void WindowManager::resetDrag( void ) + { + + if( (!useWMMoveResize() ) && _target && _cursorOverride ) { + + qApp->restoreOverrideCursor(); + _cursorOverride = false; + + } + + _target.clear(); + if( _dragTimer.isActive() ) _dragTimer.stop(); + _dragPoint = QPoint(); + _globalDragPoint = QPoint(); + _dragAboutToStart = false; + _dragInProgress = false; + + } + + //____________________________________________________________ + void WindowManager::startDrag( QWidget* widget, const QPoint& position ) + { + + if( !( enabled() && widget ) ) return; + if( QWidget::mouseGrabber() ) return; + + // ungrab pointer + if( useWMMoveResize() ) + { + + #ifdef Q_WS_X11 + #ifdef QTC_QT_ONLY + static const Atom constNetMoveResize = XInternAtom(QX11Info::display(), "_NET_WM_MOVERESIZE", False); + //...Taken from bespin... + // stolen... errr "adapted!" from QSizeGrip + QX11Info info; + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = constNetMoveResize; + xev.xclient.display = QX11Info::display(); + xev.xclient.window = widget->window()->winId(); + xev.xclient.format = 32; + xev.xclient.data.l[0] = position.x(); + xev.xclient.data.l[1] = position.y(); + xev.xclient.data.l[2] = 8; // NET::Move + xev.xclient.data.l[3] = Button1; + xev.xclient.data.l[4] = 0; + XUngrabPointer(QX11Info::display(), QX11Info::appTime()); + XSendEvent(QX11Info::display(), QX11Info::appRootWindow(info.screen()), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + #else + XUngrabPointer(QX11Info::display(), QX11Info::appTime()); + NETRootInfo rootInfo(QX11Info::display(), NET::WMMoveResize); + rootInfo.moveResizeRequest( widget->window()->winId(), position.x(), position.y(), NET::Move); + #endif // QTC_QT_ONLY + #endif + + } + + if( !useWMMoveResize() ) + { + if( !_cursorOverride ) + { + qApp->setOverrideCursor( Qt::SizeAllCursor ); + _cursorOverride = true; + } + } + + _dragInProgress = true; + + return; + + } + + //____________________________________________________________ + bool WindowManager::supportWMMoveResize( void ) const + { + + #ifdef Q_WS_X11 + return true; + #endif + + return false; + + } + + //____________________________________________________________ + bool WindowManager::isDockWidgetTitle( const QWidget* widget ) const + { + + if( !widget ) return false; + if( const QDockWidget* dockWidget = qobject_cast( widget->parent() ) ) + { + + return widget == dockWidget->titleBarWidget(); + + } else return false; + + } + + //____________________________________________________________ + bool WindowManager::AppEventFilter::eventFilter( QObject* object, QEvent* event ) + { + + if( event->type() == QEvent::MouseButtonRelease ) + { + + // stop drag timer + if( _parent->_dragTimer.isActive() ) + { _parent->resetDrag(); } + + // unlock + if( _parent->isLocked() ) + { _parent->setLocked( false ); } + + } + + if( !_parent->enabled() ) return false; + + /* + if a drag is in progress, the widget will not receive any event + we trigger on the first MouseMove or MousePress events that are received + by any widget in the application to detect that the drag is finished + */ + if( _parent->useWMMoveResize() && _parent->_dragInProgress && _parent->_target && ( event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonPress ) ) + { return appMouseEvent( object, event ); } + + return false; + + } + + //_____________________________________________________________ + bool WindowManager::AppEventFilter::appMouseEvent( QObject* object, QEvent* event ) + { + + Q_UNUSED( object ); + + // store target window (see later) + QWidget* window( _parent->_target.data()->window() ); + + /* + post some mouseRelease event to the target, in order to counter balance + the mouse press that triggered the drag. Note that it triggers a resetDrag + */ + QMouseEvent mouseEvent( QEvent::MouseButtonRelease, _parent->_dragPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier ); + qApp->sendEvent( _parent->_target.data(), &mouseEvent ); + + if( event->type() == QEvent::MouseMove ) + { + /* + HACK: quickly move the main cursor out of the window and back + this is needed to get the focus right for the window children + the origin of this issue is unknown at the moment + */ + const QPoint cursor = QCursor::pos(); + QCursor::setPos(window->mapToGlobal( window->rect().topRight() ) + QPoint(1, 0) ); + QCursor::setPos(cursor); + + } + + return true; + + } + + +} diff --git a/src/qtcurve/style/windowmanager.h b/src/qtcurve/style/windowmanager.h new file mode 100644 index 0000000000..ea158ec2e5 --- /dev/null +++ b/src/qtcurve/style/windowmanager.h @@ -0,0 +1,325 @@ +#ifndef __WINDOW_MANAGER_H__ +#define __WINDOW_MANAGER_H__ + +// Copied from oxygenwindowmanager.h svnversion: 1137195 + +////////////////////////////////////////////////////////////////////////////// +// oxygenwindowmanager.h +// pass some window mouse press/release/move event actions to window manager +// ------------------- +// +// Copyright (c) 2010 Hugo Pereira Da Costa +// +// Largely inspired from BeSpin style +// Copyright (C) 2007 Thomas Luebking +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +////////////////////////////////////////////////////////////////////////////// + +#include + +#include +#include +#include +#include +#include + +#include + +namespace QtCurve +{ +#if QT_VERSION < 0x040600 + class QtCPointer : public QObject +{ + public: + QtCPointer(QWidget *w=0L) : widget_(w) {} + QtCPointer & operator=(QWidget *w); + operator bool() const { return 0L!=widget_; } + void clear(); + bool eventFilter(QObject *, QEvent *); + QWidget *data() { return widget_; } + + private: + QWidget *widget_; + }; +#endif + + class WindowManager: public QObject + { + + Q_OBJECT + + public: + + //! constructor + explicit WindowManager( QObject* ); + + //! destructor + virtual ~WindowManager( void ) + {} + + //! initialize + /*! read relevant options from OxygenStyleConfigData */ + void initialize( int windowDrag, const QStringList &whiteList=QStringList(), const QStringList &blackList=QStringList() ); + + //! register widget + void registerWidget( QWidget* ); + + //! unregister widget + void unregisterWidget( QWidget* ); + + //! event filter [reimplemented] + virtual bool eventFilter( QObject*, QEvent* ); + + protected: + + //! timer event, + /*! used to start drag if button is pressed for a long enough time */ + void timerEvent( QTimerEvent* ); + + //! mouse press event + bool mousePressEvent( QObject*, QEvent* ); + + //! mouse move event + bool mouseMoveEvent( QObject*, QEvent* ); + + //! mouse release event + bool mouseReleaseEvent( QObject*, QEvent* ); + + //!@name configuration + //@{ + + //! enable state + bool enabled( void ) const + { return _enabled; } + + //! enable state + void setEnabled( bool value ) + { _enabled = value; } + + //! returns true if window manager is used for moving + bool useWMMoveResize( void ) const + { return supportWMMoveResize() && _useWMMoveResize; } + + //! use window manager for moving, when available + void setUseWMMoveResize( bool value ) + { _useWMMoveResize = value; } + + //! drag mode + int dragMode( void ) const + { return _dragMode; } + + //! drag mode + void setDragMode( int value ) + { _dragMode = value; } + + //! drag distance (pixels) + void setDragDistance( int value ) + { _dragDistance = value; } + + //! drag delay (msec) + void setDragDelay( int value ) + { _dragDelay = value; } + + //! set list of whiteListed widgets + /*! + white list is read from options and is used to adjust + per-app window dragging issues + */ + void initializeWhiteList( const QStringList &list ); + + //! set list of blackListed widgets + /*! + black list is read from options and is used to adjust + per-app window dragging issues + */ + void initializeBlackList( const QStringList &list ); + + //@} + + //! returns true if widget is dragable + bool isDragable( QWidget* ); + + //! returns true if widget is dragable + bool isBlackListed( QWidget* ); + + //! returns true if widget is dragable + bool isWhiteListed( QWidget* ) const; + + //! returns true if drag can be started from current widget + bool canDrag( QWidget* ); + + //! returns true if drag can be started from current widget and position + /*! child at given position is passed as second argument */ + bool canDrag( QWidget*, QWidget*, const QPoint& ); + + //! reset drag + void resetDrag( void ); + + //! start drag + void startDrag( QWidget*, const QPoint& ); + + //! returns true if window manager is used for moving + /*! right now this is true only for X11 */ + bool supportWMMoveResize( void ) const; + + //! utility function + bool isDockWidgetTitle( const QWidget* ) const; + + //!@name lock + //@{ + + void setLocked( bool value ) + { _locked = value; } + + //! lock + bool isLocked( void ) const + { return _locked; } + + //@} + + private: + + //! enability + bool _enabled; + + //! use WM moveResize + bool _useWMMoveResize; + + //! drag mode + int _dragMode; + + //! drag distance + /*! this is copied from kwin::geometry */ + int _dragDistance; + + //! drag delay + /*! this is copied from kwin::geometry */ + int _dragDelay; + + //! wrapper for exception id + class ExceptionId: public QPair + { + public: + + //! constructor + ExceptionId( const QString& value ) + { + const QStringList args( value.split( "@" ) ); + if( args.isEmpty() ) return; + second = args[0].trimmed(); + if( args.size()>1 ) first = args[1].trimmed(); + } + + const QString& appName( void ) const + { return first; } + + const QString& className( void ) const + { return second; } + + }; + + //! exception set + typedef QSet ExceptionSet; + + //! list of white listed special widgets + /*! + it is read from options and is used to adjust + per-app window dragging issues + */ + ExceptionSet _whiteList; + + //! list of black listed special widgets + /*! + it is read from options and is used to adjust + per-app window dragging issues + */ + ExceptionSet _blackList; + + //! drag point + QPoint _dragPoint; + QPoint _globalDragPoint; + + //! drag timer + QBasicTimer _dragTimer; + + //! target being dragged + /*! QWeakPointer is used in case the target gets deleted while drag is in progress */ +#if QT_VERSION < 0x040600 + QtCPointer _target; +#else + QWeakPointer _target; +#endif + + //! true if drag is about to start + bool _dragAboutToStart; + + //! true if drag is in progress + bool _dragInProgress; + + //! true if drag is locked + bool _locked; + + //! cursor override + /*! used to keep track of application cursor being overridden when dragging in non-WM mode */ + bool _cursorOverride; + + //! provide application-wise event filter + /*! + it us used to unlock dragging and make sure event look is properly restored + after a drag has occurred + */ + class AppEventFilter: public QObject + { + + public: + + //! constructor + AppEventFilter( WindowManager* parent ): + QObject( parent ), + _parent( parent ) + {} + + //! event filter + virtual bool eventFilter( QObject*, QEvent* ); + + protected: + + //! application-wise event. + /*! needed to catch end of XMoveResize events */ + bool appMouseEvent( QObject*, QEvent* ); + + private: + + //! parent + WindowManager* _parent; + + }; + + //! application event filter + AppEventFilter* _appEventFilter; + + //! allow access of all private members to the app event filter + friend class AppEventFilter; + + }; + +} + +#endif From 45d35b283e36129327f0c6fb8163b13c0870ee50 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 12:42:46 +0530 Subject: [PATCH 37/53] Fix focus highlighting obsucring text in listviews --- session.vim | 8 +++++++- setup/extensions.py | 23 ++++------------------- src/calibre/gui2/__init__.py | 8 ++++---- src/qtcurve/config.h | 12 ++++++++++++ src/qtcurve/style/qtcurve.cpp | 4 ++++ src/qtcurve/test_rendering.py | 28 ++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 src/qtcurve/config.h create mode 100644 src/qtcurve/test_rendering.py diff --git a/session.vim b/session.vim index 185e51ae0d..bbacc4e0ec 100644 --- a/session.vim +++ b/session.vim @@ -2,7 +2,13 @@ let $PYFLAKES_BUILTINS = "_,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext" " Include directories for C++ modules -let g:syntastic_cpp_include_dirs = [ '/usr/include/podofo', '/usr/include/qt4/QtCore', '/usr/include/qt4/QtGui', '/usr/include/qt4'] +let g:syntastic_cpp_include_dirs = [ + \'/usr/include/podofo', + \'/usr/include/qt4/QtCore', + \'/usr/include/qt4/QtGui', + \'/usr/include/qt4', + \'src/qtcurve/common', 'src/qtcurve', + \] fun! CalibreLog() " Setup buffers to edit the calibre changelog and version info prior to diff --git a/setup/extensions.py b/setup/extensions.py index a264885a8b..586c43fe7a 100644 --- a/setup/extensions.py +++ b/setup/extensions.py @@ -368,7 +368,8 @@ class Build(Command): self.info('\n####### Building calibre style', '#'*7) sdir = self.j(self.SRC, 'qtcurve') def path(x): - return '"%s"'%self.j(sdir, x).replace(os.sep, '/') + if x: x=self.j(sdir, x) + return ('"%s"'%x).replace(os.sep, '/') headers = [ "common/colorutils.h", "common/common.h", @@ -404,7 +405,7 @@ class Build(Command): DESTDIR = . TARGET = calibre QT *= svg - INCLUDEPATH *= . {inc} + INCLUDEPATH *= {conf} {inc} win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS # Force C++ language @@ -412,7 +413,7 @@ class Build(Command): *msvc*:QMAKE_CFLAGS *= -TP *msvc*:QMAKE_CXXFLAGS += /MP - ''').format(inc=path('common')) + ''').format(conf=path(''), inc=path('common')) if isosx: pro += '\nCONFIG += x86 x86_64\n' else: @@ -422,18 +423,6 @@ class Build(Command): pro += 'HEADERS += %s\n'%path(x) for x in sources: pro += 'SOURCES += %s\n'%path(x) - config = textwrap.dedent(''' - #pragma once - - /* #define VERSION "1.5.3" */ - #define KDE3PREFIX "/usr" - #define KDE4PREFIX "/usr" - - #define QTC_QT_ONLY - /* #undef QTC_OLD_NVIDIA_ARROW_FIX */ - #undef QTC_STYLE_SUPPORT - /* #undef QTC_KWIN_MAX_BUTTON_HACK */ - ''') odir = self.j(self.d(self.SRC), 'build', 'qtcurve') if not os.path.exists(odir): os.makedirs(odir) @@ -444,10 +433,6 @@ class Build(Command): 'rb').read() != pro): with open('qtcurve.pro', 'wb') as f: f.write(pro) - if not os.path.exists('config.h') or (open('config.h', - 'rb').read() != config): - with open('config.h', 'wb') as f: - f.write(config) qmc = [QMAKE, '-o', 'Makefile'] if iswindows: qmc += ['-spec', 'win32-msvc2008'] diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index a0fbab7bbc..1295118290 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -720,7 +720,7 @@ gui_thread = None qt_app = None class Application(QApplication): - def __init__(self, args): + def __init__(self, args, force_calibre_style=False): self.file_event_hook = None qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args] QApplication.__init__(self, qargs) @@ -731,7 +731,7 @@ class Application(QApplication): qt_app = self self._file_open_paths = [] self._file_open_lock = RLock() - self.setup_styles() + self.setup_styles(force_calibre_style) def load_calibre_style(self): # On OS X QtCurve resets the palette, so we preserve it explicitly @@ -743,7 +743,7 @@ class Application(QApplication): pi.load_style(path, 'Calibre') self.setPalette(orig_pal) - def setup_styles(self): + def setup_styles(self, force_calibre_style): self.original_font = QFont(QApplication.font()) fi = gprefs['font'] if fi is not None: @@ -753,7 +753,7 @@ class Application(QApplication): font.setStretch(s) QApplication.setFont(font) - if gprefs['widget_style'] != 'system': + if force_calibre_style or gprefs['widget_style'] != 'system': self.load_calibre_style() else: st = self.style() diff --git a/src/qtcurve/config.h b/src/qtcurve/config.h new file mode 100644 index 0000000000..19ce0bf25c --- /dev/null +++ b/src/qtcurve/config.h @@ -0,0 +1,12 @@ +#pragma once + +/* #define VERSION "1.5.3" */ +#define KDE3PREFIX "/usr" +#define KDE4PREFIX "/usr" + +#define QTC_QT_ONLY +/* #undef QTC_OLD_NVIDIA_ARROW_FIX */ +#undef QTC_STYLE_SUPPORT +/* #undef QTC_KWIN_MAX_BUTTON_HACK */ + + diff --git a/src/qtcurve/style/qtcurve.cpp b/src/qtcurve/style/qtcurve.cpp index dea39b343f..2d186c63e7 100644 --- a/src/qtcurve/style/qtcurve.cpp +++ b/src/qtcurve/style/qtcurve.cpp @@ -4986,6 +4986,10 @@ void Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, if(widget && ::qobject_cast(widget)) r2.adjust(0, 2, 0, 0); + // Added by Kovid so that the highlight does not cover the text + if(widget && ::qobject_cast(widget)) + r2.adjust(0, 0, 0, 2); + if(FOCUS_STANDARD==opts.focus) { // Taken from QWindowsStyle... diff --git a/src/qtcurve/test_rendering.py b/src/qtcurve/test_rendering.py new file mode 100644 index 0000000000..7196412b74 --- /dev/null +++ b/src/qtcurve/test_rendering.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.gui2 import Application +from PyQt4.Qt import (QDialog, QGridLayout, QListWidget, QDialogButtonBox) + +app = Application([], force_calibre_style=True) + +d = QDialog() +d.l = l = QGridLayout() +d.setLayout(l) +lw = QListWidget() +lw.addItem('Some text guy') +l.addWidget(lw, 0, 0, 2, 1) +bb = QDialogButtonBox() +bb.setStandardButtons(bb.Close) +bb.accepted.connect(d.accept) +bb.rejected.connect(d.reject) +l.addWidget(bb, 2, 0, 1, 2) + +d.exec_() + From 4d4de02e82d5962d0ea31654d958197c436539ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 13:06:20 +0530 Subject: [PATCH 38/53] Use standard button sizes for button box buttons on windows and os x --- session.vim | 1 + src/qtcurve/common/config_file.c | 5 +++++ src/qtcurve/test_rendering.py | 10 +++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/session.vim b/session.vim index bbacc4e0ec..fbb573e27e 100644 --- a/session.vim +++ b/session.vim @@ -9,6 +9,7 @@ let g:syntastic_cpp_include_dirs = [ \'/usr/include/qt4', \'src/qtcurve/common', 'src/qtcurve', \] +let g:syntastic_c_include_dirs = g:syntastic_cpp_include_dirs fun! CalibreLog() " Setup buffers to edit the calibre changelog and version info prior to diff --git a/src/qtcurve/common/config_file.c b/src/qtcurve/common/config_file.c index 3b4d732acc..17fd333890 100644 --- a/src/qtcurve/common/config_file.c +++ b/src/qtcurve/common/config_file.c @@ -2611,7 +2611,12 @@ void qtcDefaultSettings(Options *opts) opts->gbFactor=DEF_GB_FACTOR; opts->gbLabel=GB_LBL_BOLD|GB_LBL_OUTSIDE; #if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) +#if defined _WIN32 || defined __APPLE__ + // Changed by Kovid to use standard button sizes on Windows/OS X + opts->stdBtnSizes=true; +#else opts->stdBtnSizes=false; +#endif opts->titlebarButtons=TITLEBAR_BUTTON_ROUND|TITLEBAR_BUTTON_HOVER_SYMBOL; opts->titlebarIcon=TITLEBAR_ICON_NEXT_TO_TITLE; #endif diff --git a/src/qtcurve/test_rendering.py b/src/qtcurve/test_rendering.py index 7196412b74..61ded9241b 100644 --- a/src/qtcurve/test_rendering.py +++ b/src/qtcurve/test_rendering.py @@ -8,7 +8,8 @@ __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' from calibre.gui2 import Application -from PyQt4.Qt import (QDialog, QGridLayout, QListWidget, QDialogButtonBox) +from PyQt4.Qt import (QDialog, QGridLayout, QListWidget, QDialogButtonBox, + QPushButton, QTimer) app = Application([], force_calibre_style=True) @@ -24,5 +25,12 @@ bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) l.addWidget(bb, 2, 0, 1, 2) +b = QPushButton('Normal') +l.addWidget(b, 0, 1, 1, 1) + +def print_button_sizes(): + for b in d.findChildren(QPushButton): + print (unicode(b.text()), b.height()) +QTimer.singleShot(5, print_button_sizes) d.exec_() From d6ea54ff08cc4bbc3ddddaa6e3940f5a9563e48e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 13:16:42 +0530 Subject: [PATCH 39/53] Specialize the scrollbars for each platform --- src/qtcurve/common/config_file.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qtcurve/common/config_file.c b/src/qtcurve/common/config_file.c index 17fd333890..328627e2c9 100644 --- a/src/qtcurve/common/config_file.c +++ b/src/qtcurve/common/config_file.c @@ -2561,7 +2561,13 @@ void qtcDefaultSettings(Options *opts) opts->shadeMenubarOnlyWhenActive=false; opts->thin=THIN_BUTTONS; opts->tbarBtns=TBTN_STANDARD; +#ifdef _WIN32 + opts->scrollbarType=SCROLLBAR_WINDOWS; +#elif defined __APPLE__ + opts->scrollbarType=SCROLLBAR_NONE; +#else opts->scrollbarType=SCROLLBAR_KDE; +#endif opts->buttonEffect=EFFECT_SHADOW; opts->focus=FOCUS_GLOW; opts->lvButton=false; From d921a2a475b677b0d617a0e785bb1a60d200b6a6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 13:23:30 +0530 Subject: [PATCH 40/53] ... --- setup/extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/extensions.py b/setup/extensions.py index 586c43fe7a..c0132d7359 100644 --- a/setup/extensions.py +++ b/setup/extensions.py @@ -368,7 +368,7 @@ class Build(Command): self.info('\n####### Building calibre style', '#'*7) sdir = self.j(self.SRC, 'qtcurve') def path(x): - if x: x=self.j(sdir, x) + x=self.j(sdir, x) return ('"%s"'%x).replace(os.sep, '/') headers = [ "common/colorutils.h", From 2152c0044c95f7fdcde94fee4f796ce2c0a5ea9e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 14:47:45 +0530 Subject: [PATCH 41/53] Welcome wizard: Prerentially use the kindle email address set as default when more than one such address exists. Fixes #1007932 (share-by-email incorrect address selected in Welcome Wizard) --- src/calibre/gui2/wizard/__init__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 7f50c13e41..ef756a226a 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -418,9 +418,17 @@ class KindlePage(QWizardPage, KindleUI): def initializePage(self): opts = smtp_prefs().parse() - for x in opts.accounts.keys(): + accs = [] + has_default = False + for x, ac in opts.accounts.iteritems(): + default = ac[2] if x.strip().endswith('@kindle.com'): - self.to_address.setText(x) + accs.append((x, default)) + if default: has_default = True + if has_default: + accs = [x for x in accs if x[1]] + if accs: + self.to_address.setText(accs[0]) def x(): t = unicode(self.to_address.text()) if t.strip(): From 82f2c10859f78936e7d67e028569db37896b0d1c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 14:49:48 +0530 Subject: [PATCH 42/53] Driver for Pantech Android tablet. Fixes #1007929 (Pantech Element Android tablet support) --- src/calibre/devices/android/driver.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index c4abb54556..755bb0d8b2 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -165,6 +165,9 @@ class ANDROID(USBMS): # Lenovo 0x17ef : { 0x7421 : [0x0216] }, + # Pantech + 0x10a9 : { 0x6050 : [0x227] }, + } EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books', 'sdcard/ebooks'] From f3af89d3aa8ba87731608b3ed7589c0beffe01d8 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Sun, 3 Jun 2012 12:54:27 +0200 Subject: [PATCH 43/53] Fix partioning problems in tag browser with fields that have no "name" such as identifiers and formats. --- src/calibre/gui2/tag_browser/model.py | 49 ++++++++++++++++----------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index e08245f4cf..bfa10c1fcd 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -418,21 +418,24 @@ class TagsModel(QAbstractItemModel): # {{{ chardict[c][1] = idx # sort the ranges to facilitate detecting overlap - ranges = sorted([(v[0], v[1], c) for c,v in chardict.items()]) - - # Create a list of 'first letters' to use for each item in - # the category. The list is generated using the ranges. Overlaps - # are filled with the character that first occurs. - cl_list = list(repeat(None, len(data[key]))) - for t in ranges: - start = t[0] - c = t[2] - if cl_list[start] is None: - nc = c - else: - nc = cl_list[start] - for i in range(start, t[1]+1): - cl_list[i] = nc + if len(chardict) == 1 and ' ' in chardict: + # The category could not be partitioned. + collapse_model = 'disable' + else: + ranges = sorted([(v[0], v[1], c) for c,v in chardict.items()]) + # Create a list of 'first letters' to use for each item in + # the category. The list is generated using the ranges. Overlaps + # are filled with the character that first occurs. + cl_list = list(repeat(None, len(data[key]))) + for t in ranges: + start = t[0] + c = t[2] + if cl_list[start] is None: + nc = c + else: + nc = cl_list[start] + for i in range(start, t[1]+1): + cl_list[i] = nc for idx,tag in enumerate(data[key]): if clear_rating: @@ -448,13 +451,19 @@ class TagsModel(QAbstractItemModel): # {{{ else: d['last'] = data[key][cat_len-1] name = eval_formatter.safe_format(collapse_template, - d, 'TAG_VIEW', None) - sub_cat = self.create_node(parent=category, data = name, + d, '##TAG_VIEW##', None) + if name.startswith('##TAG_VIEW##'): + # Formatter threw an exception. Don't create subnode + node_parent = category + else: + sub_cat = self.create_node(parent=category, data = name, tooltip = None, temporary=True, category_icon = category_node.icon, category_key=category_node.category_key, icon_map=self.icon_state_map) - sub_cat.tag.is_searchable = False + sub_cat.tag.is_searchable = False + sub_cat.is_gst = is_gst + node_parent = sub_cat else: # by 'first letter' cl = cl_list[idx] if cl != collapse_letter: @@ -465,8 +474,8 @@ class TagsModel(QAbstractItemModel): # {{{ tooltip = None, temporary=True, category_key=category_node.category_key, icon_map=self.icon_state_map) - sub_cat.is_gst = is_gst - node_parent = sub_cat + sub_cat.is_gst = is_gst + node_parent = sub_cat else: node_parent = category From 1a45fd86e68504d3a31f6d8b1ebf79c7aa1b31d2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 16:30:15 +0530 Subject: [PATCH 44/53] ... --- src/calibre/gui2/metadata/single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 51e63429ee..07a709538d 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -108,7 +108,7 @@ class MetadataSingleDialogBase(ResizableDialog): # while the buttons outside them do not, leading to weirdness. # Further, buttons with and without icons have different minimum sizes # so things look even more out of whack. - ht = self.title.height() + ht = self.title.height() + 2 for but in self.findChildren(QPushButton): but.setMaximumHeight(ht) but.setMinimumHeight(ht) From ac94da06bea8ab89d8461e500e4311995831cdba Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Sun, 3 Jun 2012 13:46:15 +0200 Subject: [PATCH 45/53] Make tag browser searches for the empty string generate key:false. --- src/calibre/gui2/tag_browser/model.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index bfa10c1fcd..95d58d2cb6 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -1187,13 +1187,16 @@ class TagsModel(QAbstractItemModel): # {{{ for subnode in tag_item.children: if subnode.tag.sort: letters_seen[subnode.tag.sort[0]] = True - charclass = ''.join(letters_seen) - if k == 'author_sort': - expr = r'%s:"~(^[%s])|(&\s*[%s])"'%(k, charclass, charclass) - elif k == 'series': - expr = r'series_sort:"~^[%s]"'%(charclass) + if letters_seen: + charclass = ''.join(letters_seen) + if k == 'author_sort': + expr = r'%s:"~(^[%s])|(&\s*[%s])"'%(k, charclass, charclass) + elif k == 'series': + expr = r'series_sort:"~^[%s]"'%(charclass) + else: + expr = r'%s:"~^[%s]"'%(k, charclass) else: - expr = r'%s:"~^[%s]"'%(k, charclass) + expr = r'%s:false'%(k) if node_searches[tag_item.tag.state] == 'true': ans.append(expr) else: From a31972e881f2e118cd8b11c0d91203dfc5dd8e91 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 21:00:02 +0530 Subject: [PATCH 46/53] ... --- src/calibre/gui2/preferences/look_feel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 294d7a644c..ef1c6cc3e6 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -105,7 +105,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): [(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) styles = set(map(unicode, QStyleFactory.keys())) - if 'QtCurve' not in styles: + if 'Calibre' not in styles: # Can happen in linux for x in ('opt', 'label'): getattr(self, x+'_widget_style').setVisible(False) From bfb17649c693a40755065c470d3629902752a1c1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 21:08:04 +0530 Subject: [PATCH 47/53] ... --- src/calibre/gui2/preferences/look_feel.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index ef1c6cc3e6..2c675d1ee2 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -6,7 +6,7 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' from PyQt4.Qt import (QApplication, QFont, QFontInfo, QFontDialog, - QAbstractListModel, Qt, QIcon, QKeySequence, QStyleFactory) + QAbstractListModel, Qt, QIcon, QKeySequence) from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList from calibre.gui2.preferences.look_feel_ui import Ui_Form @@ -104,11 +104,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('widget_style', gprefs, restart_required=True, choices= [(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) - styles = set(map(unicode, QStyleFactory.keys())) - if 'Calibre' not in styles: - # Can happen in linux - for x in ('opt', 'label'): - getattr(self, x+'_widget_style').setVisible(False) r('cover_flow_queue_length', config, restart_required=True) From edacec78292c3b9d5aa6cdf611448d0768485853 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 21:14:34 +0530 Subject: [PATCH 48/53] ... --- src/calibre/gui2/tag_browser/view.py | 2 +- src/calibre/gui2/viewer/toc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 4535241f77..2669298c4e 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -117,7 +117,7 @@ class TagsView(QTreeView): # {{{ QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; - border-radius: 8px; + border-radius: 6px; } ''') diff --git a/src/calibre/gui2/viewer/toc.py b/src/calibre/gui2/viewer/toc.py index cb105630e6..f8add78ed6 100644 --- a/src/calibre/gui2/viewer/toc.py +++ b/src/calibre/gui2/viewer/toc.py @@ -32,7 +32,7 @@ class TOCView(QTreeView): QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; - border-radius: 8px; + border-radius: 6px; } QHeaderView::section { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, From 43618df9966055feeb54fada2fc59b0d4eb87971 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 21:25:55 +0530 Subject: [PATCH 49/53] ... --- src/calibre/gui2/preferences/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py index 66c3cd8e51..0f3d29f454 100644 --- a/src/calibre/gui2/preferences/main.py +++ b/src/calibre/gui2/preferences/main.py @@ -206,11 +206,10 @@ class Preferences(QMainWindow): self.cw.layout().addWidget(self.stack) self.bb = QDialogButtonBox(QDialogButtonBox.Close) self.wizard_button = self.bb.addButton(_('Run welcome wizard'), - self.bb.DestructiveRole) + self.bb.ActionRole) self.wizard_button.setIcon(QIcon(I('wizard.png'))) self.wizard_button.clicked.connect(self.run_wizard, type=Qt.QueuedConnection) - self.bb.button(self.bb.Close).setDefault(True) self.cw.layout().addWidget(self.bb) self.bb.rejected.connect(self.close, type=Qt.QueuedConnection) self.setCentralWidget(self.cw) From 6fe4d095ce86cd91b44cd1403681cfeb6f7b948c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 22:14:57 +0530 Subject: [PATCH 50/53] ... --- src/calibre/gui2/metadata/single.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 07a709538d..895c6b7af3 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -27,6 +27,7 @@ from calibre.utils.config import tweaks from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.localization import canonicalize_lang from calibre.utils.date import local_tz +from calibre.constants import iswindows, isosx BASE_TITLE = _('Edit Metadata') @@ -108,7 +109,7 @@ class MetadataSingleDialogBase(ResizableDialog): # while the buttons outside them do not, leading to weirdness. # Further, buttons with and without icons have different minimum sizes # so things look even more out of whack. - ht = self.title.height() + 2 + ht = self.next_button.height() if iswindows or isosx else self.title.height() + 1 for but in self.findChildren(QPushButton): but.setMaximumHeight(ht) but.setMinimumHeight(ht) From a913828a6b226eab3135aade31a6976a997d2ffe Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 3 Jun 2012 23:24:58 +0530 Subject: [PATCH 51/53] ... --- src/qtcurve/common/config_file.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qtcurve/common/config_file.c b/src/qtcurve/common/config_file.c index 328627e2c9..639f696747 100644 --- a/src/qtcurve/common/config_file.c +++ b/src/qtcurve/common/config_file.c @@ -2617,12 +2617,8 @@ void qtcDefaultSettings(Options *opts) opts->gbFactor=DEF_GB_FACTOR; opts->gbLabel=GB_LBL_BOLD|GB_LBL_OUTSIDE; #if defined CONFIG_DIALOG || (defined QT_VERSION && (QT_VERSION >= 0x040000)) -#if defined _WIN32 || defined __APPLE__ - // Changed by Kovid to use standard button sizes on Windows/OS X + // Changed by Kovid to always use standard button sizes opts->stdBtnSizes=true; -#else - opts->stdBtnSizes=false; -#endif opts->titlebarButtons=TITLEBAR_BUTTON_ROUND|TITLEBAR_BUTTON_HOVER_SYMBOL; opts->titlebarIcon=TITLEBAR_ICON_NEXT_TO_TITLE; #endif From dc5f2be9b25285e17484709875c5d98b00aa5ef0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 4 Jun 2012 00:00:44 +0530 Subject: [PATCH 52/53] ... --- src/qtcurve/test_rendering.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qtcurve/test_rendering.py b/src/qtcurve/test_rendering.py index 61ded9241b..2de860856b 100644 --- a/src/qtcurve/test_rendering.py +++ b/src/qtcurve/test_rendering.py @@ -30,7 +30,7 @@ l.addWidget(b, 0, 1, 1, 1) def print_button_sizes(): for b in d.findChildren(QPushButton): - print (unicode(b.text()), b.height()) + print (unicode(b.text()), b.height(), b.iconSize()) QTimer.singleShot(5, print_button_sizes) d.exec_() From cc8c4482e1fb0fe0d8635496c0b817f44a668c8b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 4 Jun 2012 00:51:54 +0530 Subject: [PATCH 53/53] Proper fix for QPushButton sizes. We now ensure that push buttons without icons use iconSize pixels for their text, irrespective of font size --- src/calibre/gui2/metadata/single.py | 14 -------------- src/qtcurve/style/qtcurve.cpp | 11 ++++++----- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index 895c6b7af3..3ca543cd89 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -27,7 +27,6 @@ from calibre.utils.config import tweaks from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.localization import canonicalize_lang from calibre.utils.date import local_tz -from calibre.constants import iswindows, isosx BASE_TITLE = _('Edit Metadata') @@ -101,19 +100,6 @@ class MetadataSingleDialogBase(ResizableDialog): geom = gprefs.get('metasingle_window_geometry3', None) if geom is not None: self.restoreGeometry(bytes(geom)) - self.title.resizeEvent = self.fix_push_buttons - - def fix_push_buttons(self, *args): - # Ensure all PushButtons stay the same consistent height throughout this - # dialog. Without this, the buttons inside scrollareas get shrunk, - # while the buttons outside them do not, leading to weirdness. - # Further, buttons with and without icons have different minimum sizes - # so things look even more out of whack. - ht = self.next_button.height() if iswindows or isosx else self.title.height() + 1 - for but in self.findChildren(QPushButton): - but.setMaximumHeight(ht) - but.setMinimumHeight(ht) - return TitleEdit.resizeEvent(self.title, *args) # }}} def create_basic_metadata_widgets(self): # {{{ diff --git a/src/qtcurve/style/qtcurve.cpp b/src/qtcurve/style/qtcurve.cpp index 2d186c63e7..2dcc2737ba 100644 --- a/src/qtcurve/style/qtcurve.cpp +++ b/src/qtcurve/style/qtcurve.cpp @@ -9685,13 +9685,14 @@ QSize Style::sizeFromContents(ContentsType type, const QStyleOption *option, con if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { + // Added by Kovid to ensure that pushbuttons without icons are never narrower than push buttons with icons at small font sizes + int min_pb_height = (btn->iconSize.height() > 16) ? btn->iconSize.height() : 16; + if (newSize.height() < min_pb_height) newSize.setHeight(min_pb_height); + if(!opts.stdBtnSizes) { - bool dialogButton= - // Cant rely on AutoDefaultButton - as VirtualBox does not set this!!! - // btn->features&QStyleOptionButton::AutoDefaultButton && - widget && widget->parentWidget() && - (::qobject_cast(widget->parentWidget()) || widget->parentWidget()->inherits("KFileWidget")); + // Changed by Kovid since we dont care about VirtualBox + bool dialogButton = btn->features&QStyleOptionButton::AutoDefaultButton; if(dialogButton) {