class MainWindow(QMainWindow):
    def __init__(self):
        # Boilerplate
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Specific stuff
        default_dir = config.get('default_dir')
        self._current_dir = default_dir if default_dir else '.'
        self.setWindowTitle('TRPG Creator - [{}]'.format(self.current_dir))
        self.model = QFileSystemModel()
        self.init_tree_view()
        self.ui.filesFrame.resize(500, self.ui.filesFrame.height())
        self.connect_actions()

    def connect_actions(self):
        # File
        self.ui.actionNew.triggered.connect(self.new_campaign)
        self.ui.actionOpen.triggered.connect(self.open_campaign)
        self.ui.actionQuit.triggered.connect(helper.exit_app)
        self.ui.actionToFile.triggered.connect(self.export_to_file)
        # Run
        self.ui.actionStandard.triggered.connect(self.test_standard)
        # Help
        self.ui.actionAbout.triggered.connect(
            helper.show_simple_dialog(AboutDialog))
        # Tools
        self.ui.actionSettings.triggered.connect(self.show_campaign_settings)
        # Buttons
        self.ui.openFolderButton.clicked.connect(self.open_current_dir)

    # Overrides
    def keyPressEvent(self, QKeyEvent):
        key = QKeyEvent.key()
        index = self.ui.filesTreeView.currentIndex()

        if index.isValid():
            item_name = self.model.itemData(index)[0]
            if key in (Qt.Key_Return, Qt.Key_Enter):
                if '.' in item_name:
                    # It's a file. Edit it.
                    name, ext = os.path.splitext(item_name)
                    self.file_edit_function(ext, self.model.filePath(index))()
                else:
                    # It's a directory. Expand it.
                    self.ui.filesTreeView.expand(index)
            elif key == Qt.Key_Delete:
                if '.' in item_name:
                    # It's a file. Try to delete it.
                    try:
                        name, ext = os.path.splitext(item_name)
                        resource_object = resource.ext_to_object[ext]
                        if resource_object.delete:
                            self.file_delete_function(
                                self.model.filePath(index))()
                    except KeyError:
                        helper.display_error('Operation not supported.')
                else:
                    # It's a folder. Try to delete it.
                    if item_name not in resource.folder_to_name:
                        # Make sure it's not a root director
                        self.folder_delete_function(
                            self.model.filePath(index))()

        super().keyPressEvent(QKeyEvent)

    # Actions
    def new_campaign(self):
        dialog = QFileDialog(self)
        dialog.setDirectory(helper.one_up(self.current_dir))
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setOption(QFileDialog.ShowDirsOnly)
        dialog.setWindowTitle('Select folder name')
        if dialog.exec_():
            directory = dialog.selectedFiles()[0]
            qdir = QDir(directory)
            if not qdir.exists():
                self.current_dir = qdir.path()
                for folder_name in resource.folders:
                    qdir.mkpath('./' + folder_name)
                helper.save_json_data(
                    '{}/{}/health{}'.format(self.current_dir,
                                            resource.health_stat.folder,
                                            resource.health_stat.ext),
                    resource.health_stat.default)
                qdir.mkpath('./.settings/std')
                qdir.mkpath('./.settings/debug')
                resource.create_config_files(self.current_dir, qdir.dirName())
                self.refresh_tree_view()
            else:
                helper.display_error('Directory for campaign already exists.'
                                     )  # This shouldn't happen

    def open_campaign(self):
        dialog = QFileDialog(self)
        directory = QFileDialog.getExistingDirectory(
            dialog,
            caption='Select a campaign',
            directory=helper.one_up(self.current_dir),
            options=QFileDialog.ShowDirsOnly)
        if directory:
            self.current_dir = directory
            self.refresh_tree_view()

    def export_to_file(self):
        dialog = QFileDialog(self)
        file_location = QFileDialog.getSaveFileName(
            dialog,
            caption='Export campaign file',
            directory=self.current_dir,
            filter='*.trpg')[0]
        file_location = file_location.split('.')[0] + '.trpg'
        if file_location:
            export.export_to_file(self.current_dir, file_location)

    def test_standard(self):
        qdir = QDir(self.current_dir)
        qdir.mkpath('./.run')
        file_location = self.current_dir + '/.run/std.trpg'
        export.export_to_file(self.current_dir, file_location)
        dialog = ConsoleDialog(file_location).exec_()

    def open_current_dir(self):
        QDesktopServices.openUrl(QUrl(self.current_dir))

    def show_campaign_settings(self):
        try:
            CampaignSettingsDialog(self.current_dir + '/.settings').exec_()
        except FileNotFoundError as e:
            helper.display_error(
                'You aren\'t in campaign. You cannot change campaign settings.'
            )

    # <editor-fold desc="Tree View">
    def init_tree_view(self):
        self.ui.filesTreeView.customContextMenuRequested.connect(
            self.custom_tree_menu)
        self.ui.filesTreeView.mouseDoubleClickEvent = self.custom_tree_double_click
        self.ui.filesTreeView.setHeaderHidden(True)
        self.ui.filesTreeView.setModel(self.model)
        self.refresh_tree_view()

    def refresh_tree_view(self):
        self.model.setRootPath(self.current_dir)
        root = self.model.index(self.current_dir)
        self.ui.filesTreeView.setRootIndex(root)
        for x in range(1, 4):
            self.ui.filesTreeView.hideColumn(
                x)  # TODO: Find a way to only have to do this once

    def file_edit_function(self, ext, file_location):
        # TODO: Resource dict
        if ext == resource.item.ext:
            return ItemDialog(file_location).exec_
        elif ext == resource.scenario.ext:
            return ScenarioDialog(file_location).exec_
        elif ext in (resource.health_stat.ext, resource.res_stat.ext,
                     resource.other_stat.ext):
            return StatDialog(file_location).exec_
        elif ext == resource.function.ext:
            return FunctionDialog(file_location).exec_
        else:
            return lambda: helper.display_error(
                'Operation not implemented yet.')

    @staticmethod
    def file_create_function(base_folder, file_location):
        resource_type = resource.folder_to_name[base_folder]

        def create_resource():
            new_id = CreateResourceDialog.get_new_id(resource_type)
            if new_id is not None and new_id.strip() != '':
                helper.save_json_data(
                    file_location + '/' + new_id +
                    resource.folder_to_ext[base_folder],
                    resource.name_to_default[resource_type])

        # TODO: Additional/better checks here for duplicate files
        return create_resource

    @staticmethod
    def file_delete_function(file_location):
        def delete_folder():
            if ConfirmDialog.yes_to(
                    'Are you sure you want to delete this file?'):
                QFile(file_location).remove()

        return delete_folder

    @staticmethod
    def folder_create_function(folder_location):
        def create_folder():
            new_id = CreateResourceDialog.get_new_id('folder')
            if new_id is not None and new_id.strip() != '':
                qdir = QDir(folder_location)
                qdir.mkpath('./' + new_id)

        # TODO: Additional/better checks here for duplicate folders
        return create_folder

    @staticmethod
    def folder_delete_function(folder_location):
        def delete_folder():
            qdir = QDir(folder_location)
            if ConfirmDialog.yes_to(
                    'Are you sure you want to delete this folder?'):
                qdir.removeRecursively()

        return delete_folder

    def custom_tree_double_click(self, event):
        point = event.pos()
        index = self.ui.filesTreeView.indexAt(point)
        if index.isValid():
            item_name = self.model.itemData(index)[0]
            if '.' in item_name:
                # It's a file. Edit it.
                name, ext = os.path.splitext(item_name)
                self.file_edit_function(ext, self.model.filePath(index))()
            else:
                # It's a directory. Expand it.
                self.ui.filesTreeView.expand(index)

    def custom_tree_menu(self, point):
        index = self.ui.filesTreeView.indexAt(point)
        if index.isValid():
            item_name = self.model.itemData(index)[0]
            if '.' in item_name:
                # It's a file
                name, ext = os.path.splitext(item_name)
                menu_actions = [
                    ('Edit ' + name,
                     self.file_edit_function(ext, self.model.filePath(index)))
                ]
                try:
                    resource_object = resource.ext_to_object[ext]
                    if resource_object.delete:
                        menu_actions.append(('Delete ' + name,
                                             self.file_delete_function(
                                                 self.model.filePath(index))))
                    menu = context_menus.build(menu_actions)
                    menu.exec_(self.ui.filesTreeView.mapToGlobal(point))
                except KeyError:
                    helper.display_error('Operation not supported.')
            else:
                # It's a folder
                start_index = index
                # Get the root
                if item_name not in resource.folder_to_name:
                    root = False
                    while item_name not in resource.folder_to_name:
                        index = index.parent()
                        item_name = self.model.itemData(index)[0]
                else:
                    root = True
                menu_actions = []
                resource_object = resource.folder_to_object[item_name]
                if resource_object.create:
                    menu_actions.append(
                        ('Create new ' + resource.folder_to_name[item_name],
                         self.file_create_function(
                             item_name, self.model.filePath(start_index))))
                if resource_object.subfolder:
                    menu_actions.append(
                        ('Create new folder',
                         self.folder_create_function(
                             self.model.filePath(start_index))))
                if not root:
                    menu_actions.append(
                        ('Delete folder',
                         self.folder_delete_function(
                             self.model.filePath(start_index))))
                if menu_actions:
                    menu = context_menus.build(menu_actions)
                    menu.exec_(self.ui.filesTreeView.mapToGlobal(point))

    # </editor-fold>

    # Properties
    @property
    def current_dir(self):
        return self._current_dir

    @current_dir.setter
    def current_dir(self, value):
        self._current_dir = value
        self.setWindowTitle('TRPG Creator - [{}]'.format(value))
        config.set('default_dir', value)
