def addToMenu(self, menu): """ Register the menus specific to the InputTab. Input: menu[QMenu]: The menu to add the items to. """ self._open_action = WidgetUtils.addAction(menu, "Open", self._openInputFile, "Ctrl+O") recentMenu = menu.addMenu("Recently opened") self._recently_used_menu = RecentlyUsedMenu( recentMenu, "input/recentlyUsed", "input/maxRecentlyUsed", 20, ) self._recently_used_menu.selected.connect(self.setInputFile) self._save_action = WidgetUtils.addAction(menu, "Save", self._saveInputFile) self._save_as_action = WidgetUtils.addAction(menu, "Save As", self._saveInputFileAs) self._clear_action = WidgetUtils.addAction(menu, "Clear", self._clearInputFile) self._check_action = WidgetUtils.addAction(menu, "Check", self._checkInputFile, "Ctrl+K") self._view_file = WidgetUtils.addAction(menu, "View current input file", self._viewInputFile, "Ctrl+V", True) self._menus_initialized = True self._setMenuStatus()
def addToMenu(self, menu): """ Adds menu entries specific to the Arguments to the menubar. """ workingMenu = menu.addMenu("Recent &working dirs") self._recent_working_menu = RecentlyUsedMenu(workingMenu, "execute/recentWorkingDirs", "execute/maxRecentWorkingDirs", 20, ) self._recent_working_menu.selected.connect(self.setWorkingDir) self._workingDirChanged() exeMenu = menu.addMenu("Recent &executables") self._recent_exe_menu = RecentlyUsedMenu(exeMenu, "execute/recentExes", "execute/maxRecentExes", 20, ) self._recent_exe_menu.selected.connect(self.setExecutablePath) argsMenu = menu.addMenu("Recent &arguments") self._recent_args_menu = RecentlyUsedMenu(argsMenu, "execute/recentArgs", "execute/maxRecentArgs", 20, ) self._recent_args_menu.selected.connect(self._setExecutableArgs)
def addToMenu(self, menu): """ Adds menu entries specific to the Arguments to the menubar. """ workingMenu = menu.addMenu("Recent &working dirs") self._recent_working_menu = RecentlyUsedMenu(workingMenu, "execute/recentWorkingDirs", "execute/maxRecentWorkingDirs", 20, ) self._recent_working_menu.selected.connect(self.setWorkingDir) self._workingDirChanged() exeMenu = menu.addMenu("Recent &executables") self._recent_exe_menu = RecentlyUsedMenu(exeMenu, "execute/recentExes", "execute/maxRecentExes", 20, ) self._recent_exe_menu.selected.connect(self.setExecutablePath) argsMenu = menu.addMenu("Recent &arguments") self._recent_args_menu = RecentlyUsedMenu(argsMenu, "execute/recentArgs", "execute/maxRecentArgs", 20, ) self._recent_args_menu.selected.connect(self._setExecutableArgs) self._force_reload_action = WidgetUtils.addAction(menu, "Reload executable syntax", self._reload_syntax) self._force_reload_action.setEnabled(False)
def setUp(self): super(Tests, self).setUp() self.main_win = QtWidgets.QMainWindow() self.menubar = self.main_win.menuBar() self.test_menu = self.menubar.addMenu("Test recently used") self.ru_menu = RecentlyUsedMenu(self.test_menu, "test/recentlyUsed", "test/maxRecentlyUsed", 20) self.ru_menu.selected.connect(self.selected) self.name_selected = None
def addToMenu(self, menu): """ Adds menu entries specific to the Arguments to the menubar. """ workingMenu = menu.addMenu("Recent &working dirs") self._recent_working_menu = RecentlyUsedMenu( workingMenu, "execute/recentWorkingDirs", "execute/maxRecentWorkingDirs", 20, ) self._recent_working_menu.selected.connect(self.setWorkingDir) self._workingDirChanged() exeMenu = menu.addMenu("Recent &executables") self._recent_exe_menu = RecentlyUsedMenu( exeMenu, "execute/recentExes", "execute/maxRecentExes", 20, ) self._recent_exe_menu.selected.connect(self.setExecutablePath) argsMenu = menu.addMenu("Recent &arguments") self._recent_args_menu = RecentlyUsedMenu( argsMenu, "execute/recentArgs", "execute/maxRecentArgs", 20, ) self._recent_args_menu.selected.connect(self._setExecutableArgs) self._force_reload_action = WidgetUtils.addAction( menu, "Reload executable syntax", self._reload_syntax) self._force_reload_action.setEnabled(False)
class Tests(Testing.PeacockTester): qapp = QtWidgets.QApplication([]) def setUp(self): super(Tests, self).setUp() settings = QSettings() settings.clear() self.main_win = QtWidgets.QMainWindow() self.menubar = self.main_win.menuBar() self.test_menu = self.menubar.addMenu("Test recently used") self.ru_menu = RecentlyUsedMenu(self.test_menu, "test/recentlyUsed", "test/maxRecentlyUsed", 20) self.ru_menu.selected.connect(self.selected) self.name_selected = None def selected(self, name): self.name_selected = name def test_RecentlyUsedMenu(self): self.assertEqual(self.ru_menu._values, []) self.assertEqual(self.ru_menu._menu.actions(), []) self.ru_menu.update("test_entry") self.assertEqual(self.ru_menu._values, ["test_entry"]) self.assertEqual(len(self.ru_menu._menu.actions()), 1) self.ru_menu.removeEntry("test_entry") self.assertEqual(self.ru_menu._values, []) self.assertEqual(self.ru_menu._menu.actions(), []) self.ru_menu.update("test_entry") self.assertEqual(self.ru_menu._values, ["test_entry"]) self.assertEqual(len(self.ru_menu._menu.actions()), 1) self.ru_menu._menu.actions()[0].triggered.emit() self.assertEqual(self.name_selected, "test_entry") self.ru_menu.removeEntry("no_exist") self.assertEqual(self.ru_menu._values, ["test_entry"]) self.assertEqual(len(self.ru_menu._menu.actions()), 1)
def addToMenu(self, menu): """ Register the menus specific to the InputTab. Input: menu[QMenu]: The menu to add the items to. """ self._open_action = WidgetUtils.addAction(menu, "Open", self._openInputFile, "Ctrl+O") recentMenu = menu.addMenu("Recently opened") self._recently_used_menu = RecentlyUsedMenu(recentMenu, "input/recentlyUsed", "input/maxRecentlyUsed", 20, ) self._recently_used_menu.selected.connect(self.setInputFile) self._save_action = WidgetUtils.addAction(menu, "Save", self._saveInputFile) self._save_as_action = WidgetUtils.addAction(menu, "Save As", self._saveInputFileAs) self._clear_action = WidgetUtils.addAction(menu, "Clear", self._clearInputFile) self._check_action = WidgetUtils.addAction(menu, "Check", self._checkInputFile, "Ctrl+K") self._view_file = WidgetUtils.addAction(menu, "View current input file", self._viewInputFile, "Ctrl+V", True) self._menus_initialized = True self._setMenuStatus()
class InputFileEditorPlugin(InputFileEditor, Plugin): """ The widget to edit the input file. In addition to InputFileEditor, this class adds menus and is available as a Plugin. """ def __init__(self, **kwds): super(InputFileEditorPlugin, self).__init__(**kwds) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self._menus_initialized = False self._recently_used_menu = None self._save_action = None self._open_action = None self._save_as_action = None self._clear_action = None self._check_action = None self._view_file = None self.check_widget = CheckInputWidget() self.check_widget.needInputFile.connect(self.writeInputFile) self.check_widget.hide() self.blockChanged.connect(self._updateChanged) self.input_file_view = QPlainTextEdit() self.input_file_view.setReadOnly(True) self.input_file_view.setWindowFlags(QtCore.Qt.Window) self.input_file_view.resize(640, 480) self.has_changed = False self._preferences.addInt("input/maxRecentlyUsed", "Max number of input files", 20, 1, 50, "Set the maximum number of recent input files that have been used.", ) self.setup() def _updateChanged(self, block, tree): self.has_changed = True def _askToSave(self, app_info, reason): if self.has_changed and app_info.valid() and self.tree and self.tree.input_filename and self.tree.incompatibleChanges(app_info): msg = "%s\nYou have unsaved changes in your input file, do you want to save?" % reason reply = QMessageBox.question(self, "Save?", msg, QMessageBox.Save, QMessageBox.Discard) if reply == QMessageBox.Save: self._saveInputFile() def executableInfoChanged(self, app_info): self._askToSave(app_info, "Reloading syntax from executable.") super(InputFileEditorPlugin, self).executableInfoChanged(app_info) self._setMenuStatus() self.has_changed = False def setInputFile(self, input_file): self._askToSave(self.tree.app_info, "Changing input files.") val = super(InputFileEditorPlugin, self).setInputFile(input_file) if self._menus_initialized: path = os.path.abspath(input_file) if os.path.exists(path): self._recently_used_menu.update(path) else: self._recently_used_menu.removeEntry(path) self._setMenuStatus() self.has_changed = False return val def _openInputFile(self): """ Ask the user what input file to open. """ input_name, other = QFileDialog.getOpenFileName(self, "Choose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) success = self.setInputFile(input_name) if success: self._recently_used_menu.update(input_name) else: self._recently_used_menu.removeEntry(input_name) def _saveInputFile(self): """ Save the current input tree to the current filename. """ self.writeInputFile(self.tree.input_filename) self.has_changed = False def _saveInputFileAs(self): """ Ask the user what file to save the input tree to. """ input_name, other = QFileDialog.getSaveFileName(self, "Choose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) self.writeInputFile(input_name) self.setInputFile(input_name) self._recently_used_menu.update(input_name) self.has_changed = False def _checkInputFile(self): """ Show the input file check window. """ self.check_widget.show() self.check_widget.check(self.tree.app_info.path) def _viewInputFile(self): """ View the text of the current input tree. """ if self.input_file_view.isVisible(): self.input_file_view.hide() else: data = self.tree.getInputFileString() self.input_file_view.setPlainText(data) self.input_file_view.show() def _clearInputFile(self): self.tree.resetInputFile() self.tree.input_filename = None self.block_tree.setInputTree(self.tree) self.inputFileChanged.emit("") self._setMenuStatus() self.has_changed = False def _setMenuStatus(self): """ Set the status of the menus. """ if not self._menus_initialized: return enabled = self.tree.app_info.valid() if self.tree.input_filename: self._save_action.setEnabled(enabled) else: self._save_action.setEnabled(False) self._save_as_action.setEnabled(enabled) self._open_action.setEnabled(enabled) self._recently_used_menu.setEnabled(enabled) self._clear_action.setEnabled(enabled) self._check_action.setEnabled(enabled) self._view_file.setEnabled(enabled) def addToMenu(self, menu): """ Register the menus specific to the InputTab. Input: menu[QMenu]: The menu to add the items to. """ self._open_action = WidgetUtils.addAction(menu, "Open", self._openInputFile, "Ctrl+O") recentMenu = menu.addMenu("Recently opened") self._recently_used_menu = RecentlyUsedMenu(recentMenu, "input/recentlyUsed", "input/maxRecentlyUsed", 20, ) self._recently_used_menu.selected.connect(self.setInputFile) self._save_action = WidgetUtils.addAction(menu, "Save", self._saveInputFile) self._save_as_action = WidgetUtils.addAction(menu, "Save As", self._saveInputFileAs) self._clear_action = WidgetUtils.addAction(menu, "Clear", self._clearInputFile) self._check_action = WidgetUtils.addAction(menu, "Check", self._checkInputFile, "Ctrl+K") self._view_file = WidgetUtils.addAction(menu, "View current input file", self._viewInputFile, "Ctrl+V", True) self._menus_initialized = True self._setMenuStatus() def closing(self): self.check_widget.cleanup() def clearRecentlyUsed(self): if self._menus_initialized: self._recently_used_menu.clearValues() def onCurrentChanged(self, index): """ This is called when the tab is changed. If the block editor window is open we want to raise it to the front so it doesn't get lost. """ if index == self._index: if self.block_editor: self.block_editor.raise_()
class InputFileEditorPlugin(InputFileEditor, Plugin): """ The widget to edit the input file. In addition to InputFileEditor, this class adds menus and is available as a Plugin. """ def __init__(self, **kwds): super(InputFileEditorPlugin, self).__init__(**kwds) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self._menus_initialized = False self._recently_used_menu = None self._save_action = None self._open_action = None self._save_as_action = None self._clear_action = None self._check_action = None self._view_file = None self.check_widget = CheckInputWidget() self.check_widget.needInputFile.connect(self.writeInputFile) self.check_widget.hide() self.blockChanged.connect(self._updateChanged) self.input_file_view = QPlainTextEdit() self.input_file_view.setReadOnly(True) self.input_file_view.setWindowFlags(QtCore.Qt.Window) self.input_file_view.resize(640, 480) self.has_changed = False self._preferences.addInt( "input/maxRecentlyUsed", "Max number of input files", 20, 1, 50, "Set the maximum number of recent input files that have been used.", ) self.setup() def _updateChanged(self, block, tree): self.has_changed = True def _askToSave(self, app_info, reason): if self.has_changed and app_info.valid( ) and self.tree and self.tree.input_filename and self.tree.incompatibleChanges( app_info): msg = "%s\nYou have unsaved changes in your input file, do you want to save?" % reason reply = QMessageBox.question(self, "Save?", msg, QMessageBox.Save, QMessageBox.Discard) if reply == QMessageBox.Save: self._saveInputFile() def executableInfoChanged(self, app_info): self._askToSave(app_info, "Reloading syntax from executable.") super(InputFileEditorPlugin, self).executableInfoChanged(app_info) self._setMenuStatus() self.has_changed = False def setInputFile(self, input_file): self._askToSave(self.tree.app_info, "Changing input files.") val = super(InputFileEditorPlugin, self).setInputFile(input_file) if self._menus_initialized: path = os.path.abspath(input_file) if os.path.exists(path): self._recently_used_menu.update(path) else: self._recently_used_menu.removeEntry(path) self._setMenuStatus() self.has_changed = False return val def _openInputFile(self): """ Ask the user what input file to open. """ input_name, other = QFileDialog.getOpenFileName( self, "Choose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) success = self.setInputFile(input_name) if success: self._recently_used_menu.update(input_name) else: self._recently_used_menu.removeEntry(input_name) def _saveInputFile(self): """ Save the current input tree to the current filename. """ self.writeInputFile(self.tree.input_filename) self.has_changed = False def _saveInputFileAs(self): """ Ask the user what file to save the input tree to. """ input_name, other = QFileDialog.getSaveFileName( self, "Choose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) self.writeInputFile(input_name) self.setInputFile(input_name) self._recently_used_menu.update(input_name) self.has_changed = False def _checkInputFile(self): """ Show the input file check window. """ self.check_widget.show() self.check_widget.check(self.tree.app_info.path) def _viewInputFile(self): """ View the text of the current input tree. """ if self.input_file_view.isVisible(): self.input_file_view.hide() else: data = self.tree.getInputFileString() self.input_file_view.setPlainText(data) self.input_file_view.show() def _clearInputFile(self): self.tree.resetInputFile() self.tree.input_filename = None self.block_tree.setInputTree(self.tree) self.inputFileChanged.emit("") self._setMenuStatus() self.has_changed = False def _setMenuStatus(self): """ Set the status of the menus. """ if not self._menus_initialized: return enabled = self.tree.app_info.valid() if self.tree.input_filename: self._save_action.setEnabled(enabled) else: self._save_action.setEnabled(False) self._save_as_action.setEnabled(enabled) self._open_action.setEnabled(enabled) self._recently_used_menu.setEnabled(enabled) self._clear_action.setEnabled(enabled) self._check_action.setEnabled(enabled) self._view_file.setEnabled(enabled) def addToMenu(self, menu): """ Register the menus specific to the InputTab. Input: menu[QMenu]: The menu to add the items to. """ self._open_action = WidgetUtils.addAction(menu, "Open", self._openInputFile, "Ctrl+O") recentMenu = menu.addMenu("Recently opened") self._recently_used_menu = RecentlyUsedMenu( recentMenu, "input/recentlyUsed", "input/maxRecentlyUsed", 20, ) self._recently_used_menu.selected.connect(self.setInputFile) self._save_action = WidgetUtils.addAction(menu, "Save", self._saveInputFile) self._save_as_action = WidgetUtils.addAction(menu, "Save As", self._saveInputFileAs) self._clear_action = WidgetUtils.addAction(menu, "Clear", self._clearInputFile) self._check_action = WidgetUtils.addAction(menu, "Check", self._checkInputFile, "Ctrl+K") self._view_file = WidgetUtils.addAction(menu, "View current input file", self._viewInputFile, "Ctrl+V", True) self._menus_initialized = True self._setMenuStatus() def closing(self): self.check_widget.cleanup() def clearRecentlyUsed(self): if self._menus_initialized: self._recently_used_menu.clearValues() def onCurrentChanged(self, index): """ This is called when the tab is changed. If the block editor window is open we want to raise it to the front so it doesn't get lost. """ if index == self._index: if self.block_editor: self.block_editor.raise_()
class ExecuteOptionsPlugin(QWidget, Plugin): """ Handles setting the various arguments for running. Signals: executableChanged(str): Path of the new executable is emitted when changed executableInfoChanged(ExecutableInfo): Emitted when the executable path is changed workingDirChanged(str): Path of the current directory is changed """ executableChanged = pyqtSignal(str) executableInfoChanged = pyqtSignal(ExecutableInfo) workingDirChanged = pyqtSignal(str) def __init__(self, **kwds): super(ExecuteOptionsPlugin, self).__init__(**kwds) self._preferences.addInt("execute/maxRecentWorkingDirs", "Max recent working directories", 10, 1, 50, "Set the maximum number of recent working directories that have been used.", ) self._preferences.addInt("execute/maxRecentExes", "Max recent executables", 10, 1, 50, "Set the maximum number of recent executables that have been used.", ) self._preferences.addInt("execute/maxRecentArgs", "Max recent command line arguments", 10, 1, 50, "Set the maximum number of recent command line arguments that have been used.", ) self._preferences.addBool("execute/mpiEnabled", "Enable MPI by default", False, "Set the MPI checkbox on by default", ) self._preferences.addString("execute/mpiArgs", "Default mpi command", "mpiexec -n 2", "Set the default MPI command to run", ) self._preferences.addBool("execute/threadsEnabled", "Enable threads by default", False, "Set the threads checkbox on by default", ) self._preferences.addString("execute/threadsArgs", "Default threads arguments", "--n-threads=2", "Set the default threads arguments", ) self.all_exe_layout = WidgetUtils.addLayout(grid=True) self.setLayout(self.all_exe_layout) self.working_label = WidgetUtils.addLabel(None, self, "Working Directory") self.all_exe_layout.addWidget(self.working_label, 0, 0) self.choose_working_button = WidgetUtils.addButton(None, self, "Choose", self._chooseWorkingDir) self.all_exe_layout.addWidget(self.choose_working_button, 0, 1) self.working_line = WidgetUtils.addLineEdit(None, self, None, readonly=True) self.working_line.setText(os.getcwd()) self.all_exe_layout.addWidget(self.working_line, 0, 2) self.exe_label = WidgetUtils.addLabel(None, self, "Executable") self.all_exe_layout.addWidget(self.exe_label, 1, 0) self.choose_exe_button = WidgetUtils.addButton(None, self, "Choose", self._chooseExecutable) self.all_exe_layout.addWidget(self.choose_exe_button, 1, 1) self.exe_line = WidgetUtils.addLineEdit(None, self, None, readonly=True) self.all_exe_layout.addWidget(self.exe_line, 1, 2) self.args_label = WidgetUtils.addLabel(None, self, "Extra Arguments") self.all_exe_layout.addWidget(self.args_label, 2, 0) self.args_line = WidgetUtils.addLineEdit(None, self, None) self.all_exe_layout.addWidget(self.args_line, 2, 2) self.mpi_label = WidgetUtils.addLabel(None, self, "Use MPI") self.all_exe_layout.addWidget(self.mpi_label, 3, 0) self.mpi_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.mpi_checkbox.setChecked(self._preferences.value("execute/mpiEnabled")) self.all_exe_layout.addWidget(self.mpi_checkbox, 3, 1, alignment=Qt.AlignHCenter) self.mpi_line = WidgetUtils.addLineEdit(None, self, None) self.mpi_line.setText(self._preferences.value("execute/mpiArgs")) self.mpi_line.cursorPositionChanged.connect(self._mpiLineCursorChanged) self.all_exe_layout.addWidget(self.mpi_line, 3, 2) self.threads_label = WidgetUtils.addLabel(None, self, "Use Threads") self.all_exe_layout.addWidget(self.threads_label, 4, 0) self.threads_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.threads_checkbox.setChecked(self._preferences.value("execute/threadsEnabled")) self.all_exe_layout.addWidget(self.threads_checkbox, 4, 1, alignment=Qt.AlignHCenter) self.threads_line = WidgetUtils.addLineEdit(None, self, None) self.threads_line.setText(self._preferences.value("execute/threadsArgs")) self.threads_line.cursorPositionChanged.connect(self._threadsLineCursorChanged) self.all_exe_layout.addWidget(self.threads_line, 4, 2) self.csv_label = WidgetUtils.addLabel(None, self, "Postprocessor CSV Output") self.all_exe_layout.addWidget(self.csv_label, 5, 0) self.csv_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.all_exe_layout.addWidget(self.csv_checkbox, 5, 1, alignment=Qt.AlignHCenter) self.csv_checkbox.setCheckState(Qt.Checked) self.recover_label = WidgetUtils.addLabel(None, self, "Recover") self.all_exe_layout.addWidget(self.recover_label, 6, 0) self.recover_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.all_exe_layout.addWidget(self.recover_checkbox, 6, 1, alignment=Qt.AlignHCenter) self._recent_exe_menu = None self._recent_working_menu = None self._recent_args_menu = None self._exe_watcher = QFileSystemWatcher() self._exe_watcher.fileChanged.connect(self.setExecutablePath) self._loading_dialog = QMessageBox(parent=self) self._loading_dialog.setWindowTitle("Loading executable") self._loading_dialog.setStandardButtons(QMessageBox.NoButton) # get rid of the OK button self._loading_dialog.setWindowModality(Qt.ApplicationModal) self._loading_dialog.setIcon(QMessageBox.Information) self._loading_dialog.setText("Loading executable") self.setup() def setExecutablePath(self, app_path): """ The user select a new executable path. Input: app_path: The path of the executable. """ if not app_path: return self._loading_dialog.setInformativeText(app_path) self._loading_dialog.show() self._loading_dialog.raise_() QApplication.processEvents() app_info = ExecutableInfo() app_info.setPath(app_path) QApplication.processEvents() if app_info.valid(): self.exe_line.setText(app_path) self.executableInfoChanged.emit(app_info) self.executableChanged.emit(app_path) files = self._exe_watcher.files() if files: self._exe_watcher.removePaths(files) self._exe_watcher.addPath(app_path) self._updateRecentExe(app_path, not app_info.valid()) self._loading_dialog.hide() def _chooseExecutable(self): """ Open a dialog to allow the user to choose an executable. """ #FIXME: QFileDialog seems to be a bit broken. Using # .setFilter() to filter only executable files doesn't # seem to work. Setting a QSortFilterProxyModel doesn't # seem to work either. # So just use the static method. exe_name, other = QFileDialog.getOpenFileName(self, "Chooose executable") self.setExecutablePath(exe_name) def _workingDirChanged(self): """ Slot called when working directory changed. """ working = str(self.working_line.text()) self.setWorkingDir(working) def _chooseWorkingDir(self): """ Open dialog to choose a current working directory. """ dirname = QFileDialog.getExistingDirectory(self, "Choose directory") self.setWorkingDir(dirname) def setWorkingDir(self, dir_name): """ Sets the working directory. Input: dir_name: The path of the working directory. """ if not dir_name: return old_dirname = str(self.working_line.text()) try: os.chdir(dir_name) self.working_line.setText(dir_name) if old_dirname != dir_name: self.workingDirChanged.emit(dir_name) self._updateRecentWorkingDir(dir_name) except OSError: mooseutils.mooseError("Invalid directory %s" % dir_name, dialog=True) self._updateRecentWorkingDir(dir_name, True) def _setExecutableArgs(self, args): """ Set the executable arguments. Input: args: str: A string of all the arguments. """ self.args_line.setText(args) def buildCommand(self, input_file): cmd, args = self.buildCommandWithNoInputFile() args.append("-i") args.append(os.path.relpath(input_file)) return cmd, args def buildCommandWithNoInputFile(self): """ Builds the full command line with arguments. Return: <string of command to run>, <list of arguments> """ cmd = "" args = [] if self.mpi_checkbox.isChecked(): mpi_args = shlex.split(str(self.mpi_line.text())) if mpi_args: cmd = mpi_args[0] args = mpi_args[1:] args.append(str(self.exe_line.text())) if not cmd: cmd = str(self.exe_line.text()) args += shlex.split(str(self.args_line.text())) if self.recover_checkbox.isChecked(): args.append("--recover") if self.csv_checkbox.isChecked(): #args.append("--no-color") args.append("Outputs/csv=true") if self.threads_checkbox.isChecked(): args += shlex.split(str(self.threads_line.text())) return cmd, args def _updateRecentExe(self, path, remove=False): """ Updates the recently used menu with the current executable """ if self._recent_exe_menu: abs_path = os.path.normcase(os.path.abspath(path)) if remove: self._recent_exe_menu.removeEntry(abs_path) else: self._recent_exe_menu.update(abs_path) def _updateRecentWorkingDir(self, path, remove=False): """ Updates the recently used menu with the current executable """ full_path = os.path.abspath(path) if self._recent_working_menu: if remove: self._recent_working_menu.removeEntry(full_path) else: self._recent_working_menu.update(full_path) def onPreferencesSaved(self): self._recent_args_menu.updateRecentlyOpened() self._recent_working_menu.updateRecentlyOpened() self._recent_exe_menu.updateRecentlyOpened() def addToMenu(self, menu): """ Adds menu entries specific to the Arguments to the menubar. """ workingMenu = menu.addMenu("Recent &working dirs") self._recent_working_menu = RecentlyUsedMenu(workingMenu, "execute/recentWorkingDirs", "execute/maxRecentWorkingDirs", 20, ) self._recent_working_menu.selected.connect(self.setWorkingDir) self._workingDirChanged() exeMenu = menu.addMenu("Recent &executables") self._recent_exe_menu = RecentlyUsedMenu(exeMenu, "execute/recentExes", "execute/maxRecentExes", 20, ) self._recent_exe_menu.selected.connect(self.setExecutablePath) argsMenu = menu.addMenu("Recent &arguments") self._recent_args_menu = RecentlyUsedMenu(argsMenu, "execute/recentArgs", "execute/maxRecentArgs", 20, ) self._recent_args_menu.selected.connect(self._setExecutableArgs) def clearRecentlyUsed(self): if self._recent_args_menu: self._recent_args_menu.clearValues() self._recent_working_menu.clearValues() self._recent_exe_menu.clearValues() self._workingDirChanged() def _mpiLineCursorChanged(self, old, new): self.mpi_checkbox.setChecked(True) def _threadsLineCursorChanged(self, old, new): self.threads_checkbox.setChecked(True)
class ExecuteOptionsPlugin(QWidget, Plugin): """ Handles setting the various arguments for running. Signals: executableChanged(str): Path of the new executable is emitted when changed executableInfoChanged(ExecutableInfo): Emitted when the executable path is changed workingDirChanged(str): Path of the current directory is changed """ executableChanged = pyqtSignal(str) executableInfoChanged = pyqtSignal(ExecutableInfo) workingDirChanged = pyqtSignal(str) useTestObjectsChanged = pyqtSignal(bool) def __init__(self, **kwds): super(ExecuteOptionsPlugin, self).__init__(**kwds) self._preferences.addInt("execute/maxRecentWorkingDirs", "Max recent working directories", 10, 1, 50, "Set the maximum number of recent working directories that have been used.", ) self._preferences.addInt("execute/maxRecentExes", "Max recent executables", 10, 1, 50, "Set the maximum number of recent executables that have been used.", ) self._preferences.addInt("execute/maxRecentArgs", "Max recent command line arguments", 10, 1, 50, "Set the maximum number of recent command line arguments that have been used.", ) self._preferences.addBool("execute/allowTestObjects", "Allow using test objects", False, "Allow using test objects by default", ) self._preferences.addBool("execute/mpiEnabled", "Enable MPI by default", False, "Set the MPI checkbox on by default", ) self._preferences.addString("execute/mpiArgs", "Default mpi command", "mpiexec -n 2", "Set the default MPI command to run", ) self._preferences.addBool("execute/threadsEnabled", "Enable threads by default", False, "Set the threads checkbox on by default", ) self._preferences.addString("execute/threadsArgs", "Default threads arguments", "--n-threads=2", "Set the default threads arguments", ) self.all_exe_layout = WidgetUtils.addLayout(grid=True) self.setLayout(self.all_exe_layout) self.working_label = WidgetUtils.addLabel(None, self, "Working Directory") self.all_exe_layout.addWidget(self.working_label, 0, 0) self.choose_working_button = WidgetUtils.addButton(None, self, "Choose", self._chooseWorkingDir) self.all_exe_layout.addWidget(self.choose_working_button, 0, 1) self.working_line = WidgetUtils.addLineEdit(None, self, None, readonly=True) self.working_line.setText(os.getcwd()) self.all_exe_layout.addWidget(self.working_line, 0, 2) self.exe_label = WidgetUtils.addLabel(None, self, "Executable") self.all_exe_layout.addWidget(self.exe_label, 1, 0) self.choose_exe_button = WidgetUtils.addButton(None, self, "Choose", self._chooseExecutable) self.all_exe_layout.addWidget(self.choose_exe_button, 1, 1) self.exe_line = WidgetUtils.addLineEdit(None, self, None, readonly=True) self.all_exe_layout.addWidget(self.exe_line, 1, 2) self.args_label = WidgetUtils.addLabel(None, self, "Extra Arguments") self.all_exe_layout.addWidget(self.args_label, 2, 0) self.args_line = WidgetUtils.addLineEdit(None, self, None) self.all_exe_layout.addWidget(self.args_line, 2, 2) self.test_label = WidgetUtils.addLabel(None, self, "Allow test objects") self.all_exe_layout.addWidget(self.test_label, 3, 0) self.test_checkbox = WidgetUtils.addCheckbox(None, self, "", self._allowTestObjects) self.test_checkbox.setChecked(self._preferences.value("execute/allowTestObjects")) self.all_exe_layout.addWidget(self.test_checkbox, 3, 1, alignment=Qt.AlignHCenter) self.mpi_label = WidgetUtils.addLabel(None, self, "Use MPI") self.all_exe_layout.addWidget(self.mpi_label, 4, 0) self.mpi_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.mpi_checkbox.setChecked(self._preferences.value("execute/mpiEnabled")) self.all_exe_layout.addWidget(self.mpi_checkbox, 4, 1, alignment=Qt.AlignHCenter) self.mpi_line = WidgetUtils.addLineEdit(None, self, None) self.mpi_line.setText(self._preferences.value("execute/mpiArgs")) self.mpi_line.cursorPositionChanged.connect(self._mpiLineCursorChanged) self.all_exe_layout.addWidget(self.mpi_line, 4, 2) self.threads_label = WidgetUtils.addLabel(None, self, "Use Threads") self.all_exe_layout.addWidget(self.threads_label, 5, 0) self.threads_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.threads_checkbox.setChecked(self._preferences.value("execute/threadsEnabled")) self.all_exe_layout.addWidget(self.threads_checkbox, 5, 1, alignment=Qt.AlignHCenter) self.threads_line = WidgetUtils.addLineEdit(None, self, None) self.threads_line.setText(self._preferences.value("execute/threadsArgs")) self.threads_line.cursorPositionChanged.connect(self._threadsLineCursorChanged) self.all_exe_layout.addWidget(self.threads_line, 5, 2) self.csv_label = WidgetUtils.addLabel(None, self, "Postprocessor CSV Output") self.all_exe_layout.addWidget(self.csv_label, 6, 0) self.csv_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.all_exe_layout.addWidget(self.csv_checkbox, 6, 1, alignment=Qt.AlignHCenter) self.csv_checkbox.setCheckState(Qt.Checked) self.recover_label = WidgetUtils.addLabel(None, self, "Recover") self.all_exe_layout.addWidget(self.recover_label, 7, 0) self.recover_checkbox = WidgetUtils.addCheckbox(None, self, "", None) self.all_exe_layout.addWidget(self.recover_checkbox, 7, 1, alignment=Qt.AlignHCenter) self._recent_exe_menu = None self._recent_working_menu = None self._recent_args_menu = None self._exe_watcher = QFileSystemWatcher() self._exe_watcher.fileChanged.connect(self.setExecutablePath) self._loading_dialog = QMessageBox(parent=self) self._loading_dialog.setWindowTitle("Loading executable") self._loading_dialog.setStandardButtons(QMessageBox.NoButton) # get rid of the OK button self._loading_dialog.setWindowModality(Qt.ApplicationModal) self._loading_dialog.setIcon(QMessageBox.Information) self._loading_dialog.setText("Loading executable") self.setup() def setExecutablePath(self, app_path): """ The user select a new executable path. Input: app_path: The path of the executable. """ if not app_path: return self._loading_dialog.setInformativeText(app_path) self._loading_dialog.show() self._loading_dialog.raise_() QApplication.processEvents() app_info = ExecutableInfo() app_info.setPath(app_path, self.test_checkbox.isChecked()) QApplication.processEvents() if app_info.valid(): self.exe_line.setText(app_path) self.executableInfoChanged.emit(app_info) self.executableChanged.emit(app_path) files = self._exe_watcher.files() if files: self._exe_watcher.removePaths(files) self._exe_watcher.addPath(app_path) self._updateRecentExe(app_path, not app_info.valid()) self._loading_dialog.hide() def _chooseExecutable(self): """ Open a dialog to allow the user to choose an executable. """ #FIXME: QFileDialog seems to be a bit broken. Using # .setFilter() to filter only executable files doesn't # seem to work. Setting a QSortFilterProxyModel doesn't # seem to work either. # So just use the static method. exe_name, other = QFileDialog.getOpenFileName(self, "Chooose executable") self.setExecutablePath(exe_name) def _allowTestObjects(self): """ Reload the ExecutableInfo based on whether we are allowing test objects or not. """ self.useTestObjectsChanged.emit(self.test_checkbox.isChecked()) self.setExecutablePath(self.exe_line.text()) def _workingDirChanged(self): """ Slot called when working directory changed. """ working = str(self.working_line.text()) self.setWorkingDir(working) def _chooseWorkingDir(self): """ Open dialog to choose a current working directory. """ dirname = QFileDialog.getExistingDirectory(self, "Choose directory") self.setWorkingDir(dirname) def setWorkingDir(self, dir_name): """ Sets the working directory. Input: dir_name: The path of the working directory. """ if not dir_name: return old_dirname = str(self.working_line.text()) try: os.chdir(dir_name) self.working_line.setText(dir_name) if old_dirname != dir_name: self.workingDirChanged.emit(dir_name) self._updateRecentWorkingDir(dir_name) except OSError: mooseutils.mooseError("Invalid directory %s" % dir_name, dialog=True) self._updateRecentWorkingDir(dir_name, True) def _setExecutableArgs(self, args): """ Set the executable arguments. Input: args: str: A string of all the arguments. """ self.args_line.setText(args) def buildCommand(self, input_file): cmd, args = self.buildCommandWithNoInputFile() args.append("-i") args.append(os.path.relpath(input_file)) return cmd, args def buildCommandWithNoInputFile(self): """ Builds the full command line with arguments. Return: <string of command to run>, <list of arguments> """ cmd = "" args = [] if self.mpi_checkbox.isChecked(): mpi_args = shlex.split(str(self.mpi_line.text())) if mpi_args: cmd = mpi_args[0] args = mpi_args[1:] args.append(str(self.exe_line.text())) if not cmd: cmd = str(self.exe_line.text()) args += shlex.split(str(self.args_line.text())) if self.recover_checkbox.isChecked(): args.append("--recover") if self.csv_checkbox.isChecked(): #args.append("--no-color") args.append("Outputs/csv=true") if self.threads_checkbox.isChecked(): args += shlex.split(str(self.threads_line.text())) return cmd, args def _updateRecentExe(self, path, remove=False): """ Updates the recently used menu with the current executable """ if self._recent_exe_menu: abs_path = os.path.normcase(os.path.abspath(path)) if remove: self._recent_exe_menu.removeEntry(abs_path) else: self._recent_exe_menu.update(abs_path) def _updateRecentWorkingDir(self, path, remove=False): """ Updates the recently used menu with the current executable """ full_path = os.path.abspath(path) if self._recent_working_menu: if remove: self._recent_working_menu.removeEntry(full_path) else: self._recent_working_menu.update(full_path) def onPreferencesSaved(self): self._recent_args_menu.updateRecentlyOpened() self._recent_working_menu.updateRecentlyOpened() self._recent_exe_menu.updateRecentlyOpened() def addToMenu(self, menu): """ Adds menu entries specific to the Arguments to the menubar. """ workingMenu = menu.addMenu("Recent &working dirs") self._recent_working_menu = RecentlyUsedMenu(workingMenu, "execute/recentWorkingDirs", "execute/maxRecentWorkingDirs", 20, ) self._recent_working_menu.selected.connect(self.setWorkingDir) self._workingDirChanged() exeMenu = menu.addMenu("Recent &executables") self._recent_exe_menu = RecentlyUsedMenu(exeMenu, "execute/recentExes", "execute/maxRecentExes", 20, ) self._recent_exe_menu.selected.connect(self.setExecutablePath) argsMenu = menu.addMenu("Recent &arguments") self._recent_args_menu = RecentlyUsedMenu(argsMenu, "execute/recentArgs", "execute/maxRecentArgs", 20, ) self._recent_args_menu.selected.connect(self._setExecutableArgs) def clearRecentlyUsed(self): if self._recent_args_menu: self._recent_args_menu.clearValues() self._recent_working_menu.clearValues() self._recent_exe_menu.clearValues() self._workingDirChanged() def _mpiLineCursorChanged(self, old, new): self.mpi_checkbox.setChecked(True) def _threadsLineCursorChanged(self, old, new): self.threads_checkbox.setChecked(True)
class InputFileEditorPlugin(InputFileEditor, Plugin): """ The widget to edit the input file. In addition to InputFileEditor, this class adds menus and is available as a Plugin. """ highlightBC = pyqtSignal(list, list, list) def __init__(self, **kwds): super(InputFileEditorPlugin, self).__init__(**kwds) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self._menus_initialized = False self._recently_used_menu = None self._save_action = None self._open_action = None self._save_as_action = None self._clear_action = None self._check_action = None self._view_file = None self.check_widget = CheckInputWidget() self.check_widget.needInputFile.connect(self.writeInputFile) self.check_widget.hide() self.blockChanged.connect(self._updateChanged) self.input_file_view = QPlainTextEdit() self.input_file_view.setReadOnly(True) self.input_file_view.setWindowFlags(Qt.Window) self.input_file_view.resize(640, 480) self.has_changed = False self.setup() def _updateChanged(self, block, tree): self.has_changed = True def executableInfoChanged(self, app_info): super(InputFileEditorPlugin, self).executableInfoChanged(app_info) self._setMenuStatus() self.has_changed = False def setInputFile(self, input_file): val = super(InputFileEditorPlugin, self).setInputFile(input_file) if self._menus_initialized: path = os.path.abspath(input_file) if os.path.exists(path): self._recently_used_menu.update(path) else: self._recently_used_menu.removeEntry(path) self._setMenuStatus() self.has_changed = False return val def _openInputFile(self): """ Ask the user what input file to open. """ input_name, other = QFileDialog.getOpenFileName( self, "Chooose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) success = self.setInputFile(input_name) if success: self._recently_used_menu.update(input_name) else: self._recently_used_menu.removeEntry(input_name) def _saveInputFile(self): """ Save the current input tree to the current filename. """ self.writeInputFile(self.tree.input_filename) self.has_changed = False def _saveInputFileAs(self): """ Ask the user what file to save the input tree to. """ input_name, other = QFileDialog.getSaveFileName( self, "Chooose input file", os.getcwd(), "Input File (*.i)") if input_name: input_name = os.path.abspath(input_name) self.writeInputFile(input_name) self.setInputFile(input_name) self._recently_used_menu.update(input_name) self.has_changed = False def _checkInputFile(self): """ Show the input file check window. """ self.check_widget.show() self.check_widget.check(self.tree.app_info.path) def _viewInputFile(self): """ View the text of the current input tree. """ if self.input_file_view.isVisible(): self.input_file_view.hide() else: data = self.tree.getInputFileString() self.input_file_view.setPlainText(data) self.input_file_view.show() def _clearInputFile(self): self.tree.resetInputFile() self.tree.input_filename = None self.block_tree.setInputTree(self.tree) self.inputFileChanged.emit("") self._setMenuStatus() self.has_changed = False def _setMenuStatus(self): """ Set the status of the menus. """ if not self._menus_initialized: return enabled = self.tree.app_info.valid() if self.tree.input_filename: self._save_action.setEnabled(enabled) else: self._save_action.setEnabled(False) self._save_as_action.setEnabled(enabled) self._open_action.setEnabled(enabled) self._recently_used_menu.setEnabled(enabled) self._clear_action.setEnabled(enabled) self._check_action.setEnabled(enabled) self._view_file.setEnabled(enabled) def addToMenu(self, menu): """ Register the menus specific to the InputTab. Input: menu[QMenu]: The menu to add the items to. """ self._open_action = WidgetUtils.addAction(menu, "Open", self._openInputFile, "Ctrl+O") recentMenu = menu.addMenu("Recently opened") self._recently_used_menu = RecentlyUsedMenu( recentMenu, InputSettings.RECENTLY_USED_KEY, InputSettings.MAX_RECENT_KEY, InputSettings.MAX_RECENT_DEFAULT) self._recently_used_menu.selected.connect(self.setInputFile) self._save_action = WidgetUtils.addAction(menu, "Save", self._saveInputFile) self._save_as_action = WidgetUtils.addAction(menu, "Save As", self._saveInputFileAs) self._clear_action = WidgetUtils.addAction(menu, "Clear", self._clearInputFile) self._check_action = WidgetUtils.addAction(menu, "Check", self._checkInputFile, "Ctrl+K") self._view_file = WidgetUtils.addAction(menu, "View current input file", self._viewInputFile, "Ctrl+V", True) self._menus_initialized = True self._setMenuStatus() def closing(self): self.check_widget.cleanup() def clearRecentlyUsed(self): if self._menus_initialized: self._recently_used_menu.clearValues() def onCurrentChanged(self, index): """ This is called when the tab is changed. If the block editor window is open we want to raise it to the front so it doesn't get lost. """ if index == self._index: if self.block_editor: self.block_editor.raise_()