Make progress work with block count
Break database thoroughly Fix pdf year bug
This commit is contained in:
10
TODO
10
TODO
@@ -59,7 +59,10 @@ TODO
|
|||||||
✓ Comic view context menu
|
✓ Comic view context menu
|
||||||
✓ Make the bookmark dock float over the reading area
|
✓ Make the bookmark dock float over the reading area
|
||||||
✓ Spacebar should not cut off lines at the top
|
✓ Spacebar should not cut off lines at the top
|
||||||
Track open bookmark windows so they can be closed quickly at exit
|
✓ Track open bookmark windows so they can be closed quickly at exit
|
||||||
|
Annotations
|
||||||
|
Text
|
||||||
|
Image
|
||||||
Adjust key navigation according to viewport dimensions
|
Adjust key navigation according to viewport dimensions
|
||||||
Search document using QTextCursor
|
Search document using QTextCursor
|
||||||
Filetypes:
|
Filetypes:
|
||||||
@@ -76,14 +79,13 @@ TODO
|
|||||||
✓ Define every widget in code
|
✓ Define every widget in code
|
||||||
Bugs:
|
Bugs:
|
||||||
Deselecting all directories in the settings dialog also filters out manually added books
|
Deselecting all directories in the settings dialog also filters out manually added books
|
||||||
Only one tab has its scroll position set when opening multiple books @ startup
|
PDF year
|
||||||
It's the one that has focus when application starts and ends
|
|
||||||
|
|
||||||
Secondary:
|
Secondary:
|
||||||
Annotations
|
|
||||||
Graphical themes
|
Graphical themes
|
||||||
Change focus rectangle dimensions
|
Change focus rectangle dimensions
|
||||||
Tab reordering
|
Tab reordering
|
||||||
|
Universal Ctrl + Tab
|
||||||
Allow tabs to detach and form their own windows
|
Allow tabs to detach and form their own windows
|
||||||
Goodreads API: Ratings, Read, Recommendations
|
Goodreads API: Ratings, Read, Recommendations
|
||||||
Get ISBN using python-isbnlib
|
Get ISBN using python-isbnlib
|
||||||
|
@@ -553,7 +553,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.bookToolBar.tocBox.setCurrentIndex(
|
self.bookToolBar.tocBox.setCurrentIndex(
|
||||||
current_position['current_chapter'] - 1)
|
current_position['current_chapter'] - 1)
|
||||||
if not current_metadata['images_only']:
|
if not current_metadata['images_only']:
|
||||||
current_tab.set_cursor_position()
|
current_tab.hiddenButton.animateClick(25)
|
||||||
self.bookToolBar.tocBox.blockSignals(False)
|
self.bookToolBar.tocBox.blockSignals(False)
|
||||||
|
|
||||||
self.profile_functions.format_contentView()
|
self.profile_functions.format_contentView()
|
||||||
@@ -582,45 +582,15 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
def set_toc_position(self, event=None):
|
def set_toc_position(self, event=None):
|
||||||
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
||||||
|
|
||||||
# We're updating the underlying model to have real-time
|
|
||||||
# updates on the read status
|
|
||||||
|
|
||||||
# Set a baseline model index in case the item gets deleted
|
|
||||||
# E.g It's open in a tab and deleted from the library
|
|
||||||
model_index = None
|
|
||||||
start_index = self.lib_ref.view_model.index(0, 0)
|
|
||||||
# Find index of the model item that corresponds to the tab
|
|
||||||
matching_item = self.lib_ref.view_model.match(
|
|
||||||
start_index,
|
|
||||||
QtCore.Qt.UserRole + 6,
|
|
||||||
current_tab.metadata['hash'],
|
|
||||||
1, QtCore.Qt.MatchExactly)
|
|
||||||
if matching_item:
|
|
||||||
model_row = matching_item[0].row()
|
|
||||||
model_index = self.lib_ref.view_model.index(model_row, 0)
|
|
||||||
|
|
||||||
current_tab.metadata[
|
current_tab.metadata[
|
||||||
'position']['current_chapter'] = event + 1
|
'position']['current_chapter'] = event + 1
|
||||||
current_tab.metadata[
|
current_tab.metadata[
|
||||||
'position']['is_read'] = False
|
'position']['is_read'] = False
|
||||||
|
|
||||||
# TODO
|
|
||||||
# This doesn't update correctly
|
|
||||||
# try:
|
|
||||||
# position_perc = (
|
|
||||||
# current_tab.metadata[
|
|
||||||
# 'current_chapter'] * 100 / current_tab.metadata['total_chapters'])
|
|
||||||
# except KeyError:
|
|
||||||
# position_perc = None
|
|
||||||
|
|
||||||
if model_index:
|
|
||||||
self.lib_ref.view_model.setData(
|
|
||||||
model_index, current_tab.metadata, QtCore.Qt.UserRole + 3)
|
|
||||||
# self.lib_ref.view_model.setData(
|
|
||||||
# model_index, position_perc, QtCore.Qt.UserRole + 7)
|
|
||||||
|
|
||||||
# Go on to change the value of the Table of Contents box
|
# Go on to change the value of the Table of Contents box
|
||||||
current_tab.change_chapter_tocBox()
|
current_tab.change_chapter_tocBox()
|
||||||
|
current_tab.contentView.record_position()
|
||||||
|
|
||||||
self.profile_functions.format_contentView()
|
self.profile_functions.format_contentView()
|
||||||
|
|
||||||
def set_fullscreen(self):
|
def set_fullscreen(self):
|
||||||
|
@@ -53,7 +53,7 @@ class DatabaseInit:
|
|||||||
'CheckState': 'INTEGER'}
|
'CheckState': 'INTEGER'}
|
||||||
|
|
||||||
if os.path.exists(self.database_path):
|
if os.path.exists(self.database_path):
|
||||||
self.check_database()
|
self.check_columns()
|
||||||
else:
|
else:
|
||||||
self.create_database()
|
self.create_database()
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ class DatabaseInit:
|
|||||||
self.database.commit()
|
self.database.commit()
|
||||||
self.database.close()
|
self.database.close()
|
||||||
|
|
||||||
def check_database(self):
|
def check_columns(self):
|
||||||
self.database = sqlite3.connect(self.database_path)
|
self.database = sqlite3.connect(self.database_path)
|
||||||
|
|
||||||
database_return = self.database.execute("PRAGMA table_info(books)").fetchall()
|
database_return = self.database.execute("PRAGMA table_info(books)").fetchall()
|
||||||
@@ -89,7 +89,6 @@ class DatabaseInit:
|
|||||||
|
|
||||||
if commit_required:
|
if commit_required:
|
||||||
self.database.commit()
|
self.database.commit()
|
||||||
self.database.close()
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseFunctions:
|
class DatabaseFunctions:
|
||||||
|
@@ -33,6 +33,7 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate):
|
|||||||
# painter.fillRect(option.rect, QtGui.QColor().fromRgb(255, 0, 0, 20))
|
# painter.fillRect(option.rect, QtGui.QColor().fromRgb(255, 0, 0, 20))
|
||||||
|
|
||||||
option = option.__class__(option)
|
option = option.__class__(option)
|
||||||
|
title = index.data(QtCore.Qt.UserRole)
|
||||||
file_exists = index.data(QtCore.Qt.UserRole + 5)
|
file_exists = index.data(QtCore.Qt.UserRole + 5)
|
||||||
metadata = index.data(QtCore.Qt.UserRole + 3)
|
metadata = index.data(QtCore.Qt.UserRole + 3)
|
||||||
|
|
||||||
@@ -65,20 +66,27 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate):
|
|||||||
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
|
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
|
||||||
if position:
|
if position:
|
||||||
if is_read:
|
if is_read:
|
||||||
current_chapter = total_chapters = 100
|
progress = total = -1
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
current_chapter = position['current_chapter']
|
progress = position['current_block']
|
||||||
total_chapters = position['total_chapters']
|
total = position['total_blocks']
|
||||||
|
if progress == total == 0:
|
||||||
|
raise KeyError
|
||||||
|
except KeyError:
|
||||||
|
# For comics and older database entries
|
||||||
|
# It looks ugly but leave it like this
|
||||||
|
try:
|
||||||
|
progress = position['current_chapter']
|
||||||
|
total = position['total_chapters']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return
|
return
|
||||||
|
|
||||||
read_icon = pie_chart.pixmapper(
|
read_icon = pie_chart.pixmapper(
|
||||||
current_chapter, total_chapters, self.temp_dir, 36)
|
progress, total, self.temp_dir, 36)
|
||||||
|
|
||||||
x_draw = option.rect.bottomRight().x() - 30
|
x_draw = option.rect.bottomRight().x() - 30
|
||||||
y_draw = option.rect.bottomRight().y() - 35
|
y_draw = option.rect.bottomRight().y() - 35
|
||||||
if current_chapter != 1:
|
|
||||||
painter.drawPixmap(x_draw, y_draw, read_icon)
|
painter.drawPixmap(x_draw, y_draw, read_icon)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -122,6 +122,8 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
|||||||
|
|
||||||
file_exists = item.data(QtCore.Qt.UserRole + 5)
|
file_exists = item.data(QtCore.Qt.UserRole + 5)
|
||||||
metadata = item.data(QtCore.Qt.UserRole + 3)
|
metadata = item.data(QtCore.Qt.UserRole + 3)
|
||||||
|
progress_perc = item.data(QtCore.Qt.UserRole + 7)
|
||||||
|
|
||||||
position = metadata['position']
|
position = metadata['position']
|
||||||
if position:
|
if position:
|
||||||
is_read = position['is_read']
|
is_read = position['is_read']
|
||||||
@@ -132,21 +134,23 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
|||||||
|
|
||||||
if position:
|
if position:
|
||||||
if is_read:
|
if is_read:
|
||||||
current_chapter = total_chapters = 100
|
progress = total = -2
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
current_chapter = position['current_chapter']
|
progress = position['current_block']
|
||||||
total_chapters = position['total_chapters']
|
total = position['total_blocks']
|
||||||
|
|
||||||
# TODO
|
if progress == total == 0:
|
||||||
# See if there's any rationale for this
|
|
||||||
if current_chapter == 1:
|
|
||||||
raise KeyError
|
raise KeyError
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
progress = position['current_chapter']
|
||||||
|
total = position['total_chapters']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return
|
return
|
||||||
|
|
||||||
return_pixmap = pie_chart.pixmapper(
|
return_pixmap = pie_chart.pixmapper(
|
||||||
current_chapter, total_chapters, self.temp_dir,
|
progress, total, self.temp_dir,
|
||||||
QtCore.Qt.SizeHintRole + 10)
|
QtCore.Qt.SizeHintRole + 10)
|
||||||
|
|
||||||
return return_pixmap
|
return return_pixmap
|
||||||
|
@@ -63,8 +63,8 @@ class ParsePDF:
|
|||||||
def get_year(self):
|
def get_year(self):
|
||||||
try:
|
try:
|
||||||
year = self.metadata.find('MetadataDate').text
|
year = self.metadata.find('MetadataDate').text
|
||||||
return year.replace('\n', '')
|
return int(year.replace('\n', '')[:4])
|
||||||
except AttributeError:
|
except (AttributeError, ValueError):
|
||||||
return 9999
|
return 9999
|
||||||
|
|
||||||
def get_cover_image(self):
|
def get_cover_image(self):
|
||||||
|
@@ -94,25 +94,24 @@ def generate_pie(progress_percent, temp_dir=None):
|
|||||||
return lSvg
|
return lSvg
|
||||||
|
|
||||||
|
|
||||||
def pixmapper(current_chapter, total_chapters, temp_dir, size):
|
def pixmapper(progress, total, temp_dir, size):
|
||||||
# A current_chapter of -1 implies the files does not exist
|
# A current_chapter of -1 implies the files does not exist
|
||||||
# A chapter number == Total chapters implies the file is unread
|
# A chapter number == Total chapters implies the file is unread
|
||||||
return_pixmap = None
|
return_pixmap = None
|
||||||
|
|
||||||
if current_chapter == -1:
|
if progress == -1:
|
||||||
return_pixmap = QtGui.QIcon(':/images/error.svg').pixmap(size)
|
return_pixmap = QtGui.QIcon(':/images/error.svg').pixmap(size)
|
||||||
return return_pixmap
|
return return_pixmap
|
||||||
|
|
||||||
if current_chapter == total_chapters:
|
if progress >= .95 * total: # Consider book read @ 95% progress
|
||||||
return_pixmap = QtGui.QIcon(':/images/checkmark.svg').pixmap(size)
|
return_pixmap = QtGui.QIcon(':/images/checkmark.svg').pixmap(size)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# See if saving the svg to disk can be avoided
|
# See if saving the svg to disk can be avoided
|
||||||
# Shift to lines to track progress
|
|
||||||
# Maybe make the alignment a little more uniform across emblems
|
# Maybe make the alignment a little more uniform across emblems
|
||||||
|
|
||||||
progress_percent = int(current_chapter * 100 / total_chapters)
|
progress_percent = int(progress * 100 / total)
|
||||||
generate_pie(progress_percent, temp_dir)
|
generate_pie(progress_percent, temp_dir)
|
||||||
svg_path = os.path.join(temp_dir, 'lector_progress.svg')
|
svg_path = os.path.join(temp_dir, 'lector_progress.svg')
|
||||||
return_pixmap = QtGui.QIcon(svg_path).pixmap(size - 4) ## The -4 looks more proportional
|
return_pixmap = QtGui.QIcon(svg_path).pixmap(size - 4) ## The -4 looks more proportional
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
# Reading modes
|
# Reading modes
|
||||||
# Double page, Continuous etc
|
# Double page, Continuous etc
|
||||||
# Especially for comics
|
# Especially for comics
|
||||||
# Remove variables that have anything to do with scroll position
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -191,28 +190,16 @@ class Tab(QtWidgets.QWidget):
|
|||||||
except IndexError: # The file has been deleted
|
except IndexError: # The file has been deleted
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_cursor_position(self, switch_widgets=True, search_data=None):
|
def set_cursor_position(self, cursor_position=None):
|
||||||
# if self.sender().objectName() == 'tabWidget' and self.first_run:
|
|
||||||
# return
|
|
||||||
# self.first_run = False
|
|
||||||
# ^^^ I have NO IDEA why this might be needed or how it works
|
|
||||||
|
|
||||||
if switch_widgets:
|
|
||||||
previous_widget = self.main_window.tabWidget.currentWidget()
|
|
||||||
self.main_window.tabWidget.setCurrentWidget(self)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
required_position = self.metadata['position']['cursor_position']
|
required_position = self.metadata['position']['cursor_position']
|
||||||
if search_data:
|
except KeyError:
|
||||||
required_position = search_data[1]
|
print(f'Database: Cursor position error. Recommend retry.')
|
||||||
|
|
||||||
# TODO
|
|
||||||
# Remove this at the time when a library rebuild is
|
|
||||||
# finally required
|
|
||||||
# Bookmarks will have to be regenerated in the meantime
|
|
||||||
if isinstance(required_position, str):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if cursor_position:
|
||||||
|
required_position = cursor_position
|
||||||
|
|
||||||
# This is needed so that the line we want is
|
# This is needed so that the line we want is
|
||||||
# always at the top of the window
|
# always at the top of the window
|
||||||
self.contentView.verticalScrollBar().setValue(
|
self.contentView.verticalScrollBar().setValue(
|
||||||
@@ -225,23 +212,12 @@ class Tab(QtWidgets.QWidget):
|
|||||||
self.contentView.setTextCursor(cursor)
|
self.contentView.setTextCursor(cursor)
|
||||||
self.contentView.ensureCursorVisible()
|
self.contentView.ensureCursorVisible()
|
||||||
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if switch_widgets:
|
|
||||||
self.main_window.tabWidget.setCurrentWidget(previous_widget)
|
|
||||||
|
|
||||||
def generate_position(self, is_read=False):
|
def generate_position(self, is_read=False):
|
||||||
total_chapters = len(self.metadata['content'])
|
total_chapters = len(self.metadata['content'])
|
||||||
|
|
||||||
current_chapter = 1
|
current_chapter = 1
|
||||||
scroll_value = 0
|
|
||||||
if is_read:
|
if is_read:
|
||||||
current_chapter = total_chapters
|
current_chapter = total_chapters
|
||||||
scroll_value = 1
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
# Use this to generate position
|
|
||||||
|
|
||||||
# Generate block count @ time of first read
|
# Generate block count @ time of first read
|
||||||
# Blocks are indexed from 0 up
|
# Blocks are indexed from 0 up
|
||||||
@@ -264,8 +240,8 @@ class Tab(QtWidgets.QWidget):
|
|||||||
'total_chapters': total_chapters,
|
'total_chapters': total_chapters,
|
||||||
'blocks_per_chapter': blocks_per_chapter,
|
'blocks_per_chapter': blocks_per_chapter,
|
||||||
'total_blocks': total_blocks,
|
'total_blocks': total_blocks,
|
||||||
'scroll_value': scroll_value,
|
|
||||||
'is_read': is_read,
|
'is_read': is_read,
|
||||||
|
'current_block': 0,
|
||||||
'cursor_position': 0}
|
'cursor_position': 0}
|
||||||
|
|
||||||
def generate_keyboard_shortcuts(self):
|
def generate_keyboard_shortcuts(self):
|
||||||
@@ -298,7 +274,7 @@ class Tab(QtWidgets.QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not self.are_we_doing_images_only:
|
if not self.are_we_doing_images_only:
|
||||||
self.contentView.record_scroll_position()
|
self.contentView.record_position()
|
||||||
|
|
||||||
self.contentView.setWindowFlags(QtCore.Qt.Window)
|
self.contentView.setWindowFlags(QtCore.Qt.Window)
|
||||||
self.contentView.setWindowState(QtCore.Qt.WindowFullScreen)
|
self.contentView.setWindowState(QtCore.Qt.WindowFullScreen)
|
||||||
@@ -316,7 +292,7 @@ class Tab(QtWidgets.QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not self.are_we_doing_images_only:
|
if not self.are_we_doing_images_only:
|
||||||
self.contentView.record_scroll_position()
|
self.contentView.record_position()
|
||||||
|
|
||||||
self.main_window.show()
|
self.main_window.show()
|
||||||
self.contentView.setWindowFlags(QtCore.Qt.Widget)
|
self.contentView.setWindowFlags(QtCore.Qt.Widget)
|
||||||
@@ -419,26 +395,25 @@ class Tab(QtWidgets.QWidget):
|
|||||||
|
|
||||||
if self.are_we_doing_images_only:
|
if self.are_we_doing_images_only:
|
||||||
chapter = self.metadata['position']['current_chapter']
|
chapter = self.metadata['position']['current_chapter']
|
||||||
search_data = (0, None)
|
cursor_position = 0
|
||||||
else:
|
else:
|
||||||
chapter, scroll_position, visible_text = self.contentView.record_scroll_position(True)
|
chapter, cursor_position = self.contentView.record_position(True)
|
||||||
search_data = (scroll_position, visible_text)
|
|
||||||
|
|
||||||
self.metadata['bookmarks'][identifier] = {
|
self.metadata['bookmarks'][identifier] = {
|
||||||
'chapter': chapter,
|
'chapter': chapter,
|
||||||
'search_data': search_data,
|
'cursor_position': cursor_position,
|
||||||
'description': description}
|
'description': description}
|
||||||
|
|
||||||
self.add_bookmark_to_model(
|
self.add_bookmark_to_model(
|
||||||
description, chapter, search_data, identifier)
|
description, chapter, cursor_position, identifier)
|
||||||
self.dockWidget.setVisible(True)
|
self.dockWidget.setVisible(True)
|
||||||
|
|
||||||
def add_bookmark_to_model(self, description, chapter, search_data, identifier):
|
def add_bookmark_to_model(self, description, chapter, cursor_position, identifier):
|
||||||
bookmark = QtGui.QStandardItem()
|
bookmark = QtGui.QStandardItem()
|
||||||
bookmark.setData(description, QtCore.Qt.DisplayRole)
|
bookmark.setData(description, QtCore.Qt.DisplayRole)
|
||||||
|
|
||||||
bookmark.setData(chapter, QtCore.Qt.UserRole)
|
bookmark.setData(chapter, QtCore.Qt.UserRole)
|
||||||
bookmark.setData(search_data, QtCore.Qt.UserRole + 1)
|
bookmark.setData(cursor_position, QtCore.Qt.UserRole + 1)
|
||||||
bookmark.setData(identifier, QtCore.Qt.UserRole + 2)
|
bookmark.setData(identifier, QtCore.Qt.UserRole + 2)
|
||||||
|
|
||||||
self.bookmark_model.appendRow(bookmark)
|
self.bookmark_model.appendRow(bookmark)
|
||||||
@@ -449,22 +424,30 @@ class Tab(QtWidgets.QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
chapter = self.proxy_model.data(index, QtCore.Qt.UserRole)
|
chapter = self.proxy_model.data(index, QtCore.Qt.UserRole)
|
||||||
search_data = self.proxy_model.data(index, QtCore.Qt.UserRole + 1)
|
cursor_position = self.proxy_model.data(index, QtCore.Qt.UserRole + 1)
|
||||||
|
|
||||||
self.main_window.bookToolBar.tocBox.setCurrentIndex(chapter - 1)
|
self.main_window.bookToolBar.tocBox.setCurrentIndex(chapter - 1)
|
||||||
if not self.are_we_doing_images_only:
|
if not self.are_we_doing_images_only:
|
||||||
self.set_cursor_position(False, search_data)
|
self.set_cursor_position(cursor_position)
|
||||||
|
|
||||||
def generate_bookmark_model(self):
|
def generate_bookmark_model(self):
|
||||||
# TODO
|
# TODO
|
||||||
# Sorting is not working correctly
|
# Sorting is not working correctly
|
||||||
|
|
||||||
|
try:
|
||||||
for i in self.metadata['bookmarks'].items():
|
for i in self.metadata['bookmarks'].items():
|
||||||
self.add_bookmark_to_model(
|
self.add_bookmark_to_model(
|
||||||
i[1]['description'],
|
i[1]['description'],
|
||||||
i[1]['chapter'],
|
i[1]['chapter'],
|
||||||
i[1]['search_data'],
|
i[1]['cursor_position'],
|
||||||
i[0])
|
i[0])
|
||||||
|
except KeyError:
|
||||||
|
title = self.metadata['title']
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# Delete the bookmarks entry for this file
|
||||||
|
print(f'Database: Bookmark error for {title}. Recommend delete entry.')
|
||||||
|
return
|
||||||
|
|
||||||
self.generate_bookmark_proxy_model()
|
self.generate_bookmark_proxy_model()
|
||||||
|
|
||||||
@@ -579,7 +562,7 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
|||||||
image_pixmap.loadFromData(page_data)
|
image_pixmap.loadFromData(page_data)
|
||||||
elif self.filetype == 'pdf':
|
elif self.filetype == 'pdf':
|
||||||
page_data = self.book.page(current_page)
|
page_data = self.book.page(current_page)
|
||||||
page_qimage = page_data.renderToImage(350, 350)
|
page_qimage = page_data.renderToImage(400, 400) # TODO Maybe this needs a setting?
|
||||||
image_pixmap.convertFromImage(page_qimage)
|
image_pixmap.convertFromImage(page_qimage)
|
||||||
return image_pixmap
|
return image_pixmap
|
||||||
|
|
||||||
@@ -672,7 +655,7 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
|||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
def wheelEvent(self, event):
|
def wheelEvent(self, event):
|
||||||
self.common_functions.wheelEvent(event, True)
|
self.common_functions.wheelEvent(event)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
vertical = self.verticalScrollBar().value()
|
vertical = self.verticalScrollBar().value()
|
||||||
@@ -712,6 +695,10 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
|||||||
if event.key() in view_modification_keys:
|
if event.key() in view_modification_keys:
|
||||||
self.main_window.modify_comic_view(event.key())
|
self.main_window.modify_comic_view(event.key())
|
||||||
|
|
||||||
|
def record_position(self):
|
||||||
|
self.parent.metadata['position']['is_read'] = False
|
||||||
|
self.common_functions.update_model()
|
||||||
|
|
||||||
def mouseMoveEvent(self, *args):
|
def mouseMoveEvent(self, *args):
|
||||||
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
||||||
self.parent.mouse_hide_timer.start(3000)
|
self.parent.mouse_hide_timer.start(3000)
|
||||||
@@ -825,13 +812,13 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
|||||||
self.setMouseTracking(True)
|
self.setMouseTracking(True)
|
||||||
self.viewport().setCursor(QtCore.Qt.IBeamCursor)
|
self.viewport().setCursor(QtCore.Qt.IBeamCursor)
|
||||||
self.verticalScrollBar().sliderMoved.connect(
|
self.verticalScrollBar().sliderMoved.connect(
|
||||||
self.record_scroll_position)
|
self.record_position)
|
||||||
self.ignore_wheel_event = False
|
self.ignore_wheel_event = False
|
||||||
self.ignore_wheel_event_number = 0
|
self.ignore_wheel_event_number = 0
|
||||||
|
|
||||||
def wheelEvent(self, event):
|
def wheelEvent(self, event):
|
||||||
self.record_scroll_position()
|
self.record_position()
|
||||||
self.common_functions.wheelEvent(event, False)
|
self.common_functions.wheelEvent(event)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
QtWidgets.QTextEdit.keyPressEvent(self, event)
|
QtWidgets.QTextEdit.keyPressEvent(self, event)
|
||||||
@@ -840,6 +827,7 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
|||||||
self.common_functions.change_chapter(1, True)
|
self.common_functions.change_chapter(1, True)
|
||||||
else:
|
else:
|
||||||
self.set_top_line_cleanly()
|
self.set_top_line_cleanly()
|
||||||
|
self.record_position()
|
||||||
|
|
||||||
def set_top_line_cleanly(self):
|
def set_top_line_cleanly(self):
|
||||||
# Find the cursor position of the top line and move to it
|
# Find the cursor position of the top line and move to it
|
||||||
@@ -849,22 +837,27 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
|||||||
self.setTextCursor(find_cursor)
|
self.setTextCursor(find_cursor)
|
||||||
self.ensureCursorVisible()
|
self.ensureCursorVisible()
|
||||||
|
|
||||||
def record_scroll_position(self, return_as_bookmark=False):
|
def record_position(self, return_as_bookmark=False):
|
||||||
self.parent.metadata['position']['is_read'] = False
|
self.parent.metadata['position']['is_read'] = False
|
||||||
|
|
||||||
vertical = self.verticalScrollBar().value()
|
|
||||||
maximum = self.verticalScrollBar().maximum()
|
|
||||||
|
|
||||||
self.parent.metadata['position']['scroll_value'] = 1
|
|
||||||
if maximum != 0:
|
|
||||||
self.parent.metadata['position']['scroll_value'] = (vertical / maximum)
|
|
||||||
|
|
||||||
cursor = self.cursorForPosition(QtCore.QPoint(0, 0))
|
cursor = self.cursorForPosition(QtCore.QPoint(0, 0))
|
||||||
cursor_position = cursor.position()
|
cursor_position = cursor.position()
|
||||||
|
|
||||||
|
# Current block for progress measurement
|
||||||
|
current_block = cursor.block().blockNumber()
|
||||||
|
current_chapter = self.parent.metadata['position']['current_chapter']
|
||||||
|
|
||||||
|
blocks_per_chapter = self.parent.metadata['position']['blocks_per_chapter']
|
||||||
|
block_sum = sum(blocks_per_chapter[:(current_chapter - 1)])
|
||||||
|
block_sum += current_block
|
||||||
|
|
||||||
|
# This 'current_block' refers to the number of
|
||||||
|
# blocks in the book upto this one
|
||||||
|
self.parent.metadata['position']['current_block'] = block_sum
|
||||||
|
self.common_functions.update_model()
|
||||||
|
|
||||||
if return_as_bookmark:
|
if return_as_bookmark:
|
||||||
return (self.parent.metadata['position']['current_chapter'],
|
return (self.parent.metadata['position']['current_chapter'],
|
||||||
self.parent.metadata['position']['scroll_value'],
|
|
||||||
cursor_position)
|
cursor_position)
|
||||||
else:
|
else:
|
||||||
self.parent.metadata['position']['cursor_position'] = cursor_position
|
self.parent.metadata['position']['cursor_position'] = cursor_position
|
||||||
@@ -936,14 +929,15 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
|||||||
QtWidgets.QTextBrowser.mouseMoveEvent(self, event)
|
QtWidgets.QTextBrowser.mouseMoveEvent(self, event)
|
||||||
|
|
||||||
|
|
||||||
class PliantWidgetsCommonFunctions():
|
class PliantWidgetsCommonFunctions:
|
||||||
def __init__(self, parent_widget, main_window):
|
def __init__(self, parent_widget, main_window):
|
||||||
self.pw = parent_widget
|
self.pw = parent_widget
|
||||||
self.main_window = main_window
|
self.main_window = main_window
|
||||||
|
self.are_we_doing_images_only = self.pw.parent.are_we_doing_images_only
|
||||||
|
|
||||||
def wheelEvent(self, event, are_we_doing_images_only):
|
def wheelEvent(self, event):
|
||||||
ignore_events = 20
|
ignore_events = 20
|
||||||
if are_we_doing_images_only:
|
if self.are_we_doing_images_only:
|
||||||
ignore_events = 10
|
ignore_events = 10
|
||||||
|
|
||||||
if self.pw.ignore_wheel_event:
|
if self.pw.ignore_wheel_event:
|
||||||
@@ -953,7 +947,7 @@ class PliantWidgetsCommonFunctions():
|
|||||||
self.pw.ignore_wheel_event_number = 0
|
self.pw.ignore_wheel_event_number = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
if are_we_doing_images_only:
|
if self.are_we_doing_images_only:
|
||||||
QtWidgets.QGraphicsView.wheelEvent(self.pw, event)
|
QtWidgets.QGraphicsView.wheelEvent(self.pw, event)
|
||||||
else:
|
else:
|
||||||
QtWidgets.QTextBrowser.wheelEvent(self.pw, event)
|
QtWidgets.QTextBrowser.wheelEvent(self.pw, event)
|
||||||
@@ -1002,6 +996,40 @@ class PliantWidgetsCommonFunctions():
|
|||||||
if not was_button_pressed:
|
if not was_button_pressed:
|
||||||
self.pw.ignore_wheel_event = True
|
self.pw.ignore_wheel_event = True
|
||||||
|
|
||||||
|
if not self.are_we_doing_images_only:
|
||||||
|
self.pw.record_position()
|
||||||
|
|
||||||
|
def update_model(self):
|
||||||
|
# We're updating the underlying model to have real-time
|
||||||
|
# updates on the read status
|
||||||
|
|
||||||
|
# Set a baseline model index in case the item gets deleted
|
||||||
|
# E.g It's open in a tab and deleted from the library
|
||||||
|
model_index = None
|
||||||
|
start_index = self.main_window.lib_ref.view_model.index(0, 0)
|
||||||
|
|
||||||
|
# Find index of the model item that corresponds to the tab
|
||||||
|
model_index = self.main_window.lib_ref.view_model.match(
|
||||||
|
start_index,
|
||||||
|
QtCore.Qt.UserRole + 6,
|
||||||
|
self.pw.parent.metadata['hash'],
|
||||||
|
1, QtCore.Qt.MatchExactly)
|
||||||
|
|
||||||
|
if self.are_we_doing_images_only:
|
||||||
|
position_percentage = (self.pw.parent.metadata['position']['current_chapter'] /
|
||||||
|
self.pw.parent.metadata['position']['total_chapters'])
|
||||||
|
else:
|
||||||
|
position_percentage = (self.pw.parent.metadata['position']['current_block'] /
|
||||||
|
self.pw.parent.metadata['position']['total_blocks'])
|
||||||
|
|
||||||
|
# Update book metadata and position percentage
|
||||||
|
if model_index:
|
||||||
|
self.main_window.lib_ref.view_model.setData(
|
||||||
|
model_index[0], self.pw.parent.metadata, QtCore.Qt.UserRole + 3)
|
||||||
|
|
||||||
|
self.main_window.lib_ref.view_model.setData(
|
||||||
|
model_index[0], position_percentage, QtCore.Qt.UserRole + 7)
|
||||||
|
|
||||||
def generate_combo_box_action(self, contextMenu):
|
def generate_combo_box_action(self, contextMenu):
|
||||||
contextMenu.addSeparator()
|
contextMenu.addSeparator()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user