Example #2
0
class Ui(QtWidgets.QMainWindow):
    """Main Class of the simple DMS user interface.

    Arguments:
        nothing

    Returns:
        nothing

    """
    def __init__(self):
        """Initialize variables and connect actions with functions."""
        super(Ui, self).__init__()
        uic.loadUi(os.path.join(CURRDIR, "ui", "main_simpledms.ui"), self)
        self.loadpref()
        self.rules = rules.Rules(self.pref["dmsroot"])
        self.currentselectedrulesfolder = None
        self.currentselectedsearchfolder = None
        self.current_monitorfolder_index = None
        self.parent_index = None
        self.filemodelmonitor = QFileSystemModel()
        self.rulesfoldermodel = QFileSystemModel()
        self.resultfoldermodel = QFileSystemModel()
        self.searchfoldermodel = QFileSystemModel()
        self.textEdit_tags = MyTextEdit(self.textEdit_tags)
        self.updateui_settings()
        self.updateui_pdfrename()
        self.show()

        # Connect Widget Toolbar Actions
        self.actionScan.triggered.connect(self.select_widget)
        self.actionPdf.triggered.connect(self.select_widget)
        self.actionSettings.triggered.connect(self.select_widget)
        self.actionAbout.triggered.connect(self.show_ui_about)
        self.actionExit.triggered.connect(self.select_widget)

        # Connect Preferences
        self.pushButton_setmonitorfolder.clicked.connect(
            self.browse_monitor_folder)
        self.pushButton_setdmsroot.clicked.connect(self.browse_dms_root)
        self.treeView_rulesfolders.clicked.connect(self.rulesfolderselected)
        self.treeView_rules.doubleClicked.connect(self.ruledoubleclicked)
        self.pushButton_addrule.clicked.connect(self.addruleclicked)
        self.pushButton_deleterule.clicked.connect(self.deleteruleclicked)

        # Connect page pdf renaming
        self.listView_monitorfiles.clicked.connect(
            self.listView_monitorfiles_clicked)

        self.treeView_output.clicked.connect(self.treeView_output_clicked)
        self.pushButton_ok.clicked.connect(self.pushButton_ok_clicked)
        self.listView_monitorfiles.doubleClicked.connect(
            self.listView_monitorfiles_doubleclicked)
        self.lineEdit_outputfilename.textChanged.connect(self.readyforstorage)
        self.pushButton_addDate.clicked.connect(
            self.pushButton_addDate_clicked)

    # -------- Settings page -----------
    def rulesfolderselected(self, signal):
        """Update ui if a folder in settings -> rules is selected."""
        self.currentselectedrulesfolder = self.rulesfoldermodel.filePath(
            signal)
        self.updateui_settings()
        self.pushButton_addrule.setEnabled(True)

    def ruledoubleclicked(self):
        """Open ui for rule adaption of double clicked rule."""
        selectedrule = self.treeView_rules_model.itemData(
            self.treeView_rules.selectedIndexes()[0])
        rule = self.rules.returnruleofkeywords([selectedrule[0]],
                                               self.currentselectedrulesfolder)
        rulesdialog = MyRulesWidget(
            keywords=rule[0][1],
            booleanoperator=rule[0][2],
            tags=rule[0][3],
            doctitle=rule[0][4],
            indexertags=set(self.rules.returnalltags()),
        )
        rulesdialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        if rulesdialog.exec_():
            self.rules.replacerule(
                rule[0][0],
                rulesdialog.keywords,
                rulesdialog.booleanoperator,
                rulesdialog.tags,
                rulesdialog.doctitle,
                self.currentselectedrulesfolder,
            )
            self.updateui_settings()

    def deleteruleclicked(self):
        """Delete selected rule and update ui."""
        if self.treeView_rules.selectedIndexes():
            selectedrule = self.treeView_rules_model.itemData(
                self.treeView_rules.selectedIndexes()[0])
            self.rules.delrule([selectedrule[0]],
                               self.currentselectedrulesfolder)
            self.updateui_settings()

    def addruleclicked(self):
        """Add rule to database if it does not exist yet."""
        rulesdialog = MyRulesWidget(
            indexertags=set(self.rules.returnalltags()))
        rulesdialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        if rulesdialog.exec_():
            if self.rules.returnruleofkeywords(
                    rulesdialog.keywords, self.currentselectedrulesfolder):
                QtWidgets.QMessageBox.information(
                    self, "Error",
                    "A rule with these keywords already exists.")
            else:
                self.rules.addrule(
                    rulesdialog.keywords,
                    rulesdialog.booleanoperator,
                    rulesdialog.tags,
                    rulesdialog.doctitle,
                    self.currentselectedrulesfolder,
                )
                self.updateui_settings()

    def loadpref(self):
        """Load preferences: root of dms and monitorfolder."""
        if os.path.isfile("pref.json"):
            with open("pref.json") as f:
                self.pref = json.load(f)
                if not os.path.isdir(self.pref["dmsroot"]):
                    os.makedirs(self.pref["dmsroot"])
                    QtWidgets.QMessageBox.information(
                        self, "Attention!",
                        "Stored path of dmsroot does not exist")
                if not os.path.isdir(self.pref["monitorfolder"]):
                    os.makedirs(self.pref["monitorfolder"])
                    QtWidgets.QMessageBox.information(
                        self,
                        "Attention!",
                        "Stored path of monitorfolder does not exist.",
                    )
        else:
            # If pref.json file does not exist
            if not os.path.isdir(
                    os.path.join(os.path.expanduser("~"), "paperwork")):
                os.makedirs(os.path.join(os.path.expanduser("~"), "paperwork"))
                QtWidgets.QMessageBox.information(
                    self,
                    "Attention!",
                    "Standard path for file cabinet"
                    "was created. If "
                    "needed, please change.",
                )

            if not os.path.isdir(
                    os.path.join(os.path.expanduser("~"), "paperwork_open")):
                os.makedirs(
                    os.path.join(os.path.expanduser("~"), "paperwork_open"))
                QtWidgets.QMessageBox.information(
                    self,
                    "Attention!",
                    "Standard path for monitor folder"
                    "was created. If "
                    "needed, please change.",
                )

            self.pref = {
                "dmsroot":
                os.path.join(os.path.expanduser("~"), "paperwork"),
                "monitorfolder":
                os.path.join(os.path.expanduser("~"), "paperwork_open"),
            }
            self.savepref()

    def savepref(self):
        """Save preferences to pref.json."""
        with open("pref.json", "w") as f:
            json.dump(self.pref, f)

    def browse_monitor_folder(self):
        """Select monitor folder."""
        # execute getExistingDirectory dialog and set the directory variable to be equal
        # to the user selected directory
        directory = QFileDialog.getExistingDirectory(
            self, "Select a monitor folder with files to be "
            "processed/imported")
        # if user didn't pick a directory don't continue
        if directory:
            self.pref["monitorfolder"] = directory
            self.savepref()
            self.updateui_settings()
            self.updateui_pdfrename()

    def browse_dms_root(self):
        """Select dms root folder."""
        # execute getExistingDirectory dialog and set the directory variable to be equal
        # to the user selected directory
        directory = QFileDialog.getExistingDirectory(
            self, "Select a root directory of the filing cabinet")
        # if user didn't pick a directory don't continue
        if directory:
            if not len(self.rules.returnallrules()) == 0:
                result = QtWidgets.QMessageBox.question(
                    self,
                    "Attention",
                    "If the root directory is changed, the current rules are "
                    "deleted! Are you sure and want to proceed?",
                )
                if result == QtWidgets.QMessageBox.No:
                    return
            self.rules.resetdb(directory)
            self.pref["dmsroot"] = directory
            self.savepref()
            # self.indexer.__init__(directory)
            self.updateui_settings()

    def updateui_settings(self):
        """Update ui elements of settings page."""
        self.label_monitorfolder.setText(self.pref["monitorfolder"])
        self.label_monitordir.setText(
            ".." + os.sep +
            os.path.basename(os.path.normpath(self.pref["monitorfolder"])))
        self.label_dmsroot.setText(self.pref["dmsroot"])
        self.rulesfoldermodel.setRootPath(self.pref["dmsroot"])
        self.rulesfoldermodel.setFilter(QtCore.QDir.NoDotAndDotDot
                                        | QtCore.QDir.Dirs)
        self.treeView_rulesfolders.setModel(self.rulesfoldermodel)
        self.treeView_rulesfolders.setRootIndex(
            self.rulesfoldermodel.index(self.pref["dmsroot"]))
        self.treeView_rulesfolders.hideColumn(1)
        self.treeView_rulesfolders.hideColumn(2)
        self.treeView_rulesfolders.hideColumn(3)
        self.treeView_rules_model = QtGui.QStandardItemModel()
        self.treeView_rules.setModel(self.treeView_rules_model)
        self.treeView_rules_model.setHorizontalHeaderLabels(
            ["Rules (keywords)"])
        rulesoffolder = self.rules.returnrulesoffolder(
            self.currentselectedrulesfolder)
        if rulesoffolder is not None:
            for i in rulesoffolder:
                rule = QtGui.QStandardItem(i[1])
                self.treeView_rules_model.appendRow(rule)

    # -------- Action Bar -----------
    def select_widget(self):
        """Select index of stacked widget based on toolbox actions."""
        sender = self.sender()
        if sender.text() == "Scan":
            pass
        elif sender.text() == "Import":
            self.stackedWidget.setCurrentIndex(0)
        elif sender.text() == "Settings":
            self.stackedWidget.setCurrentIndex(1)
        elif sender.text() == "Exit":
            QtWidgets.QApplication.instance().quit()

    def show_ui_about(self):
        """Show about page."""
        dialog = QDialog()
        dialog.ui = ui.about.Ui_Dialog()
        dialog.ui.setupUi(dialog)
        dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        dialog.exec_()

    # -------- pdf renaming page -----------
    def listView_monitorfiles_clicked(self, index):
        """Show preview of pdf, extract date and words and propose tags and directory in dms root."""
        self.current_monitorfolder_index = index
        pdffile = os.path.join(self.pref["monitorfolder"],
                               self.filemodelmonitor.itemData(index)[0])

        # Check if file is really a pdf.
        if "PDF" not in magic.from_file(pdffile):
            QtWidgets.QMessageBox.information(self, "Attention!",
                                              "Document is not a pdf.")
            return

        self.listView_monitorfiles.setEnabled(False)
        self.setCursor(QtCore.Qt.BusyCursor)
        self.statusbar.showMessage("Reading pdf...")

        self.pdfhandler = PdfHandler(pdffile)
        self.pdfhandler.thumbheight = (
            self.listView_monitorfiles.frameGeometry().height())
        self.pdfhandler.createthumbnail()

        pixmap = QtGui.QPixmap(self.pdfhandler.thumbfpath)
        self.thumbnail.setPixmap(pixmap)
        self.thumbnail.resize(pixmap.width(), pixmap.height())
        self.analyze_text()
        if self.readyforstorage():
            self.statusbar.showMessage("Automatic renaming and moving file...")
            # self.pushButton_ok_clicked()
        self.listView_monitorfiles.setEnabled(True)
        self.setCursor(QtCore.Qt.ArrowCursor)
        self.statusbar.showMessage("Ready")

    def listView_monitorfiles_doubleclicked(self, index):
        """Open doubleclicked file.

        Arguments:
            index: index from pyqt5 listview which element was clicked.

        Returns:
            nothing

        """
        file2open = os.path.join(self.pref["monitorfolder"],
                                 self.filemodelmonitor.itemData(index)[0])
        webbrowser.open(file2open)

    def listWidget_pdfthumbnails_doubleclicked(self):
        """Open file in browser."""
        file2open = self.pdfhandler.filepath
        if os.path.isfile(file2open):
            webbrowser.open(file2open)
        else:
            QtWidgets.QMessageBox.information(self, "Attention!",
                                              "File does not exist!")

    def analyze_text(self):
        """Analyze the found text."""
        text = self.pdfhandler.gettext()
        dateext = DateExtractor(text)
        date = dateext.getdate()
        # If Date not found in text, search for date in filename
        if not date:
            dateext = DateExtractor(self.pdfhandler.filepath)
            date = dateext.getdate()
        result = self.rules.applyrule(text)

        if result["doctitle"] is not None:
            if date is not None:
                self.lineEdit_outputfilename.setText(
                    date.strftime("%Y-%m-%d") + " " + result["doctitle"])
            else:
                self.lineEdit_outputfilename.setText(result["doctitle"])
        else:
            if date is not None:
                self.lineEdit_outputfilename.setText(
                    date.strftime("%Y-%m-%d") + " ")
            else:
                self.lineEdit_outputfilename.clear()

        if result["tags"] is not None:
            self.textEdit_tags.setText(result["tags"])
        else:
            self.textEdit_tags.clear()

        self.destination = result["destination"]

        self.treeView_output.setCurrentIndex(
            self.resultfoldermodel.index(self.destination))

        if not self.readyforstorage():
            self.lineEdit_outputfilename.setFocus()
        else:
            self.pushButton_ok.setFocus()

        self.statusbar.showMessage("Ready")
        self.setCursor(QtCore.Qt.ArrowCursor)

    def readyforstorage(self) -> bool:
        """Check if file infos like date, text, tags and folder are set."""
        if (self.lineEdit_outputfilename.text() and re.match(
                r"(\d{4}-\d{2}-\d{2}\s\S+)",
                self.lineEdit_outputfilename.text(),
                re.I | re.UNICODE,
        ) and self.resultfoldermodel.filePath(
                self.treeView_output.currentIndex())):
            self.pushButton_ok.setEnabled(True)
            return True
        else:
            self.pushButton_ok.setEnabled(False)
            return False

    def pushButton_ok_clicked(self):
        """Store document with new metadata in target directory."""
        self.setCursor(QtCore.Qt.BusyCursor)
        self.statusbar.showMessage("Storing...")
        doctitle = self.lineEdit_outputfilename.text()[11:]
        date = self.lineEdit_outputfilename.text()[0:10]
        tags = self.textEdit_tags.toPlainText()
        tags = tags.strip(", ")
        path = self.resultfoldermodel.filePath(
            self.treeView_output.currentIndex())
        self.pdfhandler.update_and_move(path, doctitle, tags, date)
        self.updateui_pdfrename()
        self.setCursor(QtCore.Qt.ArrowCursor)
        row = self.current_monitorfolder_index.row()
        n_elements = self.filemodelmonitor.rowCount(self.parent_index)
        if row + 1 < n_elements and n_elements > 0:
            self.listView_monitorfiles_clicked(
                self.current_monitorfolder_index.sibling(row + 1, 0))
        if row + 1 >= n_elements and n_elements > 1:
            self.listView_monitorfiles_clicked(
                self.current_monitorfolder_index.sibling(row - 1, 0))
        self.updateui_pdfrename()
        self.statusbar.showMessage("ready")

    def pushButton_addDate_clicked(self):
        """Add current date to document name field."""
        if self.lineEdit_outputfilename.text():
            if re.match(r"(\d{4}-\d{2}-\d{2})",
                        self.lineEdit_outputfilename.text()):
                text = (str(datetime.date.today()) +
                        self.lineEdit_outputfilename.text()[10:])
                self.lineEdit_outputfilename.setText(text)
            else:
                self.lineEdit_outputfilename.setText(
                    str(datetime.date.today()) + " ")
        else:
            self.lineEdit_outputfilename.setText(
                str(datetime.date.today()) + " ")
        self.lineEdit_outputfilename.setFocus()

    def treeView_output_clicked(self):
        """Check if all input is available after the target directory was selected."""
        self.readyforstorage()

    def updateui_pdfrename(self):
        """Update ui of page pdfrename."""
        self.filemodelmonitor.setFilter(QtCore.QDir.NoDotAndDotDot
                                        | QtCore.QDir.Files)
        self.filemodelmonitor.setNameFilters(["*.pdf"])
        self.filemodelmonitor.setNameFilterDisables(False)
        self.parent_index = self.filemodelmonitor.setRootPath(
            self.pref["monitorfolder"])
        self.listView_monitorfiles.setModel(self.filemodelmonitor)
        self.listView_monitorfiles.setRootIndex(
            self.filemodelmonitor.index(self.pref["monitorfolder"]))
        self.resultfoldermodel.setRootPath(self.pref["dmsroot"])
        self.resultfoldermodel.setFilter(QtCore.QDir.NoDotAndDotDot
                                         | QtCore.QDir.Dirs)
        self.treeView_output.setModel(self.resultfoldermodel)
        self.treeView_output.setRootIndex(
            self.resultfoldermodel.index(self.pref["dmsroot"]))
        self.treeView_output.hideColumn(1)
        self.treeView_output.hideColumn(2)
        self.treeView_output.hideColumn(3)
        indexertags = set(self.rules.returnalltags())
        completer = MyDictionaryCompleter(myKeywords=indexertags)
        self.textEdit_tags.setCompleter(completer)
