Refactored image access for new resources framework

This commit is contained in:
Kovid Goyal 2009-09-07 16:03:44 -06:00
parent 1ce7847d8d
commit 792c6b0b22
33 changed files with 154 additions and 185 deletions

View File

@ -1,5 +1,5 @@
" Project wide builtins " Project wide builtins
let g:pyflakes_builtins += ["dynamic_property", "__", "P"] let g:pyflakes_builtins += ["dynamic_property", "__", "P", "I"]
python << EOFPY python << EOFPY
import os import os

View File

@ -22,8 +22,23 @@ def check_version_info():
def option_parser(): def option_parser():
parser = optparse.OptionParser() parser = optparse.OptionParser()
parser.add_option('-c', '--clean', default=False, action='store_true',
help=('Instead of running the command delete all files generated '
'by the command'))
parser.add_option('--clean-backups', default=False, action='store_true',
help='Delete all backup files from the source tree')
parser.add_option('--clean-all', default=False, action='store_true',
help='Delete all machine generated files from the source tree')
return parser return parser
def clean_backups():
for root, _, files in os.walk('.'):
for name in files:
for t in ('.pyc', '.pyo', '~', '.swp', '.swo'):
if name.endswith(t):
os.remove(os.path.join(root, name))
def main(args=sys.argv): def main(args=sys.argv):
if len(args) == 1 or args[1] in ('-h', '--help'): if len(args) == 1 or args[1] in ('-h', '--help'):
print 'Usage: python', args[0], 'command', '[options]' print 'Usage: python', args[0], 'command', '[options]'
@ -46,6 +61,21 @@ def main(args=sys.argv):
command.description) command.description)
opts, args = parser.parse_args(args) opts, args = parser.parse_args(args)
if opts.clean_backups:
clean_backups()
if opts.clean:
prints('Cleaning', args[1])
command.clean()
return 0
if opts.clean_all():
for cmd in commands.__all__:
prints('Cleaning', cmd)
getattr(commands, cmd).clean()
return 0
command.run_all(opts) command.run_all(opts)
warnings = get_warnings() warnings = get_warnings()

View File

@ -11,13 +11,10 @@ __all__ = [
'build', 'build',
'gui', 'gui',
'develop', 'develop',
'clean', 'clean_backups',
] ]
import os, shutil
from setup.translations import POT, GetTranslations, Translations, ISO639 from setup.translations import POT, GetTranslations, Translations, ISO639
from setup import Command
pot = POT() pot = POT()
translations = Translations() translations = Translations()
get_translations = GetTranslations() get_translations = GetTranslations()
@ -32,50 +29,6 @@ develop = Develop()
from setup.gui import GUI from setup.gui import GUI
gui = GUI() gui = GUI()
class CleanBackups(Command):
description='Delete all backup files in the calibre source tree'
def clean(self):
return self.run(None)
def run(self, opts=None):
for root, _, files in os.walk(self.d(self.SRC)):
for name in files:
for t in ('.pyc', '.pyo', '~', '.swp', '.swo'):
if name.endswith(t):
os.remove(os.path.join(root, name))
clean_backups = CleanBackups()
class Clean(Command):
description='''Delete all computer generated files in the source tree'''
sub_commands = __all__
def add_options(self, parser):
opt = parser.remove_option('--only')
help = 'Only run clean for the specified command. Choices: '+\
', '.join(__all__)
parser.add_option('-1', '--only', default='all',
choices=__all__+['all'], help=help)
def run_all(self, opts):
self.info('Cleaning...')
only = None if opts.only == 'all' else commands[opts.only]
for cmd in self.sub_commands:
if only is not None and only is not cmd:
continue
self.info('\tCleaning', command_names[cmd])
cmd.clean()
def clean(self):
for dir in ('dist', os.path.join('src', 'calibre.egg-info')):
shutil.rmtree(dir, ignore_errors=True)
clean = Clean()
commands = {} commands = {}
for x in __all__: for x in __all__:

View File

@ -55,30 +55,30 @@ class GUI(Command):
def build_forms(self): def build_forms(self):
from PyQt4.uic import compileUi from PyQt4.uic import compileUi
forms = self.find_forms() forms = self.find_forms()
pat = re.compile(r'''(['"]):/images/([^'"]+)\1''')
def sub(match):
ans = 'I(%s%s%s)'%(match.group(1), match.group(2), match.group(1))
return ans
for form in forms: for form in forms:
compiled_form = self.form_to_compiled_form(form) compiled_form = self.form_to_compiled_form(form)
if not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime: if not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime:
print 'Compiling form', form self.info('\tCompiling form', form)
buf = cStringIO.StringIO() buf = cStringIO.StringIO()
compileUi(form, buf) compileUi(form, buf)
dat = buf.getvalue() dat = buf.getvalue()
dat = dat.replace('__appname__', __appname__) dat = dat.replace('__appname__', __appname__)
dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc') dat = dat.replace('import images_rc', '')
dat = dat.replace('from library import', 'from calibre.gui2.library import') dat = dat.replace('from library import', 'from calibre.gui2.library import')
dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import') dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import')
dat = dat.replace('from convert.xpath_wizard import', dat = dat.replace('from convert.xpath_wizard import',
'from calibre.gui2.convert.xpath_wizard import') 'from calibre.gui2.convert.xpath_wizard import')
dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat) dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat)
dat = dat.replace('_("MMM yyyy")', '"MMM yyyy"') dat = dat.replace('_("MMM yyyy")', '"MMM yyyy"')
dat = pat.sub(sub, dat)
# Workaround bug in Qt 4.4 on Windows
if form.endswith('dialogs%sconfig.ui'%os.sep) or form.endswith('dialogs%slrf_single.ui'%os.sep):
print 'Implementing Workaround for buggy pyuic in form', form
dat = re.sub(r'= QtGui\.QTextEdit\(self\..*?\)', '= QtGui.QTextEdit()', dat)
dat = re.sub(r'= QtGui\.QListWidget\(self\..*?\)', '= QtGui.QListWidget()', dat)
if form.endswith('viewer%smain.ui'%os.sep): if form.endswith('viewer%smain.ui'%os.sep):
print 'Promoting WebView' self.inf('\t\tPromoting WebView')
dat = dat.replace('self.view = QtWebKit.QWebView(', 'self.view = DocumentView(') dat = dat.replace('self.view = QtWebKit.QWebView(', 'self.view = DocumentView(')
dat += '\n\nfrom calibre.gui2.viewer.documentview import DocumentView' dat += '\n\nfrom calibre.gui2.viewer.documentview import DocumentView'

