Shift to tree view for bookmarks
Cleanup
This commit is contained in:
8
TODO
8
TODO
@@ -78,7 +78,8 @@ TODO
|
||||
Limit the extra files produced by KindleUnpack
|
||||
Have them save to memory
|
||||
✓ fb2 support
|
||||
Images need to show up in their placeholders
|
||||
✓ Images need to show up in their placeholders
|
||||
djvu support
|
||||
Other:
|
||||
✓ Define every widget in code
|
||||
Bugs:
|
||||
@@ -86,6 +87,9 @@ TODO
|
||||
Clean up 'switch' page layout
|
||||
Colors aren't loaded properly for annotation previews
|
||||
Cover page shouldn't be scolled midway
|
||||
Docks
|
||||
Fullscreening should keep dock visible
|
||||
Closing a book keeps dock show button clicked
|
||||
|
||||
Secondary:
|
||||
Graphical themes
|
||||
@@ -99,7 +103,7 @@ TODO
|
||||
Use embedded fonts + CSS
|
||||
Scrolling: Smooth / By Line
|
||||
Shift to logging instead of print statements
|
||||
txt, doc, chm, djvu support
|
||||
txt, doc, chm support
|
||||
Include icons for filetype emblems
|
||||
Comic view modes
|
||||
Continuous paging
|
||||
|
@@ -66,31 +66,3 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate):
|
||||
x_draw = option.rect.bottomRight().x() - 30
|
||||
y_draw = option.rect.bottomRight().y() - 35
|
||||
painter.drawPixmap(x_draw, y_draw, read_icon)
|
||||
|
||||
|
||||
class BookmarkDelegate(QtWidgets.QStyledItemDelegate):
|
||||
def __init__(self, main_window, parent=None):
|
||||
super(BookmarkDelegate, self).__init__()
|
||||
self.main_window = main_window
|
||||
self.parent = parent
|
||||
|
||||
def sizeHint(self, *args):
|
||||
dockwidget_width = self.parent.width() - 20
|
||||
return QtCore.QSize(dockwidget_width, 50)
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
# TODO
|
||||
# Alignment of the painted item
|
||||
|
||||
option = option.__class__(option)
|
||||
|
||||
chapter_index = index.data(QtCore.Qt.UserRole)
|
||||
chapter_name = self.main_window.bookToolBar.tocBox.itemText(chapter_index - 1)
|
||||
if len(chapter_name) > 25:
|
||||
chapter_name = chapter_name[:25] + '...'
|
||||
|
||||
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
|
||||
painter.drawText(
|
||||
option.rect,
|
||||
QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight | QtCore.Qt.TextWordWrap,
|
||||
' ' + chapter_name)
|
||||
|
@@ -31,7 +31,8 @@ class FB2:
|
||||
def read_fb2(self):
|
||||
try:
|
||||
if self.filename.endswith('.fb2.zip'):
|
||||
this_book = zipfile.ZipFile(self.filename, mode='r', allowZip64=True)
|
||||
this_book = zipfile.ZipFile(
|
||||
self.filename, mode='r', allowZip64=True)
|
||||
for i in this_book.filelist:
|
||||
if os.path.splitext(i.filename)[1] == '.fb2':
|
||||
book_text = this_book.read(i.filename)
|
||||
@@ -42,7 +43,7 @@ class FB2:
|
||||
|
||||
self.xml = BeautifulSoup(book_text, 'lxml')
|
||||
self.generate_book_metadata()
|
||||
except ValueError: # Not specifying an exception type here may be justified
|
||||
except: # Not specifying an exception type here may be justified
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -60,7 +61,8 @@ class FB2:
|
||||
self.book['title'] = os.path.splitext(
|
||||
os.path.basename(self.filename))[0]
|
||||
|
||||
self.book['author'] = all_tags.find('author').getText(separator=' ').replace('\n', ' ')
|
||||
self.book['author'] = all_tags.find(
|
||||
'author').getText(separator=' ').replace('\n', ' ')
|
||||
if self.book['author'] == '' or self.book['author'] is None:
|
||||
self.book['author'] = 'Unknown'
|
||||
|
||||
@@ -104,7 +106,8 @@ class FB2:
|
||||
replacement_string = f'<img src=\"{image_path}\"'
|
||||
|
||||
for j in self.book['book_list']:
|
||||
j[1] = j[1].replace(image_string, replacement_string)
|
||||
j[1] = j[1].replace(
|
||||
image_string, replacement_string)
|
||||
try:
|
||||
image_data = base64.decodebytes(i.text.encode())
|
||||
with open(image_path, 'wb') as outimage:
|
||||
|
@@ -163,7 +163,7 @@ class BookSorter:
|
||||
self.queue.put(filename)
|
||||
|
||||
# This should not get triggered in reading mode
|
||||
# IF the file is NOT being loaded into the reader,
|
||||
# IF the file is NOT being loaded into the reader
|
||||
|
||||
# Do not allow addition in case the file
|
||||
# is already in the database and it remains at its original path
|
||||
|
@@ -25,7 +25,6 @@ import uuid
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
|
||||
from lector.models import BookmarkProxyModel
|
||||
from lector.delegates import BookmarkDelegate
|
||||
from lector.sorter import resize_image
|
||||
from lector.contentwidgets import PliantQGraphicsView, PliantQTextBrowser
|
||||
|
||||
@@ -155,17 +154,14 @@ class Tab(QtWidgets.QWidget):
|
||||
self.bookmarkDock.setFeatures(QtWidgets.QDockWidget.DockWidgetClosable)
|
||||
self.bookmarkDock.hide()
|
||||
|
||||
self.bookmarkListView = QtWidgets.QListView(self.bookmarkDock)
|
||||
self.bookmarkListView.setResizeMode(QtWidgets.QListWidget.Adjust)
|
||||
self.bookmarkListView.setMaximumWidth(350)
|
||||
self.bookmarkListView.setItemDelegate(
|
||||
BookmarkDelegate(self.main_window, self.bookmarkListView))
|
||||
self.bookmarkListView.setUniformItemSizes(True)
|
||||
self.bookmarkListView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.bookmarkListView.customContextMenuRequested.connect(
|
||||
self.bookmarkTreeView = QtWidgets.QTreeView(self.bookmarkDock)
|
||||
self.bookmarkTreeView.setHeaderHidden(True)
|
||||
self.bookmarkTreeView.setMaximumWidth(350)
|
||||
self.bookmarkTreeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.bookmarkTreeView.customContextMenuRequested.connect(
|
||||
self.generate_bookmark_context_menu)
|
||||
self.bookmarkListView.clicked.connect(self.navigate_to_bookmark)
|
||||
self.bookmarkDock.setWidget(self.bookmarkListView)
|
||||
self.bookmarkTreeView.clicked.connect(self.navigate_to_bookmark)
|
||||
self.bookmarkDock.setWidget(self.bookmarkTreeView)
|
||||
|
||||
self.bookmarkModel = QtGui.QStandardItemModel(self)
|
||||
self.bookmarkProxyModel = BookmarkProxyModel(self)
|
||||
@@ -451,9 +447,6 @@ class Tab(QtWidgets.QWidget):
|
||||
self.bookmarkDock.show()
|
||||
|
||||
def add_bookmark(self):
|
||||
# TODO
|
||||
# Start dockListView.edit(index) when something new is added
|
||||
|
||||
identifier = uuid.uuid4().hex[:10]
|
||||
description = self._translate('Tab', 'New bookmark')
|
||||
|
||||
@@ -468,25 +461,55 @@ class Tab(QtWidgets.QWidget):
|
||||
'cursor_position': cursor_position,
|
||||
'description': description}
|
||||
|
||||
self.add_bookmark_to_model(
|
||||
description, chapter, cursor_position, identifier)
|
||||
self.bookmarkDock.setVisible(True)
|
||||
self.add_bookmark_to_model(
|
||||
description, chapter, cursor_position, identifier, True)
|
||||
|
||||
def add_bookmark_to_model(
|
||||
self, description, chapter, cursor_position,
|
||||
identifier, new_bookmark=False):
|
||||
|
||||
# TODO
|
||||
# Start treeview.edit(index) when a new bookmark is added
|
||||
# Expand parent item of newly added bookmark
|
||||
|
||||
def add_bookmark_to_model(self, description, chapter, cursor_position, identifier):
|
||||
bookmark = QtGui.QStandardItem()
|
||||
bookmark.setData(description, QtCore.Qt.DisplayRole)
|
||||
|
||||
bookmark.setData(chapter, QtCore.Qt.UserRole)
|
||||
bookmark.setData(cursor_position, QtCore.Qt.UserRole + 1)
|
||||
bookmark.setData(identifier, QtCore.Qt.UserRole + 2)
|
||||
bookmark.setData(False, QtCore.Qt.UserRole + 10) # Is Parent
|
||||
bookmark.setData(chapter, QtCore.Qt.UserRole) # Chapter name
|
||||
bookmark.setData(cursor_position, QtCore.Qt.UserRole + 1) # Cursor Position
|
||||
bookmark.setData(identifier, QtCore.Qt.UserRole + 2) # Identifier
|
||||
bookmark.setData(description, QtCore.Qt.DisplayRole) # Description
|
||||
|
||||
self.bookmarkModel.appendRow(bookmark)
|
||||
self.update_bookmark_proxy_model()
|
||||
for i in range(self.bookmarkModel.rowCount()):
|
||||
parentIndex = self.bookmarkModel.index(i, 0)
|
||||
parent_chapter = parentIndex.data(QtCore.Qt.UserRole)
|
||||
if parent_chapter == chapter:
|
||||
parentItem = self.bookmarkModel.itemFromIndex(parentIndex)
|
||||
parentItem.appendRow(bookmark)
|
||||
return
|
||||
|
||||
# In case no parent item exists
|
||||
bookmarkParent = QtGui.QStandardItem()
|
||||
bookmarkParent.setData(True, QtCore.Qt.UserRole + 10) # Is Parent
|
||||
bookmarkParent.setFlags(bookmarkParent.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||
chapter_name = self.metadata['content'][chapter - 1][0]
|
||||
bookmarkParent.setData(chapter_name, QtCore.Qt.DisplayRole)
|
||||
bookmarkParent.setData(chapter, QtCore.Qt.UserRole)
|
||||
|
||||
bookmarkParent.appendRow(bookmark)
|
||||
self.bookmarkModel.appendRow(bookmarkParent)
|
||||
# self.update_bookmark_proxy_model()
|
||||
|
||||
def navigate_to_bookmark(self, index):
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
is_parent = self.bookmarkProxyModel.data(
|
||||
index, QtCore.Qt.UserRole + 10)
|
||||
if is_parent:
|
||||
return
|
||||
|
||||
chapter = self.bookmarkProxyModel.data(index, QtCore.Qt.UserRole)
|
||||
cursor_position = self.bookmarkProxyModel.data(index, QtCore.Qt.UserRole + 1)
|
||||
|
||||
@@ -495,23 +518,14 @@ class Tab(QtWidgets.QWidget):
|
||||
self.set_cursor_position(cursor_position)
|
||||
|
||||
def generate_bookmark_model(self):
|
||||
# TODO
|
||||
# Sorting is not working correctly
|
||||
|
||||
try:
|
||||
for i in self.metadata['bookmarks'].items():
|
||||
self.add_bookmark_to_model(
|
||||
i[1]['description'],
|
||||
i[1]['chapter'],
|
||||
i[1]['cursor_position'],
|
||||
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.bookmarkModel = QtGui.QStandardItemModel(self)
|
||||
for i in self.metadata['bookmarks'].items():
|
||||
description = i[1]['description']
|
||||
chapter = i[1]['chapter']
|
||||
cursor_position = i[1]['cursor_position']
|
||||
identifier = i[0]
|
||||
self.add_bookmark_to_model(
|
||||
description, chapter, cursor_position, identifier)
|
||||
|
||||
self.generate_bookmark_proxy_model()
|
||||
|
||||
@@ -519,9 +533,14 @@ class Tab(QtWidgets.QWidget):
|
||||
self.bookmarkProxyModel.setSourceModel(self.bookmarkModel)
|
||||
self.bookmarkProxyModel.setSortCaseSensitivity(False)
|
||||
self.bookmarkProxyModel.setSortRole(QtCore.Qt.UserRole)
|
||||
self.bookmarkListView.setModel(self.bookmarkProxyModel)
|
||||
self.bookmarkProxyModel.sort(0)
|
||||
self.bookmarkTreeView.setModel(self.bookmarkProxyModel)
|
||||
|
||||
def update_bookmark_proxy_model(self):
|
||||
# TODO
|
||||
# This isn't being called currently
|
||||
# See if there's any rationale for keeping it / removing it
|
||||
|
||||
self.bookmarkProxyModel.invalidateFilter()
|
||||
self.bookmarkProxyModel.setFilterParams(
|
||||
self.main_window.bookToolBar.searchBar.text())
|
||||
@@ -529,10 +548,15 @@ class Tab(QtWidgets.QWidget):
|
||||
self.main_window.bookToolBar.searchBar.text())
|
||||
|
||||
def generate_bookmark_context_menu(self, position):
|
||||
index = self.bookmarkListView.indexAt(position)
|
||||
index = self.bookmarkTreeView.indexAt(position)
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
is_parent = self.bookmarkProxyModel.data(
|
||||
index, QtCore.Qt.UserRole + 10)
|
||||
if is_parent:
|
||||
return
|
||||
|
||||
bookmarkMenu = QtWidgets.QMenu()
|
||||
editAction = bookmarkMenu.addAction(
|
||||
self.main_window.QImageFactory.get_image('edit-rename'),
|
||||
@@ -542,17 +566,21 @@ class Tab(QtWidgets.QWidget):
|
||||
self._translate('Tab', 'Delete'))
|
||||
|
||||
action = bookmarkMenu.exec_(
|
||||
self.bookmarkListView.mapToGlobal(position))
|
||||
self.bookmarkTreeView.mapToGlobal(position))
|
||||
|
||||
if action == editAction:
|
||||
self.bookmarkListView.edit(index)
|
||||
self.bookmarkTreeView.edit(index)
|
||||
|
||||
if action == deleteAction:
|
||||
row = index.row()
|
||||
delete_uuid = self.bookmarkModel.item(row).data(QtCore.Qt.UserRole + 2)
|
||||
# TODO
|
||||
# Deletion that doesn't need to generate the whole model again
|
||||
|
||||
source_index = self.bookmarkProxyModel.mapToSource(index)
|
||||
delete_uuid = self.bookmarkModel.data(
|
||||
source_index, QtCore.Qt.UserRole + 2)
|
||||
|
||||
self.metadata['bookmarks'].pop(delete_uuid)
|
||||
self.bookmarkModel.removeRow(index.row())
|
||||
self.generate_bookmark_model()
|
||||
|
||||
def hide_mouse(self):
|
||||
self.contentView.viewport().setCursor(QtCore.Qt.BlankCursor)
|
||||
|
Reference in New Issue
Block a user