From e5931bc3b24afedaf362df0aaae0b705bb01a2e8 Mon Sep 17 00:00:00 2001 From: noembryo Date: Thu, 2 May 2024 17:51:54 +0300 Subject: [PATCH] 2.0.0.0 --- README.md | 81 +- boot_config.py | 52 +- gui_about.py | 63 +- gui_auto_info.py | 23 +- gui_edit.py | 33 +- gui_filter.py | 69 +- gui_main.py | 248 ++-- gui_main.ui | 56 +- gui_status.py | 73 +- gui_status.ui | 41 +- gui_sync_group.py | 149 +++ gui_sync_group.ui | 350 ++++++ gui_sync_item.py | 69 ++ gui_sync_item.ui | 108 ++ gui_toolbar.py | 246 ++-- gui_toolbar.ui | 119 +- images.qrc | 55 +- main.py | 2499 ++++++++++++++++++++++++++--------------- requirements.txt | 7 +- screens/screen d1.png | Bin 106937 -> 71020 bytes screens/screen l1.png | Bin 117819 -> 92145 bytes secondary.py | 1231 +++++++++++++++++--- slppu.py | 30 +- stuff/add.png | Bin 0 -> 1173 bytes stuff/del.png | Bin 0 -> 144 bytes stuff/files_add.png | Bin 0 -> 7722 bytes stuff/font.ttf | Bin 0 -> 11412 bytes stuff/power32gray.png | Bin 0 -> 2900 bytes stuff/power32red.png | Bin 0 -> 3369 bytes stuff/sync.png | Bin 0 -> 2646 bytes stuff/view-sync.png | Bin 0 -> 13757 bytes 31 files changed, 4026 insertions(+), 1576 deletions(-) create mode 100644 gui_sync_group.py create mode 100644 gui_sync_group.ui create mode 100644 gui_sync_item.py create mode 100644 gui_sync_item.ui create mode 100644 stuff/add.png create mode 100644 stuff/del.png create mode 100644 stuff/files_add.png create mode 100644 stuff/font.ttf create mode 100644 stuff/power32gray.png create mode 100644 stuff/power32red.png create mode 100644 stuff/sync.png create mode 100644 stuff/view-sync.png diff --git a/README.md b/README.md index f3d9d00..17e3957 100644 --- a/README.md +++ b/README.md @@ -11,26 +11,37 @@ **KOHighlights** is a utility for viewing and exporting the [Koreader](https://github.com/koreader/koreader)'s highlights to simple text, html, csv or markdown files. -This is a totally re-written application using the Qt framework (PySide). -The original KOHighlights (using the wxPython) can be found -[here](https://github.com/noonkey/KoHighlights), but is considered deprecated.. - -### Screenshots +___ +#### Screenshots +

+ + + + + + + + + + + + + + + + + +

-

- - - - - - -

+___ -## Usage +## Usage/Features * Load items by: * Selecting the reader's drive or any folder that contains books that where opened with Koreader. This will automatically load all the metadata files from all subdirectories. * Drag and drop files or folders. This will load the files and/or all the files inside the folders. @@ -41,26 +52,20 @@ The original KOHighlights (using the wxPython) can be found * Comma-separated values files (.csv) * Markdown files (.md) * View the highlights and various info for a book by selecting it in the list. -* Save the highlights to the "Archive" and view them, even if your reader is not connected. -* Merge highlights/Sync position from the same book that is read in two different devices and/or sync its reading position. To do it you have to: - * Load both metadata (e.g. by scanning your reader's _and_ your tablet's books). - * Select the relevant rows of the (same) book. - * If the book has the same cre_dom_version (version of the CREngine), then the "Merge/Sync" button gets activated and you get the options to sync the highlights or the position or both. -* Merge highlights/Sync position of a book with its archived version - (book's right click menu) -* Show/hide the page, date, chapter or even the highlight text while viewing or saving the highlights of the books. +* Save the highlights to the "Archive" database and view them, even if your reader is not connected. +* Merge highlights/Sync position from the same book that is read in different devices and/or sync its reading position. +* Merge highlights/Sync position of a book with its archived version. +* Show/hide the page, date, chapter or even the highlight (!) text while viewing or exporting the highlights of the books. * Double click or press the Open Book button to view the book in your system's reader. * Delete some or all the highlights of any book. * Clear/reset the .sdr folders with the metadata or the books in the eReader. ### Prerequisites -These plugins must be enabled in KOReader -* Progress sync plugin -* Reading statistics plugin +The progress sync plugin must be enabled in KOReader ### Portable In Windows, KOHighlights can run in Portable mode using a `portable_settings` directory to store its settings, that is located inside the installation directory of the app. -Because of this, it is advised to not install the app inside the `Program Files` folder if you indent to use it as portable. +Because of this, it is advised to not install the app inside the default `Program Files` folder if you indent to use it as portable. There are two ways to start the app in Portable mode: * Run the `KoHighlights Portable.exe` that is located next to the `KoHighlights.exe`. * Run `KoHighlights.exe` with a `-p` argument. @@ -71,13 +76,27 @@ Check the latest release on the [Downloads Page][ReleaseLink]. Read the version history at [App's Page](http://www.noembryo.com/apps.php?kohighlights). ## Dependencies -Should run in any system with Python 2.7.x or 3.x (more testing required) -It needs the [PySide](https://pypi.org/project/PySide/), +* **Source code:** +Should run in any system with Python 3.6+ (more testing required) +It needs the [PySide2](https://pypi.org/project/PySide2/), [BeautifulSoup4](https://pypi.org/project/beautifulsoup4/), -[future](https://pypi.org/project/future/) and +[packaging](https://pypi.org/project/packaging/) and [requests](https://pypi.org/project/requests/) libraries. -In Linux the `libqt4-sql-sqlite` package must be installed. -PySide2/PySide6 are also supported (download the archive from the releases) +In Windows, it might also need the [PyWin32](https://pypi.org/project/PyWin32/) and the [Pypiwin32](https://pypi.org/project/pypiwin32/) libraries. +PySide6 is also supported (download the archive from the releases) +* **Compiled binaries:** + * ***Windows***: + From version 2.x, KOHighlights dropped support for Windows XP. + Can run on any version of Windows from Windows 7 upwards. + For Windows 7, Microsoft Visual C++ 14.0 is required. Get it + [here](https://aka.ms/vs/17/release/vc_redist.x86.exe). + The Windows 7 32bit version also needs the KB2533623 update thats is included in [KB3063858](https://www.microsoft.com/en-us/download/details.aspx?id=47409) ([direct link](https://download.microsoft.com/download/C/9/6/C96CD606-3E05-4E1C-B201-51211AE80B1E/Windows6.1-KB3063858-x86.msu)). + * ***Linux***: + The binary is compiled using Xubuntu 18.04. + Any newer version should work. + + + ## Extra KOHighlights includes SLPPU (a converter between python and lua objects). diff --git a/boot_config.py b/boot_config.py index 80a0ab0..a173842 100644 --- a/boot_config.py +++ b/boot_config.py @@ -1,46 +1,35 @@ # coding=utf-8 -from __future__ import (absolute_import, division, print_function, unicode_literals) - import time import sys, os import traceback import gzip, json from os.path import dirname, join, isdir, expanduser +__author__ = "noEmbryo" + def _(text): # for future gettext support return text + APP_NAME = "KOHighlights" APP_DIR = dirname(os.path.abspath(sys.argv[0])) os.chdir(APP_DIR) # Set the current working directory to the app's directory -PORTABLE = False -PYTHON2 = sys.version_info < (3, 0) - USE_QT6 = False # select between PySide2/Qt5 and Pyside6/Qt6 if both are installed - -if PYTHON2: - from io import open - from codecs import open as c_open - from PySide.QtCore import qVersion +if USE_QT6: + from PySide6.QtCore import qVersion else: - # noinspection PyShadowingBuiltins - unicode, basestring = str, str - c_open = open - if USE_QT6: - from PySide6.QtCore import qVersion - else: - from PySide2.QtCore import qVersion + from PySide2.QtCore import qVersion # noinspection PyTypeChecker qt_version = qVersion().split(".")[0] -QT4 = qt_version == "4" QT5 = qt_version == "5" QT6 = qt_version == "6" if QT6 and QT5 and USE_QT6: QT5 = False +PORTABLE = False if sys.platform == "win32": # Windows import win32api import win32event @@ -65,7 +54,7 @@ def __del__(self): sys.exit(0) try: # noinspection PyUnresolvedReferences - portable_arg = sys.argv[1] if not PYTHON2 else sys.argv[1].decode("mbcs") + portable_arg = sys.argv[1] PORTABLE = portable_arg == "-p" except IndexError: # no arguments in the call pass @@ -86,7 +75,7 @@ def __del__(self): import socket app_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) # Create an abstract socket, by prefixing it with null. - app_socket.bind(str("\0{}_lock_port".format(APP_NAME))) + app_socket.bind(str(f"\0{APP_NAME}_lock_port")) except socket.error: # port in use - another instance is running sys.exit(0) SETTINGS_DIR = join(expanduser("~"), ".config", APP_NAME) @@ -96,10 +85,10 @@ def __del__(self): def except_hook(class_type, value, trace_back): """ Print the error to a log file """ - name = join(SETTINGS_DIR, "error_log_{}.txt".format(time.strftime(str("%Y-%m-%d")))) + name = join(SETTINGS_DIR, f"error_log_{time.strftime(str('%Y-%m-%d'))}.txt") with open(name, "a", encoding="utf8") as log: - log.write("\nCrash@{}\n".format(time.strftime(str("%Y-%m-%d %H:%M:%S")))) - traceback.print_exception(class_type, value, trace_back, file=c_open(name, str("a"))) + log.write(f"\nCrash@{time.strftime(str('%Y-%m-%d %H:%M:%S'))}\n") + traceback.print_exception(class_type, value, trace_back, file=open(name, str("a"))) sys.__excepthook__(class_type, value, trace_back) @@ -108,14 +97,13 @@ def except_hook(class_type, value, trace_back): # noinspection PyBroadException try: with gzip.GzipFile(join(SETTINGS_DIR, "settings.json.gz")) as settings: - j_text = settings.read() if PYTHON2 else settings.read().decode("utf8") - app_config = json.loads(j_text) + app_config = json.loads(settings.read().decode("utf8")) except Exception: # IOError on first run or everything else app_config = {} FIRST_RUN = True -BOOKS_VIEW, HIGHLIGHTS_VIEW = range(2) # app views +BOOKS_VIEW, HIGHLIGHTS_VIEW, SYNC_VIEW = range(3) # app views CHANGE_DB, NEW_DB, RELOAD_DB = range(3) # db change mode (TITLE, AUTHOR, TYPE, PERCENT, RATING, HIGH_COUNT, MODIFIED, PATH) = range(8) # file_table columns @@ -125,7 +113,11 @@ def except_hook(class_type, value, trace_back): (MANY_TEXT, ONE_TEXT, MANY_HTML, ONE_HTML, MANY_CSV, ONE_CSV, MANY_MD, ONE_MD) = range(8) # save_actions DB_MD5, DB_DATE, DB_PATH, DB_DATA = range(4) # db data (columns) -FILTER_ALL, FILTER_HIGH, FILTER_COMM, FILTER_TITLES = range(4) # db data (columns) +FILTER_ALL, FILTER_HIGH, FILTER_COMM, FILTER_TITLES = range(4) # filter type +(THEME_NONE_OLD, THEME_NONE_NEW, THEME_DARK_OLD, THEME_DARK_NEW, + THEME_LIGHT_OLD, THEME_LIGHT_NEW) = range(6) # theme idx +ACT_PAGE, ACT_DATE, ACT_TEXT, ACT_CHAPTER, ACT_COMMENT = range(5) # show items actions + NO_TITLE = _("NO TITLE FOUND") NO_AUTHOR = _("NO AUTHOR FOUND") @@ -133,6 +125,12 @@ def except_hook(class_type, value, trace_back): DO_NOT_SHOW = _("Don't show this again") DB_VERSION = 0 DATE_FORMAT = "%Y-%m-%d %H:%M:%S" +TOOLTIP_MERGE = _("Merge the highlights from the same book in two different\ndevices, " + "and/or sync their reading position.\nActivated only if two entries " + "of the same book are selected.") +TOOLTIP_SYNC = _("Start the sync process for all enabled groups") +SYNC_FILE = join(SETTINGS_DIR, "sync_groups.json") + CSV_HEAD = "Title\tAuthors\tPage\tDate\tChapter\tHighlight\tComment\n" CSV_KEYS = ["title", "authors", "page", "date", "chapter", "text", "comment"] HTML_HEAD = """ diff --git a/gui_about.py b/gui_about.py index aa16794..28d4727 100644 --- a/gui_about.py +++ b/gui_about.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_about.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_about.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_about.ui' applies. # -# Created: Thu Feb 6 12:55:05 2020 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_About(object): def setupUi(self, About): @@ -16,28 +17,28 @@ def setupUi(self, About): About.resize(480, 560) About.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) About.setModal(False) - self.verticalLayout = QtGui.QVBoxLayout(About) + self.verticalLayout = QtWidgets.QVBoxLayout(About) self.verticalLayout.setObjectName("verticalLayout") - self.about_tabs = QtGui.QTabWidget(About) - self.about_tabs.setTabShape(QtGui.QTabWidget.Rounded) + self.about_tabs = QtWidgets.QTabWidget(About) + self.about_tabs.setTabShape(QtWidgets.QTabWidget.Rounded) self.about_tabs.setObjectName("about_tabs") - self.info_tab = QtGui.QWidget() + self.info_tab = QtWidgets.QWidget() self.info_tab.setObjectName("info_tab") - self.verticalLayout_2 = QtGui.QVBoxLayout(self.info_tab) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.info_tab) self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.scrollArea_2 = QtGui.QScrollArea(self.info_tab) + self.scrollArea_2 = QtWidgets.QScrollArea(self.info_tab) self.scrollArea_2.setStyleSheet("QScrollArea {background-color:transparent;}") self.scrollArea_2.setWidgetResizable(True) self.scrollArea_2.setObjectName("scrollArea_2") - self.scrollAreaWidgetContents_2 = QtGui.QWidget() + self.scrollAreaWidgetContents_2 = QtWidgets.QWidget() self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 454, 485)) self.scrollAreaWidgetContents_2.setStyleSheet("background-color:transparent;") self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2") - self.verticalLayout_6 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents_2) + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_2) self.verticalLayout_6.setContentsMargins(6, 0, 6, 0) self.verticalLayout_6.setObjectName("verticalLayout_6") - self.text_lbl = QtGui.QLabel(self.scrollAreaWidgetContents_2) + self.text_lbl = QtWidgets.QLabel(self.scrollAreaWidgetContents_2) self.text_lbl.setText("") self.text_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.text_lbl.setWordWrap(True) @@ -47,12 +48,12 @@ def setupUi(self, About): self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) self.verticalLayout_2.addWidget(self.scrollArea_2) self.about_tabs.addTab(self.info_tab, "") - self.log_tab = QtGui.QWidget() + self.log_tab = QtWidgets.QWidget() self.log_tab.setObjectName("log_tab") - self.verticalLayout_8 = QtGui.QVBoxLayout(self.log_tab) + self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.log_tab) self.verticalLayout_8.setObjectName("verticalLayout_8") - self.log_txt = QtGui.QPlainTextEdit(self.log_tab) - self.log_txt.setFrameShape(QtGui.QFrame.WinPanel) + self.log_txt = QtWidgets.QPlainTextEdit(self.log_tab) + self.log_txt.setFrameShape(QtWidgets.QFrame.WinPanel) self.log_txt.setDocumentTitle("") self.log_txt.setUndoRedoEnabled(False) self.log_txt.setReadOnly(True) @@ -61,27 +62,27 @@ def setupUi(self, About): self.verticalLayout_8.addWidget(self.log_txt) self.about_tabs.addTab(self.log_tab, "") self.verticalLayout.addWidget(self.about_tabs) - self.btn_box = QtGui.QFrame(About) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.btn_box = QtWidgets.QFrame(About) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_box.sizePolicy().hasHeightForWidth()) self.btn_box.setSizePolicy(sizePolicy) self.btn_box.setObjectName("btn_box") - self.horizontalLayout = QtGui.QHBoxLayout(self.btn_box) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.btn_box) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") - self.about_qt_btn = QtGui.QPushButton(self.btn_box) + self.about_qt_btn = QtWidgets.QPushButton(self.btn_box) self.about_qt_btn.setObjectName("about_qt_btn") self.horizontalLayout.addWidget(self.about_qt_btn) - spacerItem = QtGui.QSpacerItem(92, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtWidgets.QSpacerItem(92, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) - self.updates_btn = QtGui.QPushButton(self.btn_box) + self.updates_btn = QtWidgets.QPushButton(self.btn_box) self.updates_btn.setObjectName("updates_btn") self.horizontalLayout.addWidget(self.updates_btn) - spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) - self.close_btn = QtGui.QPushButton(self.btn_box) + self.close_btn = QtWidgets.QPushButton(self.btn_box) self.close_btn.setObjectName("close_btn") self.horizontalLayout.addWidget(self.close_btn) self.verticalLayout.addWidget(self.btn_box) @@ -92,11 +93,11 @@ def setupUi(self, About): QtCore.QMetaObject.connectSlotsByName(About) def retranslateUi(self, About): - self.about_tabs.setTabText(self.about_tabs.indexOf(self.info_tab), QtGui.QApplication.translate("About", "Information", None, QtGui.QApplication.UnicodeUTF8)) - self.about_tabs.setTabText(self.about_tabs.indexOf(self.log_tab), QtGui.QApplication.translate("About", "Log", None, QtGui.QApplication.UnicodeUTF8)) - self.about_qt_btn.setText(QtGui.QApplication.translate("About", "About Qt", None, QtGui.QApplication.UnicodeUTF8)) - self.updates_btn.setToolTip(QtGui.QApplication.translate("About", "Check online for an updated version", None, QtGui.QApplication.UnicodeUTF8)) - self.updates_btn.setText(QtGui.QApplication.translate("About", "Check for Updates", None, QtGui.QApplication.UnicodeUTF8)) - self.close_btn.setText(QtGui.QApplication.translate("About", "Close", None, QtGui.QApplication.UnicodeUTF8)) + self.about_tabs.setTabText(self.about_tabs.indexOf(self.info_tab), QtWidgets.QApplication.translate("About", "Information", None, -1)) + self.about_tabs.setTabText(self.about_tabs.indexOf(self.log_tab), QtWidgets.QApplication.translate("About", "Log", None, -1)) + self.about_qt_btn.setText(QtWidgets.QApplication.translate("About", "About Qt", None, -1)) + self.updates_btn.setToolTip(QtWidgets.QApplication.translate("About", "Check online for an updated version", None, -1)) + self.updates_btn.setText(QtWidgets.QApplication.translate("About", "Check for Updates", None, -1)) + self.close_btn.setText(QtWidgets.QApplication.translate("About", "Close", None, -1)) import images_rc diff --git a/gui_auto_info.py b/gui_auto_info.py index 2aff20f..a99639f 100644 --- a/gui_auto_info.py +++ b/gui_auto_info.py @@ -1,37 +1,38 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_auto_info.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_auto_info.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_auto_info.ui' applies. # -# Created: Thu Nov 24 15:53:16 2022 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_AutoInfo(object): def setupUi(self, AutoInfo): AutoInfo.setObjectName("AutoInfo") AutoInfo.setWindowModality(QtCore.Qt.NonModal) AutoInfo.resize(300, 100) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(AutoInfo.sizePolicy().hasHeightForWidth()) AutoInfo.setSizePolicy(sizePolicy) AutoInfo.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) AutoInfo.setModal(True) - self.verticalLayout = QtGui.QVBoxLayout(AutoInfo) + self.verticalLayout = QtWidgets.QVBoxLayout(AutoInfo) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") - self.label = QtGui.QLabel(AutoInfo) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + self.label = QtWidgets.QLabel(AutoInfo) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) self.label.setSizePolicy(sizePolicy) - self.label.setFrameShape(QtGui.QFrame.Box) - self.label.setFrameShadow(QtGui.QFrame.Raised) + self.label.setFrameShape(QtWidgets.QFrame.Box) + self.label.setFrameShadow(QtWidgets.QFrame.Raised) self.label.setText("") self.label.setTextFormat(QtCore.Qt.AutoText) self.label.setAlignment(QtCore.Qt.AlignCenter) @@ -43,6 +44,6 @@ def setupUi(self, AutoInfo): QtCore.QMetaObject.connectSlotsByName(AutoInfo) def retranslateUi(self, AutoInfo): - AutoInfo.setWindowTitle(QtGui.QApplication.translate("AutoInfo", "Info", None, QtGui.QApplication.UnicodeUTF8)) + AutoInfo.setWindowTitle(QtWidgets.QApplication.translate("AutoInfo", "Info", None, -1)) import images_rc diff --git a/gui_edit.py b/gui_edit.py index 092f663..f4918db 100644 --- a/gui_edit.py +++ b/gui_edit.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_edit.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_edit.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_edit.ui' applies. # -# Created: Sun Mar 31 18:17:28 2019 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_TextDialog(object): def setupUi(self, TextDialog): @@ -16,29 +17,29 @@ def setupUi(self, TextDialog): TextDialog.resize(360, 180) TextDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) TextDialog.setModal(False) - self.verticalLayout = QtGui.QVBoxLayout(TextDialog) + self.verticalLayout = QtWidgets.QVBoxLayout(TextDialog) self.verticalLayout.setObjectName("verticalLayout") - self.high_edit_txt = QtGui.QTextEdit(TextDialog) - self.high_edit_txt.setFrameShape(QtGui.QFrame.WinPanel) + self.high_edit_txt = QtWidgets.QTextEdit(TextDialog) + self.high_edit_txt.setFrameShape(QtWidgets.QFrame.WinPanel) self.high_edit_txt.setAcceptRichText(False) self.high_edit_txt.setObjectName("high_edit_txt") self.verticalLayout.addWidget(self.high_edit_txt) - self.btn_box = QtGui.QFrame(TextDialog) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.btn_box = QtWidgets.QFrame(TextDialog) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_box.sizePolicy().hasHeightForWidth()) self.btn_box.setSizePolicy(sizePolicy) self.btn_box.setObjectName("btn_box") - self.horizontalLayout = QtGui.QHBoxLayout(self.btn_box) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.btn_box) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") - spacerItem = QtGui.QSpacerItem(175, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtWidgets.QSpacerItem(175, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) - self.ok_btn = QtGui.QPushButton(self.btn_box) + self.ok_btn = QtWidgets.QPushButton(self.btn_box) self.ok_btn.setObjectName("ok_btn") self.horizontalLayout.addWidget(self.ok_btn) - self.cancel_btn = QtGui.QPushButton(self.btn_box) + self.cancel_btn = QtWidgets.QPushButton(self.btn_box) self.cancel_btn.setObjectName("cancel_btn") self.horizontalLayout.addWidget(self.cancel_btn) self.verticalLayout.addWidget(self.btn_box) @@ -49,8 +50,8 @@ def setupUi(self, TextDialog): QtCore.QMetaObject.connectSlotsByName(TextDialog) def retranslateUi(self, TextDialog): - self.ok_btn.setToolTip(QtGui.QApplication.translate("TextDialog", "Check online for an updated version", None, QtGui.QApplication.UnicodeUTF8)) - self.ok_btn.setText(QtGui.QApplication.translate("TextDialog", "OK", None, QtGui.QApplication.UnicodeUTF8)) - self.cancel_btn.setText(QtGui.QApplication.translate("TextDialog", "Cancel", None, QtGui.QApplication.UnicodeUTF8)) + self.ok_btn.setToolTip(QtWidgets.QApplication.translate("TextDialog", "Check online for an updated version", None, -1)) + self.ok_btn.setText(QtWidgets.QApplication.translate("TextDialog", "OK", None, -1)) + self.cancel_btn.setText(QtWidgets.QApplication.translate("TextDialog", "Cancel", None, -1)) import images_rc diff --git a/gui_filter.py b/gui_filter.py index a09243b..4f456bd 100644 --- a/gui_filter.py +++ b/gui_filter.py @@ -1,31 +1,32 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_filter.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_filter.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_filter.ui' applies. # -# Created: Thu Apr 6 23:38:59 2023 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_Filter(object): def setupUi(self, Filter): Filter.setObjectName("Filter") Filter.resize(215, 66) Filter.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) - self.verticalLayout = QtGui.QVBoxLayout(Filter) + self.verticalLayout = QtWidgets.QVBoxLayout(Filter) self.verticalLayout.setContentsMargins(4, 4, 4, 4) self.verticalLayout.setObjectName("verticalLayout") - self.filter_frm1 = QtGui.QFrame(Filter) - self.filter_frm1.setFrameShape(QtGui.QFrame.StyledPanel) - self.filter_frm1.setFrameShadow(QtGui.QFrame.Raised) + self.filter_frm1 = QtWidgets.QFrame(Filter) + self.filter_frm1.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.filter_frm1.setFrameShadow(QtWidgets.QFrame.Raised) self.filter_frm1.setObjectName("filter_frm1") - self.horizontalLayout_4 = QtGui.QHBoxLayout(self.filter_frm1) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.filter_frm1) self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.filter_txt = QtGui.QLineEdit(self.filter_frm1) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) + self.filter_txt = QtWidgets.QLineEdit(self.filter_frm1) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filter_txt.sizePolicy().hasHeightForWidth()) @@ -33,8 +34,8 @@ def setupUi(self, Filter): self.filter_txt.setText("") self.filter_txt.setObjectName("filter_txt") self.horizontalLayout_4.addWidget(self.filter_txt) - self.filter_btn = QtGui.QPushButton(self.filter_frm1) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.filter_btn = QtWidgets.QPushButton(self.filter_frm1) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filter_btn.sizePolicy().hasHeightForWidth()) @@ -45,28 +46,28 @@ def setupUi(self, Filter): self.filter_btn.setObjectName("filter_btn") self.horizontalLayout_4.addWidget(self.filter_btn) self.verticalLayout.addWidget(self.filter_frm1) - self.filter_frm2 = QtGui.QFrame(Filter) - self.filter_frm2.setFrameShape(QtGui.QFrame.StyledPanel) - self.filter_frm2.setFrameShadow(QtGui.QFrame.Raised) + self.filter_frm2 = QtWidgets.QFrame(Filter) + self.filter_frm2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.filter_frm2.setFrameShadow(QtWidgets.QFrame.Raised) self.filter_frm2.setObjectName("filter_frm2") - self.horizontalLayout = QtGui.QHBoxLayout(self.filter_frm2) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.filter_frm2) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") - self.filter_box = QtGui.QComboBox(self.filter_frm2) + self.filter_box = QtWidgets.QComboBox(self.filter_frm2) self.filter_box.setObjectName("filter_box") self.filter_box.addItem("") self.filter_box.addItem("") self.filter_box.addItem("") self.filter_box.addItem("") self.horizontalLayout.addWidget(self.filter_box) - self.filtered_lbl = QtGui.QLabel(self.filter_frm2) + self.filtered_lbl = QtWidgets.QLabel(self.filter_frm2) self.filtered_lbl.setText("") self.filtered_lbl.setObjectName("filtered_lbl") self.horizontalLayout.addWidget(self.filtered_lbl) - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) - self.clear_filter_btn = QtGui.QPushButton(self.filter_frm2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.clear_filter_btn = QtWidgets.QPushButton(self.filter_frm2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.clear_filter_btn.sizePolicy().hasHeightForWidth()) @@ -83,17 +84,17 @@ def setupUi(self, Filter): QtCore.QMetaObject.connectSlotsByName(Filter) def retranslateUi(self, Filter): - self.filter_txt.setToolTip(QtGui.QApplication.translate("Filter", "Type the keywords to filter the visible items", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_txt.setPlaceholderText(QtGui.QApplication.translate("Filter", "Type here to filter...", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setToolTip(QtGui.QApplication.translate("Filter", "Set filter", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setText(QtGui.QApplication.translate("Filter", "Filter", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_box.setToolTip(QtGui.QApplication.translate("Filter", "Select where to search for the keywords", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_box.setItemText(0, QtGui.QApplication.translate("Filter", "Filter All:", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_box.setItemText(1, QtGui.QApplication.translate("Filter", "Filter Highlights:", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_box.setItemText(2, QtGui.QApplication.translate("Filter", "Filter Comments:", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_box.setItemText(3, QtGui.QApplication.translate("Filter", "Filter Book Titles:", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_filter_btn.setToolTip(QtGui.QApplication.translate("Filter", "Clear the filter field", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_filter_btn.setStatusTip(QtGui.QApplication.translate("Filter", "Clears the filter field", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_filter_btn.setText(QtGui.QApplication.translate("Filter", "Clear", None, QtGui.QApplication.UnicodeUTF8)) + self.filter_txt.setToolTip(QtWidgets.QApplication.translate("Filter", "Type the keywords to filter the visible items", None, -1)) + self.filter_txt.setPlaceholderText(QtWidgets.QApplication.translate("Filter", "Type here to filter...", None, -1)) + self.filter_btn.setToolTip(QtWidgets.QApplication.translate("Filter", "Set filter", None, -1)) + self.filter_btn.setText(QtWidgets.QApplication.translate("Filter", "Filter", None, -1)) + self.filter_box.setToolTip(QtWidgets.QApplication.translate("Filter", "Select where to search for the keywords", None, -1)) + self.filter_box.setItemText(0, QtWidgets.QApplication.translate("Filter", "Filter All:", None, -1)) + self.filter_box.setItemText(1, QtWidgets.QApplication.translate("Filter", "Filter Highlights:", None, -1)) + self.filter_box.setItemText(2, QtWidgets.QApplication.translate("Filter", "Filter Comments:", None, -1)) + self.filter_box.setItemText(3, QtWidgets.QApplication.translate("Filter", "Filter Book Titles:", None, -1)) + self.clear_filter_btn.setToolTip(QtWidgets.QApplication.translate("Filter", "Clear the filter field", None, -1)) + self.clear_filter_btn.setStatusTip(QtWidgets.QApplication.translate("Filter", "Clears the filter field", None, -1)) + self.clear_filter_btn.setText(QtWidgets.QApplication.translate("Filter", "Clear", None, -1)) import images_rc diff --git a/gui_main.py b/gui_main.py index 1a5b1bd..ea6243f 100644 --- a/gui_main.py +++ b/gui_main.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_main.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_main.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_main.ui' applies. # -# Created: Fri Jan 12 21:47:31 2024 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_Base(object): def setupUi(self, Base): @@ -18,50 +19,50 @@ def setupUi(self, Base): Base.setWindowIcon(icon) Base.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) Base.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) - self.centralwidget = QtGui.QWidget(Base) + self.centralwidget = QtWidgets.QWidget(Base) self.centralwidget.setObjectName("centralwidget") - self.verticalLayout_2 = QtGui.QVBoxLayout(self.centralwidget) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.views = QtGui.QStackedWidget(self.centralwidget) + self.views = QtWidgets.QStackedWidget(self.centralwidget) self.views.setObjectName("views") - self.books_pg = QtGui.QWidget() + self.books_pg = QtWidgets.QWidget() self.books_pg.setObjectName("books_pg") - self.verticalLayout_3 = QtGui.QVBoxLayout(self.books_pg) + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.books_pg) self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) self.verticalLayout_3.setObjectName("verticalLayout_3") - self.splitter = QtGui.QSplitter(self.books_pg) + self.splitter = QtWidgets.QSplitter(self.books_pg) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") self.file_table = DropTableWidget(self.splitter) self.file_table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.file_table.setFrameShape(QtGui.QFrame.WinPanel) - self.file_table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - self.file_table.setDragDropMode(QtGui.QAbstractItemView.DropOnly) + self.file_table.setFrameShape(QtWidgets.QFrame.WinPanel) + self.file_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.file_table.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly) self.file_table.setDefaultDropAction(QtCore.Qt.CopyAction) - self.file_table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.file_table.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) + self.file_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.file_table.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.file_table.setWordWrap(False) self.file_table.setCornerButtonEnabled(False) self.file_table.setColumnCount(8) self.file_table.setObjectName("file_table") self.file_table.setColumnCount(8) self.file_table.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(3, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(4, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(5, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(6, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.file_table.setHorizontalHeaderItem(7, item) self.file_table.horizontalHeader().setDefaultSectionSize(22) self.file_table.horizontalHeader().setHighlightSections(False) @@ -70,151 +71,151 @@ def setupUi(self, Base): self.file_table.verticalHeader().setDefaultSectionSize(22) self.file_table.verticalHeader().setHighlightSections(True) self.file_table.verticalHeader().setMinimumSectionSize(22) - self.frame = QtGui.QFrame(self.splitter) - self.frame.setFrameShape(QtGui.QFrame.WinPanel) - self.frame.setFrameShadow(QtGui.QFrame.Sunken) + self.frame = QtWidgets.QFrame(self.splitter) + self.frame.setFrameShape(QtWidgets.QFrame.WinPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Sunken) self.frame.setObjectName("frame") - self.verticalLayout = QtGui.QVBoxLayout(self.frame) + self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) + self.verticalLayout.setSpacing(3) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") - self.header = QtGui.QWidget(self.frame) + self.header = QtWidgets.QWidget(self.frame) self.header.setObjectName("header") - self.horizontalLayout = QtGui.QHBoxLayout(self.header) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.header) self.horizontalLayout.setContentsMargins(0, 0, -1, 0) self.horizontalLayout.setObjectName("horizontalLayout") - self.fold_btn = QtGui.QToolButton(self.header) + self.fold_btn = QtWidgets.QToolButton(self.header) self.fold_btn.setStyleSheet("QToolButton{border:none;}") self.fold_btn.setCheckable(True) self.fold_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.fold_btn.setArrowType(QtCore.Qt.DownArrow) self.fold_btn.setObjectName("fold_btn") self.horizontalLayout.addWidget(self.fold_btn) - self.frame_2 = QtGui.QFrame(self.header) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) + self.frame_2 = QtWidgets.QFrame(self.header) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) self.frame_2.setSizePolicy(sizePolicy) - self.frame_2.setFrameShape(QtGui.QFrame.HLine) - self.frame_2.setFrameShadow(QtGui.QFrame.Sunken) + self.frame_2.setFrameShape(QtWidgets.QFrame.HLine) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.frame_2.setLineWidth(1) self.frame_2.setObjectName("frame_2") self.horizontalLayout.addWidget(self.frame_2) self.verticalLayout.addWidget(self.header) - self.book_info = QtGui.QFrame(self.frame) - self.book_info.setFrameShape(QtGui.QFrame.StyledPanel) - self.book_info.setFrameShadow(QtGui.QFrame.Raised) + self.book_info = QtWidgets.QFrame(self.frame) + self.book_info.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.book_info.setFrameShadow(QtWidgets.QFrame.Raised) self.book_info.setObjectName("book_info") - self.gridLayout = QtGui.QGridLayout(self.book_info) + self.gridLayout = QtWidgets.QGridLayout(self.book_info) self.gridLayout.setContentsMargins(6, 0, 6, 0) self.gridLayout.setObjectName("gridLayout") - self.title_lbl = QtGui.QLabel(self.book_info) + self.title_lbl = QtWidgets.QLabel(self.book_info) self.title_lbl.setObjectName("title_lbl") self.gridLayout.addWidget(self.title_lbl, 0, 0, 1, 1) - self.series_lbl = QtGui.QLabel(self.book_info) + self.series_lbl = QtWidgets.QLabel(self.book_info) self.series_lbl.setObjectName("series_lbl") self.gridLayout.addWidget(self.series_lbl, 2, 0, 1, 1) - self.author_lbl = QtGui.QLabel(self.book_info) + self.author_lbl = QtWidgets.QLabel(self.book_info) self.author_lbl.setObjectName("author_lbl") self.gridLayout.addWidget(self.author_lbl, 1, 0, 1, 1) - self.lang_lbl = QtGui.QLabel(self.book_info) + self.lang_lbl = QtWidgets.QLabel(self.book_info) self.lang_lbl.setObjectName("lang_lbl") self.gridLayout.addWidget(self.lang_lbl, 4, 0, 1, 1) - self.pages_lbl = QtGui.QLabel(self.book_info) + self.pages_lbl = QtWidgets.QLabel(self.book_info) self.pages_lbl.setObjectName("pages_lbl") self.gridLayout.addWidget(self.pages_lbl, 4, 2, 1, 1) - self.lang_txt = QtGui.QLineEdit(self.book_info) + self.lang_txt = QtWidgets.QLineEdit(self.book_info) self.lang_txt.setReadOnly(True) self.lang_txt.setObjectName("lang_txt") self.gridLayout.addWidget(self.lang_txt, 4, 1, 1, 1) - self.pages_txt = QtGui.QLineEdit(self.book_info) + self.pages_txt = QtWidgets.QLineEdit(self.book_info) self.pages_txt.setReadOnly(True) self.pages_txt.setObjectName("pages_txt") self.gridLayout.addWidget(self.pages_txt, 4, 3, 1, 1) - self.tags_lbl = QtGui.QLabel(self.book_info) + self.tags_lbl = QtWidgets.QLabel(self.book_info) self.tags_lbl.setObjectName("tags_lbl") self.gridLayout.addWidget(self.tags_lbl, 3, 0, 1, 1) - self.description_btn = QtGui.QToolButton(self.book_info) + self.description_btn = QtWidgets.QToolButton(self.book_info) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(":/stuff/description.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.description_btn.setIcon(icon1) self.description_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.description_btn.setObjectName("description_btn") self.gridLayout.addWidget(self.description_btn, 4, 4, 1, 1) - self.tags_txt = QtGui.QLineEdit(self.book_info) + self.tags_txt = QtWidgets.QLineEdit(self.book_info) self.tags_txt.setReadOnly(True) self.tags_txt.setObjectName("tags_txt") self.gridLayout.addWidget(self.tags_txt, 3, 1, 1, 4) - self.series_txt = QtGui.QLineEdit(self.book_info) + self.series_txt = QtWidgets.QLineEdit(self.book_info) self.series_txt.setReadOnly(True) self.series_txt.setObjectName("series_txt") self.gridLayout.addWidget(self.series_txt, 2, 1, 1, 4) - self.author_txt = QtGui.QLineEdit(self.book_info) + self.author_txt = QtWidgets.QLineEdit(self.book_info) self.author_txt.setReadOnly(True) self.author_txt.setObjectName("author_txt") self.gridLayout.addWidget(self.author_txt, 1, 1, 1, 4) - self.title_txt = QtGui.QLineEdit(self.book_info) + self.title_txt = QtWidgets.QLineEdit(self.book_info) self.title_txt.setReadOnly(True) self.title_txt.setObjectName("title_txt") self.gridLayout.addWidget(self.title_txt, 0, 1, 1, 4) - self.review_lbl = QtGui.QLabel(self.book_info) + self.review_lbl = QtWidgets.QLabel(self.book_info) self.review_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.review_lbl.setObjectName("review_lbl") self.gridLayout.addWidget(self.review_lbl, 5, 0, 1, 1) - self.review_txt = QtGui.QLabel(self.book_info) - self.review_txt.setStyleSheet("background-color: rgb(255, 255, 255);") - self.review_txt.setFrameShape(QtGui.QFrame.NoFrame) + self.review_txt = QtWidgets.QLabel(self.book_info) + self.review_txt.setFrameShape(QtWidgets.QFrame.NoFrame) self.review_txt.setText("") self.review_txt.setWordWrap(True) self.review_txt.setObjectName("review_txt") self.gridLayout.addWidget(self.review_txt, 5, 1, 1, 4) self.verticalLayout.addWidget(self.book_info) - self.high_list = QtGui.QListWidget(self.frame) + self.high_list = QtWidgets.QListWidget(self.frame) self.high_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.high_list.setFrameShape(QtGui.QFrame.WinPanel) - self.high_list.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - self.high_list.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.high_list.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.high_list.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) + self.high_list.setFrameShape(QtWidgets.QFrame.WinPanel) + self.high_list.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.high_list.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.high_list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.high_list.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.high_list.setWordWrap(True) self.high_list.setObjectName("high_list") self.verticalLayout.addWidget(self.high_list) self.verticalLayout_3.addWidget(self.splitter) self.views.addWidget(self.books_pg) - self.highlights_pg = QtGui.QWidget() + self.highlights_pg = QtWidgets.QWidget() self.highlights_pg.setObjectName("highlights_pg") - self.verticalLayout_4 = QtGui.QVBoxLayout(self.highlights_pg) + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.highlights_pg) self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) self.verticalLayout_4.setObjectName("verticalLayout_4") - self.high_table = QtGui.QTableWidget(self.highlights_pg) + self.high_table = QtWidgets.QTableWidget(self.highlights_pg) self.high_table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.high_table.setFrameShape(QtGui.QFrame.WinPanel) - self.high_table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - self.high_table.setDragDropMode(QtGui.QAbstractItemView.DropOnly) + self.high_table.setFrameShape(QtWidgets.QFrame.WinPanel) + self.high_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.high_table.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly) self.high_table.setDefaultDropAction(QtCore.Qt.CopyAction) - self.high_table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.high_table.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) + self.high_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.high_table.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) self.high_table.setWordWrap(False) self.high_table.setCornerButtonEnabled(False) self.high_table.setColumnCount(8) self.high_table.setObjectName("high_table") self.high_table.setColumnCount(8) self.high_table.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(3, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(4, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(5, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(6, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.high_table.setHorizontalHeaderItem(7, item) self.high_table.horizontalHeader().setHighlightSections(False) self.high_table.horizontalHeader().setMinimumSectionSize(22) @@ -225,13 +226,35 @@ def setupUi(self, Base): self.high_table.verticalHeader().setMinimumSectionSize(22) self.verticalLayout_4.addWidget(self.high_table) self.views.addWidget(self.highlights_pg) + self.sync_pg = QtWidgets.QWidget() + self.sync_pg.setObjectName("sync_pg") + self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.sync_pg) + self.verticalLayout_5.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.sync_table = XTableWidget(self.sync_pg) + self.sync_table.setAcceptDrops(True) + self.sync_table.setDragEnabled(True) + self.sync_table.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) + self.sync_table.setDefaultDropAction(QtCore.Qt.MoveAction) + self.sync_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.sync_table.setObjectName("sync_table") + self.sync_table.setColumnCount(1) + self.sync_table.setRowCount(0) + item = QtWidgets.QTableWidgetItem() + self.sync_table.setHorizontalHeaderItem(0, item) + self.sync_table.horizontalHeader().setVisible(False) + self.sync_table.horizontalHeader().setStretchLastSection(True) + self.sync_table.verticalHeader().setDefaultSectionSize(90) + self.sync_table.verticalHeader().setMinimumSectionSize(90) + self.verticalLayout_5.addWidget(self.sync_table) + self.views.addWidget(self.sync_pg) self.verticalLayout_2.addWidget(self.views) Base.setCentralWidget(self.centralwidget) - self.statusbar = QtGui.QStatusBar(Base) + self.statusbar = QtWidgets.QStatusBar(Base) self.statusbar.setStyleSheet("QStatusBar{padding-left:8px;font-weight:bold;}") self.statusbar.setObjectName("statusbar") Base.setStatusBar(self.statusbar) - self.tool_bar = QtGui.QToolBar(Base) + self.tool_bar = QtWidgets.QToolBar(Base) self.tool_bar.setWindowTitle("toolBar") self.tool_bar.setMovable(True) self.tool_bar.setAllowedAreas(QtCore.Qt.BottomToolBarArea|QtCore.Qt.TopToolBarArea) @@ -239,15 +262,15 @@ def setupUi(self, Base): self.tool_bar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.tool_bar.setObjectName("tool_bar") Base.addToolBar(QtCore.Qt.TopToolBarArea, self.tool_bar) - self.act_english = QtGui.QAction(Base) + self.act_english = QtWidgets.QAction(Base) self.act_english.setCheckable(True) self.act_english.setChecked(False) self.act_english.setObjectName("act_english") - self.act_greek = QtGui.QAction(Base) + self.act_greek = QtWidgets.QAction(Base) self.act_greek.setCheckable(True) self.act_greek.setChecked(False) self.act_greek.setObjectName("act_greek") - self.act_view_book = QtGui.QAction(Base) + self.act_view_book = QtWidgets.QAction(Base) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap(":/stuff/files_view.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.act_view_book.setIcon(icon2) @@ -259,36 +282,37 @@ def setupUi(self, Base): def retranslateUi(self, Base): self.file_table.setSortingEnabled(True) - self.file_table.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("Base", "Title", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("Base", "Author", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("Base", "Type", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(3).setText(QtGui.QApplication.translate("Base", "Percent", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(4).setText(QtGui.QApplication.translate("Base", "Rating", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(5).setText(QtGui.QApplication.translate("Base", "Highlights", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(6).setText(QtGui.QApplication.translate("Base", "Modified", None, QtGui.QApplication.UnicodeUTF8)) - self.file_table.horizontalHeaderItem(7).setText(QtGui.QApplication.translate("Base", "Path", None, QtGui.QApplication.UnicodeUTF8)) - self.fold_btn.setText(QtGui.QApplication.translate("Base", "Hide Book Info", None, QtGui.QApplication.UnicodeUTF8)) - self.title_lbl.setText(QtGui.QApplication.translate("Base", "Title", None, QtGui.QApplication.UnicodeUTF8)) - self.series_lbl.setText(QtGui.QApplication.translate("Base", "Series", None, QtGui.QApplication.UnicodeUTF8)) - self.author_lbl.setText(QtGui.QApplication.translate("Base", "Author", None, QtGui.QApplication.UnicodeUTF8)) - self.lang_lbl.setText(QtGui.QApplication.translate("Base", "Language", None, QtGui.QApplication.UnicodeUTF8)) - self.pages_lbl.setText(QtGui.QApplication.translate("Base", "Pages", None, QtGui.QApplication.UnicodeUTF8)) - self.tags_lbl.setText(QtGui.QApplication.translate("Base", "Tags", None, QtGui.QApplication.UnicodeUTF8)) - self.description_btn.setText(QtGui.QApplication.translate("Base", "Description", None, QtGui.QApplication.UnicodeUTF8)) - self.review_lbl.setText(QtGui.QApplication.translate("Base", "Review", None, QtGui.QApplication.UnicodeUTF8)) + self.file_table.horizontalHeaderItem(0).setText(QtWidgets.QApplication.translate("Base", "Title", None, -1)) + self.file_table.horizontalHeaderItem(1).setText(QtWidgets.QApplication.translate("Base", "Author", None, -1)) + self.file_table.horizontalHeaderItem(2).setText(QtWidgets.QApplication.translate("Base", "Type", None, -1)) + self.file_table.horizontalHeaderItem(3).setText(QtWidgets.QApplication.translate("Base", "Percent", None, -1)) + self.file_table.horizontalHeaderItem(4).setText(QtWidgets.QApplication.translate("Base", "Rating", None, -1)) + self.file_table.horizontalHeaderItem(5).setText(QtWidgets.QApplication.translate("Base", "Highlights", None, -1)) + self.file_table.horizontalHeaderItem(6).setText(QtWidgets.QApplication.translate("Base", "Modified", None, -1)) + self.file_table.horizontalHeaderItem(7).setText(QtWidgets.QApplication.translate("Base", "Path", None, -1)) + self.fold_btn.setText(QtWidgets.QApplication.translate("Base", "Hide Book Info", None, -1)) + self.title_lbl.setText(QtWidgets.QApplication.translate("Base", "Title", None, -1)) + self.series_lbl.setText(QtWidgets.QApplication.translate("Base", "Series", None, -1)) + self.author_lbl.setText(QtWidgets.QApplication.translate("Base", "Author", None, -1)) + self.lang_lbl.setText(QtWidgets.QApplication.translate("Base", "Language", None, -1)) + self.pages_lbl.setText(QtWidgets.QApplication.translate("Base", "Pages", None, -1)) + self.tags_lbl.setText(QtWidgets.QApplication.translate("Base", "Tags", None, -1)) + self.description_btn.setText(QtWidgets.QApplication.translate("Base", "Description", None, -1)) + self.review_lbl.setText(QtWidgets.QApplication.translate("Base", "Review", None, -1)) self.high_table.setSortingEnabled(True) - self.high_table.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("Base", "Highlight", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("Base", "Comment", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("Base", "Date", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(3).setText(QtGui.QApplication.translate("Base", "Title", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(4).setText(QtGui.QApplication.translate("Base", "Author", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(5).setText(QtGui.QApplication.translate("Base", "Page", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(6).setText(QtGui.QApplication.translate("Base", "Chapter", None, QtGui.QApplication.UnicodeUTF8)) - self.high_table.horizontalHeaderItem(7).setText(QtGui.QApplication.translate("Base", "Book path", None, QtGui.QApplication.UnicodeUTF8)) - self.act_english.setText(QtGui.QApplication.translate("Base", "English", None, QtGui.QApplication.UnicodeUTF8)) - self.act_greek.setText(QtGui.QApplication.translate("Base", "Greek", None, QtGui.QApplication.UnicodeUTF8)) - self.act_view_book.setText(QtGui.QApplication.translate("Base", "View Book", None, QtGui.QApplication.UnicodeUTF8)) - self.act_view_book.setShortcut(QtGui.QApplication.translate("Base", "Ctrl+B", None, QtGui.QApplication.UnicodeUTF8)) + self.high_table.horizontalHeaderItem(0).setText(QtWidgets.QApplication.translate("Base", "Highlight", None, -1)) + self.high_table.horizontalHeaderItem(1).setText(QtWidgets.QApplication.translate("Base", "Comment", None, -1)) + self.high_table.horizontalHeaderItem(2).setText(QtWidgets.QApplication.translate("Base", "Date", None, -1)) + self.high_table.horizontalHeaderItem(3).setText(QtWidgets.QApplication.translate("Base", "Title", None, -1)) + self.high_table.horizontalHeaderItem(4).setText(QtWidgets.QApplication.translate("Base", "Author", None, -1)) + self.high_table.horizontalHeaderItem(5).setText(QtWidgets.QApplication.translate("Base", "Page", None, -1)) + self.high_table.horizontalHeaderItem(6).setText(QtWidgets.QApplication.translate("Base", "Chapter", None, -1)) + self.high_table.horizontalHeaderItem(7).setText(QtWidgets.QApplication.translate("Base", "Path", None, -1)) + self.sync_table.horizontalHeaderItem(0).setText(QtWidgets.QApplication.translate("Base", "Sync Groups", None, -1)) + self.act_english.setText(QtWidgets.QApplication.translate("Base", "English", None, -1)) + self.act_greek.setText(QtWidgets.QApplication.translate("Base", "Greek", None, -1)) + self.act_view_book.setText(QtWidgets.QApplication.translate("Base", "View Book", None, -1)) + self.act_view_book.setShortcut(QtWidgets.QApplication.translate("Base", "Ctrl+B", None, -1)) -from secondary import DropTableWidget +from secondary import DropTableWidget, XTableWidget import images_rc diff --git a/gui_main.ui b/gui_main.ui index 518fd1f..ce815f4 100644 --- a/gui_main.ui +++ b/gui_main.ui @@ -144,6 +144,9 @@ QFrame::Sunken + + 3 + 0 @@ -331,9 +334,6 @@ - - background-color: rgb(255, 255, 255); - QFrame::NoFrame @@ -477,7 +477,50 @@ - Book path + Path + + + + + + + + + + 0 + + + + + true + + + true + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + QAbstractItemView::SelectRows + + + false + + + true + + + 90 + + + 90 + + + + Sync Groups @@ -560,6 +603,11 @@ QTableWidget
secondary
+ + XTableWidget + QTableWidget +
secondary
+
diff --git a/gui_status.py b/gui_status.py index 772f75f..941ddbc 100644 --- a/gui_status.py +++ b/gui_status.py @@ -1,58 +1,67 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_status.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_status.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_status.ui' applies. # -# Created: Thu Mar 9 14:39:35 2023 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_Status(object): def setupUi(self, Status): Status.setObjectName("Status") - Status.resize(277, 55) - Status.setWindowTitle("") - self.horizontalLayout_2 = QtGui.QHBoxLayout(Status) + Status.resize(286, 32) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Status) self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.frame = QtGui.QFrame(Status) - self.frame.setFrameShape(QtGui.QFrame.StyledPanel) - self.frame.setFrameShadow(QtGui.QFrame.Raised) + self.frame = QtWidgets.QFrame(Status) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") - self.horizontalLayout = QtGui.QHBoxLayout(self.frame) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") - self.anim_lbl = QtGui.QLabel(self.frame) + self.anim_lbl = QtWidgets.QLabel(self.frame) self.anim_lbl.setText("") self.anim_lbl.setObjectName("anim_lbl") self.horizontalLayout.addWidget(self.anim_lbl) - self.show_items_btn = QtGui.QToolButton(self.frame) + self.theme_box = QtWidgets.QComboBox(self.frame) + self.theme_box.setObjectName("theme_box") + self.theme_box.addItem("") + self.theme_box.addItem("") + self.theme_box.addItem("") + self.theme_box.addItem("") + self.theme_box.addItem("") + self.theme_box.addItem("") + self.horizontalLayout.addWidget(self.theme_box) + self.show_items_btn = QtWidgets.QToolButton(self.frame) self.show_items_btn.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/stuff/show_pages.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.show_items_btn.setIcon(icon) self.show_items_btn.setIconSize(QtCore.QSize(24, 24)) self.show_items_btn.setChecked(False) - self.show_items_btn.setPopupMode(QtGui.QToolButton.InstantPopup) + self.show_items_btn.setPopupMode(QtWidgets.QToolButton.InstantPopup) self.show_items_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.show_items_btn.setObjectName("show_items_btn") self.horizontalLayout.addWidget(self.show_items_btn) self.horizontalLayout_2.addWidget(self.frame) - self.act_page = QtGui.QAction(Status) + self.act_page = QtWidgets.QAction(Status) self.act_page.setCheckable(True) self.act_page.setObjectName("act_page") - self.act_date = QtGui.QAction(Status) + self.act_date = QtWidgets.QAction(Status) self.act_date.setCheckable(True) self.act_date.setObjectName("act_date") - self.act_text = QtGui.QAction(Status) + self.act_text = QtWidgets.QAction(Status) self.act_text.setCheckable(True) self.act_text.setObjectName("act_text") - self.act_comment = QtGui.QAction(Status) + self.act_comment = QtWidgets.QAction(Status) self.act_comment.setCheckable(True) self.act_comment.setObjectName("act_comment") - self.act_chapter = QtGui.QAction(Status) + self.act_chapter = QtWidgets.QAction(Status) self.act_chapter.setCheckable(True) self.act_chapter.setObjectName("act_chapter") @@ -60,15 +69,21 @@ def setupUi(self, Status): QtCore.QMetaObject.connectSlotsByName(Status) def retranslateUi(self, Status): - self.show_items_btn.setToolTip(QtGui.QApplication.translate("Status", "Show/Hide elements of Highlights. Also affects\n" -"what will be saved to the text/html files.", None, QtGui.QApplication.UnicodeUTF8)) - self.show_items_btn.setStatusTip(QtGui.QApplication.translate("Status", "Show/Hide elements of Highlights. Also affects what will be saved to the text/html files.", None, QtGui.QApplication.UnicodeUTF8)) - self.show_items_btn.setText(QtGui.QApplication.translate("Status", "Show in Highlights", None, QtGui.QApplication.UnicodeUTF8)) - self.act_page.setText(QtGui.QApplication.translate("Status", "Page", None, QtGui.QApplication.UnicodeUTF8)) - self.act_date.setText(QtGui.QApplication.translate("Status", "Date", None, QtGui.QApplication.UnicodeUTF8)) - self.act_text.setText(QtGui.QApplication.translate("Status", "Highlight", None, QtGui.QApplication.UnicodeUTF8)) - self.act_comment.setText(QtGui.QApplication.translate("Status", "Comment", None, QtGui.QApplication.UnicodeUTF8)) - self.act_chapter.setText(QtGui.QApplication.translate("Status", "Chapter", None, QtGui.QApplication.UnicodeUTF8)) - self.act_chapter.setToolTip(QtGui.QApplication.translate("Status", "Chapter", None, QtGui.QApplication.UnicodeUTF8)) + self.theme_box.setItemText(0, QtWidgets.QApplication.translate("Status", "No theme - Old icons", None, -1)) + self.theme_box.setItemText(1, QtWidgets.QApplication.translate("Status", "No theme - New icons", None, -1)) + self.theme_box.setItemText(2, QtWidgets.QApplication.translate("Status", "Dark theme - Old icons", None, -1)) + self.theme_box.setItemText(3, QtWidgets.QApplication.translate("Status", "Dark theme - New icons", None, -1)) + self.theme_box.setItemText(4, QtWidgets.QApplication.translate("Status", "Light theme - Old icons", None, -1)) + self.theme_box.setItemText(5, QtWidgets.QApplication.translate("Status", "Light theme - New icons", None, -1)) + self.show_items_btn.setToolTip(QtWidgets.QApplication.translate("Status", "Show/Hide elements of Highlights. Also affects\n" +"what will be saved to the text/html files.", None, -1)) + self.show_items_btn.setStatusTip(QtWidgets.QApplication.translate("Status", "Show/Hide elements of Highlights. Also affects what will be saved to the text/html files.", None, -1)) + self.show_items_btn.setText(QtWidgets.QApplication.translate("Status", "Show in Highlights", None, -1)) + self.act_page.setText(QtWidgets.QApplication.translate("Status", "Page", None, -1)) + self.act_date.setText(QtWidgets.QApplication.translate("Status", "Date", None, -1)) + self.act_text.setText(QtWidgets.QApplication.translate("Status", "Highlight", None, -1)) + self.act_comment.setText(QtWidgets.QApplication.translate("Status", "Comment", None, -1)) + self.act_chapter.setText(QtWidgets.QApplication.translate("Status", "Chapter", None, -1)) + self.act_chapter.setToolTip(QtWidgets.QApplication.translate("Status", "Chapter", None, -1)) import images_rc diff --git a/gui_status.ui b/gui_status.ui index 268a885..b2e4ce5 100644 --- a/gui_status.ui +++ b/gui_status.ui @@ -6,13 +6,10 @@ 0 0 - 277 - 55 + 286 + 32 - - - 0 @@ -36,6 +33,40 @@
+ + + + + No theme - Old icons + + + + + No theme - New icons + + + + + Dark theme - Old icons + + + + + Dark theme - New icons + + + + + Light theme - Old icons + + + + + Light theme - New icons + + + + diff --git a/gui_sync_group.py b/gui_sync_group.py new file mode 100644 index 0000000..ce76850 --- /dev/null +++ b/gui_sync_group.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_sync_group.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_sync_group.ui' applies. +# +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 +# +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore, QtGui, QtWidgets + +class Ui_SyncGroup(object): + def setupUi(self, SyncGroup): + SyncGroup.setObjectName("SyncGroup") + SyncGroup.resize(560, 65) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout(SyncGroup) + self.horizontalLayout_5.setSpacing(0) + self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.frame = QtWidgets.QFrame(SyncGroup) + self.frame.setObjectName("frame") + self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) + self.verticalLayout.setSpacing(0) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + spacerItem = QtWidgets.QSpacerItem(20, 30, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem) + self.power_btn = QtWidgets.QToolButton(self.frame) + self.power_btn.setText("") + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/stuff/power32gray.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap(QtGui.QPixmap(":/stuff/power32red.png"), QtGui.QIcon.Normal, QtGui.QIcon.On) + self.power_btn.setIcon(icon) + self.power_btn.setIconSize(QtCore.QSize(16, 16)) + self.power_btn.setCheckable(True) + self.power_btn.setChecked(True) + self.power_btn.setAutoRaise(True) + self.power_btn.setObjectName("power_btn") + self.verticalLayout.addWidget(self.power_btn) + spacerItem1 = QtWidgets.QSpacerItem(20, 28, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout.addItem(spacerItem1) + self.horizontalLayout_5.addWidget(self.frame) + self.group_frm = QtWidgets.QFrame(SyncGroup) + self.group_frm.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.group_frm.setFrameShape(QtWidgets.QFrame.Box) + self.group_frm.setFrameShadow(QtWidgets.QFrame.Plain) + self.group_frm.setLineWidth(1) + self.group_frm.setObjectName("group_frm") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.group_frm) + self.verticalLayout_3.setSpacing(0) + self.verticalLayout_3.setContentsMargins(4, 0, 2, 0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.frame_2 = QtWidgets.QFrame(self.group_frm) + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_2) + self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.refresh_btn = QtWidgets.QToolButton(self.frame_2) + self.refresh_btn.setText("") + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/stuff/refresh16.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.refresh_btn.setIcon(icon1) + self.refresh_btn.setIconSize(QtCore.QSize(16, 16)) + self.refresh_btn.setChecked(False) + self.refresh_btn.setAutoRaise(True) + self.refresh_btn.setObjectName("refresh_btn") + self.horizontalLayout_4.addWidget(self.refresh_btn) + spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem2) + self.title_lbl = QtWidgets.QLabel(self.frame_2) + self.title_lbl.setAutoFillBackground(True) + self.title_lbl.setText("") + self.title_lbl.setAlignment(QtCore.Qt.AlignCenter) + self.title_lbl.setObjectName("title_lbl") + self.horizontalLayout_4.addWidget(self.title_lbl) + spacerItem3 = QtWidgets.QSpacerItem(161, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem3) + self.sync_btn = QtWidgets.QToolButton(self.frame_2) + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/stuff/sync.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.sync_btn.setIcon(icon2) + self.sync_btn.setChecked(False) + self.sync_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) + self.sync_btn.setAutoRaise(True) + self.sync_btn.setObjectName("sync_btn") + self.horizontalLayout_4.addWidget(self.sync_btn) + self.verticalLayout_3.addWidget(self.frame_2) + self.items_frm = QtWidgets.QFrame(self.group_frm) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.items_frm.sizePolicy().hasHeightForWidth()) + self.items_frm.setSizePolicy(sizePolicy) + self.items_frm.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.items_frm.setFrameShadow(QtWidgets.QFrame.Raised) + self.items_frm.setObjectName("items_frm") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.items_frm) + self.verticalLayout_2.setSpacing(2) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.checks_frm = QtWidgets.QFrame(self.items_frm) + self.checks_frm.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.checks_frm.setFrameShadow(QtWidgets.QFrame.Raised) + self.checks_frm.setObjectName("checks_frm") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.checks_frm) + self.horizontalLayout.setSpacing(4) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.sync_pos_chk = QtWidgets.QCheckBox(self.checks_frm) + self.sync_pos_chk.setObjectName("sync_pos_chk") + self.horizontalLayout.addWidget(self.sync_pos_chk) + self.merge_chk = QtWidgets.QCheckBox(self.checks_frm) + self.merge_chk.setObjectName("merge_chk") + self.horizontalLayout.addWidget(self.merge_chk) + self.sync_db_chk = QtWidgets.QCheckBox(self.checks_frm) + self.sync_db_chk.setObjectName("sync_db_chk") + self.horizontalLayout.addWidget(self.sync_db_chk) + spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem4) + self.verticalLayout_2.addWidget(self.checks_frm) + self.verticalLayout_3.addWidget(self.items_frm) + self.horizontalLayout_5.addWidget(self.group_frm) + + self.retranslateUi(SyncGroup) + QtCore.QObject.connect(self.power_btn, QtCore.SIGNAL("toggled(bool)"), self.group_frm.setEnabled) + QtCore.QMetaObject.connectSlotsByName(SyncGroup) + + def retranslateUi(self, SyncGroup): + self.power_btn.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Enable or disable this Sync Group", None, -1)) + self.power_btn.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Enable or disable this Sync Group", None, -1)) + self.refresh_btn.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Reload the Group and check the paths for errors", None, -1)) + self.refresh_btn.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Reload the Group and check the paths for errors", None, -1)) + self.sync_btn.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Start the sync/merge process for this group", None, -1)) + self.sync_btn.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Start the sync/merge process for this group", None, -1)) + self.sync_btn.setText(QtWidgets.QApplication.translate("SyncGroup", "Sync this group", None, -1)) + self.sync_pos_chk.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Sync the current position and read percent of the books", None, -1)) + self.sync_pos_chk.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Sync the current position and read percent of the books", None, -1)) + self.sync_pos_chk.setText(QtWidgets.QApplication.translate("SyncGroup", "Sync position", None, -1)) + self.merge_chk.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Merge the highlights from both books\\n(and/or the archived version)", None, -1)) + self.merge_chk.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Merge the highlights from both books\\\\n(and/or the archived version)", None, -1)) + self.merge_chk.setText(QtWidgets.QApplication.translate("SyncGroup", "Merge Highlights", None, -1)) + self.sync_db_chk.setToolTip(QtWidgets.QApplication.translate("SyncGroup", "Keep a synced version of the book in the archived database", None, -1)) + self.sync_db_chk.setStatusTip(QtWidgets.QApplication.translate("SyncGroup", "Keep a synced version of the book in the archived database", None, -1)) + self.sync_db_chk.setText(QtWidgets.QApplication.translate("SyncGroup", "Sync with archived", None, -1)) + +import images_rc diff --git a/gui_sync_group.ui b/gui_sync_group.ui new file mode 100644 index 0000000..46b1462 --- /dev/null +++ b/gui_sync_group.ui @@ -0,0 +1,350 @@ + + + SyncGroup + + + + 0 + 0 + 560 + 65 + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 30 + + + + + + + + Enable or disable this Sync Group + + + Enable or disable this Sync Group + + + + + + + :/stuff/power32gray.png + :/stuff/power32red.png:/stuff/power32gray.png + + + + 16 + 16 + + + + true + + + true + + + true + + + + + + + Qt::Vertical + + + + 20 + 28 + + + + + + + + + + + Qt::CustomContextMenu + + + QFrame::Box + + + QFrame::Plain + + + 1 + + + + 0 + + + 4 + + + 0 + + + 2 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + + + Reload the Group and check the paths for errors + + + Reload the Group and check the paths for errors + + + + + + + :/stuff/refresh16.png:/stuff/refresh16.png + + + + 16 + 16 + + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 161 + 20 + + + + + + + + Start the sync/merge process for this group + + + Start the sync/merge process for this group + + + Sync this group + + + + :/stuff/sync.png:/stuff/sync.png + + + false + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 4 + + + 0 + + + + + Sync the current position and read percent of the books + + + Sync the current position and read percent of the books + + + Sync position + + + + + + + Merge the highlights from both books\n(and/or the archived version) + + + Merge the highlights from both books\\n(and/or the archived version) + + + Merge Highlights + + + + + + + Keep a synced version of the book in the archived database + + + Keep a synced version of the book in the archived database + + + Sync with archived + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + power_btn + toggled(bool) + group_frm + setEnabled(bool) + + + 22 + 21 + + + 81 + 83 + + + + + diff --git a/gui_sync_item.py b/gui_sync_item.py new file mode 100644 index 0000000..4ebaa1c --- /dev/null +++ b/gui_sync_item.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_sync_item.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_sync_item.ui' applies. +# +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 +# +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore, QtGui, QtWidgets + +class Ui_SyncItem(object): + def setupUi(self, SyncItem): + SyncItem.setObjectName("SyncItem") + SyncItem.resize(446, 25) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(SyncItem) + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.label = QtWidgets.QLabel(SyncItem) + self.label.setObjectName("label") + self.horizontalLayout_2.addWidget(self.label) + self.sync_path_txt = QtWidgets.QLineEdit(SyncItem) + self.sync_path_txt.setReadOnly(True) + self.sync_path_txt.setObjectName("sync_path_txt") + self.horizontalLayout_2.addWidget(self.sync_path_txt) + self.sync_path_btn = QtWidgets.QPushButton(SyncItem) + self.sync_path_btn.setObjectName("sync_path_btn") + self.horizontalLayout_2.addWidget(self.sync_path_btn) + self.frame = QtWidgets.QFrame(SyncItem) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.add_btn = QtWidgets.QToolButton(self.frame) + self.add_btn.setText("") + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/stuff/add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.add_btn.setIcon(icon) + self.add_btn.setObjectName("add_btn") + self.horizontalLayout.addWidget(self.add_btn) + self.del_btn = QtWidgets.QToolButton(self.frame) + self.del_btn.setText("") + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/stuff/del.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.del_btn.setIcon(icon1) + self.del_btn.setObjectName("del_btn") + self.horizontalLayout.addWidget(self.del_btn) + self.horizontalLayout_2.addWidget(self.frame) + + self.retranslateUi(SyncItem) + QtCore.QMetaObject.connectSlotsByName(SyncItem) + + def retranslateUi(self, SyncItem): + self.label.setText(QtWidgets.QApplication.translate("SyncItem", "Sync path", None, -1)) + self.sync_path_txt.setToolTip(QtWidgets.QApplication.translate("SyncItem", "The path to the book\'s metadata file", None, -1)) + self.sync_path_txt.setStatusTip(QtWidgets.QApplication.translate("SyncItem", "The path to the book\'s metadata file", None, -1)) + self.sync_path_txt.setPlaceholderText(QtWidgets.QApplication.translate("SyncItem", "Select metadata file to sync", None, -1)) + self.sync_path_btn.setToolTip(QtWidgets.QApplication.translate("SyncItem", "Select/Change the metadata file path", None, -1)) + self.sync_path_btn.setStatusTip(QtWidgets.QApplication.translate("SyncItem", "Select/Change the metadata file path", None, -1)) + self.sync_path_btn.setText(QtWidgets.QApplication.translate("SyncItem", "Select", None, -1)) + self.add_btn.setToolTip(QtWidgets.QApplication.translate("SyncItem", "Add a new Sync path", None, -1)) + self.add_btn.setStatusTip(QtWidgets.QApplication.translate("SyncItem", "Add a new Sync path", None, -1)) + self.del_btn.setToolTip(QtWidgets.QApplication.translate("SyncItem", "Remove this Sync path", None, -1)) + self.del_btn.setStatusTip(QtWidgets.QApplication.translate("SyncItem", "Remove this Sync path", None, -1)) + +import images_rc diff --git a/gui_sync_item.ui b/gui_sync_item.ui new file mode 100644 index 0000000..9a8aa7b --- /dev/null +++ b/gui_sync_item.ui @@ -0,0 +1,108 @@ + + + SyncItem + + + + 0 + 0 + 446 + 25 + + + + + 0 + + + + + Sync path + + + + + + + The path to the book's metadata file + + + The path to the book's metadata file + + + true + + + Select metadata file to sync + + + + + + + Select/Change the metadata file path + + + Select/Change the metadata file path + + + Select + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + + + Add a new Sync path + + + Add a new Sync path + + + + + + + :/stuff/add.png:/stuff/add.png + + + + + + + Remove this Sync path + + + Remove this Sync path + + + + + + + :/stuff/del.png:/stuff/del.png + + + + + + + + + + + + + diff --git a/gui_toolbar.py b/gui_toolbar.py index 402892d..36e190e 100644 --- a/gui_toolbar.py +++ b/gui_toolbar.py @@ -1,89 +1,95 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_toolbar.ui' +# Form implementation generated from reading ui file 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_toolbar.ui', +# licensing of 'D:\Apps\DEV\PROJECTS\KoHighlights\gui_toolbar.ui' applies. # -# Created: Thu Mar 9 14:39:30 2023 -# by: pyside-uic 0.2.15 running on PySide 1.2.4 +# Created: Thu May 2 17:29:33 2024 +# by: pyside2-uic running on PySide2 5.13.2 # # WARNING! All changes made in this file will be lost! -from PySide import QtCore, QtGui +from PySide2 import QtCore, QtGui, QtWidgets class Ui_ToolBar(object): def setupUi(self, ToolBar): ToolBar.setObjectName("ToolBar") - ToolBar.resize(967, 73) + ToolBar.resize(1035, 91) ToolBar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu) ToolBar.setWindowTitle("") ToolBar.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) - self.verticalLayout_2 = QtGui.QVBoxLayout(ToolBar) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(ToolBar) self.verticalLayout_2.setSpacing(0) self.verticalLayout_2.setContentsMargins(0, 0, 2, 0) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.tool_frame = QtGui.QFrame(ToolBar) + self.tool_frame = QtWidgets.QFrame(ToolBar) self.tool_frame.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tool_frame.setObjectName("tool_frame") - self.horizontalLayout = QtGui.QHBoxLayout(self.tool_frame) + self.horizontalLayout = QtWidgets.QHBoxLayout(self.tool_frame) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") - self.check_btn = QtGui.QToolButton(self.tool_frame) - self.check_btn.setMinimumSize(QtCore.QSize(80, 0)) - self.check_btn.setText("") - icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap("../KataLib/:/stuff/exec.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.check_btn.setIcon(icon) - self.check_btn.setIconSize(QtCore.QSize(48, 48)) - self.check_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) - self.check_btn.setAutoRaise(True) - self.check_btn.setObjectName("check_btn") - self.horizontalLayout.addWidget(self.check_btn) - self.scan_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.scan_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.scan_btn.sizePolicy().hasHeightForWidth()) self.scan_btn.setSizePolicy(sizePolicy) self.scan_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/stuff/folder_reader.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.scan_btn.setIcon(icon1) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/stuff/folder_reader.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.scan_btn.setIcon(icon) self.scan_btn.setIconSize(QtCore.QSize(48, 48)) self.scan_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.scan_btn.setAutoRaise(True) self.scan_btn.setObjectName("scan_btn") self.horizontalLayout.addWidget(self.scan_btn) - self.export_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.export_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.export_btn.sizePolicy().hasHeightForWidth()) self.export_btn.setSizePolicy(sizePolicy) self.export_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/stuff/file_save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.export_btn.setIcon(icon2) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/stuff/file_save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.export_btn.setIcon(icon1) self.export_btn.setIconSize(QtCore.QSize(48, 48)) + self.export_btn.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) self.export_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.export_btn.setAutoRaise(True) self.export_btn.setObjectName("export_btn") self.horizontalLayout.addWidget(self.export_btn) - self.open_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.open_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.open_btn.sizePolicy().hasHeightForWidth()) self.open_btn.setSizePolicy(sizePolicy) self.open_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/stuff/files_view.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.open_btn.setIcon(icon3) + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/stuff/files_view.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.open_btn.setIcon(icon2) self.open_btn.setIconSize(QtCore.QSize(48, 48)) self.open_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.open_btn.setAutoRaise(True) self.open_btn.setObjectName("open_btn") self.horizontalLayout.addWidget(self.open_btn) - self.filter_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.add_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.add_btn.sizePolicy().hasHeightForWidth()) + self.add_btn.setSizePolicy(sizePolicy) + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(":/stuff/files_add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.add_btn.setIcon(icon3) + self.add_btn.setIconSize(QtCore.QSize(48, 48)) + self.add_btn.setChecked(False) + self.add_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) + self.add_btn.setAutoRaise(True) + self.add_btn.setObjectName("add_btn") + self.horizontalLayout.addWidget(self.add_btn) + self.filter_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filter_btn.sizePolicy().hasHeightForWidth()) @@ -98,8 +104,8 @@ def setupUi(self, ToolBar): self.filter_btn.setAutoRaise(True) self.filter_btn.setObjectName("filter_btn") self.horizontalLayout.addWidget(self.filter_btn) - self.merge_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.merge_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.merge_btn.sizePolicy().hasHeightForWidth()) @@ -109,13 +115,13 @@ def setupUi(self, ToolBar): icon5.addPixmap(QtGui.QPixmap(":/stuff/files_merge.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.merge_btn.setIcon(icon5) self.merge_btn.setIconSize(QtCore.QSize(48, 48)) - self.merge_btn.setPopupMode(QtGui.QToolButton.MenuButtonPopup) + self.merge_btn.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) self.merge_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.merge_btn.setAutoRaise(True) self.merge_btn.setObjectName("merge_btn") self.horizontalLayout.addWidget(self.merge_btn) - self.delete_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.delete_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.delete_btn.sizePolicy().hasHeightForWidth()) @@ -125,13 +131,13 @@ def setupUi(self, ToolBar): icon6.addPixmap(QtGui.QPixmap(":/stuff/files_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.delete_btn.setIcon(icon6) self.delete_btn.setIconSize(QtCore.QSize(48, 48)) - self.delete_btn.setPopupMode(QtGui.QToolButton.MenuButtonPopup) + self.delete_btn.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) self.delete_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.delete_btn.setAutoRaise(True) self.delete_btn.setObjectName("delete_btn") self.horizontalLayout.addWidget(self.delete_btn) - self.clear_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.clear_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.clear_btn.sizePolicy().hasHeightForWidth()) @@ -145,15 +151,15 @@ def setupUi(self, ToolBar): self.clear_btn.setAutoRaise(True) self.clear_btn.setObjectName("clear_btn") self.horizontalLayout.addWidget(self.clear_btn) - spacerItem = QtGui.QSpacerItem(86, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtWidgets.QSpacerItem(86, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) - self.view_grp = QtGui.QGroupBox(self.tool_frame) + self.view_grp = QtWidgets.QGroupBox(self.tool_frame) self.view_grp.setObjectName("view_grp") - self.horizontalLayout_3 = QtGui.QHBoxLayout(self.view_grp) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.view_grp) self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.books_view_btn = QtGui.QToolButton(self.view_grp) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + self.books_view_btn = QtWidgets.QToolButton(self.view_grp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.books_view_btn.sizePolicy().hasHeightForWidth()) @@ -169,8 +175,8 @@ def setupUi(self, ToolBar): self.books_view_btn.setAutoRaise(True) self.books_view_btn.setObjectName("books_view_btn") self.horizontalLayout_3.addWidget(self.books_view_btn) - self.high_view_btn = QtGui.QToolButton(self.view_grp) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + self.high_view_btn = QtWidgets.QToolButton(self.view_grp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.high_view_btn.sizePolicy().hasHeightForWidth()) @@ -185,28 +191,44 @@ def setupUi(self, ToolBar): self.high_view_btn.setAutoRaise(True) self.high_view_btn.setObjectName("high_view_btn") self.horizontalLayout_3.addWidget(self.high_view_btn) + self.sync_view_btn = QtWidgets.QToolButton(self.view_grp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.sync_view_btn.sizePolicy().hasHeightForWidth()) + self.sync_view_btn.setSizePolicy(sizePolicy) + icon10 = QtGui.QIcon() + icon10.addPixmap(QtGui.QPixmap(":/stuff/view-sync.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.sync_view_btn.setIcon(icon10) + self.sync_view_btn.setIconSize(QtCore.QSize(48, 48)) + self.sync_view_btn.setCheckable(True) + self.sync_view_btn.setAutoExclusive(True) + self.sync_view_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) + self.sync_view_btn.setAutoRaise(True) + self.sync_view_btn.setObjectName("sync_view_btn") + self.horizontalLayout_3.addWidget(self.sync_view_btn) self.horizontalLayout.addWidget(self.view_grp) - self.mode_grp = QtGui.QGroupBox(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.mode_grp = QtWidgets.QGroupBox(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.mode_grp.sizePolicy().hasHeightForWidth()) self.mode_grp.setSizePolicy(sizePolicy) self.mode_grp.setObjectName("mode_grp") - self.verticalLayout = QtGui.QVBoxLayout(self.mode_grp) + self.verticalLayout = QtWidgets.QVBoxLayout(self.mode_grp) self.verticalLayout.setSpacing(0) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") - self.loaded_btn = QtGui.QToolButton(self.mode_grp) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.loaded_btn = QtWidgets.QToolButton(self.mode_grp) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.loaded_btn.sizePolicy().hasHeightForWidth()) self.loaded_btn.setSizePolicy(sizePolicy) self.loaded_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon10 = QtGui.QIcon() - icon10.addPixmap(QtGui.QPixmap(":/stuff/books.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.loaded_btn.setIcon(icon10) + icon11 = QtGui.QIcon() + icon11.addPixmap(QtGui.QPixmap(":/stuff/books.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.loaded_btn.setIcon(icon11) self.loaded_btn.setIconSize(QtCore.QSize(24, 24)) self.loaded_btn.setCheckable(True) self.loaded_btn.setChecked(True) @@ -216,34 +238,34 @@ def setupUi(self, ToolBar): self.loaded_btn.setObjectName("loaded_btn") self.verticalLayout.addWidget(self.loaded_btn) self.db_btn = XToolButton(self.mode_grp) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.db_btn.sizePolicy().hasHeightForWidth()) self.db_btn.setSizePolicy(sizePolicy) self.db_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon11 = QtGui.QIcon() - icon11.addPixmap(QtGui.QPixmap(":/stuff/db.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.db_btn.setIcon(icon11) + icon12 = QtGui.QIcon() + icon12.addPixmap(QtGui.QPixmap(":/stuff/db.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.db_btn.setIcon(icon12) self.db_btn.setIconSize(QtCore.QSize(24, 24)) self.db_btn.setCheckable(True) self.db_btn.setAutoExclusive(True) - self.db_btn.setPopupMode(QtGui.QToolButton.MenuButtonPopup) + self.db_btn.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) self.db_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.db_btn.setAutoRaise(True) self.db_btn.setObjectName("db_btn") self.verticalLayout.addWidget(self.db_btn) self.horizontalLayout.addWidget(self.mode_grp) - self.about_btn = QtGui.QToolButton(self.tool_frame) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + self.about_btn = QtWidgets.QToolButton(self.tool_frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.about_btn.sizePolicy().hasHeightForWidth()) self.about_btn.setSizePolicy(sizePolicy) self.about_btn.setMinimumSize(QtCore.QSize(80, 0)) - icon12 = QtGui.QIcon() - icon12.addPixmap(QtGui.QPixmap(":/stuff/logo64.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.about_btn.setIcon(icon12) + icon13 = QtGui.QIcon() + icon13.addPixmap(QtGui.QPixmap(":/stuff/logo64.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.about_btn.setIcon(icon13) self.about_btn.setIconSize(QtCore.QSize(48, 48)) self.about_btn.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) self.about_btn.setAutoRaise(True) @@ -255,47 +277,53 @@ def setupUi(self, ToolBar): QtCore.QMetaObject.connectSlotsByName(ToolBar) def retranslateUi(self, ToolBar): - self.scan_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Scans a directory for Koreader metadata files\n" -"Can also be the eReader\'s root directory (Ctrl+L)", None, QtGui.QApplication.UnicodeUTF8)) - self.scan_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Scans a directory for Koreader metadata files. Can also be the eReader\'s root directory (Ctrl+L)", None, QtGui.QApplication.UnicodeUTF8)) - self.scan_btn.setText(QtGui.QApplication.translate("ToolBar", "Scan Directory", None, QtGui.QApplication.UnicodeUTF8)) - self.export_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Export selected highlights (Ctrl+S)", None, QtGui.QApplication.UnicodeUTF8)) - self.export_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Export selected highlights (Ctrl+S)", None, QtGui.QApplication.UnicodeUTF8)) - self.export_btn.setText(QtGui.QApplication.translate("ToolBar", "Export", None, QtGui.QApplication.UnicodeUTF8)) - self.open_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "View the selected book (Ctrl+B)", None, QtGui.QApplication.UnicodeUTF8)) - self.open_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "View the selected book (Ctrl+B)", None, QtGui.QApplication.UnicodeUTF8)) - self.open_btn.setText(QtGui.QApplication.translate("ToolBar", "View", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Open the filtering popup (Alt+F)", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Open the filtering popup (Alt+F)", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setText(QtGui.QApplication.translate("ToolBar", "Filter", None, QtGui.QApplication.UnicodeUTF8)) - self.filter_btn.setShortcut(QtGui.QApplication.translate("ToolBar", "Alt+F", None, QtGui.QApplication.UnicodeUTF8)) - self.merge_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Merge the highlights from the same book in two different\n" + self.tool_frame.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Right-click to change icon size", None, -1)) + self.scan_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Scans a directory for Koreader metadata files\n" +"Can also be the eReader\'s root directory (Ctrl+L)", None, -1)) + self.scan_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Scans a directory for Koreader metadata files. Can also be the eReader\'s root directory (Ctrl+L)", None, -1)) + self.scan_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Scan Directory", None, -1)) + self.export_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Export selected highlights (Ctrl+S)", None, -1)) + self.export_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Export selected highlights (Ctrl+S)", None, -1)) + self.export_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Export", None, -1)) + self.open_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "View the selected book (Ctrl+B)", None, -1)) + self.open_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "View the selected book (Ctrl+B)", None, -1)) + self.open_btn.setText(QtWidgets.QApplication.translate("ToolBar", "View", None, -1)) + self.add_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Add a sync group", None, -1)) + self.add_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Add a sync group", None, -1)) + self.add_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Add", None, -1)) + self.filter_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Open the filtering popup (Alt+F)", None, -1)) + self.filter_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Open the filtering popup (Alt+F)", None, -1)) + self.filter_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Filter", None, -1)) + self.filter_btn.setShortcut(QtWidgets.QApplication.translate("ToolBar", "Alt+F", None, -1)) + self.merge_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Merge the highlights from the same book in two different\n" "devices, and/or sync their reading position.\n" -"Activated only if two entries of the same book are selected.", None, QtGui.QApplication.UnicodeUTF8)) - self.merge_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Merge the highlights from the same book in two different devices, and/or sync their reading position. Activated only if two entries of the same book are selected.", None, QtGui.QApplication.UnicodeUTF8)) - self.merge_btn.setText(QtGui.QApplication.translate("ToolBar", "Merge/Sync", None, QtGui.QApplication.UnicodeUTF8)) - self.delete_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Delete selected Highlights (Del)", None, QtGui.QApplication.UnicodeUTF8)) - self.delete_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Delete selected Highlights (Del)", None, QtGui.QApplication.UnicodeUTF8)) - self.delete_btn.setText(QtGui.QApplication.translate("ToolBar", "Delete", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Clears the books list (Ctrl+Backspace)", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Clears the books list (Ctrl+Backspace)", None, QtGui.QApplication.UnicodeUTF8)) - self.clear_btn.setText(QtGui.QApplication.translate("ToolBar", "Clear List", None, QtGui.QApplication.UnicodeUTF8)) - self.books_view_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Books View", None, QtGui.QApplication.UnicodeUTF8)) - self.books_view_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Books View", None, QtGui.QApplication.UnicodeUTF8)) - self.books_view_btn.setText(QtGui.QApplication.translate("ToolBar", "Books", None, QtGui.QApplication.UnicodeUTF8)) - self.high_view_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Highlights View", None, QtGui.QApplication.UnicodeUTF8)) - self.high_view_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Highlights View", None, QtGui.QApplication.UnicodeUTF8)) - self.high_view_btn.setText(QtGui.QApplication.translate("ToolBar", "Highlights", None, QtGui.QApplication.UnicodeUTF8)) - self.loaded_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Show the loaded files", None, QtGui.QApplication.UnicodeUTF8)) - self.loaded_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Show the loaded files", None, QtGui.QApplication.UnicodeUTF8)) - self.loaded_btn.setText(QtGui.QApplication.translate("ToolBar", "Loaded", None, QtGui.QApplication.UnicodeUTF8)) - self.db_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Show the archived files in the database\n" -"(Right click for database actions menu)", None, QtGui.QApplication.UnicodeUTF8)) - self.db_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Show the archived files in the database (Right click for database actions menu)", None, QtGui.QApplication.UnicodeUTF8)) - self.db_btn.setText(QtGui.QApplication.translate("ToolBar", "Archived", None, QtGui.QApplication.UnicodeUTF8)) - self.about_btn.setToolTip(QtGui.QApplication.translate("ToolBar", "Info about the KoHighlights (Ctrl+I)", None, QtGui.QApplication.UnicodeUTF8)) - self.about_btn.setStatusTip(QtGui.QApplication.translate("ToolBar", "Info about the KoHighlights (Ctrl+I)", None, QtGui.QApplication.UnicodeUTF8)) - self.about_btn.setText(QtGui.QApplication.translate("ToolBar", "About", None, QtGui.QApplication.UnicodeUTF8)) +"Activated only if two entries of the same book are selected.", None, -1)) + self.merge_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Merge the highlights from the same book in two different devices, and/or sync their reading position. Activated only if two entries of the same book are selected.", None, -1)) + self.merge_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Merge/Sync", None, -1)) + self.delete_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Delete selected", None, -1)) + self.delete_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Delete", None, -1)) + self.clear_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Clear the list\'s entries (Ctrl+Backspace)", None, -1)) + self.clear_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Clear the list\'s entries (Ctrl+Backspace)", None, -1)) + self.clear_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Clear List", None, -1)) + self.books_view_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Books View", None, -1)) + self.books_view_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Books View", None, -1)) + self.books_view_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Books", None, -1)) + self.high_view_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Highlights View", None, -1)) + self.high_view_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Highlights View", None, -1)) + self.high_view_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Highlights", None, -1)) + self.sync_view_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Sync Groups View", None, -1)) + self.sync_view_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Sync Groups View", None, -1)) + self.sync_view_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Sync Groups", None, -1)) + self.loaded_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Show the loaded files", None, -1)) + self.loaded_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Show the loaded files", None, -1)) + self.loaded_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Loaded", None, -1)) + self.db_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Show the archived files in the database\n" +"(Right click for database actions menu)", None, -1)) + self.db_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Show the archived files in the database (Right click for database actions menu)", None, -1)) + self.db_btn.setText(QtWidgets.QApplication.translate("ToolBar", "Archived", None, -1)) + self.about_btn.setToolTip(QtWidgets.QApplication.translate("ToolBar", "Info about the KoHighlights (Ctrl+I)", None, -1)) + self.about_btn.setStatusTip(QtWidgets.QApplication.translate("ToolBar", "Info about the KoHighlights (Ctrl+I)", None, -1)) + self.about_btn.setText(QtWidgets.QApplication.translate("ToolBar", "About", None, -1)) from secondary import XToolButton import images_rc diff --git a/gui_toolbar.ui b/gui_toolbar.ui index 804168c..5c95e41 100644 --- a/gui_toolbar.ui +++ b/gui_toolbar.ui @@ -6,8 +6,8 @@ 0 0 - 967 - 73 + 1035 + 91 @@ -40,24 +40,40 @@ Qt::CustomContextMenu + + Right-click to change icon size + 0 - + + + + 0 + 0 + + 80 0 + + Scans a directory for Koreader metadata files +Can also be the eReader's root directory (Ctrl+L) + + + Scans a directory for Koreader metadata files. Can also be the eReader's root directory (Ctrl+L) + - + Scan Directory - ../KataLib/:/stuff/exec.png../KataLib/:/stuff/exec.png + :/stuff/folder_reader.png:/stuff/folder_reader.png @@ -74,7 +90,7 @@ - + 0 @@ -88,18 +104,17 @@ - Scans a directory for Koreader metadata files -Can also be the eReader's root directory (Ctrl+L) + Export selected highlights (Ctrl+S) - Scans a directory for Koreader metadata files. Can also be the eReader's root directory (Ctrl+L) + Export selected highlights (Ctrl+S) - Scan Directory + Export - :/stuff/folder_reader.png:/stuff/folder_reader.png + :/stuff/file_save.png:/stuff/file_save.png @@ -107,6 +122,9 @@ Can also be the eReader's root directory (Ctrl+L) 48 + + QToolButton::MenuButtonPopup + Qt::ToolButtonTextUnderIcon @@ -116,7 +134,7 @@ Can also be the eReader's root directory (Ctrl+L) - + 0 @@ -130,17 +148,17 @@ Can also be the eReader's root directory (Ctrl+L) - Export selected highlights (Ctrl+S) + View the selected book (Ctrl+B) - Export selected highlights (Ctrl+S) + View the selected book (Ctrl+B) - Export + View - :/stuff/file_save.png:/stuff/file_save.png + :/stuff/files_view.png:/stuff/files_view.png @@ -157,31 +175,25 @@ Can also be the eReader's root directory (Ctrl+L) - + 0 0 - - - 80 - 0 - - - View the selected book (Ctrl+B) + Add a sync group - View the selected book (Ctrl+B) + Add a sync group - View + Add - :/stuff/files_view.png:/stuff/files_view.png + :/stuff/files_add.png:/stuff/files_add.png @@ -189,6 +201,9 @@ Can also be the eReader's root directory (Ctrl+L) 48 + + false + Qt::ToolButtonTextUnderIcon @@ -302,10 +317,7 @@ Activated only if two entries of the same book are selected. - Delete selected Highlights (Del) - - - Delete selected Highlights (Del) + Delete selected Delete @@ -346,10 +358,10 @@ Activated only if two entries of the same book are selected. - Clears the books list (Ctrl+Backspace) + Clear the list's entries (Ctrl+Backspace) - Clears the books list (Ctrl+Backspace) + Clear the list's entries (Ctrl+Backspace) Clear List @@ -476,6 +488,47 @@ Activated only if two entries of the same book are selected. + + + + + 0 + 0 + + + + Sync Groups View + + + Sync Groups View + + + Sync Groups + + + + :/stuff/view-sync.png:/stuff/view-sync.png + + + + 48 + 48 + + + + true + + + true + + + Qt::ToolButtonTextUnderIcon + + + true + + + diff --git a/images.qrc b/images.qrc index 0a1187d..b28479e 100644 --- a/images.qrc +++ b/images.qrc @@ -1,36 +1,43 @@ -stuff/files_view.png -stuff/exec.png -stuff/refresh16.png -stuff/copy.png -stuff/file_exists.png +stuff/trash.png +stuff/files_add.png +stuff/db_open.png +stuff/folder_open.png stuff/delete.png -stuff/logo64.png -stuff/filter.png -stuff/paypal.png -stuff/wait.gif +stuff/calendar.png stuff/file_missing.png -stuff/trans32.png +stuff/show_pages.png +stuff/paypal.png +stuff/files_delete.png +stuff/label_green.png stuff/file_edit.png -stuff/folder_reader.png -stuff/sort.png -stuff/db_open.png +stuff/file_exists.png stuff/db_add.png -stuff/books.png -stuff/calendar.png -stuff/view_books.png -stuff/view-highlights.png -stuff/label_green.png +stuff/font.ttf +stuff/copy.png +stuff/power32gray.png stuff/paypal76.png -stuff/logo.png +stuff/folder_reader.png +stuff/view-sync.png +stuff/power32red.png +stuff/sync.png stuff/file_save.png +stuff/files_view.png +stuff/logo64.png +stuff/wait.gif +stuff/trans32.png +stuff/logo.png +stuff/add.png +stuff/db.png +stuff/books.png stuff/description.png -stuff/folder_open.png +stuff/filter.png +stuff/refresh16.png +stuff/view-highlights.png +stuff/view_books.png stuff/files_merge.png -stuff/db.png -stuff/trash.png -stuff/show_pages.png -stuff/files_delete.png +stuff/del.png +stuff/sort.png \ No newline at end of file diff --git a/main.py b/main.py index cdc41e3..7733e33 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,4 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals from boot_config import * from boot_config import _ import os, sys, re @@ -12,54 +11,48 @@ import hashlib from datetime import datetime from functools import partial +from copy import deepcopy from collections import defaultdict +from ntpath import normpath from os.path import (isdir, isfile, join, basename, splitext, dirname, split, getmtime, abspath, splitdrive) from pprint import pprint - -if QT4: # ___ ______________ DEPENDENCIES __________________________ - from PySide.QtSql import QSqlDatabase, QSqlQuery - from PySide.QtCore import (Qt, QTimer, Slot, QThread, QMimeData, QModelIndex, - QByteArray, QPoint) - from PySide.QtGui import (QMainWindow, QApplication, QMessageBox, QIcon, QFileDialog, - QTableWidgetItem, QTextCursor, QMenu, QAction, QHeaderView, - QPixmap, QListWidgetItem, QBrush, QColor) -elif QT5: +if QT5: from PySide2.QtWidgets import (QMainWindow, QHeaderView, QApplication, QMessageBox, QAction, QMenu, QTableWidgetItem, QListWidgetItem, - QFileDialog) + QFileDialog, QComboBox) from PySide2.QtCore import (Qt, QTimer, QThread, QModelIndex, Slot, QPoint, QMimeData, QByteArray) from PySide2.QtSql import QSqlDatabase, QSqlQuery - from PySide2.QtGui import QIcon, QPixmap, QTextCursor, QBrush, QColor + from PySide2.QtGui import QIcon, QPixmap, QTextCursor, QBrush, QColor, QFontDatabase else: # Qt6 from PySide6.QtWidgets import (QMainWindow, QHeaderView, QApplication, QMessageBox, - QFileDialog, QTableWidgetItem, QMenu, QListWidgetItem) + QFileDialog, QTableWidgetItem, QMenu, QListWidgetItem, + QComboBox) from PySide6.QtCore import Qt, QTimer, Slot, QPoint, QThread, QModelIndex, QMimeData - from PySide6.QtGui import QIcon, QAction, QBrush, QColor, QPixmap, QTextCursor + from PySide6.QtGui import (QIcon, QAction, QBrush, QColor, QPixmap, QTextCursor, + QFontDatabase) from PySide6.QtSql import QSqlDatabase, QSqlQuery from secondary import * from gui_main import Ui_Base -if PYTHON2: # ___ __________ PYTHON 2/3 COMPATIBILITY ______________ - import cPickle as pickle - from distutils.version import LooseVersion as version_parse -else: - from packaging.version import parse as version_parse - import pickle +from packaging.version import parse as version_parse +import pickle __author__ = "noEmbryo" -__version__ = "1.7.6.0" +__version__ = "2.0.0.0" class Base(QMainWindow, Ui_Base): def __init__(self, parent=None): super(Base, self).__init__(parent) + # noinspection PyArgumentList + self.app = QApplication.instance() self.scan_thread = None self.setupUi(self) @@ -87,43 +80,46 @@ def __init__(self, parent=None): self.exit_msg = True self.db_path = join(SETTINGS_DIR, "data.db") self.date_vacuumed = datetime.now().strftime(DATE_FORMAT) + self.theme = THEME_NONE_OLD self.date_format = DATE_FORMAT + self.show_items = [True, True, True, True, True] # ___ ___________________________________ self.file_selection = None self.sel_idx = None self.sel_indexes = [] - self.high_view_selection = None - self.sel_high_view = [] self.high_list_selection = None self.sel_high_list = [] + self.high_view_selection = None + self.sel_high_view = [] + self.sync_view_selection = None + self.sel_sync_view = [] self.loaded_paths = set() self.books2reload = set() self.parent_book_data = {} self.reload_highlights = True + self.sync_groups_loaded = False self.threads = [] self.query = None self.db = None self.books = [] + self.sync_groups = [] + tooltip = _("Right click to ignore english articles") + self.file_table.horizontalHeaderItem(TITLE).setToolTip(tooltip) self.header_main = self.file_table.horizontalHeader() self.header_main.setDefaultAlignment(Qt.AlignLeft) self.header_main.setContextMenuPolicy(Qt.CustomContextMenu) self.header_high_view = self.high_table.horizontalHeader() self.header_high_view.setDefaultAlignment(Qt.AlignLeft) # self.header_high_view.setResizeMode(HIGHLIGHT_H, QHeaderView.Stretch) - if QT4: - self.file_table.verticalHeader().setResizeMode(QHeaderView.Fixed) - self.header_main.setMovable(True) - self.high_table.verticalHeader().setResizeMode(QHeaderView.Fixed) - self.header_high_view.setMovable(True) - elif QT5 or QT6: - self.file_table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) - self.header_main.setSectionsMovable(True) - self.high_table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) - self.header_high_view.setSectionsMovable(True) + + self.file_table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) + self.header_main.setSectionsMovable(True) + self.high_table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) + self.header_high_view.setSectionsMovable(True) self.splitter.setCollapsible(0, False) self.splitter.setCollapsible(1, False) @@ -136,19 +132,38 @@ def __init__(self, parent=None): self.ico_file_save = QIcon(":/stuff/file_save.png") self.ico_files_merge = QIcon(":/stuff/files_merge.png") self.ico_files_delete = QIcon(":/stuff/files_delete.png") - self.ico_file_exists = QIcon(":/stuff/file_exists.png") - self.ico_file_missing = QIcon(":/stuff/file_missing.png") + self.ico_db_add = QIcon(":/stuff/db_add.png") + self.ico_db_open = QIcon(":/stuff/db_open.png") + self.ico_refresh = QIcon(":/stuff/refresh16.png") + self.ico_folder_open = QIcon(":/stuff/folder_open.png") + self.ico_calendar = QIcon(":/stuff/calendar.png") + self.ico_sort = QIcon(":/stuff/sort.png") + self.ico_view_books = QIcon(":/stuff/view_books.png") + self.ico_files_view = QIcon(":/stuff/files_view.png") self.ico_file_edit = QIcon(":/stuff/file_edit.png") self.ico_copy = QIcon(":/stuff/copy.png") self.ico_delete = QIcon(":/stuff/delete.png") + self.def_icons = [ + self.ico_file_save, + self.ico_files_merge, + self.ico_files_delete, + self.ico_db_add, + self.ico_db_open, + self.ico_refresh, + self.ico_folder_open, + self.ico_calendar, + self.ico_sort, + self.ico_view_books, + self.ico_files_view, + self.ico_file_edit, + self.ico_copy, + self.ico_delete, + ] + self.ico_file_exists = QIcon(":/stuff/file_exists.png") + self.ico_file_missing = QIcon(":/stuff/file_missing.png") self.ico_label_green = QIcon(":/stuff/label_green.png") - self.ico_view_books = QIcon(":/stuff/view_books.png") - self.ico_db_add = QIcon(":/stuff/db_add.png") - self.ico_db_open = QIcon(":/stuff/db_open.png") self.ico_app = QIcon(":/stuff/logo64.png") self.ico_empty = QIcon(":/stuff/trans32.png") - self.ico_refresh = QIcon(":/stuff/refresh16.png") - self.ico_folder_open = QIcon(":/stuff/folder_open.png") # noinspection PyArgumentList self.clip = QApplication.clipboard() @@ -163,11 +178,18 @@ def __init__(self, parent=None): self.toolbar.merge_btn.setEnabled(False) self.toolbar.delete_btn.setEnabled(False) + self.export_menu = QMenu(self) + self.export_menu.setTitle(_("Export")) + self.export_menu.setIcon(self.ico_file_save) + self.export_menu.aboutToShow.connect(self.create_export_menu) # assign menu + if QT6: # QT6 requires exec() instead of exec_() + self.export_menu.exec_ = getattr(self.export_menu, "exec") + self.toolbar.export_btn.setMenu(self.export_menu) + self.status = Status(self) self.statusbar.addPermanentWidget(self.status) self.edit_high = TextDialog(self) - self.edit_high.on_ok = self.edit_comment_ok self.edit_high.setWindowTitle(_("Comments")) self.description = TextDialog(self) @@ -179,6 +201,19 @@ def __init__(self, parent=None): self.review_lbl.setVisible(False) self.review_txt.setVisible(False) + tbar = self.toolbar + self.def_btn_icos = [] + self.buttons = [(tbar.scan_btn, "A"), (tbar.export_btn, "B"), + (tbar.open_btn, "C"), (tbar.filter_btn, "D"), + (tbar.merge_btn, "E"), (tbar.add_btn, "X"), + (tbar.delete_btn, "O"), (tbar.clear_btn, "G"), + (tbar.books_view_btn, "H"), (tbar.high_view_btn, "I"), + (tbar.sync_view_btn, "W"), (tbar.loaded_btn, "H"), + (tbar.db_btn, "K"), (self.status.show_items_btn, "U"), + (self.description_btn, "V"), (self.filter.filter_btn, "D"), + (self.filter.clear_filter_btn, "G"), + ] + # noinspection PyTypeChecker,PyCallByClass QTimer.singleShot(10000, self.auto_check4update) # check for updates @@ -192,12 +227,15 @@ def __init__(self, parent=None): def on_load(self): """ Things that must be done after the initialization """ + fdb = QFontDatabase() + fdb.addApplicationFont(":/stuff/font.ttf") + # fdb.removeApplicationFont(0) + self.settings_load() self.init_db() if FIRST_RUN: # on first run self.toolbar.loaded_btn.click() self.splitter.setSizes((500, 250)) - self.toolbar.export_btn.setMenu(self.get_export_menu()) # assign/create menu self.toolbar.merge_btn.setMenu(self.merge_menu()) # assign/create menu self.toolbar.delete_btn.setMenu(self.delete_menu()) # assign/create menu self.connect_gui() @@ -210,7 +248,7 @@ def on_load(self): self.toolbar.loaded_btn.setChecked(True) # open in Loaded mode else: self.toolbar.db_btn.setChecked(True) # open in Archived mode - text = _("Loading {} database").format(APP_NAME) + text = _(f"Loading {APP_NAME} database") self.loading_thread(DBLoader, self.books, text) self.read_books_from_db() # always load db on start if self.current_view == BOOKS_VIEW: @@ -218,8 +256,93 @@ def on_load(self): else: self.toolbar.high_view_btn.click() # open in Highlights view + self.setup_buttons() self.show() + def setup_buttons(self): + for btn, char in self.buttons: + self.def_btn_icos.append(btn.icon()) + size = btn.iconSize().toTuple() + btn.xig = XIconGlyph(self, {"family": "XFont", "size": size, "char": char}) + # btn.glyph = btn.xig.get_icon() + + def set_new_icons(self, menus=True): + """ Create the new icons + + :type menus: bool + :param menus: Create the new menu icons too + """ + # noinspection PyTypeChecker + QTimer.singleShot(0, partial(self.delayed_set_new_icons, menus)) + + def delayed_set_new_icons(self, menus=True): + """ Delay the creation of the icons to allow for the new palette to be set + + :type menus: bool + :param menus: Create the menu icons too + """ + for btn, _ in self.buttons: + size = btn.iconSize().toTuple() + btn.setIcon(btn.xig.get_icon({"size": size})) + + if menus: # recreate the menu icons + xig = XIconGlyph(self, {"family": "XFont", "size": (16, 16)}) + self.export_menu.setIcon(xig.get_icon({"char": "B"})) + self.ico_file_save = xig.get_icon({"char": "B"}) + self.ico_files_merge = xig.get_icon({"char": "E"}) + self.ico_files_delete = xig.get_icon({"char": "O"}) + self.ico_db_add = xig.get_icon({"char": "L"}) + self.ico_db_open = xig.get_icon({"char": "M"}) + self.ico_refresh = xig.get_icon({"char": "N"}) + self.ico_folder_open = xig.get_icon({"char": "P"}) + self.ico_calendar = xig.get_icon({"char": "T"}) + self.ico_sort = xig.get_icon({"char": "S"}) + self.ico_view_books = xig.get_icon({"char": "H"}) + self.act_view_book.setIcon(xig.get_icon({"char": "C"})) + self.ico_file_edit = xig.get_icon({"char": "Q"}) + self.ico_copy = xig.get_icon({"char": "R"}) + self.ico_delete = xig.get_icon({"char": "O"}) + + def set_old_icons(self): + """ Reload the old icons + """ + for idx, item in enumerate(self.buttons): + btn = item[0] + btn.setIcon(self.def_btn_icos[idx]) + + self.ico_file_save = self.def_icons[0] + self.ico_files_merge = self.def_icons[1] + self.ico_files_delete = self.def_icons[2] + self.ico_db_add = self.def_icons[3] + self.ico_db_open = self.def_icons[4] + self.ico_refresh = self.def_icons[5] + self.ico_folder_open = self.def_icons[6] + self.ico_calendar = self.def_icons[7] + self.ico_sort = self.def_icons[8] + self.ico_view_books = self.def_icons[9] + self.act_view_book.setIcon(self.def_icons[10]) + self.ico_file_edit = self.def_icons[11] + self.ico_copy = self.def_icons[12] + self.ico_delete = self.def_icons[13] + + def reset_theme_colors(self): + """ Resets the widget colors after a theme change + """ + color = self.app.palette().base().color().name() + self.review_txt.setStyleSheet(f'background-color: "{color}";') + color = self.app.palette().window().color().name() + for item in [self.status.show_items_btn, self.status.theme_box]: + item.setStyleSheet(f'background-color: "{color}";') + + color = self.app.palette().button().color().name() + for row in range(self.sync_table.rowCount()): + wdg = self.sync_table.cellWidget(row, 0) + wdg.setStyleSheet('QFrame#items_frm {background-color: "%s";}' % color) + wdg.setup_icons() + + self.setup_buttons() + self.reload_table(_("Reloading books...")) + # ___ ___________________ EVENTS STUFF __________________________ def connect_gui(self): @@ -237,6 +360,10 @@ def connect_gui(self): self.header_high_view.sectionClicked.connect(self.on_highlight_column_clicked) self.header_high_view.sectionResized.connect(self.on_highlight_column_resized) + self.sync_table.base = self + self.sync_view_selection = self.sync_table.selectionModel() + self.sync_view_selection.selectionChanged.connect(self.sync_view_selection_update) + sys.stdout = LogStream() sys.stdout.setObjectName("out") sys.stdout.append_to_log.connect(self.write_to_log) @@ -255,40 +382,36 @@ def keyPressEvent(self, event): if mod == Qt.ControlModifier: # if control is pressed if key == Qt.Key_Backspace: self.toolbar.on_clear_btn_clicked() - return True - if key == Qt.Key_L: + elif key == Qt.Key_L: self.toolbar.on_scan_btn_clicked() - return True - if key == Qt.Key_S: + elif key == Qt.Key_S: self.on_export() - return True - if key == Qt.Key_I: + elif key == Qt.Key_I: self.toolbar.on_about_btn_clicked() - return True - if key == Qt.Key_F: + elif key == Qt.Key_F: self.toolbar.filter_btn.click() - return True - if key == Qt.Key_Q: + elif key == Qt.Key_Q: self.close() - if self.current_view == HIGHLIGHTS_VIEW and self.sel_high_view: + elif self.current_view == HIGHLIGHTS_VIEW and self.sel_high_view: if key == Qt.Key_C: self.copy_text_2clip(self.get_highlights()[0]) - return True + if mod == Qt.AltModifier: # if alt is pressed if key == Qt.Key_A: self.on_archive() return True - if self.current_view == HIGHLIGHTS_VIEW and self.sel_high_view: + elif self.current_view == HIGHLIGHTS_VIEW and self.sel_high_view: if key == Qt.Key_C: self.copy_text_2clip(self.get_highlights()[1]) return True if key == Qt.Key_Escape: self.close() - return True - if key == Qt.Key_Delete: - self.delete_actions(0) - return True + elif key == Qt.Key_Delete: + if self.current_view == BOOKS_VIEW: + self.delete_actions(0) + else: + self.toolbar.on_delete_btn_clicked() def closeEvent(self, event): """ Accepts or rejects the `exit` command @@ -300,7 +423,7 @@ def closeEvent(self, event): self.bye_bye_stuff() event.accept() return - popup = self.popup(_("Confirmation"), _("Exit {}?").format(APP_NAME), buttons=2, + popup = self.popup(_("Confirmation"), _(f"Exit {APP_NAME}?"), buttons=2, check_text=DO_NOT_SHOW) self.exit_msg = not popup.checked if popup.buttonRole(popup.clickedButton()) == QMessageBox.AcceptRole: @@ -331,7 +454,7 @@ def init_db(self): self.query.exec_ = getattr(self.query, "exec") if app_config: pass - # self.query.exec_("""PRAGMA user_version""") # 2do: enable if db changes + # self.query.exec_("""PRAGMA user_version""") # 2check: enable if db changes # while self.query.next(): # self.check_db_version(self.query.value(0)) # check the db version self.set_db_version() if not isfile(self.db_path) else None @@ -354,7 +477,7 @@ def update_db(self, db_version): def set_db_version(self): """ Set the current database version """ - self.query.exec_("""PRAGMA user_version = {}""".format(DB_VERSION)) + self.query.exec_(f"""PRAGMA user_version = {DB_VERSION}""") def change_db(self, mode): """ Changes the current db file @@ -424,6 +547,7 @@ def add_books2db(self, books): def read_books_from_db(self): """ Reads the contents of the books' db table """ + # print("Reading data from db") del self.books[:] self.query.setForwardOnly(True) self.query.exec_("""SELECT * FROM books""") @@ -494,7 +618,7 @@ def on_file_table_fileDropped(self, dropped): # self.file_table.setSortingEnabled(False) for i in dropped: if splitext(i)[1] == ".lua": - self.create_row(i) + self.create_row(normpath(i)) # self.file_table.setSortingEnabled(True) folders = [j for j in dropped if isdir(j)] for folder in folders: @@ -535,36 +659,44 @@ def populate_book_info(self, data, row): :type row: int :param row: The item's row number """ + stats = "doc_props" if "doc_props" in data else "stats" if "stats" in data else "" for key, field in zip(self.info_keys, self.info_fields): try: - if key == "title" and not data["stats"][key]: + if key == "title" and not data[stats][key]: path = self.file_table.item(row, PATH).data(0) try: name = path.split("#] ")[1] value = splitext(name)[0] except IndexError: # no "#] " in filename value = "" + elif key == "pages": + if "doc_pages" in data: + value = data["doc_pages"] + else: # older type file + value = data[stats][key] elif key == "keywords": keywords = data["doc_props"][key].split("\n") value = "; ".join([i.rstrip("\\") for i in keywords]) else: - value = data["stats"][key] + value = data[stats][key] try: field.setText(value) except TypeError: # Needs string only field.setText(str(value) if value else "") # "" if 0 except KeyError: # older type file or other problems path = self.file_table.item(row, PATH).data(0) - stats = self.get_item_stats(path, data) + stats_ = self.get_item_stats(data, path) if key == "title": - field.setText(stats[1]) + field.setText(stats_["title"]) elif key == "authors": - field.setText(stats[2]) + field.setText(stats_["authors"]) else: field.setText("") review = data.get("summary", {}).get("note", "") self.review_lbl.setVisible(bool(review)) + color = self.app.palette().base().color().name() + self.review_txt.setStyleSheet(f'background-color: "{color}";') self.review_txt.setVisible(bool(review)) self.review_txt.setText(review) @@ -595,12 +727,7 @@ def on_file_table_customContextMenuRequested(self, point): self.act_view_book.setEnabled(self.toolbar.open_btn.isEnabled()) self.act_view_book.setData(row) menu.addAction(self.act_view_book) - - export_menu = self.get_export_menu() - export_menu.setIcon(self.ico_file_save) - export_menu.setTitle(_("Export")) - menu.addMenu(export_menu) - + menu.addMenu(self.export_menu) if not self.db_mode: action = QAction(_("Archive") + "\tAlt+A", menu) action.setIcon(self.ico_db_add) @@ -611,11 +738,28 @@ def on_file_table_customContextMenuRequested(self, point): sync_group = QMenu(self) sync_group.setTitle(_("Sync")) sync_group.setIcon(self.ico_files_merge) - if self.check4archive_merge() is not False: + + action = QAction(_("Create a sync group"), sync_group) + action.setIcon(self.ico_files_merge) + path = self.file_table.item(row, PATH).data(0) + title = self.file_table.item(row, TITLE).data(0) + data = self.file_table.item(row, TITLE).data(Qt.UserRole) + book_data = {"path": path, "data": data} + info = {"title": title, + "sync_pos": False, + "merge": False, + "sync_db": True, + "items": [book_data], + "enabled": True} + action.triggered.connect(partial(self.create_sync_row, info)) + sync_group.addAction(action) + + if self.check4archive_merge(book_data) is not False: sync_menu = self.create_archive_merge_menu() sync_menu.setTitle(_("Sync with archived")) sync_menu.setIcon(self.ico_files_merge) sync_group.addMenu(sync_menu) + action = QAction(_("Sync with file"), sync_group) action.setIcon(self.ico_files_merge) action.triggered.connect(self.use_meta_files) @@ -635,11 +779,20 @@ def on_file_table_customContextMenuRequested(self, point): action.triggered.connect(partial(self.open_file, folder_path)) menu.addAction(action) + elif len(self.sel_indexes) == 2: + if self.toolbar.merge_btn.isEnabled(): + action = QAction(_("Sync books"), menu) + action.setIcon(self.ico_files_merge) + action.triggered.connect(self.toolbar.on_merge_btn_clicked) + menu.addAction(action) + + menu.addSeparator() delete_menu = self.delete_menu() delete_menu.setIcon(self.ico_files_delete) delete_menu.setTitle(_("Delete") + "\tDel") menu.addMenu(delete_menu) else: + menu.addSeparator() action = QAction(_("Delete") + "\tDel", menu) action.setIcon(self.ico_files_delete) action.triggered.connect(partial(self.delete_actions, 0)) @@ -673,7 +826,7 @@ def get_book_path(meta_path, data): ext = splitext(meta_path)[1] book_path = splitext(split(meta_path)[0])[0] + ext book_exists = isfile(book_path) - if not book_exists: # use the recorded file path + if not book_exists: # use the recorded file path (newer metadata only) doc_path = data.get("doc_path") if doc_path: drive = splitdrive(meta_path)[0] @@ -719,6 +872,8 @@ def file_selection_update(self, selected, deselected): else: self.high_list.clear() self.description_btn.setEnabled(False) + self.review_txt.hide() + self.review_lbl.hide() for field in self.info_fields: field.setText("") self.toolbar.activate_buttons() @@ -760,7 +915,9 @@ def toggle_title_sort(self): """ Toggles the way titles are sorted (use or not A/The) """ self.alt_title_sort = not self.alt_title_sort - text = _("ReSorting books...") + self.reload_table(_("ReSorting books...")) + + def reload_table(self, text): if not self.db_mode: self.loading_thread(ReLoader, self.loaded_paths.copy(), text) else: @@ -790,7 +947,7 @@ def on_archive(self): if self.archive_warning: # warn about book replacement in archive extra = _("these books") if len(self.sel_indexes) > 1 else _("this book") popup = self.popup(_("Question!"), - _("Add or replace {} in the archive?").format(extra), + _(f"Add or replace {extra} in the archive?"), buttons=2, icon=QMessageBox.Question, check_text=DO_NOT_SHOW) self.archive_warning = not popup.checked @@ -806,9 +963,18 @@ def on_archive(self): path = self.file_table.item(row, PATH).text() date = self.file_table.item(row, MODIFIED).text() data = self.file_table.item(row, TITLE).data(Qt.UserRole) - if not data["highlight"]: # no highlights, don't add - empty += 1 - continue + annotations = data.get("annotations") + if annotations is not None: # new format metadata + for high_idx in annotations: + if annotations[high_idx]["pos0"]: + break # there is at least one highlight in the book + else: # no highlights don't add + empty += 1 + continue + else: # old format metadata + if not data["highlight"]: # no highlights, don't add + empty += 1 + continue try: md5 = data["partial_md5_checksum"] except KeyError: # older metadata, don't add @@ -823,24 +989,24 @@ def on_archive(self): extra = "" if empty: - extra += _("\nNot added {} books with no highlights.").format(empty) + extra += _(f"\nNot added {empty} books with no highlights.") if older: - extra += _("\nNot added {} books with old type metadata.").format(older) + extra += _(f"\nNot added {older} books with old type metadata.") self.popup(_("Added!"), - _("{} books were added/updated to the Archive from the {} processed.") - .format(added, len(self.sel_indexes)) + extra, + _(f"{added} books were added/updated to the Archive from the " + f"{len(self.sel_indexes)} processed."), icon=QMessageBox.Information) def loading_thread(self, worker, args, text, clear=True): """ Populates the file_table with different contents """ - if clear: + if clear and self.current_view != SYNC_VIEW: self.toolbar.on_clear_btn_clicked() self.file_table.setSortingEnabled(False) # re-enable it after populating table self.status.animation(True) - self.auto_info.set_text(_("{}.\nPlease Wait...").format(text)) + self.auto_info.set_text(_(f"{text}.\nPlease Wait...")) self.auto_info.show() scan_thread = QThread() @@ -884,20 +1050,26 @@ def create_row(self, meta_path, data=None, date=None): if meta_path in self.loaded_paths: return # already loaded file self.loaded_paths.add(meta_path) - data = decode_data(meta_path) + try: + data = decode_data(meta_path) + except PermissionError: + self.base.error(_(f"Could not access the book's metadata file\n" + f"{meta_path}")) + return if not data: print("No data here!", meta_path) return date = str(datetime.fromtimestamp(getmtime(meta_path))).split(".")[0] - stats = self.get_item_stats(meta_path, data) + stats = self.get_item_stats(data, meta_path) else: # for db entries - stats = self.get_item_db_stats(data) - icon, title, authors, percent, rating, status, high_count = stats - - # noinspection PyArgumentList - color = ("#660000" if status == "abandoned" else - # "#005500" if status == "complete" else - QApplication.palette().text().color()) + stats = self.get_item_stats(data) + title = stats["title"] + authors = stats["authors"] + percent = stats["percent"] + rating = stats["rating"] + status = stats["status"] + high_count = stats["high_count"] + icon = self.ico_label_green if high_count else self.ico_empty self.file_table.setSortingEnabled(False) self.file_table.insertRow(0) @@ -917,7 +1089,7 @@ def create_row(self, meta_path, data=None, date=None): book_icon = self.ico_file_exists if book_exists else self.ico_file_missing type_item = QTableWidgetItem(book_icon, ext) type_item.setToolTip(book_path if book_exists else - _("The {} file is missing!").format(ext)) + _(f"The {ext} file is missing!")) type_item.setData(Qt.UserRole, (book_path, book_exists)) self.file_table.setItem(0, TYPE, type_item) @@ -945,71 +1117,58 @@ def create_row(self, meta_path, data=None, date=None): for i in range(8): # colorize row item = self.file_table.item(0, i) - item.setForeground(QBrush(QColor(color))) + if status == "abandoned": + if self.theme in (THEME_DARK_NEW, THEME_DARK_OLD): + color = "#DD0000" + else: + color = "#660000" + item.setForeground(QBrush(QColor(color))) self.file_table.setSortingEnabled(True) - def get_item_db_stats(self, data): - """ Returns the title and authors of a history file + @staticmethod + def get_item_stats(data, filename=None): + """ Returns the title and authors of a metadata file :type data: dict :param data: The dict converted lua file - """ - if data["highlight"]: - icon = self.ico_label_green - high_count = str(len(data["highlight"])) - else: - icon = self.ico_empty - high_count = "" - title = data["stats"]["title"] - authors = data["stats"]["authors"] - title = title if title else NO_TITLE - authors = authors if authors else NO_AUTHOR - try: - percent = str(int(data["percent_finished"] * 100)) + "%" - except KeyError: - percent = "" - if "summary" in data: - rating = data["summary"].get("rating") - rating = rating * "*" if rating else "" - status = data["summary"].get("status") - else: - rating = "" - status = None - - return icon, title, authors, percent, rating, status, high_count - - def get_item_stats(self, filename, data): - """ Returns the title and authors of a metadata file - :type filename: str|unicode :param filename: The filename to get the stats for - :type data: dict - :param data: The dict converted lua file """ - if data["highlight"]: - icon = self.ico_label_green - high_count = str(len(data["highlight"])) - else: - icon = self.ico_empty - high_count = "" - try: - title = data["stats"]["title"] - authors = data["stats"]["authors"] - except KeyError: # older type file - title = splitext(basename(filename))[0] - try: - name = title.split("#] ")[1] - title = splitext(name)[0] - except IndexError: # no "#] " in filename - pass - authors = OLD_TYPE - if not title: + stats = "doc_props" if "doc_props" in data else "stats" if "stats" in data else "" + if filename: # stats from a file try: - name = filename.split("#] ")[1] - title = splitext(name)[0] - except IndexError: # no "#] " in filename - title = NO_TITLE - authors = authors if authors else NO_AUTHOR + title = data[stats]["title"] + authors = data[stats]["authors"] + except KeyError: # much older type file + title = splitext(basename(filename))[0] + try: + name = title.split("#] ")[1] + title = splitext(name)[0] + except IndexError: # no "#] " in filename + pass + authors = OLD_TYPE + if not title: + try: + name = filename.split("#] ")[1] + title = splitext(name)[0] + except IndexError: # no "#] " in filename + title = NO_TITLE + authors = authors if authors else NO_AUTHOR + else: # stats from a db entry + title = data[stats]["title"] + authors = data[stats]["authors"] + + annotations = data.get("annotations") + if annotations is not None: # new format metadata + high_count = len([i for i in annotations.values() if i.get("pos0")]) + else: # old format metadata + high_count = 0 + if data["highlight"]: + for page in data["highlight"]: + high_count += len(data["highlight"][page]) + high_count = str(high_count) if high_count else "" + high_count = str(high_count) if high_count else "" + try: percent = str(int(data["percent_finished"] * 100)) + "%" except KeyError: @@ -1021,110 +1180,575 @@ def get_item_stats(self, filename, data): else: rating = "" status = None + return {"title": title, "authors": authors, "percent": percent, + "rating": rating, "status": status, "high_count": high_count} - return icon, title, authors, percent, rating, status, high_count - - # ___ ___________________ HIGHLIGHT TABLE STUFF _________________ + # ___ ___________________ HIGHLIGHTS LIST STUFF _________________ - @Slot(QTableWidgetItem) - def on_high_table_itemClicked(self, item): - """ When an item of the high_table is clicked + def populate_high_list(self, data, path=""): + """ Populates the Highlights list of `Book` view - :type item: QTableWidgetItem - :param item: The item (cell) that is clicked + :type data: dict + :param data: The item/book's data + :type path: str|unicode + :param path: The item/book's path """ - row = item.row() - path = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole)["path"] + space = (" " if self.status.act_page.isChecked() and + self.status.act_date.isChecked() else "") + line_break = (":\n" if self.status.act_page.isChecked() or + self.status.act_date.isChecked() else "") + def_date_format = self.date_format == DATE_FORMAT + highlights = self.get_highlights_from_data(data, path) + for i in sorted(highlights, key=self.sort_high4view): + chapter_text = (f"[{i['chapter']}]\n" + if (i["chapter"] and self.status.act_chapter.isChecked()) + else "") + page_text = (_(f"Page {i['page']}") + if self.status.act_page.isChecked() else "") + date = i["date"] if def_date_format else self.get_date_text(i["date"]) + date_text = "[" + date + "]" if self.status.act_date.isChecked() else "" + high_text = i["text"] if self.status.act_text.isChecked() else "" + line_break2 = ("\n" if self.status.act_comment.isChecked() and i["comment"] + else "") + high_comment = line_break2 + "● " + i["comment"] if line_break2 else "" + highlight = (page_text + space + date_text + line_break + chapter_text + + high_text + high_comment + "\n") - # needed for edit "Comments" or "Find in Books" in Highlight View - for row in range(self.file_table.rowCount()): # 2check: need to optimize? - if path == self.file_table.item(row, TYPE).data(Qt.UserRole)[0]: - self.parent_book_data = self.file_table.item(row, TITLE).data(Qt.UserRole) - break + highlight_item = QListWidgetItem(highlight, self.high_list) + highlight_item.setData(Qt.UserRole, i) - @Slot(QModelIndex) - def on_high_table_doubleClicked(self, index): - """ When an item of the high_table is double-clicked + def get_highlights_from_data(self, data, path="", meta_path=""): + """ Get the HighLights from the .sdr data - :type index: QTableWidgetItem - :param index: The item (cell) that is clicked + :type data: dict + :param data: The lua converted book data + :type path: str|unicode + :param path: The book's path + :type meta_path: str|unicode + :param meta_path: The book metadata file's path """ - column = index.column() - if column == COMMENT_H: - self.on_edit_comment() + stats = "doc_props" if "doc_props" in data else "stats" if "stats" in data else "" + authors = data.get(stats, {}).get("authors", NO_AUTHOR) + title = data.get(stats, {}).get("title", NO_TITLE) + common = {"authors": authors, "title": title, + "path": path, "meta_path": meta_path} - @Slot(QPoint) - def on_high_table_customContextMenuRequested(self, point): - """ When an item of the high_table is right-clicked + highlights = [] + annotations = data.get("annotations") + if annotations is not None: # new format metadata + for idx in annotations: + highlight = self.get_new_highlight_info(data, idx) + if highlight: + # noinspection PyTypeChecker + highlight.update(common) + highlights.append(highlight) + else: + for page in data["highlight"]: + for page_id in data["highlight"][page]: + highlight = self.get_old_highlight_info(data, page, page_id) + if highlight: + # noinspection PyTypeChecker + highlight.update(common) + highlights.append(highlight) + return highlights - :type point: QPoint - :param point: The point where the right-click happened - """ - if not len(self.sel_high_view): # no items selected - return + @staticmethod + def get_new_highlight_info(data, idx): + """ Get the highlight's info (text, comment, date and page) [new format] - menu = QMenu(self.high_table) - if QT6: # QT6 requires exec() instead of exec_() - menu.exec_ = getattr(menu, "exec") + :type data: dict + :param data: The book's metadata + :type idx: int + :param idx: The highlight's idx + """ + high_stuff = data["annotations"][idx] + if not high_stuff.get("pos0"): + return # this is a bookmark not a highlight + pages = data["doc_pages"] + page = high_stuff.get("pageno", 0) + highlight = {"text": high_stuff.get("text", "").replace("\\\n", "\n"), + "chapter": high_stuff.get("chapter", ""), + "comment": high_stuff.get("note", "").replace("\\\n", "\n"), + "date": high_stuff.get("datetime", ""), "idx": idx, + "page": page, "pages": pages, "new": True} + return highlight - row = self.high_table.itemAt(point).row() - self.act_view_book.setData(row) - self.act_view_book.setEnabled(self.toolbar.open_btn.isEnabled()) - menu.addAction(self.act_view_book) + @staticmethod + def get_old_highlight_info(data, page, page_id): + """ Get the highlight's info (text, comment, date and page) - highlights, comments = self.get_highlights() + :type data: dict + :param data: The highlight's data + :type page: int + :param page The page where the highlight starts + :type page_id: int + :param page_id The count of this page's highlight + """ + pages = data.get("doc_pages", data.get("stats", {}).get("pages", 0)) + highlight = {"page": str(page), "page_id": page_id, "pages": pages, "new": False} + try: + high_stuf = data["highlight"][page][page_id] + date = high_stuf["datetime"] + text4check = high_stuf["text"] + chapter = high_stuf.get("chapter", "") + pat = r"Page \d+ (.+?) @ \d+-\d+-\d+ \d+:\d+:\d+" + text = text4check.replace("\\\n", "\n") + comment = "" + for idx in data["bookmarks"]: # check for comment text + if text4check == data["bookmarks"][idx]["notes"]: + bkm_text = data["bookmarks"][idx].get("text", "") + if not bkm_text or (bkm_text == text4check): + break + bkm_text = re.sub(pat, r"\1", bkm_text, 1, re.DOTALL | re.MULTILINE) + if text4check != bkm_text: # there is a comment + comment = bkm_text.replace("\\\n", "\n") + break + highlight["date"] = date + highlight["text"] = text + highlight["comment"] = comment + highlight["chapter"] = chapter + except KeyError: # blank highlight + return + return highlight - high_text = _("Copy Highlights") - com_text = _("Copy Comments") - if len(self.sel_high_view) == 1: # single selection - high_text = _("Copy Highlight") - com_text = _("Copy Comment") + @Slot(QPoint) + def on_high_list_customContextMenuRequested(self, point): + """ When a highlight is right-clicked - text = _("Find in Archive") if self.db_mode else _("Find in Books") - action = QAction(text, menu) - action.triggered.connect(partial(self.find_in_books, highlights)) - action.setIcon(self.ico_view_books) - menu.addAction(action) + :type point: QPoint + :param point: The point where the right-click happened + """ + if self.sel_high_list: + menu = QMenu(self.high_list) + if QT6: # QT6 requires exec() instead of exec_() + menu.exec_ = getattr(menu, "exec") - action = QAction(_("Comments"), menu) + action = QAction(_("Comment"), menu) action.triggered.connect(self.on_edit_comment) action.setIcon(self.ico_file_edit) menu.addAction(action) - action = QAction(high_text + "\tCtrl+C", menu) - action.triggered.connect(partial(self.copy_text_2clip, highlights)) - action.setIcon(self.ico_copy) - menu.addAction(action) + action = QAction(_("Copy"), menu) + action.triggered.connect(self.on_copy_highlights) + action.setIcon(self.ico_copy) + menu.addAction(action) - action = QAction(com_text + "\tAlt+C", menu) - action.triggered.connect(partial(self.copy_text_2clip, comments)) - action.setIcon(self.ico_copy) - menu.addAction(action) + menu.addSeparator() - action = QAction(_("Export to file"), menu) - action.triggered.connect(self.on_export) - action.setData(2) - action.setIcon(self.ico_file_save) - menu.addAction(action) + action = QAction(_("Delete"), menu) + action.triggered.connect(self.on_delete_highlights) + action.setIcon(self.ico_delete) + menu.addAction(action) - menu.exec_(self.high_table.mapToGlobal(point)) + menu.exec_(self.high_list.mapToGlobal(point)) - def get_highlights(self): - """ Returns the selected highlights and the comments texts + @Slot() + def on_high_list_itemDoubleClicked(self): + """ An item on the Highlight List is double-clicked """ - highlights = "" - comments = "" - for idx in self.sel_high_view: - item_row = idx.row() - data = self.high_table.item(item_row, HIGHLIGHT_H).data(Qt.UserRole) - highlight = data["text"] - if highlight: - highlights += highlight + "\n\n" - comment = data["comment"] - if comment: - comments += comment + "\n\n" - highlights = highlights.rstrip("\n").replace("\n", os.linesep) - comments = comments.rstrip("\n").replace("\n", os.linesep) + self.on_edit_comment() + + def on_edit_comment(self): + """ Opens a window to edit the selected highlight's comment + """ + if self.file_table.isVisible(): # edit comments from Book View + row = self.sel_high_list[-1].row() + comment = self.high_list.item(row).data(Qt.UserRole)["comment"] + elif self.high_table.isVisible(): # edit comments from Highlights View + row = self.sel_high_view[-1].row() + high_data = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) + comment = high_data["comment"] + else: + return + self.edit_high.high_edit_txt.setText(comment) + # self.edit_high.high_edit_txt.setFocus() + if QT6: # QT6 requires exec() instead of exec_() + self.edit_high.exec_ = getattr(self.edit_high, "exec") + self.edit_high.exec_() + + def edit_comment_ok(self): + """ Change the selected highlight's comment + """ + note = self.edit_high.high_edit_txt.toPlainText() + if self.file_table.isVisible(): # update comment from Book table + high_row = self.sel_high_list[-1].row() + high_data = self.high_list.item(high_row).data(Qt.UserRole) + item = self.file_table.item + row = self.sel_idx.row() + data = item(row, TITLE).data(Qt.UserRole) + self.update_comment(data, high_data, note) + + if not self.db_mode: # Loaded mode + path = item(row, PATH).text() + self.save_book_data(path, data) + else: # Archived mode + self.update_book2db(data) + self.on_file_table_itemClicked(item(row, 0), reset=False) + + elif self.high_table.isVisible(): # update comment from Highlights table + row = self.sel_high_view[-1].row() + high_data = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) + meta_path = high_data["meta_path"] + data = self.get_parent_book_data(row)[0] + + self.update_comment(data, high_data, note) + self.high_table.item(row, HIGHLIGHT_H).setData(Qt.UserRole, high_data) + self.high_table.item(row, COMMENT_H).setText(note) + + if not self.db_mode: # Loaded mode + self.save_book_data(meta_path, data) + else: # Archived mode + self.update_book2db(data) + + self.reload_highlights = True + + @staticmethod + def update_comment(data, high_data, note): + """ Update the comment of the selected highlight + """ + date = datetime.now().strftime(DATE_FORMAT) + high_text = high_data["text"].replace("\n", "\\\n") + annotations = data.get("annotations") + if annotations is not None: # new format metadata + for idx in annotations: + if high_text == annotations[idx]["text"]: + annotations[idx]["note"] = note.replace("\n", "\\\n") + annotations[idx]["datetime"] = date # update last edit date + high_data["comment"] = note + break + else: # old format metadata + for bkm in data["bookmarks"]: + if high_text == data["bookmarks"][bkm]["notes"]: + high_data["comment"] = note + data["bookmarks"][bkm]["text"] = note.replace("\n", "\\\n") + data["bookmarks"][bkm]["datetime"] = date # update bkm edit date + for pg in data["highlight"]: # and highlight's too + for pg_id in data["highlight"][pg]: + if data["highlight"][pg][pg_id]["text"] == high_text: + data["highlight"][pg][pg_id]["datetime"] = date + break + + def on_copy_highlights(self): + """ Copy the selected highlights to clipboard + """ + clipboard_text = "" + for highlight in sorted(self.sel_high_list): + row = highlight.row() + text = self.high_list.item(row).text() + clipboard_text += text + "\n" + self.copy_text_2clip(clipboard_text) + + def on_delete_highlights(self): + """ The delete highlights action was invoked + """ + if not self.db_mode: + if self.edit_lua_file_warning: + text = _("This is an one-time warning!\n\nIn order to delete highlights " + "from a book, its \"metadata\" file must be edited. This " + "contains a small risk of corrupting that file and lose all the " + "settings and info of that book.\n\nDo you still want to do it?") + popup = self.popup(_("Warning!"), text, buttons=2, + button_text=(_("Yes"), _("No"))) + if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: + return + else: + self.edit_lua_file_warning = False + text = _("This will delete the selected highlights!\nAre you sure?") + else: + text = _("This will remove the selected highlights from the Archive!\n" + "Are you sure?") + popup = self.popup(_("Warning!"), text, buttons=2, + button_text=(_("Yes"), _("No"))) + if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: + return + self.delete_highlights() + + def delete_highlights(self): + """ Delete the selected highlights + """ + if self.file_table.isVisible(): # delete comments from Book table + row = self.sel_idx.row() + data = self.file_table.item(row, TITLE).data(Qt.UserRole) + hi_count = int(self.file_table.item(row, HIGH_COUNT).text()) + annotations = data.get("annotations") + if annotations is not None: # new format metadata + for high in self.sel_high_list: + high_data = self.high_list.item(high.row()).data(Qt.UserRole) + idx = high_data["idx"] + del annotations[idx] # delete the highlight + hi_count -= 1 + self.finalize_new_highs(data) + else: # old format metadata + for high in self.sel_high_list: + high_data = self.high_list.item(high.row()).data(Qt.UserRole) + self.del_old_high(data, high_data) + hi_count -= 1 + self.finalize_old_highs(data) + self.update_and_save_meta(row, data, hi_count) + self.reload_highlights = True + elif self.high_table.isVisible(): # delete comments from Highlights table + hi2del = {} + idx2del = [] + for hi_idx in self.sel_high_view: # collect the data from the highlights + row = hi_idx.row() + high_data = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) + data = self.get_parent_book_data(row)[0] + meta_path = high_data["meta_path"] + idx2del.append(row) + data_list = hi2del.get(meta_path, []) + data_list.append((data, high_data, row)) + hi2del[meta_path] = data_list + + for meta_path, data_list in hi2del.items(): + book_row = 0 + for book_row in range(self.file_table.rowCount()): + if self.file_table.item(book_row, PATH).text() == meta_path: + break + hi_count = self.file_table.item(book_row, HIGH_COUNT).text() + hi_count = int(hi_count) if hi_count else 0 + new_format = False + data = None + for data, high_data, row in data_list: + annotations = data.get("annotations") + if annotations is not None: # new format metadata + new_format = True + idx = high_data["idx"] + del annotations[idx] # delete the highlight + hi_count -= 1 + else: # old format metadata + self.del_old_high(data, high_data) + hi_count -= 1 + if new_format: + self.finalize_new_highs(data) + else: + self.finalize_old_highs(data) # data is same for same meta_path + self.update_and_save_meta(book_row, data, hi_count) + + idx2del = sorted(idx2del, reverse=True) + for hi_idx in idx2del: + self.high_table.removeRow(hi_idx) + + @staticmethod + def finalize_new_highs(data): + annotations = data.get("annotations") + new_annot = {idx + 1: annotations[i] # renumbering the annotations + for idx, i in enumerate(sorted(annotations))} + if new_annot: + data["annotations"] = new_annot + + @staticmethod + def del_old_high(data, hi_data): + page = int(hi_data["page"]) + page_id = hi_data["page_id"] + del data["highlight"][page][page_id] # delete the highlight + text = hi_data["text"] # delete the associated bookmark + for bookmark in list(data["bookmarks"].keys()): + if text == data["bookmarks"][bookmark]["notes"]: + del data["bookmarks"][bookmark] + + @staticmethod + def finalize_old_highs(data): + for i in list(data["highlight"].keys()): + if not data["highlight"][i]: # delete page dicts with no highlights + del data["highlight"][i] + else: # renumbering the highlight keys + contents = [data["highlight"][i][j] for j in sorted(data["highlight"][i])] + if contents: + for l in list(data["highlight"][i].keys()): + del data["highlight"][i][l] # delete all the items and + for k in range(len(contents)): # rewrite with the new keys + data["highlight"][i][k + 1] = contents[k] + contents = [data["bookmarks"][bookmark] for bookmark in sorted(data["bookmarks"])] + if contents: # renumbering the bookmarks keys + for bookmark in list(data["bookmarks"].keys()): + del data["bookmarks"][bookmark] # delete all the items and + for content in range(len(contents)): # rewrite them with the new keys + data["bookmarks"][content + 1] = contents[content] + + def update_and_save_meta(self, row, data, hi_count): + if not hi_count: # change icon if no highlights + self.file_table.item(row, TITLE).setIcon(self.ico_empty) + hi_count = "" + self.file_table.item(row, HIGH_COUNT).setText(str(hi_count)) + self.file_table.item(row, HIGH_COUNT).setToolTip(str(hi_count)) + if not self.db_mode: + path = self.file_table.item(row, PATH).text() + data["annotations_externally_modified"] = True + self.save_book_data(path, data) + else: + self.update_book2db(data) + self.on_file_table_itemClicked(self.file_table.item(row, TITLE), reset=False) + + def save_book_data(self, path, data): + """ Saves the data of a book to its lua file + + :type path: str|unicode + :param path: The path to the book's data file + :type data: dict + :param data: The book's data + """ + times = os.stat(path) # read the file's created/modified times + encode_data(path, data) + if data.get("summary", {}).get("status") in ["abandoned", "complete"]: + os.utime(path, (times.st_ctime, times.st_mtime)) # reapply original times + if self.file_table.isVisible(): + self.on_file_table_itemClicked(self.file_table.item(self.sel_idx.row(), 0), + reset=False) + + # noinspection PyUnusedLocal + def high_list_selection_update(self, selected, deselected): + """ When a highlight in gets selected + + :type selected: QModelIndex + :parameter selected: The selected highlight + :type deselected: QModelIndex + :parameter deselected: The deselected highlight + """ + self.sel_high_list = self.high_list_selection.selectedRows() + + def set_highlight_sort(self): + """ Sets the sorting method of displayed highlights + """ + self.high_by_page = self.sender().data() + try: + row = self.sel_idx.row() + self.on_file_table_itemClicked(self.file_table.item(row, 0), False) + except AttributeError: # no book selected + pass + + def sort_high4view(self, data): + """ Sets the sorting method of displayed highlights + + :type data: tuple + param: data: The highlight's data + """ + if not self.high_by_page: + return data["date"] + else: + return int(data["page"]) + + def sort_high4write(self, data): + """ Sets the sorting method of written highlights + + :type data: tuple + param: data: The highlight's data + """ + if self.high_by_page and self.status.act_page.isChecked(): + page = data[3] + if page.startswith("Page"): + page = page[5:] + return int(page) + else: + return data[0] + + # ___ ___________________ HIGHLIGHT TABLE STUFF _________________ + + @Slot(QTableWidgetItem) + def on_high_table_itemClicked(self, item): + """ When an item of the high_table is clicked + + :type item: QTableWidgetItem + :param item: The item (cell) that is clicked + """ + # row = item.row() + # self.get_parent_book_data(row) + + def get_parent_book_data(self, row): + meta_path = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole)["meta_path"] + for row in range(self.file_table.rowCount()): # 2check: need to optimize? + if meta_path == self.file_table.item(row, PATH).data(0): + parent_book_data = self.file_table.item(row, TITLE).data(Qt.UserRole) + return parent_book_data, meta_path + + @Slot(QModelIndex) + def on_high_table_doubleClicked(self, index): + """ When an item of the high_table is double-clicked + + :type index: QTableWidgetItem + :param index: The item (cell) that is clicked + """ + column = index.column() + if column == COMMENT_H: + self.on_edit_comment() + + @Slot(QPoint) + def on_high_table_customContextMenuRequested(self, point): + """ When an item of the high_table is right-clicked + + :type point: QPoint + :param point: The point where the right-click happened + """ + if not len(self.sel_high_view): # no items selected + return + + menu = QMenu(self.high_table) + if QT6: # QT6 requires exec() instead of exec_() + menu.exec_ = getattr(menu, "exec") + + row = self.high_table.itemAt(point).row() + self.act_view_book.setData(row) + self.act_view_book.setEnabled(self.toolbar.open_btn.isEnabled()) + menu.addAction(self.act_view_book) + + highlights, comments = self.get_highlights() + + high_text = _("Copy Highlights") + com_text = _("Copy Comments") + if len(self.sel_high_view) == 1: # single selection + high_text = _("Copy Highlight") + com_text = _("Copy Comment") + + text = _("Find in Archive") if self.db_mode else _("Find in Books") + action = QAction(text, menu) + action.triggered.connect(partial(self.find_in_books, highlights, row)) + action.setIcon(self.ico_view_books) + menu.addAction(action) + + action = QAction(_("Comments"), menu) + action.triggered.connect(self.on_edit_comment) + action.setIcon(self.ico_file_edit) + menu.addAction(action) + + action = QAction(high_text + "\tCtrl+C", menu) + action.triggered.connect(partial(self.copy_text_2clip, highlights)) + action.setIcon(self.ico_copy) + menu.addAction(action) + + action = QAction(com_text + "\tAlt+C", menu) + action.triggered.connect(partial(self.copy_text_2clip, comments)) + action.setIcon(self.ico_copy) + menu.addAction(action) + + action = QAction(_("Export to file"), menu) + action.triggered.connect(self.on_export) + action.setData(2) + action.setIcon(self.ico_file_save) + menu.addAction(action) + + menu.addSeparator() + action = QAction(_("Delete") + "\tDel", menu) + action.setIcon(self.ico_files_delete) + action.triggered.connect(self.toolbar.on_delete_btn_clicked) + menu.addAction(action) + + menu.exec_(self.high_table.mapToGlobal(point)) + + def get_highlights(self): + """ Returns the selected highlights and the comments texts + """ + highlights = "" + comments = "" + for idx in self.sel_high_view: + item_row = idx.row() + data = self.high_table.item(item_row, HIGHLIGHT_H).data(Qt.UserRole) + highlight = data["text"] + if highlight: + highlights += highlight + "\n\n" + comment = data["comment"] + if comment: + comments += comment + "\n\n" + highlights = highlights.rstrip("\n").replace("\n", os.linesep) + comments = comments.rstrip("\n").replace("\n", os.linesep) return highlights, comments def scan_highlights_thread(self): @@ -1173,13 +1797,13 @@ def create_highlight_row(self, data): text = data["text"] item = QTableWidgetItem(text) - item.setToolTip("

{}

".format(text)) + item.setToolTip(f"

{text}

") item.setData(Qt.UserRole, data) self.high_table.setItem(0, HIGHLIGHT_H, item) comment = data["comment"] item = QTableWidgetItem(comment) - item.setToolTip("

{}

".format(comment)) if comment else None + item.setToolTip(f"

{comment}

") if comment else None self.high_table.setItem(0, COMMENT_H, item) date = data["date"] @@ -1207,434 +1831,311 @@ def create_highlight_row(self, data): chapter = data["chapter"] item = XTableWidgetIntItem(chapter) item.setToolTip(chapter) - self.high_table.setItem(0, CHAPTER_H, item) - - path = data["path"] - item = QTableWidgetItem(path) - item.setToolTip(path) - self.high_table.setItem(0, PATH_H, item) - - self.high_table.setSortingEnabled(True) - - # noinspection PyUnusedLocal - def high_view_selection_update(self, selected, deselected): - """ When a row in high_table gets selected - - :type selected: QModelIndex - :parameter selected: The selected row - :type deselected: QModelIndex - :parameter deselected: The deselected row - """ - try: - if not self.filter.isVisible(): - self.sel_high_view = self.high_view_selection.selectedRows() - else: - self.sel_high_view = [i for i in self.high_view_selection.selectedRows() - if not self.high_table.isRowHidden(i.row())] - except IndexError: # empty table - self.sel_high_view = [] - self.toolbar.activate_buttons() - - def on_highlight_column_clicked(self, column): - """ Sets the current sorting column - - :type column: int - :parameter column: The column where the sorting is applied - """ - if column == self.col_sort_h: - self.col_sort_asc_h = not self.col_sort_asc_h - else: - self.col_sort_asc_h = True - self.col_sort_h = column - - # noinspection PyUnusedLocal - def on_highlight_column_resized(self, column, oldSize, newSize): - """ Gets the column size - - :type column: int - :parameter column: The resized column - :type oldSize: int - :parameter oldSize: The old size - :type newSize: int - :parameter newSize: The new size - """ - if column == HIGHLIGHT_H: - self.highlight_width = newSize - elif column == COMMENT_H: - self.comment_width = newSize - - def find_in_books(self, highlight): - """ Finds the current highlight in the "Books View" - - :type highlight: str|unicode - :parameter highlight: The highlight we are searching for - """ - data = self.parent_book_data - - for row in range(self.file_table.rowCount()): - item = self.file_table.item(row, TITLE) - row_data = item.data(Qt.UserRole) - try: # find the book row - if data["stats"]["title"] == row_data["stats"]["title"]: - self.views.setCurrentIndex(BOOKS_VIEW) - self.toolbar.books_view_btn.setChecked(True) - self.toolbar.setup_buttons() - self.toolbar.activate_buttons() - self.file_table.selectRow(row) # select the book - self.on_file_table_itemClicked(item) - for high_row in range(self.high_list.count()): # find the highlight - if (self.high_list.item(high_row) - .data(Qt.UserRole)["text"] == highlight): - self.high_list.setCurrentRow(high_row) # select the highlight - return - except KeyError: # old metadata with no "stats" - continue - - # ___ ___________________ HIGHLIGHTS LIST STUFF _________________ - - def populate_high_list(self, data, path=""): - """ Populates the Highlights list of `Book` view - - :type data: dict - :param data: The item/book's data - :type path: str|unicode - :param path: The item/book's path - """ - space = (" " if self.status.act_page.isChecked() and - self.status.act_date.isChecked() else "") - line_break = (":\n" if self.status.act_page.isChecked() or - self.status.act_date.isChecked() else "") - def_date_format = self.date_format == DATE_FORMAT - highlights = self.get_highlights_from_data(data, path) - for i in sorted(highlights, key=self.sort_high4view): - chapter_text = i["chapter"] - if chapter_text and self.status.act_chapter.isChecked(): - chapter_text = "[{0}]\n".format(chapter_text) - page_text = (_("Page ") + i["page"] - if self.status.act_page.isChecked() else "") - date = i["date"] if def_date_format else self.get_date_text(i["date"]) - date_text = "[" + date + "]" if self.status.act_date.isChecked() else "" - high_text = i["text"] if self.status.act_text.isChecked() else "" - line_break2 = ("\n" if self.status.act_comment.isChecked() and i["comment"] - else "") - high_comment = line_break2 + "● " + i["comment"] if line_break2 else "" - highlight = (page_text + space + date_text + line_break + chapter_text + - high_text + high_comment + "\n") - - highlight_item = QListWidgetItem(highlight, self.high_list) - highlight_item.setData(Qt.UserRole, i) - - def get_highlights_from_data(self, data, path=""): - """ Get the HighLights from the .sdr data - - :type data: dict - :param data: The lua converted book data - :type path: str|unicode - :param path: The book's path - """ - authors = data.get("stats", {}).get("authors", NO_AUTHOR) - title = data.get("stats", {}).get("title", NO_TITLE) - - highlights = [] - for page in data["highlight"]: - for page_id in data["highlight"][page]: - highlight = self.get_highlight_info(data, page, page_id) - if highlight: - # noinspection PyTypeChecker - highlight.update({"authors": authors, "title": title, - "path": path}) - highlights.append(highlight) - return highlights - - @staticmethod - def get_highlight_info(data, page, page_id): - """ Get the highlight's info (text, comment, date and page) - - :type data: dict - :param data: The highlight's data - :type page: int - :param page The page where the highlight starts - :type page_id: int - :param page_id The count of this page's highlight - """ - highlight = {} - try: - high_stuf = data["highlight"][page][page_id] - date = high_stuf["datetime"] - text4check = high_stuf["text"] - chapter = high_stuf.get("chapter", "") - pat = r"Page \d+ (.+?) @ \d+-\d+-\d+ \d+:\d+:\d+" - text = text4check.replace("\\\n", "\n") - comment = "" - for idx in data["bookmarks"]: # check for comment text - if text4check == data["bookmarks"][idx]["notes"]: - bkm_text = data["bookmarks"][idx].get("text", "") - if not bkm_text or (bkm_text == text4check): - break - bkm_text = re.sub(pat, r"\1", bkm_text, 1, re.DOTALL | re.MULTILINE) - if text4check != bkm_text: # there is a comment - comment = bkm_text.replace("\\\n", "\n") - break - highlight["date"] = date - highlight["text"] = text - highlight["comment"] = comment - highlight["chapter"] = chapter - highlight["page"] = str(page) - highlight["page_id"] = page_id - except KeyError: # blank highlight - return - return highlight - - @Slot(QPoint) - def on_high_list_customContextMenuRequested(self, point): - """ When a highlight is right-clicked - - :type point: QPoint - :param point: The point where the right-click happened - """ - if self.sel_high_list: - menu = QMenu(self.high_list) - if QT6: # QT6 requires exec() instead of exec_() - menu.exec_ = getattr(menu, "exec") - - action = QAction(_("Comments"), menu) - action.triggered.connect(self.on_edit_comment) - action.setIcon(self.ico_file_edit) - menu.addAction(action) - - action = QAction(_("Copy"), menu) - action.triggered.connect(self.on_copy_highlights) - action.setIcon(self.ico_copy) - menu.addAction(action) - - action = QAction(_("Delete"), menu) - action.triggered.connect(self.on_delete_highlights) - action.setIcon(self.ico_delete) - menu.addAction(action) - - menu.exec_(self.high_list.mapToGlobal(point)) - - @Slot() - def on_high_list_itemDoubleClicked(self): - """ An item on the Highlight List is double-clicked - """ - self.on_edit_comment() - - def on_edit_comment(self): - """ Opens a window to edit the selected highlight's comment - """ - if self.file_table.isVisible(): # edit comments from Book View - row = self.sel_high_list[-1].row() - comment = self.high_list.item(row).data(Qt.UserRole)["comment"] - elif self.high_table.isVisible(): # edit comments from Highlights View - row = self.sel_high_view[-1].row() - high_data = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) - comment = high_data["comment"] - else: - return - self.edit_high.high_edit_txt.setText(comment) - # self.edit_high.high_edit_txt.setFocus() - self.edit_high.exec_() - - def edit_comment_ok(self): - """ Change the selected highlight's comment - """ - text = self.edit_high.high_edit_txt.toPlainText() - if self.file_table.isVisible(): - high_index = self.sel_high_list[-1] - high_row = high_index.row() - high_data = self.high_list.item(high_row).data(Qt.UserRole) - high_text = high_data["text"].replace("\n", "\\\n") - - row = self.sel_idx.row() - item = self.file_table.item - data = item(row, TITLE).data(Qt.UserRole) - - for bookmark in data["bookmarks"].keys(): - if high_text == data["bookmarks"][bookmark]["notes"]: - data["bookmarks"][bookmark]["text"] = text.replace("\n", "\\\n") - break - item(row, TITLE).setData(Qt.UserRole, data) - - if not self.db_mode: # Loaded mode - path = item(row, PATH).text() - self.save_book_data(path, data) - else: # Archived mode - self.update_book2db(data) - self.on_file_table_itemClicked(item(row, 0), reset=False) - - elif self.high_table.isVisible(): - data = self.parent_book_data - row = self.sel_high_view[-1].row() - high_data = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) - high_text = high_data["text"].replace("\n", "\\\n") + self.high_table.setItem(0, CHAPTER_H, item) - for bookmark in data["bookmarks"].keys(): - if high_text == data["bookmarks"][bookmark]["notes"]: - data["bookmarks"][bookmark]["text"] = text.replace("\n", "\\\n") - high_data["comment"] = text - break - self.high_table.item(row, HIGHLIGHT_H).setData(Qt.UserRole, high_data) - self.high_table.item(row, COMMENT_H).setText(text) + # path = data["path"] + path = data.get("meta_path", "") + item = QTableWidgetItem(path) + item.setToolTip(path) + self.high_table.setItem(0, PATH_H, item) - if not self.db_mode: # Loaded mode - book_path, ext = splitext(high_data["path"]) - path = join(book_path + ".sdr", "metadata{}.lua".format(ext)) - self.save_book_data(path, data) - else: # Archived mode - self.update_book2db(data) - path = self.high_table.item(row, PATH_H).text() - for row in range(self.file_table.rowCount()): - if path == self.file_table.item(row, TYPE).data(Qt.UserRole)[0]: - self.file_table.item(row, TITLE).setData(Qt.UserRole, data) - break + self.high_table.setSortingEnabled(True) - self.reload_highlights = True + # noinspection PyUnusedLocal + def high_view_selection_update(self, selected, deselected): + """ When a row in high_table gets selected - def on_copy_highlights(self): - """ Copy the selected highlights to clipboard + :type selected: QModelIndex + :parameter selected: The selected row + :type deselected: QModelIndex + :parameter deselected: The deselected row """ - clipboard_text = "" - for highlight in sorted(self.sel_high_list): - row = highlight.row() - text = self.high_list.item(row).text() - clipboard_text += text + "\n" - self.copy_text_2clip(clipboard_text) + try: + if not self.filter.isVisible(): + self.sel_high_view = self.high_view_selection.selectedRows() + else: + self.sel_high_view = [i for i in self.high_view_selection.selectedRows() + if not self.high_table.isRowHidden(i.row())] + except IndexError: # empty table + self.sel_high_view = [] + self.toolbar.activate_buttons() - def on_delete_highlights(self): - """ The delete highlights action was invoked + def on_highlight_column_clicked(self, column): + """ Sets the current sorting column + + :type column: int + :parameter column: The column where the sorting is applied """ - if not self.db_mode: - if self.edit_lua_file_warning: - text = _("This is an one-time warning!\n\nIn order to delete highlights " - "from a book, its \"metadata\" file must be edited. This " - "contains a small risk of corrupting that file and lose all the " - "settings and info of that book.\n\nDo you still want to do it?") - popup = self.popup(_("Warning!"), text, buttons=2, - button_text=(_("Yes"), _("No"))) - if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: - return - else: - self.edit_lua_file_warning = False - text = _("This will delete the selected highlights!\nAre you sure?") + if column == self.col_sort_h: + self.col_sort_asc_h = not self.col_sort_asc_h else: - text = _("This will remove the selected highlights from the Archive!\n" - "Are you sure?") - popup = self.popup(_("Warning!"), text, buttons=2, - button_text=(_("Yes"), _("No"))) - if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: - return - self.delete_highlights() + self.col_sort_asc_h = True + self.col_sort_h = column - def delete_highlights(self): - """ Delete the selected highlights + # noinspection PyUnusedLocal + def on_highlight_column_resized(self, column, oldSize, newSize): + """ Gets the column size + + :type column: int + :parameter column: The resized column + :type oldSize: int + :parameter oldSize: The old size + :type newSize: int + :parameter newSize: The new size """ - row = self.sel_idx.row() - data = self.file_table.item(row, TITLE).data(Qt.UserRole) + if column == HIGHLIGHT_H: + self.highlight_width = newSize + elif column == COMMENT_H: + self.comment_width = newSize - for highlight in self.sel_high_list: - high_row = highlight.row() - high_data = self.high_list.item(high_row).data(Qt.UserRole) - pprint(high_data) - page = high_data["page"] - page_id = high_data["page_id"] - del data["highlight"][page][page_id] # delete the highlight - - # delete the associated bookmark - text = high_data["text"] - for bookmark in data["bookmarks"].keys(): - if text == data["bookmarks"][bookmark]["notes"]: - del data["bookmarks"][bookmark] - - for i in data["highlight"].keys(): - if not data["highlight"][i]: # delete page dicts with no highlights - del data["highlight"][i] - else: # renumbering the highlight keys - contents = [data["highlight"][i][j] for j in sorted(data["highlight"][i])] - if contents: - for l in data["highlight"][i].keys(): # delete all the items and - del data["highlight"][i][l] - for k in range(len(contents)): # rewrite them with the new keys - data["highlight"][i][k + 1] = contents[k] + def find_in_books(self, highlight, hi_row): + """ Finds the current highlight in the "Books View" - contents = [data["bookmarks"][bookmark] for bookmark in sorted(data["bookmarks"])] - if contents: # renumbering the bookmarks keys - for bookmark in data["bookmarks"].keys(): # delete all the items and - del data["bookmarks"][bookmark] - for content in range(len(contents)): # rewrite them with the new keys - data["bookmarks"][content + 1] = contents[content] + :type highlight: str|unicode + :parameter highlight: The highlight we are searching for + """ + data, meta_path = self.get_parent_book_data(hi_row) - if not data["highlight"]: # change icon if no highlights - item = self.file_table.item(row, 0) - item.setIcon(self.ico_empty) + for row in range(self.file_table.rowCount()): + item = self.file_table.item(row, TITLE) + row_meta_path = self.file_table.item(row, PATH).data(0) + try: # find the book row + if meta_path == row_meta_path: + self.toolbar.books_view_btn.click() + self.toolbar.setup_buttons() + self.toolbar.activate_buttons() + self.file_table.selectRow(row) # select the book + self.on_file_table_itemClicked(item) + for high_row in range(self.high_list.count()): # find the highlight + if (self.high_list.item(high_row) + .data(Qt.UserRole)["text"] == highlight): + self.high_list.setCurrentRow(high_row) # select the highlight + return + except KeyError: # old metadata with no "stats" + continue - if not self.db_mode: - path = self.file_table.item(row, PATH).text() - self.save_book_data(path, data) - else: - self.update_book2db(data) - item = self.file_table.item - item(row, TITLE).setData(Qt.UserRole, data) - self.on_file_table_itemClicked(item(row, 0), reset=False) - self.reload_highlights = True + # ___ ___________________ SYNC GROUPS TABLE STUFF _______________ - def save_book_data(self, path, data): - """ Saves the data of a book to its lua file + @Slot(QTableWidgetItem) + def on_sync_table_itemClicked(self, item): + """ When an item of the sync_table is clicked - :type path: str|unicode - :param path: The path to the book's data file - :type data: dict - :param data: The book's data + :type item: QTableWidgetItem + :param item: The item (cell) that is clicked """ - times = os.stat(path) # read the file's created/modified times - encode_data(path, data) - os.utime(path, (times.st_ctime, times.st_mtime)) # reapply original times - if self.file_table.isVisible(): - self.on_file_table_itemClicked(self.file_table.item(self.sel_idx.row(), 0), - reset=False) + # row = item.row() + # # path = self.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole)["path"] + # print(row) # noinspection PyUnusedLocal - def high_list_selection_update(self, selected, deselected): - """ When a highlight in gets selected + def sync_view_selection_update(self, selected, deselected): + """ When a row in sync_table gets selected :type selected: QModelIndex - :parameter selected: The selected highlight + :parameter selected: The selected row :type deselected: QModelIndex - :parameter deselected: The deselected highlight - """ - self.sel_high_list = self.high_list_selection.selectedRows() - - def set_highlight_sort(self): - """ Sets the sorting method of displayed highlights + :parameter deselected: The deselected row """ - self.high_by_page = self.sender().data() try: - row = self.sel_idx.row() - self.on_file_table_itemClicked(self.file_table.item(row, 0), False) - except AttributeError: # no book selected - pass + self.sel_sync_view = self.sync_view_selection.selectedRows() + except IndexError: # empty table + self.sel_sync_view = [] + self.toolbar.activate_buttons() - def sort_high4view(self, data): - """ Sets the sorting method of displayed highlights + def create_sync_row(self, data, quiet=False): + """ Creates a sync_table row from the given data - :type data: tuple - param: data: The highlight's data + :type data: dict|list + :param data: The sync_group data + :type quiet: bool + :param quiet: Switch to the Sync view """ - return int(data["page"]) if self.high_by_page else data["date"] + if self.current_view != SYNC_VIEW and not quiet: + self.toolbar.sync_view_btn.setChecked(True) + self.toolbar.change_view() - def sort_high4write(self, data): - """ Sets the sorting method of written highlights + self.sync_table.setSortingEnabled(False) + if isinstance(data, dict): + count = self.sync_table.rowCount() + self.sync_table.insertRow(count) + wdg = self.create_sync_widget(data) + wdg.idx = count + self.sync_groups.append(data) + self.sync_table.setCellWidget(count, 0, wdg) + self.sync_table.setRowHeight(count, wdg.sizeHint().height()) + wdg.check_data() + else: + for idx, data in enumerate(data): + self.sync_table.insertRow(idx) + wdg = self.create_sync_widget(data) + self.sync_table.setCellWidget(idx, 0, wdg) + self.sync_table.setRowHeight(idx, wdg.sizeHint().height()) + wdg.on_power_btn_clicked(data.get("enabled", True)) + wdg.idx = idx + self.sync_groups.append(data) + wdg.check_data() + self.sync_table.setSortingEnabled(True) + # noinspection PyTypeChecker + QTimer.singleShot(0, self.save_sync_groups) + + def create_sync_widget(self, data): + wdg = SyncGroup(self) + wdg.data = data + wdg.power_btn.setChecked(data.get("enabled", True)) + wdg.title_lbl.setText(data.get("title", "")) + wdg.sync_pos_chk.setChecked(data.get("sync_pos", True)) + wdg.merge_chk.setChecked(data.get("merge", True)) + wdg.sync_db_chk.setChecked(data.get("sync_db", False)) + + items = deepcopy(data.get("items", [{"path": "", "data": {}}])) + for item in items: + wdg.add_item(item) + return wdg + + def synchronize_group(self, group, multi=False): + """ Start the process of syncing/merging the group + + :type group: SyncGroup + :param group: The group to be processed + """ + group.on_refresh_btn_clicked() + if not group.sync_items[0].ok: + self.popup(_(f'Error in group "{group.data["title"]}"!'), + _("There is a problem with the first metadata file path!\nCheck " + "the Tooltip that appears while hovering the mouse over it."), + icon=QMessageBox.Critical) + return + sync2db = group.sync_db_chk.isChecked() + group_changed = sync2db + to_process = [] + for idx, item in enumerate(group.sync_items): + if not item.ok: + continue + info = group.data["items"][idx] + mod_time = os.stat(info["path"]).st_mtime + to_process.append((info, mod_time)) + to_process = sorted(to_process, key=lambda x: x[1], reverse=True) + to_process = [i[0] for i in to_process] + + if sync2db: + book_data = {"data": group.data["items"][0]["data"], + "path": group.data["items"][0]["path"]} + db_idx = self.check4archive_merge(book_data) + if db_idx: + db_data = self.books[db_idx]["data"] + to_process.append({"data": db_data, "path": ""}) + + if len(to_process) > 1: + if group.sync_pos_chk.isChecked(): + self.sync_pos(to_process) + group_changed = True + if group.merge_chk.isChecked(): + items = [] + for book_info in to_process: # book_info: {"path": str, "data": dict} + data = book_info["data"] + total = data.get("doc_pages", data.get("stats", {}).get("pages", 0)) + if group.new_format: + items.append((data["annotations"], total)) + else: + items.append((data["highlight"], data["bookmarks"], total, + book_info["path"])) + if group.new_format: + self.merge_new_highs(items) + else: + self.merge_old_highs(items) + group_changed = True + + if group_changed: + for item in deepcopy(to_process): + if item["path"]: # db version has no path + item["data"]["annotations_externally_modified"] = True + self.save_book_data(item["path"], item["data"]) + + if sync2db: # add the newest version of the book to db + new_data = deepcopy(to_process[0]) + path = new_data["path"] + data = new_data["data"] + date = str(datetime.fromtimestamp(getmtime(path))).split(".")[0] + md5 = data["partial_md5_checksum"] + self.delete_books_from_db([md5]) # remove the existing version if any + try: # clean up data that can be cluttered + new_data["stats"]["performance_in_pages"] = {} + new_data["page_positions"] = {} + new_data.pop("annotations_externally_modified", None) + except KeyError: + pass + self.add_books2db([{"md5": md5, "path": path, "date": date, + "data": json.dumps(data)}]) + self.update_new_values(group) + text = _("Synchronization process completed") + else: + text = _("Nothing to sync") - :type data: tuple - param: data: The highlight's data + if not multi: # one group Sync + self.popup(_("Information"), text, QMessageBox.Information) + else: # multiple Sync operations + if group_changed: + return True # needed for counting the number of groups changed + + def update_new_values(self, group): + """ Updates the book table after sync_groups execution """ - if self.high_by_page and self.status.act_page.isChecked(): - page = data[3] - if page.startswith("Page"): - page = page[5:] - return int(page) - else: - return data[0] + self.reload_highlights = True + row_infos = {} + for idx, item in enumerate(group.data["items"]): + if not group.sync_items[idx].ok: + continue + path = item["path"] + for row in range(self.file_table.rowCount()): + if self.file_table.item(row, PATH).text() == path: + row_infos[row] = item + break + for row in row_infos: + data = row_infos[row]["data"] + self.file_table.item(row, TITLE).setData(Qt.UserRole, data) + hi_count = self.get_item_stats(data)["high_count"] + if hi_count and hi_count != "0": + self.file_table.item(row, TITLE).setIcon(self.ico_label_green) + self.file_table.item(row, HIGH_COUNT).setText(hi_count) + self.file_table.item(row, HIGH_COUNT).setToolTip(hi_count) + if group.sync_pos_chk.isChecked(): + percent = str(int(data.get("percent_finished", 0) * 100)) + "%" + self.file_table.item(row, PERCENT).setText(percent) + self.file_table.item(row, PERCENT).setToolTip(percent) + + def update_sync_groups(self): + """ Update the sync groups in memory and on disk + """ + del self.sync_groups[:] + for i in range(self.sync_table.rowCount()): + wdg = self.sync_table.cellWidget(i, 0) + wdg.idx = i # update the index of widget + wdg.check_data() + self.sync_groups.append(wdg.data) + + self.save_sync_groups() + + def load_sync_groups(self): + """ Load the sync groups from a file + """ + try: + with open(SYNC_FILE, "r", encoding="utf-8") as f: + sync_groups = json.load(f) + except (IOError, ValueError): # no json file exists or corrupted file + return + self.create_sync_row(sync_groups, quiet=True) + + def save_sync_groups(self): + """ Save the sync groups to a file + """ + sync_groups = deepcopy(self.sync_groups) + sync_groups = [i for i in sync_groups if i["items"][0].get("path")] + with open(SYNC_FILE, "w+", encoding="utf-8") as f: + items = [i for grp in sync_groups for i in grp["items"] if i.get("path")] + for item in items: + item["data"] = {} + item["path"] = normpath(item["path"]) + json.dump(sync_groups, f, indent=4) # ___ ___________________ MERGING - SYNCING STUFF _______________ @@ -1666,18 +2167,20 @@ def same_book(self, data1, data2, book1="", book2=""): def wrong_book(self): """ Shows an info dialog if the book MD5 of two metadata are different """ - text = _("It seems that the selected metadata file belongs to a different book..") + text = _("It seems that the selected metadata file belongs to a different file..") self.popup(_("Book mismatch!"), text, icon=QMessageBox.Critical) @staticmethod - def same_cre_version(data): + def same_cre_version(data1, data2): """ Check if the supplied metadata have the same CRE version - :type data: list[dict] - :param data: The data to get checked + :type data1: dict + :param data1: The data of the first book + :type data2: dict + :param data2: The data of the second book """ try: - if data[0]["cre_dom_version"] == data[1]["cre_dom_version"]: + if data1["cre_dom_version"] == data2["cre_dom_version"]: return True except KeyError: # no "cre_dom_version" key (older metadata) pass @@ -1698,21 +2201,33 @@ def wrong_cre_version(self): "and does not change that often.") self.popup(_("Version mismatch!"), text, icon=QMessageBox.Critical) - def check4archive_merge(self): + def check4archive_merge(self, book_data): """ Check if the selected books' highlights can be merged with its archived version + + :type book_data: dict + :param book_data: The data of the book """ - idx = self.sel_idx - data1 = self.file_table.item(idx.row(), idx.column()).data(Qt.UserRole) - book_path = self.file_table.item(idx.row(), TYPE).data(Qt.UserRole)[0] + data1 = book_data["data"] + book_path = book_data["path"] for index, book in enumerate(self.books): data2 = book["data"] if self.same_book(data1, data2, book_path): - if self.same_cre_version([data1, data2]): + if self.same_cre_version(data1, data2): return index return False + def wrong_meta_format(self): + """ Shows an info dialog if the format of the two metadata are different + """ + text = _("Can not merge these highlights, because their metadata format are " + "different!\nThere was a re-write of the highlight/bookmark " + "structure of KOReader that make them incompatible.\n\nRe-open the " + "books with a newer version of KOReader to update them and then merge " + "them using KOHighlights.") + self.popup(_("Metadata format mismatch!"), text, icon=QMessageBox.Critical) + def merge_menu(self): """ Creates the `Merge/Sync` button menu """ @@ -1751,18 +2266,8 @@ def on_merge_highlights(self, to_archived=False, filename=""): :type filename: str|unicode :param filename: The path to the metadata file to merge the book with """ - if self.high_merge_warning: - text = _("Merging highlights is experimental so, always do backups ;o)\n" - "Because of the different page formats and sizes, some page " - "numbers in {} might be inaccurate. " - "Do you want to continue?").format(APP_NAME) - popup = self.popup(_("Warning!"), text, buttons=2, - button_text=(_("Yes"), _("No")), - check_text=DO_NOT_SHOW) - self.high_merge_warning = not popup.checked - if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: - return - + if self.merge_warning_stop(): + return popup = self.popup(_("Warning!"), _("The highlights of the selected entries will be merged.\n" "This can not be undone! Continue?"), buttons=2, @@ -1771,6 +2276,21 @@ def on_merge_highlights(self, to_archived=False, filename=""): if popup.buttonRole(popup.clickedButton()) == QMessageBox.AcceptRole: self.merge_highlights(popup.checked, True, to_archived, filename) + def merge_warning_stop(self): + """ Stop if the merge warning is answered "No" + """ + if self.high_merge_warning: + text = _(f"Merging highlights is experimental so, always do backups ;o)\n" + f"Because of the different page formats and sizes, some page " + f"numbers in {APP_NAME} might be inaccurate. " + f"Do you want to continue?") + popup = self.popup(_("Warning!"), text, buttons=2, + button_text=(_("Yes"), _("No")), + check_text=DO_NOT_SHOW) + self.high_merge_warning = not popup.checked + if popup.buttonRole(popup.clickedButton()) == QMessageBox.RejectRole: + return True + def merge_highlights(self, sync, merge, to_archived=False, filename=""): """ Merge highlights from the same book in two different devices @@ -1783,160 +2303,314 @@ def merge_highlights(self, sync, merge, to_archived=False, filename=""): :type filename: str|unicode :param filename: The path to the metadata file to merge the book with """ + item = self.file_table.item if to_archived: # Merge/Sync a book with archive idx1, idx2 = self.sel_idx, None - data1 = self.file_table.item(idx1.row(), TITLE).data(Qt.UserRole) - data2 = self.books[self.check4archive_merge()]["data"] - path1, path2 = self.file_table.item(idx1.row(), PATH).text(), None + data1 = item(idx1.row(), TITLE).data(Qt.UserRole) + path1, path2 = item(idx1.row(), PATH).text(), None + book_data = {"data": data1, "path": path1} + db_idx = self.check4archive_merge(book_data) + if not db_idx: + return + data2 = self.books[db_idx]["data"] elif filename: # Merge/Sync a book with a metadata file idx1, idx2 = self.sel_idx, None - data1 = self.file_table.item(idx1.row(), TITLE).data(Qt.UserRole) - book1 = self.file_table.item(idx1.row(), TYPE).data(Qt.UserRole)[0] + data1 = item(idx1.row(), TITLE).data(Qt.UserRole) + book1 = item(idx1.row(), TYPE).data(Qt.UserRole)[0] data2 = decode_data(filename) name2 = splitext(dirname(filename))[0] book2 = name2 + splitext(book1)[1] if not self.same_book(data1, data2, book1, book2): self.wrong_book() return - if not self.same_cre_version([data1, data2]): + if not self.same_cre_version(data1, data2): self.wrong_cre_version() return - path1, path2 = self.file_table.item(idx1.row(), PATH).text(), None + path1, path2 = item(idx1.row(), PATH).text(), None else: # Merge/Sync two different book files idx1, idx2 = self.sel_indexes - data1, data2 = [self.file_table.item(idx.row(), TITLE).data(Qt.UserRole) + data1, data2 = [item(idx.row(), TITLE).data(Qt.UserRole) for idx in [idx1, idx2]] - path1, path2 = [self.file_table.item(idx.row(), PATH).text() + path1, path2 = [item(idx.row(), PATH).text() for idx in [idx1, idx2]] if merge: # merge highlights - args = (data1["highlight"], data2["highlight"], - data1["bookmarks"], data2["bookmarks"]) - high1, high2, bkm1, bkm2 = self.get_unique_highlights(*args) - self.update_data(data1, high2, bkm2) - self.update_data(data2, high1, bkm1) - if data1["highlight"] or data2["highlight"]: # since there are highlights - for index in [idx1, idx2]: # set the green icon - if index: - item = self.file_table.item(idx1.row(), TITLE) - item.setIcon(self.ico_label_green) + data1_new = data1.get("annotations") is not None + data2_new = data2.get("annotations") is not None + new_type = data1_new and data2_new + datas = [data1, data2] + if path2 and (os.stat(path1).st_mtime < os.stat(path2).st_mtime): + datas = [data2, data1] # put the newer metadata first + items = [] + if new_type: # new format metadata + for data in datas: + total = data.get("doc_pages", data.get("stats", {}).get("pages", 0)) + items.append([data["annotations"], total]) + self.merge_new_highs(items) + if data1["annotations"]: # update row data for books + num = str(len([i for i in data1["annotations"].values() + if i.get("pos0")])) + for index in [idx1, idx2]: + if index: + item(index.row(), TITLE).setIcon(self.ico_label_green) + item(index.row(), HIGH_COUNT).setText(num) + item(index.row(), HIGH_COUNT).setToolTip(num) + elif (data1_new and not data2_new) or (data2_new and not data1_new): + self.wrong_meta_format() + return # different formats metadata - not supported + else: # old format metadata + for data in datas: + total = data.get("doc_pages", data.get("stats", {}).get("pages", 0)) + items.append([data["highlight"], data["bookmarks"], total]) + self.merge_old_highs(items) + if data1["highlight"]: # update row data for books + num = str(len(data1["highlight"])) + for index in [idx1, idx2]: + if index: + item(index.row(), TITLE).setIcon(self.ico_label_green) + item(index.row(), HIGH_COUNT).setText(num) + item(index.row(), HIGH_COUNT).setToolTip(num) if sync: # sync position and percent - if data1["percent_finished"] > data2["percent_finished"]: - data2["percent_finished"] = data1["percent_finished"] - data2["last_xpointer"] = data1["last_xpointer"] - else: - data1["percent_finished"] = data2["percent_finished"] - data1["last_xpointer"] = data2["last_xpointer"] - - percent = str(int(data1["percent_finished"] * 100)) + "%" - self.file_table.item(idx1.row(), PERCENT).setText(percent) - if not to_archived and not filename: - self.file_table.item(idx2.row(), PERCENT).setToolTip(percent) - - self.file_table.item(idx1.row(), TITLE).setData(Qt.UserRole, data1) + to_process = [{"data": data1, "path": path1}, {"data": data2, "path": path2}] + percent = self.sync_pos(to_process) + for index in [idx1, idx2]: + if index: + item(index.row(), PERCENT).setText(percent) + item(index.row(), PERCENT).setToolTip(percent) + + data1["annotations_externally_modified"] = True self.save_book_data(path1, data1) if to_archived: # update the db item self.update_book2db(data2) elif filename: # do nothing with the loaded file pass else: # update the second item - self.file_table.item(idx2.row(), TITLE).setData(Qt.UserRole, data2) + data2["annotations_externally_modified"] = True self.save_book_data(path2, data2) self.reload_highlights = True @staticmethod - def get_unique_highlights(high1, high2, bkm1, bkm2): - """ Get the highlights, bookmarks from the first book - that do not exist in the second book and vice versa - - :type high1: dict - :param high1: The first book's highlights - :type high2: dict - :param high2: The second book's highlights - :type bkm1: dict - :param bkm1: The first book's bookmarks - :type bkm2: dict - :param bkm2: The second book's bookmarks - """ - unique_high1 = defaultdict(dict) - for page1 in high1: - for page_id1 in high1[page1]: - text1 = high1[page1][page_id1]["text"] - for page2 in high2: - for page_id2 in high2[page2]: - if text1 == high2[page2][page_id2]["text"]: - break # highlight found in book2 - else: # highlight was not found yet in book2 - continue # no break in the inner loop, keep looping - break # highlight already exists in book2 (there was a break) - else: # text not in book2 highlights, add to unique - unique_high1[page1][page_id1] = high1[page1][page_id1] - unique_bkm1 = {} - for page1 in unique_high1: - for page_id1 in unique_high1[page1]: - text1 = unique_high1[page1][page_id1]["text"] - for idx in bkm1: - if text1 == bkm1[idx]["notes"]: # add highlight's bookmark to unique - unique_bkm1[idx] = bkm1[idx] - break - - unique_high2 = defaultdict(dict) - for page2 in high2: - for page_id2 in high2[page2]: - text2 = high2[page2][page_id2]["text"] - for page1 in high1: - for page_id1 in high1[page1]: - if text2 == high1[page1][page_id1]["text"]: - break # highlight found in book1 - else: # highlight was not found yet in book1 - continue # no break in the inner loop, keep looping - break # highlight already exists in book1 (there was a break) - else: # text not in book1 highlights, add to unique - unique_high2[page2][page_id2] = high2[page2][page_id2] - unique_bkm2 = {} - for page2 in unique_high2: - for page_id2 in unique_high2[page2]: - text2 = unique_high2[page2][page_id2]["text"] - for idx in bkm2: - if text2 == bkm2[idx]["notes"]: # add highlight's bookmark to unique - unique_bkm2[idx] = bkm2[idx] - break + def merge_new_highs(items): + """ Merge the highlights of multiple books [new format] + + :type items: [[dict, int], ...] + :param items: [[annotations, total_pg], ...] + :param items: The list of books to be processed + """ + uni_check_hi = set() + uni_highs = [] + uni_check_bkm = set() + uni_bkms = [] + for book_id, info in enumerate(items): # find all unique highlights + source = info[0] # that are not in all books + for target_id, target in enumerate(items): + if target_id == book_id: + continue # don't check self + target = target[0] + for src_hi in source.values(): + if src_hi.get("pos0"): # a highlight + hi_text = src_hi.get("text", "") + for trg_hi in target.values(): + if trg_hi.get("pos0"): # a highlight not a bookmark + if hi_text == trg_hi.get("text", ""): + if src_hi["datetime"] == trg_hi["datetime"]: + break # it's the exact same annotation + src_comm = src_hi.get("note") # try to get the + trg_comm = trg_hi.get("note") # newest change + if src_hi["datetime"] > trg_hi["datetime"]: + if src_comm: # this is the newer comment + trg_hi["note"] = src_comm + elif trg_comm: # the comment was erased lately + trg_hi.pop("note", None) + trg_hi["datetime"] = src_hi["datetime"] + else: + if trg_comm: # this is the newer comment + src_hi["note"] = trg_comm + elif src_comm: # the comment was erased lately + src_hi.pop("note", None) + src_hi["datetime"] = trg_hi["datetime"] + break # highlight found in target book + else: # highlight was not found in target book + if src_hi["pos0"] + src_hi["pos1"] not in uni_check_hi: + uni_check_hi.add(src_hi["pos0"] + src_hi["pos1"]) + uni_highs.append((src_hi, info[1])) + else: # a bookmark + if src_hi["page"] not in uni_check_bkm: + uni_check_bkm.add(src_hi["page"]) + uni_bkms.append((src_hi, info[1])) + + for info in items: # update the annotations with the unique found ones + annots = deepcopy([i for i in info[0].values()]) + total = info[1] + hi_pos_check = {i["pos0"] + i["pos1"] for i in annots if i.get("pos0")} + bkm_pos_check = {i["page"] for i in annots if i.get("page")} + for hi_info in uni_highs: + hi, hi_total = hi_info + if not hi["pos0"] + hi["pos1"] in hi_pos_check: # new highlight + new_hi = deepcopy(hi) + if hi_total != total: # re-calculate the page numbers + percent = int(new_hi["pageno"]) / hi_total + new_hi["pageno"] = str(int(round(percent * total))) + annots.append(new_hi) + for bkm_info in uni_bkms: + bkm, bkm_total = bkm_info + if not bkm["page"] in bkm_pos_check: # new bookmark + new_bkm = deepcopy(bkm) + if bkm_total != total: # re-calculate the page numbers + percent = int(new_bkm["pageno"]) / bkm_total + new_bkm["pageno"] = str(int(round(percent * total))) + annots.append(new_bkm) + info[0].clear() # repopulate the annotations + annots_upd = {} + for i, hi in enumerate(sorted(annots, key=lambda x: x["pageno"])): + annots_upd[i + 1] = hi + info[0].update(annots_upd) - return unique_high1, unique_high2, unique_bkm1, unique_bkm2 + @staticmethod + def merge_old_highs(items): + """ Merge the highlights of multiple books + + :type items: [[dict, dict, int], ...] + :param items: [[highlights, bookmarks, total_pg], ...] + :param items: The list of books to be processed + """ + uni_check = set() + all_uni_highs = {} + all_uni_bkms = {} + # Collect the highlights that are missing even from one book + for book_id, s_info in enumerate(items): + source = s_info[0] + uni_highs = defaultdict(dict) + uni_bkms = defaultdict(dict) + for target_id, t_info in enumerate(items): + if target_id == book_id: + continue # don't check self + target = t_info[0] + for src_pg in source: + for src_pg_id in source[src_pg]: + high = source[src_pg][src_pg_id] + src_text = high["text"] + for target_pg in target: + for target_pg_id in target[target_pg]: + targ = target[target_pg][target_pg_id] + if src_text == targ["text"]: # same annotation + if high["datetime"] == targ["datetime"]: + break + src_comm = "" # if one comment is newer then the + trg_comm = "" # other, we keep the newer for both + src_bkm = {} + trg_bkm = {} + for bk_idx in s_info[1]: + src_bkm = s_info[1][bk_idx] + if src_bkm["notes"] == src_text: + src_comm = src_bkm.get("text", "") + break + for bk_idx in t_info[1]: + trg_bkm = t_info[1][bk_idx] + if trg_bkm["notes"] == targ["text"]: + trg_comm = trg_bkm.get("text", "") + break + if src_bkm["datetime"] > trg_bkm["datetime"]: + if src_comm: # this is the newer comment + trg_bkm["text"] = src_comm + elif trg_comm: # the comment was erased lately + trg_bkm.pop("text", None) + trg_bkm["datetime"] = src_bkm["datetime"] + targ["datetime"] = high["datetime"] + else: + if trg_comm: # this is the newer comment + src_bkm["text"] = trg_comm + elif src_comm: # the comment was erased lately + src_bkm.pop("text", None) + src_bkm["datetime"] = trg_bkm["datetime"] + high["datetime"] = targ["datetime"] + break # highlight found in target book + else: # highlight was not found yet in target book + continue # no break in the inner loop, keep checking + break # highlight exists in target (there was a break) + else: # text not in the target book highlights, add to unique + # but not if already added + if high["pos0"] + high["pos1"] not in uni_check: + uni_check.add(high["pos0"] + high["pos1"]) + uni_highs[src_pg][src_pg_id] = high + for pg in uni_highs: + for pg_id in uni_highs[pg]: + text = uni_highs[pg][pg_id]["text"] + for bkm_idx in s_info[1]: # get the associated bookmarks + if text == s_info[1][bkm_idx]["notes"]: + uni_bkms[pg][pg_id] = s_info[1][bkm_idx] + break + if uni_highs: + all_uni_highs[book_id] = dict(uni_highs) + all_uni_bkms[book_id] = dict(uni_bkms) + + # Merge the highlights that are not on all books + for book_id in all_uni_highs: + uni_highs = all_uni_highs[book_id] + uni_bkms = all_uni_bkms[book_id] + source_total = items[book_id][2] + for item_id, target_item in enumerate(items): + target_total = target_item[2] + recalculate = source_total != target_total + all_highs = [target_item[0][pg][pg_id] + for pg in target_item[0] for pg_id in target_item[0][pg]] + all_bkms = [i for i in target_item[1].values()] + renumber = False # no change made to the highlights/bookmarks + for pg in uni_highs: + new_pg = pg + for pg_id in uni_highs[pg]: + if uni_highs[pg][pg_id] not in all_highs: # add this highlight + renumber = True # mark for renumbering the bookmarks + if recalculate: # diff total pages, recalculate page number + percent = int(pg) / target_total + new_pg = int(round(percent * source_total)) + + if new_pg in target_item[0]: # sort same page highlights + contents = target_item[0][new_pg] + contents = [contents[i] for i in contents] + extras = uni_highs[pg] + extras = [extras[i] for i in extras + if extras[i] not in contents] + highs = sorted(contents + extras, key=lambda x: x["pos0"]) + target_item[0][new_pg] = {i + 1: h + for i, h in enumerate(highs)} + else: # single highlight in page, just add it + target_item[0][new_pg] = uni_highs[pg] + all_bkms.append(uni_bkms[pg][pg_id]) + if renumber: # bookmarks added, so we must merge all and renumber them + bkm_list = target_item[1].copy() + bkm_list = [bkm_list[i] for i in bkm_list] + bkm_check = {i["pos0"] + i["pos1"] for i in bkm_list} + for bkm in all_bkms: + if bkm["pos0"] + bkm["pos1"] not in bkm_check: + bkm_list.append(bkm) + bkm_list = sorted(bkm_list, key=lambda x: x["page"]) + target_item[1].clear() + offset = 1 + for bkm in bkm_list: + target_item[1][offset] = bkm + offset += 1 @staticmethod - def update_data(data, extra_highlights, extra_bookmarks): - """ Adds the new highlights to the book's data + def sync_pos(to_process): + """ Sync the reading position of multiple books - :type data: dict - :param data: The book's data - :type extra_highlights: dict - :param extra_highlights: The other book's highlights - :type extra_bookmarks: dict - :param extra_bookmarks: The other book's bookmarks - """ - highlights = data["highlight"] - for page in extra_highlights: - if page in highlights: # change page number if already exists - new_page = page - while new_page in highlights: - new_page += 1 - highlights[new_page] = extra_highlights[page] - else: - highlights[page] = extra_highlights[page] - - bookmarks = data["bookmarks"] - original = bookmarks.copy() - bookmarks.clear() - counter = 1 - for key in original.keys(): - bookmarks[counter] = original[key] - counter += 1 - for key in extra_bookmarks.keys(): - bookmarks[counter] = extra_bookmarks[key] - counter += 1 + :type to_process: list + :param to_process: The list of books to be processed + """ + percents = [i["data"]["percent_finished"] for i in to_process + if i and i.get("data", {}).get("percent_finished", 0) > 0] + max_idx = percents.index(max(percents)) + max_percent = percents[max_idx] + max_pointer = to_process[max_idx]["data"]["last_xpointer"] + + for item in to_process: + item["data"]["percent_finished"] = max_percent + item["data"]["last_xpointer"] = max_pointer + + return str(int(max_percent * 100)) + "%" def use_meta_files(self): """ Selects a metadata files to sync/merge @@ -2067,26 +2741,37 @@ def get_sdr_folder(self, row): # ___ ___________________ SAVING STUFF __________________________ - def get_export_menu(self): + def create_export_menu(self): """ Creates the `Export Files` button menu """ - menu = QMenu(self) - for idx, item in enumerate([(_("To individual text files"), MANY_TEXT), - (_("Combined to one text file"), ONE_TEXT), - (_("To individual html files"), MANY_HTML), - (_("Combined to one html file"), ONE_HTML), - (_("To individual csv files"), MANY_CSV), - (_("Combined to one csv file"), ONE_CSV), - (_("To individual markdown files"), MANY_MD), - (_("Combined to one markdown file"), ONE_MD)]): - action = QAction(item[0], menu) - action.triggered.connect(self.export_actions) - action.setData(item[1]) - action.setIcon(self.ico_file_save) - if idx and (idx % 2 == 0): - menu.addSeparator() - menu.addAction(action) - return menu + self.export_menu.clear() + single = len(self.sel_indexes) == 1 + if single: + for idx, item in enumerate([(_("To text file"), MANY_TEXT), + (_("To html file"), MANY_HTML), + (_("To csv file"), MANY_CSV), + (_("To md file"), MANY_MD)]): + action = QAction(item[0], self.export_menu) + action.triggered.connect(self.export_actions) + action.setData(item[1]) + action.setIcon(self.ico_file_save) + self.export_menu.addAction(action) + else: + for idx, item in enumerate([(_("To individual text files"), MANY_TEXT), + (_("Combined to one text file"), ONE_TEXT), + (_("To individual html files"), MANY_HTML), + (_("Combined to one html file"), ONE_HTML), + (_("To individual csv files"), MANY_CSV), + (_("Combined to one csv file"), ONE_CSV), + (_("To individual md files"), MANY_MD), + (_("Combined to one md file"), ONE_MD)]): + action = QAction(item[0], self.export_menu) + action.triggered.connect(self.export_actions) + action.setData(item[1]) + action.setIcon(self.ico_file_save) + if idx and (idx % 2 == 0): + self.export_menu.addSeparator() + self.export_menu.addAction(action) # noinspection PyCallByClass def on_export(self): @@ -2095,13 +2780,12 @@ def on_export(self): if self.current_view == BOOKS_VIEW: if not self.sel_indexes: return + self.toolbar.export_btn.showMenu() elif self.current_view == HIGHLIGHTS_VIEW: # Save from high_table, if self.save_sel_highlights(): # combine to one file self.popup(_("Finished!"), _("The Highlights were exported successfully!"), icon=QMessageBox.Information) - return - self.toolbar.export_btn.showMenu() def export_actions(self): """ An `Export as...` menu item is clicked @@ -2146,9 +2830,8 @@ def export(self, idx): ext = "md" else: return - filename = QFileDialog.getSaveFileName(self, - _("Export to {} file").format(ext), - self.last_dir, "*.{}".format(ext))[0] + filename = QFileDialog.getSaveFileName(self, _(f"Export to {ext} file"), + self.last_dir, f"*.{ext}")[0] if not filename: return self.last_dir = dirname(filename) @@ -2156,9 +2839,9 @@ def export(self, idx): self.status.animation(False) all_files = len(self.sel_indexes) - self.popup(_("Finished!"), _("{} texts were exported from the {} processed.\n" - "{} files with no highlights.") - .format(saved, all_files, all_files - saved), + self.popup(_("Finished!"), + _(f"{saved} texts were exported from the {all_files} processed.\n" + f"{all_files - saved} files with no highlights."), icon=QMessageBox.Information) def save_multi_files(self, dir_path, format_, line_break, space): @@ -2185,8 +2868,7 @@ def save_multi_files(self, dir_path, format_, line_break, space): format_, line_break, space, sort_by) saved += 1 except IOError as err: # any problem when writing (like long filename, etc.) - self.popup(_("Warning!"), - _("Could not save the file to disk!\n{}").format(err)) + self.popup(_("Warning!"), _(f"Could not save the file to disk!\n{err}")) return saved def save_merged_file(self, filename, format_, line_break, space): @@ -2222,21 +2904,31 @@ def save_merged_file(self, filename, format_, line_break, space): text_file.write(text) return saved - def get_item_data(self, idx, format_): + def get_item_data(self, index, format_): """ Get the highlight data for an item - :type idx: QModelIndex - :param idx: The item's index + :type index: QModelIndex + :param index: The item's index :type format_: int :param format_: The output format idx """ - row = idx.row() + row = index.row() data = self.file_table.item(row, 0).data(Qt.UserRole) highlights = [] - for page in data["highlight"]: - for page_id in data["highlight"][page]: - highlights.append(self.get_formatted_high(data, page, page_id, format_)) + annotations = data.get("annotations") + if annotations: # new format metadata + for idx in annotations: + highlight = self.get_new_highlight_info(data, idx) + if highlight: + formatted_high = self.get_formatted_high(highlight, format_) + highlights.append(formatted_high) + else: # old format metadata + for page in data["highlight"]: + for page_id in data["highlight"][page]: + highlight = self.get_old_highlight_info(data, page, page_id) + if highlight: + highlights.append(self.get_formatted_high(highlight, format_)) title = self.file_table.item(row, TITLE).data(0) authors = self.file_table.item(row, AUTHOR).data(0) if authors in [OLD_TYPE, NO_AUTHOR]: @@ -2244,19 +2936,14 @@ def get_item_data(self, idx, format_): return authors, title, highlights # noinspection PyTypeChecker - def get_formatted_high(self, data, page, page_id, format_): + def get_formatted_high(self, highlight, format_): """ Create the highlight's texts - :type data: dict - :param data: The highlight's data - :type page: int - :param page The page where the highlight starts - :type page_id: int - :param page_id The idx of this page's highlight + :type highlight: dict + :param highlight: The highlight's data :type format_: int :param format_ The output format idx """ - highlight = self.get_highlight_info(data, page, page_id) linesep = "
" if format_ in [ONE_HTML, MANY_HTML] else os.linesep comment = highlight["comment"].replace("\n", linesep) chapter = (highlight["chapter"].replace("\n", linesep) @@ -2267,12 +2954,13 @@ def get_formatted_high(self, data, page, page_id, format_): date = date if self.date_format == DATE_FORMAT else self.get_date_text(date) line_break2 = (os.linesep if self.status.act_text.isChecked() and comment else "") if format_ in [ONE_CSV, MANY_CSV]: - page_text = str(page) if self.status.act_page.isChecked() else "" + page_text = highlight["page"] if self.status.act_page.isChecked() else "" date_text = date if self.status.act_date.isChecked() else "" high_comment = (comment if self.status.act_comment.isChecked() and comment else "") else: - page_text = "Page " + str(page) if self.status.act_page.isChecked() else "" + page_txt = "Page " + highlight["page"] + page_text = page_txt if self.status.act_page.isChecked() else "" date_text = "[" + date + "]" if self.status.act_date.isChecked() else "" high_comment = (line_break2 + "● " + comment if self.status.act_comment.isChecked() and comment else "") @@ -2293,7 +2981,7 @@ def save_sel_highlights(self): text_out = extra.startswith("text") html_out = extra.startswith("html") csv_out = extra.startswith("csv") - md_out = extra.startswith("mark") + md_out = extra.startswith("md") if text_out: ext = ".txt" text = "" @@ -2327,13 +3015,12 @@ def save_sel_highlights(self): comment = comment.replace("\n", " \n") if text_out: - txt = ("{} [{}]\nPage {} [{}]\n[{}]\n{}{}" - .format(data["title"], data["authors"], data["page"], - data["date"], data["chapter"], data["text"], comment)) + txt = (f"{data['title']} [{data['authors']}]\nPage {data['page']} " + f"[{data['date']}]\n[{data['chapter']}]\n{data['text']}{comment}") text += txt + "\n\n" elif html_out: - left = "{} [{}]".format(data["title"], data["authors"]) - right = "Page {} [{}]".format(data["page"], data["date"]) + left = f"{data['title']} [{data['authors']}]" + right = f"Page {data['page']} [{data['date']}]" text += HIGH_BLOCK % {"page": left, "date": right, "comment": comment, "highlight": data["text"], "chapter": data["chapter"]} @@ -2344,10 +3031,10 @@ def save_sel_highlights(self): txt = data["text"].replace("\n", " \n") chapter = data["chapter"] if chapter: - chapter = "***{0}***\n\n".format(chapter).replace("\n", " \n") - text += ("\n---\n### {} [{}] \n*Page {} [{}]* \n{}{}{}\n" - .format(data["title"], data["authors"], data["page"], - data["date"], chapter, txt, comment)) + chapter = f"***{chapter}***\n\n".replace("\n", " \n") + text += (f'\n---\n### {data["title"]} [{data["authors"]}] \n' + f'*Page {data["page"]} [{data["date"]}]* \n' + f'{chapter}{txt}{comment}\n') else: print("Unknown format export!") return @@ -2389,27 +3076,27 @@ def settings_load(self): self.skip_version = app_config.get("skip_version", None) self.date_vacuumed = app_config.get("date_vacuumed", self.date_vacuumed) self.date_format = app_config.get("date_format", DATE_FORMAT) + self.theme = app_config.get("theme", THEME_NONE_OLD) + self.status.theme_box.setCurrentIndex(self.theme) self.archive_warning = app_config.get("archive_warning", True) self.exit_msg = app_config.get("exit_msg", True) self.high_merge_warning = app_config.get("high_merge_warning", True) self.edit_lua_file_warning = app_config.get("edit_lua_file_warning", True) - checked = app_config.get("show_items", (True, True, True, True, True)) - if len(checked) != 5: # settings from older versions - checked = (True, True, True, True, True) - self.status.act_page.setChecked(checked[0]) - self.status.act_date.setChecked(checked[1]) - self.status.act_chapter.setChecked(checked[2]) - self.status.act_text.setChecked(checked[3]) - self.status.act_comment.setChecked(checked[4]) + self.show_items = app_config.get("show_items", [True, True, True, True, True]) + if len(self.show_items) != 5: # settings from older versions + self.show_items = [True, True, True, True, True] self.high_by_page = app_config.get("high_by_page", False) else: + self.status.theme_box.setCurrentIndex(self.theme) self.resize(800, 600) if self.highlight_width: self.header_high_view.resizeSection(HIGHLIGHT_H, self.highlight_width) if self.comment_width: self.header_high_view.resizeSection(COMMENT_H, self.comment_width) self.toolbar.set_btn_size(self.toolbar_size) + for idx, act in enumerate(self.status.show_actions): + act.setChecked(self.show_items[idx]) def settings_save(self): """ Saves the jason based configuration settings @@ -2427,22 +3114,16 @@ def settings_save(self): "current_view": self.current_view, "db_mode": self.db_mode, "high_by_page": self.high_by_page, "date_vacuumed": self.date_vacuumed, "show_info": self.fold_btn.isChecked(), "date_format": self.date_format, - "show_items": (self.status.act_page.isChecked(), - self.status.act_date.isChecked(), - self.status.act_chapter.isChecked(), - self.status.act_text.isChecked(), - self.status.act_comment.isChecked()), + "theme": self.theme, "show_items": self.show_items, "skip_version": self.skip_version, "opened_times": self.opened_times, "edit_lua_file_warning": self.edit_lua_file_warning, "high_merge_warning": self.high_merge_warning, } try: - if not PYTHON2: - # noinspection PyUnresolvedReferences - for k, v in config.items(): - if type(v) == bytes: - # noinspection PyArgumentList - config[k] = str(v, encoding="latin") + for k, v in config.items(): + if type(v) == bytes: + # noinspection PyArgumentList + config[k] = str(v, encoding="latin") config_json = json.dumps(config, sort_keys=True, indent=4) with gzip.GzipFile(join(SETTINGS_DIR, str("settings.json.gz")), "w+") as gz_file: @@ -2473,17 +3154,9 @@ def unpickle(key): value = app_config.get(key) if not value: return - if PYTHON2: - try: - # noinspection PyTypeChecker - value = pickle.loads(str(value)) - except UnicodeEncodeError: # settings from Python 3.x - return - else: - # noinspection PyUnresolvedReferences - value = value.encode("latin1") - # noinspection PyTypeChecker,PyArgumentList - value = pickle.loads(value, encoding="bytes") + value = value.encode("latin1") + # noinspection PyTypeChecker,PyArgumentList + value = pickle.loads(value, encoding="bytes") except pickle.UnpicklingError as err: print("While unPickling:", err) return @@ -2522,7 +3195,7 @@ def popup(self, title, text, icon=QMessageBox.Warning, buttons=1, popup.setWindowIcon(self.ico_app) if type(icon) == QMessageBox.Icon: popup.setIcon(icon) - elif type(icon) == unicode: + elif type(icon) == str: popup.setIconPixmap(QPixmap(icon)) elif type(icon) == QPixmap: popup.setIconPixmap(icon) @@ -2550,6 +3223,9 @@ def popup(self, title, text, icon=QMessageBox.Warning, buttons=1, popup.exec_() return popup + def error(self, error_txt): + self.popup(_("Error!"), error_txt, icon=QMessageBox.Critical) + def passed_files(self): """ Command line parameters that are passed to the program. """ @@ -2573,8 +3249,7 @@ def open_file(self, path): opener = "open" if sys.platform == "darwin" else "xdg-open" subprocess.call([opener, path]) except OSError: - self.popup(_("Error opening target!"), - _('"{}" does not exists!').format(path)) + self.popup(_("Error opening target!"), _(f'"{path}" does not exists!')) def copy_text_2clip(self, text): """ Copy a text to clipboard @@ -2609,9 +3284,8 @@ def recalculate_md5(self, file_path): data["stats"]["md5"] = md5 if old_md5: - text = _("The MD5 was originally\n{}\nA recalculation produces\n{}\n" - "The MD5 was replaced and saved!").format(old_md5, md5) - self.file_table.item(row, TITLE).setData(Qt.UserRole, data) + text = _(f"The MD5 was originally\n{old_md5}\nA recalculation produces\n" + f"{md5}\nThe MD5 was replaced and saved!") self.save_book_data(path, data) else: text = _("Metadata file has no MD5 information!") @@ -2659,10 +3333,10 @@ def auto_check4update(self): self.opened_times += 1 if self.opened_times == 20: - text = _("Since you are using {} for some time now, perhaps you find it " - "useful enough to consider a donation.\nWould you like to visit " - "the PayPal donation page?\n\nThis is a one-time message. " - "It will never appear again!").format(APP_NAME) + text = _(f"Since you are using {APP_NAME} for some time now, perhaps you find" + f" it useful enough to consider a donation.\nWould you like to visit" + f" the PayPal donation page?\n\nThis is a one-time message. It will " + f"never appear again!") popup = self.popup(_("A reminder..."), text, icon=":/stuff/paypal76.png", buttons=3) @@ -2684,9 +3358,8 @@ def auto_check4update(self): skip_version = version_parse(self.skip_version) if version_new > current_version and version_new != skip_version: popup = self.popup(_("Newer version exists!"), - _("There is a newer version (v.{}) online.\n" - "Open the site to download it now?") - .format(version_new), + _(f"There is a newer version (v.{version_new}) online.\n" + f"Open the site to download it now?"), icon=QMessageBox.Information, buttons=2, check_text=_("Don\"t alert me for this version again")) if popup.checked: @@ -2760,10 +3433,10 @@ def __init__(self, *args, **kwargs): del argv[1] sys.argv = argv self.parser = argparse.ArgumentParser(prog=APP_NAME, - description=_("{} v{} - A KOReader's " - "highlights converter") - .format(APP_NAME, __version__), - epilog=_("Thanks for using %s!") % APP_NAME) + description=_(f"{APP_NAME} v{__version__} -" + f" A KOReader's highlights " + f"converter"), + epilog=_(f"Thanks for using {APP_NAME}!")) self.base = Base() if compiled: # the app is compiled if not on_windows: # no cli in windows @@ -2859,7 +3532,7 @@ def parse_args(self): """ Parse the command line parameters that are passed to the program. """ self.parser.add_argument("-v", "--version", action="version", - version="%(prog)s v{}".format(__version__)) + version=f"%(prog)s v{__version__}") self.parser.add_argument("paths", nargs="*", help="The paths to input files or folder") @@ -2902,9 +3575,15 @@ def parse_args(self): help="The filename of the file (in merge mode) or " "the directory for saving the highlight files") + self.parser.add_argument("-p", "--portable", action="store_true", default=False, + help="Just run the program in portable mode " + "(Windows only)") + # args, paths = self.parser.parse_known_args() args = self.parser.parse_args() - if args.use_cli: + if args.portable: + print("Running in portable mode...") + elif args.use_cli: self.cli_save_highlights(args) sys.exit(0) # quit the app if cli execution @@ -2933,15 +3612,14 @@ def cli_save_highlights(self, args): if isdir(path): ext = ("an .html" if args.html else "a .csv" if args.csv else "an .md" if args.markdown else "a .txt") - self.parser.error("The output path (-o/--output) must be {} filename " - "not a directory!".format(ext)) + self.parser.error(f"The output path (-o/--output) must be {ext} filename " + f"not a directory!") return saved = self.cli_save_merged_file(args, files, line_break, space) all_files = len(files) - sys.stdout.write(_("\n{} files were exported from the {} processed.\n" - "{} files with no highlights.\n").format(saved, all_files, - all_files - saved)) + sys.stdout.write(_(f"\n{saved} files were exported from the {all_files} processed" + f".\n{all_files - saved} files with no highlights.\n")) def cli_save_multi_files(self, args, files, line_break, space): """ Save each selected book's highlights to a different file @@ -2964,7 +3642,7 @@ def cli_save_multi_files(self, args, files, line_break, space): format_ = MANY_MD else: format_ = MANY_TEXT - sort_by = self.cli_sort + sort_by = partial(self.cli_sort, args) path = abspath(args.output) for file_ in files: authors, title, highlights = self.cli_get_item_data(file_, args) @@ -2973,8 +3651,9 @@ def cli_save_multi_files(self, args, files, line_break, space): try: save_file(title, authors, highlights, path, format_, line_break, space, sort_by) + saved += 1 except IOError as err: # any problem when writing (like long filename, etc.) - sys.stdout.write(str("Could not save the file to disk!\n{}").format(err)) + sys.stdout.write(str(f"Could not save the file to disk!\n{err}")) return saved def cli_save_merged_file(self, args, files, line_break, space): @@ -3024,7 +3703,7 @@ def cli_save_merged_file(self, args, files, line_break, space): path = name + new_ext with open(path, "w+", encoding=encoding, newline="") as text_file: text_file.write(text) - sys.stdout.write(str("Created {}\n\n").format(path)) + sys.stdout.write(f"Created {path}\n\n") return saved def cli_get_item_data(self, file_, args): @@ -3037,13 +3716,25 @@ def cli_get_item_data(self, file_, args): """ data = decode_data(file_) highlights = [] - for page in data["highlight"]: - for page_id in data["highlight"][page]: - highlights.append(self.cli_get_formatted_high(data, page, page_id, args)) + + annotations = data.get("annotations") + if annotations: # new format metadata + for idx in annotations: + highlight = self.base.get_new_highlight_info(data, idx) + if highlight: + formatted_high = self.cli_get_formatted_high(highlight, args) + highlights.append(formatted_high) + else: # old format metadata + for page in data["highlight"]: + for page_id in data["highlight"][page]: + highlight = self.base.get_old_highlight_info(data, page, page_id) + if highlight: + highlights.append(self.cli_get_formatted_high(highlight, args)) authors = "" + stats = "doc_props" if "doc_props" in data else "stats" if "stats" in data else "" try: - title = data["stats"]["title"] - authors = data["stats"]["authors"] + title = data[stats]["title"] + authors = data[stats]["authors"] except KeyError: # older type file title = splitext(basename(file_))[0] try: @@ -3059,20 +3750,15 @@ def cli_get_item_data(self, file_, args): title = NO_TITLE return authors, title, highlights - # noinspection PyTypeChecker - def cli_get_formatted_high(self, data, page, page_id, args): - """ Get the highlight's info (text, comment, date and page) + @staticmethod + def cli_get_formatted_high(highlight, args): + """ Return the highlight's info in a formatted way - :type data: dict - :param data: The highlight's data - :type page: int - :param page The page where the highlight starts - :type page_id: int - :param page_id The count of this page's highlight + :type highlight: dict + :param highlight: The highlight's data :type args: argparse.Namespace :param args: The parsed cli args """ - highlight = self.base.get_highlight_info(data, page, page_id) nl = "
" if args.html else os.linesep chapter = highlight["chapter"].replace("\n", nl) if not args.no_chapter else "" high_text = highlight["text"] @@ -3081,11 +3767,11 @@ def cli_get_formatted_high(self, data, page, page_id, args): date = highlight["date"] line_break2 = os.linesep if not args.no_highlight and comment else "" if args.csv: - page_text = str(page) if not args.no_page else "" + page_text = highlight["page"] if not args.no_page else "" date_text = date if not args.no_date else "" high_comment = comment if not args.no_comment and comment else "" else: - page_text = "Page " + str(page) if not args.no_page else "" + page_text = "Page " + highlight["page"] if not args.no_page else "" date_text = "[" + date + "]" if not args.no_date else "" high_comment = (line_break2 + "● " + comment if not args.no_comment and comment else "") @@ -3163,10 +3849,11 @@ def get_name(data, meta_path, title_counter): :type title_counter: list :param title_counter: A list with the current NO TITLE counter """ + stats = "doc_props" if "doc_props" in data else "stats" if "stats" in data else "" authors = "" try: - title = data["stats"]["title"] - authors = data["stats"]["authors"] + title = data[stats]["title"] + authors = data[stats]["authors"] except KeyError: # older type file title = splitext(basename(meta_path))[0] try: @@ -3183,7 +3870,7 @@ def get_name(data, meta_path, title_counter): title_counter[0] += 1 name = title if authors: - name = "{} - {}".format(authors, title) + name = f"{authors} - {title}" return name diff --git a/requirements.txt b/requirements.txt index 39b5618..439f897 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ beautifulsoup4 future -PySide==1.2.4 +PySide2 requests -pypiwin32 -pywin32 \ No newline at end of file +packaging +pypiwin32; sys_platform == 'win32' +pywin32; sys_platform == 'win32' \ No newline at end of file diff --git a/screens/screen d1.png b/screens/screen d1.png index 0a5fde9a061d11420e43831e54335552c5988ae4..b51e79386cd372dbe490fd039f67a6a5c8e445ff 100644 GIT binary patch literal 71020 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 literal 106937 zcmZsDWmr}1*7c^8kWflOK%`r`LqS@)Q&PG+MUZZg4oT@$N^1s z=l%1oiyyGB&0cHW_nc#nG3H!5T=}UqHYO=10)fDmm623MAW+H>2;?GkWO#+fDyI>F zphCz>N~n8IZDo0h6KK7^QsVPzc*KnU7KwD!9U0x>*ISI-ptmm?qk9z)H}l2yJ@F^f zgdLIcKZht}lO|%YAsvL?Ca3qx??#eBGgnctxI^d`^d$H8tXle18d`5p?!zzJ?`p?hH zAk4e}{!a2pnIPnUe=sQ%psk@i`S)F~2>$O^^0$Gv|M}OrHz7^wb}U4F}TI8UMWtxYkzH zC=gSa=H+Jtw1MAaW0C|&LK?#_9I>ili-m^(RO&nYM@KCW|eIn2nCjumxT z>ED{H)6>&4@;e+0xZKZ4q*ubh#Pt62t806@p-^>wZ@I7a!v~9_TM^1M=h{azSZ_=d z?Ny#hQ|{jL;BZwKW+jq3p&_y$7GFCk(6c@=pOs4&<;4gr>{_>~VV4TI=X2h{{su|5 zp-7O9{3BFWV+RYI=rA;dE?F zOdHEokum1qTJhv)DtGgmD4He}-udhwgoG}lwry0HNvi#&A#i=AM00?S>&a7-YpEUL zex|Daqo&7aHLz!6t7lC56N7io#zy`#%-f{TFr06itM8U8SyPDUDjOJFqz-W+TyMT4 z$KHIe-4%Xdd;a`xh|}$V6UG1Xa)2-3@^^sfMIU{0LVK_w0Y_w)Zmk&x!qdkmBO`-S z&^3%eP)G>n<7-wuL%&0fci5igh9dOGk@p(34HhqP1DcAJEoaIMlIti(?svvg?q-eD zQNZ%|8D8{tKQ!%$xp>f@^-1{a&EGu_O}lOT54BrWN(4t8=N-T3@>-a(2@Bs9wAk89 z#A|apWG9o|>f1|neuHHo^ok;QEI{%1o7B*|_}-2)bDeDQ+YfhA#9|=cZ`GLxCieBX z6AhjORx(alD4neuqTl0k-}>>8Y~iKkJ9g}U?~c24%*1x{23aeEF&7t?w6wImygWth z@tn`@#bH%|ot@p`(b4;N@0K0;A^0c+oC~IIP*BW#84bGC)c1CTHiDAk*1gBlda)#R z549@us*Gnoz4WO=AnbSkQm1$&iS0CYnMi25v%USzVAHVMYD6(OS+*8qzVoFy`9P|& zr%?;Z7i}?jStzVAVC4&wq}~t=n_x<{!L0sio8j<}AFBhGer%ys3uSudFR|YahOf|WzUS6D` zA$J^ZPVm`H(GW#Gpr&p+S;^2c^jc0-5)}xz{J>>8c1uc|J|&cbyrF?(i1>P?JO<}X zX_Q|CV}I;urPoPce$uFO6xp*8y?{Wpg;VwqJ*T|4<-=^{y(ZE1+&s1^(iiD&#{gfS z|BI)7N+&eF9L1KO>&UBO_Nm$&uJ1{`p|_rL#rQYMKbiIzwW}Xjkf5V=DJU#9l2V|v z?Mw*ke9p7AqT(==(%($8tfWF^ez2loovcU0lK9c{kF^gSxBe{l_#h#uJQh>e>3I~f zyG^q6-#m16k$PJi&MYi+M7|z zOU|9Du`vp>X<4F3H2RbfOw2k;tzERh(3_7@p4MuMmpu2HoO?-WW+`TfjqBncrjx zRYrtklfK-u&b0dz!TG*-Fzb5!9$KUoU7Ft8o}NUuIFkCOZjn5XBIPM9D(W5_e42%; zU6PmFYliq}aZDllMyr#r^2pQkcXr3|zwec}A=p|Kc0cs?J9eGN_HLG=wmaPqqiAeS zXNdn(9?5@9O^JH#Ng5EK{tIY9w@9I+x?NrRk&%%-xXJZzouvwUA%Pb4pPEbfMVL?h z-y5U)@*SCwI+E9L3Ss8qA5Y^Y);gY<(yw^89gazDWaBy&FDE`yJTB%}0-qh3-DJf}s zdOAY{=Mf|ItCi)x6n(adq-AzQm?SklJ-u4Yi1=ur3)}i8$J#1Z9`cj87cV5KA?j>- zGkO-&{8P-VtOT5Xeg61STuiKeC|^1wEp5F(Cr#l9Hpgb7a(QKCu07!DWPi0=R0UPy z1|k1yg2nf5#FA(;LhkPFb8~Z0_nN&U`Xp3F>ny)P9zm_Q*>aImAfOJ2whJk8Y?@(I zD+&$`Z9m;8YbM;Z<(;0JyR2xK+dDWAcH2-lG|bj!;XPWXM(6arEAGN}h~z?HnX`hG zo|dMgt84A_`RK@fMarUXl8A^%SD2q6!rIPmd*lZd(@(>n&Q1HP-;An_UnC|bHZ>Wt zr6|zhhf8Wz8HxbyfMOi&*NqaGo15F%$nU2RayzoCx3|~J%d1e%Kt7nxW3%!tXWmA!M*F;>{eqR5 z*#>cuj?Ovy&-K2T5q^sOSi-Q)*UG}8sOw#Ab+zX*VMN}5E#c?p;j?HyS~#Q`8HQGRoD(XFi) zQ}1jJN12_Pu4}_wvs+n7N$(H(soswX?FbI%r7wYjfdF&BKz{s4&B?i18+wqYnMI0E z6uG>%#&6nvih_!yf1;NE+x42sXe_GbvYtFMOjBJIyXnr( z&gOW9yn+JvhYoZEybe_7OGn2GHY;0O{dd-cZHZJ0H$G>|`+d*x%3MSX3fW&hX0&fC zEG&HccCF*(O?E@!0H!-Sy4r)7>B|cXNZ&(Or5-h=R?#*al@IA3c0yd zYFO_j@E&)r?ynAH@L3JhczAf|GKF>h+S}WkZg5y#U7c@o>G{D+O)4SghuVHR22|{n z;Pv?2od05XG|)2rcK_M0U#&H4w;(a3qkbOt1_oUHT~sP8{Iz0%6Kd+={9KAzJcp3tjCWl#ESor7U z94@n2a`R#E+S>D?)WN+ ze`O#;EWrQKqs~^J<0!kB*AUAC={)i*L=gYuqpmcepD=K7aj~$}O7R-?Dkq#sf61yir*uV;qr30trCcY^3ccmR7=!Zh>qQa)31f+@bK^>dqq~=xLz}M z!w-0oUHWWV^qVx>5E*dM0J}>z>gwtMW=2`okYc-SXKWV$Hm={YMJ^f?wc@y&(~mDJ zDk`?Ox8J{iU-a|V4MdtkQL%vay?ghbDBbvAKP$LR{t?x|VHb9(yu6&pW*i~z>|E=l zWElnpk(fpM_qd)z`~nst6}YLm`bTmc%k8Om2Os*O6a*a4dK8URK=>%_>yQJAK!8Fu z6cG_&X72m({@7$A2o3ATX=LK~fy)iCi~%Ba)IWdzAin2>YU$}szr2ZyFrKQnBHb}@ z=3248O3TU@4Nl?fc37{(*sc|1-Nif>A!mH0t>0toLM`w=VCB zC)KA{V-7$G(`&H5*eI)dPB=V4V(ToC866!BFY)kLzRW`}+DA&nLoZSP>PqP0>I$_` zNJ!}MtC3q0!XhF*SqsXBhOj}EMab)$q-12E*!)a$zEeqRe5f)}BqPgE61zwmZwrRP zb-wKo!1WGCLImy~K(pQ`P<*s{NUBq}|NbeVq@-j@#<^r%HwpOxb@suNC`V&s2L~~*IsizRnVCfjKU)J}IQ~Rj zjCFJ@EXInBJDxnm3EltGL&=pBa}$T0W8fJJPH6r?0l+Fh`5;LC<;*q$DIPvP8&MLX zb!M82G;c9YE30*|Sb*;N*bTV;8Vm*OVueI;4te_YDV)2Tw*vR~$@$|@9LD5SsJ8St zybq?_e|^T_+2dnnRlN97)zEMZxGeJ_uB78bK#@XP-X~g)o78#5O8EHrC%%`@Z!Gr2 z&O`A6tlHe%EGsSjqHf{68H|B1dj9(pFqfsJB`qUA4f`IktCMdbAtBDYgalF|-Un;l z(PS4{tj4jz|Gj&+1(>2e-cC93+@b#odp_Eq*PG{Hl?V3fKBT1 z@^WEu@rY4tYb(#z+T!A3+N_hecQd1syee%F#_QLwg(+fB>gjCC@0vTOuEe1wCZCo9 z^@6n6-r9T zzq&j=P$i9tiMb|M`zHaXBRSwnNGB|Ozm#K3Ia>&&+?i<_85r0G2BP2U%_Bl;`s`Va z^%zq?z!lgD!~_K2Lje?UDTM!yZa;~-`w-%0TQgut05DkLkDSG1*}PO`OnAS)8YO3$A!?mA3tLKGxj1rFwBJ)E zaG$VTYl(Wx=%f~@xZ&^Cb1dka<>4r`{FMyEx%e1x*9s;aJT zY0*j`nI&a8H#c`2Azmu#jT@xXY|*KF4s&gOXWrPA(J?W+AJA7E`Gq`ow%X5W`T6-j z_w;1s=0vsy+!&8c6orxiX(=l!%dA=c^N%NlAm9e9xaDAGO-)UFuNmy0%j)3l2d_H7 zwz|4~IQP{-u~;+-*Q+iQP|6o4-vZ|9trFq>Rl4!%6dD~DkhyrE@Jh?d_5zh^2O)bY zw%Cs(zUm^EihUj6pFgiTq<)*56XoGazI++K_0?N2#h-W3q7KLkF}q>ENzLV-*Z^VA z-+={HP-T*nlcBPlRvV2qJ@>-|sSueo;cVpQ6LWUF3s`=~5BGCd7pR3h72T%Gl_;!JCRwO2lyj97+wnR3^S?|1u(k5y(TmS}#!`@P_o0}VfR2Ho0`be># zNU$LzJG)V{tCg~{GDKzGM6{Q5c-JqKn>cS(>7iV}DR@&SQSP-~e#XYe1_I)oFflz1 zl)Oz0mmOv1^}~k`(>JHq*49FCDM_6_*o+h@ZoH&aRa5I-9lbu(rKNjH)QVq)hL-JF z0>5yWst=Fp*v2hA#b)*AS-HT!dlz_URcs^%zNQ6DXG~$}?r~jA_r%S5Z^IF4&yCR% zC})4yi*trYM#TR9eEIdO+?_rfb90C$T0HbS`1n9dq;YT8X_u?yKdCTiaXuiZwO z9v?sd4`U*rxg}{Frzfj9BYP=DZEcq=yKRwCQRkm1FLO82-u8;;EWFvJ-1}AVVK_LM zgoK&??zH-+j|-0e`x*1+`#Dz%ii(7hUHx9RN^pg)Yu~~033~aG@BvNl%b&1v0VjP% zGNPL4pw@B%E_DX!hbfhj$YS76pkiqX7WVcOczD$&U6{X)ljRDvD)p~L;ipjCXuC!6 zWyrGr-a*L2&50_l^7sB1-YcFn*&;sbO%d1_Lv2eg^74^00fsn-Tv)Oz7N?sK$cm0~ z`hI>FAa8)qf0;14I-P)=rjixcD%bwAX>^sIl#-mBB^J=u)&|ZmcAAS z(jb{xYxs&qp!3rwMOLDqwg83muHLw%)zutPKi$FG`;cOwto*Moj>&j!l@A|W9*iiZ zrKLs4GwSH*u1LH0!65`K;DsDb0<%`-OtYJO zC_CTd=nvP2@D!i;jgqw67DGcr3g2GnBWiA2IXDzsR>ad%oQ{y{=)|EL{iD?tSh;lN z<@>-|L;49Zn!)i58S(e;-?-qwsWPDB2MF+J2QH z8v4zyy&O-PTUyE*zR%8z@bI|JHoKWg3NbK*^(_OU4x`N62{(g$0**PfxVgP8VmHN& zzy1-U|Ew7I1s)_axy~CCx6N@-37TUucfuvthrfbjF+8jqYBi*=ImF-ihM}~yl1Dx8_+BnCB=kfC_yYK&sPFEa~z$${rzPE5V0OEE?gzIstgSc)BAnY zFrD!4b`OSyg&9V>Iy(N{s{0m(e)Rh{)$MzLT`eBFMJct@?`(+cw2CosaCjNfZbh9* zFA^6w3B|J9-oe!OMxrb4=dX3y31KDPp)@4*Y;-Zb+-nMLKp2F6{)^l{>-CxS0mpCT zxP)XcdFI!B6Ax8@RmV_>oSvWT&!4aGbsMxLas14u0?IUAWhACdm!wRfVPN35^d%lR zG-NSoKHvzj{3W-@9-Rh3^wgTmSIKGvw`;JSG@;%lBanJH@_PNVQJ=5;>t3@bIjhA4 zCFmkv#w6wVTz;nW-6!qPn;>qtbLd40?Kwgw-Ry4b;#zSpL2b*Pg3fi;NNv?K1RM8C>V^VWn;77iEvXOe4`9F{|EK~Gvtw)CkOToN=GRv zDH9VDDEtYu@=+#%O-(1@X@NUb@vKKug&_3PeR(ZCUER~OGf)WUyH}T0jKx)t4p7yQ zfDUERKc&O`K`{58(8|WfXKyK7f2MBu(IPl!G2{Y!00_*YPQAanb@}a=HLGaBt6CzNuYvjK z#hgt^%{K#_GzCo+l|NMh7xI;k(D5@(n_hs zQi_egai#bzYMc%v%I-&X2ZPE>8s4t)@z=#9pfJFOpl%nL^nk>?2Kqz{EE3E$Ii$Kt z+mWOX&QDJN{w+6ZH)QJ)0e`36zZJ+~wx-HZj8r61i8DW|eq(i&DL+)vv-YbqvBHs5 z1()nIJPGP}U%*@Eko432gKt1ncx`{=c2R57tViGP%FEBs&r@x8TD+lB4?Fi7%NQ)Z zs`krfeOXCK)DxC?8T*;W`xB%oeaU)Xrq(!iDWi!(Ta50z>eTwOAwCA@uCqyLv4J%t zF?Ug!Feo_klI}~g>rU76V#|B^k5oqCbigRuFOKvqniS~r_w$WDc>cNcqa~RJZ3e1J zPA($zH8hJNfsTiV%gV^SEiD~RE0P{=(yneLgf_zWlkdWYIx+W4$F91RU3#*pTEBs zpoV2UV#5OMP+iTTp(p$6_Q1Ucpt~D9_Fxmr%3{p9J$VBP__+N_M6K0o_uI&Anr(2K zK0zvlq3_sGp>mavb9j1sG7t^N{~@)IPZe}4O-UiH(YMN@0hdAz3yqDD@&3rq!7QQT zbM~#;B^gnYa<(bLM)N*Q|L*wn^MR#JG{hIYl|)PpDJcyEg82Pbx@<(VeDm?f!A<7T zhjfI5gf`>lP5u{xE)iIWYHb#J`r@f6UBq+niJ|ibADlLr4n;$)_^Ek~`=9^L0&D|f z4-ynO+z3Qo**|g3B*#waqg_w@+SiAF=gw%c^f-w4Ehu6Q4)f!VQi4R0hhQ5Jvn+uGU!ZaI>3BpSA`e*$F`V%UV}1{xal#d?j8?}mr1weOCYnFe5hT&CHrijBo( zEUB!#1QbRDW>X0R9R|({)dyCXix`y?vvqJi4c4Z(xcF7tAtx6Xcrm3#5)}`a<1X{L z@jAnp|LmQde-k~6q6ql@2$fk-KN_vVghyX6)zd2+xw5K?II?R>DsU~XsHkZEV#nh^ zYsK=~AbQPiROx)RV`a}I&t{8}guAA}qG~JMYyafa)RZ?=RS`!?uy9;cZ(SS>i$1~I2`(L;$_7$jd_t9`sMB7Z8hG%OnT=A~%( zPhiIyjBfFw&m0^A;Fj73TW$XFWXF`x9>h|JT+av~z*tLLW+AcxzX-OF+WsfdNuUCr zUS9D6DhLj6(A&?K*&()e1Fp`R-8NG(`GtkgfmF)bC zoest)CZwM{p`)YY48`i}>pKRs-t*5d@aZ7%{{HpMqBLMT(xQKP+5bdA83{~6@cQCL zCysaLufU^{laqsL{v~J^#vlm8aeYn?tRSs@d|J}dCP6|61qIFdpIr|n_zdMqwVw<) zz|~-zZf{n#SGHk65>2=IG_!(bYwrrY;FS(>lzWs2V^k&4dp|bLK z@G=F+W9S}sfYOVIti-1JZ1V8lSJsOibcc;Aiw zd+Ulo|JqLit%|FhTH7O-zv{R73b3+9yDB-Gj{EI(+{K~}NMSP&^x89HW-bFAX<=z; zX=Wzub7cFY`WZA_oZQ?ldc-avon1`z1cQGc97M&&vcsx6Q26+qK|7|Ur6scK7Z~?5 ztv*`R@#TiCf{ct-m**$oHwjYOLHWs3qx|4|Qkzpk#t>oBCa9;QL$Xj?T3A`R1I+}) zPYC^^t;vLhJEsTGv4b`JVS5Cg1gwuzmLP4s4BS339v%lMm-q+Lz?0}lropqz04-+R zfqatns{n!KT4zwmW4zkNl+1=ITpRK=5^Rx_P$~=z?zL9Ek{-f${(~Flo|=}%YSebVF;-^AI}HZc{{H^F&#s86 z+m@W~N62u8wiCMjmnvYPl5(BNLftSip}uf`%9;C6y0Dk}VRx-2zP`TxoY!g=SdH3x zdN9Frt>j_b;YQPB&N`4WUSm2atBq@TW3! zw)XZO5YiCvRsu>`{i7GB@$TAUiHKy$n*Y6Tm%FCcT^+9^U)e@e(RKI8_Pyrg9>vpJmVY zzlm+WL($NueNj|X^9MkV^gS2w01H<}mHtwul#~=Q5BFU>>7iMhB=NAlJ!cJeV{6Ik z1(zJgM;|^ohxGHX5TLw(AuLvpTEJ>>g*+S`mD3GU;r10spzd{(IVhxY78Vt~%42}M zfO(5OPvP3b)5A@$2HQ2Zg}nBbtVW7Npf9iVp3zG%8{q%5*mufXxN2c>PERy=V8&%# z?5aREQNhdU9bEkR#WnWLUjY{WX}{QZSh5G(7_2j}M0nr3y~MkDGxVCGm3$u^bzSKv zvAChx^f?jga8au_4ejgfg79mXV-Jjwv8w3dP2?%)RB*q2=6q))_}gmxpKdbH{c=*i zQc_)D^H%CN%$1K`%`83UK3NGXR+ zOIuml@o+=KG$(ESk;P0|??PO1GLPHFC=?2)albI0%F92fDF#$Mu+H=q%|RVomrYO2 z$N(#T#4r)GSGZ&z-5bG@k|N~LPc_iZ6Z}*U9xQm2`U}t%2hY#Ve@E^i7Z)i0AP`xq zCwefk1^2VMyj-FypwkfWdZbv1UB6M;iL|j)d=6GAHT7;0e-ZKM_s^Ess~Uxj5sVI_ z0z{;qPW+%{z4k4d+^Cn7qcC3g#XCqQSzLhpYXR1Fdkq-e?c2A(F3V4Ob=~A_a$W}e zH5Dl?V$P_uP(CHfFG7a>@5u@Da4*0B0VIchq}kiVE)xMEA$HyRHQ-}3#_W824e#Gy z%ZY;+P{09yKT+Dxx80+ptXiQwhU&jroZ}C}LdB=;;iL+Dm?p}=w}EneHmM<6d=Dav zm4U(db?&)FaQ{P-w%bpnrOSGS0it2QRE>-RfD1#-%ww#pt$odAAXmVFxb`}~zj+Lf zfSE~VHcJE8y^$e+0wL*+VXt2k9pWxtvQ!Vx%$#pca#@7mhXDsze~|2QDj_K11_rY* zx&Y4NTe-`i$}5(oqTy402u)%({kPASVKt%p9A6<*Ur0X0>x_&1bo->NcOy_i$#j=jX*ZITNA|!03Te^%f(ZKI!%Ag!AxI0AkQ@BQFmh-=v78 zCyHFZWj=L3u{Ze9GYbm~UES-+sW13x{+WPLt%u`!(BNL$WUl&13gfC z`@yeY1)Y~Ds-ef=nS$5r7VltEvW9_vz4=Cl>9 zjo@HmMFJPuJiju2_DrG~B>_wG;?a$z+fOs~7y>jT?2}bIPLi_^p1_A9X3vOg^-Wbj6_JboT1^-!B-{P)5qXj`r~^XvY zw#2x&xWvRy7IhCEJOCyo3$kL|9o%J*k!?p)HdU=hq$T|pb?dSOfP@g2l_e$jL%_-) z<+V*6cTay#5G+Y;_568mJ4|=TCnH-7`kOwn+W;zvQ>!om|Nc55A+KG{-ob%5Tyg_N z{LN<5;CUcJ9z)QW&;rdJSre0AP!=c3b*{ZZu2A)jjSU=fen%LNKuLu;5-`s%Ax?EA z-CbRU11>Ycs{*Ld)nz)8yMfoykJ~y7#2rctp!Y3G(V5|4P7aRWz?iSqQEw1CRH&P{ z6r;WeYM}u{;gZfjKfY+Ie1etE`c`73xWp~YP^Fna^BMAexR5HWn_oLJ+ie8nWIUu8 zcYz^6Y5~F>Z7ivcl($7U)YihlOhsiS?`e9{jcypMfRUvfD{e1gLl}*cmcBVs0*-`* zot>g6c+83a z=y+%`wHs9Mphl!0ulJibuo<-}T)6Q&EWvj-d~_@_U0zkI0$(EnBwQ5dFVUIz=?n@lHQ%17_;mg zz6l*KQ19S6S{f?c;jfgFBz=Nv6Q)2{28!?-3>ky8jMJXO1^y4^fRUMbbL7zgFgPfP z7VdV?FA2rDw_)=;2j_~#1Nb4>BP-bgkE)oNxQ2YK@8vlx5ryJMc7faw^w`OK_ABtL z{-9>aC8y-sM5O`vtEvYp&Q1Dva@--U!27+!De?5hr-ipp2r^EEFQ|znxCB3J-K%10 z3a0`aeV)H5H|R^xPhkiHB?;p6_)rB20i>)@ns4dVJy;$%&9&*DNafAWUIkrvjw_l| z^jitNX4f?hR#O<%IJAP+7;6YHaM<8rVp7dn`|1j+1N=F&lN%cJQko}u#6ldxx?#pa zPB-x(i$G4pJX<=ymcRj1(3zZ{pWm}*3swGy%rFiFb4Soz#TEUVn`5V`rIq-@Xfb;V zMn2O>vRosP9+Ab1s;H_yBI@M#*dcdOP@MAX*DFvI8Yc(@}afzT-VIrr9T8(Ufmc^^CnCo)ap$*{1P z&(Q~V9Q?O;L=)cGBoZ1Lso?qD`+Pr6gEh=ih1~t%=t$IcEw0oLI&kZLZeO5+f`W(6 zF>vKm5|Vt(h&&j211j=JQ}&?~Ovb=**nHy!&X6uD88H;IWoM|oFj;@w=ze`Z%uw}E z2Al&k0EuO%(Mx^`gF0OkMgexNCs+pS`=biw>XM(b@wjr=$$26@tr{CA{uTN_qfAXq zAdZ3d^V$Bm_KRU^qR5wKnMOqcCP4D@O##Nki(@o}u`~{t0^mKy2a*n9q;2hnd(%>p zXEcTb{U65$%-tOwVOHbuV^fQj@L#`dAP08TY7r!~HrAtb0`+ZqR4_Hy0^K5Ll3P=t zNTXw6F@uSt6a-kdGg&7+F!e^EQQzLzSJ*Y2!azbb)en@SpsmYKm>az@^VmBu!WhB9 z#YHCS%a5pk_b$ExM}wUL>L}eW1YMY9US?)yu~H6LDe)|`x|=_NX5-U8g(;LY8Ey*M zoZ^!t{)DHET0>DJ-|^O9sO%?<#6fpO;I_iQ4scQ8(Hkw9UtEWY(*PKw>J04cDH+0{ zsZ^}23DU7lr_CwK+JCAj{r@h62Eb@RN|HWb!AR)x=BCZB4mOZL=}O}FtHS@Xs6@c% zQxPcwai`eE%1YM6ecd@BHRv-3TyaVGPqVs78d8H#MDQ#G@TLV~CM-%7^Z7ZpgHh}%EchAp4FnjV-l6R@8mT2el0Dzt`6RV;gA8cf@O9^L&G_+ z+Gy@z|7S5!$yz4P6Seq9Y$@`FSt_Vy9Wd|K z-Tg!(hV^DVn>=($=de@MMT?okjF1O$VSf z^eLOdSq6)X%RWom%o9neymNEIKE&qKY54K3zV>L(7apUrs&TvvCS|$dh*HTuQbuRQ zU2Em^+z1-E$4ZV>2lOr!kzE@~8&;AHx##!9<206`6KZMu7;hxxsmmrgFv4-T>jCefV<+L-|6q)@A#ofwFkov&)Yr- zAXxMpe?#d{ZBY~!2SnBQ0^IIH4i*GDhOR z^VP2Cp`UbMf&x4-J_rqHu7VubVWXD?x(&k$*G*!08Ai|S7dk_j2&$=g>)y%;$wugE z7T#v{yw$L~5iEwE%&^owstMM#Qu~ff)J$){rBPSU= z__SwYLhIo(BXFl+!0gZiTM_fWL*%VoPz-hIEFj0B`+Njj)_+hAA{+Dx46IPeW@(@y zVFg)!9JBK}KQNa>#xmh*_@wd7%uM`QLV!L_Fby#+Dgq(C@MaN#m#Lpbfj}syE>RwH z@VW@uPT!awIq5lHbVeW^B}4}8!EdNFY3uQo2t?7My{Io`BA(~QhdBbq%m~>jDglv)h~SH|IbXknMKCXH`vd5FLqF%f_42c-RD$v z&78mJqPou2RSS+Vx&A8nAGxs&Q3uLdF2(h=-Z!s~AT*#+i83_(Pf$C!^bHI~BB^_| zCX6M%(pHrB%8InH(4kU&IkdJW3CtBbdb250)5mQS9%j7P@nho0_gv&1te`Ra;pRMR z1R}U6-|f%ZliPu}M7=L{FvW1fb_dAb6ri0OQK6e~ez>|k1EO^ShRzuK`qtW7qs0Iz zs41}M4`-;+vlry@{E%dfA6EyK1op8RgdC*CB{k0Z^wr918JH#rp>ZT7V;SIkZ)t0? zxo$^r<76*jYK_(NpuS^AB6Or2ieHnu)$@}`b$k$iHg|7Tx1ZXal2GacTs@^FiCSA2X# zVDCmdAyIuQITcklT{#%GfOVhhPj$K1eQb&LMWxRJ{;fnJ-D48^upne&1yKZbeY9M#n(YT+w6?k zGB>}poyuaKZ#e19g-hZH#P`y^6*tMr4%#8dU-@G}nJ>*}#S(ve9wfYUz1OtI*q~ZL1yWWHmKe_3s+^FsM{X(Ea8foNdJtZ!O{Wzn{?p!c$GxV0=U?Y8 zh+JtZNgcW10J-CdEBbZ^4=i)W+n1#tTlRBn5L_~m!T!fH-fMRUkOK1 zz5m2(ff`%$+>0r1W~b6pTtYF8XY03haaTNi+#gSPi2(UFT_i~UO$Zi zDz#FluDiEaRYw3u))BCvJ}A{ z+C5DC*G)HDS}=ufib94E7TpXf&=B4 zx-~kbZz<)>&eW1UQ1SGs`#>@uv*fIvP(z>5)l+)*Sj!2fQiRR(WcSx$OiY4$^zE34 z*xgN3<->)7U;0dF|NW0D7 z5^!>wO_V3_rg^fW7`@Bj9Pp$-Jhqz+jmtq@on4pfnRz!%GZ@TAxTD!O8QUfj#N(GN z*-&q-B|2{>0_d_3eYUt~Fy+-_$ueQ((`==z1PvN^2A~ftb($#&dph#)7zS2Wp7&{V z!M>NK2!y|ag-ReZgS^2E>-77fouTb&MX`IPMud(4LXRG)s66thn&a}jhY(Mp7o}-p zprZ*{-=)FWc2@sk2#|-p;Y*D?B43)iwxe1-BSFbID|IW>##tsN^HcKEd}63eKL{U< zh<*JUf~dT3=pl%c)2r|rM+`r;8^eed8*1KJQM?`Z6Wwy?Th?Kq<;2v?*TokyW_H-B z5BiKIWV~Zoy|_$lnbo${qFU=KRu%K6<#qKYHa7e5WwXjRm~1)*o=zT?qgK1uREJl^ZHGKE^@Jyfu^(qOwEy6#D`{)amysCW!VI!(#EfMWD=>*o8Wuq=`LTQG zocm+jKu73tLZXQG%v+hOw}Lf6o-Xu|O8No|LH5Ee-o-4m!umOfZsO1PhSIcNpA{w{ zi9dJVYxHkR#5AdEo<@L2lL$m)#HWaD=e6D5TA}Hd zi|Efx{s1_xKIFpePTmq8?fNFL4H`y+M~KE|EOGNkErx4@amA@?PZx4$rFREkXt}SK z#+mh-3hK8EuZ5tZ5v;6#o+M7lM95ysc7EC3>vIc5MMJMLY*uG;jgG=VTFXQ)-FjQ; zi))aYha#D0Aw+=-PpYN26o-Odevy??b$#qg(qFqSc;V?4=@2Gvg$HWC%JgrMV%|g~jMdU?fU_5tp z|L-gS%=>;|`~}bIpYC}X^ep{>X`Sg5xk7R3Fdqu3*kGDsY0TKdq-3`%V(;A2%yaJ2 z_Zwu?lY}bXS8vykN7Xdhf&+tLO#(CdXJf>u3>sUS(3u4b9Yvq5>etHF1ao*;`ulf( z#faLzo`USwm9W*+ED!W$*r6`l|8pmEMkkKERLW0cD+c<8^07q3mR*?5WtP2SE!?@# zU<^0w=`v3=^++Q~*Uuy*BhN@CBx824d#;7_$savh2a_bczLrrwT%HmCdy5BY_Sn8~ z?emOY%j=UkJIBg>Z^xH(eX)1mleM^Ho>GbV@2=jEnAXP=aJm!#e3rOhLMZZ$mzS%R zSy{V_lcuyvJtalvwjKT~BacWG$9)DGRAkKkddI(qzc~R9?=2S7izfu&h(A?TR`GWB zQb)^w3T#!51Yw$B0l(mcD{L3BENeegd89JLnRxerAUr**+)KDcQ-!rIRp1B*ff!f) zsk2{RQSeSxr7oH48|l&!hn1_B^kK}~_k+EIx-`huJ4^{J+2ez=&&Fzik{We7 zsW|1$j+d9gz&wsUx-eXIO$PMNL;dcBH~78Vyf^-w78tdgNf%n+|7Yrr%E*}jfq=sF z<5mlDieYLsXTFP2|7_F9J@I2hvx!3K$Q1Vg!eN`?S9FvHx@k+q*|Q|g;!OLoCnsG< z!F0szk%TmyWW%}sFt%gTt#AkJe%OHEluqle;mp=~P;l_CU%^2%?Txkw1cSVQrZV|m z%*jbSQvTMT+WLe6Mdw58XqL3%2{}gY-?~wK`4*DZyFQJya6MJT%W&fs;1<$IQ>nBk z?7R5&74axB5DUpkWRIBr3@fsaII$dWQ;6H=M#0iqC}5Wp_@?4=#sl=TY!J)Ae8?fQjYD zV1*z5NV*YngIj}M6WXJ2R5GMyH#&Esw%Lq@=My6kJFA51C*Ly5w2={P@-gI2eN@jr z9Ww|2Y!?Vv)epqdJHVG=>DS(w=-P|gd8Udqub3L2&T7%F5A)9W1qktos8nZ5dby`Gj$&)cKBB-x;u zI+NmVsjI_6@*oNSE_dq6e6XSLfx=?!13L- z7a|x@7)*<*?oS>AU;HGlf_O{(TzgLiFQF1R#{eo$D>Z@S0BFaE8nR47@(}5jwi0tLh zwp-#>u?1G`J>*o>P8;USadSH3lZ8RD*qGRuJ6h-l7R`?fpCp$(-C{~@^IDz3(qlvD z|G4A%B3ROv_qT1cldqPyW|Zj0WA{uWUJQAeKzk$m`7bg1eK?9c2NxEr#5Aa{UUeP> zo%0vQIuj;osJq8BBozjq6@JIry3C8jmppx0dfwy8#~@5W7>^RMxP++xyt$)t$e}wo z!GPWs<$`H0ut&1yT~HOdR``%sb~kBUo#B~T8}nvOiNgJ5Wf=t;{pjJ5#6pEKTl=Dr zw?Wwyv=tX8tChHXHX53yzTBh{T80aTs$M|A9GZjLyd!8aC+egXPrdj4wh5Q0>-c5A zbF(RK*4UdyAbw|N<(^nteOnAVohMj-VbU|=mBV1m5UDo1TVl^fkBkt1XjNRY^oN|g zKWp7c!|T95F-kF3Rly@$=koXTVQZ+#C$Y&GVoekpX~LskJ^Ta{ z!6OED(BVn%S)H%BO{ym?QkJCXZqdKD(l?nDX4qq?ybFYI8lP+ZTsTAMY5wMlSz2|V zqa_xvG3%78-3(!Eu~?z(4Xg?_u)7}99?fl{sa;G!j$FUHu=Drlny z=sQlfGEB=^yu04C0njRBya-RG-F|e077x$jAsx^Zz{R&qN~X z`xiWXuxwVAm*M+*ENxx9J9>N9!M}kKxMnLh?k0YYcHB>Y{VJ-M0en+5?$W0?%tIn5PSJ}*&Y$kkp0$vGz+pSj|D)_JpsIY^ zt=~m=cSv`4cMHa=n+#H0=vdy+ZZSOMAp5xKAfIRUW=|0%m6^6QKRIs|xyi64*t6^ev;?|%7H|11<}|8akRI4lw7 za=XvO+L~$232;jXnouO+A%IxQ<+4^x(oO*J6fwh@49}5uJnb-Jf8@j?hjTd8!j_*EEff?tWC!4%}wX2TzNJCTn2bQA^@f0 zsE(ED-I!+%+H*EVL`Vn__F70SP06h!rapx5X4_WA#*ugWVnHabOU|+S9)rXaelz|V zlCzsI@(MSO|i>4{3sBw z>`6;en6GiU*M7J1p~8WYMzHtdRa$oqtsoc8WC8}EWO6TZ(qLRn%*TcX@EN2Rq~r9u z$LH=Nd}-%4n<>lQoDSlAE*U`q9_mU4JD=(hHQQD1@9s>3@4al0)IS@oL%GtE{E^^ zxaa*@@G9ih=IFWkyqNDf^}waulxZN*4m8B|D3xD)I-nm{5;I&9xLK1DusBe6qwH#^ zE7)24NSZ6GC&I!JDhSUw+7a855FhpeV2#50S6@ZsN9}X6-Bz(1bGHX&eJ$*C-@ifp zLH{M_vE*QoH{ro_m8?}*x!1`0B9fjwGO`mYzkK*{Pvo3#{x>ebOzl51XQC+!Gchv* zTyg}r7d*L$h=_=fUI<5J7a0FI{i>W#+qkaX6Mn2XTT#rco9@96+V5U%-|(lq!Bv}( zh)CiX|4km*K60{}RvLu}*(bE7s|^kv1hz_kJ3^3O6vf+)SNDSM@XC!5Iiy%YY0JZT zgVe$Q7q+>h=K%~PYen1q@{;{N)?&9*43Y(=zztU92-Bl^1 z9qmMfG{CGfh^4$T9k_NI94vk37(0@r5@+<6jf#6@zG}Z| zIlVUyyM6K5NM$TL718+0bt2a&L6pthwBWJSmb4BXq@sYc+K5PZrhB7Q{nE-$-RerW z*b@q<_cPR>oWc^!=fb6+5zG%BTkF;wbx!K+Ppe)zLQIn1=I|i^@)`Z>t^Uw}=S&cL zCa58|v`yk+@ttFG1k5)^jVwCJsn`VDtJ{?5;7z&bo7QE&4#GV4_vs~2V>ZHmIB;m- z_P^pMa6MHTMx!^4LxG&6L{XGQD$v{lpo+IvJg7_@_s9?2@#~6Mr7ZdRZAZm6?K;*+ zih+Q*M~U6cXh}eT@DnhINnQpe`xOfW2o-u_Ys>1^)pBUF;o}Y}7oric_x;>w(dQ3E1epsXJIG_A7EHlUCOD1`h&lgnIt#pc17O$<|eIBvzuQ%gSITD-j?GR~( ziV&hTV!F3KcBIv|)zDsba?Mv(fZNh8CGn*D>|RM>gm8WFjuu#j|NZN!i=7FVg2g+d zt-xC+&MsKZJ=S?8lI|F!N13+N&r#o?JhYz*`zzI53LZf&9)?Y&pk#j&OA<5H_Hx>l zfZ(kc6ay;r5>n2f#NSs#chhoiCIsFhhV4Z!&fHhl zTkKBu+i2f_69d8PVtj@=|1#FrO#=h zAlciQYy;P+-?zaRmm)11T5}#%t3Q2yCOq)4VaGJ4bz5&s%@g&4SVPGZ)cLP(hO&}Z zy-|^nF?B?&wD4gkTv^9P)mfk*A+H&+o+l?0F;9L|pmm~(CPrO{>C#gpCCGe3Vv;9f zYv}W%Nw2vvjm-zEEgZ`#gxkN(R9hYXbHnAjqPq6T??u;Bi-VYr<(B1Tfsl=jjjtaR z+u`U+m~K=wE$9j~K=^JkLAU3Uviq_r5J0L?GRC-1yf{V< zPd-QR8H6IByD3kD;$Q-Q?}k{!P-OU)zSwi9ec5N^hb7KfSxi8Uml#HIU=CE9u2-kU zWo0%aX^aDW@RG@)5vi$~zP^I5KXW!wM*rBmkT2{M_3?vZy|H1=N3+p@&kYl$N*P*O zGGx06pRNTDarq=NZB&Cmzz-`cCjemf;{=A}i%cXOI#Mv?0DdfB;sM^*8}L-JMJE!H zH}uoKB=GzBskp0)Y?f&~2wsW;u@Cldveb0&0C-kJv};*^k+W<<2PP=_$`0_FtPm*= z`xc@oqNFd9OuVgpPq1$KP>^~FUd)*_B1lH@tRT14)O=kSc#2%3$R7X{0LW6Z5P)A! za&~}c{xk@Xzy)v0q2v-nsBVCZ1+LtHX^rN6PiDk0!Y5k2tc=dmFqAM2>Z&9+r#JTU zsnq&B^C9Fps@OkyS7E5mu5_f}>*A+%{h=`X>yh%@k=M2o7~ZY`;W+@piFaZL--rD5 z24!Ae2LuHKbi5PO42AwE(|d`_CSwSw-vUJ zoc&{a&C%YUyh*p@zNjxzj;1@pB!)H15w7&FSZwre(dgXyrc&_)?X*jH5xB1_vj&p$ z7}U>Yzi0EWM{rTaW68f*y6FL3|tOnEHlgv7UjLCS>Jm@Sz7<4}yY8A#oM} z9}EHLfvC^bYCFPif&Z^EDBh=HvQ%p0^coP4X9*MDN55d#DYIXUycS4IwOn*3ZC*4o zelA2>Co5g_0(sjbG@Rm2;zo~O^rbr&6XQ(Ay1);skh4hp>0>K}@95|=QSZBq&MA0koEb%z zqQC+utm^7nLrkkU3dffBm9V>SYn$IQsflG=s4pU!=V%2ndYYt^9L%R+u`5jfz>Z97 zQ{2b?#@?#oEqQXLB#~?&Ic;9y8~dR??2<9R_>;7DH_8^8j8}5eDVAf;{MUyQoSng* zP?hqTeNXwv?U9s16W`Nv-Nd`|IqHY1*Y~Tv7M z60Fj)WX~)#)K`cpjD&`^e~f}Ns~f4dQDv40df}JtgPIZoqLku@IR<+JJDsjBnpWnQ z9VEyXOKi?;(%Pb3(P~>#UC)_ z2X{R$G_0JcPa(jK13S6^-{qSX$v}v}KU(GdswerQh(JEco_Q37ETw%j>wy}}?PB9m zgBZ*dolG5+spy~ZbkoP^U0-#WotrfiBXhPIj*o^fep|BT?+7^O+VyayO^{`~hw)Hq z*a?NYC0zA^OS_7l}y>xsufjPbaDN@@CWcKEyl9=cW0{Id*KU0XsX<;R`>^Q{D zPCH@VK8L$BM3PrHvBFGHfzN$bh8X4=f!bv620@FaPX3N*RR^cnYdu=DQEkm3SBBVk zfG|Q(C;P0gwB`#7X=&LPnqq}4l5i)p#GyCkOmF^t=xss_cP>^2dSa2**M}uKVjrtHD1$U4!96(E3&M%^v42xDRxy z?Im?bU*_StiDBc&Ydd_0@70&1m5rD^fS^Lwn>REBVJi@b(6UCuc0+etv9*keZ#t0k0Rp23a9+bURp`<)EvqlYf!J?_AzhM#=w5#Dc)$!dY3D1##8O6^~!w(9Q z$7CD7V?mp?uNToy&2!6vz1oh)c638v>2-6Py_k5;#KG(EJL9*kbn-#+yaw%=fxyr= zgG~JtUhC(_%+v-d!t!A#wkazM zcP!!_T`0i;upEw$Nvz*KbCH`Q35m1guE&a^$a?&;QyTVt2@{Wui2Dl&y2c#c0Tj<)h z!<%2Z0HK{zV6KIly*}N{Cj4W_Hx=e_z3b4@&(2N+laq5J3{7hG+C)5U5d=G?AGE2;m=RGIGm*z6$>DMdQuY)2*xl(T z1h?-BpnC+A>Av_Bui~%X-1u%!T>oTACV#dXeAhR*wNLH(>hToC3m+4LYZwDzXeM2Z zK5R1|*|OSVPme(-q36w7b(%1K9+x16rJ;pQxLI~VlZ0dmahMj-z&=to-Z{3! zv}X|;3;Q0;APYRJHNny7?0fyXj}9zNdXG%D6dKP+c~FIUNrm|Ed*K7-$%6yuZ40*r z-DpYK$0-gx+hnLtzX~4%p4HpS3y(qiY+JkA1%3*RcGEgY3_JBj$L#x7Jr!7pnHBih z&=Lu9uz32)>e2M^;sJij&m;NI%BxB21y_3C0sG1qk+g#>n8-hh7nK!Y?0e3bUxa0& zWoU)odldb=u<|9U-Za77ojYrI&g~4PRJX9k-#v%L)vlLey@H8LFZ6Dk56ZByc=3am z!Y@-o#32G7hV4tk!SIZby~$nyQT2vau6@i>t~;GxLHT~PhDcnj$M}V=6_}~4rs6q& z*lkPwZ`NrYEIjyzb;0R^m=$Q~UtZ^5pg&89G=u3P6>vLWGlgMX2(Kf_!`!{d_gQTP z5iITP?Yy{Uerpy}P|ZBw^{s<(eiSs6yj^Hu6{jzb+B@gq@!gUzT?@rIKQDj$bCfN8 z4()XjYldHZb~Uy!)PeW0eq4YaHpCn zt7>9o)B%QQI;%o(t*Ea`?r|Gsn9Re~!BYZnz*rT~vJp z+Y^9;1$8kf6cgj)x6*t8IR52}Y#7C?kF1W6$k3WccYi_d<1|QIo!Hu{<>UtdtM54- zLp~-~lJO}v4mZn-1~$w9Yc9q`-?AQ7y-!hr)uVfOT?^Ek?n2bCR?rCM7rTCvRwMNL zu4X;bW2jLu8p-nMmkjyhEYGl;W^@z<;C}UlAeeq38FFe~`3B-cQ(HPZ?$*OG3PgO} z0Rj(Zhd@knJ*YVhW6mQUa#fw%qj|$8X&$z28GQ`S)r9IW@+dT0cT&| z#hXHMlJB0nI<0%uNw~w+^Zdzc&x)n)W@VlkN5FjnMG4fGw%>WOZZuBpo))JfpF&9+ z2vOmE7pvXkJ-_aZ>>wH#iH#%)xo(DTPG!g}WZ@8$Q6bi28L1vVTI%~SF3xJC0i2%; z<0QS8rVJDH z=ZX5Ll&>4@zF~2_XMHVvJZ4au$b(KqQWqt_`y^q9IU=!<1|KcofwNdU{uMd^)^%q+ z;>T~KVYK4JOS5jT01i^K&*7VNKXUgrFwYZn^K=FoNX(odAJrJjhVqBGwOgzfr=X?K zr4q@;+w{Kux`Hv9U}N0^_4YKJ67?X`b0q< z+jap!O012LUQ;Y(%NbfmI6`uN74hfvc~knrV*b2&h&s4_32blEFqd7I>J^^5tHCGi9B@}?qmQo zcL{P+J^1clG5XOKnjCkyV*YRx10mGW4JhmYZU8|hhpdS8vUW~Ra{^!A!awQ#S_*)* zKw?VHgT~}~GKCWOpeRY?vYjQJS+wScH zeUkiwZd@QM-=%uH< zU9;5gS!3k_;Up`SKJb{4O;3oQJKgLui$9ojzKnf3hHNmv1%mv8nCZibP81 z4+Rr(x(+?t#>w1Gu>Q=6Z+>bY9MT_B9*%2}o&E)tG_3Ekhy|-&q~qU5doz0{FPXisLlGg0;qY-3|JP?Bwkqm@pm& zP={q+mwdK`eQ@g=B6z3JYVXWiab4QV`vE(pafJ|>=x9618jTB@YRH=opS$hb9|Rq_ z93MK+gD0VCgsgN-fm$Me$98GRwx#hsln3eZ{F1k+%Ti$HQQ`heRSywJ>C8SjyKL@F zquR<)_DX(X6xBfv-?8%~?+GM{(?v*5%B%a?3j;vXKltRb7I$|)ci)gt`Zf4&?4o$&u3s?#=7_v{1&=qxam+7%;^W+BDU}N*F8w6txc;zdQW9sa|4kG#p`x7OZNTMF8qVH{P&o&< zJ+OR25x0vrz`W>5wDg5VQ$hXZbwFq-{1b7-esehnjvQzSvOG z7i$#G`j*f>>dQxZOD?K+Qwn1;HwzrfF)?CH9;6>$AZk$V<`=vl&tD67_b-G;KmgCr zw=7Jxxdca3`ki{4cFDqDw~+FmC%@Anf7^r&dzzx8gDWj=C7y0MWbfU{DEw8-^p2)&4Fk2ubHF6|U zAR=fTx=@BuXcrGDwmfvL`UKy!Baa$yV!sTKy3w4m-^zju(?o@g!S{k5o5)Rpa{*oi z)*NnRu&s=-d=6v18C&B$k+5=3HSD#Xzf8P>G!&tuHz7SDod@zZO7y7bJFm9n`~+UV zL8LHs6FA9a_fx}XB^%SP1X;VUI2Vl<3Y%jQA$K|(BG1t4_$Zsw#LIID4yS0Ip$~D{ zk)gQ{5IKCu_rlChze{7MpiTA^z$}|k+TKM|TY~L{ckF!py42>|o0+)T;!#IO#8cS1PUq5MfXi&{Gz2ZmTu{qbNWM+RKH;_GM9W|(M`Z#t70=OW<< z%VS*Mcnb8~QV73i(r=XKR#6?|6Jq&oFk|ST3b&MooC1ZaSo_>cB8!1v4 z`4wpGWj-Ld{Rvi%ap)O(>~A~wNxcp=w35)$poVJ7EsE;h!$4gUj9&P=3)Qt#e^HT4 zc=O0cpm>l5!=VYJD0JLkF2PFLAx1Y9AQ(t~txu+7jeQ4!aHym{Kh5tkvy**ZJ`*D& zRa>iV#bnhE0%LjP$R}JpU?y(tT*W?;T@XONwaoFd6)H;|#-$1D)X z@!aJZY0UDt>|+}2Epje2Y-3iJ|$Z3^V8WGc`+ zMLz)T7R(AmTPt*R7?AJXD2#D%u;d9juw~#Z!oEF+(EvjQl_KpwHz&jb_Xkz0mHxm% z6x?4Dup1e~8o`8!!sI`9Ml;hr)qJn+!6HzSMGyKIPTndENHl&KtJ^f0uwIwU2^ zA}q5oJ1ZILp-l4;Tix+QJa-%r5+g*ft44_kbX6b4cIuICKK}JX0{N2SCp`Va<`x$A!^~;fs)9 zsSX3VA6VN**}FTWG5i#aMR-or&16o372aupIs3nX9mb-f8|!OemJsC7eSKGXEqp#~EePEOLnpwg201V8BOO8aw;LN&l9*3Aq|f~b2)`zY z#6^Owh+lGU|4>pwP4DLGd((?R4m{>9&|VPW;{zVS-Ki%<_k(JOLF6bsfq~BFXLs~| z5QWb6lDSe!baYVE)K^3gZh~lBcJxn8Yl{QtAlexOKQpCckM;O<2HD#)k|iBp+hFU$hj=&S?2+-`~9*G-4^wEnR<+ zirCaNM;U_qAG#>nLTP~sH1VH2f2f{NTzl=LOCD8tE#?-_my)(EzuDcd}6~hGP z_?d&qb41+V)*ko7+}zAO-g`qh$a4tFvDIrue%&#}T`0nMHok zX`Hpu=;J}6Icg$8ZGwzO*>mwXn8DEP*R}ZiLh)wmM^_rDwvax5-QXknD84nV)%;?j zDH7d6mf6c?}vp-w|({(A{@Cj%qgRzaw%A^|_*PnU~o zvtK8gs(GAry55~s48mTm6%Ef=BHWsi5D6mI9WUI?)4l%MUm)y85#(w0Nc8mEZY*?h z*Fyh(?pqnv!de|HuvMRwq9Vt)Y{Q3N6!4R0JCDdyX(?4xY^@H{mvhr1H&vfW_IroX zGlyByxG}_XIIuqcKk8coFa!15f)oOpwNuU4;9o|FokZfN?*eO0#C$`(i=t4z z$>VmiJE!{?LsK5b?5?KWSP_?FA*p= z5Up>Z2g4fT(~uwv-{n&wLCloSdgu@er}X?>eU$i_ElB2i_b7`DTGPIWt@&g8{GL0} z+|QxpK%H+*%VSbnt;Rl-KT`bEs$TVg-exGHyu14`lE7qP3RXF}>lR~84+I3f@dcdJ zHiFDcmeRm_S?VH-E@PgZVa9s5q_dAD9v3{nMd6EKU?4r&{9m8l<`7+yi+SDl-`!D$ zT(^3-{g{m0tj*6A=MjJWw5T7FR6i=<;o3)00NG7U%nL0VW>Ny(r^FA|^{1l5asVJ1 zo4;lBd-+&?6@6uqkoeKj0|{x-Zdwuk6$4+-^-^XbH5UydF&8(tkojltm?MWxsD9b? zO*KltQ|ohs7e4XG(**cr6&TsZDdddA!$#>~P>_J1TPFGFMTxH-6-mfh5qOlzllg9u z6drwFLE@i??B2Ui$WvaxS9w?kc?}>&KC_kC{Q}Me4rRtxjreYfmN0l5xF=GUIi+wC=h3j@afg!GwjLTl*kGeG8@86$bSOxlo;|l5ATOKRaLi zj~@IR^i1+cvq7s03TGg=Q(c|lcM1ME(`mhN4qT^%56``OzvC*r_cJeRQ8O0{I{ zq^B-SO?Kgzn%FmME$4bIE#{PFOLrNkP*OPVZsw!>Gbx);MjTlLrdPTUS!rr`p%4V~VKF&5NU`7Peett{Gui?9~QG|~nM z*QOsfe8p2gg(bjKv*=c?j`7AWjLhZJV=F~2%A2NKX>|Q6t2}+7msoe-++0}B=|4f@ zXK=XUl;d-nWJLuJm_e0-s!b-Cyn)EKUS%6xcXmjAD#Gs2Bl5Tu$2|50kIp+TCTQ&4 z4C$Z~C_HKS1RsqQ&_y5`QYxb*fBU@BmF`I)wWo*&z}NdJg*rY1LIiJ3%eZbTt>~f8 z&-TgkchQwpa{V?Gh|a!Bgd>CBsaM~Rm+6I}Wb-z2*77smlbtAd=a80r+2}B(fMc?9 zfP(IWXa5WnwU?L7*ifyj_l222@#b zuUrJiMpz-;1L;wvU(*`N<(^?mb>={k7=>njT7YW&%Z%#}ex<+%ZWQ&;dmIpM5lAo5 zfH-MA#v91z4S0|NtcqU3imszLj5;tRpx%np(F^>^FthrtiB=<(AJh0e4`WW*8A}_#S zl}O~YV2YypDFYX(mfM=@z`7xXsp*~k7~oO8~aPxHPETP zhkUqN^EKpWzn*p@y*ipvBF$7Ozu}oU6~P$Zic`I?t2^iQMz{jidf)oX9gFY%tKnqu zrttKW;%oQR`ranY?)>Q$rrh|HATva!M@;T(*cR*ybmCsKjOG%gaqBqz(TlW6i#n~m zU-|A_f@ixXY(9;b;2JyU{1$#)?xc><%YZNwFUyb5NMnxfP`c4CDqw8hFVA7+;rhJ5wKKQ&&0s&9RuIAvRIvttI0i}Ppta8We7CpKo(WfRJ zHk(^=Qq#^#t|Lg0^+F_@uRU@R6ljsLXaZ-I7csg}Wa4M%h2rO`so!*|w=)eWXB)@O zAij4nA#YNP1)~)=ed|bMy_9=FpCzV%MjY8`khMthA}N7LGKEtG&z)Z;KFvwVmulJ+TGog9^T%@wqd>n0WVP{gY6>it8O7&pPmk zE|*+zV2jM}JuQ7smd#Cb3`R$-nLOdcDA1&T*xA`)kpIzkF@1y|kxIznuBt%_V`$@% zYlWe7%GCYI*&tc>LbZy`*%G){9*YtIK3pj34dXV+0nJa%E5Gxz%(78V71i0D`fVMX zS3MMjqm9QmdcBN_BYr$R!10sIv?IoHV6vgJZ`WUD(eTrlb||ypmx*;QDv)p8ELFR{ zQFvic23|RCTc#2PT;Z|oXo@s;Gnm?pxs$Le)LTMFF<6olICIp1Bxa}_yhy^nSxoyf6$&D}K+>ANaMHg&0 z3rX1!0LFnNESmxeJfeAX&+%hM;h6H^fNL8vCa~X}=r4(Q)PjZL^U3(D_+~<+JM(5C z)`Ta9jP_-~?}j+d!7#$Stv637!-A zxEGRZt48Pke#k6;i73DJVB44^2 z)%Mo0-gYDaN4wnAY~EH7x*fWdIAne zPi>;8Tg!X;lZ_1v7-t*3E9He0G}x<(YVH>1Gd`J{$v=PomBkD+Nt79dUEk8oe3+u)06e* zpdc-0&m@!I^lzTV#KaK1Hds1#-1Lq9V)4{qDk9mKb((ZHHsU4?UijSuTfH+x~^Gc*73=3|kvk9B&S*qK7g zm|v%fNAHj~<-Zl8zrYNT%hA6}{dA&5BP3XHmR5TypM2{f`k}iE6{5__n$u)4jp}{! zA!(gG@i8&k0q8NHUvAtQv+E(=m<4_9lg5qqFH9to_+R@9)^`rs_4F~#y6^w|S?z-d zv{ZTlL`Ug=i~|y7GT6l^E1vb&WPb0LQ`h_sKSUvOhEoi|&)B(@C8L?mi2jzt(c>is zhbooqBrgZk<-V=h8Tl_@JvpZ#-9qx|l}X0IZYy`=?7yBH`?GrqUcOilrxLvI3)Ix~ z3YVoI{@db7kV7E-s>(mbgNkH!s9jrR=wKI-|2uo3DF>eAh#L1iR(KxCZC~=^JGGT& zMp5sLkNos)nMoVjzZmVdZ1tY8REhj7jlae!?FoPjDE zkjlzXh(a3SZV?BN3t{A)b6zs^TpSEeMC^}7xwhQyk3 zhoQ3Y($9{-*NuMBt5@XQQ4@s~M|89}o|Mx>#KcInw0rwMa!Cxm2zS%op0ru1A`IAL zfA5-8RW=Oc_L>j2emYb^zh6`AM=&AR6){-Z&ZHLyzX`Qgn%-vc|J2`Jt(FTFGCWnU-e+d zRE++mxG?8ah8=Fb5DBjXdZbi(=4-8J01fzEA~1J9U`?DC!;hVJceeBy8JSx&XYCCd z35~lg?ci|87? z9-rXm@pW`ZTp#OAiP1b2gAszJ&L#IkyVm@6f09~gR9Ry5#B*Vxa{JC4XA9~iSjLXP zc4^6Fm3cU3Z@uL#`N=Ay9oVjz%1pg&`B}_V?=HLb_N|oMbJX+_eVozOPnTeMQ9Nv@ z6Ie7uLDZjP&u64#rrkA4$Q)|@%mlrqrR?TALN5}bc(0HQ9|rv7{_Z3u)KN6US0jri z2)<5lTh^4V25>$p+uk;;?B%CCmQ?ZqpP1&E4ldmelTfburCGxfxRU>K7K}vDzEW*8 zbb0vwGM|niVA&9zd!F8(zFJdq0HP$LPi^L?A?sMAZ{r>-eD!nu^B{Xqb~sM?RwMN2 z_p>vj=-yDA5e-bMhLSR<;E~%8T{G+t#cXGUj!+rnIhxSj+F6?J5o6$)0-8ki*F58; z6_d-@A!l&?TxC5LHE;Gn!x2|S#b7EydWpMP&`X$2g;>?yKc}5!gB{~mJC)Ae@dS!- z;O&+~6ecFG=TfdxY`^n>9eplX=u=asWVL1<94du8*JnnOh4Yoq%9Gg2gX%GG?2B2$ zXRY4y>S_41HYarCbm@v1tCX3J-u>bCjIqIsk!nXn3i!on*BA57_k)c8HgayiC9VG1 z!C3XWTc7SF?|kfg`Lt~i=*Bc6E0XdoMj4N6%S3Ixp4gH`a$X0W#``Ee2)#!@_s=nk z$eYgOeD5FEL4uIFJ5hQ-9aJ*_)|4OEmpGg%0f*=3;@5(M=Ma$zyb}1cp`aeD_A?Ce z(R!&#S%?7O#PEdP;!`WDAc4DR2XDE7u-tZqyS(@t86fB^B!(m{<VT9&xJ<>Tkw{OZYTPYC;uB_kA(5|ld-VW z!vTqYS$7vUiien!^%ovP1g^pwAZ)+HQk^R@1Z_vYH}@oz(6UC!Y2+HhH7@Ms8n(UI#bV=XO*qU6Ubza}#pE$ucvO zVP~J3H?aD#6EMR*_owqdftUIPo7L~QDON0v(GRBq$p+xA#WtCx|t%W@S&0TezwK3+opS0PqP_A1JDF9uK!T(U7>Q7&L zvVjz&B1j{6|JbEeRgvQ%Tj^)&l~;dU>E`IEXHl4U=X!#6wvp?a?v!?s%ia_V%-0@a zGx_K#hZKWz03XEcR*+Fpf0D<{Oy8}JHv*3W=U<_C4sXMU2xT~H9{J{dexeoi_mJ1l zYb&2aaeszx3KZOK6cqnx>>t!obc;R;Bz-``dQjzt{3FE7&CU6tggIh8 zX)(XLYW&wj5kMsiA~2t35WQr=;X7JdUV#lu{B*qoflbV@-pfxCrX^!*y9<&S4_M*q zi~dLElBm=U$RGprpYCk3H+ue70i95}Bp=duM*r6q6X4Ggoyu0jC~}{0F>nwd41R~) zz{KQfpGmN)qfWN4ptg{q5o;5e=FKliGPBP?0M*Efx@SuuXss#w&>DXTVNhkjdHU;^BK0 z?jUBN-@uA6BL2aN?t)wBo3yCbhUm z*FXxWhRg8Zgu6vKka-GH48Z{J-^&gX%_R+^JCBG^pq~&O^rt*n{_YlfucOY{?FH^o zjM%N&!wcdo2dO5EzSU4dMvMv℘w+gR+u}BLLq(5&rw?s{5o5MVS2FZ?Led$L&r- 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�(A8ni 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 @Ei=? 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 QwGgn$ORGp#OS}sCACSsxJOBUy diff --git a/secondary.py b/secondary.py index 3de81bf..542bf7a 100644 --- a/secondary.py +++ b/secondary.py @@ -1,41 +1,36 @@ # coding=utf-8 -from __future__ import absolute_import, division, print_function, unicode_literals from boot_config import * from boot_config import _ import re import webbrowser from functools import partial +from ntpath import normpath from os.path import join, basename, splitext, isfile -from pprint import pprint - -if QT4: # ___ ______________ DEPENDENCIES __________________________ - from PySide.QtCore import Qt, Slot, QObject, Signal, QSize, QPoint, QEvent - from PySide.QtGui import (QApplication, QMessageBox, QIcon, QFileDialog, QLineEdit, - QDialog, QWidget, QMovie, QFont, QMenu, QAction, QCursor, - QTableWidget, QCheckBox, QToolButton, QActionGroup, - QTableWidgetItem) -elif QT5: - from PySide2.QtCore import QObject, Qt, Signal, QPoint, Slot, QSize, QEvent - from PySide2.QtGui import QFont, QMovie, QIcon, QCursor + +if QT5: # ___ ______________ DEPENDENCIES __________________________ + from PySide2.QtCore import (QObject, Qt, Signal, QPoint, Slot, QSize, QEvent, QRect, + QTimer) + from PySide2.QtGui import (QFont, QMovie, QIcon, QCursor, QPalette, QColor, QPixmap, + QPainter, QPen) from PySide2.QtWidgets import (QTableWidgetItem, QTableWidget, QMessageBox, QLineEdit, QApplication, QWidget, QDialog, QFileDialog, - QActionGroup, QMenu, QAction, QToolButton, QCheckBox) + QStyleFactory, QActionGroup, QMenu, QAction, + QToolButton, QCheckBox) else: # Qt6 - from PySide6.QtCore import QObject, Qt, Signal, QEvent, QPoint, Slot, QSize - from PySide6.QtGui import QFont, QActionGroup, QAction, QCursor, QMovie, QIcon + from PySide6.QtCore import (QObject, Qt, Signal, QEvent, QPoint, Slot, QSize, QRect, + QTimer) + from PySide6.QtGui import (QFont, QActionGroup, QAction, QCursor, QMovie, QIcon, + QPalette, QColor, QPixmap, QPainter, QPen) from PySide6.QtWidgets import (QTableWidgetItem, QTableWidget, QApplication, QLineEdit, QToolButton, QWidget, QMenu, QFileDialog, - QDialog, QMessageBox, QCheckBox) - -if PYTHON2: # ___ __________ PYTHON 2/3 COMPATIBILITY ______________ - from distutils.version import LooseVersion as version_parse -else: - from packaging.version import parse as version_parse - + QDialog, QMessageBox, QCheckBox, QStyleFactory) import requests from bs4 import BeautifulSoup +from packaging.version import parse as version_parse from slppu import slppu as lua # https://github.com/noembryo/slppu +__author__ = "noEmbryo" + def decode_data(path): """ Converts a lua table to a Python dict @@ -105,12 +100,11 @@ def get_book_text(title, authors, highlights, format_, line_break, space, text): elif format_ == ONE_TEXT: name = title if authors: - name = "{} - {}".format(authors, title) + name = f"{authors} - {title}" line = "-" * 80 text += line + nl + name + nl + line + nl - highlights = [i[3] + space + i[0] + line_break + - ("[{}]{}".format(i[4], nl) if i[4] else "") + - i[2] + i[1] for i in highlights] + highlights = [i[3] + space + i[0] + line_break + (f"[{i[4]}]{nl}" if i[4] else "") + + i[2] + i[1] for i in highlights] text += (nl * 2).join(highlights) + nl * 2 elif format_ == ONE_CSV: for high in highlights: @@ -121,7 +115,7 @@ def get_book_text(title, authors, highlights, format_, line_break, space, text): # data = {k.encode("utf8"): v.encode("utf8") for k, v in data.items()} text += get_csv_row(data) + "\n" elif format_ == ONE_MD: - text += "\n---\n## {} \n##### {} \n---\n".format(title, authors) + text += f"\n---\n## {title} \n##### {authors} \n---\n" highs = [] for i in highlights: comment = i[1].replace(nl, " " + nl) @@ -129,7 +123,7 @@ def get_book_text(title, authors, highlights, format_, line_break, space, text): comment = " " + comment chapter = i[4] if chapter: - chapter = "***{0}***{1}{1}".format(chapter, nl).replace(nl, " " + nl) + chapter = f"***{chapter}***{nl}{nl}".replace(nl, " " + nl) high = i[2].replace(nl, " " + nl) h = ("*" + i[3] + space + i[0] + line_break + chapter + high + comment + " \n  \n") @@ -147,7 +141,7 @@ def save_file(title, authors, highlights, path, format_, line_break, space, sort encoding = "utf-8" name = title if authors: - name = "{} - {}".format(authors, title) + name = f"{authors} - {title}" if format_ == MANY_TEXT: ext = ".txt" line = "-" * 80 @@ -161,7 +155,7 @@ def save_file(title, authors, highlights, path, format_, line_break, space, sort encoding = "utf-8-sig" elif format_ == MANY_MD: ext = ".md" - text = "\n---\n## {} \n##### {} \n---\n".format(title, authors) + text = f"\n---\n## {title} \n##### {authors} \n---\n" filename = join(path, sanitize_filename(name)) if _("NO TITLE FOUND") in title: # don't overwrite unknown title files @@ -182,7 +176,7 @@ def save_file(title, authors, highlights, path, format_, line_break, space, sort "chapter": chapter} elif format_ == MANY_TEXT: text += (page_text + space + date_text + line_break + - ("[{}]{}".format(chapter, nl) if chapter else "") + + (f"[{chapter}]{nl}" if chapter else "") + high_text + high_comment) text += 2 * nl elif format_ == MANY_CSV: @@ -196,7 +190,7 @@ def save_file(title, authors, highlights, path, format_, line_break, space, sort if high_comment: high_comment = " " + high_comment if chapter: - chapter = "***{0}***{1}{1}".format(chapter, nl).replace(nl, " " + nl) + chapter = f"***{chapter}***{nl}{nl}".replace(nl, " " + nl) text += ("*" + page_text + space + date_text + line_break + chapter + high_text + high_comment + " \n  \n\n").replace("-", "\\-") @@ -210,7 +204,8 @@ def save_file(title, authors, highlights, path, format_, line_break, space, sort "get_book_text", "save_file", "XTableWidgetIntItem", "XTableWidgetPercentItem", "XTableWidgetTitleItem", "DropTableWidget", "XMessageBox", "About", "AutoInfo", "ToolBar", "TextDialog", "Status", "LogStream", "Scanner", "HighlightScanner", - "ReLoader", "DBLoader", "XToolButton", "Filter") + "ReLoader", "DBLoader", "XToolButton", "Filter", "XThemes", "XIconGlyph", + "SyncGroup", "SyncItem", "XTableWidget") # ___ _______________________ SUBCLASSING ___________________________ @@ -296,6 +291,76 @@ def dropEvent(self, event): return False +class XTableWidget(QTableWidget): + """ QTableWidget with support for drag and drop move of rows that contain widgets + """ + + def __init__(self, *args, **kwargs): + super(XTableWidget, self).__init__(*args, **kwargs) + self.viewport().setAcceptDrops(True) + self.selection = self.selectionModel() + self.base = None + + def dropEvent(self, event): + if not event.isAccepted() and event.source() == self: + drop_row = self.drop_on(event) + # rows = sorted(set(i.row() for i in self.selectedItems())) + rows = sorted(set(i.row() for i in self.selection.selectedRows())) + rows_to_move = [] + for row in rows: + items = dict() + for col in range(self.columnCount()): + # get the widget or item of current cell + widget = self.cellWidget(row, col) + if isinstance(widget, type(None)): # a normal QTableWidgetItem + items[col] = {"kind": "QTableWidgetItem", + "item": QTableWidgetItem(self.item(row, col))} + else: # another kind of widget. + # So we catch the widget's unique characteristics + items[col] = {"kind": "QWidget", "item": widget.data} + rows_to_move.append(items) + + for row in reversed(rows): + self.removeRow(row) + # if row < drop_row: + # drop_row -= 1 + for row, data in enumerate(rows_to_move): + row += drop_row + self.insertRow(row) + + for col, info in data.items(): + if info["kind"] == "QTableWidgetItem": + # for QTableWidgetItem we can re-create the item directly + self.setItem(row, col, info["item"]) + else: # for other widgets we call + # the parent's callback function to get them + widget = self.base.create_sync_widget(info["item"]) + widget.idx = row + self.base.sync_table.setRowHeight(row, widget.sizeHint().height()) + self.setCellWidget(row, col, widget) + + self.base.update_sync_groups() + event.accept() + super(XTableWidget, self).dropEvent(event) + + def drop_on(self, event): + index = self.indexAt(event.pos()) + if not index.isValid(): + return self.rowCount() - 1 + return index.row() + 1 if self.is_below(event.pos(), index) else index.row() + + def is_below(self, pos, index): + rect = self.visualRect(index) + margin = 2 + if pos.y() - rect.top() < margin: + return False + elif rect.bottom() - pos.y() < margin: + return True + # noinspection PyTypeChecker + return rect.contains(pos, True) and not (int(self.model().flags( + index)) & Qt.ItemIsDropEnabled) and pos.y() >= rect.center().y() + + class XMessageBox(QMessageBox): """ A QMessageBox with a QCheckBox """ @@ -353,7 +418,7 @@ def add_to_layout(self, widget): :param widget: The widget to be added """ # noinspection PyArgumentList - self.layout().addWidget(widget, 1, 1 if PYTHON2 else 2) + self.layout().addWidget(widget, 1, 2) class XToolButton(QToolButton): @@ -396,7 +461,7 @@ def write(self, text): class Scanner(QObject): - found = Signal(unicode) + found = Signal(str) finished = Signal() def __init__(self, path): @@ -404,10 +469,6 @@ def __init__(self, path): self.path = path def process(self): - self.start_scan() - self.finished.emit() - - def start_scan(self): try: for dir_path, dirs, files in os.walk(self.path): if dir_path.lower().endswith(".sdr"): # a book's metadata folder @@ -425,10 +486,11 @@ def start_scan(self): continue except UnicodeDecodeError: # os.walk error pass + self.finished.emit() class ReLoader(QObject): - found = Signal(unicode) + found = Signal(str) finished = Signal() def __init__(self, paths): @@ -436,13 +498,14 @@ def __init__(self, paths): self.paths = paths def process(self): + # print("Loading data from files") for path in self.paths: self.found.emit(path) self.finished.emit() class DBLoader(QObject): - found = Signal(unicode, dict, unicode) + found = Signal(str, dict, str) finished = Signal() def __init__(self, books): @@ -468,20 +531,319 @@ def process(self): for row in range(self.base.file_table.rowCount()): data = self.base.file_table.item(row, TITLE).data(Qt.UserRole) path = self.base.file_table.item(row, TYPE).data(Qt.UserRole)[0] - self.get_book_highlights(data, path) + meta_path = self.base.file_table.item(row, PATH).data(0) + highlights = self.base.get_highlights_from_data(data, path, meta_path) + for highlight in highlights: + self.found.emit(highlight) self.finished.emit() - def get_book_highlights(self, data, path): - """ Finds all the highlights from a book - :type data: dict - :param data: The book data (converted from the lua file) - :type path: str|unicode - :param path: The book path +class XThemes(QObject): + """ Dark and light theme palettes + """ + + def __init__(self, parent=None): + super(XThemes, self).__init__(parent) + + # noinspection PyArgumentList + self.app = QApplication.instance() + self.def_style = str(self.app.style()) + # noinspection PyArgumentList + themes = QStyleFactory.keys() + if "Fusion" in themes: + self.app_style = "Fusion" + elif "Plastique" in themes: + self.app_style = "Plastique" + else: + self.app_style = self.def_style + self.def_colors = self.get_current() + # self.def_palette = self.app.palette() + + def dark(self): + """ Apply a dark theme """ - highlights = self.base.get_highlights_from_data(data, path) - for highlight in highlights: - self.found.emit(highlight) + + dark_palette = QPalette() + + # base + text = 250 + dark_palette.setColor(QPalette.WindowText, QColor(text, text, text)) + dark_palette.setColor(QPalette.Button, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.Light, QColor(text, text, text)) + dark_palette.setColor(QPalette.Midlight, QColor(90, 90, 90)) + dark_palette.setColor(QPalette.Dark, QColor(35, 35, 35)) + dark_palette.setColor(QPalette.Text, QColor(text, text, text)) + dark_palette.setColor(QPalette.BrightText, QColor(text, text, text)) + dark_palette.setColor(QPalette.ButtonText, QColor(text, text, text)) + dark_palette.setColor(QPalette.Base, QColor(25, 25, 25)) + # dark_palette.setColor(QPalette.Text, QColor(180, 180, 180)) + # dark_palette.setColor(QPalette.BrightText, QColor(180, 180, 180)) + # dark_palette.setColor(QPalette.ButtonText, QColor(180, 180, 180)) + # dark_palette.setColor(QPalette.Base, QColor(42, 42, 42)) + dark_palette.setColor(QPalette.Window, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.Shadow, QColor(10, 10, 10)) + # dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218)) + dark_palette.setColor(QPalette.Highlight, QColor(20, 50, 80)) + dark_palette.setColor(QPalette.HighlightedText, QColor(text, text, text)) + dark_palette.setColor(QPalette.Link, QColor(56, 252, 196)) + dark_palette.setColor(QPalette.AlternateBase, QColor(66, 66, 66)) + dark_palette.setColor(QPalette.ToolTipBase, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.ToolTipText, QColor(text, text, text)) + dark_palette.setColor(QPalette.LinkVisited, QColor(80, 80, 80)) + + # disabled + gray = QColor(100, 100, 100) + dark_palette.setColor(QPalette.Disabled, QPalette.WindowText, gray) + dark_palette.setColor(QPalette.Disabled, QPalette.Text, gray) + dark_palette.setColor(QPalette.Disabled, QPalette.ButtonText, gray) + dark_palette.setColor(QPalette.Disabled, QPalette.HighlightedText, gray) + dark_palette.setColor(QPalette.Disabled, QPalette.Highlight, + QColor(80, 80, 80)) + + self.app.style().unpolish(self.app) + self.app.setPalette(dark_palette) + # self.app.setStyle("Fusion") + self.app.setStyle(self.app_style) + + def light(self): + """ Apply a light theme + """ + + light_palette = QPalette() + + # base + light_palette.setColor(QPalette.WindowText, QColor(0, 0, 0)) + light_palette.setColor(QPalette.Button, QColor(240, 240, 240)) + # light_palette.setColor(QPalette.Light, QColor(180, 180, 180)) + # light_palette.setColor(QPalette.Midlight, QColor(200, 200, 200)) + # light_palette.setColor(QPalette.Dark, QColor(225, 225, 225)) + light_palette.setColor(QPalette.Dark, QColor(180, 180, 180)) + light_palette.setColor(QPalette.Midlight, QColor(200, 200, 200)) + light_palette.setColor(QPalette.Light, QColor(250, 250, 250)) + light_palette.setColor(QPalette.Text, QColor(0, 0, 0)) + light_palette.setColor(QPalette.BrightText, QColor(0, 0, 0)) + light_palette.setColor(QPalette.ButtonText, QColor(0, 0, 0)) + light_palette.setColor(QPalette.Base, QColor(237, 237, 237)) + light_palette.setColor(QPalette.Window, QColor(240, 240, 240)) + light_palette.setColor(QPalette.Shadow, QColor(20, 20, 20)) + # light_palette.setColor(QPalette.Highlight, QColor(76, 163, 224)) + light_palette.setColor(QPalette.Highlight, QColor(200, 230, 255)) + light_palette.setColor(QPalette.HighlightedText, QColor(0, 0, 0)) + light_palette.setColor(QPalette.Link, QColor(0, 162, 232)) + light_palette.setColor(QPalette.AlternateBase, QColor(225, 225, 225)) + light_palette.setColor(QPalette.ToolTipBase, QColor(240, 240, 240)) + light_palette.setColor(QPalette.ToolTipText, QColor(0, 0, 0)) + light_palette.setColor(QPalette.LinkVisited, QColor(222, 222, 222)) + + # disabled + light_palette.setColor(QPalette.Disabled, QPalette.WindowText, + QColor(115, 115, 115)) + light_palette.setColor(QPalette.Disabled, QPalette.Text, + QColor(115, 115, 115)) + light_palette.setColor(QPalette.Disabled, QPalette.ButtonText, + QColor(115, 115, 115)) + light_palette.setColor(QPalette.Disabled, QPalette.Highlight, + QColor(190, 190, 190)) + light_palette.setColor(QPalette.Disabled, QPalette.HighlightedText, + QColor(115, 115, 115)) + + self.app.style().unpolish(self.app) + self.app.setPalette(light_palette) + # self.app.setStyle("Fusion") + self.app.setStyle(self.app_style) + + def normal(self): + """ Apply the normal theme + """ + normal_palette = QPalette() + + normal_palette.setColor(QPalette.WindowText, self.def_colors["WindowText"]) + normal_palette.setColor(QPalette.Button, self.def_colors["Button"]) + normal_palette.setColor(QPalette.Light, self.def_colors["Light"]) + normal_palette.setColor(QPalette.Midlight, self.def_colors["Midlight"]) + normal_palette.setColor(QPalette.Dark, self.def_colors["Dark"]) + normal_palette.setColor(QPalette.Text, self.def_colors["Text"]) + normal_palette.setColor(QPalette.BrightText, self.def_colors["BrightText"]) + normal_palette.setColor(QPalette.ButtonText, self.def_colors["ButtonText"]) + normal_palette.setColor(QPalette.Base, self.def_colors["Base"]) + normal_palette.setColor(QPalette.Window, self.def_colors["Window"]) + normal_palette.setColor(QPalette.Shadow, self.def_colors["Shadow"]) + normal_palette.setColor(QPalette.Highlight, self.def_colors["Highlight"]) + normal_palette.setColor(QPalette.HighlightedText, + self.def_colors["HighlightedText"]) + normal_palette.setColor(QPalette.Link, self.def_colors["Link"]) + normal_palette.setColor(QPalette.AlternateBase, + self.def_colors["AlternateBase"]) + normal_palette.setColor(QPalette.ToolTipBase, self.def_colors["ToolTipBase"]) + normal_palette.setColor(QPalette.ToolTipText, self.def_colors["ToolTipText"]) + normal_palette.setColor(QPalette.LinkVisited, self.def_colors["LinkVisited"]) + + # # disabled + # normal_palette.setColor(QPalette.Disabled, QPalette.WindowText, + # QColor(115, 115, 115)) + # normal_palette.setColor(QPalette.Disabled, QPalette.Text, + # QColor(115, 115, 115)) + # normal_palette.setColor(QPalette.Disabled, QPalette.ButtonText, + # QColor(115, 115, 115)) + # normal_palette.setColor(QPalette.Disabled, QPalette.Highlight, + # QColor(190, 190, 190)) + # normal_palette.setColor(QPalette.Disabled, QPalette.HighlightedText, + # QColor(115, 115, 115)) + + self.app.style().unpolish(self.app.base) + self.app.setPalette(normal_palette) + # self.app.setPalette(self.def_palette) + self.app.setStyle(self.def_style) + + @staticmethod + def get_current(): + """ Return the current theme's data + """ + light_palette = QPalette() + data = {'WindowText': (light_palette.color(QPalette.WindowText)), + 'Button': (light_palette.color(QPalette.Button)), + 'Light': (light_palette.color(QPalette.Light)), + 'Midlight': (light_palette.color(QPalette.Midlight)), + 'Dark': (light_palette.color(QPalette.Dark)), + 'Text': (light_palette.color(QPalette.Text)), + 'BrightText': (light_palette.color(QPalette.BrightText)), + 'ButtonText': (light_palette.color(QPalette.ButtonText)), + 'Base': (light_palette.color(QPalette.Base)), + 'Window': (light_palette.color(QPalette.Window)), + 'Shadow': (light_palette.color(QPalette.Shadow)), + 'Highlight': (light_palette.color(QPalette.Highlight)), + 'HighlightedText': (light_palette.color(QPalette.HighlightedText)), + 'Link': (light_palette.color(QPalette.Link)), + 'AlternateBase': (light_palette.color(QPalette.AlternateBase)), + 'ToolTipBase': (light_palette.color(QPalette.ToolTipBase)), + 'ToolTipText': (light_palette.color(QPalette.ToolTipText)), + 'LinkVisited': (light_palette.color(QPalette.LinkVisited))} + return data + + +class XIconGlyph(QObject): + """ A Font char to QIcon converter + + * Usage in Base: + fdb = QFontDatabase() + fdb.addApplicationFont(":/stuff/font.ttf") # add a custom font or use existing + # pprint(fdb.families()) + + self.font_ico = XIconGlyph(self, glyph=None) + + ico = self.font_ico.get_icon({"char": "✓", + "size": (32, 32), + "size_ratio": 1.2, + "offset": (0, -2), + "family": "XFont", + "color": "#FF0000", + "active": "orange", + "hover": (160, 50, 255), + }) + self.tool_btn.setIcon(ico) + """ + + def __init__(self, parent, glyph=None): + super(XIconGlyph, self).__init__(parent) + self.char = "" + self.family = "" + self.color = parent.palette().text().color().name() # use the default + self.active = None + self.hover = None + self.disabled = parent.palette().dark().color().name() + self.icon_size = 16, 16 + self.size_ratio = 1 + self.offset = 0, 0 + self.glyph = glyph + if glyph: + self._parse_glyph(glyph) + + def _parse_glyph(self, glyph): + """ Set the glyph options + + :type glyph: dict + """ + if self.glyph: + self.glyph.update(glyph) + + family = glyph.get("family") + if family: + self.family = family + char = glyph.get("char") + if char: + self.char = char + icon_size = glyph.get("size") + if icon_size: + self.icon_size = icon_size + offset = glyph.get("offset") + if offset: + self.offset = offset + size_ratio = glyph.get("size_ratio") + if size_ratio: + self.size_ratio = size_ratio + active = glyph.get("active") + if active: + self.active = active + hover = glyph.get("hover") + if hover: + self.hover = hover + color = glyph.get("color") + if color: + self.color = color + disabled = glyph.get("disabled") + if disabled: + self.disabled = disabled + + def _get_char_pixmap(self, color): + """ Create an icon from a font character + + :type color: str|tuple + :param color: The color of the icon + :return: QPixmap + """ + if isinstance(color, tuple): + color = QColor(*color) + else: + color = QColor(color) + font = QFont() + if self.family: + font.setFamily(self.family) + font.setPixelSize(self.icon_size[1] * self.size_ratio) + + pixmap = QPixmap(*self.icon_size) + pixmap.fill(QColor(0, 0, 0, 0)) # fill with transparency + + painter = QPainter(pixmap) + painter.setFont(font) + pen = QPen() + pen.setColor(color) + painter.setPen(pen) + painter.drawText(QRect(QPoint(*self.offset), QSize(*self.icon_size)), + Qt.AlignCenter | Qt.AlignVCenter, self.char) + painter.end() + return pixmap + + def get_icon(self, glyph=None): + """ Get the icon from the glyph + + :type glyph: dict + :return: QIcon + """ + if glyph: + self._parse_glyph(glyph) + + icon = QIcon() + icon.addPixmap(self._get_char_pixmap(self.color), QIcon.Normal, QIcon.Off) + if self.active: # the checkable down state icon + icon.addPixmap(self._get_char_pixmap(self.active), + QIcon.Active, QIcon.On) + if self.hover: # the mouse hover state icon + icon.addPixmap(self._get_char_pixmap(self.hover), + QIcon.Active, QIcon.Off) + if self.disabled: # the disabled state icon + icon.addPixmap(self._get_char_pixmap(self.disabled), + QIcon.Disabled, QIcon.Off) + return icon # ___ _______________________ GUI STUFF _____________________________ @@ -492,6 +854,8 @@ def get_book_highlights(self, data, path): from gui_status import Ui_Status from gui_edit import Ui_TextDialog from gui_filter import Ui_Filter +from gui_sync_group import Ui_SyncGroup +from gui_sync_item import Ui_SyncItem class ToolBar(QWidget, Ui_ToolBar): @@ -505,20 +869,22 @@ def __init__(self, parent=None): self.setupUi(self) self.base = parent - self.buttons = (self.check_btn, self.scan_btn, self.export_btn, self.open_btn, - self.merge_btn, self.delete_btn, self.clear_btn, self.about_btn, - self.books_view_btn, self.high_view_btn, self.filter_btn) - self.size_menu = self.create_size_menu() - self.db_menu = self.create_db_menu() + self.buttons = (self.scan_btn, self.export_btn, self.open_btn, self.merge_btn, + self.delete_btn, self.clear_btn, self.about_btn, self.filter_btn, + self.books_view_btn, self.high_view_btn, self.sync_view_btn, + self.add_btn) + + self.size_menu = QMenu(self) + # self.size_menu.aboutToShow.connect(self.create_size_menu) + + self.db_menu = QMenu() + self.db_menu.aboutToShow.connect(self.create_db_menu) self.db_btn.setMenu(self.db_menu) - for btn in [self.loaded_btn, self.db_btn, - self.books_view_btn, self.high_view_btn]: + for btn in [self.books_view_btn, self.high_view_btn, self.sync_view_btn, + self.loaded_btn, self.db_btn]: btn.clicked.connect(self.change_view) - self.check_btn.clicked.connect(parent.on_check_btn) - self.check_btn.hide() - @Slot(QPoint) def on_tool_frame_customContextMenuRequested(self, point): """ The Toolbar is right-clicked @@ -526,25 +892,20 @@ def on_tool_frame_customContextMenuRequested(self, point): :type point: QPoint :param point: The point where the right-click happened """ - self.size_menu.exec_(self.tool_frame.mapToGlobal(point)) - - def create_size_menu(self): - """ Create the toolbar's buttons size menu - """ - menu = QMenu(self) + self.size_menu.clear() group = QActionGroup(self) sizes = (_("Tiny"), 16), (_("Small"), 32), (_("Medium"), 48), (_("Big"), 64) for name, size in sizes: - action = QAction(name, menu) + action = QAction(name, self.size_menu) action.setCheckable(True) if size == self.base.toolbar_size: action.setChecked(True) action.triggered.connect(partial(self.set_btn_size, size)) group.addAction(action) - menu.addAction(action) + self.size_menu.addAction(action) if QT6: # QT6 requires exec() instead of exec_() - menu.exec_ = getattr(menu, "exec") - return menu + self.size_menu.exec_ = getattr(self.size_menu, "exec") + self.size_menu.exec_(self.tool_frame.mapToGlobal(point)) def set_btn_size(self, size): """ Changes the Toolbar's icons size @@ -559,6 +920,7 @@ def set_btn_size(self, size): for btn in self.buttons: btn.setMinimumWidth(size + 10) btn.setIconSize(button_size) + # btn.setStyleSheet("QToolButton:disabled {background-color: rgb(0, 0, 0);}") for btn in [self.loaded_btn, self.db_btn]: # btn.setMinimumWidth(size + 10) @@ -566,6 +928,9 @@ def set_btn_size(self, size): # noinspection PyArgumentList QApplication.processEvents() + if self.base.theme in [THEME_NONE_NEW, THEME_DARK_NEW, THEME_LIGHT_NEW]: + self.base.set_new_icons(menus=False) + @Slot() def on_scan_btn_clicked(self): """ The `Scan Directory` button is pressed @@ -606,6 +971,19 @@ def on_open_btn_clicked(self): data = self.base.high_table.item(idx.row(), HIGHLIGHT_H).data(Qt.UserRole) self.base.open_file(data["path"]) + @Slot() + def on_add_btn_clicked(self): + """ The `Add` sync group button is pressed + """ + if self.base.current_view == SYNC_VIEW: + info = {"title": "", + "sync_pos": False, + "merge": False, + "sync_db": True, + "items": [{"path": "", "data": {}}], + "enabled": True} + self.base.create_sync_row(info) + @Slot(bool) def on_filter_btn_toggled(self, state): """ The `Find` button is pressed @@ -623,9 +1001,27 @@ def on_filter_btn_toggled(self, state): def on_merge_btn_clicked(self): """ The `Merge` button is pressed """ + if self.base.current_view == SYNC_VIEW: + if self.base.merge_warning_stop(): + return + text = _("Synchronize all active Sync groups?") + popup = self.base.popup(_("Sync"), text, icon=QMessageBox.Question, + buttons=2) + if popup.buttonRole(popup.clickedButton()) == QMessageBox.AcceptRole: + changed_total = 0 + for idx in range(self.base.sync_table.rowCount()): + group = self.base.sync_table.cellWidget(idx, 0) + if group.power_btn.isChecked(): + changed = self.base.synchronize_group(group, multi=True) + if changed: + changed_total += 1 + text = _(f"Synchronization process completed\n" + f"{changed_total} groups were synchronized") + self.base.popup(_("Information"), text, QMessageBox.Information) + return data = [self.base.file_table.item(idx.row(), idx.column()).data(Qt.UserRole) for idx in self.base.sel_indexes] - if self.base.same_cre_version(data): + if self.base.same_cre_version(*data): self.base.on_merge_highlights() else: self.base.wrong_cre_version() @@ -634,18 +1030,31 @@ def on_merge_btn_clicked(self): def on_delete_btn_clicked(self): """ The `Delete` button is pressed """ - self.base.delete_actions(0) + if self.base.current_view == BOOKS_VIEW: + # self.base.delete_actions(0) + if not self.base.db_mode: + self.delete_btn.showMenu() + else: + self.base.delete_actions(0) + elif self.base.current_view == HIGHLIGHTS_VIEW: + self.base.on_delete_highlights() + elif self.base.current_view == SYNC_VIEW: + for index in sorted(self.base.sel_sync_view)[::-1]: + row = index.row() + del self.base.sync_groups[row] + self.base.sync_table.model().removeRow(row) + self.base.update_sync_groups() @Slot() def on_clear_btn_clicked(self): """ The `Clear List` button is pressed """ - if self.base.current_view == HIGHLIGHTS_VIEW: - (self.base.high_table.model() # clear Books view too - .removeRows(0, self.base.high_table.rowCount())) + if self.base.current_view == SYNC_VIEW: + return self.base.loaded_paths.clear() self.base.reload_highlights = True self.base.file_table.model().removeRows(0, self.base.file_table.rowCount()) + self.base.high_table.model().removeRows(0, self.base.high_table.rowCount()) self.activate_buttons() @Slot() @@ -658,44 +1067,52 @@ def on_db_btn_right_clicked(self): def create_db_menu(self): """ Create the database menu """ - menu = QMenu(self) - - action = QAction(_("Create new database"), menu) + self.db_menu.clear() + action = QAction(_("Create new database"), self.db_menu) action.setIcon(self.base.ico_db_add) action.triggered.connect(partial(self.base.change_db, NEW_DB)) - menu.addAction(action) + self.db_menu.addAction(action) - action = QAction(_("Reload database"), menu) + action = QAction(_("Reload database"), self.db_menu) action.setIcon(self.base.ico_refresh) action.triggered.connect(partial(self.base.change_db, RELOAD_DB)) - menu.addAction(action) + self.db_menu.addAction(action) - action = QAction(_("Change database"), menu) + action = QAction(_("Change database"), self.db_menu) action.setIcon(self.base.ico_db_open) action.triggered.connect(partial(self.base.change_db, CHANGE_DB)) - menu.addAction(action) + self.db_menu.addAction(action) if QT6: # QT6 requires exec() instead of exec_() - menu.exec_ = getattr(menu, "exec") - return menu + self.db_menu.exec_ = getattr(self.db_menu, "exec") def change_view(self): """ Changes what is shown in the app """ - new = self.update_archived() if self.db_btn.isChecked() else self.update_loaded() + reloaded = False + if not self.sync_view_btn.isChecked(): # don't reload when coming from Sync view + reloaded = (self.update_archived() + if self.db_btn.isChecked() else self.update_loaded()) if self.books_view_btn.isChecked(): # Books view - # self.add_btn_menu(self.base.toolbar.export_btn) + self.base.current_view = BOOKS_VIEW + self.merge_btn.setToolTip(TOOLTIP_MERGE) + self.merge_btn.setStatusTip(TOOLTIP_MERGE) if self.base.sel_idx: item = self.base.file_table.item(self.base.sel_idx.row(), self.base.sel_idx.column()) self.base.on_file_table_itemClicked(item, reset=False) - else: # Highlights view - for btn in [self.base.toolbar.export_btn, self.base.toolbar.delete_btn]: - self.remove_btn_menu(btn) - if self.base.reload_highlights and not new: + elif self.high_view_btn.isChecked(): # Highlights view + self.base.current_view = HIGHLIGHTS_VIEW + if self.base.reload_highlights and not reloaded: self.base.scan_highlights_thread() + else: # Sync view + self.base.current_view = SYNC_VIEW + self.merge_btn.setToolTip(TOOLTIP_SYNC) + self.merge_btn.setStatusTip(TOOLTIP_SYNC) + if not self.base.sync_groups_loaded: + # noinspection PyTypeChecker + QTimer.singleShot(0, self.base.load_sync_groups) + self.base.sync_groups_loaded = True - self.base.current_view = (BOOKS_VIEW if self.books_view_btn.isChecked() - else HIGHLIGHTS_VIEW) self.base.views.setCurrentIndex(self.base.current_view) self.setup_buttons() self.activate_buttons() @@ -720,7 +1137,7 @@ def update_archived(self): self.base.db_mode = True self.base.reload_highlights = True self.base.read_books_from_db() - text = _("Loading {} database").format(APP_NAME) + text = _(f"Loading {APP_NAME} database") self.base.loading_thread(DBLoader, self.base.books, text) if not len(self.base.books): # no books in the db text = _('There are no books currently in the archive.\nTo add/' @@ -733,74 +1150,84 @@ def setup_buttons(self): """ Shows/Hides toolbar's buttons based on the view selected """ books_view = self.books_view_btn.isChecked() + high_view = self.high_view_btn.isChecked() + sync_view = self.sync_view_btn.isChecked() db_mode = self.db_btn.isChecked() - self.scan_btn.setVisible(not db_mode) - self.merge_btn.setVisible(books_view and not db_mode) - self.delete_btn.setVisible(books_view) - self.clear_btn.setVisible(not db_mode) + self.scan_btn.setVisible(not (db_mode or sync_view)) + self.export_btn.setVisible(not sync_view) + self.open_btn.setVisible(not sync_view) + self.add_btn.setVisible(sync_view) + self.filter_btn.setVisible(not sync_view) + self.merge_btn.setVisible(sync_view or not (db_mode or high_view)) + # self.delete_btn.setVisible(books_view or sync_view) + self.clear_btn.setVisible(not (db_mode or sync_view)) - if self.base.db_mode: - self.remove_btn_menu(self.base.toolbar.delete_btn) - else: - self.add_btn_menu(self.base.toolbar.delete_btn) - self.base.status.setVisible(books_view) + self.mode_grp.setEnabled(not sync_view) + self.base.status.show_items_btn.setVisible(books_view) + + self.set_btn_menu(self.export_btn, books_view) + self.set_btn_menu(self.merge_btn, books_view) + self.set_btn_menu(self.delete_btn, books_view and not db_mode) def activate_buttons(self): """ Enables/Disables toolbar's buttons based on selection/view """ - if self.base.high_table.isVisible(): # Highlights view + count = 0 + sync_enable = False + book_exists = False + if self.base.current_view == HIGHLIGHTS_VIEW: # Highlights view try: idx = self.base.sel_high_view[-1] except IndexError: idx = None count = self.base.high_table.rowCount() - else: + elif self.base.current_view == BOOKS_VIEW: # Books view idx = self.base.sel_idx count = self.base.file_table.rowCount() + if len(self.base.sel_indexes) == 2: # check if we can sync/merge + idx1, idx2 = self.base.sel_indexes + data1 = self.base.file_table.item(idx1.row(), + idx1.column()).data(Qt.UserRole) + path1 = self.base.file_table.item(idx1.row(), TYPE).data(Qt.UserRole)[0] + data2 = self.base.file_table.item(idx2.row(), + idx2.column()).data(Qt.UserRole) + path2 = self.base.file_table.item(idx2.row(), TYPE).data(Qt.UserRole)[0] + sync_enable = self.base.same_book(data1, data2, path1, path2) + else: # Sync view + try: + idx = self.base.sel_sync_view[-1] + except IndexError: + idx = None + sync_enable = True + if idx: row = idx.row() - if self.base.high_table.isVisible(): # Highlights view + if self.base.file_table.isVisible(): # Books view + book_exists = self.base.file_table.item(row, TYPE).data(Qt.UserRole)[1] + elif self.base.high_table.isVisible(): # Highlights view data = self.base.high_table.item(row, HIGHLIGHT_H).data(Qt.UserRole) book_exists = isfile(data["path"]) - else: - book_exists = self.base.file_table.item(row, TYPE).data(Qt.UserRole)[1] - else: - book_exists = False - self.export_btn.setEnabled(bool(idx)) + self.export_btn.setEnabled(bool(idx) and not self.base.sync_table.isVisible()) self.open_btn.setEnabled(book_exists) self.delete_btn.setEnabled(bool(idx)) self.clear_btn.setEnabled(bool(count)) - - self.merge_btn.setEnabled(False) - if len(self.base.sel_indexes) == 2: # check if we can sync/merge - idx1, idx2 = self.base.sel_indexes - data1 = self.base.file_table.item(idx1.row(), idx1.column()).data(Qt.UserRole) - path1 = self.base.file_table.item(idx1.row(), TYPE).data(Qt.UserRole)[0] - data2 = self.base.file_table.item(idx2.row(), idx2.column()).data(Qt.UserRole) - path2 = self.base.file_table.item(idx2.row(), TYPE).data(Qt.UserRole)[0] - self.merge_btn.setEnabled(self.base.same_book(data1, data2, path1, path2)) + self.merge_btn.setEnabled(sync_enable) @staticmethod - def add_btn_menu(btn): + def set_btn_menu(btn, status=True): """ Adds a menu arrow to a toolbar button :type btn: QToolButton :param btn: The button to change """ - btn.setStyleSheet("") - btn.setPopupMode(QToolButton.MenuButtonPopup) - - @staticmethod - def remove_btn_menu(btn): - """ Removes the menu arrow from a toolbar button - - :type btn: QToolButton - :param btn: The button to change - """ - btn.setStyleSheet("QToolButton::menu-indicator{width:0px;}") - btn.setPopupMode(QToolButton.DelayedPopup) + if status: + btn.setStyleSheet("") + btn.setPopupMode(QToolButton.MenuButtonPopup) + else: + btn.setStyleSheet("QToolButton::menu-indicator{width:0px;}") + btn.setPopupMode(QToolButton.DelayedPopup) @Slot() def on_about_btn_clicked(self): @@ -819,10 +1246,7 @@ def __init__(self, parent=None): """ super(Filter, self).__init__(parent) self.setupUi(self) - if QT4: # Remove the question mark widget from dialog - # noinspection PyUnresolvedReferences - self.setWindowFlags(self.windowFlags() ^ Qt.WindowContextHelpButtonHint) - self.setWindowTitle(_("Filter").format(APP_NAME)) + self.setWindowTitle(_("Filter")) self.base = parent def keyPressEvent(self, event): @@ -899,7 +1323,7 @@ def on_filter(self): else: self.base.file_table.setRowHidden(row, True) filtered += 1 - else: + elif self.base.toolbar.high_view_btn.isChecked(): row_count = self.base.high_table.rowCount() for row in range(row_count): title = self.base.high_table.item(row, TITLE_H).data(0) @@ -934,8 +1358,10 @@ def on_filter(self): else: self.base.high_table.setRowHidden(row, True) filtered += 1 - self.filtered_lbl.setText(_("Showing {}/{}").format(row_count - filtered, - row_count)) + else: + print("SYNC FILTERRRRRRRRRRRRRRRRR") + return + self.filtered_lbl.setText(_(f"Showing {row_count - filtered}/{row_count}")) @Slot() def on_clear_filter_btn_clicked(self): @@ -976,10 +1402,7 @@ def __init__(self, parent=None): """ super(About, self).__init__(parent) self.setupUi(self) - if QT4: # Remove the question mark widget from dialog - # noinspection PyUnresolvedReferences - self.setWindowFlags(self.windowFlags() ^ Qt.WindowContextHelpButtonHint) - self.setWindowTitle(_("About {}").format(APP_NAME)) + self.setWindowTitle(_(f"About {APP_NAME}")) self.base = parent @Slot() @@ -1007,24 +1430,21 @@ def check_for_updates(self): current_version = version_parse(self.base.version) if version_new > current_version: popup = self.base.popup(_("Newer version exists!"), - _("There is a newer version (v.{}) online.\n" - "Open the site to download it now?") - .format(version_new), + _(f"There is a newer version (v.{version_new}) online" + f".\nOpen the site to download it now?"), icon=QMessageBox.Information, buttons=2) if popup.clickedButton().text() == "OK": webbrowser.open("http://www.noembryo.com/apps.php?katalib") self.close() elif version_new == current_version: self.base.popup(_("No newer version exists!"), - _("{} is up to date (v.{})").format(APP_NAME, - current_version), + _(f"{APP_NAME} is up to date (v.{current_version})"), icon=QMessageBox.Information, buttons=1) elif version_new < current_version: self.base.popup(_("No newer version exists!"), - _("It seems that you are using a newer version ({0})\n" - "than the one online ({1})!").format(current_version, - version_new), - icon=QMessageBox.Question, buttons=1) + _(f"It seems that you are using a newer version " + f"({current_version})\nthan the one online " + f"({version_new})!"), icon=QMessageBox.Question, buttons=1) @staticmethod def get_online_version(): @@ -1051,30 +1471,30 @@ def create_text(self): # color = self.palette().color(QPalette.WindowText).name() # for links splash = ":/stuff/logo.png" paypal = ":/stuff/paypal.png" - info = _(""" + info = _(f"""

-

-

{3} is a utility for viewing - Koreader's +

+

{APP_NAME} is a utility for viewing + KOReader's highlights
and/or export them to simple text

-

Version {1}

+

Version {self.base.version}

Visit - {3} page at GitHub, or

+ {APP_NAME} page at GitHub, or

noEmbryo's page with more Apps and stuff...

Use it and if you like it, consider to

- PayPal Button

 

- """).format(splash, self.base.version, paypal, APP_NAME) + """) self.text_lbl.setText(info) @@ -1101,19 +1521,16 @@ class TextDialog(QDialog, Ui_TextDialog): def __init__(self, parent=None): super(TextDialog, self).__init__(parent) - if QT4: # Remove the question mark widget from dialog - # noinspection PyUnresolvedReferences - self.setWindowFlags(self.windowFlags() ^ Qt.WindowContextHelpButtonHint) self.setupUi(self) self.base = parent - self.on_ok = None + # self.on_ok = None @Slot() def on_ok_btn_clicked(self): """ The OK button is pressed """ - self.on_ok() + self.base.edit_comment_ok() class Status(QWidget, Ui_Status): @@ -1126,26 +1543,38 @@ def __init__(self, parent=None): super(Status, self).__init__(parent) self.setupUi(self) self.base = parent + self.themes = XThemes(parent) self.wait_anim = QMovie(":/stuff/wait.gif") self.anim_lbl.setMovie(self.wait_anim) self.anim_lbl.hide() + self.show_actions = [self.act_page, self.act_date, self.act_text, + self.act_chapter, self.act_comment] + for idx, act in enumerate(self.show_actions): + act.setData(idx) + act.triggered.connect(partial(self.on_show_items, act)) + self.show_menu = QMenu(self) - for i in [self.act_page, self.act_date, self.act_text, self.act_chapter, - self.act_comment]: - self.show_menu.addAction(i) - # noinspection PyUnresolvedReferences - i.triggered.connect(self.on_show_items) - i.setChecked(True) + self.show_menu.aboutToShow.connect(self.get_show_menu) + self.show_items_btn.setMenu(self.show_menu) + + def get_show_menu(self): + """ Returns the menu with the items to show + """ + self.show_menu.clear() + for idx, act in enumerate(self.show_actions): + act.setChecked(self.base.show_items[idx]) + self.show_menu.addAction(act) action = QAction(_("Date Format"), self.show_menu) - action.setIcon(QIcon(":/stuff/calendar.png")) + action.setIcon(self.base.ico_calendar) action.triggered.connect(self.set_date_format) self.show_menu.addAction(action) sort_menu = QMenu(self) - ico_sort = QIcon(":/stuff/sort.png") + sort_menu.setIcon(self.base.ico_sort) + sort_menu.setTitle(_("Sort by")) group = QActionGroup(self) action = QAction(_("Date"), sort_menu) @@ -1164,20 +1593,57 @@ def __init__(self, parent=None): group.addAction(action) sort_menu.addAction(action) - sort_menu.setIcon(ico_sort) - sort_menu.setTitle(_("Sort by")) self.show_menu.addMenu(sort_menu) - self.show_items_btn.setMenu(self.show_menu) - - def on_show_items(self): + @Slot(int) + def on_theme_box_currentIndexChanged(self, idx): + """ Selects the app's theme style + """ + if idx == THEME_NONE_OLD: + self.themes.normal() + self.base.set_old_icons() + if self.base.theme not in [THEME_NONE_OLD, THEME_NONE_NEW]: + self.no_theme_popup(idx) + return + elif idx == THEME_NONE_NEW: + self.themes.normal() + self.base.set_new_icons() + if self.base.theme not in [THEME_NONE_OLD, THEME_NONE_NEW]: + self.no_theme_popup(idx) + return + elif idx == THEME_DARK_OLD: + self.themes.dark() + self.base.set_old_icons() + elif idx == THEME_DARK_NEW: + self.themes.dark() + self.base.set_new_icons() + elif idx == THEME_LIGHT_OLD: + self.themes.light() + self.base.set_old_icons() + elif idx == THEME_LIGHT_NEW: + self.themes.light() + self.base.set_new_icons() + + self.base.theme = idx + self.base.reset_theme_colors() + + def no_theme_popup(self, idx): + self.base.theme = idx + self.base.reset_theme_colors() + self.base.popup(_("Warning"), _("The theme will be fully reset after " + "the application is restarted.")) + + def on_show_items(self, action=None): """ Show/Hide elements of the highlight info """ + if action: + act_idx = action.data() + self.base.show_items[act_idx] = action.isChecked() try: - idx = self.base.file_table.selectionModel().selectedRows()[-1] + table_idx = self.base.file_table.selectionModel().selectedRows()[-1] except IndexError: # nothing selected return - item = self.base.file_table.item(idx.row(), 0) + item = self.base.file_table.item(table_idx.row(), 0) self.base.on_file_table_itemClicked(item) def set_date_format(self): @@ -1215,6 +1681,407 @@ def animation(self, run): self.wait_anim.stop() +class SyncGroup(QWidget, Ui_SyncGroup): + + def __init__(self, parent=None): + """ Initializes the StatusBar + + :type parent: Base + """ + super(SyncGroup, self).__init__(parent) + self.setupUi(self) + self.base = parent + self.sync_items = [] + self.items_layout = self.items_frm.layout() + + self.idx = None + self.data = None + self.new_format = True + self.def_btn_icos = [] + self.buttons = [(self.power_btn, "Y"), + (self.sync_btn, "E"), + (self.refresh_btn, "Z")] + self.setup_buttons() + self.setup_icons() + + font = QFont() + font.setBold(True) + font.setPointSize(QFont.pointSize(QFont()) + 3) + self.title_lbl.setFont(font) + + power_color = self.base.palette().button().color().name() + self.css = 'QFrame#items_frm {background-color: "%s";}' + self.setStyleSheet(self.css % power_color) + + self.sync_pos_chk.stateChanged.connect(self.update_data) + self.merge_chk.stateChanged.connect(self.update_data) + self.sync_db_chk.stateChanged.connect(self.update_data) + + @Slot(QPoint) + def on_group_frm_customContextMenuRequested(self, point): + """ When the context menu of the SyncGroup is requested + + :type point: QPoint + :param point: The point of the click + """ + menu = QMenu(self) + if QT6: # QT6 requires exec() instead of exec_() + menu.exec_ = getattr(menu, "exec") + + action = QAction(_("Rename group"), menu) + action.setIcon(self.base.ico_file_edit) + action.triggered.connect(self.on_rename) + menu.addAction(action) + + action = QAction(_("Sync group"), menu) + action.setIcon(self.base.ico_files_merge) + action.triggered.connect(self.on_sync_btn_clicked) + menu.addAction(action) + + menu.addSeparator() + + action = QAction(_("Delete selected"), menu) + action.setIcon(self.base.ico_delete) + action.triggered.connect(self.base.toolbar.on_delete_btn_clicked) + menu.addAction(action) + + menu.exec_(self.mapToGlobal(point)) + + def on_rename(self): + """ Renames the SyncGroup + """ + title = self.title_lbl.text() + title = title if title else True + popup = self.base.popup(_("Rename SyncGroup"), + _("Enter the new name of the SyncGroup:"), + icon=QMessageBox.Question, buttons=2, + input_text=title, button_text=(_("OK"), _("Cancel"))) + if popup.buttonRole(popup.clickedButton()) == QMessageBox.AcceptRole: + text = popup.typed_text + self.title_lbl.setText(text) + self.data["title"] = text + self.update_data() + + def setup_buttons(self): + for btn, char in self.buttons: + self.def_btn_icos.append(btn.icon()) + size = btn.iconSize().toTuple() + btn.xig = XIconGlyph(self, {"family": "XFont", "size": size, "char": char}) + for item in self.sync_items: + item.setup_buttons() + + def setup_icons(self): + if self.base.theme in [THEME_NONE_NEW, THEME_DARK_NEW, THEME_LIGHT_NEW]: + # noinspection PyTypeChecker + QTimer.singleShot(0, self.set_new_icons) + else: + self.set_old_icons() + for item in self.sync_items: + item.setup_icons() + + # noinspection DuplicatedCode + def set_new_icons(self): + """ Get the font icons with the new color palette + """ + color = self.palette().text().color().name() + for btn, _ in self.buttons: + size = btn.iconSize().toTuple() + btn.xig.color = color + btn.setIcon(btn.xig.get_icon({"size": size})) + + def set_old_icons(self): + """ Reload the old icons + """ + for idx, item in enumerate(self.buttons): + btn = item[0] + btn.setIcon(self.def_btn_icos[idx]) + + @Slot(bool) + def on_power_btn_clicked(self, state): + """ Enables the Group + """ + if state: + power_color = self.base.palette().button().color().name() + else: + power_color = self.base.palette().dark().color().name() + self.setStyleSheet(self.css % power_color) + + self.data["enable"] = state + self.update_data() + + @Slot() + def on_refresh_btn_clicked(self, ): + """ The `Refresh` button is pressed + """ + items_paths = [i["path"] for i in self.data.get("items", [])] + for item in self.sync_items: + self.items_layout.removeWidget(item) + self.sync_items = [] + for path in items_paths: + self.add_item({"path": path}) + self.check_data() + + @Slot() + def on_sync_btn_clicked(self, ): + """ The `Sync this group` button is pressed + """ + if self.base.merge_warning_stop(): + return + self.base.synchronize_group(self) + + def add_item(self, data): + """ Adds a new sync item + + :type data: dict + :param data: The sync item data + """ + item = SyncItem(self.base) + item.group = self + self.sync_items.append(item) + item.idx = len(self.sync_items) - 1 + path = data["path"] + if path: + item.sync_path_txt.setText(path) + try: + data = decode_data(path) + except FileNotFoundError: # path doesn't exist + self.data["items"][item.idx]["data"] = {} + self.set_erroneous(item, _("Could not access the book's metadata file")) + except PermissionError: + self.set_erroneous(item, _("Could not access the book's metadata file")) + self.base.error(_(f"Could not access the book's metadata file\n{path}\n\n" + f"Merging this group will produce unpredictable " + f"results.")) + self.data["items"][item.idx]["data"] = {} + else: + self.data["items"][item.idx]["data"] = data + if not item.idx: + self.new_format = data.get("annotations") is not None + self.items_layout.addWidget(item) + + def remove_item(self, item): + """ Removes a sync item + + :type item: SyncItem + """ + del self.data["items"][item.idx] + self.items_layout.removeWidget(item) + self.sync_items.remove(item) + item.deleteLater() + for idx, item in enumerate(self.sync_items): + item.idx = idx + + def reset_group_height(self): + """ Reset the height of the group row + """ + height = self.sizeHint().height() + self.base.sync_table.setRowHeight(self.idx, height) + + def check_data(self): + """ Checks if the data is valid for syncing + """ + source = {"path:": "", "data": {}} + for idx, sync_item in enumerate(self.sync_items): + self.set_txt_normal(sync_item) + path = self.data["items"][idx]["path"] + if path and not isfile(path): # file doesn't exist + text = _("The path to the book's metadata file does not exist") + self.set_erroneous(sync_item, text) + if idx: + continue # check the next path + else: + return # missing source file + elif not path: + continue # empty item + + data = self.data["items"][idx]["data"] + if not idx: # source is the first item + source["path"] = path + source["data"] = data + if not data.get("cre_dom_version"): + text = _("The metadata file is of an older, not supported version.\n" + "No syncing is possible for this Sync group.") + self.set_erroneous(sync_item, text) + return + continue # check source with the rest + + # check if the data format is the same + data1_new = source["data"].get("annotations") is not None + try: + data2_new = data.get("annotations") is not None + except AttributeError: + self.set_erroneous(sync_item, + _("Could not access the book's metadata file")) + self.base.error(_(f"Could not access the book's metadata file\n{path}")) + continue + if (data1_new and not data2_new) or (data2_new and not data1_new): + text = _("The book's metadata files are in different format") + self.set_erroneous(sync_item, text) + continue + + # check if the book's md5 is the same + if not self.base.same_book(source["data"], data, source["path"], path): + text = _("The book file is different from the rest") + self.set_erroneous(sync_item, text) + continue + + # check if the books have the same cre version + if not self.base.same_cre_version(source["data"], data): + text = _("The metadata files were produced with a different version " + "of the reader engine") + self.set_erroneous(sync_item, text) + continue + + def set_txt_normal(self, item): + """ Sets the normal state of the item's text + + :type item: SyncItem + """ + item.ok = True + tooltip = _("The path to the book's metadata file") + item.sync_path_txt.setToolTip(tooltip) + item.sync_path_txt.setStatusTip(tooltip) + item.sync_path_txt.setStyleSheet(self.styleSheet()) + + def set_erroneous(self, item, tooltip=""): + """ Sets the erroneous state of the item + + :type item: SyncItem + """ + item.ok = False + item.sync_path_txt.setToolTip(tooltip) + item.sync_path_txt.setStatusTip(tooltip) + + if self.base.theme in (THEME_DARK_NEW, THEME_DARK_OLD): + color = "#DD0000" + else: + color = "#990000" + style = self.styleSheet() + 'QLineEdit {color: "%s";}' % color + item.sync_path_txt.setStyleSheet(style) + + def update_data(self): + """ Saves and updates the sync group data when something is changed + """ + if self.idx is None: # on first load on startup + return + data = {"title": self.title_lbl.text(), + "sync_pos": self.sync_pos_chk.isChecked(), + "merge": self.merge_chk.isChecked(), + "sync_db": self.sync_db_chk.isChecked(), + "items": self.data["items"], + "enabled": self.power_btn.isChecked() + } + self.base.sync_groups[self.idx] = data + self.data = data + self.base.save_sync_groups() + + +class SyncItem(QWidget, Ui_SyncItem): + + def __init__(self, parent=None): + """ Initializes the StatusBar + + :type parent: Base + """ + super(SyncItem, self).__init__(parent) + self.setupUi(self) + self.base = parent + self.group = SyncGroup(self.base) + self.def_btn_icos = [] + self.buttons = [(self.add_btn, "F"), + (self.del_btn, "J")] + self.setup_buttons() + self.setup_icons() + self.ok = True + + def setup_buttons(self): + for btn, char in self.buttons: + self.def_btn_icos.append(btn.icon()) + size = btn.iconSize().toTuple() + btn.xig = XIconGlyph(self, {"family": "XFont", "size": size, "char": char}) + + def setup_icons(self): + if self.base.theme in [THEME_NONE_NEW, THEME_DARK_NEW, THEME_LIGHT_NEW]: + # noinspection PyTypeChecker + QTimer.singleShot(0, self.set_new_icons) + else: + self.set_old_icons() + + # noinspection DuplicatedCode + def set_new_icons(self): + """ Get the font icons with the new color palette + """ + color = self.palette().text().color().name() + for btn, _ in self.buttons: + size = btn.iconSize().toTuple() + btn.xig.color = color + btn.setIcon(btn.xig.get_icon({"size": size})) + + def set_old_icons(self): + """ Reload the old icons + """ + for idx, item in enumerate(self.buttons): + btn = item[0] + btn.setIcon(self.def_btn_icos[idx]) + + @Slot() + def on_sync_path_btn_clicked(self, ): + """ The `Select` path button is pressed + """ + last_dir = self.base.last_dir + text = self.sync_path_txt.text().strip() + if text: + last_dir = dirname(text) + path = QFileDialog.getOpenFileName(self.base, _("Select the metadata file"), + last_dir, "metadata files (*.lua)")[0] + if path: + path = normpath(path) + self.base.last_dir = dirname(path) + for item in self.group.data["items"]: # check existence + if item["path"] == path: + self.base.popup(_("!"), + _("This metadata file already exists in the group!"),) + return + idx = self.group.sync_items.index(self) + self.group.data["items"][idx]["path"] = path + data = decode_data(path) + self.group.data["items"][idx]["data"] = data + if idx == 0: # first item + self.group.new_format = data.get("annotations") is not None + if not self.group.title_lbl.text().strip(): + title = data.get("doc_props", data.get("stats", {})).get("title", "") + self.group.title_lbl.setText(title) + self.sync_path_txt.setText(path) + self.group.update_data() + self.group.check_data() + + @Slot() + def on_add_btn_clicked(self, ): + """ Add a new item to the group + """ + first_item = self.group.sync_items.index(self) == 0 + if first_item and not self.sync_path_txt.text().strip(): # no first sync path + self.base.error(_("The first metadata file path must not be empty!")) + return + item_data = {"path": "", "data": {}} + self.group.add_item(item_data) + self.group.data["items"].append(item_data) + self.group.update_data() + # noinspection PyTypeChecker + QTimer.singleShot(200, self.group.reset_group_height) + + @Slot() + def on_del_btn_clicked(self, ): + """ Delete this item from the group + """ + if not self.idx: # the first item can't be deleted + self.base.error(_("Can't delete the first metadata file path!")) + return + self.group.remove_item(self) + self.group.update_data() + # noinspection PyTypeChecker + QTimer.singleShot(100, self.group.reset_group_height) + # if __name__ == "__main__": # with open("secondary.py", str("r")) as py_text: # import re diff --git a/slppu.py b/slppu.py index e72bb38..1ec1731 100644 --- a/slppu.py +++ b/slppu.py @@ -1,13 +1,5 @@ -from __future__ import print_function import re import sys -try: # ___ _______ PYTHON 2/3 COMPATIBILITY ________________________ - # noinspection PyCompatibility - basestring -except NameError: # python 3.x - # noinspection PyShadowingBuiltins - basestring, unicode, long = str, str, int -from future.utils import iteritems # https://github.com/noembryo/slppu @@ -30,13 +22,13 @@ def __init__(self): self.at = 0 self.len = 0 self.depth = 0 - self.space = re.compile('\s', re.M) - self.alnum = re.compile('\w', re.M) + self.space = re.compile(r'\s', re.M) + self.alnum = re.compile(r'\w', re.M) self.newline = '\n' self.tab = ' ' # or '\t' def decode(self, text): - if not text or not isinstance(text, basestring): + if not text or not isinstance(text, str): return # FIXME: only short comments removed reg = re.compile('--.*$', re.M) @@ -57,9 +49,9 @@ def __encode(self, obj): tab = self.tab newline = self.newline tp = type(obj) - if tp in [str, unicode]: + if tp == str: s += '"%s"' % obj.replace(r'"', r'\"') - elif tp in [int, float, long, complex]: + elif tp in [int, float, complex]: s += str(obj) elif tp is bool: s += str(obj).lower() @@ -68,16 +60,16 @@ def __encode(self, obj): elif tp in [list, tuple, dict]: self.depth += 1 if len(obj) == 0 or (tp is not dict and - len(filter(lambda x: type(x) in (int, float, long) or - (isinstance(x, basestring) and + len(filter(lambda x: type(x) in (int, float, str) or + (isinstance(x, str) and len(x) < 10), obj)) == len(obj)): newline = tab = '' dp = tab * self.depth s += "%s{%s" % (tab * (self.depth - 2), newline) if tp is dict: contents = [] - for k, v in iteritems(obj): - k = ('[{}]'.format(k) if type(k) in [int, float, long, complex] + for k, v in obj.items(): + k = ('[{}]'.format(k) if type(k) in [int, float, complex] else '["{}"]'.format(k)) contents.append(dp + '%s = %s' % (k, (self.__encode(v)))) s += (',%s' % newline).join(contents) @@ -161,8 +153,8 @@ def object(self): if k is not None: o[idx] = k if not numeric_keys and len([key for key in o - if isinstance(key, (str, unicode, float, - bool, tuple))]) == 0: + if isinstance(key, (str, float, bool, + tuple))]) == 0: ar = [] for key in o: ar.insert(key, o[key]) diff --git a/stuff/add.png b/stuff/add.png new file mode 100644 index 0000000000000000000000000000000000000000..388f8ffed3ed1d1a8cff3ae8b81bd0a24e891f34 GIT binary patch literal 1173 zcmV;G1Zw+ zNkl<)NpByOhTx1b-|OXV%3r3~6l(#D{lXr4gDVou&4{7x>xt^6@5@?NeF$((K4 zz9itj%7DeCWLq(Vq?+nsygrVDpYY)6NbxL}ZRL%(Xm4Uc9Tt(xQ41IJ}Iitu$Xt)kIE|an2N4W2IW_F@@vP&g4B) z`bZ!dAFyI(z{>IHp<-0f^IfFVIVUFAuQXup3DQ=|Uk-ZNN+gtyi@X#1N+8dUpRtd& z7IH7qHV|D5UxjV7x01V?qaRZIo@{@z$0<7+UvW*mOC#A*inj!P@Emee7_cAPY1@f$ ztX_!IoHvr<+&nj3iFmsrHvSsEo9^vZy0r|vA>Oo(bQ5LKFVh|qSU^&s->jf_EvNVe z$9Gd~qvjfX#2r7z%df#_d3GG+{0BHOg1ZmUHG(wd;wrS0RFNG>?p;pJq+=?>`%zvS ziI&Gi7IM`wF1(Z3B^0Zu%#$r48A4|}7Vzc$q}S8`6+T;?VaF$oeU&}UeEk%iDL$a= ze2gc*4nxVk69a9Jfn$XXjP`>8(`y6vybvom7vJ#LHjJg}1=5Y&*g)-~EY^|Er)PdV z@EEGFB{Wg?^Vlx81uQ8KSU%)TEOf>vigTa+E+*KHlw?`tUx6biBdyD$nvTaA+K;_! z`FjOP7lkbtOtu=E$+l2@5gVwPL~%ERZYOhf3|P|m@qz5SOBDae7a}@7kPEW4{mh)ycNfVD8!v*A~k$HyV zN(x7U-}sjQjbXzmoX0~?hc~}-awr+t%EvvJMfES(MfcUHp=5LPSsCZN9kmn&ppIkv za33?i#g6DZmP?)tpUeKj`YaW7Vea?8heM?Ma5x_LjbZPhncV2u17pxZ`3JEF7RMeK z8hEl_1pR_3y?A~ny)Nkc8v^D><8+qV8l0eFYshrV^ng20N8$mYi%a8AD!)FwYk5;l zAeOYSj^sH?<6Y zV&^Ej&&5yJL^2wyLicBO|Ht>A`~#I^N_mE;-xUA=03v!+SaefwW^{L9a%BJjc-kv3 nFW1Y=%Pvk%EJ)SMFG>dhHrNJO5L3!r00000NkvXXu0mjfdW$25 literal 0 HcmV?d00001 diff --git a/stuff/del.png b/stuff/del.png new file mode 100644 index 0000000000000000000000000000000000000000..9b5b793419d340198cfae370fefd6fc2d3bed5d8 GIT binary patch literal 144 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 literal 0 HcmV?d00001 diff --git a/stuff/font.ttf b/stuff/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3812d43ccc5f4936653cb6ca07bb78637fc0756a GIT binary patch literal 11412 zcmc&)33yvawLWttOR{X)lC34SELpN*E3&-FvaH0;;yRA&#wK+g)wM$s$FY@I^;%om z0Mn)=UDDD8N}-{J&=wQgLet$fr3+A?@Sx3ODNA^dwG;|r3lvOkz5k4^-30jF<9#3R zd)J=-oLTP7nKNf*&WtVzA~FNCL>;lMZQp$A(S1Zp45`HzZ>_HF&KT+^64xWXtGnfG zJ)?ivcPH|bL>WIE810|XZq%+M%36#3`GNgO4_Wa?xvLP@?wQy-np|b7Bg$TlcV68) za%fMb`0OLduOM=q9vU1yc%`xPJ46Pwr@S^4?;mstlM(G@pqx}ablr@?r8JM_v|K6O3QA2&Fk zAxhn)c}dfZXeKF~iU;p#9H~30P+Nvrf#xMylgv`VDN~%(i?{gUmWVZ_KrfQlXkHPw zQU+39S->312IfjMlL@?qa)5c1 z3(O}o&H*Er5Cb5TFVVS*jA#fYD0pBihJ6!~R2WpLPNdP#^H1#6z?T{5z;0_)gjld>0J>rzO6d z2EkuR@zn3>D%t})OnZS>OT31Lz`utQz$0`y@LGx2(J=VyX(aVKx`9T4M`;Xrqr{tN z9Q=D}0(diB0lbAKfwxM$ji$iAkCLh1()(#2@OIh{{D8ze=m7W+(m~*d=n(KudI#{B z#1GRu!QVyiO8tiJrfJ|uBz~0M4gNS?3H%sc1-yq21Mii1A6*Up<8%#hhTfApL!Y1{ zz!MTbN!NnEpRNNwK-U8wq#J;rlK5#l3jQIwG4*RYNjCu>ruPCLk@zUx4E`~?1^77K z3VcH1lXM&SS$ZGvDSChES2Rbr13x42Y5D;8&(a;hXXt~#XX!)0=OjK)cY^;M9Rq%z zKAd`;zCd>YUy%4kx*PnL=p(={(?@|XO8g2P2me+281Ucdp42btYjiL0>k?n0`@p|U z9|xYI8Q{OuCxG9O_)R(i{#*1(;J4}i)Gz22dI0zxiQlCM!GDiF1^hmJ8hDx>0{%ea zf6z(r|49!6e@Ks{UZWpL{4qTW{wMSp@Tc@R@MrV{@KuRFrzgR`Mzg?Q&{M!)(p>82 z^twdo3H-0=Y2X?9Ebuq<4Dh!Se@D-P|2;hi`~y9odX>)7=YW5d_$T^2_&4Yaz(3Oq zz`sbGr!Rv4D}4$0CVd&WKrg0#MvD?t^cC>f+z~vP#*EBNBmRK$0mCs);BC;Dm0>hy z;SY~Wm`NufKPy|8m6e@!{<9QEezr-Moo&iK=RssCj(k&&-t>1*j+%n}T(cn;PmY9~ zoHS!r6OeDV7|iOE3yOe$i<*LbOJ1hgl75(``8+iV`T163eqO$OtUwM+n4gb)n?1{J zx5s42*Ix^fDgPA3OvVPPQxcozd6!+@ zJtbz3`glPR@L!^)Am8h=cuTzUVUlKj=>#wGOa1w!fA{#+6y%pz+RDp=_`{=;^72aN z@gTn{s<|a z8q*+2L&JJC0r?v*EZL|&Eub7WZoE+9#*N5t?=0Kg-rmlkee>qc2;e&z@E{+LMh*9q zkntj2O3_kz<@cv??tN?W^ne7&Bdo}(8H9`&?( zhWZCjYD*HW|z0PGe-rL)NdbC^*UP1Ary{O@GwFXd`RK0*g z85QlGlbW*5o=bX8Ue)3}+0@eO^m;v;PCnP!bMmPd243LjnqQqmV)vdt3ZRGHK);_zIqPl6BlWM zb2w!bNQ%u0be0OZ@adY6sI}XydWYVx^Ocm<)jLXbR(oxIU0Kv?@!B2UlCp@UuD($? zytQ_hDDx{1T|DYK+<3S;vSoC1OZmEWm#$m4ZefoI8VeR5@r6RZ`IzYNg-WZ%fzgZW zD^b!ldiQ9Ii(R^IesNbY5b}w$zECXW`-m?eYf_XH%@xXTus(U{#{RX%hjwu0j>v=ViVC;V%lJmeu7%(4=2cd~_`j}sR(S{~!5V6xlZ!JC3qejE zO9ix+$1odXSjB50Wb@&a$b~YIX?}SQwv_~GMtx4OY0Z&nQ;-uno0~h47q~9c z*{mEh7c6|tkfQ{BPH%2bfmO*iC<9)z$z=8d_gYsv7rlk0Htu5vPIRPs0rv*HPnA$5 z#@f##%*tjZ&!Lb56eENVt>DoxVQ#SYOYORnYEc%A_{$)qx7ICkMXAH)utf7~?dTpX zHCk(TwqqZPNY0D|l8ed#|;=b5@$L&Q$!J;DD zx&ga=;1I*5wkjryKC9JdT0HZOpTxr5lYY#{mVS{F35m~UI;I`kdz%4I59wl zP(vXO_k}os7t%!ty$A_}LkKq@+==i>gr^W*L@@10&u$wmpP)0F9Bf79&`T#IlA!VJO_2wy}n?SP2i0`oHjWd~1%r53!)E!fb4kL^(5 z2?<*?W9?#Fw2&JVBjwOXN~%PpF6z+PtZosuV6d>F`0FEeRl;ZUN5$EhnQh0mMb^5S zlP$~4%*_1EiD^W4b*+o8Z%H;QZRtq;21KT3PN1Dm==d(>S6H!%ao^DgDa?>U2Pus3 zYgh^cdTy3Vu`hEgmO1v4(z#{J+$xnzFA3!sDlNKL@iKa%&k=qW*cQgrcMD7od$EY- zil`s!zt1`b$f?Ah{!G{Lp~Ho1#V@^uZGk7X!T9l^s|&pg7d~FN zc12r2c`CT)l;TA1rZIPhF?Tc=iY#aV9p}#TFbJ%1Y-45!ZUi+VEtAKHpc#y-92a5n zSseL#jSp1Vuw0#;o}ZbXnVD9OE#xU@7H(0l2rT?4ptu%(f-o10p`{tL*^D-`u@>T9 zRbV8om||6;4s#4+Tf1IFZ0Qux^W)+yhHu-k#~8p$dLAfeDm%7!R7#kyWTtXDO=9Q8 zAV)0qisp9QK4xLU1SyK)K@WL$Wuxa6=ye`?orib{;@OB-^4d{`y_9XjA$L5iguJU^ z}gQj7kaC0t)uh810Bvsmq6Z-lou<=F6W`fK^9ROiQbQ=-@Db@C-)^Vxh6UnCp}+ceDudCikvzyG#`%NyRX*_EA> zSGr^`vFdAXy{0;FaS^P4x+mbhFcwHt2V5caybtYVvvO;5+fW^Hp+8{V01Sz$6O zN+6)XXv95f%NZ{$E-u{f^7&l1<(cf3LM~%AtpH;;tfM;zXG>zpk1H1}|pdg$%h9^w4E!a+W%gdJzP&VpQ_65!FU@`ehStgv!sgU-+`V5$tXz;CyymaJ%VZA*siD>50REyIje>s=n5lbegX z*R2Z{1kJ6MSfpk5?(0J#G2rs)O2evASC^h+(cd*FgKX5#FPri5C@p+_bMb~t*V(Mq zYj)q*UsLl5Y1X(g4`94rfR1cfy|0`l7siKo4Hwjs3uWbkS9rV-*CNhTug0?wXOA;m zrTK6!3$W?vs4W(D zYp(D|>m7PuBr1;2NCCFY$4)K&U`E_;&_{K;Ku^GESnOF0guE>Je0S{dsf9sNYK-Wu zx*#&|Lng}^!@55Vzfc3Ow}=|q*G(_b3be>7(@T;5fi8>qT)3>$f2hN7sTbQhi?4Ak zM#YOP=weig+p(D474nL+O54J$atx}S|HSB6O{qfk@hmuGcOBX7{9`IO-ys;{+k{Effv|y)WDF~MlxiT zoT5Vx50L>me09q?H6gD*Z1F`MK1(9JVlAv6zk7l6}h%X zd-bmE)nc;d^#(^~e(Tk(4f;&mFYOKX#oxdBbF0S6KJwBT$ADR|9=|VNHcJ~Z)0z-A zLJf^jMUjL=xWd~XbaD-4Y+CGF{#1V47}=#diBykUypN~ z!=5X2_9)JBSoyK=!(nCjHBttaFCFSMQ0=)p7f%F*Ode-JNx}9)N7S!XwANx>uECzE zXm#2qr`4;=wC5;=#acztDxYUVS4TieK>H0jc(K6qSe~U+n{QmP35+mRcS$&FhAH%<(0+!DBPOW?*Wfg863Zrl>MaSn9jmcWf$ z0{7A_fg863Zrl>2>o39L?L+%qKlGg;cP@Bcb?cSz@}V)Ko-Y6*dPhWFF_!Y>fGz5` zVF#{@`gJ=a@oP5q-`m%B@ALQeDfW`p1C8V3jazdTA6PxmFg)C_HK(pbjI>@8kH`{z z_gd->4y?X#`101Rjm7SD4JzN@ao5#hcFOY>`~w?i=-rrZ&z5MkY#V*A6f#n|)b<;iX7N$XkX*HG{v}P`Az}|p zyP9vDSSl-^pS$6^Zb)kfK93wS4TeUKA>ze1^JQp@FWnW4ZI-Mny*jfAu>t6Kb$;t? z8`d<>pP0x0Um5U$6+iF6XGxRdhsygjX3b{J&6?k8=Q28Vt8^dI{Yu}UpD`TG+?;u} zafR_jR(aN*toyR&viR#NhbV+L(+_tq%?r%0N|ooUzgm@t=(tEsm*L+8TU9;-{&Bm? z>ySRG@_HD3k z=~*=p@YL3XR(p0I^7K@BE*Kf{$c!n^WPB<Gj+0++m#xa{4FZ;X=g|5o8kqyT6wcBv4)%ktp+q(i_S?1dhjxkvElIp>Wj z8H?llqBv6b0|!wO-$SA9G1SUVTCN$Fw(}c-=zE5gZKaM zbR+M3V7a;I`#*Z{VS`YFMrcKb&*p~A9CPwy6Eu}h^Qxl^s*;4w7<@Cw;9!#B~ zrHrgS<0FHpoU67#+<0GnFtPkv_5fy6d@R{FfElTsLWTB${*n0DU_ZYxmRzpJJd&77 z_U#@&xLofL=I;p4;rOI4F}7!Xax|?mRW;|9#ncRCNo@=yCZUA19Orf`V`BV3d=g5M cvgaO1j17(-=o`gM9!Zj?onLr~Ly0YIKslK=n! literal 0 HcmV?d00001 diff --git a/stuff/power32gray.png b/stuff/power32gray.png new file mode 100644 index 0000000000000000000000000000000000000000..820a4d96f297aa5cc2f3c50197502a030f6749df GIT binary patch literal 2900 zcmbVO2~-p38XaU2K@=Yps8oqVMJXnkY(OT2H7JMy#HgrPnaoTeN-`l60^$-B#A;PU z@geI|M1?2fQWV(~QBXj%ZdC!RwiE@d7SJBcb9ocCXIs0Rmvbib&&>Vrz27q5nJuBg zb1cjzn*jh|5f~r}qs}z_VQNDClZlBhsM9!Az!DMw%&qi?0g#<*2LQ&6a!I%*Ts#j( z2?Ybe2r14;P^c(00C;#Ms1S4&uAxcsD7jJyKCe0l(&U&BT+9An6L#QPL5i?S$&=JctHjlxh&0H*3VnjUY{N4s!glKRfNL7tXhd6W&Bw=x3 zo+}J-T_83LK|@e6fyrg7e-Gus5Q{?p3QF}1hG>w#1Y;;HBh(6n3Rtc{qHv~483oct z(+K+!F@%~DrrdD`U5LeSppw)eN)!(i2|+4mhFp%pQiLmmqzFdm;;wAEJI>|P-4S;- zoyS6DY&MUB@FD)lei4Dj=_{+>Kh)(Ifl?g*QR)`xPr(-;X z1G#eD5fnm3*h18D>P16h-e=Xj!YD?BFO%_j?p(Um9g@=794U&)XqWU7^7&v@e{(*e_E#=|;@zFR% z`X|L7QYQ(SCLU4aK2cQe{<684e`KCSw0~~>@0D`M)9%(b5qY-5kPEAfG zs1JszA2CBkVg9yWgU{X@M6iTwb{S9(%Ie9({E;} z6MA{QbISj`yzR}HP#9Y8hCewU`P2QXUv53{@2@_4*5qIL`8J!L=1gDzwz{%%ps%mb zR~oCXi0CdpmlIOc3+}I+U?K)yz3J@iBzhh_+8_2b-(zap(p%geCWZrcoju~G-3z?! zw&6>xZEP0Bj60uK5nW_r7#;y+ep&E++vEO8u6?@7hX3SkYRO_PHkwqM+hMwR>C(wO zSJ$TJy}hxpP`JmtEW9m0n2mTnNv(^r>`6V|bLf!M)-7AoYYrat->3#-ie~N3HLKSO zm6db6MR|q^w!M-Q_2tDqWzKhFbt&OGDfrzQosRin+V@iqAmblC%-X%%sHq7cwdM3;Jaf5eK zQ*(21X=(8Kkl^4OO-)-{W@;II+1WWc&OF{8Gjnrip)k*6>{w?I^koztF1ASNn*1!Z z?y8H6OY#2wKJ^}+o^NZ?9qQ%l)-7+O(pgkqo~a~=#`ePPDGrk?87)ms1=-n?4<4_n z5#PLd^SN&ladB;IY`T+^Q-;U%>6lnRAnA!=`L&taDIylG)BBXxj1*5biD}g}3h2fQsP*R=y3wQ2i zv(k?)&(btb(RxXZ?j+AkPfzc7nRt-xbTT51_XW?xBZe%_Z+ev~R(@@J>DY@;H_yFo zu&7qhp1O0Np7@X04deKGwR3zWX6tE!G*r%s*PS`S@$#t}3m7`}Y@@*f_py}c*k zQosDve|wrcnwy)?P0f=?Bmtf&n>RPdewBR2&d-!}uCj7z*MWqtmz{nBm0-C-=Ju%aq2hR`Z=TAL#_xklobSATzpEyklOr2kR)(k)QY_^tj zqolA<^m#c{QC22tuvHh*9h!d{AF!D`aO6mHXZPE;>$CcS$bYW$xshZ6Ft^RHwhYRM zOsaMBt~D>(1#DU!u;g-UYim(S2_?T_g8}T}kwLZ?PVBJ#bmEzdHOjD=x3hp(TlO|I zG=$BWGZx3NwcX!soxGtxQm0!nrlZ;A4p8lQ)IZMSMMp=++K+(Oa8BH5Lt*=N0nnb8 zkx_V8;hHjb1~}npe?OVk5bQSX?3p^lZ*&o=^lw`>CJO+|YuB#b?Cd;*@mH>ih{&xh ztGyktygh}6PC0#P$-Xw*kj&}p*AB>^7@0KP<+YDvmXwy>Xl>1&C%kgrSLKqhYv;~= z5lTkMvEB8% zW=d%xnxOF}E!{TVZC$SQ9%EFSUsZ{8RypoAuLqtD+|ylqXDpn%h`Fa{+hP58Z=ip$ KsMI%d<9`ACG;P%Y literal 0 HcmV?d00001 diff --git a/stuff/power32red.png b/stuff/power32red.png new file mode 100644 index 0000000000000000000000000000000000000000..275a0dbfba56665aa8ddd456172508e8e65a111b GIT binary patch literal 3369 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 ac3H1MLPmSm-P5X%8JDddtWw9lhyDx6!CLzO literal 0 HcmV?d00001 diff --git a/stuff/sync.png b/stuff/sync.png new file mode 100644 index 0000000000000000000000000000000000000000..097aa46c7151fecb2e54ec33bcddfa93e9fc33a2 GIT binary patch literal 2646 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 Eg5L=g)c^nh literal 0 HcmV?d00001 diff --git a/stuff/view-sync.png b/stuff/view-sync.png new file mode 100644 index 0000000000000000000000000000000000000000..c46e768826dd225929e997c7c09c3ce037ca6624 GIT binary patch literal 13757 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 literal 0 HcmV?d00001

VT(!~ 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