View File

@ -194,21 +194,12 @@ class EPUBOutput(OutputFormatPlugin):
if self.opts.no_default_epub_cover: if self.opts.no_default_epub_cover:
return None return None
self.log('Generating default cover') self.log('Generating default cover')
try:
from calibre.gui2 import images_rc, is_ok_to_use_qt # Needed for access to logo
from PyQt4.Qt import QFile, QIODevice
except:
return None
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
images_rc
m = self.oeb.metadata m = self.oeb.metadata
title = unicode(m.title[0]) title = unicode(m.title[0])
a = [unicode(x) for x in m.creator if x.role == 'aut'] a = [unicode(x) for x in m.creator if x.role == 'aut']
author = authors_to_string(a) author = authors_to_string(a)
if not is_ok_to_use_qt(): return img_data = open(I('library.png'), 'rb').read()
f = QFile(':/library')
f.open(QIODevice.ReadOnly)
img_data = str(f.readAll())
id, href = self.oeb.manifest.generate('calibre-logo', id, href = self.oeb.manifest.generate('calibre-logo',
'calibre-logo.png') 'calibre-logo.png')
self.oeb.manifest.add(id, href, 'image/png', data=img_data) self.oeb.manifest.add(id, href, 'image/png', data=img_data)

View File

@ -169,7 +169,7 @@ def warning_dialog(parent, title, msg, det_msg='', show=False):
d = MessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok, d = MessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok,
parent, det_msg) parent, det_msg)
d.setEscapeButton(QMessageBox.Ok) d.setEscapeButton(QMessageBox.Ok)
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg')) d.setIconPixmap(QPixmap(I('dialog_warning.svg')))
if show: if show:
return d.exec_() return d.exec_()
return d return d
@ -177,7 +177,7 @@ def warning_dialog(parent, title, msg, det_msg='', show=False):
def error_dialog(parent, title, msg, det_msg='', show=False): def error_dialog(parent, title, msg, det_msg='', show=False):
d = MessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok, d = MessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
parent, det_msg) parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_error.svg')) d.setIconPixmap(QPixmap(I('dialog_error.svg')))
d.setEscapeButton(QMessageBox.Ok) d.setEscapeButton(QMessageBox.Ok)
if show: if show:
return d.exec_() return d.exec_()
@ -186,14 +186,14 @@ def error_dialog(parent, title, msg, det_msg='', show=False):
def question_dialog(parent, title, msg, det_msg=''): def question_dialog(parent, title, msg, det_msg=''):
d = MessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No, d = MessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No,
parent, det_msg) parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) d.setIconPixmap(QPixmap(I('dialog_information.svg')))
d.setEscapeButton(QMessageBox.No) d.setEscapeButton(QMessageBox.No)
return d.exec_() == QMessageBox.Yes return d.exec_() == QMessageBox.Yes
def info_dialog(parent, title, msg, det_msg='', show=False): def info_dialog(parent, title, msg, det_msg='', show=False):
d = MessageBox(QMessageBox.Information, title, msg, QMessageBox.Ok, d = MessageBox(QMessageBox.Information, title, msg, QMessageBox.Ok,
parent, det_msg) parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) d.setIconPixmap(QPixmap(I('dialog_information.svg')))
if show: if show:
return d.exec_() return d.exec_()
return d return d
@ -321,7 +321,7 @@ class FileIconProvider(QFileIconProvider):
QFileIconProvider.__init__(self) QFileIconProvider.__init__(self)
self.icons = {} self.icons = {}
for key in self.__class__.ICONS.keys(): for key in self.__class__.ICONS.keys():
self.icons[key] = ':/images/mimetypes/'+self.__class__.ICONS[key]+'.svg' self.icons[key] = I('mimetypes/')+self.__class__.ICONS[key]+'.svg'
for i in ('dir', 'default', 'zero'): for i in ('dir', 'default', 'zero'):
self.icons[i] = QIcon(self.icons[i]) self.icons[i] = QIcon(self.icons[i])

View File

@ -17,7 +17,7 @@ from calibre.ebooks.conversion.config import load_defaults, \
class Widget(QWidget): class Widget(QWidget):
TITLE = _('Unknown') TITLE = _('Unknown')
ICON = ':/images/config.svg' ICON = I('config.svg')
HELP = '' HELP = ''
def __init__(self, parent, name, options): def __init__(self, parent, name, options):

View File

@ -69,7 +69,7 @@ class BulkConfig(Config):
output_widget = __import__('calibre.gui2.convert.'+name, output_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1]) fromlist=[1])
pw = output_widget.PluginWidget pw = output_widget.PluginWidget
pw.ICON = ':/images/back.svg' pw.ICON = I('back.svg')
pw.HELP = _('Options specific to the output format.') pw.HELP = _('Options specific to the output format.')
output_widget = widget_factory(pw) output_widget = widget_factory(pw)
except ImportError: except ImportError:

View File

