diff --git a/__main__.py b/__main__.py index bcb89a7..e881f87 100755 --- a/__main__.py +++ b/__main__.py @@ -22,9 +22,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): super(MainUI, self).__init__() self.setupUi(self) - # Initialize settings dialog - self.settings_dialog = SettingsUI() - # Empty variables that will be infested soon self.current_view = None self.last_open_books = None @@ -36,6 +33,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.current_profile_index = None self.database_path = None self.table_header_sizes = None + self.settings_dialog_settings = None # Initialize application Settings(self).read_settings() # This should populate all variables that need @@ -43,7 +41,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): # Create the database in case it doesn't exist database.DatabaseInit(self.database_path) - self.settings_dialog.database_path = self.database_path + + # Initialize settings dialog + self.settings_dialog = SettingsUI(self) # Create and right align the statusbar label widget self.statusMessage = QtWidgets.QLabel() diff --git a/database.py b/database.py index 874788a..9907a26 100644 --- a/database.py +++ b/database.py @@ -32,6 +32,21 @@ class DatabaseFunctions: database_path = os.path.join(location_prefix, 'Lector.db') self.database = sqlite3.connect(database_path) + def set_library_paths(self, data_iterable): + for i in data_iterable: + path = i[0] + name = i[1] + tags = i[2] + + # TODO + # Get insert or replace working + + sql_command = ("INSERT OR REPLACE INTO directories (Path,Name,Tags) VALUES (?, ?, ?)") + self.database.execute(sql_command, [path, name, tags]) + + self.database.commit() + self.close_database() + def add_to_database(self, data): # data is expected to be a dictionary # with keys corresponding to the book hash @@ -145,7 +160,7 @@ class DatabaseFunctions: self.database.commit() self.close_database() - + def close_database(self): self.database.execute("VACUUM") self.database.close() diff --git a/library.py b/library.py index 80b3504..b807688 100644 --- a/library.py +++ b/library.py @@ -5,7 +5,7 @@ import pickle import database from PyQt5 import QtWidgets, QtGui, QtCore -from models import LibraryItemModel, LibraryTableModel, TableProxyModel +from models import LibraryItemModel, MostExcellentTableModel, TableProxyModel class Library: @@ -133,7 +133,7 @@ class Library: def create_table_model(self): table_header = ['Title', 'Author', 'Status', 'Year', 'Tags'] - self.table_model = LibraryTableModel( + self.table_model = MostExcellentTableModel( table_header, self.table_rows, self.parent_window.temp_dir.path()) self.create_table_proxy_model() diff --git a/models.py b/models.py index 7da8aa6..b263f27 100644 --- a/models.py +++ b/models.py @@ -12,7 +12,7 @@ class LibraryItemModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel): super(LibraryItemModel, self).__init__(parent) -class LibraryTableModel(QtCore.QAbstractTableModel): +class MostExcellentTableModel(QtCore.QAbstractTableModel): # Sorting is taken care of by the QSortFilterProxy model # which has an inbuilt sort method @@ -21,13 +21,16 @@ class LibraryTableModel(QtCore.QAbstractTableModel): # In this case, that's self.data_list def __init__(self, header_data, display_data, temp_dir=None, parent=None): - super(LibraryTableModel, self).__init__(parent) + super(MostExcellentTableModel, self).__init__(parent) self.header_data = header_data self.display_data = display_data self.temp_dir = temp_dir def rowCount(self, parent): - return len(self.display_data) + if self.display_data: + return len(self.display_data) + else: + return 0 def columnCount(self, parent): return len(self.header_data) @@ -53,7 +56,8 @@ class LibraryTableModel(QtCore.QAbstractTableModel): total_chapters = position['total_chapters'] return_pixmap = pie_chart.pixmapper( - current_chapter, total_chapters, self.temp_dir, QtCore.Qt.SizeHintRole + 10) + current_chapter, total_chapters, self.temp_dir, + QtCore.Qt.SizeHintRole + 10) return return_pixmap @@ -79,6 +83,14 @@ class LibraryTableModel(QtCore.QAbstractTableModel): return self.header_data[col] return None + def flags(self, index): + # In case of the settings model, model column index 1+ are editable + if not self.temp_dir and index.column() != 0: + 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 + class TableProxyModel(QtCore.QSortFilterProxyModel): def __init__(self, parent=None): diff --git a/resources/raw/settings.ui b/resources/raw/settings.ui index dc0cbc5..cf4b6f6 100644 --- a/resources/raw/settings.ui +++ b/resources/raw/settings.ui @@ -36,8 +36,11 @@ true + + QAbstractItemView::SingleSelection + - QAbstractItemView::SelectRows + QAbstractItemView::SelectItems Qt::NoPen @@ -59,7 +62,7 @@ - + Search for Paths, Names, Tags... diff --git a/resources/settingswindow.py b/resources/settingswindow.py index 697da0c..886295f 100644 --- a/resources/settingswindow.py +++ b/resources/settingswindow.py @@ -25,7 +25,8 @@ class Ui_Dialog(object): self.tableView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow) self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked|QtWidgets.QAbstractItemView.EditKeyPressed) self.tableView.setAlternatingRowColors(True) - self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) self.tableView.setGridStyle(QtCore.Qt.NoPen) self.tableView.setSortingEnabled(True) self.tableView.setWordWrap(False) @@ -35,9 +36,9 @@ class Ui_Dialog(object): self.gridLayout_2.addWidget(self.tableView, 0, 0, 1, 1) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") - self.lineEdit = QtWidgets.QLineEdit(self.groupBox_2) - self.lineEdit.setObjectName("lineEdit") - self.horizontalLayout.addWidget(self.lineEdit) + self.tableFilterEdit = QtWidgets.QLineEdit(self.groupBox_2) + self.tableFilterEdit.setObjectName("tableFilterEdit") + self.horizontalLayout.addWidget(self.tableFilterEdit) self.addButton = QtWidgets.QPushButton(self.groupBox_2) self.addButton.setObjectName("addButton") self.horizontalLayout.addWidget(self.addButton) @@ -87,7 +88,7 @@ class Ui_Dialog(object): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Settings")) self.groupBox_2.setTitle(_translate("Dialog", "Library")) - self.lineEdit.setPlaceholderText(_translate("Dialog", "Search for Paths, Names, Tags...")) + self.tableFilterEdit.setPlaceholderText(_translate("Dialog", "Search for Paths, Names, Tags...")) self.addButton.setText(_translate("Dialog", "Add")) self.removeButton.setText(_translate("Dialog", "Remove")) self.refreshButton.setText(_translate("Dialog", "Refresh")) diff --git a/settings.py b/settings.py index a960706..28fad8b 100644 --- a/settings.py +++ b/settings.py @@ -67,8 +67,16 @@ class Settings: self.settings.beginGroup('lastOpen') self.parent_window.last_open_books = self.settings.value('lastOpenFiles', []) self.parent_window.last_open_tab = self.settings.value('lastOpenTab', 'library') - self.parent_window.settings_dialog.last_open_directory = self.settings.value( - 'settingsLastOpenDirectory', os.path.expanduser('~')) + self.settings.endGroup() + + self.settings.beginGroup('settingsWindow') + self.parent_window.settings_dialog_settings = {} + self.parent_window.settings_dialog_settings['size'] = self.settings.value( + 'windowSize', QtCore.QSize(700, 500)) + self.parent_window.settings_dialog_settings['position'] = self.settings.value( + 'windowPosition', QtCore.QPoint(0, 0)) + self.parent_window.settings_dialog_settings['headers'] = self.settings.value( + 'tableHeaders', [200, 150]) self.settings.endGroup() def save_settings(self): @@ -113,6 +121,9 @@ class Settings: self.settings.beginGroup('lastOpen') self.settings.setValue('lastOpenFiles', self.parent_window.last_open_books) self.settings.setValue('lastOpenTab', last_open_tab) - self.settings.setValue( - 'settingsLastOpenDirectory', self.parent_window.settings_dialog.last_open_directory) self.settings.endGroup() + + self.settings.beginGroup('settingsWindow') + self.settings.setValue('windowSize', self.parent_window.settings_dialog.window_size) + self.settings.setValue('windowPosition', self.parent_window.settings_dialog.window_position) + self.settings.setValue('tableHeaders', self.parent_window.settings_dialog.table_headers) diff --git a/settingsdialog.py b/settingsdialog.py index 7c91f15..b0b5e60 100644 --- a/settingsdialog.py +++ b/settingsdialog.py @@ -7,47 +7,94 @@ from PyQt5 import QtWidgets, QtGui, QtCore import database from resources import settingswindow +from models import MostExcellentTableModel, TableProxyModel from threaded import BackGroundBookSearch, BackGroundBookAddition class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): - def __init__(self): + def __init__(self, parent_window): super(SettingsUI, self).__init__() self.setupUi(self) - # Will be overwritten by settings - self.last_open_directory = None - self.database_path = None + # These are just for declarative purposes + self.window_size = None + self.window_position = None + self.table_headers = [] - self.database_data = collections.OrderedDict() - self.database_modification = False + self.last_open_directory = None + self.parent_window = parent_window + self.database_path = self.parent_window.database_path + self.resize(self.parent_window.settings_dialog_settings['size']) + self.move(self.parent_window.settings_dialog_settings['position']) + + self.table_model = None + self.table_proxy_model = None self.thread = None + self.tableFilterEdit.textChanged.connect(self.update_table_proxy_model) self.addButton.clicked.connect(self.add_directories) + self.generate_table() + header_sizes = self.parent_window.settings_dialog_settings['headers'] + if header_sizes: + for count, i in enumerate(header_sizes): + self.tableView.horizontalHeader().resizeSection(count, int(i)) + + self.tableView.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.Interactive) + self.tableView.horizontalHeader().setHighlightSections(False) + self.tableView.horizontalHeader().setStretchLastSection(True) + + # self.tableView.horizontalHeader().setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch) + + # self.database_data = collections.OrderedDict() + # self.database_modification = False + def generate_table(self): # Fetch all directories in the database paths = database.DatabaseFunctions( self.database_path).fetch_data( - ('*',), + ('Path', 'Name', 'Tags'), 'directories', {'Path': ''}, 'LIKE') if not paths: print('Database returned no paths for settings...') - return - for i in paths: - pass + table_header = ['Path', 'Name', 'Tags'] + self.table_model = MostExcellentTableModel( + table_header, paths, None) + self.create_table_proxy_model() + + def create_table_proxy_model(self): + self.table_proxy_model = TableProxyModel() + self.table_proxy_model.setSourceModel(self.table_model) + self.table_proxy_model.setSortCaseSensitivity(False) + self.table_proxy_model.sort(1, QtCore.Qt.AscendingOrder) + self.tableView.setModel(self.table_proxy_model) + self.tableView.horizontalHeader().setSortIndicator( + 1, QtCore.Qt.AscendingOrder) + + def update_table_proxy_model(self): + self.table_proxy_model.invalidateFilter() + self.table_proxy_model.setFilterParams( + self.tableFilterEdit.text(), [0, 1, 2]) + self.table_proxy_model.setFilterFixedString( + self.tableFilterEdit.text()) def add_directories(self): add_directory = QtWidgets.QFileDialog.getExistingDirectory( self, 'Select Directory', self.last_open_directory, QtWidgets.QFileDialog.ShowDirsOnly) + data_pair = [[add_directory, None, None]] + database.DatabaseFunctions(self.database_path).set_library_paths(data_pair) + + self.generate_table() + # Directories will be added recursively # Sub directory addition is allowed in that files will not # be duplicated. However, any additional tags will get @@ -63,9 +110,28 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): # have to go into the threaded module # Traverse directories looking for files + + def parse_all(self, directories): + add_directory = None self.thread = BackGroundBookSearch(self, add_directory) self.thread.finished.connect(self.do_something) self.thread.start() def do_something(self): print('Book search completed') + + def closeEvent(self, event): + self.no_more_settings() + event.accept() + + def hideEvent(self, event): + self.no_more_settings() + event.accept() + + def no_more_settings(self): + self.parent_window.libraryToolBar.settingsButton.setChecked(False) + self.window_size = self.size() + self.window_position = self.pos() + self.table_headers = [] + for i in range(2): + self.table_headers.append(self.tableView.horizontalHeader().sectionSize(i))