Example #3
0
class kdFileFinder(QMainWindow):
    def __init__(self):
        super().__init__()
        loadUi(get_file_realpath("kdFileFinder.ui"), self)
        self.setWindowIcon(QIcon(get_file_realpath('data/kdFileFinder.png')))

        self.exception_handler = global_exception_hander()
        self.exception_handler.patch_excepthook()

        self.lw_main.clicked.connect(self.on_lw_main_clicked)
        self.lw_main.doubleClicked.connect(self.on_lw_main_dbclicked)
        self.lw_main.installEventFilter(self)
        self.fileSystemModel = QFileSystemModel(self.lw_main)
        self.fileSystemModel.setReadOnly(True)
        self.fileFilter = self.fileSystemModel.filter()
        self.fileFilter_hidden = None
        home_path = QDir.home().absolutePath()
        self.le_path.setText(home_path)
        root = self.fileSystemModel.setRootPath(home_path)
        self.lw_main.setModel(self.fileSystemModel)
        self.lw_main.setRootIndex(root)
        self.lw_main.setWrapping(True)

        self.le_path.returnPressed.connect(self.on_pb_load_path_clicked)

        self.init_toolbar()
        self.bookmark_list = bookmark.get_bookmark()
        self.init_bookmark()
        self.session_list = set()
        self.last_open_file = set()

        self.isWindowsOS = sys.platform == "win32"
        self.lw_sidebar.itemDoubleClicked.connect(self.on_lw_sidebar_dbclicked)

        self.main_menu = QMenu()
        self.file_menu = QMenu()
        self.folder_menu = QMenu()
        self.toolbar_menu = toolbar_menu()
        self.file_popup_menu = file_menu()

        self.script_manager = script_manager()

    def init_bookmark(self):
        self.lw_sidebar.clear()
        if self.bookmark_list:
            for b in self.bookmark_list:
                self.add_sidebar_item(b)
        self.lw_sidebar.currentItemChanged.connect(self.on_lw_sidebar_clicked)

    def init_drivers(self):
        self.lw_sidebar.clear()
        if self.isWindowsOS:
            drivers = QDir.drives()
            for d in drivers:
                self.add_sidebar_item(d.absoluteFilePath())
        else:
            self.le_path.setText("/")
            self.on_pb_load_path_clicked()
            #             system('x-terminal-emulator --working-directory={} &'.format(self.le_path.text()))
            pass

    def init_session(self):
        print(self.session_list)
        self.lw_sidebar.clear()
        if self.session_list:
            for b in self.session_list:
                self.add_sidebar_item(b)
        self.lw_sidebar.currentItemChanged.connect(self.on_lw_sidebar_clicked)

    def init_toolbar(self):
        self.toolBar.addAction(QIcon(get_file_realpath("data/list-add.png")),
                               "新增")
        self.toolBar.addAction(
            QIcon(get_file_realpath("data/list-remove.png")), "删除")
        self.toolBar.addAction(QIcon(get_file_realpath("data/go-home.png")),
                               "主页")
        self.toolBar.addAction(QIcon(get_file_realpath("data/device.png")),
                               "设备")
        self.toolBar.addAction(
            QIcon(get_file_realpath("data/bookmark-book.png")), "收藏夹")
        self.toolBar.addAction(QIcon(get_file_realpath("data/edit-copy.png")),
                               "标签")
        self.toolBar.addAction(
            QIcon(get_file_realpath("data/history-time.png")), "最近打开的文件")
        self.toolBar.addAction(QIcon(get_file_realpath("data/folder.png")),
                               "显示文件夹").setCheckable(True)
        self.toolBar.addAction(QIcon(get_file_realpath("data/eye.png")),
                               "显示隐藏文件").setCheckable(True)
        self.toolBar.addAction(QIcon(get_file_realpath("data/terminal.png")),
                               "终端")
        self.toolBar.addAction(
            QIcon(get_file_realpath("data/view-list-tree.png")), "我的电脑")
        self.toolBar.addAction(QIcon(get_file_realpath("data/go-up.png")),
                               "返回上层")
        self.toolBar.addAction(QIcon(get_file_realpath("data/menu.png")), "菜单")
        self.toolBar.actionTriggered[QAction].connect(self.on_toolBar_clicked)

    def add_sidebar_item(self, path):
        item = None
        if not basename(path):
            item = QListWidgetItem(path)
        else:
            item = QListWidgetItem(basename(path))
        item.setData(-1, path)
        self.lw_sidebar.addItem(item)

    def go_home(self):
        list1 = QDir.drives()
        for l in list1:
            print(l.absolutePath())

        self.le_path.setText(QDir.home().absolutePath())
        self.on_pb_load_path_clicked()

    def on_toolBar_clicked(self, action):
        action_text = action.text()
        if action_text == "收藏夹":
            self.lb_sidebar.setText(action_text)
            self.init_bookmark()
        elif action_text == "标签":
            self.lb_sidebar.setText(action_text)
            self.init_session()
        elif action_text == "菜单":
            action = self.main_menu.exec_(toolbar_menu.menu_item,
                                          QCursor.pos())
            if action:
                self.toolbar_menu.handle_action(action)
        elif action_text == "最近打开的文件":
            self.lb_sidebar.setText(action_text)
            self.lw_sidebar.clear()
            for f in self.last_open_file:
                self.add_sidebar_item(f)
        elif action_text == "主页":
            self.go_home()
        elif action_text == "终端":
            if self.isWindowsOS:
                chdir(self.le_path.text())
                startfile("cmd.exe")
            else:
                system('x-terminal-emulator --working-directory={} &'.format(
                    self.le_path.text()))
        elif action_text == "设备":
            self.lb_sidebar.setText(action_text)
            self.init_drivers()
        elif action_text == "我的电脑":
            if self.isWindowsOS:
                print("explorer.exe '" + self.le_path.text() + "'")
                try:
                    startfile(self.le_path.text())
