Fine tune progress display

Option: Set consider read at percentage
Small fixes
This commit is contained in:
BasioMeusPuga
2018-03-31 10:31:57 +05:30
parent aff69d95c1
commit 5081a31f1a
13 changed files with 175 additions and 134 deletions

1
TODO
View File

@@ -79,7 +79,6 @@ TODO
✓ Define every widget in code
Bugs:
Deselecting all directories in the settings dialog also filters out manually added books
PDF year
Secondary:
Graphical themes

View File

@@ -262,8 +262,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
if self.settings['main_window_headers']:
for count, i in enumerate(self.settings['main_window_headers']):
self.tableView.horizontalHeader().resizeSection(count, int(i))
self.tableView.horizontalHeader().resizeSection(5, 1)
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().resizeSection(5, 30)
self.tableView.horizontalHeader().setStretchLastSection(False)
self.tableView.horizontalHeader().sectionClicked.connect(
self.lib_ref.table_proxy_model.sort_table_columns)
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
@@ -822,7 +822,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
last_accessed_time = None
if action == readAction:
last_accessed_time = QtCore.QDateTime().currentDateTime()
position_perc = 100
position_perc = 1
self.lib_ref.view_model.setData(i, metadata, QtCore.Qt.UserRole + 3)
self.lib_ref.view_model.setData(i, position_perc, QtCore.Qt.UserRole + 7)
@@ -916,8 +916,11 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.settingsDialog.hide()
self.definitionDialog.hide()
self.temp_dir.remove()
for i in self.active_bookmark_docks:
i.setVisible(False)
for this_dock in self.active_bookmark_docks:
try:
this_dock.setVisible(False)
except RuntimeError:
pass
self.settings['last_open_books'] = []
if self.tabWidget.count() > 1:

View File

@@ -33,13 +33,8 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate):
# painter.fillRect(option.rect, QtGui.QColor().fromRgb(255, 0, 0, 20))
option = option.__class__(option)
title = index.data(QtCore.Qt.UserRole)
file_exists = index.data(QtCore.Qt.UserRole + 5)
metadata = index.data(QtCore.Qt.UserRole + 3)
position = metadata['position']
if position:
is_read = position['is_read']
position_percent = index.data(QtCore.Qt.UserRole + 7)
# The shadow pixmap currently is set to 420 x 600
# Only draw the cover shadow in case the setting is enabled
@@ -64,26 +59,10 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate):
return
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
if position:
if is_read:
progress = total = -1
else:
try:
progress = position['current_block']
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:
return
if position_percent:
read_icon = pie_chart.pixmapper(
progress, total, self.temp_dir, 36)
position_percent, self.temp_dir, self.parent.settings['consider_read_at'], 36)
x_draw = option.rect.bottomRight().x() - 30
y_draw = option.rect.bottomRight().y() - 35

View File

@@ -101,18 +101,22 @@ class Library:
if position:
position = pickle.loads(position)
if position['is_read']:
position_perc = 100
position_perc = 1
else:
try:
position_perc = (
position['current_chapter'] * 100 / position['total_chapters'])
except KeyError:
position_perc = None
position['current_block'] / position['total_blocks'])
except (KeyError, ZeroDivisionError):
try:
position_perc = (
position['current_chapter'] / position['total_chapters'])
except KeyError:
position_perc = None
try:
file_exists = os.path.exists(path)
except UnicodeEncodeError:
print('Error with unicode encoding in the library module')
print('Library: Unicode encoding error')
all_metadata = {
'title': title,
@@ -176,7 +180,9 @@ class Library:
self.parent.listView.setModel(self.item_proxy_model)
self.table_proxy_model = TableProxyModel(
self.parent.temp_dir.path(), self.parent.tableView.horizontalHeader())
self.parent.temp_dir.path(),
self.parent.tableView.horizontalHeader(),
self.parent.settings['consider_read_at'])
self.table_proxy_model.setSourceModel(self.view_model)
self.table_proxy_model.setSortCaseSensitivity(False)
self.parent.tableView.setModel(self.table_proxy_model)
@@ -223,7 +229,8 @@ class Library:
1: 1,
2: 2,
3: 9,
4: 12}
4: 12,
5: 7}
# Sorting according to roles and the drop down in the library toolbar
self.item_proxy_model.setSortRole(
@@ -231,7 +238,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, 4]:
if self.parent.libraryToolBar.sortingBox.currentIndex() in [3, 4, 5]:
sort_order = QtCore.Qt.DescendingOrder
self.item_proxy_model.sort(0, sort_order)

