mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More work on profiles
This commit is contained in:
parent
592dad1194
commit
43338d6123
@ -113,6 +113,7 @@ def save_viewer_profile(profile_name, profile, *user_names: str):
|
||||
user_names = expand_profile_user_names(user_names)
|
||||
if isinstance(profile, (str, bytes)):
|
||||
profile = json.loads(profile)
|
||||
if isinstance(profile, dict):
|
||||
profile['__timestamp__'] = isoformat(utcnow())
|
||||
try:
|
||||
with open(os.path.join(viewer_config_dir, 'profiles.json'), 'rb') as f:
|
||||
@ -120,6 +121,10 @@ def save_viewer_profile(profile_name, profile, *user_names: str):
|
||||
except FileNotFoundError:
|
||||
raw = {}
|
||||
for name in user_names:
|
||||
if isinstance(profile, dict):
|
||||
raw.setdefault(name, {})[profile_name] = profile
|
||||
else:
|
||||
if name in raw:
|
||||
raw[name].pop(profile_name, None)
|
||||
with open(os.path.join(viewer_config_dir, 'profiles.json'), 'wb') as f:
|
||||
f.write(json.dumps(raw, indent=2, sort_keys=True).encode())
|
||||
|
@ -190,9 +190,6 @@ class UrlSchemeHandler(QWebEngineUrlSchemeHandler):
|
||||
encoded_fname = name[len('reader-background-'):]
|
||||
mt, data = background_image(encoded_fname)
|
||||
send_reply(rq, mt, data) if data else rq.fail(QWebEngineUrlRequestJob.Error.UrlNotFound)
|
||||
elif name == 'all-profiles':
|
||||
vp = load_viewer_profiles('viewer:', as_json_string=True)
|
||||
send_reply(rq, 'application/json', vp.encode())
|
||||
elif name.startswith('mathjax/'):
|
||||
handle_mathjax_request(rq, name)
|
||||
elif not name:
|
||||
@ -287,7 +284,7 @@ class ViewerBridge(Bridge):
|
||||
show_book_folder = from_js()
|
||||
show_help = from_js(object)
|
||||
update_reading_rates = from_js(object)
|
||||
save_profile = from_js(object, object)
|
||||
profile_op = from_js(object, object, object)
|
||||
|
||||
create_view = to_js()
|
||||
start_book_load = to_js()
|
||||
@ -307,6 +304,7 @@ class ViewerBridge(Bridge):
|
||||
repair_after_fullscreen_switch = to_js()
|
||||
viewer_font_size_changed = to_js()
|
||||
tts_event = to_js()
|
||||
profile_response = to_js()
|
||||
|
||||
|
||||
def apply_font_settings(page_or_view):
|
||||
@ -552,7 +550,7 @@ class WebView(RestartingWebEngineView):
|
||||
self.bridge.close_prep_finished.connect(self.close_prep_finished)
|
||||
self.bridge.highlights_changed.connect(self.highlights_changed)
|
||||
self.bridge.update_reading_rates.connect(self.update_reading_rates)
|
||||
self.bridge.save_profile.connect(self.save_profile)
|
||||
self.bridge.profile_op.connect(self.profile_op)
|
||||
self.bridge.edit_book.connect(self.edit_book)
|
||||
self.bridge.show_book_folder.connect(self.show_book_folder)
|
||||
self.bridge.show_help.connect(self.show_help)
|
||||
@ -572,8 +570,13 @@ class WebView(RestartingWebEngineView):
|
||||
self.inspector = Inspector(parent.inspector_dock.toggleViewAction(), self)
|
||||
parent.inspector_dock.setWidget(self.inspector)
|
||||
|
||||
def save_profile(self, name, settings):
|
||||
save_viewer_profile(name, settings, 'viewer:')
|
||||
def profile_op(self, which, profile_name, settings):
|
||||
if which == 'all-profiles':
|
||||
vp = load_viewer_profiles('viewer:')
|
||||
self.execute_when_ready('profile_response', 'all-profiles', vp)
|
||||
elif which == 'save-profile':
|
||||
save_viewer_profile(profile_name, settings, 'viewer:')
|
||||
self.execute_when_ready('profile_response', 'save-profile', profile_name)
|
||||
|
||||
def link_hovered(self, url):
|
||||
if url == 'javascript:void(0)':
|
||||
|
@ -5,8 +5,10 @@ from __python__ import bound_methods, hash_literals
|
||||
from elementmaker import E
|
||||
|
||||
from book_list.globals import get_session_data
|
||||
from book_list.item_list import create_item, create_item_list, create_side_action
|
||||
from dom import clear, unique_id
|
||||
from gettext import gettext as _
|
||||
from modals import question_dialog
|
||||
from read_book.globals import ui_operations
|
||||
from session import settings_for_reader_profile
|
||||
from widgets import create_button
|
||||
@ -19,29 +21,72 @@ def save_profile(container_id, hide_panel):
|
||||
name = container.querySelector('[name=profile_name]').value
|
||||
sd = get_session_data()
|
||||
settings = settings_for_reader_profile(sd)
|
||||
ui_operations.save_profile(name, settings, def(err_msg):
|
||||
if err_msg:
|
||||
ui_operations.show_error(_('Unhandled error'), _('Could not save profile with error: ') + err_msg)
|
||||
else:
|
||||
ui_operations.save_profile(name, settings, def():
|
||||
container = document.getElementById(container_id)
|
||||
if container:
|
||||
r = container.querySelector('.saved_msg')
|
||||
if r:
|
||||
clear(r)
|
||||
r.appendChild(E.div(E.i(_('Saved: ') + name), style='margin-top: 1rem; margin-bottom: 1rem'))
|
||||
load_profiles(container_id)
|
||||
)
|
||||
|
||||
|
||||
|
||||
def got_all_profiles(hide_panel, container_id, all_profiles):
|
||||
def use_profile(container_id, profile_name, profile_data):
|
||||
container = document.getElementById(container_id)
|
||||
if not container:
|
||||
return
|
||||
print(all_profiles)
|
||||
container.dispatchEvent(new Event('close_panel'))
|
||||
|
||||
|
||||
def delete_profile(container_id, profile_name):
|
||||
question_dialog(_('Are you sure?'), _('Are you sure you want to delete the saved profile named: {}?').format(profile_name),
|
||||
def (ok):
|
||||
if ok:
|
||||
ui_operations.save_profile(profile_name, None, def():
|
||||
load_profiles(container_id)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def got_all_profiles(container_id, all_profiles):
|
||||
container = document.getElementById(container_id)
|
||||
if not container:
|
||||
return
|
||||
all_profiles['__default__'] = {}
|
||||
names = list_wrap(Object.keys(all_profiles))
|
||||
names.pysort(def(x): return '' if x is '__default__' else x.toLowerCase();)
|
||||
pl = container.querySelector('.profiles_list_container')
|
||||
clear(pl)
|
||||
pl.appendChild(E.div(
|
||||
_('Load settings from one of the previously saved profiles below…')
|
||||
))
|
||||
pl.appendChild(E.div())
|
||||
items = []
|
||||
for name in names:
|
||||
display_name = name
|
||||
if name is '__default__':
|
||||
display_name = _('Restore settings to default values')
|
||||
side_actions = []
|
||||
else:
|
||||
side_actions = [create_side_action('trash', delete_profile.bind(None, container_id, name), _('Delete this profile'))]
|
||||
items.push(create_item(display_name, action=use_profile.bind(None, container_id, name, all_profiles[name]), side_actions=side_actions))
|
||||
create_item_list(pl.lastChild, items)
|
||||
|
||||
|
||||
def load_profiles(container_id):
|
||||
container = document.getElementById(container_id)
|
||||
if not container:
|
||||
return
|
||||
pl = container.querySelector('.profiles_list_container')
|
||||
clear(pl)
|
||||
pl.appendChild(E.div(_('Loading saved profiles, please wait…'), style='padding-bottom: 1rem'))
|
||||
ui_operations.get_all_profiles(got_all_profiles.bind(None, container_id))
|
||||
|
||||
|
||||
def create_profiles_panel(hide_panel, book, container, onclick):
|
||||
c = E.div(style='margin: 1rem', id=unique_id('placeholder-prefs'))
|
||||
c.addEventListener('close_panel', def(): hide_panel();, False)
|
||||
container_id = c.id
|
||||
a = E.div(
|
||||
style='display:flex',
|
||||
@ -61,8 +106,5 @@ def create_profiles_panel(hide_panel, book, container, onclick):
|
||||
c.appendChild(a)
|
||||
c.appendChild(E.div(class_='saved_msg'))
|
||||
c.appendChild(E.hr())
|
||||
c.appendChild(E.div(
|
||||
style='padding-bottom: 1rem', class_='loading_msg',
|
||||
_('Loading saved profiles, please wait…')
|
||||
))
|
||||
ui_operations.get_all_profiles(got_all_profiles.bind(None, hide_panel, container.id)
|
||||
c.appendChild(E.div(class_='profiles_list_container'))
|
||||
load_profiles(container_id)
|
||||
|
@ -72,28 +72,26 @@ def get_file(book, name, proceed):
|
||||
xhr.send()
|
||||
|
||||
|
||||
def profiles_recevied(proceed, end_type, xhr, ev):
|
||||
end_type = workaround_qt_bug(xhr, end_type)
|
||||
if end_type is 'abort':
|
||||
return
|
||||
if end_type is not 'load':
|
||||
show_error(_('Failed to load profiles'), _(
|
||||
'Could not load viewer profiles with error: {}').format(xhr.error_html))
|
||||
return
|
||||
if not xhr.responseType or xhr.responseType is 'text':
|
||||
result = JSON.parse(xhr.responseText)
|
||||
else:
|
||||
show_error(_('Failed to load profiles'), _(
|
||||
'Could not load viewer profiles: unknown response type: {}').format(xhr.responseType))
|
||||
return
|
||||
profiles_callbacks = {'all': None, 'saved': None}
|
||||
|
||||
proceed(result)
|
||||
@from_python
|
||||
def profile_response(which, x):
|
||||
if which is 'all-profiles':
|
||||
profiles_callbacks.all(x)
|
||||
profiles_callbacks.all = None
|
||||
elif which is 'save-profile':
|
||||
profiles_callbacks.saved()
|
||||
profiles_callbacks.saved = None
|
||||
|
||||
|
||||
def get_all_profiles(proceed):
|
||||
xhr = ajax('all-profiles', profiles_recevied.bind(None, proceed), ok_code=0)
|
||||
xhr.responseType = 'text'
|
||||
xhr.send()
|
||||
profiles_callbacks.all = proceed
|
||||
to_python.profile_op('all-profiles', '', None)
|
||||
|
||||
|
||||
def save_profile(name, settings, proceed):
|
||||
profiles_callbacks.saved = proceed
|
||||
to_python.profile_op('save-profile', name, settings)
|
||||
|
||||
|
||||
def get_mathjax_files(proceed):
|
||||
@ -351,9 +349,7 @@ if window is window.top:
|
||||
if TRANSLATIONS_DATA:
|
||||
install(TRANSLATIONS_DATA)
|
||||
ui_operations.get_all_profiles = get_all_profiles
|
||||
ui_operations.save_profile = def(name, settings, proceed):
|
||||
to_python.save_profile(name, settings)
|
||||
proceed()
|
||||
ui_operations.save_profile = save_profile
|
||||
ui_operations.get_file = get_file
|
||||
ui_operations.get_url_for_book_file_name = get_url_for_book_file_name
|
||||
ui_operations.get_mathjax_files = get_mathjax_files
|
||||
|
Loading…
x
Reference in New Issue
Block a user