Remove Table Model specific code
This commit is contained in:
1
TODO
1
TODO
@@ -21,6 +21,7 @@ TODO
|
|||||||
✓ Mass tagging
|
✓ Mass tagging
|
||||||
✓ Add capability to sort by new
|
✓ Add capability to sort by new
|
||||||
Table view
|
Table view
|
||||||
|
Get sorting working again
|
||||||
Ignore a / the / numbers for sorting purposes
|
Ignore a / the / numbers for sorting purposes
|
||||||
Information dialog widget
|
Information dialog widget
|
||||||
Context menu: Cache, Read, Edit database, delete, Mark read/unread
|
Context menu: Cache, Read, Edit database, delete, Mark read/unread
|
||||||
|
51
__main__.py
51
__main__.py
@@ -116,9 +116,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.libraryToolBar.coverViewButton.triggered.connect(self.switch_library_view)
|
self.libraryToolBar.coverViewButton.triggered.connect(self.switch_library_view)
|
||||||
self.libraryToolBar.tableViewButton.triggered.connect(self.switch_library_view)
|
self.libraryToolBar.tableViewButton.triggered.connect(self.switch_library_view)
|
||||||
self.libraryToolBar.settingsButton.triggered.connect(self.show_settings)
|
self.libraryToolBar.settingsButton.triggered.connect(self.show_settings)
|
||||||
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodel)
|
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodels)
|
||||||
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_table_proxy_model)
|
self.libraryToolBar.sortingBox.activated.connect(self.lib_ref.update_proxymodels)
|
||||||
self.libraryToolBar.sortingBox.activated.connect(self.lib_ref.update_proxymodel)
|
|
||||||
self.libraryToolBar.libraryFilterButton.setPopupMode(QtWidgets.QToolButton.InstantPopup)
|
self.libraryToolBar.libraryFilterButton.setPopupMode(QtWidgets.QToolButton.InstantPopup)
|
||||||
self.addToolBar(self.libraryToolBar)
|
self.addToolBar(self.libraryToolBar)
|
||||||
|
|
||||||
@@ -194,8 +193,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
# Init display models
|
# Init display models
|
||||||
self.lib_ref.generate_model('build')
|
self.lib_ref.generate_model('build')
|
||||||
self.lib_ref.create_table_model()
|
self.lib_ref.generate_proxymodels()
|
||||||
self.lib_ref.create_proxymodel()
|
|
||||||
self.lib_ref.generate_library_tags()
|
self.lib_ref.generate_library_tags()
|
||||||
self.set_library_filter()
|
self.set_library_filter()
|
||||||
self.start_culling_timer()
|
self.start_culling_timer()
|
||||||
@@ -212,7 +210,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.tableView.doubleClicked.connect(self.library_doubleclick)
|
self.tableView.doubleClicked.connect(self.library_doubleclick)
|
||||||
self.tableView.horizontalHeader().setSectionResizeMode(
|
self.tableView.horizontalHeader().setSectionResizeMode(
|
||||||
QtWidgets.QHeaderView.Interactive)
|
QtWidgets.QHeaderView.Interactive)
|
||||||
self.tableView.horizontalHeader().setSortIndicator(1, QtCore.Qt.AscendingOrder)
|
self.tableView.horizontalHeader().setSortIndicator(2, QtCore.Qt.AscendingOrder)
|
||||||
self.tableView.setColumnHidden(0, True)
|
self.tableView.setColumnHidden(0, True)
|
||||||
self.tableView.horizontalHeader().setHighlightSections(False)
|
self.tableView.horizontalHeader().setHighlightSections(False)
|
||||||
if self.settings['main_window_headers']:
|
if self.settings['main_window_headers']:
|
||||||
@@ -275,8 +273,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
blank_pixmap.load(':/images/blank.png')
|
blank_pixmap.load(':/images/blank.png')
|
||||||
|
|
||||||
all_indexes = set()
|
all_indexes = set()
|
||||||
for i in range(self.lib_ref.proxy_model.rowCount()):
|
for i in range(self.lib_ref.item_proxy_model.rowCount()):
|
||||||
all_indexes.add(self.lib_ref.proxy_model.index(i, 0))
|
all_indexes.add(self.lib_ref.item_proxy_model.index(i, 0))
|
||||||
|
|
||||||
y_range = list(range(0, self.listView.viewport().height(), 100))
|
y_range = list(range(0, self.listView.viewport().height(), 100))
|
||||||
y_range.extend((-20, self.listView.viewport().height() + 20))
|
y_range.extend((-20, self.listView.viewport().height() + 20))
|
||||||
@@ -290,7 +288,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
invisible_indexes = all_indexes - visible_indexes
|
invisible_indexes = all_indexes - visible_indexes
|
||||||
for i in invisible_indexes:
|
for i in invisible_indexes:
|
||||||
model_index = self.lib_ref.proxy_model.mapToSource(i)
|
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
||||||
this_item = self.lib_ref.view_model.item(model_index.row())
|
this_item = self.lib_ref.view_model.item(model_index.row())
|
||||||
|
|
||||||
if this_item:
|
if this_item:
|
||||||
@@ -298,7 +296,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
this_item.setData(False, QtCore.Qt.UserRole + 8)
|
this_item.setData(False, QtCore.Qt.UserRole + 8)
|
||||||
|
|
||||||
for i in visible_indexes:
|
for i in visible_indexes:
|
||||||
model_index = self.lib_ref.proxy_model.mapToSource(i)
|
model_index = self.lib_ref.item_proxy_model.mapToSource(i)
|
||||||
this_item = self.lib_ref.view_model.item(model_index.row())
|
this_item = self.lib_ref.view_model.item(model_index.row())
|
||||||
|
|
||||||
if this_item:
|
if this_item:
|
||||||
@@ -429,7 +427,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# Get a list of QItemSelection objects
|
# Get a list of QItemSelection objects
|
||||||
# What we're interested in is the indexes()[0] in each of them
|
# What we're interested in is the indexes()[0] in each of them
|
||||||
# That gives a list of indexes from the view model
|
# That gives a list of indexes from the view model
|
||||||
selected_books = self.lib_ref.proxy_model.mapSelectionToSource(
|
selected_books = self.lib_ref.item_proxy_model.mapSelectionToSource(
|
||||||
self.listView.selectionModel().selection())
|
self.listView.selectionModel().selection())
|
||||||
|
|
||||||
if not selected_books:
|
if not selected_books:
|
||||||
@@ -484,8 +482,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.sorterProgress.setVisible(False)
|
self.sorterProgress.setVisible(False)
|
||||||
self.sorterProgress.setValue(0)
|
self.sorterProgress.setValue(0)
|
||||||
|
|
||||||
self.lib_ref.create_table_model()
|
self.lib_ref.generate_proxymodels()
|
||||||
self.lib_ref.create_proxymodel()
|
|
||||||
self.lib_ref.generate_library_tags()
|
self.lib_ref.generate_library_tags()
|
||||||
|
|
||||||
if not self.settings['perform_culling']:
|
if not self.settings['perform_culling']:
|
||||||
@@ -519,11 +516,11 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.bookToolBar.hide()
|
self.bookToolBar.hide()
|
||||||
self.libraryToolBar.show()
|
self.libraryToolBar.show()
|
||||||
|
|
||||||
if self.lib_ref.proxy_model:
|
if self.lib_ref.item_proxy_model:
|
||||||
# Making the proxy model available doesn't affect
|
# Making the proxy model available doesn't affect
|
||||||
# memory utilization at all. Bleh.
|
# memory utilization at all. Bleh.
|
||||||
self.statusMessage.setText(
|
self.statusMessage.setText(
|
||||||
str(self.lib_ref.proxy_model.rowCount()) + ' Books')
|
str(self.lib_ref.item_proxy_model.rowCount()) + ' Books')
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if self.settings['show_toolbars']:
|
if self.settings['show_toolbars']:
|
||||||
@@ -575,12 +572,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
def set_toc_position(self, event=None):
|
def set_toc_position(self, event=None):
|
||||||
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
||||||
|
|
||||||
# We're updating the underlying models to have real-time
|
# We're updating the underlying model to have real-time
|
||||||
# updates on the read status
|
# updates on the read status
|
||||||
# Since there are 2 separate models, they will each have to
|
|
||||||
# be updated individually
|
|
||||||
|
|
||||||
# The listView model
|
|
||||||
# Set a baseline model index in case the item gets deleted
|
# Set a baseline model index in case the item gets deleted
|
||||||
# E.g It's open in a tab and deleted from the library
|
# E.g It's open in a tab and deleted from the library
|
||||||
model_index = None
|
model_index = None
|
||||||
@@ -602,20 +596,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.lib_ref.view_model.setData(
|
self.lib_ref.view_model.setData(
|
||||||
model_index, current_tab.metadata['position'], QtCore.Qt.UserRole + 7)
|
model_index, current_tab.metadata['position'], QtCore.Qt.UserRole + 7)
|
||||||
|
|
||||||
# The tableView model
|
|
||||||
model_index = None
|
|
||||||
start_index = self.lib_ref.table_model.index(0, 0)
|
|
||||||
matching_item = self.lib_ref.table_model.match(
|
|
||||||
start_index,
|
|
||||||
QtCore.Qt.UserRole + 1,
|
|
||||||
current_tab.metadata['hash'],
|
|
||||||
1, QtCore.Qt.MatchExactly)
|
|
||||||
|
|
||||||
if matching_item:
|
|
||||||
model_row = matching_item[0].row()
|
|
||||||
self.lib_ref.table_model.display_data[model_row][5][
|
|
||||||
'position'] = current_tab.metadata['position']
|
|
||||||
|
|
||||||
# Go on to change the value of the Table of Contents box
|
# Go on to change the value of the Table of Contents box
|
||||||
current_tab.change_chapter_tocBox()
|
current_tab.change_chapter_tocBox()
|
||||||
self.format_contentView()
|
self.format_contentView()
|
||||||
@@ -641,7 +621,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
sender = self.sender().objectName()
|
sender = self.sender().objectName()
|
||||||
|
|
||||||
if sender == 'listView':
|
if sender == 'listView':
|
||||||
source_index = self.lib_ref.proxy_model.mapToSource(index)
|
source_index = self.lib_ref.item_proxy_model.mapToSource(index)
|
||||||
elif sender == 'tableView':
|
elif sender == 'tableView':
|
||||||
source_index = self.lib_ref.table_proxy_model.mapToSource(index)
|
source_index = self.lib_ref.table_proxy_model.mapToSource(index)
|
||||||
|
|
||||||
@@ -973,8 +953,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
self.library_filter_menu.actions()[-1].setChecked(True)
|
self.library_filter_menu.actions()[-1].setChecked(True)
|
||||||
|
|
||||||
self.lib_ref.update_proxymodel()
|
self.lib_ref.update_proxymodels()
|
||||||
self.lib_ref.update_table_proxy_model()
|
|
||||||
|
|
||||||
def toggle_toolbars(self):
|
def toggle_toolbars(self):
|
||||||
self.settings['show_toolbars'] = not self.settings['show_toolbars']
|
self.settings['show_toolbars'] = not self.settings['show_toolbars']
|
||||||
|
86
library.py
86
library.py
@@ -22,21 +22,18 @@ import pathlib
|
|||||||
from PyQt5 import QtGui, QtCore
|
from PyQt5 import QtGui, QtCore
|
||||||
|
|
||||||
import database
|
import database
|
||||||
from models import MostExcellentTableModel, TableProxyModel, ItemProxyModel
|
from models import TableProxyModel, ItemProxyModel
|
||||||
|
|
||||||
|
|
||||||
class Library:
|
class Library:
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.view_model = None
|
self.view_model = None
|
||||||
self.proxy_model = None
|
self.item_proxy_model = None
|
||||||
self.table_model = None
|
|
||||||
self.table_proxy_model = None
|
self.table_proxy_model = None
|
||||||
self.table_rows = []
|
|
||||||
|
|
||||||
def generate_model(self, mode, parsed_books=None, is_database_ready=True):
|
def generate_model(self, mode, parsed_books=None, is_database_ready=True):
|
||||||
if mode == 'build':
|
if mode == 'build':
|
||||||
self.table_rows = []
|
|
||||||
self.view_model = QtGui.QStandardItemModel()
|
self.view_model = QtGui.QStandardItemModel()
|
||||||
self.view_model.setColumnCount(10)
|
self.view_model.setColumnCount(10)
|
||||||
|
|
||||||
@@ -142,13 +139,14 @@ class Library:
|
|||||||
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.load_all_covers()
|
||||||
|
|
||||||
def create_table_model(self):
|
def generate_proxymodels(self):
|
||||||
table_header = ['Title', 'Author', 'Status', 'Year', 'Tags']
|
self.item_proxy_model = ItemProxyModel()
|
||||||
self.table_model = MostExcellentTableModel(
|
self.item_proxy_model.setSourceModel(self.view_model)
|
||||||
table_header, self.table_rows, self.parent.temp_dir.path())
|
self.item_proxy_model.setSortCaseSensitivity(False)
|
||||||
self.create_table_proxy_model()
|
s = QtCore.QSize(160, 250) # Set icon sizing here
|
||||||
|
self.parent.listView.setIconSize(s)
|
||||||
|
self.parent.listView.setModel(self.item_proxy_model)
|
||||||
|
|
||||||
def create_table_proxy_model(self):
|
|
||||||
self.table_proxy_model = TableProxyModel(self.parent.temp_dir.path())
|
self.table_proxy_model = TableProxyModel(self.parent.temp_dir.path())
|
||||||
self.table_proxy_model.setSourceModel(self.view_model)
|
self.table_proxy_model.setSourceModel(self.view_model)
|
||||||
self.table_proxy_model.setSortCaseSensitivity(False)
|
self.table_proxy_model.setSortCaseSensitivity(False)
|
||||||
@@ -156,39 +154,32 @@ class Library:
|
|||||||
self.parent.tableView.setModel(self.table_proxy_model)
|
self.parent.tableView.setModel(self.table_proxy_model)
|
||||||
self.parent.tableView.horizontalHeader().setSortIndicator(
|
self.parent.tableView.horizontalHeader().setSortIndicator(
|
||||||
0, QtCore.Qt.AscendingOrder)
|
0, QtCore.Qt.AscendingOrder)
|
||||||
self.update_table_proxy_model()
|
|
||||||
|
|
||||||
def update_table_proxy_model(self):
|
self.update_proxymodels()
|
||||||
|
|
||||||
|
def update_proxymodels(self):
|
||||||
|
# Table proxy model
|
||||||
self.table_proxy_model.invalidateFilter()
|
self.table_proxy_model.invalidateFilter()
|
||||||
self.table_proxy_model.setFilterParams(
|
self.table_proxy_model.setFilterParams(
|
||||||
self.parent.libraryToolBar.searchBar.text(),
|
self.parent.libraryToolBar.searchBar.text(),
|
||||||
self.parent.active_library_filters,
|
self.parent.active_library_filters,
|
||||||
self.parent.libraryToolBar.sortingBox.currentIndex())
|
0) # This doesn't need to know the sorting box position
|
||||||
# This isn't needed, but it forces a model update every time the
|
|
||||||
# text in the line edit changes. So I guess it is needed.
|
|
||||||
self.table_proxy_model.setFilterFixedString(
|
self.table_proxy_model.setFilterFixedString(
|
||||||
self.parent.libraryToolBar.searchBar.text())
|
self.parent.libraryToolBar.searchBar.text())
|
||||||
|
# ^^^ This isn't needed, but it forces a model update every time the
|
||||||
|
# text in the line edit changes. So I guess it is needed.
|
||||||
|
|
||||||
def create_proxymodel(self):
|
# Item proxy model
|
||||||
self.proxy_model = ItemProxyModel()
|
self.item_proxy_model.invalidateFilter()
|
||||||
self.proxy_model.setSourceModel(self.view_model)
|
self.item_proxy_model.setFilterParams(
|
||||||
self.proxy_model.setSortCaseSensitivity(False)
|
|
||||||
s = QtCore.QSize(160, 250) # Set icon sizing here
|
|
||||||
self.parent.listView.setIconSize(s)
|
|
||||||
self.parent.listView.setModel(self.proxy_model)
|
|
||||||
self.update_proxymodel()
|
|
||||||
|
|
||||||
def update_proxymodel(self):
|
|
||||||
self.proxy_model.invalidateFilter()
|
|
||||||
self.proxy_model.setFilterParams(
|
|
||||||
self.parent.libraryToolBar.searchBar.text(),
|
self.parent.libraryToolBar.searchBar.text(),
|
||||||
self.parent.active_library_filters,
|
self.parent.active_library_filters,
|
||||||
self.parent.libraryToolBar.sortingBox.currentIndex())
|
self.parent.libraryToolBar.sortingBox.currentIndex())
|
||||||
self.proxy_model.setFilterFixedString(
|
self.item_proxy_model.setFilterFixedString(
|
||||||
self.parent.libraryToolBar.searchBar.text())
|
self.parent.libraryToolBar.searchBar.text())
|
||||||
|
|
||||||
self.parent.statusMessage.setText(
|
self.parent.statusMessage.setText(
|
||||||
str(self.proxy_model.rowCount()) + ' books')
|
str(self.item_proxy_model.rowCount()) + ' books')
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# Allow sorting by type
|
# Allow sorting by type
|
||||||
@@ -205,7 +196,7 @@ class Library:
|
|||||||
4: 12}
|
4: 12}
|
||||||
|
|
||||||
# Sorting according to roles and the drop down in the library toolbar
|
# Sorting according to roles and the drop down in the library toolbar
|
||||||
self.proxy_model.setSortRole(
|
self.item_proxy_model.setSortRole(
|
||||||
QtCore.Qt.UserRole + sort_roles[self.parent.libraryToolBar.sortingBox.currentIndex()])
|
QtCore.Qt.UserRole + sort_roles[self.parent.libraryToolBar.sortingBox.currentIndex()])
|
||||||
|
|
||||||
# This can be expanded to other fields by appending to the list
|
# This can be expanded to other fields by appending to the list
|
||||||
@@ -213,7 +204,7 @@ class Library:
|
|||||||
if self.parent.libraryToolBar.sortingBox.currentIndex() in [3, 4]:
|
if self.parent.libraryToolBar.sortingBox.currentIndex() in [3, 4]:
|
||||||
sort_order = QtCore.Qt.DescendingOrder
|
sort_order = QtCore.Qt.DescendingOrder
|
||||||
|
|
||||||
self.proxy_model.sort(0, sort_order)
|
self.item_proxy_model.sort(0, sort_order)
|
||||||
self.parent.start_culling_timer()
|
self.parent.start_culling_timer()
|
||||||
|
|
||||||
def generate_library_tags(self):
|
def generate_library_tags(self):
|
||||||
@@ -250,8 +241,7 @@ class Library:
|
|||||||
|
|
||||||
return 'manually added', None
|
return 'manually added', None
|
||||||
|
|
||||||
# Both the models will have to be done separately
|
# Generate tags for the QStandardItemModel
|
||||||
# Item Model
|
|
||||||
for i in range(self.view_model.rowCount()):
|
for i in range(self.view_model.rowCount()):
|
||||||
this_item = self.view_model.item(i, 0)
|
this_item = self.view_model.item(i, 0)
|
||||||
all_metadata = this_item.data(QtCore.Qt.UserRole + 3)
|
all_metadata = this_item.data(QtCore.Qt.UserRole + 3)
|
||||||
@@ -260,19 +250,6 @@ class Library:
|
|||||||
this_item.setData(directory_name, QtCore.Qt.UserRole + 10)
|
this_item.setData(directory_name, QtCore.Qt.UserRole + 10)
|
||||||
this_item.setData(directory_tags, QtCore.Qt.UserRole + 11)
|
this_item.setData(directory_tags, QtCore.Qt.UserRole + 11)
|
||||||
|
|
||||||
# Table Model
|
|
||||||
for count, i in enumerate(self.table_model.display_data):
|
|
||||||
all_metadata = i[5]
|
|
||||||
|
|
||||||
directory_name, directory_tags = get_tags(all_metadata)
|
|
||||||
try:
|
|
||||||
i[7] = directory_name
|
|
||||||
i[8] = directory_tags
|
|
||||||
except IndexError:
|
|
||||||
i.extend([directory_name, directory_tags])
|
|
||||||
|
|
||||||
self.table_model.display_data[count] = i
|
|
||||||
|
|
||||||
def prune_models(self, valid_paths):
|
def prune_models(self, valid_paths):
|
||||||
# To be executed when the library is updated by folder
|
# To be executed when the library is updated by folder
|
||||||
# All files in unselected directories will have to be removed
|
# All files in unselected directories will have to be removed
|
||||||
@@ -280,17 +257,16 @@ class Library:
|
|||||||
# They will also have to be deleted from the library
|
# They will also have to be deleted from the library
|
||||||
valid_paths = set(valid_paths)
|
valid_paths = set(valid_paths)
|
||||||
|
|
||||||
# Get all paths in the dictionary from either of the models
|
# Get all paths
|
||||||
# self.table_rows has all file metadata in position 5
|
all_paths = set()
|
||||||
all_paths = [i[5]['path'] for i in self.table_rows]
|
for i in range(self.view_model.rowCount()):
|
||||||
all_paths = set(all_paths)
|
item = self.view_model.item(i, 0)
|
||||||
|
item_metadata = item.data(QtCore.Qt.UserRole + 3)
|
||||||
|
book_path = item_metadata['path']
|
||||||
|
all_paths.add(book_path)
|
||||||
|
|
||||||
invalid_paths = all_paths - valid_paths
|
invalid_paths = all_paths - valid_paths
|
||||||
|
|
||||||
# Remove invalid paths from both of the models
|
|
||||||
self.table_rows = [
|
|
||||||
i for i in self.table_rows if i[5]['path'] not in invalid_paths]
|
|
||||||
|
|
||||||
deletable_persistent_indexes = []
|
deletable_persistent_indexes = []
|
||||||
for i in range(self.view_model.rowCount()):
|
for i in range(self.view_model.rowCount()):
|
||||||
item = self.view_model.item(i)
|
item = self.view_model.item(i)
|
||||||
|
139
models.py
139
models.py
@@ -184,145 +184,6 @@ class ProxyModelsCommonFunctions:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class MostExcellentTableModel(QtCore.QAbstractTableModel):
|
|
||||||
# Sorting is taken care of by the QSortFilterProxy model
|
|
||||||
# which has an inbuilt sort method
|
|
||||||
|
|
||||||
# Modifying data in the table model is a case of modifying the
|
|
||||||
# data sent to it as a list
|
|
||||||
# In this case, that's self.data_list
|
|
||||||
|
|
||||||
def __init__(self, header_data, display_data, temp_dir=None, parent=None):
|
|
||||||
super(MostExcellentTableModel, self).__init__(parent)
|
|
||||||
self.header_data = header_data
|
|
||||||
self.display_data = display_data
|
|
||||||
self.temp_dir = temp_dir
|
|
||||||
|
|
||||||
def rowCount(self, parent):
|
|
||||||
if self.display_data:
|
|
||||||
return len(self.display_data)
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def columnCount(self, parent):
|
|
||||||
return len(self.header_data)
|
|
||||||
|
|
||||||
def data(self, index, role):
|
|
||||||
if not index.isValid():
|
|
||||||
return None
|
|
||||||
|
|
||||||
# This block specializes this function for the library
|
|
||||||
# Not having a self.temp_dir allows for its reuse elsewhere
|
|
||||||
if self.temp_dir:
|
|
||||||
if role == QtCore.Qt.DecorationRole and index.column() == 2:
|
|
||||||
return_pixmap = None
|
|
||||||
file_exists = self.display_data[index.row()][5]['file_exists']
|
|
||||||
position = self.display_data[index.row()][5]['position']
|
|
||||||
|
|
||||||
if not file_exists:
|
|
||||||
return_pixmap = pie_chart.pixmapper(
|
|
||||||
-1, None, None, QtCore.Qt.SizeHintRole + 10)
|
|
||||||
|
|
||||||
if position:
|
|
||||||
current_chapter = position['current_chapter']
|
|
||||||
total_chapters = position['total_chapters']
|
|
||||||
|
|
||||||
return_pixmap = pie_chart.pixmapper(
|
|
||||||
current_chapter, total_chapters, self.temp_dir,
|
|
||||||
QtCore.Qt.SizeHintRole + 10)
|
|
||||||
|
|
||||||
return return_pixmap
|
|
||||||
|
|
||||||
# The rest of the roles can be accomodated here.
|
|
||||||
elif role == QtCore.Qt.UserRole:
|
|
||||||
value = self.display_data[index.row()][5] # File metadata
|
|
||||||
return value
|
|
||||||
|
|
||||||
elif role == QtCore.Qt.UserRole + 1:
|
|
||||||
value = self.display_data[index.row()][6] # File hash
|
|
||||||
return value
|
|
||||||
|
|
||||||
#_________________________________
|
|
||||||
# The EditRole is so that editing a cell doesn't clear its contents
|
|
||||||
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
|
|
||||||
value = self.display_data[index.row()][index.column()]
|
|
||||||
return value
|
|
||||||
|
|
||||||
else:
|
|
||||||
return QtCore.QVariant()
|
|
||||||
|
|
||||||
def headerData(self, col, orientation, role):
|
|
||||||
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
|
|
||||||
return self.header_data[col]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def flags(self, index):
|
|
||||||
# This means only the Tags column is editable
|
|
||||||
if self.temp_dir and index.column() == 4:
|
|
||||||
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
|
|
||||||
else:
|
|
||||||
# These are standard select but don't edit values
|
|
||||||
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
|
|
||||||
|
|
||||||
def setData(self, index, value, role=QtCore.Qt.EditRole):
|
|
||||||
# We don't need to connect this to dataChanged since the underlying
|
|
||||||
# table model (not the proxy model) is the one that's being updated
|
|
||||||
|
|
||||||
# Database tags for files should not be updated each time
|
|
||||||
# a new folder gets added or deleted from the directory
|
|
||||||
# This will be done @ runtime
|
|
||||||
# Individually set file tags will be preserved
|
|
||||||
# Duplicate file tags will be removed
|
|
||||||
|
|
||||||
row = index.row()
|
|
||||||
col = index.column()
|
|
||||||
self.display_data[row][col] = value
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class TableProxyModel2(QtCore.QSortFilterProxyModel):
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super(TableProxyModel2, self).__init__(parent)
|
|
||||||
self.filter_string = None
|
|
||||||
self.filter_columns = None
|
|
||||||
self.active_library_filters = None
|
|
||||||
|
|
||||||
def setFilterParams(self, filter_text, filter_columns, active_library_filters):
|
|
||||||
self.filter_string = filter_text.lower()
|
|
||||||
self.filter_columns = filter_columns
|
|
||||||
self.active_library_filters = [i.lower() for i in active_library_filters]
|
|
||||||
|
|
||||||
def filterAcceptsRow(self, row_num, parent):
|
|
||||||
if self.filter_string is None or self.filter_columns is None:
|
|
||||||
return True
|
|
||||||
|
|
||||||
model = self.sourceModel()
|
|
||||||
|
|
||||||
valid_indices = [model.index(row_num, i) for i in self.filter_columns]
|
|
||||||
valid_data = [
|
|
||||||
model.data(i, QtCore.Qt.DisplayRole).lower() for i in valid_indices if model.data(
|
|
||||||
i, QtCore.Qt.DisplayRole) is not None]
|
|
||||||
|
|
||||||
try:
|
|
||||||
valid_data.extend([model.display_data[row_num][7], model.display_data[row_num][8]])
|
|
||||||
except IndexError: # Columns 7 and 8 are added after creation of the model
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Filter out all books not in the active library filters
|
|
||||||
if self.active_library_filters:
|
|
||||||
current_library_name = valid_data[-2].lower()
|
|
||||||
if current_library_name not in self.active_library_filters:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for i in valid_data:
|
|
||||||
if i:
|
|
||||||
if self.filter_string in i:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class MostExcellentFileSystemModel(QtWidgets.QFileSystemModel):
|
class MostExcellentFileSystemModel(QtWidgets.QFileSystemModel):
|
||||||
# Directories are tracked on the basis of their paths
|
# Directories are tracked on the basis of their paths
|
||||||
# Poll the tag_data dictionary to get User selection
|
# Poll the tag_data dictionary to get User selection
|
||||||
|
Reference in New Issue
Block a user