mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix changing language in welcome wizard
Fix changing the user interface language in the welcome wizard causing some parts of the interface to remain in the old language until calibre is restarted. Fixes #1220767 [Language mismatch on the welcome wizard e-mail page & throughout the rest of the program UI](https://bugs.launchpad.net/calibre/+bug/1220767)
This commit is contained in:
parent
ffc0b5af73
commit
e7bcf65c34
@ -11,7 +11,6 @@ from PyQt4.Qt import (QCoreApplication, QIcon, QObject, QTimer,
|
||||
from calibre import prints, plugins, force_unicode
|
||||
from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux,
|
||||
filesystem_encoding, get_portable_base)
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
from calibre.utils.ipc import gui_socket_address, RC
|
||||
from calibre.gui2 import (ORG_NAME, APP_UID, initialize_file_icon_provider,
|
||||
Application, choose_dir, error_dialog, question_dialog, gprefs)
|
||||
@ -83,7 +82,6 @@ def find_portable_library():
|
||||
os.mkdir(lib)
|
||||
|
||||
def init_qt(args):
|
||||
from calibre.gui2.ui import Main
|
||||
parser = option_parser()
|
||||
opts, args = parser.parse_args(args)
|
||||
find_portable_library()
|
||||
@ -99,9 +97,8 @@ def init_qt(args):
|
||||
override = 'calibre-gui' if islinux else None
|
||||
app = Application(args, override_program_name=override)
|
||||
app.file_event_hook = EventAccumulator()
|
||||
actions = tuple(Main.create_application_menubar())
|
||||
app.setWindowIcon(QIcon(I('lt.png')))
|
||||
return app, opts, args, actions
|
||||
return app, opts, args
|
||||
|
||||
|
||||
def get_default_library_path():
|
||||
@ -208,6 +205,7 @@ class GuiRunner(QObject):
|
||||
raise SystemExit(1)
|
||||
|
||||
def initialize_db_stage2(self, db, tb):
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
|
||||
if db is None and tb is not None:
|
||||
# DB Repair failed
|
||||
@ -241,6 +239,7 @@ class GuiRunner(QObject):
|
||||
det_msg=traceback.format_exc(), show=True)
|
||||
|
||||
def initialize_db(self):
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
db = None
|
||||
try:
|
||||
db = LibraryDatabase(self.library_path)
|
||||
@ -307,13 +306,15 @@ def run_in_debug_mode(logpath=None):
|
||||
stderr=subprocess.STDOUT, stdin=open(os.devnull, 'r'),
|
||||
creationflags=creationflags)
|
||||
|
||||
def run_gui(opts, args, actions, listener, app, gui_debug=None):
|
||||
def run_gui(opts, args, listener, app, gui_debug=None):
|
||||
initialize_file_icon_provider()
|
||||
app.load_builtin_fonts(scan_for_fonts=True)
|
||||
if not dynamic.get('welcome_wizard_was_run', False):
|
||||
from calibre.gui2.wizard import wizard
|
||||
wizard().exec_()
|
||||
dynamic.set('welcome_wizard_was_run', True)
|
||||
from calibre.gui2.ui import Main
|
||||
actions = tuple(Main.create_application_menubar())
|
||||
runner = GuiRunner(opts, args, actions, listener, app, gui_debug=gui_debug)
|
||||
ret = app.exec_()
|
||||
if getattr(runner.main, 'run_wizard_b4_shutdown', False):
|
||||
@ -419,7 +420,7 @@ def main(args=sys.argv):
|
||||
args = ['calibre']
|
||||
|
||||
try:
|
||||
app, opts, args, actions = init_qt(args)
|
||||
app, opts, args = init_qt(args)
|
||||
except AbortInit:
|
||||
return 1
|
||||
from calibre.utils.lock import singleinstance
|
||||
@ -440,10 +441,10 @@ def main(args=sys.argv):
|
||||
except socket.error:
|
||||
cant_start()
|
||||
else:
|
||||
return run_gui(opts, args, actions, listener, app,
|
||||
return run_gui(opts, args, listener, app,
|
||||
gui_debug=gui_debug)
|
||||
else:
|
||||
return run_gui(opts, args, actions, listener, app,
|
||||
return run_gui(opts, args, listener, app,
|
||||
gui_debug=gui_debug)
|
||||
otherinstance = False
|
||||
try:
|
||||
@ -454,7 +455,7 @@ def main(args=sys.argv):
|
||||
# On windows only singleinstance can be trusted
|
||||
otherinstance = True if iswindows else False
|
||||
if not otherinstance and not opts.shutdown_running_calibre:
|
||||
return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug)
|
||||
return run_gui(opts, args, listener, app, gui_debug=gui_debug)
|
||||
|
||||
communicate(opts, args)
|
||||
|
||||
|
@ -78,15 +78,16 @@ class MainWindow(QMainWindow):
|
||||
|
||||
@classmethod
|
||||
def create_application_menubar(cls):
|
||||
if not cls.__actions:
|
||||
mb = QMenuBar(None)
|
||||
menu = QMenu()
|
||||
for action in cls.get_menubar_actions():
|
||||
menu.addAction(action)
|
||||
cls.__actions.append(action)
|
||||
yield action
|
||||
mb.addMenu(menu)
|
||||
cls.___menu_bar = mb
|
||||
cls.___menu = menu
|
||||
return cls.__actions
|
||||
|
||||
@classmethod
|
||||
def get_menubar_actions(cls):
|
||||
|
@ -14,7 +14,6 @@ from contextlib import closing
|
||||
from PyQt4.Qt import (QWizard, QWizardPage, QPixmap, Qt, QAbstractListModel,
|
||||
QVariant, QItemSelectionModel, SIGNAL, QObject, QTimer, pyqtSignal)
|
||||
from calibre import __appname__, patheq
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
from calibre.library.move import MoveLibrary
|
||||
from calibre.constants import (filesystem_encoding, iswindows, plugins,
|
||||
isportable)
|
||||
@ -29,7 +28,6 @@ from calibre.gui2 import min_available_height, available_width
|
||||
from calibre.utils.config import dynamic, prefs
|
||||
from calibre.gui2 import NONE, choose_dir, error_dialog
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.customize.ui import device_plugins
|
||||
|
||||
if iswindows:
|
||||
winutil = plugins['winutil'][0]
|
||||
@ -272,6 +270,7 @@ class Android(Device):
|
||||
|
||||
@classmethod
|
||||
def commit(cls):
|
||||
from calibre.customize.ui import device_plugins
|
||||
super(Android, cls).commit()
|
||||
for plugin in device_plugins(include_disabled=True):
|
||||
if hasattr(plugin, 'configure_for_generic_epub_app'):
|
||||
@ -292,6 +291,7 @@ class AndroidPhoneWithKindle(Android):
|
||||
|
||||
@classmethod
|
||||
def commit(cls):
|
||||
from calibre.customize.ui import device_plugins
|
||||
super(Android, cls).commit()
|
||||
for plugin in device_plugins(include_disabled=True):
|
||||
if hasattr(plugin, 'configure_for_kindle_app'):
|
||||
@ -461,6 +461,11 @@ class KindlePage(QWizardPage, KindleUI):
|
||||
def nextId(self):
|
||||
return FinishPage.ID
|
||||
|
||||
def retranslateUi(self, widget):
|
||||
KindleUI.retranslateUi(self, widget)
|
||||
if hasattr(self, 'send_email_widget'):
|
||||
self.send_email_widget.retranslateUi(self.send_email_widget)
|
||||
|
||||
class StanzaPage(QWizardPage, StanzaUI):
|
||||
|
||||
ID = 5
|
||||
@ -617,6 +622,7 @@ class Callback(object):
|
||||
|
||||
_mm = None
|
||||
def move_library(oldloc, newloc, parent, callback_on_complete):
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
callback = Callback(callback_on_complete)
|
||||
try:
|
||||
if not os.path.exists(os.path.join(newloc, 'metadata.db')):
|
||||
@ -710,10 +716,12 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
__builtin__.__dict__['_'] = lambda(x): x
|
||||
from calibre.utils.localization import set_translators
|
||||
from calibre.gui2 import qt_app
|
||||
from calibre.ebooks.metadata.book.base import reset_field_metadata
|
||||
set_translators()
|
||||
qt_app.load_translations()
|
||||
self.retranslate.emit()
|
||||
self.init_languages()
|
||||
reset_field_metadata()
|
||||
try:
|
||||
lang = prefs['language'].lower()[:2]
|
||||
metadata_plugins = {
|
||||
@ -728,6 +736,7 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
pass
|
||||
|
||||
def is_library_dir_suitable(self, x):
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
try:
|
||||
return LibraryDatabase.exists_at(x) or not os.listdir(x)
|
||||
except:
|
||||
@ -741,6 +750,7 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
return True
|
||||
|
||||
def change(self):
|
||||
from calibre.db.legacy import LibraryDatabase
|
||||
x = choose_dir(self, 'database location dialog',
|
||||
_('Select location for books'))
|
||||
if x:
|
||||
|
@ -3,7 +3,7 @@ Created on 25 May 2010
|
||||
|
||||
@author: charles
|
||||
'''
|
||||
import copy, traceback
|
||||
import traceback
|
||||
from collections import OrderedDict
|
||||
|
||||
from calibre.utils.config_base import tweaks
|
||||
@ -40,67 +40,13 @@ category_icon_map = {
|
||||
'languages' : 'languages.png',
|
||||
}
|
||||
|
||||
|
||||
class FieldMetadata(dict):
|
||||
'''
|
||||
key: the key to the dictionary is:
|
||||
- for standard fields, the metadata field name.
|
||||
- for custom fields, the metadata field name prefixed by '#'
|
||||
This is done to create two 'namespaces' so the names don't clash
|
||||
|
||||
label: the actual column label. No prefixing.
|
||||
|
||||
datatype: the type of information in the field. Valid values are listed in
|
||||
VALID_DATA_TYPES below.
|
||||
is_multiple: valid for the text datatype. If {}, the field is to be
|
||||
treated as a single term. If not None, it contains a dict of the form
|
||||
{'cache_to_list': ',',
|
||||
'ui_to_list': ',',
|
||||
'list_to_ui': ', '}
|
||||
where the cache_to_list contains the character used to split the value in
|
||||
the meta2 table, ui_to_list contains the character used to create a list
|
||||
from a value shown in the ui (each resulting value must be strip()ed and
|
||||
empty values removed), and list_to_ui contains the string used in join()
|
||||
to create a displayable string from the list.
|
||||
|
||||
kind == field: is a db field.
|
||||
kind == category: standard tag category that isn't a field. see news.
|
||||
kind == user: user-defined tag category.
|
||||
kind == search: saved-searches category.
|
||||
|
||||
is_category: is a tag browser category. If true, then:
|
||||
table: name of the db table used to construct item list
|
||||
column: name of the column in the normalized table to join on
|
||||
link_column: name of the column in the connection table to join on. This
|
||||
key should not be present if there is no link table
|
||||
category_sort: the field in the normalized table to sort on. This
|
||||
key must be present if is_category is True
|
||||
If these are None, then the category constructor must know how
|
||||
to build the item list (e.g., formats, news).
|
||||
The order below is the order that the categories will
|
||||
appear in the tags pane.
|
||||
|
||||
name: the text that is to be used when displaying the field. Column headings
|
||||
in the GUI, etc.
|
||||
|
||||
search_terms: the terms that can be used to identify the field when
|
||||
searching. They can be thought of as aliases for metadata keys, but are only
|
||||
valid when passed to search().
|
||||
|
||||
is_custom: the field has been added by the user.
|
||||
|
||||
rec_index: the index of the field in the db metadata record.
|
||||
|
||||
is_csp: field contains colon-separated pairs. Must also be text, is_multiple
|
||||
|
||||
'''
|
||||
|
||||
VALID_DATA_TYPES = frozenset([None, 'rating', 'text', 'comments', 'datetime',
|
||||
'int', 'float', 'bool', 'series', 'composite', 'enumeration'])
|
||||
|
||||
# Builtin metadata {{{
|
||||
|
||||
_field_metadata_prototype = [
|
||||
def _builtin_field_metadata():
|
||||
# This is a function so that changing the UI language allows newly created
|
||||
# field metadata objects to have correctly translated labels for builtin
|
||||
# fields.
|
||||
return [
|
||||
('authors', {'table':'authors',
|
||||
'column':'name',
|
||||
'link_column':'author',
|
||||
@ -390,11 +336,68 @@ class FieldMetadata(dict):
|
||||
]
|
||||
# }}}
|
||||
|
||||
class FieldMetadata(dict):
|
||||
'''
|
||||
key: the key to the dictionary is:
|
||||
- for standard fields, the metadata field name.
|
||||
- for custom fields, the metadata field name prefixed by '#'
|
||||
This is done to create two 'namespaces' so the names don't clash
|
||||
|
||||
label: the actual column label. No prefixing.
|
||||
|
||||
datatype: the type of information in the field. Valid values are listed in
|
||||
VALID_DATA_TYPES below.
|
||||
is_multiple: valid for the text datatype. If {}, the field is to be
|
||||
treated as a single term. If not None, it contains a dict of the form
|
||||
{'cache_to_list': ',',
|
||||
'ui_to_list': ',',
|
||||
'list_to_ui': ', '}
|
||||
where the cache_to_list contains the character used to split the value in
|
||||
the meta2 table, ui_to_list contains the character used to create a list
|
||||
from a value shown in the ui (each resulting value must be strip()ed and
|
||||
empty values removed), and list_to_ui contains the string used in join()
|
||||
to create a displayable string from the list.
|
||||
|
||||
kind == field: is a db field.
|
||||
kind == category: standard tag category that isn't a field. see news.
|
||||
kind == user: user-defined tag category.
|
||||
kind == search: saved-searches category.
|
||||
|
||||
is_category: is a tag browser category. If true, then:
|
||||
table: name of the db table used to construct item list
|
||||
column: name of the column in the normalized table to join on
|
||||
link_column: name of the column in the connection table to join on. This
|
||||
key should not be present if there is no link table
|
||||
category_sort: the field in the normalized table to sort on. This
|
||||
key must be present if is_category is True
|
||||
If these are None, then the category constructor must know how
|
||||
to build the item list (e.g., formats, news).
|
||||
The order below is the order that the categories will
|
||||
appear in the tags pane.
|
||||
|
||||
name: the text that is to be used when displaying the field. Column headings
|
||||
in the GUI, etc.
|
||||
|
||||
search_terms: the terms that can be used to identify the field when
|
||||
searching. They can be thought of as aliases for metadata keys, but are only
|
||||
valid when passed to search().
|
||||
|
||||
is_custom: the field has been added by the user.
|
||||
|
||||
rec_index: the index of the field in the db metadata record.
|
||||
|
||||
is_csp: field contains colon-separated pairs. Must also be text, is_multiple
|
||||
|
||||
'''
|
||||
|
||||
VALID_DATA_TYPES = frozenset([None, 'rating', 'text', 'comments', 'datetime',
|
||||
'int', 'float', 'bool', 'series', 'composite', 'enumeration'])
|
||||
|
||||
# search labels that are not db columns
|
||||
search_items = ['all', 'search']
|
||||
|
||||
def __init__(self):
|
||||
self._field_metadata = copy.deepcopy(self._field_metadata_prototype)
|
||||
self._field_metadata = _builtin_field_metadata()
|
||||
self._tb_cats = OrderedDict()
|
||||
self._tb_custom_fields = {}
|
||||
self._search_term_map = {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user