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)
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)
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 多选")