From e737f3c98a0d187a3f2b5e33f4608d58221cddbd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 1 Jun 2012 23:04:26 +0530 Subject: [PATCH 01/24] ... --- 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 02/24] ... --- 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 03/24] ... --- 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 04/24] 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 05/24] 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 06/24] ... --- 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 07/24] ... --- 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 08/24] ... --- 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 09/24] 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 10/24] 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 11/24] 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 12/24] ... --- 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 13/24] 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 14/24] ... --- 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 15/24] ... --- 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 16/24] ... --- 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 17/24] 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 18/24] 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 19/24] 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 20/24] 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 21/24] 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 22/24] ... --- 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 23/24] 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 24/24] 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']