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/recipes/instapaper.recipe b/recipes/instapaper.recipe
index 40992e4d75..4481866550 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 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
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/')]
diff --git a/session.vim b/session.vim
index 4ded6d1bf3..fbb573e27e 100644
--- a/session.vim
+++ b/session.vim
@@ -1,8 +1,15 @@
" Project wide builtins
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']
+" 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',
+ \'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/setup/extensions.py b/setup/extensions.py
index dadb84233d..c0132d7359 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,88 @@ 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):
+ x=self.j(sdir, x)
+ return ('"%s"'%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 *= {conf} {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(conf=path(''), 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)
+ 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)
+ 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/__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/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/__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'
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/devices/android/driver.py b/src/calibre/devices/android/driver.py
index 6641b631a6..755bb0d8b2 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],
},
@@ -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']
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:
diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py
index f0f069639a..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,6 +731,19 @@ class Application(QApplication):
qt_app = self
self._file_open_paths = []
self._file_open_lock = RLock()
+ self.setup_styles(force_calibre_style)
+
+ 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, force_calibre_style):
self.original_font = QFont(QApplication.font())
fi = gprefs['font']
if fi is not None:
@@ -739,14 +752,9 @@ 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())
- QApplication.setStyle('QtCurve')
- self.setPalette(orig_pal)
+ if force_calibre_style or gprefs['widget_style'] != 'system':
+ self.load_calibre_style()
else:
st = self.style()
if st is not None:
@@ -754,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/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py
index 292a4e907b..51e63429ee 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)
@@ -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)
@@ -97,11 +96,23 @@ 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.
+ # 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)
+ but.setMinimumHeight(ht)
+ return TitleEdit.resizeEvent(self.title, *args)
# }}}
def create_basic_metadata_widgets(self): # {{{
@@ -508,15 +519,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
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())
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);
+
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()
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():
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:
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 0000000000..472578e47d
Binary files /dev/null and b/src/qtcurve/common/check_on.png differ
diff --git a/src/qtcurve/common/check_x_on.png b/src/qtcurve/common/check_x_on.png
new file mode 100644
index 0000000000..1be26e1a40
Binary files /dev/null and b/src/qtcurve/common/check_x_on.png differ
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