diff --git a/README.md b/README.md index 44ef051..43f8b94 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Currently supports: * cbr / cbz ## Contribute +[Paypal](https://www.paypal.me/supportlector) Bitcoin: 17jaxj26vFJNqQ2hEVerbBV5fpTusfqFro ## Requirements diff --git a/lector/__main__.py b/lector/__main__.py index e8d249f..8386682 100755 --- a/lector/__main__.py +++ b/lector/__main__.py @@ -34,9 +34,9 @@ from PyQt5 import QtWidgets, QtGui, QtCore # Init logging # Must be done first and at the module level # or it won't work properly in case of the imports below -from lector.logger import init_logging +from lector.logger import init_logging, VERSION logger = init_logging(sys.argv) -logger.log(60, 'Application started') +logger.log(60, f'Lector {VERSION} - Application started') from lector import database from lector import sorter @@ -127,6 +127,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): # Statusbar widgets self.statusMessage.setObjectName('statusMessage') self.statusBar.addPermanentWidget(self.statusMessage) + self.errorButton = QtWidgets.QPushButton(self.statusBar) + self.errorButton.setIcon(QtGui.QIcon(':/images/error.svg')) + self.errorButton.setFlat(True) + self.errorButton.setVisible(False) + self.errorButton.setToolTip('What hast thou done?') + self.errorButton.clicked.connect(self.show_errors) + self.statusBar.addPermanentWidget(self.errorButton) self.sorterProgress = QtWidgets.QProgressBar() self.sorterProgress.setMaximumWidth(300) self.sorterProgress.setObjectName('sorterProgress') @@ -375,7 +382,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.settings, self.temp_dir.path()) - parsed_books = books.initiate_threads() + parsed_books, errors = books.initiate_threads() if not parsed_books and not open_files_after_processing: return @@ -386,7 +393,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): if open_files_after_processing: self.open_files(file_dict) - self.move_on() + self.move_on(errors) def open_files(self, path_hash_dictionary): # file_paths is expected to be a dictionary @@ -461,45 +468,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.tabWidget.setCurrentIndex(self.tabWidget.count() - 1) - def start_culling_timer(self): - if self.settings['perform_culling']: - self.culling_timer.start(30) - - def resizeEvent(self, event=None): - if event: - # This implies a vertical resize event only - # We ain't about that lifestyle - if event.oldSize().width() == event.size().width(): - return - - # The hackiness of this hack is just... - default_size = 170 # This is size of the QIcon (160 by default) + - # minimum margin needed between thumbnails - - # for n icons, the n + 1th icon will appear at > n +1.11875 - # First, calculate the number of images per row - i = self.listView.viewport().width() / default_size - rem = i - int(i) - if rem >= .21875 and rem <= .9999: - num_images = int(i) - else: - num_images = int(i) - 1 - - # The rest is illustrated using informative variable names - space_occupied = num_images * default_size - # 12 is the scrollbar width - # Larger numbers keep reduce flickering but also increase - # the distance from the scrollbar - space_left = ( - self.listView.viewport().width() - space_occupied - 19) - try: - layout_extra_space_per_image = space_left // num_images - self.listView.setGridSize( - QtCore.QSize(default_size + layout_extra_space_per_image, 250)) - self.start_culling_timer() - except ZeroDivisionError: # Initial resize is ignored - return - def add_books(self): dialog_prompt = self._translate('Main_UI', 'Add books to database') ebooks_string = self._translate('Main_UI', 'eBooks') @@ -519,7 +487,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.statusMessage.setText(self._translate('Main_UI', 'Adding books...')) self.thread = BackGroundBookAddition( opened_files[0], self.database_path, 'manual', self) - self.thread.finished.connect(self.move_on) + self.thread.finished.connect( + lambda: self.move_on(self.thread.errors)) self.thread.start() def get_selection(self): @@ -584,7 +553,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): if self.tabWidget.currentIndex() == 0: self.delete_books() - def move_on(self): + def move_on(self, errors=None): self.settingsDialog.okButton.setEnabled(True) self.settingsDialog.okButton.setToolTip( self._translate('Main_UI', 'Save changes and start library scan')) @@ -593,8 +562,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.sorterProgress.setVisible(False) self.sorterProgress.setValue(0) - if self.libraryToolBar.searchBar.text() == '': - self.statusBar.setVisible(False) + # The errors argument is a list and will only be present + # in case of addition and reading + if errors: + self.display_error_notification(errors) + else: + if self.libraryToolBar.searchBar.text() == '': + self.statusBar.setVisible(False) self.lib_ref.update_proxymodels() self.lib_ref.generate_library_tags() @@ -735,6 +709,20 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.open_files(path) + def display_error_notification(self, errors): + self.statusBar.setVisible(True) + self.errorButton.setVisible(True) + + def show_errors(self): + # TODO + # Create a separate viewing area for errors + # before showing the log + + self.show_settings(3) + self.settingsDialog.aboutTabWidget.setCurrentIndex(1) + self.errorButton.setVisible(False) + self.statusBar.setVisible(False) + def statusbar_visibility(self): if self.sender() == self.libraryToolBar.searchBar: if self.libraryToolBar.searchBar.text() == '': @@ -745,12 +733,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): def show_settings(self, stacked_widget_index): if not self.settingsDialog.isVisible(): self.settingsDialog.show() - self.settingsDialog.okButton.setVisible(False) index = self.settingsDialog.listModel.index( stacked_widget_index, 0) self.settingsDialog.listView.setCurrentIndex(index) - self.settingsDialog.stackedWidget.setCurrentIndex( - stacked_widget_index) else: self.settingsDialog.hide() @@ -983,6 +968,45 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.start_culling_timer() + def start_culling_timer(self): + if self.settings['perform_culling']: + self.culling_timer.start(30) + + def resizeEvent(self, event=None): + if event: + # This implies a vertical resize event only + # We ain't about that lifestyle + if event.oldSize().width() == event.size().width(): + return + + # The hackiness of this hack is just... + default_size = 170 # This is size of the QIcon (160 by default) + + # minimum margin needed between thumbnails + + # for n icons, the n + 1th icon will appear at > n +1.11875 + # First, calculate the number of images per row + i = self.listView.viewport().width() / default_size + rem = i - int(i) + if rem >= .21875 and rem <= .9999: + num_images = int(i) + else: + num_images = int(i) - 1 + + # The rest is illustrated using informative variable names + space_occupied = num_images * default_size + # 12 is the scrollbar width + # Larger numbers keep reduce flickering but also increase + # the distance from the scrollbar + space_left = ( + self.listView.viewport().width() - space_occupied - 19) + try: + layout_extra_space_per_image = space_left // num_images + self.listView.setGridSize( + QtCore.QSize(default_size + layout_extra_space_per_image, 250)) + self.start_culling_timer() + except ZeroDivisionError: # Initial resize is ignored + return + def closeEvent(self, event=None): if event: event.ignore() diff --git a/lector/logger.py b/lector/logger.py index b8d94d7..77f6b57 100644 --- a/lector/logger.py +++ b/lector/logger.py @@ -14,20 +14,24 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +VERSION = '0.4.nowGIT' + import os import logging from PyQt5 import QtCore +location_prefix = os.path.join( + QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation), + 'Lector') +logger_filename = os.path.join(location_prefix, 'Lector.log') + def init_logging(cli_arguments): # This needs a separate 'Lector' in the os.path.join because # application name isn't explicitly set in this module - location_prefix = os.path.join( - QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation), - 'Lector') + os.makedirs(location_prefix, exist_ok=True) - logger_filename = os.path.join(location_prefix, 'Lector.log') log_level = 30 # Warning and above # Set log level according to command line arguments diff --git a/lector/models.py b/lector/models.py index c6baf26..7cdd774 100644 --- a/lector/models.py +++ b/lector/models.py @@ -343,4 +343,3 @@ class MostExcellentFileSystemModel(QtWidgets.QFileSystemModel): for i in deletable: del self.tag_data[i] - diff --git a/lector/resources/about.html b/lector/resources/about.html index 38d87ba..7470f08 100644 --- a/lector/resources/about.html +++ b/lector/resources/about.html @@ -10,6 +10,7 @@