@ -17,7 +17,7 @@ from calibre.gui2 import error_dialog, choose_dir
class DebugWidget(Widget, Ui_Form): class DebugWidget(Widget, Ui_Form):
TITLE = _('Debug') TITLE = _('Debug')
ICON = ':/images/debug.svg' ICON = I('debug.svg')
HELP = _('Debug the conversion process.') HELP = _('Debug the conversion process.')
def __init__(self, parent, get_option, get_help, db=None, book_id=None): def __init__(self, parent, get_option, get_help, db=None, book_id=None):

View File

@ -13,7 +13,7 @@ from calibre.gui2.convert import Widget
class LookAndFeelWidget(Widget, Ui_Form): class LookAndFeelWidget(Widget, Ui_Form):
TITLE = _('Look & Feel') TITLE = _('Look & Feel')
ICON = ':/images/lookfeel.svg' ICON = I('lookfeel.svg')
HELP = _('Control the look and feel of the output') HELP = _('Control the look and feel of the output')
def __init__(self, parent, get_option, get_help, db=None, book_id=None): def __init__(self, parent, get_option, get_help, db=None, book_id=None):

View File

@ -21,7 +21,7 @@ from calibre.gui2.convert import Widget
class MetadataWidget(Widget, Ui_Form): class MetadataWidget(Widget, Ui_Form):
TITLE = _('Metadata') TITLE = _('Metadata')
ICON = ':/images/dialog_information.svg' ICON = I('dialog_information.svg')
HELP = _('Set the metadata. The output file will contain as much of this ' HELP = _('Set the metadata. The output file will contain as much of this '
'metadata as possible.') 'metadata as possible.')

View File

@ -149,7 +149,7 @@ class Config(ResizableDialog, Ui_Dialog):
output_widget = __import__('calibre.gui2.convert.'+name, output_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1]) fromlist=[1])
pw = output_widget.PluginWidget pw = output_widget.PluginWidget
pw.ICON = ':/images/back.svg' pw.ICON = I('back.svg')
pw.HELP = _('Options specific to the output format.') pw.HELP = _('Options specific to the output format.')
output_widget = widget_factory(pw) output_widget = widget_factory(pw)
except ImportError: except ImportError:
@ -160,7 +160,7 @@ class Config(ResizableDialog, Ui_Dialog):
input_widget = __import__('calibre.gui2.convert.'+name, input_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1]) fromlist=[1])
pw = input_widget.PluginWidget pw = input_widget.PluginWidget
pw.ICON = ':/images/forward.svg' pw.ICON = I('forward.svg')
pw.HELP = _('Options specific to the input format.') pw.HELP = _('Options specific to the input format.')
input_widget = widget_factory(pw) input_widget = widget_factory(pw)
except ImportError: except ImportError:
@ -249,13 +249,4 @@ class Config(ResizableDialog, Ui_Dialog):
self.help.setPlainText(widget.HELP) self.help.setPlainText(widget.HELP)
if __name__ == '__main__':
from calibre.library.database2 import LibraryDatabase2
from calibre.gui2 import images_rc, Application
images_rc
a = Application([])
db = LibraryDatabase2('/home/kovid/documents/library')
d = Config(None, db, 594)
d.show()
a.exec_()

View File

@ -15,7 +15,7 @@ from calibre.gui2 import error_dialog
class StructureDetectionWidget(Widget, Ui_Form): class StructureDetectionWidget(Widget, Ui_Form):
TITLE = _('Structure\nDetection') TITLE = _('Structure\nDetection')
ICON = ':/images/chapters.svg' ICON = I('chapters.svg')
HELP = _('Fine tune the detection of chapter headings and ' HELP = _('Fine tune the detection of chapter headings and '
'other document structure.') 'other document structure.')

View File

@ -14,7 +14,7 @@ from calibre.gui2 import error_dialog
class TOCWidget(Widget, Ui_Form): class TOCWidget(Widget, Ui_Form):
TITLE = _('Table of\nContents') TITLE = _('Table of\nContents')
ICON = ':/images/series.svg' ICON = I('series.svg')
HELP = _('Control the creation/conversion of the Table of Contents.') HELP = _('Control the creation/conversion of the Table of Contents.')
def __init__(self, parent, get_option, get_help, db=None, book_id=None): def __init__(self, parent, get_option, get_help, db=None, book_id=None):

View File

@ -302,11 +302,11 @@ class DeviceMenu(QMenu):
formats, auto, default = opts.accounts[account] formats, auto, default = opts.accounts[account]
dest = 'mail:'+account+';'+formats dest = 'mail:'+account+';'+formats
if default: if default:
default_account = (dest, False, False, ':/images/mail.svg', default_account = (dest, False, False, I('mail.svg'),
_('Email to')+' '+account) _('Email to')+' '+account)
action1 = DeviceAction(dest, False, False, ':/images/mail.svg', action1 = DeviceAction(dest, False, False, I('mail.svg'),
_('Email to')+' '+account, self) _('Email to')+' '+account, self)
action2 = DeviceAction(dest, True, False, ':/images/mail.svg', action2 = DeviceAction(dest, True, False, I('mail.svg'),
_('Email to')+' '+account, self) _('Email to')+' '+account, self)
map(self.email_to_menu.addAction, (action1, action2)) map(self.email_to_menu.addAction, (action1, action2))
map(self._memory.append, (action1, action2)) map(self._memory.append, (action1, action2))
@ -317,25 +317,25 @@ class DeviceMenu(QMenu):
self.action_triggered) self.action_triggered)
_actions = [ _actions = [
('main:', False, False, ':/images/reader.svg', ('main:', False, False, I('reader.svg'),
_('Send to main memory')), _('Send to main memory')),
('carda:0', False, False, ':/images/sd.svg', ('carda:0', False, False, I('sd.svg'),
_('Send to storage card A')), _('Send to storage card A')),
('cardb:0', False, False, ':/images/sd.svg', ('cardb:0', False, False, I('sd.svg'),
_('Send to storage card B')), _('Send to storage card B')),
'-----', '-----',
('main:', True, False, ':/images/reader.svg', ('main:', True, False, I('reader.svg'),
_('Send to main memory')), _('Send to main memory')),
('carda:0', True, False, ':/images/sd.svg', ('carda:0', True, False, I('sd.svg'),
_('Send to storage card A')), _('Send to storage card A')),
('cardb:0', True, False, ':/images/sd.svg', ('cardb:0', True, False, I('sd.svg'),
_('Send to storage card B')), _('Send to storage card B')),
'-----', '-----',
('main:', False, True, ':/images/reader.svg', ('main:', False, True, I('reader.svg'),
_('Send specific format to main memory')), _('Send specific format to main memory')),
('carda:0', False, True, ':/images/sd.svg', ('carda:0', False, True, I('sd.svg'),
_('Send specific format to storage card A')), _('Send specific format to storage card A')),
('cardb:0', False, True, ':/images/sd.svg', ('cardb:0', False, True, I('sd.svg'),
_('Send specific format to storage card B')), _('Send specific format to storage card B')),
] ]

