# -*- coding: utf-8 -*- """ The main GUI model of project. """ import sys import webbrowser from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtWidgets import QErrorMessage # import qdarkstyle from src.gui.main_ui import Ui_PDFdir from src.pdfdirectory import add_directory from src.isupdated import is_updated from src.config import RE_DICT from src.gui.base import TreeWidget from src.convert import text_to_list, split_page_num from src.pdf.bookmark import add_bookmark QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) def dynamic_base_class(instance, cls_name, new_class, **kwargs): instance.__class__ = type(cls_name, (new_class, instance.__class__), kwargs) return instance class WindowDragMixin(object): def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos() - self.pos() event.accept() def mouseMoveEvent(self, QMouseEvent): if QMouseEvent.buttons() and Qt.LeftButton: self.move(QMouseEvent.globalPos() - self.m_DragPosition) QMouseEvent.accept() def mouseReleaseEvent(self, QMouseEvent): self.m_drag = False class ControlButtonMixin(object): def set_control_button(self, min_button, exit_button): min_button.clicked.connect(self.showMinimized) exit_button.clicked.connect(self.close) class Main(QtWidgets.QMainWindow, Ui_PDFdir, ControlButtonMixin): def __init__(self, app, trans): super(Main, self).__init__() # self.setWindowFlags(Qt.FramelessWindowHint) # self.menuBar.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.app = app self.trans = trans self.setupUi(self) self.version = 'v0.2.2' self.setWindowTitle(u'PDFdir %s' % self.version) self.setWindowIcon(QtGui.QIcon('pdf.ico')) self.error_message = QErrorMessage() self.dir_tree_widget = dynamic_base_class(self.dir_tree_widget, 'TreeWidget', TreeWidget) self.dir_tree_widget.init_connect(parents=[self, self.dir_tree_widget]) self.add_pagenum_box.setMinimum(-1000) self._set_connect() self._set_action() # self._set_unwritable() # self.adv_group.setEnabled(False) def _set_connect(self): self.open_button.clicked.connect(self.open_file_dialog) # self.export_button.clicked.connect(self.export_pdf) self.export_button.clicked.connect(self.write_tree_to_pdf) self.dir_text_edit.textChanged.connect(self.to_tree_widget) # self.level0_box.clicked.connect(self._change_level0_writable) # self.level1_box.clicked.connect(self._change_level1_writable) # self.level2_box.clicked.connect(self._change_level2_writable) # # self.level0_button.clicked.connect(lambda: self._level_button_clicked('level0')) # self.level1_button.clicked.connect(lambda: self._level_button_clicked('level1')) # self.level2_button.clicked.connect(lambda: self._level_button_clicked('level2')) self.add_pagenum_to_selected_button.clicked.connect(self._add_selected_pagenum) self.add_pagenum_to_all_button.clicked.connect(self._add_all_pagenum) def _set_action(self): self.home_page_action.triggered.connect(self._open_home_page) self.help_action.triggered.connect(self._open_help_page) self.update_action.triggered.connect(self._open_update_page) self.english_action.triggered.connect(self.to_english) self.chinese_action.triggered.connect(self.to_chinese) def _set_unwritable(self): self.level0_edit.setEnabled(False) self.level1_edit.setEnabled(False) self.level2_edit.setEnabled(False) def _level_button_clicked(self, level_str): context_menu = QtWidgets.QMenu() for k, v in RE_DICT.get(level_str).items(): context_menu.addAction(k, lambda v=v: self._insert_to_editor(level_str, v)) context_menu.exec_(QtGui.QCursor.pos()) def _insert_to_editor(self, level_str, text): editor = getattr(self, level_str + '_edit') if editor.isEnabled(): editor.insert(text) def _change_level0_writable(self): self.level0_edit.setEnabled(True if self.level0_box.isChecked() else False) def _change_level1_writable(self): self.level1_edit.setEnabled(True if self.level1_box.isChecked() else False) def _change_level2_writable(self): self.level2_edit.setEnabled(True if self.level2_box.isChecked() else False) def _add_pagenum_to_item(self, item): current_num = int(item.text(1)) add_num = self.add_pagenum_box.value() self.dir_tree_widget.set_pagenum(item, max(current_num + add_num, 0)) def _add_selected_pagenum(self): selected_items = self.dir_tree_widget.selectedItems() for item in selected_items: self._add_pagenum_to_item(item) def _add_all_pagenum(self): for item in self.dir_tree_widget.all_items: self._add_pagenum_to_item(item) @staticmethod def _open_home_page(): webbrowser.open('https://github.com/chroming/pdfdir', new=1) @staticmethod def _open_help_page(): webbrowser.open('https://github.com/chroming/pdfdir/blob/master/readme.md', new=1) def _open_update_page(self): url = 'https://github.com/chroming/pdfdir/releases' try: updated = is_updated(url, self.version) except Exception: self.statusbar.showMessage(u"Check update failed", 3000) else: if updated: self.statusbar.showMessage(u"Find new version", 3000) webbrowser.open(url, new=1) else: self.statusbar.showMessage(u"No update", 3000) def to_english(self): self.trans.load("./language/en") self.app.installTranslator(self.trans) self.retranslateUi(self) def to_chinese(self): self.app.removeTranslator(self.trans) self.retranslateUi(self) def _get_args(self): pdf_path = self.pdf_path_edit.text() offset = int(self.offset_edit.text()) dir_text = self.dir_text_edit.toPlainText() level0 = self.level0_edit.text() if self.level0_box.isChecked() else None level1 = self.level1_edit.text() if self.level1_box.isChecked() else None level2 = self.level2_edit.text() if self.level2_box.isChecked() else None other = self.select_level_box.currentIndex() return dir_text, offset, pdf_path, level0, level1, level2, other @property def pdf_path(self): return self.pdf_path_edit.text() def open_file_dialog(self): filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, u'select PDF', filter="PDF (*.pdf)") self.pdf_path_edit.setText(filename) def tree_to_dict(self): return self.dir_tree_widget.to_dict() def to_tree_widget(self): self.dir_tree_widget.clear() last_num = 0 for line in text_to_list(self.dir_text_edit.toPlainText()): title, num = split_page_num(line) num = max(num, last_num) self.dir_tree_widget.insertTopLevelItem(self.dir_tree_widget.topLevelItemCount(), QtWidgets.QTreeWidgetItem([title, str(num)])) last_num = num def export_pdf(self): new_path = add_directory(*self._get_args()) self.statusbar.showMessage(u"%s Finished!" % new_path, 3000) def write_tree_to_pdf(self): try: new_path = self.dict_to_pdf(self.pdf_path, self.tree_to_dict()) self.statusbar.showMessage(u"%s Finished!" % new_path, 3000) except PermissionError: self.error_message.showMessage(u"Permission denied!") @staticmethod def dict_to_pdf(pdf_path, index_dict): return add_bookmark(pdf_path, index_dict) def run(): app = QtWidgets.QApplication(sys.argv) # app.setStyle('fusion') # app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) trans = QtCore.QTranslator() # trans.load("./gui/en") # app.installTranslator(trans) window = Main(app, trans) window.show() sys.exit(app.exec_()) sys._excepthook = sys.excepthook def exception_hook(exctype, value, traceback): sys._excepthook(exctype, value, traceback) sys.exit(1) sys.excepthook = exception_hook if __name__ == '__main__': run()