import os import sys from decimal import * import pathlib from PySide2.QtWidgets import * from PySide2.QtCore import * from PySide2.QtGui import * from ui.ui_AddPath import Ui_AddPathWindow from ui.addressBar.addressbar import BreadcrumbsAddressBar from ui.file_browser import file_list from ui.file_browser.PathObject import PathObject from ui.file_browser.filewidget import FileWidget from ui.file_browser.FileObject import FileObject class Category: def __init__(self, text, simple='') -> None: self.text = text self.simple = simple if not self.simple: self.simple = text class FolderCategory: Search_Path = Category("Search Path", "SearchPath") class FileCategory: Filelist = Category('Filelist', 'Filelist') Netlist = Category('Netlist', 'Netlist') Verilog_2001 = Category('Verilog 2001', 'V2001') Verilog_2005 = Category("Verilog 2005", 'V2005') SystemVerilog_2005 = Category("SystemVerilog 2005", "SV2005") SystemVerilog_2009 = Category("SystemVerilog 2009", "SV2009") SystemVerilog_2012 = Category("SystemVerilog 2012", "SV2012") all_category = [Filelist, Netlist, Verilog_2001, Verilog_2005, SystemVerilog_2005, SystemVerilog_2009, SystemVerilog_2012] def get_category(text): for category in FileCategory.all_category: if category.text == text: return category def get_all_text()->list: return [category.text for category in FileCategory.all_category] class AddPathWindow(Ui_AddPathWindow, QDialog): add_file_sig = Signal(str,str) def __init__(self, parent, path) -> None: super().__init__(parent) self.setupUi(self) self.file_suffix = ["All Directories(*.*)"] self.init(parent, path) def init(self, parent, path): self.setWindowTitle("Add Path") self.Combobox_FileType.addItems(self.file_suffix) self.Combobox_FileType.currentIndexChanged.connect(lambda index:self.show_file_list()) self.path_obj = PathObject(path) self.bnt_Apply.clicked.connect(self.apply) self.bnt_OK.clicked.connect(self.click_ok) self.init_file_browser(path) self.fileTable.clearSelection() self.fileTable.setCurrentIndex(QModelIndex()) self.move(parent.x()+(parent.width()-self.width())/2 + self.width()*0.8,parent.y()+(parent.height()-self.height())/2) self.show() def init_file_browser(self, path): # 表格随窗口适应大小 self.fileTable.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.fileTable.cellDoubleClicked.connect(self.double_click) self.fileTable.mousePressEvent = self.click_table_widget self.address_bar = BreadcrumbsAddressBar(self) self.address_bar.path_selected.connect(self.open_folder) self.address_bar.path_error.connect(lambda path: self.address_error_connect("No such file or directory", path.name)) self.address_bar.listdir_error.connect(lambda path: self.address_error_connect("Permission denied", path.name)) self.address_bar.set_path(path) self.verticalLayout_3.insertWidget(0, self.address_bar) def open_folder(self, dir): self.path_obj.set(dir) self.show_file_list() def show_file_list(self): _, self.dirs = file_list.get_files_dirs(self.path_obj) self.fileTable.setRowCount(0) height = self.fileTable.verticalHeader().defaultSectionSize() for dir in self.dirs: row = self.fileTable.rowCount() self.fileTable.insertRow(row) fwidget = FileWidget(dir, "Folder", height) self.fileTable.setCellWidget(row, 0, fwidget) def address_error_connect(self, error, path): self.path_error_popup(error, path) self.address_bar._show_address_field(True) self.address_bar.line_address.deselect() self.address_bar.line_address.insert('/') def path_error_popup(self, error='', path=''): msg = QMessageBox(self) msg.setWindowTitle("Error") msg.setText(error) msg.setIcon(QMessageBox.Critical) msg.move(self.x()+(self.width()-msg.width())/2,self.y()+(self.height()-msg.height())/2) msg.exec_() # 点击空白处取消选择 def click_table_widget(self, event:QMouseEvent): p = event.pos() index = self.fileTable.indexAt(p) if index.row() == -1: self.fileTable.clearSelection() self.fileTable.setCurrentIndex(QModelIndex()) else: QTableWidget.mousePressEvent(self.fileTable, event) def double_click(self, row, column): if column != 0: return widg:FileWidget = self.fileTable.cellWidget(row, column) name = widg.get_text() abs_path = os.path.join(self.path_obj.pathtext, name) if os.path.isfile(abs_path): self.open_file(abs_path) # 这里不能用 elif os.path.isdir(abs_path) ,因为假如目录没有权限访问,即便它是个目录也会返回 False else: self.address_bar.set_path(abs_path) def current_select_path(self): row = self.fileTable.currentRow() if row < 0: return str(self.address_bar.path_) widg:FileWidget = self.fileTable.cellWidget(row, 0) filename = widg.get_text() abs_path = os.path.join(self.path_obj.pathtext, filename) return abs_path def apply(self): abs_path = self.current_select_path() if not abs_path: return if not os.path.isdir(abs_path): return self.add_file_sig.emit(FolderCategory.Search_Path.text, abs_path) self.fileTable.clearSelection() self.fileTable.setCurrentIndex(QModelIndex()) def click_ok(self): self.apply() self.close() class AddFileWindow(AddPathWindow): def __init__(self, parent, path) -> None: super().__init__(parent, path) def init(self,parent, path): self.setWindowTitle("Add File") self.file_type = [".v", ".sv", ".f", ".lst", ".list"] self.file_suffix = ["Supported Files(%s)" % " ".join(['*'+str(s) for s in self.file_type]), "All Files(*.*)"] super().init(parent, path) self.verticalLayout_2 = QVBoxLayout() self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalSpacer_2 = QSpacerItem(20, 31, QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout_2.addItem(self.verticalSpacer_2) file_type = FileCategory.get_all_text() for t in file_type: radio = QRadioButton(self) radio.setObjectName(t) radio.setText(t) self.verticalLayout_2.addWidget(radio) if t == FileCategory.Verilog_2005.text: radio.setChecked(True) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(self.verticalSpacer) self.horizontalLayout.insertLayout(0, self.verticalLayout_2) def path_select(self, path): self.path_obj.set(path) self.open_folder(path) def files_filter(self, files): if self.Combobox_FileType.currentText() == "All Files(*.*)": return files filt_res = [] for i in range(len(files)): _,type =os.path.splitext(files[i]) if type in self.file_type: filt_res.append(files[i]) return filt_res def show_file_list(self): all_files, self.dirs = file_list.get_files_dirs(self.path_obj) self.files = self.files_filter(all_files) self.fileTable.setRowCount(0) height = self.fileTable.verticalHeader().defaultSectionSize() for dir in self.dirs: row = self.fileTable.rowCount() self.fileTable.insertRow(row) fwidget = FileWidget(dir, "Folder", height) self.fileTable.setCellWidget(row, 0, fwidget) for f in self.files: row = self.fileTable.rowCount() self.fileTable.insertRow(row) fwidget = FileWidget(f, "File", height) self.fileTable.setCellWidget(row, 0, fwidget) def current_radio_text(self): file_type = None for children in self.findChildren(QRadioButton): children:QRadioButton if children.isChecked(): file_type = children.text() return file_type def apply(self): abs_path = self.current_select_path() if not abs_path: return if not os.path.isfile(abs_path): return text = self.current_radio_text() self.add_file_sig.emit(text, abs_path) self.fileTable.clearSelection() self.fileTable.setCurrentIndex(QModelIndex()) def click_ok(self): self.apply() self.close() def open_file(self, file): self.apply() self.close()