View File

@ -61,7 +61,7 @@ class ConfigTabs(QTabWidget):
input_widget = __import__('calibre.gui2.convert.'+name, input_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1]) fromlist=[1])
pw = input_widget.PluginWidget pw = input_widget.PluginWidget
pw.ICON = ':/images/forward.svg' pw.ICON = I('forward.svg')
self.widgets.append(widget_factory(pw)) self.widgets.append(widget_factory(pw))
except ImportError: except ImportError:
continue continue
@ -72,7 +72,7 @@ class ConfigTabs(QTabWidget):
output_widget = __import__('calibre.gui2.convert.'+name, output_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1]) fromlist=[1])
pw = output_widget.PluginWidget pw = output_widget.PluginWidget
pw.ICON = ':/images/forward.svg' pw.ICON = I('forward.svg')
self.widgets.append(widget_factory(pw)) self.widgets.append(widget_factory(pw))
except ImportError: except ImportError:
continue continue
@ -95,7 +95,7 @@ class PluginModel(QAbstractItemModel):
def __init__(self, *args): def __init__(self, *args):
QAbstractItemModel.__init__(self, *args) QAbstractItemModel.__init__(self, *args)
self.icon = QVariant(QIcon(':/images/plugins.svg')) self.icon = QVariant(QIcon(I('plugins.svg')))
p = QIcon(self.icon).pixmap(32, 32, QIcon.Disabled, QIcon.On) p = QIcon(self.icon).pixmap(32, 32, QIcon.Disabled, QIcon.On)
self.disabled_icon = QVariant(QIcon(p)) self.disabled_icon = QVariant(QIcon(p))
self._p = p self._p = p
@ -197,10 +197,10 @@ class CategoryModel(QStringListModel):
_('Email\nDelivery'), _('Add/Save'), _('Email\nDelivery'), _('Add/Save'),
_('Advanced'), _('Content\nServer'), _('Plugins')]) _('Advanced'), _('Content\nServer'), _('Plugins')])
self.icons = list(map(QVariant, map(QIcon, self.icons = list(map(QVariant, map(QIcon,
[':/images/dialog_information.svg', ':/images/lookfeel.svg', [I('dialog_information.svg'), I('lookfeel.svg'),
':/images/convert.svg', I('convert.svg'),
':/images/mail.svg', ':/images/save.svg', ':/images/view.svg', I('mail.svg'), I('save.svg'), I('view.svg'),
':/images/network-server.svg', ':/images/plugins.svg']))) I('network-server.svg'), I('plugins.svg')])))
def data(self, index, role): def data(self, index, role):
if role == Qt.DecorationRole: if role == Qt.DecorationRole:

View File

@ -85,7 +85,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
COVER_FETCH_TIMEOUT = 240 # seconds COVER_FETCH_TIMEOUT = 240 # seconds
def do_reset_cover(self, *args): def do_reset_cover(self, *args):
pix = QPixmap(':/images/book.svg') pix = QPixmap(I('book.svg'))
self.cover.setPixmap(pix) self.cover.setPixmap(pix)
self.cover_changed = True self.cover_changed = True
self.cover_data = None self.cover_data = None

View File

@ -98,8 +98,8 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
def __init__(self, db, *args): def __init__(self, db, *args):
QAbstractItemModel.__init__(self, *args) QAbstractItemModel.__init__(self, *args)
SearchQueryParser.__init__(self) SearchQueryParser.__init__(self)
self.default_icon = QIcon(':/images/news.svg') self.default_icon = QIcon(I('news.svg'))
self.custom_icon = QIcon(':/images/user_profile.svg') self.custom_icon = QIcon(I('user_profile.svg'))
self.recipes = copy.deepcopy(builtin_recipes) self.recipes = copy.deepcopy(builtin_recipes)
for x in db.get_recipes(): for x in db.get_recipes():
recipe = compile_recipe(x[1]) recipe = compile_recipe(x[1])
@ -215,7 +215,7 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
return recipe return recipe
elif role == Qt.DecorationRole: elif role == Qt.DecorationRole:
icon = self.default_icon icon = self.default_icon
icon_path = (':/images/news/%s.png'%recipe.id).replace('recipe_', '') icon_path = (I('news/%s.png')%recipe.id).replace('recipe_', '')
if not recipe.builtin: if not recipe.builtin:
icon = self.custom_icon icon = self.custom_icon
elif QFile().exists(icon_path): elif QFile().exists(icon_path):
@ -420,11 +420,11 @@ class Scheduler(QObject):
self.oldest_check() self.oldest_check()
self.news_menu = QMenu() self.news_menu = QMenu()
self.news_icon = QIcon(':/images/news.svg') self.news_icon = QIcon(I('news.svg'))
self.scheduler_action = QAction(QIcon(':/images/scheduler.svg'), _('Schedule news download'), self) self.scheduler_action = QAction(QIcon(I('scheduler.svg')), _('Schedule news download'), self)
self.news_menu.addAction(self.scheduler_action) self.news_menu.addAction(self.scheduler_action)
self.connect(self.scheduler_action, SIGNAL('triggered(bool)'), self.show_dialog) self.connect(self.scheduler_action, SIGNAL('triggered(bool)'), self.show_dialog)
self.cac = QAction(QIcon(':/images/user_profile.svg'), _('Add a custom news source'), self) self.cac = QAction(QIcon(I('user_profile.svg')), _('Add a custom news source'), self)
self.connect(self.cac, SIGNAL('triggered(bool)'), self.customize_feeds) self.connect(self.cac, SIGNAL('triggered(bool)'), self.customize_feeds)
self.news_menu.addAction(self.cac) self.news_menu.addAction(self.cac)