View File

@@ -65,9 +65,10 @@ class ItemProxyModel(QtCore.QSortFilterProxyModel):
class TableProxyModel(QtCore.QSortFilterProxyModel):
def __init__(self, temp_dir, tableViewHeader, parent=None):
def __init__(self, temp_dir, tableViewHeader, consider_read_at, parent=None):
super(TableProxyModel, self).__init__(parent)
self.tableViewHeader = tableViewHeader
self.consider_read_at = consider_read_at
self._translate = QtCore.QCoreApplication.translate
title_string = self._translate('TableProxyModel', 'Title')
@@ -101,6 +102,7 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
return self.header_data[column]
except IndexError:
print('Table proxy model: Can\'t find header for column', column)
# The column will be called IndexError. Not a typo.
return 'IndexError'
def flags(self, index):
@@ -121,36 +123,16 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
return_pixmap = None
file_exists = item.data(QtCore.Qt.UserRole + 5)
metadata = item.data(QtCore.Qt.UserRole + 3)
progress_perc = item.data(QtCore.Qt.UserRole + 7)
position = metadata['position']
if position:
is_read = position['is_read']
position_percent = item.data(QtCore.Qt.UserRole + 7)
if not file_exists:
return pie_chart.pixmapper(
-1, None, None, QtCore.Qt.SizeHintRole + 10)
if position:
if is_read:
progress = total = -2
else:
try:
progress = position['current_block']
total = position['total_blocks']
if progress == total == 0:
raise KeyError
except KeyError:
try:
progress = position['current_chapter']
total = position['total_chapters']
except KeyError:
return
if position_percent:
return_pixmap = pie_chart.pixmapper(
progress, total, self.temp_dir,
position_percent, self.temp_dir,
self.consider_read_at,
QtCore.Qt.SizeHintRole + 10)
return return_pixmap
@@ -218,6 +200,7 @@ class ProxyModelsCommonFunctions:
title = model.data(this_index, QtCore.Qt.UserRole)
author = model.data(this_index, QtCore.Qt.UserRole + 1)
tags = model.data(this_index, QtCore.Qt.UserRole + 4)
progress = model.data(this_index, QtCore.Qt.UserRole + 7)
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)
@@ -226,6 +209,10 @@ class ProxyModelsCommonFunctions:
if self.parent_model.sorting_box_position == 4 and not last_accessed:
return False
# Hide untouched files when sorting by progress
if self.parent_model.sorting_box_position == 5 and not progress:
return False
if self.parent_model.active_library_filters:
if directory_name not in self.parent_model.active_library_filters:
return False

View File

@@ -94,16 +94,18 @@ def generate_pie(progress_percent, temp_dir=None):
return lSvg
def pixmapper(progress, total, temp_dir, size):
def pixmapper(position_percent, temp_dir, consider_read_at, size):
# A current_chapter of -1 implies the files does not exist
# A chapter number == Total chapters implies the file is unread
return_pixmap = None
# position_percent and consider_read_at are expected as a <1 decimal value
if progress == -1:
return_pixmap = None
consider_read_at = consider_read_at / 100
if position_percent == -1:
return_pixmap = QtGui.QIcon(':/images/error.svg').pixmap(size)
return return_pixmap
if progress >= .95 * total: # Consider book read @ 95% progress
if position_percent >= consider_read_at: # Consider book read @ 95% progress
return_pixmap = QtGui.QIcon(':/images/checkmark.svg').pixmap(size)
else:
@@ -111,8 +113,7 @@ def pixmapper(progress, total, temp_dir, size):
# See if saving the svg to disk can be avoided
# Maybe make the alignment a little more uniform across emblems
progress_percent = int(progress * 100 / total)
generate_pie(progress_percent, temp_dir)
generate_pie(int(position_percent * 100), temp_dir)
svg_path = os.path.join(temp_dir, 'lector_progress.svg')
return_pixmap = QtGui.QIcon(svg_path).pixmap(size - 4) ## The -4 looks more proportional

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1088</width>
<width>1119</width>
<height>612</height>
</rect>
</property>
@@ -47,6 +47,74 @@
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="readAtLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Consider book read at percent</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="readAtPercent">
<property name="minimum">
<number>90</number>
</property>
<property name="value">
<number>95</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>Icon theme: </string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="darkIconsRadio">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>&amp;Dark</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="lightIconsRadio">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>L&amp;ight</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
@@ -88,40 +156,6 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>Icon theme: </string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="darkIconsRadio">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>&amp;Dark</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="lightIconsRadio">
<property name="toolTip">
<string>Restart application to see changes</string>
</property>
<property name="text">
<string>L&amp;ight</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="autoTags">
<property name="text">

