def create_project_pop_up(self): if self.check_unsaved_modifications(): self.pop_up_close = Ui_Dialog_Quit(self.project) self.pop_up_close.save_as_signal.connect(self.saveChoice) self.pop_up_close.exec() can_switch = self.pop_up_close.can_exit() else: can_switch = True if can_switch: # Opens a pop-up when the 'New Project' action is clicked and updates the recent projects self.exPopup = Ui_Dialog_New_Project() if self.exPopup.exec_(): self.project.session.unsave_modifications() self.remove_raw_files_useless( ) # We remove the useless files from the old project file_name = self.exPopup.selectedFiles() self.exPopup.retranslateUi(self.exPopup.selectedFiles()) file_name = self.exPopup.relative_path # Removing the old project from the list of currently opened projects config = Config() opened_projects = config.get_opened_projects() opened_projects.remove(self.project.folder) config.set_opened_projects(opened_projects) self.project = Project(self.exPopup.relative_path, True) self.update_project(file_name) # Project updated everywhere
def closeEvent(self, event): """ Overriding the closing event to check if there are unsaved modifications """ if self.force_exit: event.accept() return if self.check_unsaved_modifications(): self.pop_up_close = Ui_Dialog_Quit(self.project) self.pop_up_close.save_as_signal.connect(self.saveChoice) self.pop_up_close.exec() can_exit = self.pop_up_close.can_exit() else: can_exit = True if can_exit: self.project.unsaveModifications() # Clean up config = Config() opened_projects = config.get_opened_projects() opened_projects.remove(self.project.folder) config.set_opened_projects(opened_projects) self.remove_raw_files_useless() event.accept() else: event.ignore()
class Ui_Select_Tag(Ui_Tag_Selection): """ Is called when the user wants to update the tag to display in the MiniViewer """ def __init__(self, project): super(Ui_Select_Tag, self).__init__(project) self.project = project self.config = Config() # Filling the list and checking the thumbnail tag for tag in self.project.session.get_fields_names(COLLECTION_CURRENT): if tag != TAG_CHECKSUM: item = QtWidgets.QListWidgetItem() item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) if tag == self.config.getThumbnailTag(): item.setCheckState(QtCore.Qt.Checked) else: item.setCheckState(QtCore.Qt.Unchecked) self.list_widget_tags.addItem(item) item.setText(tag) self.list_widget_tags.sortItems() def ok_clicked(self): for idx in range(self.list_widget_tags.count()): item = self.list_widget_tags.item(idx) if item.checkState() == QtCore.Qt.Checked: self.config.setThumbnailTag(item.text()) break self.accept() self.close()
def clean_up(): """ Cleans up the software during "normal" closing """ global imageViewer print("clean up done") config = Config() opened_projects = config.get_opened_projects() opened_projects.remove(imageViewer.project.folder) config.set_opened_projects(opened_projects) imageViewer.remove_raw_files_useless()
def create_tabs(self): """ Creates the tabs """ self.config = Config() self.tabs = QTabWidget() self.tabs.setAutoFillBackground(False) #self.tabs.setStyleSheet('QTabBar{font-size:14pt;font-family:Helvetica;text-align: center;color:blue;}') self.tabs.setStyleSheet('QTabBar{font-size:16pt;text-align: center}') self.tabs.setMovable(True) self.data_browser = DataBrowser.DataBrowser.DataBrowser( self.project, self) self.tabs.addTab(self.data_browser, "Data Browser") self.image_viewer = ImageViewer() self.tabs.addTab(self.image_viewer, "Data Viewer") self.pipeline_manager = PipelineManagerTab(self.project, [], self) self.tabs.addTab(self.pipeline_manager, "Pipeline Manager") self.tabs.currentChanged.connect(self.tab_changed) vertical_layout = QVBoxLayout() vertical_layout.addWidget(self.tabs) self.centralWindow = QWidget() self.centralWindow.setLayout(vertical_layout)
def update_package_library_action(self): """ Updates the package library action depending on the mode """ if Config().get_clinical_mode() == 'yes': self.action_package_library.setDisabled(True) # self.action_install_processes.setDisabled(True) else: self.action_package_library.setEnabled(True)
def __init__(self, project): super(Ui_Select_Tag, self).__init__(project) self.project = project self.config = Config() # Filling the list and checking the thumbnail tag for tag in self.project.session.get_fields_names(COLLECTION_CURRENT): if tag != TAG_CHECKSUM: item = QtWidgets.QListWidgetItem() item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) if tag == self.config.getThumbnailTag(): item.setCheckState(QtCore.Qt.Checked) else: item.setCheckState(QtCore.Qt.Unchecked) self.list_widget_tags.addItem(item) item.setText(tag) self.list_widget_tags.sortItems()
def __init__(self, project, databrowser): super(Ui_Select_Filter, self).__init__(project) self.project = project self.databrowser = databrowser self.config = Config() self.setWindowTitle("Open a filter") # Filling the filter list for filter in self.project.filters: item = QtWidgets.QListWidgetItem() self.list_widget_filters.addItem(item) item.setText(filter.name)
def launch_mia(): global imageViewer def my_excepthook(type, value, tback): # log the exception here print("excepthook") clean_up() # then call the default handler sys.__excepthook__(type, value, tback) sys.exit(1) sys.excepthook = my_excepthook # Working from the scripts directory os.chdir(os.path.dirname(os.path.realpath(__file__))) lock_file = QLockFile( QDir.temp().absoluteFilePath('lock_file_populse_mia.lock')) if not lock_file.tryLock(100): # Software already opened in another instance pass else: # No instances of the software is opened, the list of opened projects can be cleared config = Config() config.set_opened_projects([]) app = QApplication(sys.argv) project = Project(None, True) imageViewer = Main_Window(project) imageViewer.show() app.exec()
def __init__(self, project, test=False): ############### Main Window ################################################################ super(Main_Window, self).__init__() self.project = project self.test = test self.force_exit = False app_icon = QIcon(os.path.join('..', 'sources_images', 'brain_mri.jpeg')) self.setWindowIcon(app_icon) ############### initial setting ############################################################ config = Config() self.saved_projects = SavedProjects() self.saved_projects_list = self.saved_projects.pathsList self.saved_projects_actions = [] ################ Create actions & menus #################################################### config = Config() background_color = config.getBackgroundColor() text_color = config.getTextColor() self.setStyleSheet("background-color:" + background_color + ";color:" + text_color + ";") self.create_actions() self.create_menus() self.setWindowTitle('MIA - Multiparametric Image Analysis') self.statusBar().showMessage( 'Please create a new project (Ctrl+N) or open an existing project (Ctrl+O)' ) # BELOW : WAS AT THE END OF MODIFY_UI self.setWindowTitle( 'MIA - Multiparametric Image Analysis - Unnamed project') ################ Create Tabs ############################################################### self.create_tabs() self.setCentralWidget(self.centralWindow) self.showMaximized()
def __init__(self, project_root_folder, new_project): if project_root_folder is None: self.isTempProject = True self.folder = os.path.relpath(tempfile.mkdtemp()) else: self.isTempProject = False self.folder = project_root_folder # Checks that the project is not already opened config = Config() opened_projects = config.get_opened_projects() if self.folder not in opened_projects: opened_projects.append(self.folder) config.set_opened_projects(opened_projects) else: raise IOError( "The project at " + str(self.folder) + " is already opened in another instance of the software.") self.database = Database_mia( 'sqlite:///' + os.path.join(self.folder, 'database', 'mia.db')) self.session = self.database.__enter__() if new_project: if not os.path.exists(self.folder): os.makedirs(self.folder) if not os.path.exists(os.path.join(self.folder, "database")): os.makedirs(os.path.join(self.folder, "database")) if not os.path.exists(os.path.join(self.folder, "filters")): os.makedirs(os.path.join(self.folder, "filters")) if not os.path.exists(os.path.join(self.folder, "data")): os.makedirs(os.path.join(self.folder, "data")) if not os.path.exists(os.path.join(self.folder, "data", "raw_data")): os.makedirs(os.path.join(self.folder, "data", "raw_data")) if not os.path.exists( os.path.join(self.folder, "data", "derived_data")): os.makedirs(os.path.join(self.folder, "data", "derived_data")) if not os.path.exists( os.path.join(self.folder, "data", "downloaded_data")): os.makedirs( os.path.join(self.folder, "data", "downloaded_data")) # Properties file created os.mkdir(os.path.join(self.folder, 'properties')) if self.isTempProject: name = "Unnamed project" else: name = os.path.basename(self.folder) properties = dict( name=name, date=datetime.now().strftime('%d/%m/%Y %H:%M:%S'), sorted_tag=TAG_FILENAME, sort_order=0) with open(os.path.join(self.folder, 'properties', 'properties.yml'), 'w', encoding='utf8') as propertyfile: yaml.dump(properties, propertyfile, default_flow_style=False, allow_unicode=True) # Adding current and initial collections self.session.add_collection(COLLECTION_CURRENT, TAG_FILENAME, True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_collection(COLLECTION_INITIAL, TAG_FILENAME, True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_collection(COLLECTION_BRICK, BRICK_ID, False, TAG_ORIGIN_BUILTIN, None, None) # Tags manually added self.session.add_field(COLLECTION_CURRENT, TAG_CHECKSUM, FIELD_TYPE_STRING, "Path checksum", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field( COLLECTION_INITIAL, TAG_CHECKSUM, FIELD_TYPE_STRING, "Path checksum", False, TAG_ORIGIN_BUILTIN, None, None) # TODO Maybe remove checksum tag from initial table self.session.add_field(COLLECTION_CURRENT, TAG_TYPE, FIELD_TYPE_STRING, "Path type", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_INITIAL, TAG_TYPE, FIELD_TYPE_STRING, "Path type", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_CURRENT, TAG_EXP_TYPE, FIELD_TYPE_STRING, "Path exp type", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_INITIAL, TAG_EXP_TYPE, FIELD_TYPE_STRING, "Path exp type", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_CURRENT, TAG_BRICKS, FIELD_TYPE_LIST_STRING, "Path bricks", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_INITIAL, TAG_BRICKS, FIELD_TYPE_LIST_STRING, "Path bricks", True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_NAME, FIELD_TYPE_STRING, "Brick name", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_INPUTS, FIELD_TYPE_JSON, "Brick input(s)", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_OUTPUTS, FIELD_TYPE_JSON, "Brick output(s)", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_INIT, FIELD_TYPE_STRING, "Brick init status", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_INIT_TIME, FIELD_TYPE_DATETIME, "Brick init time", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_EXEC, FIELD_TYPE_STRING, "Brick exec status", False, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_BRICK, BRICK_EXEC_TIME, FIELD_TYPE_DATETIME, "Brick exec time", False, TAG_ORIGIN_BUILTIN, None, None) # Adding default tags for the clinical mode if config.get_clinical_mode() == 'yes': for clinical_tag in CLINICAL_TAGS: if clinical_tag == "Age": field_type = FIELD_TYPE_INTEGER else: field_type = FIELD_TYPE_STRING self.session.add_field(COLLECTION_CURRENT, clinical_tag, field_type, clinical_tag, True, TAG_ORIGIN_BUILTIN, None, None) self.session.add_field(COLLECTION_INITIAL, clinical_tag, field_type, clinical_tag, True, TAG_ORIGIN_BUILTIN, None, None) self.session.save_modifications( ) # Base modifications, do not count for unsaved modifications self.properties = self.loadProperties() self.unsavedModifications = False self.undos = [] self.redos = [] self.initFilters()
def __init__(self): super(ImageViewer, self).__init__() pal = QPalette() pal.setColor(QPalette.Background, Qt.lightGray) self.factor = 3.0 self.config = Config() self.currentRep = "" self.createActions() self.createToolbarMenus() #self.createMenus() self.browserFile() self.imgqLabel() self.boxSliders() self.verticalLayout = QVBoxLayout(self) self.horizontalLayout = QHBoxLayout(self) self.textInfo = QTextEdit() self.textInfoTop = QTextEdit() self.textInfoTop.setEnabled(True) self.textInfoTop.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored) self.textInfoTop.setFontPointSize(11) self.textInfoTop.setStyleSheet("background-color: lightgray") #self.textInfoTop.adjustSize() self.textInfoTop.setText('Welcome to IRMaGe') self.tableJson = QTableWidget() self.tableJson.setColumnCount(2) self.tableJson.setColumnWidth(0, 150) self.tableJson.setColumnWidth(1, 400) self.tableJson.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContents) self.tableJson.setHorizontalHeaderLabels(['Keys', 'Values']) #self.tableJson.setBackgroundRole(QPalette.Light) self.scrollText = QScrollArea() self.scrollText.setBackgroundRole(QPalette.Dark) self.scrollText.setWidget(self.textInfoTop) self.scrollText.setWidgetResizable(True) #======================================================================= # self.adjustScrollBar(self.scrollText.horizontalScrollBar(), 1.0) # self.adjustScrollBar(self.scrollText.verticalScrollBar(), 2.0) #======================================================================= self.scrollTable = QScrollArea() self.scrollTable.setBackgroundRole(QPalette.Dark) self.scrollTable.setWidget(self.tableJson) self.scrollTable.setWidgetResizable(True) #======================================================================= # self.adjustScrollBar(self.scrollTable.horizontalScrollBar(), 2.0) # self.adjustScrollBar(self.scrollTable.verticalScrollBar(), 2.0) #======================================================================= self.headerTabData = [ 'Data', 'PatientName', 'StudyName', 'DateCreation', 'PatientSex', 'PatientWeight', 'ProtocolName', 'SequenceName' ] self.tableData = TableDataBrower(self) self.tableData.setColumnCount(8) self.tableData.setRowCount(10) self.tableData.setColumnWidth(0, 200) self.tableData.setHorizontalHeaderLabels(self.headerTabData) self.tableData.setBackgroundRole(QPalette.Light) self.tableData.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContents) self.tableData.verticalHeader().hide() self.scrollBrowser = QScrollArea() self.scrollBrowser.setBackgroundRole(QPalette.Dark) self.scrollBrowser.setWidget(self.tableData) self.scrollBrowser.setWidgetResizable(True) self.splitter0 = QSplitter(Qt.Vertical) self.splitter0.addWidget(self.scrollText) self.splitter0.addWidget(self.scrollTable) self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.imageLabel) self.scrollArea.setWidgetResizable(False) self.scrollArea.setAlignment(Qt.AlignCenter) self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), 0.8) self.adjustScrollBar(self.scrollArea.verticalScrollBar(), 1.0) self.splitter1 = QSplitter(Qt.Horizontal) self.splitter1.addWidget(self.splitter0) self.splitter1.addWidget(self.scrollArea) self.splitter1.addWidget(self.layoutSlide) self.splitter3 = QSplitter(Qt.Horizontal) self.splitter3.addWidget(self.browser) self.splitter3.addWidget(self.scrollBrowser) self.splitter2 = QSplitter(Qt.Vertical) self.splitter2.addWidget(self.splitter1) self.splitter2.addWidget(self.splitter3) self.splitter2.setHandleWidth(15) #======================================================================= # self.splitter2. #======================================================================= self.verticalLayout.addWidget(self.menuToolBar) self.verticalLayout.addWidget(self.splitter2) self.setWindowTitle("MRImage Viewer (IRMaGe)") self.resize(800, 600) self.setAutoFillBackground(True) self.setPalette(pal)
def save_project_as(self): """ Open a pop-up to save the current project as """ import glob self.exPopup = Ui_Dialog_Save_Project_As() if self.exPopup.exec_(): old_folder = self.project.folder file_name = self.exPopup.relative_path data_path = os.path.join( os.path.relpath(self.exPopup.relative_path), 'data') database_path = os.path.join( os.path.relpath(self.exPopup.relative_path), 'database') properties_path = os.path.join( os.path.relpath(self.exPopup.relative_path), 'properties') filters_path = os.path.join( os.path.relpath(self.exPopup.relative_path), 'filters') data_path = os.path.join( os.path.relpath(self.exPopup.relative_path), 'data') raw_data_path = os.path.join(data_path, 'raw_data') derived_data_path = os.path.join(data_path, 'derived_data') downloaded_data_path = os.path.join(data_path, 'downloaded_data') # List of projects updated if not self.test: self.saved_projects_list = self.saved_projects.addSavedProject( file_name) self.update_recent_projects_actions() os.makedirs(self.exPopup.relative_path) os.mkdir(data_path) os.mkdir(raw_data_path) os.mkdir(derived_data_path) os.mkdir(downloaded_data_path) os.mkdir(filters_path) # Data files copied if os.path.exists(os.path.join(old_folder, 'data')): for filename in glob.glob( os.path.join(os.path.relpath(old_folder), 'data', 'raw_data', '*')): shutil.copy( filename, os.path.join(os.path.relpath(data_path), 'raw_data')) for filename in glob.glob( os.path.join(os.path.relpath(old_folder), 'data', 'derived_data', '*')): shutil.copy( filename, os.path.join(os.path.relpath(data_path), 'derived_data')) for filename in glob.glob( os.path.join(os.path.relpath(old_folder), 'data', 'downloaded_data', '*')): shutil.copy( filename, os.path.join(os.path.relpath(data_path), 'downloaded_data')) if os.path.exists(os.path.join(old_folder, 'filters')): for filename in glob.glob( os.path.join(os.path.relpath(old_folder), 'filters', '*')): shutil.copy(filename, os.path.join(os.path.relpath(filters_path))) # First we register the Database before commiting the last pending modifications shutil.copy( os.path.join(os.path.relpath(old_folder), 'database', 'mia.db'), os.path.join(os.path.relpath(old_folder), 'database', 'mia_before_commit.db')) # We commit the last pending modifications self.project.saveModifications() os.mkdir(properties_path) shutil.copy( os.path.join(os.path.relpath(old_folder), 'properties', 'properties.yml'), os.path.relpath(properties_path)) # We copy the Database with all the modifications commited in the new project os.mkdir(os.path.relpath(database_path)) shutil.copy( os.path.join(os.path.relpath(old_folder), 'database', 'mia.db'), os.path.relpath(database_path)) # We remove the Database with all the modifications saved in the old project os.remove( os.path.join(os.path.relpath(old_folder), 'database', 'mia.db')) # We reput the Database without the last modifications in the old project shutil.copy( os.path.join(os.path.relpath(old_folder), 'database', 'mia_before_commit.db'), os.path.join(os.path.relpath(old_folder), 'database', 'mia.db')) os.remove( os.path.join(os.path.relpath(old_folder), 'database', 'mia_before_commit.db')) self.remove_raw_files_useless( ) # We remove the useless files from the old project # Removing the old project from the list of currently opened projects config = Config() opened_projects = config.get_opened_projects() opened_projects.remove(self.project.folder) config.set_opened_projects(opened_projects) # Project updated everywhere self.project = Project(self.exPopup.relative_path, False) self.project.setName(os.path.basename(self.exPopup.relative_path)) self.project.setDate(datetime.now().strftime('%d/%m/%Y %H:%M:%S')) self.project.saveModifications() self.update_project( file_name, call_update_table=False) # Project updated everywhere
def ok_clicked(self, main): config = Config() # Auto-save if self.save_checkbox.isChecked(): config.setAutoSave("yes") else: config.setAutoSave("no") # Use Matlab if self.use_matlab_checkbox.isChecked(): config.set_use_matlab("yes") else: config.set_use_matlab("no") # Use SPM if self.use_spm_checkbox.isChecked(): config.set_use_spm("yes") else: config.set_use_spm("no") # Use SPM standalone if self.use_spm_standalone_checkbox.isChecked(): config.set_use_spm_standalone("yes") else: config.set_use_spm_standalone("no") # Clinical mode if self.clinical_mode_checkbox.isChecked(): config.set_clinical_mode("yes") self.use_clinical_mode_signal.emit() else: config.set_clinical_mode("no") # Matlab if self.use_matlab_checkbox.isChecked(): matlab_input = self.matlab_choice.text() if os.path.exists(matlab_input) or matlab_input == "": config.set_matlab_path(matlab_input) else: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Critical) self.msg.setText("Invalid Matlab path") self.msg.setInformativeText("The MCR path entered {0} is invalid.".format(matlab_input)) self.msg.setWindowTitle("Error") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.buttonClicked.connect(self.msg.close) self.msg.show() return matlab_standalone_input = self.matlab_standalone_choice.text() if os.path.exists(matlab_standalone_input) or matlab_standalone_input == "": config.set_matlab_standalone_path(matlab_standalone_input) else: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Critical) self.msg.setText("Invalid MCR path") self.msg.setInformativeText("The MCR path entered {0} is invalid.".format(matlab_standalone_input)) self.msg.setWindowTitle("Error") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.buttonClicked.connect(self.msg.close) self.msg.show() return # SPM if self.use_spm_checkbox.isChecked(): spm_input = self.spm_choice.text() if os.path.exists(spm_input): config.set_spm_path(spm_input) else: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Critical) self.msg.setText("Invalid SPM standalone path") self.msg.setInformativeText("The SPM path entered {0} is invalid.".format(spm_input)) self.msg.setWindowTitle("Error") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.buttonClicked.connect(self.msg.close) self.msg.show() if self.use_spm_standalone_checkbox.isChecked(): spm_input = self.spm_standalone_choice.text() if os.path.exists(spm_input) and "spm12" in spm_input: config.set_spm_standalone_path(spm_input) else: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Critical) self.msg.setText("Invalid SPM standalone path") self.msg.setInformativeText("The SPM standalone path entered {0} is invalid.".format(spm_input)) self.msg.setWindowTitle("Error") self.msg.setStandardButtons(QMessageBox.Ok) self.msg.buttonClicked.connect(self.msg.close) self.msg.show() return #Colors background_color = self.background_color_combo.currentText() text_color = self.text_color_combo.currentText() config.setBackgroundColor(background_color) config.setTextColor(text_color) main.setStyleSheet("background-color:" + background_color + ";color:" + text_color + ";") self.signal_preferences_change.emit() self.accept() self.close()
def pop_up(self, main_window): _translate = QtCore.QCoreApplication.translate self.setObjectName("Dialog") self.setWindowTitle('MIA preferences') self.tab_widget = QtWidgets.QTabWidget(self) self.tab_widget.setEnabled(True) config = Config() # The 'Tools" tab self.tab_tools = QtWidgets.QWidget() self.tab_tools.setObjectName("tab_tools") self.tab_widget.addTab(self.tab_tools, _translate("Dialog", "Tools")) # Groupbox "Global preferences" self.groupbox_global = QtWidgets.QGroupBox("Global preferences") self.save_checkbox = QCheckBox('', self) self.save_label = QLabel("Auto save") if config.isAutoSave() == "yes": self.save_checkbox.setChecked(1) h_box_auto_save = QtWidgets.QHBoxLayout() h_box_auto_save.addWidget(self.save_checkbox) h_box_auto_save.addWidget(self.save_label) h_box_auto_save.addStretch(1) self.clinical_mode_checkbox = QCheckBox('', self) self.clinical_mode_label = QLabel("Clinical mode") if config.get_clinical_mode() == "yes": self.clinical_mode_checkbox.setChecked(1) else: self.clinical_mode_checkbox.setChecked(1) self.clinical_mode_checkbox.setChecked(0) h_box_clinical_mode = QtWidgets.QHBoxLayout() h_box_clinical_mode.addWidget(self.clinical_mode_checkbox) h_box_clinical_mode.addWidget(self.clinical_mode_label) h_box_clinical_mode.addStretch(1) v_box_global = QtWidgets.QVBoxLayout() v_box_global.addLayout(h_box_auto_save) v_box_global.addLayout(h_box_clinical_mode) self.groupbox_global.setLayout(v_box_global) # Groupbox "Matlab" self.groupbox_matlab = QtWidgets.QGroupBox("Matlab") self.use_matlab_label = QLabel("Use Matlab") self.use_matlab_checkbox = QCheckBox('', self) self.matlab_label = QLabel("Matlab path:") self.matlab_choice = QLineEdit(config.get_matlab_path()) self.matlab_browse = QPushButton("Browse") self.matlab_browse.clicked.connect(self.browse_matlab) self.matlab_standalone_label = QLabel("Matlab standalone path:") self.matlab_standalone_choice = QLineEdit(config.get_matlab_standalone_path()) self.matlab_standalone_browse = QPushButton("Browse") self.matlab_standalone_browse.clicked.connect(self.browse_matlab_standalone) if config.get_use_matlab() == "yes": self.use_matlab_checkbox.setChecked(1) else: self.use_matlab_checkbox.setChecked(0) h_box_use_matlab = QtWidgets.QHBoxLayout() h_box_use_matlab.addWidget(self.use_matlab_checkbox) h_box_use_matlab.addWidget(self.use_matlab_label) h_box_use_matlab.addStretch(1) h_box_matlab_path = QtWidgets.QHBoxLayout() h_box_matlab_path.addWidget(self.matlab_choice) h_box_matlab_path.addWidget(self.matlab_browse) v_box_matlab_path = QtWidgets.QVBoxLayout() v_box_matlab_path.addWidget(self.matlab_label) v_box_matlab_path.addLayout(h_box_matlab_path) h_box_matlab_standalone_path = QtWidgets.QHBoxLayout() h_box_matlab_standalone_path.addWidget(self.matlab_standalone_choice) h_box_matlab_standalone_path.addWidget(self.matlab_standalone_browse) v_box_matlab_standalone_path = QtWidgets.QVBoxLayout() v_box_matlab_standalone_path.addWidget(self.matlab_standalone_label) v_box_matlab_standalone_path.addLayout(h_box_matlab_standalone_path) v_box_matlab = QtWidgets.QVBoxLayout() v_box_matlab.addLayout(h_box_use_matlab) v_box_matlab.addLayout(v_box_matlab_path) v_box_matlab.addLayout(v_box_matlab_standalone_path) self.groupbox_matlab.setLayout(v_box_matlab) # Groupbox "SPM" self.groupbox_spm = QtWidgets.QGroupBox("SPM") self.use_spm_label = QLabel("Use SPM") self.use_spm_checkbox = QCheckBox('', self) self.spm_label = QLabel("SPM path:") self.spm_choice = QLineEdit(config.get_spm_path()) self.spm_browse = QPushButton("Browse") self.spm_browse.clicked.connect(self.browse_spm) if config.get_use_spm() == "yes": self.use_spm_checkbox.setChecked(1) else: self.use_spm_checkbox.setChecked(0) h_box_use_spm = QtWidgets.QHBoxLayout() h_box_use_spm.addWidget(self.use_spm_checkbox) h_box_use_spm.addWidget(self.use_spm_label) h_box_use_spm.addStretch(1) h_box_spm_path = QtWidgets.QHBoxLayout() h_box_spm_path.addWidget(self.spm_choice) h_box_spm_path.addWidget(self.spm_browse) v_box_spm_path = QtWidgets.QVBoxLayout() v_box_spm_path.addWidget(self.spm_label) v_box_spm_path.addLayout(h_box_spm_path) self.use_spm_standalone_label = QLabel("Use SPM standalone") self.use_spm_standalone_checkbox = QCheckBox('', self) self.spm_standalone_label = QLabel("SPM standalone path:") self.spm_standalone_choice = QLineEdit(config.get_spm_standalone_path()) self.spm_standalone_browse = QPushButton("Browse") self.spm_standalone_browse.clicked.connect(self.browse_spm_standalone) if config.get_use_spm_standalone() == "yes": self.use_spm_standalone_checkbox.setChecked(1) else: self.use_spm_standalone_checkbox.setChecked(0) h_box_use_spm_standalone = QtWidgets.QHBoxLayout() h_box_use_spm_standalone.addWidget(self.use_spm_standalone_checkbox) h_box_use_spm_standalone.addWidget(self.use_spm_standalone_label) h_box_use_spm_standalone.addStretch(1) h_box_spm_standalone_path = QtWidgets.QHBoxLayout() h_box_spm_standalone_path.addWidget(self.spm_standalone_choice) h_box_spm_standalone_path.addWidget(self.spm_standalone_browse) v_box_spm_standalone_path = QtWidgets.QVBoxLayout() v_box_spm_standalone_path.addWidget(self.spm_standalone_label) v_box_spm_standalone_path.addLayout(h_box_spm_standalone_path) v_box_spm = QtWidgets.QVBoxLayout() v_box_spm.addLayout(h_box_use_spm) v_box_spm.addLayout(v_box_spm_path) v_box_spm.addLayout(h_box_use_spm_standalone) v_box_spm.addLayout(v_box_spm_standalone_path) self.groupbox_spm.setLayout(v_box_spm) # Final tab layouts h_box_top = QtWidgets.QHBoxLayout() h_box_top.addWidget(self.groupbox_global) h_box_top.addStretch(1) self.tab_tools_layout = QtWidgets.QVBoxLayout() self.tab_tools_layout.addLayout(h_box_top) self.tab_tools_layout.addWidget(self.groupbox_matlab) self.tab_tools_layout.addWidget(self.groupbox_spm) self.tab_tools_layout.addStretch(1) self.tab_tools.setLayout(self.tab_tools_layout) # The 'OK' push button self.push_button_ok = QtWidgets.QPushButton("OK") self.push_button_ok.setObjectName("pushButton_ok") self.push_button_ok.clicked.connect(partial(self.ok_clicked, main_window)) # The 'Cancel' push button self.push_button_cancel = QtWidgets.QPushButton("Cancel") self.push_button_cancel.setObjectName("pushButton_cancel") self.push_button_cancel.clicked.connect(self.close) # Buttons ayouts hbox_buttons = QHBoxLayout() hbox_buttons.addStretch(1) hbox_buttons.addWidget(self.push_button_ok) hbox_buttons.addWidget(self.push_button_cancel) vbox = QVBoxLayout() vbox.addWidget(self.tab_widget) vbox.addLayout(hbox_buttons) # The 'Appearance" tab self.tab_appearance = QtWidgets.QWidget() self.tab_appearance.setObjectName("tab_appearance") self.tab_widget.addTab(self.tab_appearance, _translate("Dialog", "Appearance")) self.appearance_layout = QVBoxLayout() self.label_background_color = QLabel("Background color") self.background_color_combo = QComboBox(self) self.background_color_combo.addItem("") self.background_color_combo.addItem("Black") self.background_color_combo.addItem("Blue") self.background_color_combo.addItem("Green") self.background_color_combo.addItem("Grey") self.background_color_combo.addItem("Orange") self.background_color_combo.addItem("Red") self.background_color_combo.addItem("Yellow") self.background_color_combo.addItem("White") background_color = config.getBackgroundColor() self.background_color_combo.setCurrentText(background_color) self.label_text_color = QLabel("Text color") self.text_color_combo = QComboBox(self) self.text_color_combo.addItem("") self.text_color_combo.addItem("Black") self.text_color_combo.addItem("Blue") self.text_color_combo.addItem("Green") self.text_color_combo.addItem("Grey") self.text_color_combo.addItem("Orange") self.text_color_combo.addItem("Red") self.text_color_combo.addItem("Yellow") self.text_color_combo.addItem("White") text_color = config.getTextColor() self.text_color_combo.setCurrentText(text_color) self.appearance_layout.addWidget(self.label_background_color) self.appearance_layout.addWidget(self.background_color_combo) self.appearance_layout.addWidget(self.label_text_color) self.appearance_layout.addWidget(self.text_color_combo) self.appearance_layout.addStretch(1) self.tab_appearance.setLayout(self.appearance_layout) self.setLayout(vbox) # Disabling widgets self.use_spm_changed() self.use_matlab_changed() # Signals self.use_matlab_checkbox.stateChanged.connect(self.use_matlab_changed) self.use_spm_checkbox.stateChanged.connect(self.use_spm_changed) self.use_spm_standalone_checkbox.stateChanged.connect(self.use_spm_standalone_changed)
def create_actions(self): """ Create the actions in each menu """ self.action_create = QAction('New project', self) self.action_create.setShortcut('Ctrl+N') self.action_open = QAction('Open project', self) self.action_open.setShortcut('Ctrl+O') self.action_save = QAction('Save project', self) self.action_save.setShortcut('Ctrl+S') self.action_save_as = QAction('Save project as', self) self.action_save_as.setShortcut('Ctrl+Shift+S') self.action_import = QAction( QIcon(os.path.join('..', 'sources_images', 'Blue.png')), 'Import', self) self.action_import.setShortcut('Ctrl+I') for i in range(self.saved_projects.maxProjects): self.saved_projects_actions.append( QAction(self, visible=False, triggered=self.open_recent_project)) self.action_see_all_projects = QAction('See all projects', self) self.action_project_properties = QAction('Project properties', self) self.action_software_preferences = QAction('MIA preferences', self) self.action_package_library = QAction('Package library manager', self) if Config().get_clinical_mode() == 'yes': self.action_package_library.setDisabled(True) else: self.action_package_library.setEnabled(True) self.action_exit = QAction( QIcon(os.path.join('..', 'sources_images', 'exit.png')), 'Exit', self) self.action_exit.setShortcut('Ctrl+W') self.action_undo = QAction('Undo', self) self.action_undo.setShortcut('Ctrl+Z') self.action_redo = QAction('Redo', self) self.action_redo.setShortcut('Ctrl+Y') self.action_install_processes_folder = QAction('From folder', self) self.action_install_processes_zip = QAction('From zip file', self) # if Config().get_clinical_mode() == 'yes': # self.action_install_processes.setDisabled(True) # else: # self.action_install_processes.setEnabled(True) # Connection of the several triggered signals of the actions to some other methods self.action_create.triggered.connect(self.create_project_pop_up) self.action_open.triggered.connect(self.open_project_pop_up) self.action_exit.triggered.connect(self.close) self.action_save.triggered.connect(self.saveChoice) self.action_save_as.triggered.connect(self.save_project_as) self.action_import.triggered.connect(self.import_data) self.action_see_all_projects.triggered.connect(self.see_all_projects) self.action_project_properties.triggered.connect( self.project_properties_pop_up) self.action_software_preferences.triggered.connect( self.software_preferences_pop_up) self.action_package_library.triggered.connect( self.package_library_pop_up) self.action_undo.triggered.connect(self.undo) self.action_redo.triggered.connect(self.redo) self.action_install_processes_folder.triggered.connect( lambda: self.install_processes_pop_up(folder=True)) self.action_install_processes_zip.triggered.connect( lambda: self.install_processes_pop_up(folder=False))
def switch_project(self, path, file_name, name): """ Called to switch project if it's possible :param path: relative path of the new project :param file_name: raw file_name :param name: project name """ # Switching project only if it's a different one if path != self.project.folder: # If the file exists if os.path.exists(os.path.join(path)): if os.path.exists( os.path.join(path, "properties", "properties.yml") ) and os.path.exists(os.path.join( path, "database", "mia.db")) and os.path.exists( os.path.join( path, "data", "raw_data")) and os.path.exists( os.path.join(path, "data", "derived_data") ) and os.path.exists( os.path.join( path, "data", "downloaded_data")) and os.path.exists( os.path.join(path, "filters")): # We check for unsaved modifications if self.check_unsaved_modifications(): # If there are unsaved modifications, we ask the user what he wants to do self.pop_up_close = Ui_Dialog_Quit(self.project) self.pop_up_close.save_as_signal.connect( self.saveChoice) self.pop_up_close.exec() can_switch = self.pop_up_close.can_exit() else: can_switch = True # We can open a new project if can_switch: # We check for invalid scans in the project try: tempDatabase = Project(path, False) except IOError: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Project already opened") msg.setInformativeText( "The project at " + str(path) + " is already opened in another instance of the software." ) msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.buttonClicked.connect(msg.close) msg.exec() return False problem_list = controller.verify_scans( tempDatabase, path) # Message if invalid files if problem_list != []: str_msg = "" for element in problem_list: str_msg += element + "\n\n" msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText( "These files have been modified or removed since they have been converted for the first time:" ) msg.setInformativeText(str_msg) msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.buttonClicked.connect(msg.close) msg.exec() self.project.session.unsave_modifications() self.remove_raw_files_useless( ) # We remove the useless files from the old project # Project removed from the opened projects list config = Config() opened_projects = config.get_opened_projects() opened_projects.remove(self.project.folder) config.set_opened_projects(opened_projects) self.project = tempDatabase # New Database self.update_project( file_name) # Project updated everywhere return True # Not a MIA project else: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText( "The project selected isn't a valid MIA project") msg.setInformativeText( "The project selected " + name + " isn't a MIA project.\nPlease select a valid one.") msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.buttonClicked.connect(msg.close) msg.exec() return False # The project doesn't exist anymore else: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("The project selected doesn't exist anymore") msg.setInformativeText( "The project selected " + name + " doesn't exist anymore.\nPlease select another one.") msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.buttonClicked.connect(msg.close) msg.exec() return False