View File

@ -24,10 +24,10 @@ class JobManager(QAbstractTableModel):
def __init__(self): def __init__(self):
QAbstractTableModel.__init__(self) QAbstractTableModel.__init__(self)
self.wait_icon = QVariant(QIcon(':/images/jobs.svg')) self.wait_icon = QVariant(QIcon(I('jobs.svg')))
self.running_icon = QVariant(QIcon(':/images/exec.svg')) self.running_icon = QVariant(QIcon(I('exec.svg')))
self.error_icon = QVariant(QIcon(':/images/dialog_error.svg')) self.error_icon = QVariant(QIcon(I('dialog_error.svg')))
self.done_icon = QVariant(QIcon(':/images/ok.svg')) self.done_icon = QVariant(QIcon(I('ok.svg')))
self.jobs = [] self.jobs = []
self.add_job = Dispatcher(self._add_job) self.add_job = Dispatcher(self._add_job)

View File

@ -172,7 +172,7 @@ class BooksModel(QAbstractTableModel):
self.column_map = config['column_map'] self.column_map = config['column_map']
self.editable_cols = ['title', 'authors', 'rating', 'publisher', self.editable_cols = ['title', 'authors', 'rating', 'publisher',
'tags', 'series', 'timestamp', 'pubdate'] 'tags', 'series', 'timestamp', 'pubdate']
self.default_image = QImage(':/images/book.svg') self.default_image = QImage(I('book.svg'))
self.sorted_on = ('timestamp', Qt.AscendingOrder) self.sorted_on = ('timestamp', Qt.AscendingOrder)
self.last_search = '' # The last search performed on this model self.last_search = '' # The last search performed on this model
self.read_config() self.read_config()

View File

@ -307,7 +307,7 @@ def main(args=sys.argv, logger=None):
pid = os.fork() if islinux else -1 pid = os.fork() if islinux else -1
if pid <= 0: if pid <= 0:
app = Application(args) app = Application(args)
app.setWindowIcon(QIcon(':/images/viewer.svg')) app.setWindowIcon(QIcon(I('viewer.svg')))
QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setOrganizationName(ORG_NAME)
QCoreApplication.setApplicationName(APP_UID) QCoreApplication.setApplicationName(APP_UID)
opts = normalize_settings(parser, opts) opts = normalize_settings(parser, opts)

View File

@ -96,7 +96,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
'The main GUI' 'The main GUI'
def set_default_thumbnail(self, height): def set_default_thumbnail(self, height):
r = QSvgRenderer(':/images/book.svg') r = QSvgRenderer(I('book.svg'))
pixmap = QPixmap(height, height) pixmap = QPixmap(height, height)
pixmap.fill(QColor(255,255,255)) pixmap.fill(QColor(255,255,255))
p = QPainter(pixmap) p = QPainter(pixmap)
@ -146,7 +146,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.device_connected = False self.device_connected = False
self.viewers = collections.deque() self.viewers = collections.deque()
self.content_server = None self.content_server = None
self.system_tray_icon = QSystemTrayIcon(QIcon(':/images/library.png'), self) self.system_tray_icon = QSystemTrayIcon(QIcon(I('library.png')), self)
self.system_tray_icon.setToolTip('calibre') self.system_tray_icon.setToolTip('calibre')
if not config['systray_icon']: if not config['systray_icon']:
self.system_tray_icon.hide() self.system_tray_icon.hide()
@ -154,9 +154,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.system_tray_icon.show() self.system_tray_icon.show()
self.system_tray_menu = QMenu(self) self.system_tray_menu = QMenu(self)
self.restore_action = self.system_tray_menu.addAction( self.restore_action = self.system_tray_menu.addAction(
QIcon(':/images/page.svg'), _('&Restore')) QIcon(I('page.svg')), _('&Restore'))
self.donate_action = self.system_tray_menu.addAction( self.donate_action = self.system_tray_menu.addAction(
QIcon(':/images/donate.svg'), _('&Donate to support calibre')) QIcon(I('donate.svg')), _('&Donate to support calibre'))
self.donate_button.setDefaultAction(self.donate_action) self.donate_button.setDefaultAction(self.donate_action)
if not config['show_donate_button']: if not config['show_donate_button']:
self.donate_button.setVisible(False) self.donate_button.setVisible(False)
@ -1714,7 +1714,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
d = QMessageBox(QMessageBox.Warning, _('WARNING: Active jobs'), msg, d = QMessageBox(QMessageBox.Warning, _('WARNING: Active jobs'), msg,
QMessageBox.Yes|QMessageBox.No, self) QMessageBox.Yes|QMessageBox.No, self)
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg')) d.setIconPixmap(QPixmap(I('dialog_warning.svg')))
d.setDefaultButton(QMessageBox.No) d.setDefaultButton(QMessageBox.No)
if d.exec_() != QMessageBox.Yes: if d.exec_() != QMessageBox.Yes:
return False return False
@ -1826,7 +1826,7 @@ def init_qt(args):
QCoreApplication.setApplicationName(APP_UID) QCoreApplication.setApplicationName(APP_UID)
app = Application(args) app = Application(args)
actions = tuple(Main.create_application_menubar()) actions = tuple(Main.create_application_menubar())
app.setWindowIcon(QIcon(':/images/library.png')) app.setWindowIcon(QIcon(I('library.png')))
return app, opts, args, actions return app, opts, args, actions
def run_gui(opts, args, actions, listener, app): def run_gui(opts, args, actions, listener, app):

