Move cover loading and culling to guifunctions module
This commit is contained in:
@@ -37,7 +37,7 @@ from lector.widgets import Tab
|
|||||||
from lector.delegates import LibraryDelegate
|
from lector.delegates import LibraryDelegate
|
||||||
from lector.threaded import BackGroundTabUpdate, BackGroundBookAddition, BackGroundBookDeletion
|
from lector.threaded import BackGroundTabUpdate, BackGroundBookAddition, BackGroundBookDeletion
|
||||||
from lector.library import Library
|
from lector.library import Library
|
||||||
from lector.guifunctions import QImageFactory
|
from lector.guifunctions import QImageFactory, CoverLoadingAndCulling
|
||||||
from lector.settings import Settings
|
from lector.settings import Settings
|
||||||
from lector.settingsdialog import SettingsUI
|
from lector.settingsdialog import SettingsUI
|
||||||
from lector.metadatadialog import MetadataUI
|
from lector.metadatadialog import MetadataUI
|
||||||
@@ -125,13 +125,17 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# Application wide temporary directory
|
# Application wide temporary directory
|
||||||
self.temp_dir = QtCore.QTemporaryDir()
|
self.temp_dir = QtCore.QTemporaryDir()
|
||||||
|
|
||||||
|
# Init the Library
|
||||||
|
self.lib_ref = Library(self)
|
||||||
|
|
||||||
|
# Initialize Cover loading functions
|
||||||
|
# Must be after the Library init
|
||||||
|
self.cover_functions = CoverLoadingAndCulling(self)
|
||||||
|
|
||||||
# Init the culling timer
|
# Init the culling timer
|
||||||
self.culling_timer = QtCore.QTimer()
|
self.culling_timer = QtCore.QTimer()
|
||||||
self.culling_timer.setSingleShot(True)
|
self.culling_timer.setSingleShot(True)
|
||||||
self.culling_timer.timeout.connect(self.cull_covers)
|
self.culling_timer.timeout.connect(self.cover_functions.cull_covers)
|
||||||
|
|
||||||
# Init the Library
|
|
||||||
self.lib_ref = Library(self)
|
|
||||||
|
|
||||||
# Toolbar display
|
# Toolbar display
|
||||||
# Maybe make this a persistent option
|
# Maybe make this a persistent option
|
||||||
@@ -333,98 +337,10 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
self.move_on()
|
self.move_on()
|
||||||
|
|
||||||
def cull_covers(self, event=None):
|
|
||||||
blank_pixmap = QtGui.QPixmap()
|
|
||||||
blank_pixmap.load(':/images/blank.png') # Keep this. Removing it causes the
|
|
||||||
# listView to go blank on a resize
|
|
||||||
|
|
||||||
all_indexes = set()
|
|
||||||
for i in range(self.lib_ref.item_proxy_model.rowCount()):
|
|
||||||
all_indexes.add(self.lib_ref.item_proxy_model.index(i, 0))
|
|
||||||
|
|
||||||
y_range = list(range(0, self.listView.viewport().height(), 100))
|
|
||||||
y_range.extend((-20, self.listView.viewport().height() + 20))
|
|
||||||
x_range = range(0, self.listView.viewport().width(), 80)
|
|
||||||
|
|
||||||
visible_indexes = set()
|
|
||||||
for i in y_range:
|
|
||||||
for j in x_range:
|
|
||||||
this_index = self.listView.indexAt(QtCore.QPoint(j, i))
|
|
||||||
visible_indexes.add(this_index)
|
|
||||||
|
|
||||||
invisible_indexes = all_indexes - visible_indexes
|
|
||||||
for i in invisible_indexes:
|
|
||||||
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
|
||||||
this_item = self.lib_ref.view_model.item(model_index.row())
|
|
||||||
|
|
||||||
if this_item:
|
|
||||||
this_item.setIcon(QtGui.QIcon(blank_pixmap))
|
|
||||||
this_item.setData(False, QtCore.Qt.UserRole + 8)
|
|
||||||
|
|
||||||
hash_index_dict = {}
|
|
||||||
hash_list = []
|
|
||||||
for i in visible_indexes:
|
|
||||||
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
|
||||||
|
|
||||||
book_hash = self.lib_ref.view_model.data(
|
|
||||||
model_index, QtCore.Qt.UserRole + 6)
|
|
||||||
cover_displayed = self.lib_ref.view_model.data(
|
|
||||||
model_index, QtCore.Qt.UserRole + 8)
|
|
||||||
|
|
||||||
if book_hash and not cover_displayed:
|
|
||||||
hash_list.append(book_hash)
|
|
||||||
hash_index_dict[book_hash] = model_index
|
|
||||||
|
|
||||||
all_covers = database.DatabaseFunctions(
|
|
||||||
self.database_path).fetch_covers_only(hash_list)
|
|
||||||
|
|
||||||
for i in all_covers:
|
|
||||||
book_hash = i[0]
|
|
||||||
cover = i[1]
|
|
||||||
model_index = hash_index_dict[book_hash]
|
|
||||||
|
|
||||||
book_item = self.lib_ref.view_model.item(model_index.row())
|
|
||||||
self.cover_loader(book_item, cover)
|
|
||||||
|
|
||||||
def start_culling_timer(self):
|
def start_culling_timer(self):
|
||||||
if self.settings['perform_culling']:
|
if self.settings['perform_culling']:
|
||||||
self.culling_timer.start(30)
|
self.culling_timer.start(30)
|
||||||
|
|
||||||
def load_all_covers(self):
|
|
||||||
all_covers_db = database.DatabaseFunctions(
|
|
||||||
self.database_path).fetch_data(
|
|
||||||
('Hash', 'CoverImage',),
|
|
||||||
'books',
|
|
||||||
{'Hash': ''},
|
|
||||||
'LIKE')
|
|
||||||
|
|
||||||
if not all_covers_db:
|
|
||||||
return
|
|
||||||
|
|
||||||
all_covers = {
|
|
||||||
i[0]: i[1] for i in all_covers_db}
|
|
||||||
|
|
||||||
for i in range(self.lib_ref.view_model.rowCount()):
|
|
||||||
this_item = self.lib_ref.view_model.item(i, 0)
|
|
||||||
|
|
||||||
is_cover_already_displayed = this_item.data(QtCore.Qt.UserRole + 8)
|
|
||||||
if is_cover_already_displayed:
|
|
||||||
continue
|
|
||||||
|
|
||||||
book_hash = this_item.data(QtCore.Qt.UserRole + 6)
|
|
||||||
cover = all_covers[book_hash]
|
|
||||||
self.cover_loader(this_item, cover)
|
|
||||||
|
|
||||||
def cover_loader(self, item, cover):
|
|
||||||
img_pixmap = QtGui.QPixmap()
|
|
||||||
if cover:
|
|
||||||
img_pixmap.loadFromData(cover)
|
|
||||||
else:
|
|
||||||
img_pixmap.load(':/images/NotFound.png')
|
|
||||||
img_pixmap = img_pixmap.scaled(420, 600, QtCore.Qt.IgnoreAspectRatio)
|
|
||||||
item.setIcon(QtGui.QIcon(img_pixmap))
|
|
||||||
item.setData(True, QtCore.Qt.UserRole + 8)
|
|
||||||
|
|
||||||
def add_bookmark(self):
|
def add_bookmark(self):
|
||||||
if self.tabWidget.currentIndex() != 0:
|
if self.tabWidget.currentIndex() != 0:
|
||||||
self.tabWidget.widget(self.tabWidget.currentIndex()).add_bookmark()
|
self.tabWidget.widget(self.tabWidget.currentIndex()).add_bookmark()
|
||||||
@@ -570,7 +486,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self._translate('Main_UI', ' books'))
|
self._translate('Main_UI', ' books'))
|
||||||
|
|
||||||
if not self.settings['perform_culling']:
|
if not self.settings['perform_culling']:
|
||||||
self.load_all_covers()
|
self.cover_functions.load_all_covers()
|
||||||
|
|
||||||
def switch_library_view(self):
|
def switch_library_view(self):
|
||||||
if self.libraryToolBar.coverViewButton.isChecked():
|
if self.libraryToolBar.coverViewButton.isChecked():
|
||||||
@@ -1077,7 +993,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
book_item = self.lib_ref.view_model.item(edit_book.row())
|
book_item = self.lib_ref.view_model.item(edit_book.row())
|
||||||
book_cover = database.DatabaseFunctions(
|
book_cover = database.DatabaseFunctions(
|
||||||
self.database_path).fetch_covers_only([book_hash])[0][1]
|
self.database_path).fetch_covers_only([book_hash])[0][1]
|
||||||
self.cover_loader(book_item, book_cover)
|
self.cover_functions.cover_loader(book_item, book_cover)
|
||||||
|
|
||||||
cover = self.lib_ref.view_model.item(edit_book.row()).icon()
|
cover = self.lib_ref.view_model.item(edit_book.row()).icon()
|
||||||
title = metadata['title']
|
title = metadata['title']
|
||||||
|
@@ -72,7 +72,6 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
|
|||||||
|
|
||||||
def find_definition(self, word):
|
def find_definition(self, word):
|
||||||
word_root_json = self.api_call(self.root_url, word)
|
word_root_json = self.api_call(self.root_url, word)
|
||||||
print(word_root_json)
|
|
||||||
if not word_root_json:
|
if not word_root_json:
|
||||||
self.set_text(word, None, None, True)
|
self.set_text(word, None, None, True)
|
||||||
return
|
return
|
||||||
|
@@ -16,7 +16,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from PyQt5 import QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
|
from lector import database
|
||||||
from lector.resources import resources
|
from lector.resources import resources
|
||||||
|
|
||||||
|
|
||||||
@@ -30,3 +31,98 @@ class QImageFactory:
|
|||||||
|
|
||||||
this_qicon = QtGui.QIcon(icon_path)
|
this_qicon = QtGui.QIcon(icon_path)
|
||||||
return this_qicon
|
return this_qicon
|
||||||
|
|
||||||
|
|
||||||
|
class CoverLoadingAndCulling:
|
||||||
|
def __init__(self, main_window):
|
||||||
|
self.main_window = main_window
|
||||||
|
self.lib_ref = self.main_window.lib_ref
|
||||||
|
self.listView = self.main_window.listView
|
||||||
|
|
||||||
|
def cull_covers(self, event=None):
|
||||||
|
blank_pixmap = QtGui.QPixmap()
|
||||||
|
blank_pixmap.load(':/images/blank.png') # Keep this. Removing it causes the
|
||||||
|
# listView to go blank on a resize
|
||||||
|
|
||||||
|
all_indexes = set()
|
||||||
|
for i in range(self.lib_ref.item_proxy_model.rowCount()):
|
||||||
|
all_indexes.add(self.lib_ref.item_proxy_model.index(i, 0))
|
||||||
|
|
||||||
|
y_range = list(range(0, self.listView.viewport().height(), 100))
|
||||||
|
y_range.extend((-20, self.listView.viewport().height() + 20))
|
||||||
|
x_range = range(0, self.listView.viewport().width(), 80)
|
||||||
|
|
||||||
|
visible_indexes = set()
|
||||||
|
for i in y_range:
|
||||||
|
for j in x_range:
|
||||||
|
this_index = self.listView.indexAt(QtCore.QPoint(j, i))
|
||||||
|
visible_indexes.add(this_index)
|
||||||
|
|
||||||
|
invisible_indexes = all_indexes - visible_indexes
|
||||||
|
for i in invisible_indexes:
|
||||||
|
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
||||||
|
this_item = self.lib_ref.view_model.item(model_index.row())
|
||||||
|
|
||||||
|
if this_item:
|
||||||
|
this_item.setIcon(QtGui.QIcon(blank_pixmap))
|
||||||
|
this_item.setData(False, QtCore.Qt.UserRole + 8)
|
||||||
|
|
||||||
|
hash_index_dict = {}
|
||||||
|
hash_list = []
|
||||||
|
for i in visible_indexes:
|
||||||
|
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
||||||
|
|
||||||
|
book_hash = self.lib_ref.view_model.data(
|
||||||
|
model_index, QtCore.Qt.UserRole + 6)
|
||||||
|
cover_displayed = self.lib_ref.view_model.data(
|
||||||
|
model_index, QtCore.Qt.UserRole + 8)
|
||||||
|
|
||||||
|
if book_hash and not cover_displayed:
|
||||||
|
hash_list.append(book_hash)
|
||||||
|
hash_index_dict[book_hash] = model_index
|
||||||
|
|
||||||
|
all_covers = database.DatabaseFunctions(
|
||||||
|
self.main_window.database_path).fetch_covers_only(hash_list)
|
||||||
|
|
||||||
|
for i in all_covers:
|
||||||
|
book_hash = i[0]
|
||||||
|
cover = i[1]
|
||||||
|
model_index = hash_index_dict[book_hash]
|
||||||
|
|
||||||
|
book_item = self.lib_ref.view_model.item(model_index.row())
|
||||||
|
self.cover_loader(book_item, cover)
|
||||||
|
|
||||||
|
def load_all_covers(self):
|
||||||
|
all_covers_db = database.DatabaseFunctions(
|
||||||
|
self.main_window.database_path).fetch_data(
|
||||||
|
('Hash', 'CoverImage',),
|
||||||
|
'books',
|
||||||
|
{'Hash': ''},
|
||||||
|
'LIKE')
|
||||||
|
|
||||||
|
if not all_covers_db:
|
||||||
|
return
|
||||||
|
|
||||||
|
all_covers = {
|
||||||
|
i[0]: i[1] for i in all_covers_db}
|
||||||
|
|
||||||
|
for i in range(self.lib_ref.view_model.rowCount()):
|
||||||
|
this_item = self.lib_ref.view_model.item(i, 0)
|
||||||
|
|
||||||
|
is_cover_already_displayed = this_item.data(QtCore.Qt.UserRole + 8)
|
||||||
|
if is_cover_already_displayed:
|
||||||
|
continue
|
||||||
|
|
||||||
|
book_hash = this_item.data(QtCore.Qt.UserRole + 6)
|
||||||
|
cover = all_covers[book_hash]
|
||||||
|
self.cover_loader(this_item, cover)
|
||||||
|
|
||||||
|
def cover_loader(self, item, cover):
|
||||||
|
img_pixmap = QtGui.QPixmap()
|
||||||
|
if cover:
|
||||||
|
img_pixmap.loadFromData(cover)
|
||||||
|
else:
|
||||||
|
img_pixmap.load(':/images/NotFound.png')
|
||||||
|
img_pixmap = img_pixmap.scaled(420, 600, QtCore.Qt.IgnoreAspectRatio)
|
||||||
|
item.setIcon(QtGui.QIcon(img_pixmap))
|
||||||
|
item.setData(True, QtCore.Qt.UserRole + 8)
|
||||||
|
@@ -163,7 +163,7 @@ class Library:
|
|||||||
# The is_database_ready boolean is required when a new thread sends
|
# The is_database_ready boolean is required when a new thread sends
|
||||||
# books here for model generation.
|
# books here for model generation.
|
||||||
if not self.parent.settings['perform_culling'] and is_database_ready:
|
if not self.parent.settings['perform_culling'] and is_database_ready:
|
||||||
self.parent.load_all_covers()
|
self.parent.cover_functions.load_all_covers()
|
||||||
|
|
||||||
def generate_proxymodels(self):
|
def generate_proxymodels(self):
|
||||||
self.item_proxy_model = ItemProxyModel()
|
self.item_proxy_model = ItemProxyModel()
|
||||||
|
@@ -116,7 +116,7 @@ class MetadataUI(QtWidgets.QDialog, metadata.Ui_Dialog):
|
|||||||
|
|
||||||
if self.cover_for_database:
|
if self.cover_for_database:
|
||||||
database_dict['CoverImage'] = self.cover_for_database
|
database_dict['CoverImage'] = self.cover_for_database
|
||||||
self.parent.cover_loader(
|
self.parent.cover_functions.cover_loader(
|
||||||
book_item, self.cover_for_database)
|
book_item, self.cover_for_database)
|
||||||
|
|
||||||
self.parent.lib_ref.update_proxymodels()
|
self.parent.lib_ref.update_proxymodels()
|
||||||
|
@@ -309,4 +309,4 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
|||||||
self.parent.settings[sender_dict[sender]] = not self.parent.settings[sender_dict[sender]]
|
self.parent.settings[sender_dict[sender]] = not self.parent.settings[sender_dict[sender]]
|
||||||
|
|
||||||
if not self.performCulling.isChecked():
|
if not self.performCulling.isChecked():
|
||||||
self.parent.load_all_covers()
|
self.parent.cover_functions.load_all_covers()
|
||||||
|
Reference in New Issue
Block a user