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
let g:pyflakes_builtins += ["dynamic_property", "__", "P"]
let g:pyflakes_builtins += ["dynamic_property", "__", "P", "I"]
python << EOFPY
import os

View File

@ -22,8 +22,23 @@ def check_version_info():
def option_parser():
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
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):
if len(args) == 1 or args[1] in ('-h', '--help'):
print 'Usage: python', args[0], 'command', '[options]'
@ -46,6 +61,21 @@ def main(args=sys.argv):
command.description)
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)
warnings = get_warnings()

View File

@ -11,13 +11,10 @@ __all__ = [
'build',
'gui',
'develop',
'clean', 'clean_backups',
]
import os, shutil
from setup.translations import POT, GetTranslations, Translations, ISO639
from setup import Command
pot = POT()
translations = Translations()
get_translations = GetTranslations()
@ -32,50 +29,6 @@ develop = Develop()
from setup.gui import 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 = {}
for x in __all__:

View File

@ -55,30 +55,30 @@ class GUI(Command):
def build_forms(self):
from PyQt4.uic import compileUi
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:
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:
print 'Compiling form', form
self.info('\tCompiling form', form)
buf = cStringIO.StringIO()
compileUi(form, buf)
dat = buf.getvalue()
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 widgets import', 'from calibre.gui2.widgets import')
dat = dat.replace('from 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 = dat.replace('_("MMM yyyy")', '"MMM yyyy"')
# 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)
dat = pat.sub(sub, dat)
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 += '\n\nfrom calibre.gui2.viewer.documentview import DocumentView'

View File

@ -194,21 +194,12 @@ class EPUBOutput(OutputFormatPlugin):
if self.opts.no_default_epub_cover:
return None
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
images_rc
m = self.oeb.metadata
title = unicode(m.title[0])
a = [unicode(x) for x in m.creator if x.role == 'aut']
author = authors_to_string(a)
if not is_ok_to_use_qt(): return
f = QFile(':/library')
f.open(QIODevice.ReadOnly)
img_data = str(f.readAll())
img_data = open(I('library.png'), 'rb').read()
id, href = self.oeb.manifest.generate('calibre-logo',
'calibre-logo.png')
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,
parent, det_msg)
d.setEscapeButton(QMessageBox.Ok)
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
d.setIconPixmap(QPixmap(I('dialog_warning.svg')))
if show:
return d.exec_()
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):
d = MessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_error.svg'))
d.setIconPixmap(QPixmap(I('dialog_error.svg')))
d.setEscapeButton(QMessageBox.Ok)
if show:
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=''):
d = MessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No,
parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
d.setIconPixmap(QPixmap(I('dialog_information.svg')))
d.setEscapeButton(QMessageBox.No)
return d.exec_() == QMessageBox.Yes
def info_dialog(parent, title, msg, det_msg='', show=False):
d = MessageBox(QMessageBox.Information, title, msg, QMessageBox.Ok,
parent, det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
d.setIconPixmap(QPixmap(I('dialog_information.svg')))
if show:
return d.exec_()
return d
@ -321,7 +321,7 @@ class FileIconProvider(QFileIconProvider):
QFileIconProvider.__init__(self)
self.icons = {}
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'):
self.icons[i] = QIcon(self.icons[i])

View File

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

View File

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

View File

@ -17,7 +17,7 @@ from calibre.gui2 import error_dialog, choose_dir
class DebugWidget(Widget, Ui_Form):
TITLE = _('Debug')
ICON = ':/images/debug.svg'
ICON = I('debug.svg')
HELP = _('Debug the conversion process.')
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):
TITLE = _('Look & Feel')
ICON = ':/images/lookfeel.svg'
ICON = I('lookfeel.svg')
HELP = _('Control the look and feel of the output')
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):
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 '
'metadata as possible.')

View File

@ -149,7 +149,7 @@ class Config(ResizableDialog, Ui_Dialog):
output_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1])
pw = output_widget.PluginWidget
pw.ICON = ':/images/back.svg'
pw.ICON = I('back.svg')
pw.HELP = _('Options specific to the output format.')
output_widget = widget_factory(pw)
except ImportError:
@ -160,7 +160,7 @@ class Config(ResizableDialog, Ui_Dialog):
input_widget = __import__('calibre.gui2.convert.'+name,
fromlist=[1])
pw = input_widget.PluginWidget
pw.ICON = ':/images/forward.svg'
pw.ICON = I('forward.svg')
pw.HELP = _('Options specific to the input format.')
input_widget = widget_factory(pw)
except ImportError:
@ -249,13 +249,4 @@ class Config(ResizableDialog, Ui_Dialog):
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):
TITLE = _('Structure\nDetection')
ICON = ':/images/chapters.svg'
ICON = I('chapters.svg')
HELP = _('Fine tune the detection of chapter headings and '
'other document structure.')

View File