View File

@ -56,8 +56,8 @@ class MainWindow(QMainWindow):
@classmethod @classmethod
def get_menubar_actions(cls): def get_menubar_actions(cls):
preferences_action = QAction(QIcon(':/images/config.svg'), _('&Preferences'), None) preferences_action = QAction(QIcon(I('config.svg')), _('&Preferences'), None)
quit_action = QAction(QIcon(':/images/window-close.svg'), _('&Quit'), None) quit_action = QAction(QIcon(I('window-close.svg')), _('&Quit'), None)
preferences_action.setMenuRole(QAction.PreferencesRole) preferences_action.setMenuRole(QAction.PreferencesRole)
quit_action.setMenuRole(QAction.QuitRole) quit_action.setMenuRole(QAction.QuitRole)
return preferences_action, quit_action return preferences_action, quit_action

View File

@ -14,7 +14,7 @@ class BookInfoDisplay(QWidget):
WIDTH = 81 WIDTH = 81
HEIGHT = 108 HEIGHT = 108
def __init__(self, coverpath=':/images/book.svg'): def __init__(self, coverpath=I('book.svg')):
QLabel.__init__(self) QLabel.__init__(self)
self.default_pixmap = QPixmap(coverpath).scaled(self.__class__.WIDTH, self.default_pixmap = QPixmap(coverpath).scaled(self.__class__.WIDTH,
self.__class__.HEIGHT, self.__class__.HEIGHT,
@ -141,7 +141,7 @@ class CoverFlowButton(QToolButton):
def __init__(self, parent=None): def __init__(self, parent=None):
QToolButton.__init__(self, parent) QToolButton.__init__(self, parent)
self.setIconSize(QSize(80, 80)) self.setIconSize(QSize(80, 80))
self.setIcon(QIcon(':/images/cover_flow.svg')) self.setIcon(QIcon(I('cover_flow.svg')))
self.setCheckable(True) self.setCheckable(True)
self.setChecked(False) self.setChecked(False)
self.setAutoRaise(True) self.setAutoRaise(True)
@ -163,7 +163,7 @@ class TagViewButton(QToolButton):
def __init__(self, parent=None): def __init__(self, parent=None):
QToolButton.__init__(self, parent) QToolButton.__init__(self, parent)
self.setIconSize(QSize(80, 80)) self.setIconSize(QSize(80, 80))
self.setIcon(QIcon(':/images/tags.svg')) self.setIcon(QIcon(I('tags.svg')))
self.setToolTip(_('Click to browse books by tags')) self.setToolTip(_('Click to browse books by tags'))
self.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)) self.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding))
self.setCursor(Qt.PointingHandCursor) self.setCursor(Qt.PointingHandCursor)
@ -177,7 +177,7 @@ class StatusBar(QStatusBar):
def __init__(self, jobs_dialog, systray=None): def __init__(self, jobs_dialog, systray=None):
QStatusBar.__init__(self) QStatusBar.__init__(self)
self.systray = systray self.systray = systray
self.movie_button = MovieButton(QMovie(':/images/jobs-animated.mng'), jobs_dialog) self.movie_button = MovieButton(QMovie(I('jobs-animated.mng')), jobs_dialog)
self.cover_flow_button = CoverFlowButton() self.cover_flow_button = CoverFlowButton()
self.tag_view_button = TagViewButton() self.tag_view_button = TagViewButton()
self.addPermanentWidget(self.cover_flow_button) self.addPermanentWidget(self.cover_flow_button)

View File

@ -84,13 +84,13 @@ class TagsModel(QStandardItemModel):
row_map = ['author', 'series', 'format', 'publisher', 'news', 'tag'] row_map = ['author', 'series', 'format', 'publisher', 'news', 'tag']
def __init__(self, db): def __init__(self, db):
self.cmap = tuple(map(QIcon, [':/images/user_profile.svg', self.cmap = tuple(map(QIcon, [I('user_profile.svg'),
':/images/series.svg', ':/images/book.svg', ':/images/publisher.png', I('series.svg'), I('book.svg'), I('publisher.png'),
':/images/news.svg', ':/images/tags.svg'])) I('news.svg'), I('tags.svg')]))
p = QPixmap(30, 30) p = QPixmap(30, 30)
p.fill(Qt.transparent) p.fill(Qt.transparent)
self.icon_map = [QIcon(p), QIcon(':/images/plus.svg'), self.icon_map = [QIcon(p), QIcon(I('plus.svg')),
QIcon(':/images/minus.svg')] QIcon(I('minus.svg'))]
QStandardItemModel.__init__(self) QStandardItemModel.__init__(self)
self.db = db self.db = db
self.ignore_next_search = 0 self.ignore_next_search = 0

View File