View File

@@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(1088, 612)
Dialog.resize(1119, 612)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.gridLayout.setObjectName("gridLayout")
self.listView = QtWidgets.QListView(Dialog)
@@ -46,6 +46,38 @@ class Ui_Dialog(object):
self.gridLayout_4.setObjectName("gridLayout_4")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
self.horizontalLayout_13.setObjectName("horizontalLayout_13")
self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
self.horizontalLayout_14.setObjectName("horizontalLayout_14")
self.readAtLabel = QtWidgets.QLabel(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.readAtLabel.sizePolicy().hasHeightForWidth())
self.readAtLabel.setSizePolicy(sizePolicy)
self.readAtLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.readAtLabel.setObjectName("readAtLabel")
self.horizontalLayout_14.addWidget(self.readAtLabel)
self.readAtPercent = QtWidgets.QSpinBox(self.groupBox)
self.readAtPercent.setMinimum(90)
self.readAtPercent.setProperty("value", 95)
self.readAtPercent.setObjectName("readAtPercent")
self.horizontalLayout_14.addWidget(self.readAtPercent)
self.horizontalLayout_13.addLayout(self.horizontalLayout_14)
self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
self.label = QtWidgets.QLabel(self.groupBox)
self.label.setObjectName("label")
self.horizontalLayout_7.addWidget(self.label)
self.darkIconsRadio = QtWidgets.QRadioButton(self.groupBox)
self.darkIconsRadio.setObjectName("darkIconsRadio")
self.horizontalLayout_7.addWidget(self.darkIconsRadio)
self.lightIconsRadio = QtWidgets.QRadioButton(self.groupBox)
self.lightIconsRadio.setObjectName("lightIconsRadio")
self.horizontalLayout_7.addWidget(self.lightIconsRadio)
self.horizontalLayout_13.addLayout(self.horizontalLayout_7)
self.verticalLayout_2.addLayout(self.horizontalLayout_13)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.refreshLibrary = QtWidgets.QCheckBox(self.groupBox)
@@ -66,18 +98,6 @@ class Ui_Dialog(object):
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
self.horizontalLayout_9.setObjectName("horizontalLayout_9")
self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
self.label = QtWidgets.QLabel(self.groupBox)
self.label.setObjectName("label")
self.horizontalLayout_7.addWidget(self.label)
self.darkIconsRadio = QtWidgets.QRadioButton(self.groupBox)
self.darkIconsRadio.setObjectName("darkIconsRadio")
self.horizontalLayout_7.addWidget(self.darkIconsRadio)
self.lightIconsRadio = QtWidgets.QRadioButton(self.groupBox)
self.lightIconsRadio.setObjectName("lightIconsRadio")
self.horizontalLayout_7.addWidget(self.lightIconsRadio)
self.horizontalLayout_9.addLayout(self.horizontalLayout_7)
self.autoTags = QtWidgets.QCheckBox(self.groupBox)
self.autoTags.setObjectName("autoTags")
self.horizontalLayout_9.addWidget(self.autoTags)
@@ -283,17 +303,18 @@ class Ui_Dialog(object):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Settings"))
self.groupBox.setTitle(_translate("Dialog", "Library"))
self.refreshLibrary.setText(_translate("Dialog", "Startup: Refresh library"))
self.fileRemember.setText(_translate("Dialog", "Remember open files"))
self.coverShadows.setText(_translate("Dialog", "Cover shadows"))
self.performCulling.setToolTip(_translate("Dialog", "Enabling reduces startup time and memory usage"))
self.performCulling.setText(_translate("Dialog", "Load covers only when needed"))
self.readAtLabel.setText(_translate("Dialog", "Consider book read at percent"))
self.label.setToolTip(_translate("Dialog", "Restart application to see changes"))
self.label.setText(_translate("Dialog", "Icon theme: "))
self.darkIconsRadio.setToolTip(_translate("Dialog", "Restart application to see changes"))
self.darkIconsRadio.setText(_translate("Dialog", "&Dark"))
self.lightIconsRadio.setToolTip(_translate("Dialog", "Restart application to see changes"))
self.lightIconsRadio.setText(_translate("Dialog", "L&ight"))
self.refreshLibrary.setText(_translate("Dialog", "Startup: Refresh library"))
self.fileRemember.setText(_translate("Dialog", "Remember open files"))
self.coverShadows.setText(_translate("Dialog", "Cover shadows"))
self.performCulling.setToolTip(_translate("Dialog", "Enabling reduces startup time and memory usage"))
self.performCulling.setText(_translate("Dialog", "Load covers only when needed"))
self.autoTags.setText(_translate("Dialog", "Generate tags from files"))
self.groupBox_2.setTitle(_translate("Dialog", "Reading"))
self.hideScrollBars.setToolTip(_translate("Dialog", "Horizontal scrolling with Alt + Scroll\n"

View File

@@ -105,6 +105,7 @@ class Settings:
self.parent.settings['hide_scrollbars'] = literal_eval(self.settings.value(
'hideScrollBars', 'False').capitalize())
self.parent.settings['scroll_speed'] = int(self.settings.value('scrollSpeed', 7))
self.parent.settings['consider_read_at'] = int(self.settings.value('considerReadAt', 95))
self.settings.endGroup()
self.settings.beginGroup('dialogSettings')
@@ -176,6 +177,7 @@ class Settings:
self.settings.setValue('cachingEnabled', current_settings['caching_enabled'])
self.settings.setValue('hideScrollBars', current_settings['hide_scrollbars'])
self.settings.setValue('scrollSpeed', current_settings['scroll_speed'])
self.settings.setValue('considerReadAt', current_settings['consider_read_at'])
self.settings.endGroup()
self.settings.beginGroup('dialogSettings')

View File

@@ -92,6 +92,7 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
self.cachingEnabled.setChecked(self.parent.settings['caching_enabled'])
self.hideScrollBars.setChecked(self.parent.settings['hide_scrollbars'])
self.scrollSpeedSlider.setValue(self.parent.settings['scroll_speed'])
self.readAtPercent.setValue(self.parent.settings['consider_read_at'])
self.autoTags.clicked.connect(self.manage_checkboxes)
self.coverShadows.clicked.connect(self.manage_checkboxes)
@@ -101,6 +102,7 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
self.cachingEnabled.clicked.connect(self.manage_checkboxes)
self.hideScrollBars.clicked.connect(self.manage_checkboxes)
self.scrollSpeedSlider.valueChanged.connect(self.change_scroll_speed)
self.readAtPercent.valueChanged.connect(self.change_read_at)
# Generate the QStandardItemModel for the listView
self.listModel = QtGui.QStandardItemModel()
@@ -318,9 +320,12 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
2: 'hi'}
self.parent.settings['dictionary_language'] = language_dict[self.languageBox.currentIndex()]
def change_scroll_speed(self, event):
def change_scroll_speed(self, event=None):
self.parent.settings['scroll_speed'] = self.scrollSpeedSlider.value()
def change_read_at(self, event=None):
self.parent.settings['consider_read_at'] = self.readAtPercent.value()
def manage_checkboxes(self, event=None):
sender = self.sender().objectName()

View File

@@ -130,6 +130,10 @@ class BackGroundCacheRefill(QtCore.QThread):
def __init__(self, image_cache, remove_value, filetype, book, all_pages, parent=None):
super(BackGroundCacheRefill, self).__init__(parent)
# TODO
# Return with only the first image in case of a cache miss
# Rebuilding the entire n image cache takes considerably longer
self.image_cache = image_cache
self.remove_value = remove_value
self.filetype = filetype

View File

@@ -426,13 +426,15 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.searchBar.setObjectName('searchBar')
# Sorter
title_string = self._translate('TableProxyModel', 'Title')
author_string = self._translate('TableProxyModel', 'Author')
year_string = self._translate('TableProxyModel', 'Year')
newest_string = self._translate('TableProxyModel', 'Newest')
lastread_string = self._translate('TableProxyModel', 'Last Read')
title_string = self._translate('LibraryToolBar', 'Title')
author_string = self._translate('LibraryToolBar', 'Author')
year_string = self._translate('LibraryToolBar', 'Year')
newest_string = self._translate('LibraryToolBar', 'Newest')
lastread_string = self._translate('LibraryToolBar', 'Last Read')
progress_string = self._translate('LibraryToolBar', 'Progress')
sorting_choices = [
title_string, author_string, year_string, newest_string, lastread_string]
title_string, author_string, year_string,
newest_string, lastread_string, progress_string]
self.sortingBox = FixedComboBox(self)
self.sortingBox.addItems(sorting_choices)

View File

@@ -1022,11 +1022,8 @@ class PliantWidgetsCommonFunctions:
position_percentage = (self.pw.parent.metadata['position']['current_block'] /
self.pw.parent.metadata['position']['total_blocks'])
# Update book metadata and position percentage
# Update 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)