Implement sorting by last read

This commit is contained in:
BasioMeusPuga
2018-02-21 01:05:15 +05:30
parent a65bd054be
commit 0b64fc3e8d
7 changed files with 67 additions and 29 deletions

1
TODO
View File

@@ -45,6 +45,7 @@ TODO
✓ Record progress
Search document using QTextCursor?
Use embedded fonts
Cache multiple images
Graphical themes
Comic view keyboard shortcuts
Comic view modes

View File

@@ -16,9 +16,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# TODO
# Consider using sender().text() instead of sender().objectName()
import os
import sys
import hashlib
@@ -159,6 +156,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.addToolBar(self.bookToolBar)
# Make the correct toolbar visible
self.current_tab = self.tabWidget.currentIndex()
self.tab_switch()
self.tabWidget.currentChanged.connect(self.tab_switch)
@@ -481,6 +479,15 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.resizeEvent()
def tab_switch(self):
try:
if self.current_tab != 0:
self.tabWidget.widget(
self.current_tab).update_last_accessed_time()
except AttributeError:
pass
self.current_tab = self.tabWidget.currentIndex()
if self.tabWidget.currentIndex() == 0:
self.resizeEvent()
@@ -539,6 +546,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.database_path, [tab_metadata])
self.thread.start()
self.tabWidget.widget(tab_index).update_last_accessed_time()
self.tabWidget.removeTab(tab_index)
def set_toc_position(self, event=None):
@@ -892,7 +900,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
checked = [i for i in directory_list if i[3] == QtCore.Qt.Checked]
filter_list = list(map(generate_name, checked))
filter_list.sort()
filter_list.append('Manually added')
filter_list.append('Manually Added')
filter_actions = [QtWidgets.QAction(i, self.library_filter_menu) for i in filter_list]
filter_all = QtWidgets.QAction('All', self.library_filter_menu)

View File

@@ -38,8 +38,8 @@ class DatabaseInit:
# addition mode
self.database.execute(
"CREATE TABLE books \
(id INTEGER PRIMARY KEY, Title TEXT, Author TEXT, Year INTEGER, DateAdded TEXT, \
Path TEXT, Position BLOB, ISBN TEXT, Tags TEXT, Hash TEXT, \
(id INTEGER PRIMARY KEY, Title TEXT, Author TEXT, Year INTEGER, DateAdded BLOB, \
Path TEXT, Position BLOB, ISBN TEXT, Tags TEXT, Hash TEXT, LastAccessed BLOB,\
Bookmarks BLOB, CoverImage BLOB)")
# CheckState is the standard QtCore.Qt.Checked / Unchecked
@@ -167,18 +167,22 @@ class DatabaseFunctions:
self.close_database()
def modify_position(self, hash_position_pairs):
for i in hash_position_pairs:
def modify_position(self, hash_position_last_accessed):
for i in hash_position_last_accessed:
file_hash = i[0]
position = i[1]
last_accessed = i[2]
pickled_position = pickle.dumps(position)
position_bin = sqlite3.Binary(pickle.dumps(position))
last_accessed_bin = sqlite3.Binary(pickle.dumps(last_accessed))
sql_command = (
"UPDATE books SET Position = ?, LastAccessed = ? WHERE Hash = ?")
sql_command = "UPDATE books SET Position = ? WHERE Hash = ?"
try:
self.database.execute(
sql_command,
[sqlite3.Binary(pickled_position), file_hash])
[position_bin, last_accessed_bin, file_hash])
except sqlite3.OperationalError:
print('SQLite is in rebellion, Commander')
return

View File