@ -67,7 +67,7 @@ class ProgressIndicator(QWidget):
def __init__(self, *args): def __init__(self, *args):
QWidget.__init__(self, *args) QWidget.__init__(self, *args)
self.setGeometry(0, 0, 300, 500) self.setGeometry(0, 0, 300, 500)
self.movie = QMovie(':/images/jobs-animated.mng') self.movie = QMovie(I('jobs-animated.mng'))
self.ml = QLabel(self) self.ml = QLabel(self)
self.ml.setMovie(self.movie) self.ml.setMovie(self.movie)
self.movie.start() self.movie.start()
@ -283,7 +283,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.action_full_screen.setCheckable(True) self.action_full_screen.setCheckable(True)
self.print_menu = QMenu() self.print_menu = QMenu()
self.print_menu.addAction(QIcon(':/images/print-preview.svg'), _('Print Preview')) self.print_menu.addAction(QIcon(I('print-preview.svg')), _('Print Preview'))
self.action_print.setMenu(self.print_menu) self.action_print.setMenu(self.print_menu)
self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup) self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup)
self.connect(self.action_print, SIGNAL("triggered(bool)"), partial(self.print_book, preview=False)) self.connect(self.action_print, SIGNAL("triggered(bool)"), partial(self.print_book, preview=False))
@ -668,7 +668,7 @@ def main(args=sys.argv):
pid = os.fork() if False and islinux else -1 pid = os.fork() if False and islinux else -1
if pid <= 0: if pid <= 0:
app = Application(args) app = Application(args)
app.setWindowIcon(QIcon(':/images/viewer.svg')) app.setWindowIcon(QIcon(I('viewer.svg')))
QApplication.setOrganizationName(ORG_NAME) QApplication.setOrganizationName(ORG_NAME)
QApplication.setApplicationName(APP_UID) QApplication.setApplicationName(APP_UID)
main = EbookViewer(args[1] if len(args) > 1 else None, main = EbookViewer(args[1] if len(args) > 1 else None,

View File

@ -27,7 +27,7 @@ class ProgressIndicator(QWidget):
def __init__(self, *args): def __init__(self, *args):
QWidget.__init__(self, *args) QWidget.__init__(self, *args)
self.setGeometry(0, 0, 300, 350) self.setGeometry(0, 0, 300, 350)
self.movie = QMovie(':/images/jobs-animated.mng') self.movie = QMovie(I('jobs-animated.mng'))
self.ml = QLabel(self) self.ml = QLabel(self)
self.ml.setMovie(self.movie) self.ml.setMovie(self.movie)
self.movie.start() self.movie.start()
@ -159,10 +159,10 @@ class LocationModel(QAbstractListModel):
def __init__(self, parent): def __init__(self, parent):
QAbstractListModel.__init__(self, parent) QAbstractListModel.__init__(self, parent)
self.icons = [QVariant(QIcon(':/images/library.png')), self.icons = [QVariant(QIcon(I('library.png'))),
QVariant(QIcon(':/images/reader.svg')), QVariant(QIcon(I('reader.svg'))),
QVariant(QIcon(':/images/sd.svg')), QVariant(QIcon(I('sd.svg'))),
QVariant(QIcon(':/images/sd.svg'))] QVariant(QIcon(I('sd.svg')))]
self.text = [_('Library\n%d\nbooks'), self.text = [_('Library\n%d\nbooks'),
_('Reader\n%s\navailable'), _('Reader\n%s\navailable'),
_('Card A\n%s\navailable'), _('Card A\n%s\navailable'),
@ -313,7 +313,7 @@ class EjectButton(QAbstractButton):
def paintEvent(self, event): def paintEvent(self, event):
painter = QPainter(self) painter = QPainter(self)
painter.setClipRect(event.rect()) painter.setClipRect(event.rect())
image = QPixmap(':/images/eject').scaledToHeight(event.rect().height(), image = QPixmap(I('eject')).scaledToHeight(event.rect().height(),
Qt.SmoothTransformation) Qt.SmoothTransformation)
if not self.mouse_over: if not self.mouse_over:

View File

@ -532,8 +532,8 @@ class Wizard(QWizard):
self.setPixmap(self.LogoPixmap, p.scaledToHeight(80, self.setPixmap(self.LogoPixmap, p.scaledToHeight(80,
Qt.SmoothTransformation)) Qt.SmoothTransformation))
self.setPixmap(self.WatermarkPixmap, self.setPixmap(self.WatermarkPixmap,
QPixmap(':/images/welcome_wizard.svg')) QPixmap(I('welcome_wizard.svg')))
self.setPixmap(self.BackgroundPixmap, QPixmap(':/images/wizard.svg')) self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.svg')))
self.device_page = DevicePage() self.device_page = DevicePage()
self.library_page = LibraryPage() self.library_page = LibraryPage()
self.finish_page = FinishPage() self.finish_page = FinishPage()

View File

@ -428,7 +428,6 @@ def render_svg(image, dest):
def setup_desktop_integration(fatal_errors): def setup_desktop_integration(fatal_errors):
try: try:
from PyQt4.QtCore import QFile from PyQt4.QtCore import QFile
from calibre.gui2 import images_rc # Load images
from tempfile import mkdtemp from tempfile import mkdtemp
print 'Setting up desktop integration...' print 'Setting up desktop integration...'
@ -438,12 +437,12 @@ def setup_desktop_integration(fatal_errors):
cwd = os.getcwdu() cwd = os.getcwdu()
try: try:
os.chdir(tdir) os.chdir(tdir)
render_svg(QFile(':/images/mimetypes/lrf.svg'), os.path.join(tdir, 'calibre-lrf.png')) render_svg(QFile(I('mimetypes/lrf.svg')), os.path.join(tdir, 'calibre-lrf.png'))
check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True) check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True)
check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True) check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True)
QFile(':library').copy(os.path.join(tdir, 'calibre-gui.png')) QFile(I('library.png')).copy(os.path.join(tdir, 'calibre-gui.png'))
check_call('xdg-icon-resource install --size 128 calibre-gui.png calibre-gui', shell=True) check_call('xdg-icon-resource install --size 128 calibre-gui.png calibre-gui', shell=True)
render_svg(QFile(':/images/viewer.svg'), os.path.join(tdir, 'calibre-viewer.png')) render_svg(QFile(I('viewer.svg')), os.path.join(tdir, 'calibre-viewer.png'))
check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True)
f = open('calibre-lrfviewer.desktop', 'wb') f = open('calibre-lrfviewer.desktop', 'wb')