Author: BasioMeusPuga disgruntled.mob@gmail.com

Page: https://github.com/BasioMeusPuga/Lector

License: GPLv3 https://www.gnu.org/licenses/gpl-3.0.en.html

+

Donate (Paypal): https://www.paypal.me/supportlector

Donate (Bitcoin): 17jaxj26vFJNqQ2hEVerbBV5fpTusfqFro

 

diff --git a/lector/resources/raw/settings.ui b/lector/resources/raw/settings.ui index 2500654..9f2ab01 100644 --- a/lector/resources/raw/settings.ui +++ b/lector/resources/raw/settings.ui @@ -15,7 +15,7 @@ - + 0 @@ -610,15 +610,39 @@ Reopen book to see changes - + - - - true - - - false + + + 0 + + + About + + + + + + true + + + false + + + + + + + + Log + + + + + + + @@ -627,6 +651,20 @@ Reopen book to see changes + + + + Reset Application + + + + + + + Clear Log + + + @@ -660,6 +698,13 @@ Reopen book to see changes + + + SaysHelloWhenClicked + QListView +
lector.widgets
+
+
diff --git a/lector/resources/settingswindow.py b/lector/resources/settingswindow.py index b320e3e..429bc0f 100644 --- a/lector/resources/settingswindow.py +++ b/lector/resources/settingswindow.py @@ -14,7 +14,7 @@ class Ui_Dialog(object): Dialog.resize(1139, 612) self.gridLayout = QtWidgets.QGridLayout(Dialog) self.gridLayout.setObjectName("gridLayout") - self.listView = QtWidgets.QListView(Dialog) + self.listView = SaysHelloWhenClicked(Dialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -304,17 +304,39 @@ class Ui_Dialog(object): self.stackedWidget.addWidget(self.annotationsPage) self.aboutPage = QtWidgets.QWidget() self.aboutPage.setObjectName("aboutPage") - self.gridLayout_6 = QtWidgets.QGridLayout(self.aboutPage) + self.gridLayout_9 = QtWidgets.QGridLayout(self.aboutPage) + self.gridLayout_9.setObjectName("gridLayout_9") + self.aboutTabWidget = QtWidgets.QTabWidget(self.aboutPage) + self.aboutTabWidget.setObjectName("aboutTabWidget") + self.aboutTab = QtWidgets.QWidget() + self.aboutTab.setObjectName("aboutTab") + self.gridLayout_6 = QtWidgets.QGridLayout(self.aboutTab) self.gridLayout_6.setObjectName("gridLayout_6") - self.aboutBox = QtWidgets.QTextBrowser(self.aboutPage) + self.aboutBox = QtWidgets.QTextBrowser(self.aboutTab) self.aboutBox.setOpenExternalLinks(True) self.aboutBox.setOpenLinks(False) self.aboutBox.setObjectName("aboutBox") self.gridLayout_6.addWidget(self.aboutBox, 0, 0, 1, 1) + self.aboutTabWidget.addTab(self.aboutTab, "") + self.logTab = QtWidgets.QWidget() + self.logTab.setObjectName("logTab") + self.gridLayout_10 = QtWidgets.QGridLayout(self.logTab) + self.gridLayout_10.setObjectName("gridLayout_10") + self.logBox = QtWidgets.QPlainTextEdit(self.logTab) + self.logBox.setObjectName("logBox") + self.gridLayout_10.addWidget(self.logBox, 0, 0, 1, 1) + self.aboutTabWidget.addTab(self.logTab, "") + self.gridLayout_9.addWidget(self.aboutTabWidget, 0, 0, 1, 1) self.stackedWidget.addWidget(self.aboutPage) self.verticalLayout_4.addWidget(self.stackedWidget) self.horizontalLayout_10 = QtWidgets.QHBoxLayout() self.horizontalLayout_10.setObjectName("horizontalLayout_10") + self.resetButton = QtWidgets.QPushButton(Dialog) + self.resetButton.setObjectName("resetButton") + self.horizontalLayout_10.addWidget(self.resetButton) + self.clearLogButton = QtWidgets.QPushButton(Dialog) + self.clearLogButton.setObjectName("clearLogButton") + self.horizontalLayout_10.addWidget(self.clearLogButton) spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_10.addItem(spacerItem3) self.okButton = QtWidgets.QPushButton(Dialog) @@ -328,6 +350,7 @@ class Ui_Dialog(object): self.retranslateUi(Dialog) self.tabWidget.setCurrentIndex(0) + self.aboutTabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): @@ -371,6 +394,11 @@ class Ui_Dialog(object): self.moveDown.setToolTip(_translate("Dialog", "Move Down")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.textTab), _translate("Dialog", "Text")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.imageTab), _translate("Dialog", "Image")) + self.aboutTabWidget.setTabText(self.aboutTabWidget.indexOf(self.aboutTab), _translate("Dialog", "About")) + self.aboutTabWidget.setTabText(self.aboutTabWidget.indexOf(self.logTab), _translate("Dialog", "Log")) + self.resetButton.setText(_translate("Dialog", "Reset Application")) + self.clearLogButton.setText(_translate("Dialog", "Clear Log")) self.okButton.setText(_translate("Dialog", "Scan Library")) self.cancelButton.setText(_translate("Dialog", "Close")) +from lector.widgets import SaysHelloWhenClicked diff --git a/lector/settingsdialog.py b/lector/settingsdialog.py index 0f7eb83..a6e80bf 100644 --- a/lector/settingsdialog.py +++ b/lector/settingsdialog.py @@ -30,6 +30,7 @@ from lector.models import MostExcellentFileSystemModel from lector.threaded import BackGroundBookSearch, BackGroundBookAddition from lector.resources import settingswindow from lector.settings import Settings +from lector.logger import logger_filename, VERSION logger = logging.getLogger(__name__) @@ -55,7 +56,10 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): install_dir = pathlib.Path(install_dir).parents[1] aboutfile_path = os.path.join(install_dir, 'lector', 'resources', 'about.html') with open(aboutfile_path) as about_html: - self.aboutBox.setHtml(about_html.read()) + html = about_html.readlines() + html.insert( + 8, f'

v{VERSION}

\n') + self.aboutBox.setHtml(''.join(html)) self.paths = None self.thread = None @@ -120,7 +124,7 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): self.largeIncrementBox.valueChanged.connect(self.change_increment) # Generate the QStandardItemModel for the listView - self.listModel = QtGui.QStandardItemModel() + self.listModel = QtGui.QStandardItemModel(self.listView) library_string = self._translate('SettingsUI', 'Library') switches_string = self._translate('SettingsUI', 'Switches') @@ -143,7 +147,9 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): self.main_window.QImageFactory.get_image(this_icon)) self.listModel.appendRow(item) self.listView.setModel(self.listModel) - self.listView.clicked.connect(self.page_switch) + + # Custom signal to account for page changes + self.listView.newIndexSignal.connect(self.list_index_changed) # Annotation related buttons # Icon names @@ -175,11 +181,37 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): # Generate the filesystem treeView self.generate_tree() + # About... About + self.aboutTabWidget.setDocumentMode(True) + self.aboutTabWidget.setContentsMargins(0, 0, 0, 0) + self.logBox.setReadOnly(True) + + # About buttons + self.resetButton.clicked.connect(self.delete_database) + self.clearLogButton.clicked.connect(self.clear_log) + # Hide the image annotation tab # TODO # Maybe get off your lazy ass and write something for this + self.tabWidget.setContentsMargins(0, 0, 0, 0) self.tabWidget.tabBar().setVisible(False) + def list_index_changed(self, index): + switch_to = index.row() + self.stackedWidget.setCurrentIndex(switch_to) + + valid_buttons = { + 0: (self.okButton,), + 3: (self.resetButton, self.clearLogButton),} + + for i in valid_buttons: + if i == switch_to: + for j in valid_buttons[i]: + j.setVisible(True) + else: + for j in valid_buttons[i]: + j.setVisible(False) + def generate_tree(self): # Fetch all directories in the database paths = database.DatabaseFunctions( @@ -203,7 +235,8 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): 'check_state': i[3]} self.filesystemModel = MostExcellentFileSystemModel(directory_data) - self.filesystemModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Dirs) + self.filesystemModel.setFilter( + QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Dirs) self.treeView.setModel(self.filesystemModel) # TODO @@ -216,7 +249,8 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): # Set the treeView and QFileSystemModel to its desired state selected_paths = [ - i for i in directory_data if directory_data[i]['check_state'] == QtCore.Qt.Checked] + i for i in directory_data + if directory_data[i]['check_state'] == QtCore.Qt.Checked] expand_paths = set() for i in selected_paths: @@ -270,7 +304,6 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): self.show() treeViewIndex = self.listModel.index(0, 0) self.listView.setCurrentIndex(treeViewIndex) - self.page_switch(treeViewIndex) return except AttributeError: pass @@ -317,16 +350,10 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): # We now create a new thread to put those files into the database self.thread = BackGroundBookAddition( self.thread.valid_files, self.database_path, 'automatic', self.main_window) - self.thread.finished.connect(self.main_window.move_on) + self.thread.finished.connect( + lambda: self.main_window.move_on(self.thread.errors)) self.thread.start() - def page_switch(self, index): - self.stackedWidget.setCurrentIndex(index.row()) - if index.row() == 0: - self.okButton.setVisible(True) - else: - self.okButton.setVisible(False) - def cancel_pressed(self): self.filesystemModel.tag_data = copy.deepcopy(self.tag_data_copy) self.hide() @@ -336,8 +363,15 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): event.accept() def showEvent(self, event): + # Load log into the plainTextEdit + with open(logger_filename) as infile: + log_text = infile.read() + self.logBox.setPlainText(log_text) + # Annotation preview self.format_preview() + # Make copy of tags in case of a nope.jpg self.tag_data_copy = copy.deepcopy(self.filesystemModel.tag_data) + event.accept() def no_more_settings(self): @@ -497,3 +531,30 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): annotations_out.append(annotation_data) self.main_window.settings['annotations'] = annotations_out + + def delete_database(self): + def ifcontinue(box_button): + if box_button.text() != '&Yes': + return + + database_filename = os.path.join( + self.main_window.database_path, 'Lector.db') + os.remove(database_filename) + QtWidgets.qApp.exit() + + # Generate a message box to confirm deletion + confirm_deletion = QtWidgets.QMessageBox() + deletion_prompt = self._translate( + 'SettingsUI', f'Delete database and exit?') + confirm_deletion.setText(deletion_prompt) + confirm_deletion.setIcon(QtWidgets.QMessageBox.Critical) + confirm_deletion.setWindowTitle(self._translate('SettingsUI', 'Confirm')) + confirm_deletion.setStandardButtons( + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) + confirm_deletion.buttonClicked.connect(ifcontinue) + confirm_deletion.show() + confirm_deletion.exec_() + + def clear_log(self): + self.logBox.clear() + open(logger_filename, 'w').close() diff --git a/lector/sorter.py b/lector/sorter.py index aa71f95..625372f 100644 --- a/lector/sorter.py +++ b/lector/sorter.py @@ -123,6 +123,7 @@ class BookSorter: self.threading_completed = [] self.queue = Manager().Queue() + self.errors = Manager().list() self.processed_books = [] if self.work_mode == 'addition': @@ -214,8 +215,9 @@ class BookSorter: try: book_ref.read_book() except Exception as e: - this_error = f'Error initializing: {filename} {type(e).__name__} Arguments: {e.args}' - logger.exception(this_error) + this_error = f'Error initializing: {filename}' + self.errors.append(this_error) + logger.exception(this_error + f' {type(e).__name__} Arguments: {e.args}') return this_book = {} @@ -228,9 +230,9 @@ class BookSorter: try: metadata = book_ref.generate_metadata() except Exception as e: - this_error = ( - f'Metadata generation error: {filename} {type(e).__name__} Arguments: {e.args}') - logger.exception(this_error) + this_error = f'Metadata generation error: {filename}' + self.errors.append(this_error) + logger.exception(this_error + f' {type(e).__name__} Arguments: {e.args}') return title = metadata.title @@ -257,9 +259,9 @@ class BookSorter: try: book_breakdown = book_ref.generate_content() except Exception as e: - this_error = ( - f'Content generation error: {filename} {type(e).__name__} Arguments: {e.args}') - logger.exception(this_error) + this_error = f'Content generation error: {filename}' + self.errors.append(this_error) + logger.exception(this_error + f' {type(e).__name__} Arguments: {e.args}') return toc = book_breakdown[0] @@ -347,7 +349,8 @@ class BookSorter: del self.processed_books processing_time = str(time.time() - start_time) logger.info('Finished processing in ' + processing_time) - return return_books + + return return_books, self.errors def progress_object_generator(): diff --git a/lector/threaded.py b/lector/threaded.py index e9eae91..4702881 100644 --- a/lector/threaded.py +++ b/lector/threaded.py @@ -55,6 +55,7 @@ class BackGroundBookAddition(QtCore.QThread): self.database_path = database_path self.addition_mode = addition_mode self.main_window = main_window + self.errors = [] self.prune_required = True if self.addition_mode == 'manual': @@ -68,7 +69,7 @@ class BackGroundBookAddition(QtCore.QThread): self.main_window.settings, self.main_window.temp_dir.path()) - parsed_books = books.initiate_threads() + parsed_books, self.errors = books.initiate_threads() self.main_window.lib_ref.generate_model('addition', parsed_books, False) database.DatabaseFunctions(self.database_path).add_to_database(parsed_books) diff --git a/lector/widgets.py b/lector/widgets.py index 9f8b1df..ec16acd 100644 --- a/lector/widgets.py +++ b/lector/widgets.py @@ -683,3 +683,19 @@ class DragDropTableView(QtWidgets.QTableView): event.acceptProposedAction() else: super(DragDropTableView, self).dropEvent(event) + + +class SaysHelloWhenClicked(QtWidgets.QListView): + # Signal declarations must be outside the constructor + # The argument is the type of the data emitted + newIndexSignal = QtCore.pyqtSignal(QtCore.QModelIndex) + + def __init__(self, parent): + super(SaysHelloWhenClicked, self).__init__(parent) + self.parent = parent + + def currentChanged(self, index, previous_index): + if not index.isValid(): + return + + self.newIndexSignal.emit(index) diff --git a/setup.py b/setup.py index 5aedc16..2636ffd 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,10 @@ import codecs from os import path from setuptools import setup, find_packages +from lector.logger import VERSION HERE = path.abspath(path.dirname(__file__)) -MAJOR_VERSION = '0' -MINOR_VERSION = '4' -MICRO_VERSION = '1' -VERSION = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION) - # Get the long description from the README file with codecs.open(path.join(HERE, 'README.md'), encoding='utf-8') as f: LONG_DESC = f.read() @@ -73,6 +69,6 @@ setup( extras_require={ 'dev': DEV_DEPS, 'test': TEST_DEPS, - 'PDF': ['python-poppler-qt5'] + 'PDF': ['pymupdf'] }, )