#                     system("start C:\Users\bkd")
                except Exception as e:
                    print(str(e))
            else:
                system('xdg-open ' + self.le_path.text())
        elif action_text == "返回上层":
            paren_dir = dirname(self.le_path.text())
            self.le_path.setText(paren_dir)
            self.on_pb_load_path_clicked()
        elif action_text == "显示隐藏文件":
            if action.isChecked():
                self.fileFilter_hidden = QDir.Hidden
                self.fileSystemModel.setFilter(self.fileFilter | QDir.Hidden)
            else:
                self.fileFilter_hidden = None
                self.fileSystemModel.setFilter(self.fileFilter)
        elif action_text == "显示文件夹":
            if action.isChecked():
                if self.fileFilter_hidden:
                    self.fileSystemModel.setFilter(QDir.Dirs | QDir.Hidden
                                                   | QDir.NoDot
                                                   | QDir.NoDotDot)
                else:
                    self.fileSystemModel.setFilter(QDir.Dirs | QDir.NoDot
                                                   | QDir.NoDotDot)
            else:
                self.fileSystemModel.setFilter(self.fileFilter)
        elif action_text == "新增":
            if self.lb_sidebar.text() == "收藏夹":
                self.add_sidebar_item(self.le_path.text())
                kdconfig.list_add("global", "bookmark", self.le_path.text())
            elif self.lb_sidebar.text() == "标签":
                self.session_list.add(self.le_path.text())
                self.add_sidebar_item(self.le_path.text())
                print(self.session_list)
        elif action_text == "删除":
            if self.lb_sidebar.text() == "收藏夹":
                print(self.lw_sidebar.currentRow())
                kdconfig.list_del("global", "bookmark", self.le_path.text())
                self.bookmark_list.discard(self.le_path.text())
                self.lw_sidebar.takeItem(self.lw_sidebar.currentRow())
                print(self.bookmark_list)
            elif self.lb_sidebar.text() == "标签":
                self.session_list.remove(self.le_path.text())

    @pyqtSlot()
    def on_lw_sidebar_clicked(self):
        cur_item = self.lw_sidebar.currentItem()
        if cur_item:
            cur_item_data = cur_item.data(-1)
            if self.lb_sidebar.text() == "最近打开的文件":
                self.statusbar.showMessage(cur_item_data)
            else:
                self.le_path.setText(cur_item_data)
                self.on_pb_load_path_clicked()

    @pyqtSlot()
    def on_lw_sidebar_dbclicked(self):
        cur_item = self.lw_sidebar.currentItem()
        if cur_item:
            cur_item_data = cur_item.data(-1)
            self.statusbar.showMessage(cur_item_data)
            if self.isWindowsOS:
                startfile(cur_item_data)

    @pyqtSlot()
    def on_pb_load_path_clicked(self):
        root = self.fileSystemModel.setRootPath(self.le_path.text())
        self.lw_main.setRootIndex(root)

    def eventFilter(self, qobject, qevent):
        qtype = qevent.type()
        #         print("qtype",qtype)
        #         print("qobject",qobject)
        if qtype == 82:
            counter = len(self.lw_main.selectedIndexes())

            #             右键所在的位置又可能是空白处
            if counter == 1:
                i = self.lw_main.indexAt(QCursor.pos())
                if not i.isValid():
                    print("valid")
                    counter = len(self.lw_main.selectedIndexes())
                else:
                    print("invalid")