View File

@ -5,9 +5,10 @@ Dynamic language lookup of translations for user-visible strings.
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
from cStringIO import StringIO import os
from gettext import GNUTranslations from gettext import GNUTranslations
from calibre.translations.compiled import translations from calibre.utils.localization import get_lc_messages_path
__all__ = ['translate'] __all__ = ['translate']
@ -17,10 +18,13 @@ def translate(lang, text):
trans = None trans = None
if lang in _CACHE: if lang in _CACHE:
trans = _CACHE[lang] trans = _CACHE[lang]
elif lang in translations: else:
buf = StringIO(translations[lang]) mpath = get_lc_messages_path(lang)
trans = GNUTranslations(buf) if mpath is not None:
_CACHE[lang] = trans p = os.path.join(mpath, 'messages.mo')
if os.path.exists(p):
trans = GNUTranslations(open(p, 'rb'))
_CACHE[lang] = trans
if trans is None: if trans is None:
return getattr(__builtins__, '_', lambda x: x)(text) return getattr(__builtins__, '_', lambda x: x)(text)
return trans.ugettext(text) return trans.ugettext(text)

View File

@ -44,6 +44,19 @@ def get_lang():
def messages_path(lang): def messages_path(lang):
return P('localization/locales/%s/LC_MESSAGES'%lang) return P('localization/locales/%s/LC_MESSAGES'%lang)
def get_lc_messages_path(lang):
hlang = None
if lang in available_translations():
hlang = lang
else:
xlang = lang.split('_')[0]
if xlang in available_translations():
hlang = xlang
if hlang is not None:
return messages_path(hlang)
return None
def set_translators(): def set_translators():
# To test different translations invoke as # To test different translations invoke as
# CALIBRE_OVERRIDE_LANG=de_DE.utf8 program # CALIBRE_OVERRIDE_LANG=de_DE.utf8 program
@ -57,20 +70,12 @@ def set_translators():
make(lang+'.po', buf) make(lang+'.po', buf)
buf = cStringIO.StringIO(buf.getvalue()) buf = cStringIO.StringIO(buf.getvalue())
hlang = None mpath = get_lc_messages_path(lang)
if lang in available_translations(): if mpath is not None:
hlang = lang
else:
xlang = lang.split('_')[0]
if xlang in available_translations():
hlang = xlang
if hlang is not None:
if buf is None: if buf is None:
buf = open(os.path.join(messages_path(hlang), buf = open(os.path.join(mpath, 'messages.mo'), 'rb')
'messages.mo'), 'rb') mpath = mpath.replace(os.sep+'nds'+os.sep, os.sep+'de'+os.sep)
if hlang == 'nds': isof = os.path.join(mpath, 'iso639.mo')
hlang = 'de'
isof = os.path.join(messages_path(hlang), 'iso639.mo')
if os.path.exists(isof): if os.path.exists(isof):
iso639 = open(isof, 'rb') iso639 = open(isof, 'rb')
@ -115,8 +120,9 @@ def set_qt_translator(translator):
if lang is not None: if lang is not None:
if lang == 'nds': if lang == 'nds':
lang = 'de' lang = 'de'
for x in (lang, lang.split('_')[0]): mpath = get_lc_messages_path(lang)
p = os.path.join(messages_path(x), 'qt.qm') if mpath is not None:
p = os.path.join(mpath, 'qt.qm')
if os.path.exists(p): if os.path.exists(p):
return translator.load(p) return translator.load(p)
return False return False

View File

@ -13,5 +13,8 @@ def get_path(path):
path = path.replace(os.sep, '/') path = path.replace(os.sep, '/')
return os.path.join(sys.resources_location, *path.split('/')) return os.path.join(sys.resources_location, *path.split('/'))
__builtin__.__dict__['P'] = get_path def get_image_path(path):
return get_path('images/'+path)
__builtin__.__dict__['P'] = get_path
__builtin__.__dict__['I'] = get_image_path

View File

@ -13,8 +13,6 @@ from functools import partial
from contextlib import nested, closing from contextlib import nested, closing
from datetime import datetime from datetime import datetime
from PyQt4.Qt import QApplication, QFile, QIODevice
from calibre import browser, __appname__, iswindows, \ from calibre import browser, __appname__, iswindows, \
strftime, __version__, preferred_encoding strftime, __version__, preferred_encoding
@ -812,17 +810,11 @@ class BasicNewsRecipe(Recipe):
from calibre.gui2 import is_ok_to_use_qt from calibre.gui2 import is_ok_to_use_qt
if not is_ok_to_use_qt(): if not is_ok_to_use_qt():
return False return False
from calibre.gui2 import images_rc # Needed for access to logo img_data = open(I('library.png'), 'rb').read()
images_rc
if QApplication.instance() is None: QApplication([])
f = QFile(':/library')
f.open(QIODevice.ReadOnly)
img_data = str(f.readAll())
tdir = PersistentTemporaryDirectory('_default_cover') tdir = PersistentTemporaryDirectory('_default_cover')
img = os.path.join(tdir, 'logo.png') img = os.path.join(tdir, 'logo.png')
with open(img, 'wb') as g: with open(img, 'wb') as g:
g.write(img_data) g.write(img_data)
f.close()
img = os.path.basename(img) img = os.path.basename(img)
html= u'''\ html= u'''\
<html> <html>