Position setting should work all the time now

Learn not to swear so much at the screen
Cover icons in the tab bar
Shift Scan Library button from the Library tab to the Library toolbar
This commit is contained in:
BasioMeusPuga
2018-03-29 01:45:58 +05:30
parent ab6760226e
commit 406ca0485f
6 changed files with 69 additions and 61 deletions

5
TODO
View File

@@ -58,6 +58,8 @@ TODO
✓ Comic view keyboard shortcuts
✓ Comic view context menu
✓ Make the bookmark dock float over the reading area
✓ Spacebar should not cut off lines at the top
Track open bookmark windows so they can be closed quickly at exit
Adjust key navigation according to viewport dimensions
Search document using QTextCursor
Filetypes:
@@ -74,6 +76,8 @@ TODO
✓ Define every widget in code
Bugs:
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
It's the one that has focus when application starts and ends
Secondary:
Annotations
@@ -86,7 +90,6 @@ TODO
Pagination
Use embedded fonts + CSS
Scrolling: Smooth / By Line
Spacebar should not cut off lines at the top
Shift to logging instead of print statements
txt, doc, chm, djvu, fb2 support
Include icons for filetype emblems

View File

@@ -155,6 +155,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.libraryToolBar.deleteButton.triggered.connect(self.delete_books)
self.libraryToolBar.coverViewButton.triggered.connect(self.switch_library_view)
self.libraryToolBar.tableViewButton.triggered.connect(self.switch_library_view)
self.libraryToolBar.reloadLibraryButton.triggered.connect(
self.settingsDialog.start_library_scan)
self.libraryToolBar.colorButton.triggered.connect(self.get_color)
self.libraryToolBar.settingsButton.triggered.connect(self.show_settings)
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodels)
@@ -218,16 +220,11 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.available_parsers = '*.' + ' *.'.join(sorter.available_parsers)
print('Available parsers: ' + self.available_parsers)
# The library refresh button on the Library tab
self.reloadLibrary.setFlat(True)
self.reloadLibrary.setIcon(self.QImageFactory.get_image('reload'))
self.reloadLibrary.setObjectName('reloadLibrary')
self.reloadLibrary.setToolTip(self._translate('Main_UI', 'Scan library'))
self.reloadLibrary.clicked.connect(self.settingsDialog.start_library_scan)
# The Library tab gets no button
self.tabWidget.tabBar().setTabButton(
0, QtWidgets.QTabBar.RightSide, self.reloadLibrary)
0, QtWidgets.QTabBar.RightSide, None)
self.tabWidget.tabCloseRequested.connect(self.tab_close)
self.tabWidget.setTabBarAutoHide(True)
# Init display models
self.lib_ref.generate_model('build')
@@ -556,7 +553,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.bookToolBar.tocBox.setCurrentIndex(
current_position['current_chapter'] - 1)
if not current_metadata['images_only']:
current_tab.set_scroll_value(True)
current_tab.set_cursor_position()
self.bookToolBar.tocBox.blockSignals(False)
self.profile_functions.format_contentView()

View File