@@ -42,7 +42,7 @@ class Library:
books = database.DatabaseFunctions(
self.parent.database_path).fetch_data(
('Title', 'Author', 'Year', 'DateAdded', 'Path',
'Position', 'ISBN', 'Tags', 'Hash',),
'Position', 'ISBN', 'Tags', 'Hash', 'LastAccessed'),
'books',
{'Title': ''},
'LIKE')
@@ -65,7 +65,7 @@ class Library:
books.append([
i[1]['title'], i[1]['author'], i[1]['year'], current_qdatetime,
i[1]['path'], None, i[1]['isbn'], _tags, i[0]])
i[1]['path'], None, i[1]['isbn'], _tags, i[0], None])
else:
return
@@ -73,12 +73,12 @@ class Library:
for i in books:
# The database query returns (or the extension data is)
# an iterable with the following indices:
# Index 0 is the key ID is ignored
title = i[0]
author = i[1]
year = i[2]
path = i[4]
tags = i[7]
last_accessed = i[9]
try:
date_added = pickle.loads(i[3])
@@ -101,6 +101,7 @@ class Library:
'isbn': i[6],
'tags': tags,
'hash': i[8],
'last_accessed': last_accessed,
'file_exists': file_exists}
tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)
@@ -129,6 +130,7 @@ class Library:
item.setData(position, QtCore.Qt.UserRole + 7)
item.setData(False, QtCore.Qt.UserRole + 8) # Is the cover being displayed?
item.setData(date_added, QtCore.Qt.UserRole + 9)
item.setData(last_accessed, QtCore.Qt.UserRole + 12)
item.setIcon(QtGui.QIcon(img_pixmap))
self.view_model.appendRow(item)
@@ -182,7 +184,8 @@ class Library:
self.proxy_model.invalidateFilter()
self.proxy_model.setFilterParams(
self.parent.libraryToolBar.searchBar.text(),
self.parent.active_library_filters)
self.parent.active_library_filters,
self.parent.libraryToolBar.sortingBox.currentIndex())
self.proxy_model.setFilterFixedString(
self.parent.libraryToolBar.searchBar.text())
@@ -200,7 +203,8 @@ class Library:
0: 0,
1: 1,
2: 2,
3: 9}
3: 9,
4: 12}
# Sorting according to roles and the drop down in the library toolbar
self.proxy_model.setSortRole(
@@ -208,7 +212,7 @@ class Library:
# This can be expanded to other fields by appending to the list
sort_order = QtCore.Qt.AscendingOrder
if self.parent.libraryToolBar.sortingBox.currentIndex() in [3]:
if self.parent.libraryToolBar.sortingBox.currentIndex() in [3, 4]:
sort_order = QtCore.Qt.DescendingOrder
self.proxy_model.sort(0, sort_order)

View File

@@ -27,10 +27,12 @@ class ItemProxyModel(QtCore.QSortFilterProxyModel):
super(ItemProxyModel, self).__init__(parent)
self.filter_text = None
self.active_library_filters = None
self.sorting_position = None
def setFilterParams(self, filter_text, active_library_filters):
def setFilterParams(self, filter_text, active_library_filters, sorting_position):
self.filter_text = filter_text
self.active_library_filters = [i.lower() for i in active_library_filters]
self.sorting_position = sorting_position
def filterAcceptsRow(self, row, parent):
model = self.sourceModel()
@@ -42,6 +44,10 @@ class ItemProxyModel(QtCore.QSortFilterProxyModel):
tags = model.data(this_index, QtCore.Qt.UserRole + 4)
directory_name = model.data(this_index, QtCore.Qt.UserRole + 10)
directory_tags = model.data(this_index, QtCore.Qt.UserRole + 11)
last_accessed = model.data(this_index, QtCore.Qt.UserRole + 12)
if self.sorting_position == 4 and not last_accessed:
return False
if self.active_library_filters:
if directory_name not in self.active_library_filters:

View File

@@ -36,7 +36,9 @@ class BackGroundTabUpdate(QtCore.QThread):
for i in self.all_metadata:
file_hash = i['hash']
position = i['position']
hash_position_pairs.append([file_hash, position])
last_accessed = i['last_accessed']
hash_position_pairs.append([file_hash, position, last_accessed])
database.DatabaseFunctions(
self.database_path).modify_position(hash_position_pairs)

View File

@@ -333,7 +333,7 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.searchBar.setObjectName('searchBar')
# Sorter
sorting_choices = ['Title', 'Author', 'Year', 'Newest']
sorting_choices = ['Title', 'Author', 'Year', 'Newest', 'Last read']
self.sortingBox = FixedComboBox(self)
self.sortingBox.addItems(sorting_choices)
self.sortingBox.setObjectName('sortingBox')
@@ -374,10 +374,6 @@ class FixedPushButton(QtWidgets.QPushButton):
class Tab(QtWidgets.QWidget):
def __init__(self, metadata, parent=None):
# TODO
# Take hint from a position function argument to open the book
# at a specific page
super(Tab, self).__init__(parent)
self.parent = parent
self.metadata = metadata # Save progress data into this dictionary
@@ -387,10 +383,10 @@ class Tab(QtWidgets.QWidget):
self.horzLayout.setOrientation(QtCore.Qt.Horizontal)
self.masterLayout.addWidget(self.horzLayout)
self.metadata['last_accessed'] = QtCore.QDateTime().currentDateTime()
position = self.metadata['position']
# TODO
# Chapter position and vertical scrollbar position
if position:
current_chapter = position['current_chapter']
else:
@@ -461,6 +457,19 @@ class Tab(QtWidgets.QWidget):
self.contentView.setFocus()
def update_last_accessed_time(self):
self.metadata['last_accessed'] = QtCore.QDateTime().currentDateTime()
start_index = self.window().lib_ref.view_model.index(0, 0)
matching_item = self.window().lib_ref.view_model.match(
start_index,
QtCore.Qt.UserRole + 6,
self.metadata['hash'],
1, QtCore.Qt.MatchExactly)
self.window().lib_ref.view_model.setData(
matching_item[0], self.metadata['last_accessed'], QtCore.Qt.UserRole + 12)
def set_scroll_value(self, switch_widgets=True):
if switch_widgets:
previous_widget = self.window().tabWidget.currentWidget()
@@ -489,7 +498,7 @@ class Tab(QtWidgets.QWidget):
def generate_position(self):
total_chapters = len(self.metadata['content'].keys())
# TODO
# Calculate lines
# Calculate lines to incorporate into progress
self.metadata['position'] = {
'current_chapter': 1,
'current_line': 0,
@@ -754,9 +763,13 @@ class PliantWidgetsCommonFunctions():
self.main_window = main_window
def wheelEvent(self, event, are_we_doing_images_only):
ignore_events = 20
if are_we_doing_images_only:
ignore_events = 10
if self.pw.ignore_wheel_event:
self.pw.ignore_wheel_event_number += 1
if self.pw.ignore_wheel_event_number > 20:
if self.pw.ignore_wheel_event_number > ignore_events:
self.pw.ignore_wheel_event = False
self.pw.ignore_wheel_event_number = 0
return