def __init__(self, analysis_type, study_directory=None, import_study=False): super(MainWindow, self).__init__() if ApplicationStudy is None: self._init_class() self.ui = loadUi(self.uifile, self) toolbar_action_group = QtGui.QActionGroup(self) toolbar_action_group.addAction(self.ui.action_axial_view) toolbar_action_group.addAction(self.ui.action_coronal_view) self._init_action_handlers() self._analysis_type = analysis_type self.study = ApplicationStudy(self._analysis_type) self.runner = self._create_runner(self.study) self.study_model = LazyStudyModel(self.study, self.runner) self.analysis_model = LazyAnalysisModel() self.viewport_model = IntraAnalysisViewportModel(self.analysis_model) self.viewport_widget = IntraAnalysisViewportWidget(self.viewport_model, self) self.setCentralWidget(self.viewport_widget) self.study_view = SubjectsWidget(self.study_model) self.ui.study_widget_dock.setWidget(self.study_view) self.setCorner(QtCore.Qt.TopRightCorner, QtCore.Qt.RightDockWidgetArea) self.setCorner(QtCore.Qt.BottomRightCorner, QtCore.Qt.RightDockWidgetArea) self.setCorner(QtCore.Qt.TopLeftCorner, QtCore.Qt.LeftDockWidgetArea) self.setCorner(QtCore.Qt.BottomLeftCorner, QtCore.Qt.LeftDockWidgetArea) self.runner_view = RunnerView(self.study_model) self.ui.runner_widget_dock.setWidget(self.runner_view) self.setWindowTitle(self._window_title()) self.dialogs = {} self.study_model.current_subject_changed.connect(self.on_current_subject_changed) self.on_current_subject_changed() if study_directory is not None: if import_study: self._create_inplace_study(study_directory) else: self._try_open_study_from_directory(study_directory)
class MainWindow(QtGui.QMainWindow): uifile = os.path.join(ui_directory, "main_window.ui") def _init_class(self): global ApplicationStudy if settings.tests.mock: from morphologist.core.tests.mocks.study import MockStudy ApplicationStudy = MockStudy else: ApplicationStudy = Study def __init__(self, analysis_type, study_directory=None, import_study=False): super(MainWindow, self).__init__() if ApplicationStudy is None: self._init_class() self.ui = loadUi(self.uifile, self) toolbar_action_group = QtGui.QActionGroup(self) toolbar_action_group.addAction(self.ui.action_axial_view) toolbar_action_group.addAction(self.ui.action_coronal_view) self._init_action_handlers() self._analysis_type = analysis_type self.study = ApplicationStudy(self._analysis_type) self.runner = self._create_runner(self.study) self.study_model = LazyStudyModel(self.study, self.runner) self.analysis_model = LazyAnalysisModel() self.viewport_model = IntraAnalysisViewportModel(self.analysis_model) self.viewport_widget = IntraAnalysisViewportWidget(self.viewport_model, self) self.setCentralWidget(self.viewport_widget) self.study_view = SubjectsWidget(self.study_model) self.ui.study_widget_dock.setWidget(self.study_view) self.setCorner(QtCore.Qt.TopRightCorner, QtCore.Qt.RightDockWidgetArea) self.setCorner(QtCore.Qt.BottomRightCorner, QtCore.Qt.RightDockWidgetArea) self.setCorner(QtCore.Qt.TopLeftCorner, QtCore.Qt.LeftDockWidgetArea) self.setCorner(QtCore.Qt.BottomLeftCorner, QtCore.Qt.LeftDockWidgetArea) self.runner_view = RunnerView(self.study_model) self.ui.runner_widget_dock.setWidget(self.runner_view) self.setWindowTitle(self._window_title()) self.dialogs = {} self.study_model.current_subject_changed.connect(self.on_current_subject_changed) self.on_current_subject_changed() if study_directory is not None: if import_study: self._create_inplace_study(study_directory) else: self._try_open_study_from_directory(study_directory) def _init_action_handlers(self): self._new_study_action_handler = None self._import_study_action_handler = None self._edit_study_action_handler = None def _try_open_study_from_directory(self, study_directory): try: study = ApplicationStudy.from_study_directory(study_directory) except StudySerializationError as e: title = "Cannot load study" msg = "'%s':\n%s" % (study_directory, e) QtGui.QMessageBox.critical(self, title, msg) else: self.set_study(study) def _create_inplace_study(self, study_directory): QtGui.QApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) pb = _create_import_progress_dialog() QtGui.QApplication.instance().processEvents() study = ApplicationStudy.from_organized_directory( self._analysis_type, study_directory, progress_callback=pb.update_value ) self.set_study(study) study.save_to_backup_file() pb.deleteLater() del pb QtGui.QApplication.instance().restoreOverrideCursor() def _create_runner(self, study): return SomaWorkflowRunner(study) # this slot is automagically connected @QtCore.Slot() def on_action_new_study_triggered(self): msg = "Stop current running analysis and create a new study ?" if self._runner_still_running_after_stopping_asked_to_user(msg): return self._new_study_action_handler = NewStudyActionHandler(self._analysis_type, self) self._new_study_action_handler.study_updated.connect(self.on_study_action_handler_study_updated) self._new_study_action_handler.start() # this slot is automagically connected @QtCore.Slot() def on_action_import_study_triggered(self): msg = "Stop current running analysis and import a study ?" if self._runner_still_running_after_stopping_asked_to_user(msg): return self._import_study_action_handler = ImportStudyActionHandler(self._analysis_type, self) self._import_study_action_handler.study_updated.connect(self.on_study_action_handler_study_updated) self._import_study_action_handler.start() # this slot is automagically connected @QtCore.Slot() def on_action_edit_study_triggered(self): msg = "Stop current running analysis and edit the current study ?" if self._runner_still_running_after_stopping_asked_to_user(msg): return self._edit_study_action_handler = EditStudyActionHandler(self.study, self) self._edit_study_action_handler.study_updated.connect(self.on_study_action_handler_study_updated) self._edit_study_action_handler.start() @QtCore.Slot(Study) def on_study_action_handler_study_updated(self, study): self.set_study(study) self._try_save_to_backup_file() self.runner.set_study(study) # this slot is automagically connected @QtCore.Slot() def on_action_open_study_triggered(self): msg = "Stop current running analysis and open a study ?" if self._runner_still_running_after_stopping_asked_to_user(msg): return study_directory = QtGui.QFileDialog.getExistingDirectory( parent=self.ui, caption="Open a study directory", directory="", options=QtGui.QFileDialog.DontUseNativeDialog, ) if study_directory: self._try_open_study_from_directory(study_directory) def _runner_still_running_after_stopping_asked_to_user(self, msg="Stop current running analysis ?"): if self.runner.is_running(): title = "Analyses are currently running" answer = QtGui.QMessageBox.question(self, title, msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.Cancel) if answer == QtGui.QMessageBox.Yes: self.runner.stop() return False else: return True return False def _try_save_to_backup_file(self): try: self.study.save_to_backup_file() except StudySerializationError as e: QtGui.QMessageBox.critical(self, "Cannot save the study", "%s" % (e)) # this slot is automagically connected @QtCore.Slot() def on_action_export_morphometry_triggered(self): self.save_morphometry(ALL_SUBJECTS) # this slot is automagically connected @QtCore.Slot() def on_action_export_selection_morphometry_triggered(self): subject_ids = self.study_model.get_selected_subject_ids() self.save_morphometry(subject_ids) def save_morphometry(self, subject_ids): msg = "Stop current running analysis and save " + "availables morphometry data ?" if self._runner_still_running_after_stopping_asked_to_user(msg): return filter = "CSV (*.csv)" morphometry_filepath = QtGui.QFileDialog.getSaveFileName( self.ui, caption="Choose morphometry output file", directory="", options=QtGui.QFileDialog.DontUseNativeDialog, filter=filter, ) if morphometry_filepath == "": return if subject_ids is ALL_SUBJECTS: subject_ids = six.iterkeys(self.study.subjects) command = ["python", "-m", "brainvisa.axon.runprocess", "concatenatefiles"] morpho_files = [] subjects = [] for subject_id in subject_ids: analysis = self.study.analyses[subject_id] analysis.propagate_parameters() csv_filepath = getattr(analysis.pipeline.process, IntraAnalysisParameterNames.MORPHOMETRY_CSV) print("morpho file:", csv_filepath) # ignore none-existing files if os.path.isfile(csv_filepath): print("exists.") morpho_files.append(csv_filepath) subject_name = analysis.subject.name subjects.append(subject_name) print("morpho_files:", morpho_files) command += ['"' + repr(morpho_files) + '"', '"' + repr(subjects) + '"', morphometry_filepath] print("command:", " ".join(command)) os.system(" ".join(command)) @QtCore.Slot() def on_current_subject_changed(self): subject_id = self.study_model.get_current_subject_id() if subject_id: analysis = self.study.analyses[subject_id] self.analysis_model.set_analysis(analysis) def set_study(self, study): self.study = study self.runner = self._create_runner(self.study) self.study_model.set_study_and_runner(self.study, self.runner) if not self.study.has_subjects(): self.analysis_model.remove_analysis() self.setWindowTitle(self._window_title()) def _window_title(self): title = "Morphologist - %s" % self.study.study_name if settings.tests.mock: title += "--- MOCK MODE ---" return title def closeEvent(self, event): msg = "Stop current running analysis and quit ?" if self._runner_still_running_after_stopping_asked_to_user(msg): event.ignore() else: if hasattr(self, "browser"): del self.browser event.accept() # this slot is automagically connected @QtCore.Slot() def on_action_runner_settings_triggered(self): dialog = RunnerSettingsDialog(settings, self.study, self) dialog.show() # this slot is automagically connected @QtCore.Slot(bool) def on_action_axial_view_toggled(self, checked): if checked: self.viewport_widget.set_object3d_views_view_type(ViewType.AXIAL) # this slot is automagically connected @QtCore.Slot(bool) def on_action_coronal_view_toggled(self, checked): if checked: self.viewport_widget.set_object3d_views_view_type(ViewType.CORONAL) @QtCore.Slot() def on_action_documentation_triggered(self): if not hasattr(self, "browser"): self.browser = QtWebKit.QWebView() self.browser.setWindowTitle("Morphologist UI documentation") self.browser.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.browser.destroyed.connect(self._remove_browser) version = "%d.%d" % (info.version_major, info.version_minor) help_index = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) help_index = os.path.join(help_index, "share", "doc", "morphologist-ui-%s" % version, "index.html") print("help_index:", help_index) self.browser.setUrl(QtCore.QUrl.fromLocalFile(help_index)) self.browser.show() self.browser.raise_() def _remove_browser(self): del self.browser @QtCore.Slot() def on_action_brainvisa_configuration_triggered(self): from soma.wip.application.api import Application from soma.qtgui.api import ApplicationQtGUI from brainvisa.configuration import neuroConfig configuration = Application().configuration appGUI = ApplicationQtGUI() dialog = appGUI.createEditionDialog(configuration, parent=None, live=False, modal=True) from soma.qt4gui.configuration_qt4gui import ConfigurationWidget from soma.qt_gui.qt_backend import QtGui # remove the database panel and icon stackw = dialog.findChild(QtGui.QStackedWidget) dbwidget = stackw.widget(1) stackw.removeWidget(dbwidget) listw = dialog.findChild(QtGui.QSplitter).findChild(QtGui.QListWidget) listw.takeItem(1) result = dialog.exec_() if result: dialog.setObject(configuration) appGUI.closeEditionDialog(dialog) # if appGUI.edit(configuration, live=False, modal=True): if result: # from brainvisa.configuration import axon_capsul_config_link # axon_capsul_config_link.axon_to_capsul_config_sync(self.study) configuration.save(neuroConfig.userOptionFile) try: self.study.save_to_backup_file() except StudySerializationError as e: pass # study is not saved, don't notify