#             处理选中的文件
            if counter >= 1:
                action = self.file_menu.exec_(self.file_popup_menu.menu_item,
                                              QCursor.pos())
                if action:
                    file_list = [
                        self.fileSystemModel.itemData(i)[0]
                        for i in self.lw_main.selectedIndexes()
                    ]
                    self.script_manager.run_script(action.text(),
                                                   self.le_path.text(),
                                                   file_list)
#             选中空白处,返回上层目录
            else:
                parent_dir = dirname(self.le_path.text())
                if parent_dir == self.le_path.text() and self.isWindowsOS:
                    pass
                else:
                    self.le_path.setText(parent_dir)
                    self.on_pb_load_path_clicked()
        return False

    @pyqtSlot()
    def on_lw_main_clicked(self):
        #         不连续的多选模式,不处理文件和文件夹,只选中当前项目
        if self.lw_main.selectionMode() == Qt.ControlModifier:
            return

        cur_item_index = self.lw_main.currentIndex()
        cur_item1 = self.fileSystemModel.itemData(cur_item_index)
        cur_item = cur_item1[0]
        print("cur_item", cur_item1)
        sub_path = join(self.le_path.text(), cur_item)
        print("sub_path:" + sub_path)
        if isdir(str(sub_path)):
            print(sub_path + "is a dir")
            self.le_path.setText(sub_path)
            self.on_pb_load_path_clicked()
        elif isfile(str(sub_path)):
            print(sub_path + " is a file")
        else:
            print(type(sub_path))

    @pyqtSlot()
    def on_lw_main_dbclicked(self):
        cur_item_index = self.lw_main.currentIndex()
        cur_item1 = self.fileSystemModel.itemData(cur_item_index)
        cur_item = cur_item1[0]
        sub_path = join(self.le_path.text(), cur_item)
        if isfile(sub_path):
            self.last_open_file.add(sub_path)
            if self.isWindowsOS:
                startfile(sub_path)
            else:
                subprocess.call(["xdg-open", sub_path])
            self.showMinimized()

