def __initFileTreeView__(self, model): treeView = QTreeView() treeView.setIndentation(20) treeView.setSortingEnabled(True) treeView.setMinimumWidth(100) treeView.setModel(model) treeView.setRootIndex(model.index(r'C:')) for i in range(1, 5): treeView.hideColumn(i) return treeView
class Snippets(QDialog): def __init__(self, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.NonModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("Save")) self.revertButton = QPushButton(self.tr("Revert")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) self.newFolderButton = QPushButton("New Folder") self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QPlainTextEdit() self.resetting = False self.columns = 3 self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetEditsPending = False self.clearSelection() #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.revertButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addWidget(self.currentFileLabel) vlayout.addWidget(self.edit) vlayout.addLayout(description) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" self.settings = QSettings("Vector 35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.revertButton.clicked.connect(self.loadSnippet) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) self.newFolderButton.clicked.connect(self.newFolder) def registerAllSnippets(self): for action in list(filter(lambda x: x.startswith("Snippet\\"), UIAction.getAllRegisteredActions())): UIActionHandler.globalActions().unbindAction(action) UIAction.unregisterAction(action) for snippet in includeWalk(snippetPath, ".py"): (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(snippet) if not snippetDescription: actionText = "Snippet\\" + snippet else: actionText = "Snippet\\" + snippetDescription UIAction.registerAction(actionText, snippetKey) UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode))) def clearSelection(self): self.keySequenceEdit.clear() self.currentHotkey = QKeySequence() self.currentHotkeyLabel.setText("") self.currentFileLabel.setText("") self.snippetDescription.setText("") self.edit.setPlainText("") def reject(self): self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry()) if self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?")) if question != QMessageBox.StandardButton.Yes: return self.accept() def newFolder(self): (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: ")) if ok and folderName: index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): QDir(selection).mkdir(folderName) else: QDir(snippetPath).mkdir(folderName) def selectFile(self, new, old): if (self.resetting): self.resetting = False return newSelection = self.files.filePath(new.indexes()[0]) if QFileInfo(newSelection).isDir(): self.clearSelection() return if old.length() > 0: oldSelection = self.files.filePath(old.indexes()[0]) if not QFileInfo(oldSelection).isDir() and self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?")) if question != QMessageBox.StandardButton.Yes: self.resetting = True self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) return False self.currentFile = newSelection self.loadSnippet() def loadSnippet(self): self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName()) log_debug("Loading %s as a snippet." % self.currentFile) (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile) self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("") self.keySequenceEdit.setKeySequence(snippetKey[0]) if len(snippetKey) != 0 else self.keySequenceEdit.setKeySequence(QKeySequence("")) self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("") def newFileDialog(self): (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: ")) if ok and snippetName: if not snippetName.endswith(".py"): snippetName += ".py" index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): open(os.path.join(selection, snippetName), "w").close() else: open(os.path.join(snippetPath, snippetName), "w").close() log_debug("Snippet %s created." % snippetName) def deleteSnippet(self): selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row snippetName = self.files.fileName(selection) question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName) if (question == QMessageBox.StandardButton.Yes): log_debug("Deleting snippet %s." % snippetName) self.clearSelection() self.files.remove(selection) def snippetChanged(self): if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()): return False (snippetDescription, snippetKey, snippetCode) = loadSnippetFromFile(self.currentFile) if (not snippetCode): return False if len(snippetKey) == 0 and not self.keySequenceEdit.keySequence().isEmpty(): return True if len(snippetKey) != 0 and snippetKey[0] != self.keySequenceEdit.keySequence(): return True return self.edit.toPlainText() != snippetCode or \ self.snippetDescription.text() != snippetDescription def save(self): log_debug("Saving snippet %s" % self.currentFile) outputSnippet = open(self.currentFile, "w") outputSnippet.write("#" + self.snippetDescription.text() + "\n") outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n") outputSnippet.write(self.edit.toPlainText()) outputSnippet.close() self.registerAllSnippets() def clearHotkey(self): self.keySequenceEdit.clear()
class Snippets(QDialog): def __init__(self, context, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("&Save")) self.saveButton.setShortcut(QKeySequence(self.tr("Ctrl+S"))) self.runButton = QPushButton(self.tr("&Run")) self.runButton.setShortcut(QKeySequence(self.tr("Ctrl+R"))) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) #self.newFolderButton = QPushButton("New Folder") self.browseButton = QPushButton("Browse Snippets") self.browseButton.setIcon(QIcon.fromTheme("edit-undo")) self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QCodeEditor(HIGHLIGHT_CURRENT_LINE=False, SyntaxHighlighter=PythonHighlighter) self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.context = context self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() #treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.browseButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.runButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" #Because you can't trust QT to do the right thing here if (sys.platform == "darwin"): self.settings = QSettings("Vector35", "Snippet Editor") else: self.settings = QSettings("Vector 35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.runButton.clicked.connect(self.run) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) #self.newFolderButton.clicked.connect(self.newFolder) self.browseButton.clicked.connect(self.browseSnippets) if self.settings.contains("ui/snippeteditor/selected"): selectedName = self.settings.value("ui/snippeteditor/selected") self.tree.selectionModel().select(self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) if self.tree.selectionModel().hasSelection(): self.selectFile(self.tree.selectionModel().selection(), None) self.edit.setFocus() cursor = self.edit.textCursor() cursor.setPosition(self.edit.document().characterCount()-1) self.edit.setTextCursor(cursor) else: self.readOnly(True) else: self.readOnly(True) @staticmethod def registerAllSnippets(): for action in list(filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())): if action == "Snippets\\Snippet Editor...": continue UIActionHandler.globalActions().unbindAction(action) Menu.mainMenu("Tools").removeAction(action) UIAction.unregisterAction(action) for snippet in includeWalk(snippetPath, ".py"): snippetKeys = None (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet) actionText = actionFromSnippet(snippet, snippetDescription) if snippetCode: if snippetKeys == None: UIAction.registerAction(actionText) else: UIAction.registerAction(actionText, snippetKeys) UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode))) Menu.mainMenu("Tools").addAction(actionText, "Snippets") def clearSelection(self): self.keySequenceEdit.clear() self.currentHotkey = QKeySequence() self.currentHotkeyLabel.setText("") self.currentFileLabel.setText("") self.snippetDescription.setText("") self.edit.clear() self.tree.clearSelection() self.currentFile = "" def reject(self): self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry()) if self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?")) if question != QMessageBox.StandardButton.Yes: return self.accept() def browseSnippets(self): url = QUrl.fromLocalFile(snippetPath) QDesktopServices.openUrl(url); def newFolder(self): (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: ")) if ok and folderName: index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): QDir(selection).mkdir(folderName) else: QDir(snippetPath).mkdir(folderName) def selectFile(self, new, old): if (self.resetting): self.resetting = False return if len(new.indexes()) == 0: self.clearSelection() self.currentFile = "" self.readOnly(True) return newSelection = self.files.filePath(new.indexes()[0]) self.settings.setValue("ui/snippeteditor/selected", newSelection) if QFileInfo(newSelection).isDir(): self.readOnly(True) self.clearSelection() self.currentFile = "" return if old and old.length() > 0: oldSelection = self.files.filePath(old.indexes()[0]) if not QFileInfo(oldSelection).isDir() and self.snippetChanged(): question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?")) if question != QMessageBox.StandardButton.Yes: self.resetting = True self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) return False self.currentFile = newSelection self.loadSnippet() def loadSnippet(self): self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName()) (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("") self.keySequenceEdit.setKeySequence(snippetKeys) if snippetKeys else self.keySequenceEdit.setKeySequence(QKeySequence("")) self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("") self.readOnly(False) def newFileDialog(self): (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: ")) if ok and snippetName: if not snippetName.endswith(".py"): snippetName += ".py" index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): path = os.path.join(selection, snippetName) else: path = os.path.join(snippetPath, snippetName) self.readOnly(False) open(path, "w").close() self.tree.setCurrentIndex(self.files.index(path)) log_debug("Snippet %s created." % snippetName) def readOnly(self, flag): self.keySequenceEdit.setEnabled(not flag) self.snippetDescription.setReadOnly(flag) self.edit.setReadOnly(flag) if flag: self.snippetDescription.setDisabled(True) self.edit.setDisabled(True) else: self.snippetDescription.setEnabled(True) self.edit.setEnabled(True) def deleteSnippet(self): selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row snippetName = self.files.fileName(selection) question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName) if (question == QMessageBox.StandardButton.Yes): log_debug("Deleting snippet %s." % snippetName) self.clearSelection() self.files.remove(selection) self.registerAllSnippets() def snippetChanged(self): if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()): return False (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) if snippetKeys == None and not self.keySequenceEdit.keySequence().isEmpty(): return True if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence().toString(): return True return self.edit.toPlainText() != snippetCode or \ self.snippetDescription.text() != snippetDescription def save(self): log_debug("Saving snippet %s" % self.currentFile) outputSnippet = codecs.open(self.currentFile, "w", "utf-8") outputSnippet.write("#" + self.snippetDescription.text() + "\n") outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n") outputSnippet.write(self.edit.toPlainText()) outputSnippet.close() self.registerAllSnippets() def run(self): if self.context == None: log_warn("Cannot run snippets outside of the UI at this time.") return if self.snippetChanged(): question = QMessageBox.question(self, self.tr("Confirm"), self.tr("You have unsaved changes, must save first. Save?")) if (question == QMessageBox.StandardButton.No): return else: self.save() actionText = actionFromSnippet(self.currentFile, self.snippetDescription.text()) UIActionHandler.globalActions().executeAction(actionText, self.context) log_debug("Saving snippet %s" % self.currentFile) outputSnippet = codecs.open(self.currentFile, "w", "utf-8") outputSnippet.write("#" + self.snippetDescription.text() + "\n") outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n") outputSnippet.write(self.edit.toPlainText()) outputSnippet.close() self.registerAllSnippets() def clearHotkey(self): self.keySequenceEdit.clear()
class FileSystemWidget(QWidget): def __init__(self, parent, *args, **kwargs): super().__init__(*args, **kwargs) self.currentRootPath = '/' self.currentPath = QDir.currentPath() self.mainWindow = parent self.chooseDirAction = QAction(IconFactory.getIcon('folder'), 'Root directory', self, statusTip="Change root directory", triggered=self.chooseRootDir) self.showOFAction = QAction(IconFactory.getIcon('filter_alt'), 'Show only FITS files', self, statusTip="Show only FITS/all files", triggered=self.showOFFiles) self.showOFAction.setCheckable(True) self.showOFAction.toggled.connect(self.showOFFiles) self.chooseDirBtn = QToolButton() self.chooseDirBtn.setDefaultAction(self.chooseDirAction) self.showOFBtn = QToolButton() self.showOFBtn.setDefaultAction(self.showOFAction) iconlayout = QHBoxLayout() iconlayout.setAlignment(Qt.AlignLeft) iconlayout.addWidget(self.chooseDirBtn) iconlayout.addWidget(self.showOFBtn) self.viewsSplitter = QSplitter(Qt.Horizontal) self.viewsSplitter.splitterMoved.connect(self.splitterMoved) self.dirsModel = QFileSystemModel(self) self.dirsModel.setOption(QFileSystemModel.DontWatchForChanges, True) self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.dirsModel.setNameFilterDisables(False) self.dirs = QTreeView() self.dirs.setModel(self.dirsModel) self.dirs.hideColumn(1) self.dirs.hideColumn(2) self.dirs.hideColumn(3) self.dirs.clicked.connect(self.onDirsClick) self.dirs.doubleClicked.connect(self.onDirsDoubleClick) self.filesModel = QFileSystemModel(self) self.filesModel.setOption(QFileSystemModel.DontWatchForChanges, True) self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.filesModel.setNameFilterDisables(False) self.files = QListView() self.files.setModel(self.filesModel) self.files.doubleClicked.connect(self.onFilesDoubleClick) self.viewsSplitter.addWidget(self.dirs) self.viewsSplitter.addWidget(self.files) viewslayout = QHBoxLayout() viewslayout.addWidget(self.viewsSplitter) layout = QVBoxLayout() layout.addLayout(iconlayout) layout.addLayout(viewslayout) self.setLayout(layout) self.dirsModel.setRootPath(self.currentRootPath) self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath)) index = self.dirsModel.index(self.currentPath) self.dirs.setCurrentIndex(index) self.dirs.setExpanded(index, True) self.filesModel.setRootPath(self.currentPath) self.files.setRootIndex(self.filesModel.index(self.currentPath)) def splitterMoved(self, pos, index): if pos == 0: self.filesModel.setFilter(QDir.NoDot | QDir.AllEntries | QDir.DirsFirst | QDir.Type) elif pos == self.viewsSplitter.width( ) - self.viewsSplitter.handleWidth(): self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries) else: self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) def onDirsClick(self, item): index = self.dirs.selectedIndexes()[0] info = self.dirsModel.fileInfo(index) if info.isDir(): self.currentPath = info.filePath() self.files.setRootIndex( self.filesModel.setRootPath(info.filePath())) def onDirsDoubleClick(self, item): index = self.dirs.selectedIndexes()[0] info = self.dirsModel.fileInfo(index) if info.isDir(): self.currentPath = info.filePath() self.files.setRootIndex( self.filesModel.setRootPath(info.filePath())) else: self.mainWindow.open_fits(info.filePath()) def onFilesDoubleClick(self, item): index = self.files.selectedIndexes()[0] info = self.filesModel.fileInfo(index) if info.isDir(): self.setPath(info.filePath()) else: try: self.mainWindow.open_fits(info.filePath()) except FileNotFoundError: self.setPath(self.currentPath) # refesh maybe? def setPath(self, path): self.currentPath = path index = self.dirsModel.index(self.currentPath) self.dirs.setCurrentIndex(index) self.dirs.setExpanded(index, True) self.files.setRootIndex(self.filesModel.setRootPath(self.currentPath)) def chooseRootDir(self): dir = QFileDialog.getExistingDirectory(self, 'Select directory') if dir: self.setRootPath(dir) def setRootPath(self, dir): self.currentRootPath = dir self.dirsModel.setRootPath(self.currentRootPath) self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath)) self.setPath(self.currentRootPath) def showOFFiles(self): if self.showOFAction.isChecked(): self.dirsModel.setNameFilters(["*.FITS", "*.fits"]) self.filesModel.setNameFilters(["*.FITS", "*.fits"]) else: self.dirsModel.setNameFilters(["*"]) self.filesModel.setNameFilters(["*"]) def writeSettings(self, settings): settings.beginGroup("fileWidget") settings.setValue('splitterGeometry', self.viewsSplitter.saveGeometry()) settings.setValue('splitterState', self.viewsSplitter.saveState()) settings.setValue('rootPath', self.currentRootPath) settings.setValue('path', self.currentPath) settings.endGroup() def readSettings(self, settings): settings.beginGroup("fileWidget") self.viewsSplitter.restoreGeometry(settings.value("splitterGeometry")) self.viewsSplitter.restoreState(settings.value("splitterState")) rootPath = settings.value("rootPath") path = settings.value("path") settings.endGroup() if rootPath is None: rootPath = '/' self.setRootPath(rootPath) if path is None: path = QDir.currentPath() self.setPath(path) self.splitterMoved(self.viewsSplitter.handle(1).pos().x(), 0)
class SVDBrowser(QDialog): def __init__(self, context, parent=None): super(SVDBrowser, self).__init__(parent) QWebEngineProfile.defaultProfile().downloadRequested.connect( self.on_downloadRequested) # Create widgets #self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("SVD Browser")) self.closeButton = QPushButton(self.tr("Close")) self.setWindowTitle(self.title.text()) self.browseButton = QPushButton("Browse SVD Folder") self.deleteSvdButton = QPushButton("Delete") self.applySvdButton = QPushButton("Apply SVD") self.view = QWebEngineView() url = "https://developer.arm.com/tools-and-software/embedded/cmsis/cmsis-search" self.view.load(QUrl(url)) self.columns = 3 self.context = context self.currentFileLabel = QLabel() self.currentFile = "" #Files self.files = QFileSystemModel() self.files.setRootPath(svdPath) self.files.setNameFilters(["*.svd", "*.patched"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(svdPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode( x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() #treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.browseButton) treeButtons.addWidget(self.applySvdButton) treeButtons.addWidget(self.deleteSvdButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.closeButton) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addWidget(self.view) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showMaximized() #Fixes bug that maximized windows are "stuck" #Because you can't trust QT to do the right thing here # Set dialog layout self.setLayout(hlayout) # Add signals self.closeButton.clicked.connect(self.close) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.applySvdButton.clicked.connect(self.applySvd) self.deleteSvdButton.clicked.connect(self.deleteSvd) self.browseButton.clicked.connect(self.browseSvd) def browseSvd(self): url = QUrl.fromLocalFile(svdPath) QDesktopServices.openUrl(url) def selectFile(self, new, old): if len(new.indexes()) == 0: self.tree.clearSelection() self.currentFile = "" return newSelection = self.files.filePath(new.indexes()[0]) if QFileInfo(newSelection).isDir(): self.tree.clearSelection() self.currentFile = "" return self.currentFile = newSelection def applySvd(self): selection = self.tree.selectedIndexes()[::self.columns][ 0] #treeview returns each selected element in the row svdName = self.files.fileName(selection) if (svdName != ""): question = QMessageBox.question( self, self.tr("Confirm"), self. tr(f"Confirm applying {svdName} to {os.path.basename(self.context.file.filename)} : " )) if (question == QMessageBox.StandardButton.Yes): log_debug("SVD Browser: Applying SVD %s." % svdName) load_svd(self.context, self.currentFile) self.close() def deleteSvd(self): selection = self.tree.selectedIndexes()[::self.columns][ 0] #treeview returns each selected element in the row svdName = self.files.fileName(selection) question = QMessageBox.question( self, self.tr("Confirm"), self.tr("Confirm deletion: ") + svdName) if (question == QMessageBox.StandardButton.Yes): log_debug("SVD Browser: Deleting SVD %s." % svdName) self.files.remove(selection) self.tree.clearSelection() def on_downloadRequested(self, download): old_path = download.url().path() # download.path() suffix = QFileInfo(old_path).suffix() if (suffix.lower() in ["zip", "svd", "pack", "patched"]): log_debug(f"SVD Browser: Downloading {str(download.url())}") if suffix.lower() == "svd" or suffix.lower() == "patched": download.setDownloadDirectory(svdPath) download.accept() else: with TemporaryDirectory() as tempfolder: log_debug( f"SVD Browser: Downloading pack/zip to {tempfolder}") fname = download.url().fileName() r = requests.get(download.url().toString(), allow_redirects=True) dlfile = os.path.join(tempfolder, fname) open(dlfile, "wb").write(r.content) ''' # TODO: See if the original QT Downloader can be fixed since it would # help with situations where the user entered credentials in the browser. download.setDownloadDirectory(tempfolder) download.accept() while not download.finished: import time time.sleep(100) ''' if fname.endswith(".zip") or fname.endswith(".pack"): destFolder = os.path.join(svdPath, os.path.splitext(fname)[0]) log_debug(f"SVD Browser: Creating {destFolder}") if not os.path.exists(destFolder): os.mkdir(destFolder) with ZipFile(dlfile, 'r') as zipp: for ifname in zipp.namelist(): if ifname.endswith(".svd"): info = zipp.getinfo(ifname) info.filename = os.path.basename( info.filename) log_debug( f"SVD Browser: Extracting {info.filename} from {ifname}" ) zipp.extract(info, path=destFolder) else: #Move file into place shutil.move(dlfile, svdPath) else: show_message_box( "Invalid file", "That download does not appear to be a valid SVD/ZIP/PACK file." ) download.cancel()