Multiple fixes
MuPDF import error Definition text color Database logging
This commit is contained in:
5
TODO
5
TODO
@@ -97,10 +97,15 @@ TODO
|
||||
Bookmark name for a page that's not on the TOC and has nothing before
|
||||
Screen position still keeps jumping when inside a paragraph
|
||||
Better recursion needed for fb2 toc
|
||||
Search results should ignore punctuation
|
||||
Keep text size for annotations
|
||||
|
||||
Secondary:
|
||||
Definitions dialog needs to respond to escape
|
||||
Zoom slider for comics
|
||||
Tab tooltip
|
||||
Additional Settings:
|
||||
Find definitions on Google
|
||||
Disable progressbar - 20% book addition speed improvement
|
||||
Disable cover loading when reading - Saves ~2M / book
|
||||
Special formatting for each chapter's title
|
||||
|
@@ -21,13 +21,13 @@ import webbrowser
|
||||
|
||||
try:
|
||||
import fitz
|
||||
from lector.parsers.pdf import render_pdf_page
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
|
||||
from lector.rarfile import rarfile
|
||||
from lector.parsers.pdf import render_pdf_page
|
||||
from lector.threaded import BackGroundCacheRefill
|
||||
from lector.annotations import AnnotationPlacement
|
||||
|
||||
@@ -501,13 +501,17 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
QtWidgets.QTextBrowser.mouseReleaseEvent(self, event)
|
||||
return
|
||||
|
||||
self.place_annotation(self.current_annotation)
|
||||
self.toggle_annotation_mode()
|
||||
|
||||
def place_annotation(self, annotation):
|
||||
current_chapter = self.parent.metadata['position']['current_chapter']
|
||||
cursor = self.textCursor()
|
||||
cursor_start = cursor.selectionStart()
|
||||
cursor_end = cursor.selectionEnd()
|
||||
annotation_type = 'text_markup'
|
||||
applicable_to = 'text'
|
||||
annotation_components = self.current_annotation['components']
|
||||
annotation_components = annotation['components']
|
||||
|
||||
self.annotator.set_current_annotation(
|
||||
annotation_type, annotation_components)
|
||||
@@ -520,7 +524,7 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
# Maybe use annotation name for a consolidated annotation list
|
||||
|
||||
this_annotation = {
|
||||
'name': self.current_annotation['name'],
|
||||
'name': annotation['name'],
|
||||
'applicable_to': applicable_to,
|
||||
'type': annotation_type,
|
||||
'cursor': (cursor_start, cursor_end),
|
||||
@@ -533,8 +537,6 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
self.annotation_dict[current_chapter] = []
|
||||
self.annotation_dict[current_chapter].append(this_annotation)
|
||||
|
||||
self.toggle_annotation_mode()
|
||||
|
||||
def generate_textbrowser_context_menu(self, position):
|
||||
selection = self.textCursor().selection()
|
||||
selection = selection.toPlainText()
|
||||
@@ -552,6 +554,7 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
searchWikipediaAction = searchYoutubeAction = 'Does anyone know something funny in Latin?'
|
||||
searchAction = searchGoogleAction = bookmarksToggleAction = 'TODO Insert Latin Joke'
|
||||
deleteAnnotationAction = editAnnotationNoteAction = 'Latin quote 2. Electric Boogaloo.'
|
||||
annotationActions = []
|
||||
|
||||
if self.parent.is_fullscreen:
|
||||
fsToggleAction = contextMenu.addAction(
|
||||
@@ -566,13 +569,18 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
|
||||
if selection and selection != '':
|
||||
first_selected_word = selection.split()[0]
|
||||
elided_selection = selection
|
||||
if len(elided_selection) > 15:
|
||||
elided_selection = elided_selection[:15] + '...'
|
||||
|
||||
define_string = self._translate('PliantQTextBrowser', 'Define')
|
||||
defineAction = contextMenu.addAction(
|
||||
self.main_window.QImageFactory.get_image('view-readermode'),
|
||||
f'{define_string} "{first_selected_word}"')
|
||||
|
||||
search_submenu_string = self._translate('PliantQTextBrowser', 'Search for')
|
||||
searchSubMenu = contextMenu.addMenu(search_submenu_string + f' "{selection}"')
|
||||
searchSubMenu = contextMenu.addMenu(
|
||||
search_submenu_string + f' "{elided_selection}"')
|
||||
searchSubMenu.setIcon(self.main_window.QImageFactory.get_image('search'))
|
||||
|
||||
searchAction = searchSubMenu.addAction(
|
||||
@@ -588,6 +596,26 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
searchYoutubeAction = searchSubMenu.addAction(
|
||||
QtGui.QIcon(':/images/Youtube.png'),
|
||||
'Youtube')
|
||||
|
||||
# Allow adding new annotation from the context menu
|
||||
if not annotation_is_present:
|
||||
annotation_string = self._translate('PliantQTextBrowser', 'Annotate')
|
||||
annotationSubmenu = contextMenu.addMenu(annotation_string)
|
||||
annotationSubmenu.setIcon(
|
||||
self.main_window.QImageFactory.get_image('annotate'))
|
||||
|
||||
saved_annotations = self.parent.main_window.settings['annotations']
|
||||
if not saved_annotations:
|
||||
nope = annotationSubmenu.addAction('<No annotations set>')
|
||||
nope.setEnabled(False)
|
||||
|
||||
for i in saved_annotations:
|
||||
this_action = QtWidgets.QAction(i['name'])
|
||||
# Does not require / support a role
|
||||
this_action.setData(i)
|
||||
annotationActions.append(this_action)
|
||||
annotationSubmenu.addAction(this_action)
|
||||
|
||||
else:
|
||||
searchAction = contextMenu.addAction(
|
||||
self.main_window.QImageFactory.get_image('search'),
|
||||
@@ -639,10 +667,12 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
webbrowser.open_new_tab(
|
||||
f'https://www.youtube.com/results?search_query={selection}')
|
||||
|
||||
if action in annotationActions:
|
||||
self.place_annotation(action.data())
|
||||
|
||||
if action == editAnnotationNoteAction:
|
||||
self.common_functions.annotation_specific(
|
||||
'note', 'text', current_chapter, cursor_at_mouse.position())
|
||||
|
||||
if action == deleteAnnotationAction:
|
||||
self.common_functions.annotation_specific(
|
||||
'delete', 'text', current_chapter, cursor_at_mouse.position())
|
||||
|
@@ -210,8 +210,9 @@ class DatabaseFunctions:
|
||||
else:
|
||||
return None
|
||||
|
||||
except (KeyError, sqlite3.OperationalError):
|
||||
logger.critical('SQLite is in wretched rebellion @ data fetching handling')
|
||||
except Exception as e:
|
||||
error_string = 'SQLite is in wretched rebellion @ data fetching handling'
|
||||
logger.critical(error_string + f' {type(e).__name__} Arguments: {e.args}')
|
||||
|
||||
def fetch_covers_only(self, hash_list):
|
||||
parameter_marks = ','.join(['?' for i in hash_list])
|
||||
@@ -243,8 +244,9 @@ class DatabaseFunctions:
|
||||
try:
|
||||
self.database.execute(
|
||||
sql_command, update_data)
|
||||
except sqlite3.OperationalError:
|
||||
logger.critical('SQLite is in wretched rebellion @ metadata handling')
|
||||
except sqlite3.OperationalError as e:
|
||||
error_string = 'SQLite is in wretched rebellion @ metadata handling'
|
||||
logger.critical(error_string + f' {type(e).__name__} Arguments: {e.args}')
|
||||
|
||||
self.database.commit()
|
||||
self.database.close()
|
||||
|
@@ -86,12 +86,15 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
|
||||
if response.getcode() == 200:
|
||||
return_json = json.loads(response.read())
|
||||
return return_json
|
||||
except (urllib.error.HTTPError, urllib.error.URLError):
|
||||
except Exception as e:
|
||||
this_error = f'API access error'
|
||||
logger.exception(this_error + f' {type(e).__name__} Arguments: {e.args}')
|
||||
return None
|
||||
|
||||
def find_definition(self, word):
|
||||
word_root_json = self.api_call(self.root_url, word)
|
||||
if not word_root_json:
|
||||
logger.error('Word root json noped out: ' + word)
|
||||
self.set_text(word, None, None, True)
|
||||
return
|
||||
|
||||
@@ -100,6 +103,7 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
|
||||
|
||||
definition_json = self.api_call(self.define_url, word_root)
|
||||
if not definition_json:
|
||||
logger.error('Definition json noped out: ' + word_root)
|
||||
self.set_text(word, None, None, True)
|
||||
return
|
||||
|
||||
@@ -118,7 +122,7 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
|
||||
this_definition = j['definitions'][0].capitalize()
|
||||
except KeyError:
|
||||
# The API also reports crossReferenceMarkers here
|
||||
pass
|
||||
this_definition = '<Not found>'
|
||||
|
||||
try:
|
||||
definitions[category].add(this_definition)
|
||||
@@ -163,10 +167,21 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
|
||||
self.parent.get_color()
|
||||
background = self.parent.settings['dialog_background']
|
||||
|
||||
# Calculate inverse color for the background so that
|
||||
# the text doesn't look blank
|
||||
r, g, b, alpha = background.getRgb()
|
||||
inv_average = 255 - (r + g + b) // 3
|
||||
if 100 < inv_average < 150:
|
||||
inv_average = 255
|
||||
|
||||
foreground = QtGui.QColor(
|
||||
inv_average, inv_average, inv_average, alpha)
|
||||
|
||||
self.setStyleSheet(
|
||||
"QDialog {{background-color: {0}}}".format(background.name()))
|
||||
self.definitionView.setStyleSheet(
|
||||
"QTextBrowser {{background-color: {0}}}".format(background.name()))
|
||||
"QTextBrowser {{color:{0}; background-color: {1}}}".format(
|
||||
foreground.name(), background.name()))
|
||||
|
||||
if not set_initial:
|
||||
self.show()
|
||||
|
@@ -24,7 +24,11 @@ from PyQt5 import QtCore, QtGui
|
||||
|
||||
from lector import sorter
|
||||
from lector import database
|
||||
from lector.parsers.pdf import render_pdf_page
|
||||
|
||||
try:
|
||||
from lector.parsers.pdf import render_pdf_page
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -450,6 +450,8 @@ class Tab(QtWidgets.QWidget):
|
||||
if tocBox_readjust:
|
||||
self.set_tocBox_index(required_position, None)
|
||||
|
||||
self.contentView.setFocus()
|
||||
|
||||
def set_tocBox_index(self, current_position=None, tocBox=None):
|
||||
# Get current position from the metadata dictionary
|
||||
# in case it isn't specified
|
||||
|
Reference in New Issue
Block a user