@@ -42,7 +42,8 @@ class DatabaseInit:
'LastAccessed': 'BLOB',
'Bookmarks': 'BLOB',
'CoverImage': 'BLOB',
'Addition': 'TEXT'}
'Addition': 'TEXT',
'Annotations': 'BLOB'}
self.directories_table_columns = {
'id': 'INTEGER PRIMARY KEY',
@@ -82,7 +83,7 @@ class DatabaseInit:
for i in self.books_table_columns.items():
if i[0] not in database_columns:
commit_required = True
print(f'Database: Adding column {i[0]}')
print(f'Database: Adding column "{i[0]}"')
sql_command = f"ALTER TABLE books ADD COLUMN {i[0]} {i[1]}"
self.database.execute(sql_command)

View File

@@ -118,7 +118,7 @@ class BookSorter:
def database_entry_for_book(self, file_hash):
database_return = database.DatabaseFunctions(
self.database_path).fetch_data(
('Title', 'Author', 'Year', 'ISBN', 'Tags', 'Position', 'Bookmarks'),
('Title', 'Author', 'Year', 'ISBN', 'Tags', 'Position', 'Bookmarks', 'CoverImage'),
'books',
{'Hash': file_hash},
'EQUALS')[0]
@@ -231,11 +231,13 @@ class BookSorter:
tags = book_data[4]
position = book_data[5]
bookmarks = book_data[6]
cover = book_data[7]
this_book[file_md5]['position'] = position
this_book[file_md5]['bookmarks'] = bookmarks
this_book[file_md5]['content'] = content
this_book[file_md5]['images_only'] = images_only
this_book[file_md5]['cover'] = cover
this_book[file_md5]['title'] = title
this_book[file_md5]['author'] = author

View File

@@ -376,6 +376,11 @@ class LibraryToolBar(QtWidgets.QToolBar):
self)
self.tableViewButton.setCheckable(True)
self.reloadLibraryButton = QtWidgets.QAction(
image_factory.get_image('reload'),
self._translate('LibraryToolBar', 'Scan Library'),
self)
self.libraryFilterButton = QtWidgets.QToolButton(self)
self.libraryFilterButton.setIcon(image_factory.get_image('view-readermode'))
self.libraryFilterButton.setText(
@@ -396,6 +401,7 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.addAction(self.coverViewButton)
self.addAction(self.tableViewButton)
self.addSeparator()
self.addAction(self.reloadLibraryButton)
self.addWidget(self.libraryFilterButton)
self.addSeparator()
self.addAction(self.colorButton)

View File

@@ -105,7 +105,7 @@ class Tab(QtWidgets.QWidget):
self.hiddenButton = QtWidgets.QToolButton(self)
self.hiddenButton.setVisible(False)
self.hiddenButton.clicked.connect(self.set_scroll_value)
self.hiddenButton.clicked.connect(self.set_cursor_position)
self.hiddenButton.animateClick(50)
# The following are common to both the text browser and
@@ -135,7 +135,8 @@ class Tab(QtWidgets.QWidget):
self.dockListView = QtWidgets.QListView(self.dockWidget)
self.dockListView.setResizeMode(QtWidgets.QListWidget.Adjust)
self.dockListView.setMaximumWidth(350)
self.dockListView.setItemDelegate(BookmarkDelegate(self.main_window, self.dockListView))
self.dockListView.setItemDelegate(
BookmarkDelegate(self.main_window, self.dockListView))
self.dockListView.setUniformItemSizes(True)
self.dockListView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.dockListView.customContextMenuRequested.connect(
@@ -157,6 +158,14 @@ class Tab(QtWidgets.QWidget):
title = self.metadata['title']
self.main_window.tabWidget.addTab(self, title)
# TODO
# Show cover image as tooltip text
this_tab_index = self.main_window.tabWidget.indexOf(self)
cover_icon = QtGui.QPixmap()
cover_icon.loadFromData(self.metadata['cover'])
self.main_window.tabWidget.setTabIcon(
this_tab_index, QtGui.QIcon(cover_icon))
# Hide mouse cursor timer
self.mouse_hide_timer = QtCore.QTimer()
self.mouse_hide_timer.setSingleShot(True)
@@ -180,38 +189,38 @@ class Tab(QtWidgets.QWidget):
except IndexError: # The file has been deleted
pass
def set_scroll_value(self, switch_widgets=True, search_data=None):
if self.sender().objectName() == 'tabWidget' and self.first_run:
return
self.first_run = False
# ^^^ I have NO IDEA why this is needed or how it works
# but scroll positioning does NOT work without the return
# Enabling it somehow makes document formatting not work either
def set_cursor_position(self, switch_widgets=True, search_data=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:
search_text = self.metadata['position']['last_visible_text']
required_position = self.metadata['position']['cursor_position']
if search_data:
search_text = search_data[1]
required_position = search_data[1]
# textCursor() RETURNS a copy of the textcursor
cursor = self.contentView.textCursor()
cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.KeepAnchor)
self.contentView.setTextCursor(cursor)
# 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
# This is needed so that search results are always at the top
# of the window
# This is needed so that the line we want is
# always at the top of the window
self.contentView.verticalScrollBar().setValue(
self.contentView.verticalScrollBar().maximum())
# find_forward is a new cursor object that must replace
# the existing text cursor
find_forward = self.contentView.document().find(search_text)
find_forward.clearSelection()
self.contentView.setTextCursor(find_forward)
# textCursor() RETURNS a copy of the textcursor
cursor = self.contentView.textCursor()
cursor.setPosition(
required_position, QtGui.QTextCursor.MoveAnchor)
self.contentView.setTextCursor(cursor)
self.contentView.ensureCursorVisible()
except KeyError:
@@ -254,8 +263,8 @@ class Tab(QtWidgets.QWidget):
'blocks_per_chapter': blocks_per_chapter,
'total_blocks': total_blocks,
'scroll_value': scroll_value,
'last_visible_text': None,
'is_read': is_read}
'is_read': is_read,
'cursor_position': 0}
def generate_keyboard_shortcuts(self):
self.ksNextChapter = QtWidgets.QShortcut(
@@ -323,6 +332,8 @@ class Tab(QtWidgets.QWidget):
if not self.main_window.settings['show_bars']:
self.main_window.toggle_distraction_free()
self.contentView.setFocus()
def change_chapter_tocBox(self):
chapter_number = self.main_window.bookToolBar.tocBox.currentIndex()
required_content = self.metadata['content'][chapter_number][1]
@@ -440,7 +451,7 @@ class Tab(QtWidgets.QWidget):
self.main_window.bookToolBar.tocBox.setCurrentIndex(chapter - 1)
if not self.are_we_doing_images_only:
self.set_scroll_value(False, search_data)
self.set_cursor_position(False, search_data)
def generate_bookmark_model(self):
# TODO
@@ -811,7 +822,8 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
self.setMouseTracking(True)
self.viewport().setCursor(QtCore.Qt.IBeamCursor)
self.verticalScrollBar().sliderMoved.connect(self.record_scroll_position)
self.verticalScrollBar().sliderMoved.connect(
self.record_scroll_position)
self.ignore_wheel_event = False
self.ignore_wheel_event_number = 0
@@ -828,19 +840,12 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
self.set_top_line_cleanly()
def set_top_line_cleanly(self):
# TODO
# This can't find the next line sometimes despite having
# a valid search text to look up
# It could have something to do with textCursor position
self.record_scroll_position()
search_text = self.parent.metadata['position']['last_visible_text']
new_cursor = self.document().find(search_text)
if not new_cursor.isNull():
new_cursor.clearSelection()
self.setTextCursor(new_cursor)
self.ensureCursorVisible()
# Find the cursor position of the top line and move to it
find_cursor = self.cursorForPosition(QtCore.QPoint(0, 0))
find_cursor.movePosition(
find_cursor.position(), QtGui.QTextCursor.KeepAnchor)
self.setTextCursor(find_cursor)
self.ensureCursorVisible()
def record_scroll_position(self, return_as_bookmark=False):
self.parent.metadata['position']['is_read'] = False
@@ -853,20 +858,14 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
self.parent.metadata['position']['scroll_value'] = (vertical / maximum)
cursor = self.cursorForPosition(QtCore.QPoint(0, 0))
bottom_right = QtCore.QPoint(self.viewport().width() - 1, self.viewport().height())
bottom_right_cursor = self.cursorForPosition(bottom_right).position()
cursor.setPosition(bottom_right_cursor, QtGui.QTextCursor.KeepAnchor)
visible_text = cursor.selectedText()
if len(visible_text) > 50:
visible_text = visible_text[:51]
cursor_position = cursor.position()
if return_as_bookmark:
return (self.parent.metadata['position']['current_chapter'],
self.parent.metadata['position']['scroll_value'],
visible_text)
cursor_position)
else:
self.parent.metadata['position']['last_visible_text'] = visible_text
self.parent.metadata['position']['cursor_position'] = cursor_position
def generate_textbrowser_context_menu(self, position):
selected_word = self.textCursor().selection()