@ -14,7 +14,7 @@ from calibre.gui2 import error_dialog
class TOCWidget(Widget, Ui_Form):
TITLE = _('Table of\nContents')
ICON = ':/images/series.svg'
ICON = I('series.svg')
HELP = _('Control the creation/conversion of the Table of Contents.')
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]
dest = 'mail:'+account+';'+formats
if default:
default_account = (dest, False, False, ':/images/mail.svg',
default_account = (dest, False, False, I('mail.svg'),
_('Email to')+' '+account)
action1 = DeviceAction(dest, False, False, ':/images/mail.svg',
action1 = DeviceAction(dest, False, False, I('mail.svg'),
_('Email to')+' '+account, self)
action2 = DeviceAction(dest, True, False, ':/images/mail.svg',
action2 = DeviceAction(dest, True, False, I('mail.svg'),
_('Email to')+' '+account, self)
map(self.email_to_menu.addAction, (action1, action2))
map(self._memory.append, (action1, action2))
@ -317,25 +317,25 @@ class DeviceMenu(QMenu):
self.action_triggered)
_actions = [
('main:', False, False, ':/images/reader.svg',
('main:', False, False, I('reader.svg'),
_('Send to main memory')),
('carda:0', False, False, ':/images/sd.svg',
('carda:0', False, False, I('sd.svg'),
_('Send to storage card A')),
('cardb:0', False, False, ':/images/sd.svg',
('cardb:0', False, False, I('sd.svg'),
_('Send to storage card B')),
'-----',
('main:', True, False, ':/images/reader.svg',
('main:', True, False, I('reader.svg'),
_('Send to main memory')),
('carda:0', True, False, ':/images/sd.svg',
('carda:0', True, False, I('sd.svg'),
_('Send to storage card A')),
('cardb:0', True, False, ':/images/sd.svg',
('cardb:0', True, False, I('sd.svg'),
_('Send to storage card B')),
'-----',
('main:', False, True, ':/images/reader.svg',
('main:', False, True, I('reader.svg'),
_('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')),
('cardb:0', False, True, ':/images/sd.svg',
('cardb:0', False, True, I('sd.svg'),
_('Send specific format to storage card B')),
]

View File

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

View File

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

View File

@ -98,8 +98,8 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
def __init__(self, db, *args):
QAbstractItemModel.__init__(self, *args)
SearchQueryParser.__init__(self)
self.default_icon = QIcon(':/images/news.svg')
self.custom_icon = QIcon(':/images/user_profile.svg')
self.default_icon = QIcon(I('news.svg'))
self.custom_icon = QIcon(I('user_profile.svg'))
self.recipes = copy.deepcopy(builtin_recipes)
for x in db.get_recipes():
recipe = compile_recipe(x[1])
@ -215,7 +215,7 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
return recipe
elif role == Qt.DecorationRole:
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:
icon = self.custom_icon
elif QFile().exists(icon_path):
@ -420,11 +420,11 @@ class Scheduler(QObject):
self.oldest_check()
self.news_menu = QMenu()
self.news_icon = QIcon(':/images/news.svg')
self.scheduler_action = QAction(QIcon(':/images/scheduler.svg'), _('Schedule news download'), self)
self.news_icon = QIcon(I('news.svg'))
self.scheduler_action = QAction(QIcon(I('scheduler.svg')), _('Schedule news download'), self)
self.news_menu.addAction(self.scheduler_action)
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.news_menu.addAction(self.cac)

View File

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

View File

@ -172,7 +172,7 @@ class BooksModel(QAbstractTableModel):
self.column_map = config['column_map']
self.editable_cols = ['title', 'authors', 'rating', 'publisher',
'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.last_search = '' # The last search performed on this model
self.read_config()

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ class BookInfoDisplay(QWidget):
WIDTH = 81
HEIGHT = 108
def __init__(self, coverpath=':/images/book.svg'):
def __init__(self, coverpath=I('book.svg')):
QLabel.__init__(self)
self.default_pixmap = QPixmap(coverpath).scaled(self.__class__.WIDTH,
self.__class__.HEIGHT,
@ -141,7 +141,7 @@ class CoverFlowButton(QToolButton):
def __init__(self, parent=None):
QToolButton.__init__(self, parent)
self.setIconSize(QSize(80, 80))
self.setIcon(QIcon(':/images/cover_flow.svg'))
self.setIcon(QIcon(I('cover_flow.svg')))
self.setCheckable(True)
self.setChecked(False)
self.setAutoRaise(True)
@ -163,7 +163,7 @@ class TagViewButton(QToolButton):
def __init__(self, parent=None):
QToolButton.__init__(self, parent)
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.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding))
self.setCursor(Qt.PointingHandCursor)
@ -177,7 +177,7 @@ class StatusBar(QStatusBar):
def __init__(self, jobs_dialog, systray=None):
QStatusBar.__init__(self)
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.tag_view_button = TagViewButton()
self.addPermanentWidget(self.cover_flow_button)

View File

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

View File

@ -67,7 +67,7 @@ class ProgressIndicator(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
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.setMovie(self.movie)
self.movie.start()
@ -283,7 +283,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.action_full_screen.setCheckable(True)
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.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup)
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
if pid <= 0:
app = Application(args)
app.setWindowIcon(QIcon(':/images/viewer.svg'))
app.setWindowIcon(QIcon(I('viewer.svg')))
QApplication.setOrganizationName(ORG_NAME)
QApplication.setApplicationName(APP_UID)
main = EbookViewer(args[1] if len(args) > 1 else None,

View File

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

View File

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

View File

@ -428,7 +428,6 @@ def render_svg(image, dest):
def setup_desktop_integration(fatal_errors):
try:
from PyQt4.QtCore import QFile
from calibre.gui2 import images_rc # Load images
from tempfile import mkdtemp
print 'Setting up desktop integration...'
@ -438,12 +437,12 @@ def setup_desktop_integration(fatal_errors):
cwd = os.getcwdu()
try:
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 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)
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)
f = open('calibre-lrfviewer.desktop', 'wb')

View File

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

View File

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

View File

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