#     def keyPressEvent(self, event):
#         curKey = event.key()
#         print("按下:" + str(event.key()))
#         if curKey == Qt.Key_M:
#             self.last_open_dir.append(self.le_path)
#             print(self.last_open_dir)
#         return False

    def show_statusbar_msg(self, msg):
        self.statusbar.showMessage(msg)

#     拦截快捷键

    def keyPressEvent(self, event):
        key = event.key()
        print("按下:" + str(event.key()))
        if event.modifiers() == Qt.ControlModifier and key == Qt.Key_C:
            file_list = [
                self.fileSystemModel.itemData(i)[0]
                for i in self.lw_main.selectedIndexes()
            ]
            self.script_manager.run_script("复制", self.le_path.text(),
                                           file_list)
        elif event.modifiers() == Qt.ControlModifier and key == Qt.Key_V:
            self.script_manager.run_script("粘贴", self.le_path.text(), None)
        elif key == Qt.Key_F2:
            file_list = [
                self.fileSystemModel.itemData(self.lw_main.currentIndex())[0]
            ]
            self.script_manager.run_script("重命名", self.le_path.text(),
                                           file_list)
        elif event.modifiers() == Qt.ControlModifier and key == Qt.Key_D:
            self.lb_sidebar.setText("收藏夹")
            self.add_sidebar_item(self.le_path.text())
            kdconfig.list_add("global", "bookmark", self.le_path.text())
        elif event.modifiers() == Qt.ControlModifier and key == Qt.Key_T:
            self.lb_sidebar.setText("标签")
            self.session_list.add(self.le_path.text())
            self.add_sidebar_item(self.le_path.text())
        elif event.modifiers() == Qt.ControlModifier and key == None:
            self.lw_main.setSelectionMode(QAbstractItemView.ExtendedSelection)
            print("duoxuan")
        elif event.modifiers() == Qt.ShiftModifier and key == None:
            self.lw_main.setSelectionMode(
                QAbstractItemView.ContiguousSelection)
            print("shit 多选")