diff --git a/__main__.py b/__main__.py index 260cc23..d113973 100755 --- a/__main__.py +++ b/__main__.py @@ -14,6 +14,7 @@ ✓ Image reflow ✓ Search bar in toolbar ✓ Shift focus to the tab that has the book open + Tie file deletion and tab closing to model updates ? Create emblem per filetype Look into how you might group icons Ignore a / the / numbers for sorting purposes @@ -63,7 +64,8 @@ import database import sorter from widgets import LibraryToolBar, BookToolBar, Tab, LibraryDelegate -from subclasses import Settings, Library +from library import Library +from settings import Settings class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): @@ -242,7 +244,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.bookToolBar.hide() self.libraryToolBar.show() - + if self.lib_ref.proxy_model: # Making the proxy model available doesn't affect # memory utilization at all. Bleh. @@ -287,6 +289,11 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): # We're also updating the underlying model to have real-time # updates on the read status # Find index of the model item that corresponds to the tab + + # Set a baseline model index in case the item gets deleted + # E.g It's open in a tab and deleted from the library + model_index = None + start_index = self.viewModel.index(0, 0) matching_item = self.viewModel.match( start_index, @@ -298,9 +305,11 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): model_index = self.viewModel.index(model_row, 0) current_tab.metadata[ - 'position']['current_chapter'] = self.bookToolBar.tocBox.currentIndex() + 1 - self.viewModel.setData( - model_index, current_tab.metadata['position'], QtCore.Qt.UserRole + 7) + 'position']['current_chapter'] = event + 1 + + if model_index: + self.viewModel.setData( + model_index, current_tab.metadata['position'], QtCore.Qt.UserRole + 7) current_tab.contentView.verticalScrollBar().setValue(0) current_tab.contentView.setHtml(required_content) diff --git a/subclasses.py b/library.py similarity index 55% rename from subclasses.py rename to library.py index 1f09df0..3dcefe0 100644 --- a/subclasses.py +++ b/library.py @@ -3,7 +3,9 @@ import os import pickle import database + from PyQt5 import QtWidgets, QtGui, QtCore +from widgets import MyAbsModel class Library: @@ -107,88 +109,3 @@ class Library: self.proxy_model.setSortRole( QtCore.Qt.UserRole + self.parent_window.libraryToolBar.sortingBox.currentIndex()) self.proxy_model.sort(0) - - -class Settings: - def __init__(self, parent): - self.parent_window = parent - self.settings = QtCore.QSettings('Lector', 'Lector') - - self.default_profile1 = { - 'font': 'Noto Sans', - 'foreground': '#000000', - 'background': '#d8d8d8', - 'padding': 140, - 'font_size': 20, - 'line_spacing': 1.5} - - self.default_profile2 = { - 'font': 'Roboto', - 'foreground': '#c2c2c2', - 'background': '#161616', - 'padding': 140, - 'font_size': 20, - 'line_spacing': 1.5} - - self.default_profile3 = { - 'font': 'Roboto', - 'foreground': '#657b83', - 'background': '#002b36', - 'padding': 140, - 'font_size': 20, - 'line_spacing': 1.5} - - def read_settings(self): - self.settings.beginGroup('mainWindow') - self.parent_window.resize(self.settings.value( - 'windowSize', - QtCore.QSize(1299, 748))) - self.parent_window.move(self.settings.value( - 'windowPosition', - QtCore.QPoint(286, 141))) - self.settings.endGroup() - - self.settings.beginGroup('runtimeVariables') - self.parent_window.last_open_path = self.settings.value( - 'lastOpenPath', os.path.expanduser('~')) - self.parent_window.database_path = self.settings.value( - 'databasePath', - QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation)) - self.parent_window.display_profiles = self.settings.value( - 'displayProfiles', [ - self.default_profile1, - self.default_profile2, - self.default_profile3]) - self.parent_window.current_profile_index = int(self.settings.value( - 'currentProfileIndex', 0)) - self.settings.endGroup() - - def save_settings(self): - self.settings.beginGroup('mainWindow') - self.settings.setValue('windowSize', self.parent_window.size()) - self.settings.setValue('windowPosition', self.parent_window.pos()) - self.settings.endGroup() - - self.settings.beginGroup('runtimeVariables') - self.settings.setValue('lastOpenPath', self.parent_window.last_open_path) - self.settings.setValue('databasePath', self.parent_window.database_path) - - current_profile1 = self.parent_window.bookToolBar.profileBox.itemData( - 0, QtCore.Qt.UserRole) - current_profile2 = self.parent_window.bookToolBar.profileBox.itemData( - 1, QtCore.Qt.UserRole) - current_profile3 = self.parent_window.bookToolBar.profileBox.itemData( - 2, QtCore.Qt.UserRole) - current_profile_index = self.parent_window.bookToolBar.profileBox.currentIndex() - self.settings.setValue('displayProfiles', [ - current_profile1, - current_profile2, - current_profile3]) - self.settings.setValue('currentProfileIndex', current_profile_index) - self.settings.endGroup() - - -class MyAbsModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel): - def __init__(self, parent=None): - # We're using this to be able to access the match() method - super(MyAbsModel, self).__init__(parent) diff --git a/parsers/cbz.py b/parsers/cbz.py index 8a68729..e491954 100644 --- a/parsers/cbz.py +++ b/parsers/cbz.py @@ -47,16 +47,24 @@ class ParseCBZ: # This is a brute force approach # Maybe try reading from the file as everything # matures a little bit more - tmp_dir = tempfile.mkdtemp() + temp_dir = tempfile.mkdtemp() contents = collections.OrderedDict() for count, i in enumerate(self.book.infolist()): - self.book.extract(i, path=tmp_dir) + self.book.extract(i, path=temp_dir) page_name = 'Page ' + str(count + 1) - image_path = os.path.join(tmp_dir, i.filename) + image_path = os.path.join(temp_dir, i.filename) # This does image returns. + # TODO # Image resizing, formatting - # Cleanup after exit + # Include this as a collection of absolute paths only + # Post processing can be carried out by the program + contents[page_name] = "" % image_path - return contents, tmp_dir + + file_settings = { + 'temp_dir': temp_dir, + 'images_only': True} + + return contents, file_settings diff --git a/parsers/epub.py b/parsers/epub.py index bea1da3..1235a2f 100644 --- a/parsers/epub.py +++ b/parsers/epub.py @@ -138,5 +138,10 @@ class ParseEPUB: except AttributeError: contents[title] = '' - # The 1th index is a directory that has to be cleaned up if needed - return contents, None + # Special settings that have to be returned with the file + # Referenced in sorter.py + file_settings = { + 'temp_dir': None, + 'images_only': False} + + return contents, file_settings diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..880eba0 --- /dev/null +++ b/settings.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +import os +from PyQt5 import QtCore + + +class Settings: + def __init__(self, parent): + self.parent_window = parent + self.settings = QtCore.QSettings('Lector', 'Lector') + + self.default_profile1 = { + 'font': 'Noto Sans', + 'foreground': '#000000', + 'background': '#d8d8d8', + 'padding': 140, + 'font_size': 20, + 'line_spacing': 1.5} + + self.default_profile2 = { + 'font': 'Roboto', + 'foreground': '#c2c2c2', + 'background': '#161616', + 'padding': 140, + 'font_size': 20, + 'line_spacing': 1.5} + + self.default_profile3 = { + 'font': 'Roboto', + 'foreground': '#657b83', + 'background': '#002b36', + 'padding': 140, + 'font_size': 20, + 'line_spacing': 1.5} + + def read_settings(self): + self.settings.beginGroup('mainWindow') + self.parent_window.resize(self.settings.value( + 'windowSize', + QtCore.QSize(1299, 748))) + self.parent_window.move(self.settings.value( + 'windowPosition', + QtCore.QPoint(286, 141))) + self.settings.endGroup() + + self.settings.beginGroup('runtimeVariables') + self.parent_window.last_open_path = self.settings.value( + 'lastOpenPath', os.path.expanduser('~')) + self.parent_window.database_path = self.settings.value( + 'databasePath', + QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation)) + self.parent_window.display_profiles = self.settings.value( + 'displayProfiles', [ + self.default_profile1, + self.default_profile2, + self.default_profile3]) + self.parent_window.current_profile_index = int(self.settings.value( + 'currentProfileIndex', 0)) + self.settings.endGroup() + + def save_settings(self): + self.settings.beginGroup('mainWindow') + self.settings.setValue('windowSize', self.parent_window.size()) + self.settings.setValue('windowPosition', self.parent_window.pos()) + self.settings.endGroup() + + self.settings.beginGroup('runtimeVariables') + self.settings.setValue('lastOpenPath', self.parent_window.last_open_path) + self.settings.setValue('databasePath', self.parent_window.database_path) + + current_profile1 = self.parent_window.bookToolBar.profileBox.itemData( + 0, QtCore.Qt.UserRole) + current_profile2 = self.parent_window.bookToolBar.profileBox.itemData( + 1, QtCore.Qt.UserRole) + current_profile3 = self.parent_window.bookToolBar.profileBox.itemData( + 2, QtCore.Qt.UserRole) + current_profile_index = self.parent_window.bookToolBar.profileBox.currentIndex() + self.settings.setValue('displayProfiles', [ + current_profile1, + current_profile2, + current_profile3]) + self.settings.setValue('currentProfileIndex', current_profile_index) + self.settings.endGroup() diff --git a/sorter.py b/sorter.py index 7f6b146..3029001 100644 --- a/sorter.py +++ b/sorter.py @@ -121,8 +121,17 @@ class BookSorter: if self.mode == 'reading': all_content = book_ref.get_contents() + + # get_contents() returns a tuple. Index 1 is a collection of + # special settings that depend on the kind of data being parsed. + # Currently, this includes: + # Temporary Directory temp_dir STR Deleted upon exit + # Only images included images_only BOOL Specify only paths to images + # File will not be cached on exit + content = all_content[0] - temp_dir = all_content[1] + temp_dir = all_content[1]['temp_dir'] + images_only = all_content[1]['images_only'] if not content.keys(): content['Invalid'] = 'Possible Parse Error' @@ -137,7 +146,8 @@ class BookSorter: 'path': filename, 'position': position, 'content': content, - 'temp_dir': temp_dir} + 'temp_dir': temp_dir, + 'images_only': images_only} def initiate_threads(self): diff --git a/widgets.py b/widgets.py index 4355666..2634bec 100644 --- a/widgets.py +++ b/widgets.py @@ -366,3 +366,9 @@ class LibraryDelegate(QtWidgets.QStyledItemDelegate): else: QtWidgets.QStyledItemDelegate.paint(self, painter, option, index) + + +class MyAbsModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel): + def __init__(self, parent=None): + # We're using this to be able to access the match() method + super(MyAbsModel, self).__init__(parent)