def fluid_species_delete(self): ui = self.ui.fluid tw = ui.tablewidget_fluid_species row = get_selected_row(tw) if row is None: # No selection return alias = tw.item(row, 0).text() msg = self.fluid_check_species_in_use(alias) if msg: self.message(text="%s is used in %s " % (alias, msg)) return tw.clearSelection() #? species_index = 1 + list(self.fluid_species.keys()).index(alias) self.bcs_delete_fluid_species( species_index) # special handling for memoized eq_type self.fluid_species.pop(alias, None) self.fluid_delete_species_keys( species_index) # Must remove fluid species first (why?) self.update_fluid_species_table() # Sigh, we have to update the row in the popup too. # Should the popup just be modal, to avoid this? sp = self.species_popup sp.defined_species = deepcopy(self.fluid_species) sp.update_defined_species() self.update_nav_tree() # Chemistry
def iss_delete_regions(self): ui = self.ui.internal_surfaces tw = ui.tablewidget_regions row = get_selected_row(tw) if row is None: # No selection return # Unset keywords kwlist = list(self.project.keywordItems()) for kw in kwlist: key, args = kw.key, kw.args if key.startswith( 'is_') and args and args[0] in self.iss_current_indices: self.unset_keyword(key, args=args) for r in self.iss_current_regions: if r in self.iss_region_dict: self.iss_region_dict[r]['available'] = True for i in self.iss_current_indices: del self.iss[i] self.iss_current_regions = [] self.iss_current_indices = [] tw.removeRow(row) self.fixup_iss_table(tw) self.iss_setup_current_tab() self.update_nav_tree()
def monitors_delete_regions(self): ui = self.ui.monitors tw = ui.tablewidget_regions row = get_selected_row(tw) if row is None: # No selection return # Unset keywords kwlist = list(self.project.keywordItems()) for kw in kwlist: key, args = kw.key, kw.args if key.startswith('monitor_') and args and args[ 0] == self.monitors_current_index: self.unset_keyword(key, args=args) r = self.monitors_current_region if r and r in self.monitors_region_dict: self.monitors_region_dict[r]['available'] = True i = self.monitors_current_index if i in self.monitors: del self.monitors[i] self.monitors_current_region = None self.monitors_current_index = None tw.removeRow(row) self.fixup_monitors_table() self.monitors_setup_current_tab() self.update_nav_tree()
def iss_cancel_add(self): ui = self.ui.internal_surfaces for item in (ui.toolbutton_add, ui.tablewidget_regions): item.setEnabled(True) if get_selected_row(ui.tablewidget_regions) is not None: for item in (ui.bottom_frame, ui.toolbutton_delete): item.setEnabled(True)
def setup_iss(self): ui = self.ui.internal_surfaces # Grab a fresh copy, may have been updated self.iss_region_dict = self.ui.regions.get_region_dict() # Mark regions which are in use (this gets reset each time we get here) for (i, data) in self.iss.items(): region = data['region'] if region in self.iss_region_dict: self.iss_region_dict[region]['available'] = False self.fixup_iss_table(ui.tablewidget_regions) row = get_selected_row(ui.tablewidget_regions) # Autoselect if only 1 row if row is None and ui.tablewidget_regions.rowCount() == 1: row = 0 ui.tablewidget_regions.setCurrentCell(row, 0) enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) solids_names = list(self.solids.keys()) # There should be a line for each solids phase. Use the user provided solids name. if not self.solids: ui.groupbox_solids_velocities.hide() else: if self.iss_saved_solids_names != solids_names: # Clear out the old ones for w in widget_iter(ui.groupbox_solids_velocities): if not isinstance(w, (LineEdit, QLabel)): continue self.project.unregister_widget(w) w.setParent(None) w.deleteLater() # make new ones layout = ui.groupbox_solids_velocities.layout() row = 0 key = 'is_vel_s' for phase, solid_name in enumerate(self.solids.keys(), 1): label = QLabel(solid_name) self.add_tooltip(label, key) layout.addWidget(label, row, 0) le = LineEdit() le.key = key le.args = ['IS', phase] le.dtype = float self.project.register_widget(le, key, le.args) self.add_tooltip(le, key) layout.addWidget(le, row, 1) units_label = QLabel('m/s') layout.addWidget(units_label, row, 2) row += 1 ui.groupbox_solids_velocities.show() self.iss_saved_solids_names = solids_names self.iss_setup_current_tab()
def monitors_cancel_add(self): ui = self.ui.monitors for item in (ui.toolbutton_add, ui.tablewidget_regions): item.setEnabled(True) tw = ui.tablewidget_regions row = get_selected_row(tw) if row is not None: for item in (ui.bottom_frame, ui.toolbutton_delete): item.setEnabled(True)
def handle_defined_species_selection(self): self.ui.tablewidget_search.clearSelection() tw = self.tablewidget_defined_species row = get_selected_row(tw) if row is None: self.current_species = None self.clear_species_panel() self.ui.pushbutton_copy.setEnabled(False) self.ui.combobox_phase.setEnabled(False) else: self.ui.pushbutton_copy.setEnabled(True) self.current_species = tw.item(row, 0).text() self.enable_species_panel()
def handle_fluid_species_selection(self): ui = self.ui.fluid tw = ui.tablewidget_fluid_species row = get_selected_row(tw) enabled = (row is not None) ui.toolbutton_fluid_species_delete.setEnabled(enabled) ui.toolbutton_fluid_species_copy.setEnabled(enabled) if enabled: tw.doubleClicked.connect(self.fluid_species_edit) else: try: tw.doubleClicked.disconnect() #self.fluid_species_edit) except: pass
def handle_alias(self): val = self.ui.lineedit_alias.text() # Already validated (?) tw = self.ui.tablewidget_defined_species row = get_selected_row(tw) if row is None: # No selection return #note, making a new item here, instead of changing item inplace item = QTableWidgetItem(val) set_item_noedit(item) tw.setItem(row, 0, item) defined_species = OrderedDict() for (key, data) in self.defined_species.items(): if key == self.current_species: key = val data['alias'] = val defined_species[key] = data self.current_species = val self.defined_species = defined_species
def fluid_species_edit(self): tw = self.ui.fluid.tablewidget_fluid_species row = get_selected_row(tw) sp = self.species_popup sp.set_phases('GL') sp.reset_signals() sp.cancel.connect(self.fluid_species_revert) sp.save.connect(self.fluid_species_save) sp.defined_species = deepcopy(self.fluid_species) sp.extra_aliases = self.fluid_make_extra_aliases() sp.update_defined_species() if row is None: sp.tablewidget_defined_species.clearSelection() else: sp.tablewidget_defined_species.setCurrentCell(row, 0) sp.setWindowTitle("Fluid Species") sp.enable_density(False) sp.popup()
def handle_copy(self): tw = self.ui.tablewidget_defined_species row = get_selected_row(tw) if row is None: return species = tw.item(row, 0).text() alias = self.make_alias(species) if species not in self.defined_species: return species_data = deepcopy(self.defined_species[species]) species_data['alias'] = alias species = alias self.defined_species[species] = species_data self.current_species = species self.enable_species_panel() self.add_defined_species_row(alias, select=True) lineedit = self.ui.lineedit_alias lineedit.selectAll() lineedit.setFocus() self.ui.combobox_phase.setEnabled(True)
def change_is_type(self, idx): if not self.iss_current_indices: return ui = self.ui.internal_surfaces row = get_selected_row(ui.tablewidget_regions) if row is None: return new_name = IS_NAMES[idx] new_type = IS_TYPES[idx] item = QTableWidgetItem(new_name) set_item_noedit(item) ui.tablewidget_regions.setItem(row, 1, item) for IS in self.iss_current_indices: self.update_keyword('is_type', new_type, args=[IS]) for kw in list(self.project.keywordItems()): if kw.key.startswith('is_') and kw.args and kw.args[0] == IS: if kw.key not in ('is_type', 'is_x_e', 'is_x_w', 'is_y_s', 'is_y_n', 'is_z_b', 'is_z_t'): self.unset_keyword(kw.key, args=kw.args) self.iss_setup_current_tab()
def setup_fluid(self): # Called whenever we switch to fluid tab self.P = 0 ui = self.ui.fluid tw = ui.tablewidget_fluid_species # Autoselect if unique row if get_selected_row(tw) is None and tw.rowCount() == 1: tw.setCurrentCell(0, 0) cb = ui.checkbox_enable_scalar_eq sb = ui.spinbox_nscalar_eq nscalar_phase = self.get_nscalar_phase(0) enabled = (nscalar_phase > 0) cb.setChecked(enabled) sb.setEnabled(enabled) # Lower minimum before setting value if not enabled: sb.setMinimum(0) sb.setValue(nscalar_phase) # Raise minimum after value is set to avoid spurious callback if enabled: sb.setMinimum(1)
def handle_pss_region_selection(self): ui = self.ui.point_sources table = ui.tablewidget_regions row = get_selected_row(table) if row is None: indices = [] regions = [] else: (indices, regions) = table.item(row, 0).data(UserRole) self.pss_current_indices, self.pss_current_regions = indices, regions enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) if not enabled: # Clear for widget in widget_iter(ui.bottom_frame): if isinstance(widget, LineEdit): widget.setText('') return self.setup_pss() # reinitialize all widgets ui.scrollarea_detail.ensureVisible(0, 0) # scroll to top
def handle_monitors_region_selection(self): ui = self.ui.monitors table = ui.tablewidget_regions row = get_selected_row(table) nrows = table.rowCount() if row is None: index = None region = None else: (index, region) = table.item(row, COLUMN_REGION).data(UserRole) self.monitors_current_index, self.monitors_current_region = index, region enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) if not enabled: return # Set combobox to only allow appropriate monitor_type cb = ui.combobox_monitor_type mon = index monitor_type = self.project.get_value('monitor_type', args=[mon]) region_type = self.monitors_region_dict.get(region) if region_type is None: self.error("Invalid region %s" % region) return region_type = region_type.get('type') if region_type == 'point': valids = MONITOR_TYPES_POINT elif 'plane' in region_type: valids = MONITOR_TYPES_PLANE elif 'box' in region_type: valids = MONITOR_TYPES_VOLUME else: valids = [] for i in range(len(cb)): get_combobox_item(cb, i).setEnabled(i in valids) if monitor_type is None or monitor_type not in valids: # Default not specified in SRS, but 1 (sum) is valid for planes and volumes monitor_type = 0 if region_type == 'point' else 1 self.update_keyword('monitor_type', monitor_type, args=[mon]) cb.setCurrentIndex(monitor_type) cb.setToolTip(get_combobox_item(cb, monitor_type).toolTip()) enable_phase = self.monitor_requires_phase(mon) if enable_phase: # Disable all tabs except 'Phase' for i in range(ui.tab_layout.columnCount() - 1): # Skip 'Phase' item = ui.tab_layout.itemAtPosition(0, i) if not item: continue widget = item.widget() if not widget: continue widget.setEnabled(False) widget.setToolTip('') ui.pushbutton_phase.setEnabled(True) else: ui.pushbutton_fluid.setEnabled(True) for i in range(1, 1 + len(self.solids)): # Enable tabs for TFM solids item = ui.tab_layout.itemAtPosition(0, i) if not item: continue widget = item.widget() if not widget: continue enabled = self.project.get_value('solids_model', args=[i]) == 'TFM' widget.setEnabled(enabled) widget.setToolTip('TFM solids required' if not enabled else '') ui.pushbutton_scalar.setEnabled( self.project.get_value('nscalar', default=0) > 0) ui.pushbutton_phase.setEnabled(False) self.setup_monitors() # reinitialize all widgets ui.scrollarea_detail.ensureVisible(0, 0) # scroll to top
def handle_iss_region_selection(self): ui = self.ui.internal_surfaces table = ui.tablewidget_regions row = get_selected_row(table) if row is None: indices = [] regions = [] else: (indices, regions) = table.item(row, 0).data(UserRole) self.iss_current_indices, self.iss_current_regions = indices, regions enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) ui.bottom_frame.setEnabled(enabled) if not enabled: # Clear for widget in widget_iter(ui.bottom_frame): if isinstance(widget, LineEdit): widget.setText('') return IS0 = self.iss_current_indices[0] cb = ui.combobox_is_type key = 'is_type' is_type = self.project.get_value(key, args=[IS0]) if is_type not in IS_TYPES: self.error("Unknown IS_TYPE %s" % is_type) is_type = 'IMPERMEABLE' for IS in self.iss_current_indices: self.update_keyword(key, is_type, args=[IS]) cb.setCurrentIndex(IS_TYPES.index(is_type)) # Available selections: # Impermeable # Selection only available for plane regions # set keyword IS_TYPE(#) to 'IMPERMEABLE' # X-Axis Impermeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'X_IMPERMEABLE' # Y-Axis Impermeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'Y_IMPERMEABLE' # z-Axis Impermeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'Z_IMPERMEABLE' # Semi-permeable # Selection only available for plane regions # set keyword IS_TYPE(#) to 'SEMIPERMEABLE' # X-Axis semi-permeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'X_SEMIPERMEABLE' # Y-Axis semi-permeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'Y_SEMIPERMEABLE' # Z-Axis semi-permeable # Selection only available for volume regions # set keyword IS_TYPE(#) to 'Z_SEMIPERMEABLE' # DEFAULT - Impermeable plane = is_type in ('IMPERMEABLE', 'SEMIPERMEABLE') vol = not plane for (i, enable) in enumerate( (plane, vol, vol, vol, plane, vol, vol, vol)): get_combobox_item(cb, i).setEnabled(enable) self.setup_iss() # reinitialize all widgets in current tab ui.scrollarea_detail.ensureVisible(0, 0) # scroll to top
def setup_monitors(self): ui = self.ui.monitors # Grab a fresh copy, may have been updated self.monitors_region_dict = self.ui.regions.get_region_dict() # Mark regions which are in use (this gets reset each time we get here) #for (i, data) in self.monitors.items(): # region = data['region'] # if region in self.monitors_region_dict: # self.monitors_region_dict[region]['available'] = False self.fixup_monitors_table() row = get_selected_row(ui.tablewidget_regions) # Autoselect if only 1 row if row is None and ui.tablewidget_regions.rowCount() == 1: row = 0 ui.tablewidget_regions.setCurrentCell(row, COLUMN_REGION) enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) mon = self.monitors_current_index enable_phase = self.monitor_requires_phase(mon) #**Fluid phase tab** b = ui.pushbutton_fluid b.setText(self.fluid_phase_name) font = b.font() font.setBold(self.monitors_current_tab == FLUID_TAB) b.setFont(font) w = b.fontMetrics().boundingRect(b.text()).width() + 20 b.setMaximumWidth(w) b.setEnabled(not enable_phase) #**Solids Phase Tab** *(Requires TFM Solids)* #Each solid phase will have its own tab. The tab name should be the name of the solid solids_names = list(self.solids.keys()) if self.monitors_saved_solids_names != solids_names: # Clear out the old ones n_cols = ui.tab_layout.columnCount() for i in range(n_cols - 1, 0, -1): item = ui.tab_layout.itemAtPosition(0, i) if not item: continue widget = item.widget() if not widget: continue if widget in (ui.pushbutton_fluid, ui.pushbutton_scalar, ui.pushbutton_reactions, ui.pushbutton_phase): continue ui.tab_layout.removeWidget(widget) widget.setParent(None) widget.deleteLater() # And make new ones for (i, solid_name) in enumerate(solids_names, 1): b = QPushButton(text=solid_name) w = b.fontMetrics().boundingRect(solid_name).width() + 20 b.setMaximumWidth(w) b.setFlat(True) font = b.font() font.setBold(self.monitors_current_tab == SOLIDS_TAB and i == self.monitors_current_solid) b.setFont(font) b.pressed.connect( lambda i=i: self.monitors_change_tab(SOLIDS_TAB, i)) ui.tab_layout.addWidget(b, 0, i) # Only TFM solids for i in range(1, 1 + len(self.solids)): enabled = self.project.get_value( 'solids_model', args=[i]) == 'TFM' and not enable_phase item = ui.tab_layout.itemAtPosition(0, i) if item: widget = item.widget() if widget: widget.setEnabled(enabled) #Scalar (tab) - Tab only available if scalar equations are solved # Move the 'Scalar' button to the right of all solids, if needed b = ui.pushbutton_scalar font = b.font() font.setBold(self.monitors_current_tab == SCALAR_TAB) b.setFont(font) nscalar = self.project.get_value('nscalar', default=0) enabled = (nscalar > 0) and not enable_phase b.setEnabled(enabled) if len(self.solids) != len(self.monitors_saved_solids_names): ui.tab_layout.removeWidget(b) ui.tab_layout.addWidget(b, 0, 1 + len(self.solids)) #Reactions (tab) - Tab only available if nrr > 0 # Move the 'Reactions' button to the right of all solids, if needed b = ui.pushbutton_reactions font = b.font() font.setBold(self.monitors_current_tab == REACTIONS_TAB) b.setFont(font) nrr = self.project.get_value('nrr', default=0) enabled = (nrr > 0) and not enable_phase if nrr == 0 and not enable_phase: b.setToolTip("Requires nrr > 0") else: b.setToolTip('') b.setEnabled(enabled) if len(self.solids) != len(self.monitors_saved_solids_names): ui.tab_layout.removeWidget(b) ui.tab_layout.addWidget(b, 0, 2 + len(self.solids)) # Move the 'Phase' button to the right of all solids, if needed b = ui.pushbutton_phase font = b.font() font.setBold(self.monitors_current_tab == PHASE_TAB) b.setFont(font) b.setEnabled(enable_phase) if len(self.solids) != len(self.monitors_saved_solids_names): ui.tab_layout.removeWidget(b) ui.tab_layout.addWidget(b, 0, 3 + len(self.solids)) self.monitors_saved_solids_names = solids_names self.P = self.monitors_current_solid if mon is None: #Construct the GUI, even though disabled (species checkboxes, etc) self.monitors_setup_current_tab() return key = 'monitor_name' le = ui.lineedit_keyword_monitor_name_args_MONITOR val = self.project.get_value(key, args=[mon]) if val is None: # Construct from region name val = self.monitor_default_name(self.monitors_current_region) self.update_keyword(key, val, args=[mon]) le.updateValue(key, val) # Update table too tw = ui.tablewidget_regions for i in range(tw.rowCount()): data = tw.item(i, 0).data(UserRole) index, name = data if index == mon: tw.item(i, COLUMN_FILENAME).setText(val) #Specify write interval key = 'monitor_dt' default = 0.05 le = ui.lineedit_keyword_monitor_dt_args_MONITOR val = self.project.get_value(key, args=[mon]) if val is None: val = default self.update_keyword(key, val, args=[mon]) le.updateValue(key, val) # Don't stay on a disabled tab index = self.monitors_tab_to_index(self.monitors_current_tab, self.monitors_current_solid) item = None if index is None else ui.tab_layout.itemAtPosition( 0, index) b = item.widget() if item else None if ui.isEnabled() and not (b and b.isEnabled()): self.monitors_change_tab(*self.monitors_find_valid_tab()) else: self.monitors_setup_current_tab() # make sure underline is in the right place, as # of solids may # have changed (lifted from animate_stacked_widget, which we # don't want to call here) tab = self.monitors_current_tab line_to = self.monitors_tab_to_index(tab, self.monitors_current_solid) line = ui.tab_underline btn_layout = ui.tab_layout if line_to is not None: btn_layout.addItem(btn_layout.takeAt(btn_layout.indexOf(line)), 1, line_to)
def setup_pss(self): ui = self.ui.point_sources # Grab a fresh copy, may have been updated self.pss_region_dict = self.ui.regions.get_region_dict() # Mark regions which are in use (this gets reset each time we get here) for (i, data) in self.pss.items(): region = data['region'] if region in self.pss_region_dict: self.pss_region_dict[region]['available'] = False self.fixup_pss_table(ui.tablewidget_regions) row = get_selected_row(ui.tablewidget_regions) # Autoselect if only 1 row if row is None and ui.tablewidget_regions.rowCount() == 1: row = 0 ui.tablewidget_regions.setCurrentCell(row, 0) enabled = (row is not None) for item in (ui.toolbutton_delete, ui.bottom_frame): item.setEnabled(enabled) #Tabs group point source parameters for phases. Tabs are unavailable if no input #is required from the user. # Fluid tab - Unavailable if the fluid phase was disabled. b = ui.pushbutton_fluid b.setText(self.fluid_phase_name) b.setEnabled(not self.fluid_solver_disabled) font = b.font() font.setBold(self.pss_current_tab == 0) b.setFont(font) # Each solid phase will have its own tab. The tab name should be the name of the solid solids_names = list(self.solids.keys()) if self.pss_saved_solids_names != solids_names: # Clear out the old ones n_cols = ui.tab_layout.columnCount() for i in range(n_cols - 1, 0, -1): item = ui.tab_layout.itemAtPosition(0, i) if not item: continue widget = item.widget() if not widget: continue if widget == ui.pushbutton_fluid: continue ui.tab_layout.removeWidget(widget) widget.setParent(None) widget.deleteLater() # And make new ones for (i, solid_name) in enumerate(solids_names, 1): b = QPushButton(text=solid_name) w = b.fontMetrics().boundingRect(solid_name).width() + 20 b.setMaximumWidth(w) b.setFlat(True) font = b.font() font.setBold(self.pss_current_tab == SOLIDS_TAB and i == self.pss_current_solid) b.setFont(font) ui.tab_layout.addWidget(b, 0, i) b.pressed.connect( lambda i=i: self.pss_change_tab(SOLIDS_TAB, i)) for (i, solid_name) in enumerate(self.solids.keys(), 1): model = self.project.get_value('solids_model', args=[i]) #At this time, only TFM solids can be defined with point sources. #At some point in the future, this could be extended to PIC solids, but never DEM. b = ui.tab_layout.itemAtPosition(0, i).widget() if model == 'TFM': b.setEnabled(True) b.setToolTip(None) else: b.setEnabled(False) b.setToolTip("Only TFM solids can be defined as point sources" "") self.pss_saved_solids_names = solids_names self.P = self.pss_current_solid # Don't stay on a disabled tab index = self.pss_tab_to_index(self.pss_current_tab, self.pss_current_solid) item = None if index is None else ui.tab_layout.itemAtPosition( 0, index) b = item.widget() if item else None if ui.isEnabled() and not (b and b.isEnabled()): self.pss_change_tab(*self.pss_find_valid_tab()) else: self.pss_setup_current_tab() # make sure underline is in the right place, as # of solids may # have changed (lifted from animate_stacked_widget, which we # don't want to call here) tab = self.pss_current_tab line_to = self.pss_tab_to_index(tab, self.pss_current_solid) line = ui.tab_underline btn_layout = ui.tab_layout if line_to is not None: btn_layout.addItem(btn_layout.takeAt(btn_layout.indexOf(line)), 1, line_to)
def handle_search_selection(self): row = get_selected_row(self.tablewidget_search) self.ui.pushbutton_import.setEnabled(row is not None)